From 8b68b9d9c962dc80b8e954e0f6bbf3a011da9598 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Oct 18 2022 20:16:56 +0000 Subject: Merge remote-tracking branch 'kerncvs/SLE15-SP5' into SLE15-SP5-AZURE --- diff --git a/blacklist.conf b/blacklist.conf index e05519e..3f7233a 100644 --- a/blacklist.conf +++ b/blacklist.conf @@ -191,8 +191,6 @@ faf890985e30d5e88cc3a7c50c1bcad32f89ab7c # Duplicate of a63bcf08f0efb5348105bb8e a9cdc1c5e3700a5200e5ca1f90b6958b6483845b # Checked into perf userspace package 218848835699879ed6260ec49bbb22e9e7839017 # went in through stable 1cbf731ef3a17b3dd4c22ed0c634ac126d1a4876 # The docs that this patch removes never got backported -ef775a0e36c6a81c5b07cb228c02f967133fe768 # PROC_FS is always set in our configs -f28439db470cca8b6b082239314e9fd10bd39034 # sparse warning fix only 3e2a56e6f639492311e0a8533f0a7aed60816308 # optimization only a672b2e36a648afb04ad3bda93b6bda947a479a5 # we lack type changes needed to make bpf_ret composable, not serious enough to justify backport 5a897531e00243cebbcc4dbe4ab06cd559ccf53f # added to perf userspace package @@ -220,7 +218,6 @@ a7ebf564de325e1d7d52cd85b12721c424338bcc # build warning in !CONFIG_MEMCG_KMEM 1f06f7d97f741667bab0f459a4f940b21cab1549 # Dup of a10834a36c8ab59b1a76df48d526fd9ddc090fca 9de2b9286a6dd16966959b3cb34fc2ddfd39213e # SoC:mediatek: Reverted in stable aff6657f5243db77e50838072b841cb6fa26375a # Soc:mediatek: reverting the above -b59f2f2b865cedd6d1641394b9cd84399bd738ff # cosmetic c7a75d07827a1f33d566e18e6098379cc2a0c2b2 # pci:xgene: caused a regression (bsc#1195352) 03ee5956781b2245b1c77334ecdea6386fd3bfba # not applicable 83dbf898a2d45289be875deb580e93050ba67529 # pci:msi: caused a regression (bsc#1196403) @@ -245,7 +242,6 @@ bf9727a27442a50c75b7d99a5088330c578b2a42 # misattributed. Introduced in 680a2ead d2f8114f9574509580a8506d2ef72e7e43d1a5bd # misattributed, actually introduced with cf75ad8b41d2aa06f98f365d42a3ae8b059daddd b3cf94c8b6b2f1a2b94825a025db291da2b151fd # misattributed, actually introduced with d2f8114f9574509580a8506d2ef72e7e43d1a5bd 3d135db510240fefd79da46181493d3e3b415f6b # changes the layout of attributes in sysfs by design -f6fb34390cd047543ff00b34b8ad910bf76c8eb3 # build fix selecting option we also switch on anyway 8aadeb8ad874b3b13431fd08c1ddb6d5e0212c7f # Duplicate of 50ca8cc7c0fdd9ab16b8b66ffb301fface101fac: drm/vmwgfx: Remove the dedicated memory accounting 4e13f6706d5aee1a6b835a44f6cf4971a921dcb8 # applied to perf userspace package ffab487052054162b3b6c9c6005777ec6cfcea05 # applied to perf userspace package @@ -286,7 +282,6 @@ f32c34d6cfbb3d1f1c26f223cb549cca9767cfbd # duplicate of 41512e4dc0b84525495e7842 f094399fae9cde11c3f98565eb150522aa7c15ab # duplicate of 21d90aaee8d5c2a097ef41f1430d97661233ecc6 2a19b28f7929866e1cec92a3619f4de9f2d20005 # introduces a regression (bsc#1200569) 245a489e81e13dd55ae46d27becf6d5901eb7828 # depends on 2a19b28f7929866e1cec92a3619f4de9f2d20005 -9974cb5c879048f5144d0660c4932d98176213c4 # deletes redundant declaration in header file 54f0bad6686cdc50a3f4c5f7c4252c5018511459 # net: sungem_phy: fix code indentation ffc95a46d677adb5f49f01789db9d8c3ae0af5e2 # CONFIG_SLAB not set in config 7acae6183cf37c48b8da48bbbdb78820fb3913f3 # N/A, bug introduced by e1a4541ec0b9 ("ceph: flush the mdlog before waiting on unsafe reqs") @@ -347,9 +342,7 @@ cfd3a9be0ac423be41afcc7a07d708056bf097a8 # selftest:vm: reverting the above 504627ee4cf4a2d42cba7ce156d423299c06a618 # net: wwan: already applied d68c2e1d19c540464ad12a8a11bdd88eedcaf3dc # octeontx2-nicvf:: a76053707dbf is not applied d8d83d8ab0a453e17e68b3a3bed1f940c34b8646 # lib/crypto: blake2s: breakes KABI -c26d4c5d4f0df7207da3975458261927f9305465 # config only fix c51ba246cb172c9e947dc6fb8868a1eaf0b2a913 # cleanup with a risk of regressions -9ef165406308515dcf2e3f6e97b39a1c56d86db5 # pure cleanup 14c174633f349cb41ea90c2c0aaddac157012f74 # tracepoints removal cleanup, not a bug 5f41fdaea63ddf96d921ab36b2af4a90ccdb5744 # Requires new mount API in ext4 d41b60359ffb24a39c93ea1f4bffaafd651118c3 # Documentation fix @@ -370,7 +363,6 @@ a52ed4866d2b90dd5e4ae9dabd453f3ed8fa3cbc # mwifiex: reverted in the stable patch 06781a5026350cde699d2d10c9914a25c1524f45 # mtd: reverted by below stable commit c80b15105a08dceffcbb0381f85696b46bce0d1b # mtd: reverting the above in stable bdc120a2bcd834e571ce4115aaddf71ab34495de # net: ieee802154: ca8210: already applied -5bc7b01c513a4a9b4cfe306e8d1720cfcfd3b8a3 # code from this commit already present in our code base f323896fe6fa8fa55ed37cb8b804fa97ead641c3 # requires many changes no present in our code base d9a434fa0c12ed5f7afe1e9dd30003ab5d059b85 # code to be patched not even present in our code base 25deecb21c18ee29e3be8ac6177b2a9504c33d2d # build fix selecting option we also switch on anyway @@ -378,3 +370,27 @@ d9a434fa0c12ed5f7afe1e9dd30003ab5d059b85 # code to be patched not even present i 28be5743c6306b3070012c00ca2ff2bff5c02258 # cleanup, not a bug fix 9a39abb7c9aab50eec4ac4421e9ee7f3de013d24 # memory layout change, might break debuggers 953503751a426413ea8aee2299ae3ee971b70d9b # reverts commit 6f5c672d17f583b081e283927f5040f726c54598, which is not backported +1dbd11ca75fe664d3e54607547771d021f531f59 # removal of unused function, would break KABI +ad2c302bc6049c56c85cc2b64a0b4bd8e7ffdc56 # kernel-doc warning +e9b6013a7ce31535b04b02ba99babefe8a8599fa # documentation +ea768b2ffec6cc9c3e17c37ef75d0539b8f89ff5 # already applied +fb7e76ea3f3b6238dda2f19a4212052d2caf00aa # there is no mlx5e_tc_act_parse_state +b1190d5175acb2c9feea69871737274eb6f462ff # comment spelling fix +8fe4ce5836e932f5766317cb651c1ff2a4cd0506 # changes Scsi_Host, difficult to mitigate the kABI changes +26ae150bbb6d19767f10800e17ad0fd81f3da67e # ASoC:cs35l41: RUNTIME_PM_OPS() not defined yet in SLE15-SP4 +00da0cb385d05a89226e150a102eb49d8abb0359 # documentation +df5b035b5683d6a25f077af889fb88e09827f8bc # we don't build CONFIG_SMP=n kernels +27599aacbaefcbf2af7b06b0029459bbf682000d # break kabi: fbdev: Hot-unplug firmware fb devices on forced removal +8b766b0f8eece55155146f7628610ce54a065e0f # not required on SLE15-SP4: sysfb: Enable boot time VESA graphic mode selection +26817fb7b066b21c66cd41d75ed2137e046045be # removes required interface: Revert "fbdev: fbmem: add a helper to determine if an aperture is used by a fw fb" +a157802359f7451ed8046b2b6dbaca187797e062 # not relevant in our configurations +2618a0dae09ef37728dab89ff60418cbe25ae6bd # silences the warning, ignore +c57094a6e1ed5dd2d6401f79b8e6da34dd28f959 # doesn't apply, not needed (fixes a mess, not a bug) +e151db8ecfb019b7da31d076130a794574c89f6f # was reverted +1d258758cf06a0734482989911d184dd5837ed4e # this is the revert of the above +4ef87d8f10aa375604b98c4e555f671d11e4111f # Duplicate of d47255d3f87338164762ac56df1f28d751e27246: drm/amdgpu: Fix resource leak on probe error path +655c167edc8c260b6df08bdcfaca8afde0efbeb6 # not applicable: drm/amd/display: Fix wrong format specifier in amdgpu_dm.c +59050d783848d9b62e9d8fb6ce0cd00771c2bf87 # not required: drm/bridge: Add stubs for devm_drm_of_get_bridge when OF is disabled +30ea703a38ef76ca119673cd8bdd05c6e068e2ac # not needed - a -Wmissing-prototypes fix +255584b138343d4a28c6d25bd82d04b09460d672 # clk:ti: reverted in 5.15 stable below +f7b16f51753a845b08e977184fb0b76b145ae0ba # clk:ti: reverting the above in 5.15.y diff --git a/config/arm64/default b/config/arm64/default index bdef2aa..7cbf6e8 100644 --- a/config/arm64/default +++ b/config/arm64/default @@ -672,6 +672,7 @@ CONFIG_TURRIS_MOX_RWTM=m CONFIG_ARM_FFA_TRANSPORT=m CONFIG_ARM_FFA_SMCCC=y CONFIG_TEE_BNXT_FW=m +CONFIG_CS_DSP=m # CONFIG_GOOGLE_FIRMWARE is not set # @@ -927,10 +928,6 @@ 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_CYC_COMPLEXITY is not set -# 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 @@ -3907,7 +3904,6 @@ CONFIG_IWLWIFI_LEDS=y CONFIG_IWLDVM=m CONFIG_IWLMVM=m CONFIG_IWLWIFI_OPMODE_MODULAR=y -# CONFIG_IWLWIFI_BCAST_FILTERING is not set # # Debugging Options @@ -7197,6 +7193,7 @@ 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 @@ -7345,6 +7342,10 @@ CONFIG_SND_HDA_RECONFIG=y CONFIG_SND_HDA_INPUT_BEEP=y CONFIG_SND_HDA_INPUT_BEEP_MODE=1 CONFIG_SND_HDA_PATCH_LOADER=y +CONFIG_SND_HDA_SCODEC_CS35L41=m +CONFIG_SND_HDA_CS_DSP_CONTROLS=m +CONFIG_SND_HDA_SCODEC_CS35L41_I2C=m +CONFIG_SND_HDA_SCODEC_CS35L41_SPI=m CONFIG_SND_HDA_CODEC_REALTEK=m CONFIG_SND_HDA_CODEC_ANALOG=m CONFIG_SND_HDA_CODEC_SIGMATEL=m @@ -7621,6 +7622,7 @@ CONFIG_SND_SOC_I2C_AND_SPI=m # CODEC drivers # CONFIG_SND_SOC_WM_HUBS=m +CONFIG_SND_SOC_WM_ADSP=m CONFIG_SND_SOC_AC97_CODEC=m CONFIG_SND_SOC_ADAU_UTILS=m # CONFIG_SND_SOC_ADAU1372_I2C is not set @@ -7653,6 +7655,10 @@ CONFIG_SND_SOC_CS35L33=m CONFIG_SND_SOC_CS35L34=m CONFIG_SND_SOC_CS35L35=m CONFIG_SND_SOC_CS35L36=m +CONFIG_SND_SOC_CS35L41_LIB=m +CONFIG_SND_SOC_CS35L41=m +CONFIG_SND_SOC_CS35L41_SPI=m +CONFIG_SND_SOC_CS35L41_I2C=m CONFIG_SND_SOC_CS42L42=m CONFIG_SND_SOC_CS42L51=m CONFIG_SND_SOC_CS42L51_I2C=m @@ -11296,12 +11302,8 @@ CONFIG_LSM="integrity,apparmor" CONFIG_CC_HAS_AUTO_VAR_INIT_PATTERN=y CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO=y 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_INIT_STACK_ALL_PATTERN is not set # CONFIG_INIT_STACK_ALL_ZERO 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 diff --git a/config/arm64/kvmsmall b/config/arm64/kvmsmall index 6e64408..174443f 100644 --- a/config/arm64/kvmsmall +++ b/config/arm64/kvmsmall @@ -61,6 +61,7 @@ CONFIG_BLK_DEV_PMEM=y # CONFIG_COMMON_CLK_SI5341 is not set # CONFIG_CRAMFS is not set # CONFIG_CRYPTO_HW is not set +# CONFIG_CS_DSP is not set # CONFIG_DAVICOM_PHY is not set # CONFIG_DCB is not set # CONFIG_DEVPORT is not set diff --git a/config/armv7hl/default b/config/armv7hl/default index e9236f5..5ce07e2 100644 --- a/config/armv7hl/default +++ b/config/armv7hl/default @@ -699,7 +699,6 @@ CONFIG_ALIGNMENT_TRAP=y # CONFIG_PARAVIRT is not set # CONFIG_PARAVIRT_TIME_ACCOUNTING is not set # CONFIG_XEN is not set -# CONFIG_STACKPROTECTOR_PER_TASK is not set # end of Kernel Features # @@ -879,6 +878,7 @@ CONFIG_TI_SCI_PROTOCOL=m # CONFIG_TURRIS_MOX_RWTM is not set # CONFIG_BCM47XX_NVRAM is not set CONFIG_TEE_BNXT_FW=m +CONFIG_CS_DSP=m # CONFIG_GOOGLE_FIRMWARE is not set # @@ -1016,10 +1016,6 @@ 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_CYC_COMPLEXITY is not set -# 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 @@ -7164,6 +7160,7 @@ CONFIG_HDMI=y # CONFIG_DUMMY_CONSOLE=y 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 @@ -7568,6 +7565,7 @@ CONFIG_SND_SOC_I2C_AND_SPI=m # CODEC drivers # CONFIG_SND_SOC_WM_HUBS=m +CONFIG_SND_SOC_WM_ADSP=m CONFIG_SND_SOC_AC97_CODEC=m CONFIG_SND_SOC_ADAU_UTILS=m # CONFIG_SND_SOC_ADAU1372_I2C is not set @@ -7600,6 +7598,10 @@ CONFIG_SND_SOC_CS35L33=m CONFIG_SND_SOC_CS35L34=m CONFIG_SND_SOC_CS35L35=m CONFIG_SND_SOC_CS35L36=m +CONFIG_SND_SOC_CS35L41_LIB=m +CONFIG_SND_SOC_CS35L41=m +CONFIG_SND_SOC_CS35L41_SPI=m +CONFIG_SND_SOC_CS35L41_I2C=m CONFIG_SND_SOC_CS42L42=m CONFIG_SND_SOC_CS42L51=m CONFIG_SND_SOC_CS42L51_I2C=m @@ -11145,9 +11147,6 @@ CONFIG_LSM="integrity,apparmor" CONFIG_CC_HAS_AUTO_VAR_INIT_PATTERN=y CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO=y 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_INIT_STACK_ALL_PATTERN is not set # CONFIG_INIT_STACK_ALL_ZERO is not set # CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set diff --git a/config/ppc64le/default b/config/ppc64le/default index bb428d1..83f150b 100644 --- a/config/ppc64le/default +++ b/config/ppc64le/default @@ -664,10 +664,6 @@ 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_CYC_COMPLEXITY is not set -# 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 @@ -3132,7 +3128,6 @@ CONFIG_IWLWIFI_LEDS=y CONFIG_IWLDVM=m CONFIG_IWLMVM=m CONFIG_IWLWIFI_OPMODE_MODULAR=y -# CONFIG_IWLWIFI_BCAST_FILTERING is not set # # Debugging Options @@ -4537,6 +4532,7 @@ 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 @@ -6087,9 +6083,6 @@ CONFIG_LSM="integrity,apparmor" CONFIG_CC_HAS_AUTO_VAR_INIT_PATTERN=y CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO=y 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_INIT_STACK_ALL_PATTERN is not set # CONFIG_INIT_STACK_ALL_ZERO is not set # CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set diff --git a/config/s390x/default b/config/s390x/default index 53aa51c..16dd565 100644 --- a/config/s390x/default +++ b/config/s390x/default @@ -526,10 +526,6 @@ 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_CYC_COMPLEXITY is not set -# 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 @@ -2885,6 +2881,7 @@ 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 # end of Console display driver support @@ -3697,9 +3694,6 @@ CONFIG_LSM="integrity,apparmor" CONFIG_CC_HAS_AUTO_VAR_INIT_PATTERN=y CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO=y 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_INIT_STACK_ALL_PATTERN is not set # CONFIG_INIT_STACK_ALL_ZERO is not set # CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set diff --git a/config/s390x/zfcpdump b/config/s390x/zfcpdump index 2f77386..65dffff 100644 --- a/config/s390x/zfcpdump +++ b/config/s390x/zfcpdump @@ -451,9 +451,6 @@ 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 @@ -1261,9 +1258,6 @@ CONFIG_LSM="" CONFIG_CC_HAS_AUTO_VAR_INIT_PATTERN=y CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO=y 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_INIT_STACK_ALL_PATTERN is not set # CONFIG_INIT_STACK_ALL_ZERO is not set # CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set diff --git a/config/x86_64/default b/config/x86_64/default index 6fda052..426854b 100644 --- a/config/x86_64/default +++ b/config/x86_64/default @@ -727,6 +727,7 @@ CONFIG_FW_CFG_SYSFS=m CONFIG_FW_CFG_SYSFS_CMDLINE=y CONFIG_SYSFB=y CONFIG_SYSFB_SIMPLEFB=y +CONFIG_CS_DSP=m # CONFIG_GOOGLE_FIRMWARE is not set # @@ -925,10 +926,6 @@ 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_CYC_COMPLEXITY is not set -# 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 @@ -3742,7 +3739,6 @@ CONFIG_IWLWIFI_LEDS=y CONFIG_IWLDVM=m CONFIG_IWLMVM=m CONFIG_IWLWIFI_OPMODE_MODULAR=y -# CONFIG_IWLWIFI_BCAST_FILTERING is not set # # Debugging Options @@ -6463,6 +6459,7 @@ 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 @@ -6617,6 +6614,10 @@ CONFIG_SND_HDA_RECONFIG=y CONFIG_SND_HDA_INPUT_BEEP=y CONFIG_SND_HDA_INPUT_BEEP_MODE=1 CONFIG_SND_HDA_PATCH_LOADER=y +CONFIG_SND_HDA_SCODEC_CS35L41=m +CONFIG_SND_HDA_CS_DSP_CONTROLS=m +CONFIG_SND_HDA_SCODEC_CS35L41_I2C=m +CONFIG_SND_HDA_SCODEC_CS35L41_SPI=m CONFIG_SND_HDA_CODEC_REALTEK=m CONFIG_SND_HDA_CODEC_ANALOG=m CONFIG_SND_HDA_CODEC_SIGMATEL=m @@ -6830,6 +6831,7 @@ CONFIG_SND_SOC_I2C_AND_SPI=m # # CODEC drivers # +CONFIG_SND_SOC_WM_ADSP=m # CONFIG_SND_SOC_AC97_CODEC is not set # CONFIG_SND_SOC_ADAU1372_I2C is not set # CONFIG_SND_SOC_ADAU1372_SPI is not set @@ -6856,6 +6858,10 @@ CONFIG_SND_SOC_CROS_EC_CODEC=m CONFIG_SND_SOC_CS35L34=m CONFIG_SND_SOC_CS35L35=m CONFIG_SND_SOC_CS35L36=m +CONFIG_SND_SOC_CS35L41_LIB=m +CONFIG_SND_SOC_CS35L41=m +CONFIG_SND_SOC_CS35L41_SPI=m +CONFIG_SND_SOC_CS35L41_I2C=m CONFIG_SND_SOC_CS42L42=m # CONFIG_SND_SOC_CS42L51_I2C is not set # CONFIG_SND_SOC_CS42L52 is not set @@ -7572,6 +7578,7 @@ CONFIG_TYPEC_TCPCI=m CONFIG_TYPEC_RT1711H=m CONFIG_TYPEC_TCPCI_MAXIM=m CONFIG_TYPEC_FUSB302=m +CONFIG_TYPEC_WCOVE=m CONFIG_TYPEC_UCSI=m CONFIG_UCSI_CCG=m CONFIG_UCSI_ACPI=m @@ -8002,6 +8009,7 @@ CONFIG_VIRT_DRIVERS=y CONFIG_VBOXGUEST=m CONFIG_NITRO_ENCLAVES=m CONFIG_ACRN_HSM=m +CONFIG_SEV_GUEST=m CONFIG_VIRTIO=y CONFIG_ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS=y CONFIG_VIRTIO_PCI_LIB=y @@ -8288,7 +8296,7 @@ CONFIG_SONY_LAPTOP=m CONFIG_SONYPI_COMPAT=y CONFIG_SYSTEM76_ACPI=m CONFIG_TOPSTAR_LAPTOP=m -CONFIG_I2C_MULTI_INSTANTIATE=m +CONFIG_SERIAL_MULTI_INSTANTIATE=m CONFIG_MLX_PLATFORM=m CONFIG_TOUCHSCREEN_DMI=y CONFIG_FW_ATTR_CLASS=m @@ -9733,12 +9741,8 @@ CONFIG_LSM="integrity,apparmor" CONFIG_CC_HAS_AUTO_VAR_INIT_PATTERN=y CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO=y 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_INIT_STACK_ALL_PATTERN is not set # CONFIG_INIT_STACK_ALL_ZERO 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 diff --git a/config/x86_64/kvmsmall b/config/x86_64/kvmsmall index dc74a20..c11be61 100644 --- a/config/x86_64/kvmsmall +++ b/config/x86_64/kvmsmall @@ -74,6 +74,7 @@ CONFIG_BLK_DEV_PMEM=y # CONFIG_CRYPTO_CHACHA20POLY1305 is not set # CONFIG_CRYPTO_HW is not set # CONFIG_CRYPTO_LZ4 is not set +# CONFIG_CS_DSP is not set # CONFIG_CX_ECAT is not set # CONFIG_DAVICOM_PHY is not set # CONFIG_DCB is not set diff --git a/kabi/severities b/kabi/severities index 59729f7..d080082 100644 --- a/kabi/severities +++ b/kabi/severities @@ -94,3 +94,6 @@ drivers/net/ethernet/marvell/octeontx2/* PASS # dropped due to new enum added (bsc#1202471) drivers/scsi/hisi_sas/* PASS + +# CS35L41 HD-audio local dependencies +sound/pci/hda/snd-hda-cs-dsp-ctls PASS diff --git a/patches.suse/0001-drm-amdgpu-gfx9-switch-to-golden-tsc-registers-for-r.patch b/patches.suse/0001-drm-amdgpu-gfx9-switch-to-golden-tsc-registers-for-r.patch new file mode 100644 index 0000000..1927f98 --- /dev/null +++ b/patches.suse/0001-drm-amdgpu-gfx9-switch-to-golden-tsc-registers-for-r.patch @@ -0,0 +1,83 @@ +From 53af98c091bc42fd9ec64cfabc40da4e5f3aae93 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Thu, 18 Nov 2021 14:50:37 -0500 +Subject: drm/amdgpu/gfx9: switch to golden tsc registers for renoir+ +Git-commit: 53af98c091bc42fd9ec64cfabc40da4e5f3aae93 +Patch-mainline: v5.16-rc3 +References: bsc#1152472 + +Renoir and newer gfx9 APUs have new TSC register that is +not part of the gfxoff tile, so it can be read without +needing to disable gfx off. + +Acked-by: Luben Tuikov +Signed-off-by: Alex Deucher +Acked-by: Thomas Zimmermann +--- + drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 46 +++++++++++++++++++++++++--------- + 1 file changed, 35 insertions(+), 11 deletions(-) + +--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +@@ -140,6 +140,11 @@ MODULE_FIRMWARE("amdgpu/aldebaran_rlc.bi + #define mmTCP_CHAN_STEER_5_ARCT 0x0b0c + #define mmTCP_CHAN_STEER_5_ARCT_BASE_IDX 0 + ++#define mmGOLDEN_TSC_COUNT_UPPER_Renoir 0x0025 ++#define mmGOLDEN_TSC_COUNT_UPPER_Renoir_BASE_IDX 1 ++#define mmGOLDEN_TSC_COUNT_LOWER_Renoir 0x0026 ++#define mmGOLDEN_TSC_COUNT_LOWER_Renoir_BASE_IDX 1 ++ + enum ta_ras_gfx_subblock { + /*CPC*/ + TA_RAS_BLOCK__GFX_CPC_INDEX_START = 0, +@@ -4227,19 +4232,38 @@ failed_kiq_read: + + static uint64_t gfx_v9_0_get_gpu_clock_counter(struct amdgpu_device *adev) + { +- uint64_t clock; ++ uint64_t clock, clock_lo, clock_hi, hi_check; + +- amdgpu_gfx_off_ctrl(adev, false); +- mutex_lock(&adev->gfx.gpu_clock_mutex); +- if (adev->asic_type == CHIP_VEGA10 && amdgpu_sriov_runtime(adev)) { +- clock = gfx_v9_0_kiq_read_clock(adev); +- } else { +- WREG32_SOC15(GC, 0, mmRLC_CAPTURE_GPU_CLOCK_COUNT, 1); +- clock = (uint64_t)RREG32_SOC15(GC, 0, mmRLC_GPU_CLOCK_COUNT_LSB) | +- ((uint64_t)RREG32_SOC15(GC, 0, mmRLC_GPU_CLOCK_COUNT_MSB) << 32ULL); ++ switch (adev->asic_type) { ++ case CHIP_RENOIR: ++ preempt_disable(); ++ clock_hi = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER_Renoir); ++ clock_lo = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER_Renoir); ++ hi_check = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER_Renoir); ++ /* The SMUIO TSC clock frequency is 100MHz, which sets 32-bit carry over ++ * roughly every 42 seconds. ++ */ ++ if (hi_check != clock_hi) { ++ clock_lo = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER_Renoir); ++ clock_hi = hi_check; ++ } ++ preempt_enable(); ++ clock = clock_lo | (clock_hi << 32ULL); ++ break; ++ default: ++ amdgpu_gfx_off_ctrl(adev, false); ++ mutex_lock(&adev->gfx.gpu_clock_mutex); ++ if (adev->asic_type == CHIP_VEGA10 && amdgpu_sriov_runtime(adev)) { ++ clock = gfx_v9_0_kiq_read_clock(adev); ++ } else { ++ WREG32_SOC15(GC, 0, mmRLC_CAPTURE_GPU_CLOCK_COUNT, 1); ++ clock = (uint64_t)RREG32_SOC15(GC, 0, mmRLC_GPU_CLOCK_COUNT_LSB) | ++ ((uint64_t)RREG32_SOC15(GC, 0, mmRLC_GPU_CLOCK_COUNT_MSB) << 32ULL); ++ } ++ mutex_unlock(&adev->gfx.gpu_clock_mutex); ++ amdgpu_gfx_off_ctrl(adev, true); ++ break; + } +- mutex_unlock(&adev->gfx.gpu_clock_mutex); +- amdgpu_gfx_off_ctrl(adev, true); + return clock; + } + diff --git a/patches.suse/0001-parisc-sticon-fix-reverse-colors.patch b/patches.suse/0001-parisc-sticon-fix-reverse-colors.patch new file mode 100644 index 0000000..9e29d27 --- /dev/null +++ b/patches.suse/0001-parisc-sticon-fix-reverse-colors.patch @@ -0,0 +1,49 @@ +From bec05f33ebc1006899c6d3e59a00c58881fe7626 Mon Sep 17 00:00:00 2001 +From: Sven Schnelle +Date: Sun, 14 Nov 2021 17:08:17 +0100 +Subject: parisc/sticon: fix reverse colors +Git-commit: bec05f33ebc1006899c6d3e59a00c58881fe7626 +Patch-mainline: v5.16-rc2 +References: bsc#1152489 + +sticon_build_attr() checked the reverse argument and flipped +background and foreground color, but returned the non-reverse +value afterwards. Fix this and also add two local variables +for foreground and background color to make the code easier +to read. + +Signed-off-by: Sven Schnelle +Cc: +Signed-off-by: Helge Deller +Acked-by: Thomas Zimmermann +--- + drivers/video/console/sticon.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c +index 1b451165311c..40496e9e9b43 100644 +--- a/drivers/video/console/sticon.c ++++ b/drivers/video/console/sticon.c +@@ -332,13 +332,13 @@ static u8 sticon_build_attr(struct vc_data *conp, u8 color, + bool blink, bool underline, bool reverse, + bool italic) + { +- u8 attr = ((color & 0x70) >> 1) | ((color & 7)); ++ u8 fg = color & 7; ++ u8 bg = (color & 0x70) >> 4; + +- if (reverse) { +- color = ((color >> 3) & 0x7) | ((color & 0x7) << 3); +- } +- +- return attr; ++ if (reverse) ++ return (fg << 3) | bg; ++ else ++ return (bg << 3) | fg; + } + + static void sticon_invert_region(struct vc_data *conp, u16 *p, int count) +-- +2.37.3 + diff --git a/patches.suse/0002-drm-amd-display-Changed-pipe-split-policy-to-allow-f.patch b/patches.suse/0002-drm-amd-display-Changed-pipe-split-policy-to-allow-f.patch new file mode 100644 index 0000000..88a2bd9 --- /dev/null +++ b/patches.suse/0002-drm-amd-display-Changed-pipe-split-policy-to-allow-f.patch @@ -0,0 +1,122 @@ +From ee2698cf79cc759a397c61086c758d4cc85938bf Mon Sep 17 00:00:00 2001 +From: Angus Wang +Date: Thu, 9 Dec 2021 17:27:01 -0500 +Subject: drm/amd/display: Changed pipe split policy to allow for multi-display + pipe split +Git-commit: ee2698cf79cc759a397c61086c758d4cc85938bf +Patch-mainline: v5.16-rc8 +References: bsc#1152472 + +[WHY] +Current implementation of pipe split policy prevents pipe split with +multiple displays connected, which caused the MCLK speed to be stuck at +max + +[HOW] +Changed the pipe split policies so that pipe split is allowed for +multi-display configurations + +Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1522 +Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1709 +Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1655 +Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1403 + +Note this is a backport of this commit from amdgpu drm-next for 5.16. + +Tested-by: Daniel Wheeler +Reviewed-by: Aric Cyr +Acked-by: Rodrigo Siqueira +Signed-off-by: Angus Wang +Signed-off-by: Alex Deucher +Cc: stable@vger.kernel.org +Acked-by: Thomas Zimmermann +--- + drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 2 +- + drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c | 2 +- + drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c | 2 +- + drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c | 2 +- + drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c | 2 +- + drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c | 2 +- + 8 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +index 3883f918b3bb2..83f5d9aaffcb6 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +@@ -1069,7 +1069,7 @@ static const struct dc_debug_options debug_defaults_drv = { + .timing_trace = false, + .clock_trace = true, + .disable_pplib_clock_request = true, +- .pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP, ++ .pipe_split_policy = MPC_SPLIT_DYNAMIC, + .force_single_disp_pipe_split = false, + .disable_dcc = DCC_ENABLE, + .vsr_support = true, +diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +index d452a0d1777ea..79313d1ab5d95 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +@@ -874,7 +874,7 @@ static const struct dc_debug_options debug_defaults_drv = { + .clock_trace = true, + .disable_pplib_clock_request = true, + .min_disp_clk_khz = 100000, +- .pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP, ++ .pipe_split_policy = MPC_SPLIT_DYNAMIC, + .force_single_disp_pipe_split = false, + .disable_dcc = DCC_ENABLE, + .vsr_support = true, +diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c +index 79a66e0c43039..98852b5862956 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c +@@ -840,7 +840,7 @@ static const struct dc_debug_options debug_defaults_drv = { + .timing_trace = false, + .clock_trace = true, + .disable_pplib_clock_request = true, +- .pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP, ++ .pipe_split_policy = MPC_SPLIT_DYNAMIC, + .force_single_disp_pipe_split = false, + .disable_dcc = DCC_ENABLE, + .vsr_support = true, +diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c +index fbaa03f26d8bf..e472b729d8690 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c +@@ -686,7 +686,7 @@ static const struct dc_debug_options debug_defaults_drv = { + .disable_clock_gate = true, + .disable_pplib_clock_request = true, + .disable_pplib_wm_range = true, +- .pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP, ++ .pipe_split_policy = MPC_SPLIT_DYNAMIC, + .force_single_disp_pipe_split = false, + .disable_dcc = DCC_ENABLE, + .vsr_support = true, +diff --git a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c +index fcf96cf08c761..16e7059393fac 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c +@@ -211,7 +211,7 @@ static const struct dc_debug_options debug_defaults_drv = { + .timing_trace = false, + .clock_trace = true, + .disable_pplib_clock_request = true, +- .pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP, ++ .pipe_split_policy = MPC_SPLIT_DYNAMIC, + .force_single_disp_pipe_split = false, + .disable_dcc = DCC_ENABLE, + .vsr_support = true, +diff --git a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c +index 4a9b640236755..87cec14b78704 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c +@@ -193,7 +193,7 @@ static const struct dc_debug_options debug_defaults_drv = { + .timing_trace = false, + .clock_trace = true, + .disable_pplib_clock_request = true, +- .pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP, ++ .pipe_split_policy = MPC_SPLIT_DYNAMIC, + .force_single_disp_pipe_split = false, + .disable_dcc = DCC_ENABLE, + .vsr_support = true, +-- +2.37.3 + diff --git a/patches.suse/0002-drm-i915-hdmi-convert-intel_hdmi_to_dev-to-intel_hdm.patch b/patches.suse/0002-drm-i915-hdmi-convert-intel_hdmi_to_dev-to-intel_hdm.patch new file mode 100644 index 0000000..d1bf507 --- /dev/null +++ b/patches.suse/0002-drm-i915-hdmi-convert-intel_hdmi_to_dev-to-intel_hdm.patch @@ -0,0 +1,82 @@ +From 7ceb751b615900086eed1d65955933923f127d99 Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Tue, 21 Sep 2021 14:02:44 +0300 +Subject: drm/i915/hdmi: convert intel_hdmi_to_dev to intel_hdmi_to_i915 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Git-commit: 7ceb751b615900086eed1d65955933923f127d99 +Patch-mainline: v5.16-rc1 +References: bsc#1152489 + +Prefer i915 over drm pointer. + +Reviewed-by: Ville Syrjälä +Signed-off-by: Jani Nikula +Link: https://patchwork.freedesktop.org/patch/msgid/20210921110244.8666-1-jani.nikula@intel.com +Acked-by: Thomas Zimmermann +--- + drivers/gpu/drm/i915/display/intel_hdmi.c | 16 +++++++--------- + 1 file changed, 7 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c +index 468a107aaabc8..d2e61f6c6e08e 100644 +--- a/drivers/gpu/drm/i915/display/intel_hdmi.c ++++ b/drivers/gpu/drm/i915/display/intel_hdmi.c +@@ -53,21 +53,20 @@ + #include "intel_panel.h" + #include "intel_snps_phy.h" + +-static struct drm_device *intel_hdmi_to_dev(struct intel_hdmi *intel_hdmi) ++static struct drm_i915_private *intel_hdmi_to_i915(struct intel_hdmi *intel_hdmi) + { +- return hdmi_to_dig_port(intel_hdmi)->base.base.dev; ++ return to_i915(hdmi_to_dig_port(intel_hdmi)->base.base.dev); + } + + static void + assert_hdmi_port_disabled(struct intel_hdmi *intel_hdmi) + { +- struct drm_device *dev = intel_hdmi_to_dev(intel_hdmi); +- struct drm_i915_private *dev_priv = to_i915(dev); ++ struct drm_i915_private *dev_priv = intel_hdmi_to_i915(intel_hdmi); + u32 enabled_bits; + + enabled_bits = HAS_DDI(dev_priv) ? DDI_BUF_CTL_ENABLE : SDVO_ENABLE; + +- drm_WARN(dev, ++ drm_WARN(&dev_priv->drm, + intel_de_read(dev_priv, intel_hdmi->hdmi_reg) & enabled_bits, + "HDMI port enabled, expecting disabled\n"); + } +@@ -1246,7 +1245,7 @@ static void hsw_set_infoframes(struct intel_encoder *encoder, + + void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable) + { +- struct drm_i915_private *dev_priv = to_i915(intel_hdmi_to_dev(hdmi)); ++ struct drm_i915_private *dev_priv = intel_hdmi_to_i915(hdmi); + struct i2c_adapter *adapter = + intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus); + +@@ -1830,7 +1829,7 @@ hdmi_port_clock_valid(struct intel_hdmi *hdmi, + int clock, bool respect_downstream_limits, + bool has_hdmi_sink) + { +- struct drm_i915_private *dev_priv = to_i915(intel_hdmi_to_dev(hdmi)); ++ struct drm_i915_private *dev_priv = intel_hdmi_to_i915(hdmi); + + if (clock < 25000) + return MODE_CLOCK_LOW; +@@ -1946,8 +1945,7 @@ intel_hdmi_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) + { + struct intel_hdmi *hdmi = intel_attached_hdmi(to_intel_connector(connector)); +- struct drm_device *dev = intel_hdmi_to_dev(hdmi); +- struct drm_i915_private *dev_priv = to_i915(dev); ++ struct drm_i915_private *dev_priv = intel_hdmi_to_i915(hdmi); + enum drm_mode_status status; + int clock = mode->clock; + int max_dotclk = to_i915(connector->dev)->max_dotclk_freq; +-- +2.37.3 + diff --git a/patches.suse/0002-fbcon-Add-option-to-enable-legacy-hardware-accelerat.patch b/patches.suse/0002-fbcon-Add-option-to-enable-legacy-hardware-accelerat.patch new file mode 100644 index 0000000..cbfac91 --- /dev/null +++ b/patches.suse/0002-fbcon-Add-option-to-enable-legacy-hardware-accelerat.patch @@ -0,0 +1,389 @@ +From a3f781a9d6114c1d1e01defb7aa234dec45d2a5f Mon Sep 17 00:00:00 2001 +From: Helge Deller +Date: Wed, 2 Feb 2022 14:55:31 +0100 +Subject: fbcon: Add option to enable legacy hardware acceleration +Git-commit: a3f781a9d6114c1d1e01defb7aa234dec45d2a5f +Patch-mainline: v5.17-rc3 +References: bsc#1152472 + +Add a config option CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION to +enable bitblt and fillrect hardware acceleration in the framebuffer +console. If disabled, such acceleration will not be used, even if it is +supported by the graphics hardware driver. + +If you plan to use DRM as your main graphics output system, you should +disable this option since it will prevent compiling in code which isn't +used later on when DRM takes over. + +For all other configurations, e.g. if none of your graphic cards support +DRM (yet), DRM isn't available for your architecture, or you can't be +sure that the graphic card in the target system will support DRM, you +most likely want to enable this option. + +In the non-accelerated case (e.g. when DRM is used), the inlined +fb_scrollmode() function is hardcoded to return SCROLL_REDRAW and as such the +compiler is able to optimize much unneccesary code away. + +In this v3 patch version I additionally changed the GETVYRES() and GETVXRES() +macros to take a pointer to the fbcon_display struct. This fixes the build when +console rotation is enabled and helps the compiler again to optimize out code. + +Signed-off-by: Helge Deller +Cc: stable@vger.kernel.org # v5.10+ +Signed-off-by: Helge Deller +Signed-off-by: Daniel Vetter +Link: https://patchwork.freedesktop.org/patch/msgid/20220202135531.92183-4-deller@gmx.de +Acked-by: Thomas Zimmermann +--- + drivers/video/console/Kconfig | 20 +++++++++++++ + drivers/video/fbdev/core/fbcon.c | 39 ++++++++++++++++++------- + drivers/video/fbdev/core/fbcon.h | 15 +++++++++- + drivers/video/fbdev/core/fbcon_ccw.c | 10 +++---- + drivers/video/fbdev/core/fbcon_cw.c | 10 +++---- + drivers/video/fbdev/core/fbcon_rotate.h | 4 +-- + drivers/video/fbdev/core/fbcon_ud.c | 20 ++++++------- + 7 files changed, 84 insertions(+), 34 deletions(-) + +diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig +index 840d9813b0bc..fcc46380e7c9 100644 +--- a/drivers/video/console/Kconfig ++++ b/drivers/video/console/Kconfig +@@ -78,6 +78,26 @@ config FRAMEBUFFER_CONSOLE + help + Low-level framebuffer-based console driver. + ++config FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION ++ bool "Enable legacy fbcon hardware acceleration code" ++ depends on FRAMEBUFFER_CONSOLE ++ default y if PARISC ++ default n ++ help ++ This option enables the fbcon (framebuffer text-based) hardware ++ acceleration for graphics drivers which were written for the fbdev ++ graphics interface. ++ ++ On modern machines, on mainstream machines (like x86-64) or when ++ using a modern Linux distribution those fbdev drivers usually aren't used. ++ So enabling this option wouldn't have any effect, which is why you want ++ to disable this option on such newer machines. ++ ++ If you compile this kernel for older machines which still require the ++ fbdev drivers, you may want to say Y. ++ ++ If unsure, select n. ++ + config FRAMEBUFFER_CONSOLE_DETECT_PRIMARY + bool "Map the console to the primary display device" + depends on FRAMEBUFFER_CONSOLE +diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c +index 0cc2a36b674a..f36829eeb5a9 100644 +--- a/drivers/video/fbdev/core/fbcon.c ++++ b/drivers/video/fbdev/core/fbcon.c +@@ -1136,11 +1136,13 @@ static void fbcon_init(struct vc_data *vc, int init) + + ops->graphics = 0; + ++#ifdef CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION + if ((cap & FBINFO_HWACCEL_COPYAREA) && + !(cap & FBINFO_HWACCEL_DISABLED)) + p->scrollmode = SCROLL_MOVE; + else /* default to something safe */ + p->scrollmode = SCROLL_REDRAW; ++#endif + + /* + * ++guenther: console.c:vc_allocate() relies on initializing +@@ -1705,7 +1707,7 @@ static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b, + count = vc->vc_rows; + if (logo_shown >= 0) + goto redraw_up; +- switch (p->scrollmode) { ++ switch (fb_scrollmode(p)) { + case SCROLL_MOVE: + fbcon_redraw_blit(vc, info, p, t, b - t - count, + count); +@@ -1795,7 +1797,7 @@ static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b, + count = vc->vc_rows; + if (logo_shown >= 0) + goto redraw_down; +- switch (p->scrollmode) { ++ switch (fb_scrollmode(p)) { + case SCROLL_MOVE: + fbcon_redraw_blit(vc, info, p, b - 1, b - t - count, + -count); +@@ -1946,12 +1948,12 @@ static void fbcon_bmove_rec(struct vc_data *vc, struct fbcon_display *p, int sy, + height, width); + } + +-static void updatescrollmode(struct fbcon_display *p, ++static void updatescrollmode_accel(struct fbcon_display *p, + struct fb_info *info, + struct vc_data *vc) + { ++#ifdef CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION + struct fbcon_ops *ops = info->fbcon_par; +- int fh = vc->vc_font.height; + int cap = info->flags; + u16 t = 0; + int ypan = FBCON_SWAP(ops->rotate, info->fix.ypanstep, +@@ -1972,12 +1974,6 @@ static void updatescrollmode(struct fbcon_display *p, + int fast_imageblit = (cap & FBINFO_HWACCEL_IMAGEBLIT) && + !(cap & FBINFO_HWACCEL_DISABLED); + +- p->vrows = vyres/fh; +- if (yres > (fh * (vc->vc_rows + 1))) +- p->vrows -= (yres - (fh * vc->vc_rows)) / fh; +- if ((yres % fh) && (vyres % fh < yres % fh)) +- p->vrows--; +- + if (good_wrap || good_pan) { + if (reading_fast || fast_copyarea) + p->scrollmode = good_wrap ? +@@ -1991,6 +1987,27 @@ static void updatescrollmode(struct fbcon_display *p, + else + p->scrollmode = SCROLL_REDRAW; + } ++#endif ++} ++ ++static void updatescrollmode(struct fbcon_display *p, ++ struct fb_info *info, ++ struct vc_data *vc) ++{ ++ struct fbcon_ops *ops = info->fbcon_par; ++ int fh = vc->vc_font.height; ++ int yres = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); ++ int vyres = FBCON_SWAP(ops->rotate, info->var.yres_virtual, ++ info->var.xres_virtual); ++ ++ p->vrows = vyres/fh; ++ if (yres > (fh * (vc->vc_rows + 1))) ++ p->vrows -= (yres - (fh * vc->vc_rows)) / fh; ++ if ((yres % fh) && (vyres % fh < yres % fh)) ++ p->vrows--; ++ ++ /* update scrollmode in case hardware acceleration is used */ ++ updatescrollmode_accel(p, info, vc); + } + + #define PITCH(w) (((w) + 7) >> 3) +@@ -2148,7 +2165,7 @@ static int fbcon_switch(struct vc_data *vc) + + updatescrollmode(p, info, vc); + +- switch (p->scrollmode) { ++ switch (fb_scrollmode(p)) { + case SCROLL_WRAP_MOVE: + scrollback_phys_max = p->vrows - vc->vc_rows; + break; +diff --git a/drivers/video/fbdev/core/fbcon.h b/drivers/video/fbdev/core/fbcon.h +index 5246d0f2574b..969d41ecede5 100644 +--- a/drivers/video/fbdev/core/fbcon.h ++++ b/drivers/video/fbdev/core/fbcon.h +@@ -29,7 +29,9 @@ struct fbcon_display { + /* Filled in by the low-level console driver */ + const u_char *fontdata; + int userfont; /* != 0 if fontdata kmalloc()ed */ +- u_short scrollmode; /* Scroll Method */ ++#ifdef CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION ++ u_short scrollmode; /* Scroll Method, use fb_scrollmode() */ ++#endif + u_short inverse; /* != 0 text black on white as default */ + short yscroll; /* Hardware scrolling */ + int vrows; /* number of virtual rows */ +@@ -208,6 +210,17 @@ static inline int attr_col_ec(int shift, struct vc_data *vc, + #define SCROLL_REDRAW 0x004 + #define SCROLL_PAN_REDRAW 0x005 + ++static inline u_short fb_scrollmode(struct fbcon_display *fb) ++{ ++#ifdef CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION ++ return fb->scrollmode; ++#else ++ /* hardcoded to SCROLL_REDRAW if acceleration was disabled. */ ++ return SCROLL_REDRAW; ++#endif ++} ++ ++ + #ifdef CONFIG_FB_TILEBLITTING + extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info); + #endif +diff --git a/drivers/video/fbdev/core/fbcon_ccw.c b/drivers/video/fbdev/core/fbcon_ccw.c +index 9cd2c4b05c32..2789ace79634 100644 +--- a/drivers/video/fbdev/core/fbcon_ccw.c ++++ b/drivers/video/fbdev/core/fbcon_ccw.c +@@ -65,7 +65,7 @@ static void ccw_bmove(struct vc_data *vc, struct fb_info *info, int sy, + { + struct fbcon_ops *ops = info->fbcon_par; + struct fb_copyarea area; +- u32 vyres = GETVYRES(ops->p->scrollmode, info); ++ u32 vyres = GETVYRES(ops->p, info); + + area.sx = sy * vc->vc_font.height; + area.sy = vyres - ((sx + width) * vc->vc_font.width); +@@ -83,7 +83,7 @@ static void ccw_clear(struct vc_data *vc, struct fb_info *info, int sy, + struct fbcon_ops *ops = info->fbcon_par; + struct fb_fillrect region; + int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; +- u32 vyres = GETVYRES(ops->p->scrollmode, info); ++ u32 vyres = GETVYRES(ops->p, info); + + region.color = attr_bgcol_ec(bgshift,vc,info); + region.dx = sy * vc->vc_font.height; +@@ -140,7 +140,7 @@ static void ccw_putcs(struct vc_data *vc, struct fb_info *info, + u32 cnt, pitch, size; + u32 attribute = get_attribute(info, scr_readw(s)); + u8 *dst, *buf = NULL; +- u32 vyres = GETVYRES(ops->p->scrollmode, info); ++ u32 vyres = GETVYRES(ops->p, info); + + if (!ops->fontbuffer) + return; +@@ -229,7 +229,7 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, int mode, + int attribute, use_sw = vc->vc_cursor_type & CUR_SW; + int err = 1, dx, dy; + char *src; +- u32 vyres = GETVYRES(ops->p->scrollmode, info); ++ u32 vyres = GETVYRES(ops->p, info); + + if (!ops->fontbuffer) + return; +@@ -387,7 +387,7 @@ static int ccw_update_start(struct fb_info *info) + { + struct fbcon_ops *ops = info->fbcon_par; + u32 yoffset; +- u32 vyres = GETVYRES(ops->p->scrollmode, info); ++ u32 vyres = GETVYRES(ops->p, info); + int err; + + yoffset = (vyres - info->var.yres) - ops->var.xoffset; +diff --git a/drivers/video/fbdev/core/fbcon_cw.c b/drivers/video/fbdev/core/fbcon_cw.c +index 88d89fad3f05..86a254c1b2b7 100644 +--- a/drivers/video/fbdev/core/fbcon_cw.c ++++ b/drivers/video/fbdev/core/fbcon_cw.c +@@ -50,7 +50,7 @@ static void cw_bmove(struct vc_data *vc, struct fb_info *info, int sy, + { + struct fbcon_ops *ops = info->fbcon_par; + struct fb_copyarea area; +- u32 vxres = GETVXRES(ops->p->scrollmode, info); ++ u32 vxres = GETVXRES(ops->p, info); + + area.sx = vxres - ((sy + height) * vc->vc_font.height); + area.sy = sx * vc->vc_font.width; +@@ -68,7 +68,7 @@ static void cw_clear(struct vc_data *vc, struct fb_info *info, int sy, + struct fbcon_ops *ops = info->fbcon_par; + struct fb_fillrect region; + int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; +- u32 vxres = GETVXRES(ops->p->scrollmode, info); ++ u32 vxres = GETVXRES(ops->p, info); + + region.color = attr_bgcol_ec(bgshift,vc,info); + region.dx = vxres - ((sy + height) * vc->vc_font.height); +@@ -125,7 +125,7 @@ static void cw_putcs(struct vc_data *vc, struct fb_info *info, + u32 cnt, pitch, size; + u32 attribute = get_attribute(info, scr_readw(s)); + u8 *dst, *buf = NULL; +- u32 vxres = GETVXRES(ops->p->scrollmode, info); ++ u32 vxres = GETVXRES(ops->p, info); + + if (!ops->fontbuffer) + return; +@@ -212,7 +212,7 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode, + int attribute, use_sw = vc->vc_cursor_type & CUR_SW; + int err = 1, dx, dy; + char *src; +- u32 vxres = GETVXRES(ops->p->scrollmode, info); ++ u32 vxres = GETVXRES(ops->p, info); + + if (!ops->fontbuffer) + return; +@@ -369,7 +369,7 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode, + static int cw_update_start(struct fb_info *info) + { + struct fbcon_ops *ops = info->fbcon_par; +- u32 vxres = GETVXRES(ops->p->scrollmode, info); ++ u32 vxres = GETVXRES(ops->p, info); + u32 xoffset; + int err; + +diff --git a/drivers/video/fbdev/core/fbcon_rotate.h b/drivers/video/fbdev/core/fbcon_rotate.h +index e233444cda66..01cbe303b8a2 100644 +--- a/drivers/video/fbdev/core/fbcon_rotate.h ++++ b/drivers/video/fbdev/core/fbcon_rotate.h +@@ -12,11 +12,11 @@ + #define _FBCON_ROTATE_H + + #define GETVYRES(s,i) ({ \ +- (s == SCROLL_REDRAW || s == SCROLL_MOVE) ? \ ++ (fb_scrollmode(s) == SCROLL_REDRAW || fb_scrollmode(s) == SCROLL_MOVE) ? \ + (i)->var.yres : (i)->var.yres_virtual; }) + + #define GETVXRES(s,i) ({ \ +- (s == SCROLL_REDRAW || s == SCROLL_MOVE || !(i)->fix.xpanstep) ? \ ++ (fb_scrollmode(s) == SCROLL_REDRAW || fb_scrollmode(s) == SCROLL_MOVE || !(i)->fix.xpanstep) ? \ + (i)->var.xres : (i)->var.xres_virtual; }) + + +diff --git a/drivers/video/fbdev/core/fbcon_ud.c b/drivers/video/fbdev/core/fbcon_ud.c +index 8d5e66b1bdfb..23bc045769d0 100644 +--- a/drivers/video/fbdev/core/fbcon_ud.c ++++ b/drivers/video/fbdev/core/fbcon_ud.c +@@ -50,8 +50,8 @@ static void ud_bmove(struct vc_data *vc, struct fb_info *info, int sy, + { + struct fbcon_ops *ops = info->fbcon_par; + struct fb_copyarea area; +- u32 vyres = GETVYRES(ops->p->scrollmode, info); +- u32 vxres = GETVXRES(ops->p->scrollmode, info); ++ u32 vyres = GETVYRES(ops->p, info); ++ u32 vxres = GETVXRES(ops->p, info); + + area.sy = vyres - ((sy + height) * vc->vc_font.height); + area.sx = vxres - ((sx + width) * vc->vc_font.width); +@@ -69,8 +69,8 @@ static void ud_clear(struct vc_data *vc, struct fb_info *info, int sy, + struct fbcon_ops *ops = info->fbcon_par; + struct fb_fillrect region; + int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; +- u32 vyres = GETVYRES(ops->p->scrollmode, info); +- u32 vxres = GETVXRES(ops->p->scrollmode, info); ++ u32 vyres = GETVYRES(ops->p, info); ++ u32 vxres = GETVXRES(ops->p, info); + + region.color = attr_bgcol_ec(bgshift,vc,info); + region.dy = vyres - ((sy + height) * vc->vc_font.height); +@@ -162,8 +162,8 @@ static void ud_putcs(struct vc_data *vc, struct fb_info *info, + u32 mod = vc->vc_font.width % 8, cnt, pitch, size; + u32 attribute = get_attribute(info, scr_readw(s)); + u8 *dst, *buf = NULL; +- u32 vyres = GETVYRES(ops->p->scrollmode, info); +- u32 vxres = GETVXRES(ops->p->scrollmode, info); ++ u32 vyres = GETVYRES(ops->p, info); ++ u32 vxres = GETVXRES(ops->p, info); + + if (!ops->fontbuffer) + return; +@@ -259,8 +259,8 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, int mode, + int attribute, use_sw = vc->vc_cursor_type & CUR_SW; + int err = 1, dx, dy; + char *src; +- u32 vyres = GETVYRES(ops->p->scrollmode, info); +- u32 vxres = GETVXRES(ops->p->scrollmode, info); ++ u32 vyres = GETVYRES(ops->p, info); ++ u32 vxres = GETVXRES(ops->p, info); + + if (!ops->fontbuffer) + return; +@@ -410,8 +410,8 @@ static int ud_update_start(struct fb_info *info) + { + struct fbcon_ops *ops = info->fbcon_par; + int xoffset, yoffset; +- u32 vyres = GETVYRES(ops->p->scrollmode, info); +- u32 vxres = GETVXRES(ops->p->scrollmode, info); ++ u32 vyres = GETVYRES(ops->p, info); ++ u32 vxres = GETVXRES(ops->p, info); + int err; + + xoffset = vxres - info->var.xres - ops->var.xoffset; +-- +2.37.3 + diff --git a/patches.suse/0003-drm-nouveau-wait-for-the-exclusive-fence-after-the-s.patch b/patches.suse/0003-drm-nouveau-wait-for-the-exclusive-fence-after-the-s.patch new file mode 100644 index 0000000..0db82da --- /dev/null +++ b/patches.suse/0003-drm-nouveau-wait-for-the-exclusive-fence-after-the-s.patch @@ -0,0 +1,89 @@ +From 67f74302f45d5d862f22ced3297624e50ac352f0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= +Date: Tue, 7 Dec 2021 10:10:15 +0100 +Subject: drm/nouveau: wait for the exclusive fence after the shared ones v2 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Git-commit: 67f74302f45d5d862f22ced3297624e50ac352f0 +Patch-mainline: v5.16-rc8 +References: bsc#1152472 + +Always waiting for the exclusive fence resulted on some performance +regressions. So try to wait for the shared fences first, then the +exclusive fence should always be signaled already. + +v2: fix incorrectly placed "(", add some comment why we do this. + +Signed-off-by: Christian König +Tested-by: Stefan Fritsch +Tested-by: Dan Moulding +Acked-by: Ben Skeggs +Signed-off-by: Christian König +Cc: +Link: https://patchwork.freedesktop.org/patch/msgid/20211209102335.18321-1-christian.koenig@amd.com +Acked-by: Thomas Zimmermann +--- + drivers/gpu/drm/nouveau/nouveau_fence.c | 27 ++++++++++++++------------- + 1 file changed, 14 insertions(+), 13 deletions(-) + +--- a/drivers/gpu/drm/nouveau/nouveau_fence.c ++++ b/drivers/gpu/drm/nouveau/nouveau_fence.c +@@ -353,15 +353,21 @@ nouveau_fence_sync(struct nouveau_bo *nv + + if (ret) + return ret; ++ fobj = NULL; ++ } else { ++ fobj = dma_resv_shared_list(resv); + } + +- fobj = dma_resv_shared_list(resv); +- fence = dma_resv_excl_fence(resv); +- +- if (fence && (!exclusive || !fobj || !fobj->shared_count)) { ++ /* Waiting for the exclusive fence first causes performance regressions ++ * under some circumstances. So manually wait for the shared ones first. ++ */ ++ for (i = 0; i < (fobj ? fobj->shared_count : 0) && !ret; ++i) { + struct nouveau_channel *prev = NULL; + bool must_wait = true; + ++ fence = rcu_dereference_protected(fobj->shared[i], ++ dma_resv_held(resv)); ++ + f = nouveau_local_fence(fence, chan->drm); + if (f) { + rcu_read_lock(); +@@ -373,20 +379,13 @@ nouveau_fence_sync(struct nouveau_bo *nv + + if (must_wait) + ret = dma_fence_wait(fence, intr); +- +- return ret; + } + +- if (!exclusive || !fobj) +- return ret; +- +- for (i = 0; i < fobj->shared_count && !ret; ++i) { ++ fence = dma_resv_excl_fence(resv); ++ if (fence) { + struct nouveau_channel *prev = NULL; + bool must_wait = true; + +- fence = rcu_dereference_protected(fobj->shared[i], +- dma_resv_held(resv)); +- + f = nouveau_local_fence(fence, chan->drm); + if (f) { + rcu_read_lock(); +@@ -398,6 +397,8 @@ nouveau_fence_sync(struct nouveau_bo *nv + + if (must_wait) + ret = dma_fence_wait(fence, intr); ++ ++ return ret; + } + + return ret; diff --git a/patches.suse/0004-fbcon-Avoid-cap-set-but-not-used-warning.patch b/patches.suse/0004-fbcon-Avoid-cap-set-but-not-used-warning.patch index bc13ff1..0a05c44 100644 --- a/patches.suse/0004-fbcon-Avoid-cap-set-but-not-used-warning.patch +++ b/patches.suse/0004-fbcon-Avoid-cap-set-but-not-used-warning.patch @@ -43,10 +43,10 @@ Acked-by: Thomas Zimmermann if (logo_shown < 0 && console_loglevel <= CONSOLE_LOGLEVEL_QUIET) logo_shown = FBCON_LOGO_DONTSHOW; -@@ -1136,8 +1135,8 @@ static void fbcon_init(struct vc_data *v - +@@ -1137,8 +1136,8 @@ static void fbcon_init(struct vc_data *v ops->graphics = 0; + #ifdef CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION - if ((cap & FBINFO_HWACCEL_COPYAREA) && - !(cap & FBINFO_HWACCEL_DISABLED)) + if ((info->flags & FBINFO_HWACCEL_COPYAREA) && diff --git a/patches.suse/0005-drm-amdgpu-gfx10-add-wraparound-gpu-counter-check-fo.patch b/patches.suse/0005-drm-amdgpu-gfx10-add-wraparound-gpu-counter-check-fo.patch new file mode 100644 index 0000000..e39ce6d --- /dev/null +++ b/patches.suse/0005-drm-amdgpu-gfx10-add-wraparound-gpu-counter-check-fo.patch @@ -0,0 +1,66 @@ +From 244ee398855df2adc7d3ac5702b58424a5f684cc Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Thu, 18 Nov 2021 14:33:23 -0500 +Subject: drm/amdgpu/gfx10: add wraparound gpu counter check for APUs as well +Git-commit: 244ee398855df2adc7d3ac5702b58424a5f684cc +Patch-mainline: v5.16-rc3 +References: bsc#1152472 + +Apply the same check we do for dGPUs for APUs as well. + +Acked-by: Luben Tuikov +Signed-off-by: Alex Deucher +Acked-by: Thomas Zimmermann +--- + drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 32 +++++++++++++++++++++++++++----- + 1 file changed, 27 insertions(+), 5 deletions(-) + +--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +@@ -7608,19 +7608,41 @@ static int gfx_v10_0_soft_reset(void *ha + + static uint64_t gfx_v10_0_get_gpu_clock_counter(struct amdgpu_device *adev) + { +- uint64_t clock; ++ uint64_t clock, clock_lo, clock_hi, hi_check; + + amdgpu_gfx_off_ctrl(adev, false); + mutex_lock(&adev->gfx.gpu_clock_mutex); + switch (adev->asic_type) { + case CHIP_VANGOGH: + case CHIP_YELLOW_CARP: +- clock = (uint64_t)RREG32_SOC15(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER_Vangogh) | +- ((uint64_t)RREG32_SOC15(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER_Vangogh) << 32ULL); ++ preempt_disable(); ++ clock_hi = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER_Vangogh); ++ clock_lo = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER_Vangogh); ++ hi_check = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER_Vangogh); ++ /* The SMUIO TSC clock frequency is 100MHz, which sets 32-bit carry over ++ * roughly every 42 seconds. ++ */ ++ if (hi_check != clock_hi) { ++ clock_lo = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER_Vangogh); ++ clock_hi = hi_check; ++ } ++ preempt_enable(); ++ clock = clock_lo | (clock_hi << 32ULL); + break; + default: +- clock = (uint64_t)RREG32_SOC15(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER) | +- ((uint64_t)RREG32_SOC15(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER) << 32ULL); ++ preempt_disable(); ++ clock_hi = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER); ++ clock_lo = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER); ++ hi_check = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER); ++ /* The SMUIO TSC clock frequency is 100MHz, which sets 32-bit carry over ++ * roughly every 42 seconds. ++ */ ++ if (hi_check != clock_hi) { ++ clock_lo = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER); ++ clock_hi = hi_check; ++ } ++ preempt_enable(); ++ clock = clock_lo | (clock_hi << 32ULL); + break; + } + mutex_unlock(&adev->gfx.gpu_clock_mutex); diff --git a/patches.suse/0005-efi-generate-secret-key-in-EFI-boot-environment.patch b/patches.suse/0005-efi-generate-secret-key-in-EFI-boot-environment.patch index 2801991..29c3fef 100644 --- a/patches.suse/0005-efi-generate-secret-key-in-EFI-boot-environment.patch +++ b/patches.suse/0005-efi-generate-secret-key-in-EFI-boot-environment.patch @@ -72,10 +72,10 @@ Signed-off-by: Lee, Chun-Yi return false; --- a/arch/x86/include/uapi/asm/bootparam.h +++ b/arch/x86/include/uapi/asm/bootparam.h -@@ -10,6 +10,7 @@ - #define SETUP_EFI 4 +@@ -11,6 +11,7 @@ #define SETUP_APPLE_PROPERTIES 5 #define SETUP_JAILHOUSE 6 + #define SETUP_CC_BLOB 7 +#define SETUP_EFI_SECRET_KEY 16 #define SETUP_INDIRECT (1<<31) @@ -278,7 +278,7 @@ Signed-off-by: Lee, Chun-Yi +late_initcall(init_efi_secret_key); --- a/drivers/firmware/efi/libstub/Makefile +++ b/drivers/firmware/efi/libstub/Makefile -@@ -66,6 +66,8 @@ $(obj)/lib-%.o: $(srctree)/lib/%.c FORCE +@@ -73,6 +73,8 @@ $(obj)/lib-%.o: $(srctree)/lib/%.c FORCE lib-$(CONFIG_EFI_GENERIC_STUB) += efi-stub.o fdt.o string.o \ $(patsubst %.c,lib-%.o,$(efi-deps-y)) @@ -513,7 +513,7 @@ Signed-off-by: Lee, Chun-Yi status = exit_boot(boot_params, handle); --- a/include/linux/efi.h +++ b/include/linux/efi.h -@@ -1287,4 +1287,22 @@ static inline struct efi_mokvar_table_en +@@ -1291,4 +1291,22 @@ static inline struct efi_mokvar_table_en } #endif diff --git a/patches.suse/0006-parisc-stifb-Implement-fb_is_primary_device.patch b/patches.suse/0006-parisc-stifb-Implement-fb_is_primary_device.patch new file mode 100644 index 0000000..a7fa753 --- /dev/null +++ b/patches.suse/0006-parisc-stifb-Implement-fb_is_primary_device.patch @@ -0,0 +1,95 @@ +From cf936af790a3ef5f41ff687ec91bfbffee141278 Mon Sep 17 00:00:00 2001 +From: Helge Deller +Date: Thu, 2 Jun 2022 13:50:44 +0200 +Subject: parisc/stifb: Implement fb_is_primary_device() +Git-commit: cf936af790a3ef5f41ff687ec91bfbffee141278 +Patch-mainline: v5.19-rc1 +References: bsc#1152489 + +Implement fb_is_primary_device() function, so that fbcon detects if this +framebuffer belongs to the default graphics card which was used to start +the system. + +Signed-off-by: Helge Deller +Cc: stable@vger.kernel.org # v5.10+ +Acked-by: Thomas Zimmermann +--- + arch/parisc/include/asm/fb.h | 4 ++++ + drivers/video/console/sticore.c | 17 +++++++++++++++++ + drivers/video/fbdev/stifb.c | 4 ++-- + 3 files changed, 23 insertions(+), 2 deletions(-) + +diff --git a/arch/parisc/include/asm/fb.h b/arch/parisc/include/asm/fb.h +index c4cd6360f996..d63a2acb91f2 100644 +--- a/arch/parisc/include/asm/fb.h ++++ b/arch/parisc/include/asm/fb.h +@@ -12,9 +12,13 @@ static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma, + pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE; + } + ++#if defined(CONFIG_STI_CONSOLE) || defined(CONFIG_FB_STI) ++int fb_is_primary_device(struct fb_info *info); ++#else + static inline int fb_is_primary_device(struct fb_info *info) + { + return 0; + } ++#endif + + #endif /* _ASM_FB_H_ */ +diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c +index f869b723494f..62005064911b 100644 +--- a/drivers/video/console/sticore.c ++++ b/drivers/video/console/sticore.c +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + + #include "../fbdev/sticore.h" + +@@ -1127,6 +1128,22 @@ int sti_call(const struct sti_struct *sti, unsigned long func, + return ret; + } + ++/* check if given fb_info is the primary device */ ++int fb_is_primary_device(struct fb_info *info) ++{ ++ struct sti_struct *sti; ++ ++ sti = sti_get_rom(0); ++ ++ /* if no built-in graphics card found, allow any fb driver as default */ ++ if (!sti) ++ return true; ++ ++ /* return true if it's the default built-in framebuffer driver */ ++ return (sti->info == info); ++} ++EXPORT_SYMBOL(fb_is_primary_device); ++ + MODULE_AUTHOR("Philipp Rumpf, Helge Deller, Thomas Bogendoerfer"); + MODULE_DESCRIPTION("Core STI driver for HP's NGLE series graphics cards in HP PARISC machines"); + MODULE_LICENSE("GPL v2"); +diff --git a/drivers/video/fbdev/stifb.c b/drivers/video/fbdev/stifb.c +index bebb2eea6448..38a861e22c33 100644 +--- a/drivers/video/fbdev/stifb.c ++++ b/drivers/video/fbdev/stifb.c +@@ -1358,11 +1358,11 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref) + goto out_err3; + } + ++ /* save for primary gfx device detection & unregister_framebuffer() */ ++ sti->info = info; + if (register_framebuffer(&fb->info) < 0) + goto out_err4; + +- sti->info = info; /* save for unregister_framebuffer() */ +- + fb_info(&fb->info, "%s %dx%d-%d frame buffer device, %s, id: %04x, mmio: 0x%04lx\n", + fix->id, + var->xres, +-- +2.37.3 + diff --git a/patches.suse/0007-parisc-stifb-Keep-track-of-hardware-path-of-graphics.patch b/patches.suse/0007-parisc-stifb-Keep-track-of-hardware-path-of-graphics.patch new file mode 100644 index 0000000..82ab27d --- /dev/null +++ b/patches.suse/0007-parisc-stifb-Keep-track-of-hardware-path-of-graphics.patch @@ -0,0 +1,121 @@ +From b046f984814af7985f444150ec28716d42d00d9a Mon Sep 17 00:00:00 2001 +From: Helge Deller +Date: Thu, 2 Jun 2022 13:55:26 +0200 +Subject: parisc/stifb: Keep track of hardware path of graphics card +Git-commit: b046f984814af7985f444150ec28716d42d00d9a +Patch-mainline: v5.19-rc1 +References: bsc#1152489 + +Keep the pa_path (hardware path) of the graphics card in sti_struct and use +this info to give more useful info which card is currently being used. + +Signed-off-by: Helge Deller +Cc: stable@vger.kernel.org # v5.10+ +Acked-by: Thomas Zimmermann +--- + drivers/video/console/sticon.c | 5 ++++- + drivers/video/console/sticore.c | 15 +++++++-------- + drivers/video/fbdev/sticore.h | 3 +++ + 3 files changed, 14 insertions(+), 9 deletions(-) + +diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c +index 40496e9e9b43..f304163e87e9 100644 +--- a/drivers/video/console/sticon.c ++++ b/drivers/video/console/sticon.c +@@ -46,6 +46,7 @@ + #include + #include + #include ++#include + + #include + +@@ -392,7 +393,9 @@ static int __init sticonsole_init(void) + for (i = 0; i < MAX_NR_CONSOLES; i++) + font_data[i] = STI_DEF_FONT; + +- pr_info("sticon: Initializing STI text console.\n"); ++ pr_info("sticon: Initializing STI text console on %s at [%s]\n", ++ sticon_sti->sti_data->inq_outptr.dev_name, ++ sticon_sti->pa_path); + console_lock(); + err = do_take_over_console(&sti_con, 0, MAX_NR_CONSOLES - 1, + PAGE0->mem_cons.cl_class != CL_DUPLEX); +diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c +index 62005064911b..6a947ff96d6e 100644 +--- a/drivers/video/console/sticore.c ++++ b/drivers/video/console/sticore.c +@@ -34,7 +34,7 @@ + + #include "../fbdev/sticore.h" + +-#define STI_DRIVERVERSION "Version 0.9b" ++#define STI_DRIVERVERSION "Version 0.9c" + + static struct sti_struct *default_sti __read_mostly; + +@@ -503,7 +503,7 @@ sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name) + if (!fbfont) + return NULL; + +- pr_info("STI selected %ux%u framebuffer font %s for sticon\n", ++ pr_info(" using %ux%u framebuffer font %s\n", + fbfont->width, fbfont->height, fbfont->name); + + bpc = ((fbfont->width+7)/8) * fbfont->height; +@@ -947,6 +947,7 @@ static struct sti_struct *sti_try_rom_generic(unsigned long address, + + static void sticore_check_for_default_sti(struct sti_struct *sti, char *path) + { ++ pr_info(" located at [%s]\n", sti->pa_path); + if (strcmp (path, default_sti_path) == 0) + default_sti = sti; + } +@@ -958,7 +959,6 @@ static void sticore_check_for_default_sti(struct sti_struct *sti, char *path) + */ + static int __init sticore_pa_init(struct parisc_device *dev) + { +- char pa_path[21]; + struct sti_struct *sti = NULL; + int hpa = dev->hpa.start; + +@@ -971,8 +971,8 @@ static int __init sticore_pa_init(struct parisc_device *dev) + if (!sti) + return 1; + +- print_pa_hwpath(dev, pa_path); +- sticore_check_for_default_sti(sti, pa_path); ++ print_pa_hwpath(dev, sti->pa_path); ++ sticore_check_for_default_sti(sti, sti->pa_path); + return 0; + } + +@@ -1008,9 +1008,8 @@ static int sticore_pci_init(struct pci_dev *pd, const struct pci_device_id *ent) + + sti = sti_try_rom_generic(rom_base, fb_base, pd); + if (sti) { +- char pa_path[30]; +- print_pci_hwpath(pd, pa_path); +- sticore_check_for_default_sti(sti, pa_path); ++ print_pci_hwpath(pd, sti->pa_path); ++ sticore_check_for_default_sti(sti, sti->pa_path); + } + + if (!sti) { +diff --git a/drivers/video/fbdev/sticore.h b/drivers/video/fbdev/sticore.h +index c338f7848ae2..0ebdd28a0b81 100644 +--- a/drivers/video/fbdev/sticore.h ++++ b/drivers/video/fbdev/sticore.h +@@ -370,6 +370,9 @@ struct sti_struct { + + /* pointer to all internal data */ + struct sti_all_data *sti_data; ++ ++ /* pa_path of this device */ ++ char pa_path[24]; + }; + + +-- +2.37.3 + diff --git a/patches.suse/0008-parisc-stifb-Fix-fb_is_primary_device-only-available.patch b/patches.suse/0008-parisc-stifb-Fix-fb_is_primary_device-only-available.patch new file mode 100644 index 0000000..0d77d0b --- /dev/null +++ b/patches.suse/0008-parisc-stifb-Fix-fb_is_primary_device-only-available.patch @@ -0,0 +1,59 @@ +From 1d0811b03eb30b2f0793acaa96c6ce90b8b9c87a Mon Sep 17 00:00:00 2001 +From: Helge Deller +Date: Tue, 7 Jun 2022 12:57:58 +0200 +Subject: parisc/stifb: Fix fb_is_primary_device() only available with + CONFIG_FB_STI +Git-commit: 1d0811b03eb30b2f0793acaa96c6ce90b8b9c87a +Patch-mainline: v5.19-rc4 +References: bsc#1152489 + +Fix this build error noticed by the kernel test robot: + +drivers/video/console/sticore.c:1132:5: error: redefinition of 'fb_is_primary_device' + arch/parisc/include/asm/fb.h:18:19: note: previous definition of 'fb_is_primary_device' + +Signed-off-by: Helge Deller +Reported-by: kernel test robot +Cc: stable@vger.kernel.org # v5.10+ +Acked-by: Thomas Zimmermann +--- + arch/parisc/include/asm/fb.h | 2 +- + drivers/video/console/sticore.c | 2 ++ + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/arch/parisc/include/asm/fb.h b/arch/parisc/include/asm/fb.h +index d63a2acb91f2..55d29c4f716e 100644 +--- a/arch/parisc/include/asm/fb.h ++++ b/arch/parisc/include/asm/fb.h +@@ -12,7 +12,7 @@ static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma, + pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE; + } + +-#if defined(CONFIG_STI_CONSOLE) || defined(CONFIG_FB_STI) ++#if defined(CONFIG_FB_STI) + int fb_is_primary_device(struct fb_info *info); + #else + static inline int fb_is_primary_device(struct fb_info *info) +diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c +index fa23bf0247b0..bd4dc97d4d34 100644 +--- a/drivers/video/console/sticore.c ++++ b/drivers/video/console/sticore.c +@@ -1148,6 +1148,7 @@ int sti_call(const struct sti_struct *sti, unsigned long func, + return ret; + } + ++#if defined(CONFIG_FB_STI) + /* check if given fb_info is the primary device */ + int fb_is_primary_device(struct fb_info *info) + { +@@ -1163,6 +1164,7 @@ int fb_is_primary_device(struct fb_info *info) + return (sti->info == info); + } + EXPORT_SYMBOL(fb_is_primary_device); ++#endif + + MODULE_AUTHOR("Philipp Rumpf, Helge Deller, Thomas Bogendoerfer"); + MODULE_DESCRIPTION("Core STI driver for HP's NGLE series graphics cards in HP PARISC machines"); +-- +2.37.3 + diff --git a/patches.suse/0009-fbcon-Fix-accelerated-fbdev-scrolling-while-logo-is-.patch b/patches.suse/0009-fbcon-Fix-accelerated-fbdev-scrolling-while-logo-is-.patch new file mode 100644 index 0000000..ff13a0d --- /dev/null +++ b/patches.suse/0009-fbcon-Fix-accelerated-fbdev-scrolling-while-logo-is-.patch @@ -0,0 +1,56 @@ +From 3866cba87dcd0162fb41e9b3b653d0af68fad5ec Mon Sep 17 00:00:00 2001 +From: Helge Deller +Date: Thu, 2 Jun 2022 22:08:38 +0200 +Subject: fbcon: Fix accelerated fbdev scrolling while logo is still shown +Git-commit: 3866cba87dcd0162fb41e9b3b653d0af68fad5ec +Patch-mainline: v6.0-rc1 +References: bsc#1152472 + +There is no need to directly skip over to the SCROLL_REDRAW case while +the logo is still shown. + +When using DRM, this change has no effect because the code will reach +the SCROLL_REDRAW case immediately anyway. + +But if you run an accelerated fbdev driver and have +FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION enabled, console scrolling is +slowed down by factors so that it feels as if you use a 9600 baud +terminal. + +So, drop those unnecessary checks and speed up fbdev console +acceleration during bootup. + +Cc: stable@vger.kernel.org # v5.10+ +Acked-by: Daniel Vetter +Signed-off-by: Helge Deller +Link: https://patchwork.freedesktop.org/patch/msgid/YpkYxk7wsBPx3po+@p100 +Acked-by: Thomas Zimmermann +--- + drivers/video/fbdev/core/fbcon.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c +index d765bbdf19dc..cb8d94d7feba 100644 +--- a/drivers/video/fbdev/core/fbcon.c ++++ b/drivers/video/fbdev/core/fbcon.c +@@ -1758,8 +1758,6 @@ static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b, + case SM_UP: + if (count > vc->vc_rows) /* Maximum realistic size */ + count = vc->vc_rows; +- if (logo_shown >= 0) +- goto redraw_up; + switch (fb_scrollmode(p)) { + case SCROLL_MOVE: + fbcon_redraw_blit(vc, info, p, t, b - t - count, +@@ -1848,8 +1846,6 @@ static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b, + case SM_DOWN: + if (count > vc->vc_rows) /* Maximum realistic size */ + count = vc->vc_rows; +- if (logo_shown >= 0) +- goto redraw_down; + switch (fb_scrollmode(p)) { + case SCROLL_MOVE: + fbcon_redraw_blit(vc, info, p, b - 1, b - t - count, +-- +2.37.3 + diff --git a/patches.suse/ACPI-APEI-EINJ-Refuse-to-inject-into-the-zero-page.patch b/patches.suse/ACPI-APEI-EINJ-Refuse-to-inject-into-the-zero-page.patch new file mode 100644 index 0000000..007719e --- /dev/null +++ b/patches.suse/ACPI-APEI-EINJ-Refuse-to-inject-into-the-zero-page.patch @@ -0,0 +1,38 @@ +From: Tony Luck +Date: Tue, 19 Apr 2022 14:19:21 -0700 +Subject: ACPI, APEI, EINJ: Refuse to inject into the zero page +Patch-mainline: v5.19-rc1 +Git-commit: ab59c89396c007c360b1a4d762732d1621ff5456 +References: jsc#PED-1408 + +Some validation tests dynamically inject errors into memory used by +applications to check that the system can recover from a variety of +poison consumption sceenarios. + +But sometimes the virtual address picked by these tests is mapped to +the zero page. + +This causes additional unexpected machine checks as other processes that +map the zero page also consume the poison. + +Disallow injection to the zero page. + +Signed-off-by: Tony Luck +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/apei/einj.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/acpi/apei/einj.c ++++ b/drivers/acpi/apei/einj.c +@@ -548,6 +548,9 @@ static int einj_error_inject(u32 type, u + != REGION_INTERSECTS))) + return -EINVAL; + ++ if (is_zero_pfn(base_addr >> PAGE_SHIFT)) ++ return -EADDRINUSE; ++ + inject: + mutex_lock(&einj_mutex); + rc = __einj_error_inject(type, flags, param1, param2, param3, param4); diff --git a/patches.suse/ACPI-APEI-Fix-missing-ERST-record-id.patch b/patches.suse/ACPI-APEI-Fix-missing-ERST-record-id.patch new file mode 100644 index 0000000..a6b9124 --- /dev/null +++ b/patches.suse/ACPI-APEI-Fix-missing-ERST-record-id.patch @@ -0,0 +1,200 @@ +From: Liu Xinpeng +Date: Tue, 12 Apr 2022 11:05:19 +0800 +Subject: ACPI: APEI: Fix missing ERST record id +Patch-mainline: v5.19-rc1 +Git-commit: a090931524d03a4975c84b89a32210420d852313 +References: jsc#PED-1408 + +Read a record is cleared by others, but the deleted record cache entry is +still created by erst_get_record_id_next. When next enumerate the records, +get the cached deleted record, then erst_read() return -ENOENT and try to +get next record, loop back to first ID will return 0 in function +__erst_record_id_cache_add_one and then set record_id as +APEI_ERST_INVALID_RECORD_ID, finished this time read operation. +It will result in read the records just in the cache hereafter. + +This patch cleared the deleted record cache, fix the issue that +"./erst-inject -p" shows record counts not equal to "./erst-inject -n". + +A reproducer of the problem(retry many times): + +[root@localhost erst-inject]# ./erst-inject -c 0xaaaaa00011 +[root@localhost erst-inject]# ./erst-inject -p +rc: 273 +rcd sig: CPER +rcd id: 0xaaaaa00012 +rc: 273 +rcd sig: CPER +rcd id: 0xaaaaa00013 +rc: 273 +rcd sig: CPER +rcd id: 0xaaaaa00014 +[root@localhost erst-inject]# ./erst-inject -i 0xaaaaa000006 +[root@localhost erst-inject]# ./erst-inject -i 0xaaaaa000007 +[root@localhost erst-inject]# ./erst-inject -i 0xaaaaa000008 +[root@localhost erst-inject]# ./erst-inject -p +rc: 273 +rcd sig: CPER +rcd id: 0xaaaaa00012 +rc: 273 +rcd sig: CPER +rcd id: 0xaaaaa00013 +rc: 273 +rcd sig: CPER +rcd id: 0xaaaaa00014 +[root@localhost erst-inject]# ./erst-inject -n +total error record count: 6 + +Signed-off-by: Liu Xinpeng +Reviewed-by: Tony Luck +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + arch/x86/kernel/cpu/mce/apei.c | 8 +--- + drivers/acpi/apei/erst-dbg.c | 3 + + drivers/acpi/apei/erst.c | 77 +++++++++++++++++++++++++++++++++++++---- + include/acpi/apei.h | 2 + + 4 files changed, 78 insertions(+), 12 deletions(-) + +--- a/arch/x86/kernel/cpu/mce/apei.c ++++ b/arch/x86/kernel/cpu/mce/apei.c +@@ -177,16 +177,14 @@ retry: + /* no more record */ + if (*record_id == APEI_ERST_INVALID_RECORD_ID) + goto out; +- rc = erst_read(*record_id, &rcd.hdr, sizeof(rcd)); ++ rc = erst_read_record(*record_id, &rcd.hdr, sizeof(rcd), sizeof(rcd), ++ &CPER_CREATOR_MCE); + /* someone else has cleared the record, try next one */ + if (rc == -ENOENT) + goto retry; + else if (rc < 0) + goto out; +- /* try to skip other type records in storage */ +- else if (rc != sizeof(rcd) || +- !guid_equal(&rcd.hdr.creator_id, &CPER_CREATOR_MCE)) +- goto retry; ++ + memcpy(m, &rcd.mce, sizeof(*m)); + rc = sizeof(*m); + out: +--- a/drivers/acpi/apei/erst-dbg.c ++++ b/drivers/acpi/apei/erst-dbg.c +@@ -111,7 +111,8 @@ retry_next: + goto out; + } + retry: +- rc = len = erst_read(id, erst_dbg_buf, erst_dbg_buf_len); ++ rc = len = erst_read_record(id, erst_dbg_buf, erst_dbg_buf_len, ++ erst_dbg_buf_len, NULL); + /* The record may be cleared by others, try read next record */ + if (rc == -ENOENT) + goto retry_next; +--- a/drivers/acpi/apei/erst.c ++++ b/drivers/acpi/apei/erst.c +@@ -856,6 +856,74 @@ ssize_t erst_read(u64 record_id, struct + } + EXPORT_SYMBOL_GPL(erst_read); + ++static void erst_clear_cache(u64 record_id) ++{ ++ int i; ++ u64 *entries; ++ ++ mutex_lock(&erst_record_id_cache.lock); ++ ++ entries = erst_record_id_cache.entries; ++ for (i = 0; i < erst_record_id_cache.len; i++) { ++ if (entries[i] == record_id) ++ entries[i] = APEI_ERST_INVALID_RECORD_ID; ++ } ++ __erst_record_id_cache_compact(); ++ ++ mutex_unlock(&erst_record_id_cache.lock); ++} ++ ++ssize_t erst_read_record(u64 record_id, struct cper_record_header *record, ++ size_t buflen, size_t recordlen, const guid_t *creatorid) ++{ ++ ssize_t len; ++ ++ /* ++ * if creatorid is NULL, read any record for erst-dbg module ++ */ ++ if (creatorid == NULL) { ++ len = erst_read(record_id, record, buflen); ++ if (len == -ENOENT) ++ erst_clear_cache(record_id); ++ ++ return len; ++ } ++ ++ len = erst_read(record_id, record, buflen); ++ /* ++ * if erst_read return value is -ENOENT skip to next record_id, ++ * and clear the record_id cache. ++ */ ++ if (len == -ENOENT) { ++ erst_clear_cache(record_id); ++ goto out; ++ } ++ ++ if (len < 0) ++ goto out; ++ ++ /* ++ * if erst_read return value is less than record head length, ++ * consider it as -EIO, and clear the record_id cache. ++ */ ++ if (len < recordlen) { ++ len = -EIO; ++ erst_clear_cache(record_id); ++ goto out; ++ } ++ ++ /* ++ * if creatorid is not wanted, consider it as not found, ++ * for skipping to next record_id. ++ */ ++ if (!guid_equal(&record->creator_id, creatorid)) ++ len = -ENOENT; ++ ++out: ++ return len; ++} ++EXPORT_SYMBOL_GPL(erst_read_record); ++ + int erst_clear(u64 record_id) + { + int rc, i; +@@ -996,16 +1064,13 @@ skip: + goto out; + } + +- len = erst_read(record_id, &rcd->hdr, rcd_len); ++ len = erst_read_record(record_id, &rcd->hdr, rcd_len, sizeof(*rcd), ++ &CPER_CREATOR_PSTORE); + /* The record may be cleared by others, try read next record */ + if (len == -ENOENT) + goto skip; +- else if (len < 0 || len < sizeof(*rcd)) { +- rc = -EIO; ++ else if (len < 0) + goto out; +- } +- if (!guid_equal(&rcd->hdr.creator_id, &CPER_CREATOR_PSTORE)) +- goto skip; + + record->buf = kmalloc(len, GFP_KERNEL); + if (record->buf == NULL) { +--- a/include/acpi/apei.h ++++ b/include/acpi/apei.h +@@ -46,6 +46,8 @@ int erst_get_record_id_next(int *pos, u6 + void erst_get_record_id_end(void); + ssize_t erst_read(u64 record_id, struct cper_record_header *record, + size_t buflen); ++ssize_t erst_read_record(u64 record_id, struct cper_record_header *record, ++ size_t buflen, size_t recordlen, const guid_t *creatorid); + int erst_clear(u64 record_id); + + int arch_apei_enable_cmcff(struct acpi_hest_header *hest_hdr, void *data); diff --git a/patches.suse/ACPI-APEI-do-not-add-task_work-to-kernel-thread-to-a.patch b/patches.suse/ACPI-APEI-do-not-add-task_work-to-kernel-thread-to-a.patch new file mode 100644 index 0000000..f647ac2 --- /dev/null +++ b/patches.suse/ACPI-APEI-do-not-add-task_work-to-kernel-thread-to-a.patch @@ -0,0 +1,77 @@ +From 415fed694fe11395df56e05022d6e7cee1d39dd3 Mon Sep 17 00:00:00 2001 +From: Shuai Xue +Date: Sat, 24 Sep 2022 15:49:53 +0800 +Subject: [PATCH] ACPI: APEI: do not add task_work to kernel thread to avoid memory leak +Git-commit: 415fed694fe11395df56e05022d6e7cee1d39dd3 +Patch-mainline: v6.1-rc1 +References: git-fixes + +If an error is detected as a result of user-space process accessing a +corrupt memory location, the CPU may take an abort. Then the platform +firmware reports kernel via NMI like notifications, e.g. NOTIFY_SEA, +NOTIFY_SOFTWARE_DELEGATED, etc. + +For NMI like notifications, commit 7f17b4a121d0 ("ACPI: APEI: Kick the +memory_failure() queue for synchronous errors") keep track of whether +memory_failure() work was queued, and make task_work pending to flush out +the queue so that the work is processed before return to user-space. + +The code use init_mm to check whether the error occurs in user space: + + if (current->mm != &init_mm) + +The condition is always true, becase _nobody_ ever has "init_mm" as a real +VM any more. + +In addition to abort, errors can also be signaled as asynchronous +exceptions, such as interrupt and SError. In such case, the interrupted +current process could be any kind of thread. When a kernel thread is +interrupted, the work ghes_kick_task_work deferred to task_work will never +be processed because entry_handler returns to call ret_to_kernel() instead +of ret_to_user(). Consequently, the estatus_node alloced from +ghes_estatus_pool in ghes_in_nmi_queue_one_entry() will not be freed. +After around 200 allocations in our platform, the ghes_estatus_pool will +run of memory and ghes_in_nmi_queue_one_entry() returns ENOMEM. As a +result, the event failed to be processed. + + sdei: event 805 on CPU 113 failed with error: -2 + +Finally, a lot of unhandled events may cause platform firmware to exceed +some threshold and reboot. + +The condition should generally just do + + if (current->mm) + +as described in active_mm.rst documentation. + +Then if an asynchronous error is detected when a kernel thread is running, +(e.g. when detected by a background scrubber), do not add task_work to it +as the original patch intends to do. + +Fixes: 7f17b4a121d0 ("ACPI: APEI: Kick the memory_failure() queue for synchronous errors") +Signed-off-by: Shuai Xue +Reviewed-by: Tony Luck +Signed-off-by: Rafael J. Wysocki +Acked-by: Takashi Iwai + +--- + drivers/acpi/apei/ghes.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c +index d91ad378c00d..80ad530583c9 100644 +--- a/drivers/acpi/apei/ghes.c ++++ b/drivers/acpi/apei/ghes.c +@@ -985,7 +985,7 @@ static void ghes_proc_in_irq(struct irq_work *irq_work) + ghes_estatus_cache_add(generic, estatus); + } + +- if (task_work_pending && current->mm != &init_mm) { ++ if (task_work_pending && current->mm) { + estatus_node->task_work.func = ghes_kick_task_work; + estatus_node->task_work_cpu = smp_processor_id(); + ret = task_work_add(current, &estatus_node->task_work, +-- +2.35.3 + diff --git a/patches.suse/ACPI-Add-perf-low-power-callback.patch b/patches.suse/ACPI-Add-perf-low-power-callback.patch new file mode 100644 index 0000000..5f10c52 --- /dev/null +++ b/patches.suse/ACPI-Add-perf-low-power-callback.patch @@ -0,0 +1,97 @@ +From: Stephane Eranian +Date: Tue, 22 Mar 2022 15:15:12 -0700 +Subject: ACPI: Add perf low power callback +Patch-mainline: v5.19-rc1 +Git-commit: 2a606a18cd672a16343d146a126721b34cc6adbd +References: jsc#PED-1408 + +Add an optional callback needed by some PMU features, e.g., AMD +BRS, to give a chance to the perf_events code to change its state before +a CPU goes to low power and after it comes back. + +The callback is void when the PERF_NEEDS_LOPWR_CB flag is not set. +This flag must be set in arch specific perf_event.h header whenever needed. +When not set, there is no impact on the ACPI code. + +Signed-off-by: Stephane Eranian +[peterz: build fix] +Signed-off-by: Peter Zijlstra (Intel) +Link: https://lore.kernel.org/r/20220322221517.2510440-9-eranian@google.com +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/acpi_pad.c | 7 +++++++ + drivers/acpi/processor_idle.c | 5 +++++ + include/linux/perf_event.h | 6 ++++++ + 3 files changed, 18 insertions(+) + +--- a/drivers/acpi/acpi_pad.c ++++ b/drivers/acpi/acpi_pad.c +@@ -17,6 +17,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -164,6 +165,9 @@ static int power_saving_thread(void *dat + tsc_marked_unstable = 1; + } + local_irq_disable(); ++ ++ perf_lopwr_cb(true); ++ + tick_broadcast_enable(); + tick_broadcast_enter(); + stop_critical_timings(); +@@ -172,6 +176,9 @@ static int power_saving_thread(void *dat + + start_critical_timings(); + tick_broadcast_exit(); ++ ++ perf_lopwr_cb(false); ++ + local_irq_enable(); + + if (time_before(expire_time, jiffies)) { +--- a/drivers/acpi/processor_idle.c ++++ b/drivers/acpi/processor_idle.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + #include + + /* +@@ -544,6 +545,8 @@ static void wait_for_freeze(void) + */ + static void __cpuidle acpi_idle_do_entry(struct acpi_processor_cx *cx) + { ++ perf_lopwr_cb(true); ++ + if (cx->entry_method == ACPI_CSTATE_FFH) { + /* Call into architectural FFH based C-state */ + acpi_processor_ffh_cstate_enter(cx); +@@ -554,6 +557,8 @@ static void __cpuidle acpi_idle_do_entry + inb(cx->address); + wait_for_freeze(); + } ++ ++ perf_lopwr_cb(false); + } + + /** +--- a/include/linux/perf_event.h ++++ b/include/linux/perf_event.h +@@ -1615,4 +1615,10 @@ extern void __weak arch_perf_update_user + extern __weak u64 arch_perf_get_page_size(struct mm_struct *mm, unsigned long addr); + #endif + ++#ifndef PERF_NEEDS_LOPWR_CB ++static inline void perf_lopwr_cb(bool mode) ++{ ++} ++#endif ++ + #endif /* _LINUX_PERF_EVENT_H */ diff --git a/patches.suse/ACPI-BGRT-use-static-for-BGRT_SHOW-kobj_attribute-de.patch b/patches.suse/ACPI-BGRT-use-static-for-BGRT_SHOW-kobj_attribute-de.patch new file mode 100644 index 0000000..7270e89 --- /dev/null +++ b/patches.suse/ACPI-BGRT-use-static-for-BGRT_SHOW-kobj_attribute-de.patch @@ -0,0 +1,36 @@ +From: Tom Rix +Date: Thu, 21 Apr 2022 12:42:54 -0400 +Subject: ACPI: BGRT: use static for BGRT_SHOW kobj_attribute defines +Patch-mainline: v5.19-rc1 +Git-commit: db2d1693fae37e01e7fcfd627b407c18737e8373 +References: jsc#PED-1408 + +Smatch reports this repesentative issue: + +bgrt.c:26:1: warning: symbol 'bgrt_attr_version' was not declared. Should it be static? + +Similar for *status,type,xoffset,yoffset + +These variables are defined with the BGRT_SHOW macro. + +For the definition of bgrt_attr_##_name, +the storage-class specifier should be static. + +Signed-off-by: Tom Rix +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/bgrt.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/acpi/bgrt.c ++++ b/drivers/acpi/bgrt.c +@@ -21,7 +21,7 @@ static struct kobject *bgrt_kobj; + { \ + return sysfs_emit(buf, "%d\n", bgrt_tab._member); \ + } \ +- struct kobj_attribute bgrt_attr_##_name = __ATTR_RO(_name) ++ static struct kobj_attribute bgrt_attr_##_name = __ATTR_RO(_name) + + BGRT_SHOW(version, version); + BGRT_SHOW(status, status); diff --git a/patches.suse/ACPI-CPPC-Check-_OSC-for-flexible-address-space.patch b/patches.suse/ACPI-CPPC-Check-_OSC-for-flexible-address-space.patch new file mode 100644 index 0000000..0ce7fa6 --- /dev/null +++ b/patches.suse/ACPI-CPPC-Check-_OSC-for-flexible-address-space.patch @@ -0,0 +1,116 @@ +From: Pierre Gondois +Date: Wed, 18 May 2022 11:08:57 +0200 +Subject: ACPI: CPPC: Check _OSC for flexible address space +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Patch-mainline: v5.19-rc1 +Git-commit: 0651ab90e4ade17f1d4f4367b70f6120480410f3 +References: jsc#PED-1408 + +ACPI 6.2 Section 6.2.11.2 'Platform-Wide OSPM Capabilities': + Starting with ACPI Specification 6.2, all _CPC registers can be in + PCC, System Memory, System IO, or Functional Fixed Hardware address + spaces. OSPM support for this more flexible register space scheme is + indicated by the “Flexible Address Space for CPPC Registers” _OSC bit + +Otherwise (cf ACPI 6.1, s8.4.7.1.1.X), _CPC registers must be in: +- PCC or Functional Fixed Hardware address space if defined +- SystemMemory address space (NULL register) if not defined + +Add the corresponding _OSC bit and check it when parsing _CPC objects. + +Signed-off-by: Pierre Gondois +Reviewed-by: Sudeep Holla +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/bus.c | 18 ++++++++++++++++++ + drivers/acpi/cppc_acpi.c | 9 +++++++++ + include/linux/acpi.h | 2 ++ + 3 files changed, 29 insertions(+) + +--- a/drivers/acpi/bus.c ++++ b/drivers/acpi/bus.c +@@ -279,6 +279,20 @@ bool osc_pc_lpi_support_confirmed; + EXPORT_SYMBOL_GPL(osc_pc_lpi_support_confirmed); + + /* ++ * ACPI 6.2 Section 6.2.11.2 'Platform-Wide OSPM Capabilities': ++ * Starting with ACPI Specification 6.2, all _CPC registers can be in ++ * PCC, System Memory, System IO, or Functional Fixed Hardware address ++ * spaces. OSPM support for this more flexible register space scheme is ++ * indicated by the “Flexible Address Space for CPPC Registers” _OSC bit. ++ * ++ * Otherwise (cf ACPI 6.1, s8.4.7.1.1.X), _CPC registers must be in: ++ * - PCC or Functional Fixed Hardware address space if defined ++ * - SystemMemory address space (NULL register) if not defined ++ */ ++bool osc_cpc_flexible_adr_space_confirmed; ++EXPORT_SYMBOL_GPL(osc_cpc_flexible_adr_space_confirmed); ++ ++/* + * ACPI 6.4 Operating System Capabilities for USB. + */ + bool osc_sb_native_usb4_support_confirmed; +@@ -321,6 +335,8 @@ static void acpi_bus_osc_negotiate_platf + } + #endif + ++ capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPC_FLEXIBLE_ADR_SPACE; ++ + if (IS_ENABLED(CONFIG_SCHED_MC_PRIO)) + capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPC_DIVERSE_HIGH_SUPPORT; + +@@ -366,6 +382,8 @@ static void acpi_bus_osc_negotiate_platf + capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_PCLPI_SUPPORT; + osc_sb_native_usb4_support_confirmed = + capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_NATIVE_USB4_SUPPORT; ++ osc_cpc_flexible_adr_space_confirmed = ++ capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_CPC_FLEXIBLE_ADR_SPACE; + } + + kfree(context.ret.pointer); +--- a/drivers/acpi/cppc_acpi.c ++++ b/drivers/acpi/cppc_acpi.c +@@ -749,6 +749,11 @@ int acpi_cppc_processor_probe(struct acp + if (gas_t->address) { + void __iomem *addr; + ++ if (!osc_cpc_flexible_adr_space_confirmed) { ++ pr_debug("Flexible address space capability not supported\n"); ++ goto out_free; ++ } ++ + addr = ioremap(gas_t->address, gas_t->bit_width/8); + if (!addr) + goto out_free; +@@ -771,6 +776,10 @@ int acpi_cppc_processor_probe(struct acp + gas_t->address); + goto out_free; + } ++ if (!osc_cpc_flexible_adr_space_confirmed) { ++ pr_debug("Flexible address space capability not supported\n"); ++ goto out_free; ++ } + } else { + if (gas_t->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE || !cpc_ffh_supported()) { + /* Support only PCC, SystemMemory, SystemIO, and FFH type regs. */ +--- a/include/linux/acpi.h ++++ b/include/linux/acpi.h +@@ -574,6 +574,7 @@ acpi_status acpi_run_osc(acpi_handle han + #define OSC_SB_OSLPI_SUPPORT 0x00000100 + #define OSC_SB_CPC_DIVERSE_HIGH_SUPPORT 0x00001000 + #define OSC_SB_GENERIC_INITIATOR_SUPPORT 0x00002000 ++#define OSC_SB_CPC_FLEXIBLE_ADR_SPACE 0x00004000 + #define OSC_SB_NATIVE_USB4_SUPPORT 0x00040000 + #define OSC_SB_PRM_SUPPORT 0x00200000 + +@@ -581,6 +582,7 @@ extern bool osc_sb_apei_support_acked; + extern bool osc_pc_lpi_support_confirmed; + extern bool osc_sb_native_usb4_support_confirmed; + extern bool osc_sb_cppc_not_supported; ++extern bool osc_cpc_flexible_adr_space_confirmed; + + /* USB4 Capabilities */ + #define OSC_USB_USB3_TUNNELING 0x00000001 diff --git a/patches.suse/ACPI-CPPC-Don-t-require-_OSC-if-X86_FEATURE_CPPC-is-.patch b/patches.suse/ACPI-CPPC-Don-t-require-_OSC-if-X86_FEATURE_CPPC-is-.patch new file mode 100644 index 0000000..51bd039 --- /dev/null +++ b/patches.suse/ACPI-CPPC-Don-t-require-_OSC-if-X86_FEATURE_CPPC-is-.patch @@ -0,0 +1,94 @@ +From: Mario Limonciello +Date: Tue, 5 Jul 2022 13:29:15 -0500 +Subject: ACPI: CPPC: Don't require _OSC if X86_FEATURE_CPPC is supported +Patch-mainline: v5.19-rc6 +Git-commit: 8b356e536e69f3a4d6778ae9f0858a1beadabb1f +References: jsc#PED-1408 + +commit 72f2ecb7ece7 ("ACPI: bus: Set CPPC _OSC bits for all and +when CPPC_LIB is supported") added support for claiming to +support CPPC in _OSC on non-Intel platforms. + +This unfortunately caused a regression on a vartiety of AMD +platforms in the field because a number of AMD platforms don't set +the `_OSC` bit 5 or 6 to indicate CPPC or CPPC v2 support. + +As these AMD platforms already claim CPPC support via a dedicated +MSR from `X86_FEATURE_CPPC`, use this enable this feature rather +than requiring the `_OSC` on platforms with a dedicated MSR. + +If there is additional breakage on the shared memory designs also +missing this _OSC, additional follow up changes may be needed. + +Fixes: 72f2ecb7ece7 ("Set CPPC _OSC bits for all and when CPPC_LIB is supported") +Reported-by: Perry Yuan +Signed-off-by: Mario Limonciello +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + arch/x86/kernel/acpi/cppc.c | 10 ++++++++++ + drivers/acpi/cppc_acpi.c | 16 +++++++++++++++- + include/acpi/cppc_acpi.h | 1 + + 3 files changed, 26 insertions(+), 1 deletion(-) + +--- a/arch/x86/kernel/acpi/cppc.c ++++ b/arch/x86/kernel/acpi/cppc.c +@@ -11,6 +11,16 @@ + + /* Refer to drivers/acpi/cppc_acpi.c for the description of functions */ + ++bool cpc_supported_by_cpu(void) ++{ ++ switch (boot_cpu_data.x86_vendor) { ++ case X86_VENDOR_AMD: ++ case X86_VENDOR_HYGON: ++ return boot_cpu_has(X86_FEATURE_CPPC); ++ } ++ return false; ++} ++ + bool cpc_ffh_supported(void) + { + return true; +--- a/drivers/acpi/cppc_acpi.c ++++ b/drivers/acpi/cppc_acpi.c +@@ -591,6 +591,19 @@ bool __weak cpc_ffh_supported(void) + } + + /** ++ * cpc_supported_by_cpu() - check if CPPC is supported by CPU ++ * ++ * Check if the architectural support for CPPC is present even ++ * if the _OSC hasn't prescribed it ++ * ++ * Return: true for supported, false for not supported ++ */ ++bool __weak cpc_supported_by_cpu(void) ++{ ++ return false; ++} ++ ++/** + * pcc_data_alloc() - Allocate the pcc_data memory for pcc subspace + * + * Check and allocate the cppc_pcc_data memory. +@@ -699,7 +712,8 @@ int acpi_cppc_processor_probe(struct acp + + if (!osc_sb_cppc2_support_acked) { + pr_debug("CPPC v2 _OSC not acked\n"); +- return -ENODEV; ++ if (!cpc_supported_by_cpu()) ++ return -ENODEV; + } + + /* Parse the ACPI _CPC table for this CPU. */ +--- a/include/acpi/cppc_acpi.h ++++ b/include/acpi/cppc_acpi.h +@@ -145,6 +145,7 @@ extern bool cppc_allow_fast_switch(void) + extern int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data); + extern unsigned int cppc_get_transition_latency(int cpu); + extern bool cpc_ffh_supported(void); ++extern bool cpc_supported_by_cpu(void); + extern int cpc_read_ffh(int cpunum, struct cpc_reg *reg, u64 *val); + extern int cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val); + #else /* !CONFIG_ACPI_CPPC_LIB */ diff --git a/patches.suse/ACPI-CPPC-Don-t-require-flexible-address-space-if-X8.patch b/patches.suse/ACPI-CPPC-Don-t-require-flexible-address-space-if-X8.patch new file mode 100644 index 0000000..c9163d7 --- /dev/null +++ b/patches.suse/ACPI-CPPC-Don-t-require-flexible-address-space-if-X8.patch @@ -0,0 +1,55 @@ +From: Mario Limonciello +Date: Fri, 15 Jul 2022 12:33:25 -0500 +Subject: ACPI: CPPC: Don't require flexible address space if X86_FEATURE_CPPC + is supported +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Patch-mainline: v5.19-rc8 +Git-commit: 09073396ea62d0a10b03f5661dcabfd8eca3f098 +References: jsc#PED-1408 + +Commit 0651ab90e4ad ("ACPI: CPPC: Check _OSC for flexible address space") +changed _CPC probing to require flexible address space to be negotiated +for CPPC to work. + +However it was observed that this caused a regression for Arek's ROG +Zephyrus G15 GA503QM which previously CPPC worked, but now it stopped +working. + +To avoid causing a regression waive this failure when the CPU is known +to support CPPC. + +Cc: Pierre Gondois +Link: https://bugzilla.kernel.org/show_bug.cgi?id=216248 +Fixes: 0651ab90e4ad ("ACPI: CPPC: Check _OSC for flexible address space") +Reported-and-tested-by: Arek Ruśniak +Signed-off-by: Mario Limonciello +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/cppc_acpi.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/acpi/cppc_acpi.c ++++ b/drivers/acpi/cppc_acpi.c +@@ -795,7 +795,8 @@ int acpi_cppc_processor_probe(struct acp + + if (!osc_cpc_flexible_adr_space_confirmed) { + pr_debug("Flexible address space capability not supported\n"); +- goto out_free; ++ if (!cpc_supported_by_cpu()) ++ goto out_free; + } + + addr = ioremap(gas_t->address, gas_t->bit_width/8); +@@ -822,7 +823,8 @@ int acpi_cppc_processor_probe(struct acp + } + if (!osc_cpc_flexible_adr_space_confirmed) { + pr_debug("Flexible address space capability not supported\n"); +- goto out_free; ++ if (!cpc_supported_by_cpu()) ++ goto out_free; + } + } else { + if (gas_t->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE || !cpc_ffh_supported()) { diff --git a/patches.suse/ACPI-CPPC-Fix-enabling-CPPC-on-AMD-systems-with-shar.patch b/patches.suse/ACPI-CPPC-Fix-enabling-CPPC-on-AMD-systems-with-shar.patch new file mode 100644 index 0000000..a0c053d --- /dev/null +++ b/patches.suse/ACPI-CPPC-Fix-enabling-CPPC-on-AMD-systems-with-shar.patch @@ -0,0 +1,47 @@ +From: Mario Limonciello +Date: Wed, 13 Jul 2022 12:53:46 -0500 +Subject: ACPI: CPPC: Fix enabling CPPC on AMD systems with shared memory +Patch-mainline: v5.19-rc7 +Git-commit: fbd74d16890b9f5d08ea69b5282b123c894f8860 +References: jsc#PED-1408 + +When commit 72f2ecb7ece7 ("ACPI: bus: Set CPPC _OSC bits for all +and when CPPC_LIB is supported") was introduced, we found collateral +damage that a number of AMD systems that supported CPPC but +didn't advertise support in _OSC stopped having a functional +amd-pstate driver. The _OSC was only enforced on Intel systems at that +time. + +This was fixed for the MSR based designs by commit 8b356e536e69f +("ACPI: CPPC: Don't require _OSC if X86_FEATURE_CPPC is supported") +but some shared memory based designs also support CPPC but haven't +advertised support in the _OSC. Add support for those designs as well by +hardcoding the list of systems. + +Fixes: 72f2ecb7ece7 ("ACPI: bus: Set CPPC _OSC bits for all and when CPPC_LIB is supported") +Fixes: 8b356e536e69f ("ACPI: CPPC: Don't require _OSC if X86_FEATURE_CPPC is supported") +Link: https://lore.kernel.org/all/3559249.JlDtxWtqDm@natalenko.name/ +Cc: 5.18+ # 5.18+ +Reported-and-tested-by: Oleksandr Natalenko +Signed-off-by: Mario Limonciello +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + arch/x86/kernel/acpi/cppc.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/arch/x86/kernel/acpi/cppc.c ++++ b/arch/x86/kernel/acpi/cppc.c +@@ -16,6 +16,12 @@ bool cpc_supported_by_cpu(void) + switch (boot_cpu_data.x86_vendor) { + case X86_VENDOR_AMD: + case X86_VENDOR_HYGON: ++ if (boot_cpu_data.x86 == 0x19 && ((boot_cpu_data.x86_model <= 0x0f) || ++ (boot_cpu_data.x86_model >= 0x20 && boot_cpu_data.x86_model <= 0x2f))) ++ return true; ++ else if (boot_cpu_data.x86 == 0x17 && ++ boot_cpu_data.x86_model >= 0x70 && boot_cpu_data.x86_model <= 0x7f) ++ return true; + return boot_cpu_has(X86_FEATURE_CPPC); + } + return false; diff --git a/patches.suse/ACPI-CPPC-Only-probe-for-_CPC-if-CPPC-v2-is-acked.patch b/patches.suse/ACPI-CPPC-Only-probe-for-_CPC-if-CPPC-v2-is-acked.patch index ae7cf80..ebb308b 100644 --- a/patches.suse/ACPI-CPPC-Only-probe-for-_CPC-if-CPPC-v2-is-acked.patch +++ b/patches.suse/ACPI-CPPC-Only-probe-for-_CPC-if-CPPC-v2-is-acked.patch @@ -44,14 +44,14 @@ Signed-off-by: Rafael J. Wysocki Acked-by: Takashi Iwai --- - drivers/acpi/bus.c | 12 +++++------- + drivers/acpi/bus.c | 11 +++++------ drivers/acpi/cppc_acpi.c | 4 +++- include/linux/acpi.h | 2 +- - 3 files changed, 9 insertions(+), 9 deletions(-) + 3 files changed, 9 insertions(+), 8 deletions(-) --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c -@@ -284,7 +284,7 @@ EXPORT_SYMBOL_GPL(osc_pc_lpi_support_con +@@ -298,7 +298,7 @@ EXPORT_SYMBOL_GPL(osc_cpc_flexible_adr_s bool osc_sb_native_usb4_support_confirmed; EXPORT_SYMBOL_GPL(osc_sb_native_usb4_support_confirmed); @@ -60,20 +60,19 @@ Acked-by: Takashi Iwai static u8 sb_uuid_str[] = "0811B06E-4A27-44F9-8D60-3CBBC22E7B48"; static void acpi_bus_osc_negotiate_platform_control(void) -@@ -341,12 +341,6 @@ static void acpi_bus_osc_negotiate_platf +@@ -358,11 +358,6 @@ static void acpi_bus_osc_negotiate_platf return; } --#ifdef CONFIG_X86 -- if (boot_cpu_has(X86_FEATURE_HWP)) -- osc_sb_cppc_not_supported = !(capbuf_ret[OSC_SUPPORT_DWORD] & -- (OSC_SB_CPC_SUPPORT | OSC_SB_CPCV2_SUPPORT)); +-#ifdef CONFIG_ACPI_CPPC_LIB +- osc_sb_cppc_not_supported = !(capbuf_ret[OSC_SUPPORT_DWORD] & +- (OSC_SB_CPC_SUPPORT | OSC_SB_CPCV2_SUPPORT)); -#endif - /* * Now run _OSC again with query flag clear and with the caps * supported by both the OS and the platform. -@@ -360,6 +354,10 @@ static void acpi_bus_osc_negotiate_platf +@@ -376,6 +371,10 @@ static void acpi_bus_osc_negotiate_platf capbuf_ret = context.ret.pointer; if (context.ret.length > OSC_SUPPORT_DWORD) { @@ -100,12 +99,12 @@ Acked-by: Takashi Iwai status = acpi_evaluate_object_typed(handle, "_CPC", NULL, &output, --- a/include/linux/acpi.h +++ b/include/linux/acpi.h -@@ -580,7 +580,7 @@ acpi_status acpi_run_osc(acpi_handle han +@@ -581,7 +581,7 @@ acpi_status acpi_run_osc(acpi_handle han extern bool osc_sb_apei_support_acked; extern bool osc_pc_lpi_support_confirmed; extern bool osc_sb_native_usb4_support_confirmed; -extern bool osc_sb_cppc_not_supported; +extern bool osc_sb_cppc2_support_acked; + extern bool osc_cpc_flexible_adr_space_confirmed; /* USB4 Capabilities */ - #define OSC_USB_USB3_TUNNELING 0x00000001 diff --git a/patches.suse/ACPI-CPPC-fix-typo-in-comment.patch b/patches.suse/ACPI-CPPC-fix-typo-in-comment.patch new file mode 100644 index 0000000..c0b0afa --- /dev/null +++ b/patches.suse/ACPI-CPPC-fix-typo-in-comment.patch @@ -0,0 +1,28 @@ +From: Julia Lawall +Date: Sat, 21 May 2022 13:10:13 +0200 +Subject: ACPI: CPPC: fix typo in comment +Patch-mainline: v5.19-rc1 +Git-commit: 9e12eb8231496682525b6f9ba04131132d139759 +References: jsc#PED-1408 + +Spelling mistake (triple letters) in comment. +Detected with the help of Coccinelle. + +Signed-off-by: Julia Lawall +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/cppc_acpi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/acpi/cppc_acpi.c ++++ b/drivers/acpi/cppc_acpi.c +@@ -315,7 +315,7 @@ static int send_pcc_cmd(int pcc_ss_id, u + goto end; + } + +- /* wait for completion and check for PCC errro bit */ ++ /* wait for completion and check for PCC error bit */ + ret = check_pcc_chan(pcc_ss_id, true); + + if (pcc_ss_data->pcc_mrtt) diff --git a/patches.suse/ACPI-DPTF-Add-support-for-high-frequency-impedance-n.patch b/patches.suse/ACPI-DPTF-Add-support-for-high-frequency-impedance-n.patch new file mode 100644 index 0000000..f5d88f8 --- /dev/null +++ b/patches.suse/ACPI-DPTF-Add-support-for-high-frequency-impedance-n.patch @@ -0,0 +1,40 @@ +From: Sumeet Pawnikar +Date: Thu, 5 May 2022 22:30:19 +0530 +Subject: ACPI: DPTF: Add support for high frequency impedance notification +Patch-mainline: v5.19-rc1 +Git-commit: 42e5ed0618030543e4f679afa5e42ec8ab9337bb +References: jsc#PED-1408 + +Add high frequency impedance notification support under DPTF. +This returns high frequency impedance value that can be obtained +from battery fuel gauge whenever there is change over a threshold. +Also, corrected the typo from IMPEDANCED_CHNGED to IMPEDANCE_CHANGED. + +Signed-off-by: Sumeet Pawnikar +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/dptf/dptf_power.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/acpi/dptf/dptf_power.c ++++ b/drivers/acpi/dptf/dptf_power.c +@@ -115,7 +115,7 @@ static const struct attribute_group dptf + #define POWER_STATE_CHANGED 0x81 + #define STEADY_STATE_POWER_CHANGED 0x83 + #define POWER_PROP_CHANGE_EVENT 0x84 +-#define IMPEDANCED_CHNGED 0x85 ++#define IMPEDANCE_CHANGED 0x85 + #define VOLTAGE_CURRENT_CHANGED 0x86 + + static long long dptf_participant_type(acpi_handle handle) +@@ -148,6 +148,9 @@ static void dptf_power_notify(acpi_handl + case STEADY_STATE_POWER_CHANGED: + attr = "max_steady_state_power_mw"; + break; ++ case IMPEDANCE_CHANGED: ++ attr = "high_freq_impedance_mohm"; ++ break; + case VOLTAGE_CURRENT_CHANGED: + attr = "no_load_voltage_mv"; + break; diff --git a/patches.suse/ACPI-DPTF-Correct-description-of-INT3407-INT3532-att.patch b/patches.suse/ACPI-DPTF-Correct-description-of-INT3407-INT3532-att.patch new file mode 100644 index 0000000..be99356 --- /dev/null +++ b/patches.suse/ACPI-DPTF-Correct-description-of-INT3407-INT3532-att.patch @@ -0,0 +1,35 @@ +From: Sumeet Pawnikar +Date: Thu, 21 Apr 2022 22:25:43 +0530 +Subject: ACPI: DPTF: Correct description of INT3407 / INT3532 attributes +Patch-mainline: v5.19-rc1 +Git-commit: 290a20782ac6d1bfbd70541cacddaf9acbe1f1f5 +References: jsc#PED-1408 + +Remove duplicate comments of PBSS for Battery steady state power and +correct the typo for PMAX Maximum platform power. + +Signed-off-by: Sumeet Pawnikar +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/dptf/dptf_power.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/drivers/acpi/dptf/dptf_power.c ++++ b/drivers/acpi/dptf/dptf_power.c +@@ -12,14 +12,12 @@ + /* + * Presentation of attributes which are defined for INT3407 and INT3532. + * They are: +- * PMAX : Maximum platform powe ++ * PMAX : Maximum platform power + * PSRC : Platform power source + * ARTG : Adapter rating + * CTYP : Charger type +- * PBSS : Battery steady power + * PROP : Rest of worst case platform Power + * PBSS : Power Battery Steady State +- * PBSS : Power Battery Steady State + * RBHF : High Frequency Impedance + * VBNL : Instantaneous No-Load Voltage + * CMPP : Current Discharge Capability diff --git a/patches.suse/ACPI-DPTF-Support-Meteor-Lake.patch b/patches.suse/ACPI-DPTF-Support-Meteor-Lake.patch new file mode 100644 index 0000000..15ea4e6 --- /dev/null +++ b/patches.suse/ACPI-DPTF-Support-Meteor-Lake.patch @@ -0,0 +1,95 @@ +From: Sumeet Pawnikar +Date: Mon, 23 May 2022 23:16:30 +0530 +Subject: ACPI: DPTF: Support Meteor Lake +Patch-mainline: v5.19-rc1 +Git-commit: 657b95d34ba3cecc62993817a21896475110603d +References: jsc#PED-1408 + +Add Meteor Lake ACPI IDs for DPTF devices. + +Signed-off-by: Sumeet Pawnikar +Reviewed-by: Srinivas Pandruvada +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/dptf/dptf_pch_fivr.c | 1 + + drivers/acpi/dptf/dptf_power.c | 2 ++ + drivers/acpi/dptf/int340x_thermal.c | 6 ++++++ + drivers/acpi/fan.h | 1 + + drivers/thermal/intel/int340x_thermal/int3400_thermal.c | 1 + + drivers/thermal/intel/int340x_thermal/int3403_thermal.c | 1 + + 6 files changed, 12 insertions(+) + +--- a/drivers/acpi/dptf/dptf_pch_fivr.c ++++ b/drivers/acpi/dptf/dptf_pch_fivr.c +@@ -151,6 +151,7 @@ static int pch_fivr_remove(struct platfo + static const struct acpi_device_id pch_fivr_device_ids[] = { + {"INTC1045", 0}, + {"INTC1049", 0}, ++ {"INTC1064", 0}, + {"INTC10A3", 0}, + {"", 0}, + }; +--- a/drivers/acpi/dptf/dptf_power.c ++++ b/drivers/acpi/dptf/dptf_power.c +@@ -232,6 +232,8 @@ static const struct acpi_device_id int34 + {"INTC1050", 0}, + {"INTC1060", 0}, + {"INTC1061", 0}, ++ {"INTC1065", 0}, ++ {"INTC1066", 0}, + {"INTC10A4", 0}, + {"INTC10A5", 0}, + {"", 0}, +--- a/drivers/acpi/dptf/int340x_thermal.c ++++ b/drivers/acpi/dptf/int340x_thermal.c +@@ -27,6 +27,7 @@ static const struct acpi_device_id int34 + {"INT3532"}, + {"INTC1040"}, + {"INTC1041"}, ++ {"INTC1042"}, + {"INTC1043"}, + {"INTC1044"}, + {"INTC1045"}, +@@ -37,6 +38,11 @@ static const struct acpi_device_id int34 + {"INTC1050"}, + {"INTC1060"}, + {"INTC1061"}, ++ {"INTC1062"}, ++ {"INTC1063"}, ++ {"INTC1064"}, ++ {"INTC1065"}, ++ {"INTC1066"}, + {"INTC10A0"}, + {"INTC10A1"}, + {"INTC10A2"}, +--- a/drivers/acpi/fan.h ++++ b/drivers/acpi/fan.h +@@ -14,6 +14,7 @@ + {"INT3404", }, /* Fan */ \ + {"INTC1044", }, /* Fan for Tiger Lake generation */ \ + {"INTC1048", }, /* Fan for Alder Lake generation */ \ ++ {"INTC1063", }, /* Fan for Meteor Lake generation */ \ + {"INTC10A2", }, /* Fan for Raptor Lake generation */ \ + {"PNP0C0B", } /* Generic ACPI fan */ + +--- a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c ++++ b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c +@@ -594,6 +594,7 @@ static const struct acpi_device_id int34 + {"INT3400", 0}, + {"INTC1040", 0}, + {"INTC1041", 0}, ++ {"INTC1042", 0}, + {} + }; + +--- a/drivers/thermal/intel/int340x_thermal/int3403_thermal.c ++++ b/drivers/thermal/intel/int340x_thermal/int3403_thermal.c +@@ -285,6 +285,7 @@ static const struct acpi_device_id int34 + {"INT3403", 0}, + {"INTC1043", 0}, + {"INTC1046", 0}, ++ {"INTC1062", 0}, + {"", 0}, + }; + MODULE_DEVICE_TABLE(acpi, int3403_device_ids); diff --git a/patches.suse/ACPI-HMAT-Release-platform-device-in-case-of-platfor.patch b/patches.suse/ACPI-HMAT-Release-platform-device-in-case-of-platfor.patch new file mode 100644 index 0000000..b15a330 --- /dev/null +++ b/patches.suse/ACPI-HMAT-Release-platform-device-in-case-of-platfor.patch @@ -0,0 +1,51 @@ +From 6a02124c87f0b61dcaaeb65e7fd406d8afb40fd4 Mon Sep 17 00:00:00 2001 +From: Lin Yujun +Date: Wed, 14 Sep 2022 11:37:55 +0800 +Subject: [PATCH] ACPI: HMAT: Release platform device in case of platform_device_add_data() fails +Git-commit: 6a02124c87f0b61dcaaeb65e7fd406d8afb40fd4 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The platform device is not released when platform_device_add_data() +fails. And platform_device_put() perfom one more pointer check than +put_device() to check for errors in the 'pdev' pointer. + +Use platform_device_put() to release platform device in +platform_device_add()/platform_device_add_data()/ +platform_device_add_resources() error case. + +Fixes: c01044cc8191 ("ACPI: HMAT: refactor hmat_register_target_device to hmem_register_device") +Signed-off-by: Lin Yujun +Link: https://lore.kernel.org/r/20220914033755.99924-1-linyujun809@huawei.com +Signed-off-by: Dan Williams +Acked-by: Takashi Iwai + +--- + drivers/dax/hmem/device.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/dax/hmem/device.c b/drivers/dax/hmem/device.c +index cb6401c9e9a4..f87ae005431a 100644 +--- a/drivers/dax/hmem/device.c ++++ b/drivers/dax/hmem/device.c +@@ -47,7 +47,7 @@ void hmem_register_device(int target_nid, struct resource *r) + rc = platform_device_add_data(pdev, &info, sizeof(info)); + if (rc < 0) { + pr_err("hmem memregion_info allocation failure for %pr\n", &res); +- goto out_pdev; ++ goto out_resource; + } + + rc = platform_device_add_resources(pdev, &res, 1); +@@ -65,7 +65,7 @@ void hmem_register_device(int target_nid, struct resource *r) + return; + + out_resource: +- put_device(&pdev->dev); ++ platform_device_put(pdev); + out_pdev: + memregion_free(id); + } +-- +2.35.3 + diff --git a/patches.suse/ACPI-NFIT-Drop-nfit_device_lock.patch b/patches.suse/ACPI-NFIT-Drop-nfit_device_lock.patch new file mode 100644 index 0000000..137b6f2 --- /dev/null +++ b/patches.suse/ACPI-NFIT-Drop-nfit_device_lock.patch @@ -0,0 +1,162 @@ +From: Dan Williams +Date: Thu, 21 Apr 2022 08:33:34 -0700 +Subject: ACPI: NFIT: Drop nfit_device_lock() +Patch-mainline: v5.19-rc1 +Git-commit: 1550a17a7da2936281fda5e87fc454cee3c9c683 +References: jsc#PED-1408 + +The nfit_device_lock() helper was added to provide lockdep coverage for +the NFIT driver's usage of device_lock() on the nvdimm_bus object. Now +that nvdimm_bus objects have their own lock class this wrapper can be +dropped. + +Cc: Vishal Verma +Cc: Dave Jiang +Cc: Ira Weiny +Reviewed-by: Ira Weiny +Link: https://lore.kernel.org/r/165055521409.3745911.8085645201146909612.stgit@dwillia2-desk3.amr.corp.intel.com +Signed-off-by: Dan Williams +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/nfit/core.c | 30 +++++++++++++++--------------- + drivers/acpi/nfit/nfit.h | 24 ------------------------ + 2 files changed, 15 insertions(+), 39 deletions(-) + +--- a/drivers/acpi/nfit/core.c ++++ b/drivers/acpi/nfit/core.c +@@ -1305,7 +1305,7 @@ static ssize_t hw_error_scrub_store(stru + if (rc) + return rc; + +- nfit_device_lock(dev); ++ device_lock(dev); + nd_desc = dev_get_drvdata(dev); + if (nd_desc) { + struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc); +@@ -1322,7 +1322,7 @@ static ssize_t hw_error_scrub_store(stru + break; + } + } +- nfit_device_unlock(dev); ++ device_unlock(dev); + if (rc) + return rc; + return size; +@@ -1342,10 +1342,10 @@ static ssize_t scrub_show(struct device + ssize_t rc = -ENXIO; + bool busy; + +- nfit_device_lock(dev); ++ device_lock(dev); + nd_desc = dev_get_drvdata(dev); + if (!nd_desc) { +- nfit_device_unlock(dev); ++ device_unlock(dev); + return rc; + } + acpi_desc = to_acpi_desc(nd_desc); +@@ -1362,7 +1362,7 @@ static ssize_t scrub_show(struct device + } + + mutex_unlock(&acpi_desc->init_mutex); +- nfit_device_unlock(dev); ++ device_unlock(dev); + return rc; + } + +@@ -1379,14 +1379,14 @@ static ssize_t scrub_store(struct device + if (val != 1) + return -EINVAL; + +- nfit_device_lock(dev); ++ device_lock(dev); + nd_desc = dev_get_drvdata(dev); + if (nd_desc) { + struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc); + + rc = acpi_nfit_ars_rescan(acpi_desc, ARS_REQ_LONG); + } +- nfit_device_unlock(dev); ++ device_unlock(dev); + if (rc) + return rc; + return size; +@@ -1774,9 +1774,9 @@ static void acpi_nvdimm_notify(acpi_hand + struct acpi_device *adev = data; + struct device *dev = &adev->dev; + +- nfit_device_lock(dev->parent); ++ device_lock(dev->parent); + __acpi_nvdimm_notify(dev, event); +- nfit_device_unlock(dev->parent); ++ device_unlock(dev->parent); + } + + static bool acpi_nvdimm_has_method(struct acpi_device *adev, char *method) +@@ -3532,8 +3532,8 @@ static int acpi_nfit_flush_probe(struct + struct device *dev = acpi_desc->dev; + + /* Bounce the device lock to flush acpi_nfit_add / acpi_nfit_notify */ +- nfit_device_lock(dev); +- nfit_device_unlock(dev); ++ device_lock(dev); ++ device_unlock(dev); + + /* Bounce the init_mutex to complete initial registration */ + mutex_lock(&acpi_desc->init_mutex); +@@ -3686,8 +3686,8 @@ void acpi_nfit_shutdown(void *data) + * acpi_nfit_ars_rescan() submissions have had a chance to + * either submit or see ->cancel set. + */ +- nfit_device_lock(bus_dev); +- nfit_device_unlock(bus_dev); ++ device_lock(bus_dev); ++ device_unlock(bus_dev); + + flush_workqueue(nfit_wq); + } +@@ -3830,9 +3830,9 @@ EXPORT_SYMBOL_GPL(__acpi_nfit_notify); + + static void acpi_nfit_notify(struct acpi_device *adev, u32 event) + { +- nfit_device_lock(&adev->dev); ++ device_lock(&adev->dev); + __acpi_nfit_notify(&adev->dev, adev->handle, event); +- nfit_device_unlock(&adev->dev); ++ device_unlock(&adev->dev); + } + + static const struct acpi_device_id acpi_nfit_ids[] = { +--- a/drivers/acpi/nfit/nfit.h ++++ b/drivers/acpi/nfit/nfit.h +@@ -343,30 +343,6 @@ static inline struct acpi_nfit_desc *to_ + return container_of(nd_desc, struct acpi_nfit_desc, nd_desc); + } + +-#ifdef CONFIG_PROVE_LOCKING +-static inline void nfit_device_lock(struct device *dev) +-{ +- device_lock(dev); +- mutex_lock(&dev->lockdep_mutex); +-} +- +-static inline void nfit_device_unlock(struct device *dev) +-{ +- mutex_unlock(&dev->lockdep_mutex); +- device_unlock(dev); +-} +-#else +-static inline void nfit_device_lock(struct device *dev) +-{ +- device_lock(dev); +-} +- +-static inline void nfit_device_unlock(struct device *dev) +-{ +- device_unlock(dev); +-} +-#endif +- + const guid_t *to_nfit_uuid(enum nfit_uuids id); + int acpi_nfit_init(struct acpi_nfit_desc *acpi_desc, void *nfit, acpi_size sz); + void acpi_nfit_shutdown(void *data); diff --git a/patches.suse/ACPI-PM-Always-print-final-debug-message-in-acpi_dev.patch b/patches.suse/ACPI-PM-Always-print-final-debug-message-in-acpi_dev.patch new file mode 100644 index 0000000..e59b9cf --- /dev/null +++ b/patches.suse/ACPI-PM-Always-print-final-debug-message-in-acpi_dev.patch @@ -0,0 +1,75 @@ +From: "Rafael J. Wysocki" +Date: Thu, 14 Apr 2022 14:58:42 +0200 +Subject: ACPI: PM: Always print final debug message in acpi_device_set_power() +Patch-mainline: v5.19-rc1 +Git-commit: 6dd4a29d26200d303d354ee8fc806113b5fcc882 +References: jsc#PED-1408 + +acpi_device_set_power() prints debug messages regarding its outcome +(whether or not the power state has been changed and how) in all +cases except when the device whose power state is being changed to D0 +is in that power state already. + +Make acpi_device_set_power() print a final debug message in that case +too and while at it, fix the indentation of the "end" label in this +function. + +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/device_pm.c | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +--- a/drivers/acpi/device_pm.c ++++ b/drivers/acpi/device_pm.c +@@ -173,11 +173,8 @@ int acpi_device_set_power(struct acpi_de + /* Make sure this is a valid target state */ + + /* There is a special case for D0 addressed below. */ +- if (state > ACPI_STATE_D0 && state == device->power.state) { +- acpi_handle_debug(device->handle, "Already in %s\n", +- acpi_power_state_string(state)); +- return 0; +- } ++ if (state > ACPI_STATE_D0 && state == device->power.state) ++ goto no_change; + + if (state == ACPI_STATE_D3_COLD) { + /* +@@ -249,7 +246,7 @@ int acpi_device_set_power(struct acpi_de + + /* Nothing to do here if _PSC is not present. */ + if (!device->power.flags.explicit_get) +- return 0; ++ goto no_change; + + /* + * The power state of the device was set to D0 last +@@ -264,13 +261,13 @@ int acpi_device_set_power(struct acpi_de + */ + result = acpi_dev_pm_explicit_get(device, &psc); + if (result || psc == ACPI_STATE_D0) +- return 0; ++ goto no_change; + } + + result = acpi_dev_pm_explicit_set(device, ACPI_STATE_D0); + } + +- end: ++end: + if (result) { + acpi_handle_debug(device->handle, + "Failed to change power state to %s\n", +@@ -282,6 +279,11 @@ int acpi_device_set_power(struct acpi_de + } + + return result; ++ ++no_change: ++ acpi_handle_debug(device->handle, "Already in %s\n", ++ acpi_power_state_string(state)); ++ return 0; + } + EXPORT_SYMBOL(acpi_device_set_power); + diff --git a/patches.suse/ACPI-PM-Change-pr_fmt-in-device_pm.c.patch b/patches.suse/ACPI-PM-Change-pr_fmt-in-device_pm.c.patch new file mode 100644 index 0000000..5914762 --- /dev/null +++ b/patches.suse/ACPI-PM-Change-pr_fmt-in-device_pm.c.patch @@ -0,0 +1,31 @@ +From: "Rafael J. Wysocki" +Date: Mon, 4 Apr 2022 17:02:00 +0200 +Subject: ACPI: PM: Change pr_fmt() in device_pm.c +Patch-mainline: v5.19-rc1 +Git-commit: 255a04cc457e57c1b429c2a5c0f4d7604b1ef41b +References: jsc#PED-1408 + +All messages printed by functions in this file either contain +the "ACPI" or "acpi" string regardless of the format, or they don't +need to contain it at all. + +In the former case, the "ACPI:" string added by the format is +redundant, so drop it from there. + +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/device_pm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/acpi/device_pm.c ++++ b/drivers/acpi/device_pm.c +@@ -10,7 +10,7 @@ + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +-#define pr_fmt(fmt) "ACPI: PM: " fmt ++#define pr_fmt(fmt) "PM: " fmt + + #include + #include diff --git a/patches.suse/ACPI-PM-Convert-debug-message-in-acpi_device_get_pow.patch b/patches.suse/ACPI-PM-Convert-debug-message-in-acpi_device_get_pow.patch new file mode 100644 index 0000000..e754e09 --- /dev/null +++ b/patches.suse/ACPI-PM-Convert-debug-message-in-acpi_device_get_pow.patch @@ -0,0 +1,31 @@ +From: "Rafael J. Wysocki" +Date: Mon, 4 Apr 2022 17:00:45 +0200 +Subject: ACPI: PM: Convert debug message in acpi_device_get_power() +Patch-mainline: v5.19-rc1 +Git-commit: 198ee4377b9675898a53c1a02f6ba55d186cc806 +References: jsc#PED-1408 + +Convert the debug message printed by acpi_device_get_power() to +acpi_handle_debug(), because that function is also called when +the ACPI device object name has not been set yet and the dev_dbg() +message printed by it at that time is not useful. + +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/device_pm.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/acpi/device_pm.c ++++ b/drivers/acpi/device_pm.c +@@ -130,8 +130,8 @@ int acpi_device_get_power(struct acpi_de + *state = result; + + out: +- dev_dbg(&device->dev, "Device power state is %s\n", +- acpi_power_state_string(*state)); ++ acpi_handle_debug(device->handle, "Power state: %s\n", ++ acpi_power_state_string(*state)); + + return 0; + } diff --git a/patches.suse/ACPI-PM-Introduce-acpi_dev_power_up_children_with_ad.patch b/patches.suse/ACPI-PM-Introduce-acpi_dev_power_up_children_with_ad.patch new file mode 100644 index 0000000..5a246af --- /dev/null +++ b/patches.suse/ACPI-PM-Introduce-acpi_dev_power_up_children_with_ad.patch @@ -0,0 +1,72 @@ +From: "Rafael J. Wysocki" +Date: Mon, 4 Apr 2022 17:23:13 +0200 +Subject: ACPI: PM: Introduce acpi_dev_power_up_children_with_adr() +Patch-mainline: v5.19-rc1 +Git-commit: b7dd6298db81ea6dd902f1787eaf9a43228e2707 +References: jsc#PED-1408 + +Introduce a function powering up all of the children of a given ACPI +device object that are power-manageable and hold valid _ADR ACPI +objects so as to make it possible to prepare the corresponding +"physical" devices for enumeration carried out by a bus type driver, +like PCI. + +This function will be used in a subsequent change set. + +Signed-off-by: Rafael J. Wysocki +Reviewed-by: Mika Westerberg +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/device_pm.c | 30 ++++++++++++++++++++++++++++++ + include/acpi/acpi_bus.h | 1 + + 2 files changed, 31 insertions(+) + +--- a/drivers/acpi/device_pm.c ++++ b/drivers/acpi/device_pm.c +@@ -429,6 +429,36 @@ bool acpi_bus_power_manageable(acpi_hand + } + EXPORT_SYMBOL(acpi_bus_power_manageable); + ++static int acpi_power_up_if_adr_present(struct device *dev, void *not_used) ++{ ++ struct acpi_device *adev; ++ ++ adev = to_acpi_device(dev); ++ if (!(adev->flags.power_manageable && adev->pnp.type.bus_address)) ++ return 0; ++ ++ acpi_handle_debug(adev->handle, "Power state: %s\n", ++ acpi_power_state_string(adev->power.state)); ++ ++ if (adev->power.state == ACPI_STATE_D3_COLD) ++ return acpi_device_set_power(adev, ACPI_STATE_D0); ++ ++ return 0; ++} ++ ++/** ++ * acpi_dev_power_up_children_with_adr - Power up childres with valid _ADR ++ * @adev: Parent ACPI device object. ++ * ++ * Change the power states of the direct children of @adev that are in D3cold ++ * and hold valid _ADR objects to D0 in order to allow bus (e.g. PCI) ++ * enumeration code to access them. ++ */ ++void acpi_dev_power_up_children_with_adr(struct acpi_device *adev) ++{ ++ acpi_dev_for_each_child(adev, acpi_power_up_if_adr_present, NULL); ++} ++ + #ifdef CONFIG_PM + static DEFINE_MUTEX(acpi_pm_notifier_lock); + static DEFINE_MUTEX(acpi_pm_notifier_install_lock); +--- a/include/acpi/acpi_bus.h ++++ b/include/acpi/acpi_bus.h +@@ -525,6 +525,7 @@ int acpi_device_fix_up_power(struct acpi + int acpi_bus_update_power(acpi_handle handle, int *state_p); + int acpi_device_update_power(struct acpi_device *device, int *state_p); + bool acpi_bus_power_manageable(acpi_handle handle); ++void acpi_dev_power_up_children_with_adr(struct acpi_device *adev); + int acpi_device_power_add_dependent(struct acpi_device *adev, + struct device *dev); + void acpi_device_power_remove_dependent(struct acpi_device *adev, diff --git a/patches.suse/ACPI-PM-Unify-debug-messages-in-acpi_device_set_powe.patch b/patches.suse/ACPI-PM-Unify-debug-messages-in-acpi_device_set_powe.patch new file mode 100644 index 0000000..54b4041 --- /dev/null +++ b/patches.suse/ACPI-PM-Unify-debug-messages-in-acpi_device_set_powe.patch @@ -0,0 +1,89 @@ +From: "Rafael J. Wysocki" +Date: Mon, 4 Apr 2022 17:03:11 +0200 +Subject: ACPI: PM: Unify debug messages in acpi_device_set_power() +Patch-mainline: v5.19-rc1 +Git-commit: f4f3548dc8d53d683770b058fdafa01fd7c07669 +References: jsc#PED-1408 + +Convert all of the debug messages printed by acpi_device_set_power() +to acpi_handle_debug() and adjust them slightly for consistency with +acpi_device_get_power() and other acpi_device_set_power() debug +messages. + +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/device_pm.c | 36 +++++++++++++++++++----------------- + 1 file changed, 19 insertions(+), 17 deletions(-) + +--- a/drivers/acpi/device_pm.c ++++ b/drivers/acpi/device_pm.c +@@ -174,8 +174,8 @@ int acpi_device_set_power(struct acpi_de + + /* There is a special case for D0 addressed below. */ + if (state > ACPI_STATE_D0 && state == device->power.state) { +- dev_dbg(&device->dev, "Device already in %s\n", +- acpi_power_state_string(state)); ++ acpi_handle_debug(device->handle, "Already in %s\n", ++ acpi_power_state_string(state)); + return 0; + } + +@@ -189,17 +189,17 @@ int acpi_device_set_power(struct acpi_de + if (!device->power.states[ACPI_STATE_D3_COLD].flags.valid) + target_state = state; + } else if (!device->power.states[state].flags.valid) { +- dev_warn(&device->dev, "Power state %s not supported\n", +- acpi_power_state_string(state)); ++ acpi_handle_debug(device->handle, "Power state %s not supported\n", ++ acpi_power_state_string(state)); + return -ENODEV; + } + +- if (!device->power.flags.ignore_parent && +- device->parent && (state < device->parent->power.state)) { +- dev_warn(&device->dev, +- "Cannot transition to power state %s for parent in %s\n", +- acpi_power_state_string(state), +- acpi_power_state_string(device->parent->power.state)); ++ if (!device->power.flags.ignore_parent && device->parent && ++ state < device->parent->power.state) { ++ acpi_handle_debug(device->handle, ++ "Cannot transition to %s for parent in %s\n", ++ acpi_power_state_string(state), ++ acpi_power_state_string(device->parent->power.state)); + return -ENODEV; + } + +@@ -216,9 +216,10 @@ int acpi_device_set_power(struct acpi_de + * (deeper) states to higher-power (shallower) states. + */ + if (state < device->power.state) { +- dev_warn(&device->dev, "Cannot transition from %s to %s\n", +- acpi_power_state_string(device->power.state), +- acpi_power_state_string(state)); ++ acpi_handle_debug(device->handle, ++ "Cannot transition from %s to %s\n", ++ acpi_power_state_string(device->power.state), ++ acpi_power_state_string(state)); + return -ENODEV; + } + +@@ -271,12 +272,13 @@ int acpi_device_set_power(struct acpi_de + + end: + if (result) { +- dev_warn(&device->dev, "Failed to change power state to %s\n", +- acpi_power_state_string(target_state)); ++ acpi_handle_debug(device->handle, ++ "Failed to change power state to %s\n", ++ acpi_power_state_string(target_state)); + } else { + device->power.state = target_state; +- dev_dbg(&device->dev, "Power state changed to %s\n", +- acpi_power_state_string(target_state)); ++ acpi_handle_debug(device->handle, "Power state changed to %s\n", ++ acpi_power_state_string(target_state)); + } + + return result; diff --git a/patches.suse/ACPI-SPCR-Add-support-for-NVIDIA-16550-compatible-po.patch b/patches.suse/ACPI-SPCR-Add-support-for-NVIDIA-16550-compatible-po.patch new file mode 100644 index 0000000..87a1217 --- /dev/null +++ b/patches.suse/ACPI-SPCR-Add-support-for-NVIDIA-16550-compatible-po.patch @@ -0,0 +1,28 @@ +From: Jeff Brasen +Date: Fri, 11 Mar 2022 16:53:10 +0000 +Subject: ACPI: SPCR: Add support for NVIDIA 16550-compatible port subtype +Patch-mainline: v5.19-rc1 +Git-commit: 3a506ca2cc042bb16d563078e10ef9493588e545 +References: jsc#PED-1408 + +Add support for the NVIDIA specific 16550 subtype to SPCR table parsing +routine. + +Signed-off-by: Jeff Brasen +Signed-off-by: Jon Hunter +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/spcr.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/acpi/spcr.c ++++ b/drivers/acpi/spcr.c +@@ -142,6 +142,7 @@ int __init acpi_parse_spcr(bool enable_e + case ACPI_DBG2_16550_COMPATIBLE: + case ACPI_DBG2_16550_SUBSET: + case ACPI_DBG2_16550_WITH_GAS: ++ case ACPI_DBG2_16550_NVIDIA: + uart = "uart"; + break; + default: diff --git a/patches.suse/ACPI-acpi_pad-Do-not-launch-acpi_pad-threads-on-idle-cpus.patch b/patches.suse/ACPI-acpi_pad-Do-not-launch-acpi_pad-threads-on-idle-cpus.patch index 4d6696d..3ff86ad 100644 --- a/patches.suse/ACPI-acpi_pad-Do-not-launch-acpi_pad-threads-on-idle-cpus.patch +++ b/patches.suse/ACPI-acpi_pad-Do-not-launch-acpi_pad-threads-on-idle-cpus.patch @@ -30,15 +30,15 @@ Acked-by: Giovanni Gherdovich --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c -@@ -26,6 +26,8 @@ +@@ -17,6 +17,8 @@ #include #include #include +#include +#include + #include #include #include - @@ -254,12 +256,62 @@ static void set_power_saving_task_num(un } } diff --git a/patches.suse/ACPI-battery-Make-not-charging-the-default-on-no-cha.patch b/patches.suse/ACPI-battery-Make-not-charging-the-default-on-no-cha.patch new file mode 100644 index 0000000..1636f5d --- /dev/null +++ b/patches.suse/ACPI-battery-Make-not-charging-the-default-on-no-cha.patch @@ -0,0 +1,80 @@ +From: Werner Sembach +Date: Wed, 27 Apr 2022 17:40:53 +0200 +Subject: ACPI: battery: Make "not-charging" the default on no charging or full + info +Patch-mainline: v5.19-rc1 +Git-commit: 185d20694a8aceb4eda9fc1314cbaad0df0aab07 +References: jsc#PED-1408 + +When the battery is neither charging or discharging and is not full, +"not-charging" is a useful status description for the case in general. +Currently this state is set as "unknown" by default, expect when this is +explicitly replaced with "not-charging" on a per device or per vendor +basis. + +A lot of devices have this state without a BIOS specification available +explicitly describing it. e.g. some current Clevo barebones have a BIOS +setting to stop charging at a user defined battery level. + +Signed-off-by: Werner Sembach +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/battery.c | 24 +----------------------- + 1 file changed, 1 insertion(+), 23 deletions(-) + +--- a/drivers/acpi/battery.c ++++ b/drivers/acpi/battery.c +@@ -52,7 +52,6 @@ static bool battery_driver_registered; + static int battery_bix_broken_package; + static int battery_notification_delay_ms; + static int battery_ac_is_broken; +-static int battery_quirk_notcharging; + static unsigned int cache_time = 1000; + module_param(cache_time, uint, 0644); + MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); +@@ -216,10 +215,8 @@ static int acpi_battery_get_property(str + val->intval = POWER_SUPPLY_STATUS_CHARGING; + else if (acpi_battery_is_charged(battery)) + val->intval = POWER_SUPPLY_STATUS_FULL; +- else if (battery_quirk_notcharging) +- val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; + else +- val->intval = POWER_SUPPLY_STATUS_UNKNOWN; ++ val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; + break; + case POWER_SUPPLY_PROP_PRESENT: + val->intval = acpi_battery_present(battery); +@@ -1105,12 +1102,6 @@ battery_ac_is_broken_quirk(const struct + return 0; + } + +-static int __init battery_quirk_not_charging(const struct dmi_system_id *d) +-{ +- battery_quirk_notcharging = 1; +- return 0; +-} +- + static const struct dmi_system_id bat_dmi_table[] __initconst = { + { + /* NEC LZ750/LS */ +@@ -1140,19 +1131,6 @@ static const struct dmi_system_id bat_dm + }, + }, + { +- /* +- * On Lenovo ThinkPads the BIOS specification defines +- * a state when the bits for charging and discharging +- * are both set to 0. That state is "Not Charging". +- */ +- .callback = battery_quirk_not_charging, +- .ident = "Lenovo ThinkPad", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), +- DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad"), +- }, +- }, +- { + /* Microsoft Surface Go 3 */ + .callback = battery_notification_delay_quirk, + .matches = { diff --git a/patches.suse/ACPI-bus-Avoid-non-ACPI-device-objects-in-walks-over.patch b/patches.suse/ACPI-bus-Avoid-non-ACPI-device-objects-in-walks-over.patch new file mode 100644 index 0000000..14137b5 --- /dev/null +++ b/patches.suse/ACPI-bus-Avoid-non-ACPI-device-objects-in-walks-over.patch @@ -0,0 +1,88 @@ +From: "Rafael J. Wysocki" +Date: Fri, 22 Apr 2022 17:13:48 +0200 +Subject: ACPI: bus: Avoid non-ACPI device objects in walks over children +Patch-mainline: v5.19-rc1 +Git-commit: 10fa1b2cdc899ab471000968af56215bf3c90d8e +References: jsc#PED-1408 + +When walking the children of an ACPI device, take extra care to avoid +using to_acpi_device() on the ones that are not ACPI devices, because +that may lead to out-of-bounds access and memory corruption. + +While at it, make the function passed to acpi_dev_for_each_child() +take a struct acpi_device pointer argument (instead of a struct device +one), so it is more straightforward to use. + +Fixes: b7dd6298db81 ("ACPI: PM: Introduce acpi_dev_power_up_children_with_adr()") +Reported-by: kernel test robot +BugLink: https://lore.kernel.org/lkml/20220420064725.GB16310@xsang-OptiPlex-9020/ +Signed-off-by: Rafael J. Wysocki +Reviewed-by: Mika Westerberg +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/bus.c | 24 ++++++++++++++++++++++-- + drivers/acpi/device_pm.c | 5 +---- + include/acpi/acpi_bus.h | 2 +- + 3 files changed, 24 insertions(+), 7 deletions(-) + +--- a/drivers/acpi/bus.c ++++ b/drivers/acpi/bus.c +@@ -1070,10 +1070,30 @@ int acpi_bus_for_each_dev(int (*fn)(stru + } + EXPORT_SYMBOL_GPL(acpi_bus_for_each_dev); + ++struct acpi_dev_walk_context { ++ int (*fn)(struct acpi_device *, void *); ++ void *data; ++}; ++ ++static int acpi_dev_for_one_check(struct device *dev, void *context) ++{ ++ struct acpi_dev_walk_context *adwc = context; ++ ++ if (dev->bus != &acpi_bus_type) ++ return 0; ++ ++ return adwc->fn(to_acpi_device(dev), adwc->data); ++} ++ + int acpi_dev_for_each_child(struct acpi_device *adev, +- int (*fn)(struct device *, void *), void *data) ++ int (*fn)(struct acpi_device *, void *), void *data) + { +- return device_for_each_child(&adev->dev, data, fn); ++ struct acpi_dev_walk_context adwc = { ++ .fn = fn, ++ .data = data, ++ }; ++ ++ return device_for_each_child(&adev->dev, &adwc, acpi_dev_for_one_check); + } + + /* -------------------------------------------------------------------------- +--- a/drivers/acpi/device_pm.c ++++ b/drivers/acpi/device_pm.c +@@ -429,11 +429,8 @@ bool acpi_bus_power_manageable(acpi_hand + } + EXPORT_SYMBOL(acpi_bus_power_manageable); + +-static int acpi_power_up_if_adr_present(struct device *dev, void *not_used) ++static int acpi_power_up_if_adr_present(struct acpi_device *adev, void *not_used) + { +- struct acpi_device *adev; +- +- adev = to_acpi_device(dev); + if (!(adev->flags.power_manageable && adev->pnp.type.bus_address)) + return 0; + +--- a/include/acpi/acpi_bus.h ++++ b/include/acpi/acpi_bus.h +@@ -482,7 +482,7 @@ extern struct bus_type acpi_bus_type; + + int acpi_bus_for_each_dev(int (*fn)(struct device *, void *), void *data); + int acpi_dev_for_each_child(struct acpi_device *adev, +- int (*fn)(struct device *, void *), void *data); ++ int (*fn)(struct acpi_device *, void *), void *data); + + /* + * Events diff --git a/patches.suse/ACPI-bus-Introduce-acpi_dev_for_each_child.patch b/patches.suse/ACPI-bus-Introduce-acpi_dev_for_each_child.patch new file mode 100644 index 0000000..ad7e58f --- /dev/null +++ b/patches.suse/ACPI-bus-Introduce-acpi_dev_for_each_child.patch @@ -0,0 +1,46 @@ +From: "Rafael J. Wysocki" +Date: Mon, 4 Apr 2022 17:21:50 +0200 +Subject: ACPI: bus: Introduce acpi_dev_for_each_child() +Patch-mainline: v5.19-rc1 +Git-commit: cf6ba0750a22a54f5101986401271429995cc4a0 +References: jsc#PED-1408 + +Introduce a wrapper around device_for_each_child() to iterate over +the children of a given ACPI device object. + +This function will be used in subsequent change sets. + +Signed-off-by: Rafael J. Wysocki +Reviewed-by: Mika Westerberg +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/bus.c | 6 ++++++ + include/acpi/acpi_bus.h | 2 ++ + 2 files changed, 8 insertions(+) + +--- a/drivers/acpi/bus.c ++++ b/drivers/acpi/bus.c +@@ -1070,6 +1070,12 @@ int acpi_bus_for_each_dev(int (*fn)(stru + } + EXPORT_SYMBOL_GPL(acpi_bus_for_each_dev); + ++int acpi_dev_for_each_child(struct acpi_device *adev, ++ int (*fn)(struct device *, void *), void *data) ++{ ++ return device_for_each_child(&adev->dev, data, fn); ++} ++ + /* -------------------------------------------------------------------------- + Initialization/Cleanup + -------------------------------------------------------------------------- */ +--- a/include/acpi/acpi_bus.h ++++ b/include/acpi/acpi_bus.h +@@ -481,6 +481,8 @@ void acpi_initialize_hp_context(struct a + extern struct bus_type acpi_bus_type; + + int acpi_bus_for_each_dev(int (*fn)(struct device *, void *), void *data); ++int acpi_dev_for_each_child(struct acpi_device *adev, ++ int (*fn)(struct device *, void *), void *data); + + /* + * Events diff --git a/patches.suse/ACPI-bus-Set-CPPC-_OSC-bits-for-all-and-when-CPPC_LI.patch b/patches.suse/ACPI-bus-Set-CPPC-_OSC-bits-for-all-and-when-CPPC_LI.patch new file mode 100644 index 0000000..09281ab --- /dev/null +++ b/patches.suse/ACPI-bus-Set-CPPC-_OSC-bits-for-all-and-when-CPPC_LI.patch @@ -0,0 +1,64 @@ +From: Pierre Gondois +Date: Wed, 18 May 2022 11:08:58 +0200 +Subject: ACPI: bus: Set CPPC _OSC bits for all and when CPPC_LIB is supported +Patch-mainline: v5.19-rc1 +Git-commit: 72f2ecb7ece7c1d89758d4929d98e95d95fe7199 +References: jsc#PED-1408 + +The _OSC method allows the OS and firmware to communicate about +supported features/capabitlities. It also allows the OS to take +control of some features. + +In ACPI 6.4, s6.2.11.2 Platform-Wide OSPM Capabilities, the CPPC +(resp. v2) bit should be set by the OS if it 'supports controlling +processor performance via the interfaces described in the _CPC +object'. + +The OS supports CPPC and parses the _CPC object only if +CONFIG_ACPI_CPPC_LIB is set. Replace the x86 specific +boot_cpu_has(X86_FEATURE_HWP) dynamic check with an arch +generic CONFIG_ACPI_CPPC_LIB build-time check. + +Note: +CONFIG_X86_INTEL_PSTATE selects CONFIG_ACPI_CPPC_LIB. + +Signed-off-by: Pierre Gondois +Reviewed-by: Sudeep Holla +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/bus.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +--- a/drivers/acpi/bus.c ++++ b/drivers/acpi/bus.c +@@ -329,10 +329,11 @@ static void acpi_bus_osc_negotiate_platf + #endif + #ifdef CONFIG_X86 + capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_GENERIC_INITIATOR_SUPPORT; +- if (boot_cpu_has(X86_FEATURE_HWP)) { +- capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPC_SUPPORT; +- capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPCV2_SUPPORT; +- } ++#endif ++ ++#ifdef CONFIG_ACPI_CPPC_LIB ++ capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPC_SUPPORT; ++ capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPCV2_SUPPORT; + #endif + + capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPC_FLEXIBLE_ADR_SPACE; +@@ -357,10 +358,9 @@ static void acpi_bus_osc_negotiate_platf + return; + } + +-#ifdef CONFIG_X86 +- if (boot_cpu_has(X86_FEATURE_HWP)) +- osc_sb_cppc_not_supported = !(capbuf_ret[OSC_SUPPORT_DWORD] & +- (OSC_SB_CPC_SUPPORT | OSC_SB_CPCV2_SUPPORT)); ++#ifdef CONFIG_ACPI_CPPC_LIB ++ osc_sb_cppc_not_supported = !(capbuf_ret[OSC_SUPPORT_DWORD] & ++ (OSC_SB_CPC_SUPPORT | OSC_SB_CPCV2_SUPPORT)); + #endif + + /* diff --git a/patches.suse/ACPI-clean-up-white-space-in-a-few-places-for-consis.patch b/patches.suse/ACPI-clean-up-white-space-in-a-few-places-for-consis.patch new file mode 100644 index 0000000..a7d5db4 --- /dev/null +++ b/patches.suse/ACPI-clean-up-white-space-in-a-few-places-for-consis.patch @@ -0,0 +1,54 @@ +From: Ian Cowan +Date: Fri, 6 May 2022 16:47:31 -0400 +Subject: ACPI: clean up white space in a few places for consistency +Patch-mainline: v5.19-rc1 +Git-commit: 4c19851c70bae39e85979a72954982891a72e1c2 +References: jsc#PED-1408 + +This cleans up a few line spaces so that it is consistent with the rest +of the file. There are a few places where a space was added before a +return and two spots where a double line space was made into one line +space. + +Signed-off-by: Ian Cowan +[ rjw: Subject adjustment ] +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/ac.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/acpi/ac.c ++++ b/drivers/acpi/ac.c +@@ -32,7 +32,6 @@ MODULE_AUTHOR("Paul Diefenbaugh"); + MODULE_DESCRIPTION("ACPI AC Adapter Driver"); + MODULE_LICENSE("GPL"); + +- + static int acpi_ac_add(struct acpi_device *device); + static int acpi_ac_remove(struct acpi_device *device); + static void acpi_ac_notify(struct acpi_device *device, u32 event); +@@ -125,6 +124,7 @@ static int get_ac_property(struct power_ + default: + return -EINVAL; + } ++ + return 0; + } + +@@ -286,6 +286,7 @@ static int acpi_ac_resume(struct device + return 0; + if (old_state != ac->state) + kobject_uevent(&ac->charger->dev.kobj, KOBJ_CHANGE); ++ + return 0; + } + #else +@@ -296,7 +297,6 @@ static int acpi_ac_remove(struct acpi_de + { + struct acpi_ac *ac = NULL; + +- + if (!device || !acpi_driver_data(device)) + return -EINVAL; + diff --git a/patches.suse/ACPI-glue-Rearrange-find_child_checks.patch b/patches.suse/ACPI-glue-Rearrange-find_child_checks.patch new file mode 100644 index 0000000..dd757ec --- /dev/null +++ b/patches.suse/ACPI-glue-Rearrange-find_child_checks.patch @@ -0,0 +1,62 @@ +From: "Rafael J. Wysocki" +Date: Thu, 5 May 2022 20:52:57 +0200 +Subject: ACPI: glue: Rearrange find_child_checks() +Patch-mainline: v5.19-rc1 +Git-commit: b7fbf4cebd7c693d30e258f2ce27a362848634ae +References: jsc#PED-1408 + +Notice that it is not necessary to evaluate _STA in find_child_checks() +if the device is expected to have children, but there are none, so +move the children check to the front of the function. + +Also notice that FIND_CHILD_MIN_SCORE can be returned right away if +_STA is missing, so make the function do so. + +Finally, replace the ternary operator in the return statement argument +with an if () and a standalone return which is somewhat easier to +follow. + +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/glue.c | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +--- a/drivers/acpi/glue.c ++++ b/drivers/acpi/glue.c +@@ -79,17 +79,17 @@ static struct acpi_bus_type *acpi_get_bu + + static int find_child_checks(struct acpi_device *adev, bool check_children) + { +- bool sta_present = true; + unsigned long long sta; + acpi_status status; + ++ if (check_children && list_empty(&adev->children)) ++ return -ENODEV; ++ + status = acpi_evaluate_integer(adev->handle, "_STA", NULL, &sta); + if (status == AE_NOT_FOUND) +- sta_present = false; +- else if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_ENABLED)) +- return -ENODEV; ++ return FIND_CHILD_MIN_SCORE; + +- if (check_children && list_empty(&adev->children)) ++ if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_ENABLED)) + return -ENODEV; + + /* +@@ -99,8 +99,10 @@ static int find_child_checks(struct acpi + * matched going forward. [This means a second spec violation in a row, + * so whatever we do here is best effort anyway.] + */ +- return sta_present && !adev->pnp.type.platform_id ? +- FIND_CHILD_MAX_SCORE : FIND_CHILD_MIN_SCORE; ++ if (adev->pnp.type.platform_id) ++ return FIND_CHILD_MIN_SCORE; ++ ++ return FIND_CHILD_MAX_SCORE; + } + + struct acpi_device *acpi_find_child_device(struct acpi_device *parent, diff --git a/patches.suse/ACPI-processor-idle-Expose-max_cstate-nocst-bm_check.patch b/patches.suse/ACPI-processor-idle-Expose-max_cstate-nocst-bm_check.patch new file mode 100644 index 0000000..d3ae119 --- /dev/null +++ b/patches.suse/ACPI-processor-idle-Expose-max_cstate-nocst-bm_check.patch @@ -0,0 +1,41 @@ +From: Yajun Deng +Date: Thu, 28 Apr 2022 17:54:13 +0800 +Subject: ACPI: processor: idle: Expose max_cstate/nocst/bm_check_disable + read-only in sysfs +Patch-mainline: v5.19-rc1 +Git-commit: 27263b3428f5b2b73be97adf3d679125b6065271 +References: jsc#PED-1408 + +This will allow super users to verify the module parameters in question +when changed via kernel command line. + +The parameters "nocst/bm_check_disable" are only used for enable/disable, +so change them from integer to bool. + +Signed-off-by: Yajun Deng +[ rjw: Changelog edits ] +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/processor_idle.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/drivers/acpi/processor_idle.c ++++ b/drivers/acpi/processor_idle.c +@@ -38,11 +38,11 @@ + #define ACPI_IDLE_STATE_START (IS_ENABLED(CONFIG_ARCH_HAS_CPU_RELAX) ? 1 : 0) + + static unsigned int max_cstate __read_mostly = ACPI_PROCESSOR_MAX_POWER; +-module_param(max_cstate, uint, 0000); +-static unsigned int nocst __read_mostly; +-module_param(nocst, uint, 0000); +-static int bm_check_disable __read_mostly; +-module_param(bm_check_disable, uint, 0000); ++module_param(max_cstate, uint, 0400); ++static bool nocst __read_mostly; ++module_param(nocst, bool, 0400); ++static bool bm_check_disable __read_mostly; ++module_param(bm_check_disable, bool, 0400); + + static unsigned int latency_factor __read_mostly = 2; + module_param(latency_factor, uint, 0644); diff --git a/patches.suse/ACPI-processor-idle-Practically-limit-Dummy-wait-wor.patch b/patches.suse/ACPI-processor-idle-Practically-limit-Dummy-wait-wor.patch new file mode 100644 index 0000000..bcf3c45 --- /dev/null +++ b/patches.suse/ACPI-processor-idle-Practically-limit-Dummy-wait-wor.patch @@ -0,0 +1,82 @@ +From e400ad8b7e6a1b9102123c6240289a811501f7d9 Mon Sep 17 00:00:00 2001 +From: Dave Hansen +Date: Thu, 22 Sep 2022 11:47:45 -0700 +Subject: [PATCH] ACPI: processor idle: Practically limit "Dummy wait" + workaround to old Intel systems +Git-commit: e400ad8b7e6a1b9102123c6240289a811501f7d9 +Patch-mainline: v6.0-rc8 +References: bsc#1203767,bsc#1203802 + + +Old, circa 2002 chipsets have a bug: they don't go idle when they are +supposed to. So, a workaround was added to slow the CPU down and +ensure that the CPU waits a bit for the chipset to actually go idle. +This workaround is ancient and has been in place in some form since +the original kernel ACPI implementation. + +But, this workaround is very painful on modern systems. The "inl()" +can take thousands of cycles (see Link: for some more detailed +numbers and some fun kernel archaeology). + +First and foremost, modern systems should not be using this code. +Typical Intel systems have not used it in over a decade because it is +horribly inferior to MWAIT-based idle. + +Despite this, people do seem to be tripping over this workaround on +AMD system today. + +Limit the "dummy wait" workaround to Intel systems. Keep Modern AMD +systems from tripping over the workaround. Remotely modern Intel +systems use intel_idle instead of this code and will, in practice, +remain unaffected by the dummy wait. + +Reported-by: K Prateek Nayak +Suggested-by: Rafael J. Wysocki +Signed-off-by: Dave Hansen +Reviewed-by: Mario Limonciello +Tested-by: K Prateek Nayak +Acked-by: Dirk Mueller +Link: https://lore.kernel.org/all/20220921063638.2489-1-kprateek.nayak@amd.com/ +Link: https://lkml.kernel.org/r/20220922184745.3252932-1-dave.hansen@intel.com +--- + drivers/acpi/processor_idle.c | 23 ++++++++++++++++++++--- + 1 file changed, 20 insertions(+), 3 deletions(-) + +diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c +index 16a1663d02d4..9f40917c49ef 100644 +--- a/drivers/acpi/processor_idle.c ++++ b/drivers/acpi/processor_idle.c +@@ -531,10 +531,27 @@ static void wait_for_freeze(void) + /* No delay is needed if we are in guest */ + if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) + return; ++ /* ++ * Modern (>=Nehalem) Intel systems use ACPI via intel_idle, ++ * not this code. Assume that any Intel systems using this ++ * are ancient and may need the dummy wait. This also assumes ++ * that the motivating chipset issue was Intel-only. ++ */ ++ if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) ++ return; + #endif +- /* Dummy wait op - must do something useless after P_LVL2 read +- because chipsets cannot guarantee that STPCLK# signal +- gets asserted in time to freeze execution properly. */ ++ /* ++ * Dummy wait op - must do something useless after P_LVL2 read ++ * because chipsets cannot guarantee that STPCLK# signal gets ++ * asserted in time to freeze execution properly ++ * ++ * This workaround has been in place since the original ACPI ++ * implementation was merged, circa 2002. ++ * ++ * If a profile is pointing to this instruction, please first ++ * consider moving your system to a more modern idle ++ * mechanism. ++ */ + inl(acpi_gbl_FADT.xpm_timer_block.address); + } + +-- +2.37.3 + diff --git a/patches.suse/ACPI-property-Move-acpi_fwnode_device_get_match_data.patch b/patches.suse/ACPI-property-Move-acpi_fwnode_device_get_match_data.patch new file mode 100644 index 0000000..4e9e0cf --- /dev/null +++ b/patches.suse/ACPI-property-Move-acpi_fwnode_device_get_match_data.patch @@ -0,0 +1,50 @@ +From: Sakari Ailus +Date: Thu, 31 Mar 2022 15:54:48 +0300 +Subject: ACPI: property: Move acpi_fwnode_device_get_match_data() up +Patch-mainline: v5.19-rc1 +Git-commit: 55dcbc05827ebcefe888a2829e0a59343ce6ae0a +References: jsc#PED-1408 + +Move acpi_fwnode_device_get_match_data() up below +acpi_fwnode_device_is_available() so the order matches that in struct +fwnode_operations. + +Signed-off-by: Sakari Ailus +Reviewed-by: Andy Shevchenko +Reviewed-by: Heikki Krogerus +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/property.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +--- a/drivers/acpi/property.c ++++ b/drivers/acpi/property.c +@@ -1256,6 +1256,13 @@ static bool acpi_fwnode_device_is_availa + return acpi_device_is_present(to_acpi_device_node(fwnode)); + } + ++static const void * ++acpi_fwnode_device_get_match_data(const struct fwnode_handle *fwnode, ++ const struct device *dev) ++{ ++ return acpi_device_get_match_data(dev); ++} ++ + static bool acpi_fwnode_device_dma_supported(const struct fwnode_handle *fwnode) + { + return acpi_dma_supported(to_acpi_device_node(fwnode)); +@@ -1387,13 +1394,6 @@ static int acpi_fwnode_graph_parse_endpo + return 0; + } + +-static const void * +-acpi_fwnode_device_get_match_data(const struct fwnode_handle *fwnode, +- const struct device *dev) +-{ +- return acpi_device_get_match_data(dev); +-} +- + #define DECLARE_ACPI_FWNODE_OPS(ops) \ + const struct fwnode_operations ops = { \ + .device_is_available = acpi_fwnode_device_is_available, \ diff --git a/patches.suse/ACPI-scan-Add-CLSA0101-Laptop-Support.patch b/patches.suse/ACPI-scan-Add-CLSA0101-Laptop-Support.patch new file mode 100644 index 0000000..1fc64ba --- /dev/null +++ b/patches.suse/ACPI-scan-Add-CLSA0101-Laptop-Support.patch @@ -0,0 +1,35 @@ +From: Lucas Tanure +Date: Wed, 27 Jul 2022 10:59:23 +0100 +Subject: ACPI: scan: Add CLSA0101 Laptop Support + +Git-commit: 87eb04bb87fbdf1d53f0fc64e6fc56ba2b504762 +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +Add CLSA0101 id to the ignore_serial_bus_ids +so serial-multi-instantiate can correctly +instantiate the driver. + +Signed-off-by: Lucas Tanure +Link: https://lore.kernel.org/r/20220727095924.80884-4-tanureal@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + drivers/acpi/scan.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c +index 762b61f67e6c..834d6a2da780 100644 +--- a/drivers/acpi/scan.c ++++ b/drivers/acpi/scan.c +@@ -1737,6 +1737,7 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device) + {"INT3515", }, + /* Non-conforming _HID for Cirrus Logic already released */ + {"CLSA0100", }, ++ {"CLSA0101", }, + /* + * Some ACPI devs contain SerialBus resources even though they are not + * attached to a serial bus at all. +-- +2.35.3 + diff --git a/patches.suse/ACPI-scan-Create-platform-device-for-CS35L41.patch b/patches.suse/ACPI-scan-Create-platform-device-for-CS35L41.patch new file mode 100644 index 0000000..5f8b25a --- /dev/null +++ b/patches.suse/ACPI-scan-Create-platform-device-for-CS35L41.patch @@ -0,0 +1,81 @@ +From d9c01c530cc5e3b6d5bdfeae12c3d0f33fae7498 Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Fri, 21 Jan 2022 17:24:31 +0000 +Subject: [PATCH] ACPI / scan: Create platform device for CS35L41 +Git-commit: d9c01c530cc5e3b6d5bdfeae12c3d0f33fae7498 +Patch-mainline: v5.18-rc1 +References: bsc#1203699 + +The ACPI device with CSC3551 or CLSA0100 are sound cards +with multiple instances of CS35L41 connected by I2C or SPI +to the main CPU. + +We add an ID to the ignore_serial_bus_ids list to enumerate +all I2C or SPI devices correctly. + +The same IDs are also added into serial-multi-instantiate +so that the driver can correctly enumerate the ACPI. + +Signed-off-by: Lucas Tanure +Signed-off-by: Stefan Binding +Link: https://lore.kernel.org/r/20220121172431.6876-10-sbinding@opensource.cirrus.com +Reviewed-by: Hans de Goede +Signed-off-by: Hans de Goede +Acked-by: Takashi Iwai + +--- + drivers/acpi/scan.c | 3 +++ + drivers/platform/x86/serial-multi-instantiate.c | 14 ++++++++++++++ + 2 files changed, 17 insertions(+) + +diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c +index 48db5e80c2dc..4463c2eda61e 100644 +--- a/drivers/acpi/scan.c ++++ b/drivers/acpi/scan.c +@@ -1744,8 +1744,11 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device) + */ + {"BSG1160", }, + {"BSG2150", }, ++ {"CSC3551", }, + {"INT33FE", }, + {"INT3515", }, ++ /* Non-conforming _HID for Cirrus Logic already released */ ++ {"CLSA0100", }, + /* + * HIDs of device with an UartSerialBusV2 resource for which userspace + * expects a regular tty cdev to be created (instead of the in kernel +diff --git a/drivers/platform/x86/serial-multi-instantiate.c b/drivers/platform/x86/serial-multi-instantiate.c +index e2fd73905312..1e8063b7c169 100644 +--- a/drivers/platform/x86/serial-multi-instantiate.c ++++ b/drivers/platform/x86/serial-multi-instantiate.c +@@ -307,6 +307,17 @@ static const struct smi_node int3515_data = { + .bus_type = SMI_I2C, + }; + ++static const struct smi_node cs35l41_hda = { ++ .instances = { ++ { "cs35l41-hda", IRQ_RESOURCE_GPIO, 0 }, ++ { "cs35l41-hda", IRQ_RESOURCE_GPIO, 0 }, ++ { "cs35l41-hda", IRQ_RESOURCE_GPIO, 0 }, ++ { "cs35l41-hda", IRQ_RESOURCE_GPIO, 0 }, ++ {} ++ }, ++ .bus_type = SMI_AUTO_DETECT, ++}; ++ + /* + * Note new device-ids must also be added to ignore_serial_bus_ids in + * drivers/acpi/scan.c: acpi_device_enumeration_by_parent(). +@@ -315,6 +326,9 @@ static const struct acpi_device_id smi_acpi_ids[] = { + { "BSG1160", (unsigned long)&bsg1160_data }, + { "BSG2150", (unsigned long)&bsg2150_data }, + { "INT3515", (unsigned long)&int3515_data }, ++ { "CSC3551", (unsigned long)&cs35l41_hda }, ++ /* Non-conforming _HID for Cirrus Logic already released */ ++ { "CLSA0100", (unsigned long)&cs35l41_hda }, + { } + }; + MODULE_DEVICE_TABLE(acpi, smi_acpi_ids); +-- +2.35.3 + diff --git a/patches.suse/ACPI-utils-Add-api-to-read-_SUB-from-ACPI.patch b/patches.suse/ACPI-utils-Add-api-to-read-_SUB-from-ACPI.patch new file mode 100644 index 0000000..6ddc79d --- /dev/null +++ b/patches.suse/ACPI-utils-Add-api-to-read-_SUB-from-ACPI.patch @@ -0,0 +1,97 @@ +From 93064e15c8a3a8394319a11b8037666e4b7d653d Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Thu, 7 Jul 2022 16:10:36 +0100 +Subject: [PATCH] ACPI: utils: Add api to read _SUB from ACPI +Git-commit: 93064e15c8a3a8394319a11b8037666e4b7d653d +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +Add a wrapper function to read the _SUB string from ACPI. + +Signed-off-by: Stefan Binding +Acked-by: Rafael J. Wysocki +Link: https://lore.kernel.org/r/20220707151037.3901050-2-sbinding@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + drivers/acpi/utils.c | 38 ++++++++++++++++++++++++++++++++++++++ + include/linux/acpi.h | 6 ++++++ + 2 files changed, 44 insertions(+) + +diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c +index 3a9773a09e19..5a7b8065e77f 100644 +--- a/drivers/acpi/utils.c ++++ b/drivers/acpi/utils.c +@@ -291,6 +291,44 @@ int acpi_get_local_address(acpi_handle handle, u32 *addr) + } + EXPORT_SYMBOL(acpi_get_local_address); + ++#define ACPI_MAX_SUB_BUF_SIZE 9 ++ ++const char *acpi_get_subsystem_id(acpi_handle handle) ++{ ++ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; ++ union acpi_object *obj; ++ acpi_status status; ++ const char *sub; ++ size_t len; ++ ++ status = acpi_evaluate_object(handle, METHOD_NAME__SUB, NULL, &buffer); ++ if (ACPI_FAILURE(status)) { ++ acpi_handle_debug(handle, "Reading ACPI _SUB failed: %#x\n", status); ++ return ERR_PTR(-ENODATA); ++ } ++ ++ obj = buffer.pointer; ++ if (obj->type == ACPI_TYPE_STRING) { ++ len = strlen(obj->string.pointer); ++ if (len < ACPI_MAX_SUB_BUF_SIZE && len > 0) { ++ sub = kstrdup(obj->string.pointer, GFP_KERNEL); ++ if (!sub) ++ sub = ERR_PTR(-ENOMEM); ++ } else { ++ acpi_handle_err(handle, "ACPI _SUB Length %zu is Invalid\n", len); ++ sub = ERR_PTR(-ENODATA); ++ } ++ } else { ++ acpi_handle_warn(handle, "Warning ACPI _SUB did not return a string\n"); ++ sub = ERR_PTR(-ENODATA); ++ } ++ ++ acpi_os_free(buffer.pointer); ++ ++ return sub; ++} ++EXPORT_SYMBOL_GPL(acpi_get_subsystem_id); ++ + acpi_status + acpi_evaluate_reference(acpi_handle handle, + acpi_string pathname, +diff --git a/include/linux/acpi.h b/include/linux/acpi.h +index 4f82a5bc6d98..968a187f14f0 100644 +--- a/include/linux/acpi.h ++++ b/include/linux/acpi.h +@@ -762,6 +762,7 @@ static inline u64 acpi_arch_get_root_pointer(void) + #endif + + int acpi_get_local_address(acpi_handle handle, u32 *addr); ++const char *acpi_get_subsystem_id(acpi_handle handle); + + #else /* !CONFIG_ACPI */ + +@@ -1023,6 +1024,11 @@ static inline int acpi_get_local_address(acpi_handle handle, u32 *addr) + return -ENODEV; + } + ++static inline const char *acpi_get_subsystem_id(acpi_handle handle) ++{ ++ return ERR_PTR(-ENODEV); ++} ++ + static inline int acpi_register_wakeup_handler(int wake_irq, + bool (*wakeup)(void *context), void *context) + { +-- +2.35.3 + diff --git a/patches.suse/ACPI-utils-include-UUID-in-_DSM-evaluation-warning.patch b/patches.suse/ACPI-utils-include-UUID-in-_DSM-evaluation-warning.patch new file mode 100644 index 0000000..4f42c72 --- /dev/null +++ b/patches.suse/ACPI-utils-include-UUID-in-_DSM-evaluation-warning.patch @@ -0,0 +1,35 @@ +From: =?UTF-8?q?Michael=20Niew=C3=B6hner?= +Date: Tue, 17 May 2022 20:40:06 +0200 +Subject: ACPI: utils: include UUID in _DSM evaluation warning +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Patch-mainline: v5.19-rc1 +Git-commit: 06eb8dc097b3fcb2d02eb553b17af5fcc2952f96 +References: jsc#PED-1408 + +The _DSM evaluation warning in its current form is not very helpful, as +it lacks any specific information: + ACPI: \: failed to evaluate _DSM (0x1001) + +Thus, include the UUID of the missing _DSM: + ACPI: \: failed to evaluate _DSM bf0212f2-... (0x1001) + +Signed-off-by: Michael Niewöhner +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/utils.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/acpi/utils.c ++++ b/drivers/acpi/utils.c +@@ -681,7 +681,7 @@ acpi_evaluate_dsm(acpi_handle handle, co + + if (ret != AE_NOT_FOUND) + acpi_handle_warn(handle, +- "failed to evaluate _DSM (0x%x)\n", ret); ++ "failed to evaluate _DSM %pUb (0x%x)\n", guid, ret); + + return NULL; + } diff --git a/patches.suse/ACPI-video-improve-PM-notifer-callback.patch b/patches.suse/ACPI-video-improve-PM-notifer-callback.patch new file mode 100644 index 0000000..82ad1e8 --- /dev/null +++ b/patches.suse/ACPI-video-improve-PM-notifer-callback.patch @@ -0,0 +1,62 @@ +From: Zhang Rui +Date: Thu, 19 May 2022 22:37:32 +0800 +Subject: ACPI: video: improve PM notifer callback +Patch-mainline: v5.19-rc1 +Git-commit: 1934fee67593c561ef883761bf2ddee82f908ed9 +References: jsc#PED-1408 + +PM notifier callbacks should check for supported events rather than filter +out the unsupported events. So that it won't break when a new event is +introduced. + +No functional change in this patch. + +Signed-off-by: Zhang Rui +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/acpi_video.c | 31 +++++++++++++++---------------- + 1 file changed, 15 insertions(+), 16 deletions(-) + +--- a/drivers/acpi/acpi_video.c ++++ b/drivers/acpi/acpi_video.c +@@ -1707,24 +1707,23 @@ static int acpi_video_resume(struct noti + int i; + + switch (val) { +- case PM_HIBERNATION_PREPARE: +- case PM_SUSPEND_PREPARE: +- case PM_RESTORE_PREPARE: +- return NOTIFY_DONE; +- } +- +- video = container_of(nb, struct acpi_video_bus, pm_nb); ++ case PM_POST_HIBERNATION: ++ case PM_POST_SUSPEND: ++ case PM_POST_RESTORE: ++ video = container_of(nb, struct acpi_video_bus, pm_nb); ++ ++ dev_info(&video->device->dev, "Restoring backlight state\n"); ++ ++ for (i = 0; i < video->attached_count; i++) { ++ video_device = video->attached_array[i].bind_info; ++ if (video_device && video_device->brightness) ++ acpi_video_device_lcd_set_level(video_device, ++ video_device->brightness->curr); ++ } + +- dev_info(&video->device->dev, "Restoring backlight state\n"); +- +- for (i = 0; i < video->attached_count; i++) { +- video_device = video->attached_array[i].bind_info; +- if (video_device && video_device->brightness) +- acpi_video_device_lcd_set_level(video_device, +- video_device->brightness->curr); ++ return NOTIFY_OK; + } +- +- return NOTIFY_OK; ++ return NOTIFY_DONE; + } + + static acpi_status diff --git a/patches.suse/ACPICA-Add-new-ACPI-6.4-semantics-for-LoadTable-oper.patch b/patches.suse/ACPICA-Add-new-ACPI-6.4-semantics-for-LoadTable-oper.patch new file mode 100644 index 0000000..0c42412 --- /dev/null +++ b/patches.suse/ACPICA-Add-new-ACPI-6.4-semantics-for-LoadTable-oper.patch @@ -0,0 +1,71 @@ +From: Bob Moore +Date: Mon, 11 Apr 2022 20:52:26 +0200 +Subject: ACPICA: Add new ACPI 6.4 semantics for LoadTable() operator +Patch-mainline: v5.19-rc1 +Git-commit: e468e39f7cabce2095a2f19dadbfdbf3c21f18f1 +References: jsc#PED-1408 + +ACPICA commit b32dde35e26a63a85d78d4dc0a7260b61e626ac1 + +DDB_HANDLE is gone, now LoadTable() returns a pass/fail integer. + +Link: https://github.com/acpica/acpica/commit/b32dde35 +Signed-off-by: Bob Moore +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/acpica/exconfig.c | 24 +++++++++++++++++------- + 1 file changed, 17 insertions(+), 7 deletions(-) + +--- a/drivers/acpi/acpica/exconfig.c ++++ b/drivers/acpi/acpica/exconfig.c +@@ -87,11 +87,21 @@ acpi_ex_load_table_op(struct acpi_walk_s + struct acpi_namespace_node *parent_node; + struct acpi_namespace_node *start_node; + struct acpi_namespace_node *parameter_node = NULL; ++ union acpi_operand_object *return_obj; + union acpi_operand_object *ddb_handle; + u32 table_index; + + ACPI_FUNCTION_TRACE(ex_load_table_op); + ++ /* Create the return object */ ++ ++ return_obj = acpi_ut_create_integer_object((u64)0); ++ if (!return_obj) { ++ return_ACPI_STATUS(AE_NO_MEMORY); ++ } ++ ++ *return_desc = return_obj; ++ + /* Find the ACPI table in the RSDT/XSDT */ + + acpi_ex_exit_interpreter(); +@@ -106,12 +116,6 @@ acpi_ex_load_table_op(struct acpi_walk_s + + /* Table not found, return an Integer=0 and AE_OK */ + +- ddb_handle = acpi_ut_create_integer_object((u64) 0); +- if (!ddb_handle) { +- return_ACPI_STATUS(AE_NO_MEMORY); +- } +- +- *return_desc = ddb_handle; + return_ACPI_STATUS(AE_OK); + } + +@@ -198,7 +202,13 @@ acpi_ex_load_table_op(struct acpi_walk_s + } + } + +- *return_desc = ddb_handle; ++ /* Remove the reference to ddb_handle created by acpi_ex_add_table above */ ++ ++ acpi_ut_remove_reference(ddb_handle); ++ ++ /* Return -1 (non-zero) indicates success */ ++ ++ return_obj->integer.value = 0xFFFFFFFFFFFFFFFF; + return_ACPI_STATUS(status); + } + diff --git a/patches.suse/ACPICA-Add-new-ACPI-6.4-semantics-to-the-Load-operat.patch b/patches.suse/ACPICA-Add-new-ACPI-6.4-semantics-to-the-Load-operat.patch new file mode 100644 index 0000000..2d47869 --- /dev/null +++ b/patches.suse/ACPICA-Add-new-ACPI-6.4-semantics-to-the-Load-operat.patch @@ -0,0 +1,184 @@ +From: Bob Moore +Date: Mon, 11 Apr 2022 20:51:27 +0200 +Subject: ACPICA: Add new ACPI 6.4 semantics to the Load() operator +Patch-mainline: v5.19-rc1 +Git-commit: 39ea1bbf270a617c81369f2867ca14b8eac331bd +References: jsc#PED-1408 + +ACPICA commit 84bf573ab7222c4e1c22167b22d29c4da1552b20 + +DDB_HANDLE is gone, now Load() returns a pass/fail integer, as well as +storing it in an optional 2nd argument. + +Link: https://github.com/acpica/acpica/commit/84bf573a +Signed-off-by: Bob Moore +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/acpica/dswexec.c | 2 +- + drivers/acpi/acpica/exconfig.c | 35 +++++++++++++++++++---------------- + drivers/acpi/acpica/exoparg1.c | 21 +++++++++++++++++++++ + drivers/acpi/acpica/psopcode.c | 4 ++-- + 4 files changed, 43 insertions(+), 19 deletions(-) + +--- a/drivers/acpi/acpica/dswexec.c ++++ b/drivers/acpi/acpica/dswexec.c +@@ -30,7 +30,7 @@ static acpi_execute_op acpi_gbl_op_type_ + acpi_ex_opcode_0A_0T_1R, + acpi_ex_opcode_1A_0T_0R, + acpi_ex_opcode_1A_0T_1R, +- acpi_ex_opcode_1A_1T_0R, ++ NULL, /* Was: acpi_ex_opcode_1A_0T_0R (Was for Load operator) */ + acpi_ex_opcode_1A_1T_1R, + acpi_ex_opcode_2A_0T_0R, + acpi_ex_opcode_2A_0T_1R, +--- a/drivers/acpi/acpica/exconfig.c ++++ b/drivers/acpi/acpica/exconfig.c +@@ -249,7 +249,7 @@ acpi_ex_region_read(union acpi_operand_o + * + * PARAMETERS: obj_desc - Region or Buffer/Field where the table will be + * obtained +- * target - Where a handle to the table will be stored ++ * target - Where the status of the load will be stored + * walk_state - Current state + * + * RETURN: Status +@@ -278,6 +278,20 @@ acpi_ex_load_op(union acpi_operand_objec + + ACPI_FUNCTION_TRACE(ex_load_op); + ++ if (target->common.descriptor_type == ACPI_DESC_TYPE_NAMED) { ++ target = ++ acpi_ns_get_attached_object(ACPI_CAST_PTR ++ (struct acpi_namespace_node, ++ target)); ++ } ++ if (target->common.type != ACPI_TYPE_INTEGER) { ++ ACPI_EXCEPTION((AE_INFO, AE_TYPE, ++ "Type not integer: %X\n", target->common.type)); ++ return_ACPI_STATUS(AE_AML_OPERAND_TYPE); ++ } ++ ++ target->integer.value = 0; ++ + /* Source Object can be either an op_region or a Buffer/Field */ + + switch (obj_desc->common.type) { +@@ -430,9 +444,6 @@ acpi_ex_load_op(union acpi_operand_objec + */ + status = acpi_ex_add_table(table_index, &ddb_handle); + if (ACPI_FAILURE(status)) { +- +- /* On error, table_ptr was deallocated above */ +- + return_ACPI_STATUS(status); + } + +@@ -442,21 +453,13 @@ acpi_ex_load_op(union acpi_operand_objec + acpi_ns_initialize_objects(); + acpi_ex_enter_interpreter(); + +- /* Store the ddb_handle into the Target operand */ ++ /* Remove the reference to ddb_handle created by acpi_ex_add_table above */ + +- status = acpi_ex_store(ddb_handle, target, walk_state); +- if (ACPI_FAILURE(status)) { +- (void)acpi_ex_unload_table(ddb_handle); +- +- /* table_ptr was deallocated above */ +- +- acpi_ut_remove_reference(ddb_handle); +- return_ACPI_STATUS(status); +- } ++ acpi_ut_remove_reference(ddb_handle); + +- /* Remove the reference by added by acpi_ex_store above */ ++ /* Return -1 (non-zero) indicates success */ + +- acpi_ut_remove_reference(ddb_handle); ++ target->integer.value = 0xFFFFFFFFFFFFFFFF; + return_ACPI_STATUS(status); + } + +--- a/drivers/acpi/acpica/exoparg1.c ++++ b/drivers/acpi/acpica/exoparg1.c +@@ -163,6 +163,7 @@ acpi_status acpi_ex_opcode_1A_0T_0R(stru + return_ACPI_STATUS(status); + } + ++#ifdef _OBSOLETE_CODE /* Was originally used for Load() operator */ + /******************************************************************************* + * + * FUNCTION: acpi_ex_opcode_1A_1T_0R +@@ -187,10 +188,12 @@ acpi_status acpi_ex_opcode_1A_1T_0R(stru + /* Examine the AML opcode */ + + switch (walk_state->opcode) { ++#ifdef _OBSOLETE_CODE + case AML_LOAD_OP: + + status = acpi_ex_load_op(operand[0], operand[1], walk_state); + break; ++#endif + + default: /* Unknown opcode */ + +@@ -204,6 +207,7 @@ cleanup: + + return_ACPI_STATUS(status); + } ++#endif + + /******************************************************************************* + * +@@ -215,6 +219,8 @@ cleanup: + * + * DESCRIPTION: Execute opcode with one argument, one target, and a + * return value. ++ * January 2022: Added Load operator, with new ACPI 6.4 ++ * semantics. + * + ******************************************************************************/ + +@@ -239,6 +245,7 @@ acpi_status acpi_ex_opcode_1A_1T_1R(stru + case AML_FIND_SET_LEFT_BIT_OP: + case AML_FIND_SET_RIGHT_BIT_OP: + case AML_FROM_BCD_OP: ++ case AML_LOAD_OP: + case AML_TO_BCD_OP: + case AML_CONDITIONAL_REF_OF_OP: + +@@ -338,6 +345,20 @@ acpi_status acpi_ex_opcode_1A_1T_1R(stru + } + break; + ++ case AML_LOAD_OP: /* Result1 = Load (Operand[0], Result1) */ ++ ++ return_desc->integer.value = 0; ++ status = ++ acpi_ex_load_op(operand[0], return_desc, ++ walk_state); ++ if (ACPI_SUCCESS(status)) { ++ ++ /* Return -1 (non-zero) indicates success */ ++ ++ return_desc->integer.value = 0xFFFFFFFFFFFFFFFF; ++ } ++ break; ++ + case AML_TO_BCD_OP: /* to_bcd (Operand, Result) */ + + return_desc->integer.value = 0; +--- a/drivers/acpi/acpica/psopcode.c ++++ b/drivers/acpi/acpica/psopcode.c +@@ -408,8 +408,8 @@ const struct acpi_opcode_info acpi_gbl_a + AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | + AML_DEFER | AML_FIELD | AML_CREATE), + /* 4A */ ACPI_OP("Load", ARGP_LOAD_OP, ARGI_LOAD_OP, ACPI_TYPE_ANY, +- AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_0R, +- AML_FLAGS_EXEC_1A_1T_0R), ++ AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R, ++ AML_FLAGS_EXEC_1A_1T_1R), + /* 4B */ ACPI_OP("Stall", ARGP_STALL_OP, ARGI_STALL_OP, ACPI_TYPE_ANY, + AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_0R, + AML_FLAGS_EXEC_1A_0T_0R), diff --git a/patches.suse/ACPICA-Add-support-for-ARM-Performance-Monitoring-Un.patch b/patches.suse/ACPICA-Add-support-for-ARM-Performance-Monitoring-Un.patch new file mode 100644 index 0000000..4aeebbd --- /dev/null +++ b/patches.suse/ACPICA-Add-support-for-ARM-Performance-Monitoring-Un.patch @@ -0,0 +1,121 @@ +From: Besar Wicaksono +Date: Mon, 11 Apr 2022 20:58:04 +0200 +Subject: ACPICA: Add support for ARM Performance Monitoring Unit Table. +Patch-mainline: v5.19-rc1 +Git-commit: 1c5d62f5dd979dbe7f4b16a5bd3c64fbecb7d92a +References: jsc#PED-1408 + +ACPICA commit 002165ecc0a3dc703bb24c789aaa02fdada01675 + +The specification of this table is described in +"ARM Performance Monitoring Unit Architecture 1.0 Platform Design Document" +ARM DEN0117. + +This patch adds the necessary types and support for +compiling/disassembling APMT. + +Link: https://github.com/acpica/acpica/commit/002165ec +Signed-off-by: Besar Wicaksono +Signed-off-by: Bob Moore +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + include/acpi/actbl2.h | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 80 insertions(+) + +--- a/include/acpi/actbl2.h ++++ b/include/acpi/actbl2.h +@@ -25,6 +25,7 @@ + * the wrong signature. + */ + #define ACPI_SIG_AGDI "AGDI" /* Arm Generic Diagnostic Dump and Reset Device Interface */ ++#define ACPI_SIG_APMT "APMT" /* Arm Performance Monitoring Unit table */ + #define ACPI_SIG_BDAT "BDAT" /* BIOS Data ACPI Table */ + #define ACPI_SIG_IORT "IORT" /* IO Remapping Table */ + #define ACPI_SIG_IVRS "IVRS" /* I/O Virtualization Reporting Structure */ +@@ -260,6 +261,85 @@ struct acpi_table_agdi { + + /******************************************************************************* + * ++ * APMT - ARM Performance Monitoring Unit Table ++ * ++ * Conforms to: ++ * ARM Performance Monitoring Unit Architecture 1.0 Platform Design Document ++ * ARM DEN0117 v1.0 November 25, 2021 ++ * ++ ******************************************************************************/ ++ ++struct acpi_table_apmt { ++ struct acpi_table_header header; /* Common ACPI table header */ ++}; ++ ++#define ACPI_APMT_NODE_ID_LENGTH 4 ++ ++/* ++ * APMT subtables ++ */ ++struct acpi_apmt_node { ++ u16 length; ++ u8 flags; ++ u8 type; ++ u32 id; ++ u64 inst_primary; ++ u32 inst_secondary; ++ u64 base_address0; ++ u64 base_address1; ++ u32 ovflw_irq; ++ u32 reserved; ++ u32 ovflw_irq_flags; ++ u32 proc_affinity; ++ u32 impl_id; ++}; ++ ++/* Masks for Flags field above */ ++ ++#define ACPI_APMT_FLAGS_DUAL_PAGE (1<<0) ++#define ACPI_APMT_FLAGS_AFFINITY (1<<1) ++#define ACPI_APMT_FLAGS_ATOMIC (1<<2) ++ ++/* Values for Flags dual page field above */ ++ ++#define ACPI_APMT_FLAGS_DUAL_PAGE_NSUPP (0<<0) ++#define ACPI_APMT_FLAGS_DUAL_PAGE_SUPP (1<<0) ++ ++/* Values for Flags processor affinity field above */ ++#define ACPI_APMT_FLAGS_AFFINITY_PROC (0<<1) ++#define ACPI_APMT_FLAGS_AFFINITY_PROC_CONTAINER (1<<1) ++ ++/* Values for Flags 64-bit atomic field above */ ++#define ACPI_APMT_FLAGS_ATOMIC_NSUPP (0<<2) ++#define ACPI_APMT_FLAGS_ATOMIC_SUPP (1<<2) ++ ++/* Values for Type field above */ ++ ++enum acpi_apmt_node_type { ++ ACPI_APMT_NODE_TYPE_MC = 0x00, ++ ACPI_APMT_NODE_TYPE_SMMU = 0x01, ++ ACPI_APMT_NODE_TYPE_PCIE_ROOT = 0x02, ++ ACPI_APMT_NODE_TYPE_ACPI = 0x03, ++ ACPI_APMT_NODE_TYPE_CACHE = 0x04, ++ ACPI_APMT_NODE_TYPE_COUNT ++}; ++ ++/* Masks for ovflw_irq_flags field above */ ++ ++#define ACPI_APMT_OVFLW_IRQ_FLAGS_MODE (1<<0) ++#define ACPI_APMT_OVFLW_IRQ_FLAGS_TYPE (1<<1) ++ ++/* Values for ovflw_irq_flags mode field above */ ++ ++#define ACPI_APMT_OVFLW_IRQ_FLAGS_MODE_LEVEL (0<<0) ++#define ACPI_APMT_OVFLW_IRQ_FLAGS_MODE_EDGE (1<<0) ++ ++/* Values for ovflw_irq_flags type field above */ ++ ++#define ACPI_APMT_OVFLW_IRQ_FLAGS_TYPE_WIRED (0<<1) ++ ++/******************************************************************************* ++ * + * BDAT - BIOS Data ACPI Table + * + * Conforms to "BIOS Data ACPI Table", Interface Specification v4.0 Draft 5 diff --git a/patches.suse/ACPICA-Add-support-for-the-Windows-11-_OSI-string.patch b/patches.suse/ACPICA-Add-support-for-the-Windows-11-_OSI-string.patch new file mode 100644 index 0000000..dc00664 --- /dev/null +++ b/patches.suse/ACPICA-Add-support-for-the-Windows-11-_OSI-string.patch @@ -0,0 +1,40 @@ +From: Mario Limonciello +Date: Mon, 11 Apr 2022 20:47:00 +0200 +Subject: ACPICA: Add support for the Windows 11 _OSI string +Patch-mainline: v5.19-rc1 +Git-commit: 62b32fd961cf2d8b2c9fdcd8d58abeb184bb439b +References: jsc#PED-1408 + +ACPICA commit f2e9fb8345b9146a67f8c63474b65ccfc06d962a + +See https://github.com/microsoft_docs/windows-driver-docs/commit/a061e31fd77c20cc8e6eb0234e5d3a83e417f48 + +Link: https://github.com/acpica/acpica/commit/f2e9fb83 +Signed-off-by: Bob Moore +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/acpica/utosi.c | 1 + + include/acpi/actypes.h | 1 + + 2 files changed, 2 insertions(+) + +--- a/drivers/acpi/acpica/utosi.c ++++ b/drivers/acpi/acpica/utosi.c +@@ -74,6 +74,7 @@ static struct acpi_interface_info acpi_d + {"Windows 2018.2", NULL, 0, ACPI_OSI_WIN_10_RS5}, /* Windows 10 version 1809 - Added 11/2018 */ + {"Windows 2019", NULL, 0, ACPI_OSI_WIN_10_19H1}, /* Windows 10 version 1903 - Added 08/2019 */ + {"Windows 2020", NULL, 0, ACPI_OSI_WIN_10_20H1}, /* Windows 10 version 2004 - Added 08/2021 */ ++ {"Windows 2021", NULL, 0, ACPI_OSI_WIN_11}, /* Windows 11 - Added 01/2022 */ + + /* Feature Group Strings */ + +--- a/include/acpi/actypes.h ++++ b/include/acpi/actypes.h +@@ -1303,6 +1303,7 @@ typedef enum { + #define ACPI_OSI_WIN_10_RS5 0x13 + #define ACPI_OSI_WIN_10_19H1 0x14 + #define ACPI_OSI_WIN_10_20H1 0x15 ++#define ACPI_OSI_WIN_11 0x16 + + /* Definitions of getopt */ + diff --git a/patches.suse/ACPICA-Add-the-subtable-CFMWS-to-the-CEDT-table.patch b/patches.suse/ACPICA-Add-the-subtable-CFMWS-to-the-CEDT-table.patch new file mode 100644 index 0000000..02c3259 --- /dev/null +++ b/patches.suse/ACPICA-Add-the-subtable-CFMWS-to-the-CEDT-table.patch @@ -0,0 +1,30 @@ +From: Lawrence Hileman +Date: Mon, 11 Apr 2022 20:47:40 +0200 +Subject: ACPICA: Add the subtable CFMWS to the CEDT table +Patch-mainline: v5.19-rc1 +Git-commit: a95d2fb08538f29f6e9f54a803dffc303b5263cd +References: jsc#PED-1408 + +ACPICA commit 19b11f91660b1a38a8e9655b0b1a4ad51ec4db1e + +Link: https://github.com/acpica/acpica/commit/19b11f91 +Signed-off-by: Bob Moore +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + include/acpi/actbl1.h | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/include/acpi/actbl1.h ++++ b/include/acpi/actbl1.h +@@ -373,6 +373,10 @@ struct acpi_cedt_cfmws { + u32 interleave_targets[]; + }; + ++struct acpi_cedt_cfmws_target_element { ++ u32 interleave_target; ++}; ++ + /* Values for Interleave Arithmetic field above */ + + #define ACPI_CEDT_CFMWS_ARITHMETIC_MODULO (0) diff --git a/patches.suse/ACPICA-Clean-up-double-word-in-comment.patch b/patches.suse/ACPICA-Clean-up-double-word-in-comment.patch new file mode 100644 index 0000000..66e1ee6 --- /dev/null +++ b/patches.suse/ACPICA-Clean-up-double-word-in-comment.patch @@ -0,0 +1,43 @@ +From: Tom Rix +Date: Mon, 11 Apr 2022 20:53:22 +0200 +Subject: ACPICA: Clean up double word in comment +Patch-mainline: v5.19-rc1 +Git-commit: 1cf0cee1da04548be15f24b67889cf6be8306f86 +References: jsc#PED-1408 + +ACPICA commit 01f43b049722fa7613fca3c9fa657b150fae8ac1 + +Remove the second 'know' and 'than'. + +Link: https://github.com/acpica/acpica/commit/01f43b04 +Signed-off-by: Tom Rix +Signed-off-by: Bob Moore +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/acpica/exfldio.c | 2 +- + drivers/acpi/acpica/hwregs.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/acpi/acpica/exfldio.c ++++ b/drivers/acpi/acpica/exfldio.c +@@ -104,7 +104,7 @@ acpi_ex_setup_region(union acpi_operand_ + #ifdef ACPI_UNDER_DEVELOPMENT + /* + * If the Field access is any_acc, we can now compute the optimal +- * access (because we know know the length of the parent region) ++ * access (because we know the length of the parent region) + */ + if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) { + if (ACPI_FAILURE(status)) { +--- a/drivers/acpi/acpica/hwregs.c ++++ b/drivers/acpi/acpica/hwregs.c +@@ -446,7 +446,7 @@ struct acpi_bit_register_info *acpi_hw_g + * RETURN: Status + * + * DESCRIPTION: Write the PM1 A/B control registers. These registers are +- * different than than the PM1 A/B status and enable registers ++ * different than the PM1 A/B status and enable registers + * in that different values can be written to the A/B registers. + * Most notably, the SLP_TYP bits can be different, as per the + * values returned from the _Sx predefined methods. diff --git a/patches.suse/ACPICA-Headers-Replace-zero-length-array-with-flexib.patch b/patches.suse/ACPICA-Headers-Replace-zero-length-array-with-flexib.patch new file mode 100644 index 0000000..80b15f1 --- /dev/null +++ b/patches.suse/ACPICA-Headers-Replace-zero-length-array-with-flexib.patch @@ -0,0 +1,44 @@ +From: "Gustavo A. R. Silva" +Date: Mon, 11 Apr 2022 20:56:15 +0200 +Subject: ACPICA: Headers: Replace zero-length array with flexible-array member +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Patch-mainline: v5.19-rc1 +Git-commit: aa29b2083e11722a0ceedfa2a87de74cc7cfa676 +References: jsc#PED-1408 + +ACPICA commit 98835f452c698b015d4da999944405ecb90da670 + +There is a regular need in the kernel to provide a way to declare +having a dynamically sized set of trailing elements in a structure. +Kernel code should always use “flexible array members”[1] for these +cases. The older style of one-element or zero-length arrays should +no longer be used[2]. + +[1] https://en.wikipedia.org/wiki/Flexible_array_member +[2] https://www.kernel.org/doc/html/v5.16/process/deprecated.html#zero-length-and-one-element-arrays + +Link: https://github.com/acpica/acpica/commit/98835f45 +Link: https://github.com/KSPP/linux/issues/78 +Signed-off-by: Gustavo A. R. Silva +Reviewed-by: Kees Cook +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Bob Moore +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + include/acpi/actbl2.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/include/acpi/actbl2.h ++++ b/include/acpi/actbl2.h +@@ -2310,7 +2310,7 @@ struct acpi_table_rgrt { + u16 version; + u8 image_type; + u8 reserved; +- u8 image[0]; ++ u8 image[]; + }; + + /* image_type values */ diff --git a/patches.suse/ACPICA-IORT-Updates-for-revision-E.d.patch b/patches.suse/ACPICA-IORT-Updates-for-revision-E.d.patch new file mode 100644 index 0000000..611060b --- /dev/null +++ b/patches.suse/ACPICA-IORT-Updates-for-revision-E.d.patch @@ -0,0 +1,84 @@ +From: Shameer Kolothum +Date: Mon, 11 Apr 2022 21:02:33 +0200 +Subject: ACPICA: IORT: Updates for revision E.d +Patch-mainline: v5.19-rc1 +Git-commit: 4fd147530edd44439a099dda6b22f1a390f306ab +References: jsc#PED-1408 + +ACPICA commit 87a2e39b8abdfedfb86b0a105708e37e895becd9 + +IORT revision is now updated to E.d (ARM DEN 0049E.d) and +contains a few additions like, + -Added descriptor in the root complex node for specifying + PASID width supported by the root complex. + -Updated RMR node Flags field. + -Introduced memory access attributes in the RMR node. + +Please note that IORT Rev E.c is deprecated and not supported. + +Link: https://github.com/acpica/acpica/commit/87a2e39b +Signed-off-by: Shameer Kolothum +Signed-off-by: Bob Moore +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + include/acpi/actbl2.h | 27 +++++++++++++++++++++++++-- + 1 file changed, 25 insertions(+), 2 deletions(-) + +--- a/include/acpi/actbl2.h ++++ b/include/acpi/actbl2.h +@@ -357,7 +357,7 @@ struct acpi_table_bdat { + * IORT - IO Remapping Table + * + * Conforms to "IO Remapping Table System Software on ARM Platforms", +- * Document number: ARM DEN 0049E.b, Feb 2021 ++ * Document number: ARM DEN 0049E.d, Feb 2022 + * + ******************************************************************************/ + +@@ -454,7 +454,8 @@ struct acpi_iort_root_complex { + u32 ats_attribute; + u32 pci_segment_number; + u8 memory_address_limit; /* Memory address size limit */ +- u8 reserved[3]; /* Reserved, must be zero */ ++ u16 pasid_capabilities; /* PASID Capabilities */ ++ u8 reserved[1]; /* Reserved, must be zero */ + }; + + /* Masks for ats_attribute field above */ +@@ -463,6 +464,9 @@ struct acpi_iort_root_complex { + #define ACPI_IORT_PRI_SUPPORTED (1<<1) /* The root complex PRI support */ + #define ACPI_IORT_PASID_FWD_SUPPORTED (1<<2) /* The root complex PASID forward support */ + ++/* Masks for pasid_capabilities field above */ ++#define ACPI_IORT_PASID_MAX_WIDTH (0x1F) /* Bits 0-4 */ ++ + struct acpi_iort_smmu { + u64 base_address; /* SMMU base address */ + u64 span; /* Length of memory range */ +@@ -538,6 +542,25 @@ struct acpi_iort_rmr { + u32 rmr_offset; + }; + ++/* Masks for Flags field above */ ++#define ACPI_IORT_RMR_REMAP_PERMITTED (1) ++#define ACPI_IORT_RMR_ACCESS_PRIVILEGE (1<<1) ++ ++/* ++ * Macro to access the Access Attributes in flags field above: ++ * Access Attributes is encoded in bits 9:2 ++ */ ++#define ACPI_IORT_RMR_ACCESS_ATTRIBUTES(flags) (((flags) >> 2) & 0xFF) ++ ++/* Values for above Access Attributes */ ++ ++#define ACPI_IORT_RMR_ATTR_DEVICE_NGNRNE 0x00 ++#define ACPI_IORT_RMR_ATTR_DEVICE_NGNRE 0x01 ++#define ACPI_IORT_RMR_ATTR_DEVICE_NGRE 0x02 ++#define ACPI_IORT_RMR_ATTR_DEVICE_GRE 0x03 ++#define ACPI_IORT_RMR_ATTR_NORMAL_NC 0x04 ++#define ACPI_IORT_RMR_ATTR_NORMAL_IWB_OWB 0x05 ++ + struct acpi_iort_rmr_desc { + u64 base_address; + u64 length; diff --git a/patches.suse/ACPICA-Removed-some-tabs-and-comments.patch b/patches.suse/ACPICA-Removed-some-tabs-and-comments.patch new file mode 100644 index 0000000..58a26c2 --- /dev/null +++ b/patches.suse/ACPICA-Removed-some-tabs-and-comments.patch @@ -0,0 +1,159 @@ +From: Bob Moore +Date: Mon, 11 Apr 2022 20:55:10 +0200 +Subject: ACPICA: Removed some tabs and // comments +Patch-mainline: v5.19-rc1 +Git-commit: 45882a817d4bae5a3b63c3861cb62b9b9a025de5 +References: jsc#PED-1408 + +ACPICA commit 0914618b553d6f3366e568409cebf2656891ca69 + +Automated cleanup; No functional changes. + +Link: https://github.com/acpica/acpica/commit/0914618b +Signed-off-by: Bob Moore +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + include/acpi/actbl1.h | 12 ++++++------ + include/acpi/actbl2.h | 40 ++++++++++++++++++++-------------------- + include/acpi/actypes.h | 16 ++++++++-------- + 3 files changed, 34 insertions(+), 34 deletions(-) + +--- a/include/acpi/actbl1.h ++++ b/include/acpi/actbl1.h +@@ -379,15 +379,15 @@ struct acpi_cedt_cfmws_target_element { + + /* Values for Interleave Arithmetic field above */ + +-#define ACPI_CEDT_CFMWS_ARITHMETIC_MODULO (0) ++#define ACPI_CEDT_CFMWS_ARITHMETIC_MODULO (0) + + /* Values for Restrictions field above */ + +-#define ACPI_CEDT_CFMWS_RESTRICT_TYPE2 (1) +-#define ACPI_CEDT_CFMWS_RESTRICT_TYPE3 (1<<1) +-#define ACPI_CEDT_CFMWS_RESTRICT_VOLATILE (1<<2) +-#define ACPI_CEDT_CFMWS_RESTRICT_PMEM (1<<3) +-#define ACPI_CEDT_CFMWS_RESTRICT_FIXED (1<<4) ++#define ACPI_CEDT_CFMWS_RESTRICT_TYPE2 (1) ++#define ACPI_CEDT_CFMWS_RESTRICT_TYPE3 (1<<1) ++#define ACPI_CEDT_CFMWS_RESTRICT_VOLATILE (1<<2) ++#define ACPI_CEDT_CFMWS_RESTRICT_PMEM (1<<3) ++#define ACPI_CEDT_CFMWS_RESTRICT_FIXED (1<<4) + + /******************************************************************************* + * +--- a/include/acpi/actbl2.h ++++ b/include/acpi/actbl2.h +@@ -978,8 +978,8 @@ struct acpi_madt_multiproc_wakeup { + u64 base_address; + }; + +-#define ACPI_MULTIPROC_WAKEUP_MB_OS_SIZE 2032 +-#define ACPI_MULTIPROC_WAKEUP_MB_FIRMWARE_SIZE 2048 ++#define ACPI_MULTIPROC_WAKEUP_MB_OS_SIZE 2032 ++#define ACPI_MULTIPROC_WAKEUP_MB_FIRMWARE_SIZE 2048 + + struct acpi_madt_multiproc_wakeup_mailbox { + u16 command; +@@ -1597,7 +1597,7 @@ struct acpi_nhlt_mic_device_specific_con + + /* Values for array_type_ext above */ + +-#define ACPI_NHLT_ARRAY_TYPE_RESERVED 0x09 // 9 and below are reserved ++#define ACPI_NHLT_ARRAY_TYPE_RESERVED 0x09 /* 9 and below are reserved */ + #define ACPI_NHLT_SMALL_LINEAR_2ELEMENT 0x0A + #define ACPI_NHLT_BIG_LINEAR_2ELEMENT 0x0B + #define ACPI_NHLT_FIRST_GEOMETRY_LINEAR_4ELEMENT 0x0C +@@ -1617,17 +1617,17 @@ struct acpi_nhlt_vendor_mic_count { + struct acpi_nhlt_vendor_mic_config { + u8 type; + u8 panel; +- u16 speaker_position_distance; // mm +- u16 horizontal_offset; // mm +- u16 vertical_offset; // mm +- u8 frequency_low_band; // 5*hz +- u8 frequency_high_band; // 500*hz +- u16 direction_angle; // -180 - + 180 +- u16 elevation_angle; // -180 - + 180 +- u16 work_vertical_angle_begin; // -180 - + 180 with 2 deg step +- u16 work_vertical_angle_end; // -180 - + 180 with 2 deg step +- u16 work_horizontal_angle_begin; // -180 - + 180 with 2 deg step +- u16 work_horizontal_angle_end; // -180 - + 180 with 2 deg step ++ u16 speaker_position_distance; /* mm */ ++ u16 horizontal_offset; /* mm */ ++ u16 vertical_offset; /* mm */ ++ u8 frequency_low_band; /* 5*Hz */ ++ u8 frequency_high_band; /* 500*Hz */ ++ u16 direction_angle; /* -180 - + 180 */ ++ u16 elevation_angle; /* -180 - + 180 */ ++ u16 work_vertical_angle_begin; /* -180 - + 180 with 2 deg step */ ++ u16 work_vertical_angle_end; /* -180 - + 180 with 2 deg step */ ++ u16 work_horizontal_angle_begin; /* -180 - + 180 with 2 deg step */ ++ u16 work_horizontal_angle_end; /* -180 - + 180 with 2 deg step */ + }; + + /* Values for Type field above */ +@@ -1638,9 +1638,9 @@ struct acpi_nhlt_vendor_mic_config { + #define ACPI_NHLT_MIC_SUPER_CARDIOID 3 + #define ACPI_NHLT_MIC_HYPER_CARDIOID 4 + #define ACPI_NHLT_MIC_8_SHAPED 5 +-#define ACPI_NHLT_MIC_RESERVED6 6 // 6 is reserved ++#define ACPI_NHLT_MIC_RESERVED6 6 /* 6 is reserved */ + #define ACPI_NHLT_MIC_VENDOR_DEFINED 7 +-#define ACPI_NHLT_MIC_RESERVED 8 // 8 and above are reserved ++#define ACPI_NHLT_MIC_RESERVED 8 /* 8 and above are reserved */ + + /* Values for Panel field above */ + +@@ -1650,12 +1650,12 @@ struct acpi_nhlt_vendor_mic_config { + #define ACPI_NHLT_MIC_POSITION_RIGHT 3 + #define ACPI_NHLT_MIC_POSITION_FRONT 4 + #define ACPI_NHLT_MIC_POSITION_BACK 5 +-#define ACPI_NHLT_MIC_POSITION_RESERVED 6 // 6 and above are reserved ++#define ACPI_NHLT_MIC_POSITION_RESERVED 6 /* 6 and above are reserved */ + + struct acpi_nhlt_vendor_mic_device_specific_config { + struct acpi_nhlt_mic_device_specific_config mic_array_device_config; + u8 number_of_microphones; +- struct acpi_nhlt_vendor_mic_config mic_config[]; // indexed by number_of_microphones ++ struct acpi_nhlt_vendor_mic_config mic_config[]; /* Indexed by number_of_microphones */ + }; + + /* Microphone SNR and Sensitivity extension */ +@@ -1668,8 +1668,8 @@ struct acpi_nhlt_mic_snr_sensitivity_ext + /* Render device with feedback */ + + struct acpi_nhlt_render_feedback_device_specific_config { +- u8 feedback_virtual_slot; // render slot in case of capture +- u16 feedback_channels; // informative only ++ u8 feedback_virtual_slot; /* Render slot in case of capture */ ++ u16 feedback_channels; /* Informative only */ + u16 feedback_valid_bits_per_sample; + }; + +--- a/include/acpi/actypes.h ++++ b/include/acpi/actypes.h +@@ -539,14 +539,14 @@ typedef u64 acpi_integer; + * Can be used with access_width of struct acpi_generic_address and access_size of + * struct acpi_resource_generic_register. + */ +-#define ACPI_ACCESS_BIT_SHIFT 2 +-#define ACPI_ACCESS_BYTE_SHIFT -1 +-#define ACPI_ACCESS_BIT_MAX (31 - ACPI_ACCESS_BIT_SHIFT) +-#define ACPI_ACCESS_BYTE_MAX (31 - ACPI_ACCESS_BYTE_SHIFT) +-#define ACPI_ACCESS_BIT_DEFAULT (8 - ACPI_ACCESS_BIT_SHIFT) +-#define ACPI_ACCESS_BYTE_DEFAULT (8 - ACPI_ACCESS_BYTE_SHIFT) +-#define ACPI_ACCESS_BIT_WIDTH(size) (1 << ((size) + ACPI_ACCESS_BIT_SHIFT)) +-#define ACPI_ACCESS_BYTE_WIDTH(size) (1 << ((size) + ACPI_ACCESS_BYTE_SHIFT)) ++#define ACPI_ACCESS_BIT_SHIFT 2 ++#define ACPI_ACCESS_BYTE_SHIFT -1 ++#define ACPI_ACCESS_BIT_MAX (31 - ACPI_ACCESS_BIT_SHIFT) ++#define ACPI_ACCESS_BYTE_MAX (31 - ACPI_ACCESS_BYTE_SHIFT) ++#define ACPI_ACCESS_BIT_DEFAULT (8 - ACPI_ACCESS_BIT_SHIFT) ++#define ACPI_ACCESS_BYTE_DEFAULT (8 - ACPI_ACCESS_BYTE_SHIFT) ++#define ACPI_ACCESS_BIT_WIDTH(size) (1 << ((size) + ACPI_ACCESS_BIT_SHIFT)) ++#define ACPI_ACCESS_BYTE_WIDTH(size) (1 << ((size) + ACPI_ACCESS_BYTE_SHIFT)) + + /******************************************************************************* + * diff --git a/patches.suse/ACPICA-Update-copyright-notices-to-the-year-2022.patch b/patches.suse/ACPICA-Update-copyright-notices-to-the-year-2022.patch new file mode 100644 index 0000000..85170db --- /dev/null +++ b/patches.suse/ACPICA-Update-copyright-notices-to-the-year-2022.patch @@ -0,0 +1,2115 @@ +From: Bob Moore +Date: Mon, 11 Apr 2022 20:54:22 +0200 +Subject: ACPICA: Update copyright notices to the year 2022 +Patch-mainline: v5.19-rc1 +Git-commit: 487ea80a2848b7147eede3b73a4ee160c150f567 +References: jsc#PED-1408 + +ACPICA commit 738d7b0726e6c0458ef93c0a01c0377490888d1e + +Affects all source modules and utility signons. + +Link: https://github.com/acpica/acpica/commit/738d7b07 +Signed-off-by: Bob Moore +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/acpica/acapps.h | 4 ++-- + drivers/acpi/acpica/accommon.h | 2 +- + drivers/acpi/acpica/acconvert.h | 2 +- + drivers/acpi/acpica/acdebug.h | 2 +- + drivers/acpi/acpica/acdispat.h | 2 +- + drivers/acpi/acpica/acevents.h | 2 +- + drivers/acpi/acpica/acglobal.h | 2 +- + drivers/acpi/acpica/achware.h | 2 +- + drivers/acpi/acpica/acinterp.h | 2 +- + drivers/acpi/acpica/aclocal.h | 2 +- + drivers/acpi/acpica/acmacros.h | 2 +- + drivers/acpi/acpica/acnamesp.h | 2 +- + drivers/acpi/acpica/acobject.h | 2 +- + drivers/acpi/acpica/acopcode.h | 2 +- + drivers/acpi/acpica/acparser.h | 2 +- + drivers/acpi/acpica/acpredef.h | 2 +- + drivers/acpi/acpica/acresrc.h | 2 +- + drivers/acpi/acpica/acstruct.h | 2 +- + drivers/acpi/acpica/actables.h | 2 +- + drivers/acpi/acpica/acutils.h | 2 +- + drivers/acpi/acpica/amlcode.h | 2 +- + drivers/acpi/acpica/amlresrc.h | 2 +- + drivers/acpi/acpica/dbhistry.c | 2 +- + drivers/acpi/acpica/dsargs.c | 2 +- + drivers/acpi/acpica/dscontrol.c | 2 +- + drivers/acpi/acpica/dsdebug.c | 2 +- + drivers/acpi/acpica/dsfield.c | 2 +- + drivers/acpi/acpica/dsinit.c | 2 +- + drivers/acpi/acpica/dsmethod.c | 2 +- + drivers/acpi/acpica/dsobject.c | 2 +- + drivers/acpi/acpica/dsopcode.c | 2 +- + drivers/acpi/acpica/dspkginit.c | 2 +- + drivers/acpi/acpica/dswexec.c | 2 +- + drivers/acpi/acpica/dswload.c | 2 +- + drivers/acpi/acpica/dswload2.c | 2 +- + drivers/acpi/acpica/dswscope.c | 2 +- + drivers/acpi/acpica/dswstate.c | 2 +- + drivers/acpi/acpica/evevent.c | 2 +- + drivers/acpi/acpica/evglock.c | 2 +- + drivers/acpi/acpica/evgpe.c | 2 +- + drivers/acpi/acpica/evgpeblk.c | 2 +- + drivers/acpi/acpica/evgpeinit.c | 2 +- + drivers/acpi/acpica/evgpeutil.c | 2 +- + drivers/acpi/acpica/evhandler.c | 2 +- + drivers/acpi/acpica/evmisc.c | 2 +- + drivers/acpi/acpica/evregion.c | 2 +- + drivers/acpi/acpica/evrgnini.c | 2 +- + drivers/acpi/acpica/evxface.c | 2 +- + drivers/acpi/acpica/evxfevnt.c | 2 +- + drivers/acpi/acpica/evxfgpe.c | 2 +- + drivers/acpi/acpica/evxfregn.c | 2 +- + drivers/acpi/acpica/exconcat.c | 2 +- + drivers/acpi/acpica/exconfig.c | 2 +- + drivers/acpi/acpica/exconvrt.c | 2 +- + drivers/acpi/acpica/excreate.c | 2 +- + drivers/acpi/acpica/exdebug.c | 2 +- + drivers/acpi/acpica/exdump.c | 2 +- + drivers/acpi/acpica/exfield.c | 2 +- + drivers/acpi/acpica/exfldio.c | 2 +- + drivers/acpi/acpica/exmisc.c | 2 +- + drivers/acpi/acpica/exmutex.c | 2 +- + drivers/acpi/acpica/exnames.c | 2 +- + drivers/acpi/acpica/exoparg1.c | 2 +- + drivers/acpi/acpica/exoparg2.c | 2 +- + drivers/acpi/acpica/exoparg3.c | 2 +- + drivers/acpi/acpica/exoparg6.c | 2 +- + drivers/acpi/acpica/exprep.c | 2 +- + drivers/acpi/acpica/exregion.c | 2 +- + drivers/acpi/acpica/exresnte.c | 2 +- + drivers/acpi/acpica/exresolv.c | 2 +- + drivers/acpi/acpica/exresop.c | 2 +- + drivers/acpi/acpica/exserial.c | 2 +- + drivers/acpi/acpica/exstore.c | 2 +- + drivers/acpi/acpica/exstoren.c | 2 +- + drivers/acpi/acpica/exstorob.c | 2 +- + drivers/acpi/acpica/exsystem.c | 2 +- + drivers/acpi/acpica/extrace.c | 2 +- + drivers/acpi/acpica/exutils.c | 2 +- + drivers/acpi/acpica/hwacpi.c | 2 +- + drivers/acpi/acpica/hwesleep.c | 2 +- + drivers/acpi/acpica/hwgpe.c | 2 +- + drivers/acpi/acpica/hwsleep.c | 2 +- + drivers/acpi/acpica/hwtimer.c | 2 +- + drivers/acpi/acpica/hwvalid.c | 2 +- + drivers/acpi/acpica/hwxface.c | 2 +- + drivers/acpi/acpica/hwxfsleep.c | 2 +- + drivers/acpi/acpica/nsarguments.c | 2 +- + drivers/acpi/acpica/nsconvert.c | 2 +- + drivers/acpi/acpica/nsdump.c | 2 +- + drivers/acpi/acpica/nsdumpdv.c | 2 +- + drivers/acpi/acpica/nsinit.c | 2 +- + drivers/acpi/acpica/nsload.c | 2 +- + drivers/acpi/acpica/nsparse.c | 2 +- + drivers/acpi/acpica/nspredef.c | 2 +- + drivers/acpi/acpica/nsprepkg.c | 2 +- + drivers/acpi/acpica/nsrepair.c | 2 +- + drivers/acpi/acpica/nsrepair2.c | 2 +- + drivers/acpi/acpica/nsutils.c | 2 +- + drivers/acpi/acpica/nswalk.c | 2 +- + drivers/acpi/acpica/nsxfname.c | 2 +- + drivers/acpi/acpica/psargs.c | 2 +- + drivers/acpi/acpica/psloop.c | 2 +- + drivers/acpi/acpica/psobject.c | 2 +- + drivers/acpi/acpica/psopcode.c | 2 +- + drivers/acpi/acpica/psopinfo.c | 2 +- + drivers/acpi/acpica/psparse.c | 2 +- + drivers/acpi/acpica/psscope.c | 2 +- + drivers/acpi/acpica/pstree.c | 2 +- + drivers/acpi/acpica/psutils.c | 2 +- + drivers/acpi/acpica/pswalk.c | 2 +- + drivers/acpi/acpica/psxface.c | 2 +- + drivers/acpi/acpica/tbdata.c | 2 +- + drivers/acpi/acpica/tbfadt.c | 2 +- + drivers/acpi/acpica/tbfind.c | 2 +- + drivers/acpi/acpica/tbinstal.c | 2 +- + drivers/acpi/acpica/tbprint.c | 2 +- + drivers/acpi/acpica/tbutils.c | 2 +- + drivers/acpi/acpica/tbxface.c | 2 +- + drivers/acpi/acpica/tbxfload.c | 2 +- + drivers/acpi/acpica/tbxfroot.c | 2 +- + drivers/acpi/acpica/utaddress.c | 2 +- + drivers/acpi/acpica/utalloc.c | 2 +- + drivers/acpi/acpica/utascii.c | 2 +- + drivers/acpi/acpica/utbuffer.c | 2 +- + drivers/acpi/acpica/utcache.c | 2 +- + drivers/acpi/acpica/utcopy.c | 2 +- + drivers/acpi/acpica/utdebug.c | 2 +- + drivers/acpi/acpica/utdecode.c | 2 +- + drivers/acpi/acpica/uteval.c | 2 +- + drivers/acpi/acpica/utglobal.c | 2 +- + drivers/acpi/acpica/uthex.c | 2 +- + drivers/acpi/acpica/utids.c | 2 +- + drivers/acpi/acpica/utinit.c | 2 +- + drivers/acpi/acpica/utlock.c | 2 +- + drivers/acpi/acpica/utobject.c | 2 +- + drivers/acpi/acpica/utosi.c | 2 +- + drivers/acpi/acpica/utpredef.c | 2 +- + drivers/acpi/acpica/utprint.c | 2 +- + drivers/acpi/acpica/uttrack.c | 2 +- + drivers/acpi/acpica/utuuid.c | 2 +- + drivers/acpi/acpica/utxface.c | 2 +- + drivers/acpi/acpica/utxfinit.c | 2 +- + include/acpi/acbuffer.h | 2 +- + include/acpi/acconfig.h | 2 +- + include/acpi/acexcep.h | 2 +- + include/acpi/acnames.h | 2 +- + include/acpi/acoutput.h | 2 +- + include/acpi/acpi.h | 2 +- + include/acpi/acpiosxf.h | 2 +- + include/acpi/acpixf.h | 2 +- + include/acpi/acrestyp.h | 2 +- + include/acpi/actbl.h | 2 +- + include/acpi/actbl1.h | 2 +- + include/acpi/actbl2.h | 2 +- + include/acpi/actbl3.h | 2 +- + include/acpi/actypes.h | 2 +- + include/acpi/acuuid.h | 2 +- + include/acpi/platform/acenv.h | 2 +- + include/acpi/platform/acenvex.h | 2 +- + include/acpi/platform/acgcc.h | 2 +- + include/acpi/platform/acgccex.h | 2 +- + include/acpi/platform/acintel.h | 2 +- + include/acpi/platform/aclinux.h | 2 +- + include/acpi/platform/aclinuxex.h | 2 +- + tools/power/acpi/common/cmfsize.c | 2 +- + tools/power/acpi/common/getopt.c | 2 +- + tools/power/acpi/os_specific/service_layers/oslinuxtbl.c | 2 +- + tools/power/acpi/os_specific/service_layers/osunixdir.c | 2 +- + tools/power/acpi/os_specific/service_layers/osunixmap.c | 2 +- + tools/power/acpi/os_specific/service_layers/osunixxf.c | 2 +- + tools/power/acpi/tools/acpidump/acpidump.h | 2 +- + tools/power/acpi/tools/acpidump/apdump.c | 2 +- + tools/power/acpi/tools/acpidump/apfiles.c | 2 +- + tools/power/acpi/tools/acpidump/apmain.c | 2 +- + 174 files changed, 175 insertions(+), 175 deletions(-) + +--- a/drivers/acpi/acpica/acapps.h ++++ b/drivers/acpi/acpica/acapps.h +@@ -3,7 +3,7 @@ + * + * Module Name: acapps - common include for ACPI applications/tools + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +@@ -17,7 +17,7 @@ + /* Common info for tool signons */ + + #define ACPICA_NAME "Intel ACPI Component Architecture" +-#define ACPICA_COPYRIGHT "Copyright (c) 2000 - 2021 Intel Corporation" ++#define ACPICA_COPYRIGHT "Copyright (c) 2000 - 2022 Intel Corporation" + + #if ACPI_MACHINE_WIDTH == 64 + #define ACPI_WIDTH " (64-bit version)" +--- a/drivers/acpi/acpica/accommon.h ++++ b/drivers/acpi/acpica/accommon.h +@@ -3,7 +3,7 @@ + * + * Name: accommon.h - Common include files for generation of ACPICA source + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/acconvert.h ++++ b/drivers/acpi/acpica/acconvert.h +@@ -3,7 +3,7 @@ + * + * Module Name: acapps - common include for ACPI applications/tools + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/acdebug.h ++++ b/drivers/acpi/acpica/acdebug.h +@@ -3,7 +3,7 @@ + * + * Name: acdebug.h - ACPI/AML debugger + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/acdispat.h ++++ b/drivers/acpi/acpica/acdispat.h +@@ -3,7 +3,7 @@ + * + * Name: acdispat.h - dispatcher (parser to interpreter interface) + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/acevents.h ++++ b/drivers/acpi/acpica/acevents.h +@@ -3,7 +3,7 @@ + * + * Name: acevents.h - Event subcomponent prototypes and defines + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/acglobal.h ++++ b/drivers/acpi/acpica/acglobal.h +@@ -3,7 +3,7 @@ + * + * Name: acglobal.h - Declarations for global variables + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/achware.h ++++ b/drivers/acpi/acpica/achware.h +@@ -3,7 +3,7 @@ + * + * Name: achware.h -- hardware specific interfaces + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/acinterp.h ++++ b/drivers/acpi/acpica/acinterp.h +@@ -3,7 +3,7 @@ + * + * Name: acinterp.h - Interpreter subcomponent prototypes and defines + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/aclocal.h ++++ b/drivers/acpi/acpica/aclocal.h +@@ -3,7 +3,7 @@ + * + * Name: aclocal.h - Internal data types used across the ACPI subsystem + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/acmacros.h ++++ b/drivers/acpi/acpica/acmacros.h +@@ -3,7 +3,7 @@ + * + * Name: acmacros.h - C macros for the entire subsystem. + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/acnamesp.h ++++ b/drivers/acpi/acpica/acnamesp.h +@@ -3,7 +3,7 @@ + * + * Name: acnamesp.h - Namespace subcomponent prototypes and defines + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/acobject.h ++++ b/drivers/acpi/acpica/acobject.h +@@ -3,7 +3,7 @@ + * + * Name: acobject.h - Definition of union acpi_operand_object (Internal object only) + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/acopcode.h ++++ b/drivers/acpi/acpica/acopcode.h +@@ -3,7 +3,7 @@ + * + * Name: acopcode.h - AML opcode information for the AML parser and interpreter + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/acparser.h ++++ b/drivers/acpi/acpica/acparser.h +@@ -3,7 +3,7 @@ + * + * Module Name: acparser.h - AML Parser subcomponent prototypes and defines + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/acpredef.h ++++ b/drivers/acpi/acpica/acpredef.h +@@ -3,7 +3,7 @@ + * + * Name: acpredef - Information table for ACPI predefined methods and objects + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/acresrc.h ++++ b/drivers/acpi/acpica/acresrc.h +@@ -3,7 +3,7 @@ + * + * Name: acresrc.h - Resource Manager function prototypes + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/acstruct.h ++++ b/drivers/acpi/acpica/acstruct.h +@@ -3,7 +3,7 @@ + * + * Name: acstruct.h - Internal structs + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/actables.h ++++ b/drivers/acpi/acpica/actables.h +@@ -3,7 +3,7 @@ + * + * Name: actables.h - ACPI table management + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/acutils.h ++++ b/drivers/acpi/acpica/acutils.h +@@ -3,7 +3,7 @@ + * + * Name: acutils.h -- prototypes for the common (subsystem-wide) procedures + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/amlcode.h ++++ b/drivers/acpi/acpica/amlcode.h +@@ -5,7 +5,7 @@ + * Declarations and definitions contained herein are derived + * directly from the ACPI specification. + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/amlresrc.h ++++ b/drivers/acpi/acpica/amlresrc.h +@@ -3,7 +3,7 @@ + * + * Module Name: amlresrc.h - AML resource descriptors + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/dbhistry.c ++++ b/drivers/acpi/acpica/dbhistry.c +@@ -3,7 +3,7 @@ + * + * Module Name: dbhistry - debugger HISTORY command + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/dsargs.c ++++ b/drivers/acpi/acpica/dsargs.c +@@ -4,7 +4,7 @@ + * Module Name: dsargs - Support for execution of dynamic arguments for static + * objects (regions, fields, buffer fields, etc.) + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/dscontrol.c ++++ b/drivers/acpi/acpica/dscontrol.c +@@ -4,7 +4,7 @@ + * Module Name: dscontrol - Support for execution control opcodes - + * if/else/while/return + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/dsdebug.c ++++ b/drivers/acpi/acpica/dsdebug.c +@@ -3,7 +3,7 @@ + * + * Module Name: dsdebug - Parser/Interpreter interface - debugging + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/dsfield.c ++++ b/drivers/acpi/acpica/dsfield.c +@@ -3,7 +3,7 @@ + * + * Module Name: dsfield - Dispatcher field routines + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/dsinit.c ++++ b/drivers/acpi/acpica/dsinit.c +@@ -3,7 +3,7 @@ + * + * Module Name: dsinit - Object initialization namespace walk + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/dsmethod.c ++++ b/drivers/acpi/acpica/dsmethod.c +@@ -3,7 +3,7 @@ + * + * Module Name: dsmethod - Parser/Interpreter interface - control method parsing + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/dsobject.c ++++ b/drivers/acpi/acpica/dsobject.c +@@ -3,7 +3,7 @@ + * + * Module Name: dsobject - Dispatcher object management routines + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/dsopcode.c ++++ b/drivers/acpi/acpica/dsopcode.c +@@ -3,7 +3,7 @@ + * + * Module Name: dsopcode - Dispatcher support for regions and fields + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/dspkginit.c ++++ b/drivers/acpi/acpica/dspkginit.c +@@ -3,7 +3,7 @@ + * + * Module Name: dspkginit - Completion of deferred package initialization + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/dswexec.c ++++ b/drivers/acpi/acpica/dswexec.c +@@ -4,7 +4,7 @@ + * Module Name: dswexec - Dispatcher method execution callbacks; + * dispatch to interpreter. + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/dswload.c ++++ b/drivers/acpi/acpica/dswload.c +@@ -3,7 +3,7 @@ + * + * Module Name: dswload - Dispatcher first pass namespace load callbacks + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/dswload2.c ++++ b/drivers/acpi/acpica/dswload2.c +@@ -3,7 +3,7 @@ + * + * Module Name: dswload2 - Dispatcher second pass namespace load callbacks + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/dswscope.c ++++ b/drivers/acpi/acpica/dswscope.c +@@ -3,7 +3,7 @@ + * + * Module Name: dswscope - Scope stack manipulation + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/dswstate.c ++++ b/drivers/acpi/acpica/dswstate.c +@@ -3,7 +3,7 @@ + * + * Module Name: dswstate - Dispatcher parse tree walk management routines + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/evevent.c ++++ b/drivers/acpi/acpica/evevent.c +@@ -3,7 +3,7 @@ + * + * Module Name: evevent - Fixed Event handling and dispatch + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/evglock.c ++++ b/drivers/acpi/acpica/evglock.c +@@ -3,7 +3,7 @@ + * + * Module Name: evglock - Global Lock support + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/evgpe.c ++++ b/drivers/acpi/acpica/evgpe.c +@@ -3,7 +3,7 @@ + * + * Module Name: evgpe - General Purpose Event handling and dispatch + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/evgpeblk.c ++++ b/drivers/acpi/acpica/evgpeblk.c +@@ -3,7 +3,7 @@ + * + * Module Name: evgpeblk - GPE block creation and initialization. + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/evgpeinit.c ++++ b/drivers/acpi/acpica/evgpeinit.c +@@ -3,7 +3,7 @@ + * + * Module Name: evgpeinit - System GPE initialization and update + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/evgpeutil.c ++++ b/drivers/acpi/acpica/evgpeutil.c +@@ -3,7 +3,7 @@ + * + * Module Name: evgpeutil - GPE utilities + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/evhandler.c ++++ b/drivers/acpi/acpica/evhandler.c +@@ -3,7 +3,7 @@ + * + * Module Name: evhandler - Support for Address Space handlers + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/evmisc.c ++++ b/drivers/acpi/acpica/evmisc.c +@@ -3,7 +3,7 @@ + * + * Module Name: evmisc - Miscellaneous event manager support functions + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/evregion.c ++++ b/drivers/acpi/acpica/evregion.c +@@ -3,7 +3,7 @@ + * + * Module Name: evregion - Operation Region support + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/evrgnini.c ++++ b/drivers/acpi/acpica/evrgnini.c +@@ -3,7 +3,7 @@ + * + * Module Name: evrgnini- ACPI address_space (op_region) init + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/evxface.c ++++ b/drivers/acpi/acpica/evxface.c +@@ -3,7 +3,7 @@ + * + * Module Name: evxface - External interfaces for ACPI events + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/evxfevnt.c ++++ b/drivers/acpi/acpica/evxfevnt.c +@@ -3,7 +3,7 @@ + * + * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/evxfgpe.c ++++ b/drivers/acpi/acpica/evxfgpe.c +@@ -3,7 +3,7 @@ + * + * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs) + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/evxfregn.c ++++ b/drivers/acpi/acpica/evxfregn.c +@@ -4,7 +4,7 @@ + * Module Name: evxfregn - External Interfaces, ACPI Operation Regions and + * Address Spaces. + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/exconcat.c ++++ b/drivers/acpi/acpica/exconcat.c +@@ -3,7 +3,7 @@ + * + * Module Name: exconcat - Concatenate-type AML operators + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/exconfig.c ++++ b/drivers/acpi/acpica/exconfig.c +@@ -3,7 +3,7 @@ + * + * Module Name: exconfig - Namespace reconfiguration (Load/Unload opcodes) + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/exconvrt.c ++++ b/drivers/acpi/acpica/exconvrt.c +@@ -3,7 +3,7 @@ + * + * Module Name: exconvrt - Object conversion routines + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/excreate.c ++++ b/drivers/acpi/acpica/excreate.c +@@ -3,7 +3,7 @@ + * + * Module Name: excreate - Named object creation + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/exdebug.c ++++ b/drivers/acpi/acpica/exdebug.c +@@ -3,7 +3,7 @@ + * + * Module Name: exdebug - Support for stores to the AML Debug Object + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/exdump.c ++++ b/drivers/acpi/acpica/exdump.c +@@ -3,7 +3,7 @@ + * + * Module Name: exdump - Interpreter debug output routines + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/exfield.c ++++ b/drivers/acpi/acpica/exfield.c +@@ -3,7 +3,7 @@ + * + * Module Name: exfield - AML execution - field_unit read/write + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/exfldio.c ++++ b/drivers/acpi/acpica/exfldio.c +@@ -3,7 +3,7 @@ + * + * Module Name: exfldio - Aml Field I/O + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/exmisc.c ++++ b/drivers/acpi/acpica/exmisc.c +@@ -3,7 +3,7 @@ + * + * Module Name: exmisc - ACPI AML (p-code) execution - specific opcodes + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/exmutex.c ++++ b/drivers/acpi/acpica/exmutex.c +@@ -3,7 +3,7 @@ + * + * Module Name: exmutex - ASL Mutex Acquire/Release functions + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/exnames.c ++++ b/drivers/acpi/acpica/exnames.c +@@ -3,7 +3,7 @@ + * + * Module Name: exnames - interpreter/scanner name load/execute + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/exoparg1.c ++++ b/drivers/acpi/acpica/exoparg1.c +@@ -3,7 +3,7 @@ + * + * Module Name: exoparg1 - AML execution - opcodes with 1 argument + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/exoparg2.c ++++ b/drivers/acpi/acpica/exoparg2.c +@@ -3,7 +3,7 @@ + * + * Module Name: exoparg2 - AML execution - opcodes with 2 arguments + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/exoparg3.c ++++ b/drivers/acpi/acpica/exoparg3.c +@@ -3,7 +3,7 @@ + * + * Module Name: exoparg3 - AML execution - opcodes with 3 arguments + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/exoparg6.c ++++ b/drivers/acpi/acpica/exoparg6.c +@@ -3,7 +3,7 @@ + * + * Module Name: exoparg6 - AML execution - opcodes with 6 arguments + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/exprep.c ++++ b/drivers/acpi/acpica/exprep.c +@@ -3,7 +3,7 @@ + * + * Module Name: exprep - ACPI AML field prep utilities + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/exregion.c ++++ b/drivers/acpi/acpica/exregion.c +@@ -3,7 +3,7 @@ + * + * Module Name: exregion - ACPI default op_region (address space) handlers + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/exresnte.c ++++ b/drivers/acpi/acpica/exresnte.c +@@ -3,7 +3,7 @@ + * + * Module Name: exresnte - AML Interpreter object resolution + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/exresolv.c ++++ b/drivers/acpi/acpica/exresolv.c +@@ -3,7 +3,7 @@ + * + * Module Name: exresolv - AML Interpreter object resolution + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/exresop.c ++++ b/drivers/acpi/acpica/exresop.c +@@ -3,7 +3,7 @@ + * + * Module Name: exresop - AML Interpreter operand/object resolution + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/exserial.c ++++ b/drivers/acpi/acpica/exserial.c +@@ -3,7 +3,7 @@ + * + * Module Name: exserial - field_unit support for serial address spaces + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/exstore.c ++++ b/drivers/acpi/acpica/exstore.c +@@ -3,7 +3,7 @@ + * + * Module Name: exstore - AML Interpreter object store support + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/exstoren.c ++++ b/drivers/acpi/acpica/exstoren.c +@@ -4,7 +4,7 @@ + * Module Name: exstoren - AML Interpreter object store support, + * Store to Node (namespace object) + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/exstorob.c ++++ b/drivers/acpi/acpica/exstorob.c +@@ -3,7 +3,7 @@ + * + * Module Name: exstorob - AML object store support, store to object + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/exsystem.c ++++ b/drivers/acpi/acpica/exsystem.c +@@ -3,7 +3,7 @@ + * + * Module Name: exsystem - Interface to OS services + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/extrace.c ++++ b/drivers/acpi/acpica/extrace.c +@@ -3,7 +3,7 @@ + * + * Module Name: extrace - Support for interpreter execution tracing + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/exutils.c ++++ b/drivers/acpi/acpica/exutils.c +@@ -3,7 +3,7 @@ + * + * Module Name: exutils - interpreter/scanner utilities + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/hwacpi.c ++++ b/drivers/acpi/acpica/hwacpi.c +@@ -3,7 +3,7 @@ + * + * Module Name: hwacpi - ACPI Hardware Initialization/Mode Interface + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/hwesleep.c ++++ b/drivers/acpi/acpica/hwesleep.c +@@ -4,7 +4,7 @@ + * Name: hwesleep.c - ACPI Hardware Sleep/Wake Support functions for the + * extended FADT-V5 sleep registers. + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/hwgpe.c ++++ b/drivers/acpi/acpica/hwgpe.c +@@ -3,7 +3,7 @@ + * + * Module Name: hwgpe - Low level GPE enable/disable/clear functions + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/hwsleep.c ++++ b/drivers/acpi/acpica/hwsleep.c +@@ -4,7 +4,7 @@ + * Name: hwsleep.c - ACPI Hardware Sleep/Wake Support functions for the + * original/legacy sleep/PM registers. + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/hwtimer.c ++++ b/drivers/acpi/acpica/hwtimer.c +@@ -3,7 +3,7 @@ + * + * Name: hwtimer.c - ACPI Power Management Timer Interface + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/hwvalid.c ++++ b/drivers/acpi/acpica/hwvalid.c +@@ -3,7 +3,7 @@ + * + * Module Name: hwvalid - I/O request validation + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/hwxface.c ++++ b/drivers/acpi/acpica/hwxface.c +@@ -3,7 +3,7 @@ + * + * Module Name: hwxface - Public ACPICA hardware interfaces + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/hwxfsleep.c ++++ b/drivers/acpi/acpica/hwxfsleep.c +@@ -3,7 +3,7 @@ + * + * Name: hwxfsleep.c - ACPI Hardware Sleep/Wake External Interfaces + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/nsarguments.c ++++ b/drivers/acpi/acpica/nsarguments.c +@@ -3,7 +3,7 @@ + * + * Module Name: nsarguments - Validation of args for ACPI predefined methods + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/nsconvert.c ++++ b/drivers/acpi/acpica/nsconvert.c +@@ -4,7 +4,7 @@ + * Module Name: nsconvert - Object conversions for objects returned by + * predefined methods + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/nsdump.c ++++ b/drivers/acpi/acpica/nsdump.c +@@ -3,7 +3,7 @@ + * + * Module Name: nsdump - table dumping routines for debug + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/nsdumpdv.c ++++ b/drivers/acpi/acpica/nsdumpdv.c +@@ -3,7 +3,7 @@ + * + * Module Name: nsdump - table dumping routines for debug + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/nsinit.c ++++ b/drivers/acpi/acpica/nsinit.c +@@ -3,7 +3,7 @@ + * + * Module Name: nsinit - namespace initialization + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/nsload.c ++++ b/drivers/acpi/acpica/nsload.c +@@ -3,7 +3,7 @@ + * + * Module Name: nsload - namespace loading/expanding/contracting procedures + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/nsparse.c ++++ b/drivers/acpi/acpica/nsparse.c +@@ -3,7 +3,7 @@ + * + * Module Name: nsparse - namespace interface to AML parser + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/nspredef.c ++++ b/drivers/acpi/acpica/nspredef.c +@@ -3,7 +3,7 @@ + * + * Module Name: nspredef - Validation of ACPI predefined methods and objects + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/nsprepkg.c ++++ b/drivers/acpi/acpica/nsprepkg.c +@@ -3,7 +3,7 @@ + * + * Module Name: nsprepkg - Validation of package objects for predefined names + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/nsrepair.c ++++ b/drivers/acpi/acpica/nsrepair.c +@@ -3,7 +3,7 @@ + * + * Module Name: nsrepair - Repair for objects returned by predefined methods + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/nsrepair2.c ++++ b/drivers/acpi/acpica/nsrepair2.c +@@ -4,7 +4,7 @@ + * Module Name: nsrepair2 - Repair for objects returned by specific + * predefined methods + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/nsutils.c ++++ b/drivers/acpi/acpica/nsutils.c +@@ -4,7 +4,7 @@ + * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing + * parents and siblings and Scope manipulation + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/nswalk.c ++++ b/drivers/acpi/acpica/nswalk.c +@@ -3,7 +3,7 @@ + * + * Module Name: nswalk - Functions for walking the ACPI namespace + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/nsxfname.c ++++ b/drivers/acpi/acpica/nsxfname.c +@@ -4,7 +4,7 @@ + * Module Name: nsxfname - Public interfaces to the ACPI subsystem + * ACPI Namespace oriented interfaces + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/psargs.c ++++ b/drivers/acpi/acpica/psargs.c +@@ -3,7 +3,7 @@ + * + * Module Name: psargs - Parse AML opcode arguments + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/psloop.c ++++ b/drivers/acpi/acpica/psloop.c +@@ -3,7 +3,7 @@ + * + * Module Name: psloop - Main AML parse loop + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/psobject.c ++++ b/drivers/acpi/acpica/psobject.c +@@ -3,7 +3,7 @@ + * + * Module Name: psobject - Support for parse objects + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/psopcode.c ++++ b/drivers/acpi/acpica/psopcode.c +@@ -3,7 +3,7 @@ + * + * Module Name: psopcode - Parser/Interpreter opcode information table + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/psopinfo.c ++++ b/drivers/acpi/acpica/psopinfo.c +@@ -3,7 +3,7 @@ + * + * Module Name: psopinfo - AML opcode information functions and dispatch tables + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/psparse.c ++++ b/drivers/acpi/acpica/psparse.c +@@ -3,7 +3,7 @@ + * + * Module Name: psparse - Parser top level AML parse routines + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/psscope.c ++++ b/drivers/acpi/acpica/psscope.c +@@ -3,7 +3,7 @@ + * + * Module Name: psscope - Parser scope stack management routines + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/pstree.c ++++ b/drivers/acpi/acpica/pstree.c +@@ -3,7 +3,7 @@ + * + * Module Name: pstree - Parser op tree manipulation/traversal/search + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/psutils.c ++++ b/drivers/acpi/acpica/psutils.c +@@ -3,7 +3,7 @@ + * + * Module Name: psutils - Parser miscellaneous utilities (Parser only) + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/pswalk.c ++++ b/drivers/acpi/acpica/pswalk.c +@@ -3,7 +3,7 @@ + * + * Module Name: pswalk - Parser routines to walk parsed op tree(s) + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/psxface.c ++++ b/drivers/acpi/acpica/psxface.c +@@ -3,7 +3,7 @@ + * + * Module Name: psxface - Parser external interfaces + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/tbdata.c ++++ b/drivers/acpi/acpica/tbdata.c +@@ -3,7 +3,7 @@ + * + * Module Name: tbdata - Table manager data structure functions + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/tbfadt.c ++++ b/drivers/acpi/acpica/tbfadt.c +@@ -3,7 +3,7 @@ + * + * Module Name: tbfadt - FADT table utilities + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/tbfind.c ++++ b/drivers/acpi/acpica/tbfind.c +@@ -3,7 +3,7 @@ + * + * Module Name: tbfind - find table + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/tbinstal.c ++++ b/drivers/acpi/acpica/tbinstal.c +@@ -3,7 +3,7 @@ + * + * Module Name: tbinstal - ACPI table installation and removal + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/tbprint.c ++++ b/drivers/acpi/acpica/tbprint.c +@@ -3,7 +3,7 @@ + * + * Module Name: tbprint - Table output utilities + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/tbutils.c ++++ b/drivers/acpi/acpica/tbutils.c +@@ -3,7 +3,7 @@ + * + * Module Name: tbutils - ACPI Table utilities + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/tbxface.c ++++ b/drivers/acpi/acpica/tbxface.c +@@ -3,7 +3,7 @@ + * + * Module Name: tbxface - ACPI table-oriented external interfaces + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/tbxfload.c ++++ b/drivers/acpi/acpica/tbxfload.c +@@ -3,7 +3,7 @@ + * + * Module Name: tbxfload - Table load/unload external interfaces + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/tbxfroot.c ++++ b/drivers/acpi/acpica/tbxfroot.c +@@ -3,7 +3,7 @@ + * + * Module Name: tbxfroot - Find the root ACPI table (RSDT) + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/utaddress.c ++++ b/drivers/acpi/acpica/utaddress.c +@@ -3,7 +3,7 @@ + * + * Module Name: utaddress - op_region address range check + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/utalloc.c ++++ b/drivers/acpi/acpica/utalloc.c +@@ -3,7 +3,7 @@ + * + * Module Name: utalloc - local memory allocation routines + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/utascii.c ++++ b/drivers/acpi/acpica/utascii.c +@@ -3,7 +3,7 @@ + * + * Module Name: utascii - Utility ascii functions + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/utbuffer.c ++++ b/drivers/acpi/acpica/utbuffer.c +@@ -3,7 +3,7 @@ + * + * Module Name: utbuffer - Buffer dump routines + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/utcache.c ++++ b/drivers/acpi/acpica/utcache.c +@@ -3,7 +3,7 @@ + * + * Module Name: utcache - local cache allocation routines + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/utcopy.c ++++ b/drivers/acpi/acpica/utcopy.c +@@ -3,7 +3,7 @@ + * + * Module Name: utcopy - Internal to external object translation utilities + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/utdebug.c ++++ b/drivers/acpi/acpica/utdebug.c +@@ -3,7 +3,7 @@ + * + * Module Name: utdebug - Debug print/trace routines + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/utdecode.c ++++ b/drivers/acpi/acpica/utdecode.c +@@ -3,7 +3,7 @@ + * + * Module Name: utdecode - Utility decoding routines (value-to-string) + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/uteval.c ++++ b/drivers/acpi/acpica/uteval.c +@@ -3,7 +3,7 @@ + * + * Module Name: uteval - Object evaluation + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/utglobal.c ++++ b/drivers/acpi/acpica/utglobal.c +@@ -3,7 +3,7 @@ + * + * Module Name: utglobal - Global variables for the ACPI subsystem + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/uthex.c ++++ b/drivers/acpi/acpica/uthex.c +@@ -3,7 +3,7 @@ + * + * Module Name: uthex -- Hex/ASCII support functions + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/utids.c ++++ b/drivers/acpi/acpica/utids.c +@@ -3,7 +3,7 @@ + * + * Module Name: utids - support for device Ids - HID, UID, CID, SUB, CLS + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/utinit.c ++++ b/drivers/acpi/acpica/utinit.c +@@ -3,7 +3,7 @@ + * + * Module Name: utinit - Common ACPI subsystem initialization + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/utlock.c ++++ b/drivers/acpi/acpica/utlock.c +@@ -3,7 +3,7 @@ + * + * Module Name: utlock - Reader/Writer lock interfaces + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/utobject.c ++++ b/drivers/acpi/acpica/utobject.c +@@ -3,7 +3,7 @@ + * + * Module Name: utobject - ACPI object create/delete/size/cache routines + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/utosi.c ++++ b/drivers/acpi/acpica/utosi.c +@@ -3,7 +3,7 @@ + * + * Module Name: utosi - Support for the _OSI predefined control method + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/utpredef.c ++++ b/drivers/acpi/acpica/utpredef.c +@@ -3,7 +3,7 @@ + * + * Module Name: utpredef - support functions for predefined names + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/utprint.c ++++ b/drivers/acpi/acpica/utprint.c +@@ -3,7 +3,7 @@ + * + * Module Name: utprint - Formatted printing routines + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/uttrack.c ++++ b/drivers/acpi/acpica/uttrack.c +@@ -3,7 +3,7 @@ + * + * Module Name: uttrack - Memory allocation tracking routines (debug only) + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/utuuid.c ++++ b/drivers/acpi/acpica/utuuid.c +@@ -3,7 +3,7 @@ + * + * Module Name: utuuid -- UUID support functions + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/utxface.c ++++ b/drivers/acpi/acpica/utxface.c +@@ -3,7 +3,7 @@ + * + * Module Name: utxface - External interfaces, miscellaneous utility functions + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/drivers/acpi/acpica/utxfinit.c ++++ b/drivers/acpi/acpica/utxfinit.c +@@ -3,7 +3,7 @@ + * + * Module Name: utxfinit - External interfaces for ACPICA initialization + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/include/acpi/acbuffer.h ++++ b/include/acpi/acbuffer.h +@@ -3,7 +3,7 @@ + * + * Name: acbuffer.h - Support for buffers returned by ACPI predefined names + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/include/acpi/acconfig.h ++++ b/include/acpi/acconfig.h +@@ -3,7 +3,7 @@ + * + * Name: acconfig.h - Global configuration constants + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/include/acpi/acexcep.h ++++ b/include/acpi/acexcep.h +@@ -3,7 +3,7 @@ + * + * Name: acexcep.h - Exception codes returned by the ACPI subsystem + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/include/acpi/acnames.h ++++ b/include/acpi/acnames.h +@@ -3,7 +3,7 @@ + * + * Name: acnames.h - Global names and strings + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/include/acpi/acoutput.h ++++ b/include/acpi/acoutput.h +@@ -3,7 +3,7 @@ + * + * Name: acoutput.h -- debug output + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/include/acpi/acpi.h ++++ b/include/acpi/acpi.h +@@ -3,7 +3,7 @@ + * + * Name: acpi.h - Master public include file used to interface to ACPICA + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/include/acpi/acpiosxf.h ++++ b/include/acpi/acpiosxf.h +@@ -5,7 +5,7 @@ + * interfaces must be implemented by OSL to interface the + * ACPI components to the host operating system. + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/include/acpi/acpixf.h ++++ b/include/acpi/acpixf.h +@@ -3,7 +3,7 @@ + * + * Name: acpixf.h - External interfaces to the ACPI subsystem + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/include/acpi/acrestyp.h ++++ b/include/acpi/acrestyp.h +@@ -3,7 +3,7 @@ + * + * Name: acrestyp.h - Defines, types, and structures for resource descriptors + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/include/acpi/actbl.h ++++ b/include/acpi/actbl.h +@@ -3,7 +3,7 @@ + * + * Name: actbl.h - Basic ACPI Table Definitions + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/include/acpi/actbl1.h ++++ b/include/acpi/actbl1.h +@@ -3,7 +3,7 @@ + * + * Name: actbl1.h - Additional ACPI table definitions + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/include/acpi/actbl2.h ++++ b/include/acpi/actbl2.h +@@ -3,7 +3,7 @@ + * + * Name: actbl2.h - ACPI Table Definitions (tables not in ACPI spec) + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/include/acpi/actbl3.h ++++ b/include/acpi/actbl3.h +@@ -3,7 +3,7 @@ + * + * Name: actbl3.h - ACPI Table Definitions + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/include/acpi/actypes.h ++++ b/include/acpi/actypes.h +@@ -3,7 +3,7 @@ + * + * Name: actypes.h - Common data types for the entire ACPI subsystem + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/include/acpi/acuuid.h ++++ b/include/acpi/acuuid.h +@@ -3,7 +3,7 @@ + * + * Name: acuuid.h - ACPI-related UUID/GUID definitions + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/include/acpi/platform/acenv.h ++++ b/include/acpi/platform/acenv.h +@@ -3,7 +3,7 @@ + * + * Name: acenv.h - Host and compiler configuration + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/include/acpi/platform/acenvex.h ++++ b/include/acpi/platform/acenvex.h +@@ -3,7 +3,7 @@ + * + * Name: acenvex.h - Extra host and compiler configuration + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/include/acpi/platform/acgcc.h ++++ b/include/acpi/platform/acgcc.h +@@ -3,7 +3,7 @@ + * + * Name: acgcc.h - GCC specific defines, etc. + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/include/acpi/platform/acgccex.h ++++ b/include/acpi/platform/acgccex.h +@@ -3,7 +3,7 @@ + * + * Name: acgccex.h - Extra GCC specific defines, etc. + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/include/acpi/platform/acintel.h ++++ b/include/acpi/platform/acintel.h +@@ -3,7 +3,7 @@ + * + * Name: acintel.h - VC specific defines, etc. + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/include/acpi/platform/aclinux.h ++++ b/include/acpi/platform/aclinux.h +@@ -3,7 +3,7 @@ + * + * Name: aclinux.h - OS specific defines, etc. for Linux + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/include/acpi/platform/aclinuxex.h ++++ b/include/acpi/platform/aclinuxex.h +@@ -3,7 +3,7 @@ + * + * Name: aclinuxex.h - Extra OS specific defines, etc. for Linux + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/tools/power/acpi/common/cmfsize.c ++++ b/tools/power/acpi/common/cmfsize.c +@@ -3,7 +3,7 @@ + * + * Module Name: cmfsize - Common get file size function + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/tools/power/acpi/common/getopt.c ++++ b/tools/power/acpi/common/getopt.c +@@ -3,7 +3,7 @@ + * + * Module Name: getopt + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c ++++ b/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c +@@ -3,7 +3,7 @@ + * + * Module Name: oslinuxtbl - Linux OSL for obtaining ACPI tables + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/tools/power/acpi/os_specific/service_layers/osunixdir.c ++++ b/tools/power/acpi/os_specific/service_layers/osunixdir.c +@@ -3,7 +3,7 @@ + * + * Module Name: osunixdir - Unix directory access interfaces + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/tools/power/acpi/os_specific/service_layers/osunixmap.c ++++ b/tools/power/acpi/os_specific/service_layers/osunixmap.c +@@ -3,7 +3,7 @@ + * + * Module Name: osunixmap - Unix OSL for file mappings + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/tools/power/acpi/os_specific/service_layers/osunixxf.c ++++ b/tools/power/acpi/os_specific/service_layers/osunixxf.c +@@ -3,7 +3,7 @@ + * + * Module Name: osunixxf - UNIX OSL interfaces + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/tools/power/acpi/tools/acpidump/acpidump.h ++++ b/tools/power/acpi/tools/acpidump/acpidump.h +@@ -3,7 +3,7 @@ + * + * Module Name: acpidump.h - Include file for acpi_dump utility + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/tools/power/acpi/tools/acpidump/apdump.c ++++ b/tools/power/acpi/tools/acpidump/apdump.c +@@ -3,7 +3,7 @@ + * + * Module Name: apdump - Dump routines for ACPI tables (acpidump) + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/tools/power/acpi/tools/acpidump/apfiles.c ++++ b/tools/power/acpi/tools/acpidump/apfiles.c +@@ -3,7 +3,7 @@ + * + * Module Name: apfiles - File-related functions for acpidump utility + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + +--- a/tools/power/acpi/tools/acpidump/apmain.c ++++ b/tools/power/acpi/tools/acpidump/apmain.c +@@ -3,7 +3,7 @@ + * + * Module Name: apmain - Main module for the acpidump utility + * +- * Copyright (C) 2000 - 2021, Intel Corp. ++ * Copyright (C) 2000 - 2022, Intel Corp. + * + *****************************************************************************/ + diff --git a/patches.suse/ACPICA-Update-version-to-20220331.patch b/patches.suse/ACPICA-Update-version-to-20220331.patch new file mode 100644 index 0000000..d145397 --- /dev/null +++ b/patches.suse/ACPICA-Update-version-to-20220331.patch @@ -0,0 +1,30 @@ +From: Bob Moore +Date: Mon, 11 Apr 2022 21:04:03 +0200 +Subject: ACPICA: Update version to 20220331 +Patch-mainline: v5.19-rc1 +Git-commit: 0076ca940e3f1a1eae6b5e39b6594c96934713a2 +References: jsc#PED-1408 + +ACPICA commit ada5b805eaa7480930082af9bc3d689c6f181329 + +Version 20220331. + +Link: https://github.com/acpica/acpica/commit/ada5b805 +Signed-off-by: Bob Moore +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + include/acpi/acpixf.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/include/acpi/acpixf.h ++++ b/include/acpi/acpixf.h +@@ -12,7 +12,7 @@ + + /* Current ACPICA subsystem version in YYYYMMDD format */ + +-#define ACPI_CA_VERSION 0x20211217 ++#define ACPI_CA_VERSION 0x20220331 + + #include + #include diff --git a/patches.suse/ACPICA-executer-exsystem-Add-units-to-time-variable-.patch b/patches.suse/ACPICA-executer-exsystem-Add-units-to-time-variable-.patch new file mode 100644 index 0000000..589fda8 --- /dev/null +++ b/patches.suse/ACPICA-executer-exsystem-Add-units-to-time-variable-.patch @@ -0,0 +1,94 @@ +From: Paul Menzel +Date: Mon, 11 Apr 2022 20:57:02 +0200 +Subject: ACPICA: executer/exsystem: Add units to time variable names +Patch-mainline: v5.19-rc1 +Git-commit: 1838ffe7001bf37e3e31796c7b04e5e083df886e +References: jsc#PED-1408 + +ACPICA commit b69cbef7a83eadb102a1ff6c6f6fc5abce34805a + +`how_long` refers to different units in both functions, so make it more +clear, what unit they expect. That also makes one comment superfluous. + +Link: https://github.com/acpica/acpica/commit/b69cbef7 +Signed-off-by: Bob Moore +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/acpica/exsystem.c | 22 +++++++++++----------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +--- a/drivers/acpi/acpica/exsystem.c ++++ b/drivers/acpi/acpica/exsystem.c +@@ -107,7 +107,7 @@ acpi_status acpi_ex_system_wait_mutex(ac + * + * FUNCTION: acpi_ex_system_do_stall + * +- * PARAMETERS: how_long - The amount of time to stall, ++ * PARAMETERS: how_long_us - The amount of time to stall, + * in microseconds + * + * RETURN: Status +@@ -120,24 +120,24 @@ acpi_status acpi_ex_system_wait_mutex(ac + * + ******************************************************************************/ + +-acpi_status acpi_ex_system_do_stall(u32 how_long) ++acpi_status acpi_ex_system_do_stall(u32 how_long_us) + { + acpi_status status = AE_OK; + + ACPI_FUNCTION_ENTRY(); + +- if (how_long > 255) { /* 255 microseconds */ ++ if (how_long_us > 255) { + /* +- * Longer than 255 usec, this is an error ++ * Longer than 255 microseconds, this is an error + * + * (ACPI specifies 100 usec as max, but this gives some slack in + * order to support existing BIOSs) + */ + ACPI_ERROR((AE_INFO, +- "Time parameter is too large (%u)", how_long)); ++ "Time parameter is too large (%u)", how_long_us)); + status = AE_AML_OPERAND_VALUE; + } else { +- acpi_os_stall(how_long); ++ acpi_os_stall(how_long_us); + } + + return (status); +@@ -147,7 +147,7 @@ acpi_status acpi_ex_system_do_stall(u32 + * + * FUNCTION: acpi_ex_system_do_sleep + * +- * PARAMETERS: how_long - The amount of time to sleep, ++ * PARAMETERS: how_long_ms - The amount of time to sleep, + * in milliseconds + * + * RETURN: None +@@ -156,7 +156,7 @@ acpi_status acpi_ex_system_do_stall(u32 + * + ******************************************************************************/ + +-acpi_status acpi_ex_system_do_sleep(u64 how_long) ++acpi_status acpi_ex_system_do_sleep(u64 how_long_ms) + { + ACPI_FUNCTION_ENTRY(); + +@@ -168,11 +168,11 @@ acpi_status acpi_ex_system_do_sleep(u64 + * For compatibility with other ACPI implementations and to prevent + * accidental deep sleeps, limit the sleep time to something reasonable. + */ +- if (how_long > ACPI_MAX_SLEEP) { +- how_long = ACPI_MAX_SLEEP; ++ if (how_long_ms > ACPI_MAX_SLEEP) { ++ how_long_ms = ACPI_MAX_SLEEP; + } + +- acpi_os_sleep(how_long); ++ acpi_os_sleep(how_long_ms); + + /* And now we must get the interpreter again */ + diff --git a/patches.suse/ACPICA-executer-exsystem-Fix-some-typo-mistakes.patch b/patches.suse/ACPICA-executer-exsystem-Fix-some-typo-mistakes.patch new file mode 100644 index 0000000..1bf0441 --- /dev/null +++ b/patches.suse/ACPICA-executer-exsystem-Fix-some-typo-mistakes.patch @@ -0,0 +1,40 @@ +From: Selvarasu Ganesan +Date: Mon, 11 Apr 2022 21:01:36 +0200 +Subject: ACPICA: executer/exsystem: Fix some typo mistakes +Patch-mainline: v5.19-rc1 +Git-commit: 3d6c6552f1c1b174e1bc27102f55942ec94f144d +References: jsc#PED-1408 + +ACPICA commit 441747f1dcff770d692acbfd4d85b2cfaabdb38a + +Link: https://github.com/acpica/acpica/commit/441747f1 +Signed-off-by: Selvarasu Ganesan +Signed-off-by: Bob Moore +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/acpica/exsystem.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/acpi/acpica/exsystem.c ++++ b/drivers/acpi/acpica/exsystem.c +@@ -137,7 +137,7 @@ acpi_status acpi_ex_system_do_stall(u32 + "Time parameter is too large (%u)", how_long_us)); + status = AE_AML_OPERAND_VALUE; + } else { +- if (how_long_US > 100) { ++ if (how_long_us > 100) { + ACPI_WARNING((AE_INFO, + "Time parameter %u us > 100 us violating ACPI spec, please fix the firmware.", + how_long_us)); +@@ -175,8 +175,8 @@ acpi_status acpi_ex_system_do_sleep(u64 + */ + if (how_long_ms > 10) { + ACPI_WARNING((AE_INFO, +- "Firmware issue: Excessive sleep time (%llu ms > 10 ms) in ACPI Control Method", +- how_long_us)); ++ "Firmware issue: Excessive sleep time (%lu ms > 10 ms) in ACPI Control Method", ++ how_long_ms)); + } + + /* diff --git a/patches.suse/ACPICA-executer-exsystem-Inform-users-about-ACPI-spe.patch b/patches.suse/ACPICA-executer-exsystem-Inform-users-about-ACPI-spe.patch new file mode 100644 index 0000000..e43fb23 --- /dev/null +++ b/patches.suse/ACPICA-executer-exsystem-Inform-users-about-ACPI-spe.patch @@ -0,0 +1,42 @@ +From: Paul Menzel +Date: Mon, 11 Apr 2022 20:59:00 +0200 +Subject: ACPICA: executer/exsystem: Inform users about ACPI spec violation +Patch-mainline: v5.19-rc1 +Git-commit: ace8f1c54a02b96036b50defa9d842c10292b6bb +References: jsc#PED-1408 + +ACPICA commit 05ba545ce7859392250b18c10081db25c90ed8d7 + +Values greater than 100 microseconds violate the ACPI specification, so +warn users about it. + +From ACPI Specification version 6.2 Errata A, 19.6.128 *Stall (Stall for +a Short Time)*: + +> The implementation of Stall is OS-specific, but must not relinquish +> control of the processor. Because of this, delays longer than 100 +> microseconds must use Sleep instead of Stall. + +Link: https://github.com/acpica/acpica/commit/05ba545c +Signed-off-by: Bob Moore +Signed-off-by: Rafael J. Wysocki +Reported-by: kernel test robot +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/acpica/exsystem.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/acpi/acpica/exsystem.c ++++ b/drivers/acpi/acpica/exsystem.c +@@ -137,6 +137,11 @@ acpi_status acpi_ex_system_do_stall(u32 + "Time parameter is too large (%u)", how_long_us)); + status = AE_AML_OPERAND_VALUE; + } else { ++ if (how_long_US > 100) { ++ ACPI_WARNING((AE_INFO, ++ "Time parameter %u us > 100 us violating ACPI spec, please fix the firmware.", ++ how_long_us)); ++ } + acpi_os_stall(how_long_us); + } + diff --git a/patches.suse/ACPICA-executer-exsystem-Warn-about-sleeps-greater-t.patch b/patches.suse/ACPICA-executer-exsystem-Warn-about-sleeps-greater-t.patch new file mode 100644 index 0000000..016feec --- /dev/null +++ b/patches.suse/ACPICA-executer-exsystem-Warn-about-sleeps-greater-t.patch @@ -0,0 +1,43 @@ +From: Paul Menzel +Date: Mon, 11 Apr 2022 20:59:51 +0200 +Subject: ACPICA: executer/exsystem: Warn about sleeps greater than 10 ms +Patch-mainline: v5.19-rc1 +Git-commit: 6eaf08770ee8562ea497c8b3f1c0079832953e20 +References: jsc#PED-1408 + +ACPICA commit 2a0d1d475e7ea1c815bee1e0692d81db9a7c909c + +Quick boottime is important, so warn about sleeps greater than 10 ms. + +Distribution Linux kernels reach initrd in 350 ms, so excessive delays +should be called out. 10 ms is chosen randomly, but three of such delays +would already make up ten percent of the boottime. + +Link: https://github.com/acpica/acpica/commit/2a0d1d47 +Signed-off-by: Bob Moore +Signed-off-by: Rafael J. Wysocki +Reported-by: kernel test robot +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/acpica/exsystem.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/drivers/acpi/acpica/exsystem.c ++++ b/drivers/acpi/acpica/exsystem.c +@@ -170,6 +170,16 @@ acpi_status acpi_ex_system_do_sleep(u64 + acpi_ex_exit_interpreter(); + + /* ++ * Warn users about excessive sleep times, so ASL code can be improved to ++ * use polling or similar techniques. ++ */ ++ if (how_long_ms > 10) { ++ ACPI_WARNING((AE_INFO, ++ "Firmware issue: Excessive sleep time (%llu ms > 10 ms) in ACPI Control Method", ++ how_long_us)); ++ } ++ ++ /* + * For compatibility with other ACPI implementations and to prevent + * accidental deep sleeps, limit the sleep time to something reasonable. + */ diff --git a/patches.suse/ACPICA-exsystem.c-Use-ACPI_FORMAT_UINT64-for-64-bit-.patch b/patches.suse/ACPICA-exsystem.c-Use-ACPI_FORMAT_UINT64-for-64-bit-.patch new file mode 100644 index 0000000..7d33f8c --- /dev/null +++ b/patches.suse/ACPICA-exsystem.c-Use-ACPI_FORMAT_UINT64-for-64-bit-.patch @@ -0,0 +1,33 @@ +From: Bob Moore +Date: Mon, 11 Apr 2022 21:03:16 +0200 +Subject: ACPICA: exsystem.c: Use ACPI_FORMAT_UINT64 for 64-bit output +Patch-mainline: v5.19-rc1 +Git-commit: bf285d25406ed44d1711d59155a658032d31a11c +References: jsc#PED-1408 + +ACPICA commit 82a46ba57fe03ae99342740b92a04d8a8184860d + +%llu fails on 32-bit compilers. + +Link: https://github.com/acpica/acpica/commit/82a46ba5 +Signed-off-by: Bob Moore +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/acpica/exsystem.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/acpi/acpica/exsystem.c ++++ b/drivers/acpi/acpica/exsystem.c +@@ -175,8 +175,9 @@ acpi_status acpi_ex_system_do_sleep(u64 + */ + if (how_long_ms > 10) { + ACPI_WARNING((AE_INFO, +- "Firmware issue: Excessive sleep time (%lu ms > 10 ms) in ACPI Control Method", +- how_long_ms)); ++ "Firmware issue: Excessive sleep time (0x%8.8X%8.8X ms > 10 ms)" ++ " in ACPI Control Method", ++ ACPI_FORMAT_UINT64(how_long_ms))); + } + + /* diff --git a/patches.suse/ACPICA-iASL-MADT-Add-OEM-defined-subtable.patch b/patches.suse/ACPICA-iASL-MADT-Add-OEM-defined-subtable.patch new file mode 100644 index 0000000..8aa5147 --- /dev/null +++ b/patches.suse/ACPICA-iASL-MADT-Add-OEM-defined-subtable.patch @@ -0,0 +1,44 @@ +From: Bob Moore +Date: Mon, 11 Apr 2022 21:00:45 +0200 +Subject: ACPICA: iASL/MADT: Add OEM-defined subtable +Patch-mainline: v5.19-rc1 +Git-commit: da6a9bbedc79c49ba94a6ca746580a9b43931641 +References: jsc#PED-1408 + +ACPICA commit 4450b89b596a2b54b0cdfe2357b49a63445c2e03 + +Adds support for the "reserved for OEM use" subtable (types 0x80 to 0xFF). + +Link: https://github.com/acpica/acpica/commit/4450b89b +Signed-off-by: Bob Moore +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + include/acpi/actbl2.h | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/include/acpi/actbl2.h ++++ b/include/acpi/actbl2.h +@@ -842,7 +842,8 @@ enum acpi_madt_type { + ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR = 14, + ACPI_MADT_TYPE_GENERIC_TRANSLATOR = 15, + ACPI_MADT_TYPE_MULTIPROC_WAKEUP = 16, +- ACPI_MADT_TYPE_RESERVED = 17 /* 17 and greater are reserved */ ++ ACPI_MADT_TYPE_RESERVED = 17, /* 17 to 0x7F are reserved */ ++ ACPI_MADT_TYPE_OEM_RESERVED = 0x80 /* 0x80 to 0xFF are reserved for OEM use */ + }; + + /* +@@ -1072,6 +1073,12 @@ struct acpi_madt_multiproc_wakeup_mailbo + + #define ACPI_MP_WAKE_COMMAND_WAKEUP 1 + ++/* 17: OEM data */ ++ ++struct acpi_madt_oem_data { ++ u8 oem_data[0]; ++}; ++ + /* + * Common flags fields for MADT subtables + */ diff --git a/patches.suse/ACPICA-iASL-NHLT-Fix-parsing-undocumented-bytes-at-t.patch b/patches.suse/ACPICA-iASL-NHLT-Fix-parsing-undocumented-bytes-at-t.patch new file mode 100644 index 0000000..3463529 --- /dev/null +++ b/patches.suse/ACPICA-iASL-NHLT-Fix-parsing-undocumented-bytes-at-t.patch @@ -0,0 +1,34 @@ +From: Piotr Maziarz +Date: Mon, 11 Apr 2022 20:49:08 +0200 +Subject: ACPICA: iASL: NHLT: Fix parsing undocumented bytes at the end of + Endpoint Descriptor +Patch-mainline: v5.19-rc1 +Git-commit: ab1ba87bd71a507286781b8a7f5c64e1eb7a2d34 +References: jsc#PED-1408 + +ACPICA commit 961221a76814ffa0ecc92219ddf857579b0f7d54 + +Undocumented bytes at the end of Endpoint Descriptor can be present +independently of Linux-specific structures. Their size can also vary. + +Link: https://github.com/acpica/acpica/commit/961221a7 +Signed-off-by: Bob Moore +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + include/acpi/actbl2.h | 4 ---- + 1 file changed, 4 deletions(-) + +--- a/include/acpi/actbl2.h ++++ b/include/acpi/actbl2.h +@@ -1685,10 +1685,6 @@ struct acpi_nhlt_linux_specific_data { + u8 device_port_id; + }; + +-struct acpi_nhlt_linux_specific_data_b { +- u8 specific_data[18]; +-}; +- + /******************************************************************************* + * + * PCCT - Platform Communications Channel Table (ACPI 5.0) diff --git a/patches.suse/ACPICA-iASL-NHLT-Rename-linux-specific-strucures-to-.patch b/patches.suse/ACPICA-iASL-NHLT-Rename-linux-specific-strucures-to-.patch new file mode 100644 index 0000000..2d2f859 --- /dev/null +++ b/patches.suse/ACPICA-iASL-NHLT-Rename-linux-specific-strucures-to-.patch @@ -0,0 +1,39 @@ +From: Piotr Maziarz +Date: Mon, 11 Apr 2022 20:50:25 +0200 +Subject: ACPICA: iASL: NHLT: Rename linux specific strucures to device_info +Patch-mainline: v5.19-rc1 +Git-commit: 8bd24835db1781685f9abd0d1b628eaaac20d7c1 +References: jsc#PED-1408 + +ACPICA commit 68c7e542075319d57129467872fcbe98906f2b2c + +Those structures aren't used by Linux drivers, and in other NHLT related +tools they are called device_info. + +Link: https://github.com/acpica/acpica/commit/68c7e542 +Signed-off-by: Bob Moore +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + include/acpi/actbl2.h | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/include/acpi/actbl2.h ++++ b/include/acpi/actbl2.h +@@ -1673,13 +1673,13 @@ struct acpi_nhlt_render_feedback_device_ + u16 feedback_valid_bits_per_sample; + }; + +-/* Linux-specific structures */ ++/* Non documented structures */ + +-struct acpi_nhlt_linux_specific_count { ++struct acpi_nhlt_device_info_count { + u8 structure_count; + }; + +-struct acpi_nhlt_linux_specific_data { ++struct acpi_nhlt_device_info { + u8 device_id[16]; + u8 device_instance_id; + u8 device_port_id; diff --git a/patches.suse/ACPICA-iASL-NHLT-Treat-Terminator-as-specific_config.patch b/patches.suse/ACPICA-iASL-NHLT-Treat-Terminator-as-specific_config.patch new file mode 100644 index 0000000..82588a6 --- /dev/null +++ b/patches.suse/ACPICA-iASL-NHLT-Treat-Terminator-as-specific_config.patch @@ -0,0 +1,35 @@ +From: Piotr Maziarz +Date: Mon, 11 Apr 2022 20:48:21 +0200 +Subject: ACPICA: iASL: NHLT: Treat Terminator as specific_config +Patch-mainline: v5.19-rc1 +Git-commit: 90037551c68d08facd6fb56a971352a9cd189c44 +References: jsc#PED-1408 + +ACPICA commit 23a659e190cf3ed0edd46cddf12bbbcfeaa09396 + +specific_config has 4 bytes of size and then an amount of bytes specified +by size. All of the terminators that I've seen had a size equal to 4, but +theoretically it can vary. + +Link: https://github.com/acpica/acpica/commit/23a659e1 +Signed-off-by: Bob Moore +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + include/acpi/actbl2.h | 5 ----- + 1 file changed, 5 deletions(-) + +--- a/include/acpi/actbl2.h ++++ b/include/acpi/actbl2.h +@@ -1689,11 +1689,6 @@ struct acpi_nhlt_linux_specific_data_b { + u8 specific_data[18]; + }; + +-struct acpi_nhlt_table_terminator { +- u32 terminator_value; +- u32 terminator_signature; +-}; +- + /******************************************************************************* + * + * PCCT - Platform Communications Channel Table (ACPI 5.0) diff --git a/patches.suse/ALSA-asihpi-Remove-useless-code-in-hpi_meter_get_pea.patch b/patches.suse/ALSA-asihpi-Remove-useless-code-in-hpi_meter_get_pea.patch new file mode 100644 index 0000000..853c07c --- /dev/null +++ b/patches.suse/ALSA-asihpi-Remove-useless-code-in-hpi_meter_get_pea.patch @@ -0,0 +1,37 @@ +From f51ba1148a810a16eead9f0b29bfa2a8f8ab3afb Mon Sep 17 00:00:00 2001 +From: Valentina Goncharenko +Date: Thu, 1 Sep 2022 13:28:14 +0300 +Subject: [PATCH] ALSA: asihpi - Remove useless code in hpi_meter_get_peak() +Git-commit: f51ba1148a810a16eead9f0b29bfa2a8f8ab3afb +Patch-mainline: v6.1-rc1 +References: git-fixes + +The hpi_meter_get_peak() function contains the expression +"hm.obj_index = hm.obj_index", which does not carry any semantic load. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 719f82d3987a ("ALSA: Add support of AudioScience ASI boards") +Signed-off-by: Valentina Goncharenko +Link: https://lore.kernel.org/r/20220901102814.131855-1-goncharenko.vp@ispras.ru +Signed-off-by: Takashi Iwai + +--- + sound/pci/asihpi/hpifunc.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/sound/pci/asihpi/hpifunc.c b/sound/pci/asihpi/hpifunc.c +index 1de05383126a..24047fafef51 100644 +--- a/sound/pci/asihpi/hpifunc.c ++++ b/sound/pci/asihpi/hpifunc.c +@@ -2020,7 +2020,6 @@ u16 hpi_meter_get_peak(u32 h_control, short an_peakdB[HPI_MAX_CHANNELS] + HPI_CONTROL_GET_STATE); + if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index)) + return HPI_ERROR_INVALID_HANDLE; +- hm.obj_index = hm.obj_index; + hm.u.c.attribute = HPI_METER_PEAK; + + hpi_send_recv(&hm, &hr); +-- +2.35.3 + diff --git a/patches.suse/ALSA-core-Fix-double-free-at-snd_card_new.patch b/patches.suse/ALSA-core-Fix-double-free-at-snd_card_new.patch new file mode 100644 index 0000000..6049e78 --- /dev/null +++ b/patches.suse/ALSA-core-Fix-double-free-at-snd_card_new.patch @@ -0,0 +1,69 @@ +From c3afa2a402d1ecefa59f88d55d9e765f52f75bd9 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Mon, 19 Sep 2022 14:35:16 +0200 +Subject: [PATCH] ALSA: core: Fix double-free at snd_card_new() +Git-commit: c3afa2a402d1ecefa59f88d55d9e765f52f75bd9 +Patch-mainline: v6.0-rc7 +References: git-fixes + +During the code change to add the support for devres-managed card +instance, we put an explicit kfree(card) call at the error path in +snd_card_new(). This is needed for the early error path before the +card is initialized with the device, but is rather superfluous and +causes a double-free at the error path after the card instance is +initialized, as the destructor of the card object already contains a +kfree() call. + +This patch fixes the double-free situation by removing the superfluous +kfree(). Meanwhile we need to call kfree() explicitly for the early +error path, so it's added there instead. + +Fixes: e8ad415b7a55 ("ALSA: core: Add managed card creation") +Reported-by: Rondreis +Cc: +Link: https://lore.kernel.org/r/CAB7eexL1zBnB636hwS27d-LdPYZ_R1-5fJS_h=ZbCWYU=UPWJg@mail.gmail.com +Link: https://lore.kernel.org/r/20220919123516.28222-1-tiwai@suse.de +Signed-off-by: Takashi Iwai + +--- + sound/core/init.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/sound/core/init.c b/sound/core/init.c +index 193dae361fac..5377f94eb211 100644 +--- a/sound/core/init.c ++++ b/sound/core/init.c +@@ -178,10 +178,8 @@ int snd_card_new(struct device *parent, int idx, const char *xid, + return -ENOMEM; + + err = snd_card_init(card, parent, idx, xid, module, extra_size); +- if (err < 0) { +- kfree(card); +- return err; +- } ++ if (err < 0) ++ return err; /* card is freed by error handler */ + + *card_ret = card; + return 0; +@@ -233,7 +231,7 @@ int snd_devm_card_new(struct device *parent, int idx, const char *xid, + card->managed = true; + err = snd_card_init(card, parent, idx, xid, module, extra_size); + if (err < 0) { +- devres_free(card); ++ devres_free(card); /* in managed mode, we need to free manually */ + return err; + } + +@@ -297,6 +295,8 @@ static int snd_card_init(struct snd_card *card, struct device *parent, + mutex_unlock(&snd_card_mutex); + dev_err(parent, "cannot find the slot for index %d (range 0-%i), error: %d\n", + idx, snd_ecards_limit - 1, err); ++ if (!card->managed) ++ kfree(card); /* manually free here, as no destructor called */ + return err; + } + set_bit(idx, snd_cards_lock); /* lock it */ +-- +2.35.3 + diff --git a/patches.suse/ALSA-cs35l41-Check-hw_config-before-using-it.patch b/patches.suse/ALSA-cs35l41-Check-hw_config-before-using-it.patch new file mode 100644 index 0000000..1786841 --- /dev/null +++ b/patches.suse/ALSA-cs35l41-Check-hw_config-before-using-it.patch @@ -0,0 +1,350 @@ +From 2603c974b45dbfeece80474ee32173756aac3ba1 Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Wed, 13 Apr 2022 09:37:14 +0100 +Subject: [PATCH] ALSA: cs35l41: Check hw_config before using it +Git-commit: 2603c974b45dbfeece80474ee32173756aac3ba1 +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +The driver can receive an empty hw_config, so mark as valid if +successfully read from device tree/ACPI or set by the driver itself. +Platforms not marked with a valid hw config will not be supported. + +Signed-off-by: Lucas Tanure +Acked-by: Charles Keepax +Link: https://lore.kernel.org/r/20220413083728.10730-3-tanureal@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + include/sound/cs35l41.h | 3 +- + sound/pci/hda/cs35l41_hda.c | 70 +++++++++++++++++++------------ + sound/soc/codecs/cs35l41-lib.c | 16 ++++--- + sound/soc/codecs/cs35l41.c | 76 +++++++++++++++++++++------------- + 4 files changed, 104 insertions(+), 61 deletions(-) + +diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h +index abcf850f7110..4200379e0c26 100644 +--- a/include/sound/cs35l41.h ++++ b/include/sound/cs35l41.h +@@ -538,7 +538,6 @@ + #define CS35L41_OTP_SIZE_WORDS 32 + #define CS35L41_NUM_OTP_ELEM 100 + +-#define CS35L41_VALID_PDATA 0x80000000 + #define CS35L41_NUM_SUPPLIES 2 + + #define CS35L41_SCLK_MSTR_MASK 0x10 +@@ -753,12 +752,14 @@ enum cs35l41_gpio2_func { + }; + + struct cs35l41_gpio_cfg { ++ bool valid; + bool pol_inv; + bool out_en; + unsigned int func; + }; + + struct cs35l41_hw_cfg { ++ bool valid; + int bst_ind; + int bst_ipk; + int bst_cap; +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index b79d6ad4b4f5..a14ad3b0d516 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -219,46 +219,52 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41) + bool internal_boost = false; + int ret; + ++ if (!cs35l41->hw_cfg.valid) ++ return -EINVAL; ++ + if (hw_cfg->vspk_always_on) { + cs35l41->reg_seq = &cs35l41_hda_reg_seq_no_bst; + return 0; + } + +- if (hw_cfg->bst_ind || hw_cfg->bst_cap || hw_cfg->bst_ipk) ++ if (hw_cfg->bst_ind > 0 || hw_cfg->bst_cap > 0 || hw_cfg->bst_ipk > 0) + internal_boost = true; + +- switch (hw_cfg->gpio1.func) { +- case CS35L41_NOT_USED: +- break; +- case CS35l41_VSPK_SWITCH: +- regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL, +- CS35L41_GPIO1_CTRL_MASK, 1 << CS35L41_GPIO1_CTRL_SHIFT); +- break; +- case CS35l41_SYNC: +- regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL, +- CS35L41_GPIO1_CTRL_MASK, 2 << CS35L41_GPIO1_CTRL_SHIFT); +- break; +- default: +- dev_err(cs35l41->dev, "Invalid function %d for GPIO1\n", hw_cfg->gpio1.func); +- return -EINVAL; ++ if (hw_cfg->gpio1.valid) { ++ switch (hw_cfg->gpio1.func) { ++ case CS35L41_NOT_USED: ++ break; ++ case CS35l41_VSPK_SWITCH: ++ regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL, ++ CS35L41_GPIO1_CTRL_MASK, 1 << CS35L41_GPIO1_CTRL_SHIFT); ++ break; ++ case CS35l41_SYNC: ++ regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL, ++ CS35L41_GPIO1_CTRL_MASK, 2 << CS35L41_GPIO1_CTRL_SHIFT); ++ break; ++ default: ++ dev_err(cs35l41->dev, "Invalid function %d for GPIO1\n", ++ hw_cfg->gpio1.func); ++ return -EINVAL; ++ } + } + +- switch (hw_cfg->gpio2.func) { +- case CS35L41_NOT_USED: +- break; +- case CS35L41_INTERRUPT: +- regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL, +- CS35L41_GPIO2_CTRL_MASK, 2 << CS35L41_GPIO2_CTRL_SHIFT); +- break; +- default: +- dev_err(cs35l41->dev, "Invalid function %d for GPIO2\n", hw_cfg->gpio2.func); +- return -EINVAL; ++ if (hw_cfg->gpio2.valid) { ++ switch (hw_cfg->gpio2.func) { ++ case CS35L41_NOT_USED: ++ break; ++ case CS35L41_INTERRUPT: ++ regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL, ++ CS35L41_GPIO2_CTRL_MASK, 2 << CS35L41_GPIO2_CTRL_SHIFT); ++ break; ++ default: ++ dev_err(cs35l41->dev, "Invalid GPIO2 function %d\n", hw_cfg->gpio2.func); ++ return -EINVAL; ++ } + } + + if (internal_boost) { + cs35l41->reg_seq = &cs35l41_hda_reg_seq_int_bst; +- if (!(hw_cfg->bst_ind && hw_cfg->bst_cap && hw_cfg->bst_ipk)) +- return -EINVAL; + ret = cs35l41_boost_config(cs35l41->dev, cs35l41->regmap, + hw_cfg->bst_ind, hw_cfg->bst_cap, hw_cfg->bst_ipk); + if (ret) +@@ -334,28 +340,37 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i + if (ret) + goto err; + hw_cfg->gpio1.func = values[cs35l41->index]; ++ hw_cfg->gpio1.valid = true; + + property = "cirrus,gpio2-func"; + ret = device_property_read_u32_array(physdev, property, values, nval); + if (ret) + goto err; + hw_cfg->gpio2.func = values[cs35l41->index]; ++ hw_cfg->gpio2.valid = true; + + property = "cirrus,boost-peak-milliamp"; + ret = device_property_read_u32_array(physdev, property, values, nval); + if (ret == 0) + hw_cfg->bst_ipk = values[cs35l41->index]; ++ else ++ hw_cfg->bst_ipk = -1; + + property = "cirrus,boost-ind-nanohenry"; + ret = device_property_read_u32_array(physdev, property, values, nval); + if (ret == 0) + hw_cfg->bst_ind = values[cs35l41->index]; ++ else ++ hw_cfg->bst_ind = -1; + + property = "cirrus,boost-cap-microfarad"; + ret = device_property_read_u32_array(physdev, property, values, nval); + if (ret == 0) + hw_cfg->bst_cap = values[cs35l41->index]; ++ else ++ hw_cfg->bst_cap = -1; + ++ hw_cfg->valid = true; + put_device(physdev); + + return 0; +@@ -381,6 +396,7 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i + cs35l41->index = id == 0x40 ? 0 : 1; + cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 0, GPIOD_OUT_HIGH); + cs35l41->hw_cfg.vspk_always_on = true; ++ cs35l41->hw_cfg.valid = true; + put_device(physdev); + + return 0; +diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c +index e5a56bcbb223..905c648a8f49 100644 +--- a/sound/soc/codecs/cs35l41-lib.c ++++ b/sound/soc/codecs/cs35l41-lib.c +@@ -992,10 +992,20 @@ int cs35l41_boost_config(struct device *dev, struct regmap *regmap, int boost_in + case 101 ... 200: + bst_cbst_range = 3; + break; +- default: /* 201 uF and greater */ ++ default: ++ if (boost_cap < 0) { ++ dev_err(dev, "Invalid boost capacitor value: %d nH\n", boost_cap); ++ return -EINVAL; ++ } ++ /* 201 uF and greater */ + bst_cbst_range = 4; + } + ++ if (boost_ipk < 1600 || boost_ipk > 4500) { ++ dev_err(dev, "Invalid boost inductor peak current: %d mA\n", boost_ipk); ++ return -EINVAL; ++ } ++ + ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_COEFF, + CS35L41_BST_K1_MASK | CS35L41_BST_K2_MASK, + cs35l41_bst_k1_table[bst_lbst_val][bst_cbst_range] +@@ -1017,10 +1027,6 @@ int cs35l41_boost_config(struct device *dev, struct regmap *regmap, int boost_in + return ret; + } + +- if (boost_ipk < 1600 || boost_ipk > 4500) { +- dev_err(dev, "Invalid boost inductor peak current: %d mA\n", boost_ipk); +- return -EINVAL; +- } + bst_ipk_scaled = ((boost_ipk - 1600) / 50) + 0x10; + + ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_PEAK_CUR, CS35L41_BST_IPK_MASK, +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index e76b93c15106..90dec80707ea 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -995,28 +995,24 @@ static int cs35l41_dai_set_sysclk(struct snd_soc_dai *dai, + + static int cs35l41_set_pdata(struct cs35l41_private *cs35l41) + { ++ struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg; + int ret; + +- /* Set Platform Data */ +- /* Required */ +- if (cs35l41->hw_cfg.bst_ipk && +- cs35l41->hw_cfg.bst_ind && cs35l41->hw_cfg.bst_cap) { +- ret = cs35l41_boost_config(cs35l41->dev, cs35l41->regmap, cs35l41->hw_cfg.bst_ind, +- cs35l41->hw_cfg.bst_cap, cs35l41->hw_cfg.bst_ipk); +- if (ret) { +- dev_err(cs35l41->dev, "Error in Boost DT config: %d\n", ret); +- return ret; +- } +- } else { +- dev_err(cs35l41->dev, "Incomplete Boost component DT config\n"); ++ if (!hw_cfg->valid) + return -EINVAL; ++ ++ /* Required */ ++ ret = cs35l41_boost_config(cs35l41->dev, cs35l41->regmap, ++ hw_cfg->bst_ind, hw_cfg->bst_cap, hw_cfg->bst_ipk); ++ if (ret) { ++ dev_err(cs35l41->dev, "Error in Boost DT config: %d\n", ret); ++ return ret; + } + + /* Optional */ +- if (cs35l41->hw_cfg.dout_hiz <= CS35L41_ASP_DOUT_HIZ_MASK && +- cs35l41->hw_cfg.dout_hiz >= 0) ++ if (hw_cfg->dout_hiz <= CS35L41_ASP_DOUT_HIZ_MASK && hw_cfg->dout_hiz >= 0) + regmap_update_bits(cs35l41->regmap, CS35L41_SP_HIZ_CTRL, CS35L41_ASP_DOUT_HIZ_MASK, +- cs35l41->hw_cfg.dout_hiz); ++ hw_cfg->dout_hiz); + + return 0; + } +@@ -1037,16 +1033,28 @@ static int cs35l41_gpio_config(struct cs35l41_private *cs35l41) + gpio2->pol_inv << CS35L41_GPIO_POL_SHIFT | + !gpio2->out_en << CS35L41_GPIO_DIR_SHIFT); + +- regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL, +- CS35L41_GPIO1_CTRL_MASK | CS35L41_GPIO2_CTRL_MASK, +- gpio1->func << CS35L41_GPIO1_CTRL_SHIFT | +- gpio2->func << CS35L41_GPIO2_CTRL_SHIFT); ++ if (gpio1->valid) ++ regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL, ++ CS35L41_GPIO1_CTRL_MASK, ++ gpio1->func << CS35L41_GPIO1_CTRL_SHIFT); + +- if ((gpio2->func == (CS35L41_GPIO2_INT_PUSH_PULL_LOW | CS35L41_VALID_PDATA)) || +- (gpio2->func == (CS35L41_GPIO2_INT_OPEN_DRAIN | CS35L41_VALID_PDATA))) +- irq_pol = IRQF_TRIGGER_LOW; +- else if (gpio2->func == (CS35L41_GPIO2_INT_PUSH_PULL_HIGH | CS35L41_VALID_PDATA)) +- irq_pol = IRQF_TRIGGER_HIGH; ++ if (gpio2->valid) { ++ regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL, ++ CS35L41_GPIO2_CTRL_MASK, ++ gpio2->func << CS35L41_GPIO2_CTRL_SHIFT); ++ ++ switch (gpio2->func) { ++ case CS35L41_GPIO2_INT_PUSH_PULL_LOW: ++ case CS35L41_GPIO2_INT_OPEN_DRAIN: ++ irq_pol = IRQF_TRIGGER_LOW; ++ break; ++ case CS35L41_GPIO2_INT_PUSH_PULL_HIGH: ++ irq_pol = IRQF_TRIGGER_HIGH; ++ break; ++ default: ++ break; ++ } ++ } + + return irq_pol; + } +@@ -1121,14 +1129,20 @@ static int cs35l41_handle_pdata(struct device *dev, struct cs35l41_hw_cfg *hw_cf + ret = device_property_read_u32(dev, "cirrus,boost-peak-milliamp", &val); + if (ret >= 0) + hw_cfg->bst_ipk = val; ++ else ++ hw_cfg->bst_ipk = -1; + + ret = device_property_read_u32(dev, "cirrus,boost-ind-nanohenry", &val); + if (ret >= 0) + hw_cfg->bst_ind = val; ++ else ++ hw_cfg->bst_ind = -1; + + ret = device_property_read_u32(dev, "cirrus,boost-cap-microfarad", &val); + if (ret >= 0) + hw_cfg->bst_cap = val; ++ else ++ hw_cfg->bst_cap = -1; + + ret = device_property_read_u32(dev, "cirrus,asp-sdout-hiz", &val); + if (ret >= 0) +@@ -1140,15 +1154,21 @@ static int cs35l41_handle_pdata(struct device *dev, struct cs35l41_hw_cfg *hw_cf + gpio1->pol_inv = device_property_read_bool(dev, "cirrus,gpio1-polarity-invert"); + gpio1->out_en = device_property_read_bool(dev, "cirrus,gpio1-output-enable"); + ret = device_property_read_u32(dev, "cirrus,gpio1-src-select", &val); +- if (ret >= 0) +- gpio1->func = val | CS35L41_VALID_PDATA; ++ if (ret >= 0) { ++ gpio1->func = val; ++ gpio1->valid = true; ++ } + + /* GPIO2 Pin Config */ + gpio2->pol_inv = device_property_read_bool(dev, "cirrus,gpio2-polarity-invert"); + gpio2->out_en = device_property_read_bool(dev, "cirrus,gpio2-output-enable"); + ret = device_property_read_u32(dev, "cirrus,gpio2-src-select", &val); +- if (ret >= 0) +- gpio2->func = val | CS35L41_VALID_PDATA; ++ if (ret >= 0) { ++ gpio2->func = val; ++ gpio2->valid = true; ++ } ++ ++ hw_cfg->valid = true; + + return 0; + } +-- +2.35.3 + diff --git a/patches.suse/ALSA-cs35l41-Enable-Internal-Boost-in-shared-lib.patch b/patches.suse/ALSA-cs35l41-Enable-Internal-Boost-in-shared-lib.patch new file mode 100644 index 0000000..299d81b --- /dev/null +++ b/patches.suse/ALSA-cs35l41-Enable-Internal-Boost-in-shared-lib.patch @@ -0,0 +1,39 @@ +From ca17707f441f7a033364fe18ed5590ab326d0b29 Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Wed, 13 Apr 2022 09:37:21 +0100 +Subject: [PATCH] ALSA: cs35l41: Enable Internal Boost in shared lib +Git-commit: ca17707f441f7a033364fe18ed5590ab326d0b29 +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +Internal Boost enable is the default option from reset, but with +external boost support, internal boost must be disabled. +Add the enable of internal boost in cs35l41_boost_config to +centralize the internal boost configuration. + +Signed-off-by: Lucas Tanure +Acked-by: Charles Keepax +Link: https://lore.kernel.org/r/20220413083728.10730-10-tanureal@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/soc/codecs/cs35l41-lib.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c +index eeeaeaa0db82..03039d8488b9 100644 +--- a/sound/soc/codecs/cs35l41-lib.c ++++ b/sound/soc/codecs/cs35l41-lib.c +@@ -1036,6 +1036,9 @@ int cs35l41_boost_config(struct device *dev, struct regmap *regmap, int boost_in + return ret; + } + ++ regmap_update_bits(regmap, CS35L41_PWR_CTRL2, CS35L41_BST_EN_MASK, ++ CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT); ++ + return 0; + } + EXPORT_SYMBOL_GPL(cs35l41_boost_config); +-- +2.35.3 + diff --git a/patches.suse/ALSA-cs35l41-Move-cs35l41_gpio_config-to-shared-lib.patch b/patches.suse/ALSA-cs35l41-Move-cs35l41_gpio_config-to-shared-lib.patch new file mode 100644 index 0000000..50d8423 --- /dev/null +++ b/patches.suse/ALSA-cs35l41-Move-cs35l41_gpio_config-to-shared-lib.patch @@ -0,0 +1,188 @@ +From fcad8950a50dec5962b1b7b18a285daf7c137178 Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Wed, 13 Apr 2022 09:37:15 +0100 +Subject: [PATCH] ALSA: cs35l41: Move cs35l41_gpio_config to shared lib +Git-commit: fcad8950a50dec5962b1b7b18a285daf7c137178 +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +ASoC and HDA can use a single function to configure the chip gpios. + +Signed-off-by: Lucas Tanure +Acked-by: Charles Keepax +Link: https://lore.kernel.org/r/20220413083728.10730-4-tanureal@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + include/sound/cs35l41.h | 1 + + sound/pci/hda/cs35l41_hda.c | 11 ++++----- + sound/soc/codecs/cs35l41-lib.c | 41 +++++++++++++++++++++++++++++++ + sound/soc/codecs/cs35l41.c | 44 +--------------------------------- + 4 files changed, 48 insertions(+), 49 deletions(-) + +diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h +index 4200379e0c26..e312eb1f6e48 100644 +--- a/include/sound/cs35l41.h ++++ b/include/sound/cs35l41.h +@@ -798,5 +798,6 @@ int cs35l41_set_channels(struct device *dev, struct regmap *reg, + unsigned int rx_num, unsigned int *rx_slot); + int cs35l41_boost_config(struct device *dev, struct regmap *regmap, int boost_ind, int boost_cap, + int boost_ipk); ++int cs35l41_gpio_config(struct regmap *regmap, struct cs35l41_hw_cfg *hw_cfg); + + #endif /* __CS35L41_H */ +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index a14ad3b0d516..e00ceaca79c0 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -235,12 +235,11 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41) + case CS35L41_NOT_USED: + break; + case CS35l41_VSPK_SWITCH: +- regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL, +- CS35L41_GPIO1_CTRL_MASK, 1 << CS35L41_GPIO1_CTRL_SHIFT); ++ hw_cfg->gpio1.func = CS35L41_GPIO1_GPIO; ++ hw_cfg->gpio1.out_en = true; + break; + case CS35l41_SYNC: +- regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL, +- CS35L41_GPIO1_CTRL_MASK, 2 << CS35L41_GPIO1_CTRL_SHIFT); ++ hw_cfg->gpio1.func = CS35L41_GPIO1_MDSYNC; + break; + default: + dev_err(cs35l41->dev, "Invalid function %d for GPIO1\n", +@@ -254,8 +253,6 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41) + case CS35L41_NOT_USED: + break; + case CS35L41_INTERRUPT: +- regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL, +- CS35L41_GPIO2_CTRL_MASK, 2 << CS35L41_GPIO2_CTRL_SHIFT); + break; + default: + dev_err(cs35l41->dev, "Invalid GPIO2 function %d\n", hw_cfg->gpio2.func); +@@ -263,6 +260,8 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41) + } + } + ++ cs35l41_gpio_config(cs35l41->regmap, hw_cfg); ++ + if (internal_boost) { + cs35l41->reg_seq = &cs35l41_hda_reg_seq_int_bst; + ret = cs35l41_boost_config(cs35l41->dev, cs35l41->regmap, +diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c +index 905c648a8f49..eeeaeaa0db82 100644 +--- a/sound/soc/codecs/cs35l41-lib.c ++++ b/sound/soc/codecs/cs35l41-lib.c +@@ -1040,6 +1040,47 @@ int cs35l41_boost_config(struct device *dev, struct regmap *regmap, int boost_in + } + EXPORT_SYMBOL_GPL(cs35l41_boost_config); + ++int cs35l41_gpio_config(struct regmap *regmap, struct cs35l41_hw_cfg *hw_cfg) ++{ ++ struct cs35l41_gpio_cfg *gpio1 = &hw_cfg->gpio1; ++ struct cs35l41_gpio_cfg *gpio2 = &hw_cfg->gpio2; ++ int irq_pol = IRQF_TRIGGER_NONE; ++ ++ regmap_update_bits(regmap, CS35L41_GPIO1_CTRL1, ++ CS35L41_GPIO_POL_MASK | CS35L41_GPIO_DIR_MASK, ++ gpio1->pol_inv << CS35L41_GPIO_POL_SHIFT | ++ !gpio1->out_en << CS35L41_GPIO_DIR_SHIFT); ++ ++ regmap_update_bits(regmap, CS35L41_GPIO2_CTRL1, ++ CS35L41_GPIO_POL_MASK | CS35L41_GPIO_DIR_MASK, ++ gpio2->pol_inv << CS35L41_GPIO_POL_SHIFT | ++ !gpio2->out_en << CS35L41_GPIO_DIR_SHIFT); ++ ++ if (gpio1->valid) ++ regmap_update_bits(regmap, CS35L41_GPIO_PAD_CONTROL, CS35L41_GPIO1_CTRL_MASK, ++ gpio1->func << CS35L41_GPIO1_CTRL_SHIFT); ++ ++ if (gpio2->valid) { ++ regmap_update_bits(regmap, CS35L41_GPIO_PAD_CONTROL, CS35L41_GPIO2_CTRL_MASK, ++ gpio2->func << CS35L41_GPIO2_CTRL_SHIFT); ++ ++ switch (gpio2->func) { ++ case CS35L41_GPIO2_INT_PUSH_PULL_LOW: ++ case CS35L41_GPIO2_INT_OPEN_DRAIN: ++ irq_pol = IRQF_TRIGGER_LOW; ++ break; ++ case CS35L41_GPIO2_INT_PUSH_PULL_HIGH: ++ irq_pol = IRQF_TRIGGER_HIGH; ++ break; ++ default: ++ break; ++ } ++ } ++ ++ return irq_pol; ++} ++EXPORT_SYMBOL_GPL(cs35l41_gpio_config); ++ + MODULE_DESCRIPTION("CS35L41 library"); + MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, "); + MODULE_AUTHOR("Lucas Tanure, Cirrus Logic Inc, "); +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index 90dec80707ea..d25689fe0c60 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -1017,48 +1017,6 @@ static int cs35l41_set_pdata(struct cs35l41_private *cs35l41) + return 0; + } + +-static int cs35l41_gpio_config(struct cs35l41_private *cs35l41) +-{ +- struct cs35l41_gpio_cfg *gpio1 = &cs35l41->hw_cfg.gpio1; +- struct cs35l41_gpio_cfg *gpio2 = &cs35l41->hw_cfg.gpio2; +- int irq_pol = IRQF_TRIGGER_NONE; +- +- regmap_update_bits(cs35l41->regmap, CS35L41_GPIO1_CTRL1, +- CS35L41_GPIO_POL_MASK | CS35L41_GPIO_DIR_MASK, +- gpio1->pol_inv << CS35L41_GPIO_POL_SHIFT | +- !gpio1->out_en << CS35L41_GPIO_DIR_SHIFT); +- +- regmap_update_bits(cs35l41->regmap, CS35L41_GPIO2_CTRL1, +- CS35L41_GPIO_POL_MASK | CS35L41_GPIO_DIR_MASK, +- gpio2->pol_inv << CS35L41_GPIO_POL_SHIFT | +- !gpio2->out_en << CS35L41_GPIO_DIR_SHIFT); +- +- if (gpio1->valid) +- regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL, +- CS35L41_GPIO1_CTRL_MASK, +- gpio1->func << CS35L41_GPIO1_CTRL_SHIFT); +- +- if (gpio2->valid) { +- regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL, +- CS35L41_GPIO2_CTRL_MASK, +- gpio2->func << CS35L41_GPIO2_CTRL_SHIFT); +- +- switch (gpio2->func) { +- case CS35L41_GPIO2_INT_PUSH_PULL_LOW: +- case CS35L41_GPIO2_INT_OPEN_DRAIN: +- irq_pol = IRQF_TRIGGER_LOW; +- break; +- case CS35L41_GPIO2_INT_PUSH_PULL_HIGH: +- irq_pol = IRQF_TRIGGER_HIGH; +- break; +- default: +- break; +- } +- } +- +- return irq_pol; +-} +- + static int cs35l41_component_probe(struct snd_soc_component *component) + { + struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component); +@@ -1366,7 +1324,7 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg * + + cs35l41_test_key_lock(cs35l41->dev, cs35l41->regmap); + +- irq_pol = cs35l41_gpio_config(cs35l41); ++ irq_pol = cs35l41_gpio_config(cs35l41->regmap, &cs35l41->hw_cfg); + + /* Set interrupt masks for critical errors */ + regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, +-- +2.35.3 + diff --git a/patches.suse/ALSA-cs35l41-Unify-hardware-configuration.patch b/patches.suse/ALSA-cs35l41-Unify-hardware-configuration.patch new file mode 100644 index 0000000..ab33284 --- /dev/null +++ b/patches.suse/ALSA-cs35l41-Unify-hardware-configuration.patch @@ -0,0 +1,558 @@ +From f7f207375d4e6eb9acc78d312eed8806b37d101a Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Wed, 13 Apr 2022 09:37:13 +0100 +Subject: [PATCH] ALSA: cs35l41: Unify hardware configuration +Git-commit: f7f207375d4e6eb9acc78d312eed8806b37d101a +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +Both ASoC and HDA require to configure the GPIOs and Boost, so +create a single shared struct for hardware configuration. + +Signed-off-by: Lucas Tanure +Acked-by: Charles Keepax +Link: https://lore.kernel.org/r/20220413083728.10730-2-tanureal@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + include/sound/cs35l41.h | 41 +++++++++++++----- + sound/pci/hda/cs35l41_hda.c | 69 ++++++++++++------------------ + sound/pci/hda/cs35l41_hda.h | 13 ----- + sound/soc/codecs/cs35l41-i2c.c | 4 - + sound/soc/codecs/cs35l41-spi.c | 4 - + sound/soc/codecs/cs35l41.c | 93 ++++++++++++++++++----------------------- + sound/soc/codecs/cs35l41.h | 5 -- + 7 files changed, 108 insertions(+), 121 deletions(-) + +--- a/include/sound/cs35l41.h ++++ b/include/sound/cs35l41.h +@@ -701,9 +701,6 @@ + #define CS35L41_GPIO1_CTRL_SHIFT 16 + #define CS35L41_GPIO2_CTRL_MASK 0x07000000 + #define CS35L41_GPIO2_CTRL_SHIFT 24 +-#define CS35L41_GPIO_CTRL_OPEN_INT 2 +-#define CS35L41_GPIO_CTRL_ACTV_LO 4 +-#define CS35L41_GPIO_CTRL_ACTV_HI 5 + #define CS35L41_GPIO_POL_MASK 0x1000 + #define CS35L41_GPIO_POL_SHIFT 12 + +@@ -735,19 +732,43 @@ enum cs35l41_clk_ids { + CS35L41_CLKID_MCLK = 4, + }; + +-struct cs35l41_irq_cfg { +- bool irq_pol_inv; +- bool irq_out_en; +- int irq_src_sel; ++enum cs35l41_gpio1_func { ++ CS35L41_GPIO1_HIZ, ++ CS35L41_GPIO1_GPIO, ++ CS35L41_GPIO1_MDSYNC, ++ CS35L41_GPIO1_MCLK, ++ CS35L41_GPIO1_PDM_CLK, ++ CS35L41_GPIO1_PDM_DATA, + }; + +-struct cs35l41_platform_data { ++enum cs35l41_gpio2_func { ++ CS35L41_GPIO2_HIZ, ++ CS35L41_GPIO2_GPIO, ++ CS35L41_GPIO2_INT_OPEN_DRAIN, ++ CS35L41_GPIO2_MCLK, ++ CS35L41_GPIO2_INT_PUSH_PULL_LOW, ++ CS35L41_GPIO2_INT_PUSH_PULL_HIGH, ++ CS35L41_GPIO2_PDM_CLK, ++ CS35L41_GPIO2_PDM_DATA, ++}; ++ ++struct cs35l41_gpio_cfg { ++ bool pol_inv; ++ bool out_en; ++ unsigned int func; ++}; ++ ++struct cs35l41_hw_cfg { + int bst_ind; + int bst_ipk; + int bst_cap; + int dout_hiz; +- struct cs35l41_irq_cfg irq_config1; +- struct cs35l41_irq_cfg irq_config2; ++ struct cs35l41_gpio_cfg gpio1; ++ struct cs35l41_gpio_cfg gpio2; ++ unsigned int spk_pos; ++ ++ /* Don't put the AMP in reset if VSPK can not be turned off */ ++ bool vspk_always_on; + }; + + struct cs35l41_otp_packed_element_t { +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -213,13 +213,13 @@ static const struct component_ops cs35l4 + .unbind = cs35l41_hda_unbind, + }; + +-static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41, +- const struct cs35l41_hda_hw_config *hw_cfg) ++static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41) + { ++ struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg; + bool internal_boost = false; + int ret; + +- if (!hw_cfg) { ++ if (hw_cfg->vspk_always_on) { + cs35l41->reg_seq = &cs35l41_hda_reg_seq_no_bst; + return 0; + } +@@ -227,7 +227,7 @@ static int cs35l41_hda_apply_properties( + if (hw_cfg->bst_ind || hw_cfg->bst_cap || hw_cfg->bst_ipk) + internal_boost = true; + +- switch (hw_cfg->gpio1_func) { ++ switch (hw_cfg->gpio1.func) { + case CS35L41_NOT_USED: + break; + case CS35l41_VSPK_SWITCH: +@@ -239,11 +239,11 @@ static int cs35l41_hda_apply_properties( + CS35L41_GPIO1_CTRL_MASK, 2 << CS35L41_GPIO1_CTRL_SHIFT); + break; + default: +- dev_err(cs35l41->dev, "Invalid function %d for GPIO1\n", hw_cfg->gpio1_func); ++ dev_err(cs35l41->dev, "Invalid function %d for GPIO1\n", hw_cfg->gpio1.func); + return -EINVAL; + } + +- switch (hw_cfg->gpio2_func) { ++ switch (hw_cfg->gpio2.func) { + case CS35L41_NOT_USED: + break; + case CS35L41_INTERRUPT: +@@ -251,7 +251,7 @@ static int cs35l41_hda_apply_properties( + CS35L41_GPIO2_CTRL_MASK, 2 << CS35L41_GPIO2_CTRL_SHIFT); + break; + default: +- dev_err(cs35l41->dev, "Invalid function %d for GPIO2\n", hw_cfg->gpio2_func); ++ dev_err(cs35l41->dev, "Invalid function %d for GPIO2\n", hw_cfg->gpio2.func); + return -EINVAL; + } + +@@ -267,13 +267,12 @@ static int cs35l41_hda_apply_properties( + cs35l41->reg_seq = &cs35l41_hda_reg_seq_ext_bst; + } + +- return cs35l41_hda_channel_map(cs35l41->dev, 0, NULL, 1, (unsigned int *)&hw_cfg->spk_pos); ++ return cs35l41_hda_channel_map(cs35l41->dev, 0, NULL, 1, &hw_cfg->spk_pos); + } + +-static struct cs35l41_hda_hw_config *cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, +- const char *hid, int id) ++static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, int id) + { +- struct cs35l41_hda_hw_config *hw_cfg; ++ struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg; + u32 values[HDA_MAX_COMPONENTS]; + struct acpi_device *adev; + struct device *physdev; +@@ -284,7 +283,7 @@ static struct cs35l41_hda_hw_config *cs3 + adev = acpi_dev_get_first_match_dev(hid, NULL, -1); + if (!adev) { + dev_err(cs35l41->dev, "Failed to find an ACPI device for %s\n", hid); +- return ERR_PTR(-ENODEV); ++ return -ENODEV; + } + + physdev = get_device(acpi_get_first_physical_node(adev)); +@@ -324,29 +323,23 @@ static struct cs35l41_hda_hw_config *cs3 + cs35l41->reset_gpio = fwnode_gpiod_get_index(&adev->fwnode, "reset", cs35l41->index, + GPIOD_OUT_LOW, "cs35l41-reset"); + +- hw_cfg = kzalloc(sizeof(*hw_cfg), GFP_KERNEL); +- if (!hw_cfg) { +- ret = -ENOMEM; +- goto err; +- } +- + property = "cirrus,speaker-position"; + ret = device_property_read_u32_array(physdev, property, values, nval); + if (ret) +- goto err_free; ++ goto err; + hw_cfg->spk_pos = values[cs35l41->index]; + + property = "cirrus,gpio1-func"; + ret = device_property_read_u32_array(physdev, property, values, nval); + if (ret) +- goto err_free; +- hw_cfg->gpio1_func = values[cs35l41->index]; ++ goto err; ++ hw_cfg->gpio1.func = values[cs35l41->index]; + + property = "cirrus,gpio2-func"; + ret = device_property_read_u32_array(physdev, property, values, nval); + if (ret) +- goto err_free; +- hw_cfg->gpio2_func = values[cs35l41->index]; ++ goto err; ++ hw_cfg->gpio2.func = values[cs35l41->index]; + + property = "cirrus,boost-peak-milliamp"; + ret = device_property_read_u32_array(physdev, property, values, nval); +@@ -365,15 +358,13 @@ static struct cs35l41_hda_hw_config *cs3 + + put_device(physdev); + +- return hw_cfg; ++ return 0; + +-err_free: +- kfree(hw_cfg); + err: + put_device(physdev); + dev_err(cs35l41->dev, "Failed property %s: %d\n", property, ret); + +- return ERR_PTR(ret); ++ return ret; + + no_acpi_dsd: + /* +@@ -384,22 +375,21 @@ no_acpi_dsd: + * fwnode. + */ + if (strncmp(hid, "CLSA0100", 8) != 0) +- return ERR_PTR(-EINVAL); ++ return -EINVAL; + + /* check I2C address to assign the index */ + cs35l41->index = id == 0x40 ? 0 : 1; + cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 0, GPIOD_OUT_HIGH); +- cs35l41->vspk_always_on = true; ++ cs35l41->hw_cfg.vspk_always_on = true; + put_device(physdev); + +- return NULL; ++ return 0; + } + + int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq, + struct regmap *regmap) + { + unsigned int int_sts, regid, reg_revid, mtl_revid, chipid, int_status; +- struct cs35l41_hda_hw_config *acpi_hw_cfg; + struct cs35l41_hda *cs35l41; + int ret; + +@@ -415,9 +405,11 @@ int cs35l41_hda_probe(struct device *dev + cs35l41->regmap = regmap; + dev_set_drvdata(dev, cs35l41); + +- acpi_hw_cfg = cs35l41_hda_read_acpi(cs35l41, device_name, id); +- if (IS_ERR(acpi_hw_cfg)) +- return PTR_ERR(acpi_hw_cfg); ++ ret = cs35l41_hda_read_acpi(cs35l41, device_name, id); ++ if (ret) { ++ dev_err_probe(cs35l41->dev, ret, "Platform not supported %d\n", ret); ++ return ret; ++ } + + if (IS_ERR(cs35l41->reset_gpio)) { + ret = PTR_ERR(cs35l41->reset_gpio); +@@ -490,11 +482,9 @@ int cs35l41_hda_probe(struct device *dev + if (ret) + goto err; + +- ret = cs35l41_hda_apply_properties(cs35l41, acpi_hw_cfg); ++ ret = cs35l41_hda_apply_properties(cs35l41); + if (ret) + goto err; +- kfree(acpi_hw_cfg); +- acpi_hw_cfg = NULL; + + if (cs35l41->reg_seq->probe) { + ret = regmap_multi_reg_write(cs35l41->regmap, cs35l41->reg_seq->probe, +@@ -516,8 +506,7 @@ int cs35l41_hda_probe(struct device *dev + return 0; + + err: +- kfree(acpi_hw_cfg); +- if (!cs35l41->vspk_always_on) ++ if (!cs35l41->hw_cfg.vspk_always_on) + gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); + gpiod_put(cs35l41->reset_gpio); + +@@ -531,7 +520,7 @@ void cs35l41_hda_remove(struct device *d + + component_del(cs35l41->dev, &cs35l41_hda_comp_ops); + +- if (!cs35l41->vspk_always_on) ++ if (!cs35l41->hw_cfg.vspk_always_on) + gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); + gpiod_put(cs35l41->reset_gpio); + } +--- a/sound/pci/hda/cs35l41_hda.h ++++ b/sound/pci/hda/cs35l41_hda.h +@@ -40,26 +40,15 @@ struct cs35l41_hda_reg_sequence { + unsigned int num_close; + }; + +-struct cs35l41_hda_hw_config { +- unsigned int spk_pos; +- unsigned int gpio1_func; +- unsigned int gpio2_func; +- int bst_ind; +- int bst_ipk; +- int bst_cap; +-}; +- + struct cs35l41_hda { + struct device *dev; + struct regmap *regmap; + struct gpio_desc *reset_gpio; + const struct cs35l41_hda_reg_sequence *reg_seq; ++ struct cs35l41_hw_cfg hw_cfg; + + int irq; + int index; +- +- /* Don't put the AMP in reset of VSPK can not be turned off */ +- bool vspk_always_on; + }; + + int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq, +--- a/sound/soc/codecs/cs35l41-i2c.c ++++ b/sound/soc/codecs/cs35l41-i2c.c +@@ -34,7 +34,7 @@ static int cs35l41_i2c_probe(struct i2c_ + { + struct cs35l41_private *cs35l41; + struct device *dev = &client->dev; +- struct cs35l41_platform_data *pdata = dev_get_platdata(dev); ++ struct cs35l41_hw_cfg *hw_cfg = dev_get_platdata(dev); + const struct regmap_config *regmap_config = &cs35l41_regmap_i2c; + int ret; + +@@ -54,7 +54,7 @@ static int cs35l41_i2c_probe(struct i2c_ + return ret; + } + +- return cs35l41_probe(cs35l41, pdata); ++ return cs35l41_probe(cs35l41, hw_cfg); + } + + static int cs35l41_i2c_remove(struct i2c_client *client) +--- a/sound/soc/codecs/cs35l41-spi.c ++++ b/sound/soc/codecs/cs35l41-spi.c +@@ -30,7 +30,7 @@ MODULE_DEVICE_TABLE(spi, cs35l41_id_spi) + static int cs35l41_spi_probe(struct spi_device *spi) + { + const struct regmap_config *regmap_config = &cs35l41_regmap_spi; +- struct cs35l41_platform_data *pdata = dev_get_platdata(&spi->dev); ++ struct cs35l41_hw_cfg *hw_cfg = dev_get_platdata(&spi->dev); + struct cs35l41_private *cs35l41; + int ret; + +@@ -52,7 +52,7 @@ static int cs35l41_spi_probe(struct spi_ + cs35l41->dev = &spi->dev; + cs35l41->irq = spi->irq; + +- return cs35l41_probe(cs35l41, pdata); ++ return cs35l41_probe(cs35l41, hw_cfg); + } + + static int cs35l41_spi_remove(struct spi_device *spi) +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -999,10 +999,10 @@ static int cs35l41_set_pdata(struct cs35 + + /* Set Platform Data */ + /* Required */ +- if (cs35l41->pdata.bst_ipk && +- cs35l41->pdata.bst_ind && cs35l41->pdata.bst_cap) { +- ret = cs35l41_boost_config(cs35l41->dev, cs35l41->regmap, cs35l41->pdata.bst_ind, +- cs35l41->pdata.bst_cap, cs35l41->pdata.bst_ipk); ++ if (cs35l41->hw_cfg.bst_ipk && ++ cs35l41->hw_cfg.bst_ind && cs35l41->hw_cfg.bst_cap) { ++ ret = cs35l41_boost_config(cs35l41->dev, cs35l41->regmap, cs35l41->hw_cfg.bst_ind, ++ cs35l41->hw_cfg.bst_cap, cs35l41->hw_cfg.bst_ipk); + if (ret) { + dev_err(cs35l41->dev, "Error in Boost DT config: %d\n", ret); + return ret; +@@ -1013,43 +1013,39 @@ static int cs35l41_set_pdata(struct cs35 + } + + /* Optional */ +- if (cs35l41->pdata.dout_hiz <= CS35L41_ASP_DOUT_HIZ_MASK && +- cs35l41->pdata.dout_hiz >= 0) +- regmap_update_bits(cs35l41->regmap, CS35L41_SP_HIZ_CTRL, +- CS35L41_ASP_DOUT_HIZ_MASK, +- cs35l41->pdata.dout_hiz); ++ if (cs35l41->hw_cfg.dout_hiz <= CS35L41_ASP_DOUT_HIZ_MASK && ++ cs35l41->hw_cfg.dout_hiz >= 0) ++ regmap_update_bits(cs35l41->regmap, CS35L41_SP_HIZ_CTRL, CS35L41_ASP_DOUT_HIZ_MASK, ++ cs35l41->hw_cfg.dout_hiz); + + return 0; + } + +-static int cs35l41_irq_gpio_config(struct cs35l41_private *cs35l41) ++static int cs35l41_gpio_config(struct cs35l41_private *cs35l41) + { +- struct cs35l41_irq_cfg *irq_gpio_cfg1 = &cs35l41->pdata.irq_config1; +- struct cs35l41_irq_cfg *irq_gpio_cfg2 = &cs35l41->pdata.irq_config2; ++ struct cs35l41_gpio_cfg *gpio1 = &cs35l41->hw_cfg.gpio1; ++ struct cs35l41_gpio_cfg *gpio2 = &cs35l41->hw_cfg.gpio2; + int irq_pol = IRQF_TRIGGER_NONE; + + regmap_update_bits(cs35l41->regmap, CS35L41_GPIO1_CTRL1, + CS35L41_GPIO_POL_MASK | CS35L41_GPIO_DIR_MASK, +- irq_gpio_cfg1->irq_pol_inv << CS35L41_GPIO_POL_SHIFT | +- !irq_gpio_cfg1->irq_out_en << CS35L41_GPIO_DIR_SHIFT); ++ gpio1->pol_inv << CS35L41_GPIO_POL_SHIFT | ++ !gpio1->out_en << CS35L41_GPIO_DIR_SHIFT); + + regmap_update_bits(cs35l41->regmap, CS35L41_GPIO2_CTRL1, + CS35L41_GPIO_POL_MASK | CS35L41_GPIO_DIR_MASK, +- irq_gpio_cfg2->irq_pol_inv << CS35L41_GPIO_POL_SHIFT | +- !irq_gpio_cfg2->irq_out_en << CS35L41_GPIO_DIR_SHIFT); ++ gpio2->pol_inv << CS35L41_GPIO_POL_SHIFT | ++ !gpio2->out_en << CS35L41_GPIO_DIR_SHIFT); + + regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL, + CS35L41_GPIO1_CTRL_MASK | CS35L41_GPIO2_CTRL_MASK, +- irq_gpio_cfg1->irq_src_sel << CS35L41_GPIO1_CTRL_SHIFT | +- irq_gpio_cfg2->irq_src_sel << CS35L41_GPIO2_CTRL_SHIFT); ++ gpio1->func << CS35L41_GPIO1_CTRL_SHIFT | ++ gpio2->func << CS35L41_GPIO2_CTRL_SHIFT); + +- if ((irq_gpio_cfg2->irq_src_sel == +- (CS35L41_GPIO_CTRL_ACTV_LO | CS35L41_VALID_PDATA)) || +- (irq_gpio_cfg2->irq_src_sel == +- (CS35L41_GPIO_CTRL_OPEN_INT | CS35L41_VALID_PDATA))) ++ if ((gpio2->func == (CS35L41_GPIO2_INT_PUSH_PULL_LOW | CS35L41_VALID_PDATA)) || ++ (gpio2->func == (CS35L41_GPIO2_INT_OPEN_DRAIN | CS35L41_VALID_PDATA))) + irq_pol = IRQF_TRIGGER_LOW; +- else if (irq_gpio_cfg2->irq_src_sel == +- (CS35L41_GPIO_CTRL_ACTV_HI | CS35L41_VALID_PDATA)) ++ else if (gpio2->func == (CS35L41_GPIO2_INT_PUSH_PULL_HIGH | CS35L41_VALID_PDATA)) + irq_pol = IRQF_TRIGGER_HIGH; + + return irq_pol; +@@ -1115,50 +1111,44 @@ static const struct snd_soc_component_dr + .set_sysclk = cs35l41_component_set_sysclk, + }; + +-static int cs35l41_handle_pdata(struct device *dev, struct cs35l41_platform_data *pdata) ++static int cs35l41_handle_pdata(struct device *dev, struct cs35l41_hw_cfg *hw_cfg) + { +- struct cs35l41_irq_cfg *irq_gpio1_config = &pdata->irq_config1; +- struct cs35l41_irq_cfg *irq_gpio2_config = &pdata->irq_config2; ++ struct cs35l41_gpio_cfg *gpio1 = &hw_cfg->gpio1; ++ struct cs35l41_gpio_cfg *gpio2 = &hw_cfg->gpio2; + unsigned int val; + int ret; + + ret = device_property_read_u32(dev, "cirrus,boost-peak-milliamp", &val); + if (ret >= 0) +- pdata->bst_ipk = val; ++ hw_cfg->bst_ipk = val; + + ret = device_property_read_u32(dev, "cirrus,boost-ind-nanohenry", &val); + if (ret >= 0) +- pdata->bst_ind = val; ++ hw_cfg->bst_ind = val; + + ret = device_property_read_u32(dev, "cirrus,boost-cap-microfarad", &val); + if (ret >= 0) +- pdata->bst_cap = val; ++ hw_cfg->bst_cap = val; + + ret = device_property_read_u32(dev, "cirrus,asp-sdout-hiz", &val); + if (ret >= 0) +- pdata->dout_hiz = val; ++ hw_cfg->dout_hiz = val; + else +- pdata->dout_hiz = -1; ++ hw_cfg->dout_hiz = -1; + + /* GPIO1 Pin Config */ +- irq_gpio1_config->irq_pol_inv = device_property_read_bool(dev, +- "cirrus,gpio1-polarity-invert"); +- irq_gpio1_config->irq_out_en = device_property_read_bool(dev, +- "cirrus,gpio1-output-enable"); +- ret = device_property_read_u32(dev, "cirrus,gpio1-src-select", +- &val); ++ gpio1->pol_inv = device_property_read_bool(dev, "cirrus,gpio1-polarity-invert"); ++ gpio1->out_en = device_property_read_bool(dev, "cirrus,gpio1-output-enable"); ++ ret = device_property_read_u32(dev, "cirrus,gpio1-src-select", &val); + if (ret >= 0) +- irq_gpio1_config->irq_src_sel = val | CS35L41_VALID_PDATA; ++ gpio1->func = val | CS35L41_VALID_PDATA; + + /* GPIO2 Pin Config */ +- irq_gpio2_config->irq_pol_inv = device_property_read_bool(dev, +- "cirrus,gpio2-polarity-invert"); +- irq_gpio2_config->irq_out_en = device_property_read_bool(dev, +- "cirrus,gpio2-output-enable"); +- ret = device_property_read_u32(dev, "cirrus,gpio2-src-select", +- &val); ++ gpio2->pol_inv = device_property_read_bool(dev, "cirrus,gpio2-polarity-invert"); ++ gpio2->out_en = device_property_read_bool(dev, "cirrus,gpio2-output-enable"); ++ ret = device_property_read_u32(dev, "cirrus,gpio2-src-select", &val); + if (ret >= 0) +- irq_gpio2_config->irq_src_sel = val | CS35L41_VALID_PDATA; ++ gpio2->func = val | CS35L41_VALID_PDATA; + + return 0; + } +@@ -1248,17 +1238,16 @@ err_dsp: + return ret; + } + +-int cs35l41_probe(struct cs35l41_private *cs35l41, +- struct cs35l41_platform_data *pdata) ++int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg *hw_cfg) + { + u32 regid, reg_revid, i, mtl_revid, int_status, chipid_match; + int irq_pol = 0; + int ret; + +- if (pdata) { +- cs35l41->pdata = *pdata; ++ if (hw_cfg) { ++ cs35l41->hw_cfg = *hw_cfg; + } else { +- ret = cs35l41_handle_pdata(cs35l41->dev, &cs35l41->pdata); ++ ret = cs35l41_handle_pdata(cs35l41->dev, &cs35l41->hw_cfg); + if (ret != 0) + return ret; + } +@@ -1357,7 +1346,7 @@ int cs35l41_probe(struct cs35l41_private + + cs35l41_test_key_lock(cs35l41->dev, cs35l41->regmap); + +- irq_pol = cs35l41_irq_gpio_config(cs35l41); ++ irq_pol = cs35l41_gpio_config(cs35l41); + + /* Set interrupt masks for critical errors */ + regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, +--- a/sound/soc/codecs/cs35l41.h ++++ b/sound/soc/codecs/cs35l41.h +@@ -44,7 +44,7 @@ enum cs35l41_cspl_mbox_cmd { + struct cs35l41_private { + struct wm_adsp dsp; /* needs to be first member */ + struct snd_soc_codec *codec; +- struct cs35l41_platform_data pdata; ++ struct cs35l41_hw_cfg hw_cfg; + struct device *dev; + struct regmap *regmap; + struct regulator_bulk_data supplies[CS35L41_NUM_SUPPLIES]; +@@ -53,8 +53,7 @@ struct cs35l41_private { + struct gpio_desc *reset_gpio; + }; + +-int cs35l41_probe(struct cs35l41_private *cs35l41, +- struct cs35l41_platform_data *pdata); ++int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg *hw_cfg); + void cs35l41_remove(struct cs35l41_private *cs35l41); + + #endif /*__CS35L41_H__*/ diff --git a/patches.suse/ALSA-dmaengine-increment-buffer-pointer-atomically.patch b/patches.suse/ALSA-dmaengine-increment-buffer-pointer-atomically.patch new file mode 100644 index 0000000..74fafad --- /dev/null +++ b/patches.suse/ALSA-dmaengine-increment-buffer-pointer-atomically.patch @@ -0,0 +1,48 @@ +From d1c442019594692c64a70a86ad88eb5b6db92216 Mon Sep 17 00:00:00 2001 +From: Andreas Pape +Date: Mon, 26 Sep 2022 18:58:13 +0200 +Subject: [PATCH] ALSA: dmaengine: increment buffer pointer atomically +Git-commit: d1c442019594692c64a70a86ad88eb5b6db92216 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Setting pointer and afterwards checking for wraparound leads +to the possibility of returning the inconsistent pointer position. + +This patch increments buffer pointer atomically to avoid this issue. + +Fixes: e7f73a1613567a ("ASoC: Add dmaengine PCM helper functions") +Signed-off-by: Andreas Pape +Signed-off-by: Eugeniu Rosca +Link: https://lore.kernel.org/r/1664211493-11789-1-git-send-email-erosca@de.adit-jv.com +Signed-off-by: Takashi Iwai + +--- + sound/core/pcm_dmaengine.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/sound/core/pcm_dmaengine.c b/sound/core/pcm_dmaengine.c +index 5b2ca028f5aa..494ec0c207fa 100644 +--- a/sound/core/pcm_dmaengine.c ++++ b/sound/core/pcm_dmaengine.c +@@ -133,12 +133,14 @@ EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_set_config_from_dai_data); + + static void dmaengine_pcm_dma_complete(void *arg) + { ++ unsigned int new_pos; + struct snd_pcm_substream *substream = arg; + struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); + +- prtd->pos += snd_pcm_lib_period_bytes(substream); +- if (prtd->pos >= snd_pcm_lib_buffer_bytes(substream)) +- prtd->pos = 0; ++ new_pos = prtd->pos + snd_pcm_lib_period_bytes(substream); ++ if (new_pos >= snd_pcm_lib_buffer_bytes(substream)) ++ new_pos = 0; ++ prtd->pos = new_pos; + + snd_pcm_period_elapsed(substream); + } +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-ALC287-Add-Lenovo-IdeaPad-Slim-9i-14ITL5-sp.patch b/patches.suse/ALSA-hda-ALC287-Add-Lenovo-IdeaPad-Slim-9i-14ITL5-sp.patch index 513bd1b..f0929c9 100644 --- a/patches.suse/ALSA-hda-ALC287-Add-Lenovo-IdeaPad-Slim-9i-14ITL5-sp.patch +++ b/patches.suse/ALSA-hda-ALC287-Add-Lenovo-IdeaPad-Slim-9i-14ITL5-sp.patch @@ -25,11 +25,11 @@ Signed-off-by: Takashi Iwai --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c -@@ -8969,6 +8969,7 @@ static const struct snd_pci_quirk alc269 +@@ -9075,6 +9075,7 @@ static const struct snd_pci_quirk alc269 SND_PCI_QUIRK(0x17aa, 0x3819, "Lenovo 13s Gen2 ITL", ALC287_FIXUP_13S_GEN2_SPEAKERS), SND_PCI_QUIRK(0x17aa, 0x3824, "Legion Y9000X 2020", ALC285_FIXUP_LEGION_Y9000X_SPEAKERS), SND_PCI_QUIRK(0x17aa, 0x3827, "Ideapad S740", ALC285_FIXUP_IDEAPAD_S740_COEF), + SND_PCI_QUIRK(0x17aa, 0x3834, "Lenovo IdeaPad Slim 9i 14ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS), SND_PCI_QUIRK(0x17aa, 0x3843, "Yoga 9i", ALC287_FIXUP_IDEAPAD_BASS_SPK_AMP), + SND_PCI_QUIRK(0x17aa, 0x3847, "Legion 7 16ACHG6", ALC287_FIXUP_LEGION_16ACHG6), SND_PCI_QUIRK(0x17aa, 0x384a, "Lenovo Yoga 7 15ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS), - SND_PCI_QUIRK(0x17aa, 0x3852, "Lenovo Yoga 7 14ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS), diff --git a/patches.suse/ALSA-hda-Fix-Nvidia-dp-infoframe.patch b/patches.suse/ALSA-hda-Fix-Nvidia-dp-infoframe.patch new file mode 100644 index 0000000..0e843e8 --- /dev/null +++ b/patches.suse/ALSA-hda-Fix-Nvidia-dp-infoframe.patch @@ -0,0 +1,99 @@ +From f89e409402e2aeb3bc3aa44d2b7a597959e4e6af Mon Sep 17 00:00:00 2001 +From: Mohan Kumar +Date: Tue, 13 Sep 2022 12:28:18 +0530 +Subject: [PATCH] ALSA: hda: Fix Nvidia dp infoframe +Git-commit: f89e409402e2aeb3bc3aa44d2b7a597959e4e6af +Patch-mainline: v6.0-rc7 +References: git-fixes + +Nvidia HDA HW expects infoframe data bytes order same for both +HDMI and DP i.e infoframe data starts from 5th bytes offset. As +dp infoframe structure has 4th byte as valid infoframe data, use +hdmi infoframe structure for nvidia dp infoframe to match HW behvaior. + +Signed-off-by: Mohan Kumar +Cc: +Link: https://lore.kernel.org/r/20220913065818.13015-1-mkumard@nvidia.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_hdmi.c | 23 +++++++++++++++++++---- + 1 file changed, 19 insertions(+), 4 deletions(-) + +diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c +index acaf6b790ee1..c9d9aa6351ec 100644 +--- a/sound/pci/hda/patch_hdmi.c ++++ b/sound/pci/hda/patch_hdmi.c +@@ -170,6 +170,8 @@ struct hdmi_spec { + bool dyn_pcm_no_legacy; + /* hdmi interrupt trigger control flag for Nvidia codec */ + bool hdmi_intr_trig_ctrl; ++ bool nv_dp_workaround; /* workaround DP audio infoframe for Nvidia */ ++ + bool intel_hsw_fixup; /* apply Intel platform-specific fixups */ + /* + * Non-generic VIA/NVIDIA specific +@@ -679,15 +681,24 @@ static void hdmi_pin_setup_infoframe(struct hda_codec *codec, + int ca, int active_channels, + int conn_type) + { ++ struct hdmi_spec *spec = codec->spec; + union audio_infoframe ai; + + memset(&ai, 0, sizeof(ai)); +- if (conn_type == 0) { /* HDMI */ ++ if ((conn_type == 0) || /* HDMI */ ++ /* Nvidia DisplayPort: Nvidia HW expects same layout as HDMI */ ++ (conn_type == 1 && spec->nv_dp_workaround)) { + struct hdmi_audio_infoframe *hdmi_ai = &ai.hdmi; + +- hdmi_ai->type = 0x84; +- hdmi_ai->ver = 0x01; +- hdmi_ai->len = 0x0a; ++ if (conn_type == 0) { /* HDMI */ ++ hdmi_ai->type = 0x84; ++ hdmi_ai->ver = 0x01; ++ hdmi_ai->len = 0x0a; ++ } else {/* Nvidia DP */ ++ hdmi_ai->type = 0x84; ++ hdmi_ai->ver = 0x1b; ++ hdmi_ai->len = 0x11 << 2; ++ } + hdmi_ai->CC02_CT47 = active_channels - 1; + hdmi_ai->CA = ca; + hdmi_checksum_audio_infoframe(hdmi_ai); +@@ -3617,6 +3628,7 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec) + spec->pcm_playback.rates = SUPPORTED_RATES; + spec->pcm_playback.maxbps = SUPPORTED_MAXBPS; + spec->pcm_playback.formats = SUPPORTED_FORMATS; ++ spec->nv_dp_workaround = true; + return 0; + } + +@@ -3756,6 +3768,7 @@ static int patch_nvhdmi(struct hda_codec *codec) + spec->chmap.ops.chmap_cea_alloc_validate_get_type = + nvhdmi_chmap_cea_alloc_validate_get_type; + spec->chmap.ops.chmap_validate = nvhdmi_chmap_validate; ++ spec->nv_dp_workaround = true; + + codec->link_down_at_suspend = 1; + +@@ -3779,6 +3792,7 @@ static int patch_nvhdmi_legacy(struct hda_codec *codec) + spec->chmap.ops.chmap_cea_alloc_validate_get_type = + nvhdmi_chmap_cea_alloc_validate_get_type; + spec->chmap.ops.chmap_validate = nvhdmi_chmap_validate; ++ spec->nv_dp_workaround = true; + + codec->link_down_at_suspend = 1; + +@@ -3993,6 +4007,7 @@ static int tegra_hdmi_init(struct hda_codec *codec) + spec->chmap.ops.chmap_cea_alloc_validate_get_type = + nvhdmi_chmap_cea_alloc_validate_get_type; + spec->chmap.ops.chmap_validate = nvhdmi_chmap_validate; ++ spec->nv_dp_workaround = true; + + return 0; + } +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-Fix-dependencies-of-CS35L41-on-SPI-I2C-buse.patch b/patches.suse/ALSA-hda-Fix-dependencies-of-CS35L41-on-SPI-I2C-buse.patch new file mode 100644 index 0000000..741a911 --- /dev/null +++ b/patches.suse/ALSA-hda-Fix-dependencies-of-CS35L41-on-SPI-I2C-buse.patch @@ -0,0 +1,44 @@ +From 2e88c6a805fc5311e27e0f6efe243842634052ab Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Sun, 9 Jan 2022 09:13:37 +0100 +Subject: [PATCH] ALSA: hda: Fix dependencies of CS35L41 on SPI/I2C buses +Git-commit: 2e88c6a805fc5311e27e0f6efe243842634052ab +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +CS35L41 SPI and I2C drivers depend on those buses, hence they have to +have dependencies in Kconfig; otherwise it may result in missing +symbols. + +Fixes: 7b2f3eb492da ("ALSA: hda: cs35l41: Add support for CS35L41 in HDA systems") +Reported-by: kernel test robot +Link: https://lore.kernel.org/r/20220109081337.30623-1-tiwai@suse.de +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/Kconfig | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig +index 68effb74866c..febe1c2b7d9a 100644 +--- a/sound/pci/hda/Kconfig ++++ b/sound/pci/hda/Kconfig +@@ -96,6 +96,7 @@ config SND_HDA_SCODEC_CS35L41 + + config SND_HDA_SCODEC_CS35L41_I2C + tristate "Build CS35L41 HD-audio side codec support for I2C Bus" ++ depends on I2C + depends on ACPI + depends on SND_SOC + select SND_HDA_GENERIC +@@ -110,6 +111,7 @@ comment "Set to Y if you want auto-loading the side codec driver" + + config SND_HDA_SCODEC_CS35L41_SPI + tristate "Build CS35L41 HD-audio codec support for SPI Bus" ++ depends on SPI_MASTER + depends on ACPI + depends on SND_SOC + select SND_HDA_GENERIC +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-Fix-dependency-on-ASoC-cs35l41-codec.patch b/patches.suse/ALSA-hda-Fix-dependency-on-ASoC-cs35l41-codec.patch new file mode 100644 index 0000000..90be324 --- /dev/null +++ b/patches.suse/ALSA-hda-Fix-dependency-on-ASoC-cs35l41-codec.patch @@ -0,0 +1,43 @@ +From 3e4518035a23e02ef818ea22570868a82956c6b0 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Fri, 7 Jan 2022 10:26:47 +0100 +Subject: [PATCH] ALSA: hda: Fix dependency on ASoC cs35l41 codec +Git-commit: 3e4518035a23e02ef818ea22570868a82956c6b0 +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +The recently added support for CS35L41 codec unconditionally selects +CONFIG_SND_SOC_CS35L41_LIB, but this can't work unless the top-level +CONFIG_SND_SOC is enabled. This patch adds the proper dependency. + +Fixes: 7b2f3eb492da ("ALSA: hda: cs35l41: Add support for CS35L41 in HDA systems") +Link: https://lore.kernel.org/r/20220107092647.20258-1-tiwai@suse.de +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/Kconfig | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig +index 84cefc006f29..68effb74866c 100644 +--- a/sound/pci/hda/Kconfig ++++ b/sound/pci/hda/Kconfig +@@ -97,6 +97,7 @@ config SND_HDA_SCODEC_CS35L41 + config SND_HDA_SCODEC_CS35L41_I2C + tristate "Build CS35L41 HD-audio side codec support for I2C Bus" + depends on ACPI ++ depends on SND_SOC + select SND_HDA_GENERIC + select SND_SOC_CS35L41_LIB + select SND_HDA_SCODEC_CS35L41 +@@ -110,6 +111,7 @@ comment "Set to Y if you want auto-loading the side codec driver" + config SND_HDA_SCODEC_CS35L41_SPI + tristate "Build CS35L41 HD-audio codec support for SPI Bus" + depends on ACPI ++ depends on SND_SOC + select SND_HDA_GENERIC + select SND_SOC_CS35L41_LIB + select SND_HDA_SCODEC_CS35L41 +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-Fix-hang-at-HD-audio-codec-unbinding-due-to.patch b/patches.suse/ALSA-hda-Fix-hang-at-HD-audio-codec-unbinding-due-to.patch new file mode 100644 index 0000000..a2f5962 --- /dev/null +++ b/patches.suse/ALSA-hda-Fix-hang-at-HD-audio-codec-unbinding-due-to.patch @@ -0,0 +1,64 @@ +From ead3d3c5b54f76da79c079e61bacb4279ec56965 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Sat, 10 Sep 2022 16:25:50 +0200 +Subject: [PATCH] ALSA: hda: Fix hang at HD-audio codec unbinding due to refcount saturation +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: ead3d3c5b54f76da79c079e61bacb4279ec56965 +Patch-mainline: v6.0-rc7 +References: git-fixes + +We fixed the potential deadlock at dynamic unbinding the HD-audio +codec at the commit 7206998f578d ("ALSA: hda: Fix potential deadlock +at codec unbinding"), but ironically, this caused another potential +deadlock. The current code uses refcount_dec() and waits for the +pending task with wait_event for dropping the refcount to 0. This +works fine when PCMs are assigned and actually waiting for the +refcount drop. + +Meanwhile, when there was no PCM assigned, the refcount_dec() call +itself was supposed to drop to zero -- alas, it doesn't in reality; +refcount_dec() complains, spews kernel warning and it saturates +instead of dropping to 0, due to the nature of refcount_dec() +implementation. This eventually blocks the wait_event() wakeup and +the code get stuck there. + +For avoiding the problem, we call refcount_dec_and_test() and skips +the sync-wait if it already reaches to zero. + +The patch does a slight code reshuffling to make sure to invoke other +disconnect calls before the sync-wait, too. + +Fixes: 7206998f578d ("ALSA: hda: Fix potential deadlock at codec unbinding") +Reported-by: Ville Syrjälä +Tested-by: Ville Syrjälä +Cc: +Link: https://lore.kernel.org/r/YxtflWQnslMHVlU7@intel.com +Link: https://lore.kernel.org/r/20220910142550.28494-1-tiwai@suse.de +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/hda_bind.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/sound/pci/hda/hda_bind.c b/sound/pci/hda/hda_bind.c +index cae9a975cbcc..1a868dd9dc4b 100644 +--- a/sound/pci/hda/hda_bind.c ++++ b/sound/pci/hda/hda_bind.c +@@ -157,10 +157,10 @@ static int hda_codec_driver_remove(struct device *dev) + return codec->bus->core.ext_ops->hdev_detach(&codec->core); + } + +- refcount_dec(&codec->pcm_ref); + snd_hda_codec_disconnect_pcms(codec); + snd_hda_jack_tbl_disconnect(codec); +- wait_event(codec->remove_sleep, !refcount_read(&codec->pcm_ref)); ++ if (!refcount_dec_and_test(&codec->pcm_ref)) ++ wait_event(codec->remove_sleep, !refcount_read(&codec->pcm_ref)); + snd_power_sync_ref(codec->bus->card); + + if (codec->patch_ops.free) +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-Fix-position-reporting-on-Poulsbo.patch b/patches.suse/ALSA-hda-Fix-position-reporting-on-Poulsbo.patch new file mode 100644 index 0000000..653e847 --- /dev/null +++ b/patches.suse/ALSA-hda-Fix-position-reporting-on-Poulsbo.patch @@ -0,0 +1,44 @@ +From 56e696c0f0c71b77fff921fc94b58a02f0445b2c Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Sat, 1 Oct 2022 16:21:24 +0200 +Subject: [PATCH] ALSA: hda: Fix position reporting on Poulsbo +Git-commit: 56e696c0f0c71b77fff921fc94b58a02f0445b2c +Patch-mainline: v6.1-rc1 +References: git-fixes + +Hans reported that his Sony VAIO VPX11S1E showed the broken sound +behavior at the start of the stream for a couple of seconds, and it +turned out that the position_fix=1 option fixes the issue. It implies +that the position reporting is inaccurate, and very likely hitting on +all Poulsbo devices. + +The patch applies the workaround for Poulsbo generically to switch to +LPIB mode instead of the default position buffer. + +Reported-and-tested-by: Hans de Goede +Cc: +Link: https://lore.kernel.org/r/3e8697e1-87c6-7a7b-d2e8-b21f1d2f181b@redhat.com +Link: https://lore.kernel.org/r/20221001142124.7241-1-tiwai@suse.de +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/hda_intel.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c +index 2a93bc64c2d8..6ff19dd0d10c 100644 +--- a/sound/pci/hda/hda_intel.c ++++ b/sound/pci/hda/hda_intel.c +@@ -2547,7 +2547,8 @@ static const struct pci_device_id azx_ids[] = { + .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM }, + /* Poulsbo */ + { PCI_DEVICE(0x8086, 0x811b), +- .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_BASE }, ++ .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_BASE | ++ AZX_DCAPS_POSFIX_LPIB }, + /* Oaktrail */ + { PCI_DEVICE(0x8086, 0x080a), + .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_BASE }, +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-add-Intel-5-Series-3400-PCI-DID.patch b/patches.suse/ALSA-hda-add-Intel-5-Series-3400-PCI-DID.patch new file mode 100644 index 0000000..6242c96 --- /dev/null +++ b/patches.suse/ALSA-hda-add-Intel-5-Series-3400-PCI-DID.patch @@ -0,0 +1,38 @@ +From 4d40ceef4745536289012670103c59264e0fb3ec Mon Sep 17 00:00:00 2001 +From: Kai Vehmanen +Date: Mon, 12 Sep 2022 21:37:16 +0300 +Subject: [PATCH] ALSA: hda: add Intel 5 Series / 3400 PCI DID +Git-commit: 4d40ceef4745536289012670103c59264e0fb3ec +Patch-mainline: v6.0-rc7 +References: git-fixes + +Handle 0x3b57 variant with same AZX_DCAPS_INTEL_PCH_NOPM +capabilities as 0x3b56. In practise this allow use of HDMI/DP +display audio via i915. + +Buglink: https://gitlab.freedesktop.org/drm/intel/-/issues/2751 +Signed-off-by: Kai Vehmanen +Cc: +Link: https://lore.kernel.org/r/20220912183716.2126312-1-kai.vehmanen@linux.intel.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/hda_intel.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c +index b20694fd69de..6f30c374f896 100644 +--- a/sound/pci/hda/hda_intel.c ++++ b/sound/pci/hda/hda_intel.c +@@ -2550,6 +2550,8 @@ static const struct pci_device_id azx_ids[] = { + /* 5 Series/3400 */ + { PCI_DEVICE(0x8086, 0x3b56), + .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM }, ++ { PCI_DEVICE(0x8086, 0x3b57), ++ .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM }, + /* Poulsbo */ + { PCI_DEVICE(0x8086, 0x811b), + .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_BASE }, +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Add-Amp-Name-based-on-channel-and-i.patch b/patches.suse/ALSA-hda-cs35l41-Add-Amp-Name-based-on-channel-and-i.patch new file mode 100644 index 0000000..2c0822e --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Add-Amp-Name-based-on-channel-and-i.patch @@ -0,0 +1,81 @@ +From 00f87ec74c3c09628889173b0f594cfc01e74157 Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Mon, 9 May 2022 22:46:46 +0100 +Subject: [PATCH] ALSA: hda: cs35l41: Add Amp Name based on channel and index +Git-commit: 00f87ec74c3c09628889173b0f594cfc01e74157 +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +This will be used to identify ALSA controls and firmware. +The Amp Name will be a channel identifier (L or R), and an +index, which identifies which amp for that channel. + +Signed-off-by: Stefan Binding +Signed-off-by: Vitaly Rodionov +Link: https://lore.kernel.org/r/20220509214703.4482-10-vitalyr@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 17 +++++++++++++++++ + sound/pci/hda/cs35l41_hda.h | 2 ++ + 2 files changed, 19 insertions(+) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index 2608bf4a6851..cce27a86267f 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -88,6 +88,17 @@ static int cs35l41_hda_channel_map(struct device *dev, unsigned int tx_num, unsi + unsigned int rx_num, unsigned int *rx_slot) + { + struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); ++ static const char * const channel_name[] = { "L", "R" }; ++ ++ if (!cs35l41->amp_name) { ++ if (*rx_slot >= ARRAY_SIZE(channel_name)) ++ return -EINVAL; ++ ++ cs35l41->amp_name = devm_kasprintf(cs35l41->dev, GFP_KERNEL, "%s%d", ++ channel_name[*rx_slot], cs35l41->channel_index); ++ if (!cs35l41->amp_name) ++ return -ENOMEM; ++ } + + return cs35l41_set_channels(cs35l41->dev, cs35l41->regmap, tx_num, tx_slot, rx_num, + rx_slot); +@@ -345,6 +356,11 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i + goto err; + hw_cfg->spk_pos = values[cs35l41->index]; + ++ cs35l41->channel_index = 0; ++ for (i = 0; i < cs35l41->index; i++) ++ if (values[i] == hw_cfg->spk_pos) ++ cs35l41->channel_index++; ++ + property = "cirrus,gpio1-func"; + ret = device_property_read_u32_array(physdev, property, values, nval); + if (ret) +@@ -410,6 +426,7 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i + /* check I2C address to assign the index */ + cs35l41->index = id == 0x40 ? 0 : 1; + cs35l41->hw_cfg.spk_pos = cs35l41->index; ++ cs35l41->channel_index = 0; + cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 0, GPIOD_OUT_HIGH); + cs35l41->hw_cfg.bst_type = CS35L41_EXT_BOOST_NO_VSPK_SWITCH; + hw_cfg->gpio2.func = CS35L41_GPIO2_INT_OPEN_DRAIN; +diff --git a/sound/pci/hda/cs35l41_hda.h b/sound/pci/hda/cs35l41_hda.h +index c486e4a5bb24..a52ffd1f7999 100644 +--- a/sound/pci/hda/cs35l41_hda.h ++++ b/sound/pci/hda/cs35l41_hda.h +@@ -35,7 +35,9 @@ struct cs35l41_hda { + + int irq; + int index; ++ int channel_index; + unsigned volatile long irq_errors; ++ const char *amp_name; + struct regmap_irq_chip_data *irq_data; + }; + +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Add-Boost-type-flag.patch b/patches.suse/ALSA-hda-cs35l41-Add-Boost-type-flag.patch new file mode 100644 index 0000000..5fcf3f3 --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Add-Boost-type-flag.patch @@ -0,0 +1,149 @@ +From b8388a1aba32bef84884c06c8270efa9eec91267 Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Wed, 13 Apr 2022 09:37:18 +0100 +Subject: [PATCH] ALSA: hda: cs35l41: Add Boost type flag +Git-commit: b8388a1aba32bef84884c06c8270efa9eec91267 +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +Replace vspk_always_on by a enum that better characterizes the boost +type, as there is 3 types of boost hardware. +And with the new boost type other parts of the driver can better handle +the configuration of the chip. + +Signed-off-by: Lucas Tanure +Link: https://lore.kernel.org/r/20220413083728.10730-7-tanureal@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + include/sound/cs35l41.h | 9 ++++++-- + sound/pci/hda/cs35l41_hda.c | 43 +++++++++++++++++++++---------------- + 2 files changed, 31 insertions(+), 21 deletions(-) + +diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h +index e312eb1f6e48..64d98cbd5c0e 100644 +--- a/include/sound/cs35l41.h ++++ b/include/sound/cs35l41.h +@@ -725,6 +725,12 @@ + #define CS35L41_SPI_MAX_FREQ 4000000 + #define CS35L41_REGSTRIDE 4 + ++enum cs35l41_boost_type { ++ CS35L41_INT_BOOST, ++ CS35L41_EXT_BOOST, ++ CS35L41_EXT_BOOST_NO_VSPK_SWITCH, ++}; ++ + enum cs35l41_clk_ids { + CS35L41_CLKID_SCLK = 0, + CS35L41_CLKID_LRCLK = 1, +@@ -768,8 +774,7 @@ struct cs35l41_hw_cfg { + struct cs35l41_gpio_cfg gpio2; + unsigned int spk_pos; + +- /* Don't put the AMP in reset if VSPK can not be turned off */ +- bool vspk_always_on; ++ enum cs35l41_boost_type bst_type; + }; + + struct cs35l41_otp_packed_element_t { +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index f853530eb385..0dac622805c4 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -210,20 +210,30 @@ static const struct component_ops cs35l41_hda_comp_ops = { + static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41) + { + struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg; +- bool internal_boost = false; + int ret; + + if (!cs35l41->hw_cfg.valid) + return -EINVAL; + +- if (hw_cfg->vspk_always_on) { ++ switch (hw_cfg->bst_type) { ++ case CS35L41_INT_BOOST: ++ cs35l41->reg_seq = &cs35l41_hda_reg_seq_int_bst; ++ ret = cs35l41_boost_config(cs35l41->dev, cs35l41->regmap, ++ hw_cfg->bst_ind, hw_cfg->bst_cap, hw_cfg->bst_ipk); ++ if (ret) ++ return ret; ++ break; ++ case CS35L41_EXT_BOOST: ++ cs35l41->reg_seq = &cs35l41_hda_reg_seq_ext_bst; ++ break; ++ case CS35L41_EXT_BOOST_NO_VSPK_SWITCH: + cs35l41->reg_seq = &cs35l41_hda_reg_seq_no_bst; +- return 0; ++ break; ++ default: ++ dev_err(cs35l41->dev, "Boost type %d not supported\n", hw_cfg->bst_type); ++ return -EINVAL; + } + +- if (hw_cfg->bst_ind > 0 || hw_cfg->bst_cap > 0 || hw_cfg->bst_ipk > 0) +- internal_boost = true; +- + if (hw_cfg->gpio1.valid) { + switch (hw_cfg->gpio1.func) { + case CS35L41_NOT_USED: +@@ -256,16 +266,6 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41) + + cs35l41_gpio_config(cs35l41->regmap, hw_cfg); + +- if (internal_boost) { +- cs35l41->reg_seq = &cs35l41_hda_reg_seq_int_bst; +- ret = cs35l41_boost_config(cs35l41->dev, cs35l41->regmap, +- hw_cfg->bst_ind, hw_cfg->bst_cap, hw_cfg->bst_ipk); +- if (ret) +- return ret; +- } else { +- cs35l41->reg_seq = &cs35l41_hda_reg_seq_ext_bst; +- } +- + return cs35l41_hda_channel_map(cs35l41->dev, 0, NULL, 1, &hw_cfg->spk_pos); + } + +@@ -363,6 +363,11 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i + else + hw_cfg->bst_cap = -1; + ++ if (hw_cfg->bst_ind > 0 || hw_cfg->bst_cap > 0 || hw_cfg->bst_ipk > 0) ++ hw_cfg->bst_type = CS35L41_INT_BOOST; ++ else ++ hw_cfg->bst_type = CS35L41_EXT_BOOST; ++ + hw_cfg->valid = true; + put_device(physdev); + +@@ -388,7 +393,7 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i + /* check I2C address to assign the index */ + cs35l41->index = id == 0x40 ? 0 : 1; + cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 0, GPIOD_OUT_HIGH); +- cs35l41->hw_cfg.vspk_always_on = true; ++ cs35l41->hw_cfg.bst_type = CS35L41_EXT_BOOST_NO_VSPK_SWITCH; + cs35l41->hw_cfg.valid = true; + put_device(physdev); + +@@ -515,7 +520,7 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i + return 0; + + err: +- if (!cs35l41->hw_cfg.vspk_always_on) ++ if (cs35l41->hw_cfg.bst_type != CS35L41_EXT_BOOST_NO_VSPK_SWITCH) + gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); + gpiod_put(cs35l41->reset_gpio); + +@@ -529,7 +534,7 @@ void cs35l41_hda_remove(struct device *dev) + + component_del(cs35l41->dev, &cs35l41_hda_comp_ops); + +- if (!cs35l41->hw_cfg.vspk_always_on) ++ if (cs35l41->hw_cfg.bst_type != CS35L41_EXT_BOOST_NO_VSPK_SWITCH) + gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); + gpiod_put(cs35l41->reset_gpio); + } +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Add-Support-for-Interrupts.patch b/patches.suse/ALSA-hda-cs35l41-Add-Support-for-Interrupts.patch new file mode 100644 index 0000000..55614a0 --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Add-Support-for-Interrupts.patch @@ -0,0 +1,318 @@ +From aa4a38af97e9f117450bcafd25ef02f9f1a37215 Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Mon, 9 May 2022 22:46:41 +0100 +Subject: [PATCH] ALSA: hda: cs35l41: Add Support for Interrupts +Git-commit: aa4a38af97e9f117450bcafd25ef02f9f1a37215 +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +The CS35L41 can produce interrupts on error. + +When the interrupts occur, the driver will report +the error, but errors will only be fixed after playback +finishes. + +Signed-off-by: Stefan Binding +Signed-off-by: Vitaly Rodionov +Link: https://lore.kernel.org/r/20220509214703.4482-5-vitalyr@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + include/sound/cs35l41.h | 54 +++++++++++++++ + sound/pci/hda/Kconfig | 2 + + sound/pci/hda/cs35l41_hda.c | 134 +++++++++++++++++++++++++++++++++++- + sound/pci/hda/cs35l41_hda.h | 2 + + 4 files changed, 191 insertions(+), 1 deletion(-) + +diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h +index dbe8d9c0191b..8e4b125c81c8 100644 +--- a/include/sound/cs35l41.h ++++ b/include/sound/cs35l41.h +@@ -691,6 +691,13 @@ + #define CS35L41_TEMP_WARN_ERR_RLS 0x20 + #define CS35L41_TEMP_ERR_RLS 0x40 + ++#define CS35L41_AMP_SHORT_ERR_RLS_SHIFT 1 ++#define CS35L41_BST_SHORT_ERR_RLS_SHIFT 2 ++#define CS35L41_BST_OVP_ERR_RLS_SHIFT 3 ++#define CS35L41_BST_UVP_ERR_RLS_SHIFT 4 ++#define CS35L41_TEMP_WARN_ERR_RLS_SHIFT 5 ++#define CS35L41_TEMP_ERR_RLS_SHIFT 6 ++ + #define CS35L41_INT1_MASK_DEFAULT 0x7FFCFE3F + #define CS35L41_INT1_UNMASK_PUP 0xFEFFFFFF + #define CS35L41_INT1_UNMASK_PDN 0xFF7FFFFF +@@ -794,6 +801,53 @@ struct cs35l41_otp_map_element_t { + u32 word_offset; + }; + ++/* ++ * IRQs ++ */ ++#define CS35L41_IRQ(_irq, _name, _hand) \ ++ { \ ++ .irq = CS35L41_ ## _irq ## _IRQ,\ ++ .name = _name, \ ++ .handler = _hand, \ ++ } ++ ++struct cs35l41_irq { ++ int irq; ++ const char *name; ++ irqreturn_t (*handler)(int irq, void *data); ++}; ++ ++#define CS35L41_REG_IRQ(_reg, _irq) \ ++ [CS35L41_ ## _irq ## _IRQ] = { \ ++ .reg_offset = (CS35L41_ ## _reg) - CS35L41_IRQ1_STATUS1,\ ++ .mask = CS35L41_ ## _irq ## _MASK \ ++ } ++ ++/* (0x0000E010) CS35L41_IRQ1_STATUS1 */ ++#define CS35L41_BST_OVP_ERR_SHIFT 6 ++#define CS35L41_BST_OVP_ERR_MASK BIT(CS35L41_BST_OVP_ERR_SHIFT) ++#define CS35L41_BST_DCM_UVP_ERR_SHIFT 7 ++#define CS35L41_BST_DCM_UVP_ERR_MASK BIT(CS35L41_BST_DCM_UVP_ERR_SHIFT) ++#define CS35L41_BST_SHORT_ERR_SHIFT 8 ++#define CS35L41_BST_SHORT_ERR_MASK BIT(CS35L41_BST_SHORT_ERR_SHIFT) ++#define CS35L41_TEMP_WARN_SHIFT 15 ++#define CS35L41_TEMP_WARN_MASK BIT(CS35L41_TEMP_WARN_SHIFT) ++#define CS35L41_TEMP_ERR_SHIFT 17 ++#define CS35L41_TEMP_ERR_MASK BIT(CS35L41_TEMP_ERR_SHIFT) ++#define CS35L41_AMP_SHORT_ERR_SHIFT 31 ++#define CS35L41_AMP_SHORT_ERR_MASK BIT(CS35L41_AMP_SHORT_ERR_SHIFT) ++ ++enum cs35l41_irq_list { ++ CS35L41_BST_OVP_ERR_IRQ, ++ CS35L41_BST_DCM_UVP_ERR_IRQ, ++ CS35L41_BST_SHORT_ERR_IRQ, ++ CS35L41_TEMP_WARN_IRQ, ++ CS35L41_TEMP_ERR_IRQ, ++ CS35L41_AMP_SHORT_ERR_IRQ, ++ ++ CS35L41_NUM_IRQ ++}; ++ + extern struct regmap_config cs35l41_regmap_i2c; + extern struct regmap_config cs35l41_regmap_spi; + +diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig +index 9f6c99c1d87b..79ade4787d95 100644 +--- a/sound/pci/hda/Kconfig ++++ b/sound/pci/hda/Kconfig +@@ -102,6 +102,7 @@ config SND_HDA_SCODEC_CS35L41_I2C + select SND_HDA_GENERIC + select SND_SOC_CS35L41_LIB + select SND_HDA_SCODEC_CS35L41 ++ select REGMAP_IRQ + help + Say Y or M here to include CS35L41 I2C HD-audio side codec support + in snd-hda-intel driver, such as ALC287. +@@ -117,6 +118,7 @@ config SND_HDA_SCODEC_CS35L41_SPI + select SND_HDA_GENERIC + select SND_SOC_CS35L41_LIB + select SND_HDA_SCODEC_CS35L41 ++ select REGMAP_IRQ + help + Say Y or M here to include CS35L41 SPI HD-audio side codec support + in snd-hda-intel driver, such as ALC287. +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index 96c3e541696d..bd52e0c2c772 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -32,6 +32,21 @@ static const struct reg_sequence cs35l41_hda_mute[] = { + { CS35L41_AMP_DIG_VOL_CTRL, 0x0000A678 }, // AMP_VOL_PCM Mute + }; + ++/* Protection release cycle to get the speaker out of Safe-Mode */ ++static void cs35l41_error_release(struct device *dev, struct regmap *regmap, unsigned int mask) ++{ ++ regmap_write(regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); ++ regmap_set_bits(regmap, CS35L41_PROTECT_REL_ERR_IGN, mask); ++ regmap_clear_bits(regmap, CS35L41_PROTECT_REL_ERR_IGN, mask); ++} ++ ++/* Clear all errors to release safe mode. Global Enable must be cleared first. */ ++static void cs35l41_irq_release(struct cs35l41_hda *cs35l41) ++{ ++ cs35l41_error_release(cs35l41->dev, cs35l41->regmap, cs35l41->irq_errors); ++ cs35l41->irq_errors = 0; ++} ++ + static void cs35l41_hda_playback_hook(struct device *dev, int action) + { + struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); +@@ -58,6 +73,7 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action) + CS35L41_AMP_EN_MASK, 0 << CS35L41_AMP_EN_SHIFT); + if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST) + regmap_write(reg, CS35L41_GPIO1_CTRL1, 0x00000001); ++ cs35l41_irq_release(cs35l41); + break; + default: + dev_warn(cs35l41->dev, "Playback action not supported: %d\n", action); +@@ -110,10 +126,101 @@ static const struct component_ops cs35l41_hda_comp_ops = { + .unbind = cs35l41_hda_unbind, + }; + ++static irqreturn_t cs35l41_bst_short_err(int irq, void *data) ++{ ++ struct cs35l41_hda *cs35l41 = data; ++ ++ dev_crit_ratelimited(cs35l41->dev, "LBST Error\n"); ++ set_bit(CS35L41_BST_SHORT_ERR_RLS_SHIFT, &cs35l41->irq_errors); ++ ++ return IRQ_HANDLED; ++} ++ ++static irqreturn_t cs35l41_bst_dcm_uvp_err(int irq, void *data) ++{ ++ struct cs35l41_hda *cs35l41 = data; ++ ++ dev_crit_ratelimited(cs35l41->dev, "DCM VBST Under Voltage Error\n"); ++ set_bit(CS35L41_BST_UVP_ERR_RLS_SHIFT, &cs35l41->irq_errors); ++ ++ return IRQ_HANDLED; ++} ++ ++static irqreturn_t cs35l41_bst_ovp_err(int irq, void *data) ++{ ++ struct cs35l41_hda *cs35l41 = data; ++ ++ dev_crit_ratelimited(cs35l41->dev, "VBST Over Voltage error\n"); ++ set_bit(CS35L41_BST_OVP_ERR_RLS_SHIFT, &cs35l41->irq_errors); ++ ++ return IRQ_HANDLED; ++} ++ ++static irqreturn_t cs35l41_temp_err(int irq, void *data) ++{ ++ struct cs35l41_hda *cs35l41 = data; ++ ++ dev_crit_ratelimited(cs35l41->dev, "Over temperature error\n"); ++ set_bit(CS35L41_TEMP_ERR_RLS_SHIFT, &cs35l41->irq_errors); ++ ++ return IRQ_HANDLED; ++} ++ ++static irqreturn_t cs35l41_temp_warn(int irq, void *data) ++{ ++ struct cs35l41_hda *cs35l41 = data; ++ ++ dev_crit_ratelimited(cs35l41->dev, "Over temperature warning\n"); ++ set_bit(CS35L41_TEMP_WARN_ERR_RLS_SHIFT, &cs35l41->irq_errors); ++ ++ return IRQ_HANDLED; ++} ++ ++static irqreturn_t cs35l41_amp_short(int irq, void *data) ++{ ++ struct cs35l41_hda *cs35l41 = data; ++ ++ dev_crit_ratelimited(cs35l41->dev, "Amp short error\n"); ++ set_bit(CS35L41_AMP_SHORT_ERR_RLS_SHIFT, &cs35l41->irq_errors); ++ ++ return IRQ_HANDLED; ++} ++ ++static const struct cs35l41_irq cs35l41_irqs[] = { ++ CS35L41_IRQ(BST_OVP_ERR, "Boost Overvoltage Error", cs35l41_bst_ovp_err), ++ CS35L41_IRQ(BST_DCM_UVP_ERR, "Boost Undervoltage Error", cs35l41_bst_dcm_uvp_err), ++ CS35L41_IRQ(BST_SHORT_ERR, "Boost Inductor Short Error", cs35l41_bst_short_err), ++ CS35L41_IRQ(TEMP_WARN, "Temperature Warning", cs35l41_temp_warn), ++ CS35L41_IRQ(TEMP_ERR, "Temperature Error", cs35l41_temp_err), ++ CS35L41_IRQ(AMP_SHORT_ERR, "Amp Short", cs35l41_amp_short), ++}; ++ ++static const struct regmap_irq cs35l41_reg_irqs[] = { ++ CS35L41_REG_IRQ(IRQ1_STATUS1, BST_OVP_ERR), ++ CS35L41_REG_IRQ(IRQ1_STATUS1, BST_DCM_UVP_ERR), ++ CS35L41_REG_IRQ(IRQ1_STATUS1, BST_SHORT_ERR), ++ CS35L41_REG_IRQ(IRQ1_STATUS1, TEMP_WARN), ++ CS35L41_REG_IRQ(IRQ1_STATUS1, TEMP_ERR), ++ CS35L41_REG_IRQ(IRQ1_STATUS1, AMP_SHORT_ERR), ++}; ++ ++static const struct regmap_irq_chip cs35l41_regmap_irq_chip = { ++ .name = "cs35l41 IRQ1 Controller", ++ .status_base = CS35L41_IRQ1_STATUS1, ++ .mask_base = CS35L41_IRQ1_MASK1, ++ .ack_base = CS35L41_IRQ1_STATUS1, ++ .num_regs = 4, ++ .irqs = cs35l41_reg_irqs, ++ .num_irqs = ARRAY_SIZE(cs35l41_reg_irqs), ++}; ++ + static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41) + { + struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg; ++ bool using_irq = false; ++ int irq, irq_pol; + int ret; ++ int i; + + if (!cs35l41->hw_cfg.valid) + return -EINVAL; +@@ -145,6 +252,7 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41) + case CS35L41_NOT_USED: + break; + case CS35L41_INTERRUPT: ++ using_irq = true; + break; + default: + dev_err(cs35l41->dev, "Invalid GPIO2 function %d\n", hw_cfg->gpio2.func); +@@ -152,7 +260,28 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41) + } + } + +- cs35l41_gpio_config(cs35l41->regmap, hw_cfg); ++ irq_pol = cs35l41_gpio_config(cs35l41->regmap, hw_cfg); ++ ++ if (cs35l41->irq && using_irq) { ++ ret = devm_regmap_add_irq_chip(cs35l41->dev, cs35l41->regmap, cs35l41->irq, ++ IRQF_ONESHOT | IRQF_SHARED | irq_pol, ++ 0, &cs35l41_regmap_irq_chip, &cs35l41->irq_data); ++ if (ret) ++ return ret; ++ ++ for (i = 0; i < ARRAY_SIZE(cs35l41_irqs); i++) { ++ irq = regmap_irq_get_virq(cs35l41->irq_data, cs35l41_irqs[i].irq); ++ if (irq < 0) ++ return irq; ++ ++ ret = devm_request_threaded_irq(cs35l41->dev, irq, NULL, ++ cs35l41_irqs[i].handler, ++ IRQF_ONESHOT | IRQF_SHARED | irq_pol, ++ cs35l41_irqs[i].name, cs35l41); ++ if (ret) ++ return ret; ++ } ++ } + + return cs35l41_hda_channel_map(cs35l41->dev, 0, NULL, 1, &hw_cfg->spk_pos); + } +@@ -296,6 +425,9 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i + struct cs35l41_hda *cs35l41; + int ret; + ++ BUILD_BUG_ON(ARRAY_SIZE(cs35l41_irqs) != ARRAY_SIZE(cs35l41_reg_irqs)); ++ BUILD_BUG_ON(ARRAY_SIZE(cs35l41_irqs) != CS35L41_NUM_IRQ); ++ + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + +diff --git a/sound/pci/hda/cs35l41_hda.h b/sound/pci/hda/cs35l41_hda.h +index 44d9204ffdf1..c486e4a5bb24 100644 +--- a/sound/pci/hda/cs35l41_hda.h ++++ b/sound/pci/hda/cs35l41_hda.h +@@ -35,6 +35,8 @@ struct cs35l41_hda { + + int irq; + int index; ++ unsigned volatile long irq_errors; ++ struct regmap_irq_chip_data *irq_data; + }; + + int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq, +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Add-calls-to-newly-added-test-key-f.patch b/patches.suse/ALSA-hda-cs35l41-Add-calls-to-newly-added-test-key-f.patch new file mode 100644 index 0000000..8c717bc --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Add-calls-to-newly-added-test-key-f.patch @@ -0,0 +1,52 @@ +From 6e4320d8ecbc8711209b3075f2d896667006fa37 Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Mon, 17 Jan 2022 16:08:26 +0000 +Subject: [PATCH] ALSA: hda: cs35l41: Add calls to newly added test key function +Git-commit: 6e4320d8ecbc8711209b3075f2d896667006fa37 +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +The test key now needs to be manually held when calling +cs35l41_register_errata_patch, after patch: + +Add the missing function calls to this driver. + +Fixes: f517ba4924ad ("ASoC: cs35l41: Add support for hibernate memory retention mode") +Signed-off-by: Charles Keepax +Signed-off-by: Lucas Tanure +Link: https://lore.kernel.org/r/20220117160830.709403-2-tanureal@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index c47c5f0b4e59..509a380f9be7 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -463,6 +463,10 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i + goto err; + } + ++ ret = cs35l41_test_key_unlock(cs35l41->dev, cs35l41->regmap); ++ if (ret) ++ goto err; ++ + ret = cs35l41_register_errata_patch(cs35l41->dev, cs35l41->regmap, reg_revid); + if (ret) + goto err; +@@ -473,6 +477,10 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i + goto err; + } + ++ ret = cs35l41_test_key_lock(cs35l41->dev, cs35l41->regmap); ++ if (ret) ++ goto err; ++ + ret = cs35l41_hda_apply_properties(cs35l41, acpi_hw_cfg); + if (ret) + goto err; +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Add-defaulted-values-into-dsp-bypas.patch b/patches.suse/ALSA-hda-cs35l41-Add-defaulted-values-into-dsp-bypas.patch new file mode 100644 index 0000000..45782cc --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Add-defaulted-values-into-dsp-bypas.patch @@ -0,0 +1,60 @@ +From 4fa58b1d7ec714581bfb1d12370746d29518cd3a Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Thu, 30 Jun 2022 01:23:33 +0100 +Subject: [PATCH] ALSA: hda: cs35l41: Add defaulted values into dsp bypass config sequence +Git-commit: 4fa58b1d7ec714581bfb1d12370746d29518cd3a +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +The config sequences for running with and without firmware and DSP +are different. The original behavior assumed that we would only +run without DSP only in the case where firmware load failed. +This meant the non-firmware sequence was written with the assumtion +that various registers would be set to their default value. +However, to support the ability to unload the firmware, the +non-firmware register sequence must be updated to update all +required registers, including values that would be defaulted, +in case the firmware sequence, which could have already run, +has changed their value. + +Signed-off-by: Stefan Binding +Signed-off-by: Vitaly Rodionov +Link: https://lore.kernel.org/r/20220630002335.366545-13-vitalyr@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index 75edaffb568a..a02a74f68c2d 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -35,11 +35,24 @@ + + static const struct reg_sequence cs35l41_hda_config[] = { + { CS35L41_PLL_CLK_CTRL, 0x00000430 }, // 3072000Hz, BCLK Input, PLL_REFCLK_EN = 1 ++ { CS35L41_DSP_CLK_CTRL, 0x00000003 }, // DSP CLK EN + { CS35L41_GLOBAL_CLK_CTRL, 0x00000003 }, // GLOBAL_FS = 48 kHz + { CS35L41_SP_ENABLES, 0x00010000 }, // ASP_RX1_EN = 1 + { CS35L41_SP_RATE_CTRL, 0x00000021 }, // ASP_BCLK_FREQ = 3.072 MHz + { CS35L41_SP_FORMAT, 0x20200200 }, // 32 bits RX/TX slots, I2S, clk consumer ++ { CS35L41_SP_HIZ_CTRL, 0x00000002 }, // Hi-Z unused ++ { CS35L41_SP_TX_WL, 0x00000018 }, // 24 cycles/slot ++ { CS35L41_SP_RX_WL, 0x00000018 }, // 24 cycles/slot + { CS35L41_DAC_PCM1_SRC, 0x00000008 }, // DACPCM1_SRC = ASPRX1 ++ { CS35L41_ASP_TX1_SRC, 0x00000018 }, // ASPTX1 SRC = VMON ++ { CS35L41_ASP_TX2_SRC, 0x00000019 }, // ASPTX2 SRC = IMON ++ { CS35L41_ASP_TX3_SRC, 0x00000032 }, // ASPTX3 SRC = ERRVOL ++ { CS35L41_ASP_TX4_SRC, 0x00000033 }, // ASPTX4 SRC = CLASSH_TGT ++ { CS35L41_DSP1_RX1_SRC, 0x00000008 }, // DSP1RX1 SRC = ASPRX1 ++ { CS35L41_DSP1_RX2_SRC, 0x00000009 }, // DSP1RX2 SRC = ASPRX2 ++ { CS35L41_DSP1_RX3_SRC, 0x00000018 }, // DSP1RX3 SRC = VMON ++ { CS35L41_DSP1_RX4_SRC, 0x00000019 }, // DSP1RX4 SRC = IMON ++ { CS35L41_DSP1_RX5_SRC, 0x00000020 }, // DSP1RX5 SRC = ERRVOL + { CS35L41_AMP_DIG_VOL_CTRL, 0x00000000 }, // AMP_VOL_PCM 0.0 dB + { CS35L41_AMP_GAIN_CTRL, 0x00000084 }, // AMP_GAIN_PCM 4.5 dB + }; +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Add-initial-DSP-support-and-firmwar.patch b/patches.suse/ALSA-hda-cs35l41-Add-initial-DSP-support-and-firmwar.patch new file mode 100644 index 0000000..63aa460 --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Add-initial-DSP-support-and-firmwar.patch @@ -0,0 +1,438 @@ +From 2e81e1fffd53ba108481f2f14388b628884efe61 Mon Sep 17 00:00:00 2001 +From: Vitaly Rodionov +Date: Thu, 30 Jun 2022 01:23:25 +0100 +Subject: [PATCH] ALSA: hda: cs35l41: Add initial DSP support and firmware loading +Git-commit: 2e81e1fffd53ba108481f2f14388b628884efe61 +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +This patch adds support for the CS35L41 DSP. +The DSP allows for extra features, such as running +speaker protection algorithms and hibernations. + +To utilize these features, the driver must load +firmware into the DSP, as well as various tuning +files which allow for customization for specific +models. + +[ Slightly simplified Kconfig changes by tiwai ] + +Signed-off-by: Vitaly Rodionov +Signed-off-by: Vitaly Rodionov +Link: https://lore.kernel.org/r/20220630002335.366545-5-vitalyr@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + include/sound/cs35l41.h | 4 + + sound/pci/hda/Kconfig | 2 + + sound/pci/hda/cs35l41_hda.c | 251 +++++++++++++++++++++++++++++++++++- + sound/pci/hda/cs35l41_hda.h | 13 ++ + 4 files changed, 269 insertions(+), 1 deletion(-) + +diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h +index 8972fa697622..8887087815a7 100644 +--- a/include/sound/cs35l41.h ++++ b/include/sound/cs35l41.h +@@ -665,6 +665,10 @@ + #define CS35L41_BST_EN_DEFAULT 0x2 + #define CS35L41_AMP_EN_SHIFT 0 + #define CS35L41_AMP_EN_MASK 1 ++#define CS35L41_VMON_EN_MASK 0x1000 ++#define CS35L41_VMON_EN_SHIFT 12 ++#define CS35L41_IMON_EN_MASK 0x2000 ++#define CS35L41_IMON_EN_SHIFT 13 + + #define CS35L41_PDN_DONE_MASK 0x00800000 + #define CS35L41_PDN_DONE_SHIFT 23 +diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig +index a17803953222..44c33bc0740e 100644 +--- a/sound/pci/hda/Kconfig ++++ b/sound/pci/hda/Kconfig +@@ -107,6 +107,7 @@ config SND_HDA_SCODEC_CS35L41_I2C + depends on SND_SOC + select SND_SOC_CS35L41_LIB + select SND_HDA_SCODEC_CS35L41 ++ select SND_HDA_CS_DSP_CONTROLS + help + Say Y or M here to include CS35L41 I2C HD-audio side codec support + in snd-hda-intel driver, such as ALC287. +@@ -121,6 +122,7 @@ config SND_HDA_SCODEC_CS35L41_SPI + depends on SND_SOC + select SND_SOC_CS35L41_LIB + select SND_HDA_SCODEC_CS35L41 ++ select SND_HDA_CS_DSP_CONTROLS + help + Say Y or M here to include CS35L41 SPI HD-audio side codec support + in snd-hda-intel driver, such as ALC287. +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index 20d3ce8773dd..d68d951c434e 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -9,12 +9,22 @@ + #include + #include + #include ++#include + #include "hda_local.h" + #include "hda_auto_parser.h" + #include "hda_jack.h" + #include "hda_generic.h" + #include "hda_component.h" + #include "cs35l41_hda.h" ++#include "hda_cs_dsp_ctl.h" ++ ++#define CS35L41_FIRMWARE_ROOT "cirrus/" ++#define CS35L41_PART "cs35l41" ++#define FW_NAME "CSPL" ++ ++#define HALO_STATE_DSP_CTL_NAME "HALO_STATE" ++#define HALO_STATE_DSP_CTL_TYPE 5 ++#define HALO_STATE_DSP_CTL_ALG 262308 + + static const struct reg_sequence cs35l41_hda_config[] = { + { CS35L41_PLL_CLK_CTRL, 0x00000430 }, // 3072000Hz, BCLK Input, PLL_REFCLK_EN = 1 +@@ -27,11 +37,172 @@ static const struct reg_sequence cs35l41_hda_config[] = { + { CS35L41_AMP_GAIN_CTRL, 0x00000084 }, // AMP_GAIN_PCM 4.5 dB + }; + ++static const struct reg_sequence cs35l41_hda_config_dsp[] = { ++ { CS35L41_PLL_CLK_CTRL, 0x00000430 }, // 3072000Hz, BCLK Input, PLL_REFCLK_EN = 1 ++ { CS35L41_DSP_CLK_CTRL, 0x00000003 }, // DSP CLK EN ++ { CS35L41_GLOBAL_CLK_CTRL, 0x00000003 }, // GLOBAL_FS = 48 kHz ++ { CS35L41_SP_ENABLES, 0x00010001 }, // ASP_RX1_EN = 1, ASP_TX1_EN = 1 ++ { CS35L41_SP_RATE_CTRL, 0x00000021 }, // ASP_BCLK_FREQ = 3.072 MHz ++ { CS35L41_SP_FORMAT, 0x20200200 }, // 32 bits RX/TX slots, I2S, clk consumer ++ { CS35L41_SP_HIZ_CTRL, 0x00000003 }, // Hi-Z unused/disabled ++ { CS35L41_SP_TX_WL, 0x00000018 }, // 24 cycles/slot ++ { CS35L41_SP_RX_WL, 0x00000018 }, // 24 cycles/slot ++ { CS35L41_DAC_PCM1_SRC, 0x00000032 }, // DACPCM1_SRC = ERR_VOL ++ { CS35L41_ASP_TX1_SRC, 0x00000018 }, // ASPTX1 SRC = VMON ++ { CS35L41_ASP_TX2_SRC, 0x00000019 }, // ASPTX2 SRC = IMON ++ { CS35L41_ASP_TX3_SRC, 0x00000028 }, // ASPTX3 SRC = VPMON ++ { CS35L41_ASP_TX4_SRC, 0x00000029 }, // ASPTX4 SRC = VBSTMON ++ { CS35L41_DSP1_RX1_SRC, 0x00000008 }, // DSP1RX1 SRC = ASPRX1 ++ { CS35L41_DSP1_RX2_SRC, 0x00000008 }, // DSP1RX2 SRC = ASPRX1 ++ { CS35L41_DSP1_RX3_SRC, 0x00000018 }, // DSP1RX3 SRC = VMON ++ { CS35L41_DSP1_RX4_SRC, 0x00000019 }, // DSP1RX4 SRC = IMON ++ { CS35L41_DSP1_RX5_SRC, 0x00000029 }, // DSP1RX5 SRC = VBSTMON ++ { CS35L41_AMP_DIG_VOL_CTRL, 0x00000000 }, // AMP_VOL_PCM 0.0 dB ++ { CS35L41_AMP_GAIN_CTRL, 0x00000233 }, // AMP_GAIN_PCM = 17.5dB AMP_GAIN_PDM = 19.5dB ++}; ++ + static const struct reg_sequence cs35l41_hda_mute[] = { + { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, // AMP_GAIN_PCM 0.5 dB + { CS35L41_AMP_DIG_VOL_CTRL, 0x0000A678 }, // AMP_VOL_PCM Mute + }; + ++static int cs35l41_control_add(struct cs_dsp_coeff_ctl *cs_ctl) ++{ ++ struct cs35l41_hda *cs35l41 = container_of(cs_ctl->dsp, struct cs35l41_hda, cs_dsp); ++ struct hda_cs_dsp_ctl_info info; ++ ++ info.device_name = cs35l41->amp_name; ++ info.fw_type = HDA_CS_DSP_FW_SPK_PROT; ++ info.card = cs35l41->codec->card; ++ ++ return hda_cs_dsp_control_add(cs_ctl, &info); ++} ++ ++static const struct cs_dsp_client_ops client_ops = { ++ .control_add = cs35l41_control_add, ++ .control_remove = hda_cs_dsp_control_remove, ++}; ++ ++static int cs35l41_request_firmware_file(struct cs35l41_hda *cs35l41, ++ const struct firmware **firmware, char **filename, ++ const char *dir, const char *filetype) ++{ ++ const char * const dsp_name = cs35l41->cs_dsp.name; ++ char *s, c; ++ int ret = 0; ++ ++ *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s.%s", dir, CS35L41_PART, dsp_name, "spk-prot", ++ filetype); ++ ++ if (*filename == NULL) ++ return -ENOMEM; ++ ++ /* ++ * Make sure that filename is lower-case and any non alpha-numeric ++ * characters except full stop and '/' are replaced with hyphens. ++ */ ++ s = *filename; ++ while (*s) { ++ c = *s; ++ if (isalnum(c)) ++ *s = tolower(c); ++ else if (c != '.' && c != '/') ++ *s = '-'; ++ s++; ++ } ++ ++ ret = firmware_request_nowarn(firmware, *filename, cs35l41->dev); ++ if (ret != 0) { ++ dev_dbg(cs35l41->dev, "Failed to request '%s'\n", *filename); ++ kfree(*filename); ++ *filename = NULL; ++ } ++ ++ return ret; ++} ++ ++static int cs35l41_request_firmware_files(struct cs35l41_hda *cs35l41, ++ const struct firmware **wmfw_firmware, ++ char **wmfw_filename, ++ const struct firmware **coeff_firmware, ++ char **coeff_filename) ++{ ++ int ret; ++ ++ /* cirrus/part-dspN-fwtype.wmfw */ ++ ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, ++ CS35L41_FIRMWARE_ROOT, "wmfw"); ++ if (!ret) { ++ cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, ++ CS35L41_FIRMWARE_ROOT, "bin"); ++ return 0; ++ } ++ ++ dev_warn(cs35l41->dev, "Failed to request firmware\n"); ++ ++ return ret; ++} ++ ++static int cs35l41_init_dsp(struct cs35l41_hda *cs35l41) ++{ ++ const struct firmware *coeff_firmware = NULL; ++ const struct firmware *wmfw_firmware = NULL; ++ struct cs_dsp *dsp = &cs35l41->cs_dsp; ++ char *coeff_filename = NULL; ++ char *wmfw_filename = NULL; ++ int ret; ++ ++ if (!cs35l41->halo_initialized) { ++ cs35l41_configure_cs_dsp(cs35l41->dev, cs35l41->regmap, dsp); ++ dsp->client_ops = &client_ops; ++ ++ ret = cs_dsp_halo_init(&cs35l41->cs_dsp); ++ if (ret) ++ return ret; ++ cs35l41->halo_initialized = true; ++ } ++ ++ ret = cs35l41_request_firmware_files(cs35l41, &wmfw_firmware, &wmfw_filename, ++ &coeff_firmware, &coeff_filename); ++ if (ret < 0) ++ return ret; ++ ++ dev_dbg(cs35l41->dev, "Loading WMFW Firmware: %s\n", wmfw_filename); ++ if (coeff_filename) ++ dev_dbg(cs35l41->dev, "Loading Coefficient File: %s\n", coeff_filename); ++ else ++ dev_warn(cs35l41->dev, "No Coefficient File available.\n"); ++ ++ ret = cs_dsp_power_up(dsp, wmfw_firmware, wmfw_filename, coeff_firmware, coeff_filename, ++ FW_NAME); ++ ++ release_firmware(wmfw_firmware); ++ release_firmware(coeff_firmware); ++ kfree(wmfw_filename); ++ kfree(coeff_filename); ++ ++ return ret; ++} ++ ++static void cs35l41_shutdown_dsp(struct cs35l41_hda *cs35l41) ++{ ++ struct cs_dsp *dsp = &cs35l41->cs_dsp; ++ ++ cs_dsp_stop(dsp); ++ cs_dsp_power_down(dsp); ++ cs35l41->firmware_running = false; ++ dev_dbg(cs35l41->dev, "Unloaded Firmware\n"); ++} ++ ++static void cs35l41_remove_dsp(struct cs35l41_hda *cs35l41) ++{ ++ struct cs_dsp *dsp = &cs35l41->cs_dsp; ++ ++ cs35l41_shutdown_dsp(cs35l41); ++ cs_dsp_remove(dsp); ++ cs35l41->halo_initialized = false; ++} ++ + /* Protection release cycle to get the speaker out of Safe-Mode */ + static void cs35l41_error_release(struct device *dev, struct regmap *regmap, unsigned int mask) + { +@@ -53,9 +224,22 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action) + struct regmap *reg = cs35l41->regmap; + int ret = 0; + ++ mutex_lock(&cs35l41->fw_mutex); ++ + switch (action) { + case HDA_GEN_PCM_ACT_OPEN: +- regmap_multi_reg_write(reg, cs35l41_hda_config, ARRAY_SIZE(cs35l41_hda_config)); ++ if (cs35l41->firmware_running) { ++ regmap_multi_reg_write(reg, cs35l41_hda_config_dsp, ++ ARRAY_SIZE(cs35l41_hda_config_dsp)); ++ regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, ++ CS35L41_VMON_EN_MASK | CS35L41_IMON_EN_MASK, ++ 1 << CS35L41_VMON_EN_SHIFT | 1 << CS35L41_IMON_EN_SHIFT); ++ cs35l41_set_cspl_mbox_cmd(cs35l41->dev, cs35l41->regmap, ++ CSPL_MBOX_CMD_RESUME); ++ } else { ++ regmap_multi_reg_write(reg, cs35l41_hda_config, ++ ARRAY_SIZE(cs35l41_hda_config)); ++ } + ret = regmap_update_bits(reg, CS35L41_PWR_CTRL2, + CS35L41_AMP_EN_MASK, 1 << CS35L41_AMP_EN_SHIFT); + if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST) +@@ -73,6 +257,13 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action) + CS35L41_AMP_EN_MASK, 0 << CS35L41_AMP_EN_SHIFT); + if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST) + regmap_write(reg, CS35L41_GPIO1_CTRL1, 0x00000001); ++ if (cs35l41->firmware_running) { ++ cs35l41_set_cspl_mbox_cmd(cs35l41->dev, cs35l41->regmap, ++ CSPL_MBOX_CMD_PAUSE); ++ regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, ++ CS35L41_VMON_EN_MASK | CS35L41_IMON_EN_MASK, ++ 0 << CS35L41_VMON_EN_SHIFT | 0 << CS35L41_IMON_EN_SHIFT); ++ } + cs35l41_irq_release(cs35l41); + break; + default: +@@ -80,6 +271,8 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action) + break; + } + ++ mutex_unlock(&cs35l41->fw_mutex); ++ + if (ret) + dev_err(cs35l41->dev, "Regmap access fail: %d\n", ret); + } +@@ -104,6 +297,51 @@ static int cs35l41_hda_channel_map(struct device *dev, unsigned int tx_num, unsi + rx_slot); + } + ++static int cs35l41_smart_amp(struct cs35l41_hda *cs35l41) ++{ ++ int halo_sts; ++ int ret; ++ ++ ret = cs35l41_init_dsp(cs35l41); ++ if (ret) { ++ dev_warn(cs35l41->dev, "Cannot Initialize Firmware. Error: %d\n", ret); ++ goto clean_dsp; ++ } ++ ++ ret = cs35l41_write_fs_errata(cs35l41->dev, cs35l41->regmap); ++ if (ret) { ++ dev_err(cs35l41->dev, "Cannot Write FS Errata: %d\n", ret); ++ goto clean_dsp; ++ } ++ ++ ret = cs_dsp_run(&cs35l41->cs_dsp); ++ if (ret) { ++ dev_err(cs35l41->dev, "Fail to start dsp: %d\n", ret); ++ goto clean_dsp; ++ } ++ ++ ret = read_poll_timeout(hda_cs_dsp_read_ctl, ret, ++ be32_to_cpu(halo_sts) == HALO_STATE_CODE_RUN, ++ 1000, 15000, false, &cs35l41->cs_dsp, HALO_STATE_DSP_CTL_NAME, ++ HALO_STATE_DSP_CTL_TYPE, HALO_STATE_DSP_CTL_ALG, ++ &halo_sts, sizeof(halo_sts)); ++ ++ if (ret) { ++ dev_err(cs35l41->dev, "Timeout waiting for HALO Core to start. State: %d\n", ++ halo_sts); ++ goto clean_dsp; ++ } ++ ++ cs35l41_set_cspl_mbox_cmd(cs35l41->dev, cs35l41->regmap, CSPL_MBOX_CMD_PAUSE); ++ cs35l41->firmware_running = true; ++ ++ return 0; ++ ++clean_dsp: ++ cs35l41_shutdown_dsp(cs35l41); ++ return ret; ++} ++ + static int cs35l41_hda_bind(struct device *dev, struct device *master, void *master_data) + { + struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); +@@ -121,6 +359,11 @@ static int cs35l41_hda_bind(struct device *dev, struct device *master, void *mas + strscpy(comps->name, dev_name(dev), sizeof(comps->name)); + comps->playback_hook = cs35l41_hda_playback_hook; + ++ mutex_lock(&cs35l41->fw_mutex); ++ if (cs35l41_smart_amp(cs35l41) < 0) ++ dev_warn(cs35l41->dev, "Cannot Run Firmware, reverting to dsp bypass...\n"); ++ mutex_unlock(&cs35l41->fw_mutex); ++ + return 0; + } + +@@ -535,6 +778,8 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i + if (ret) + goto err; + ++ mutex_init(&cs35l41->fw_mutex); ++ + ret = cs35l41_hda_apply_properties(cs35l41); + if (ret) + goto err; +@@ -562,6 +807,9 @@ void cs35l41_hda_remove(struct device *dev) + { + struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); + ++ if (cs35l41->halo_initialized) ++ cs35l41_remove_dsp(cs35l41); ++ + component_del(cs35l41->dev, &cs35l41_hda_comp_ops); + + if (cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type)) +@@ -571,5 +819,6 @@ void cs35l41_hda_remove(struct device *dev) + EXPORT_SYMBOL_NS_GPL(cs35l41_hda_remove, SND_HDA_SCODEC_CS35L41); + + MODULE_DESCRIPTION("CS35L41 HDA Driver"); ++MODULE_IMPORT_NS(SND_HDA_CS_DSP_CONTROLS); + MODULE_AUTHOR("Lucas Tanure, Cirrus Logic Inc, "); + MODULE_LICENSE("GPL"); +diff --git a/sound/pci/hda/cs35l41_hda.h b/sound/pci/hda/cs35l41_hda.h +index aaf9e16684c2..5814af050944 100644 +--- a/sound/pci/hda/cs35l41_hda.h ++++ b/sound/pci/hda/cs35l41_hda.h +@@ -15,6 +15,9 @@ + #include + #include + ++#include ++#include ++ + enum cs35l41_hda_spk_pos { + CS35l41_LEFT, + CS35l41_RIGHT, +@@ -39,7 +42,17 @@ struct cs35l41_hda { + int channel_index; + unsigned volatile long irq_errors; + const char *amp_name; ++ struct mutex fw_mutex; + struct regmap_irq_chip_data *irq_data; ++ bool firmware_running; ++ bool halo_initialized; ++ struct cs_dsp cs_dsp; ++}; ++ ++enum halo_state { ++ HALO_STATE_CODE_INIT_DOWNLOAD = 0, ++ HALO_STATE_CODE_START, ++ HALO_STATE_CODE_RUN + }; + + int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq, +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Add-missing-default-cases.patch b/patches.suse/ALSA-hda-cs35l41-Add-missing-default-cases.patch new file mode 100644 index 0000000..d89d0a2 --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Add-missing-default-cases.patch @@ -0,0 +1,66 @@ +From cd8abf7d04c940c627ceb6f416b2142d3e7b36dd Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Mon, 17 Jan 2022 16:08:28 +0000 +Subject: [PATCH] ALSA: hda: cs35l41: Add missing default cases +Git-commit: cd8abf7d04c940c627ceb6f416b2142d3e7b36dd +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +Add switch default cases at gpio pins configs + +Signed-off-by: Lucas Tanure +Link: https://lore.kernel.org/r/20220117160830.709403-4-tanureal@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index c4f25e48dcc0..82f982f574a9 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -161,6 +161,9 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action) + if (reg_seq->close) + ret = regmap_multi_reg_write(reg, reg_seq->close, reg_seq->num_close); + break; ++ default: ++ ret = -EINVAL; ++ break; + } + + if (ret) +@@ -227,6 +230,8 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41, + internal_boost = true; + + switch (hw_cfg->gpio1_func) { ++ case CS35L41_NOT_USED: ++ break; + case CS35l41_VSPK_SWITCH: + regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL, + CS35L41_GPIO1_CTRL_MASK, 1 << CS35L41_GPIO1_CTRL_SHIFT); +@@ -235,13 +240,21 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41, + regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL, + CS35L41_GPIO1_CTRL_MASK, 2 << CS35L41_GPIO1_CTRL_SHIFT); + break; ++ default: ++ dev_err(cs35l41->dev, "Invalid function %d for GPIO1\n", hw_cfg->gpio1_func); ++ return -EINVAL; + } + + switch (hw_cfg->gpio2_func) { ++ case CS35L41_NOT_USED: ++ break; + case CS35L41_INTERRUPT: + regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL, + CS35L41_GPIO2_CTRL_MASK, 2 << CS35L41_GPIO2_CTRL_SHIFT); + break; ++ default: ++ dev_err(cs35l41->dev, "Invalid function %d for GPIO2\n", hw_cfg->gpio2_func); ++ return -EINVAL; + } + + if (internal_boost) { +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Add-module-parameter-to-control-fir.patch b/patches.suse/ALSA-hda-cs35l41-Add-module-parameter-to-control-fir.patch new file mode 100644 index 0000000..3c613b4 --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Add-module-parameter-to-control-fir.patch @@ -0,0 +1,70 @@ +From 622f21994506e1dac7b8e4e362c8951426e032c5 Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Thu, 30 Jun 2022 01:23:35 +0100 +Subject: [PATCH] ALSA: hda: cs35l41: Add module parameter to control firmware load +Git-commit: 622f21994506e1dac7b8e4e362c8951426e032c5 +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +By default, the driver will automatically load DSP firmware +for the amps, if available. Adding this option allows the +autoload to be optional, which allows for different configurations. + +Signed-off-by: Stefan Binding +Signed-off-by: Vitaly Rodionov +Link: https://lore.kernel.org/r/20220630002335.366545-15-vitalyr@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 21 ++++++++++++++++----- + 1 file changed, 16 insertions(+), 5 deletions(-) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index 4252c0ac69b7..28798d5c1cf1 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -8,6 +8,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -32,6 +33,11 @@ + #define CAL_DSP_CTL_TYPE 5 + #define CAL_DSP_CTL_ALG 205 + ++static bool firmware_autostart = 1; ++module_param(firmware_autostart, bool, 0444); ++MODULE_PARM_DESC(firmware_autostart, "Allow automatic firmware download on boot" ++ "(0=Disable, 1=Enable) (default=1); "); ++ + static const struct reg_sequence cs35l41_hda_config[] = { + { CS35L41_PLL_CLK_CTRL, 0x00000430 }, // 3072000Hz, BCLK Input, PLL_REFCLK_EN = 1 + { CS35L41_DSP_CLK_CTRL, 0x00000003 }, // DSP CLK EN +@@ -843,11 +849,16 @@ static int cs35l41_hda_bind(struct device *dev, struct device *master, void *mas + + cs35l41->firmware_type = HDA_CS_DSP_FW_SPK_PROT; + +- cs35l41->request_fw_load = true; +- mutex_lock(&cs35l41->fw_mutex); +- if (cs35l41_smart_amp(cs35l41) < 0) +- dev_warn(cs35l41->dev, "Cannot Run Firmware, reverting to dsp bypass...\n"); +- mutex_unlock(&cs35l41->fw_mutex); ++ if (firmware_autostart) { ++ dev_dbg(cs35l41->dev, "Firmware Autostart.\n"); ++ cs35l41->request_fw_load = true; ++ mutex_lock(&cs35l41->fw_mutex); ++ if (cs35l41_smart_amp(cs35l41) < 0) ++ dev_warn(cs35l41->dev, "Cannot Run Firmware, reverting to dsp bypass...\n"); ++ mutex_unlock(&cs35l41->fw_mutex); ++ } else { ++ dev_dbg(cs35l41->dev, "Firmware Autostart is disabled.\n"); ++ } + + ret = cs35l41_create_controls(cs35l41); + +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Add-support-for-CS35L41-in-HDA-syst.patch b/patches.suse/ALSA-hda-cs35l41-Add-support-for-CS35L41-in-HDA-syst.patch new file mode 100644 index 0000000..a0151a7 --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Add-support-for-CS35L41-in-HDA-syst.patch @@ -0,0 +1,894 @@ +From 7b2f3eb492dac7665c75df067e4d8e4869589f4a Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Fri, 17 Dec 2021 11:57:05 +0000 +Subject: [PATCH] ALSA: hda: cs35l41: Add support for CS35L41 in HDA systems +Git-commit: 7b2f3eb492dac7665c75df067e4d8e4869589f4a +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +Add support for CS35L41 using a new separated driver +that can be used in all upcoming designs + +Signed-off-by: Lucas Tanure +Link: https://lore.kernel.org/r/20211217115708.882525-8-tanureal@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + MAINTAINERS | 2 + + sound/pci/hda/Kconfig | 29 ++ + sound/pci/hda/Makefile | 10 + + sound/pci/hda/cs35l41_hda.c | 527 ++++++++++++++++++++++++++++++++ + sound/pci/hda/cs35l41_hda.h | 69 +++++ + sound/pci/hda/cs35l41_hda_i2c.c | 66 ++++ + sound/pci/hda/cs35l41_hda_spi.c | 63 ++++ + sound/pci/hda/hda_component.h | 20 ++ + 8 files changed, 786 insertions(+) + create mode 100644 sound/pci/hda/cs35l41_hda.c + create mode 100644 sound/pci/hda/cs35l41_hda.h + create mode 100644 sound/pci/hda/cs35l41_hda_i2c.c + create mode 100644 sound/pci/hda/cs35l41_hda_spi.c + create mode 100644 sound/pci/hda/hda_component.h + +diff --git a/MAINTAINERS b/MAINTAINERS +index 74d7d20b9d19..e8d4805e093e 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -4511,10 +4511,12 @@ F: drivers/media/cec/i2c/ch7322.c + CIRRUS LOGIC AUDIO CODEC DRIVERS + M: James Schulman + M: David Rhodes ++M: Lucas Tanure + L: alsa-devel@alsa-project.org (moderated for non-subscribers) + L: patches@opensource.cirrus.com + S: Maintained + F: Documentation/devicetree/bindings/sound/cirrus,cs* ++F: sound/pci/hda/cs* + F: sound/soc/codecs/cs* + + CIRRUS LOGIC DSP FIRMWARE DRIVER +diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig +index ab9d2746e804..84cefc006f29 100644 +--- a/sound/pci/hda/Kconfig ++++ b/sound/pci/hda/Kconfig +@@ -91,6 +91,35 @@ config SND_HDA_PATCH_LOADER + start up. The "patch" file can be specified via patch module + option, such as patch=hda-init. + ++config SND_HDA_SCODEC_CS35L41 ++ tristate ++ ++config SND_HDA_SCODEC_CS35L41_I2C ++ tristate "Build CS35L41 HD-audio side codec support for I2C Bus" ++ depends on ACPI ++ select SND_HDA_GENERIC ++ select SND_SOC_CS35L41_LIB ++ select SND_HDA_SCODEC_CS35L41 ++ help ++ Say Y or M here to include CS35L41 I2C HD-audio side codec support ++ in snd-hda-intel driver, such as ALC287. ++ ++comment "Set to Y if you want auto-loading the side codec driver" ++ depends on SND_HDA=y && SND_HDA_SCODEC_CS35L41_I2C=m ++ ++config SND_HDA_SCODEC_CS35L41_SPI ++ tristate "Build CS35L41 HD-audio codec support for SPI Bus" ++ depends on ACPI ++ select SND_HDA_GENERIC ++ select SND_SOC_CS35L41_LIB ++ select SND_HDA_SCODEC_CS35L41 ++ help ++ Say Y or M here to include CS35L41 SPI HD-audio side codec support ++ in snd-hda-intel driver, such as ALC287. ++ ++comment "Set to Y if you want auto-loading the side codec driver" ++ depends on SND_HDA=y && SND_HDA_SCODEC_CS35L41_SPI=m ++ + config SND_HDA_CODEC_REALTEK + tristate "Build Realtek HD-audio codec support" + select SND_HDA_GENERIC +diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile +index b8fa682ce66a..3e7bc608d45f 100644 +--- a/sound/pci/hda/Makefile ++++ b/sound/pci/hda/Makefile +@@ -27,6 +27,11 @@ snd-hda-codec-conexant-objs := patch_conexant.o + snd-hda-codec-via-objs := patch_via.o + snd-hda-codec-hdmi-objs := patch_hdmi.o hda_eld.o + ++# side codecs ++snd-hda-scodec-cs35l41-objs := cs35l41_hda.o ++snd-hda-scodec-cs35l41-i2c-objs := cs35l41_hda_i2c.o ++snd-hda-scodec-cs35l41-spi-objs := cs35l41_hda_spi.o ++ + # common driver + obj-$(CONFIG_SND_HDA) := snd-hda-codec.o + +@@ -45,6 +50,11 @@ obj-$(CONFIG_SND_HDA_CODEC_CONEXANT) += snd-hda-codec-conexant.o + obj-$(CONFIG_SND_HDA_CODEC_VIA) += snd-hda-codec-via.o + obj-$(CONFIG_SND_HDA_CODEC_HDMI) += snd-hda-codec-hdmi.o + ++# side codecs ++obj-$(CONFIG_SND_HDA_SCODEC_CS35L41) += snd-hda-scodec-cs35l41.o ++obj-$(CONFIG_SND_HDA_SCODEC_CS35L41_I2C) += snd-hda-scodec-cs35l41-i2c.o ++obj-$(CONFIG_SND_HDA_SCODEC_CS35L41_SPI) += snd-hda-scodec-cs35l41-spi.o ++ + # this must be the last entry after codec drivers; + # otherwise the codec patches won't be hooked before the PCI probe + # when built in kernel +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +new file mode 100644 +index 000000000000..aa5bb6977792 +--- /dev/null ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -0,0 +1,527 @@ ++// SPDX-License-Identifier: GPL-2.0 ++// ++// cs35l41.c -- CS35l41 ALSA HDA audio driver ++// ++// Copyright 2021 Cirrus Logic, Inc. ++// ++// Author: Lucas Tanure ++ ++#include ++#include ++#include ++#include "hda_local.h" ++#include "hda_auto_parser.h" ++#include "hda_jack.h" ++#include "hda_generic.h" ++#include "hda_component.h" ++#include "cs35l41_hda.h" ++ ++static const struct reg_sequence cs35l41_hda_config[] = { ++ { CS35L41_PLL_CLK_CTRL, 0x00000430 }, //3200000Hz, BCLK Input, PLL_REFCLK_EN = 1 ++ { CS35L41_GLOBAL_CLK_CTRL, 0x00000003 }, //GLOBAL_FS = 48 kHz ++ { CS35L41_SP_ENABLES, 0x00010000 }, //ASP_RX1_EN = 1 ++ { CS35L41_SP_RATE_CTRL, 0x00000021 }, //ASP_BCLK_FREQ = 3.072 MHz ++ { CS35L41_SP_FORMAT, 0x20200200 }, //24 bits, I2S, BCLK Slave, FSYNC Slave ++ { CS35L41_DAC_PCM1_SRC, 0x00000008 }, //DACPCM1_SRC = ASPRX1 ++ { CS35L41_AMP_DIG_VOL_CTRL, 0x00000000 }, //AMP_VOL_PCM 0.0 dB ++ { CS35L41_AMP_GAIN_CTRL, 0x00000084 }, //AMP_GAIN_PCM 4.5 dB ++ { CS35L41_PWR_CTRL2, 0x00000001 }, //AMP_EN = 1 ++}; ++ ++static const struct reg_sequence cs35l41_hda_start_bst[] = { ++ { CS35L41_PWR_CTRL2, 0x00000021 }, //BST_EN = 10, AMP_EN = 1 ++ { CS35L41_PWR_CTRL1, 0x00000001, 3000}, // set GLOBAL_EN = 1 ++}; ++ ++static const struct reg_sequence cs35l41_hda_stop_bst[] = { ++ { CS35L41_PWR_CTRL1, 0x00000000, 3000}, // set GLOBAL_EN = 0 ++}; ++ ++// only on amps where GPIO1 is used to control ext. VSPK switch ++static const struct reg_sequence cs35l41_start_ext_vspk[] = { ++ { 0x00000040, 0x00000055 }, ++ { 0x00000040, 0x000000AA }, ++ { 0x00007438, 0x00585941 }, ++ { 0x00007414, 0x08C82222 }, ++ { 0x0000742C, 0x00000009 }, ++ { 0x00011008, 0x00008001 }, ++ { 0x0000742C, 0x0000000F }, ++ { 0x0000742C, 0x00000079 }, ++ { 0x00007438, 0x00585941 }, ++ { CS35L41_PWR_CTRL1, 0x00000001, 3000}, // set GLOBAL_EN = 1 ++ { 0x0000742C, 0x000000F9 }, ++ { 0x00007438, 0x00580941 }, ++ { 0x00000040, 0x000000CC }, ++ { 0x00000040, 0x00000033 }, ++}; ++ ++//only on amps where GPIO1 is used to control ext. VSPK switch ++static const struct reg_sequence cs35l41_stop_ext_vspk[] = { ++ { 0x00000040, 0x00000055 }, ++ { 0x00000040, 0x000000AA }, ++ { 0x00007438, 0x00585941 }, ++ { 0x00002014, 0x00000000, 3000}, //set GLOBAL_EN = 0 ++ { 0x0000742C, 0x00000009 }, ++ { 0x00007438, 0x00580941 }, ++ { 0x00011008, 0x00000001 }, ++ { 0x0000393C, 0x000000C0, 6000}, ++ { 0x0000393C, 0x00000000 }, ++ { 0x00007414, 0x00C82222 }, ++ { 0x0000742C, 0x00000000 }, ++ { 0x00000040, 0x000000CC }, ++ { 0x00000040, 0x00000033 }, ++}; ++ ++static const struct reg_sequence cs35l41_safe_to_active[] = { ++ { 0x00000040, 0x00000055 }, ++ { 0x00000040, 0x000000AA }, ++ { 0x0000742C, 0x0000000F }, ++ { 0x0000742C, 0x00000079 }, ++ { 0x00007438, 0x00585941 }, ++ { CS35L41_PWR_CTRL1, 0x00000001, 2000 }, //GLOBAL_EN = 1 ++ { 0x0000742C, 0x000000F9 }, ++ { 0x00007438, 0x00580941 }, ++ { 0x00000040, 0x000000CC }, ++ { 0x00000040, 0x00000033 }, ++}; ++ ++static const struct reg_sequence cs35l41_active_to_safe[] = { ++ { 0x00000040, 0x00000055 }, ++ { 0x00000040, 0x000000AA }, ++ { 0x00007438, 0x00585941 }, ++ { CS35L41_AMP_DIG_VOL_CTRL, 0x0000A678 }, //AMP_VOL_PCM Mute ++ { CS35L41_PWR_CTRL2, 0x00000000 }, //AMP_EN = 0 ++ { CS35L41_PWR_CTRL1, 0x00000000 }, ++ { 0x0000742C, 0x00000009, 2000 }, ++ { 0x00007438, 0x00580941 }, ++ { 0x00000040, 0x000000CC }, ++ { 0x00000040, 0x00000033 }, ++}; ++ ++static const struct reg_sequence cs35l41_reset_to_safe[] = { ++ { 0x00000040, 0x00000055 }, ++ { 0x00000040, 0x000000AA }, ++ { 0x00007438, 0x00585941 }, ++ { 0x00007414, 0x08C82222 }, ++ { 0x0000742C, 0x00000009 }, ++ { 0x00000040, 0x000000CC }, ++ { 0x00000040, 0x00000033 }, ++}; ++ ++static const struct cs35l41_hda_reg_sequence cs35l41_hda_reg_seq_no_bst = { ++ .probe = cs35l41_reset_to_safe, ++ .num_probe = ARRAY_SIZE(cs35l41_reset_to_safe), ++ .open = cs35l41_hda_config, ++ .num_open = ARRAY_SIZE(cs35l41_hda_config), ++ .prepare = cs35l41_safe_to_active, ++ .num_prepare = ARRAY_SIZE(cs35l41_safe_to_active), ++ .cleanup = cs35l41_active_to_safe, ++ .num_cleanup = ARRAY_SIZE(cs35l41_active_to_safe), ++}; ++ ++static const struct cs35l41_hda_reg_sequence cs35l41_hda_reg_seq_ext_bst = { ++ .open = cs35l41_hda_config, ++ .num_open = ARRAY_SIZE(cs35l41_hda_config), ++ .prepare = cs35l41_start_ext_vspk, ++ .num_prepare = ARRAY_SIZE(cs35l41_start_ext_vspk), ++ .cleanup = cs35l41_stop_ext_vspk, ++ .num_cleanup = ARRAY_SIZE(cs35l41_stop_ext_vspk), ++}; ++ ++static const struct cs35l41_hda_reg_sequence cs35l41_hda_reg_seq_int_bst = { ++ .open = cs35l41_hda_config, ++ .num_open = ARRAY_SIZE(cs35l41_hda_config), ++ .prepare = cs35l41_hda_start_bst, ++ .num_prepare = ARRAY_SIZE(cs35l41_hda_start_bst), ++ .cleanup = cs35l41_hda_stop_bst, ++ .num_cleanup = ARRAY_SIZE(cs35l41_hda_stop_bst), ++}; ++ ++static void cs35l41_hda_playback_hook(struct device *dev, int action) ++{ ++ struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); ++ const struct cs35l41_hda_reg_sequence *reg_seq = cs35l41->reg_seq; ++ struct regmap *reg = cs35l41->regmap; ++ int ret = 0; ++ ++ switch (action) { ++ case HDA_GEN_PCM_ACT_OPEN: ++ if (reg_seq->open) ++ ret = regmap_multi_reg_write(reg, reg_seq->open, reg_seq->num_open); ++ break; ++ case HDA_GEN_PCM_ACT_PREPARE: ++ if (reg_seq->prepare) ++ ret = regmap_multi_reg_write(reg, reg_seq->prepare, reg_seq->num_prepare); ++ break; ++ case HDA_GEN_PCM_ACT_CLEANUP: ++ if (reg_seq->cleanup) ++ ret = regmap_multi_reg_write(reg, reg_seq->cleanup, reg_seq->num_cleanup); ++ break; ++ case HDA_GEN_PCM_ACT_CLOSE: ++ if (reg_seq->close) ++ ret = regmap_multi_reg_write(reg, reg_seq->close, reg_seq->num_close); ++ break; ++ } ++ ++ if (ret) ++ dev_warn(cs35l41->dev, "Failed to apply multi reg write: %d\n", ret); ++ ++} ++ ++static int cs35l41_hda_channel_map(struct device *dev, unsigned int tx_num, unsigned int *tx_slot, ++ unsigned int rx_num, unsigned int *rx_slot) ++{ ++ struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); ++ ++ return cs35l41_set_channels(cs35l41->dev, cs35l41->regmap, tx_num, tx_slot, rx_num, ++ rx_slot); ++} ++ ++static int cs35l41_hda_bind(struct device *dev, struct device *master, void *master_data) ++{ ++ struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); ++ struct hda_component *comps = master_data; ++ ++ if (comps && cs35l41->index >= 0 && cs35l41->index < HDA_MAX_COMPONENTS) ++ comps = &comps[cs35l41->index]; ++ else ++ return -EINVAL; ++ ++ if (!comps->dev) { ++ comps->dev = dev; ++ strscpy(comps->name, dev_name(dev), sizeof(comps->name)); ++ comps->playback_hook = cs35l41_hda_playback_hook; ++ comps->set_channel_map = cs35l41_hda_channel_map; ++ return 0; ++ } ++ ++ return -EBUSY; ++} ++ ++static void cs35l41_hda_unbind(struct device *dev, struct device *master, void *master_data) ++{ ++ struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); ++ struct hda_component *comps = master_data; ++ ++ if (comps[cs35l41->index].dev == dev) ++ memset(&comps[cs35l41->index], 0, sizeof(*comps)); ++} ++ ++static const struct component_ops cs35l41_hda_comp_ops = { ++ .bind = cs35l41_hda_bind, ++ .unbind = cs35l41_hda_unbind, ++}; ++ ++static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41, ++ const struct cs35l41_hda_hw_config *hw_cfg) ++{ ++ bool internal_boost = false; ++ int ret; ++ ++ if (!hw_cfg) { ++ cs35l41->reg_seq = &cs35l41_hda_reg_seq_no_bst; ++ return 0; ++ } ++ ++ if (hw_cfg->bst_ind || hw_cfg->bst_cap || hw_cfg->bst_ipk) ++ internal_boost = true; ++ ++ switch (hw_cfg->gpio1_func) { ++ case CS35l41_VSPK_SWITCH: ++ regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL, ++ CS35L41_GPIO1_CTRL_MASK, 1 << CS35L41_GPIO1_CTRL_SHIFT); ++ break; ++ case CS35l41_SYNC: ++ regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL, ++ CS35L41_GPIO1_CTRL_MASK, 2 << CS35L41_GPIO1_CTRL_SHIFT); ++ break; ++ } ++ ++ switch (hw_cfg->gpio2_func) { ++ case CS35L41_INTERRUPT: ++ regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL, ++ CS35L41_GPIO2_CTRL_MASK, 2 << CS35L41_GPIO2_CTRL_SHIFT); ++ break; ++ } ++ ++ if (internal_boost) { ++ cs35l41->reg_seq = &cs35l41_hda_reg_seq_int_bst; ++ if (!(hw_cfg->bst_ind && hw_cfg->bst_cap && hw_cfg->bst_ipk)) ++ return -EINVAL; ++ ret = cs35l41_boost_config(cs35l41->dev, cs35l41->regmap, ++ hw_cfg->bst_ind, hw_cfg->bst_cap, hw_cfg->bst_ipk); ++ if (ret) ++ return ret; ++ } else { ++ cs35l41->reg_seq = &cs35l41_hda_reg_seq_ext_bst; ++ } ++ ++ ret = cs35l41_hda_channel_map(cs35l41->dev, 0, NULL, 1, (unsigned int *)&hw_cfg->spk_pos); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static struct cs35l41_hda_hw_config *cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, ++ const char *hid, int id) ++{ ++ struct cs35l41_hda_hw_config *hw_cfg; ++ u32 values[HDA_MAX_COMPONENTS]; ++ struct acpi_device *adev; ++ struct device *acpi_dev; ++ char *property; ++ size_t nval; ++ int i, ret; ++ ++ adev = acpi_dev_get_first_match_dev(hid, NULL, -1); ++ if (!adev) { ++ dev_err(cs35l41->dev, "Failed to find an ACPI device for %s\n", hid); ++ return ERR_PTR(-ENODEV); ++ } ++ ++ acpi_dev = get_device(acpi_get_first_physical_node(adev)); ++ acpi_dev_put(adev); ++ ++ property = "cirrus,dev-index"; ++ ret = device_property_count_u32(acpi_dev, property); ++ if (ret <= 0) ++ goto no_acpi_dsd; ++ ++ if (ret > ARRAY_SIZE(values)) { ++ ret = -EINVAL; ++ goto err; ++ } ++ nval = ret; ++ ++ ret = device_property_read_u32_array(acpi_dev, property, values, nval); ++ if (ret) ++ goto err; ++ ++ cs35l41->index = -1; ++ for (i = 0; i < nval; i++) { ++ if (values[i] == id) { ++ cs35l41->index = i; ++ break; ++ } ++ } ++ if (cs35l41->index == -1) { ++ dev_err(cs35l41->dev, "No index found in %s\n", property); ++ ret = -ENODEV; ++ goto err; ++ } ++ ++ /* No devm_ version as CLSA0100, in no_acpi_dsd case, can't use devm version */ ++ cs35l41->reset_gpio = fwnode_gpiod_get_index(&adev->fwnode, "reset", cs35l41->index, ++ GPIOD_OUT_LOW, "cs35l41-reset"); ++ ++ hw_cfg = kzalloc(sizeof(*hw_cfg), GFP_KERNEL); ++ if (!hw_cfg) { ++ ret = -ENOMEM; ++ goto err; ++ } ++ ++ property = "cirrus,speaker-position"; ++ ret = device_property_read_u32_array(acpi_dev, property, values, nval); ++ if (ret) ++ goto err_free; ++ hw_cfg->spk_pos = values[cs35l41->index]; ++ ++ property = "cirrus,gpio1-func"; ++ ret = device_property_read_u32_array(acpi_dev, property, values, nval); ++ if (ret) ++ goto err_free; ++ hw_cfg->gpio1_func = values[cs35l41->index]; ++ ++ property = "cirrus,gpio2-func"; ++ ret = device_property_read_u32_array(acpi_dev, property, values, nval); ++ if (ret) ++ goto err_free; ++ hw_cfg->gpio2_func = values[cs35l41->index]; ++ ++ property = "cirrus,boost-peak-milliamp"; ++ ret = device_property_read_u32_array(acpi_dev, property, values, nval); ++ if (ret == 0) ++ hw_cfg->bst_ipk = values[cs35l41->index]; ++ ++ property = "cirrus,boost-ind-nanohenry"; ++ ret = device_property_read_u32_array(acpi_dev, property, values, nval); ++ if (ret == 0) ++ hw_cfg->bst_ind = values[cs35l41->index]; ++ ++ property = "cirrus,boost-cap-microfarad"; ++ ret = device_property_read_u32_array(acpi_dev, property, values, nval); ++ if (ret == 0) ++ hw_cfg->bst_cap = values[cs35l41->index]; ++ ++ put_device(acpi_dev); ++ ++ return hw_cfg; ++ ++err_free: ++ kfree(hw_cfg); ++err: ++ put_device(acpi_dev); ++ dev_err(cs35l41->dev, "Failed property %s: %d\n", property, ret); ++ ++ return ERR_PTR(ret); ++ ++no_acpi_dsd: ++ /* ++ * Device CLSA0100 doesn't have _DSD so a gpiod_get by the label reset won't work. ++ * And devices created by i2c-multi-instantiate don't have their device struct pointing to ++ * the correct fwnode, so acpi_dev must be used here ++ * And devm functions expect that the device requesting the resource has the correct ++ * fwnode ++ */ ++ if (strncmp(hid, "CLSA0100", 8) != 0) ++ return ERR_PTR(-EINVAL); ++ ++ /* check I2C address to assign the index */ ++ cs35l41->index = id == 0x40 ? 0 : 1; ++ cs35l41->reset_gpio = gpiod_get_index(acpi_dev, NULL, 0, GPIOD_OUT_HIGH); ++ cs35l41->vspk_always_on = true; ++ put_device(acpi_dev); ++ ++ return NULL; ++} ++ ++int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq, ++ struct regmap *regmap) ++{ ++ unsigned int int_sts, regid, reg_revid, mtl_revid, chipid, int_status; ++ struct cs35l41_hda_hw_config *acpi_hw_cfg; ++ struct cs35l41_hda *cs35l41; ++ int ret; ++ ++ if (IS_ERR(regmap)) ++ return PTR_ERR(regmap); ++ ++ cs35l41 = devm_kzalloc(dev, sizeof(*cs35l41), GFP_KERNEL); ++ if (!cs35l41) ++ return -ENOMEM; ++ ++ cs35l41->dev = dev; ++ cs35l41->irq = irq; ++ cs35l41->regmap = regmap; ++ dev_set_drvdata(dev, cs35l41); ++ ++ acpi_hw_cfg = cs35l41_hda_read_acpi(cs35l41, device_name, id); ++ if (IS_ERR(acpi_hw_cfg)) ++ return PTR_ERR(acpi_hw_cfg); ++ ++ if (IS_ERR(cs35l41->reset_gpio)) { ++ ret = PTR_ERR(cs35l41->reset_gpio); ++ cs35l41->reset_gpio = NULL; ++ if (ret == -EBUSY) { ++ dev_info(cs35l41->dev, "Reset line busy, assuming shared reset\n"); ++ } else { ++ if (ret != -EPROBE_DEFER) ++ dev_err(cs35l41->dev, "Failed to get reset GPIO: %d\n", ret); ++ goto err; ++ } ++ } ++ if (cs35l41->reset_gpio) { ++ usleep_range(2000, 2100); ++ gpiod_set_value_cansleep(cs35l41->reset_gpio, 1); ++ } ++ ++ usleep_range(2000, 2100); ++ ++ ret = regmap_read_poll_timeout(cs35l41->regmap, CS35L41_IRQ1_STATUS4, int_status, ++ int_status & CS35L41_OTP_BOOT_DONE, 1000, 100000); ++ if (ret) { ++ dev_err(cs35l41->dev, "Failed waiting for OTP_BOOT_DONE: %d\n", ret); ++ goto err; ++ } ++ ++ ret = regmap_read(cs35l41->regmap, CS35L41_IRQ1_STATUS3, &int_sts); ++ if (ret || (int_sts & CS35L41_OTP_BOOT_ERR)) { ++ dev_err(cs35l41->dev, "OTP Boot error\n"); ++ ret = -EIO; ++ goto err; ++ } ++ ++ ret = regmap_read(cs35l41->regmap, CS35L41_DEVID, ®id); ++ if (ret) { ++ dev_err(cs35l41->dev, "Get Device ID failed: %d\n", ret); ++ goto err; ++ } ++ ++ ret = regmap_read(cs35l41->regmap, CS35L41_REVID, ®_revid); ++ if (ret) { ++ dev_err(cs35l41->dev, "Get Revision ID failed: %d\n", ret); ++ goto err; ++ } ++ ++ mtl_revid = reg_revid & CS35L41_MTLREVID_MASK; ++ ++ chipid = (mtl_revid % 2) ? CS35L41R_CHIP_ID : CS35L41_CHIP_ID; ++ if (regid != chipid) { ++ dev_err(cs35l41->dev, "CS35L41 Device ID (%X). Expected ID %X\n", regid, chipid); ++ ret = -ENODEV; ++ goto err; ++ } ++ ++ ret = cs35l41_register_errata_patch(cs35l41->dev, cs35l41->regmap, reg_revid); ++ if (ret) ++ goto err; ++ ++ ret = cs35l41_otp_unpack(cs35l41->dev, cs35l41->regmap); ++ if (ret) { ++ dev_err(cs35l41->dev, "OTP Unpack failed: %d\n", ret); ++ goto err; ++ } ++ ++ ret = cs35l41_hda_apply_properties(cs35l41, acpi_hw_cfg); ++ if (ret) ++ goto err; ++ kfree(acpi_hw_cfg); ++ ++ if (cs35l41->reg_seq->probe) { ++ ret = regmap_register_patch(cs35l41->regmap, cs35l41->reg_seq->probe, ++ cs35l41->reg_seq->num_probe); ++ if (ret) { ++ dev_err(cs35l41->dev, "Fail to apply probe reg patch: %d\n", ret); ++ goto err; ++ } ++ } ++ ++ ret = component_add(cs35l41->dev, &cs35l41_hda_comp_ops); ++ if (ret) { ++ dev_err(cs35l41->dev, "Register component failed: %d\n", ret); ++ goto err; ++ } ++ ++ dev_info(cs35l41->dev, "Cirrus Logic CS35L41 (%x), Revision: %02X\n", regid, reg_revid); ++ ++ return 0; ++ ++err: ++ kfree(acpi_hw_cfg); ++ if (!cs35l41->vspk_always_on) ++ gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); ++ gpiod_put(cs35l41->reset_gpio); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(cs35l41_hda_probe); ++ ++int cs35l41_hda_remove(struct device *dev) ++{ ++ struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); ++ ++ component_del(cs35l41->dev, &cs35l41_hda_comp_ops); ++ ++ if (!cs35l41->vspk_always_on) ++ gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); ++ gpiod_put(cs35l41->reset_gpio); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(cs35l41_hda_remove); ++ ++ ++MODULE_DESCRIPTION("CS35L41 HDA Driver"); ++MODULE_AUTHOR("Lucas Tanure, Cirrus Logic Inc, "); ++MODULE_LICENSE("GPL"); +diff --git a/sound/pci/hda/cs35l41_hda.h b/sound/pci/hda/cs35l41_hda.h +new file mode 100644 +index 000000000000..76c69a8a22f6 +--- /dev/null ++++ b/sound/pci/hda/cs35l41_hda.h +@@ -0,0 +1,69 @@ ++/* SPDX-License-Identifier: GPL-2.0 ++ * ++ * cs35l41_hda.h -- CS35L41 ALSA HDA audio driver ++ * ++ * Copyright 2021 Cirrus Logic, Inc. ++ * ++ * Author: Lucas Tanure ++ */ ++ ++#ifndef __CS35L41_HDA_H__ ++#define __CS35L41_HDA_H__ ++ ++#include ++#include ++#include ++#include ++ ++enum cs35l41_hda_spk_pos { ++ CS35l41_LEFT, ++ CS35l41_RIGHT, ++}; ++ ++enum cs35l41_hda_gpio_function { ++ CS35L41_NOT_USED, ++ CS35l41_VSPK_SWITCH, ++ CS35L41_INTERRUPT, ++ CS35l41_SYNC, ++}; ++ ++struct cs35l41_hda_reg_sequence { ++ const struct reg_sequence *probe; ++ unsigned int num_probe; ++ const struct reg_sequence *open; ++ unsigned int num_open; ++ const struct reg_sequence *prepare; ++ unsigned int num_prepare; ++ const struct reg_sequence *cleanup; ++ unsigned int num_cleanup; ++ const struct reg_sequence *close; ++ unsigned int num_close; ++}; ++ ++struct cs35l41_hda_hw_config { ++ unsigned int spk_pos; ++ unsigned int gpio1_func; ++ unsigned int gpio2_func; ++ int bst_ind; ++ int bst_ipk; ++ int bst_cap; ++}; ++ ++struct cs35l41_hda { ++ struct device *dev; ++ struct regmap *regmap; ++ struct gpio_desc *reset_gpio; ++ const struct cs35l41_hda_reg_sequence *reg_seq; ++ ++ int irq; ++ int index; ++ ++ /* Don't put the AMP in reset of VSPK can not be turned off */ ++ bool vspk_always_on; ++}; ++ ++int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq, ++ struct regmap *regmap); ++int cs35l41_hda_remove(struct device *dev); ++ ++#endif /*__CS35L41_HDA_H__*/ +diff --git a/sound/pci/hda/cs35l41_hda_i2c.c b/sound/pci/hda/cs35l41_hda_i2c.c +new file mode 100644 +index 000000000000..4a9462fb5c14 +--- /dev/null ++++ b/sound/pci/hda/cs35l41_hda_i2c.c +@@ -0,0 +1,66 @@ ++// SPDX-License-Identifier: GPL-2.0 ++// ++// cs35l41.c -- CS35l41 HDA I2C driver ++// ++// Copyright 2021 Cirrus Logic, Inc. ++// ++// Author: Lucas Tanure ++ ++#include ++#include ++#include ++ ++#include "cs35l41_hda.h" ++ ++static int cs35l41_hda_i2c_probe(struct i2c_client *clt, const struct i2c_device_id *id) ++{ ++ const char *device_name; ++ ++ /* Compare against the device name so it works for I2C, normal ACPI ++ * and for ACPI by i2c-multi-instantiate matching cases ++ */ ++ if (strstr(dev_name(&clt->dev), "CLSA0100")) ++ device_name = "CLSA0100"; ++ else if (strstr(dev_name(&clt->dev), "CSC3551")) ++ device_name = "CSC3551"; ++ else ++ return -ENODEV; ++ ++ return cs35l41_hda_probe(&clt->dev, device_name, clt->addr, clt->irq, ++ devm_regmap_init_i2c(clt, &cs35l41_regmap_i2c)); ++} ++ ++static int cs35l41_hda_i2c_remove(struct i2c_client *clt) ++{ ++ return cs35l41_hda_remove(&clt->dev); ++} ++ ++static const struct i2c_device_id cs35l41_hda_i2c_id[] = { ++ { "cs35l41-hda", 0 }, ++ {} ++}; ++ ++#ifdef CONFIG_ACPI ++static const struct acpi_device_id cs35l41_acpi_hda_match[] = { ++ {"CLSA0100", 0 }, ++ {"CSC3551", 0 }, ++ { }, ++}; ++MODULE_DEVICE_TABLE(acpi, cs35l41_acpi_hda_match); ++#endif ++ ++static struct i2c_driver cs35l41_i2c_driver = { ++ .driver = { ++ .name = "cs35l41-hda", ++ .acpi_match_table = ACPI_PTR(cs35l41_acpi_hda_match), ++ }, ++ .id_table = cs35l41_hda_i2c_id, ++ .probe = cs35l41_hda_i2c_probe, ++ .remove = cs35l41_hda_i2c_remove, ++}; ++ ++module_i2c_driver(cs35l41_i2c_driver); ++ ++MODULE_DESCRIPTION("HDA CS35L41 driver"); ++MODULE_AUTHOR("Lucas Tanure "); ++MODULE_LICENSE("GPL"); +diff --git a/sound/pci/hda/cs35l41_hda_spi.c b/sound/pci/hda/cs35l41_hda_spi.c +new file mode 100644 +index 000000000000..77426e96c58f +--- /dev/null ++++ b/sound/pci/hda/cs35l41_hda_spi.c +@@ -0,0 +1,63 @@ ++// SPDX-License-Identifier: GPL-2.0 ++// ++// cs35l41.c -- CS35l41 HDA SPI driver ++// ++// Copyright 2021 Cirrus Logic, Inc. ++// ++// Author: Lucas Tanure ++ ++#include ++#include ++#include ++ ++#include "cs35l41_hda.h" ++ ++static int cs35l41_hda_spi_probe(struct spi_device *spi) ++{ ++ const char *device_name; ++ ++ /* Compare against the device name so it works for SPI, normal ACPI ++ * and for ACPI by spi-multi-instantiate matching cases ++ */ ++ if (strstr(dev_name(&spi->dev), "CSC3551")) ++ device_name = "CSC3551"; ++ else ++ return -ENODEV; ++ ++ return cs35l41_hda_probe(&spi->dev, device_name, spi->chip_select, spi->irq, ++ devm_regmap_init_spi(spi, &cs35l41_regmap_spi)); ++} ++ ++static int cs35l41_hda_spi_remove(struct spi_device *spi) ++{ ++ return cs35l41_hda_remove(&spi->dev); ++} ++ ++static const struct spi_device_id cs35l41_hda_spi_id[] = { ++ { "cs35l41-hda", 0 }, ++ {} ++}; ++ ++#ifdef CONFIG_ACPI ++static const struct acpi_device_id cs35l41_acpi_hda_match[] = { ++ { "CSC3551", 0 }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(acpi, cs35l41_acpi_hda_match); ++#endif ++ ++static struct spi_driver cs35l41_spi_driver = { ++ .driver = { ++ .name = "cs35l41_hda", ++ .acpi_match_table = ACPI_PTR(cs35l41_acpi_hda_match), ++ }, ++ .id_table = cs35l41_hda_spi_id, ++ .probe = cs35l41_hda_spi_probe, ++ .remove = cs35l41_hda_spi_remove, ++}; ++ ++module_spi_driver(cs35l41_spi_driver); ++ ++MODULE_DESCRIPTION("HDA CS35L41 driver"); ++MODULE_AUTHOR("Lucas Tanure "); ++MODULE_LICENSE("GPL"); +diff --git a/sound/pci/hda/hda_component.h b/sound/pci/hda/hda_component.h +new file mode 100644 +index 000000000000..2e52be6db9c2 +--- /dev/null ++++ b/sound/pci/hda/hda_component.h +@@ -0,0 +1,20 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++/* ++ * HD audio Component Binding Interface ++ * ++ * Copyright (C) 2021 Cirrus Logic, Inc. and ++ * Cirrus Logic International Semiconductor Ltd. ++ */ ++ ++#include ++ ++#define HDA_MAX_COMPONENTS 4 ++#define HDA_MAX_NAME_SIZE 50 ++ ++struct hda_component { ++ struct device *dev; ++ char name[HDA_MAX_NAME_SIZE]; ++ void (*playback_hook)(struct device *dev, int action); ++ int (*set_channel_map)(struct device *dev, unsigned int rx_num, unsigned int *rx_slot, ++ unsigned int tx_num, unsigned int *tx_slot); ++}; +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Allow-compilation-test-on-non-ACPI-.patch b/patches.suse/ALSA-hda-cs35l41-Allow-compilation-test-on-non-ACPI-.patch new file mode 100644 index 0000000..ef010ed --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Allow-compilation-test-on-non-ACPI-.patch @@ -0,0 +1,44 @@ +From d60b05b4c7802b45c4f2ac003827384618a17bb4 Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Tue, 12 Jul 2022 18:35:17 +0300 +Subject: [PATCH] ALSA: hda: cs35l41: Allow compilation test on non-ACPI configurations +Git-commit: d60b05b4c7802b45c4f2ac003827384618a17bb4 +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +ACPI is needed only for functioning of this codec on some platforms, +there is no compilation dependency, so make it optional + +Signed-off-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20220712153519.35692-2-andriy.shevchenko@linux.intel.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/Kconfig | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig +index 79ade4787d95..e86cf80bdf96 100644 +--- a/sound/pci/hda/Kconfig ++++ b/sound/pci/hda/Kconfig +@@ -97,7 +97,7 @@ config SND_HDA_SCODEC_CS35L41 + config SND_HDA_SCODEC_CS35L41_I2C + tristate "Build CS35L41 HD-audio side codec support for I2C Bus" + depends on I2C +- depends on ACPI ++ depends on ACPI || COMPILE_TEST + depends on SND_SOC + select SND_HDA_GENERIC + select SND_SOC_CS35L41_LIB +@@ -113,7 +113,7 @@ comment "Set to Y if you want auto-loading the side codec driver" + config SND_HDA_SCODEC_CS35L41_SPI + tristate "Build CS35L41 HD-audio codec support for SPI Bus" + depends on SPI_MASTER +- depends on ACPI ++ depends on ACPI || COMPILE_TEST + depends on SND_SOC + select SND_HDA_GENERIC + select SND_SOC_CS35L41_LIB +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Always-configure-the-DAI.patch b/patches.suse/ALSA-hda-cs35l41-Always-configure-the-DAI.patch new file mode 100644 index 0000000..6274d2f --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Always-configure-the-DAI.patch @@ -0,0 +1,64 @@ +From 0256949baa327b42aa9224bb10c00b17edd84956 Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Wed, 13 Apr 2022 09:37:17 +0100 +Subject: [PATCH] ALSA: hda: cs35l41: Always configure the DAI +Git-commit: 0256949baa327b42aa9224bb10c00b17edd84956 +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +The dai configuration is always the same and should always configured +during the opening the stream. + +Signed-off-by: Lucas Tanure +Link: https://lore.kernel.org/r/20220413083728.10730-6-tanureal@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 10 ++-------- + 1 file changed, 2 insertions(+), 8 deletions(-) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index d2addae8c085..f853530eb385 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -111,8 +111,6 @@ static const struct reg_sequence cs35l41_reset_to_safe[] = { + static const struct cs35l41_hda_reg_sequence cs35l41_hda_reg_seq_no_bst = { + .probe = cs35l41_reset_to_safe, + .num_probe = ARRAY_SIZE(cs35l41_reset_to_safe), +- .open = cs35l41_hda_config, +- .num_open = ARRAY_SIZE(cs35l41_hda_config), + .prepare = cs35l41_safe_to_active, + .num_prepare = ARRAY_SIZE(cs35l41_safe_to_active), + .cleanup = cs35l41_active_to_safe, +@@ -120,8 +118,6 @@ static const struct cs35l41_hda_reg_sequence cs35l41_hda_reg_seq_no_bst = { + }; + + static const struct cs35l41_hda_reg_sequence cs35l41_hda_reg_seq_ext_bst = { +- .open = cs35l41_hda_config, +- .num_open = ARRAY_SIZE(cs35l41_hda_config), + .prepare = cs35l41_start_ext_vspk, + .num_prepare = ARRAY_SIZE(cs35l41_start_ext_vspk), + .cleanup = cs35l41_stop_ext_vspk, +@@ -129,8 +125,6 @@ static const struct cs35l41_hda_reg_sequence cs35l41_hda_reg_seq_ext_bst = { + }; + + static const struct cs35l41_hda_reg_sequence cs35l41_hda_reg_seq_int_bst = { +- .open = cs35l41_hda_config, +- .num_open = ARRAY_SIZE(cs35l41_hda_config), + .prepare = cs35l41_hda_start_bst, + .num_prepare = ARRAY_SIZE(cs35l41_hda_start_bst), + .cleanup = cs35l41_hda_stop_bst, +@@ -146,8 +140,8 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action) + + switch (action) { + case HDA_GEN_PCM_ACT_OPEN: +- if (reg_seq->open) +- ret = regmap_multi_reg_write(reg, reg_seq->open, reg_seq->num_open); ++ ret = regmap_multi_reg_write(reg, cs35l41_hda_config, ++ ARRAY_SIZE(cs35l41_hda_config)); + break; + case HDA_GEN_PCM_ACT_PREPARE: + if (reg_seq->prepare) +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Avoid-overwriting-register-patch.patch b/patches.suse/ALSA-hda-cs35l41-Avoid-overwriting-register-patch.patch new file mode 100644 index 0000000..4f5b178 --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Avoid-overwriting-register-patch.patch @@ -0,0 +1,40 @@ +From 2cb52046d186863e16ac82850c0e225462e493f1 Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Mon, 17 Jan 2022 16:08:25 +0000 +Subject: [PATCH] ALSA: hda: cs35l41: Avoid overwriting register patch +Git-commit: 2cb52046d186863e16ac82850c0e225462e493f1 +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +regmap_register_patch can't be used to apply the probe sequence as a +patch is already registers with the regmap by +cs35l41_register_errata_patch and only a single patch can be attached to +a single regmap. The driver doesn't currently rely on a cache sync to +re-apply this probe sequence so simply switch it to a multi write. + +Fixes: 7b2f3eb492da ("ALSA: hda: cs35l41: Add support for CS35L41 in HDA systems") +Signed-off-by: Charles Keepax +Signed-off-by: Lucas Tanure +Link: https://lore.kernel.org/r/20220117160830.709403-1-tanureal@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index 30b40d865863..c47c5f0b4e59 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -480,7 +480,7 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i + acpi_hw_cfg = NULL; + + if (cs35l41->reg_seq->probe) { +- ret = regmap_register_patch(cs35l41->regmap, cs35l41->reg_seq->probe, ++ ret = regmap_multi_reg_write(cs35l41->regmap, cs35l41->reg_seq->probe, + cs35l41->reg_seq->num_probe); + if (ret) { + dev_err(cs35l41->dev, "Fail to apply probe reg patch: %d\n", ret); +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Clarify-support-for-CSC3551-without.patch b/patches.suse/ALSA-hda-cs35l41-Clarify-support-for-CSC3551-without.patch new file mode 100644 index 0000000..c042800 --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Clarify-support-for-CSC3551-without.patch @@ -0,0 +1,39 @@ +From 4d4c4bff4f8ed79d95e0592aed6c6144d558a236 Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Mon, 15 Aug 2022 17:29:06 +0100 +Subject: [PATCH] ALSA: hda: cs35l41: Clarify support for CSC3551 without _DSD Properties +Git-commit: 4d4c4bff4f8ed79d95e0592aed6c6144d558a236 +Patch-mainline: v6.0-rc2 +References: bsc#1203699 + +For devices which use HID CSC3551, correct ACPI _DSD properties are +required to be able support those systems. +Add error message to clarify this. + +Signed-off-by: Stefan Binding +Link: https://lore.kernel.org/r/20220815162906.463108-1-sbinding@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index 129bffb431c2..15e2a0009080 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -1163,6 +1163,11 @@ static int cs35l41_no_acpi_dsd(struct cs35l41_hda *cs35l41, struct device *physd + hw_cfg->gpio1.func = CS35l41_VSPK_SWITCH; + hw_cfg->gpio1.valid = true; + } else { ++ /* ++ * Note: CLSA010(0/1) are special cases which use a slightly different design. ++ * All other HIDs e.g. CSC3551 require valid ACPI _DSD properties to be supported. ++ */ ++ dev_err(cs35l41->dev, "Error: ACPI _DSD Properties are missing for HID %s.\n", hid); + hw_cfg->valid = false; + hw_cfg->gpio1.valid = false; + hw_cfg->gpio2.valid = false; +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Consolidate-selections-under-SND_HD.patch b/patches.suse/ALSA-hda-cs35l41-Consolidate-selections-under-SND_HD.patch new file mode 100644 index 0000000..647e7d3 --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Consolidate-selections-under-SND_HD.patch @@ -0,0 +1,56 @@ +From 33c1f401939c66858157c0665dc07ad9596cd1bd Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Tue, 12 Jul 2022 18:35:19 +0300 +Subject: [PATCH] ALSA: hda: cs35l41: Consolidate selections under SND_HDA_SCODEC_CS35L41 +Git-commit: 33c1f401939c66858157c0665dc07ad9596cd1bd +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +Selections can be propagated via selections, while dependencies are not. +Hence, consolidate selections under the SND_HDA_SCODEC_CS35L41 option. + +Signed-off-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20220712153519.35692-4-andriy.shevchenko@linux.intel.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/Kconfig | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig +index e86cf80bdf96..8b73a12d356f 100644 +--- a/sound/pci/hda/Kconfig ++++ b/sound/pci/hda/Kconfig +@@ -93,16 +93,16 @@ config SND_HDA_PATCH_LOADER + + config SND_HDA_SCODEC_CS35L41 + tristate ++ select SND_HDA_GENERIC ++ select REGMAP_IRQ + + config SND_HDA_SCODEC_CS35L41_I2C + tristate "Build CS35L41 HD-audio side codec support for I2C Bus" + depends on I2C + depends on ACPI || COMPILE_TEST + depends on SND_SOC +- select SND_HDA_GENERIC + select SND_SOC_CS35L41_LIB + select SND_HDA_SCODEC_CS35L41 +- select REGMAP_IRQ + help + Say Y or M here to include CS35L41 I2C HD-audio side codec support + in snd-hda-intel driver, such as ALC287. +@@ -115,10 +115,8 @@ config SND_HDA_SCODEC_CS35L41_SPI + depends on SPI_MASTER + depends on ACPI || COMPILE_TEST + depends on SND_SOC +- select SND_HDA_GENERIC + select SND_SOC_CS35L41_LIB + select SND_HDA_SCODEC_CS35L41 +- select REGMAP_IRQ + help + Say Y or M here to include CS35L41 SPI HD-audio side codec support + in snd-hda-intel driver, such as ALC287. +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Don-t-dereference-fwnode-handle.patch b/patches.suse/ALSA-hda-cs35l41-Don-t-dereference-fwnode-handle.patch new file mode 100644 index 0000000..9eb1d19 --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Don-t-dereference-fwnode-handle.patch @@ -0,0 +1,35 @@ +From 20bcf721068f6418607283cdb0c16cf0b606cfc1 Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Tue, 12 Jul 2022 18:35:16 +0300 +Subject: [PATCH] ALSA: hda: cs35l41: Don't dereference fwnode handle +Git-commit: 20bcf721068f6418607283cdb0c16cf0b606cfc1 +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +Use acpi_fwnode_handle() instead of dereferencing an fwnode handle directly, +which is a better coding practice. + +Signed-off-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20220712153519.35692-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index 49b25432a9f5..1a1afa0725e0 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -347,7 +347,7 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i + /* To use the same release code for all laptop variants we can't use devm_ version of + * gpiod_get here, as CLSA010* don't have a fully functional bios with an _DSD node + */ +- cs35l41->reset_gpio = fwnode_gpiod_get_index(&adev->fwnode, "reset", cs35l41->index, ++ cs35l41->reset_gpio = fwnode_gpiod_get_index(acpi_fwnode_handle(adev), "reset", cs35l41->index, + GPIOD_OUT_LOW, "cs35l41-reset"); + + property = "cirrus,speaker-position"; +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Drop-wrong-use-of-ACPI_PTR.patch b/patches.suse/ALSA-hda-cs35l41-Drop-wrong-use-of-ACPI_PTR.patch new file mode 100644 index 0000000..e851e02 --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Drop-wrong-use-of-ACPI_PTR.patch @@ -0,0 +1,96 @@ +From 931c940fc5d96e5ef7a2188abfb14e7c3ab1290e Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Tue, 12 Jul 2022 18:35:18 +0300 +Subject: [PATCH] ALSA: hda: cs35l41: Drop wrong use of ACPI_PTR() +Git-commit: 931c940fc5d96e5ef7a2188abfb14e7c3ab1290e +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +ACPI_PTR() is more harmful than helpful. For example, in this case +if CONFIG_ACPI=n, the ID table left unused which is not what we want. + +Instead of adding ifdeffery or attribute here and there, drop ACPI_PTR(). + +Signed-off-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20220712153519.35692-3-andriy.shevchenko@linux.intel.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda_i2c.c | 8 +++----- + sound/pci/hda/cs35l41_hda_spi.c | 8 +++----- + 2 files changed, 6 insertions(+), 10 deletions(-) + +diff --git a/sound/pci/hda/cs35l41_hda_i2c.c b/sound/pci/hda/cs35l41_hda_i2c.c +index ec626e0fbedc..df39fc76e6be 100644 +--- a/sound/pci/hda/cs35l41_hda_i2c.c ++++ b/sound/pci/hda/cs35l41_hda_i2c.c +@@ -6,9 +6,9 @@ + // + // Author: Lucas Tanure + ++#include + #include + #include +-#include + + #include "cs35l41_hda.h" + +@@ -43,19 +43,17 @@ static const struct i2c_device_id cs35l41_hda_i2c_id[] = { + {} + }; + +-#ifdef CONFIG_ACPI + static const struct acpi_device_id cs35l41_acpi_hda_match[] = { + {"CLSA0100", 0 }, + {"CSC3551", 0 }, +- { }, ++ {} + }; + MODULE_DEVICE_TABLE(acpi, cs35l41_acpi_hda_match); +-#endif + + static struct i2c_driver cs35l41_i2c_driver = { + .driver = { + .name = "cs35l41-hda", +- .acpi_match_table = ACPI_PTR(cs35l41_acpi_hda_match), ++ .acpi_match_table = cs35l41_acpi_hda_match, + }, + .id_table = cs35l41_hda_i2c_id, + .probe = cs35l41_hda_i2c_probe, +diff --git a/sound/pci/hda/cs35l41_hda_spi.c b/sound/pci/hda/cs35l41_hda_spi.c +index 3a1472e1bc24..2f5afad3719e 100644 +--- a/sound/pci/hda/cs35l41_hda_spi.c ++++ b/sound/pci/hda/cs35l41_hda_spi.c +@@ -6,7 +6,7 @@ + // + // Author: Lucas Tanure + +-#include ++#include + #include + #include + +@@ -39,18 +39,16 @@ static const struct spi_device_id cs35l41_hda_spi_id[] = { + {} + }; + +-#ifdef CONFIG_ACPI + static const struct acpi_device_id cs35l41_acpi_hda_match[] = { + { "CSC3551", 0 }, +- {}, ++ {} + }; + MODULE_DEVICE_TABLE(acpi, cs35l41_acpi_hda_match); +-#endif + + static struct spi_driver cs35l41_spi_driver = { + .driver = { + .name = "cs35l41-hda", +- .acpi_match_table = ACPI_PTR(cs35l41_acpi_hda_match), ++ .acpi_match_table = cs35l41_acpi_hda_match, + }, + .id_table = cs35l41_hda_spi_id, + .probe = cs35l41_hda_spi_probe, +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Enable-GPIO2-Interrupt-for-CLSA0100.patch b/patches.suse/ALSA-hda-cs35l41-Enable-GPIO2-Interrupt-for-CLSA0100.patch new file mode 100644 index 0000000..452328e --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Enable-GPIO2-Interrupt-for-CLSA0100.patch @@ -0,0 +1,37 @@ +From de8cab7b38d74e7f2bec7f3abe129c31354a5dcf Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Mon, 9 May 2022 22:46:42 +0100 +Subject: [PATCH] ALSA: hda: cs35l41: Enable GPIO2 Interrupt for CLSA0100 laptops +Git-commit: de8cab7b38d74e7f2bec7f3abe129c31354a5dcf +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +CLSA0100 Laptop does not contain configuration inside ACPI, +instead the hardware configuration needs to be hardcoded. +Hardcode GPIO2 Interrupt in the driver for CSLA0100. + +Signed-off-by: Stefan Binding +Signed-off-by: Vitaly Rodionov +Link: https://lore.kernel.org/r/20220509214703.4482-6-vitalyr@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index bd52e0c2c772..2608bf4a6851 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -412,6 +412,8 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i + cs35l41->hw_cfg.spk_pos = cs35l41->index; + cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 0, GPIOD_OUT_HIGH); + cs35l41->hw_cfg.bst_type = CS35L41_EXT_BOOST_NO_VSPK_SWITCH; ++ hw_cfg->gpio2.func = CS35L41_GPIO2_INT_OPEN_DRAIN; ++ hw_cfg->gpio2.valid = true; + cs35l41->hw_cfg.valid = true; + put_device(physdev); + +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Fix-I2S-params-comments.patch b/patches.suse/ALSA-hda-cs35l41-Fix-I2S-params-comments.patch new file mode 100644 index 0000000..b2487d1 --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Fix-I2S-params-comments.patch @@ -0,0 +1,39 @@ +From 1e616a9c468a481616b0d00f35674865ec99296f Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Wed, 13 Apr 2022 09:37:16 +0100 +Subject: [PATCH] ALSA: hda: cs35l41: Fix I2S params comments +Git-commit: 1e616a9c468a481616b0d00f35674865ec99296f +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +Fix clock and slot size comments + +Signed-off-by: Lucas Tanure +Link: https://lore.kernel.org/r/20220413083728.10730-5-tanureal@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index e00ceaca79c0..d2addae8c085 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -17,11 +17,11 @@ + #include "cs35l41_hda.h" + + static const struct reg_sequence cs35l41_hda_config[] = { +- { CS35L41_PLL_CLK_CTRL, 0x00000430 }, // 3200000Hz, BCLK Input, PLL_REFCLK_EN = 1 ++ { CS35L41_PLL_CLK_CTRL, 0x00000430 }, // 3072000Hz, BCLK Input, PLL_REFCLK_EN = 1 + { CS35L41_GLOBAL_CLK_CTRL, 0x00000003 }, // GLOBAL_FS = 48 kHz + { CS35L41_SP_ENABLES, 0x00010000 }, // ASP_RX1_EN = 1 + { CS35L41_SP_RATE_CTRL, 0x00000021 }, // ASP_BCLK_FREQ = 3.072 MHz +- { CS35L41_SP_FORMAT, 0x20200200 }, // 24 bits, I2S, BCLK Slave, FSYNC Slave ++ { CS35L41_SP_FORMAT, 0x20200200 }, // 32 bits RX/TX slots, I2S, clk consumer + { CS35L41_DAC_PCM1_SRC, 0x00000008 }, // DACPCM1_SRC = ASPRX1 + { CS35L41_AMP_DIG_VOL_CTRL, 0x00000000 }, // AMP_VOL_PCM 0.0 dB + { CS35L41_AMP_GAIN_CTRL, 0x00000084 }, // AMP_GAIN_PCM 4.5 dB +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Fix-comments-wrt-serial-multi-insta.patch b/patches.suse/ALSA-hda-cs35l41-Fix-comments-wrt-serial-multi-insta.patch new file mode 100644 index 0000000..f661633 --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Fix-comments-wrt-serial-multi-insta.patch @@ -0,0 +1,93 @@ +From 642999365da3b7cd5552ec758d6e1bb6f2f465d8 Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Mon, 11 Jul 2022 13:01:29 +0300 +Subject: [PATCH] ALSA: hda: cs35l41: Fix comments wrt serial-multi-instantiate reference +Git-commit: 642999365da3b7cd5552ec758d6e1bb6f2f465d8 +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +The comments are inconsistent and point to the wrong driver name. +The initially named i2c-multi-instantiate it was renamed to the +serial-multi-instantiate exactly due to support of the platforms +with multiple CS35L41 codecs. + +Fix comments accordingly. + +While at it, drop file names from the files. + +Signed-off-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20220711100129.37326-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 4 ++-- + sound/pci/hda/cs35l41_hda_i2c.c | 7 ++++--- + sound/pci/hda/cs35l41_hda_spi.c | 7 ++++--- + 3 files changed, 10 insertions(+), 8 deletions(-) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index cce27a86267f..a9923a8818a2 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -415,8 +415,8 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i + no_acpi_dsd: + /* + * Device CLSA0100 doesn't have _DSD so a gpiod_get by the label reset won't work. +- * And devices created by i2c-multi-instantiate don't have their device struct pointing to +- * the correct fwnode, so acpi_dev must be used here. ++ * And devices created by serial-multi-instantiate don't have their device struct ++ * pointing to the correct fwnode, so acpi_dev must be used here. + * And devm functions expect that the device requesting the resource has the correct + * fwnode. + */ +diff --git a/sound/pci/hda/cs35l41_hda_i2c.c b/sound/pci/hda/cs35l41_hda_i2c.c +index e810b278fb91..ec626e0fbedc 100644 +--- a/sound/pci/hda/cs35l41_hda_i2c.c ++++ b/sound/pci/hda/cs35l41_hda_i2c.c +@@ -1,6 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0 + // +-// cs35l41.c -- CS35l41 HDA I2C driver ++// CS35l41 HDA I2C driver + // + // Copyright 2021 Cirrus Logic, Inc. + // +@@ -16,8 +16,9 @@ static int cs35l41_hda_i2c_probe(struct i2c_client *clt, const struct i2c_device + { + const char *device_name; + +- /* Compare against the device name so it works for I2C, normal ACPI +- * and for ACPI by i2c-multi-instantiate matching cases ++ /* ++ * Compare against the device name so it works for SPI, normal ACPI ++ * and for ACPI by serial-multi-instantiate matching cases. + */ + if (strstr(dev_name(&clt->dev), "CLSA0100")) + device_name = "CLSA0100"; +diff --git a/sound/pci/hda/cs35l41_hda_spi.c b/sound/pci/hda/cs35l41_hda_spi.c +index 22e088f28438..3a1472e1bc24 100644 +--- a/sound/pci/hda/cs35l41_hda_spi.c ++++ b/sound/pci/hda/cs35l41_hda_spi.c +@@ -1,6 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0 + // +-// cs35l41.c -- CS35l41 HDA SPI driver ++// CS35l41 HDA SPI driver + // + // Copyright 2021 Cirrus Logic, Inc. + // +@@ -16,8 +16,9 @@ static int cs35l41_hda_spi_probe(struct spi_device *spi) + { + const char *device_name; + +- /* Compare against the device name so it works for SPI, normal ACPI +- * and for ACPI by spi-multi-instantiate matching cases ++ /* ++ * Compare against the device name so it works for SPI, normal ACPI ++ * and for ACPI by serial-multi-instantiate matching cases. + */ + if (strstr(dev_name(&spi->dev), "CSC3551")) + device_name = "CSC3551"; +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Fix-error-in-spi-cs35l41-hda-driver.patch b/patches.suse/ALSA-hda-cs35l41-Fix-error-in-spi-cs35l41-hda-driver.patch new file mode 100644 index 0000000..bfbc25f --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Fix-error-in-spi-cs35l41-hda-driver.patch @@ -0,0 +1,36 @@ +From c960aa6aa3ccfc59293fb0850a1addf7646d790a Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Mon, 9 May 2022 22:46:38 +0100 +Subject: [PATCH] ALSA: hda: cs35l41: Fix error in spi cs35l41 hda driver name +Git-commit: c960aa6aa3ccfc59293fb0850a1addf7646d790a +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +For consistency, rename spi cs35l41 hda driver name so that +it matches i2c. + +Signed-off-by: Stefan Binding +Signed-off-by: Vitaly Rodionov +Link: https://lore.kernel.org/r/20220509214703.4482-2-vitalyr@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda_spi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/pci/hda/cs35l41_hda_spi.c b/sound/pci/hda/cs35l41_hda_spi.c +index 50eb6c0e6658..22e088f28438 100644 +--- a/sound/pci/hda/cs35l41_hda_spi.c ++++ b/sound/pci/hda/cs35l41_hda_spi.c +@@ -48,7 +48,7 @@ MODULE_DEVICE_TABLE(acpi, cs35l41_acpi_hda_match); + + static struct spi_driver cs35l41_spi_driver = { + .driver = { +- .name = "cs35l41_hda", ++ .name = "cs35l41-hda", + .acpi_match_table = ACPI_PTR(cs35l41_acpi_hda_match), + }, + .id_table = cs35l41_hda_spi_id, +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Handle-all-external-boost-setups-th.patch b/patches.suse/ALSA-hda-cs35l41-Handle-all-external-boost-setups-th.patch new file mode 100644 index 0000000..51250df --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Handle-all-external-boost-setups-th.patch @@ -0,0 +1,161 @@ +From 734b965e67c637c1c59206e302985eea413d588c Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Wed, 13 Apr 2022 09:37:25 +0100 +Subject: [PATCH] ALSA: hda: cs35l41: Handle all external boost setups the same way +Git-commit: 734b965e67c637c1c59206e302985eea413d588c +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +External boost enables sequences for devices with or without GPIO1 as +VSPK switch are the same if devices are put in safe mode from reset. +As a previous patch put all external boost devices into safe mode +from reset, all external boost devices can be handled in the same way +for stream open and close. + +The only difference is that devices without an VSPK switch can not be +put in reset and devices with it can be put into reset if a +configuration is applied. +The function cs35l41_hda_safe_reset is created to handle the safe reset +of the chip, and as systems without VSPK switch are not supported +anymore, only the CS35L41 HDA driver should check its return. + +Signed-off-by: Lucas Tanure +Link: https://lore.kernel.org/r/20220413083728.10730-14-tanureal@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 60 +++++++++++++++---------------------- + 1 file changed, 24 insertions(+), 36 deletions(-) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index 3294837ff606..e54b5fbb6fb5 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -32,33 +32,9 @@ static const struct reg_sequence cs35l41_hda_mute[] = { + { CS35L41_AMP_DIG_VOL_CTRL, 0x0000A678 }, // AMP_VOL_PCM Mute + }; + +-// only on amps where GPIO1 is used to control ext. VSPK switch +-static const struct reg_sequence cs35l41_start_ext_vspk[] = { ++static const struct reg_sequence cs35l41_safe_to_reset[] = { + { 0x00000040, 0x00000055 }, + { 0x00000040, 0x000000AA }, +- { 0x00007438, 0x00585941 }, +- { 0x00007414, 0x08C82222 }, +- { 0x0000742C, 0x00000009 }, +- { 0x00011008, 0x00008001 }, +- { 0x0000742C, 0x0000000F }, +- { 0x0000742C, 0x00000079 }, +- { 0x00007438, 0x00585941 }, +- { CS35L41_PWR_CTRL1, 0x00000001, 3000}, // set GLOBAL_EN = 1 +- { 0x0000742C, 0x000000F9 }, +- { 0x00007438, 0x00580941 }, +- { 0x00000040, 0x000000CC }, +- { 0x00000040, 0x00000033 }, +-}; +- +-//only on amps where GPIO1 is used to control ext. VSPK switch +-static const struct reg_sequence cs35l41_stop_ext_vspk[] = { +- { 0x00000040, 0x00000055 }, +- { 0x00000040, 0x000000AA }, +- { 0x00007438, 0x00585941 }, +- { 0x00002014, 0x00000000, 3000}, // set GLOBAL_EN = 0 +- { 0x0000742C, 0x00000009 }, +- { 0x00007438, 0x00580941 }, +- { 0x00011008, 0x00000001 }, + { 0x0000393C, 0x000000C0, 6000}, + { 0x0000393C, 0x00000000 }, + { 0x00007414, 0x00C82222 }, +@@ -73,7 +49,7 @@ static const struct reg_sequence cs35l41_safe_to_active[] = { + { 0x0000742C, 0x0000000F }, + { 0x0000742C, 0x00000079 }, + { 0x00007438, 0x00585941 }, +- { CS35L41_PWR_CTRL1, 0x00000001, 2000 }, // GLOBAL_EN = 1 ++ { CS35L41_PWR_CTRL1, 0x00000001, 3000 }, // GLOBAL_EN = 1 + { 0x0000742C, 0x000000F9 }, + { 0x00007438, 0x00580941 }, + { 0x00000040, 0x000000CC }, +@@ -85,7 +61,7 @@ static const struct reg_sequence cs35l41_active_to_safe[] = { + { 0x00000040, 0x000000AA }, + { 0x00007438, 0x00585941 }, + { CS35L41_PWR_CTRL1, 0x00000000 }, +- { 0x0000742C, 0x00000009, 2000 }, ++ { 0x0000742C, 0x00000009, 3000 }, + { 0x00007438, 0x00580941 }, + { 0x00000040, 0x000000CC }, + { 0x00000040, 0x00000033 }, +@@ -101,6 +77,21 @@ static const struct reg_sequence cs35l41_reset_to_safe[] = { + { 0x00000040, 0x00000033 }, + }; + ++static bool cs35l41_hda_safe_reset(struct cs35l41_hda *cs35l41) ++{ ++ switch (cs35l41->hw_cfg.bst_type) { ++ case CS35L41_EXT_BOOST: ++ regmap_write(cs35l41->regmap, CS35L41_GPIO1_CTRL1, 0x00000001); ++ regmap_multi_reg_write(cs35l41->regmap, cs35l41_safe_to_reset, ++ ARRAY_SIZE(cs35l41_safe_to_reset)); ++ return true; ++ case CS35L41_EXT_BOOST_NO_VSPK_SWITCH: ++ return false; ++ default: ++ return true; ++ } ++}; ++ + static int cs35l41_hda_global_enable(struct cs35l41_hda *cs35l41, int enable) + { + int ret; +@@ -113,13 +104,6 @@ static int cs35l41_hda_global_enable(struct cs35l41_hda *cs35l41, int enable) + usleep_range(3000, 3100); + break; + case CS35L41_EXT_BOOST: +- if (enable) +- ret = regmap_multi_reg_write(cs35l41->regmap, cs35l41_start_ext_vspk, +- ARRAY_SIZE(cs35l41_start_ext_vspk)); +- else +- ret = regmap_multi_reg_write(cs35l41->regmap, cs35l41_stop_ext_vspk, +- ARRAY_SIZE(cs35l41_stop_ext_vspk)); +- break; + case CS35L41_EXT_BOOST_NO_VSPK_SWITCH: + if (enable) + ret = regmap_multi_reg_write(cs35l41->regmap, cs35l41_safe_to_active, +@@ -147,6 +131,8 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action) + regmap_multi_reg_write(reg, cs35l41_hda_config, ARRAY_SIZE(cs35l41_hda_config)); + ret = regmap_update_bits(reg, CS35L41_PWR_CTRL2, + CS35L41_AMP_EN_MASK, 1 << CS35L41_AMP_EN_SHIFT); ++ if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST) ++ regmap_write(reg, CS35L41_GPIO1_CTRL1, 0x00008001); + break; + case HDA_GEN_PCM_ACT_PREPARE: + ret = cs35l41_hda_global_enable(cs35l41, 1); +@@ -158,6 +144,8 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action) + case HDA_GEN_PCM_ACT_CLOSE: + ret = regmap_update_bits(reg, CS35L41_PWR_CTRL2, + CS35L41_AMP_EN_MASK, 0 << CS35L41_AMP_EN_SHIFT); ++ if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST) ++ regmap_write(reg, CS35L41_GPIO1_CTRL1, 0x00000001); + break; + default: + dev_warn(cs35l41->dev, "Playback action not supported: %d\n", action); +@@ -517,7 +505,7 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i + return 0; + + err: +- if (cs35l41->hw_cfg.bst_type != CS35L41_EXT_BOOST_NO_VSPK_SWITCH) ++ if (cs35l41_hda_safe_reset(cs35l41)) + gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); + gpiod_put(cs35l41->reset_gpio); + +@@ -531,7 +519,7 @@ void cs35l41_hda_remove(struct device *dev) + + component_del(cs35l41->dev, &cs35l41_hda_comp_ops); + +- if (cs35l41->hw_cfg.bst_type != CS35L41_EXT_BOOST_NO_VSPK_SWITCH) ++ if (cs35l41_hda_safe_reset(cs35l41)) + gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); + gpiod_put(cs35l41->reset_gpio); + } +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Improve-dev_err_probe-messaging.patch b/patches.suse/ALSA-hda-cs35l41-Improve-dev_err_probe-messaging.patch new file mode 100644 index 0000000..f95c9a3 --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Improve-dev_err_probe-messaging.patch @@ -0,0 +1,48 @@ +From e35cd6881dd56d5ad7711d23faab668268e17555 Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Mon, 11 Jul 2022 12:52:16 +0300 +Subject: [PATCH] ALSA: hda: cs35l41: Improve dev_err_probe() messaging +Git-commit: e35cd6881dd56d5ad7711d23faab668268e17555 +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +Drop duplicate print of returned value in the messages and use pattern +return dev_err_probe(...) where it's possible. + +Signed-off-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20220711095219.36915-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index a9923a8818a2..49b25432a9f5 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -460,10 +460,8 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i + dev_set_drvdata(dev, cs35l41); + + ret = cs35l41_hda_read_acpi(cs35l41, device_name, id); +- if (ret) { +- dev_err_probe(cs35l41->dev, ret, "Platform not supported %d\n", ret); +- return ret; +- } ++ if (ret) ++ return dev_err_probe(cs35l41->dev, ret, "Platform not supported\n"); + + if (IS_ERR(cs35l41->reset_gpio)) { + ret = PTR_ERR(cs35l41->reset_gpio); +@@ -471,7 +469,7 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i + if (ret == -EBUSY) { + dev_info(cs35l41->dev, "Reset line busy, assuming shared reset\n"); + } else { +- dev_err_probe(cs35l41->dev, ret, "Failed to get reset GPIO: %d\n", ret); ++ dev_err_probe(cs35l41->dev, ret, "Failed to get reset GPIO\n"); + goto err; + } + } +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Make-cs35l41_hda_remove-return-void.patch b/patches.suse/ALSA-hda-cs35l41-Make-cs35l41_hda_remove-return-void.patch new file mode 100644 index 0000000..8e1f35e --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Make-cs35l41_hda_remove-return-void.patch @@ -0,0 +1,96 @@ +From 85c25662d18903874fad585d17fc398a7ba37ab0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= +Date: Mon, 17 Jan 2022 23:00:55 +0100 +Subject: [PATCH] ALSA: hda: cs35l41: Make cs35l41_hda_remove() return void +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 85c25662d18903874fad585d17fc398a7ba37ab0 +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +Up to now cs35l41_hda_remove() returns zero unconditionally. Make it +return void instead which makes it easier to see in the callers that +there is no error to handle. + +Also the return value of i2c and spi remove callbacks is ignored anyway. + +Signed-off-by: Uwe Kleine-König +Reviewed-by: Lucas Tanure +Link: https://lore.kernel.org/r/20220117220055.120955-1-u.kleine-koenig@pengutronix.de +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 4 +--- + sound/pci/hda/cs35l41_hda.h | 2 +- + sound/pci/hda/cs35l41_hda_i2c.c | 4 +++- + sound/pci/hda/cs35l41_hda_spi.c | 4 +++- + 4 files changed, 8 insertions(+), 6 deletions(-) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index 3f9ddfb4eaf3..718595380868 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -525,7 +525,7 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i + } + EXPORT_SYMBOL_NS_GPL(cs35l41_hda_probe, SND_HDA_SCODEC_CS35L41); + +-int cs35l41_hda_remove(struct device *dev) ++void cs35l41_hda_remove(struct device *dev) + { + struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); + +@@ -534,8 +534,6 @@ int cs35l41_hda_remove(struct device *dev) + if (!cs35l41->vspk_always_on) + gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); + gpiod_put(cs35l41->reset_gpio); +- +- return 0; + } + EXPORT_SYMBOL_NS_GPL(cs35l41_hda_remove, SND_HDA_SCODEC_CS35L41); + +diff --git a/sound/pci/hda/cs35l41_hda.h b/sound/pci/hda/cs35l41_hda.h +index 640afc98b686..74951001501c 100644 +--- a/sound/pci/hda/cs35l41_hda.h ++++ b/sound/pci/hda/cs35l41_hda.h +@@ -64,6 +64,6 @@ struct cs35l41_hda { + + int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq, + struct regmap *regmap); +-int cs35l41_hda_remove(struct device *dev); ++void cs35l41_hda_remove(struct device *dev); + + #endif /*__CS35L41_HDA_H__*/ +diff --git a/sound/pci/hda/cs35l41_hda_i2c.c b/sound/pci/hda/cs35l41_hda_i2c.c +index c2397dc53e78..e810b278fb91 100644 +--- a/sound/pci/hda/cs35l41_hda_i2c.c ++++ b/sound/pci/hda/cs35l41_hda_i2c.c +@@ -32,7 +32,9 @@ static int cs35l41_hda_i2c_probe(struct i2c_client *clt, const struct i2c_device + + static int cs35l41_hda_i2c_remove(struct i2c_client *clt) + { +- return cs35l41_hda_remove(&clt->dev); ++ cs35l41_hda_remove(&clt->dev); ++ ++ return 0; + } + + static const struct i2c_device_id cs35l41_hda_i2c_id[] = { +diff --git a/sound/pci/hda/cs35l41_hda_spi.c b/sound/pci/hda/cs35l41_hda_spi.c +index 36815ab4e461..9f8123893cc8 100644 +--- a/sound/pci/hda/cs35l41_hda_spi.c ++++ b/sound/pci/hda/cs35l41_hda_spi.c +@@ -30,7 +30,9 @@ static int cs35l41_hda_spi_probe(struct spi_device *spi) + + static int cs35l41_hda_spi_remove(struct spi_device *spi) + { +- return cs35l41_hda_remove(&spi->dev); ++ cs35l41_hda_remove(&spi->dev); ++ ++ return 0; + } + + static const struct spi_device_id cs35l41_hda_spi_id[] = { +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Make-use-of-the-helper-function-dev.patch b/patches.suse/ALSA-hda-cs35l41-Make-use-of-the-helper-function-dev.patch new file mode 100644 index 0000000..922222e --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Make-use-of-the-helper-function-dev.patch @@ -0,0 +1,39 @@ +From a025df02ce424fa77f6bc6aa195db21677e11274 Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Mon, 17 Jan 2022 16:08:29 +0000 +Subject: [PATCH] ALSA: hda: cs35l41: Make use of the helper function dev_err_probe() +Git-commit: a025df02ce424fa77f6bc6aa195db21677e11274 +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +When possible use dev_err_probe help to properly deal with the +PROBE_DEFER error, the benefit is that DEFER issue will be logged +in the devices_deferred debugfs file. +Using dev_err_probe() can reduce code size, and the error value +gets printed. + +Signed-off-by: Lucas Tanure +Link: https://lore.kernel.org/r/20220117160830.709403-5-tanureal@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index 82f982f574a9..c317b392c3e3 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -429,8 +429,7 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i + if (ret == -EBUSY) { + dev_info(cs35l41->dev, "Reset line busy, assuming shared reset\n"); + } else { +- if (ret != -EPROBE_DEFER) +- dev_err(cs35l41->dev, "Failed to get reset GPIO: %d\n", ret); ++ dev_err_probe(cs35l41->dev, ret, "Failed to get reset GPIO: %d\n", ret); + goto err; + } + } +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Move-boost-config-to-initialization.patch b/patches.suse/ALSA-hda-cs35l41-Move-boost-config-to-initialization.patch new file mode 100644 index 0000000..fd9529a --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Move-boost-config-to-initialization.patch @@ -0,0 +1,96 @@ +From 5fdb68a7618e3c25816d458e07fd102803493400 Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Wed, 13 Apr 2022 09:37:22 +0100 +Subject: [PATCH] ALSA: hda: cs35l41: Move boost config to initialization code +Git-commit: 5fdb68a7618e3c25816d458e07fd102803493400 +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +Having CS35L41_PWR_CTRL2 on cs35l41_hda_config overwrites the boost +configuration for internal boost. +So move it to the initialization part and use regmap_update_bits to +only change the correct bits. + +Signed-off-by: Lucas Tanure +Link: https://lore.kernel.org/r/20220413083728.10730-11-tanureal@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + include/sound/cs35l41.h | 1 + + sound/pci/hda/cs35l41_hda.c | 13 ++++++++----- + 2 files changed, 9 insertions(+), 5 deletions(-) + +diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h +index 64d98cbd5c0e..7d892c97b1e8 100644 +--- a/include/sound/cs35l41.h ++++ b/include/sound/cs35l41.h +@@ -661,6 +661,7 @@ + #define CS35L41_GLOBAL_EN_SHIFT 0 + #define CS35L41_BST_EN_MASK 0x0030 + #define CS35L41_BST_EN_SHIFT 4 ++#define CS35L41_BST_DIS_FET_OFF 0x00 + #define CS35L41_BST_EN_DEFAULT 0x2 + #define CS35L41_AMP_EN_SHIFT 0 + #define CS35L41_AMP_EN_MASK 1 +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index 0709d09f4e13..6e82ab9517f0 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -25,7 +25,6 @@ static const struct reg_sequence cs35l41_hda_config[] = { + { CS35L41_DAC_PCM1_SRC, 0x00000008 }, // DACPCM1_SRC = ASPRX1 + { CS35L41_AMP_DIG_VOL_CTRL, 0x00000000 }, // AMP_VOL_PCM 0.0 dB + { CS35L41_AMP_GAIN_CTRL, 0x00000084 }, // AMP_GAIN_PCM 4.5 dB +- { CS35L41_PWR_CTRL2, 0x00000001 }, // AMP_EN = 1 + }; + + static const struct reg_sequence cs35l41_hda_mute[] = { +@@ -34,7 +33,6 @@ static const struct reg_sequence cs35l41_hda_mute[] = { + }; + + static const struct reg_sequence cs35l41_hda_start_bst[] = { +- { CS35L41_PWR_CTRL2, 0x00000021 }, // BST_EN = 10, AMP_EN = 1 + { CS35L41_PWR_CTRL1, 0x00000001, 3000}, // set GLOBAL_EN = 1 + }; + +@@ -94,7 +92,6 @@ static const struct reg_sequence cs35l41_active_to_safe[] = { + { 0x00000040, 0x00000055 }, + { 0x00000040, 0x000000AA }, + { 0x00007438, 0x00585941 }, +- { CS35L41_PWR_CTRL2, 0x00000000 }, // AMP_EN = 0 + { CS35L41_PWR_CTRL1, 0x00000000 }, + { 0x0000742C, 0x00000009, 2000 }, + { 0x00007438, 0x00580941 }, +@@ -144,6 +141,8 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action) + case HDA_GEN_PCM_ACT_OPEN: + ret = regmap_multi_reg_write(reg, cs35l41_hda_config, + ARRAY_SIZE(cs35l41_hda_config)); ++ regmap_update_bits(reg, CS35L41_PWR_CTRL2, ++ CS35L41_AMP_EN_MASK, 1 << CS35L41_AMP_EN_SHIFT); + break; + case HDA_GEN_PCM_ACT_PREPARE: + if (reg_seq->prepare) +@@ -155,6 +154,8 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action) + ret = regmap_multi_reg_write(reg, reg_seq->cleanup, reg_seq->num_cleanup); + break; + case HDA_GEN_PCM_ACT_CLOSE: ++ regmap_update_bits(reg, CS35L41_PWR_CTRL2, ++ CS35L41_AMP_EN_MASK, 0 << CS35L41_AMP_EN_SHIFT); + if (reg_seq->close) + ret = regmap_multi_reg_write(reg, reg_seq->close, reg_seq->num_close); + break; +@@ -232,8 +233,10 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41) + cs35l41->reg_seq = &cs35l41_hda_reg_seq_ext_bst; + else + cs35l41->reg_seq = &cs35l41_hda_reg_seq_no_bst; +- ret = regmap_multi_reg_write(cs35l41->regmap, cs35l41_reset_to_safe, +- ARRAY_SIZE(cs35l41_reset_to_safe)); ++ regmap_multi_reg_write(cs35l41->regmap, cs35l41_reset_to_safe, ++ ARRAY_SIZE(cs35l41_reset_to_safe)); ++ ret = regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, CS35L41_BST_EN_MASK, ++ CS35L41_BST_DIS_FET_OFF << CS35L41_BST_EN_SHIFT); + if (ret) + return ret; + break; +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Move-cs35l41-calls-to-its-own-symbo.patch b/patches.suse/ALSA-hda-cs35l41-Move-cs35l41-calls-to-its-own-symbo.patch new file mode 100644 index 0000000..e90494d --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Move-cs35l41-calls-to-its-own-symbo.patch @@ -0,0 +1,68 @@ +From 77dc3a6ee2eb5851535fe3a84fc31bf0705e4a2e Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Mon, 17 Jan 2022 16:08:27 +0000 +Subject: [PATCH] ALSA: hda: cs35l41: Move cs35l41* calls to its own symbol namespace +Git-commit: 77dc3a6ee2eb5851535fe3a84fc31bf0705e4a2e +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +Create own namespace and avoid polluting the global namespace + +Signed-off-by: Lucas Tanure +Link: https://lore.kernel.org/r/20220117160830.709403-3-tanureal@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 5 ++--- + sound/pci/hda/cs35l41_hda_i2c.c | 1 + + sound/pci/hda/cs35l41_hda_spi.c | 1 + + 3 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index 509a380f9be7..c4f25e48dcc0 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -514,7 +514,7 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i + + return ret; + } +-EXPORT_SYMBOL_GPL(cs35l41_hda_probe); ++EXPORT_SYMBOL_NS_GPL(cs35l41_hda_probe, SND_HDA_SCODEC_CS35L41); + + int cs35l41_hda_remove(struct device *dev) + { +@@ -528,8 +528,7 @@ int cs35l41_hda_remove(struct device *dev) + + return 0; + } +-EXPORT_SYMBOL_GPL(cs35l41_hda_remove); +- ++EXPORT_SYMBOL_NS_GPL(cs35l41_hda_remove, SND_HDA_SCODEC_CS35L41); + + MODULE_DESCRIPTION("CS35L41 HDA Driver"); + MODULE_AUTHOR("Lucas Tanure, Cirrus Logic Inc, "); +diff --git a/sound/pci/hda/cs35l41_hda_i2c.c b/sound/pci/hda/cs35l41_hda_i2c.c +index 4a9462fb5c14..eeb387853ee3 100644 +--- a/sound/pci/hda/cs35l41_hda_i2c.c ++++ b/sound/pci/hda/cs35l41_hda_i2c.c +@@ -62,5 +62,6 @@ static struct i2c_driver cs35l41_i2c_driver = { + module_i2c_driver(cs35l41_i2c_driver); + + MODULE_DESCRIPTION("HDA CS35L41 driver"); ++MODULE_IMPORT_NS(SND_HDA_SCODEC_CS35L41); + MODULE_AUTHOR("Lucas Tanure "); + MODULE_LICENSE("GPL"); +diff --git a/sound/pci/hda/cs35l41_hda_spi.c b/sound/pci/hda/cs35l41_hda_spi.c +index 77426e96c58f..15345a72b9d1 100644 +--- a/sound/pci/hda/cs35l41_hda_spi.c ++++ b/sound/pci/hda/cs35l41_hda_spi.c +@@ -59,5 +59,6 @@ static struct spi_driver cs35l41_spi_driver = { + module_spi_driver(cs35l41_spi_driver); + + MODULE_DESCRIPTION("HDA CS35L41 driver"); ++MODULE_IMPORT_NS(SND_HDA_SCODEC_CS35L41); + MODULE_AUTHOR("Lucas Tanure "); + MODULE_LICENSE("GPL"); +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Move-external-boost-handling-to-lib.patch b/patches.suse/ALSA-hda-cs35l41-Move-external-boost-handling-to-lib.patch new file mode 100644 index 0000000..8e5ac8d --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Move-external-boost-handling-to-lib.patch @@ -0,0 +1,346 @@ +From 5577dd2329d03ef88a7c87c17d4c127f3d666192 Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Wed, 13 Apr 2022 09:37:26 +0100 +Subject: [PATCH] ALSA: hda: cs35l41: Move external boost handling to lib for ASoC use +Git-commit: 5577dd2329d03ef88a7c87c17d4c127f3d666192 +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +To add support for external boost for ASoC move the HDA external +boost implementation to the shared lib. + +Signed-off-by: Lucas Tanure +Link: https://lore.kernel.org/r/20220413083728.10730-15-tanureal@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + include/sound/cs35l41.h | 4 + + sound/pci/hda/cs35l41_hda.c | 119 ++---------------------------- + sound/soc/codecs/cs35l41-lib.c | 129 ++++++++++++++++++++++++++++++++- + 3 files changed, 137 insertions(+), 115 deletions(-) + +diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h +index 7d892c97b1e8..ac629f852f2a 100644 +--- a/include/sound/cs35l41.h ++++ b/include/sound/cs35l41.h +@@ -805,5 +805,9 @@ int cs35l41_set_channels(struct device *dev, struct regmap *reg, + int cs35l41_boost_config(struct device *dev, struct regmap *regmap, int boost_ind, int boost_cap, + int boost_ipk); + int cs35l41_gpio_config(struct regmap *regmap, struct cs35l41_hw_cfg *hw_cfg); ++int cs35l41_init_boost(struct device *dev, struct regmap *regmap, ++ struct cs35l41_hw_cfg *hw_cfg); ++bool cs35l41_safe_reset(struct regmap *regmap, enum cs35l41_boost_type b_type); ++int cs35l41_global_enable(struct regmap *regmap, enum cs35l41_boost_type b_type, int enable); + + #endif /* __CS35L41_H */ +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index e54b5fbb6fb5..bc277b352ac9 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -32,94 +32,6 @@ static const struct reg_sequence cs35l41_hda_mute[] = { + { CS35L41_AMP_DIG_VOL_CTRL, 0x0000A678 }, // AMP_VOL_PCM Mute + }; + +-static const struct reg_sequence cs35l41_safe_to_reset[] = { +- { 0x00000040, 0x00000055 }, +- { 0x00000040, 0x000000AA }, +- { 0x0000393C, 0x000000C0, 6000}, +- { 0x0000393C, 0x00000000 }, +- { 0x00007414, 0x00C82222 }, +- { 0x0000742C, 0x00000000 }, +- { 0x00000040, 0x000000CC }, +- { 0x00000040, 0x00000033 }, +-}; +- +-static const struct reg_sequence cs35l41_safe_to_active[] = { +- { 0x00000040, 0x00000055 }, +- { 0x00000040, 0x000000AA }, +- { 0x0000742C, 0x0000000F }, +- { 0x0000742C, 0x00000079 }, +- { 0x00007438, 0x00585941 }, +- { CS35L41_PWR_CTRL1, 0x00000001, 3000 }, // GLOBAL_EN = 1 +- { 0x0000742C, 0x000000F9 }, +- { 0x00007438, 0x00580941 }, +- { 0x00000040, 0x000000CC }, +- { 0x00000040, 0x00000033 }, +-}; +- +-static const struct reg_sequence cs35l41_active_to_safe[] = { +- { 0x00000040, 0x00000055 }, +- { 0x00000040, 0x000000AA }, +- { 0x00007438, 0x00585941 }, +- { CS35L41_PWR_CTRL1, 0x00000000 }, +- { 0x0000742C, 0x00000009, 3000 }, +- { 0x00007438, 0x00580941 }, +- { 0x00000040, 0x000000CC }, +- { 0x00000040, 0x00000033 }, +-}; +- +-static const struct reg_sequence cs35l41_reset_to_safe[] = { +- { 0x00000040, 0x00000055 }, +- { 0x00000040, 0x000000AA }, +- { 0x00007438, 0x00585941 }, +- { 0x00007414, 0x08C82222 }, +- { 0x0000742C, 0x00000009 }, +- { 0x00000040, 0x000000CC }, +- { 0x00000040, 0x00000033 }, +-}; +- +-static bool cs35l41_hda_safe_reset(struct cs35l41_hda *cs35l41) +-{ +- switch (cs35l41->hw_cfg.bst_type) { +- case CS35L41_EXT_BOOST: +- regmap_write(cs35l41->regmap, CS35L41_GPIO1_CTRL1, 0x00000001); +- regmap_multi_reg_write(cs35l41->regmap, cs35l41_safe_to_reset, +- ARRAY_SIZE(cs35l41_safe_to_reset)); +- return true; +- case CS35L41_EXT_BOOST_NO_VSPK_SWITCH: +- return false; +- default: +- return true; +- } +-}; +- +-static int cs35l41_hda_global_enable(struct cs35l41_hda *cs35l41, int enable) +-{ +- int ret; +- +- switch (cs35l41->hw_cfg.bst_type) { +- case CS35L41_INT_BOOST: +- ret = regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL1, +- CS35L41_GLOBAL_EN_MASK, +- enable << CS35L41_GLOBAL_EN_SHIFT); +- usleep_range(3000, 3100); +- break; +- case CS35L41_EXT_BOOST: +- case CS35L41_EXT_BOOST_NO_VSPK_SWITCH: +- if (enable) +- ret = regmap_multi_reg_write(cs35l41->regmap, cs35l41_safe_to_active, +- ARRAY_SIZE(cs35l41_safe_to_active)); +- else +- ret = regmap_multi_reg_write(cs35l41->regmap, cs35l41_active_to_safe, +- ARRAY_SIZE(cs35l41_active_to_safe)); +- break; +- default: +- ret = -EINVAL; +- break; +- } +- +- return ret; +-}; +- + static void cs35l41_hda_playback_hook(struct device *dev, int action) + { + struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); +@@ -135,11 +47,11 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action) + regmap_write(reg, CS35L41_GPIO1_CTRL1, 0x00008001); + break; + case HDA_GEN_PCM_ACT_PREPARE: +- ret = cs35l41_hda_global_enable(cs35l41, 1); ++ ret = cs35l41_global_enable(reg, cs35l41->hw_cfg.bst_type, 1); + break; + case HDA_GEN_PCM_ACT_CLEANUP: + regmap_multi_reg_write(reg, cs35l41_hda_mute, ARRAY_SIZE(cs35l41_hda_mute)); +- ret = cs35l41_hda_global_enable(cs35l41, 0); ++ ret = cs35l41_global_enable(reg, cs35l41->hw_cfg.bst_type, 0); + break; + case HDA_GEN_PCM_ACT_CLOSE: + ret = regmap_update_bits(reg, CS35L41_PWR_CTRL2, +@@ -207,26 +119,9 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41) + if (!cs35l41->hw_cfg.valid) + return -EINVAL; + +- switch (hw_cfg->bst_type) { +- case CS35L41_INT_BOOST: +- ret = cs35l41_boost_config(cs35l41->dev, cs35l41->regmap, +- hw_cfg->bst_ind, hw_cfg->bst_cap, hw_cfg->bst_ipk); +- if (ret) +- return ret; +- break; +- case CS35L41_EXT_BOOST: +- case CS35L41_EXT_BOOST_NO_VSPK_SWITCH: +- regmap_multi_reg_write(cs35l41->regmap, cs35l41_reset_to_safe, +- ARRAY_SIZE(cs35l41_reset_to_safe)); +- ret = regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, CS35L41_BST_EN_MASK, +- CS35L41_BST_DIS_FET_OFF << CS35L41_BST_EN_SHIFT); +- if (ret) +- return ret; +- break; +- default: +- dev_err(cs35l41->dev, "Boost type %d not supported\n", hw_cfg->bst_type); +- return -EINVAL; +- } ++ ret = cs35l41_init_boost(cs35l41->dev, cs35l41->regmap, hw_cfg); ++ if (ret) ++ return ret; + + if (hw_cfg->gpio1.valid) { + switch (hw_cfg->gpio1.func) { +@@ -505,7 +400,7 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i + return 0; + + err: +- if (cs35l41_hda_safe_reset(cs35l41)) ++ if (cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type)) + gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); + gpiod_put(cs35l41->reset_gpio); + +@@ -519,7 +414,7 @@ void cs35l41_hda_remove(struct device *dev) + + component_del(cs35l41->dev, &cs35l41_hda_comp_ops); + +- if (cs35l41_hda_safe_reset(cs35l41)) ++ if (cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type)) + gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); + gpiod_put(cs35l41->reset_gpio); + } +diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c +index 03039d8488b9..2d3b577a63e3 100644 +--- a/sound/soc/codecs/cs35l41-lib.c ++++ b/sound/soc/codecs/cs35l41-lib.c +@@ -954,9 +954,8 @@ static const unsigned char cs35l41_bst_slope_table[4] = { + 0x75, 0x6B, 0x3B, 0x28 + }; + +- +-int cs35l41_boost_config(struct device *dev, struct regmap *regmap, int boost_ind, int boost_cap, +- int boost_ipk) ++int cs35l41_boost_config(struct device *dev, struct regmap *regmap, int boost_ind, ++ int boost_cap, int boost_ipk) + { + unsigned char bst_lbst_val, bst_cbst_range, bst_ipk_scaled; + int ret; +@@ -1043,6 +1042,130 @@ int cs35l41_boost_config(struct device *dev, struct regmap *regmap, int boost_in + } + EXPORT_SYMBOL_GPL(cs35l41_boost_config); + ++static const struct reg_sequence cs35l41_safe_to_reset[] = { ++ { 0x00000040, 0x00000055 }, ++ { 0x00000040, 0x000000AA }, ++ { 0x0000393C, 0x000000C0, 6000}, ++ { 0x0000393C, 0x00000000 }, ++ { 0x00007414, 0x00C82222 }, ++ { 0x0000742C, 0x00000000 }, ++ { 0x00000040, 0x000000CC }, ++ { 0x00000040, 0x00000033 }, ++}; ++ ++static const struct reg_sequence cs35l41_active_to_safe[] = { ++ { 0x00000040, 0x00000055 }, ++ { 0x00000040, 0x000000AA }, ++ { 0x00007438, 0x00585941 }, ++ { CS35L41_PWR_CTRL1, 0x00000000 }, ++ { 0x0000742C, 0x00000009, 3000 }, ++ { 0x00007438, 0x00580941 }, ++ { 0x00000040, 0x000000CC }, ++ { 0x00000040, 0x00000033 }, ++}; ++ ++static const struct reg_sequence cs35l41_safe_to_active[] = { ++ { 0x00000040, 0x00000055 }, ++ { 0x00000040, 0x000000AA }, ++ { 0x0000742C, 0x0000000F }, ++ { 0x0000742C, 0x00000079 }, ++ { 0x00007438, 0x00585941 }, ++ { CS35L41_PWR_CTRL1, 0x00000001, 3000 }, // GLOBAL_EN = 1 ++ { 0x0000742C, 0x000000F9 }, ++ { 0x00007438, 0x00580941 }, ++ { 0x00000040, 0x000000CC }, ++ { 0x00000040, 0x00000033 }, ++}; ++ ++static const struct reg_sequence cs35l41_reset_to_safe[] = { ++ { 0x00000040, 0x00000055 }, ++ { 0x00000040, 0x000000AA }, ++ { 0x00007438, 0x00585941 }, ++ { 0x00007414, 0x08C82222 }, ++ { 0x0000742C, 0x00000009 }, ++ { 0x00000040, 0x000000CC }, ++ { 0x00000040, 0x00000033 }, ++}; ++ ++int cs35l41_init_boost(struct device *dev, struct regmap *regmap, ++ struct cs35l41_hw_cfg *hw_cfg) ++{ ++ int ret; ++ ++ switch (hw_cfg->bst_type) { ++ case CS35L41_INT_BOOST: ++ ret = cs35l41_boost_config(dev, regmap, hw_cfg->bst_ind, ++ hw_cfg->bst_cap, hw_cfg->bst_ipk); ++ if (ret) ++ dev_err(dev, "Error in Boost DT config: %d\n", ret); ++ break; ++ case CS35L41_EXT_BOOST: ++ case CS35L41_EXT_BOOST_NO_VSPK_SWITCH: ++ /* Only CLSA0100 doesn't use GPIO as VSPK switch, but even on that laptop we can ++ * toggle GPIO1 as is not connected to anything. ++ * There will be no other device without VSPK switch. ++ */ ++ regmap_write(regmap, CS35L41_GPIO1_CTRL1, 0x00000001); ++ regmap_multi_reg_write(regmap, cs35l41_reset_to_safe, ++ ARRAY_SIZE(cs35l41_reset_to_safe)); ++ ret = regmap_update_bits(regmap, CS35L41_PWR_CTRL2, CS35L41_BST_EN_MASK, ++ CS35L41_BST_DIS_FET_OFF << CS35L41_BST_EN_SHIFT); ++ break; ++ default: ++ dev_err(dev, "Boost type %d not supported\n", hw_cfg->bst_type); ++ ret = -EINVAL; ++ break; ++ } ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(cs35l41_init_boost); ++ ++bool cs35l41_safe_reset(struct regmap *regmap, enum cs35l41_boost_type b_type) ++{ ++ switch (b_type) { ++ /* There is only one laptop that doesn't have VSPK switch. */ ++ case CS35L41_EXT_BOOST_NO_VSPK_SWITCH: ++ return false; ++ case CS35L41_EXT_BOOST: ++ regmap_write(regmap, CS35L41_GPIO1_CTRL1, 0x00000001); ++ regmap_multi_reg_write(regmap, cs35l41_safe_to_reset, ++ ARRAY_SIZE(cs35l41_safe_to_reset)); ++ return true; ++ default: ++ return true; ++ } ++} ++EXPORT_SYMBOL_GPL(cs35l41_safe_reset); ++ ++int cs35l41_global_enable(struct regmap *regmap, enum cs35l41_boost_type b_type, int enable) ++{ ++ int ret; ++ ++ switch (b_type) { ++ case CS35L41_INT_BOOST: ++ ret = regmap_update_bits(regmap, CS35L41_PWR_CTRL1, CS35L41_GLOBAL_EN_MASK, ++ enable << CS35L41_GLOBAL_EN_SHIFT); ++ usleep_range(3000, 3100); ++ break; ++ case CS35L41_EXT_BOOST: ++ case CS35L41_EXT_BOOST_NO_VSPK_SWITCH: ++ if (enable) ++ ret = regmap_multi_reg_write(regmap, cs35l41_safe_to_active, ++ ARRAY_SIZE(cs35l41_safe_to_active)); ++ else ++ ret = regmap_multi_reg_write(regmap, cs35l41_active_to_safe, ++ ARRAY_SIZE(cs35l41_active_to_safe)); ++ break; ++ default: ++ ret = -EINVAL; ++ break; ++ } ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(cs35l41_global_enable); ++ + int cs35l41_gpio_config(struct regmap *regmap, struct cs35l41_hw_cfg *hw_cfg) + { + struct cs35l41_gpio_cfg *gpio1 = &hw_cfg->gpio1; +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Mute-the-device-before-shutdown.patch b/patches.suse/ALSA-hda-cs35l41-Mute-the-device-before-shutdown.patch new file mode 100644 index 0000000..b71bcdb --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Mute-the-device-before-shutdown.patch @@ -0,0 +1,54 @@ +From f29db0892b2a9b2827f4a1afd3abebb82bcf843c Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Wed, 13 Apr 2022 09:37:20 +0100 +Subject: [PATCH] ALSA: hda: cs35l41: Mute the device before shutdown +Git-commit: f29db0892b2a9b2827f4a1afd3abebb82bcf843c +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +Mute the device before shutdown to avoid pops and clicks for all types +of boost. + +Signed-off-by: Lucas Tanure +Link: https://lore.kernel.org/r/20220413083728.10730-9-tanureal@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index 46e920ec3000..0709d09f4e13 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -28,6 +28,11 @@ static const struct reg_sequence cs35l41_hda_config[] = { + { CS35L41_PWR_CTRL2, 0x00000001 }, // AMP_EN = 1 + }; + ++static const struct reg_sequence cs35l41_hda_mute[] = { ++ { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, // AMP_GAIN_PCM 0.5 dB ++ { CS35L41_AMP_DIG_VOL_CTRL, 0x0000A678 }, // AMP_VOL_PCM Mute ++}; ++ + static const struct reg_sequence cs35l41_hda_start_bst[] = { + { CS35L41_PWR_CTRL2, 0x00000021 }, // BST_EN = 10, AMP_EN = 1 + { CS35L41_PWR_CTRL1, 0x00000001, 3000}, // set GLOBAL_EN = 1 +@@ -89,7 +94,6 @@ static const struct reg_sequence cs35l41_active_to_safe[] = { + { 0x00000040, 0x00000055 }, + { 0x00000040, 0x000000AA }, + { 0x00007438, 0x00585941 }, +- { CS35L41_AMP_DIG_VOL_CTRL, 0x0000A678 }, // AMP_VOL_PCM Mute + { CS35L41_PWR_CTRL2, 0x00000000 }, // AMP_EN = 0 + { CS35L41_PWR_CTRL1, 0x00000000 }, + { 0x0000742C, 0x00000009, 2000 }, +@@ -146,6 +150,7 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action) + ret = regmap_multi_reg_write(reg, reg_seq->prepare, reg_seq->num_prepare); + break; + case HDA_GEN_PCM_ACT_CLEANUP: ++ regmap_multi_reg_write(reg, cs35l41_hda_mute, ARRAY_SIZE(cs35l41_hda_mute)); + if (reg_seq->cleanup) + ret = regmap_multi_reg_write(reg, reg_seq->cleanup, reg_seq->num_cleanup); + break; +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Put-the-device-into-safe-mode-for-e.patch b/patches.suse/ALSA-hda-cs35l41-Put-the-device-into-safe-mode-for-e.patch new file mode 100644 index 0000000..f4b5bd4 --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Put-the-device-into-safe-mode-for-e.patch @@ -0,0 +1,56 @@ +From f04bb4cae18b8eb7e7e7bc35a8e07f1f26bbb919 Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Wed, 13 Apr 2022 09:37:19 +0100 +Subject: [PATCH] ALSA: hda: cs35l41: Put the device into safe mode for external boost +Git-commit: f04bb4cae18b8eb7e7e7bc35a8e07f1f26bbb919 +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +To facilitate the configuration of external boost devices, put all +devices, with or without VSPK switch, into safe mode from the start. +That allows the following parts of the driver to handle all external +boost devices in the same way. + +Signed-off-by: Lucas Tanure +Link: https://lore.kernel.org/r/20220413083728.10730-8-tanureal@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index 0dac622805c4..46e920ec3000 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -109,8 +109,6 @@ static const struct reg_sequence cs35l41_reset_to_safe[] = { + }; + + static const struct cs35l41_hda_reg_sequence cs35l41_hda_reg_seq_no_bst = { +- .probe = cs35l41_reset_to_safe, +- .num_probe = ARRAY_SIZE(cs35l41_reset_to_safe), + .prepare = cs35l41_safe_to_active, + .num_prepare = ARRAY_SIZE(cs35l41_safe_to_active), + .cleanup = cs35l41_active_to_safe, +@@ -224,10 +222,15 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41) + return ret; + break; + case CS35L41_EXT_BOOST: +- cs35l41->reg_seq = &cs35l41_hda_reg_seq_ext_bst; +- break; + case CS35L41_EXT_BOOST_NO_VSPK_SWITCH: +- cs35l41->reg_seq = &cs35l41_hda_reg_seq_no_bst; ++ if (hw_cfg->bst_type == CS35L41_EXT_BOOST) ++ cs35l41->reg_seq = &cs35l41_hda_reg_seq_ext_bst; ++ else ++ cs35l41->reg_seq = &cs35l41_hda_reg_seq_no_bst; ++ ret = regmap_multi_reg_write(cs35l41->regmap, cs35l41_reset_to_safe, ++ ARRAY_SIZE(cs35l41_reset_to_safe)); ++ if (ret) ++ return ret; + break; + default: + dev_err(cs35l41->dev, "Boost type %d not supported\n", hw_cfg->bst_type); +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Read-Speaker-Calibration-data-from-.patch b/patches.suse/ALSA-hda-cs35l41-Read-Speaker-Calibration-data-from-.patch new file mode 100644 index 0000000..3edcd00 --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Read-Speaker-Calibration-data-from-.patch @@ -0,0 +1,185 @@ +From 3e34e2ae29591f0fd84dca905d296da1e127160c Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Thu, 30 Jun 2022 01:23:31 +0100 +Subject: [PATCH] ALSA: hda: cs35l41: Read Speaker Calibration data from UEFI variables +Git-commit: 3e34e2ae29591f0fd84dca905d296da1e127160c +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +Speaker Calibration data, specific to an individual speaker is +stored inside UEFI variables during calibration, and can be +used by the DSP. + +Signed-off-by: Stefan Binding +Signed-off-by: Vitaly Rodionov +Link: https://lore.kernel.org/r/20220630002335.366545-11-vitalyr@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 101 ++++++++++++++++++++++++++++++++++++ + sound/pci/hda/cs35l41_hda.h | 15 ++++++ + 2 files changed, 116 insertions(+) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index 61441bfc9fa9..75edaffb568a 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -26,6 +26,12 @@ + #define HALO_STATE_DSP_CTL_NAME "HALO_STATE" + #define HALO_STATE_DSP_CTL_TYPE 5 + #define HALO_STATE_DSP_CTL_ALG 262308 ++#define CAL_R_DSP_CTL_NAME "CAL_R" ++#define CAL_STATUS_DSP_CTL_NAME "CAL_STATUS" ++#define CAL_CHECKSUM_DSP_CTL_NAME "CAL_CHECKSUM" ++#define CAL_AMBIENT_DSP_CTL_NAME "CAL_AMBIENT" ++#define CAL_DSP_CTL_TYPE 5 ++#define CAL_DSP_CTL_ALG 205 + + static const struct reg_sequence cs35l41_hda_config[] = { + { CS35L41_PLL_CLK_CTRL, 0x00000430 }, // 3072000Hz, BCLK Input, PLL_REFCLK_EN = 1 +@@ -282,6 +288,96 @@ static int cs35l41_request_firmware_files(struct cs35l41_hda *cs35l41, + return ret; + } + ++#if IS_ENABLED(CONFIG_EFI) ++static int cs35l41_apply_calibration(struct cs35l41_hda *cs35l41, unsigned int ambient, ++ unsigned int r0, unsigned int status, unsigned int checksum) ++{ ++ int ret; ++ ++ ret = hda_cs_dsp_write_ctl(&cs35l41->cs_dsp, CAL_AMBIENT_DSP_CTL_NAME, CAL_DSP_CTL_TYPE, ++ CAL_DSP_CTL_ALG, &ambient, 4); ++ if (ret) { ++ dev_err(cs35l41->dev, "Cannot Write Control: %s - %d\n", CAL_AMBIENT_DSP_CTL_NAME, ++ ret); ++ return ret; ++ } ++ ret = hda_cs_dsp_write_ctl(&cs35l41->cs_dsp, CAL_R_DSP_CTL_NAME, CAL_DSP_CTL_TYPE, ++ CAL_DSP_CTL_ALG, &r0, 4); ++ if (ret) { ++ dev_err(cs35l41->dev, "Cannot Write Control: %s - %d\n", CAL_R_DSP_CTL_NAME, ret); ++ return ret; ++ } ++ ret = hda_cs_dsp_write_ctl(&cs35l41->cs_dsp, CAL_STATUS_DSP_CTL_NAME, CAL_DSP_CTL_TYPE, ++ CAL_DSP_CTL_ALG, &status, 4); ++ if (ret) { ++ dev_err(cs35l41->dev, "Cannot Write Control: %s - %d\n", CAL_STATUS_DSP_CTL_NAME, ++ ret); ++ return ret; ++ } ++ ret = hda_cs_dsp_write_ctl(&cs35l41->cs_dsp, CAL_CHECKSUM_DSP_CTL_NAME, CAL_DSP_CTL_TYPE, ++ CAL_DSP_CTL_ALG, &checksum, 4); ++ if (ret) { ++ dev_err(cs35l41->dev, "Cannot Write Control: %s - %d\n", CAL_CHECKSUM_DSP_CTL_NAME, ++ ret); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int cs35l41_save_calibration(struct cs35l41_hda *cs35l41) ++{ ++ static efi_guid_t efi_guid = EFI_GUID(0x02f9af02, 0x7734, 0x4233, 0xb4, 0x3d, 0x93, 0xfe, ++ 0x5a, 0xa3, 0x5d, 0xb3); ++ static efi_char16_t efi_name[] = L"CirrusSmartAmpCalibrationData"; ++ const struct cs35l41_amp_efi_data *efi_data; ++ const struct cs35l41_amp_cal_data *cl; ++ unsigned long data_size = 0; ++ efi_status_t status; ++ int ret = 0; ++ u8 *data = NULL; ++ u32 attr; ++ ++ /* Get real size of UEFI variable */ ++ status = efi.get_variable(efi_name, &efi_guid, &attr, &data_size, data); ++ if (status == EFI_BUFFER_TOO_SMALL) { ++ ret = -ENODEV; ++ /* Allocate data buffer of data_size bytes */ ++ data = vmalloc(data_size); ++ if (!data) ++ return -ENOMEM; ++ /* Get variable contents into buffer */ ++ status = efi.get_variable(efi_name, &efi_guid, &attr, &data_size, data); ++ if (status == EFI_SUCCESS) { ++ efi_data = (struct cs35l41_amp_efi_data *)data; ++ dev_dbg(cs35l41->dev, "Calibration: Size=%d, Amp Count=%d\n", ++ efi_data->size, efi_data->count); ++ if (efi_data->count > cs35l41->index) { ++ cl = &efi_data->data[cs35l41->index]; ++ dev_dbg(cs35l41->dev, ++ "Calibration: Ambient=%02x, Status=%02x, R0=%d\n", ++ cl->calAmbient, cl->calStatus, cl->calR); ++ ++ /* Calibration can only be applied whilst the DSP is not running */ ++ ret = cs35l41_apply_calibration(cs35l41, ++ cpu_to_be32(cl->calAmbient), ++ cpu_to_be32(cl->calR), ++ cpu_to_be32(cl->calStatus), ++ cpu_to_be32(cl->calR + 1)); ++ } ++ } ++ vfree(data); ++ } ++ return ret; ++} ++#else ++static int cs35l41_save_calibration(struct cs35l41_hda *cs35l41) ++{ ++ dev_warn(cs35l41->dev, "Calibration not supported without EFI support.\n"); ++ return 0; ++} ++#endif ++ + static int cs35l41_init_dsp(struct cs35l41_hda *cs35l41) + { + const struct firmware *coeff_firmware = NULL; +@@ -314,7 +410,12 @@ static int cs35l41_init_dsp(struct cs35l41_hda *cs35l41) + + ret = cs_dsp_power_up(dsp, wmfw_firmware, wmfw_filename, coeff_firmware, coeff_filename, + FW_NAME); ++ if (ret) ++ goto err_release; ++ ++ ret = cs35l41_save_calibration(cs35l41); + ++err_release: + release_firmware(wmfw_firmware); + release_firmware(coeff_firmware); + kfree(wmfw_filename); +diff --git a/sound/pci/hda/cs35l41_hda.h b/sound/pci/hda/cs35l41_hda.h +index 439c4b705328..59a9461d0444 100644 +--- a/sound/pci/hda/cs35l41_hda.h ++++ b/sound/pci/hda/cs35l41_hda.h +@@ -10,6 +10,7 @@ + #ifndef __CS35L41_HDA_H__ + #define __CS35L41_HDA_H__ + ++#include + #include + #include + #include +@@ -18,6 +19,20 @@ + #include + #include + ++struct cs35l41_amp_cal_data { ++ u32 calTarget[2]; ++ u32 calTime[2]; ++ s8 calAmbient; ++ u8 calStatus; ++ u16 calR; ++} __packed; ++ ++struct cs35l41_amp_efi_data { ++ u32 size; ++ u32 count; ++ struct cs35l41_amp_cal_data data[]; ++} __packed; ++ + enum cs35l41_hda_spk_pos { + CS35l41_LEFT, + CS35l41_RIGHT, +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Remove-Set-Channel-Map-api-from-bin.patch b/patches.suse/ALSA-hda-cs35l41-Remove-Set-Channel-Map-api-from-bin.patch new file mode 100644 index 0000000..2a4a23d --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Remove-Set-Channel-Map-api-from-bin.patch @@ -0,0 +1,120 @@ +From 14e42ceec89a59ad34bb22da9bbf3426a8824265 Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Mon, 9 May 2022 22:46:40 +0100 +Subject: [PATCH] ALSA: hda: cs35l41: Remove Set Channel Map api from binding +Git-commit: 14e42ceec89a59ad34bb22da9bbf3426a8824265 +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +This API was required for CLSA0100 laptop, which did not +have correct properties inside ACPI. The required values +are now hardcoded inside the driver so this is no longer +needed. +Without this api, there CLSA0100 can now use the generic +cs35l41 fixup, like the other laptops. +All other laptops will read the Speaker Position from +ACPI and set the channel map from within the driver. + +Signed-off-by: Stefan Binding +Signed-off-by: Vitaly Rodionov +Link: https://lore.kernel.org/r/20220509214703.4482-4-vitalyr@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 1 + sound/pci/hda/hda_component.h | 2 - + sound/pci/hda/patch_realtek.c | 54 ------------------------------------------ + 3 files changed, 1 insertion(+), 56 deletions(-) + +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -92,7 +92,6 @@ static int cs35l41_hda_bind(struct devic + comps->dev = dev; + strscpy(comps->name, dev_name(dev), sizeof(comps->name)); + comps->playback_hook = cs35l41_hda_playback_hook; +- comps->set_channel_map = cs35l41_hda_channel_map; + + return 0; + } +--- a/sound/pci/hda/hda_component.h ++++ b/sound/pci/hda/hda_component.h +@@ -15,6 +15,4 @@ struct hda_component { + struct device *dev; + char name[HDA_MAX_NAME_SIZE]; + void (*playback_hook)(struct device *dev, int action); +- int (*set_channel_map)(struct device *dev, unsigned int rx_num, unsigned int *rx_slot, +- unsigned int tx_num, unsigned int *tx_slot); + }; +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -6653,18 +6653,6 @@ static int comp_match_dev_name(struct de + return strcmp(dev_name(dev), data) == 0; + } + +-static int find_comp_by_dev_name(struct alc_spec *spec, const char *name) +-{ +- int i; +- +- for (i = 0; i < HDA_MAX_COMPONENTS; i++) { +- if (strcmp(spec->comps[i].name, name) == 0) +- return i; +- } +- +- return -ENODEV; +-} +- + static int comp_bind(struct device *dev) + { + struct hda_codec *cdc = dev_to_hda_codec(dev); +@@ -6739,50 +6727,10 @@ static void cs35l41_fixup_spi_four(struc + cs35l41_generic_fixup(codec, action, "spi0", "CSC3551", 4); + } + +-static void alc287_legion_16achg6_playback_hook(struct hda_pcm_stream *hinfo, struct hda_codec *cdc, +- struct snd_pcm_substream *sub, int action) +-{ +- struct alc_spec *spec = cdc->spec; +- unsigned int rx_slot; +- int i; +- +- switch (action) { +- case HDA_GEN_PCM_ACT_PREPARE: +- rx_slot = 0; +- i = find_comp_by_dev_name(spec, "i2c-CLSA0100:00-cs35l41-hda.0"); +- if (i >= 0) +- spec->comps[i].set_channel_map(spec->comps[i].dev, 0, NULL, 1, &rx_slot); +- +- rx_slot = 1; +- i = find_comp_by_dev_name(spec, "i2c-CLSA0100:00-cs35l41-hda.1"); +- if (i >= 0) +- spec->comps[i].set_channel_map(spec->comps[i].dev, 0, NULL, 1, &rx_slot); +- break; +- } +- +- comp_generic_playback_hook(hinfo, cdc, sub, action); +-} +- + static void alc287_fixup_legion_16achg6_speakers(struct hda_codec *cdc, const struct hda_fixup *fix, + int action) + { +- struct device *dev = hda_codec_dev(cdc); +- struct alc_spec *spec = cdc->spec; +- int ret; +- +- switch (action) { +- case HDA_FIXUP_ACT_PRE_PROBE: +- component_match_add(dev, &spec->match, comp_match_dev_name, +- "i2c-CLSA0100:00-cs35l41-hda.0"); +- component_match_add(dev, &spec->match, comp_match_dev_name, +- "i2c-CLSA0100:00-cs35l41-hda.1"); +- ret = component_master_add_with_match(dev, &comp_master_ops, spec->match); +- if (ret) +- codec_err(cdc, "Fail to register component aggregator %d\n", ret); +- else +- spec->gen.pcm_playback_hook = alc287_legion_16achg6_playback_hook; +- break; +- } ++ cs35l41_generic_fixup(cdc, action, "i2c", "CLSA0100", 2); + } + + /* for alc295_fixup_hp_top_speakers */ diff --git a/patches.suse/ALSA-hda-cs35l41-Remove-cs35l41_hda_reg_sequence-str.patch b/patches.suse/ALSA-hda-cs35l41-Remove-cs35l41_hda_reg_sequence-str.patch new file mode 100644 index 0000000..097f5d2 --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Remove-cs35l41_hda_reg_sequence-str.patch @@ -0,0 +1,193 @@ +From fabcf7f12b5fc8e26606fe831843c3ee7023142c Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Wed, 13 Apr 2022 09:37:23 +0100 +Subject: [PATCH] ALSA: hda: cs35l41: Remove cs35l41_hda_reg_sequence struct +Git-commit: fabcf7f12b5fc8e26606fe831843c3ee7023142c +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +Remove cs35l41_hd_reg_sequence as it adds a layer of flexibility not needed. +As cs35l41_hda_(start/stop)_bst is a single register, it can be replaced by +regmap_update_bits with usleep_range to wait for the same 3000us that +reg_sequence had. + +Signed-off-by: Lucas Tanure +Link: https://lore.kernel.org/r/20220413083728.10730-12-tanureal@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 79 ++++++++++++++++--------------------- + sound/pci/hda/cs35l41_hda.h | 14 ------- + 2 files changed, 33 insertions(+), 60 deletions(-) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index 6e82ab9517f0..ece784662dbd 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -32,14 +32,6 @@ static const struct reg_sequence cs35l41_hda_mute[] = { + { CS35L41_AMP_DIG_VOL_CTRL, 0x0000A678 }, // AMP_VOL_PCM Mute + }; + +-static const struct reg_sequence cs35l41_hda_start_bst[] = { +- { CS35L41_PWR_CTRL1, 0x00000001, 3000}, // set GLOBAL_EN = 1 +-}; +- +-static const struct reg_sequence cs35l41_hda_stop_bst[] = { +- { CS35L41_PWR_CTRL1, 0x00000000, 3000}, // set GLOBAL_EN = 0 +-}; +- + // only on amps where GPIO1 is used to control ext. VSPK switch + static const struct reg_sequence cs35l41_start_ext_vspk[] = { + { 0x00000040, 0x00000055 }, +@@ -109,31 +101,44 @@ static const struct reg_sequence cs35l41_reset_to_safe[] = { + { 0x00000040, 0x00000033 }, + }; + +-static const struct cs35l41_hda_reg_sequence cs35l41_hda_reg_seq_no_bst = { +- .prepare = cs35l41_safe_to_active, +- .num_prepare = ARRAY_SIZE(cs35l41_safe_to_active), +- .cleanup = cs35l41_active_to_safe, +- .num_cleanup = ARRAY_SIZE(cs35l41_active_to_safe), +-}; ++static int cs35l41_hda_global_enable(struct cs35l41_hda *cs35l41, int enable) ++{ ++ int ret; + +-static const struct cs35l41_hda_reg_sequence cs35l41_hda_reg_seq_ext_bst = { +- .prepare = cs35l41_start_ext_vspk, +- .num_prepare = ARRAY_SIZE(cs35l41_start_ext_vspk), +- .cleanup = cs35l41_stop_ext_vspk, +- .num_cleanup = ARRAY_SIZE(cs35l41_stop_ext_vspk), +-}; ++ switch (cs35l41->hw_cfg.bst_type) { ++ case CS35L41_INT_BOOST: ++ ret = regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL1, ++ CS35L41_GLOBAL_EN_MASK, ++ enable << CS35L41_GLOBAL_EN_SHIFT); ++ usleep_range(3000, 3100); ++ break; ++ case CS35L41_EXT_BOOST: ++ if (enable) ++ ret = regmap_multi_reg_write(cs35l41->regmap, cs35l41_start_ext_vspk, ++ ARRAY_SIZE(cs35l41_start_ext_vspk)); ++ else ++ ret = regmap_multi_reg_write(cs35l41->regmap, cs35l41_stop_ext_vspk, ++ ARRAY_SIZE(cs35l41_stop_ext_vspk)); ++ break; ++ case CS35L41_EXT_BOOST_NO_VSPK_SWITCH: ++ if (enable) ++ ret = regmap_multi_reg_write(cs35l41->regmap, cs35l41_safe_to_active, ++ ARRAY_SIZE(cs35l41_safe_to_active)); ++ else ++ ret = regmap_multi_reg_write(cs35l41->regmap, cs35l41_active_to_safe, ++ ARRAY_SIZE(cs35l41_active_to_safe)); ++ break; ++ default: ++ ret = -EINVAL; ++ break; ++ } + +-static const struct cs35l41_hda_reg_sequence cs35l41_hda_reg_seq_int_bst = { +- .prepare = cs35l41_hda_start_bst, +- .num_prepare = ARRAY_SIZE(cs35l41_hda_start_bst), +- .cleanup = cs35l41_hda_stop_bst, +- .num_cleanup = ARRAY_SIZE(cs35l41_hda_stop_bst), ++ return ret; + }; + + static void cs35l41_hda_playback_hook(struct device *dev, int action) + { + struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); +- const struct cs35l41_hda_reg_sequence *reg_seq = cs35l41->reg_seq; + struct regmap *reg = cs35l41->regmap; + int ret = 0; + +@@ -145,19 +150,15 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action) + CS35L41_AMP_EN_MASK, 1 << CS35L41_AMP_EN_SHIFT); + break; + case HDA_GEN_PCM_ACT_PREPARE: +- if (reg_seq->prepare) +- ret = regmap_multi_reg_write(reg, reg_seq->prepare, reg_seq->num_prepare); ++ ret = cs35l41_hda_global_enable(cs35l41, 1); + break; + case HDA_GEN_PCM_ACT_CLEANUP: + regmap_multi_reg_write(reg, cs35l41_hda_mute, ARRAY_SIZE(cs35l41_hda_mute)); +- if (reg_seq->cleanup) +- ret = regmap_multi_reg_write(reg, reg_seq->cleanup, reg_seq->num_cleanup); ++ ret = cs35l41_hda_global_enable(cs35l41, 0); + break; + case HDA_GEN_PCM_ACT_CLOSE: + regmap_update_bits(reg, CS35L41_PWR_CTRL2, + CS35L41_AMP_EN_MASK, 0 << CS35L41_AMP_EN_SHIFT); +- if (reg_seq->close) +- ret = regmap_multi_reg_write(reg, reg_seq->close, reg_seq->num_close); + break; + default: + ret = -EINVAL; +@@ -221,7 +222,6 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41) + + switch (hw_cfg->bst_type) { + case CS35L41_INT_BOOST: +- cs35l41->reg_seq = &cs35l41_hda_reg_seq_int_bst; + ret = cs35l41_boost_config(cs35l41->dev, cs35l41->regmap, + hw_cfg->bst_ind, hw_cfg->bst_cap, hw_cfg->bst_ipk); + if (ret) +@@ -229,10 +229,6 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41) + break; + case CS35L41_EXT_BOOST: + case CS35L41_EXT_BOOST_NO_VSPK_SWITCH: +- if (hw_cfg->bst_type == CS35L41_EXT_BOOST) +- cs35l41->reg_seq = &cs35l41_hda_reg_seq_ext_bst; +- else +- cs35l41->reg_seq = &cs35l41_hda_reg_seq_no_bst; + regmap_multi_reg_write(cs35l41->regmap, cs35l41_reset_to_safe, + ARRAY_SIZE(cs35l41_reset_to_safe)); + ret = regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, CS35L41_BST_EN_MASK, +@@ -511,15 +507,6 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i + if (ret) + goto err; + +- if (cs35l41->reg_seq->probe) { +- ret = regmap_multi_reg_write(cs35l41->regmap, cs35l41->reg_seq->probe, +- cs35l41->reg_seq->num_probe); +- if (ret) { +- dev_err(cs35l41->dev, "Fail to apply probe reg patch: %d\n", ret); +- goto err; +- } +- } +- + ret = component_add(cs35l41->dev, &cs35l41_hda_comp_ops); + if (ret) { + dev_err(cs35l41->dev, "Register component failed: %d\n", ret); +diff --git a/sound/pci/hda/cs35l41_hda.h b/sound/pci/hda/cs35l41_hda.h +index 17f10764f174..44d9204ffdf1 100644 +--- a/sound/pci/hda/cs35l41_hda.h ++++ b/sound/pci/hda/cs35l41_hda.h +@@ -27,24 +27,10 @@ enum cs35l41_hda_gpio_function { + CS35l41_SYNC, + }; + +-struct cs35l41_hda_reg_sequence { +- const struct reg_sequence *probe; +- unsigned int num_probe; +- const struct reg_sequence *open; +- unsigned int num_open; +- const struct reg_sequence *prepare; +- unsigned int num_prepare; +- const struct reg_sequence *cleanup; +- unsigned int num_cleanup; +- const struct reg_sequence *close; +- unsigned int num_close; +-}; +- + struct cs35l41_hda { + struct device *dev; + struct regmap *regmap; + struct gpio_desc *reset_gpio; +- const struct cs35l41_hda_reg_sequence *reg_seq; + struct cs35l41_hw_cfg hw_cfg; + + int irq; +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Remove-suspend-resume-hda-hooks.patch b/patches.suse/ALSA-hda-cs35l41-Remove-suspend-resume-hda-hooks.patch new file mode 100644 index 0000000..6d2b75f --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Remove-suspend-resume-hda-hooks.patch @@ -0,0 +1,190 @@ +From 23904f7b2518e9b6bbfe2ac7bbe9e284bcdda18e Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Tue, 11 Oct 2022 15:35:51 +0100 +Subject: [PATCH] ALSA: hda: cs35l41: Remove suspend/resume hda hooks +Git-commit: 23904f7b2518e9b6bbfe2ac7bbe9e284bcdda18e +Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git +Patch-mainline: Queued in subsystem maintainer repository +References: bsc#1203699 + +The current code uses calls from the HDA Codec driver to +determine when to suspend/resume by calling hooks via the +hda_component binding. +However, this means the cs35l41 driver relies on the HDA +Codec driver to tell it when to suspend or resume, +creating an additional external dependency, and potentially +creating race conditions in the future. It is better for +the cs35l41 hda driver to decide for itself when the part +should be suspended or resumed. +This makes supporting system suspend easier. + +Signed-off-by: Stefan Binding +Link: https://lore.kernel.org/r/20221011143552.621792-5-sbinding@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 31 ++++++++++++------------------- + sound/pci/hda/hda_component.h | 2 -- + sound/pci/hda/patch_realtek.c | 19 +------------------ + 3 files changed, 13 insertions(+), 39 deletions(-) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index 102ac4a94a9d..89f6b4a28d3d 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -487,10 +487,10 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action) + struct regmap *reg = cs35l41->regmap; + int ret = 0; + +- mutex_lock(&cs35l41->fw_mutex); +- + switch (action) { + case HDA_GEN_PCM_ACT_OPEN: ++ pm_runtime_get_sync(dev); ++ mutex_lock(&cs35l41->fw_mutex); + cs35l41->playback_started = true; + if (cs35l41->firmware_running) { + regmap_multi_reg_write(reg, cs35l41_hda_config_dsp, +@@ -508,15 +508,21 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action) + CS35L41_AMP_EN_MASK, 1 << CS35L41_AMP_EN_SHIFT); + if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST) + regmap_write(reg, CS35L41_GPIO1_CTRL1, 0x00008001); ++ mutex_unlock(&cs35l41->fw_mutex); + break; + case HDA_GEN_PCM_ACT_PREPARE: ++ mutex_lock(&cs35l41->fw_mutex); + ret = cs35l41_global_enable(reg, cs35l41->hw_cfg.bst_type, 1); ++ mutex_unlock(&cs35l41->fw_mutex); + break; + case HDA_GEN_PCM_ACT_CLEANUP: ++ mutex_lock(&cs35l41->fw_mutex); + regmap_multi_reg_write(reg, cs35l41_hda_mute, ARRAY_SIZE(cs35l41_hda_mute)); + ret = cs35l41_global_enable(reg, cs35l41->hw_cfg.bst_type, 0); ++ mutex_unlock(&cs35l41->fw_mutex); + break; + case HDA_GEN_PCM_ACT_CLOSE: ++ mutex_lock(&cs35l41->fw_mutex); + ret = regmap_update_bits(reg, CS35L41_PWR_CTRL2, + CS35L41_AMP_EN_MASK, 0 << CS35L41_AMP_EN_SHIFT); + if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST) +@@ -530,14 +536,16 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action) + } + cs35l41_irq_release(cs35l41); + cs35l41->playback_started = false; ++ mutex_unlock(&cs35l41->fw_mutex); ++ ++ pm_runtime_mark_last_busy(dev); ++ pm_runtime_put_autosuspend(dev); + break; + default: + dev_warn(cs35l41->dev, "Playback action not supported: %d\n", action); + break; + } + +- mutex_unlock(&cs35l41->fw_mutex); +- + if (ret) + dev_err(cs35l41->dev, "Regmap access fail: %d\n", ret); + } +@@ -618,19 +626,6 @@ static int cs35l41_runtime_resume(struct device *dev) + return 0; + } + +-static int cs35l41_hda_suspend_hook(struct device *dev) +-{ +- dev_dbg(dev, "Request Suspend\n"); +- pm_runtime_mark_last_busy(dev); +- return pm_runtime_put_autosuspend(dev); +-} +- +-static int cs35l41_hda_resume_hook(struct device *dev) +-{ +- dev_dbg(dev, "Request Resume\n"); +- return pm_runtime_get_sync(dev); +-} +- + static int cs35l41_smart_amp(struct cs35l41_hda *cs35l41) + { + int halo_sts; +@@ -863,8 +858,6 @@ static int cs35l41_hda_bind(struct device *dev, struct device *master, void *mas + ret = cs35l41_create_controls(cs35l41); + + comps->playback_hook = cs35l41_hda_playback_hook; +- comps->suspend_hook = cs35l41_hda_suspend_hook; +- comps->resume_hook = cs35l41_hda_resume_hook; + + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); +diff --git a/sound/pci/hda/hda_component.h b/sound/pci/hda/hda_component.h +index 1223621bd62c..534e845b9cd1 100644 +--- a/sound/pci/hda/hda_component.h ++++ b/sound/pci/hda/hda_component.h +@@ -16,6 +16,4 @@ struct hda_component { + char name[HDA_MAX_NAME_SIZE]; + struct hda_codec *codec; + void (*playback_hook)(struct device *dev, int action); +- int (*suspend_hook)(struct device *dev); +- int (*resume_hook)(struct device *dev); + }; +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 4b076912bbf4..e6c4bb5fa041 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -4022,22 +4022,16 @@ static void alc5505_dsp_init(struct hda_codec *codec) + static int alc269_suspend(struct hda_codec *codec) + { + struct alc_spec *spec = codec->spec; +- int i; + + if (spec->has_alc5505_dsp) + alc5505_dsp_suspend(codec); + +- for (i = 0; i < HDA_MAX_COMPONENTS; i++) +- if (spec->comps[i].suspend_hook) +- spec->comps[i].suspend_hook(spec->comps[i].dev); +- + return alc_suspend(codec); + } + + static int alc269_resume(struct hda_codec *codec) + { + struct alc_spec *spec = codec->spec; +- int i; + + if (spec->codec_variant == ALC269_TYPE_ALC269VB) + alc269vb_toggle_power_output(codec, 0); +@@ -4068,10 +4062,6 @@ static int alc269_resume(struct hda_codec *codec) + if (spec->has_alc5505_dsp) + alc5505_dsp_resume(codec); + +- for (i = 0; i < HDA_MAX_COMPONENTS; i++) +- if (spec->comps[i].resume_hook) +- spec->comps[i].resume_hook(spec->comps[i].dev); +- + return 0; + } + #endif /* CONFIG_PM */ +@@ -6664,19 +6654,12 @@ static int comp_bind(struct device *dev) + { + struct hda_codec *cdc = dev_to_hda_codec(dev); + struct alc_spec *spec = cdc->spec; +- int ret, i; ++ int ret; + + ret = component_bind_all(dev, spec->comps); + if (ret) + return ret; + +- if (snd_hdac_is_power_on(&cdc->core)) { +- codec_dbg(cdc, "Resuming after bind.\n"); +- for (i = 0; i < HDA_MAX_COMPONENTS; i++) +- if (spec->comps[i].resume_hook) +- spec->comps[i].resume_hook(spec->comps[i].dev); +- } +- + return 0; + } + +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Reorganize-log-for-playback-actions.patch b/patches.suse/ALSA-hda-cs35l41-Reorganize-log-for-playback-actions.patch new file mode 100644 index 0000000..53d9a00 --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Reorganize-log-for-playback-actions.patch @@ -0,0 +1,66 @@ +From b50a99979865555381780dc1fea10afb3a0f98fa Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Wed, 13 Apr 2022 09:37:24 +0100 +Subject: [PATCH] ALSA: hda: cs35l41: Reorganize log for playback actions +Git-commit: b50a99979865555381780dc1fea10afb3a0f98fa +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +For each case, only log the last regmap access, so it doesn't get +overwritten, and as all regmap access should show the same issues +logging the last one should be enough. +Change to dev_err to log this error. + +Also, differentiate between a regmap access failure and invalid +playback action. + +Signed-off-by: Lucas Tanure +Link: https://lore.kernel.org/r/20220413083728.10730-13-tanureal@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 15 +++++++-------- + 1 file changed, 7 insertions(+), 8 deletions(-) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index ece784662dbd..3294837ff606 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -144,10 +144,9 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action) + + switch (action) { + case HDA_GEN_PCM_ACT_OPEN: +- ret = regmap_multi_reg_write(reg, cs35l41_hda_config, +- ARRAY_SIZE(cs35l41_hda_config)); +- regmap_update_bits(reg, CS35L41_PWR_CTRL2, +- CS35L41_AMP_EN_MASK, 1 << CS35L41_AMP_EN_SHIFT); ++ regmap_multi_reg_write(reg, cs35l41_hda_config, ARRAY_SIZE(cs35l41_hda_config)); ++ ret = regmap_update_bits(reg, CS35L41_PWR_CTRL2, ++ CS35L41_AMP_EN_MASK, 1 << CS35L41_AMP_EN_SHIFT); + break; + case HDA_GEN_PCM_ACT_PREPARE: + ret = cs35l41_hda_global_enable(cs35l41, 1); +@@ -157,16 +156,16 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action) + ret = cs35l41_hda_global_enable(cs35l41, 0); + break; + case HDA_GEN_PCM_ACT_CLOSE: +- regmap_update_bits(reg, CS35L41_PWR_CTRL2, +- CS35L41_AMP_EN_MASK, 0 << CS35L41_AMP_EN_SHIFT); ++ ret = regmap_update_bits(reg, CS35L41_PWR_CTRL2, ++ CS35L41_AMP_EN_MASK, 0 << CS35L41_AMP_EN_SHIFT); + break; + default: +- ret = -EINVAL; ++ dev_warn(cs35l41->dev, "Playback action not supported: %d\n", action); + break; + } + + if (ret) +- dev_warn(cs35l41->dev, "Failed to apply multi reg write: %d\n", ret); ++ dev_err(cs35l41->dev, "Regmap access fail: %d\n", ret); + } + + static int cs35l41_hda_channel_map(struct device *dev, unsigned int tx_num, unsigned int *tx_slot, +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Save-Subsystem-ID-inside-CS35L41-Dr.patch b/patches.suse/ALSA-hda-cs35l41-Save-Subsystem-ID-inside-CS35L41-Dr.patch new file mode 100644 index 0000000..1f73d48 --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Save-Subsystem-ID-inside-CS35L41-Dr.patch @@ -0,0 +1,52 @@ +From e99f3c7e3250dd895d2da506d0d910d641136d2c Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Thu, 30 Jun 2022 01:23:26 +0100 +Subject: [PATCH] ALSA: hda: cs35l41: Save Subsystem ID inside CS35L41 Driver +Git-commit: e99f3c7e3250dd895d2da506d0d910d641136d2c +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +The Subsystem ID is read from the HDA driver, and will +be used by the CS35L41 driver to be able to uniquely +identify the laptop, which is required to be able to +define firmware to be used by specific models. + +Signed-off-by: Stefan Binding +Signed-off-by: Vitaly Rodionov +Link: https://lore.kernel.org/r/20220630002335.366545-6-vitalyr@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 3 +++ + sound/pci/hda/cs35l41_hda.h | 1 + + 2 files changed, 4 insertions(+) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index d68d951c434e..25cb76437ba5 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -355,6 +355,9 @@ static int cs35l41_hda_bind(struct device *dev, struct device *master, void *mas + return -EBUSY; + + comps->dev = dev; ++ if (!cs35l41->acpi_subsystem_id) ++ cs35l41->acpi_subsystem_id = devm_kasprintf(dev, GFP_KERNEL, "%.8x", ++ comps->codec->core.subsystem_id); + cs35l41->codec = comps->codec; + strscpy(comps->name, dev_name(dev), sizeof(comps->name)); + comps->playback_hook = cs35l41_hda_playback_hook; +diff --git a/sound/pci/hda/cs35l41_hda.h b/sound/pci/hda/cs35l41_hda.h +index 5814af050944..b57f59a1ba49 100644 +--- a/sound/pci/hda/cs35l41_hda.h ++++ b/sound/pci/hda/cs35l41_hda.h +@@ -42,6 +42,7 @@ struct cs35l41_hda { + int channel_index; + unsigned volatile long irq_errors; + const char *amp_name; ++ const char *acpi_subsystem_id; + struct mutex fw_mutex; + struct regmap_irq_chip_data *irq_data; + bool firmware_running; +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Save-codec-object-inside-component-.patch b/patches.suse/ALSA-hda-cs35l41-Save-codec-object-inside-component-.patch new file mode 100644 index 0000000..d178112 --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Save-codec-object-inside-component-.patch @@ -0,0 +1,61 @@ +From 22d5cbd273a2ca90ba026ec82f0b9c3e984b0c1c Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Thu, 30 Jun 2022 01:23:24 +0100 +Subject: [PATCH] ALSA: hda: cs35l41: Save codec object inside component struct +Git-commit: 22d5cbd273a2ca90ba026ec82f0b9c3e984b0c1c +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +This is required for ALSA control support. + +Signed-off-by: Stefan Binding +Signed-off-by: Vitaly Rodionov +Link: https://lore.kernel.org/r/20220630002335.366545-4-vitalyr@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 1 + + sound/pci/hda/cs35l41_hda.h | 1 + + sound/pci/hda/hda_component.h | 1 + + sound/pci/hda/patch_realtek.c | 1 + + 4 files changed, 4 insertions(+) + +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -117,6 +117,7 @@ static int cs35l41_hda_bind(struct devic + return -EBUSY; + + comps->dev = dev; ++ cs35l41->codec = comps->codec; + strscpy(comps->name, dev_name(dev), sizeof(comps->name)); + comps->playback_hook = cs35l41_hda_playback_hook; + +--- a/sound/pci/hda/cs35l41_hda.h ++++ b/sound/pci/hda/cs35l41_hda.h +@@ -32,6 +32,7 @@ struct cs35l41_hda { + struct regmap *regmap; + struct gpio_desc *reset_gpio; + struct cs35l41_hw_cfg hw_cfg; ++ struct hda_codec *codec; + + int irq; + int index; +--- a/sound/pci/hda/hda_component.h ++++ b/sound/pci/hda/hda_component.h +@@ -14,5 +14,6 @@ + struct hda_component { + struct device *dev; + char name[HDA_MAX_NAME_SIZE]; ++ struct hda_codec *codec; + void (*playback_hook)(struct device *dev, int action); + }; +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -6701,6 +6701,7 @@ static void cs35l41_generic_fixup(struct + "%s-%s:00-cs35l41-hda.%d", bus, hid, i); + if (!name) + return; ++ spec->comps[i].codec = cdc; + component_match_add(dev, &spec->match, comp_match_dev_name, name); + } + ret = component_master_add_with_match(dev, &comp_master_ops, spec->match); diff --git a/patches.suse/ALSA-hda-cs35l41-Set-Speaker-Position-for-CLSA0100-L.patch b/patches.suse/ALSA-hda-cs35l41-Set-Speaker-Position-for-CLSA0100-L.patch new file mode 100644 index 0000000..d4d381f --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Set-Speaker-Position-for-CLSA0100-L.patch @@ -0,0 +1,35 @@ +From 775d667539a4dd8b9f7015c5da5526999f1d5bf1 Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Mon, 9 May 2022 22:46:39 +0100 +Subject: [PATCH] ALSA: hda: cs35l41: Set Speaker Position for CLSA0100 Laptop +Git-commit: 775d667539a4dd8b9f7015c5da5526999f1d5bf1 +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +This laptop does not contain required properties inside ACPI, +instead the values are be hardcoded inside the driver. + +Signed-off-by: Stefan Binding +Signed-off-by: Vitaly Rodionov +Link: https://lore.kernel.org/r/20220509214703.4482-3-vitalyr@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index bc277b352ac9..d7e90c0cae51 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -281,6 +281,7 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i + + /* check I2C address to assign the index */ + cs35l41->index = id == 0x40 ? 0 : 1; ++ cs35l41->hw_cfg.spk_pos = cs35l41->index; + cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 0, GPIOD_OUT_HIGH); + cs35l41->hw_cfg.bst_type = CS35L41_EXT_BOOST_NO_VSPK_SWITCH; + cs35l41->hw_cfg.valid = true; +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Support-CLSA0101.patch b/patches.suse/ALSA-hda-cs35l41-Support-CLSA0101.patch new file mode 100644 index 0000000..7f4d5b1 --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Support-CLSA0101.patch @@ -0,0 +1,179 @@ +From 1e24881d8b2a7c198a67fe9e5179e9efb2140df7 Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Wed, 27 Jul 2022 10:59:22 +0100 +Subject: [PATCH] ALSA: hda: cs35l41: Support CLSA0101 +Git-commit: 1e24881d8b2a7c198a67fe9e5179e9efb2140df7 +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +Add support for Intel version of Legion 7 laptop. + +Signed-off-by: Lucas Tanure +Link: https://lore.kernel.org/r/20220727095924.80884-3-tanureal@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 66 ++++++++++++++++++++------------- + sound/pci/hda/cs35l41_hda_i2c.c | 3 ++ + sound/pci/hda/patch_realtek.c | 12 ++++++ + 3 files changed, 55 insertions(+), 26 deletions(-) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index 9af5e2e9be55..129bffb431c2 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -1133,6 +1133,45 @@ static int cs35l41_get_speaker_id(struct device *dev, int amp_index, + return speaker_id; + } + ++/* ++ * Device CLSA010(0/1) doesn't have _DSD so a gpiod_get by the label reset won't work. ++ * And devices created by serial-multi-instantiate don't have their device struct ++ * pointing to the correct fwnode, so acpi_dev must be used here. ++ * And devm functions expect that the device requesting the resource has the correct ++ * fwnode. ++ */ ++static int cs35l41_no_acpi_dsd(struct cs35l41_hda *cs35l41, struct device *physdev, int id, ++ const char *hid) ++{ ++ struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg; ++ ++ /* check I2C address to assign the index */ ++ cs35l41->index = id == 0x40 ? 0 : 1; ++ cs35l41->channel_index = 0; ++ cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 0, GPIOD_OUT_HIGH); ++ cs35l41->speaker_id = cs35l41_get_speaker_id(physdev, 0, 0, 2); ++ hw_cfg->spk_pos = cs35l41->index; ++ hw_cfg->gpio2.func = CS35L41_INTERRUPT; ++ hw_cfg->gpio2.valid = true; ++ hw_cfg->valid = true; ++ put_device(physdev); ++ ++ if (strncmp(hid, "CLSA0100", 8) == 0) { ++ hw_cfg->bst_type = CS35L41_EXT_BOOST_NO_VSPK_SWITCH; ++ } else if (strncmp(hid, "CLSA0101", 8) == 0) { ++ hw_cfg->bst_type = CS35L41_EXT_BOOST; ++ hw_cfg->gpio1.func = CS35l41_VSPK_SWITCH; ++ hw_cfg->gpio1.valid = true; ++ } else { ++ hw_cfg->valid = false; ++ hw_cfg->gpio1.valid = false; ++ hw_cfg->gpio2.valid = false; ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ + static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, int id) + { + struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg; +@@ -1161,7 +1200,7 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i + property = "cirrus,dev-index"; + ret = device_property_count_u32(physdev, property); + if (ret <= 0) +- goto no_acpi_dsd; ++ return cs35l41_no_acpi_dsd(cs35l41, physdev, id, hid); + + if (ret > ARRAY_SIZE(values)) { + ret = -EINVAL; +@@ -1255,31 +1294,6 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i + dev_err(cs35l41->dev, "Failed property %s: %d\n", property, ret); + + return ret; +- +-no_acpi_dsd: +- /* +- * Device CLSA0100 doesn't have _DSD so a gpiod_get by the label reset won't work. +- * And devices created by serial-multi-instantiate don't have their device struct +- * pointing to the correct fwnode, so acpi_dev must be used here. +- * And devm functions expect that the device requesting the resource has the correct +- * fwnode. +- */ +- if (strncmp(hid, "CLSA0100", 8) != 0) +- return -EINVAL; +- +- /* check I2C address to assign the index */ +- cs35l41->index = id == 0x40 ? 0 : 1; +- cs35l41->hw_cfg.spk_pos = cs35l41->index; +- cs35l41->channel_index = 0; +- cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 0, GPIOD_OUT_HIGH); +- cs35l41->hw_cfg.bst_type = CS35L41_EXT_BOOST_NO_VSPK_SWITCH; +- cs35l41->speaker_id = cs35l41_get_speaker_id(physdev, 0, 0, 2); +- hw_cfg->gpio2.func = CS35L41_INTERRUPT; +- hw_cfg->gpio2.valid = true; +- cs35l41->hw_cfg.valid = true; +- put_device(physdev); +- +- return 0; + } + + int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq, +diff --git a/sound/pci/hda/cs35l41_hda_i2c.c b/sound/pci/hda/cs35l41_hda_i2c.c +index 9c08fa08c421..5baacfde4f16 100644 +--- a/sound/pci/hda/cs35l41_hda_i2c.c ++++ b/sound/pci/hda/cs35l41_hda_i2c.c +@@ -22,6 +22,8 @@ static int cs35l41_hda_i2c_probe(struct i2c_client *clt, const struct i2c_device + */ + if (strstr(dev_name(&clt->dev), "CLSA0100")) + device_name = "CLSA0100"; ++ else if (strstr(dev_name(&clt->dev), "CLSA0101")) ++ device_name = "CLSA0101"; + else if (strstr(dev_name(&clt->dev), "CSC3551")) + device_name = "CSC3551"; + else +@@ -45,6 +47,7 @@ static const struct i2c_device_id cs35l41_hda_i2c_id[] = { + + static const struct acpi_device_id cs35l41_acpi_hda_match[] = { + {"CLSA0100", 0 }, ++ {"CLSA0101", 0 }, + {"CSC3551", 0 }, + {} + }; +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 06bb55399564..e1fbda215975 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -6710,6 +6710,12 @@ static void alc287_fixup_legion_16achg6_speakers(struct hda_codec *cdc, const st + cs35l41_generic_fixup(cdc, action, "i2c", "CLSA0100", 2); + } + ++static void alc287_fixup_legion_16ithg6_speakers(struct hda_codec *cdc, const struct hda_fixup *fix, ++ int action) ++{ ++ cs35l41_generic_fixup(cdc, action, "i2c", "CLSA0101", 2); ++} ++ + /* for alc295_fixup_hp_top_speakers */ + #include "hp_x360_helper.c" + +@@ -7047,6 +7053,7 @@ enum { + ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED, + ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED, + ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE, ++ ALC287_FIXUP_LEGION_16ITHG6, + }; + + /* A special fixup for Lenovo C940 and Yoga Duet 7; +@@ -8889,6 +8896,10 @@ static const struct hda_fixup alc269_fixups[] = { + .chained = true, + .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC + }, ++ [ALC287_FIXUP_LEGION_16ITHG6] = { ++ .type = HDA_FIXUP_FUNC, ++ .v.func = alc287_fixup_legion_16ithg6_speakers, ++ }, + }; + + static const struct snd_pci_quirk alc269_fixup_tbl[] = { +@@ -9355,6 +9366,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x384a, "Lenovo Yoga 7 15ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS), + SND_PCI_QUIRK(0x17aa, 0x3852, "Lenovo Yoga 7 14ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS), + SND_PCI_QUIRK(0x17aa, 0x3853, "Lenovo Yoga 7 15ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS), ++ SND_PCI_QUIRK(0x17aa, 0x3855, "Legion 7 16ITHG6", ALC287_FIXUP_LEGION_16ITHG6), + SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI), + SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC), + SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI), +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Support-Firmware-switching-and-relo.patch b/patches.suse/ALSA-hda-cs35l41-Support-Firmware-switching-and-relo.patch new file mode 100644 index 0000000..cf3e93c --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Support-Firmware-switching-and-relo.patch @@ -0,0 +1,347 @@ +From 47ceabd99a28399f8971f4ca0a37ebc0a21dd2a8 Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Thu, 30 Jun 2022 01:23:34 +0100 +Subject: [PATCH] ALSA: hda: cs35l41: Support Firmware switching and reloading +Git-commit: 47ceabd99a28399f8971f4ca0a37ebc0a21dd2a8 +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +This is required to support CS35L41 calibration. + +By default, speaker protection firmware will be loaded, if +available. However, different firmware is required to run +the calibration sequence, so it is necessary to add support +to be able to unload, switch and reload firmware. + +This patch adds 2 ALSA Controls for each amp: +"DSP1 Firmware Load" +"DSP1 Firmware Type" + +"DSP1 Firmware Load" can be used to unload and +load the firmware. +"DSP1 Firmware Type" can be used to switch the +target firmware to be loaded by "DSP1 Firmware Load" + +Since loading firmware can add new ALSA controls, it is +necessary to ensure the firmware loading is run asynchronously +from the ALSA control itself to prevent deadlocks. + +Note: When switching between firmwares, an ALSA control is +only added if it has not previously existed. If it had existed +previously, it will be re-enabled instead. + +Signed-off-by: Stefan Binding +Signed-off-by: Vitaly Rodionov +Link: https://lore.kernel.org/r/20220630002335.366545-14-vitalyr@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 182 ++++++++++++++++++++++++++++++++++-- + sound/pci/hda/cs35l41_hda.h | 6 ++ + 2 files changed, 178 insertions(+), 10 deletions(-) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index a02a74f68c2d..4252c0ac69b7 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -21,7 +21,6 @@ + + #define CS35L41_FIRMWARE_ROOT "cirrus/" + #define CS35L41_PART "cs35l41" +-#define FW_NAME "CSPL" + + #define HALO_STATE_DSP_CTL_NAME "HALO_STATE" + #define HALO_STATE_DSP_CTL_TYPE 5 +@@ -92,7 +91,7 @@ static int cs35l41_control_add(struct cs_dsp_coeff_ctl *cs_ctl) + struct hda_cs_dsp_ctl_info info; + + info.device_name = cs35l41->amp_name; +- info.fw_type = HDA_CS_DSP_FW_SPK_PROT; ++ info.fw_type = cs35l41->firmware_type; + info.card = cs35l41->codec->card; + + return hda_cs_dsp_control_add(cs_ctl, &info); +@@ -114,20 +113,24 @@ static int cs35l41_request_firmware_file(struct cs35l41_hda *cs35l41, + + if (spkid > -1 && ssid && amp_name) + *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s-spkid%d-%s.%s", dir, CS35L41_PART, +- dsp_name, "spk-prot", ssid, spkid, amp_name, filetype); ++ dsp_name, hda_cs_dsp_fw_ids[cs35l41->firmware_type], ++ ssid, spkid, amp_name, filetype); + else if (spkid > -1 && ssid) + *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s-spkid%d.%s", dir, CS35L41_PART, +- dsp_name, "spk-prot", ssid, spkid, filetype); ++ dsp_name, hda_cs_dsp_fw_ids[cs35l41->firmware_type], ++ ssid, spkid, filetype); + else if (ssid && amp_name) + *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s-%s.%s", dir, CS35L41_PART, +- dsp_name, "spk-prot", ssid, amp_name, +- filetype); ++ dsp_name, hda_cs_dsp_fw_ids[cs35l41->firmware_type], ++ ssid, amp_name, filetype); + else if (ssid) + *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s.%s", dir, CS35L41_PART, +- dsp_name, "spk-prot", ssid, filetype); ++ dsp_name, hda_cs_dsp_fw_ids[cs35l41->firmware_type], ++ ssid, filetype); + else + *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s.%s", dir, CS35L41_PART, +- dsp_name, "spk-prot", filetype); ++ dsp_name, hda_cs_dsp_fw_ids[cs35l41->firmware_type], ++ filetype); + + if (*filename == NULL) + return -ENOMEM; +@@ -422,7 +425,7 @@ static int cs35l41_init_dsp(struct cs35l41_hda *cs35l41) + dev_warn(cs35l41->dev, "No Coefficient File available.\n"); + + ret = cs_dsp_power_up(dsp, wmfw_firmware, wmfw_filename, coeff_firmware, coeff_filename, +- FW_NAME); ++ hda_cs_dsp_fw_ids[cs35l41->firmware_type]); + if (ret) + goto err_release; + +@@ -451,6 +454,7 @@ static void cs35l41_remove_dsp(struct cs35l41_hda *cs35l41) + { + struct cs_dsp *dsp = &cs35l41->cs_dsp; + ++ cancel_work_sync(&cs35l41->fw_load_work); + cs35l41_shutdown_dsp(cs35l41); + cs_dsp_remove(dsp); + cs35l41->halo_initialized = false; +@@ -481,6 +485,7 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action) + + switch (action) { + case HDA_GEN_PCM_ACT_OPEN: ++ cs35l41->playback_started = true; + if (cs35l41->firmware_running) { + regmap_multi_reg_write(reg, cs35l41_hda_config_dsp, + ARRAY_SIZE(cs35l41_hda_config_dsp)); +@@ -518,6 +523,7 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action) + 0 << CS35L41_VMON_EN_SHIFT | 0 << CS35L41_IMON_EN_SHIFT); + } + cs35l41_irq_release(cs35l41); ++ cs35l41->playback_started = false; + break; + default: + dev_warn(cs35l41->dev, "Playback action not supported: %d\n", action); +@@ -664,10 +670,160 @@ static int cs35l41_smart_amp(struct cs35l41_hda *cs35l41) + return ret; + } + ++static void cs35l41_load_firmware(struct cs35l41_hda *cs35l41, bool load) ++{ ++ pm_runtime_get_sync(cs35l41->dev); ++ ++ if (cs35l41->firmware_running && !load) { ++ dev_dbg(cs35l41->dev, "Unloading Firmware\n"); ++ cs35l41_shutdown_dsp(cs35l41); ++ } else if (!cs35l41->firmware_running && load) { ++ dev_dbg(cs35l41->dev, "Loading Firmware\n"); ++ cs35l41_smart_amp(cs35l41); ++ } else { ++ dev_dbg(cs35l41->dev, "Unable to Load firmware.\n"); ++ } ++ ++ pm_runtime_mark_last_busy(cs35l41->dev); ++ pm_runtime_put_autosuspend(cs35l41->dev); ++} ++ ++static int cs35l41_fw_load_ctl_get(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct cs35l41_hda *cs35l41 = snd_kcontrol_chip(kcontrol); ++ ++ ucontrol->value.integer.value[0] = cs35l41->request_fw_load; ++ return 0; ++} ++ ++static void cs35l41_fw_load_work(struct work_struct *work) ++{ ++ struct cs35l41_hda *cs35l41 = container_of(work, struct cs35l41_hda, fw_load_work); ++ ++ mutex_lock(&cs35l41->fw_mutex); ++ ++ /* Recheck if playback is ongoing, mutex will block playback during firmware loading */ ++ if (cs35l41->playback_started) ++ dev_err(cs35l41->dev, "Cannot Load/Unload firmware during Playback\n"); ++ else ++ cs35l41_load_firmware(cs35l41, cs35l41->request_fw_load); ++ ++ cs35l41->fw_request_ongoing = false; ++ mutex_unlock(&cs35l41->fw_mutex); ++} ++ ++static int cs35l41_fw_load_ctl_put(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct cs35l41_hda *cs35l41 = snd_kcontrol_chip(kcontrol); ++ unsigned int ret = 0; ++ ++ mutex_lock(&cs35l41->fw_mutex); ++ ++ if (cs35l41->request_fw_load == ucontrol->value.integer.value[0]) ++ goto err; ++ ++ if (cs35l41->fw_request_ongoing) { ++ dev_dbg(cs35l41->dev, "Existing request not complete\n"); ++ ret = -EBUSY; ++ goto err; ++ } ++ ++ /* Check if playback is ongoing when initial request is made */ ++ if (cs35l41->playback_started) { ++ dev_err(cs35l41->dev, "Cannot Load/Unload firmware during Playback\n"); ++ ret = -EBUSY; ++ goto err; ++ } ++ ++ cs35l41->fw_request_ongoing = true; ++ cs35l41->request_fw_load = ucontrol->value.integer.value[0]; ++ schedule_work(&cs35l41->fw_load_work); ++ ++err: ++ mutex_unlock(&cs35l41->fw_mutex); ++ ++ return ret; ++} ++ ++static int cs35l41_fw_type_ctl_get(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct cs35l41_hda *cs35l41 = snd_kcontrol_chip(kcontrol); ++ ++ ucontrol->value.enumerated.item[0] = cs35l41->firmware_type; ++ ++ return 0; ++} ++ ++static int cs35l41_fw_type_ctl_put(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct cs35l41_hda *cs35l41 = snd_kcontrol_chip(kcontrol); ++ ++ if (ucontrol->value.enumerated.item[0] < HDA_CS_DSP_NUM_FW) { ++ cs35l41->firmware_type = ucontrol->value.enumerated.item[0]; ++ return 0; ++ } ++ ++ return -EINVAL; ++} ++ ++static int cs35l41_fw_type_ctl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) ++{ ++ return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(hda_cs_dsp_fw_ids), hda_cs_dsp_fw_ids); ++} ++ ++static int cs35l41_create_controls(struct cs35l41_hda *cs35l41) ++{ ++ char fw_type_ctl_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; ++ char fw_load_ctl_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; ++ struct snd_kcontrol_new fw_type_ctl = { ++ .name = fw_type_ctl_name, ++ .iface = SNDRV_CTL_ELEM_IFACE_CARD, ++ .info = cs35l41_fw_type_ctl_info, ++ .get = cs35l41_fw_type_ctl_get, ++ .put = cs35l41_fw_type_ctl_put, ++ }; ++ struct snd_kcontrol_new fw_load_ctl = { ++ .name = fw_load_ctl_name, ++ .iface = SNDRV_CTL_ELEM_IFACE_CARD, ++ .info = snd_ctl_boolean_mono_info, ++ .get = cs35l41_fw_load_ctl_get, ++ .put = cs35l41_fw_load_ctl_put, ++ }; ++ int ret; ++ ++ scnprintf(fw_type_ctl_name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s DSP1 Firmware Type", ++ cs35l41->amp_name); ++ scnprintf(fw_load_ctl_name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s DSP1 Firmware Load", ++ cs35l41->amp_name); ++ ++ ret = snd_ctl_add(cs35l41->codec->card, snd_ctl_new1(&fw_type_ctl, cs35l41)); ++ if (ret) { ++ dev_err(cs35l41->dev, "Failed to add KControl %s = %d\n", fw_type_ctl.name, ret); ++ return ret; ++ } ++ ++ dev_dbg(cs35l41->dev, "Added Control %s\n", fw_type_ctl.name); ++ ++ ret = snd_ctl_add(cs35l41->codec->card, snd_ctl_new1(&fw_load_ctl, cs35l41)); ++ if (ret) { ++ dev_err(cs35l41->dev, "Failed to add KControl %s = %d\n", fw_load_ctl.name, ret); ++ return ret; ++ } ++ ++ dev_dbg(cs35l41->dev, "Added Control %s\n", fw_load_ctl.name); ++ ++ return 0; ++} ++ + static int cs35l41_hda_bind(struct device *dev, struct device *master, void *master_data) + { + struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); + struct hda_component *comps = master_data; ++ int ret = 0; + + if (!comps || cs35l41->index < 0 || cs35l41->index >= HDA_MAX_COMPONENTS) + return -EINVAL; +@@ -685,11 +841,16 @@ static int cs35l41_hda_bind(struct device *dev, struct device *master, void *mas + cs35l41->codec = comps->codec; + strscpy(comps->name, dev_name(dev), sizeof(comps->name)); + ++ cs35l41->firmware_type = HDA_CS_DSP_FW_SPK_PROT; ++ ++ cs35l41->request_fw_load = true; + mutex_lock(&cs35l41->fw_mutex); + if (cs35l41_smart_amp(cs35l41) < 0) + dev_warn(cs35l41->dev, "Cannot Run Firmware, reverting to dsp bypass...\n"); + mutex_unlock(&cs35l41->fw_mutex); + ++ ret = cs35l41_create_controls(cs35l41); ++ + comps->playback_hook = cs35l41_hda_playback_hook; + comps->suspend_hook = cs35l41_hda_suspend_hook; + comps->resume_hook = cs35l41_hda_resume_hook; +@@ -697,7 +858,7 @@ static int cs35l41_hda_bind(struct device *dev, struct device *master, void *mas + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + +- return 0; ++ return ret; + } + + static void cs35l41_hda_unbind(struct device *dev, struct device *master, void *master_data) +@@ -1206,6 +1367,7 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i + if (ret) + goto err; + ++ INIT_WORK(&cs35l41->fw_load_work, cs35l41_fw_load_work); + mutex_init(&cs35l41->fw_mutex); + + pm_runtime_set_autosuspend_delay(cs35l41->dev, 3000); +diff --git a/sound/pci/hda/cs35l41_hda.h b/sound/pci/hda/cs35l41_hda.h +index 59a9461d0444..bdb35f3be68a 100644 +--- a/sound/pci/hda/cs35l41_hda.h ++++ b/sound/pci/hda/cs35l41_hda.h +@@ -58,11 +58,17 @@ struct cs35l41_hda { + unsigned volatile long irq_errors; + const char *amp_name; + const char *acpi_subsystem_id; ++ int firmware_type; + int speaker_id; + struct mutex fw_mutex; ++ struct work_struct fw_load_work; ++ + struct regmap_irq_chip_data *irq_data; + bool firmware_running; ++ bool request_fw_load; ++ bool fw_request_ongoing; + bool halo_initialized; ++ bool playback_started; + struct cs_dsp cs_dsp; + }; + +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Support-Hibernation-during-Suspend.patch b/patches.suse/ALSA-hda-cs35l41-Support-Hibernation-during-Suspend.patch new file mode 100644 index 0000000..169844b --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Support-Hibernation-during-Suspend.patch @@ -0,0 +1,340 @@ +From 1873ebd30cc818eefd151e40a4bd05fd8f83b85a Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Thu, 30 Jun 2022 01:23:30 +0100 +Subject: [PATCH] ALSA: hda: cs35l41: Support Hibernation during Suspend +Git-commit: 1873ebd30cc818eefd151e40a4bd05fd8f83b85a +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +CS35L41 supports hibernation during suspend when using +DSP firmware. +When the driver suspends it will hibernate the part, if +firmware is running, and resume will wake from hibernation. +CS35L41 driver will suspend/resume when requested by +hda driver. +Note that suspend/resume and hibernation is only supported +when firmware is running. + +Signed-off-by: Stefan Binding +Signed-off-by: Vitaly Rodionov +Link: https://lore.kernel.org/r/20220630002335.366545-10-vitalyr@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 109 +++++++++++++++++++++++++++++++- + sound/pci/hda/cs35l41_hda.h | 2 + + sound/pci/hda/cs35l41_hda_i2c.c | 1 + + sound/pci/hda/cs35l41_hda_spi.c | 1 + + sound/pci/hda/hda_component.h | 2 + + sound/pci/hda/patch_realtek.c | 25 +++++++- + 6 files changed, 136 insertions(+), 4 deletions(-) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index d5d2323cc8c7..61441bfc9fa9 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + #include "hda_local.h" + #include "hda_auto_parser.h" + #include "hda_jack.h" +@@ -435,6 +436,75 @@ static int cs35l41_hda_channel_map(struct device *dev, unsigned int tx_num, unsi + rx_slot); + } + ++static int cs35l41_runtime_suspend(struct device *dev) ++{ ++ struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); ++ ++ dev_dbg(cs35l41->dev, "Suspend\n"); ++ ++ if (!cs35l41->firmware_running) ++ return 0; ++ ++ if (cs35l41_enter_hibernate(cs35l41->dev, cs35l41->regmap, cs35l41->hw_cfg.bst_type) < 0) ++ return 0; ++ ++ regcache_cache_only(cs35l41->regmap, true); ++ regcache_mark_dirty(cs35l41->regmap); ++ ++ return 0; ++} ++ ++static int cs35l41_runtime_resume(struct device *dev) ++{ ++ struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); ++ int ret; ++ ++ dev_dbg(cs35l41->dev, "Resume.\n"); ++ ++ if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST_NO_VSPK_SWITCH) { ++ dev_dbg(cs35l41->dev, "System does not support Resume\n"); ++ return 0; ++ } ++ ++ if (!cs35l41->firmware_running) ++ return 0; ++ ++ regcache_cache_only(cs35l41->regmap, false); ++ ++ ret = cs35l41_exit_hibernate(cs35l41->dev, cs35l41->regmap); ++ if (ret) { ++ regcache_cache_only(cs35l41->regmap, true); ++ return ret; ++ } ++ ++ /* Test key needs to be unlocked to allow the OTP settings to re-apply */ ++ cs35l41_test_key_unlock(cs35l41->dev, cs35l41->regmap); ++ ret = regcache_sync(cs35l41->regmap); ++ cs35l41_test_key_lock(cs35l41->dev, cs35l41->regmap); ++ if (ret) { ++ dev_err(cs35l41->dev, "Failed to restore register cache: %d\n", ret); ++ return ret; ++ } ++ ++ if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST) ++ cs35l41_init_boost(cs35l41->dev, cs35l41->regmap, &cs35l41->hw_cfg); ++ ++ return 0; ++} ++ ++static int cs35l41_hda_suspend_hook(struct device *dev) ++{ ++ dev_dbg(dev, "Request Suspend\n"); ++ pm_runtime_mark_last_busy(dev); ++ return pm_runtime_put_autosuspend(dev); ++} ++ ++static int cs35l41_hda_resume_hook(struct device *dev) ++{ ++ dev_dbg(dev, "Request Resume\n"); ++ return pm_runtime_get_sync(dev); ++} ++ + static int cs35l41_smart_amp(struct cs35l41_hda *cs35l41) + { + int halo_sts; +@@ -492,19 +562,27 @@ static int cs35l41_hda_bind(struct device *dev, struct device *master, void *mas + if (comps->dev) + return -EBUSY; + ++ pm_runtime_get_sync(dev); ++ + comps->dev = dev; + if (!cs35l41->acpi_subsystem_id) + cs35l41->acpi_subsystem_id = devm_kasprintf(dev, GFP_KERNEL, "%.8x", + comps->codec->core.subsystem_id); + cs35l41->codec = comps->codec; + strscpy(comps->name, dev_name(dev), sizeof(comps->name)); +- comps->playback_hook = cs35l41_hda_playback_hook; + + mutex_lock(&cs35l41->fw_mutex); + if (cs35l41_smart_amp(cs35l41) < 0) + dev_warn(cs35l41->dev, "Cannot Run Firmware, reverting to dsp bypass...\n"); + mutex_unlock(&cs35l41->fw_mutex); + ++ comps->playback_hook = cs35l41_hda_playback_hook; ++ comps->suspend_hook = cs35l41_hda_suspend_hook; ++ comps->resume_hook = cs35l41_hda_resume_hook; ++ ++ pm_runtime_mark_last_busy(dev); ++ pm_runtime_put_autosuspend(dev); ++ + return 0; + } + +@@ -600,7 +678,7 @@ static const struct regmap_irq cs35l41_reg_irqs[] = { + CS35L41_REG_IRQ(IRQ1_STATUS1, AMP_SHORT_ERR), + }; + +-static const struct regmap_irq_chip cs35l41_regmap_irq_chip = { ++static struct regmap_irq_chip cs35l41_regmap_irq_chip = { + .name = "cs35l41 IRQ1 Controller", + .status_base = CS35L41_IRQ1_STATUS1, + .mask_base = CS35L41_IRQ1_MASK1, +@@ -608,6 +686,7 @@ static const struct regmap_irq_chip cs35l41_regmap_irq_chip = { + .num_regs = 4, + .irqs = cs35l41_reg_irqs, + .num_irqs = ARRAY_SIZE(cs35l41_reg_irqs), ++ .runtime_pm = true, + }; + + static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41) +@@ -1015,13 +1094,23 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i + + mutex_init(&cs35l41->fw_mutex); + ++ pm_runtime_set_autosuspend_delay(cs35l41->dev, 3000); ++ pm_runtime_use_autosuspend(cs35l41->dev); ++ pm_runtime_mark_last_busy(cs35l41->dev); ++ pm_runtime_set_active(cs35l41->dev); ++ pm_runtime_get_noresume(cs35l41->dev); ++ pm_runtime_enable(cs35l41->dev); ++ + ret = cs35l41_hda_apply_properties(cs35l41); + if (ret) +- goto err; ++ goto err_pm; ++ ++ pm_runtime_put_autosuspend(cs35l41->dev); + + ret = component_add(cs35l41->dev, &cs35l41_hda_comp_ops); + if (ret) { + dev_err(cs35l41->dev, "Register component failed: %d\n", ret); ++ pm_runtime_disable(cs35l41->dev); + goto err; + } + +@@ -1029,6 +1118,10 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i + + return 0; + ++err_pm: ++ pm_runtime_disable(cs35l41->dev); ++ pm_runtime_put_noidle(cs35l41->dev); ++ + err: + if (cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type)) + gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); +@@ -1042,17 +1135,27 @@ void cs35l41_hda_remove(struct device *dev) + { + struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); + ++ pm_runtime_get_sync(cs35l41->dev); ++ pm_runtime_disable(cs35l41->dev); ++ + if (cs35l41->halo_initialized) + cs35l41_remove_dsp(cs35l41); + + component_del(cs35l41->dev, &cs35l41_hda_comp_ops); + ++ pm_runtime_put_noidle(cs35l41->dev); ++ + if (cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type)) + gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); + gpiod_put(cs35l41->reset_gpio); + } + EXPORT_SYMBOL_NS_GPL(cs35l41_hda_remove, SND_HDA_SCODEC_CS35L41); + ++const struct dev_pm_ops cs35l41_hda_pm_ops = { ++ SET_RUNTIME_PM_OPS(cs35l41_runtime_suspend, cs35l41_runtime_resume, NULL) ++}; ++EXPORT_SYMBOL_NS_GPL(cs35l41_hda_pm_ops, SND_HDA_SCODEC_CS35L41); ++ + MODULE_DESCRIPTION("CS35L41 HDA Driver"); + MODULE_IMPORT_NS(SND_HDA_CS_DSP_CONTROLS); + MODULE_AUTHOR("Lucas Tanure, Cirrus Logic Inc, "); +diff --git a/sound/pci/hda/cs35l41_hda.h b/sound/pci/hda/cs35l41_hda.h +index a9dbc1c19248..439c4b705328 100644 +--- a/sound/pci/hda/cs35l41_hda.h ++++ b/sound/pci/hda/cs35l41_hda.h +@@ -57,6 +57,8 @@ enum halo_state { + HALO_STATE_CODE_RUN + }; + ++extern const struct dev_pm_ops cs35l41_hda_pm_ops; ++ + int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq, + struct regmap *regmap); + void cs35l41_hda_remove(struct device *dev); +diff --git a/sound/pci/hda/cs35l41_hda_i2c.c b/sound/pci/hda/cs35l41_hda_i2c.c +index df39fc76e6be..9c08fa08c421 100644 +--- a/sound/pci/hda/cs35l41_hda_i2c.c ++++ b/sound/pci/hda/cs35l41_hda_i2c.c +@@ -54,6 +54,7 @@ static struct i2c_driver cs35l41_i2c_driver = { + .driver = { + .name = "cs35l41-hda", + .acpi_match_table = cs35l41_acpi_hda_match, ++ .pm = &cs35l41_hda_pm_ops, + }, + .id_table = cs35l41_hda_i2c_id, + .probe = cs35l41_hda_i2c_probe, +diff --git a/sound/pci/hda/cs35l41_hda_spi.c b/sound/pci/hda/cs35l41_hda_spi.c +index 2f5afad3719e..71979cfb4d7e 100644 +--- a/sound/pci/hda/cs35l41_hda_spi.c ++++ b/sound/pci/hda/cs35l41_hda_spi.c +@@ -49,6 +49,7 @@ static struct spi_driver cs35l41_spi_driver = { + .driver = { + .name = "cs35l41-hda", + .acpi_match_table = cs35l41_acpi_hda_match, ++ .pm = &cs35l41_hda_pm_ops, + }, + .id_table = cs35l41_hda_spi_id, + .probe = cs35l41_hda_spi_probe, +diff --git a/sound/pci/hda/hda_component.h b/sound/pci/hda/hda_component.h +index 534e845b9cd1..1223621bd62c 100644 +--- a/sound/pci/hda/hda_component.h ++++ b/sound/pci/hda/hda_component.h +@@ -16,4 +16,6 @@ struct hda_component { + char name[HDA_MAX_NAME_SIZE]; + struct hda_codec *codec; + void (*playback_hook)(struct device *dev, int action); ++ int (*suspend_hook)(struct device *dev); ++ int (*resume_hook)(struct device *dev); + }; +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 44744d568404..7c21bc439c46 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -4021,15 +4021,22 @@ static void alc5505_dsp_init(struct hda_codec *codec) + static int alc269_suspend(struct hda_codec *codec) + { + struct alc_spec *spec = codec->spec; ++ int i; + + if (spec->has_alc5505_dsp) + alc5505_dsp_suspend(codec); ++ ++ for (i = 0; i < HDA_MAX_COMPONENTS; i++) ++ if (spec->comps[i].suspend_hook) ++ spec->comps[i].suspend_hook(spec->comps[i].dev); ++ + return alc_suspend(codec); + } + + static int alc269_resume(struct hda_codec *codec) + { + struct alc_spec *spec = codec->spec; ++ int i; + + if (spec->codec_variant == ALC269_TYPE_ALC269VB) + alc269vb_toggle_power_output(codec, 0); +@@ -4060,6 +4067,10 @@ static int alc269_resume(struct hda_codec *codec) + if (spec->has_alc5505_dsp) + alc5505_dsp_resume(codec); + ++ for (i = 0; i < HDA_MAX_COMPONENTS; i++) ++ if (spec->comps[i].resume_hook) ++ spec->comps[i].resume_hook(spec->comps[i].dev); ++ + return 0; + } + #endif /* CONFIG_PM */ +@@ -6610,8 +6621,20 @@ static int comp_bind(struct device *dev) + { + struct hda_codec *cdc = dev_to_hda_codec(dev); + struct alc_spec *spec = cdc->spec; ++ int ret, i; ++ ++ ret = component_bind_all(dev, spec->comps); ++ if (ret) ++ return ret; + +- return component_bind_all(dev, spec->comps); ++ if (snd_hdac_is_power_on(&cdc->core)) { ++ codec_dbg(cdc, "Resuming after bind.\n"); ++ for (i = 0; i < HDA_MAX_COMPONENTS; i++) ++ if (spec->comps[i].resume_hook) ++ spec->comps[i].resume_hook(spec->comps[i].dev); ++ } ++ ++ return 0; + } + + static void comp_unbind(struct device *dev) +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Support-Speaker-ID-for-laptops.patch b/patches.suse/ALSA-hda-cs35l41-Support-Speaker-ID-for-laptops.patch new file mode 100644 index 0000000..eb350a6 --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Support-Speaker-ID-for-laptops.patch @@ -0,0 +1,292 @@ +From 63f4b99f0089a9719aa4441015fe30ff4b6f10e5 Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Thu, 30 Jun 2022 01:23:29 +0100 +Subject: [PATCH] ALSA: hda: cs35l41: Support Speaker ID for laptops +Git-commit: 63f4b99f0089a9719aa4441015fe30ff4b6f10e5 +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +Some Laptops use a number of gpios to define which vendor is +used for a particular laptop. +Different coefficient files are used for different vendors. + +Signed-off-by: Stefan Binding +Signed-off-by: Vitaly Rodionov +Link: https://lore.kernel.org/r/20220630002335.366545-9-vitalyr@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 174 ++++++++++++++++++++++++++++++++++-- + sound/pci/hda/cs35l41_hda.h | 1 + + 2 files changed, 166 insertions(+), 9 deletions(-) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index d356c1a55ad5..d5d2323cc8c7 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -86,13 +86,19 @@ static const struct cs_dsp_client_ops client_ops = { + static int cs35l41_request_firmware_file(struct cs35l41_hda *cs35l41, + const struct firmware **firmware, char **filename, + const char *dir, const char *ssid, const char *amp_name, +- const char *filetype) ++ int spkid, const char *filetype) + { + const char * const dsp_name = cs35l41->cs_dsp.name; + char *s, c; + int ret = 0; + +- if (ssid && amp_name) ++ if (spkid > -1 && ssid && amp_name) ++ *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s-spkid%d-%s.%s", dir, CS35L41_PART, ++ dsp_name, "spk-prot", ssid, spkid, amp_name, filetype); ++ else if (spkid > -1 && ssid) ++ *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s-spkid%d.%s", dir, CS35L41_PART, ++ dsp_name, "spk-prot", ssid, spkid, filetype); ++ else if (ssid && amp_name) + *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s-%s.%s", dir, CS35L41_PART, + dsp_name, "spk-prot", ssid, amp_name, + filetype); +@@ -130,6 +136,93 @@ static int cs35l41_request_firmware_file(struct cs35l41_hda *cs35l41, + return ret; + } + ++static int cs35l41_request_firmware_files_spkid(struct cs35l41_hda *cs35l41, ++ const struct firmware **wmfw_firmware, ++ char **wmfw_filename, ++ const struct firmware **coeff_firmware, ++ char **coeff_filename) ++{ ++ int ret; ++ ++ /* try cirrus/part-dspN-fwtype-sub<-spkidN><-ampname>.wmfw */ ++ ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, ++ CS35L41_FIRMWARE_ROOT, ++ cs35l41->acpi_subsystem_id, cs35l41->amp_name, ++ cs35l41->speaker_id, "wmfw"); ++ if (!ret) { ++ /* try cirrus/part-dspN-fwtype-sub<-spkidN><-ampname>.bin */ ++ cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, ++ CS35L41_FIRMWARE_ROOT, ++ cs35l41->acpi_subsystem_id, cs35l41->amp_name, ++ cs35l41->speaker_id, "bin"); ++ return 0; ++ } ++ ++ /* try cirrus/part-dspN-fwtype-sub<-ampname>.wmfw */ ++ ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, ++ CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, ++ cs35l41->amp_name, -1, "wmfw"); ++ if (!ret) { ++ /* try cirrus/part-dspN-fwtype-sub<-spkidN><-ampname>.bin */ ++ cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, ++ CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, ++ cs35l41->amp_name, cs35l41->speaker_id, "bin"); ++ return 0; ++ } ++ ++ /* try cirrus/part-dspN-fwtype-sub<-spkidN>.wmfw */ ++ ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, ++ CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, ++ NULL, cs35l41->speaker_id, "wmfw"); ++ if (!ret) { ++ /* try cirrus/part-dspN-fwtype-sub<-spkidN><-ampname>.bin */ ++ ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, ++ CS35L41_FIRMWARE_ROOT, ++ cs35l41->acpi_subsystem_id, ++ cs35l41->amp_name, cs35l41->speaker_id, "bin"); ++ if (ret) ++ /* try cirrus/part-dspN-fwtype-sub<-spkidN>.bin */ ++ cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, ++ CS35L41_FIRMWARE_ROOT, ++ cs35l41->acpi_subsystem_id, ++ NULL, cs35l41->speaker_id, "bin"); ++ return 0; ++ } ++ ++ /* try cirrus/part-dspN-fwtype-sub.wmfw */ ++ ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, ++ CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, ++ NULL, -1, "wmfw"); ++ if (!ret) { ++ /* try cirrus/part-dspN-fwtype-sub<-spkidN><-ampname>.bin */ ++ ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, ++ CS35L41_FIRMWARE_ROOT, ++ cs35l41->acpi_subsystem_id, ++ cs35l41->amp_name, cs35l41->speaker_id, "bin"); ++ if (ret) ++ /* try cirrus/part-dspN-fwtype-sub<-spkidN>.bin */ ++ cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, ++ CS35L41_FIRMWARE_ROOT, ++ cs35l41->acpi_subsystem_id, ++ NULL, cs35l41->speaker_id, "bin"); ++ return 0; ++ } ++ ++ /* fallback try cirrus/part-dspN-fwtype.wmfw */ ++ ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, ++ CS35L41_FIRMWARE_ROOT, NULL, NULL, -1, "wmfw"); ++ if (!ret) { ++ /* fallback try cirrus/part-dspN-fwtype.bin */ ++ cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, ++ CS35L41_FIRMWARE_ROOT, NULL, NULL, -1, "bin"); ++ return 0; ++ } ++ ++ dev_warn(cs35l41->dev, "Failed to request firmware\n"); ++ ++ return ret; ++} ++ + static int cs35l41_request_firmware_files(struct cs35l41_hda *cs35l41, + const struct firmware **wmfw_firmware, + char **wmfw_filename, +@@ -138,43 +231,48 @@ static int cs35l41_request_firmware_files(struct cs35l41_hda *cs35l41, + { + int ret; + ++ if (cs35l41->speaker_id > -1) ++ return cs35l41_request_firmware_files_spkid(cs35l41, wmfw_firmware, wmfw_filename, ++ coeff_firmware, coeff_filename); ++ + /* try cirrus/part-dspN-fwtype-sub<-ampname>.wmfw */ + ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, + CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, +- cs35l41->amp_name, "wmfw"); ++ cs35l41->amp_name, -1, "wmfw"); + if (!ret) { + /* try cirrus/part-dspN-fwtype-sub<-ampname>.bin */ + cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, + CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, +- cs35l41->amp_name, "bin"); ++ cs35l41->amp_name, -1, "bin"); + return 0; + } + + /* try cirrus/part-dspN-fwtype-sub.wmfw */ + ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, + CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, +- NULL, "wmfw"); ++ NULL, -1, "wmfw"); + if (!ret) { + /* try cirrus/part-dspN-fwtype-sub<-ampname>.bin */ + ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, + CS35L41_FIRMWARE_ROOT, + cs35l41->acpi_subsystem_id, +- cs35l41->amp_name, "bin"); ++ cs35l41->amp_name, -1, "bin"); + if (ret) + /* try cirrus/part-dspN-fwtype-sub.bin */ + cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, + CS35L41_FIRMWARE_ROOT, +- cs35l41->acpi_subsystem_id, NULL, "bin"); ++ cs35l41->acpi_subsystem_id, ++ NULL, -1, "bin"); + return 0; + } + + /* fallback try cirrus/part-dspN-fwtype.wmfw */ + ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, +- CS35L41_FIRMWARE_ROOT, NULL, NULL, "wmfw"); ++ CS35L41_FIRMWARE_ROOT, NULL, NULL, -1, "wmfw"); + if (!ret) { + /* fallback try cirrus/part-dspN-fwtype.bin */ + cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, +- CS35L41_FIRMWARE_ROOT, NULL, NULL, "bin"); ++ CS35L41_FIRMWARE_ROOT, NULL, NULL, -1, "bin"); + return 0; + } + +@@ -614,6 +712,61 @@ static int cs35l41_get_acpi_sub_string(struct device *dev, struct acpi_device *a + return ret; + } + ++static int cs35l41_get_speaker_id(struct device *dev, int amp_index, ++ int num_amps, int fixed_gpio_id) ++{ ++ struct gpio_desc *speaker_id_desc; ++ int speaker_id = -ENODEV; ++ ++ if (fixed_gpio_id >= 0) { ++ dev_dbg(dev, "Found Fixed Speaker ID GPIO (index = %d)\n", fixed_gpio_id); ++ speaker_id_desc = gpiod_get_index(dev, NULL, fixed_gpio_id, GPIOD_IN); ++ if (IS_ERR(speaker_id_desc)) { ++ speaker_id = PTR_ERR(speaker_id_desc); ++ return speaker_id; ++ } ++ speaker_id = gpiod_get_value_cansleep(speaker_id_desc); ++ gpiod_put(speaker_id_desc); ++ dev_dbg(dev, "Speaker ID = %d\n", speaker_id); ++ } else { ++ int base_index; ++ int gpios_per_amp; ++ int count; ++ int tmp; ++ int i; ++ ++ count = gpiod_count(dev, "spk-id"); ++ if (count > 0) { ++ speaker_id = 0; ++ gpios_per_amp = count / num_amps; ++ base_index = gpios_per_amp * amp_index; ++ ++ if (count % num_amps) ++ return -EINVAL; ++ ++ dev_dbg(dev, "Found %d Speaker ID GPIOs per Amp\n", gpios_per_amp); ++ ++ for (i = 0; i < gpios_per_amp; i++) { ++ speaker_id_desc = gpiod_get_index(dev, "spk-id", i + base_index, ++ GPIOD_IN); ++ if (IS_ERR(speaker_id_desc)) { ++ speaker_id = PTR_ERR(speaker_id_desc); ++ break; ++ } ++ tmp = gpiod_get_value_cansleep(speaker_id_desc); ++ gpiod_put(speaker_id_desc); ++ if (tmp < 0) { ++ speaker_id = tmp; ++ break; ++ } ++ speaker_id |= tmp << i; ++ } ++ dev_dbg(dev, "Speaker ID = %d\n", speaker_id); ++ } ++ } ++ return speaker_id; ++} ++ + static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, int id) + { + struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg; +@@ -719,6 +872,8 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i + else + hw_cfg->bst_cap = -1; + ++ cs35l41->speaker_id = cs35l41_get_speaker_id(physdev, cs35l41->index, nval, -1); ++ + if (hw_cfg->bst_ind > 0 || hw_cfg->bst_cap > 0 || hw_cfg->bst_ipk > 0) + hw_cfg->bst_type = CS35L41_INT_BOOST; + else +@@ -752,6 +907,7 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i + cs35l41->channel_index = 0; + cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 0, GPIOD_OUT_HIGH); + cs35l41->hw_cfg.bst_type = CS35L41_EXT_BOOST_NO_VSPK_SWITCH; ++ cs35l41->speaker_id = cs35l41_get_speaker_id(physdev, 0, 0, 2); + hw_cfg->gpio2.func = CS35L41_GPIO2_INT_OPEN_DRAIN; + hw_cfg->gpio2.valid = true; + cs35l41->hw_cfg.valid = true; +diff --git a/sound/pci/hda/cs35l41_hda.h b/sound/pci/hda/cs35l41_hda.h +index b57f59a1ba49..a9dbc1c19248 100644 +--- a/sound/pci/hda/cs35l41_hda.h ++++ b/sound/pci/hda/cs35l41_hda.h +@@ -43,6 +43,7 @@ struct cs35l41_hda { + unsigned volatile long irq_errors; + const char *amp_name; + const char *acpi_subsystem_id; ++ int speaker_id; + struct mutex fw_mutex; + struct regmap_irq_chip_data *irq_data; + bool firmware_running; +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Support-System-Suspend.patch b/patches.suse/ALSA-hda-cs35l41-Support-System-Suspend.patch new file mode 100644 index 0000000..230d0f4 --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Support-System-Suspend.patch @@ -0,0 +1,300 @@ +From 88672826e2a465d2f4c0a50fb5ced2956f4ffcbc Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Tue, 11 Oct 2022 15:35:52 +0100 +Subject: [PATCH] ALSA: hda: cs35l41: Support System Suspend +Git-commit: 88672826e2a465d2f4c0a50fb5ced2956f4ffcbc +Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git +Patch-mainline: Queued in subsystem maintainer repository +References: bsc#1203699 + +Add support for system suspend into the CS35L41 HDA Driver. +Since S4 suspend may power off the system, it is required +that the driver ensure the part is safe to be shutdown before +system suspend, as well as ensuring that the firmware is +unloaded before shutdown. The part must then be restored +on system resume, including re-downloading the firmware. + +Signed-off-by: Stefan Binding +Link: https://lore.kernel.org/r/20221011143552.621792-6-sbinding@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 160 +++++++++++++++++++++++++++++++++++++------- + 1 file changed, 136 insertions(+), 24 deletions(-) + +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -461,9 +461,12 @@ static void cs35l41_remove_dsp(struct cs + struct cs_dsp *dsp = &cs35l41->cs_dsp; + + cancel_work_sync(&cs35l41->fw_load_work); ++ ++ mutex_lock(&cs35l41->fw_mutex); + cs35l41_shutdown_dsp(cs35l41); + cs_dsp_remove(dsp); + cs35l41->halo_initialized = false; ++ mutex_unlock(&cs35l41->fw_mutex); + } + + /* Protection release cycle to get the speaker out of Safe-Mode */ +@@ -570,45 +573,148 @@ static int cs35l41_hda_channel_map(struc + rx_slot); + } + ++static void cs35l41_ready_for_reset(struct cs35l41_hda *cs35l41) ++{ ++ mutex_lock(&cs35l41->fw_mutex); ++ if (cs35l41->firmware_running) { ++ ++ regcache_cache_only(cs35l41->regmap, false); ++ ++ cs35l41_exit_hibernate(cs35l41->dev, cs35l41->regmap); ++ cs35l41_shutdown_dsp(cs35l41); ++ cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type); ++ ++ regcache_cache_only(cs35l41->regmap, true); ++ regcache_mark_dirty(cs35l41->regmap); ++ } ++ mutex_unlock(&cs35l41->fw_mutex); ++} ++ ++static int cs35l41_system_suspend(struct device *dev) ++{ ++ struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); ++ int ret; ++ ++ dev_dbg(cs35l41->dev, "System Suspend\n"); ++ ++ if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST_NO_VSPK_SWITCH) { ++ dev_err(cs35l41->dev, "System Suspend not supported\n"); ++ return -EINVAL; ++ } ++ ++ ret = pm_runtime_force_suspend(dev); ++ if (ret) ++ return ret; ++ ++ /* Shutdown DSP before system suspend */ ++ cs35l41_ready_for_reset(cs35l41); ++ ++ /* ++ * Reset GPIO may be shared, so cannot reset here. ++ * However beyond this point, amps may be powered down. ++ */ ++ return 0; ++} ++ ++static int cs35l41_system_resume(struct device *dev) ++{ ++ struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); ++ int ret; ++ ++ dev_dbg(cs35l41->dev, "System Resume\n"); ++ ++ if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST_NO_VSPK_SWITCH) { ++ dev_err(cs35l41->dev, "System Resume not supported\n"); ++ return -EINVAL; ++ } ++ ++ if (cs35l41->reset_gpio) { ++ usleep_range(2000, 2100); ++ gpiod_set_value_cansleep(cs35l41->reset_gpio, 1); ++ } ++ ++ usleep_range(2000, 2100); ++ ++ ret = pm_runtime_force_resume(dev); ++ ++ mutex_lock(&cs35l41->fw_mutex); ++ if (!ret && cs35l41->request_fw_load && !cs35l41->fw_request_ongoing) { ++ cs35l41->fw_request_ongoing = true; ++ schedule_work(&cs35l41->fw_load_work); ++ } ++ mutex_unlock(&cs35l41->fw_mutex); ++ ++ return ret; ++} ++ + static int cs35l41_runtime_suspend(struct device *dev) + { + struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); ++ int ret = 0; + +- dev_dbg(cs35l41->dev, "Suspend\n"); ++ dev_dbg(cs35l41->dev, "Runtime Suspend\n"); + +- if (!cs35l41->firmware_running) ++ if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST_NO_VSPK_SWITCH) { ++ dev_dbg(cs35l41->dev, "Runtime Suspend not supported\n"); + return 0; ++ } + +- if (cs35l41_enter_hibernate(cs35l41->dev, cs35l41->regmap, cs35l41->hw_cfg.bst_type) < 0) +- return 0; ++ mutex_lock(&cs35l41->fw_mutex); ++ ++ if (cs35l41->playback_started) { ++ regmap_multi_reg_write(cs35l41->regmap, cs35l41_hda_mute, ++ ARRAY_SIZE(cs35l41_hda_mute)); ++ cs35l41_global_enable(cs35l41->regmap, cs35l41->hw_cfg.bst_type, 0); ++ regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, ++ CS35L41_AMP_EN_MASK, 0 << CS35L41_AMP_EN_SHIFT); ++ if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST) ++ regmap_write(cs35l41->regmap, CS35L41_GPIO1_CTRL1, 0x00000001); ++ regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, ++ CS35L41_VMON_EN_MASK | CS35L41_IMON_EN_MASK, ++ 0 << CS35L41_VMON_EN_SHIFT | 0 << CS35L41_IMON_EN_SHIFT); ++ cs35l41->playback_started = false; ++ } ++ ++ if (cs35l41->firmware_running) { ++ ret = cs35l41_enter_hibernate(cs35l41->dev, cs35l41->regmap, ++ cs35l41->hw_cfg.bst_type); ++ if (ret) ++ goto err; ++ } else { ++ cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type); ++ } + + regcache_cache_only(cs35l41->regmap, true); + regcache_mark_dirty(cs35l41->regmap); + +- return 0; ++err: ++ mutex_unlock(&cs35l41->fw_mutex); ++ ++ return ret; + } + + static int cs35l41_runtime_resume(struct device *dev) + { + struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); +- int ret; ++ int ret = 0; + +- dev_dbg(cs35l41->dev, "Resume.\n"); ++ dev_dbg(cs35l41->dev, "Runtime Resume\n"); + + if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST_NO_VSPK_SWITCH) { +- dev_dbg(cs35l41->dev, "System does not support Resume\n"); ++ dev_dbg(cs35l41->dev, "Runtime Resume not supported\n"); + return 0; + } + +- if (!cs35l41->firmware_running) +- return 0; ++ mutex_lock(&cs35l41->fw_mutex); + + regcache_cache_only(cs35l41->regmap, false); + +- ret = cs35l41_exit_hibernate(cs35l41->dev, cs35l41->regmap); +- if (ret) { +- regcache_cache_only(cs35l41->regmap, true); +- return ret; ++ if (cs35l41->firmware_running) { ++ ret = cs35l41_exit_hibernate(cs35l41->dev, cs35l41->regmap); ++ if (ret) { ++ dev_warn(cs35l41->dev, "Unable to exit Hibernate."); ++ goto err; ++ } + } + + /* Test key needs to be unlocked to allow the OTP settings to re-apply */ +@@ -617,13 +723,16 @@ static int cs35l41_runtime_resume(struct + cs35l41_test_key_lock(cs35l41->dev, cs35l41->regmap); + if (ret) { + dev_err(cs35l41->dev, "Failed to restore register cache: %d\n", ret); +- return ret; ++ goto err; + } + + if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST) + cs35l41_init_boost(cs35l41->dev, cs35l41->regmap, &cs35l41->hw_cfg); + +- return 0; ++err: ++ mutex_unlock(&cs35l41->fw_mutex); ++ ++ return ret; + } + + static int cs35l41_smart_amp(struct cs35l41_hda *cs35l41) +@@ -673,8 +782,6 @@ clean_dsp: + + static void cs35l41_load_firmware(struct cs35l41_hda *cs35l41, bool load) + { +- pm_runtime_get_sync(cs35l41->dev); +- + if (cs35l41->firmware_running && !load) { + dev_dbg(cs35l41->dev, "Unloading Firmware\n"); + cs35l41_shutdown_dsp(cs35l41); +@@ -684,9 +791,6 @@ static void cs35l41_load_firmware(struct + } else { + dev_dbg(cs35l41->dev, "Unable to Load firmware.\n"); + } +- +- pm_runtime_mark_last_busy(cs35l41->dev); +- pm_runtime_put_autosuspend(cs35l41->dev); + } + + static int cs35l41_fw_load_ctl_get(struct snd_kcontrol *kcontrol, +@@ -702,16 +806,21 @@ static void cs35l41_fw_load_work(struct + { + struct cs35l41_hda *cs35l41 = container_of(work, struct cs35l41_hda, fw_load_work); + ++ pm_runtime_get_sync(cs35l41->dev); ++ + mutex_lock(&cs35l41->fw_mutex); + + /* Recheck if playback is ongoing, mutex will block playback during firmware loading */ + if (cs35l41->playback_started) +- dev_err(cs35l41->dev, "Cannot Load/Unload firmware during Playback\n"); ++ dev_err(cs35l41->dev, "Cannot Load/Unload firmware during Playback. Retrying...\n"); + else + cs35l41_load_firmware(cs35l41, cs35l41->request_fw_load); + + cs35l41->fw_request_ongoing = false; + mutex_unlock(&cs35l41->fw_mutex); ++ ++ pm_runtime_mark_last_busy(cs35l41->dev); ++ pm_runtime_put_autosuspend(cs35l41->dev); + } + + static int cs35l41_fw_load_ctl_put(struct snd_kcontrol *kcontrol, +@@ -835,6 +944,8 @@ static int cs35l41_hda_bind(struct devic + + pm_runtime_get_sync(dev); + ++ mutex_lock(&cs35l41->fw_mutex); ++ + comps->dev = dev; + if (!cs35l41->acpi_subsystem_id) + cs35l41->acpi_subsystem_id = devm_kasprintf(dev, GFP_KERNEL, "%.8x", +@@ -847,10 +958,8 @@ static int cs35l41_hda_bind(struct devic + if (firmware_autostart) { + dev_dbg(cs35l41->dev, "Firmware Autostart.\n"); + cs35l41->request_fw_load = true; +- mutex_lock(&cs35l41->fw_mutex); + if (cs35l41_smart_amp(cs35l41) < 0) + dev_warn(cs35l41->dev, "Cannot Run Firmware, reverting to dsp bypass...\n"); +- mutex_unlock(&cs35l41->fw_mutex); + } else { + dev_dbg(cs35l41->dev, "Firmware Autostart is disabled.\n"); + } +@@ -859,6 +968,8 @@ static int cs35l41_hda_bind(struct devic + + comps->playback_hook = cs35l41_hda_playback_hook; + ++ mutex_unlock(&cs35l41->fw_mutex); ++ + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + +@@ -1453,6 +1564,7 @@ EXPORT_SYMBOL_NS_GPL(cs35l41_hda_remove, + + const struct dev_pm_ops cs35l41_hda_pm_ops = { + SET_RUNTIME_PM_OPS(cs35l41_runtime_suspend, cs35l41_runtime_resume, NULL) ++ SET_SYSTEM_SLEEP_PM_OPS(cs35l41_system_suspend, cs35l41_system_resume) + }; + EXPORT_SYMBOL_NS_GPL(cs35l41_hda_pm_ops, SND_HDA_SCODEC_CS35L41); + diff --git a/patches.suse/ALSA-hda-cs35l41-Support-multiple-load-paths-for-fir.patch b/patches.suse/ALSA-hda-cs35l41-Support-multiple-load-paths-for-fir.patch new file mode 100644 index 0000000..49d4a58 --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Support-multiple-load-paths-for-fir.patch @@ -0,0 +1,110 @@ +From bb6eb621f522d1f76ee4593966d2863401892407 Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Thu, 30 Jun 2022 01:23:28 +0100 +Subject: [PATCH] ALSA: hda: cs35l41: Support multiple load paths for firmware +Git-commit: bb6eb621f522d1f76ee4593966d2863401892407 +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +To be able to support different firmwares and tuning +for different models, the driver needs to be able to +load a different firmware and coefficient file based +on its Subsystem ID. + +The driver attempts to load the firmware in the +following order: + +/lib/firmware/cirrus/cs35l41-dsp1---dev<#>.wmfw +/lib/firmware/cirrus/cs35l41-dsp1--.wmfw +/lib/firmware/cirrus/cs35l41-dsp1-.wmfw + +Signed-off-by: Stefan Binding +Signed-off-by: Vitaly Rodionov +Link: https://lore.kernel.org/r/20220630002335.366545-8-vitalyr@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 52 ++++++++++++++++++++++++++++++++----- + 1 file changed, 46 insertions(+), 6 deletions(-) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index effb3ce95c00..d356c1a55ad5 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -85,14 +85,23 @@ static const struct cs_dsp_client_ops client_ops = { + + static int cs35l41_request_firmware_file(struct cs35l41_hda *cs35l41, + const struct firmware **firmware, char **filename, +- const char *dir, const char *filetype) ++ const char *dir, const char *ssid, const char *amp_name, ++ const char *filetype) + { + const char * const dsp_name = cs35l41->cs_dsp.name; + char *s, c; + int ret = 0; + +- *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s.%s", dir, CS35L41_PART, dsp_name, "spk-prot", +- filetype); ++ if (ssid && amp_name) ++ *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s-%s.%s", dir, CS35L41_PART, ++ dsp_name, "spk-prot", ssid, amp_name, ++ filetype); ++ else if (ssid) ++ *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s.%s", dir, CS35L41_PART, ++ dsp_name, "spk-prot", ssid, filetype); ++ else ++ *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s.%s", dir, CS35L41_PART, ++ dsp_name, "spk-prot", filetype); + + if (*filename == NULL) + return -ENOMEM; +@@ -129,12 +138,43 @@ static int cs35l41_request_firmware_files(struct cs35l41_hda *cs35l41, + { + int ret; + +- /* cirrus/part-dspN-fwtype.wmfw */ ++ /* try cirrus/part-dspN-fwtype-sub<-ampname>.wmfw */ ++ ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, ++ CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, ++ cs35l41->amp_name, "wmfw"); ++ if (!ret) { ++ /* try cirrus/part-dspN-fwtype-sub<-ampname>.bin */ ++ cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, ++ CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, ++ cs35l41->amp_name, "bin"); ++ return 0; ++ } ++ ++ /* try cirrus/part-dspN-fwtype-sub.wmfw */ ++ ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, ++ CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, ++ NULL, "wmfw"); ++ if (!ret) { ++ /* try cirrus/part-dspN-fwtype-sub<-ampname>.bin */ ++ ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, ++ CS35L41_FIRMWARE_ROOT, ++ cs35l41->acpi_subsystem_id, ++ cs35l41->amp_name, "bin"); ++ if (ret) ++ /* try cirrus/part-dspN-fwtype-sub.bin */ ++ cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, ++ CS35L41_FIRMWARE_ROOT, ++ cs35l41->acpi_subsystem_id, NULL, "bin"); ++ return 0; ++ } ++ ++ /* fallback try cirrus/part-dspN-fwtype.wmfw */ + ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, +- CS35L41_FIRMWARE_ROOT, "wmfw"); ++ CS35L41_FIRMWARE_ROOT, NULL, NULL, "wmfw"); + if (!ret) { ++ /* fallback try cirrus/part-dspN-fwtype.bin */ + cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, +- CS35L41_FIRMWARE_ROOT, "bin"); ++ CS35L41_FIRMWARE_ROOT, NULL, NULL, "bin"); + return 0; + } + +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Support-reading-subsystem-id-from-A.patch b/patches.suse/ALSA-hda-cs35l41-Support-reading-subsystem-id-from-A.patch new file mode 100644 index 0000000..9ac6bc1 --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Support-reading-subsystem-id-from-A.patch @@ -0,0 +1,78 @@ +From eef375960210fdc1ec2786bddc91ff100444ffb8 Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Thu, 30 Jun 2022 01:23:27 +0100 +Subject: [PATCH] ALSA: hda: cs35l41: Support reading subsystem id from ACPI +Git-commit: eef375960210fdc1ec2786bddc91ff100444ffb8 +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +On some laptop models, the ACPI contains the unique +Subsystem ID, and this value should be preferred +over the value from the HDA driver. + +Signed-off-by: Stefan Binding +Signed-off-by: Vitaly Rodionov +Link: https://lore.kernel.org/r/20220630002335.366545-7-vitalyr@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 36 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 36 insertions(+) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index 25cb76437ba5..effb3ce95c00 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -544,6 +544,36 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41) + return cs35l41_hda_channel_map(cs35l41->dev, 0, NULL, 1, &hw_cfg->spk_pos); + } + ++static int cs35l41_get_acpi_sub_string(struct device *dev, struct acpi_device *adev, ++ const char **subsysid) ++{ ++ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; ++ union acpi_object *obj; ++ acpi_status status; ++ int ret = 0; ++ ++ status = acpi_evaluate_object(adev->handle, "_SUB", NULL, &buffer); ++ if (ACPI_SUCCESS(status)) { ++ obj = buffer.pointer; ++ if (obj->type == ACPI_TYPE_STRING) { ++ *subsysid = devm_kstrdup(dev, obj->string.pointer, GFP_KERNEL); ++ if (*subsysid == NULL) { ++ dev_err(dev, "Cannot allocate Subsystem ID"); ++ ret = -ENOMEM; ++ } ++ } else { ++ dev_warn(dev, "Warning ACPI _SUB did not return a string\n"); ++ ret = -ENODEV; ++ } ++ acpi_os_free(buffer.pointer); ++ } else { ++ dev_dbg(dev, "Warning ACPI _SUB failed: %#x\n", status); ++ ret = -ENODEV; ++ } ++ ++ return ret; ++} ++ + static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, int id) + { + struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg; +@@ -563,6 +593,12 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i + physdev = get_device(acpi_get_first_physical_node(adev)); + acpi_dev_put(adev); + ++ ret = cs35l41_get_acpi_sub_string(cs35l41->dev, adev, &cs35l41->acpi_subsystem_id); ++ if (ret) ++ dev_info(cs35l41->dev, "No Subsystem ID found in ACPI: %d", ret); ++ else ++ dev_dbg(cs35l41->dev, "Subsystem ID %s found", cs35l41->acpi_subsystem_id); ++ + property = "cirrus,dev-index"; + ret = device_property_count_u32(physdev, property); + if (ret <= 0) +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Tidyup-code.patch b/patches.suse/ALSA-hda-cs35l41-Tidyup-code.patch new file mode 100644 index 0000000..d52d7f2 --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Tidyup-code.patch @@ -0,0 +1,323 @@ +From 8c286a0f973a81201a0cef72a7ca55eda29fc35c Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Mon, 17 Jan 2022 16:08:30 +0000 +Subject: [PATCH] ALSA: hda: cs35l41: Tidyup code +Git-commit: 8c286a0f973a81201a0cef72a7ca55eda29fc35c +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +Clean up and simplify cs35l41_hda_bind function + +Signed-off-by: Lucas Tanure +Link: https://lore.kernel.org/r/20220117160830.709403-6-tanureal@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 99 ++++++++++++++++----------------- + sound/pci/hda/cs35l41_hda.h | 2 +- + sound/pci/hda/cs35l41_hda_i2c.c | 1 - + sound/pci/hda/cs35l41_hda_spi.c | 1 - + 4 files changed, 49 insertions(+), 54 deletions(-) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index c317b392c3e3..3f9ddfb4eaf3 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -1,6 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0 + // +-// cs35l41.c -- CS35l41 ALSA HDA audio driver ++// CS35l41 ALSA HDA audio driver + // + // Copyright 2021 Cirrus Logic, Inc. + // +@@ -17,19 +17,19 @@ + #include "cs35l41_hda.h" + + static const struct reg_sequence cs35l41_hda_config[] = { +- { CS35L41_PLL_CLK_CTRL, 0x00000430 }, //3200000Hz, BCLK Input, PLL_REFCLK_EN = 1 +- { CS35L41_GLOBAL_CLK_CTRL, 0x00000003 }, //GLOBAL_FS = 48 kHz +- { CS35L41_SP_ENABLES, 0x00010000 }, //ASP_RX1_EN = 1 +- { CS35L41_SP_RATE_CTRL, 0x00000021 }, //ASP_BCLK_FREQ = 3.072 MHz +- { CS35L41_SP_FORMAT, 0x20200200 }, //24 bits, I2S, BCLK Slave, FSYNC Slave +- { CS35L41_DAC_PCM1_SRC, 0x00000008 }, //DACPCM1_SRC = ASPRX1 +- { CS35L41_AMP_DIG_VOL_CTRL, 0x00000000 }, //AMP_VOL_PCM 0.0 dB +- { CS35L41_AMP_GAIN_CTRL, 0x00000084 }, //AMP_GAIN_PCM 4.5 dB +- { CS35L41_PWR_CTRL2, 0x00000001 }, //AMP_EN = 1 ++ { CS35L41_PLL_CLK_CTRL, 0x00000430 }, // 3200000Hz, BCLK Input, PLL_REFCLK_EN = 1 ++ { CS35L41_GLOBAL_CLK_CTRL, 0x00000003 }, // GLOBAL_FS = 48 kHz ++ { CS35L41_SP_ENABLES, 0x00010000 }, // ASP_RX1_EN = 1 ++ { CS35L41_SP_RATE_CTRL, 0x00000021 }, // ASP_BCLK_FREQ = 3.072 MHz ++ { CS35L41_SP_FORMAT, 0x20200200 }, // 24 bits, I2S, BCLK Slave, FSYNC Slave ++ { CS35L41_DAC_PCM1_SRC, 0x00000008 }, // DACPCM1_SRC = ASPRX1 ++ { CS35L41_AMP_DIG_VOL_CTRL, 0x00000000 }, // AMP_VOL_PCM 0.0 dB ++ { CS35L41_AMP_GAIN_CTRL, 0x00000084 }, // AMP_GAIN_PCM 4.5 dB ++ { CS35L41_PWR_CTRL2, 0x00000001 }, // AMP_EN = 1 + }; + + static const struct reg_sequence cs35l41_hda_start_bst[] = { +- { CS35L41_PWR_CTRL2, 0x00000021 }, //BST_EN = 10, AMP_EN = 1 ++ { CS35L41_PWR_CTRL2, 0x00000021 }, // BST_EN = 10, AMP_EN = 1 + { CS35L41_PWR_CTRL1, 0x00000001, 3000}, // set GLOBAL_EN = 1 + }; + +@@ -60,7 +60,7 @@ static const struct reg_sequence cs35l41_stop_ext_vspk[] = { + { 0x00000040, 0x00000055 }, + { 0x00000040, 0x000000AA }, + { 0x00007438, 0x00585941 }, +- { 0x00002014, 0x00000000, 3000}, //set GLOBAL_EN = 0 ++ { 0x00002014, 0x00000000, 3000}, // set GLOBAL_EN = 0 + { 0x0000742C, 0x00000009 }, + { 0x00007438, 0x00580941 }, + { 0x00011008, 0x00000001 }, +@@ -78,7 +78,7 @@ static const struct reg_sequence cs35l41_safe_to_active[] = { + { 0x0000742C, 0x0000000F }, + { 0x0000742C, 0x00000079 }, + { 0x00007438, 0x00585941 }, +- { CS35L41_PWR_CTRL1, 0x00000001, 2000 }, //GLOBAL_EN = 1 ++ { CS35L41_PWR_CTRL1, 0x00000001, 2000 }, // GLOBAL_EN = 1 + { 0x0000742C, 0x000000F9 }, + { 0x00007438, 0x00580941 }, + { 0x00000040, 0x000000CC }, +@@ -89,8 +89,8 @@ static const struct reg_sequence cs35l41_active_to_safe[] = { + { 0x00000040, 0x00000055 }, + { 0x00000040, 0x000000AA }, + { 0x00007438, 0x00585941 }, +- { CS35L41_AMP_DIG_VOL_CTRL, 0x0000A678 }, //AMP_VOL_PCM Mute +- { CS35L41_PWR_CTRL2, 0x00000000 }, //AMP_EN = 0 ++ { CS35L41_AMP_DIG_VOL_CTRL, 0x0000A678 }, // AMP_VOL_PCM Mute ++ { CS35L41_PWR_CTRL2, 0x00000000 }, // AMP_EN = 0 + { CS35L41_PWR_CTRL1, 0x00000000 }, + { 0x0000742C, 0x00000009, 2000 }, + { 0x00007438, 0x00580941 }, +@@ -168,7 +168,6 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action) + + if (ret) + dev_warn(cs35l41->dev, "Failed to apply multi reg write: %d\n", ret); +- + } + + static int cs35l41_hda_channel_map(struct device *dev, unsigned int tx_num, unsigned int *tx_slot, +@@ -185,20 +184,19 @@ static int cs35l41_hda_bind(struct device *dev, struct device *master, void *mas + struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); + struct hda_component *comps = master_data; + +- if (comps && cs35l41->index >= 0 && cs35l41->index < HDA_MAX_COMPONENTS) +- comps = &comps[cs35l41->index]; +- else ++ if (!comps || cs35l41->index < 0 || cs35l41->index >= HDA_MAX_COMPONENTS) + return -EINVAL; + +- if (!comps->dev) { +- comps->dev = dev; +- strscpy(comps->name, dev_name(dev), sizeof(comps->name)); +- comps->playback_hook = cs35l41_hda_playback_hook; +- comps->set_channel_map = cs35l41_hda_channel_map; +- return 0; +- } ++ comps = &comps[cs35l41->index]; ++ if (comps->dev) ++ return -EBUSY; + +- return -EBUSY; ++ comps->dev = dev; ++ strscpy(comps->name, dev_name(dev), sizeof(comps->name)); ++ comps->playback_hook = cs35l41_hda_playback_hook; ++ comps->set_channel_map = cs35l41_hda_channel_map; ++ ++ return 0; + } + + static void cs35l41_hda_unbind(struct device *dev, struct device *master, void *master_data) +@@ -269,11 +267,7 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41, + cs35l41->reg_seq = &cs35l41_hda_reg_seq_ext_bst; + } + +- ret = cs35l41_hda_channel_map(cs35l41->dev, 0, NULL, 1, (unsigned int *)&hw_cfg->spk_pos); +- if (ret) +- return ret; +- +- return 0; ++ return cs35l41_hda_channel_map(cs35l41->dev, 0, NULL, 1, (unsigned int *)&hw_cfg->spk_pos); + } + + static struct cs35l41_hda_hw_config *cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, +@@ -282,7 +276,7 @@ static struct cs35l41_hda_hw_config *cs35l41_hda_read_acpi(struct cs35l41_hda *c + struct cs35l41_hda_hw_config *hw_cfg; + u32 values[HDA_MAX_COMPONENTS]; + struct acpi_device *adev; +- struct device *acpi_dev; ++ struct device *physdev; + char *property; + size_t nval; + int i, ret; +@@ -293,11 +287,11 @@ static struct cs35l41_hda_hw_config *cs35l41_hda_read_acpi(struct cs35l41_hda *c + return ERR_PTR(-ENODEV); + } + +- acpi_dev = get_device(acpi_get_first_physical_node(adev)); ++ physdev = get_device(acpi_get_first_physical_node(adev)); + acpi_dev_put(adev); + + property = "cirrus,dev-index"; +- ret = device_property_count_u32(acpi_dev, property); ++ ret = device_property_count_u32(physdev, property); + if (ret <= 0) + goto no_acpi_dsd; + +@@ -307,7 +301,7 @@ static struct cs35l41_hda_hw_config *cs35l41_hda_read_acpi(struct cs35l41_hda *c + } + nval = ret; + +- ret = device_property_read_u32_array(acpi_dev, property, values, nval); ++ ret = device_property_read_u32_array(physdev, property, values, nval); + if (ret) + goto err; + +@@ -324,7 +318,9 @@ static struct cs35l41_hda_hw_config *cs35l41_hda_read_acpi(struct cs35l41_hda *c + goto err; + } + +- /* No devm_ version as CLSA0100, in no_acpi_dsd case, can't use devm version */ ++ /* To use the same release code for all laptop variants we can't use devm_ version of ++ * gpiod_get here, as CLSA010* don't have a fully functional bios with an _DSD node ++ */ + cs35l41->reset_gpio = fwnode_gpiod_get_index(&adev->fwnode, "reset", cs35l41->index, + GPIOD_OUT_LOW, "cs35l41-reset"); + +@@ -335,46 +331,46 @@ static struct cs35l41_hda_hw_config *cs35l41_hda_read_acpi(struct cs35l41_hda *c + } + + property = "cirrus,speaker-position"; +- ret = device_property_read_u32_array(acpi_dev, property, values, nval); ++ ret = device_property_read_u32_array(physdev, property, values, nval); + if (ret) + goto err_free; + hw_cfg->spk_pos = values[cs35l41->index]; + + property = "cirrus,gpio1-func"; +- ret = device_property_read_u32_array(acpi_dev, property, values, nval); ++ ret = device_property_read_u32_array(physdev, property, values, nval); + if (ret) + goto err_free; + hw_cfg->gpio1_func = values[cs35l41->index]; + + property = "cirrus,gpio2-func"; +- ret = device_property_read_u32_array(acpi_dev, property, values, nval); ++ ret = device_property_read_u32_array(physdev, property, values, nval); + if (ret) + goto err_free; + hw_cfg->gpio2_func = values[cs35l41->index]; + + property = "cirrus,boost-peak-milliamp"; +- ret = device_property_read_u32_array(acpi_dev, property, values, nval); ++ ret = device_property_read_u32_array(physdev, property, values, nval); + if (ret == 0) + hw_cfg->bst_ipk = values[cs35l41->index]; + + property = "cirrus,boost-ind-nanohenry"; +- ret = device_property_read_u32_array(acpi_dev, property, values, nval); ++ ret = device_property_read_u32_array(physdev, property, values, nval); + if (ret == 0) + hw_cfg->bst_ind = values[cs35l41->index]; + + property = "cirrus,boost-cap-microfarad"; +- ret = device_property_read_u32_array(acpi_dev, property, values, nval); ++ ret = device_property_read_u32_array(physdev, property, values, nval); + if (ret == 0) + hw_cfg->bst_cap = values[cs35l41->index]; + +- put_device(acpi_dev); ++ put_device(physdev); + + return hw_cfg; + + err_free: + kfree(hw_cfg); + err: +- put_device(acpi_dev); ++ put_device(physdev); + dev_err(cs35l41->dev, "Failed property %s: %d\n", property, ret); + + return ERR_PTR(ret); +@@ -383,18 +379,18 @@ static struct cs35l41_hda_hw_config *cs35l41_hda_read_acpi(struct cs35l41_hda *c + /* + * Device CLSA0100 doesn't have _DSD so a gpiod_get by the label reset won't work. + * And devices created by i2c-multi-instantiate don't have their device struct pointing to +- * the correct fwnode, so acpi_dev must be used here ++ * the correct fwnode, so acpi_dev must be used here. + * And devm functions expect that the device requesting the resource has the correct +- * fwnode ++ * fwnode. + */ + if (strncmp(hid, "CLSA0100", 8) != 0) + return ERR_PTR(-EINVAL); + + /* check I2C address to assign the index */ + cs35l41->index = id == 0x40 ? 0 : 1; +- cs35l41->reset_gpio = gpiod_get_index(acpi_dev, NULL, 0, GPIOD_OUT_HIGH); ++ cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 0, GPIOD_OUT_HIGH); + cs35l41->vspk_always_on = true; +- put_device(acpi_dev); ++ put_device(physdev); + + return NULL; + } +@@ -449,7 +445,8 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i + + ret = regmap_read(cs35l41->regmap, CS35L41_IRQ1_STATUS3, &int_sts); + if (ret || (int_sts & CS35L41_OTP_BOOT_ERR)) { +- dev_err(cs35l41->dev, "OTP Boot error\n"); ++ dev_err(cs35l41->dev, "OTP Boot status %x error: %d\n", ++ int_sts & CS35L41_OTP_BOOT_ERR, ret); + ret = -EIO; + goto err; + } +@@ -501,7 +498,7 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i + + if (cs35l41->reg_seq->probe) { + ret = regmap_multi_reg_write(cs35l41->regmap, cs35l41->reg_seq->probe, +- cs35l41->reg_seq->num_probe); ++ cs35l41->reg_seq->num_probe); + if (ret) { + dev_err(cs35l41->dev, "Fail to apply probe reg patch: %d\n", ret); + goto err; +diff --git a/sound/pci/hda/cs35l41_hda.h b/sound/pci/hda/cs35l41_hda.h +index 76c69a8a22f6..640afc98b686 100644 +--- a/sound/pci/hda/cs35l41_hda.h ++++ b/sound/pci/hda/cs35l41_hda.h +@@ -1,6 +1,6 @@ + /* SPDX-License-Identifier: GPL-2.0 + * +- * cs35l41_hda.h -- CS35L41 ALSA HDA audio driver ++ * CS35L41 ALSA HDA audio driver + * + * Copyright 2021 Cirrus Logic, Inc. + * +diff --git a/sound/pci/hda/cs35l41_hda_i2c.c b/sound/pci/hda/cs35l41_hda_i2c.c +index eeb387853ee3..c2397dc53e78 100644 +--- a/sound/pci/hda/cs35l41_hda_i2c.c ++++ b/sound/pci/hda/cs35l41_hda_i2c.c +@@ -58,7 +58,6 @@ static struct i2c_driver cs35l41_i2c_driver = { + .probe = cs35l41_hda_i2c_probe, + .remove = cs35l41_hda_i2c_remove, + }; +- + module_i2c_driver(cs35l41_i2c_driver); + + MODULE_DESCRIPTION("HDA CS35L41 driver"); +diff --git a/sound/pci/hda/cs35l41_hda_spi.c b/sound/pci/hda/cs35l41_hda_spi.c +index 15345a72b9d1..36815ab4e461 100644 +--- a/sound/pci/hda/cs35l41_hda_spi.c ++++ b/sound/pci/hda/cs35l41_hda_spi.c +@@ -55,7 +55,6 @@ static struct spi_driver cs35l41_spi_driver = { + .probe = cs35l41_hda_spi_probe, + .remove = cs35l41_hda_spi_remove, + }; +- + module_spi_driver(cs35l41_spi_driver); + + MODULE_DESCRIPTION("HDA CS35L41 driver"); +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-Use-the-CS35L41-HDA-internal-define.patch b/patches.suse/ALSA-hda-cs35l41-Use-the-CS35L41-HDA-internal-define.patch new file mode 100644 index 0000000..483563d --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-Use-the-CS35L41-HDA-internal-define.patch @@ -0,0 +1,43 @@ +From f81ee579c0898201eb2b5105718bedf34c0401f9 Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Wed, 27 Jul 2022 10:59:21 +0100 +Subject: [PATCH] ALSA: hda: cs35l41: Use the CS35L41 HDA internal define +Git-commit: f81ee579c0898201eb2b5105718bedf34c0401f9 +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +Follow GPIO1 pattern, use cs35l41 HDA internal define for +IRQ and then translate to ASoC cs35l41 define. + +Signed-off-by: Lucas Tanure +Link: https://lore.kernel.org/r/20220727095924.80884-2-tanureal@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index 93cf039abb02..9af5e2e9be55 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -1014,6 +1014,7 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41) + break; + case CS35L41_INTERRUPT: + using_irq = true; ++ hw_cfg->gpio2.func = CS35L41_GPIO2_INT_OPEN_DRAIN; + break; + default: + dev_err(cs35l41->dev, "Invalid GPIO2 function %d\n", hw_cfg->gpio2.func); +@@ -1273,7 +1274,7 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i + cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 0, GPIOD_OUT_HIGH); + cs35l41->hw_cfg.bst_type = CS35L41_EXT_BOOST_NO_VSPK_SWITCH; + cs35l41->speaker_id = cs35l41_get_speaker_id(physdev, 0, 0, 2); +- hw_cfg->gpio2.func = CS35L41_GPIO2_INT_OPEN_DRAIN; ++ hw_cfg->gpio2.func = CS35L41_INTERRUPT; + hw_cfg->gpio2.valid = true; + cs35l41->hw_cfg.valid = true; + put_device(physdev); +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs35l41-fix-double-free-on-error-in-probe.patch b/patches.suse/ALSA-hda-cs35l41-fix-double-free-on-error-in-probe.patch new file mode 100644 index 0000000..460af06 --- /dev/null +++ b/patches.suse/ALSA-hda-cs35l41-fix-double-free-on-error-in-probe.patch @@ -0,0 +1,35 @@ +From 10b1a5a99c6ac42be7a490676aec626fba28b048 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Tue, 11 Jan 2022 10:22:32 +0300 +Subject: [PATCH] ALSA: hda: cs35l41: fix double free on error in probe() +Git-commit: 10b1a5a99c6ac42be7a490676aec626fba28b048 +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +If we encounter an error after the kfree(acpi_hw_cfg); then the goto +err; will result in a double free. + +Fixes: 7b2f3eb492da ("ALSA: hda: cs35l41: Add support for CS35L41 in HDA systems") +Signed-off-by: Dan Carpenter +Link: https://lore.kernel.org/r/20220111072232.GG11243@kili +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index aa5bb6977792..30b40d865863 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -477,6 +477,7 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i + if (ret) + goto err; + kfree(acpi_hw_cfg); ++ acpi_hw_cfg = NULL; + + if (cs35l41->reg_seq->probe) { + ret = regmap_register_patch(cs35l41->regmap, cs35l41->reg_seq->probe, +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs8409-Add-Speaker-Playback-Switch-for-Cybo.patch b/patches.suse/ALSA-hda-cs8409-Add-Speaker-Playback-Switch-for-Cybo.patch new file mode 100644 index 0000000..faf3c2d --- /dev/null +++ b/patches.suse/ALSA-hda-cs8409-Add-Speaker-Playback-Switch-for-Cybo.patch @@ -0,0 +1,190 @@ +From f129f26f76959fb09784c1d2d959a7c1d05201a3 Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Wed, 11 May 2022 11:02:06 +0100 +Subject: [PATCH] ALSA: hda/cs8409: Add Speaker Playback Switch for Cyborg +Git-commit: f129f26f76959fb09784c1d2d959a7c1d05201a3 +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +Add support for a Speaker Playback Switch, which disables +the Amp connected to cs8409. The Switch is not added +automatically because cs8409 does not have an output amp +for the speaker NID. + +Signed-off-by: Stefan Binding +Link: https://lore.kernel.org/r/20220511100207.1268321-3-sbinding@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_cs8409.c | 72 ++++++++++++++++++++++++++++++------ + sound/pci/hda/patch_cs8409.h | 3 ++ + 2 files changed, 64 insertions(+), 11 deletions(-) + +diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c +index 91571e82d148..e9b9273dbfd9 100644 +--- a/sound/pci/hda/patch_cs8409.c ++++ b/sound/pci/hda/patch_cs8409.c +@@ -419,6 +419,39 @@ static void cs8409_fix_caps(struct hda_codec *codec, unsigned int nid) + snd_hda_override_wcaps(codec, nid, (get_wcaps(codec, nid) | AC_WCAP_UNSOL_CAP)); + } + ++static int cs8409_spk_sw_gpio_get(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct hda_codec *codec = snd_kcontrol_chip(kcontrol); ++ struct cs8409_spec *spec = codec->spec; ++ ++ ucontrol->value.integer.value[0] = !!(spec->gpio_data & spec->speaker_pdn_gpio); ++ return 0; ++} ++ ++static int cs8409_spk_sw_gpio_put(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct hda_codec *codec = snd_kcontrol_chip(kcontrol); ++ struct cs8409_spec *spec = codec->spec; ++ unsigned int gpio_data; ++ ++ gpio_data = (spec->gpio_data & ~spec->speaker_pdn_gpio) | ++ (ucontrol->value.integer.value[0] ? spec->speaker_pdn_gpio : 0); ++ if (gpio_data == spec->gpio_data) ++ return 0; ++ spec->gpio_data = gpio_data; ++ snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, spec->gpio_data); ++ return 1; ++} ++ ++static const struct snd_kcontrol_new cs8409_spk_sw_ctrl = { ++ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, ++ .info = snd_ctl_boolean_mono_info, ++ .get = cs8409_spk_sw_gpio_get, ++ .put = cs8409_spk_sw_gpio_put, ++}; ++ + /****************************************************************************** + * CS42L42 Specific Functions + ******************************************************************************/ +@@ -836,7 +869,7 @@ static int cs42l42_jack_unsol_event(struct sub_codec *cs42l42) + static void cs42l42_resume(struct sub_codec *cs42l42) + { + struct hda_codec *codec = cs42l42->codec; +- unsigned int gpio_data; ++ struct cs8409_spec *spec = codec->spec; + struct cs8409_i2c_param irq_regs[] = { + { CS42L42_CODEC_STATUS, 0x00 }, + { CS42L42_DET_INT_STATUS1, 0x00 }, +@@ -846,9 +879,9 @@ static void cs42l42_resume(struct sub_codec *cs42l42) + int fsv_old, fsv_new; + + /* Bring CS42L42 out of Reset */ +- gpio_data = snd_hda_codec_read(codec, CS8409_PIN_AFG, 0, AC_VERB_GET_GPIO_DATA, 0); +- gpio_data |= cs42l42->reset_gpio; +- snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, gpio_data); ++ spec->gpio_data = snd_hda_codec_read(codec, CS8409_PIN_AFG, 0, AC_VERB_GET_GPIO_DATA, 0); ++ spec->gpio_data |= cs42l42->reset_gpio; ++ snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, spec->gpio_data); + usleep_range(10000, 15000); + + cs42l42->suspended = 0; +@@ -880,7 +913,7 @@ static void cs42l42_resume(struct sub_codec *cs42l42) + static void cs42l42_suspend(struct sub_codec *cs42l42) + { + struct hda_codec *codec = cs42l42->codec; +- unsigned int gpio_data; ++ struct cs8409_spec *spec = codec->spec; + int reg_cdc_status = 0; + const struct cs8409_i2c_param cs42l42_pwr_down_seq[] = { + { CS42L42_DAC_CTL2, 0x02 }, +@@ -911,9 +944,9 @@ static void cs42l42_suspend(struct sub_codec *cs42l42) + cs42l42->mic_jack_in = 0; + + /* Put CS42L42 into Reset */ +- gpio_data = snd_hda_codec_read(codec, CS8409_PIN_AFG, 0, AC_VERB_GET_GPIO_DATA, 0); +- gpio_data &= ~cs42l42->reset_gpio; +- snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, gpio_data); ++ spec->gpio_data = snd_hda_codec_read(codec, CS8409_PIN_AFG, 0, AC_VERB_GET_GPIO_DATA, 0); ++ spec->gpio_data &= ~cs42l42->reset_gpio; ++ snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, spec->gpio_data); + } + #endif + +@@ -1107,6 +1140,8 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, + spec->gen.no_primary_hp = 1; + spec->gen.suppress_vmaster = 1; + ++ spec->speaker_pdn_gpio = 0; ++ + /* GPIO 5 out, 3,4 in */ + spec->gpio_dir = spec->scodecs[CS8409_CODEC0]->reset_gpio; + spec->gpio_data = 0; +@@ -1118,21 +1153,33 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, + cs8409_fix_caps(codec, CS8409_CS42L42_HP_PIN_NID); + cs8409_fix_caps(codec, CS8409_CS42L42_AMIC_PIN_NID); + +- /* Set HSBIAS_SENSE_EN and Full Scale volume for some variants. */ ++ spec->scodecs[CS8409_CODEC0]->hsbias_hiz = 0x0020; ++ + switch (codec->fixup_id) { ++ case CS8409_CYBORG: ++ spec->scodecs[CS8409_CODEC0]->full_scale_vol = ++ CS42L42_FULL_SCALE_VOL_MINUS6DB; ++ spec->speaker_pdn_gpio = CS8409_CYBORG_SPEAKER_PDN; ++ break; + case CS8409_ODIN: ++ spec->scodecs[CS8409_CODEC0]->full_scale_vol = CS42L42_FULL_SCALE_VOL_0DB; ++ spec->speaker_pdn_gpio = CS8409_CYBORG_SPEAKER_PDN; ++ break; + case CS8409_WARLOCK_MLK: + case CS8409_WARLOCK_MLK_DUAL_MIC: +- spec->scodecs[CS8409_CODEC0]->hsbias_hiz = 0x0020; + spec->scodecs[CS8409_CODEC0]->full_scale_vol = CS42L42_FULL_SCALE_VOL_0DB; + break; + default: +- spec->scodecs[CS8409_CODEC0]->hsbias_hiz = 0x0020; + spec->scodecs[CS8409_CODEC0]->full_scale_vol = + CS42L42_FULL_SCALE_VOL_MINUS6DB; + break; + } + ++ if (spec->speaker_pdn_gpio > 0) { ++ spec->gpio_dir |= spec->speaker_pdn_gpio; ++ spec->gpio_data |= spec->speaker_pdn_gpio; ++ } ++ + break; + case HDA_FIXUP_ACT_PROBE: + /* Fix Sample Rate to 48kHz */ +@@ -1149,6 +1196,9 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, + &cs42l42_dac_volume_mixer); + snd_hda_gen_add_kctl(&spec->gen, "Mic Capture Volume", + &cs42l42_adc_volume_mixer); ++ if (spec->speaker_pdn_gpio > 0) ++ snd_hda_gen_add_kctl(&spec->gen, "Speaker Playback Switch", ++ &cs8409_spk_sw_ctrl); + /* Disable Unsolicited Response during boot */ + cs8409_enable_ur(codec, 0); + snd_hda_codec_set_name(codec, "CS8409/CS42L42"); +diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h +index 9852dc4234b4..630a7a2de51f 100644 +--- a/sound/pci/hda/patch_cs8409.h ++++ b/sound/pci/hda/patch_cs8409.h +@@ -238,6 +238,7 @@ enum cs8409_coefficient_index_registers { + #define CS42L42_I2C_ADDR (0x48 << 1) + #define CS8409_CS42L42_RESET GENMASK(5, 5) /* CS8409_GPIO5 */ + #define CS8409_CS42L42_INT GENMASK(4, 4) /* CS8409_GPIO4 */ ++#define CS8409_CYBORG_SPEAKER_PDN GENMASK(2, 2) /* CS8409_GPIO2 */ + #define CS8409_CS42L42_HP_PIN_NID CS8409_PIN_ASP1_TRANSMITTER_A + #define CS8409_CS42L42_SPK_PIN_NID CS8409_PIN_ASP2_TRANSMITTER_A + #define CS8409_CS42L42_AMIC_PIN_NID CS8409_PIN_ASP1_RECEIVER_A +@@ -326,6 +327,8 @@ struct cs8409_spec { + unsigned int gpio_dir; + unsigned int gpio_data; + ++ int speaker_pdn_gpio; ++ + struct mutex i2c_mux; + unsigned int i2c_clck_enabled; + unsigned int dev_addr; +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs8409-Add-Speaker-Playback-Switch-for-Warl.patch b/patches.suse/ALSA-hda-cs8409-Add-Speaker-Playback-Switch-for-Warl.patch new file mode 100644 index 0000000..5fad29a --- /dev/null +++ b/patches.suse/ALSA-hda-cs8409-Add-Speaker-Playback-Switch-for-Warl.patch @@ -0,0 +1,56 @@ +From 6e7cf6702c6a6338b2116aae236cf3c9e1c07855 Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Wed, 11 May 2022 11:02:07 +0100 +Subject: [PATCH] ALSA: hda/cs8409: Add Speaker Playback Switch for Warlock +Git-commit: 6e7cf6702c6a6338b2116aae236cf3c9e1c07855 +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +Add support for a Speaker Playback Switch, which disables +the Amp connected to cs8409. The Switch is not added +automatically because cs8409 does not have an output amp +for the speaker NID. + +Note: This switch uses a different GPIO to Cyborg/Odin variants + +Signed-off-by: Stefan Binding +Link: https://lore.kernel.org/r/20220511100207.1268321-4-sbinding@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_cs8409.c | 2 ++ + sound/pci/hda/patch_cs8409.h | 1 + + 2 files changed, 3 insertions(+) + +diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c +index e9b9273dbfd9..754aa8ddd2e4 100644 +--- a/sound/pci/hda/patch_cs8409.c ++++ b/sound/pci/hda/patch_cs8409.c +@@ -1168,10 +1168,12 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, + case CS8409_WARLOCK_MLK: + case CS8409_WARLOCK_MLK_DUAL_MIC: + spec->scodecs[CS8409_CODEC0]->full_scale_vol = CS42L42_FULL_SCALE_VOL_0DB; ++ spec->speaker_pdn_gpio = CS8409_WARLOCK_SPEAKER_PDN; + break; + default: + spec->scodecs[CS8409_CODEC0]->full_scale_vol = + CS42L42_FULL_SCALE_VOL_MINUS6DB; ++ spec->speaker_pdn_gpio = CS8409_WARLOCK_SPEAKER_PDN; + break; + } + +diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h +index 630a7a2de51f..260388a6256c 100644 +--- a/sound/pci/hda/patch_cs8409.h ++++ b/sound/pci/hda/patch_cs8409.h +@@ -239,6 +239,7 @@ enum cs8409_coefficient_index_registers { + #define CS8409_CS42L42_RESET GENMASK(5, 5) /* CS8409_GPIO5 */ + #define CS8409_CS42L42_INT GENMASK(4, 4) /* CS8409_GPIO4 */ + #define CS8409_CYBORG_SPEAKER_PDN GENMASK(2, 2) /* CS8409_GPIO2 */ ++#define CS8409_WARLOCK_SPEAKER_PDN GENMASK(1, 1) /* CS8409_GPIO1 */ + #define CS8409_CS42L42_HP_PIN_NID CS8409_PIN_ASP1_TRANSMITTER_A + #define CS8409_CS42L42_SPK_PIN_NID CS8409_PIN_ASP2_TRANSMITTER_A + #define CS8409_CS42L42_AMIC_PIN_NID CS8409_PIN_ASP1_RECEIVER_A +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs8409-Add-new-Dolphin-HW-variants.patch b/patches.suse/ALSA-hda-cs8409-Add-new-Dolphin-HW-variants.patch new file mode 100644 index 0000000..0af49d2 --- /dev/null +++ b/patches.suse/ALSA-hda-cs8409-Add-new-Dolphin-HW-variants.patch @@ -0,0 +1,37 @@ +From 5e2baa04e4cd94c2465b248b7d861fcff8c22fae Mon Sep 17 00:00:00 2001 +From: Vitaly Rodionov +Date: Mon, 28 Mar 2022 12:56:14 +0100 +Subject: [PATCH] ALSA: hda/cs8409: Add new Dolphin HW variants +Git-commit: 5e2baa04e4cd94c2465b248b7d861fcff8c22fae +Patch-mainline: v5.18-rc1 +References: bsc#1203699 + +Add 5 new Dolphin Systems, same configuration as older systems. + +Signed-off-by: Vitaly Rodionov +Link: https://lore.kernel.org/r/20220328115614.15761-7-vitalyr@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_cs8409-tables.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/sound/pci/hda/patch_cs8409-tables.c b/sound/pci/hda/patch_cs8409-tables.c +index 8d20d7fb3d68..74c50ec040d9 100644 +--- a/sound/pci/hda/patch_cs8409-tables.c ++++ b/sound/pci/hda/patch_cs8409-tables.c +@@ -532,6 +532,11 @@ const struct snd_pci_quirk cs8409_fixup_tbl[] = { + SND_PCI_QUIRK(0x1028, 0x0BBB, "Warlock MLK Dual Mic", CS8409_WARLOCK_MLK_DUAL_MIC), + SND_PCI_QUIRK(0x1028, 0x0BBC, "Warlock MLK", CS8409_WARLOCK_MLK), + SND_PCI_QUIRK(0x1028, 0x0BBD, "Warlock MLK Dual Mic", CS8409_WARLOCK_MLK_DUAL_MIC), ++ SND_PCI_QUIRK(0x1028, 0x0BD4, "Dolphin", CS8409_DOLPHIN), ++ SND_PCI_QUIRK(0x1028, 0x0BD5, "Dolphin", CS8409_DOLPHIN), ++ SND_PCI_QUIRK(0x1028, 0x0BD6, "Dolphin", CS8409_DOLPHIN), ++ SND_PCI_QUIRK(0x1028, 0x0BD7, "Dolphin", CS8409_DOLPHIN), ++ SND_PCI_QUIRK(0x1028, 0x0BD8, "Dolphin", CS8409_DOLPHIN), + {} /* terminator */ + }; + +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs8409-Disable-HSBIAS_SENSE_EN-for-Cyborg.patch b/patches.suse/ALSA-hda-cs8409-Disable-HSBIAS_SENSE_EN-for-Cyborg.patch new file mode 100644 index 0000000..5846c74 --- /dev/null +++ b/patches.suse/ALSA-hda-cs8409-Disable-HSBIAS_SENSE_EN-for-Cyborg.patch @@ -0,0 +1,43 @@ +From 5e74a144837997e6efc52c56d6686fb6c11c627e Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Mon, 28 Mar 2022 12:56:13 +0100 +Subject: [PATCH] ALSA: hda/cs8409: Disable HSBIAS_SENSE_EN for Cyborg +Git-commit: 5e74a144837997e6efc52c56d6686fb6c11c627e +Patch-mainline: v5.18-rc1 +References: bsc#1203699 + +For ESD reasons, all variants should now set HSBIAS_SENSE_EN. + +Signed-off-by: Stefan Binding +Signed-off-by: Vitaly Rodionov +Link: https://lore.kernel.org/r/20220328115614.15761-6-vitalyr@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_cs8409.c | 9 +-------- + 1 file changed, 1 insertion(+), 8 deletions(-) + +diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c +index ce5fc03a8065..343fabc4387d 100644 +--- a/sound/pci/hda/patch_cs8409.c ++++ b/sound/pci/hda/patch_cs8409.c +@@ -1005,15 +1005,8 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, + cs8409_fix_caps(codec, CS8409_CS42L42_HP_PIN_NID); + cs8409_fix_caps(codec, CS8409_CS42L42_AMIC_PIN_NID); + +- /* Set TIP_SENSE_EN for analog front-end of tip sense. +- * Additionally set HSBIAS_SENSE_EN and Full Scale volume for some variants. +- */ ++ /* Set HSBIAS_SENSE_EN and Full Scale volume for some variants. */ + switch (codec->fixup_id) { +- case CS8409_CYBORG: +- spec->scodecs[CS8409_CODEC0]->hsbias_hiz = 0x00a0; +- spec->scodecs[CS8409_CODEC0]->full_scale_vol = +- CS42L42_FULL_SCALE_VOL_MINUS6DB; +- break; + case CS8409_WARLOCK_MLK: + case CS8409_WARLOCK_MLK_DUAL_MIC: + spec->scodecs[CS8409_CODEC0]->hsbias_hiz = 0x0020; +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs8409-Fix-Full-Scale-Volume-setting-for-al.patch b/patches.suse/ALSA-hda-cs8409-Fix-Full-Scale-Volume-setting-for-al.patch new file mode 100644 index 0000000..051fb3b --- /dev/null +++ b/patches.suse/ALSA-hda-cs8409-Fix-Full-Scale-Volume-setting-for-al.patch @@ -0,0 +1,106 @@ +From 342b6b610ae2a351de904022271e740c4c2b452b Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Mon, 28 Mar 2022 12:56:11 +0100 +Subject: [PATCH] ALSA: hda/cs8409: Fix Full Scale Volume setting for all variants +Git-commit: 342b6b610ae2a351de904022271e740c4c2b452b +Patch-mainline: v5.18-rc1 +References: bsc#1203699 + +All current variants (Bullseye/Warlock/Cyborg) should be using +reduced volume (-6dB) for better speaker protection. + +Refactor to make more explicit the meaning and setting of +Full Scale Volume setting to avoid future confusion. + +Signed-off-by: Stefan Binding +Signed-off-by: Vitaly Rodionov +Link: https://lore.kernel.org/r/20220328115614.15761-4-vitalyr@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_cs8409.c | 29 ++++++++++++++++------------- + sound/pci/hda/patch_cs8409.h | 3 +++ + 2 files changed, 19 insertions(+), 13 deletions(-) + +diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c +index 1411e3845f16..163ff3b3092a 100644 +--- a/sound/pci/hda/patch_cs8409.c ++++ b/sound/pci/hda/patch_cs8409.c +@@ -733,6 +733,7 @@ static void cs42l42_resume(struct sub_codec *cs42l42) + { 0x130A, 0x00 }, + { 0x130F, 0x00 }, + }; ++ int fsv_old, fsv_new; + + /* Bring CS42L42 out of Reset */ + gpio_data = snd_hda_codec_read(codec, CS8409_PIN_AFG, 0, AC_VERB_GET_GPIO_DATA, 0); +@@ -749,8 +750,13 @@ static void cs42l42_resume(struct sub_codec *cs42l42) + /* Clear interrupts, by reading interrupt status registers */ + cs8409_i2c_bulk_read(cs42l42, irq_regs, ARRAY_SIZE(irq_regs)); + +- if (cs42l42->full_scale_vol) +- cs8409_i2c_write(cs42l42, 0x2001, 0x01); ++ fsv_old = cs8409_i2c_read(cs42l42, 0x2001); ++ if (cs42l42->full_scale_vol == CS42L42_FULL_SCALE_VOL_0DB) ++ fsv_new = fsv_old & ~CS42L42_FULL_SCALE_VOL_MASK; ++ else ++ fsv_new = fsv_old & CS42L42_FULL_SCALE_VOL_MASK; ++ if (fsv_new != fsv_old) ++ cs8409_i2c_write(cs42l42, 0x2001, fsv_new); + + /* we have to explicitly allow unsol event handling even during the + * resume phase so that the jack event is processed properly +@@ -997,21 +1003,15 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, + * Additionally set HSBIAS_SENSE_EN and Full Scale volume for some variants. + */ + switch (codec->fixup_id) { +- case CS8409_WARLOCK: +- spec->scodecs[CS8409_CODEC0]->hsbias_hiz = 0x0020; +- spec->scodecs[CS8409_CODEC0]->full_scale_vol = 1; +- break; +- case CS8409_BULLSEYE: +- spec->scodecs[CS8409_CODEC0]->hsbias_hiz = 0x0020; +- spec->scodecs[CS8409_CODEC0]->full_scale_vol = 0; +- break; + case CS8409_CYBORG: + spec->scodecs[CS8409_CODEC0]->hsbias_hiz = 0x00a0; +- spec->scodecs[CS8409_CODEC0]->full_scale_vol = 1; ++ spec->scodecs[CS8409_CODEC0]->full_scale_vol = ++ CS42L42_FULL_SCALE_VOL_MINUS6DB; + break; + default: +- spec->scodecs[CS8409_CODEC0]->hsbias_hiz = 0x0003; +- spec->scodecs[CS8409_CODEC0]->full_scale_vol = 1; ++ spec->scodecs[CS8409_CODEC0]->hsbias_hiz = 0x0020; ++ spec->scodecs[CS8409_CODEC0]->full_scale_vol = ++ CS42L42_FULL_SCALE_VOL_MINUS6DB; + break; + } + +@@ -1222,6 +1222,9 @@ void dolphin_fixups(struct hda_codec *codec, const struct hda_fixup *fix, int ac + cs8409_fix_caps(codec, DOLPHIN_LO_PIN_NID); + cs8409_fix_caps(codec, DOLPHIN_AMIC_PIN_NID); + ++ spec->scodecs[CS8409_CODEC0]->full_scale_vol = CS42L42_FULL_SCALE_VOL_MINUS6DB; ++ spec->scodecs[CS8409_CODEC1]->full_scale_vol = CS42L42_FULL_SCALE_VOL_MINUS6DB; ++ + break; + case HDA_FIXUP_ACT_PROBE: + /* Fix Sample Rate to 48kHz */ +diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h +index d0b725c7285b..8e846f292cd0 100644 +--- a/sound/pci/hda/patch_cs8409.h ++++ b/sound/pci/hda/patch_cs8409.h +@@ -235,6 +235,9 @@ enum cs8409_coefficient_index_registers { + #define CS42L42_I2C_SLEEP_US (2000) + #define CS42L42_PDN_TIMEOUT_US (250000) + #define CS42L42_PDN_SLEEP_US (2000) ++#define CS42L42_FULL_SCALE_VOL_MASK (2) ++#define CS42L42_FULL_SCALE_VOL_0DB (1) ++#define CS42L42_FULL_SCALE_VOL_MINUS6DB (0) + + /* Dell BULLSEYE / WARLOCK / CYBORG Specific Definitions */ + +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs8409-Fix-Warlock-to-use-mono-mic-configur.patch b/patches.suse/ALSA-hda-cs8409-Fix-Warlock-to-use-mono-mic-configur.patch new file mode 100644 index 0000000..4d01f32 --- /dev/null +++ b/patches.suse/ALSA-hda-cs8409-Fix-Warlock-to-use-mono-mic-configur.patch @@ -0,0 +1,38 @@ +From 8a7724535bacbb94fd9441ec232a83d71006d2a9 Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Mon, 28 Mar 2022 12:56:09 +0100 +Subject: [PATCH] ALSA: hda/cs8409: Fix Warlock to use mono mic configuration +Git-commit: 8a7724535bacbb94fd9441ec232a83d71006d2a9 +Patch-mainline: v5.18-rc1 +References: bsc#1203699 + +Warlock/Bullseye Laptops have a mono DMIC, Cyborg uses +a stereo DMIC, and the configuration should reflect this. + +Signed-off-by: Stefan Binding +Signed-off-by: Vitaly Rodionov +Link: https://lore.kernel.org/r/20220328115614.15761-2-vitalyr@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_cs8409.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c +index aff2b5abb81e..1411e3845f16 100644 +--- a/sound/pci/hda/patch_cs8409.c ++++ b/sound/pci/hda/patch_cs8409.c +@@ -907,8 +907,8 @@ static void cs8409_cs42l42_hw_init(struct hda_codec *codec) + } + + /* DMIC1_MO=00b, DMIC1/2_SR=1 */ +- if (codec->fixup_id == CS8409_WARLOCK || codec->fixup_id == CS8409_CYBORG) +- cs8409_vendor_coef_set(codec, 0x09, 0x0003); ++ if (codec->fixup_id == CS8409_CYBORG) ++ cs8409_vendor_coef_set(codec, CS8409_DMIC_CFG, 0x0003); + + cs42l42_resume(cs42l42); + +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs8409-Re-order-quirk-table-into-ascending-.patch b/patches.suse/ALSA-hda-cs8409-Re-order-quirk-table-into-ascending-.patch new file mode 100644 index 0000000..a83e5a9 --- /dev/null +++ b/patches.suse/ALSA-hda-cs8409-Re-order-quirk-table-into-ascending-.patch @@ -0,0 +1,87 @@ +From bdc159dfda0acec5ca3adde1a1b58e1e0ddc8311 Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Mon, 28 Mar 2022 12:56:10 +0100 +Subject: [PATCH] ALSA: hda/cs8409: Re-order quirk table into ascending order +Git-commit: bdc159dfda0acec5ca3adde1a1b58e1e0ddc8311 +Patch-mainline: v5.18-rc1 +References: bsc#1203699 + +To ensure consistency, the quirk table should be re-ordered +in ascending order + +[ a typo fix in the patch description by tiwai ] + +Signed-off-by: Stefan Binding +Signed-off-by: Vitaly Rodionov +Link: https://lore.kernel.org/r/20220328115614.15761-3-vitalyr@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_cs8409-tables.c | 34 ++++++++++++++--------------- + 1 file changed, 17 insertions(+), 17 deletions(-) + +diff --git a/sound/pci/hda/patch_cs8409-tables.c b/sound/pci/hda/patch_cs8409-tables.c +index 2d1fa706327b..9c1fa97100ef 100644 +--- a/sound/pci/hda/patch_cs8409-tables.c ++++ b/sound/pci/hda/patch_cs8409-tables.c +@@ -478,28 +478,29 @@ const struct snd_pci_quirk cs8409_fixup_tbl[] = { + SND_PCI_QUIRK(0x1028, 0x0A29, "Bullseye", CS8409_BULLSEYE), + SND_PCI_QUIRK(0x1028, 0x0A2A, "Bullseye", CS8409_BULLSEYE), + SND_PCI_QUIRK(0x1028, 0x0A2B, "Bullseye", CS8409_BULLSEYE), ++ SND_PCI_QUIRK(0x1028, 0x0A77, "Cyborg", CS8409_CYBORG), ++ SND_PCI_QUIRK(0x1028, 0x0A78, "Cyborg", CS8409_CYBORG), ++ SND_PCI_QUIRK(0x1028, 0x0A79, "Cyborg", CS8409_CYBORG), ++ SND_PCI_QUIRK(0x1028, 0x0A7A, "Cyborg", CS8409_CYBORG), ++ SND_PCI_QUIRK(0x1028, 0x0A7D, "Cyborg", CS8409_CYBORG), ++ SND_PCI_QUIRK(0x1028, 0x0A7E, "Cyborg", CS8409_CYBORG), ++ SND_PCI_QUIRK(0x1028, 0x0A7F, "Cyborg", CS8409_CYBORG), ++ SND_PCI_QUIRK(0x1028, 0x0A80, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AB0, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AB2, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AB1, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AB3, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AB4, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AB5, "Warlock", CS8409_WARLOCK), ++ SND_PCI_QUIRK(0x1028, 0x0ACF, "Dolphin", CS8409_DOLPHIN), ++ SND_PCI_QUIRK(0x1028, 0x0AD0, "Dolphin", CS8409_DOLPHIN), ++ SND_PCI_QUIRK(0x1028, 0x0AD1, "Dolphin", CS8409_DOLPHIN), ++ SND_PCI_QUIRK(0x1028, 0x0AD2, "Dolphin", CS8409_DOLPHIN), ++ SND_PCI_QUIRK(0x1028, 0x0AD3, "Dolphin", CS8409_DOLPHIN), + SND_PCI_QUIRK(0x1028, 0x0AD9, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0ADA, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0ADB, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0ADC, "Warlock", CS8409_WARLOCK), +- SND_PCI_QUIRK(0x1028, 0x0AF4, "Warlock", CS8409_WARLOCK), +- SND_PCI_QUIRK(0x1028, 0x0AF5, "Warlock", CS8409_WARLOCK), +- SND_PCI_QUIRK(0x1028, 0x0BB5, "Warlock N3 15 TGL-U Nuvoton EC", CS8409_WARLOCK), +- SND_PCI_QUIRK(0x1028, 0x0BB6, "Warlock V3 15 TGL-U Nuvoton EC", CS8409_WARLOCK), +- SND_PCI_QUIRK(0x1028, 0x0A77, "Cyborg", CS8409_CYBORG), +- SND_PCI_QUIRK(0x1028, 0x0A78, "Cyborg", CS8409_CYBORG), +- SND_PCI_QUIRK(0x1028, 0x0A79, "Cyborg", CS8409_CYBORG), +- SND_PCI_QUIRK(0x1028, 0x0A7A, "Cyborg", CS8409_CYBORG), +- SND_PCI_QUIRK(0x1028, 0x0A7D, "Cyborg", CS8409_CYBORG), +- SND_PCI_QUIRK(0x1028, 0x0A7E, "Cyborg", CS8409_CYBORG), +- SND_PCI_QUIRK(0x1028, 0x0A7F, "Cyborg", CS8409_CYBORG), +- SND_PCI_QUIRK(0x1028, 0x0A80, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0ADF, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AE0, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AE1, "Cyborg", CS8409_CYBORG), +@@ -512,11 +513,10 @@ const struct snd_pci_quirk cs8409_fixup_tbl[] = { + SND_PCI_QUIRK(0x1028, 0x0AEE, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AEF, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AF0, "Cyborg", CS8409_CYBORG), +- SND_PCI_QUIRK(0x1028, 0x0AD0, "Dolphin", CS8409_DOLPHIN), +- SND_PCI_QUIRK(0x1028, 0x0AD1, "Dolphin", CS8409_DOLPHIN), +- SND_PCI_QUIRK(0x1028, 0x0AD2, "Dolphin", CS8409_DOLPHIN), +- SND_PCI_QUIRK(0x1028, 0x0AD3, "Dolphin", CS8409_DOLPHIN), +- SND_PCI_QUIRK(0x1028, 0x0ACF, "Dolphin", CS8409_DOLPHIN), ++ SND_PCI_QUIRK(0x1028, 0x0AF4, "Warlock", CS8409_WARLOCK), ++ SND_PCI_QUIRK(0x1028, 0x0AF5, "Warlock", CS8409_WARLOCK), ++ SND_PCI_QUIRK(0x1028, 0x0BB5, "Warlock N3 15 TGL-U Nuvoton EC", CS8409_WARLOCK), ++ SND_PCI_QUIRK(0x1028, 0x0BB6, "Warlock V3 15 TGL-U Nuvoton EC", CS8409_WARLOCK), + {} /* terminator */ + }; + +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs8409-Support-manual-mode-detection-for-CS.patch b/patches.suse/ALSA-hda-cs8409-Support-manual-mode-detection-for-CS.patch new file mode 100644 index 0000000..a64d67e --- /dev/null +++ b/patches.suse/ALSA-hda-cs8409-Support-manual-mode-detection-for-CS.patch @@ -0,0 +1,276 @@ +From ec6a8aaafbc5b0467b7554b6e61a93d91fceb613 Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Wed, 4 May 2022 17:12:36 +0100 +Subject: [PATCH] ALSA: hda/cs8409: Support manual mode detection for CS42L42 +Git-commit: ec6a8aaafbc5b0467b7554b6e61a93d91fceb613 +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +For Jack detection on CS42L42, detection is normally done using +"auto" mode, which automatically detects what type of jack is +connected to the device. However, some headsets are not +automatically detected, and as such and alternative detection +method "manual mode" can be used to detect these headsets. + +Signed-off-by: Stefan Binding +Tested-by: Chris Chiu +Link: https://lore.kernel.org/r/20220504161236.2490532-4-sbinding@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_cs8409-tables.c | 3 - + sound/pci/hda/patch_cs8409.c | 159 +++++++++++++++++++++++----- + sound/pci/hda/patch_cs8409.h | 1 - + 3 files changed, 132 insertions(+), 31 deletions(-) + +diff --git a/sound/pci/hda/patch_cs8409-tables.c b/sound/pci/hda/patch_cs8409-tables.c +index a7ee489e6aec..0d11b24a1317 100644 +--- a/sound/pci/hda/patch_cs8409-tables.c ++++ b/sound/pci/hda/patch_cs8409-tables.c +@@ -252,7 +252,6 @@ struct sub_codec cs8409_cs42l42_codec = { + .init_seq_num = ARRAY_SIZE(cs42l42_init_reg_seq), + .hp_jack_in = 0, + .mic_jack_in = 0, +- .force_status_change = 1, + .paged = 1, + .suspended = 1, + .no_type_dect = 0, +@@ -444,7 +443,6 @@ struct sub_codec dolphin_cs42l42_0 = { + .init_seq_num = ARRAY_SIZE(dolphin_c0_init_reg_seq), + .hp_jack_in = 0, + .mic_jack_in = 0, +- .force_status_change = 1, + .paged = 1, + .suspended = 1, + .no_type_dect = 0, +@@ -458,7 +456,6 @@ struct sub_codec dolphin_cs42l42_1 = { + .init_seq_num = ARRAY_SIZE(dolphin_c1_init_reg_seq), + .hp_jack_in = 0, + .mic_jack_in = 0, +- .force_status_change = 1, + .paged = 1, + .suspended = 1, + .no_type_dect = 1, +diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c +index d35d124bf3dc..c3a8b04c71d8 100644 +--- a/sound/pci/hda/patch_cs8409.c ++++ b/sound/pci/hda/patch_cs8409.c +@@ -634,38 +634,128 @@ static void cs42l42_run_jack_detect(struct sub_codec *cs42l42) + cs8409_i2c_write(cs42l42, CS42L42_HSDET_CTL2, 0xc0); + } + +-static int cs42l42_handle_tip_sense(struct sub_codec *cs42l42, unsigned int reg_ts_status) ++static int cs42l42_manual_hs_det(struct sub_codec *cs42l42) + { +- int status_changed = cs42l42->force_status_change; ++ unsigned int hs_det_status; ++ unsigned int hs_det_comp1; ++ unsigned int hs_det_comp2; ++ unsigned int hs_det_sw; ++ unsigned int hs_type; ++ ++ /* Set hs detect to manual, active mode */ ++ cs8409_i2c_write(cs42l42, CS42L42_HSDET_CTL2, ++ (1 << CS42L42_HSDET_CTRL_SHIFT) | ++ (0 << CS42L42_HSDET_SET_SHIFT) | ++ (0 << CS42L42_HSBIAS_REF_SHIFT) | ++ (0 << CS42L42_HSDET_AUTO_TIME_SHIFT)); ++ ++ /* Configure HS DET comparator reference levels. */ ++ cs8409_i2c_write(cs42l42, CS42L42_HSDET_CTL1, ++ (CS42L42_HSDET_COMP1_LVL_VAL << CS42L42_HSDET_COMP1_LVL_SHIFT) | ++ (CS42L42_HSDET_COMP2_LVL_VAL << CS42L42_HSDET_COMP2_LVL_SHIFT)); ++ ++ /* Open the SW_HSB_HS3 switch and close SW_HSB_HS4 for a Type 1 headset. */ ++ cs8409_i2c_write(cs42l42, CS42L42_HS_SWITCH_CTL, CS42L42_HSDET_SW_COMP1); ++ ++ msleep(100); ++ ++ hs_det_status = cs8409_i2c_read(cs42l42, CS42L42_HS_DET_STATUS); ++ ++ hs_det_comp1 = (hs_det_status & CS42L42_HSDET_COMP1_OUT_MASK) >> ++ CS42L42_HSDET_COMP1_OUT_SHIFT; ++ hs_det_comp2 = (hs_det_status & CS42L42_HSDET_COMP2_OUT_MASK) >> ++ CS42L42_HSDET_COMP2_OUT_SHIFT; ++ ++ /* Close the SW_HSB_HS3 switch for a Type 2 headset. */ ++ cs8409_i2c_write(cs42l42, CS42L42_HS_SWITCH_CTL, CS42L42_HSDET_SW_COMP2); + +- cs42l42->force_status_change = 0; ++ msleep(100); ++ ++ hs_det_status = cs8409_i2c_read(cs42l42, CS42L42_HS_DET_STATUS); ++ ++ hs_det_comp1 |= ((hs_det_status & CS42L42_HSDET_COMP1_OUT_MASK) >> ++ CS42L42_HSDET_COMP1_OUT_SHIFT) << 1; ++ hs_det_comp2 |= ((hs_det_status & CS42L42_HSDET_COMP2_OUT_MASK) >> ++ CS42L42_HSDET_COMP2_OUT_SHIFT) << 1; ++ ++ /* Use Comparator 1 with 1.25V Threshold. */ ++ switch (hs_det_comp1) { ++ case CS42L42_HSDET_COMP_TYPE1: ++ hs_type = CS42L42_PLUG_CTIA; ++ hs_det_sw = CS42L42_HSDET_SW_TYPE1; ++ break; ++ case CS42L42_HSDET_COMP_TYPE2: ++ hs_type = CS42L42_PLUG_OMTP; ++ hs_det_sw = CS42L42_HSDET_SW_TYPE2; ++ break; ++ default: ++ /* Fallback to Comparator 2 with 1.75V Threshold. */ ++ switch (hs_det_comp2) { ++ case CS42L42_HSDET_COMP_TYPE1: ++ hs_type = CS42L42_PLUG_CTIA; ++ hs_det_sw = CS42L42_HSDET_SW_TYPE1; ++ break; ++ case CS42L42_HSDET_COMP_TYPE2: ++ hs_type = CS42L42_PLUG_OMTP; ++ hs_det_sw = CS42L42_HSDET_SW_TYPE2; ++ break; ++ case CS42L42_HSDET_COMP_TYPE3: ++ hs_type = CS42L42_PLUG_HEADPHONE; ++ hs_det_sw = CS42L42_HSDET_SW_TYPE3; ++ break; ++ default: ++ hs_type = CS42L42_PLUG_INVALID; ++ hs_det_sw = CS42L42_HSDET_SW_TYPE4; ++ break; ++ } ++ } ++ ++ /* Set Switches */ ++ cs8409_i2c_write(cs42l42, CS42L42_HS_SWITCH_CTL, hs_det_sw); ++ ++ /* Set HSDET mode to Manual—Disabled */ ++ cs8409_i2c_write(cs42l42, CS42L42_HSDET_CTL2, ++ (0 << CS42L42_HSDET_CTRL_SHIFT) | ++ (0 << CS42L42_HSDET_SET_SHIFT) | ++ (0 << CS42L42_HSBIAS_REF_SHIFT) | ++ (0 << CS42L42_HSDET_AUTO_TIME_SHIFT)); ++ ++ /* Configure HS DET comparator reference levels. */ ++ cs8409_i2c_write(cs42l42, CS42L42_HSDET_CTL1, ++ (CS42L42_HSDET_COMP1_LVL_DEFAULT << CS42L42_HSDET_COMP1_LVL_SHIFT) | ++ (CS42L42_HSDET_COMP2_LVL_DEFAULT << CS42L42_HSDET_COMP2_LVL_SHIFT)); ++ ++ return hs_type; ++} ++ ++static int cs42l42_handle_tip_sense(struct sub_codec *cs42l42, unsigned int reg_ts_status) ++{ ++ int status_changed = 0; + + /* TIP_SENSE INSERT/REMOVE */ + switch (reg_ts_status) { + case CS42L42_TS_PLUG: +- if (!cs42l42->hp_jack_in) { +- if (cs42l42->no_type_dect) { +- status_changed = 1; +- cs42l42->hp_jack_in = 1; +- cs42l42->mic_jack_in = 0; +- } else { +- cs42l42_run_jack_detect(cs42l42); +- } ++ if (cs42l42->no_type_dect) { ++ status_changed = 1; ++ cs42l42->hp_jack_in = 1; ++ cs42l42->mic_jack_in = 0; ++ } else { ++ cs42l42_run_jack_detect(cs42l42); + } + break; + + case CS42L42_TS_UNPLUG: +- if (cs42l42->hp_jack_in || cs42l42->mic_jack_in) { +- status_changed = 1; +- cs42l42->hp_jack_in = 0; +- cs42l42->mic_jack_in = 0; +- } ++ status_changed = 1; ++ cs42l42->hp_jack_in = 0; ++ cs42l42->mic_jack_in = 0; + break; + default: + /* jack in transition */ + break; + } + ++ codec_dbg(cs42l42->codec, "Tip Sense Detection: (%d)\n", reg_ts_status); ++ + return status_changed; + } + +@@ -698,24 +788,40 @@ static int cs42l42_jack_unsol_event(struct sub_codec *cs42l42) + + type = (reg_hs_status & CS42L42_HSDET_TYPE_MASK) >> CS42L42_HSDET_TYPE_SHIFT; + ++ /* Configure the HSDET mode. */ ++ cs8409_i2c_write(cs42l42, CS42L42_HSDET_CTL2, 0x80); ++ + if (cs42l42->no_type_dect) { + status_changed = cs42l42_handle_tip_sense(cs42l42, current_plug_status); +- } else if (type == CS42L42_PLUG_INVALID) { +- /* Type CS42L42_PLUG_INVALID not supported */ +- status_changed = cs42l42_handle_tip_sense(cs42l42, CS42L42_TS_UNPLUG); + } else { +- if (!cs42l42->hp_jack_in) { +- status_changed = 1; +- cs42l42->hp_jack_in = 1; ++ if (type == CS42L42_PLUG_INVALID || type == CS42L42_PLUG_HEADPHONE) { ++ codec_dbg(cs42l42->codec, ++ "Auto detect value not valid (%d), running manual det\n", ++ type); ++ type = cs42l42_manual_hs_det(cs42l42); + } +- /* type = CS42L42_PLUG_HEADPHONE has no mic */ +- if ((!cs42l42->mic_jack_in) && (type != CS42L42_PLUG_HEADPHONE)) { ++ ++ switch (type) { ++ case CS42L42_PLUG_CTIA: ++ case CS42L42_PLUG_OMTP: + status_changed = 1; ++ cs42l42->hp_jack_in = 1; + cs42l42->mic_jack_in = 1; ++ break; ++ case CS42L42_PLUG_HEADPHONE: ++ status_changed = 1; ++ cs42l42->hp_jack_in = 1; ++ cs42l42->mic_jack_in = 0; ++ break; ++ default: ++ status_changed = 1; ++ cs42l42->hp_jack_in = 0; ++ cs42l42->mic_jack_in = 0; ++ break; + } ++ codec_dbg(cs42l42->codec, "Detection done (%d)\n", type); + } +- /* Configure the HSDET mode. */ +- cs8409_i2c_write(cs42l42, CS42L42_HSDET_CTL2, 0x80); ++ + /* Enable the HPOUT ground clamp and configure the HP pull-down */ + cs8409_i2c_write(cs42l42, CS42L42_DAC_CTL2, 0x02); + /* Re-Enable Tip Sense Interrupt */ +@@ -803,7 +909,6 @@ static void cs42l42_suspend(struct sub_codec *cs42l42) + cs42l42->last_page = 0; + cs42l42->hp_jack_in = 0; + cs42l42->mic_jack_in = 0; +- cs42l42->force_status_change = 1; + + /* Put CS42L42 into Reset */ + gpio_data = snd_hda_codec_read(codec, CS8409_PIN_AFG, 0, AC_VERB_GET_GPIO_DATA, 0); +diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h +index 988259f8a940..ebf473a3f109 100644 +--- a/sound/pci/hda/patch_cs8409.h ++++ b/sound/pci/hda/patch_cs8409.h +@@ -304,7 +304,6 @@ struct sub_codec { + + unsigned int hp_jack_in:1; + unsigned int mic_jack_in:1; +- unsigned int force_status_change:1; + unsigned int suspended:1; + unsigned int paged:1; + unsigned int last_page; +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs8409-Support-new-Dolphin-Variants.patch b/patches.suse/ALSA-hda-cs8409-Support-new-Dolphin-Variants.patch new file mode 100644 index 0000000..2500c2e --- /dev/null +++ b/patches.suse/ALSA-hda-cs8409-Support-new-Dolphin-Variants.patch @@ -0,0 +1,36 @@ +From 1ff954f9ab054675b9eb02dd14add8f7aa376d71 Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Tue, 16 Aug 2022 16:19:01 +0100 +Subject: [PATCH] ALSA: hda/cs8409: Support new Dolphin Variants +Git-commit: 1ff954f9ab054675b9eb02dd14add8f7aa376d71 +Patch-mainline: v6.0-rc2 +References: bsc#1203699 + +Add 4 new Dolphin Systems, same configuration as older systems. + +Signed-off-by: Stefan Binding +Link: https://lore.kernel.org/r/20220816151901.1398007-1-sbinding@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_cs8409-tables.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/sound/pci/hda/patch_cs8409-tables.c b/sound/pci/hda/patch_cs8409-tables.c +index e0d3a8be2e38..b288874e401e 100644 +--- a/sound/pci/hda/patch_cs8409-tables.c ++++ b/sound/pci/hda/patch_cs8409-tables.c +@@ -546,6 +546,10 @@ const struct snd_pci_quirk cs8409_fixup_tbl[] = { + SND_PCI_QUIRK(0x1028, 0x0BD6, "Dolphin", CS8409_DOLPHIN), + SND_PCI_QUIRK(0x1028, 0x0BD7, "Dolphin", CS8409_DOLPHIN), + SND_PCI_QUIRK(0x1028, 0x0BD8, "Dolphin", CS8409_DOLPHIN), ++ SND_PCI_QUIRK(0x1028, 0x0C43, "Dolphin", CS8409_DOLPHIN), ++ SND_PCI_QUIRK(0x1028, 0x0C50, "Dolphin", CS8409_DOLPHIN), ++ SND_PCI_QUIRK(0x1028, 0x0C51, "Dolphin", CS8409_DOLPHIN), ++ SND_PCI_QUIRK(0x1028, 0x0C52, "Dolphin", CS8409_DOLPHIN), + {} /* terminator */ + }; + +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs8409-Support-new-Odin-Variants.patch b/patches.suse/ALSA-hda-cs8409-Support-new-Odin-Variants.patch new file mode 100644 index 0000000..e70448c --- /dev/null +++ b/patches.suse/ALSA-hda-cs8409-Support-new-Odin-Variants.patch @@ -0,0 +1,122 @@ +From 22bb82264c655ef297adf442cdc796849e5a2a8c Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Wed, 11 May 2022 11:02:05 +0100 +Subject: [PATCH] ALSA: hda/cs8409: Support new Odin Variants +Git-commit: 22bb82264c655ef297adf442cdc796849e5a2a8c +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +Odin Variants have the internal mic connected +directly to the CPU rather than codec. + +Signed-off-by: Stefan Binding +Link: https://lore.kernel.org/r/20220511100207.1268321-2-sbinding@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_cs8409-tables.c | 19 +++++++++++++++++++ + sound/pci/hda/patch_cs8409.c | 12 +++++++++--- + sound/pci/hda/patch_cs8409.h | 1 + + 3 files changed, 29 insertions(+), 3 deletions(-) + +diff --git a/sound/pci/hda/patch_cs8409-tables.c b/sound/pci/hda/patch_cs8409-tables.c +index 0d11b24a1317..4f4cc8215917 100644 +--- a/sound/pci/hda/patch_cs8409-tables.c ++++ b/sound/pci/hda/patch_cs8409-tables.c +@@ -76,6 +76,13 @@ const struct hda_pintbl cs8409_cs42l42_pincfgs[] = { + {} /* terminator */ + }; + ++const struct hda_pintbl cs8409_cs42l42_pincfgs_no_dmic[] = { ++ { CS8409_PIN_ASP1_TRANSMITTER_A, 0x042120f0 }, /* ASP-1-TX */ ++ { CS8409_PIN_ASP1_RECEIVER_A, 0x04a12050 }, /* ASP-1-RX */ ++ { CS8409_PIN_ASP2_TRANSMITTER_A, 0x901000f0 }, /* ASP-2-TX */ ++ {} /* terminator */ ++}; ++ + /* Vendor specific HW configuration for CS42L42 */ + static const struct cs8409_i2c_param cs42l42_init_reg_seq[] = { + { CS42L42_I2C_TIMEOUT, 0xB0 }, +@@ -518,6 +525,11 @@ const struct snd_pci_quirk cs8409_fixup_tbl[] = { + SND_PCI_QUIRK(0x1028, 0x0B95, "Warlock MLK Dual Mic", CS8409_WARLOCK_MLK_DUAL_MIC), + SND_PCI_QUIRK(0x1028, 0x0B96, "Warlock MLK", CS8409_WARLOCK_MLK), + SND_PCI_QUIRK(0x1028, 0x0B97, "Warlock MLK Dual Mic", CS8409_WARLOCK_MLK_DUAL_MIC), ++ SND_PCI_QUIRK(0x1028, 0x0BA5, "Odin", CS8409_ODIN), ++ SND_PCI_QUIRK(0x1028, 0x0BA6, "Odin", CS8409_ODIN), ++ SND_PCI_QUIRK(0x1028, 0x0BA8, "Odin", CS8409_ODIN), ++ SND_PCI_QUIRK(0x1028, 0x0BAA, "Odin", CS8409_ODIN), ++ SND_PCI_QUIRK(0x1028, 0x0BAE, "Odin", CS8409_ODIN), + SND_PCI_QUIRK(0x1028, 0x0BB2, "Warlock MLK", CS8409_WARLOCK_MLK), + SND_PCI_QUIRK(0x1028, 0x0BB3, "Warlock MLK", CS8409_WARLOCK_MLK), + SND_PCI_QUIRK(0x1028, 0x0BB4, "Warlock MLK", CS8409_WARLOCK_MLK), +@@ -545,6 +557,7 @@ const struct hda_model_fixup cs8409_models[] = { + { .id = CS8409_WARLOCK_MLK_DUAL_MIC, .name = "warlock mlk dual mic" }, + { .id = CS8409_CYBORG, .name = "cyborg" }, + { .id = CS8409_DOLPHIN, .name = "dolphin" }, ++ { .id = CS8409_ODIN, .name = "odin" }, + {} + }; + +@@ -593,4 +606,10 @@ const struct hda_fixup cs8409_fixups[] = { + .type = HDA_FIXUP_FUNC, + .v.func = dolphin_fixups, + }, ++ [CS8409_ODIN] = { ++ .type = HDA_FIXUP_PINS, ++ .v.pins = cs8409_cs42l42_pincfgs_no_dmic, ++ .chained = true, ++ .chain_id = CS8409_FIXUPS, ++ }, + }; +diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c +index c3a8b04c71d8..91571e82d148 100644 +--- a/sound/pci/hda/patch_cs8409.c ++++ b/sound/pci/hda/patch_cs8409.c +@@ -1027,6 +1027,10 @@ static void cs8409_cs42l42_hw_init(struct hda_codec *codec) + /* DMIC1_MO=00b, DMIC1/2_SR=1 */ + cs8409_vendor_coef_set(codec, CS8409_DMIC_CFG, 0x0003); + break; ++ case CS8409_ODIN: ++ /* ASP1/2_xxx_EN=1, ASP1/2_MCLK_EN=0, DMIC1_SCL_EN=0 */ ++ cs8409_vendor_coef_set(codec, CS8409_PAD_CFG_SLW_RATE_CTRL, 0xfc00); ++ break; + default: + break; + } +@@ -1116,6 +1120,7 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, + + /* Set HSBIAS_SENSE_EN and Full Scale volume for some variants. */ + switch (codec->fixup_id) { ++ case CS8409_ODIN: + case CS8409_WARLOCK_MLK: + case CS8409_WARLOCK_MLK_DUAL_MIC: + spec->scodecs[CS8409_CODEC0]->hsbias_hiz = 0x0020; +@@ -1136,9 +1141,10 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, + /* add hooks */ + spec->gen.pcm_playback_hook = cs42l42_playback_pcm_hook; + spec->gen.pcm_capture_hook = cs42l42_capture_pcm_hook; +- /* Set initial DMIC volume to -26 dB */ +- snd_hda_codec_amp_init_stereo(codec, CS8409_CS42L42_DMIC_ADC_PIN_NID, +- HDA_INPUT, 0, 0xff, 0x19); ++ if (codec->fixup_id != CS8409_ODIN) ++ /* Set initial DMIC volume to -26 dB */ ++ snd_hda_codec_amp_init_stereo(codec, CS8409_CS42L42_DMIC_ADC_PIN_NID, ++ HDA_INPUT, 0, 0xff, 0x19); + snd_hda_gen_add_kctl(&spec->gen, "Headphone Playback Volume", + &cs42l42_dac_volume_mixer); + snd_hda_gen_add_kctl(&spec->gen, "Mic Capture Volume", +diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h +index ebf473a3f109..9852dc4234b4 100644 +--- a/sound/pci/hda/patch_cs8409.h ++++ b/sound/pci/hda/patch_cs8409.h +@@ -267,6 +267,7 @@ enum { + CS8409_FIXUPS, + CS8409_DOLPHIN, + CS8409_DOLPHIN_FIXUPS, ++ CS8409_ODIN, + }; + + enum { +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs8409-Support-new-Warlock-MLK-Variants.patch b/patches.suse/ALSA-hda-cs8409-Support-new-Warlock-MLK-Variants.patch new file mode 100644 index 0000000..bf718cc --- /dev/null +++ b/patches.suse/ALSA-hda-cs8409-Support-new-Warlock-MLK-Variants.patch @@ -0,0 +1,133 @@ +From 6581a045d54c6a8fe335dd2f343fc7cd2ebfe9e7 Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Mon, 28 Mar 2022 12:56:12 +0100 +Subject: [PATCH] ALSA: hda/cs8409: Support new Warlock MLK Variants +Git-commit: 6581a045d54c6a8fe335dd2f343fc7cd2ebfe9e7 +Patch-mainline: v5.18-rc1 +References: bsc#1203699 + +Added 15 new laptops, with 2 variants: +Warlock MLK and Warlock MLK with Dual Mic + +The only difference between the variants, is the +the dual Mic variants use a stereo DMIC. + +These variants do no use reduce volume (Full Scale Volume) + +Signed-off-by: Stefan Binding +Signed-off-by: Vitaly Rodionov +Link: https://lore.kernel.org/r/20220328115614.15761-5-vitalyr@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_cs8409-tables.c | 29 +++++++++++++++++++++++++++++ + sound/pci/hda/patch_cs8409.c | 15 +++++++++++++-- + sound/pci/hda/patch_cs8409.h | 2 ++ + 3 files changed, 44 insertions(+), 2 deletions(-) + +diff --git a/sound/pci/hda/patch_cs8409-tables.c b/sound/pci/hda/patch_cs8409-tables.c +index 9c1fa97100ef..8d20d7fb3d68 100644 +--- a/sound/pci/hda/patch_cs8409-tables.c ++++ b/sound/pci/hda/patch_cs8409-tables.c +@@ -515,8 +515,23 @@ const struct snd_pci_quirk cs8409_fixup_tbl[] = { + SND_PCI_QUIRK(0x1028, 0x0AF0, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AF4, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AF5, "Warlock", CS8409_WARLOCK), ++ SND_PCI_QUIRK(0x1028, 0x0B92, "Warlock MLK", CS8409_WARLOCK_MLK), ++ SND_PCI_QUIRK(0x1028, 0x0B93, "Warlock MLK Dual Mic", CS8409_WARLOCK_MLK_DUAL_MIC), ++ SND_PCI_QUIRK(0x1028, 0x0B94, "Warlock MLK", CS8409_WARLOCK_MLK), ++ SND_PCI_QUIRK(0x1028, 0x0B95, "Warlock MLK Dual Mic", CS8409_WARLOCK_MLK_DUAL_MIC), ++ SND_PCI_QUIRK(0x1028, 0x0B96, "Warlock MLK", CS8409_WARLOCK_MLK), ++ SND_PCI_QUIRK(0x1028, 0x0B97, "Warlock MLK Dual Mic", CS8409_WARLOCK_MLK_DUAL_MIC), ++ SND_PCI_QUIRK(0x1028, 0x0BB2, "Warlock MLK", CS8409_WARLOCK_MLK), ++ SND_PCI_QUIRK(0x1028, 0x0BB3, "Warlock MLK", CS8409_WARLOCK_MLK), ++ SND_PCI_QUIRK(0x1028, 0x0BB4, "Warlock MLK", CS8409_WARLOCK_MLK), + SND_PCI_QUIRK(0x1028, 0x0BB5, "Warlock N3 15 TGL-U Nuvoton EC", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0BB6, "Warlock V3 15 TGL-U Nuvoton EC", CS8409_WARLOCK), ++ SND_PCI_QUIRK(0x1028, 0x0BB8, "Warlock MLK", CS8409_WARLOCK_MLK), ++ SND_PCI_QUIRK(0x1028, 0x0BB9, "Warlock MLK Dual Mic", CS8409_WARLOCK_MLK_DUAL_MIC), ++ SND_PCI_QUIRK(0x1028, 0x0BBA, "Warlock MLK", CS8409_WARLOCK_MLK), ++ SND_PCI_QUIRK(0x1028, 0x0BBB, "Warlock MLK Dual Mic", CS8409_WARLOCK_MLK_DUAL_MIC), ++ SND_PCI_QUIRK(0x1028, 0x0BBC, "Warlock MLK", CS8409_WARLOCK_MLK), ++ SND_PCI_QUIRK(0x1028, 0x0BBD, "Warlock MLK Dual Mic", CS8409_WARLOCK_MLK_DUAL_MIC), + {} /* terminator */ + }; + +@@ -524,6 +539,8 @@ const struct snd_pci_quirk cs8409_fixup_tbl[] = { + const struct hda_model_fixup cs8409_models[] = { + { .id = CS8409_BULLSEYE, .name = "bullseye" }, + { .id = CS8409_WARLOCK, .name = "warlock" }, ++ { .id = CS8409_WARLOCK_MLK, .name = "warlock mlk" }, ++ { .id = CS8409_WARLOCK_MLK_DUAL_MIC, .name = "warlock mlk dual mic" }, + { .id = CS8409_CYBORG, .name = "cyborg" }, + { .id = CS8409_DOLPHIN, .name = "dolphin" }, + {} +@@ -542,6 +559,18 @@ const struct hda_fixup cs8409_fixups[] = { + .chained = true, + .chain_id = CS8409_FIXUPS, + }, ++ [CS8409_WARLOCK_MLK] = { ++ .type = HDA_FIXUP_PINS, ++ .v.pins = cs8409_cs42l42_pincfgs, ++ .chained = true, ++ .chain_id = CS8409_FIXUPS, ++ }, ++ [CS8409_WARLOCK_MLK_DUAL_MIC] = { ++ .type = HDA_FIXUP_PINS, ++ .v.pins = cs8409_cs42l42_pincfgs, ++ .chained = true, ++ .chain_id = CS8409_FIXUPS, ++ }, + [CS8409_CYBORG] = { + .type = HDA_FIXUP_PINS, + .v.pins = cs8409_cs42l42_pincfgs, +diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c +index 163ff3b3092a..ce5fc03a8065 100644 +--- a/sound/pci/hda/patch_cs8409.c ++++ b/sound/pci/hda/patch_cs8409.c +@@ -912,9 +912,15 @@ static void cs8409_cs42l42_hw_init(struct hda_codec *codec) + cs8409_vendor_coef_set(codec, seq_bullseye->cir, seq_bullseye->coeff); + } + +- /* DMIC1_MO=00b, DMIC1/2_SR=1 */ +- if (codec->fixup_id == CS8409_CYBORG) ++ switch (codec->fixup_id) { ++ case CS8409_CYBORG: ++ case CS8409_WARLOCK_MLK_DUAL_MIC: ++ /* DMIC1_MO=00b, DMIC1/2_SR=1 */ + cs8409_vendor_coef_set(codec, CS8409_DMIC_CFG, 0x0003); ++ break; ++ default: ++ break; ++ } + + cs42l42_resume(cs42l42); + +@@ -1008,6 +1014,11 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, + spec->scodecs[CS8409_CODEC0]->full_scale_vol = + CS42L42_FULL_SCALE_VOL_MINUS6DB; + break; ++ case CS8409_WARLOCK_MLK: ++ case CS8409_WARLOCK_MLK_DUAL_MIC: ++ spec->scodecs[CS8409_CODEC0]->hsbias_hiz = 0x0020; ++ spec->scodecs[CS8409_CODEC0]->full_scale_vol = CS42L42_FULL_SCALE_VOL_0DB; ++ break; + default: + spec->scodecs[CS8409_CODEC0]->hsbias_hiz = 0x0020; + spec->scodecs[CS8409_CODEC0]->full_scale_vol = +diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h +index 8e846f292cd0..7df46bd8d2da 100644 +--- a/sound/pci/hda/patch_cs8409.h ++++ b/sound/pci/hda/patch_cs8409.h +@@ -267,6 +267,8 @@ enum cs8409_coefficient_index_registers { + enum { + CS8409_BULLSEYE, + CS8409_WARLOCK, ++ CS8409_WARLOCK_MLK, ++ CS8409_WARLOCK_MLK_DUAL_MIC, + CS8409_CYBORG, + CS8409_FIXUPS, + CS8409_DOLPHIN, +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs8409-Use-general-cs42l42-include-in-cs840.patch b/patches.suse/ALSA-hda-cs8409-Use-general-cs42l42-include-in-cs840.patch new file mode 100644 index 0000000..384e980 --- /dev/null +++ b/patches.suse/ALSA-hda-cs8409-Use-general-cs42l42-include-in-cs840.patch @@ -0,0 +1,658 @@ +From 9cd827381310e9947ea0ed7fb69b6491419549f2 Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Wed, 4 May 2022 17:12:35 +0100 +Subject: [PATCH] ALSA: hda/cs8409: Use general cs42l42 include in cs8409 hda driver +Git-commit: 9cd827381310e9947ea0ed7fb69b6491419549f2 +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +This is to improve maintainability of the driver. + +Signed-off-by: Stefan Binding +Link: https://lore.kernel.org/r/20220504161236.2490532-3-sbinding@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_cs8409-tables.c | 324 ++++++++++++++-------------- + sound/pci/hda/patch_cs8409.c | 128 +++++------ + sound/pci/hda/patch_cs8409.h | 8 +- + 3 files changed, 229 insertions(+), 231 deletions(-) + +diff --git a/sound/pci/hda/patch_cs8409-tables.c b/sound/pci/hda/patch_cs8409-tables.c +index 74c50ec040d9..a7ee489e6aec 100644 +--- a/sound/pci/hda/patch_cs8409-tables.c ++++ b/sound/pci/hda/patch_cs8409-tables.c +@@ -78,65 +78,65 @@ const struct hda_pintbl cs8409_cs42l42_pincfgs[] = { + + /* Vendor specific HW configuration for CS42L42 */ + static const struct cs8409_i2c_param cs42l42_init_reg_seq[] = { +- { 0x1010, 0xB0 }, +- { 0x1D01, 0x00 }, ++ { CS42L42_I2C_TIMEOUT, 0xB0 }, ++ { CS42L42_ADC_CTL, 0x00 }, + { 0x1D02, 0x06 }, +- { 0x1D03, 0x9F }, +- { 0x1107, 0x01 }, +- { 0x1009, 0x02 }, +- { 0x1007, 0x03 }, +- { 0x1201, 0x00 }, +- { 0x1208, 0x13 }, +- { 0x1205, 0xFF }, +- { 0x1206, 0x00 }, +- { 0x1207, 0x20 }, +- { 0x1202, 0x0D }, +- { 0x2A02, 0x02 }, +- { 0x2A03, 0x00 }, +- { 0x2A04, 0x00 }, +- { 0x2A05, 0x02 }, +- { 0x2A06, 0x00 }, +- { 0x2A07, 0x20 }, +- { 0x2A08, 0x02 }, +- { 0x2A09, 0x00 }, +- { 0x2A0A, 0x80 }, +- { 0x2A0B, 0x02 }, +- { 0x2A0C, 0x00 }, +- { 0x2A0D, 0xA0 }, +- { 0x2A01, 0x0C }, +- { 0x2902, 0x01 }, +- { 0x2903, 0x02 }, +- { 0x2904, 0x00 }, +- { 0x2905, 0x00 }, +- { 0x2901, 0x01 }, +- { 0x1101, 0x0A }, +- { 0x1102, 0x84 }, +- { 0x2301, 0x3F }, +- { 0x2303, 0x3F }, +- { 0x2302, 0x3f }, +- { 0x2001, 0x03 }, +- { 0x1B75, 0xB6 }, +- { 0x1B73, 0xC2 }, +- { 0x1129, 0x01 }, +- { 0x1121, 0xF3 }, +- { 0x1103, 0x20 }, +- { 0x1105, 0x00 }, +- { 0x1112, 0x00 }, +- { 0x1113, 0x80 }, +- { 0x1C03, 0xC0 }, +- { 0x1101, 0x02 }, +- { 0x1316, 0xff }, +- { 0x1317, 0xff }, +- { 0x1318, 0xff }, +- { 0x1319, 0xff }, +- { 0x131a, 0xff }, +- { 0x131b, 0xff }, +- { 0x131c, 0xff }, +- { 0x131e, 0xff }, +- { 0x131f, 0xff }, +- { 0x1320, 0xff }, +- { 0x1b79, 0xff }, +- { 0x1b7a, 0xff }, ++ { CS42L42_ADC_VOLUME, 0x9F }, ++ { CS42L42_OSC_SWITCH, 0x01 }, ++ { CS42L42_MCLK_CTL, 0x02 }, ++ { CS42L42_SRC_CTL, 0x03 }, ++ { CS42L42_MCLK_SRC_SEL, 0x00 }, ++ { CS42L42_ASP_FRM_CFG, 0x13 }, ++ { CS42L42_FSYNC_P_LOWER, 0xFF }, ++ { CS42L42_FSYNC_P_UPPER, 0x00 }, ++ { CS42L42_ASP_CLK_CFG, 0x20 }, ++ { CS42L42_SPDIF_CLK_CFG, 0x0D }, ++ { CS42L42_ASP_RX_DAI0_CH1_AP_RES, 0x02 }, ++ { CS42L42_ASP_RX_DAI0_CH1_BIT_MSB, 0x00 }, ++ { CS42L42_ASP_RX_DAI0_CH1_BIT_LSB, 0x00 }, ++ { CS42L42_ASP_RX_DAI0_CH2_AP_RES, 0x02 }, ++ { CS42L42_ASP_RX_DAI0_CH2_BIT_MSB, 0x00 }, ++ { CS42L42_ASP_RX_DAI0_CH2_BIT_LSB, 0x20 }, ++ { CS42L42_ASP_RX_DAI0_CH3_AP_RES, 0x02 }, ++ { CS42L42_ASP_RX_DAI0_CH3_BIT_MSB, 0x00 }, ++ { CS42L42_ASP_RX_DAI0_CH3_BIT_LSB, 0x80 }, ++ { CS42L42_ASP_RX_DAI0_CH4_AP_RES, 0x02 }, ++ { CS42L42_ASP_RX_DAI0_CH4_BIT_MSB, 0x00 }, ++ { CS42L42_ASP_RX_DAI0_CH4_BIT_LSB, 0xA0 }, ++ { CS42L42_ASP_RX_DAI0_EN, 0x0C }, ++ { CS42L42_ASP_TX_CH_EN, 0x01 }, ++ { CS42L42_ASP_TX_CH_AP_RES, 0x02 }, ++ { CS42L42_ASP_TX_CH1_BIT_MSB, 0x00 }, ++ { CS42L42_ASP_TX_CH1_BIT_LSB, 0x00 }, ++ { CS42L42_ASP_TX_SZ_EN, 0x01 }, ++ { CS42L42_PWR_CTL1, 0x0A }, ++ { CS42L42_PWR_CTL2, 0x84 }, ++ { CS42L42_MIXER_CHA_VOL, 0x3F }, ++ { CS42L42_MIXER_CHB_VOL, 0x3F }, ++ { CS42L42_MIXER_ADC_VOL, 0x3f }, ++ { CS42L42_HP_CTL, 0x03 }, ++ { CS42L42_MIC_DET_CTL1, 0xB6 }, ++ { CS42L42_TIPSENSE_CTL, 0xC2 }, ++ { CS42L42_HS_CLAMP_DISABLE, 0x01 }, ++ { CS42L42_HS_SWITCH_CTL, 0xF3 }, ++ { CS42L42_PWR_CTL3, 0x20 }, ++ { CS42L42_RSENSE_CTL2, 0x00 }, ++ { CS42L42_RSENSE_CTL3, 0x00 }, ++ { CS42L42_TSENSE_CTL, 0x80 }, ++ { CS42L42_HS_BIAS_CTL, 0xC0 }, ++ { CS42L42_PWR_CTL1, 0x02 }, ++ { CS42L42_ADC_OVFL_INT_MASK, 0xff }, ++ { CS42L42_MIXER_INT_MASK, 0xff }, ++ { CS42L42_SRC_INT_MASK, 0xff }, ++ { CS42L42_ASP_RX_INT_MASK, 0xff }, ++ { CS42L42_ASP_TX_INT_MASK, 0xff }, ++ { CS42L42_CODEC_INT_MASK, 0xff }, ++ { CS42L42_SRCPL_INT_MASK, 0xff }, ++ { CS42L42_VPMON_INT_MASK, 0xff }, ++ { CS42L42_PLL_LOCK_INT_MASK, 0xff }, ++ { CS42L42_TSRS_PLUG_INT_MASK, 0xff }, ++ { CS42L42_DET_INT1_MASK, 0xff }, ++ { CS42L42_DET_INT2_MASK, 0xff }, + }; + + /* Vendor specific hw configuration for CS8409 */ +@@ -282,115 +282,115 @@ const struct hda_pintbl dolphin_pincfgs[] = { + + /* Vendor specific HW configuration for CS42L42 */ + static const struct cs8409_i2c_param dolphin_c0_init_reg_seq[] = { +- { 0x1010, 0xB0 }, +- { 0x1D01, 0x00 }, ++ { CS42L42_I2C_TIMEOUT, 0xB0 }, ++ { CS42L42_ADC_CTL, 0x00 }, + { 0x1D02, 0x06 }, +- { 0x1D03, 0x9F }, +- { 0x1107, 0x01 }, +- { 0x1009, 0x02 }, +- { 0x1007, 0x03 }, +- { 0x1201, 0x00 }, +- { 0x1208, 0x13 }, +- { 0x1205, 0xFF }, +- { 0x1206, 0x00 }, +- { 0x1207, 0x20 }, +- { 0x1202, 0x0D }, +- { 0x2A02, 0x02 }, +- { 0x2A03, 0x00 }, +- { 0x2A04, 0x00 }, +- { 0x2A05, 0x02 }, +- { 0x2A06, 0x00 }, +- { 0x2A07, 0x20 }, +- { 0x2A01, 0x0C }, +- { 0x2902, 0x01 }, +- { 0x2903, 0x02 }, +- { 0x2904, 0x00 }, +- { 0x2905, 0x00 }, +- { 0x2901, 0x01 }, +- { 0x1101, 0x0A }, +- { 0x1102, 0x84 }, +- { 0x2001, 0x03 }, +- { 0x2301, 0x3F }, +- { 0x2303, 0x3F }, +- { 0x2302, 0x3f }, +- { 0x1B75, 0xB6 }, +- { 0x1B73, 0xC2 }, +- { 0x1129, 0x01 }, +- { 0x1121, 0xF3 }, +- { 0x1103, 0x20 }, +- { 0x1105, 0x00 }, +- { 0x1112, 0x00 }, +- { 0x1113, 0x80 }, +- { 0x1C03, 0xC0 }, +- { 0x1101, 0x02 }, +- { 0x1316, 0xff }, +- { 0x1317, 0xff }, +- { 0x1318, 0xff }, +- { 0x1319, 0xff }, +- { 0x131a, 0xff }, +- { 0x131b, 0xff }, +- { 0x131c, 0xff }, +- { 0x131e, 0xff }, +- { 0x131f, 0xff }, +- { 0x1320, 0xff }, +- { 0x1b79, 0xff }, +- { 0x1b7a, 0xff } ++ { CS42L42_ADC_VOLUME, 0x9F }, ++ { CS42L42_OSC_SWITCH, 0x01 }, ++ { CS42L42_MCLK_CTL, 0x02 }, ++ { CS42L42_SRC_CTL, 0x03 }, ++ { CS42L42_MCLK_SRC_SEL, 0x00 }, ++ { CS42L42_ASP_FRM_CFG, 0x13 }, ++ { CS42L42_FSYNC_P_LOWER, 0xFF }, ++ { CS42L42_FSYNC_P_UPPER, 0x00 }, ++ { CS42L42_ASP_CLK_CFG, 0x20 }, ++ { CS42L42_SPDIF_CLK_CFG, 0x0D }, ++ { CS42L42_ASP_RX_DAI0_CH1_AP_RES, 0x02 }, ++ { CS42L42_ASP_RX_DAI0_CH1_BIT_MSB, 0x00 }, ++ { CS42L42_ASP_RX_DAI0_CH1_BIT_LSB, 0x00 }, ++ { CS42L42_ASP_RX_DAI0_CH2_AP_RES, 0x02 }, ++ { CS42L42_ASP_RX_DAI0_CH2_BIT_MSB, 0x00 }, ++ { CS42L42_ASP_RX_DAI0_CH2_BIT_LSB, 0x20 }, ++ { CS42L42_ASP_RX_DAI0_EN, 0x0C }, ++ { CS42L42_ASP_TX_CH_EN, 0x01 }, ++ { CS42L42_ASP_TX_CH_AP_RES, 0x02 }, ++ { CS42L42_ASP_TX_CH1_BIT_MSB, 0x00 }, ++ { CS42L42_ASP_TX_CH1_BIT_LSB, 0x00 }, ++ { CS42L42_ASP_TX_SZ_EN, 0x01 }, ++ { CS42L42_PWR_CTL1, 0x0A }, ++ { CS42L42_PWR_CTL2, 0x84 }, ++ { CS42L42_HP_CTL, 0x03 }, ++ { CS42L42_MIXER_CHA_VOL, 0x3F }, ++ { CS42L42_MIXER_CHB_VOL, 0x3F }, ++ { CS42L42_MIXER_ADC_VOL, 0x3f }, ++ { CS42L42_MIC_DET_CTL1, 0xB6 }, ++ { CS42L42_TIPSENSE_CTL, 0xC2 }, ++ { CS42L42_HS_CLAMP_DISABLE, 0x01 }, ++ { CS42L42_HS_SWITCH_CTL, 0xF3 }, ++ { CS42L42_PWR_CTL3, 0x20 }, ++ { CS42L42_RSENSE_CTL2, 0x00 }, ++ { CS42L42_RSENSE_CTL3, 0x00 }, ++ { CS42L42_TSENSE_CTL, 0x80 }, ++ { CS42L42_HS_BIAS_CTL, 0xC0 }, ++ { CS42L42_PWR_CTL1, 0x02 }, ++ { CS42L42_ADC_OVFL_INT_MASK, 0xff }, ++ { CS42L42_MIXER_INT_MASK, 0xff }, ++ { CS42L42_SRC_INT_MASK, 0xff }, ++ { CS42L42_ASP_RX_INT_MASK, 0xff }, ++ { CS42L42_ASP_TX_INT_MASK, 0xff }, ++ { CS42L42_CODEC_INT_MASK, 0xff }, ++ { CS42L42_SRCPL_INT_MASK, 0xff }, ++ { CS42L42_VPMON_INT_MASK, 0xff }, ++ { CS42L42_PLL_LOCK_INT_MASK, 0xff }, ++ { CS42L42_TSRS_PLUG_INT_MASK, 0xff }, ++ { CS42L42_DET_INT1_MASK, 0xff }, ++ { CS42L42_DET_INT2_MASK, 0xff } + }; + + static const struct cs8409_i2c_param dolphin_c1_init_reg_seq[] = { +- { 0x1010, 0xB0 }, +- { 0x1D01, 0x00 }, ++ { CS42L42_I2C_TIMEOUT, 0xB0 }, ++ { CS42L42_ADC_CTL, 0x00 }, + { 0x1D02, 0x06 }, +- { 0x1D03, 0x9F }, +- { 0x1107, 0x01 }, +- { 0x1009, 0x02 }, +- { 0x1007, 0x03 }, +- { 0x1201, 0x00 }, +- { 0x1208, 0x13 }, +- { 0x1205, 0xFF }, +- { 0x1206, 0x00 }, +- { 0x1207, 0x20 }, +- { 0x1202, 0x0D }, +- { 0x2A02, 0x02 }, +- { 0x2A03, 0x00 }, +- { 0x2A04, 0x80 }, +- { 0x2A05, 0x02 }, +- { 0x2A06, 0x00 }, +- { 0x2A07, 0xA0 }, +- { 0x2A01, 0x0C }, +- { 0x2902, 0x00 }, +- { 0x2903, 0x02 }, +- { 0x2904, 0x00 }, +- { 0x2905, 0x00 }, +- { 0x2901, 0x00 }, +- { 0x1101, 0x0E }, +- { 0x1102, 0x84 }, +- { 0x2001, 0x01 }, +- { 0x2301, 0x3F }, +- { 0x2303, 0x3F }, +- { 0x2302, 0x3f }, +- { 0x1B75, 0xB6 }, +- { 0x1B73, 0xC2 }, +- { 0x1129, 0x01 }, +- { 0x1121, 0xF3 }, +- { 0x1103, 0x20 }, +- { 0x1105, 0x00 }, +- { 0x1112, 0x00 }, +- { 0x1113, 0x80 }, +- { 0x1C03, 0xC0 }, +- { 0x1101, 0x06 }, +- { 0x1316, 0xff }, +- { 0x1317, 0xff }, +- { 0x1318, 0xff }, +- { 0x1319, 0xff }, +- { 0x131a, 0xff }, +- { 0x131b, 0xff }, +- { 0x131c, 0xff }, +- { 0x131e, 0xff }, +- { 0x131f, 0xff }, +- { 0x1320, 0xff }, +- { 0x1b79, 0xff }, +- { 0x1b7a, 0xff } ++ { CS42L42_ADC_VOLUME, 0x9F }, ++ { CS42L42_OSC_SWITCH, 0x01 }, ++ { CS42L42_MCLK_CTL, 0x02 }, ++ { CS42L42_SRC_CTL, 0x03 }, ++ { CS42L42_MCLK_SRC_SEL, 0x00 }, ++ { CS42L42_ASP_FRM_CFG, 0x13 }, ++ { CS42L42_FSYNC_P_LOWER, 0xFF }, ++ { CS42L42_FSYNC_P_UPPER, 0x00 }, ++ { CS42L42_ASP_CLK_CFG, 0x20 }, ++ { CS42L42_SPDIF_CLK_CFG, 0x0D }, ++ { CS42L42_ASP_RX_DAI0_CH1_AP_RES, 0x02 }, ++ { CS42L42_ASP_RX_DAI0_CH1_BIT_MSB, 0x00 }, ++ { CS42L42_ASP_RX_DAI0_CH1_BIT_LSB, 0x80 }, ++ { CS42L42_ASP_RX_DAI0_CH2_AP_RES, 0x02 }, ++ { CS42L42_ASP_RX_DAI0_CH2_BIT_MSB, 0x00 }, ++ { CS42L42_ASP_RX_DAI0_CH2_BIT_LSB, 0xA0 }, ++ { CS42L42_ASP_RX_DAI0_EN, 0x0C }, ++ { CS42L42_ASP_TX_CH_EN, 0x00 }, ++ { CS42L42_ASP_TX_CH_AP_RES, 0x02 }, ++ { CS42L42_ASP_TX_CH1_BIT_MSB, 0x00 }, ++ { CS42L42_ASP_TX_CH1_BIT_LSB, 0x00 }, ++ { CS42L42_ASP_TX_SZ_EN, 0x00 }, ++ { CS42L42_PWR_CTL1, 0x0E }, ++ { CS42L42_PWR_CTL2, 0x84 }, ++ { CS42L42_HP_CTL, 0x01 }, ++ { CS42L42_MIXER_CHA_VOL, 0x3F }, ++ { CS42L42_MIXER_CHB_VOL, 0x3F }, ++ { CS42L42_MIXER_ADC_VOL, 0x3f }, ++ { CS42L42_MIC_DET_CTL1, 0xB6 }, ++ { CS42L42_TIPSENSE_CTL, 0xC2 }, ++ { CS42L42_HS_CLAMP_DISABLE, 0x01 }, ++ { CS42L42_HS_SWITCH_CTL, 0xF3 }, ++ { CS42L42_PWR_CTL3, 0x20 }, ++ { CS42L42_RSENSE_CTL2, 0x00 }, ++ { CS42L42_RSENSE_CTL3, 0x00 }, ++ { CS42L42_TSENSE_CTL, 0x80 }, ++ { CS42L42_HS_BIAS_CTL, 0xC0 }, ++ { CS42L42_PWR_CTL1, 0x06 }, ++ { CS42L42_ADC_OVFL_INT_MASK, 0xff }, ++ { CS42L42_MIXER_INT_MASK, 0xff }, ++ { CS42L42_SRC_INT_MASK, 0xff }, ++ { CS42L42_ASP_RX_INT_MASK, 0xff }, ++ { CS42L42_ASP_TX_INT_MASK, 0xff }, ++ { CS42L42_CODEC_INT_MASK, 0xff }, ++ { CS42L42_SRCPL_INT_MASK, 0xff }, ++ { CS42L42_VPMON_INT_MASK, 0xff }, ++ { CS42L42_PLL_LOCK_INT_MASK, 0xff }, ++ { CS42L42_TSRS_PLUG_INT_MASK, 0xff }, ++ { CS42L42_DET_INT1_MASK, 0xff }, ++ { CS42L42_DET_INT2_MASK, 0xff } + }; + + /* Vendor specific hw configuration for CS8409 */ +diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c +index 343fabc4387d..d35d124bf3dc 100644 +--- a/sound/pci/hda/patch_cs8409.c ++++ b/sound/pci/hda/patch_cs8409.c +@@ -481,26 +481,26 @@ static void cs42l42_mute(struct sub_codec *cs42l42, int vol_type, + if (mute) { + if (vol_type == CS42L42_VOL_DAC) { + if (chs & BIT(0)) +- cs8409_i2c_write(cs42l42, CS42L42_REG_HS_VOL_CHA, 0x3f); ++ cs8409_i2c_write(cs42l42, CS42L42_MIXER_CHA_VOL, 0x3f); + if (chs & BIT(1)) +- cs8409_i2c_write(cs42l42, CS42L42_REG_HS_VOL_CHB, 0x3f); ++ cs8409_i2c_write(cs42l42, CS42L42_MIXER_CHB_VOL, 0x3f); + } else if (vol_type == CS42L42_VOL_ADC) { + if (chs & BIT(0)) +- cs8409_i2c_write(cs42l42, CS42L42_REG_AMIC_VOL, 0x9f); ++ cs8409_i2c_write(cs42l42, CS42L42_ADC_VOLUME, 0x9f); + } + } else { + if (vol_type == CS42L42_VOL_DAC) { + if (chs & BIT(0)) +- cs8409_i2c_write(cs42l42, CS42L42_REG_HS_VOL_CHA, ++ cs8409_i2c_write(cs42l42, CS42L42_MIXER_CHA_VOL, + -(cs42l42->vol[CS42L42_DAC_CH0_VOL_OFFSET]) +- & CS42L42_REG_HS_VOL_MASK); ++ & CS42L42_MIXER_CH_VOL_MASK); + if (chs & BIT(1)) +- cs8409_i2c_write(cs42l42, CS42L42_REG_HS_VOL_CHB, ++ cs8409_i2c_write(cs42l42, CS42L42_MIXER_CHB_VOL, + -(cs42l42->vol[CS42L42_DAC_CH1_VOL_OFFSET]) +- & CS42L42_REG_HS_VOL_MASK); ++ & CS42L42_MIXER_CH_VOL_MASK); + } else if (vol_type == CS42L42_VOL_ADC) { + if (chs & BIT(0)) +- cs8409_i2c_write(cs42l42, CS42L42_REG_AMIC_VOL, ++ cs8409_i2c_write(cs42l42, CS42L42_ADC_VOLUME, + cs42l42->vol[CS42L42_ADC_VOL_OFFSET] + & CS42L42_REG_AMIC_VOL_MASK); + } +@@ -601,37 +601,37 @@ static void cs42l42_capture_pcm_hook(struct hda_pcm_stream *hinfo, + /* Configure CS42L42 slave codec for jack autodetect */ + static void cs42l42_enable_jack_detect(struct sub_codec *cs42l42) + { +- cs8409_i2c_write(cs42l42, 0x1b70, cs42l42->hsbias_hiz); ++ cs8409_i2c_write(cs42l42, CS42L42_HSBIAS_SC_AUTOCTL, cs42l42->hsbias_hiz); + /* Clear WAKE# */ +- cs8409_i2c_write(cs42l42, 0x1b71, 0x00C1); ++ cs8409_i2c_write(cs42l42, CS42L42_WAKE_CTL, 0x00C1); + /* Wait ~2.5ms */ + usleep_range(2500, 3000); + /* Set mode WAKE# output follows the combination logic directly */ +- cs8409_i2c_write(cs42l42, 0x1b71, 0x00C0); ++ cs8409_i2c_write(cs42l42, CS42L42_WAKE_CTL, 0x00C0); + /* Clear interrupts status */ +- cs8409_i2c_read(cs42l42, 0x130f); ++ cs8409_i2c_read(cs42l42, CS42L42_TSRS_PLUG_STATUS); + /* Enable interrupt */ +- cs8409_i2c_write(cs42l42, 0x1320, 0xF3); ++ cs8409_i2c_write(cs42l42, CS42L42_TSRS_PLUG_INT_MASK, 0xF3); + } + + /* Enable and run CS42L42 slave codec jack auto detect */ + static void cs42l42_run_jack_detect(struct sub_codec *cs42l42) + { + /* Clear interrupts */ +- cs8409_i2c_read(cs42l42, 0x1308); +- cs8409_i2c_read(cs42l42, 0x1b77); +- cs8409_i2c_write(cs42l42, 0x1320, 0xFF); +- cs8409_i2c_read(cs42l42, 0x130f); +- +- cs8409_i2c_write(cs42l42, 0x1102, 0x87); +- cs8409_i2c_write(cs42l42, 0x1f06, 0x86); +- cs8409_i2c_write(cs42l42, 0x1b74, 0x07); +- cs8409_i2c_write(cs42l42, 0x131b, 0xFD); +- cs8409_i2c_write(cs42l42, 0x1120, 0x80); ++ cs8409_i2c_read(cs42l42, CS42L42_CODEC_STATUS); ++ cs8409_i2c_read(cs42l42, CS42L42_DET_STATUS1); ++ cs8409_i2c_write(cs42l42, CS42L42_TSRS_PLUG_INT_MASK, 0xFF); ++ cs8409_i2c_read(cs42l42, CS42L42_TSRS_PLUG_STATUS); ++ ++ cs8409_i2c_write(cs42l42, CS42L42_PWR_CTL2, 0x87); ++ cs8409_i2c_write(cs42l42, CS42L42_DAC_CTL2, 0x86); ++ cs8409_i2c_write(cs42l42, CS42L42_MISC_DET_CTL, 0x07); ++ cs8409_i2c_write(cs42l42, CS42L42_CODEC_INT_MASK, 0xFD); ++ cs8409_i2c_write(cs42l42, CS42L42_HSDET_CTL2, 0x80); + /* Wait ~20ms*/ + usleep_range(20000, 25000); +- cs8409_i2c_write(cs42l42, 0x111f, 0x77); +- cs8409_i2c_write(cs42l42, 0x1120, 0xc0); ++ cs8409_i2c_write(cs42l42, CS42L42_HSDET_CTL1, 0x77); ++ cs8409_i2c_write(cs42l42, CS42L42_HSDET_CTL2, 0xc0); + } + + static int cs42l42_handle_tip_sense(struct sub_codec *cs42l42, unsigned int reg_ts_status) +@@ -642,7 +642,7 @@ static int cs42l42_handle_tip_sense(struct sub_codec *cs42l42, unsigned int reg_ + + /* TIP_SENSE INSERT/REMOVE */ + switch (reg_ts_status) { +- case CS42L42_JACK_INSERTED: ++ case CS42L42_TS_PLUG: + if (!cs42l42->hp_jack_in) { + if (cs42l42->no_type_dect) { + status_changed = 1; +@@ -654,7 +654,7 @@ static int cs42l42_handle_tip_sense(struct sub_codec *cs42l42, unsigned int reg_ + } + break; + +- case CS42L42_JACK_REMOVED: ++ case CS42L42_TS_UNPLUG: + if (cs42l42->hp_jack_in || cs42l42->mic_jack_in) { + status_changed = 1; + cs42l42->hp_jack_in = 0; +@@ -671,6 +671,7 @@ static int cs42l42_handle_tip_sense(struct sub_codec *cs42l42, unsigned int reg_ + + static int cs42l42_jack_unsol_event(struct sub_codec *cs42l42) + { ++ int current_plug_status; + int status_changed = 0; + int reg_cdc_status; + int reg_hs_status; +@@ -678,46 +679,49 @@ static int cs42l42_jack_unsol_event(struct sub_codec *cs42l42) + int type; + + /* Read jack detect status registers */ +- reg_cdc_status = cs8409_i2c_read(cs42l42, 0x1308); +- reg_hs_status = cs8409_i2c_read(cs42l42, 0x1124); +- reg_ts_status = cs8409_i2c_read(cs42l42, 0x130f); ++ reg_cdc_status = cs8409_i2c_read(cs42l42, CS42L42_CODEC_STATUS); ++ reg_hs_status = cs8409_i2c_read(cs42l42, CS42L42_HS_DET_STATUS); ++ reg_ts_status = cs8409_i2c_read(cs42l42, CS42L42_TSRS_PLUG_STATUS); + + /* If status values are < 0, read error has occurred. */ + if (reg_cdc_status < 0 || reg_hs_status < 0 || reg_ts_status < 0) + return -EIO; + ++ current_plug_status = (reg_ts_status & (CS42L42_TS_PLUG_MASK | CS42L42_TS_UNPLUG_MASK)) ++ >> CS42L42_TS_PLUG_SHIFT; ++ + /* HSDET_AUTO_DONE */ +- if (reg_cdc_status & CS42L42_HSDET_AUTO_DONE) { ++ if (reg_cdc_status & CS42L42_HSDET_AUTO_DONE_MASK) { + + /* Disable HSDET_AUTO_DONE */ +- cs8409_i2c_write(cs42l42, 0x131b, 0xFF); ++ cs8409_i2c_write(cs42l42, CS42L42_CODEC_INT_MASK, 0xFF); + +- type = ((reg_hs_status & CS42L42_HSTYPE_MASK) + 1); ++ type = (reg_hs_status & CS42L42_HSDET_TYPE_MASK) >> CS42L42_HSDET_TYPE_SHIFT; + + if (cs42l42->no_type_dect) { +- status_changed = cs42l42_handle_tip_sense(cs42l42, reg_ts_status); +- } else if (type == 4) { +- /* Type 4 not supported */ +- status_changed = cs42l42_handle_tip_sense(cs42l42, CS42L42_JACK_REMOVED); ++ status_changed = cs42l42_handle_tip_sense(cs42l42, current_plug_status); ++ } else if (type == CS42L42_PLUG_INVALID) { ++ /* Type CS42L42_PLUG_INVALID not supported */ ++ status_changed = cs42l42_handle_tip_sense(cs42l42, CS42L42_TS_UNPLUG); + } else { + if (!cs42l42->hp_jack_in) { + status_changed = 1; + cs42l42->hp_jack_in = 1; + } +- /* type = 3 has no mic */ +- if ((!cs42l42->mic_jack_in) && (type != 3)) { ++ /* type = CS42L42_PLUG_HEADPHONE has no mic */ ++ if ((!cs42l42->mic_jack_in) && (type != CS42L42_PLUG_HEADPHONE)) { + status_changed = 1; + cs42l42->mic_jack_in = 1; + } + } + /* Configure the HSDET mode. */ +- cs8409_i2c_write(cs42l42, 0x1120, 0x80); ++ cs8409_i2c_write(cs42l42, CS42L42_HSDET_CTL2, 0x80); + /* Enable the HPOUT ground clamp and configure the HP pull-down */ +- cs8409_i2c_write(cs42l42, 0x1F06, 0x02); ++ cs8409_i2c_write(cs42l42, CS42L42_DAC_CTL2, 0x02); + /* Re-Enable Tip Sense Interrupt */ +- cs8409_i2c_write(cs42l42, 0x1320, 0xF3); ++ cs8409_i2c_write(cs42l42, CS42L42_TSRS_PLUG_INT_MASK, 0xF3); + } else { +- status_changed = cs42l42_handle_tip_sense(cs42l42, reg_ts_status); ++ status_changed = cs42l42_handle_tip_sense(cs42l42, current_plug_status); + } + + return status_changed; +@@ -728,10 +732,10 @@ static void cs42l42_resume(struct sub_codec *cs42l42) + struct hda_codec *codec = cs42l42->codec; + unsigned int gpio_data; + struct cs8409_i2c_param irq_regs[] = { +- { 0x1308, 0x00 }, +- { 0x1309, 0x00 }, +- { 0x130A, 0x00 }, +- { 0x130F, 0x00 }, ++ { CS42L42_CODEC_STATUS, 0x00 }, ++ { CS42L42_DET_INT_STATUS1, 0x00 }, ++ { CS42L42_DET_INT_STATUS2, 0x00 }, ++ { CS42L42_TSRS_PLUG_STATUS, 0x00 }, + }; + int fsv_old, fsv_new; + +@@ -750,13 +754,13 @@ static void cs42l42_resume(struct sub_codec *cs42l42) + /* Clear interrupts, by reading interrupt status registers */ + cs8409_i2c_bulk_read(cs42l42, irq_regs, ARRAY_SIZE(irq_regs)); + +- fsv_old = cs8409_i2c_read(cs42l42, 0x2001); ++ fsv_old = cs8409_i2c_read(cs42l42, CS42L42_HP_CTL); + if (cs42l42->full_scale_vol == CS42L42_FULL_SCALE_VOL_0DB) + fsv_new = fsv_old & ~CS42L42_FULL_SCALE_VOL_MASK; + else + fsv_new = fsv_old & CS42L42_FULL_SCALE_VOL_MASK; + if (fsv_new != fsv_old) +- cs8409_i2c_write(cs42l42, 0x2001, fsv_new); ++ cs8409_i2c_write(cs42l42, CS42L42_HP_CTL, fsv_new); + + /* we have to explicitly allow unsol event handling even during the + * resume phase so that the jack event is processed properly +@@ -773,28 +777,28 @@ static void cs42l42_suspend(struct sub_codec *cs42l42) + unsigned int gpio_data; + int reg_cdc_status = 0; + const struct cs8409_i2c_param cs42l42_pwr_down_seq[] = { +- { 0x1F06, 0x02 }, +- { 0x1129, 0x00 }, +- { 0x2301, 0x3F }, +- { 0x2302, 0x3F }, +- { 0x2303, 0x3F }, +- { 0x2001, 0x0F }, +- { 0x2A01, 0x00 }, +- { 0x1207, 0x00 }, +- { 0x1101, 0xFE }, +- { 0x1102, 0x8C }, +- { 0x1101, 0xFF }, ++ { CS42L42_DAC_CTL2, 0x02 }, ++ { CS42L42_HS_CLAMP_DISABLE, 0x00 }, ++ { CS42L42_MIXER_CHA_VOL, 0x3F }, ++ { CS42L42_MIXER_ADC_VOL, 0x3F }, ++ { CS42L42_MIXER_CHB_VOL, 0x3F }, ++ { CS42L42_HP_CTL, 0x0F }, ++ { CS42L42_ASP_RX_DAI0_EN, 0x00 }, ++ { CS42L42_ASP_CLK_CFG, 0x00 }, ++ { CS42L42_PWR_CTL1, 0xFE }, ++ { CS42L42_PWR_CTL2, 0x8C }, ++ { CS42L42_PWR_CTL1, 0xFF }, + }; + + cs8409_i2c_bulk_write(cs42l42, cs42l42_pwr_down_seq, ARRAY_SIZE(cs42l42_pwr_down_seq)); + + if (read_poll_timeout(cs8409_i2c_read, reg_cdc_status, + (reg_cdc_status & 0x1), CS42L42_PDN_SLEEP_US, CS42L42_PDN_TIMEOUT_US, +- true, cs42l42, 0x1308) < 0) ++ true, cs42l42, CS42L42_CODEC_STATUS) < 0) + codec_warn(codec, "Timeout waiting for PDN_DONE for CS42L42\n"); + + /* Power down CS42L42 ASP/EQ/MIX/HP */ +- cs8409_i2c_write(cs42l42, 0x1102, 0x9C); ++ cs8409_i2c_write(cs42l42, CS42L42_PWR_CTL2, 0x9C); + cs42l42->suspended = 1; + cs42l42->last_page = 0; + cs42l42->hp_jack_in = 0; +diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h +index 7df46bd8d2da..988259f8a940 100644 +--- a/sound/pci/hda/patch_cs8409.h ++++ b/sound/pci/hda/patch_cs8409.h +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + #include + #include "hda_local.h" + #include "hda_auto_parser.h" +@@ -222,15 +223,8 @@ enum cs8409_coefficient_index_registers { + #define CS42L42_HP_VOL_REAL_MAX (0) + #define CS42L42_AMIC_VOL_REAL_MIN (-97) + #define CS42L42_AMIC_VOL_REAL_MAX (12) +-#define CS42L42_REG_HS_VOL_CHA (0x2301) +-#define CS42L42_REG_HS_VOL_CHB (0x2303) +-#define CS42L42_REG_HS_VOL_MASK (0x003F) +-#define CS42L42_REG_AMIC_VOL (0x1D03) + #define CS42L42_REG_AMIC_VOL_MASK (0x00FF) +-#define CS42L42_HSDET_AUTO_DONE (0x02) + #define CS42L42_HSTYPE_MASK (0x03) +-#define CS42L42_JACK_INSERTED (0x0C) +-#define CS42L42_JACK_REMOVED (0x00) + #define CS42L42_I2C_TIMEOUT_US (20000) + #define CS42L42_I2C_SLEEP_US (2000) + #define CS42L42_PDN_TIMEOUT_US (250000) +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs8409-change-cs8409_fixups-v.pins-initiali.patch b/patches.suse/ALSA-hda-cs8409-change-cs8409_fixups-v.pins-initiali.patch new file mode 100644 index 0000000..6ce39a1 --- /dev/null +++ b/patches.suse/ALSA-hda-cs8409-change-cs8409_fixups-v.pins-initiali.patch @@ -0,0 +1,83 @@ +From 65123b899818b1adf7388b3583624e0f1d8d6858 Mon Sep 17 00:00:00 2001 +From: Tom Rix +Date: Mon, 4 Jul 2022 10:28:36 -0400 +Subject: [PATCH] ALSA: hda/cs8409: change cs8409_fixups v.pins initializers to static +Git-commit: 65123b899818b1adf7388b3583624e0f1d8d6858 +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +sparse reports +sound/pci/hda/patch_cs8409-tables.c:79:25: warning: symbol 'cs8409_cs42l42_pincfgs_no_dmic' was not declared. Should it be static? + +cs8409_cs42l42_pincfgs_no_dmic is only used by cs8409_fixups table as an +initializer for the hda_fixup element v.pins. Both are defined in the +patch_cs8408-table.c file but only cs8409_fixups is used externally in +patch_cs8409.c. So cs8409_cs42l42_pincfgs_no_dmic should have a static +storage class specifier. + +The other v.pins initializers in cs8409_fixups table, though declared +extern in patch_cs8409.h are also only used in patch_cs8409-tables.c. +So change all the v.pins initializers to static. + +Fixes: 9e7647b5070f ("ALSA: hda/cs8409: Move arrays of configuration to a new file") +Signed-off-by: Tom Rix +Link: https://lore.kernel.org/r/20220704142836.636204-1-trix@redhat.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_cs8409-tables.c | 6 +++--- + sound/pci/hda/patch_cs8409.h | 2 -- + 2 files changed, 3 insertions(+), 5 deletions(-) + +diff --git a/sound/pci/hda/patch_cs8409-tables.c b/sound/pci/hda/patch_cs8409-tables.c +index 4f4cc8215917..e0d3a8be2e38 100644 +--- a/sound/pci/hda/patch_cs8409-tables.c ++++ b/sound/pci/hda/patch_cs8409-tables.c +@@ -68,7 +68,7 @@ const struct hda_verb cs8409_cs42l42_init_verbs[] = { + {} /* terminator */ + }; + +-const struct hda_pintbl cs8409_cs42l42_pincfgs[] = { ++static const struct hda_pintbl cs8409_cs42l42_pincfgs[] = { + { CS8409_PIN_ASP1_TRANSMITTER_A, 0x042120f0 }, /* ASP-1-TX */ + { CS8409_PIN_ASP1_RECEIVER_A, 0x04a12050 }, /* ASP-1-RX */ + { CS8409_PIN_ASP2_TRANSMITTER_A, 0x901000f0 }, /* ASP-2-TX */ +@@ -76,7 +76,7 @@ const struct hda_pintbl cs8409_cs42l42_pincfgs[] = { + {} /* terminator */ + }; + +-const struct hda_pintbl cs8409_cs42l42_pincfgs_no_dmic[] = { ++static const struct hda_pintbl cs8409_cs42l42_pincfgs_no_dmic[] = { + { CS8409_PIN_ASP1_TRANSMITTER_A, 0x042120f0 }, /* ASP-1-TX */ + { CS8409_PIN_ASP1_RECEIVER_A, 0x04a12050 }, /* ASP-1-RX */ + { CS8409_PIN_ASP2_TRANSMITTER_A, 0x901000f0 }, /* ASP-2-TX */ +@@ -279,7 +279,7 @@ const struct hda_verb dolphin_init_verbs[] = { + {} /* terminator */ + }; + +-const struct hda_pintbl dolphin_pincfgs[] = { ++static const struct hda_pintbl dolphin_pincfgs[] = { + { 0x24, 0x022210f0 }, /* ASP-1-TX-A */ + { 0x25, 0x010240f0 }, /* ASP-1-TX-B */ + { 0x34, 0x02a21050 }, /* ASP-1-RX */ +diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h +index 260388a6256c..2a8dfb4ff046 100644 +--- a/sound/pci/hda/patch_cs8409.h ++++ b/sound/pci/hda/patch_cs8409.h +@@ -358,13 +358,11 @@ extern const struct snd_pci_quirk cs8409_fixup_tbl[]; + extern const struct hda_model_fixup cs8409_models[]; + extern const struct hda_fixup cs8409_fixups[]; + extern const struct hda_verb cs8409_cs42l42_init_verbs[]; +-extern const struct hda_pintbl cs8409_cs42l42_pincfgs[]; + extern const struct cs8409_cir_param cs8409_cs42l42_hw_cfg[]; + extern const struct cs8409_cir_param cs8409_cs42l42_bullseye_atn[]; + extern struct sub_codec cs8409_cs42l42_codec; + + extern const struct hda_verb dolphin_init_verbs[]; +-extern const struct hda_pintbl dolphin_pincfgs[]; + extern const struct cs8409_cir_param dolphin_hw_cfg[]; + extern struct sub_codec dolphin_cs42l42_0; + extern struct sub_codec dolphin_cs42l42_1; +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-cs_dsp_ctl-Fix-mutex-inversion-when-creatin.patch b/patches.suse/ALSA-hda-cs_dsp_ctl-Fix-mutex-inversion-when-creatin.patch new file mode 100644 index 0000000..677227d --- /dev/null +++ b/patches.suse/ALSA-hda-cs_dsp_ctl-Fix-mutex-inversion-when-creatin.patch @@ -0,0 +1,222 @@ +From 2176c6b599dba55a640cffec0182c0b6bab680d1 Mon Sep 17 00:00:00 2001 +From: Richard Fitzgerald +Date: Tue, 11 Oct 2022 15:35:50 +0100 +Subject: [PATCH] ALSA: hda/cs_dsp_ctl: Fix mutex inversion when creating + controls +Git-commit: 2176c6b599dba55a640cffec0182c0b6bab680d1 +Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git +Patch-mainline: Queued in subsystem maintainer repository +References: bsc#1203699 + +Redesign the creation of ALSA controls so that the cs_dsp +pwr_lock is not held when calling snd_ctl_add(). Instead of +creating the ALSA control from the cs_dsp control_add callback, +do it after cs_dsp_power_up() has completed. The existing +functions are changed to return void instead of passing errors +back - this duplicates the original behaviour, as cs_dsp does +not abort firmware load if creation of a control fails. + +It is safe to walk the control list without taking any mutex +provided that the caller is not trying to load a new firmware +or remove the driver in parallel. There is no other situation +that the list can change. So the caller can trigger creation +of ALSA controls after cs_dsp_power_up() has returned. A cs_dsp +control will have a non-NULL priv pointer if we have created +an ALSA control. + +With the previous code the ALSA controls were created from +the cs_dsp control_add callback. But this is called with +pwr_lock held (as it is part of the DSP power-up sequence). +The kernel lock checking will show a mutex inversion between +this and the control creation path: + +control_add + pwr_lock held, takes controls_rwsem (in snd_ctl_add) + +get/put + controls_rwsem held, takes pwr_lock to call cs_dsp. + +This is not completely theoretical. Although the time window +is very small, it is possible for these to run in parallel +and deadlock the old implementation. + +Signed-off-by: Richard Fitzgerald +Signed-off-by: Stefan Binding +Link: https://lore.kernel.org/r/20221011143552.621792-4-sbinding@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/cs35l41_hda.c | 8 ++--- + sound/pci/hda/hda_cs_dsp_ctl.c | 59 ++++++++++++++++++++-------------- + sound/pci/hda/hda_cs_dsp_ctl.h | 2 +- + 3 files changed, 40 insertions(+), 29 deletions(-) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index 3952f2853703..102ac4a94a9d 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -91,20 +91,18 @@ static const struct reg_sequence cs35l41_hda_mute[] = { + { CS35L41_AMP_DIG_VOL_CTRL, 0x0000A678 }, // AMP_VOL_PCM Mute + }; + +-static int cs35l41_control_add(struct cs_dsp_coeff_ctl *cs_ctl) ++static void cs35l41_add_controls(struct cs35l41_hda *cs35l41) + { +- struct cs35l41_hda *cs35l41 = container_of(cs_ctl->dsp, struct cs35l41_hda, cs_dsp); + struct hda_cs_dsp_ctl_info info; + + info.device_name = cs35l41->amp_name; + info.fw_type = cs35l41->firmware_type; + info.card = cs35l41->codec->card; + +- return hda_cs_dsp_control_add(cs_ctl, &info); ++ hda_cs_dsp_add_controls(&cs35l41->cs_dsp, &info); + } + + static const struct cs_dsp_client_ops client_ops = { +- .control_add = cs35l41_control_add, + .control_remove = hda_cs_dsp_control_remove, + }; + +@@ -435,6 +433,8 @@ static int cs35l41_init_dsp(struct cs35l41_hda *cs35l41) + if (ret) + goto err_release; + ++ cs35l41_add_controls(cs35l41); ++ + ret = cs35l41_save_calibration(cs35l41); + + err_release: +diff --git a/sound/pci/hda/hda_cs_dsp_ctl.c b/sound/pci/hda/hda_cs_dsp_ctl.c +index 75fb69185817..1622a22f96f6 100644 +--- a/sound/pci/hda/hda_cs_dsp_ctl.c ++++ b/sound/pci/hda/hda_cs_dsp_ctl.c +@@ -97,7 +97,7 @@ static unsigned int wmfw_convert_flags(unsigned int in) + return out; + } + +-static int hda_cs_dsp_add_kcontrol(struct hda_cs_dsp_coeff_ctl *ctl, const char *name) ++static void hda_cs_dsp_add_kcontrol(struct hda_cs_dsp_coeff_ctl *ctl, const char *name) + { + struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl; + struct snd_kcontrol_new kcontrol = {0}; +@@ -107,7 +107,7 @@ static int hda_cs_dsp_add_kcontrol(struct hda_cs_dsp_coeff_ctl *ctl, const char + if (cs_ctl->len > ADSP_MAX_STD_CTRL_SIZE) { + dev_err(cs_ctl->dsp->dev, "KControl %s: length %zu exceeds maximum %d\n", name, + cs_ctl->len, ADSP_MAX_STD_CTRL_SIZE); +- return -EINVAL; ++ return; + } + + kcontrol.name = name; +@@ -120,24 +120,21 @@ static int hda_cs_dsp_add_kcontrol(struct hda_cs_dsp_coeff_ctl *ctl, const char + /* Save ctl inside private_data, ctl is owned by cs_dsp, + * and will be freed when cs_dsp removes the control */ + kctl = snd_ctl_new1(&kcontrol, (void *)ctl); +- if (!kctl) { +- ret = -ENOMEM; +- return ret; +- } ++ if (!kctl) ++ return; + + ret = snd_ctl_add(ctl->card, kctl); + if (ret) { + dev_err(cs_ctl->dsp->dev, "Failed to add KControl %s = %d\n", kcontrol.name, ret); +- return ret; ++ return; + } + + dev_dbg(cs_ctl->dsp->dev, "Added KControl: %s\n", kcontrol.name); + ctl->kctl = kctl; +- +- return 0; + } + +-int hda_cs_dsp_control_add(struct cs_dsp_coeff_ctl *cs_ctl, struct hda_cs_dsp_ctl_info *info) ++static void hda_cs_dsp_control_add(struct cs_dsp_coeff_ctl *cs_ctl, ++ const struct hda_cs_dsp_ctl_info *info) + { + struct cs_dsp *cs_dsp = cs_ctl->dsp; + char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; +@@ -145,13 +142,10 @@ int hda_cs_dsp_control_add(struct cs_dsp_coeff_ctl *cs_ctl, struct hda_cs_dsp_ct + const char *region_name; + int ret; + +- if (cs_ctl->flags & WMFW_CTL_FLAG_SYS) +- return 0; +- + region_name = cs_dsp_mem_region_name(cs_ctl->alg_region.type); + if (!region_name) { +- dev_err(cs_dsp->dev, "Unknown region type: %d\n", cs_ctl->alg_region.type); +- return -EINVAL; ++ dev_warn(cs_dsp->dev, "Unknown region type: %d\n", cs_ctl->alg_region.type); ++ return; + } + + ret = scnprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s %s %.12s %x", info->device_name, +@@ -171,22 +165,39 @@ int hda_cs_dsp_control_add(struct cs_dsp_coeff_ctl *cs_ctl, struct hda_cs_dsp_ct + + ctl = kzalloc(sizeof(*ctl), GFP_KERNEL); + if (!ctl) +- return -ENOMEM; ++ return; + + ctl->cs_ctl = cs_ctl; + ctl->card = info->card; + cs_ctl->priv = ctl; + +- ret = hda_cs_dsp_add_kcontrol(ctl, name); +- if (ret) { +- dev_err(cs_dsp->dev, "Error (%d) adding control %s\n", ret, name); +- kfree(ctl); +- return ret; +- } ++ hda_cs_dsp_add_kcontrol(ctl, name); ++} + +- return 0; ++void hda_cs_dsp_add_controls(struct cs_dsp *dsp, const struct hda_cs_dsp_ctl_info *info) ++{ ++ struct cs_dsp_coeff_ctl *cs_ctl; ++ ++ /* ++ * pwr_lock would cause mutex inversion with ALSA control lock compared ++ * to the get/put functions. ++ * It is safe to walk the list without holding a mutex because entries ++ * are persistent and only cs_dsp_power_up() or cs_dsp_remove() can ++ * change the list. ++ */ ++ lockdep_assert_not_held(&dsp->pwr_lock); ++ ++ list_for_each_entry(cs_ctl, &dsp->ctl_list, list) { ++ if (cs_ctl->flags & WMFW_CTL_FLAG_SYS) ++ continue; ++ ++ if (cs_ctl->priv) ++ continue; ++ ++ hda_cs_dsp_control_add(cs_ctl, info); ++ } + } +-EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_control_add, SND_HDA_CS_DSP_CONTROLS); ++EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_add_controls, SND_HDA_CS_DSP_CONTROLS); + + void hda_cs_dsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl) + { +diff --git a/sound/pci/hda/hda_cs_dsp_ctl.h b/sound/pci/hda/hda_cs_dsp_ctl.h +index 4babc69cf2f0..2cf93359c4f2 100644 +--- a/sound/pci/hda/hda_cs_dsp_ctl.h ++++ b/sound/pci/hda/hda_cs_dsp_ctl.h +@@ -29,7 +29,7 @@ struct hda_cs_dsp_ctl_info { + + extern const char * const hda_cs_dsp_fw_ids[HDA_CS_DSP_NUM_FW]; + +-int hda_cs_dsp_control_add(struct cs_dsp_coeff_ctl *cs_ctl, struct hda_cs_dsp_ctl_info *info); ++void hda_cs_dsp_add_controls(struct cs_dsp *dsp, const struct hda_cs_dsp_ctl_info *info); + void hda_cs_dsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl); + int hda_cs_dsp_write_ctl(struct cs_dsp *dsp, const char *name, int type, + unsigned int alg, const void *buf, size_t len); +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-hda_cs_dsp_ctl-Add-Library-to-support-CS_DS.patch b/patches.suse/ALSA-hda-hda_cs_dsp_ctl-Add-Library-to-support-CS_DS.patch new file mode 100644 index 0000000..9ddfa42 --- /dev/null +++ b/patches.suse/ALSA-hda-hda_cs_dsp_ctl-Add-Library-to-support-CS_DS.patch @@ -0,0 +1,307 @@ +From 3233b978af23f11b4ad4f7f11a9a64bd05702b1f Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Thu, 30 Jun 2022 01:23:22 +0100 +Subject: [PATCH] ALSA: hda: hda_cs_dsp_ctl: Add Library to support CS_DSP ALSA controls +Git-commit: 3233b978af23f11b4ad4f7f11a9a64bd05702b1f +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +The cs35l41 part contains a DSP which is able to run firmware. +The cs_dsp library can be used to control the DSP. +These controls can be exposed to userspace using ALSA controls. +This library adds apis to be able to interface between +cs_dsp and hda drivers and expose the relevant controls as +ALSA controls. + +[ Note: the dependency of CONFIG_SND_HDA_CS_DSP_CONTROLS Kconfig is + corrected. Also, this Kconfig isn't enabled now but will be + actually enabled in a later patch -- tiwai ] + +Signed-off-by: Stefan Binding +Signed-off-by: Vitaly Rodionov +Link: https://lore.kernel.org/r/20220630002335.366545-2-vitalyr@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + MAINTAINERS | 1 + sound/pci/hda/Kconfig | 4 + sound/pci/hda/Makefile | 2 + sound/pci/hda/hda_cs_dsp_ctl.c | 193 +++++++++++++++++++++++++++++++++++++++++ + sound/pci/hda/hda_cs_dsp_ctl.h | 33 +++++++ + 5 files changed, 233 insertions(+) + create mode 100644 sound/pci/hda/hda_cs_dsp_ctl.c + create mode 100644 sound/pci/hda/hda_cs_dsp_ctl.h + +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -4441,6 +4441,7 @@ L: patches@opensource.cirrus.com + S: Maintained + F: Documentation/devicetree/bindings/sound/cirrus,cs* + F: sound/pci/hda/cs* ++F: sound/pci/hda/hda_cs_dsp_ctl.* + F: sound/soc/codecs/cs* + + CIRRUS LOGIC DSP FIRMWARE DRIVER +--- a/sound/pci/hda/Kconfig ++++ b/sound/pci/hda/Kconfig +@@ -96,6 +96,10 @@ config SND_HDA_SCODEC_CS35L41 + select SND_HDA_GENERIC + select REGMAP_IRQ + ++config SND_HDA_CS_DSP_CONTROLS ++ tristate ++ select CS_DSP ++ + config SND_HDA_SCODEC_CS35L41_I2C + tristate "Build CS35L41 HD-audio side codec support for I2C Bus" + depends on I2C +--- a/sound/pci/hda/Makefile ++++ b/sound/pci/hda/Makefile +@@ -31,6 +31,7 @@ snd-hda-codec-hdmi-objs := patch_hdmi.o + snd-hda-scodec-cs35l41-objs := cs35l41_hda.o + snd-hda-scodec-cs35l41-i2c-objs := cs35l41_hda_i2c.o + snd-hda-scodec-cs35l41-spi-objs := cs35l41_hda_spi.o ++snd-hda-cs-dsp-ctls-objs := hda_cs_dsp_ctl.o + + # common driver + obj-$(CONFIG_SND_HDA) := snd-hda-codec.o +@@ -54,6 +55,7 @@ obj-$(CONFIG_SND_HDA_CODEC_HDMI) += snd- + obj-$(CONFIG_SND_HDA_SCODEC_CS35L41) += snd-hda-scodec-cs35l41.o + obj-$(CONFIG_SND_HDA_SCODEC_CS35L41_I2C) += snd-hda-scodec-cs35l41-i2c.o + obj-$(CONFIG_SND_HDA_SCODEC_CS35L41_SPI) += snd-hda-scodec-cs35l41-spi.o ++obj-$(CONFIG_SND_HDA_CS_DSP_CONTROLS) += snd-hda-cs-dsp-ctls.o + + # this must be the last entry after codec drivers; + # otherwise the codec patches won't be hooked before the PCI probe +--- /dev/null ++++ b/sound/pci/hda/hda_cs_dsp_ctl.c +@@ -0,0 +1,193 @@ ++// SPDX-License-Identifier: GPL-2.0 ++// ++// HDA DSP ALSA Control Driver ++// ++// Copyright 2022 Cirrus Logic, Inc. ++// ++// Author: Stefan Binding ++ ++#include ++#include ++#include ++#include ++#include "hda_cs_dsp_ctl.h" ++ ++#define ADSP_MAX_STD_CTRL_SIZE 512 ++ ++struct hda_cs_dsp_coeff_ctl { ++ struct cs_dsp_coeff_ctl *cs_ctl; ++ struct snd_card *card; ++ struct snd_kcontrol *kctl; ++}; ++ ++static const char * const hda_cs_dsp_fw_text[HDA_CS_DSP_NUM_FW] = { ++ [HDA_CS_DSP_FW_SPK_PROT] = "Prot", ++ [HDA_CS_DSP_FW_SPK_CALI] = "Cali", ++ [HDA_CS_DSP_FW_SPK_DIAG] = "Diag", ++ [HDA_CS_DSP_FW_MISC] = "Misc", ++}; ++ ++static int hda_cs_dsp_coeff_info(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo) ++{ ++ struct hda_cs_dsp_coeff_ctl *ctl = (struct hda_cs_dsp_coeff_ctl *)snd_kcontrol_chip(kctl); ++ struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl; ++ ++ uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; ++ uinfo->count = cs_ctl->len; ++ ++ return 0; ++} ++ ++static int hda_cs_dsp_coeff_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol) ++{ ++ struct hda_cs_dsp_coeff_ctl *ctl = (struct hda_cs_dsp_coeff_ctl *)snd_kcontrol_chip(kctl); ++ struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl; ++ char *p = ucontrol->value.bytes.data; ++ int ret = 0; ++ ++ mutex_lock(&cs_ctl->dsp->pwr_lock); ++ ret = cs_dsp_coeff_write_ctrl(cs_ctl, 0, p, cs_ctl->len); ++ mutex_unlock(&cs_ctl->dsp->pwr_lock); ++ ++ return ret; ++} ++ ++static int hda_cs_dsp_coeff_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol) ++{ ++ struct hda_cs_dsp_coeff_ctl *ctl = (struct hda_cs_dsp_coeff_ctl *)snd_kcontrol_chip(kctl); ++ struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl; ++ char *p = ucontrol->value.bytes.data; ++ int ret; ++ ++ mutex_lock(&cs_ctl->dsp->pwr_lock); ++ ret = cs_dsp_coeff_read_ctrl(cs_ctl, 0, p, cs_ctl->len); ++ mutex_unlock(&cs_ctl->dsp->pwr_lock); ++ ++ return ret; ++} ++ ++static unsigned int wmfw_convert_flags(unsigned int in) ++{ ++ unsigned int out, rd, wr, vol; ++ ++ rd = SNDRV_CTL_ELEM_ACCESS_READ; ++ wr = SNDRV_CTL_ELEM_ACCESS_WRITE; ++ vol = SNDRV_CTL_ELEM_ACCESS_VOLATILE; ++ ++ out = 0; ++ ++ if (in) { ++ out |= rd; ++ if (in & WMFW_CTL_FLAG_WRITEABLE) ++ out |= wr; ++ if (in & WMFW_CTL_FLAG_VOLATILE) ++ out |= vol; ++ } else { ++ out |= rd | wr | vol; ++ } ++ ++ return out; ++} ++ ++static int hda_cs_dsp_add_kcontrol(struct hda_cs_dsp_coeff_ctl *ctl, const char *name) ++{ ++ struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl; ++ struct snd_kcontrol_new kcontrol = {0}; ++ struct snd_kcontrol *kctl; ++ int ret = 0; ++ ++ if (cs_ctl->len > ADSP_MAX_STD_CTRL_SIZE) { ++ dev_err(cs_ctl->dsp->dev, "KControl %s: length %zu exceeds maximum %d\n", name, ++ cs_ctl->len, ADSP_MAX_STD_CTRL_SIZE); ++ return -EINVAL; ++ } ++ ++ kcontrol.name = name; ++ kcontrol.info = hda_cs_dsp_coeff_info; ++ kcontrol.iface = SNDRV_CTL_ELEM_IFACE_MIXER; ++ kcontrol.access = wmfw_convert_flags(cs_ctl->flags); ++ kcontrol.get = hda_cs_dsp_coeff_get; ++ kcontrol.put = hda_cs_dsp_coeff_put; ++ ++ /* Save ctl inside private_data, ctl is owned by cs_dsp, ++ * and will be freed when cs_dsp removes the control */ ++ kctl = snd_ctl_new1(&kcontrol, (void *)ctl); ++ if (!kctl) { ++ ret = -ENOMEM; ++ return ret; ++ } ++ ++ ret = snd_ctl_add(ctl->card, kctl); ++ if (ret) { ++ dev_err(cs_ctl->dsp->dev, "Failed to add KControl %s = %d\n", kcontrol.name, ret); ++ return ret; ++ } ++ ++ dev_dbg(cs_ctl->dsp->dev, "Added KControl: %s\n", kcontrol.name); ++ ctl->kctl = kctl; ++ ++ return 0; ++} ++ ++int hda_cs_dsp_control_add(struct cs_dsp_coeff_ctl *cs_ctl, struct hda_cs_dsp_ctl_info *info) ++{ ++ struct cs_dsp *cs_dsp = cs_ctl->dsp; ++ char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; ++ struct hda_cs_dsp_coeff_ctl *ctl; ++ const char *region_name; ++ int ret; ++ ++ if (cs_ctl->flags & WMFW_CTL_FLAG_SYS) ++ return 0; ++ ++ region_name = cs_dsp_mem_region_name(cs_ctl->alg_region.type); ++ if (!region_name) { ++ dev_err(cs_dsp->dev, "Unknown region type: %d\n", cs_ctl->alg_region.type); ++ return -EINVAL; ++ } ++ ++ ret = scnprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s %s %.12s %x", info->device_name, ++ cs_dsp->name, hda_cs_dsp_fw_text[info->fw_type], cs_ctl->alg_region.alg); ++ ++ if (cs_ctl->subname) { ++ int avail = SNDRV_CTL_ELEM_ID_NAME_MAXLEN - ret - 2; ++ int skip = 0; ++ ++ /* Truncate the subname from the start if it is too long */ ++ if (cs_ctl->subname_len > avail) ++ skip = cs_ctl->subname_len - avail; ++ ++ snprintf(name + ret, SNDRV_CTL_ELEM_ID_NAME_MAXLEN - ret, ++ " %.*s", cs_ctl->subname_len - skip, cs_ctl->subname + skip); ++ } ++ ++ ctl = kzalloc(sizeof(*ctl), GFP_KERNEL); ++ if (!ctl) ++ return -ENOMEM; ++ ++ ctl->cs_ctl = cs_ctl; ++ ctl->card = info->card; ++ cs_ctl->priv = ctl; ++ ++ ret = hda_cs_dsp_add_kcontrol(ctl, name); ++ if (ret) { ++ dev_err(cs_dsp->dev, "Error (%d) adding control %s\n", ret, name); ++ kfree(ctl); ++ return ret; ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_control_add, SND_HDA_CS_DSP_CONTROLS); ++ ++void hda_cs_dsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl) ++{ ++ struct hda_cs_dsp_coeff_ctl *ctl = cs_ctl->priv; ++ ++ kfree(ctl); ++} ++EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_control_remove, SND_HDA_CS_DSP_CONTROLS); ++ ++MODULE_DESCRIPTION("CS_DSP ALSA Control HDA Library"); ++MODULE_AUTHOR("Stefan Binding, "); ++MODULE_LICENSE("GPL"); +--- /dev/null ++++ b/sound/pci/hda/hda_cs_dsp_ctl.h +@@ -0,0 +1,33 @@ ++/* SPDX-License-Identifier: GPL-2.0 ++ * ++ * HDA DSP ALSA Control Driver ++ * ++ * Copyright 2022 Cirrus Logic, Inc. ++ * ++ * Author: Stefan Binding ++ */ ++ ++#ifndef __HDA_CS_DSP_CTL_H__ ++#define __HDA_CS_DSP_CTL_H__ ++ ++#include ++#include ++ ++enum hda_cs_dsp_fw_id { ++ HDA_CS_DSP_FW_SPK_PROT, ++ HDA_CS_DSP_FW_SPK_CALI, ++ HDA_CS_DSP_FW_SPK_DIAG, ++ HDA_CS_DSP_FW_MISC, ++ HDA_CS_DSP_NUM_FW ++}; ++ ++struct hda_cs_dsp_ctl_info { ++ struct snd_card *card; ++ enum hda_cs_dsp_fw_id fw_type; ++ const char *device_name; ++}; ++ ++int hda_cs_dsp_control_add(struct cs_dsp_coeff_ctl *cs_ctl, struct hda_cs_dsp_ctl_info *info); ++void hda_cs_dsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl); ++ ++#endif /*__HDA_CS_DSP_CTL_H__*/ diff --git a/patches.suse/ALSA-hda-hda_cs_dsp_ctl-Add-apis-to-write-the-contro.patch b/patches.suse/ALSA-hda-hda_cs_dsp_ctl-Add-apis-to-write-the-contro.patch new file mode 100644 index 0000000..26c302f --- /dev/null +++ b/patches.suse/ALSA-hda-hda_cs_dsp_ctl-Add-apis-to-write-the-contro.patch @@ -0,0 +1,91 @@ +From e414b05e724f5fbae6e86d074d7668287a603b24 Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Thu, 30 Jun 2022 01:23:23 +0100 +Subject: [PATCH] ALSA: hda: hda_cs_dsp_ctl: Add apis to write the controls directly +Git-commit: e414b05e724f5fbae6e86d074d7668287a603b24 +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +DSP controls are exposed as ALSA controls, however, +some of these controls are required to be accessed by +the driver. Add apis which allow read/write of these +controls. The write api will also notify the ALSA control +on value change. + +Signed-off-by: Stefan Binding +Signed-off-by: Vitaly Rodionov +Link: https://lore.kernel.org/r/20220630002335.366545-3-vitalyr@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/hda_cs_dsp_ctl.c | 39 ++++++++++++++++++++++++++++++++++ + sound/pci/hda/hda_cs_dsp_ctl.h | 4 ++++ + 2 files changed, 43 insertions(+) + +diff --git a/sound/pci/hda/hda_cs_dsp_ctl.c b/sound/pci/hda/hda_cs_dsp_ctl.c +index 74e2c5bd1b08..2351476c9ee6 100644 +--- a/sound/pci/hda/hda_cs_dsp_ctl.c ++++ b/sound/pci/hda/hda_cs_dsp_ctl.c +@@ -188,6 +188,45 @@ void hda_cs_dsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl) + } + EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_control_remove, SND_HDA_CS_DSP_CONTROLS); + ++int hda_cs_dsp_write_ctl(struct cs_dsp *dsp, const char *name, int type, ++ unsigned int alg, const void *buf, size_t len) ++{ ++ struct cs_dsp_coeff_ctl *cs_ctl; ++ struct hda_cs_dsp_coeff_ctl *ctl; ++ int ret; ++ ++ cs_ctl = cs_dsp_get_ctl(dsp, name, type, alg); ++ if (!cs_ctl) ++ return -EINVAL; ++ ++ ctl = cs_ctl->priv; ++ ++ ret = cs_dsp_coeff_write_ctrl(cs_ctl, 0, buf, len); ++ if (ret) ++ return ret; ++ ++ if (cs_ctl->flags & WMFW_CTL_FLAG_SYS) ++ return 0; ++ ++ snd_ctl_notify(ctl->card, SNDRV_CTL_EVENT_MASK_VALUE, &ctl->kctl->id); ++ ++ return 0; ++} ++EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_write_ctl, SND_HDA_CS_DSP_CONTROLS); ++ ++int hda_cs_dsp_read_ctl(struct cs_dsp *dsp, const char *name, int type, ++ unsigned int alg, void *buf, size_t len) ++{ ++ struct cs_dsp_coeff_ctl *cs_ctl; ++ ++ cs_ctl = cs_dsp_get_ctl(dsp, name, type, alg); ++ if (!cs_ctl) ++ return -EINVAL; ++ ++ return cs_dsp_coeff_read_ctrl(cs_ctl, 0, buf, len); ++} ++EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_read_ctl, SND_HDA_CS_DSP_CONTROLS); ++ + MODULE_DESCRIPTION("CS_DSP ALSA Control HDA Library"); + MODULE_AUTHOR("Stefan Binding, "); + MODULE_LICENSE("GPL"); +diff --git a/sound/pci/hda/hda_cs_dsp_ctl.h b/sound/pci/hda/hda_cs_dsp_ctl.h +index 1c6d0fc9a2cc..c65bfd6878fd 100644 +--- a/sound/pci/hda/hda_cs_dsp_ctl.h ++++ b/sound/pci/hda/hda_cs_dsp_ctl.h +@@ -29,5 +29,9 @@ struct hda_cs_dsp_ctl_info { + + int hda_cs_dsp_control_add(struct cs_dsp_coeff_ctl *cs_ctl, struct hda_cs_dsp_ctl_info *info); + void hda_cs_dsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl); ++int hda_cs_dsp_write_ctl(struct cs_dsp *dsp, const char *name, int type, ++ unsigned int alg, const void *buf, size_t len); ++int hda_cs_dsp_read_ctl(struct cs_dsp *dsp, const char *name, int type, ++ unsigned int alg, void *buf, size_t len); + + #endif /*__HDA_CS_DSP_CTL_H__*/ +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-hda_cs_dsp_ctl-Add-fw-id-strings.patch b/patches.suse/ALSA-hda-hda_cs_dsp_ctl-Add-fw-id-strings.patch new file mode 100644 index 0000000..4faa57c --- /dev/null +++ b/patches.suse/ALSA-hda-hda_cs_dsp_ctl-Add-fw-id-strings.patch @@ -0,0 +1,55 @@ +From 291e7c220b82b28d4c128dfb2abaa51d29969dd5 Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Thu, 30 Jun 2022 01:23:32 +0100 +Subject: [PATCH] ALSA: hda: hda_cs_dsp_ctl: Add fw id strings +Git-commit: 291e7c220b82b28d4c128dfb2abaa51d29969dd5 +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +This will be used to define the firmware names. + +Signed-off-by: Stefan Binding +Signed-off-by: Vitaly Rodionov +Link: https://lore.kernel.org/r/20220630002335.366545-12-vitalyr@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/hda_cs_dsp_ctl.c | 8 ++++++++ + sound/pci/hda/hda_cs_dsp_ctl.h | 2 ++ + 2 files changed, 10 insertions(+) + +diff --git a/sound/pci/hda/hda_cs_dsp_ctl.c b/sound/pci/hda/hda_cs_dsp_ctl.c +index 2351476c9ee6..89ee549cb7d5 100644 +--- a/sound/pci/hda/hda_cs_dsp_ctl.c ++++ b/sound/pci/hda/hda_cs_dsp_ctl.c +@@ -27,6 +27,14 @@ static const char * const hda_cs_dsp_fw_text[HDA_CS_DSP_NUM_FW] = { + [HDA_CS_DSP_FW_MISC] = "Misc", + }; + ++const char * const hda_cs_dsp_fw_ids[HDA_CS_DSP_NUM_FW] = { ++ [HDA_CS_DSP_FW_SPK_PROT] = "spk-prot", ++ [HDA_CS_DSP_FW_SPK_CALI] = "spk-cali", ++ [HDA_CS_DSP_FW_SPK_DIAG] = "spk-diag", ++ [HDA_CS_DSP_FW_MISC] = "misc", ++}; ++EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_fw_ids, SND_HDA_CS_DSP_CONTROLS); ++ + static int hda_cs_dsp_coeff_info(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo) + { + struct hda_cs_dsp_coeff_ctl *ctl = (struct hda_cs_dsp_coeff_ctl *)snd_kcontrol_chip(kctl); +diff --git a/sound/pci/hda/hda_cs_dsp_ctl.h b/sound/pci/hda/hda_cs_dsp_ctl.h +index c65bfd6878fd..4babc69cf2f0 100644 +--- a/sound/pci/hda/hda_cs_dsp_ctl.h ++++ b/sound/pci/hda/hda_cs_dsp_ctl.h +@@ -27,6 +27,8 @@ struct hda_cs_dsp_ctl_info { + const char *device_name; + }; + ++extern const char * const hda_cs_dsp_fw_ids[HDA_CS_DSP_NUM_FW]; ++ + int hda_cs_dsp_control_add(struct cs_dsp_coeff_ctl *cs_ctl, struct hda_cs_dsp_ctl_info *info); + void hda_cs_dsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl); + int hda_cs_dsp_write_ctl(struct cs_dsp *dsp, const char *name, int type, +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-hda_cs_dsp_ctl-Ensure-pwr_lock-is-held-befo.patch b/patches.suse/ALSA-hda-hda_cs_dsp_ctl-Ensure-pwr_lock-is-held-befo.patch new file mode 100644 index 0000000..0da7455 --- /dev/null +++ b/patches.suse/ALSA-hda-hda_cs_dsp_ctl-Ensure-pwr_lock-is-held-befo.patch @@ -0,0 +1,58 @@ +From 06f3a0a758c4246dc644e22fb33f85c6e5f92af6 Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Tue, 11 Oct 2022 15:35:49 +0100 +Subject: [PATCH] ALSA: hda: hda_cs_dsp_ctl: Ensure pwr_lock is held before + reading/writing controls +Git-commit: 06f3a0a758c4246dc644e22fb33f85c6e5f92af6 +Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git +Patch-mainline: Queued in subsystem maintainer repository +References: bsc#1203699 + +These apis require the pwr_lock to be held. + +Signed-off-by: Stefan Binding +Link: https://lore.kernel.org/r/20221011143552.621792-3-sbinding@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/hda_cs_dsp_ctl.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +diff --git a/sound/pci/hda/hda_cs_dsp_ctl.c b/sound/pci/hda/hda_cs_dsp_ctl.c +index 41d3e8fd289d..75fb69185817 100644 +--- a/sound/pci/hda/hda_cs_dsp_ctl.c ++++ b/sound/pci/hda/hda_cs_dsp_ctl.c +@@ -199,11 +199,14 @@ EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_control_remove, SND_HDA_CS_DSP_CONTROLS); + int hda_cs_dsp_write_ctl(struct cs_dsp *dsp, const char *name, int type, + unsigned int alg, const void *buf, size_t len) + { +- struct cs_dsp_coeff_ctl *cs_ctl = cs_dsp_get_ctl(dsp, name, type, alg); ++ struct cs_dsp_coeff_ctl *cs_ctl; + struct hda_cs_dsp_coeff_ctl *ctl; + int ret; + ++ mutex_lock(&dsp->pwr_lock); ++ cs_ctl = cs_dsp_get_ctl(dsp, name, type, alg); + ret = cs_dsp_coeff_write_ctrl(cs_ctl, 0, buf, len); ++ mutex_unlock(&dsp->pwr_lock); + if (ret) + return ret; + +@@ -221,7 +224,13 @@ EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_write_ctl, SND_HDA_CS_DSP_CONTROLS); + int hda_cs_dsp_read_ctl(struct cs_dsp *dsp, const char *name, int type, + unsigned int alg, void *buf, size_t len) + { +- return cs_dsp_coeff_read_ctrl(cs_dsp_get_ctl(dsp, name, type, alg), 0, buf, len); ++ int ret; ++ ++ mutex_lock(&dsp->pwr_lock); ++ ret = cs_dsp_coeff_read_ctrl(cs_dsp_get_ctl(dsp, name, type, alg), 0, buf, len); ++ mutex_unlock(&dsp->pwr_lock); ++ ++ return ret; + + } + EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_read_ctl, SND_HDA_CS_DSP_CONTROLS); +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-hda_cs_dsp_ctl-Minor-clean-and-redundant-co.patch b/patches.suse/ALSA-hda-hda_cs_dsp_ctl-Minor-clean-and-redundant-co.patch new file mode 100644 index 0000000..58da6cb --- /dev/null +++ b/patches.suse/ALSA-hda-hda_cs_dsp_ctl-Minor-clean-and-redundant-co.patch @@ -0,0 +1,73 @@ +From 49b0dea1eb5e0fd5e498a2c2ce50d2e036494072 Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Tue, 11 Oct 2022 15:35:48 +0100 +Subject: [PATCH] ALSA: hda: hda_cs_dsp_ctl: Minor clean and redundant code + removal +Git-commit: 49b0dea1eb5e0fd5e498a2c2ce50d2e036494072 +Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git +Patch-mainline: Queued in subsystem maintainer repository +References: bsc#1203699 + +The cs_dsp core will return an error if passed a NULL cs_dsp struct so +there is no need for the hda_cs_dsp_write|read_ctl functions to manually +check that. The cs_dsp core will also check the data is within bounds of +the control so the additional bounds check is redundant too. Simplify +things a bit by removing said code. + +Signed-off-by: Stefan Binding +Link: https://lore.kernel.org/r/20221011143552.621792-2-sbinding@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/hda_cs_dsp_ctl.c | 17 ++++------------- + 1 file changed, 4 insertions(+), 13 deletions(-) + +diff --git a/sound/pci/hda/hda_cs_dsp_ctl.c b/sound/pci/hda/hda_cs_dsp_ctl.c +index 89ee549cb7d5..41d3e8fd289d 100644 +--- a/sound/pci/hda/hda_cs_dsp_ctl.c ++++ b/sound/pci/hda/hda_cs_dsp_ctl.c +@@ -199,16 +199,10 @@ EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_control_remove, SND_HDA_CS_DSP_CONTROLS); + int hda_cs_dsp_write_ctl(struct cs_dsp *dsp, const char *name, int type, + unsigned int alg, const void *buf, size_t len) + { +- struct cs_dsp_coeff_ctl *cs_ctl; ++ struct cs_dsp_coeff_ctl *cs_ctl = cs_dsp_get_ctl(dsp, name, type, alg); + struct hda_cs_dsp_coeff_ctl *ctl; + int ret; + +- cs_ctl = cs_dsp_get_ctl(dsp, name, type, alg); +- if (!cs_ctl) +- return -EINVAL; +- +- ctl = cs_ctl->priv; +- + ret = cs_dsp_coeff_write_ctrl(cs_ctl, 0, buf, len); + if (ret) + return ret; +@@ -216,6 +210,8 @@ int hda_cs_dsp_write_ctl(struct cs_dsp *dsp, const char *name, int type, + if (cs_ctl->flags & WMFW_CTL_FLAG_SYS) + return 0; + ++ ctl = cs_ctl->priv; ++ + snd_ctl_notify(ctl->card, SNDRV_CTL_EVENT_MASK_VALUE, &ctl->kctl->id); + + return 0; +@@ -225,13 +221,8 @@ EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_write_ctl, SND_HDA_CS_DSP_CONTROLS); + int hda_cs_dsp_read_ctl(struct cs_dsp *dsp, const char *name, int type, + unsigned int alg, void *buf, size_t len) + { +- struct cs_dsp_coeff_ctl *cs_ctl; +- +- cs_ctl = cs_dsp_get_ctl(dsp, name, type, alg); +- if (!cs_ctl) +- return -EINVAL; ++ return cs_dsp_coeff_read_ctrl(cs_dsp_get_ctl(dsp, name, type, alg), 0, buf, len); + +- return cs_dsp_coeff_read_ctrl(cs_ctl, 0, buf, len); + } + EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_read_ctl, SND_HDA_CS_DSP_CONTROLS); + +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-hdmi-Don-t-skip-notification-handling-durin.patch b/patches.suse/ALSA-hda-hdmi-Don-t-skip-notification-handling-durin.patch new file mode 100644 index 0000000..c02018a --- /dev/null +++ b/patches.suse/ALSA-hda-hdmi-Don-t-skip-notification-handling-durin.patch @@ -0,0 +1,62 @@ +From 5226c7b9784eee215e3914f440b3c2e1764f67a8 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Sat, 1 Oct 2022 09:48:10 +0200 +Subject: [PATCH] ALSA: hda/hdmi: Don't skip notification handling during PM operation +Git-commit: 5226c7b9784eee215e3914f440b3c2e1764f67a8 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The HDMI driver skips the notification handling from the graphics +driver when the codec driver is being in the PM operation. This +behavior was introduced by the commit eb399d3c99d8 ("ALSA: hda - Skip +ELD notification during PM process"). This skip may cause a problem, +as we may miss the ELD update when the connection/disconnection +happens right at the runtime-PM operation of the audio codec. + +Although this workaround was valid at that time, it's no longer true; +the fix was required just because the ELD update procedure needed to +wake up the audio codec, which had lead to a runtime-resume during a +runtime-suspend. Meanwhile, the ELD update procedure doesn't need a +codec wake up any longer since the commit 788d441a164c ("ALSA: hda - +Use component ops for i915 HDMI/DP audio jack handling"); i.e. there +is no much reason for skipping the notification. + +Let's drop those checks for addressing the missing notification. + +Fixes: 788d441a164c ("ALSA: hda - Use component ops for i915 HDMI/DP audio jack handling") +Reported-by: Brent Lu +Link: https://lore.kernel.org/r/20220927135807.4097052-1-brent.lu@intel.com +Link: https://lore.kernel.org/r/20221001074809.7461-1-tiwai@suse.de +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_hdmi.c | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c +index c172640c8a41..21edf7a619f0 100644 +--- a/sound/pci/hda/patch_hdmi.c ++++ b/sound/pci/hda/patch_hdmi.c +@@ -2666,9 +2666,6 @@ static void generic_acomp_pin_eld_notify(void *audio_ptr, int port, int dev_id) + */ + if (codec->core.dev.power.power_state.event == PM_EVENT_SUSPEND) + return; +- /* ditto during suspend/resume process itself */ +- if (snd_hdac_is_in_pm(&codec->core)) +- return; + + check_presence_and_report(codec, pin_nid, dev_id); + } +@@ -2852,9 +2849,6 @@ static void intel_pin_eld_notify(void *audio_ptr, int port, int pipe) + */ + if (codec->core.dev.power.power_state.event == PM_EVENT_SUSPEND) + return; +- /* ditto during suspend/resume process itself */ +- if (snd_hdac_is_in_pm(&codec->core)) +- return; + + snd_hdac_i915_set_bclk(&codec->bus->core); + check_presence_and_report(codec, pin_nid, dev_id); +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-hdmi-Fix-the-converter-allocation-for-the-s.patch b/patches.suse/ALSA-hda-hdmi-Fix-the-converter-allocation-for-the-s.patch new file mode 100644 index 0000000..1efbe08 --- /dev/null +++ b/patches.suse/ALSA-hda-hdmi-Fix-the-converter-allocation-for-the-s.patch @@ -0,0 +1,114 @@ +From fc6f923ecfa2fafd0600f1b7e2de09baf29865e2 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Mon, 19 Sep 2022 15:54:44 +0200 +Subject: [PATCH] ALSA: hda/hdmi: Fix the converter allocation for the silent stream +Git-commit: fc6f923ecfa2fafd0600f1b7e2de09baf29865e2 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Track the converters handling the silent stream using a new +variable to avoid mixing of the open/close and silent stream +use. This change ensures the proper allocation of the converters. + +Fixes: 5f80d6bd2b01 ("ALSA: hda/hdmi: Fix the converter reuse for the silent stream") + +Signed-off-by: Jaroslav Kysela +Reviewed-by: Kai Vehmanen +Link: https://lore.kernel.org/r/20220919135444.3554982-1-perex@perex.cz +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_hdmi.c | 20 ++++++++++++-------- + 1 file changed, 12 insertions(+), 8 deletions(-) + +--- a/sound/pci/hda/patch_hdmi.c ++++ b/sound/pci/hda/patch_hdmi.c +@@ -54,6 +54,7 @@ MODULE_PARM_DESC(enable_all_pins, "Forci + struct hdmi_spec_per_cvt { + hda_nid_t cvt_nid; + bool assigned; /* the stream has been assigned */ ++ bool silent_stream; /* silent stream activated */ + unsigned int channels_min; + unsigned int channels_max; + u32 rates; +@@ -982,7 +983,8 @@ static int hdmi_setup_stream(struct hda_ + * of the pin. + */ + static int hdmi_choose_cvt(struct hda_codec *codec, +- int pin_idx, int *cvt_id) ++ int pin_idx, int *cvt_id, ++ bool silent) + { + struct hdmi_spec *spec = codec->spec; + struct hdmi_spec_per_pin *per_pin; +@@ -997,6 +999,9 @@ static int hdmi_choose_cvt(struct hda_co + + if (per_pin && per_pin->silent_stream) { + cvt_idx = cvt_nid_to_cvt_index(codec, per_pin->cvt_nid); ++ per_cvt = get_cvt(spec, cvt_idx); ++ if (per_cvt->assigned && !silent) ++ return -EBUSY; + if (cvt_id) + *cvt_id = cvt_idx; + return 0; +@@ -1007,7 +1012,7 @@ static int hdmi_choose_cvt(struct hda_co + per_cvt = get_cvt(spec, cvt_idx); + + /* Must not already be assigned */ +- if (per_cvt->assigned) ++ if (per_cvt->assigned || per_cvt->silent_stream) + continue; + if (per_pin == NULL) + break; +@@ -1193,7 +1198,7 @@ static int hdmi_pcm_open_no_pin(struct h + if (pcm_idx < 0) + return -EINVAL; + +- err = hdmi_choose_cvt(codec, -1, &cvt_idx); ++ err = hdmi_choose_cvt(codec, -1, &cvt_idx, false); + if (err) + return err; + +@@ -1261,7 +1266,7 @@ static int hdmi_pcm_open(struct hda_pcm_ + } + } + +- err = hdmi_choose_cvt(codec, pin_idx, &cvt_idx); ++ err = hdmi_choose_cvt(codec, pin_idx, &cvt_idx, false); + if (err < 0) + goto unlock; + +@@ -1272,7 +1277,6 @@ static int hdmi_pcm_open(struct hda_pcm_ + set_bit(pcm_idx, &spec->pcm_in_use); + per_pin = get_pin(spec, pin_idx); + per_pin->cvt_nid = per_cvt->cvt_nid; +- per_pin->silent_stream = false; + hinfo->nid = per_cvt->cvt_nid; + + /* flip stripe flag for the assigned stream if supported */ +@@ -1701,14 +1705,14 @@ static void silent_stream_enable(struct + } + + pin_idx = pin_id_to_pin_index(codec, per_pin->pin_nid, per_pin->dev_id); +- err = hdmi_choose_cvt(codec, pin_idx, &cvt_idx); ++ err = hdmi_choose_cvt(codec, pin_idx, &cvt_idx, true); + if (err) { + codec_err(codec, "hdmi: no free converter to enable silent mode\n"); + goto unlock_out; + } + + per_cvt = get_cvt(spec, cvt_idx); +- per_cvt->assigned = true; ++ per_cvt->silent_stream = true; + per_pin->cvt_nid = per_cvt->cvt_nid; + per_pin->silent_stream = true; + +@@ -1758,7 +1762,7 @@ static void silent_stream_disable(struct + cvt_idx = cvt_nid_to_cvt_index(codec, per_pin->cvt_nid); + if (cvt_idx >= 0 && cvt_idx < spec->num_cvts) { + per_cvt = get_cvt(spec, cvt_idx); +- per_cvt->assigned = false; ++ per_cvt->silent_stream = false; + } + + per_pin->cvt_nid = 0; diff --git a/patches.suse/ALSA-hda-hdmi-Fix-the-converter-reuse-for-the-silent.patch b/patches.suse/ALSA-hda-hdmi-Fix-the-converter-reuse-for-the-silent.patch new file mode 100644 index 0000000..9940ba8 --- /dev/null +++ b/patches.suse/ALSA-hda-hdmi-Fix-the-converter-reuse-for-the-silent.patch @@ -0,0 +1,41 @@ +From 5f80d6bd2b01de4cafac3302f58456bf860322fc Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Tue, 13 Sep 2022 09:02:16 +0200 +Subject: [PATCH] ALSA: hda/hdmi: Fix the converter reuse for the silent stream +Git-commit: 5f80d6bd2b01de4cafac3302f58456bf860322fc +Patch-mainline: v6.0-rc7 +References: git-fixes + +When the user space pcm stream uses the silent stream converter, +it is no longer allocated for the silent stream. Clear the appropriate +flag in the hdmi_pcm_open() function. The silent stream setup may +be applied in hdmi_pcm_close() (and the error path - open fcn) again. + +If the flag is not cleared, the reuse conditions for the silent +stream converter in hdmi_choose_cvt() may improperly share +this converter. + +Cc: Kai Vehmanen +Signed-off-by: Jaroslav Kysela +Link: https://lore.kernel.org/r/20220913070216.3233974-1-perex@perex.cz +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_hdmi.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c +index c9d9aa6351ec..c239d9dbbaef 100644 +--- a/sound/pci/hda/patch_hdmi.c ++++ b/sound/pci/hda/patch_hdmi.c +@@ -1278,6 +1278,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, + set_bit(pcm_idx, &spec->pcm_in_use); + per_pin = get_pin(spec, pin_idx); + per_pin->cvt_nid = per_cvt->cvt_nid; ++ per_pin->silent_stream = false; + hinfo->nid = per_cvt->cvt_nid; + + /* flip stripe flag for the assigned stream if supported */ +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-hdmi-change-type-for-the-assigned-variable.patch b/patches.suse/ALSA-hda-hdmi-change-type-for-the-assigned-variable.patch new file mode 100644 index 0000000..a17e67b --- /dev/null +++ b/patches.suse/ALSA-hda-hdmi-change-type-for-the-assigned-variable.patch @@ -0,0 +1,85 @@ +From 4053a41282f8aae290d3fe7b8daef4c8c53a4ab8 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Tue, 13 Sep 2022 09:03:07 +0200 +Subject: [PATCH] ALSA: hda/hdmi: change type for the 'assigned' variable +Git-commit: 4053a41282f8aae290d3fe7b8daef4c8c53a4ab8 +Patch-mainline: v6.1-rc1 +References: git-fixes + +This change converts the assigned value from int type to +the bool type to retain consistency with other structure +members like 'setup', 'non_pcm' etc. + +Signed-off-by: Jaroslav Kysela +Link: https://lore.kernel.org/r/20220913070307.3234038-1-perex@perex.cz +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_hdmi.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +--- a/sound/pci/hda/patch_hdmi.c ++++ b/sound/pci/hda/patch_hdmi.c +@@ -53,7 +53,7 @@ MODULE_PARM_DESC(enable_all_pins, "Forci + + struct hdmi_spec_per_cvt { + hda_nid_t cvt_nid; +- int assigned; ++ bool assigned; /* the stream has been assigned */ + unsigned int channels_min; + unsigned int channels_max; + u32 rates; +@@ -1198,7 +1198,7 @@ static int hdmi_pcm_open_no_pin(struct h + return err; + + per_cvt = get_cvt(spec, cvt_idx); +- per_cvt->assigned = 1; ++ per_cvt->assigned = true; + hinfo->nid = per_cvt->cvt_nid; + + pin_cvt_fixup(codec, NULL, per_cvt->cvt_nid); +@@ -1267,7 +1267,7 @@ static int hdmi_pcm_open(struct hda_pcm_ + + per_cvt = get_cvt(spec, cvt_idx); + /* Claim converter */ +- per_cvt->assigned = 1; ++ per_cvt->assigned = true; + + set_bit(pcm_idx, &spec->pcm_in_use); + per_pin = get_pin(spec, pin_idx); +@@ -1302,7 +1302,7 @@ static int hdmi_pcm_open(struct hda_pcm_ + snd_hdmi_eld_update_pcm_info(&eld->info, hinfo); + if (hinfo->channels_min > hinfo->channels_max || + !hinfo->rates || !hinfo->formats) { +- per_cvt->assigned = 0; ++ per_cvt->assigned = false; + hinfo->nid = 0; + snd_hda_spdif_ctls_unassign(codec, pcm_idx); + err = -ENODEV; +@@ -1708,7 +1708,7 @@ static void silent_stream_enable(struct + } + + per_cvt = get_cvt(spec, cvt_idx); +- per_cvt->assigned = 1; ++ per_cvt->assigned = true; + per_pin->cvt_nid = per_cvt->cvt_nid; + per_pin->silent_stream = true; + +@@ -1758,7 +1758,7 @@ static void silent_stream_disable(struct + cvt_idx = cvt_nid_to_cvt_index(codec, per_pin->cvt_nid); + if (cvt_idx >= 0 && cvt_idx < spec->num_cvts) { + per_cvt = get_cvt(spec, cvt_idx); +- per_cvt->assigned = 0; ++ per_cvt->assigned = false; + } + + per_pin->cvt_nid = 0; +@@ -2163,7 +2163,7 @@ static int hdmi_pcm_close(struct hda_pcm + goto unlock; + } + per_cvt = get_cvt(spec, cvt_idx); +- per_cvt->assigned = 0; ++ per_cvt->assigned = false; + hinfo->nid = 0; + + azx_stream(get_azx_dev(substream))->stripe = 0; diff --git a/patches.suse/ALSA-hda-realtek-Add-CS35L41-support-for-Thinkpad-la.patch b/patches.suse/ALSA-hda-realtek-Add-CS35L41-support-for-Thinkpad-la.patch new file mode 100644 index 0000000..8d43f7e --- /dev/null +++ b/patches.suse/ALSA-hda-realtek-Add-CS35L41-support-for-Thinkpad-la.patch @@ -0,0 +1,96 @@ +From ae7abe36e352eddf8e30d3b1ea3fb402514ba13b Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Fri, 17 Dec 2021 11:57:08 +0000 +Subject: [PATCH] ALSA: hda/realtek: Add CS35L41 support for Thinkpad laptops +Git-commit: ae7abe36e352eddf8e30d3b1ea3fb402514ba13b +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +Add support for two CS35L41 using I2C bus and the component +binding method + +[ Fix the entries to be sorted order by tiwai ] + +Signed-off-by: Stefan Binding +Signed-off-by: Lucas Tanure +Link: https://lore.kernel.org/r/20211217115708.882525-11-tanureal@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_realtek.c | 39 +++++++++++++++++++++++++++++++++++ + 1 file changed, 39 insertions(+) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 395483b9753b..2e20bbfe5357 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -6580,6 +6580,37 @@ static void comp_generic_playback_hook(struct hda_pcm_stream *hinfo, struct hda_ + } + } + ++static void cs35l41_generic_fixup(struct hda_codec *cdc, int action, const char *bus, ++ const char *hid, int count) ++{ ++ struct device *dev = hda_codec_dev(cdc); ++ struct alc_spec *spec = cdc->spec; ++ char *name; ++ int ret, i; ++ ++ switch (action) { ++ case HDA_FIXUP_ACT_PRE_PROBE: ++ for (i = 0; i < count; i++) { ++ name = devm_kasprintf(dev, GFP_KERNEL, ++ "%s-%s:00-cs35l41-hda.%d", bus, hid, i); ++ if (!name) ++ return; ++ component_match_add(dev, &spec->match, comp_match_dev_name, name); ++ } ++ ret = component_master_add_with_match(dev, &comp_master_ops, spec->match); ++ if (ret) ++ codec_err(cdc, "Fail to register component aggregator %d\n", ret); ++ else ++ spec->gen.pcm_playback_hook = comp_generic_playback_hook; ++ break; ++ } ++} ++ ++static void cs35l41_fixup_i2c_two(struct hda_codec *cdc, const struct hda_fixup *fix, int action) ++{ ++ cs35l41_generic_fixup(cdc, action, "i2c", "CSC3551", 2); ++} ++ + static void alc287_legion_16achg6_playback_hook(struct hda_pcm_stream *hinfo, struct hda_codec *cdc, + struct snd_pcm_substream *sub, int action) + { +@@ -6916,6 +6947,7 @@ enum { + ALC285_FIXUP_LEGION_Y9000X_SPEAKERS, + ALC285_FIXUP_LEGION_Y9000X_AUTOMUTE, + ALC287_FIXUP_LEGION_16ACHG6, ++ ALC287_FIXUP_CS35L41_I2C_2, + }; + + static const struct hda_fixup alc269_fixups[] = { +@@ -8662,6 +8694,10 @@ static const struct hda_fixup alc269_fixups[] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc287_fixup_legion_16achg6_speakers, + }, ++ [ALC287_FIXUP_CS35L41_I2C_2] = { ++ .type = HDA_FIXUP_FUNC, ++ .v.func = cs35l41_fixup_i2c_two, ++ }, + }; + + static const struct snd_pci_quirk alc269_fixup_tbl[] = { +@@ -9059,6 +9095,9 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x22be, "Thinkpad X1 Carbon 8th", ALC285_FIXUP_THINKPAD_HEADSET_JACK), + SND_PCI_QUIRK(0x17aa, 0x22c1, "Thinkpad P1 Gen 3", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK), + SND_PCI_QUIRK(0x17aa, 0x22c2, "Thinkpad X1 Extreme Gen 3", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK), ++ SND_PCI_QUIRK(0x17aa, 0x22f1, "Thinkpad", ALC287_FIXUP_CS35L41_I2C_2), ++ SND_PCI_QUIRK(0x17aa, 0x22f2, "Thinkpad", ALC287_FIXUP_CS35L41_I2C_2), ++ SND_PCI_QUIRK(0x17aa, 0x22f3, "Thinkpad", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), + SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), + SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION), +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-realtek-Add-Intel-Reference-SSID-to-support.patch b/patches.suse/ALSA-hda-realtek-Add-Intel-Reference-SSID-to-support.patch new file mode 100644 index 0000000..867f34b --- /dev/null +++ b/patches.suse/ALSA-hda-realtek-Add-Intel-Reference-SSID-to-support.patch @@ -0,0 +1,38 @@ +From 4f2e56a59b9947b3e698d3cabcb858765c12b1e8 Mon Sep 17 00:00:00 2001 +From: Saranya Gopal +Date: Tue, 11 Oct 2022 10:19:16 +0530 +Subject: [PATCH] ALSA: hda/realtek: Add Intel Reference SSID to support headset keys +Git-commit: 4f2e56a59b9947b3e698d3cabcb858765c12b1e8 +Patch-mainline: v6.1-rc1 +References: git-fixes + +This patch fixes the issue with 3.5mm headset keys +on RPL-P platform. + +[ Rearranged the entry in SSID order by tiwai ] + +Signed-off-by: Saranya Gopal +Signed-off-by: Ninad Naik +Cc: +Link: https://lore.kernel.org/r/20221011044916.2278867-1-saranya.gopal@intel.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_realtek.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 54a0f6b4ffc7..4b076912bbf4 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -9445,6 +9445,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x10ec, 0x10f2, "Intel Reference board", ALC700_FIXUP_INTEL_REFERENCE), + SND_PCI_QUIRK(0x10ec, 0x118c, "Medion EE4254 MD62100", ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE), + SND_PCI_QUIRK(0x10ec, 0x1230, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK), ++ SND_PCI_QUIRK(0x10ec, 0x124c, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK), + SND_PCI_QUIRK(0x10ec, 0x1252, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK), + SND_PCI_QUIRK(0x10ec, 0x1254, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK), + SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-SZ6", ALC269_FIXUP_HEADSET_MODE), +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-realtek-Add-a-quirk-for-HP-OMEN-16-8902-mut.patch b/patches.suse/ALSA-hda-realtek-Add-a-quirk-for-HP-OMEN-16-8902-mut.patch new file mode 100644 index 0000000..b599e1b --- /dev/null +++ b/patches.suse/ALSA-hda-realtek-Add-a-quirk-for-HP-OMEN-16-8902-mut.patch @@ -0,0 +1,32 @@ +From 496322302bf1e58dc2ff134173527493105f51ab Mon Sep 17 00:00:00 2001 +From: Daniel Houldsworth +Date: Sun, 18 Sep 2022 18:13:00 +0100 +Subject: [PATCH] ALSA: hda/realtek: Add a quirk for HP OMEN 16 (8902) mute LED +Git-commit: 496322302bf1e58dc2ff134173527493105f51ab +Patch-mainline: v6.0-rc7 +References: git-fixes + +Similair to the HP OMEN 15, the HP OMEN 16 also needs +ALC285_FIXUP_HP_MUTE_LED for the mute LED to work. + +[ Rearranged the entry in PCI SSID order by tiwai ] + +Signed-off-by: Daniel Houldsworth +Cc: +Link: https://lore.kernel.org/r/20220918171300.24693-1-dhould3@gmail.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_realtek.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -9284,6 +9284,7 @@ static const struct snd_pci_quirk alc269 + SND_PCI_QUIRK(0x103c, 0x8896, "HP EliteBook 855 G8 Notebook PC", ALC285_FIXUP_HP_MUTE_LED), + SND_PCI_QUIRK(0x103c, 0x8898, "HP EliteBook 845 G8 Notebook PC", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST), + SND_PCI_QUIRK(0x103c, 0x88d0, "HP Pavilion 15-eh1xxx (mainboard 88D0)", ALC287_FIXUP_HP_GPIO_LED), ++ SND_PCI_QUIRK(0x103c, 0x8902, "HP OMEN 16", ALC285_FIXUP_HP_MUTE_LED), + SND_PCI_QUIRK(0x103c, 0x896e, "HP EliteBook x360 830 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8971, "HP EliteBook 830 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8972, "HP EliteBook 840 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), diff --git a/patches.suse/ALSA-hda-realtek-Add-mute-and-micmut-LED-support-for.patch b/patches.suse/ALSA-hda-realtek-Add-mute-and-micmut-LED-support-for.patch new file mode 100644 index 0000000..50d4bde --- /dev/null +++ b/patches.suse/ALSA-hda-realtek-Add-mute-and-micmut-LED-support-for.patch @@ -0,0 +1,59 @@ +From ce18f905a500879e86ca998963a55f99d413a462 Mon Sep 17 00:00:00 2001 +From: Kai-Heng Feng +Date: Thu, 24 Mar 2022 14:21:58 +0800 +Subject: [PATCH] ALSA: hda/realtek: Add mute and micmut LED support for Zbook Fury 17 G9 +Git-commit: ce18f905a500879e86ca998963a55f99d413a462 +Patch-mainline: v5.18-rc1 +References: bsc#1203699 + +Zbook Fury 17 G9 requires the same ALC285_FIXUP_HP_GPIO_LED quirk to +make its audio LEDs work. + +So apply the quirk, and make it the last one since it's an LED quirk. + +Fixes: 07bcab93946c ("ALSA: hda/realtek: Add support for HP Laptops") +Signed-off-by: Kai-Heng Feng +Link: https://lore.kernel.org/r/20220324062159.241313-1-kai.heng.feng@canonical.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_realtek.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index f6ee67f41c45..e88fbef57c40 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -7011,6 +7011,7 @@ enum { + ALC287_FIXUP_LEGION_16ACHG6, + ALC287_FIXUP_CS35L41_I2C_2, + ALC245_FIXUP_CS35L41_SPI_2, ++ ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED, + ALC245_FIXUP_CS35L41_SPI_4, + ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED, + ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED, +@@ -8776,6 +8777,12 @@ static const struct hda_fixup alc269_fixups[] = { + .type = HDA_FIXUP_FUNC, + .v.func = cs35l41_fixup_spi_two, + }, ++ [ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED] = { ++ .type = HDA_FIXUP_FUNC, ++ .v.func = cs35l41_fixup_spi_two, ++ .chained = true, ++ .chain_id = ALC285_FIXUP_HP_GPIO_LED, ++ }, + [ALC245_FIXUP_CS35L41_SPI_4] = { + .type = HDA_FIXUP_FUNC, + .v.func = cs35l41_fixup_spi_four, +@@ -9031,7 +9038,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x89ac, "HP EliteBook 640 G9", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x89ae, "HP EliteBook 650 G9", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x89c3, "Zbook Studio G9", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED), +- SND_PCI_QUIRK(0x103c, 0x89c6, "Zbook Fury 17 G9", ALC245_FIXUP_CS35L41_SPI_2), ++ SND_PCI_QUIRK(0x103c, 0x89c6, "Zbook Fury 17 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x89ca, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), + SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), + SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-realtek-Add-pincfg-for-ASUS-G513-HP-jack.patch b/patches.suse/ALSA-hda-realtek-Add-pincfg-for-ASUS-G513-HP-jack.patch new file mode 100644 index 0000000..93ec6bd --- /dev/null +++ b/patches.suse/ALSA-hda-realtek-Add-pincfg-for-ASUS-G513-HP-jack.patch @@ -0,0 +1,60 @@ +From c611e659044168e7abcbae8ba1ea833521498fbb Mon Sep 17 00:00:00 2001 +From: "Luke D. Jones" +Date: Thu, 15 Sep 2022 20:09:19 +1200 +Subject: [PATCH] ALSA: hda/realtek: Add pincfg for ASUS G513 HP jack +Git-commit: c611e659044168e7abcbae8ba1ea833521498fbb +Patch-mainline: v6.0-rc7 +References: git-fixes + +Fixes up the pincfg for ASUS ROG Strix G513 headphone and mic combo jack + +[ Fixed the position in the quirk table by tiwai ] + +Signed-off-by: Luke D. Jones +Cc: +Link: https://lore.kernel.org/r/20220915080921.35563-2-luke@ljones.dev +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_realtek.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 90fde53e6956..5ab20059e4dd 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -7067,6 +7067,7 @@ enum { + ALC294_FIXUP_ASUS_GU502_HP, + ALC294_FIXUP_ASUS_GU502_PINS, + ALC294_FIXUP_ASUS_GU502_VERBS, ++ ALC294_FIXUP_ASUS_G513_PINS, + ALC285_FIXUP_HP_GPIO_LED, + ALC285_FIXUP_HP_MUTE_LED, + ALC236_FIXUP_HP_GPIO_LED, +@@ -8405,6 +8406,15 @@ static const struct hda_fixup alc269_fixups[] = { + [ALC294_FIXUP_ASUS_GU502_HP] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc294_fixup_gu502_hp, ++ }, ++ [ALC294_FIXUP_ASUS_G513_PINS] = { ++ .type = HDA_FIXUP_PINS, ++ .v.pins = (const struct hda_pintbl[]) { ++ { 0x19, 0x03a11050 }, /* front HP mic */ ++ { 0x1a, 0x03a11c30 }, /* rear external mic */ ++ { 0x21, 0x03211420 }, /* front HP out */ ++ { } ++ }, + }, + [ALC294_FIXUP_ASUS_COEF_1B] = { + .type = HDA_FIXUP_VERBS, +@@ -9366,6 +9376,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE), + SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502), + SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS), ++ SND_PCI_QUIRK(0x1043, 0x1e5e, "ASUS ROG Strix G513", ALC294_FIXUP_ASUS_G513_PINS), + SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401), + SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401), + SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2), +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-realtek-Add-pincfg-for-ASUS-G533Z-HP-jack.patch b/patches.suse/ALSA-hda-realtek-Add-pincfg-for-ASUS-G533Z-HP-jack.patch new file mode 100644 index 0000000..731e8ea --- /dev/null +++ b/patches.suse/ALSA-hda-realtek-Add-pincfg-for-ASUS-G533Z-HP-jack.patch @@ -0,0 +1,60 @@ +From bc2c23549ccd7105eb6ff0d4f0ac519285628673 Mon Sep 17 00:00:00 2001 +From: "Luke D. Jones" +Date: Thu, 15 Sep 2022 20:09:20 +1200 +Subject: [PATCH] ALSA: hda/realtek: Add pincfg for ASUS G533Z HP jack +Git-commit: bc2c23549ccd7105eb6ff0d4f0ac519285628673 +Patch-mainline: v6.0-rc7 +References: git-fixes + +Fixes up the pincfg for ASUS ROG Strix G15 (G533Z) headphone combo jack + +[ Fixed the position in the quirk table by tiwai ] + +Signed-off-by: Luke D. Jones +Cc: +Link: https://lore.kernel.org/r/20220915080921.35563-3-luke@ljones.dev +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_realtek.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 5ab20059e4dd..de8c29d65362 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -7068,6 +7068,7 @@ enum { + ALC294_FIXUP_ASUS_GU502_PINS, + ALC294_FIXUP_ASUS_GU502_VERBS, + ALC294_FIXUP_ASUS_G513_PINS, ++ ALC285_FIXUP_ASUS_G533Z_PINS, + ALC285_FIXUP_HP_GPIO_LED, + ALC285_FIXUP_HP_MUTE_LED, + ALC236_FIXUP_HP_GPIO_LED, +@@ -8416,6 +8417,15 @@ static const struct hda_fixup alc269_fixups[] = { + { } + }, + }, ++ [ALC285_FIXUP_ASUS_G533Z_PINS] = { ++ .type = HDA_FIXUP_PINS, ++ .v.pins = (const struct hda_pintbl[]) { ++ { 0x14, 0x90170120 }, ++ { } ++ }, ++ .chained = true, ++ .chain_id = ALC294_FIXUP_ASUS_G513_PINS, ++ }, + [ALC294_FIXUP_ASUS_COEF_1B] = { + .type = HDA_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { +@@ -9371,6 +9381,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC), + SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), ++ SND_PCI_QUIRK(0x1043, 0x1c92, "ASUS ROG Strix G15", ALC285_FIXUP_ASUS_G533Z_PINS), + SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC), + SND_PCI_QUIRK(0x1043, 0x1d42, "ASUS Zephyrus G14 2022", ALC289_FIXUP_ASUS_GA401), + SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE), +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-realtek-Add-quirk-for-ASUS-GA503R-laptop.patch b/patches.suse/ALSA-hda-realtek-Add-quirk-for-ASUS-GA503R-laptop.patch new file mode 100644 index 0000000..91a92a3 --- /dev/null +++ b/patches.suse/ALSA-hda-realtek-Add-quirk-for-ASUS-GA503R-laptop.patch @@ -0,0 +1,38 @@ +From ba1f818053b0668a1ce2fe86b840e81b592cc560 Mon Sep 17 00:00:00 2001 +From: "Luke D. Jones" +Date: Thu, 15 Sep 2022 20:09:21 +1200 +Subject: [PATCH] ALSA: hda/realtek: Add quirk for ASUS GA503R laptop +Git-commit: ba1f818053b0668a1ce2fe86b840e81b592cc560 +Patch-mainline: v6.0-rc7 +References: git-fixes + +The ASUS G15 2022 (GA503R) series laptop has the same node-to-DAC pairs +as early models and the G14, this includes bass speakers which are by +default mapped incorrectly to the 0x06 node. + +Add a quirk to use the same DAC pairs as the G14. + +Signed-off-by: Luke D. Jones +Cc: +Link: https://lore.kernel.org/r/20220915080921.35563-4-luke@ljones.dev +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_realtek.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index de8c29d65362..ab0ee0565706 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -9389,6 +9389,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS), + SND_PCI_QUIRK(0x1043, 0x1e5e, "ASUS ROG Strix G513", ALC294_FIXUP_ASUS_G513_PINS), + SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401), ++ SND_PCI_QUIRK(0x1043, 0x1c52, "ASUS Zephyrus G15 2022", ALC289_FIXUP_ASUS_GA401), + SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401), + SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2), + SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-realtek-Add-quirk-for-ASUS-GV601R-laptop.patch b/patches.suse/ALSA-hda-realtek-Add-quirk-for-ASUS-GV601R-laptop.patch new file mode 100644 index 0000000..94bf8b7 --- /dev/null +++ b/patches.suse/ALSA-hda-realtek-Add-quirk-for-ASUS-GV601R-laptop.patch @@ -0,0 +1,38 @@ +From 2ea8e1297801f7b0220ebf6ae61a5b74ca83981e Mon Sep 17 00:00:00 2001 +From: "Luke D. Jones" +Date: Mon, 10 Oct 2022 20:03:47 +1300 +Subject: [PATCH] ALSA: hda/realtek: Add quirk for ASUS GV601R laptop +Git-commit: 2ea8e1297801f7b0220ebf6ae61a5b74ca83981e +Patch-mainline: v6.1-rc1 +References: git-fixes + +The ASUS ROG X16 (GV601R) series laptop has the same node-to-DAC pairs +as early models and the G14, this includes bass speakers which are by +default mapped incorrectly to the 0x06 node. + +Add a quirk to use the same DAC pairs as the G14. + +Signed-off-by: Luke D. Jones +Cc: +Link: https://lore.kernel.org/r/20221010070347.36883-1-luke@ljones.dev +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_realtek.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 77a308a71cd4..54a0f6b4ffc7 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -9423,6 +9423,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401), + SND_PCI_QUIRK(0x1043, 0x1c52, "ASUS Zephyrus G15 2022", ALC289_FIXUP_ASUS_GA401), + SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401), ++ SND_PCI_QUIRK(0x1043, 0x1f92, "ASUS ROG Flow X16", ALC289_FIXUP_ASUS_GA401), + SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2), + SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), + SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC), +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-realtek-Add-quirk-for-HP-Dev-One.patch b/patches.suse/ALSA-hda-realtek-Add-quirk-for-HP-Dev-One.patch index 098f94a..1533878 100644 --- a/patches.suse/ALSA-hda-realtek-Add-quirk-for-HP-Dev-One.patch +++ b/patches.suse/ALSA-hda-realtek-Add-quirk-for-HP-Dev-One.patch @@ -21,9 +21,9 @@ Signed-off-by: Takashi Iwai --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c -@@ -8917,6 +8917,7 @@ static const struct snd_pci_quirk alc269 - SND_PCI_QUIRK(0x103c, 0x89ae, "HP EliteBook 650 G9", ALC236_FIXUP_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x89c3, "HP", ALC285_FIXUP_HP_GPIO_LED), +@@ -9119,6 +9119,7 @@ static const struct snd_pci_quirk alc269 + SND_PCI_QUIRK(0x103c, 0x89c3, "Zbook Studio G9", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x89c6, "Zbook Fury 17 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x89ca, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), + SND_PCI_QUIRK(0x103c, 0x8a78, "HP Dev One", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST), SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), diff --git a/patches.suse/ALSA-hda-realtek-Add-quirk-for-HP-Zbook-Firefly-14-G.patch b/patches.suse/ALSA-hda-realtek-Add-quirk-for-HP-Zbook-Firefly-14-G.patch new file mode 100644 index 0000000..ae80fd7 --- /dev/null +++ b/patches.suse/ALSA-hda-realtek-Add-quirk-for-HP-Zbook-Firefly-14-G.patch @@ -0,0 +1,73 @@ +From 225f6e1bc151978041595c7d2acaded3aac41f54 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Thu, 29 Sep 2022 08:14:55 +0200 +Subject: [PATCH] ALSA: hda/realtek: Add quirk for HP Zbook Firefly 14 G9 model +References: bsc#1203699 +Git-commit: 225f6e1bc151978041595c7d2acaded3aac41f54 +Patch-mainline: v6.1-rc1 + +HP Zbook Firefly 14 G9 model (103c:8abb) requires yet another binding +with CS35L41 codec, but with a slightly different configuration. It's +over spi1 instead of spi0. Create a new fixup entry for that. + +Cc: +Link: https://lore.kernel.org/r/20220929061455.13355-1-tiwai@suse.de +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_realtek.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index f9d46ae4c7b7..3dc19174670e 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -6741,6 +6741,11 @@ static void cs35l41_fixup_spi_two(struct hda_codec *codec, const struct hda_fixu + cs35l41_generic_fixup(codec, action, "spi0", "CSC3551", 2); + } + ++static void cs35l41_fixup_spi1_two(struct hda_codec *codec, const struct hda_fixup *fix, int action) ++{ ++ cs35l41_generic_fixup(codec, action, "spi1", "CSC3551", 2); ++} ++ + static void cs35l41_fixup_spi_four(struct hda_codec *codec, const struct hda_fixup *fix, int action) + { + cs35l41_generic_fixup(codec, action, "spi0", "CSC3551", 4); +@@ -7132,6 +7137,8 @@ enum { + ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED, + ALC245_FIXUP_CS35L41_SPI_2, + ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED, ++ ALC245_FIXUP_CS35L41_SPI1_2, ++ ALC245_FIXUP_CS35L41_SPI1_2_HP_GPIO_LED, + ALC245_FIXUP_CS35L41_SPI_4, + ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED, + ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED, +@@ -8979,6 +8986,16 @@ static const struct hda_fixup alc269_fixups[] = { + .chained = true, + .chain_id = ALC285_FIXUP_HP_GPIO_LED, + }, ++ [ALC245_FIXUP_CS35L41_SPI1_2] = { ++ .type = HDA_FIXUP_FUNC, ++ .v.func = cs35l41_fixup_spi1_two, ++ }, ++ [ALC245_FIXUP_CS35L41_SPI1_2_HP_GPIO_LED] = { ++ .type = HDA_FIXUP_FUNC, ++ .v.func = cs35l41_fixup_spi1_two, ++ .chained = true, ++ .chain_id = ALC285_FIXUP_HP_GPIO_LED, ++ }, + [ALC245_FIXUP_CS35L41_SPI_4] = { + .type = HDA_FIXUP_FUNC, + .v.func = cs35l41_fixup_spi_four, +@@ -9341,6 +9358,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x8aa3, "HP ProBook 450 G9 (MB 8AA1)", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8aa8, "HP EliteBook 640 G9 (MB 8AA6)", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8aab, "HP EliteBook 650 G9 (MB 8AA9)", ALC236_FIXUP_HP_GPIO_LED), ++ SND_PCI_QUIRK(0x103c, 0x8abb, "HP ZBook Firefly 14 G9", ALC245_FIXUP_CS35L41_SPI1_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8ad1, "HP EliteBook 840 14 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8ad2, "HP EliteBook 860 16 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-realtek-Add-quirk-for-Huawei-WRT-WX9.patch b/patches.suse/ALSA-hda-realtek-Add-quirk-for-Huawei-WRT-WX9.patch new file mode 100644 index 0000000..c49491f --- /dev/null +++ b/patches.suse/ALSA-hda-realtek-Add-quirk-for-Huawei-WRT-WX9.patch @@ -0,0 +1,34 @@ +From cbcdf8c4d35cd74aee8581eb2f0453e0ecab7b05 Mon Sep 17 00:00:00 2001 +From: huangwenhui +Date: Tue, 13 Sep 2022 13:46:22 +0800 +Subject: [PATCH] ALSA: hda/realtek: Add quirk for Huawei WRT-WX9 +Git-commit: cbcdf8c4d35cd74aee8581eb2f0453e0ecab7b05 +Patch-mainline: v6.0-rc7 +References: git-fixes + +Fixes headphone and headset microphone detection on Huawei WRT-WX9. + +Signed-off-by: huangwenhui +Cc: +Link: https://lore.kernel.org/r/20220913054622.15979-1-huangwenhuia@uniontech.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_realtek.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 38930cf5aace..0996a8fd008c 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -9569,6 +9569,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), + SND_PCI_QUIRK(0x1849, 0x1233, "ASRock NUC Box 1100", ALC233_FIXUP_NO_AUDIO_JACK), + SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS), ++ SND_PCI_QUIRK(0x19e5, 0x320f, "Huawei WRT-WX9 ", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1b35, 0x1235, "CZC B20", ALC269_FIXUP_CZC_B20), + SND_PCI_QUIRK(0x1b35, 0x1236, "CZC TMI", ALC269_FIXUP_CZC_TMI), + SND_PCI_QUIRK(0x1b35, 0x1237, "CZC L101", ALC269_FIXUP_CZC_L101), +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-realtek-Add-quirk-for-Legion-Y9000X-2019.patch b/patches.suse/ALSA-hda-realtek-Add-quirk-for-Legion-Y9000X-2019.patch index a944aec..c356caf 100644 --- a/patches.suse/ALSA-hda-realtek-Add-quirk-for-Legion-Y9000X-2019.patch +++ b/patches.suse/ALSA-hda-realtek-Add-quirk-for-Legion-Y9000X-2019.patch @@ -21,11 +21,11 @@ Signed-off-by: Takashi Iwai --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c -@@ -9034,6 +9034,7 @@ static const struct snd_pci_quirk alc269 +@@ -9131,6 +9131,7 @@ static const struct snd_pci_quirk alc269 SND_PCI_QUIRK(0x17aa, 0x3824, "Legion Y9000X 2020", ALC285_FIXUP_LEGION_Y9000X_SPEAKERS), SND_PCI_QUIRK(0x17aa, 0x3827, "Ideapad S740", ALC285_FIXUP_IDEAPAD_S740_COEF), SND_PCI_QUIRK(0x17aa, 0x3834, "Lenovo IdeaPad Slim 9i 14ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS), + SND_PCI_QUIRK(0x17aa, 0x383d, "Legion Y9000X 2019", ALC285_FIXUP_LEGION_Y9000X_SPEAKERS), SND_PCI_QUIRK(0x17aa, 0x3843, "Yoga 9i", ALC287_FIXUP_IDEAPAD_BASS_SPK_AMP), + SND_PCI_QUIRK(0x17aa, 0x3847, "Legion 7 16ACHG6", ALC287_FIXUP_LEGION_16ACHG6), SND_PCI_QUIRK(0x17aa, 0x384a, "Lenovo Yoga 7 15ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS), - SND_PCI_QUIRK(0x17aa, 0x3852, "Lenovo Yoga 7 14ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS), diff --git a/patches.suse/ALSA-hda-realtek-Add-quirk-for-Lenovo-Yoga7-14IAL7.patch b/patches.suse/ALSA-hda-realtek-Add-quirk-for-Lenovo-Yoga7-14IAL7.patch new file mode 100644 index 0000000..c09b094 --- /dev/null +++ b/patches.suse/ALSA-hda-realtek-Add-quirk-for-Lenovo-Yoga7-14IAL7.patch @@ -0,0 +1,36 @@ +From 70cfdd0365acf550350d8949096c0b34a96b6b48 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 16 Aug 2022 15:21:32 +0200 +Subject: [PATCH] ALSA: hda/realtek: Add quirk for Lenovo Yoga7 14IAL7 +Git-commit: 70cfdd0365acf550350d8949096c0b34a96b6b48 +Patch-mainline: v6.0-rc2 +References: bsc#1203699 + +Lenovo Yoga7 14IAL7 requires the same quirk as Lenovo Yoga9 14IAP7 for +fixing the bass speaker problems. + +Reported-by: Pascal Gross +Cc: +Link: https://lore.kernel.org/r/N9_CjBz--3-2@tutanota.com +Link: https://lore.kernel.org/r/20220816132132.15520-1-tiwai@suse.de +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_realtek.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index f544761eb11b..b42496c01c43 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -9492,6 +9492,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x3852, "Lenovo Yoga 7 14ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS), + SND_PCI_QUIRK(0x17aa, 0x3853, "Lenovo Yoga 7 15ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS), + SND_PCI_QUIRK(0x17aa, 0x3855, "Legion 7 16ITHG6", ALC287_FIXUP_LEGION_16ITHG6), ++ SND_PCI_QUIRK(0x17aa, 0x3869, "Lenovo Yoga7 14IAL7", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN), + SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI), + SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC), + SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI), +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-realtek-Add-quirk-for-Lenovo-Yoga9-14IAP7.patch b/patches.suse/ALSA-hda-realtek-Add-quirk-for-Lenovo-Yoga9-14IAP7.patch index 6e81e2a..0c6c835 100644 --- a/patches.suse/ALSA-hda-realtek-Add-quirk-for-Lenovo-Yoga9-14IAP7.patch +++ b/patches.suse/ALSA-hda-realtek-Add-quirk-for-Lenovo-Yoga9-14IAP7.patch @@ -28,7 +28,7 @@ Signed-off-by: Takashi Iwai --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c -@@ -6702,6 +6702,43 @@ static void alc_fixup_dell4_mic_no_prese +@@ -6822,6 +6822,43 @@ static void alc_fixup_dell4_mic_no_prese } } @@ -72,18 +72,18 @@ Signed-off-by: Takashi Iwai enum { ALC269_FIXUP_GPIO2, ALC269_FIXUP_SONY_VAIO, -@@ -6931,6 +6968,8 @@ enum { - ALC285_FIXUP_LEGION_Y9000X_AUTOMUTE, +@@ -7059,6 +7096,8 @@ enum { ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED, ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE, + ALC287_FIXUP_LEGION_16ITHG6, + ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK, + ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN, }; /* A special fixup for Lenovo C940 and Yoga Duet 7; -@@ -8737,6 +8776,74 @@ static const struct hda_fixup alc269_fix - .chained = true, - .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC +@@ -8905,6 +8944,74 @@ static const struct hda_fixup alc269_fix + .type = HDA_FIXUP_FUNC, + .v.func = alc287_fixup_legion_16ithg6_speakers, }, + [ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK] = { + .type = HDA_FIXUP_VERBS, @@ -156,7 +156,7 @@ Signed-off-by: Takashi Iwai }; static const struct snd_pci_quirk alc269_fixup_tbl[] = { -@@ -9170,6 +9277,7 @@ static const struct snd_pci_quirk alc269 +@@ -9357,6 +9464,7 @@ static const struct snd_pci_quirk alc269 SND_PCI_QUIRK(0x17aa, 0x3176, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC), SND_PCI_QUIRK(0x17aa, 0x3178, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC), SND_PCI_QUIRK(0x17aa, 0x31af, "ThinkCentre Station", ALC623_FIXUP_LENOVO_THINKSTATION_P340), @@ -164,7 +164,7 @@ Signed-off-by: Takashi Iwai SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo Yoga DuetITL 2021", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS), SND_PCI_QUIRK(0x17aa, 0x3813, "Legion 7i 15IMHG05", ALC287_FIXUP_LEGION_15IMHG05_SPEAKERS), SND_PCI_QUIRK(0x17aa, 0x3818, "Lenovo C940 / Yoga Duet 7", ALC298_FIXUP_LENOVO_C940_DUET7), -@@ -9414,6 +9522,7 @@ static const struct hda_model_fixup alc2 +@@ -9603,6 +9711,7 @@ static const struct hda_model_fixup alc2 {.id = ALC285_FIXUP_HP_SPECTRE_X360, .name = "alc285-hp-spectre-x360"}, {.id = ALC285_FIXUP_HP_SPECTRE_X360_EB1, .name = "alc285-hp-spectre-x360-eb1"}, {.id = ALC287_FIXUP_IDEAPAD_BASS_SPK_AMP, .name = "alc287-ideapad-bass-spk-amp"}, diff --git a/patches.suse/ALSA-hda-realtek-Add-quirk-for-the-Framework-Laptop.patch b/patches.suse/ALSA-hda-realtek-Add-quirk-for-the-Framework-Laptop.patch index d3409e0..ae02d9c 100644 --- a/patches.suse/ALSA-hda-realtek-Add-quirk-for-the-Framework-Laptop.patch +++ b/patches.suse/ALSA-hda-realtek-Add-quirk-for-the-Framework-Laptop.patch @@ -34,15 +34,15 @@ Signed-off-by: Takashi Iwai --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c -@@ -6902,6 +6902,7 @@ enum { - ALC285_FIXUP_LEGION_Y9000X_SPEAKERS, - ALC285_FIXUP_LEGION_Y9000X_AUTOMUTE, +@@ -7049,6 +7049,7 @@ enum { + ALC245_FIXUP_CS35L41_SPI_4, + ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED, ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED, + ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE, }; static const struct hda_fixup alc269_fixups[] = { -@@ -8668,6 +8669,15 @@ static const struct hda_fixup alc269_fix +@@ -8837,6 +8838,15 @@ static const struct hda_fixup alc269_fix .chained = true, .chain_id = ALC269_FIXUP_DELL4_MIC_NO_PRESENCE, }, @@ -58,7 +58,7 @@ Signed-off-by: Takashi Iwai }; static const struct snd_pci_quirk alc269_fixup_tbl[] = { -@@ -9140,6 +9150,7 @@ static const struct snd_pci_quirk alc269 +@@ -9327,6 +9337,7 @@ static const struct snd_pci_quirk alc269 SND_PCI_QUIRK(0x8086, 0x2074, "Intel NUC 8", ALC233_FIXUP_INTEL_NUC8_DMIC), SND_PCI_QUIRK(0x8086, 0x2080, "Intel NUC 8 Rugged", ALC256_FIXUP_INTEL_NUC8_RUGGED), SND_PCI_QUIRK(0x8086, 0x2081, "Intel NUC 10", ALC256_FIXUP_INTEL_NUC10), diff --git a/patches.suse/ALSA-hda-realtek-Add-quirks-for-ASUS-Zenbooks-using-.patch b/patches.suse/ALSA-hda-realtek-Add-quirks-for-ASUS-Zenbooks-using-.patch new file mode 100644 index 0000000..87bc77d --- /dev/null +++ b/patches.suse/ALSA-hda-realtek-Add-quirks-for-ASUS-Zenbooks-using-.patch @@ -0,0 +1,42 @@ +From 461122b999bda2ebef2086a35d8990f9ccac5ab8 Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Mon, 15 Aug 2022 15:19:53 +0100 +Subject: [PATCH] ALSA: hda/realtek: Add quirks for ASUS Zenbooks using CS35L41 +Git-commit: 461122b999bda2ebef2086a35d8990f9ccac5ab8 +Patch-mainline: v6.0-rc2 +References: bsc#1203699 + +These Asus Zenbook laptop use Realtek HDA codec combined with +2xCS35L41 Amplifiers using SPI. + +Signed-off-by: Stefan Binding +Link: https://lore.kernel.org/r/20220815141953.25197-1-sbinding@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_realtek.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index fd630d62b5a0..f544761eb11b 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -9283,6 +9283,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x1271, "ASUS X430UN", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1043, 0x1290, "ASUS X441SA", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1043, 0x12a0, "ASUS X441UV", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE), ++ SND_PCI_QUIRK(0x1043, 0x12af, "ASUS UX582ZS", ALC245_FIXUP_CS35L41_SPI_2), + SND_PCI_QUIRK(0x1043, 0x12e0, "ASUS X541SA", ALC256_FIXUP_ASUS_MIC), + SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC), + SND_PCI_QUIRK(0x1043, 0x1313, "Asus K42JZ", ALC269VB_FIXUP_ASUS_MIC_NO_PRESENCE), +@@ -9303,6 +9304,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x19e1, "ASUS UX581LV", ALC295_FIXUP_ASUS_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), + SND_PCI_QUIRK(0x1043, 0x1a30, "ASUS X705UD", ALC256_FIXUP_ASUS_MIC), ++ SND_PCI_QUIRK(0x1043, 0x1a8f, "ASUS UX582ZS", ALC245_FIXUP_CS35L41_SPI_2), + SND_PCI_QUIRK(0x1043, 0x1b11, "ASUS UX431DA", ALC294_FIXUP_ASUS_COEF_1B), + SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC), + SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE), +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-realtek-Add-support-for-HP-Laptops.patch b/patches.suse/ALSA-hda-realtek-Add-support-for-HP-Laptops.patch new file mode 100644 index 0000000..e21c62a --- /dev/null +++ b/patches.suse/ALSA-hda-realtek-Add-support-for-HP-Laptops.patch @@ -0,0 +1,100 @@ +From 07bcab93946cd9980f8eafe89afe991cd918acb0 Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Fri, 21 Jan 2022 17:24:30 +0000 +Subject: [PATCH] ALSA: hda/realtek: Add support for HP Laptops +Git-commit: 07bcab93946cd9980f8eafe89afe991cd918acb0 +Patch-mainline: v5.18-rc1 +References: bsc#1203699 + +Add support for two and four CS35L41 using the component +binding method + +Signed-off-by: Lucas Tanure +Signed-off-by: Stefan Binding +Reviewed-by: Takashi Iwai +Link: https://lore.kernel.org/r/20220121172431.6876-9-sbinding@opensource.cirrus.com +Signed-off-by: Hans de Goede +Acked-by: Takashi Iwai + +--- + sound/pci/hda/patch_realtek.c | 43 ++++++++++++++++++++++++++++++++++- + 1 file changed, 42 insertions(+), 1 deletion(-) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 668274e52674..db0fce42887c 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -6611,6 +6611,16 @@ static void cs35l41_fixup_i2c_two(struct hda_codec *cdc, const struct hda_fixup + cs35l41_generic_fixup(cdc, action, "i2c", "CSC3551", 2); + } + ++static void cs35l41_fixup_spi_two(struct hda_codec *codec, const struct hda_fixup *fix, int action) ++{ ++ cs35l41_generic_fixup(codec, action, "spi0", "CSC3551", 2); ++} ++ ++static void cs35l41_fixup_spi_four(struct hda_codec *codec, const struct hda_fixup *fix, int action) ++{ ++ cs35l41_generic_fixup(codec, action, "spi0", "CSC3551", 4); ++} ++ + static void alc287_legion_16achg6_playback_hook(struct hda_pcm_stream *hinfo, struct hda_codec *cdc, + struct snd_pcm_substream *sub, int action) + { +@@ -6948,6 +6958,9 @@ enum { + ALC285_FIXUP_LEGION_Y9000X_AUTOMUTE, + ALC287_FIXUP_LEGION_16ACHG6, + ALC287_FIXUP_CS35L41_I2C_2, ++ ALC245_FIXUP_CS35L41_SPI_2, ++ ALC245_FIXUP_CS35L41_SPI_4, ++ ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED, + ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED, + }; + +@@ -8699,6 +8712,20 @@ static const struct hda_fixup alc269_fixups[] = { + .type = HDA_FIXUP_FUNC, + .v.func = cs35l41_fixup_i2c_two, + }, ++ [ALC245_FIXUP_CS35L41_SPI_2] = { ++ .type = HDA_FIXUP_FUNC, ++ .v.func = cs35l41_fixup_spi_two, ++ }, ++ [ALC245_FIXUP_CS35L41_SPI_4] = { ++ .type = HDA_FIXUP_FUNC, ++ .v.func = cs35l41_fixup_spi_four, ++ }, ++ [ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED] = { ++ .type = HDA_FIXUP_FUNC, ++ .v.func = alc245_fixup_hp_gpio_led, ++ .chained = true, ++ .chain_id = ALC245_FIXUP_CS35L41_SPI_4, ++ }, + [ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED] = { + .type = HDA_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { +@@ -8926,7 +8953,21 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x8896, "HP EliteBook 855 G8 Notebook PC", ALC285_FIXUP_HP_MUTE_LED), + SND_PCI_QUIRK(0x103c, 0x8898, "HP EliteBook 845 G8 Notebook PC", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST), + SND_PCI_QUIRK(0x103c, 0x88d0, "HP Pavilion 15-eh1xxx (mainboard 88D0)", ALC287_FIXUP_HP_GPIO_LED), +- SND_PCI_QUIRK(0x103c, 0x89c3, "HP", ALC285_FIXUP_HP_GPIO_LED), ++ SND_PCI_QUIRK(0x103c, 0x896e, "HP EliteBook x360 830 G9", ALC245_FIXUP_CS35L41_SPI_2), ++ SND_PCI_QUIRK(0x103c, 0x8971, "HP EliteBook 830 G9", ALC245_FIXUP_CS35L41_SPI_2), ++ SND_PCI_QUIRK(0x103c, 0x8972, "HP EliteBook 840 G9", ALC245_FIXUP_CS35L41_SPI_2), ++ SND_PCI_QUIRK(0x103c, 0x8973, "HP EliteBook 860 G9", ALC245_FIXUP_CS35L41_SPI_2), ++ SND_PCI_QUIRK(0x103c, 0x8974, "HP EliteBook 840 Aero G9", ALC245_FIXUP_CS35L41_SPI_2), ++ SND_PCI_QUIRK(0x103c, 0x8975, "HP EliteBook x360 840 Aero G9", ALC245_FIXUP_CS35L41_SPI_2), ++ SND_PCI_QUIRK(0x103c, 0x8981, "HP Elite Dragonfly G3", ALC245_FIXUP_CS35L41_SPI_4), ++ SND_PCI_QUIRK(0x103c, 0x898e, "HP EliteBook 835 G9", ALC287_FIXUP_CS35L41_I2C_2), ++ SND_PCI_QUIRK(0x103c, 0x898f, "HP EliteBook 835 G9", ALC287_FIXUP_CS35L41_I2C_2), ++ SND_PCI_QUIRK(0x103c, 0x8991, "HP EliteBook 845 G9", ALC287_FIXUP_CS35L41_I2C_2), ++ SND_PCI_QUIRK(0x103c, 0x8992, "HP EliteBook 845 G9", ALC287_FIXUP_CS35L41_I2C_2), ++ SND_PCI_QUIRK(0x103c, 0x8994, "HP EliteBook 855 G9", ALC287_FIXUP_CS35L41_I2C_2), ++ SND_PCI_QUIRK(0x103c, 0x8995, "HP EliteBook 855 G9", ALC287_FIXUP_CS35L41_I2C_2), ++ SND_PCI_QUIRK(0x103c, 0x89c3, "Zbook Studio G9", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED), ++ SND_PCI_QUIRK(0x103c, 0x89c6, "Zbook Fury 17 G9", ALC245_FIXUP_CS35L41_SPI_2), + SND_PCI_QUIRK(0x103c, 0x89ca, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), + SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), + SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-realtek-Add-support-for-Legion-7-16ACHg6-la.patch b/patches.suse/ALSA-hda-realtek-Add-support-for-Legion-7-16ACHg6-la.patch new file mode 100644 index 0000000..9987cd4 --- /dev/null +++ b/patches.suse/ALSA-hda-realtek-Add-support-for-Legion-7-16ACHg6-la.patch @@ -0,0 +1,177 @@ +From d3dca026375f2be550041b75833f2e3238738a70 Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Fri, 17 Dec 2021 11:57:07 +0000 +Subject: [PATCH] ALSA: hda/realtek: Add support for Legion 7 16ACHg6 laptop +Git-commit: d3dca026375f2be550041b75833f2e3238738a70 +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +Add Support for CS35L41 using the component binding +method + +[ corrected the quirk entry position by tiwai ] + +Signed-off-by: Lucas Tanure +Link: https://lore.kernel.org/r/20211217115708.882525-10-tanureal@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_realtek.c | 107 ++++++++++++++++++++++++++++++++++ + 1 file changed, 107 insertions(+) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 57fb3aa95426..395483b9753b 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -25,6 +25,7 @@ + #include "hda_auto_parser.h" + #include "hda_jack.h" + #include "hda_generic.h" ++#include "hda_component.h" + + /* keep halting ALC5505 DSP, for power saving */ + #define HALT_REALTEK_ALC5505 +@@ -126,6 +127,10 @@ struct alc_spec { + unsigned int coef0; + struct input_dev *kb_dev; + u8 alc_mute_keycode_map[1]; ++ ++ /* component binding */ ++ struct component_match *match; ++ struct hda_component comps[HDA_MAX_COMPONENTS]; + }; + + /* +@@ -6525,6 +6530,102 @@ static void alc287_fixup_legion_15imhg05_speakers(struct hda_codec *codec, + } + } + ++static int comp_match_dev_name(struct device *dev, void *data) ++{ ++ return strcmp(dev_name(dev), data) == 0; ++} ++ ++static int find_comp_by_dev_name(struct alc_spec *spec, const char *name) ++{ ++ int i; ++ ++ for (i = 0; i < HDA_MAX_COMPONENTS; i++) { ++ if (strcmp(spec->comps[i].name, name) == 0) ++ return i; ++ } ++ ++ return -ENODEV; ++} ++ ++static int comp_bind(struct device *dev) ++{ ++ struct hda_codec *cdc = dev_to_hda_codec(dev); ++ struct alc_spec *spec = cdc->spec; ++ ++ return component_bind_all(dev, spec->comps); ++} ++ ++static void comp_unbind(struct device *dev) ++{ ++ struct hda_codec *cdc = dev_to_hda_codec(dev); ++ struct alc_spec *spec = cdc->spec; ++ ++ component_unbind_all(dev, spec->comps); ++} ++ ++static const struct component_master_ops comp_master_ops = { ++ .bind = comp_bind, ++ .unbind = comp_unbind, ++}; ++ ++static void comp_generic_playback_hook(struct hda_pcm_stream *hinfo, struct hda_codec *cdc, ++ struct snd_pcm_substream *sub, int action) ++{ ++ struct alc_spec *spec = cdc->spec; ++ int i; ++ ++ for (i = 0; i < HDA_MAX_COMPONENTS; i++) { ++ if (spec->comps[i].dev) ++ spec->comps[i].playback_hook(spec->comps[i].dev, action); ++ } ++} ++ ++static void alc287_legion_16achg6_playback_hook(struct hda_pcm_stream *hinfo, struct hda_codec *cdc, ++ struct snd_pcm_substream *sub, int action) ++{ ++ struct alc_spec *spec = cdc->spec; ++ unsigned int rx_slot; ++ int i; ++ ++ switch (action) { ++ case HDA_GEN_PCM_ACT_PREPARE: ++ rx_slot = 0; ++ i = find_comp_by_dev_name(spec, "i2c-CLSA0100:00-cs35l41-hda.0"); ++ if (i >= 0) ++ spec->comps[i].set_channel_map(spec->comps[i].dev, 0, NULL, 1, &rx_slot); ++ ++ rx_slot = 1; ++ i = find_comp_by_dev_name(spec, "i2c-CLSA0100:00-cs35l41-hda.1"); ++ if (i >= 0) ++ spec->comps[i].set_channel_map(spec->comps[i].dev, 0, NULL, 1, &rx_slot); ++ break; ++ } ++ ++ comp_generic_playback_hook(hinfo, cdc, sub, action); ++} ++ ++static void alc287_fixup_legion_16achg6_speakers(struct hda_codec *cdc, const struct hda_fixup *fix, ++ int action) ++{ ++ struct device *dev = hda_codec_dev(cdc); ++ struct alc_spec *spec = cdc->spec; ++ int ret; ++ ++ switch (action) { ++ case HDA_FIXUP_ACT_PRE_PROBE: ++ component_match_add(dev, &spec->match, comp_match_dev_name, ++ "i2c-CLSA0100:00-cs35l41-hda.0"); ++ component_match_add(dev, &spec->match, comp_match_dev_name, ++ "i2c-CLSA0100:00-cs35l41-hda.1"); ++ ret = component_master_add_with_match(dev, &comp_master_ops, spec->match); ++ if (ret) ++ codec_err(cdc, "Fail to register component aggregator %d\n", ret); ++ else ++ spec->gen.pcm_playback_hook = alc287_legion_16achg6_playback_hook; ++ break; ++ } ++} ++ + /* for alc295_fixup_hp_top_speakers */ + #include "hp_x360_helper.c" + +@@ -6814,6 +6915,7 @@ enum { + ALC256_FIXUP_MIC_NO_PRESENCE_AND_RESUME, + ALC285_FIXUP_LEGION_Y9000X_SPEAKERS, + ALC285_FIXUP_LEGION_Y9000X_AUTOMUTE, ++ ALC287_FIXUP_LEGION_16ACHG6, + }; + + static const struct hda_fixup alc269_fixups[] = { +@@ -8556,6 +8658,10 @@ static const struct hda_fixup alc269_fixups[] = { + .chained = true, + .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC + }, ++ [ALC287_FIXUP_LEGION_16ACHG6] = { ++ .type = HDA_FIXUP_FUNC, ++ .v.func = alc287_fixup_legion_16achg6_speakers, ++ }, + }; + + static const struct snd_pci_quirk alc269_fixup_tbl[] = { +@@ -8970,6 +9076,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x3824, "Legion Y9000X 2020", ALC285_FIXUP_LEGION_Y9000X_SPEAKERS), + SND_PCI_QUIRK(0x17aa, 0x3827, "Ideapad S740", ALC285_FIXUP_IDEAPAD_S740_COEF), + SND_PCI_QUIRK(0x17aa, 0x3843, "Yoga 9i", ALC287_FIXUP_IDEAPAD_BASS_SPK_AMP), ++ SND_PCI_QUIRK(0x17aa, 0x3847, "Legion 7 16ACHG6", ALC287_FIXUP_LEGION_16ACHG6), + SND_PCI_QUIRK(0x17aa, 0x384a, "Lenovo Yoga 7 15ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS), + SND_PCI_QUIRK(0x17aa, 0x3852, "Lenovo Yoga 7 14ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS), + SND_PCI_QUIRK(0x17aa, 0x3853, "Lenovo Yoga 7 15ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS), +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-realtek-Correct-pin-configs-for-ASUS-G533Z.patch b/patches.suse/ALSA-hda-realtek-Correct-pin-configs-for-ASUS-G533Z.patch new file mode 100644 index 0000000..0ae61d5 --- /dev/null +++ b/patches.suse/ALSA-hda-realtek-Correct-pin-configs-for-ASUS-G533Z.patch @@ -0,0 +1,50 @@ +From 66ba7c88507344dee68ad1acbdb630473ab36114 Mon Sep 17 00:00:00 2001 +From: "Luke D. Jones" +Date: Mon, 10 Oct 2022 19:57:02 +1300 +Subject: [PATCH] ALSA: hda/realtek: Correct pin configs for ASUS G533Z +Git-commit: 66ba7c88507344dee68ad1acbdb630473ab36114 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The initial fix for ASUS G533Z was based on faulty information. This +fixes the pincfg to values that have been verified with no existing +module options or other hacks enabled. + +Enables headphone jack, and 5.1 surround. + +[ corrected the indent level by tiwai ] + +Fixes: bc2c23549ccd ("ALSA: hda/realtek: Add pincfg for ASUS G533Z HP jack") +Signed-off-by: Luke D. Jones +Cc: +Link: https://lore.kernel.org/r/20221010065702.35190-1-luke@ljones.dev +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_realtek.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index d89f95ae0efc..77a308a71cd4 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -8449,11 +8449,13 @@ static const struct hda_fixup alc269_fixups[] = { + [ALC285_FIXUP_ASUS_G533Z_PINS] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { +- { 0x14, 0x90170120 }, ++ { 0x14, 0x90170152 }, /* Speaker Surround Playback Switch */ ++ { 0x19, 0x03a19020 }, /* Mic Boost Volume */ ++ { 0x1a, 0x03a11c30 }, /* Mic Boost Volume */ ++ { 0x1e, 0x90170151 }, /* Rear jack, IN OUT EAPD Detect */ ++ { 0x21, 0x03211420 }, + { } + }, +- .chained = true, +- .chain_id = ALC294_FIXUP_ASUS_G513_PINS, + }, + [ALC294_FIXUP_ASUS_COEF_1B] = { + .type = HDA_FIXUP_VERBS, +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-realtek-Enable-4-speaker-output-Dell-Precis-1885ff13d4c4.patch b/patches.suse/ALSA-hda-realtek-Enable-4-speaker-output-Dell-Precis-1885ff13d4c4.patch new file mode 100644 index 0000000..acd005e --- /dev/null +++ b/patches.suse/ALSA-hda-realtek-Enable-4-speaker-output-Dell-Precis-1885ff13d4c4.patch @@ -0,0 +1,37 @@ +From 1885ff13d4c42910b37a0e3f7c2f182520f4eed1 Mon Sep 17 00:00:00 2001 +From: Callum Osmotherly +Date: Thu, 15 Sep 2022 22:36:08 +0930 +Subject: [PATCH] ALSA: hda/realtek: Enable 4-speaker output Dell Precision 5530 laptop +Git-commit: 1885ff13d4c42910b37a0e3f7c2f182520f4eed1 +Patch-mainline: v6.0-rc7 +References: git-fixes + +Just as with the 5570 (and the other Dell laptops), this enables the two +subwoofer speakers on the Dell Precision 5530 together with the main +ones, significantly increasing the audio quality. I've tested this +myself on a 5530 and can confirm it's working as expected. + +Signed-off-by: Callum Osmotherly +Cc: +Link: https://lore.kernel.org/r/YyMjQO3mhyXlMbCf@piranha +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_realtek.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index e722885da5f6..d309304cdc46 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -9149,6 +9149,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1028, 0x0871, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC), + SND_PCI_QUIRK(0x1028, 0x0872, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC), + SND_PCI_QUIRK(0x1028, 0x0873, "Dell Precision 3930", ALC255_FIXUP_DUMMY_LINEOUT_VERB), ++ SND_PCI_QUIRK(0x1028, 0x087d, "Dell Precision 5530", ALC289_FIXUP_DUAL_SPK), + SND_PCI_QUIRK(0x1028, 0x08ad, "Dell WYSE AIO", ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x08ae, "Dell WYSE NB", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0935, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB), +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-realtek-Enable-4-speaker-output-Dell-Precis.patch b/patches.suse/ALSA-hda-realtek-Enable-4-speaker-output-Dell-Precis.patch new file mode 100644 index 0000000..b8e9d05 --- /dev/null +++ b/patches.suse/ALSA-hda-realtek-Enable-4-speaker-output-Dell-Precis.patch @@ -0,0 +1,37 @@ +From bdc9b7396f7d4d6533e70fd8d5472f505b5ef58f Mon Sep 17 00:00:00 2001 +From: Callum Osmotherly +Date: Wed, 14 Sep 2022 18:44:00 +0930 +Subject: [PATCH] ALSA: hda/realtek: Enable 4-speaker output Dell Precision 5570 laptop +Git-commit: bdc9b7396f7d4d6533e70fd8d5472f505b5ef58f +Patch-mainline: v6.0-rc7 +References: git-fixes + +The Dell Precision 5570 uses the same 4-speakers-on-ALC289 just like the +previous Precision 5560. I replicated that patch onto this one, and can +confirm that the audio is much better (the woofers are now working); +I've tested it on my Dell Precision 5570. + +Signed-off-by: Callum Osmotherly +Cc: +Link: https://lore.kernel.org/r/YyGbWM5wEoFMbW2v@piranha +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_realtek.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 0996a8fd008c..e722885da5f6 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -9165,6 +9165,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1028, 0x0a9d, "Dell Latitude 5430", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0a9e, "Dell Latitude 5430", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0b19, "Dell XPS 15 9520", ALC289_FIXUP_DUAL_SPK), ++ SND_PCI_QUIRK(0x1028, 0x0b1a, "Dell Precision 5570", ALC289_FIXUP_DUAL_SPK), + SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-realtek-Enable-mute-micmute-LEDs-and-limit-.patch b/patches.suse/ALSA-hda-realtek-Enable-mute-micmute-LEDs-and-limit-.patch new file mode 100644 index 0000000..943a467 --- /dev/null +++ b/patches.suse/ALSA-hda-realtek-Enable-mute-micmute-LEDs-and-limit-.patch @@ -0,0 +1,60 @@ +From b3fbe53610b5ed8f0370ec4c7e6c8a1f261ddf70 Mon Sep 17 00:00:00 2001 +From: Andy Chi +Date: Thu, 21 Apr 2022 14:36:04 +0800 +Subject: [PATCH] ALSA: hda/realtek: Enable mute/micmute LEDs and limit mic boost on EliteBook 845/865 G9 +Git-commit: b3fbe53610b5ed8f0370ec4c7e6c8a1f261ddf70 +Patch-mainline: v5.18-rc4 +References: bsc#1203699 + +On HP EliteBook 845 G9 and EliteBook 865 G9, the audio LEDs can be enabled by +ALC285_FIXUP_HP_MUTE_LED. So use it accordingly. + +Signed-off-by: Andy Chi +Fixes: 07bcab93946c ("ALSA: hda/realtek: Add support for HP Laptops") +Link: https://lore.kernel.org/r/20220421063606.39772-1-andy.chi@canonical.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_realtek.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 62fbf3772b41..0cba2f19a772 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -7006,6 +7006,7 @@ enum { + ALC285_FIXUP_LEGION_Y9000X_AUTOMUTE, + ALC287_FIXUP_LEGION_16ACHG6, + ALC287_FIXUP_CS35L41_I2C_2, ++ ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED, + ALC245_FIXUP_CS35L41_SPI_2, + ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED, + ALC245_FIXUP_CS35L41_SPI_4, +@@ -8769,6 +8770,12 @@ static const struct hda_fixup alc269_fixups[] = { + .type = HDA_FIXUP_FUNC, + .v.func = cs35l41_fixup_i2c_two, + }, ++ [ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED] = { ++ .type = HDA_FIXUP_FUNC, ++ .v.func = cs35l41_fixup_i2c_two, ++ .chained = true, ++ .chain_id = ALC285_FIXUP_HP_MUTE_LED, ++ }, + [ALC245_FIXUP_CS35L41_SPI_2] = { + .type = HDA_FIXUP_FUNC, + .v.func = cs35l41_fixup_spi_two, +@@ -9025,9 +9032,9 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x8981, "HP Elite Dragonfly G3", ALC245_FIXUP_CS35L41_SPI_4), + SND_PCI_QUIRK(0x103c, 0x898e, "HP EliteBook 835 G9", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x103c, 0x898f, "HP EliteBook 835 G9", ALC287_FIXUP_CS35L41_I2C_2), +- SND_PCI_QUIRK(0x103c, 0x8991, "HP EliteBook 845 G9", ALC287_FIXUP_CS35L41_I2C_2), ++ SND_PCI_QUIRK(0x103c, 0x8991, "HP EliteBook 845 G9", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8992, "HP EliteBook 845 G9", ALC287_FIXUP_CS35L41_I2C_2), +- SND_PCI_QUIRK(0x103c, 0x8994, "HP EliteBook 855 G9", ALC287_FIXUP_CS35L41_I2C_2), ++ SND_PCI_QUIRK(0x103c, 0x8994, "HP EliteBook 855 G9", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8995, "HP EliteBook 855 G9", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x103c, 0x89a4, "HP ProBook 440 G9", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x89a6, "HP ProBook 450 G9", ALC236_FIXUP_HP_GPIO_LED), +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-realtek-Enable-mute-micmute-LEDs-support-fo.patch b/patches.suse/ALSA-hda-realtek-Enable-mute-micmute-LEDs-support-fo.patch new file mode 100644 index 0000000..3caa6da --- /dev/null +++ b/patches.suse/ALSA-hda-realtek-Enable-mute-micmute-LEDs-support-fo.patch @@ -0,0 +1,48 @@ +From 5f5d8890789c90470d9571a283f0b789acd594af Mon Sep 17 00:00:00 2001 +From: Andy Chi +Date: Fri, 22 Apr 2022 17:08:43 +0800 +Subject: [PATCH] ALSA: hda/realtek: Enable mute/micmute LEDs support for HP Laptops +Git-commit: 5f5d8890789c90470d9571a283f0b789acd594af +Patch-mainline: v5.18-rc6 +References: bsc#1203699 + +On HP Laptops, requires the same ALC285_FIXUP_HP_GPIO_LED quirk to +make its audio LEDs work. + +So apply the quirk, and make it the last one since it's an LED quirk. + +Signed-off-by: Andy Chi +Fixes: 07bcab93946c ("ALSA: hda/realtek: Add support for HP Laptops") +Link: https://lore.kernel.org/r/20220422090845.230071-1-andy.chi@canonical.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_realtek.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index f9c3b2c9ca12..c65d3dbc6cc9 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -9025,12 +9025,12 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x8896, "HP EliteBook 855 G8 Notebook PC", ALC285_FIXUP_HP_MUTE_LED), + SND_PCI_QUIRK(0x103c, 0x8898, "HP EliteBook 845 G8 Notebook PC", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST), + SND_PCI_QUIRK(0x103c, 0x88d0, "HP Pavilion 15-eh1xxx (mainboard 88D0)", ALC287_FIXUP_HP_GPIO_LED), +- SND_PCI_QUIRK(0x103c, 0x896e, "HP EliteBook x360 830 G9", ALC245_FIXUP_CS35L41_SPI_2), +- SND_PCI_QUIRK(0x103c, 0x8971, "HP EliteBook 830 G9", ALC245_FIXUP_CS35L41_SPI_2), +- SND_PCI_QUIRK(0x103c, 0x8972, "HP EliteBook 840 G9", ALC245_FIXUP_CS35L41_SPI_2), +- SND_PCI_QUIRK(0x103c, 0x8973, "HP EliteBook 860 G9", ALC245_FIXUP_CS35L41_SPI_2), +- SND_PCI_QUIRK(0x103c, 0x8974, "HP EliteBook 840 Aero G9", ALC245_FIXUP_CS35L41_SPI_2), +- SND_PCI_QUIRK(0x103c, 0x8975, "HP EliteBook x360 840 Aero G9", ALC245_FIXUP_CS35L41_SPI_2), ++ SND_PCI_QUIRK(0x103c, 0x896e, "HP EliteBook x360 830 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), ++ SND_PCI_QUIRK(0x103c, 0x8971, "HP EliteBook 830 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), ++ SND_PCI_QUIRK(0x103c, 0x8972, "HP EliteBook 840 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), ++ SND_PCI_QUIRK(0x103c, 0x8973, "HP EliteBook 860 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), ++ SND_PCI_QUIRK(0x103c, 0x8974, "HP EliteBook 840 Aero G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), ++ SND_PCI_QUIRK(0x103c, 0x8975, "HP EliteBook x360 840 Aero G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8981, "HP Elite Dragonfly G3", ALC245_FIXUP_CS35L41_SPI_4), + SND_PCI_QUIRK(0x103c, 0x898e, "HP EliteBook 835 G9", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x103c, 0x898f, "HP EliteBook 835 G9", ALC287_FIXUP_CS35L41_I2C_2), +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-realtek-Enable-speaker-and-mute-LEDs-for-HP.patch b/patches.suse/ALSA-hda-realtek-Enable-speaker-and-mute-LEDs-for-HP.patch new file mode 100644 index 0000000..0f77ec6 --- /dev/null +++ b/patches.suse/ALSA-hda-realtek-Enable-speaker-and-mute-LEDs-for-HP.patch @@ -0,0 +1,40 @@ +From c578d5da10dc429c6676ab09f3fec0b79b31633a Mon Sep 17 00:00:00 2001 +From: Kai-Heng Feng +Date: Tue, 19 Jul 2022 22:20:14 +0800 +Subject: [PATCH] ALSA: hda/realtek: Enable speaker and mute LEDs for HP laptops +Git-commit: c578d5da10dc429c6676ab09f3fec0b79b31633a +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +Two more HP laptops that use cs35l41 AMP for speaker and GPIO for mute +LEDs. + +So use the existing quirk to enable them accordingly. + +[ Sort the entries at the SSID order by tiwai ] + +Signed-off-by: Kai-Heng Feng +Reviewed-by: Lucas Tanure +Link: https://lore.kernel.org/r/20220719142015.244426-1-kai.heng.feng@canonical.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_realtek.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 0e340c0934db..06bb55399564 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -9138,6 +9138,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x8aa3, "HP ProBook 450 G9 (MB 8AA1)", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8aa8, "HP EliteBook 640 G9 (MB 8AA6)", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8aab, "HP EliteBook 650 G9 (MB 8AA9)", ALC236_FIXUP_HP_GPIO_LED), ++ SND_PCI_QUIRK(0x103c, 0x8ad1, "HP EliteBook 840 14 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), ++ SND_PCI_QUIRK(0x103c, 0x8ad2, "HP EliteBook 860 16 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), + SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), + SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-realtek-Fix-LED-on-Zbook-Studio-G9.patch b/patches.suse/ALSA-hda-realtek-Fix-LED-on-Zbook-Studio-G9.patch new file mode 100644 index 0000000..e3182ed --- /dev/null +++ b/patches.suse/ALSA-hda-realtek-Fix-LED-on-Zbook-Studio-G9.patch @@ -0,0 +1,44 @@ +From 864cb14c0fa22344613ae93d68e155bf9bbbc9fb Mon Sep 17 00:00:00 2001 +From: Kai-Heng Feng +Date: Fri, 18 Mar 2022 06:11:33 +0800 +Subject: [PATCH] ALSA: hda/realtek: Fix LED on Zbook Studio G9 +Git-commit: 864cb14c0fa22344613ae93d68e155bf9bbbc9fb +Patch-mainline: v5.18-rc1 +References: bsc#1203699 + +Commit 07bcab93946c ("ALSA: hda/realtek: Add support for HP Laptops") +breaks mute and micmute LEDs because it changed the LED quirk from +ALC285_FIXUP_HP_GPIO_LED to ALC245_FIXUP_HP_GPIO_LED, so change it back +here. + +Also reorder the chain of quirks to ensure LED quirk is the last one +being applied. + +Fixes: 07bcab93946c ("ALSA: hda/realtek: Add support for HP Laptops") +Signed-off-by: Kai-Heng Feng +Link: https://lore.kernel.org/r/20220317221134.566358-1-kai.heng.feng@canonical.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_realtek.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index d7bebe3bdea7..0a9ad35d34c1 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -8773,9 +8773,9 @@ static const struct hda_fixup alc269_fixups[] = { + }, + [ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED] = { + .type = HDA_FIXUP_FUNC, +- .v.func = alc245_fixup_hp_gpio_led, ++ .v.func = cs35l41_fixup_spi_four, + .chained = true, +- .chain_id = ALC245_FIXUP_CS35L41_SPI_4, ++ .chain_id = ALC285_FIXUP_HP_GPIO_LED, + }, + [ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED] = { + .type = HDA_FIXUP_VERBS, +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-realtek-Fix-mute-led-issue-on-thinkpad-with.patch b/patches.suse/ALSA-hda-realtek-Fix-mute-led-issue-on-thinkpad-with.patch new file mode 100644 index 0000000..c7b69f2 --- /dev/null +++ b/patches.suse/ALSA-hda-realtek-Fix-mute-led-issue-on-thinkpad-with.patch @@ -0,0 +1,40 @@ +From a6ac60b36dade525c13c5bb0838589619533efb7 Mon Sep 17 00:00:00 2001 +From: Hui Wang +Date: Fri, 22 Apr 2022 15:39:37 +0800 +Subject: [PATCH] ALSA: hda/realtek: Fix mute led issue on thinkpad with cs35l41 s-codec +Git-commit: a6ac60b36dade525c13c5bb0838589619533efb7 +Patch-mainline: v5.18-rc6 +References: bsc#1203699 + +The quirk ALC287_FIXUP_CS35L41_I2C_2 needs to chain the quirk +ALC269_FIXUP_THINKPAD_ACPI, otherwise the mute led will not work if a +thinkpad machine applies that quirk. + +And it will be safe if non-thinkpad machines apply that quirk since +hda_fixup_thinkpad_acpi() will check and return in this case. + +Fixes: ae7abe36e352e ("ALSA: hda/realtek: Add CS35L41 support for Thinkpad laptops") +Signed-off-by: Hui Wang +Link: https://lore.kernel.org/r/20220422073937.10073-1-hui.wang@canonical.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_realtek.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 4c0c593f3c0a..f9c3b2c9ca12 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -8769,6 +8769,8 @@ static const struct hda_fixup alc269_fixups[] = { + [ALC287_FIXUP_CS35L41_I2C_2] = { + .type = HDA_FIXUP_FUNC, + .v.func = cs35l41_fixup_i2c_two, ++ .chained = true, ++ .chain_id = ALC269_FIXUP_THINKPAD_ACPI, + }, + [ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED] = { + .type = HDA_FIXUP_FUNC, +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-realtek-More-robust-component-matching-for-.patch b/patches.suse/ALSA-hda-realtek-More-robust-component-matching-for-.patch new file mode 100644 index 0000000..1747e80 --- /dev/null +++ b/patches.suse/ALSA-hda-realtek-More-robust-component-matching-for-.patch @@ -0,0 +1,161 @@ +From 35a1744423743247026668e2323d1b932583fc2a Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Fri, 30 Sep 2022 10:48:10 +0200 +Subject: [PATCH] ALSA: hda/realtek: More robust component matching for CS35L41 +Git-commit: 35a1744423743247026668e2323d1b932583fc2a +Patch-mainline: v6.1-rc1 +References: bsc#1203699 + +As the previous commit implies, a system may have a different SPI bus +number that is embedded in the device string. And, assuming the fixed +bus number is rather fragile; it may be assigned differently depending +on the configuration or on the boot environment. Once when a bus +number change happens, the binding fails, resulting in the silence. + +This patch tries to make the matching a bit more relaxed, allowing to +bind with a different bus number (or without it). So the previous +fix, the introduction of ALC245_FIXUP_CS35L41_SPI1_2 fixup became +superfluous, and this is unified to ALC245_FIXUP_CS35L41_SPI_2. + +Fixes: 225f6e1bc151 ("ALSA: hda/realtek: Add quirk for HP Zbook Firefly 14 G9 model") +Link: https://lore.kernel.org/r/20220930084810.10435-1-tiwai@suse.de +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_realtek.c | 67 +++++++++++++++++++++++------------------- + 1 file changed, 37 insertions(+), 30 deletions(-) + +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -18,6 +18,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -6659,11 +6660,6 @@ static void alc287_fixup_legion_15imhg05 + } + } + +-static int comp_match_dev_name(struct device *dev, void *data) +-{ +- return strcmp(dev_name(dev), data) == 0; +-} +- + static int comp_bind(struct device *dev) + { + struct hda_codec *cdc = dev_to_hda_codec(dev); +@@ -6709,23 +6705,51 @@ static void comp_generic_playback_hook(s + } + } + ++struct cs35l41_dev_name { ++ const char *bus; ++ const char *hid; ++ int index; ++}; ++ ++/* match the device name in a slightly relaxed manner */ ++static int comp_match_cs35l41_dev_name(struct device *dev, void *data) ++{ ++ struct cs35l41_dev_name *p = data; ++ const char *d = dev_name(dev); ++ int n = strlen(p->bus); ++ char tmp[32]; ++ ++ /* check the bus name */ ++ if (strncmp(d, p->bus, n)) ++ return 0; ++ /* skip the bus number */ ++ if (isdigit(d[n])) ++ n++; ++ /* the rest must be exact matching */ ++ snprintf(tmp, sizeof(tmp), "-%s:00-cs35l41-hda.%d", p->hid, p->index); ++ return !strcmp(d + n, tmp); ++} ++ + static void cs35l41_generic_fixup(struct hda_codec *cdc, int action, const char *bus, + const char *hid, int count) + { + struct device *dev = hda_codec_dev(cdc); + struct alc_spec *spec = cdc->spec; +- char *name; ++ struct cs35l41_dev_name *rec; + int ret, i; + + switch (action) { + case HDA_FIXUP_ACT_PRE_PROBE: + for (i = 0; i < count; i++) { +- name = devm_kasprintf(dev, GFP_KERNEL, +- "%s-%s:00-cs35l41-hda.%d", bus, hid, i); +- if (!name) ++ rec = devm_kmalloc(dev, sizeof(*rec), GFP_KERNEL); ++ if (!rec) + return; ++ rec->bus = bus; ++ rec->hid = hid; ++ rec->index = i; + spec->comps[i].codec = cdc; +- component_match_add(dev, &spec->match, comp_match_dev_name, name); ++ component_match_add(dev, &spec->match, ++ comp_match_cs35l41_dev_name, rec); + } + ret = component_master_add_with_match(dev, &comp_master_ops, spec->match); + if (ret) +@@ -6743,17 +6767,12 @@ static void cs35l41_fixup_i2c_two(struct + + static void cs35l41_fixup_spi_two(struct hda_codec *codec, const struct hda_fixup *fix, int action) + { +- cs35l41_generic_fixup(codec, action, "spi0", "CSC3551", 2); +-} +- +-static void cs35l41_fixup_spi1_two(struct hda_codec *codec, const struct hda_fixup *fix, int action) +-{ +- cs35l41_generic_fixup(codec, action, "spi1", "CSC3551", 2); ++ cs35l41_generic_fixup(codec, action, "spi", "CSC3551", 2); + } + + static void cs35l41_fixup_spi_four(struct hda_codec *codec, const struct hda_fixup *fix, int action) + { +- cs35l41_generic_fixup(codec, action, "spi0", "CSC3551", 4); ++ cs35l41_generic_fixup(codec, action, "spi", "CSC3551", 4); + } + + static void alc287_fixup_legion_16achg6_speakers(struct hda_codec *cdc, const struct hda_fixup *fix, +@@ -7142,8 +7161,6 @@ enum { + ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED, + ALC245_FIXUP_CS35L41_SPI_2, + ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED, +- ALC245_FIXUP_CS35L41_SPI1_2, +- ALC245_FIXUP_CS35L41_SPI1_2_HP_GPIO_LED, + ALC245_FIXUP_CS35L41_SPI_4, + ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED, + ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED, +@@ -8991,16 +9008,6 @@ static const struct hda_fixup alc269_fix + .chained = true, + .chain_id = ALC285_FIXUP_HP_GPIO_LED, + }, +- [ALC245_FIXUP_CS35L41_SPI1_2] = { +- .type = HDA_FIXUP_FUNC, +- .v.func = cs35l41_fixup_spi1_two, +- }, +- [ALC245_FIXUP_CS35L41_SPI1_2_HP_GPIO_LED] = { +- .type = HDA_FIXUP_FUNC, +- .v.func = cs35l41_fixup_spi1_two, +- .chained = true, +- .chain_id = ALC285_FIXUP_HP_GPIO_LED, +- }, + [ALC245_FIXUP_CS35L41_SPI_4] = { + .type = HDA_FIXUP_FUNC, + .v.func = cs35l41_fixup_spi_four, +@@ -9363,7 +9370,7 @@ static const struct snd_pci_quirk alc269 + SND_PCI_QUIRK(0x103c, 0x8aa3, "HP ProBook 450 G9 (MB 8AA1)", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8aa8, "HP EliteBook 640 G9 (MB 8AA6)", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8aab, "HP EliteBook 650 G9 (MB 8AA9)", ALC236_FIXUP_HP_GPIO_LED), +- SND_PCI_QUIRK(0x103c, 0x8abb, "HP ZBook Firefly 14 G9", ALC245_FIXUP_CS35L41_SPI1_2_HP_GPIO_LED), ++ SND_PCI_QUIRK(0x103c, 0x8abb, "HP ZBook Firefly 14 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8ad1, "HP EliteBook 840 14 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8ad2, "HP EliteBook 860 16 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), diff --git a/patches.suse/ALSA-hda-realtek-Re-arrange-quirk-table-entries.patch b/patches.suse/ALSA-hda-realtek-Re-arrange-quirk-table-entries.patch new file mode 100644 index 0000000..be1df37 --- /dev/null +++ b/patches.suse/ALSA-hda-realtek-Re-arrange-quirk-table-entries.patch @@ -0,0 +1,57 @@ +From b16c8f229a58eaddfc58aab447253464abd3c85e Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Thu, 15 Sep 2022 17:47:24 +0200 +Subject: [PATCH] ALSA: hda/realtek: Re-arrange quirk table entries +Git-commit: b16c8f229a58eaddfc58aab447253464abd3c85e +Patch-mainline: v6.0-rc7 +References: git-fixes + +A few entries have been mistakenly inserted in wrong positions without +considering the SSID ordering. Place them at right positions. + +Fixes: b7557267c233 ("ALSA: hda/realtek: Add quirk for ASUS GA402") +Fixes: 94db9cc8f8fa ("ALSA: hda/realtek: Add quirk for ASUS GU603") +Fixes: 739d0959fbed ("ALSA: hda: Add quirk for ASUS Flow x13") +Cc: +Link: https://lore.kernel.org/r/20220915154724.31634-1-tiwai@suse.de +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_realtek.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index d309304cdc46..90fde53e6956 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -9341,10 +9341,11 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC), + SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK), + SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A), ++ SND_PCI_QUIRK(0x1043, 0x1662, "ASUS GV301QH", ALC294_FIXUP_ASUS_DUAL_SPK), ++ SND_PCI_QUIRK(0x1043, 0x16b2, "ASUS GU603", ALC289_FIXUP_ASUS_GA401), + SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), + SND_PCI_QUIRK(0x1043, 0x1740, "ASUS UX430UA", ALC295_FIXUP_ASUS_DACS), + SND_PCI_QUIRK(0x1043, 0x17d1, "ASUS UX431FL", ALC294_FIXUP_ASUS_DUAL_SPK), +- SND_PCI_QUIRK(0x1043, 0x1662, "ASUS GV301QH", ALC294_FIXUP_ASUS_DUAL_SPK), + SND_PCI_QUIRK(0x1043, 0x1881, "ASUS Zephyrus S/M", ALC294_FIXUP_ASUS_GX502_PINS), + SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC), + SND_PCI_QUIRK(0x1043, 0x18f1, "Asus FX505DT", ALC256_FIXUP_ASUS_HEADSET_MIC), +@@ -9361,13 +9362,12 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), + SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC), ++ SND_PCI_QUIRK(0x1043, 0x1d42, "ASUS Zephyrus G14 2022", ALC289_FIXUP_ASUS_GA401), + SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE), + SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502), + SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS), + SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401), + SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401), +- SND_PCI_QUIRK(0x1043, 0x1d42, "ASUS Zephyrus G14 2022", ALC289_FIXUP_ASUS_GA401), +- SND_PCI_QUIRK(0x1043, 0x16b2, "ASUS GU603", ALC289_FIXUP_ASUS_GA401), + SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2), + SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), + SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC), +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-realtek-fix-mute-micmute-LEDs-for-HP-machin.patch b/patches.suse/ALSA-hda-realtek-fix-mute-micmute-LEDs-for-HP-machin.patch index 129b2e2..c8d99e1 100644 --- a/patches.suse/ALSA-hda-realtek-fix-mute-micmute-LEDs-for-HP-machin.patch +++ b/patches.suse/ALSA-hda-realtek-fix-mute-micmute-LEDs-for-HP-machin.patch @@ -21,8 +21,8 @@ Signed-off-by: Takashi Iwai --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c -@@ -8956,6 +8956,10 @@ static const struct snd_pci_quirk alc269 - SND_PCI_QUIRK(0x103c, 0x89c3, "HP", ALC285_FIXUP_HP_GPIO_LED), +@@ -9146,6 +9146,10 @@ static const struct snd_pci_quirk alc269 + SND_PCI_QUIRK(0x103c, 0x89c6, "Zbook Fury 17 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x89ca, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), SND_PCI_QUIRK(0x103c, 0x8a78, "HP Dev One", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST), + SND_PCI_QUIRK(0x103c, 0x8aa0, "HP ProBook 440 G9 (MB 8A9E)", ALC236_FIXUP_HP_GPIO_LED), diff --git a/patches.suse/ALSA-hda-realtek-fix-right-sounds-and-mute-micmute-L-024a7ad9eb4d.patch b/patches.suse/ALSA-hda-realtek-fix-right-sounds-and-mute-micmute-L-024a7ad9eb4d.patch index 4ffabd2..bfcab6e 100644 --- a/patches.suse/ALSA-hda-realtek-fix-right-sounds-and-mute-micmute-L-024a7ad9eb4d.patch +++ b/patches.suse/ALSA-hda-realtek-fix-right-sounds-and-mute-micmute-L-024a7ad9eb4d.patch @@ -20,11 +20,11 @@ Signed-off-by: Takashi Iwai --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c -@@ -8898,6 +8898,7 @@ static const struct snd_pci_quirk alc269 - SND_PCI_QUIRK(0x103c, 0x88d0, "HP Pavilion 15-eh1xxx (mainboard 88D0)", ALC287_FIXUP_HP_GPIO_LED), +@@ -9080,6 +9080,7 @@ static const struct snd_pci_quirk alc269 + SND_PCI_QUIRK(0x103c, 0x8995, "HP EliteBook 855 G9", ALC287_FIXUP_CS35L41_I2C_2), SND_PCI_QUIRK(0x103c, 0x89a4, "HP ProBook 440 G9", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x89a6, "HP ProBook 450 G9", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x89aa, "HP EliteBook 630 G9", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x89ac, "HP EliteBook 640 G9", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x89ae, "HP EliteBook 650 G9", ALC236_FIXUP_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x89c3, "HP", ALC285_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x89c3, "Zbook Studio G9", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED), diff --git a/patches.suse/ALSA-hda-realtek-fix-right-sounds-and-mute-micmute-L.patch b/patches.suse/ALSA-hda-realtek-fix-right-sounds-and-mute-micmute-L.patch index 780347a..49d2d7f 100644 --- a/patches.suse/ALSA-hda-realtek-fix-right-sounds-and-mute-micmute-L.patch +++ b/patches.suse/ALSA-hda-realtek-fix-right-sounds-and-mute-micmute-L.patch @@ -20,14 +20,14 @@ Signed-off-by: Takashi Iwai --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c -@@ -8844,6 +8844,10 @@ static const struct snd_pci_quirk alc269 - SND_PCI_QUIRK(0x103c, 0x8896, "HP EliteBook 855 G8 Notebook PC", ALC285_FIXUP_HP_MUTE_LED), - SND_PCI_QUIRK(0x103c, 0x8898, "HP EliteBook 845 G8 Notebook PC", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST), - SND_PCI_QUIRK(0x103c, 0x88d0, "HP Pavilion 15-eh1xxx (mainboard 88D0)", ALC287_FIXUP_HP_GPIO_LED), +@@ -9017,6 +9017,10 @@ static const struct snd_pci_quirk alc269 + SND_PCI_QUIRK(0x103c, 0x8992, "HP EliteBook 845 G9", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x103c, 0x8994, "HP EliteBook 855 G9", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x103c, 0x8995, "HP EliteBook 855 G9", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x103c, 0x89a4, "HP ProBook 440 G9", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x89a6, "HP ProBook 450 G9", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x89ac, "HP EliteBook 640 G9", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x89ae, "HP EliteBook 650 G9", ALC236_FIXUP_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x89c3, "HP", ALC285_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x89c3, "Zbook Studio G9", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x89c6, "Zbook Fury 17 G9", ALC245_FIXUP_CS35L41_SPI_2), SND_PCI_QUIRK(0x103c, 0x89ca, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), - SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), diff --git a/patches.suse/ALSA-hda-realtek-fix-speakers-and-micmute-on-HP-855-.patch b/patches.suse/ALSA-hda-realtek-fix-speakers-and-micmute-on-HP-855-.patch index 861f5da..56ff356 100644 --- a/patches.suse/ALSA-hda-realtek-fix-speakers-and-micmute-on-HP-855-.patch +++ b/patches.suse/ALSA-hda-realtek-fix-speakers-and-micmute-on-HP-855-.patch @@ -30,17 +30,17 @@ Signed-off-by: Takashi Iwai --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c -@@ -6814,6 +6814,7 @@ enum { - ALC256_FIXUP_MIC_NO_PRESENCE_AND_RESUME, - ALC285_FIXUP_LEGION_Y9000X_SPEAKERS, +@@ -6948,6 +6948,7 @@ enum { ALC285_FIXUP_LEGION_Y9000X_AUTOMUTE, + ALC287_FIXUP_LEGION_16ACHG6, + ALC287_FIXUP_CS35L41_I2C_2, + ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED, }; static const struct hda_fixup alc269_fixups[] = { -@@ -8556,6 +8557,16 @@ static const struct hda_fixup alc269_fix - .chained = true, - .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC +@@ -8698,6 +8699,16 @@ static const struct hda_fixup alc269_fix + .type = HDA_FIXUP_FUNC, + .v.func = cs35l41_fixup_i2c_two, }, + [ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED] = { + .type = HDA_FIXUP_VERBS, @@ -55,7 +55,7 @@ Signed-off-by: Takashi Iwai }; static const struct snd_pci_quirk alc269_fixup_tbl[] = { -@@ -8769,6 +8780,7 @@ static const struct snd_pci_quirk alc269 +@@ -8911,6 +8922,7 @@ static const struct snd_pci_quirk alc269 SND_PCI_QUIRK(0x103c, 0x8870, "HP ZBook Fury 15.6 Inch G8 Mobile Workstation PC", ALC285_FIXUP_HP_GPIO_AMP_INIT), SND_PCI_QUIRK(0x103c, 0x8873, "HP ZBook Studio 15.6 Inch G8 Mobile Workstation PC", ALC285_FIXUP_HP_GPIO_AMP_INIT), SND_PCI_QUIRK(0x103c, 0x888d, "HP ZBook Power 15.6 inch G8 Mobile Workstation PC", ALC236_FIXUP_HP_GPIO_LED), diff --git a/patches.suse/ALSA-hda-realtek-remove-ALC289_FIXUP_DUAL_SPK-for-De.patch b/patches.suse/ALSA-hda-realtek-remove-ALC289_FIXUP_DUAL_SPK-for-De.patch new file mode 100644 index 0000000..559e8bc --- /dev/null +++ b/patches.suse/ALSA-hda-realtek-remove-ALC289_FIXUP_DUAL_SPK-for-De.patch @@ -0,0 +1,38 @@ +From 417b9c51f59734d852e47252476fadc293ad994a Mon Sep 17 00:00:00 2001 +From: Callum Osmotherly +Date: Wed, 5 Oct 2022 17:44:16 +1030 +Subject: [PATCH] ALSA: hda/realtek: remove ALC289_FIXUP_DUAL_SPK for Dell 5530 +Git-commit: 417b9c51f59734d852e47252476fadc293ad994a +Patch-mainline: v6.1-rc1 +References: git-fixes + +After some feedback from users with Dell Precision 5530 machines, this +patch reverts the previous change to add ALC289_FIXUP_DUAL_SPK. +While it improved the speaker output quality, it caused the headphone +jack to have an audible "pop" sound when power saving was toggled. + +Fixes: 1885ff13d4c4 ("ALSA: hda/realtek: Enable 4-speaker output Dell Precision 5530 laptop") +Signed-off-by: Callum Osmotherly +Cc: +Link: https://lore.kernel.org/r/Yz0uyN1zwZhnyRD6@piranha +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_realtek.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index bce82b834cec..d89f95ae0efc 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -9198,7 +9198,6 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1028, 0x0871, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC), + SND_PCI_QUIRK(0x1028, 0x0872, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC), + SND_PCI_QUIRK(0x1028, 0x0873, "Dell Precision 3930", ALC255_FIXUP_DUMMY_LINEOUT_VERB), +- SND_PCI_QUIRK(0x1028, 0x087d, "Dell Precision 5530", ALC289_FIXUP_DUAL_SPK), + SND_PCI_QUIRK(0x1028, 0x08ad, "Dell WYSE AIO", ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x08ae, "Dell WYSE NB", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0935, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB), +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-tegra-Add-Tegra234-hda-driver-support.patch b/patches.suse/ALSA-hda-tegra-Add-Tegra234-hda-driver-support.patch new file mode 100644 index 0000000..2674789 --- /dev/null +++ b/patches.suse/ALSA-hda-tegra-Add-Tegra234-hda-driver-support.patch @@ -0,0 +1,172 @@ +From f43156a9563f9262d7852ab79770f38f1fae7d76 Mon Sep 17 00:00:00 2001 +From: Mohan Kumar +Date: Wed, 16 Feb 2022 14:52:35 +0530 +Subject: [PATCH] ALSA: hda/tegra: Add Tegra234 hda driver support +Git-commit: f43156a9563f9262d7852ab79770f38f1fae7d76 +Patch-mainline: v5.18-rc1 +References: git-fixes + +Add hda driver support for the Tegra234 chip. The hdacodec +on this chip now supports DP MST feature, HDA block contains +azalia controller and one hda-codec instance by supporting +4 independent output streams over DP MST mode. There is no +input stream support. + +Signed-off-by: Mohan Kumar +Link: https://lore.kernel.org/r/20220216092240.26464-2-mkumard@nvidia.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/hda_tegra.c | 21 +++++++++++++-- + sound/pci/hda/patch_hdmi.c | 54 +++++++++++++++++++++++++++++++++----- + 2 files changed, 67 insertions(+), 8 deletions(-) + +diff --git a/sound/pci/hda/hda_tegra.c b/sound/pci/hda/hda_tegra.c +index 773f4903550a..95df52b0505b 100644 +--- a/sound/pci/hda/hda_tegra.c ++++ b/sound/pci/hda/hda_tegra.c +@@ -70,6 +70,7 @@ + + struct hda_tegra_soc { + bool has_hda2codec_2x_reset; ++ bool has_hda2hdmi; + }; + + struct hda_tegra { +@@ -435,15 +436,23 @@ static int hda_tegra_create(struct snd_card *card, + + static const struct hda_tegra_soc tegra30_data = { + .has_hda2codec_2x_reset = true, ++ .has_hda2hdmi = true, + }; + + static const struct hda_tegra_soc tegra194_data = { + .has_hda2codec_2x_reset = false, ++ .has_hda2hdmi = true, ++}; ++ ++static const struct hda_tegra_soc tegra234_data = { ++ .has_hda2codec_2x_reset = true, ++ .has_hda2hdmi = false, + }; + + static const struct of_device_id hda_tegra_match[] = { + { .compatible = "nvidia,tegra30-hda", .data = &tegra30_data }, + { .compatible = "nvidia,tegra194-hda", .data = &tegra194_data }, ++ { .compatible = "nvidia,tegra234-hda", .data = &tegra234_data }, + {}, + }; + MODULE_DEVICE_TABLE(of, hda_tegra_match); +@@ -473,7 +482,14 @@ static int hda_tegra_probe(struct platform_device *pdev) + } + + hda->resets[hda->nresets++].id = "hda"; +- hda->resets[hda->nresets++].id = "hda2hdmi"; ++ ++ /* ++ * "hda2hdmi" is not applicable for Tegra234. This is because the ++ * codec is separate IP and not under display SOR partition now. ++ */ ++ if (hda->soc->has_hda2hdmi) ++ hda->resets[hda->nresets++].id = "hda2hdmi"; ++ + /* + * "hda2codec_2x" reset is not present on Tegra194. Though DT would + * be updated to reflect this, but to have backward compatibility +@@ -488,7 +504,8 @@ static int hda_tegra_probe(struct platform_device *pdev) + goto out_free; + + hda->clocks[hda->nclocks++].id = "hda"; +- hda->clocks[hda->nclocks++].id = "hda2hdmi"; ++ if (hda->soc->has_hda2hdmi) ++ hda->clocks[hda->nclocks++].id = "hda2hdmi"; + hda->clocks[hda->nclocks++].id = "hda2codec_2x"; + + err = devm_clk_bulk_get(&pdev->dev, hda->nclocks, hda->clocks); +diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c +index 69a912c52ca7..a134d91db5ff 100644 +--- a/sound/pci/hda/patch_hdmi.c ++++ b/sound/pci/hda/patch_hdmi.c +@@ -3927,17 +3927,29 @@ static int tegra_hdmi_build_pcms(struct hda_codec *codec) + return 0; + } + +-static int patch_tegra_hdmi(struct hda_codec *codec) ++static int tegra_hdmi_init(struct hda_codec *codec) + { +- struct hdmi_spec *spec; +- int err; ++ struct hdmi_spec *spec = codec->spec; ++ int i, err; + +- err = patch_generic_hdmi(codec); +- if (err) ++ err = hdmi_parse_codec(codec); ++ if (err < 0) { ++ generic_spec_free(codec); + return err; ++ } ++ ++ for (i = 0; i < spec->num_cvts; i++) ++ snd_hda_codec_write(codec, spec->cvt_nids[i], 0, ++ AC_VERB_SET_DIGI_CONVERT_1, ++ AC_DIG1_ENABLE); ++ ++ generic_hdmi_init_per_pins(codec); + + codec->patch_ops.build_pcms = tegra_hdmi_build_pcms; +- spec = codec->spec; ++ spec->chmap.ops.chmap_cea_alloc_validate_get_type = ++ nvhdmi_chmap_cea_alloc_validate_get_type; ++ spec->chmap.ops.chmap_validate = nvhdmi_chmap_validate; ++ + spec->chmap.ops.chmap_cea_alloc_validate_get_type = + nvhdmi_chmap_cea_alloc_validate_get_type; + spec->chmap.ops.chmap_validate = nvhdmi_chmap_validate; +@@ -3945,6 +3957,35 @@ static int patch_tegra_hdmi(struct hda_codec *codec) + return 0; + } + ++static int patch_tegra_hdmi(struct hda_codec *codec) ++{ ++ int err; ++ ++ err = alloc_generic_hdmi(codec); ++ if (err < 0) ++ return err; ++ ++ return tegra_hdmi_init(codec); ++} ++ ++static int patch_tegra234_hdmi(struct hda_codec *codec) ++{ ++ struct hdmi_spec *spec; ++ int err; ++ ++ err = alloc_generic_hdmi(codec); ++ if (err < 0) ++ return err; ++ ++ codec->dp_mst = true; ++ codec->mst_no_extra_pcms = true; ++ spec = codec->spec; ++ spec->dyn_pin_out = true; ++ spec->dyn_pcm_assign = true; ++ ++ return tegra_hdmi_init(codec); ++} ++ + /* + * ATI/AMD-specific implementations + */ +@@ -4398,6 +4439,7 @@ HDA_CODEC_ENTRY(0x10de002d, "Tegra186 HDMI/DP0", patch_tegra_hdmi), + HDA_CODEC_ENTRY(0x10de002e, "Tegra186 HDMI/DP1", patch_tegra_hdmi), + HDA_CODEC_ENTRY(0x10de002f, "Tegra194 HDMI/DP2", patch_tegra_hdmi), + HDA_CODEC_ENTRY(0x10de0030, "Tegra194 HDMI/DP3", patch_tegra_hdmi), ++HDA_CODEC_ENTRY(0x10de0031, "Tegra234 HDMI/DP", patch_tegra234_hdmi), + HDA_CODEC_ENTRY(0x10de0040, "GPU 40 HDMI/DP", patch_nvhdmi), + HDA_CODEC_ENTRY(0x10de0041, "GPU 41 HDMI/DP", patch_nvhdmi), + HDA_CODEC_ENTRY(0x10de0042, "GPU 42 HDMI/DP", patch_nvhdmi), +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-tegra-Update-scratch-reg.-communication.patch b/patches.suse/ALSA-hda-tegra-Update-scratch-reg.-communication.patch new file mode 100644 index 0000000..dc58701 --- /dev/null +++ b/patches.suse/ALSA-hda-tegra-Update-scratch-reg.-communication.patch @@ -0,0 +1,161 @@ +From 85f29492929bd52dc3b05876c7ae0362608475ce Mon Sep 17 00:00:00 2001 +From: Mohan Kumar +Date: Wed, 16 Feb 2022 14:52:37 +0530 +Subject: [PATCH] ALSA: hda/tegra: Update scratch reg. communication +Git-commit: 85f29492929bd52dc3b05876c7ae0362608475ce +Patch-mainline: v5.18-rc1 +References: git-fixes + +Tegra234 chip scratch register communication between audio +and hdmi driver differs slightly in the way it triggers the +interrupt compared to legacy chips. Interrupt is triggered +by writing non-zero values to verb 0xF80 instead of 31st bit +of scratch register. + +DP MST support changed the NID to be used for scratch register +read/write from audio function group NID to Converter widget NID. + +Signed-off-by: Mohan Kumar +Link: https://lore.kernel.org/r/20220216092240.26464-4-mkumard@nvidia.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_hdmi.c | 64 ++++++++++++++++++++++++++++---------- + 1 file changed, 48 insertions(+), 16 deletions(-) + +diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c +index a134d91db5ff..c85ed7bc121e 100644 +--- a/sound/pci/hda/patch_hdmi.c ++++ b/sound/pci/hda/patch_hdmi.c +@@ -168,6 +168,8 @@ struct hdmi_spec { + bool dyn_pin_out; + bool dyn_pcm_assign; + bool dyn_pcm_no_legacy; ++ /* hdmi interrupt trigger control flag for Nvidia codec */ ++ bool hdmi_intr_trig_ctrl; + bool intel_hsw_fixup; /* apply Intel platform-specific fixups */ + /* + * Non-generic VIA/NVIDIA specific +@@ -3797,8 +3799,11 @@ static int patch_nvhdmi_legacy(struct hda_codec *codec) + * +-----------------------------------| + * + * Note that for the trigger bit to take effect it needs to change value +- * (i.e. it needs to be toggled). ++ * (i.e. it needs to be toggled). The trigger bit is not applicable from ++ * TEGRA234 chip onwards, as new verb id 0xf80 will be used for interrupt ++ * trigger to hdmi. + */ ++#define NVIDIA_SET_HOST_INTR 0xf80 + #define NVIDIA_GET_SCRATCH0 0xfa6 + #define NVIDIA_SET_SCRATCH0_BYTE0 0xfa7 + #define NVIDIA_SET_SCRATCH0_BYTE1 0xfa8 +@@ -3817,25 +3822,38 @@ static int patch_nvhdmi_legacy(struct hda_codec *codec) + * The format parameter is the HDA audio format (see AC_FMT_*). If set to 0, + * the format is invalidated so that the HDMI codec can be disabled. + */ +-static void tegra_hdmi_set_format(struct hda_codec *codec, unsigned int format) ++static void tegra_hdmi_set_format(struct hda_codec *codec, ++ hda_nid_t cvt_nid, ++ unsigned int format) + { + unsigned int value; ++ unsigned int nid = NVIDIA_AFG_NID; ++ struct hdmi_spec *spec = codec->spec; ++ ++ /* ++ * Tegra HDA codec design from TEGRA234 chip onwards support DP MST. ++ * This resulted in moving scratch registers from audio function ++ * group to converter widget context. So CVT NID should be used for ++ * scratch register read/write for DP MST supported Tegra HDA codec. ++ */ ++ if (codec->dp_mst) ++ nid = cvt_nid; + + /* bits [31:30] contain the trigger and valid bits */ +- value = snd_hda_codec_read(codec, NVIDIA_AFG_NID, 0, ++ value = snd_hda_codec_read(codec, nid, 0, + NVIDIA_GET_SCRATCH0, 0); + value = (value >> 24) & 0xff; + + /* bits [15:0] are used to store the HDA format */ +- snd_hda_codec_write(codec, NVIDIA_AFG_NID, 0, ++ snd_hda_codec_write(codec, nid, 0, + NVIDIA_SET_SCRATCH0_BYTE0, + (format >> 0) & 0xff); +- snd_hda_codec_write(codec, NVIDIA_AFG_NID, 0, ++ snd_hda_codec_write(codec, nid, 0, + NVIDIA_SET_SCRATCH0_BYTE1, + (format >> 8) & 0xff); + + /* bits [16:24] are unused */ +- snd_hda_codec_write(codec, NVIDIA_AFG_NID, 0, ++ snd_hda_codec_write(codec, nid, 0, + NVIDIA_SET_SCRATCH0_BYTE2, 0); + + /* +@@ -3847,15 +3865,28 @@ static void tegra_hdmi_set_format(struct hda_codec *codec, unsigned int format) + else + value |= NVIDIA_SCRATCH_VALID; + +- /* +- * Whenever the trigger bit is toggled, an interrupt is raised in the +- * HDMI codec. The HDMI driver will use that as trigger to update its +- * configuration. +- */ +- value ^= NVIDIA_SCRATCH_TRIGGER; ++ if (spec->hdmi_intr_trig_ctrl) { ++ /* ++ * For Tegra HDA Codec design from TEGRA234 onwards, the ++ * Interrupt to hdmi driver is triggered by writing ++ * non-zero values to verb 0xF80 instead of 31st bit of ++ * scratch register. ++ */ ++ snd_hda_codec_write(codec, nid, 0, ++ NVIDIA_SET_SCRATCH0_BYTE3, value); ++ snd_hda_codec_write(codec, nid, 0, ++ NVIDIA_SET_HOST_INTR, 0x1); ++ } else { ++ /* ++ * Whenever the 31st trigger bit is toggled, an interrupt is raised ++ * in the HDMI codec. The HDMI driver will use that as trigger ++ * to update its configuration. ++ */ ++ value ^= NVIDIA_SCRATCH_TRIGGER; + +- snd_hda_codec_write(codec, NVIDIA_AFG_NID, 0, +- NVIDIA_SET_SCRATCH0_BYTE3, value); ++ snd_hda_codec_write(codec, nid, 0, ++ NVIDIA_SET_SCRATCH0_BYTE3, value); ++ } + } + + static int tegra_hdmi_pcm_prepare(struct hda_pcm_stream *hinfo, +@@ -3872,7 +3903,7 @@ static int tegra_hdmi_pcm_prepare(struct hda_pcm_stream *hinfo, + return err; + + /* notify the HDMI codec of the format change */ +- tegra_hdmi_set_format(codec, format); ++ tegra_hdmi_set_format(codec, hinfo->nid, format); + + return 0; + } +@@ -3882,7 +3913,7 @@ static int tegra_hdmi_pcm_cleanup(struct hda_pcm_stream *hinfo, + struct snd_pcm_substream *substream) + { + /* invalidate the format in the HDMI codec */ +- tegra_hdmi_set_format(codec, 0); ++ tegra_hdmi_set_format(codec, hinfo->nid, 0); + + return generic_hdmi_playback_pcm_cleanup(hinfo, codec, substream); + } +@@ -3982,6 +4013,7 @@ static int patch_tegra234_hdmi(struct hda_codec *codec) + spec = codec->spec; + spec->dyn_pin_out = true; + spec->dyn_pcm_assign = true; ++ spec->hdmi_intr_trig_ctrl = true; + + return tegra_hdmi_init(codec); + } +-- +2.35.3 + diff --git a/patches.suse/ALSA-hda-tegra-set-depop-delay-for-tegra.patch b/patches.suse/ALSA-hda-tegra-set-depop-delay-for-tegra.patch new file mode 100644 index 0000000..39c7b03 --- /dev/null +++ b/patches.suse/ALSA-hda-tegra-set-depop-delay-for-tegra.patch @@ -0,0 +1,35 @@ +From 3c4d8c24fb6c44f426e447b04800b0ed61a7b5ae Mon Sep 17 00:00:00 2001 +From: Mohan Kumar +Date: Tue, 13 Sep 2022 11:06:41 +0530 +Subject: [PATCH] ALSA: hda/tegra: set depop delay for tegra +Git-commit: 3c4d8c24fb6c44f426e447b04800b0ed61a7b5ae +Patch-mainline: v6.0-rc7 +References: git-fixes + +Reduce the suspend time by setting depop delay to 10ms for +tegra. + +Signed-off-by: Mohan Kumar +Cc: +Link: https://lore.kernel.org/r/20220913053641.23299-1-mkumard@nvidia.com +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/patch_hdmi.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c +index 6c209cd26c0c..acaf6b790ee1 100644 +--- a/sound/pci/hda/patch_hdmi.c ++++ b/sound/pci/hda/patch_hdmi.c +@@ -3984,6 +3984,7 @@ static int tegra_hdmi_init(struct hda_codec *codec) + + generic_hdmi_init_per_pins(codec); + ++ codec->depop_delay = 10; + codec->patch_ops.build_pcms = tegra_hdmi_build_pcms; + spec->chmap.ops.chmap_cea_alloc_validate_get_type = + nvhdmi_chmap_cea_alloc_validate_get_type; +-- +2.35.3 + diff --git a/patches.suse/ALSA-oss-Fix-potential-deadlock-at-unregistration.patch b/patches.suse/ALSA-oss-Fix-potential-deadlock-at-unregistration.patch new file mode 100644 index 0000000..4396cb4 --- /dev/null +++ b/patches.suse/ALSA-oss-Fix-potential-deadlock-at-unregistration.patch @@ -0,0 +1,65 @@ +From 97d917879d7f92df09c3f21fd54609a8bcd654b2 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 11 Oct 2022 09:01:47 +0200 +Subject: [PATCH] ALSA: oss: Fix potential deadlock at unregistration +Git-commit: 97d917879d7f92df09c3f21fd54609a8bcd654b2 +Patch-mainline: v6.1-rc1 +References: git-fixes + +We took sound_oss_mutex around the calls of unregister_sound_special() +at unregistering OSS devices. This may, however, lead to a deadlock, +because we manage the card release via the card's device object, and +the release may happen at unregister_sound_special() call -- which +will take sound_oss_mutex again in turn. + +Although the deadlock might be fixed by relaxing the rawmidi mutex in +the previous commit, it's safer to move unregister_sound_special() +calls themselves out of the sound_oss_mutex, too. The call is +race-safe as the function has a spinlock protection by itself. + +Link: https://lore.kernel.org/r/CAB7eexJP7w1B0mVgDF0dQ+gWor7UdkiwPczmL7pn91xx8xpzOA@mail.gmail.com +Cc: +Link: https://lore.kernel.org/r/20221011070147.7611-2-tiwai@suse.de +Signed-off-by: Takashi Iwai + +--- + sound/core/sound_oss.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c +index 7ed0a2a91035..2751bf2ff61b 100644 +--- a/sound/core/sound_oss.c ++++ b/sound/core/sound_oss.c +@@ -162,7 +162,6 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev) + mutex_unlock(&sound_oss_mutex); + return -ENOENT; + } +- unregister_sound_special(minor); + switch (SNDRV_MINOR_OSS_DEVICE(minor)) { + case SNDRV_MINOR_OSS_PCM: + track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_AUDIO); +@@ -174,12 +173,18 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev) + track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_DMMIDI1); + break; + } +- if (track2 >= 0) { +- unregister_sound_special(track2); ++ if (track2 >= 0) + snd_oss_minors[track2] = NULL; +- } + snd_oss_minors[minor] = NULL; + mutex_unlock(&sound_oss_mutex); ++ ++ /* call unregister_sound_special() outside sound_oss_mutex; ++ * otherwise may deadlock, as it can trigger the release of a card ++ */ ++ unregister_sound_special(minor); ++ if (track2 >= 0) ++ unregister_sound_special(track2); ++ + kfree(mptr); + return 0; + } +-- +2.35.3 + diff --git a/patches.suse/ALSA-pcm-oss-Fix-race-at-SNDCTL_DSP_SYNC.patch b/patches.suse/ALSA-pcm-oss-Fix-race-at-SNDCTL_DSP_SYNC.patch index 731c973..423d768 100644 --- a/patches.suse/ALSA-pcm-oss-Fix-race-at-SNDCTL_DSP_SYNC.patch +++ b/patches.suse/ALSA-pcm-oss-Fix-race-at-SNDCTL_DSP_SYNC.patch @@ -4,7 +4,7 @@ Date: Mon, 5 Sep 2022 08:07:14 +0200 Subject: [PATCH] ALSA: pcm: oss: Fix race at SNDCTL_DSP_SYNC Git-commit: 8423f0b6d513b259fdab9c9bf4aaa6188d054c2d Patch-mainline: v6.0-rc5 -References: git-fixes +References: CVE-2022-3303 bsc#1203769 git-fixes There is a small race window at snd_pcm_oss_sync() that is called from OSS PCM SNDCTL_DSP_SYNC ioctl; namely the function calls diff --git a/patches.suse/ALSA-rawmidi-Drop-register_mutex-in-snd_rawmidi_free.patch b/patches.suse/ALSA-rawmidi-Drop-register_mutex-in-snd_rawmidi_free.patch new file mode 100644 index 0000000..e591dce --- /dev/null +++ b/patches.suse/ALSA-rawmidi-Drop-register_mutex-in-snd_rawmidi_free.patch @@ -0,0 +1,42 @@ +From a70aef7982b012e86dfd39fbb235e76a21ae778a Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 11 Oct 2022 09:01:46 +0200 +Subject: [PATCH] ALSA: rawmidi: Drop register_mutex in snd_rawmidi_free() +Git-commit: a70aef7982b012e86dfd39fbb235e76a21ae778a +Patch-mainline: v6.1-rc1 +References: git-fixes + +The register_mutex taken around the dev_unregister callback call in +snd_rawmidi_free() may potentially lead to a mutex deadlock, when OSS +emulation and a hot unplug are involved. + +Since the mutex doesn't protect the actual race (as the registration +itself is already protected by another means), let's drop it. + +Link: https://lore.kernel.org/r/CAB7eexJP7w1B0mVgDF0dQ+gWor7UdkiwPczmL7pn91xx8xpzOA@mail.gmail.com +Cc: +Link: https://lore.kernel.org/r/20221011070147.7611-1-tiwai@suse.de +Signed-off-by: Takashi Iwai + +--- + sound/core/rawmidi.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c +index 6963d5a487b3..d8edb6055072 100644 +--- a/sound/core/rawmidi.c ++++ b/sound/core/rawmidi.c +@@ -1899,10 +1899,8 @@ static int snd_rawmidi_free(struct snd_rawmidi *rmidi) + + snd_info_free_entry(rmidi->proc_entry); + rmidi->proc_entry = NULL; +- mutex_lock(®ister_mutex); + if (rmidi->ops && rmidi->ops->dev_unregister) + rmidi->ops->dev_unregister(rmidi); +- mutex_unlock(®ister_mutex); + + snd_rawmidi_free_substreams(&rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT]); + snd_rawmidi_free_substreams(&rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]); +-- +2.35.3 + diff --git a/patches.suse/ALSA-usb-audio-Fix-NULL-dererence-at-error-path.patch b/patches.suse/ALSA-usb-audio-Fix-NULL-dererence-at-error-path.patch new file mode 100644 index 0000000..658b5f0 --- /dev/null +++ b/patches.suse/ALSA-usb-audio-Fix-NULL-dererence-at-error-path.patch @@ -0,0 +1,47 @@ +From 568be8aaf8a535f79c4db76cabe17b035aa2584d Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Fri, 30 Sep 2022 12:01:29 +0200 +Subject: [PATCH] ALSA: usb-audio: Fix NULL dererence at error path +Git-commit: 568be8aaf8a535f79c4db76cabe17b035aa2584d +Patch-mainline: v6.1-rc1 +References: git-fixes + +At an error path to release URB buffers and contexts, the driver might +hit a NULL dererence for u->urb pointer, when u->buffer_size has been +already set but the actual URB allocation failed. + +Fix it by adding the NULL check of urb. Also, make sure that +buffer_size is cleared after the error path or the close. + +Cc: +Reported-by: Sabri N. Ferreiro +Link: https://lore.kernel.org/r/CAKG+3NRjTey+fFfUEGwuxL-pi_=T4cUskYG9OzpzHytF+tzYng@mail.gmail.com +Link: https://lore.kernel.org/r/20220930100129.19445-1-tiwai@suse.de +Signed-off-by: Takashi Iwai + +--- + sound/usb/endpoint.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c +index b2d0b42b581f..36f753a28341 100644 +--- a/sound/usb/endpoint.c ++++ b/sound/usb/endpoint.c +@@ -95,12 +95,13 @@ static inline unsigned get_usb_high_speed_rate(unsigned int rate) + */ + static void release_urb_ctx(struct snd_urb_ctx *u) + { +- if (u->buffer_size) ++ if (u->urb && u->buffer_size) + usb_free_coherent(u->ep->chip->dev, u->buffer_size, + u->urb->transfer_buffer, + u->urb->transfer_dma); + usb_free_urb(u->urb); + u->urb = NULL; ++ u->buffer_size = 0; + } + + static const char *usb_error_string(int err) +-- +2.35.3 + diff --git a/patches.suse/ALSA-usb-audio-Fix-potential-memory-leaks.patch b/patches.suse/ALSA-usb-audio-Fix-potential-memory-leaks.patch new file mode 100644 index 0000000..1366c96 --- /dev/null +++ b/patches.suse/ALSA-usb-audio-Fix-potential-memory-leaks.patch @@ -0,0 +1,49 @@ +From 6382da0828995af87aa8b8bef28cc61aceb4aff3 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Fri, 30 Sep 2022 12:01:51 +0200 +Subject: [PATCH] ALSA: usb-audio: Fix potential memory leaks +Git-commit: 6382da0828995af87aa8b8bef28cc61aceb4aff3 +Patch-mainline: v6.1-rc1 +References: git-fixes + +When the driver hits -ENOMEM at allocating a URB or a buffer, it +aborts and goes to the error path that releases the all previously +allocated resources. However, when -ENOMEM hits at the middle of the +sync EP URB allocation loop, the partially allocated URBs might be +left without released, because ep->nurbs is still zero at that point. + +Fix it by setting ep->nurbs at first, so that the error handler loops +over the full URB list. + +Cc: +Link: https://lore.kernel.org/r/20220930100151.19461-1-tiwai@suse.de +Signed-off-by: Takashi Iwai + +--- + sound/usb/endpoint.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c +index 36f753a28341..48a3843a08f1 100644 +--- a/sound/usb/endpoint.c ++++ b/sound/usb/endpoint.c +@@ -1268,6 +1268,7 @@ static int sync_ep_set_params(struct snd_usb_endpoint *ep) + if (!ep->syncbuf) + return -ENOMEM; + ++ ep->nurbs = SYNC_URBS; + for (i = 0; i < SYNC_URBS; i++) { + struct snd_urb_ctx *u = &ep->urb[i]; + u->index = i; +@@ -1287,8 +1288,6 @@ static int sync_ep_set_params(struct snd_usb_endpoint *ep) + u->urb->complete = snd_complete_urb; + } + +- ep->nurbs = SYNC_URBS; +- + return 0; + + out_of_memory: +-- +2.35.3 + diff --git a/patches.suse/ARM-Drop-CMDLINE_-dependency-on-ATAGS.patch b/patches.suse/ARM-Drop-CMDLINE_-dependency-on-ATAGS.patch new file mode 100644 index 0000000..04ac437 --- /dev/null +++ b/patches.suse/ARM-Drop-CMDLINE_-dependency-on-ATAGS.patch @@ -0,0 +1,45 @@ +From 136f4b1ec7c962ee37a787e095fd37b058d72bd3 Mon Sep 17 00:00:00 2001 +From: Geert Uytterhoeven +Date: Tue, 27 Sep 2022 15:28:26 +0200 +Subject: [PATCH] ARM: Drop CMDLINE_* dependency on ATAGS +Git-commit: 136f4b1ec7c962ee37a787e095fd37b058d72bd3 +Patch-mainline: v6.1-rc1 +References: git-fixes + +On arm32, the configuration options to specify the kernel command line +type depend on ATAGS. However, the actual CMDLINE cofiguration option +does not depend on ATAGS, and the code that handles this is not specific +to ATAGS (see drivers/of/fdt.c:early_init_dt_scan_chosen()). + +Hence users who desire to override the kernel command line on arm32 must +enable support for ATAGS, even on a pure-DT system. Other architectures +(arm64, loongarch, microblaze, nios2, powerpc, and riscv) do not impose +such a restriction. + +Hence drop the dependency on ATAGS. + +Fixes: bd51e2f595580fb6 ("ARM: 7506/1: allow for ATAGS to be configured out when DT support is selected") +Signed-off-by: Geert Uytterhoeven +Acked-by: Ard Biesheuvel +Signed-off-by: Arnd Bergmann +Acked-by: Takashi Iwai + +--- + arch/arm/Kconfig | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig +index ad808e92066e..22dc1d6936bc 100644 +--- a/arch/arm/Kconfig ++++ b/arch/arm/Kconfig +@@ -1599,7 +1599,6 @@ config CMDLINE + choice + prompt "Kernel command line type" if CMDLINE != "" + default CMDLINE_FROM_BOOTLOADER +- depends on ATAGS + + config CMDLINE_FROM_BOOTLOADER + bool "Use bootloader kernel arguments if available" +-- +2.35.3 + diff --git a/patches.suse/ARM-defconfig-clean-up-multi_v4t-and-multi_v5-config.patch b/patches.suse/ARM-defconfig-clean-up-multi_v4t-and-multi_v5-config.patch new file mode 100644 index 0000000..727a5b0 --- /dev/null +++ b/patches.suse/ARM-defconfig-clean-up-multi_v4t-and-multi_v5-config.patch @@ -0,0 +1,51 @@ +From d11277c35e1a2a3a4ace05d1a4f79eee92b76a2f Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Thu, 11 Aug 2022 16:14:13 +0200 +Subject: [PATCH] ARM: defconfig: clean up multi_v4t and multi_v5 configs +Git-commit: d11277c35e1a2a3a4ace05d1a4f79eee92b76a2f +Patch-mainline: v6.1-rc1 +References: git-fixes + +Integrator now selects the regulators and versatile selects the +reset driver, so the correspondig options can be dropped from +the defconfig files. + +Fixes: d2854bbe5f5c ("ARM: integrator: Add some Kconfig selections") +Fixes: 1c6e288da6cc ("ARM: versatile: move restart to the device tree") +Reviewed-by: Linus Walleij +Signed-off-by: Arnd Bergmann +Acked-by: Takashi Iwai + +--- + arch/arm/configs/multi_v4t_defconfig | 2 -- + arch/arm/configs/multi_v5_defconfig | 1 - + 2 files changed, 3 deletions(-) + +diff --git a/arch/arm/configs/multi_v4t_defconfig b/arch/arm/configs/multi_v4t_defconfig +index 6c3e45b71ab5..e2fd822f741a 100644 +--- a/arch/arm/configs/multi_v4t_defconfig ++++ b/arch/arm/configs/multi_v4t_defconfig +@@ -71,8 +71,6 @@ CONFIG_POWER_RESET_SYSCON_POWEROFF=y + CONFIG_WATCHDOG=y + CONFIG_GPIO_WATCHDOG=y + CONFIG_AT91RM9200_WATCHDOG=y +-CONFIG_REGULATOR=y +-CONFIG_REGULATOR_FIXED_VOLTAGE=y + CONFIG_REGULATOR_GPIO=y + CONFIG_FB=y + CONFIG_FB_CLPS711X=y +diff --git a/arch/arm/configs/multi_v5_defconfig b/arch/arm/configs/multi_v5_defconfig +index 5f3ed81228b0..a65f32a78885 100644 +--- a/arch/arm/configs/multi_v5_defconfig ++++ b/arch/arm/configs/multi_v5_defconfig +@@ -149,7 +149,6 @@ CONFIG_SPI_SUN6I=y + CONFIG_GPIO_ASPEED=m + CONFIG_GPIO_ASPEED_SGPIO=y + CONFIG_GPIO_MXC=y +-CONFIG_POWER_RESET=y + CONFIG_POWER_RESET_GPIO=y + CONFIG_POWER_RESET_QNAP=y + CONFIG_SENSORS_ADT7475=y +-- +2.35.3 + diff --git a/patches.suse/ARM-defconfig-drop-CONFIG_PTP_1588_CLOCK-y.patch b/patches.suse/ARM-defconfig-drop-CONFIG_PTP_1588_CLOCK-y.patch new file mode 100644 index 0000000..06aadad --- /dev/null +++ b/patches.suse/ARM-defconfig-drop-CONFIG_PTP_1588_CLOCK-y.patch @@ -0,0 +1,53 @@ +From 39916e7d40e8dc9eca904e0b3e190753fa945ead Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Thu, 11 Aug 2022 16:29:25 +0200 +Subject: [PATCH] ARM: defconfig: drop CONFIG_PTP_1588_CLOCK=y +Git-commit: 39916e7d40e8dc9eca904e0b3e190753fa945ead +Patch-mainline: v6.1-rc1 +References: git-fixes + +PTP support is now enabled by default for configurations with +ethernet support, so drop the redundant entries in defconfig +files. + +Fixes: e5f31552674e ("ethernet: fix PTP_1588_CLOCK dependencies") +Acked-by: Richard Cochran +Signed-off-by: Arnd Bergmann +Acked-by: Takashi Iwai + +--- + arch/arm/configs/keystone_defconfig | 1 - + arch/arm/configs/multi_v7_defconfig | 1 - + arch/arm/configs/omap2plus_defconfig | 1 - + 3 files changed, 3 deletions(-) + +--- a/arch/arm/configs/keystone_defconfig ++++ b/arch/arm/configs/keystone_defconfig +@@ -146,7 +146,6 @@ CONFIG_I2C_DAVINCI=y + CONFIG_SPI=y + CONFIG_SPI_DAVINCI=y + CONFIG_SPI_SPIDEV=y +-CONFIG_PTP_1588_CLOCK=y + CONFIG_PINCTRL_SINGLE=y + CONFIG_GPIOLIB=y + CONFIG_GPIO_SYSFS=y +--- a/arch/arm/configs/multi_v7_defconfig ++++ b/arch/arm/configs/multi_v7_defconfig +@@ -445,7 +445,6 @@ CONFIG_SPI_TEGRA20_SLINK=y + CONFIG_SPI_XILINX=y + CONFIG_SPI_SPIDEV=y + CONFIG_SPMI=y +-CONFIG_PTP_1588_CLOCK=y + CONFIG_PINCTRL_AS3722=y + CONFIG_PINCTRL_RZA2=y + CONFIG_PINCTRL_STMFX=y +--- a/arch/arm/configs/omap2plus_defconfig ++++ b/arch/arm/configs/omap2plus_defconfig +@@ -428,7 +428,6 @@ CONFIG_SPI_TI_QSPI=m + CONFIG_HSI=m + CONFIG_OMAP_SSI=m + CONFIG_SSI_PROTOCOL=m +-CONFIG_PTP_1588_CLOCK=y + CONFIG_PINCTRL_SINGLE=y + CONFIG_DEBUG_GPIO=y + CONFIG_GPIO_SYSFS=y diff --git a/patches.suse/ARM-defconfig-drop-CONFIG_SERIAL_OMAP-references.patch b/patches.suse/ARM-defconfig-drop-CONFIG_SERIAL_OMAP-references.patch new file mode 100644 index 0000000..0628fd0 --- /dev/null +++ b/patches.suse/ARM-defconfig-drop-CONFIG_SERIAL_OMAP-references.patch @@ -0,0 +1,52 @@ +From 1c9cb2bbf7ceee7fbebcecfc0d3c951d938731e7 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Thu, 11 Aug 2022 16:22:35 +0200 +Subject: [PATCH] ARM: defconfig: drop CONFIG_SERIAL_OMAP references +Git-commit: 1c9cb2bbf7ceee7fbebcecfc0d3c951d938731e7 +Patch-mainline: v6.1-rc1 +References: git-fixes + +This driver is mutually exclusive with the new 8250_OMAP +driver, so 'make defconfig' turns it off already. Drop +the reference now. + +Fixes: 077e1cde78c3 ("ARM: omap2plus_defconfig: Enable 8250_OMAP") +Fixes: f98d45145e6a ("ARM: multi_v7_defconfig: Enable 8250-omap serial driver and use it by default") +Acked-by: Tony Lindgren +Signed-off-by: Arnd Bergmann +Acked-by: Takashi Iwai + +--- + arch/arm/configs/multi_v7_defconfig | 2 -- + arch/arm/configs/omap2plus_defconfig | 2 -- + 2 files changed, 4 deletions(-) + +diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig +index ecf743b3409d..4cfe795981c8 100644 +--- a/arch/arm/configs/multi_v7_defconfig ++++ b/arch/arm/configs/multi_v7_defconfig +@@ -377,8 +377,6 @@ CONFIG_SERIAL_MSM=y + CONFIG_SERIAL_MSM_CONSOLE=y + CONFIG_SERIAL_VT8500=y + CONFIG_SERIAL_VT8500_CONSOLE=y +-CONFIG_SERIAL_OMAP=y +-CONFIG_SERIAL_OMAP_CONSOLE=y + CONFIG_SERIAL_BCM63XX=y + CONFIG_SERIAL_BCM63XX_CONSOLE=y + CONFIG_SERIAL_XILINX_PS_UART=y +diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig +index e273365838cb..89cda0877c52 100644 +--- a/arch/arm/configs/omap2plus_defconfig ++++ b/arch/arm/configs/omap2plus_defconfig +@@ -419,8 +419,6 @@ CONFIG_SERIAL_8250_DETECT_IRQ=y + CONFIG_SERIAL_8250_RSA=y + CONFIG_SERIAL_8250_OMAP=y + CONFIG_SERIAL_OF_PLATFORM=y +-CONFIG_SERIAL_OMAP=y +-CONFIG_SERIAL_OMAP_CONSOLE=y + CONFIG_SERIAL_DEV_BUS=y + CONFIG_I2C_CHARDEV=y + CONFIG_SPI=y +-- +2.35.3 + diff --git a/patches.suse/ARM-defconfig-drop-CONFIG_USB_FSL_USB2.patch b/patches.suse/ARM-defconfig-drop-CONFIG_USB_FSL_USB2.patch new file mode 100644 index 0000000..3180a30 --- /dev/null +++ b/patches.suse/ARM-defconfig-drop-CONFIG_USB_FSL_USB2.patch @@ -0,0 +1,35 @@ +From 1bc709eb315f58b5231c8f0137c73d2bdabca9cf Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Thu, 11 Aug 2022 17:33:02 +0200 +Subject: [PATCH] ARM: defconfig: drop CONFIG_USB_FSL_USB2 +Git-commit: 1bc709eb315f58b5231c8f0137c73d2bdabca9cf +Patch-mainline: v6.1-rc1 +References: git-fixes + +USB_FSL_USB2 is no longer available for Arm platforms and +was replaced by the chipidea driver. + +Fixes: a390bef7db1f ("usb: gadget: fsl_mxc_udc: Remove the driver") +Acked-by: Greg Kroah-Hartman +Signed-off-by: Arnd Bergmann +Acked-by: Takashi Iwai + +--- + arch/arm/configs/multi_v7_defconfig | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig +index 7af627a816ec..1cb293adecb1 100644 +--- a/arch/arm/configs/multi_v7_defconfig ++++ b/arch/arm/configs/multi_v7_defconfig +@@ -869,7 +869,6 @@ CONFIG_USB_GPIO_VBUS=y + CONFIG_USB_ISP1301=y + CONFIG_USB_MXS_PHY=y + CONFIG_USB_GADGET=y +-CONFIG_USB_FSL_USB2=y + CONFIG_USB_RENESAS_USBHS_UDC=m + CONFIG_USB_ASPEED_VHUB=m + CONFIG_USB_CONFIGFS=m +-- +2.35.3 + diff --git a/patches.suse/ARM-dts-am33xx-Fix-MMCHS0-dma-properties.patch b/patches.suse/ARM-dts-am33xx-Fix-MMCHS0-dma-properties.patch new file mode 100644 index 0000000..e90291a --- /dev/null +++ b/patches.suse/ARM-dts-am33xx-Fix-MMCHS0-dma-properties.patch @@ -0,0 +1,39 @@ +From 2eb502f496f7764027b7958d4e74356fed918059 Mon Sep 17 00:00:00 2001 +From: YuTong Chang +Date: Mon, 20 Jun 2022 05:41:46 -0700 +Subject: [PATCH] ARM: dts: am33xx: Fix MMCHS0 dma properties +Git-commit: 2eb502f496f7764027b7958d4e74356fed918059 +Patch-mainline: v6.0 +References: git-fixes + +According to technical manual(table 11-24), the DMA of MMCHS0 should be +direct mapped. + +Fixes: b5e509066074 ("ARM: DTS: am33xx: Use the new DT bindings for the eDMA3") +Signed-off-by: YuTong Chang +Message-id: <20220620124146.5330-1-mtwget@gmail.com> +Acked-by: Krzysztof Kozlowski +Signed-off-by: Tony Lindgren +Acked-by: Takashi Iwai + +--- + arch/arm/boot/dts/am33xx-l4.dtsi | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/arch/arm/boot/dts/am33xx-l4.dtsi b/arch/arm/boot/dts/am33xx-l4.dtsi +index 7da42a5b959c..7e50fe633d8a 100644 +--- a/arch/arm/boot/dts/am33xx-l4.dtsi ++++ b/arch/arm/boot/dts/am33xx-l4.dtsi +@@ -1502,8 +1502,7 @@ SYSC_OMAP2_SOFTRESET | + mmc1: mmc@0 { + compatible = "ti,am335-sdhci"; + ti,needs-special-reset; +- dmas = <&edma_xbar 24 0 0 +- &edma_xbar 25 0 0>; ++ dmas = <&edma 24 0>, <&edma 25 0>; + dma-names = "tx", "rx"; + interrupts = <64>; + reg = <0x0 0x1000>; +-- +2.35.3 + diff --git a/patches.suse/ARM-dts-armada-38x-Add-gpio-ranges-for-pin-muxing.patch b/patches.suse/ARM-dts-armada-38x-Add-gpio-ranges-for-pin-muxing.patch new file mode 100644 index 0000000..2b3c889 --- /dev/null +++ b/patches.suse/ARM-dts-armada-38x-Add-gpio-ranges-for-pin-muxing.patch @@ -0,0 +1,45 @@ +From 467b43a944b3c7810b600a0adc409be74ee1b8d0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= +Date: Wed, 27 Jul 2022 15:16:19 +0200 +Subject: [PATCH] ARM: dts: armada-38x: Add gpio-ranges for pin muxing +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 467b43a944b3c7810b600a0adc409be74ee1b8d0 +Patch-mainline: v6.1-rc1 +References: git-fixes + +GPIOs are configured by pinmux driver, so add corresponding references. + +Fixes: 0d3d96ab0059 ("ARM: mvebu: add Device Tree description of the Armada 380/385 SoCs") +Signed-off-by: Pali Rohár +Signed-off-by: Gregory CLEMENT +Acked-by: Takashi Iwai + +--- + arch/arm/boot/dts/armada-38x.dtsi | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi +index df3c8d1d8f64..a40a70e70458 100644 +--- a/arch/arm/boot/dts/armada-38x.dtsi ++++ b/arch/arm/boot/dts/armada-38x.dtsi +@@ -298,6 +298,7 @@ gpio0: gpio@18100 { + reg-names = "gpio", "pwm"; + ngpios = <32>; + gpio-controller; ++ gpio-ranges = <&pinctrl 0 0 32>; + #gpio-cells = <2>; + #pwm-cells = <2>; + interrupt-controller; +@@ -316,6 +317,7 @@ gpio1: gpio@18140 { + reg-names = "gpio", "pwm"; + ngpios = <28>; + gpio-controller; ++ gpio-ranges = <&pinctrl 0 32 28>; + #gpio-cells = <2>; + #pwm-cells = <2>; + interrupt-controller; +-- +2.35.3 + diff --git a/patches.suse/ARM-dts-exynos-correct-s5k6a3-reset-polarity-on-Mida.patch b/patches.suse/ARM-dts-exynos-correct-s5k6a3-reset-polarity-on-Mida.patch new file mode 100644 index 0000000..ad59c68 --- /dev/null +++ b/patches.suse/ARM-dts-exynos-correct-s5k6a3-reset-polarity-on-Mida.patch @@ -0,0 +1,42 @@ +From 3ba2d4bb9592bf7a6a3fe3dbe711ecfc3d004bab Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Mon, 26 Sep 2022 12:43:53 +0200 +Subject: [PATCH] ARM: dts: exynos: correct s5k6a3 reset polarity on Midas family +Git-commit: 3ba2d4bb9592bf7a6a3fe3dbe711ecfc3d004bab +Patch-mainline: v6.1-rc1 +References: git-fixes + +According to s5k6a3 driver code, the reset line for the chip appears to +be active low. This also matches the typical polarity of reset lines in +general. Let's fix it up as having correct polarity in DTS is important +when the driver will be switched over to gpiod API. + +Fixes: b4fec64758ab ("ARM: dts: Add camera device nodes for Exynos4412 TRATS2 board") +Signed-off-by: Dmitry Torokhov +Signed-off-by: Krzysztof Kozlowski +Reviewed-by: Linus Walleij +Link: https://lore.kernel.org/r/20220913164104.203957-1-dmitry.torokhov@gmail.com +Link: https://lore.kernel.org/r/20220926104354.118578-2-krzysztof.kozlowski@linaro.org' +Signed-off-by: Arnd Bergmann +Acked-by: Takashi Iwai + +--- + arch/arm/boot/dts/exynos4412-midas.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/exynos4412-midas.dtsi b/arch/arm/boot/dts/exynos4412-midas.dtsi +index b967397a46c5..8e1c19a8ad06 100644 +--- a/arch/arm/boot/dts/exynos4412-midas.dtsi ++++ b/arch/arm/boot/dts/exynos4412-midas.dtsi +@@ -586,7 +586,7 @@ image-sensor@10 { + clocks = <&camera 1>; + clock-names = "extclk"; + samsung,camclk-out = <1>; +- gpios = <&gpm1 6 GPIO_ACTIVE_HIGH>; ++ gpios = <&gpm1 6 GPIO_ACTIVE_LOW>; + + port { + is_s5k6a3_ep: endpoint { +-- +2.35.3 + diff --git a/patches.suse/ARM-dts-exynos-fix-polarity-of-VBUS-GPIO-of-Origen.patch b/patches.suse/ARM-dts-exynos-fix-polarity-of-VBUS-GPIO-of-Origen.patch new file mode 100644 index 0000000..d26448b --- /dev/null +++ b/patches.suse/ARM-dts-exynos-fix-polarity-of-VBUS-GPIO-of-Origen.patch @@ -0,0 +1,39 @@ +From a08137bd1e0a7ce951dce9ce4a83e39d379b6e1b Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Tue, 27 Sep 2022 15:05:03 -0700 +Subject: [PATCH] ARM: dts: exynos: fix polarity of VBUS GPIO of Origen +Git-commit: a08137bd1e0a7ce951dce9ce4a83e39d379b6e1b +Patch-mainline: v6.1-rc1 +References: git-fixes + +EHCI Oxynos (drivers/usb/host/ehci-exynos.c) drives VBUS GPIO high when +trying to power up the bus, therefore the GPIO in DTS must be marked as +"active high". This will be important when EHCI driver is converted to +gpiod API that respects declared polarities. + +Fixes: 4e8991def565 ("ARM: dts: exynos: Enable AX88760 USB hub on Origen board") +Signed-off-by: Dmitry Torokhov +Link: https://lore.kernel.org/r/20220927220504.3744878-1-dmitry.torokhov@gmail.com +Signed-off-by: Krzysztof Kozlowski +Acked-by: Takashi Iwai + +--- + arch/arm/boot/dts/exynos4412-origen.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/exynos4412-origen.dts b/arch/arm/boot/dts/exynos4412-origen.dts +index 6db09dba07ff..a3905e27b9cd 100644 +--- a/arch/arm/boot/dts/exynos4412-origen.dts ++++ b/arch/arm/boot/dts/exynos4412-origen.dts +@@ -95,7 +95,7 @@ &exynos_usbphy { + }; + + &ehci { +- samsung,vbus-gpio = <&gpx3 5 1>; ++ samsung,vbus-gpio = <&gpx3 5 GPIO_ACTIVE_HIGH>; + status = "okay"; + phys = <&exynos_usbphy 2>, <&exynos_usbphy 3>; + phy-names = "hsic0", "hsic1"; +-- +2.35.3 + diff --git a/patches.suse/ARM-dts-fix-Moxa-SDIO-compatible-remove-sdhci-misnom.patch b/patches.suse/ARM-dts-fix-Moxa-SDIO-compatible-remove-sdhci-misnom.patch new file mode 100644 index 0000000..a2ccdca --- /dev/null +++ b/patches.suse/ARM-dts-fix-Moxa-SDIO-compatible-remove-sdhci-misnom.patch @@ -0,0 +1,77 @@ +From 02181e68275d28cab3c3f755852770367f1bc229 Mon Sep 17 00:00:00 2001 +From: Sergei Antonov +Date: Wed, 7 Sep 2022 20:53:41 +0300 +Subject: [PATCH] ARM: dts: fix Moxa SDIO 'compatible', remove 'sdhci' misnomer +Git-commit: 02181e68275d28cab3c3f755852770367f1bc229 +Patch-mainline: v6.0-rc7 +References: git-fixes + +Driver moxart-mmc.c has .compatible = "moxa,moxart-mmc". + +But moxart .dts/.dtsi and the documentation file moxa,moxart-dma.txt +contain compatible = "moxa,moxart-sdhci". + +Change moxart .dts/.dtsi files and moxa,moxart-dma.txt to match the driver. + +Replace 'sdhci' with 'mmc' in names too, since SDHCI is a different +controller from FTSDC010. + +Suggested-by: Arnd Bergmann +Signed-off-by: Sergei Antonov +Cc: Jonas Jensen +Link: https://lore.kernel.org/r/20220907175341.1477383-1-saproj@gmail.com' +Signed-off-by: Arnd Bergmann +Acked-by: Takashi Iwai + +--- + Documentation/devicetree/bindings/dma/moxa,moxart-dma.txt | 4 ++-- + arch/arm/boot/dts/moxart-uc7112lx.dts | 2 +- + arch/arm/boot/dts/moxart.dtsi | 4 ++-- + 3 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/Documentation/devicetree/bindings/dma/moxa,moxart-dma.txt b/Documentation/devicetree/bindings/dma/moxa,moxart-dma.txt +index 8a9f3559335b..7e14e26676ec 100644 +--- a/Documentation/devicetree/bindings/dma/moxa,moxart-dma.txt ++++ b/Documentation/devicetree/bindings/dma/moxa,moxart-dma.txt +@@ -34,8 +34,8 @@ Example: + Use specific request line passing from dma + For example, MMC request line is 5 + +- sdhci: sdhci@98e00000 { +- compatible = "moxa,moxart-sdhci"; ++ mmc: mmc@98e00000 { ++ compatible = "moxa,moxart-mmc"; + reg = <0x98e00000 0x5C>; + interrupts = <5 0>; + clocks = <&clk_apb>; +diff --git a/arch/arm/boot/dts/moxart-uc7112lx.dts b/arch/arm/boot/dts/moxart-uc7112lx.dts +index eb5291b0ee3a..e07b807b4cec 100644 +--- a/arch/arm/boot/dts/moxart-uc7112lx.dts ++++ b/arch/arm/boot/dts/moxart-uc7112lx.dts +@@ -79,7 +79,7 @@ &clk_pll { + clocks = <&ref12>; + }; + +-&sdhci { ++&mmc { + status = "okay"; + }; + +diff --git a/arch/arm/boot/dts/moxart.dtsi b/arch/arm/boot/dts/moxart.dtsi +index f5f070a87482..764832ddfa78 100644 +--- a/arch/arm/boot/dts/moxart.dtsi ++++ b/arch/arm/boot/dts/moxart.dtsi +@@ -93,8 +93,8 @@ watchdog: watchdog@98500000 { + clock-names = "PCLK"; + }; + +- sdhci: sdhci@98e00000 { +- compatible = "moxa,moxart-sdhci"; ++ mmc: mmc@98e00000 { ++ compatible = "moxa,moxart-mmc"; + reg = <0x98e00000 0x5C>; + interrupts = <5 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk_apb>; +-- +2.35.3 + diff --git a/patches.suse/ARM-dts-imx-align-SPI-NOR-node-name-with-dtschema.patch b/patches.suse/ARM-dts-imx-align-SPI-NOR-node-name-with-dtschema.patch new file mode 100644 index 0000000..0b626d2 --- /dev/null +++ b/patches.suse/ARM-dts-imx-align-SPI-NOR-node-name-with-dtschema.patch @@ -0,0 +1,486 @@ +From ba9fe460dc2cfe90dc115b22af14dd3f13cffa0f Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +Date: Thu, 7 Apr 2022 16:31:54 +0200 +Subject: [PATCH] ARM: dts: imx: align SPI NOR node name with dtschema +Git-commit: ba9fe460dc2cfe90dc115b22af14dd3f13cffa0f +Patch-mainline: v5.19-rc1 +References: git-fixes + +The node names should be generic and SPI NOR dtschema expects "flash". + +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Shawn Guo +Acked-by: Takashi Iwai + +--- + arch/arm/boot/dts/imx28-evk.dts | 2 +- + arch/arm/boot/dts/imx28-m28evk.dts | 2 +- + arch/arm/boot/dts/imx28-sps1.dts | 2 +- + arch/arm/boot/dts/imx6dl-rex-basic.dts | 2 +- + arch/arm/boot/dts/imx6q-ba16.dtsi | 2 +- + arch/arm/boot/dts/imx6q-bx50v3.dtsi | 2 +- + arch/arm/boot/dts/imx6q-cm-fx6.dts | 2 +- + arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts | 2 +- + arch/arm/boot/dts/imx6q-dms-ba16.dts | 2 +- + arch/arm/boot/dts/imx6q-gw5400-a.dts | 2 +- + arch/arm/boot/dts/imx6q-marsboard.dts | 2 +- + arch/arm/boot/dts/imx6q-rex-pro.dts | 2 +- + arch/arm/boot/dts/imx6qdl-aristainetos.dtsi | 2 +- + arch/arm/boot/dts/imx6qdl-aristainetos2.dtsi | 2 +- + arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi | 2 +- + arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi | 2 +- + arch/arm/boot/dts/imx6qdl-nit6xlite.dtsi | 2 +- + arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi | 2 +- + arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi | 2 +- + arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi | 2 +- + arch/arm/boot/dts/imx6qdl-sabreauto.dtsi | 2 +- + arch/arm/boot/dts/imx6qdl-sabrelite.dtsi | 2 +- + arch/arm/boot/dts/imx6qdl-sabresd.dtsi | 2 +- + arch/arm/boot/dts/imx6sl-evk.dts | 2 +- + arch/arm/boot/dts/imx6sx-nitrogen6sx.dts | 2 +- + arch/arm/boot/dts/imx6sx-sdb-reva.dts | 4 ++-- + arch/arm/boot/dts/imx6sx-sdb.dts | 4 ++-- + arch/arm/boot/dts/imx6ul-14x14-evk.dtsi | 2 +- + arch/arm/boot/dts/imx6ul-kontron-n6310-som.dtsi | 2 +- + arch/arm/boot/dts/imx6ul-kontron-n6311-som.dtsi | 2 +- + arch/arm/boot/dts/imx6ul-kontron-n6x1x-som-common.dtsi | 2 +- + arch/arm/boot/dts/imx6ull-kontron-n6411-som.dtsi | 2 +- + 32 files changed, 34 insertions(+), 34 deletions(-) + +diff --git a/arch/arm/boot/dts/imx28-evk.dts b/arch/arm/boot/dts/imx28-evk.dts +index 7e2b0f198dfa..1053b7c584d8 100644 +--- a/arch/arm/boot/dts/imx28-evk.dts ++++ b/arch/arm/boot/dts/imx28-evk.dts +@@ -129,7 +129,7 @@ ssp2: spi@80014000 { + pinctrl-0 = <&spi2_pins_a>; + status = "okay"; + +- flash: m25p80@0 { ++ flash: flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "sst,sst25vf016b", "jedec,spi-nor"; +diff --git a/arch/arm/boot/dts/imx28-m28evk.dts b/arch/arm/boot/dts/imx28-m28evk.dts +index f3bddc5ada4b..13acdc7916b9 100644 +--- a/arch/arm/boot/dts/imx28-m28evk.dts ++++ b/arch/arm/boot/dts/imx28-m28evk.dts +@@ -33,7 +33,7 @@ ssp2: spi@80014000 { + pinctrl-0 = <&spi2_pins_a>; + status = "okay"; + +- flash: m25p80@0 { ++ flash: flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "m25p80", "jedec,spi-nor"; +diff --git a/arch/arm/boot/dts/imx28-sps1.dts b/arch/arm/boot/dts/imx28-sps1.dts +index 43be7a6a769b..90928db0df70 100644 +--- a/arch/arm/boot/dts/imx28-sps1.dts ++++ b/arch/arm/boot/dts/imx28-sps1.dts +@@ -51,7 +51,7 @@ ssp2: spi@80014000 { + pinctrl-0 = <&spi2_pins_a>; + status = "okay"; + +- flash: m25p80@0 { ++ flash: flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "everspin,mr25h256", "mr25h256"; +diff --git a/arch/arm/boot/dts/imx6dl-rex-basic.dts b/arch/arm/boot/dts/imx6dl-rex-basic.dts +index 0f1616bfa9a8..b72f8ea1e6f6 100644 +--- a/arch/arm/boot/dts/imx6dl-rex-basic.dts ++++ b/arch/arm/boot/dts/imx6dl-rex-basic.dts +@@ -19,7 +19,7 @@ memory@10000000 { + }; + + &ecspi3 { +- flash: m25p80@0 { ++ flash: flash@0 { + compatible = "sst,sst25vf016b", "jedec,spi-nor"; + spi-max-frequency = <20000000>; + reg = <0>; +diff --git a/arch/arm/boot/dts/imx6q-ba16.dtsi b/arch/arm/boot/dts/imx6q-ba16.dtsi +index 6330d75f8f39..f266f1b7e0cf 100644 +--- a/arch/arm/boot/dts/imx6q-ba16.dtsi ++++ b/arch/arm/boot/dts/imx6q-ba16.dtsi +@@ -142,7 +142,7 @@ &ecspi1 { + pinctrl-0 = <&pinctrl_ecspi1>; + status = "okay"; + +- flash: n25q032@0 { ++ flash: flash@0 { + compatible = "jedec,spi-nor"; + #address-cells = <1>; + #size-cells = <1>; +diff --git a/arch/arm/boot/dts/imx6q-bx50v3.dtsi b/arch/arm/boot/dts/imx6q-bx50v3.dtsi +index 10922375c51e..ead83091e193 100644 +--- a/arch/arm/boot/dts/imx6q-bx50v3.dtsi ++++ b/arch/arm/boot/dts/imx6q-bx50v3.dtsi +@@ -160,7 +160,7 @@ &ecspi5 { + pinctrl-0 = <&pinctrl_ecspi5>; + status = "okay"; + +- m25_eeprom: m25p80@0 { ++ m25_eeprom: flash@0 { + compatible = "atmel,at25"; + spi-max-frequency = <10000000>; + size = <0x8000>; +diff --git a/arch/arm/boot/dts/imx6q-cm-fx6.dts b/arch/arm/boot/dts/imx6q-cm-fx6.dts +index bfb530f29d9d..1ad41c944b4b 100644 +--- a/arch/arm/boot/dts/imx6q-cm-fx6.dts ++++ b/arch/arm/boot/dts/imx6q-cm-fx6.dts +@@ -260,7 +260,7 @@ &ecspi1 { + pinctrl-0 = <&pinctrl_ecspi1>; + status = "okay"; + +- m25p80@0 { ++ flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "st,m25p", "jedec,spi-nor"; +diff --git a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts +index c713ac03b3b9..9591848cbd37 100644 +--- a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts ++++ b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts +@@ -102,7 +102,7 @@ &ecspi5 { + cs-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>; + status = "okay"; + +- flash: m25p80@0 { ++ flash: flash@0 { + compatible = "m25p80", "jedec,spi-nor"; + spi-max-frequency = <40000000>; + reg = <0>; +diff --git a/arch/arm/boot/dts/imx6q-dms-ba16.dts b/arch/arm/boot/dts/imx6q-dms-ba16.dts +index 48fb47e715f6..137db38f0d27 100644 +--- a/arch/arm/boot/dts/imx6q-dms-ba16.dts ++++ b/arch/arm/boot/dts/imx6q-dms-ba16.dts +@@ -47,7 +47,7 @@ &ecspi5 { + pinctrl-0 = <&pinctrl_ecspi5>; + status = "okay"; + +- m25_eeprom: m25p80@0 { ++ m25_eeprom: flash@0 { + compatible = "atmel,at25256B", "atmel,at25"; + spi-max-frequency = <20000000>; + size = <0x8000>; +diff --git a/arch/arm/boot/dts/imx6q-gw5400-a.dts b/arch/arm/boot/dts/imx6q-gw5400-a.dts +index 4cde45d5c90c..e894faba571f 100644 +--- a/arch/arm/boot/dts/imx6q-gw5400-a.dts ++++ b/arch/arm/boot/dts/imx6q-gw5400-a.dts +@@ -137,7 +137,7 @@ &ecspi1 { + pinctrl-0 = <&pinctrl_ecspi1>; + status = "okay"; + +- flash: m25p80@0 { ++ flash: flash@0 { + compatible = "sst,w25q256", "jedec,spi-nor"; + spi-max-frequency = <30000000>; + reg = <0>; +diff --git a/arch/arm/boot/dts/imx6q-marsboard.dts b/arch/arm/boot/dts/imx6q-marsboard.dts +index 05ee28388229..cc1801002394 100644 +--- a/arch/arm/boot/dts/imx6q-marsboard.dts ++++ b/arch/arm/boot/dts/imx6q-marsboard.dts +@@ -100,7 +100,7 @@ &ecspi1 { + cs-gpios = <&gpio2 30 GPIO_ACTIVE_LOW>; + status = "okay"; + +- m25p80@0 { ++ flash@0 { + compatible = "microchip,sst25vf016b"; + spi-max-frequency = <20000000>; + reg = <0>; +diff --git a/arch/arm/boot/dts/imx6q-rex-pro.dts b/arch/arm/boot/dts/imx6q-rex-pro.dts +index 1767e1a3cd53..271f4b2d9b9f 100644 +--- a/arch/arm/boot/dts/imx6q-rex-pro.dts ++++ b/arch/arm/boot/dts/imx6q-rex-pro.dts +@@ -19,7 +19,7 @@ memory@10000000 { + }; + + &ecspi3 { +- flash: m25p80@0 { ++ flash: flash@0 { + compatible = "sst,sst25vf032b", "jedec,spi-nor"; + spi-max-frequency = <20000000>; + reg = <0>; +diff --git a/arch/arm/boot/dts/imx6qdl-aristainetos.dtsi b/arch/arm/boot/dts/imx6qdl-aristainetos.dtsi +index e21f6ac864e5..baa197c90060 100644 +--- a/arch/arm/boot/dts/imx6qdl-aristainetos.dtsi ++++ b/arch/arm/boot/dts/imx6qdl-aristainetos.dtsi +@@ -96,7 +96,7 @@ &ecspi4 { + pinctrl-0 = <&pinctrl_ecspi4>; + status = "okay"; + +- flash: m25p80@0 { ++ flash: flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "micron,n25q128a11", "jedec,spi-nor"; +diff --git a/arch/arm/boot/dts/imx6qdl-aristainetos2.dtsi b/arch/arm/boot/dts/imx6qdl-aristainetos2.dtsi +index 563bf9d44fe0..2ba577e602e7 100644 +--- a/arch/arm/boot/dts/imx6qdl-aristainetos2.dtsi ++++ b/arch/arm/boot/dts/imx6qdl-aristainetos2.dtsi +@@ -131,7 +131,7 @@ &ecspi4 { + pinctrl-0 = <&pinctrl_ecspi4>; + status = "okay"; + +- flash: m25p80@1 { ++ flash: flash@1 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "micron,n25q128a11", "jedec,spi-nor"; +diff --git a/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi b/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi +index 648f5fcb72e6..2c1d6f28e695 100644 +--- a/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi ++++ b/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi +@@ -35,7 +35,7 @@ &ecspi3 { + pinctrl-0 = <&pinctrl_ecspi3>; + status = "okay"; + +- flash: m25p80@0 { ++ flash: flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "sst,sst25vf040b", "jedec,spi-nor"; +diff --git a/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi b/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi +index b167b33bd108..095c9143d99a 100644 +--- a/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi ++++ b/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi +@@ -258,7 +258,7 @@ &ecspi4 { + status = "okay"; + + /* default boot source: workaround #1 for errata ERR006282 */ +- smarc_flash: spi-flash@0 { ++ smarc_flash: flash@0 { + compatible = "winbond,w25q16dw", "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <20000000>; +diff --git a/arch/arm/boot/dts/imx6qdl-nit6xlite.dtsi b/arch/arm/boot/dts/imx6qdl-nit6xlite.dtsi +index ac34709e9741..0ad4cb4f1e82 100644 +--- a/arch/arm/boot/dts/imx6qdl-nit6xlite.dtsi ++++ b/arch/arm/boot/dts/imx6qdl-nit6xlite.dtsi +@@ -179,7 +179,7 @@ &ecspi1 { + pinctrl-0 = <&pinctrl_ecspi1>; + status = "okay"; + +- flash: m25p80@0 { ++ flash: flash@0 { + compatible = "microchip,sst25vf016b"; + spi-max-frequency = <20000000>; + reg = <0>; +diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi +index c96f4d7e1e0d..beaa2dcd436c 100644 +--- a/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi ++++ b/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi +@@ -321,7 +321,7 @@ &ecspi1 { + pinctrl-0 = <&pinctrl_ecspi1>; + status = "okay"; + +- flash: m25p80@0 { ++ flash: flash@0 { + compatible = "microchip,sst25vf016b"; + spi-max-frequency = <20000000>; + reg = <0>; +diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi +index 92d09a3ebe0e..ee7e2371f94b 100644 +--- a/arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi ++++ b/arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi +@@ -252,7 +252,7 @@ &ecspi1 { + pinctrl-0 = <&pinctrl_ecspi1>; + status = "okay"; + +- flash: m25p80@0 { ++ flash: flash@0 { + compatible = "microchip,sst25vf016b"; + spi-max-frequency = <20000000>; + reg = <0>; +diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi +index 49da30d7510c..904d5d051d63 100644 +--- a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi ++++ b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi +@@ -237,7 +237,7 @@ &ecspi1 { + pinctrl-0 = <&pinctrl_ecspi1>; + status = "okay"; + +- flash: m25p80@0 { ++ flash: flash@0 { + compatible = "sst,sst25vf016b", "jedec,spi-nor"; + spi-max-frequency = <20000000>; + reg = <0>; +diff --git a/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi b/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi +index 5e58740d40c5..1368a4762037 100644 +--- a/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi ++++ b/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi +@@ -272,7 +272,7 @@ &ecspi1 { + pinctrl-0 = <&pinctrl_ecspi1 &pinctrl_ecspi1_cs>; + status = "disabled"; /* pin conflict with WEIM NOR */ + +- flash: m25p80@0 { ++ flash: flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "st,m25p32", "jedec,spi-nor"; +diff --git a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi +index eb9a0b104f1c..901b9a761b66 100644 +--- a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi ++++ b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi +@@ -313,7 +313,7 @@ &ecspi1 { + pinctrl-0 = <&pinctrl_ecspi1>; + status = "okay"; + +- flash: m25p80@0 { ++ flash: flash@0 { + compatible = "sst,sst25vf016b", "jedec,spi-nor"; + spi-max-frequency = <20000000>; + reg = <0>; +diff --git a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi +index 0c0105468a2f..37482a9023fc 100644 +--- a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi ++++ b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi +@@ -197,7 +197,7 @@ &ecspi1 { + pinctrl-0 = <&pinctrl_ecspi1>; + status = "okay"; + +- flash: m25p80@0 { ++ flash: flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "st,m25p32", "jedec,spi-nor"; +diff --git a/arch/arm/boot/dts/imx6sl-evk.dts b/arch/arm/boot/dts/imx6sl-evk.dts +index 25f6f2fb1555..f16c830f1e91 100644 +--- a/arch/arm/boot/dts/imx6sl-evk.dts ++++ b/arch/arm/boot/dts/imx6sl-evk.dts +@@ -137,7 +137,7 @@ &ecspi1 { + pinctrl-0 = <&pinctrl_ecspi1>; + status = "okay"; + +- flash: m25p80@0 { ++ flash: flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "st,m25p32", "jedec,spi-nor"; +diff --git a/arch/arm/boot/dts/imx6sx-nitrogen6sx.dts b/arch/arm/boot/dts/imx6sx-nitrogen6sx.dts +index 66af78e83b70..a2c79bcf9a11 100644 +--- a/arch/arm/boot/dts/imx6sx-nitrogen6sx.dts ++++ b/arch/arm/boot/dts/imx6sx-nitrogen6sx.dts +@@ -107,7 +107,7 @@ &ecspi1 { + pinctrl-0 = <&pinctrl_ecspi1>; + status = "okay"; + +- flash: m25p80@0 { ++ flash: flash@0 { + compatible = "microchip,sst25vf016b"; + spi-max-frequency = <20000000>; + reg = <0>; +diff --git a/arch/arm/boot/dts/imx6sx-sdb-reva.dts b/arch/arm/boot/dts/imx6sx-sdb-reva.dts +index dce5dcf96c25..7dda42553f4b 100644 +--- a/arch/arm/boot/dts/imx6sx-sdb-reva.dts ++++ b/arch/arm/boot/dts/imx6sx-sdb-reva.dts +@@ -123,7 +123,7 @@ &qspi2 { + pinctrl-0 = <&pinctrl_qspi2>; + status = "okay"; + +- flash0: s25fl128s@0 { ++ flash0: flash@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <1>; +@@ -133,7 +133,7 @@ flash0: s25fl128s@0 { + spi-tx-bus-width = <4>; + }; + +- flash1: s25fl128s@2 { ++ flash1: flash@2 { + reg = <2>; + #address-cells = <1>; + #size-cells = <1>; +diff --git a/arch/arm/boot/dts/imx6sx-sdb.dts b/arch/arm/boot/dts/imx6sx-sdb.dts +index 99f4cf777a38..969cfe920d25 100644 +--- a/arch/arm/boot/dts/imx6sx-sdb.dts ++++ b/arch/arm/boot/dts/imx6sx-sdb.dts +@@ -108,7 +108,7 @@ &qspi2 { + pinctrl-0 = <&pinctrl_qspi2>; + status = "okay"; + +- flash0: n25q256a@0 { ++ flash0: flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "micron,n25q256a", "jedec,spi-nor"; +@@ -118,7 +118,7 @@ flash0: n25q256a@0 { + reg = <0>; + }; + +- flash1: n25q256a@2 { ++ flash1: flash@2 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "micron,n25q256a", "jedec,spi-nor"; +diff --git a/arch/arm/boot/dts/imx6ul-14x14-evk.dtsi b/arch/arm/boot/dts/imx6ul-14x14-evk.dtsi +index a3fde3316c73..1a18c41ce385 100644 +--- a/arch/arm/boot/dts/imx6ul-14x14-evk.dtsi ++++ b/arch/arm/boot/dts/imx6ul-14x14-evk.dtsi +@@ -286,7 +286,7 @@ &qspi { + pinctrl-0 = <&pinctrl_qspi>; + status = "okay"; + +- flash0: n25q256a@0 { ++ flash0: flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "micron,n25q256a", "jedec,spi-nor"; +diff --git a/arch/arm/boot/dts/imx6ul-kontron-n6310-som.dtsi b/arch/arm/boot/dts/imx6ul-kontron-n6310-som.dtsi +index 47d3ce5d255f..acd936540d89 100644 +--- a/arch/arm/boot/dts/imx6ul-kontron-n6310-som.dtsi ++++ b/arch/arm/boot/dts/imx6ul-kontron-n6310-som.dtsi +@@ -19,7 +19,7 @@ memory@80000000 { + }; + + &qspi { +- spi-flash@0 { ++ flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "spi-nand"; +diff --git a/arch/arm/boot/dts/imx6ul-kontron-n6311-som.dtsi b/arch/arm/boot/dts/imx6ul-kontron-n6311-som.dtsi +index a095a7654ac6..29ed38dce580 100644 +--- a/arch/arm/boot/dts/imx6ul-kontron-n6311-som.dtsi ++++ b/arch/arm/boot/dts/imx6ul-kontron-n6311-som.dtsi +@@ -18,7 +18,7 @@ memory@80000000 { + }; + + &qspi { +- spi-flash@0 { ++ flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "spi-nand"; +diff --git a/arch/arm/boot/dts/imx6ul-kontron-n6x1x-som-common.dtsi b/arch/arm/boot/dts/imx6ul-kontron-n6x1x-som-common.dtsi +index 2a449a3c1ae2..09a83dbdf651 100644 +--- a/arch/arm/boot/dts/imx6ul-kontron-n6x1x-som-common.dtsi ++++ b/arch/arm/boot/dts/imx6ul-kontron-n6x1x-som-common.dtsi +@@ -19,7 +19,7 @@ &ecspi2 { + pinctrl-0 = <&pinctrl_ecspi2>; + status = "okay"; + +- spi-flash@0 { ++ flash@0 { + compatible = "mxicy,mx25v8035f", "jedec,spi-nor"; + spi-max-frequency = <50000000>; + reg = <0>; +diff --git a/arch/arm/boot/dts/imx6ull-kontron-n6411-som.dtsi b/arch/arm/boot/dts/imx6ull-kontron-n6411-som.dtsi +index b7e984284e1a..d000606c0704 100644 +--- a/arch/arm/boot/dts/imx6ull-kontron-n6411-som.dtsi ++++ b/arch/arm/boot/dts/imx6ull-kontron-n6411-som.dtsi +@@ -18,7 +18,7 @@ memory@80000000 { + }; + + &qspi { +- spi-flash@0 { ++ flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "spi-nand"; +-- +2.35.3 + diff --git a/patches.suse/ARM-dts-imx6qdl-kontron-samx6i-fix-spi-flash-compati.patch b/patches.suse/ARM-dts-imx6qdl-kontron-samx6i-fix-spi-flash-compati.patch new file mode 100644 index 0000000..0f7a4a0 --- /dev/null +++ b/patches.suse/ARM-dts-imx6qdl-kontron-samx6i-fix-spi-flash-compati.patch @@ -0,0 +1,37 @@ +From af7d78c957017f8b3a0986769f6f18e57f9362ea Mon Sep 17 00:00:00 2001 +From: Marco Felsch +Date: Tue, 26 Jul 2022 15:05:22 +0200 +Subject: [PATCH] ARM: dts: imx6qdl-kontron-samx6i: fix spi-flash compatible +Git-commit: af7d78c957017f8b3a0986769f6f18e57f9362ea +Patch-mainline: v6.0-rc5 +References: git-fixes + +Drop the "winbond,w25q16dw" compatible since it causes to set the +MODALIAS to w25q16dw which is not specified within spi-nor id table. +Fix this by use the common "jedec,spi-nor" compatible. + +Fixes: 2125212785c9 ("ARM: dts: imx6qdl-kontron-samx6i: add Kontron SMARC SoM Support") +Signed-off-by: Marco Felsch +Signed-off-by: Shawn Guo +Acked-by: Takashi Iwai + +--- + arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi b/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi +index f159c58b9edb..6b791d515e29 100644 +--- a/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi ++++ b/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi +@@ -249,7 +249,7 @@ &ecspi4 { + + /* default boot source: workaround #1 for errata ERR006282 */ + smarc_flash: flash@0 { +- compatible = "winbond,w25q16dw", "jedec,spi-nor"; ++ compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <20000000>; + }; +-- +2.35.3 + diff --git a/patches.suse/ARM-dts-imx6qdl-kontron-samx6i-hook-up-DDC-i2c-bus.patch b/patches.suse/ARM-dts-imx6qdl-kontron-samx6i-hook-up-DDC-i2c-bus.patch new file mode 100644 index 0000000..88fbaaf --- /dev/null +++ b/patches.suse/ARM-dts-imx6qdl-kontron-samx6i-hook-up-DDC-i2c-bus.patch @@ -0,0 +1,45 @@ +From afd8f77957e3e83adf21d9229c61ff37f44a177a Mon Sep 17 00:00:00 2001 +From: Lucas Stach +Date: Tue, 26 Jul 2022 15:05:23 +0200 +Subject: [PATCH] ARM: dts: imx6qdl-kontron-samx6i: hook up DDC i2c bus +Git-commit: afd8f77957e3e83adf21d9229c61ff37f44a177a +Patch-mainline: v6.1-rc1 +References: git-fixes + +i2c2 is routed to the pins dedicated as DDC in the module standard. +Reduce clock rate to 100kHz to be in line with VESA standard and hook +this bus up to the HDMI node. + +Fixes: 708ed2649ad8 ("ARM: dts: imx6qdl-kontron-samx6i: increase i2c-frequency") +Signed-off-by: Lucas Stach +[m.felsch@pengutronix.de: add fixes line] +Signed-off-by: Marco Felsch +Signed-off-by: Shawn Guo +Acked-by: Takashi Iwai + +--- + arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi ++++ b/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi +@@ -263,6 +263,10 @@ + phy-reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>; + }; + ++&hdmi { ++ ddc-i2c-bus = <&i2c2>; ++}; ++ + &i2c_intern { + pmic@8 { + compatible = "fsl,pfuze100"; +@@ -387,7 +391,7 @@ + + /* HDMI_CTRL */ + &i2c2 { +- clock-frequency = <375000>; ++ clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + }; diff --git a/patches.suse/ARM-dts-integrator-Tag-PCI-host-with-device_type.patch b/patches.suse/ARM-dts-integrator-Tag-PCI-host-with-device_type.patch new file mode 100644 index 0000000..1382e3c --- /dev/null +++ b/patches.suse/ARM-dts-integrator-Tag-PCI-host-with-device_type.patch @@ -0,0 +1,37 @@ +From 4952aa696a9f221c5e34e5961e02fca41ef67ad6 Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Mon, 19 Sep 2022 11:26:08 +0200 +Subject: [PATCH] ARM: dts: integrator: Tag PCI host with device_type +Git-commit: 4952aa696a9f221c5e34e5961e02fca41ef67ad6 +Patch-mainline: v6.0 +References: git-fixes + +The DT parser is dependent on the PCI device being tagged as +device_type = "pci" in order to parse memory ranges properly. +Fix this up. + +Signed-off-by: Linus Walleij +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20220919092608.813511-1-linus.walleij@linaro.org' +Signed-off-by: Arnd Bergmann +Acked-by: Takashi Iwai + +--- + arch/arm/boot/dts/integratorap.dts | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/boot/dts/integratorap.dts b/arch/arm/boot/dts/integratorap.dts +index 9b652cc27b14..c983435ed492 100644 +--- a/arch/arm/boot/dts/integratorap.dts ++++ b/arch/arm/boot/dts/integratorap.dts +@@ -160,6 +160,7 @@ pic: pic@14000000 { + + pci: pciv3@62000000 { + compatible = "arm,integrator-ap-pci", "v3,v360epc-pci"; ++ device_type = "pci"; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; +-- +2.35.3 + diff --git a/patches.suse/ARM-dts-kirkwood-lsxl-fix-serial-line.patch b/patches.suse/ARM-dts-kirkwood-lsxl-fix-serial-line.patch new file mode 100644 index 0000000..1e0fd06 --- /dev/null +++ b/patches.suse/ARM-dts-kirkwood-lsxl-fix-serial-line.patch @@ -0,0 +1,50 @@ +From 04eabc6ac10fda9424606d9a7ab6ab9a5d95350a Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Tue, 16 Aug 2022 02:10:24 +0200 +Subject: [PATCH] ARM: dts: kirkwood: lsxl: fix serial line +Git-commit: 04eabc6ac10fda9424606d9a7ab6ab9a5d95350a +Patch-mainline: v6.1-rc1 +References: git-fixes + +Commit 327e15428977 ("ARM: dts: kirkwood: consolidate common pinctrl +settings") unknowingly broke the serial output on this board. Before +this commit, the pinmux was still configured by the bootloader and the +kernel didn't reconfigured it again. This was an oversight by the +initial board support where the pinmux for the serial line was never +configured by the kernel. But with this commit, the serial line will be +reconfigured to the wrong pins. This is especially confusing, because +the output still works, but the input doesn't. Presumingly, the input is +reconfigured to MPP10, but the output is connected to both MPP11 and +MPP5. + +Override the pinmux in the board device tree. + +Fixes: 327e15428977 ("ARM: dts: kirkwood: consolidate common pinctrl settings") +Signed-off-by: Michael Walle +Reviewed-by: Andrew Lunn +Signed-off-by: Gregory CLEMENT +Acked-by: Takashi Iwai + +--- + arch/arm/boot/dts/kirkwood-lsxl.dtsi | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/arch/arm/boot/dts/kirkwood-lsxl.dtsi b/arch/arm/boot/dts/kirkwood-lsxl.dtsi +index 7b151acb9984..321a40a98ed2 100644 +--- a/arch/arm/boot/dts/kirkwood-lsxl.dtsi ++++ b/arch/arm/boot/dts/kirkwood-lsxl.dtsi +@@ -10,6 +10,11 @@ chosen { + + ocp@f1000000 { + pinctrl: pin-controller@10000 { ++ /* Non-default UART pins */ ++ pmx_uart0: pmx-uart0 { ++ marvell,pins = "mpp4", "mpp5"; ++ }; ++ + pmx_power_hdd: pmx-power-hdd { + marvell,pins = "mpp10"; + marvell,function = "gpo"; +-- +2.35.3 + diff --git a/patches.suse/ARM-dts-kirkwood-lsxl-remove-first-ethernet-port.patch b/patches.suse/ARM-dts-kirkwood-lsxl-remove-first-ethernet-port.patch new file mode 100644 index 0000000..7c7d685 --- /dev/null +++ b/patches.suse/ARM-dts-kirkwood-lsxl-remove-first-ethernet-port.patch @@ -0,0 +1,53 @@ +From 2d528eda7c96ce5c70f895854ecd5684bd5d80b9 Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Tue, 16 Aug 2022 02:10:25 +0200 +Subject: [PATCH] ARM: dts: kirkwood: lsxl: remove first ethernet port +Git-commit: 2d528eda7c96ce5c70f895854ecd5684bd5d80b9 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Both the Linkstation LS-CHLv2 and the LS-XHL have only one ethernet +port. This has always been wrong, i.e. the board code used to set up +both ports, but the driver will play nice and return -ENODEV if the +assiciated PHY is not found. Nevertheless, it is wrong. Remove it. + +Fixes: 876e23333511 ("ARM: kirkwood: add gigabit ethernet and mvmdio device tree nodes") +Signed-off-by: Michael Walle +Reviewed-by: Andrew Lunn +Signed-off-by: Gregory CLEMENT +Acked-by: Takashi Iwai + +--- + arch/arm/boot/dts/kirkwood-lsxl.dtsi | 11 ----------- + 1 file changed, 11 deletions(-) + +diff --git a/arch/arm/boot/dts/kirkwood-lsxl.dtsi b/arch/arm/boot/dts/kirkwood-lsxl.dtsi +index 321a40a98ed2..88b70ba1c8fe 100644 +--- a/arch/arm/boot/dts/kirkwood-lsxl.dtsi ++++ b/arch/arm/boot/dts/kirkwood-lsxl.dtsi +@@ -218,22 +218,11 @@ hdd_power: regulator@2 { + &mdio { + status = "okay"; + +- ethphy0: ethernet-phy@0 { +- reg = <0>; +- }; +- + ethphy1: ethernet-phy@8 { + reg = <8>; + }; + }; + +-ð0 { +- status = "okay"; +- ethernet0-port@0 { +- phy-handle = <ðphy0>; +- }; +-}; +- + ð1 { + status = "okay"; + ethernet1-port@0 { +-- +2.35.3 + diff --git a/patches.suse/ARM-dts-turris-omnia-Add-label-for-wan-port.patch b/patches.suse/ARM-dts-turris-omnia-Add-label-for-wan-port.patch new file mode 100644 index 0000000..396ae43 --- /dev/null +++ b/patches.suse/ARM-dts-turris-omnia-Add-label-for-wan-port.patch @@ -0,0 +1,40 @@ +From 649acf24d8c86ab8861a05cdd6833100a5fe4e78 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= +Date: Wed, 21 Sep 2022 13:50:37 +0200 +Subject: [PATCH] ARM: dts: turris-omnia: Add label for wan port +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 649acf24d8c86ab8861a05cdd6833100a5fe4e78 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Device tree label property should contain label from the box/stick. +Labels for other ports are already specified in DT but wan is missing. +So add missing label for wan port. + +Fixes: 26ca8b52d6e1 ("ARM: dts: add support for Turris Omnia") +Signed-off-by: Pali Rohár +Reviewed-by: Andrew Lunn +Signed-off-by: Gregory CLEMENT +Acked-by: Takashi Iwai + +--- + arch/arm/boot/dts/armada-385-turris-omnia.dts | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/boot/dts/armada-385-turris-omnia.dts b/arch/arm/boot/dts/armada-385-turris-omnia.dts +index 8fc98d51eb7e..72ac807cae25 100644 +--- a/arch/arm/boot/dts/armada-385-turris-omnia.dts ++++ b/arch/arm/boot/dts/armada-385-turris-omnia.dts +@@ -193,6 +193,7 @@ ð2 { + buffer-manager = <&bm>; + bm,pool-long = <2>; + bm,pool-short = <3>; ++ label = "wan"; + }; + + &i2c0 { +-- +2.35.3 + diff --git a/patches.suse/ARM-dts-turris-omnia-Fix-mpp26-pin-name-and-comment.patch b/patches.suse/ARM-dts-turris-omnia-Fix-mpp26-pin-name-and-comment.patch new file mode 100644 index 0000000..5ad824f --- /dev/null +++ b/patches.suse/ARM-dts-turris-omnia-Fix-mpp26-pin-name-and-comment.patch @@ -0,0 +1,53 @@ +From 49e93898f0dc177e645c22d0664813567fd9ec00 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marek=20Beh=C3=BAn?= +Date: Wed, 27 Jul 2022 14:56:10 +0200 +Subject: [PATCH] ARM: dts: turris-omnia: Fix mpp26 pin name and comment +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 49e93898f0dc177e645c22d0664813567fd9ec00 +Patch-mainline: v6.1-rc1 +References: git-fixes + +There is a bug in Turris Omnia's schematics, whereupon the MPP[26] pin, +which is routed to CN11 pin header, is documented as SPI CS1, but +MPP[26] pin does not support this function. Instead it controls chip +select 2 if in "spi0" mode. + +Fix the name of the pin node in pinctrl node and fix the comment in SPI +node. + +Fixes: 26ca8b52d6e1 ("ARM: dts: add support for Turris Omnia") +Signed-off-by: Marek Behún +Signed-off-by: Gregory CLEMENT +Acked-by: Takashi Iwai + +--- + arch/arm/boot/dts/armada-385-turris-omnia.dts | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/boot/dts/armada-385-turris-omnia.dts b/arch/arm/boot/dts/armada-385-turris-omnia.dts +index d1e0db6e5730..a41902e3815c 100644 +--- a/arch/arm/boot/dts/armada-385-turris-omnia.dts ++++ b/arch/arm/boot/dts/armada-385-turris-omnia.dts +@@ -476,7 +476,7 @@ spi0cs0_pins: spi0cs0-pins { + marvell,function = "spi0"; + }; + +- spi0cs1_pins: spi0cs1-pins { ++ spi0cs2_pins: spi0cs2-pins { + marvell,pins = "mpp26"; + marvell,function = "spi0"; + }; +@@ -511,7 +511,7 @@ partition@100000 { + }; + }; + +- /* MISO, MOSI, SCLK and CS1 are routed to pin header CN11 */ ++ /* MISO, MOSI, SCLK and CS2 are routed to pin header CN11 */ + }; + + &uart0 { +-- +2.35.3 + diff --git a/patches.suse/ASoC-codecs-tx-macro-fix-kcontrol-put.patch b/patches.suse/ASoC-codecs-tx-macro-fix-kcontrol-put.patch new file mode 100644 index 0000000..d5c0983 --- /dev/null +++ b/patches.suse/ASoC-codecs-tx-macro-fix-kcontrol-put.patch @@ -0,0 +1,68 @@ +From c1057a08af438e0cf5450c1d977a3011198ed2f8 Mon Sep 17 00:00:00 2001 +From: Srinivas Kandagatla +Date: Tue, 6 Sep 2022 18:01:05 +0100 +Subject: [PATCH] ASoC: codecs: tx-macro: fix kcontrol put +Git-commit: c1057a08af438e0cf5450c1d977a3011198ed2f8 +Patch-mainline: v6.1-rc1 +References: git-fixes + +tx_macro_tx_mixer_put() and tx_macro_dec_mode_put() currently returns zero +eventhough it changes the value. +Fix this, so that change notifications are sent correctly. + +Fixes: d207bdea0ca9 ("ASoC: codecs: lpass-tx-macro: add dapm widgets and route") +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20220906170112.1984-6-srinivas.kandagatla@linaro.org +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/lpass-tx-macro.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/codecs/lpass-tx-macro.c b/sound/soc/codecs/lpass-tx-macro.c +index 5c03ef8d88b3..7f9370ed126f 100644 +--- a/sound/soc/codecs/lpass-tx-macro.c ++++ b/sound/soc/codecs/lpass-tx-macro.c +@@ -822,17 +822,23 @@ static int tx_macro_tx_mixer_put(struct snd_kcontrol *kcontrol, + struct tx_macro *tx = snd_soc_component_get_drvdata(component); + + if (enable) { ++ if (tx->active_decimator[dai_id] == dec_id) ++ return 0; ++ + set_bit(dec_id, &tx->active_ch_mask[dai_id]); + tx->active_ch_cnt[dai_id]++; + tx->active_decimator[dai_id] = dec_id; + } else { ++ if (tx->active_decimator[dai_id] == -1) ++ return 0; ++ + tx->active_ch_cnt[dai_id]--; + clear_bit(dec_id, &tx->active_ch_mask[dai_id]); + tx->active_decimator[dai_id] = -1; + } + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, update); + +- return 0; ++ return 1; + } + + static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, +@@ -1018,9 +1024,12 @@ static int tx_macro_dec_mode_put(struct snd_kcontrol *kcontrol, + int path = e->shift_l; + struct tx_macro *tx = snd_soc_component_get_drvdata(component); + ++ if (tx->dec_mode[path] == value) ++ return 0; ++ + tx->dec_mode[path] = value; + +- return 0; ++ return 1; + } + + static int tx_macro_get_bcs(struct snd_kcontrol *kcontrol, +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Add-ASP-TX3-4-source-to-register-patch.patch b/patches.suse/ASoC-cs35l41-Add-ASP-TX3-4-source-to-register-patch.patch new file mode 100644 index 0000000..efbd5eb --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Add-ASP-TX3-4-source-to-register-patch.patch @@ -0,0 +1,69 @@ +From 46b0d050c8c7df6dfb2c376aaa149bf2cfc5ca3e Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Thu, 23 Jun 2022 11:51:16 +0100 +Subject: [PATCH] ASoC: cs35l41: Add ASP TX3/4 source to register patch +Git-commit: 46b0d050c8c7df6dfb2c376aaa149bf2cfc5ca3e +Patch-mainline: v5.19-rc6 +References: bsc#1203699 + +The mixer controls for ASP TX3/4 are set to values that are not included +in their enumeration control. This will cause spurious event +notifications when the controls are first changed, as the register value +changes whilst the actual visible enumeration value does not. Use the +register patch to set them to a known value, zero, which equates to zero +fill, thereby avoiding the spurious notifications. + +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20220623105120.1981154-2-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs35l41-lib.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c +index 6d3070ea9e06..198cfe54a46f 100644 +--- a/sound/soc/codecs/cs35l41-lib.c ++++ b/sound/soc/codecs/cs35l41-lib.c +@@ -37,8 +37,8 @@ static const struct reg_default cs35l41_reg[] = { + { CS35L41_DAC_PCM1_SRC, 0x00000008 }, + { CS35L41_ASP_TX1_SRC, 0x00000018 }, + { CS35L41_ASP_TX2_SRC, 0x00000019 }, +- { CS35L41_ASP_TX3_SRC, 0x00000020 }, +- { CS35L41_ASP_TX4_SRC, 0x00000021 }, ++ { CS35L41_ASP_TX3_SRC, 0x00000000 }, ++ { CS35L41_ASP_TX4_SRC, 0x00000000 }, + { CS35L41_DSP1_RX1_SRC, 0x00000008 }, + { CS35L41_DSP1_RX2_SRC, 0x00000009 }, + { CS35L41_DSP1_RX3_SRC, 0x00000018 }, +@@ -644,6 +644,8 @@ static const struct reg_sequence cs35l41_reva0_errata_patch[] = { + { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, + { CS35L41_PWR_CTRL2, 0x00000000 }, + { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, ++ { CS35L41_ASP_TX3_SRC, 0x00000000 }, ++ { CS35L41_ASP_TX4_SRC, 0x00000000 }, + }; + + static const struct reg_sequence cs35l41_revb0_errata_patch[] = { +@@ -655,6 +657,8 @@ static const struct reg_sequence cs35l41_revb0_errata_patch[] = { + { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, + { CS35L41_PWR_CTRL2, 0x00000000 }, + { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, ++ { CS35L41_ASP_TX3_SRC, 0x00000000 }, ++ { CS35L41_ASP_TX4_SRC, 0x00000000 }, + }; + + static const struct reg_sequence cs35l41_revb2_errata_patch[] = { +@@ -666,6 +670,8 @@ static const struct reg_sequence cs35l41_revb2_errata_patch[] = { + { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, + { CS35L41_PWR_CTRL2, 0x00000000 }, + { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, ++ { CS35L41_ASP_TX3_SRC, 0x00000000 }, ++ { CS35L41_ASP_TX4_SRC, 0x00000000 }, + }; + + static const struct reg_sequence cs35l41_fs_errata_patch[] = { +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Add-bindings-for-CS35L41.patch b/patches.suse/ASoC-cs35l41-Add-bindings-for-CS35L41.patch new file mode 100644 index 0000000..fd01bf1 --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Add-bindings-for-CS35L41.patch @@ -0,0 +1,185 @@ +From 8d7ab8800184cc75000dd2e784fe121934482878 Mon Sep 17 00:00:00 2001 +From: David Rhodes +Date: Tue, 7 Sep 2021 17:57:19 -0500 +Subject: [PATCH] ASoC: cs35l41: Add bindings for CS35L41 +Git-commit: 8d7ab8800184cc75000dd2e784fe121934482878 +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +Devicetree binding documentation for CS35L41 driver + +CS35L41 is a 11-V Boosted Mono Class D Amplifier with +DSP Speaker Protection and Equalization + +Signed-off-by: David Rhodes +Reviewed-by: Charles Keepax +Link: https://lore.kernel.org/r/20210907225719.2018115-3-drhodes@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + .../devicetree/bindings/sound/cs35l41.yaml | 151 ++++++++++++++++++ + 1 file changed, 151 insertions(+) + create mode 100644 Documentation/devicetree/bindings/sound/cs35l41.yaml + +diff --git a/Documentation/devicetree/bindings/sound/cs35l41.yaml b/Documentation/devicetree/bindings/sound/cs35l41.yaml +new file mode 100644 +index 000000000000..fde78c850286 +--- /dev/null ++++ b/Documentation/devicetree/bindings/sound/cs35l41.yaml +@@ -0,0 +1,151 @@ ++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/sound/cs35l41.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Cirrus Logic CS35L41 Speaker Amplifier ++ ++maintainers: ++ - david.rhodes@cirrus.com ++ ++description: | ++ CS35L41 is a boosted mono Class D amplifier with DSP ++ speaker protection and equalization ++ ++properties: ++ compatible: ++ enum: ++ - cirrus,cs35l40 ++ - cirrus,cs35l41 ++ ++ reg: ++ maxItems: 1 ++ ++ '#sound-dai-cells': ++ description: ++ The first cell indicating the audio interface. ++ const: 1 ++ ++ reset-gpios: ++ maxItems: 1 ++ ++ VA-supply: ++ description: voltage regulator phandle for the VA supply ++ ++ VP-supply: ++ description: voltage regulator phandle for the VP supply ++ ++ cirrus,boost-peak-milliamp: ++ description: ++ Boost-converter peak current limit in mA. ++ Configures the peak current by monitoring the current through the boost FET. ++ Range starts at 1600 mA and goes to a maximum of 4500 mA with increments ++ of 50 mA. See section 4.3.6 of the datasheet for details. ++ $ref: "/schemas/types.yaml#/definitions/uint32" ++ minimum: 1600 ++ maximum: 4500 ++ default: 4500 ++ ++ cirrus,boost-ind-nanohenry: ++ description: ++ Boost inductor value, expressed in nH. Valid ++ values include 1000, 1200, 1500 and 2200. ++ $ref: "/schemas/types.yaml#/definitions/uint32" ++ minimum: 1000 ++ maximum: 2200 ++ ++ cirrus,boost-cap-microfarad: ++ description: ++ Total equivalent boost capacitance on the VBST ++ and VAMP pins, derated at 11 volts DC. The value must be rounded to the ++ nearest integer and expressed in uF. ++ $ref: "/schemas/types.yaml#/definitions/uint32" ++ ++ cirrus,asp-sdout-hiz: ++ description: ++ Audio serial port SDOUT Hi-Z control. Sets the Hi-Z ++ configuration for SDOUT pin of amplifier. ++ 0 = Logic 0 during unused slots, and while all transmit channels disabled ++ 1 = Hi-Z during unused slots but logic 0 while all transmit channels disabled ++ 2 = (Default) Logic 0 during unused slots, but Hi-Z while all transmit channels disabled ++ 3 = Hi-Z during unused slots and while all transmit channels disabled ++ $ref: "/schemas/types.yaml#/definitions/uint32" ++ minimum: 0 ++ maximum: 3 ++ default: 2 ++ ++ cirrus,gpio1-polarity-invert: ++ description: ++ Boolean which specifies whether the GPIO1 ++ level is inverted. If this property is not present the level is not inverted. ++ type: boolean ++ ++ cirrus,gpio1-output-enable: ++ description: ++ Boolean which specifies whether the GPIO1 pin ++ is configured as an output. If this property is not present the ++ pin will be configured as an input. ++ type: boolean ++ ++ cirrus,gpio1-src-select: ++ description: ++ Configures the function of the GPIO1 pin. ++ Note that the options are different from the GPIO2 pin ++ 0 = High Impedance (Default) ++ 1 = GPIO ++ 2 = Sync ++ 3 = MCLK input ++ $ref: "/schemas/types.yaml#/definitions/uint32" ++ minimum: 0 ++ maximum: 3 ++ ++ cirrus,gpio2-polarity-invert: ++ description: ++ Boolean which specifies whether the GPIO2 ++ level is inverted. If this property is not present the level is not inverted. ++ type: boolean ++ ++ cirrus,gpio2-output-enable: ++ description: ++ Boolean which specifies whether the GPIO2 pin ++ is configured as an output. If this property is not present the ++ pin will be configured as an input. ++ type: boolean ++ ++ cirrus,gpio2-src-select: ++ description: ++ Configures the function of the GPIO2 pin. ++ Note that the options are different from the GPIO1 pin. ++ 0 = High Impedance (Default) ++ 1 = GPIO ++ 2 = Open Drain INTB ++ 3 = MCLK input ++ 4 = Push-pull INTB (active low) ++ 5 = Push-pull INT (active high) ++ $ref: "/schemas/types.yaml#/definitions/uint32" ++ minimum: 0 ++ maximum: 5 ++ ++required: ++ - compatible ++ - reg ++ - "#sound-dai-cells" ++ - cirrus,boost-peak-milliamp ++ - cirrus,boost-ind-nanohenry ++ - cirrus,boost-cap-microfarad ++ ++unevaluatedProperties: false ++ ++examples: ++ - | ++ cs35l41: cs35l41@2 { ++ compatible = "cirrus,cs35l41"; ++ reg = <2>; ++ VA-supply = <&dummy_vreg>; ++ VP-supply = <&dummy_vreg>; ++ reset-gpios = <&gpio 110 0>; ++ cirrus,boost-peak-milliamp = <4500>; ++ cirrus,boost-ind-nanohenry = <1000>; ++ cirrus,boost-cap-microfarad = <15>; ++ }; +\ No newline at end of file +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Add-common-cs35l41-enter-hibernate-func.patch b/patches.suse/ASoC-cs35l41-Add-common-cs35l41-enter-hibernate-func.patch new file mode 100644 index 0000000..bdd7df5 --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Add-common-cs35l41-enter-hibernate-func.patch @@ -0,0 +1,98 @@ +From e341efc308e5374ded6b471f9e1ec01450bcc93e Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Wed, 25 May 2022 14:16:32 +0100 +Subject: [PATCH] ASoC: cs35l41: Add common cs35l41 enter hibernate function +Git-commit: e341efc308e5374ded6b471f9e1ec01450bcc93e +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +Since the CS35L41 HDA driver also support hibernation, it +makes sense to move code from the ASoC driver to enter +hibernation into common code. + +Since HDA must support laptops which do not support hibernation +due to lack of external boost GPIO it is necessary to +ensure the function returns an error when an unsupported +boost type is in use. + +Acked-by: Charles Keepax + +Signed-off-by: Stefan Binding +Signed-off-by: Vitaly Rodionov +Link: https://lore.kernel.org/r/20220525131638.5512-12-vitalyr@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + include/sound/cs35l41.h | 2 ++ + sound/soc/codecs/cs35l41-lib.c | 19 +++++++++++++++++++ + sound/soc/codecs/cs35l41.c | 10 +--------- + 3 files changed, 22 insertions(+), 9 deletions(-) + +diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h +index 7759f2e14d96..a66ef37184fd 100644 +--- a/include/sound/cs35l41.h ++++ b/include/sound/cs35l41.h +@@ -881,6 +881,8 @@ void cs35l41_configure_cs_dsp(struct device *dev, struct regmap *reg, struct cs_ + int cs35l41_set_cspl_mbox_cmd(struct device *dev, struct regmap *regmap, + enum cs35l41_cspl_mbox_cmd cmd); + int cs35l41_write_fs_errata(struct device *dev, struct regmap *regmap); ++int cs35l41_enter_hibernate(struct device *dev, struct regmap *regmap, ++ enum cs35l41_boost_type b_type); + int cs35l41_exit_hibernate(struct device *dev, struct regmap *regmap); + int cs35l41_init_boost(struct device *dev, struct regmap *regmap, + struct cs35l41_hw_cfg *hw_cfg); +diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c +index cc5366c8bdd6..10b754481ca2 100644 +--- a/sound/soc/codecs/cs35l41-lib.c ++++ b/sound/soc/codecs/cs35l41-lib.c +@@ -1321,6 +1321,25 @@ int cs35l41_write_fs_errata(struct device *dev, struct regmap *regmap) + } + EXPORT_SYMBOL_GPL(cs35l41_write_fs_errata); + ++int cs35l41_enter_hibernate(struct device *dev, struct regmap *regmap, ++ enum cs35l41_boost_type b_type) ++{ ++ if (!cs35l41_safe_reset(regmap, b_type)) { ++ dev_dbg(dev, "System does not support Suspend\n"); ++ return -EINVAL; ++ } ++ ++ dev_dbg(dev, "Enter hibernate\n"); ++ regmap_write(regmap, CS35L41_WAKESRC_CTL, 0x0088); ++ regmap_write(regmap, CS35L41_WAKESRC_CTL, 0x0188); ++ ++ // Don't wait for ACK since bus activity would wake the device ++ regmap_write(regmap, CS35L41_DSP_VIRT1_MBOX_1, CSPL_MBOX_CMD_HIBERNATE); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(cs35l41_enter_hibernate); ++ + static void cs35l41_wait_for_pwrmgt_sts(struct device *dev, struct regmap *regmap) + { + const int pwrmgt_retries = 10; +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index be7d02517739..a115ea35b92d 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -1335,15 +1335,7 @@ static int __maybe_unused cs35l41_runtime_suspend(struct device *dev) + if (!cs35l41->dsp.preloaded || !cs35l41->dsp.cs_dsp.running) + return 0; + +- dev_dbg(cs35l41->dev, "Enter hibernate\n"); +- +- cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type); +- regmap_write(cs35l41->regmap, CS35L41_WAKESRC_CTL, 0x0088); +- regmap_write(cs35l41->regmap, CS35L41_WAKESRC_CTL, 0x0188); +- +- // Don't wait for ACK since bus activity would wake the device +- regmap_write(cs35l41->regmap, CS35L41_DSP_VIRT1_MBOX_1, +- CSPL_MBOX_CMD_HIBERNATE); ++ cs35l41_enter_hibernate(dev, cs35l41->regmap, cs35l41->hw_cfg.bst_type); + + regcache_cache_only(cs35l41->regmap, true); + regcache_mark_dirty(cs35l41->regmap); +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Add-cs35l51-53-IDs.patch b/patches.suse/ASoC-cs35l41-Add-cs35l51-53-IDs.patch new file mode 100644 index 0000000..077e98a --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Add-cs35l51-53-IDs.patch @@ -0,0 +1,51 @@ +From dcf821319474edde7e85b95608a4539703a2b67d Mon Sep 17 00:00:00 2001 +From: David Rhodes +Date: Wed, 5 Jan 2022 11:30:19 +0000 +Subject: [PATCH] ASoC: cs35l41: Add cs35l51/53 IDs +Git-commit: dcf821319474edde7e85b95608a4539703a2b67d +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +Add IDs for the CS35L51/53 variants, the functionality is shared with +CS35L41. + +Signed-off-by: David Rhodes +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20220105113026.18955-2-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs35l41-i2c.c | 2 ++ + sound/soc/codecs/cs35l41-spi.c | 2 ++ + 2 files changed, 4 insertions(+) + +diff --git a/sound/soc/codecs/cs35l41-i2c.c b/sound/soc/codecs/cs35l41-i2c.c +index de5c8612f030..eb8dfb6d9c95 100644 +--- a/sound/soc/codecs/cs35l41-i2c.c ++++ b/sound/soc/codecs/cs35l41-i2c.c +@@ -22,6 +22,8 @@ + static const struct i2c_device_id cs35l41_id_i2c[] = { + { "cs35l40", 0 }, + { "cs35l41", 0 }, ++ { "cs35l51", 0 }, ++ { "cs35l53", 0 }, + {} + }; + +diff --git a/sound/soc/codecs/cs35l41-spi.c b/sound/soc/codecs/cs35l41-spi.c +index c157153f28d8..86bbe2fba956 100644 +--- a/sound/soc/codecs/cs35l41-spi.c ++++ b/sound/soc/codecs/cs35l41-spi.c +@@ -20,6 +20,8 @@ + static const struct spi_device_id cs35l41_id_spi[] = { + { "cs35l40", 0 }, + { "cs35l41", 0 }, ++ { "cs35l51", 0 }, ++ { "cs35l53", 0 }, + {} + }; + +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Add-endianness-flag-in-snd_soc_componen.patch b/patches.suse/ASoC-cs35l41-Add-endianness-flag-in-snd_soc_componen.patch new file mode 100644 index 0000000..00abfa1 --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Add-endianness-flag-in-snd_soc_componen.patch @@ -0,0 +1,33 @@ +From f0688b567fb88ba7636e87a5daed8a175275aa2e Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Wed, 4 May 2022 18:08:41 +0100 +Subject: [PATCH] ASoC: cs35l41: Add endianness flag in snd_soc_component_driver +Git-commit: f0688b567fb88ba7636e87a5daed8a175275aa2e +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +The endianness flag is used on the CODEC side to specify an +ambivalence to endian, typically because it is lost over the hardware +link. This device receives audio over an I2S DAI and as such should +have endianness applied. + +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20220504170905.332415-15-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs35l41.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -1025,6 +1025,8 @@ static const struct snd_soc_component_dr + .controls = cs35l41_aud_controls, + .num_controls = ARRAY_SIZE(cs35l41_aud_controls), + .set_sysclk = cs35l41_component_set_sysclk, ++ ++ .endianness = 1, + }; + + static int cs35l41_handle_pdata(struct device *dev, struct cs35l41_hw_cfg *hw_cfg) diff --git a/patches.suse/ASoC-cs35l41-Add-one-more-variable-in-the-debug-log-0f91bc71fe1f.patch b/patches.suse/ASoC-cs35l41-Add-one-more-variable-in-the-debug-log-0f91bc71fe1f.patch new file mode 100644 index 0000000..8d80832 --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Add-one-more-variable-in-the-debug-log-0f91bc71fe1f.patch @@ -0,0 +1,34 @@ +From 0f91bc71fe1f24b29e8980504a23681324713a0f Mon Sep 17 00:00:00 2001 +From: Hui Wang +Date: Mon, 28 Mar 2022 20:35:34 +0800 +Subject: [PATCH] ASoC: cs35l41: Add one more variable in the debug log +Git-commit: 0f91bc71fe1f24b29e8980504a23681324713a0f +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +otp_map[].size is a key variable to compute the value of otp_val and +to update the bit_offset, it is helpful to debug if could put it in +the debug log. + +Reviewed-by: Lucas Tanure +Signed-off-by: Hui Wang +Acked-by: Charles Keepax +Link: https://lore.kernel.org/r/20220328123535.50000-1-hui.wang@canonical.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs35l41-lib.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/sound/soc/codecs/cs35l41-lib.c ++++ b/sound/soc/codecs/cs35l41-lib.c +@@ -842,7 +842,7 @@ int cs35l41_otp_unpack(struct device *de + word_offset = otp_map_match->word_offset; + + for (i = 0; i < otp_map_match->num_elements; i++) { +- dev_dbg(dev, "bitoffset= %d, word_offset=%d, bit_sum mod 32=%d otp_map[i].size = %d\n", ++ dev_dbg(dev, "bitoffset= %d, word_offset=%d, bit_sum mod 32=%d, otp_map[i].size = %u\n", + bit_offset, word_offset, bit_sum % 32, otp_map[i].size); + if (bit_offset + otp_map[i].size - 1 >= 32) { + otp_val = (otp_mem[word_offset] & diff --git a/patches.suse/ASoC-cs35l41-Add-one-more-variable-in-the-debug-log.patch b/patches.suse/ASoC-cs35l41-Add-one-more-variable-in-the-debug-log.patch new file mode 100644 index 0000000..11ffc4c --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Add-one-more-variable-in-the-debug-log.patch @@ -0,0 +1,40 @@ +From c598ccfbeb26cb9452f99e7beb92ef779dcb16b1 Mon Sep 17 00:00:00 2001 +From: Hui Wang +Date: Thu, 24 Mar 2022 16:18:38 +0800 +Subject: [PATCH] ASoC: cs35l41: Add one more variable in the debug log +Git-commit: c598ccfbeb26cb9452f99e7beb92ef779dcb16b1 +Patch-mainline: v5.18-rc4 +References: bsc#1203699 + +otp_map[].size is a key variable to compute the value of otp_val and +to update the bit_offset, it is helpful to debug if could put it in +the debug log. + +Signed-off-by: Hui Wang +Reviewed-by: Lucas Tanure +Link: https://lore.kernel.org/r/20220324081839.62009-1-hui.wang@canonical.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs35l41-lib.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c +index e5a56bcbb223..d0a480c40231 100644 +--- a/sound/soc/codecs/cs35l41-lib.c ++++ b/sound/soc/codecs/cs35l41-lib.c +@@ -822,8 +822,8 @@ int cs35l41_otp_unpack(struct device *dev, struct regmap *regmap) + word_offset = otp_map_match->word_offset; + + for (i = 0; i < otp_map_match->num_elements; i++) { +- dev_dbg(dev, "bitoffset= %d, word_offset=%d, bit_sum mod 32=%d\n", +- bit_offset, word_offset, bit_sum % 32); ++ dev_dbg(dev, "bitoffset= %d, word_offset=%d, bit_sum mod 32=%d otp_map[i].size = %d\n", ++ bit_offset, word_offset, bit_sum % 32, otp_map[i].size); + if (bit_offset + otp_map[i].size - 1 >= 32) { + otp_val = (otp_mem[word_offset] & + GENMASK(31, bit_offset)) >> bit_offset; +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Add-support-for-CLSA3541-ACPI-device-ID.patch b/patches.suse/ASoC-cs35l41-Add-support-for-CLSA3541-ACPI-device-ID.patch new file mode 100644 index 0000000..d42fb86 --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Add-support-for-CLSA3541-ACPI-device-ID.patch @@ -0,0 +1,37 @@ +From 658e95953075ca781ef8712d0a3203e485888c7f Mon Sep 17 00:00:00 2001 +From: Cristian Ciocaltea +Date: Wed, 22 Jun 2022 00:38:19 +0300 +Subject: [PATCH] ASoC: cs35l41: Add support for CLSA3541 ACPI device ID +Git-commit: 658e95953075ca781ef8712d0a3203e485888c7f +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +Add support for the CLSA3541 ACPI device ID used on Valve's Steam Deck. +The driver is fully compatible with the indicated hardware, hence no +additional changes are required. + +Signed-off-by: Cristian Ciocaltea +Acked-by: David Rhodes +Link: https://lore.kernel.org/r/20220621213819.262537-1-cristian.ciocaltea@collabora.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs35l41-spi.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/soc/codecs/cs35l41-spi.c b/sound/soc/codecs/cs35l41-spi.c +index 9e19c946a66b..5c8bb24909eb 100644 +--- a/sound/soc/codecs/cs35l41-spi.c ++++ b/sound/soc/codecs/cs35l41-spi.c +@@ -74,6 +74,7 @@ MODULE_DEVICE_TABLE(of, cs35l41_of_match); + #ifdef CONFIG_ACPI + static const struct acpi_device_id cs35l41_acpi_match[] = { + { "CSC3541", 0 }, /* Cirrus Logic PnP ID + part ID */ ++ { "CLSA3541", 0 }, /* Cirrus Logic PnP ID + part ID */ + {}, + }; + MODULE_DEVICE_TABLE(acpi, cs35l41_acpi_match); +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Add-support-for-hibernate-memory-retent.patch b/patches.suse/ASoC-cs35l41-Add-support-for-hibernate-memory-retent.patch new file mode 100644 index 0000000..f839580 --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Add-support-for-hibernate-memory-retent.patch @@ -0,0 +1,419 @@ +From f517ba4924ad026f2583553db02f3c8bc69de88b Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Fri, 7 Jan 2022 16:06:36 +0000 +Subject: [PATCH] ASoC: cs35l41: Add support for hibernate memory retention mode +Git-commit: f517ba4924ad026f2583553db02f3c8bc69de88b +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +The cs35l41 supports a low power DSP memory retention mode. Add support +for entering this mode when then device is not in use. + +Co-authored-by: David Rhodes +Signed-off-by: David Rhodes +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20220107160636.6555-3-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + include/sound/cs35l41.h | 5 + + sound/soc/codecs/cs35l41-i2c.c | 1 + + sound/soc/codecs/cs35l41-lib.c | 6 + + sound/soc/codecs/cs35l41-spi.c | 1 + + sound/soc/codecs/cs35l41.c | 201 ++++++++++++++++++++++++++++++++- + sound/soc/codecs/cs35l41.h | 4 + + 6 files changed, 214 insertions(+), 4 deletions(-) + +diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h +index 56289b67b9a0..bf7f9a9aeba0 100644 +--- a/include/sound/cs35l41.h ++++ b/include/sound/cs35l41.h +@@ -40,6 +40,9 @@ + #define CS35L41_PROTECT_REL_ERR_IGN 0x00002034 + #define CS35L41_GPIO_PAD_CONTROL 0x0000242C + #define CS35L41_JTAG_CONTROL 0x00002438 ++#define CS35L41_PWRMGT_CTL 0x00002900 ++#define CS35L41_WAKESRC_CTL 0x00002904 ++#define CS35L41_PWRMGT_STS 0x00002908 + #define CS35L41_PLL_CLK_CTRL 0x00002C04 + #define CS35L41_DSP_CLK_CTRL 0x00002C08 + #define CS35L41_GLOBAL_CLK_CTRL 0x00002C0C +@@ -635,6 +638,8 @@ + #define CS35L41_INPUT_DSP_TX1 0x32 + #define CS35L41_INPUT_DSP_TX2 0x33 + ++#define CS35L41_WR_PEND_STS_MASK 0x2 ++ + #define CS35L41_PLL_CLK_SEL_MASK 0x07 + #define CS35L41_PLL_CLK_SEL_SHIFT 0 + #define CS35L41_PLL_CLK_EN_MASK 0x10 +diff --git a/sound/soc/codecs/cs35l41-i2c.c b/sound/soc/codecs/cs35l41-i2c.c +index eb8dfb6d9c95..faad5c638cb8 100644 +--- a/sound/soc/codecs/cs35l41-i2c.c ++++ b/sound/soc/codecs/cs35l41-i2c.c +@@ -86,6 +86,7 @@ MODULE_DEVICE_TABLE(acpi, cs35l41_acpi_match); + static struct i2c_driver cs35l41_i2c_driver = { + .driver = { + .name = "cs35l41", ++ .pm = &cs35l41_pm_ops, + .of_match_table = of_match_ptr(cs35l41_of_match), + .acpi_match_table = ACPI_PTR(cs35l41_acpi_match), + }, +diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c +index ecaf67fd7653..e5a56bcbb223 100644 +--- a/sound/soc/codecs/cs35l41-lib.c ++++ b/sound/soc/codecs/cs35l41-lib.c +@@ -90,6 +90,9 @@ static bool cs35l41_readable_reg(struct device *dev, unsigned int reg) + case CS35L41_PROTECT_REL_ERR_IGN: + case CS35L41_GPIO_PAD_CONTROL: + case CS35L41_JTAG_CONTROL: ++ case CS35L41_PWRMGT_CTL: ++ case CS35L41_WAKESRC_CTL: ++ case CS35L41_PWRMGT_STS: + case CS35L41_PLL_CLK_CTRL: + case CS35L41_DSP_CLK_CTRL: + case CS35L41_GLOBAL_CLK_CTRL: +@@ -376,6 +379,9 @@ static bool cs35l41_volatile_reg(struct device *dev, unsigned int reg) + case CS35L41_OTPID: + case CS35L41_TEST_KEY_CTL: + case CS35L41_USER_KEY_CTL: ++ case CS35L41_PWRMGT_CTL: ++ case CS35L41_WAKESRC_CTL: ++ case CS35L41_PWRMGT_STS: + case CS35L41_DTEMP_EN: + case CS35L41_IRQ1_STATUS: + case CS35L41_IRQ1_STATUS1: +diff --git a/sound/soc/codecs/cs35l41-spi.c b/sound/soc/codecs/cs35l41-spi.c +index 86bbe2fba956..6dfd5459aa20 100644 +--- a/sound/soc/codecs/cs35l41-spi.c ++++ b/sound/soc/codecs/cs35l41-spi.c +@@ -84,6 +84,7 @@ MODULE_DEVICE_TABLE(acpi, cs35l41_acpi_match); + static struct spi_driver cs35l41_spi_driver = { + .driver = { + .name = "cs35l41", ++ .pm = &cs35l41_pm_ops, + .of_match_table = of_match_ptr(cs35l41_of_match), + .acpi_match_table = ACPI_PTR(cs35l41_acpi_match), + }, +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index e1b9fd8ee996..77a017694645 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -187,8 +188,14 @@ static int cs35l41_dsp_preload_ev(struct snd_soc_dapm_widget *w, + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: ++ if (cs35l41->dsp.cs_dsp.booted) ++ return 0; ++ + return wm_adsp_early_event(w, kcontrol, event); + case SND_SOC_DAPM_PRE_PMD: ++ if (cs35l41->dsp.preloaded) ++ return 0; ++ + if (cs35l41->dsp.cs_dsp.running) { + ret = wm_adsp_event(w, kcontrol, event); + if (ret) +@@ -209,6 +216,7 @@ static bool cs35l41_check_cspl_mbox_sts(enum cs35l41_cspl_mbox_cmd cmd, + case CSPL_MBOX_CMD_UNKNOWN_CMD: + return true; + case CSPL_MBOX_CMD_PAUSE: ++ case CSPL_MBOX_CMD_OUT_OF_HIBERNATE: + return (sts == CSPL_MBOX_STS_PAUSED); + case CSPL_MBOX_CMD_RESUME: + return (sts == CSPL_MBOX_STS_RUNNING); +@@ -230,7 +238,8 @@ static int cs35l41_set_cspl_mbox_cmd(struct cs35l41_private *cs35l41, + // Set mailbox cmd + ret = regmap_write(cs35l41->regmap, CS35L41_DSP_VIRT1_MBOX_1, cmd); + if (ret < 0) { +- dev_err(cs35l41->dev, "Failed to write MBOX: %d\n", ret); ++ if (cmd != CSPL_MBOX_CMD_OUT_OF_HIBERNATE) ++ dev_err(cs35l41->dev, "Failed to write MBOX: %d\n", ret); + return ret; + } + +@@ -413,6 +422,8 @@ static irqreturn_t cs35l41_irq(int irq, void *data) + int ret = IRQ_NONE; + unsigned int i; + ++ pm_runtime_get_sync(cs35l41->dev); ++ + for (i = 0; i < ARRAY_SIZE(status); i++) { + regmap_read(cs35l41->regmap, + CS35L41_IRQ1_STATUS1 + (i * CS35L41_REGSTRIDE), +@@ -425,7 +436,7 @@ static irqreturn_t cs35l41_irq(int irq, void *data) + /* Check to see if unmasked bits are active */ + if (!(status[0] & ~masks[0]) && !(status[1] & ~masks[1]) && + !(status[2] & ~masks[2]) && !(status[3] & ~masks[3])) +- return IRQ_NONE; ++ goto done; + + if (status[3] & CS35L41_OTP_BOOT_DONE) { + regmap_update_bits(cs35l41->regmap, CS35L41_IRQ1_MASK4, +@@ -530,6 +541,10 @@ static irqreturn_t cs35l41_irq(int irq, void *data) + ret = IRQ_HANDLED; + } + ++done: ++ pm_runtime_mark_last_busy(cs35l41->dev); ++ pm_runtime_put_autosuspend(cs35l41->dev); ++ + return ret; + } + +@@ -1180,6 +1195,7 @@ static int cs35l41_dsp_init(struct cs35l41_private *cs35l41) + dsp->cs_dsp.type = WMFW_HALO; + dsp->cs_dsp.rev = 0; + dsp->fw = 9; /* 9 is WM_ADSP_FW_SPK_PROT in wm_adsp.c */ ++ dsp->toggle_preload = true; + dsp->cs_dsp.dev = cs35l41->dev; + dsp->cs_dsp.regmap = cs35l41->regmap; + dsp->cs_dsp.base = CS35L41_DSP1_CTRL_BASE; +@@ -1367,20 +1383,32 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, + if (ret < 0) + goto err; + ++ pm_runtime_set_autosuspend_delay(cs35l41->dev, 3000); ++ pm_runtime_use_autosuspend(cs35l41->dev); ++ pm_runtime_mark_last_busy(cs35l41->dev); ++ pm_runtime_set_active(cs35l41->dev); ++ pm_runtime_get_noresume(cs35l41->dev); ++ pm_runtime_enable(cs35l41->dev); ++ + ret = devm_snd_soc_register_component(cs35l41->dev, + &soc_component_dev_cs35l41, + cs35l41_dai, ARRAY_SIZE(cs35l41_dai)); + if (ret < 0) { + dev_err(cs35l41->dev, "Register codec failed: %d\n", ret); +- goto err_dsp; ++ goto err_pm; + } + ++ pm_runtime_put_autosuspend(cs35l41->dev); ++ + dev_info(cs35l41->dev, "Cirrus Logic CS35L41 (%x), Revision: %02X\n", + regid, reg_revid); + + return 0; + +-err_dsp: ++err_pm: ++ pm_runtime_disable(cs35l41->dev); ++ pm_runtime_put_noidle(cs35l41->dev); ++ + wm_adsp2_remove(&cs35l41->dsp); + err: + regulator_bulk_disable(CS35L41_NUM_SUPPLIES, cs35l41->supplies); +@@ -1392,13 +1420,178 @@ EXPORT_SYMBOL_GPL(cs35l41_probe); + + void cs35l41_remove(struct cs35l41_private *cs35l41) + { ++ pm_runtime_get_sync(cs35l41->dev); ++ pm_runtime_disable(cs35l41->dev); ++ + regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, 0xFFFFFFFF); + wm_adsp2_remove(&cs35l41->dsp); ++ ++ pm_runtime_put_noidle(cs35l41->dev); ++ + regulator_bulk_disable(CS35L41_NUM_SUPPLIES, cs35l41->supplies); + gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); + } + EXPORT_SYMBOL_GPL(cs35l41_remove); + ++static int __maybe_unused cs35l41_runtime_suspend(struct device *dev) ++{ ++ struct cs35l41_private *cs35l41 = dev_get_drvdata(dev); ++ ++ dev_dbg(cs35l41->dev, "Runtime suspend\n"); ++ ++ if (!cs35l41->dsp.preloaded || !cs35l41->dsp.cs_dsp.running) ++ return 0; ++ ++ dev_dbg(cs35l41->dev, "Enter hibernate\n"); ++ ++ regmap_write(cs35l41->regmap, CS35L41_WAKESRC_CTL, 0x0088); ++ regmap_write(cs35l41->regmap, CS35L41_WAKESRC_CTL, 0x0188); ++ ++ // Don't wait for ACK since bus activity would wake the device ++ regmap_write(cs35l41->regmap, CS35L41_DSP_VIRT1_MBOX_1, ++ CSPL_MBOX_CMD_HIBERNATE); ++ ++ regcache_cache_only(cs35l41->regmap, true); ++ regcache_mark_dirty(cs35l41->regmap); ++ ++ return 0; ++} ++ ++static void cs35l41_wait_for_pwrmgt_sts(struct cs35l41_private *cs35l41) ++{ ++ const int pwrmgt_retries = 10; ++ unsigned int sts; ++ int i, ret; ++ ++ for (i = 0; i < pwrmgt_retries; i++) { ++ ret = regmap_read(cs35l41->regmap, CS35L41_PWRMGT_STS, &sts); ++ if (ret) ++ dev_err(cs35l41->dev, "Failed to read PWRMGT_STS: %d\n", ret); ++ else if (!(sts & CS35L41_WR_PEND_STS_MASK)) ++ return; ++ ++ udelay(20); ++ } ++ ++ dev_err(cs35l41->dev, "Timed out reading PWRMGT_STS\n"); ++} ++ ++static int cs35l41_exit_hibernate(struct cs35l41_private *cs35l41) ++{ ++ const int wake_retries = 20; ++ const int sleep_retries = 5; ++ int ret, i, j; ++ ++ for (i = 0; i < sleep_retries; i++) { ++ dev_dbg(cs35l41->dev, "Exit hibernate\n"); ++ ++ for (j = 0; j < wake_retries; j++) { ++ ret = cs35l41_set_cspl_mbox_cmd(cs35l41, ++ CSPL_MBOX_CMD_OUT_OF_HIBERNATE); ++ if (!ret) ++ break; ++ ++ usleep_range(100, 200); ++ } ++ ++ if (j < wake_retries) { ++ dev_dbg(cs35l41->dev, "Wake success at cycle: %d\n", j); ++ return 0; ++ } ++ ++ dev_err(cs35l41->dev, "Wake failed, re-enter hibernate: %d\n", ret); ++ ++ cs35l41_wait_for_pwrmgt_sts(cs35l41); ++ regmap_write(cs35l41->regmap, CS35L41_WAKESRC_CTL, 0x0088); ++ ++ cs35l41_wait_for_pwrmgt_sts(cs35l41); ++ regmap_write(cs35l41->regmap, CS35L41_WAKESRC_CTL, 0x0188); ++ ++ cs35l41_wait_for_pwrmgt_sts(cs35l41); ++ regmap_write(cs35l41->regmap, CS35L41_PWRMGT_CTL, 0x3); ++ } ++ ++ dev_err(cs35l41->dev, "Timed out waking device\n"); ++ ++ return -ETIMEDOUT; ++} ++ ++static int __maybe_unused cs35l41_runtime_resume(struct device *dev) ++{ ++ struct cs35l41_private *cs35l41 = dev_get_drvdata(dev); ++ int ret; ++ ++ dev_dbg(cs35l41->dev, "Runtime resume\n"); ++ ++ if (!cs35l41->dsp.preloaded || !cs35l41->dsp.cs_dsp.running) ++ return 0; ++ ++ regcache_cache_only(cs35l41->regmap, false); ++ ++ ret = cs35l41_exit_hibernate(cs35l41); ++ if (ret) ++ return ret; ++ ++ /* Test key needs to be unlocked to allow the OTP settings to re-apply */ ++ cs35l41_test_key_unlock(cs35l41->dev, cs35l41->regmap); ++ ret = regcache_sync(cs35l41->regmap); ++ cs35l41_test_key_lock(cs35l41->dev, cs35l41->regmap); ++ if (ret) { ++ dev_err(cs35l41->dev, "Failed to restore register cache: %d\n", ret); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int __maybe_unused cs35l41_sys_suspend(struct device *dev) ++{ ++ struct cs35l41_private *cs35l41 = dev_get_drvdata(dev); ++ ++ dev_dbg(cs35l41->dev, "System suspend, disabling IRQ\n"); ++ disable_irq(cs35l41->irq); ++ ++ return 0; ++} ++ ++static int __maybe_unused cs35l41_sys_suspend_noirq(struct device *dev) ++{ ++ struct cs35l41_private *cs35l41 = dev_get_drvdata(dev); ++ ++ dev_dbg(cs35l41->dev, "Late system suspend, reenabling IRQ\n"); ++ enable_irq(cs35l41->irq); ++ ++ return 0; ++} ++ ++static int __maybe_unused cs35l41_sys_resume_noirq(struct device *dev) ++{ ++ struct cs35l41_private *cs35l41 = dev_get_drvdata(dev); ++ ++ dev_dbg(cs35l41->dev, "Early system resume, disabling IRQ\n"); ++ disable_irq(cs35l41->irq); ++ ++ return 0; ++} ++ ++static int __maybe_unused cs35l41_sys_resume(struct device *dev) ++{ ++ struct cs35l41_private *cs35l41 = dev_get_drvdata(dev); ++ ++ dev_dbg(cs35l41->dev, "System resume, reenabling IRQ\n"); ++ enable_irq(cs35l41->irq); ++ ++ return 0; ++} ++ ++const struct dev_pm_ops cs35l41_pm_ops = { ++ SET_RUNTIME_PM_OPS(cs35l41_runtime_suspend, cs35l41_runtime_resume, NULL) ++ ++ SET_SYSTEM_SLEEP_PM_OPS(cs35l41_sys_suspend, cs35l41_sys_resume) ++ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(cs35l41_sys_suspend_noirq, cs35l41_sys_resume_noirq) ++}; ++EXPORT_SYMBOL_GPL(cs35l41_pm_ops); ++ + MODULE_DESCRIPTION("ASoC CS35L41 driver"); + MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, "); + MODULE_LICENSE("GPL"); +diff --git a/sound/soc/codecs/cs35l41.h b/sound/soc/codecs/cs35l41.h +index 26a08d58a8c3..88a3d6e3434f 100644 +--- a/sound/soc/codecs/cs35l41.h ++++ b/sound/soc/codecs/cs35l41.h +@@ -21,6 +21,8 @@ + #define CS35L41_RX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) + #define CS35L41_TX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) + ++extern const struct dev_pm_ops cs35l41_pm_ops; ++ + enum cs35l41_cspl_mbox_status { + CSPL_MBOX_STS_RUNNING = 0, + CSPL_MBOX_STS_PAUSED = 1, +@@ -33,6 +35,8 @@ enum cs35l41_cspl_mbox_cmd { + CSPL_MBOX_CMD_RESUME = 2, + CSPL_MBOX_CMD_REINIT = 3, + CSPL_MBOX_CMD_STOP_PRE_REINIT = 4, ++ CSPL_MBOX_CMD_HIBERNATE = 5, ++ CSPL_MBOX_CMD_OUT_OF_HIBERNATE = 6, + CSPL_MBOX_CMD_UNKNOWN_CMD = -1, + CSPL_MBOX_CMD_INVALID_SEQUENCE = -2, + }; +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Binding-fixes.patch b/patches.suse/ASoC-cs35l41-Binding-fixes.patch new file mode 100644 index 0000000..40c046d --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Binding-fixes.patch @@ -0,0 +1,352 @@ +From 6116df7fafabbd9b2b09bfd8d568cd5fad656125 Mon Sep 17 00:00:00 2001 +From: David Rhodes +Date: Wed, 15 Sep 2021 14:14:22 -0500 +Subject: [PATCH] ASoC: cs35l41: Binding fixes +Git-commit: 6116df7fafabbd9b2b09bfd8d568cd5fad656125 +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +Fix warnings and errors in DT bindings + +Add newline at end of file +Replace 'unevaluatedProperties' with 'additionalProperties' +Add spi context to DT example +Add #sound-dai-cells to DT example +Rename to 'cirrus,cs35l41.yaml' + +Signed-off-by: David Rhodes +Link: https://lore.kernel.org/r/20210915191422.2371623-1-drhodes@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + .../bindings/sound/cirrus,cs35l41.yaml | 157 ++++++++++++++++++ + .../devicetree/bindings/sound/cs35l41.yaml | 151 ----------------- + 2 files changed, 157 insertions(+), 151 deletions(-) + create mode 100644 Documentation/devicetree/bindings/sound/cirrus,cs35l41.yaml + delete mode 100644 Documentation/devicetree/bindings/sound/cs35l41.yaml + +diff --git a/Documentation/devicetree/bindings/sound/cirrus,cs35l41.yaml b/Documentation/devicetree/bindings/sound/cirrus,cs35l41.yaml +new file mode 100644 +index 000000000000..3235702ce402 +--- /dev/null ++++ b/Documentation/devicetree/bindings/sound/cirrus,cs35l41.yaml +@@ -0,0 +1,157 @@ ++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/sound/cirrus,cs35l41.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Cirrus Logic CS35L41 Speaker Amplifier ++ ++maintainers: ++ - david.rhodes@cirrus.com ++ ++description: | ++ CS35L41 is a boosted mono Class D amplifier with DSP ++ speaker protection and equalization ++ ++properties: ++ compatible: ++ enum: ++ - cirrus,cs35l40 ++ - cirrus,cs35l41 ++ ++ reg: ++ maxItems: 1 ++ ++ '#sound-dai-cells': ++ description: ++ The first cell indicating the audio interface. ++ const: 1 ++ ++ reset-gpios: ++ maxItems: 1 ++ ++ VA-supply: ++ description: voltage regulator phandle for the VA supply ++ ++ VP-supply: ++ description: voltage regulator phandle for the VP supply ++ ++ cirrus,boost-peak-milliamp: ++ description: ++ Boost-converter peak current limit in mA. ++ Configures the peak current by monitoring the current through the boost FET. ++ Range starts at 1600 mA and goes to a maximum of 4500 mA with increments ++ of 50 mA. See section 4.3.6 of the datasheet for details. ++ $ref: "/schemas/types.yaml#/definitions/uint32" ++ minimum: 1600 ++ maximum: 4500 ++ default: 4500 ++ ++ cirrus,boost-ind-nanohenry: ++ description: ++ Boost inductor value, expressed in nH. Valid ++ values include 1000, 1200, 1500 and 2200. ++ $ref: "/schemas/types.yaml#/definitions/uint32" ++ minimum: 1000 ++ maximum: 2200 ++ ++ cirrus,boost-cap-microfarad: ++ description: ++ Total equivalent boost capacitance on the VBST ++ and VAMP pins, derated at 11 volts DC. The value must be rounded to the ++ nearest integer and expressed in uF. ++ $ref: "/schemas/types.yaml#/definitions/uint32" ++ ++ cirrus,asp-sdout-hiz: ++ description: ++ Audio serial port SDOUT Hi-Z control. Sets the Hi-Z ++ configuration for SDOUT pin of amplifier. ++ 0 = Logic 0 during unused slots, and while all transmit channels disabled ++ 1 = Hi-Z during unused slots but logic 0 while all transmit channels disabled ++ 2 = (Default) Logic 0 during unused slots, but Hi-Z while all transmit channels disabled ++ 3 = Hi-Z during unused slots and while all transmit channels disabled ++ $ref: "/schemas/types.yaml#/definitions/uint32" ++ minimum: 0 ++ maximum: 3 ++ default: 2 ++ ++ cirrus,gpio1-polarity-invert: ++ description: ++ Boolean which specifies whether the GPIO1 ++ level is inverted. If this property is not present the level is not inverted. ++ type: boolean ++ ++ cirrus,gpio1-output-enable: ++ description: ++ Boolean which specifies whether the GPIO1 pin ++ is configured as an output. If this property is not present the ++ pin will be configured as an input. ++ type: boolean ++ ++ cirrus,gpio1-src-select: ++ description: ++ Configures the function of the GPIO1 pin. ++ Note that the options are different from the GPIO2 pin ++ 0 = High Impedance (Default) ++ 1 = GPIO ++ 2 = Sync ++ 3 = MCLK input ++ $ref: "/schemas/types.yaml#/definitions/uint32" ++ minimum: 0 ++ maximum: 3 ++ ++ cirrus,gpio2-polarity-invert: ++ description: ++ Boolean which specifies whether the GPIO2 ++ level is inverted. If this property is not present the level is not inverted. ++ type: boolean ++ ++ cirrus,gpio2-output-enable: ++ description: ++ Boolean which specifies whether the GPIO2 pin ++ is configured as an output. If this property is not present the ++ pin will be configured as an input. ++ type: boolean ++ ++ cirrus,gpio2-src-select: ++ description: ++ Configures the function of the GPIO2 pin. ++ Note that the options are different from the GPIO1 pin. ++ 0 = High Impedance (Default) ++ 1 = GPIO ++ 2 = Open Drain INTB ++ 3 = MCLK input ++ 4 = Push-pull INTB (active low) ++ 5 = Push-pull INT (active high) ++ $ref: "/schemas/types.yaml#/definitions/uint32" ++ minimum: 0 ++ maximum: 5 ++ ++required: ++ - compatible ++ - reg ++ - "#sound-dai-cells" ++ - cirrus,boost-peak-milliamp ++ - cirrus,boost-ind-nanohenry ++ - cirrus,boost-cap-microfarad ++ ++additionalProperties: false ++ ++examples: ++ - | ++ spi { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cs35l41: cs35l41@2 { ++ #sound-dai-cells = <1>; ++ compatible = "cirrus,cs35l41"; ++ reg = <2>; ++ VA-supply = <&dummy_vreg>; ++ VP-supply = <&dummy_vreg>; ++ reset-gpios = <&gpio 110 0>; ++ cirrus,boost-peak-milliamp = <4500>; ++ cirrus,boost-ind-nanohenry = <1000>; ++ cirrus,boost-cap-microfarad = <15>; ++ }; ++ }; +diff --git a/Documentation/devicetree/bindings/sound/cs35l41.yaml b/Documentation/devicetree/bindings/sound/cs35l41.yaml +deleted file mode 100644 +index fde78c850286..000000000000 +--- a/Documentation/devicetree/bindings/sound/cs35l41.yaml ++++ /dev/null +@@ -1,151 +0,0 @@ +-# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +-%YAML 1.2 +---- +-$id: http://devicetree.org/schemas/sound/cs35l41.yaml# +-$schema: http://devicetree.org/meta-schemas/core.yaml# +- +-title: Cirrus Logic CS35L41 Speaker Amplifier +- +-maintainers: +- - david.rhodes@cirrus.com +- +-description: | +- CS35L41 is a boosted mono Class D amplifier with DSP +- speaker protection and equalization +- +-properties: +- compatible: +- enum: +- - cirrus,cs35l40 +- - cirrus,cs35l41 +- +- reg: +- maxItems: 1 +- +- '#sound-dai-cells': +- description: +- The first cell indicating the audio interface. +- const: 1 +- +- reset-gpios: +- maxItems: 1 +- +- VA-supply: +- description: voltage regulator phandle for the VA supply +- +- VP-supply: +- description: voltage regulator phandle for the VP supply +- +- cirrus,boost-peak-milliamp: +- description: +- Boost-converter peak current limit in mA. +- Configures the peak current by monitoring the current through the boost FET. +- Range starts at 1600 mA and goes to a maximum of 4500 mA with increments +- of 50 mA. See section 4.3.6 of the datasheet for details. +- $ref: "/schemas/types.yaml#/definitions/uint32" +- minimum: 1600 +- maximum: 4500 +- default: 4500 +- +- cirrus,boost-ind-nanohenry: +- description: +- Boost inductor value, expressed in nH. Valid +- values include 1000, 1200, 1500 and 2200. +- $ref: "/schemas/types.yaml#/definitions/uint32" +- minimum: 1000 +- maximum: 2200 +- +- cirrus,boost-cap-microfarad: +- description: +- Total equivalent boost capacitance on the VBST +- and VAMP pins, derated at 11 volts DC. The value must be rounded to the +- nearest integer and expressed in uF. +- $ref: "/schemas/types.yaml#/definitions/uint32" +- +- cirrus,asp-sdout-hiz: +- description: +- Audio serial port SDOUT Hi-Z control. Sets the Hi-Z +- configuration for SDOUT pin of amplifier. +- 0 = Logic 0 during unused slots, and while all transmit channels disabled +- 1 = Hi-Z during unused slots but logic 0 while all transmit channels disabled +- 2 = (Default) Logic 0 during unused slots, but Hi-Z while all transmit channels disabled +- 3 = Hi-Z during unused slots and while all transmit channels disabled +- $ref: "/schemas/types.yaml#/definitions/uint32" +- minimum: 0 +- maximum: 3 +- default: 2 +- +- cirrus,gpio1-polarity-invert: +- description: +- Boolean which specifies whether the GPIO1 +- level is inverted. If this property is not present the level is not inverted. +- type: boolean +- +- cirrus,gpio1-output-enable: +- description: +- Boolean which specifies whether the GPIO1 pin +- is configured as an output. If this property is not present the +- pin will be configured as an input. +- type: boolean +- +- cirrus,gpio1-src-select: +- description: +- Configures the function of the GPIO1 pin. +- Note that the options are different from the GPIO2 pin +- 0 = High Impedance (Default) +- 1 = GPIO +- 2 = Sync +- 3 = MCLK input +- $ref: "/schemas/types.yaml#/definitions/uint32" +- minimum: 0 +- maximum: 3 +- +- cirrus,gpio2-polarity-invert: +- description: +- Boolean which specifies whether the GPIO2 +- level is inverted. If this property is not present the level is not inverted. +- type: boolean +- +- cirrus,gpio2-output-enable: +- description: +- Boolean which specifies whether the GPIO2 pin +- is configured as an output. If this property is not present the +- pin will be configured as an input. +- type: boolean +- +- cirrus,gpio2-src-select: +- description: +- Configures the function of the GPIO2 pin. +- Note that the options are different from the GPIO1 pin. +- 0 = High Impedance (Default) +- 1 = GPIO +- 2 = Open Drain INTB +- 3 = MCLK input +- 4 = Push-pull INTB (active low) +- 5 = Push-pull INT (active high) +- $ref: "/schemas/types.yaml#/definitions/uint32" +- minimum: 0 +- maximum: 5 +- +-required: +- - compatible +- - reg +- - "#sound-dai-cells" +- - cirrus,boost-peak-milliamp +- - cirrus,boost-ind-nanohenry +- - cirrus,boost-cap-microfarad +- +-unevaluatedProperties: false +- +-examples: +- - | +- cs35l41: cs35l41@2 { +- compatible = "cirrus,cs35l41"; +- reg = <2>; +- VA-supply = <&dummy_vreg>; +- VP-supply = <&dummy_vreg>; +- reset-gpios = <&gpio 110 0>; +- cirrus,boost-peak-milliamp = <4500>; +- cirrus,boost-ind-nanohenry = <1000>; +- cirrus,boost-cap-microfarad = <15>; +- }; +\ No newline at end of file +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-CS35L41-Boosted-Smart-Amplifier.patch b/patches.suse/ASoC-cs35l41-CS35L41-Boosted-Smart-Amplifier.patch new file mode 100644 index 0000000..70cab75 --- /dev/null +++ b/patches.suse/ASoC-cs35l41-CS35L41-Boosted-Smart-Amplifier.patch @@ -0,0 +1,3332 @@ +From 6450ef55905688602175fae4ed1bfbfef6a14dde Mon Sep 17 00:00:00 2001 +From: David Rhodes +Date: Tue, 7 Sep 2021 17:57:18 -0500 +Subject: [PATCH] ASoC: cs35l41: CS35L41 Boosted Smart Amplifier +Git-commit: 6450ef55905688602175fae4ed1bfbfef6a14dde +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +SoC Audio driver for the Cirrus Logic CS35L41 amplifier + +Signed-off-by: David Rhodes +Tested-by: Charles Keepax +Link: https://lore.kernel.org/r/20210907225719.2018115-2-drhodes@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + include/sound/cs35l41.h | 34 + + sound/soc/codecs/Kconfig | 12 + + sound/soc/codecs/Makefile | 4 + + sound/soc/codecs/cs35l41-i2c.c | 114 +++ + sound/soc/codecs/cs35l41-spi.c | 143 +++ + sound/soc/codecs/cs35l41-tables.c | 597 +++++++++++ + sound/soc/codecs/cs35l41.c | 1545 +++++++++++++++++++++++++++++ + sound/soc/codecs/cs35l41.h | 775 +++++++++++++++ + 8 files changed, 3224 insertions(+) + create mode 100644 include/sound/cs35l41.h + create mode 100644 sound/soc/codecs/cs35l41-i2c.c + create mode 100644 sound/soc/codecs/cs35l41-spi.c + create mode 100644 sound/soc/codecs/cs35l41-tables.c + create mode 100644 sound/soc/codecs/cs35l41.c + create mode 100644 sound/soc/codecs/cs35l41.h + +diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h +new file mode 100644 +index 000000000000..1f1e3c6c9be1 +--- /dev/null ++++ b/include/sound/cs35l41.h +@@ -0,0 +1,34 @@ ++/* SPDX-License-Identifier: GPL-2.0 ++ * ++ * linux/sound/cs35l41.h -- Platform data for CS35L41 ++ * ++ * Copyright (c) 2017-2021 Cirrus Logic Inc. ++ * ++ * Author: David Rhodes ++ */ ++ ++#ifndef __CS35L41_H ++#define __CS35L41_H ++ ++enum cs35l41_clk_ids { ++ CS35L41_CLKID_SCLK = 0, ++ CS35L41_CLKID_LRCLK = 1, ++ CS35L41_CLKID_MCLK = 4, ++}; ++ ++struct cs35l41_irq_cfg { ++ bool irq_pol_inv; ++ bool irq_out_en; ++ int irq_src_sel; ++}; ++ ++struct cs35l41_platform_data { ++ int bst_ind; ++ int bst_ipk; ++ int bst_cap; ++ int dout_hiz; ++ struct cs35l41_irq_cfg irq_config1; ++ struct cs35l41_irq_cfg irq_config2; ++}; ++ ++#endif /* __CS35L41_H */ +diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig +index 82ee233a269d..53aa20bc7707 100644 +--- a/sound/soc/codecs/Kconfig ++++ b/sound/soc/codecs/Kconfig +@@ -61,6 +61,8 @@ config SND_SOC_ALL_CODECS + imply SND_SOC_CS35L34 + imply SND_SOC_CS35L35 + imply SND_SOC_CS35L36 ++ imply SND_SOC_CS35L41_SPI ++ imply SND_SOC_CS35L41_I2C + imply SND_SOC_CS42L42 + imply SND_SOC_CS42L51_I2C + imply SND_SOC_CS42L52 +@@ -602,6 +604,16 @@ config SND_SOC_CS35L36 + tristate "Cirrus Logic CS35L36 CODEC" + depends on I2C + ++config SND_SOC_CS35L41_SPI ++ tristate "Cirrus Logic CS35L41 CODEC (SPI)" ++ depends on SPI_MASTER ++ select REGMAP_SPI ++ ++config SND_SOC_CS35L41_I2C ++ tristate "Cirrus Logic CS35L41 CODEC (I2C)" ++ depends on I2C ++ select REGMAP_I2C ++ + config SND_SOC_CS42L42 + tristate "Cirrus Logic CS42L42 CODEC" + depends on I2C +diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile +index 8dcea2c4604a..8b580a9004ea 100644 +--- a/sound/soc/codecs/Makefile ++++ b/sound/soc/codecs/Makefile +@@ -54,6 +54,8 @@ snd-soc-cs35l33-objs := cs35l33.o + snd-soc-cs35l34-objs := cs35l34.o + snd-soc-cs35l35-objs := cs35l35.o + snd-soc-cs35l36-objs := cs35l36.o ++snd-soc-cs35l41-spi-objs := cs35l41-spi.o cs35l41.o cs35l41-tables.o ++snd-soc-cs35l41-i2c-objs := cs35l41-i2c.o cs35l41.o cs35l41-tables.o + snd-soc-cs42l42-objs := cs42l42.o + snd-soc-cs42l51-objs := cs42l51.o + snd-soc-cs42l51-i2c-objs := cs42l51-i2c.o +@@ -385,6 +387,8 @@ obj-$(CONFIG_SND_SOC_CS35L33) += snd-soc-cs35l33.o + obj-$(CONFIG_SND_SOC_CS35L34) += snd-soc-cs35l34.o + obj-$(CONFIG_SND_SOC_CS35L35) += snd-soc-cs35l35.o + obj-$(CONFIG_SND_SOC_CS35L36) += snd-soc-cs35l36.o ++obj-$(CONFIG_SND_SOC_CS35L41_SPI) += snd-soc-cs35l41-spi.o ++obj-$(CONFIG_SND_SOC_CS35L41_I2C) += snd-soc-cs35l41-i2c.o + obj-$(CONFIG_SND_SOC_CS42L42) += snd-soc-cs42l42.o + obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o + obj-$(CONFIG_SND_SOC_CS42L51_I2C) += snd-soc-cs42l51-i2c.o +diff --git a/sound/soc/codecs/cs35l41-i2c.c b/sound/soc/codecs/cs35l41-i2c.c +new file mode 100644 +index 000000000000..dc9da78df412 +--- /dev/null ++++ b/sound/soc/codecs/cs35l41-i2c.c +@@ -0,0 +1,114 @@ ++// SPDX-License-Identifier: GPL-2.0 ++// ++// cs35l41-i2c.c -- CS35l41 I2C driver ++// ++// Copyright 2017-2021 Cirrus Logic, Inc. ++// ++// Author: David Rhodes ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include "cs35l41.h" ++ ++static struct regmap_config cs35l41_regmap_i2c = { ++ .reg_bits = 32, ++ .val_bits = 32, ++ .reg_stride = CS35L41_REGSTRIDE, ++ .reg_format_endian = REGMAP_ENDIAN_BIG, ++ .val_format_endian = REGMAP_ENDIAN_BIG, ++ .max_register = CS35L41_LASTREG, ++ .reg_defaults = cs35l41_reg, ++ .num_reg_defaults = ARRAY_SIZE(cs35l41_reg), ++ .volatile_reg = cs35l41_volatile_reg, ++ .readable_reg = cs35l41_readable_reg, ++ .precious_reg = cs35l41_precious_reg, ++ .cache_type = REGCACHE_RBTREE, ++}; ++ ++static const struct i2c_device_id cs35l41_id_i2c[] = { ++ { "cs35l40", 0 }, ++ { "cs35l41", 0 }, ++ {} ++}; ++ ++MODULE_DEVICE_TABLE(i2c, cs35l41_id_i2c); ++ ++static int cs35l41_i2c_probe(struct i2c_client *client, ++ const struct i2c_device_id *id) ++{ ++ struct cs35l41_private *cs35l41; ++ struct device *dev = &client->dev; ++ struct cs35l41_platform_data *pdata = dev_get_platdata(dev); ++ const struct regmap_config *regmap_config = &cs35l41_regmap_i2c; ++ int ret; ++ ++ cs35l41 = devm_kzalloc(dev, sizeof(struct cs35l41_private), GFP_KERNEL); ++ ++ if (!cs35l41) ++ return -ENOMEM; ++ ++ cs35l41->dev = dev; ++ cs35l41->irq = client->irq; ++ ++ i2c_set_clientdata(client, cs35l41); ++ cs35l41->regmap = devm_regmap_init_i2c(client, regmap_config); ++ if (IS_ERR(cs35l41->regmap)) { ++ ret = PTR_ERR(cs35l41->regmap); ++ dev_err(cs35l41->dev, "Failed to allocate register map: %d\n", ++ ret); ++ return ret; ++ } ++ ++ return cs35l41_probe(cs35l41, pdata); ++} ++ ++static int cs35l41_i2c_remove(struct i2c_client *client) ++{ ++ struct cs35l41_private *cs35l41 = i2c_get_clientdata(client); ++ ++ return cs35l41_remove(cs35l41); ++} ++ ++#ifdef CONFIG_OF ++static const struct of_device_id cs35l41_of_match[] = { ++ { .compatible = "cirrus,cs35l40" }, ++ { .compatible = "cirrus,cs35l41" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, cs35l41_of_match); ++#endif ++ ++#ifdef CONFIG_ACPI ++static const struct acpi_device_id cs35l41_acpi_match[] = { ++ { "CSC3541", 0 }, /* Cirrus Logic PnP ID + part ID */ ++ {}, ++}; ++MODULE_DEVICE_TABLE(acpi, cs35l41_acpi_match); ++#endif ++ ++static struct i2c_driver cs35l41_i2c_driver = { ++ .driver = { ++ .name = "cs35l41", ++ .of_match_table = of_match_ptr(cs35l41_of_match), ++ .acpi_match_table = ACPI_PTR(cs35l41_acpi_match), ++ }, ++ .id_table = cs35l41_id_i2c, ++ .probe = cs35l41_i2c_probe, ++ .remove = cs35l41_i2c_remove, ++}; ++ ++module_i2c_driver(cs35l41_i2c_driver); ++ ++MODULE_DESCRIPTION("I2C CS35L41 driver"); ++MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, "); ++MODULE_LICENSE("GPL"); +diff --git a/sound/soc/codecs/cs35l41-spi.c b/sound/soc/codecs/cs35l41-spi.c +new file mode 100644 +index 000000000000..e253c6d82ce8 +--- /dev/null ++++ b/sound/soc/codecs/cs35l41-spi.c +@@ -0,0 +1,143 @@ ++// SPDX-License-Identifier: GPL-2.0 ++// ++// cs35l41-spi.c -- CS35l41 SPI driver ++// ++// Copyright 2017-2021 Cirrus Logic, Inc. ++// ++// Author: David Rhodes ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include "cs35l41.h" ++ ++static struct regmap_config cs35l41_regmap_spi = { ++ .reg_bits = 32, ++ .val_bits = 32, ++ .pad_bits = 16, ++ .reg_stride = CS35L41_REGSTRIDE, ++ .reg_format_endian = REGMAP_ENDIAN_BIG, ++ .val_format_endian = REGMAP_ENDIAN_BIG, ++ .max_register = CS35L41_LASTREG, ++ .reg_defaults = cs35l41_reg, ++ .num_reg_defaults = ARRAY_SIZE(cs35l41_reg), ++ .volatile_reg = cs35l41_volatile_reg, ++ .readable_reg = cs35l41_readable_reg, ++ .precious_reg = cs35l41_precious_reg, ++ .cache_type = REGCACHE_RBTREE, ++}; ++ ++static const struct spi_device_id cs35l41_id_spi[] = { ++ { "cs35l40", 0 }, ++ { "cs35l41", 0 }, ++ {} ++}; ++ ++MODULE_DEVICE_TABLE(spi, cs35l41_id_spi); ++ ++static void cs35l41_spi_otp_setup(struct cs35l41_private *cs35l41, ++ bool is_pre_setup, unsigned int *freq) ++{ ++ struct spi_device *spi; ++ u32 orig_spi_freq; ++ ++ spi = to_spi_device(cs35l41->dev); ++ ++ if (!spi) { ++ dev_err(cs35l41->dev, "%s: No SPI device\n", __func__); ++ return; ++ } ++ ++ if (is_pre_setup) { ++ orig_spi_freq = spi->max_speed_hz; ++ if (orig_spi_freq > CS35L41_SPI_MAX_FREQ_OTP) { ++ spi->max_speed_hz = CS35L41_SPI_MAX_FREQ_OTP; ++ spi_setup(spi); ++ } ++ *freq = orig_spi_freq; ++ } else { ++ if (spi->max_speed_hz != *freq) { ++ spi->max_speed_hz = *freq; ++ spi_setup(spi); ++ } ++ } ++} ++ ++static int cs35l41_spi_probe(struct spi_device *spi) ++{ ++ const struct regmap_config *regmap_config = &cs35l41_regmap_spi; ++ struct cs35l41_platform_data *pdata = ++ dev_get_platdata(&spi->dev); ++ struct cs35l41_private *cs35l41; ++ int ret; ++ ++ cs35l41 = devm_kzalloc(&spi->dev, ++ sizeof(struct cs35l41_private), ++ GFP_KERNEL); ++ if (!cs35l41) ++ return -ENOMEM; ++ ++ ++ spi_set_drvdata(spi, cs35l41); ++ cs35l41->regmap = devm_regmap_init_spi(spi, regmap_config); ++ if (IS_ERR(cs35l41->regmap)) { ++ ret = PTR_ERR(cs35l41->regmap); ++ dev_err(&spi->dev, "Failed to allocate register map: %d\n", ++ ret); ++ return ret; ++ } ++ ++ cs35l41->dev = &spi->dev; ++ cs35l41->irq = spi->irq; ++ cs35l41->otp_setup = cs35l41_spi_otp_setup; ++ ++ return cs35l41_probe(cs35l41, pdata); ++} ++ ++static int cs35l41_spi_remove(struct spi_device *spi) ++{ ++ struct cs35l41_private *cs35l41 = spi_get_drvdata(spi); ++ ++ return cs35l41_remove(cs35l41); ++} ++ ++#ifdef CONFIG_OF ++static const struct of_device_id cs35l41_of_match[] = { ++ { .compatible = "cirrus,cs35l40" }, ++ { .compatible = "cirrus,cs35l41" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, cs35l41_of_match); ++#endif ++ ++#ifdef CONFIG_ACPI ++static const struct acpi_device_id cs35l41_acpi_match[] = { ++ { "CSC3541", 0 }, /* Cirrus Logic PnP ID + part ID */ ++ {}, ++}; ++MODULE_DEVICE_TABLE(acpi, cs35l41_acpi_match); ++#endif ++ ++static struct spi_driver cs35l41_spi_driver = { ++ .driver = { ++ .name = "cs35l41", ++ .of_match_table = of_match_ptr(cs35l41_of_match), ++ .acpi_match_table = ACPI_PTR(cs35l41_acpi_match), ++ }, ++ .id_table = cs35l41_id_spi, ++ .probe = cs35l41_spi_probe, ++ .remove = cs35l41_spi_remove, ++}; ++ ++module_spi_driver(cs35l41_spi_driver); ++ ++MODULE_DESCRIPTION("SPI CS35L41 driver"); ++MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, "); ++MODULE_LICENSE("GPL"); +diff --git a/sound/soc/codecs/cs35l41-tables.c b/sound/soc/codecs/cs35l41-tables.c +new file mode 100644 +index 000000000000..155db0e6e3d8 +--- /dev/null ++++ b/sound/soc/codecs/cs35l41-tables.c +@@ -0,0 +1,597 @@ ++// SPDX-License-Identifier: GPL-2.0 ++// ++// cs35l41-tables.c -- CS35L41 ALSA SoC audio driver ++// ++// Copyright 2017-2021 Cirrus Logic, Inc. ++// ++// Author: David Rhodes ++ ++#include "cs35l41.h" ++ ++const struct reg_default cs35l41_reg[CS35L41_MAX_CACHE_REG] = { ++ {CS35L41_PWR_CTRL1, 0x00000000}, ++ {CS35L41_PWR_CTRL3, 0x01000010}, ++ {CS35L41_GPIO_PAD_CONTROL, 0x00000000}, ++ {CS35L41_SP_ENABLES, 0x00000000}, ++ {CS35L41_SP_RATE_CTRL, 0x00000028}, ++ {CS35L41_SP_FORMAT, 0x18180200}, ++ {CS35L41_SP_HIZ_CTRL, 0x00000002}, ++ {CS35L41_SP_FRAME_TX_SLOT, 0x03020100}, ++ {CS35L41_SP_FRAME_RX_SLOT, 0x00000100}, ++ {CS35L41_SP_TX_WL, 0x00000018}, ++ {CS35L41_SP_RX_WL, 0x00000018}, ++ {CS35L41_DAC_PCM1_SRC, 0x00000008}, ++ {CS35L41_ASP_TX1_SRC, 0x00000018}, ++ {CS35L41_ASP_TX2_SRC, 0x00000019}, ++ {CS35L41_ASP_TX3_SRC, 0x00000020}, ++ {CS35L41_ASP_TX4_SRC, 0x00000021}, ++ {CS35L41_DSP1_RX1_SRC, 0x00000008}, ++ {CS35L41_DSP1_RX2_SRC, 0x00000009}, ++ {CS35L41_DSP1_RX3_SRC, 0x00000018}, ++ {CS35L41_DSP1_RX4_SRC, 0x00000019}, ++ {CS35L41_DSP1_RX5_SRC, 0x00000020}, ++ {CS35L41_DSP1_RX6_SRC, 0x00000021}, ++ {CS35L41_DSP1_RX7_SRC, 0x0000003A}, ++ {CS35L41_DSP1_RX8_SRC, 0x00000001}, ++ {CS35L41_NGATE1_SRC, 0x00000008}, ++ {CS35L41_NGATE2_SRC, 0x00000009}, ++ {CS35L41_AMP_DIG_VOL_CTRL, 0x00008000}, ++ {CS35L41_CLASSH_CFG, 0x000B0405}, ++ {CS35L41_WKFET_CFG, 0x00000111}, ++ {CS35L41_NG_CFG, 0x00000033}, ++ {CS35L41_AMP_GAIN_CTRL, 0x00000273}, ++ {CS35L41_GPIO1_CTRL1, 0xE1000001}, ++ {CS35L41_GPIO2_CTRL1, 0xE1000001}, ++ {CS35L41_MIXER_NGATE_CFG, 0x00000000}, ++ {CS35L41_MIXER_NGATE_CH1_CFG, 0x00000303}, ++ {CS35L41_MIXER_NGATE_CH2_CFG, 0x00000303}, ++}; ++ ++bool cs35l41_readable_reg(struct device *dev, unsigned int reg) ++{ ++ switch (reg) { ++ case CS35L41_DEVID: ++ case CS35L41_REVID: ++ case CS35L41_FABID: ++ case CS35L41_RELID: ++ case CS35L41_OTPID: ++ case CS35L41_TEST_KEY_CTL: ++ case CS35L41_USER_KEY_CTL: ++ case CS35L41_OTP_CTRL0: ++ case CS35L41_OTP_CTRL3: ++ case CS35L41_OTP_CTRL4: ++ case CS35L41_OTP_CTRL5: ++ case CS35L41_OTP_CTRL6: ++ case CS35L41_OTP_CTRL7: ++ case CS35L41_OTP_CTRL8: ++ case CS35L41_PWR_CTRL1: ++ case CS35L41_PWR_CTRL2: ++ case CS35L41_PWR_CTRL3: ++ case CS35L41_CTRL_OVRRIDE: ++ case CS35L41_AMP_OUT_MUTE: ++ case CS35L41_PROTECT_REL_ERR_IGN: ++ case CS35L41_GPIO_PAD_CONTROL: ++ case CS35L41_JTAG_CONTROL: ++ case CS35L41_PLL_CLK_CTRL: ++ case CS35L41_DSP_CLK_CTRL: ++ case CS35L41_GLOBAL_CLK_CTRL: ++ case CS35L41_DATA_FS_SEL: ++ case CS35L41_MDSYNC_EN: ++ case CS35L41_MDSYNC_TX_ID: ++ case CS35L41_MDSYNC_PWR_CTRL: ++ case CS35L41_MDSYNC_DATA_TX: ++ case CS35L41_MDSYNC_TX_STATUS: ++ case CS35L41_MDSYNC_DATA_RX: ++ case CS35L41_MDSYNC_RX_STATUS: ++ case CS35L41_MDSYNC_ERR_STATUS: ++ case CS35L41_MDSYNC_SYNC_PTE2: ++ case CS35L41_MDSYNC_SYNC_PTE3: ++ case CS35L41_MDSYNC_SYNC_MSM_STATUS: ++ case CS35L41_BSTCVRT_VCTRL1: ++ case CS35L41_BSTCVRT_VCTRL2: ++ case CS35L41_BSTCVRT_PEAK_CUR: ++ case CS35L41_BSTCVRT_SFT_RAMP: ++ case CS35L41_BSTCVRT_COEFF: ++ case CS35L41_BSTCVRT_SLOPE_LBST: ++ case CS35L41_BSTCVRT_SW_FREQ: ++ case CS35L41_BSTCVRT_DCM_CTRL: ++ case CS35L41_BSTCVRT_DCM_MODE_FORCE: ++ case CS35L41_BSTCVRT_OVERVOLT_CTRL: ++ case CS35L41_VI_VOL_POL: ++ case CS35L41_DTEMP_WARN_THLD: ++ case CS35L41_DTEMP_CFG: ++ case CS35L41_DTEMP_EN: ++ case CS35L41_VPVBST_FS_SEL: ++ case CS35L41_SP_ENABLES: ++ case CS35L41_SP_RATE_CTRL: ++ case CS35L41_SP_FORMAT: ++ case CS35L41_SP_HIZ_CTRL: ++ case CS35L41_SP_FRAME_TX_SLOT: ++ case CS35L41_SP_FRAME_RX_SLOT: ++ case CS35L41_SP_TX_WL: ++ case CS35L41_SP_RX_WL: ++ case CS35L41_DAC_PCM1_SRC: ++ case CS35L41_ASP_TX1_SRC: ++ case CS35L41_ASP_TX2_SRC: ++ case CS35L41_ASP_TX3_SRC: ++ case CS35L41_ASP_TX4_SRC: ++ case CS35L41_DSP1_RX1_SRC: ++ case CS35L41_DSP1_RX2_SRC: ++ case CS35L41_DSP1_RX3_SRC: ++ case CS35L41_DSP1_RX4_SRC: ++ case CS35L41_DSP1_RX5_SRC: ++ case CS35L41_DSP1_RX6_SRC: ++ case CS35L41_DSP1_RX7_SRC: ++ case CS35L41_DSP1_RX8_SRC: ++ case CS35L41_NGATE1_SRC: ++ case CS35L41_NGATE2_SRC: ++ case CS35L41_AMP_DIG_VOL_CTRL: ++ case CS35L41_VPBR_CFG: ++ case CS35L41_VBBR_CFG: ++ case CS35L41_VPBR_STATUS: ++ case CS35L41_VBBR_STATUS: ++ case CS35L41_OVERTEMP_CFG: ++ case CS35L41_AMP_ERR_VOL: ++ case CS35L41_VOL_STATUS_TO_DSP: ++ case CS35L41_CLASSH_CFG: ++ case CS35L41_WKFET_CFG: ++ case CS35L41_NG_CFG: ++ case CS35L41_AMP_GAIN_CTRL: ++ case CS35L41_DAC_MSM_CFG: ++ case CS35L41_IRQ1_CFG: ++ case CS35L41_IRQ1_STATUS: ++ case CS35L41_IRQ1_STATUS1: ++ case CS35L41_IRQ1_STATUS2: ++ case CS35L41_IRQ1_STATUS3: ++ case CS35L41_IRQ1_STATUS4: ++ case CS35L41_IRQ1_RAW_STATUS1: ++ case CS35L41_IRQ1_RAW_STATUS2: ++ case CS35L41_IRQ1_RAW_STATUS3: ++ case CS35L41_IRQ1_RAW_STATUS4: ++ case CS35L41_IRQ1_MASK1: ++ case CS35L41_IRQ1_MASK2: ++ case CS35L41_IRQ1_MASK3: ++ case CS35L41_IRQ1_MASK4: ++ case CS35L41_IRQ1_FRC1: ++ case CS35L41_IRQ1_FRC2: ++ case CS35L41_IRQ1_FRC3: ++ case CS35L41_IRQ1_FRC4: ++ case CS35L41_IRQ1_EDGE1: ++ case CS35L41_IRQ1_EDGE4: ++ case CS35L41_IRQ1_POL1: ++ case CS35L41_IRQ1_POL2: ++ case CS35L41_IRQ1_POL3: ++ case CS35L41_IRQ1_POL4: ++ case CS35L41_IRQ1_DB3: ++ case CS35L41_IRQ2_CFG: ++ case CS35L41_IRQ2_STATUS: ++ case CS35L41_IRQ2_STATUS1: ++ case CS35L41_IRQ2_STATUS2: ++ case CS35L41_IRQ2_STATUS3: ++ case CS35L41_IRQ2_STATUS4: ++ case CS35L41_IRQ2_RAW_STATUS1: ++ case CS35L41_IRQ2_RAW_STATUS2: ++ case CS35L41_IRQ2_RAW_STATUS3: ++ case CS35L41_IRQ2_RAW_STATUS4: ++ case CS35L41_IRQ2_MASK1: ++ case CS35L41_IRQ2_MASK2: ++ case CS35L41_IRQ2_MASK3: ++ case CS35L41_IRQ2_MASK4: ++ case CS35L41_IRQ2_FRC1: ++ case CS35L41_IRQ2_FRC2: ++ case CS35L41_IRQ2_FRC3: ++ case CS35L41_IRQ2_FRC4: ++ case CS35L41_IRQ2_EDGE1: ++ case CS35L41_IRQ2_EDGE4: ++ case CS35L41_IRQ2_POL1: ++ case CS35L41_IRQ2_POL2: ++ case CS35L41_IRQ2_POL3: ++ case CS35L41_IRQ2_POL4: ++ case CS35L41_IRQ2_DB3: ++ case CS35L41_GPIO_STATUS1: ++ case CS35L41_GPIO1_CTRL1: ++ case CS35L41_GPIO2_CTRL1: ++ case CS35L41_MIXER_NGATE_CFG: ++ case CS35L41_MIXER_NGATE_CH1_CFG: ++ case CS35L41_MIXER_NGATE_CH2_CFG: ++ case CS35L41_DSP_MBOX_1 ... CS35L41_DSP_VIRT2_MBOX_8: ++ case CS35L41_CLOCK_DETECT_1: ++ case CS35L41_DIE_STS1: ++ case CS35L41_DIE_STS2: ++ case CS35L41_TEMP_CAL1: ++ case CS35L41_TEMP_CAL2: ++ case CS35L41_OTP_TRIM_1: ++ case CS35L41_OTP_TRIM_2: ++ case CS35L41_OTP_TRIM_3: ++ case CS35L41_OTP_TRIM_4: ++ case CS35L41_OTP_TRIM_5: ++ case CS35L41_OTP_TRIM_6: ++ case CS35L41_OTP_TRIM_7: ++ case CS35L41_OTP_TRIM_8: ++ case CS35L41_OTP_TRIM_9: ++ case CS35L41_OTP_TRIM_10: ++ case CS35L41_OTP_TRIM_11: ++ case CS35L41_OTP_TRIM_12: ++ case CS35L41_OTP_TRIM_13: ++ case CS35L41_OTP_TRIM_14: ++ case CS35L41_OTP_TRIM_15: ++ case CS35L41_OTP_TRIM_16: ++ case CS35L41_OTP_TRIM_17: ++ case CS35L41_OTP_TRIM_18: ++ case CS35L41_OTP_TRIM_19: ++ case CS35L41_OTP_TRIM_20: ++ case CS35L41_OTP_TRIM_21: ++ case CS35L41_OTP_TRIM_22: ++ case CS35L41_OTP_TRIM_23: ++ case CS35L41_OTP_TRIM_24: ++ case CS35L41_OTP_TRIM_25: ++ case CS35L41_OTP_TRIM_26: ++ case CS35L41_OTP_TRIM_27: ++ case CS35L41_OTP_TRIM_28: ++ case CS35L41_OTP_TRIM_29: ++ case CS35L41_OTP_TRIM_30: ++ case CS35L41_OTP_TRIM_31: ++ case CS35L41_OTP_TRIM_32: ++ case CS35L41_OTP_TRIM_33: ++ case CS35L41_OTP_TRIM_34: ++ case CS35L41_OTP_TRIM_35: ++ case CS35L41_OTP_TRIM_36: ++ case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31: ++ /*test regs*/ ++ case CS35L41_PLL_OVR: ++ case CS35L41_BST_TEST_DUTY: ++ case CS35L41_DIGPWM_IOCTRL: ++ return true; ++ default: ++ return false; ++ } ++} ++ ++bool cs35l41_precious_reg(struct device *dev, unsigned int reg) ++{ ++ switch (reg) { ++ case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31: ++ return true; ++ default: ++ return false; ++ } ++} ++ ++bool cs35l41_volatile_reg(struct device *dev, unsigned int reg) ++{ ++ switch (reg) { ++ case CS35L41_DEVID: ++ case CS35L41_SFT_RESET: ++ case CS35L41_FABID: ++ case CS35L41_REVID: ++ case CS35L41_DTEMP_EN: ++ case CS35L41_IRQ1_STATUS: ++ case CS35L41_IRQ1_STATUS1: ++ case CS35L41_IRQ1_STATUS2: ++ case CS35L41_IRQ1_STATUS3: ++ case CS35L41_IRQ1_STATUS4: ++ case CS35L41_IRQ1_RAW_STATUS1: ++ case CS35L41_IRQ1_RAW_STATUS2: ++ case CS35L41_IRQ1_RAW_STATUS3: ++ case CS35L41_IRQ1_RAW_STATUS4: ++ case CS35L41_IRQ1_FRC1: ++ case CS35L41_IRQ1_FRC2: ++ case CS35L41_IRQ1_FRC3: ++ case CS35L41_IRQ1_FRC4: ++ case CS35L41_IRQ1_EDGE1: ++ case CS35L41_IRQ1_EDGE4: ++ case CS35L41_IRQ1_POL1: ++ case CS35L41_IRQ1_POL2: ++ case CS35L41_IRQ1_POL3: ++ case CS35L41_IRQ1_POL4: ++ case CS35L41_IRQ1_DB3: ++ case CS35L41_IRQ2_STATUS: ++ case CS35L41_IRQ2_STATUS1: ++ case CS35L41_IRQ2_STATUS2: ++ case CS35L41_IRQ2_STATUS3: ++ case CS35L41_IRQ2_STATUS4: ++ case CS35L41_IRQ2_RAW_STATUS1: ++ case CS35L41_IRQ2_RAW_STATUS2: ++ case CS35L41_IRQ2_RAW_STATUS3: ++ case CS35L41_IRQ2_RAW_STATUS4: ++ case CS35L41_IRQ2_FRC1: ++ case CS35L41_IRQ2_FRC2: ++ case CS35L41_IRQ2_FRC3: ++ case CS35L41_IRQ2_FRC4: ++ case CS35L41_IRQ2_EDGE1: ++ case CS35L41_IRQ2_EDGE4: ++ case CS35L41_IRQ2_POL1: ++ case CS35L41_IRQ2_POL2: ++ case CS35L41_IRQ2_POL3: ++ case CS35L41_IRQ2_POL4: ++ case CS35L41_IRQ2_DB3: ++ case CS35L41_GPIO_STATUS1: ++ case CS35L41_OTP_TRIM_1: ++ case CS35L41_OTP_TRIM_2: ++ case CS35L41_OTP_TRIM_3: ++ case CS35L41_OTP_TRIM_4: ++ case CS35L41_OTP_TRIM_5: ++ case CS35L41_OTP_TRIM_6: ++ case CS35L41_OTP_TRIM_7: ++ case CS35L41_OTP_TRIM_8: ++ case CS35L41_OTP_TRIM_9: ++ case CS35L41_OTP_TRIM_10: ++ case CS35L41_OTP_TRIM_11: ++ case CS35L41_OTP_TRIM_12: ++ case CS35L41_OTP_TRIM_13: ++ case CS35L41_OTP_TRIM_14: ++ case CS35L41_OTP_TRIM_15: ++ case CS35L41_OTP_TRIM_16: ++ case CS35L41_OTP_TRIM_17: ++ case CS35L41_OTP_TRIM_18: ++ case CS35L41_OTP_TRIM_19: ++ case CS35L41_OTP_TRIM_20: ++ case CS35L41_OTP_TRIM_21: ++ case CS35L41_OTP_TRIM_22: ++ case CS35L41_OTP_TRIM_23: ++ case CS35L41_OTP_TRIM_24: ++ case CS35L41_OTP_TRIM_25: ++ case CS35L41_OTP_TRIM_26: ++ case CS35L41_OTP_TRIM_27: ++ case CS35L41_OTP_TRIM_28: ++ case CS35L41_OTP_TRIM_29: ++ case CS35L41_OTP_TRIM_30: ++ case CS35L41_OTP_TRIM_31: ++ case CS35L41_OTP_TRIM_32: ++ case CS35L41_OTP_TRIM_33: ++ case CS35L41_OTP_TRIM_34: ++ case CS35L41_OTP_TRIM_35: ++ case CS35L41_OTP_TRIM_36: ++ case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31: ++ return true; ++ default: ++ return false; ++ } ++} ++ ++static const struct cs35l41_otp_packed_element_t ++ otp_map_1[CS35L41_NUM_OTP_ELEM] = { ++ /* addr shift size */ ++ {0x00002030, 0, 4}, /*TRIM_OSC_FREQ_TRIM*/ ++ {0x00002030, 7, 1}, /*TRIM_OSC_TRIM_DONE*/ ++ {0x0000208c, 24, 6}, /*TST_DIGREG_VREF_TRIM*/ ++ {0x00002090, 14, 4}, /*TST_REF_TRIM*/ ++ {0x00002090, 10, 4}, /*TST_REF_TEMPCO_TRIM*/ ++ {0x0000300C, 11, 4}, /*PLL_LDOA_TST_VREF_TRIM*/ ++ {0x0000394C, 23, 2}, /*BST_ATEST_CM_VOFF*/ ++ {0x00003950, 0, 7}, /*BST_ATRIM_IADC_OFFSET*/ ++ {0x00003950, 8, 7}, /*BST_ATRIM_IADC_GAIN1*/ ++ {0x00003950, 16, 8}, /*BST_ATRIM_IPKCOMP_OFFSET1*/ ++ {0x00003950, 24, 8}, /*BST_ATRIM_IPKCOMP_GAIN1*/ ++ {0x00003954, 0, 7}, /*BST_ATRIM_IADC_OFFSET2*/ ++ {0x00003954, 8, 7}, /*BST_ATRIM_IADC_GAIN2*/ ++ {0x00003954, 16, 8}, /*BST_ATRIM_IPKCOMP_OFFSET2*/ ++ {0x00003954, 24, 8}, /*BST_ATRIM_IPKCOMP_GAIN2*/ ++ {0x00003958, 0, 7}, /*BST_ATRIM_IADC_OFFSET3*/ ++ {0x00003958, 8, 7}, /*BST_ATRIM_IADC_GAIN3*/ ++ {0x00003958, 16, 8}, /*BST_ATRIM_IPKCOMP_OFFSET3*/ ++ {0x00003958, 24, 8}, /*BST_ATRIM_IPKCOMP_GAIN3*/ ++ {0x0000395C, 0, 7}, /*BST_ATRIM_IADC_OFFSET4*/ ++ {0x0000395C, 8, 7}, /*BST_ATRIM_IADC_GAIN4*/ ++ {0x0000395C, 16, 8}, /*BST_ATRIM_IPKCOMP_OFFSET4*/ ++ {0x0000395C, 24, 8}, /*BST_ATRIM_IPKCOMP_GAIN4*/ ++ {0x0000416C, 0, 8}, /*VMON_GAIN_OTP_VAL*/ ++ {0x00004160, 0, 7}, /*VMON_OFFSET_OTP_VAL*/ ++ {0x0000416C, 8, 8}, /*IMON_GAIN_OTP_VAL*/ ++ {0x00004160, 16, 10}, /*IMON_OFFSET_OTP_VAL*/ ++ {0x0000416C, 16, 12}, /*VMON_CM_GAIN_OTP_VAL*/ ++ {0x0000416C, 28, 1}, /*VMON_CM_GAIN_SIGN_OTP_VAL*/ ++ {0x00004170, 0, 6}, /*IMON_CAL_TEMPCO_OTP_VAL*/ ++ {0x00004170, 6, 1}, /*IMON_CAL_TEMPCO_SIGN_OTP*/ ++ {0x00004170, 8, 6}, /*IMON_CAL_TEMPCO2_OTP_VAL*/ ++ {0x00004170, 14, 1}, /*IMON_CAL_TEMPCO2_DN_UPB_OTP_VAL*/ ++ {0x00004170, 16, 9}, /*IMON_CAL_TEMPCO_TBASE_OTP_VAL*/ ++ {0x00004360, 0, 5}, /*TEMP_GAIN_OTP_VAL*/ ++ {0x00004360, 6, 9}, /*TEMP_OFFSET_OTP_VAL*/ ++ {0x00004448, 0, 8}, /*VP_SARADC_OFFSET*/ ++ {0x00004448, 8, 8}, /*VP_GAIN_INDEX*/ ++ {0x00004448, 16, 8}, /*VBST_SARADC_OFFSET*/ ++ {0x00004448, 24, 8}, /*VBST_GAIN_INDEX*/ ++ {0x0000444C, 0, 3}, /*ANA_SELINVREF*/ ++ {0x00006E30, 0, 5}, /*GAIN_ERR_COEFF_0*/ ++ {0x00006E30, 8, 5}, /*GAIN_ERR_COEFF_1*/ ++ {0x00006E30, 16, 5}, /*GAIN_ERR_COEFF_2*/ ++ {0x00006E30, 24, 5}, /*GAIN_ERR_COEFF_3*/ ++ {0x00006E34, 0, 5}, /*GAIN_ERR_COEFF_4*/ ++ {0x00006E34, 8, 5}, /*GAIN_ERR_COEFF_5*/ ++ {0x00006E34, 16, 5}, /*GAIN_ERR_COEFF_6*/ ++ {0x00006E34, 24, 5}, /*GAIN_ERR_COEFF_7*/ ++ {0x00006E38, 0, 5}, /*GAIN_ERR_COEFF_8*/ ++ {0x00006E38, 8, 5}, /*GAIN_ERR_COEFF_9*/ ++ {0x00006E38, 16, 5}, /*GAIN_ERR_COEFF_10*/ ++ {0x00006E38, 24, 5}, /*GAIN_ERR_COEFF_11*/ ++ {0x00006E3C, 0, 5}, /*GAIN_ERR_COEFF_12*/ ++ {0x00006E3C, 8, 5}, /*GAIN_ERR_COEFF_13*/ ++ {0x00006E3C, 16, 5}, /*GAIN_ERR_COEFF_14*/ ++ {0x00006E3C, 24, 5}, /*GAIN_ERR_COEFF_15*/ ++ {0x00006E40, 0, 5}, /*GAIN_ERR_COEFF_16*/ ++ {0x00006E40, 8, 5}, /*GAIN_ERR_COEFF_17*/ ++ {0x00006E40, 16, 5}, /*GAIN_ERR_COEFF_18*/ ++ {0x00006E40, 24, 5}, /*GAIN_ERR_COEFF_19*/ ++ {0x00006E44, 0, 5}, /*GAIN_ERR_COEFF_20*/ ++ {0x00006E48, 0, 10}, /*VOFF_GAIN_0*/ ++ {0x00006E48, 10, 10}, /*VOFF_GAIN_1*/ ++ {0x00006E48, 20, 10}, /*VOFF_GAIN_2*/ ++ {0x00006E4C, 0, 10}, /*VOFF_GAIN_3*/ ++ {0x00006E4C, 10, 10}, /*VOFF_GAIN_4*/ ++ {0x00006E4C, 20, 10}, /*VOFF_GAIN_5*/ ++ {0x00006E50, 0, 10}, /*VOFF_GAIN_6*/ ++ {0x00006E50, 10, 10}, /*VOFF_GAIN_7*/ ++ {0x00006E50, 20, 10}, /*VOFF_GAIN_8*/ ++ {0x00006E54, 0, 10}, /*VOFF_GAIN_9*/ ++ {0x00006E54, 10, 10}, /*VOFF_GAIN_10*/ ++ {0x00006E54, 20, 10}, /*VOFF_GAIN_11*/ ++ {0x00006E58, 0, 10}, /*VOFF_GAIN_12*/ ++ {0x00006E58, 10, 10}, /*VOFF_GAIN_13*/ ++ {0x00006E58, 20, 10}, /*VOFF_GAIN_14*/ ++ {0x00006E5C, 0, 10}, /*VOFF_GAIN_15*/ ++ {0x00006E5C, 10, 10}, /*VOFF_GAIN_16*/ ++ {0x00006E5C, 20, 10}, /*VOFF_GAIN_17*/ ++ {0x00006E60, 0, 10}, /*VOFF_GAIN_18*/ ++ {0x00006E60, 10, 10}, /*VOFF_GAIN_19*/ ++ {0x00006E60, 20, 10}, /*VOFF_GAIN_20*/ ++ {0x00006E64, 0, 10}, /*VOFF_INT1*/ ++ {0x00007418, 7, 5}, /*DS_SPK_INT1_CAP_TRIM*/ ++ {0x0000741C, 0, 5}, /*DS_SPK_INT2_CAP_TRIM*/ ++ {0x0000741C, 11, 4}, /*DS_SPK_LPF_CAP_TRIM*/ ++ {0x0000741C, 19, 4}, /*DS_SPK_QUAN_CAP_TRIM*/ ++ {0x00007434, 17, 1}, /*FORCE_CAL*/ ++ {0x00007434, 18, 7}, /*CAL_OVERRIDE*/ ++ {0x00007068, 0, 9}, /*MODIX*/ ++ {0x0000410C, 7, 1}, /*VIMON_DLY_NOT_COMB*/ ++ {0x0000400C, 0, 7}, /*VIMON_DLY*/ ++ {0x00000000, 0, 1}, /*extra bit*/ ++ {0x00017040, 0, 8}, /*X_COORDINATE*/ ++ {0x00017040, 8, 8}, /*Y_COORDINATE*/ ++ {0x00017040, 16, 8}, /*WAFER_ID*/ ++ {0x00017040, 24, 8}, /*DVS*/ ++ {0x00017044, 0, 24}, /*LOT_NUMBER*/ ++}; ++ ++static const struct cs35l41_otp_packed_element_t ++ otp_map_2[CS35L41_NUM_OTP_ELEM] = { ++ /* addr shift size */ ++ {0x00002030, 0, 4}, /*TRIM_OSC_FREQ_TRIM*/ ++ {0x00002030, 7, 1}, /*TRIM_OSC_TRIM_DONE*/ ++ {0x0000208c, 24, 6}, /*TST_DIGREG_VREF_TRIM*/ ++ {0x00002090, 14, 4}, /*TST_REF_TRIM*/ ++ {0x00002090, 10, 4}, /*TST_REF_TEMPCO_TRIM*/ ++ {0x0000300C, 11, 4}, /*PLL_LDOA_TST_VREF_TRIM*/ ++ {0x0000394C, 23, 2}, /*BST_ATEST_CM_VOFF*/ ++ {0x00003950, 0, 7}, /*BST_ATRIM_IADC_OFFSET*/ ++ {0x00003950, 8, 7}, /*BST_ATRIM_IADC_GAIN1*/ ++ {0x00003950, 16, 8}, /*BST_ATRIM_IPKCOMP_OFFSET1*/ ++ {0x00003950, 24, 8}, /*BST_ATRIM_IPKCOMP_GAIN1*/ ++ {0x00003954, 0, 7}, /*BST_ATRIM_IADC_OFFSET2*/ ++ {0x00003954, 8, 7}, /*BST_ATRIM_IADC_GAIN2*/ ++ {0x00003954, 16, 8}, /*BST_ATRIM_IPKCOMP_OFFSET2*/ ++ {0x00003954, 24, 8}, /*BST_ATRIM_IPKCOMP_GAIN2*/ ++ {0x00003958, 0, 7}, /*BST_ATRIM_IADC_OFFSET3*/ ++ {0x00003958, 8, 7}, /*BST_ATRIM_IADC_GAIN3*/ ++ {0x00003958, 16, 8}, /*BST_ATRIM_IPKCOMP_OFFSET3*/ ++ {0x00003958, 24, 8}, /*BST_ATRIM_IPKCOMP_GAIN3*/ ++ {0x0000395C, 0, 7}, /*BST_ATRIM_IADC_OFFSET4*/ ++ {0x0000395C, 8, 7}, /*BST_ATRIM_IADC_GAIN4*/ ++ {0x0000395C, 16, 8}, /*BST_ATRIM_IPKCOMP_OFFSET4*/ ++ {0x0000395C, 24, 8}, /*BST_ATRIM_IPKCOMP_GAIN4*/ ++ {0x0000416C, 0, 8}, /*VMON_GAIN_OTP_VAL*/ ++ {0x00004160, 0, 7}, /*VMON_OFFSET_OTP_VAL*/ ++ {0x0000416C, 8, 8}, /*IMON_GAIN_OTP_VAL*/ ++ {0x00004160, 16, 10}, /*IMON_OFFSET_OTP_VAL*/ ++ {0x0000416C, 16, 12}, /*VMON_CM_GAIN_OTP_VAL*/ ++ {0x0000416C, 28, 1}, /*VMON_CM_GAIN_SIGN_OTP_VAL*/ ++ {0x00004170, 0, 6}, /*IMON_CAL_TEMPCO_OTP_VAL*/ ++ {0x00004170, 6, 1}, /*IMON_CAL_TEMPCO_SIGN_OTP*/ ++ {0x00004170, 8, 6}, /*IMON_CAL_TEMPCO2_OTP_VAL*/ ++ {0x00004170, 14, 1}, /*IMON_CAL_TEMPCO2_DN_UPB_OTP_VAL*/ ++ {0x00004170, 16, 9}, /*IMON_CAL_TEMPCO_TBASE_OTP_VAL*/ ++ {0x00004360, 0, 5}, /*TEMP_GAIN_OTP_VAL*/ ++ {0x00004360, 6, 9}, /*TEMP_OFFSET_OTP_VAL*/ ++ {0x00004448, 0, 8}, /*VP_SARADC_OFFSET*/ ++ {0x00004448, 8, 8}, /*VP_GAIN_INDEX*/ ++ {0x00004448, 16, 8}, /*VBST_SARADC_OFFSET*/ ++ {0x00004448, 24, 8}, /*VBST_GAIN_INDEX*/ ++ {0x0000444C, 0, 3}, /*ANA_SELINVREF*/ ++ {0x00006E30, 0, 5}, /*GAIN_ERR_COEFF_0*/ ++ {0x00006E30, 8, 5}, /*GAIN_ERR_COEFF_1*/ ++ {0x00006E30, 16, 5}, /*GAIN_ERR_COEFF_2*/ ++ {0x00006E30, 24, 5}, /*GAIN_ERR_COEFF_3*/ ++ {0x00006E34, 0, 5}, /*GAIN_ERR_COEFF_4*/ ++ {0x00006E34, 8, 5}, /*GAIN_ERR_COEFF_5*/ ++ {0x00006E34, 16, 5}, /*GAIN_ERR_COEFF_6*/ ++ {0x00006E34, 24, 5}, /*GAIN_ERR_COEFF_7*/ ++ {0x00006E38, 0, 5}, /*GAIN_ERR_COEFF_8*/ ++ {0x00006E38, 8, 5}, /*GAIN_ERR_COEFF_9*/ ++ {0x00006E38, 16, 5}, /*GAIN_ERR_COEFF_10*/ ++ {0x00006E38, 24, 5}, /*GAIN_ERR_COEFF_11*/ ++ {0x00006E3C, 0, 5}, /*GAIN_ERR_COEFF_12*/ ++ {0x00006E3C, 8, 5}, /*GAIN_ERR_COEFF_13*/ ++ {0x00006E3C, 16, 5}, /*GAIN_ERR_COEFF_14*/ ++ {0x00006E3C, 24, 5}, /*GAIN_ERR_COEFF_15*/ ++ {0x00006E40, 0, 5}, /*GAIN_ERR_COEFF_16*/ ++ {0x00006E40, 8, 5}, /*GAIN_ERR_COEFF_17*/ ++ {0x00006E40, 16, 5}, /*GAIN_ERR_COEFF_18*/ ++ {0x00006E40, 24, 5}, /*GAIN_ERR_COEFF_19*/ ++ {0x00006E44, 0, 5}, /*GAIN_ERR_COEFF_20*/ ++ {0x00006E48, 0, 10}, /*VOFF_GAIN_0*/ ++ {0x00006E48, 10, 10}, /*VOFF_GAIN_1*/ ++ {0x00006E48, 20, 10}, /*VOFF_GAIN_2*/ ++ {0x00006E4C, 0, 10}, /*VOFF_GAIN_3*/ ++ {0x00006E4C, 10, 10}, /*VOFF_GAIN_4*/ ++ {0x00006E4C, 20, 10}, /*VOFF_GAIN_5*/ ++ {0x00006E50, 0, 10}, /*VOFF_GAIN_6*/ ++ {0x00006E50, 10, 10}, /*VOFF_GAIN_7*/ ++ {0x00006E50, 20, 10}, /*VOFF_GAIN_8*/ ++ {0x00006E54, 0, 10}, /*VOFF_GAIN_9*/ ++ {0x00006E54, 10, 10}, /*VOFF_GAIN_10*/ ++ {0x00006E54, 20, 10}, /*VOFF_GAIN_11*/ ++ {0x00006E58, 0, 10}, /*VOFF_GAIN_12*/ ++ {0x00006E58, 10, 10}, /*VOFF_GAIN_13*/ ++ {0x00006E58, 20, 10}, /*VOFF_GAIN_14*/ ++ {0x00006E5C, 0, 10}, /*VOFF_GAIN_15*/ ++ {0x00006E5C, 10, 10}, /*VOFF_GAIN_16*/ ++ {0x00006E5C, 20, 10}, /*VOFF_GAIN_17*/ ++ {0x00006E60, 0, 10}, /*VOFF_GAIN_18*/ ++ {0x00006E60, 10, 10}, /*VOFF_GAIN_19*/ ++ {0x00006E60, 20, 10}, /*VOFF_GAIN_20*/ ++ {0x00006E64, 0, 10}, /*VOFF_INT1*/ ++ {0x00007418, 7, 5}, /*DS_SPK_INT1_CAP_TRIM*/ ++ {0x0000741C, 0, 5}, /*DS_SPK_INT2_CAP_TRIM*/ ++ {0x0000741C, 11, 4}, /*DS_SPK_LPF_CAP_TRIM*/ ++ {0x0000741C, 19, 4}, /*DS_SPK_QUAN_CAP_TRIM*/ ++ {0x00007434, 17, 1}, /*FORCE_CAL*/ ++ {0x00007434, 18, 7}, /*CAL_OVERRIDE*/ ++ {0x00007068, 0, 9}, /*MODIX*/ ++ {0x0000410C, 7, 1}, /*VIMON_DLY_NOT_COMB*/ ++ {0x0000400C, 0, 7}, /*VIMON_DLY*/ ++ {0x00004000, 11, 1}, /*VMON_POL*/ ++ {0x00017040, 0, 8}, /*X_COORDINATE*/ ++ {0x00017040, 8, 8}, /*Y_COORDINATE*/ ++ {0x00017040, 16, 8}, /*WAFER_ID*/ ++ {0x00017040, 24, 8}, /*DVS*/ ++ {0x00017044, 0, 24}, /*LOT_NUMBER*/ ++}; ++ ++const struct cs35l41_otp_map_element_t ++ cs35l41_otp_map_map[CS35L41_NUM_OTP_MAPS] = { ++ { ++ .id = 0x01, ++ .map = otp_map_1, ++ .num_elements = CS35L41_NUM_OTP_ELEM, ++ .bit_offset = 16, ++ .word_offset = 2, ++ }, ++ { ++ .id = 0x02, ++ .map = otp_map_2, ++ .num_elements = CS35L41_NUM_OTP_ELEM, ++ .bit_offset = 16, ++ .word_offset = 2, ++ }, ++ { ++ .id = 0x03, ++ .map = otp_map_2, ++ .num_elements = CS35L41_NUM_OTP_ELEM, ++ .bit_offset = 16, ++ .word_offset = 2, ++ }, ++ { ++ .id = 0x06, ++ .map = otp_map_2, ++ .num_elements = CS35L41_NUM_OTP_ELEM, ++ .bit_offset = 16, ++ .word_offset = 2, ++ }, ++ { ++ .id = 0x08, ++ .map = otp_map_1, ++ .num_elements = CS35L41_NUM_OTP_ELEM, ++ .bit_offset = 16, ++ .word_offset = 2, ++ }, ++}; +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +new file mode 100644 +index 000000000000..dbec54a28a9e +--- /dev/null ++++ b/sound/soc/codecs/cs35l41.c +@@ -0,0 +1,1545 @@ ++// SPDX-License-Identifier: GPL-2.0 ++// ++// cs35l41.c -- CS35l41 ALSA SoC audio driver ++// ++// Copyright 2017-2021 Cirrus Logic, Inc. ++// ++// Author: David Rhodes ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "cs35l41.h" ++ ++static const char * const cs35l41_supplies[CS35L41_NUM_SUPPLIES] = { ++ "VA", ++ "VP", ++}; ++ ++struct cs35l41_pll_sysclk_config { ++ int freq; ++ int clk_cfg; ++}; ++ ++static const struct cs35l41_pll_sysclk_config cs35l41_pll_sysclk[] = { ++ { 32768, 0x00 }, ++ { 8000, 0x01 }, ++ { 11025, 0x02 }, ++ { 12000, 0x03 }, ++ { 16000, 0x04 }, ++ { 22050, 0x05 }, ++ { 24000, 0x06 }, ++ { 32000, 0x07 }, ++ { 44100, 0x08 }, ++ { 48000, 0x09 }, ++ { 88200, 0x0A }, ++ { 96000, 0x0B }, ++ { 128000, 0x0C }, ++ { 176400, 0x0D }, ++ { 192000, 0x0E }, ++ { 256000, 0x0F }, ++ { 352800, 0x10 }, ++ { 384000, 0x11 }, ++ { 512000, 0x12 }, ++ { 705600, 0x13 }, ++ { 750000, 0x14 }, ++ { 768000, 0x15 }, ++ { 1000000, 0x16 }, ++ { 1024000, 0x17 }, ++ { 1200000, 0x18 }, ++ { 1411200, 0x19 }, ++ { 1500000, 0x1A }, ++ { 1536000, 0x1B }, ++ { 2000000, 0x1C }, ++ { 2048000, 0x1D }, ++ { 2400000, 0x1E }, ++ { 2822400, 0x1F }, ++ { 3000000, 0x20 }, ++ { 3072000, 0x21 }, ++ { 3200000, 0x22 }, ++ { 4000000, 0x23 }, ++ { 4096000, 0x24 }, ++ { 4800000, 0x25 }, ++ { 5644800, 0x26 }, ++ { 6000000, 0x27 }, ++ { 6144000, 0x28 }, ++ { 6250000, 0x29 }, ++ { 6400000, 0x2A }, ++ { 6500000, 0x2B }, ++ { 6750000, 0x2C }, ++ { 7526400, 0x2D }, ++ { 8000000, 0x2E }, ++ { 8192000, 0x2F }, ++ { 9600000, 0x30 }, ++ { 11289600, 0x31 }, ++ { 12000000, 0x32 }, ++ { 12288000, 0x33 }, ++ { 12500000, 0x34 }, ++ { 12800000, 0x35 }, ++ { 13000000, 0x36 }, ++ { 13500000, 0x37 }, ++ { 19200000, 0x38 }, ++ { 22579200, 0x39 }, ++ { 24000000, 0x3A }, ++ { 24576000, 0x3B }, ++ { 25000000, 0x3C }, ++ { 25600000, 0x3D }, ++ { 26000000, 0x3E }, ++ { 27000000, 0x3F }, ++}; ++ ++struct cs35l41_fs_mon_config { ++ int freq; ++ unsigned int fs1; ++ unsigned int fs2; ++}; ++ ++static const struct cs35l41_fs_mon_config cs35l41_fs_mon[] = { ++ { 32768, 2254, 3754 }, ++ { 8000, 9220, 15364 }, ++ { 11025, 6148, 10244 }, ++ { 12000, 6148, 10244 }, ++ { 16000, 4612, 7684 }, ++ { 22050, 3076, 5124 }, ++ { 24000, 3076, 5124 }, ++ { 32000, 2308, 3844 }, ++ { 44100, 1540, 2564 }, ++ { 48000, 1540, 2564 }, ++ { 88200, 772, 1284 }, ++ { 96000, 772, 1284 }, ++ { 128000, 580, 964 }, ++ { 176400, 388, 644 }, ++ { 192000, 388, 644 }, ++ { 256000, 292, 484 }, ++ { 352800, 196, 324 }, ++ { 384000, 196, 324 }, ++ { 512000, 148, 244 }, ++ { 705600, 100, 164 }, ++ { 750000, 100, 164 }, ++ { 768000, 100, 164 }, ++ { 1000000, 76, 124 }, ++ { 1024000, 76, 124 }, ++ { 1200000, 64, 104 }, ++ { 1411200, 52, 84 }, ++ { 1500000, 52, 84 }, ++ { 1536000, 52, 84 }, ++ { 2000000, 40, 64 }, ++ { 2048000, 40, 64 }, ++ { 2400000, 34, 54 }, ++ { 2822400, 28, 44 }, ++ { 3000000, 28, 44 }, ++ { 3072000, 28, 44 }, ++ { 3200000, 27, 42 }, ++ { 4000000, 22, 34 }, ++ { 4096000, 22, 34 }, ++ { 4800000, 19, 29 }, ++ { 5644800, 16, 24 }, ++ { 6000000, 16, 24 }, ++ { 6144000, 16, 24 }, ++}; ++ ++static const unsigned char cs35l41_bst_k1_table[4][5] = { ++ { 0x24, 0x32, 0x32, 0x4F, 0x57 }, ++ { 0x24, 0x32, 0x32, 0x4F, 0x57 }, ++ { 0x40, 0x32, 0x32, 0x4F, 0x57 }, ++ { 0x40, 0x32, 0x32, 0x4F, 0x57 } ++}; ++ ++static const unsigned char cs35l41_bst_k2_table[4][5] = { ++ { 0x24, 0x49, 0x66, 0xA3, 0xEA }, ++ { 0x24, 0x49, 0x66, 0xA3, 0xEA }, ++ { 0x48, 0x49, 0x66, 0xA3, 0xEA }, ++ { 0x48, 0x49, 0x66, 0xA3, 0xEA } ++}; ++ ++static const unsigned char cs35l41_bst_slope_table[4] = { ++ 0x75, 0x6B, 0x3B, 0x28}; ++ ++static int cs35l41_get_fs_mon_config_index(int freq) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(cs35l41_fs_mon); i++) { ++ if (cs35l41_fs_mon[i].freq == freq) ++ return i; ++ } ++ ++ return -EINVAL; ++} ++ ++static const DECLARE_TLV_DB_RANGE(dig_vol_tlv, ++ 0, 0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1), ++ 1, 913, TLV_DB_MINMAX_ITEM(-10200, 1200)); ++static DECLARE_TLV_DB_SCALE(amp_gain_tlv, 0, 1, 1); ++ ++static const struct snd_kcontrol_new dre_ctrl = ++ SOC_DAPM_SINGLE("Switch", CS35L41_PWR_CTRL3, 20, 1, 0); ++ ++static const char * const cs35l41_pcm_sftramp_text[] = { ++ "Off", ".5ms", "1ms", "2ms", "4ms", "8ms", "15ms", "30ms"}; ++ ++static SOC_ENUM_SINGLE_DECL(pcm_sft_ramp, ++ CS35L41_AMP_DIG_VOL_CTRL, 0, ++ cs35l41_pcm_sftramp_text); ++ ++static const char * const cs35l41_pcm_source_texts[] = {"ASP", "DSP"}; ++static const unsigned int cs35l41_pcm_source_values[] = {0x08, 0x32}; ++static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_pcm_source_enum, ++ CS35L41_DAC_PCM1_SRC, ++ 0, CS35L41_ASP_SOURCE_MASK, ++ cs35l41_pcm_source_texts, ++ cs35l41_pcm_source_values); ++ ++static const struct snd_kcontrol_new pcm_source_mux = ++ SOC_DAPM_ENUM("PCM Source", cs35l41_pcm_source_enum); ++ ++static const char * const cs35l41_tx_input_texts[] = {"Zero", "ASPRX1", ++ "ASPRX2", "VMON", ++ "IMON", "VPMON", ++ "VBSTMON", ++ "DSPTX1", "DSPTX2"}; ++static const unsigned int cs35l41_tx_input_values[] = {0x00, ++ CS35L41_INPUT_SRC_ASPRX1, ++ CS35L41_INPUT_SRC_ASPRX2, ++ CS35L41_INPUT_SRC_VMON, ++ CS35L41_INPUT_SRC_IMON, ++ CS35L41_INPUT_SRC_VPMON, ++ CS35L41_INPUT_SRC_VBSTMON, ++ CS35L41_INPUT_DSP_TX1, ++ CS35L41_INPUT_DSP_TX2}; ++ ++static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx1_enum, ++ CS35L41_ASP_TX1_SRC, ++ 0, CS35L41_ASP_SOURCE_MASK, ++ cs35l41_tx_input_texts, ++ cs35l41_tx_input_values); ++ ++static const struct snd_kcontrol_new asp_tx1_mux = ++ SOC_DAPM_ENUM("ASPTX1 SRC", cs35l41_asptx1_enum); ++ ++static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx2_enum, ++ CS35L41_ASP_TX2_SRC, ++ 0, CS35L41_ASP_SOURCE_MASK, ++ cs35l41_tx_input_texts, ++ cs35l41_tx_input_values); ++ ++static const struct snd_kcontrol_new asp_tx2_mux = ++ SOC_DAPM_ENUM("ASPTX2 SRC", cs35l41_asptx2_enum); ++ ++static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx3_enum, ++ CS35L41_ASP_TX3_SRC, ++ 0, CS35L41_ASP_SOURCE_MASK, ++ cs35l41_tx_input_texts, ++ cs35l41_tx_input_values); ++ ++static const struct snd_kcontrol_new asp_tx3_mux = ++ SOC_DAPM_ENUM("ASPTX3 SRC", cs35l41_asptx3_enum); ++ ++static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx4_enum, ++ CS35L41_ASP_TX4_SRC, ++ 0, CS35L41_ASP_SOURCE_MASK, ++ cs35l41_tx_input_texts, ++ cs35l41_tx_input_values); ++ ++static const struct snd_kcontrol_new asp_tx4_mux = ++ SOC_DAPM_ENUM("ASPTX4 SRC", cs35l41_asptx4_enum); ++ ++static const struct snd_kcontrol_new cs35l41_aud_controls[] = { ++ SOC_SINGLE_SX_TLV("Digital PCM Volume", CS35L41_AMP_DIG_VOL_CTRL, ++ 3, 0x4CF, 0x391, dig_vol_tlv), ++ SOC_SINGLE_TLV("Analog PCM Volume", CS35L41_AMP_GAIN_CTRL, 5, 0x14, 0, ++ amp_gain_tlv), ++ SOC_ENUM("PCM Soft Ramp", pcm_sft_ramp), ++ SOC_SINGLE("HW Noise Gate Enable", CS35L41_NG_CFG, 8, 63, 0), ++ SOC_SINGLE("HW Noise Gate Delay", CS35L41_NG_CFG, 4, 7, 0), ++ SOC_SINGLE("HW Noise Gate Threshold", CS35L41_NG_CFG, 0, 7, 0), ++ SOC_SINGLE("Aux Noise Gate CH1 Enable", ++ CS35L41_MIXER_NGATE_CH1_CFG, 16, 1, 0), ++ SOC_SINGLE("Aux Noise Gate CH1 Entry Delay", ++ CS35L41_MIXER_NGATE_CH1_CFG, 8, 15, 0), ++ SOC_SINGLE("Aux Noise Gate CH1 Threshold", ++ CS35L41_MIXER_NGATE_CH1_CFG, 0, 7, 0), ++ SOC_SINGLE("Aux Noise Gate CH2 Entry Delay", ++ CS35L41_MIXER_NGATE_CH2_CFG, 8, 15, 0), ++ SOC_SINGLE("Aux Noise Gate CH2 Enable", ++ CS35L41_MIXER_NGATE_CH2_CFG, 16, 1, 0), ++ SOC_SINGLE("Aux Noise Gate CH2 Threshold", ++ CS35L41_MIXER_NGATE_CH2_CFG, 0, 7, 0), ++ SOC_SINGLE("SCLK Force", CS35L41_SP_FORMAT, CS35L41_SCLK_FRC_SHIFT, 1, 0), ++ SOC_SINGLE("LRCLK Force", CS35L41_SP_FORMAT, CS35L41_LRCLK_FRC_SHIFT, 1, 0), ++ SOC_SINGLE("Invert Class D", CS35L41_AMP_DIG_VOL_CTRL, ++ CS35L41_AMP_INV_PCM_SHIFT, 1, 0), ++ SOC_SINGLE("Amp Gain ZC", CS35L41_AMP_GAIN_CTRL, ++ CS35L41_AMP_GAIN_ZC_SHIFT, 1, 0), ++}; ++ ++static const struct cs35l41_otp_map_element_t *cs35l41_find_otp_map(u32 otp_id) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(cs35l41_otp_map_map); i++) { ++ if (cs35l41_otp_map_map[i].id == otp_id) ++ return &cs35l41_otp_map_map[i]; ++ } ++ ++ return NULL; ++} ++ ++static int cs35l41_otp_unpack(void *data) ++{ ++ const struct cs35l41_otp_map_element_t *otp_map_match; ++ const struct cs35l41_otp_packed_element_t *otp_map; ++ struct cs35l41_private *cs35l41 = data; ++ int bit_offset, word_offset, ret, i; ++ unsigned int orig_spi_freq; ++ unsigned int bit_sum = 8; ++ u32 otp_val, otp_id_reg; ++ u32 *otp_mem; ++ ++ otp_mem = kmalloc_array(CS35L41_OTP_SIZE_WORDS, sizeof(*otp_mem), ++ GFP_KERNEL); ++ if (!otp_mem) ++ return -ENOMEM; ++ ++ ret = regmap_read(cs35l41->regmap, CS35L41_OTPID, &otp_id_reg); ++ if (ret < 0) { ++ dev_err(cs35l41->dev, "Read OTP ID failed\n"); ++ ret = -EINVAL; ++ goto err_otp_unpack; ++ } ++ ++ otp_map_match = cs35l41_find_otp_map(otp_id_reg); ++ ++ if (!otp_map_match) { ++ dev_err(cs35l41->dev, "OTP Map matching ID %d not found\n", ++ otp_id_reg); ++ ret = -EINVAL; ++ goto err_otp_unpack; ++ } ++ ++ if (cs35l41->otp_setup) ++ cs35l41->otp_setup(cs35l41, true, &orig_spi_freq); ++ ++ ret = regmap_bulk_read(cs35l41->regmap, CS35L41_OTP_MEM0, otp_mem, ++ CS35L41_OTP_SIZE_WORDS); ++ if (ret < 0) { ++ dev_err(cs35l41->dev, "Read OTP Mem failed\n"); ++ ret = -EINVAL; ++ goto err_otp_unpack; ++ } ++ ++ if (cs35l41->otp_setup) ++ cs35l41->otp_setup(cs35l41, false, &orig_spi_freq); ++ ++ otp_map = otp_map_match->map; ++ ++ bit_offset = otp_map_match->bit_offset; ++ word_offset = otp_map_match->word_offset; ++ ++ ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x00000055); ++ if (ret < 0) { ++ dev_err(cs35l41->dev, "Write Unlock key failed 1/2\n"); ++ ret = -EINVAL; ++ goto err_otp_unpack; ++ } ++ ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x000000AA); ++ if (ret < 0) { ++ dev_err(cs35l41->dev, "Write Unlock key failed 2/2\n"); ++ ret = -EINVAL; ++ goto err_otp_unpack; ++ } ++ ++ for (i = 0; i < otp_map_match->num_elements; i++) { ++ dev_dbg(cs35l41->dev, ++ "bitoffset= %d, word_offset=%d, bit_sum mod 32=%d\n", ++ bit_offset, word_offset, bit_sum % 32); ++ if (bit_offset + otp_map[i].size - 1 >= 32) { ++ otp_val = (otp_mem[word_offset] & ++ GENMASK(31, bit_offset)) >> ++ bit_offset; ++ otp_val |= (otp_mem[++word_offset] & ++ GENMASK(bit_offset + ++ otp_map[i].size - 33, 0)) << ++ (32 - bit_offset); ++ bit_offset += otp_map[i].size - 32; ++ } else { ++ ++ otp_val = (otp_mem[word_offset] & ++ GENMASK(bit_offset + otp_map[i].size - 1, ++ bit_offset)) >> bit_offset; ++ bit_offset += otp_map[i].size; ++ } ++ bit_sum += otp_map[i].size; ++ ++ if (bit_offset == 32) { ++ bit_offset = 0; ++ word_offset++; ++ } ++ ++ if (otp_map[i].reg != 0) { ++ ret = regmap_update_bits(cs35l41->regmap, ++ otp_map[i].reg, ++ GENMASK(otp_map[i].shift + ++ otp_map[i].size - 1, ++ otp_map[i].shift), ++ otp_val << otp_map[i].shift); ++ if (ret < 0) { ++ dev_err(cs35l41->dev, "Write OTP val failed\n"); ++ ret = -EINVAL; ++ goto err_otp_unpack; ++ } ++ } ++ } ++ ++ ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x000000CC); ++ if (ret < 0) { ++ dev_err(cs35l41->dev, "Write Lock key failed 1/2\n"); ++ ret = -EINVAL; ++ goto err_otp_unpack; ++ } ++ ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x00000033); ++ if (ret < 0) { ++ dev_err(cs35l41->dev, "Write Lock key failed 2/2\n"); ++ ret = -EINVAL; ++ goto err_otp_unpack; ++ } ++ ret = 0; ++ ++err_otp_unpack: ++ kfree(otp_mem); ++ return ret; ++} ++ ++static irqreturn_t cs35l41_irq(int irq, void *data) ++{ ++ struct cs35l41_private *cs35l41 = data; ++ unsigned int status[4] = { 0, 0, 0, 0 }; ++ unsigned int masks[4] = { 0, 0, 0, 0 }; ++ int ret = IRQ_NONE; ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(status); i++) { ++ regmap_read(cs35l41->regmap, ++ CS35L41_IRQ1_STATUS1 + (i * CS35L41_REGSTRIDE), ++ &status[i]); ++ regmap_read(cs35l41->regmap, ++ CS35L41_IRQ1_MASK1 + (i * CS35L41_REGSTRIDE), ++ &masks[i]); ++ } ++ ++ /* Check to see if unmasked bits are active */ ++ if (!(status[0] & ~masks[0]) && !(status[1] & ~masks[1]) && ++ !(status[2] & ~masks[2]) && !(status[3] & ~masks[3])) ++ return IRQ_NONE; ++ ++ if (status[3] & CS35L41_OTP_BOOT_DONE) { ++ regmap_update_bits(cs35l41->regmap, CS35L41_IRQ1_MASK4, ++ CS35L41_OTP_BOOT_DONE, CS35L41_OTP_BOOT_DONE); ++ } ++ ++ /* ++ * The following interrupts require a ++ * protection release cycle to get the ++ * speaker out of Safe-Mode. ++ */ ++ if (status[0] & CS35L41_AMP_SHORT_ERR) { ++ dev_crit_ratelimited(cs35l41->dev, "Amp short error\n"); ++ regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, ++ CS35L41_AMP_SHORT_ERR); ++ regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); ++ regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, ++ CS35L41_AMP_SHORT_ERR_RLS, ++ CS35L41_AMP_SHORT_ERR_RLS); ++ regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, ++ CS35L41_AMP_SHORT_ERR_RLS, 0); ++ ret = IRQ_HANDLED; ++ } ++ ++ if (status[0] & CS35L41_TEMP_WARN) { ++ dev_crit_ratelimited(cs35l41->dev, "Over temperature warning\n"); ++ regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, ++ CS35L41_TEMP_WARN); ++ regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); ++ regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, ++ CS35L41_TEMP_WARN_ERR_RLS, ++ CS35L41_TEMP_WARN_ERR_RLS); ++ regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, ++ CS35L41_TEMP_WARN_ERR_RLS, 0); ++ ret = IRQ_HANDLED; ++ } ++ ++ if (status[0] & CS35L41_TEMP_ERR) { ++ dev_crit_ratelimited(cs35l41->dev, "Over temperature error\n"); ++ regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, ++ CS35L41_TEMP_ERR); ++ regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); ++ regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, ++ CS35L41_TEMP_ERR_RLS, ++ CS35L41_TEMP_ERR_RLS); ++ regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, ++ CS35L41_TEMP_ERR_RLS, 0); ++ ret = IRQ_HANDLED; ++ } ++ ++ if (status[0] & CS35L41_BST_OVP_ERR) { ++ dev_crit_ratelimited(cs35l41->dev, "VBST Over Voltage error\n"); ++ regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, ++ CS35L41_BST_EN_MASK, 0); ++ regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, ++ CS35L41_BST_OVP_ERR); ++ regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); ++ regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, ++ CS35L41_BST_OVP_ERR_RLS, ++ CS35L41_BST_OVP_ERR_RLS); ++ regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, ++ CS35L41_BST_OVP_ERR_RLS, 0); ++ regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, ++ CS35L41_BST_EN_MASK, ++ CS35L41_BST_EN_DEFAULT << ++ CS35L41_BST_EN_SHIFT); ++ ret = IRQ_HANDLED; ++ } ++ ++ if (status[0] & CS35L41_BST_DCM_UVP_ERR) { ++ dev_crit_ratelimited(cs35l41->dev, "DCM VBST Under Voltage Error\n"); ++ regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, ++ CS35L41_BST_EN_MASK, 0); ++ regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, ++ CS35L41_BST_DCM_UVP_ERR); ++ regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); ++ regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, ++ CS35L41_BST_UVP_ERR_RLS, ++ CS35L41_BST_UVP_ERR_RLS); ++ regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, ++ CS35L41_BST_UVP_ERR_RLS, 0); ++ regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, ++ CS35L41_BST_EN_MASK, ++ CS35L41_BST_EN_DEFAULT << ++ CS35L41_BST_EN_SHIFT); ++ ret = IRQ_HANDLED; ++ } ++ ++ if (status[0] & CS35L41_BST_SHORT_ERR) { ++ dev_crit_ratelimited(cs35l41->dev, "LBST error: powering off!\n"); ++ regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, ++ CS35L41_BST_EN_MASK, 0); ++ regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, ++ CS35L41_BST_SHORT_ERR); ++ regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); ++ regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, ++ CS35L41_BST_SHORT_ERR_RLS, ++ CS35L41_BST_SHORT_ERR_RLS); ++ regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, ++ CS35L41_BST_SHORT_ERR_RLS, 0); ++ regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, ++ CS35L41_BST_EN_MASK, ++ CS35L41_BST_EN_DEFAULT << ++ CS35L41_BST_EN_SHIFT); ++ ret = IRQ_HANDLED; ++ } ++ ++ return ret; ++} ++ ++static const struct reg_sequence cs35l41_pup_patch[] = { ++ { 0x00000040, 0x00000055 }, ++ { 0x00000040, 0x000000AA }, ++ { 0x00002084, 0x002F1AA0 }, ++ { 0x00000040, 0x000000CC }, ++ { 0x00000040, 0x00000033 }, ++}; ++ ++static const struct reg_sequence cs35l41_pdn_patch[] = { ++ { 0x00000040, 0x00000055 }, ++ { 0x00000040, 0x000000AA }, ++ { 0x00002084, 0x002F1AA3 }, ++ { 0x00000040, 0x000000CC }, ++ { 0x00000040, 0x00000033 }, ++}; ++ ++static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w, ++ struct snd_kcontrol *kcontrol, int event) ++{ ++ struct snd_soc_component *component = ++ snd_soc_dapm_to_component(w->dapm); ++ struct cs35l41_private *cs35l41 = ++ snd_soc_component_get_drvdata(component); ++ unsigned int val; ++ int ret = 0; ++ bool pdn; ++ int i; ++ ++ switch (event) { ++ case SND_SOC_DAPM_POST_PMU: ++ regmap_multi_reg_write_bypassed(cs35l41->regmap, ++ cs35l41_pup_patch, ++ ARRAY_SIZE(cs35l41_pup_patch)); ++ ++ regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL1, ++ CS35L41_GLOBAL_EN_MASK, ++ 1 << CS35L41_GLOBAL_EN_SHIFT); ++ ++ usleep_range(1000, 1100); ++ break; ++ case SND_SOC_DAPM_POST_PMD: ++ regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL1, ++ CS35L41_GLOBAL_EN_MASK, 0); ++ ++ pdn = false; ++ for (i = 0; i < 100; i++) { ++ regmap_read(cs35l41->regmap, ++ CS35L41_IRQ1_STATUS1, ++ &val); ++ if (val & CS35L41_PDN_DONE_MASK) { ++ pdn = true; ++ break; ++ } ++ usleep_range(1000, 1100); ++ } ++ ++ if (!pdn) ++ dev_warn(cs35l41->dev, "PDN failed\n"); ++ ++ regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, ++ CS35L41_PDN_DONE_MASK); ++ ++ regmap_multi_reg_write_bypassed(cs35l41->regmap, ++ cs35l41_pdn_patch, ++ ARRAY_SIZE(cs35l41_pdn_patch)); ++ break; ++ default: ++ dev_err(cs35l41->dev, "Invalid event = 0x%x\n", event); ++ ret = -EINVAL; ++ } ++ return ret; ++} ++ ++static const struct snd_soc_dapm_widget cs35l41_dapm_widgets[] = { ++ SND_SOC_DAPM_OUTPUT("SPK"), ++ ++ SND_SOC_DAPM_AIF_IN("ASPRX1", NULL, 0, CS35L41_SP_ENABLES, 16, 0), ++ SND_SOC_DAPM_AIF_IN("ASPRX2", NULL, 0, CS35L41_SP_ENABLES, 17, 0), ++ SND_SOC_DAPM_AIF_OUT("ASPTX1", NULL, 0, CS35L41_SP_ENABLES, 0, 0), ++ SND_SOC_DAPM_AIF_OUT("ASPTX2", NULL, 0, CS35L41_SP_ENABLES, 1, 0), ++ SND_SOC_DAPM_AIF_OUT("ASPTX3", NULL, 0, CS35L41_SP_ENABLES, 2, 0), ++ SND_SOC_DAPM_AIF_OUT("ASPTX4", NULL, 0, CS35L41_SP_ENABLES, 3, 0), ++ ++ SND_SOC_DAPM_ADC("VMON ADC", NULL, CS35L41_PWR_CTRL2, 12, 0), ++ SND_SOC_DAPM_ADC("IMON ADC", NULL, CS35L41_PWR_CTRL2, 13, 0), ++ SND_SOC_DAPM_ADC("VPMON ADC", NULL, CS35L41_PWR_CTRL2, 8, 0), ++ SND_SOC_DAPM_ADC("VBSTMON ADC", NULL, CS35L41_PWR_CTRL2, 9, 0), ++ SND_SOC_DAPM_ADC("TEMPMON ADC", NULL, CS35L41_PWR_CTRL2, 10, 0), ++ SND_SOC_DAPM_ADC("CLASS H", NULL, CS35L41_PWR_CTRL3, 4, 0), ++ ++ SND_SOC_DAPM_OUT_DRV_E("Main AMP", CS35L41_PWR_CTRL2, 0, 0, NULL, 0, ++ cs35l41_main_amp_event, ++ SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), ++ ++ SND_SOC_DAPM_INPUT("VP"), ++ SND_SOC_DAPM_INPUT("VBST"), ++ SND_SOC_DAPM_INPUT("ISENSE"), ++ SND_SOC_DAPM_INPUT("VSENSE"), ++ SND_SOC_DAPM_INPUT("TEMP"), ++ ++ SND_SOC_DAPM_MUX("ASP TX1 Source", SND_SOC_NOPM, 0, 0, &asp_tx1_mux), ++ SND_SOC_DAPM_MUX("ASP TX2 Source", SND_SOC_NOPM, 0, 0, &asp_tx2_mux), ++ SND_SOC_DAPM_MUX("ASP TX3 Source", SND_SOC_NOPM, 0, 0, &asp_tx3_mux), ++ SND_SOC_DAPM_MUX("ASP TX4 Source", SND_SOC_NOPM, 0, 0, &asp_tx4_mux), ++ SND_SOC_DAPM_MUX("PCM Source", SND_SOC_NOPM, 0, 0, &pcm_source_mux), ++ SND_SOC_DAPM_SWITCH("DRE", SND_SOC_NOPM, 0, 0, &dre_ctrl), ++}; ++ ++static const struct snd_soc_dapm_route cs35l41_audio_map[] = { ++ ++ {"ASP TX1 Source", "VMON", "VMON ADC"}, ++ {"ASP TX1 Source", "IMON", "IMON ADC"}, ++ {"ASP TX1 Source", "VPMON", "VPMON ADC"}, ++ {"ASP TX1 Source", "VBSTMON", "VBSTMON ADC"}, ++ {"ASP TX1 Source", "ASPRX1", "ASPRX1" }, ++ {"ASP TX1 Source", "ASPRX2", "ASPRX2" }, ++ {"ASP TX2 Source", "VMON", "VMON ADC"}, ++ {"ASP TX2 Source", "IMON", "IMON ADC"}, ++ {"ASP TX2 Source", "VPMON", "VPMON ADC"}, ++ {"ASP TX2 Source", "VBSTMON", "VBSTMON ADC"}, ++ {"ASP TX2 Source", "ASPRX1", "ASPRX1" }, ++ {"ASP TX2 Source", "ASPRX2", "ASPRX2" }, ++ {"ASP TX3 Source", "VMON", "VMON ADC"}, ++ {"ASP TX3 Source", "IMON", "IMON ADC"}, ++ {"ASP TX3 Source", "VPMON", "VPMON ADC"}, ++ {"ASP TX3 Source", "VBSTMON", "VBSTMON ADC"}, ++ {"ASP TX3 Source", "ASPRX1", "ASPRX1" }, ++ {"ASP TX3 Source", "ASPRX2", "ASPRX2" }, ++ {"ASP TX4 Source", "VMON", "VMON ADC"}, ++ {"ASP TX4 Source", "IMON", "IMON ADC"}, ++ {"ASP TX4 Source", "VPMON", "VPMON ADC"}, ++ {"ASP TX4 Source", "VBSTMON", "VBSTMON ADC"}, ++ {"ASP TX4 Source", "ASPRX1", "ASPRX1" }, ++ {"ASP TX4 Source", "ASPRX2", "ASPRX2" }, ++ {"ASPTX1", NULL, "ASP TX1 Source"}, ++ {"ASPTX2", NULL, "ASP TX2 Source"}, ++ {"ASPTX3", NULL, "ASP TX3 Source"}, ++ {"ASPTX4", NULL, "ASP TX4 Source"}, ++ {"AMP Capture", NULL, "ASPTX1"}, ++ {"AMP Capture", NULL, "ASPTX2"}, ++ {"AMP Capture", NULL, "ASPTX3"}, ++ {"AMP Capture", NULL, "ASPTX4"}, ++ ++ {"VMON ADC", NULL, "VSENSE"}, ++ {"IMON ADC", NULL, "ISENSE"}, ++ {"VPMON ADC", NULL, "VP"}, ++ {"TEMPMON ADC", NULL, "TEMP"}, ++ {"VBSTMON ADC", NULL, "VBST"}, ++ ++ {"ASPRX1", NULL, "AMP Playback"}, ++ {"ASPRX2", NULL, "AMP Playback"}, ++ {"DRE", "Switch", "CLASS H"}, ++ {"Main AMP", NULL, "CLASS H"}, ++ {"Main AMP", NULL, "DRE"}, ++ {"SPK", NULL, "Main AMP"}, ++ ++ {"PCM Source", "ASP", "ASPRX1"}, ++ {"CLASS H", NULL, "PCM Source"}, ++ ++}; ++ ++static int cs35l41_set_channel_map(struct snd_soc_dai *dai, unsigned int tx_num, ++ unsigned int *tx_slot, unsigned int rx_num, ++ unsigned int *rx_slot) ++{ ++ struct cs35l41_private *cs35l41 = ++ snd_soc_component_get_drvdata(dai->component); ++ int i; ++ ++ if (tx_num > 4 || rx_num > 2) ++ return -EINVAL; ++ ++ for (i = 0; i < rx_num; i++) { ++ dev_dbg(cs35l41->dev, "%s: rx slot %d position = %d\n", ++ __func__, i, rx_slot[i]); ++ regmap_update_bits(cs35l41->regmap, CS35L41_SP_FRAME_RX_SLOT, ++ 0x3F << (i * 8), rx_slot[i] << (i * 8)); ++ } ++ ++ for (i = 0; i < tx_num; i++) { ++ dev_dbg(cs35l41->dev, "%s: tx slot %d position = %d\n", ++ __func__, i, tx_slot[i]); ++ regmap_update_bits(cs35l41->regmap, CS35L41_SP_FRAME_TX_SLOT, ++ 0x3F << (i * 8), tx_slot[i] << (i * 8)); ++ } ++ ++ return 0; ++} ++ ++static int cs35l41_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) ++{ ++ struct cs35l41_private *cs35l41 = ++ snd_soc_component_get_drvdata(codec_dai->component); ++ unsigned int asp_fmt, lrclk_fmt, sclk_fmt, clock_provider; ++ ++ switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { ++ case SND_SOC_DAIFMT_CBP_CFP: ++ clock_provider = 1; ++ break; ++ case SND_SOC_DAIFMT_CBC_CFC: ++ clock_provider = 0; ++ break; ++ default: ++ dev_warn(cs35l41->dev, ++ "%s: Mixed provider/consumer mode unsupported\n", ++ __func__); ++ return -EINVAL; ++ } ++ ++ regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, ++ CS35L41_SCLK_MSTR_MASK, ++ clock_provider << CS35L41_SCLK_MSTR_SHIFT); ++ regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, ++ CS35L41_LRCLK_MSTR_MASK, ++ clock_provider << CS35L41_LRCLK_MSTR_SHIFT); ++ ++ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { ++ case SND_SOC_DAIFMT_DSP_A: ++ asp_fmt = 0; ++ break; ++ case SND_SOC_DAIFMT_I2S: ++ asp_fmt = 2; ++ break; ++ default: ++ dev_warn(cs35l41->dev, ++ "%s: Invalid or unsupported DAI format\n", __func__); ++ return -EINVAL; ++ } ++ ++ regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, ++ CS35L41_ASP_FMT_MASK, ++ asp_fmt << CS35L41_ASP_FMT_SHIFT); ++ ++ switch (fmt & SND_SOC_DAIFMT_INV_MASK) { ++ case SND_SOC_DAIFMT_NB_IF: ++ lrclk_fmt = 1; ++ sclk_fmt = 0; ++ break; ++ case SND_SOC_DAIFMT_IB_NF: ++ lrclk_fmt = 0; ++ sclk_fmt = 1; ++ break; ++ case SND_SOC_DAIFMT_IB_IF: ++ lrclk_fmt = 1; ++ sclk_fmt = 1; ++ break; ++ case SND_SOC_DAIFMT_NB_NF: ++ lrclk_fmt = 0; ++ sclk_fmt = 0; ++ break; ++ default: ++ dev_warn(cs35l41->dev, ++ "%s: Invalid DAI clock INV\n", __func__); ++ return -EINVAL; ++ } ++ ++ regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, ++ CS35L41_LRCLK_INV_MASK, ++ lrclk_fmt << CS35L41_LRCLK_INV_SHIFT); ++ regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, ++ CS35L41_SCLK_INV_MASK, ++ sclk_fmt << CS35L41_SCLK_INV_SHIFT); ++ ++ return 0; ++} ++ ++struct cs35l41_global_fs_config { ++ int rate; ++ int fs_cfg; ++}; ++ ++static const struct cs35l41_global_fs_config cs35l41_fs_rates[] = { ++ { 12000, 0x01 }, ++ { 24000, 0x02 }, ++ { 48000, 0x03 }, ++ { 96000, 0x04 }, ++ { 192000, 0x05 }, ++ { 11025, 0x09 }, ++ { 22050, 0x0A }, ++ { 44100, 0x0B }, ++ { 88200, 0x0C }, ++ { 176400, 0x0D }, ++ { 8000, 0x11 }, ++ { 16000, 0x12 }, ++ { 32000, 0x13 }, ++}; ++ ++static int cs35l41_pcm_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params, ++ struct snd_soc_dai *dai) ++{ ++ struct cs35l41_private *cs35l41 = ++ snd_soc_component_get_drvdata(dai->component); ++ unsigned int rate = params_rate(params); ++ u8 asp_wl; ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(cs35l41_fs_rates); i++) { ++ if (rate == cs35l41_fs_rates[i].rate) ++ break; ++ } ++ ++ if (i >= ARRAY_SIZE(cs35l41_fs_rates)) { ++ dev_err(cs35l41->dev, "%s: Unsupported rate: %u\n", ++ __func__, rate); ++ return -EINVAL; ++ } ++ ++ asp_wl = params_width(params); ++ ++ if (i < ARRAY_SIZE(cs35l41_fs_rates)) ++ regmap_update_bits(cs35l41->regmap, CS35L41_GLOBAL_CLK_CTRL, ++ CS35L41_GLOBAL_FS_MASK, ++ cs35l41_fs_rates[i].fs_cfg << CS35L41_GLOBAL_FS_SHIFT); ++ ++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { ++ regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, ++ CS35L41_ASP_WIDTH_RX_MASK, ++ asp_wl << CS35L41_ASP_WIDTH_RX_SHIFT); ++ regmap_update_bits(cs35l41->regmap, CS35L41_SP_RX_WL, ++ CS35L41_ASP_RX_WL_MASK, ++ asp_wl << CS35L41_ASP_RX_WL_SHIFT); ++ } else { ++ regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, ++ CS35L41_ASP_WIDTH_TX_MASK, ++ asp_wl << CS35L41_ASP_WIDTH_TX_SHIFT); ++ regmap_update_bits(cs35l41->regmap, CS35L41_SP_TX_WL, ++ CS35L41_ASP_TX_WL_MASK, ++ asp_wl << CS35L41_ASP_TX_WL_SHIFT); ++ } ++ ++ return 0; ++} ++ ++static int cs35l41_get_clk_config(int freq) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(cs35l41_pll_sysclk); i++) { ++ if (cs35l41_pll_sysclk[i].freq == freq) ++ return cs35l41_pll_sysclk[i].clk_cfg; ++ } ++ ++ return -EINVAL; ++} ++ ++static const unsigned int cs35l41_src_rates[] = { ++ 8000, 12000, 11025, 16000, 22050, 24000, 32000, ++ 44100, 48000, 88200, 96000, 176400, 192000 ++}; ++ ++static const struct snd_pcm_hw_constraint_list cs35l41_constraints = { ++ .count = ARRAY_SIZE(cs35l41_src_rates), ++ .list = cs35l41_src_rates, ++}; ++ ++static int cs35l41_pcm_startup(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai) ++{ ++ if (substream->runtime) ++ return snd_pcm_hw_constraint_list(substream->runtime, 0, ++ SNDRV_PCM_HW_PARAM_RATE, &cs35l41_constraints); ++ return 0; ++} ++ ++static int cs35l41_component_set_sysclk(struct snd_soc_component *component, ++ int clk_id, int source, unsigned int freq, ++ int dir) ++{ ++ struct cs35l41_private *cs35l41 = ++ snd_soc_component_get_drvdata(component); ++ int extclk_cfg, clksrc; ++ ++ switch (clk_id) { ++ case CS35L41_CLKID_SCLK: ++ clksrc = CS35L41_PLLSRC_SCLK; ++ break; ++ case CS35L41_CLKID_LRCLK: ++ clksrc = CS35L41_PLLSRC_LRCLK; ++ break; ++ case CS35L41_CLKID_MCLK: ++ clksrc = CS35L41_PLLSRC_MCLK; ++ break; ++ default: ++ dev_err(cs35l41->dev, "Invalid CLK Config\n"); ++ return -EINVAL; ++ } ++ ++ extclk_cfg = cs35l41_get_clk_config(freq); ++ ++ if (extclk_cfg < 0) { ++ dev_err(cs35l41->dev, "Invalid CLK Config: %d, freq: %u\n", ++ extclk_cfg, freq); ++ return -EINVAL; ++ } ++ ++ regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, ++ CS35L41_PLL_OPENLOOP_MASK, ++ 1 << CS35L41_PLL_OPENLOOP_SHIFT); ++ regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, ++ CS35L41_REFCLK_FREQ_MASK, ++ extclk_cfg << CS35L41_REFCLK_FREQ_SHIFT); ++ regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, ++ CS35L41_PLL_CLK_EN_MASK, ++ 0 << CS35L41_PLL_CLK_EN_SHIFT); ++ regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, ++ CS35L41_PLL_CLK_SEL_MASK, clksrc); ++ regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, ++ CS35L41_PLL_OPENLOOP_MASK, ++ 0 << CS35L41_PLL_OPENLOOP_SHIFT); ++ regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, ++ CS35L41_PLL_CLK_EN_MASK, ++ 1 << CS35L41_PLL_CLK_EN_SHIFT); ++ ++ return 0; ++} ++ ++static int cs35l41_dai_set_sysclk(struct snd_soc_dai *dai, ++ int clk_id, unsigned int freq, int dir) ++{ ++ struct cs35l41_private *cs35l41 = ++ snd_soc_component_get_drvdata(dai->component); ++ unsigned int fs1_val; ++ unsigned int fs2_val; ++ unsigned int val; ++ int fsIndex; ++ ++ fsIndex = cs35l41_get_fs_mon_config_index(freq); ++ if (fsIndex < 0) { ++ dev_err(cs35l41->dev, "Invalid CLK Config freq: %u\n", freq); ++ return -EINVAL; ++ } ++ ++ dev_dbg(cs35l41->dev, "Set DAI sysclk %d\n", freq); ++ if (freq <= 6144000) { ++ /* Use the lookup table */ ++ fs1_val = cs35l41_fs_mon[fsIndex].fs1; ++ fs2_val = cs35l41_fs_mon[fsIndex].fs2; ++ } else { ++ /* Use hard-coded values */ ++ fs1_val = 0x10; ++ fs2_val = 0x24; ++ } ++ ++ val = fs1_val; ++ val |= (fs2_val << CS35L41_FS2_WINDOW_SHIFT) & CS35L41_FS2_WINDOW_MASK; ++ regmap_write(cs35l41->regmap, CS35L41_TST_FS_MON0, val); ++ ++ return 0; ++} ++ ++static int cs35l41_boost_config(struct cs35l41_private *cs35l41, ++ int boost_ind, int boost_cap, int boost_ipk) ++{ ++ unsigned char bst_lbst_val, bst_cbst_range, bst_ipk_scaled; ++ struct regmap *regmap = cs35l41->regmap; ++ struct device *dev = cs35l41->dev; ++ int ret; ++ ++ switch (boost_ind) { ++ case 1000: /* 1.0 uH */ ++ bst_lbst_val = 0; ++ break; ++ case 1200: /* 1.2 uH */ ++ bst_lbst_val = 1; ++ break; ++ case 1500: /* 1.5 uH */ ++ bst_lbst_val = 2; ++ break; ++ case 2200: /* 2.2 uH */ ++ bst_lbst_val = 3; ++ break; ++ default: ++ dev_err(dev, "Invalid boost inductor value: %d nH\n", ++ boost_ind); ++ return -EINVAL; ++ } ++ ++ switch (boost_cap) { ++ case 0 ... 19: ++ bst_cbst_range = 0; ++ break; ++ case 20 ... 50: ++ bst_cbst_range = 1; ++ break; ++ case 51 ... 100: ++ bst_cbst_range = 2; ++ break; ++ case 101 ... 200: ++ bst_cbst_range = 3; ++ break; ++ default: /* 201 uF and greater */ ++ bst_cbst_range = 4; ++ } ++ ++ ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_COEFF, ++ CS35L41_BST_K1_MASK, ++ cs35l41_bst_k1_table[bst_lbst_val][bst_cbst_range] ++ << CS35L41_BST_K1_SHIFT); ++ if (ret) { ++ dev_err(dev, "Failed to write boost K1 coefficient\n"); ++ return ret; ++ } ++ ++ ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_COEFF, ++ CS35L41_BST_K2_MASK, ++ cs35l41_bst_k2_table[bst_lbst_val][bst_cbst_range] ++ << CS35L41_BST_K2_SHIFT); ++ if (ret) { ++ dev_err(dev, "Failed to write boost K2 coefficient\n"); ++ return ret; ++ } ++ ++ ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_SLOPE_LBST, ++ CS35L41_BST_SLOPE_MASK, ++ cs35l41_bst_slope_table[bst_lbst_val] ++ << CS35L41_BST_SLOPE_SHIFT); ++ if (ret) { ++ dev_err(dev, "Failed to write boost slope coefficient\n"); ++ return ret; ++ } ++ ++ ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_SLOPE_LBST, ++ CS35L41_BST_LBST_VAL_MASK, ++ bst_lbst_val << CS35L41_BST_LBST_VAL_SHIFT); ++ if (ret) { ++ dev_err(dev, "Failed to write boost inductor value\n"); ++ return ret; ++ } ++ ++ if ((boost_ipk < 1600) || (boost_ipk > 4500)) { ++ dev_err(dev, "Invalid boost inductor peak current: %d mA\n", ++ boost_ipk); ++ return -EINVAL; ++ } ++ bst_ipk_scaled = ((boost_ipk - 1600) / 50) + 0x10; ++ ++ ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_PEAK_CUR, ++ CS35L41_BST_IPK_MASK, ++ bst_ipk_scaled << CS35L41_BST_IPK_SHIFT); ++ if (ret) { ++ dev_err(dev, "Failed to write boost inductor peak current\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int cs35l41_set_pdata(struct cs35l41_private *cs35l41) ++{ ++ int ret; ++ ++ /* Set Platform Data */ ++ /* Required */ ++ if (cs35l41->pdata.bst_ipk && ++ cs35l41->pdata.bst_ind && cs35l41->pdata.bst_cap) { ++ ret = cs35l41_boost_config(cs35l41, cs35l41->pdata.bst_ind, ++ cs35l41->pdata.bst_cap, ++ cs35l41->pdata.bst_ipk); ++ if (ret) { ++ dev_err(cs35l41->dev, "Error in Boost DT config\n"); ++ return ret; ++ } ++ } else { ++ dev_err(cs35l41->dev, "Incomplete Boost component DT config\n"); ++ return -EINVAL; ++ } ++ ++ /* Optional */ ++ if (cs35l41->pdata.dout_hiz <= CS35L41_ASP_DOUT_HIZ_MASK && ++ cs35l41->pdata.dout_hiz >= 0) ++ regmap_update_bits(cs35l41->regmap, CS35L41_SP_HIZ_CTRL, ++ CS35L41_ASP_DOUT_HIZ_MASK, ++ cs35l41->pdata.dout_hiz); ++ ++ return 0; ++} ++ ++static int cs35l41_irq_gpio_config(struct cs35l41_private *cs35l41) ++{ ++ struct cs35l41_irq_cfg *irq_gpio_cfg1 = &cs35l41->pdata.irq_config1; ++ struct cs35l41_irq_cfg *irq_gpio_cfg2 = &cs35l41->pdata.irq_config2; ++ int irq_pol = IRQF_TRIGGER_NONE; ++ ++ if (irq_gpio_cfg1->irq_pol_inv) ++ regmap_update_bits(cs35l41->regmap, ++ CS35L41_GPIO1_CTRL1, ++ CS35L41_GPIO_POL_MASK, ++ CS35L41_GPIO_POL_MASK); ++ if (irq_gpio_cfg1->irq_out_en) ++ regmap_update_bits(cs35l41->regmap, ++ CS35L41_GPIO1_CTRL1, ++ CS35L41_GPIO_DIR_MASK, ++ 0); ++ if (irq_gpio_cfg1->irq_src_sel) ++ regmap_update_bits(cs35l41->regmap, ++ CS35L41_GPIO_PAD_CONTROL, ++ CS35L41_GPIO1_CTRL_MASK, ++ irq_gpio_cfg1->irq_src_sel << ++ CS35L41_GPIO1_CTRL_SHIFT); ++ ++ if (irq_gpio_cfg2->irq_pol_inv) ++ regmap_update_bits(cs35l41->regmap, ++ CS35L41_GPIO2_CTRL1, ++ CS35L41_GPIO_POL_MASK, ++ CS35L41_GPIO_POL_MASK); ++ if (irq_gpio_cfg2->irq_out_en) ++ regmap_update_bits(cs35l41->regmap, ++ CS35L41_GPIO2_CTRL1, ++ CS35L41_GPIO_DIR_MASK, ++ 0); ++ if (irq_gpio_cfg2->irq_src_sel) ++ regmap_update_bits(cs35l41->regmap, ++ CS35L41_GPIO_PAD_CONTROL, ++ CS35L41_GPIO2_CTRL_MASK, ++ irq_gpio_cfg2->irq_src_sel << ++ CS35L41_GPIO2_CTRL_SHIFT); ++ ++ if ((irq_gpio_cfg2->irq_src_sel == ++ (CS35L41_GPIO_CTRL_ACTV_LO | CS35L41_VALID_PDATA)) || ++ (irq_gpio_cfg2->irq_src_sel == ++ (CS35L41_GPIO_CTRL_OPEN_INT | CS35L41_VALID_PDATA))) ++ irq_pol = IRQF_TRIGGER_LOW; ++ else if (irq_gpio_cfg2->irq_src_sel == ++ (CS35L41_GPIO_CTRL_ACTV_HI | CS35L41_VALID_PDATA)) ++ irq_pol = IRQF_TRIGGER_HIGH; ++ ++ return irq_pol; ++} ++ ++static const struct snd_soc_dai_ops cs35l41_ops = { ++ .startup = cs35l41_pcm_startup, ++ .set_fmt = cs35l41_set_dai_fmt, ++ .hw_params = cs35l41_pcm_hw_params, ++ .set_sysclk = cs35l41_dai_set_sysclk, ++ .set_channel_map = cs35l41_set_channel_map, ++}; ++ ++static struct snd_soc_dai_driver cs35l41_dai[] = { ++ { ++ .name = "cs35l41-pcm", ++ .id = 0, ++ .playback = { ++ .stream_name = "AMP Playback", ++ .channels_min = 1, ++ .channels_max = 2, ++ .rates = SNDRV_PCM_RATE_KNOT, ++ .formats = CS35L41_RX_FORMATS, ++ }, ++ .capture = { ++ .stream_name = "AMP Capture", ++ .channels_min = 1, ++ .channels_max = 8, ++ .rates = SNDRV_PCM_RATE_KNOT, ++ .formats = CS35L41_TX_FORMATS, ++ }, ++ .ops = &cs35l41_ops, ++ .symmetric_rate = 1, ++ }, ++}; ++ ++static const struct snd_soc_component_driver soc_component_dev_cs35l41 = { ++ .name = "cs35l41-codec", ++ ++ .dapm_widgets = cs35l41_dapm_widgets, ++ .num_dapm_widgets = ARRAY_SIZE(cs35l41_dapm_widgets), ++ .dapm_routes = cs35l41_audio_map, ++ .num_dapm_routes = ARRAY_SIZE(cs35l41_audio_map), ++ ++ .controls = cs35l41_aud_controls, ++ .num_controls = ARRAY_SIZE(cs35l41_aud_controls), ++ .set_sysclk = cs35l41_component_set_sysclk, ++}; ++ ++static int cs35l41_handle_pdata(struct device *dev, ++ struct cs35l41_platform_data *pdata, ++ struct cs35l41_private *cs35l41) ++{ ++ struct cs35l41_irq_cfg *irq_gpio1_config = &pdata->irq_config1; ++ struct cs35l41_irq_cfg *irq_gpio2_config = &pdata->irq_config2; ++ unsigned int val; ++ int ret; ++ ++ ret = device_property_read_u32(dev, "cirrus,boost-peak-milliamp", &val); ++ if (ret >= 0) ++ pdata->bst_ipk = val; ++ ++ ret = device_property_read_u32(dev, "cirrus,boost-ind-nanohenry", &val); ++ if (ret >= 0) ++ pdata->bst_ind = val; ++ ++ ret = device_property_read_u32(dev, "cirrus,boost-cap-microfarad", &val); ++ if (ret >= 0) ++ pdata->bst_cap = val; ++ ++ ret = device_property_read_u32(dev, "cirrus,asp-sdout-hiz", &val); ++ if (ret >= 0) ++ pdata->dout_hiz = val; ++ else ++ pdata->dout_hiz = -1; ++ ++ /* GPIO1 Pin Config */ ++ irq_gpio1_config->irq_pol_inv = device_property_read_bool(dev, ++ "cirrus,gpio1-polarity-invert"); ++ irq_gpio1_config->irq_out_en = device_property_read_bool(dev, ++ "cirrus,gpio1-output-enable"); ++ ret = device_property_read_u32(dev, "cirrus,gpio1-src-select", ++ &val); ++ if (ret >= 0) { ++ val |= CS35L41_VALID_PDATA; ++ irq_gpio1_config->irq_src_sel = val; ++ } ++ ++ /* GPIO2 Pin Config */ ++ irq_gpio2_config->irq_pol_inv = device_property_read_bool(dev, ++ "cirrus,gpio2-polarity-invert"); ++ irq_gpio2_config->irq_out_en = device_property_read_bool(dev, ++ "cirrus,gpio2-output-enable"); ++ ret = device_property_read_u32(dev, "cirrus,gpio2-src-select", ++ &val); ++ if (ret >= 0) { ++ val |= CS35L41_VALID_PDATA; ++ irq_gpio2_config->irq_src_sel = val; ++ } ++ ++ return 0; ++} ++ ++static const struct reg_sequence cs35l41_reva0_errata_patch[] = { ++ { 0x00000040, 0x00005555 }, ++ { 0x00000040, 0x0000AAAA }, ++ { 0x00003854, 0x05180240 }, ++ { CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 }, ++ { 0x00004310, 0x00000000 }, ++ { CS35L41_VPVBST_FS_SEL, 0x00000000 }, ++ { CS35L41_OTP_TRIM_30, 0x9091A1C8 }, ++ { 0x00003014, 0x0200EE0E }, ++ { CS35L41_BSTCVRT_DCM_CTRL, 0x00000051 }, ++ { 0x00000054, 0x00000004 }, ++ { CS35L41_IRQ1_DB3, 0x00000000 }, ++ { CS35L41_IRQ2_DB3, 0x00000000 }, ++ { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 }, ++ { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, ++ { 0x00000040, 0x0000CCCC }, ++ { 0x00000040, 0x00003333 }, ++}; ++ ++static const struct reg_sequence cs35l41_revb0_errata_patch[] = { ++ { 0x00000040, 0x00005555 }, ++ { 0x00000040, 0x0000AAAA }, ++ { CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 }, ++ { 0x00004310, 0x00000000 }, ++ { CS35L41_VPVBST_FS_SEL, 0x00000000 }, ++ { CS35L41_BSTCVRT_DCM_CTRL, 0x00000051 }, ++ { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 }, ++ { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, ++ { 0x00000040, 0x0000CCCC }, ++ { 0x00000040, 0x00003333 }, ++}; ++ ++static const struct reg_sequence cs35l41_revb2_errata_patch[] = { ++ { 0x00000040, 0x00005555 }, ++ { 0x00000040, 0x0000AAAA }, ++ { CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 }, ++ { 0x00004310, 0x00000000 }, ++ { CS35L41_VPVBST_FS_SEL, 0x00000000 }, ++ { CS35L41_BSTCVRT_DCM_CTRL, 0x00000051 }, ++ { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 }, ++ { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, ++ { 0x00000040, 0x0000CCCC }, ++ { 0x00000040, 0x00003333 }, ++}; ++ ++int cs35l41_probe(struct cs35l41_private *cs35l41, ++ struct cs35l41_platform_data *pdata) ++{ ++ u32 regid, reg_revid, i, mtl_revid, int_status, chipid_match; ++ int irq_pol = 0; ++ int timeout; ++ int ret; ++ ++ if (pdata) { ++ cs35l41->pdata = *pdata; ++ } else { ++ ret = cs35l41_handle_pdata(cs35l41->dev, &cs35l41->pdata, ++ cs35l41); ++ if (ret != 0) ++ return ret; ++ } ++ ++ for (i = 0; i < CS35L41_NUM_SUPPLIES; i++) ++ cs35l41->supplies[i].supply = cs35l41_supplies[i]; ++ ++ ret = devm_regulator_bulk_get(cs35l41->dev, CS35L41_NUM_SUPPLIES, ++ cs35l41->supplies); ++ if (ret != 0) { ++ dev_err(cs35l41->dev, ++ "Failed to request core supplies: %d\n", ++ ret); ++ return ret; ++ } ++ ++ ret = regulator_bulk_enable(CS35L41_NUM_SUPPLIES, cs35l41->supplies); ++ if (ret != 0) { ++ dev_err(cs35l41->dev, ++ "Failed to enable core supplies: %d\n", ret); ++ return ret; ++ } ++ ++ /* returning NULL can be an option if in stereo mode */ ++ cs35l41->reset_gpio = devm_gpiod_get_optional(cs35l41->dev, "reset", ++ GPIOD_OUT_LOW); ++ if (IS_ERR(cs35l41->reset_gpio)) { ++ ret = PTR_ERR(cs35l41->reset_gpio); ++ cs35l41->reset_gpio = NULL; ++ if (ret == -EBUSY) { ++ dev_info(cs35l41->dev, ++ "Reset line busy, assuming shared reset\n"); ++ } else { ++ dev_err(cs35l41->dev, ++ "Failed to get reset GPIO: %d\n", ret); ++ goto err; ++ } ++ } ++ if (cs35l41->reset_gpio) { ++ /* satisfy minimum reset pulse width spec */ ++ usleep_range(2000, 2100); ++ gpiod_set_value_cansleep(cs35l41->reset_gpio, 1); ++ } ++ ++ usleep_range(2000, 2100); ++ ++ timeout = 100; ++ do { ++ if (timeout == 0) { ++ dev_err(cs35l41->dev, ++ "Timeout waiting for OTP_BOOT_DONE\n"); ++ ret = -EBUSY; ++ goto err; ++ } ++ usleep_range(1000, 1100); ++ regmap_read(cs35l41->regmap, CS35L41_IRQ1_STATUS4, &int_status); ++ timeout--; ++ } while (!(int_status & CS35L41_OTP_BOOT_DONE)); ++ ++ regmap_read(cs35l41->regmap, CS35L41_IRQ1_STATUS3, &int_status); ++ if (int_status & CS35L41_OTP_BOOT_ERR) { ++ dev_err(cs35l41->dev, "OTP Boot error\n"); ++ ret = -EINVAL; ++ goto err; ++ } ++ ++ ret = regmap_read(cs35l41->regmap, CS35L41_DEVID, ®id); ++ if (ret < 0) { ++ dev_err(cs35l41->dev, "Get Device ID failed\n"); ++ goto err; ++ } ++ ++ ret = regmap_read(cs35l41->regmap, CS35L41_REVID, ®_revid); ++ if (ret < 0) { ++ dev_err(cs35l41->dev, "Get Revision ID failed\n"); ++ goto err; ++ } ++ ++ mtl_revid = reg_revid & CS35L41_MTLREVID_MASK; ++ ++ /* CS35L41 will have even MTLREVID ++ * CS35L41R will have odd MTLREVID ++ */ ++ chipid_match = (mtl_revid % 2) ? CS35L41R_CHIP_ID : CS35L41_CHIP_ID; ++ if (regid != chipid_match) { ++ dev_err(cs35l41->dev, "CS35L41 Device ID (%X). Expected ID %X\n", ++ regid, chipid_match); ++ ret = -ENODEV; ++ goto err; ++ } ++ ++ switch (reg_revid) { ++ case CS35L41_REVID_A0: ++ ret = regmap_register_patch(cs35l41->regmap, ++ cs35l41_reva0_errata_patch, ++ ARRAY_SIZE(cs35l41_reva0_errata_patch)); ++ if (ret < 0) { ++ dev_err(cs35l41->dev, ++ "Failed to apply A0 errata patch %d\n", ret); ++ goto err; ++ } ++ break; ++ case CS35L41_REVID_B0: ++ ret = regmap_register_patch(cs35l41->regmap, ++ cs35l41_revb0_errata_patch, ++ ARRAY_SIZE(cs35l41_revb0_errata_patch)); ++ if (ret < 0) { ++ dev_err(cs35l41->dev, ++ "Failed to apply B0 errata patch %d\n", ret); ++ goto err; ++ } ++ break; ++ case CS35L41_REVID_B2: ++ ret = regmap_register_patch(cs35l41->regmap, ++ cs35l41_revb2_errata_patch, ++ ARRAY_SIZE(cs35l41_revb2_errata_patch)); ++ if (ret < 0) { ++ dev_err(cs35l41->dev, ++ "Failed to apply B2 errata patch %d\n", ret); ++ goto err; ++ } ++ break; ++ } ++ ++ irq_pol = cs35l41_irq_gpio_config(cs35l41); ++ ++ /* Set interrupt masks for critical errors */ ++ regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, ++ CS35L41_INT1_MASK_DEFAULT); ++ ++ ret = devm_request_threaded_irq(cs35l41->dev, cs35l41->irq, NULL, ++ cs35l41_irq, IRQF_ONESHOT | IRQF_SHARED | irq_pol, ++ "cs35l41", cs35l41); ++ ++ /* CS35L41 needs INT for PDN_DONE */ ++ if (ret != 0) { ++ dev_err(cs35l41->dev, "Failed to request IRQ: %d\n", ret); ++ ret = -ENODEV; ++ goto err; ++ } ++ ++ ret = cs35l41_otp_unpack(cs35l41); ++ if (ret < 0) { ++ dev_err(cs35l41->dev, "OTP Unpack failed\n"); ++ goto err; ++ } ++ ++ ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_CCM_CORE_CTRL, 0); ++ if (ret < 0) { ++ dev_err(cs35l41->dev, "Write CCM_CORE_CTRL failed\n"); ++ goto err; ++ } ++ ++ ret = regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, ++ CS35L41_AMP_EN_MASK, 0); ++ if (ret < 0) { ++ dev_err(cs35l41->dev, "Write CS35L41_PWR_CTRL2 failed\n"); ++ goto err; ++ } ++ ++ ret = regmap_update_bits(cs35l41->regmap, CS35L41_AMP_GAIN_CTRL, ++ CS35L41_AMP_GAIN_PCM_MASK, 0); ++ if (ret < 0) { ++ dev_err(cs35l41->dev, "Write CS35L41_AMP_GAIN_CTRL failed\n"); ++ goto err; ++ } ++ ++ ret = cs35l41_set_pdata(cs35l41); ++ if (ret < 0) { ++ dev_err(cs35l41->dev, "%s: Set pdata failed\n", __func__); ++ goto err; ++ } ++ ++ ret = devm_snd_soc_register_component(cs35l41->dev, ++ &soc_component_dev_cs35l41, ++ cs35l41_dai, ARRAY_SIZE(cs35l41_dai)); ++ if (ret < 0) { ++ dev_err(cs35l41->dev, "%s: Register codec failed\n", __func__); ++ goto err; ++ } ++ ++ dev_info(cs35l41->dev, "Cirrus Logic CS35L41 (%x), Revision: %02X\n", ++ regid, reg_revid); ++ ++ return 0; ++ ++err: ++ regulator_bulk_disable(CS35L41_NUM_SUPPLIES, cs35l41->supplies); ++ gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); ++ return ret; ++} ++ ++int cs35l41_remove(struct cs35l41_private *cs35l41) ++{ ++ regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, 0xFFFFFFFF); ++ regulator_bulk_disable(CS35L41_NUM_SUPPLIES, cs35l41->supplies); ++ gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); ++ return 0; ++} ++ ++MODULE_DESCRIPTION("ASoC CS35L41 driver"); ++MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, "); ++MODULE_LICENSE("GPL"); +diff --git a/sound/soc/codecs/cs35l41.h b/sound/soc/codecs/cs35l41.h +new file mode 100644 +index 000000000000..7a25430182f8 +--- /dev/null ++++ b/sound/soc/codecs/cs35l41.h +@@ -0,0 +1,775 @@ ++/* SPDX-License-Identifier: GPL-2.0 ++ * ++ * cs35l41.h -- CS35L41 ALSA SoC audio driver ++ * ++ * Copyright 2017-2021 Cirrus Logic, Inc. ++ * ++ * Author: David Rhodes ++ */ ++ ++#ifndef __CS35L41_H__ ++#define __CS35L41_H__ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define CS35L41_FIRSTREG 0x00000000 ++#define CS35L41_LASTREG 0x03804FE8 ++#define CS35L41_DEVID 0x00000000 ++#define CS35L41_REVID 0x00000004 ++#define CS35L41_FABID 0x00000008 ++#define CS35L41_RELID 0x0000000C ++#define CS35L41_OTPID 0x00000010 ++#define CS35L41_SFT_RESET 0x00000020 ++#define CS35L41_TEST_KEY_CTL 0x00000040 ++#define CS35L41_USER_KEY_CTL 0x00000044 ++#define CS35L41_OTP_MEM0 0x00000400 ++#define CS35L41_OTP_MEM31 0x0000047C ++#define CS35L41_OTP_CTRL0 0x00000500 ++#define CS35L41_OTP_CTRL1 0x00000504 ++#define CS35L41_OTP_CTRL3 0x00000508 ++#define CS35L41_OTP_CTRL4 0x0000050C ++#define CS35L41_OTP_CTRL5 0x00000510 ++#define CS35L41_OTP_CTRL6 0x00000514 ++#define CS35L41_OTP_CTRL7 0x00000518 ++#define CS35L41_OTP_CTRL8 0x0000051C ++#define CS35L41_PWR_CTRL1 0x00002014 ++#define CS35L41_PWR_CTRL2 0x00002018 ++#define CS35L41_PWR_CTRL3 0x0000201C ++#define CS35L41_CTRL_OVRRIDE 0x00002020 ++#define CS35L41_AMP_OUT_MUTE 0x00002024 ++#define CS35L41_PROTECT_REL_ERR_IGN 0x00002034 ++#define CS35L41_GPIO_PAD_CONTROL 0x0000242C ++#define CS35L41_JTAG_CONTROL 0x00002438 ++#define CS35L41_PLL_CLK_CTRL 0x00002C04 ++#define CS35L41_DSP_CLK_CTRL 0x00002C08 ++#define CS35L41_GLOBAL_CLK_CTRL 0x00002C0C ++#define CS35L41_DATA_FS_SEL 0x00002C10 ++#define CS35L41_TST_FS_MON0 0x00002D10 ++#define CS35L41_MDSYNC_EN 0x00003400 ++#define CS35L41_MDSYNC_TX_ID 0x00003408 ++#define CS35L41_MDSYNC_PWR_CTRL 0x0000340C ++#define CS35L41_MDSYNC_DATA_TX 0x00003410 ++#define CS35L41_MDSYNC_TX_STATUS 0x00003414 ++#define CS35L41_MDSYNC_DATA_RX 0x0000341C ++#define CS35L41_MDSYNC_RX_STATUS 0x00003420 ++#define CS35L41_MDSYNC_ERR_STATUS 0x00003424 ++#define CS35L41_MDSYNC_SYNC_PTE2 0x00003528 ++#define CS35L41_MDSYNC_SYNC_PTE3 0x0000352C ++#define CS35L41_MDSYNC_SYNC_MSM_STATUS 0x0000353C ++#define CS35L41_BSTCVRT_VCTRL1 0x00003800 ++#define CS35L41_BSTCVRT_VCTRL2 0x00003804 ++#define CS35L41_BSTCVRT_PEAK_CUR 0x00003808 ++#define CS35L41_BSTCVRT_SFT_RAMP 0x0000380C ++#define CS35L41_BSTCVRT_COEFF 0x00003810 ++#define CS35L41_BSTCVRT_SLOPE_LBST 0x00003814 ++#define CS35L41_BSTCVRT_SW_FREQ 0x00003818 ++#define CS35L41_BSTCVRT_DCM_CTRL 0x0000381C ++#define CS35L41_BSTCVRT_DCM_MODE_FORCE 0x00003820 ++#define CS35L41_BSTCVRT_OVERVOLT_CTRL 0x00003830 ++#define CS35L41_VI_VOL_POL 0x00004000 ++#define CS35L41_VIMON_SPKMON_RESYNC 0x00004100 ++#define CS35L41_DTEMP_WARN_THLD 0x00004220 ++#define CS35L41_DTEMP_CFG 0x00004224 ++#define CS35L41_DTEMP_EN 0x00004308 ++#define CS35L41_VPVBST_FS_SEL 0x00004400 ++#define CS35L41_SP_ENABLES 0x00004800 ++#define CS35L41_SP_RATE_CTRL 0x00004804 ++#define CS35L41_SP_FORMAT 0x00004808 ++#define CS35L41_SP_HIZ_CTRL 0x0000480C ++#define CS35L41_SP_FRAME_TX_SLOT 0x00004810 ++#define CS35L41_SP_FRAME_RX_SLOT 0x00004820 ++#define CS35L41_SP_TX_WL 0x00004830 ++#define CS35L41_SP_RX_WL 0x00004840 ++#define CS35L41_ASP_CONTROL4 0x00004854 ++#define CS35L41_DAC_PCM1_SRC 0x00004C00 ++#define CS35L41_ASP_TX1_SRC 0x00004C20 ++#define CS35L41_ASP_TX2_SRC 0x00004C24 ++#define CS35L41_ASP_TX3_SRC 0x00004C28 ++#define CS35L41_ASP_TX4_SRC 0x00004C2C ++#define CS35L41_DSP1_RX1_SRC 0x00004C40 ++#define CS35L41_DSP1_RX2_SRC 0x00004C44 ++#define CS35L41_DSP1_RX3_SRC 0x00004C48 ++#define CS35L41_DSP1_RX4_SRC 0x00004C4C ++#define CS35L41_DSP1_RX5_SRC 0x00004C50 ++#define CS35L41_DSP1_RX6_SRC 0x00004C54 ++#define CS35L41_DSP1_RX7_SRC 0x00004C58 ++#define CS35L41_DSP1_RX8_SRC 0x00004C5C ++#define CS35L41_NGATE1_SRC 0x00004C60 ++#define CS35L41_NGATE2_SRC 0x00004C64 ++#define CS35L41_AMP_DIG_VOL_CTRL 0x00006000 ++#define CS35L41_VPBR_CFG 0x00006404 ++#define CS35L41_VBBR_CFG 0x00006408 ++#define CS35L41_VPBR_STATUS 0x0000640C ++#define CS35L41_VBBR_STATUS 0x00006410 ++#define CS35L41_OVERTEMP_CFG 0x00006414 ++#define CS35L41_AMP_ERR_VOL 0x00006418 ++#define CS35L41_VOL_STATUS_TO_DSP 0x00006450 ++#define CS35L41_CLASSH_CFG 0x00006800 ++#define CS35L41_WKFET_CFG 0x00006804 ++#define CS35L41_NG_CFG 0x00006808 ++#define CS35L41_AMP_GAIN_CTRL 0x00006C04 ++#define CS35L41_DAC_MSM_CFG 0x00007400 ++#define CS35L41_IRQ1_CFG 0x00010000 ++#define CS35L41_IRQ1_STATUS 0x00010004 ++#define CS35L41_IRQ1_STATUS1 0x00010010 ++#define CS35L41_IRQ1_STATUS2 0x00010014 ++#define CS35L41_IRQ1_STATUS3 0x00010018 ++#define CS35L41_IRQ1_STATUS4 0x0001001C ++#define CS35L41_IRQ1_RAW_STATUS1 0x00010090 ++#define CS35L41_IRQ1_RAW_STATUS2 0x00010094 ++#define CS35L41_IRQ1_RAW_STATUS3 0x00010098 ++#define CS35L41_IRQ1_RAW_STATUS4 0x0001009C ++#define CS35L41_IRQ1_MASK1 0x00010110 ++#define CS35L41_IRQ1_MASK2 0x00010114 ++#define CS35L41_IRQ1_MASK3 0x00010118 ++#define CS35L41_IRQ1_MASK4 0x0001011C ++#define CS35L41_IRQ1_FRC1 0x00010190 ++#define CS35L41_IRQ1_FRC2 0x00010194 ++#define CS35L41_IRQ1_FRC3 0x00010198 ++#define CS35L41_IRQ1_FRC4 0x0001019C ++#define CS35L41_IRQ1_EDGE1 0x00010210 ++#define CS35L41_IRQ1_EDGE4 0x0001021C ++#define CS35L41_IRQ1_POL1 0x00010290 ++#define CS35L41_IRQ1_POL2 0x00010294 ++#define CS35L41_IRQ1_POL3 0x00010298 ++#define CS35L41_IRQ1_POL4 0x0001029C ++#define CS35L41_IRQ1_DB3 0x00010318 ++#define CS35L41_IRQ2_CFG 0x00010800 ++#define CS35L41_IRQ2_STATUS 0x00010804 ++#define CS35L41_IRQ2_STATUS1 0x00010810 ++#define CS35L41_IRQ2_STATUS2 0x00010814 ++#define CS35L41_IRQ2_STATUS3 0x00010818 ++#define CS35L41_IRQ2_STATUS4 0x0001081C ++#define CS35L41_IRQ2_RAW_STATUS1 0x00010890 ++#define CS35L41_IRQ2_RAW_STATUS2 0x00010894 ++#define CS35L41_IRQ2_RAW_STATUS3 0x00010898 ++#define CS35L41_IRQ2_RAW_STATUS4 0x0001089C ++#define CS35L41_IRQ2_MASK1 0x00010910 ++#define CS35L41_IRQ2_MASK2 0x00010914 ++#define CS35L41_IRQ2_MASK3 0x00010918 ++#define CS35L41_IRQ2_MASK4 0x0001091C ++#define CS35L41_IRQ2_FRC1 0x00010990 ++#define CS35L41_IRQ2_FRC2 0x00010994 ++#define CS35L41_IRQ2_FRC3 0x00010998 ++#define CS35L41_IRQ2_FRC4 0x0001099C ++#define CS35L41_IRQ2_EDGE1 0x00010A10 ++#define CS35L41_IRQ2_EDGE4 0x00010A1C ++#define CS35L41_IRQ2_POL1 0x00010A90 ++#define CS35L41_IRQ2_POL2 0x00010A94 ++#define CS35L41_IRQ2_POL3 0x00010A98 ++#define CS35L41_IRQ2_POL4 0x00010A9C ++#define CS35L41_IRQ2_DB3 0x00010B18 ++#define CS35L41_GPIO_STATUS1 0x00011000 ++#define CS35L41_GPIO1_CTRL1 0x00011008 ++#define CS35L41_GPIO2_CTRL1 0x0001100C ++#define CS35L41_MIXER_NGATE_CFG 0x00012000 ++#define CS35L41_MIXER_NGATE_CH1_CFG 0x00012004 ++#define CS35L41_MIXER_NGATE_CH2_CFG 0x00012008 ++#define CS35L41_DSP_MBOX_1 0x00013000 ++#define CS35L41_DSP_MBOX_2 0x00013004 ++#define CS35L41_DSP_MBOX_3 0x00013008 ++#define CS35L41_DSP_MBOX_4 0x0001300C ++#define CS35L41_DSP_MBOX_5 0x00013010 ++#define CS35L41_DSP_MBOX_6 0x00013014 ++#define CS35L41_DSP_MBOX_7 0x00013018 ++#define CS35L41_DSP_MBOX_8 0x0001301C ++#define CS35L41_DSP_VIRT1_MBOX_1 0x00013020 ++#define CS35L41_DSP_VIRT1_MBOX_2 0x00013024 ++#define CS35L41_DSP_VIRT1_MBOX_3 0x00013028 ++#define CS35L41_DSP_VIRT1_MBOX_4 0x0001302C ++#define CS35L41_DSP_VIRT1_MBOX_5 0x00013030 ++#define CS35L41_DSP_VIRT1_MBOX_6 0x00013034 ++#define CS35L41_DSP_VIRT1_MBOX_7 0x00013038 ++#define CS35L41_DSP_VIRT1_MBOX_8 0x0001303C ++#define CS35L41_DSP_VIRT2_MBOX_1 0x00013040 ++#define CS35L41_DSP_VIRT2_MBOX_2 0x00013044 ++#define CS35L41_DSP_VIRT2_MBOX_3 0x00013048 ++#define CS35L41_DSP_VIRT2_MBOX_4 0x0001304C ++#define CS35L41_DSP_VIRT2_MBOX_5 0x00013050 ++#define CS35L41_DSP_VIRT2_MBOX_6 0x00013054 ++#define CS35L41_DSP_VIRT2_MBOX_7 0x00013058 ++#define CS35L41_DSP_VIRT2_MBOX_8 0x0001305C ++#define CS35L41_CLOCK_DETECT_1 0x00014000 ++#define CS35L41_TIMER1_CONTROL 0x00015000 ++#define CS35L41_TIMER1_COUNT_PRESET 0x00015004 ++#define CS35L41_TIMER1_START_STOP 0x0001500C ++#define CS35L41_TIMER1_STATUS 0x00015010 ++#define CS35L41_TIMER1_COUNT_READBACK 0x00015014 ++#define CS35L41_TIMER1_DSP_CLK_CFG 0x00015018 ++#define CS35L41_TIMER1_DSP_CLK_STATUS 0x0001501C ++#define CS35L41_TIMER2_CONTROL 0x00015100 ++#define CS35L41_TIMER2_COUNT_PRESET 0x00015104 ++#define CS35L41_TIMER2_START_STOP 0x0001510C ++#define CS35L41_TIMER2_STATUS 0x00015110 ++#define CS35L41_TIMER2_COUNT_READBACK 0x00015114 ++#define CS35L41_TIMER2_DSP_CLK_CFG 0x00015118 ++#define CS35L41_TIMER2_DSP_CLK_STATUS 0x0001511C ++#define CS35L41_DFT_JTAG_CONTROL 0x00016000 ++#define CS35L41_DIE_STS1 0x00017040 ++#define CS35L41_DIE_STS2 0x00017044 ++#define CS35L41_TEMP_CAL1 0x00017048 ++#define CS35L41_TEMP_CAL2 0x0001704C ++#define CS35L41_DSP1_XMEM_PACK_0 0x02000000 ++#define CS35L41_DSP1_XMEM_PACK_3068 0x02002FF0 ++#define CS35L41_DSP1_XMEM_UNPACK32_0 0x02400000 ++#define CS35L41_DSP1_XMEM_UNPACK32_2046 0x02401FF8 ++#define CS35L41_DSP1_TIMESTAMP_COUNT 0x025C0800 ++#define CS35L41_DSP1_SYS_ID 0x025E0000 ++#define CS35L41_DSP1_SYS_VERSION 0x025E0004 ++#define CS35L41_DSP1_SYS_CORE_ID 0x025E0008 ++#define CS35L41_DSP1_SYS_AHB_ADDR 0x025E000C ++#define CS35L41_DSP1_SYS_XSRAM_SIZE 0x025E0010 ++#define CS35L41_DSP1_SYS_YSRAM_SIZE 0x025E0018 ++#define CS35L41_DSP1_SYS_PSRAM_SIZE 0x025E0020 ++#define CS35L41_DSP1_SYS_PM_BOOT_SIZE 0x025E0028 ++#define CS35L41_DSP1_SYS_FEATURES 0x025E002C ++#define CS35L41_DSP1_SYS_FIR_FILTERS 0x025E0030 ++#define CS35L41_DSP1_SYS_LMS_FILTERS 0x025E0034 ++#define CS35L41_DSP1_SYS_XM_BANK_SIZE 0x025E0038 ++#define CS35L41_DSP1_SYS_YM_BANK_SIZE 0x025E003C ++#define CS35L41_DSP1_SYS_PM_BANK_SIZE 0x025E0040 ++#define CS35L41_DSP1_AHBM_WIN0_CTRL0 0x025E2000 ++#define CS35L41_DSP1_AHBM_WIN0_CTRL1 0x025E2004 ++#define CS35L41_DSP1_AHBM_WIN1_CTRL0 0x025E2008 ++#define CS35L41_DSP1_AHBM_WIN1_CTRL1 0x025E200C ++#define CS35L41_DSP1_AHBM_WIN2_CTRL0 0x025E2010 ++#define CS35L41_DSP1_AHBM_WIN2_CTRL1 0x025E2014 ++#define CS35L41_DSP1_AHBM_WIN3_CTRL0 0x025E2018 ++#define CS35L41_DSP1_AHBM_WIN3_CTRL1 0x025E201C ++#define CS35L41_DSP1_AHBM_WIN4_CTRL0 0x025E2020 ++#define CS35L41_DSP1_AHBM_WIN4_CTRL1 0x025E2024 ++#define CS35L41_DSP1_AHBM_WIN5_CTRL0 0x025E2028 ++#define CS35L41_DSP1_AHBM_WIN5_CTRL1 0x025E202C ++#define CS35L41_DSP1_AHBM_WIN6_CTRL0 0x025E2030 ++#define CS35L41_DSP1_AHBM_WIN6_CTRL1 0x025E2034 ++#define CS35L41_DSP1_AHBM_WIN7_CTRL0 0x025E2038 ++#define CS35L41_DSP1_AHBM_WIN7_CTRL1 0x025E203C ++#define CS35L41_DSP1_AHBM_WIN_DBG_CTRL0 0x025E2040 ++#define CS35L41_DSP1_AHBM_WIN_DBG_CTRL1 0x025E2044 ++#define CS35L41_DSP1_XMEM_UNPACK24_0 0x02800000 ++#define CS35L41_DSP1_XMEM_UNPACK24_4093 0x02803FF4 ++#define CS35L41_DSP1_CTRL_BASE 0x02B80000 ++#define CS35L41_DSP1_CORE_SOFT_RESET 0x02B80010 ++#define CS35L41_DSP1_DEBUG 0x02B80040 ++#define CS35L41_DSP1_TIMER_CTRL 0x02B80048 ++#define CS35L41_DSP1_STREAM_ARB_CTRL 0x02B80050 ++#define CS35L41_DSP1_RX1_RATE 0x02B80080 ++#define CS35L41_DSP1_RX2_RATE 0x02B80088 ++#define CS35L41_DSP1_RX3_RATE 0x02B80090 ++#define CS35L41_DSP1_RX4_RATE 0x02B80098 ++#define CS35L41_DSP1_RX5_RATE 0x02B800A0 ++#define CS35L41_DSP1_RX6_RATE 0x02B800A8 ++#define CS35L41_DSP1_RX7_RATE 0x02B800B0 ++#define CS35L41_DSP1_RX8_RATE 0x02B800B8 ++#define CS35L41_DSP1_TX1_RATE 0x02B80280 ++#define CS35L41_DSP1_TX2_RATE 0x02B80288 ++#define CS35L41_DSP1_TX3_RATE 0x02B80290 ++#define CS35L41_DSP1_TX4_RATE 0x02B80298 ++#define CS35L41_DSP1_TX5_RATE 0x02B802A0 ++#define CS35L41_DSP1_TX6_RATE 0x02B802A8 ++#define CS35L41_DSP1_TX7_RATE 0x02B802B0 ++#define CS35L41_DSP1_TX8_RATE 0x02B802B8 ++#define CS35L41_DSP1_NMI_CTRL1 0x02B80480 ++#define CS35L41_DSP1_NMI_CTRL2 0x02B80488 ++#define CS35L41_DSP1_NMI_CTRL3 0x02B80490 ++#define CS35L41_DSP1_NMI_CTRL4 0x02B80498 ++#define CS35L41_DSP1_NMI_CTRL5 0x02B804A0 ++#define CS35L41_DSP1_NMI_CTRL6 0x02B804A8 ++#define CS35L41_DSP1_NMI_CTRL7 0x02B804B0 ++#define CS35L41_DSP1_NMI_CTRL8 0x02B804B8 ++#define CS35L41_DSP1_RESUME_CTRL 0x02B80500 ++#define CS35L41_DSP1_IRQ1_CTRL 0x02B80508 ++#define CS35L41_DSP1_IRQ2_CTRL 0x02B80510 ++#define CS35L41_DSP1_IRQ3_CTRL 0x02B80518 ++#define CS35L41_DSP1_IRQ4_CTRL 0x02B80520 ++#define CS35L41_DSP1_IRQ5_CTRL 0x02B80528 ++#define CS35L41_DSP1_IRQ6_CTRL 0x02B80530 ++#define CS35L41_DSP1_IRQ7_CTRL 0x02B80538 ++#define CS35L41_DSP1_IRQ8_CTRL 0x02B80540 ++#define CS35L41_DSP1_IRQ9_CTRL 0x02B80548 ++#define CS35L41_DSP1_IRQ10_CTRL 0x02B80550 ++#define CS35L41_DSP1_IRQ11_CTRL 0x02B80558 ++#define CS35L41_DSP1_IRQ12_CTRL 0x02B80560 ++#define CS35L41_DSP1_IRQ13_CTRL 0x02B80568 ++#define CS35L41_DSP1_IRQ14_CTRL 0x02B80570 ++#define CS35L41_DSP1_IRQ15_CTRL 0x02B80578 ++#define CS35L41_DSP1_IRQ16_CTRL 0x02B80580 ++#define CS35L41_DSP1_IRQ17_CTRL 0x02B80588 ++#define CS35L41_DSP1_IRQ18_CTRL 0x02B80590 ++#define CS35L41_DSP1_IRQ19_CTRL 0x02B80598 ++#define CS35L41_DSP1_IRQ20_CTRL 0x02B805A0 ++#define CS35L41_DSP1_IRQ21_CTRL 0x02B805A8 ++#define CS35L41_DSP1_IRQ22_CTRL 0x02B805B0 ++#define CS35L41_DSP1_IRQ23_CTRL 0x02B805B8 ++#define CS35L41_DSP1_SCRATCH1 0x02B805C0 ++#define CS35L41_DSP1_SCRATCH2 0x02B805C8 ++#define CS35L41_DSP1_SCRATCH3 0x02B805D0 ++#define CS35L41_DSP1_SCRATCH4 0x02B805D8 ++#define CS35L41_DSP1_CCM_CORE_CTRL 0x02BC1000 ++#define CS35L41_DSP1_CCM_CLK_OVERRIDE 0x02BC1008 ++#define CS35L41_DSP1_XM_MSTR_EN 0x02BC2000 ++#define CS35L41_DSP1_XM_CORE_PRI 0x02BC2008 ++#define CS35L41_DSP1_XM_AHB_PACK_PL_PRI 0x02BC2010 ++#define CS35L41_DSP1_XM_AHB_UP_PL_PRI 0x02BC2018 ++#define CS35L41_DSP1_XM_ACCEL_PL0_PRI 0x02BC2020 ++#define CS35L41_DSP1_XM_NPL0_PRI 0x02BC2078 ++#define CS35L41_DSP1_YM_MSTR_EN 0x02BC20C0 ++#define CS35L41_DSP1_YM_CORE_PRI 0x02BC20C8 ++#define CS35L41_DSP1_YM_AHB_PACK_PL_PRI 0x02BC20D0 ++#define CS35L41_DSP1_YM_AHB_UP_PL_PRI 0x02BC20D8 ++#define CS35L41_DSP1_YM_ACCEL_PL0_PRI 0x02BC20E0 ++#define CS35L41_DSP1_YM_NPL0_PRI 0x02BC2138 ++#define CS35L41_DSP1_PM_MSTR_EN 0x02BC2180 ++#define CS35L41_DSP1_PM_PATCH0_ADDR 0x02BC2188 ++#define CS35L41_DSP1_PM_PATCH0_EN 0x02BC218C ++#define CS35L41_DSP1_PM_PATCH0_DATA_LO 0x02BC2190 ++#define CS35L41_DSP1_PM_PATCH0_DATA_HI 0x02BC2194 ++#define CS35L41_DSP1_PM_PATCH1_ADDR 0x02BC2198 ++#define CS35L41_DSP1_PM_PATCH1_EN 0x02BC219C ++#define CS35L41_DSP1_PM_PATCH1_DATA_LO 0x02BC21A0 ++#define CS35L41_DSP1_PM_PATCH1_DATA_HI 0x02BC21A4 ++#define CS35L41_DSP1_PM_PATCH2_ADDR 0x02BC21A8 ++#define CS35L41_DSP1_PM_PATCH2_EN 0x02BC21AC ++#define CS35L41_DSP1_PM_PATCH2_DATA_LO 0x02BC21B0 ++#define CS35L41_DSP1_PM_PATCH2_DATA_HI 0x02BC21B4 ++#define CS35L41_DSP1_PM_PATCH3_ADDR 0x02BC21B8 ++#define CS35L41_DSP1_PM_PATCH3_EN 0x02BC21BC ++#define CS35L41_DSP1_PM_PATCH3_DATA_LO 0x02BC21C0 ++#define CS35L41_DSP1_PM_PATCH3_DATA_HI 0x02BC21C4 ++#define CS35L41_DSP1_PM_PATCH4_ADDR 0x02BC21C8 ++#define CS35L41_DSP1_PM_PATCH4_EN 0x02BC21CC ++#define CS35L41_DSP1_PM_PATCH4_DATA_LO 0x02BC21D0 ++#define CS35L41_DSP1_PM_PATCH4_DATA_HI 0x02BC21D4 ++#define CS35L41_DSP1_PM_PATCH5_ADDR 0x02BC21D8 ++#define CS35L41_DSP1_PM_PATCH5_EN 0x02BC21DC ++#define CS35L41_DSP1_PM_PATCH5_DATA_LO 0x02BC21E0 ++#define CS35L41_DSP1_PM_PATCH5_DATA_HI 0x02BC21E4 ++#define CS35L41_DSP1_PM_PATCH6_ADDR 0x02BC21E8 ++#define CS35L41_DSP1_PM_PATCH6_EN 0x02BC21EC ++#define CS35L41_DSP1_PM_PATCH6_DATA_LO 0x02BC21F0 ++#define CS35L41_DSP1_PM_PATCH6_DATA_HI 0x02BC21F4 ++#define CS35L41_DSP1_PM_PATCH7_ADDR 0x02BC21F8 ++#define CS35L41_DSP1_PM_PATCH7_EN 0x02BC21FC ++#define CS35L41_DSP1_PM_PATCH7_DATA_LO 0x02BC2200 ++#define CS35L41_DSP1_PM_PATCH7_DATA_HI 0x02BC2204 ++#define CS35L41_DSP1_MPU_XM_ACCESS0 0x02BC3000 ++#define CS35L41_DSP1_MPU_YM_ACCESS0 0x02BC3004 ++#define CS35L41_DSP1_MPU_WNDW_ACCESS0 0x02BC3008 ++#define CS35L41_DSP1_MPU_XREG_ACCESS0 0x02BC300C ++#define CS35L41_DSP1_MPU_YREG_ACCESS0 0x02BC3014 ++#define CS35L41_DSP1_MPU_XM_ACCESS1 0x02BC3018 ++#define CS35L41_DSP1_MPU_YM_ACCESS1 0x02BC301C ++#define CS35L41_DSP1_MPU_WNDW_ACCESS1 0x02BC3020 ++#define CS35L41_DSP1_MPU_XREG_ACCESS1 0x02BC3024 ++#define CS35L41_DSP1_MPU_YREG_ACCESS1 0x02BC302C ++#define CS35L41_DSP1_MPU_XM_ACCESS2 0x02BC3030 ++#define CS35L41_DSP1_MPU_YM_ACCESS2 0x02BC3034 ++#define CS35L41_DSP1_MPU_WNDW_ACCESS2 0x02BC3038 ++#define CS35L41_DSP1_MPU_XREG_ACCESS2 0x02BC303C ++#define CS35L41_DSP1_MPU_YREG_ACCESS2 0x02BC3044 ++#define CS35L41_DSP1_MPU_XM_ACCESS3 0x02BC3048 ++#define CS35L41_DSP1_MPU_YM_ACCESS3 0x02BC304C ++#define CS35L41_DSP1_MPU_WNDW_ACCESS3 0x02BC3050 ++#define CS35L41_DSP1_MPU_XREG_ACCESS3 0x02BC3054 ++#define CS35L41_DSP1_MPU_YREG_ACCESS3 0x02BC305C ++#define CS35L41_DSP1_MPU_XM_VIO_ADDR 0x02BC3100 ++#define CS35L41_DSP1_MPU_XM_VIO_STATUS 0x02BC3104 ++#define CS35L41_DSP1_MPU_YM_VIO_ADDR 0x02BC3108 ++#define CS35L41_DSP1_MPU_YM_VIO_STATUS 0x02BC310C ++#define CS35L41_DSP1_MPU_PM_VIO_ADDR 0x02BC3110 ++#define CS35L41_DSP1_MPU_PM_VIO_STATUS 0x02BC3114 ++#define CS35L41_DSP1_MPU_LOCK_CONFIG 0x02BC3140 ++#define CS35L41_DSP1_MPU_WDT_RST_CTRL 0x02BC3180 ++#define CS35L41_DSP1_STRMARB_MSTR0_CFG0 0x02BC5000 ++#define CS35L41_DSP1_STRMARB_MSTR0_CFG1 0x02BC5004 ++#define CS35L41_DSP1_STRMARB_MSTR0_CFG2 0x02BC5008 ++#define CS35L41_DSP1_STRMARB_MSTR1_CFG0 0x02BC5010 ++#define CS35L41_DSP1_STRMARB_MSTR1_CFG1 0x02BC5014 ++#define CS35L41_DSP1_STRMARB_MSTR1_CFG2 0x02BC5018 ++#define CS35L41_DSP1_STRMARB_MSTR2_CFG0 0x02BC5020 ++#define CS35L41_DSP1_STRMARB_MSTR2_CFG1 0x02BC5024 ++#define CS35L41_DSP1_STRMARB_MSTR2_CFG2 0x02BC5028 ++#define CS35L41_DSP1_STRMARB_MSTR3_CFG0 0x02BC5030 ++#define CS35L41_DSP1_STRMARB_MSTR3_CFG1 0x02BC5034 ++#define CS35L41_DSP1_STRMARB_MSTR3_CFG2 0x02BC5038 ++#define CS35L41_DSP1_STRMARB_MSTR4_CFG0 0x02BC5040 ++#define CS35L41_DSP1_STRMARB_MSTR4_CFG1 0x02BC5044 ++#define CS35L41_DSP1_STRMARB_MSTR4_CFG2 0x02BC5048 ++#define CS35L41_DSP1_STRMARB_MSTR5_CFG0 0x02BC5050 ++#define CS35L41_DSP1_STRMARB_MSTR5_CFG1 0x02BC5054 ++#define CS35L41_DSP1_STRMARB_MSTR5_CFG2 0x02BC5058 ++#define CS35L41_DSP1_STRMARB_MSTR6_CFG0 0x02BC5060 ++#define CS35L41_DSP1_STRMARB_MSTR6_CFG1 0x02BC5064 ++#define CS35L41_DSP1_STRMARB_MSTR6_CFG2 0x02BC5068 ++#define CS35L41_DSP1_STRMARB_MSTR7_CFG0 0x02BC5070 ++#define CS35L41_DSP1_STRMARB_MSTR7_CFG1 0x02BC5074 ++#define CS35L41_DSP1_STRMARB_MSTR7_CFG2 0x02BC5078 ++#define CS35L41_DSP1_STRMARB_TX0_CFG0 0x02BC5200 ++#define CS35L41_DSP1_STRMARB_TX0_CFG1 0x02BC5204 ++#define CS35L41_DSP1_STRMARB_TX1_CFG0 0x02BC5208 ++#define CS35L41_DSP1_STRMARB_TX1_CFG1 0x02BC520C ++#define CS35L41_DSP1_STRMARB_TX2_CFG0 0x02BC5210 ++#define CS35L41_DSP1_STRMARB_TX2_CFG1 0x02BC5214 ++#define CS35L41_DSP1_STRMARB_TX3_CFG0 0x02BC5218 ++#define CS35L41_DSP1_STRMARB_TX3_CFG1 0x02BC521C ++#define CS35L41_DSP1_STRMARB_TX4_CFG0 0x02BC5220 ++#define CS35L41_DSP1_STRMARB_TX4_CFG1 0x02BC5224 ++#define CS35L41_DSP1_STRMARB_TX5_CFG0 0x02BC5228 ++#define CS35L41_DSP1_STRMARB_TX5_CFG1 0x02BC522C ++#define CS35L41_DSP1_STRMARB_TX6_CFG0 0x02BC5230 ++#define CS35L41_DSP1_STRMARB_TX6_CFG1 0x02BC5234 ++#define CS35L41_DSP1_STRMARB_TX7_CFG0 0x02BC5238 ++#define CS35L41_DSP1_STRMARB_TX7_CFG1 0x02BC523C ++#define CS35L41_DSP1_STRMARB_RX0_CFG0 0x02BC5400 ++#define CS35L41_DSP1_STRMARB_RX0_CFG1 0x02BC5404 ++#define CS35L41_DSP1_STRMARB_RX1_CFG0 0x02BC5408 ++#define CS35L41_DSP1_STRMARB_RX1_CFG1 0x02BC540C ++#define CS35L41_DSP1_STRMARB_RX2_CFG0 0x02BC5410 ++#define CS35L41_DSP1_STRMARB_RX2_CFG1 0x02BC5414 ++#define CS35L41_DSP1_STRMARB_RX3_CFG0 0x02BC5418 ++#define CS35L41_DSP1_STRMARB_RX3_CFG1 0x02BC541C ++#define CS35L41_DSP1_STRMARB_RX4_CFG0 0x02BC5420 ++#define CS35L41_DSP1_STRMARB_RX4_CFG1 0x02BC5424 ++#define CS35L41_DSP1_STRMARB_RX5_CFG0 0x02BC5428 ++#define CS35L41_DSP1_STRMARB_RX5_CFG1 0x02BC542C ++#define CS35L41_DSP1_STRMARB_RX6_CFG0 0x02BC5430 ++#define CS35L41_DSP1_STRMARB_RX6_CFG1 0x02BC5434 ++#define CS35L41_DSP1_STRMARB_RX7_CFG0 0x02BC5438 ++#define CS35L41_DSP1_STRMARB_RX7_CFG1 0x02BC543C ++#define CS35L41_DSP1_STRMARB_IRQ0_CFG0 0x02BC5600 ++#define CS35L41_DSP1_STRMARB_IRQ0_CFG1 0x02BC5604 ++#define CS35L41_DSP1_STRMARB_IRQ0_CFG2 0x02BC5608 ++#define CS35L41_DSP1_STRMARB_IRQ1_CFG0 0x02BC5610 ++#define CS35L41_DSP1_STRMARB_IRQ1_CFG1 0x02BC5614 ++#define CS35L41_DSP1_STRMARB_IRQ1_CFG2 0x02BC5618 ++#define CS35L41_DSP1_STRMARB_IRQ2_CFG0 0x02BC5620 ++#define CS35L41_DSP1_STRMARB_IRQ2_CFG1 0x02BC5624 ++#define CS35L41_DSP1_STRMARB_IRQ2_CFG2 0x02BC5628 ++#define CS35L41_DSP1_STRMARB_IRQ3_CFG0 0x02BC5630 ++#define CS35L41_DSP1_STRMARB_IRQ3_CFG1 0x02BC5634 ++#define CS35L41_DSP1_STRMARB_IRQ3_CFG2 0x02BC5638 ++#define CS35L41_DSP1_STRMARB_IRQ4_CFG0 0x02BC5640 ++#define CS35L41_DSP1_STRMARB_IRQ4_CFG1 0x02BC5644 ++#define CS35L41_DSP1_STRMARB_IRQ4_CFG2 0x02BC5648 ++#define CS35L41_DSP1_STRMARB_IRQ5_CFG0 0x02BC5650 ++#define CS35L41_DSP1_STRMARB_IRQ5_CFG1 0x02BC5654 ++#define CS35L41_DSP1_STRMARB_IRQ5_CFG2 0x02BC5658 ++#define CS35L41_DSP1_STRMARB_IRQ6_CFG0 0x02BC5660 ++#define CS35L41_DSP1_STRMARB_IRQ6_CFG1 0x02BC5664 ++#define CS35L41_DSP1_STRMARB_IRQ6_CFG2 0x02BC5668 ++#define CS35L41_DSP1_STRMARB_IRQ7_CFG0 0x02BC5670 ++#define CS35L41_DSP1_STRMARB_IRQ7_CFG1 0x02BC5674 ++#define CS35L41_DSP1_STRMARB_IRQ7_CFG2 0x02BC5678 ++#define CS35L41_DSP1_STRMARB_RESYNC_MSK 0x02BC5A00 ++#define CS35L41_DSP1_STRMARB_ERR_STATUS 0x02BC5A08 ++#define CS35L41_DSP1_INTPCTL_RES_STATIC 0x02BC6000 ++#define CS35L41_DSP1_INTPCTL_RES_DYN 0x02BC6004 ++#define CS35L41_DSP1_INTPCTL_NMI_CTRL 0x02BC6008 ++#define CS35L41_DSP1_INTPCTL_IRQ_INV 0x02BC6010 ++#define CS35L41_DSP1_INTPCTL_IRQ_MODE 0x02BC6014 ++#define CS35L41_DSP1_INTPCTL_IRQ_EN 0x02BC6018 ++#define CS35L41_DSP1_INTPCTL_IRQ_MSK 0x02BC601C ++#define CS35L41_DSP1_INTPCTL_IRQ_FLUSH 0x02BC6020 ++#define CS35L41_DSP1_INTPCTL_IRQ_MSKCLR 0x02BC6024 ++#define CS35L41_DSP1_INTPCTL_IRQ_FRC 0x02BC6028 ++#define CS35L41_DSP1_INTPCTL_IRQ_MSKSET 0x02BC602C ++#define CS35L41_DSP1_INTPCTL_IRQ_ERR 0x02BC6030 ++#define CS35L41_DSP1_INTPCTL_IRQ_PEND 0x02BC6034 ++#define CS35L41_DSP1_INTPCTL_IRQ_GEN 0x02BC6038 ++#define CS35L41_DSP1_INTPCTL_TESTBITS 0x02BC6040 ++#define CS35L41_DSP1_WDT_CONTROL 0x02BC7000 ++#define CS35L41_DSP1_WDT_STATUS 0x02BC7008 ++#define CS35L41_DSP1_YMEM_PACK_0 0x02C00000 ++#define CS35L41_DSP1_YMEM_PACK_1532 0x02C017F0 ++#define CS35L41_DSP1_YMEM_UNPACK32_0 0x03000000 ++#define CS35L41_DSP1_YMEM_UNPACK32_1022 0x03000FF8 ++#define CS35L41_DSP1_YMEM_UNPACK24_0 0x03400000 ++#define CS35L41_DSP1_YMEM_UNPACK24_2045 0x03401FF4 ++#define CS35L41_DSP1_PMEM_0 0x03800000 ++#define CS35L41_DSP1_PMEM_5114 0x03804FE8 ++ ++/*test regs for emulation bringup*/ ++#define CS35L41_PLL_OVR 0x00003018 ++#define CS35L41_BST_TEST_DUTY 0x00003900 ++#define CS35L41_DIGPWM_IOCTRL 0x0000706C ++ ++/*registers populated by OTP*/ ++#define CS35L41_OTP_TRIM_1 0x0000208c ++#define CS35L41_OTP_TRIM_2 0x00002090 ++#define CS35L41_OTP_TRIM_3 0x00003010 ++#define CS35L41_OTP_TRIM_4 0x0000300C ++#define CS35L41_OTP_TRIM_5 0x0000394C ++#define CS35L41_OTP_TRIM_6 0x00003950 ++#define CS35L41_OTP_TRIM_7 0x00003954 ++#define CS35L41_OTP_TRIM_8 0x00003958 ++#define CS35L41_OTP_TRIM_9 0x0000395C ++#define CS35L41_OTP_TRIM_10 0x0000416C ++#define CS35L41_OTP_TRIM_11 0x00004160 ++#define CS35L41_OTP_TRIM_12 0x00004170 ++#define CS35L41_OTP_TRIM_13 0x00004360 ++#define CS35L41_OTP_TRIM_14 0x00004448 ++#define CS35L41_OTP_TRIM_15 0x0000444C ++#define CS35L41_OTP_TRIM_16 0x00006E30 ++#define CS35L41_OTP_TRIM_17 0x00006E34 ++#define CS35L41_OTP_TRIM_18 0x00006E38 ++#define CS35L41_OTP_TRIM_19 0x00006E3C ++#define CS35L41_OTP_TRIM_20 0x00006E40 ++#define CS35L41_OTP_TRIM_21 0x00006E44 ++#define CS35L41_OTP_TRIM_22 0x00006E48 ++#define CS35L41_OTP_TRIM_23 0x00006E4C ++#define CS35L41_OTP_TRIM_24 0x00006E50 ++#define CS35L41_OTP_TRIM_25 0x00006E54 ++#define CS35L41_OTP_TRIM_26 0x00006E58 ++#define CS35L41_OTP_TRIM_27 0x00006E5C ++#define CS35L41_OTP_TRIM_28 0x00006E60 ++#define CS35L41_OTP_TRIM_29 0x00006E64 ++#define CS35L41_OTP_TRIM_30 0x00007418 ++#define CS35L41_OTP_TRIM_31 0x0000741C ++#define CS35L41_OTP_TRIM_32 0x00007434 ++#define CS35L41_OTP_TRIM_33 0x00007068 ++#define CS35L41_OTP_TRIM_34 0x0000410C ++#define CS35L41_OTP_TRIM_35 0x0000400C ++#define CS35L41_OTP_TRIM_36 0x00002030 ++ ++#define CS35L41_MAX_CACHE_REG 36 ++#define CS35L41_OTP_SIZE_WORDS 32 ++#define CS35L41_NUM_OTP_ELEM 100 ++#define CS35L41_NUM_OTP_MAPS 5 ++ ++#define CS35L41_VALID_PDATA 0x80000000 ++#define CS35L41_NUM_SUPPLIES 2 ++ ++#define CS35L41_SCLK_MSTR_MASK 0x10 ++#define CS35L41_SCLK_MSTR_SHIFT 4 ++#define CS35L41_LRCLK_MSTR_MASK 0x01 ++#define CS35L41_LRCLK_MSTR_SHIFT 0 ++#define CS35L41_SCLK_INV_MASK 0x40 ++#define CS35L41_SCLK_INV_SHIFT 6 ++#define CS35L41_LRCLK_INV_MASK 0x04 ++#define CS35L41_LRCLK_INV_SHIFT 2 ++#define CS35L41_SCLK_FRC_MASK 0x20 ++#define CS35L41_SCLK_FRC_SHIFT 5 ++#define CS35L41_LRCLK_FRC_MASK 0x02 ++#define CS35L41_LRCLK_FRC_SHIFT 1 ++ ++#define CS35L41_AMP_GAIN_PCM_MASK 0x3E0 ++#define CS35L41_AMP_GAIN_ZC_MASK 0x0400 ++#define CS35L41_AMP_GAIN_ZC_SHIFT 10 ++ ++#define CS35L41_BST_CTL_MASK 0xFF ++#define CS35L41_BST_CTL_SEL_MASK 0x03 ++#define CS35L41_BST_CTL_SEL_REG 0x00 ++#define CS35L41_BST_CTL_SEL_CLASSH 0x01 ++#define CS35L41_BST_IPK_MASK 0x7F ++#define CS35L41_BST_IPK_SHIFT 0 ++#define CS35L41_BST_LIM_MASK 0x4 ++#define CS35L41_BST_LIM_SHIFT 2 ++#define CS35L41_BST_K1_MASK 0x000000FF ++#define CS35L41_BST_K1_SHIFT 0 ++#define CS35L41_BST_K2_MASK 0x0000FF00 ++#define CS35L41_BST_K2_SHIFT 8 ++#define CS35L41_BST_SLOPE_MASK 0x0000FF00 ++#define CS35L41_BST_SLOPE_SHIFT 8 ++#define CS35L41_BST_LBST_VAL_MASK 0x00000003 ++#define CS35L41_BST_LBST_VAL_SHIFT 0 ++ ++#define CS35L41_TEMP_THLD_MASK 0x03 ++#define CS35L41_VMON_IMON_VOL_MASK 0x07FF07FF ++#define CS35L41_PDM_MODE_MASK 0x01 ++#define CS35L41_PDM_MODE_SHIFT 0 ++ ++#define CS35L41_CH_MEM_DEPTH_MASK 0x07 ++#define CS35L41_CH_MEM_DEPTH_SHIFT 0 ++#define CS35L41_CH_HDRM_CTL_MASK 0x007F0000 ++#define CS35L41_CH_HDRM_CTL_SHIFT 16 ++#define CS35L41_CH_REL_RATE_MASK 0xFF00 ++#define CS35L41_CH_REL_RATE_SHIFT 8 ++#define CS35L41_CH_WKFET_DLY_MASK 0x001C ++#define CS35L41_CH_WKFET_DLY_SHIFT 2 ++#define CS35L41_CH_WKFET_THLD_MASK 0x0F00 ++#define CS35L41_CH_WKFET_THLD_SHIFT 8 ++ ++#define CS35L41_HW_NG_SEL_MASK 0x3F00 ++#define CS35L41_HW_NG_SEL_SHIFT 8 ++#define CS35L41_HW_NG_DLY_MASK 0x0070 ++#define CS35L41_HW_NG_DLY_SHIFT 4 ++#define CS35L41_HW_NG_THLD_MASK 0x0007 ++#define CS35L41_HW_NG_THLD_SHIFT 0 ++ ++#define CS35L41_DSP_NG_ENABLE_MASK 0x00010000 ++#define CS35L41_DSP_NG_ENABLE_SHIFT 16 ++#define CS35L41_DSP_NG_THLD_MASK 0x7 ++#define CS35L41_DSP_NG_THLD_SHIFT 0 ++#define CS35L41_DSP_NG_DELAY_MASK 0x0F00 ++#define CS35L41_DSP_NG_DELAY_SHIFT 8 ++ ++#define CS35L41_ASP_FMT_MASK 0x0700 ++#define CS35L41_ASP_FMT_SHIFT 8 ++#define CS35L41_ASP_DOUT_HIZ_MASK 0x03 ++#define CS35L41_ASP_DOUT_HIZ_SHIFT 0 ++#define CS35L41_ASP_WIDTH_16 0x10 ++#define CS35L41_ASP_WIDTH_24 0x18 ++#define CS35L41_ASP_WIDTH_32 0x20 ++#define CS35L41_ASP_WIDTH_TX_MASK 0xFF0000 ++#define CS35L41_ASP_WIDTH_TX_SHIFT 16 ++#define CS35L41_ASP_WIDTH_RX_MASK 0xFF000000 ++#define CS35L41_ASP_WIDTH_RX_SHIFT 24 ++#define CS35L41_ASP_RX1_SLOT_MASK 0x3F ++#define CS35L41_ASP_RX1_SLOT_SHIFT 0 ++#define CS35L41_ASP_RX2_SLOT_MASK 0x3F00 ++#define CS35L41_ASP_RX2_SLOT_SHIFT 8 ++#define CS35L41_ASP_RX_WL_MASK 0x3F ++#define CS35L41_ASP_TX_WL_MASK 0x3F ++#define CS35L41_ASP_RX_WL_SHIFT 0 ++#define CS35L41_ASP_TX_WL_SHIFT 0 ++#define CS35L41_ASP_SOURCE_MASK 0x7F ++ ++#define CS35L41_INPUT_SRC_ASPRX1 0x08 ++#define CS35L41_INPUT_SRC_ASPRX2 0x09 ++#define CS35L41_INPUT_SRC_VMON 0x18 ++#define CS35L41_INPUT_SRC_IMON 0x19 ++#define CS35L41_INPUT_SRC_CLASSH 0x21 ++#define CS35L41_INPUT_SRC_VPMON 0x28 ++#define CS35L41_INPUT_SRC_VBSTMON 0x29 ++#define CS35L41_INPUT_SRC_TEMPMON 0x3A ++#define CS35L41_INPUT_SRC_RSVD 0x3B ++#define CS35L41_INPUT_DSP_TX1 0x32 ++#define CS35L41_INPUT_DSP_TX2 0x33 ++ ++#define CS35L41_PLL_CLK_SEL_MASK 0x07 ++#define CS35L41_PLL_CLK_SEL_SHIFT 0 ++#define CS35L41_PLL_CLK_EN_MASK 0x10 ++#define CS35L41_PLL_CLK_EN_SHIFT 4 ++#define CS35L41_PLL_OPENLOOP_MASK 0x0800 ++#define CS35L41_PLL_OPENLOOP_SHIFT 11 ++#define CS35L41_PLLSRC_SCLK 0 ++#define CS35L41_PLLSRC_LRCLK 1 ++#define CS35L41_PLLSRC_SELF 3 ++#define CS35L41_PLLSRC_PDMCLK 4 ++#define CS35L41_PLLSRC_MCLK 5 ++#define CS35L41_PLLSRC_SWIRE 7 ++#define CS35L41_REFCLK_FREQ_MASK 0x7E0 ++#define CS35L41_REFCLK_FREQ_SHIFT 5 ++ ++#define CS35L41_GLOBAL_FS_MASK 0x1F ++#define CS35L41_GLOBAL_FS_SHIFT 0 ++ ++#define CS35L41_GLOBAL_EN_MASK 0x01 ++#define CS35L41_GLOBAL_EN_SHIFT 0 ++#define CS35L41_BST_EN_MASK 0x0030 ++#define CS35L41_BST_EN_SHIFT 4 ++#define CS35L41_BST_EN_DEFAULT 0x2 ++#define CS35L41_AMP_EN_SHIFT 0 ++#define CS35L41_AMP_EN_MASK 1 ++ ++#define CS35L41_PDN_DONE_MASK 0x00800000 ++#define CS35L41_PDN_DONE_SHIFT 23 ++#define CS35L41_PUP_DONE_MASK 0x01000000 ++#define CS35L41_PUP_DONE_SHIFT 24 ++ ++#define CS35L36_PUP_DONE_IRQ_UNMASK 0x5F ++#define CS35L36_PUP_DONE_IRQ_MASK 0xBF ++ ++#define CS35L41_AMP_SHORT_ERR 0x80000000 ++#define CS35L41_BST_SHORT_ERR 0x0100 ++#define CS35L41_TEMP_WARN 0x8000 ++#define CS35L41_TEMP_ERR 0x00020000 ++#define CS35L41_BST_OVP_ERR 0x40 ++#define CS35L41_BST_DCM_UVP_ERR 0x80 ++#define CS35L41_OTP_BOOT_DONE 0x02 ++#define CS35L41_PLL_UNLOCK 0x10 ++#define CS35L41_OTP_BOOT_ERR 0x80000000 ++ ++#define CS35L41_AMP_SHORT_ERR_RLS 0x02 ++#define CS35L41_BST_SHORT_ERR_RLS 0x04 ++#define CS35L41_BST_OVP_ERR_RLS 0x08 ++#define CS35L41_BST_UVP_ERR_RLS 0x10 ++#define CS35L41_TEMP_WARN_ERR_RLS 0x20 ++#define CS35L41_TEMP_ERR_RLS 0x40 ++ ++ ++#define CS35L41_INT1_MASK_DEFAULT 0x7FFCFE3F ++#define CS35L41_INT1_UNMASK_PUP 0xFEFFFFFF ++#define CS35L41_INT1_UNMASK_PDN 0xFF7FFFFF ++ ++#define CS35L41_GPIO_DIR_MASK 0x80000000 ++#define CS35L41_GPIO1_CTRL_MASK 0x00030000 ++#define CS35L41_GPIO1_CTRL_SHIFT 16 ++#define CS35L41_GPIO2_CTRL_MASK 0x07000000 ++#define CS35L41_GPIO2_CTRL_SHIFT 24 ++#define CS35L41_GPIO_CTRL_OPEN_INT 2 ++#define CS35L41_GPIO_CTRL_ACTV_LO 4 ++#define CS35L41_GPIO_CTRL_ACTV_HI 5 ++#define CS35L41_GPIO_POL_MASK 0x1000 ++#define CS35L41_GPIO_POL_SHIFT 12 ++ ++#define CS35L41_AMP_INV_PCM_SHIFT 14 ++#define CS35L41_AMP_INV_PCM_MASK (1 << CS35L41_AMP_INV_PCM_SHIFT) ++#define CS35L41_AMP_PCM_VOL_SHIFT 3 ++#define CS35L41_AMP_PCM_VOL_MASK (0x7FF << 3) ++#define CS35L41_AMP_PCM_VOL_MUTE 0x4CF ++ ++#define CS35L41_CHIP_ID 0x35a40 ++#define CS35L41R_CHIP_ID 0x35b40 ++#define CS35L41_MTLREVID_MASK 0x0F ++#define CS35L41_REVID_A0 0xA0 ++#define CS35L41_REVID_B0 0xB0 ++#define CS35L41_REVID_B2 0xB2 ++ ++#define CS35L41_HALO_CORE_RESET 0x00000200 ++ ++#define CS35L41_FS1_WINDOW_MASK 0x000007FF ++#define CS35L41_FS2_WINDOW_MASK 0x00FFF800 ++#define CS35L41_FS2_WINDOW_SHIFT 12 ++ ++#define CS35L41_SPI_MAX_FREQ_OTP 4000000 ++ ++#define CS35L41_RX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) ++#define CS35L41_TX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) ++ ++bool cs35l41_readable_reg(struct device *dev, unsigned int reg); ++bool cs35l41_precious_reg(struct device *dev, unsigned int reg); ++bool cs35l41_volatile_reg(struct device *dev, unsigned int reg); ++ ++struct cs35l41_otp_packed_element_t { ++ u32 reg; ++ u8 shift; ++ u8 size; ++}; ++ ++struct cs35l41_otp_map_element_t { ++ u32 id; ++ u32 num_elements; ++ const struct cs35l41_otp_packed_element_t *map; ++ u32 bit_offset; ++ u32 word_offset; ++}; ++ ++extern const struct reg_default cs35l41_reg[CS35L41_MAX_CACHE_REG]; ++extern const struct cs35l41_otp_map_element_t ++ cs35l41_otp_map_map[CS35L41_NUM_OTP_MAPS]; ++ ++#define CS35L41_REGSTRIDE 4 ++ ++struct cs35l41_private { ++ struct snd_soc_codec *codec; ++ struct cs35l41_platform_data pdata; ++ struct device *dev; ++ struct regmap *regmap; ++ struct regulator_bulk_data supplies[CS35L41_NUM_SUPPLIES]; ++ int irq; ++ /* GPIO for /RST */ ++ struct gpio_desc *reset_gpio; ++ void (*otp_setup)(struct cs35l41_private *cs35l41, bool is_pre_setup, ++ unsigned int *freq); ++}; ++ ++int cs35l41_probe(struct cs35l41_private *cs35l41, ++ struct cs35l41_platform_data *pdata); ++int cs35l41_remove(struct cs35l41_private *cs35l41); ++ ++#endif /*__CS35L41_H__*/ +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Change-monitor-widgets-to-siggens.patch b/patches.suse/ASoC-cs35l41-Change-monitor-widgets-to-siggens.patch new file mode 100644 index 0000000..7bb490f --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Change-monitor-widgets-to-siggens.patch @@ -0,0 +1,69 @@ +From a2697972b9369c41afea8a928c30ac5b7f28d292 Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Fri, 29 Oct 2021 16:40:27 -0500 +Subject: [PATCH] ASoC: cs35l41: Change monitor widgets to siggens +Git-commit: a2697972b9369c41afea8a928c30ac5b7f28d292 +Patch-mainline: v5.16-rc3 +References: bsc#1203699 + +Currently the internal monitor sources are input widgets, which means +if the card is set to fully routed these will not enable unless connected +to something in the machine driver. However, all these are internal +monitor signals so it makes no sense to connect them to something in the +machine driver. As such switch them to siggen widgets which will have +the same behaviour except not require external linkage on a fully routed +card. + +Signed-off-by: Charles Keepax +Signed-off-by: David Rhodes +Link: https://lore.kernel.org/r/20211029214028.401284-1-drhodes@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs35l41.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index 94ed21d7676f..9d0530dde996 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -612,6 +612,12 @@ static const struct snd_soc_dapm_widget cs35l41_dapm_widgets[] = { + SND_SOC_DAPM_AIF_OUT("ASPTX3", NULL, 0, CS35L41_SP_ENABLES, 2, 0), + SND_SOC_DAPM_AIF_OUT("ASPTX4", NULL, 0, CS35L41_SP_ENABLES, 3, 0), + ++ SND_SOC_DAPM_SIGGEN("VSENSE"), ++ SND_SOC_DAPM_SIGGEN("ISENSE"), ++ SND_SOC_DAPM_SIGGEN("VP"), ++ SND_SOC_DAPM_SIGGEN("VBST"), ++ SND_SOC_DAPM_SIGGEN("TEMP"), ++ + SND_SOC_DAPM_ADC("VMON ADC", NULL, CS35L41_PWR_CTRL2, 12, 0), + SND_SOC_DAPM_ADC("IMON ADC", NULL, CS35L41_PWR_CTRL2, 13, 0), + SND_SOC_DAPM_ADC("VPMON ADC", NULL, CS35L41_PWR_CTRL2, 8, 0), +@@ -623,12 +629,6 @@ static const struct snd_soc_dapm_widget cs35l41_dapm_widgets[] = { + cs35l41_main_amp_event, + SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), + +- SND_SOC_DAPM_INPUT("VP"), +- SND_SOC_DAPM_INPUT("VBST"), +- SND_SOC_DAPM_INPUT("ISENSE"), +- SND_SOC_DAPM_INPUT("VSENSE"), +- SND_SOC_DAPM_INPUT("TEMP"), +- + SND_SOC_DAPM_MUX("ASP TX1 Source", SND_SOC_NOPM, 0, 0, &asp_tx1_mux), + SND_SOC_DAPM_MUX("ASP TX2 Source", SND_SOC_NOPM, 0, 0, &asp_tx2_mux), + SND_SOC_DAPM_MUX("ASP TX3 Source", SND_SOC_NOPM, 0, 0, &asp_tx3_mux), +@@ -674,8 +674,8 @@ static const struct snd_soc_dapm_route cs35l41_audio_map[] = { + {"VMON ADC", NULL, "VSENSE"}, + {"IMON ADC", NULL, "ISENSE"}, + {"VPMON ADC", NULL, "VP"}, +- {"TEMPMON ADC", NULL, "TEMP"}, + {"VBSTMON ADC", NULL, "VBST"}, ++ {"TEMPMON ADC", NULL, "TEMP"}, + + {"ASPRX1", NULL, "AMP Playback"}, + {"ASPRX2", NULL, "AMP Playback"}, +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Combine-adjacent-register-writes.patch b/patches.suse/ASoC-cs35l41-Combine-adjacent-register-writes.patch new file mode 100644 index 0000000..c8142fe --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Combine-adjacent-register-writes.patch @@ -0,0 +1,270 @@ +From fe1024d50477becf35128f3ef03bf3525a2cd140 Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Tue, 14 Sep 2021 15:13:46 +0100 +Subject: [PATCH] ASoC: cs35l41: Combine adjacent register writes +Git-commit: fe1024d50477becf35128f3ef03bf3525a2cd140 +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +cs35l41 is often connected over I2C which is a very slow bus, as such +timings can be greatly improved combining writes where acceptable. +Update several points where the driver does multiple register writes +when a single one would suffice. + +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20210914141349.30218-3-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs35l41.c | 146 ++++++++++++------------------------- + sound/soc/codecs/cs35l41.h | 1 + + 2 files changed, 49 insertions(+), 98 deletions(-) + +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index 8c2c695813cd..ce652a454dfc 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -712,24 +712,29 @@ static int cs35l41_set_channel_map(struct snd_soc_dai *dai, unsigned int tx_num, + { + struct cs35l41_private *cs35l41 = + snd_soc_component_get_drvdata(dai->component); ++ unsigned int val, mask; + int i; + + if (tx_num > 4 || rx_num > 2) + return -EINVAL; + ++ val = 0; ++ mask = 0; + for (i = 0; i < rx_num; i++) { +- dev_dbg(cs35l41->dev, "%s: rx slot %d position = %d\n", +- __func__, i, rx_slot[i]); +- regmap_update_bits(cs35l41->regmap, CS35L41_SP_FRAME_RX_SLOT, +- 0x3F << (i * 8), rx_slot[i] << (i * 8)); ++ dev_dbg(cs35l41->dev, "rx slot %d position = %d\n", i, rx_slot[i]); ++ val |= rx_slot[i] << (i * 8); ++ mask |= 0x3F << (i * 8); + } ++ regmap_update_bits(cs35l41->regmap, CS35L41_SP_FRAME_RX_SLOT, mask, val); + ++ val = 0; ++ mask = 0; + for (i = 0; i < tx_num; i++) { +- dev_dbg(cs35l41->dev, "%s: tx slot %d position = %d\n", +- __func__, i, tx_slot[i]); +- regmap_update_bits(cs35l41->regmap, CS35L41_SP_FRAME_TX_SLOT, +- 0x3F << (i * 8), tx_slot[i] << (i * 8)); ++ dev_dbg(cs35l41->dev, "tx slot %d position = %d\n", i, tx_slot[i]); ++ val |= tx_slot[i] << (i * 8); ++ mask |= 0x3F << (i * 8); + } ++ regmap_update_bits(cs35l41->regmap, CS35L41_SP_FRAME_TX_SLOT, mask, val); + + return 0; + } +@@ -738,14 +743,13 @@ static int cs35l41_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) + { + struct cs35l41_private *cs35l41 = + snd_soc_component_get_drvdata(codec_dai->component); +- unsigned int asp_fmt, lrclk_fmt, sclk_fmt, clock_provider; ++ unsigned int daifmt = 0; + + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBP_CFP: +- clock_provider = 1; ++ daifmt |= CS35L41_SCLK_MSTR_MASK | CS35L41_LRCLK_MSTR_MASK; + break; + case SND_SOC_DAIFMT_CBC_CFC: +- clock_provider = 0; + break; + default: + dev_warn(cs35l41->dev, +@@ -754,19 +758,11 @@ static int cs35l41_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) + return -EINVAL; + } + +- regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, +- CS35L41_SCLK_MSTR_MASK, +- clock_provider << CS35L41_SCLK_MSTR_SHIFT); +- regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, +- CS35L41_LRCLK_MSTR_MASK, +- clock_provider << CS35L41_LRCLK_MSTR_SHIFT); +- + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_A: +- asp_fmt = 0; + break; + case SND_SOC_DAIFMT_I2S: +- asp_fmt = 2; ++ daifmt |= 2 << CS35L41_ASP_FMT_SHIFT; + break; + default: + dev_warn(cs35l41->dev, +@@ -774,26 +770,17 @@ static int cs35l41_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) + return -EINVAL; + } + +- regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, +- CS35L41_ASP_FMT_MASK, +- asp_fmt << CS35L41_ASP_FMT_SHIFT); +- + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_IF: +- lrclk_fmt = 1; +- sclk_fmt = 0; ++ daifmt |= CS35L41_LRCLK_INV_MASK; + break; + case SND_SOC_DAIFMT_IB_NF: +- lrclk_fmt = 0; +- sclk_fmt = 1; ++ daifmt |= CS35L41_SCLK_INV_MASK; + break; + case SND_SOC_DAIFMT_IB_IF: +- lrclk_fmt = 1; +- sclk_fmt = 1; ++ daifmt |= CS35L41_LRCLK_INV_MASK | CS35L41_SCLK_INV_MASK; + break; + case SND_SOC_DAIFMT_NB_NF: +- lrclk_fmt = 0; +- sclk_fmt = 0; + break; + default: + dev_warn(cs35l41->dev, +@@ -801,14 +788,10 @@ static int cs35l41_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) + return -EINVAL; + } + +- regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, +- CS35L41_LRCLK_INV_MASK, +- lrclk_fmt << CS35L41_LRCLK_INV_SHIFT); +- regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, +- CS35L41_SCLK_INV_MASK, +- sclk_fmt << CS35L41_SCLK_INV_SHIFT); +- +- return 0; ++ return regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, ++ CS35L41_SCLK_MSTR_MASK | CS35L41_LRCLK_MSTR_MASK | ++ CS35L41_ASP_FMT_MASK | CS35L41_LRCLK_INV_MASK | ++ CS35L41_SCLK_INV_MASK, daifmt); + } + + struct cs35l41_global_fs_config { +@@ -1041,37 +1024,23 @@ static int cs35l41_boost_config(struct cs35l41_private *cs35l41, + } + + ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_COEFF, +- CS35L41_BST_K1_MASK, +- cs35l41_bst_k1_table[bst_lbst_val][bst_cbst_range] +- << CS35L41_BST_K1_SHIFT); +- if (ret) { +- dev_err(dev, "Failed to write boost K1 coefficient\n"); +- return ret; +- } +- +- ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_COEFF, +- CS35L41_BST_K2_MASK, +- cs35l41_bst_k2_table[bst_lbst_val][bst_cbst_range] +- << CS35L41_BST_K2_SHIFT); +- if (ret) { +- dev_err(dev, "Failed to write boost K2 coefficient\n"); +- return ret; +- } +- +- ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_SLOPE_LBST, +- CS35L41_BST_SLOPE_MASK, +- cs35l41_bst_slope_table[bst_lbst_val] +- << CS35L41_BST_SLOPE_SHIFT); ++ CS35L41_BST_K1_MASK | CS35L41_BST_K2_MASK, ++ cs35l41_bst_k1_table[bst_lbst_val][bst_cbst_range] ++ << CS35L41_BST_K1_SHIFT | ++ cs35l41_bst_k2_table[bst_lbst_val][bst_cbst_range] ++ << CS35L41_BST_K2_SHIFT); + if (ret) { +- dev_err(dev, "Failed to write boost slope coefficient\n"); ++ dev_err(dev, "Failed to write boost coefficients: %d\n", ret); + return ret; + } + + ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_SLOPE_LBST, +- CS35L41_BST_LBST_VAL_MASK, +- bst_lbst_val << CS35L41_BST_LBST_VAL_SHIFT); ++ CS35L41_BST_SLOPE_MASK | CS35L41_BST_LBST_VAL_MASK, ++ cs35l41_bst_slope_table[bst_lbst_val] ++ << CS35L41_BST_SLOPE_SHIFT | ++ bst_lbst_val << CS35L41_BST_LBST_VAL_SHIFT); + if (ret) { +- dev_err(dev, "Failed to write boost inductor value\n"); ++ dev_err(dev, "Failed to write boost slope/inductor value: %d\n", ret); + return ret; + } + +@@ -1129,39 +1098,20 @@ static int cs35l41_irq_gpio_config(struct cs35l41_private *cs35l41) + struct cs35l41_irq_cfg *irq_gpio_cfg2 = &cs35l41->pdata.irq_config2; + int irq_pol = IRQF_TRIGGER_NONE; + +- if (irq_gpio_cfg1->irq_pol_inv) +- regmap_update_bits(cs35l41->regmap, +- CS35L41_GPIO1_CTRL1, +- CS35L41_GPIO_POL_MASK, +- CS35L41_GPIO_POL_MASK); +- if (irq_gpio_cfg1->irq_out_en) +- regmap_update_bits(cs35l41->regmap, +- CS35L41_GPIO1_CTRL1, +- CS35L41_GPIO_DIR_MASK, +- 0); +- if (irq_gpio_cfg1->irq_src_sel) +- regmap_update_bits(cs35l41->regmap, +- CS35L41_GPIO_PAD_CONTROL, +- CS35L41_GPIO1_CTRL_MASK, +- irq_gpio_cfg1->irq_src_sel << +- CS35L41_GPIO1_CTRL_SHIFT); +- +- if (irq_gpio_cfg2->irq_pol_inv) +- regmap_update_bits(cs35l41->regmap, +- CS35L41_GPIO2_CTRL1, +- CS35L41_GPIO_POL_MASK, +- CS35L41_GPIO_POL_MASK); +- if (irq_gpio_cfg2->irq_out_en) +- regmap_update_bits(cs35l41->regmap, +- CS35L41_GPIO2_CTRL1, +- CS35L41_GPIO_DIR_MASK, +- 0); +- if (irq_gpio_cfg2->irq_src_sel) +- regmap_update_bits(cs35l41->regmap, +- CS35L41_GPIO_PAD_CONTROL, +- CS35L41_GPIO2_CTRL_MASK, +- irq_gpio_cfg2->irq_src_sel << +- CS35L41_GPIO2_CTRL_SHIFT); ++ regmap_update_bits(cs35l41->regmap, CS35L41_GPIO1_CTRL1, ++ CS35L41_GPIO_POL_MASK | CS35L41_GPIO_DIR_MASK, ++ irq_gpio_cfg1->irq_pol_inv << CS35L41_GPIO_POL_SHIFT | ++ !irq_gpio_cfg1->irq_out_en << CS35L41_GPIO_DIR_SHIFT); ++ ++ regmap_update_bits(cs35l41->regmap, CS35L41_GPIO2_CTRL1, ++ CS35L41_GPIO_POL_MASK | CS35L41_GPIO_DIR_MASK, ++ irq_gpio_cfg1->irq_pol_inv << CS35L41_GPIO_POL_SHIFT | ++ !irq_gpio_cfg1->irq_out_en << CS35L41_GPIO_DIR_SHIFT); ++ ++ regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL, ++ CS35L41_GPIO1_CTRL_MASK | CS35L41_GPIO2_CTRL_MASK, ++ irq_gpio_cfg1->irq_src_sel << CS35L41_GPIO1_CTRL_SHIFT | ++ irq_gpio_cfg2->irq_src_sel << CS35L41_GPIO2_CTRL_SHIFT); + + if ((irq_gpio_cfg2->irq_src_sel == + (CS35L41_GPIO_CTRL_ACTV_LO | CS35L41_VALID_PDATA)) || +diff --git a/sound/soc/codecs/cs35l41.h b/sound/soc/codecs/cs35l41.h +index 7a25430182f8..ec1b00b47d5d 100644 +--- a/sound/soc/codecs/cs35l41.h ++++ b/sound/soc/codecs/cs35l41.h +@@ -697,6 +697,7 @@ + #define CS35L41_INT1_UNMASK_PDN 0xFF7FFFFF + + #define CS35L41_GPIO_DIR_MASK 0x80000000 ++#define CS35L41_GPIO_DIR_SHIFT 31 + #define CS35L41_GPIO1_CTRL_MASK 0x00030000 + #define CS35L41_GPIO1_CTRL_SHIFT 16 + #define CS35L41_GPIO2_CTRL_MASK 0x07000000 +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Convert-tables-to-shared-source-code.patch b/patches.suse/ASoC-cs35l41-Convert-tables-to-shared-source-code.patch new file mode 100644 index 0000000..688f760 --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Convert-tables-to-shared-source-code.patch @@ -0,0 +1,3093 @@ +From a87d42227cf5614fe0040ddd1fe642c54298b42c Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Fri, 17 Dec 2021 11:56:59 +0000 +Subject: [PATCH] ASoC: cs35l41: Convert tables to shared source code +Git-commit: a87d42227cf5614fe0040ddd1fe642c54298b42c +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +To support CS35L41 in HDA systems the HDA driver +for CS35L41 would have to duplicate some functions +that already exist on ASoC driver +So instead of duplicate the code, use the new lib +source as a shared resource for both ASoC and HDA + +Also, change the way CONFIG_SND_SOC_CS35L41 is +selected, as reported by Intel Kernel test robot, +it is possible to build SND_SOC_CS35L41_SPI/I2C +without the main driver, which would lead to build +failures. + +Signed-off-by: Lucas Tanure +Reported-by: kernel test robot +Link: https://lore.kernel.org/r/20211217115708.882525-2-tanureal@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + include/sound/cs35l41.h | 733 +++++++++++++++++++++++++++++ + sound/soc/codecs/Kconfig | 11 +- + sound/soc/codecs/Makefile | 4 +- + sound/soc/codecs/cs35l41-i2c.c | 1 - + sound/soc/codecs/cs35l41-lib.c | 733 +++++++++++++++++++++++++++++ + sound/soc/codecs/cs35l41-spi.c | 1 - + sound/soc/codecs/cs35l41-tables.c | 723 ----------------------------- + sound/soc/codecs/cs35l41.h | 734 ------------------------------ + 8 files changed, 1476 insertions(+), 1464 deletions(-) + create mode 100644 sound/soc/codecs/cs35l41-lib.c + delete mode 100644 sound/soc/codecs/cs35l41-tables.c + +diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h +index 1f1e3c6c9be1..aac3ffb9bc89 100644 +--- a/include/sound/cs35l41.h ++++ b/include/sound/cs35l41.h +@@ -10,6 +10,721 @@ + #ifndef __CS35L41_H + #define __CS35L41_H + ++#include ++ ++#define CS35L41_FIRSTREG 0x00000000 ++#define CS35L41_LASTREG 0x03804FE8 ++#define CS35L41_DEVID 0x00000000 ++#define CS35L41_REVID 0x00000004 ++#define CS35L41_FABID 0x00000008 ++#define CS35L41_RELID 0x0000000C ++#define CS35L41_OTPID 0x00000010 ++#define CS35L41_SFT_RESET 0x00000020 ++#define CS35L41_TEST_KEY_CTL 0x00000040 ++#define CS35L41_USER_KEY_CTL 0x00000044 ++#define CS35L41_OTP_MEM0 0x00000400 ++#define CS35L41_OTP_MEM31 0x0000047C ++#define CS35L41_OTP_CTRL0 0x00000500 ++#define CS35L41_OTP_CTRL1 0x00000504 ++#define CS35L41_OTP_CTRL3 0x00000508 ++#define CS35L41_OTP_CTRL4 0x0000050C ++#define CS35L41_OTP_CTRL5 0x00000510 ++#define CS35L41_OTP_CTRL6 0x00000514 ++#define CS35L41_OTP_CTRL7 0x00000518 ++#define CS35L41_OTP_CTRL8 0x0000051C ++#define CS35L41_PWR_CTRL1 0x00002014 ++#define CS35L41_PWR_CTRL2 0x00002018 ++#define CS35L41_PWR_CTRL3 0x0000201C ++#define CS35L41_CTRL_OVRRIDE 0x00002020 ++#define CS35L41_AMP_OUT_MUTE 0x00002024 ++#define CS35L41_PROTECT_REL_ERR_IGN 0x00002034 ++#define CS35L41_GPIO_PAD_CONTROL 0x0000242C ++#define CS35L41_JTAG_CONTROL 0x00002438 ++#define CS35L41_PLL_CLK_CTRL 0x00002C04 ++#define CS35L41_DSP_CLK_CTRL 0x00002C08 ++#define CS35L41_GLOBAL_CLK_CTRL 0x00002C0C ++#define CS35L41_DATA_FS_SEL 0x00002C10 ++#define CS35L41_TST_FS_MON0 0x00002D10 ++#define CS35L41_MDSYNC_EN 0x00003400 ++#define CS35L41_MDSYNC_TX_ID 0x00003408 ++#define CS35L41_MDSYNC_PWR_CTRL 0x0000340C ++#define CS35L41_MDSYNC_DATA_TX 0x00003410 ++#define CS35L41_MDSYNC_TX_STATUS 0x00003414 ++#define CS35L41_MDSYNC_DATA_RX 0x0000341C ++#define CS35L41_MDSYNC_RX_STATUS 0x00003420 ++#define CS35L41_MDSYNC_ERR_STATUS 0x00003424 ++#define CS35L41_MDSYNC_SYNC_PTE2 0x00003528 ++#define CS35L41_MDSYNC_SYNC_PTE3 0x0000352C ++#define CS35L41_MDSYNC_SYNC_MSM_STATUS 0x0000353C ++#define CS35L41_BSTCVRT_VCTRL1 0x00003800 ++#define CS35L41_BSTCVRT_VCTRL2 0x00003804 ++#define CS35L41_BSTCVRT_PEAK_CUR 0x00003808 ++#define CS35L41_BSTCVRT_SFT_RAMP 0x0000380C ++#define CS35L41_BSTCVRT_COEFF 0x00003810 ++#define CS35L41_BSTCVRT_SLOPE_LBST 0x00003814 ++#define CS35L41_BSTCVRT_SW_FREQ 0x00003818 ++#define CS35L41_BSTCVRT_DCM_CTRL 0x0000381C ++#define CS35L41_BSTCVRT_DCM_MODE_FORCE 0x00003820 ++#define CS35L41_BSTCVRT_OVERVOLT_CTRL 0x00003830 ++#define CS35L41_VI_VOL_POL 0x00004000 ++#define CS35L41_VIMON_SPKMON_RESYNC 0x00004100 ++#define CS35L41_DTEMP_WARN_THLD 0x00004220 ++#define CS35L41_DTEMP_CFG 0x00004224 ++#define CS35L41_DTEMP_EN 0x00004308 ++#define CS35L41_VPVBST_FS_SEL 0x00004400 ++#define CS35L41_SP_ENABLES 0x00004800 ++#define CS35L41_SP_RATE_CTRL 0x00004804 ++#define CS35L41_SP_FORMAT 0x00004808 ++#define CS35L41_SP_HIZ_CTRL 0x0000480C ++#define CS35L41_SP_FRAME_TX_SLOT 0x00004810 ++#define CS35L41_SP_FRAME_RX_SLOT 0x00004820 ++#define CS35L41_SP_TX_WL 0x00004830 ++#define CS35L41_SP_RX_WL 0x00004840 ++#define CS35L41_ASP_CONTROL4 0x00004854 ++#define CS35L41_DAC_PCM1_SRC 0x00004C00 ++#define CS35L41_ASP_TX1_SRC 0x00004C20 ++#define CS35L41_ASP_TX2_SRC 0x00004C24 ++#define CS35L41_ASP_TX3_SRC 0x00004C28 ++#define CS35L41_ASP_TX4_SRC 0x00004C2C ++#define CS35L41_DSP1_RX1_SRC 0x00004C40 ++#define CS35L41_DSP1_RX2_SRC 0x00004C44 ++#define CS35L41_DSP1_RX3_SRC 0x00004C48 ++#define CS35L41_DSP1_RX4_SRC 0x00004C4C ++#define CS35L41_DSP1_RX5_SRC 0x00004C50 ++#define CS35L41_DSP1_RX6_SRC 0x00004C54 ++#define CS35L41_DSP1_RX7_SRC 0x00004C58 ++#define CS35L41_DSP1_RX8_SRC 0x00004C5C ++#define CS35L41_NGATE1_SRC 0x00004C60 ++#define CS35L41_NGATE2_SRC 0x00004C64 ++#define CS35L41_AMP_DIG_VOL_CTRL 0x00006000 ++#define CS35L41_VPBR_CFG 0x00006404 ++#define CS35L41_VBBR_CFG 0x00006408 ++#define CS35L41_VPBR_STATUS 0x0000640C ++#define CS35L41_VBBR_STATUS 0x00006410 ++#define CS35L41_OVERTEMP_CFG 0x00006414 ++#define CS35L41_AMP_ERR_VOL 0x00006418 ++#define CS35L41_VOL_STATUS_TO_DSP 0x00006450 ++#define CS35L41_CLASSH_CFG 0x00006800 ++#define CS35L41_WKFET_CFG 0x00006804 ++#define CS35L41_NG_CFG 0x00006808 ++#define CS35L41_AMP_GAIN_CTRL 0x00006C04 ++#define CS35L41_DAC_MSM_CFG 0x00007400 ++#define CS35L41_IRQ1_CFG 0x00010000 ++#define CS35L41_IRQ1_STATUS 0x00010004 ++#define CS35L41_IRQ1_STATUS1 0x00010010 ++#define CS35L41_IRQ1_STATUS2 0x00010014 ++#define CS35L41_IRQ1_STATUS3 0x00010018 ++#define CS35L41_IRQ1_STATUS4 0x0001001C ++#define CS35L41_IRQ1_RAW_STATUS1 0x00010090 ++#define CS35L41_IRQ1_RAW_STATUS2 0x00010094 ++#define CS35L41_IRQ1_RAW_STATUS3 0x00010098 ++#define CS35L41_IRQ1_RAW_STATUS4 0x0001009C ++#define CS35L41_IRQ1_MASK1 0x00010110 ++#define CS35L41_IRQ1_MASK2 0x00010114 ++#define CS35L41_IRQ1_MASK3 0x00010118 ++#define CS35L41_IRQ1_MASK4 0x0001011C ++#define CS35L41_IRQ1_FRC1 0x00010190 ++#define CS35L41_IRQ1_FRC2 0x00010194 ++#define CS35L41_IRQ1_FRC3 0x00010198 ++#define CS35L41_IRQ1_FRC4 0x0001019C ++#define CS35L41_IRQ1_EDGE1 0x00010210 ++#define CS35L41_IRQ1_EDGE4 0x0001021C ++#define CS35L41_IRQ1_POL1 0x00010290 ++#define CS35L41_IRQ1_POL2 0x00010294 ++#define CS35L41_IRQ1_POL3 0x00010298 ++#define CS35L41_IRQ1_POL4 0x0001029C ++#define CS35L41_IRQ1_DB3 0x00010318 ++#define CS35L41_IRQ2_CFG 0x00010800 ++#define CS35L41_IRQ2_STATUS 0x00010804 ++#define CS35L41_IRQ2_STATUS1 0x00010810 ++#define CS35L41_IRQ2_STATUS2 0x00010814 ++#define CS35L41_IRQ2_STATUS3 0x00010818 ++#define CS35L41_IRQ2_STATUS4 0x0001081C ++#define CS35L41_IRQ2_RAW_STATUS1 0x00010890 ++#define CS35L41_IRQ2_RAW_STATUS2 0x00010894 ++#define CS35L41_IRQ2_RAW_STATUS3 0x00010898 ++#define CS35L41_IRQ2_RAW_STATUS4 0x0001089C ++#define CS35L41_IRQ2_MASK1 0x00010910 ++#define CS35L41_IRQ2_MASK2 0x00010914 ++#define CS35L41_IRQ2_MASK3 0x00010918 ++#define CS35L41_IRQ2_MASK4 0x0001091C ++#define CS35L41_IRQ2_FRC1 0x00010990 ++#define CS35L41_IRQ2_FRC2 0x00010994 ++#define CS35L41_IRQ2_FRC3 0x00010998 ++#define CS35L41_IRQ2_FRC4 0x0001099C ++#define CS35L41_IRQ2_EDGE1 0x00010A10 ++#define CS35L41_IRQ2_EDGE4 0x00010A1C ++#define CS35L41_IRQ2_POL1 0x00010A90 ++#define CS35L41_IRQ2_POL2 0x00010A94 ++#define CS35L41_IRQ2_POL3 0x00010A98 ++#define CS35L41_IRQ2_POL4 0x00010A9C ++#define CS35L41_IRQ2_DB3 0x00010B18 ++#define CS35L41_GPIO_STATUS1 0x00011000 ++#define CS35L41_GPIO1_CTRL1 0x00011008 ++#define CS35L41_GPIO2_CTRL1 0x0001100C ++#define CS35L41_MIXER_NGATE_CFG 0x00012000 ++#define CS35L41_MIXER_NGATE_CH1_CFG 0x00012004 ++#define CS35L41_MIXER_NGATE_CH2_CFG 0x00012008 ++#define CS35L41_DSP_MBOX_1 0x00013000 ++#define CS35L41_DSP_MBOX_2 0x00013004 ++#define CS35L41_DSP_MBOX_3 0x00013008 ++#define CS35L41_DSP_MBOX_4 0x0001300C ++#define CS35L41_DSP_MBOX_5 0x00013010 ++#define CS35L41_DSP_MBOX_6 0x00013014 ++#define CS35L41_DSP_MBOX_7 0x00013018 ++#define CS35L41_DSP_MBOX_8 0x0001301C ++#define CS35L41_DSP_VIRT1_MBOX_1 0x00013020 ++#define CS35L41_DSP_VIRT1_MBOX_2 0x00013024 ++#define CS35L41_DSP_VIRT1_MBOX_3 0x00013028 ++#define CS35L41_DSP_VIRT1_MBOX_4 0x0001302C ++#define CS35L41_DSP_VIRT1_MBOX_5 0x00013030 ++#define CS35L41_DSP_VIRT1_MBOX_6 0x00013034 ++#define CS35L41_DSP_VIRT1_MBOX_7 0x00013038 ++#define CS35L41_DSP_VIRT1_MBOX_8 0x0001303C ++#define CS35L41_DSP_VIRT2_MBOX_1 0x00013040 ++#define CS35L41_DSP_VIRT2_MBOX_2 0x00013044 ++#define CS35L41_DSP_VIRT2_MBOX_3 0x00013048 ++#define CS35L41_DSP_VIRT2_MBOX_4 0x0001304C ++#define CS35L41_DSP_VIRT2_MBOX_5 0x00013050 ++#define CS35L41_DSP_VIRT2_MBOX_6 0x00013054 ++#define CS35L41_DSP_VIRT2_MBOX_7 0x00013058 ++#define CS35L41_DSP_VIRT2_MBOX_8 0x0001305C ++#define CS35L41_CLOCK_DETECT_1 0x00014000 ++#define CS35L41_TIMER1_CONTROL 0x00015000 ++#define CS35L41_TIMER1_COUNT_PRESET 0x00015004 ++#define CS35L41_TIMER1_START_STOP 0x0001500C ++#define CS35L41_TIMER1_STATUS 0x00015010 ++#define CS35L41_TIMER1_COUNT_READBACK 0x00015014 ++#define CS35L41_TIMER1_DSP_CLK_CFG 0x00015018 ++#define CS35L41_TIMER1_DSP_CLK_STATUS 0x0001501C ++#define CS35L41_TIMER2_CONTROL 0x00015100 ++#define CS35L41_TIMER2_COUNT_PRESET 0x00015104 ++#define CS35L41_TIMER2_START_STOP 0x0001510C ++#define CS35L41_TIMER2_STATUS 0x00015110 ++#define CS35L41_TIMER2_COUNT_READBACK 0x00015114 ++#define CS35L41_TIMER2_DSP_CLK_CFG 0x00015118 ++#define CS35L41_TIMER2_DSP_CLK_STATUS 0x0001511C ++#define CS35L41_DFT_JTAG_CONTROL 0x00016000 ++#define CS35L41_DIE_STS1 0x00017040 ++#define CS35L41_DIE_STS2 0x00017044 ++#define CS35L41_TEMP_CAL1 0x00017048 ++#define CS35L41_TEMP_CAL2 0x0001704C ++#define CS35L41_DSP1_XMEM_PACK_0 0x02000000 ++#define CS35L41_DSP1_XMEM_PACK_3068 0x02002FF0 ++#define CS35L41_DSP1_XMEM_UNPACK32_0 0x02400000 ++#define CS35L41_DSP1_XMEM_UNPACK32_2046 0x02401FF8 ++#define CS35L41_DSP1_TIMESTAMP_COUNT 0x025C0800 ++#define CS35L41_DSP1_SYS_ID 0x025E0000 ++#define CS35L41_DSP1_SYS_VERSION 0x025E0004 ++#define CS35L41_DSP1_SYS_CORE_ID 0x025E0008 ++#define CS35L41_DSP1_SYS_AHB_ADDR 0x025E000C ++#define CS35L41_DSP1_SYS_XSRAM_SIZE 0x025E0010 ++#define CS35L41_DSP1_SYS_YSRAM_SIZE 0x025E0018 ++#define CS35L41_DSP1_SYS_PSRAM_SIZE 0x025E0020 ++#define CS35L41_DSP1_SYS_PM_BOOT_SIZE 0x025E0028 ++#define CS35L41_DSP1_SYS_FEATURES 0x025E002C ++#define CS35L41_DSP1_SYS_FIR_FILTERS 0x025E0030 ++#define CS35L41_DSP1_SYS_LMS_FILTERS 0x025E0034 ++#define CS35L41_DSP1_SYS_XM_BANK_SIZE 0x025E0038 ++#define CS35L41_DSP1_SYS_YM_BANK_SIZE 0x025E003C ++#define CS35L41_DSP1_SYS_PM_BANK_SIZE 0x025E0040 ++#define CS35L41_DSP1_AHBM_WIN0_CTRL0 0x025E2000 ++#define CS35L41_DSP1_AHBM_WIN0_CTRL1 0x025E2004 ++#define CS35L41_DSP1_AHBM_WIN1_CTRL0 0x025E2008 ++#define CS35L41_DSP1_AHBM_WIN1_CTRL1 0x025E200C ++#define CS35L41_DSP1_AHBM_WIN2_CTRL0 0x025E2010 ++#define CS35L41_DSP1_AHBM_WIN2_CTRL1 0x025E2014 ++#define CS35L41_DSP1_AHBM_WIN3_CTRL0 0x025E2018 ++#define CS35L41_DSP1_AHBM_WIN3_CTRL1 0x025E201C ++#define CS35L41_DSP1_AHBM_WIN4_CTRL0 0x025E2020 ++#define CS35L41_DSP1_AHBM_WIN4_CTRL1 0x025E2024 ++#define CS35L41_DSP1_AHBM_WIN5_CTRL0 0x025E2028 ++#define CS35L41_DSP1_AHBM_WIN5_CTRL1 0x025E202C ++#define CS35L41_DSP1_AHBM_WIN6_CTRL0 0x025E2030 ++#define CS35L41_DSP1_AHBM_WIN6_CTRL1 0x025E2034 ++#define CS35L41_DSP1_AHBM_WIN7_CTRL0 0x025E2038 ++#define CS35L41_DSP1_AHBM_WIN7_CTRL1 0x025E203C ++#define CS35L41_DSP1_AHBM_WIN_DBG_CTRL0 0x025E2040 ++#define CS35L41_DSP1_AHBM_WIN_DBG_CTRL1 0x025E2044 ++#define CS35L41_DSP1_XMEM_UNPACK24_0 0x02800000 ++#define CS35L41_DSP1_XMEM_UNPACK24_4093 0x02803FF4 ++#define CS35L41_DSP1_CTRL_BASE 0x02B80000 ++#define CS35L41_DSP1_CORE_SOFT_RESET 0x02B80010 ++#define CS35L41_DSP1_DEBUG 0x02B80040 ++#define CS35L41_DSP1_TIMER_CTRL 0x02B80048 ++#define CS35L41_DSP1_STREAM_ARB_CTRL 0x02B80050 ++#define CS35L41_DSP1_RX1_RATE 0x02B80080 ++#define CS35L41_DSP1_RX2_RATE 0x02B80088 ++#define CS35L41_DSP1_RX3_RATE 0x02B80090 ++#define CS35L41_DSP1_RX4_RATE 0x02B80098 ++#define CS35L41_DSP1_RX5_RATE 0x02B800A0 ++#define CS35L41_DSP1_RX6_RATE 0x02B800A8 ++#define CS35L41_DSP1_RX7_RATE 0x02B800B0 ++#define CS35L41_DSP1_RX8_RATE 0x02B800B8 ++#define CS35L41_DSP1_TX1_RATE 0x02B80280 ++#define CS35L41_DSP1_TX2_RATE 0x02B80288 ++#define CS35L41_DSP1_TX3_RATE 0x02B80290 ++#define CS35L41_DSP1_TX4_RATE 0x02B80298 ++#define CS35L41_DSP1_TX5_RATE 0x02B802A0 ++#define CS35L41_DSP1_TX6_RATE 0x02B802A8 ++#define CS35L41_DSP1_TX7_RATE 0x02B802B0 ++#define CS35L41_DSP1_TX8_RATE 0x02B802B8 ++#define CS35L41_DSP1_NMI_CTRL1 0x02B80480 ++#define CS35L41_DSP1_NMI_CTRL2 0x02B80488 ++#define CS35L41_DSP1_NMI_CTRL3 0x02B80490 ++#define CS35L41_DSP1_NMI_CTRL4 0x02B80498 ++#define CS35L41_DSP1_NMI_CTRL5 0x02B804A0 ++#define CS35L41_DSP1_NMI_CTRL6 0x02B804A8 ++#define CS35L41_DSP1_NMI_CTRL7 0x02B804B0 ++#define CS35L41_DSP1_NMI_CTRL8 0x02B804B8 ++#define CS35L41_DSP1_RESUME_CTRL 0x02B80500 ++#define CS35L41_DSP1_IRQ1_CTRL 0x02B80508 ++#define CS35L41_DSP1_IRQ2_CTRL 0x02B80510 ++#define CS35L41_DSP1_IRQ3_CTRL 0x02B80518 ++#define CS35L41_DSP1_IRQ4_CTRL 0x02B80520 ++#define CS35L41_DSP1_IRQ5_CTRL 0x02B80528 ++#define CS35L41_DSP1_IRQ6_CTRL 0x02B80530 ++#define CS35L41_DSP1_IRQ7_CTRL 0x02B80538 ++#define CS35L41_DSP1_IRQ8_CTRL 0x02B80540 ++#define CS35L41_DSP1_IRQ9_CTRL 0x02B80548 ++#define CS35L41_DSP1_IRQ10_CTRL 0x02B80550 ++#define CS35L41_DSP1_IRQ11_CTRL 0x02B80558 ++#define CS35L41_DSP1_IRQ12_CTRL 0x02B80560 ++#define CS35L41_DSP1_IRQ13_CTRL 0x02B80568 ++#define CS35L41_DSP1_IRQ14_CTRL 0x02B80570 ++#define CS35L41_DSP1_IRQ15_CTRL 0x02B80578 ++#define CS35L41_DSP1_IRQ16_CTRL 0x02B80580 ++#define CS35L41_DSP1_IRQ17_CTRL 0x02B80588 ++#define CS35L41_DSP1_IRQ18_CTRL 0x02B80590 ++#define CS35L41_DSP1_IRQ19_CTRL 0x02B80598 ++#define CS35L41_DSP1_IRQ20_CTRL 0x02B805A0 ++#define CS35L41_DSP1_IRQ21_CTRL 0x02B805A8 ++#define CS35L41_DSP1_IRQ22_CTRL 0x02B805B0 ++#define CS35L41_DSP1_IRQ23_CTRL 0x02B805B8 ++#define CS35L41_DSP1_SCRATCH1 0x02B805C0 ++#define CS35L41_DSP1_SCRATCH2 0x02B805C8 ++#define CS35L41_DSP1_SCRATCH3 0x02B805D0 ++#define CS35L41_DSP1_SCRATCH4 0x02B805D8 ++#define CS35L41_DSP1_CCM_CORE_CTRL 0x02BC1000 ++#define CS35L41_DSP1_CCM_CLK_OVERRIDE 0x02BC1008 ++#define CS35L41_DSP1_XM_MSTR_EN 0x02BC2000 ++#define CS35L41_DSP1_XM_CORE_PRI 0x02BC2008 ++#define CS35L41_DSP1_XM_AHB_PACK_PL_PRI 0x02BC2010 ++#define CS35L41_DSP1_XM_AHB_UP_PL_PRI 0x02BC2018 ++#define CS35L41_DSP1_XM_ACCEL_PL0_PRI 0x02BC2020 ++#define CS35L41_DSP1_XM_NPL0_PRI 0x02BC2078 ++#define CS35L41_DSP1_YM_MSTR_EN 0x02BC20C0 ++#define CS35L41_DSP1_YM_CORE_PRI 0x02BC20C8 ++#define CS35L41_DSP1_YM_AHB_PACK_PL_PRI 0x02BC20D0 ++#define CS35L41_DSP1_YM_AHB_UP_PL_PRI 0x02BC20D8 ++#define CS35L41_DSP1_YM_ACCEL_PL0_PRI 0x02BC20E0 ++#define CS35L41_DSP1_YM_NPL0_PRI 0x02BC2138 ++#define CS35L41_DSP1_PM_MSTR_EN 0x02BC2180 ++#define CS35L41_DSP1_PM_PATCH0_ADDR 0x02BC2188 ++#define CS35L41_DSP1_PM_PATCH0_EN 0x02BC218C ++#define CS35L41_DSP1_PM_PATCH0_DATA_LO 0x02BC2190 ++#define CS35L41_DSP1_PM_PATCH0_DATA_HI 0x02BC2194 ++#define CS35L41_DSP1_PM_PATCH1_ADDR 0x02BC2198 ++#define CS35L41_DSP1_PM_PATCH1_EN 0x02BC219C ++#define CS35L41_DSP1_PM_PATCH1_DATA_LO 0x02BC21A0 ++#define CS35L41_DSP1_PM_PATCH1_DATA_HI 0x02BC21A4 ++#define CS35L41_DSP1_PM_PATCH2_ADDR 0x02BC21A8 ++#define CS35L41_DSP1_PM_PATCH2_EN 0x02BC21AC ++#define CS35L41_DSP1_PM_PATCH2_DATA_LO 0x02BC21B0 ++#define CS35L41_DSP1_PM_PATCH2_DATA_HI 0x02BC21B4 ++#define CS35L41_DSP1_PM_PATCH3_ADDR 0x02BC21B8 ++#define CS35L41_DSP1_PM_PATCH3_EN 0x02BC21BC ++#define CS35L41_DSP1_PM_PATCH3_DATA_LO 0x02BC21C0 ++#define CS35L41_DSP1_PM_PATCH3_DATA_HI 0x02BC21C4 ++#define CS35L41_DSP1_PM_PATCH4_ADDR 0x02BC21C8 ++#define CS35L41_DSP1_PM_PATCH4_EN 0x02BC21CC ++#define CS35L41_DSP1_PM_PATCH4_DATA_LO 0x02BC21D0 ++#define CS35L41_DSP1_PM_PATCH4_DATA_HI 0x02BC21D4 ++#define CS35L41_DSP1_PM_PATCH5_ADDR 0x02BC21D8 ++#define CS35L41_DSP1_PM_PATCH5_EN 0x02BC21DC ++#define CS35L41_DSP1_PM_PATCH5_DATA_LO 0x02BC21E0 ++#define CS35L41_DSP1_PM_PATCH5_DATA_HI 0x02BC21E4 ++#define CS35L41_DSP1_PM_PATCH6_ADDR 0x02BC21E8 ++#define CS35L41_DSP1_PM_PATCH6_EN 0x02BC21EC ++#define CS35L41_DSP1_PM_PATCH6_DATA_LO 0x02BC21F0 ++#define CS35L41_DSP1_PM_PATCH6_DATA_HI 0x02BC21F4 ++#define CS35L41_DSP1_PM_PATCH7_ADDR 0x02BC21F8 ++#define CS35L41_DSP1_PM_PATCH7_EN 0x02BC21FC ++#define CS35L41_DSP1_PM_PATCH7_DATA_LO 0x02BC2200 ++#define CS35L41_DSP1_PM_PATCH7_DATA_HI 0x02BC2204 ++#define CS35L41_DSP1_MPU_XM_ACCESS0 0x02BC3000 ++#define CS35L41_DSP1_MPU_YM_ACCESS0 0x02BC3004 ++#define CS35L41_DSP1_MPU_WNDW_ACCESS0 0x02BC3008 ++#define CS35L41_DSP1_MPU_XREG_ACCESS0 0x02BC300C ++#define CS35L41_DSP1_MPU_YREG_ACCESS0 0x02BC3014 ++#define CS35L41_DSP1_MPU_XM_ACCESS1 0x02BC3018 ++#define CS35L41_DSP1_MPU_YM_ACCESS1 0x02BC301C ++#define CS35L41_DSP1_MPU_WNDW_ACCESS1 0x02BC3020 ++#define CS35L41_DSP1_MPU_XREG_ACCESS1 0x02BC3024 ++#define CS35L41_DSP1_MPU_YREG_ACCESS1 0x02BC302C ++#define CS35L41_DSP1_MPU_XM_ACCESS2 0x02BC3030 ++#define CS35L41_DSP1_MPU_YM_ACCESS2 0x02BC3034 ++#define CS35L41_DSP1_MPU_WNDW_ACCESS2 0x02BC3038 ++#define CS35L41_DSP1_MPU_XREG_ACCESS2 0x02BC303C ++#define CS35L41_DSP1_MPU_YREG_ACCESS2 0x02BC3044 ++#define CS35L41_DSP1_MPU_XM_ACCESS3 0x02BC3048 ++#define CS35L41_DSP1_MPU_YM_ACCESS3 0x02BC304C ++#define CS35L41_DSP1_MPU_WNDW_ACCESS3 0x02BC3050 ++#define CS35L41_DSP1_MPU_XREG_ACCESS3 0x02BC3054 ++#define CS35L41_DSP1_MPU_YREG_ACCESS3 0x02BC305C ++#define CS35L41_DSP1_MPU_XM_VIO_ADDR 0x02BC3100 ++#define CS35L41_DSP1_MPU_XM_VIO_STATUS 0x02BC3104 ++#define CS35L41_DSP1_MPU_YM_VIO_ADDR 0x02BC3108 ++#define CS35L41_DSP1_MPU_YM_VIO_STATUS 0x02BC310C ++#define CS35L41_DSP1_MPU_PM_VIO_ADDR 0x02BC3110 ++#define CS35L41_DSP1_MPU_PM_VIO_STATUS 0x02BC3114 ++#define CS35L41_DSP1_MPU_LOCK_CONFIG 0x02BC3140 ++#define CS35L41_DSP1_MPU_WDT_RST_CTRL 0x02BC3180 ++#define CS35L41_DSP1_STRMARB_MSTR0_CFG0 0x02BC5000 ++#define CS35L41_DSP1_STRMARB_MSTR0_CFG1 0x02BC5004 ++#define CS35L41_DSP1_STRMARB_MSTR0_CFG2 0x02BC5008 ++#define CS35L41_DSP1_STRMARB_MSTR1_CFG0 0x02BC5010 ++#define CS35L41_DSP1_STRMARB_MSTR1_CFG1 0x02BC5014 ++#define CS35L41_DSP1_STRMARB_MSTR1_CFG2 0x02BC5018 ++#define CS35L41_DSP1_STRMARB_MSTR2_CFG0 0x02BC5020 ++#define CS35L41_DSP1_STRMARB_MSTR2_CFG1 0x02BC5024 ++#define CS35L41_DSP1_STRMARB_MSTR2_CFG2 0x02BC5028 ++#define CS35L41_DSP1_STRMARB_MSTR3_CFG0 0x02BC5030 ++#define CS35L41_DSP1_STRMARB_MSTR3_CFG1 0x02BC5034 ++#define CS35L41_DSP1_STRMARB_MSTR3_CFG2 0x02BC5038 ++#define CS35L41_DSP1_STRMARB_MSTR4_CFG0 0x02BC5040 ++#define CS35L41_DSP1_STRMARB_MSTR4_CFG1 0x02BC5044 ++#define CS35L41_DSP1_STRMARB_MSTR4_CFG2 0x02BC5048 ++#define CS35L41_DSP1_STRMARB_MSTR5_CFG0 0x02BC5050 ++#define CS35L41_DSP1_STRMARB_MSTR5_CFG1 0x02BC5054 ++#define CS35L41_DSP1_STRMARB_MSTR5_CFG2 0x02BC5058 ++#define CS35L41_DSP1_STRMARB_MSTR6_CFG0 0x02BC5060 ++#define CS35L41_DSP1_STRMARB_MSTR6_CFG1 0x02BC5064 ++#define CS35L41_DSP1_STRMARB_MSTR6_CFG2 0x02BC5068 ++#define CS35L41_DSP1_STRMARB_MSTR7_CFG0 0x02BC5070 ++#define CS35L41_DSP1_STRMARB_MSTR7_CFG1 0x02BC5074 ++#define CS35L41_DSP1_STRMARB_MSTR7_CFG2 0x02BC5078 ++#define CS35L41_DSP1_STRMARB_TX0_CFG0 0x02BC5200 ++#define CS35L41_DSP1_STRMARB_TX0_CFG1 0x02BC5204 ++#define CS35L41_DSP1_STRMARB_TX1_CFG0 0x02BC5208 ++#define CS35L41_DSP1_STRMARB_TX1_CFG1 0x02BC520C ++#define CS35L41_DSP1_STRMARB_TX2_CFG0 0x02BC5210 ++#define CS35L41_DSP1_STRMARB_TX2_CFG1 0x02BC5214 ++#define CS35L41_DSP1_STRMARB_TX3_CFG0 0x02BC5218 ++#define CS35L41_DSP1_STRMARB_TX3_CFG1 0x02BC521C ++#define CS35L41_DSP1_STRMARB_TX4_CFG0 0x02BC5220 ++#define CS35L41_DSP1_STRMARB_TX4_CFG1 0x02BC5224 ++#define CS35L41_DSP1_STRMARB_TX5_CFG0 0x02BC5228 ++#define CS35L41_DSP1_STRMARB_TX5_CFG1 0x02BC522C ++#define CS35L41_DSP1_STRMARB_TX6_CFG0 0x02BC5230 ++#define CS35L41_DSP1_STRMARB_TX6_CFG1 0x02BC5234 ++#define CS35L41_DSP1_STRMARB_TX7_CFG0 0x02BC5238 ++#define CS35L41_DSP1_STRMARB_TX7_CFG1 0x02BC523C ++#define CS35L41_DSP1_STRMARB_RX0_CFG0 0x02BC5400 ++#define CS35L41_DSP1_STRMARB_RX0_CFG1 0x02BC5404 ++#define CS35L41_DSP1_STRMARB_RX1_CFG0 0x02BC5408 ++#define CS35L41_DSP1_STRMARB_RX1_CFG1 0x02BC540C ++#define CS35L41_DSP1_STRMARB_RX2_CFG0 0x02BC5410 ++#define CS35L41_DSP1_STRMARB_RX2_CFG1 0x02BC5414 ++#define CS35L41_DSP1_STRMARB_RX3_CFG0 0x02BC5418 ++#define CS35L41_DSP1_STRMARB_RX3_CFG1 0x02BC541C ++#define CS35L41_DSP1_STRMARB_RX4_CFG0 0x02BC5420 ++#define CS35L41_DSP1_STRMARB_RX4_CFG1 0x02BC5424 ++#define CS35L41_DSP1_STRMARB_RX5_CFG0 0x02BC5428 ++#define CS35L41_DSP1_STRMARB_RX5_CFG1 0x02BC542C ++#define CS35L41_DSP1_STRMARB_RX6_CFG0 0x02BC5430 ++#define CS35L41_DSP1_STRMARB_RX6_CFG1 0x02BC5434 ++#define CS35L41_DSP1_STRMARB_RX7_CFG0 0x02BC5438 ++#define CS35L41_DSP1_STRMARB_RX7_CFG1 0x02BC543C ++#define CS35L41_DSP1_STRMARB_IRQ0_CFG0 0x02BC5600 ++#define CS35L41_DSP1_STRMARB_IRQ0_CFG1 0x02BC5604 ++#define CS35L41_DSP1_STRMARB_IRQ0_CFG2 0x02BC5608 ++#define CS35L41_DSP1_STRMARB_IRQ1_CFG0 0x02BC5610 ++#define CS35L41_DSP1_STRMARB_IRQ1_CFG1 0x02BC5614 ++#define CS35L41_DSP1_STRMARB_IRQ1_CFG2 0x02BC5618 ++#define CS35L41_DSP1_STRMARB_IRQ2_CFG0 0x02BC5620 ++#define CS35L41_DSP1_STRMARB_IRQ2_CFG1 0x02BC5624 ++#define CS35L41_DSP1_STRMARB_IRQ2_CFG2 0x02BC5628 ++#define CS35L41_DSP1_STRMARB_IRQ3_CFG0 0x02BC5630 ++#define CS35L41_DSP1_STRMARB_IRQ3_CFG1 0x02BC5634 ++#define CS35L41_DSP1_STRMARB_IRQ3_CFG2 0x02BC5638 ++#define CS35L41_DSP1_STRMARB_IRQ4_CFG0 0x02BC5640 ++#define CS35L41_DSP1_STRMARB_IRQ4_CFG1 0x02BC5644 ++#define CS35L41_DSP1_STRMARB_IRQ4_CFG2 0x02BC5648 ++#define CS35L41_DSP1_STRMARB_IRQ5_CFG0 0x02BC5650 ++#define CS35L41_DSP1_STRMARB_IRQ5_CFG1 0x02BC5654 ++#define CS35L41_DSP1_STRMARB_IRQ5_CFG2 0x02BC5658 ++#define CS35L41_DSP1_STRMARB_IRQ6_CFG0 0x02BC5660 ++#define CS35L41_DSP1_STRMARB_IRQ6_CFG1 0x02BC5664 ++#define CS35L41_DSP1_STRMARB_IRQ6_CFG2 0x02BC5668 ++#define CS35L41_DSP1_STRMARB_IRQ7_CFG0 0x02BC5670 ++#define CS35L41_DSP1_STRMARB_IRQ7_CFG1 0x02BC5674 ++#define CS35L41_DSP1_STRMARB_IRQ7_CFG2 0x02BC5678 ++#define CS35L41_DSP1_STRMARB_RESYNC_MSK 0x02BC5A00 ++#define CS35L41_DSP1_STRMARB_ERR_STATUS 0x02BC5A08 ++#define CS35L41_DSP1_INTPCTL_RES_STATIC 0x02BC6000 ++#define CS35L41_DSP1_INTPCTL_RES_DYN 0x02BC6004 ++#define CS35L41_DSP1_INTPCTL_NMI_CTRL 0x02BC6008 ++#define CS35L41_DSP1_INTPCTL_IRQ_INV 0x02BC6010 ++#define CS35L41_DSP1_INTPCTL_IRQ_MODE 0x02BC6014 ++#define CS35L41_DSP1_INTPCTL_IRQ_EN 0x02BC6018 ++#define CS35L41_DSP1_INTPCTL_IRQ_MSK 0x02BC601C ++#define CS35L41_DSP1_INTPCTL_IRQ_FLUSH 0x02BC6020 ++#define CS35L41_DSP1_INTPCTL_IRQ_MSKCLR 0x02BC6024 ++#define CS35L41_DSP1_INTPCTL_IRQ_FRC 0x02BC6028 ++#define CS35L41_DSP1_INTPCTL_IRQ_MSKSET 0x02BC602C ++#define CS35L41_DSP1_INTPCTL_IRQ_ERR 0x02BC6030 ++#define CS35L41_DSP1_INTPCTL_IRQ_PEND 0x02BC6034 ++#define CS35L41_DSP1_INTPCTL_IRQ_GEN 0x02BC6038 ++#define CS35L41_DSP1_INTPCTL_TESTBITS 0x02BC6040 ++#define CS35L41_DSP1_WDT_CONTROL 0x02BC7000 ++#define CS35L41_DSP1_WDT_STATUS 0x02BC7008 ++#define CS35L41_DSP1_YMEM_PACK_0 0x02C00000 ++#define CS35L41_DSP1_YMEM_PACK_1532 0x02C017F0 ++#define CS35L41_DSP1_YMEM_UNPACK32_0 0x03000000 ++#define CS35L41_DSP1_YMEM_UNPACK32_1022 0x03000FF8 ++#define CS35L41_DSP1_YMEM_UNPACK24_0 0x03400000 ++#define CS35L41_DSP1_YMEM_UNPACK24_2045 0x03401FF4 ++#define CS35L41_DSP1_PMEM_0 0x03800000 ++#define CS35L41_DSP1_PMEM_5114 0x03804FE8 ++ ++/*test regs for emulation bringup*/ ++#define CS35L41_PLL_OVR 0x00003018 ++#define CS35L41_BST_TEST_DUTY 0x00003900 ++#define CS35L41_DIGPWM_IOCTRL 0x0000706C ++ ++/*registers populated by OTP*/ ++#define CS35L41_OTP_TRIM_1 0x0000208c ++#define CS35L41_OTP_TRIM_2 0x00002090 ++#define CS35L41_OTP_TRIM_3 0x00003010 ++#define CS35L41_OTP_TRIM_4 0x0000300C ++#define CS35L41_OTP_TRIM_5 0x0000394C ++#define CS35L41_OTP_TRIM_6 0x00003950 ++#define CS35L41_OTP_TRIM_7 0x00003954 ++#define CS35L41_OTP_TRIM_8 0x00003958 ++#define CS35L41_OTP_TRIM_9 0x0000395C ++#define CS35L41_OTP_TRIM_10 0x0000416C ++#define CS35L41_OTP_TRIM_11 0x00004160 ++#define CS35L41_OTP_TRIM_12 0x00004170 ++#define CS35L41_OTP_TRIM_13 0x00004360 ++#define CS35L41_OTP_TRIM_14 0x00004448 ++#define CS35L41_OTP_TRIM_15 0x0000444C ++#define CS35L41_OTP_TRIM_16 0x00006E30 ++#define CS35L41_OTP_TRIM_17 0x00006E34 ++#define CS35L41_OTP_TRIM_18 0x00006E38 ++#define CS35L41_OTP_TRIM_19 0x00006E3C ++#define CS35L41_OTP_TRIM_20 0x00006E40 ++#define CS35L41_OTP_TRIM_21 0x00006E44 ++#define CS35L41_OTP_TRIM_22 0x00006E48 ++#define CS35L41_OTP_TRIM_23 0x00006E4C ++#define CS35L41_OTP_TRIM_24 0x00006E50 ++#define CS35L41_OTP_TRIM_25 0x00006E54 ++#define CS35L41_OTP_TRIM_26 0x00006E58 ++#define CS35L41_OTP_TRIM_27 0x00006E5C ++#define CS35L41_OTP_TRIM_28 0x00006E60 ++#define CS35L41_OTP_TRIM_29 0x00006E64 ++#define CS35L41_OTP_TRIM_30 0x00007418 ++#define CS35L41_OTP_TRIM_31 0x0000741C ++#define CS35L41_OTP_TRIM_32 0x00007434 ++#define CS35L41_OTP_TRIM_33 0x00007068 ++#define CS35L41_OTP_TRIM_34 0x0000410C ++#define CS35L41_OTP_TRIM_35 0x0000400C ++#define CS35L41_OTP_TRIM_36 0x00002030 ++ ++#define CS35L41_MAX_CACHE_REG 36 ++#define CS35L41_OTP_SIZE_WORDS 32 ++#define CS35L41_NUM_OTP_ELEM 100 ++#define CS35L41_NUM_OTP_MAPS 5 ++ ++#define CS35L41_VALID_PDATA 0x80000000 ++#define CS35L41_NUM_SUPPLIES 2 ++ ++#define CS35L41_SCLK_MSTR_MASK 0x10 ++#define CS35L41_SCLK_MSTR_SHIFT 4 ++#define CS35L41_LRCLK_MSTR_MASK 0x01 ++#define CS35L41_LRCLK_MSTR_SHIFT 0 ++#define CS35L41_SCLK_INV_MASK 0x40 ++#define CS35L41_SCLK_INV_SHIFT 6 ++#define CS35L41_LRCLK_INV_MASK 0x04 ++#define CS35L41_LRCLK_INV_SHIFT 2 ++#define CS35L41_SCLK_FRC_MASK 0x20 ++#define CS35L41_SCLK_FRC_SHIFT 5 ++#define CS35L41_LRCLK_FRC_MASK 0x02 ++#define CS35L41_LRCLK_FRC_SHIFT 1 ++ ++#define CS35L41_AMP_GAIN_PCM_MASK 0x3E0 ++#define CS35L41_AMP_GAIN_ZC_MASK 0x0400 ++#define CS35L41_AMP_GAIN_ZC_SHIFT 10 ++ ++#define CS35L41_BST_CTL_MASK 0xFF ++#define CS35L41_BST_CTL_SEL_MASK 0x03 ++#define CS35L41_BST_CTL_SEL_REG 0x00 ++#define CS35L41_BST_CTL_SEL_CLASSH 0x01 ++#define CS35L41_BST_IPK_MASK 0x7F ++#define CS35L41_BST_IPK_SHIFT 0 ++#define CS35L41_BST_LIM_MASK 0x4 ++#define CS35L41_BST_LIM_SHIFT 2 ++#define CS35L41_BST_K1_MASK 0x000000FF ++#define CS35L41_BST_K1_SHIFT 0 ++#define CS35L41_BST_K2_MASK 0x0000FF00 ++#define CS35L41_BST_K2_SHIFT 8 ++#define CS35L41_BST_SLOPE_MASK 0x0000FF00 ++#define CS35L41_BST_SLOPE_SHIFT 8 ++#define CS35L41_BST_LBST_VAL_MASK 0x00000003 ++#define CS35L41_BST_LBST_VAL_SHIFT 0 ++ ++#define CS35L41_TEMP_THLD_MASK 0x03 ++#define CS35L41_VMON_IMON_VOL_MASK 0x07FF07FF ++#define CS35L41_PDM_MODE_MASK 0x01 ++#define CS35L41_PDM_MODE_SHIFT 0 ++ ++#define CS35L41_CH_MEM_DEPTH_MASK 0x07 ++#define CS35L41_CH_MEM_DEPTH_SHIFT 0 ++#define CS35L41_CH_HDRM_CTL_MASK 0x007F0000 ++#define CS35L41_CH_HDRM_CTL_SHIFT 16 ++#define CS35L41_CH_REL_RATE_MASK 0xFF00 ++#define CS35L41_CH_REL_RATE_SHIFT 8 ++#define CS35L41_CH_WKFET_DLY_MASK 0x001C ++#define CS35L41_CH_WKFET_DLY_SHIFT 2 ++#define CS35L41_CH_WKFET_THLD_MASK 0x0F00 ++#define CS35L41_CH_WKFET_THLD_SHIFT 8 ++ ++#define CS35L41_HW_NG_SEL_MASK 0x3F00 ++#define CS35L41_HW_NG_SEL_SHIFT 8 ++#define CS35L41_HW_NG_DLY_MASK 0x0070 ++#define CS35L41_HW_NG_DLY_SHIFT 4 ++#define CS35L41_HW_NG_THLD_MASK 0x0007 ++#define CS35L41_HW_NG_THLD_SHIFT 0 ++ ++#define CS35L41_DSP_NG_ENABLE_MASK 0x00010000 ++#define CS35L41_DSP_NG_ENABLE_SHIFT 16 ++#define CS35L41_DSP_NG_THLD_MASK 0x7 ++#define CS35L41_DSP_NG_THLD_SHIFT 0 ++#define CS35L41_DSP_NG_DELAY_MASK 0x0F00 ++#define CS35L41_DSP_NG_DELAY_SHIFT 8 ++ ++#define CS35L41_ASP_FMT_MASK 0x0700 ++#define CS35L41_ASP_FMT_SHIFT 8 ++#define CS35L41_ASP_DOUT_HIZ_MASK 0x03 ++#define CS35L41_ASP_DOUT_HIZ_SHIFT 0 ++#define CS35L41_ASP_WIDTH_16 0x10 ++#define CS35L41_ASP_WIDTH_24 0x18 ++#define CS35L41_ASP_WIDTH_32 0x20 ++#define CS35L41_ASP_WIDTH_TX_MASK 0xFF0000 ++#define CS35L41_ASP_WIDTH_TX_SHIFT 16 ++#define CS35L41_ASP_WIDTH_RX_MASK 0xFF000000 ++#define CS35L41_ASP_WIDTH_RX_SHIFT 24 ++#define CS35L41_ASP_RX1_SLOT_MASK 0x3F ++#define CS35L41_ASP_RX1_SLOT_SHIFT 0 ++#define CS35L41_ASP_RX2_SLOT_MASK 0x3F00 ++#define CS35L41_ASP_RX2_SLOT_SHIFT 8 ++#define CS35L41_ASP_RX_WL_MASK 0x3F ++#define CS35L41_ASP_TX_WL_MASK 0x3F ++#define CS35L41_ASP_RX_WL_SHIFT 0 ++#define CS35L41_ASP_TX_WL_SHIFT 0 ++#define CS35L41_ASP_SOURCE_MASK 0x7F ++ ++#define CS35L41_INPUT_SRC_ASPRX1 0x08 ++#define CS35L41_INPUT_SRC_ASPRX2 0x09 ++#define CS35L41_INPUT_SRC_VMON 0x18 ++#define CS35L41_INPUT_SRC_IMON 0x19 ++#define CS35L41_INPUT_SRC_CLASSH 0x21 ++#define CS35L41_INPUT_SRC_VPMON 0x28 ++#define CS35L41_INPUT_SRC_VBSTMON 0x29 ++#define CS35L41_INPUT_SRC_TEMPMON 0x3A ++#define CS35L41_INPUT_SRC_RSVD 0x3B ++#define CS35L41_INPUT_DSP_TX1 0x32 ++#define CS35L41_INPUT_DSP_TX2 0x33 ++ ++#define CS35L41_PLL_CLK_SEL_MASK 0x07 ++#define CS35L41_PLL_CLK_SEL_SHIFT 0 ++#define CS35L41_PLL_CLK_EN_MASK 0x10 ++#define CS35L41_PLL_CLK_EN_SHIFT 4 ++#define CS35L41_PLL_OPENLOOP_MASK 0x0800 ++#define CS35L41_PLL_OPENLOOP_SHIFT 11 ++#define CS35L41_PLLSRC_SCLK 0 ++#define CS35L41_PLLSRC_LRCLK 1 ++#define CS35L41_PLLSRC_SELF 3 ++#define CS35L41_PLLSRC_PDMCLK 4 ++#define CS35L41_PLLSRC_MCLK 5 ++#define CS35L41_PLLSRC_SWIRE 7 ++#define CS35L41_REFCLK_FREQ_MASK 0x7E0 ++#define CS35L41_REFCLK_FREQ_SHIFT 5 ++ ++#define CS35L41_GLOBAL_FS_MASK 0x1F ++#define CS35L41_GLOBAL_FS_SHIFT 0 ++ ++#define CS35L41_GLOBAL_EN_MASK 0x01 ++#define CS35L41_GLOBAL_EN_SHIFT 0 ++#define CS35L41_BST_EN_MASK 0x0030 ++#define CS35L41_BST_EN_SHIFT 4 ++#define CS35L41_BST_EN_DEFAULT 0x2 ++#define CS35L41_AMP_EN_SHIFT 0 ++#define CS35L41_AMP_EN_MASK 1 ++ ++#define CS35L41_PDN_DONE_MASK 0x00800000 ++#define CS35L41_PDN_DONE_SHIFT 23 ++#define CS35L41_PUP_DONE_MASK 0x01000000 ++#define CS35L41_PUP_DONE_SHIFT 24 ++ ++#define CS35L36_PUP_DONE_IRQ_UNMASK 0x5F ++#define CS35L36_PUP_DONE_IRQ_MASK 0xBF ++ ++#define CS35L41_AMP_SHORT_ERR 0x80000000 ++#define CS35L41_BST_SHORT_ERR 0x0100 ++#define CS35L41_TEMP_WARN 0x8000 ++#define CS35L41_TEMP_ERR 0x00020000 ++#define CS35L41_BST_OVP_ERR 0x40 ++#define CS35L41_BST_DCM_UVP_ERR 0x80 ++#define CS35L41_OTP_BOOT_DONE 0x02 ++#define CS35L41_PLL_UNLOCK 0x10 ++#define CS35L41_OTP_BOOT_ERR 0x80000000 ++ ++#define CS35L41_AMP_SHORT_ERR_RLS 0x02 ++#define CS35L41_BST_SHORT_ERR_RLS 0x04 ++#define CS35L41_BST_OVP_ERR_RLS 0x08 ++#define CS35L41_BST_UVP_ERR_RLS 0x10 ++#define CS35L41_TEMP_WARN_ERR_RLS 0x20 ++#define CS35L41_TEMP_ERR_RLS 0x40 ++ ++#define CS35L41_INT1_MASK_DEFAULT 0x7FFCFE3F ++#define CS35L41_INT1_UNMASK_PUP 0xFEFFFFFF ++#define CS35L41_INT1_UNMASK_PDN 0xFF7FFFFF ++ ++#define CS35L41_GPIO_DIR_MASK 0x80000000 ++#define CS35L41_GPIO_DIR_SHIFT 31 ++#define CS35L41_GPIO1_CTRL_MASK 0x00030000 ++#define CS35L41_GPIO1_CTRL_SHIFT 16 ++#define CS35L41_GPIO2_CTRL_MASK 0x07000000 ++#define CS35L41_GPIO2_CTRL_SHIFT 24 ++#define CS35L41_GPIO_CTRL_OPEN_INT 2 ++#define CS35L41_GPIO_CTRL_ACTV_LO 4 ++#define CS35L41_GPIO_CTRL_ACTV_HI 5 ++#define CS35L41_GPIO_POL_MASK 0x1000 ++#define CS35L41_GPIO_POL_SHIFT 12 ++ ++#define CS35L41_AMP_INV_PCM_SHIFT 14 ++#define CS35L41_AMP_INV_PCM_MASK BIT(CS35L41_AMP_INV_PCM_SHIFT) ++#define CS35L41_AMP_PCM_VOL_SHIFT 3 ++#define CS35L41_AMP_PCM_VOL_MASK (0x7FF << 3) ++#define CS35L41_AMP_PCM_VOL_MUTE 0x4CF ++ ++#define CS35L41_CHIP_ID 0x35a40 ++#define CS35L41R_CHIP_ID 0x35b40 ++#define CS35L41_MTLREVID_MASK 0x0F ++#define CS35L41_REVID_A0 0xA0 ++#define CS35L41_REVID_B0 0xB0 ++#define CS35L41_REVID_B2 0xB2 ++ ++#define CS35L41_HALO_CORE_RESET 0x00000200 ++ ++#define CS35L41_FS1_WINDOW_MASK 0x000007FF ++#define CS35L41_FS2_WINDOW_MASK 0x00FFF800 ++#define CS35L41_FS2_WINDOW_SHIFT 12 ++ ++#define CS35L41_SPI_MAX_FREQ 4000000 ++#define CS35L41_REGSTRIDE 4 ++ + enum cs35l41_clk_ids { + CS35L41_CLKID_SCLK = 0, + CS35L41_CLKID_LRCLK = 1, +@@ -31,4 +746,22 @@ struct cs35l41_platform_data { + struct cs35l41_irq_cfg irq_config2; + }; + ++struct cs35l41_otp_packed_element_t { ++ u32 reg; ++ u8 shift; ++ u8 size; ++}; ++ ++struct cs35l41_otp_map_element_t { ++ u32 id; ++ u32 num_elements; ++ const struct cs35l41_otp_packed_element_t *map; ++ u32 bit_offset; ++ u32 word_offset; ++}; ++ ++extern const struct cs35l41_otp_map_element_t cs35l41_otp_map_map[CS35L41_NUM_OTP_MAPS]; ++extern struct regmap_config cs35l41_regmap_i2c; ++extern struct regmap_config cs35l41_regmap_spi; ++ + #endif /* __CS35L41_H */ +diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig +index 5fe9ec924864..d3e5ae8310ef 100644 +--- a/sound/soc/codecs/Kconfig ++++ b/sound/soc/codecs/Kconfig +@@ -624,21 +624,24 @@ config SND_SOC_CS35L36 + tristate "Cirrus Logic CS35L36 CODEC" + depends on I2C + ++config SND_SOC_CS35L41_LIB ++ tristate ++ + config SND_SOC_CS35L41 + tristate +- default y if SND_SOC_CS35L41_SPI=y +- default y if SND_SOC_CS35L41_I2C=y +- default m if SND_SOC_CS35L41_SPI=m +- default m if SND_SOC_CS35L41_I2C=m + + config SND_SOC_CS35L41_SPI + tristate "Cirrus Logic CS35L41 CODEC (SPI)" + depends on SPI_MASTER ++ select SND_SOC_CS35L41_LIB ++ select SND_SOC_CS35L41 + select REGMAP_SPI + + config SND_SOC_CS35L41_I2C + tristate "Cirrus Logic CS35L41 CODEC (I2C)" + depends on I2C ++ select SND_SOC_CS35L41_LIB ++ select SND_SOC_CS35L41 + select REGMAP_I2C + + config SND_SOC_CS42L42 +diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile +index 8dbdf3518bda..ac7f20972470 100644 +--- a/sound/soc/codecs/Makefile ++++ b/sound/soc/codecs/Makefile +@@ -55,7 +55,8 @@ snd-soc-cs35l33-objs := cs35l33.o + snd-soc-cs35l34-objs := cs35l34.o + snd-soc-cs35l35-objs := cs35l35.o + snd-soc-cs35l36-objs := cs35l36.o +-snd-soc-cs35l41-objs := cs35l41.o cs35l41-tables.o ++snd-soc-cs35l41-lib-objs := cs35l41-lib.o ++snd-soc-cs35l41-objs := cs35l41.o + snd-soc-cs35l41-spi-objs := cs35l41-spi.o + snd-soc-cs35l41-i2c-objs := cs35l41-i2c.o + snd-soc-cs42l42-objs := cs42l42.o +@@ -396,6 +397,7 @@ obj-$(CONFIG_SND_SOC_CS35L34) += snd-soc-cs35l34.o + obj-$(CONFIG_SND_SOC_CS35L35) += snd-soc-cs35l35.o + obj-$(CONFIG_SND_SOC_CS35L36) += snd-soc-cs35l36.o + obj-$(CONFIG_SND_SOC_CS35L41) += snd-soc-cs35l41.o ++obj-$(CONFIG_SND_SOC_CS35L41_LIB) += snd-soc-cs35l41-lib.o + obj-$(CONFIG_SND_SOC_CS35L41_SPI) += snd-soc-cs35l41-spi.o + obj-$(CONFIG_SND_SOC_CS35L41_I2C) += snd-soc-cs35l41-i2c.o + obj-$(CONFIG_SND_SOC_CS42L42) += snd-soc-cs42l42.o +diff --git a/sound/soc/codecs/cs35l41-i2c.c b/sound/soc/codecs/cs35l41-i2c.c +index c9b604af6b71..de5c8612f030 100644 +--- a/sound/soc/codecs/cs35l41-i2c.c ++++ b/sound/soc/codecs/cs35l41-i2c.c +@@ -17,7 +17,6 @@ + #include + #include + +-#include + #include "cs35l41.h" + + static const struct i2c_device_id cs35l41_id_i2c[] = { +diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c +new file mode 100644 +index 000000000000..f19531ebf729 +--- /dev/null ++++ b/sound/soc/codecs/cs35l41-lib.c +@@ -0,0 +1,733 @@ ++// SPDX-License-Identifier: GPL-2.0 ++// ++// cs35l41-lib.c -- CS35L41 Common functions for HDA and ASoC Audio drivers ++// ++// Copyright 2017-2021 Cirrus Logic, Inc. ++// ++// Author: David Rhodes ++// Author: Lucas Tanure ++ ++#include ++#include ++ ++#include ++ ++static const struct reg_default cs35l41_reg[] = { ++ { CS35L41_PWR_CTRL1, 0x00000000 }, ++ { CS35L41_PWR_CTRL3, 0x01000010 }, ++ { CS35L41_GPIO_PAD_CONTROL, 0x00000000 }, ++ { CS35L41_SP_ENABLES, 0x00000000 }, ++ { CS35L41_SP_RATE_CTRL, 0x00000028 }, ++ { CS35L41_SP_FORMAT, 0x18180200 }, ++ { CS35L41_SP_HIZ_CTRL, 0x00000002 }, ++ { CS35L41_SP_FRAME_TX_SLOT, 0x03020100 }, ++ { CS35L41_SP_FRAME_RX_SLOT, 0x00000100 }, ++ { CS35L41_SP_TX_WL, 0x00000018 }, ++ { CS35L41_SP_RX_WL, 0x00000018 }, ++ { CS35L41_DAC_PCM1_SRC, 0x00000008 }, ++ { CS35L41_ASP_TX1_SRC, 0x00000018 }, ++ { CS35L41_ASP_TX2_SRC, 0x00000019 }, ++ { CS35L41_ASP_TX3_SRC, 0x00000020 }, ++ { CS35L41_ASP_TX4_SRC, 0x00000021 }, ++ { CS35L41_DSP1_RX1_SRC, 0x00000008 }, ++ { CS35L41_DSP1_RX2_SRC, 0x00000009 }, ++ { CS35L41_DSP1_RX3_SRC, 0x00000018 }, ++ { CS35L41_DSP1_RX4_SRC, 0x00000019 }, ++ { CS35L41_DSP1_RX5_SRC, 0x00000020 }, ++ { CS35L41_DSP1_RX6_SRC, 0x00000021 }, ++ { CS35L41_DSP1_RX7_SRC, 0x0000003A }, ++ { CS35L41_DSP1_RX8_SRC, 0x00000001 }, ++ { CS35L41_NGATE1_SRC, 0x00000008 }, ++ { CS35L41_NGATE2_SRC, 0x00000009 }, ++ { CS35L41_AMP_DIG_VOL_CTRL, 0x00008000 }, ++ { CS35L41_CLASSH_CFG, 0x000B0405 }, ++ { CS35L41_WKFET_CFG, 0x00000111 }, ++ { CS35L41_NG_CFG, 0x00000033 }, ++ { CS35L41_AMP_GAIN_CTRL, 0x00000273 }, ++ { CS35L41_GPIO1_CTRL1, 0xE1000001 }, ++ { CS35L41_GPIO2_CTRL1, 0xE1000001 }, ++ { CS35L41_MIXER_NGATE_CFG, 0x00000000 }, ++ { CS35L41_MIXER_NGATE_CH1_CFG, 0x00000303 }, ++ { CS35L41_MIXER_NGATE_CH2_CFG, 0x00000303 }, ++}; ++ ++static bool cs35l41_readable_reg(struct device *dev, unsigned int reg) ++{ ++ switch (reg) { ++ case CS35L41_DEVID: ++ case CS35L41_REVID: ++ case CS35L41_FABID: ++ case CS35L41_RELID: ++ case CS35L41_OTPID: ++ case CS35L41_TEST_KEY_CTL: ++ case CS35L41_USER_KEY_CTL: ++ case CS35L41_OTP_CTRL0: ++ case CS35L41_OTP_CTRL3: ++ case CS35L41_OTP_CTRL4: ++ case CS35L41_OTP_CTRL5: ++ case CS35L41_OTP_CTRL6: ++ case CS35L41_OTP_CTRL7: ++ case CS35L41_OTP_CTRL8: ++ case CS35L41_PWR_CTRL1: ++ case CS35L41_PWR_CTRL2: ++ case CS35L41_PWR_CTRL3: ++ case CS35L41_CTRL_OVRRIDE: ++ case CS35L41_AMP_OUT_MUTE: ++ case CS35L41_PROTECT_REL_ERR_IGN: ++ case CS35L41_GPIO_PAD_CONTROL: ++ case CS35L41_JTAG_CONTROL: ++ case CS35L41_PLL_CLK_CTRL: ++ case CS35L41_DSP_CLK_CTRL: ++ case CS35L41_GLOBAL_CLK_CTRL: ++ case CS35L41_DATA_FS_SEL: ++ case CS35L41_MDSYNC_EN: ++ case CS35L41_MDSYNC_TX_ID: ++ case CS35L41_MDSYNC_PWR_CTRL: ++ case CS35L41_MDSYNC_DATA_TX: ++ case CS35L41_MDSYNC_TX_STATUS: ++ case CS35L41_MDSYNC_DATA_RX: ++ case CS35L41_MDSYNC_RX_STATUS: ++ case CS35L41_MDSYNC_ERR_STATUS: ++ case CS35L41_MDSYNC_SYNC_PTE2: ++ case CS35L41_MDSYNC_SYNC_PTE3: ++ case CS35L41_MDSYNC_SYNC_MSM_STATUS: ++ case CS35L41_BSTCVRT_VCTRL1: ++ case CS35L41_BSTCVRT_VCTRL2: ++ case CS35L41_BSTCVRT_PEAK_CUR: ++ case CS35L41_BSTCVRT_SFT_RAMP: ++ case CS35L41_BSTCVRT_COEFF: ++ case CS35L41_BSTCVRT_SLOPE_LBST: ++ case CS35L41_BSTCVRT_SW_FREQ: ++ case CS35L41_BSTCVRT_DCM_CTRL: ++ case CS35L41_BSTCVRT_DCM_MODE_FORCE: ++ case CS35L41_BSTCVRT_OVERVOLT_CTRL: ++ case CS35L41_VI_VOL_POL: ++ case CS35L41_DTEMP_WARN_THLD: ++ case CS35L41_DTEMP_CFG: ++ case CS35L41_DTEMP_EN: ++ case CS35L41_VPVBST_FS_SEL: ++ case CS35L41_SP_ENABLES: ++ case CS35L41_SP_RATE_CTRL: ++ case CS35L41_SP_FORMAT: ++ case CS35L41_SP_HIZ_CTRL: ++ case CS35L41_SP_FRAME_TX_SLOT: ++ case CS35L41_SP_FRAME_RX_SLOT: ++ case CS35L41_SP_TX_WL: ++ case CS35L41_SP_RX_WL: ++ case CS35L41_DAC_PCM1_SRC: ++ case CS35L41_ASP_TX1_SRC: ++ case CS35L41_ASP_TX2_SRC: ++ case CS35L41_ASP_TX3_SRC: ++ case CS35L41_ASP_TX4_SRC: ++ case CS35L41_DSP1_RX1_SRC: ++ case CS35L41_DSP1_RX2_SRC: ++ case CS35L41_DSP1_RX3_SRC: ++ case CS35L41_DSP1_RX4_SRC: ++ case CS35L41_DSP1_RX5_SRC: ++ case CS35L41_DSP1_RX6_SRC: ++ case CS35L41_DSP1_RX7_SRC: ++ case CS35L41_DSP1_RX8_SRC: ++ case CS35L41_NGATE1_SRC: ++ case CS35L41_NGATE2_SRC: ++ case CS35L41_AMP_DIG_VOL_CTRL: ++ case CS35L41_VPBR_CFG: ++ case CS35L41_VBBR_CFG: ++ case CS35L41_VPBR_STATUS: ++ case CS35L41_VBBR_STATUS: ++ case CS35L41_OVERTEMP_CFG: ++ case CS35L41_AMP_ERR_VOL: ++ case CS35L41_VOL_STATUS_TO_DSP: ++ case CS35L41_CLASSH_CFG: ++ case CS35L41_WKFET_CFG: ++ case CS35L41_NG_CFG: ++ case CS35L41_AMP_GAIN_CTRL: ++ case CS35L41_DAC_MSM_CFG: ++ case CS35L41_IRQ1_CFG: ++ case CS35L41_IRQ1_STATUS: ++ case CS35L41_IRQ1_STATUS1: ++ case CS35L41_IRQ1_STATUS2: ++ case CS35L41_IRQ1_STATUS3: ++ case CS35L41_IRQ1_STATUS4: ++ case CS35L41_IRQ1_RAW_STATUS1: ++ case CS35L41_IRQ1_RAW_STATUS2: ++ case CS35L41_IRQ1_RAW_STATUS3: ++ case CS35L41_IRQ1_RAW_STATUS4: ++ case CS35L41_IRQ1_MASK1: ++ case CS35L41_IRQ1_MASK2: ++ case CS35L41_IRQ1_MASK3: ++ case CS35L41_IRQ1_MASK4: ++ case CS35L41_IRQ1_FRC1: ++ case CS35L41_IRQ1_FRC2: ++ case CS35L41_IRQ1_FRC3: ++ case CS35L41_IRQ1_FRC4: ++ case CS35L41_IRQ1_EDGE1: ++ case CS35L41_IRQ1_EDGE4: ++ case CS35L41_IRQ1_POL1: ++ case CS35L41_IRQ1_POL2: ++ case CS35L41_IRQ1_POL3: ++ case CS35L41_IRQ1_POL4: ++ case CS35L41_IRQ1_DB3: ++ case CS35L41_IRQ2_CFG: ++ case CS35L41_IRQ2_STATUS: ++ case CS35L41_IRQ2_STATUS1: ++ case CS35L41_IRQ2_STATUS2: ++ case CS35L41_IRQ2_STATUS3: ++ case CS35L41_IRQ2_STATUS4: ++ case CS35L41_IRQ2_RAW_STATUS1: ++ case CS35L41_IRQ2_RAW_STATUS2: ++ case CS35L41_IRQ2_RAW_STATUS3: ++ case CS35L41_IRQ2_RAW_STATUS4: ++ case CS35L41_IRQ2_MASK1: ++ case CS35L41_IRQ2_MASK2: ++ case CS35L41_IRQ2_MASK3: ++ case CS35L41_IRQ2_MASK4: ++ case CS35L41_IRQ2_FRC1: ++ case CS35L41_IRQ2_FRC2: ++ case CS35L41_IRQ2_FRC3: ++ case CS35L41_IRQ2_FRC4: ++ case CS35L41_IRQ2_EDGE1: ++ case CS35L41_IRQ2_EDGE4: ++ case CS35L41_IRQ2_POL1: ++ case CS35L41_IRQ2_POL2: ++ case CS35L41_IRQ2_POL3: ++ case CS35L41_IRQ2_POL4: ++ case CS35L41_IRQ2_DB3: ++ case CS35L41_GPIO_STATUS1: ++ case CS35L41_GPIO1_CTRL1: ++ case CS35L41_GPIO2_CTRL1: ++ case CS35L41_MIXER_NGATE_CFG: ++ case CS35L41_MIXER_NGATE_CH1_CFG: ++ case CS35L41_MIXER_NGATE_CH2_CFG: ++ case CS35L41_DSP_MBOX_1 ... CS35L41_DSP_VIRT2_MBOX_8: ++ case CS35L41_CLOCK_DETECT_1: ++ case CS35L41_DIE_STS1: ++ case CS35L41_DIE_STS2: ++ case CS35L41_TEMP_CAL1: ++ case CS35L41_TEMP_CAL2: ++ case CS35L41_DSP1_TIMESTAMP_COUNT: ++ case CS35L41_DSP1_SYS_ID: ++ case CS35L41_DSP1_SYS_VERSION: ++ case CS35L41_DSP1_SYS_CORE_ID: ++ case CS35L41_DSP1_SYS_AHB_ADDR: ++ case CS35L41_DSP1_SYS_XSRAM_SIZE: ++ case CS35L41_DSP1_SYS_YSRAM_SIZE: ++ case CS35L41_DSP1_SYS_PSRAM_SIZE: ++ case CS35L41_DSP1_SYS_PM_BOOT_SIZE: ++ case CS35L41_DSP1_SYS_FEATURES: ++ case CS35L41_DSP1_SYS_FIR_FILTERS: ++ case CS35L41_DSP1_SYS_LMS_FILTERS: ++ case CS35L41_DSP1_SYS_XM_BANK_SIZE: ++ case CS35L41_DSP1_SYS_YM_BANK_SIZE: ++ case CS35L41_DSP1_SYS_PM_BANK_SIZE: ++ case CS35L41_DSP1_RX1_RATE: ++ case CS35L41_DSP1_RX2_RATE: ++ case CS35L41_DSP1_RX3_RATE: ++ case CS35L41_DSP1_RX4_RATE: ++ case CS35L41_DSP1_RX5_RATE: ++ case CS35L41_DSP1_RX6_RATE: ++ case CS35L41_DSP1_RX7_RATE: ++ case CS35L41_DSP1_RX8_RATE: ++ case CS35L41_DSP1_TX1_RATE: ++ case CS35L41_DSP1_TX2_RATE: ++ case CS35L41_DSP1_TX3_RATE: ++ case CS35L41_DSP1_TX4_RATE: ++ case CS35L41_DSP1_TX5_RATE: ++ case CS35L41_DSP1_TX6_RATE: ++ case CS35L41_DSP1_TX7_RATE: ++ case CS35L41_DSP1_TX8_RATE: ++ case CS35L41_DSP1_SCRATCH1: ++ case CS35L41_DSP1_SCRATCH2: ++ case CS35L41_DSP1_SCRATCH3: ++ case CS35L41_DSP1_SCRATCH4: ++ case CS35L41_DSP1_CCM_CORE_CTRL: ++ case CS35L41_DSP1_CCM_CLK_OVERRIDE: ++ case CS35L41_DSP1_XM_MSTR_EN: ++ case CS35L41_DSP1_XM_CORE_PRI: ++ case CS35L41_DSP1_XM_AHB_PACK_PL_PRI: ++ case CS35L41_DSP1_XM_AHB_UP_PL_PRI: ++ case CS35L41_DSP1_XM_ACCEL_PL0_PRI: ++ case CS35L41_DSP1_XM_NPL0_PRI: ++ case CS35L41_DSP1_YM_MSTR_EN: ++ case CS35L41_DSP1_YM_CORE_PRI: ++ case CS35L41_DSP1_YM_AHB_PACK_PL_PRI: ++ case CS35L41_DSP1_YM_AHB_UP_PL_PRI: ++ case CS35L41_DSP1_YM_ACCEL_PL0_PRI: ++ case CS35L41_DSP1_YM_NPL0_PRI: ++ case CS35L41_DSP1_MPU_XM_ACCESS0: ++ case CS35L41_DSP1_MPU_YM_ACCESS0: ++ case CS35L41_DSP1_MPU_WNDW_ACCESS0: ++ case CS35L41_DSP1_MPU_XREG_ACCESS0: ++ case CS35L41_DSP1_MPU_YREG_ACCESS0: ++ case CS35L41_DSP1_MPU_XM_ACCESS1: ++ case CS35L41_DSP1_MPU_YM_ACCESS1: ++ case CS35L41_DSP1_MPU_WNDW_ACCESS1: ++ case CS35L41_DSP1_MPU_XREG_ACCESS1: ++ case CS35L41_DSP1_MPU_YREG_ACCESS1: ++ case CS35L41_DSP1_MPU_XM_ACCESS2: ++ case CS35L41_DSP1_MPU_YM_ACCESS2: ++ case CS35L41_DSP1_MPU_WNDW_ACCESS2: ++ case CS35L41_DSP1_MPU_XREG_ACCESS2: ++ case CS35L41_DSP1_MPU_YREG_ACCESS2: ++ case CS35L41_DSP1_MPU_XM_ACCESS3: ++ case CS35L41_DSP1_MPU_YM_ACCESS3: ++ case CS35L41_DSP1_MPU_WNDW_ACCESS3: ++ case CS35L41_DSP1_MPU_XREG_ACCESS3: ++ case CS35L41_DSP1_MPU_YREG_ACCESS3: ++ case CS35L41_DSP1_MPU_XM_VIO_ADDR: ++ case CS35L41_DSP1_MPU_XM_VIO_STATUS: ++ case CS35L41_DSP1_MPU_YM_VIO_ADDR: ++ case CS35L41_DSP1_MPU_YM_VIO_STATUS: ++ case CS35L41_DSP1_MPU_PM_VIO_ADDR: ++ case CS35L41_DSP1_MPU_PM_VIO_STATUS: ++ case CS35L41_DSP1_MPU_LOCK_CONFIG: ++ case CS35L41_DSP1_MPU_WDT_RST_CTRL: ++ case CS35L41_OTP_TRIM_1: ++ case CS35L41_OTP_TRIM_2: ++ case CS35L41_OTP_TRIM_3: ++ case CS35L41_OTP_TRIM_4: ++ case CS35L41_OTP_TRIM_5: ++ case CS35L41_OTP_TRIM_6: ++ case CS35L41_OTP_TRIM_7: ++ case CS35L41_OTP_TRIM_8: ++ case CS35L41_OTP_TRIM_9: ++ case CS35L41_OTP_TRIM_10: ++ case CS35L41_OTP_TRIM_11: ++ case CS35L41_OTP_TRIM_12: ++ case CS35L41_OTP_TRIM_13: ++ case CS35L41_OTP_TRIM_14: ++ case CS35L41_OTP_TRIM_15: ++ case CS35L41_OTP_TRIM_16: ++ case CS35L41_OTP_TRIM_17: ++ case CS35L41_OTP_TRIM_18: ++ case CS35L41_OTP_TRIM_19: ++ case CS35L41_OTP_TRIM_20: ++ case CS35L41_OTP_TRIM_21: ++ case CS35L41_OTP_TRIM_22: ++ case CS35L41_OTP_TRIM_23: ++ case CS35L41_OTP_TRIM_24: ++ case CS35L41_OTP_TRIM_25: ++ case CS35L41_OTP_TRIM_26: ++ case CS35L41_OTP_TRIM_27: ++ case CS35L41_OTP_TRIM_28: ++ case CS35L41_OTP_TRIM_29: ++ case CS35L41_OTP_TRIM_30: ++ case CS35L41_OTP_TRIM_31: ++ case CS35L41_OTP_TRIM_32: ++ case CS35L41_OTP_TRIM_33: ++ case CS35L41_OTP_TRIM_34: ++ case CS35L41_OTP_TRIM_35: ++ case CS35L41_OTP_TRIM_36: ++ case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31: ++ case CS35L41_DSP1_XMEM_PACK_0 ... CS35L41_DSP1_XMEM_PACK_3068: ++ case CS35L41_DSP1_XMEM_UNPACK32_0 ... CS35L41_DSP1_XMEM_UNPACK32_2046: ++ case CS35L41_DSP1_XMEM_UNPACK24_0 ... CS35L41_DSP1_XMEM_UNPACK24_4093: ++ case CS35L41_DSP1_YMEM_PACK_0 ... CS35L41_DSP1_YMEM_PACK_1532: ++ case CS35L41_DSP1_YMEM_UNPACK32_0 ... CS35L41_DSP1_YMEM_UNPACK32_1022: ++ case CS35L41_DSP1_YMEM_UNPACK24_0 ... CS35L41_DSP1_YMEM_UNPACK24_2045: ++ case CS35L41_DSP1_PMEM_0 ... CS35L41_DSP1_PMEM_5114: ++ /*test regs*/ ++ case CS35L41_PLL_OVR: ++ case CS35L41_BST_TEST_DUTY: ++ case CS35L41_DIGPWM_IOCTRL: ++ return true; ++ default: ++ return false; ++ } ++} ++ ++static bool cs35l41_precious_reg(struct device *dev, unsigned int reg) ++{ ++ switch (reg) { ++ case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31: ++ case CS35L41_DSP1_XMEM_PACK_0 ... CS35L41_DSP1_XMEM_PACK_3068: ++ case CS35L41_DSP1_YMEM_PACK_0 ... CS35L41_DSP1_YMEM_PACK_1532: ++ case CS35L41_DSP1_PMEM_0 ... CS35L41_DSP1_PMEM_5114: ++ return true; ++ default: ++ return false; ++ } ++} ++ ++static bool cs35l41_volatile_reg(struct device *dev, unsigned int reg) ++{ ++ switch (reg) { ++ case CS35L41_DEVID: ++ case CS35L41_SFT_RESET: ++ case CS35L41_FABID: ++ case CS35L41_REVID: ++ case CS35L41_DTEMP_EN: ++ case CS35L41_IRQ1_STATUS: ++ case CS35L41_IRQ1_STATUS1: ++ case CS35L41_IRQ1_STATUS2: ++ case CS35L41_IRQ1_STATUS3: ++ case CS35L41_IRQ1_STATUS4: ++ case CS35L41_IRQ1_RAW_STATUS1: ++ case CS35L41_IRQ1_RAW_STATUS2: ++ case CS35L41_IRQ1_RAW_STATUS3: ++ case CS35L41_IRQ1_RAW_STATUS4: ++ case CS35L41_IRQ1_FRC1: ++ case CS35L41_IRQ1_FRC2: ++ case CS35L41_IRQ1_FRC3: ++ case CS35L41_IRQ1_FRC4: ++ case CS35L41_IRQ1_EDGE1: ++ case CS35L41_IRQ1_EDGE4: ++ case CS35L41_IRQ1_POL1: ++ case CS35L41_IRQ1_POL2: ++ case CS35L41_IRQ1_POL3: ++ case CS35L41_IRQ1_POL4: ++ case CS35L41_IRQ1_DB3: ++ case CS35L41_IRQ2_STATUS: ++ case CS35L41_IRQ2_STATUS1: ++ case CS35L41_IRQ2_STATUS2: ++ case CS35L41_IRQ2_STATUS3: ++ case CS35L41_IRQ2_STATUS4: ++ case CS35L41_IRQ2_RAW_STATUS1: ++ case CS35L41_IRQ2_RAW_STATUS2: ++ case CS35L41_IRQ2_RAW_STATUS3: ++ case CS35L41_IRQ2_RAW_STATUS4: ++ case CS35L41_IRQ2_FRC1: ++ case CS35L41_IRQ2_FRC2: ++ case CS35L41_IRQ2_FRC3: ++ case CS35L41_IRQ2_FRC4: ++ case CS35L41_IRQ2_EDGE1: ++ case CS35L41_IRQ2_EDGE4: ++ case CS35L41_IRQ2_POL1: ++ case CS35L41_IRQ2_POL2: ++ case CS35L41_IRQ2_POL3: ++ case CS35L41_IRQ2_POL4: ++ case CS35L41_IRQ2_DB3: ++ case CS35L41_GPIO_STATUS1: ++ case CS35L41_OTP_TRIM_1: ++ case CS35L41_OTP_TRIM_2: ++ case CS35L41_OTP_TRIM_3: ++ case CS35L41_OTP_TRIM_4: ++ case CS35L41_OTP_TRIM_5: ++ case CS35L41_OTP_TRIM_6: ++ case CS35L41_OTP_TRIM_7: ++ case CS35L41_OTP_TRIM_8: ++ case CS35L41_OTP_TRIM_9: ++ case CS35L41_OTP_TRIM_10: ++ case CS35L41_OTP_TRIM_11: ++ case CS35L41_OTP_TRIM_12: ++ case CS35L41_OTP_TRIM_13: ++ case CS35L41_OTP_TRIM_14: ++ case CS35L41_OTP_TRIM_15: ++ case CS35L41_OTP_TRIM_16: ++ case CS35L41_OTP_TRIM_17: ++ case CS35L41_OTP_TRIM_18: ++ case CS35L41_OTP_TRIM_19: ++ case CS35L41_OTP_TRIM_20: ++ case CS35L41_OTP_TRIM_21: ++ case CS35L41_OTP_TRIM_22: ++ case CS35L41_OTP_TRIM_23: ++ case CS35L41_OTP_TRIM_24: ++ case CS35L41_OTP_TRIM_25: ++ case CS35L41_OTP_TRIM_26: ++ case CS35L41_OTP_TRIM_27: ++ case CS35L41_OTP_TRIM_28: ++ case CS35L41_OTP_TRIM_29: ++ case CS35L41_OTP_TRIM_30: ++ case CS35L41_OTP_TRIM_31: ++ case CS35L41_OTP_TRIM_32: ++ case CS35L41_OTP_TRIM_33: ++ case CS35L41_OTP_TRIM_34: ++ case CS35L41_OTP_TRIM_35: ++ case CS35L41_OTP_TRIM_36: ++ case CS35L41_DSP_MBOX_1 ... CS35L41_DSP_VIRT2_MBOX_8: ++ case CS35L41_DSP1_XMEM_PACK_0 ... CS35L41_DSP1_XMEM_PACK_3068: ++ case CS35L41_DSP1_XMEM_UNPACK32_0 ... CS35L41_DSP1_XMEM_UNPACK32_2046: ++ case CS35L41_DSP1_XMEM_UNPACK24_0 ... CS35L41_DSP1_XMEM_UNPACK24_4093: ++ case CS35L41_DSP1_YMEM_PACK_0 ... CS35L41_DSP1_YMEM_PACK_1532: ++ case CS35L41_DSP1_YMEM_UNPACK32_0 ... CS35L41_DSP1_YMEM_UNPACK32_1022: ++ case CS35L41_DSP1_YMEM_UNPACK24_0 ... CS35L41_DSP1_YMEM_UNPACK24_2045: ++ case CS35L41_DSP1_PMEM_0 ... CS35L41_DSP1_PMEM_5114: ++ case CS35L41_DSP1_CCM_CORE_CTRL ... CS35L41_DSP1_WDT_STATUS: ++ case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31: ++ return true; ++ default: ++ return false; ++ } ++} ++ ++static const struct cs35l41_otp_packed_element_t otp_map_1[CS35L41_NUM_OTP_ELEM] = { ++ /* addr shift size */ ++ { 0x00002030, 0, 4 }, /*TRIM_OSC_FREQ_TRIM*/ ++ { 0x00002030, 7, 1 }, /*TRIM_OSC_TRIM_DONE*/ ++ { 0x0000208c, 24, 6 }, /*TST_DIGREG_VREF_TRIM*/ ++ { 0x00002090, 14, 4 }, /*TST_REF_TRIM*/ ++ { 0x00002090, 10, 4 }, /*TST_REF_TEMPCO_TRIM*/ ++ { 0x0000300C, 11, 4 }, /*PLL_LDOA_TST_VREF_TRIM*/ ++ { 0x0000394C, 23, 2 }, /*BST_ATEST_CM_VOFF*/ ++ { 0x00003950, 0, 7 }, /*BST_ATRIM_IADC_OFFSET*/ ++ { 0x00003950, 8, 7 }, /*BST_ATRIM_IADC_GAIN1*/ ++ { 0x00003950, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET1*/ ++ { 0x00003950, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN1*/ ++ { 0x00003954, 0, 7 }, /*BST_ATRIM_IADC_OFFSET2*/ ++ { 0x00003954, 8, 7 }, /*BST_ATRIM_IADC_GAIN2*/ ++ { 0x00003954, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET2*/ ++ { 0x00003954, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN2*/ ++ { 0x00003958, 0, 7 }, /*BST_ATRIM_IADC_OFFSET3*/ ++ { 0x00003958, 8, 7 }, /*BST_ATRIM_IADC_GAIN3*/ ++ { 0x00003958, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET3*/ ++ { 0x00003958, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN3*/ ++ { 0x0000395C, 0, 7 }, /*BST_ATRIM_IADC_OFFSET4*/ ++ { 0x0000395C, 8, 7 }, /*BST_ATRIM_IADC_GAIN4*/ ++ { 0x0000395C, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET4*/ ++ { 0x0000395C, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN4*/ ++ { 0x0000416C, 0, 8 }, /*VMON_GAIN_OTP_VAL*/ ++ { 0x00004160, 0, 7 }, /*VMON_OFFSET_OTP_VAL*/ ++ { 0x0000416C, 8, 8 }, /*IMON_GAIN_OTP_VAL*/ ++ { 0x00004160, 16, 10 }, /*IMON_OFFSET_OTP_VAL*/ ++ { 0x0000416C, 16, 12 }, /*VMON_CM_GAIN_OTP_VAL*/ ++ { 0x0000416C, 28, 1 }, /*VMON_CM_GAIN_SIGN_OTP_VAL*/ ++ { 0x00004170, 0, 6 }, /*IMON_CAL_TEMPCO_OTP_VAL*/ ++ { 0x00004170, 6, 1 }, /*IMON_CAL_TEMPCO_SIGN_OTP*/ ++ { 0x00004170, 8, 6 }, /*IMON_CAL_TEMPCO2_OTP_VAL*/ ++ { 0x00004170, 14, 1 }, /*IMON_CAL_TEMPCO2_DN_UPB_OTP_VAL*/ ++ { 0x00004170, 16, 9 }, /*IMON_CAL_TEMPCO_TBASE_OTP_VAL*/ ++ { 0x00004360, 0, 5 }, /*TEMP_GAIN_OTP_VAL*/ ++ { 0x00004360, 6, 9 }, /*TEMP_OFFSET_OTP_VAL*/ ++ { 0x00004448, 0, 8 }, /*VP_SARADC_OFFSET*/ ++ { 0x00004448, 8, 8 }, /*VP_GAIN_INDEX*/ ++ { 0x00004448, 16, 8 }, /*VBST_SARADC_OFFSET*/ ++ { 0x00004448, 24, 8 }, /*VBST_GAIN_INDEX*/ ++ { 0x0000444C, 0, 3 }, /*ANA_SELINVREF*/ ++ { 0x00006E30, 0, 5 }, /*GAIN_ERR_COEFF_0*/ ++ { 0x00006E30, 8, 5 }, /*GAIN_ERR_COEFF_1*/ ++ { 0x00006E30, 16, 5 }, /*GAIN_ERR_COEFF_2*/ ++ { 0x00006E30, 24, 5 }, /*GAIN_ERR_COEFF_3*/ ++ { 0x00006E34, 0, 5 }, /*GAIN_ERR_COEFF_4*/ ++ { 0x00006E34, 8, 5 }, /*GAIN_ERR_COEFF_5*/ ++ { 0x00006E34, 16, 5 }, /*GAIN_ERR_COEFF_6*/ ++ { 0x00006E34, 24, 5 }, /*GAIN_ERR_COEFF_7*/ ++ { 0x00006E38, 0, 5 }, /*GAIN_ERR_COEFF_8*/ ++ { 0x00006E38, 8, 5 }, /*GAIN_ERR_COEFF_9*/ ++ { 0x00006E38, 16, 5 }, /*GAIN_ERR_COEFF_10*/ ++ { 0x00006E38, 24, 5 }, /*GAIN_ERR_COEFF_11*/ ++ { 0x00006E3C, 0, 5 }, /*GAIN_ERR_COEFF_12*/ ++ { 0x00006E3C, 8, 5 }, /*GAIN_ERR_COEFF_13*/ ++ { 0x00006E3C, 16, 5 }, /*GAIN_ERR_COEFF_14*/ ++ { 0x00006E3C, 24, 5 }, /*GAIN_ERR_COEFF_15*/ ++ { 0x00006E40, 0, 5 }, /*GAIN_ERR_COEFF_16*/ ++ { 0x00006E40, 8, 5 }, /*GAIN_ERR_COEFF_17*/ ++ { 0x00006E40, 16, 5 }, /*GAIN_ERR_COEFF_18*/ ++ { 0x00006E40, 24, 5 }, /*GAIN_ERR_COEFF_19*/ ++ { 0x00006E44, 0, 5 }, /*GAIN_ERR_COEFF_20*/ ++ { 0x00006E48, 0, 10 }, /*VOFF_GAIN_0*/ ++ { 0x00006E48, 10, 10 }, /*VOFF_GAIN_1*/ ++ { 0x00006E48, 20, 10 }, /*VOFF_GAIN_2*/ ++ { 0x00006E4C, 0, 10 }, /*VOFF_GAIN_3*/ ++ { 0x00006E4C, 10, 10 }, /*VOFF_GAIN_4*/ ++ { 0x00006E4C, 20, 10 }, /*VOFF_GAIN_5*/ ++ { 0x00006E50, 0, 10 }, /*VOFF_GAIN_6*/ ++ { 0x00006E50, 10, 10 }, /*VOFF_GAIN_7*/ ++ { 0x00006E50, 20, 10 }, /*VOFF_GAIN_8*/ ++ { 0x00006E54, 0, 10 }, /*VOFF_GAIN_9*/ ++ { 0x00006E54, 10, 10 }, /*VOFF_GAIN_10*/ ++ { 0x00006E54, 20, 10 }, /*VOFF_GAIN_11*/ ++ { 0x00006E58, 0, 10 }, /*VOFF_GAIN_12*/ ++ { 0x00006E58, 10, 10 }, /*VOFF_GAIN_13*/ ++ { 0x00006E58, 20, 10 }, /*VOFF_GAIN_14*/ ++ { 0x00006E5C, 0, 10 }, /*VOFF_GAIN_15*/ ++ { 0x00006E5C, 10, 10 }, /*VOFF_GAIN_16*/ ++ { 0x00006E5C, 20, 10 }, /*VOFF_GAIN_17*/ ++ { 0x00006E60, 0, 10 }, /*VOFF_GAIN_18*/ ++ { 0x00006E60, 10, 10 }, /*VOFF_GAIN_19*/ ++ { 0x00006E60, 20, 10 }, /*VOFF_GAIN_20*/ ++ { 0x00006E64, 0, 10 }, /*VOFF_INT1*/ ++ { 0x00007418, 7, 5 }, /*DS_SPK_INT1_CAP_TRIM*/ ++ { 0x0000741C, 0, 5 }, /*DS_SPK_INT2_CAP_TRIM*/ ++ { 0x0000741C, 11, 4 }, /*DS_SPK_LPF_CAP_TRIM*/ ++ { 0x0000741C, 19, 4 }, /*DS_SPK_QUAN_CAP_TRIM*/ ++ { 0x00007434, 17, 1 }, /*FORCE_CAL*/ ++ { 0x00007434, 18, 7 }, /*CAL_OVERRIDE*/ ++ { 0x00007068, 0, 9 }, /*MODIX*/ ++ { 0x0000410C, 7, 1 }, /*VIMON_DLY_NOT_COMB*/ ++ { 0x0000400C, 0, 7 }, /*VIMON_DLY*/ ++ { 0x00000000, 0, 1 }, /*extra bit*/ ++ { 0x00017040, 0, 8 }, /*X_COORDINATE*/ ++ { 0x00017040, 8, 8 }, /*Y_COORDINATE*/ ++ { 0x00017040, 16, 8 }, /*WAFER_ID*/ ++ { 0x00017040, 24, 8 }, /*DVS*/ ++ { 0x00017044, 0, 24 }, /*LOT_NUMBER*/ ++}; ++ ++static const struct cs35l41_otp_packed_element_t otp_map_2[CS35L41_NUM_OTP_ELEM] = { ++ /* addr shift size */ ++ { 0x00002030, 0, 4 }, /*TRIM_OSC_FREQ_TRIM*/ ++ { 0x00002030, 7, 1 }, /*TRIM_OSC_TRIM_DONE*/ ++ { 0x0000208c, 24, 6 }, /*TST_DIGREG_VREF_TRIM*/ ++ { 0x00002090, 14, 4 }, /*TST_REF_TRIM*/ ++ { 0x00002090, 10, 4 }, /*TST_REF_TEMPCO_TRIM*/ ++ { 0x0000300C, 11, 4 }, /*PLL_LDOA_TST_VREF_TRIM*/ ++ { 0x0000394C, 23, 2 }, /*BST_ATEST_CM_VOFF*/ ++ { 0x00003950, 0, 7 }, /*BST_ATRIM_IADC_OFFSET*/ ++ { 0x00003950, 8, 7 }, /*BST_ATRIM_IADC_GAIN1*/ ++ { 0x00003950, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET1*/ ++ { 0x00003950, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN1*/ ++ { 0x00003954, 0, 7 }, /*BST_ATRIM_IADC_OFFSET2*/ ++ { 0x00003954, 8, 7 }, /*BST_ATRIM_IADC_GAIN2*/ ++ { 0x00003954, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET2*/ ++ { 0x00003954, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN2*/ ++ { 0x00003958, 0, 7 }, /*BST_ATRIM_IADC_OFFSET3*/ ++ { 0x00003958, 8, 7 }, /*BST_ATRIM_IADC_GAIN3*/ ++ { 0x00003958, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET3*/ ++ { 0x00003958, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN3*/ ++ { 0x0000395C, 0, 7 }, /*BST_ATRIM_IADC_OFFSET4*/ ++ { 0x0000395C, 8, 7 }, /*BST_ATRIM_IADC_GAIN4*/ ++ { 0x0000395C, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET4*/ ++ { 0x0000395C, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN4*/ ++ { 0x0000416C, 0, 8 }, /*VMON_GAIN_OTP_VAL*/ ++ { 0x00004160, 0, 7 }, /*VMON_OFFSET_OTP_VAL*/ ++ { 0x0000416C, 8, 8 }, /*IMON_GAIN_OTP_VAL*/ ++ { 0x00004160, 16, 10 }, /*IMON_OFFSET_OTP_VAL*/ ++ { 0x0000416C, 16, 12 }, /*VMON_CM_GAIN_OTP_VAL*/ ++ { 0x0000416C, 28, 1 }, /*VMON_CM_GAIN_SIGN_OTP_VAL*/ ++ { 0x00004170, 0, 6 }, /*IMON_CAL_TEMPCO_OTP_VAL*/ ++ { 0x00004170, 6, 1 }, /*IMON_CAL_TEMPCO_SIGN_OTP*/ ++ { 0x00004170, 8, 6 }, /*IMON_CAL_TEMPCO2_OTP_VAL*/ ++ { 0x00004170, 14, 1 }, /*IMON_CAL_TEMPCO2_DN_UPB_OTP_VAL*/ ++ { 0x00004170, 16, 9 }, /*IMON_CAL_TEMPCO_TBASE_OTP_VAL*/ ++ { 0x00004360, 0, 5 }, /*TEMP_GAIN_OTP_VAL*/ ++ { 0x00004360, 6, 9 }, /*TEMP_OFFSET_OTP_VAL*/ ++ { 0x00004448, 0, 8 }, /*VP_SARADC_OFFSET*/ ++ { 0x00004448, 8, 8 }, /*VP_GAIN_INDEX*/ ++ { 0x00004448, 16, 8 }, /*VBST_SARADC_OFFSET*/ ++ { 0x00004448, 24, 8 }, /*VBST_GAIN_INDEX*/ ++ { 0x0000444C, 0, 3 }, /*ANA_SELINVREF*/ ++ { 0x00006E30, 0, 5 }, /*GAIN_ERR_COEFF_0*/ ++ { 0x00006E30, 8, 5 }, /*GAIN_ERR_COEFF_1*/ ++ { 0x00006E30, 16, 5 }, /*GAIN_ERR_COEFF_2*/ ++ { 0x00006E30, 24, 5 }, /*GAIN_ERR_COEFF_3*/ ++ { 0x00006E34, 0, 5 }, /*GAIN_ERR_COEFF_4*/ ++ { 0x00006E34, 8, 5 }, /*GAIN_ERR_COEFF_5*/ ++ { 0x00006E34, 16, 5 }, /*GAIN_ERR_COEFF_6*/ ++ { 0x00006E34, 24, 5 }, /*GAIN_ERR_COEFF_7*/ ++ { 0x00006E38, 0, 5 }, /*GAIN_ERR_COEFF_8*/ ++ { 0x00006E38, 8, 5 }, /*GAIN_ERR_COEFF_9*/ ++ { 0x00006E38, 16, 5 }, /*GAIN_ERR_COEFF_10*/ ++ { 0x00006E38, 24, 5 }, /*GAIN_ERR_COEFF_11*/ ++ { 0x00006E3C, 0, 5 }, /*GAIN_ERR_COEFF_12*/ ++ { 0x00006E3C, 8, 5 }, /*GAIN_ERR_COEFF_13*/ ++ { 0x00006E3C, 16, 5 }, /*GAIN_ERR_COEFF_14*/ ++ { 0x00006E3C, 24, 5 }, /*GAIN_ERR_COEFF_15*/ ++ { 0x00006E40, 0, 5 }, /*GAIN_ERR_COEFF_16*/ ++ { 0x00006E40, 8, 5 }, /*GAIN_ERR_COEFF_17*/ ++ { 0x00006E40, 16, 5 }, /*GAIN_ERR_COEFF_18*/ ++ { 0x00006E40, 24, 5 }, /*GAIN_ERR_COEFF_19*/ ++ { 0x00006E44, 0, 5 }, /*GAIN_ERR_COEFF_20*/ ++ { 0x00006E48, 0, 10 }, /*VOFF_GAIN_0*/ ++ { 0x00006E48, 10, 10 }, /*VOFF_GAIN_1*/ ++ { 0x00006E48, 20, 10 }, /*VOFF_GAIN_2*/ ++ { 0x00006E4C, 0, 10 }, /*VOFF_GAIN_3*/ ++ { 0x00006E4C, 10, 10 }, /*VOFF_GAIN_4*/ ++ { 0x00006E4C, 20, 10 }, /*VOFF_GAIN_5*/ ++ { 0x00006E50, 0, 10 }, /*VOFF_GAIN_6*/ ++ { 0x00006E50, 10, 10 }, /*VOFF_GAIN_7*/ ++ { 0x00006E50, 20, 10 }, /*VOFF_GAIN_8*/ ++ { 0x00006E54, 0, 10 }, /*VOFF_GAIN_9*/ ++ { 0x00006E54, 10, 10 }, /*VOFF_GAIN_10*/ ++ { 0x00006E54, 20, 10 }, /*VOFF_GAIN_11*/ ++ { 0x00006E58, 0, 10 }, /*VOFF_GAIN_12*/ ++ { 0x00006E58, 10, 10 }, /*VOFF_GAIN_13*/ ++ { 0x00006E58, 20, 10 }, /*VOFF_GAIN_14*/ ++ { 0x00006E5C, 0, 10 }, /*VOFF_GAIN_15*/ ++ { 0x00006E5C, 10, 10 }, /*VOFF_GAIN_16*/ ++ { 0x00006E5C, 20, 10 }, /*VOFF_GAIN_17*/ ++ { 0x00006E60, 0, 10 }, /*VOFF_GAIN_18*/ ++ { 0x00006E60, 10, 10 }, /*VOFF_GAIN_19*/ ++ { 0x00006E60, 20, 10 }, /*VOFF_GAIN_20*/ ++ { 0x00006E64, 0, 10 }, /*VOFF_INT1*/ ++ { 0x00007418, 7, 5 }, /*DS_SPK_INT1_CAP_TRIM*/ ++ { 0x0000741C, 0, 5 }, /*DS_SPK_INT2_CAP_TRIM*/ ++ { 0x0000741C, 11, 4 }, /*DS_SPK_LPF_CAP_TRIM*/ ++ { 0x0000741C, 19, 4 }, /*DS_SPK_QUAN_CAP_TRIM*/ ++ { 0x00007434, 17, 1 }, /*FORCE_CAL*/ ++ { 0x00007434, 18, 7 }, /*CAL_OVERRIDE*/ ++ { 0x00007068, 0, 9 }, /*MODIX*/ ++ { 0x0000410C, 7, 1 }, /*VIMON_DLY_NOT_COMB*/ ++ { 0x0000400C, 0, 7 }, /*VIMON_DLY*/ ++ { 0x00004000, 11, 1 }, /*VMON_POL*/ ++ { 0x00017040, 0, 8 }, /*X_COORDINATE*/ ++ { 0x00017040, 8, 8 }, /*Y_COORDINATE*/ ++ { 0x00017040, 16, 8 }, /*WAFER_ID*/ ++ { 0x00017040, 24, 8 }, /*DVS*/ ++ { 0x00017044, 0, 24 }, /*LOT_NUMBER*/ ++}; ++ ++const struct cs35l41_otp_map_element_t cs35l41_otp_map_map[CS35L41_NUM_OTP_MAPS] = { ++ { ++ .id = 0x01, ++ .map = otp_map_1, ++ .num_elements = CS35L41_NUM_OTP_ELEM, ++ .bit_offset = 16, ++ .word_offset = 2, ++ }, ++ { ++ .id = 0x02, ++ .map = otp_map_2, ++ .num_elements = CS35L41_NUM_OTP_ELEM, ++ .bit_offset = 16, ++ .word_offset = 2, ++ }, ++ { ++ .id = 0x03, ++ .map = otp_map_2, ++ .num_elements = CS35L41_NUM_OTP_ELEM, ++ .bit_offset = 16, ++ .word_offset = 2, ++ }, ++ { ++ .id = 0x06, ++ .map = otp_map_2, ++ .num_elements = CS35L41_NUM_OTP_ELEM, ++ .bit_offset = 16, ++ .word_offset = 2, ++ }, ++ { ++ .id = 0x08, ++ .map = otp_map_1, ++ .num_elements = CS35L41_NUM_OTP_ELEM, ++ .bit_offset = 16, ++ .word_offset = 2, ++ }, ++}; ++EXPORT_SYMBOL_GPL(cs35l41_otp_map_map); ++ ++struct regmap_config cs35l41_regmap_i2c = { ++ .reg_bits = 32, ++ .val_bits = 32, ++ .reg_stride = CS35L41_REGSTRIDE, ++ .reg_format_endian = REGMAP_ENDIAN_BIG, ++ .val_format_endian = REGMAP_ENDIAN_BIG, ++ .max_register = CS35L41_LASTREG, ++ .reg_defaults = cs35l41_reg, ++ .num_reg_defaults = ARRAY_SIZE(cs35l41_reg), ++ .volatile_reg = cs35l41_volatile_reg, ++ .readable_reg = cs35l41_readable_reg, ++ .precious_reg = cs35l41_precious_reg, ++ .cache_type = REGCACHE_RBTREE, ++}; ++EXPORT_SYMBOL_GPL(cs35l41_regmap_i2c); ++ ++struct regmap_config cs35l41_regmap_spi = { ++ .reg_bits = 32, ++ .val_bits = 32, ++ .pad_bits = 16, ++ .reg_stride = CS35L41_REGSTRIDE, ++ .reg_format_endian = REGMAP_ENDIAN_BIG, ++ .val_format_endian = REGMAP_ENDIAN_BIG, ++ .max_register = CS35L41_LASTREG, ++ .reg_defaults = cs35l41_reg, ++ .num_reg_defaults = ARRAY_SIZE(cs35l41_reg), ++ .volatile_reg = cs35l41_volatile_reg, ++ .readable_reg = cs35l41_readable_reg, ++ .precious_reg = cs35l41_precious_reg, ++ .cache_type = REGCACHE_RBTREE, ++}; ++EXPORT_SYMBOL_GPL(cs35l41_regmap_spi); ++ ++MODULE_DESCRIPTION("CS35L41 library"); ++MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, "); ++MODULE_AUTHOR("Lucas Tanure, Cirrus Logic Inc, "); ++MODULE_LICENSE("GPL"); +diff --git a/sound/soc/codecs/cs35l41-spi.c b/sound/soc/codecs/cs35l41-spi.c +index c202d9df70ee..c157153f28d8 100644 +--- a/sound/soc/codecs/cs35l41-spi.c ++++ b/sound/soc/codecs/cs35l41-spi.c +@@ -15,7 +15,6 @@ + #include + #include + +-#include + #include "cs35l41.h" + + static const struct spi_device_id cs35l41_id_spi[] = { +diff --git a/sound/soc/codecs/cs35l41-tables.c b/sound/soc/codecs/cs35l41-tables.c +deleted file mode 100644 +index 3eb18b17a7b0..000000000000 +--- a/sound/soc/codecs/cs35l41-tables.c ++++ /dev/null +@@ -1,723 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0 +-// +-// cs35l41-tables.c -- CS35L41 ALSA SoC audio driver +-// +-// Copyright 2017-2021 Cirrus Logic, Inc. +-// +-// Author: David Rhodes +- +-#include "cs35l41.h" +- +-static const struct reg_default cs35l41_reg[] = { +- { CS35L41_PWR_CTRL1, 0x00000000 }, +- { CS35L41_PWR_CTRL3, 0x01000010 }, +- { CS35L41_GPIO_PAD_CONTROL, 0x00000000 }, +- { CS35L41_SP_ENABLES, 0x00000000 }, +- { CS35L41_SP_RATE_CTRL, 0x00000028 }, +- { CS35L41_SP_FORMAT, 0x18180200 }, +- { CS35L41_SP_HIZ_CTRL, 0x00000002 }, +- { CS35L41_SP_FRAME_TX_SLOT, 0x03020100 }, +- { CS35L41_SP_FRAME_RX_SLOT, 0x00000100 }, +- { CS35L41_SP_TX_WL, 0x00000018 }, +- { CS35L41_SP_RX_WL, 0x00000018 }, +- { CS35L41_DAC_PCM1_SRC, 0x00000008 }, +- { CS35L41_ASP_TX1_SRC, 0x00000018 }, +- { CS35L41_ASP_TX2_SRC, 0x00000019 }, +- { CS35L41_ASP_TX3_SRC, 0x00000020 }, +- { CS35L41_ASP_TX4_SRC, 0x00000021 }, +- { CS35L41_DSP1_RX1_SRC, 0x00000008 }, +- { CS35L41_DSP1_RX2_SRC, 0x00000009 }, +- { CS35L41_DSP1_RX3_SRC, 0x00000018 }, +- { CS35L41_DSP1_RX4_SRC, 0x00000019 }, +- { CS35L41_DSP1_RX5_SRC, 0x00000020 }, +- { CS35L41_DSP1_RX6_SRC, 0x00000021 }, +- { CS35L41_DSP1_RX7_SRC, 0x0000003A }, +- { CS35L41_DSP1_RX8_SRC, 0x00000001 }, +- { CS35L41_NGATE1_SRC, 0x00000008 }, +- { CS35L41_NGATE2_SRC, 0x00000009 }, +- { CS35L41_AMP_DIG_VOL_CTRL, 0x00008000 }, +- { CS35L41_CLASSH_CFG, 0x000B0405 }, +- { CS35L41_WKFET_CFG, 0x00000111 }, +- { CS35L41_NG_CFG, 0x00000033 }, +- { CS35L41_AMP_GAIN_CTRL, 0x00000273 }, +- { CS35L41_GPIO1_CTRL1, 0xE1000001 }, +- { CS35L41_GPIO2_CTRL1, 0xE1000001 }, +- { CS35L41_MIXER_NGATE_CFG, 0x00000000 }, +- { CS35L41_MIXER_NGATE_CH1_CFG, 0x00000303 }, +- { CS35L41_MIXER_NGATE_CH2_CFG, 0x00000303 }, +-}; +- +-static bool cs35l41_readable_reg(struct device *dev, unsigned int reg) +-{ +- switch (reg) { +- case CS35L41_DEVID: +- case CS35L41_REVID: +- case CS35L41_FABID: +- case CS35L41_RELID: +- case CS35L41_OTPID: +- case CS35L41_TEST_KEY_CTL: +- case CS35L41_USER_KEY_CTL: +- case CS35L41_OTP_CTRL0: +- case CS35L41_OTP_CTRL3: +- case CS35L41_OTP_CTRL4: +- case CS35L41_OTP_CTRL5: +- case CS35L41_OTP_CTRL6: +- case CS35L41_OTP_CTRL7: +- case CS35L41_OTP_CTRL8: +- case CS35L41_PWR_CTRL1: +- case CS35L41_PWR_CTRL2: +- case CS35L41_PWR_CTRL3: +- case CS35L41_CTRL_OVRRIDE: +- case CS35L41_AMP_OUT_MUTE: +- case CS35L41_PROTECT_REL_ERR_IGN: +- case CS35L41_GPIO_PAD_CONTROL: +- case CS35L41_JTAG_CONTROL: +- case CS35L41_PLL_CLK_CTRL: +- case CS35L41_DSP_CLK_CTRL: +- case CS35L41_GLOBAL_CLK_CTRL: +- case CS35L41_DATA_FS_SEL: +- case CS35L41_MDSYNC_EN: +- case CS35L41_MDSYNC_TX_ID: +- case CS35L41_MDSYNC_PWR_CTRL: +- case CS35L41_MDSYNC_DATA_TX: +- case CS35L41_MDSYNC_TX_STATUS: +- case CS35L41_MDSYNC_DATA_RX: +- case CS35L41_MDSYNC_RX_STATUS: +- case CS35L41_MDSYNC_ERR_STATUS: +- case CS35L41_MDSYNC_SYNC_PTE2: +- case CS35L41_MDSYNC_SYNC_PTE3: +- case CS35L41_MDSYNC_SYNC_MSM_STATUS: +- case CS35L41_BSTCVRT_VCTRL1: +- case CS35L41_BSTCVRT_VCTRL2: +- case CS35L41_BSTCVRT_PEAK_CUR: +- case CS35L41_BSTCVRT_SFT_RAMP: +- case CS35L41_BSTCVRT_COEFF: +- case CS35L41_BSTCVRT_SLOPE_LBST: +- case CS35L41_BSTCVRT_SW_FREQ: +- case CS35L41_BSTCVRT_DCM_CTRL: +- case CS35L41_BSTCVRT_DCM_MODE_FORCE: +- case CS35L41_BSTCVRT_OVERVOLT_CTRL: +- case CS35L41_VI_VOL_POL: +- case CS35L41_DTEMP_WARN_THLD: +- case CS35L41_DTEMP_CFG: +- case CS35L41_DTEMP_EN: +- case CS35L41_VPVBST_FS_SEL: +- case CS35L41_SP_ENABLES: +- case CS35L41_SP_RATE_CTRL: +- case CS35L41_SP_FORMAT: +- case CS35L41_SP_HIZ_CTRL: +- case CS35L41_SP_FRAME_TX_SLOT: +- case CS35L41_SP_FRAME_RX_SLOT: +- case CS35L41_SP_TX_WL: +- case CS35L41_SP_RX_WL: +- case CS35L41_DAC_PCM1_SRC: +- case CS35L41_ASP_TX1_SRC: +- case CS35L41_ASP_TX2_SRC: +- case CS35L41_ASP_TX3_SRC: +- case CS35L41_ASP_TX4_SRC: +- case CS35L41_DSP1_RX1_SRC: +- case CS35L41_DSP1_RX2_SRC: +- case CS35L41_DSP1_RX3_SRC: +- case CS35L41_DSP1_RX4_SRC: +- case CS35L41_DSP1_RX5_SRC: +- case CS35L41_DSP1_RX6_SRC: +- case CS35L41_DSP1_RX7_SRC: +- case CS35L41_DSP1_RX8_SRC: +- case CS35L41_NGATE1_SRC: +- case CS35L41_NGATE2_SRC: +- case CS35L41_AMP_DIG_VOL_CTRL: +- case CS35L41_VPBR_CFG: +- case CS35L41_VBBR_CFG: +- case CS35L41_VPBR_STATUS: +- case CS35L41_VBBR_STATUS: +- case CS35L41_OVERTEMP_CFG: +- case CS35L41_AMP_ERR_VOL: +- case CS35L41_VOL_STATUS_TO_DSP: +- case CS35L41_CLASSH_CFG: +- case CS35L41_WKFET_CFG: +- case CS35L41_NG_CFG: +- case CS35L41_AMP_GAIN_CTRL: +- case CS35L41_DAC_MSM_CFG: +- case CS35L41_IRQ1_CFG: +- case CS35L41_IRQ1_STATUS: +- case CS35L41_IRQ1_STATUS1: +- case CS35L41_IRQ1_STATUS2: +- case CS35L41_IRQ1_STATUS3: +- case CS35L41_IRQ1_STATUS4: +- case CS35L41_IRQ1_RAW_STATUS1: +- case CS35L41_IRQ1_RAW_STATUS2: +- case CS35L41_IRQ1_RAW_STATUS3: +- case CS35L41_IRQ1_RAW_STATUS4: +- case CS35L41_IRQ1_MASK1: +- case CS35L41_IRQ1_MASK2: +- case CS35L41_IRQ1_MASK3: +- case CS35L41_IRQ1_MASK4: +- case CS35L41_IRQ1_FRC1: +- case CS35L41_IRQ1_FRC2: +- case CS35L41_IRQ1_FRC3: +- case CS35L41_IRQ1_FRC4: +- case CS35L41_IRQ1_EDGE1: +- case CS35L41_IRQ1_EDGE4: +- case CS35L41_IRQ1_POL1: +- case CS35L41_IRQ1_POL2: +- case CS35L41_IRQ1_POL3: +- case CS35L41_IRQ1_POL4: +- case CS35L41_IRQ1_DB3: +- case CS35L41_IRQ2_CFG: +- case CS35L41_IRQ2_STATUS: +- case CS35L41_IRQ2_STATUS1: +- case CS35L41_IRQ2_STATUS2: +- case CS35L41_IRQ2_STATUS3: +- case CS35L41_IRQ2_STATUS4: +- case CS35L41_IRQ2_RAW_STATUS1: +- case CS35L41_IRQ2_RAW_STATUS2: +- case CS35L41_IRQ2_RAW_STATUS3: +- case CS35L41_IRQ2_RAW_STATUS4: +- case CS35L41_IRQ2_MASK1: +- case CS35L41_IRQ2_MASK2: +- case CS35L41_IRQ2_MASK3: +- case CS35L41_IRQ2_MASK4: +- case CS35L41_IRQ2_FRC1: +- case CS35L41_IRQ2_FRC2: +- case CS35L41_IRQ2_FRC3: +- case CS35L41_IRQ2_FRC4: +- case CS35L41_IRQ2_EDGE1: +- case CS35L41_IRQ2_EDGE4: +- case CS35L41_IRQ2_POL1: +- case CS35L41_IRQ2_POL2: +- case CS35L41_IRQ2_POL3: +- case CS35L41_IRQ2_POL4: +- case CS35L41_IRQ2_DB3: +- case CS35L41_GPIO_STATUS1: +- case CS35L41_GPIO1_CTRL1: +- case CS35L41_GPIO2_CTRL1: +- case CS35L41_MIXER_NGATE_CFG: +- case CS35L41_MIXER_NGATE_CH1_CFG: +- case CS35L41_MIXER_NGATE_CH2_CFG: +- case CS35L41_DSP_MBOX_1 ... CS35L41_DSP_VIRT2_MBOX_8: +- case CS35L41_CLOCK_DETECT_1: +- case CS35L41_DIE_STS1: +- case CS35L41_DIE_STS2: +- case CS35L41_TEMP_CAL1: +- case CS35L41_TEMP_CAL2: +- case CS35L41_DSP1_TIMESTAMP_COUNT: +- case CS35L41_DSP1_SYS_ID: +- case CS35L41_DSP1_SYS_VERSION: +- case CS35L41_DSP1_SYS_CORE_ID: +- case CS35L41_DSP1_SYS_AHB_ADDR: +- case CS35L41_DSP1_SYS_XSRAM_SIZE: +- case CS35L41_DSP1_SYS_YSRAM_SIZE: +- case CS35L41_DSP1_SYS_PSRAM_SIZE: +- case CS35L41_DSP1_SYS_PM_BOOT_SIZE: +- case CS35L41_DSP1_SYS_FEATURES: +- case CS35L41_DSP1_SYS_FIR_FILTERS: +- case CS35L41_DSP1_SYS_LMS_FILTERS: +- case CS35L41_DSP1_SYS_XM_BANK_SIZE: +- case CS35L41_DSP1_SYS_YM_BANK_SIZE: +- case CS35L41_DSP1_SYS_PM_BANK_SIZE: +- case CS35L41_DSP1_RX1_RATE: +- case CS35L41_DSP1_RX2_RATE: +- case CS35L41_DSP1_RX3_RATE: +- case CS35L41_DSP1_RX4_RATE: +- case CS35L41_DSP1_RX5_RATE: +- case CS35L41_DSP1_RX6_RATE: +- case CS35L41_DSP1_RX7_RATE: +- case CS35L41_DSP1_RX8_RATE: +- case CS35L41_DSP1_TX1_RATE: +- case CS35L41_DSP1_TX2_RATE: +- case CS35L41_DSP1_TX3_RATE: +- case CS35L41_DSP1_TX4_RATE: +- case CS35L41_DSP1_TX5_RATE: +- case CS35L41_DSP1_TX6_RATE: +- case CS35L41_DSP1_TX7_RATE: +- case CS35L41_DSP1_TX8_RATE: +- case CS35L41_DSP1_SCRATCH1: +- case CS35L41_DSP1_SCRATCH2: +- case CS35L41_DSP1_SCRATCH3: +- case CS35L41_DSP1_SCRATCH4: +- case CS35L41_DSP1_CCM_CORE_CTRL: +- case CS35L41_DSP1_CCM_CLK_OVERRIDE: +- case CS35L41_DSP1_XM_MSTR_EN: +- case CS35L41_DSP1_XM_CORE_PRI: +- case CS35L41_DSP1_XM_AHB_PACK_PL_PRI: +- case CS35L41_DSP1_XM_AHB_UP_PL_PRI: +- case CS35L41_DSP1_XM_ACCEL_PL0_PRI: +- case CS35L41_DSP1_XM_NPL0_PRI: +- case CS35L41_DSP1_YM_MSTR_EN: +- case CS35L41_DSP1_YM_CORE_PRI: +- case CS35L41_DSP1_YM_AHB_PACK_PL_PRI: +- case CS35L41_DSP1_YM_AHB_UP_PL_PRI: +- case CS35L41_DSP1_YM_ACCEL_PL0_PRI: +- case CS35L41_DSP1_YM_NPL0_PRI: +- case CS35L41_DSP1_MPU_XM_ACCESS0: +- case CS35L41_DSP1_MPU_YM_ACCESS0: +- case CS35L41_DSP1_MPU_WNDW_ACCESS0: +- case CS35L41_DSP1_MPU_XREG_ACCESS0: +- case CS35L41_DSP1_MPU_YREG_ACCESS0: +- case CS35L41_DSP1_MPU_XM_ACCESS1: +- case CS35L41_DSP1_MPU_YM_ACCESS1: +- case CS35L41_DSP1_MPU_WNDW_ACCESS1: +- case CS35L41_DSP1_MPU_XREG_ACCESS1: +- case CS35L41_DSP1_MPU_YREG_ACCESS1: +- case CS35L41_DSP1_MPU_XM_ACCESS2: +- case CS35L41_DSP1_MPU_YM_ACCESS2: +- case CS35L41_DSP1_MPU_WNDW_ACCESS2: +- case CS35L41_DSP1_MPU_XREG_ACCESS2: +- case CS35L41_DSP1_MPU_YREG_ACCESS2: +- case CS35L41_DSP1_MPU_XM_ACCESS3: +- case CS35L41_DSP1_MPU_YM_ACCESS3: +- case CS35L41_DSP1_MPU_WNDW_ACCESS3: +- case CS35L41_DSP1_MPU_XREG_ACCESS3: +- case CS35L41_DSP1_MPU_YREG_ACCESS3: +- case CS35L41_DSP1_MPU_XM_VIO_ADDR: +- case CS35L41_DSP1_MPU_XM_VIO_STATUS: +- case CS35L41_DSP1_MPU_YM_VIO_ADDR: +- case CS35L41_DSP1_MPU_YM_VIO_STATUS: +- case CS35L41_DSP1_MPU_PM_VIO_ADDR: +- case CS35L41_DSP1_MPU_PM_VIO_STATUS: +- case CS35L41_DSP1_MPU_LOCK_CONFIG: +- case CS35L41_DSP1_MPU_WDT_RST_CTRL: +- case CS35L41_OTP_TRIM_1: +- case CS35L41_OTP_TRIM_2: +- case CS35L41_OTP_TRIM_3: +- case CS35L41_OTP_TRIM_4: +- case CS35L41_OTP_TRIM_5: +- case CS35L41_OTP_TRIM_6: +- case CS35L41_OTP_TRIM_7: +- case CS35L41_OTP_TRIM_8: +- case CS35L41_OTP_TRIM_9: +- case CS35L41_OTP_TRIM_10: +- case CS35L41_OTP_TRIM_11: +- case CS35L41_OTP_TRIM_12: +- case CS35L41_OTP_TRIM_13: +- case CS35L41_OTP_TRIM_14: +- case CS35L41_OTP_TRIM_15: +- case CS35L41_OTP_TRIM_16: +- case CS35L41_OTP_TRIM_17: +- case CS35L41_OTP_TRIM_18: +- case CS35L41_OTP_TRIM_19: +- case CS35L41_OTP_TRIM_20: +- case CS35L41_OTP_TRIM_21: +- case CS35L41_OTP_TRIM_22: +- case CS35L41_OTP_TRIM_23: +- case CS35L41_OTP_TRIM_24: +- case CS35L41_OTP_TRIM_25: +- case CS35L41_OTP_TRIM_26: +- case CS35L41_OTP_TRIM_27: +- case CS35L41_OTP_TRIM_28: +- case CS35L41_OTP_TRIM_29: +- case CS35L41_OTP_TRIM_30: +- case CS35L41_OTP_TRIM_31: +- case CS35L41_OTP_TRIM_32: +- case CS35L41_OTP_TRIM_33: +- case CS35L41_OTP_TRIM_34: +- case CS35L41_OTP_TRIM_35: +- case CS35L41_OTP_TRIM_36: +- case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31: +- case CS35L41_DSP1_XMEM_PACK_0 ... CS35L41_DSP1_XMEM_PACK_3068: +- case CS35L41_DSP1_XMEM_UNPACK32_0 ... CS35L41_DSP1_XMEM_UNPACK32_2046: +- case CS35L41_DSP1_XMEM_UNPACK24_0 ... CS35L41_DSP1_XMEM_UNPACK24_4093: +- case CS35L41_DSP1_YMEM_PACK_0 ... CS35L41_DSP1_YMEM_PACK_1532: +- case CS35L41_DSP1_YMEM_UNPACK32_0 ... CS35L41_DSP1_YMEM_UNPACK32_1022: +- case CS35L41_DSP1_YMEM_UNPACK24_0 ... CS35L41_DSP1_YMEM_UNPACK24_2045: +- case CS35L41_DSP1_PMEM_0 ... CS35L41_DSP1_PMEM_5114: +- /*test regs*/ +- case CS35L41_PLL_OVR: +- case CS35L41_BST_TEST_DUTY: +- case CS35L41_DIGPWM_IOCTRL: +- return true; +- default: +- return false; +- } +-} +- +-static bool cs35l41_precious_reg(struct device *dev, unsigned int reg) +-{ +- switch (reg) { +- case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31: +- case CS35L41_DSP1_XMEM_PACK_0 ... CS35L41_DSP1_XMEM_PACK_3068: +- case CS35L41_DSP1_YMEM_PACK_0 ... CS35L41_DSP1_YMEM_PACK_1532: +- case CS35L41_DSP1_PMEM_0 ... CS35L41_DSP1_PMEM_5114: +- return true; +- default: +- return false; +- } +-} +- +-static bool cs35l41_volatile_reg(struct device *dev, unsigned int reg) +-{ +- switch (reg) { +- case CS35L41_DEVID: +- case CS35L41_SFT_RESET: +- case CS35L41_FABID: +- case CS35L41_REVID: +- case CS35L41_DTEMP_EN: +- case CS35L41_IRQ1_STATUS: +- case CS35L41_IRQ1_STATUS1: +- case CS35L41_IRQ1_STATUS2: +- case CS35L41_IRQ1_STATUS3: +- case CS35L41_IRQ1_STATUS4: +- case CS35L41_IRQ1_RAW_STATUS1: +- case CS35L41_IRQ1_RAW_STATUS2: +- case CS35L41_IRQ1_RAW_STATUS3: +- case CS35L41_IRQ1_RAW_STATUS4: +- case CS35L41_IRQ1_FRC1: +- case CS35L41_IRQ1_FRC2: +- case CS35L41_IRQ1_FRC3: +- case CS35L41_IRQ1_FRC4: +- case CS35L41_IRQ1_EDGE1: +- case CS35L41_IRQ1_EDGE4: +- case CS35L41_IRQ1_POL1: +- case CS35L41_IRQ1_POL2: +- case CS35L41_IRQ1_POL3: +- case CS35L41_IRQ1_POL4: +- case CS35L41_IRQ1_DB3: +- case CS35L41_IRQ2_STATUS: +- case CS35L41_IRQ2_STATUS1: +- case CS35L41_IRQ2_STATUS2: +- case CS35L41_IRQ2_STATUS3: +- case CS35L41_IRQ2_STATUS4: +- case CS35L41_IRQ2_RAW_STATUS1: +- case CS35L41_IRQ2_RAW_STATUS2: +- case CS35L41_IRQ2_RAW_STATUS3: +- case CS35L41_IRQ2_RAW_STATUS4: +- case CS35L41_IRQ2_FRC1: +- case CS35L41_IRQ2_FRC2: +- case CS35L41_IRQ2_FRC3: +- case CS35L41_IRQ2_FRC4: +- case CS35L41_IRQ2_EDGE1: +- case CS35L41_IRQ2_EDGE4: +- case CS35L41_IRQ2_POL1: +- case CS35L41_IRQ2_POL2: +- case CS35L41_IRQ2_POL3: +- case CS35L41_IRQ2_POL4: +- case CS35L41_IRQ2_DB3: +- case CS35L41_GPIO_STATUS1: +- case CS35L41_OTP_TRIM_1: +- case CS35L41_OTP_TRIM_2: +- case CS35L41_OTP_TRIM_3: +- case CS35L41_OTP_TRIM_4: +- case CS35L41_OTP_TRIM_5: +- case CS35L41_OTP_TRIM_6: +- case CS35L41_OTP_TRIM_7: +- case CS35L41_OTP_TRIM_8: +- case CS35L41_OTP_TRIM_9: +- case CS35L41_OTP_TRIM_10: +- case CS35L41_OTP_TRIM_11: +- case CS35L41_OTP_TRIM_12: +- case CS35L41_OTP_TRIM_13: +- case CS35L41_OTP_TRIM_14: +- case CS35L41_OTP_TRIM_15: +- case CS35L41_OTP_TRIM_16: +- case CS35L41_OTP_TRIM_17: +- case CS35L41_OTP_TRIM_18: +- case CS35L41_OTP_TRIM_19: +- case CS35L41_OTP_TRIM_20: +- case CS35L41_OTP_TRIM_21: +- case CS35L41_OTP_TRIM_22: +- case CS35L41_OTP_TRIM_23: +- case CS35L41_OTP_TRIM_24: +- case CS35L41_OTP_TRIM_25: +- case CS35L41_OTP_TRIM_26: +- case CS35L41_OTP_TRIM_27: +- case CS35L41_OTP_TRIM_28: +- case CS35L41_OTP_TRIM_29: +- case CS35L41_OTP_TRIM_30: +- case CS35L41_OTP_TRIM_31: +- case CS35L41_OTP_TRIM_32: +- case CS35L41_OTP_TRIM_33: +- case CS35L41_OTP_TRIM_34: +- case CS35L41_OTP_TRIM_35: +- case CS35L41_OTP_TRIM_36: +- case CS35L41_DSP_MBOX_1 ... CS35L41_DSP_VIRT2_MBOX_8: +- case CS35L41_DSP1_XMEM_PACK_0 ... CS35L41_DSP1_XMEM_PACK_3068: +- case CS35L41_DSP1_XMEM_UNPACK32_0 ... CS35L41_DSP1_XMEM_UNPACK32_2046: +- case CS35L41_DSP1_XMEM_UNPACK24_0 ... CS35L41_DSP1_XMEM_UNPACK24_4093: +- case CS35L41_DSP1_YMEM_PACK_0 ... CS35L41_DSP1_YMEM_PACK_1532: +- case CS35L41_DSP1_YMEM_UNPACK32_0 ... CS35L41_DSP1_YMEM_UNPACK32_1022: +- case CS35L41_DSP1_YMEM_UNPACK24_0 ... CS35L41_DSP1_YMEM_UNPACK24_2045: +- case CS35L41_DSP1_PMEM_0 ... CS35L41_DSP1_PMEM_5114: +- case CS35L41_DSP1_CCM_CORE_CTRL ... CS35L41_DSP1_WDT_STATUS: +- case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31: +- return true; +- default: +- return false; +- } +-} +- +-static const struct cs35l41_otp_packed_element_t otp_map_1[CS35L41_NUM_OTP_ELEM] = { +- /* addr shift size */ +- { 0x00002030, 0, 4 }, /*TRIM_OSC_FREQ_TRIM*/ +- { 0x00002030, 7, 1 }, /*TRIM_OSC_TRIM_DONE*/ +- { 0x0000208c, 24, 6 }, /*TST_DIGREG_VREF_TRIM*/ +- { 0x00002090, 14, 4 }, /*TST_REF_TRIM*/ +- { 0x00002090, 10, 4 }, /*TST_REF_TEMPCO_TRIM*/ +- { 0x0000300C, 11, 4 }, /*PLL_LDOA_TST_VREF_TRIM*/ +- { 0x0000394C, 23, 2 }, /*BST_ATEST_CM_VOFF*/ +- { 0x00003950, 0, 7 }, /*BST_ATRIM_IADC_OFFSET*/ +- { 0x00003950, 8, 7 }, /*BST_ATRIM_IADC_GAIN1*/ +- { 0x00003950, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET1*/ +- { 0x00003950, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN1*/ +- { 0x00003954, 0, 7 }, /*BST_ATRIM_IADC_OFFSET2*/ +- { 0x00003954, 8, 7 }, /*BST_ATRIM_IADC_GAIN2*/ +- { 0x00003954, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET2*/ +- { 0x00003954, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN2*/ +- { 0x00003958, 0, 7 }, /*BST_ATRIM_IADC_OFFSET3*/ +- { 0x00003958, 8, 7 }, /*BST_ATRIM_IADC_GAIN3*/ +- { 0x00003958, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET3*/ +- { 0x00003958, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN3*/ +- { 0x0000395C, 0, 7 }, /*BST_ATRIM_IADC_OFFSET4*/ +- { 0x0000395C, 8, 7 }, /*BST_ATRIM_IADC_GAIN4*/ +- { 0x0000395C, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET4*/ +- { 0x0000395C, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN4*/ +- { 0x0000416C, 0, 8 }, /*VMON_GAIN_OTP_VAL*/ +- { 0x00004160, 0, 7 }, /*VMON_OFFSET_OTP_VAL*/ +- { 0x0000416C, 8, 8 }, /*IMON_GAIN_OTP_VAL*/ +- { 0x00004160, 16, 10 }, /*IMON_OFFSET_OTP_VAL*/ +- { 0x0000416C, 16, 12 }, /*VMON_CM_GAIN_OTP_VAL*/ +- { 0x0000416C, 28, 1 }, /*VMON_CM_GAIN_SIGN_OTP_VAL*/ +- { 0x00004170, 0, 6 }, /*IMON_CAL_TEMPCO_OTP_VAL*/ +- { 0x00004170, 6, 1 }, /*IMON_CAL_TEMPCO_SIGN_OTP*/ +- { 0x00004170, 8, 6 }, /*IMON_CAL_TEMPCO2_OTP_VAL*/ +- { 0x00004170, 14, 1 }, /*IMON_CAL_TEMPCO2_DN_UPB_OTP_VAL*/ +- { 0x00004170, 16, 9 }, /*IMON_CAL_TEMPCO_TBASE_OTP_VAL*/ +- { 0x00004360, 0, 5 }, /*TEMP_GAIN_OTP_VAL*/ +- { 0x00004360, 6, 9 }, /*TEMP_OFFSET_OTP_VAL*/ +- { 0x00004448, 0, 8 }, /*VP_SARADC_OFFSET*/ +- { 0x00004448, 8, 8 }, /*VP_GAIN_INDEX*/ +- { 0x00004448, 16, 8 }, /*VBST_SARADC_OFFSET*/ +- { 0x00004448, 24, 8 }, /*VBST_GAIN_INDEX*/ +- { 0x0000444C, 0, 3 }, /*ANA_SELINVREF*/ +- { 0x00006E30, 0, 5 }, /*GAIN_ERR_COEFF_0*/ +- { 0x00006E30, 8, 5 }, /*GAIN_ERR_COEFF_1*/ +- { 0x00006E30, 16, 5 }, /*GAIN_ERR_COEFF_2*/ +- { 0x00006E30, 24, 5 }, /*GAIN_ERR_COEFF_3*/ +- { 0x00006E34, 0, 5 }, /*GAIN_ERR_COEFF_4*/ +- { 0x00006E34, 8, 5 }, /*GAIN_ERR_COEFF_5*/ +- { 0x00006E34, 16, 5 }, /*GAIN_ERR_COEFF_6*/ +- { 0x00006E34, 24, 5 }, /*GAIN_ERR_COEFF_7*/ +- { 0x00006E38, 0, 5 }, /*GAIN_ERR_COEFF_8*/ +- { 0x00006E38, 8, 5 }, /*GAIN_ERR_COEFF_9*/ +- { 0x00006E38, 16, 5 }, /*GAIN_ERR_COEFF_10*/ +- { 0x00006E38, 24, 5 }, /*GAIN_ERR_COEFF_11*/ +- { 0x00006E3C, 0, 5 }, /*GAIN_ERR_COEFF_12*/ +- { 0x00006E3C, 8, 5 }, /*GAIN_ERR_COEFF_13*/ +- { 0x00006E3C, 16, 5 }, /*GAIN_ERR_COEFF_14*/ +- { 0x00006E3C, 24, 5 }, /*GAIN_ERR_COEFF_15*/ +- { 0x00006E40, 0, 5 }, /*GAIN_ERR_COEFF_16*/ +- { 0x00006E40, 8, 5 }, /*GAIN_ERR_COEFF_17*/ +- { 0x00006E40, 16, 5 }, /*GAIN_ERR_COEFF_18*/ +- { 0x00006E40, 24, 5 }, /*GAIN_ERR_COEFF_19*/ +- { 0x00006E44, 0, 5 }, /*GAIN_ERR_COEFF_20*/ +- { 0x00006E48, 0, 10 }, /*VOFF_GAIN_0*/ +- { 0x00006E48, 10, 10 }, /*VOFF_GAIN_1*/ +- { 0x00006E48, 20, 10 }, /*VOFF_GAIN_2*/ +- { 0x00006E4C, 0, 10 }, /*VOFF_GAIN_3*/ +- { 0x00006E4C, 10, 10 }, /*VOFF_GAIN_4*/ +- { 0x00006E4C, 20, 10 }, /*VOFF_GAIN_5*/ +- { 0x00006E50, 0, 10 }, /*VOFF_GAIN_6*/ +- { 0x00006E50, 10, 10 }, /*VOFF_GAIN_7*/ +- { 0x00006E50, 20, 10 }, /*VOFF_GAIN_8*/ +- { 0x00006E54, 0, 10 }, /*VOFF_GAIN_9*/ +- { 0x00006E54, 10, 10 }, /*VOFF_GAIN_10*/ +- { 0x00006E54, 20, 10 }, /*VOFF_GAIN_11*/ +- { 0x00006E58, 0, 10 }, /*VOFF_GAIN_12*/ +- { 0x00006E58, 10, 10 }, /*VOFF_GAIN_13*/ +- { 0x00006E58, 20, 10 }, /*VOFF_GAIN_14*/ +- { 0x00006E5C, 0, 10 }, /*VOFF_GAIN_15*/ +- { 0x00006E5C, 10, 10 }, /*VOFF_GAIN_16*/ +- { 0x00006E5C, 20, 10 }, /*VOFF_GAIN_17*/ +- { 0x00006E60, 0, 10 }, /*VOFF_GAIN_18*/ +- { 0x00006E60, 10, 10 }, /*VOFF_GAIN_19*/ +- { 0x00006E60, 20, 10 }, /*VOFF_GAIN_20*/ +- { 0x00006E64, 0, 10 }, /*VOFF_INT1*/ +- { 0x00007418, 7, 5 }, /*DS_SPK_INT1_CAP_TRIM*/ +- { 0x0000741C, 0, 5 }, /*DS_SPK_INT2_CAP_TRIM*/ +- { 0x0000741C, 11, 4 }, /*DS_SPK_LPF_CAP_TRIM*/ +- { 0x0000741C, 19, 4 }, /*DS_SPK_QUAN_CAP_TRIM*/ +- { 0x00007434, 17, 1 }, /*FORCE_CAL*/ +- { 0x00007434, 18, 7 }, /*CAL_OVERRIDE*/ +- { 0x00007068, 0, 9 }, /*MODIX*/ +- { 0x0000410C, 7, 1 }, /*VIMON_DLY_NOT_COMB*/ +- { 0x0000400C, 0, 7 }, /*VIMON_DLY*/ +- { 0x00000000, 0, 1 }, /*extra bit*/ +- { 0x00017040, 0, 8 }, /*X_COORDINATE*/ +- { 0x00017040, 8, 8 }, /*Y_COORDINATE*/ +- { 0x00017040, 16, 8 }, /*WAFER_ID*/ +- { 0x00017040, 24, 8 }, /*DVS*/ +- { 0x00017044, 0, 24 }, /*LOT_NUMBER*/ +-}; +- +-static const struct cs35l41_otp_packed_element_t otp_map_2[CS35L41_NUM_OTP_ELEM] = { +- /* addr shift size */ +- { 0x00002030, 0, 4 }, /*TRIM_OSC_FREQ_TRIM*/ +- { 0x00002030, 7, 1 }, /*TRIM_OSC_TRIM_DONE*/ +- { 0x0000208c, 24, 6 }, /*TST_DIGREG_VREF_TRIM*/ +- { 0x00002090, 14, 4 }, /*TST_REF_TRIM*/ +- { 0x00002090, 10, 4 }, /*TST_REF_TEMPCO_TRIM*/ +- { 0x0000300C, 11, 4 }, /*PLL_LDOA_TST_VREF_TRIM*/ +- { 0x0000394C, 23, 2 }, /*BST_ATEST_CM_VOFF*/ +- { 0x00003950, 0, 7 }, /*BST_ATRIM_IADC_OFFSET*/ +- { 0x00003950, 8, 7 }, /*BST_ATRIM_IADC_GAIN1*/ +- { 0x00003950, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET1*/ +- { 0x00003950, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN1*/ +- { 0x00003954, 0, 7 }, /*BST_ATRIM_IADC_OFFSET2*/ +- { 0x00003954, 8, 7 }, /*BST_ATRIM_IADC_GAIN2*/ +- { 0x00003954, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET2*/ +- { 0x00003954, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN2*/ +- { 0x00003958, 0, 7 }, /*BST_ATRIM_IADC_OFFSET3*/ +- { 0x00003958, 8, 7 }, /*BST_ATRIM_IADC_GAIN3*/ +- { 0x00003958, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET3*/ +- { 0x00003958, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN3*/ +- { 0x0000395C, 0, 7 }, /*BST_ATRIM_IADC_OFFSET4*/ +- { 0x0000395C, 8, 7 }, /*BST_ATRIM_IADC_GAIN4*/ +- { 0x0000395C, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET4*/ +- { 0x0000395C, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN4*/ +- { 0x0000416C, 0, 8 }, /*VMON_GAIN_OTP_VAL*/ +- { 0x00004160, 0, 7 }, /*VMON_OFFSET_OTP_VAL*/ +- { 0x0000416C, 8, 8 }, /*IMON_GAIN_OTP_VAL*/ +- { 0x00004160, 16, 10 }, /*IMON_OFFSET_OTP_VAL*/ +- { 0x0000416C, 16, 12 }, /*VMON_CM_GAIN_OTP_VAL*/ +- { 0x0000416C, 28, 1 }, /*VMON_CM_GAIN_SIGN_OTP_VAL*/ +- { 0x00004170, 0, 6 }, /*IMON_CAL_TEMPCO_OTP_VAL*/ +- { 0x00004170, 6, 1 }, /*IMON_CAL_TEMPCO_SIGN_OTP*/ +- { 0x00004170, 8, 6 }, /*IMON_CAL_TEMPCO2_OTP_VAL*/ +- { 0x00004170, 14, 1 }, /*IMON_CAL_TEMPCO2_DN_UPB_OTP_VAL*/ +- { 0x00004170, 16, 9 }, /*IMON_CAL_TEMPCO_TBASE_OTP_VAL*/ +- { 0x00004360, 0, 5 }, /*TEMP_GAIN_OTP_VAL*/ +- { 0x00004360, 6, 9 }, /*TEMP_OFFSET_OTP_VAL*/ +- { 0x00004448, 0, 8 }, /*VP_SARADC_OFFSET*/ +- { 0x00004448, 8, 8 }, /*VP_GAIN_INDEX*/ +- { 0x00004448, 16, 8 }, /*VBST_SARADC_OFFSET*/ +- { 0x00004448, 24, 8 }, /*VBST_GAIN_INDEX*/ +- { 0x0000444C, 0, 3 }, /*ANA_SELINVREF*/ +- { 0x00006E30, 0, 5 }, /*GAIN_ERR_COEFF_0*/ +- { 0x00006E30, 8, 5 }, /*GAIN_ERR_COEFF_1*/ +- { 0x00006E30, 16, 5 }, /*GAIN_ERR_COEFF_2*/ +- { 0x00006E30, 24, 5 }, /*GAIN_ERR_COEFF_3*/ +- { 0x00006E34, 0, 5 }, /*GAIN_ERR_COEFF_4*/ +- { 0x00006E34, 8, 5 }, /*GAIN_ERR_COEFF_5*/ +- { 0x00006E34, 16, 5 }, /*GAIN_ERR_COEFF_6*/ +- { 0x00006E34, 24, 5 }, /*GAIN_ERR_COEFF_7*/ +- { 0x00006E38, 0, 5 }, /*GAIN_ERR_COEFF_8*/ +- { 0x00006E38, 8, 5 }, /*GAIN_ERR_COEFF_9*/ +- { 0x00006E38, 16, 5 }, /*GAIN_ERR_COEFF_10*/ +- { 0x00006E38, 24, 5 }, /*GAIN_ERR_COEFF_11*/ +- { 0x00006E3C, 0, 5 }, /*GAIN_ERR_COEFF_12*/ +- { 0x00006E3C, 8, 5 }, /*GAIN_ERR_COEFF_13*/ +- { 0x00006E3C, 16, 5 }, /*GAIN_ERR_COEFF_14*/ +- { 0x00006E3C, 24, 5 }, /*GAIN_ERR_COEFF_15*/ +- { 0x00006E40, 0, 5 }, /*GAIN_ERR_COEFF_16*/ +- { 0x00006E40, 8, 5 }, /*GAIN_ERR_COEFF_17*/ +- { 0x00006E40, 16, 5 }, /*GAIN_ERR_COEFF_18*/ +- { 0x00006E40, 24, 5 }, /*GAIN_ERR_COEFF_19*/ +- { 0x00006E44, 0, 5 }, /*GAIN_ERR_COEFF_20*/ +- { 0x00006E48, 0, 10 }, /*VOFF_GAIN_0*/ +- { 0x00006E48, 10, 10 }, /*VOFF_GAIN_1*/ +- { 0x00006E48, 20, 10 }, /*VOFF_GAIN_2*/ +- { 0x00006E4C, 0, 10 }, /*VOFF_GAIN_3*/ +- { 0x00006E4C, 10, 10 }, /*VOFF_GAIN_4*/ +- { 0x00006E4C, 20, 10 }, /*VOFF_GAIN_5*/ +- { 0x00006E50, 0, 10 }, /*VOFF_GAIN_6*/ +- { 0x00006E50, 10, 10 }, /*VOFF_GAIN_7*/ +- { 0x00006E50, 20, 10 }, /*VOFF_GAIN_8*/ +- { 0x00006E54, 0, 10 }, /*VOFF_GAIN_9*/ +- { 0x00006E54, 10, 10 }, /*VOFF_GAIN_10*/ +- { 0x00006E54, 20, 10 }, /*VOFF_GAIN_11*/ +- { 0x00006E58, 0, 10 }, /*VOFF_GAIN_12*/ +- { 0x00006E58, 10, 10 }, /*VOFF_GAIN_13*/ +- { 0x00006E58, 20, 10 }, /*VOFF_GAIN_14*/ +- { 0x00006E5C, 0, 10 }, /*VOFF_GAIN_15*/ +- { 0x00006E5C, 10, 10 }, /*VOFF_GAIN_16*/ +- { 0x00006E5C, 20, 10 }, /*VOFF_GAIN_17*/ +- { 0x00006E60, 0, 10 }, /*VOFF_GAIN_18*/ +- { 0x00006E60, 10, 10 }, /*VOFF_GAIN_19*/ +- { 0x00006E60, 20, 10 }, /*VOFF_GAIN_20*/ +- { 0x00006E64, 0, 10 }, /*VOFF_INT1*/ +- { 0x00007418, 7, 5 }, /*DS_SPK_INT1_CAP_TRIM*/ +- { 0x0000741C, 0, 5 }, /*DS_SPK_INT2_CAP_TRIM*/ +- { 0x0000741C, 11, 4 }, /*DS_SPK_LPF_CAP_TRIM*/ +- { 0x0000741C, 19, 4 }, /*DS_SPK_QUAN_CAP_TRIM*/ +- { 0x00007434, 17, 1 }, /*FORCE_CAL*/ +- { 0x00007434, 18, 7 }, /*CAL_OVERRIDE*/ +- { 0x00007068, 0, 9 }, /*MODIX*/ +- { 0x0000410C, 7, 1 }, /*VIMON_DLY_NOT_COMB*/ +- { 0x0000400C, 0, 7 }, /*VIMON_DLY*/ +- { 0x00004000, 11, 1 }, /*VMON_POL*/ +- { 0x00017040, 0, 8 }, /*X_COORDINATE*/ +- { 0x00017040, 8, 8 }, /*Y_COORDINATE*/ +- { 0x00017040, 16, 8 }, /*WAFER_ID*/ +- { 0x00017040, 24, 8 }, /*DVS*/ +- { 0x00017044, 0, 24 }, /*LOT_NUMBER*/ +-}; +- +-const struct cs35l41_otp_map_element_t cs35l41_otp_map_map[CS35L41_NUM_OTP_MAPS] = { +- { +- .id = 0x01, +- .map = otp_map_1, +- .num_elements = CS35L41_NUM_OTP_ELEM, +- .bit_offset = 16, +- .word_offset = 2, +- }, +- { +- .id = 0x02, +- .map = otp_map_2, +- .num_elements = CS35L41_NUM_OTP_ELEM, +- .bit_offset = 16, +- .word_offset = 2, +- }, +- { +- .id = 0x03, +- .map = otp_map_2, +- .num_elements = CS35L41_NUM_OTP_ELEM, +- .bit_offset = 16, +- .word_offset = 2, +- }, +- { +- .id = 0x06, +- .map = otp_map_2, +- .num_elements = CS35L41_NUM_OTP_ELEM, +- .bit_offset = 16, +- .word_offset = 2, +- }, +- { +- .id = 0x08, +- .map = otp_map_1, +- .num_elements = CS35L41_NUM_OTP_ELEM, +- .bit_offset = 16, +- .word_offset = 2, +- }, +-}; +- +-struct regmap_config cs35l41_regmap_i2c = { +- .reg_bits = 32, +- .val_bits = 32, +- .reg_stride = CS35L41_REGSTRIDE, +- .reg_format_endian = REGMAP_ENDIAN_BIG, +- .val_format_endian = REGMAP_ENDIAN_BIG, +- .max_register = CS35L41_LASTREG, +- .reg_defaults = cs35l41_reg, +- .num_reg_defaults = ARRAY_SIZE(cs35l41_reg), +- .volatile_reg = cs35l41_volatile_reg, +- .readable_reg = cs35l41_readable_reg, +- .precious_reg = cs35l41_precious_reg, +- .cache_type = REGCACHE_RBTREE, +-}; +-EXPORT_SYMBOL_GPL(cs35l41_regmap_i2c); +- +-struct regmap_config cs35l41_regmap_spi = { +- .reg_bits = 32, +- .val_bits = 32, +- .pad_bits = 16, +- .reg_stride = CS35L41_REGSTRIDE, +- .reg_format_endian = REGMAP_ENDIAN_BIG, +- .val_format_endian = REGMAP_ENDIAN_BIG, +- .max_register = CS35L41_LASTREG, +- .reg_defaults = cs35l41_reg, +- .num_reg_defaults = ARRAY_SIZE(cs35l41_reg), +- .volatile_reg = cs35l41_volatile_reg, +- .readable_reg = cs35l41_readable_reg, +- .precious_reg = cs35l41_precious_reg, +- .cache_type = REGCACHE_RBTREE, +-}; +-EXPORT_SYMBOL_GPL(cs35l41_regmap_spi); +diff --git a/sound/soc/codecs/cs35l41.h b/sound/soc/codecs/cs35l41.h +index c7c45f19754b..26a08d58a8c3 100644 +--- a/sound/soc/codecs/cs35l41.h ++++ b/sound/soc/codecs/cs35l41.h +@@ -11,7 +11,6 @@ + #define __CS35L41_H__ + + #include +-#include + #include + #include + #include +@@ -19,742 +18,9 @@ + + #include "wm_adsp.h" + +-#define CS35L41_FIRSTREG 0x00000000 +-#define CS35L41_LASTREG 0x03804FE8 +-#define CS35L41_DEVID 0x00000000 +-#define CS35L41_REVID 0x00000004 +-#define CS35L41_FABID 0x00000008 +-#define CS35L41_RELID 0x0000000C +-#define CS35L41_OTPID 0x00000010 +-#define CS35L41_SFT_RESET 0x00000020 +-#define CS35L41_TEST_KEY_CTL 0x00000040 +-#define CS35L41_USER_KEY_CTL 0x00000044 +-#define CS35L41_OTP_MEM0 0x00000400 +-#define CS35L41_OTP_MEM31 0x0000047C +-#define CS35L41_OTP_CTRL0 0x00000500 +-#define CS35L41_OTP_CTRL1 0x00000504 +-#define CS35L41_OTP_CTRL3 0x00000508 +-#define CS35L41_OTP_CTRL4 0x0000050C +-#define CS35L41_OTP_CTRL5 0x00000510 +-#define CS35L41_OTP_CTRL6 0x00000514 +-#define CS35L41_OTP_CTRL7 0x00000518 +-#define CS35L41_OTP_CTRL8 0x0000051C +-#define CS35L41_PWR_CTRL1 0x00002014 +-#define CS35L41_PWR_CTRL2 0x00002018 +-#define CS35L41_PWR_CTRL3 0x0000201C +-#define CS35L41_CTRL_OVRRIDE 0x00002020 +-#define CS35L41_AMP_OUT_MUTE 0x00002024 +-#define CS35L41_PROTECT_REL_ERR_IGN 0x00002034 +-#define CS35L41_GPIO_PAD_CONTROL 0x0000242C +-#define CS35L41_JTAG_CONTROL 0x00002438 +-#define CS35L41_PLL_CLK_CTRL 0x00002C04 +-#define CS35L41_DSP_CLK_CTRL 0x00002C08 +-#define CS35L41_GLOBAL_CLK_CTRL 0x00002C0C +-#define CS35L41_DATA_FS_SEL 0x00002C10 +-#define CS35L41_TST_FS_MON0 0x00002D10 +-#define CS35L41_MDSYNC_EN 0x00003400 +-#define CS35L41_MDSYNC_TX_ID 0x00003408 +-#define CS35L41_MDSYNC_PWR_CTRL 0x0000340C +-#define CS35L41_MDSYNC_DATA_TX 0x00003410 +-#define CS35L41_MDSYNC_TX_STATUS 0x00003414 +-#define CS35L41_MDSYNC_DATA_RX 0x0000341C +-#define CS35L41_MDSYNC_RX_STATUS 0x00003420 +-#define CS35L41_MDSYNC_ERR_STATUS 0x00003424 +-#define CS35L41_MDSYNC_SYNC_PTE2 0x00003528 +-#define CS35L41_MDSYNC_SYNC_PTE3 0x0000352C +-#define CS35L41_MDSYNC_SYNC_MSM_STATUS 0x0000353C +-#define CS35L41_BSTCVRT_VCTRL1 0x00003800 +-#define CS35L41_BSTCVRT_VCTRL2 0x00003804 +-#define CS35L41_BSTCVRT_PEAK_CUR 0x00003808 +-#define CS35L41_BSTCVRT_SFT_RAMP 0x0000380C +-#define CS35L41_BSTCVRT_COEFF 0x00003810 +-#define CS35L41_BSTCVRT_SLOPE_LBST 0x00003814 +-#define CS35L41_BSTCVRT_SW_FREQ 0x00003818 +-#define CS35L41_BSTCVRT_DCM_CTRL 0x0000381C +-#define CS35L41_BSTCVRT_DCM_MODE_FORCE 0x00003820 +-#define CS35L41_BSTCVRT_OVERVOLT_CTRL 0x00003830 +-#define CS35L41_VI_VOL_POL 0x00004000 +-#define CS35L41_VIMON_SPKMON_RESYNC 0x00004100 +-#define CS35L41_DTEMP_WARN_THLD 0x00004220 +-#define CS35L41_DTEMP_CFG 0x00004224 +-#define CS35L41_DTEMP_EN 0x00004308 +-#define CS35L41_VPVBST_FS_SEL 0x00004400 +-#define CS35L41_SP_ENABLES 0x00004800 +-#define CS35L41_SP_RATE_CTRL 0x00004804 +-#define CS35L41_SP_FORMAT 0x00004808 +-#define CS35L41_SP_HIZ_CTRL 0x0000480C +-#define CS35L41_SP_FRAME_TX_SLOT 0x00004810 +-#define CS35L41_SP_FRAME_RX_SLOT 0x00004820 +-#define CS35L41_SP_TX_WL 0x00004830 +-#define CS35L41_SP_RX_WL 0x00004840 +-#define CS35L41_ASP_CONTROL4 0x00004854 +-#define CS35L41_DAC_PCM1_SRC 0x00004C00 +-#define CS35L41_ASP_TX1_SRC 0x00004C20 +-#define CS35L41_ASP_TX2_SRC 0x00004C24 +-#define CS35L41_ASP_TX3_SRC 0x00004C28 +-#define CS35L41_ASP_TX4_SRC 0x00004C2C +-#define CS35L41_DSP1_RX1_SRC 0x00004C40 +-#define CS35L41_DSP1_RX2_SRC 0x00004C44 +-#define CS35L41_DSP1_RX3_SRC 0x00004C48 +-#define CS35L41_DSP1_RX4_SRC 0x00004C4C +-#define CS35L41_DSP1_RX5_SRC 0x00004C50 +-#define CS35L41_DSP1_RX6_SRC 0x00004C54 +-#define CS35L41_DSP1_RX7_SRC 0x00004C58 +-#define CS35L41_DSP1_RX8_SRC 0x00004C5C +-#define CS35L41_NGATE1_SRC 0x00004C60 +-#define CS35L41_NGATE2_SRC 0x00004C64 +-#define CS35L41_AMP_DIG_VOL_CTRL 0x00006000 +-#define CS35L41_VPBR_CFG 0x00006404 +-#define CS35L41_VBBR_CFG 0x00006408 +-#define CS35L41_VPBR_STATUS 0x0000640C +-#define CS35L41_VBBR_STATUS 0x00006410 +-#define CS35L41_OVERTEMP_CFG 0x00006414 +-#define CS35L41_AMP_ERR_VOL 0x00006418 +-#define CS35L41_VOL_STATUS_TO_DSP 0x00006450 +-#define CS35L41_CLASSH_CFG 0x00006800 +-#define CS35L41_WKFET_CFG 0x00006804 +-#define CS35L41_NG_CFG 0x00006808 +-#define CS35L41_AMP_GAIN_CTRL 0x00006C04 +-#define CS35L41_DAC_MSM_CFG 0x00007400 +-#define CS35L41_IRQ1_CFG 0x00010000 +-#define CS35L41_IRQ1_STATUS 0x00010004 +-#define CS35L41_IRQ1_STATUS1 0x00010010 +-#define CS35L41_IRQ1_STATUS2 0x00010014 +-#define CS35L41_IRQ1_STATUS3 0x00010018 +-#define CS35L41_IRQ1_STATUS4 0x0001001C +-#define CS35L41_IRQ1_RAW_STATUS1 0x00010090 +-#define CS35L41_IRQ1_RAW_STATUS2 0x00010094 +-#define CS35L41_IRQ1_RAW_STATUS3 0x00010098 +-#define CS35L41_IRQ1_RAW_STATUS4 0x0001009C +-#define CS35L41_IRQ1_MASK1 0x00010110 +-#define CS35L41_IRQ1_MASK2 0x00010114 +-#define CS35L41_IRQ1_MASK3 0x00010118 +-#define CS35L41_IRQ1_MASK4 0x0001011C +-#define CS35L41_IRQ1_FRC1 0x00010190 +-#define CS35L41_IRQ1_FRC2 0x00010194 +-#define CS35L41_IRQ1_FRC3 0x00010198 +-#define CS35L41_IRQ1_FRC4 0x0001019C +-#define CS35L41_IRQ1_EDGE1 0x00010210 +-#define CS35L41_IRQ1_EDGE4 0x0001021C +-#define CS35L41_IRQ1_POL1 0x00010290 +-#define CS35L41_IRQ1_POL2 0x00010294 +-#define CS35L41_IRQ1_POL3 0x00010298 +-#define CS35L41_IRQ1_POL4 0x0001029C +-#define CS35L41_IRQ1_DB3 0x00010318 +-#define CS35L41_IRQ2_CFG 0x00010800 +-#define CS35L41_IRQ2_STATUS 0x00010804 +-#define CS35L41_IRQ2_STATUS1 0x00010810 +-#define CS35L41_IRQ2_STATUS2 0x00010814 +-#define CS35L41_IRQ2_STATUS3 0x00010818 +-#define CS35L41_IRQ2_STATUS4 0x0001081C +-#define CS35L41_IRQ2_RAW_STATUS1 0x00010890 +-#define CS35L41_IRQ2_RAW_STATUS2 0x00010894 +-#define CS35L41_IRQ2_RAW_STATUS3 0x00010898 +-#define CS35L41_IRQ2_RAW_STATUS4 0x0001089C +-#define CS35L41_IRQ2_MASK1 0x00010910 +-#define CS35L41_IRQ2_MASK2 0x00010914 +-#define CS35L41_IRQ2_MASK3 0x00010918 +-#define CS35L41_IRQ2_MASK4 0x0001091C +-#define CS35L41_IRQ2_FRC1 0x00010990 +-#define CS35L41_IRQ2_FRC2 0x00010994 +-#define CS35L41_IRQ2_FRC3 0x00010998 +-#define CS35L41_IRQ2_FRC4 0x0001099C +-#define CS35L41_IRQ2_EDGE1 0x00010A10 +-#define CS35L41_IRQ2_EDGE4 0x00010A1C +-#define CS35L41_IRQ2_POL1 0x00010A90 +-#define CS35L41_IRQ2_POL2 0x00010A94 +-#define CS35L41_IRQ2_POL3 0x00010A98 +-#define CS35L41_IRQ2_POL4 0x00010A9C +-#define CS35L41_IRQ2_DB3 0x00010B18 +-#define CS35L41_GPIO_STATUS1 0x00011000 +-#define CS35L41_GPIO1_CTRL1 0x00011008 +-#define CS35L41_GPIO2_CTRL1 0x0001100C +-#define CS35L41_MIXER_NGATE_CFG 0x00012000 +-#define CS35L41_MIXER_NGATE_CH1_CFG 0x00012004 +-#define CS35L41_MIXER_NGATE_CH2_CFG 0x00012008 +-#define CS35L41_DSP_MBOX_1 0x00013000 +-#define CS35L41_DSP_MBOX_2 0x00013004 +-#define CS35L41_DSP_MBOX_3 0x00013008 +-#define CS35L41_DSP_MBOX_4 0x0001300C +-#define CS35L41_DSP_MBOX_5 0x00013010 +-#define CS35L41_DSP_MBOX_6 0x00013014 +-#define CS35L41_DSP_MBOX_7 0x00013018 +-#define CS35L41_DSP_MBOX_8 0x0001301C +-#define CS35L41_DSP_VIRT1_MBOX_1 0x00013020 +-#define CS35L41_DSP_VIRT1_MBOX_2 0x00013024 +-#define CS35L41_DSP_VIRT1_MBOX_3 0x00013028 +-#define CS35L41_DSP_VIRT1_MBOX_4 0x0001302C +-#define CS35L41_DSP_VIRT1_MBOX_5 0x00013030 +-#define CS35L41_DSP_VIRT1_MBOX_6 0x00013034 +-#define CS35L41_DSP_VIRT1_MBOX_7 0x00013038 +-#define CS35L41_DSP_VIRT1_MBOX_8 0x0001303C +-#define CS35L41_DSP_VIRT2_MBOX_1 0x00013040 +-#define CS35L41_DSP_VIRT2_MBOX_2 0x00013044 +-#define CS35L41_DSP_VIRT2_MBOX_3 0x00013048 +-#define CS35L41_DSP_VIRT2_MBOX_4 0x0001304C +-#define CS35L41_DSP_VIRT2_MBOX_5 0x00013050 +-#define CS35L41_DSP_VIRT2_MBOX_6 0x00013054 +-#define CS35L41_DSP_VIRT2_MBOX_7 0x00013058 +-#define CS35L41_DSP_VIRT2_MBOX_8 0x0001305C +-#define CS35L41_CLOCK_DETECT_1 0x00014000 +-#define CS35L41_TIMER1_CONTROL 0x00015000 +-#define CS35L41_TIMER1_COUNT_PRESET 0x00015004 +-#define CS35L41_TIMER1_START_STOP 0x0001500C +-#define CS35L41_TIMER1_STATUS 0x00015010 +-#define CS35L41_TIMER1_COUNT_READBACK 0x00015014 +-#define CS35L41_TIMER1_DSP_CLK_CFG 0x00015018 +-#define CS35L41_TIMER1_DSP_CLK_STATUS 0x0001501C +-#define CS35L41_TIMER2_CONTROL 0x00015100 +-#define CS35L41_TIMER2_COUNT_PRESET 0x00015104 +-#define CS35L41_TIMER2_START_STOP 0x0001510C +-#define CS35L41_TIMER2_STATUS 0x00015110 +-#define CS35L41_TIMER2_COUNT_READBACK 0x00015114 +-#define CS35L41_TIMER2_DSP_CLK_CFG 0x00015118 +-#define CS35L41_TIMER2_DSP_CLK_STATUS 0x0001511C +-#define CS35L41_DFT_JTAG_CONTROL 0x00016000 +-#define CS35L41_DIE_STS1 0x00017040 +-#define CS35L41_DIE_STS2 0x00017044 +-#define CS35L41_TEMP_CAL1 0x00017048 +-#define CS35L41_TEMP_CAL2 0x0001704C +-#define CS35L41_DSP1_XMEM_PACK_0 0x02000000 +-#define CS35L41_DSP1_XMEM_PACK_3068 0x02002FF0 +-#define CS35L41_DSP1_XMEM_UNPACK32_0 0x02400000 +-#define CS35L41_DSP1_XMEM_UNPACK32_2046 0x02401FF8 +-#define CS35L41_DSP1_TIMESTAMP_COUNT 0x025C0800 +-#define CS35L41_DSP1_SYS_ID 0x025E0000 +-#define CS35L41_DSP1_SYS_VERSION 0x025E0004 +-#define CS35L41_DSP1_SYS_CORE_ID 0x025E0008 +-#define CS35L41_DSP1_SYS_AHB_ADDR 0x025E000C +-#define CS35L41_DSP1_SYS_XSRAM_SIZE 0x025E0010 +-#define CS35L41_DSP1_SYS_YSRAM_SIZE 0x025E0018 +-#define CS35L41_DSP1_SYS_PSRAM_SIZE 0x025E0020 +-#define CS35L41_DSP1_SYS_PM_BOOT_SIZE 0x025E0028 +-#define CS35L41_DSP1_SYS_FEATURES 0x025E002C +-#define CS35L41_DSP1_SYS_FIR_FILTERS 0x025E0030 +-#define CS35L41_DSP1_SYS_LMS_FILTERS 0x025E0034 +-#define CS35L41_DSP1_SYS_XM_BANK_SIZE 0x025E0038 +-#define CS35L41_DSP1_SYS_YM_BANK_SIZE 0x025E003C +-#define CS35L41_DSP1_SYS_PM_BANK_SIZE 0x025E0040 +-#define CS35L41_DSP1_AHBM_WIN0_CTRL0 0x025E2000 +-#define CS35L41_DSP1_AHBM_WIN0_CTRL1 0x025E2004 +-#define CS35L41_DSP1_AHBM_WIN1_CTRL0 0x025E2008 +-#define CS35L41_DSP1_AHBM_WIN1_CTRL1 0x025E200C +-#define CS35L41_DSP1_AHBM_WIN2_CTRL0 0x025E2010 +-#define CS35L41_DSP1_AHBM_WIN2_CTRL1 0x025E2014 +-#define CS35L41_DSP1_AHBM_WIN3_CTRL0 0x025E2018 +-#define CS35L41_DSP1_AHBM_WIN3_CTRL1 0x025E201C +-#define CS35L41_DSP1_AHBM_WIN4_CTRL0 0x025E2020 +-#define CS35L41_DSP1_AHBM_WIN4_CTRL1 0x025E2024 +-#define CS35L41_DSP1_AHBM_WIN5_CTRL0 0x025E2028 +-#define CS35L41_DSP1_AHBM_WIN5_CTRL1 0x025E202C +-#define CS35L41_DSP1_AHBM_WIN6_CTRL0 0x025E2030 +-#define CS35L41_DSP1_AHBM_WIN6_CTRL1 0x025E2034 +-#define CS35L41_DSP1_AHBM_WIN7_CTRL0 0x025E2038 +-#define CS35L41_DSP1_AHBM_WIN7_CTRL1 0x025E203C +-#define CS35L41_DSP1_AHBM_WIN_DBG_CTRL0 0x025E2040 +-#define CS35L41_DSP1_AHBM_WIN_DBG_CTRL1 0x025E2044 +-#define CS35L41_DSP1_XMEM_UNPACK24_0 0x02800000 +-#define CS35L41_DSP1_XMEM_UNPACK24_4093 0x02803FF4 +-#define CS35L41_DSP1_CTRL_BASE 0x02B80000 +-#define CS35L41_DSP1_CORE_SOFT_RESET 0x02B80010 +-#define CS35L41_DSP1_DEBUG 0x02B80040 +-#define CS35L41_DSP1_TIMER_CTRL 0x02B80048 +-#define CS35L41_DSP1_STREAM_ARB_CTRL 0x02B80050 +-#define CS35L41_DSP1_RX1_RATE 0x02B80080 +-#define CS35L41_DSP1_RX2_RATE 0x02B80088 +-#define CS35L41_DSP1_RX3_RATE 0x02B80090 +-#define CS35L41_DSP1_RX4_RATE 0x02B80098 +-#define CS35L41_DSP1_RX5_RATE 0x02B800A0 +-#define CS35L41_DSP1_RX6_RATE 0x02B800A8 +-#define CS35L41_DSP1_RX7_RATE 0x02B800B0 +-#define CS35L41_DSP1_RX8_RATE 0x02B800B8 +-#define CS35L41_DSP1_TX1_RATE 0x02B80280 +-#define CS35L41_DSP1_TX2_RATE 0x02B80288 +-#define CS35L41_DSP1_TX3_RATE 0x02B80290 +-#define CS35L41_DSP1_TX4_RATE 0x02B80298 +-#define CS35L41_DSP1_TX5_RATE 0x02B802A0 +-#define CS35L41_DSP1_TX6_RATE 0x02B802A8 +-#define CS35L41_DSP1_TX7_RATE 0x02B802B0 +-#define CS35L41_DSP1_TX8_RATE 0x02B802B8 +-#define CS35L41_DSP1_NMI_CTRL1 0x02B80480 +-#define CS35L41_DSP1_NMI_CTRL2 0x02B80488 +-#define CS35L41_DSP1_NMI_CTRL3 0x02B80490 +-#define CS35L41_DSP1_NMI_CTRL4 0x02B80498 +-#define CS35L41_DSP1_NMI_CTRL5 0x02B804A0 +-#define CS35L41_DSP1_NMI_CTRL6 0x02B804A8 +-#define CS35L41_DSP1_NMI_CTRL7 0x02B804B0 +-#define CS35L41_DSP1_NMI_CTRL8 0x02B804B8 +-#define CS35L41_DSP1_RESUME_CTRL 0x02B80500 +-#define CS35L41_DSP1_IRQ1_CTRL 0x02B80508 +-#define CS35L41_DSP1_IRQ2_CTRL 0x02B80510 +-#define CS35L41_DSP1_IRQ3_CTRL 0x02B80518 +-#define CS35L41_DSP1_IRQ4_CTRL 0x02B80520 +-#define CS35L41_DSP1_IRQ5_CTRL 0x02B80528 +-#define CS35L41_DSP1_IRQ6_CTRL 0x02B80530 +-#define CS35L41_DSP1_IRQ7_CTRL 0x02B80538 +-#define CS35L41_DSP1_IRQ8_CTRL 0x02B80540 +-#define CS35L41_DSP1_IRQ9_CTRL 0x02B80548 +-#define CS35L41_DSP1_IRQ10_CTRL 0x02B80550 +-#define CS35L41_DSP1_IRQ11_CTRL 0x02B80558 +-#define CS35L41_DSP1_IRQ12_CTRL 0x02B80560 +-#define CS35L41_DSP1_IRQ13_CTRL 0x02B80568 +-#define CS35L41_DSP1_IRQ14_CTRL 0x02B80570 +-#define CS35L41_DSP1_IRQ15_CTRL 0x02B80578 +-#define CS35L41_DSP1_IRQ16_CTRL 0x02B80580 +-#define CS35L41_DSP1_IRQ17_CTRL 0x02B80588 +-#define CS35L41_DSP1_IRQ18_CTRL 0x02B80590 +-#define CS35L41_DSP1_IRQ19_CTRL 0x02B80598 +-#define CS35L41_DSP1_IRQ20_CTRL 0x02B805A0 +-#define CS35L41_DSP1_IRQ21_CTRL 0x02B805A8 +-#define CS35L41_DSP1_IRQ22_CTRL 0x02B805B0 +-#define CS35L41_DSP1_IRQ23_CTRL 0x02B805B8 +-#define CS35L41_DSP1_SCRATCH1 0x02B805C0 +-#define CS35L41_DSP1_SCRATCH2 0x02B805C8 +-#define CS35L41_DSP1_SCRATCH3 0x02B805D0 +-#define CS35L41_DSP1_SCRATCH4 0x02B805D8 +-#define CS35L41_DSP1_CCM_CORE_CTRL 0x02BC1000 +-#define CS35L41_DSP1_CCM_CLK_OVERRIDE 0x02BC1008 +-#define CS35L41_DSP1_XM_MSTR_EN 0x02BC2000 +-#define CS35L41_DSP1_XM_CORE_PRI 0x02BC2008 +-#define CS35L41_DSP1_XM_AHB_PACK_PL_PRI 0x02BC2010 +-#define CS35L41_DSP1_XM_AHB_UP_PL_PRI 0x02BC2018 +-#define CS35L41_DSP1_XM_ACCEL_PL0_PRI 0x02BC2020 +-#define CS35L41_DSP1_XM_NPL0_PRI 0x02BC2078 +-#define CS35L41_DSP1_YM_MSTR_EN 0x02BC20C0 +-#define CS35L41_DSP1_YM_CORE_PRI 0x02BC20C8 +-#define CS35L41_DSP1_YM_AHB_PACK_PL_PRI 0x02BC20D0 +-#define CS35L41_DSP1_YM_AHB_UP_PL_PRI 0x02BC20D8 +-#define CS35L41_DSP1_YM_ACCEL_PL0_PRI 0x02BC20E0 +-#define CS35L41_DSP1_YM_NPL0_PRI 0x02BC2138 +-#define CS35L41_DSP1_PM_MSTR_EN 0x02BC2180 +-#define CS35L41_DSP1_PM_PATCH0_ADDR 0x02BC2188 +-#define CS35L41_DSP1_PM_PATCH0_EN 0x02BC218C +-#define CS35L41_DSP1_PM_PATCH0_DATA_LO 0x02BC2190 +-#define CS35L41_DSP1_PM_PATCH0_DATA_HI 0x02BC2194 +-#define CS35L41_DSP1_PM_PATCH1_ADDR 0x02BC2198 +-#define CS35L41_DSP1_PM_PATCH1_EN 0x02BC219C +-#define CS35L41_DSP1_PM_PATCH1_DATA_LO 0x02BC21A0 +-#define CS35L41_DSP1_PM_PATCH1_DATA_HI 0x02BC21A4 +-#define CS35L41_DSP1_PM_PATCH2_ADDR 0x02BC21A8 +-#define CS35L41_DSP1_PM_PATCH2_EN 0x02BC21AC +-#define CS35L41_DSP1_PM_PATCH2_DATA_LO 0x02BC21B0 +-#define CS35L41_DSP1_PM_PATCH2_DATA_HI 0x02BC21B4 +-#define CS35L41_DSP1_PM_PATCH3_ADDR 0x02BC21B8 +-#define CS35L41_DSP1_PM_PATCH3_EN 0x02BC21BC +-#define CS35L41_DSP1_PM_PATCH3_DATA_LO 0x02BC21C0 +-#define CS35L41_DSP1_PM_PATCH3_DATA_HI 0x02BC21C4 +-#define CS35L41_DSP1_PM_PATCH4_ADDR 0x02BC21C8 +-#define CS35L41_DSP1_PM_PATCH4_EN 0x02BC21CC +-#define CS35L41_DSP1_PM_PATCH4_DATA_LO 0x02BC21D0 +-#define CS35L41_DSP1_PM_PATCH4_DATA_HI 0x02BC21D4 +-#define CS35L41_DSP1_PM_PATCH5_ADDR 0x02BC21D8 +-#define CS35L41_DSP1_PM_PATCH5_EN 0x02BC21DC +-#define CS35L41_DSP1_PM_PATCH5_DATA_LO 0x02BC21E0 +-#define CS35L41_DSP1_PM_PATCH5_DATA_HI 0x02BC21E4 +-#define CS35L41_DSP1_PM_PATCH6_ADDR 0x02BC21E8 +-#define CS35L41_DSP1_PM_PATCH6_EN 0x02BC21EC +-#define CS35L41_DSP1_PM_PATCH6_DATA_LO 0x02BC21F0 +-#define CS35L41_DSP1_PM_PATCH6_DATA_HI 0x02BC21F4 +-#define CS35L41_DSP1_PM_PATCH7_ADDR 0x02BC21F8 +-#define CS35L41_DSP1_PM_PATCH7_EN 0x02BC21FC +-#define CS35L41_DSP1_PM_PATCH7_DATA_LO 0x02BC2200 +-#define CS35L41_DSP1_PM_PATCH7_DATA_HI 0x02BC2204 +-#define CS35L41_DSP1_MPU_XM_ACCESS0 0x02BC3000 +-#define CS35L41_DSP1_MPU_YM_ACCESS0 0x02BC3004 +-#define CS35L41_DSP1_MPU_WNDW_ACCESS0 0x02BC3008 +-#define CS35L41_DSP1_MPU_XREG_ACCESS0 0x02BC300C +-#define CS35L41_DSP1_MPU_YREG_ACCESS0 0x02BC3014 +-#define CS35L41_DSP1_MPU_XM_ACCESS1 0x02BC3018 +-#define CS35L41_DSP1_MPU_YM_ACCESS1 0x02BC301C +-#define CS35L41_DSP1_MPU_WNDW_ACCESS1 0x02BC3020 +-#define CS35L41_DSP1_MPU_XREG_ACCESS1 0x02BC3024 +-#define CS35L41_DSP1_MPU_YREG_ACCESS1 0x02BC302C +-#define CS35L41_DSP1_MPU_XM_ACCESS2 0x02BC3030 +-#define CS35L41_DSP1_MPU_YM_ACCESS2 0x02BC3034 +-#define CS35L41_DSP1_MPU_WNDW_ACCESS2 0x02BC3038 +-#define CS35L41_DSP1_MPU_XREG_ACCESS2 0x02BC303C +-#define CS35L41_DSP1_MPU_YREG_ACCESS2 0x02BC3044 +-#define CS35L41_DSP1_MPU_XM_ACCESS3 0x02BC3048 +-#define CS35L41_DSP1_MPU_YM_ACCESS3 0x02BC304C +-#define CS35L41_DSP1_MPU_WNDW_ACCESS3 0x02BC3050 +-#define CS35L41_DSP1_MPU_XREG_ACCESS3 0x02BC3054 +-#define CS35L41_DSP1_MPU_YREG_ACCESS3 0x02BC305C +-#define CS35L41_DSP1_MPU_XM_VIO_ADDR 0x02BC3100 +-#define CS35L41_DSP1_MPU_XM_VIO_STATUS 0x02BC3104 +-#define CS35L41_DSP1_MPU_YM_VIO_ADDR 0x02BC3108 +-#define CS35L41_DSP1_MPU_YM_VIO_STATUS 0x02BC310C +-#define CS35L41_DSP1_MPU_PM_VIO_ADDR 0x02BC3110 +-#define CS35L41_DSP1_MPU_PM_VIO_STATUS 0x02BC3114 +-#define CS35L41_DSP1_MPU_LOCK_CONFIG 0x02BC3140 +-#define CS35L41_DSP1_MPU_WDT_RST_CTRL 0x02BC3180 +-#define CS35L41_DSP1_STRMARB_MSTR0_CFG0 0x02BC5000 +-#define CS35L41_DSP1_STRMARB_MSTR0_CFG1 0x02BC5004 +-#define CS35L41_DSP1_STRMARB_MSTR0_CFG2 0x02BC5008 +-#define CS35L41_DSP1_STRMARB_MSTR1_CFG0 0x02BC5010 +-#define CS35L41_DSP1_STRMARB_MSTR1_CFG1 0x02BC5014 +-#define CS35L41_DSP1_STRMARB_MSTR1_CFG2 0x02BC5018 +-#define CS35L41_DSP1_STRMARB_MSTR2_CFG0 0x02BC5020 +-#define CS35L41_DSP1_STRMARB_MSTR2_CFG1 0x02BC5024 +-#define CS35L41_DSP1_STRMARB_MSTR2_CFG2 0x02BC5028 +-#define CS35L41_DSP1_STRMARB_MSTR3_CFG0 0x02BC5030 +-#define CS35L41_DSP1_STRMARB_MSTR3_CFG1 0x02BC5034 +-#define CS35L41_DSP1_STRMARB_MSTR3_CFG2 0x02BC5038 +-#define CS35L41_DSP1_STRMARB_MSTR4_CFG0 0x02BC5040 +-#define CS35L41_DSP1_STRMARB_MSTR4_CFG1 0x02BC5044 +-#define CS35L41_DSP1_STRMARB_MSTR4_CFG2 0x02BC5048 +-#define CS35L41_DSP1_STRMARB_MSTR5_CFG0 0x02BC5050 +-#define CS35L41_DSP1_STRMARB_MSTR5_CFG1 0x02BC5054 +-#define CS35L41_DSP1_STRMARB_MSTR5_CFG2 0x02BC5058 +-#define CS35L41_DSP1_STRMARB_MSTR6_CFG0 0x02BC5060 +-#define CS35L41_DSP1_STRMARB_MSTR6_CFG1 0x02BC5064 +-#define CS35L41_DSP1_STRMARB_MSTR6_CFG2 0x02BC5068 +-#define CS35L41_DSP1_STRMARB_MSTR7_CFG0 0x02BC5070 +-#define CS35L41_DSP1_STRMARB_MSTR7_CFG1 0x02BC5074 +-#define CS35L41_DSP1_STRMARB_MSTR7_CFG2 0x02BC5078 +-#define CS35L41_DSP1_STRMARB_TX0_CFG0 0x02BC5200 +-#define CS35L41_DSP1_STRMARB_TX0_CFG1 0x02BC5204 +-#define CS35L41_DSP1_STRMARB_TX1_CFG0 0x02BC5208 +-#define CS35L41_DSP1_STRMARB_TX1_CFG1 0x02BC520C +-#define CS35L41_DSP1_STRMARB_TX2_CFG0 0x02BC5210 +-#define CS35L41_DSP1_STRMARB_TX2_CFG1 0x02BC5214 +-#define CS35L41_DSP1_STRMARB_TX3_CFG0 0x02BC5218 +-#define CS35L41_DSP1_STRMARB_TX3_CFG1 0x02BC521C +-#define CS35L41_DSP1_STRMARB_TX4_CFG0 0x02BC5220 +-#define CS35L41_DSP1_STRMARB_TX4_CFG1 0x02BC5224 +-#define CS35L41_DSP1_STRMARB_TX5_CFG0 0x02BC5228 +-#define CS35L41_DSP1_STRMARB_TX5_CFG1 0x02BC522C +-#define CS35L41_DSP1_STRMARB_TX6_CFG0 0x02BC5230 +-#define CS35L41_DSP1_STRMARB_TX6_CFG1 0x02BC5234 +-#define CS35L41_DSP1_STRMARB_TX7_CFG0 0x02BC5238 +-#define CS35L41_DSP1_STRMARB_TX7_CFG1 0x02BC523C +-#define CS35L41_DSP1_STRMARB_RX0_CFG0 0x02BC5400 +-#define CS35L41_DSP1_STRMARB_RX0_CFG1 0x02BC5404 +-#define CS35L41_DSP1_STRMARB_RX1_CFG0 0x02BC5408 +-#define CS35L41_DSP1_STRMARB_RX1_CFG1 0x02BC540C +-#define CS35L41_DSP1_STRMARB_RX2_CFG0 0x02BC5410 +-#define CS35L41_DSP1_STRMARB_RX2_CFG1 0x02BC5414 +-#define CS35L41_DSP1_STRMARB_RX3_CFG0 0x02BC5418 +-#define CS35L41_DSP1_STRMARB_RX3_CFG1 0x02BC541C +-#define CS35L41_DSP1_STRMARB_RX4_CFG0 0x02BC5420 +-#define CS35L41_DSP1_STRMARB_RX4_CFG1 0x02BC5424 +-#define CS35L41_DSP1_STRMARB_RX5_CFG0 0x02BC5428 +-#define CS35L41_DSP1_STRMARB_RX5_CFG1 0x02BC542C +-#define CS35L41_DSP1_STRMARB_RX6_CFG0 0x02BC5430 +-#define CS35L41_DSP1_STRMARB_RX6_CFG1 0x02BC5434 +-#define CS35L41_DSP1_STRMARB_RX7_CFG0 0x02BC5438 +-#define CS35L41_DSP1_STRMARB_RX7_CFG1 0x02BC543C +-#define CS35L41_DSP1_STRMARB_IRQ0_CFG0 0x02BC5600 +-#define CS35L41_DSP1_STRMARB_IRQ0_CFG1 0x02BC5604 +-#define CS35L41_DSP1_STRMARB_IRQ0_CFG2 0x02BC5608 +-#define CS35L41_DSP1_STRMARB_IRQ1_CFG0 0x02BC5610 +-#define CS35L41_DSP1_STRMARB_IRQ1_CFG1 0x02BC5614 +-#define CS35L41_DSP1_STRMARB_IRQ1_CFG2 0x02BC5618 +-#define CS35L41_DSP1_STRMARB_IRQ2_CFG0 0x02BC5620 +-#define CS35L41_DSP1_STRMARB_IRQ2_CFG1 0x02BC5624 +-#define CS35L41_DSP1_STRMARB_IRQ2_CFG2 0x02BC5628 +-#define CS35L41_DSP1_STRMARB_IRQ3_CFG0 0x02BC5630 +-#define CS35L41_DSP1_STRMARB_IRQ3_CFG1 0x02BC5634 +-#define CS35L41_DSP1_STRMARB_IRQ3_CFG2 0x02BC5638 +-#define CS35L41_DSP1_STRMARB_IRQ4_CFG0 0x02BC5640 +-#define CS35L41_DSP1_STRMARB_IRQ4_CFG1 0x02BC5644 +-#define CS35L41_DSP1_STRMARB_IRQ4_CFG2 0x02BC5648 +-#define CS35L41_DSP1_STRMARB_IRQ5_CFG0 0x02BC5650 +-#define CS35L41_DSP1_STRMARB_IRQ5_CFG1 0x02BC5654 +-#define CS35L41_DSP1_STRMARB_IRQ5_CFG2 0x02BC5658 +-#define CS35L41_DSP1_STRMARB_IRQ6_CFG0 0x02BC5660 +-#define CS35L41_DSP1_STRMARB_IRQ6_CFG1 0x02BC5664 +-#define CS35L41_DSP1_STRMARB_IRQ6_CFG2 0x02BC5668 +-#define CS35L41_DSP1_STRMARB_IRQ7_CFG0 0x02BC5670 +-#define CS35L41_DSP1_STRMARB_IRQ7_CFG1 0x02BC5674 +-#define CS35L41_DSP1_STRMARB_IRQ7_CFG2 0x02BC5678 +-#define CS35L41_DSP1_STRMARB_RESYNC_MSK 0x02BC5A00 +-#define CS35L41_DSP1_STRMARB_ERR_STATUS 0x02BC5A08 +-#define CS35L41_DSP1_INTPCTL_RES_STATIC 0x02BC6000 +-#define CS35L41_DSP1_INTPCTL_RES_DYN 0x02BC6004 +-#define CS35L41_DSP1_INTPCTL_NMI_CTRL 0x02BC6008 +-#define CS35L41_DSP1_INTPCTL_IRQ_INV 0x02BC6010 +-#define CS35L41_DSP1_INTPCTL_IRQ_MODE 0x02BC6014 +-#define CS35L41_DSP1_INTPCTL_IRQ_EN 0x02BC6018 +-#define CS35L41_DSP1_INTPCTL_IRQ_MSK 0x02BC601C +-#define CS35L41_DSP1_INTPCTL_IRQ_FLUSH 0x02BC6020 +-#define CS35L41_DSP1_INTPCTL_IRQ_MSKCLR 0x02BC6024 +-#define CS35L41_DSP1_INTPCTL_IRQ_FRC 0x02BC6028 +-#define CS35L41_DSP1_INTPCTL_IRQ_MSKSET 0x02BC602C +-#define CS35L41_DSP1_INTPCTL_IRQ_ERR 0x02BC6030 +-#define CS35L41_DSP1_INTPCTL_IRQ_PEND 0x02BC6034 +-#define CS35L41_DSP1_INTPCTL_IRQ_GEN 0x02BC6038 +-#define CS35L41_DSP1_INTPCTL_TESTBITS 0x02BC6040 +-#define CS35L41_DSP1_WDT_CONTROL 0x02BC7000 +-#define CS35L41_DSP1_WDT_STATUS 0x02BC7008 +-#define CS35L41_DSP1_YMEM_PACK_0 0x02C00000 +-#define CS35L41_DSP1_YMEM_PACK_1532 0x02C017F0 +-#define CS35L41_DSP1_YMEM_UNPACK32_0 0x03000000 +-#define CS35L41_DSP1_YMEM_UNPACK32_1022 0x03000FF8 +-#define CS35L41_DSP1_YMEM_UNPACK24_0 0x03400000 +-#define CS35L41_DSP1_YMEM_UNPACK24_2045 0x03401FF4 +-#define CS35L41_DSP1_PMEM_0 0x03800000 +-#define CS35L41_DSP1_PMEM_5114 0x03804FE8 +- +-/*test regs for emulation bringup*/ +-#define CS35L41_PLL_OVR 0x00003018 +-#define CS35L41_BST_TEST_DUTY 0x00003900 +-#define CS35L41_DIGPWM_IOCTRL 0x0000706C +- +-/*registers populated by OTP*/ +-#define CS35L41_OTP_TRIM_1 0x0000208c +-#define CS35L41_OTP_TRIM_2 0x00002090 +-#define CS35L41_OTP_TRIM_3 0x00003010 +-#define CS35L41_OTP_TRIM_4 0x0000300C +-#define CS35L41_OTP_TRIM_5 0x0000394C +-#define CS35L41_OTP_TRIM_6 0x00003950 +-#define CS35L41_OTP_TRIM_7 0x00003954 +-#define CS35L41_OTP_TRIM_8 0x00003958 +-#define CS35L41_OTP_TRIM_9 0x0000395C +-#define CS35L41_OTP_TRIM_10 0x0000416C +-#define CS35L41_OTP_TRIM_11 0x00004160 +-#define CS35L41_OTP_TRIM_12 0x00004170 +-#define CS35L41_OTP_TRIM_13 0x00004360 +-#define CS35L41_OTP_TRIM_14 0x00004448 +-#define CS35L41_OTP_TRIM_15 0x0000444C +-#define CS35L41_OTP_TRIM_16 0x00006E30 +-#define CS35L41_OTP_TRIM_17 0x00006E34 +-#define CS35L41_OTP_TRIM_18 0x00006E38 +-#define CS35L41_OTP_TRIM_19 0x00006E3C +-#define CS35L41_OTP_TRIM_20 0x00006E40 +-#define CS35L41_OTP_TRIM_21 0x00006E44 +-#define CS35L41_OTP_TRIM_22 0x00006E48 +-#define CS35L41_OTP_TRIM_23 0x00006E4C +-#define CS35L41_OTP_TRIM_24 0x00006E50 +-#define CS35L41_OTP_TRIM_25 0x00006E54 +-#define CS35L41_OTP_TRIM_26 0x00006E58 +-#define CS35L41_OTP_TRIM_27 0x00006E5C +-#define CS35L41_OTP_TRIM_28 0x00006E60 +-#define CS35L41_OTP_TRIM_29 0x00006E64 +-#define CS35L41_OTP_TRIM_30 0x00007418 +-#define CS35L41_OTP_TRIM_31 0x0000741C +-#define CS35L41_OTP_TRIM_32 0x00007434 +-#define CS35L41_OTP_TRIM_33 0x00007068 +-#define CS35L41_OTP_TRIM_34 0x0000410C +-#define CS35L41_OTP_TRIM_35 0x0000400C +-#define CS35L41_OTP_TRIM_36 0x00002030 +- +-#define CS35L41_OTP_SIZE_WORDS 32 +-#define CS35L41_NUM_OTP_ELEM 100 +-#define CS35L41_NUM_OTP_MAPS 5 +- +-#define CS35L41_VALID_PDATA 0x80000000 +-#define CS35L41_NUM_SUPPLIES 2 +- +-#define CS35L41_SCLK_MSTR_MASK 0x10 +-#define CS35L41_SCLK_MSTR_SHIFT 4 +-#define CS35L41_LRCLK_MSTR_MASK 0x01 +-#define CS35L41_LRCLK_MSTR_SHIFT 0 +-#define CS35L41_SCLK_INV_MASK 0x40 +-#define CS35L41_SCLK_INV_SHIFT 6 +-#define CS35L41_LRCLK_INV_MASK 0x04 +-#define CS35L41_LRCLK_INV_SHIFT 2 +-#define CS35L41_SCLK_FRC_MASK 0x20 +-#define CS35L41_SCLK_FRC_SHIFT 5 +-#define CS35L41_LRCLK_FRC_MASK 0x02 +-#define CS35L41_LRCLK_FRC_SHIFT 1 +- +-#define CS35L41_AMP_GAIN_PCM_MASK 0x3E0 +-#define CS35L41_AMP_GAIN_ZC_MASK 0x0400 +-#define CS35L41_AMP_GAIN_ZC_SHIFT 10 +- +-#define CS35L41_BST_CTL_MASK 0xFF +-#define CS35L41_BST_CTL_SEL_MASK 0x03 +-#define CS35L41_BST_CTL_SEL_REG 0x00 +-#define CS35L41_BST_CTL_SEL_CLASSH 0x01 +-#define CS35L41_BST_IPK_MASK 0x7F +-#define CS35L41_BST_IPK_SHIFT 0 +-#define CS35L41_BST_LIM_MASK 0x4 +-#define CS35L41_BST_LIM_SHIFT 2 +-#define CS35L41_BST_K1_MASK 0x000000FF +-#define CS35L41_BST_K1_SHIFT 0 +-#define CS35L41_BST_K2_MASK 0x0000FF00 +-#define CS35L41_BST_K2_SHIFT 8 +-#define CS35L41_BST_SLOPE_MASK 0x0000FF00 +-#define CS35L41_BST_SLOPE_SHIFT 8 +-#define CS35L41_BST_LBST_VAL_MASK 0x00000003 +-#define CS35L41_BST_LBST_VAL_SHIFT 0 +- +-#define CS35L41_TEMP_THLD_MASK 0x03 +-#define CS35L41_VMON_IMON_VOL_MASK 0x07FF07FF +-#define CS35L41_PDM_MODE_MASK 0x01 +-#define CS35L41_PDM_MODE_SHIFT 0 +- +-#define CS35L41_CH_MEM_DEPTH_MASK 0x07 +-#define CS35L41_CH_MEM_DEPTH_SHIFT 0 +-#define CS35L41_CH_HDRM_CTL_MASK 0x007F0000 +-#define CS35L41_CH_HDRM_CTL_SHIFT 16 +-#define CS35L41_CH_REL_RATE_MASK 0xFF00 +-#define CS35L41_CH_REL_RATE_SHIFT 8 +-#define CS35L41_CH_WKFET_DLY_MASK 0x001C +-#define CS35L41_CH_WKFET_DLY_SHIFT 2 +-#define CS35L41_CH_WKFET_THLD_MASK 0x0F00 +-#define CS35L41_CH_WKFET_THLD_SHIFT 8 +- +-#define CS35L41_HW_NG_SEL_MASK 0x3F00 +-#define CS35L41_HW_NG_SEL_SHIFT 8 +-#define CS35L41_HW_NG_DLY_MASK 0x0070 +-#define CS35L41_HW_NG_DLY_SHIFT 4 +-#define CS35L41_HW_NG_THLD_MASK 0x0007 +-#define CS35L41_HW_NG_THLD_SHIFT 0 +- +-#define CS35L41_DSP_NG_ENABLE_MASK 0x00010000 +-#define CS35L41_DSP_NG_ENABLE_SHIFT 16 +-#define CS35L41_DSP_NG_THLD_MASK 0x7 +-#define CS35L41_DSP_NG_THLD_SHIFT 0 +-#define CS35L41_DSP_NG_DELAY_MASK 0x0F00 +-#define CS35L41_DSP_NG_DELAY_SHIFT 8 +- +-#define CS35L41_ASP_FMT_MASK 0x0700 +-#define CS35L41_ASP_FMT_SHIFT 8 +-#define CS35L41_ASP_DOUT_HIZ_MASK 0x03 +-#define CS35L41_ASP_DOUT_HIZ_SHIFT 0 +-#define CS35L41_ASP_WIDTH_16 0x10 +-#define CS35L41_ASP_WIDTH_24 0x18 +-#define CS35L41_ASP_WIDTH_32 0x20 +-#define CS35L41_ASP_WIDTH_TX_MASK 0xFF0000 +-#define CS35L41_ASP_WIDTH_TX_SHIFT 16 +-#define CS35L41_ASP_WIDTH_RX_MASK 0xFF000000 +-#define CS35L41_ASP_WIDTH_RX_SHIFT 24 +-#define CS35L41_ASP_RX1_SLOT_MASK 0x3F +-#define CS35L41_ASP_RX1_SLOT_SHIFT 0 +-#define CS35L41_ASP_RX2_SLOT_MASK 0x3F00 +-#define CS35L41_ASP_RX2_SLOT_SHIFT 8 +-#define CS35L41_ASP_RX_WL_MASK 0x3F +-#define CS35L41_ASP_TX_WL_MASK 0x3F +-#define CS35L41_ASP_RX_WL_SHIFT 0 +-#define CS35L41_ASP_TX_WL_SHIFT 0 +-#define CS35L41_ASP_SOURCE_MASK 0x7F +- +-#define CS35L41_INPUT_SRC_ASPRX1 0x08 +-#define CS35L41_INPUT_SRC_ASPRX2 0x09 +-#define CS35L41_INPUT_SRC_VMON 0x18 +-#define CS35L41_INPUT_SRC_IMON 0x19 +-#define CS35L41_INPUT_SRC_CLASSH 0x21 +-#define CS35L41_INPUT_SRC_VPMON 0x28 +-#define CS35L41_INPUT_SRC_VBSTMON 0x29 +-#define CS35L41_INPUT_SRC_TEMPMON 0x3A +-#define CS35L41_INPUT_SRC_RSVD 0x3B +-#define CS35L41_INPUT_DSP_TX1 0x32 +-#define CS35L41_INPUT_DSP_TX2 0x33 +- +-#define CS35L41_PLL_CLK_SEL_MASK 0x07 +-#define CS35L41_PLL_CLK_SEL_SHIFT 0 +-#define CS35L41_PLL_CLK_EN_MASK 0x10 +-#define CS35L41_PLL_CLK_EN_SHIFT 4 +-#define CS35L41_PLL_OPENLOOP_MASK 0x0800 +-#define CS35L41_PLL_OPENLOOP_SHIFT 11 +-#define CS35L41_PLLSRC_SCLK 0 +-#define CS35L41_PLLSRC_LRCLK 1 +-#define CS35L41_PLLSRC_SELF 3 +-#define CS35L41_PLLSRC_PDMCLK 4 +-#define CS35L41_PLLSRC_MCLK 5 +-#define CS35L41_PLLSRC_SWIRE 7 +-#define CS35L41_REFCLK_FREQ_MASK 0x7E0 +-#define CS35L41_REFCLK_FREQ_SHIFT 5 +- +-#define CS35L41_GLOBAL_FS_MASK 0x1F +-#define CS35L41_GLOBAL_FS_SHIFT 0 +- +-#define CS35L41_GLOBAL_EN_MASK 0x01 +-#define CS35L41_GLOBAL_EN_SHIFT 0 +-#define CS35L41_BST_EN_MASK 0x0030 +-#define CS35L41_BST_EN_SHIFT 4 +-#define CS35L41_BST_EN_DEFAULT 0x2 +-#define CS35L41_AMP_EN_SHIFT 0 +-#define CS35L41_AMP_EN_MASK 1 +- +-#define CS35L41_PDN_DONE_MASK 0x00800000 +-#define CS35L41_PDN_DONE_SHIFT 23 +-#define CS35L41_PUP_DONE_MASK 0x01000000 +-#define CS35L41_PUP_DONE_SHIFT 24 +- +-#define CS35L36_PUP_DONE_IRQ_UNMASK 0x5F +-#define CS35L36_PUP_DONE_IRQ_MASK 0xBF +- +-#define CS35L41_AMP_SHORT_ERR 0x80000000 +-#define CS35L41_BST_SHORT_ERR 0x0100 +-#define CS35L41_TEMP_WARN 0x8000 +-#define CS35L41_TEMP_ERR 0x00020000 +-#define CS35L41_BST_OVP_ERR 0x40 +-#define CS35L41_BST_DCM_UVP_ERR 0x80 +-#define CS35L41_OTP_BOOT_DONE 0x02 +-#define CS35L41_PLL_UNLOCK 0x10 +-#define CS35L41_OTP_BOOT_ERR 0x80000000 +- +-#define CS35L41_AMP_SHORT_ERR_RLS 0x02 +-#define CS35L41_BST_SHORT_ERR_RLS 0x04 +-#define CS35L41_BST_OVP_ERR_RLS 0x08 +-#define CS35L41_BST_UVP_ERR_RLS 0x10 +-#define CS35L41_TEMP_WARN_ERR_RLS 0x20 +-#define CS35L41_TEMP_ERR_RLS 0x40 +- +-#define CS35L41_INT1_MASK_DEFAULT 0x7FFCFE3F +-#define CS35L41_INT1_UNMASK_PUP 0xFEFFFFFF +-#define CS35L41_INT1_UNMASK_PDN 0xFF7FFFFF +- +-#define CS35L41_GPIO_DIR_MASK 0x80000000 +-#define CS35L41_GPIO_DIR_SHIFT 31 +-#define CS35L41_GPIO1_CTRL_MASK 0x00030000 +-#define CS35L41_GPIO1_CTRL_SHIFT 16 +-#define CS35L41_GPIO2_CTRL_MASK 0x07000000 +-#define CS35L41_GPIO2_CTRL_SHIFT 24 +-#define CS35L41_GPIO_CTRL_OPEN_INT 2 +-#define CS35L41_GPIO_CTRL_ACTV_LO 4 +-#define CS35L41_GPIO_CTRL_ACTV_HI 5 +-#define CS35L41_GPIO_POL_MASK 0x1000 +-#define CS35L41_GPIO_POL_SHIFT 12 +- +-#define CS35L41_AMP_INV_PCM_SHIFT 14 +-#define CS35L41_AMP_INV_PCM_MASK BIT(CS35L41_AMP_INV_PCM_SHIFT) +-#define CS35L41_AMP_PCM_VOL_SHIFT 3 +-#define CS35L41_AMP_PCM_VOL_MASK (0x7FF << 3) +-#define CS35L41_AMP_PCM_VOL_MUTE 0x4CF +- +-#define CS35L41_CHIP_ID 0x35a40 +-#define CS35L41R_CHIP_ID 0x35b40 +-#define CS35L41_MTLREVID_MASK 0x0F +-#define CS35L41_REVID_A0 0xA0 +-#define CS35L41_REVID_B0 0xB0 +-#define CS35L41_REVID_B2 0xB2 +- +-#define CS35L41_HALO_CORE_RESET 0x00000200 +- +-#define CS35L41_FS1_WINDOW_MASK 0x000007FF +-#define CS35L41_FS2_WINDOW_MASK 0x00FFF800 +-#define CS35L41_FS2_WINDOW_SHIFT 12 +- +-#define CS35L41_SPI_MAX_FREQ 4000000 +- + #define CS35L41_RX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) + #define CS35L41_TX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) + +-extern struct regmap_config cs35l41_regmap_i2c; +-extern struct regmap_config cs35l41_regmap_spi; +- +-struct cs35l41_otp_packed_element_t { +- u32 reg; +- u8 shift; +- u8 size; +-}; +- +-struct cs35l41_otp_map_element_t { +- u32 id; +- u32 num_elements; +- const struct cs35l41_otp_packed_element_t *map; +- u32 bit_offset; +- u32 word_offset; +-}; +- +-extern const struct cs35l41_otp_map_element_t +- cs35l41_otp_map_map[CS35L41_NUM_OTP_MAPS]; +- +-#define CS35L41_REGSTRIDE 4 +- + enum cs35l41_cspl_mbox_status { + CSPL_MBOX_STS_RUNNING = 0, + CSPL_MBOX_STS_PAUSED = 1, +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Correct-DSP-power-down.patch b/patches.suse/ASoC-cs35l41-Correct-DSP-power-down.patch new file mode 100644 index 0000000..e2abdc4 --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Correct-DSP-power-down.patch @@ -0,0 +1,55 @@ +From 56852cf4b2179fb90068a49538501f31c2de18ea Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Wed, 5 Jan 2022 11:30:21 +0000 +Subject: [PATCH] ASoC: cs35l41: Correct DSP power down +Git-commit: 56852cf4b2179fb90068a49538501f31c2de18ea +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +The wm_adsp_event should be called before the early_event on power +down, event stops the core running and early_event then powers down +the core. Additionally, the core should only be stopped if it was +actually running in the first place. + +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20220105113026.18955-4-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs35l41.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index 980294c1bcdb..05839fabf97b 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -181,17 +181,21 @@ static SOC_ENUM_SINGLE_DECL(pcm_sft_ramp, + static int cs35l41_dsp_preload_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) + { ++ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); ++ struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component); + int ret; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + return wm_adsp_early_event(w, kcontrol, event); + case SND_SOC_DAPM_PRE_PMD: +- ret = wm_adsp_early_event(w, kcontrol, event); +- if (ret) +- return ret; ++ if (cs35l41->dsp.cs_dsp.running) { ++ ret = wm_adsp_event(w, kcontrol, event); ++ if (ret) ++ return ret; ++ } + +- return wm_adsp_event(w, kcontrol, event); ++ return wm_adsp_early_event(w, kcontrol, event); + default: + return 0; + } +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Correct-handling-of-some-registers-in-t.patch b/patches.suse/ASoC-cs35l41-Correct-handling-of-some-registers-in-t.patch new file mode 100644 index 0000000..b0b246f --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Correct-handling-of-some-registers-in-t.patch @@ -0,0 +1,187 @@ +From 5f2f539901b0d9bda722637521a11b7f7cf753f1 Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Wed, 5 Jan 2022 11:30:22 +0000 +Subject: [PATCH] ASoC: cs35l41: Correct handling of some registers in the cache +Git-commit: 5f2f539901b0d9bda722637521a11b7f7cf753f1 +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +It makes no sense to cache the test/user key registers, since they +require values written at specific times, mark them volatile. It is +probably best if they can't be accessed from user-space either, so +mark them precious as well. + +The interrupt force, edge, polarity and debounce are all settings +applied to the IRQ rather than status bits and as such should not be +volatile. + +The OTP trim values will require re-application in the event of a +cache sync and as such should not be volatile. The OTPID however +should be volatile. + +The DSP scratch registers are used to read back an error/debug code +from the DSP on shutdown, as such these should be marked volatile. + +Finally, add some missing defaults, add TST_FS_MON0, and allow the +DSP core control register to be cached. + +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20220105113026.18955-5-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs35l41-lib.c | 81 +++++++++------------------------- + 1 file changed, 22 insertions(+), 59 deletions(-) + +diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c +index d026c5e3a378..639dcd25b17e 100644 +--- a/sound/soc/codecs/cs35l41-lib.c ++++ b/sound/soc/codecs/cs35l41-lib.c +@@ -20,6 +20,11 @@ static const struct reg_default cs35l41_reg[] = { + { CS35L41_PWR_CTRL2, 0x00000000 }, + { CS35L41_PWR_CTRL3, 0x01000010 }, + { CS35L41_GPIO_PAD_CONTROL, 0x00000000 }, ++ { CS35L41_GLOBAL_CLK_CTRL, 0x00000003 }, ++ { CS35L41_TST_FS_MON0, 0x00020016 }, ++ { CS35L41_BSTCVRT_COEFF, 0x00002424 }, ++ { CS35L41_BSTCVRT_SLOPE_LBST, 0x00007500 }, ++ { CS35L41_BSTCVRT_PEAK_CUR, 0x0000004A }, + { CS35L41_SP_ENABLES, 0x00000000 }, + { CS35L41_SP_RATE_CTRL, 0x00000028 }, + { CS35L41_SP_FORMAT, 0x18180200 }, +@@ -48,11 +53,16 @@ static const struct reg_default cs35l41_reg[] = { + { CS35L41_WKFET_CFG, 0x00000111 }, + { CS35L41_NG_CFG, 0x00000033 }, + { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, ++ { CS35L41_IRQ1_MASK1, 0xFFFFFFFF }, ++ { CS35L41_IRQ1_MASK2, 0xFFFFFFFF }, ++ { CS35L41_IRQ1_MASK3, 0xFFFF87FF }, ++ { CS35L41_IRQ1_MASK4, 0xFEFFFFFF }, + { CS35L41_GPIO1_CTRL1, 0xE1000001 }, + { CS35L41_GPIO2_CTRL1, 0xE1000001 }, + { CS35L41_MIXER_NGATE_CFG, 0x00000000 }, + { CS35L41_MIXER_NGATE_CH1_CFG, 0x00000303 }, + { CS35L41_MIXER_NGATE_CH2_CFG, 0x00000303 }, ++ { CS35L41_DSP1_CCM_CORE_CTRL, 0x00000101 }, + }; + + static bool cs35l41_readable_reg(struct device *dev, unsigned int reg) +@@ -84,6 +94,7 @@ static bool cs35l41_readable_reg(struct device *dev, unsigned int reg) + case CS35L41_DSP_CLK_CTRL: + case CS35L41_GLOBAL_CLK_CTRL: + case CS35L41_DATA_FS_SEL: ++ case CS35L41_TST_FS_MON0: + case CS35L41_MDSYNC_EN: + case CS35L41_MDSYNC_TX_ID: + case CS35L41_MDSYNC_PWR_CTRL: +@@ -342,7 +353,10 @@ static bool cs35l41_readable_reg(struct device *dev, unsigned int reg) + static bool cs35l41_precious_reg(struct device *dev, unsigned int reg) + { + switch (reg) { ++ case CS35L41_TEST_KEY_CTL: ++ case CS35L41_USER_KEY_CTL: + case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31: ++ case CS35L41_TST_FS_MON0: + case CS35L41_DSP1_XMEM_PACK_0 ... CS35L41_DSP1_XMEM_PACK_3068: + case CS35L41_DSP1_YMEM_PACK_0 ... CS35L41_DSP1_YMEM_PACK_1532: + case CS35L41_DSP1_PMEM_0 ... CS35L41_DSP1_PMEM_5114: +@@ -359,6 +373,9 @@ static bool cs35l41_volatile_reg(struct device *dev, unsigned int reg) + case CS35L41_SFT_RESET: + case CS35L41_FABID: + case CS35L41_REVID: ++ case CS35L41_OTPID: ++ case CS35L41_TEST_KEY_CTL: ++ case CS35L41_USER_KEY_CTL: + case CS35L41_DTEMP_EN: + case CS35L41_IRQ1_STATUS: + case CS35L41_IRQ1_STATUS1: +@@ -369,17 +386,6 @@ static bool cs35l41_volatile_reg(struct device *dev, unsigned int reg) + case CS35L41_IRQ1_RAW_STATUS2: + case CS35L41_IRQ1_RAW_STATUS3: + case CS35L41_IRQ1_RAW_STATUS4: +- case CS35L41_IRQ1_FRC1: +- case CS35L41_IRQ1_FRC2: +- case CS35L41_IRQ1_FRC3: +- case CS35L41_IRQ1_FRC4: +- case CS35L41_IRQ1_EDGE1: +- case CS35L41_IRQ1_EDGE4: +- case CS35L41_IRQ1_POL1: +- case CS35L41_IRQ1_POL2: +- case CS35L41_IRQ1_POL3: +- case CS35L41_IRQ1_POL4: +- case CS35L41_IRQ1_DB3: + case CS35L41_IRQ2_STATUS: + case CS35L41_IRQ2_STATUS1: + case CS35L41_IRQ2_STATUS2: +@@ -389,54 +395,7 @@ static bool cs35l41_volatile_reg(struct device *dev, unsigned int reg) + case CS35L41_IRQ2_RAW_STATUS2: + case CS35L41_IRQ2_RAW_STATUS3: + case CS35L41_IRQ2_RAW_STATUS4: +- case CS35L41_IRQ2_FRC1: +- case CS35L41_IRQ2_FRC2: +- case CS35L41_IRQ2_FRC3: +- case CS35L41_IRQ2_FRC4: +- case CS35L41_IRQ2_EDGE1: +- case CS35L41_IRQ2_EDGE4: +- case CS35L41_IRQ2_POL1: +- case CS35L41_IRQ2_POL2: +- case CS35L41_IRQ2_POL3: +- case CS35L41_IRQ2_POL4: +- case CS35L41_IRQ2_DB3: + case CS35L41_GPIO_STATUS1: +- case CS35L41_OTP_TRIM_1: +- case CS35L41_OTP_TRIM_2: +- case CS35L41_OTP_TRIM_3: +- case CS35L41_OTP_TRIM_4: +- case CS35L41_OTP_TRIM_5: +- case CS35L41_OTP_TRIM_6: +- case CS35L41_OTP_TRIM_7: +- case CS35L41_OTP_TRIM_8: +- case CS35L41_OTP_TRIM_9: +- case CS35L41_OTP_TRIM_10: +- case CS35L41_OTP_TRIM_11: +- case CS35L41_OTP_TRIM_12: +- case CS35L41_OTP_TRIM_13: +- case CS35L41_OTP_TRIM_14: +- case CS35L41_OTP_TRIM_15: +- case CS35L41_OTP_TRIM_16: +- case CS35L41_OTP_TRIM_17: +- case CS35L41_OTP_TRIM_18: +- case CS35L41_OTP_TRIM_19: +- case CS35L41_OTP_TRIM_20: +- case CS35L41_OTP_TRIM_21: +- case CS35L41_OTP_TRIM_22: +- case CS35L41_OTP_TRIM_23: +- case CS35L41_OTP_TRIM_24: +- case CS35L41_OTP_TRIM_25: +- case CS35L41_OTP_TRIM_26: +- case CS35L41_OTP_TRIM_27: +- case CS35L41_OTP_TRIM_28: +- case CS35L41_OTP_TRIM_29: +- case CS35L41_OTP_TRIM_30: +- case CS35L41_OTP_TRIM_31: +- case CS35L41_OTP_TRIM_32: +- case CS35L41_OTP_TRIM_33: +- case CS35L41_OTP_TRIM_34: +- case CS35L41_OTP_TRIM_35: +- case CS35L41_OTP_TRIM_36: + case CS35L41_DSP_MBOX_1 ... CS35L41_DSP_VIRT2_MBOX_8: + case CS35L41_DSP1_XMEM_PACK_0 ... CS35L41_DSP1_XMEM_PACK_3068: + case CS35L41_DSP1_XMEM_UNPACK32_0 ... CS35L41_DSP1_XMEM_UNPACK32_2046: +@@ -445,7 +404,11 @@ static bool cs35l41_volatile_reg(struct device *dev, unsigned int reg) + case CS35L41_DSP1_YMEM_UNPACK32_0 ... CS35L41_DSP1_YMEM_UNPACK32_1022: + case CS35L41_DSP1_YMEM_UNPACK24_0 ... CS35L41_DSP1_YMEM_UNPACK24_2045: + case CS35L41_DSP1_PMEM_0 ... CS35L41_DSP1_PMEM_5114: +- case CS35L41_DSP1_CCM_CORE_CTRL ... CS35L41_DSP1_WDT_STATUS: ++ case CS35L41_DSP1_SCRATCH1: ++ case CS35L41_DSP1_SCRATCH2: ++ case CS35L41_DSP1_SCRATCH3: ++ case CS35L41_DSP1_SCRATCH4: ++ case CS35L41_DSP1_CCM_CLK_OVERRIDE ... CS35L41_DSP1_WDT_STATUS: + case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31: + return true; + default: +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Correct-some-control-names.patch b/patches.suse/ASoC-cs35l41-Correct-some-control-names.patch new file mode 100644 index 0000000..345f55b --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Correct-some-control-names.patch @@ -0,0 +1,57 @@ +From c6a5f22f9b4fd5f21414be690ce34046d9712f05 Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Tue, 21 Jun 2022 11:20:40 +0100 +Subject: [PATCH] ASoC: cs35l41: Correct some control names +Git-commit: c6a5f22f9b4fd5f21414be690ce34046d9712f05 +Patch-mainline: v5.19-rc6 +References: bsc#1203699 + +Various boolean controls on cs35l41 are missing the required "Switch" in +the name, add these. + +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20220621102041.1713504-3-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs35l41.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index 3e68a07a3c8e..71ab2a5d1c55 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -333,7 +333,7 @@ static const struct snd_kcontrol_new cs35l41_aud_controls[] = { + SOC_SINGLE("HW Noise Gate Enable", CS35L41_NG_CFG, 8, 63, 0), + SOC_SINGLE("HW Noise Gate Delay", CS35L41_NG_CFG, 4, 7, 0), + SOC_SINGLE("HW Noise Gate Threshold", CS35L41_NG_CFG, 0, 7, 0), +- SOC_SINGLE("Aux Noise Gate CH1 Enable", ++ SOC_SINGLE("Aux Noise Gate CH1 Switch", + CS35L41_MIXER_NGATE_CH1_CFG, 16, 1, 0), + SOC_SINGLE("Aux Noise Gate CH1 Entry Delay", + CS35L41_MIXER_NGATE_CH1_CFG, 8, 15, 0), +@@ -341,15 +341,15 @@ static const struct snd_kcontrol_new cs35l41_aud_controls[] = { + CS35L41_MIXER_NGATE_CH1_CFG, 0, 7, 0), + SOC_SINGLE("Aux Noise Gate CH2 Entry Delay", + CS35L41_MIXER_NGATE_CH2_CFG, 8, 15, 0), +- SOC_SINGLE("Aux Noise Gate CH2 Enable", ++ SOC_SINGLE("Aux Noise Gate CH2 Switch", + CS35L41_MIXER_NGATE_CH2_CFG, 16, 1, 0), + SOC_SINGLE("Aux Noise Gate CH2 Threshold", + CS35L41_MIXER_NGATE_CH2_CFG, 0, 7, 0), +- SOC_SINGLE("SCLK Force", CS35L41_SP_FORMAT, CS35L41_SCLK_FRC_SHIFT, 1, 0), +- SOC_SINGLE("LRCLK Force", CS35L41_SP_FORMAT, CS35L41_LRCLK_FRC_SHIFT, 1, 0), +- SOC_SINGLE("Invert Class D", CS35L41_AMP_DIG_VOL_CTRL, ++ SOC_SINGLE("SCLK Force Switch", CS35L41_SP_FORMAT, CS35L41_SCLK_FRC_SHIFT, 1, 0), ++ SOC_SINGLE("LRCLK Force Switch", CS35L41_SP_FORMAT, CS35L41_LRCLK_FRC_SHIFT, 1, 0), ++ SOC_SINGLE("Invert Class D Switch", CS35L41_AMP_DIG_VOL_CTRL, + CS35L41_AMP_INV_PCM_SHIFT, 1, 0), +- SOC_SINGLE("Amp Gain ZC", CS35L41_AMP_GAIN_CTRL, ++ SOC_SINGLE("Amp Gain ZC Switch", CS35L41_AMP_GAIN_CTRL, + CS35L41_AMP_GAIN_ZC_SHIFT, 1, 0), + WM_ADSP2_PRELOAD_SWITCH("DSP1", 1), + WM_ADSP_FW_CONTROL("DSP1", 0), +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Create-shared-function-for-boost-config.patch b/patches.suse/ASoC-cs35l41-Create-shared-function-for-boost-config.patch new file mode 100644 index 0000000..ce5e550 --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Create-shared-function-for-boost-config.patch @@ -0,0 +1,276 @@ +From e8e4fcc047c6e0c5411faeb8cc29aed2e5036a00 Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Fri, 17 Dec 2021 11:57:04 +0000 +Subject: [PATCH] ASoC: cs35l41: Create shared function for boost configuration +Git-commit: e8e4fcc047c6e0c5411faeb8cc29aed2e5036a00 +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +ASoC and HDA will use the same registers to configure +internal boost for the device + +Signed-off-by: Lucas Tanure +Link: https://lore.kernel.org/r/20211217115708.882525-7-tanureal@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + include/sound/cs35l41.h | 2 + + sound/soc/codecs/cs35l41-lib.c | 98 ++++++++++++++++++++++++++++++ + sound/soc/codecs/cs35l41.c | 105 +-------------------------------- + 3 files changed, 102 insertions(+), 103 deletions(-) + +diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h +index 39d150f61382..29a527457b48 100644 +--- a/include/sound/cs35l41.h ++++ b/include/sound/cs35l41.h +@@ -767,5 +767,7 @@ int cs35l41_register_errata_patch(struct device *dev, struct regmap *reg, unsign + int cs35l41_set_channels(struct device *dev, struct regmap *reg, + unsigned int tx_num, unsigned int *tx_slot, + unsigned int rx_num, unsigned int *rx_slot); ++int cs35l41_boost_config(struct device *dev, struct regmap *regmap, int boost_ind, int boost_cap, ++ int boost_ipk); + + #endif /* __CS35L41_H */ +diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c +index afcec715374d..d026c5e3a378 100644 +--- a/sound/soc/codecs/cs35l41-lib.c ++++ b/sound/soc/codecs/cs35l41-lib.c +@@ -966,6 +966,104 @@ int cs35l41_set_channels(struct device *dev, struct regmap *reg, + } + EXPORT_SYMBOL_GPL(cs35l41_set_channels); + ++static const unsigned char cs35l41_bst_k1_table[4][5] = { ++ { 0x24, 0x32, 0x32, 0x4F, 0x57 }, ++ { 0x24, 0x32, 0x32, 0x4F, 0x57 }, ++ { 0x40, 0x32, 0x32, 0x4F, 0x57 }, ++ { 0x40, 0x32, 0x32, 0x4F, 0x57 } ++}; ++ ++static const unsigned char cs35l41_bst_k2_table[4][5] = { ++ { 0x24, 0x49, 0x66, 0xA3, 0xEA }, ++ { 0x24, 0x49, 0x66, 0xA3, 0xEA }, ++ { 0x48, 0x49, 0x66, 0xA3, 0xEA }, ++ { 0x48, 0x49, 0x66, 0xA3, 0xEA } ++}; ++ ++static const unsigned char cs35l41_bst_slope_table[4] = { ++ 0x75, 0x6B, 0x3B, 0x28 ++}; ++ ++ ++int cs35l41_boost_config(struct device *dev, struct regmap *regmap, int boost_ind, int boost_cap, ++ int boost_ipk) ++{ ++ unsigned char bst_lbst_val, bst_cbst_range, bst_ipk_scaled; ++ int ret; ++ ++ switch (boost_ind) { ++ case 1000: /* 1.0 uH */ ++ bst_lbst_val = 0; ++ break; ++ case 1200: /* 1.2 uH */ ++ bst_lbst_val = 1; ++ break; ++ case 1500: /* 1.5 uH */ ++ bst_lbst_val = 2; ++ break; ++ case 2200: /* 2.2 uH */ ++ bst_lbst_val = 3; ++ break; ++ default: ++ dev_err(dev, "Invalid boost inductor value: %d nH\n", boost_ind); ++ return -EINVAL; ++ } ++ ++ switch (boost_cap) { ++ case 0 ... 19: ++ bst_cbst_range = 0; ++ break; ++ case 20 ... 50: ++ bst_cbst_range = 1; ++ break; ++ case 51 ... 100: ++ bst_cbst_range = 2; ++ break; ++ case 101 ... 200: ++ bst_cbst_range = 3; ++ break; ++ default: /* 201 uF and greater */ ++ bst_cbst_range = 4; ++ } ++ ++ ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_COEFF, ++ CS35L41_BST_K1_MASK | CS35L41_BST_K2_MASK, ++ cs35l41_bst_k1_table[bst_lbst_val][bst_cbst_range] ++ << CS35L41_BST_K1_SHIFT | ++ cs35l41_bst_k2_table[bst_lbst_val][bst_cbst_range] ++ << CS35L41_BST_K2_SHIFT); ++ if (ret) { ++ dev_err(dev, "Failed to write boost coefficients: %d\n", ret); ++ return ret; ++ } ++ ++ ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_SLOPE_LBST, ++ CS35L41_BST_SLOPE_MASK | CS35L41_BST_LBST_VAL_MASK, ++ cs35l41_bst_slope_table[bst_lbst_val] ++ << CS35L41_BST_SLOPE_SHIFT | ++ bst_lbst_val << CS35L41_BST_LBST_VAL_SHIFT); ++ if (ret) { ++ dev_err(dev, "Failed to write boost slope/inductor value: %d\n", ret); ++ return ret; ++ } ++ ++ if (boost_ipk < 1600 || boost_ipk > 4500) { ++ dev_err(dev, "Invalid boost inductor peak current: %d mA\n", boost_ipk); ++ return -EINVAL; ++ } ++ bst_ipk_scaled = ((boost_ipk - 1600) / 50) + 0x10; ++ ++ ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_PEAK_CUR, CS35L41_BST_IPK_MASK, ++ bst_ipk_scaled << CS35L41_BST_IPK_SHIFT); ++ if (ret) { ++ dev_err(dev, "Failed to write boost inductor peak current: %d\n", ret); ++ return ret; ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(cs35l41_boost_config); ++ + MODULE_DESCRIPTION("CS35L41 library"); + MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, "); + MODULE_AUTHOR("Lucas Tanure, Cirrus Logic Inc, "); +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index 88d6e77fdb50..d9e6e84e64d0 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -150,24 +150,6 @@ static const struct cs35l41_fs_mon_config cs35l41_fs_mon[] = { + { 6144000, 16, 24 }, + }; + +-static const unsigned char cs35l41_bst_k1_table[4][5] = { +- { 0x24, 0x32, 0x32, 0x4F, 0x57 }, +- { 0x24, 0x32, 0x32, 0x4F, 0x57 }, +- { 0x40, 0x32, 0x32, 0x4F, 0x57 }, +- { 0x40, 0x32, 0x32, 0x4F, 0x57 } +-}; +- +-static const unsigned char cs35l41_bst_k2_table[4][5] = { +- { 0x24, 0x49, 0x66, 0xA3, 0xEA }, +- { 0x24, 0x49, 0x66, 0xA3, 0xEA }, +- { 0x48, 0x49, 0x66, 0xA3, 0xEA }, +- { 0x48, 0x49, 0x66, 0xA3, 0xEA } +-}; +- +-static const unsigned char cs35l41_bst_slope_table[4] = { +- 0x75, 0x6B, 0x3B, 0x28 +-}; +- + static int cs35l41_get_fs_mon_config_index(int freq) + { + int i; +@@ -992,88 +974,6 @@ static int cs35l41_dai_set_sysclk(struct snd_soc_dai *dai, + return 0; + } + +-static int cs35l41_boost_config(struct cs35l41_private *cs35l41, +- int boost_ind, int boost_cap, int boost_ipk) +-{ +- unsigned char bst_lbst_val, bst_cbst_range, bst_ipk_scaled; +- struct regmap *regmap = cs35l41->regmap; +- struct device *dev = cs35l41->dev; +- int ret; +- +- switch (boost_ind) { +- case 1000: /* 1.0 uH */ +- bst_lbst_val = 0; +- break; +- case 1200: /* 1.2 uH */ +- bst_lbst_val = 1; +- break; +- case 1500: /* 1.5 uH */ +- bst_lbst_val = 2; +- break; +- case 2200: /* 2.2 uH */ +- bst_lbst_val = 3; +- break; +- default: +- dev_err(dev, "Invalid boost inductor value: %d nH\n", boost_ind); +- return -EINVAL; +- } +- +- switch (boost_cap) { +- case 0 ... 19: +- bst_cbst_range = 0; +- break; +- case 20 ... 50: +- bst_cbst_range = 1; +- break; +- case 51 ... 100: +- bst_cbst_range = 2; +- break; +- case 101 ... 200: +- bst_cbst_range = 3; +- break; +- default: /* 201 uF and greater */ +- bst_cbst_range = 4; +- } +- +- ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_COEFF, +- CS35L41_BST_K1_MASK | CS35L41_BST_K2_MASK, +- cs35l41_bst_k1_table[bst_lbst_val][bst_cbst_range] +- << CS35L41_BST_K1_SHIFT | +- cs35l41_bst_k2_table[bst_lbst_val][bst_cbst_range] +- << CS35L41_BST_K2_SHIFT); +- if (ret) { +- dev_err(dev, "Failed to write boost coefficients: %d\n", ret); +- return ret; +- } +- +- ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_SLOPE_LBST, +- CS35L41_BST_SLOPE_MASK | CS35L41_BST_LBST_VAL_MASK, +- cs35l41_bst_slope_table[bst_lbst_val] +- << CS35L41_BST_SLOPE_SHIFT | +- bst_lbst_val << CS35L41_BST_LBST_VAL_SHIFT); +- if (ret) { +- dev_err(dev, "Failed to write boost slope/inductor value: %d\n", ret); +- return ret; +- } +- +- if (boost_ipk < 1600 || boost_ipk > 4500) { +- dev_err(dev, "Invalid boost inductor peak current: %d mA\n", +- boost_ipk); +- return -EINVAL; +- } +- bst_ipk_scaled = ((boost_ipk - 1600) / 50) + 0x10; +- +- ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_PEAK_CUR, +- CS35L41_BST_IPK_MASK, +- bst_ipk_scaled << CS35L41_BST_IPK_SHIFT); +- if (ret) { +- dev_err(dev, "Failed to write boost inductor peak current: %d\n", ret); +- return ret; +- } +- +- return 0; +-} +- + static int cs35l41_set_pdata(struct cs35l41_private *cs35l41) + { + int ret; +@@ -1082,9 +982,8 @@ static int cs35l41_set_pdata(struct cs35l41_private *cs35l41) + /* Required */ + if (cs35l41->pdata.bst_ipk && + cs35l41->pdata.bst_ind && cs35l41->pdata.bst_cap) { +- ret = cs35l41_boost_config(cs35l41, cs35l41->pdata.bst_ind, +- cs35l41->pdata.bst_cap, +- cs35l41->pdata.bst_ipk); ++ ret = cs35l41_boost_config(cs35l41->dev, cs35l41->regmap, cs35l41->pdata.bst_ind, ++ cs35l41->pdata.bst_cap, cs35l41->pdata.bst_ipk); + if (ret) { + dev_err(cs35l41->dev, "Error in Boost DT config: %d\n", ret); + return ret; +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Create-shared-function-for-errata-patch.patch b/patches.suse/ASoC-cs35l41-Create-shared-function-for-errata-patch.patch new file mode 100644 index 0000000..5e249d6 --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Create-shared-function-for-errata-patch.patch @@ -0,0 +1,266 @@ +From 8b2278604b6de27329ec7ed82ca696c4751111b6 Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Fri, 17 Dec 2021 11:57:02 +0000 +Subject: [PATCH] ASoC: cs35l41: Create shared function for errata patches +Git-commit: 8b2278604b6de27329ec7ed82ca696c4751111b6 +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +ASoC and HDA systems require the same errata patches, so +move it to the shared code using a function the correctly +applies the patches by revision + +Also, move CS35L41_DSP1_CCM_CORE_CTRL write to errata +patch function as is required to be written at boot, +but not in regmap_register_patch sequence as will affect +waking up from hibernation + +Signed-off-by: Lucas Tanure +Link: https://lore.kernel.org/r/20211217115708.882525-5-tanureal@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + include/sound/cs35l41.h | 1 + + sound/soc/codecs/cs35l41-lib.c | 89 ++++++++++++++++++++++++++++++++ + sound/soc/codecs/cs35l41.c | 92 ++-------------------------------- + 3 files changed, 93 insertions(+), 89 deletions(-) + +diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h +index 6cf3ef02b26a..ad2e32a12b8c 100644 +--- a/include/sound/cs35l41.h ++++ b/include/sound/cs35l41.h +@@ -763,5 +763,6 @@ extern struct regmap_config cs35l41_regmap_i2c; + extern struct regmap_config cs35l41_regmap_spi; + + int cs35l41_otp_unpack(struct device *dev, struct regmap *regmap); ++int cs35l41_register_errata_patch(struct device *dev, struct regmap *reg, unsigned int reg_revid); + + #endif /* __CS35L41_H */ +diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c +index b3567e10adc4..5e382eaea340 100644 +--- a/sound/soc/codecs/cs35l41-lib.c ++++ b/sound/soc/codecs/cs35l41-lib.c +@@ -659,6 +659,57 @@ static const struct cs35l41_otp_packed_element_t otp_map_2[CS35L41_NUM_OTP_ELEM] + { 0x00017044, 0, 24 }, /*LOT_NUMBER*/ + }; + ++static const struct reg_sequence cs35l41_reva0_errata_patch[] = { ++ { 0x00000040, 0x00005555 }, ++ { 0x00000040, 0x0000AAAA }, ++ { 0x00003854, 0x05180240 }, ++ { CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 }, ++ { 0x00004310, 0x00000000 }, ++ { CS35L41_VPVBST_FS_SEL, 0x00000000 }, ++ { CS35L41_OTP_TRIM_30, 0x9091A1C8 }, ++ { 0x00003014, 0x0200EE0E }, ++ { CS35L41_BSTCVRT_DCM_CTRL, 0x00000051 }, ++ { 0x00000054, 0x00000004 }, ++ { CS35L41_IRQ1_DB3, 0x00000000 }, ++ { CS35L41_IRQ2_DB3, 0x00000000 }, ++ { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 }, ++ { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, ++ { 0x00000040, 0x0000CCCC }, ++ { 0x00000040, 0x00003333 }, ++ { CS35L41_PWR_CTRL2, 0x00000000 }, ++ { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, ++}; ++ ++static const struct reg_sequence cs35l41_revb0_errata_patch[] = { ++ { 0x00000040, 0x00005555 }, ++ { 0x00000040, 0x0000AAAA }, ++ { CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 }, ++ { 0x00004310, 0x00000000 }, ++ { CS35L41_VPVBST_FS_SEL, 0x00000000 }, ++ { CS35L41_BSTCVRT_DCM_CTRL, 0x00000051 }, ++ { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 }, ++ { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, ++ { 0x00000040, 0x0000CCCC }, ++ { 0x00000040, 0x00003333 }, ++ { CS35L41_PWR_CTRL2, 0x00000000 }, ++ { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, ++}; ++ ++static const struct reg_sequence cs35l41_revb2_errata_patch[] = { ++ { 0x00000040, 0x00005555 }, ++ { 0x00000040, 0x0000AAAA }, ++ { CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 }, ++ { 0x00004310, 0x00000000 }, ++ { CS35L41_VPVBST_FS_SEL, 0x00000000 }, ++ { CS35L41_BSTCVRT_DCM_CTRL, 0x00000051 }, ++ { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 }, ++ { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, ++ { 0x00000040, 0x0000CCCC }, ++ { 0x00000040, 0x00003333 }, ++ { CS35L41_PWR_CTRL2, 0x00000000 }, ++ { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, ++}; ++ + static const struct cs35l41_otp_map_element_t cs35l41_otp_map_map[] = { + { + .id = 0x01, +@@ -845,6 +896,44 @@ int cs35l41_otp_unpack(struct device *dev, struct regmap *regmap) + } + EXPORT_SYMBOL_GPL(cs35l41_otp_unpack); + ++int cs35l41_register_errata_patch(struct device *dev, struct regmap *reg, unsigned int reg_revid) ++{ ++ char *rev; ++ int ret; ++ ++ switch (reg_revid) { ++ case CS35L41_REVID_A0: ++ ret = regmap_register_patch(reg, cs35l41_reva0_errata_patch, ++ ARRAY_SIZE(cs35l41_reva0_errata_patch)); ++ rev = "A0"; ++ break; ++ case CS35L41_REVID_B0: ++ ret = regmap_register_patch(reg, cs35l41_revb0_errata_patch, ++ ARRAY_SIZE(cs35l41_revb0_errata_patch)); ++ rev = "B0"; ++ break; ++ case CS35L41_REVID_B2: ++ ret = regmap_register_patch(reg, cs35l41_revb2_errata_patch, ++ ARRAY_SIZE(cs35l41_revb2_errata_patch)); ++ rev = "B2"; ++ break; ++ default: ++ ret = -EINVAL; ++ rev = "XX"; ++ break; ++ } ++ ++ if (ret) ++ dev_err(dev, "Failed to apply %s errata patch: %d\n", rev, ret); ++ ++ ret = regmap_write(reg, CS35L41_DSP1_CCM_CORE_CTRL, 0); ++ if (ret < 0) ++ dev_err(dev, "Write CCM_CORE_CTRL failed: %d\n", ret); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(cs35l41_register_errata_patch); ++ + MODULE_DESCRIPTION("CS35L41 library"); + MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, "); + MODULE_AUTHOR("Lucas Tanure, Cirrus Logic Inc, "); +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index 7494710ae6e6..afc10f7ca65e 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -1271,57 +1271,6 @@ static int cs35l41_handle_pdata(struct device *dev, + return 0; + } + +-static const struct reg_sequence cs35l41_reva0_errata_patch[] = { +- { 0x00000040, 0x00005555 }, +- { 0x00000040, 0x0000AAAA }, +- { 0x00003854, 0x05180240 }, +- { CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 }, +- { 0x00004310, 0x00000000 }, +- { CS35L41_VPVBST_FS_SEL, 0x00000000 }, +- { CS35L41_OTP_TRIM_30, 0x9091A1C8 }, +- { 0x00003014, 0x0200EE0E }, +- { CS35L41_BSTCVRT_DCM_CTRL, 0x00000051 }, +- { 0x00000054, 0x00000004 }, +- { CS35L41_IRQ1_DB3, 0x00000000 }, +- { CS35L41_IRQ2_DB3, 0x00000000 }, +- { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 }, +- { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, +- { 0x00000040, 0x0000CCCC }, +- { 0x00000040, 0x00003333 }, +- { CS35L41_PWR_CTRL2, 0x00000000 }, +- { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, +-}; +- +-static const struct reg_sequence cs35l41_revb0_errata_patch[] = { +- { 0x00000040, 0x00005555 }, +- { 0x00000040, 0x0000AAAA }, +- { CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 }, +- { 0x00004310, 0x00000000 }, +- { CS35L41_VPVBST_FS_SEL, 0x00000000 }, +- { CS35L41_BSTCVRT_DCM_CTRL, 0x00000051 }, +- { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 }, +- { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, +- { 0x00000040, 0x0000CCCC }, +- { 0x00000040, 0x00003333 }, +- { CS35L41_PWR_CTRL2, 0x00000000 }, +- { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, +-}; +- +-static const struct reg_sequence cs35l41_revb2_errata_patch[] = { +- { 0x00000040, 0x00005555 }, +- { 0x00000040, 0x0000AAAA }, +- { CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 }, +- { 0x00004310, 0x00000000 }, +- { CS35L41_VPVBST_FS_SEL, 0x00000000 }, +- { CS35L41_BSTCVRT_DCM_CTRL, 0x00000051 }, +- { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 }, +- { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, +- { 0x00000040, 0x0000CCCC }, +- { 0x00000040, 0x00003333 }, +- { CS35L41_PWR_CTRL2, 0x00000000 }, +- { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, +-}; +- + static const struct reg_sequence cs35l41_fs_errata_patch[] = { + { CS35L41_DSP1_RX1_RATE, 0x00000001 }, + { CS35L41_DSP1_RX2_RATE, 0x00000001 }, +@@ -1501,38 +1450,9 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, + goto err; + } + +- switch (reg_revid) { +- case CS35L41_REVID_A0: +- ret = regmap_register_patch(cs35l41->regmap, +- cs35l41_reva0_errata_patch, +- ARRAY_SIZE(cs35l41_reva0_errata_patch)); +- if (ret < 0) { +- dev_err(cs35l41->dev, +- "Failed to apply A0 errata patch: %d\n", ret); +- goto err; +- } +- break; +- case CS35L41_REVID_B0: +- ret = regmap_register_patch(cs35l41->regmap, +- cs35l41_revb0_errata_patch, +- ARRAY_SIZE(cs35l41_revb0_errata_patch)); +- if (ret < 0) { +- dev_err(cs35l41->dev, +- "Failed to apply B0 errata patch: %d\n", ret); +- goto err; +- } +- break; +- case CS35L41_REVID_B2: +- ret = regmap_register_patch(cs35l41->regmap, +- cs35l41_revb2_errata_patch, +- ARRAY_SIZE(cs35l41_revb2_errata_patch)); +- if (ret < 0) { +- dev_err(cs35l41->dev, +- "Failed to apply B2 errata patch: %d\n", ret); +- goto err; +- } +- break; +- } ++ ret = cs35l41_register_errata_patch(cs35l41->dev, cs35l41->regmap, reg_revid); ++ if (ret) ++ goto err; + + irq_pol = cs35l41_irq_gpio_config(cs35l41); + +@@ -1556,12 +1476,6 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, + goto err; + } + +- ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_CCM_CORE_CTRL, 0); +- if (ret < 0) { +- dev_err(cs35l41->dev, "Write CCM_CORE_CTRL failed: %d\n", ret); +- goto err; +- } +- + ret = cs35l41_set_pdata(cs35l41); + if (ret < 0) { + dev_err(cs35l41->dev, "Set pdata failed: %d\n", ret); +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Create-shared-function-for-setting-chan.patch b/patches.suse/ASoC-cs35l41-Create-shared-function-for-setting-chan.patch new file mode 100644 index 0000000..beb0c0b --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Create-shared-function-for-setting-chan.patch @@ -0,0 +1,125 @@ +From 3bc3e3da657f17c14df8ae8fab58183407bd7521 Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Fri, 17 Dec 2021 11:57:03 +0000 +Subject: [PATCH] ASoC: cs35l41: Create shared function for setting channels +Git-commit: 3bc3e3da657f17c14df8ae8fab58183407bd7521 +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +ASoC and HDA will use the same register to set channels +for the device + +Signed-off-by: Lucas Tanure +Link: https://lore.kernel.org/r/20211217115708.882525-6-tanureal@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + include/sound/cs35l41.h | 3 +++ + sound/soc/codecs/cs35l41-lib.c | 32 ++++++++++++++++++++++++++++++++ + sound/soc/codecs/cs35l41.c | 30 +++--------------------------- + 3 files changed, 38 insertions(+), 27 deletions(-) + +diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h +index ad2e32a12b8c..39d150f61382 100644 +--- a/include/sound/cs35l41.h ++++ b/include/sound/cs35l41.h +@@ -764,5 +764,8 @@ extern struct regmap_config cs35l41_regmap_spi; + + int cs35l41_otp_unpack(struct device *dev, struct regmap *regmap); + int cs35l41_register_errata_patch(struct device *dev, struct regmap *reg, unsigned int reg_revid); ++int cs35l41_set_channels(struct device *dev, struct regmap *reg, ++ unsigned int tx_num, unsigned int *tx_slot, ++ unsigned int rx_num, unsigned int *rx_slot); + + #endif /* __CS35L41_H */ +diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c +index 5e382eaea340..afcec715374d 100644 +--- a/sound/soc/codecs/cs35l41-lib.c ++++ b/sound/soc/codecs/cs35l41-lib.c +@@ -934,6 +934,38 @@ int cs35l41_register_errata_patch(struct device *dev, struct regmap *reg, unsign + } + EXPORT_SYMBOL_GPL(cs35l41_register_errata_patch); + ++int cs35l41_set_channels(struct device *dev, struct regmap *reg, ++ unsigned int tx_num, unsigned int *tx_slot, ++ unsigned int rx_num, unsigned int *rx_slot) ++{ ++ unsigned int val, mask; ++ int i; ++ ++ if (tx_num > 4 || rx_num > 2) ++ return -EINVAL; ++ ++ val = 0; ++ mask = 0; ++ for (i = 0; i < rx_num; i++) { ++ dev_dbg(dev, "rx slot %d position = %d\n", i, rx_slot[i]); ++ val |= rx_slot[i] << (i * 8); ++ mask |= 0x3F << (i * 8); ++ } ++ regmap_update_bits(reg, CS35L41_SP_FRAME_RX_SLOT, mask, val); ++ ++ val = 0; ++ mask = 0; ++ for (i = 0; i < tx_num; i++) { ++ dev_dbg(dev, "tx slot %d position = %d\n", i, tx_slot[i]); ++ val |= tx_slot[i] << (i * 8); ++ mask |= 0x3F << (i * 8); ++ } ++ regmap_update_bits(reg, CS35L41_SP_FRAME_TX_SLOT, mask, val); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(cs35l41_set_channels); ++ + MODULE_DESCRIPTION("CS35L41 library"); + MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, "); + MODULE_AUTHOR("Lucas Tanure, Cirrus Logic Inc, "); +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index afc10f7ca65e..88d6e77fdb50 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -751,36 +751,12 @@ static const struct cs_dsp_region cs35l41_dsp1_regions[] = { + {. type = WMFW_ADSP2_YM, .base = CS35L41_DSP1_YMEM_UNPACK24_0}, + }; + +-static int cs35l41_set_channel_map(struct snd_soc_dai *dai, unsigned int tx_num, +- unsigned int *tx_slot, unsigned int rx_num, +- unsigned int *rx_slot) ++static int cs35l41_set_channel_map(struct snd_soc_dai *dai, unsigned int tx_n, ++ unsigned int *tx_slot, unsigned int rx_n, unsigned int *rx_slot) + { + struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component); +- unsigned int val, mask; +- int i; +- +- if (tx_num > 4 || rx_num > 2) +- return -EINVAL; + +- val = 0; +- mask = 0; +- for (i = 0; i < rx_num; i++) { +- dev_dbg(cs35l41->dev, "rx slot %d position = %d\n", i, rx_slot[i]); +- val |= rx_slot[i] << (i * 8); +- mask |= 0x3F << (i * 8); +- } +- regmap_update_bits(cs35l41->regmap, CS35L41_SP_FRAME_RX_SLOT, mask, val); +- +- val = 0; +- mask = 0; +- for (i = 0; i < tx_num; i++) { +- dev_dbg(cs35l41->dev, "tx slot %d position = %d\n", i, tx_slot[i]); +- val |= tx_slot[i] << (i * 8); +- mask |= 0x3F << (i * 8); +- } +- regmap_update_bits(cs35l41->regmap, CS35L41_SP_FRAME_TX_SLOT, mask, val); +- +- return 0; ++ return cs35l41_set_channels(cs35l41->dev, cs35l41->regmap, tx_n, tx_slot, rx_n, rx_slot); + } + + static int cs35l41_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-DSP-Support.patch b/patches.suse/ASoC-cs35l41-DSP-Support.patch new file mode 100644 index 0000000..5ed9316 --- /dev/null +++ b/patches.suse/ASoC-cs35l41-DSP-Support.patch @@ -0,0 +1,671 @@ +From bae9e13fc55cbc5ae25409385b2f1ba9187082d0 Mon Sep 17 00:00:00 2001 +From: David Rhodes +Date: Fri, 29 Oct 2021 16:40:28 -0500 +Subject: [PATCH] ASoC: cs35l41: DSP Support +Git-commit: bae9e13fc55cbc5ae25409385b2f1ba9187082d0 +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +Support for HALO DSP and firmware + +Signed-off-by: David Rhodes +Reviewed-by: Charles Keepax +Link: https://lore.kernel.org/r/20211029214028.401284-2-drhodes@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/Kconfig | 4 + + sound/soc/codecs/cs35l41-tables.c | 96 +++++++++ + sound/soc/codecs/cs35l41.c | 312 +++++++++++++++++++++++++++++- + sound/soc/codecs/cs35l41.h | 20 ++ + 4 files changed, 426 insertions(+), 6 deletions(-) + +diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig +index 326f2d611ad4..3fe62df32238 100644 +--- a/sound/soc/codecs/Kconfig ++++ b/sound/soc/codecs/Kconfig +@@ -343,11 +343,15 @@ config SND_SOC_WM_ADSP + default y if SND_SOC_WM5102=y + default y if SND_SOC_WM5110=y + default y if SND_SOC_WM2200=y ++ default y if SND_SOC_CS35L41_SPI=y ++ default y if SND_SOC_CS35L41_I2C=y + default m if SND_SOC_MADERA=m + default m if SND_SOC_CS47L24=m + default m if SND_SOC_WM5102=m + default m if SND_SOC_WM5110=m + default m if SND_SOC_WM2200=m ++ default m if SND_SOC_CS35L41_SPI=m ++ default m if SND_SOC_CS35L41_I2C=m + + config SND_SOC_AB8500_CODEC + tristate +diff --git a/sound/soc/codecs/cs35l41-tables.c b/sound/soc/codecs/cs35l41-tables.c +index 964e530afa27..9d1a7d7dd24d 100644 +--- a/sound/soc/codecs/cs35l41-tables.c ++++ b/sound/soc/codecs/cs35l41-tables.c +@@ -200,6 +200,83 @@ bool cs35l41_readable_reg(struct device *dev, unsigned int reg) + case CS35L41_DIE_STS2: + case CS35L41_TEMP_CAL1: + case CS35L41_TEMP_CAL2: ++ case CS35L41_DSP1_TIMESTAMP_COUNT: ++ case CS35L41_DSP1_SYS_ID: ++ case CS35L41_DSP1_SYS_VERSION: ++ case CS35L41_DSP1_SYS_CORE_ID: ++ case CS35L41_DSP1_SYS_AHB_ADDR: ++ case CS35L41_DSP1_SYS_XSRAM_SIZE: ++ case CS35L41_DSP1_SYS_YSRAM_SIZE: ++ case CS35L41_DSP1_SYS_PSRAM_SIZE: ++ case CS35L41_DSP1_SYS_PM_BOOT_SIZE: ++ case CS35L41_DSP1_SYS_FEATURES: ++ case CS35L41_DSP1_SYS_FIR_FILTERS: ++ case CS35L41_DSP1_SYS_LMS_FILTERS: ++ case CS35L41_DSP1_SYS_XM_BANK_SIZE: ++ case CS35L41_DSP1_SYS_YM_BANK_SIZE: ++ case CS35L41_DSP1_SYS_PM_BANK_SIZE: ++ case CS35L41_DSP1_RX1_RATE: ++ case CS35L41_DSP1_RX2_RATE: ++ case CS35L41_DSP1_RX3_RATE: ++ case CS35L41_DSP1_RX4_RATE: ++ case CS35L41_DSP1_RX5_RATE: ++ case CS35L41_DSP1_RX6_RATE: ++ case CS35L41_DSP1_RX7_RATE: ++ case CS35L41_DSP1_RX8_RATE: ++ case CS35L41_DSP1_TX1_RATE: ++ case CS35L41_DSP1_TX2_RATE: ++ case CS35L41_DSP1_TX3_RATE: ++ case CS35L41_DSP1_TX4_RATE: ++ case CS35L41_DSP1_TX5_RATE: ++ case CS35L41_DSP1_TX6_RATE: ++ case CS35L41_DSP1_TX7_RATE: ++ case CS35L41_DSP1_TX8_RATE: ++ case CS35L41_DSP1_SCRATCH1: ++ case CS35L41_DSP1_SCRATCH2: ++ case CS35L41_DSP1_SCRATCH3: ++ case CS35L41_DSP1_SCRATCH4: ++ case CS35L41_DSP1_CCM_CORE_CTRL: ++ case CS35L41_DSP1_CCM_CLK_OVERRIDE: ++ case CS35L41_DSP1_XM_MSTR_EN: ++ case CS35L41_DSP1_XM_CORE_PRI: ++ case CS35L41_DSP1_XM_AHB_PACK_PL_PRI: ++ case CS35L41_DSP1_XM_AHB_UP_PL_PRI: ++ case CS35L41_DSP1_XM_ACCEL_PL0_PRI: ++ case CS35L41_DSP1_XM_NPL0_PRI: ++ case CS35L41_DSP1_YM_MSTR_EN: ++ case CS35L41_DSP1_YM_CORE_PRI: ++ case CS35L41_DSP1_YM_AHB_PACK_PL_PRI: ++ case CS35L41_DSP1_YM_AHB_UP_PL_PRI: ++ case CS35L41_DSP1_YM_ACCEL_PL0_PRI: ++ case CS35L41_DSP1_YM_NPL0_PRI: ++ case CS35L41_DSP1_MPU_XM_ACCESS0: ++ case CS35L41_DSP1_MPU_YM_ACCESS0: ++ case CS35L41_DSP1_MPU_WNDW_ACCESS0: ++ case CS35L41_DSP1_MPU_XREG_ACCESS0: ++ case CS35L41_DSP1_MPU_YREG_ACCESS0: ++ case CS35L41_DSP1_MPU_XM_ACCESS1: ++ case CS35L41_DSP1_MPU_YM_ACCESS1: ++ case CS35L41_DSP1_MPU_WNDW_ACCESS1: ++ case CS35L41_DSP1_MPU_XREG_ACCESS1: ++ case CS35L41_DSP1_MPU_YREG_ACCESS1: ++ case CS35L41_DSP1_MPU_XM_ACCESS2: ++ case CS35L41_DSP1_MPU_YM_ACCESS2: ++ case CS35L41_DSP1_MPU_WNDW_ACCESS2: ++ case CS35L41_DSP1_MPU_XREG_ACCESS2: ++ case CS35L41_DSP1_MPU_YREG_ACCESS2: ++ case CS35L41_DSP1_MPU_XM_ACCESS3: ++ case CS35L41_DSP1_MPU_YM_ACCESS3: ++ case CS35L41_DSP1_MPU_WNDW_ACCESS3: ++ case CS35L41_DSP1_MPU_XREG_ACCESS3: ++ case CS35L41_DSP1_MPU_YREG_ACCESS3: ++ case CS35L41_DSP1_MPU_XM_VIO_ADDR: ++ case CS35L41_DSP1_MPU_XM_VIO_STATUS: ++ case CS35L41_DSP1_MPU_YM_VIO_ADDR: ++ case CS35L41_DSP1_MPU_YM_VIO_STATUS: ++ case CS35L41_DSP1_MPU_PM_VIO_ADDR: ++ case CS35L41_DSP1_MPU_PM_VIO_STATUS: ++ case CS35L41_DSP1_MPU_LOCK_CONFIG: ++ case CS35L41_DSP1_MPU_WDT_RST_CTRL: + case CS35L41_OTP_TRIM_1: + case CS35L41_OTP_TRIM_2: + case CS35L41_OTP_TRIM_3: +@@ -237,6 +314,13 @@ bool cs35l41_readable_reg(struct device *dev, unsigned int reg) + case CS35L41_OTP_TRIM_35: + case CS35L41_OTP_TRIM_36: + case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31: ++ case CS35L41_DSP1_XMEM_PACK_0 ... CS35L41_DSP1_XMEM_PACK_3068: ++ case CS35L41_DSP1_XMEM_UNPACK32_0 ... CS35L41_DSP1_XMEM_UNPACK32_2046: ++ case CS35L41_DSP1_XMEM_UNPACK24_0 ... CS35L41_DSP1_XMEM_UNPACK24_4093: ++ case CS35L41_DSP1_YMEM_PACK_0 ... CS35L41_DSP1_YMEM_PACK_1532: ++ case CS35L41_DSP1_YMEM_UNPACK32_0 ... CS35L41_DSP1_YMEM_UNPACK32_1022: ++ case CS35L41_DSP1_YMEM_UNPACK24_0 ... CS35L41_DSP1_YMEM_UNPACK24_2045: ++ case CS35L41_DSP1_PMEM_0 ... CS35L41_DSP1_PMEM_5114: + /*test regs*/ + case CS35L41_PLL_OVR: + case CS35L41_BST_TEST_DUTY: +@@ -251,6 +335,9 @@ bool cs35l41_precious_reg(struct device *dev, unsigned int reg) + { + switch (reg) { + case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31: ++ case CS35L41_DSP1_XMEM_PACK_0 ... CS35L41_DSP1_XMEM_PACK_3068: ++ case CS35L41_DSP1_YMEM_PACK_0 ... CS35L41_DSP1_YMEM_PACK_1532: ++ case CS35L41_DSP1_PMEM_0 ... CS35L41_DSP1_PMEM_5114: + return true; + default: + return false; +@@ -342,6 +429,15 @@ bool cs35l41_volatile_reg(struct device *dev, unsigned int reg) + case CS35L41_OTP_TRIM_34: + case CS35L41_OTP_TRIM_35: + case CS35L41_OTP_TRIM_36: ++ case CS35L41_DSP_MBOX_1 ... CS35L41_DSP_VIRT2_MBOX_8: ++ case CS35L41_DSP1_XMEM_PACK_0 ... CS35L41_DSP1_XMEM_PACK_3068: ++ case CS35L41_DSP1_XMEM_UNPACK32_0 ... CS35L41_DSP1_XMEM_UNPACK32_2046: ++ case CS35L41_DSP1_XMEM_UNPACK24_0 ... CS35L41_DSP1_XMEM_UNPACK24_4093: ++ case CS35L41_DSP1_YMEM_PACK_0 ... CS35L41_DSP1_YMEM_PACK_1532: ++ case CS35L41_DSP1_YMEM_UNPACK32_0 ... CS35L41_DSP1_YMEM_UNPACK32_1022: ++ case CS35L41_DSP1_YMEM_UNPACK24_0 ... CS35L41_DSP1_YMEM_UNPACK24_2045: ++ case CS35L41_DSP1_PMEM_0 ... CS35L41_DSP1_PMEM_5114: ++ case CS35L41_DSP1_CCM_CORE_CTRL ... CS35L41_DSP1_WDT_STATUS: + case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31: + return true; + default: +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index 9d0530dde996..afb07d2991ba 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -197,6 +197,122 @@ static SOC_ENUM_SINGLE_DECL(pcm_sft_ramp, + CS35L41_AMP_DIG_VOL_CTRL, 0, + cs35l41_pcm_sftramp_text); + ++static int cs35l41_dsp_preload_ev(struct snd_soc_dapm_widget *w, ++ struct snd_kcontrol *kcontrol, int event) ++{ ++ int ret; ++ ++ switch (event) { ++ case SND_SOC_DAPM_PRE_PMU: ++ return wm_adsp_early_event(w, kcontrol, event); ++ case SND_SOC_DAPM_PRE_PMD: ++ ret = wm_adsp_early_event(w, kcontrol, event); ++ if (ret) ++ return ret; ++ ++ return wm_adsp_event(w, kcontrol, event); ++ default: ++ return 0; ++ } ++} ++ ++static bool cs35l41_check_cspl_mbox_sts(enum cs35l41_cspl_mbox_cmd cmd, ++ enum cs35l41_cspl_mbox_status sts) ++{ ++ switch (cmd) { ++ case CSPL_MBOX_CMD_NONE: ++ case CSPL_MBOX_CMD_UNKNOWN_CMD: ++ return true; ++ case CSPL_MBOX_CMD_PAUSE: ++ return (sts == CSPL_MBOX_STS_PAUSED); ++ case CSPL_MBOX_CMD_RESUME: ++ return (sts == CSPL_MBOX_STS_RUNNING); ++ case CSPL_MBOX_CMD_REINIT: ++ return (sts == CSPL_MBOX_STS_RUNNING); ++ case CSPL_MBOX_CMD_STOP_PRE_REINIT: ++ return (sts == CSPL_MBOX_STS_RDY_FOR_REINIT); ++ default: ++ return false; ++ } ++} ++ ++static int cs35l41_set_cspl_mbox_cmd(struct cs35l41_private *cs35l41, ++ enum cs35l41_cspl_mbox_cmd cmd) ++{ ++ unsigned int sts = 0, i; ++ int ret; ++ ++ // Set mailbox cmd ++ ret = regmap_write(cs35l41->regmap, CS35L41_DSP_VIRT1_MBOX_1, cmd); ++ if (ret < 0) { ++ dev_err(cs35l41->dev, "Failed to write MBOX: %d\n", ret); ++ return ret; ++ } ++ ++ // Read mailbox status and verify it is appropriate for the given cmd ++ for (i = 0; i < 5; i++) { ++ usleep_range(1000, 1100); ++ ++ ret = regmap_read(cs35l41->regmap, CS35L41_DSP_MBOX_2, &sts); ++ if (ret < 0) { ++ dev_err(cs35l41->dev, "Failed to read MBOX STS: %d\n", ret); ++ continue; ++ } ++ ++ if (!cs35l41_check_cspl_mbox_sts(cmd, sts)) { ++ dev_dbg(cs35l41->dev, ++ "[%u] cmd %u returned invalid sts %u", ++ i, cmd, sts); ++ } else { ++ return 0; ++ } ++ } ++ ++ dev_err(cs35l41->dev, ++ "Failed to set mailbox cmd %u (status %u)\n", ++ cmd, sts); ++ ++ return -ENOMSG; ++} ++ ++static int cs35l41_dsp_audio_ev(struct snd_soc_dapm_widget *w, ++ struct snd_kcontrol *kcontrol, int event) ++{ ++ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); ++ struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component); ++ unsigned int fw_status; ++ int ret; ++ ++ switch (event) { ++ case SND_SOC_DAPM_POST_PMU: ++ if (!cs35l41->dsp.cs_dsp.running) ++ return wm_adsp_event(w, kcontrol, event); ++ ++ ret = regmap_read(cs35l41->regmap, CS35L41_DSP_MBOX_2, &fw_status); ++ if (ret < 0) { ++ dev_err(cs35l41->dev, ++ "Failed to read firmware status: %d\n", ret); ++ return ret; ++ } ++ ++ switch (fw_status) { ++ case CSPL_MBOX_STS_RUNNING: ++ case CSPL_MBOX_STS_PAUSED: ++ break; ++ default: ++ dev_err(cs35l41->dev, "Firmware status is invalid: %u\n", ++ fw_status); ++ return -EINVAL; ++ } ++ ++ return cs35l41_set_cspl_mbox_cmd(cs35l41, CSPL_MBOX_CMD_RESUME); ++ case SND_SOC_DAPM_PRE_PMD: ++ return cs35l41_set_cspl_mbox_cmd(cs35l41, CSPL_MBOX_CMD_PAUSE); ++ default: ++ return 0; ++ } ++} ++ + static const char * const cs35l41_pcm_source_texts[] = {"ASP", "DSP"}; + static const unsigned int cs35l41_pcm_source_values[] = {0x08, 0x32}; + static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_pcm_source_enum, +@@ -255,6 +371,24 @@ static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx4_enum, + static const struct snd_kcontrol_new asp_tx4_mux = + SOC_DAPM_ENUM("ASPTX4 SRC", cs35l41_asptx4_enum); + ++static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_dsprx1_enum, ++ CS35L41_DSP1_RX1_SRC, ++ 0, CS35L41_ASP_SOURCE_MASK, ++ cs35l41_tx_input_texts, ++ cs35l41_tx_input_values); ++ ++static const struct snd_kcontrol_new dsp_rx1_mux = ++ SOC_DAPM_ENUM("DSPRX1 SRC", cs35l41_dsprx1_enum); ++ ++static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_dsprx2_enum, ++ CS35L41_DSP1_RX2_SRC, ++ 0, CS35L41_ASP_SOURCE_MASK, ++ cs35l41_tx_input_texts, ++ cs35l41_tx_input_values); ++ ++static const struct snd_kcontrol_new dsp_rx2_mux = ++ SOC_DAPM_ENUM("DSPRX2 SRC", cs35l41_dsprx2_enum); ++ + static const struct snd_kcontrol_new cs35l41_aud_controls[] = { + SOC_SINGLE_SX_TLV("Digital PCM Volume", CS35L41_AMP_DIG_VOL_CTRL, + 3, 0x4CF, 0x391, dig_vol_tlv), +@@ -282,6 +416,8 @@ static const struct snd_kcontrol_new cs35l41_aud_controls[] = { + CS35L41_AMP_INV_PCM_SHIFT, 1, 0), + SOC_SINGLE("Amp Gain ZC", CS35L41_AMP_GAIN_CTRL, + CS35L41_AMP_GAIN_ZC_SHIFT, 1, 0), ++ WM_ADSP2_PRELOAD_SWITCH("DSP1", 1), ++ WM_ADSP_FW_CONTROL("DSP1", 0), + }; + + static const struct cs35l41_otp_map_element_t *cs35l41_find_otp_map(u32 otp_id) +@@ -603,6 +739,14 @@ static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w, + } + + static const struct snd_soc_dapm_widget cs35l41_dapm_widgets[] = { ++ SND_SOC_DAPM_SPK("DSP1 Preload", NULL), ++ SND_SOC_DAPM_SUPPLY_S("DSP1 Preloader", 100, SND_SOC_NOPM, 0, 0, ++ cs35l41_dsp_preload_ev, ++ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), ++ SND_SOC_DAPM_OUT_DRV_E("DSP1", SND_SOC_NOPM, 0, 0, NULL, 0, ++ cs35l41_dsp_audio_ev, ++ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), ++ + SND_SOC_DAPM_OUTPUT("SPK"), + + SND_SOC_DAPM_AIF_IN("ASPRX1", NULL, 0, CS35L41_SP_ENABLES, 16, 0), +@@ -618,11 +762,18 @@ static const struct snd_soc_dapm_widget cs35l41_dapm_widgets[] = { + SND_SOC_DAPM_SIGGEN("VBST"), + SND_SOC_DAPM_SIGGEN("TEMP"), + +- SND_SOC_DAPM_ADC("VMON ADC", NULL, CS35L41_PWR_CTRL2, 12, 0), +- SND_SOC_DAPM_ADC("IMON ADC", NULL, CS35L41_PWR_CTRL2, 13, 0), +- SND_SOC_DAPM_ADC("VPMON ADC", NULL, CS35L41_PWR_CTRL2, 8, 0), +- SND_SOC_DAPM_ADC("VBSTMON ADC", NULL, CS35L41_PWR_CTRL2, 9, 0), +- SND_SOC_DAPM_ADC("TEMPMON ADC", NULL, CS35L41_PWR_CTRL2, 10, 0), ++ SND_SOC_DAPM_SUPPLY("VMON", CS35L41_PWR_CTRL2, 12, 0, NULL, 0), ++ SND_SOC_DAPM_SUPPLY("IMON", CS35L41_PWR_CTRL2, 13, 0, NULL, 0), ++ SND_SOC_DAPM_SUPPLY("VPMON", CS35L41_PWR_CTRL2, 8, 0, NULL, 0), ++ SND_SOC_DAPM_SUPPLY("VBSTMON", CS35L41_PWR_CTRL2, 9, 0, NULL, 0), ++ SND_SOC_DAPM_SUPPLY("TEMPMON", CS35L41_PWR_CTRL2, 10, 0, NULL, 0), ++ ++ SND_SOC_DAPM_ADC("VMON ADC", NULL, SND_SOC_NOPM, 0, 0), ++ SND_SOC_DAPM_ADC("IMON ADC", NULL, SND_SOC_NOPM, 0, 0), ++ SND_SOC_DAPM_ADC("VPMON ADC", NULL, SND_SOC_NOPM, 0, 0), ++ SND_SOC_DAPM_ADC("VBSTMON ADC", NULL, SND_SOC_NOPM, 0, 0), ++ SND_SOC_DAPM_ADC("TEMPMON ADC", NULL, SND_SOC_NOPM, 0, 0), ++ + SND_SOC_DAPM_ADC("CLASS H", NULL, CS35L41_PWR_CTRL3, 4, 0), + + SND_SOC_DAPM_OUT_DRV_E("Main AMP", CS35L41_PWR_CTRL2, 0, 0, NULL, 0, +@@ -633,33 +784,51 @@ static const struct snd_soc_dapm_widget cs35l41_dapm_widgets[] = { + SND_SOC_DAPM_MUX("ASP TX2 Source", SND_SOC_NOPM, 0, 0, &asp_tx2_mux), + SND_SOC_DAPM_MUX("ASP TX3 Source", SND_SOC_NOPM, 0, 0, &asp_tx3_mux), + SND_SOC_DAPM_MUX("ASP TX4 Source", SND_SOC_NOPM, 0, 0, &asp_tx4_mux), ++ SND_SOC_DAPM_MUX("DSP RX1 Source", SND_SOC_NOPM, 0, 0, &dsp_rx1_mux), ++ SND_SOC_DAPM_MUX("DSP RX2 Source", SND_SOC_NOPM, 0, 0, &dsp_rx2_mux), + SND_SOC_DAPM_MUX("PCM Source", SND_SOC_NOPM, 0, 0, &pcm_source_mux), + SND_SOC_DAPM_SWITCH("DRE", SND_SOC_NOPM, 0, 0, &dre_ctrl), + }; + + static const struct snd_soc_dapm_route cs35l41_audio_map[] = { ++ {"DSP RX1 Source", "ASPRX1", "ASPRX1"}, ++ {"DSP RX1 Source", "ASPRX2", "ASPRX2"}, ++ {"DSP RX2 Source", "ASPRX1", "ASPRX1"}, ++ {"DSP RX2 Source", "ASPRX2", "ASPRX2"}, ++ ++ {"DSP1", NULL, "DSP RX1 Source"}, ++ {"DSP1", NULL, "DSP RX2 Source"}, ++ + {"ASP TX1 Source", "VMON", "VMON ADC"}, + {"ASP TX1 Source", "IMON", "IMON ADC"}, + {"ASP TX1 Source", "VPMON", "VPMON ADC"}, + {"ASP TX1 Source", "VBSTMON", "VBSTMON ADC"}, ++ {"ASP TX1 Source", "DSPTX1", "DSP1"}, ++ {"ASP TX1 Source", "DSPTX2", "DSP1"}, + {"ASP TX1 Source", "ASPRX1", "ASPRX1" }, + {"ASP TX1 Source", "ASPRX2", "ASPRX2" }, + {"ASP TX2 Source", "VMON", "VMON ADC"}, + {"ASP TX2 Source", "IMON", "IMON ADC"}, + {"ASP TX2 Source", "VPMON", "VPMON ADC"}, + {"ASP TX2 Source", "VBSTMON", "VBSTMON ADC"}, ++ {"ASP TX2 Source", "DSPTX1", "DSP1"}, ++ {"ASP TX2 Source", "DSPTX2", "DSP1"}, + {"ASP TX2 Source", "ASPRX1", "ASPRX1" }, + {"ASP TX2 Source", "ASPRX2", "ASPRX2" }, + {"ASP TX3 Source", "VMON", "VMON ADC"}, + {"ASP TX3 Source", "IMON", "IMON ADC"}, + {"ASP TX3 Source", "VPMON", "VPMON ADC"}, + {"ASP TX3 Source", "VBSTMON", "VBSTMON ADC"}, ++ {"ASP TX3 Source", "DSPTX1", "DSP1"}, ++ {"ASP TX3 Source", "DSPTX2", "DSP1"}, + {"ASP TX3 Source", "ASPRX1", "ASPRX1" }, + {"ASP TX3 Source", "ASPRX2", "ASPRX2" }, + {"ASP TX4 Source", "VMON", "VMON ADC"}, + {"ASP TX4 Source", "IMON", "IMON ADC"}, + {"ASP TX4 Source", "VPMON", "VPMON ADC"}, + {"ASP TX4 Source", "VBSTMON", "VBSTMON ADC"}, ++ {"ASP TX4 Source", "DSPTX1", "DSP1"}, ++ {"ASP TX4 Source", "DSPTX2", "DSP1"}, + {"ASP TX4 Source", "ASPRX1", "ASPRX1" }, + {"ASP TX4 Source", "ASPRX2", "ASPRX2" }, + {"ASPTX1", NULL, "ASP TX1 Source"}, +@@ -671,12 +840,27 @@ static const struct snd_soc_dapm_route cs35l41_audio_map[] = { + {"AMP Capture", NULL, "ASPTX3"}, + {"AMP Capture", NULL, "ASPTX4"}, + ++ {"DSP1", NULL, "VMON"}, ++ {"DSP1", NULL, "IMON"}, ++ {"DSP1", NULL, "VPMON"}, ++ {"DSP1", NULL, "VBSTMON"}, ++ {"DSP1", NULL, "TEMPMON"}, ++ ++ {"VMON ADC", NULL, "VMON"}, ++ {"IMON ADC", NULL, "IMON"}, ++ {"VPMON ADC", NULL, "VPMON"}, ++ {"VBSTMON ADC", NULL, "VBSTMON"}, ++ {"TEMPMON ADC", NULL, "TEMPMON"}, ++ + {"VMON ADC", NULL, "VSENSE"}, + {"IMON ADC", NULL, "ISENSE"}, + {"VPMON ADC", NULL, "VP"}, + {"VBSTMON ADC", NULL, "VBST"}, + {"TEMPMON ADC", NULL, "TEMP"}, + ++ {"DSP1 Preload", NULL, "DSP1 Preloader"}, ++ {"DSP1", NULL, "DSP1 Preloader"}, ++ + {"ASPRX1", NULL, "AMP Playback"}, + {"ASPRX2", NULL, "AMP Playback"}, + {"DRE", "Switch", "CLASS H"}, +@@ -685,9 +869,18 @@ static const struct snd_soc_dapm_route cs35l41_audio_map[] = { + {"SPK", NULL, "Main AMP"}, + + {"PCM Source", "ASP", "ASPRX1"}, ++ {"PCM Source", "DSP", "DSP1"}, + {"CLASS H", NULL, "PCM Source"}, + }; + ++static const struct cs_dsp_region cs35l41_dsp1_regions[] = { ++ { .type = WMFW_HALO_PM_PACKED, .base = CS35L41_DSP1_PMEM_0 }, ++ { .type = WMFW_HALO_XM_PACKED, .base = CS35L41_DSP1_XMEM_PACK_0 }, ++ { .type = WMFW_HALO_YM_PACKED, .base = CS35L41_DSP1_YMEM_PACK_0 }, ++ {. type = WMFW_ADSP2_XM, .base = CS35L41_DSP1_XMEM_UNPACK24_0}, ++ {. type = WMFW_ADSP2_YM, .base = CS35L41_DSP1_YMEM_UNPACK24_0}, ++}; ++ + static int cs35l41_set_channel_map(struct snd_soc_dai *dai, unsigned int tx_num, + unsigned int *tx_slot, unsigned int rx_num, + unsigned int *rx_slot) +@@ -1098,6 +1291,20 @@ static int cs35l41_irq_gpio_config(struct cs35l41_private *cs35l41) + return irq_pol; + } + ++static int cs35l41_component_probe(struct snd_soc_component *component) ++{ ++ struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component); ++ ++ return wm_adsp2_component_probe(&cs35l41->dsp, component); ++} ++ ++static void cs35l41_component_remove(struct snd_soc_component *component) ++{ ++ struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component); ++ ++ wm_adsp2_component_remove(&cs35l41->dsp, component); ++} ++ + static const struct snd_soc_dai_ops cs35l41_ops = { + .startup = cs35l41_pcm_startup, + .set_fmt = cs35l41_set_dai_fmt, +@@ -1131,6 +1338,8 @@ static struct snd_soc_dai_driver cs35l41_dai[] = { + + static const struct snd_soc_component_driver soc_component_dev_cs35l41 = { + .name = "cs35l41-codec", ++ .probe = cs35l41_component_probe, ++ .remove = cs35l41_component_remove, + + .dapm_widgets = cs35l41_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(cs35l41_dapm_widgets), +@@ -1237,6 +1446,90 @@ static const struct reg_sequence cs35l41_revb2_errata_patch[] = { + { 0x00000040, 0x00003333 }, + }; + ++static const struct reg_sequence cs35l41_fs_errata_patch[] = { ++ { CS35L41_DSP1_RX1_RATE, 0x00000001 }, ++ { CS35L41_DSP1_RX2_RATE, 0x00000001 }, ++ { CS35L41_DSP1_RX3_RATE, 0x00000001 }, ++ { CS35L41_DSP1_RX4_RATE, 0x00000001 }, ++ { CS35L41_DSP1_RX5_RATE, 0x00000001 }, ++ { CS35L41_DSP1_RX6_RATE, 0x00000001 }, ++ { CS35L41_DSP1_RX7_RATE, 0x00000001 }, ++ { CS35L41_DSP1_RX8_RATE, 0x00000001 }, ++ { CS35L41_DSP1_TX1_RATE, 0x00000001 }, ++ { CS35L41_DSP1_TX2_RATE, 0x00000001 }, ++ { CS35L41_DSP1_TX3_RATE, 0x00000001 }, ++ { CS35L41_DSP1_TX4_RATE, 0x00000001 }, ++ { CS35L41_DSP1_TX5_RATE, 0x00000001 }, ++ { CS35L41_DSP1_TX6_RATE, 0x00000001 }, ++ { CS35L41_DSP1_TX7_RATE, 0x00000001 }, ++ { CS35L41_DSP1_TX8_RATE, 0x00000001 }, ++}; ++ ++static int cs35l41_dsp_init(struct cs35l41_private *cs35l41) ++{ ++ struct wm_adsp *dsp; ++ int ret; ++ ++ dsp = &cs35l41->dsp; ++ dsp->part = "cs35l41"; ++ dsp->cs_dsp.num = 1; ++ dsp->cs_dsp.type = WMFW_HALO; ++ dsp->cs_dsp.rev = 0; ++ dsp->fw = 9; /* 9 is WM_ADSP_FW_SPK_PROT in wm_adsp.c */ ++ dsp->cs_dsp.dev = cs35l41->dev; ++ dsp->cs_dsp.regmap = cs35l41->regmap; ++ dsp->cs_dsp.base = CS35L41_DSP1_CTRL_BASE; ++ dsp->cs_dsp.base_sysinfo = CS35L41_DSP1_SYS_ID; ++ dsp->cs_dsp.mem = cs35l41_dsp1_regions; ++ dsp->cs_dsp.num_mems = ARRAY_SIZE(cs35l41_dsp1_regions); ++ dsp->cs_dsp.lock_regions = 0xFFFFFFFF; ++ ++ ret = regmap_multi_reg_write(cs35l41->regmap, cs35l41_fs_errata_patch, ++ ARRAY_SIZE(cs35l41_fs_errata_patch)); ++ if (ret < 0) { ++ dev_err(cs35l41->dev, "Failed to write fs errata: %d\n", ret); ++ return ret; ++ } ++ ++ ret = wm_halo_init(dsp); ++ if (ret) { ++ dev_err(cs35l41->dev, "wm_halo_init failed: %d\n", ret); ++ return ret; ++ } ++ ++ ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_RX5_SRC, ++ CS35L41_INPUT_SRC_VPMON); ++ if (ret < 0) { ++ dev_err(cs35l41->dev, "Write INPUT_SRC_VPMON failed: %d\n", ret); ++ goto err_dsp; ++ } ++ ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_RX6_SRC, ++ CS35L41_INPUT_SRC_CLASSH); ++ if (ret < 0) { ++ dev_err(cs35l41->dev, "Write INPUT_SRC_CLASSH failed: %d\n", ret); ++ goto err_dsp; ++ } ++ ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_RX7_SRC, ++ CS35L41_INPUT_SRC_TEMPMON); ++ if (ret < 0) { ++ dev_err(cs35l41->dev, "Write INPUT_SRC_TEMPMON failed: %d\n", ret); ++ goto err_dsp; ++ } ++ ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_RX8_SRC, ++ CS35L41_INPUT_SRC_RSVD); ++ if (ret < 0) { ++ dev_err(cs35l41->dev, "Write INPUT_SRC_RSVD failed: %d\n", ret); ++ goto err_dsp; ++ } ++ ++ return 0; ++ ++err_dsp: ++ wm_adsp2_remove(dsp); ++ ++ return ret; ++} ++ + int cs35l41_probe(struct cs35l41_private *cs35l41, + struct cs35l41_platform_data *pdata) + { +@@ -1413,12 +1706,16 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, + goto err; + } + ++ ret = cs35l41_dsp_init(cs35l41); ++ if (ret < 0) ++ goto err; ++ + ret = devm_snd_soc_register_component(cs35l41->dev, + &soc_component_dev_cs35l41, + cs35l41_dai, ARRAY_SIZE(cs35l41_dai)); + if (ret < 0) { + dev_err(cs35l41->dev, "Register codec failed: %d\n", ret); +- goto err; ++ goto err_dsp; + } + + dev_info(cs35l41->dev, "Cirrus Logic CS35L41 (%x), Revision: %02X\n", +@@ -1426,6 +1723,8 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, + + return 0; + ++err_dsp: ++ wm_adsp2_remove(&cs35l41->dsp); + err: + regulator_bulk_disable(CS35L41_NUM_SUPPLIES, cs35l41->supplies); + gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); +@@ -1436,6 +1735,7 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, + void cs35l41_remove(struct cs35l41_private *cs35l41) + { + regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, 0xFFFFFFFF); ++ wm_adsp2_remove(&cs35l41->dsp); + regulator_bulk_disable(CS35L41_NUM_SUPPLIES, cs35l41->supplies); + gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); + } +diff --git a/sound/soc/codecs/cs35l41.h b/sound/soc/codecs/cs35l41.h +index 6cffe8a55beb..eea3b14acb0b 100644 +--- a/sound/soc/codecs/cs35l41.h ++++ b/sound/soc/codecs/cs35l41.h +@@ -13,9 +13,12 @@ + #include + #include + #include ++#include + #include + #include + ++#include "wm_adsp.h" ++ + #define CS35L41_FIRSTREG 0x00000000 + #define CS35L41_LASTREG 0x03804FE8 + #define CS35L41_DEVID 0x00000000 +@@ -755,7 +758,24 @@ extern const struct cs35l41_otp_map_element_t + + #define CS35L41_REGSTRIDE 4 + ++enum cs35l41_cspl_mbox_status { ++ CSPL_MBOX_STS_RUNNING = 0, ++ CSPL_MBOX_STS_PAUSED = 1, ++ CSPL_MBOX_STS_RDY_FOR_REINIT = 2, ++}; ++ ++enum cs35l41_cspl_mbox_cmd { ++ CSPL_MBOX_CMD_NONE = 0, ++ CSPL_MBOX_CMD_PAUSE = 1, ++ CSPL_MBOX_CMD_RESUME = 2, ++ CSPL_MBOX_CMD_REINIT = 3, ++ CSPL_MBOX_CMD_STOP_PRE_REINIT = 4, ++ CSPL_MBOX_CMD_UNKNOWN_CMD = -1, ++ CSPL_MBOX_CMD_INVALID_SEQUENCE = -2, ++}; ++ + struct cs35l41_private { ++ struct wm_adsp dsp; /* needs to be first member */ + struct snd_soc_codec *codec; + struct cs35l41_platform_data pdata; + struct device *dev; +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Do-not-print-error-when-waking-from-hib.patch b/patches.suse/ASoC-cs35l41-Do-not-print-error-when-waking-from-hib.patch new file mode 100644 index 0000000..5f02422 --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Do-not-print-error-when-waking-from-hib.patch @@ -0,0 +1,41 @@ +From 97076475e2fdf471348b9ce73215cdbceeb4390f Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Wed, 25 May 2022 14:16:31 +0100 +Subject: [PATCH] ASoC: cs35l41: Do not print error when waking from hibernation +Git-commit: 97076475e2fdf471348b9ce73215cdbceeb4390f +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +When waking from hibernation, it is possible for the function +which sends the wake command to fail initially, but after a +retry it will succeed. There is no need to print an error if +the initial attempts fail. + +Signed-off-by: Stefan Binding +Signed-off-by: Vitaly Rodionov +Acked-by: Charles Keepax +Link: https://lore.kernel.org/r/20220525131638.5512-11-vitalyr@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs35l41-lib.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c +index 10b754481ca2..0c7d1c791279 100644 +--- a/sound/soc/codecs/cs35l41-lib.c ++++ b/sound/soc/codecs/cs35l41-lib.c +@@ -1302,7 +1302,8 @@ int cs35l41_set_cspl_mbox_cmd(struct device *dev, struct regmap *regmap, + return 0; + } + +- dev_err(dev, "Failed to set mailbox cmd %u (status %u)\n", cmd, sts); ++ if (cmd != CSPL_MBOX_CMD_OUT_OF_HIBERNATE) ++ dev_err(dev, "Failed to set mailbox cmd %u (status %u)\n", cmd, sts); + + return -ENOMSG; + } +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Document-CS35l41-External-Boost.patch b/patches.suse/ASoC-cs35l41-Document-CS35l41-External-Boost.patch new file mode 100644 index 0000000..624104f --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Document-CS35l41-External-Boost.patch @@ -0,0 +1,103 @@ +From 4b047ec3a15d1eda7a3d8526566796ad4f4930c0 Mon Sep 17 00:00:00 2001 +From: David Rhodes +Date: Wed, 13 Apr 2022 09:37:27 +0100 +Subject: [PATCH] ASoC: cs35l41: Document CS35l41 External Boost +Git-commit: 4b047ec3a15d1eda7a3d8526566796ad4f4930c0 +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +Document internal and external boost feature for ASoC CS35L41. +For internal boost the following properties are required: +- cirrus,boost-peak-milliamp +- cirrus,boost-ind-nanohenry +- cirrus,boost-cap-microfarad + +For external boost, the GPIO1 must be configured as output, +so the following properties are required: +- cirrus,gpio1-src-select = <1> +- cirrus,gpio1-output-enable + +Signed-off-by: David Rhodes +Signed-off-by: Lucas Tanure +Acked-by: Charles Keepax +Reviewed-by: Rob Herring +Acked-by: Mark Brown +Link: https://lore.kernel.org/r/20220413083728.10730-16-tanureal@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + .../bindings/sound/cirrus,cs35l41.yaml | 44 +++++++++++++++++-- + 1 file changed, 41 insertions(+), 3 deletions(-) + +diff --git a/Documentation/devicetree/bindings/sound/cirrus,cs35l41.yaml b/Documentation/devicetree/bindings/sound/cirrus,cs35l41.yaml +index 3235702ce402..51d815d0c696 100644 +--- a/Documentation/devicetree/bindings/sound/cirrus,cs35l41.yaml ++++ b/Documentation/devicetree/bindings/sound/cirrus,cs35l41.yaml +@@ -75,6 +75,19 @@ properties: + maximum: 3 + default: 2 + ++ cirrus,boost-type: ++ description: ++ Configures the type of Boost being used. ++ Internal boost requires boost-peak-milliamp, boost-ind-nanohenry and ++ boost-cap-microfarad. ++ External Boost must have GPIO1 as GPIO output. GPIO1 will be set high to ++ enable boost voltage. ++ 0 = Internal Boost ++ 1 = External Boost ++ $ref: "/schemas/types.yaml#/definitions/uint32" ++ minimum: 0 ++ maximum: 1 ++ + cirrus,gpio1-polarity-invert: + description: + Boolean which specifies whether the GPIO1 +@@ -131,9 +144,32 @@ required: + - compatible + - reg + - "#sound-dai-cells" +- - cirrus,boost-peak-milliamp +- - cirrus,boost-ind-nanohenry +- - cirrus,boost-cap-microfarad ++ ++allOf: ++ - if: ++ properties: ++ cirrus,boost-type: ++ const: 0 ++ then: ++ required: ++ - cirrus,boost-peak-milliamp ++ - cirrus,boost-ind-nanohenry ++ - cirrus,boost-cap-microfarad ++ else: ++ if: ++ properties: ++ cirrus,boost-type: ++ const: 1 ++ then: ++ required: ++ - cirrus,gpio1-output-enable ++ - cirrus,gpio1-src-select ++ properties: ++ cirrus,boost-peak-milliamp: false ++ cirrus,boost-ind-nanohenry: false ++ cirrus,boost-cap-microfarad: false ++ cirrus,gpio1-src-select: ++ enum: [1] + + additionalProperties: false + +@@ -150,6 +186,8 @@ examples: + VA-supply = <&dummy_vreg>; + VP-supply = <&dummy_vreg>; + reset-gpios = <&gpio 110 0>; ++ ++ cirrus,boost-type = <0>; + cirrus,boost-peak-milliamp = <4500>; + cirrus,boost-ind-nanohenry = <1000>; + cirrus,boost-cap-microfarad = <15>; +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Don-t-overwrite-returned-error-code.patch b/patches.suse/ASoC-cs35l41-Don-t-overwrite-returned-error-code.patch new file mode 100644 index 0000000..dde14e7 --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Don-t-overwrite-returned-error-code.patch @@ -0,0 +1,88 @@ +From e371eadf2a93a653211331b66beaac3b1bcbc931 Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Tue, 14 Sep 2021 15:13:47 +0100 +Subject: [PATCH] ASoC: cs35l41: Don't overwrite returned error code +Git-commit: e371eadf2a93a653211331b66beaac3b1bcbc931 +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +In multiple places the driver overwrites the error code returned with +a static error code, this is not helpful for debugging. Update to pass +the error codes straight through. + +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20210914141349.30218-4-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs35l41.c | 8 -------- + 1 file changed, 8 deletions(-) + +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index ce652a454dfc..0d7073bb313a 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -317,7 +317,6 @@ static int cs35l41_otp_unpack(void *data) + ret = regmap_read(cs35l41->regmap, CS35L41_OTPID, &otp_id_reg); + if (ret < 0) { + dev_err(cs35l41->dev, "Read OTP ID failed\n"); +- ret = -EINVAL; + goto err_otp_unpack; + } + +@@ -337,7 +336,6 @@ static int cs35l41_otp_unpack(void *data) + CS35L41_OTP_SIZE_WORDS); + if (ret < 0) { + dev_err(cs35l41->dev, "Read OTP Mem failed\n"); +- ret = -EINVAL; + goto err_otp_unpack; + } + +@@ -352,13 +350,11 @@ static int cs35l41_otp_unpack(void *data) + ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x00000055); + if (ret < 0) { + dev_err(cs35l41->dev, "Write Unlock key failed 1/2\n"); +- ret = -EINVAL; + goto err_otp_unpack; + } + ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x000000AA); + if (ret < 0) { + dev_err(cs35l41->dev, "Write Unlock key failed 2/2\n"); +- ret = -EINVAL; + goto err_otp_unpack; + } + +@@ -398,7 +394,6 @@ static int cs35l41_otp_unpack(void *data) + otp_val << otp_map[i].shift); + if (ret < 0) { + dev_err(cs35l41->dev, "Write OTP val failed\n"); +- ret = -EINVAL; + goto err_otp_unpack; + } + } +@@ -407,13 +402,11 @@ static int cs35l41_otp_unpack(void *data) + ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x000000CC); + if (ret < 0) { + dev_err(cs35l41->dev, "Write Lock key failed 1/2\n"); +- ret = -EINVAL; + goto err_otp_unpack; + } + ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x00000033); + if (ret < 0) { + dev_err(cs35l41->dev, "Write Lock key failed 2/2\n"); +- ret = -EINVAL; + goto err_otp_unpack; + } + ret = 0; +@@ -1413,7 +1406,6 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, + /* CS35L41 needs INT for PDN_DONE */ + if (ret != 0) { + dev_err(cs35l41->dev, "Failed to request IRQ: %d\n", ret); +- ret = -ENODEV; + goto err; + } + +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Fix-DSP-mbox-start-command-and-global-e.patch b/patches.suse/ASoC-cs35l41-Fix-DSP-mbox-start-command-and-global-e.patch new file mode 100644 index 0000000..37facd8 --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Fix-DSP-mbox-start-command-and-global-e.patch @@ -0,0 +1,47 @@ +From 5e02fb590e83684f63217f93a9cdeabd6a925f9c Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Thu, 3 Mar 2022 17:30:42 +0000 +Subject: [PATCH] ASoC: cs35l41: Fix DSP mbox start command and global enable order +Git-commit: 5e02fb590e83684f63217f93a9cdeabd6a925f9c +Patch-mainline: v5.18-rc1 +References: bsc#1203699 + +Global enable must happen before CSPL_MBOX_CMD_RESUME command +is sent. Move it to PRE_PMU as both events use +SND_SOC_DAPM_OUT_DRV_E macro. + +Signed-off-by: Lucas Tanure +Acked-by: Charles Keepax +Link: https://lore.kernel.org/r/20220303173059.269657-4-tanureal@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs35l41.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index f3787d77f892..05de94fd2e55 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -573,7 +573,7 @@ static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w, + int ret = 0; + + switch (event) { +- case SND_SOC_DAPM_POST_PMU: ++ case SND_SOC_DAPM_PRE_PMU: + regmap_multi_reg_write_bypassed(cs35l41->regmap, + cs35l41_pup_patch, + ARRAY_SIZE(cs35l41_pup_patch)); +@@ -649,7 +649,7 @@ static const struct snd_soc_dapm_widget cs35l41_dapm_widgets[] = { + + SND_SOC_DAPM_OUT_DRV_E("Main AMP", CS35L41_PWR_CTRL2, 0, 0, NULL, 0, + cs35l41_main_amp_event, +- SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), ++ SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_PRE_PMU), + + SND_SOC_DAPM_MUX("ASP TX1 Source", SND_SOC_NOPM, 0, 0, &asp_tx1_mux), + SND_SOC_DAPM_MUX("ASP TX2 Source", SND_SOC_NOPM, 0, 0, &asp_tx2_mux), +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Fix-GPIO2-configuration.patch b/patches.suse/ASoC-cs35l41-Fix-GPIO2-configuration.patch new file mode 100644 index 0000000..b763218 --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Fix-GPIO2-configuration.patch @@ -0,0 +1,39 @@ +From 03a7895ee701e873c88c06bdb830ff40adb2be73 Mon Sep 17 00:00:00 2001 +From: David Rhodes +Date: Thu, 3 Mar 2022 17:30:40 +0000 +Subject: [PATCH] ASoC: cs35l41: Fix GPIO2 configuration +Git-commit: 03a7895ee701e873c88c06bdb830ff40adb2be73 +Patch-mainline: v5.18-rc1 +References: bsc#1203699 + +Fix GPIO2 polarity and direction configuration + +Fixes: fe1024d50477b ("ASoC: cs35l41: Combine adjacent register writes") +Signed-off-by: David Rhodes +Acked-by: Charles Keepax +Link: https://lore.kernel.org/r/20220303173059.269657-2-tanureal@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs35l41.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index 77a017694645..90c91b00288b 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -1035,8 +1035,8 @@ static int cs35l41_irq_gpio_config(struct cs35l41_private *cs35l41) + + regmap_update_bits(cs35l41->regmap, CS35L41_GPIO2_CTRL1, + CS35L41_GPIO_POL_MASK | CS35L41_GPIO_DIR_MASK, +- irq_gpio_cfg1->irq_pol_inv << CS35L41_GPIO_POL_SHIFT | +- !irq_gpio_cfg1->irq_out_en << CS35L41_GPIO_DIR_SHIFT); ++ irq_gpio_cfg2->irq_pol_inv << CS35L41_GPIO_POL_SHIFT | ++ !irq_gpio_cfg2->irq_out_en << CS35L41_GPIO_DIR_SHIFT); + + regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL, + CS35L41_GPIO1_CTRL_MASK | CS35L41_GPIO2_CTRL_MASK, +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Fix-a-bunch-of-trivial-code-formating-s.patch b/patches.suse/ASoC-cs35l41-Fix-a-bunch-of-trivial-code-formating-s.patch new file mode 100644 index 0000000..281cd9d --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Fix-a-bunch-of-trivial-code-formating-s.patch @@ -0,0 +1,1561 @@ +From 4295c8cc17481e0d7d4c3a404eaf87dc8dfc26be Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Tue, 14 Sep 2021 15:13:49 +0100 +Subject: [PATCH] ASoC: cs35l41: Fix a bunch of trivial code formating/style issues +Git-commit: 4295c8cc17481e0d7d4c3a404eaf87dc8dfc26be +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20210914141349.30218-6-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs35l41-i2c.c | 5 +- + sound/soc/codecs/cs35l41-spi.c | 13 +- + sound/soc/codecs/cs35l41-tables.c | 477 +++++++++++++++--------------- + sound/soc/codecs/cs35l41.c | 387 ++++++++++++------------ + sound/soc/codecs/cs35l41.h | 81 +++-- + 5 files changed, 467 insertions(+), 496 deletions(-) + +diff --git a/sound/soc/codecs/cs35l41-i2c.c b/sound/soc/codecs/cs35l41-i2c.c +index dc9da78df412..2f3d1bd8e046 100644 +--- a/sound/soc/codecs/cs35l41-i2c.c ++++ b/sound/soc/codecs/cs35l41-i2c.c +@@ -44,7 +44,7 @@ static const struct i2c_device_id cs35l41_id_i2c[] = { + MODULE_DEVICE_TABLE(i2c, cs35l41_id_i2c); + + static int cs35l41_i2c_probe(struct i2c_client *client, +- const struct i2c_device_id *id) ++ const struct i2c_device_id *id) + { + struct cs35l41_private *cs35l41; + struct device *dev = &client->dev; +@@ -64,8 +64,7 @@ static int cs35l41_i2c_probe(struct i2c_client *client, + cs35l41->regmap = devm_regmap_init_i2c(client, regmap_config); + if (IS_ERR(cs35l41->regmap)) { + ret = PTR_ERR(cs35l41->regmap); +- dev_err(cs35l41->dev, "Failed to allocate register map: %d\n", +- ret); ++ dev_err(cs35l41->dev, "Failed to allocate register map: %d\n", ret); + return ret; + } + +diff --git a/sound/soc/codecs/cs35l41-spi.c b/sound/soc/codecs/cs35l41-spi.c +index e253c6d82ce8..eac64779eea8 100644 +--- a/sound/soc/codecs/cs35l41-spi.c ++++ b/sound/soc/codecs/cs35l41-spi.c +@@ -43,7 +43,7 @@ static const struct spi_device_id cs35l41_id_spi[] = { + MODULE_DEVICE_TABLE(spi, cs35l41_id_spi); + + static void cs35l41_spi_otp_setup(struct cs35l41_private *cs35l41, +- bool is_pre_setup, unsigned int *freq) ++ bool is_pre_setup, unsigned int *freq) + { + struct spi_device *spi; + u32 orig_spi_freq; +@@ -73,24 +73,19 @@ static void cs35l41_spi_otp_setup(struct cs35l41_private *cs35l41, + static int cs35l41_spi_probe(struct spi_device *spi) + { + const struct regmap_config *regmap_config = &cs35l41_regmap_spi; +- struct cs35l41_platform_data *pdata = +- dev_get_platdata(&spi->dev); ++ struct cs35l41_platform_data *pdata = dev_get_platdata(&spi->dev); + struct cs35l41_private *cs35l41; + int ret; + +- cs35l41 = devm_kzalloc(&spi->dev, +- sizeof(struct cs35l41_private), +- GFP_KERNEL); ++ cs35l41 = devm_kzalloc(&spi->dev, sizeof(struct cs35l41_private), GFP_KERNEL); + if (!cs35l41) + return -ENOMEM; + +- + spi_set_drvdata(spi, cs35l41); + cs35l41->regmap = devm_regmap_init_spi(spi, regmap_config); + if (IS_ERR(cs35l41->regmap)) { + ret = PTR_ERR(cs35l41->regmap); +- dev_err(&spi->dev, "Failed to allocate register map: %d\n", +- ret); ++ dev_err(&spi->dev, "Failed to allocate register map: %d\n", ret); + return ret; + } + +diff --git a/sound/soc/codecs/cs35l41-tables.c b/sound/soc/codecs/cs35l41-tables.c +index 155db0e6e3d8..964e530afa27 100644 +--- a/sound/soc/codecs/cs35l41-tables.c ++++ b/sound/soc/codecs/cs35l41-tables.c +@@ -9,42 +9,42 @@ + #include "cs35l41.h" + + const struct reg_default cs35l41_reg[CS35L41_MAX_CACHE_REG] = { +- {CS35L41_PWR_CTRL1, 0x00000000}, +- {CS35L41_PWR_CTRL3, 0x01000010}, +- {CS35L41_GPIO_PAD_CONTROL, 0x00000000}, +- {CS35L41_SP_ENABLES, 0x00000000}, +- {CS35L41_SP_RATE_CTRL, 0x00000028}, +- {CS35L41_SP_FORMAT, 0x18180200}, +- {CS35L41_SP_HIZ_CTRL, 0x00000002}, +- {CS35L41_SP_FRAME_TX_SLOT, 0x03020100}, +- {CS35L41_SP_FRAME_RX_SLOT, 0x00000100}, +- {CS35L41_SP_TX_WL, 0x00000018}, +- {CS35L41_SP_RX_WL, 0x00000018}, +- {CS35L41_DAC_PCM1_SRC, 0x00000008}, +- {CS35L41_ASP_TX1_SRC, 0x00000018}, +- {CS35L41_ASP_TX2_SRC, 0x00000019}, +- {CS35L41_ASP_TX3_SRC, 0x00000020}, +- {CS35L41_ASP_TX4_SRC, 0x00000021}, +- {CS35L41_DSP1_RX1_SRC, 0x00000008}, +- {CS35L41_DSP1_RX2_SRC, 0x00000009}, +- {CS35L41_DSP1_RX3_SRC, 0x00000018}, +- {CS35L41_DSP1_RX4_SRC, 0x00000019}, +- {CS35L41_DSP1_RX5_SRC, 0x00000020}, +- {CS35L41_DSP1_RX6_SRC, 0x00000021}, +- {CS35L41_DSP1_RX7_SRC, 0x0000003A}, +- {CS35L41_DSP1_RX8_SRC, 0x00000001}, +- {CS35L41_NGATE1_SRC, 0x00000008}, +- {CS35L41_NGATE2_SRC, 0x00000009}, +- {CS35L41_AMP_DIG_VOL_CTRL, 0x00008000}, +- {CS35L41_CLASSH_CFG, 0x000B0405}, +- {CS35L41_WKFET_CFG, 0x00000111}, +- {CS35L41_NG_CFG, 0x00000033}, +- {CS35L41_AMP_GAIN_CTRL, 0x00000273}, +- {CS35L41_GPIO1_CTRL1, 0xE1000001}, +- {CS35L41_GPIO2_CTRL1, 0xE1000001}, +- {CS35L41_MIXER_NGATE_CFG, 0x00000000}, +- {CS35L41_MIXER_NGATE_CH1_CFG, 0x00000303}, +- {CS35L41_MIXER_NGATE_CH2_CFG, 0x00000303}, ++ { CS35L41_PWR_CTRL1, 0x00000000 }, ++ { CS35L41_PWR_CTRL3, 0x01000010 }, ++ { CS35L41_GPIO_PAD_CONTROL, 0x00000000 }, ++ { CS35L41_SP_ENABLES, 0x00000000 }, ++ { CS35L41_SP_RATE_CTRL, 0x00000028 }, ++ { CS35L41_SP_FORMAT, 0x18180200 }, ++ { CS35L41_SP_HIZ_CTRL, 0x00000002 }, ++ { CS35L41_SP_FRAME_TX_SLOT, 0x03020100 }, ++ { CS35L41_SP_FRAME_RX_SLOT, 0x00000100 }, ++ { CS35L41_SP_TX_WL, 0x00000018 }, ++ { CS35L41_SP_RX_WL, 0x00000018 }, ++ { CS35L41_DAC_PCM1_SRC, 0x00000008 }, ++ { CS35L41_ASP_TX1_SRC, 0x00000018 }, ++ { CS35L41_ASP_TX2_SRC, 0x00000019 }, ++ { CS35L41_ASP_TX3_SRC, 0x00000020 }, ++ { CS35L41_ASP_TX4_SRC, 0x00000021 }, ++ { CS35L41_DSP1_RX1_SRC, 0x00000008 }, ++ { CS35L41_DSP1_RX2_SRC, 0x00000009 }, ++ { CS35L41_DSP1_RX3_SRC, 0x00000018 }, ++ { CS35L41_DSP1_RX4_SRC, 0x00000019 }, ++ { CS35L41_DSP1_RX5_SRC, 0x00000020 }, ++ { CS35L41_DSP1_RX6_SRC, 0x00000021 }, ++ { CS35L41_DSP1_RX7_SRC, 0x0000003A }, ++ { CS35L41_DSP1_RX8_SRC, 0x00000001 }, ++ { CS35L41_NGATE1_SRC, 0x00000008 }, ++ { CS35L41_NGATE2_SRC, 0x00000009 }, ++ { CS35L41_AMP_DIG_VOL_CTRL, 0x00008000 }, ++ { CS35L41_CLASSH_CFG, 0x000B0405 }, ++ { CS35L41_WKFET_CFG, 0x00000111 }, ++ { CS35L41_NG_CFG, 0x00000033 }, ++ { CS35L41_AMP_GAIN_CTRL, 0x00000273 }, ++ { CS35L41_GPIO1_CTRL1, 0xE1000001 }, ++ { CS35L41_GPIO2_CTRL1, 0xE1000001 }, ++ { CS35L41_MIXER_NGATE_CFG, 0x00000000 }, ++ { CS35L41_MIXER_NGATE_CH1_CFG, 0x00000303 }, ++ { CS35L41_MIXER_NGATE_CH2_CFG, 0x00000303 }, + }; + + bool cs35l41_readable_reg(struct device *dev, unsigned int reg) +@@ -349,216 +349,213 @@ bool cs35l41_volatile_reg(struct device *dev, unsigned int reg) + } + } + +-static const struct cs35l41_otp_packed_element_t +- otp_map_1[CS35L41_NUM_OTP_ELEM] = { ++static const struct cs35l41_otp_packed_element_t otp_map_1[CS35L41_NUM_OTP_ELEM] = { + /* addr shift size */ +- {0x00002030, 0, 4}, /*TRIM_OSC_FREQ_TRIM*/ +- {0x00002030, 7, 1}, /*TRIM_OSC_TRIM_DONE*/ +- {0x0000208c, 24, 6}, /*TST_DIGREG_VREF_TRIM*/ +- {0x00002090, 14, 4}, /*TST_REF_TRIM*/ +- {0x00002090, 10, 4}, /*TST_REF_TEMPCO_TRIM*/ +- {0x0000300C, 11, 4}, /*PLL_LDOA_TST_VREF_TRIM*/ +- {0x0000394C, 23, 2}, /*BST_ATEST_CM_VOFF*/ +- {0x00003950, 0, 7}, /*BST_ATRIM_IADC_OFFSET*/ +- {0x00003950, 8, 7}, /*BST_ATRIM_IADC_GAIN1*/ +- {0x00003950, 16, 8}, /*BST_ATRIM_IPKCOMP_OFFSET1*/ +- {0x00003950, 24, 8}, /*BST_ATRIM_IPKCOMP_GAIN1*/ +- {0x00003954, 0, 7}, /*BST_ATRIM_IADC_OFFSET2*/ +- {0x00003954, 8, 7}, /*BST_ATRIM_IADC_GAIN2*/ +- {0x00003954, 16, 8}, /*BST_ATRIM_IPKCOMP_OFFSET2*/ +- {0x00003954, 24, 8}, /*BST_ATRIM_IPKCOMP_GAIN2*/ +- {0x00003958, 0, 7}, /*BST_ATRIM_IADC_OFFSET3*/ +- {0x00003958, 8, 7}, /*BST_ATRIM_IADC_GAIN3*/ +- {0x00003958, 16, 8}, /*BST_ATRIM_IPKCOMP_OFFSET3*/ +- {0x00003958, 24, 8}, /*BST_ATRIM_IPKCOMP_GAIN3*/ +- {0x0000395C, 0, 7}, /*BST_ATRIM_IADC_OFFSET4*/ +- {0x0000395C, 8, 7}, /*BST_ATRIM_IADC_GAIN4*/ +- {0x0000395C, 16, 8}, /*BST_ATRIM_IPKCOMP_OFFSET4*/ +- {0x0000395C, 24, 8}, /*BST_ATRIM_IPKCOMP_GAIN4*/ +- {0x0000416C, 0, 8}, /*VMON_GAIN_OTP_VAL*/ +- {0x00004160, 0, 7}, /*VMON_OFFSET_OTP_VAL*/ +- {0x0000416C, 8, 8}, /*IMON_GAIN_OTP_VAL*/ +- {0x00004160, 16, 10}, /*IMON_OFFSET_OTP_VAL*/ +- {0x0000416C, 16, 12}, /*VMON_CM_GAIN_OTP_VAL*/ +- {0x0000416C, 28, 1}, /*VMON_CM_GAIN_SIGN_OTP_VAL*/ +- {0x00004170, 0, 6}, /*IMON_CAL_TEMPCO_OTP_VAL*/ +- {0x00004170, 6, 1}, /*IMON_CAL_TEMPCO_SIGN_OTP*/ +- {0x00004170, 8, 6}, /*IMON_CAL_TEMPCO2_OTP_VAL*/ +- {0x00004170, 14, 1}, /*IMON_CAL_TEMPCO2_DN_UPB_OTP_VAL*/ +- {0x00004170, 16, 9}, /*IMON_CAL_TEMPCO_TBASE_OTP_VAL*/ +- {0x00004360, 0, 5}, /*TEMP_GAIN_OTP_VAL*/ +- {0x00004360, 6, 9}, /*TEMP_OFFSET_OTP_VAL*/ +- {0x00004448, 0, 8}, /*VP_SARADC_OFFSET*/ +- {0x00004448, 8, 8}, /*VP_GAIN_INDEX*/ +- {0x00004448, 16, 8}, /*VBST_SARADC_OFFSET*/ +- {0x00004448, 24, 8}, /*VBST_GAIN_INDEX*/ +- {0x0000444C, 0, 3}, /*ANA_SELINVREF*/ +- {0x00006E30, 0, 5}, /*GAIN_ERR_COEFF_0*/ +- {0x00006E30, 8, 5}, /*GAIN_ERR_COEFF_1*/ +- {0x00006E30, 16, 5}, /*GAIN_ERR_COEFF_2*/ +- {0x00006E30, 24, 5}, /*GAIN_ERR_COEFF_3*/ +- {0x00006E34, 0, 5}, /*GAIN_ERR_COEFF_4*/ +- {0x00006E34, 8, 5}, /*GAIN_ERR_COEFF_5*/ +- {0x00006E34, 16, 5}, /*GAIN_ERR_COEFF_6*/ +- {0x00006E34, 24, 5}, /*GAIN_ERR_COEFF_7*/ +- {0x00006E38, 0, 5}, /*GAIN_ERR_COEFF_8*/ +- {0x00006E38, 8, 5}, /*GAIN_ERR_COEFF_9*/ +- {0x00006E38, 16, 5}, /*GAIN_ERR_COEFF_10*/ +- {0x00006E38, 24, 5}, /*GAIN_ERR_COEFF_11*/ +- {0x00006E3C, 0, 5}, /*GAIN_ERR_COEFF_12*/ +- {0x00006E3C, 8, 5}, /*GAIN_ERR_COEFF_13*/ +- {0x00006E3C, 16, 5}, /*GAIN_ERR_COEFF_14*/ +- {0x00006E3C, 24, 5}, /*GAIN_ERR_COEFF_15*/ +- {0x00006E40, 0, 5}, /*GAIN_ERR_COEFF_16*/ +- {0x00006E40, 8, 5}, /*GAIN_ERR_COEFF_17*/ +- {0x00006E40, 16, 5}, /*GAIN_ERR_COEFF_18*/ +- {0x00006E40, 24, 5}, /*GAIN_ERR_COEFF_19*/ +- {0x00006E44, 0, 5}, /*GAIN_ERR_COEFF_20*/ +- {0x00006E48, 0, 10}, /*VOFF_GAIN_0*/ +- {0x00006E48, 10, 10}, /*VOFF_GAIN_1*/ +- {0x00006E48, 20, 10}, /*VOFF_GAIN_2*/ +- {0x00006E4C, 0, 10}, /*VOFF_GAIN_3*/ +- {0x00006E4C, 10, 10}, /*VOFF_GAIN_4*/ +- {0x00006E4C, 20, 10}, /*VOFF_GAIN_5*/ +- {0x00006E50, 0, 10}, /*VOFF_GAIN_6*/ +- {0x00006E50, 10, 10}, /*VOFF_GAIN_7*/ +- {0x00006E50, 20, 10}, /*VOFF_GAIN_8*/ +- {0x00006E54, 0, 10}, /*VOFF_GAIN_9*/ +- {0x00006E54, 10, 10}, /*VOFF_GAIN_10*/ +- {0x00006E54, 20, 10}, /*VOFF_GAIN_11*/ +- {0x00006E58, 0, 10}, /*VOFF_GAIN_12*/ +- {0x00006E58, 10, 10}, /*VOFF_GAIN_13*/ +- {0x00006E58, 20, 10}, /*VOFF_GAIN_14*/ +- {0x00006E5C, 0, 10}, /*VOFF_GAIN_15*/ +- {0x00006E5C, 10, 10}, /*VOFF_GAIN_16*/ +- {0x00006E5C, 20, 10}, /*VOFF_GAIN_17*/ +- {0x00006E60, 0, 10}, /*VOFF_GAIN_18*/ +- {0x00006E60, 10, 10}, /*VOFF_GAIN_19*/ +- {0x00006E60, 20, 10}, /*VOFF_GAIN_20*/ +- {0x00006E64, 0, 10}, /*VOFF_INT1*/ +- {0x00007418, 7, 5}, /*DS_SPK_INT1_CAP_TRIM*/ +- {0x0000741C, 0, 5}, /*DS_SPK_INT2_CAP_TRIM*/ +- {0x0000741C, 11, 4}, /*DS_SPK_LPF_CAP_TRIM*/ +- {0x0000741C, 19, 4}, /*DS_SPK_QUAN_CAP_TRIM*/ +- {0x00007434, 17, 1}, /*FORCE_CAL*/ +- {0x00007434, 18, 7}, /*CAL_OVERRIDE*/ +- {0x00007068, 0, 9}, /*MODIX*/ +- {0x0000410C, 7, 1}, /*VIMON_DLY_NOT_COMB*/ +- {0x0000400C, 0, 7}, /*VIMON_DLY*/ +- {0x00000000, 0, 1}, /*extra bit*/ +- {0x00017040, 0, 8}, /*X_COORDINATE*/ +- {0x00017040, 8, 8}, /*Y_COORDINATE*/ +- {0x00017040, 16, 8}, /*WAFER_ID*/ +- {0x00017040, 24, 8}, /*DVS*/ +- {0x00017044, 0, 24}, /*LOT_NUMBER*/ ++ { 0x00002030, 0, 4 }, /*TRIM_OSC_FREQ_TRIM*/ ++ { 0x00002030, 7, 1 }, /*TRIM_OSC_TRIM_DONE*/ ++ { 0x0000208c, 24, 6 }, /*TST_DIGREG_VREF_TRIM*/ ++ { 0x00002090, 14, 4 }, /*TST_REF_TRIM*/ ++ { 0x00002090, 10, 4 }, /*TST_REF_TEMPCO_TRIM*/ ++ { 0x0000300C, 11, 4 }, /*PLL_LDOA_TST_VREF_TRIM*/ ++ { 0x0000394C, 23, 2 }, /*BST_ATEST_CM_VOFF*/ ++ { 0x00003950, 0, 7 }, /*BST_ATRIM_IADC_OFFSET*/ ++ { 0x00003950, 8, 7 }, /*BST_ATRIM_IADC_GAIN1*/ ++ { 0x00003950, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET1*/ ++ { 0x00003950, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN1*/ ++ { 0x00003954, 0, 7 }, /*BST_ATRIM_IADC_OFFSET2*/ ++ { 0x00003954, 8, 7 }, /*BST_ATRIM_IADC_GAIN2*/ ++ { 0x00003954, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET2*/ ++ { 0x00003954, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN2*/ ++ { 0x00003958, 0, 7 }, /*BST_ATRIM_IADC_OFFSET3*/ ++ { 0x00003958, 8, 7 }, /*BST_ATRIM_IADC_GAIN3*/ ++ { 0x00003958, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET3*/ ++ { 0x00003958, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN3*/ ++ { 0x0000395C, 0, 7 }, /*BST_ATRIM_IADC_OFFSET4*/ ++ { 0x0000395C, 8, 7 }, /*BST_ATRIM_IADC_GAIN4*/ ++ { 0x0000395C, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET4*/ ++ { 0x0000395C, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN4*/ ++ { 0x0000416C, 0, 8 }, /*VMON_GAIN_OTP_VAL*/ ++ { 0x00004160, 0, 7 }, /*VMON_OFFSET_OTP_VAL*/ ++ { 0x0000416C, 8, 8 }, /*IMON_GAIN_OTP_VAL*/ ++ { 0x00004160, 16, 10 }, /*IMON_OFFSET_OTP_VAL*/ ++ { 0x0000416C, 16, 12 }, /*VMON_CM_GAIN_OTP_VAL*/ ++ { 0x0000416C, 28, 1 }, /*VMON_CM_GAIN_SIGN_OTP_VAL*/ ++ { 0x00004170, 0, 6 }, /*IMON_CAL_TEMPCO_OTP_VAL*/ ++ { 0x00004170, 6, 1 }, /*IMON_CAL_TEMPCO_SIGN_OTP*/ ++ { 0x00004170, 8, 6 }, /*IMON_CAL_TEMPCO2_OTP_VAL*/ ++ { 0x00004170, 14, 1 }, /*IMON_CAL_TEMPCO2_DN_UPB_OTP_VAL*/ ++ { 0x00004170, 16, 9 }, /*IMON_CAL_TEMPCO_TBASE_OTP_VAL*/ ++ { 0x00004360, 0, 5 }, /*TEMP_GAIN_OTP_VAL*/ ++ { 0x00004360, 6, 9 }, /*TEMP_OFFSET_OTP_VAL*/ ++ { 0x00004448, 0, 8 }, /*VP_SARADC_OFFSET*/ ++ { 0x00004448, 8, 8 }, /*VP_GAIN_INDEX*/ ++ { 0x00004448, 16, 8 }, /*VBST_SARADC_OFFSET*/ ++ { 0x00004448, 24, 8 }, /*VBST_GAIN_INDEX*/ ++ { 0x0000444C, 0, 3 }, /*ANA_SELINVREF*/ ++ { 0x00006E30, 0, 5 }, /*GAIN_ERR_COEFF_0*/ ++ { 0x00006E30, 8, 5 }, /*GAIN_ERR_COEFF_1*/ ++ { 0x00006E30, 16, 5 }, /*GAIN_ERR_COEFF_2*/ ++ { 0x00006E30, 24, 5 }, /*GAIN_ERR_COEFF_3*/ ++ { 0x00006E34, 0, 5 }, /*GAIN_ERR_COEFF_4*/ ++ { 0x00006E34, 8, 5 }, /*GAIN_ERR_COEFF_5*/ ++ { 0x00006E34, 16, 5 }, /*GAIN_ERR_COEFF_6*/ ++ { 0x00006E34, 24, 5 }, /*GAIN_ERR_COEFF_7*/ ++ { 0x00006E38, 0, 5 }, /*GAIN_ERR_COEFF_8*/ ++ { 0x00006E38, 8, 5 }, /*GAIN_ERR_COEFF_9*/ ++ { 0x00006E38, 16, 5 }, /*GAIN_ERR_COEFF_10*/ ++ { 0x00006E38, 24, 5 }, /*GAIN_ERR_COEFF_11*/ ++ { 0x00006E3C, 0, 5 }, /*GAIN_ERR_COEFF_12*/ ++ { 0x00006E3C, 8, 5 }, /*GAIN_ERR_COEFF_13*/ ++ { 0x00006E3C, 16, 5 }, /*GAIN_ERR_COEFF_14*/ ++ { 0x00006E3C, 24, 5 }, /*GAIN_ERR_COEFF_15*/ ++ { 0x00006E40, 0, 5 }, /*GAIN_ERR_COEFF_16*/ ++ { 0x00006E40, 8, 5 }, /*GAIN_ERR_COEFF_17*/ ++ { 0x00006E40, 16, 5 }, /*GAIN_ERR_COEFF_18*/ ++ { 0x00006E40, 24, 5 }, /*GAIN_ERR_COEFF_19*/ ++ { 0x00006E44, 0, 5 }, /*GAIN_ERR_COEFF_20*/ ++ { 0x00006E48, 0, 10 }, /*VOFF_GAIN_0*/ ++ { 0x00006E48, 10, 10 }, /*VOFF_GAIN_1*/ ++ { 0x00006E48, 20, 10 }, /*VOFF_GAIN_2*/ ++ { 0x00006E4C, 0, 10 }, /*VOFF_GAIN_3*/ ++ { 0x00006E4C, 10, 10 }, /*VOFF_GAIN_4*/ ++ { 0x00006E4C, 20, 10 }, /*VOFF_GAIN_5*/ ++ { 0x00006E50, 0, 10 }, /*VOFF_GAIN_6*/ ++ { 0x00006E50, 10, 10 }, /*VOFF_GAIN_7*/ ++ { 0x00006E50, 20, 10 }, /*VOFF_GAIN_8*/ ++ { 0x00006E54, 0, 10 }, /*VOFF_GAIN_9*/ ++ { 0x00006E54, 10, 10 }, /*VOFF_GAIN_10*/ ++ { 0x00006E54, 20, 10 }, /*VOFF_GAIN_11*/ ++ { 0x00006E58, 0, 10 }, /*VOFF_GAIN_12*/ ++ { 0x00006E58, 10, 10 }, /*VOFF_GAIN_13*/ ++ { 0x00006E58, 20, 10 }, /*VOFF_GAIN_14*/ ++ { 0x00006E5C, 0, 10 }, /*VOFF_GAIN_15*/ ++ { 0x00006E5C, 10, 10 }, /*VOFF_GAIN_16*/ ++ { 0x00006E5C, 20, 10 }, /*VOFF_GAIN_17*/ ++ { 0x00006E60, 0, 10 }, /*VOFF_GAIN_18*/ ++ { 0x00006E60, 10, 10 }, /*VOFF_GAIN_19*/ ++ { 0x00006E60, 20, 10 }, /*VOFF_GAIN_20*/ ++ { 0x00006E64, 0, 10 }, /*VOFF_INT1*/ ++ { 0x00007418, 7, 5 }, /*DS_SPK_INT1_CAP_TRIM*/ ++ { 0x0000741C, 0, 5 }, /*DS_SPK_INT2_CAP_TRIM*/ ++ { 0x0000741C, 11, 4 }, /*DS_SPK_LPF_CAP_TRIM*/ ++ { 0x0000741C, 19, 4 }, /*DS_SPK_QUAN_CAP_TRIM*/ ++ { 0x00007434, 17, 1 }, /*FORCE_CAL*/ ++ { 0x00007434, 18, 7 }, /*CAL_OVERRIDE*/ ++ { 0x00007068, 0, 9 }, /*MODIX*/ ++ { 0x0000410C, 7, 1 }, /*VIMON_DLY_NOT_COMB*/ ++ { 0x0000400C, 0, 7 }, /*VIMON_DLY*/ ++ { 0x00000000, 0, 1 }, /*extra bit*/ ++ { 0x00017040, 0, 8 }, /*X_COORDINATE*/ ++ { 0x00017040, 8, 8 }, /*Y_COORDINATE*/ ++ { 0x00017040, 16, 8 }, /*WAFER_ID*/ ++ { 0x00017040, 24, 8 }, /*DVS*/ ++ { 0x00017044, 0, 24 }, /*LOT_NUMBER*/ + }; + +-static const struct cs35l41_otp_packed_element_t +- otp_map_2[CS35L41_NUM_OTP_ELEM] = { ++static const struct cs35l41_otp_packed_element_t otp_map_2[CS35L41_NUM_OTP_ELEM] = { + /* addr shift size */ +- {0x00002030, 0, 4}, /*TRIM_OSC_FREQ_TRIM*/ +- {0x00002030, 7, 1}, /*TRIM_OSC_TRIM_DONE*/ +- {0x0000208c, 24, 6}, /*TST_DIGREG_VREF_TRIM*/ +- {0x00002090, 14, 4}, /*TST_REF_TRIM*/ +- {0x00002090, 10, 4}, /*TST_REF_TEMPCO_TRIM*/ +- {0x0000300C, 11, 4}, /*PLL_LDOA_TST_VREF_TRIM*/ +- {0x0000394C, 23, 2}, /*BST_ATEST_CM_VOFF*/ +- {0x00003950, 0, 7}, /*BST_ATRIM_IADC_OFFSET*/ +- {0x00003950, 8, 7}, /*BST_ATRIM_IADC_GAIN1*/ +- {0x00003950, 16, 8}, /*BST_ATRIM_IPKCOMP_OFFSET1*/ +- {0x00003950, 24, 8}, /*BST_ATRIM_IPKCOMP_GAIN1*/ +- {0x00003954, 0, 7}, /*BST_ATRIM_IADC_OFFSET2*/ +- {0x00003954, 8, 7}, /*BST_ATRIM_IADC_GAIN2*/ +- {0x00003954, 16, 8}, /*BST_ATRIM_IPKCOMP_OFFSET2*/ +- {0x00003954, 24, 8}, /*BST_ATRIM_IPKCOMP_GAIN2*/ +- {0x00003958, 0, 7}, /*BST_ATRIM_IADC_OFFSET3*/ +- {0x00003958, 8, 7}, /*BST_ATRIM_IADC_GAIN3*/ +- {0x00003958, 16, 8}, /*BST_ATRIM_IPKCOMP_OFFSET3*/ +- {0x00003958, 24, 8}, /*BST_ATRIM_IPKCOMP_GAIN3*/ +- {0x0000395C, 0, 7}, /*BST_ATRIM_IADC_OFFSET4*/ +- {0x0000395C, 8, 7}, /*BST_ATRIM_IADC_GAIN4*/ +- {0x0000395C, 16, 8}, /*BST_ATRIM_IPKCOMP_OFFSET4*/ +- {0x0000395C, 24, 8}, /*BST_ATRIM_IPKCOMP_GAIN4*/ +- {0x0000416C, 0, 8}, /*VMON_GAIN_OTP_VAL*/ +- {0x00004160, 0, 7}, /*VMON_OFFSET_OTP_VAL*/ +- {0x0000416C, 8, 8}, /*IMON_GAIN_OTP_VAL*/ +- {0x00004160, 16, 10}, /*IMON_OFFSET_OTP_VAL*/ +- {0x0000416C, 16, 12}, /*VMON_CM_GAIN_OTP_VAL*/ +- {0x0000416C, 28, 1}, /*VMON_CM_GAIN_SIGN_OTP_VAL*/ +- {0x00004170, 0, 6}, /*IMON_CAL_TEMPCO_OTP_VAL*/ +- {0x00004170, 6, 1}, /*IMON_CAL_TEMPCO_SIGN_OTP*/ +- {0x00004170, 8, 6}, /*IMON_CAL_TEMPCO2_OTP_VAL*/ +- {0x00004170, 14, 1}, /*IMON_CAL_TEMPCO2_DN_UPB_OTP_VAL*/ +- {0x00004170, 16, 9}, /*IMON_CAL_TEMPCO_TBASE_OTP_VAL*/ +- {0x00004360, 0, 5}, /*TEMP_GAIN_OTP_VAL*/ +- {0x00004360, 6, 9}, /*TEMP_OFFSET_OTP_VAL*/ +- {0x00004448, 0, 8}, /*VP_SARADC_OFFSET*/ +- {0x00004448, 8, 8}, /*VP_GAIN_INDEX*/ +- {0x00004448, 16, 8}, /*VBST_SARADC_OFFSET*/ +- {0x00004448, 24, 8}, /*VBST_GAIN_INDEX*/ +- {0x0000444C, 0, 3}, /*ANA_SELINVREF*/ +- {0x00006E30, 0, 5}, /*GAIN_ERR_COEFF_0*/ +- {0x00006E30, 8, 5}, /*GAIN_ERR_COEFF_1*/ +- {0x00006E30, 16, 5}, /*GAIN_ERR_COEFF_2*/ +- {0x00006E30, 24, 5}, /*GAIN_ERR_COEFF_3*/ +- {0x00006E34, 0, 5}, /*GAIN_ERR_COEFF_4*/ +- {0x00006E34, 8, 5}, /*GAIN_ERR_COEFF_5*/ +- {0x00006E34, 16, 5}, /*GAIN_ERR_COEFF_6*/ +- {0x00006E34, 24, 5}, /*GAIN_ERR_COEFF_7*/ +- {0x00006E38, 0, 5}, /*GAIN_ERR_COEFF_8*/ +- {0x00006E38, 8, 5}, /*GAIN_ERR_COEFF_9*/ +- {0x00006E38, 16, 5}, /*GAIN_ERR_COEFF_10*/ +- {0x00006E38, 24, 5}, /*GAIN_ERR_COEFF_11*/ +- {0x00006E3C, 0, 5}, /*GAIN_ERR_COEFF_12*/ +- {0x00006E3C, 8, 5}, /*GAIN_ERR_COEFF_13*/ +- {0x00006E3C, 16, 5}, /*GAIN_ERR_COEFF_14*/ +- {0x00006E3C, 24, 5}, /*GAIN_ERR_COEFF_15*/ +- {0x00006E40, 0, 5}, /*GAIN_ERR_COEFF_16*/ +- {0x00006E40, 8, 5}, /*GAIN_ERR_COEFF_17*/ +- {0x00006E40, 16, 5}, /*GAIN_ERR_COEFF_18*/ +- {0x00006E40, 24, 5}, /*GAIN_ERR_COEFF_19*/ +- {0x00006E44, 0, 5}, /*GAIN_ERR_COEFF_20*/ +- {0x00006E48, 0, 10}, /*VOFF_GAIN_0*/ +- {0x00006E48, 10, 10}, /*VOFF_GAIN_1*/ +- {0x00006E48, 20, 10}, /*VOFF_GAIN_2*/ +- {0x00006E4C, 0, 10}, /*VOFF_GAIN_3*/ +- {0x00006E4C, 10, 10}, /*VOFF_GAIN_4*/ +- {0x00006E4C, 20, 10}, /*VOFF_GAIN_5*/ +- {0x00006E50, 0, 10}, /*VOFF_GAIN_6*/ +- {0x00006E50, 10, 10}, /*VOFF_GAIN_7*/ +- {0x00006E50, 20, 10}, /*VOFF_GAIN_8*/ +- {0x00006E54, 0, 10}, /*VOFF_GAIN_9*/ +- {0x00006E54, 10, 10}, /*VOFF_GAIN_10*/ +- {0x00006E54, 20, 10}, /*VOFF_GAIN_11*/ +- {0x00006E58, 0, 10}, /*VOFF_GAIN_12*/ +- {0x00006E58, 10, 10}, /*VOFF_GAIN_13*/ +- {0x00006E58, 20, 10}, /*VOFF_GAIN_14*/ +- {0x00006E5C, 0, 10}, /*VOFF_GAIN_15*/ +- {0x00006E5C, 10, 10}, /*VOFF_GAIN_16*/ +- {0x00006E5C, 20, 10}, /*VOFF_GAIN_17*/ +- {0x00006E60, 0, 10}, /*VOFF_GAIN_18*/ +- {0x00006E60, 10, 10}, /*VOFF_GAIN_19*/ +- {0x00006E60, 20, 10}, /*VOFF_GAIN_20*/ +- {0x00006E64, 0, 10}, /*VOFF_INT1*/ +- {0x00007418, 7, 5}, /*DS_SPK_INT1_CAP_TRIM*/ +- {0x0000741C, 0, 5}, /*DS_SPK_INT2_CAP_TRIM*/ +- {0x0000741C, 11, 4}, /*DS_SPK_LPF_CAP_TRIM*/ +- {0x0000741C, 19, 4}, /*DS_SPK_QUAN_CAP_TRIM*/ +- {0x00007434, 17, 1}, /*FORCE_CAL*/ +- {0x00007434, 18, 7}, /*CAL_OVERRIDE*/ +- {0x00007068, 0, 9}, /*MODIX*/ +- {0x0000410C, 7, 1}, /*VIMON_DLY_NOT_COMB*/ +- {0x0000400C, 0, 7}, /*VIMON_DLY*/ +- {0x00004000, 11, 1}, /*VMON_POL*/ +- {0x00017040, 0, 8}, /*X_COORDINATE*/ +- {0x00017040, 8, 8}, /*Y_COORDINATE*/ +- {0x00017040, 16, 8}, /*WAFER_ID*/ +- {0x00017040, 24, 8}, /*DVS*/ +- {0x00017044, 0, 24}, /*LOT_NUMBER*/ ++ { 0x00002030, 0, 4 }, /*TRIM_OSC_FREQ_TRIM*/ ++ { 0x00002030, 7, 1 }, /*TRIM_OSC_TRIM_DONE*/ ++ { 0x0000208c, 24, 6 }, /*TST_DIGREG_VREF_TRIM*/ ++ { 0x00002090, 14, 4 }, /*TST_REF_TRIM*/ ++ { 0x00002090, 10, 4 }, /*TST_REF_TEMPCO_TRIM*/ ++ { 0x0000300C, 11, 4 }, /*PLL_LDOA_TST_VREF_TRIM*/ ++ { 0x0000394C, 23, 2 }, /*BST_ATEST_CM_VOFF*/ ++ { 0x00003950, 0, 7 }, /*BST_ATRIM_IADC_OFFSET*/ ++ { 0x00003950, 8, 7 }, /*BST_ATRIM_IADC_GAIN1*/ ++ { 0x00003950, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET1*/ ++ { 0x00003950, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN1*/ ++ { 0x00003954, 0, 7 }, /*BST_ATRIM_IADC_OFFSET2*/ ++ { 0x00003954, 8, 7 }, /*BST_ATRIM_IADC_GAIN2*/ ++ { 0x00003954, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET2*/ ++ { 0x00003954, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN2*/ ++ { 0x00003958, 0, 7 }, /*BST_ATRIM_IADC_OFFSET3*/ ++ { 0x00003958, 8, 7 }, /*BST_ATRIM_IADC_GAIN3*/ ++ { 0x00003958, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET3*/ ++ { 0x00003958, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN3*/ ++ { 0x0000395C, 0, 7 }, /*BST_ATRIM_IADC_OFFSET4*/ ++ { 0x0000395C, 8, 7 }, /*BST_ATRIM_IADC_GAIN4*/ ++ { 0x0000395C, 16, 8 }, /*BST_ATRIM_IPKCOMP_OFFSET4*/ ++ { 0x0000395C, 24, 8 }, /*BST_ATRIM_IPKCOMP_GAIN4*/ ++ { 0x0000416C, 0, 8 }, /*VMON_GAIN_OTP_VAL*/ ++ { 0x00004160, 0, 7 }, /*VMON_OFFSET_OTP_VAL*/ ++ { 0x0000416C, 8, 8 }, /*IMON_GAIN_OTP_VAL*/ ++ { 0x00004160, 16, 10 }, /*IMON_OFFSET_OTP_VAL*/ ++ { 0x0000416C, 16, 12 }, /*VMON_CM_GAIN_OTP_VAL*/ ++ { 0x0000416C, 28, 1 }, /*VMON_CM_GAIN_SIGN_OTP_VAL*/ ++ { 0x00004170, 0, 6 }, /*IMON_CAL_TEMPCO_OTP_VAL*/ ++ { 0x00004170, 6, 1 }, /*IMON_CAL_TEMPCO_SIGN_OTP*/ ++ { 0x00004170, 8, 6 }, /*IMON_CAL_TEMPCO2_OTP_VAL*/ ++ { 0x00004170, 14, 1 }, /*IMON_CAL_TEMPCO2_DN_UPB_OTP_VAL*/ ++ { 0x00004170, 16, 9 }, /*IMON_CAL_TEMPCO_TBASE_OTP_VAL*/ ++ { 0x00004360, 0, 5 }, /*TEMP_GAIN_OTP_VAL*/ ++ { 0x00004360, 6, 9 }, /*TEMP_OFFSET_OTP_VAL*/ ++ { 0x00004448, 0, 8 }, /*VP_SARADC_OFFSET*/ ++ { 0x00004448, 8, 8 }, /*VP_GAIN_INDEX*/ ++ { 0x00004448, 16, 8 }, /*VBST_SARADC_OFFSET*/ ++ { 0x00004448, 24, 8 }, /*VBST_GAIN_INDEX*/ ++ { 0x0000444C, 0, 3 }, /*ANA_SELINVREF*/ ++ { 0x00006E30, 0, 5 }, /*GAIN_ERR_COEFF_0*/ ++ { 0x00006E30, 8, 5 }, /*GAIN_ERR_COEFF_1*/ ++ { 0x00006E30, 16, 5 }, /*GAIN_ERR_COEFF_2*/ ++ { 0x00006E30, 24, 5 }, /*GAIN_ERR_COEFF_3*/ ++ { 0x00006E34, 0, 5 }, /*GAIN_ERR_COEFF_4*/ ++ { 0x00006E34, 8, 5 }, /*GAIN_ERR_COEFF_5*/ ++ { 0x00006E34, 16, 5 }, /*GAIN_ERR_COEFF_6*/ ++ { 0x00006E34, 24, 5 }, /*GAIN_ERR_COEFF_7*/ ++ { 0x00006E38, 0, 5 }, /*GAIN_ERR_COEFF_8*/ ++ { 0x00006E38, 8, 5 }, /*GAIN_ERR_COEFF_9*/ ++ { 0x00006E38, 16, 5 }, /*GAIN_ERR_COEFF_10*/ ++ { 0x00006E38, 24, 5 }, /*GAIN_ERR_COEFF_11*/ ++ { 0x00006E3C, 0, 5 }, /*GAIN_ERR_COEFF_12*/ ++ { 0x00006E3C, 8, 5 }, /*GAIN_ERR_COEFF_13*/ ++ { 0x00006E3C, 16, 5 }, /*GAIN_ERR_COEFF_14*/ ++ { 0x00006E3C, 24, 5 }, /*GAIN_ERR_COEFF_15*/ ++ { 0x00006E40, 0, 5 }, /*GAIN_ERR_COEFF_16*/ ++ { 0x00006E40, 8, 5 }, /*GAIN_ERR_COEFF_17*/ ++ { 0x00006E40, 16, 5 }, /*GAIN_ERR_COEFF_18*/ ++ { 0x00006E40, 24, 5 }, /*GAIN_ERR_COEFF_19*/ ++ { 0x00006E44, 0, 5 }, /*GAIN_ERR_COEFF_20*/ ++ { 0x00006E48, 0, 10 }, /*VOFF_GAIN_0*/ ++ { 0x00006E48, 10, 10 }, /*VOFF_GAIN_1*/ ++ { 0x00006E48, 20, 10 }, /*VOFF_GAIN_2*/ ++ { 0x00006E4C, 0, 10 }, /*VOFF_GAIN_3*/ ++ { 0x00006E4C, 10, 10 }, /*VOFF_GAIN_4*/ ++ { 0x00006E4C, 20, 10 }, /*VOFF_GAIN_5*/ ++ { 0x00006E50, 0, 10 }, /*VOFF_GAIN_6*/ ++ { 0x00006E50, 10, 10 }, /*VOFF_GAIN_7*/ ++ { 0x00006E50, 20, 10 }, /*VOFF_GAIN_8*/ ++ { 0x00006E54, 0, 10 }, /*VOFF_GAIN_9*/ ++ { 0x00006E54, 10, 10 }, /*VOFF_GAIN_10*/ ++ { 0x00006E54, 20, 10 }, /*VOFF_GAIN_11*/ ++ { 0x00006E58, 0, 10 }, /*VOFF_GAIN_12*/ ++ { 0x00006E58, 10, 10 }, /*VOFF_GAIN_13*/ ++ { 0x00006E58, 20, 10 }, /*VOFF_GAIN_14*/ ++ { 0x00006E5C, 0, 10 }, /*VOFF_GAIN_15*/ ++ { 0x00006E5C, 10, 10 }, /*VOFF_GAIN_16*/ ++ { 0x00006E5C, 20, 10 }, /*VOFF_GAIN_17*/ ++ { 0x00006E60, 0, 10 }, /*VOFF_GAIN_18*/ ++ { 0x00006E60, 10, 10 }, /*VOFF_GAIN_19*/ ++ { 0x00006E60, 20, 10 }, /*VOFF_GAIN_20*/ ++ { 0x00006E64, 0, 10 }, /*VOFF_INT1*/ ++ { 0x00007418, 7, 5 }, /*DS_SPK_INT1_CAP_TRIM*/ ++ { 0x0000741C, 0, 5 }, /*DS_SPK_INT2_CAP_TRIM*/ ++ { 0x0000741C, 11, 4 }, /*DS_SPK_LPF_CAP_TRIM*/ ++ { 0x0000741C, 19, 4 }, /*DS_SPK_QUAN_CAP_TRIM*/ ++ { 0x00007434, 17, 1 }, /*FORCE_CAL*/ ++ { 0x00007434, 18, 7 }, /*CAL_OVERRIDE*/ ++ { 0x00007068, 0, 9 }, /*MODIX*/ ++ { 0x0000410C, 7, 1 }, /*VIMON_DLY_NOT_COMB*/ ++ { 0x0000400C, 0, 7 }, /*VIMON_DLY*/ ++ { 0x00004000, 11, 1 }, /*VMON_POL*/ ++ { 0x00017040, 0, 8 }, /*X_COORDINATE*/ ++ { 0x00017040, 8, 8 }, /*Y_COORDINATE*/ ++ { 0x00017040, 16, 8 }, /*WAFER_ID*/ ++ { 0x00017040, 24, 8 }, /*DVS*/ ++ { 0x00017044, 0, 24 }, /*LOT_NUMBER*/ + }; + +-const struct cs35l41_otp_map_element_t +- cs35l41_otp_map_map[CS35L41_NUM_OTP_MAPS] = { ++const struct cs35l41_otp_map_element_t cs35l41_otp_map_map[CS35L41_NUM_OTP_MAPS] = { + { + .id = 0x01, + .map = otp_map_1, +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index cc158fe4b7fe..ad86c030d9cb 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -166,7 +166,8 @@ static const unsigned char cs35l41_bst_k2_table[4][5] = { + }; + + static const unsigned char cs35l41_bst_slope_table[4] = { +- 0x75, 0x6B, 0x3B, 0x28}; ++ 0x75, 0x6B, 0x3B, 0x28 ++}; + + static int cs35l41_get_fs_mon_config_index(int freq) + { +@@ -189,7 +190,8 @@ static const struct snd_kcontrol_new dre_ctrl = + SOC_DAPM_SINGLE("Switch", CS35L41_PWR_CTRL3, 20, 1, 0); + + static const char * const cs35l41_pcm_sftramp_text[] = { +- "Off", ".5ms", "1ms", "2ms", "4ms", "8ms", "15ms", "30ms"}; ++ "Off", ".5ms", "1ms", "2ms", "4ms", "8ms", "15ms", "30ms" ++}; + + static SOC_ENUM_SINGLE_DECL(pcm_sft_ramp, + CS35L41_AMP_DIG_VOL_CTRL, 0, +@@ -198,92 +200,88 @@ static SOC_ENUM_SINGLE_DECL(pcm_sft_ramp, + static const char * const cs35l41_pcm_source_texts[] = {"ASP", "DSP"}; + static const unsigned int cs35l41_pcm_source_values[] = {0x08, 0x32}; + static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_pcm_source_enum, +- CS35L41_DAC_PCM1_SRC, +- 0, CS35L41_ASP_SOURCE_MASK, +- cs35l41_pcm_source_texts, +- cs35l41_pcm_source_values); ++ CS35L41_DAC_PCM1_SRC, ++ 0, CS35L41_ASP_SOURCE_MASK, ++ cs35l41_pcm_source_texts, ++ cs35l41_pcm_source_values); + + static const struct snd_kcontrol_new pcm_source_mux = + SOC_DAPM_ENUM("PCM Source", cs35l41_pcm_source_enum); + +-static const char * const cs35l41_tx_input_texts[] = {"Zero", "ASPRX1", +- "ASPRX2", "VMON", +- "IMON", "VPMON", +- "VBSTMON", +- "DSPTX1", "DSPTX2"}; +-static const unsigned int cs35l41_tx_input_values[] = {0x00, +- CS35L41_INPUT_SRC_ASPRX1, +- CS35L41_INPUT_SRC_ASPRX2, +- CS35L41_INPUT_SRC_VMON, +- CS35L41_INPUT_SRC_IMON, +- CS35L41_INPUT_SRC_VPMON, +- CS35L41_INPUT_SRC_VBSTMON, +- CS35L41_INPUT_DSP_TX1, +- CS35L41_INPUT_DSP_TX2}; ++static const char * const cs35l41_tx_input_texts[] = { ++ "Zero", "ASPRX1", "ASPRX2", "VMON", "IMON", ++ "VPMON", "VBSTMON", "DSPTX1", "DSPTX2" ++}; ++ ++static const unsigned int cs35l41_tx_input_values[] = { ++ 0x00, CS35L41_INPUT_SRC_ASPRX1, CS35L41_INPUT_SRC_ASPRX2, ++ CS35L41_INPUT_SRC_VMON, CS35L41_INPUT_SRC_IMON, CS35L41_INPUT_SRC_VPMON, ++ CS35L41_INPUT_SRC_VBSTMON, CS35L41_INPUT_DSP_TX1, CS35L41_INPUT_DSP_TX2 ++}; + + static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx1_enum, +- CS35L41_ASP_TX1_SRC, +- 0, CS35L41_ASP_SOURCE_MASK, +- cs35l41_tx_input_texts, +- cs35l41_tx_input_values); ++ CS35L41_ASP_TX1_SRC, ++ 0, CS35L41_ASP_SOURCE_MASK, ++ cs35l41_tx_input_texts, ++ cs35l41_tx_input_values); + + static const struct snd_kcontrol_new asp_tx1_mux = + SOC_DAPM_ENUM("ASPTX1 SRC", cs35l41_asptx1_enum); + + static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx2_enum, +- CS35L41_ASP_TX2_SRC, +- 0, CS35L41_ASP_SOURCE_MASK, +- cs35l41_tx_input_texts, +- cs35l41_tx_input_values); ++ CS35L41_ASP_TX2_SRC, ++ 0, CS35L41_ASP_SOURCE_MASK, ++ cs35l41_tx_input_texts, ++ cs35l41_tx_input_values); + + static const struct snd_kcontrol_new asp_tx2_mux = + SOC_DAPM_ENUM("ASPTX2 SRC", cs35l41_asptx2_enum); + + static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx3_enum, +- CS35L41_ASP_TX3_SRC, +- 0, CS35L41_ASP_SOURCE_MASK, +- cs35l41_tx_input_texts, +- cs35l41_tx_input_values); ++ CS35L41_ASP_TX3_SRC, ++ 0, CS35L41_ASP_SOURCE_MASK, ++ cs35l41_tx_input_texts, ++ cs35l41_tx_input_values); + + static const struct snd_kcontrol_new asp_tx3_mux = + SOC_DAPM_ENUM("ASPTX3 SRC", cs35l41_asptx3_enum); + + static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx4_enum, +- CS35L41_ASP_TX4_SRC, +- 0, CS35L41_ASP_SOURCE_MASK, +- cs35l41_tx_input_texts, +- cs35l41_tx_input_values); ++ CS35L41_ASP_TX4_SRC, ++ 0, CS35L41_ASP_SOURCE_MASK, ++ cs35l41_tx_input_texts, ++ cs35l41_tx_input_values); + + static const struct snd_kcontrol_new asp_tx4_mux = + SOC_DAPM_ENUM("ASPTX4 SRC", cs35l41_asptx4_enum); + + static const struct snd_kcontrol_new cs35l41_aud_controls[] = { + SOC_SINGLE_SX_TLV("Digital PCM Volume", CS35L41_AMP_DIG_VOL_CTRL, +- 3, 0x4CF, 0x391, dig_vol_tlv), ++ 3, 0x4CF, 0x391, dig_vol_tlv), + SOC_SINGLE_TLV("Analog PCM Volume", CS35L41_AMP_GAIN_CTRL, 5, 0x14, 0, +- amp_gain_tlv), ++ amp_gain_tlv), + SOC_ENUM("PCM Soft Ramp", pcm_sft_ramp), + SOC_SINGLE("HW Noise Gate Enable", CS35L41_NG_CFG, 8, 63, 0), + SOC_SINGLE("HW Noise Gate Delay", CS35L41_NG_CFG, 4, 7, 0), + SOC_SINGLE("HW Noise Gate Threshold", CS35L41_NG_CFG, 0, 7, 0), + SOC_SINGLE("Aux Noise Gate CH1 Enable", +- CS35L41_MIXER_NGATE_CH1_CFG, 16, 1, 0), ++ CS35L41_MIXER_NGATE_CH1_CFG, 16, 1, 0), + SOC_SINGLE("Aux Noise Gate CH1 Entry Delay", +- CS35L41_MIXER_NGATE_CH1_CFG, 8, 15, 0), ++ CS35L41_MIXER_NGATE_CH1_CFG, 8, 15, 0), + SOC_SINGLE("Aux Noise Gate CH1 Threshold", +- CS35L41_MIXER_NGATE_CH1_CFG, 0, 7, 0), ++ CS35L41_MIXER_NGATE_CH1_CFG, 0, 7, 0), + SOC_SINGLE("Aux Noise Gate CH2 Entry Delay", +- CS35L41_MIXER_NGATE_CH2_CFG, 8, 15, 0), ++ CS35L41_MIXER_NGATE_CH2_CFG, 8, 15, 0), + SOC_SINGLE("Aux Noise Gate CH2 Enable", +- CS35L41_MIXER_NGATE_CH2_CFG, 16, 1, 0), ++ CS35L41_MIXER_NGATE_CH2_CFG, 16, 1, 0), + SOC_SINGLE("Aux Noise Gate CH2 Threshold", +- CS35L41_MIXER_NGATE_CH2_CFG, 0, 7, 0), ++ CS35L41_MIXER_NGATE_CH2_CFG, 0, 7, 0), + SOC_SINGLE("SCLK Force", CS35L41_SP_FORMAT, CS35L41_SCLK_FRC_SHIFT, 1, 0), + SOC_SINGLE("LRCLK Force", CS35L41_SP_FORMAT, CS35L41_LRCLK_FRC_SHIFT, 1, 0), + SOC_SINGLE("Invert Class D", CS35L41_AMP_DIG_VOL_CTRL, +- CS35L41_AMP_INV_PCM_SHIFT, 1, 0), ++ CS35L41_AMP_INV_PCM_SHIFT, 1, 0), + SOC_SINGLE("Amp Gain ZC", CS35L41_AMP_GAIN_CTRL, +- CS35L41_AMP_GAIN_ZC_SHIFT, 1, 0), ++ CS35L41_AMP_GAIN_ZC_SHIFT, 1, 0), + }; + + static const struct cs35l41_otp_map_element_t *cs35l41_find_otp_map(u32 otp_id) +@@ -309,8 +307,7 @@ static int cs35l41_otp_unpack(void *data) + u32 otp_val, otp_id_reg; + u32 *otp_mem; + +- otp_mem = kmalloc_array(CS35L41_OTP_SIZE_WORDS, sizeof(*otp_mem), +- GFP_KERNEL); ++ otp_mem = kmalloc_array(CS35L41_OTP_SIZE_WORDS, sizeof(*otp_mem), GFP_KERNEL); + if (!otp_mem) + return -ENOMEM; + +@@ -324,7 +321,7 @@ static int cs35l41_otp_unpack(void *data) + + if (!otp_map_match) { + dev_err(cs35l41->dev, "OTP Map matching ID %d not found\n", +- otp_id_reg); ++ otp_id_reg); + ret = -EINVAL; + goto err_otp_unpack; + } +@@ -333,7 +330,7 @@ static int cs35l41_otp_unpack(void *data) + cs35l41->otp_setup(cs35l41, true, &orig_spi_freq); + + ret = regmap_bulk_read(cs35l41->regmap, CS35L41_OTP_MEM0, otp_mem, +- CS35L41_OTP_SIZE_WORDS); ++ CS35L41_OTP_SIZE_WORDS); + if (ret < 0) { + dev_err(cs35l41->dev, "Read OTP Mem failed: %d\n", ret); + goto err_otp_unpack; +@@ -360,8 +357,8 @@ static int cs35l41_otp_unpack(void *data) + + for (i = 0; i < otp_map_match->num_elements; i++) { + dev_dbg(cs35l41->dev, +- "bitoffset= %d, word_offset=%d, bit_sum mod 32=%d\n", +- bit_offset, word_offset, bit_sum % 32); ++ "bitoffset= %d, word_offset=%d, bit_sum mod 32=%d\n", ++ bit_offset, word_offset, bit_sum % 32); + if (bit_offset + otp_map[i].size - 1 >= 32) { + otp_val = (otp_mem[word_offset] & + GENMASK(31, bit_offset)) >> +@@ -372,7 +369,6 @@ static int cs35l41_otp_unpack(void *data) + (32 - bit_offset); + bit_offset += otp_map[i].size - 32; + } else { +- + otp_val = (otp_mem[word_offset] & + GENMASK(bit_offset + otp_map[i].size - 1, + bit_offset)) >> bit_offset; +@@ -387,13 +383,14 @@ static int cs35l41_otp_unpack(void *data) + + if (otp_map[i].reg != 0) { + ret = regmap_update_bits(cs35l41->regmap, +- otp_map[i].reg, +- GENMASK(otp_map[i].shift + +- otp_map[i].size - 1, +- otp_map[i].shift), +- otp_val << otp_map[i].shift); ++ otp_map[i].reg, ++ GENMASK(otp_map[i].shift + ++ otp_map[i].size - 1, ++ otp_map[i].shift), ++ otp_val << otp_map[i].shift); + if (ret < 0) { +- dev_err(cs35l41->dev, "Write OTP val failed: %d\n", ret); ++ dev_err(cs35l41->dev, "Write OTP val failed: %d\n", ++ ret); + goto err_otp_unpack; + } + } +@@ -435,12 +432,12 @@ static irqreturn_t cs35l41_irq(int irq, void *data) + + /* Check to see if unmasked bits are active */ + if (!(status[0] & ~masks[0]) && !(status[1] & ~masks[1]) && +- !(status[2] & ~masks[2]) && !(status[3] & ~masks[3])) ++ !(status[2] & ~masks[2]) && !(status[3] & ~masks[3])) + return IRQ_NONE; + + if (status[3] & CS35L41_OTP_BOOT_DONE) { + regmap_update_bits(cs35l41->regmap, CS35L41_IRQ1_MASK4, +- CS35L41_OTP_BOOT_DONE, CS35L41_OTP_BOOT_DONE); ++ CS35L41_OTP_BOOT_DONE, CS35L41_OTP_BOOT_DONE); + } + + /* +@@ -451,96 +448,93 @@ static irqreturn_t cs35l41_irq(int irq, void *data) + if (status[0] & CS35L41_AMP_SHORT_ERR) { + dev_crit_ratelimited(cs35l41->dev, "Amp short error\n"); + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, +- CS35L41_AMP_SHORT_ERR); ++ CS35L41_AMP_SHORT_ERR); + regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, +- CS35L41_AMP_SHORT_ERR_RLS, +- CS35L41_AMP_SHORT_ERR_RLS); ++ CS35L41_AMP_SHORT_ERR_RLS, ++ CS35L41_AMP_SHORT_ERR_RLS); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, +- CS35L41_AMP_SHORT_ERR_RLS, 0); ++ CS35L41_AMP_SHORT_ERR_RLS, 0); + ret = IRQ_HANDLED; + } + + if (status[0] & CS35L41_TEMP_WARN) { + dev_crit_ratelimited(cs35l41->dev, "Over temperature warning\n"); + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, +- CS35L41_TEMP_WARN); ++ CS35L41_TEMP_WARN); + regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, +- CS35L41_TEMP_WARN_ERR_RLS, +- CS35L41_TEMP_WARN_ERR_RLS); ++ CS35L41_TEMP_WARN_ERR_RLS, ++ CS35L41_TEMP_WARN_ERR_RLS); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, +- CS35L41_TEMP_WARN_ERR_RLS, 0); ++ CS35L41_TEMP_WARN_ERR_RLS, 0); + ret = IRQ_HANDLED; + } + + if (status[0] & CS35L41_TEMP_ERR) { + dev_crit_ratelimited(cs35l41->dev, "Over temperature error\n"); + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, +- CS35L41_TEMP_ERR); ++ CS35L41_TEMP_ERR); + regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, +- CS35L41_TEMP_ERR_RLS, +- CS35L41_TEMP_ERR_RLS); ++ CS35L41_TEMP_ERR_RLS, ++ CS35L41_TEMP_ERR_RLS); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, +- CS35L41_TEMP_ERR_RLS, 0); ++ CS35L41_TEMP_ERR_RLS, 0); + ret = IRQ_HANDLED; + } + + if (status[0] & CS35L41_BST_OVP_ERR) { + dev_crit_ratelimited(cs35l41->dev, "VBST Over Voltage error\n"); + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, +- CS35L41_BST_EN_MASK, 0); ++ CS35L41_BST_EN_MASK, 0); + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, +- CS35L41_BST_OVP_ERR); ++ CS35L41_BST_OVP_ERR); + regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, +- CS35L41_BST_OVP_ERR_RLS, +- CS35L41_BST_OVP_ERR_RLS); ++ CS35L41_BST_OVP_ERR_RLS, ++ CS35L41_BST_OVP_ERR_RLS); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, +- CS35L41_BST_OVP_ERR_RLS, 0); ++ CS35L41_BST_OVP_ERR_RLS, 0); + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, +- CS35L41_BST_EN_MASK, +- CS35L41_BST_EN_DEFAULT << +- CS35L41_BST_EN_SHIFT); ++ CS35L41_BST_EN_MASK, ++ CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT); + ret = IRQ_HANDLED; + } + + if (status[0] & CS35L41_BST_DCM_UVP_ERR) { + dev_crit_ratelimited(cs35l41->dev, "DCM VBST Under Voltage Error\n"); + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, +- CS35L41_BST_EN_MASK, 0); ++ CS35L41_BST_EN_MASK, 0); + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, +- CS35L41_BST_DCM_UVP_ERR); ++ CS35L41_BST_DCM_UVP_ERR); + regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, +- CS35L41_BST_UVP_ERR_RLS, +- CS35L41_BST_UVP_ERR_RLS); ++ CS35L41_BST_UVP_ERR_RLS, ++ CS35L41_BST_UVP_ERR_RLS); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, +- CS35L41_BST_UVP_ERR_RLS, 0); ++ CS35L41_BST_UVP_ERR_RLS, 0); + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, +- CS35L41_BST_EN_MASK, +- CS35L41_BST_EN_DEFAULT << +- CS35L41_BST_EN_SHIFT); ++ CS35L41_BST_EN_MASK, ++ CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT); + ret = IRQ_HANDLED; + } + + if (status[0] & CS35L41_BST_SHORT_ERR) { + dev_crit_ratelimited(cs35l41->dev, "LBST error: powering off!\n"); + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, +- CS35L41_BST_EN_MASK, 0); ++ CS35L41_BST_EN_MASK, 0); + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, +- CS35L41_BST_SHORT_ERR); ++ CS35L41_BST_SHORT_ERR); + regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, +- CS35L41_BST_SHORT_ERR_RLS, +- CS35L41_BST_SHORT_ERR_RLS); ++ CS35L41_BST_SHORT_ERR_RLS, ++ CS35L41_BST_SHORT_ERR_RLS); + regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, +- CS35L41_BST_SHORT_ERR_RLS, 0); ++ CS35L41_BST_SHORT_ERR_RLS, 0); + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, +- CS35L41_BST_EN_MASK, +- CS35L41_BST_EN_DEFAULT << +- CS35L41_BST_EN_SHIFT); ++ CS35L41_BST_EN_MASK, ++ CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT); + ret = IRQ_HANDLED; + } + +@@ -564,12 +558,10 @@ static const struct reg_sequence cs35l41_pdn_patch[] = { + }; + + static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w, +- struct snd_kcontrol *kcontrol, int event) ++ struct snd_kcontrol *kcontrol, int event) + { +- struct snd_soc_component *component = +- snd_soc_dapm_to_component(w->dapm); +- struct cs35l41_private *cs35l41 = +- snd_soc_component_get_drvdata(component); ++ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); ++ struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component); + unsigned int val; + int ret = 0; + bool pdn; +@@ -577,18 +569,18 @@ static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w, + switch (event) { + case SND_SOC_DAPM_POST_PMU: + regmap_multi_reg_write_bypassed(cs35l41->regmap, +- cs35l41_pup_patch, +- ARRAY_SIZE(cs35l41_pup_patch)); ++ cs35l41_pup_patch, ++ ARRAY_SIZE(cs35l41_pup_patch)); + + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL1, +- CS35L41_GLOBAL_EN_MASK, +- 1 << CS35L41_GLOBAL_EN_SHIFT); ++ CS35L41_GLOBAL_EN_MASK, ++ 1 << CS35L41_GLOBAL_EN_SHIFT); + + usleep_range(1000, 1100); + break; + case SND_SOC_DAPM_POST_PMD: + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL1, +- CS35L41_GLOBAL_EN_MASK, 0); ++ CS35L41_GLOBAL_EN_MASK, 0); + + pdn = false; + ret = regmap_read_poll_timeout(cs35l41->regmap, CS35L41_IRQ1_STATUS1, +@@ -598,16 +590,17 @@ static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w, + dev_warn(cs35l41->dev, "PDN failed: %d\n", ret); + + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, +- CS35L41_PDN_DONE_MASK); ++ CS35L41_PDN_DONE_MASK); + + regmap_multi_reg_write_bypassed(cs35l41->regmap, +- cs35l41_pdn_patch, +- ARRAY_SIZE(cs35l41_pdn_patch)); ++ cs35l41_pdn_patch, ++ ARRAY_SIZE(cs35l41_pdn_patch)); + break; + default: + dev_err(cs35l41->dev, "Invalid event = 0x%x\n", event); + ret = -EINVAL; + } ++ + return ret; + } + +@@ -629,8 +622,8 @@ static const struct snd_soc_dapm_widget cs35l41_dapm_widgets[] = { + SND_SOC_DAPM_ADC("CLASS H", NULL, CS35L41_PWR_CTRL3, 4, 0), + + SND_SOC_DAPM_OUT_DRV_E("Main AMP", CS35L41_PWR_CTRL2, 0, 0, NULL, 0, +- cs35l41_main_amp_event, +- SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), ++ cs35l41_main_amp_event, ++ SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), + + SND_SOC_DAPM_INPUT("VP"), + SND_SOC_DAPM_INPUT("VBST"), +@@ -647,7 +640,6 @@ static const struct snd_soc_dapm_widget cs35l41_dapm_widgets[] = { + }; + + static const struct snd_soc_dapm_route cs35l41_audio_map[] = { +- + {"ASP TX1 Source", "VMON", "VMON ADC"}, + {"ASP TX1 Source", "IMON", "IMON ADC"}, + {"ASP TX1 Source", "VPMON", "VPMON ADC"}, +@@ -696,15 +688,13 @@ static const struct snd_soc_dapm_route cs35l41_audio_map[] = { + + {"PCM Source", "ASP", "ASPRX1"}, + {"CLASS H", NULL, "PCM Source"}, +- + }; + + static int cs35l41_set_channel_map(struct snd_soc_dai *dai, unsigned int tx_num, +- unsigned int *tx_slot, unsigned int rx_num, +- unsigned int *rx_slot) ++ unsigned int *tx_slot, unsigned int rx_num, ++ unsigned int *rx_slot) + { +- struct cs35l41_private *cs35l41 = +- snd_soc_component_get_drvdata(dai->component); ++ struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component); + unsigned int val, mask; + int i; + +@@ -732,10 +722,9 @@ static int cs35l41_set_channel_map(struct snd_soc_dai *dai, unsigned int tx_num, + return 0; + } + +-static int cs35l41_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) ++static int cs35l41_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) + { +- struct cs35l41_private *cs35l41 = +- snd_soc_component_get_drvdata(codec_dai->component); ++ struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component); + unsigned int daifmt = 0; + + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { +@@ -808,8 +797,7 @@ static int cs35l41_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) + { +- struct cs35l41_private *cs35l41 = +- snd_soc_component_get_drvdata(dai->component); ++ struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component); + unsigned int rate = params_rate(params); + u8 asp_wl; + int i; +@@ -828,23 +816,23 @@ static int cs35l41_pcm_hw_params(struct snd_pcm_substream *substream, + + if (i < ARRAY_SIZE(cs35l41_fs_rates)) + regmap_update_bits(cs35l41->regmap, CS35L41_GLOBAL_CLK_CTRL, +- CS35L41_GLOBAL_FS_MASK, +- cs35l41_fs_rates[i].fs_cfg << CS35L41_GLOBAL_FS_SHIFT); ++ CS35L41_GLOBAL_FS_MASK, ++ cs35l41_fs_rates[i].fs_cfg << CS35L41_GLOBAL_FS_SHIFT); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, +- CS35L41_ASP_WIDTH_RX_MASK, +- asp_wl << CS35L41_ASP_WIDTH_RX_SHIFT); ++ CS35L41_ASP_WIDTH_RX_MASK, ++ asp_wl << CS35L41_ASP_WIDTH_RX_SHIFT); + regmap_update_bits(cs35l41->regmap, CS35L41_SP_RX_WL, +- CS35L41_ASP_RX_WL_MASK, +- asp_wl << CS35L41_ASP_RX_WL_SHIFT); ++ CS35L41_ASP_RX_WL_MASK, ++ asp_wl << CS35L41_ASP_RX_WL_SHIFT); + } else { + regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT, +- CS35L41_ASP_WIDTH_TX_MASK, +- asp_wl << CS35L41_ASP_WIDTH_TX_SHIFT); ++ CS35L41_ASP_WIDTH_TX_MASK, ++ asp_wl << CS35L41_ASP_WIDTH_TX_SHIFT); + regmap_update_bits(cs35l41->regmap, CS35L41_SP_TX_WL, +- CS35L41_ASP_TX_WL_MASK, +- asp_wl << CS35L41_ASP_TX_WL_SHIFT); ++ CS35L41_ASP_TX_WL_MASK, ++ asp_wl << CS35L41_ASP_TX_WL_SHIFT); + } + + return 0; +@@ -877,16 +865,16 @@ static int cs35l41_pcm_startup(struct snd_pcm_substream *substream, + { + if (substream->runtime) + return snd_pcm_hw_constraint_list(substream->runtime, 0, +- SNDRV_PCM_HW_PARAM_RATE, &cs35l41_constraints); ++ SNDRV_PCM_HW_PARAM_RATE, ++ &cs35l41_constraints); + return 0; + } + + static int cs35l41_component_set_sysclk(struct snd_soc_component *component, +- int clk_id, int source, unsigned int freq, +- int dir) ++ int clk_id, int source, ++ unsigned int freq, int dir) + { +- struct cs35l41_private *cs35l41 = +- snd_soc_component_get_drvdata(component); ++ struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component); + int extclk_cfg, clksrc; + + switch (clk_id) { +@@ -913,47 +901,47 @@ static int cs35l41_component_set_sysclk(struct snd_soc_component *component, + } + + regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, +- CS35L41_PLL_OPENLOOP_MASK, +- 1 << CS35L41_PLL_OPENLOOP_SHIFT); ++ CS35L41_PLL_OPENLOOP_MASK, ++ 1 << CS35L41_PLL_OPENLOOP_SHIFT); + regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, +- CS35L41_REFCLK_FREQ_MASK, +- extclk_cfg << CS35L41_REFCLK_FREQ_SHIFT); ++ CS35L41_REFCLK_FREQ_MASK, ++ extclk_cfg << CS35L41_REFCLK_FREQ_SHIFT); + regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, +- CS35L41_PLL_CLK_EN_MASK, +- 0 << CS35L41_PLL_CLK_EN_SHIFT); ++ CS35L41_PLL_CLK_EN_MASK, ++ 0 << CS35L41_PLL_CLK_EN_SHIFT); + regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, +- CS35L41_PLL_CLK_SEL_MASK, clksrc); ++ CS35L41_PLL_CLK_SEL_MASK, clksrc); + regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, +- CS35L41_PLL_OPENLOOP_MASK, +- 0 << CS35L41_PLL_OPENLOOP_SHIFT); ++ CS35L41_PLL_OPENLOOP_MASK, ++ 0 << CS35L41_PLL_OPENLOOP_SHIFT); + regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL, +- CS35L41_PLL_CLK_EN_MASK, +- 1 << CS35L41_PLL_CLK_EN_SHIFT); ++ CS35L41_PLL_CLK_EN_MASK, ++ 1 << CS35L41_PLL_CLK_EN_SHIFT); + + return 0; + } + + static int cs35l41_dai_set_sysclk(struct snd_soc_dai *dai, +- int clk_id, unsigned int freq, int dir) ++ int clk_id, unsigned int freq, int dir) + { +- struct cs35l41_private *cs35l41 = +- snd_soc_component_get_drvdata(dai->component); ++ struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component); + unsigned int fs1_val; + unsigned int fs2_val; + unsigned int val; +- int fsIndex; ++ int fsindex; + +- fsIndex = cs35l41_get_fs_mon_config_index(freq); +- if (fsIndex < 0) { ++ fsindex = cs35l41_get_fs_mon_config_index(freq); ++ if (fsindex < 0) { + dev_err(cs35l41->dev, "Invalid CLK Config freq: %u\n", freq); + return -EINVAL; + } + + dev_dbg(cs35l41->dev, "Set DAI sysclk %d\n", freq); ++ + if (freq <= 6144000) { + /* Use the lookup table */ +- fs1_val = cs35l41_fs_mon[fsIndex].fs1; +- fs2_val = cs35l41_fs_mon[fsIndex].fs2; ++ fs1_val = cs35l41_fs_mon[fsindex].fs1; ++ fs2_val = cs35l41_fs_mon[fsindex].fs2; + } else { + /* Use hard-coded values */ + fs1_val = 0x10; +@@ -968,7 +956,7 @@ static int cs35l41_dai_set_sysclk(struct snd_soc_dai *dai, + } + + static int cs35l41_boost_config(struct cs35l41_private *cs35l41, +- int boost_ind, int boost_cap, int boost_ipk) ++ int boost_ind, int boost_cap, int boost_ipk) + { + unsigned char bst_lbst_val, bst_cbst_range, bst_ipk_scaled; + struct regmap *regmap = cs35l41->regmap; +@@ -989,8 +977,7 @@ static int cs35l41_boost_config(struct cs35l41_private *cs35l41, + bst_lbst_val = 3; + break; + default: +- dev_err(dev, "Invalid boost inductor value: %d nH\n", +- boost_ind); ++ dev_err(dev, "Invalid boost inductor value: %d nH\n", boost_ind); + return -EINVAL; + } + +@@ -1032,16 +1019,16 @@ static int cs35l41_boost_config(struct cs35l41_private *cs35l41, + return ret; + } + +- if ((boost_ipk < 1600) || (boost_ipk > 4500)) { ++ if (boost_ipk < 1600 || boost_ipk > 4500) { + dev_err(dev, "Invalid boost inductor peak current: %d mA\n", +- boost_ipk); ++ boost_ipk); + return -EINVAL; + } + bst_ipk_scaled = ((boost_ipk - 1600) / 50) + 0x10; + + ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_PEAK_CUR, +- CS35L41_BST_IPK_MASK, +- bst_ipk_scaled << CS35L41_BST_IPK_SHIFT); ++ CS35L41_BST_IPK_MASK, ++ bst_ipk_scaled << CS35L41_BST_IPK_SHIFT); + if (ret) { + dev_err(dev, "Failed to write boost inductor peak current: %d\n", ret); + return ret; +@@ -1059,8 +1046,8 @@ static int cs35l41_set_pdata(struct cs35l41_private *cs35l41) + if (cs35l41->pdata.bst_ipk && + cs35l41->pdata.bst_ind && cs35l41->pdata.bst_cap) { + ret = cs35l41_boost_config(cs35l41, cs35l41->pdata.bst_ind, +- cs35l41->pdata.bst_cap, +- cs35l41->pdata.bst_ipk); ++ cs35l41->pdata.bst_cap, ++ cs35l41->pdata.bst_ipk); + if (ret) { + dev_err(cs35l41->dev, "Error in Boost DT config: %d\n", ret); + return ret; +@@ -1074,8 +1061,8 @@ static int cs35l41_set_pdata(struct cs35l41_private *cs35l41) + if (cs35l41->pdata.dout_hiz <= CS35L41_ASP_DOUT_HIZ_MASK && + cs35l41->pdata.dout_hiz >= 0) + regmap_update_bits(cs35l41->regmap, CS35L41_SP_HIZ_CTRL, +- CS35L41_ASP_DOUT_HIZ_MASK, +- cs35l41->pdata.dout_hiz); ++ CS35L41_ASP_DOUT_HIZ_MASK, ++ cs35l41->pdata.dout_hiz); + + return 0; + } +@@ -1158,8 +1145,8 @@ static const struct snd_soc_component_driver soc_component_dev_cs35l41 = { + }; + + static int cs35l41_handle_pdata(struct device *dev, +- struct cs35l41_platform_data *pdata, +- struct cs35l41_private *cs35l41) ++ struct cs35l41_platform_data *pdata, ++ struct cs35l41_private *cs35l41) + { + struct cs35l41_irq_cfg *irq_gpio1_config = &pdata->irq_config1; + struct cs35l41_irq_cfg *irq_gpio2_config = &pdata->irq_config2; +@@ -1190,11 +1177,9 @@ static int cs35l41_handle_pdata(struct device *dev, + irq_gpio1_config->irq_out_en = device_property_read_bool(dev, + "cirrus,gpio1-output-enable"); + ret = device_property_read_u32(dev, "cirrus,gpio1-src-select", +- &val); +- if (ret >= 0) { +- val |= CS35L41_VALID_PDATA; +- irq_gpio1_config->irq_src_sel = val; +- } ++ &val); ++ if (ret >= 0) ++ irq_gpio1_config->irq_src_sel = val | CS35L41_VALID_PDATA; + + /* GPIO2 Pin Config */ + irq_gpio2_config->irq_pol_inv = device_property_read_bool(dev, +@@ -1202,11 +1187,9 @@ static int cs35l41_handle_pdata(struct device *dev, + irq_gpio2_config->irq_out_en = device_property_read_bool(dev, + "cirrus,gpio2-output-enable"); + ret = device_property_read_u32(dev, "cirrus,gpio2-src-select", +- &val); +- if (ret >= 0) { +- val |= CS35L41_VALID_PDATA; +- irq_gpio2_config->irq_src_sel = val; +- } ++ &val); ++ if (ret >= 0) ++ irq_gpio2_config->irq_src_sel = val | CS35L41_VALID_PDATA; + + return 0; + } +@@ -1257,7 +1240,7 @@ static const struct reg_sequence cs35l41_revb2_errata_patch[] = { + }; + + int cs35l41_probe(struct cs35l41_private *cs35l41, +- struct cs35l41_platform_data *pdata) ++ struct cs35l41_platform_data *pdata) + { + u32 regid, reg_revid, i, mtl_revid, int_status, chipid_match; + int irq_pol = 0; +@@ -1266,8 +1249,7 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, + if (pdata) { + cs35l41->pdata = *pdata; + } else { +- ret = cs35l41_handle_pdata(cs35l41->dev, &cs35l41->pdata, +- cs35l41); ++ ret = cs35l41_handle_pdata(cs35l41->dev, &cs35l41->pdata, cs35l41); + if (ret != 0) + return ret; + } +@@ -1276,24 +1258,21 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, + cs35l41->supplies[i].supply = cs35l41_supplies[i]; + + ret = devm_regulator_bulk_get(cs35l41->dev, CS35L41_NUM_SUPPLIES, +- cs35l41->supplies); ++ cs35l41->supplies); + if (ret != 0) { +- dev_err(cs35l41->dev, +- "Failed to request core supplies: %d\n", +- ret); ++ dev_err(cs35l41->dev, "Failed to request core supplies: %d\n", ret); + return ret; + } + + ret = regulator_bulk_enable(CS35L41_NUM_SUPPLIES, cs35l41->supplies); + if (ret != 0) { +- dev_err(cs35l41->dev, +- "Failed to enable core supplies: %d\n", ret); ++ dev_err(cs35l41->dev, "Failed to enable core supplies: %d\n", ret); + return ret; + } + + /* returning NULL can be an option if in stereo mode */ + cs35l41->reset_gpio = devm_gpiod_get_optional(cs35l41->dev, "reset", +- GPIOD_OUT_LOW); ++ GPIOD_OUT_LOW); + if (IS_ERR(cs35l41->reset_gpio)) { + ret = PTR_ERR(cs35l41->reset_gpio); + cs35l41->reset_gpio = NULL; +@@ -1358,8 +1337,8 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, + switch (reg_revid) { + case CS35L41_REVID_A0: + ret = regmap_register_patch(cs35l41->regmap, +- cs35l41_reva0_errata_patch, +- ARRAY_SIZE(cs35l41_reva0_errata_patch)); ++ cs35l41_reva0_errata_patch, ++ ARRAY_SIZE(cs35l41_reva0_errata_patch)); + if (ret < 0) { + dev_err(cs35l41->dev, + "Failed to apply A0 errata patch: %d\n", ret); +@@ -1368,8 +1347,8 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, + break; + case CS35L41_REVID_B0: + ret = regmap_register_patch(cs35l41->regmap, +- cs35l41_revb0_errata_patch, +- ARRAY_SIZE(cs35l41_revb0_errata_patch)); ++ cs35l41_revb0_errata_patch, ++ ARRAY_SIZE(cs35l41_revb0_errata_patch)); + if (ret < 0) { + dev_err(cs35l41->dev, + "Failed to apply B0 errata patch: %d\n", ret); +@@ -1378,8 +1357,8 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, + break; + case CS35L41_REVID_B2: + ret = regmap_register_patch(cs35l41->regmap, +- cs35l41_revb2_errata_patch, +- ARRAY_SIZE(cs35l41_revb2_errata_patch)); ++ cs35l41_revb2_errata_patch, ++ ARRAY_SIZE(cs35l41_revb2_errata_patch)); + if (ret < 0) { + dev_err(cs35l41->dev, + "Failed to apply B2 errata patch: %d\n", ret); +@@ -1392,11 +1371,11 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, + + /* Set interrupt masks for critical errors */ + regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, +- CS35L41_INT1_MASK_DEFAULT); ++ CS35L41_INT1_MASK_DEFAULT); + +- ret = devm_request_threaded_irq(cs35l41->dev, cs35l41->irq, NULL, +- cs35l41_irq, IRQF_ONESHOT | IRQF_SHARED | irq_pol, +- "cs35l41", cs35l41); ++ ret = devm_request_threaded_irq(cs35l41->dev, cs35l41->irq, NULL, cs35l41_irq, ++ IRQF_ONESHOT | IRQF_SHARED | irq_pol, ++ "cs35l41", cs35l41); + + /* CS35L41 needs INT for PDN_DONE */ + if (ret != 0) { +@@ -1437,21 +1416,22 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, + } + + ret = devm_snd_soc_register_component(cs35l41->dev, +- &soc_component_dev_cs35l41, +- cs35l41_dai, ARRAY_SIZE(cs35l41_dai)); ++ &soc_component_dev_cs35l41, ++ cs35l41_dai, ARRAY_SIZE(cs35l41_dai)); + if (ret < 0) { + dev_err(cs35l41->dev, "Register codec failed: %d\n", ret); + goto err; + } + + dev_info(cs35l41->dev, "Cirrus Logic CS35L41 (%x), Revision: %02X\n", +- regid, reg_revid); ++ regid, reg_revid); + + return 0; + + err: + regulator_bulk_disable(CS35L41_NUM_SUPPLIES, cs35l41->supplies); + gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); ++ + return ret; + } + +@@ -1460,6 +1440,7 @@ int cs35l41_remove(struct cs35l41_private *cs35l41) + regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, 0xFFFFFFFF); + regulator_bulk_disable(CS35L41_NUM_SUPPLIES, cs35l41->supplies); + gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); ++ + return 0; + } + +diff --git a/sound/soc/codecs/cs35l41.h b/sound/soc/codecs/cs35l41.h +index ec1b00b47d5d..0e2639d6ef19 100644 +--- a/sound/soc/codecs/cs35l41.h ++++ b/sound/soc/codecs/cs35l41.h +@@ -498,42 +498,42 @@ + #define CS35L41_DIGPWM_IOCTRL 0x0000706C + + /*registers populated by OTP*/ +-#define CS35L41_OTP_TRIM_1 0x0000208c +-#define CS35L41_OTP_TRIM_2 0x00002090 +-#define CS35L41_OTP_TRIM_3 0x00003010 +-#define CS35L41_OTP_TRIM_4 0x0000300C +-#define CS35L41_OTP_TRIM_5 0x0000394C +-#define CS35L41_OTP_TRIM_6 0x00003950 +-#define CS35L41_OTP_TRIM_7 0x00003954 +-#define CS35L41_OTP_TRIM_8 0x00003958 +-#define CS35L41_OTP_TRIM_9 0x0000395C +-#define CS35L41_OTP_TRIM_10 0x0000416C +-#define CS35L41_OTP_TRIM_11 0x00004160 +-#define CS35L41_OTP_TRIM_12 0x00004170 +-#define CS35L41_OTP_TRIM_13 0x00004360 +-#define CS35L41_OTP_TRIM_14 0x00004448 +-#define CS35L41_OTP_TRIM_15 0x0000444C +-#define CS35L41_OTP_TRIM_16 0x00006E30 +-#define CS35L41_OTP_TRIM_17 0x00006E34 +-#define CS35L41_OTP_TRIM_18 0x00006E38 +-#define CS35L41_OTP_TRIM_19 0x00006E3C +-#define CS35L41_OTP_TRIM_20 0x00006E40 +-#define CS35L41_OTP_TRIM_21 0x00006E44 +-#define CS35L41_OTP_TRIM_22 0x00006E48 +-#define CS35L41_OTP_TRIM_23 0x00006E4C +-#define CS35L41_OTP_TRIM_24 0x00006E50 +-#define CS35L41_OTP_TRIM_25 0x00006E54 +-#define CS35L41_OTP_TRIM_26 0x00006E58 +-#define CS35L41_OTP_TRIM_27 0x00006E5C +-#define CS35L41_OTP_TRIM_28 0x00006E60 +-#define CS35L41_OTP_TRIM_29 0x00006E64 +-#define CS35L41_OTP_TRIM_30 0x00007418 +-#define CS35L41_OTP_TRIM_31 0x0000741C +-#define CS35L41_OTP_TRIM_32 0x00007434 +-#define CS35L41_OTP_TRIM_33 0x00007068 +-#define CS35L41_OTP_TRIM_34 0x0000410C +-#define CS35L41_OTP_TRIM_35 0x0000400C +-#define CS35L41_OTP_TRIM_36 0x00002030 ++#define CS35L41_OTP_TRIM_1 0x0000208c ++#define CS35L41_OTP_TRIM_2 0x00002090 ++#define CS35L41_OTP_TRIM_3 0x00003010 ++#define CS35L41_OTP_TRIM_4 0x0000300C ++#define CS35L41_OTP_TRIM_5 0x0000394C ++#define CS35L41_OTP_TRIM_6 0x00003950 ++#define CS35L41_OTP_TRIM_7 0x00003954 ++#define CS35L41_OTP_TRIM_8 0x00003958 ++#define CS35L41_OTP_TRIM_9 0x0000395C ++#define CS35L41_OTP_TRIM_10 0x0000416C ++#define CS35L41_OTP_TRIM_11 0x00004160 ++#define CS35L41_OTP_TRIM_12 0x00004170 ++#define CS35L41_OTP_TRIM_13 0x00004360 ++#define CS35L41_OTP_TRIM_14 0x00004448 ++#define CS35L41_OTP_TRIM_15 0x0000444C ++#define CS35L41_OTP_TRIM_16 0x00006E30 ++#define CS35L41_OTP_TRIM_17 0x00006E34 ++#define CS35L41_OTP_TRIM_18 0x00006E38 ++#define CS35L41_OTP_TRIM_19 0x00006E3C ++#define CS35L41_OTP_TRIM_20 0x00006E40 ++#define CS35L41_OTP_TRIM_21 0x00006E44 ++#define CS35L41_OTP_TRIM_22 0x00006E48 ++#define CS35L41_OTP_TRIM_23 0x00006E4C ++#define CS35L41_OTP_TRIM_24 0x00006E50 ++#define CS35L41_OTP_TRIM_25 0x00006E54 ++#define CS35L41_OTP_TRIM_26 0x00006E58 ++#define CS35L41_OTP_TRIM_27 0x00006E5C ++#define CS35L41_OTP_TRIM_28 0x00006E60 ++#define CS35L41_OTP_TRIM_29 0x00006E64 ++#define CS35L41_OTP_TRIM_30 0x00007418 ++#define CS35L41_OTP_TRIM_31 0x0000741C ++#define CS35L41_OTP_TRIM_32 0x00007434 ++#define CS35L41_OTP_TRIM_33 0x00007068 ++#define CS35L41_OTP_TRIM_34 0x0000410C ++#define CS35L41_OTP_TRIM_35 0x0000400C ++#define CS35L41_OTP_TRIM_36 0x00002030 + + #define CS35L41_MAX_CACHE_REG 36 + #define CS35L41_OTP_SIZE_WORDS 32 +@@ -691,7 +691,6 @@ + #define CS35L41_TEMP_WARN_ERR_RLS 0x20 + #define CS35L41_TEMP_ERR_RLS 0x40 + +- + #define CS35L41_INT1_MASK_DEFAULT 0x7FFCFE3F + #define CS35L41_INT1_UNMASK_PUP 0xFEFFFFFF + #define CS35L41_INT1_UNMASK_PDN 0xFF7FFFFF +@@ -709,7 +708,7 @@ + #define CS35L41_GPIO_POL_SHIFT 12 + + #define CS35L41_AMP_INV_PCM_SHIFT 14 +-#define CS35L41_AMP_INV_PCM_MASK (1 << CS35L41_AMP_INV_PCM_SHIFT) ++#define CS35L41_AMP_INV_PCM_MASK BIT(CS35L41_AMP_INV_PCM_SHIFT) + #define CS35L41_AMP_PCM_VOL_SHIFT 3 + #define CS35L41_AMP_PCM_VOL_MASK (0x7FF << 3) + #define CS35L41_AMP_PCM_VOL_MUTE 0x4CF +@@ -754,7 +753,7 @@ extern const struct reg_default cs35l41_reg[CS35L41_MAX_CACHE_REG]; + extern const struct cs35l41_otp_map_element_t + cs35l41_otp_map_map[CS35L41_NUM_OTP_MAPS]; + +-#define CS35L41_REGSTRIDE 4 ++#define CS35L41_REGSTRIDE 4 + + struct cs35l41_private { + struct snd_soc_codec *codec; +@@ -766,11 +765,11 @@ struct cs35l41_private { + /* GPIO for /RST */ + struct gpio_desc *reset_gpio; + void (*otp_setup)(struct cs35l41_private *cs35l41, bool is_pre_setup, +- unsigned int *freq); ++ unsigned int *freq); + }; + + int cs35l41_probe(struct cs35l41_private *cs35l41, +- struct cs35l41_platform_data *pdata); ++ struct cs35l41_platform_data *pdata); + int cs35l41_remove(struct cs35l41_private *cs35l41); + + #endif /*__CS35L41_H__*/ +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Fix-a-shift-out-of-bounds-warning-found.patch b/patches.suse/ASoC-cs35l41-Fix-a-shift-out-of-bounds-warning-found.patch new file mode 100644 index 0000000..186083f --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Fix-a-shift-out-of-bounds-warning-found.patch @@ -0,0 +1,71 @@ +From 0b3d5d2e358ca6772fc3662fca27acb12a682fbf Mon Sep 17 00:00:00 2001 +From: Hui Wang +Date: Thu, 24 Mar 2022 16:18:39 +0800 +Subject: [PATCH] ASoC: cs35l41: Fix a shift-out-of-bounds warning found by UBSAN +Git-commit: 0b3d5d2e358ca6772fc3662fca27acb12a682fbf +Patch-mainline: v5.18-rc4 +References: bsc#1203699 + +We enabled UBSAN in the ubuntu kernel, and the cs35l41 driver triggers +a warning calltrace like below: + +cs35l41-hda i2c-CSC3551:00-cs35l41-hda.0: bitoffset= 8, word_offset=23, bit_sum mod 32=0, otp_map[i].size = 24 +cs35l41-hda i2c-CSC3551:00-cs35l41-hda.0: bitoffset= 0, word_offset=24, bit_sum mod 32=24, otp_map[i].size = 0 +================================================================================ +Ubsan: shift-out-of-bounds in linux-kernel-src/sound/soc/codecs/cs35l41-lib.c:836:8 +shift exponent 64 is too large for 64-bit type 'long unsigned int' +Cpu: 10 PID: 595 Comm: systemd-udevd Not tainted 5.15.0-23-generic #23 +Hardware name: LENOVO \x02MFG_IN_GO/\x02MFG_IN_GO, BIOS N3GET19W (1.00 ) 03/11/2022 +Call Trace: + + show_stack+0x52/0x58 + dump_stack_lvl+0x4a/0x5f + dump_stack+0x10/0x12 + ubsan_epilogue+0x9/0x45 + __ubsan_handle_shift_out_of_bounds.cold+0x61/0xef + ? regmap_unlock_mutex+0xe/0x10 + cs35l41_otp_unpack.cold+0x1c6/0x2b2 [snd_soc_cs35l41_lib] + cs35l41_hda_probe+0x24f/0x33a [snd_hda_scodec_cs35l41] + cs35l41_hda_i2c_probe+0x65/0x90 [snd_hda_scodec_cs35l41_i2c] + +When both bitoffset and otp_map[i].size are 0, the line 836 will +result in GENMASK(-1, 0), this triggers the shift-out-of-bounds +calltrace. + +Here add a checking, if both bitoffset and otp_map[i].size are 0, +do not run GENMASK() and directly set otp_val to 0, this will not +bring any function change on the driver but could avoid the calltrace. + +Signed-off-by: Hui Wang +Link: https://lore.kernel.org/r/20220324081839.62009-2-hui.wang@canonical.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs35l41-lib.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c +index d0a480c40231..aa6823fbd1a4 100644 +--- a/sound/soc/codecs/cs35l41-lib.c ++++ b/sound/soc/codecs/cs35l41-lib.c +@@ -831,12 +831,14 @@ int cs35l41_otp_unpack(struct device *dev, struct regmap *regmap) + GENMASK(bit_offset + otp_map[i].size - 33, 0)) << + (32 - bit_offset); + bit_offset += otp_map[i].size - 32; +- } else { ++ } else if (bit_offset + otp_map[i].size - 1 >= 0) { + otp_val = (otp_mem[word_offset] & + GENMASK(bit_offset + otp_map[i].size - 1, bit_offset) + ) >> bit_offset; + bit_offset += otp_map[i].size; +- } ++ } else /* both bit_offset and otp_map[i].size are 0 */ ++ otp_val = 0; ++ + bit_sum += otp_map[i].size; + + if (bit_offset == 32) { +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Fix-an-out-of-bounds-access-in-otp_pack.patch b/patches.suse/ASoC-cs35l41-Fix-an-out-of-bounds-access-in-otp_pack.patch new file mode 100644 index 0000000..920e446 --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Fix-an-out-of-bounds-access-in-otp_pack.patch @@ -0,0 +1,116 @@ +From 9f342904216f378e88008bb0ce1ae200a4b99fe8 Mon Sep 17 00:00:00 2001 +From: Hui Wang +Date: Mon, 28 Mar 2022 20:35:35 +0800 +Subject: [PATCH] ASoC: cs35l41: Fix an out-of-bounds access in otp_packed_element_t +Git-commit: 9f342904216f378e88008bb0ce1ae200a4b99fe8 +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +The CS35L41_NUM_OTP_ELEM is 100, but only 99 entries are defined in +the array otp_map_1/2[CS35L41_NUM_OTP_ELEM], this will trigger UBSAN +to report a shift-out-of-bounds warning in the cs35l41_otp_unpack() +since the last entry in the array will result in GENMASK(-1, 0). + +UBSAN reports this problem: + UBSAN: shift-out-of-bounds in /home/hwang4/build/jammy/jammy/sound/soc/codecs/cs35l41-lib.c:836:8 + shift exponent 64 is too large for 64-bit type 'long unsigned int' + CPU: 10 PID: 595 Comm: systemd-udevd Not tainted 5.15.0-23-generic #23 + Hardware name: LENOVO \x02MFG_IN_GO/\x02MFG_IN_GO, BIOS N3GET19W (1.00 ) 03/11/2022 + Call Trace: + + show_stack+0x52/0x58 + dump_stack_lvl+0x4a/0x5f + dump_stack+0x10/0x12 + ubsan_epilogue+0x9/0x45 + __ubsan_handle_shift_out_of_bounds.cold+0x61/0xef + ? regmap_unlock_mutex+0xe/0x10 + cs35l41_otp_unpack.cold+0x1c6/0x2b2 [snd_soc_cs35l41_lib] + cs35l41_hda_probe+0x24f/0x33a [snd_hda_scodec_cs35l41] + cs35l41_hda_i2c_probe+0x65/0x90 [snd_hda_scodec_cs35l41_i2c] + ? cs35l41_hda_i2c_remove+0x20/0x20 [snd_hda_scodec_cs35l41_i2c] + i2c_device_probe+0x252/0x2b0 + +Fixes: 6450ef559056 ("ASoC: cs35l41: CS35L41 Boosted Smart Amplifier") +Reviewed-by: Lucas Tanure +Acked-by: Charles Keepax +Signed-off-by: Hui Wang +Link: https://lore.kernel.org/r/20220328123535.50000-2-hui.wang@canonical.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + include/sound/cs35l41.h | 1 - + sound/soc/codecs/cs35l41-lib.c | 14 +++++++------- + 2 files changed, 7 insertions(+), 8 deletions(-) + +--- a/include/sound/cs35l41.h ++++ b/include/sound/cs35l41.h +@@ -537,7 +537,6 @@ + + #define CS35L41_MAX_CACHE_REG 36 + #define CS35L41_OTP_SIZE_WORDS 32 +-#define CS35L41_NUM_OTP_ELEM 100 + + #define CS35L41_NUM_SUPPLIES 2 + +--- a/sound/soc/codecs/cs35l41-lib.c ++++ b/sound/soc/codecs/cs35l41-lib.c +@@ -423,7 +423,7 @@ static bool cs35l41_volatile_reg(struct + } + } + +-static const struct cs35l41_otp_packed_element_t otp_map_1[CS35L41_NUM_OTP_ELEM] = { ++static const struct cs35l41_otp_packed_element_t otp_map_1[] = { + /* addr shift size */ + { 0x00002030, 0, 4 }, /*TRIM_OSC_FREQ_TRIM*/ + { 0x00002030, 7, 1 }, /*TRIM_OSC_TRIM_DONE*/ +@@ -526,7 +526,7 @@ static const struct cs35l41_otp_packed_e + { 0x00017044, 0, 24 }, /*LOT_NUMBER*/ + }; + +-static const struct cs35l41_otp_packed_element_t otp_map_2[CS35L41_NUM_OTP_ELEM] = { ++static const struct cs35l41_otp_packed_element_t otp_map_2[] = { + /* addr shift size */ + { 0x00002030, 0, 4 }, /*TRIM_OSC_FREQ_TRIM*/ + { 0x00002030, 7, 1 }, /*TRIM_OSC_TRIM_DONE*/ +@@ -691,35 +691,35 @@ static const struct cs35l41_otp_map_elem + { + .id = 0x01, + .map = otp_map_1, +- .num_elements = CS35L41_NUM_OTP_ELEM, ++ .num_elements = ARRAY_SIZE(otp_map_1), + .bit_offset = 16, + .word_offset = 2, + }, + { + .id = 0x02, + .map = otp_map_2, +- .num_elements = CS35L41_NUM_OTP_ELEM, ++ .num_elements = ARRAY_SIZE(otp_map_2), + .bit_offset = 16, + .word_offset = 2, + }, + { + .id = 0x03, + .map = otp_map_2, +- .num_elements = CS35L41_NUM_OTP_ELEM, ++ .num_elements = ARRAY_SIZE(otp_map_2), + .bit_offset = 16, + .word_offset = 2, + }, + { + .id = 0x06, + .map = otp_map_2, +- .num_elements = CS35L41_NUM_OTP_ELEM, ++ .num_elements = ARRAY_SIZE(otp_map_2), + .bit_offset = 16, + .word_offset = 2, + }, + { + .id = 0x08, + .map = otp_map_1, +- .num_elements = CS35L41_NUM_OTP_ELEM, ++ .num_elements = ARRAY_SIZE(otp_map_1), + .bit_offset = 16, + .word_offset = 2, + }, diff --git a/patches.suse/ASoC-cs35l41-Fix-link-problem.patch b/patches.suse/ASoC-cs35l41-Fix-link-problem.patch new file mode 100644 index 0000000..50fac11 --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Fix-link-problem.patch @@ -0,0 +1,262 @@ +From a5e0091d62abb9599d9dea505ec0e8c820001831 Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Thu, 25 Nov 2021 14:35:01 +0000 +Subject: [PATCH] ASoC: cs35l41: Fix link problem +Git-commit: a5e0091d62abb9599d9dea505ec0e8c820001831 +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +Can't link I2C and SPI to the same binary, better +to move CS35L41 to 3 modules approach. +And instead of exposing cs35l41_reg, volatile_reg, +readable_reg and precious_reg arrays, move +cs35l41_regmap_i2c/spi to new module and expose it. + +Signed-off-by: Lucas Tanure +Link: https://lore.kernel.org/r/20211125143501.7720-1-tanureal@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/Kconfig | 5 ++++ + sound/soc/codecs/Makefile | 6 +++-- + sound/soc/codecs/cs35l41-i2c.c | 15 ----------- + sound/soc/codecs/cs35l41-spi.c | 16 ------------ + sound/soc/codecs/cs35l41-tables.c | 41 ++++++++++++++++++++++++++++--- + sound/soc/codecs/cs35l41.c | 2 ++ + sound/soc/codecs/cs35l41.h | 7 ++---- + 7 files changed, 50 insertions(+), 42 deletions(-) + +diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig +index b6d1827e7986..b4f70e27342c 100644 +--- a/sound/soc/codecs/Kconfig ++++ b/sound/soc/codecs/Kconfig +@@ -612,14 +612,19 @@ config SND_SOC_CS35L36 + tristate "Cirrus Logic CS35L36 CODEC" + depends on I2C + ++config SND_SOC_CS35L41 ++ tristate ++ + config SND_SOC_CS35L41_SPI + tristate "Cirrus Logic CS35L41 CODEC (SPI)" + depends on SPI_MASTER ++ select SND_SOC_CS35L41 + select REGMAP_SPI + + config SND_SOC_CS35L41_I2C + tristate "Cirrus Logic CS35L41 CODEC (I2C)" + depends on I2C ++ select SND_SOC_CS35L41 + select REGMAP_I2C + + config SND_SOC_CS42L42 +diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile +index 9acfbcbfc46d..485eee75502b 100644 +--- a/sound/soc/codecs/Makefile ++++ b/sound/soc/codecs/Makefile +@@ -54,8 +54,9 @@ snd-soc-cs35l33-objs := cs35l33.o + snd-soc-cs35l34-objs := cs35l34.o + snd-soc-cs35l35-objs := cs35l35.o + snd-soc-cs35l36-objs := cs35l36.o +-snd-soc-cs35l41-spi-objs := cs35l41-spi.o cs35l41.o cs35l41-tables.o +-snd-soc-cs35l41-i2c-objs := cs35l41-i2c.o cs35l41.o cs35l41-tables.o ++snd-soc-cs35l41-objs := cs35l41.o cs35l41-tables.o ++snd-soc-cs35l41-spi-objs := cs35l41-spi.o ++snd-soc-cs35l41-i2c-objs := cs35l41-i2c.o + snd-soc-cs42l42-objs := cs42l42.o + snd-soc-cs42l51-objs := cs42l51.o + snd-soc-cs42l51-i2c-objs := cs42l51-i2c.o +@@ -391,6 +392,7 @@ obj-$(CONFIG_SND_SOC_CS35L33) += snd-soc-cs35l33.o + obj-$(CONFIG_SND_SOC_CS35L34) += snd-soc-cs35l34.o + obj-$(CONFIG_SND_SOC_CS35L35) += snd-soc-cs35l35.o + obj-$(CONFIG_SND_SOC_CS35L36) += snd-soc-cs35l36.o ++obj-$(CONFIG_SND_SOC_CS35L41) += snd-soc-cs35l41.o + obj-$(CONFIG_SND_SOC_CS35L41_SPI) += snd-soc-cs35l41-spi.o + obj-$(CONFIG_SND_SOC_CS35L41_I2C) += snd-soc-cs35l41-i2c.o + obj-$(CONFIG_SND_SOC_CS42L42) += snd-soc-cs42l42.o +diff --git a/sound/soc/codecs/cs35l41-i2c.c b/sound/soc/codecs/cs35l41-i2c.c +index d5fa8d2c4a70..c9b604af6b71 100644 +--- a/sound/soc/codecs/cs35l41-i2c.c ++++ b/sound/soc/codecs/cs35l41-i2c.c +@@ -20,21 +20,6 @@ + #include + #include "cs35l41.h" + +-static struct regmap_config cs35l41_regmap_i2c = { +- .reg_bits = 32, +- .val_bits = 32, +- .reg_stride = CS35L41_REGSTRIDE, +- .reg_format_endian = REGMAP_ENDIAN_BIG, +- .val_format_endian = REGMAP_ENDIAN_BIG, +- .max_register = CS35L41_LASTREG, +- .reg_defaults = cs35l41_reg, +- .num_reg_defaults = ARRAY_SIZE(cs35l41_reg), +- .volatile_reg = cs35l41_volatile_reg, +- .readable_reg = cs35l41_readable_reg, +- .precious_reg = cs35l41_precious_reg, +- .cache_type = REGCACHE_RBTREE, +-}; +- + static const struct i2c_device_id cs35l41_id_i2c[] = { + { "cs35l40", 0 }, + { "cs35l41", 0 }, +diff --git a/sound/soc/codecs/cs35l41-spi.c b/sound/soc/codecs/cs35l41-spi.c +index 90a921f726c3..5d6cf39abec4 100644 +--- a/sound/soc/codecs/cs35l41-spi.c ++++ b/sound/soc/codecs/cs35l41-spi.c +@@ -18,22 +18,6 @@ + #include + #include "cs35l41.h" + +-static struct regmap_config cs35l41_regmap_spi = { +- .reg_bits = 32, +- .val_bits = 32, +- .pad_bits = 16, +- .reg_stride = CS35L41_REGSTRIDE, +- .reg_format_endian = REGMAP_ENDIAN_BIG, +- .val_format_endian = REGMAP_ENDIAN_BIG, +- .max_register = CS35L41_LASTREG, +- .reg_defaults = cs35l41_reg, +- .num_reg_defaults = ARRAY_SIZE(cs35l41_reg), +- .volatile_reg = cs35l41_volatile_reg, +- .readable_reg = cs35l41_readable_reg, +- .precious_reg = cs35l41_precious_reg, +- .cache_type = REGCACHE_RBTREE, +-}; +- + static const struct spi_device_id cs35l41_id_spi[] = { + { "cs35l40", 0 }, + { "cs35l41", 0 }, +diff --git a/sound/soc/codecs/cs35l41-tables.c b/sound/soc/codecs/cs35l41-tables.c +index 9d1a7d7dd24d..3eb18b17a7b0 100644 +--- a/sound/soc/codecs/cs35l41-tables.c ++++ b/sound/soc/codecs/cs35l41-tables.c +@@ -8,7 +8,7 @@ + + #include "cs35l41.h" + +-const struct reg_default cs35l41_reg[CS35L41_MAX_CACHE_REG] = { ++static const struct reg_default cs35l41_reg[] = { + { CS35L41_PWR_CTRL1, 0x00000000 }, + { CS35L41_PWR_CTRL3, 0x01000010 }, + { CS35L41_GPIO_PAD_CONTROL, 0x00000000 }, +@@ -47,7 +47,7 @@ const struct reg_default cs35l41_reg[CS35L41_MAX_CACHE_REG] = { + { CS35L41_MIXER_NGATE_CH2_CFG, 0x00000303 }, + }; + +-bool cs35l41_readable_reg(struct device *dev, unsigned int reg) ++static bool cs35l41_readable_reg(struct device *dev, unsigned int reg) + { + switch (reg) { + case CS35L41_DEVID: +@@ -331,7 +331,7 @@ bool cs35l41_readable_reg(struct device *dev, unsigned int reg) + } + } + +-bool cs35l41_precious_reg(struct device *dev, unsigned int reg) ++static bool cs35l41_precious_reg(struct device *dev, unsigned int reg) + { + switch (reg) { + case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31: +@@ -344,7 +344,7 @@ bool cs35l41_precious_reg(struct device *dev, unsigned int reg) + } + } + +-bool cs35l41_volatile_reg(struct device *dev, unsigned int reg) ++static bool cs35l41_volatile_reg(struct device *dev, unsigned int reg) + { + switch (reg) { + case CS35L41_DEVID: +@@ -688,3 +688,36 @@ const struct cs35l41_otp_map_element_t cs35l41_otp_map_map[CS35L41_NUM_OTP_MAPS] + .word_offset = 2, + }, + }; ++ ++struct regmap_config cs35l41_regmap_i2c = { ++ .reg_bits = 32, ++ .val_bits = 32, ++ .reg_stride = CS35L41_REGSTRIDE, ++ .reg_format_endian = REGMAP_ENDIAN_BIG, ++ .val_format_endian = REGMAP_ENDIAN_BIG, ++ .max_register = CS35L41_LASTREG, ++ .reg_defaults = cs35l41_reg, ++ .num_reg_defaults = ARRAY_SIZE(cs35l41_reg), ++ .volatile_reg = cs35l41_volatile_reg, ++ .readable_reg = cs35l41_readable_reg, ++ .precious_reg = cs35l41_precious_reg, ++ .cache_type = REGCACHE_RBTREE, ++}; ++EXPORT_SYMBOL_GPL(cs35l41_regmap_i2c); ++ ++struct regmap_config cs35l41_regmap_spi = { ++ .reg_bits = 32, ++ .val_bits = 32, ++ .pad_bits = 16, ++ .reg_stride = CS35L41_REGSTRIDE, ++ .reg_format_endian = REGMAP_ENDIAN_BIG, ++ .val_format_endian = REGMAP_ENDIAN_BIG, ++ .max_register = CS35L41_LASTREG, ++ .reg_defaults = cs35l41_reg, ++ .num_reg_defaults = ARRAY_SIZE(cs35l41_reg), ++ .volatile_reg = cs35l41_volatile_reg, ++ .readable_reg = cs35l41_readable_reg, ++ .precious_reg = cs35l41_precious_reg, ++ .cache_type = REGCACHE_RBTREE, ++}; ++EXPORT_SYMBOL_GPL(cs35l41_regmap_spi); +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index afb07d2991ba..e04924526883 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -1731,6 +1731,7 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, + + return ret; + } ++EXPORT_SYMBOL_GPL(cs35l41_probe); + + void cs35l41_remove(struct cs35l41_private *cs35l41) + { +@@ -1739,6 +1740,7 @@ void cs35l41_remove(struct cs35l41_private *cs35l41) + regulator_bulk_disable(CS35L41_NUM_SUPPLIES, cs35l41->supplies); + gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); + } ++EXPORT_SYMBOL_GPL(cs35l41_remove); + + MODULE_DESCRIPTION("ASoC CS35L41 driver"); + MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, "); +diff --git a/sound/soc/codecs/cs35l41.h b/sound/soc/codecs/cs35l41.h +index eea3b14acb0b..f82075ea855f 100644 +--- a/sound/soc/codecs/cs35l41.h ++++ b/sound/soc/codecs/cs35l41.h +@@ -538,7 +538,6 @@ + #define CS35L41_OTP_TRIM_35 0x0000400C + #define CS35L41_OTP_TRIM_36 0x00002030 + +-#define CS35L41_MAX_CACHE_REG 36 + #define CS35L41_OTP_SIZE_WORDS 32 + #define CS35L41_NUM_OTP_ELEM 100 + #define CS35L41_NUM_OTP_MAPS 5 +@@ -734,9 +733,8 @@ + #define CS35L41_RX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) + #define CS35L41_TX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) + +-bool cs35l41_readable_reg(struct device *dev, unsigned int reg); +-bool cs35l41_precious_reg(struct device *dev, unsigned int reg); +-bool cs35l41_volatile_reg(struct device *dev, unsigned int reg); ++extern struct regmap_config cs35l41_regmap_i2c; ++extern struct regmap_config cs35l41_regmap_spi; + + struct cs35l41_otp_packed_element_t { + u32 reg; +@@ -752,7 +750,6 @@ struct cs35l41_otp_map_element_t { + u32 word_offset; + }; + +-extern const struct reg_default cs35l41_reg[CS35L41_MAX_CACHE_REG]; + extern const struct cs35l41_otp_map_element_t + cs35l41_otp_map_map[CS35L41_NUM_OTP_MAPS]; + +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Fix-max-number-of-TX-channels.patch b/patches.suse/ASoC-cs35l41-Fix-max-number-of-TX-channels.patch new file mode 100644 index 0000000..a656f9c --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Fix-max-number-of-TX-channels.patch @@ -0,0 +1,38 @@ +From 16639d39bdf577168d3fe34315917a94365c8d19 Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Thu, 3 Mar 2022 17:30:41 +0000 +Subject: [PATCH] ASoC: cs35l41: Fix max number of TX channels +Git-commit: 16639d39bdf577168d3fe34315917a94365c8d19 +Alt-commit: dacf1497a8ea388cca67081dc25780c50f77fa42 +Patch-mainline: v5.18-rc1 +References: bsc#1203699 + +This device only has 4 TX channels. + +Fixes: fe1024d50477b ("ASoC: cs35l41: Combine adjacent register writes") +Signed-off-by: Lucas Tanure +Acked-by: Charles Keepax +Link: https://lore.kernel.org/r/20220303173059.269657-3-tanureal@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs35l41.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index 90c91b00288b..f3787d77f892 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -1091,7 +1091,7 @@ static struct snd_soc_dai_driver cs35l41_dai[] = { + .capture = { + .stream_name = "AMP Capture", + .channels_min = 1, +- .channels_max = 8, ++ .channels_max = 4, + .rates = SNDRV_PCM_RATE_KNOT, + .formats = CS35L41_TX_FORMATS, + }, +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Fix-undefined-reference-to-core-functio.patch b/patches.suse/ASoC-cs35l41-Fix-undefined-reference-to-core-functio.patch new file mode 100644 index 0000000..62ca4ee --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Fix-undefined-reference-to-core-functio.patch @@ -0,0 +1,52 @@ +From 0695ad92fe1a0bb7697eb92c6a145a73c5ab0e24 Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Wed, 1 Dec 2021 18:00:04 +0000 +Subject: [PATCH] ASoC: cs35l41: Fix undefined reference to core functions +Git-commit: 0695ad92fe1a0bb7697eb92c6a145a73c5ab0e24 +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +Auto select core driver if i2c or spi bus drivers are +selected + +Fixes: a5e0091d62ab ("ASoC: cs35l41: Fix link problem") + +Signed-off-by: Lucas Tanure +Reported-by: kernel test robot +Link: https://lore.kernel.org/r/20211201180004.1402156-2-tanureal@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/Kconfig | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig +index b4f70e27342c..c033ee7d82e4 100644 +--- a/sound/soc/codecs/Kconfig ++++ b/sound/soc/codecs/Kconfig +@@ -614,17 +614,19 @@ config SND_SOC_CS35L36 + + config SND_SOC_CS35L41 + tristate ++ default y if SND_SOC_CS35L41_SPI=y ++ default y if SND_SOC_CS35L41_I2C=y ++ default m if SND_SOC_CS35L41_SPI=m ++ default m if SND_SOC_CS35L41_I2C=m + + config SND_SOC_CS35L41_SPI + tristate "Cirrus Logic CS35L41 CODEC (SPI)" + depends on SPI_MASTER +- select SND_SOC_CS35L41 + select REGMAP_SPI + + config SND_SOC_CS35L41_I2C + tristate "Cirrus Logic CS35L41 CODEC (I2C)" + depends on I2C +- select SND_SOC_CS35L41 + select REGMAP_I2C + + config SND_SOC_CS42L42 +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Fix-use-of-an-uninitialised-variable.patch b/patches.suse/ASoC-cs35l41-Fix-use-of-an-uninitialised-variable.patch new file mode 100644 index 0000000..07d46c0 --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Fix-use-of-an-uninitialised-variable.patch @@ -0,0 +1,64 @@ +From c2f14cc2bcdd532f8a18450407ffc27bbbff2319 Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Tue, 14 Sep 2021 15:13:44 +0100 +Subject: [PATCH] ASoC: cs35l41: Fix use of an uninitialised variable +Git-commit: c2f14cc2bcdd532f8a18450407ffc27bbbff2319 +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +The loop checking PDN_DONE doesn't check the return value from +regmap_read, nor does it initialise val. This means if regmap_read fails +val will be checked for the PDN_DONE bit whilst being uninitialised. + +Fix this up by switching to regmap_read_poll_timeout which tidies up the +code and avoids the uninitialised variable. + +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20210914141349.30218-1-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs35l41.c | 19 +++++-------------- + 1 file changed, 5 insertions(+), 14 deletions(-) + +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index dbec54a28a9e..d2a11cc33683 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -580,7 +580,6 @@ static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w, + unsigned int val; + int ret = 0; + bool pdn; +- int i; + + switch (event) { + case SND_SOC_DAPM_POST_PMU: +@@ -599,19 +598,11 @@ static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w, + CS35L41_GLOBAL_EN_MASK, 0); + + pdn = false; +- for (i = 0; i < 100; i++) { +- regmap_read(cs35l41->regmap, +- CS35L41_IRQ1_STATUS1, +- &val); +- if (val & CS35L41_PDN_DONE_MASK) { +- pdn = true; +- break; +- } +- usleep_range(1000, 1100); +- } +- +- if (!pdn) +- dev_warn(cs35l41->dev, "PDN failed\n"); ++ ret = regmap_read_poll_timeout(cs35l41->regmap, CS35L41_IRQ1_STATUS1, ++ val, val & CS35L41_PDN_DONE_MASK, ++ 1000, 100000); ++ if (ret) ++ dev_warn(cs35l41->dev, "PDN failed: %d\n", ret); + + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, + CS35L41_PDN_DONE_MASK); +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Fixup-the-error-messages.patch b/patches.suse/ASoC-cs35l41-Fixup-the-error-messages.patch new file mode 100644 index 0000000..9a25caa --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Fixup-the-error-messages.patch @@ -0,0 +1,235 @@ +From 3e60abeb5cb51bccc8bcc6808eef2037ab412334 Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Tue, 14 Sep 2021 15:13:48 +0100 +Subject: [PATCH] ASoC: cs35l41: Fixup the error messages +Git-commit: 3e60abeb5cb51bccc8bcc6808eef2037ab412334 +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +It is not idiomatic for ASoC to print the function name in the error +messages, however it is expected to show the return code. Update the +error messages to follow these conventions. + +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20210914141349.30218-5-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs35l41.c | 53 +++++++++++++++++--------------------- + 1 file changed, 24 insertions(+), 29 deletions(-) + +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index 0d7073bb313a..cc158fe4b7fe 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -316,7 +316,7 @@ static int cs35l41_otp_unpack(void *data) + + ret = regmap_read(cs35l41->regmap, CS35L41_OTPID, &otp_id_reg); + if (ret < 0) { +- dev_err(cs35l41->dev, "Read OTP ID failed\n"); ++ dev_err(cs35l41->dev, "Read OTP ID failed: %d\n", ret); + goto err_otp_unpack; + } + +@@ -335,7 +335,7 @@ static int cs35l41_otp_unpack(void *data) + ret = regmap_bulk_read(cs35l41->regmap, CS35L41_OTP_MEM0, otp_mem, + CS35L41_OTP_SIZE_WORDS); + if (ret < 0) { +- dev_err(cs35l41->dev, "Read OTP Mem failed\n"); ++ dev_err(cs35l41->dev, "Read OTP Mem failed: %d\n", ret); + goto err_otp_unpack; + } + +@@ -349,12 +349,12 @@ static int cs35l41_otp_unpack(void *data) + + ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x00000055); + if (ret < 0) { +- dev_err(cs35l41->dev, "Write Unlock key failed 1/2\n"); ++ dev_err(cs35l41->dev, "Write Unlock key failed 1/2: %d\n", ret); + goto err_otp_unpack; + } + ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x000000AA); + if (ret < 0) { +- dev_err(cs35l41->dev, "Write Unlock key failed 2/2\n"); ++ dev_err(cs35l41->dev, "Write Unlock key failed 2/2: %d\n", ret); + goto err_otp_unpack; + } + +@@ -393,7 +393,7 @@ static int cs35l41_otp_unpack(void *data) + otp_map[i].shift), + otp_val << otp_map[i].shift); + if (ret < 0) { +- dev_err(cs35l41->dev, "Write OTP val failed\n"); ++ dev_err(cs35l41->dev, "Write OTP val failed: %d\n", ret); + goto err_otp_unpack; + } + } +@@ -401,12 +401,12 @@ static int cs35l41_otp_unpack(void *data) + + ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x000000CC); + if (ret < 0) { +- dev_err(cs35l41->dev, "Write Lock key failed 1/2\n"); ++ dev_err(cs35l41->dev, "Write Lock key failed 1/2: %d\n", ret); + goto err_otp_unpack; + } + ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x00000033); + if (ret < 0) { +- dev_err(cs35l41->dev, "Write Lock key failed 2/2\n"); ++ dev_err(cs35l41->dev, "Write Lock key failed 2/2: %d\n", ret); + goto err_otp_unpack; + } + ret = 0; +@@ -745,9 +745,7 @@ static int cs35l41_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) + case SND_SOC_DAIFMT_CBC_CFC: + break; + default: +- dev_warn(cs35l41->dev, +- "%s: Mixed provider/consumer mode unsupported\n", +- __func__); ++ dev_warn(cs35l41->dev, "Mixed provider/consumer mode unsupported\n"); + return -EINVAL; + } + +@@ -758,8 +756,7 @@ static int cs35l41_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) + daifmt |= 2 << CS35L41_ASP_FMT_SHIFT; + break; + default: +- dev_warn(cs35l41->dev, +- "%s: Invalid or unsupported DAI format\n", __func__); ++ dev_warn(cs35l41->dev, "Invalid or unsupported DAI format\n"); + return -EINVAL; + } + +@@ -776,8 +773,7 @@ static int cs35l41_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) + case SND_SOC_DAIFMT_NB_NF: + break; + default: +- dev_warn(cs35l41->dev, +- "%s: Invalid DAI clock INV\n", __func__); ++ dev_warn(cs35l41->dev, "Invalid DAI clock INV\n"); + return -EINVAL; + } + +@@ -824,8 +820,7 @@ static int cs35l41_pcm_hw_params(struct snd_pcm_substream *substream, + } + + if (i >= ARRAY_SIZE(cs35l41_fs_rates)) { +- dev_err(cs35l41->dev, "%s: Unsupported rate: %u\n", +- __func__, rate); ++ dev_err(cs35l41->dev, "Unsupported rate: %u\n", rate); + return -EINVAL; + } + +@@ -1048,7 +1043,7 @@ static int cs35l41_boost_config(struct cs35l41_private *cs35l41, + CS35L41_BST_IPK_MASK, + bst_ipk_scaled << CS35L41_BST_IPK_SHIFT); + if (ret) { +- dev_err(dev, "Failed to write boost inductor peak current\n"); ++ dev_err(dev, "Failed to write boost inductor peak current: %d\n", ret); + return ret; + } + +@@ -1067,7 +1062,7 @@ static int cs35l41_set_pdata(struct cs35l41_private *cs35l41) + cs35l41->pdata.bst_cap, + cs35l41->pdata.bst_ipk); + if (ret) { +- dev_err(cs35l41->dev, "Error in Boost DT config\n"); ++ dev_err(cs35l41->dev, "Error in Boost DT config: %d\n", ret); + return ret; + } + } else { +@@ -1337,13 +1332,13 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, + + ret = regmap_read(cs35l41->regmap, CS35L41_DEVID, ®id); + if (ret < 0) { +- dev_err(cs35l41->dev, "Get Device ID failed\n"); ++ dev_err(cs35l41->dev, "Get Device ID failed: %d\n", ret); + goto err; + } + + ret = regmap_read(cs35l41->regmap, CS35L41_REVID, ®_revid); + if (ret < 0) { +- dev_err(cs35l41->dev, "Get Revision ID failed\n"); ++ dev_err(cs35l41->dev, "Get Revision ID failed: %d\n", ret); + goto err; + } + +@@ -1367,7 +1362,7 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, + ARRAY_SIZE(cs35l41_reva0_errata_patch)); + if (ret < 0) { + dev_err(cs35l41->dev, +- "Failed to apply A0 errata patch %d\n", ret); ++ "Failed to apply A0 errata patch: %d\n", ret); + goto err; + } + break; +@@ -1377,7 +1372,7 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, + ARRAY_SIZE(cs35l41_revb0_errata_patch)); + if (ret < 0) { + dev_err(cs35l41->dev, +- "Failed to apply B0 errata patch %d\n", ret); ++ "Failed to apply B0 errata patch: %d\n", ret); + goto err; + } + break; +@@ -1387,7 +1382,7 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, + ARRAY_SIZE(cs35l41_revb2_errata_patch)); + if (ret < 0) { + dev_err(cs35l41->dev, +- "Failed to apply B2 errata patch %d\n", ret); ++ "Failed to apply B2 errata patch: %d\n", ret); + goto err; + } + break; +@@ -1411,33 +1406,33 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, + + ret = cs35l41_otp_unpack(cs35l41); + if (ret < 0) { +- dev_err(cs35l41->dev, "OTP Unpack failed\n"); ++ dev_err(cs35l41->dev, "OTP Unpack failed: %d\n", ret); + goto err; + } + + ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_CCM_CORE_CTRL, 0); + if (ret < 0) { +- dev_err(cs35l41->dev, "Write CCM_CORE_CTRL failed\n"); ++ dev_err(cs35l41->dev, "Write CCM_CORE_CTRL failed: %d\n", ret); + goto err; + } + + ret = regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, + CS35L41_AMP_EN_MASK, 0); + if (ret < 0) { +- dev_err(cs35l41->dev, "Write CS35L41_PWR_CTRL2 failed\n"); ++ dev_err(cs35l41->dev, "Write CS35L41_PWR_CTRL2 failed: %d\n", ret); + goto err; + } + + ret = regmap_update_bits(cs35l41->regmap, CS35L41_AMP_GAIN_CTRL, + CS35L41_AMP_GAIN_PCM_MASK, 0); + if (ret < 0) { +- dev_err(cs35l41->dev, "Write CS35L41_AMP_GAIN_CTRL failed\n"); ++ dev_err(cs35l41->dev, "Write CS35L41_AMP_GAIN_CTRL failed: %d\n", ret); + goto err; + } + + ret = cs35l41_set_pdata(cs35l41); + if (ret < 0) { +- dev_err(cs35l41->dev, "%s: Set pdata failed\n", __func__); ++ dev_err(cs35l41->dev, "Set pdata failed: %d\n", ret); + goto err; + } + +@@ -1445,7 +1440,7 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, + &soc_component_dev_cs35l41, + cs35l41_dai, ARRAY_SIZE(cs35l41_dai)); + if (ret < 0) { +- dev_err(cs35l41->dev, "%s: Register codec failed\n", __func__); ++ dev_err(cs35l41->dev, "Register codec failed: %d\n", ret); + goto err; + } + +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Make-cs35l41_remove-return-void.patch b/patches.suse/ASoC-cs35l41-Make-cs35l41_remove-return-void.patch new file mode 100644 index 0000000..c0e59bc --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Make-cs35l41_remove-return-void.patch @@ -0,0 +1,94 @@ +From ca7270a7b60dfb25b7fd180d93ea18eebd5edee7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= +Date: Wed, 20 Oct 2021 15:24:16 +0200 +Subject: [PATCH] ASoC: cs35l41: Make cs35l41_remove() return void +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: ca7270a7b60dfb25b7fd180d93ea18eebd5edee7 +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +Up to now cs35l41_remove() returns zero unconditionally. Make it +return void instead which makes it easier to see in the callers that +there is no error to handle. + +Also the return value of i2c, platform and spi remove callbacks is +ignored anyway. + +Signed-off-by: Uwe Kleine-König +Link: https://lore.kernel.org/r/20211020132416.30288-1-u.kleine-koenig@pengutronix.de +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs35l41-i2c.c | 4 +++- + sound/soc/codecs/cs35l41-spi.c | 4 +++- + sound/soc/codecs/cs35l41.c | 4 +--- + sound/soc/codecs/cs35l41.h | 2 +- + 4 files changed, 8 insertions(+), 6 deletions(-) + +diff --git a/sound/soc/codecs/cs35l41-i2c.c b/sound/soc/codecs/cs35l41-i2c.c +index 2f3d1bd8e046..d5fa8d2c4a70 100644 +--- a/sound/soc/codecs/cs35l41-i2c.c ++++ b/sound/soc/codecs/cs35l41-i2c.c +@@ -75,7 +75,9 @@ static int cs35l41_i2c_remove(struct i2c_client *client) + { + struct cs35l41_private *cs35l41 = i2c_get_clientdata(client); + +- return cs35l41_remove(cs35l41); ++ cs35l41_remove(cs35l41); ++ ++ return 0; + } + + #ifdef CONFIG_OF +diff --git a/sound/soc/codecs/cs35l41-spi.c b/sound/soc/codecs/cs35l41-spi.c +index eac64779eea8..90a921f726c3 100644 +--- a/sound/soc/codecs/cs35l41-spi.c ++++ b/sound/soc/codecs/cs35l41-spi.c +@@ -100,7 +100,9 @@ static int cs35l41_spi_remove(struct spi_device *spi) + { + struct cs35l41_private *cs35l41 = spi_get_drvdata(spi); + +- return cs35l41_remove(cs35l41); ++ cs35l41_remove(cs35l41); ++ ++ return 0; + } + + #ifdef CONFIG_OF +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index b16eb6610c0e..94ed21d7676f 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -1433,13 +1433,11 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, + return ret; + } + +-int cs35l41_remove(struct cs35l41_private *cs35l41) ++void cs35l41_remove(struct cs35l41_private *cs35l41) + { + regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, 0xFFFFFFFF); + regulator_bulk_disable(CS35L41_NUM_SUPPLIES, cs35l41->supplies); + gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); +- +- return 0; + } + + MODULE_DESCRIPTION("ASoC CS35L41 driver"); +diff --git a/sound/soc/codecs/cs35l41.h b/sound/soc/codecs/cs35l41.h +index 0e2639d6ef19..6cffe8a55beb 100644 +--- a/sound/soc/codecs/cs35l41.h ++++ b/sound/soc/codecs/cs35l41.h +@@ -770,6 +770,6 @@ struct cs35l41_private { + + int cs35l41_probe(struct cs35l41_private *cs35l41, + struct cs35l41_platform_data *pdata); +-int cs35l41_remove(struct cs35l41_private *cs35l41); ++void cs35l41_remove(struct cs35l41_private *cs35l41); + + #endif /*__CS35L41_H__*/ +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Move-cs35l41-exit-hibernate-function-in.patch b/patches.suse/ASoC-cs35l41-Move-cs35l41-exit-hibernate-function-in.patch new file mode 100644 index 0000000..484b963 --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Move-cs35l41-exit-hibernate-function-in.patch @@ -0,0 +1,191 @@ +From 94e0bc317ad241c022a6bb311b3a28b4d51ea8b6 Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Wed, 25 May 2022 14:16:30 +0100 +Subject: [PATCH] ASoC: cs35l41: Move cs35l41 exit hibernate function into shared code +Git-commit: 94e0bc317ad241c022a6bb311b3a28b4d51ea8b6 +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +CS35L41 HDA Driver will support hibernation using DSP firmware, +move the exit hibernate function into shared code so this can +be reused. + +Acked-by: Charles Keepax + +Signed-off-by: Stefan Binding +Signed-off-by: Vitaly Rodionov +Link: https://lore.kernel.org/r/20220525131638.5512-10-vitalyr@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + include/sound/cs35l41.h | 1 + + sound/soc/codecs/cs35l41-lib.c | 60 +++++++++++++++++++++++++++++++++ + sound/soc/codecs/cs35l41.c | 61 +--------------------------------- + 3 files changed, 62 insertions(+), 60 deletions(-) + +diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h +index 8972fa697622..7759f2e14d96 100644 +--- a/include/sound/cs35l41.h ++++ b/include/sound/cs35l41.h +@@ -881,6 +881,7 @@ void cs35l41_configure_cs_dsp(struct device *dev, struct regmap *reg, struct cs_ + int cs35l41_set_cspl_mbox_cmd(struct device *dev, struct regmap *regmap, + enum cs35l41_cspl_mbox_cmd cmd); + int cs35l41_write_fs_errata(struct device *dev, struct regmap *regmap); ++int cs35l41_exit_hibernate(struct device *dev, struct regmap *regmap); + int cs35l41_init_boost(struct device *dev, struct regmap *regmap, + struct cs35l41_hw_cfg *hw_cfg); + bool cs35l41_safe_reset(struct regmap *regmap, enum cs35l41_boost_type b_type); +diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c +index 6d3070ea9e06..cc5366c8bdd6 100644 +--- a/sound/soc/codecs/cs35l41-lib.c ++++ b/sound/soc/codecs/cs35l41-lib.c +@@ -1321,6 +1321,66 @@ int cs35l41_write_fs_errata(struct device *dev, struct regmap *regmap) + } + EXPORT_SYMBOL_GPL(cs35l41_write_fs_errata); + ++static void cs35l41_wait_for_pwrmgt_sts(struct device *dev, struct regmap *regmap) ++{ ++ const int pwrmgt_retries = 10; ++ unsigned int sts; ++ int i, ret; ++ ++ for (i = 0; i < pwrmgt_retries; i++) { ++ ret = regmap_read(regmap, CS35L41_PWRMGT_STS, &sts); ++ if (ret) ++ dev_err(dev, "Failed to read PWRMGT_STS: %d\n", ret); ++ else if (!(sts & CS35L41_WR_PEND_STS_MASK)) ++ return; ++ ++ udelay(20); ++ } ++ ++ dev_err(dev, "Timed out reading PWRMGT_STS\n"); ++} ++ ++int cs35l41_exit_hibernate(struct device *dev, struct regmap *regmap) ++{ ++ const int wake_retries = 20; ++ const int sleep_retries = 5; ++ int ret, i, j; ++ ++ for (i = 0; i < sleep_retries; i++) { ++ dev_dbg(dev, "Exit hibernate\n"); ++ ++ for (j = 0; j < wake_retries; j++) { ++ ret = cs35l41_set_cspl_mbox_cmd(dev, regmap, ++ CSPL_MBOX_CMD_OUT_OF_HIBERNATE); ++ if (!ret) ++ break; ++ ++ usleep_range(100, 200); ++ } ++ ++ if (j < wake_retries) { ++ dev_dbg(dev, "Wake success at cycle: %d\n", j); ++ return 0; ++ } ++ ++ dev_err(dev, "Wake failed, re-enter hibernate: %d\n", ret); ++ ++ cs35l41_wait_for_pwrmgt_sts(dev, regmap); ++ regmap_write(regmap, CS35L41_WAKESRC_CTL, 0x0088); ++ ++ cs35l41_wait_for_pwrmgt_sts(dev, regmap); ++ regmap_write(regmap, CS35L41_WAKESRC_CTL, 0x0188); ++ ++ cs35l41_wait_for_pwrmgt_sts(dev, regmap); ++ regmap_write(regmap, CS35L41_PWRMGT_CTL, 0x3); ++ } ++ ++ dev_err(dev, "Timed out waking device\n"); ++ ++ return -ETIMEDOUT; ++} ++EXPORT_SYMBOL_GPL(cs35l41_exit_hibernate); ++ + MODULE_DESCRIPTION("CS35L41 library"); + MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, "); + MODULE_AUTHOR("Lucas Tanure, Cirrus Logic Inc, "); +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index 3e68a07a3c8e..be7d02517739 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -1351,65 +1351,6 @@ static int __maybe_unused cs35l41_runtime_suspend(struct device *dev) + return 0; + } + +-static void cs35l41_wait_for_pwrmgt_sts(struct cs35l41_private *cs35l41) +-{ +- const int pwrmgt_retries = 10; +- unsigned int sts; +- int i, ret; +- +- for (i = 0; i < pwrmgt_retries; i++) { +- ret = regmap_read(cs35l41->regmap, CS35L41_PWRMGT_STS, &sts); +- if (ret) +- dev_err(cs35l41->dev, "Failed to read PWRMGT_STS: %d\n", ret); +- else if (!(sts & CS35L41_WR_PEND_STS_MASK)) +- return; +- +- udelay(20); +- } +- +- dev_err(cs35l41->dev, "Timed out reading PWRMGT_STS\n"); +-} +- +-static int cs35l41_exit_hibernate(struct cs35l41_private *cs35l41) +-{ +- const int wake_retries = 20; +- const int sleep_retries = 5; +- int ret, i, j; +- +- for (i = 0; i < sleep_retries; i++) { +- dev_dbg(cs35l41->dev, "Exit hibernate\n"); +- +- for (j = 0; j < wake_retries; j++) { +- ret = cs35l41_set_cspl_mbox_cmd(cs35l41->dev, cs35l41->regmap, +- CSPL_MBOX_CMD_OUT_OF_HIBERNATE); +- if (!ret) +- break; +- +- usleep_range(100, 200); +- } +- +- if (j < wake_retries) { +- dev_dbg(cs35l41->dev, "Wake success at cycle: %d\n", j); +- return 0; +- } +- +- dev_err(cs35l41->dev, "Wake failed, re-enter hibernate: %d\n", ret); +- +- cs35l41_wait_for_pwrmgt_sts(cs35l41); +- regmap_write(cs35l41->regmap, CS35L41_WAKESRC_CTL, 0x0088); +- +- cs35l41_wait_for_pwrmgt_sts(cs35l41); +- regmap_write(cs35l41->regmap, CS35L41_WAKESRC_CTL, 0x0188); +- +- cs35l41_wait_for_pwrmgt_sts(cs35l41); +- regmap_write(cs35l41->regmap, CS35L41_PWRMGT_CTL, 0x3); +- } +- +- dev_err(cs35l41->dev, "Timed out waking device\n"); +- +- return -ETIMEDOUT; +-} +- + static int __maybe_unused cs35l41_runtime_resume(struct device *dev) + { + struct cs35l41_private *cs35l41 = dev_get_drvdata(dev); +@@ -1422,7 +1363,7 @@ static int __maybe_unused cs35l41_runtime_resume(struct device *dev) + + regcache_cache_only(cs35l41->regmap, false); + +- ret = cs35l41_exit_hibernate(cs35l41); ++ ret = cs35l41_exit_hibernate(cs35l41->dev, cs35l41->regmap); + if (ret) + return ret; + +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Move-cs35l41-fs-errata-into-shared-code.patch b/patches.suse/ASoC-cs35l41-Move-cs35l41-fs-errata-into-shared-code.patch new file mode 100644 index 0000000..369a0b4 --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Move-cs35l41-fs-errata-into-shared-code.patch @@ -0,0 +1,133 @@ +From ff8aad072e6388243fb0c76db4154d0883988384 Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Mon, 9 May 2022 22:46:44 +0100 +Subject: [PATCH] ASoC: cs35l41: Move cs35l41 fs errata into shared code +Git-commit: ff8aad072e6388243fb0c76db4154d0883988384 +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +This sequence is required to setup firmware, and will +be needed for hda driver. + +Signed-off-by: Stefan Binding +Signed-off-by: Vitaly Rodionov +Acked-by: Charles Keepax +Link: https://lore.kernel.org/r/20220509214703.4482-8-vitalyr@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + include/sound/cs35l41.h | 1 + + sound/soc/codecs/cs35l41-lib.c | 32 ++++++++++++++++++++++++++++++++ + sound/soc/codecs/cs35l41.c | 26 ++------------------------ + 3 files changed, 35 insertions(+), 24 deletions(-) + +diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h +index 2271471225b1..d0cfb41495b0 100644 +--- a/include/sound/cs35l41.h ++++ b/include/sound/cs35l41.h +@@ -879,6 +879,7 @@ int cs35l41_set_channels(struct device *dev, struct regmap *reg, + int cs35l41_gpio_config(struct regmap *regmap, struct cs35l41_hw_cfg *hw_cfg); + int cs35l41_set_cspl_mbox_cmd(struct device *dev, struct regmap *regmap, + enum cs35l41_cspl_mbox_cmd cmd); ++int cs35l41_write_fs_errata(struct device *dev, struct regmap *regmap); + int cs35l41_init_boost(struct device *dev, struct regmap *regmap, + struct cs35l41_hw_cfg *hw_cfg); + bool cs35l41_safe_reset(struct regmap *regmap, enum cs35l41_boost_type b_type); +diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c +index 451d3be37157..85fe5f88d6b4 100644 +--- a/sound/soc/codecs/cs35l41-lib.c ++++ b/sound/soc/codecs/cs35l41-lib.c +@@ -667,6 +667,25 @@ static const struct reg_sequence cs35l41_revb2_errata_patch[] = { + { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, + }; + ++static const struct reg_sequence cs35l41_fs_errata_patch[] = { ++ { CS35L41_DSP1_RX1_RATE, 0x00000001 }, ++ { CS35L41_DSP1_RX2_RATE, 0x00000001 }, ++ { CS35L41_DSP1_RX3_RATE, 0x00000001 }, ++ { CS35L41_DSP1_RX4_RATE, 0x00000001 }, ++ { CS35L41_DSP1_RX5_RATE, 0x00000001 }, ++ { CS35L41_DSP1_RX6_RATE, 0x00000001 }, ++ { CS35L41_DSP1_RX7_RATE, 0x00000001 }, ++ { CS35L41_DSP1_RX8_RATE, 0x00000001 }, ++ { CS35L41_DSP1_TX1_RATE, 0x00000001 }, ++ { CS35L41_DSP1_TX2_RATE, 0x00000001 }, ++ { CS35L41_DSP1_TX3_RATE, 0x00000001 }, ++ { CS35L41_DSP1_TX4_RATE, 0x00000001 }, ++ { CS35L41_DSP1_TX5_RATE, 0x00000001 }, ++ { CS35L41_DSP1_TX6_RATE, 0x00000001 }, ++ { CS35L41_DSP1_TX7_RATE, 0x00000001 }, ++ { CS35L41_DSP1_TX8_RATE, 0x00000001 }, ++}; ++ + static const struct cs35l41_otp_map_element_t cs35l41_otp_map_map[] = { + { + .id = 0x01, +@@ -1263,6 +1282,19 @@ int cs35l41_set_cspl_mbox_cmd(struct device *dev, struct regmap *regmap, + } + EXPORT_SYMBOL_GPL(cs35l41_set_cspl_mbox_cmd); + ++int cs35l41_write_fs_errata(struct device *dev, struct regmap *regmap) ++{ ++ int ret; ++ ++ ret = regmap_multi_reg_write(regmap, cs35l41_fs_errata_patch, ++ ARRAY_SIZE(cs35l41_fs_errata_patch)); ++ if (ret < 0) ++ dev_err(dev, "Failed to write fs errata: %d\n", ret); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(cs35l41_write_fs_errata); ++ + MODULE_DESCRIPTION("CS35L41 library"); + MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, "); + MODULE_AUTHOR("Lucas Tanure, Cirrus Logic Inc, "); +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index 0285946688f7..75527649bb14 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -1093,25 +1093,6 @@ static int cs35l41_handle_pdata(struct device *dev, struct cs35l41_hw_cfg *hw_cf + return 0; + } + +-static const struct reg_sequence cs35l41_fs_errata_patch[] = { +- { CS35L41_DSP1_RX1_RATE, 0x00000001 }, +- { CS35L41_DSP1_RX2_RATE, 0x00000001 }, +- { CS35L41_DSP1_RX3_RATE, 0x00000001 }, +- { CS35L41_DSP1_RX4_RATE, 0x00000001 }, +- { CS35L41_DSP1_RX5_RATE, 0x00000001 }, +- { CS35L41_DSP1_RX6_RATE, 0x00000001 }, +- { CS35L41_DSP1_RX7_RATE, 0x00000001 }, +- { CS35L41_DSP1_RX8_RATE, 0x00000001 }, +- { CS35L41_DSP1_TX1_RATE, 0x00000001 }, +- { CS35L41_DSP1_TX2_RATE, 0x00000001 }, +- { CS35L41_DSP1_TX3_RATE, 0x00000001 }, +- { CS35L41_DSP1_TX4_RATE, 0x00000001 }, +- { CS35L41_DSP1_TX5_RATE, 0x00000001 }, +- { CS35L41_DSP1_TX6_RATE, 0x00000001 }, +- { CS35L41_DSP1_TX7_RATE, 0x00000001 }, +- { CS35L41_DSP1_TX8_RATE, 0x00000001 }, +-}; +- + static int cs35l41_dsp_init(struct cs35l41_private *cs35l41) + { + struct wm_adsp *dsp; +@@ -1132,12 +1113,9 @@ static int cs35l41_dsp_init(struct cs35l41_private *cs35l41) + dsp->cs_dsp.num_mems = ARRAY_SIZE(cs35l41_dsp1_regions); + dsp->cs_dsp.lock_regions = 0xFFFFFFFF; + +- ret = regmap_multi_reg_write(cs35l41->regmap, cs35l41_fs_errata_patch, +- ARRAY_SIZE(cs35l41_fs_errata_patch)); +- if (ret < 0) { +- dev_err(cs35l41->dev, "Failed to write fs errata: %d\n", ret); ++ ret = cs35l41_write_fs_errata(cs35l41->dev, cs35l41->regmap); ++ if (ret < 0) + return ret; +- } + + ret = wm_halo_init(dsp); + if (ret) { +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Move-cs35l41_otp_unpack-to-shared-code.patch b/patches.suse/ASoC-cs35l41-Move-cs35l41_otp_unpack-to-shared-code.patch new file mode 100644 index 0000000..6403dd7 --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Move-cs35l41_otp_unpack-to-shared-code.patch @@ -0,0 +1,353 @@ +From fe120d4cb6f6cd03007239e7c578b8703fe6d336 Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Fri, 17 Dec 2021 11:57:00 +0000 +Subject: [PATCH] ASoC: cs35l41: Move cs35l41_otp_unpack to shared code +Git-commit: fe120d4cb6f6cd03007239e7c578b8703fe6d336 +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +ASoC and HDA will do the same cs35l41_otp_unpack, so move it +to shared code + +Signed-off-by: Lucas Tanure +Link: https://lore.kernel.org/r/20211217115708.882525-3-tanureal@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + include/sound/cs35l41.h | 4 +- + sound/soc/codecs/cs35l41-lib.c | 121 ++++++++++++++++++++++++++++++- + sound/soc/codecs/cs35l41.c | 125 +-------------------------------- + 3 files changed, 122 insertions(+), 128 deletions(-) + +diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h +index aac3ffb9bc89..6cf3ef02b26a 100644 +--- a/include/sound/cs35l41.h ++++ b/include/sound/cs35l41.h +@@ -534,7 +534,6 @@ + #define CS35L41_MAX_CACHE_REG 36 + #define CS35L41_OTP_SIZE_WORDS 32 + #define CS35L41_NUM_OTP_ELEM 100 +-#define CS35L41_NUM_OTP_MAPS 5 + + #define CS35L41_VALID_PDATA 0x80000000 + #define CS35L41_NUM_SUPPLIES 2 +@@ -760,8 +759,9 @@ struct cs35l41_otp_map_element_t { + u32 word_offset; + }; + +-extern const struct cs35l41_otp_map_element_t cs35l41_otp_map_map[CS35L41_NUM_OTP_MAPS]; + extern struct regmap_config cs35l41_regmap_i2c; + extern struct regmap_config cs35l41_regmap_spi; + ++int cs35l41_otp_unpack(struct device *dev, struct regmap *regmap); ++ + #endif /* __CS35L41_H */ +diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c +index f19531ebf729..dc5f502447a2 100644 +--- a/sound/soc/codecs/cs35l41-lib.c ++++ b/sound/soc/codecs/cs35l41-lib.c +@@ -7,8 +7,11 @@ + // Author: David Rhodes + // Author: Lucas Tanure + ++#include + #include + #include ++#include ++#include + + #include + +@@ -655,7 +658,7 @@ static const struct cs35l41_otp_packed_element_t otp_map_2[CS35L41_NUM_OTP_ELEM] + { 0x00017044, 0, 24 }, /*LOT_NUMBER*/ + }; + +-const struct cs35l41_otp_map_element_t cs35l41_otp_map_map[CS35L41_NUM_OTP_MAPS] = { ++static const struct cs35l41_otp_map_element_t cs35l41_otp_map_map[] = { + { + .id = 0x01, + .map = otp_map_1, +@@ -692,7 +695,6 @@ const struct cs35l41_otp_map_element_t cs35l41_otp_map_map[CS35L41_NUM_OTP_MAPS] + .word_offset = 2, + }, + }; +-EXPORT_SYMBOL_GPL(cs35l41_otp_map_map); + + struct regmap_config cs35l41_regmap_i2c = { + .reg_bits = 32, +@@ -727,6 +729,121 @@ struct regmap_config cs35l41_regmap_spi = { + }; + EXPORT_SYMBOL_GPL(cs35l41_regmap_spi); + ++static const struct cs35l41_otp_map_element_t *cs35l41_find_otp_map(u32 otp_id) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(cs35l41_otp_map_map); i++) { ++ if (cs35l41_otp_map_map[i].id == otp_id) ++ return &cs35l41_otp_map_map[i]; ++ } ++ ++ return NULL; ++} ++ ++int cs35l41_otp_unpack(struct device *dev, struct regmap *regmap) ++{ ++ const struct cs35l41_otp_map_element_t *otp_map_match; ++ const struct cs35l41_otp_packed_element_t *otp_map; ++ int bit_offset, word_offset, ret, i; ++ unsigned int bit_sum = 8; ++ u32 otp_val, otp_id_reg; ++ u32 *otp_mem; ++ ++ otp_mem = kmalloc_array(CS35L41_OTP_SIZE_WORDS, sizeof(*otp_mem), GFP_KERNEL); ++ if (!otp_mem) ++ return -ENOMEM; ++ ++ ret = regmap_read(regmap, CS35L41_OTPID, &otp_id_reg); ++ if (ret) { ++ dev_err(dev, "Read OTP ID failed: %d\n", ret); ++ goto err_otp_unpack; ++ } ++ ++ otp_map_match = cs35l41_find_otp_map(otp_id_reg); ++ ++ if (!otp_map_match) { ++ dev_err(dev, "OTP Map matching ID %d not found\n", otp_id_reg); ++ ret = -EINVAL; ++ goto err_otp_unpack; ++ } ++ ++ ret = regmap_bulk_read(regmap, CS35L41_OTP_MEM0, otp_mem, CS35L41_OTP_SIZE_WORDS); ++ if (ret) { ++ dev_err(dev, "Read OTP Mem failed: %d\n", ret); ++ goto err_otp_unpack; ++ } ++ ++ otp_map = otp_map_match->map; ++ ++ bit_offset = otp_map_match->bit_offset; ++ word_offset = otp_map_match->word_offset; ++ ++ ret = regmap_write(regmap, CS35L41_TEST_KEY_CTL, 0x00000055); ++ if (ret) { ++ dev_err(dev, "Write Unlock key failed 1/2: %d\n", ret); ++ goto err_otp_unpack; ++ } ++ ret = regmap_write(regmap, CS35L41_TEST_KEY_CTL, 0x000000AA); ++ if (ret) { ++ dev_err(dev, "Write Unlock key failed 2/2: %d\n", ret); ++ goto err_otp_unpack; ++ } ++ ++ for (i = 0; i < otp_map_match->num_elements; i++) { ++ dev_dbg(dev, "bitoffset= %d, word_offset=%d, bit_sum mod 32=%d\n", ++ bit_offset, word_offset, bit_sum % 32); ++ if (bit_offset + otp_map[i].size - 1 >= 32) { ++ otp_val = (otp_mem[word_offset] & ++ GENMASK(31, bit_offset)) >> bit_offset; ++ otp_val |= (otp_mem[++word_offset] & ++ GENMASK(bit_offset + otp_map[i].size - 33, 0)) << ++ (32 - bit_offset); ++ bit_offset += otp_map[i].size - 32; ++ } else { ++ otp_val = (otp_mem[word_offset] & ++ GENMASK(bit_offset + otp_map[i].size - 1, bit_offset) ++ ) >> bit_offset; ++ bit_offset += otp_map[i].size; ++ } ++ bit_sum += otp_map[i].size; ++ ++ if (bit_offset == 32) { ++ bit_offset = 0; ++ word_offset++; ++ } ++ ++ if (otp_map[i].reg != 0) { ++ ret = regmap_update_bits(regmap, otp_map[i].reg, ++ GENMASK(otp_map[i].shift + otp_map[i].size - 1, ++ otp_map[i].shift), ++ otp_val << otp_map[i].shift); ++ if (ret < 0) { ++ dev_err(dev, "Write OTP val failed: %d\n", ret); ++ goto err_otp_unpack; ++ } ++ } ++ } ++ ++ ret = regmap_write(regmap, CS35L41_TEST_KEY_CTL, 0x000000CC); ++ if (ret) { ++ dev_err(dev, "Write Lock key failed 1/2: %d\n", ret); ++ goto err_otp_unpack; ++ } ++ ret = regmap_write(regmap, CS35L41_TEST_KEY_CTL, 0x00000033); ++ if (ret) { ++ dev_err(dev, "Write Lock key failed 2/2: %d\n", ret); ++ goto err_otp_unpack; ++ } ++ ret = 0; ++ ++err_otp_unpack: ++ kfree(otp_mem); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(cs35l41_otp_unpack); ++ + MODULE_DESCRIPTION("CS35L41 library"); + MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, "); + MODULE_AUTHOR("Lucas Tanure, Cirrus Logic Inc, "); +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index 60332eae1162..aa57c59b334d 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -14,7 +14,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -420,128 +419,6 @@ static const struct snd_kcontrol_new cs35l41_aud_controls[] = { + WM_ADSP_FW_CONTROL("DSP1", 0), + }; + +-static const struct cs35l41_otp_map_element_t *cs35l41_find_otp_map(u32 otp_id) +-{ +- int i; +- +- for (i = 0; i < ARRAY_SIZE(cs35l41_otp_map_map); i++) { +- if (cs35l41_otp_map_map[i].id == otp_id) +- return &cs35l41_otp_map_map[i]; +- } +- +- return NULL; +-} +- +-static int cs35l41_otp_unpack(void *data) +-{ +- const struct cs35l41_otp_map_element_t *otp_map_match; +- const struct cs35l41_otp_packed_element_t *otp_map; +- struct cs35l41_private *cs35l41 = data; +- int bit_offset, word_offset, ret, i; +- unsigned int bit_sum = 8; +- u32 otp_val, otp_id_reg; +- u32 *otp_mem; +- +- otp_mem = kmalloc_array(CS35L41_OTP_SIZE_WORDS, sizeof(*otp_mem), GFP_KERNEL); +- if (!otp_mem) +- return -ENOMEM; +- +- ret = regmap_read(cs35l41->regmap, CS35L41_OTPID, &otp_id_reg); +- if (ret < 0) { +- dev_err(cs35l41->dev, "Read OTP ID failed: %d\n", ret); +- goto err_otp_unpack; +- } +- +- otp_map_match = cs35l41_find_otp_map(otp_id_reg); +- +- if (!otp_map_match) { +- dev_err(cs35l41->dev, "OTP Map matching ID %d not found\n", +- otp_id_reg); +- ret = -EINVAL; +- goto err_otp_unpack; +- } +- +- ret = regmap_bulk_read(cs35l41->regmap, CS35L41_OTP_MEM0, otp_mem, +- CS35L41_OTP_SIZE_WORDS); +- if (ret < 0) { +- dev_err(cs35l41->dev, "Read OTP Mem failed: %d\n", ret); +- goto err_otp_unpack; +- } +- +- otp_map = otp_map_match->map; +- +- bit_offset = otp_map_match->bit_offset; +- word_offset = otp_map_match->word_offset; +- +- ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x00000055); +- if (ret < 0) { +- dev_err(cs35l41->dev, "Write Unlock key failed 1/2: %d\n", ret); +- goto err_otp_unpack; +- } +- ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x000000AA); +- if (ret < 0) { +- dev_err(cs35l41->dev, "Write Unlock key failed 2/2: %d\n", ret); +- goto err_otp_unpack; +- } +- +- for (i = 0; i < otp_map_match->num_elements; i++) { +- dev_dbg(cs35l41->dev, +- "bitoffset= %d, word_offset=%d, bit_sum mod 32=%d\n", +- bit_offset, word_offset, bit_sum % 32); +- if (bit_offset + otp_map[i].size - 1 >= 32) { +- otp_val = (otp_mem[word_offset] & +- GENMASK(31, bit_offset)) >> +- bit_offset; +- otp_val |= (otp_mem[++word_offset] & +- GENMASK(bit_offset + +- otp_map[i].size - 33, 0)) << +- (32 - bit_offset); +- bit_offset += otp_map[i].size - 32; +- } else { +- otp_val = (otp_mem[word_offset] & +- GENMASK(bit_offset + otp_map[i].size - 1, +- bit_offset)) >> bit_offset; +- bit_offset += otp_map[i].size; +- } +- bit_sum += otp_map[i].size; +- +- if (bit_offset == 32) { +- bit_offset = 0; +- word_offset++; +- } +- +- if (otp_map[i].reg != 0) { +- ret = regmap_update_bits(cs35l41->regmap, +- otp_map[i].reg, +- GENMASK(otp_map[i].shift + +- otp_map[i].size - 1, +- otp_map[i].shift), +- otp_val << otp_map[i].shift); +- if (ret < 0) { +- dev_err(cs35l41->dev, "Write OTP val failed: %d\n", +- ret); +- goto err_otp_unpack; +- } +- } +- } +- +- ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x000000CC); +- if (ret < 0) { +- dev_err(cs35l41->dev, "Write Lock key failed 1/2: %d\n", ret); +- goto err_otp_unpack; +- } +- ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x00000033); +- if (ret < 0) { +- dev_err(cs35l41->dev, "Write Lock key failed 2/2: %d\n", ret); +- goto err_otp_unpack; +- } +- ret = 0; +- +-err_otp_unpack: +- kfree(otp_mem); +- return ret; +-} +- + static irqreturn_t cs35l41_irq(int irq, void *data) + { + struct cs35l41_private *cs35l41 = data; +@@ -1667,7 +1544,7 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, + goto err; + } + +- ret = cs35l41_otp_unpack(cs35l41); ++ ret = cs35l41_otp_unpack(cs35l41->dev, cs35l41->regmap); + if (ret < 0) { + dev_err(cs35l41->dev, "OTP Unpack failed: %d\n", ret); + goto err; +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Move-cs35l41_set_cspl_mbox_cmd-to-share.patch b/patches.suse/ASoC-cs35l41-Move-cs35l41_set_cspl_mbox_cmd-to-share.patch new file mode 100644 index 0000000..1ea85dd --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Move-cs35l41_set_cspl_mbox_cmd-to-share.patch @@ -0,0 +1,258 @@ +From caf7c1f1de9f011ea0e6494fcb1b2ba203bd3422 Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Mon, 9 May 2022 22:46:43 +0100 +Subject: [PATCH] ASoC: cs35l41: Move cs35l41_set_cspl_mbox_cmd to shared code +Git-commit: caf7c1f1de9f011ea0e6494fcb1b2ba203bd3422 +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +This function is used to control the DSP Firmware for cs35l41, +and will be needed by the cs35l41 hda driver, when firmware +support is added. + +Signed-off-by: Stefan Binding +Signed-off-by: Vitaly Rodionov +Acked-by: Charles Keepax +Link: https://lore.kernel.org/r/20220509214703.4482-7-vitalyr@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + include/sound/cs35l41.h | 20 ++++++++++ + sound/soc/codecs/cs35l41-lib.c | 57 ++++++++++++++++++++++++++++ + sound/soc/codecs/cs35l41.c | 69 +++------------------------------- + sound/soc/codecs/cs35l41.h | 18 --------- + 4 files changed, 82 insertions(+), 82 deletions(-) + +diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h +index 8e4b125c81c8..2271471225b1 100644 +--- a/include/sound/cs35l41.h ++++ b/include/sound/cs35l41.h +@@ -801,6 +801,24 @@ struct cs35l41_otp_map_element_t { + u32 word_offset; + }; + ++enum cs35l41_cspl_mbox_status { ++ CSPL_MBOX_STS_RUNNING = 0, ++ CSPL_MBOX_STS_PAUSED = 1, ++ CSPL_MBOX_STS_RDY_FOR_REINIT = 2, ++}; ++ ++enum cs35l41_cspl_mbox_cmd { ++ CSPL_MBOX_CMD_NONE = 0, ++ CSPL_MBOX_CMD_PAUSE = 1, ++ CSPL_MBOX_CMD_RESUME = 2, ++ CSPL_MBOX_CMD_REINIT = 3, ++ CSPL_MBOX_CMD_STOP_PRE_REINIT = 4, ++ CSPL_MBOX_CMD_HIBERNATE = 5, ++ CSPL_MBOX_CMD_OUT_OF_HIBERNATE = 6, ++ CSPL_MBOX_CMD_UNKNOWN_CMD = -1, ++ CSPL_MBOX_CMD_INVALID_SEQUENCE = -2, ++}; ++ + /* + * IRQs + */ +@@ -859,6 +877,8 @@ int cs35l41_set_channels(struct device *dev, struct regmap *reg, + unsigned int tx_num, unsigned int *tx_slot, + unsigned int rx_num, unsigned int *rx_slot); + int cs35l41_gpio_config(struct regmap *regmap, struct cs35l41_hw_cfg *hw_cfg); ++int cs35l41_set_cspl_mbox_cmd(struct device *dev, struct regmap *regmap, ++ enum cs35l41_cspl_mbox_cmd cmd); + int cs35l41_init_boost(struct device *dev, struct regmap *regmap, + struct cs35l41_hw_cfg *hw_cfg); + bool cs35l41_safe_reset(struct regmap *regmap, enum cs35l41_boost_type b_type); +diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c +index 491616c7c5c7..451d3be37157 100644 +--- a/sound/soc/codecs/cs35l41-lib.c ++++ b/sound/soc/codecs/cs35l41-lib.c +@@ -1206,6 +1206,63 @@ int cs35l41_gpio_config(struct regmap *regmap, struct cs35l41_hw_cfg *hw_cfg) + } + EXPORT_SYMBOL_GPL(cs35l41_gpio_config); + ++static bool cs35l41_check_cspl_mbox_sts(enum cs35l41_cspl_mbox_cmd cmd, ++ enum cs35l41_cspl_mbox_status sts) ++{ ++ switch (cmd) { ++ case CSPL_MBOX_CMD_NONE: ++ case CSPL_MBOX_CMD_UNKNOWN_CMD: ++ return true; ++ case CSPL_MBOX_CMD_PAUSE: ++ case CSPL_MBOX_CMD_OUT_OF_HIBERNATE: ++ return (sts == CSPL_MBOX_STS_PAUSED); ++ case CSPL_MBOX_CMD_RESUME: ++ return (sts == CSPL_MBOX_STS_RUNNING); ++ case CSPL_MBOX_CMD_REINIT: ++ return (sts == CSPL_MBOX_STS_RUNNING); ++ case CSPL_MBOX_CMD_STOP_PRE_REINIT: ++ return (sts == CSPL_MBOX_STS_RDY_FOR_REINIT); ++ default: ++ return false; ++ } ++} ++ ++int cs35l41_set_cspl_mbox_cmd(struct device *dev, struct regmap *regmap, ++ enum cs35l41_cspl_mbox_cmd cmd) ++{ ++ unsigned int sts = 0, i; ++ int ret; ++ ++ // Set mailbox cmd ++ ret = regmap_write(regmap, CS35L41_DSP_VIRT1_MBOX_1, cmd); ++ if (ret < 0) { ++ if (cmd != CSPL_MBOX_CMD_OUT_OF_HIBERNATE) ++ dev_err(dev, "Failed to write MBOX: %d\n", ret); ++ return ret; ++ } ++ ++ // Read mailbox status and verify it is appropriate for the given cmd ++ for (i = 0; i < 5; i++) { ++ usleep_range(1000, 1100); ++ ++ ret = regmap_read(regmap, CS35L41_DSP_MBOX_2, &sts); ++ if (ret < 0) { ++ dev_err(dev, "Failed to read MBOX STS: %d\n", ret); ++ continue; ++ } ++ ++ if (!cs35l41_check_cspl_mbox_sts(cmd, sts)) ++ dev_dbg(dev, "[%u] cmd %u returned invalid sts %u", i, cmd, sts); ++ else ++ return 0; ++ } ++ ++ dev_err(dev, "Failed to set mailbox cmd %u (status %u)\n", cmd, sts); ++ ++ return -ENOMSG; ++} ++EXPORT_SYMBOL_GPL(cs35l41_set_cspl_mbox_cmd); ++ + MODULE_DESCRIPTION("CS35L41 library"); + MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, "); + MODULE_AUTHOR("Lucas Tanure, Cirrus Logic Inc, "); +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index 912196f45648..0285946688f7 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -208,67 +208,6 @@ static int cs35l41_dsp_preload_ev(struct snd_soc_dapm_widget *w, + } + } + +-static bool cs35l41_check_cspl_mbox_sts(enum cs35l41_cspl_mbox_cmd cmd, +- enum cs35l41_cspl_mbox_status sts) +-{ +- switch (cmd) { +- case CSPL_MBOX_CMD_NONE: +- case CSPL_MBOX_CMD_UNKNOWN_CMD: +- return true; +- case CSPL_MBOX_CMD_PAUSE: +- case CSPL_MBOX_CMD_OUT_OF_HIBERNATE: +- return (sts == CSPL_MBOX_STS_PAUSED); +- case CSPL_MBOX_CMD_RESUME: +- return (sts == CSPL_MBOX_STS_RUNNING); +- case CSPL_MBOX_CMD_REINIT: +- return (sts == CSPL_MBOX_STS_RUNNING); +- case CSPL_MBOX_CMD_STOP_PRE_REINIT: +- return (sts == CSPL_MBOX_STS_RDY_FOR_REINIT); +- default: +- return false; +- } +-} +- +-static int cs35l41_set_cspl_mbox_cmd(struct cs35l41_private *cs35l41, +- enum cs35l41_cspl_mbox_cmd cmd) +-{ +- unsigned int sts = 0, i; +- int ret; +- +- // Set mailbox cmd +- ret = regmap_write(cs35l41->regmap, CS35L41_DSP_VIRT1_MBOX_1, cmd); +- if (ret < 0) { +- if (cmd != CSPL_MBOX_CMD_OUT_OF_HIBERNATE) +- dev_err(cs35l41->dev, "Failed to write MBOX: %d\n", ret); +- return ret; +- } +- +- // Read mailbox status and verify it is appropriate for the given cmd +- for (i = 0; i < 5; i++) { +- usleep_range(1000, 1100); +- +- ret = regmap_read(cs35l41->regmap, CS35L41_DSP_MBOX_2, &sts); +- if (ret < 0) { +- dev_err(cs35l41->dev, "Failed to read MBOX STS: %d\n", ret); +- continue; +- } +- +- if (!cs35l41_check_cspl_mbox_sts(cmd, sts)) { +- dev_dbg(cs35l41->dev, +- "[%u] cmd %u returned invalid sts %u", +- i, cmd, sts); +- } else { +- return 0; +- } +- } +- +- dev_err(cs35l41->dev, +- "Failed to set mailbox cmd %u (status %u)\n", +- cmd, sts); +- +- return -ENOMSG; +-} +- + static int cs35l41_dsp_audio_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) + { +@@ -299,9 +238,11 @@ static int cs35l41_dsp_audio_ev(struct snd_soc_dapm_widget *w, + return -EINVAL; + } + +- return cs35l41_set_cspl_mbox_cmd(cs35l41, CSPL_MBOX_CMD_RESUME); ++ return cs35l41_set_cspl_mbox_cmd(cs35l41->dev, cs35l41->regmap, ++ CSPL_MBOX_CMD_RESUME); + case SND_SOC_DAPM_PRE_PMD: +- return cs35l41_set_cspl_mbox_cmd(cs35l41, CSPL_MBOX_CMD_PAUSE); ++ return cs35l41_set_cspl_mbox_cmd(cs35l41->dev, cs35l41->regmap, ++ CSPL_MBOX_CMD_PAUSE); + default: + return 0; + } +@@ -1475,7 +1416,7 @@ static int cs35l41_exit_hibernate(struct cs35l41_private *cs35l41) + dev_dbg(cs35l41->dev, "Exit hibernate\n"); + + for (j = 0; j < wake_retries; j++) { +- ret = cs35l41_set_cspl_mbox_cmd(cs35l41, ++ ret = cs35l41_set_cspl_mbox_cmd(cs35l41->dev, cs35l41->regmap, + CSPL_MBOX_CMD_OUT_OF_HIBERNATE); + if (!ret) + break; +diff --git a/sound/soc/codecs/cs35l41.h b/sound/soc/codecs/cs35l41.h +index e3369e0aa89f..c85cbc1dd333 100644 +--- a/sound/soc/codecs/cs35l41.h ++++ b/sound/soc/codecs/cs35l41.h +@@ -23,24 +23,6 @@ + + extern const struct dev_pm_ops cs35l41_pm_ops; + +-enum cs35l41_cspl_mbox_status { +- CSPL_MBOX_STS_RUNNING = 0, +- CSPL_MBOX_STS_PAUSED = 1, +- CSPL_MBOX_STS_RDY_FOR_REINIT = 2, +-}; +- +-enum cs35l41_cspl_mbox_cmd { +- CSPL_MBOX_CMD_NONE = 0, +- CSPL_MBOX_CMD_PAUSE = 1, +- CSPL_MBOX_CMD_RESUME = 2, +- CSPL_MBOX_CMD_REINIT = 3, +- CSPL_MBOX_CMD_STOP_PRE_REINIT = 4, +- CSPL_MBOX_CMD_HIBERNATE = 5, +- CSPL_MBOX_CMD_OUT_OF_HIBERNATE = 6, +- CSPL_MBOX_CMD_UNKNOWN_CMD = -1, +- CSPL_MBOX_CMD_INVALID_SEQUENCE = -2, +-}; +- + struct cs35l41_private { + struct wm_adsp dsp; /* needs to be first member */ + struct snd_soc_codec *codec; +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Move-cs_dsp-config-struct-into-shared-c.patch b/patches.suse/ASoC-cs35l41-Move-cs_dsp-config-struct-into-shared-c.patch new file mode 100644 index 0000000..3141fb9 --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Move-cs_dsp-config-struct-into-shared-c.patch @@ -0,0 +1,127 @@ +From 0db99577c4cddc45447701aeb7b4d7d7b03d626f Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Mon, 9 May 2022 22:46:45 +0100 +Subject: [PATCH] ASoC: cs35l41: Move cs_dsp config struct into shared code +Git-commit: 0db99577c4cddc45447701aeb7b4d7d7b03d626f +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +This can then be used by HDA code to configure cs_dsp. + +Signed-off-by: Stefan Binding +Signed-off-by: Vitaly Rodionov +Acked-by: Charles Keepax +Link: https://lore.kernel.org/r/20220509214703.4482-9-vitalyr@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + include/sound/cs35l41.h | 2 ++ + sound/soc/codecs/cs35l41-lib.c | 24 ++++++++++++++++++++++++ + sound/soc/codecs/cs35l41.c | 20 ++------------------ + 3 files changed, 28 insertions(+), 18 deletions(-) + +diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h +index d0cfb41495b0..dd70fb8dd860 100644 +--- a/include/sound/cs35l41.h ++++ b/include/sound/cs35l41.h +@@ -11,6 +11,7 @@ + #define __CS35L41_H + + #include ++#include + + #define CS35L41_FIRSTREG 0x00000000 + #define CS35L41_LASTREG 0x03804FE8 +@@ -877,6 +878,7 @@ int cs35l41_set_channels(struct device *dev, struct regmap *reg, + unsigned int tx_num, unsigned int *tx_slot, + unsigned int rx_num, unsigned int *rx_slot); + int cs35l41_gpio_config(struct regmap *regmap, struct cs35l41_hw_cfg *hw_cfg); ++void cs35l41_configure_cs_dsp(struct device *dev, struct regmap *reg, struct cs_dsp *dsp); + int cs35l41_set_cspl_mbox_cmd(struct device *dev, struct regmap *regmap, + enum cs35l41_cspl_mbox_cmd cmd); + int cs35l41_write_fs_errata(struct device *dev, struct regmap *regmap); +diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c +index 85fe5f88d6b4..37ae8ddccac9 100644 +--- a/sound/soc/codecs/cs35l41-lib.c ++++ b/sound/soc/codecs/cs35l41-lib.c +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + + #include + +@@ -1225,6 +1226,29 @@ int cs35l41_gpio_config(struct regmap *regmap, struct cs35l41_hw_cfg *hw_cfg) + } + EXPORT_SYMBOL_GPL(cs35l41_gpio_config); + ++static const struct cs_dsp_region cs35l41_dsp1_regions[] = { ++ { .type = WMFW_HALO_PM_PACKED, .base = CS35L41_DSP1_PMEM_0 }, ++ { .type = WMFW_HALO_XM_PACKED, .base = CS35L41_DSP1_XMEM_PACK_0 }, ++ { .type = WMFW_HALO_YM_PACKED, .base = CS35L41_DSP1_YMEM_PACK_0 }, ++ {. type = WMFW_ADSP2_XM, .base = CS35L41_DSP1_XMEM_UNPACK24_0}, ++ {. type = WMFW_ADSP2_YM, .base = CS35L41_DSP1_YMEM_UNPACK24_0}, ++}; ++ ++void cs35l41_configure_cs_dsp(struct device *dev, struct regmap *reg, struct cs_dsp *dsp) ++{ ++ dsp->num = 1; ++ dsp->type = WMFW_HALO; ++ dsp->rev = 0; ++ dsp->dev = dev; ++ dsp->regmap = reg; ++ dsp->base = CS35L41_DSP1_CTRL_BASE; ++ dsp->base_sysinfo = CS35L41_DSP1_SYS_ID; ++ dsp->mem = cs35l41_dsp1_regions; ++ dsp->num_mems = ARRAY_SIZE(cs35l41_dsp1_regions); ++ dsp->lock_regions = 0xFFFFFFFF; ++} ++EXPORT_SYMBOL_GPL(cs35l41_configure_cs_dsp); ++ + static bool cs35l41_check_cspl_mbox_sts(enum cs35l41_cspl_mbox_cmd cmd, + enum cs35l41_cspl_mbox_status sts) + { +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index 75527649bb14..5f0eca229dd3 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -680,14 +680,6 @@ static const struct snd_soc_dapm_route cs35l41_audio_map[] = { + {"CLASS H", NULL, "PCM Source"}, + }; + +-static const struct cs_dsp_region cs35l41_dsp1_regions[] = { +- { .type = WMFW_HALO_PM_PACKED, .base = CS35L41_DSP1_PMEM_0 }, +- { .type = WMFW_HALO_XM_PACKED, .base = CS35L41_DSP1_XMEM_PACK_0 }, +- { .type = WMFW_HALO_YM_PACKED, .base = CS35L41_DSP1_YMEM_PACK_0 }, +- {. type = WMFW_ADSP2_XM, .base = CS35L41_DSP1_XMEM_UNPACK24_0}, +- {. type = WMFW_ADSP2_YM, .base = CS35L41_DSP1_YMEM_UNPACK24_0}, +-}; +- + static int cs35l41_set_channel_map(struct snd_soc_dai *dai, unsigned int tx_n, + unsigned int *tx_slot, unsigned int rx_n, unsigned int *rx_slot) + { +@@ -1100,18 +1092,10 @@ static int cs35l41_dsp_init(struct cs35l41_private *cs35l41) + + dsp = &cs35l41->dsp; + dsp->part = "cs35l41"; +- dsp->cs_dsp.num = 1; +- dsp->cs_dsp.type = WMFW_HALO; +- dsp->cs_dsp.rev = 0; + dsp->fw = 9; /* 9 is WM_ADSP_FW_SPK_PROT in wm_adsp.c */ + dsp->toggle_preload = true; +- dsp->cs_dsp.dev = cs35l41->dev; +- dsp->cs_dsp.regmap = cs35l41->regmap; +- dsp->cs_dsp.base = CS35L41_DSP1_CTRL_BASE; +- dsp->cs_dsp.base_sysinfo = CS35L41_DSP1_SYS_ID; +- dsp->cs_dsp.mem = cs35l41_dsp1_regions; +- dsp->cs_dsp.num_mems = ARRAY_SIZE(cs35l41_dsp1_regions); +- dsp->cs_dsp.lock_regions = 0xFFFFFFFF; ++ ++ cs35l41_configure_cs_dsp(cs35l41->dev, cs35l41->regmap, &dsp->cs_dsp); + + ret = cs35l41_write_fs_errata(cs35l41->dev, cs35l41->regmap); + if (ret < 0) +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Move-power-initializations-to-reg_seque.patch b/patches.suse/ASoC-cs35l41-Move-power-initializations-to-reg_seque.patch new file mode 100644 index 0000000..7dc4273 --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Move-power-initializations-to-reg_seque.patch @@ -0,0 +1,101 @@ +From 062ce0593315e22aac527389dd6dd4328c49f0fb Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Fri, 17 Dec 2021 11:57:01 +0000 +Subject: [PATCH] ASoC: cs35l41: Move power initializations to reg_sequence +Git-commit: 062ce0593315e22aac527389dd6dd4328c49f0fb +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +ASoC and HDA systems for all revisions of CS35L41 will benefit +from having this initialization, so add it to reg_sequence of +each revision + +By moving to reg_sequence all gains are set to zero. And boost, +monitoring parts, and class D amplifier are disabled. + +Signed-off-by: Lucas Tanure +Link: https://lore.kernel.org/r/20211217115708.882525-4-tanureal@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs35l41-lib.c | 3 ++- + sound/soc/codecs/cs35l41.c | 20 ++++++-------------- + 2 files changed, 8 insertions(+), 15 deletions(-) + +diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c +index dc5f502447a2..b3567e10adc4 100644 +--- a/sound/soc/codecs/cs35l41-lib.c ++++ b/sound/soc/codecs/cs35l41-lib.c +@@ -17,6 +17,7 @@ + + static const struct reg_default cs35l41_reg[] = { + { CS35L41_PWR_CTRL1, 0x00000000 }, ++ { CS35L41_PWR_CTRL2, 0x00000000 }, + { CS35L41_PWR_CTRL3, 0x01000010 }, + { CS35L41_GPIO_PAD_CONTROL, 0x00000000 }, + { CS35L41_SP_ENABLES, 0x00000000 }, +@@ -46,7 +47,7 @@ static const struct reg_default cs35l41_reg[] = { + { CS35L41_CLASSH_CFG, 0x000B0405 }, + { CS35L41_WKFET_CFG, 0x00000111 }, + { CS35L41_NG_CFG, 0x00000033 }, +- { CS35L41_AMP_GAIN_CTRL, 0x00000273 }, ++ { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, + { CS35L41_GPIO1_CTRL1, 0xE1000001 }, + { CS35L41_GPIO2_CTRL1, 0xE1000001 }, + { CS35L41_MIXER_NGATE_CFG, 0x00000000 }, +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index aa57c59b334d..7494710ae6e6 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -1288,6 +1288,8 @@ static const struct reg_sequence cs35l41_reva0_errata_patch[] = { + { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, + { 0x00000040, 0x0000CCCC }, + { 0x00000040, 0x00003333 }, ++ { CS35L41_PWR_CTRL2, 0x00000000 }, ++ { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, + }; + + static const struct reg_sequence cs35l41_revb0_errata_patch[] = { +@@ -1301,6 +1303,8 @@ static const struct reg_sequence cs35l41_revb0_errata_patch[] = { + { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, + { 0x00000040, 0x0000CCCC }, + { 0x00000040, 0x00003333 }, ++ { CS35L41_PWR_CTRL2, 0x00000000 }, ++ { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, + }; + + static const struct reg_sequence cs35l41_revb2_errata_patch[] = { +@@ -1314,6 +1318,8 @@ static const struct reg_sequence cs35l41_revb2_errata_patch[] = { + { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, + { 0x00000040, 0x0000CCCC }, + { 0x00000040, 0x00003333 }, ++ { CS35L41_PWR_CTRL2, 0x00000000 }, ++ { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, + }; + + static const struct reg_sequence cs35l41_fs_errata_patch[] = { +@@ -1556,20 +1562,6 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, + goto err; + } + +- ret = regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, +- CS35L41_AMP_EN_MASK, 0); +- if (ret < 0) { +- dev_err(cs35l41->dev, "Write CS35L41_PWR_CTRL2 failed: %d\n", ret); +- goto err; +- } +- +- ret = regmap_update_bits(cs35l41->regmap, CS35L41_AMP_GAIN_CTRL, +- CS35L41_AMP_GAIN_PCM_MASK, 0); +- if (ret < 0) { +- dev_err(cs35l41->dev, "Write CS35L41_AMP_GAIN_CTRL failed: %d\n", ret); +- goto err; +- } +- + ret = cs35l41_set_pdata(cs35l41); + if (ret < 0) { + dev_err(cs35l41->dev, "Set pdata failed: %d\n", ret); +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Read-System-Name-from-ACPI-_SUB-to-iden.patch b/patches.suse/ASoC-cs35l41-Read-System-Name-from-ACPI-_SUB-to-iden.patch new file mode 100644 index 0000000..6aed4d3 --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Read-System-Name-from-ACPI-_SUB-to-iden.patch @@ -0,0 +1,89 @@ +From c1ad138822a1be95a7a7b122521c2415583a0c26 Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Thu, 7 Jul 2022 16:10:37 +0100 +Subject: [PATCH] ASoC: cs35l41: Read System Name from ACPI _SUB to identify firmware +Git-commit: c1ad138822a1be95a7a7b122521c2415583a0c26 +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +When loading firmware, wm_adsp uses a number of parameters to +determine the path of the firmware and tuning files to load. +One of these parameters is system_name. +Add support in cs35l41 to read this system name from the ACPI +_SUB ID in order to uniquely identify the firmware and tuning +mapped to a particular system. + +Signed-off-by: Stefan Binding +Link: https://lore.kernel.org/r/20220707151037.3901050-3-sbinding@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs35l41.c | 30 ++++++++++++++++++++++++++++++ + 1 file changed, 30 insertions(+) + +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index 8766e19d85f1..c223d83e02cf 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -6,6 +6,7 @@ + // + // Author: David Rhodes + ++#include + #include + #include + #include +@@ -1142,6 +1143,30 @@ static int cs35l41_dsp_init(struct cs35l41_private *cs35l41) + return ret; + } + ++static int cs35l41_acpi_get_name(struct cs35l41_private *cs35l41) ++{ ++ acpi_handle handle = ACPI_HANDLE(cs35l41->dev); ++ const char *sub; ++ ++ /* If there is no ACPI_HANDLE, there is no ACPI for this system, return 0 */ ++ if (!handle) ++ return 0; ++ ++ sub = acpi_get_subsystem_id(handle); ++ if (IS_ERR(sub)) { ++ /* If bad ACPI, return 0 and fallback to legacy firmware path, otherwise fail */ ++ if (PTR_ERR(sub) == -ENODATA) ++ return 0; ++ else ++ return PTR_ERR(sub); ++ } ++ ++ cs35l41->dsp.system_name = sub; ++ dev_dbg(cs35l41->dev, "Subsystem ID: %s\n", cs35l41->dsp.system_name); ++ ++ return 0; ++} ++ + int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg *hw_cfg) + { + u32 regid, reg_revid, i, mtl_revid, int_status, chipid_match; +@@ -1270,6 +1295,10 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg * + goto err; + } + ++ ret = cs35l41_acpi_get_name(cs35l41); ++ if (ret < 0) ++ goto err; ++ + ret = cs35l41_dsp_init(cs35l41); + if (ret < 0) + goto err; +@@ -1316,6 +1345,7 @@ void cs35l41_remove(struct cs35l41_private *cs35l41) + pm_runtime_disable(cs35l41->dev); + + regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, 0xFFFFFFFF); ++ kfree(cs35l41->dsp.system_name); + wm_adsp2_remove(&cs35l41->dsp); + cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type); + +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Remove-incorrect-comment.patch b/patches.suse/ASoC-cs35l41-Remove-incorrect-comment.patch new file mode 100644 index 0000000..d885245 --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Remove-incorrect-comment.patch @@ -0,0 +1,36 @@ +From 4e7c3cd87db8d9350062a25a8476f90fd1cbc4c9 Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Wed, 5 Jan 2022 11:30:20 +0000 +Subject: [PATCH] ASoC: cs35l41: Remove incorrect comment +Git-commit: 4e7c3cd87db8d9350062a25a8476f90fd1cbc4c9 +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +The IRQ is not used for the PDN_DONE bit, this is polled during the DAPM +sequence, remove the misleading comment. + +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20220105113026.18955-3-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs35l41.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index d9e6e84e64d0..980294c1bcdb 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -1338,8 +1338,6 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, + ret = devm_request_threaded_irq(cs35l41->dev, cs35l41->irq, NULL, cs35l41_irq, + IRQF_ONESHOT | IRQF_SHARED | irq_pol, + "cs35l41", cs35l41); +- +- /* CS35L41 needs INT for PDN_DONE */ + if (ret != 0) { + dev_err(cs35l41->dev, "Failed to request IRQ: %d\n", ret); + goto err; +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Remove-unnecessary-param.patch b/patches.suse/ASoC-cs35l41-Remove-unnecessary-param.patch new file mode 100644 index 0000000..c249113 --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Remove-unnecessary-param.patch @@ -0,0 +1,47 @@ +From 139cad4bde675552466da5af61b4686da9fc8008 Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Fri, 4 Mar 2022 15:07:05 +0000 +Subject: [PATCH] ASoC: cs35l41: Remove unnecessary param +Git-commit: 139cad4bde675552466da5af61b4686da9fc8008 +Patch-mainline: v5.18-rc1 +References: bsc#1203699 + +cs35l41_private is not used on cs35l41_handle_pdata + +Signed-off-by: Lucas Tanure +Acked-by: Charles Keepax +Link: https://lore.kernel.org/r/20220304150721.3802-5-tanureal@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs35l41.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index c90722b657c0..e10d1276a937 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -1115,9 +1115,7 @@ static const struct snd_soc_component_driver soc_component_dev_cs35l41 = { + .set_sysclk = cs35l41_component_set_sysclk, + }; + +-static int cs35l41_handle_pdata(struct device *dev, +- struct cs35l41_platform_data *pdata, +- struct cs35l41_private *cs35l41) ++static int cs35l41_handle_pdata(struct device *dev, struct cs35l41_platform_data *pdata) + { + struct cs35l41_irq_cfg *irq_gpio1_config = &pdata->irq_config1; + struct cs35l41_irq_cfg *irq_gpio2_config = &pdata->irq_config2; +@@ -1260,7 +1258,7 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, + if (pdata) { + cs35l41->pdata = *pdata; + } else { +- ret = cs35l41_handle_pdata(cs35l41->dev, &cs35l41->pdata, cs35l41); ++ ret = cs35l41_handle_pdata(cs35l41->dev, &cs35l41->pdata); + if (ret != 0) + return ret; + } +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Set-the-max-SPI-speed-for-the-whole-dev.patch b/patches.suse/ASoC-cs35l41-Set-the-max-SPI-speed-for-the-whole-dev.patch new file mode 100644 index 0000000..3300ef9 --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Set-the-max-SPI-speed-for-the-whole-dev.patch @@ -0,0 +1,146 @@ +From 872fc0b6bde8b2dd6891c740cd792d214255dca3 Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Tue, 23 Nov 2021 16:31:39 +0000 +Subject: [PATCH] ASoC: cs35l41: Set the max SPI speed for the whole device +Git-commit: 872fc0b6bde8b2dd6891c740cd792d214255dca3 +Patch-mainline: v5.16-rc4 +References: bsc#1203699 + +Higher speeds are only supported when PLL is enabled, but +the current driver doesn't enable PLL outside of stream +use cases, so better to set the lowest SPI speed accepted +by the entire device. + +Move the current frequency set to the spi sub-driver so +the whole device can benefit from that speed. + +spi-max-frequency property could be used, but ACPI systems don't +support it, so by setting it in the spi sub-driver probe +both Device Trees and ACPI systems are supported. + +Signed-off-by: Lucas Tanure +Reviewed-by: Charles Keepax +Link: https://lore.kernel.org/r/20211123163149.1530535-2-tanureal@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs35l41-spi.c | 32 +++----------------------------- + sound/soc/codecs/cs35l41.c | 7 ------- + sound/soc/codecs/cs35l41.h | 4 +--- + 3 files changed, 4 insertions(+), 39 deletions(-) + +diff --git a/sound/soc/codecs/cs35l41-spi.c b/sound/soc/codecs/cs35l41-spi.c +index 90a921f726c3..3fa99741779a 100644 +--- a/sound/soc/codecs/cs35l41-spi.c ++++ b/sound/soc/codecs/cs35l41-spi.c +@@ -42,34 +42,6 @@ static const struct spi_device_id cs35l41_id_spi[] = { + + MODULE_DEVICE_TABLE(spi, cs35l41_id_spi); + +-static void cs35l41_spi_otp_setup(struct cs35l41_private *cs35l41, +- bool is_pre_setup, unsigned int *freq) +-{ +- struct spi_device *spi; +- u32 orig_spi_freq; +- +- spi = to_spi_device(cs35l41->dev); +- +- if (!spi) { +- dev_err(cs35l41->dev, "%s: No SPI device\n", __func__); +- return; +- } +- +- if (is_pre_setup) { +- orig_spi_freq = spi->max_speed_hz; +- if (orig_spi_freq > CS35L41_SPI_MAX_FREQ_OTP) { +- spi->max_speed_hz = CS35L41_SPI_MAX_FREQ_OTP; +- spi_setup(spi); +- } +- *freq = orig_spi_freq; +- } else { +- if (spi->max_speed_hz != *freq) { +- spi->max_speed_hz = *freq; +- spi_setup(spi); +- } +- } +-} +- + static int cs35l41_spi_probe(struct spi_device *spi) + { + const struct regmap_config *regmap_config = &cs35l41_regmap_spi; +@@ -81,6 +53,9 @@ static int cs35l41_spi_probe(struct spi_device *spi) + if (!cs35l41) + return -ENOMEM; + ++ spi->max_speed_hz = CS35L41_SPI_MAX_FREQ; ++ spi_setup(spi); ++ + spi_set_drvdata(spi, cs35l41); + cs35l41->regmap = devm_regmap_init_spi(spi, regmap_config); + if (IS_ERR(cs35l41->regmap)) { +@@ -91,7 +66,6 @@ static int cs35l41_spi_probe(struct spi_device *spi) + + cs35l41->dev = &spi->dev; + cs35l41->irq = spi->irq; +- cs35l41->otp_setup = cs35l41_spi_otp_setup; + + return cs35l41_probe(cs35l41, pdata); + } +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index 9d0530dde996..9c4d481f7614 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -302,7 +302,6 @@ static int cs35l41_otp_unpack(void *data) + const struct cs35l41_otp_packed_element_t *otp_map; + struct cs35l41_private *cs35l41 = data; + int bit_offset, word_offset, ret, i; +- unsigned int orig_spi_freq; + unsigned int bit_sum = 8; + u32 otp_val, otp_id_reg; + u32 *otp_mem; +@@ -326,9 +325,6 @@ static int cs35l41_otp_unpack(void *data) + goto err_otp_unpack; + } + +- if (cs35l41->otp_setup) +- cs35l41->otp_setup(cs35l41, true, &orig_spi_freq); +- + ret = regmap_bulk_read(cs35l41->regmap, CS35L41_OTP_MEM0, otp_mem, + CS35L41_OTP_SIZE_WORDS); + if (ret < 0) { +@@ -336,9 +332,6 @@ static int cs35l41_otp_unpack(void *data) + goto err_otp_unpack; + } + +- if (cs35l41->otp_setup) +- cs35l41->otp_setup(cs35l41, false, &orig_spi_freq); +- + otp_map = otp_map_match->map; + + bit_offset = otp_map_match->bit_offset; +diff --git a/sound/soc/codecs/cs35l41.h b/sound/soc/codecs/cs35l41.h +index 6cffe8a55beb..48485b08a6f1 100644 +--- a/sound/soc/codecs/cs35l41.h ++++ b/sound/soc/codecs/cs35l41.h +@@ -726,7 +726,7 @@ + #define CS35L41_FS2_WINDOW_MASK 0x00FFF800 + #define CS35L41_FS2_WINDOW_SHIFT 12 + +-#define CS35L41_SPI_MAX_FREQ_OTP 4000000 ++#define CS35L41_SPI_MAX_FREQ 4000000 + + #define CS35L41_RX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) + #define CS35L41_TX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) +@@ -764,8 +764,6 @@ struct cs35l41_private { + int irq; + /* GPIO for /RST */ + struct gpio_desc *reset_gpio; +- void (*otp_setup)(struct cs35l41_private *cs35l41, bool is_pre_setup, +- unsigned int *freq); + }; + + int cs35l41_probe(struct cs35l41_private *cs35l41, +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Support-external-boost.patch b/patches.suse/ASoC-cs35l41-Support-external-boost.patch new file mode 100644 index 0000000..6ad5ebf --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Support-external-boost.patch @@ -0,0 +1,187 @@ +From bb06c203f86766fc2c37cbce0e20e9daae786f6e Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Wed, 13 Apr 2022 09:37:28 +0100 +Subject: [PATCH] ASoC: cs35l41: Support external boost +Git-commit: bb06c203f86766fc2c37cbce0e20e9daae786f6e +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +Add support for external boost voltage, where GPIO1 must control a +switch to isolate CS35L41 from the external Boost Voltage + +Signed-off-by: Lucas Tanure +Acked-by: Charles Keepax +Acked-by: Mark Brown +Link: https://lore.kernel.org/r/20220413083728.10730-17-tanureal@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + include/sound/cs35l41.h | 4 +-- + sound/soc/codecs/cs35l41-lib.c | 5 ++-- + sound/soc/codecs/cs35l41.c | 49 +++++++++++++++++++++++++--------- + 3 files changed, 41 insertions(+), 17 deletions(-) + +diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h +index ac629f852f2a..dbe8d9c0191b 100644 +--- a/include/sound/cs35l41.h ++++ b/include/sound/cs35l41.h +@@ -701,6 +701,8 @@ + #define CS35L41_GPIO1_CTRL_SHIFT 16 + #define CS35L41_GPIO2_CTRL_MASK 0x07000000 + #define CS35L41_GPIO2_CTRL_SHIFT 24 ++#define CS35L41_GPIO_LVL_SHIFT 15 ++#define CS35L41_GPIO_LVL_MASK BIT(CS35L41_GPIO_LVL_SHIFT) + #define CS35L41_GPIO_POL_MASK 0x1000 + #define CS35L41_GPIO_POL_SHIFT 12 + +@@ -802,8 +804,6 @@ int cs35l41_register_errata_patch(struct device *dev, struct regmap *reg, unsign + int cs35l41_set_channels(struct device *dev, struct regmap *reg, + unsigned int tx_num, unsigned int *tx_slot, + unsigned int rx_num, unsigned int *rx_slot); +-int cs35l41_boost_config(struct device *dev, struct regmap *regmap, int boost_ind, int boost_cap, +- int boost_ipk); + int cs35l41_gpio_config(struct regmap *regmap, struct cs35l41_hw_cfg *hw_cfg); + int cs35l41_init_boost(struct device *dev, struct regmap *regmap, + struct cs35l41_hw_cfg *hw_cfg); +diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c +index 2d3b577a63e3..491616c7c5c7 100644 +--- a/sound/soc/codecs/cs35l41-lib.c ++++ b/sound/soc/codecs/cs35l41-lib.c +@@ -954,8 +954,8 @@ static const unsigned char cs35l41_bst_slope_table[4] = { + 0x75, 0x6B, 0x3B, 0x28 + }; + +-int cs35l41_boost_config(struct device *dev, struct regmap *regmap, int boost_ind, +- int boost_cap, int boost_ipk) ++static int cs35l41_boost_config(struct device *dev, struct regmap *regmap, int boost_ind, ++ int boost_cap, int boost_ipk) + { + unsigned char bst_lbst_val, bst_cbst_range, bst_ipk_scaled; + int ret; +@@ -1040,7 +1040,6 @@ int cs35l41_boost_config(struct device *dev, struct regmap *regmap, int boost_in + + return 0; + } +-EXPORT_SYMBOL_GPL(cs35l41_boost_config); + + static const struct reg_sequence cs35l41_safe_to_reset[] = { + { 0x00000040, 0x00000055 }, +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index d25689fe0c60..912196f45648 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -578,15 +578,10 @@ static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w, + cs35l41_pup_patch, + ARRAY_SIZE(cs35l41_pup_patch)); + +- regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL1, +- CS35L41_GLOBAL_EN_MASK, +- 1 << CS35L41_GLOBAL_EN_SHIFT); +- +- usleep_range(1000, 1100); ++ cs35l41_global_enable(cs35l41->regmap, cs35l41->hw_cfg.bst_type, 1); + break; + case SND_SOC_DAPM_POST_PMD: +- regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL1, +- CS35L41_GLOBAL_EN_MASK, 0); ++ cs35l41_global_enable(cs35l41->regmap, cs35l41->hw_cfg.bst_type, 0); + + ret = regmap_read_poll_timeout(cs35l41->regmap, CS35L41_IRQ1_STATUS1, + val, val & CS35L41_PDN_DONE_MASK, +@@ -1001,13 +996,13 @@ static int cs35l41_set_pdata(struct cs35l41_private *cs35l41) + if (!hw_cfg->valid) + return -EINVAL; + ++ if (hw_cfg->bst_type == CS35L41_EXT_BOOST_NO_VSPK_SWITCH) ++ return -EINVAL; ++ + /* Required */ +- ret = cs35l41_boost_config(cs35l41->dev, cs35l41->regmap, +- hw_cfg->bst_ind, hw_cfg->bst_cap, hw_cfg->bst_ipk); +- if (ret) { +- dev_err(cs35l41->dev, "Error in Boost DT config: %d\n", ret); ++ ret = cs35l41_init_boost(cs35l41->dev, cs35l41->regmap, hw_cfg); ++ if (ret) + return ret; +- } + + /* Optional */ + if (hw_cfg->dout_hiz <= CS35L41_ASP_DOUT_HIZ_MASK && hw_cfg->dout_hiz >= 0) +@@ -1017,9 +1012,31 @@ static int cs35l41_set_pdata(struct cs35l41_private *cs35l41) + return 0; + } + ++static const struct snd_soc_dapm_route cs35l41_ext_bst_routes[] = { ++ {"Main AMP", NULL, "VSPK"}, ++}; ++ ++static const struct snd_soc_dapm_widget cs35l41_ext_bst_widget[] = { ++ SND_SOC_DAPM_SUPPLY("VSPK", CS35L41_GPIO1_CTRL1, CS35L41_GPIO_LVL_SHIFT, 0, NULL, 0), ++}; ++ + static int cs35l41_component_probe(struct snd_soc_component *component) + { + struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component); ++ struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); ++ int ret; ++ ++ if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST) { ++ ret = snd_soc_dapm_new_controls(dapm, cs35l41_ext_bst_widget, ++ ARRAY_SIZE(cs35l41_ext_bst_widget)); ++ if (ret) ++ return ret; ++ ++ ret = snd_soc_dapm_add_routes(dapm, cs35l41_ext_bst_routes, ++ ARRAY_SIZE(cs35l41_ext_bst_routes)); ++ if (ret) ++ return ret; ++ } + + return wm_adsp2_component_probe(&cs35l41->dsp, component); + } +@@ -1084,6 +1101,10 @@ static int cs35l41_handle_pdata(struct device *dev, struct cs35l41_hw_cfg *hw_cf + unsigned int val; + int ret; + ++ ret = device_property_read_u32(dev, "cirrus,boost-type", &val); ++ if (ret >= 0) ++ hw_cfg->bst_type = val; ++ + ret = device_property_read_u32(dev, "cirrus,boost-peak-milliamp", &val); + if (ret >= 0) + hw_cfg->bst_ipk = val; +@@ -1376,6 +1397,7 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg * + + wm_adsp2_remove(&cs35l41->dsp); + err: ++ cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type); + regulator_bulk_disable(CS35L41_NUM_SUPPLIES, cs35l41->supplies); + gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); + +@@ -1390,6 +1412,7 @@ void cs35l41_remove(struct cs35l41_private *cs35l41) + + regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, 0xFFFFFFFF); + wm_adsp2_remove(&cs35l41->dsp); ++ cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type); + + pm_runtime_put_noidle(cs35l41->dev); + +@@ -1409,6 +1432,7 @@ static int __maybe_unused cs35l41_runtime_suspend(struct device *dev) + + dev_dbg(cs35l41->dev, "Enter hibernate\n"); + ++ cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type); + regmap_write(cs35l41->regmap, CS35L41_WAKESRC_CTL, 0x0088); + regmap_write(cs35l41->regmap, CS35L41_WAKESRC_CTL, 0x0188); + +@@ -1505,6 +1529,7 @@ static int __maybe_unused cs35l41_runtime_resume(struct device *dev) + dev_err(cs35l41->dev, "Failed to restore register cache: %d\n", ret); + return ret; + } ++ cs35l41_init_boost(cs35l41->dev, cs35l41->regmap, &cs35l41->hw_cfg); + + return 0; + } +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Update-handling-of-test-key-registers.patch b/patches.suse/ASoC-cs35l41-Update-handling-of-test-key-registers.patch new file mode 100644 index 0000000..f5158ad --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Update-handling-of-test-key-registers.patch @@ -0,0 +1,245 @@ +From d92321bbe46b0ecae0941461379d39599610d869 Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Fri, 7 Jan 2022 16:06:35 +0000 +Subject: [PATCH] ASoC: cs35l41: Update handling of test key registers +Git-commit: d92321bbe46b0ecae0941461379d39599610d869 +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +In preparation for the addition of PM runtime support move the test +key out of the register patches themselves. This is necessary to +allow the test key to be held during cache synchronisation, which is +required by the OTP settings which were unpacked from the device and +written by the driver. + +Also whilst at it, the driver uses a mixture of accessing the test key +register by name and by address, consistently use the name. + +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20220107160636.6555-2-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + include/sound/cs35l41.h | 2 + + sound/soc/codecs/cs35l41-lib.c | 67 +++++++++++++++++----------------- + sound/soc/codecs/cs35l41.c | 32 +++++++++------- + 3 files changed, 54 insertions(+), 47 deletions(-) + +diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h +index 29a527457b48..56289b67b9a0 100644 +--- a/include/sound/cs35l41.h ++++ b/include/sound/cs35l41.h +@@ -762,6 +762,8 @@ struct cs35l41_otp_map_element_t { + extern struct regmap_config cs35l41_regmap_i2c; + extern struct regmap_config cs35l41_regmap_spi; + ++int cs35l41_test_key_unlock(struct device *dev, struct regmap *regmap); ++int cs35l41_test_key_lock(struct device *dev, struct regmap *regmap); + int cs35l41_otp_unpack(struct device *dev, struct regmap *regmap); + int cs35l41_register_errata_patch(struct device *dev, struct regmap *reg, unsigned int reg_revid); + int cs35l41_set_channels(struct device *dev, struct regmap *reg, +diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c +index 639dcd25b17e..ecaf67fd7653 100644 +--- a/sound/soc/codecs/cs35l41-lib.c ++++ b/sound/soc/codecs/cs35l41-lib.c +@@ -623,8 +623,6 @@ static const struct cs35l41_otp_packed_element_t otp_map_2[CS35L41_NUM_OTP_ELEM] + }; + + static const struct reg_sequence cs35l41_reva0_errata_patch[] = { +- { 0x00000040, 0x00005555 }, +- { 0x00000040, 0x0000AAAA }, + { 0x00003854, 0x05180240 }, + { CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 }, + { 0x00004310, 0x00000000 }, +@@ -637,38 +635,28 @@ static const struct reg_sequence cs35l41_reva0_errata_patch[] = { + { CS35L41_IRQ2_DB3, 0x00000000 }, + { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 }, + { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, +- { 0x00000040, 0x0000CCCC }, +- { 0x00000040, 0x00003333 }, + { CS35L41_PWR_CTRL2, 0x00000000 }, + { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, + }; + + static const struct reg_sequence cs35l41_revb0_errata_patch[] = { +- { 0x00000040, 0x00005555 }, +- { 0x00000040, 0x0000AAAA }, + { CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 }, + { 0x00004310, 0x00000000 }, + { CS35L41_VPVBST_FS_SEL, 0x00000000 }, + { CS35L41_BSTCVRT_DCM_CTRL, 0x00000051 }, + { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 }, + { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, +- { 0x00000040, 0x0000CCCC }, +- { 0x00000040, 0x00003333 }, + { CS35L41_PWR_CTRL2, 0x00000000 }, + { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, + }; + + static const struct reg_sequence cs35l41_revb2_errata_patch[] = { +- { 0x00000040, 0x00005555 }, +- { 0x00000040, 0x0000AAAA }, + { CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 }, + { 0x00004310, 0x00000000 }, + { CS35L41_VPVBST_FS_SEL, 0x00000000 }, + { CS35L41_BSTCVRT_DCM_CTRL, 0x00000051 }, + { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 }, + { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, +- { 0x00000040, 0x0000CCCC }, +- { 0x00000040, 0x00003333 }, + { CS35L41_PWR_CTRL2, 0x00000000 }, + { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, + }; +@@ -756,6 +744,39 @@ static const struct cs35l41_otp_map_element_t *cs35l41_find_otp_map(u32 otp_id) + return NULL; + } + ++int cs35l41_test_key_unlock(struct device *dev, struct regmap *regmap) ++{ ++ static const struct reg_sequence unlock[] = { ++ { CS35L41_TEST_KEY_CTL, 0x00000055 }, ++ { CS35L41_TEST_KEY_CTL, 0x000000AA }, ++ }; ++ int ret; ++ ++ ret = regmap_multi_reg_write(regmap, unlock, ARRAY_SIZE(unlock)); ++ if (ret) ++ dev_err(dev, "Failed to unlock test key: %d\n", ret); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(cs35l41_test_key_unlock); ++ ++int cs35l41_test_key_lock(struct device *dev, struct regmap *regmap) ++{ ++ static const struct reg_sequence unlock[] = { ++ { CS35L41_TEST_KEY_CTL, 0x000000CC }, ++ { CS35L41_TEST_KEY_CTL, 0x00000033 }, ++ }; ++ int ret; ++ ++ ret = regmap_multi_reg_write(regmap, unlock, ARRAY_SIZE(unlock)); ++ if (ret) ++ dev_err(dev, "Failed to lock test key: %d\n", ret); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(cs35l41_test_key_lock); ++ ++/* Must be called with the TEST_KEY unlocked */ + int cs35l41_otp_unpack(struct device *dev, struct regmap *regmap) + { + const struct cs35l41_otp_map_element_t *otp_map_match; +@@ -794,17 +815,6 @@ int cs35l41_otp_unpack(struct device *dev, struct regmap *regmap) + bit_offset = otp_map_match->bit_offset; + word_offset = otp_map_match->word_offset; + +- ret = regmap_write(regmap, CS35L41_TEST_KEY_CTL, 0x00000055); +- if (ret) { +- dev_err(dev, "Write Unlock key failed 1/2: %d\n", ret); +- goto err_otp_unpack; +- } +- ret = regmap_write(regmap, CS35L41_TEST_KEY_CTL, 0x000000AA); +- if (ret) { +- dev_err(dev, "Write Unlock key failed 2/2: %d\n", ret); +- goto err_otp_unpack; +- } +- + for (i = 0; i < otp_map_match->num_elements; i++) { + dev_dbg(dev, "bitoffset= %d, word_offset=%d, bit_sum mod 32=%d\n", + bit_offset, word_offset, bit_sum % 32); +@@ -840,16 +850,6 @@ int cs35l41_otp_unpack(struct device *dev, struct regmap *regmap) + } + } + +- ret = regmap_write(regmap, CS35L41_TEST_KEY_CTL, 0x000000CC); +- if (ret) { +- dev_err(dev, "Write Lock key failed 1/2: %d\n", ret); +- goto err_otp_unpack; +- } +- ret = regmap_write(regmap, CS35L41_TEST_KEY_CTL, 0x00000033); +- if (ret) { +- dev_err(dev, "Write Lock key failed 2/2: %d\n", ret); +- goto err_otp_unpack; +- } + ret = 0; + + err_otp_unpack: +@@ -859,6 +859,7 @@ int cs35l41_otp_unpack(struct device *dev, struct regmap *regmap) + } + EXPORT_SYMBOL_GPL(cs35l41_otp_unpack); + ++/* Must be called with the TEST_KEY unlocked */ + int cs35l41_register_errata_patch(struct device *dev, struct regmap *reg, unsigned int reg_revid) + { + char *rev; +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index 05839fabf97b..e1b9fd8ee996 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -534,19 +534,19 @@ static irqreturn_t cs35l41_irq(int irq, void *data) + } + + static const struct reg_sequence cs35l41_pup_patch[] = { +- { 0x00000040, 0x00000055 }, +- { 0x00000040, 0x000000AA }, ++ { CS35L41_TEST_KEY_CTL, 0x00000055 }, ++ { CS35L41_TEST_KEY_CTL, 0x000000AA }, + { 0x00002084, 0x002F1AA0 }, +- { 0x00000040, 0x000000CC }, +- { 0x00000040, 0x00000033 }, ++ { CS35L41_TEST_KEY_CTL, 0x000000CC }, ++ { CS35L41_TEST_KEY_CTL, 0x00000033 }, + }; + + static const struct reg_sequence cs35l41_pdn_patch[] = { +- { 0x00000040, 0x00000055 }, +- { 0x00000040, 0x000000AA }, ++ { CS35L41_TEST_KEY_CTL, 0x00000055 }, ++ { CS35L41_TEST_KEY_CTL, 0x000000AA }, + { 0x00002084, 0x002F1AA3 }, +- { 0x00000040, 0x000000CC }, +- { 0x00000040, 0x00000033 }, ++ { CS35L41_TEST_KEY_CTL, 0x000000CC }, ++ { CS35L41_TEST_KEY_CTL, 0x00000033 }, + }; + + static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w, +@@ -1329,10 +1329,20 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, + goto err; + } + ++ cs35l41_test_key_unlock(cs35l41->dev, cs35l41->regmap); ++ + ret = cs35l41_register_errata_patch(cs35l41->dev, cs35l41->regmap, reg_revid); + if (ret) + goto err; + ++ ret = cs35l41_otp_unpack(cs35l41->dev, cs35l41->regmap); ++ if (ret < 0) { ++ dev_err(cs35l41->dev, "OTP Unpack failed: %d\n", ret); ++ goto err; ++ } ++ ++ cs35l41_test_key_lock(cs35l41->dev, cs35l41->regmap); ++ + irq_pol = cs35l41_irq_gpio_config(cs35l41); + + /* Set interrupt masks for critical errors */ +@@ -1347,12 +1357,6 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, + goto err; + } + +- ret = cs35l41_otp_unpack(cs35l41->dev, cs35l41->regmap); +- if (ret < 0) { +- dev_err(cs35l41->dev, "OTP Unpack failed: %d\n", ret); +- goto err; +- } +- + ret = cs35l41_set_pdata(cs35l41); + if (ret < 0) { + dev_err(cs35l41->dev, "Set pdata failed: %d\n", ret); +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs35l41-Use-regmap_read_poll_timeout-to-wait-fo.patch b/patches.suse/ASoC-cs35l41-Use-regmap_read_poll_timeout-to-wait-fo.patch new file mode 100644 index 0000000..4a578a0 --- /dev/null +++ b/patches.suse/ASoC-cs35l41-Use-regmap_read_poll_timeout-to-wait-fo.patch @@ -0,0 +1,62 @@ +From 3a2eb0b4b02060340af10a1db3c452472471be2f Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Tue, 14 Sep 2021 15:13:45 +0100 +Subject: [PATCH] ASoC: cs35l41: Use regmap_read_poll_timeout to wait for OTP boot +Git-commit: 3a2eb0b4b02060340af10a1db3c452472471be2f +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +Just clean up the code a little by using the helper rather than open +coding waiting for OTP_BOOT_DONE. + +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20210914141349.30218-2-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs35l41.c | 21 ++++++++------------- + 1 file changed, 8 insertions(+), 13 deletions(-) + +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index d2a11cc33683..8c2c695813cd 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -1323,7 +1323,6 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, + { + u32 regid, reg_revid, i, mtl_revid, int_status, chipid_match; + int irq_pol = 0; +- int timeout; + int ret; + + if (pdata) { +@@ -1377,18 +1376,14 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, + + usleep_range(2000, 2100); + +- timeout = 100; +- do { +- if (timeout == 0) { +- dev_err(cs35l41->dev, +- "Timeout waiting for OTP_BOOT_DONE\n"); +- ret = -EBUSY; +- goto err; +- } +- usleep_range(1000, 1100); +- regmap_read(cs35l41->regmap, CS35L41_IRQ1_STATUS4, &int_status); +- timeout--; +- } while (!(int_status & CS35L41_OTP_BOOT_DONE)); ++ ret = regmap_read_poll_timeout(cs35l41->regmap, CS35L41_IRQ1_STATUS4, ++ int_status, int_status & CS35L41_OTP_BOOT_DONE, ++ 1000, 100000); ++ if (ret) { ++ dev_err(cs35l41->dev, ++ "Failed waiting for OTP_BOOT_DONE: %d\n", ret); ++ goto err; ++ } + + regmap_read(cs35l41->regmap, CS35L41_IRQ1_STATUS3, &int_status); + if (int_status & CS35L41_OTP_BOOT_ERR) { +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs42l42-Add-control-for-audio-slow-start-switch.patch b/patches.suse/ASoC-cs42l42-Add-control-for-audio-slow-start-switch.patch new file mode 100644 index 0000000..40a6c0d --- /dev/null +++ b/patches.suse/ASoC-cs42l42-Add-control-for-audio-slow-start-switch.patch @@ -0,0 +1,103 @@ +From 7ec4a058c16f3da9c2c0c66506f45c083198ed30 Mon Sep 17 00:00:00 2001 +From: Richard Fitzgerald +Date: Mon, 1 Nov 2021 10:10:06 +0000 +Subject: [PATCH] ASoC: cs42l42: Add control for audio slow-start switch +Git-commit: 7ec4a058c16f3da9c2c0c66506f45c083198ed30 +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +This adds an ALSA control so that the slow-start audio ramp feature +can be disabled. This is useful for high-definition audio applications. + +The register field is unusual in that it is a 3-bit field with only +two valid values, 000=off and 111=on. + +Signed-off-by: Richard Fitzgerald +Link: https://lore.kernel.org/r/20211101101006.13092-1-rf@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs42l42.c | 30 +++++++++++++++++++++++++++++- + sound/soc/codecs/cs42l42.h | 3 +++ + 2 files changed, 32 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c +index 27a1c4c73074..56804a3f285e 100644 +--- a/sound/soc/codecs/cs42l42.c ++++ b/sound/soc/codecs/cs42l42.c +@@ -42,6 +42,7 @@ static const struct reg_default cs42l42_reg_defaults[] = { + { CS42L42_SRC_CTL, 0x10 }, + { CS42L42_MCLK_CTL, 0x02 }, + { CS42L42_SFTRAMP_RATE, 0xA4 }, ++ { CS42L42_SLOW_START_ENABLE, 0x70 }, + { CS42L42_I2C_DEBOUNCE, 0x88 }, + { CS42L42_I2C_STRETCH, 0x03 }, + { CS42L42_I2C_TIMEOUT, 0xB7 }, +@@ -177,6 +178,7 @@ static bool cs42l42_readable_register(struct device *dev, unsigned int reg) + case CS42L42_MCLK_STATUS: + case CS42L42_MCLK_CTL: + case CS42L42_SFTRAMP_RATE: ++ case CS42L42_SLOW_START_ENABLE: + case CS42L42_I2C_DEBOUNCE: + case CS42L42_I2C_STRETCH: + case CS42L42_I2C_TIMEOUT: +@@ -387,6 +389,28 @@ static const struct regmap_config cs42l42_regmap = { + static DECLARE_TLV_DB_SCALE(adc_tlv, -9700, 100, true); + static DECLARE_TLV_DB_SCALE(mixer_tlv, -6300, 100, true); + ++static int cs42l42_slow_start_put(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); ++ u8 val; ++ ++ /* all bits of SLOW_START_EN much change together */ ++ switch (ucontrol->value.integer.value[0]) { ++ case 0: ++ val = 0; ++ break; ++ case 1: ++ val = CS42L42_SLOW_START_EN_MASK; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return snd_soc_component_update_bits(component, CS42L42_SLOW_START_ENABLE, ++ CS42L42_SLOW_START_EN_MASK, val); ++} ++ + static const char * const cs42l42_hpf_freq_text[] = { + "1.86Hz", "120Hz", "235Hz", "466Hz" + }; +@@ -431,7 +455,11 @@ static const struct snd_kcontrol_new cs42l42_snd_controls[] = { + CS42L42_DAC_HPF_EN_SHIFT, true, false), + SOC_DOUBLE_R_TLV("Mixer Volume", CS42L42_MIXER_CHA_VOL, + CS42L42_MIXER_CHB_VOL, CS42L42_MIXER_CH_VOL_SHIFT, +- 0x3f, 1, mixer_tlv) ++ 0x3f, 1, mixer_tlv), ++ ++ SOC_SINGLE_EXT("Slow Start Switch", CS42L42_SLOW_START_ENABLE, ++ CS42L42_SLOW_START_EN_SHIFT, true, false, ++ snd_soc_get_volsw, cs42l42_slow_start_put), + }; + + static int cs42l42_hp_adc_ev(struct snd_soc_dapm_widget *w, +diff --git a/sound/soc/codecs/cs42l42.h b/sound/soc/codecs/cs42l42.h +index f45bcc9a3a62..c8b3267a318b 100644 +--- a/sound/soc/codecs/cs42l42.h ++++ b/sound/soc/codecs/cs42l42.h +@@ -62,6 +62,9 @@ + #define CS42L42_INTERNAL_FS_MASK (1 << CS42L42_INTERNAL_FS_SHIFT) + + #define CS42L42_SFTRAMP_RATE (CS42L42_PAGE_10 + 0x0A) ++#define CS42L42_SLOW_START_ENABLE (CS42L42_PAGE_10 + 0x0B) ++#define CS42L42_SLOW_START_EN_MASK GENMASK(6, 4) ++#define CS42L42_SLOW_START_EN_SHIFT 4 + #define CS42L42_I2C_DEBOUNCE (CS42L42_PAGE_10 + 0x0E) + #define CS42L42_I2C_STRETCH (CS42L42_PAGE_10 + 0x0F) + #define CS42L42_I2C_TIMEOUT (CS42L42_PAGE_10 + 0x10) +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs42l42-Add-warnings-about-DETECT_MODE-and-PLL_.patch b/patches.suse/ASoC-cs42l42-Add-warnings-about-DETECT_MODE-and-PLL_.patch new file mode 100644 index 0000000..5228615 --- /dev/null +++ b/patches.suse/ASoC-cs42l42-Add-warnings-about-DETECT_MODE-and-PLL_.patch @@ -0,0 +1,104 @@ +From 71a6254c8b8aa3dcac3a5cb1d1cc2a2d3a840bfb Mon Sep 17 00:00:00 2001 +From: Richard Fitzgerald +Date: Fri, 4 Mar 2022 14:40:15 +0000 +Subject: [PATCH] ASoC: cs42l42: Add warnings about DETECT_MODE and PLL_START +Git-commit: 71a6254c8b8aa3dcac3a5cb1d1cc2a2d3a840bfb +Patch-mainline: v5.18-rc1 +References: bsc#1203699 + +DETECT_MODE and PLL_START must be zero while HP_PDN and ADC_PDN are +both 1. If this condition is broken it can discharge FILT+ and it +can then take up to 1 second for FILT+ to recharge. + +There is no workaround required for this, simply avoiding settings +and sequences that would break the requirement. The driver already +meets the requirement. + +But it is not obvious from reading the code that this requirement +exists, or what is ensuring it is met. So it would not currently be +obvious to someone changing the code that there is certain special +behaviour that must be maintained. + +To avoid accidental breakage in the future: + +- Add comments into the register definitions to warn about this so + that anyone changing the code around DETECT_MODE and PLL_START is + aware of this requirement. + +- Add a comment where PLL_START is written to 1 to highlight the + requirement and why it is satisfied. + +- Add a comment in cs42l42_setup_hs_type_detect() when DETECT_MODE is + initialized. + +Signed-off-by: Richard Fitzgerald +Link: https://lore.kernel.org/r/20220304144015.398656-1-rf@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs42l42.c | 13 ++++++++++++- + sound/soc/codecs/cs42l42.h | 9 ++++++++- + 2 files changed, 20 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c +index db6ef6cdce15..c8409d50e934 100644 +--- a/sound/soc/codecs/cs42l42.c ++++ b/sound/soc/codecs/cs42l42.c +@@ -1012,7 +1012,14 @@ static int cs42l42_mute_stream(struct snd_soc_dai *dai, int mute, int stream) + } + } else { + if (!cs42l42->stream_use) { +- /* SCLK must be running before codec unmute */ ++ /* SCLK must be running before codec unmute. ++ * ++ * PLL must not be started with ADC and HP both off ++ * otherwise the FILT+ supply will not charge properly. ++ * DAPM widgets power-up before stream unmute so at least ++ * one of the "DAC" or "ADC" widgets will already have ++ * powered-up. ++ */ + if (pll_ratio_table[cs42l42->pll_config].mclk_src_sel) { + snd_soc_component_update_bits(component, CS42L42_PLL_CTL1, + CS42L42_PLL_START_MASK, 1); +@@ -1830,6 +1837,10 @@ static void cs42l42_setup_hs_type_detect(struct cs42l42_private *cs42l42) + + cs42l42->hs_type = CS42L42_PLUG_INVALID; + ++ /* ++ * DETECT_MODE must always be 0 with ADC and HP both off otherwise the ++ * FILT+ supply will not charge properly. ++ */ + regmap_update_bits(cs42l42->regmap, CS42L42_MISC_DET_CTL, + CS42L42_DETECT_MODE_MASK, 0); + +diff --git a/sound/soc/codecs/cs42l42.h b/sound/soc/codecs/cs42l42.h +index 244b24d1f5e9..60d3bdf5d7c9 100644 +--- a/sound/soc/codecs/cs42l42.h ++++ b/sound/soc/codecs/cs42l42.h +@@ -491,7 +491,10 @@ + #define CS42L42_TS_UNPLUG 0 + #define CS42L42_TS_TRANS 1 + +-/* Page 0x15 Fractional-N PLL Registers */ ++/* ++ * NOTE: PLL_START must be 0 while both ADC_PDN=1 and HP_PDN=1. ++ * Otherwise it will prevent FILT+ from charging properly. ++ */ + #define CS42L42_PLL_CTL1 (CS42L42_PAGE_15 + 0x01) + #define CS42L42_PLL_START_SHIFT 0 + #define CS42L42_PLL_START_MASK (1 << CS42L42_PLL_START_SHIFT) +@@ -574,6 +577,10 @@ + #define CS42L42_TIP_SENSE_CTRL_MASK (3 << \ + CS42L42_TIP_SENSE_CTRL_SHIFT) + ++/* ++ * NOTE: DETECT_MODE must be 0 while both ADC_PDN=1 and HP_PDN=1. ++ * Otherwise it will prevent FILT+ from charging properly. ++ */ + #define CS42L42_MISC_DET_CTL (CS42L42_PAGE_1B + 0x74) + #define CS42L42_PDN_MIC_LVL_DET_SHIFT 0 + #define CS42L42_PDN_MIC_LVL_DET_MASK (1 << CS42L42_PDN_MIC_LVL_DET_SHIFT) +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs42l42-Allow-time-for-HP-ADC-to-power-up-after.patch b/patches.suse/ASoC-cs42l42-Allow-time-for-HP-ADC-to-power-up-after.patch new file mode 100644 index 0000000..d5f1a91 --- /dev/null +++ b/patches.suse/ASoC-cs42l42-Allow-time-for-HP-ADC-to-power-up-after.patch @@ -0,0 +1,101 @@ +From 4ae1d8f911d6fc20baefd5eb061bf6964fa22a32 Mon Sep 17 00:00:00 2001 +From: Richard Fitzgerald +Date: Fri, 15 Oct 2021 14:36:15 +0100 +Subject: [PATCH] ASoC: cs42l42: Allow time for HP/ADC to power-up after enable +Git-commit: 4ae1d8f911d6fc20baefd5eb061bf6964fa22a32 +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +After enabling the HP or ADC by writing the corresponding PDN=0, +it takes around 20 milliseconds for it to power up and the midrail +supply to be stable. Add this wait into a DAPM widget callback. + +If HP and ADC are both powering up in a DAPM sequence, there's no +need to do the wait twice. The widget will perform one wait in the +POST_PMU if there was a PRE_PMU for one or both. + +Signed-off-by: Richard Fitzgerald +Link: https://lore.kernel.org/r/20211015133619.4698-13-rf@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs42l42.c | 31 +++++++++++++++++++++++++++++-- + sound/soc/codecs/cs42l42.h | 2 ++ + 2 files changed, 31 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c +index 4ec7fdcedca7..d6d74a7bbde9 100644 +--- a/sound/soc/codecs/cs42l42.c ++++ b/sound/soc/codecs/cs42l42.c +@@ -435,10 +435,36 @@ static const struct snd_kcontrol_new cs42l42_snd_controls[] = { + 0x3f, 1, mixer_tlv) + }; + ++static int cs42l42_hp_adc_ev(struct snd_soc_dapm_widget *w, ++ struct snd_kcontrol *kcontrol, int event) ++{ ++ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); ++ struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component); ++ ++ switch (event) { ++ case SND_SOC_DAPM_PRE_PMU: ++ cs42l42->hp_adc_up_pending = true; ++ break; ++ case SND_SOC_DAPM_POST_PMU: ++ /* Only need one delay if HP and ADC are both powering-up */ ++ if (cs42l42->hp_adc_up_pending) { ++ usleep_range(CS42L42_HP_ADC_EN_TIME_US, ++ CS42L42_HP_ADC_EN_TIME_US + 1000); ++ cs42l42->hp_adc_up_pending = false; ++ } ++ break; ++ default: ++ break; ++ } ++ ++ return 0; ++} ++ + static const struct snd_soc_dapm_widget cs42l42_dapm_widgets[] = { + /* Playback Path */ + SND_SOC_DAPM_OUTPUT("HP"), +- SND_SOC_DAPM_DAC("DAC", NULL, CS42L42_PWR_CTL1, CS42L42_HP_PDN_SHIFT, 1), ++ SND_SOC_DAPM_DAC_E("DAC", NULL, CS42L42_PWR_CTL1, CS42L42_HP_PDN_SHIFT, 1, ++ cs42l42_hp_adc_ev, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_MIXER("MIXER", CS42L42_PWR_CTL1, CS42L42_MIXER_PDN_SHIFT, 1, NULL, 0), + SND_SOC_DAPM_AIF_IN("SDIN1", NULL, 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("SDIN2", NULL, 1, SND_SOC_NOPM, 0, 0), +@@ -448,7 +474,8 @@ static const struct snd_soc_dapm_widget cs42l42_dapm_widgets[] = { + + /* Capture Path */ + SND_SOC_DAPM_INPUT("HS"), +- SND_SOC_DAPM_ADC("ADC", NULL, CS42L42_PWR_CTL1, CS42L42_ADC_PDN_SHIFT, 1), ++ SND_SOC_DAPM_ADC_E("ADC", NULL, CS42L42_PWR_CTL1, CS42L42_ADC_PDN_SHIFT, 1, ++ cs42l42_hp_adc_ev, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_AIF_OUT("SDOUT1", NULL, 0, CS42L42_ASP_TX_CH_EN, CS42L42_ASP_TX0_CH1_SHIFT, 0), + SND_SOC_DAPM_AIF_OUT("SDOUT2", NULL, 1, CS42L42_ASP_TX_CH_EN, CS42L42_ASP_TX0_CH2_SHIFT, 0), + +diff --git a/sound/soc/codecs/cs42l42.h b/sound/soc/codecs/cs42l42.h +index 8734f6828f3e..ded61af6ea8b 100644 +--- a/sound/soc/codecs/cs42l42.h ++++ b/sound/soc/codecs/cs42l42.h +@@ -761,6 +761,7 @@ + #define CS42L42_CLOCK_SWITCH_DELAY_US 150 + #define CS42L42_PLL_LOCK_POLL_US 250 + #define CS42L42_PLL_LOCK_TIMEOUT_US 1250 ++#define CS42L42_HP_ADC_EN_TIME_US 20000 + + static const char *const cs42l42_supply_names[CS42L42_NUM_SUPPLIES] = { + "VA", +@@ -794,6 +795,7 @@ struct cs42l42_private { + u8 hs_bias_ramp_time; + u8 hs_bias_sense_en; + u8 stream_use; ++ bool hp_adc_up_pending; + }; + + #endif /* __CS42L42_H__ */ +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs42l42-Always-enable-TS_PLUG-and-TS_UNPLUG-int.patch b/patches.suse/ASoC-cs42l42-Always-enable-TS_PLUG-and-TS_UNPLUG-int.patch new file mode 100644 index 0000000..7721061 --- /dev/null +++ b/patches.suse/ASoC-cs42l42-Always-enable-TS_PLUG-and-TS_UNPLUG-int.patch @@ -0,0 +1,62 @@ +From 4ca239f33737198827c7f4ac68a1f6fc8a9d79ba Mon Sep 17 00:00:00 2001 +From: Richard Fitzgerald +Date: Fri, 15 Oct 2021 14:36:19 +0100 +Subject: [PATCH] ASoC: cs42l42: Always enable TS_PLUG and TS_UNPLUG interrupts +Git-commit: 4ca239f33737198827c7f4ac68a1f6fc8a9d79ba +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +The headset type detection must run to set the analogue switches +correctly for the attached headset type. Without this only headsets +with wiring matching the chip default will have a functioning mic. + +commit c26a5289e865 ("ASoC: cs42l42: Add support for set_jack calls") +moved the interrupt unmasking to the component set_jack() callback. +But it's not mandatory for a machine driver to register a struct +snd_soc_jack handler. Without a registered handler the type detection +would not have run and so the mic would not work on some types of +headset. + +This patch restores the unmasking of TS_PLUG and TS_UNPLUG interrupts +during probe. + +Signed-off-by: Richard Fitzgerald +Link: https://lore.kernel.org/r/20211015133619.4698-17-rf@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs42l42.c | 10 ++-------- + 1 file changed, 2 insertions(+), 8 deletions(-) + +diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c +index c6d91ad996e0..ac145915445a 100644 +--- a/sound/soc/codecs/cs42l42.c ++++ b/sound/soc/codecs/cs42l42.c +@@ -524,12 +524,6 @@ static int cs42l42_set_jack(struct snd_soc_component *component, struct snd_soc_ + + cs42l42->jack = jk; + +- regmap_update_bits(cs42l42->regmap, CS42L42_TSRS_PLUG_INT_MASK, +- CS42L42_RS_PLUG_MASK | CS42L42_RS_UNPLUG_MASK | +- CS42L42_TS_PLUG_MASK | CS42L42_TS_UNPLUG_MASK, +- (1 << CS42L42_RS_PLUG_SHIFT) | (1 << CS42L42_RS_UNPLUG_SHIFT) | +- (0 << CS42L42_TS_PLUG_SHIFT) | (0 << CS42L42_TS_UNPLUG_SHIFT)); +- + return 0; + } + +@@ -1691,8 +1685,8 @@ static void cs42l42_set_interrupt_masks(struct cs42l42_private *cs42l42) + CS42L42_TS_UNPLUG_MASK, + (1 << CS42L42_RS_PLUG_SHIFT) | + (1 << CS42L42_RS_UNPLUG_SHIFT) | +- (1 << CS42L42_TS_PLUG_SHIFT) | +- (1 << CS42L42_TS_UNPLUG_SHIFT)); ++ (0 << CS42L42_TS_PLUG_SHIFT) | ++ (0 << CS42L42_TS_UNPLUG_SHIFT)); + } + + static void cs42l42_setup_hs_type_detect(struct cs42l42_private *cs42l42) +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs42l42-Change-jack_detect_mutex-to-a-lock-of-a.patch b/patches.suse/ASoC-cs42l42-Change-jack_detect_mutex-to-a-lock-of-a.patch new file mode 100644 index 0000000..bc99ad2 --- /dev/null +++ b/patches.suse/ASoC-cs42l42-Change-jack_detect_mutex-to-a-lock-of-a.patch @@ -0,0 +1,106 @@ +From 5982b5a8ec7ddb076e774bdd0b17d74681ab0943 Mon Sep 17 00:00:00 2001 +From: Richard Fitzgerald +Date: Fri, 21 Jan 2022 12:04:11 +0000 +Subject: [PATCH] ASoC: cs42l42: Change jack_detect_mutex to a lock of all IRQ handling +Git-commit: 5982b5a8ec7ddb076e774bdd0b17d74681ab0943 +Patch-mainline: v5.18-rc1 +References: bsc#1203699 + +Rename jack_detect_mutex to irq_lock and make it lock the entire IRQ +handling. + +The jack_detect_mutex was introduced to synchronize registering an +ALSA jack handler, via cs42l42_set_jack(), with the jack state +processing in the IRQ handler, and was taken only around the +relevant part of the IRQ handling code. + +System suspend will need to synchronize with the IRQ handler thread +so will need a similar mutex that surrounds all of the IRQ handling. +Repurposing the existing jack_detect_mutex is the simplest option. +It does no harm for a call to cs42l42_set_jack() to additionally +block the first few lines of IRQ handling, and the only interrupts +used by the driver are all for jack handling. + +Signed-off-by: Richard Fitzgerald +Link: https://lore.kernel.org/r/20220121120412.672284-3-rf@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs42l42.c | 11 +++++------ + sound/soc/codecs/cs42l42.h | 2 +- + 2 files changed, 6 insertions(+), 7 deletions(-) + +diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c +index 2c294868008e..f1b95d45af4a 100644 +--- a/sound/soc/codecs/cs42l42.c ++++ b/sound/soc/codecs/cs42l42.c +@@ -550,7 +550,7 @@ static int cs42l42_set_jack(struct snd_soc_component *component, struct snd_soc_ + struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component); + + /* Prevent race with interrupt handler */ +- mutex_lock(&cs42l42->jack_detect_mutex); ++ mutex_lock(&cs42l42->irq_lock); + cs42l42->jack = jk; + + if (jk) { +@@ -566,7 +566,7 @@ static int cs42l42_set_jack(struct snd_soc_component *component, struct snd_soc_ + break; + } + } +- mutex_unlock(&cs42l42->jack_detect_mutex); ++ mutex_unlock(&cs42l42->irq_lock); + + return 0; + } +@@ -1613,6 +1613,7 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data) + unsigned int i; + int report = 0; + ++ mutex_lock(&cs42l42->irq_lock); + + /* Read sticky registers to clear interurpt */ + for (i = 0; i < ARRAY_SIZE(stickies); i++) { +@@ -1635,8 +1636,6 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data) + CS42L42_M_DETECT_FT_MASK | + CS42L42_M_HSBIAS_HIZ_MASK); + +- mutex_lock(&cs42l42->jack_detect_mutex); +- + /* + * Check auto-detect status. Don't assume a previous unplug event has + * cleared the flags. If the jack is unplugged and plugged during +@@ -1713,7 +1712,7 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data) + } + } + +- mutex_unlock(&cs42l42->jack_detect_mutex); ++ mutex_unlock(&cs42l42->irq_lock); + + return IRQ_HANDLED; + } +@@ -2062,7 +2061,7 @@ static int cs42l42_i2c_probe(struct i2c_client *i2c_client, + + cs42l42->dev = &i2c_client->dev; + i2c_set_clientdata(i2c_client, cs42l42); +- mutex_init(&cs42l42->jack_detect_mutex); ++ mutex_init(&cs42l42->irq_lock); + + cs42l42->regmap = devm_regmap_init_i2c(i2c_client, &cs42l42_regmap); + if (IS_ERR(cs42l42->regmap)) { +diff --git a/sound/soc/codecs/cs42l42.h b/sound/soc/codecs/cs42l42.h +index 9fff183dce8e..53d96287abba 100644 +--- a/sound/soc/codecs/cs42l42.h ++++ b/sound/soc/codecs/cs42l42.h +@@ -842,7 +842,7 @@ struct cs42l42_private { + struct gpio_desc *reset_gpio; + struct completion pdn_done; + struct snd_soc_jack *jack; +- struct mutex jack_detect_mutex; ++ struct mutex irq_lock; + int pll_config; + int bclk; + u32 sclk; +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs42l42-Don-t-claim-to-support-192k.patch b/patches.suse/ASoC-cs42l42-Don-t-claim-to-support-192k.patch new file mode 100644 index 0000000..6e1a250 --- /dev/null +++ b/patches.suse/ASoC-cs42l42-Don-t-claim-to-support-192k.patch @@ -0,0 +1,62 @@ +From 2a031a99428bafba089437e9044b8fd5dc6e7551 Mon Sep 17 00:00:00 2001 +From: Richard Fitzgerald +Date: Fri, 15 Oct 2021 14:36:13 +0100 +Subject: [PATCH] ASoC: cs42l42: Don't claim to support 192k +Git-commit: 2a031a99428bafba089437e9044b8fd5dc6e7551 +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +The driver currently only supports configuring for sample rates <= 96k +and it isn't possible to setup a configuration that will support all +sample rates up to 192k. + +For sample rates up to 96k MCLK is in the 12MHz group. +However, although 192k only requires an I2S clock in the 12MHz group, +the cs42l42 audio path is not natively 192k so the audio must be +resampled. But for 192k the SRC requires a 24MHz MCLK. + +It is not possible to switch MCLK between 12MHz and 24MHz groups +on-the-fly. The 12MHz group supports all sample rates up to 96k. + +Signed-off-by: Richard Fitzgerald +Link: https://lore.kernel.org/r/20211015133619.4698-11-rf@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs42l42.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c +index dc84b3de3da3..71390c20e7a1 100644 +--- a/sound/soc/codecs/cs42l42.c ++++ b/sound/soc/codecs/cs42l42.c +@@ -812,7 +812,7 @@ static int cs42l42_dai_startup(struct snd_pcm_substream *substream, struct snd_s + /* Machine driver has not set a SCLK, limit bottom end to 44.1 kHz */ + return snd_pcm_hw_constraint_minmax(substream->runtime, + SNDRV_PCM_HW_PARAM_RATE, +- 44100, 192000); ++ 44100, 96000); + } + + static int cs42l42_pcm_hw_params(struct snd_pcm_substream *substream, +@@ -1008,14 +1008,14 @@ static struct snd_soc_dai_driver cs42l42_dai = { + .stream_name = "Playback", + .channels_min = 1, + .channels_max = 2, +- .rates = SNDRV_PCM_RATE_8000_192000, ++ .rates = SNDRV_PCM_RATE_8000_96000, + .formats = CS42L42_FORMATS, + }, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 2, +- .rates = SNDRV_PCM_RATE_8000_192000, ++ .rates = SNDRV_PCM_RATE_8000_96000, + .formats = CS42L42_FORMATS, + }, + .symmetric_rate = 1, +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs42l42-Don-t-reconfigure-the-PLL-while-it-is-r.patch b/patches.suse/ASoC-cs42l42-Don-t-reconfigure-the-PLL-while-it-is-r.patch new file mode 100644 index 0000000..23a683a --- /dev/null +++ b/patches.suse/ASoC-cs42l42-Don-t-reconfigure-the-PLL-while-it-is-r.patch @@ -0,0 +1,52 @@ +From 06441c82f0cd836402ca5fa4162d28ed07cfb0ed Mon Sep 17 00:00:00 2001 +From: Richard Fitzgerald +Date: Fri, 15 Oct 2021 14:36:04 +0100 +Subject: [PATCH] ASoC: cs42l42: Don't reconfigure the PLL while it is running +Git-commit: 06441c82f0cd836402ca5fa4162d28ed07cfb0ed +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +When capture and playback substreams are both running at the same time, +cs42l42_pcm_hw_params() would be called for each direction. The first +call will configure the PLL. The second call must not write the PLL +configuration registers again if the first substream is already running, +as this could destabilize the PLL. + +The DAI is marked symmetric sample bits and sample rate, so the two +directions will always have the same SCLK (I2S always has 2 channel slots +so the DAI does not need to require symmetric channels to guarantee the +same SCLK). However, since cs42l42_pll_config() is checking for an active +stream it may as well test that the requested SCLK is the same as the +currently active configuration. + +Signed-off-by: Richard Fitzgerald +Link: https://lore.kernel.org/r/20211015133619.4698-2-rf@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs42l42.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c +index 9a463ab54bdd..cdcb6d81d900 100644 +--- a/sound/soc/codecs/cs42l42.c ++++ b/sound/soc/codecs/cs42l42.c +@@ -618,6 +618,14 @@ static int cs42l42_pll_config(struct snd_soc_component *component) + else + clk = cs42l42->sclk; + ++ /* Don't reconfigure if there is an audio stream running */ ++ if (cs42l42->stream_use) { ++ if (pll_ratio_table[cs42l42->pll_config].sclk == clk) ++ return 0; ++ else ++ return -EBUSY; ++ } ++ + for (i = 0; i < ARRAY_SIZE(pll_ratio_table); i++) { + if (pll_ratio_table[i].sclk == clk) { + cs42l42->pll_config = i; +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs42l42-Fix-WARN-in-remove-if-running-without-a.patch b/patches.suse/ASoC-cs42l42-Fix-WARN-in-remove-if-running-without-a.patch new file mode 100644 index 0000000..dd81d8b --- /dev/null +++ b/patches.suse/ASoC-cs42l42-Fix-WARN-in-remove-if-running-without-a.patch @@ -0,0 +1,80 @@ +From 4c8d49bc476c7cf1fb7377b469ced43ced470027 Mon Sep 17 00:00:00 2001 +From: Richard Fitzgerald +Date: Fri, 15 Oct 2021 14:36:18 +0100 +Subject: [PATCH] ASoC: cs42l42: Fix WARN in remove() if running without an interrupt +Git-commit: 4c8d49bc476c7cf1fb7377b469ced43ced470027 +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +The driver must free the IRQ in remove() to prevent the potential race +where an IRQ starts to be handled while the driver is being removed but +devres has not yet called free_irq(). However, the driver can run without +an interrupt but devm_free_irq() will hit a WARN() if no devres-managed +interrupt was ever created. + +Fix this by only attempting to create the interrupt handler if the hardware +config specified an interrupt, and failing probe() if the interrupt could +not be created. This means that in cs42l42_remove() an interrupt must have +been registered if the irq number is valid and therefore it is safe to call +devm_free_irq(). + +Signed-off-by: Richard Fitzgerald +Link: https://lore.kernel.org/r/20211015133619.4698-16-rf@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs42l42.c | 30 ++++++++++++++++++------------ + 1 file changed, 18 insertions(+), 12 deletions(-) + +diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c +index 390cd7ea3a7f..c6d91ad996e0 100644 +--- a/sound/soc/codecs/cs42l42.c ++++ b/sound/soc/codecs/cs42l42.c +@@ -1975,17 +1975,21 @@ static int cs42l42_i2c_probe(struct i2c_client *i2c_client, + } + usleep_range(CS42L42_BOOT_TIME_US, CS42L42_BOOT_TIME_US * 2); + +- /* Request IRQ */ +- ret = devm_request_threaded_irq(&i2c_client->dev, +- i2c_client->irq, +- NULL, cs42l42_irq_thread, +- IRQF_ONESHOT | IRQF_TRIGGER_LOW, +- "cs42l42", cs42l42); +- if (ret == -EPROBE_DEFER) +- goto err_disable; +- else if (ret != 0) +- dev_err(&i2c_client->dev, +- "Failed to request IRQ: %d\n", ret); ++ /* Request IRQ if one was specified */ ++ if (i2c_client->irq) { ++ ret = devm_request_threaded_irq(&i2c_client->dev, ++ i2c_client->irq, ++ NULL, cs42l42_irq_thread, ++ IRQF_ONESHOT | IRQF_TRIGGER_LOW, ++ "cs42l42", cs42l42); ++ if (ret == -EPROBE_DEFER) { ++ goto err_disable; ++ } else if (ret != 0) { ++ dev_err(&i2c_client->dev, ++ "Failed to request IRQ: %d\n", ret); ++ goto err_disable; ++ } ++ } + + /* initialize codec */ + devid = cirrus_read_device_id(cs42l42->regmap, CS42L42_DEVID_AB); +@@ -2056,7 +2060,9 @@ static int cs42l42_i2c_remove(struct i2c_client *i2c_client) + { + struct cs42l42_private *cs42l42 = i2c_get_clientdata(i2c_client); + +- devm_free_irq(&i2c_client->dev, i2c_client->irq, cs42l42); ++ if (i2c_client->irq) ++ devm_free_irq(&i2c_client->dev, i2c_client->irq, cs42l42); ++ + pm_runtime_suspend(&i2c_client->dev); + pm_runtime_disable(&i2c_client->dev); + +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs42l42-Handle-system-suspend.patch b/patches.suse/ASoC-cs42l42-Handle-system-suspend.patch new file mode 100644 index 0000000..a0f185e --- /dev/null +++ b/patches.suse/ASoC-cs42l42-Handle-system-suspend.patch @@ -0,0 +1,232 @@ +From f8593e88540052b3feaf1fb36f2c1c0484c9dc14 Mon Sep 17 00:00:00 2001 +From: Richard Fitzgerald +Date: Fri, 21 Jan 2022 12:04:12 +0000 +Subject: [PATCH] ASoC: cs42l42: Handle system suspend +Git-commit: f8593e88540052b3feaf1fb36f2c1c0484c9dc14 +Patch-mainline: v5.18-rc1 +References: bsc#1203699 + +Add system suspend functions to handle clean power-down on suspend and +restoring registers on resume. + +The jack state could change during suspend. Plug->unplug and unplug->plug +are straightforward because this looks no different from any other plug +state change - there will be a plugged or unplugged interrupt pending. +The jack could be unplugged and a different type of jack plugged, and on +resume the plug state would not have changed. Setting plug_state back to +TS_TRANS (transitioning) will make the next plug interrupt after resume +run a type detection. + +During system suspend any jack plug/unplug and button events will not be +reported or generate a system wakeup. If the plug state or headset type +has changed it will be reported after resume. + +Signed-off-by: Richard Fitzgerald +Link: https://lore.kernel.org/r/20220121120412.672284-4-rf@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs42l42.c | 141 +++++++++++++++++++++++++++++++++++++ + sound/soc/codecs/cs42l42.h | 5 ++ + 2 files changed, 146 insertions(+) + +diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c +index f1b95d45af4a..db6ef6cdce15 100644 +--- a/sound/soc/codecs/cs42l42.c ++++ b/sound/soc/codecs/cs42l42.c +@@ -1614,6 +1614,10 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data) + int report = 0; + + mutex_lock(&cs42l42->irq_lock); ++ if (cs42l42->suspended) { ++ mutex_unlock(&cs42l42->irq_lock); ++ return IRQ_NONE; ++ } + + /* Read sticky registers to clear interurpt */ + for (i = 0; i < ARRAY_SIZE(stickies); i++) { +@@ -2047,6 +2051,138 @@ static int cs42l42_handle_device_data(struct device *dev, + return 0; + } + ++/* Datasheet suspend sequence */ ++static const struct reg_sequence __maybe_unused cs42l42_shutdown_seq[] = { ++ REG_SEQ0(CS42L42_MIC_DET_CTL1, 0x9F), ++ REG_SEQ0(CS42L42_ADC_OVFL_INT_MASK, 0x01), ++ REG_SEQ0(CS42L42_MIXER_INT_MASK, 0x0F), ++ REG_SEQ0(CS42L42_SRC_INT_MASK, 0x0F), ++ REG_SEQ0(CS42L42_ASP_RX_INT_MASK, 0x1F), ++ REG_SEQ0(CS42L42_ASP_TX_INT_MASK, 0x0F), ++ REG_SEQ0(CS42L42_CODEC_INT_MASK, 0x03), ++ REG_SEQ0(CS42L42_SRCPL_INT_MASK, 0x7F), ++ REG_SEQ0(CS42L42_VPMON_INT_MASK, 0x01), ++ REG_SEQ0(CS42L42_PLL_LOCK_INT_MASK, 0x01), ++ REG_SEQ0(CS42L42_TSRS_PLUG_INT_MASK, 0x0F), ++ REG_SEQ0(CS42L42_WAKE_CTL, 0xE1), ++ REG_SEQ0(CS42L42_DET_INT1_MASK, 0xE0), ++ REG_SEQ0(CS42L42_DET_INT2_MASK, 0xFF), ++ REG_SEQ0(CS42L42_MIXER_CHA_VOL, 0x3F), ++ REG_SEQ0(CS42L42_MIXER_ADC_VOL, 0x3F), ++ REG_SEQ0(CS42L42_MIXER_CHB_VOL, 0x3F), ++ REG_SEQ0(CS42L42_HP_CTL, 0x0F), ++ REG_SEQ0(CS42L42_ASP_RX_DAI0_EN, 0x00), ++ REG_SEQ0(CS42L42_ASP_CLK_CFG, 0x00), ++ REG_SEQ0(CS42L42_HSDET_CTL2, 0x00), ++ REG_SEQ0(CS42L42_PWR_CTL1, 0xFE), ++ REG_SEQ0(CS42L42_PWR_CTL2, 0x8C), ++ REG_SEQ0(CS42L42_DAC_CTL2, 0x02), ++ REG_SEQ0(CS42L42_HS_CLAMP_DISABLE, 0x00), ++ REG_SEQ0(CS42L42_MISC_DET_CTL, 0x03), ++ REG_SEQ0(CS42L42_TIPSENSE_CTL, 0x02), ++ REG_SEQ0(CS42L42_HSBIAS_SC_AUTOCTL, 0x03), ++ REG_SEQ0(CS42L42_PWR_CTL1, 0xFF) ++}; ++ ++static int __maybe_unused cs42l42_suspend(struct device *dev) ++{ ++ struct cs42l42_private *cs42l42 = dev_get_drvdata(dev); ++ unsigned int reg; ++ u8 save_regs[ARRAY_SIZE(cs42l42_shutdown_seq)]; ++ int i, ret; ++ ++ /* ++ * Wait for threaded irq handler to be idle and stop it processing ++ * future interrupts. This ensures a safe disable if the interrupt ++ * is shared. ++ */ ++ mutex_lock(&cs42l42->irq_lock); ++ cs42l42->suspended = true; ++ ++ /* Save register values that will be overwritten by shutdown sequence */ ++ for (i = 0; i < ARRAY_SIZE(cs42l42_shutdown_seq); ++i) { ++ regmap_read(cs42l42->regmap, cs42l42_shutdown_seq[i].reg, ®); ++ save_regs[i] = (u8)reg; ++ } ++ ++ /* Shutdown codec */ ++ regmap_multi_reg_write(cs42l42->regmap, ++ cs42l42_shutdown_seq, ++ ARRAY_SIZE(cs42l42_shutdown_seq)); ++ ++ /* All interrupt sources are now disabled */ ++ mutex_unlock(&cs42l42->irq_lock); ++ ++ /* Wait for power-down complete */ ++ msleep(CS42L42_PDN_DONE_TIME_MS); ++ ret = regmap_read_poll_timeout(cs42l42->regmap, ++ CS42L42_CODEC_STATUS, reg, ++ (reg & CS42L42_PDN_DONE_MASK), ++ CS42L42_PDN_DONE_POLL_US, ++ CS42L42_PDN_DONE_TIMEOUT_US); ++ if (ret) ++ dev_warn(dev, "Failed to get PDN_DONE: %d\n", ret); ++ ++ /* Discharge FILT+ */ ++ regmap_update_bits(cs42l42->regmap, CS42L42_PWR_CTL2, ++ CS42L42_DISCHARGE_FILT_MASK, CS42L42_DISCHARGE_FILT_MASK); ++ msleep(CS42L42_FILT_DISCHARGE_TIME_MS); ++ ++ regcache_cache_only(cs42l42->regmap, true); ++ gpiod_set_value_cansleep(cs42l42->reset_gpio, 0); ++ regulator_bulk_disable(ARRAY_SIZE(cs42l42->supplies), cs42l42->supplies); ++ ++ /* Restore register values to the regmap cache */ ++ for (i = 0; i < ARRAY_SIZE(cs42l42_shutdown_seq); ++i) ++ regmap_write(cs42l42->regmap, cs42l42_shutdown_seq[i].reg, save_regs[i]); ++ ++ /* The cached address page register value is now stale */ ++ regcache_drop_region(cs42l42->regmap, CS42L42_PAGE_REGISTER, CS42L42_PAGE_REGISTER); ++ ++ dev_dbg(dev, "System suspended\n"); ++ ++ return 0; ++ ++} ++ ++static int __maybe_unused cs42l42_resume(struct device *dev) ++{ ++ struct cs42l42_private *cs42l42 = dev_get_drvdata(dev); ++ int ret; ++ ++ /* ++ * If jack was unplugged and re-plugged during suspend it could ++ * have changed type but the tip-sense state hasn't changed. ++ * Force a plugged state to be re-evaluated. ++ */ ++ if (cs42l42->plug_state != CS42L42_TS_UNPLUG) ++ cs42l42->plug_state = CS42L42_TS_TRANS; ++ ++ ret = regulator_bulk_enable(ARRAY_SIZE(cs42l42->supplies), cs42l42->supplies); ++ if (ret != 0) { ++ dev_err(dev, "Failed to enable supplies: %d\n", ret); ++ return ret; ++ } ++ ++ gpiod_set_value_cansleep(cs42l42->reset_gpio, 1); ++ usleep_range(CS42L42_BOOT_TIME_US, CS42L42_BOOT_TIME_US * 2); ++ ++ regcache_cache_only(cs42l42->regmap, false); ++ regcache_mark_dirty(cs42l42->regmap); ++ ++ mutex_lock(&cs42l42->irq_lock); ++ /* Sync LATCH_TO_VP first so the VP domain registers sync correctly */ ++ regcache_sync_region(cs42l42->regmap, CS42L42_MIC_DET_CTL1, CS42L42_MIC_DET_CTL1); ++ regcache_sync(cs42l42->regmap); ++ ++ cs42l42->suspended = false; ++ mutex_unlock(&cs42l42->irq_lock); ++ ++ dev_dbg(dev, "System resumed\n"); ++ ++ return 0; ++} ++ + static int cs42l42_i2c_probe(struct i2c_client *i2c_client, + const struct i2c_device_id *id) + { +@@ -2217,6 +2353,10 @@ static int cs42l42_i2c_remove(struct i2c_client *i2c_client) + return 0; + } + ++static const struct dev_pm_ops cs42l42_pm_ops = { ++ SET_SYSTEM_SLEEP_PM_OPS(cs42l42_suspend, cs42l42_resume) ++}; ++ + #ifdef CONFIG_OF + static const struct of_device_id cs42l42_of_match[] = { + { .compatible = "cirrus,cs42l42", }, +@@ -2243,6 +2383,7 @@ MODULE_DEVICE_TABLE(i2c, cs42l42_id); + static struct i2c_driver cs42l42_i2c_driver = { + .driver = { + .name = "cs42l42", ++ .pm = &cs42l42_pm_ops, + .of_match_table = of_match_ptr(cs42l42_of_match), + .acpi_match_table = ACPI_PTR(cs42l42_acpi_match), + }, +diff --git a/sound/soc/codecs/cs42l42.h b/sound/soc/codecs/cs42l42.h +index 53d96287abba..244b24d1f5e9 100644 +--- a/sound/soc/codecs/cs42l42.h ++++ b/sound/soc/codecs/cs42l42.h +@@ -826,6 +826,10 @@ + #define CS42L42_PLL_LOCK_POLL_US 250 + #define CS42L42_PLL_LOCK_TIMEOUT_US 1250 + #define CS42L42_HP_ADC_EN_TIME_US 20000 ++#define CS42L42_PDN_DONE_POLL_US 1000 ++#define CS42L42_PDN_DONE_TIMEOUT_US 200000 ++#define CS42L42_PDN_DONE_TIME_MS 100 ++#define CS42L42_FILT_DISCHARGE_TIME_MS 46 + + static const char *const cs42l42_supply_names[CS42L42_NUM_SUPPLIES] = { + "VA", +@@ -860,6 +864,7 @@ struct cs42l42_private { + u8 hs_bias_sense_en; + u8 stream_use; + bool hp_adc_up_pending; ++ bool suspended; + }; + + #endif /* __CS42L42_H__ */ +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs42l42-Implement-Manual-Type-detection-as-fall.patch b/patches.suse/ASoC-cs42l42-Implement-Manual-Type-detection-as-fall.patch new file mode 100644 index 0000000..4f7e76a --- /dev/null +++ b/patches.suse/ASoC-cs42l42-Implement-Manual-Type-detection-as-fall.patch @@ -0,0 +1,225 @@ +From 12451814496a5433f41843ca4e3d9961d69304f7 Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Thu, 16 Sep 2021 11:27:50 +0100 +Subject: [PATCH] ASoC: cs42l42: Implement Manual Type detection as fallback +Git-commit: 12451814496a5433f41843ca4e3d9961d69304f7 +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +Some headsets are not detected correctly by Automatic Type Detection +on cs42l42. Instead, Manual Type Detection can be used to give a +more accurate value. + +Signed-off-by: Stefan Binding +Signed-off-by: Vitaly Rodionov +Link: https://lore.kernel.org/r/20210916102750.9212-2-vitalyr@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs42l42.c | 104 ++++++++++++++++++++++++++++++++----- + sound/soc/codecs/cs42l42.h | 54 +++++++++++++++++++ + 2 files changed, 146 insertions(+), 12 deletions(-) + +diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c +index fb1e4c33e27d..c586ebff45f7 100644 +--- a/sound/soc/codecs/cs42l42.c ++++ b/sound/soc/codecs/cs42l42.c +@@ -1046,37 +1046,117 @@ static struct snd_soc_dai_driver cs42l42_dai = { + .ops = &cs42l42_ops, + }; + +-static void cs42l42_process_hs_type_detect(struct cs42l42_private *cs42l42) ++static void cs42l42_manual_hs_type_detect(struct cs42l42_private *cs42l42) + { + unsigned int hs_det_status; +- unsigned int int_status; ++ unsigned int hs_det_comp; ++ unsigned int hs_det_sw; + +- /* Mask the auto detect interrupt */ ++ /* Set hs detect to manual, active mode */ + regmap_update_bits(cs42l42->regmap, +- CS42L42_CODEC_INT_MASK, +- CS42L42_PDN_DONE_MASK | +- CS42L42_HSDET_AUTO_DONE_MASK, +- (1 << CS42L42_PDN_DONE_SHIFT) | +- (1 << CS42L42_HSDET_AUTO_DONE_SHIFT)); ++ CS42L42_HSDET_CTL2, ++ CS42L42_HSDET_CTRL_MASK | ++ CS42L42_HSDET_SET_MASK | ++ CS42L42_HSBIAS_REF_MASK | ++ CS42L42_HSDET_AUTO_TIME_MASK, ++ (1 << CS42L42_HSDET_CTRL_SHIFT) | ++ (0 << CS42L42_HSDET_SET_SHIFT) | ++ (0 << CS42L42_HSBIAS_REF_SHIFT) | ++ (0 << CS42L42_HSDET_AUTO_TIME_SHIFT)); ++ ++ /* Open the SW_HSB_HS3 switch and close SW_HSB_HS4 for a Type 1 headset. */ ++ regmap_write(cs42l42->regmap, CS42L42_HS_SWITCH_CTL, CS42L42_HSDET_SW_COMP1); ++ ++ regmap_read(cs42l42->regmap, CS42L42_HS_DET_STATUS, &hs_det_status); ++ ++ hs_det_comp = (hs_det_status & CS42L42_HSDET_COMP1_OUT_MASK) >> ++ CS42L42_HSDET_COMP1_OUT_SHIFT; ++ ++ /* Close the SW_HSB_HS3 switch for a Type 2 headset. */ ++ regmap_write(cs42l42->regmap, CS42L42_HS_SWITCH_CTL, CS42L42_HSDET_SW_COMP2); ++ ++ regmap_read(cs42l42->regmap, CS42L42_HS_DET_STATUS, &hs_det_status); ++ ++ hs_det_comp |= ((hs_det_status & CS42L42_HSDET_COMP2_OUT_MASK) >> ++ CS42L42_HSDET_COMP2_OUT_SHIFT) << 1; ++ ++ switch (hs_det_comp) { ++ case CS42L42_HSDET_COMP_TYPE1: ++ cs42l42->hs_type = CS42L42_PLUG_CTIA; ++ hs_det_sw = CS42L42_HSDET_SW_TYPE1; ++ break; ++ case CS42L42_HSDET_COMP_TYPE2: ++ cs42l42->hs_type = CS42L42_PLUG_OMTP; ++ hs_det_sw = CS42L42_HSDET_SW_TYPE2; ++ break; ++ case CS42L42_HSDET_COMP_TYPE3: ++ cs42l42->hs_type = CS42L42_PLUG_HEADPHONE; ++ hs_det_sw = CS42L42_HSDET_SW_TYPE3; ++ break; ++ default: ++ cs42l42->hs_type = CS42L42_PLUG_INVALID; ++ hs_det_sw = CS42L42_HSDET_SW_TYPE4; ++ break; ++ } + +- /* Set hs detect to automatic, disabled mode */ ++ /* Set Switches */ ++ regmap_write(cs42l42->regmap, CS42L42_HS_SWITCH_CTL, hs_det_sw); ++ ++ /* Set HSDET mode to Manual—Disabled */ + regmap_update_bits(cs42l42->regmap, + CS42L42_HSDET_CTL2, + CS42L42_HSDET_CTRL_MASK | + CS42L42_HSDET_SET_MASK | + CS42L42_HSBIAS_REF_MASK | + CS42L42_HSDET_AUTO_TIME_MASK, +- (2 << CS42L42_HSDET_CTRL_SHIFT) | +- (2 << CS42L42_HSDET_SET_SHIFT) | ++ (0 << CS42L42_HSDET_CTRL_SHIFT) | ++ (0 << CS42L42_HSDET_SET_SHIFT) | + (0 << CS42L42_HSBIAS_REF_SHIFT) | +- (3 << CS42L42_HSDET_AUTO_TIME_SHIFT)); ++ (0 << CS42L42_HSDET_AUTO_TIME_SHIFT)); ++} ++ ++static void cs42l42_process_hs_type_detect(struct cs42l42_private *cs42l42) ++{ ++ unsigned int hs_det_status; ++ unsigned int int_status; + + /* Read and save the hs detection result */ + regmap_read(cs42l42->regmap, CS42L42_HS_DET_STATUS, &hs_det_status); + ++ /* Mask the auto detect interrupt */ ++ regmap_update_bits(cs42l42->regmap, ++ CS42L42_CODEC_INT_MASK, ++ CS42L42_PDN_DONE_MASK | ++ CS42L42_HSDET_AUTO_DONE_MASK, ++ (1 << CS42L42_PDN_DONE_SHIFT) | ++ (1 << CS42L42_HSDET_AUTO_DONE_SHIFT)); ++ ++ + cs42l42->hs_type = (hs_det_status & CS42L42_HSDET_TYPE_MASK) >> + CS42L42_HSDET_TYPE_SHIFT; + ++ /* Run Manual detection if auto detect has not found a headset. ++ * We Re-Run with Manual Detection if the original detection was invalid or headphones, ++ * to ensure that a headset mic is detected in all cases. ++ */ ++ if (cs42l42->hs_type == CS42L42_PLUG_INVALID || ++ cs42l42->hs_type == CS42L42_PLUG_HEADPHONE) { ++ dev_dbg(cs42l42->component->dev, "Running Manual Detection Fallback\n"); ++ cs42l42_manual_hs_type_detect(cs42l42); ++ } else { ++ /* Set hs detect to automatic, disabled mode */ ++ regmap_update_bits(cs42l42->regmap, ++ CS42L42_HSDET_CTL2, ++ CS42L42_HSDET_CTRL_MASK | ++ CS42L42_HSDET_SET_MASK | ++ CS42L42_HSBIAS_REF_MASK | ++ CS42L42_HSDET_AUTO_TIME_MASK, ++ (2 << CS42L42_HSDET_CTRL_SHIFT) | ++ (2 << CS42L42_HSDET_SET_SHIFT) | ++ (0 << CS42L42_HSBIAS_REF_SHIFT) | ++ (3 << CS42L42_HSDET_AUTO_TIME_SHIFT)); ++ } ++ + /* Set up button detection */ + if ((cs42l42->hs_type == CS42L42_PLUG_CTIA) || + (cs42l42->hs_type == CS42L42_PLUG_OMTP)) { +diff --git a/sound/soc/codecs/cs42l42.h b/sound/soc/codecs/cs42l42.h +index 8734f6828f3e..2aeabba73e05 100644 +--- a/sound/soc/codecs/cs42l42.h ++++ b/sound/soc/codecs/cs42l42.h +@@ -228,6 +228,60 @@ + #define CS42L42_PLUG_HEADPHONE 2 + #define CS42L42_PLUG_INVALID 3 + ++#define CS42L42_HSDET_SW_COMP1 ((0 << CS42L42_SW_GNDHS_HS4_SHIFT) | \ ++ (1 << CS42L42_SW_GNDHS_HS3_SHIFT) | \ ++ (1 << CS42L42_SW_HSB_HS4_SHIFT) | \ ++ (0 << CS42L42_SW_HSB_HS3_SHIFT) | \ ++ (0 << CS42L42_SW_HSB_FILT_HS4_SHIFT) | \ ++ (1 << CS42L42_SW_HSB_FILT_HS3_SHIFT) | \ ++ (0 << CS42L42_SW_REF_HS4_SHIFT) | \ ++ (1 << CS42L42_SW_REF_HS3_SHIFT)) ++#define CS42L42_HSDET_SW_COMP2 ((1 << CS42L42_SW_GNDHS_HS4_SHIFT) | \ ++ (0 << CS42L42_SW_GNDHS_HS3_SHIFT) | \ ++ (0 << CS42L42_SW_HSB_HS4_SHIFT) | \ ++ (1 << CS42L42_SW_HSB_HS3_SHIFT) | \ ++ (1 << CS42L42_SW_HSB_FILT_HS4_SHIFT) | \ ++ (0 << CS42L42_SW_HSB_FILT_HS3_SHIFT) | \ ++ (1 << CS42L42_SW_REF_HS4_SHIFT) | \ ++ (0 << CS42L42_SW_REF_HS3_SHIFT)) ++#define CS42L42_HSDET_SW_TYPE1 ((0 << CS42L42_SW_GNDHS_HS4_SHIFT) | \ ++ (1 << CS42L42_SW_GNDHS_HS3_SHIFT) | \ ++ (1 << CS42L42_SW_HSB_HS4_SHIFT) | \ ++ (0 << CS42L42_SW_HSB_HS3_SHIFT) | \ ++ (0 << CS42L42_SW_HSB_FILT_HS4_SHIFT) | \ ++ (1 << CS42L42_SW_HSB_FILT_HS3_SHIFT) | \ ++ (0 << CS42L42_SW_REF_HS4_SHIFT) | \ ++ (1 << CS42L42_SW_REF_HS3_SHIFT)) ++#define CS42L42_HSDET_SW_TYPE2 ((1 << CS42L42_SW_GNDHS_HS4_SHIFT) | \ ++ (0 << CS42L42_SW_GNDHS_HS3_SHIFT) | \ ++ (0 << CS42L42_SW_HSB_HS4_SHIFT) | \ ++ (1 << CS42L42_SW_HSB_HS3_SHIFT) | \ ++ (1 << CS42L42_SW_HSB_FILT_HS4_SHIFT) | \ ++ (0 << CS42L42_SW_HSB_FILT_HS3_SHIFT) | \ ++ (1 << CS42L42_SW_REF_HS4_SHIFT) | \ ++ (0 << CS42L42_SW_REF_HS3_SHIFT)) ++#define CS42L42_HSDET_SW_TYPE3 ((1 << CS42L42_SW_GNDHS_HS4_SHIFT) | \ ++ (1 << CS42L42_SW_GNDHS_HS3_SHIFT) | \ ++ (0 << CS42L42_SW_HSB_HS4_SHIFT) | \ ++ (0 << CS42L42_SW_HSB_HS3_SHIFT) | \ ++ (1 << CS42L42_SW_HSB_FILT_HS4_SHIFT) | \ ++ (1 << CS42L42_SW_HSB_FILT_HS3_SHIFT) | \ ++ (1 << CS42L42_SW_REF_HS4_SHIFT) | \ ++ (1 << CS42L42_SW_REF_HS3_SHIFT)) ++#define CS42L42_HSDET_SW_TYPE4 ((0 << CS42L42_SW_GNDHS_HS4_SHIFT) | \ ++ (1 << CS42L42_SW_GNDHS_HS3_SHIFT) | \ ++ (1 << CS42L42_SW_HSB_HS4_SHIFT) | \ ++ (0 << CS42L42_SW_HSB_HS3_SHIFT) | \ ++ (0 << CS42L42_SW_HSB_FILT_HS4_SHIFT) | \ ++ (1 << CS42L42_SW_HSB_FILT_HS3_SHIFT) | \ ++ (0 << CS42L42_SW_REF_HS4_SHIFT) | \ ++ (1 << CS42L42_SW_REF_HS3_SHIFT)) ++ ++#define CS42L42_HSDET_COMP_TYPE1 1 ++#define CS42L42_HSDET_COMP_TYPE2 2 ++#define CS42L42_HSDET_COMP_TYPE3 0 ++#define CS42L42_HSDET_COMP_TYPE4 3 ++ + #define CS42L42_HS_CLAMP_DISABLE (CS42L42_PAGE_11 + 0x29) + #define CS42L42_HS_CLAMP_DISABLE_SHIFT 0 + #define CS42L42_HS_CLAMP_DISABLE_MASK (1 << CS42L42_HS_CLAMP_DISABLE_SHIFT) +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs42l42-Mark-OSC_SWITCH_STATUS-register-volatil.patch b/patches.suse/ASoC-cs42l42-Mark-OSC_SWITCH_STATUS-register-volatil.patch new file mode 100644 index 0000000..e742586 --- /dev/null +++ b/patches.suse/ASoC-cs42l42-Mark-OSC_SWITCH_STATUS-register-volatil.patch @@ -0,0 +1,43 @@ +From 0c3d6c6ff75aa6b21cd4ac872dd3050b6525c75c Mon Sep 17 00:00:00 2001 +From: Richard Fitzgerald +Date: Fri, 15 Oct 2021 14:36:17 +0100 +Subject: [PATCH] ASoC: cs42l42: Mark OSC_SWITCH_STATUS register volatile +Git-commit: 0c3d6c6ff75aa6b21cd4ac872dd3050b6525c75c +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +OSC_SWITCH_STATUS is a volatile register indicating the current state +of the clock switch logic. + +Signed-off-by: Richard Fitzgerald +Link: https://lore.kernel.org/r/20211015133619.4698-15-rf@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs42l42.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c +index d62272d0ab8c..390cd7ea3a7f 100644 +--- a/sound/soc/codecs/cs42l42.c ++++ b/sound/soc/codecs/cs42l42.c +@@ -52,7 +52,6 @@ static const struct reg_default cs42l42_reg_defaults[] = { + { CS42L42_RSENSE_CTL1, 0x40 }, + { CS42L42_RSENSE_CTL2, 0x00 }, + { CS42L42_OSC_SWITCH, 0x00 }, +- { CS42L42_OSC_SWITCH_STATUS, 0x05 }, + { CS42L42_RSENSE_CTL3, 0x1B }, + { CS42L42_TSENSE_CTL, 0x1B }, + { CS42L42_TSRS_INT_DISABLE, 0x00 }, +@@ -331,6 +330,7 @@ static bool cs42l42_volatile_register(struct device *dev, unsigned int reg) + case CS42L42_DEVID_CD: + case CS42L42_DEVID_E: + case CS42L42_MCLK_STATUS: ++ case CS42L42_OSC_SWITCH_STATUS: + case CS42L42_TRSENSE_STATUS: + case CS42L42_HS_DET_STATUS: + case CS42L42_ADC_OVFL_STATUS: +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs42l42-Minor-fix-all-errors-reported-by-checkp.patch b/patches.suse/ASoC-cs42l42-Minor-fix-all-errors-reported-by-checkp.patch new file mode 100644 index 0000000..17496af --- /dev/null +++ b/patches.suse/ASoC-cs42l42-Minor-fix-all-errors-reported-by-checkp.patch @@ -0,0 +1,64 @@ +From 7a20dec45d0701671abca965b0dd3e4cda2af3d3 Mon Sep 17 00:00:00 2001 +From: Vitaly Rodionov +Date: Thu, 16 Sep 2021 12:09:32 +0100 +Subject: [PATCH] ASoC: cs42l42: Minor fix all errors reported by checkpatch.pl script +Git-commit: 7a20dec45d0701671abca965b0dd3e4cda2af3d3 +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +Signed-off-by: Vitaly Rodionov +Link: https://lore.kernel.org/r/20210916110932.10293-1-vitalyr@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs42l42.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/sound/soc/codecs/cs42l42.c ++++ b/sound/soc/codecs/cs42l42.c +@@ -831,7 +831,7 @@ static int cs42l42_pcm_hw_params(struct + if (params_width(params) == 24) + cs42l42->bclk = (cs42l42->bclk / 3) * 4; + +- switch(substream->stream) { ++ switch (substream->stream) { + case SNDRV_PCM_STREAM_CAPTURE: + /* channel 2 on high LRCLK */ + val = CS42L42_ASP_TX_CH2_AP_MASK | +@@ -913,7 +913,7 @@ static int cs42l42_mute_stream(struct sn + CS42L42_HP_ANA_BMUTE_MASK); + + cs42l42->stream_use &= ~(1 << stream); +- if(!cs42l42->stream_use) { ++ if (!cs42l42->stream_use) { + /* + * Switch to the internal oscillator. + * SCLK must remain running until after this clock switch. +@@ -984,7 +984,7 @@ static int cs42l42_mute_stream(struct sn + + #define CS42L42_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ +- SNDRV_PCM_FMTBIT_S32_LE ) ++ SNDRV_PCM_FMTBIT_S32_LE) + + static const struct snd_soc_dai_ops cs42l42_ops = { + .startup = cs42l42_dai_startup, +@@ -1461,7 +1461,7 @@ static irqreturn_t cs42l42_irq_thread(in + if ((~masks[5]) & irq_params_table[5].mask) { + if (stickies[5] & CS42L42_HSDET_AUTO_DONE_MASK) { + cs42l42_process_hs_type_detect(cs42l42); +- switch(cs42l42->hs_type){ ++ switch (cs42l42->hs_type) { + case CS42L42_PLUG_CTIA: + case CS42L42_PLUG_OMTP: + snd_soc_jack_report(cs42l42->jack, SND_JACK_HEADSET, +@@ -1493,7 +1493,7 @@ static irqreturn_t cs42l42_irq_thread(in + cs42l42->plug_state = CS42L42_TS_UNPLUG; + cs42l42_cancel_hs_type_detect(cs42l42); + +- switch(cs42l42->hs_type){ ++ switch (cs42l42->hs_type) { + case CS42L42_PLUG_CTIA: + case CS42L42_PLUG_OMTP: + snd_soc_jack_report(cs42l42->jack, 0, SND_JACK_HEADSET); diff --git a/patches.suse/ASoC-cs42l42-Move-CS42L42-register-descriptions-to-g.patch b/patches.suse/ASoC-cs42l42-Move-CS42L42-register-descriptions-to-g.patch new file mode 100644 index 0000000..feeca67 --- /dev/null +++ b/patches.suse/ASoC-cs42l42-Move-CS42L42-register-descriptions-to-g.patch @@ -0,0 +1,1686 @@ +From 7b43e6d795623e23834dd528c36023f692468480 Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Wed, 4 May 2022 17:12:34 +0100 +Subject: [PATCH] ASoC: cs42l42: Move CS42L42 register descriptions to general include +Git-commit: 7b43e6d795623e23834dd528c36023f692468480 +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +This is to allow the hda driver to have access to the register names, +for improved maintainability. +Also ensure new header is aligned to 100 columns. + +Signed-off-by: Stefan Binding +Acked-by: Mark Brown +Link: https://lore.kernel.org/r/20220504161236.2490532-2-sbinding@opensource.cirrus.com +Signed-off-by: Takashi Iwai + +--- + include/sound/cs42l42.h | 810 ++++++++++++++++++++++++++++++++++++ + sound/soc/codecs/cs42l42.h | 826 +------------------------------------ + 2 files changed, 812 insertions(+), 824 deletions(-) + create mode 100644 include/sound/cs42l42.h + +diff --git a/include/sound/cs42l42.h b/include/sound/cs42l42.h +new file mode 100644 +index 000000000000..a55d522f1772 +--- /dev/null ++++ b/include/sound/cs42l42.h +@@ -0,0 +1,810 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * linux/sound/cs42l42.h -- Platform data for CS42L42 ALSA SoC audio driver header ++ * ++ * Copyright 2016-2022 Cirrus Logic, Inc. ++ * ++ * Author: James Schulman ++ * Author: Brian Austin ++ * Author: Michael White ++ */ ++ ++#ifndef __CS42L42_H ++#define __CS42L42_H ++ ++#define CS42L42_PAGE_REGISTER 0x00 /* Page Select Register */ ++#define CS42L42_WIN_START 0x00 ++#define CS42L42_WIN_LEN 0x100 ++#define CS42L42_RANGE_MIN 0x00 ++#define CS42L42_RANGE_MAX 0x7F ++ ++#define CS42L42_PAGE_10 0x1000 ++#define CS42L42_PAGE_11 0x1100 ++#define CS42L42_PAGE_12 0x1200 ++#define CS42L42_PAGE_13 0x1300 ++#define CS42L42_PAGE_15 0x1500 ++#define CS42L42_PAGE_19 0x1900 ++#define CS42L42_PAGE_1B 0x1B00 ++#define CS42L42_PAGE_1C 0x1C00 ++#define CS42L42_PAGE_1D 0x1D00 ++#define CS42L42_PAGE_1F 0x1F00 ++#define CS42L42_PAGE_20 0x2000 ++#define CS42L42_PAGE_21 0x2100 ++#define CS42L42_PAGE_23 0x2300 ++#define CS42L42_PAGE_24 0x2400 ++#define CS42L42_PAGE_25 0x2500 ++#define CS42L42_PAGE_26 0x2600 ++#define CS42L42_PAGE_28 0x2800 ++#define CS42L42_PAGE_29 0x2900 ++#define CS42L42_PAGE_2A 0x2A00 ++#define CS42L42_PAGE_30 0x3000 ++ ++#define CS42L42_CHIP_ID 0x42A42 ++ ++/* Page 0x10 Global Registers */ ++#define CS42L42_DEVID_AB (CS42L42_PAGE_10 + 0x01) ++#define CS42L42_DEVID_CD (CS42L42_PAGE_10 + 0x02) ++#define CS42L42_DEVID_E (CS42L42_PAGE_10 + 0x03) ++#define CS42L42_FABID (CS42L42_PAGE_10 + 0x04) ++#define CS42L42_REVID (CS42L42_PAGE_10 + 0x05) ++#define CS42L42_FRZ_CTL (CS42L42_PAGE_10 + 0x06) ++ ++#define CS42L42_SRC_CTL (CS42L42_PAGE_10 + 0x07) ++#define CS42L42_SRC_BYPASS_DAC_SHIFT 1 ++#define CS42L42_SRC_BYPASS_DAC_MASK (1 << CS42L42_SRC_BYPASS_DAC_SHIFT) ++ ++#define CS42L42_MCLK_STATUS (CS42L42_PAGE_10 + 0x08) ++ ++#define CS42L42_MCLK_CTL (CS42L42_PAGE_10 + 0x09) ++#define CS42L42_INTERNAL_FS_SHIFT 1 ++#define CS42L42_INTERNAL_FS_MASK (1 << CS42L42_INTERNAL_FS_SHIFT) ++ ++#define CS42L42_SFTRAMP_RATE (CS42L42_PAGE_10 + 0x0A) ++#define CS42L42_SLOW_START_ENABLE (CS42L42_PAGE_10 + 0x0B) ++#define CS42L42_SLOW_START_EN_MASK GENMASK(6, 4) ++#define CS42L42_SLOW_START_EN_SHIFT 4 ++#define CS42L42_I2C_DEBOUNCE (CS42L42_PAGE_10 + 0x0E) ++#define CS42L42_I2C_STRETCH (CS42L42_PAGE_10 + 0x0F) ++#define CS42L42_I2C_TIMEOUT (CS42L42_PAGE_10 + 0x10) ++ ++/* Page 0x11 Power and Headset Detect Registers */ ++#define CS42L42_PWR_CTL1 (CS42L42_PAGE_11 + 0x01) ++#define CS42L42_ASP_DAO_PDN_SHIFT 7 ++#define CS42L42_ASP_DAO_PDN_MASK (1 << CS42L42_ASP_DAO_PDN_SHIFT) ++#define CS42L42_ASP_DAI_PDN_SHIFT 6 ++#define CS42L42_ASP_DAI_PDN_MASK (1 << CS42L42_ASP_DAI_PDN_SHIFT) ++#define CS42L42_MIXER_PDN_SHIFT 5 ++#define CS42L42_MIXER_PDN_MASK (1 << CS42L42_MIXER_PDN_SHIFT) ++#define CS42L42_EQ_PDN_SHIFT 4 ++#define CS42L42_EQ_PDN_MASK (1 << CS42L42_EQ_PDN_SHIFT) ++#define CS42L42_HP_PDN_SHIFT 3 ++#define CS42L42_HP_PDN_MASK (1 << CS42L42_HP_PDN_SHIFT) ++#define CS42L42_ADC_PDN_SHIFT 2 ++#define CS42L42_ADC_PDN_MASK (1 << CS42L42_ADC_PDN_SHIFT) ++#define CS42L42_PDN_ALL_SHIFT 0 ++#define CS42L42_PDN_ALL_MASK (1 << CS42L42_PDN_ALL_SHIFT) ++ ++#define CS42L42_PWR_CTL2 (CS42L42_PAGE_11 + 0x02) ++#define CS42L42_ADC_SRC_PDNB_SHIFT 0 ++#define CS42L42_ADC_SRC_PDNB_MASK (1 << CS42L42_ADC_SRC_PDNB_SHIFT) ++#define CS42L42_DAC_SRC_PDNB_SHIFT 1 ++#define CS42L42_DAC_SRC_PDNB_MASK (1 << CS42L42_DAC_SRC_PDNB_SHIFT) ++#define CS42L42_ASP_DAI1_PDN_SHIFT 2 ++#define CS42L42_ASP_DAI1_PDN_MASK (1 << CS42L42_ASP_DAI1_PDN_SHIFT) ++#define CS42L42_SRC_PDN_OVERRIDE_SHIFT 3 ++#define CS42L42_SRC_PDN_OVERRIDE_MASK (1 << CS42L42_SRC_PDN_OVERRIDE_SHIFT) ++#define CS42L42_DISCHARGE_FILT_SHIFT 4 ++#define CS42L42_DISCHARGE_FILT_MASK (1 << CS42L42_DISCHARGE_FILT_SHIFT) ++ ++#define CS42L42_PWR_CTL3 (CS42L42_PAGE_11 + 0x03) ++#define CS42L42_RING_SENSE_PDNB_SHIFT 1 ++#define CS42L42_RING_SENSE_PDNB_MASK (1 << CS42L42_RING_SENSE_PDNB_SHIFT) ++#define CS42L42_VPMON_PDNB_SHIFT 2 ++#define CS42L42_VPMON_PDNB_MASK (1 << CS42L42_VPMON_PDNB_SHIFT) ++#define CS42L42_SW_CLK_STP_STAT_SEL_SHIFT 5 ++#define CS42L42_SW_CLK_STP_STAT_SEL_MASK (3 << CS42L42_SW_CLK_STP_STAT_SEL_SHIFT) ++ ++#define CS42L42_RSENSE_CTL1 (CS42L42_PAGE_11 + 0x04) ++#define CS42L42_RS_TRIM_R_SHIFT 0 ++#define CS42L42_RS_TRIM_R_MASK (1 << CS42L42_RS_TRIM_R_SHIFT) ++#define CS42L42_RS_TRIM_T_SHIFT 1 ++#define CS42L42_RS_TRIM_T_MASK (1 << CS42L42_RS_TRIM_T_SHIFT) ++#define CS42L42_HPREF_RS_SHIFT 2 ++#define CS42L42_HPREF_RS_MASK (1 << CS42L42_HPREF_RS_SHIFT) ++#define CS42L42_HSBIAS_FILT_REF_RS_SHIFT 3 ++#define CS42L42_HSBIAS_FILT_REF_RS_MASK (1 << CS42L42_HSBIAS_FILT_REF_RS_SHIFT) ++#define CS42L42_RING_SENSE_PU_HIZ_SHIFT 6 ++#define CS42L42_RING_SENSE_PU_HIZ_MASK (1 << CS42L42_RING_SENSE_PU_HIZ_SHIFT) ++ ++#define CS42L42_RSENSE_CTL2 (CS42L42_PAGE_11 + 0x05) ++#define CS42L42_TS_RS_GATE_SHIFT 7 ++#define CS42L42_TS_RS_GATE_MAS (1 << CS42L42_TS_RS_GATE_SHIFT) ++ ++#define CS42L42_OSC_SWITCH (CS42L42_PAGE_11 + 0x07) ++#define CS42L42_SCLK_PRESENT_SHIFT 0 ++#define CS42L42_SCLK_PRESENT_MASK (1 << CS42L42_SCLK_PRESENT_SHIFT) ++ ++#define CS42L42_OSC_SWITCH_STATUS (CS42L42_PAGE_11 + 0x09) ++#define CS42L42_OSC_SW_SEL_STAT_SHIFT 0 ++#define CS42L42_OSC_SW_SEL_STAT_MASK (3 << CS42L42_OSC_SW_SEL_STAT_SHIFT) ++#define CS42L42_OSC_PDNB_STAT_SHIFT 2 ++#define CS42L42_OSC_PDNB_STAT_MASK (1 << CS42L42_OSC_SW_SEL_STAT_SHIFT) ++ ++#define CS42L42_RSENSE_CTL3 (CS42L42_PAGE_11 + 0x12) ++#define CS42L42_RS_RISE_DBNCE_TIME_SHIFT 0 ++#define CS42L42_RS_RISE_DBNCE_TIME_MASK (7 << CS42L42_RS_RISE_DBNCE_TIME_SHIFT) ++#define CS42L42_RS_FALL_DBNCE_TIME_SHIFT 3 ++#define CS42L42_RS_FALL_DBNCE_TIME_MASK (7 << CS42L42_RS_FALL_DBNCE_TIME_SHIFT) ++#define CS42L42_RS_PU_EN_SHIFT 6 ++#define CS42L42_RS_PU_EN_MASK (1 << CS42L42_RS_PU_EN_SHIFT) ++#define CS42L42_RS_INV_SHIFT 7 ++#define CS42L42_RS_INV_MASK (1 << CS42L42_RS_INV_SHIFT) ++ ++#define CS42L42_TSENSE_CTL (CS42L42_PAGE_11 + 0x13) ++#define CS42L42_TS_RISE_DBNCE_TIME_SHIFT 0 ++#define CS42L42_TS_RISE_DBNCE_TIME_MASK (7 << CS42L42_TS_RISE_DBNCE_TIME_SHIFT) ++#define CS42L42_TS_FALL_DBNCE_TIME_SHIFT 3 ++#define CS42L42_TS_FALL_DBNCE_TIME_MASK (7 << CS42L42_TS_FALL_DBNCE_TIME_SHIFT) ++#define CS42L42_TS_INV_SHIFT 7 ++#define CS42L42_TS_INV_MASK (1 << CS42L42_TS_INV_SHIFT) ++ ++#define CS42L42_TSRS_INT_DISABLE (CS42L42_PAGE_11 + 0x14) ++#define CS42L42_D_RS_PLUG_DBNC_SHIFT 0 ++#define CS42L42_D_RS_PLUG_DBNC_MASK (1 << CS42L42_D_RS_PLUG_DBNC_SHIFT) ++#define CS42L42_D_RS_UNPLUG_DBNC_SHIFT 1 ++#define CS42L42_D_RS_UNPLUG_DBNC_MASK (1 << CS42L42_D_RS_UNPLUG_DBNC_SHIFT) ++#define CS42L42_D_TS_PLUG_DBNC_SHIFT 2 ++#define CS42L42_D_TS_PLUG_DBNC_MASK (1 << CS42L42_D_TS_PLUG_DBNC_SHIFT) ++#define CS42L42_D_TS_UNPLUG_DBNC_SHIFT 3 ++#define CS42L42_D_TS_UNPLUG_DBNC_MASK (1 << CS42L42_D_TS_UNPLUG_DBNC_SHIFT) ++ ++#define CS42L42_TRSENSE_STATUS (CS42L42_PAGE_11 + 0x15) ++#define CS42L42_RS_PLUG_DBNC_SHIFT 0 ++#define CS42L42_RS_PLUG_DBNC_MASK (1 << CS42L42_RS_PLUG_DBNC_SHIFT) ++#define CS42L42_RS_UNPLUG_DBNC_SHIFT 1 ++#define CS42L42_RS_UNPLUG_DBNC_MASK (1 << CS42L42_RS_UNPLUG_DBNC_SHIFT) ++#define CS42L42_TS_PLUG_DBNC_SHIFT 2 ++#define CS42L42_TS_PLUG_DBNC_MASK (1 << CS42L42_TS_PLUG_DBNC_SHIFT) ++#define CS42L42_TS_UNPLUG_DBNC_SHIFT 3 ++#define CS42L42_TS_UNPLUG_DBNC_MASK (1 << CS42L42_TS_UNPLUG_DBNC_SHIFT) ++ ++#define CS42L42_HSDET_CTL1 (CS42L42_PAGE_11 + 0x1F) ++#define CS42L42_HSDET_COMP1_LVL_SHIFT 0 ++#define CS42L42_HSDET_COMP1_LVL_MASK (15 << CS42L42_HSDET_COMP1_LVL_SHIFT) ++#define CS42L42_HSDET_COMP2_LVL_SHIFT 4 ++#define CS42L42_HSDET_COMP2_LVL_MASK (15 << CS42L42_HSDET_COMP2_LVL_SHIFT) ++ ++#define CS42L42_HSDET_COMP1_LVL_VAL 12 /* 1.25V Comparator */ ++#define CS42L42_HSDET_COMP2_LVL_VAL 2 /* 1.75V Comparator */ ++#define CS42L42_HSDET_COMP1_LVL_DEFAULT 7 /* 1V Comparator */ ++#define CS42L42_HSDET_COMP2_LVL_DEFAULT 7 /* 2V Comparator */ ++ ++#define CS42L42_HSDET_CTL2 (CS42L42_PAGE_11 + 0x20) ++#define CS42L42_HSDET_AUTO_TIME_SHIFT 0 ++#define CS42L42_HSDET_AUTO_TIME_MASK (3 << CS42L42_HSDET_AUTO_TIME_SHIFT) ++#define CS42L42_HSBIAS_REF_SHIFT 3 ++#define CS42L42_HSBIAS_REF_MASK (1 << CS42L42_HSBIAS_REF_SHIFT) ++#define CS42L42_HSDET_SET_SHIFT 4 ++#define CS42L42_HSDET_SET_MASK (3 << CS42L42_HSDET_SET_SHIFT) ++#define CS42L42_HSDET_CTRL_SHIFT 6 ++#define CS42L42_HSDET_CTRL_MASK (3 << CS42L42_HSDET_CTRL_SHIFT) ++ ++#define CS42L42_HS_SWITCH_CTL (CS42L42_PAGE_11 + 0x21) ++#define CS42L42_SW_GNDHS_HS4_SHIFT 0 ++#define CS42L42_SW_GNDHS_HS4_MASK (1 << CS42L42_SW_GNDHS_HS4_SHIFT) ++#define CS42L42_SW_GNDHS_HS3_SHIFT 1 ++#define CS42L42_SW_GNDHS_HS3_MASK (1 << CS42L42_SW_GNDHS_HS3_SHIFT) ++#define CS42L42_SW_HSB_HS4_SHIFT 2 ++#define CS42L42_SW_HSB_HS4_MASK (1 << CS42L42_SW_HSB_HS4_SHIFT) ++#define CS42L42_SW_HSB_HS3_SHIFT 3 ++#define CS42L42_SW_HSB_HS3_MASK (1 << CS42L42_SW_HSB_HS3_SHIFT) ++#define CS42L42_SW_HSB_FILT_HS4_SHIFT 4 ++#define CS42L42_SW_HSB_FILT_HS4_MASK (1 << CS42L42_SW_HSB_FILT_HS4_SHIFT) ++#define CS42L42_SW_HSB_FILT_HS3_SHIFT 5 ++#define CS42L42_SW_HSB_FILT_HS3_MASK (1 << CS42L42_SW_HSB_FILT_HS3_SHIFT) ++#define CS42L42_SW_REF_HS4_SHIFT 6 ++#define CS42L42_SW_REF_HS4_MASK (1 << CS42L42_SW_REF_HS4_SHIFT) ++#define CS42L42_SW_REF_HS3_SHIFT 7 ++#define CS42L42_SW_REF_HS3_MASK (1 << CS42L42_SW_REF_HS3_SHIFT) ++ ++#define CS42L42_HS_DET_STATUS (CS42L42_PAGE_11 + 0x24) ++#define CS42L42_HSDET_TYPE_SHIFT 0 ++#define CS42L42_HSDET_TYPE_MASK (3 << CS42L42_HSDET_TYPE_SHIFT) ++#define CS42L42_HSDET_COMP1_OUT_SHIFT 6 ++#define CS42L42_HSDET_COMP1_OUT_MASK (1 << CS42L42_HSDET_COMP1_OUT_SHIFT) ++#define CS42L42_HSDET_COMP2_OUT_SHIFT 7 ++#define CS42L42_HSDET_COMP2_OUT_MASK (1 << CS42L42_HSDET_COMP2_OUT_SHIFT) ++#define CS42L42_PLUG_CTIA 0 ++#define CS42L42_PLUG_OMTP 1 ++#define CS42L42_PLUG_HEADPHONE 2 ++#define CS42L42_PLUG_INVALID 3 ++ ++#define CS42L42_HSDET_SW_COMP1 ((0 << CS42L42_SW_GNDHS_HS4_SHIFT) | \ ++ (1 << CS42L42_SW_GNDHS_HS3_SHIFT) | \ ++ (1 << CS42L42_SW_HSB_HS4_SHIFT) | \ ++ (0 << CS42L42_SW_HSB_HS3_SHIFT) | \ ++ (0 << CS42L42_SW_HSB_FILT_HS4_SHIFT) | \ ++ (1 << CS42L42_SW_HSB_FILT_HS3_SHIFT) | \ ++ (0 << CS42L42_SW_REF_HS4_SHIFT) | \ ++ (1 << CS42L42_SW_REF_HS3_SHIFT)) ++#define CS42L42_HSDET_SW_COMP2 ((1 << CS42L42_SW_GNDHS_HS4_SHIFT) | \ ++ (0 << CS42L42_SW_GNDHS_HS3_SHIFT) | \ ++ (0 << CS42L42_SW_HSB_HS4_SHIFT) | \ ++ (1 << CS42L42_SW_HSB_HS3_SHIFT) | \ ++ (1 << CS42L42_SW_HSB_FILT_HS4_SHIFT) | \ ++ (0 << CS42L42_SW_HSB_FILT_HS3_SHIFT) | \ ++ (1 << CS42L42_SW_REF_HS4_SHIFT) | \ ++ (0 << CS42L42_SW_REF_HS3_SHIFT)) ++#define CS42L42_HSDET_SW_TYPE1 ((0 << CS42L42_SW_GNDHS_HS4_SHIFT) | \ ++ (1 << CS42L42_SW_GNDHS_HS3_SHIFT) | \ ++ (1 << CS42L42_SW_HSB_HS4_SHIFT) | \ ++ (0 << CS42L42_SW_HSB_HS3_SHIFT) | \ ++ (0 << CS42L42_SW_HSB_FILT_HS4_SHIFT) | \ ++ (1 << CS42L42_SW_HSB_FILT_HS3_SHIFT) | \ ++ (0 << CS42L42_SW_REF_HS4_SHIFT) | \ ++ (1 << CS42L42_SW_REF_HS3_SHIFT)) ++#define CS42L42_HSDET_SW_TYPE2 ((1 << CS42L42_SW_GNDHS_HS4_SHIFT) | \ ++ (0 << CS42L42_SW_GNDHS_HS3_SHIFT) | \ ++ (0 << CS42L42_SW_HSB_HS4_SHIFT) | \ ++ (1 << CS42L42_SW_HSB_HS3_SHIFT) | \ ++ (1 << CS42L42_SW_HSB_FILT_HS4_SHIFT) | \ ++ (0 << CS42L42_SW_HSB_FILT_HS3_SHIFT) | \ ++ (1 << CS42L42_SW_REF_HS4_SHIFT) | \ ++ (0 << CS42L42_SW_REF_HS3_SHIFT)) ++#define CS42L42_HSDET_SW_TYPE3 ((1 << CS42L42_SW_GNDHS_HS4_SHIFT) | \ ++ (1 << CS42L42_SW_GNDHS_HS3_SHIFT) | \ ++ (0 << CS42L42_SW_HSB_HS4_SHIFT) | \ ++ (0 << CS42L42_SW_HSB_HS3_SHIFT) | \ ++ (1 << CS42L42_SW_HSB_FILT_HS4_SHIFT) | \ ++ (1 << CS42L42_SW_HSB_FILT_HS3_SHIFT) | \ ++ (1 << CS42L42_SW_REF_HS4_SHIFT) | \ ++ (1 << CS42L42_SW_REF_HS3_SHIFT)) ++#define CS42L42_HSDET_SW_TYPE4 ((0 << CS42L42_SW_GNDHS_HS4_SHIFT) | \ ++ (1 << CS42L42_SW_GNDHS_HS3_SHIFT) | \ ++ (1 << CS42L42_SW_HSB_HS4_SHIFT) | \ ++ (0 << CS42L42_SW_HSB_HS3_SHIFT) | \ ++ (0 << CS42L42_SW_HSB_FILT_HS4_SHIFT) | \ ++ (1 << CS42L42_SW_HSB_FILT_HS3_SHIFT) | \ ++ (0 << CS42L42_SW_REF_HS4_SHIFT) | \ ++ (1 << CS42L42_SW_REF_HS3_SHIFT)) ++ ++#define CS42L42_HSDET_COMP_TYPE1 1 ++#define CS42L42_HSDET_COMP_TYPE2 2 ++#define CS42L42_HSDET_COMP_TYPE3 0 ++#define CS42L42_HSDET_COMP_TYPE4 3 ++ ++#define CS42L42_HS_CLAMP_DISABLE (CS42L42_PAGE_11 + 0x29) ++#define CS42L42_HS_CLAMP_DISABLE_SHIFT 0 ++#define CS42L42_HS_CLAMP_DISABLE_MASK (1 << CS42L42_HS_CLAMP_DISABLE_SHIFT) ++ ++/* Page 0x12 Clocking Registers */ ++#define CS42L42_MCLK_SRC_SEL (CS42L42_PAGE_12 + 0x01) ++#define CS42L42_MCLKDIV_SHIFT 1 ++#define CS42L42_MCLKDIV_MASK (1 << CS42L42_MCLKDIV_SHIFT) ++#define CS42L42_MCLK_SRC_SEL_SHIFT 0 ++#define CS42L42_MCLK_SRC_SEL_MASK (1 << CS42L42_MCLK_SRC_SEL_SHIFT) ++ ++#define CS42L42_SPDIF_CLK_CFG (CS42L42_PAGE_12 + 0x02) ++#define CS42L42_FSYNC_PW_LOWER (CS42L42_PAGE_12 + 0x03) ++ ++#define CS42L42_FSYNC_PW_UPPER (CS42L42_PAGE_12 + 0x04) ++#define CS42L42_FSYNC_PULSE_WIDTH_SHIFT 0 ++#define CS42L42_FSYNC_PULSE_WIDTH_MASK (0xff << \ ++ CS42L42_FSYNC_PULSE_WIDTH_SHIFT) ++ ++#define CS42L42_FSYNC_P_LOWER (CS42L42_PAGE_12 + 0x05) ++ ++#define CS42L42_FSYNC_P_UPPER (CS42L42_PAGE_12 + 0x06) ++#define CS42L42_FSYNC_PERIOD_SHIFT 0 ++#define CS42L42_FSYNC_PERIOD_MASK (0xff << CS42L42_FSYNC_PERIOD_SHIFT) ++ ++#define CS42L42_ASP_CLK_CFG (CS42L42_PAGE_12 + 0x07) ++#define CS42L42_ASP_SCLK_EN_SHIFT 5 ++#define CS42L42_ASP_SCLK_EN_MASK (1 << CS42L42_ASP_SCLK_EN_SHIFT) ++#define CS42L42_ASP_MASTER_MODE 0x01 ++#define CS42L42_ASP_SLAVE_MODE 0x00 ++#define CS42L42_ASP_MODE_SHIFT 4 ++#define CS42L42_ASP_MODE_MASK (1 << CS42L42_ASP_MODE_SHIFT) ++#define CS42L42_ASP_SCPOL_SHIFT 2 ++#define CS42L42_ASP_SCPOL_MASK (3 << CS42L42_ASP_SCPOL_SHIFT) ++#define CS42L42_ASP_SCPOL_NOR 3 ++#define CS42L42_ASP_LCPOL_SHIFT 0 ++#define CS42L42_ASP_LCPOL_MASK (3 << CS42L42_ASP_LCPOL_SHIFT) ++#define CS42L42_ASP_LCPOL_INV 3 ++ ++#define CS42L42_ASP_FRM_CFG (CS42L42_PAGE_12 + 0x08) ++#define CS42L42_ASP_STP_SHIFT 4 ++#define CS42L42_ASP_STP_MASK (1 << CS42L42_ASP_STP_SHIFT) ++#define CS42L42_ASP_5050_SHIFT 3 ++#define CS42L42_ASP_5050_MASK (1 << CS42L42_ASP_5050_SHIFT) ++#define CS42L42_ASP_FSD_SHIFT 0 ++#define CS42L42_ASP_FSD_MASK (7 << CS42L42_ASP_FSD_SHIFT) ++#define CS42L42_ASP_FSD_0_5 1 ++#define CS42L42_ASP_FSD_1_0 2 ++#define CS42L42_ASP_FSD_1_5 3 ++#define CS42L42_ASP_FSD_2_0 4 ++ ++#define CS42L42_FS_RATE_EN (CS42L42_PAGE_12 + 0x09) ++#define CS42L42_FS_EN_SHIFT 0 ++#define CS42L42_FS_EN_MASK (0xf << CS42L42_FS_EN_SHIFT) ++#define CS42L42_FS_EN_IASRC_96K 0x1 ++#define CS42L42_FS_EN_OASRC_96K 0x2 ++ ++#define CS42L42_IN_ASRC_CLK (CS42L42_PAGE_12 + 0x0A) ++#define CS42L42_CLK_IASRC_SEL_SHIFT 0 ++#define CS42L42_CLK_IASRC_SEL_MASK (1 << CS42L42_CLK_IASRC_SEL_SHIFT) ++#define CS42L42_CLK_IASRC_SEL_6 0 ++#define CS42L42_CLK_IASRC_SEL_12 1 ++ ++#define CS42L42_OUT_ASRC_CLK (CS42L42_PAGE_12 + 0x0B) ++#define CS42L42_CLK_OASRC_SEL_SHIFT 0 ++#define CS42L42_CLK_OASRC_SEL_MASK (1 << CS42L42_CLK_OASRC_SEL_SHIFT) ++#define CS42L42_CLK_OASRC_SEL_12 1 ++ ++#define CS42L42_PLL_DIV_CFG1 (CS42L42_PAGE_12 + 0x0C) ++#define CS42L42_SCLK_PREDIV_SHIFT 0 ++#define CS42L42_SCLK_PREDIV_MASK (3 << CS42L42_SCLK_PREDIV_SHIFT) ++ ++/* Page 0x13 Interrupt Registers */ ++/* Interrupts */ ++#define CS42L42_ADC_OVFL_STATUS (CS42L42_PAGE_13 + 0x01) ++#define CS42L42_MIXER_STATUS (CS42L42_PAGE_13 + 0x02) ++#define CS42L42_SRC_STATUS (CS42L42_PAGE_13 + 0x03) ++#define CS42L42_ASP_RX_STATUS (CS42L42_PAGE_13 + 0x04) ++#define CS42L42_ASP_TX_STATUS (CS42L42_PAGE_13 + 0x05) ++#define CS42L42_CODEC_STATUS (CS42L42_PAGE_13 + 0x08) ++#define CS42L42_DET_INT_STATUS1 (CS42L42_PAGE_13 + 0x09) ++#define CS42L42_DET_INT_STATUS2 (CS42L42_PAGE_13 + 0x0A) ++#define CS42L42_SRCPL_INT_STATUS (CS42L42_PAGE_13 + 0x0B) ++#define CS42L42_VPMON_STATUS (CS42L42_PAGE_13 + 0x0D) ++#define CS42L42_PLL_LOCK_STATUS (CS42L42_PAGE_13 + 0x0E) ++#define CS42L42_TSRS_PLUG_STATUS (CS42L42_PAGE_13 + 0x0F) ++/* Masks */ ++#define CS42L42_ADC_OVFL_INT_MASK (CS42L42_PAGE_13 + 0x16) ++#define CS42L42_ADC_OVFL_SHIFT 0 ++#define CS42L42_ADC_OVFL_MASK (1 << CS42L42_ADC_OVFL_SHIFT) ++#define CS42L42_ADC_OVFL_VAL_MASK CS42L42_ADC_OVFL_MASK ++ ++#define CS42L42_MIXER_INT_MASK (CS42L42_PAGE_13 + 0x17) ++#define CS42L42_MIX_CHB_OVFL_SHIFT 0 ++#define CS42L42_MIX_CHB_OVFL_MASK (1 << CS42L42_MIX_CHB_OVFL_SHIFT) ++#define CS42L42_MIX_CHA_OVFL_SHIFT 1 ++#define CS42L42_MIX_CHA_OVFL_MASK (1 << CS42L42_MIX_CHA_OVFL_SHIFT) ++#define CS42L42_EQ_OVFL_SHIFT 2 ++#define CS42L42_EQ_OVFL_MASK (1 << CS42L42_EQ_OVFL_SHIFT) ++#define CS42L42_EQ_BIQUAD_OVFL_SHIFT 3 ++#define CS42L42_EQ_BIQUAD_OVFL_MASK (1 << CS42L42_EQ_BIQUAD_OVFL_SHIFT) ++#define CS42L42_MIXER_VAL_MASK (CS42L42_MIX_CHB_OVFL_MASK | \ ++ CS42L42_MIX_CHA_OVFL_MASK | \ ++ CS42L42_EQ_OVFL_MASK | \ ++ CS42L42_EQ_BIQUAD_OVFL_MASK) ++ ++#define CS42L42_SRC_INT_MASK (CS42L42_PAGE_13 + 0x18) ++#define CS42L42_SRC_ILK_SHIFT 0 ++#define CS42L42_SRC_ILK_MASK (1 << CS42L42_SRC_ILK_SHIFT) ++#define CS42L42_SRC_OLK_SHIFT 1 ++#define CS42L42_SRC_OLK_MASK (1 << CS42L42_SRC_OLK_SHIFT) ++#define CS42L42_SRC_IUNLK_SHIFT 2 ++#define CS42L42_SRC_IUNLK_MASK (1 << CS42L42_SRC_IUNLK_SHIFT) ++#define CS42L42_SRC_OUNLK_SHIFT 3 ++#define CS42L42_SRC_OUNLK_MASK (1 << CS42L42_SRC_OUNLK_SHIFT) ++#define CS42L42_SRC_VAL_MASK (CS42L42_SRC_ILK_MASK | \ ++ CS42L42_SRC_OLK_MASK | \ ++ CS42L42_SRC_IUNLK_MASK | \ ++ CS42L42_SRC_OUNLK_MASK) ++ ++#define CS42L42_ASP_RX_INT_MASK (CS42L42_PAGE_13 + 0x19) ++#define CS42L42_ASPRX_NOLRCK_SHIFT 0 ++#define CS42L42_ASPRX_NOLRCK_MASK (1 << CS42L42_ASPRX_NOLRCK_SHIFT) ++#define CS42L42_ASPRX_EARLY_SHIFT 1 ++#define CS42L42_ASPRX_EARLY_MASK (1 << CS42L42_ASPRX_EARLY_SHIFT) ++#define CS42L42_ASPRX_LATE_SHIFT 2 ++#define CS42L42_ASPRX_LATE_MASK (1 << CS42L42_ASPRX_LATE_SHIFT) ++#define CS42L42_ASPRX_ERROR_SHIFT 3 ++#define CS42L42_ASPRX_ERROR_MASK (1 << CS42L42_ASPRX_ERROR_SHIFT) ++#define CS42L42_ASPRX_OVLD_SHIFT 4 ++#define CS42L42_ASPRX_OVLD_MASK (1 << CS42L42_ASPRX_OVLD_SHIFT) ++#define CS42L42_ASP_RX_VAL_MASK (CS42L42_ASPRX_NOLRCK_MASK | \ ++ CS42L42_ASPRX_EARLY_MASK | \ ++ CS42L42_ASPRX_LATE_MASK | \ ++ CS42L42_ASPRX_ERROR_MASK | \ ++ CS42L42_ASPRX_OVLD_MASK) ++ ++#define CS42L42_ASP_TX_INT_MASK (CS42L42_PAGE_13 + 0x1A) ++#define CS42L42_ASPTX_NOLRCK_SHIFT 0 ++#define CS42L42_ASPTX_NOLRCK_MASK (1 << CS42L42_ASPTX_NOLRCK_SHIFT) ++#define CS42L42_ASPTX_EARLY_SHIFT 1 ++#define CS42L42_ASPTX_EARLY_MASK (1 << CS42L42_ASPTX_EARLY_SHIFT) ++#define CS42L42_ASPTX_LATE_SHIFT 2 ++#define CS42L42_ASPTX_LATE_MASK (1 << CS42L42_ASPTX_LATE_SHIFT) ++#define CS42L42_ASPTX_SMERROR_SHIFT 3 ++#define CS42L42_ASPTX_SMERROR_MASK (1 << CS42L42_ASPTX_SMERROR_SHIFT) ++#define CS42L42_ASP_TX_VAL_MASK (CS42L42_ASPTX_NOLRCK_MASK | \ ++ CS42L42_ASPTX_EARLY_MASK | \ ++ CS42L42_ASPTX_LATE_MASK | \ ++ CS42L42_ASPTX_SMERROR_MASK) ++ ++#define CS42L42_CODEC_INT_MASK (CS42L42_PAGE_13 + 0x1B) ++#define CS42L42_PDN_DONE_SHIFT 0 ++#define CS42L42_PDN_DONE_MASK (1 << CS42L42_PDN_DONE_SHIFT) ++#define CS42L42_HSDET_AUTO_DONE_SHIFT 1 ++#define CS42L42_HSDET_AUTO_DONE_MASK (1 << CS42L42_HSDET_AUTO_DONE_SHIFT) ++#define CS42L42_CODEC_VAL_MASK (CS42L42_PDN_DONE_MASK | \ ++ CS42L42_HSDET_AUTO_DONE_MASK) ++ ++#define CS42L42_SRCPL_INT_MASK (CS42L42_PAGE_13 + 0x1C) ++#define CS42L42_SRCPL_ADC_LK_SHIFT 0 ++#define CS42L42_SRCPL_ADC_LK_MASK (1 << CS42L42_SRCPL_ADC_LK_SHIFT) ++#define CS42L42_SRCPL_DAC_LK_SHIFT 2 ++#define CS42L42_SRCPL_DAC_LK_MASK (1 << CS42L42_SRCPL_DAC_LK_SHIFT) ++#define CS42L42_SRCPL_ADC_UNLK_SHIFT 5 ++#define CS42L42_SRCPL_ADC_UNLK_MASK (1 << CS42L42_SRCPL_ADC_UNLK_SHIFT) ++#define CS42L42_SRCPL_DAC_UNLK_SHIFT 6 ++#define CS42L42_SRCPL_DAC_UNLK_MASK (1 << CS42L42_SRCPL_DAC_UNLK_SHIFT) ++#define CS42L42_SRCPL_VAL_MASK (CS42L42_SRCPL_ADC_LK_MASK | \ ++ CS42L42_SRCPL_DAC_LK_MASK | \ ++ CS42L42_SRCPL_ADC_UNLK_MASK | \ ++ CS42L42_SRCPL_DAC_UNLK_MASK) ++ ++#define CS42L42_VPMON_INT_MASK (CS42L42_PAGE_13 + 0x1E) ++#define CS42L42_VPMON_SHIFT 0 ++#define CS42L42_VPMON_MASK (1 << CS42L42_VPMON_SHIFT) ++#define CS42L42_VPMON_VAL_MASK CS42L42_VPMON_MASK ++ ++#define CS42L42_PLL_LOCK_INT_MASK (CS42L42_PAGE_13 + 0x1F) ++#define CS42L42_PLL_LOCK_SHIFT 0 ++#define CS42L42_PLL_LOCK_MASK (1 << CS42L42_PLL_LOCK_SHIFT) ++#define CS42L42_PLL_LOCK_VAL_MASK CS42L42_PLL_LOCK_MASK ++ ++#define CS42L42_TSRS_PLUG_INT_MASK (CS42L42_PAGE_13 + 0x20) ++#define CS42L42_RS_PLUG_SHIFT 0 ++#define CS42L42_RS_PLUG_MASK (1 << CS42L42_RS_PLUG_SHIFT) ++#define CS42L42_RS_UNPLUG_SHIFT 1 ++#define CS42L42_RS_UNPLUG_MASK (1 << CS42L42_RS_UNPLUG_SHIFT) ++#define CS42L42_TS_PLUG_SHIFT 2 ++#define CS42L42_TS_PLUG_MASK (1 << CS42L42_TS_PLUG_SHIFT) ++#define CS42L42_TS_UNPLUG_SHIFT 3 ++#define CS42L42_TS_UNPLUG_MASK (1 << CS42L42_TS_UNPLUG_SHIFT) ++#define CS42L42_TSRS_PLUG_VAL_MASK (CS42L42_RS_PLUG_MASK | \ ++ CS42L42_RS_UNPLUG_MASK | \ ++ CS42L42_TS_PLUG_MASK | \ ++ CS42L42_TS_UNPLUG_MASK) ++#define CS42L42_TS_PLUG 3 ++#define CS42L42_TS_UNPLUG 0 ++#define CS42L42_TS_TRANS 1 ++ ++/* ++ * NOTE: PLL_START must be 0 while both ADC_PDN=1 and HP_PDN=1. ++ * Otherwise it will prevent FILT+ from charging properly. ++ */ ++#define CS42L42_PLL_CTL1 (CS42L42_PAGE_15 + 0x01) ++#define CS42L42_PLL_START_SHIFT 0 ++#define CS42L42_PLL_START_MASK (1 << CS42L42_PLL_START_SHIFT) ++ ++#define CS42L42_PLL_DIV_FRAC0 (CS42L42_PAGE_15 + 0x02) ++#define CS42L42_PLL_DIV_FRAC_SHIFT 0 ++#define CS42L42_PLL_DIV_FRAC_MASK (0xff << CS42L42_PLL_DIV_FRAC_SHIFT) ++ ++#define CS42L42_PLL_DIV_FRAC1 (CS42L42_PAGE_15 + 0x03) ++#define CS42L42_PLL_DIV_FRAC2 (CS42L42_PAGE_15 + 0x04) ++ ++#define CS42L42_PLL_DIV_INT (CS42L42_PAGE_15 + 0x05) ++#define CS42L42_PLL_DIV_INT_SHIFT 0 ++#define CS42L42_PLL_DIV_INT_MASK (0xff << CS42L42_PLL_DIV_INT_SHIFT) ++ ++#define CS42L42_PLL_CTL3 (CS42L42_PAGE_15 + 0x08) ++#define CS42L42_PLL_DIVOUT_SHIFT 0 ++#define CS42L42_PLL_DIVOUT_MASK (0xff << CS42L42_PLL_DIVOUT_SHIFT) ++ ++#define CS42L42_PLL_CAL_RATIO (CS42L42_PAGE_15 + 0x0A) ++#define CS42L42_PLL_CAL_RATIO_SHIFT 0 ++#define CS42L42_PLL_CAL_RATIO_MASK (0xff << CS42L42_PLL_CAL_RATIO_SHIFT) ++ ++#define CS42L42_PLL_CTL4 (CS42L42_PAGE_15 + 0x1B) ++#define CS42L42_PLL_MODE_SHIFT 0 ++#define CS42L42_PLL_MODE_MASK (3 << CS42L42_PLL_MODE_SHIFT) ++ ++/* Page 0x19 HP Load Detect Registers */ ++#define CS42L42_LOAD_DET_RCSTAT (CS42L42_PAGE_19 + 0x25) ++#define CS42L42_RLA_STAT_SHIFT 0 ++#define CS42L42_RLA_STAT_MASK (3 << CS42L42_RLA_STAT_SHIFT) ++#define CS42L42_RLA_STAT_15_OHM 0 ++ ++#define CS42L42_LOAD_DET_DONE (CS42L42_PAGE_19 + 0x26) ++#define CS42L42_HPLOAD_DET_DONE_SHIFT 0 ++#define CS42L42_HPLOAD_DET_DONE_MASK (1 << CS42L42_HPLOAD_DET_DONE_SHIFT) ++ ++#define CS42L42_LOAD_DET_EN (CS42L42_PAGE_19 + 0x27) ++#define CS42L42_HP_LD_EN_SHIFT 0 ++#define CS42L42_HP_LD_EN_MASK (1 << CS42L42_HP_LD_EN_SHIFT) ++ ++/* Page 0x1B Headset Interface Registers */ ++#define CS42L42_HSBIAS_SC_AUTOCTL (CS42L42_PAGE_1B + 0x70) ++#define CS42L42_HSBIAS_SENSE_TRIP_SHIFT 0 ++#define CS42L42_HSBIAS_SENSE_TRIP_MASK (7 << CS42L42_HSBIAS_SENSE_TRIP_SHIFT) ++#define CS42L42_TIP_SENSE_EN_SHIFT 5 ++#define CS42L42_TIP_SENSE_EN_MASK (1 << CS42L42_TIP_SENSE_EN_SHIFT) ++#define CS42L42_AUTO_HSBIAS_HIZ_SHIFT 6 ++#define CS42L42_AUTO_HSBIAS_HIZ_MASK (1 << CS42L42_AUTO_HSBIAS_HIZ_SHIFT) ++#define CS42L42_HSBIAS_SENSE_EN_SHIFT 7 ++#define CS42L42_HSBIAS_SENSE_EN_MASK (1 << CS42L42_HSBIAS_SENSE_EN_SHIFT) ++ ++#define CS42L42_WAKE_CTL (CS42L42_PAGE_1B + 0x71) ++#define CS42L42_WAKEB_CLEAR_SHIFT 0 ++#define CS42L42_WAKEB_CLEAR_MASK (1 << CS42L42_WAKEB_CLEAR_SHIFT) ++#define CS42L42_WAKEB_MODE_SHIFT 5 ++#define CS42L42_WAKEB_MODE_MASK (1 << CS42L42_WAKEB_MODE_SHIFT) ++#define CS42L42_M_HP_WAKE_SHIFT 6 ++#define CS42L42_M_HP_WAKE_MASK (1 << CS42L42_M_HP_WAKE_SHIFT) ++#define CS42L42_M_MIC_WAKE_SHIFT 7 ++#define CS42L42_M_MIC_WAKE_MASK (1 << CS42L42_M_MIC_WAKE_SHIFT) ++ ++#define CS42L42_ADC_DISABLE_MUTE (CS42L42_PAGE_1B + 0x72) ++#define CS42L42_ADC_DISABLE_S0_MUTE_SHIFT 7 ++#define CS42L42_ADC_DISABLE_S0_MUTE_MASK (1 << CS42L42_ADC_DISABLE_S0_MUTE_SHIFT) ++ ++#define CS42L42_TIPSENSE_CTL (CS42L42_PAGE_1B + 0x73) ++#define CS42L42_TIP_SENSE_DEBOUNCE_SHIFT 0 ++#define CS42L42_TIP_SENSE_DEBOUNCE_MASK (3 << CS42L42_TIP_SENSE_DEBOUNCE_SHIFT) ++#define CS42L42_TIP_SENSE_INV_SHIFT 5 ++#define CS42L42_TIP_SENSE_INV_MASK (1 << CS42L42_TIP_SENSE_INV_SHIFT) ++#define CS42L42_TIP_SENSE_CTRL_SHIFT 6 ++#define CS42L42_TIP_SENSE_CTRL_MASK (3 << CS42L42_TIP_SENSE_CTRL_SHIFT) ++ ++/* ++ * NOTE: DETECT_MODE must be 0 while both ADC_PDN=1 and HP_PDN=1. ++ * Otherwise it will prevent FILT+ from charging properly. ++ */ ++#define CS42L42_MISC_DET_CTL (CS42L42_PAGE_1B + 0x74) ++#define CS42L42_PDN_MIC_LVL_DET_SHIFT 0 ++#define CS42L42_PDN_MIC_LVL_DET_MASK (1 << CS42L42_PDN_MIC_LVL_DET_SHIFT) ++#define CS42L42_HSBIAS_CTL_SHIFT 1 ++#define CS42L42_HSBIAS_CTL_MASK (3 << CS42L42_HSBIAS_CTL_SHIFT) ++#define CS42L42_DETECT_MODE_SHIFT 3 ++#define CS42L42_DETECT_MODE_MASK (3 << CS42L42_DETECT_MODE_SHIFT) ++ ++#define CS42L42_MIC_DET_CTL1 (CS42L42_PAGE_1B + 0x75) ++#define CS42L42_HS_DET_LEVEL_SHIFT 0 ++#define CS42L42_HS_DET_LEVEL_MASK (0x3F << CS42L42_HS_DET_LEVEL_SHIFT) ++#define CS42L42_EVENT_STAT_SEL_SHIFT 6 ++#define CS42L42_EVENT_STAT_SEL_MASK (1 << CS42L42_EVENT_STAT_SEL_SHIFT) ++#define CS42L42_LATCH_TO_VP_SHIFT 7 ++#define CS42L42_LATCH_TO_VP_MASK (1 << CS42L42_LATCH_TO_VP_SHIFT) ++ ++#define CS42L42_MIC_DET_CTL2 (CS42L42_PAGE_1B + 0x76) ++#define CS42L42_DEBOUNCE_TIME_SHIFT 5 ++#define CS42L42_DEBOUNCE_TIME_MASK (0x07 << CS42L42_DEBOUNCE_TIME_SHIFT) ++ ++#define CS42L42_DET_STATUS1 (CS42L42_PAGE_1B + 0x77) ++#define CS42L42_HSBIAS_HIZ_MODE_SHIFT 6 ++#define CS42L42_HSBIAS_HIZ_MODE_MASK (1 << CS42L42_HSBIAS_HIZ_MODE_SHIFT) ++#define CS42L42_TIP_SENSE_SHIFT 7 ++#define CS42L42_TIP_SENSE_MASK (1 << CS42L42_TIP_SENSE_SHIFT) ++ ++#define CS42L42_DET_STATUS2 (CS42L42_PAGE_1B + 0x78) ++#define CS42L42_SHORT_TRUE_SHIFT 0 ++#define CS42L42_SHORT_TRUE_MASK (1 << CS42L42_SHORT_TRUE_SHIFT) ++#define CS42L42_HS_TRUE_SHIFT 1 ++#define CS42L42_HS_TRUE_MASK (1 << CS42L42_HS_TRUE_SHIFT) ++ ++#define CS42L42_DET_INT1_MASK (CS42L42_PAGE_1B + 0x79) ++#define CS42L42_TIP_SENSE_UNPLUG_SHIFT 5 ++#define CS42L42_TIP_SENSE_UNPLUG_MASK (1 << CS42L42_TIP_SENSE_UNPLUG_SHIFT) ++#define CS42L42_TIP_SENSE_PLUG_SHIFT 6 ++#define CS42L42_TIP_SENSE_PLUG_MASK (1 << CS42L42_TIP_SENSE_PLUG_SHIFT) ++#define CS42L42_HSBIAS_SENSE_SHIFT 7 ++#define CS42L42_HSBIAS_SENSE_MASK (1 << CS42L42_HSBIAS_SENSE_SHIFT) ++#define CS42L42_DET_INT_VAL1_MASK (CS42L42_TIP_SENSE_UNPLUG_MASK | \ ++ CS42L42_TIP_SENSE_PLUG_MASK | \ ++ CS42L42_HSBIAS_SENSE_MASK) ++ ++#define CS42L42_DET_INT2_MASK (CS42L42_PAGE_1B + 0x7A) ++#define CS42L42_M_SHORT_DET_SHIFT 0 ++#define CS42L42_M_SHORT_DET_MASK (1 << CS42L42_M_SHORT_DET_SHIFT) ++#define CS42L42_M_SHORT_RLS_SHIFT 1 ++#define CS42L42_M_SHORT_RLS_MASK (1 << CS42L42_M_SHORT_RLS_SHIFT) ++#define CS42L42_M_HSBIAS_HIZ_SHIFT 2 ++#define CS42L42_M_HSBIAS_HIZ_MASK (1 << CS42L42_M_HSBIAS_HIZ_SHIFT) ++#define CS42L42_M_DETECT_FT_SHIFT 6 ++#define CS42L42_M_DETECT_FT_MASK (1 << CS42L42_M_DETECT_FT_SHIFT) ++#define CS42L42_M_DETECT_TF_SHIFT 7 ++#define CS42L42_M_DETECT_TF_MASK (1 << CS42L42_M_DETECT_TF_SHIFT) ++#define CS42L42_DET_INT_VAL2_MASK (CS42L42_M_SHORT_DET_MASK | \ ++ CS42L42_M_SHORT_RLS_MASK | \ ++ CS42L42_M_HSBIAS_HIZ_MASK | \ ++ CS42L42_M_DETECT_FT_MASK | \ ++ CS42L42_M_DETECT_TF_MASK) ++ ++/* Page 0x1C Headset Bias Registers */ ++#define CS42L42_HS_BIAS_CTL (CS42L42_PAGE_1C + 0x03) ++#define CS42L42_HSBIAS_RAMP_SHIFT 0 ++#define CS42L42_HSBIAS_RAMP_MASK (3 << CS42L42_HSBIAS_RAMP_SHIFT) ++#define CS42L42_HSBIAS_PD_SHIFT 4 ++#define CS42L42_HSBIAS_PD_MASK (1 << CS42L42_HSBIAS_PD_SHIFT) ++#define CS42L42_HSBIAS_CAPLESS_SHIFT 7 ++#define CS42L42_HSBIAS_CAPLESS_MASK (1 << CS42L42_HSBIAS_CAPLESS_SHIFT) ++ ++/* Page 0x1D ADC Registers */ ++#define CS42L42_ADC_CTL (CS42L42_PAGE_1D + 0x01) ++#define CS42L42_ADC_NOTCH_DIS_SHIFT 5 ++#define CS42L42_ADC_FORCE_WEAK_VCM_SHIFT 4 ++#define CS42L42_ADC_INV_SHIFT 2 ++#define CS42L42_ADC_DIG_BOOST_SHIFT 0 ++ ++#define CS42L42_ADC_VOLUME (CS42L42_PAGE_1D + 0x03) ++#define CS42L42_ADC_VOL_SHIFT 0 ++ ++#define CS42L42_ADC_WNF_HPF_CTL (CS42L42_PAGE_1D + 0x04) ++#define CS42L42_ADC_WNF_CF_SHIFT 4 ++#define CS42L42_ADC_WNF_EN_SHIFT 3 ++#define CS42L42_ADC_HPF_CF_SHIFT 1 ++#define CS42L42_ADC_HPF_EN_SHIFT 0 ++ ++/* Page 0x1F DAC Registers */ ++#define CS42L42_DAC_CTL1 (CS42L42_PAGE_1F + 0x01) ++#define CS42L42_DACB_INV_SHIFT 1 ++#define CS42L42_DACA_INV_SHIFT 0 ++ ++#define CS42L42_DAC_CTL2 (CS42L42_PAGE_1F + 0x06) ++#define CS42L42_HPOUT_PULLDOWN_SHIFT 4 ++#define CS42L42_HPOUT_PULLDOWN_MASK (15 << CS42L42_HPOUT_PULLDOWN_SHIFT) ++#define CS42L42_HPOUT_LOAD_SHIFT 3 ++#define CS42L42_HPOUT_LOAD_MASK (1 << CS42L42_HPOUT_LOAD_SHIFT) ++#define CS42L42_HPOUT_CLAMP_SHIFT 2 ++#define CS42L42_HPOUT_CLAMP_MASK (1 << CS42L42_HPOUT_CLAMP_SHIFT) ++#define CS42L42_DAC_HPF_EN_SHIFT 1 ++#define CS42L42_DAC_HPF_EN_MASK (1 << CS42L42_DAC_HPF_EN_SHIFT) ++#define CS42L42_DAC_MON_EN_SHIFT 0 ++#define CS42L42_DAC_MON_EN_MASK (1 << CS42L42_DAC_MON_EN_SHIFT) ++ ++/* Page 0x20 HP CTL Registers */ ++#define CS42L42_HP_CTL (CS42L42_PAGE_20 + 0x01) ++#define CS42L42_HP_ANA_BMUTE_SHIFT 3 ++#define CS42L42_HP_ANA_BMUTE_MASK (1 << CS42L42_HP_ANA_BMUTE_SHIFT) ++#define CS42L42_HP_ANA_AMUTE_SHIFT 2 ++#define CS42L42_HP_ANA_AMUTE_MASK (1 << CS42L42_HP_ANA_AMUTE_SHIFT) ++#define CS42L42_HP_FULL_SCALE_VOL_SHIFT 1 ++#define CS42L42_HP_FULL_SCALE_VOL_MASK (1 << CS42L42_HP_FULL_SCALE_VOL_SHIFT) ++ ++/* Page 0x21 Class H Registers */ ++#define CS42L42_CLASSH_CTL (CS42L42_PAGE_21 + 0x01) ++ ++/* Page 0x23 Mixer Volume Registers */ ++#define CS42L42_MIXER_CHA_VOL (CS42L42_PAGE_23 + 0x01) ++#define CS42L42_MIXER_ADC_VOL (CS42L42_PAGE_23 + 0x02) ++ ++#define CS42L42_MIXER_CHB_VOL (CS42L42_PAGE_23 + 0x03) ++#define CS42L42_MIXER_CH_VOL_SHIFT 0 ++#define CS42L42_MIXER_CH_VOL_MASK (0x3f << CS42L42_MIXER_CH_VOL_SHIFT) ++ ++/* Page 0x24 EQ Registers */ ++#define CS42L42_EQ_COEF_IN0 (CS42L42_PAGE_24 + 0x01) ++#define CS42L42_EQ_COEF_IN1 (CS42L42_PAGE_24 + 0x02) ++#define CS42L42_EQ_COEF_IN2 (CS42L42_PAGE_24 + 0x03) ++#define CS42L42_EQ_COEF_IN3 (CS42L42_PAGE_24 + 0x04) ++#define CS42L42_EQ_COEF_RW (CS42L42_PAGE_24 + 0x06) ++#define CS42L42_EQ_COEF_OUT0 (CS42L42_PAGE_24 + 0x07) ++#define CS42L42_EQ_COEF_OUT1 (CS42L42_PAGE_24 + 0x08) ++#define CS42L42_EQ_COEF_OUT2 (CS42L42_PAGE_24 + 0x09) ++#define CS42L42_EQ_COEF_OUT3 (CS42L42_PAGE_24 + 0x0A) ++#define CS42L42_EQ_INIT_STAT (CS42L42_PAGE_24 + 0x0B) ++#define CS42L42_EQ_START_FILT (CS42L42_PAGE_24 + 0x0C) ++#define CS42L42_EQ_MUTE_CTL (CS42L42_PAGE_24 + 0x0E) ++ ++/* Page 0x25 Audio Port Registers */ ++#define CS42L42_SP_RX_CH_SEL (CS42L42_PAGE_25 + 0x01) ++#define CS42L42_SP_RX_CHB_SEL_SHIFT 2 ++#define CS42L42_SP_RX_CHB_SEL_MASK (3 << CS42L42_SP_RX_CHB_SEL_SHIFT) ++ ++#define CS42L42_SP_RX_ISOC_CTL (CS42L42_PAGE_25 + 0x02) ++#define CS42L42_SP_RX_RSYNC_SHIFT 6 ++#define CS42L42_SP_RX_RSYNC_MASK (1 << CS42L42_SP_RX_RSYNC_SHIFT) ++#define CS42L42_SP_RX_NSB_POS_SHIFT 3 ++#define CS42L42_SP_RX_NSB_POS_MASK (7 << CS42L42_SP_RX_NSB_POS_SHIFT) ++#define CS42L42_SP_RX_NFS_NSBB_SHIFT 2 ++#define CS42L42_SP_RX_NFS_NSBB_MASK (1 << CS42L42_SP_RX_NFS_NSBB_SHIFT) ++#define CS42L42_SP_RX_ISOC_MODE_SHIFT 0 ++#define CS42L42_SP_RX_ISOC_MODE_MASK (3 << CS42L42_SP_RX_ISOC_MODE_SHIFT) ++ ++#define CS42L42_SP_RX_FS (CS42L42_PAGE_25 + 0x03) ++#define CS42l42_SPDIF_CH_SEL (CS42L42_PAGE_25 + 0x04) ++#define CS42L42_SP_TX_ISOC_CTL (CS42L42_PAGE_25 + 0x05) ++#define CS42L42_SP_TX_FS (CS42L42_PAGE_25 + 0x06) ++#define CS42L42_SPDIF_SW_CTL1 (CS42L42_PAGE_25 + 0x07) ++ ++/* Page 0x26 SRC Registers */ ++#define CS42L42_SRC_SDIN_FS (CS42L42_PAGE_26 + 0x01) ++#define CS42L42_SRC_SDIN_FS_SHIFT 0 ++#define CS42L42_SRC_SDIN_FS_MASK (0x1f << CS42L42_SRC_SDIN_FS_SHIFT) ++ ++#define CS42L42_SRC_SDOUT_FS (CS42L42_PAGE_26 + 0x09) ++ ++/* Page 0x28 S/PDIF Registers */ ++#define CS42L42_SPDIF_CTL1 (CS42L42_PAGE_28 + 0x01) ++#define CS42L42_SPDIF_CTL2 (CS42L42_PAGE_28 + 0x02) ++#define CS42L42_SPDIF_CTL3 (CS42L42_PAGE_28 + 0x03) ++#define CS42L42_SPDIF_CTL4 (CS42L42_PAGE_28 + 0x04) ++ ++/* Page 0x29 Serial Port TX Registers */ ++#define CS42L42_ASP_TX_SZ_EN (CS42L42_PAGE_29 + 0x01) ++#define CS42L42_ASP_TX_EN_SHIFT 0 ++#define CS42L42_ASP_TX_CH_EN (CS42L42_PAGE_29 + 0x02) ++#define CS42L42_ASP_TX0_CH2_SHIFT 1 ++#define CS42L42_ASP_TX0_CH1_SHIFT 0 ++ ++#define CS42L42_ASP_TX_CH_AP_RES (CS42L42_PAGE_29 + 0x03) ++#define CS42L42_ASP_TX_CH1_AP_SHIFT 7 ++#define CS42L42_ASP_TX_CH1_AP_MASK (1 << CS42L42_ASP_TX_CH1_AP_SHIFT) ++#define CS42L42_ASP_TX_CH2_AP_SHIFT 6 ++#define CS42L42_ASP_TX_CH2_AP_MASK (1 << CS42L42_ASP_TX_CH2_AP_SHIFT) ++#define CS42L42_ASP_TX_CH2_RES_SHIFT 2 ++#define CS42L42_ASP_TX_CH2_RES_MASK (3 << CS42L42_ASP_TX_CH2_RES_SHIFT) ++#define CS42L42_ASP_TX_CH1_RES_SHIFT 0 ++#define CS42L42_ASP_TX_CH1_RES_MASK (3 << CS42L42_ASP_TX_CH1_RES_SHIFT) ++#define CS42L42_ASP_TX_CH1_BIT_MSB (CS42L42_PAGE_29 + 0x04) ++#define CS42L42_ASP_TX_CH1_BIT_LSB (CS42L42_PAGE_29 + 0x05) ++#define CS42L42_ASP_TX_HIZ_DLY_CFG (CS42L42_PAGE_29 + 0x06) ++#define CS42L42_ASP_TX_CH2_BIT_MSB (CS42L42_PAGE_29 + 0x0A) ++#define CS42L42_ASP_TX_CH2_BIT_LSB (CS42L42_PAGE_29 + 0x0B) ++ ++/* Page 0x2A Serial Port RX Registers */ ++#define CS42L42_ASP_RX_DAI0_EN (CS42L42_PAGE_2A + 0x01) ++#define CS42L42_ASP_RX0_CH_EN_SHIFT 2 ++#define CS42L42_ASP_RX0_CH_EN_MASK (0xf << CS42L42_ASP_RX0_CH_EN_SHIFT) ++#define CS42L42_ASP_RX0_CH1_SHIFT 2 ++#define CS42L42_ASP_RX0_CH2_SHIFT 3 ++#define CS42L42_ASP_RX0_CH3_SHIFT 4 ++#define CS42L42_ASP_RX0_CH4_SHIFT 5 ++ ++#define CS42L42_ASP_RX_DAI0_CH1_AP_RES (CS42L42_PAGE_2A + 0x02) ++#define CS42L42_ASP_RX_DAI0_CH1_BIT_MSB (CS42L42_PAGE_2A + 0x03) ++#define CS42L42_ASP_RX_DAI0_CH1_BIT_LSB (CS42L42_PAGE_2A + 0x04) ++#define CS42L42_ASP_RX_DAI0_CH2_AP_RES (CS42L42_PAGE_2A + 0x05) ++#define CS42L42_ASP_RX_DAI0_CH2_BIT_MSB (CS42L42_PAGE_2A + 0x06) ++#define CS42L42_ASP_RX_DAI0_CH2_BIT_LSB (CS42L42_PAGE_2A + 0x07) ++#define CS42L42_ASP_RX_DAI0_CH3_AP_RES (CS42L42_PAGE_2A + 0x08) ++#define CS42L42_ASP_RX_DAI0_CH3_BIT_MSB (CS42L42_PAGE_2A + 0x09) ++#define CS42L42_ASP_RX_DAI0_CH3_BIT_LSB (CS42L42_PAGE_2A + 0x0A) ++#define CS42L42_ASP_RX_DAI0_CH4_AP_RES (CS42L42_PAGE_2A + 0x0B) ++#define CS42L42_ASP_RX_DAI0_CH4_BIT_MSB (CS42L42_PAGE_2A + 0x0C) ++#define CS42L42_ASP_RX_DAI0_CH4_BIT_LSB (CS42L42_PAGE_2A + 0x0D) ++#define CS42L42_ASP_RX_DAI1_CH1_AP_RES (CS42L42_PAGE_2A + 0x0E) ++#define CS42L42_ASP_RX_DAI1_CH1_BIT_MSB (CS42L42_PAGE_2A + 0x0F) ++#define CS42L42_ASP_RX_DAI1_CH1_BIT_LSB (CS42L42_PAGE_2A + 0x10) ++#define CS42L42_ASP_RX_DAI1_CH2_AP_RES (CS42L42_PAGE_2A + 0x11) ++#define CS42L42_ASP_RX_DAI1_CH2_BIT_MSB (CS42L42_PAGE_2A + 0x12) ++#define CS42L42_ASP_RX_DAI1_CH2_BIT_LSB (CS42L42_PAGE_2A + 0x13) ++ ++#define CS42L42_ASP_RX_CH_AP_SHIFT 6 ++#define CS42L42_ASP_RX_CH_AP_MASK (1 << CS42L42_ASP_RX_CH_AP_SHIFT) ++#define CS42L42_ASP_RX_CH_AP_LOW 0 ++#define CS42L42_ASP_RX_CH_AP_HI 1 ++#define CS42L42_ASP_RX_CH_RES_SHIFT 0 ++#define CS42L42_ASP_RX_CH_RES_MASK (3 << CS42L42_ASP_RX_CH_RES_SHIFT) ++#define CS42L42_ASP_RX_CH_RES_32 3 ++#define CS42L42_ASP_RX_CH_RES_16 1 ++#define CS42L42_ASP_RX_CH_BIT_ST_SHIFT 0 ++#define CS42L42_ASP_RX_CH_BIT_ST_MASK (0xff << CS42L42_ASP_RX_CH_BIT_ST_SHIFT) ++ ++/* Page 0x30 ID Registers */ ++#define CS42L42_SUB_REVID (CS42L42_PAGE_30 + 0x14) ++#define CS42L42_MAX_REGISTER (CS42L42_PAGE_30 + 0x14) ++ ++/* Defines for fracturing values spread across multiple registers */ ++#define CS42L42_FRAC0_VAL(val) ((val) & 0x0000ff) ++#define CS42L42_FRAC1_VAL(val) (((val) & 0x00ff00) >> 8) ++#define CS42L42_FRAC2_VAL(val) (((val) & 0xff0000) >> 16) ++ ++#define CS42L42_NUM_SUPPLIES 5 ++#define CS42L42_BOOT_TIME_US 3000 ++#define CS42L42_PLL_DIVOUT_TIME_US 800 ++#define CS42L42_CLOCK_SWITCH_DELAY_US 150 ++#define CS42L42_PLL_LOCK_POLL_US 250 ++#define CS42L42_PLL_LOCK_TIMEOUT_US 1250 ++#define CS42L42_HP_ADC_EN_TIME_US 20000 ++#define CS42L42_PDN_DONE_POLL_US 1000 ++#define CS42L42_PDN_DONE_TIMEOUT_US 200000 ++#define CS42L42_PDN_DONE_TIME_MS 100 ++#define CS42L42_FILT_DISCHARGE_TIME_MS 46 ++ ++#endif /* __CS42L42_H */ +diff --git a/sound/soc/codecs/cs42l42.h b/sound/soc/codecs/cs42l42.h +index 60d3bdf5d7c9..5f50970375d4 100644 +--- a/sound/soc/codecs/cs42l42.h ++++ b/sound/soc/codecs/cs42l42.h +@@ -2,7 +2,7 @@ + /* + * cs42l42.h -- CS42L42 ALSA SoC audio driver header + * +- * Copyright 2016 Cirrus Logic, Inc. ++ * Copyright 2016-2022 Cirrus Logic, Inc. + * + * Author: James Schulman + * Author: Brian Austin +@@ -14,829 +14,7 @@ + + #include + #include +- +-#define CS42L42_PAGE_REGISTER 0x00 /* Page Select Register */ +-#define CS42L42_WIN_START 0x00 +-#define CS42L42_WIN_LEN 0x100 +-#define CS42L42_RANGE_MIN 0x00 +-#define CS42L42_RANGE_MAX 0x7F +- +-#define CS42L42_PAGE_10 0x1000 +-#define CS42L42_PAGE_11 0x1100 +-#define CS42L42_PAGE_12 0x1200 +-#define CS42L42_PAGE_13 0x1300 +-#define CS42L42_PAGE_15 0x1500 +-#define CS42L42_PAGE_19 0x1900 +-#define CS42L42_PAGE_1B 0x1B00 +-#define CS42L42_PAGE_1C 0x1C00 +-#define CS42L42_PAGE_1D 0x1D00 +-#define CS42L42_PAGE_1F 0x1F00 +-#define CS42L42_PAGE_20 0x2000 +-#define CS42L42_PAGE_21 0x2100 +-#define CS42L42_PAGE_23 0x2300 +-#define CS42L42_PAGE_24 0x2400 +-#define CS42L42_PAGE_25 0x2500 +-#define CS42L42_PAGE_26 0x2600 +-#define CS42L42_PAGE_28 0x2800 +-#define CS42L42_PAGE_29 0x2900 +-#define CS42L42_PAGE_2A 0x2A00 +-#define CS42L42_PAGE_30 0x3000 +- +-#define CS42L42_CHIP_ID 0x42A42 +- +-/* Page 0x10 Global Registers */ +-#define CS42L42_DEVID_AB (CS42L42_PAGE_10 + 0x01) +-#define CS42L42_DEVID_CD (CS42L42_PAGE_10 + 0x02) +-#define CS42L42_DEVID_E (CS42L42_PAGE_10 + 0x03) +-#define CS42L42_FABID (CS42L42_PAGE_10 + 0x04) +-#define CS42L42_REVID (CS42L42_PAGE_10 + 0x05) +-#define CS42L42_FRZ_CTL (CS42L42_PAGE_10 + 0x06) +- +-#define CS42L42_SRC_CTL (CS42L42_PAGE_10 + 0x07) +-#define CS42L42_SRC_BYPASS_DAC_SHIFT 1 +-#define CS42L42_SRC_BYPASS_DAC_MASK (1 << CS42L42_SRC_BYPASS_DAC_SHIFT) +- +-#define CS42L42_MCLK_STATUS (CS42L42_PAGE_10 + 0x08) +- +-#define CS42L42_MCLK_CTL (CS42L42_PAGE_10 + 0x09) +-#define CS42L42_INTERNAL_FS_SHIFT 1 +-#define CS42L42_INTERNAL_FS_MASK (1 << CS42L42_INTERNAL_FS_SHIFT) +- +-#define CS42L42_SFTRAMP_RATE (CS42L42_PAGE_10 + 0x0A) +-#define CS42L42_SLOW_START_ENABLE (CS42L42_PAGE_10 + 0x0B) +-#define CS42L42_SLOW_START_EN_MASK GENMASK(6, 4) +-#define CS42L42_SLOW_START_EN_SHIFT 4 +-#define CS42L42_I2C_DEBOUNCE (CS42L42_PAGE_10 + 0x0E) +-#define CS42L42_I2C_STRETCH (CS42L42_PAGE_10 + 0x0F) +-#define CS42L42_I2C_TIMEOUT (CS42L42_PAGE_10 + 0x10) +- +-/* Page 0x11 Power and Headset Detect Registers */ +-#define CS42L42_PWR_CTL1 (CS42L42_PAGE_11 + 0x01) +-#define CS42L42_ASP_DAO_PDN_SHIFT 7 +-#define CS42L42_ASP_DAO_PDN_MASK (1 << CS42L42_ASP_DAO_PDN_SHIFT) +-#define CS42L42_ASP_DAI_PDN_SHIFT 6 +-#define CS42L42_ASP_DAI_PDN_MASK (1 << CS42L42_ASP_DAI_PDN_SHIFT) +-#define CS42L42_MIXER_PDN_SHIFT 5 +-#define CS42L42_MIXER_PDN_MASK (1 << CS42L42_MIXER_PDN_SHIFT) +-#define CS42L42_EQ_PDN_SHIFT 4 +-#define CS42L42_EQ_PDN_MASK (1 << CS42L42_EQ_PDN_SHIFT) +-#define CS42L42_HP_PDN_SHIFT 3 +-#define CS42L42_HP_PDN_MASK (1 << CS42L42_HP_PDN_SHIFT) +-#define CS42L42_ADC_PDN_SHIFT 2 +-#define CS42L42_ADC_PDN_MASK (1 << CS42L42_ADC_PDN_SHIFT) +-#define CS42L42_PDN_ALL_SHIFT 0 +-#define CS42L42_PDN_ALL_MASK (1 << CS42L42_PDN_ALL_SHIFT) +- +-#define CS42L42_PWR_CTL2 (CS42L42_PAGE_11 + 0x02) +-#define CS42L42_ADC_SRC_PDNB_SHIFT 0 +-#define CS42L42_ADC_SRC_PDNB_MASK (1 << CS42L42_ADC_SRC_PDNB_SHIFT) +-#define CS42L42_DAC_SRC_PDNB_SHIFT 1 +-#define CS42L42_DAC_SRC_PDNB_MASK (1 << CS42L42_DAC_SRC_PDNB_SHIFT) +-#define CS42L42_ASP_DAI1_PDN_SHIFT 2 +-#define CS42L42_ASP_DAI1_PDN_MASK (1 << CS42L42_ASP_DAI1_PDN_SHIFT) +-#define CS42L42_SRC_PDN_OVERRIDE_SHIFT 3 +-#define CS42L42_SRC_PDN_OVERRIDE_MASK (1 << CS42L42_SRC_PDN_OVERRIDE_SHIFT) +-#define CS42L42_DISCHARGE_FILT_SHIFT 4 +-#define CS42L42_DISCHARGE_FILT_MASK (1 << CS42L42_DISCHARGE_FILT_SHIFT) +- +-#define CS42L42_PWR_CTL3 (CS42L42_PAGE_11 + 0x03) +-#define CS42L42_RING_SENSE_PDNB_SHIFT 1 +-#define CS42L42_RING_SENSE_PDNB_MASK (1 << \ +- CS42L42_RING_SENSE_PDNB_SHIFT) +-#define CS42L42_VPMON_PDNB_SHIFT 2 +-#define CS42L42_VPMON_PDNB_MASK (1 << \ +- CS42L42_VPMON_PDNB_SHIFT) +-#define CS42L42_SW_CLK_STP_STAT_SEL_SHIFT 5 +-#define CS42L42_SW_CLK_STP_STAT_SEL_MASK (3 << \ +- CS42L42_SW_CLK_STP_STAT_SEL_SHIFT) +- +-#define CS42L42_RSENSE_CTL1 (CS42L42_PAGE_11 + 0x04) +-#define CS42L42_RS_TRIM_R_SHIFT 0 +-#define CS42L42_RS_TRIM_R_MASK (1 << \ +- CS42L42_RS_TRIM_R_SHIFT) +-#define CS42L42_RS_TRIM_T_SHIFT 1 +-#define CS42L42_RS_TRIM_T_MASK (1 << \ +- CS42L42_RS_TRIM_T_SHIFT) +-#define CS42L42_HPREF_RS_SHIFT 2 +-#define CS42L42_HPREF_RS_MASK (1 << \ +- CS42L42_HPREF_RS_SHIFT) +-#define CS42L42_HSBIAS_FILT_REF_RS_SHIFT 3 +-#define CS42L42_HSBIAS_FILT_REF_RS_MASK (1 << \ +- CS42L42_HSBIAS_FILT_REF_RS_SHIFT) +-#define CS42L42_RING_SENSE_PU_HIZ_SHIFT 6 +-#define CS42L42_RING_SENSE_PU_HIZ_MASK (1 << \ +- CS42L42_RING_SENSE_PU_HIZ_SHIFT) +- +-#define CS42L42_RSENSE_CTL2 (CS42L42_PAGE_11 + 0x05) +-#define CS42L42_TS_RS_GATE_SHIFT 7 +-#define CS42L42_TS_RS_GATE_MAS (1 << CS42L42_TS_RS_GATE_SHIFT) +- +-#define CS42L42_OSC_SWITCH (CS42L42_PAGE_11 + 0x07) +-#define CS42L42_SCLK_PRESENT_SHIFT 0 +-#define CS42L42_SCLK_PRESENT_MASK (1 << CS42L42_SCLK_PRESENT_SHIFT) +- +-#define CS42L42_OSC_SWITCH_STATUS (CS42L42_PAGE_11 + 0x09) +-#define CS42L42_OSC_SW_SEL_STAT_SHIFT 0 +-#define CS42L42_OSC_SW_SEL_STAT_MASK (3 << CS42L42_OSC_SW_SEL_STAT_SHIFT) +-#define CS42L42_OSC_PDNB_STAT_SHIFT 2 +-#define CS42L42_OSC_PDNB_STAT_MASK (1 << CS42L42_OSC_SW_SEL_STAT_SHIFT) +- +-#define CS42L42_RSENSE_CTL3 (CS42L42_PAGE_11 + 0x12) +-#define CS42L42_RS_RISE_DBNCE_TIME_SHIFT 0 +-#define CS42L42_RS_RISE_DBNCE_TIME_MASK (7 << \ +- CS42L42_RS_RISE_DBNCE_TIME_SHIFT) +-#define CS42L42_RS_FALL_DBNCE_TIME_SHIFT 3 +-#define CS42L42_RS_FALL_DBNCE_TIME_MASK (7 << \ +- CS42L42_RS_FALL_DBNCE_TIME_SHIFT) +-#define CS42L42_RS_PU_EN_SHIFT 6 +-#define CS42L42_RS_PU_EN_MASK (1 << \ +- CS42L42_RS_PU_EN_SHIFT) +-#define CS42L42_RS_INV_SHIFT 7 +-#define CS42L42_RS_INV_MASK (1 << \ +- CS42L42_RS_INV_SHIFT) +- +-#define CS42L42_TSENSE_CTL (CS42L42_PAGE_11 + 0x13) +-#define CS42L42_TS_RISE_DBNCE_TIME_SHIFT 0 +-#define CS42L42_TS_RISE_DBNCE_TIME_MASK (7 << \ +- CS42L42_TS_RISE_DBNCE_TIME_SHIFT) +-#define CS42L42_TS_FALL_DBNCE_TIME_SHIFT 3 +-#define CS42L42_TS_FALL_DBNCE_TIME_MASK (7 << \ +- CS42L42_TS_FALL_DBNCE_TIME_SHIFT) +-#define CS42L42_TS_INV_SHIFT 7 +-#define CS42L42_TS_INV_MASK (1 << \ +- CS42L42_TS_INV_SHIFT) +- +-#define CS42L42_TSRS_INT_DISABLE (CS42L42_PAGE_11 + 0x14) +-#define CS42L42_D_RS_PLUG_DBNC_SHIFT 0 +-#define CS42L42_D_RS_PLUG_DBNC_MASK (1 << CS42L42_D_RS_PLUG_DBNC_SHIFT) +-#define CS42L42_D_RS_UNPLUG_DBNC_SHIFT 1 +-#define CS42L42_D_RS_UNPLUG_DBNC_MASK (1 << CS42L42_D_RS_UNPLUG_DBNC_SHIFT) +-#define CS42L42_D_TS_PLUG_DBNC_SHIFT 2 +-#define CS42L42_D_TS_PLUG_DBNC_MASK (1 << CS42L42_D_TS_PLUG_DBNC_SHIFT) +-#define CS42L42_D_TS_UNPLUG_DBNC_SHIFT 3 +-#define CS42L42_D_TS_UNPLUG_DBNC_MASK (1 << CS42L42_D_TS_UNPLUG_DBNC_SHIFT) +- +-#define CS42L42_TRSENSE_STATUS (CS42L42_PAGE_11 + 0x15) +-#define CS42L42_RS_PLUG_DBNC_SHIFT 0 +-#define CS42L42_RS_PLUG_DBNC_MASK (1 << CS42L42_RS_PLUG_DBNC_SHIFT) +-#define CS42L42_RS_UNPLUG_DBNC_SHIFT 1 +-#define CS42L42_RS_UNPLUG_DBNC_MASK (1 << CS42L42_RS_UNPLUG_DBNC_SHIFT) +-#define CS42L42_TS_PLUG_DBNC_SHIFT 2 +-#define CS42L42_TS_PLUG_DBNC_MASK (1 << CS42L42_TS_PLUG_DBNC_SHIFT) +-#define CS42L42_TS_UNPLUG_DBNC_SHIFT 3 +-#define CS42L42_TS_UNPLUG_DBNC_MASK (1 << CS42L42_TS_UNPLUG_DBNC_SHIFT) +- +-#define CS42L42_HSDET_CTL1 (CS42L42_PAGE_11 + 0x1F) +-#define CS42L42_HSDET_COMP1_LVL_SHIFT 0 +-#define CS42L42_HSDET_COMP1_LVL_MASK (15 << CS42L42_HSDET_COMP1_LVL_SHIFT) +-#define CS42L42_HSDET_COMP2_LVL_SHIFT 4 +-#define CS42L42_HSDET_COMP2_LVL_MASK (15 << CS42L42_HSDET_COMP2_LVL_SHIFT) +- +-#define CS42L42_HSDET_COMP1_LVL_VAL 12 /* 1.25V Comparator */ +-#define CS42L42_HSDET_COMP2_LVL_VAL 2 /* 1.75V Comparator */ +-#define CS42L42_HSDET_COMP1_LVL_DEFAULT 7 /* 1V Comparator */ +-#define CS42L42_HSDET_COMP2_LVL_DEFAULT 7 /* 2V Comparator */ +- +-#define CS42L42_HSDET_CTL2 (CS42L42_PAGE_11 + 0x20) +-#define CS42L42_HSDET_AUTO_TIME_SHIFT 0 +-#define CS42L42_HSDET_AUTO_TIME_MASK (3 << CS42L42_HSDET_AUTO_TIME_SHIFT) +-#define CS42L42_HSBIAS_REF_SHIFT 3 +-#define CS42L42_HSBIAS_REF_MASK (1 << CS42L42_HSBIAS_REF_SHIFT) +-#define CS42L42_HSDET_SET_SHIFT 4 +-#define CS42L42_HSDET_SET_MASK (3 << CS42L42_HSDET_SET_SHIFT) +-#define CS42L42_HSDET_CTRL_SHIFT 6 +-#define CS42L42_HSDET_CTRL_MASK (3 << CS42L42_HSDET_CTRL_SHIFT) +- +-#define CS42L42_HS_SWITCH_CTL (CS42L42_PAGE_11 + 0x21) +-#define CS42L42_SW_GNDHS_HS4_SHIFT 0 +-#define CS42L42_SW_GNDHS_HS4_MASK (1 << CS42L42_SW_GNDHS_HS4_SHIFT) +-#define CS42L42_SW_GNDHS_HS3_SHIFT 1 +-#define CS42L42_SW_GNDHS_HS3_MASK (1 << CS42L42_SW_GNDHS_HS3_SHIFT) +-#define CS42L42_SW_HSB_HS4_SHIFT 2 +-#define CS42L42_SW_HSB_HS4_MASK (1 << CS42L42_SW_HSB_HS4_SHIFT) +-#define CS42L42_SW_HSB_HS3_SHIFT 3 +-#define CS42L42_SW_HSB_HS3_MASK (1 << CS42L42_SW_HSB_HS3_SHIFT) +-#define CS42L42_SW_HSB_FILT_HS4_SHIFT 4 +-#define CS42L42_SW_HSB_FILT_HS4_MASK (1 << CS42L42_SW_HSB_FILT_HS4_SHIFT) +-#define CS42L42_SW_HSB_FILT_HS3_SHIFT 5 +-#define CS42L42_SW_HSB_FILT_HS3_MASK (1 << CS42L42_SW_HSB_FILT_HS3_SHIFT) +-#define CS42L42_SW_REF_HS4_SHIFT 6 +-#define CS42L42_SW_REF_HS4_MASK (1 << CS42L42_SW_REF_HS4_SHIFT) +-#define CS42L42_SW_REF_HS3_SHIFT 7 +-#define CS42L42_SW_REF_HS3_MASK (1 << CS42L42_SW_REF_HS3_SHIFT) +- +-#define CS42L42_HS_DET_STATUS (CS42L42_PAGE_11 + 0x24) +-#define CS42L42_HSDET_TYPE_SHIFT 0 +-#define CS42L42_HSDET_TYPE_MASK (3 << CS42L42_HSDET_TYPE_SHIFT) +-#define CS42L42_HSDET_COMP1_OUT_SHIFT 6 +-#define CS42L42_HSDET_COMP1_OUT_MASK (1 << CS42L42_HSDET_COMP1_OUT_SHIFT) +-#define CS42L42_HSDET_COMP2_OUT_SHIFT 7 +-#define CS42L42_HSDET_COMP2_OUT_MASK (1 << CS42L42_HSDET_COMP2_OUT_SHIFT) +-#define CS42L42_PLUG_CTIA 0 +-#define CS42L42_PLUG_OMTP 1 +-#define CS42L42_PLUG_HEADPHONE 2 +-#define CS42L42_PLUG_INVALID 3 +- +-#define CS42L42_HSDET_SW_COMP1 ((0 << CS42L42_SW_GNDHS_HS4_SHIFT) | \ +- (1 << CS42L42_SW_GNDHS_HS3_SHIFT) | \ +- (1 << CS42L42_SW_HSB_HS4_SHIFT) | \ +- (0 << CS42L42_SW_HSB_HS3_SHIFT) | \ +- (0 << CS42L42_SW_HSB_FILT_HS4_SHIFT) | \ +- (1 << CS42L42_SW_HSB_FILT_HS3_SHIFT) | \ +- (0 << CS42L42_SW_REF_HS4_SHIFT) | \ +- (1 << CS42L42_SW_REF_HS3_SHIFT)) +-#define CS42L42_HSDET_SW_COMP2 ((1 << CS42L42_SW_GNDHS_HS4_SHIFT) | \ +- (0 << CS42L42_SW_GNDHS_HS3_SHIFT) | \ +- (0 << CS42L42_SW_HSB_HS4_SHIFT) | \ +- (1 << CS42L42_SW_HSB_HS3_SHIFT) | \ +- (1 << CS42L42_SW_HSB_FILT_HS4_SHIFT) | \ +- (0 << CS42L42_SW_HSB_FILT_HS3_SHIFT) | \ +- (1 << CS42L42_SW_REF_HS4_SHIFT) | \ +- (0 << CS42L42_SW_REF_HS3_SHIFT)) +-#define CS42L42_HSDET_SW_TYPE1 ((0 << CS42L42_SW_GNDHS_HS4_SHIFT) | \ +- (1 << CS42L42_SW_GNDHS_HS3_SHIFT) | \ +- (1 << CS42L42_SW_HSB_HS4_SHIFT) | \ +- (0 << CS42L42_SW_HSB_HS3_SHIFT) | \ +- (0 << CS42L42_SW_HSB_FILT_HS4_SHIFT) | \ +- (1 << CS42L42_SW_HSB_FILT_HS3_SHIFT) | \ +- (0 << CS42L42_SW_REF_HS4_SHIFT) | \ +- (1 << CS42L42_SW_REF_HS3_SHIFT)) +-#define CS42L42_HSDET_SW_TYPE2 ((1 << CS42L42_SW_GNDHS_HS4_SHIFT) | \ +- (0 << CS42L42_SW_GNDHS_HS3_SHIFT) | \ +- (0 << CS42L42_SW_HSB_HS4_SHIFT) | \ +- (1 << CS42L42_SW_HSB_HS3_SHIFT) | \ +- (1 << CS42L42_SW_HSB_FILT_HS4_SHIFT) | \ +- (0 << CS42L42_SW_HSB_FILT_HS3_SHIFT) | \ +- (1 << CS42L42_SW_REF_HS4_SHIFT) | \ +- (0 << CS42L42_SW_REF_HS3_SHIFT)) +-#define CS42L42_HSDET_SW_TYPE3 ((1 << CS42L42_SW_GNDHS_HS4_SHIFT) | \ +- (1 << CS42L42_SW_GNDHS_HS3_SHIFT) | \ +- (0 << CS42L42_SW_HSB_HS4_SHIFT) | \ +- (0 << CS42L42_SW_HSB_HS3_SHIFT) | \ +- (1 << CS42L42_SW_HSB_FILT_HS4_SHIFT) | \ +- (1 << CS42L42_SW_HSB_FILT_HS3_SHIFT) | \ +- (1 << CS42L42_SW_REF_HS4_SHIFT) | \ +- (1 << CS42L42_SW_REF_HS3_SHIFT)) +-#define CS42L42_HSDET_SW_TYPE4 ((0 << CS42L42_SW_GNDHS_HS4_SHIFT) | \ +- (1 << CS42L42_SW_GNDHS_HS3_SHIFT) | \ +- (1 << CS42L42_SW_HSB_HS4_SHIFT) | \ +- (0 << CS42L42_SW_HSB_HS3_SHIFT) | \ +- (0 << CS42L42_SW_HSB_FILT_HS4_SHIFT) | \ +- (1 << CS42L42_SW_HSB_FILT_HS3_SHIFT) | \ +- (0 << CS42L42_SW_REF_HS4_SHIFT) | \ +- (1 << CS42L42_SW_REF_HS3_SHIFT)) +- +-#define CS42L42_HSDET_COMP_TYPE1 1 +-#define CS42L42_HSDET_COMP_TYPE2 2 +-#define CS42L42_HSDET_COMP_TYPE3 0 +-#define CS42L42_HSDET_COMP_TYPE4 3 +- +-#define CS42L42_HS_CLAMP_DISABLE (CS42L42_PAGE_11 + 0x29) +-#define CS42L42_HS_CLAMP_DISABLE_SHIFT 0 +-#define CS42L42_HS_CLAMP_DISABLE_MASK (1 << CS42L42_HS_CLAMP_DISABLE_SHIFT) +- +-/* Page 0x12 Clocking Registers */ +-#define CS42L42_MCLK_SRC_SEL (CS42L42_PAGE_12 + 0x01) +-#define CS42L42_MCLKDIV_SHIFT 1 +-#define CS42L42_MCLKDIV_MASK (1 << CS42L42_MCLKDIV_SHIFT) +-#define CS42L42_MCLK_SRC_SEL_SHIFT 0 +-#define CS42L42_MCLK_SRC_SEL_MASK (1 << CS42L42_MCLK_SRC_SEL_SHIFT) +- +-#define CS42L42_SPDIF_CLK_CFG (CS42L42_PAGE_12 + 0x02) +-#define CS42L42_FSYNC_PW_LOWER (CS42L42_PAGE_12 + 0x03) +- +-#define CS42L42_FSYNC_PW_UPPER (CS42L42_PAGE_12 + 0x04) +-#define CS42L42_FSYNC_PULSE_WIDTH_SHIFT 0 +-#define CS42L42_FSYNC_PULSE_WIDTH_MASK (0xff << \ +- CS42L42_FSYNC_PULSE_WIDTH_SHIFT) +- +-#define CS42L42_FSYNC_P_LOWER (CS42L42_PAGE_12 + 0x05) +- +-#define CS42L42_FSYNC_P_UPPER (CS42L42_PAGE_12 + 0x06) +-#define CS42L42_FSYNC_PERIOD_SHIFT 0 +-#define CS42L42_FSYNC_PERIOD_MASK (0xff << CS42L42_FSYNC_PERIOD_SHIFT) +- +-#define CS42L42_ASP_CLK_CFG (CS42L42_PAGE_12 + 0x07) +-#define CS42L42_ASP_SCLK_EN_SHIFT 5 +-#define CS42L42_ASP_SCLK_EN_MASK (1 << CS42L42_ASP_SCLK_EN_SHIFT) +-#define CS42L42_ASP_MASTER_MODE 0x01 +-#define CS42L42_ASP_SLAVE_MODE 0x00 +-#define CS42L42_ASP_MODE_SHIFT 4 +-#define CS42L42_ASP_MODE_MASK (1 << CS42L42_ASP_MODE_SHIFT) +-#define CS42L42_ASP_SCPOL_SHIFT 2 +-#define CS42L42_ASP_SCPOL_MASK (3 << CS42L42_ASP_SCPOL_SHIFT) +-#define CS42L42_ASP_SCPOL_NOR 3 +-#define CS42L42_ASP_LCPOL_SHIFT 0 +-#define CS42L42_ASP_LCPOL_MASK (3 << CS42L42_ASP_LCPOL_SHIFT) +-#define CS42L42_ASP_LCPOL_INV 3 +- +-#define CS42L42_ASP_FRM_CFG (CS42L42_PAGE_12 + 0x08) +-#define CS42L42_ASP_STP_SHIFT 4 +-#define CS42L42_ASP_STP_MASK (1 << CS42L42_ASP_STP_SHIFT) +-#define CS42L42_ASP_5050_SHIFT 3 +-#define CS42L42_ASP_5050_MASK (1 << CS42L42_ASP_5050_SHIFT) +-#define CS42L42_ASP_FSD_SHIFT 0 +-#define CS42L42_ASP_FSD_MASK (7 << CS42L42_ASP_FSD_SHIFT) +-#define CS42L42_ASP_FSD_0_5 1 +-#define CS42L42_ASP_FSD_1_0 2 +-#define CS42L42_ASP_FSD_1_5 3 +-#define CS42L42_ASP_FSD_2_0 4 +- +-#define CS42L42_FS_RATE_EN (CS42L42_PAGE_12 + 0x09) +-#define CS42L42_FS_EN_SHIFT 0 +-#define CS42L42_FS_EN_MASK (0xf << CS42L42_FS_EN_SHIFT) +-#define CS42L42_FS_EN_IASRC_96K 0x1 +-#define CS42L42_FS_EN_OASRC_96K 0x2 +- +-#define CS42L42_IN_ASRC_CLK (CS42L42_PAGE_12 + 0x0A) +-#define CS42L42_CLK_IASRC_SEL_SHIFT 0 +-#define CS42L42_CLK_IASRC_SEL_MASK (1 << CS42L42_CLK_IASRC_SEL_SHIFT) +-#define CS42L42_CLK_IASRC_SEL_6 0 +-#define CS42L42_CLK_IASRC_SEL_12 1 +- +-#define CS42L42_OUT_ASRC_CLK (CS42L42_PAGE_12 + 0x0B) +-#define CS42L42_CLK_OASRC_SEL_SHIFT 0 +-#define CS42L42_CLK_OASRC_SEL_MASK (1 << CS42L42_CLK_OASRC_SEL_SHIFT) +-#define CS42L42_CLK_OASRC_SEL_12 1 +- +-#define CS42L42_PLL_DIV_CFG1 (CS42L42_PAGE_12 + 0x0C) +-#define CS42L42_SCLK_PREDIV_SHIFT 0 +-#define CS42L42_SCLK_PREDIV_MASK (3 << CS42L42_SCLK_PREDIV_SHIFT) +- +-/* Page 0x13 Interrupt Registers */ +-/* Interrupts */ +-#define CS42L42_ADC_OVFL_STATUS (CS42L42_PAGE_13 + 0x01) +-#define CS42L42_MIXER_STATUS (CS42L42_PAGE_13 + 0x02) +-#define CS42L42_SRC_STATUS (CS42L42_PAGE_13 + 0x03) +-#define CS42L42_ASP_RX_STATUS (CS42L42_PAGE_13 + 0x04) +-#define CS42L42_ASP_TX_STATUS (CS42L42_PAGE_13 + 0x05) +-#define CS42L42_CODEC_STATUS (CS42L42_PAGE_13 + 0x08) +-#define CS42L42_DET_INT_STATUS1 (CS42L42_PAGE_13 + 0x09) +-#define CS42L42_DET_INT_STATUS2 (CS42L42_PAGE_13 + 0x0A) +-#define CS42L42_SRCPL_INT_STATUS (CS42L42_PAGE_13 + 0x0B) +-#define CS42L42_VPMON_STATUS (CS42L42_PAGE_13 + 0x0D) +-#define CS42L42_PLL_LOCK_STATUS (CS42L42_PAGE_13 + 0x0E) +-#define CS42L42_TSRS_PLUG_STATUS (CS42L42_PAGE_13 + 0x0F) +-/* Masks */ +-#define CS42L42_ADC_OVFL_INT_MASK (CS42L42_PAGE_13 + 0x16) +-#define CS42L42_ADC_OVFL_SHIFT 0 +-#define CS42L42_ADC_OVFL_MASK (1 << CS42L42_ADC_OVFL_SHIFT) +-#define CS42L42_ADC_OVFL_VAL_MASK CS42L42_ADC_OVFL_MASK +- +-#define CS42L42_MIXER_INT_MASK (CS42L42_PAGE_13 + 0x17) +-#define CS42L42_MIX_CHB_OVFL_SHIFT 0 +-#define CS42L42_MIX_CHB_OVFL_MASK (1 << CS42L42_MIX_CHB_OVFL_SHIFT) +-#define CS42L42_MIX_CHA_OVFL_SHIFT 1 +-#define CS42L42_MIX_CHA_OVFL_MASK (1 << CS42L42_MIX_CHA_OVFL_SHIFT) +-#define CS42L42_EQ_OVFL_SHIFT 2 +-#define CS42L42_EQ_OVFL_MASK (1 << CS42L42_EQ_OVFL_SHIFT) +-#define CS42L42_EQ_BIQUAD_OVFL_SHIFT 3 +-#define CS42L42_EQ_BIQUAD_OVFL_MASK (1 << CS42L42_EQ_BIQUAD_OVFL_SHIFT) +-#define CS42L42_MIXER_VAL_MASK (CS42L42_MIX_CHB_OVFL_MASK | \ +- CS42L42_MIX_CHA_OVFL_MASK | \ +- CS42L42_EQ_OVFL_MASK | \ +- CS42L42_EQ_BIQUAD_OVFL_MASK) +- +-#define CS42L42_SRC_INT_MASK (CS42L42_PAGE_13 + 0x18) +-#define CS42L42_SRC_ILK_SHIFT 0 +-#define CS42L42_SRC_ILK_MASK (1 << CS42L42_SRC_ILK_SHIFT) +-#define CS42L42_SRC_OLK_SHIFT 1 +-#define CS42L42_SRC_OLK_MASK (1 << CS42L42_SRC_OLK_SHIFT) +-#define CS42L42_SRC_IUNLK_SHIFT 2 +-#define CS42L42_SRC_IUNLK_MASK (1 << CS42L42_SRC_IUNLK_SHIFT) +-#define CS42L42_SRC_OUNLK_SHIFT 3 +-#define CS42L42_SRC_OUNLK_MASK (1 << CS42L42_SRC_OUNLK_SHIFT) +-#define CS42L42_SRC_VAL_MASK (CS42L42_SRC_ILK_MASK | \ +- CS42L42_SRC_OLK_MASK | \ +- CS42L42_SRC_IUNLK_MASK | \ +- CS42L42_SRC_OUNLK_MASK) +- +-#define CS42L42_ASP_RX_INT_MASK (CS42L42_PAGE_13 + 0x19) +-#define CS42L42_ASPRX_NOLRCK_SHIFT 0 +-#define CS42L42_ASPRX_NOLRCK_MASK (1 << CS42L42_ASPRX_NOLRCK_SHIFT) +-#define CS42L42_ASPRX_EARLY_SHIFT 1 +-#define CS42L42_ASPRX_EARLY_MASK (1 << CS42L42_ASPRX_EARLY_SHIFT) +-#define CS42L42_ASPRX_LATE_SHIFT 2 +-#define CS42L42_ASPRX_LATE_MASK (1 << CS42L42_ASPRX_LATE_SHIFT) +-#define CS42L42_ASPRX_ERROR_SHIFT 3 +-#define CS42L42_ASPRX_ERROR_MASK (1 << CS42L42_ASPRX_ERROR_SHIFT) +-#define CS42L42_ASPRX_OVLD_SHIFT 4 +-#define CS42L42_ASPRX_OVLD_MASK (1 << CS42L42_ASPRX_OVLD_SHIFT) +-#define CS42L42_ASP_RX_VAL_MASK (CS42L42_ASPRX_NOLRCK_MASK | \ +- CS42L42_ASPRX_EARLY_MASK | \ +- CS42L42_ASPRX_LATE_MASK | \ +- CS42L42_ASPRX_ERROR_MASK | \ +- CS42L42_ASPRX_OVLD_MASK) +- +-#define CS42L42_ASP_TX_INT_MASK (CS42L42_PAGE_13 + 0x1A) +-#define CS42L42_ASPTX_NOLRCK_SHIFT 0 +-#define CS42L42_ASPTX_NOLRCK_MASK (1 << CS42L42_ASPTX_NOLRCK_SHIFT) +-#define CS42L42_ASPTX_EARLY_SHIFT 1 +-#define CS42L42_ASPTX_EARLY_MASK (1 << CS42L42_ASPTX_EARLY_SHIFT) +-#define CS42L42_ASPTX_LATE_SHIFT 2 +-#define CS42L42_ASPTX_LATE_MASK (1 << CS42L42_ASPTX_LATE_SHIFT) +-#define CS42L42_ASPTX_SMERROR_SHIFT 3 +-#define CS42L42_ASPTX_SMERROR_MASK (1 << CS42L42_ASPTX_SMERROR_SHIFT) +-#define CS42L42_ASP_TX_VAL_MASK (CS42L42_ASPTX_NOLRCK_MASK | \ +- CS42L42_ASPTX_EARLY_MASK | \ +- CS42L42_ASPTX_LATE_MASK | \ +- CS42L42_ASPTX_SMERROR_MASK) +- +-#define CS42L42_CODEC_INT_MASK (CS42L42_PAGE_13 + 0x1B) +-#define CS42L42_PDN_DONE_SHIFT 0 +-#define CS42L42_PDN_DONE_MASK (1 << CS42L42_PDN_DONE_SHIFT) +-#define CS42L42_HSDET_AUTO_DONE_SHIFT 1 +-#define CS42L42_HSDET_AUTO_DONE_MASK (1 << CS42L42_HSDET_AUTO_DONE_SHIFT) +-#define CS42L42_CODEC_VAL_MASK (CS42L42_PDN_DONE_MASK | \ +- CS42L42_HSDET_AUTO_DONE_MASK) +- +-#define CS42L42_SRCPL_INT_MASK (CS42L42_PAGE_13 + 0x1C) +-#define CS42L42_SRCPL_ADC_LK_SHIFT 0 +-#define CS42L42_SRCPL_ADC_LK_MASK (1 << CS42L42_SRCPL_ADC_LK_SHIFT) +-#define CS42L42_SRCPL_DAC_LK_SHIFT 2 +-#define CS42L42_SRCPL_DAC_LK_MASK (1 << CS42L42_SRCPL_DAC_LK_SHIFT) +-#define CS42L42_SRCPL_ADC_UNLK_SHIFT 5 +-#define CS42L42_SRCPL_ADC_UNLK_MASK (1 << CS42L42_SRCPL_ADC_UNLK_SHIFT) +-#define CS42L42_SRCPL_DAC_UNLK_SHIFT 6 +-#define CS42L42_SRCPL_DAC_UNLK_MASK (1 << CS42L42_SRCPL_DAC_UNLK_SHIFT) +-#define CS42L42_SRCPL_VAL_MASK (CS42L42_SRCPL_ADC_LK_MASK | \ +- CS42L42_SRCPL_DAC_LK_MASK | \ +- CS42L42_SRCPL_ADC_UNLK_MASK | \ +- CS42L42_SRCPL_DAC_UNLK_MASK) +- +-#define CS42L42_VPMON_INT_MASK (CS42L42_PAGE_13 + 0x1E) +-#define CS42L42_VPMON_SHIFT 0 +-#define CS42L42_VPMON_MASK (1 << CS42L42_VPMON_SHIFT) +-#define CS42L42_VPMON_VAL_MASK CS42L42_VPMON_MASK +- +-#define CS42L42_PLL_LOCK_INT_MASK (CS42L42_PAGE_13 + 0x1F) +-#define CS42L42_PLL_LOCK_SHIFT 0 +-#define CS42L42_PLL_LOCK_MASK (1 << CS42L42_PLL_LOCK_SHIFT) +-#define CS42L42_PLL_LOCK_VAL_MASK CS42L42_PLL_LOCK_MASK +- +-#define CS42L42_TSRS_PLUG_INT_MASK (CS42L42_PAGE_13 + 0x20) +-#define CS42L42_RS_PLUG_SHIFT 0 +-#define CS42L42_RS_PLUG_MASK (1 << CS42L42_RS_PLUG_SHIFT) +-#define CS42L42_RS_UNPLUG_SHIFT 1 +-#define CS42L42_RS_UNPLUG_MASK (1 << CS42L42_RS_UNPLUG_SHIFT) +-#define CS42L42_TS_PLUG_SHIFT 2 +-#define CS42L42_TS_PLUG_MASK (1 << CS42L42_TS_PLUG_SHIFT) +-#define CS42L42_TS_UNPLUG_SHIFT 3 +-#define CS42L42_TS_UNPLUG_MASK (1 << CS42L42_TS_UNPLUG_SHIFT) +-#define CS42L42_TSRS_PLUG_VAL_MASK (CS42L42_RS_PLUG_MASK | \ +- CS42L42_RS_UNPLUG_MASK | \ +- CS42L42_TS_PLUG_MASK | \ +- CS42L42_TS_UNPLUG_MASK) +-#define CS42L42_TS_PLUG 3 +-#define CS42L42_TS_UNPLUG 0 +-#define CS42L42_TS_TRANS 1 +- +-/* +- * NOTE: PLL_START must be 0 while both ADC_PDN=1 and HP_PDN=1. +- * Otherwise it will prevent FILT+ from charging properly. +- */ +-#define CS42L42_PLL_CTL1 (CS42L42_PAGE_15 + 0x01) +-#define CS42L42_PLL_START_SHIFT 0 +-#define CS42L42_PLL_START_MASK (1 << CS42L42_PLL_START_SHIFT) +- +-#define CS42L42_PLL_DIV_FRAC0 (CS42L42_PAGE_15 + 0x02) +-#define CS42L42_PLL_DIV_FRAC_SHIFT 0 +-#define CS42L42_PLL_DIV_FRAC_MASK (0xff << CS42L42_PLL_DIV_FRAC_SHIFT) +- +-#define CS42L42_PLL_DIV_FRAC1 (CS42L42_PAGE_15 + 0x03) +-#define CS42L42_PLL_DIV_FRAC2 (CS42L42_PAGE_15 + 0x04) +- +-#define CS42L42_PLL_DIV_INT (CS42L42_PAGE_15 + 0x05) +-#define CS42L42_PLL_DIV_INT_SHIFT 0 +-#define CS42L42_PLL_DIV_INT_MASK (0xff << CS42L42_PLL_DIV_INT_SHIFT) +- +-#define CS42L42_PLL_CTL3 (CS42L42_PAGE_15 + 0x08) +-#define CS42L42_PLL_DIVOUT_SHIFT 0 +-#define CS42L42_PLL_DIVOUT_MASK (0xff << CS42L42_PLL_DIVOUT_SHIFT) +- +-#define CS42L42_PLL_CAL_RATIO (CS42L42_PAGE_15 + 0x0A) +-#define CS42L42_PLL_CAL_RATIO_SHIFT 0 +-#define CS42L42_PLL_CAL_RATIO_MASK (0xff << CS42L42_PLL_CAL_RATIO_SHIFT) +- +-#define CS42L42_PLL_CTL4 (CS42L42_PAGE_15 + 0x1B) +-#define CS42L42_PLL_MODE_SHIFT 0 +-#define CS42L42_PLL_MODE_MASK (3 << CS42L42_PLL_MODE_SHIFT) +- +-/* Page 0x19 HP Load Detect Registers */ +-#define CS42L42_LOAD_DET_RCSTAT (CS42L42_PAGE_19 + 0x25) +-#define CS42L42_RLA_STAT_SHIFT 0 +-#define CS42L42_RLA_STAT_MASK (3 << CS42L42_RLA_STAT_SHIFT) +-#define CS42L42_RLA_STAT_15_OHM 0 +- +-#define CS42L42_LOAD_DET_DONE (CS42L42_PAGE_19 + 0x26) +-#define CS42L42_HPLOAD_DET_DONE_SHIFT 0 +-#define CS42L42_HPLOAD_DET_DONE_MASK (1 << CS42L42_HPLOAD_DET_DONE_SHIFT) +- +-#define CS42L42_LOAD_DET_EN (CS42L42_PAGE_19 + 0x27) +-#define CS42L42_HP_LD_EN_SHIFT 0 +-#define CS42L42_HP_LD_EN_MASK (1 << CS42L42_HP_LD_EN_SHIFT) +- +-/* Page 0x1B Headset Interface Registers */ +-#define CS42L42_HSBIAS_SC_AUTOCTL (CS42L42_PAGE_1B + 0x70) +-#define CS42L42_HSBIAS_SENSE_TRIP_SHIFT 0 +-#define CS42L42_HSBIAS_SENSE_TRIP_MASK (7 << \ +- CS42L42_HSBIAS_SENSE_TRIP_SHIFT) +-#define CS42L42_TIP_SENSE_EN_SHIFT 5 +-#define CS42L42_TIP_SENSE_EN_MASK (1 << \ +- CS42L42_TIP_SENSE_EN_SHIFT) +-#define CS42L42_AUTO_HSBIAS_HIZ_SHIFT 6 +-#define CS42L42_AUTO_HSBIAS_HIZ_MASK (1 << \ +- CS42L42_AUTO_HSBIAS_HIZ_SHIFT) +-#define CS42L42_HSBIAS_SENSE_EN_SHIFT 7 +-#define CS42L42_HSBIAS_SENSE_EN_MASK (1 << \ +- CS42L42_HSBIAS_SENSE_EN_SHIFT) +- +-#define CS42L42_WAKE_CTL (CS42L42_PAGE_1B + 0x71) +-#define CS42L42_WAKEB_CLEAR_SHIFT 0 +-#define CS42L42_WAKEB_CLEAR_MASK (1 << CS42L42_WAKEB_CLEAR_SHIFT) +-#define CS42L42_WAKEB_MODE_SHIFT 5 +-#define CS42L42_WAKEB_MODE_MASK (1 << CS42L42_WAKEB_MODE_SHIFT) +-#define CS42L42_M_HP_WAKE_SHIFT 6 +-#define CS42L42_M_HP_WAKE_MASK (1 << CS42L42_M_HP_WAKE_SHIFT) +-#define CS42L42_M_MIC_WAKE_SHIFT 7 +-#define CS42L42_M_MIC_WAKE_MASK (1 << CS42L42_M_MIC_WAKE_SHIFT) +- +-#define CS42L42_ADC_DISABLE_MUTE (CS42L42_PAGE_1B + 0x72) +-#define CS42L42_ADC_DISABLE_S0_MUTE_SHIFT 7 +-#define CS42L42_ADC_DISABLE_S0_MUTE_MASK (1 << \ +- CS42L42_ADC_DISABLE_S0_MUTE_SHIFT) +- +-#define CS42L42_TIPSENSE_CTL (CS42L42_PAGE_1B + 0x73) +-#define CS42L42_TIP_SENSE_DEBOUNCE_SHIFT 0 +-#define CS42L42_TIP_SENSE_DEBOUNCE_MASK (3 << \ +- CS42L42_TIP_SENSE_DEBOUNCE_SHIFT) +-#define CS42L42_TIP_SENSE_INV_SHIFT 5 +-#define CS42L42_TIP_SENSE_INV_MASK (1 << \ +- CS42L42_TIP_SENSE_INV_SHIFT) +-#define CS42L42_TIP_SENSE_CTRL_SHIFT 6 +-#define CS42L42_TIP_SENSE_CTRL_MASK (3 << \ +- CS42L42_TIP_SENSE_CTRL_SHIFT) +- +-/* +- * NOTE: DETECT_MODE must be 0 while both ADC_PDN=1 and HP_PDN=1. +- * Otherwise it will prevent FILT+ from charging properly. +- */ +-#define CS42L42_MISC_DET_CTL (CS42L42_PAGE_1B + 0x74) +-#define CS42L42_PDN_MIC_LVL_DET_SHIFT 0 +-#define CS42L42_PDN_MIC_LVL_DET_MASK (1 << CS42L42_PDN_MIC_LVL_DET_SHIFT) +-#define CS42L42_HSBIAS_CTL_SHIFT 1 +-#define CS42L42_HSBIAS_CTL_MASK (3 << CS42L42_HSBIAS_CTL_SHIFT) +-#define CS42L42_DETECT_MODE_SHIFT 3 +-#define CS42L42_DETECT_MODE_MASK (3 << CS42L42_DETECT_MODE_SHIFT) +- +-#define CS42L42_MIC_DET_CTL1 (CS42L42_PAGE_1B + 0x75) +-#define CS42L42_HS_DET_LEVEL_SHIFT 0 +-#define CS42L42_HS_DET_LEVEL_MASK (0x3F << CS42L42_HS_DET_LEVEL_SHIFT) +-#define CS42L42_EVENT_STAT_SEL_SHIFT 6 +-#define CS42L42_EVENT_STAT_SEL_MASK (1 << CS42L42_EVENT_STAT_SEL_SHIFT) +-#define CS42L42_LATCH_TO_VP_SHIFT 7 +-#define CS42L42_LATCH_TO_VP_MASK (1 << CS42L42_LATCH_TO_VP_SHIFT) +- +-#define CS42L42_MIC_DET_CTL2 (CS42L42_PAGE_1B + 0x76) +-#define CS42L42_DEBOUNCE_TIME_SHIFT 5 +-#define CS42L42_DEBOUNCE_TIME_MASK (0x07 << CS42L42_DEBOUNCE_TIME_SHIFT) +- +-#define CS42L42_DET_STATUS1 (CS42L42_PAGE_1B + 0x77) +-#define CS42L42_HSBIAS_HIZ_MODE_SHIFT 6 +-#define CS42L42_HSBIAS_HIZ_MODE_MASK (1 << CS42L42_HSBIAS_HIZ_MODE_SHIFT) +-#define CS42L42_TIP_SENSE_SHIFT 7 +-#define CS42L42_TIP_SENSE_MASK (1 << CS42L42_TIP_SENSE_SHIFT) +- +-#define CS42L42_DET_STATUS2 (CS42L42_PAGE_1B + 0x78) +-#define CS42L42_SHORT_TRUE_SHIFT 0 +-#define CS42L42_SHORT_TRUE_MASK (1 << CS42L42_SHORT_TRUE_SHIFT) +-#define CS42L42_HS_TRUE_SHIFT 1 +-#define CS42L42_HS_TRUE_MASK (1 << CS42L42_HS_TRUE_SHIFT) +- +-#define CS42L42_DET_INT1_MASK (CS42L42_PAGE_1B + 0x79) +-#define CS42L42_TIP_SENSE_UNPLUG_SHIFT 5 +-#define CS42L42_TIP_SENSE_UNPLUG_MASK (1 << CS42L42_TIP_SENSE_UNPLUG_SHIFT) +-#define CS42L42_TIP_SENSE_PLUG_SHIFT 6 +-#define CS42L42_TIP_SENSE_PLUG_MASK (1 << CS42L42_TIP_SENSE_PLUG_SHIFT) +-#define CS42L42_HSBIAS_SENSE_SHIFT 7 +-#define CS42L42_HSBIAS_SENSE_MASK (1 << CS42L42_HSBIAS_SENSE_SHIFT) +-#define CS42L42_DET_INT_VAL1_MASK (CS42L42_TIP_SENSE_UNPLUG_MASK | \ +- CS42L42_TIP_SENSE_PLUG_MASK | \ +- CS42L42_HSBIAS_SENSE_MASK) +- +-#define CS42L42_DET_INT2_MASK (CS42L42_PAGE_1B + 0x7A) +-#define CS42L42_M_SHORT_DET_SHIFT 0 +-#define CS42L42_M_SHORT_DET_MASK (1 << \ +- CS42L42_M_SHORT_DET_SHIFT) +-#define CS42L42_M_SHORT_RLS_SHIFT 1 +-#define CS42L42_M_SHORT_RLS_MASK (1 << \ +- CS42L42_M_SHORT_RLS_SHIFT) +-#define CS42L42_M_HSBIAS_HIZ_SHIFT 2 +-#define CS42L42_M_HSBIAS_HIZ_MASK (1 << \ +- CS42L42_M_HSBIAS_HIZ_SHIFT) +-#define CS42L42_M_DETECT_FT_SHIFT 6 +-#define CS42L42_M_DETECT_FT_MASK (1 << \ +- CS42L42_M_DETECT_FT_SHIFT) +-#define CS42L42_M_DETECT_TF_SHIFT 7 +-#define CS42L42_M_DETECT_TF_MASK (1 << \ +- CS42L42_M_DETECT_TF_SHIFT) +-#define CS42L42_DET_INT_VAL2_MASK (CS42L42_M_SHORT_DET_MASK | \ +- CS42L42_M_SHORT_RLS_MASK | \ +- CS42L42_M_HSBIAS_HIZ_MASK | \ +- CS42L42_M_DETECT_FT_MASK | \ +- CS42L42_M_DETECT_TF_MASK) +- +-/* Page 0x1C Headset Bias Registers */ +-#define CS42L42_HS_BIAS_CTL (CS42L42_PAGE_1C + 0x03) +-#define CS42L42_HSBIAS_RAMP_SHIFT 0 +-#define CS42L42_HSBIAS_RAMP_MASK (3 << CS42L42_HSBIAS_RAMP_SHIFT) +-#define CS42L42_HSBIAS_PD_SHIFT 4 +-#define CS42L42_HSBIAS_PD_MASK (1 << CS42L42_HSBIAS_PD_SHIFT) +-#define CS42L42_HSBIAS_CAPLESS_SHIFT 7 +-#define CS42L42_HSBIAS_CAPLESS_MASK (1 << CS42L42_HSBIAS_CAPLESS_SHIFT) +- +-/* Page 0x1D ADC Registers */ +-#define CS42L42_ADC_CTL (CS42L42_PAGE_1D + 0x01) +-#define CS42L42_ADC_NOTCH_DIS_SHIFT 5 +-#define CS42L42_ADC_FORCE_WEAK_VCM_SHIFT 4 +-#define CS42L42_ADC_INV_SHIFT 2 +-#define CS42L42_ADC_DIG_BOOST_SHIFT 0 +- +-#define CS42L42_ADC_VOLUME (CS42L42_PAGE_1D + 0x03) +-#define CS42L42_ADC_VOL_SHIFT 0 +- +-#define CS42L42_ADC_WNF_HPF_CTL (CS42L42_PAGE_1D + 0x04) +-#define CS42L42_ADC_WNF_CF_SHIFT 4 +-#define CS42L42_ADC_WNF_EN_SHIFT 3 +-#define CS42L42_ADC_HPF_CF_SHIFT 1 +-#define CS42L42_ADC_HPF_EN_SHIFT 0 +- +-/* Page 0x1F DAC Registers */ +-#define CS42L42_DAC_CTL1 (CS42L42_PAGE_1F + 0x01) +-#define CS42L42_DACB_INV_SHIFT 1 +-#define CS42L42_DACA_INV_SHIFT 0 +- +-#define CS42L42_DAC_CTL2 (CS42L42_PAGE_1F + 0x06) +-#define CS42L42_HPOUT_PULLDOWN_SHIFT 4 +-#define CS42L42_HPOUT_PULLDOWN_MASK (15 << CS42L42_HPOUT_PULLDOWN_SHIFT) +-#define CS42L42_HPOUT_LOAD_SHIFT 3 +-#define CS42L42_HPOUT_LOAD_MASK (1 << CS42L42_HPOUT_LOAD_SHIFT) +-#define CS42L42_HPOUT_CLAMP_SHIFT 2 +-#define CS42L42_HPOUT_CLAMP_MASK (1 << CS42L42_HPOUT_CLAMP_SHIFT) +-#define CS42L42_DAC_HPF_EN_SHIFT 1 +-#define CS42L42_DAC_HPF_EN_MASK (1 << CS42L42_DAC_HPF_EN_SHIFT) +-#define CS42L42_DAC_MON_EN_SHIFT 0 +-#define CS42L42_DAC_MON_EN_MASK (1 << CS42L42_DAC_MON_EN_SHIFT) +- +-/* Page 0x20 HP CTL Registers */ +-#define CS42L42_HP_CTL (CS42L42_PAGE_20 + 0x01) +-#define CS42L42_HP_ANA_BMUTE_SHIFT 3 +-#define CS42L42_HP_ANA_BMUTE_MASK (1 << CS42L42_HP_ANA_BMUTE_SHIFT) +-#define CS42L42_HP_ANA_AMUTE_SHIFT 2 +-#define CS42L42_HP_ANA_AMUTE_MASK (1 << CS42L42_HP_ANA_AMUTE_SHIFT) +-#define CS42L42_HP_FULL_SCALE_VOL_SHIFT 1 +-#define CS42L42_HP_FULL_SCALE_VOL_MASK (1 << CS42L42_HP_FULL_SCALE_VOL_SHIFT) +- +-/* Page 0x21 Class H Registers */ +-#define CS42L42_CLASSH_CTL (CS42L42_PAGE_21 + 0x01) +- +-/* Page 0x23 Mixer Volume Registers */ +-#define CS42L42_MIXER_CHA_VOL (CS42L42_PAGE_23 + 0x01) +-#define CS42L42_MIXER_ADC_VOL (CS42L42_PAGE_23 + 0x02) +- +-#define CS42L42_MIXER_CHB_VOL (CS42L42_PAGE_23 + 0x03) +-#define CS42L42_MIXER_CH_VOL_SHIFT 0 +-#define CS42L42_MIXER_CH_VOL_MASK (0x3f << CS42L42_MIXER_CH_VOL_SHIFT) +- +-/* Page 0x24 EQ Registers */ +-#define CS42L42_EQ_COEF_IN0 (CS42L42_PAGE_24 + 0x01) +-#define CS42L42_EQ_COEF_IN1 (CS42L42_PAGE_24 + 0x02) +-#define CS42L42_EQ_COEF_IN2 (CS42L42_PAGE_24 + 0x03) +-#define CS42L42_EQ_COEF_IN3 (CS42L42_PAGE_24 + 0x04) +-#define CS42L42_EQ_COEF_RW (CS42L42_PAGE_24 + 0x06) +-#define CS42L42_EQ_COEF_OUT0 (CS42L42_PAGE_24 + 0x07) +-#define CS42L42_EQ_COEF_OUT1 (CS42L42_PAGE_24 + 0x08) +-#define CS42L42_EQ_COEF_OUT2 (CS42L42_PAGE_24 + 0x09) +-#define CS42L42_EQ_COEF_OUT3 (CS42L42_PAGE_24 + 0x0A) +-#define CS42L42_EQ_INIT_STAT (CS42L42_PAGE_24 + 0x0B) +-#define CS42L42_EQ_START_FILT (CS42L42_PAGE_24 + 0x0C) +-#define CS42L42_EQ_MUTE_CTL (CS42L42_PAGE_24 + 0x0E) +- +-/* Page 0x25 Audio Port Registers */ +-#define CS42L42_SP_RX_CH_SEL (CS42L42_PAGE_25 + 0x01) +-#define CS42L42_SP_RX_CHB_SEL_SHIFT 2 +-#define CS42L42_SP_RX_CHB_SEL_MASK (3 << CS42L42_SP_RX_CHB_SEL_SHIFT) +- +-#define CS42L42_SP_RX_ISOC_CTL (CS42L42_PAGE_25 + 0x02) +-#define CS42L42_SP_RX_RSYNC_SHIFT 6 +-#define CS42L42_SP_RX_RSYNC_MASK (1 << CS42L42_SP_RX_RSYNC_SHIFT) +-#define CS42L42_SP_RX_NSB_POS_SHIFT 3 +-#define CS42L42_SP_RX_NSB_POS_MASK (7 << CS42L42_SP_RX_NSB_POS_SHIFT) +-#define CS42L42_SP_RX_NFS_NSBB_SHIFT 2 +-#define CS42L42_SP_RX_NFS_NSBB_MASK (1 << CS42L42_SP_RX_NFS_NSBB_SHIFT) +-#define CS42L42_SP_RX_ISOC_MODE_SHIFT 0 +-#define CS42L42_SP_RX_ISOC_MODE_MASK (3 << CS42L42_SP_RX_ISOC_MODE_SHIFT) +- +-#define CS42L42_SP_RX_FS (CS42L42_PAGE_25 + 0x03) +-#define CS42l42_SPDIF_CH_SEL (CS42L42_PAGE_25 + 0x04) +-#define CS42L42_SP_TX_ISOC_CTL (CS42L42_PAGE_25 + 0x05) +-#define CS42L42_SP_TX_FS (CS42L42_PAGE_25 + 0x06) +-#define CS42L42_SPDIF_SW_CTL1 (CS42L42_PAGE_25 + 0x07) +- +-/* Page 0x26 SRC Registers */ +-#define CS42L42_SRC_SDIN_FS (CS42L42_PAGE_26 + 0x01) +-#define CS42L42_SRC_SDIN_FS_SHIFT 0 +-#define CS42L42_SRC_SDIN_FS_MASK (0x1f << CS42L42_SRC_SDIN_FS_SHIFT) +- +-#define CS42L42_SRC_SDOUT_FS (CS42L42_PAGE_26 + 0x09) +- +-/* Page 0x28 S/PDIF Registers */ +-#define CS42L42_SPDIF_CTL1 (CS42L42_PAGE_28 + 0x01) +-#define CS42L42_SPDIF_CTL2 (CS42L42_PAGE_28 + 0x02) +-#define CS42L42_SPDIF_CTL3 (CS42L42_PAGE_28 + 0x03) +-#define CS42L42_SPDIF_CTL4 (CS42L42_PAGE_28 + 0x04) +- +-/* Page 0x29 Serial Port TX Registers */ +-#define CS42L42_ASP_TX_SZ_EN (CS42L42_PAGE_29 + 0x01) +-#define CS42L42_ASP_TX_EN_SHIFT 0 +-#define CS42L42_ASP_TX_CH_EN (CS42L42_PAGE_29 + 0x02) +-#define CS42L42_ASP_TX0_CH2_SHIFT 1 +-#define CS42L42_ASP_TX0_CH1_SHIFT 0 +- +-#define CS42L42_ASP_TX_CH_AP_RES (CS42L42_PAGE_29 + 0x03) +-#define CS42L42_ASP_TX_CH1_AP_SHIFT 7 +-#define CS42L42_ASP_TX_CH1_AP_MASK (1 << CS42L42_ASP_TX_CH1_AP_SHIFT) +-#define CS42L42_ASP_TX_CH2_AP_SHIFT 6 +-#define CS42L42_ASP_TX_CH2_AP_MASK (1 << CS42L42_ASP_TX_CH2_AP_SHIFT) +-#define CS42L42_ASP_TX_CH2_RES_SHIFT 2 +-#define CS42L42_ASP_TX_CH2_RES_MASK (3 << CS42L42_ASP_TX_CH2_RES_SHIFT) +-#define CS42L42_ASP_TX_CH1_RES_SHIFT 0 +-#define CS42L42_ASP_TX_CH1_RES_MASK (3 << CS42L42_ASP_TX_CH1_RES_SHIFT) +-#define CS42L42_ASP_TX_CH1_BIT_MSB (CS42L42_PAGE_29 + 0x04) +-#define CS42L42_ASP_TX_CH1_BIT_LSB (CS42L42_PAGE_29 + 0x05) +-#define CS42L42_ASP_TX_HIZ_DLY_CFG (CS42L42_PAGE_29 + 0x06) +-#define CS42L42_ASP_TX_CH2_BIT_MSB (CS42L42_PAGE_29 + 0x0A) +-#define CS42L42_ASP_TX_CH2_BIT_LSB (CS42L42_PAGE_29 + 0x0B) +- +-/* Page 0x2A Serial Port RX Registers */ +-#define CS42L42_ASP_RX_DAI0_EN (CS42L42_PAGE_2A + 0x01) +-#define CS42L42_ASP_RX0_CH_EN_SHIFT 2 +-#define CS42L42_ASP_RX0_CH_EN_MASK (0xf << CS42L42_ASP_RX0_CH_EN_SHIFT) +-#define CS42L42_ASP_RX0_CH1_SHIFT 2 +-#define CS42L42_ASP_RX0_CH2_SHIFT 3 +-#define CS42L42_ASP_RX0_CH3_SHIFT 4 +-#define CS42L42_ASP_RX0_CH4_SHIFT 5 +- +-#define CS42L42_ASP_RX_DAI0_CH1_AP_RES (CS42L42_PAGE_2A + 0x02) +-#define CS42L42_ASP_RX_DAI0_CH1_BIT_MSB (CS42L42_PAGE_2A + 0x03) +-#define CS42L42_ASP_RX_DAI0_CH1_BIT_LSB (CS42L42_PAGE_2A + 0x04) +-#define CS42L42_ASP_RX_DAI0_CH2_AP_RES (CS42L42_PAGE_2A + 0x05) +-#define CS42L42_ASP_RX_DAI0_CH2_BIT_MSB (CS42L42_PAGE_2A + 0x06) +-#define CS42L42_ASP_RX_DAI0_CH2_BIT_LSB (CS42L42_PAGE_2A + 0x07) +-#define CS42L42_ASP_RX_DAI0_CH3_AP_RES (CS42L42_PAGE_2A + 0x08) +-#define CS42L42_ASP_RX_DAI0_CH3_BIT_MSB (CS42L42_PAGE_2A + 0x09) +-#define CS42L42_ASP_RX_DAI0_CH3_BIT_LSB (CS42L42_PAGE_2A + 0x0A) +-#define CS42L42_ASP_RX_DAI0_CH4_AP_RES (CS42L42_PAGE_2A + 0x0B) +-#define CS42L42_ASP_RX_DAI0_CH4_BIT_MSB (CS42L42_PAGE_2A + 0x0C) +-#define CS42L42_ASP_RX_DAI0_CH4_BIT_LSB (CS42L42_PAGE_2A + 0x0D) +-#define CS42L42_ASP_RX_DAI1_CH1_AP_RES (CS42L42_PAGE_2A + 0x0E) +-#define CS42L42_ASP_RX_DAI1_CH1_BIT_MSB (CS42L42_PAGE_2A + 0x0F) +-#define CS42L42_ASP_RX_DAI1_CH1_BIT_LSB (CS42L42_PAGE_2A + 0x10) +-#define CS42L42_ASP_RX_DAI1_CH2_AP_RES (CS42L42_PAGE_2A + 0x11) +-#define CS42L42_ASP_RX_DAI1_CH2_BIT_MSB (CS42L42_PAGE_2A + 0x12) +-#define CS42L42_ASP_RX_DAI1_CH2_BIT_LSB (CS42L42_PAGE_2A + 0x13) +- +-#define CS42L42_ASP_RX_CH_AP_SHIFT 6 +-#define CS42L42_ASP_RX_CH_AP_MASK (1 << CS42L42_ASP_RX_CH_AP_SHIFT) +-#define CS42L42_ASP_RX_CH_AP_LOW 0 +-#define CS42L42_ASP_RX_CH_AP_HI 1 +-#define CS42L42_ASP_RX_CH_RES_SHIFT 0 +-#define CS42L42_ASP_RX_CH_RES_MASK (3 << CS42L42_ASP_RX_CH_RES_SHIFT) +-#define CS42L42_ASP_RX_CH_RES_32 3 +-#define CS42L42_ASP_RX_CH_RES_16 1 +-#define CS42L42_ASP_RX_CH_BIT_ST_SHIFT 0 +-#define CS42L42_ASP_RX_CH_BIT_ST_MASK (0xff << CS42L42_ASP_RX_CH_BIT_ST_SHIFT) +- +-/* Page 0x30 ID Registers */ +-#define CS42L42_SUB_REVID (CS42L42_PAGE_30 + 0x14) +-#define CS42L42_MAX_REGISTER (CS42L42_PAGE_30 + 0x14) +- +-/* Defines for fracturing values spread across multiple registers */ +-#define CS42L42_FRAC0_VAL(val) ((val) & 0x0000ff) +-#define CS42L42_FRAC1_VAL(val) (((val) & 0x00ff00) >> 8) +-#define CS42L42_FRAC2_VAL(val) (((val) & 0xff0000) >> 16) +- +-#define CS42L42_NUM_SUPPLIES 5 +-#define CS42L42_BOOT_TIME_US 3000 +-#define CS42L42_PLL_DIVOUT_TIME_US 800 +-#define CS42L42_CLOCK_SWITCH_DELAY_US 150 +-#define CS42L42_PLL_LOCK_POLL_US 250 +-#define CS42L42_PLL_LOCK_TIMEOUT_US 1250 +-#define CS42L42_HP_ADC_EN_TIME_US 20000 +-#define CS42L42_PDN_DONE_POLL_US 1000 +-#define CS42L42_PDN_DONE_TIMEOUT_US 200000 +-#define CS42L42_PDN_DONE_TIME_MS 100 +-#define CS42L42_FILT_DISCHARGE_TIME_MS 46 ++#include + + static const char *const cs42l42_supply_names[CS42L42_NUM_SUPPLIES] = { + "VA", +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs42l42-Only-report-button-state-if-there-was-a.patch b/patches.suse/ASoC-cs42l42-Only-report-button-state-if-there-was-a.patch new file mode 100644 index 0000000..a9d9405 --- /dev/null +++ b/patches.suse/ASoC-cs42l42-Only-report-button-state-if-there-was-a.patch @@ -0,0 +1,63 @@ +From ea75deef1a738d25502cfbb2caa564270b271525 Mon Sep 17 00:00:00 2001 +From: Richard Fitzgerald +Date: Mon, 15 Aug 2022 13:31:38 +0100 +Subject: [PATCH] ASoC: cs42l42: Only report button state if there was a button interrupt +Git-commit: ea75deef1a738d25502cfbb2caa564270b271525 +Patch-mainline: v6.0-rc5 +References: git-fixes + +Only report a button state change if the interrupt status shows that +there was a button event. + +Previously the code would always drop into the button reporting at the +end of interrupt handling if the jack was present. If neither of the +button report interrupts were pending it would report all buttons +released. This could then lead to a button being reported as released +while it is still pressed. + +Fixes: c5b8ee0879bc ("ASoC: cs42l42: Report jack and button detection") +Signed-off-by: Richard Fitzgerald +Link: https://lore.kernel.org/r/20220815123138.3810249-1-rf@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs42l42.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c +index d545a593a251..daafd4251ce6 100644 +--- a/sound/soc/codecs/cs42l42.c ++++ b/sound/soc/codecs/cs42l42.c +@@ -1617,7 +1617,6 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data) + unsigned int current_plug_status; + unsigned int current_button_status; + unsigned int i; +- int report = 0; + + mutex_lock(&cs42l42->irq_lock); + if (cs42l42->suspended) { +@@ -1711,13 +1710,15 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data) + + if (current_button_status & CS42L42_M_DETECT_TF_MASK) { + dev_dbg(cs42l42->dev, "Button released\n"); +- report = 0; ++ snd_soc_jack_report(cs42l42->jack, 0, ++ SND_JACK_BTN_0 | SND_JACK_BTN_1 | ++ SND_JACK_BTN_2 | SND_JACK_BTN_3); + } else if (current_button_status & CS42L42_M_DETECT_FT_MASK) { +- report = cs42l42_handle_button_press(cs42l42); +- ++ snd_soc_jack_report(cs42l42->jack, ++ cs42l42_handle_button_press(cs42l42), ++ SND_JACK_BTN_0 | SND_JACK_BTN_1 | ++ SND_JACK_BTN_2 | SND_JACK_BTN_3); + } +- snd_soc_jack_report(cs42l42->jack, report, SND_JACK_BTN_0 | SND_JACK_BTN_1 | +- SND_JACK_BTN_2 | SND_JACK_BTN_3); + } + } + +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs42l42-Prevent-NULL-pointer-deref-in-interrupt.patch b/patches.suse/ASoC-cs42l42-Prevent-NULL-pointer-deref-in-interrupt.patch new file mode 100644 index 0000000..365adac --- /dev/null +++ b/patches.suse/ASoC-cs42l42-Prevent-NULL-pointer-deref-in-interrupt.patch @@ -0,0 +1,141 @@ +From 2003c44e28ac9759200a78dda20c5f695949e3f4 Mon Sep 17 00:00:00 2001 +From: Richard Fitzgerald +Date: Mon, 25 Oct 2021 12:22:58 +0100 +Subject: [PATCH] ASoC: cs42l42: Prevent NULL pointer deref in interrupt handler +Git-commit: 2003c44e28ac9759200a78dda20c5f695949e3f4 +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +The interrupt handling code was getting the struct device* from a +struct snd_soc_component* stored in struct cs42l42_private. If the +interrupt was asserted before ASoC calls component_probe() the +snd_soc_component* will be NULL. + +The stored snd_soc_component* is not actually used for anything other +than indirectly getting the struct device*. Remove it, and store the +struct device* in struct cs42l42_private. + +Signed-off-by: Richard Fitzgerald +Link: https://lore.kernel.org/r/20211025112258.9282-1-rf@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs42l42.c | 28 +++++++++------------------- + sound/soc/codecs/cs42l42.h | 2 +- + 2 files changed, 10 insertions(+), 20 deletions(-) + +diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c +index 0dbe4e23194b..a8fff274ec63 100644 +--- a/sound/soc/codecs/cs42l42.c ++++ b/sound/soc/codecs/cs42l42.c +@@ -526,17 +526,7 @@ static int cs42l42_set_jack(struct snd_soc_component *component, struct snd_soc_ + return 0; + } + +-static int cs42l42_component_probe(struct snd_soc_component *component) +-{ +- struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component); +- +- cs42l42->component = component; +- +- return 0; +-} +- + static const struct snd_soc_component_driver soc_component_dev_cs42l42 = { +- .probe = cs42l42_component_probe, + .set_jack = cs42l42_set_jack, + .dapm_widgets = cs42l42_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(cs42l42_dapm_widgets), +@@ -1207,7 +1197,7 @@ static void cs42l42_process_hs_type_detect(struct cs42l42_private *cs42l42) + */ + if (cs42l42->hs_type == CS42L42_PLUG_INVALID || + cs42l42->hs_type == CS42L42_PLUG_HEADPHONE) { +- dev_dbg(cs42l42->component->dev, "Running Manual Detection Fallback\n"); ++ dev_dbg(cs42l42->dev, "Running Manual Detection Fallback\n"); + cs42l42_manual_hs_type_detect(cs42l42); + } + +@@ -1506,19 +1496,19 @@ static int cs42l42_handle_button_press(struct cs42l42_private *cs42l42) + switch (bias_level) { + case 1: /* Function C button press */ + bias_level = SND_JACK_BTN_2; +- dev_dbg(cs42l42->component->dev, "Function C button press\n"); ++ dev_dbg(cs42l42->dev, "Function C button press\n"); + break; + case 2: /* Function B button press */ + bias_level = SND_JACK_BTN_1; +- dev_dbg(cs42l42->component->dev, "Function B button press\n"); ++ dev_dbg(cs42l42->dev, "Function B button press\n"); + break; + case 3: /* Function D button press */ + bias_level = SND_JACK_BTN_3; +- dev_dbg(cs42l42->component->dev, "Function D button press\n"); ++ dev_dbg(cs42l42->dev, "Function D button press\n"); + break; + case 4: /* Function A button press */ + bias_level = SND_JACK_BTN_0; +- dev_dbg(cs42l42->component->dev, "Function A button press\n"); ++ dev_dbg(cs42l42->dev, "Function A button press\n"); + break; + default: + bias_level = 0; +@@ -1592,7 +1582,6 @@ static const struct cs42l42_irq_params irq_params_table[] = { + static irqreturn_t cs42l42_irq_thread(int irq, void *data) + { + struct cs42l42_private *cs42l42 = (struct cs42l42_private *)data; +- struct snd_soc_component *component = cs42l42->component; + unsigned int stickies[12]; + unsigned int masks[12]; + unsigned int current_plug_status; +@@ -1639,7 +1628,7 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data) + default: + break; + } +- dev_dbg(component->dev, "Auto detect done (%d)\n", cs42l42->hs_type); ++ dev_dbg(cs42l42->dev, "Auto detect done (%d)\n", cs42l42->hs_type); + } + } + +@@ -1673,7 +1662,7 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data) + SND_JACK_BTN_0 | SND_JACK_BTN_1 | + SND_JACK_BTN_2 | SND_JACK_BTN_3); + +- dev_dbg(component->dev, "Unplug event\n"); ++ dev_dbg(cs42l42->dev, "Unplug event\n"); + } + break; + +@@ -1689,7 +1678,7 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data) + CS42L42_M_HSBIAS_HIZ_MASK)) { + + if (current_button_status & CS42L42_M_DETECT_TF_MASK) { +- dev_dbg(component->dev, "Button released\n"); ++ dev_dbg(cs42l42->dev, "Button released\n"); + report = 0; + } else if (current_button_status & CS42L42_M_DETECT_FT_MASK) { + report = cs42l42_handle_button_press(cs42l42); +@@ -2043,6 +2032,7 @@ static int cs42l42_i2c_probe(struct i2c_client *i2c_client, + if (!cs42l42) + return -ENOMEM; + ++ cs42l42->dev = &i2c_client->dev; + i2c_set_clientdata(i2c_client, cs42l42); + + cs42l42->regmap = devm_regmap_init_i2c(i2c_client, &cs42l42_regmap); +diff --git a/sound/soc/codecs/cs42l42.h b/sound/soc/codecs/cs42l42.h +index dd4744de9e0a..f45bcc9a3a62 100644 +--- a/sound/soc/codecs/cs42l42.h ++++ b/sound/soc/codecs/cs42l42.h +@@ -833,7 +833,7 @@ static const char *const cs42l42_supply_names[CS42L42_NUM_SUPPLIES] = { + + struct cs42l42_private { + struct regmap *regmap; +- struct snd_soc_component *component; ++ struct device *dev; + struct regulator_bulk_data supplies[CS42L42_NUM_SUPPLIES]; + struct gpio_desc *reset_gpio; + struct completion pdn_done; +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs42l42-Remove-redundant-pll_divout-member.patch b/patches.suse/ASoC-cs42l42-Remove-redundant-pll_divout-member.patch new file mode 100644 index 0000000..a966cd8 --- /dev/null +++ b/patches.suse/ASoC-cs42l42-Remove-redundant-pll_divout-member.patch @@ -0,0 +1,69 @@ +From bbf0e1d36519a5cd2c08dc1348f997cd5240eb2e Mon Sep 17 00:00:00 2001 +From: Richard Fitzgerald +Date: Tue, 16 Nov 2021 16:39:01 +0000 +Subject: [PATCH] ASoC: cs42l42: Remove redundant pll_divout member +Git-commit: bbf0e1d36519a5cd2c08dc1348f997cd5240eb2e +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +Now that struct cs42l42_private has pll_config, the current PLL +configuration can be looked up directly in pll_ratio_table. This +makes the pll_divout member of cs42l42_private redundant since it +was only a copy of the value from pll_ratio_table. + +Signed-off-by: Richard Fitzgerald +Link: https://lore.kernel.org/r/20211116163901.45390-5-rf@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs42l42.c | 9 +++------ + sound/soc/codecs/cs42l42.h | 1 - + 2 files changed, 3 insertions(+), 7 deletions(-) + +diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c +index 8efcee3e60d3..0c4303547fd8 100644 +--- a/sound/soc/codecs/cs42l42.c ++++ b/sound/soc/codecs/cs42l42.c +@@ -734,10 +734,6 @@ static int cs42l42_pll_config(struct snd_soc_component *component) + CS42L42_PLL_DIVOUT_MASK, + (pll_ratio_table[i].pll_divout * pll_ratio_table[i].n) + << CS42L42_PLL_DIVOUT_SHIFT); +- if (pll_ratio_table[i].n != 1) +- cs42l42->pll_divout = pll_ratio_table[i].pll_divout; +- else +- cs42l42->pll_divout = 0; + snd_soc_component_update_bits(component, + CS42L42_PLL_CAL_RATIO, + CS42L42_PLL_CAL_RATIO_MASK, +@@ -1004,12 +1000,13 @@ static int cs42l42_mute_stream(struct snd_soc_dai *dai, int mute, int stream) + snd_soc_component_update_bits(component, CS42L42_PLL_CTL1, + CS42L42_PLL_START_MASK, 1); + +- if (cs42l42->pll_divout) { ++ if (pll_ratio_table[cs42l42->pll_config].n > 1) { + usleep_range(CS42L42_PLL_DIVOUT_TIME_US, + CS42L42_PLL_DIVOUT_TIME_US * 2); ++ regval = pll_ratio_table[cs42l42->pll_config].pll_divout; + snd_soc_component_update_bits(component, CS42L42_PLL_CTL3, + CS42L42_PLL_DIVOUT_MASK, +- cs42l42->pll_divout << ++ regval << + CS42L42_PLL_DIVOUT_SHIFT); + } + +diff --git a/sound/soc/codecs/cs42l42.h b/sound/soc/codecs/cs42l42.h +index c8b3267a318b..75ade987d0db 100644 +--- a/sound/soc/codecs/cs42l42.h ++++ b/sound/soc/codecs/cs42l42.h +@@ -845,7 +845,6 @@ struct cs42l42_private { + int bclk; + u32 sclk; + u32 srate; +- u8 pll_divout; + u8 plug_state; + u8 hs_type; + u8 ts_inv; +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs42l42-Remove-redundant-writes-to-DETECT_MODE.patch b/patches.suse/ASoC-cs42l42-Remove-redundant-writes-to-DETECT_MODE.patch new file mode 100644 index 0000000..bac44c5 --- /dev/null +++ b/patches.suse/ASoC-cs42l42-Remove-redundant-writes-to-DETECT_MODE.patch @@ -0,0 +1,96 @@ +From 976001b10fa4441917f216452e70fd8c5aeccd94 Mon Sep 17 00:00:00 2001 +From: Richard Fitzgerald +Date: Tue, 16 Nov 2021 16:38:58 +0000 +Subject: [PATCH] ASoC: cs42l42: Remove redundant writes to DETECT_MODE +Git-commit: 976001b10fa4441917f216452e70fd8c5aeccd94 +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +There are multiple places where DETECT_MODE is included in a register +write, but in every case it is written as 0. Removing these redundant +writes makes the code less cluttered and also makes it obvious that +DETECT_MODE is never changed. + +A single initialization to 0 is added to cs42l42_setup_hs_type_detect(). + +Signed-off-by: Richard Fitzgerald +Link: https://lore.kernel.org/r/20211116163901.45390-2-rf@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs42l42.c | 13 +++---------- + 1 file changed, 3 insertions(+), 10 deletions(-) + +diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c +index 56804a3f285e..92bdc3a355ff 100644 +--- a/sound/soc/codecs/cs42l42.c ++++ b/sound/soc/codecs/cs42l42.c +@@ -1270,10 +1270,8 @@ static void cs42l42_process_hs_type_detect(struct cs42l42_private *cs42l42) + /* Turn on level detect circuitry */ + regmap_update_bits(cs42l42->regmap, + CS42L42_MISC_DET_CTL, +- CS42L42_DETECT_MODE_MASK | + CS42L42_HSBIAS_CTL_MASK | + CS42L42_PDN_MIC_LVL_DET_MASK, +- (0 << CS42L42_DETECT_MODE_SHIFT) | + (3 << CS42L42_HSBIAS_CTL_SHIFT) | + (0 << CS42L42_PDN_MIC_LVL_DET_SHIFT)); + +@@ -1300,10 +1298,8 @@ static void cs42l42_process_hs_type_detect(struct cs42l42_private *cs42l42) + /* Make sure button detect and HS bias circuits are off */ + regmap_update_bits(cs42l42->regmap, + CS42L42_MISC_DET_CTL, +- CS42L42_DETECT_MODE_MASK | + CS42L42_HSBIAS_CTL_MASK | + CS42L42_PDN_MIC_LVL_DET_MASK, +- (0 << CS42L42_DETECT_MODE_SHIFT) | + (1 << CS42L42_HSBIAS_CTL_SHIFT) | + (1 << CS42L42_PDN_MIC_LVL_DET_SHIFT)); + } +@@ -1351,10 +1347,8 @@ static void cs42l42_init_hs_type_detect(struct cs42l42_private *cs42l42) + /* Make sure button detect and HS bias circuits are off */ + regmap_update_bits(cs42l42->regmap, + CS42L42_MISC_DET_CTL, +- CS42L42_DETECT_MODE_MASK | + CS42L42_HSBIAS_CTL_MASK | + CS42L42_PDN_MIC_LVL_DET_MASK, +- (0 << CS42L42_DETECT_MODE_SHIFT) | + (1 << CS42L42_HSBIAS_CTL_SHIFT) | + (1 << CS42L42_PDN_MIC_LVL_DET_SHIFT)); + +@@ -1398,10 +1392,8 @@ static void cs42l42_init_hs_type_detect(struct cs42l42_private *cs42l42) + /* Power up HS bias to 2.7V */ + regmap_update_bits(cs42l42->regmap, + CS42L42_MISC_DET_CTL, +- CS42L42_DETECT_MODE_MASK | + CS42L42_HSBIAS_CTL_MASK | + CS42L42_PDN_MIC_LVL_DET_MASK, +- (0 << CS42L42_DETECT_MODE_SHIFT) | + (3 << CS42L42_HSBIAS_CTL_SHIFT) | + (1 << CS42L42_PDN_MIC_LVL_DET_SHIFT)); + +@@ -1448,10 +1440,8 @@ static void cs42l42_cancel_hs_type_detect(struct cs42l42_private *cs42l42) + /* Ground HS bias */ + regmap_update_bits(cs42l42->regmap, + CS42L42_MISC_DET_CTL, +- CS42L42_DETECT_MODE_MASK | + CS42L42_HSBIAS_CTL_MASK | + CS42L42_PDN_MIC_LVL_DET_MASK, +- (0 << CS42L42_DETECT_MODE_SHIFT) | + (1 << CS42L42_HSBIAS_CTL_SHIFT) | + (1 << CS42L42_PDN_MIC_LVL_DET_SHIFT)); + +@@ -1829,6 +1819,9 @@ static void cs42l42_setup_hs_type_detect(struct cs42l42_private *cs42l42) + + cs42l42->hs_type = CS42L42_PLUG_INVALID; + ++ regmap_update_bits(cs42l42->regmap, CS42L42_MISC_DET_CTL, ++ CS42L42_DETECT_MODE_MASK, 0); ++ + /* Latch analog controls to VP power domain */ + regmap_update_bits(cs42l42->regmap, CS42L42_MIC_DET_CTL1, + CS42L42_LATCH_TO_VP_MASK | +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs42l42-Remove-redundant-writes-to-RS_PLUG-RS_U.patch b/patches.suse/ASoC-cs42l42-Remove-redundant-writes-to-RS_PLUG-RS_U.patch new file mode 100644 index 0000000..e099481 --- /dev/null +++ b/patches.suse/ASoC-cs42l42-Remove-redundant-writes-to-RS_PLUG-RS_U.patch @@ -0,0 +1,56 @@ +From f2dfbaaa5404cadf70213146a5b4b89b647d9092 Mon Sep 17 00:00:00 2001 +From: Richard Fitzgerald +Date: Tue, 16 Nov 2021 16:38:59 +0000 +Subject: [PATCH] ASoC: cs42l42: Remove redundant writes to RS_PLUG/RS_UNPLUG masks +Git-commit: f2dfbaaa5404cadf70213146a5b4b89b647d9092 +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +The RS_PLUG and RS_UNPLUG interrupt masks are always written as 1 so +those writes are redundant and can be deleted. + +This makes it completely clear in the code that only the TS_PLUG and +TS_UNPLUG masks are being changed. + +Signed-off-by: Richard Fitzgerald +Link: https://lore.kernel.org/r/20211116163901.45390-3-rf@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs42l42.c | 8 -------- + 1 file changed, 8 deletions(-) + +diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c +index 92bdc3a355ff..3674f73301dc 100644 +--- a/sound/soc/codecs/cs42l42.c ++++ b/sound/soc/codecs/cs42l42.c +@@ -1320,12 +1320,8 @@ static void cs42l42_process_hs_type_detect(struct cs42l42_private *cs42l42) + /* Unmask tip sense interrupts */ + regmap_update_bits(cs42l42->regmap, + CS42L42_TSRS_PLUG_INT_MASK, +- CS42L42_RS_PLUG_MASK | +- CS42L42_RS_UNPLUG_MASK | + CS42L42_TS_PLUG_MASK | + CS42L42_TS_UNPLUG_MASK, +- (1 << CS42L42_RS_PLUG_SHIFT) | +- (1 << CS42L42_RS_UNPLUG_SHIFT) | + (0 << CS42L42_TS_PLUG_SHIFT) | + (0 << CS42L42_TS_UNPLUG_SHIFT)); + } +@@ -1335,12 +1331,8 @@ static void cs42l42_init_hs_type_detect(struct cs42l42_private *cs42l42) + /* Mask tip sense interrupts */ + regmap_update_bits(cs42l42->regmap, + CS42L42_TSRS_PLUG_INT_MASK, +- CS42L42_RS_PLUG_MASK | +- CS42L42_RS_UNPLUG_MASK | + CS42L42_TS_PLUG_MASK | + CS42L42_TS_UNPLUG_MASK, +- (1 << CS42L42_RS_PLUG_SHIFT) | +- (1 << CS42L42_RS_UNPLUG_SHIFT) | + (1 << CS42L42_TS_PLUG_SHIFT) | + (1 << CS42L42_TS_UNPLUG_SHIFT)); + +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs42l42-Remove-unused-runtime_suspend-runtime_r.patch b/patches.suse/ASoC-cs42l42-Remove-unused-runtime_suspend-runtime_r.patch new file mode 100644 index 0000000..75409d7 --- /dev/null +++ b/patches.suse/ASoC-cs42l42-Remove-unused-runtime_suspend-runtime_r.patch @@ -0,0 +1,108 @@ +From c778c01d3e665045d29d548d946f7cd64aec0ff9 Mon Sep 17 00:00:00 2001 +From: Richard Fitzgerald +Date: Mon, 18 Oct 2021 17:44:31 +0100 +Subject: [PATCH] ASoC: cs42l42: Remove unused runtime_suspend/runtime_resume callbacks +Git-commit: c778c01d3e665045d29d548d946f7cd64aec0ff9 +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +The driver has runtime_suspend and runtime_resume callbacks, but +pm_runtime is never enabled so these functions won't be called. They +could not be used anyway because the runtime_suspend would cause jack +detect to stop working. + +These functions are unused - delete them. + +Signed-off-by: Richard Fitzgerald +Link: https://lore.kernel.org/r/20211018164431.5871-1-rf@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs42l42.c | 51 +------------------------------------- + 1 file changed, 1 insertion(+), 50 deletions(-) + +diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c +index 5e4d6791756b..0dbe4e23194b 100644 +--- a/sound/soc/codecs/cs42l42.c ++++ b/sound/soc/codecs/cs42l42.c +@@ -25,7 +25,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -2175,59 +2174,12 @@ static int cs42l42_i2c_remove(struct i2c_client *i2c_client) + if (i2c_client->irq) + devm_free_irq(&i2c_client->dev, i2c_client->irq, cs42l42); + +- pm_runtime_suspend(&i2c_client->dev); +- pm_runtime_disable(&i2c_client->dev); +- +- return 0; +-} +- +-#ifdef CONFIG_PM +-static int cs42l42_runtime_suspend(struct device *dev) +-{ +- struct cs42l42_private *cs42l42 = dev_get_drvdata(dev); +- +- regcache_cache_only(cs42l42->regmap, true); +- regcache_mark_dirty(cs42l42->regmap); +- +- /* Hold down reset */ + gpiod_set_value_cansleep(cs42l42->reset_gpio, 0); +- +- /* remove power */ +- regulator_bulk_disable(ARRAY_SIZE(cs42l42->supplies), +- cs42l42->supplies); ++ regulator_bulk_disable(ARRAY_SIZE(cs42l42->supplies), cs42l42->supplies); + + return 0; + } + +-static int cs42l42_runtime_resume(struct device *dev) +-{ +- struct cs42l42_private *cs42l42 = dev_get_drvdata(dev); +- int ret; +- +- /* Enable power */ +- ret = regulator_bulk_enable(ARRAY_SIZE(cs42l42->supplies), +- cs42l42->supplies); +- if (ret != 0) { +- dev_err(dev, "Failed to enable supplies: %d\n", +- ret); +- return ret; +- } +- +- gpiod_set_value_cansleep(cs42l42->reset_gpio, 1); +- usleep_range(CS42L42_BOOT_TIME_US, CS42L42_BOOT_TIME_US * 2); +- +- regcache_cache_only(cs42l42->regmap, false); +- regcache_sync(cs42l42->regmap); +- +- return 0; +-} +-#endif +- +-static const struct dev_pm_ops cs42l42_runtime_pm = { +- SET_RUNTIME_PM_OPS(cs42l42_runtime_suspend, cs42l42_runtime_resume, +- NULL) +-}; +- + #ifdef CONFIG_OF + static const struct of_device_id cs42l42_of_match[] = { + { .compatible = "cirrus,cs42l42", }, +@@ -2254,7 +2206,6 @@ MODULE_DEVICE_TABLE(i2c, cs42l42_id); + static struct i2c_driver cs42l42_i2c_driver = { + .driver = { + .name = "cs42l42", +- .pm = &cs42l42_runtime_pm, + .of_match_table = of_match_ptr(cs42l42_of_match), + .acpi_match_table = ACPI_PTR(cs42l42_acpi_match), + }, +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs42l42-Report-full-jack-status-when-plug-is-de.patch b/patches.suse/ASoC-cs42l42-Report-full-jack-status-when-plug-is-de.patch new file mode 100644 index 0000000..8460aca --- /dev/null +++ b/patches.suse/ASoC-cs42l42-Report-full-jack-status-when-plug-is-de.patch @@ -0,0 +1,67 @@ +From 8d06f797f844d04a961f201f886f7f9985edc9bf Mon Sep 17 00:00:00 2001 +From: Richard Fitzgerald +Date: Fri, 21 Jan 2022 12:04:10 +0000 +Subject: [PATCH] ASoC: cs42l42: Report full jack status when plug is detected +Git-commit: 8d06f797f844d04a961f201f886f7f9985edc9bf +Patch-mainline: v5.18-rc1 +References: bsc#1203699 + +When a plug event is detect report the full state of all status +bits, don't assume that there will have been a previous unplug +event to clear all the bits. Report the state of both HEADPHONE +and MICROPHONE bits according to detected type, and clear all the +button status bits. The current button status is already checked +and reported at the end of the function. + +During a system suspend the jack could be unplugged and plugged, +possibly changing the jack type. On resume the interrupt status will +indicate a plug event - there will not be an unplug event to clear +the bits. + +Signed-off-by: Richard Fitzgerald +Link: https://lore.kernel.org/r/20220121120412.672284-2-rf@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs42l42.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c +index 43d98bdb5b5b..2c294868008e 100644 +--- a/sound/soc/codecs/cs42l42.c ++++ b/sound/soc/codecs/cs42l42.c +@@ -1637,7 +1637,11 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data) + + mutex_lock(&cs42l42->jack_detect_mutex); + +- /* Check auto-detect status */ ++ /* ++ * Check auto-detect status. Don't assume a previous unplug event has ++ * cleared the flags. If the jack is unplugged and plugged during ++ * system suspend there won't have been an unplug event. ++ */ + if ((~masks[5]) & irq_params_table[5].mask) { + if (stickies[5] & CS42L42_HSDET_AUTO_DONE_MASK) { + cs42l42_process_hs_type_detect(cs42l42); +@@ -1645,11 +1649,15 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data) + case CS42L42_PLUG_CTIA: + case CS42L42_PLUG_OMTP: + snd_soc_jack_report(cs42l42->jack, SND_JACK_HEADSET, +- SND_JACK_HEADSET); ++ SND_JACK_HEADSET | ++ SND_JACK_BTN_0 | SND_JACK_BTN_1 | ++ SND_JACK_BTN_2 | SND_JACK_BTN_3); + break; + case CS42L42_PLUG_HEADPHONE: + snd_soc_jack_report(cs42l42->jack, SND_JACK_HEADPHONE, +- SND_JACK_HEADPHONE); ++ SND_JACK_HEADSET | ++ SND_JACK_BTN_0 | SND_JACK_BTN_1 | ++ SND_JACK_BTN_2 | SND_JACK_BTN_3); + break; + default: + break; +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs42l42-Report-initial-jack-state.patch b/patches.suse/ASoC-cs42l42-Report-initial-jack-state.patch new file mode 100644 index 0000000..4282f88 --- /dev/null +++ b/patches.suse/ASoC-cs42l42-Report-initial-jack-state.patch @@ -0,0 +1,109 @@ +From fdd535283779ec9f9c35fda352585c629121214f Mon Sep 17 00:00:00 2001 +From: Richard Fitzgerald +Date: Fri, 19 Nov 2021 12:48:54 +0000 +Subject: [PATCH] ASoC: cs42l42: Report initial jack state +Git-commit: fdd535283779ec9f9c35fda352585c629121214f +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +When a jack handler is registered in cs42l42_set_jack() the +initial state should be reported if an attached headphone/headset +has already been detected. + +The jack detect sequence takes around 1 second: typically long +enough for the machine driver to probe and register the jack handler +in time to receive the first report from the interrupt handler. So +it is possible on some systems that the correct initial state was seen +simply because of lucky timing. Modular builds were more likely to +miss the reporting of the initial state. + +Signed-off-by: Richard Fitzgerald +Fixes: 4ca239f33737 ("ASoC: cs42l42: Always enable TS_PLUG and TS_UNPLUG interrupts") +Link: https://lore.kernel.org/r/20211119124854.58939-1-rf@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs42l42.c | 22 ++++++++++++++++++++++ + sound/soc/codecs/cs42l42.h | 2 ++ + 2 files changed, 24 insertions(+) + +diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c +index 0c4303547fd8..43d98bdb5b5b 100644 +--- a/sound/soc/codecs/cs42l42.c ++++ b/sound/soc/codecs/cs42l42.c +@@ -549,8 +549,25 @@ static int cs42l42_set_jack(struct snd_soc_component *component, struct snd_soc_ + { + struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component); + ++ /* Prevent race with interrupt handler */ ++ mutex_lock(&cs42l42->jack_detect_mutex); + cs42l42->jack = jk; + ++ if (jk) { ++ switch (cs42l42->hs_type) { ++ case CS42L42_PLUG_CTIA: ++ case CS42L42_PLUG_OMTP: ++ snd_soc_jack_report(jk, SND_JACK_HEADSET, SND_JACK_HEADSET); ++ break; ++ case CS42L42_PLUG_HEADPHONE: ++ snd_soc_jack_report(jk, SND_JACK_HEADPHONE, SND_JACK_HEADPHONE); ++ break; ++ default: ++ break; ++ } ++ } ++ mutex_unlock(&cs42l42->jack_detect_mutex); ++ + return 0; + } + +@@ -1618,6 +1635,8 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data) + CS42L42_M_DETECT_FT_MASK | + CS42L42_M_HSBIAS_HIZ_MASK); + ++ mutex_lock(&cs42l42->jack_detect_mutex); ++ + /* Check auto-detect status */ + if ((~masks[5]) & irq_params_table[5].mask) { + if (stickies[5] & CS42L42_HSDET_AUTO_DONE_MASK) { +@@ -1686,6 +1705,8 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data) + } + } + ++ mutex_unlock(&cs42l42->jack_detect_mutex); ++ + return IRQ_HANDLED; + } + +@@ -2033,6 +2054,7 @@ static int cs42l42_i2c_probe(struct i2c_client *i2c_client, + + cs42l42->dev = &i2c_client->dev; + i2c_set_clientdata(i2c_client, cs42l42); ++ mutex_init(&cs42l42->jack_detect_mutex); + + cs42l42->regmap = devm_regmap_init_i2c(i2c_client, &cs42l42_regmap); + if (IS_ERR(cs42l42->regmap)) { +diff --git a/sound/soc/codecs/cs42l42.h b/sound/soc/codecs/cs42l42.h +index 75ade987d0db..9fff183dce8e 100644 +--- a/sound/soc/codecs/cs42l42.h ++++ b/sound/soc/codecs/cs42l42.h +@@ -12,6 +12,7 @@ + #ifndef __CS42L42_H__ + #define __CS42L42_H__ + ++#include + #include + + #define CS42L42_PAGE_REGISTER 0x00 /* Page Select Register */ +@@ -841,6 +842,7 @@ struct cs42l42_private { + struct gpio_desc *reset_gpio; + struct completion pdn_done; + struct snd_soc_jack *jack; ++ struct mutex jack_detect_mutex; + int pll_config; + int bclk; + u32 sclk; +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs42l42-Reset-and-power-down-on-remove-and-fail.patch b/patches.suse/ASoC-cs42l42-Reset-and-power-down-on-remove-and-fail.patch new file mode 100644 index 0000000..93627e7 --- /dev/null +++ b/patches.suse/ASoC-cs42l42-Reset-and-power-down-on-remove-and-fail.patch @@ -0,0 +1,91 @@ +From 6cb725b8a5cc7b9106d5d6dd5d2ca78c76913775 Mon Sep 17 00:00:00 2001 +From: Richard Fitzgerald +Date: Tue, 26 Oct 2021 13:57:21 +0100 +Subject: [PATCH] ASoC: cs42l42: Reset and power-down on remove() and failed probe() +Git-commit: 6cb725b8a5cc7b9106d5d6dd5d2ca78c76913775 +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +Driver remove() should assert RESET and disable the supplies. + +probe() fail was disabling supplies but it didn't assert reset or +put the codec into a power-down state. + +Signed-off-by: Richard Fitzgerald +Link: https://lore.kernel.org/r/20211026125722.10220-2-rf@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs42l42.c | 24 ++++++++++++++++++++---- + 1 file changed, 20 insertions(+), 4 deletions(-) + +diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c +index a8fff274ec63..dc12842ee6e1 100644 +--- a/sound/soc/codecs/cs42l42.c ++++ b/sound/soc/codecs/cs42l42.c +@@ -2067,7 +2067,7 @@ static int cs42l42_i2c_probe(struct i2c_client *i2c_client, + "reset", GPIOD_OUT_LOW); + if (IS_ERR(cs42l42->reset_gpio)) { + ret = PTR_ERR(cs42l42->reset_gpio); +- goto err_disable; ++ goto err_disable_noreset; + } + + if (cs42l42->reset_gpio) { +@@ -2111,7 +2111,7 @@ static int cs42l42_i2c_probe(struct i2c_client *i2c_client, + ret = regmap_read(cs42l42->regmap, CS42L42_REVID, ®); + if (ret < 0) { + dev_err(&i2c_client->dev, "Get Revision ID failed\n"); +- goto err_disable; ++ goto err_shutdown; + } + + dev_info(&i2c_client->dev, +@@ -2136,7 +2136,7 @@ static int cs42l42_i2c_probe(struct i2c_client *i2c_client, + + ret = cs42l42_handle_device_data(&i2c_client->dev, cs42l42); + if (ret != 0) +- goto err_disable; ++ goto err_shutdown; + + /* Setup headset detection */ + cs42l42_setup_hs_type_detect(cs42l42); +@@ -2148,10 +2148,18 @@ static int cs42l42_i2c_probe(struct i2c_client *i2c_client, + ret = devm_snd_soc_register_component(&i2c_client->dev, + &soc_component_dev_cs42l42, &cs42l42_dai, 1); + if (ret < 0) +- goto err_disable; ++ goto err_shutdown; ++ + return 0; + ++err_shutdown: ++ regmap_write(cs42l42->regmap, CS42L42_CODEC_INT_MASK, 0xff); ++ regmap_write(cs42l42->regmap, CS42L42_TSRS_PLUG_INT_MASK, 0xff); ++ regmap_write(cs42l42->regmap, CS42L42_PWR_CTL1, 0xff); ++ + err_disable: ++ gpiod_set_value_cansleep(cs42l42->reset_gpio, 0); ++err_disable_noreset: + regulator_bulk_disable(ARRAY_SIZE(cs42l42->supplies), + cs42l42->supplies); + return ret; +@@ -2164,6 +2172,14 @@ static int cs42l42_i2c_remove(struct i2c_client *i2c_client) + if (i2c_client->irq) + devm_free_irq(&i2c_client->dev, i2c_client->irq, cs42l42); + ++ /* ++ * The driver might not have control of reset and power supplies, ++ * so ensure that the chip internals are powered down. ++ */ ++ regmap_write(cs42l42->regmap, CS42L42_CODEC_INT_MASK, 0xff); ++ regmap_write(cs42l42->regmap, CS42L42_TSRS_PLUG_INT_MASK, 0xff); ++ regmap_write(cs42l42->regmap, CS42L42_PWR_CTL1, 0xff); ++ + gpiod_set_value_cansleep(cs42l42->reset_gpio, 0); + regulator_bulk_disable(ARRAY_SIZE(cs42l42->supplies), cs42l42->supplies); + +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs42l42-Set-correct-SRC-MCLK.patch b/patches.suse/ASoC-cs42l42-Set-correct-SRC-MCLK.patch new file mode 100644 index 0000000..4d3ff30 --- /dev/null +++ b/patches.suse/ASoC-cs42l42-Set-correct-SRC-MCLK.patch @@ -0,0 +1,127 @@ +From fdbd256175a1e11c1ba827112d56b9a3952e1219 Mon Sep 17 00:00:00 2001 +From: Richard Fitzgerald +Date: Fri, 15 Oct 2021 14:36:16 +0100 +Subject: [PATCH] ASoC: cs42l42: Set correct SRC MCLK +Git-commit: fdbd256175a1e11c1ba827112d56b9a3952e1219 +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +According to the datasheet the SRC MCLK must be as near as possible to +(125 * sample rate). This means it should be ~6MHz for rates up to 48k +and ~12MHz for rates above that. As per datasheet table 4-21. + +Signed-off-by: Richard Fitzgerald +Link: https://lore.kernel.org/r/20211015133619.4698-14-rf@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs42l42.c | 58 +++++++++++++++++++++++++++----------- + sound/soc/codecs/cs42l42.h | 1 + + 2 files changed, 42 insertions(+), 17 deletions(-) + +diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c +index d6d74a7bbde9..d62272d0ab8c 100644 +--- a/sound/soc/codecs/cs42l42.c ++++ b/sound/soc/codecs/cs42l42.c +@@ -678,22 +678,6 @@ static int cs42l42_pll_config(struct snd_soc_component *component) + CS42L42_FSYNC_PULSE_WIDTH_MASK, + CS42L42_FRAC1_VAL(fsync - 1) << + CS42L42_FSYNC_PULSE_WIDTH_SHIFT); +- /* Set the sample rates (96k or lower) */ +- snd_soc_component_update_bits(component, CS42L42_FS_RATE_EN, +- CS42L42_FS_EN_MASK, +- (CS42L42_FS_EN_IASRC_96K | +- CS42L42_FS_EN_OASRC_96K) << +- CS42L42_FS_EN_SHIFT); +- /* Set the input/output internal MCLK clock ~12 MHz */ +- snd_soc_component_update_bits(component, CS42L42_IN_ASRC_CLK, +- CS42L42_CLK_IASRC_SEL_MASK, +- CS42L42_CLK_IASRC_SEL_12 << +- CS42L42_CLK_IASRC_SEL_SHIFT); +- snd_soc_component_update_bits(component, +- CS42L42_OUT_ASRC_CLK, +- CS42L42_CLK_OASRC_SEL_MASK, +- CS42L42_CLK_OASRC_SEL_12 << +- CS42L42_CLK_OASRC_SEL_SHIFT); + if (pll_ratio_table[i].mclk_src_sel == 0) { + /* Pass the clock straight through */ + snd_soc_component_update_bits(component, +@@ -756,6 +740,39 @@ static int cs42l42_pll_config(struct snd_soc_component *component) + return -EINVAL; + } + ++static void cs42l42_src_config(struct snd_soc_component *component, unsigned int sample_rate) ++{ ++ struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component); ++ unsigned int fs; ++ ++ /* Don't reconfigure if there is an audio stream running */ ++ if (cs42l42->stream_use) ++ return; ++ ++ /* SRC MCLK must be as close as possible to 125 * sample rate */ ++ if (sample_rate <= 48000) ++ fs = CS42L42_CLK_IASRC_SEL_6; ++ else ++ fs = CS42L42_CLK_IASRC_SEL_12; ++ ++ /* Set the sample rates (96k or lower) */ ++ snd_soc_component_update_bits(component, ++ CS42L42_FS_RATE_EN, ++ CS42L42_FS_EN_MASK, ++ (CS42L42_FS_EN_IASRC_96K | ++ CS42L42_FS_EN_OASRC_96K) << ++ CS42L42_FS_EN_SHIFT); ++ ++ snd_soc_component_update_bits(component, ++ CS42L42_IN_ASRC_CLK, ++ CS42L42_CLK_IASRC_SEL_MASK, ++ fs << CS42L42_CLK_IASRC_SEL_SHIFT); ++ snd_soc_component_update_bits(component, ++ CS42L42_OUT_ASRC_CLK, ++ CS42L42_CLK_OASRC_SEL_MASK, ++ fs << CS42L42_CLK_OASRC_SEL_SHIFT); ++} ++ + static int cs42l42_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) + { + struct snd_soc_component *component = codec_dai->component; +@@ -846,6 +863,7 @@ static int cs42l42_pcm_hw_params(struct snd_pcm_substream *substream, + unsigned int channels = params_channels(params); + unsigned int width = (params_width(params) / 8) - 1; + unsigned int val = 0; ++ int ret; + + cs42l42->srate = params_rate(params); + cs42l42->bclk = snd_soc_params_to_bclk(params); +@@ -899,7 +917,13 @@ static int cs42l42_pcm_hw_params(struct snd_pcm_substream *substream, + break; + } + +- return cs42l42_pll_config(component); ++ ret = cs42l42_pll_config(component); ++ if (ret) ++ return ret; ++ ++ cs42l42_src_config(component, params_rate(params)); ++ ++ return 0; + } + + static int cs42l42_set_sysclk(struct snd_soc_dai *dai, +diff --git a/sound/soc/codecs/cs42l42.h b/sound/soc/codecs/cs42l42.h +index ded61af6ea8b..d13749e9d8c5 100644 +--- a/sound/soc/codecs/cs42l42.h ++++ b/sound/soc/codecs/cs42l42.h +@@ -288,6 +288,7 @@ + #define CS42L42_IN_ASRC_CLK (CS42L42_PAGE_12 + 0x0A) + #define CS42L42_CLK_IASRC_SEL_SHIFT 0 + #define CS42L42_CLK_IASRC_SEL_MASK (1 << CS42L42_CLK_IASRC_SEL_SHIFT) ++#define CS42L42_CLK_IASRC_SEL_6 0 + #define CS42L42_CLK_IASRC_SEL_12 1 + + #define CS42L42_OUT_ASRC_CLK (CS42L42_PAGE_12 + 0x0B) +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs42l42-Simplify-reporting-of-jack-unplug.patch b/patches.suse/ASoC-cs42l42-Simplify-reporting-of-jack-unplug.patch new file mode 100644 index 0000000..e3c64af --- /dev/null +++ b/patches.suse/ASoC-cs42l42-Simplify-reporting-of-jack-unplug.patch @@ -0,0 +1,53 @@ +From 3edde6de090617adea18f2068489086c0d8087e3 Mon Sep 17 00:00:00 2001 +From: Richard Fitzgerald +Date: Tue, 16 Nov 2021 16:39:00 +0000 +Subject: [PATCH] ASoC: cs42l42: Simplify reporting of jack unplug +Git-commit: 3edde6de090617adea18f2068489086c0d8087e3 +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +When reporting a jack unplug there's no need to make the reported +flags conditional on which flags were reported during the plug +event. It's perfectly safe to report all flags and buttons as +not-present and let the higher code filter for changes. + +There's also no need to make two separate snd_soc_jack_report() +calls for presence flags and button flags. It can all be done in +one report. + +Signed-off-by: Richard Fitzgerald +Link: https://lore.kernel.org/r/20211116163901.45390-4-rf@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs42l42.c | 12 +----------- + 1 file changed, 1 insertion(+), 11 deletions(-) + +diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c +index 3674f73301dc..8efcee3e60d3 100644 +--- a/sound/soc/codecs/cs42l42.c ++++ b/sound/soc/codecs/cs42l42.c +@@ -1657,18 +1657,8 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data) + cs42l42->plug_state = CS42L42_TS_UNPLUG; + cs42l42_cancel_hs_type_detect(cs42l42); + +- switch (cs42l42->hs_type) { +- case CS42L42_PLUG_CTIA: +- case CS42L42_PLUG_OMTP: +- snd_soc_jack_report(cs42l42->jack, 0, SND_JACK_HEADSET); +- break; +- case CS42L42_PLUG_HEADPHONE: +- snd_soc_jack_report(cs42l42->jack, 0, SND_JACK_HEADPHONE); +- break; +- default: +- break; +- } + snd_soc_jack_report(cs42l42->jack, 0, ++ SND_JACK_HEADSET | + SND_JACK_BTN_0 | SND_JACK_BTN_1 | + SND_JACK_BTN_2 | SND_JACK_BTN_3); + +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs42l42-Use-PLL-for-SCLK-12.288MHz.patch b/patches.suse/ASoC-cs42l42-Use-PLL-for-SCLK-12.288MHz.patch new file mode 100644 index 0000000..f83aac5 --- /dev/null +++ b/patches.suse/ASoC-cs42l42-Use-PLL-for-SCLK-12.288MHz.patch @@ -0,0 +1,96 @@ +From 3c211cb7db2905221f9f006aa66b8af17bfcd480 Mon Sep 17 00:00:00 2001 +From: Richard Fitzgerald +Date: Fri, 15 Oct 2021 14:36:14 +0100 +Subject: [PATCH] ASoC: cs42l42: Use PLL for SCLK > 12.288MHz +Git-commit: 3c211cb7db2905221f9f006aa66b8af17bfcd480 +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +It isn't possible to switch MCLK between 12MHz and 24MHz rate groups +on-the-fly - this can only be done when cs42l42 is powered-down. + +All "normal" SCLK rates use an MCLK in the 12MHz group, so change the +configs for SCLK > 12.288 MHz to use the PLL to generate an MCLK in +the 12MHz group. + +As this means MCLK_DIV is always 0 it can be removed from the pll +configuration setup. + +Signed-off-by: Richard Fitzgerald +Link: https://lore.kernel.org/r/20211015133619.4698-12-rf@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs42l42.c | 41 +++++++++++++++++--------------------- + 1 file changed, 18 insertions(+), 23 deletions(-) + +diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c +index 71390c20e7a1..4ec7fdcedca7 100644 +--- a/sound/soc/codecs/cs42l42.c ++++ b/sound/soc/codecs/cs42l42.c +@@ -549,7 +549,6 @@ static const struct reg_sequence cs42l42_to_osc_seq[] = { + + struct cs42l42_pll_params { + u32 sclk; +- u8 mclk_div; + u8 mclk_src_sel; + u8 sclk_prediv; + u8 pll_div_int; +@@ -566,24 +565,24 @@ struct cs42l42_pll_params { + * Table 4-5 from the Datasheet + */ + static const struct cs42l42_pll_params pll_ratio_table[] = { +- { 1411200, 0, 1, 0x00, 0x80, 0x000000, 0x03, 0x10, 11289600, 128, 2}, +- { 1536000, 0, 1, 0x00, 0x7D, 0x000000, 0x03, 0x10, 12000000, 125, 2}, +- { 2304000, 0, 1, 0x00, 0x55, 0xC00000, 0x02, 0x10, 12288000, 85, 2}, +- { 2400000, 0, 1, 0x00, 0x50, 0x000000, 0x03, 0x10, 12000000, 80, 2}, +- { 2822400, 0, 1, 0x00, 0x40, 0x000000, 0x03, 0x10, 11289600, 128, 1}, +- { 3000000, 0, 1, 0x00, 0x40, 0x000000, 0x03, 0x10, 12000000, 128, 1}, +- { 3072000, 0, 1, 0x00, 0x3E, 0x800000, 0x03, 0x10, 12000000, 125, 1}, +- { 4000000, 0, 1, 0x00, 0x30, 0x800000, 0x03, 0x10, 12000000, 96, 1}, +- { 4096000, 0, 1, 0x00, 0x2E, 0xE00000, 0x03, 0x10, 12000000, 94, 1}, +- { 5644800, 0, 1, 0x01, 0x40, 0x000000, 0x03, 0x10, 11289600, 128, 1}, +- { 6000000, 0, 1, 0x01, 0x40, 0x000000, 0x03, 0x10, 12000000, 128, 1}, +- { 6144000, 0, 1, 0x01, 0x3E, 0x800000, 0x03, 0x10, 12000000, 125, 1}, +- { 11289600, 0, 0, 0, 0, 0, 0, 0, 11289600, 0, 1}, +- { 12000000, 0, 0, 0, 0, 0, 0, 0, 12000000, 0, 1}, +- { 12288000, 0, 0, 0, 0, 0, 0, 0, 12288000, 0, 1}, +- { 22579200, 1, 0, 0, 0, 0, 0, 0, 22579200, 0, 1}, +- { 24000000, 1, 0, 0, 0, 0, 0, 0, 24000000, 0, 1}, +- { 24576000, 1, 0, 0, 0, 0, 0, 0, 24576000, 0, 1} ++ { 1411200, 1, 0x00, 0x80, 0x000000, 0x03, 0x10, 11289600, 128, 2}, ++ { 1536000, 1, 0x00, 0x7D, 0x000000, 0x03, 0x10, 12000000, 125, 2}, ++ { 2304000, 1, 0x00, 0x55, 0xC00000, 0x02, 0x10, 12288000, 85, 2}, ++ { 2400000, 1, 0x00, 0x50, 0x000000, 0x03, 0x10, 12000000, 80, 2}, ++ { 2822400, 1, 0x00, 0x40, 0x000000, 0x03, 0x10, 11289600, 128, 1}, ++ { 3000000, 1, 0x00, 0x40, 0x000000, 0x03, 0x10, 12000000, 128, 1}, ++ { 3072000, 1, 0x00, 0x3E, 0x800000, 0x03, 0x10, 12000000, 125, 1}, ++ { 4000000, 1, 0x00, 0x30, 0x800000, 0x03, 0x10, 12000000, 96, 1}, ++ { 4096000, 1, 0x00, 0x2E, 0xE00000, 0x03, 0x10, 12000000, 94, 1}, ++ { 5644800, 1, 0x01, 0x40, 0x000000, 0x03, 0x10, 11289600, 128, 1}, ++ { 6000000, 1, 0x01, 0x40, 0x000000, 0x03, 0x10, 12000000, 128, 1}, ++ { 6144000, 1, 0x01, 0x3E, 0x800000, 0x03, 0x10, 12000000, 125, 1}, ++ { 11289600, 0, 0, 0, 0, 0, 0, 11289600, 0, 1}, ++ { 12000000, 0, 0, 0, 0, 0, 0, 12000000, 0, 1}, ++ { 12288000, 0, 0, 0, 0, 0, 0, 12288000, 0, 1}, ++ { 22579200, 1, 0x03, 0x40, 0x000000, 0x03, 0x10, 11289600, 128, 1}, ++ { 24000000, 1, 0x03, 0x40, 0x000000, 0x03, 0x10, 12000000, 128, 1}, ++ { 24576000, 1, 0x03, 0x40, 0x000000, 0x03, 0x10, 12288000, 128, 1} + }; + + static int cs42l42_pll_config(struct snd_soc_component *component) +@@ -619,10 +618,6 @@ static int cs42l42_pll_config(struct snd_soc_component *component) + 24000000)) << + CS42L42_INTERNAL_FS_SHIFT); + +- snd_soc_component_update_bits(component, CS42L42_MCLK_SRC_SEL, +- CS42L42_MCLKDIV_MASK, +- (pll_ratio_table[i].mclk_div << +- CS42L42_MCLKDIV_SHIFT)); + /* Set up the LRCLK */ + fsync = clk / cs42l42->srate; + if (((fsync * cs42l42->srate) != clk) +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs42l42-Use-two-thresholds-and-increased-wait-t.patch b/patches.suse/ASoC-cs42l42-Use-two-thresholds-and-increased-wait-t.patch new file mode 100644 index 0000000..c7ede8d --- /dev/null +++ b/patches.suse/ASoC-cs42l42-Use-two-thresholds-and-increased-wait-t.patch @@ -0,0 +1,189 @@ +From edd6dffdc6670836909972b32a324dbf6c150757 Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Mon, 27 Sep 2021 12:14:37 +0100 +Subject: [PATCH] ASoC: cs42l42: Use two thresholds and increased wait time for manual type detection +Git-commit: edd6dffdc6670836909972b32a324dbf6c150757 +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +Some headsets require very different comparator thresholds for type detection, +as well as longer settling times. In order to detect a larger number of headsets, +use 2 thresholds to give maximum coverage (1.25V and 1.75V), as well as a longer +settling time of 100ms. This will not affect default audotodetect mode +and applies to manual mode type detection only. + +Signed-off-by: Stefan Binding +Signed-off-by: Vitaly Rodionov +Link: https://lore.kernel.org/r/20210927111437.18113-1-vitalyr@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs42l42.c | 84 +++++++++++++++++++++++++++----------- + sound/soc/codecs/cs42l42.h | 5 +++ + 2 files changed, 66 insertions(+), 23 deletions(-) + +diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c +index d5e1e5228b5f..d484ec09eb2e 100644 +--- a/sound/soc/codecs/cs42l42.c ++++ b/sound/soc/codecs/cs42l42.c +@@ -1049,7 +1049,8 @@ static struct snd_soc_dai_driver cs42l42_dai = { + static void cs42l42_manual_hs_type_detect(struct cs42l42_private *cs42l42) + { + unsigned int hs_det_status; +- unsigned int hs_det_comp; ++ unsigned int hs_det_comp1; ++ unsigned int hs_det_comp2; + unsigned int hs_det_sw; + + /* Set hs detect to manual, active mode */ +@@ -1064,23 +1065,40 @@ static void cs42l42_manual_hs_type_detect(struct cs42l42_private *cs42l42) + (0 << CS42L42_HSBIAS_REF_SHIFT) | + (0 << CS42L42_HSDET_AUTO_TIME_SHIFT)); + ++ /* Configure HS DET comparator reference levels. */ ++ regmap_update_bits(cs42l42->regmap, ++ CS42L42_HSDET_CTL1, ++ CS42L42_HSDET_COMP1_LVL_MASK | ++ CS42L42_HSDET_COMP2_LVL_MASK, ++ (CS42L42_HSDET_COMP1_LVL_VAL << CS42L42_HSDET_COMP1_LVL_SHIFT) | ++ (CS42L42_HSDET_COMP2_LVL_VAL << CS42L42_HSDET_COMP2_LVL_SHIFT)); ++ + /* Open the SW_HSB_HS3 switch and close SW_HSB_HS4 for a Type 1 headset. */ + regmap_write(cs42l42->regmap, CS42L42_HS_SWITCH_CTL, CS42L42_HSDET_SW_COMP1); + ++ msleep(100); ++ + regmap_read(cs42l42->regmap, CS42L42_HS_DET_STATUS, &hs_det_status); + +- hs_det_comp = (hs_det_status & CS42L42_HSDET_COMP1_OUT_MASK) >> ++ hs_det_comp1 = (hs_det_status & CS42L42_HSDET_COMP1_OUT_MASK) >> + CS42L42_HSDET_COMP1_OUT_SHIFT; ++ hs_det_comp2 = (hs_det_status & CS42L42_HSDET_COMP2_OUT_MASK) >> ++ CS42L42_HSDET_COMP2_OUT_SHIFT; + + /* Close the SW_HSB_HS3 switch for a Type 2 headset. */ + regmap_write(cs42l42->regmap, CS42L42_HS_SWITCH_CTL, CS42L42_HSDET_SW_COMP2); + ++ msleep(100); ++ + regmap_read(cs42l42->regmap, CS42L42_HS_DET_STATUS, &hs_det_status); + +- hs_det_comp |= ((hs_det_status & CS42L42_HSDET_COMP2_OUT_MASK) >> ++ hs_det_comp1 |= ((hs_det_status & CS42L42_HSDET_COMP1_OUT_MASK) >> ++ CS42L42_HSDET_COMP1_OUT_SHIFT) << 1; ++ hs_det_comp2 |= ((hs_det_status & CS42L42_HSDET_COMP2_OUT_MASK) >> + CS42L42_HSDET_COMP2_OUT_SHIFT) << 1; + +- switch (hs_det_comp) { ++ /* Use Comparator 1 with 1.25V Threshold. */ ++ switch (hs_det_comp1) { + case CS42L42_HSDET_COMP_TYPE1: + cs42l42->hs_type = CS42L42_PLUG_CTIA; + hs_det_sw = CS42L42_HSDET_SW_TYPE1; +@@ -1089,14 +1107,26 @@ static void cs42l42_manual_hs_type_detect(struct cs42l42_private *cs42l42) + cs42l42->hs_type = CS42L42_PLUG_OMTP; + hs_det_sw = CS42L42_HSDET_SW_TYPE2; + break; +- case CS42L42_HSDET_COMP_TYPE3: +- cs42l42->hs_type = CS42L42_PLUG_HEADPHONE; +- hs_det_sw = CS42L42_HSDET_SW_TYPE3; +- break; + default: +- cs42l42->hs_type = CS42L42_PLUG_INVALID; +- hs_det_sw = CS42L42_HSDET_SW_TYPE4; +- break; ++ /* Fallback to Comparator 2 with 1.75V Threshold. */ ++ switch (hs_det_comp2) { ++ case CS42L42_HSDET_COMP_TYPE1: ++ cs42l42->hs_type = CS42L42_PLUG_CTIA; ++ hs_det_sw = CS42L42_HSDET_SW_TYPE1; ++ break; ++ case CS42L42_HSDET_COMP_TYPE2: ++ cs42l42->hs_type = CS42L42_PLUG_OMTP; ++ hs_det_sw = CS42L42_HSDET_SW_TYPE2; ++ break; ++ case CS42L42_HSDET_COMP_TYPE3: ++ cs42l42->hs_type = CS42L42_PLUG_HEADPHONE; ++ hs_det_sw = CS42L42_HSDET_SW_TYPE3; ++ break; ++ default: ++ cs42l42->hs_type = CS42L42_PLUG_INVALID; ++ hs_det_sw = CS42L42_HSDET_SW_TYPE4; ++ break; ++ } + } + + /* Set Switches */ +@@ -1113,6 +1143,14 @@ static void cs42l42_manual_hs_type_detect(struct cs42l42_private *cs42l42) + (0 << CS42L42_HSDET_SET_SHIFT) | + (0 << CS42L42_HSBIAS_REF_SHIFT) | + (0 << CS42L42_HSDET_AUTO_TIME_SHIFT)); ++ ++ /* Configure HS DET comparator reference levels. */ ++ regmap_update_bits(cs42l42->regmap, ++ CS42L42_HSDET_CTL1, ++ CS42L42_HSDET_COMP1_LVL_MASK | ++ CS42L42_HSDET_COMP2_LVL_MASK, ++ (CS42L42_HSDET_COMP1_LVL_DEFAULT << CS42L42_HSDET_COMP1_LVL_SHIFT) | ++ (CS42L42_HSDET_COMP2_LVL_DEFAULT << CS42L42_HSDET_COMP2_LVL_SHIFT)); + } + + static void cs42l42_process_hs_type_detect(struct cs42l42_private *cs42l42) +@@ -1135,6 +1173,18 @@ static void cs42l42_process_hs_type_detect(struct cs42l42_private *cs42l42) + cs42l42->hs_type = (hs_det_status & CS42L42_HSDET_TYPE_MASK) >> + CS42L42_HSDET_TYPE_SHIFT; + ++ /* Set hs detect to automatic, disabled mode */ ++ regmap_update_bits(cs42l42->regmap, ++ CS42L42_HSDET_CTL2, ++ CS42L42_HSDET_CTRL_MASK | ++ CS42L42_HSDET_SET_MASK | ++ CS42L42_HSBIAS_REF_MASK | ++ CS42L42_HSDET_AUTO_TIME_MASK, ++ (2 << CS42L42_HSDET_CTRL_SHIFT) | ++ (2 << CS42L42_HSDET_SET_SHIFT) | ++ (0 << CS42L42_HSBIAS_REF_SHIFT) | ++ (3 << CS42L42_HSDET_AUTO_TIME_SHIFT)); ++ + /* Run Manual detection if auto detect has not found a headset. + * We Re-Run with Manual Detection if the original detection was invalid or headphones, + * to ensure that a headset mic is detected in all cases. +@@ -1143,18 +1193,6 @@ static void cs42l42_process_hs_type_detect(struct cs42l42_private *cs42l42) + cs42l42->hs_type == CS42L42_PLUG_HEADPHONE) { + dev_dbg(cs42l42->component->dev, "Running Manual Detection Fallback\n"); + cs42l42_manual_hs_type_detect(cs42l42); +- } else { +- /* Set hs detect to automatic, disabled mode */ +- regmap_update_bits(cs42l42->regmap, +- CS42L42_HSDET_CTL2, +- CS42L42_HSDET_CTRL_MASK | +- CS42L42_HSDET_SET_MASK | +- CS42L42_HSBIAS_REF_MASK | +- CS42L42_HSDET_AUTO_TIME_MASK, +- (2 << CS42L42_HSDET_CTRL_SHIFT) | +- (2 << CS42L42_HSDET_SET_SHIFT) | +- (0 << CS42L42_HSBIAS_REF_SHIFT) | +- (3 << CS42L42_HSDET_AUTO_TIME_SHIFT)); + } + + /* Set up button detection */ +diff --git a/sound/soc/codecs/cs42l42.h b/sound/soc/codecs/cs42l42.h +index 2aeabba73e05..0704c902475f 100644 +--- a/sound/soc/codecs/cs42l42.h ++++ b/sound/soc/codecs/cs42l42.h +@@ -188,6 +188,11 @@ + #define CS42L42_HSDET_COMP2_LVL_SHIFT 4 + #define CS42L42_HSDET_COMP2_LVL_MASK (15 << CS42L42_HSDET_COMP2_LVL_SHIFT) + ++#define CS42L42_HSDET_COMP1_LVL_VAL 12 /* 1.25V Comparator */ ++#define CS42L42_HSDET_COMP2_LVL_VAL 2 /* 1.75V Comparator */ ++#define CS42L42_HSDET_COMP1_LVL_DEFAULT 7 /* 1V Comparator */ ++#define CS42L42_HSDET_COMP2_LVL_DEFAULT 7 /* 2V Comparator */ ++ + #define CS42L42_HSDET_CTL2 (CS42L42_PAGE_11 + 0x20) + #define CS42L42_HSDET_AUTO_TIME_SHIFT 0 + #define CS42L42_HSDET_AUTO_TIME_MASK (3 << CS42L42_HSDET_AUTO_TIME_SHIFT) +-- +2.35.3 + diff --git a/patches.suse/ASoC-cs42l42-free_irq-before-powering-down-on-probe-.patch b/patches.suse/ASoC-cs42l42-free_irq-before-powering-down-on-probe-.patch new file mode 100644 index 0000000..b96d06f --- /dev/null +++ b/patches.suse/ASoC-cs42l42-free_irq-before-powering-down-on-probe-.patch @@ -0,0 +1,78 @@ +From a10148a8cf561d728c0f57994330b2da1df35577 Mon Sep 17 00:00:00 2001 +From: Richard Fitzgerald +Date: Tue, 26 Oct 2021 13:57:22 +0100 +Subject: [PATCH] ASoC: cs42l42: free_irq() before powering-down on probe() fail +Git-commit: a10148a8cf561d728c0f57994330b2da1df35577 +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +Relying on devm to free the irq handler on probe failure leaves a +small window of opportunity for an interrupt to become pending and +then the handler to run after the chip has been reset and powered +off. + +For safety cs42l42_probe() should free the irq in the error path. +As the irq is now disabled by the driver in probe() and remove() +there is no point allocating it as a devres-managed item, so +convert to plain non-devres. + +Signed-off-by: Richard Fitzgerald +Link: https://lore.kernel.org/r/20211026125722.10220-3-rf@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs42l42.c | 19 +++++++++++-------- + 1 file changed, 11 insertions(+), 8 deletions(-) + +diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c +index dc12842ee6e1..1029f6b3eb48 100644 +--- a/sound/soc/codecs/cs42l42.c ++++ b/sound/soc/codecs/cs42l42.c +@@ -2078,17 +2078,16 @@ static int cs42l42_i2c_probe(struct i2c_client *i2c_client, + + /* Request IRQ if one was specified */ + if (i2c_client->irq) { +- ret = devm_request_threaded_irq(&i2c_client->dev, +- i2c_client->irq, +- NULL, cs42l42_irq_thread, +- IRQF_ONESHOT | IRQF_TRIGGER_LOW, +- "cs42l42", cs42l42); ++ ret = request_threaded_irq(i2c_client->irq, ++ NULL, cs42l42_irq_thread, ++ IRQF_ONESHOT | IRQF_TRIGGER_LOW, ++ "cs42l42", cs42l42); + if (ret == -EPROBE_DEFER) { +- goto err_disable; ++ goto err_disable_noirq; + } else if (ret != 0) { + dev_err(&i2c_client->dev, + "Failed to request IRQ: %d\n", ret); +- goto err_disable; ++ goto err_disable_noirq; + } + } + +@@ -2158,6 +2157,10 @@ static int cs42l42_i2c_probe(struct i2c_client *i2c_client, + regmap_write(cs42l42->regmap, CS42L42_PWR_CTL1, 0xff); + + err_disable: ++ if (i2c_client->irq) ++ free_irq(i2c_client->irq, cs42l42); ++ ++err_disable_noirq: + gpiod_set_value_cansleep(cs42l42->reset_gpio, 0); + err_disable_noreset: + regulator_bulk_disable(ARRAY_SIZE(cs42l42->supplies), +@@ -2170,7 +2173,7 @@ static int cs42l42_i2c_remove(struct i2c_client *i2c_client) + struct cs42l42_private *cs42l42 = i2c_get_clientdata(i2c_client); + + if (i2c_client->irq) +- devm_free_irq(&i2c_client->dev, i2c_client->irq, cs42l42); ++ free_irq(i2c_client->irq, cs42l42); + + /* + * The driver might not have control of reset and power supplies, +-- +2.35.3 + diff --git a/patches.suse/ASoC-da7219-Fix-an-error-handling-path-in-da7219_reg.patch b/patches.suse/ASoC-da7219-Fix-an-error-handling-path-in-da7219_reg.patch new file mode 100644 index 0000000..eb930d6 --- /dev/null +++ b/patches.suse/ASoC-da7219-Fix-an-error-handling-path-in-da7219_reg.patch @@ -0,0 +1,57 @@ +From abb4e4349afe7eecdb0499582f1c777031e3a7c8 Mon Sep 17 00:00:00 2001 +From: Christophe JAILLET +Date: Thu, 22 Sep 2022 21:44:57 +0200 +Subject: [PATCH] ASoC: da7219: Fix an error handling path in da7219_register_dai_clks() +Git-commit: abb4e4349afe7eecdb0499582f1c777031e3a7c8 +Patch-mainline: v6.1-rc1 +References: git-fixes + +If clk_hw_register() fails, the corresponding clk should not be +unregistered. + +To handle errors from loops, clean up partial iterations before doing the +goto. So add a clk_hw_unregister(). +Then use a while (--i >= 0) loop in the unwind section. + +Fixes: 78013a1cf297 ("ASoC: da7219: Fix clock handling around codec level probe") +Reported-by: Dan Carpenter +Signed-off-by: Christophe JAILLET +Reviewed-by: Dan Carpenter +Link: https://lore.kernel.org/r/e4acceab57a0d9e477a8d5890a45c5309e553e7c.1663875789.git.christophe.jaillet@wanadoo.fr +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/da7219.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/codecs/da7219.c b/sound/soc/codecs/da7219.c +index 50ecf30e6136..4746c8700451 100644 +--- a/sound/soc/codecs/da7219.c ++++ b/sound/soc/codecs/da7219.c +@@ -2196,6 +2196,7 @@ static int da7219_register_dai_clks(struct snd_soc_component *component) + dai_clk_lookup = clkdev_hw_create(dai_clk_hw, init.name, + "%s", dev_name(dev)); + if (!dai_clk_lookup) { ++ clk_hw_unregister(dai_clk_hw); + ret = -ENOMEM; + goto err; + } else { +@@ -2217,12 +2218,12 @@ static int da7219_register_dai_clks(struct snd_soc_component *component) + return 0; + + err: +- do { ++ while (--i >= 0) { + if (da7219->dai_clks_lookup[i]) + clkdev_drop(da7219->dai_clks_lookup[i]); + + clk_hw_unregister(&da7219->dai_clks_hw[i]); +- } while (i-- > 0); ++ } + + if (np) + kfree(da7219->clk_hw_data); +-- +2.35.3 + diff --git a/patches.suse/ASoC-dt-bindings-cs42l42-Convert-binding-to-yaml.patch b/patches.suse/ASoC-dt-bindings-cs42l42-Convert-binding-to-yaml.patch new file mode 100644 index 0000000..f84a2f2 --- /dev/null +++ b/patches.suse/ASoC-dt-bindings-cs42l42-Convert-binding-to-yaml.patch @@ -0,0 +1,397 @@ +From 0f9710603e803ae9b64ed3b54019170b323968d7 Mon Sep 17 00:00:00 2001 +From: Richard Fitzgerald +Date: Thu, 28 Oct 2021 15:09:02 +0100 +Subject: [PATCH] ASoC: dt-bindings: cs42l42: Convert binding to yaml +Git-commit: 0f9710603e803ae9b64ed3b54019170b323968d7 +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +Replace the old .txt binding with a new schema binding. +At the same time, some of the descriptions are updated to make them +clearer, fix errors, or just make them fit better into the style +of schema binding. + +The cirrus,hs-bias-ramp-rate property was missing from the old .txt +binding and has been added to the yaml. + +Signed-off-by: Richard Fitzgerald +Reviewed-by: Rob Herring +Link: https://lore.kernel.org/r/20211028140902.11786-4-rf@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + .../bindings/sound/cirrus,cs42l42.yaml | 225 ++++++++++++++++++ + .../devicetree/bindings/sound/cs42l42.txt | 115 --------- + MAINTAINERS | 1 + + 3 files changed, 226 insertions(+), 115 deletions(-) + create mode 100644 Documentation/devicetree/bindings/sound/cirrus,cs42l42.yaml + delete mode 100644 Documentation/devicetree/bindings/sound/cs42l42.txt + +diff --git a/Documentation/devicetree/bindings/sound/cirrus,cs42l42.yaml b/Documentation/devicetree/bindings/sound/cirrus,cs42l42.yaml +new file mode 100644 +index 000000000000..31800f70e9d9 +--- /dev/null ++++ b/Documentation/devicetree/bindings/sound/cirrus,cs42l42.yaml +@@ -0,0 +1,225 @@ ++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/sound/cirrus,cs42l42.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Cirrus Logic CS42L42 audio CODEC ++ ++maintainers: ++ - patches@opensource.cirrus.com ++ ++description: ++ The CS42L42 is a low-power audio codec designed for portable applications. ++ It provides a high-dynamic range, stereo DAC for audio playback and a mono ++ high-dynamic-range ADC for audio capture. There is an integrated headset ++ detection block. ++ ++properties: ++ compatible: ++ enum: ++ - cirrus,cs42l42 ++ ++ reg: ++ description: ++ The I2C address of the CS42L42. ++ maxItems: 1 ++ ++ VP-supply: ++ description: ++ VP power supply. ++ ++ VCP-supply: ++ description: ++ Charge pump power supply. ++ ++ VD_FILT-supply: ++ description: ++ FILT+ power supply. ++ ++ VL-supply: ++ description: ++ Logic power supply. ++ ++ VA-supply: ++ description: ++ Analog power supply. ++ ++ reset-gpios: ++ description: ++ This pin will be asserted and then deasserted to reset the ++ CS42L42 before communication starts. ++ maxItems: 1 ++ ++ interrupts: ++ description: ++ Interrupt for CS42L42 IRQ line. ++ maxItems: 1 ++ ++ cirrus,ts-inv: ++ description: | ++ Sets the behaviour of the jack plug detect switch. ++ ++ 0 - (Default) Shorted to tip when unplugged, open when plugged. ++ This is "inverted tip sense (ITS)" in the datasheet. ++ ++ 1 - Open when unplugged, shorted to tip when plugged. ++ This is "normal tip sense (TS)" in the datasheet. ++ ++ The CS42L42_TS_INV_* defines are available for this. ++ $ref: "/schemas/types.yaml#/definitions/uint32" ++ minimum: 0 ++ maximum: 1 ++ ++ cirrus,ts-dbnc-rise: ++ description: | ++ Debounce the rising edge of TIP_SENSE_PLUG. With no ++ debounce, the tip sense pin might be noisy on a plug event. ++ ++ 0 - 0ms ++ 1 - 125ms ++ 2 - 250ms ++ 3 - 500ms ++ 4 - 750ms ++ 5 - 1s (Default) ++ 6 - 1.25s ++ 7 - 1.5s ++ ++ The CS42L42_TS_DBNCE_* defines are available for this. ++ $ref: "/schemas/types.yaml#/definitions/uint32" ++ minimum: 0 ++ maximum: 7 ++ ++ cirrus,ts-dbnc-fall: ++ description: | ++ Debounce the falling edge of TIP_SENSE_UNPLUG. With no ++ debounce, the tip sense pin might be noisy on an unplug event. ++ ++ 0 - 0ms ++ 1 - 125ms ++ 2 - 250ms ++ 3 - 500ms ++ 4 - 750ms ++ 5 - 1s (Default) ++ 6 - 1.25s ++ 7 - 1.5s ++ ++ The CS42L42_TS_DBNCE_* defines are available for this. ++ $ref: "/schemas/types.yaml#/definitions/uint32" ++ minimum: 0 ++ maximum: 7 ++ ++ cirrus,btn-det-init-dbnce: ++ description: | ++ This sets how long to wait after enabling button detection ++ interrupts before servicing button interrupts, to allow the ++ HS bias time to settle. Value is in milliseconds. ++ There may be erroneous button interrupts if this debounce time ++ is too short. ++ ++ 0ms - 200ms, ++ Default = 100ms ++ $ref: "/schemas/types.yaml#/definitions/uint32" ++ minimum: 0 ++ maximum: 200 ++ ++ cirrus,btn-det-event-dbnce: ++ description: | ++ This sets how long to wait after receiving a button press ++ interrupt before processing it. Allows time for the button ++ press to make a clean connection with the bias resistors. ++ Value is in milliseconds. ++ ++ 0ms - 20ms, ++ Default = 10ms ++ $ref: "/schemas/types.yaml#/definitions/uint32" ++ minimum: 0 ++ maximum: 20 ++ ++ cirrus,bias-lvls: ++ description: | ++ For a level-detect headset button scheme, each button will bias ++ the mic pin to a certain voltage. To determine which button was ++ pressed, the voltage is compared to sequential, decreasing ++ voltages, until the compared voltage < bias voltage. ++ For different hardware setups, a designer might want to tweak this. ++ This is an array of descending values for the comparator voltage, ++ given as percent of the HSBIAS voltage. ++ ++ Array of 4 values, each 0-63 ++ < x1 x2 x3 x4 > ++ Default = < 15 8 4 1 > ++ $ref: /schemas/types.yaml#/definitions/uint32-array ++ minItems: 4 ++ maxItems: 4 ++ items: ++ minimum: 0 ++ maximum: 63 ++ ++ cirrus,hs-bias-ramp-rate: ++ description: | ++ If present this sets the rate that the HS bias should rise and fall. ++ The actual rise and fall times depend on external hardware (the ++ datasheet gives several rise and fall time examples). ++ ++ 0 - Fast rise time; slow, load-dependent fall time ++ 1 - Fast ++ 2 - Slow (default) ++ 3 - Slowest ++ ++ The CS42L42_HSBIAS_RAMP_* defines are available for this. ++ $ref: "/schemas/types.yaml#/definitions/uint32" ++ minimum: 0 ++ maximum: 3 ++ ++ cirrus,hs-bias-sense-disable: ++ description: | ++ If present the HSBIAS sense is disabled. Configures HSBIAS output ++ current sense through the external 2.21-k resistor. HSBIAS_SENSE ++ is a hardware feature to reduce the potential pop noise when the ++ headset plug is removed slowly. But on some platforms ESD voltage ++ will affect it causing plug detection to fail, especially with CTIA ++ headset type. For different hardware setups, a designer might want ++ to tweak default behavior. ++ type: boolean ++ ++required: ++ - compatible ++ - reg ++ - VP-supply ++ - VCP-supply ++ - VD_FILT-supply ++ - VL-supply ++ - VA-supply ++ ++additionalProperties: false ++ ++examples: ++ - | ++ #include ++ i2c { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cs42l42: cs42l42@48 { ++ compatible = "cirrus,cs42l42"; ++ reg = <0x48>; ++ VA-supply = <&dummy_vreg>; ++ VP-supply = <&dummy_vreg>; ++ VCP-supply = <&dummy_vreg>; ++ VD_FILT-supply = <&dummy_vreg>; ++ VL-supply = <&dummy_vreg>; ++ ++ reset-gpios = <&axi_gpio_0 1 0>; ++ interrupt-parent = <&gpio0>; ++ interrupts = <55 8>; ++ ++ cirrus,ts-inv = ; ++ cirrus,ts-dbnc-rise = ; ++ cirrus,ts-dbnc-fall = ; ++ cirrus,btn-det-init-dbnce = <100>; ++ cirrus,btn-det-event-dbnce = <10>; ++ cirrus,bias-lvls = <0x0F 0x08 0x04 0x01>; ++ cirrus,hs-bias-ramp-rate = ; ++ }; ++ }; +diff --git a/Documentation/devicetree/bindings/sound/cs42l42.txt b/Documentation/devicetree/bindings/sound/cs42l42.txt +deleted file mode 100644 +index 3b7705623980..000000000000 +--- a/Documentation/devicetree/bindings/sound/cs42l42.txt ++++ /dev/null +@@ -1,115 +0,0 @@ +-CS42L42 audio CODEC +- +-Required properties: +- +- - compatible : "cirrus,cs42l42" +- +- - reg : the I2C address of the device for I2C. +- +- - VP-supply, VCP-supply, VD_FILT-supply, VL-supply, VA-supply : +- power supplies for the device, as covered in +- Documentation/devicetree/bindings/regulator/regulator.txt. +- +-Optional properties: +- +- - reset-gpios : a GPIO spec for the reset pin. If specified, it will be +- deasserted before communication to the codec starts. +- +- - interrupts : IRQ line info CS42L42. +- (See Documentation/devicetree/bindings/interrupt-controller/interrupts.txt +- for further information relating to interrupt properties) +- +- - cirrus,ts-inv : Boolean property. Sets the behaviour of the jack plug +- detect switch. +- +- 0 = (Default) Shorted to tip when unplugged, open when plugged. +- This is "inverted tip sense (ITS)" in the datasheet. +- +- 1 = Open when unplugged, shorted to tip when plugged. +- This is "normal tip sense (TS)" in the datasheet. +- +- - cirrus,ts-dbnc-rise : Debounce the rising edge of TIP_SENSE_PLUG. With no +- debounce, the tip sense pin might be noisy on a plug event. +- +- 0 - 0ms, +- 1 - 125ms, +- 2 - 250ms, +- 3 - 500ms, +- 4 - 750ms, +- 5 - (Default) 1s, +- 6 - 1.25s, +- 7 - 1.5s, +- +- - cirrus,ts-dbnc-fall : Debounce the falling edge of TIP_SENSE_UNPLUG. +- With no debounce, the tip sense pin might be noisy on an unplug event. +- +- 0 - 0ms, +- 1 - 125ms, +- 2 - 250ms, +- 3 - 500ms, +- 4 - 750ms, +- 5 - (Default) 1s, +- 6 - 1.25s, +- 7 - 1.5s, +- +- - cirrus,btn-det-init-dbnce : This sets how long the driver sleeps after +- enabling button detection interrupts. After auto-detection and before +- servicing button interrupts, the HS bias needs time to settle. If you +- don't wait, there is possibility for erroneous button interrupt. +- +- 0ms - 200ms, +- Default = 100ms +- +- - cirrus,btn-det-event-dbnce : This sets how long the driver delays after +- receiving a button press interrupt. With level detect interrupts, you want +- to wait a small amount of time to make sure the button press is making a +- clean connection with the bias resistors. +- +- 0ms - 20ms, +- Default = 10ms +- +- - cirrus,bias-lvls : For a level-detect headset button scheme, each button +- will bias the mic pin to a certain voltage. To determine which button was +- pressed, the driver will compare this biased voltage to sequential, +- decreasing voltages and will stop when a comparator is tripped, +- indicating a comparator voltage < bias voltage. This value represents a +- percentage of the internally generated HS bias voltage. For different +- hardware setups, a designer might want to tweak this. This is an array of +- descending values for the comparator voltage. +- +- Array of 4 values +- Each 0-63 +- < x1 x2 x3 x4 > +- Default = < 15 8 4 1> +- +- - cirrus,hs-bias-sense-disable: This is boolean property. If present the +- HSBIAS sense is disabled. Configures HSBIAS output current sense through +- the external 2.21-k resistor. HSBIAS_SENSE is hardware feature to reduce +- the potential pop noise during the headset plug out slowly. But on some +- platforms ESD voltage will affect it causing test to fail, especially +- with CTIA headset type. For different hardware setups, a designer might +- want to tweak default behavior. +- +-Example: +- +-cs42l42: cs42l42@48 { +- compatible = "cirrus,cs42l42"; +- reg = <0x48>; +- VA-supply = <&dummy_vreg>; +- VP-supply = <&dummy_vreg>; +- VCP-supply = <&dummy_vreg>; +- VD_FILT-supply = <&dummy_vreg>; +- VL-supply = <&dummy_vreg>; +- +- reset-gpios = <&axi_gpio_0 1 0>; +- interrupt-parent = <&gpio0>; +- interrupts = <55 8> +- +- cirrus,ts-inv = <0x00>; +- cirrus,ts-dbnc-rise = <0x05>; +- cirrus,ts-dbnc-fall = <0x00>; +- cirrus,btn-det-init-dbnce = <100>; +- cirrus,btn-det-event-dbnce = <10>; +- cirrus,bias-lvls = <0x0F 0x08 0x04 0x01>; +- cirrus,hs-bias-ramp-rate = <0x02>; +-}; +diff --git a/MAINTAINERS b/MAINTAINERS +index 7a2345ce8521..09734251e1de 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -4514,6 +4514,7 @@ M: David Rhodes + L: alsa-devel@alsa-project.org (moderated for non-subscribers) + L: patches@opensource.cirrus.com + S: Maintained ++F: Documentation/devicetree/bindings/sound/cirrus,cs* + F: sound/soc/codecs/cs* + + CIRRUS LOGIC DSP FIRMWARE DRIVER +-- +2.35.3 + diff --git a/patches.suse/ASoC-eureka-tlv320-Hold-reference-returned-from-of_f.patch b/patches.suse/ASoC-eureka-tlv320-Hold-reference-returned-from-of_f.patch new file mode 100644 index 0000000..ecc8108 --- /dev/null +++ b/patches.suse/ASoC-eureka-tlv320-Hold-reference-returned-from-of_f.patch @@ -0,0 +1,69 @@ +From bfb735a3ceff0bab6473bac275da96f9b2a06dec Mon Sep 17 00:00:00 2001 +From: Liang He +Date: Wed, 14 Sep 2022 21:43:54 +0800 +Subject: [PATCH] ASoC: eureka-tlv320: Hold reference returned from of_find_xxx API +Git-commit: bfb735a3ceff0bab6473bac275da96f9b2a06dec +Patch-mainline: v6.1-rc1 +References: git-fixes + +In eukrea_tlv320_probe(), we need to hold the reference returned +from of_find_compatible_node() which has increased the refcount +and then call of_node_put() with it when done. + +Fixes: 66f232908de2 ("ASoC: eukrea-tlv320: Add DT support.") +Co-authored-by: Kelin Wang +Signed-off-by: Liang He +Link: https://lore.kernel.org/r/20220914134354.3995587-1-windhl@126.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/fsl/eukrea-tlv320.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/sound/soc/fsl/eukrea-tlv320.c b/sound/soc/fsl/eukrea-tlv320.c +index 8b61582753c8..9af4c4a35eb1 100644 +--- a/sound/soc/fsl/eukrea-tlv320.c ++++ b/sound/soc/fsl/eukrea-tlv320.c +@@ -86,7 +86,7 @@ static int eukrea_tlv320_probe(struct platform_device *pdev) + int ret; + int int_port = 0, ext_port; + struct device_node *np = pdev->dev.of_node; +- struct device_node *ssi_np = NULL, *codec_np = NULL; ++ struct device_node *ssi_np = NULL, *codec_np = NULL, *tmp_np = NULL; + + eukrea_tlv320.dev = &pdev->dev; + if (np) { +@@ -143,7 +143,7 @@ static int eukrea_tlv320_probe(struct platform_device *pdev) + } + + if (machine_is_eukrea_cpuimx27() || +- of_find_compatible_node(NULL, NULL, "fsl,imx21-audmux")) { ++ (tmp_np = of_find_compatible_node(NULL, NULL, "fsl,imx21-audmux"))) { + imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0, + IMX_AUDMUX_V1_PCR_SYN | + IMX_AUDMUX_V1_PCR_TFSDIR | +@@ -158,10 +158,11 @@ static int eukrea_tlv320_probe(struct platform_device *pdev) + IMX_AUDMUX_V1_PCR_SYN | + IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0) + ); ++ of_node_put(tmp_np); + } else if (machine_is_eukrea_cpuimx25sd() || + machine_is_eukrea_cpuimx35sd() || + machine_is_eukrea_cpuimx51sd() || +- of_find_compatible_node(NULL, NULL, "fsl,imx31-audmux")) { ++ (tmp_np = of_find_compatible_node(NULL, NULL, "fsl,imx31-audmux"))) { + if (!np) + ext_port = machine_is_eukrea_cpuimx25sd() ? + 4 : 3; +@@ -178,6 +179,7 @@ static int eukrea_tlv320_probe(struct platform_device *pdev) + IMX_AUDMUX_V2_PTCR_SYN, + IMX_AUDMUX_V2_PDCR_RXDSEL(int_port) + ); ++ of_node_put(tmp_np); + } else { + if (np) { + /* The eukrea,asoc-tlv320 driver was explicitly +-- +2.35.3 + diff --git a/patches.suse/ASoC-fsl_sai-Remove-unnecessary-FIFO-reset-in-ISR.patch b/patches.suse/ASoC-fsl_sai-Remove-unnecessary-FIFO-reset-in-ISR.patch new file mode 100644 index 0000000..482bc5d --- /dev/null +++ b/patches.suse/ASoC-fsl_sai-Remove-unnecessary-FIFO-reset-in-ISR.patch @@ -0,0 +1,56 @@ +From cb225ac125a9c82889f4796a6092dd0bed39720a Mon Sep 17 00:00:00 2001 +From: Shengjiu Wang +Date: Wed, 17 Aug 2022 13:24:27 +0800 +Subject: [PATCH] ASoC: fsl_sai: Remove unnecessary FIFO reset in ISR +Git-commit: cb225ac125a9c82889f4796a6092dd0bed39720a +Patch-mainline: v6.1-rc1 +References: git-fixes + +The FIFO reset drops the words in the FIFO, which may cause +channel swap when SAI module is running, especially when the +DMA speed is low. So it is not good to do FIFO reset in ISR, +then remove the operation. + +Fixes: e2681a1bf5ae ("ASoC: fsl_sai: Add isr to deal with error flag") +Signed-off-by: Shengjiu Wang +Link: https://lore.kernel.org/r/1660713867-26921-1-git-send-email-shengjiu.wang@nxp.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/fsl/fsl_sai.c | 10 ++-------- + 1 file changed, 2 insertions(+), 8 deletions(-) + +diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c +index d430eece1d6b..a7fa6f0bf83d 100644 +--- a/sound/soc/fsl/fsl_sai.c ++++ b/sound/soc/fsl/fsl_sai.c +@@ -114,11 +114,8 @@ static irqreturn_t fsl_sai_isr(int irq, void *devid) + if (flags & FSL_SAI_CSR_SEF) + dev_dbg(dev, "isr: Tx Frame sync error detected\n"); + +- if (flags & FSL_SAI_CSR_FEF) { ++ if (flags & FSL_SAI_CSR_FEF) + dev_dbg(dev, "isr: Transmit underrun detected\n"); +- /* FIFO reset for safety */ +- xcsr |= FSL_SAI_CSR_FR; +- } + + if (flags & FSL_SAI_CSR_FWF) + dev_dbg(dev, "isr: Enabled transmit FIFO is empty\n"); +@@ -148,11 +145,8 @@ static irqreturn_t fsl_sai_isr(int irq, void *devid) + if (flags & FSL_SAI_CSR_SEF) + dev_dbg(dev, "isr: Rx Frame sync error detected\n"); + +- if (flags & FSL_SAI_CSR_FEF) { ++ if (flags & FSL_SAI_CSR_FEF) + dev_dbg(dev, "isr: Receive overflow detected\n"); +- /* FIFO reset for safety */ +- xcsr |= FSL_SAI_CSR_FR; +- } + + if (flags & FSL_SAI_CSR_FWF) + dev_dbg(dev, "isr: Enabled receive FIFO is full\n"); +-- +2.35.3 + diff --git a/patches.suse/ASoC-imx-card-Fix-refcount-issue-with-of_node_put.patch b/patches.suse/ASoC-imx-card-Fix-refcount-issue-with-of_node_put.patch new file mode 100644 index 0000000..f1a8798 --- /dev/null +++ b/patches.suse/ASoC-imx-card-Fix-refcount-issue-with-of_node_put.patch @@ -0,0 +1,44 @@ +From d56ba9a04d7548d4149c46ec86a0e3cc41a70f4a Mon Sep 17 00:00:00 2001 +From: Shengjiu Wang +Date: Tue, 13 Sep 2022 17:00:01 +0800 +Subject: [PATCH] ASoC: imx-card: Fix refcount issue with of_node_put +Git-commit: d56ba9a04d7548d4149c46ec86a0e3cc41a70f4a +Patch-mainline: v6.0 +References: git-fixes + +imx_card_parse_of will search all the node with loop, +if there is defer probe happen in the middle of loop, +the previous released codec node will be released +twice, then cause refcount issue. + +Here assign NULL to pointer of released nodes to fix +the issue. + +Fixes: aa736700f42f ("ASoC: imx-card: Add imx-card machine driver") +Signed-off-by: Shengjiu Wang +Link: https://lore.kernel.org/r/1663059601-29259-1-git-send-email-shengjiu.wang@nxp.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/fsl/imx-card.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/sound/soc/fsl/imx-card.c b/sound/soc/fsl/imx-card.c +index 14be29530fb5..3f128ced4180 100644 +--- a/sound/soc/fsl/imx-card.c ++++ b/sound/soc/fsl/imx-card.c +@@ -698,6 +698,10 @@ static int imx_card_parse_of(struct imx_card_data *data) + of_node_put(cpu); + of_node_put(codec); + of_node_put(platform); ++ ++ cpu = NULL; ++ codec = NULL; ++ platform = NULL; + } + + return 0; +-- +2.35.3 + diff --git a/patches.suse/ASoC-mchp-spdiftx-Fix-clang-Wbitfield-constant-conve.patch b/patches.suse/ASoC-mchp-spdiftx-Fix-clang-Wbitfield-constant-conve.patch new file mode 100644 index 0000000..19ed80f --- /dev/null +++ b/patches.suse/ASoC-mchp-spdiftx-Fix-clang-Wbitfield-constant-conve.patch @@ -0,0 +1,51 @@ +From 5c5c2baad2b55cc0a4b190266889959642298f79 Mon Sep 17 00:00:00 2001 +From: Nathan Chancellor +Date: Tue, 9 Aug 2022 18:08:09 -0700 +Subject: [PATCH] ASoC: mchp-spdiftx: Fix clang -Wbitfield-constant-conversion +Git-commit: 5c5c2baad2b55cc0a4b190266889959642298f79 +Patch-mainline: v6.0-rc5 +References: git-fixes + +A recent change in clang strengthened its -Wbitfield-constant-conversion +to warn when 1 is assigned to a 1-bit signed integer bitfield, as it can +only be 0 or -1, not 1: + + sound/soc/atmel/mchp-spdiftx.c:505:20: error: implicit truncation from 'int' to bit-field changes value from 1 to -1 [-Werror,-Wbitfield-constant-conversion] + dev->gclk_enabled = 1; + ^ ~ + 1 error generated. + +The actual value of the field is never checked, just that it is not +zero, so there is not a real bug here. However, it is simple enough to +silence the warning by making the bitfield unsigned, which matches the +mchp-spdifrx driver. + +Fixes: 06ca24e98e6b ("ASoC: mchp-spdiftx: add driver for S/PDIF TX Controller") +Link: https://github.com/ClangBuiltLinux/linux/issues/1686 +Link: https://github.com/llvm/llvm-project/commit/82afc9b169a67e8b8a1862fb9c41a2cd974d6691 +Signed-off-by: Nathan Chancellor +Reviewed-by: Nick Desaulniers +Link: https://lore.kernel.org/r/20220810010809.2024482-1-nathan@kernel.org +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/atmel/mchp-spdiftx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/atmel/mchp-spdiftx.c b/sound/soc/atmel/mchp-spdiftx.c +index 4850a177803d..ab2d7a791f39 100644 +--- a/sound/soc/atmel/mchp-spdiftx.c ++++ b/sound/soc/atmel/mchp-spdiftx.c +@@ -196,7 +196,7 @@ struct mchp_spdiftx_dev { + struct clk *pclk; + struct clk *gclk; + unsigned int fmt; +- int gclk_enabled:1; ++ unsigned int gclk_enabled:1; + }; + + static inline int mchp_spdiftx_is_running(struct mchp_spdiftx_dev *dev) +-- +2.35.3 + diff --git a/patches.suse/ASoC-mchp-spdiftx-remove-references-to-mchp_i2s_caps.patch b/patches.suse/ASoC-mchp-spdiftx-remove-references-to-mchp_i2s_caps.patch new file mode 100644 index 0000000..a5fd4d4 --- /dev/null +++ b/patches.suse/ASoC-mchp-spdiftx-remove-references-to-mchp_i2s_caps.patch @@ -0,0 +1,55 @@ +From 403fcb5118a0f4091001a537e76923031fb45eaf Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea +Date: Wed, 27 Jul 2022 12:08:14 +0300 +Subject: [PATCH] ASoC: mchp-spdiftx: remove references to mchp_i2s_caps +Git-commit: 403fcb5118a0f4091001a537e76923031fb45eaf +Patch-mainline: v6.0-rc1 +References: git-fixes + +Remove references to struct mchp_i2s_caps as they are not used. + +Signed-off-by: Claudiu Beznea +Link: https://lore.kernel.org/r/20220727090814.2446111-3-claudiu.beznea@microchip.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/atmel/mchp-spdiftx.c | 8 -------- + 1 file changed, 8 deletions(-) + +diff --git a/sound/soc/atmel/mchp-spdiftx.c b/sound/soc/atmel/mchp-spdiftx.c +index d24380046435..9b40df2c39f9 100644 +--- a/sound/soc/atmel/mchp-spdiftx.c ++++ b/sound/soc/atmel/mchp-spdiftx.c +@@ -196,7 +196,6 @@ struct mchp_spdiftx_dev { + struct clk *pclk; + struct clk *gclk; + unsigned int fmt; +- const struct mchp_i2s_caps *caps; + int gclk_enabled:1; + }; + +@@ -766,8 +765,6 @@ static const struct of_device_id mchp_spdiftx_dt_ids[] = { + MODULE_DEVICE_TABLE(of, mchp_spdiftx_dt_ids); + static int mchp_spdiftx_probe(struct platform_device *pdev) + { +- struct device_node *np = pdev->dev.of_node; +- const struct of_device_id *match; + struct mchp_spdiftx_dev *dev; + struct resource *mem; + struct regmap *regmap; +@@ -781,11 +778,6 @@ static int mchp_spdiftx_probe(struct platform_device *pdev) + if (!dev) + return -ENOMEM; + +- /* Get hardware capabilities. */ +- match = of_match_node(mchp_spdiftx_dt_ids, np); +- if (match) +- dev->caps = match->data; +- + /* Map I/O registers. */ + base = devm_platform_get_and_ioremap_resource(pdev, 0, &mem); + if (IS_ERR(base)) +-- +2.35.3 + diff --git a/patches.suse/ASoC-mt6359-fix-tests-for-platform_get_irq-failure.patch b/patches.suse/ASoC-mt6359-fix-tests-for-platform_get_irq-failure.patch new file mode 100644 index 0000000..5bb96e2 --- /dev/null +++ b/patches.suse/ASoC-mt6359-fix-tests-for-platform_get_irq-failure.patch @@ -0,0 +1,55 @@ +From 51eea3a6fb4d39c2cc71824e6eee5949d7ae4d1c Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Thu, 11 Aug 2022 14:01:26 +0300 +Subject: [PATCH] ASoC: mt6359: fix tests for platform_get_irq() failure +Git-commit: 51eea3a6fb4d39c2cc71824e6eee5949d7ae4d1c +Patch-mainline: v6.1-rc1 +References: git-fixes + +The platform_get_irq() returns negative error codes. It can't actually +return zero, but if it did that should be treated as success. + +Fixes: eef07b9e0925 ("ASoC: mediatek: mt6359: add MT6359 accdet jack driver") +Signed-off-by: Dan Carpenter +Link: https://lore.kernel.org/r/YvThhr86N3qQM2EO@kili +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/mt6359-accdet.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/sound/soc/codecs/mt6359-accdet.c b/sound/soc/codecs/mt6359-accdet.c +index c190628e2905..7f624854948c 100644 +--- a/sound/soc/codecs/mt6359-accdet.c ++++ b/sound/soc/codecs/mt6359-accdet.c +@@ -965,7 +965,7 @@ static int mt6359_accdet_probe(struct platform_device *pdev) + mutex_init(&priv->res_lock); + + priv->accdet_irq = platform_get_irq(pdev, 0); +- if (priv->accdet_irq) { ++ if (priv->accdet_irq >= 0) { + ret = devm_request_threaded_irq(&pdev->dev, priv->accdet_irq, + NULL, mt6359_accdet_irq, + IRQF_TRIGGER_HIGH | IRQF_ONESHOT, +@@ -979,7 +979,7 @@ static int mt6359_accdet_probe(struct platform_device *pdev) + + if (priv->caps & ACCDET_PMIC_EINT0) { + priv->accdet_eint0 = platform_get_irq(pdev, 1); +- if (priv->accdet_eint0) { ++ if (priv->accdet_eint0 >= 0) { + ret = devm_request_threaded_irq(&pdev->dev, + priv->accdet_eint0, + NULL, mt6359_accdet_irq, +@@ -994,7 +994,7 @@ static int mt6359_accdet_probe(struct platform_device *pdev) + } + } else if (priv->caps & ACCDET_PMIC_EINT1) { + priv->accdet_eint1 = platform_get_irq(pdev, 2); +- if (priv->accdet_eint1) { ++ if (priv->accdet_eint1 >= 0) { + ret = devm_request_threaded_irq(&pdev->dev, + priv->accdet_eint1, + NULL, mt6359_accdet_irq, +-- +2.35.3 + diff --git a/patches.suse/ASoC-mt6660-Fix-PM-disable-depth-imbalance-in-mt6660.patch b/patches.suse/ASoC-mt6660-Fix-PM-disable-depth-imbalance-in-mt6660.patch new file mode 100644 index 0000000..a06124a --- /dev/null +++ b/patches.suse/ASoC-mt6660-Fix-PM-disable-depth-imbalance-in-mt6660.patch @@ -0,0 +1,51 @@ +From b73f11e895e140537e7f8c7251211ccd3ce0782b Mon Sep 17 00:00:00 2001 +From: Zhang Qilong +Date: Thu, 29 Sep 2022 00:01:16 +0800 +Subject: [PATCH] ASoC: mt6660: Fix PM disable depth imbalance in mt6660_i2c_probe +Git-commit: b73f11e895e140537e7f8c7251211ccd3ce0782b +Patch-mainline: v6.1-rc1 +References: git-fixes + +The pm_runtime_enable will increase power disable depth. Thus +a pairing decrement is needed on the error handling path to +keep it balanced according to context. We fix it by moving +pm_runtime_enable to the endding of mt6660_i2c_probe. + +Fixes:f289e55c6eeb4 ("ASoC: Add MediaTek MT6660 Speaker Amp Driver") + +Signed-off-by: Zhang Qilong +Link: https://lore.kernel.org/r/20220928160116.125020-5-zhangqilong3@huawei.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/mt6660.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/codecs/mt6660.c b/sound/soc/codecs/mt6660.c +index ba11555796ad..45e0df13afb9 100644 +--- a/sound/soc/codecs/mt6660.c ++++ b/sound/soc/codecs/mt6660.c +@@ -503,13 +503,17 @@ static int mt6660_i2c_probe(struct i2c_client *client) + dev_err(chip->dev, "read chip revision fail\n"); + goto probe_fail; + } +- pm_runtime_set_active(chip->dev); +- pm_runtime_enable(chip->dev); + + ret = devm_snd_soc_register_component(chip->dev, + &mt6660_component_driver, + &mt6660_codec_dai, 1); ++ if (!ret) { ++ pm_runtime_set_active(chip->dev); ++ pm_runtime_enable(chip->dev); ++ } ++ + return ret; ++ + probe_fail: + _mt6660_chip_power_on(chip, 0); + mutex_destroy(&chip->io_lock); +-- +2.35.3 + diff --git a/patches.suse/ASoC-nau8824-Fix-semaphore-unbalance-at-error-paths.patch b/patches.suse/ASoC-nau8824-Fix-semaphore-unbalance-at-error-paths.patch new file mode 100644 index 0000000..138c0dc --- /dev/null +++ b/patches.suse/ASoC-nau8824-Fix-semaphore-unbalance-at-error-paths.patch @@ -0,0 +1,100 @@ +From 5628560e90395d3812800a8e44a01c32ffa429ec Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 23 Aug 2022 10:09:57 +0200 +Subject: [PATCH] ASoC: nau8824: Fix semaphore unbalance at error paths +Git-commit: 5628560e90395d3812800a8e44a01c32ffa429ec +Patch-mainline: v6.0-rc5 +References: git-fixes + +The semaphore of nau8824 wasn't properly unlocked at some error +handling code paths, hence this may result in the unbalance (and +potential lock-up). Fix them to handle the semaphore up properly. + +Signed-off-by: Takashi Iwai +Link: https://lore.kernel.org/r/20220823081000.2965-3-tiwai@suse.de +Signed-off-by: Mark Brown + +--- + sound/soc/codecs/nau8824.c | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +diff --git a/sound/soc/codecs/nau8824.c b/sound/soc/codecs/nau8824.c +index ad54d70f7d8e..10bdfebe92d5 100644 +--- a/sound/soc/codecs/nau8824.c ++++ b/sound/soc/codecs/nau8824.c +@@ -1043,6 +1043,7 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream, + struct snd_soc_component *component = dai->component; + struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component); + unsigned int val_len = 0, osr, ctrl_val, bclk_fs, bclk_div; ++ int err = -EINVAL; + + nau8824_sema_acquire(nau8824, HZ); + +@@ -1059,7 +1060,7 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream, + osr &= NAU8824_DAC_OVERSAMPLE_MASK; + if (nau8824_clock_check(nau8824, substream->stream, + nau8824->fs, osr)) +- return -EINVAL; ++ goto error; + regmap_update_bits(nau8824->regmap, NAU8824_REG_CLK_DIVIDER, + NAU8824_CLK_DAC_SRC_MASK, + osr_dac_sel[osr].clk_src << NAU8824_CLK_DAC_SRC_SFT); +@@ -1069,7 +1070,7 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream, + osr &= NAU8824_ADC_SYNC_DOWN_MASK; + if (nau8824_clock_check(nau8824, substream->stream, + nau8824->fs, osr)) +- return -EINVAL; ++ goto error; + regmap_update_bits(nau8824->regmap, NAU8824_REG_CLK_DIVIDER, + NAU8824_CLK_ADC_SRC_MASK, + osr_adc_sel[osr].clk_src << NAU8824_CLK_ADC_SRC_SFT); +@@ -1090,7 +1091,7 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream, + else if (bclk_fs <= 256) + bclk_div = 0; + else +- return -EINVAL; ++ goto error; + regmap_update_bits(nau8824->regmap, + NAU8824_REG_PORT0_I2S_PCM_CTRL_2, + NAU8824_I2S_LRC_DIV_MASK | NAU8824_I2S_BLK_DIV_MASK, +@@ -1111,15 +1112,17 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream, + val_len |= NAU8824_I2S_DL_32; + break; + default: +- return -EINVAL; ++ goto error; + } + + regmap_update_bits(nau8824->regmap, NAU8824_REG_PORT0_I2S_PCM_CTRL_1, + NAU8824_I2S_DL_MASK, val_len); ++ err = 0; + ++ error: + nau8824_sema_release(nau8824); + +- return 0; ++ return err; + } + + static int nau8824_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) +@@ -1128,8 +1131,6 @@ static int nau8824_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) + struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component); + unsigned int ctrl1_val = 0, ctrl2_val = 0; + +- nau8824_sema_acquire(nau8824, HZ); +- + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + ctrl2_val |= NAU8824_I2S_MS_MASTER; +@@ -1171,6 +1172,8 @@ static int nau8824_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) + return -EINVAL; + } + ++ nau8824_sema_acquire(nau8824, HZ); ++ + regmap_update_bits(nau8824->regmap, NAU8824_REG_PORT0_I2S_PCM_CTRL_1, + NAU8824_I2S_DF_MASK | NAU8824_I2S_BP_MASK | + NAU8824_I2S_PCMB_EN, ctrl1_val); +-- +2.35.3 + diff --git a/patches.suse/ASoC-rsnd-Add-check-for-rsnd_mod_power_on.patch b/patches.suse/ASoC-rsnd-Add-check-for-rsnd_mod_power_on.patch new file mode 100644 index 0000000..13041fd --- /dev/null +++ b/patches.suse/ASoC-rsnd-Add-check-for-rsnd_mod_power_on.patch @@ -0,0 +1,116 @@ +From 376be51caf8871419bbcbb755e1e615d30dc3153 Mon Sep 17 00:00:00 2001 +From: Jiasheng Jiang +Date: Fri, 2 Sep 2022 09:30:30 +0800 +Subject: [PATCH] ASoC: rsnd: Add check for rsnd_mod_power_on +Git-commit: 376be51caf8871419bbcbb755e1e615d30dc3153 +Patch-mainline: v6.1-rc1 +References: git-fixes + +As rsnd_mod_power_on() can return negative numbers, +it should be better to check the return value and +deal with the exception. + +Fixes: e7d850dd10f4 ("ASoC: rsnd: use mod base common method on SSI-parent") +Signed-off-by: Jiasheng Jiang +Acked-by: Kuninori Morimoto +Link: https://lore.kernel.org/r/20220902013030.3691266-1-jiasheng@iscas.ac.cn +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/sh/rcar/ctu.c | 6 +++++- + sound/soc/sh/rcar/dvc.c | 6 +++++- + sound/soc/sh/rcar/mix.c | 6 +++++- + sound/soc/sh/rcar/src.c | 5 ++++- + sound/soc/sh/rcar/ssi.c | 4 +++- + 5 files changed, 22 insertions(+), 5 deletions(-) + +diff --git a/sound/soc/sh/rcar/ctu.c b/sound/soc/sh/rcar/ctu.c +index 6156445bcb69..e39eb2ac7e95 100644 +--- a/sound/soc/sh/rcar/ctu.c ++++ b/sound/soc/sh/rcar/ctu.c +@@ -171,7 +171,11 @@ static int rsnd_ctu_init(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) + { +- rsnd_mod_power_on(mod); ++ int ret; ++ ++ ret = rsnd_mod_power_on(mod); ++ if (ret < 0) ++ return ret; + + rsnd_ctu_activation(mod); + +diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c +index 5137e03a9d7c..16befcbc312c 100644 +--- a/sound/soc/sh/rcar/dvc.c ++++ b/sound/soc/sh/rcar/dvc.c +@@ -186,7 +186,11 @@ static int rsnd_dvc_init(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) + { +- rsnd_mod_power_on(mod); ++ int ret; ++ ++ ret = rsnd_mod_power_on(mod); ++ if (ret < 0) ++ return ret; + + rsnd_dvc_activation(mod); + +diff --git a/sound/soc/sh/rcar/mix.c b/sound/soc/sh/rcar/mix.c +index 3572c2c5686c..1de0e085804c 100644 +--- a/sound/soc/sh/rcar/mix.c ++++ b/sound/soc/sh/rcar/mix.c +@@ -146,7 +146,11 @@ static int rsnd_mix_init(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) + { +- rsnd_mod_power_on(mod); ++ int ret; ++ ++ ret = rsnd_mod_power_on(mod); ++ if (ret < 0) ++ return ret; + + rsnd_mix_activation(mod); + +diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c +index 0ea84ae57c6a..f832165e46bc 100644 +--- a/sound/soc/sh/rcar/src.c ++++ b/sound/soc/sh/rcar/src.c +@@ -463,11 +463,14 @@ static int rsnd_src_init(struct rsnd_mod *mod, + struct rsnd_priv *priv) + { + struct rsnd_src *src = rsnd_mod_to_src(mod); ++ int ret; + + /* reset sync convert_rate */ + src->sync.val = 0; + +- rsnd_mod_power_on(mod); ++ ret = rsnd_mod_power_on(mod); ++ if (ret < 0) ++ return ret; + + rsnd_src_activation(mod); + +diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c +index 43c5e27dc5c8..7ade6c5ed96f 100644 +--- a/sound/soc/sh/rcar/ssi.c ++++ b/sound/soc/sh/rcar/ssi.c +@@ -480,7 +480,9 @@ static int rsnd_ssi_init(struct rsnd_mod *mod, + + ssi->usrcnt++; + +- rsnd_mod_power_on(mod); ++ ret = rsnd_mod_power_on(mod); ++ if (ret < 0) ++ return ret; + + rsnd_ssi_config_init(mod, io); + +-- +2.35.3 + diff --git a/patches.suse/ASoC-tas2764-Allow-mono-streams.patch b/patches.suse/ASoC-tas2764-Allow-mono-streams.patch new file mode 100644 index 0000000..16b3be8 --- /dev/null +++ b/patches.suse/ASoC-tas2764-Allow-mono-streams.patch @@ -0,0 +1,43 @@ +From 23204d928a27146d13e11c9383632775345ecca8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Martin=20Povi=C5=A1er?= +Date: Thu, 25 Aug 2022 16:02:37 +0200 +Subject: [PATCH] ASoC: tas2764: Allow mono streams +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 23204d928a27146d13e11c9383632775345ecca8 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The part is a mono speaker amp, but it can do downmix and switch between +left and right channel, so the right channel range is 1 to 2. + +(This mirrors commit bf54d97a835d ("ASoC: tas2770: Allow mono streams") +which was a fix to the tas2770 driver.) + +Fixes: 827ed8a0fa50 ("ASoC: tas2764: Add the driver for the TAS2764") +Signed-off-by: Martin Povišer +Link: https://lore.kernel.org/r/20220825140241.53963-2-povik+lin@cutebit.org +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/tas2764.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/codecs/tas2764.c b/sound/soc/codecs/tas2764.c +index 846d9d3ecc9d..0df5d975c3c9 100644 +--- a/sound/soc/codecs/tas2764.c ++++ b/sound/soc/codecs/tas2764.c +@@ -485,7 +485,7 @@ static struct snd_soc_dai_driver tas2764_dai_driver[] = { + .id = 0, + .playback = { + .stream_name = "ASI1 Playback", +- .channels_min = 2, ++ .channels_min = 1, + .channels_max = 2, + .rates = TAS2764_RATES, + .formats = TAS2764_FORMATS, +-- +2.35.3 + diff --git a/patches.suse/ASoC-tas2764-Drop-conflicting-set_bias_level-power-s.patch b/patches.suse/ASoC-tas2764-Drop-conflicting-set_bias_level-power-s.patch new file mode 100644 index 0000000..660832b --- /dev/null +++ b/patches.suse/ASoC-tas2764-Drop-conflicting-set_bias_level-power-s.patch @@ -0,0 +1,83 @@ +From 09273f38832406db19a8907a934687cc10660a6b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Martin=20Povi=C5=A1er?= +Date: Thu, 25 Aug 2022 16:02:38 +0200 +Subject: [PATCH] ASoC: tas2764: Drop conflicting set_bias_level power setting +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 09273f38832406db19a8907a934687cc10660a6b +Patch-mainline: v6.1-rc1 +References: git-fixes + +The driver is setting the PWR_CTRL field in both the set_bias_level +callback and on DAPM events of the DAC widget (and also in the +mute_stream method). Drop the set_bias_level callback altogether as the +power setting it does is in conflict with the other code paths. + +(This mirrors commit c8a6ae3fe1c8 ("ASoC: tas2770: Drop conflicting +set_bias_level power setting") which was a fix to the tas2770 driver.) + +Fixes: 827ed8a0fa50 ("ASoC: tas2764: Add the driver for the TAS2764") +Signed-off-by: Martin Povišer +Link: https://lore.kernel.org/r/20220825140241.53963-3-povik+lin@cutebit.org +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/tas2764.c | 33 --------------------------------- + 1 file changed, 33 deletions(-) + +diff --git a/sound/soc/codecs/tas2764.c b/sound/soc/codecs/tas2764.c +index 0df5d975c3c9..f4ac6edefdc0 100644 +--- a/sound/soc/codecs/tas2764.c ++++ b/sound/soc/codecs/tas2764.c +@@ -50,38 +50,6 @@ static void tas2764_reset(struct tas2764_priv *tas2764) + usleep_range(1000, 2000); + } + +-static int tas2764_set_bias_level(struct snd_soc_component *component, +- enum snd_soc_bias_level level) +-{ +- struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component); +- +- switch (level) { +- case SND_SOC_BIAS_ON: +- snd_soc_component_update_bits(component, TAS2764_PWR_CTRL, +- TAS2764_PWR_CTRL_MASK, +- TAS2764_PWR_CTRL_ACTIVE); +- break; +- case SND_SOC_BIAS_STANDBY: +- case SND_SOC_BIAS_PREPARE: +- snd_soc_component_update_bits(component, TAS2764_PWR_CTRL, +- TAS2764_PWR_CTRL_MASK, +- TAS2764_PWR_CTRL_MUTE); +- break; +- case SND_SOC_BIAS_OFF: +- snd_soc_component_update_bits(component, TAS2764_PWR_CTRL, +- TAS2764_PWR_CTRL_MASK, +- TAS2764_PWR_CTRL_SHUTDOWN); +- break; +- +- default: +- dev_err(tas2764->dev, +- "wrong power level setting %d\n", level); +- return -EINVAL; +- } +- +- return 0; +-} +- + #ifdef CONFIG_PM + static int tas2764_codec_suspend(struct snd_soc_component *component) + { +@@ -549,7 +517,6 @@ static const struct snd_soc_component_driver soc_component_driver_tas2764 = { + .probe = tas2764_codec_probe, + .suspend = tas2764_codec_suspend, + .resume = tas2764_codec_resume, +- .set_bias_level = tas2764_set_bias_level, + .controls = tas2764_snd_controls, + .num_controls = ARRAY_SIZE(tas2764_snd_controls), + .dapm_widgets = tas2764_dapm_widgets, +-- +2.35.3 + diff --git a/patches.suse/ASoC-tas2764-Fix-mute-unmute.patch b/patches.suse/ASoC-tas2764-Fix-mute-unmute.patch new file mode 100644 index 0000000..865bfa4 --- /dev/null +++ b/patches.suse/ASoC-tas2764-Fix-mute-unmute.patch @@ -0,0 +1,139 @@ +From f5ad67f13623548e5aff847f89700c178aaf2a98 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Martin=20Povi=C5=A1er?= +Date: Thu, 25 Aug 2022 16:02:39 +0200 +Subject: [PATCH] ASoC: tas2764: Fix mute/unmute +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: f5ad67f13623548e5aff847f89700c178aaf2a98 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Because the PWR_CTRL field is modeled as the power state of the DAC +widget, and at the same time it is used to implement mute/unmute, we +need some additional book-keeping to have the right end result no matter +the sequence of calls. Without this fix, one permanently mutes an +ongoing stream by toggling the associated speaker pin control. + +(This mirrors commit 1e5907bcb3a3 ("ASoC: tas2770: Fix handling of +mute/unmute") which was a fix to the tas2770 driver.) + +Fixes: 827ed8a0fa50 ("ASoC: tas2764: Add the driver for the TAS2764") +Signed-off-by: Martin Povišer +Link: https://lore.kernel.org/r/20220825140241.53963-4-povik+lin@cutebit.org +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/tas2764.c | 57 +++++++++++++++++++++----------------- + 1 file changed, 32 insertions(+), 25 deletions(-) + +diff --git a/sound/soc/codecs/tas2764.c b/sound/soc/codecs/tas2764.c +index f4ac6edefdc0..39902f77a2e0 100644 +--- a/sound/soc/codecs/tas2764.c ++++ b/sound/soc/codecs/tas2764.c +@@ -34,6 +34,9 @@ struct tas2764_priv { + + int v_sense_slot; + int i_sense_slot; ++ ++ bool dac_powered; ++ bool unmuted; + }; + + static void tas2764_reset(struct tas2764_priv *tas2764) +@@ -50,6 +53,26 @@ static void tas2764_reset(struct tas2764_priv *tas2764) + usleep_range(1000, 2000); + } + ++static int tas2764_update_pwr_ctrl(struct tas2764_priv *tas2764) ++{ ++ struct snd_soc_component *component = tas2764->component; ++ unsigned int val; ++ int ret; ++ ++ if (tas2764->dac_powered) ++ val = tas2764->unmuted ? ++ TAS2764_PWR_CTRL_ACTIVE : TAS2764_PWR_CTRL_MUTE; ++ else ++ val = TAS2764_PWR_CTRL_SHUTDOWN; ++ ++ ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL, ++ TAS2764_PWR_CTRL_MASK, val); ++ if (ret < 0) ++ return ret; ++ ++ return 0; ++} ++ + #ifdef CONFIG_PM + static int tas2764_codec_suspend(struct snd_soc_component *component) + { +@@ -82,9 +105,7 @@ static int tas2764_codec_resume(struct snd_soc_component *component) + usleep_range(1000, 2000); + } + +- ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL, +- TAS2764_PWR_CTRL_MASK, +- TAS2764_PWR_CTRL_ACTIVE); ++ ret = tas2764_update_pwr_ctrl(tas2764); + + if (ret < 0) + return ret; +@@ -118,14 +139,12 @@ static int tas2764_dac_event(struct snd_soc_dapm_widget *w, + + switch (event) { + case SND_SOC_DAPM_POST_PMU: +- ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL, +- TAS2764_PWR_CTRL_MASK, +- TAS2764_PWR_CTRL_MUTE); ++ tas2764->dac_powered = true; ++ ret = tas2764_update_pwr_ctrl(tas2764); + break; + case SND_SOC_DAPM_PRE_PMD: +- ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL, +- TAS2764_PWR_CTRL_MASK, +- TAS2764_PWR_CTRL_SHUTDOWN); ++ tas2764->dac_powered = false; ++ ret = tas2764_update_pwr_ctrl(tas2764); + break; + default: + dev_err(tas2764->dev, "Unsupported event\n"); +@@ -170,17 +189,11 @@ static const struct snd_soc_dapm_route tas2764_audio_map[] = { + + static int tas2764_mute(struct snd_soc_dai *dai, int mute, int direction) + { +- struct snd_soc_component *component = dai->component; +- int ret; +- +- ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL, +- TAS2764_PWR_CTRL_MASK, +- mute ? TAS2764_PWR_CTRL_MUTE : 0); ++ struct tas2764_priv *tas2764 = ++ snd_soc_component_get_drvdata(dai->component); + +- if (ret < 0) +- return ret; +- +- return 0; ++ tas2764->unmuted = !mute; ++ return tas2764_update_pwr_ctrl(tas2764); + } + + static int tas2764_set_bitwidth(struct tas2764_priv *tas2764, int bitwidth) +@@ -494,12 +507,6 @@ static int tas2764_codec_probe(struct snd_soc_component *component) + if (ret < 0) + return ret; + +- ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL, +- TAS2764_PWR_CTRL_MASK, +- TAS2764_PWR_CTRL_MUTE); +- if (ret < 0) +- return ret; +- + return 0; + } + +-- +2.35.3 + diff --git a/patches.suse/ASoC-tas2770-Reinit-regcache-on-reset.patch b/patches.suse/ASoC-tas2770-Reinit-regcache-on-reset.patch new file mode 100644 index 0000000..fea14c5 --- /dev/null +++ b/patches.suse/ASoC-tas2770-Reinit-regcache-on-reset.patch @@ -0,0 +1,50 @@ +From 0a0342ede303fc420f3a388e1ae82da3ae8ff6bd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Martin=20Povi=C5=A1er?= +Date: Mon, 19 Sep 2022 19:34:53 +0200 +Subject: [PATCH] ASoC: tas2770: Reinit regcache on reset +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 0a0342ede303fc420f3a388e1ae82da3ae8ff6bd +Patch-mainline: v6.0 +References: git-fixes + +On probe of the ASoC component, the device is reset but the regcache is +retained. This means the regcache gets out of sync if the codec is +rebound to a sound card for a second time. Fix it by reinitializing the +regcache to defaults after the device is reset. + +Fixes: b0bcbe615756 ("ASoC: tas2770: Fix calling reset in probe") +Signed-off-by: Martin Povišer +Link: https://lore.kernel.org/r/20220919173453.84292-1-povik+lin@cutebit.org +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/tas2770.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/sound/soc/codecs/tas2770.c b/sound/soc/codecs/tas2770.c +index bb653b664146..b6765235a4b3 100644 +--- a/sound/soc/codecs/tas2770.c ++++ b/sound/soc/codecs/tas2770.c +@@ -495,6 +495,8 @@ static struct snd_soc_dai_driver tas2770_dai_driver[] = { + }, + }; + ++static const struct regmap_config tas2770_i2c_regmap; ++ + static int tas2770_codec_probe(struct snd_soc_component *component) + { + struct tas2770_priv *tas2770 = +@@ -508,6 +510,7 @@ static int tas2770_codec_probe(struct snd_soc_component *component) + } + + tas2770_reset(tas2770); ++ regmap_reinit_cache(tas2770->regmap, &tas2770_i2c_regmap); + + return 0; + } +-- +2.35.3 + diff --git a/patches.suse/ASoC-wcd9335-fix-order-of-Slimbus-unprepare-disable.patch b/patches.suse/ASoC-wcd9335-fix-order-of-Slimbus-unprepare-disable.patch new file mode 100644 index 0000000..a44f96e --- /dev/null +++ b/patches.suse/ASoC-wcd9335-fix-order-of-Slimbus-unprepare-disable.patch @@ -0,0 +1,43 @@ +From ea8ef003aa53ad23e7705c5cab1c4e664faa6c79 Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +Date: Wed, 21 Sep 2022 16:53:53 +0200 +Subject: [PATCH] ASoC: wcd9335: fix order of Slimbus unprepare/disable +Git-commit: ea8ef003aa53ad23e7705c5cab1c4e664faa6c79 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Slimbus streams are first prepared and then enabled, so the cleanup path +should reverse it. The unprepare sets stream->num_ports to 0 and frees +the stream->ports. Calling disable after unprepare was not really +effective (channels was not deactivated) and could lead to further +issues due to making transfers on unprepared stream. + +Fixes: 20aedafdf492 ("ASoC: wcd9335: add support to wcd9335 codec") +Cc: +Signed-off-by: Krzysztof Kozlowski +Reviewed-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20220921145354.1683791-1-krzysztof.kozlowski@linaro.org +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/wcd9335.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c +index beeeb35e8032..8a1f741de948 100644 +--- a/sound/soc/codecs/wcd9335.c ++++ b/sound/soc/codecs/wcd9335.c +@@ -1974,8 +1974,8 @@ static int wcd9335_trigger(struct snd_pcm_substream *substream, int cmd, + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: +- slim_stream_unprepare(dai_data->sruntime); + slim_stream_disable(dai_data->sruntime); ++ slim_stream_unprepare(dai_data->sruntime); + break; + default: + break; +-- +2.35.3 + diff --git a/patches.suse/ASoC-wcd934x-fix-order-of-Slimbus-unprepare-disable.patch b/patches.suse/ASoC-wcd934x-fix-order-of-Slimbus-unprepare-disable.patch new file mode 100644 index 0000000..a4c6fdc --- /dev/null +++ b/patches.suse/ASoC-wcd934x-fix-order-of-Slimbus-unprepare-disable.patch @@ -0,0 +1,43 @@ +From e96bca7eaa5747633ec638b065630ff83728982a Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +Date: Wed, 21 Sep 2022 16:53:54 +0200 +Subject: [PATCH] ASoC: wcd934x: fix order of Slimbus unprepare/disable +Git-commit: e96bca7eaa5747633ec638b065630ff83728982a +Patch-mainline: v6.1-rc1 +References: git-fixes + +Slimbus streams are first prepared and then enabled, so the cleanup path +should reverse it. The unprepare sets stream->num_ports to 0 and frees +the stream->ports. Calling disable after unprepare was not really +effective (channels was not deactivated) and could lead to further +issues due to making transfers on unprepared stream. + +Fixes: a61f3b4f476e ("ASoC: wcd934x: add support to wcd9340/wcd9341 codec") +Cc: +Signed-off-by: Krzysztof Kozlowski +Reviewed-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20220921145354.1683791-2-krzysztof.kozlowski@linaro.org +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/wcd934x.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/codecs/wcd934x.c b/sound/soc/codecs/wcd934x.c +index f56907d0942d..28175c746b9a 100644 +--- a/sound/soc/codecs/wcd934x.c ++++ b/sound/soc/codecs/wcd934x.c +@@ -1913,8 +1913,8 @@ static int wcd934x_trigger(struct snd_pcm_substream *substream, int cmd, + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: +- slim_stream_unprepare(dai_data->sruntime); + slim_stream_disable(dai_data->sruntime); ++ slim_stream_unprepare(dai_data->sruntime); + break; + default: + break; +-- +2.35.3 + diff --git a/patches.suse/ASoC-wm5102-Fix-PM-disable-depth-imbalance-in-wm5102.patch b/patches.suse/ASoC-wm5102-Fix-PM-disable-depth-imbalance-in-wm5102.patch new file mode 100644 index 0000000..d590300 --- /dev/null +++ b/patches.suse/ASoC-wm5102-Fix-PM-disable-depth-imbalance-in-wm5102.patch @@ -0,0 +1,51 @@ +From fcbb60820cd3008bb44334a0395e5e57ccb77329 Mon Sep 17 00:00:00 2001 +From: Zhang Qilong +Date: Thu, 29 Sep 2022 00:01:15 +0800 +Subject: [PATCH] ASoC: wm5102: Fix PM disable depth imbalance in wm5102_probe +Git-commit: fcbb60820cd3008bb44334a0395e5e57ccb77329 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The pm_runtime_enable will increase power disable depth. Thus +a pairing decrement is needed on the error handling path to +keep it balanced according to context. We fix it by moving +pm_runtime_enable to the endding of wm5102_probe. + +Fixes:93e8791dd34ca ("ASoC: wm5102: Initial driver") + +Signed-off-by: Zhang Qilong +Link: https://lore.kernel.org/r/20220928160116.125020-4-zhangqilong3@huawei.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/wm5102.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c +index af7d324e3352..c09c9ac51b3e 100644 +--- a/sound/soc/codecs/wm5102.c ++++ b/sound/soc/codecs/wm5102.c +@@ -2099,9 +2099,6 @@ static int wm5102_probe(struct platform_device *pdev) + regmap_update_bits(arizona->regmap, wm5102_digital_vu[i], + WM5102_DIG_VU, WM5102_DIG_VU); + +- pm_runtime_enable(&pdev->dev); +- pm_runtime_idle(&pdev->dev); +- + ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, + "ADSP2 Compressed IRQ", wm5102_adsp2_irq, + wm5102); +@@ -2134,6 +2131,9 @@ static int wm5102_probe(struct platform_device *pdev) + goto err_spk_irqs; + } + ++ pm_runtime_enable(&pdev->dev); ++ pm_runtime_idle(&pdev->dev); ++ + return ret; + + err_spk_irqs: +-- +2.35.3 + diff --git a/patches.suse/ASoC-wm5110-Fix-PM-disable-depth-imbalance-in-wm5110.patch b/patches.suse/ASoC-wm5110-Fix-PM-disable-depth-imbalance-in-wm5110.patch new file mode 100644 index 0000000..7606834 --- /dev/null +++ b/patches.suse/ASoC-wm5110-Fix-PM-disable-depth-imbalance-in-wm5110.patch @@ -0,0 +1,51 @@ +From 86b46bf1feb83898d89a2b4a8d08d21e9ea277a7 Mon Sep 17 00:00:00 2001 +From: Zhang Qilong +Date: Thu, 29 Sep 2022 00:01:14 +0800 +Subject: [PATCH] ASoC: wm5110: Fix PM disable depth imbalance in wm5110_probe +Git-commit: 86b46bf1feb83898d89a2b4a8d08d21e9ea277a7 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The pm_runtime_enable will increase power disable depth. Thus +a pairing decrement is needed on the error handling path to +keep it balanced according to context. We fix it by moving +pm_runtime_enable to the endding of wm5110_probe. + +Fixes:5c6af635fd772 ("ASoC: wm5110: Add audio CODEC driver") + +Signed-off-by: Zhang Qilong +Link: https://lore.kernel.org/r/20220928160116.125020-3-zhangqilong3@huawei.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/wm5110.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c +index f3f4a10bf0f7..fc634c995834 100644 +--- a/sound/soc/codecs/wm5110.c ++++ b/sound/soc/codecs/wm5110.c +@@ -2457,9 +2457,6 @@ static int wm5110_probe(struct platform_device *pdev) + regmap_update_bits(arizona->regmap, wm5110_digital_vu[i], + WM5110_DIG_VU, WM5110_DIG_VU); + +- pm_runtime_enable(&pdev->dev); +- pm_runtime_idle(&pdev->dev); +- + ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, + "ADSP2 Compressed IRQ", wm5110_adsp2_irq, + wm5110); +@@ -2492,6 +2489,9 @@ static int wm5110_probe(struct platform_device *pdev) + goto err_spk_irqs; + } + ++ pm_runtime_enable(&pdev->dev); ++ pm_runtime_idle(&pdev->dev); ++ + return ret; + + err_spk_irqs: +-- +2.35.3 + diff --git a/patches.suse/ASoC-wm8997-Fix-PM-disable-depth-imbalance-in-wm8997.patch b/patches.suse/ASoC-wm8997-Fix-PM-disable-depth-imbalance-in-wm8997.patch new file mode 100644 index 0000000..9b13d18 --- /dev/null +++ b/patches.suse/ASoC-wm8997-Fix-PM-disable-depth-imbalance-in-wm8997.patch @@ -0,0 +1,51 @@ +From 41a736ac20602f64773e80f0f5b32cde1830a44a Mon Sep 17 00:00:00 2001 +From: Zhang Qilong +Date: Thu, 29 Sep 2022 00:01:13 +0800 +Subject: [PATCH] ASoC: wm8997: Fix PM disable depth imbalance in wm8997_probe +Git-commit: 41a736ac20602f64773e80f0f5b32cde1830a44a +Patch-mainline: v6.1-rc1 +References: git-fixes + +The pm_runtime_enable will increase power disable depth. Thus +a pairing decrement is needed on the error handling path to +keep it balanced according to context. We fix it by moving +pm_runtime_enable to the endding of wm8997_probe + +Fixes:40843aea5a9bd ("ASoC: wm8997: Initial CODEC driver") + +Signed-off-by: Zhang Qilong +Link: https://lore.kernel.org/r/20220928160116.125020-2-zhangqilong3@huawei.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/wm8997.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c +index 210ad662fc26..77136a521605 100644 +--- a/sound/soc/codecs/wm8997.c ++++ b/sound/soc/codecs/wm8997.c +@@ -1161,9 +1161,6 @@ static int wm8997_probe(struct platform_device *pdev) + regmap_update_bits(arizona->regmap, wm8997_digital_vu[i], + WM8997_DIG_VU, WM8997_DIG_VU); + +- pm_runtime_enable(&pdev->dev); +- pm_runtime_idle(&pdev->dev); +- + arizona_init_common(arizona); + + ret = arizona_init_vol_limit(arizona); +@@ -1182,6 +1179,9 @@ static int wm8997_probe(struct platform_device *pdev) + goto err_spk_irqs; + } + ++ pm_runtime_enable(&pdev->dev); ++ pm_runtime_idle(&pdev->dev); ++ + return ret; + + err_spk_irqs: +-- +2.35.3 + diff --git a/patches.suse/ASoC-wm_adsp-Add-support-for-toggle-preloaders.patch b/patches.suse/ASoC-wm_adsp-Add-support-for-toggle-preloaders.patch new file mode 100644 index 0000000..af1600a --- /dev/null +++ b/patches.suse/ASoC-wm_adsp-Add-support-for-toggle-preloaders.patch @@ -0,0 +1,81 @@ +From ba235634b138cd9d012dbe983e7920481211e132 Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Wed, 5 Jan 2022 11:30:24 +0000 +Subject: [PATCH] ASoC: wm_adsp: Add support for "toggle" preloaders +Git-commit: ba235634b138cd9d012dbe983e7920481211e132 +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +In the case a device can support retaining the firmware memory across +low power states it is useful for the preloader widget to only power up +whilst actually loading/unloading the core, as opposed to the normal +operation where the widget is powered for the entire time a firmware is +preloaded onto the core. Add support for this mode and a flag to enable +it. + +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20220105113026.18955-7-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/wm_adsp.c | 14 +++++++++++--- + sound/soc/codecs/wm_adsp.h | 8 ++++++++ + 2 files changed, 19 insertions(+), 3 deletions(-) + +diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c +index c3112bf23866..f3672e3d1703 100644 +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -896,11 +896,12 @@ int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol, + struct wm_adsp *dsp = &dsps[mc->shift - 1]; + char preload[32]; + +- snprintf(preload, ARRAY_SIZE(preload), "%s Preload", dsp->cs_dsp.name); ++ if (dsp->preloaded == ucontrol->value.integer.value[0]) ++ return 0; + +- dsp->preloaded = ucontrol->value.integer.value[0]; ++ snprintf(preload, ARRAY_SIZE(preload), "%s Preload", dsp->cs_dsp.name); + +- if (ucontrol->value.integer.value[0]) ++ if (ucontrol->value.integer.value[0] || dsp->toggle_preload) + snd_soc_component_force_enable_pin(component, preload); + else + snd_soc_component_disable_pin(component, preload); +@@ -909,6 +910,13 @@ int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol, + + flush_work(&dsp->boot_work); + ++ dsp->preloaded = ucontrol->value.integer.value[0]; ++ ++ if (dsp->toggle_preload) { ++ snd_soc_component_disable_pin(component, preload); ++ snd_soc_dapm_sync(dapm); ++ } ++ + return 0; + } + EXPORT_SYMBOL_GPL(wm_adsp2_preloader_put); +diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h +index 0e2f113bd342..7f4fabbc6ad3 100644 +--- a/sound/soc/codecs/wm_adsp.h ++++ b/sound/soc/codecs/wm_adsp.h +@@ -41,6 +41,14 @@ struct wm_adsp { + + struct list_head compr_list; + struct list_head buffer_list; ++ ++ /* ++ * Flag indicating the preloader widget only needs power toggled ++ * on state change rather than held on for the duration of the ++ * preload, useful for devices that can retain firmware memory ++ * across power down. ++ */ ++ bool toggle_preload; + }; + + #define WM_ADSP1(wname, num) \ +-- +2.35.3 + diff --git a/patches.suse/ASoC-wm_adsp-Add-trace-caps-to-speaker-protection-FW.patch b/patches.suse/ASoC-wm_adsp-Add-trace-caps-to-speaker-protection-FW.patch new file mode 100644 index 0000000..480526f --- /dev/null +++ b/patches.suse/ASoC-wm_adsp-Add-trace-caps-to-speaker-protection-FW.patch @@ -0,0 +1,52 @@ +From c55b3e46cb99a8342cad9c1a35485bfe15187832 Mon Sep 17 00:00:00 2001 +From: Vlad Karpovich +Date: Thu, 10 Feb 2022 17:20:53 +0000 +Subject: [PATCH] ASoC: wm_adsp: Add trace caps to speaker protection FW +Git-commit: c55b3e46cb99a8342cad9c1a35485bfe15187832 +Patch-mainline: v5.18-rc1 +References: bsc#1203699 + +Enable access to the speaker protection firmware debug stream +using compress stream API and lower minimum fragment size to +16 words. + +Signed-off-by: Vlad Karpovich +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20220210172053.22782-3-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/wm_adsp.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c +index 8b9726f400a9..c8c8338cb401 100644 +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -180,7 +180,7 @@ struct wm_adsp_compr { + + #define WM_ADSP_MIN_FRAGMENTS 1 + #define WM_ADSP_MAX_FRAGMENTS 256 +-#define WM_ADSP_MIN_FRAGMENT_SIZE (64 * CS_DSP_DATA_WORD_SIZE) ++#define WM_ADSP_MIN_FRAGMENT_SIZE (16 * CS_DSP_DATA_WORD_SIZE) + #define WM_ADSP_MAX_FRAGMENT_SIZE (4096 * CS_DSP_DATA_WORD_SIZE) + + #define WM_ADSP_ALG_XM_STRUCT_MAGIC 0x49aec7 +@@ -296,7 +296,12 @@ static const struct { + .num_caps = ARRAY_SIZE(trace_caps), + .caps = trace_caps, + }, +- [WM_ADSP_FW_SPK_PROT] = { .file = "spk-prot" }, ++ [WM_ADSP_FW_SPK_PROT] = { ++ .file = "spk-prot", ++ .compr_direction = SND_COMPRESS_CAPTURE, ++ .num_caps = ARRAY_SIZE(trace_caps), ++ .caps = trace_caps, ++ }, + [WM_ADSP_FW_SPK_CALI] = { .file = "spk-cali" }, + [WM_ADSP_FW_SPK_DIAG] = { .file = "spk-diag" }, + [WM_ADSP_FW_MISC] = { .file = "misc" }, +-- +2.35.3 + diff --git a/patches.suse/ASoC-wm_adsp-Cancel-ongoing-work-when-removing-contr.patch b/patches.suse/ASoC-wm_adsp-Cancel-ongoing-work-when-removing-contr.patch new file mode 100644 index 0000000..74cba8e --- /dev/null +++ b/patches.suse/ASoC-wm_adsp-Cancel-ongoing-work-when-removing-contr.patch @@ -0,0 +1,104 @@ +From df6c505c129a114da783ae82b9f0b4d2d4691c91 Mon Sep 17 00:00:00 2001 +From: Simon Trimmer +Date: Mon, 13 Sep 2021 17:00:45 +0100 +Subject: [PATCH] ASoC: wm_adsp: Cancel ongoing work when removing controls +Git-commit: df6c505c129a114da783ae82b9f0b4d2d4691c91 +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +Removes wm_adsp_ctl_work and integrates the work_struct into +wm_coeff_ctl so it may be referenced. + +Signed-off-by: Simon Trimmer +Link: https://lore.kernel.org/r/20210913160057.103842-5-simont@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/wm_adsp.c | 34 +++++++++------------------------- + 1 file changed, 9 insertions(+), 25 deletions(-) + +diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c +index 9c3d4b96fd7c..c1b5ea3b5718 100644 +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -613,6 +613,7 @@ struct wm_coeff_ctl { + struct soc_bytes_ext bytes_ext; + unsigned int flags; + unsigned int type; ++ struct work_struct work; + }; + + static const char *wm_adsp_mem_region_name(unsigned int type) +@@ -1240,12 +1241,6 @@ static int wm_coeff_get_acked(struct snd_kcontrol *kcontrol, + return 0; + } + +-struct wmfw_ctl_work { +- struct wm_adsp *dsp; +- struct wm_coeff_ctl *ctl; +- struct work_struct work; +-}; +- + static unsigned int wmfw_convert_flags(unsigned int in, unsigned int len) + { + unsigned int out, rd, wr, vol; +@@ -1394,16 +1389,17 @@ static void wm_adsp_signal_event_controls(struct wm_adsp *dsp, + + static void wm_adsp_ctl_work(struct work_struct *work) + { +- struct wmfw_ctl_work *ctl_work = container_of(work, +- struct wmfw_ctl_work, +- work); ++ struct wm_coeff_ctl *ctl = container_of(work, ++ struct wm_coeff_ctl, ++ work); + +- wmfw_add_ctl(ctl_work->dsp, ctl_work->ctl); +- kfree(ctl_work); ++ wmfw_add_ctl(ctl->dsp, ctl); + } + + static void wm_adsp_free_ctl_blk(struct wm_coeff_ctl *ctl) + { ++ cancel_work_sync(&ctl->work); ++ + kfree(ctl->cache); + kfree(ctl->name); + kfree(ctl->subname); +@@ -1417,7 +1413,6 @@ static int wm_adsp_create_control(struct wm_adsp *dsp, + unsigned int flags, unsigned int type) + { + struct wm_coeff_ctl *ctl; +- struct wmfw_ctl_work *ctl_work; + char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; + const char *region_name; + int ret; +@@ -1513,22 +1508,11 @@ static int wm_adsp_create_control(struct wm_adsp *dsp, + if (flags & WMFW_CTL_FLAG_SYS) + return 0; + +- ctl_work = kzalloc(sizeof(*ctl_work), GFP_KERNEL); +- if (!ctl_work) { +- ret = -ENOMEM; +- goto err_list_del; +- } +- +- ctl_work->dsp = dsp; +- ctl_work->ctl = ctl; +- INIT_WORK(&ctl_work->work, wm_adsp_ctl_work); +- schedule_work(&ctl_work->work); ++ INIT_WORK(&ctl->work, wm_adsp_ctl_work); ++ schedule_work(&ctl->work); + + return 0; + +-err_list_del: +- list_del(&ctl->list); +- kfree(ctl->cache); + err_ctl_subname: + kfree(ctl->subname); + err_ctl_name: +-- +2.35.3 + diff --git a/patches.suse/ASoC-wm_adsp-Compressed-stream-DSP-memory-structs-sh.patch b/patches.suse/ASoC-wm_adsp-Compressed-stream-DSP-memory-structs-sh.patch new file mode 100644 index 0000000..982332c --- /dev/null +++ b/patches.suse/ASoC-wm_adsp-Compressed-stream-DSP-memory-structs-sh.patch @@ -0,0 +1,70 @@ +From 353bb6a5f2ac495f289b7c7a528c7d134c9a8ec4 Mon Sep 17 00:00:00 2001 +From: Simon Trimmer +Date: Wed, 9 Mar 2022 13:00:17 +0000 +Subject: [PATCH] ASoC: wm_adsp: Compressed stream DSP memory structs should be __packed +Git-commit: 353bb6a5f2ac495f289b7c7a528c7d134c9a8ec4 +Patch-mainline: v5.19-rc1 +References: bsc#1203699 + +The compressed stream code has a bunch of structs that are used to +represent DSP memory but have not been marked __packed. This isn't +safe, they could get padded on a 64-bit build. + +Signed-off-by: Simon Trimmer +Link: https://lore.kernel.org/r/20220309130017.2816-1-simont@opensource.cirrus.com +Acked-by: Charles Keepax +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/wm_adsp.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c +index 0582585236a2..5a57bb04a0ae 100644 +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -97,13 +97,13 @@ struct wm_adsp_system_config_xm_hdr { + __be32 wdma[8]; + __be32 build_job_name[3]; + __be32 build_job_number; +-}; ++} __packed; + + struct wm_halo_system_config_xm_hdr { + __be32 halo_heartbeat; + __be32 build_job_name[3]; + __be32 build_job_number; +-}; ++} __packed; + + struct wm_adsp_alg_xm_struct { + __be32 magic; +@@ -114,13 +114,13 @@ struct wm_adsp_alg_xm_struct { + __be32 high_water_mark; + __be32 low_water_mark; + __be64 smoothed_power; +-}; ++} __packed; + + struct wm_adsp_host_buf_coeff_v1 { + __be32 host_buf_ptr; /* Host buffer pointer */ + __be32 versions; /* Version numbers */ + __be32 name[4]; /* The buffer name */ +-}; ++} __packed; + + struct wm_adsp_buffer { + __be32 buf1_base; /* Base addr of first buffer area */ +@@ -141,7 +141,7 @@ struct wm_adsp_buffer { + __be32 min_free; /* min free space since stream start */ + __be32 blocks_written[2]; /* total blocks written (64 bit) */ + __be32 words_written[2]; /* total words written (64 bit) */ +-}; ++} __packed; + + struct wm_adsp_compr; + +-- +2.35.3 + diff --git a/patches.suse/ASoC-wm_adsp-Correct-control-read-size-when-parsing-.patch b/patches.suse/ASoC-wm_adsp-Correct-control-read-size-when-parsing-.patch new file mode 100644 index 0000000..93d4a65 --- /dev/null +++ b/patches.suse/ASoC-wm_adsp-Correct-control-read-size-when-parsing-.patch @@ -0,0 +1,47 @@ +From a887f9c7a4d37a8e874ba8415a42a92a1b5139fc Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Thu, 10 Feb 2022 17:20:51 +0000 +Subject: [PATCH] ASoC: wm_adsp: Correct control read size when parsing compressed buffer +Git-commit: a887f9c7a4d37a8e874ba8415a42a92a1b5139fc +Patch-mainline: v5.17-rc5 +References: bsc#1203699 + +When parsing the compressed stream the whole buffer descriptor is +now read in a single cs_dsp_coeff_read_ctrl; on older firmwares +this descriptor is just 4 bytes but on more modern firmwares it is +24 bytes. The current code reads the full 24 bytes regardless, this +was working but reading junk for the last 20 bytes. However commit +f444da38ac92 ("firmware: cs_dsp: Add offset to cs_dsp read/write") +added a size check into cs_dsp_coeff_read_ctrl, causing the older +firmwares to now return an error. + +Update the code to only read the amount of data appropriate for +the firmware loaded. + +Fixes: 04ae08596737 ("ASoC: wm_adsp: Switch to using wm_coeff_read_ctrl for compressed buffers") +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20220210172053.22782-1-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/wm_adsp.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c +index f3672e3d1703..0582585236a2 100644 +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -1441,7 +1441,8 @@ static int wm_adsp_buffer_parse_coeff(struct cs_dsp_coeff_ctl *cs_ctl) + int ret, i; + + for (i = 0; i < 5; ++i) { +- ret = cs_dsp_coeff_read_ctrl(cs_ctl, 0, &coeff_v1, sizeof(coeff_v1)); ++ ret = cs_dsp_coeff_read_ctrl(cs_ctl, 0, &coeff_v1, ++ min(cs_ctl->len, sizeof(coeff_v1))); + if (ret < 0) + return ret; + +-- +2.35.3 + diff --git a/patches.suse/ASoC-wm_adsp-Expand-firmware-loading-search-options.patch b/patches.suse/ASoC-wm_adsp-Expand-firmware-loading-search-options.patch new file mode 100644 index 0000000..1d3d070 --- /dev/null +++ b/patches.suse/ASoC-wm_adsp-Expand-firmware-loading-search-options.patch @@ -0,0 +1,215 @@ +From b6b62d942bbc4d926bcf3799ea3bcaeb105fd04f Mon Sep 17 00:00:00 2001 +From: Simon Trimmer +Date: Thu, 3 Mar 2022 15:50:16 +0000 +Subject: [PATCH] ASoC: wm_adsp: Expand firmware loading search options +Git-commit: b6b62d942bbc4d926bcf3799ea3bcaeb105fd04f +Patch-mainline: v5.18-rc1 +References: bsc#1203699 + +The parts supported by this driver can have product-specific +firmware and tunings files. Typically these have been used on +embedded systems where the manufacturer is responsible for +installing the correct product-specific firmware files into +/lib/firmware. However, the linux-firmware repository places all +available firmwares into /lib/firmware and it is up to the driver to +select the correct product-specific firmware from that directory. + +For example a product containing four smart amplifiers may provide +firmware specific for that product and each of the amplifiers may +have coefficient files containing tunings for their placement in the +mechanical design. + +This change extends firmware (wmfw) and coefficient (bin) filenames +to be of the general form: + +part-dspN-fwtype<-system_name<-asoc_component_prefix>>.type + +Where the cirrus subdirectory, system_name and asoc_component_prefix +are optional. + +New files will be placed in the cirrus subdirectory to avoid +polluting the main /lib/firmware/ location. The generic name must be +searched in /lib/firmware before /lib/firmware/cirrus so that a +generic file in the new location does not override existing +product-specific files in the legacy location. + +The search order for firmware files is: + - cirrus/part-dspN-fwtype-system_name-asoc_component_prefix.wmfw + - cirrus/part-dspN-fwtype-system_name.wmfw + - part-dspN-fwtype.wmfw + - cirrus/part-dspN-fwtype.wmfw + +- Qualifications are added to the filename so that rightwards is more + specific. +- The system_name is provided by the codec driver. +- The asoc_component_prefix is used to identify tunings for individual + parts because it would already exist to disambiguate the controls + and it makes it obvious which firmware file applies to which device. + +The optional coefficient file must have the same filename +construction as the discovered wmfw except: + - where the wmfw has only system_name then the bin file can + optionally include the asoc_component_prefix. This is to allow a + common wmfw for all amps but separate tunings per amp. + +Signed-off-by: Simon Trimmer +Acked-by: Charles Keepax +Link: https://lore.kernel.org/r/20220303155016.122125-1-simont@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/wm_adsp.c | 99 +++++++++++++++++++++++++++++++++----- + sound/soc/codecs/wm_adsp.h | 1 + + 2 files changed, 88 insertions(+), 12 deletions(-) + +diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c +index c8c8338cb401..375cb14aaccd 100644 +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -749,21 +749,48 @@ static void wm_adsp_release_firmware_files(struct wm_adsp *dsp, + } + + static int wm_adsp_request_firmware_file(struct wm_adsp *dsp, +- const struct firmware **firmware, +- char **filename, +- char *suffix) ++ const struct firmware **firmware, char **filename, ++ const char *dir, const char *system_name, ++ const char *asoc_component_prefix, ++ const char *filetype) + { + struct cs_dsp *cs_dsp = &dsp->cs_dsp; ++ char *s, c; + int ret = 0; + +- *filename = kasprintf(GFP_KERNEL, "%s-%s-%s.%s", dsp->part, dsp->fwf_name, +- wm_adsp_fw[dsp->fw].file, suffix); ++ if (system_name && asoc_component_prefix) ++ *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s-%s.%s", dir, dsp->part, ++ dsp->fwf_name, wm_adsp_fw[dsp->fw].file, system_name, ++ asoc_component_prefix, filetype); ++ else if (system_name) ++ *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s.%s", dir, dsp->part, ++ dsp->fwf_name, wm_adsp_fw[dsp->fw].file, system_name, ++ filetype); ++ else ++ *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s.%s", dir, dsp->part, dsp->fwf_name, ++ wm_adsp_fw[dsp->fw].file, filetype); ++ + if (*filename == NULL) + return -ENOMEM; + +- ret = request_firmware(firmware, *filename, cs_dsp->dev); ++ /* ++ * Make sure that filename is lower-case and any non alpha-numeric ++ * characters except full stop and forward slash are replaced with ++ * hyphens. ++ */ ++ s = *filename; ++ while (*s) { ++ c = *s; ++ if (isalnum(c)) ++ *s = tolower(c); ++ else if ((c != '.') && (c != '/')) ++ *s = '-'; ++ s++; ++ } ++ ++ ret = firmware_request_nowarn(firmware, *filename, cs_dsp->dev); + if (ret != 0) { +- adsp_err(dsp, "Failed to request '%s'\n", *filename); ++ adsp_dbg(dsp, "Failed to request '%s'\n", *filename); + kfree(*filename); + *filename = NULL; + } +@@ -771,21 +798,69 @@ static int wm_adsp_request_firmware_file(struct wm_adsp *dsp, + return ret; + } + ++static const char *cirrus_dir = "cirrus/"; + static int wm_adsp_request_firmware_files(struct wm_adsp *dsp, + const struct firmware **wmfw_firmware, + char **wmfw_filename, + const struct firmware **coeff_firmware, + char **coeff_filename) + { ++ const char *system_name = dsp->system_name; ++ const char *asoc_component_prefix = dsp->component->name_prefix; + int ret = 0; + +- ret = wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename, "wmfw"); +- if (ret != 0) +- return ret; ++ if (system_name && asoc_component_prefix) { ++ if (!wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename, ++ cirrus_dir, system_name, ++ asoc_component_prefix, "wmfw")) { ++ adsp_dbg(dsp, "Found '%s'\n", *wmfw_filename); ++ wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename, ++ cirrus_dir, system_name, ++ asoc_component_prefix, "bin"); ++ return 0; ++ } ++ } + +- wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename, "bin"); ++ if (system_name) { ++ if (!wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename, ++ cirrus_dir, system_name, ++ NULL, "wmfw")) { ++ adsp_dbg(dsp, "Found '%s'\n", *wmfw_filename); ++ if (asoc_component_prefix) ++ wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename, ++ cirrus_dir, system_name, ++ asoc_component_prefix, "bin"); ++ ++ if (!*coeff_firmware) ++ wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename, ++ cirrus_dir, system_name, ++ NULL, "bin"); ++ return 0; ++ } ++ } + +- return 0; ++ if (!wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename, ++ "", NULL, NULL, "wmfw")) { ++ adsp_dbg(dsp, "Found '%s'\n", *wmfw_filename); ++ wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename, ++ "", NULL, NULL, "bin"); ++ return 0; ++ } ++ ++ ret = wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename, ++ cirrus_dir, NULL, NULL, "wmfw"); ++ if (!ret) { ++ adsp_dbg(dsp, "Found '%s'\n", *wmfw_filename); ++ wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename, ++ cirrus_dir, NULL, NULL, "bin"); ++ return 0; ++ } ++ ++ adsp_err(dsp, "Failed to request firmware <%s>%s-%s-%s<-%s<%s>>.wmfw\n", ++ cirrus_dir, dsp->part, dsp->fwf_name, wm_adsp_fw[dsp->fw].file, ++ system_name, asoc_component_prefix); ++ ++ return -ENOENT; + } + + static int wm_adsp_common_init(struct wm_adsp *dsp) +diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h +index 7f4fabbc6ad3..375009a65828 100644 +--- a/sound/soc/codecs/wm_adsp.h ++++ b/sound/soc/codecs/wm_adsp.h +@@ -28,6 +28,7 @@ struct wm_adsp { + struct cs_dsp cs_dsp; + const char *part; + const char *fwf_name; ++ const char *system_name; + struct snd_soc_component *component; + + unsigned int sys_config_size; +-- +2.35.3 + diff --git a/patches.suse/ASoC-wm_adsp-Fix-event-for-preloader.patch b/patches.suse/ASoC-wm_adsp-Fix-event-for-preloader.patch new file mode 100644 index 0000000..438435e --- /dev/null +++ b/patches.suse/ASoC-wm_adsp-Fix-event-for-preloader.patch @@ -0,0 +1,36 @@ +From 81d74ddae83fbd85c9006835f36c362114127a7a Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Tue, 21 Jun 2022 11:20:38 +0100 +Subject: [PATCH] ASoC: wm_adsp: Fix event for preloader +Git-commit: 81d74ddae83fbd85c9006835f36c362114127a7a +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +The preloader controls on ADSP should return a value of 1 if the +preloader value was changed, update to correct this. + +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20220621102041.1713504-1-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/wm_adsp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c +index 6d7fd88243aa..a7784ac15dde 100644 +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -997,7 +997,7 @@ int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol, + snd_soc_dapm_sync(dapm); + } + +- return 0; ++ return 1; + } + EXPORT_SYMBOL_GPL(wm_adsp2_preloader_put); + +-- +2.35.3 + diff --git a/patches.suse/ASoC-wm_adsp-Handle-optional-legacy-support.patch b/patches.suse/ASoC-wm_adsp-Handle-optional-legacy-support.patch new file mode 100644 index 0000000..3d5e17b --- /dev/null +++ b/patches.suse/ASoC-wm_adsp-Handle-optional-legacy-support.patch @@ -0,0 +1,57 @@ +From 35c8ae25c4fdeabf490e005692795a3be17ca5f6 Mon Sep 17 00:00:00 2001 +From: Cristian Ciocaltea +Date: Fri, 26 Aug 2022 01:05:30 +0300 +Subject: [PATCH] ASoC: wm_adsp: Handle optional legacy support +Git-commit: 35c8ae25c4fdeabf490e005692795a3be17ca5f6 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The tracing capabilities for the speaker protection fw enabled via +commit c55b3e46cb99 ("ASoC: wm_adsp: Add trace caps to speaker +protection FW") are not be available on all platforms, such as the +Valve's Steam Deck which is based on the Halo Core DSP. + +As a consequence, whenever the firmware is loaded, a rather misleading +'Failed to parse legacy: -19' error message is written to the kernel +ring buffer: + +[ 288.977412] steamdeck kernel: cs35l41 spi-VLV1776:01: DSP1: Firmware version: 3 +[ 288.978002] steamdeck kernel: cs35l41 spi-VLV1776:01: DSP1: cs35l41-dsp1-spk-prot.wmfw: Fri 02 Apr 2021 21:03:50 W. Europe Daylight Time +[ 289.094065] steamdeck kernel: cs35l41 spi-VLV1776:01: DSP1: Firmware: 400a4 vendor: 0x2 v0.33.0, 2 algorithms +[ 289.095073] steamdeck kernel: cs35l41 spi-VLV1776:01: DSP1: 0: ID cd v29.53.0 XM@94 YM@e +[ 289.095665] steamdeck kernel: cs35l41 spi-VLV1776:01: DSP1: 1: ID f20b v0.0.1 XM@170 YM@0 +[ 289.096275] steamdeck kernel: cs35l41 spi-VLV1776:01: DSP1: Protection: C:\Users\ocanavan\Desktop\cirrusTune_july2021.bin +[ 291.172383] steamdeck kernel: cs35l41 spi-VLV1776:01: DSP1: Failed to parse legacy: -19 + +Update wm_adsp_buffer_init() to print a more descriptive info message +when wm_adsp_buffer_parse_legacy() returns -ENODEV. + +Fixes: c55b3e46cb99 ("ASoC: wm_adsp: Add trace caps to speaker protection FW") +Signed-off-by: Cristian Ciocaltea +Acked-by: Charles Keepax +Link: https://lore.kernel.org/r/20220825220530.1205141-1-cristian.ciocaltea@collabora.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/wm_adsp.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c +index cfaa45ede916..8a2e9771bb50 100644 +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -1602,7 +1602,9 @@ static int wm_adsp_buffer_init(struct wm_adsp *dsp) + if (list_empty(&dsp->buffer_list)) { + /* Fall back to legacy support */ + ret = wm_adsp_buffer_parse_legacy(dsp); +- if (ret) ++ if (ret == -ENODEV) ++ adsp_info(dsp, "Legacy support not available\n"); ++ else if (ret) + adsp_warn(dsp, "Failed to parse legacy: %d\n", ret); + } + +-- +2.35.3 + diff --git a/patches.suse/ASoC-wm_adsp-Introduce-cs_dsp-logging-macros.patch b/patches.suse/ASoC-wm_adsp-Introduce-cs_dsp-logging-macros.patch new file mode 100644 index 0000000..28fbfd8 --- /dev/null +++ b/patches.suse/ASoC-wm_adsp-Introduce-cs_dsp-logging-macros.patch @@ -0,0 +1,1074 @@ +From 6ab1d0cc8470100cc8e0b478d94ff00b44df1625 Mon Sep 17 00:00:00 2001 +From: Simon Trimmer +Date: Mon, 13 Sep 2021 17:00:47 +0100 +Subject: [PATCH] ASoC: wm_adsp: Introduce cs_dsp logging macros +Git-commit: 6ab1d0cc8470100cc8e0b478d94ff00b44df1625 +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +In preparation for moving the generic DSP support out of ASoC, add +some new logging macros that will be used from the generic code. + +Signed-off-by: Simon Trimmer +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20210913160057.103842-7-simont@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/wm_adsp.c | 461 +++++++++++++++++++------------------ + 1 file changed, 234 insertions(+), 227 deletions(-) + +diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c +index a039c137a3cb..cfa8f1476c00 100644 +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -43,6 +43,15 @@ + #define adsp_dbg(_dsp, fmt, ...) \ + dev_dbg(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) + ++#define cs_dsp_err(_dsp, fmt, ...) \ ++ dev_err(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) ++#define cs_dsp_warn(_dsp, fmt, ...) \ ++ dev_warn(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) ++#define cs_dsp_info(_dsp, fmt, ...) \ ++ dev_info(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) ++#define cs_dsp_dbg(_dsp, fmt, ...) \ ++ dev_dbg(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) ++ + #define compr_err(_obj, fmt, ...) \ + adsp_err(_obj->dsp, "%s: " fmt, _obj->name ? _obj->name : "legacy", \ + ##__VA_ARGS__) +@@ -883,7 +892,7 @@ static void cs_dsp_read_fw_status(struct wm_adsp *dsp, + for (i = 0; i < noffs; ++i) { + ret = regmap_read(dsp->regmap, dsp->base + offs[i], &offs[i]); + if (ret) { +- adsp_err(dsp, "Failed to read SCRATCH%u: %d\n", i, ret); ++ cs_dsp_err(dsp, "Failed to read SCRATCH%u: %d\n", i, ret); + return; + } + } +@@ -897,8 +906,8 @@ static void cs_dsp_adsp2_show_fw_status(struct wm_adsp *dsp) + + cs_dsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs); + +- adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", +- offs[0], offs[1], offs[2], offs[3]); ++ cs_dsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", ++ offs[0], offs[1], offs[2], offs[3]); + } + + static void cs_dsp_adsp2v2_show_fw_status(struct wm_adsp *dsp) +@@ -907,9 +916,9 @@ static void cs_dsp_adsp2v2_show_fw_status(struct wm_adsp *dsp) + + cs_dsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs); + +- adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", +- offs[0] & 0xFFFF, offs[0] >> 16, +- offs[1] & 0xFFFF, offs[1] >> 16); ++ cs_dsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", ++ offs[0] & 0xFFFF, offs[0] >> 16, ++ offs[1] & 0xFFFF, offs[1] >> 16); + } + + static void cs_dsp_halo_show_fw_status(struct wm_adsp *dsp) +@@ -920,8 +929,8 @@ static void cs_dsp_halo_show_fw_status(struct wm_adsp *dsp) + + cs_dsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs); + +- adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", +- offs[0], offs[1], offs[2], offs[3]); ++ cs_dsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", ++ offs[0], offs[1], offs[2], offs[3]); + } + + static inline struct wm_coeff_ctl *bytes_ext_to_ctl(struct soc_bytes_ext *ext) +@@ -937,8 +946,8 @@ static int cs_dsp_coeff_base_reg(struct wm_coeff_ctl *ctl, unsigned int *reg) + + mem = cs_dsp_find_region(dsp, alg_region->type); + if (!mem) { +- adsp_err(dsp, "No base for region %x\n", +- alg_region->type); ++ cs_dsp_err(dsp, "No base for region %x\n", ++ alg_region->type); + return -EINVAL; + } + +@@ -983,13 +992,13 @@ static int cs_dsp_coeff_write_acked_control(struct wm_coeff_ctl *ctl, + if (ret) + return ret; + +- adsp_dbg(dsp, "Sending 0x%x to acked control alg 0x%x %s:0x%x\n", +- event_id, ctl->alg_region.alg, +- cs_dsp_mem_region_name(ctl->alg_region.type), ctl->offset); ++ cs_dsp_dbg(dsp, "Sending 0x%x to acked control alg 0x%x %s:0x%x\n", ++ event_id, ctl->alg_region.alg, ++ cs_dsp_mem_region_name(ctl->alg_region.type), ctl->offset); + + ret = regmap_raw_write(dsp->regmap, reg, &val, sizeof(val)); + if (ret) { +- adsp_err(dsp, "Failed to write %x: %d\n", reg, ret); ++ cs_dsp_err(dsp, "Failed to write %x: %d\n", reg, ret); + return ret; + } + +@@ -1013,20 +1022,20 @@ static int cs_dsp_coeff_write_acked_control(struct wm_coeff_ctl *ctl, + + ret = regmap_raw_read(dsp->regmap, reg, &val, sizeof(val)); + if (ret) { +- adsp_err(dsp, "Failed to read %x: %d\n", reg, ret); ++ cs_dsp_err(dsp, "Failed to read %x: %d\n", reg, ret); + return ret; + } + + if (val == 0) { +- adsp_dbg(dsp, "Acked control ACKED at poll %u\n", i); ++ cs_dsp_dbg(dsp, "Acked control ACKED at poll %u\n", i); + return 0; + } + } + +- adsp_warn(dsp, "Acked control @0x%x alg:0x%x %s:0x%x timed out\n", +- reg, ctl->alg_region.alg, +- cs_dsp_mem_region_name(ctl->alg_region.type), +- ctl->offset); ++ cs_dsp_warn(dsp, "Acked control @0x%x alg:0x%x %s:0x%x timed out\n", ++ reg, ctl->alg_region.alg, ++ cs_dsp_mem_region_name(ctl->alg_region.type), ++ ctl->offset); + + return -ETIMEDOUT; + } +@@ -1050,12 +1059,12 @@ static int cs_dsp_coeff_write_ctrl_raw(struct wm_coeff_ctl *ctl, + ret = regmap_raw_write(dsp->regmap, reg, scratch, + len); + if (ret) { +- adsp_err(dsp, "Failed to write %zu bytes to %x: %d\n", +- len, reg, ret); ++ cs_dsp_err(dsp, "Failed to write %zu bytes to %x: %d\n", ++ len, reg, ret); + kfree(scratch); + return ret; + } +- adsp_dbg(dsp, "Wrote %zu bytes to %x\n", len, reg); ++ cs_dsp_dbg(dsp, "Wrote %zu bytes to %x\n", len, reg); + + kfree(scratch); + +@@ -1157,12 +1166,12 @@ static int cs_dsp_coeff_read_ctrl_raw(struct wm_coeff_ctl *ctl, + + ret = regmap_raw_read(dsp->regmap, reg, scratch, len); + if (ret) { +- adsp_err(dsp, "Failed to read %zu bytes from %x: %d\n", +- len, reg, ret); ++ cs_dsp_err(dsp, "Failed to read %zu bytes from %x: %d\n", ++ len, reg, ret); + kfree(scratch); + return ret; + } +- adsp_dbg(dsp, "Read %zu bytes from %x\n", len, reg); ++ cs_dsp_dbg(dsp, "Read %zu bytes from %x\n", len, reg); + + memcpy(buf, scratch, len); + kfree(scratch); +@@ -1381,9 +1390,9 @@ static void cs_dsp_signal_event_controls(struct wm_adsp *dsp, + + ret = cs_dsp_coeff_write_acked_control(ctl, event); + if (ret) +- adsp_warn(dsp, +- "Failed to send 0x%x event to alg 0x%x (%d)\n", +- event, ctl->alg_region.alg, ret); ++ cs_dsp_warn(dsp, ++ "Failed to send 0x%x event to alg 0x%x (%d)\n", ++ event, ctl->alg_region.alg, ret); + } + } + +@@ -1432,7 +1441,7 @@ static int cs_dsp_create_control(struct wm_adsp *dsp, + + region_name = cs_dsp_mem_region_name(alg_region->type); + if (!region_name) { +- adsp_err(dsp, "Unknown region type: %d\n", alg_region->type); ++ cs_dsp_err(dsp, "Unknown region type: %d\n", alg_region->type); + return -EINVAL; + } + +@@ -1608,9 +1617,9 @@ static inline void cs_dsp_coeff_parse_alg(struct wm_adsp *dsp, const u8 **data, + break; + } + +- adsp_dbg(dsp, "Algorithm ID: %#x\n", blk->id); +- adsp_dbg(dsp, "Algorithm name: %.*s\n", blk->name_len, blk->name); +- adsp_dbg(dsp, "# of coefficient descriptors: %#x\n", blk->ncoeff); ++ cs_dsp_dbg(dsp, "Algorithm ID: %#x\n", blk->id); ++ cs_dsp_dbg(dsp, "Algorithm name: %.*s\n", blk->name_len, blk->name); ++ cs_dsp_dbg(dsp, "# of coefficient descriptors: %#x\n", blk->ncoeff); + } + + static inline void cs_dsp_coeff_parse_coeff(struct wm_adsp *dsp, const u8 **data, +@@ -1651,12 +1660,12 @@ static inline void cs_dsp_coeff_parse_coeff(struct wm_adsp *dsp, const u8 **data + break; + } + +- adsp_dbg(dsp, "\tCoefficient type: %#x\n", blk->mem_type); +- adsp_dbg(dsp, "\tCoefficient offset: %#x\n", blk->offset); +- adsp_dbg(dsp, "\tCoefficient name: %.*s\n", blk->name_len, blk->name); +- adsp_dbg(dsp, "\tCoefficient flags: %#x\n", blk->flags); +- adsp_dbg(dsp, "\tALSA control type: %#x\n", blk->ctl_type); +- adsp_dbg(dsp, "\tALSA control len: %#x\n", blk->len); ++ cs_dsp_dbg(dsp, "\tCoefficient type: %#x\n", blk->mem_type); ++ cs_dsp_dbg(dsp, "\tCoefficient offset: %#x\n", blk->offset); ++ cs_dsp_dbg(dsp, "\tCoefficient name: %.*s\n", blk->name_len, blk->name); ++ cs_dsp_dbg(dsp, "\tCoefficient flags: %#x\n", blk->flags); ++ cs_dsp_dbg(dsp, "\tALSA control type: %#x\n", blk->ctl_type); ++ cs_dsp_dbg(dsp, "\tALSA control len: %#x\n", blk->len); + } + + static int cs_dsp_check_coeff_flags(struct wm_adsp *dsp, +@@ -1666,8 +1675,8 @@ static int cs_dsp_check_coeff_flags(struct wm_adsp *dsp, + { + if ((coeff_blk->flags & f_illegal) || + ((coeff_blk->flags & f_required) != f_required)) { +- adsp_err(dsp, "Illegal flags 0x%x for control type 0x%x\n", +- coeff_blk->flags, coeff_blk->ctl_type); ++ cs_dsp_err(dsp, "Illegal flags 0x%x for control type 0x%x\n", ++ coeff_blk->flags, coeff_blk->ctl_type); + return -EINVAL; + } + +@@ -1722,8 +1731,8 @@ static int cs_dsp_parse_coeff(struct wm_adsp *dsp, + return -EINVAL; + break; + default: +- adsp_err(dsp, "Unknown control type: %d\n", +- coeff_blk.ctl_type); ++ cs_dsp_err(dsp, "Unknown control type: %d\n", ++ coeff_blk.ctl_type); + return -EINVAL; + } + +@@ -1738,8 +1747,8 @@ static int cs_dsp_parse_coeff(struct wm_adsp *dsp, + coeff_blk.flags, + coeff_blk.ctl_type); + if (ret < 0) +- adsp_err(dsp, "Failed to create control: %.*s, %d\n", +- coeff_blk.name_len, coeff_blk.name, ret); ++ cs_dsp_err(dsp, "Failed to create control: %.*s, %d\n", ++ coeff_blk.name_len, coeff_blk.name, ret); + } + + return 0; +@@ -1754,9 +1763,9 @@ static unsigned int cs_dsp_adsp1_parse_sizes(struct wm_adsp *dsp, + + adsp1_sizes = (void *)&firmware->data[pos]; + +- adsp_dbg(dsp, "%s: %d DM, %d PM, %d ZM\n", file, +- le32_to_cpu(adsp1_sizes->dm), le32_to_cpu(adsp1_sizes->pm), +- le32_to_cpu(adsp1_sizes->zm)); ++ cs_dsp_dbg(dsp, "%s: %d DM, %d PM, %d ZM\n", file, ++ le32_to_cpu(adsp1_sizes->dm), le32_to_cpu(adsp1_sizes->pm), ++ le32_to_cpu(adsp1_sizes->zm)); + + return pos + sizeof(*adsp1_sizes); + } +@@ -1770,9 +1779,9 @@ static unsigned int cs_dsp_adsp2_parse_sizes(struct wm_adsp *dsp, + + adsp2_sizes = (void *)&firmware->data[pos]; + +- adsp_dbg(dsp, "%s: %d XM, %d YM %d PM, %d ZM\n", file, +- le32_to_cpu(adsp2_sizes->xm), le32_to_cpu(adsp2_sizes->ym), +- le32_to_cpu(adsp2_sizes->pm), le32_to_cpu(adsp2_sizes->zm)); ++ cs_dsp_dbg(dsp, "%s: %d XM, %d YM %d PM, %d ZM\n", file, ++ le32_to_cpu(adsp2_sizes->xm), le32_to_cpu(adsp2_sizes->ym), ++ le32_to_cpu(adsp2_sizes->pm), le32_to_cpu(adsp2_sizes->zm)); + + return pos + sizeof(*adsp2_sizes); + } +@@ -1781,7 +1790,7 @@ static bool cs_dsp_validate_version(struct wm_adsp *dsp, unsigned int version) + { + switch (version) { + case 0: +- adsp_warn(dsp, "Deprecated file format %d\n", version); ++ cs_dsp_warn(dsp, "Deprecated file format %d\n", version); + return true; + case 1: + case 2: +@@ -1829,37 +1838,37 @@ static int cs_dsp_load(struct wm_adsp *dsp) + + ret = request_firmware(&firmware, file, dsp->dev); + if (ret != 0) { +- adsp_err(dsp, "Failed to request '%s'\n", file); ++ cs_dsp_err(dsp, "Failed to request '%s'\n", file); + goto out; + } + ret = -EINVAL; + + pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer); + if (pos >= firmware->size) { +- adsp_err(dsp, "%s: file too short, %zu bytes\n", +- file, firmware->size); ++ cs_dsp_err(dsp, "%s: file too short, %zu bytes\n", ++ file, firmware->size); + goto out_fw; + } + + header = (void *)&firmware->data[0]; + + if (memcmp(&header->magic[0], "WMFW", 4) != 0) { +- adsp_err(dsp, "%s: invalid magic\n", file); ++ cs_dsp_err(dsp, "%s: invalid magic\n", file); + goto out_fw; + } + + if (!dsp->ops->validate_version(dsp, header->ver)) { +- adsp_err(dsp, "%s: unknown file format %d\n", +- file, header->ver); ++ cs_dsp_err(dsp, "%s: unknown file format %d\n", ++ file, header->ver); + goto out_fw; + } + +- adsp_info(dsp, "Firmware version: %d\n", header->ver); ++ cs_dsp_info(dsp, "Firmware version: %d\n", header->ver); + dsp->fw_ver = header->ver; + + if (header->core != dsp->type) { +- adsp_err(dsp, "%s: invalid core %d != %d\n", +- file, header->core, dsp->type); ++ cs_dsp_err(dsp, "%s: invalid core %d != %d\n", ++ file, header->core, dsp->type); + goto out_fw; + } + +@@ -1870,13 +1879,13 @@ static int cs_dsp_load(struct wm_adsp *dsp) + pos += sizeof(*footer); + + if (le32_to_cpu(header->len) != pos) { +- adsp_err(dsp, "%s: unexpected header length %d\n", +- file, le32_to_cpu(header->len)); ++ cs_dsp_err(dsp, "%s: unexpected header length %d\n", ++ file, le32_to_cpu(header->len)); + goto out_fw; + } + +- adsp_dbg(dsp, "%s: timestamp %llu\n", file, +- le64_to_cpu(footer->timestamp)); ++ cs_dsp_dbg(dsp, "%s: timestamp %llu\n", file, ++ le64_to_cpu(footer->timestamp)); + + while (pos < firmware->size && + sizeof(*region) < firmware->size - pos) { +@@ -1918,7 +1927,7 @@ static int cs_dsp_load(struct wm_adsp *dsp) + case WMFW_HALO_YM_PACKED: + mem = cs_dsp_find_region(dsp, type); + if (!mem) { +- adsp_err(dsp, "No region of type: %x\n", type); ++ cs_dsp_err(dsp, "No region of type: %x\n", type); + ret = -EINVAL; + goto out_fw; + } +@@ -1927,29 +1936,29 @@ static int cs_dsp_load(struct wm_adsp *dsp) + reg = dsp->ops->region_to_reg(mem, offset); + break; + default: +- adsp_warn(dsp, +- "%s.%d: Unknown region type %x at %d(%x)\n", +- file, regions, type, pos, pos); ++ cs_dsp_warn(dsp, ++ "%s.%d: Unknown region type %x at %d(%x)\n", ++ file, regions, type, pos, pos); + break; + } + +- adsp_dbg(dsp, "%s.%d: %d bytes at %d in %s\n", file, +- regions, le32_to_cpu(region->len), offset, +- region_name); ++ cs_dsp_dbg(dsp, "%s.%d: %d bytes at %d in %s\n", file, ++ regions, le32_to_cpu(region->len), offset, ++ region_name); + + if (le32_to_cpu(region->len) > + firmware->size - pos - sizeof(*region)) { +- adsp_err(dsp, +- "%s.%d: %s region len %d bytes exceeds file length %zu\n", +- file, regions, region_name, +- le32_to_cpu(region->len), firmware->size); ++ cs_dsp_err(dsp, ++ "%s.%d: %s region len %d bytes exceeds file length %zu\n", ++ file, regions, region_name, ++ le32_to_cpu(region->len), firmware->size); + ret = -EINVAL; + goto out_fw; + } + + if (text) { + memcpy(text, region->data, le32_to_cpu(region->len)); +- adsp_info(dsp, "%s: %s\n", file, text); ++ cs_dsp_info(dsp, "%s: %s\n", file, text); + kfree(text); + text = NULL; + } +@@ -1959,7 +1968,7 @@ static int cs_dsp_load(struct wm_adsp *dsp) + le32_to_cpu(region->len), + &buf_list); + if (!buf) { +- adsp_err(dsp, "Out of memory\n"); ++ cs_dsp_err(dsp, "Out of memory\n"); + ret = -ENOMEM; + goto out_fw; + } +@@ -1967,11 +1976,11 @@ static int cs_dsp_load(struct wm_adsp *dsp) + ret = regmap_raw_write_async(regmap, reg, buf->buf, + le32_to_cpu(region->len)); + if (ret != 0) { +- adsp_err(dsp, +- "%s.%d: Failed to write %d bytes at %d in %s: %d\n", +- file, regions, +- le32_to_cpu(region->len), offset, +- region_name, ret); ++ cs_dsp_err(dsp, ++ "%s.%d: Failed to write %d bytes at %d in %s: %d\n", ++ file, regions, ++ le32_to_cpu(region->len), offset, ++ region_name, ret); + goto out_fw; + } + } +@@ -1982,13 +1991,13 @@ static int cs_dsp_load(struct wm_adsp *dsp) + + ret = regmap_async_complete(regmap); + if (ret != 0) { +- adsp_err(dsp, "Failed to complete async write: %d\n", ret); ++ cs_dsp_err(dsp, "Failed to complete async write: %d\n", ret); + goto out_fw; + } + + if (pos > firmware->size) +- adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", +- file, regions, pos - firmware->size); ++ cs_dsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", ++ file, regions, pos - firmware->size); + + cs_dsp_debugfs_save_wmfwname(dsp, file); + +@@ -2111,12 +2120,12 @@ static void *cs_dsp_read_algs(struct wm_adsp *dsp, size_t n_algs, + __be32 val; + + if (n_algs == 0) { +- adsp_err(dsp, "No algorithms\n"); ++ cs_dsp_err(dsp, "No algorithms\n"); + return ERR_PTR(-EINVAL); + } + + if (n_algs > 1024) { +- adsp_err(dsp, "Algorithm count %zx excessive\n", n_algs); ++ cs_dsp_err(dsp, "Algorithm count %zx excessive\n", n_algs); + return ERR_PTR(-EINVAL); + } + +@@ -2125,14 +2134,14 @@ static void *cs_dsp_read_algs(struct wm_adsp *dsp, size_t n_algs, + + ret = regmap_raw_read(dsp->regmap, reg, &val, sizeof(val)); + if (ret != 0) { +- adsp_err(dsp, "Failed to read algorithm list end: %d\n", +- ret); ++ cs_dsp_err(dsp, "Failed to read algorithm list end: %d\n", ++ ret); + return ERR_PTR(ret); + } + + if (be32_to_cpu(val) != 0xbedead) +- adsp_warn(dsp, "Algorithm list end %x 0x%x != 0xbedead\n", +- reg, be32_to_cpu(val)); ++ cs_dsp_warn(dsp, "Algorithm list end %x 0x%x != 0xbedead\n", ++ reg, be32_to_cpu(val)); + + /* Convert length from DSP words to bytes */ + len *= sizeof(u32); +@@ -2145,7 +2154,7 @@ static void *cs_dsp_read_algs(struct wm_adsp *dsp, size_t n_algs, + + ret = regmap_raw_read(dsp->regmap, reg, alg, len); + if (ret != 0) { +- adsp_err(dsp, "Failed to read algorithm list: %d\n", ret); ++ cs_dsp_err(dsp, "Failed to read algorithm list: %d\n", ret); + kfree(alg); + return ERR_PTR(ret); + } +@@ -2207,10 +2216,10 @@ static void cs_dsp_parse_wmfw_id_header(struct wm_adsp *dsp, + dsp->fw_id = be32_to_cpu(fw->id); + dsp->fw_id_version = be32_to_cpu(fw->ver); + +- adsp_info(dsp, "Firmware: %x v%d.%d.%d, %d algorithms\n", +- dsp->fw_id, (dsp->fw_id_version & 0xff0000) >> 16, +- (dsp->fw_id_version & 0xff00) >> 8, dsp->fw_id_version & 0xff, +- nalgs); ++ cs_dsp_info(dsp, "Firmware: %x v%d.%d.%d, %d algorithms\n", ++ dsp->fw_id, (dsp->fw_id_version & 0xff0000) >> 16, ++ (dsp->fw_id_version & 0xff00) >> 8, dsp->fw_id_version & 0xff, ++ nalgs); + } + + static void cs_dsp_parse_wmfw_v3_id_header(struct wm_adsp *dsp, +@@ -2220,11 +2229,11 @@ static void cs_dsp_parse_wmfw_v3_id_header(struct wm_adsp *dsp, + dsp->fw_id_version = be32_to_cpu(fw->ver); + dsp->fw_vendor_id = be32_to_cpu(fw->vendor_id); + +- adsp_info(dsp, "Firmware: %x vendor: 0x%x v%d.%d.%d, %d algorithms\n", +- dsp->fw_id, dsp->fw_vendor_id, +- (dsp->fw_id_version & 0xff0000) >> 16, +- (dsp->fw_id_version & 0xff00) >> 8, dsp->fw_id_version & 0xff, +- nalgs); ++ cs_dsp_info(dsp, "Firmware: %x vendor: 0x%x v%d.%d.%d, %d algorithms\n", ++ dsp->fw_id, dsp->fw_vendor_id, ++ (dsp->fw_id_version & 0xff0000) >> 16, ++ (dsp->fw_id_version & 0xff00) >> 8, dsp->fw_id_version & 0xff, ++ nalgs); + } + + static int cs_dsp_create_regions(struct wm_adsp *dsp, __be32 id, int nregions, +@@ -2259,8 +2268,8 @@ static int cs_dsp_adsp1_setup_algs(struct wm_adsp *dsp) + ret = regmap_raw_read(dsp->regmap, mem->base, &adsp1_id, + sizeof(adsp1_id)); + if (ret != 0) { +- adsp_err(dsp, "Failed to read algorithm info: %d\n", +- ret); ++ cs_dsp_err(dsp, "Failed to read algorithm info: %d\n", ++ ret); + return ret; + } + +@@ -2287,13 +2296,13 @@ static int cs_dsp_adsp1_setup_algs(struct wm_adsp *dsp) + return PTR_ERR(adsp1_alg); + + for (i = 0; i < n_algs; i++) { +- adsp_info(dsp, "%d: ID %x v%d.%d.%d DM@%x ZM@%x\n", +- i, be32_to_cpu(adsp1_alg[i].alg.id), +- (be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff0000) >> 16, +- (be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff00) >> 8, +- be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff, +- be32_to_cpu(adsp1_alg[i].dm), +- be32_to_cpu(adsp1_alg[i].zm)); ++ cs_dsp_info(dsp, "%d: ID %x v%d.%d.%d DM@%x ZM@%x\n", ++ i, be32_to_cpu(adsp1_alg[i].alg.id), ++ (be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff0000) >> 16, ++ (be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff00) >> 8, ++ be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff, ++ be32_to_cpu(adsp1_alg[i].dm), ++ be32_to_cpu(adsp1_alg[i].zm)); + + alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_DM, + adsp1_alg[i].alg.id, +@@ -2311,8 +2320,8 @@ static int cs_dsp_adsp1_setup_algs(struct wm_adsp *dsp) + len, NULL, 0, 0, + WMFW_CTL_TYPE_BYTES); + } else { +- adsp_warn(dsp, "Missing length info for region DM with ID %x\n", +- be32_to_cpu(adsp1_alg[i].alg.id)); ++ cs_dsp_warn(dsp, "Missing length info for region DM with ID %x\n", ++ be32_to_cpu(adsp1_alg[i].alg.id)); + } + } + +@@ -2332,8 +2341,8 @@ static int cs_dsp_adsp1_setup_algs(struct wm_adsp *dsp) + len, NULL, 0, 0, + WMFW_CTL_TYPE_BYTES); + } else { +- adsp_warn(dsp, "Missing length info for region ZM with ID %x\n", +- be32_to_cpu(adsp1_alg[i].alg.id)); ++ cs_dsp_warn(dsp, "Missing length info for region ZM with ID %x\n", ++ be32_to_cpu(adsp1_alg[i].alg.id)); + } + } + } +@@ -2360,8 +2369,8 @@ static int cs_dsp_adsp2_setup_algs(struct wm_adsp *dsp) + ret = regmap_raw_read(dsp->regmap, mem->base, &adsp2_id, + sizeof(adsp2_id)); + if (ret != 0) { +- adsp_err(dsp, "Failed to read algorithm info: %d\n", +- ret); ++ cs_dsp_err(dsp, "Failed to read algorithm info: %d\n", ++ ret); + return ret; + } + +@@ -2393,15 +2402,15 @@ static int cs_dsp_adsp2_setup_algs(struct wm_adsp *dsp) + return PTR_ERR(adsp2_alg); + + for (i = 0; i < n_algs; i++) { +- adsp_info(dsp, +- "%d: ID %x v%d.%d.%d XM@%x YM@%x ZM@%x\n", +- i, be32_to_cpu(adsp2_alg[i].alg.id), +- (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff0000) >> 16, +- (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff00) >> 8, +- be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff, +- be32_to_cpu(adsp2_alg[i].xm), +- be32_to_cpu(adsp2_alg[i].ym), +- be32_to_cpu(adsp2_alg[i].zm)); ++ cs_dsp_info(dsp, ++ "%d: ID %x v%d.%d.%d XM@%x YM@%x ZM@%x\n", ++ i, be32_to_cpu(adsp2_alg[i].alg.id), ++ (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff0000) >> 16, ++ (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff00) >> 8, ++ be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff, ++ be32_to_cpu(adsp2_alg[i].xm), ++ be32_to_cpu(adsp2_alg[i].ym), ++ be32_to_cpu(adsp2_alg[i].zm)); + + alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_XM, + adsp2_alg[i].alg.id, +@@ -2419,8 +2428,8 @@ static int cs_dsp_adsp2_setup_algs(struct wm_adsp *dsp) + len, NULL, 0, 0, + WMFW_CTL_TYPE_BYTES); + } else { +- adsp_warn(dsp, "Missing length info for region XM with ID %x\n", +- be32_to_cpu(adsp2_alg[i].alg.id)); ++ cs_dsp_warn(dsp, "Missing length info for region XM with ID %x\n", ++ be32_to_cpu(adsp2_alg[i].alg.id)); + } + } + +@@ -2440,8 +2449,8 @@ static int cs_dsp_adsp2_setup_algs(struct wm_adsp *dsp) + len, NULL, 0, 0, + WMFW_CTL_TYPE_BYTES); + } else { +- adsp_warn(dsp, "Missing length info for region YM with ID %x\n", +- be32_to_cpu(adsp2_alg[i].alg.id)); ++ cs_dsp_warn(dsp, "Missing length info for region YM with ID %x\n", ++ be32_to_cpu(adsp2_alg[i].alg.id)); + } + } + +@@ -2461,8 +2470,8 @@ static int cs_dsp_adsp2_setup_algs(struct wm_adsp *dsp) + len, NULL, 0, 0, + WMFW_CTL_TYPE_BYTES); + } else { +- adsp_warn(dsp, "Missing length info for region ZM with ID %x\n", +- be32_to_cpu(adsp2_alg[i].alg.id)); ++ cs_dsp_warn(dsp, "Missing length info for region ZM with ID %x\n", ++ be32_to_cpu(adsp2_alg[i].alg.id)); + } + } + } +@@ -2500,8 +2509,8 @@ static int cs_dsp_halo_setup_algs(struct wm_adsp *dsp) + ret = regmap_raw_read(dsp->regmap, mem->base, &halo_id, + sizeof(halo_id)); + if (ret != 0) { +- adsp_err(dsp, "Failed to read algorithm info: %d\n", +- ret); ++ cs_dsp_err(dsp, "Failed to read algorithm info: %d\n", ++ ret); + return ret; + } + +@@ -2523,14 +2532,14 @@ static int cs_dsp_halo_setup_algs(struct wm_adsp *dsp) + return PTR_ERR(halo_alg); + + for (i = 0; i < n_algs; i++) { +- adsp_info(dsp, +- "%d: ID %x v%d.%d.%d XM@%x YM@%x\n", +- i, be32_to_cpu(halo_alg[i].alg.id), +- (be32_to_cpu(halo_alg[i].alg.ver) & 0xff0000) >> 16, +- (be32_to_cpu(halo_alg[i].alg.ver) & 0xff00) >> 8, +- be32_to_cpu(halo_alg[i].alg.ver) & 0xff, +- be32_to_cpu(halo_alg[i].xm_base), +- be32_to_cpu(halo_alg[i].ym_base)); ++ cs_dsp_info(dsp, ++ "%d: ID %x v%d.%d.%d XM@%x YM@%x\n", ++ i, be32_to_cpu(halo_alg[i].alg.id), ++ (be32_to_cpu(halo_alg[i].alg.ver) & 0xff0000) >> 16, ++ (be32_to_cpu(halo_alg[i].alg.ver) & 0xff00) >> 8, ++ be32_to_cpu(halo_alg[i].alg.ver) & 0xff, ++ be32_to_cpu(halo_alg[i].xm_base), ++ be32_to_cpu(halo_alg[i].ym_base)); + + ret = cs_dsp_halo_create_regions(dsp, halo_alg[i].alg.id, + halo_alg[i].xm_base, +@@ -2568,21 +2577,21 @@ static int cs_dsp_load_coeff(struct wm_adsp *dsp) + + ret = request_firmware(&firmware, file, dsp->dev); + if (ret != 0) { +- adsp_warn(dsp, "Failed to request '%s'\n", file); ++ cs_dsp_warn(dsp, "Failed to request '%s'\n", file); + ret = 0; + goto out; + } + ret = -EINVAL; + + if (sizeof(*hdr) >= firmware->size) { +- adsp_err(dsp, "%s: file too short, %zu bytes\n", +- file, firmware->size); ++ cs_dsp_err(dsp, "%s: file too short, %zu bytes\n", ++ file, firmware->size); + goto out_fw; + } + + hdr = (void *)&firmware->data[0]; + if (memcmp(hdr->magic, "WMDR", 4) != 0) { +- adsp_err(dsp, "%s: invalid magic\n", file); ++ cs_dsp_err(dsp, "%s: invalid magic\n", file); + goto out_fw; + } + +@@ -2590,16 +2599,16 @@ static int cs_dsp_load_coeff(struct wm_adsp *dsp) + case 1: + break; + default: +- adsp_err(dsp, "%s: Unsupported coefficient file format %d\n", +- file, be32_to_cpu(hdr->rev) & 0xff); ++ cs_dsp_err(dsp, "%s: Unsupported coefficient file format %d\n", ++ file, be32_to_cpu(hdr->rev) & 0xff); + ret = -EINVAL; + goto out_fw; + } + +- adsp_dbg(dsp, "%s: v%d.%d.%d\n", file, +- (le32_to_cpu(hdr->ver) >> 16) & 0xff, +- (le32_to_cpu(hdr->ver) >> 8) & 0xff, +- le32_to_cpu(hdr->ver) & 0xff); ++ cs_dsp_dbg(dsp, "%s: v%d.%d.%d\n", file, ++ (le32_to_cpu(hdr->ver) >> 16) & 0xff, ++ (le32_to_cpu(hdr->ver) >> 8) & 0xff, ++ le32_to_cpu(hdr->ver) & 0xff); + + pos = le32_to_cpu(hdr->len); + +@@ -2611,13 +2620,13 @@ static int cs_dsp_load_coeff(struct wm_adsp *dsp) + type = le16_to_cpu(blk->type); + offset = le16_to_cpu(blk->offset); + +- adsp_dbg(dsp, "%s.%d: %x v%d.%d.%d\n", +- file, blocks, le32_to_cpu(blk->id), +- (le32_to_cpu(blk->ver) >> 16) & 0xff, +- (le32_to_cpu(blk->ver) >> 8) & 0xff, +- le32_to_cpu(blk->ver) & 0xff); +- adsp_dbg(dsp, "%s.%d: %d bytes at 0x%x in %x\n", +- file, blocks, le32_to_cpu(blk->len), offset, type); ++ cs_dsp_dbg(dsp, "%s.%d: %x v%d.%d.%d\n", ++ file, blocks, le32_to_cpu(blk->id), ++ (le32_to_cpu(blk->ver) >> 16) & 0xff, ++ (le32_to_cpu(blk->ver) >> 8) & 0xff, ++ le32_to_cpu(blk->ver) & 0xff); ++ cs_dsp_dbg(dsp, "%s.%d: %d bytes at 0x%x in %x\n", ++ file, blocks, le32_to_cpu(blk->len), offset, type); + + reg = 0; + region_name = "Unknown"; +@@ -2636,7 +2645,7 @@ static int cs_dsp_load_coeff(struct wm_adsp *dsp) + region_name = "global coefficients"; + mem = cs_dsp_find_region(dsp, type); + if (!mem) { +- adsp_err(dsp, "No ZM\n"); ++ cs_dsp_err(dsp, "No ZM\n"); + break; + } + reg = dsp->ops->region_to_reg(mem, 0); +@@ -2654,13 +2663,13 @@ static int cs_dsp_load_coeff(struct wm_adsp *dsp) + case WMFW_HALO_XM_PACKED: + case WMFW_HALO_YM_PACKED: + case WMFW_HALO_PM_PACKED: +- adsp_dbg(dsp, "%s.%d: %d bytes in %x for %x\n", +- file, blocks, le32_to_cpu(blk->len), +- type, le32_to_cpu(blk->id)); ++ cs_dsp_dbg(dsp, "%s.%d: %d bytes in %x for %x\n", ++ file, blocks, le32_to_cpu(blk->len), ++ type, le32_to_cpu(blk->id)); + + mem = cs_dsp_find_region(dsp, type); + if (!mem) { +- adsp_err(dsp, "No base for region %x\n", type); ++ cs_dsp_err(dsp, "No base for region %x\n", type); + break; + } + +@@ -2671,25 +2680,25 @@ static int cs_dsp_load_coeff(struct wm_adsp *dsp) + reg = dsp->ops->region_to_reg(mem, reg); + reg += offset; + } else { +- adsp_err(dsp, "No %x for algorithm %x\n", +- type, le32_to_cpu(blk->id)); ++ cs_dsp_err(dsp, "No %x for algorithm %x\n", ++ type, le32_to_cpu(blk->id)); + } + break; + + default: +- adsp_err(dsp, "%s.%d: Unknown region type %x at %d\n", +- file, blocks, type, pos); ++ cs_dsp_err(dsp, "%s.%d: Unknown region type %x at %d\n", ++ file, blocks, type, pos); + break; + } + + if (reg) { + if (le32_to_cpu(blk->len) > + firmware->size - pos - sizeof(*blk)) { +- adsp_err(dsp, +- "%s.%d: %s region len %d bytes exceeds file length %zu\n", +- file, blocks, region_name, +- le32_to_cpu(blk->len), +- firmware->size); ++ cs_dsp_err(dsp, ++ "%s.%d: %s region len %d bytes exceeds file length %zu\n", ++ file, blocks, region_name, ++ le32_to_cpu(blk->len), ++ firmware->size); + ret = -EINVAL; + goto out_fw; + } +@@ -2698,20 +2707,20 @@ static int cs_dsp_load_coeff(struct wm_adsp *dsp) + le32_to_cpu(blk->len), + &buf_list); + if (!buf) { +- adsp_err(dsp, "Out of memory\n"); ++ cs_dsp_err(dsp, "Out of memory\n"); + ret = -ENOMEM; + goto out_fw; + } + +- adsp_dbg(dsp, "%s.%d: Writing %d bytes at %x\n", +- file, blocks, le32_to_cpu(blk->len), +- reg); ++ cs_dsp_dbg(dsp, "%s.%d: Writing %d bytes at %x\n", ++ file, blocks, le32_to_cpu(blk->len), ++ reg); + ret = regmap_raw_write_async(regmap, reg, buf->buf, + le32_to_cpu(blk->len)); + if (ret != 0) { +- adsp_err(dsp, +- "%s.%d: Failed to write to %x in %s: %d\n", +- file, blocks, reg, region_name, ret); ++ cs_dsp_err(dsp, ++ "%s.%d: Failed to write to %x in %s: %d\n", ++ file, blocks, reg, region_name, ret); + } + } + +@@ -2721,11 +2730,11 @@ static int cs_dsp_load_coeff(struct wm_adsp *dsp) + + ret = regmap_async_complete(regmap); + if (ret != 0) +- adsp_err(dsp, "Failed to complete async write: %d\n", ret); ++ cs_dsp_err(dsp, "Failed to complete async write: %d\n", ret); + + if (pos > firmware->size) +- adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", +- file, blocks, pos - firmware->size); ++ cs_dsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", ++ file, blocks, pos - firmware->size); + + cs_dsp_debugfs_save_binname(dsp, file); + +@@ -2815,8 +2824,7 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, + if (dsp->sysclk_reg) { + ret = regmap_read(dsp->regmap, dsp->sysclk_reg, &val); + if (ret != 0) { +- adsp_err(dsp, "Failed to read SYSCLK state: %d\n", +- ret); ++ cs_dsp_err(dsp, "Failed to read SYSCLK state: %d\n", ret); + goto err_mutex; + } + +@@ -2826,8 +2834,7 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, + dsp->base + ADSP1_CONTROL_31, + ADSP1_CLK_SEL_MASK, val); + if (ret != 0) { +- adsp_err(dsp, "Failed to set clock rate: %d\n", +- ret); ++ cs_dsp_err(dsp, "Failed to set clock rate: %d\n", ret); + goto err_mutex; + } + } +@@ -2921,11 +2928,11 @@ static int cs_dsp_adsp2v2_enable_core(struct wm_adsp *dsp) + } + + if (!(val & ADSP2_RAM_RDY)) { +- adsp_err(dsp, "Failed to start DSP RAM\n"); ++ cs_dsp_err(dsp, "Failed to start DSP RAM\n"); + return -EBUSY; + } + +- adsp_dbg(dsp, "RAM ready after %d polls\n", count); ++ cs_dsp_dbg(dsp, "RAM ready after %d polls\n", count); + + return 0; + } +@@ -3100,7 +3107,7 @@ int wm_adsp2_set_dspclk(struct snd_soc_dapm_widget *w, unsigned int freq) + ADSP2_CLK_SEL_MASK, + freq << ADSP2_CLK_SEL_SHIFT); + if (ret) +- adsp_err(dsp, "Failed to set clock rate: %d\n", ret); ++ cs_dsp_err(dsp, "Failed to set clock rate: %d\n", ret); + + return ret; + } +@@ -3193,7 +3200,7 @@ int wm_adsp_early_event(struct snd_soc_dapm_widget *w, + + mutex_unlock(&dsp->pwr_lock); + +- adsp_dbg(dsp, "Shutdown complete\n"); ++ cs_dsp_dbg(dsp, "Shutdown complete\n"); + break; + default: + break; +@@ -3249,8 +3256,7 @@ int wm_adsp_event(struct snd_soc_dapm_widget *w, + if (dsp->ops->lock_memory) { + ret = dsp->ops->lock_memory(dsp, dsp->lock_regions); + if (ret != 0) { +- adsp_err(dsp, "Error configuring MPU: %d\n", +- ret); ++ cs_dsp_err(dsp, "Error configuring MPU: %d\n", ret); + goto err; + } + } +@@ -3299,7 +3305,7 @@ int wm_adsp_event(struct snd_soc_dapm_widget *w, + + mutex_unlock(&dsp->pwr_lock); + +- adsp_dbg(dsp, "Execution stopped\n"); ++ cs_dsp_dbg(dsp, "Execution stopped\n"); + break; + + default: +@@ -3375,8 +3381,8 @@ int wm_adsp2_init(struct wm_adsp *dsp) + ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_MEM_ENA, 0); + if (ret) { +- adsp_err(dsp, +- "Failed to clear memory retention: %d\n", ret); ++ cs_dsp_err(dsp, ++ "Failed to clear memory retention: %d\n", ret); + return ret; + } + +@@ -4351,49 +4357,49 @@ irqreturn_t wm_adsp2_bus_error(int irq, void *data) + + ret = regmap_read(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, &val); + if (ret) { +- adsp_err(dsp, +- "Failed to read Region Lock Ctrl register: %d\n", ret); ++ cs_dsp_err(dsp, ++ "Failed to read Region Lock Ctrl register: %d\n", ret); + goto error; + } + + if (val & ADSP2_WDT_TIMEOUT_STS_MASK) { +- adsp_err(dsp, "watchdog timeout error\n"); ++ cs_dsp_err(dsp, "watchdog timeout error\n"); + dsp->ops->stop_watchdog(dsp); + wm_adsp_fatal_error(dsp); + } + + if (val & (ADSP2_ADDR_ERR_MASK | ADSP2_REGION_LOCK_ERR_MASK)) { + if (val & ADSP2_ADDR_ERR_MASK) +- adsp_err(dsp, "bus error: address error\n"); ++ cs_dsp_err(dsp, "bus error: address error\n"); + else +- adsp_err(dsp, "bus error: region lock error\n"); ++ cs_dsp_err(dsp, "bus error: region lock error\n"); + + ret = regmap_read(regmap, dsp->base + ADSP2_BUS_ERR_ADDR, &val); + if (ret) { +- adsp_err(dsp, +- "Failed to read Bus Err Addr register: %d\n", +- ret); ++ cs_dsp_err(dsp, ++ "Failed to read Bus Err Addr register: %d\n", ++ ret); + goto error; + } + +- adsp_err(dsp, "bus error address = 0x%x\n", +- val & ADSP2_BUS_ERR_ADDR_MASK); ++ cs_dsp_err(dsp, "bus error address = 0x%x\n", ++ val & ADSP2_BUS_ERR_ADDR_MASK); + + ret = regmap_read(regmap, + dsp->base + ADSP2_PMEM_ERR_ADDR_XMEM_ERR_ADDR, + &val); + if (ret) { +- adsp_err(dsp, +- "Failed to read Pmem Xmem Err Addr register: %d\n", +- ret); ++ cs_dsp_err(dsp, ++ "Failed to read Pmem Xmem Err Addr register: %d\n", ++ ret); + goto error; + } + +- adsp_err(dsp, "xmem error address = 0x%x\n", +- val & ADSP2_XMEM_ERR_ADDR_MASK); +- adsp_err(dsp, "pmem error address = 0x%x\n", +- (val & ADSP2_PMEM_ERR_ADDR_MASK) >> +- ADSP2_PMEM_ERR_ADDR_SHIFT); ++ cs_dsp_err(dsp, "xmem error address = 0x%x\n", ++ val & ADSP2_XMEM_ERR_ADDR_MASK); ++ cs_dsp_err(dsp, "pmem error address = 0x%x\n", ++ (val & ADSP2_PMEM_ERR_ADDR_MASK) >> ++ ADSP2_PMEM_ERR_ADDR_SHIFT); + } + + regmap_update_bits(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, +@@ -4423,38 +4429,38 @@ irqreturn_t wm_halo_bus_error(int irq, void *data) + ret = regmap_read(regmap, dsp->base_sysinfo + HALO_AHBM_WINDOW_DEBUG_1, + fault); + if (ret) { +- adsp_warn(dsp, "Failed to read AHB DEBUG_1: %d\n", ret); ++ cs_dsp_warn(dsp, "Failed to read AHB DEBUG_1: %d\n", ret); + goto exit_unlock; + } + +- adsp_warn(dsp, "AHB: STATUS: 0x%x ADDR: 0x%x\n", +- *fault & HALO_AHBM_FLAGS_ERR_MASK, +- (*fault & HALO_AHBM_CORE_ERR_ADDR_MASK) >> +- HALO_AHBM_CORE_ERR_ADDR_SHIFT); ++ cs_dsp_warn(dsp, "AHB: STATUS: 0x%x ADDR: 0x%x\n", ++ *fault & HALO_AHBM_FLAGS_ERR_MASK, ++ (*fault & HALO_AHBM_CORE_ERR_ADDR_MASK) >> ++ HALO_AHBM_CORE_ERR_ADDR_SHIFT); + + ret = regmap_read(regmap, dsp->base_sysinfo + HALO_AHBM_WINDOW_DEBUG_0, + fault); + if (ret) { +- adsp_warn(dsp, "Failed to read AHB DEBUG_0: %d\n", ret); ++ cs_dsp_warn(dsp, "Failed to read AHB DEBUG_0: %d\n", ret); + goto exit_unlock; + } + +- adsp_warn(dsp, "AHB: SYS_ADDR: 0x%x\n", *fault); ++ cs_dsp_warn(dsp, "AHB: SYS_ADDR: 0x%x\n", *fault); + + ret = regmap_bulk_read(regmap, dsp->base + HALO_MPU_XM_VIO_ADDR, + fault, ARRAY_SIZE(fault)); + if (ret) { +- adsp_warn(dsp, "Failed to read MPU fault info: %d\n", ret); ++ cs_dsp_warn(dsp, "Failed to read MPU fault info: %d\n", ret); + goto exit_unlock; + } + +- adsp_warn(dsp, "XM: STATUS:0x%x ADDR:0x%x\n", fault[1], fault[0]); +- adsp_warn(dsp, "YM: STATUS:0x%x ADDR:0x%x\n", fault[3], fault[2]); +- adsp_warn(dsp, "PM: STATUS:0x%x ADDR:0x%x\n", fault[5], fault[4]); ++ cs_dsp_warn(dsp, "XM: STATUS:0x%x ADDR:0x%x\n", fault[1], fault[0]); ++ cs_dsp_warn(dsp, "YM: STATUS:0x%x ADDR:0x%x\n", fault[3], fault[2]); ++ cs_dsp_warn(dsp, "PM: STATUS:0x%x ADDR:0x%x\n", fault[5], fault[4]); + + ret = regmap_multi_reg_write(dsp->regmap, clear, ARRAY_SIZE(clear)); + if (ret) +- adsp_warn(dsp, "Failed to clear MPU status: %d\n", ret); ++ cs_dsp_warn(dsp, "Failed to clear MPU status: %d\n", ret); + + exit_unlock: + mutex_unlock(&dsp->pwr_lock); +@@ -4469,7 +4475,8 @@ irqreturn_t wm_halo_wdt_expire(int irq, void *data) + + mutex_lock(&dsp->pwr_lock); + +- adsp_warn(dsp, "WDT Expiry Fault\n"); ++ cs_dsp_warn(dsp, "WDT Expiry Fault\n"); ++ + dsp->ops->stop_watchdog(dsp); + wm_adsp_fatal_error(dsp); + +-- +2.35.3 + diff --git a/patches.suse/ASoC-wm_adsp-Make-compressed-buffers-optional.patch b/patches.suse/ASoC-wm_adsp-Make-compressed-buffers-optional.patch new file mode 100644 index 0000000..c535e6d --- /dev/null +++ b/patches.suse/ASoC-wm_adsp-Make-compressed-buffers-optional.patch @@ -0,0 +1,171 @@ +From 0f1d41a85bda6f3502634fe15fa21bfee4c668a4 Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Thu, 10 Feb 2022 17:20:52 +0000 +Subject: [PATCH] ASoC: wm_adsp: Make compressed buffers optional +Git-commit: 0f1d41a85bda6f3502634fe15fa21bfee4c668a4 +Patch-mainline: v5.18-rc1 +References: bsc#1203699 + +Newer firmwares will support compressed buffers that may or may not +exist, for example debugging streams. Update the driver to make a +compressed stream optional. A warning will still be generated at DSP +boot time and opening the stream will fail if the compressed buffer in +question does not exist, however the DSP can still be booted and other +features used. + +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20220210172053.22782-2-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/wm_adsp.c | 54 +++++++++++++++++++++++--------------- + 1 file changed, 33 insertions(+), 21 deletions(-) + +diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c +index f3672e3d1703..8b9726f400a9 100644 +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -1373,8 +1373,6 @@ static struct wm_adsp_compr_buf *wm_adsp_buffer_alloc(struct wm_adsp *dsp) + + wm_adsp_buffer_clear(buf); + +- list_add_tail(&buf->list, &dsp->buffer_list); +- + return buf; + } + +@@ -1391,10 +1389,6 @@ static int wm_adsp_buffer_parse_legacy(struct wm_adsp *dsp) + return -EINVAL; + } + +- buf = wm_adsp_buffer_alloc(dsp); +- if (!buf) +- return -ENOMEM; +- + xmalg = dsp->sys_config_size / sizeof(__be32); + + addr = alg_region->base + xmalg + ALG_XM_FIELD(magic); +@@ -1405,12 +1399,16 @@ static int wm_adsp_buffer_parse_legacy(struct wm_adsp *dsp) + if (magic != WM_ADSP_ALG_XM_STRUCT_MAGIC) + return -ENODEV; + ++ buf = wm_adsp_buffer_alloc(dsp); ++ if (!buf) ++ return -ENOMEM; ++ + addr = alg_region->base + xmalg + ALG_XM_FIELD(host_buf_ptr); + for (i = 0; i < 5; ++i) { + ret = cs_dsp_read_data_word(&dsp->cs_dsp, WMFW_ADSP2_XM, addr, + &buf->host_buf_ptr); + if (ret < 0) +- return ret; ++ goto err; + + if (buf->host_buf_ptr) + break; +@@ -1418,18 +1416,27 @@ static int wm_adsp_buffer_parse_legacy(struct wm_adsp *dsp) + usleep_range(1000, 2000); + } + +- if (!buf->host_buf_ptr) +- return -EIO; ++ if (!buf->host_buf_ptr) { ++ ret = -EIO; ++ goto err; ++ } + + buf->host_buf_mem_type = WMFW_ADSP2_XM; + + ret = wm_adsp_buffer_populate(buf); + if (ret < 0) +- return ret; ++ goto err; ++ ++ list_add_tail(&buf->list, &dsp->buffer_list); + + compr_dbg(buf, "legacy host_buf_ptr=%x\n", buf->host_buf_ptr); + + return 0; ++ ++err: ++ kfree(buf); ++ ++ return ret; + } + + static int wm_adsp_buffer_parse_coeff(struct cs_dsp_coeff_ctl *cs_ctl) +@@ -1437,7 +1444,7 @@ static int wm_adsp_buffer_parse_coeff(struct cs_dsp_coeff_ctl *cs_ctl) + struct wm_adsp_host_buf_coeff_v1 coeff_v1; + struct wm_adsp_compr_buf *buf; + struct wm_adsp *dsp = container_of(cs_ctl->dsp, struct wm_adsp, cs_dsp); +- unsigned int version; ++ unsigned int version = 0; + int ret, i; + + for (i = 0; i < 5; ++i) { +@@ -1465,16 +1472,14 @@ static int wm_adsp_buffer_parse_coeff(struct cs_dsp_coeff_ctl *cs_ctl) + + ret = wm_adsp_buffer_populate(buf); + if (ret < 0) +- return ret; ++ goto err; + + /* + * v0 host_buffer coefficients didn't have versioning, so if the + * control is one word, assume version 0. + */ +- if (cs_ctl->len == 4) { +- compr_dbg(buf, "host_buf_ptr=%x\n", buf->host_buf_ptr); +- return 0; +- } ++ if (cs_ctl->len == 4) ++ goto done; + + version = be32_to_cpu(coeff_v1.versions) & HOST_BUF_COEFF_COMPAT_VER_MASK; + version >>= HOST_BUF_COEFF_COMPAT_VER_SHIFT; +@@ -1483,7 +1488,8 @@ static int wm_adsp_buffer_parse_coeff(struct cs_dsp_coeff_ctl *cs_ctl) + adsp_err(dsp, + "Host buffer coeff ver %u > supported version %u\n", + version, HOST_BUF_COEFF_SUPPORTED_COMPAT_VER); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err; + } + + cs_dsp_remove_padding((u32 *)&coeff_v1.name, ARRAY_SIZE(coeff_v1.name)); +@@ -1491,10 +1497,18 @@ static int wm_adsp_buffer_parse_coeff(struct cs_dsp_coeff_ctl *cs_ctl) + buf->name = kasprintf(GFP_KERNEL, "%s-dsp-%s", dsp->part, + (char *)&coeff_v1.name); + ++done: ++ list_add_tail(&buf->list, &dsp->buffer_list); ++ + compr_dbg(buf, "host_buf_ptr=%x coeff version %u\n", + buf->host_buf_ptr, version); + + return version; ++ ++err: ++ kfree(buf); ++ ++ return ret; + } + + static int wm_adsp_buffer_init(struct wm_adsp *dsp) +@@ -1522,10 +1536,8 @@ static int wm_adsp_buffer_init(struct wm_adsp *dsp) + if (list_empty(&dsp->buffer_list)) { + /* Fall back to legacy support */ + ret = wm_adsp_buffer_parse_legacy(dsp); +- if (ret) { +- adsp_err(dsp, "Failed to parse legacy: %d\n", ret); +- goto error; +- } ++ if (ret) ++ adsp_warn(dsp, "Failed to parse legacy: %d\n", ret); + } + + return 0; +-- +2.35.3 + diff --git a/patches.suse/ASoC-wm_adsp-Minor-clean-and-redundant-code-removal.patch b/patches.suse/ASoC-wm_adsp-Minor-clean-and-redundant-code-removal.patch new file mode 100644 index 0000000..eddd331 --- /dev/null +++ b/patches.suse/ASoC-wm_adsp-Minor-clean-and-redundant-code-removal.patch @@ -0,0 +1,81 @@ +From e8010efc7b83038d1c18abe1b8d171e3c7d4ed92 Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Thu, 30 Jun 2022 11:14:59 +0100 +Subject: [PATCH] ASoC: wm_adsp: Minor clean and redundant code removal +Git-commit: e8010efc7b83038d1c18abe1b8d171e3c7d4ed92 +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +The cs_dsp core will return an error if passed a NULL cs_dsp struct so +there is no need for the wm_adsp_write|read_ctl functions to manually +check that. The cs_dsp core will also check the data is within bounds of +the control so the additional bounds check is redundant too. Simplify +things a bit by removing said code. + +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20220630101459.3442327-1-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/wm_adsp.c | 25 +++++-------------------- + 1 file changed, 5 insertions(+), 20 deletions(-) + +diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c +index a7784ac15dde..cfaa45ede916 100644 +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -675,21 +675,12 @@ static void wm_adsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl) + int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type, + unsigned int alg, void *buf, size_t len) + { +- struct cs_dsp_coeff_ctl *cs_ctl; ++ struct cs_dsp_coeff_ctl *cs_ctl = cs_dsp_get_ctl(&dsp->cs_dsp, name, type, alg); + struct wm_coeff_ctl *ctl; + struct snd_kcontrol *kcontrol; + char ctl_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; + int ret; + +- cs_ctl = cs_dsp_get_ctl(&dsp->cs_dsp, name, type, alg); +- if (!cs_ctl) +- return -EINVAL; +- +- ctl = cs_ctl->priv; +- +- if (len > cs_ctl->len) +- return -EINVAL; +- + ret = cs_dsp_coeff_write_ctrl(cs_ctl, 0, buf, len); + if (ret) + return ret; +@@ -697,6 +688,8 @@ int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type, + if (cs_ctl->flags & WMFW_CTL_FLAG_SYS) + return 0; + ++ ctl = cs_ctl->priv; ++ + if (dsp->component->name_prefix) + snprintf(ctl_name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s %s", + dsp->component->name_prefix, ctl->name); +@@ -720,16 +713,8 @@ EXPORT_SYMBOL_GPL(wm_adsp_write_ctl); + int wm_adsp_read_ctl(struct wm_adsp *dsp, const char *name, int type, + unsigned int alg, void *buf, size_t len) + { +- struct cs_dsp_coeff_ctl *cs_ctl; +- +- cs_ctl = cs_dsp_get_ctl(&dsp->cs_dsp, name, type, alg); +- if (!cs_ctl) +- return -EINVAL; +- +- if (len > cs_ctl->len) +- return -EINVAL; +- +- return cs_dsp_coeff_read_ctrl(cs_ctl, 0, buf, len); ++ return cs_dsp_coeff_read_ctrl(cs_dsp_get_ctl(&dsp->cs_dsp, name, type, alg), ++ 0, buf, len); + } + EXPORT_SYMBOL_GPL(wm_adsp_read_ctl); + +-- +2.35.3 + diff --git a/patches.suse/ASoC-wm_adsp-Move-check-for-control-existence.patch b/patches.suse/ASoC-wm_adsp-Move-check-for-control-existence.patch new file mode 100644 index 0000000..a344045 --- /dev/null +++ b/patches.suse/ASoC-wm_adsp-Move-check-for-control-existence.patch @@ -0,0 +1,64 @@ +From 6477960755fb2c0ca9b0497bc86abfa4ee173556 Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Mon, 13 Sep 2021 17:00:43 +0100 +Subject: [PATCH] ASoC: wm_adsp: Move check for control existence +Git-commit: 6477960755fb2c0ca9b0497bc86abfa4ee173556 +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +Checking earlier in the function if a control already exists avoids +superfluous string construction and also prepares for future +refactoring. + +Signed-off-by: Charles Keepax +Signed-off-by: Simon Trimmer +Link: https://lore.kernel.org/r/20210913160057.103842-3-simont@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/wm_adsp.c | 21 +++++++++++++-------- + 1 file changed, 13 insertions(+), 8 deletions(-) + +diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c +index f5db6e3b9f60..b300af6fdd41 100644 +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -1422,6 +1422,19 @@ static int wm_adsp_create_control(struct wm_adsp *dsp, + const char *region_name; + int ret; + ++ list_for_each_entry(ctl, &dsp->ctl_list, list) { ++ if (ctl->fw_name == wm_adsp_fw_text[dsp->fw] && ++ ctl->alg_region.alg == alg_region->alg && ++ ctl->alg_region.type == alg_region->type) { ++ if ((!subname && !ctl->subname) || ++ (subname && !strncmp(ctl->subname, subname, ctl->subname_len))) { ++ if (!ctl->enabled) ++ ctl->enabled = 1; ++ return 0; ++ } ++ } ++ } ++ + region_name = wm_adsp_mem_region_name(alg_region->type); + if (!region_name) { + adsp_err(dsp, "Unknown region type: %d\n", alg_region->type); +@@ -1462,14 +1475,6 @@ static int wm_adsp_create_control(struct wm_adsp *dsp, + " %.*s", subname_len - skip, subname + skip); + } + +- list_for_each_entry(ctl, &dsp->ctl_list, list) { +- if (!strcmp(ctl->name, name)) { +- if (!ctl->enabled) +- ctl->enabled = 1; +- return 0; +- } +- } +- + ctl = kzalloc(sizeof(*ctl), GFP_KERNEL); + if (!ctl) + return -ENOMEM; +-- +2.35.3 + diff --git a/patches.suse/ASoC-wm_adsp-Move-check-of-dsp-running-to-better-pla.patch b/patches.suse/ASoC-wm_adsp-Move-check-of-dsp-running-to-better-pla.patch new file mode 100644 index 0000000..e0caeff --- /dev/null +++ b/patches.suse/ASoC-wm_adsp-Move-check-of-dsp-running-to-better-pla.patch @@ -0,0 +1,48 @@ +From edb1d6d7f03913b2b6ca299b1f6fd8dc96d511f5 Mon Sep 17 00:00:00 2001 +From: Simon Trimmer +Date: Mon, 13 Sep 2021 17:00:52 +0100 +Subject: [PATCH] ASoC: wm_adsp: Move check of dsp->running to better place +Git-commit: edb1d6d7f03913b2b6ca299b1f6fd8dc96d511f5 +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +In preparation for moving the generic DSP support out of ASoC, move +the check of dsp->running to a more appropriate place that will move +to the generic code. + +Signed-off-by: Simon Trimmer +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20210913160057.103842-12-simont@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/wm_adsp.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c +index bd335e4240e5..1c8bf818dab9 100644 +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -976,6 +976,9 @@ static int cs_dsp_coeff_write_acked_control(struct cs_dsp_coeff_ctl *ctl, + unsigned int reg; + int i, ret; + ++ if (!dsp->running) ++ return -EPERM; ++ + ret = cs_dsp_coeff_base_reg(ctl, ®); + if (ret) + return ret; +@@ -1129,7 +1132,7 @@ static int wm_coeff_put_acked(struct snd_kcontrol *kctl, + + mutex_lock(&cs_ctl->dsp->pwr_lock); + +- if (cs_ctl->enabled && cs_ctl->dsp->running) ++ if (cs_ctl->enabled) + ret = cs_dsp_coeff_write_acked_control(cs_ctl, val); + else + ret = -EPERM; +-- +2.35.3 + diff --git a/patches.suse/ASoC-wm_adsp-Move-sys_config_size-to-wm_adsp.patch b/patches.suse/ASoC-wm_adsp-Move-sys_config_size-to-wm_adsp.patch new file mode 100644 index 0000000..0d3f06b --- /dev/null +++ b/patches.suse/ASoC-wm_adsp-Move-sys_config_size-to-wm_adsp.patch @@ -0,0 +1,110 @@ +From 6092be2d93b3b28dfeca4e5944052a1a21f51ca3 Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Mon, 13 Sep 2021 17:00:50 +0100 +Subject: [PATCH] ASoC: wm_adsp: Move sys_config_size to wm_adsp +Git-commit: 6092be2d93b3b28dfeca4e5944052a1a21f51ca3 +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +sys_config_size is part of the compressed stream support, move it from +what will become generic DSP code so that it remains in ASoC. + +Signed-off-by: Charles Keepax +Signed-off-by: Simon Trimmer +Link: https://lore.kernel.org/r/20210913160057.103842-10-simont@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/wm_adsp.c | 10 +++++----- + sound/soc/codecs/wm_adsp.h | 4 ++-- + 2 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c +index 1bca3922a6b8..82038cac4286 100644 +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -3467,6 +3467,8 @@ int wm_adsp2_init(struct wm_adsp *dsp) + { + INIT_WORK(&dsp->boot_work, wm_adsp_boot_work); + ++ dsp->sys_config_size = sizeof(struct wm_adsp_system_config_xm_hdr); ++ + wm_adsp_common_init(dsp); + + return cs_dsp_adsp2_init(dsp); +@@ -3484,6 +3486,8 @@ int wm_halo_init(struct wm_adsp *dsp) + { + INIT_WORK(&dsp->boot_work, wm_adsp_boot_work); + ++ dsp->sys_config_size = sizeof(struct wm_halo_system_config_xm_hdr); ++ + wm_adsp_common_init(dsp); + + return cs_dsp_halo_init(dsp); +@@ -3895,7 +3899,7 @@ static int wm_adsp_buffer_parse_legacy(struct wm_adsp *dsp) + if (!buf) + return -ENOMEM; + +- xmalg = dsp->ops->sys_config_size / sizeof(__be32); ++ xmalg = dsp->sys_config_size / sizeof(__be32); + + addr = alg_region->base + xmalg + ALG_XM_FIELD(magic); + ret = cs_dsp_read_data_word(dsp, WMFW_ADSP2_XM, addr, &magic); +@@ -4588,7 +4592,6 @@ static const struct cs_dsp_ops cs_dsp_adsp1_ops = { + + static const struct cs_dsp_ops cs_dsp_adsp2_ops[] = { + { +- .sys_config_size = sizeof(struct wm_adsp_system_config_xm_hdr), + .parse_sizes = cs_dsp_adsp2_parse_sizes, + .validate_version = cs_dsp_validate_version, + .setup_algs = cs_dsp_adsp2_setup_algs, +@@ -4607,7 +4610,6 @@ static const struct cs_dsp_ops cs_dsp_adsp2_ops[] = { + + }, + { +- .sys_config_size = sizeof(struct wm_adsp_system_config_xm_hdr), + .parse_sizes = cs_dsp_adsp2_parse_sizes, + .validate_version = cs_dsp_validate_version, + .setup_algs = cs_dsp_adsp2_setup_algs, +@@ -4626,7 +4628,6 @@ static const struct cs_dsp_ops cs_dsp_adsp2_ops[] = { + .stop_core = cs_dsp_adsp2_stop_core, + }, + { +- .sys_config_size = sizeof(struct wm_adsp_system_config_xm_hdr), + .parse_sizes = cs_dsp_adsp2_parse_sizes, + .validate_version = cs_dsp_validate_version, + .setup_algs = cs_dsp_adsp2_setup_algs, +@@ -4648,7 +4649,6 @@ static const struct cs_dsp_ops cs_dsp_adsp2_ops[] = { + }; + + static const struct cs_dsp_ops cs_dsp_halo_ops = { +- .sys_config_size = sizeof(struct wm_halo_system_config_xm_hdr), + .parse_sizes = cs_dsp_adsp2_parse_sizes, + .validate_version = cs_dsp_halo_validate_version, + .setup_algs = cs_dsp_halo_setup_algs, +diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h +index 114bc41981ef..98b12b485916 100644 +--- a/sound/soc/codecs/wm_adsp.h ++++ b/sound/soc/codecs/wm_adsp.h +@@ -81,6 +81,8 @@ struct wm_adsp { + const struct cs_dsp_region *mem; + int num_mems; + ++ unsigned int sys_config_size; ++ + int fw; + int fw_ver; + +@@ -109,8 +111,6 @@ struct wm_adsp { + }; + + struct cs_dsp_ops { +- unsigned int sys_config_size; +- + bool (*validate_version)(struct wm_adsp *dsp, unsigned int version); + unsigned int (*parse_sizes)(struct wm_adsp *dsp, + const char * const file, +-- +2.35.3 + diff --git a/patches.suse/ASoC-wm_adsp-Pass-firmware-names-as-parameters-when-.patch b/patches.suse/ASoC-wm_adsp-Pass-firmware-names-as-parameters-when-.patch new file mode 100644 index 0000000..8ce8fc5 --- /dev/null +++ b/patches.suse/ASoC-wm_adsp-Pass-firmware-names-as-parameters-when-.patch @@ -0,0 +1,215 @@ +From 2169f2f15185f9393b1c16eac6e7c7d4adb6279b Mon Sep 17 00:00:00 2001 +From: Simon Trimmer +Date: Mon, 13 Sep 2021 17:00:53 +0100 +Subject: [PATCH] ASoC: wm_adsp: Pass firmware names as parameters when starting DSP core +Git-commit: 2169f2f15185f9393b1c16eac6e7c7d4adb6279b +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +As preparation for moving the generic DSP support out of ASoC pass the +firmware names used when loading files as parameters as the generic code +can't refer directly to the array specific to wm_adsp. The code +remaining in wm_adsp.c doesn't need to change, it can continue to use +the string arrays directly. + +Signed-off-by: Simon Trimmer +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20210913160057.103842-13-simont@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/wm_adsp.c | 43 +++++++++++++++++++++++--------------- + sound/soc/codecs/wm_adsp.h | 1 + + 2 files changed, 27 insertions(+), 17 deletions(-) + +diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c +index 1c8bf818dab9..c2e1eb8ff357 100644 +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -1499,7 +1499,7 @@ static int cs_dsp_create_control(struct wm_adsp *dsp, + int ret; + + list_for_each_entry(ctl, &dsp->ctl_list, list) { +- if (ctl->fw_name == wm_adsp_fw_text[dsp->fw] && ++ if (ctl->fw_name == dsp->fw_name && + ctl->alg_region.alg == alg_region->alg && + ctl->alg_region.type == alg_region->type) { + if ((!subname && !ctl->subname) || +@@ -1514,7 +1514,8 @@ static int cs_dsp_create_control(struct wm_adsp *dsp, + ctl = kzalloc(sizeof(*ctl), GFP_KERNEL); + if (!ctl) + return -ENOMEM; +- ctl->fw_name = wm_adsp_fw_text[dsp->fw]; ++ ++ ctl->fw_name = dsp->fw_name; + ctl->alg_region = *alg_region; + if (subname && dsp->fw_ver >= 2) { + ctl->subname_len = subname_len; +@@ -1836,7 +1837,7 @@ static bool cs_dsp_halo_validate_version(struct wm_adsp *dsp, unsigned int versi + } + } + +-static int cs_dsp_load(struct wm_adsp *dsp) ++static int cs_dsp_load(struct wm_adsp *dsp, const char *fw_file_name) + { + LIST_HEAD(buf_list); + const struct firmware *firmware; +@@ -1859,7 +1860,7 @@ static int cs_dsp_load(struct wm_adsp *dsp) + return -ENOMEM; + + snprintf(file, PAGE_SIZE, "%s-%s-%s.wmfw", dsp->part, dsp->fwf_name, +- wm_adsp_fw[dsp->fw].file); ++ fw_file_name); + file[PAGE_SIZE - 1] = '\0'; + + ret = request_firmware(&firmware, file, dsp->dev); +@@ -2047,13 +2048,12 @@ static struct cs_dsp_coeff_ctl *cs_dsp_get_ctl(struct wm_adsp *dsp, + unsigned int alg) + { + struct cs_dsp_coeff_ctl *pos, *rslt = NULL; +- const char *fw_txt = wm_adsp_fw_text[dsp->fw]; + + list_for_each_entry(pos, &dsp->ctl_list, list) { + if (!pos->subname) + continue; + if (strncmp(pos->subname, name, pos->subname_len) == 0 && +- pos->fw_name == fw_txt && ++ pos->fw_name == dsp->fw_name && + pos->alg_region.alg == alg && + pos->alg_region.type == type) { + rslt = pos; +@@ -2131,7 +2131,7 @@ static void cs_dsp_ctl_fixup_base(struct wm_adsp *dsp, + struct cs_dsp_coeff_ctl *ctl; + + list_for_each_entry(ctl, &dsp->ctl_list, list) { +- if (ctl->fw_name == wm_adsp_fw_text[dsp->fw] && ++ if (ctl->fw_name == dsp->fw_name && + alg_region->alg == ctl->alg_region.alg && + alg_region->type == ctl->alg_region.type) { + ctl->alg_region.base = alg_region->base; +@@ -2582,7 +2582,7 @@ static int cs_dsp_halo_setup_algs(struct wm_adsp *dsp) + return ret; + } + +-static int cs_dsp_load_coeff(struct wm_adsp *dsp) ++static int cs_dsp_load_coeff(struct wm_adsp *dsp, const char *fw_file_name) + { + LIST_HEAD(buf_list); + struct regmap *regmap = dsp->regmap; +@@ -2601,7 +2601,7 @@ static int cs_dsp_load_coeff(struct wm_adsp *dsp) + return -ENOMEM; + + snprintf(file, PAGE_SIZE, "%s-%s-%s.bin", dsp->part, dsp->fwf_name, +- wm_adsp_fw[dsp->fw].file); ++ fw_file_name); + file[PAGE_SIZE - 1] = '\0'; + + ret = request_firmware(&firmware, file, dsp->dev); +@@ -2837,13 +2837,15 @@ int wm_adsp1_init(struct wm_adsp *dsp) + } + EXPORT_SYMBOL_GPL(wm_adsp1_init); + +-static int cs_dsp_adsp1_power_up(struct wm_adsp *dsp) ++static int cs_dsp_adsp1_power_up(struct wm_adsp *dsp, const char *fw_file_name, const char *fw_name) + { + unsigned int val; + int ret; + + mutex_lock(&dsp->pwr_lock); + ++ dsp->fw_name = fw_name; ++ + regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, + ADSP1_SYS_ENA, ADSP1_SYS_ENA); + +@@ -2869,7 +2871,7 @@ static int cs_dsp_adsp1_power_up(struct wm_adsp *dsp) + } + } + +- ret = cs_dsp_load(dsp); ++ ret = cs_dsp_load(dsp, fw_file_name); + if (ret != 0) + goto err_ena; + +@@ -2877,7 +2879,7 @@ static int cs_dsp_adsp1_power_up(struct wm_adsp *dsp) + if (ret != 0) + goto err_ena; + +- ret = cs_dsp_load_coeff(dsp); ++ ret = cs_dsp_load_coeff(dsp, fw_file_name); + if (ret != 0) + goto err_ena; + +@@ -2952,7 +2954,9 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, + + switch (event) { + case SND_SOC_DAPM_POST_PMU: +- ret = cs_dsp_adsp1_power_up(dsp); ++ ret = cs_dsp_adsp1_power_up(dsp, ++ wm_adsp_fw[dsp->fw].file, ++ wm_adsp_fw_text[dsp->fw]); + break; + case SND_SOC_DAPM_PRE_PMD: + cs_dsp_adsp1_power_down(dsp); +@@ -3172,12 +3176,15 @@ static void cs_dsp_halo_stop_watchdog(struct wm_adsp *dsp) + HALO_WDT_EN_MASK, 0); + } + +-static void cs_dsp_power_up(struct wm_adsp *dsp) ++static void cs_dsp_power_up(struct wm_adsp *dsp, const char *fw_file_name, ++ const char *fw_name) + { + int ret; + + mutex_lock(&dsp->pwr_lock); + ++ dsp->fw_name = fw_name; ++ + if (dsp->ops->enable_memory) { + ret = dsp->ops->enable_memory(dsp); + if (ret != 0) +@@ -3190,7 +3197,7 @@ static void cs_dsp_power_up(struct wm_adsp *dsp) + goto err_mem; + } + +- ret = cs_dsp_load(dsp); ++ ret = cs_dsp_load(dsp, fw_file_name); + if (ret != 0) + goto err_ena; + +@@ -3198,7 +3205,7 @@ static void cs_dsp_power_up(struct wm_adsp *dsp) + if (ret != 0) + goto err_ena; + +- ret = cs_dsp_load_coeff(dsp); ++ ret = cs_dsp_load_coeff(dsp, fw_file_name); + if (ret != 0) + goto err_ena; + +@@ -3258,7 +3265,9 @@ static void wm_adsp_boot_work(struct work_struct *work) + struct wm_adsp, + boot_work); + +- cs_dsp_power_up(dsp); ++ cs_dsp_power_up(dsp, ++ wm_adsp_fw[dsp->fw].file, ++ wm_adsp_fw_text[dsp->fw]); + } + + int wm_adsp_early_event(struct snd_soc_dapm_widget *w, +diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h +index eee298e94946..3bad022c4bb1 100644 +--- a/sound/soc/codecs/wm_adsp.h ++++ b/sound/soc/codecs/wm_adsp.h +@@ -94,6 +94,7 @@ struct wm_adsp { + + struct list_head alg_regions; + ++ const char *fw_name; + unsigned int fw_id; + unsigned int fw_id_version; + unsigned int fw_vendor_id; +-- +2.35.3 + diff --git a/patches.suse/ASoC-wm_adsp-Remove-pointless-string-comparison.patch b/patches.suse/ASoC-wm_adsp-Remove-pointless-string-comparison.patch new file mode 100644 index 0000000..1a91ab1 --- /dev/null +++ b/patches.suse/ASoC-wm_adsp-Remove-pointless-string-comparison.patch @@ -0,0 +1,42 @@ +From 2ba907894f9e69b68e5934b57afb744482a72984 Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Sat, 26 Jun 2021 16:59:41 +0100 +Subject: [PATCH] ASoC: wm_adsp: Remove pointless string comparison +Git-commit: 2ba907894f9e69b68e5934b57afb744482a72984 +Patch-mainline: v5.15-rc1 +References: bsc#1203699 + +The control fw_name is always directly assigned from the wm_adsp_fw_text +array, so it isn't necessary to compare the actual strings just the +pointer values. + +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20210626155941.12251-3-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/wm_adsp.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c +index 549d98241dae..b395df1eb72d 100644 +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -2030,10 +2030,9 @@ static struct wm_coeff_ctl *wm_adsp_get_ctl(struct wm_adsp *dsp, + if (!pos->subname) + continue; + if (strncmp(pos->subname, name, pos->subname_len) == 0 && +- strncmp(pos->fw_name, fw_txt, +- SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == 0 && +- pos->alg_region.alg == alg && +- pos->alg_region.type == type) { ++ pos->fw_name == fw_txt && ++ pos->alg_region.alg == alg && ++ pos->alg_region.type == type) { + rslt = pos; + break; + } +-- +2.35.3 + diff --git a/patches.suse/ASoC-wm_adsp-Remove-the-wmfw_add_ctl-helper-function.patch b/patches.suse/ASoC-wm_adsp-Remove-the-wmfw_add_ctl-helper-function.patch new file mode 100644 index 0000000..5d3635e --- /dev/null +++ b/patches.suse/ASoC-wm_adsp-Remove-the-wmfw_add_ctl-helper-function.patch @@ -0,0 +1,83 @@ +From 56717d72f7a811799e8d138ff3d49325272c5cf6 Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Wed, 17 Nov 2021 13:22:51 +0000 +Subject: [PATCH] ASoC: wm_adsp: Remove the wmfw_add_ctl helper function +Git-commit: 56717d72f7a811799e8d138ff3d49325272c5cf6 +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +The helper function wmfw_add_ctl is only called from one place and that +place is a function with only 2 lines of code. Merge the helper function +into the work function to simplify the code. + +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20211117132300.1290-1-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/wm_adsp.c | 33 +++++++++------------------------ + 1 file changed, 9 insertions(+), 24 deletions(-) + +diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c +index d4f0d72cbcc8..404717e30f44 100644 +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -537,15 +537,20 @@ static unsigned int wmfw_convert_flags(unsigned int in, unsigned int len) + return out; + } + +-static int wmfw_add_ctl(struct wm_adsp *dsp, struct wm_coeff_ctl *ctl) ++static void wm_adsp_ctl_work(struct work_struct *work) + { ++ struct wm_coeff_ctl *ctl = container_of(work, ++ struct wm_coeff_ctl, ++ work); + struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl; ++ struct wm_adsp *dsp = container_of(cs_ctl->dsp, ++ struct wm_adsp, ++ cs_dsp); + struct snd_kcontrol_new *kcontrol; +- int ret; + + kcontrol = kzalloc(sizeof(*kcontrol), GFP_KERNEL); + if (!kcontrol) +- return -ENOMEM; ++ return; + + kcontrol->name = ctl->name; + kcontrol->info = wm_coeff_info; +@@ -571,29 +576,9 @@ static int wmfw_add_ctl(struct wm_adsp *dsp, struct wm_coeff_ctl *ctl) + break; + } + +- ret = snd_soc_add_component_controls(dsp->component, kcontrol, 1); +- if (ret < 0) +- goto err_kcontrol; ++ snd_soc_add_component_controls(dsp->component, kcontrol, 1); + + kfree(kcontrol); +- +- return 0; +- +-err_kcontrol: +- kfree(kcontrol); +- return ret; +-} +- +-static void wm_adsp_ctl_work(struct work_struct *work) +-{ +- struct wm_coeff_ctl *ctl = container_of(work, +- struct wm_coeff_ctl, +- work); +- struct wm_adsp *dsp = container_of(ctl->cs_ctl->dsp, +- struct wm_adsp, +- cs_dsp); +- +- wmfw_add_ctl(dsp, ctl); + } + + static int wm_adsp_control_add(struct cs_dsp_coeff_ctl *cs_ctl) +-- +2.35.3 + diff --git a/patches.suse/ASoC-wm_adsp-Remove-use-of-snd_ctl_elem_type_t.patch b/patches.suse/ASoC-wm_adsp-Remove-use-of-snd_ctl_elem_type_t.patch new file mode 100644 index 0000000..8d59236 --- /dev/null +++ b/patches.suse/ASoC-wm_adsp-Remove-use-of-snd_ctl_elem_type_t.patch @@ -0,0 +1,152 @@ +From d07a6d454ffa310ee306d57f486eb64380bbdfff Mon Sep 17 00:00:00 2001 +From: Simon Trimmer +Date: Mon, 13 Sep 2021 17:00:42 +0100 +Subject: [PATCH] ASoC: wm_adsp: Remove use of snd_ctl_elem_type_t +Git-commit: d07a6d454ffa310ee306d57f486eb64380bbdfff +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +In preparation for moving the generic DSP support out of ASoC, remove +the use of the ALSA specific types for the control type. The use of an +ALSA type was unnecessary, the simplified code is easier to read and +avoids Sparse warnings. + +Signed-off-by: Simon Trimmer +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20210913160057.103842-2-simont@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/wm_adsp.c | 24 +++++++++++------------- + sound/soc/codecs/wmfw.h | 8 +++++--- + 2 files changed, 16 insertions(+), 16 deletions(-) + +diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c +index f7c800927cb2..f5db6e3b9f60 100644 +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -612,7 +612,7 @@ struct wm_coeff_ctl { + unsigned int set:1; + struct soc_bytes_ext bytes_ext; + unsigned int flags; +- snd_ctl_elem_type_t type; ++ unsigned int type; + }; + + static const char *wm_adsp_mem_region_name(unsigned int type) +@@ -1414,7 +1414,7 @@ static int wm_adsp_create_control(struct wm_adsp *dsp, + const struct wm_adsp_alg_region *alg_region, + unsigned int offset, unsigned int len, + const char *subname, unsigned int subname_len, +- unsigned int flags, snd_ctl_elem_type_t type) ++ unsigned int flags, unsigned int type) + { + struct wm_coeff_ctl *ctl; + struct wmfw_ctl_work *ctl_work; +@@ -1546,7 +1546,7 @@ struct wm_coeff_parsed_coeff { + int mem_type; + const u8 *name; + int name_len; +- snd_ctl_elem_type_t ctl_type; ++ unsigned int ctl_type; + int flags; + int len; + }; +@@ -1641,7 +1641,7 @@ static inline void wm_coeff_parse_coeff(struct wm_adsp *dsp, const u8 **data, + blk->mem_type = le16_to_cpu(raw->hdr.type); + blk->name = raw->name; + blk->name_len = strlen(raw->name); +- blk->ctl_type = (__force snd_ctl_elem_type_t)le16_to_cpu(raw->ctl_type); ++ blk->ctl_type = le16_to_cpu(raw->ctl_type); + blk->flags = le16_to_cpu(raw->flags); + blk->len = le32_to_cpu(raw->len); + break; +@@ -1654,9 +1654,7 @@ static inline void wm_coeff_parse_coeff(struct wm_adsp *dsp, const u8 **data, + &blk->name); + wm_coeff_parse_string(sizeof(u8), &tmp, NULL); + wm_coeff_parse_string(sizeof(u16), &tmp, NULL); +- blk->ctl_type = +- (__force snd_ctl_elem_type_t)wm_coeff_parse_int(sizeof(raw->ctl_type), +- &tmp); ++ blk->ctl_type = wm_coeff_parse_int(sizeof(raw->ctl_type), &tmp); + blk->flags = wm_coeff_parse_int(sizeof(raw->flags), &tmp); + blk->len = wm_coeff_parse_int(sizeof(raw->len), &tmp); + +@@ -1701,7 +1699,7 @@ static int wm_adsp_parse_coeff(struct wm_adsp *dsp, + wm_coeff_parse_coeff(dsp, &data, &coeff_blk); + + switch (coeff_blk.ctl_type) { +- case SNDRV_CTL_ELEM_TYPE_BYTES: ++ case WMFW_CTL_TYPE_BYTES: + break; + case WMFW_CTL_TYPE_ACKED: + if (coeff_blk.flags & WMFW_CTL_FLAG_SYS) +@@ -2322,7 +2320,7 @@ static int wm_adsp1_setup_algs(struct wm_adsp *dsp) + len *= 4; + wm_adsp_create_control(dsp, alg_region, 0, + len, NULL, 0, 0, +- SNDRV_CTL_ELEM_TYPE_BYTES); ++ WMFW_CTL_TYPE_BYTES); + } else { + adsp_warn(dsp, "Missing length info for region DM with ID %x\n", + be32_to_cpu(adsp1_alg[i].alg.id)); +@@ -2343,7 +2341,7 @@ static int wm_adsp1_setup_algs(struct wm_adsp *dsp) + len *= 4; + wm_adsp_create_control(dsp, alg_region, 0, + len, NULL, 0, 0, +- SNDRV_CTL_ELEM_TYPE_BYTES); ++ WMFW_CTL_TYPE_BYTES); + } else { + adsp_warn(dsp, "Missing length info for region ZM with ID %x\n", + be32_to_cpu(adsp1_alg[i].alg.id)); +@@ -2430,7 +2428,7 @@ static int wm_adsp2_setup_algs(struct wm_adsp *dsp) + len *= 4; + wm_adsp_create_control(dsp, alg_region, 0, + len, NULL, 0, 0, +- SNDRV_CTL_ELEM_TYPE_BYTES); ++ WMFW_CTL_TYPE_BYTES); + } else { + adsp_warn(dsp, "Missing length info for region XM with ID %x\n", + be32_to_cpu(adsp2_alg[i].alg.id)); +@@ -2451,7 +2449,7 @@ static int wm_adsp2_setup_algs(struct wm_adsp *dsp) + len *= 4; + wm_adsp_create_control(dsp, alg_region, 0, + len, NULL, 0, 0, +- SNDRV_CTL_ELEM_TYPE_BYTES); ++ WMFW_CTL_TYPE_BYTES); + } else { + adsp_warn(dsp, "Missing length info for region YM with ID %x\n", + be32_to_cpu(adsp2_alg[i].alg.id)); +@@ -2472,7 +2470,7 @@ static int wm_adsp2_setup_algs(struct wm_adsp *dsp) + len *= 4; + wm_adsp_create_control(dsp, alg_region, 0, + len, NULL, 0, 0, +- SNDRV_CTL_ELEM_TYPE_BYTES); ++ WMFW_CTL_TYPE_BYTES); + } else { + adsp_warn(dsp, "Missing length info for region ZM with ID %x\n", + be32_to_cpu(adsp2_alg[i].alg.id)); +diff --git a/sound/soc/codecs/wmfw.h b/sound/soc/codecs/wmfw.h +index f3d51602f85c..a19bf7c6fc8b 100644 +--- a/sound/soc/codecs/wmfw.h ++++ b/sound/soc/codecs/wmfw.h +@@ -23,10 +23,12 @@ + #define WMFW_CTL_FLAG_WRITEABLE 0x0002 + #define WMFW_CTL_FLAG_READABLE 0x0001 + ++#define WMFW_CTL_TYPE_BYTES 0x0004 /* byte control */ ++ + /* Non-ALSA coefficient types start at 0x1000 */ +-#define WMFW_CTL_TYPE_ACKED ((__force snd_ctl_elem_type_t)0x1000) /* acked control */ +-#define WMFW_CTL_TYPE_HOSTEVENT ((__force snd_ctl_elem_type_t)0x1001) /* event control */ +-#define WMFW_CTL_TYPE_HOST_BUFFER ((__force snd_ctl_elem_type_t)0x1002) /* host buffer pointer */ ++#define WMFW_CTL_TYPE_ACKED 0x1000 /* acked control */ ++#define WMFW_CTL_TYPE_HOSTEVENT 0x1001 /* event control */ ++#define WMFW_CTL_TYPE_HOST_BUFFER 0x1002 /* host buffer pointer */ + + struct wmfw_header { + char magic[4]; +-- +2.35.3 + diff --git a/patches.suse/ASoC-wm_adsp-Rename-generic-DSP-support.patch b/patches.suse/ASoC-wm_adsp-Rename-generic-DSP-support.patch new file mode 100644 index 0000000..80657dc --- /dev/null +++ b/patches.suse/ASoC-wm_adsp-Rename-generic-DSP-support.patch @@ -0,0 +1,2608 @@ +From 5beb8eeade2c03b55ae729c05bb9fa245633fe74 Mon Sep 17 00:00:00 2001 +From: Simon Trimmer +Date: Mon, 13 Sep 2021 17:00:46 +0100 +Subject: [PATCH] ASoC: wm_adsp: Rename generic DSP support +Git-commit: 5beb8eeade2c03b55ae729c05bb9fa245633fe74 +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +This rename is preparation for moving the generic DSP support out of +ASoC, generic code named wm_* will be renamed to cs_*. + +Signed-off-by: Simon Trimmer +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20210913160057.103842-6-simont@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs47l15.c | 4 +- + sound/soc/codecs/cs47l24.c | 6 +- + sound/soc/codecs/cs47l35.c | 8 +- + sound/soc/codecs/cs47l85.c | 16 +- + sound/soc/codecs/cs47l90.c | 18 +- + sound/soc/codecs/cs47l92.c | 4 +- + sound/soc/codecs/wm2200.c | 4 +- + sound/soc/codecs/wm5102.c | 2 +- + sound/soc/codecs/wm5110.c | 10 +- + sound/soc/codecs/wm_adsp.c | 826 ++++++++++++++++++------------------- + sound/soc/codecs/wm_adsp.h | 48 +-- + 11 files changed, 473 insertions(+), 473 deletions(-) + +diff --git a/sound/soc/codecs/cs47l15.c b/sound/soc/codecs/cs47l15.c +index 1ee83160b83f..07388701f89f 100644 +--- a/sound/soc/codecs/cs47l15.c ++++ b/sound/soc/codecs/cs47l15.c +@@ -45,7 +45,7 @@ struct cs47l15 { + bool in1_lp_mode; + }; + +-static const struct wm_adsp_region cs47l15_dsp1_regions[] = { ++static const struct cs_dsp_region cs47l15_dsp1_regions[] = { + { .type = WMFW_ADSP2_PM, .base = 0x080000 }, + { .type = WMFW_ADSP2_ZM, .base = 0x0e0000 }, + { .type = WMFW_ADSP2_XM, .base = 0x0a0000 }, +@@ -1413,7 +1413,7 @@ static int cs47l15_probe(struct platform_device *pdev) + cs47l15->core.adsp[0].num_mems = ARRAY_SIZE(cs47l15_dsp1_regions); + + cs47l15->core.adsp[0].lock_regions = +- WM_ADSP2_REGION_1 | WM_ADSP2_REGION_2 | WM_ADSP2_REGION_3; ++ CS_ADSP2_REGION_1 | CS_ADSP2_REGION_2 | CS_ADSP2_REGION_3; + + ret = wm_adsp2_init(&cs47l15->core.adsp[0]); + if (ret != 0) +diff --git a/sound/soc/codecs/cs47l24.c b/sound/soc/codecs/cs47l24.c +index 6b6d08816024..be81094dbf1e 100644 +--- a/sound/soc/codecs/cs47l24.c ++++ b/sound/soc/codecs/cs47l24.c +@@ -37,21 +37,21 @@ struct cs47l24_priv { + struct arizona_fll fll[2]; + }; + +-static const struct wm_adsp_region cs47l24_dsp2_regions[] = { ++static const struct cs_dsp_region cs47l24_dsp2_regions[] = { + { .type = WMFW_ADSP2_PM, .base = 0x200000 }, + { .type = WMFW_ADSP2_ZM, .base = 0x280000 }, + { .type = WMFW_ADSP2_XM, .base = 0x290000 }, + { .type = WMFW_ADSP2_YM, .base = 0x2a8000 }, + }; + +-static const struct wm_adsp_region cs47l24_dsp3_regions[] = { ++static const struct cs_dsp_region cs47l24_dsp3_regions[] = { + { .type = WMFW_ADSP2_PM, .base = 0x300000 }, + { .type = WMFW_ADSP2_ZM, .base = 0x380000 }, + { .type = WMFW_ADSP2_XM, .base = 0x390000 }, + { .type = WMFW_ADSP2_YM, .base = 0x3a8000 }, + }; + +-static const struct wm_adsp_region *cs47l24_dsp_regions[] = { ++static const struct cs_dsp_region *cs47l24_dsp_regions[] = { + cs47l24_dsp2_regions, + cs47l24_dsp3_regions, + }; +diff --git a/sound/soc/codecs/cs47l35.c b/sound/soc/codecs/cs47l35.c +index 3f04a2a74521..b8d594bf4d13 100644 +--- a/sound/soc/codecs/cs47l35.c ++++ b/sound/soc/codecs/cs47l35.c +@@ -37,28 +37,28 @@ struct cs47l35 { + struct madera_fll fll; + }; + +-static const struct wm_adsp_region cs47l35_dsp1_regions[] = { ++static const struct cs_dsp_region cs47l35_dsp1_regions[] = { + { .type = WMFW_ADSP2_PM, .base = 0x080000 }, + { .type = WMFW_ADSP2_ZM, .base = 0x0e0000 }, + { .type = WMFW_ADSP2_XM, .base = 0x0a0000 }, + { .type = WMFW_ADSP2_YM, .base = 0x0c0000 }, + }; + +-static const struct wm_adsp_region cs47l35_dsp2_regions[] = { ++static const struct cs_dsp_region cs47l35_dsp2_regions[] = { + { .type = WMFW_ADSP2_PM, .base = 0x100000 }, + { .type = WMFW_ADSP2_ZM, .base = 0x160000 }, + { .type = WMFW_ADSP2_XM, .base = 0x120000 }, + { .type = WMFW_ADSP2_YM, .base = 0x140000 }, + }; + +-static const struct wm_adsp_region cs47l35_dsp3_regions[] = { ++static const struct cs_dsp_region cs47l35_dsp3_regions[] = { + { .type = WMFW_ADSP2_PM, .base = 0x180000 }, + { .type = WMFW_ADSP2_ZM, .base = 0x1e0000 }, + { .type = WMFW_ADSP2_XM, .base = 0x1a0000 }, + { .type = WMFW_ADSP2_YM, .base = 0x1c0000 }, + }; + +-static const struct wm_adsp_region *cs47l35_dsp_regions[] = { ++static const struct cs_dsp_region *cs47l35_dsp_regions[] = { + cs47l35_dsp1_regions, + cs47l35_dsp2_regions, + cs47l35_dsp3_regions, +diff --git a/sound/soc/codecs/cs47l85.c b/sound/soc/codecs/cs47l85.c +index 748a180870bc..7ba08ca75c4f 100644 +--- a/sound/soc/codecs/cs47l85.c ++++ b/sound/soc/codecs/cs47l85.c +@@ -37,56 +37,56 @@ struct cs47l85 { + struct madera_fll fll[3]; + }; + +-static const struct wm_adsp_region cs47l85_dsp1_regions[] = { ++static const struct cs_dsp_region cs47l85_dsp1_regions[] = { + { .type = WMFW_ADSP2_PM, .base = 0x080000 }, + { .type = WMFW_ADSP2_ZM, .base = 0x0e0000 }, + { .type = WMFW_ADSP2_XM, .base = 0x0a0000 }, + { .type = WMFW_ADSP2_YM, .base = 0x0c0000 }, + }; + +-static const struct wm_adsp_region cs47l85_dsp2_regions[] = { ++static const struct cs_dsp_region cs47l85_dsp2_regions[] = { + { .type = WMFW_ADSP2_PM, .base = 0x100000 }, + { .type = WMFW_ADSP2_ZM, .base = 0x160000 }, + { .type = WMFW_ADSP2_XM, .base = 0x120000 }, + { .type = WMFW_ADSP2_YM, .base = 0x140000 }, + }; + +-static const struct wm_adsp_region cs47l85_dsp3_regions[] = { ++static const struct cs_dsp_region cs47l85_dsp3_regions[] = { + { .type = WMFW_ADSP2_PM, .base = 0x180000 }, + { .type = WMFW_ADSP2_ZM, .base = 0x1e0000 }, + { .type = WMFW_ADSP2_XM, .base = 0x1a0000 }, + { .type = WMFW_ADSP2_YM, .base = 0x1c0000 }, + }; + +-static const struct wm_adsp_region cs47l85_dsp4_regions[] = { ++static const struct cs_dsp_region cs47l85_dsp4_regions[] = { + { .type = WMFW_ADSP2_PM, .base = 0x200000 }, + { .type = WMFW_ADSP2_ZM, .base = 0x260000 }, + { .type = WMFW_ADSP2_XM, .base = 0x220000 }, + { .type = WMFW_ADSP2_YM, .base = 0x240000 }, + }; + +-static const struct wm_adsp_region cs47l85_dsp5_regions[] = { ++static const struct cs_dsp_region cs47l85_dsp5_regions[] = { + { .type = WMFW_ADSP2_PM, .base = 0x280000 }, + { .type = WMFW_ADSP2_ZM, .base = 0x2e0000 }, + { .type = WMFW_ADSP2_XM, .base = 0x2a0000 }, + { .type = WMFW_ADSP2_YM, .base = 0x2c0000 }, + }; + +-static const struct wm_adsp_region cs47l85_dsp6_regions[] = { ++static const struct cs_dsp_region cs47l85_dsp6_regions[] = { + { .type = WMFW_ADSP2_PM, .base = 0x300000 }, + { .type = WMFW_ADSP2_ZM, .base = 0x360000 }, + { .type = WMFW_ADSP2_XM, .base = 0x320000 }, + { .type = WMFW_ADSP2_YM, .base = 0x340000 }, + }; + +-static const struct wm_adsp_region cs47l85_dsp7_regions[] = { ++static const struct cs_dsp_region cs47l85_dsp7_regions[] = { + { .type = WMFW_ADSP2_PM, .base = 0x380000 }, + { .type = WMFW_ADSP2_ZM, .base = 0x3e0000 }, + { .type = WMFW_ADSP2_XM, .base = 0x3a0000 }, + { .type = WMFW_ADSP2_YM, .base = 0x3c0000 }, + }; + +-static const struct wm_adsp_region *cs47l85_dsp_regions[] = { ++static const struct cs_dsp_region *cs47l85_dsp_regions[] = { + cs47l85_dsp1_regions, + cs47l85_dsp2_regions, + cs47l85_dsp3_regions, +diff --git a/sound/soc/codecs/cs47l90.c b/sound/soc/codecs/cs47l90.c +index d2911c014b86..01d75c32d81e 100644 +--- a/sound/soc/codecs/cs47l90.c ++++ b/sound/soc/codecs/cs47l90.c +@@ -37,56 +37,56 @@ struct cs47l90 { + struct madera_fll fll[3]; + }; + +-static const struct wm_adsp_region cs47l90_dsp1_regions[] = { ++static const struct cs_dsp_region cs47l90_dsp1_regions[] = { + { .type = WMFW_ADSP2_PM, .base = 0x080000 }, + { .type = WMFW_ADSP2_ZM, .base = 0x0e0000 }, + { .type = WMFW_ADSP2_XM, .base = 0x0a0000 }, + { .type = WMFW_ADSP2_YM, .base = 0x0c0000 }, + }; + +-static const struct wm_adsp_region cs47l90_dsp2_regions[] = { ++static const struct cs_dsp_region cs47l90_dsp2_regions[] = { + { .type = WMFW_ADSP2_PM, .base = 0x100000 }, + { .type = WMFW_ADSP2_ZM, .base = 0x160000 }, + { .type = WMFW_ADSP2_XM, .base = 0x120000 }, + { .type = WMFW_ADSP2_YM, .base = 0x140000 }, + }; + +-static const struct wm_adsp_region cs47l90_dsp3_regions[] = { ++static const struct cs_dsp_region cs47l90_dsp3_regions[] = { + { .type = WMFW_ADSP2_PM, .base = 0x180000 }, + { .type = WMFW_ADSP2_ZM, .base = 0x1e0000 }, + { .type = WMFW_ADSP2_XM, .base = 0x1a0000 }, + { .type = WMFW_ADSP2_YM, .base = 0x1c0000 }, + }; + +-static const struct wm_adsp_region cs47l90_dsp4_regions[] = { ++static const struct cs_dsp_region cs47l90_dsp4_regions[] = { + { .type = WMFW_ADSP2_PM, .base = 0x200000 }, + { .type = WMFW_ADSP2_ZM, .base = 0x260000 }, + { .type = WMFW_ADSP2_XM, .base = 0x220000 }, + { .type = WMFW_ADSP2_YM, .base = 0x240000 }, + }; + +-static const struct wm_adsp_region cs47l90_dsp5_regions[] = { ++static const struct cs_dsp_region cs47l90_dsp5_regions[] = { + { .type = WMFW_ADSP2_PM, .base = 0x280000 }, + { .type = WMFW_ADSP2_ZM, .base = 0x2e0000 }, + { .type = WMFW_ADSP2_XM, .base = 0x2a0000 }, + { .type = WMFW_ADSP2_YM, .base = 0x2c0000 }, + }; + +-static const struct wm_adsp_region cs47l90_dsp6_regions[] = { ++static const struct cs_dsp_region cs47l90_dsp6_regions[] = { + { .type = WMFW_ADSP2_PM, .base = 0x300000 }, + { .type = WMFW_ADSP2_ZM, .base = 0x360000 }, + { .type = WMFW_ADSP2_XM, .base = 0x320000 }, + { .type = WMFW_ADSP2_YM, .base = 0x340000 }, + }; + +-static const struct wm_adsp_region cs47l90_dsp7_regions[] = { ++static const struct cs_dsp_region cs47l90_dsp7_regions[] = { + { .type = WMFW_ADSP2_PM, .base = 0x380000 }, + { .type = WMFW_ADSP2_ZM, .base = 0x3e0000 }, + { .type = WMFW_ADSP2_XM, .base = 0x3a0000 }, + { .type = WMFW_ADSP2_YM, .base = 0x3c0000 }, + }; + +-static const struct wm_adsp_region *cs47l90_dsp_regions[] = { ++static const struct cs_dsp_region *cs47l90_dsp_regions[] = { + cs47l90_dsp1_regions, + cs47l90_dsp2_regions, + cs47l90_dsp3_regions, +@@ -2554,7 +2554,7 @@ static int cs47l90_probe(struct platform_device *pdev) + cs47l90->core.adsp[i].num_mems = + ARRAY_SIZE(cs47l90_dsp1_regions); + +- cs47l90->core.adsp[i].lock_regions = WM_ADSP2_REGION_1_9; ++ cs47l90->core.adsp[i].lock_regions = CS_ADSP2_REGION_1_9; + + ret = wm_adsp2_init(&cs47l90->core.adsp[i]); + +diff --git a/sound/soc/codecs/cs47l92.c b/sound/soc/codecs/cs47l92.c +index 1a0280416d92..05087cc9c44b 100644 +--- a/sound/soc/codecs/cs47l92.c ++++ b/sound/soc/codecs/cs47l92.c +@@ -37,7 +37,7 @@ struct cs47l92 { + struct madera_fll fll[2]; + }; + +-static const struct wm_adsp_region cs47l92_dsp1_regions[] = { ++static const struct cs_dsp_region cs47l92_dsp1_regions[] = { + { .type = WMFW_ADSP2_PM, .base = 0x080000 }, + { .type = WMFW_ADSP2_ZM, .base = 0x0e0000 }, + { .type = WMFW_ADSP2_XM, .base = 0x0a0000 }, +@@ -2012,7 +2012,7 @@ static int cs47l92_probe(struct platform_device *pdev) + cs47l92->core.adsp[0].mem = cs47l92_dsp1_regions; + cs47l92->core.adsp[0].num_mems = ARRAY_SIZE(cs47l92_dsp1_regions); + +- cs47l92->core.adsp[0].lock_regions = WM_ADSP2_REGION_1_9; ++ cs47l92->core.adsp[0].lock_regions = CS_ADSP2_REGION_1_9; + + ret = wm_adsp2_init(&cs47l92->core.adsp[0]); + if (ret != 0) +diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c +index c35673e7f420..68355188eb55 100644 +--- a/sound/soc/codecs/wm2200.c ++++ b/sound/soc/codecs/wm2200.c +@@ -145,13 +145,13 @@ static const struct regmap_range_cfg wm2200_ranges[] = { + .window_start = WM2200_DSP2_ZM_0, .window_len = 1024, }, + }; + +-static const struct wm_adsp_region wm2200_dsp1_regions[] = { ++static const struct cs_dsp_region wm2200_dsp1_regions[] = { + { .type = WMFW_ADSP1_PM, .base = WM2200_DSP1_PM_BASE }, + { .type = WMFW_ADSP1_DM, .base = WM2200_DSP1_DM_BASE }, + { .type = WMFW_ADSP1_ZM, .base = WM2200_DSP1_ZM_BASE }, + }; + +-static const struct wm_adsp_region wm2200_dsp2_regions[] = { ++static const struct cs_dsp_region wm2200_dsp2_regions[] = { + { .type = WMFW_ADSP1_PM, .base = WM2200_DSP2_PM_BASE }, + { .type = WMFW_ADSP1_DM, .base = WM2200_DSP2_DM_BASE }, + { .type = WMFW_ADSP1_ZM, .base = WM2200_DSP2_ZM_BASE }, +diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c +index 621598608bf0..26e87c6be35b 100644 +--- a/sound/soc/codecs/wm5102.c ++++ b/sound/soc/codecs/wm5102.c +@@ -44,7 +44,7 @@ static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0); + static DECLARE_TLV_DB_SCALE(noise_tlv, -13200, 600, 0); + static DECLARE_TLV_DB_SCALE(ng_tlv, -10200, 600, 0); + +-static const struct wm_adsp_region wm5102_dsp1_regions[] = { ++static const struct cs_dsp_region wm5102_dsp1_regions[] = { + { .type = WMFW_ADSP2_PM, .base = 0x100000 }, + { .type = WMFW_ADSP2_ZM, .base = 0x180000 }, + { .type = WMFW_ADSP2_XM, .base = 0x190000 }, +diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c +index 5c2d45d05c97..e13e66b0ee52 100644 +--- a/sound/soc/codecs/wm5110.c ++++ b/sound/soc/codecs/wm5110.c +@@ -45,35 +45,35 @@ struct wm5110_priv { + unsigned int in_pga_cache[6]; + }; + +-static const struct wm_adsp_region wm5110_dsp1_regions[] = { ++static const struct cs_dsp_region wm5110_dsp1_regions[] = { + { .type = WMFW_ADSP2_PM, .base = 0x100000 }, + { .type = WMFW_ADSP2_ZM, .base = 0x180000 }, + { .type = WMFW_ADSP2_XM, .base = 0x190000 }, + { .type = WMFW_ADSP2_YM, .base = 0x1a8000 }, + }; + +-static const struct wm_adsp_region wm5110_dsp2_regions[] = { ++static const struct cs_dsp_region wm5110_dsp2_regions[] = { + { .type = WMFW_ADSP2_PM, .base = 0x200000 }, + { .type = WMFW_ADSP2_ZM, .base = 0x280000 }, + { .type = WMFW_ADSP2_XM, .base = 0x290000 }, + { .type = WMFW_ADSP2_YM, .base = 0x2a8000 }, + }; + +-static const struct wm_adsp_region wm5110_dsp3_regions[] = { ++static const struct cs_dsp_region wm5110_dsp3_regions[] = { + { .type = WMFW_ADSP2_PM, .base = 0x300000 }, + { .type = WMFW_ADSP2_ZM, .base = 0x380000 }, + { .type = WMFW_ADSP2_XM, .base = 0x390000 }, + { .type = WMFW_ADSP2_YM, .base = 0x3a8000 }, + }; + +-static const struct wm_adsp_region wm5110_dsp4_regions[] = { ++static const struct cs_dsp_region wm5110_dsp4_regions[] = { + { .type = WMFW_ADSP2_PM, .base = 0x400000 }, + { .type = WMFW_ADSP2_ZM, .base = 0x480000 }, + { .type = WMFW_ADSP2_XM, .base = 0x490000 }, + { .type = WMFW_ADSP2_YM, .base = 0x4a8000 }, + }; + +-static const struct wm_adsp_region *wm5110_dsp_regions[] = { ++static const struct cs_dsp_region *wm5110_dsp_regions[] = { + wm5110_dsp1_regions, + wm5110_dsp2_regions, + wm5110_dsp3_regions, +diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c +index c1b5ea3b5718..a039c137a3cb 100644 +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -214,15 +214,15 @@ + + #define ADSP_MAX_STD_CTRL_SIZE 512 + +-#define WM_ADSP_ACKED_CTL_TIMEOUT_MS 100 +-#define WM_ADSP_ACKED_CTL_N_QUICKPOLLS 10 +-#define WM_ADSP_ACKED_CTL_MIN_VALUE 0 +-#define WM_ADSP_ACKED_CTL_MAX_VALUE 0xFFFFFF ++#define CS_DSP_ACKED_CTL_TIMEOUT_MS 100 ++#define CS_DSP_ACKED_CTL_N_QUICKPOLLS 10 ++#define CS_DSP_ACKED_CTL_MIN_VALUE 0 ++#define CS_DSP_ACKED_CTL_MAX_VALUE 0xFFFFFF + + /* + * Event control messages + */ +-#define WM_ADSP_FW_EVENT_SHUTDOWN 0x000001 ++#define CS_DSP_FW_EVENT_SHUTDOWN 0x000001 + + /* + * HALO system info +@@ -304,19 +304,19 @@ + #define HALO_MPU_VIO_ERR_SRC_MASK 0x00007fff + #define HALO_MPU_VIO_ERR_SRC_SHIFT 0 + +-static const struct wm_adsp_ops wm_adsp1_ops; +-static const struct wm_adsp_ops wm_adsp2_ops[]; +-static const struct wm_adsp_ops wm_halo_ops; ++static const struct cs_dsp_ops cs_dsp_adsp1_ops; ++static const struct cs_dsp_ops cs_dsp_adsp2_ops[]; ++static const struct cs_dsp_ops cs_dsp_halo_ops; + +-struct wm_adsp_buf { ++struct cs_dsp_buf { + struct list_head list; + void *buf; + }; + +-static struct wm_adsp_buf *wm_adsp_buf_alloc(const void *src, size_t len, +- struct list_head *list) ++static struct cs_dsp_buf *cs_dsp_buf_alloc(const void *src, size_t len, ++ struct list_head *list) + { +- struct wm_adsp_buf *buf = kzalloc(sizeof(*buf), GFP_KERNEL); ++ struct cs_dsp_buf *buf = kzalloc(sizeof(*buf), GFP_KERNEL); + + if (buf == NULL) + return NULL; +@@ -334,12 +334,12 @@ static struct wm_adsp_buf *wm_adsp_buf_alloc(const void *src, size_t len, + return buf; + } + +-static void wm_adsp_buf_free(struct list_head *list) ++static void cs_dsp_buf_free(struct list_head *list) + { + while (!list_empty(list)) { +- struct wm_adsp_buf *buf = list_first_entry(list, +- struct wm_adsp_buf, +- list); ++ struct cs_dsp_buf *buf = list_first_entry(list, ++ struct cs_dsp_buf, ++ list); + list_del(&buf->list); + vfree(buf->buf); + kfree(buf); +@@ -470,12 +470,12 @@ struct wm_adsp_compr { + const char *name; + }; + +-#define WM_ADSP_DATA_WORD_SIZE 3 ++#define CS_DSP_DATA_WORD_SIZE 3 + + #define WM_ADSP_MIN_FRAGMENTS 1 + #define WM_ADSP_MAX_FRAGMENTS 256 +-#define WM_ADSP_MIN_FRAGMENT_SIZE (64 * WM_ADSP_DATA_WORD_SIZE) +-#define WM_ADSP_MAX_FRAGMENT_SIZE (4096 * WM_ADSP_DATA_WORD_SIZE) ++#define WM_ADSP_MIN_FRAGMENT_SIZE (64 * CS_DSP_DATA_WORD_SIZE) ++#define WM_ADSP_MAX_FRAGMENT_SIZE (4096 * CS_DSP_DATA_WORD_SIZE) + + #define WM_ADSP_ALG_XM_STRUCT_MAGIC 0x49aec7 + +@@ -602,7 +602,7 @@ struct wm_coeff_ctl { + /* Subname is needed to match with firmware */ + const char *subname; + unsigned int subname_len; +- struct wm_adsp_alg_region alg_region; ++ struct cs_dsp_alg_region alg_region; + struct wm_adsp *dsp; + unsigned int enabled:1; + struct list_head list; +@@ -616,7 +616,7 @@ struct wm_coeff_ctl { + struct work_struct work; + }; + +-static const char *wm_adsp_mem_region_name(unsigned int type) ++static const char *cs_dsp_mem_region_name(unsigned int type) + { + switch (type) { + case WMFW_ADSP1_PM: +@@ -641,7 +641,7 @@ static const char *wm_adsp_mem_region_name(unsigned int type) + } + + #ifdef CONFIG_DEBUG_FS +-static void wm_adsp_debugfs_save_wmfwname(struct wm_adsp *dsp, const char *s) ++static void cs_dsp_debugfs_save_wmfwname(struct wm_adsp *dsp, const char *s) + { + char *tmp = kasprintf(GFP_KERNEL, "%s\n", s); + +@@ -649,7 +649,7 @@ static void wm_adsp_debugfs_save_wmfwname(struct wm_adsp *dsp, const char *s) + dsp->wmfw_file_name = tmp; + } + +-static void wm_adsp_debugfs_save_binname(struct wm_adsp *dsp, const char *s) ++static void cs_dsp_debugfs_save_binname(struct wm_adsp *dsp, const char *s) + { + char *tmp = kasprintf(GFP_KERNEL, "%s\n", s); + +@@ -657,7 +657,7 @@ static void wm_adsp_debugfs_save_binname(struct wm_adsp *dsp, const char *s) + dsp->bin_file_name = tmp; + } + +-static void wm_adsp_debugfs_clear(struct wm_adsp *dsp) ++static void cs_dsp_debugfs_clear(struct wm_adsp *dsp) + { + kfree(dsp->wmfw_file_name); + kfree(dsp->bin_file_name); +@@ -665,9 +665,9 @@ static void wm_adsp_debugfs_clear(struct wm_adsp *dsp) + dsp->bin_file_name = NULL; + } + +-static ssize_t wm_adsp_debugfs_wmfw_read(struct file *file, +- char __user *user_buf, +- size_t count, loff_t *ppos) ++static ssize_t cs_dsp_debugfs_wmfw_read(struct file *file, ++ char __user *user_buf, ++ size_t count, loff_t *ppos) + { + struct wm_adsp *dsp = file->private_data; + ssize_t ret; +@@ -685,9 +685,9 @@ static ssize_t wm_adsp_debugfs_wmfw_read(struct file *file, + return ret; + } + +-static ssize_t wm_adsp_debugfs_bin_read(struct file *file, +- char __user *user_buf, +- size_t count, loff_t *ppos) ++static ssize_t cs_dsp_debugfs_bin_read(struct file *file, ++ char __user *user_buf, ++ size_t count, loff_t *ppos) + { + struct wm_adsp *dsp = file->private_data; + ssize_t ret; +@@ -708,25 +708,25 @@ static ssize_t wm_adsp_debugfs_bin_read(struct file *file, + static const struct { + const char *name; + const struct file_operations fops; +-} wm_adsp_debugfs_fops[] = { ++} cs_dsp_debugfs_fops[] = { + { + .name = "wmfw_file_name", + .fops = { + .open = simple_open, +- .read = wm_adsp_debugfs_wmfw_read, ++ .read = cs_dsp_debugfs_wmfw_read, + }, + }, + { + .name = "bin_file_name", + .fops = { + .open = simple_open, +- .read = wm_adsp_debugfs_bin_read, ++ .read = cs_dsp_debugfs_bin_read, + }, + }, + }; + +-static void wm_adsp2_init_debugfs(struct wm_adsp *dsp, +- struct snd_soc_component *component) ++static void cs_dsp_init_debugfs(struct wm_adsp *dsp, ++ struct snd_soc_component *component) + { + struct dentry *root = NULL; + int i; +@@ -738,40 +738,40 @@ static void wm_adsp2_init_debugfs(struct wm_adsp *dsp, + debugfs_create_x32("fw_id", 0444, root, &dsp->fw_id); + debugfs_create_x32("fw_version", 0444, root, &dsp->fw_id_version); + +- for (i = 0; i < ARRAY_SIZE(wm_adsp_debugfs_fops); ++i) +- debugfs_create_file(wm_adsp_debugfs_fops[i].name, 0444, root, +- dsp, &wm_adsp_debugfs_fops[i].fops); ++ for (i = 0; i < ARRAY_SIZE(cs_dsp_debugfs_fops); ++i) ++ debugfs_create_file(cs_dsp_debugfs_fops[i].name, 0444, root, ++ dsp, &cs_dsp_debugfs_fops[i].fops); + + dsp->debugfs_root = root; + } + +-static void wm_adsp2_cleanup_debugfs(struct wm_adsp *dsp) ++static void cs_dsp_cleanup_debugfs(struct wm_adsp *dsp) + { +- wm_adsp_debugfs_clear(dsp); ++ cs_dsp_debugfs_clear(dsp); + debugfs_remove_recursive(dsp->debugfs_root); + dsp->debugfs_root = NULL; + } + #else +-static inline void wm_adsp2_init_debugfs(struct wm_adsp *dsp, +- struct snd_soc_component *component) ++static inline void cs_dsp_init_debugfs(struct wm_adsp *dsp, ++ struct snd_soc_component *component) + { + } + +-static inline void wm_adsp2_cleanup_debugfs(struct wm_adsp *dsp) ++static inline void cs_dsp_cleanup_debugfs(struct wm_adsp *dsp) + { + } + +-static inline void wm_adsp_debugfs_save_wmfwname(struct wm_adsp *dsp, ++static inline void cs_dsp_debugfs_save_wmfwname(struct wm_adsp *dsp, + const char *s) + { + } + +-static inline void wm_adsp_debugfs_save_binname(struct wm_adsp *dsp, ++static inline void cs_dsp_debugfs_save_binname(struct wm_adsp *dsp, + const char *s) + { + } + +-static inline void wm_adsp_debugfs_clear(struct wm_adsp *dsp) ++static inline void cs_dsp_debugfs_clear(struct wm_adsp *dsp) + { + } + #endif +@@ -827,8 +827,8 @@ const struct soc_enum wm_adsp_fw_enum[] = { + }; + EXPORT_SYMBOL_GPL(wm_adsp_fw_enum); + +-static const struct wm_adsp_region *wm_adsp_find_region(struct wm_adsp *dsp, +- int type) ++static const struct cs_dsp_region *cs_dsp_find_region(struct wm_adsp *dsp, ++ int type) + { + int i; + +@@ -839,8 +839,8 @@ static const struct wm_adsp_region *wm_adsp_find_region(struct wm_adsp *dsp, + return NULL; + } + +-static unsigned int wm_adsp_region_to_reg(struct wm_adsp_region const *mem, +- unsigned int offset) ++static unsigned int cs_dsp_region_to_reg(struct cs_dsp_region const *mem, ++ unsigned int offset) + { + switch (mem->type) { + case WMFW_ADSP1_PM: +@@ -856,8 +856,8 @@ static unsigned int wm_adsp_region_to_reg(struct wm_adsp_region const *mem, + } + } + +-static unsigned int wm_halo_region_to_reg(struct wm_adsp_region const *mem, +- unsigned int offset) ++static unsigned int cs_dsp_halo_region_to_reg(struct cs_dsp_region const *mem, ++ unsigned int offset) + { + switch (mem->type) { + case WMFW_ADSP2_XM: +@@ -874,8 +874,8 @@ static unsigned int wm_halo_region_to_reg(struct wm_adsp_region const *mem, + } + } + +-static void wm_adsp_read_fw_status(struct wm_adsp *dsp, +- int noffs, unsigned int *offs) ++static void cs_dsp_read_fw_status(struct wm_adsp *dsp, ++ int noffs, unsigned int *offs) + { + unsigned int i; + int ret; +@@ -889,36 +889,36 @@ static void wm_adsp_read_fw_status(struct wm_adsp *dsp, + } + } + +-static void wm_adsp2_show_fw_status(struct wm_adsp *dsp) ++static void cs_dsp_adsp2_show_fw_status(struct wm_adsp *dsp) + { + unsigned int offs[] = { + ADSP2_SCRATCH0, ADSP2_SCRATCH1, ADSP2_SCRATCH2, ADSP2_SCRATCH3, + }; + +- wm_adsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs); ++ cs_dsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs); + + adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", + offs[0], offs[1], offs[2], offs[3]); + } + +-static void wm_adsp2v2_show_fw_status(struct wm_adsp *dsp) ++static void cs_dsp_adsp2v2_show_fw_status(struct wm_adsp *dsp) + { + unsigned int offs[] = { ADSP2V2_SCRATCH0_1, ADSP2V2_SCRATCH2_3 }; + +- wm_adsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs); ++ cs_dsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs); + + adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", + offs[0] & 0xFFFF, offs[0] >> 16, + offs[1] & 0xFFFF, offs[1] >> 16); + } + +-static void wm_halo_show_fw_status(struct wm_adsp *dsp) ++static void cs_dsp_halo_show_fw_status(struct wm_adsp *dsp) + { + unsigned int offs[] = { + HALO_SCRATCH1, HALO_SCRATCH2, HALO_SCRATCH3, HALO_SCRATCH4, + }; + +- wm_adsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs); ++ cs_dsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs); + + adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", + offs[0], offs[1], offs[2], offs[3]); +@@ -929,13 +929,13 @@ static inline struct wm_coeff_ctl *bytes_ext_to_ctl(struct soc_bytes_ext *ext) + return container_of(ext, struct wm_coeff_ctl, bytes_ext); + } + +-static int wm_coeff_base_reg(struct wm_coeff_ctl *ctl, unsigned int *reg) ++static int cs_dsp_coeff_base_reg(struct wm_coeff_ctl *ctl, unsigned int *reg) + { +- const struct wm_adsp_alg_region *alg_region = &ctl->alg_region; ++ const struct cs_dsp_alg_region *alg_region = &ctl->alg_region; + struct wm_adsp *dsp = ctl->dsp; +- const struct wm_adsp_region *mem; ++ const struct cs_dsp_region *mem; + +- mem = wm_adsp_find_region(dsp, alg_region->type); ++ mem = cs_dsp_find_region(dsp, alg_region->type); + if (!mem) { + adsp_err(dsp, "No base for region %x\n", + alg_region->type); +@@ -957,8 +957,8 @@ static int wm_coeff_info(struct snd_kcontrol *kctl, + switch (ctl->type) { + case WMFW_CTL_TYPE_ACKED: + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; +- uinfo->value.integer.min = WM_ADSP_ACKED_CTL_MIN_VALUE; +- uinfo->value.integer.max = WM_ADSP_ACKED_CTL_MAX_VALUE; ++ uinfo->value.integer.min = CS_DSP_ACKED_CTL_MIN_VALUE; ++ uinfo->value.integer.max = CS_DSP_ACKED_CTL_MAX_VALUE; + uinfo->value.integer.step = 1; + uinfo->count = 1; + break; +@@ -971,21 +971,21 @@ static int wm_coeff_info(struct snd_kcontrol *kctl, + return 0; + } + +-static int wm_coeff_write_acked_control(struct wm_coeff_ctl *ctl, +- unsigned int event_id) ++static int cs_dsp_coeff_write_acked_control(struct wm_coeff_ctl *ctl, ++ unsigned int event_id) + { + struct wm_adsp *dsp = ctl->dsp; + __be32 val = cpu_to_be32(event_id); + unsigned int reg; + int i, ret; + +- ret = wm_coeff_base_reg(ctl, ®); ++ ret = cs_dsp_coeff_base_reg(ctl, ®); + if (ret) + return ret; + + adsp_dbg(dsp, "Sending 0x%x to acked control alg 0x%x %s:0x%x\n", + event_id, ctl->alg_region.alg, +- wm_adsp_mem_region_name(ctl->alg_region.type), ctl->offset); ++ cs_dsp_mem_region_name(ctl->alg_region.type), ctl->offset); + + ret = regmap_raw_write(dsp->regmap, reg, &val, sizeof(val)); + if (ret) { +@@ -999,9 +999,9 @@ static int wm_coeff_write_acked_control(struct wm_coeff_ctl *ctl, + * to ack instantly so we do the first 1ms delay before reading the + * control to avoid a pointless bus transaction + */ +- for (i = 0; i < WM_ADSP_ACKED_CTL_TIMEOUT_MS;) { ++ for (i = 0; i < CS_DSP_ACKED_CTL_TIMEOUT_MS;) { + switch (i) { +- case 0 ... WM_ADSP_ACKED_CTL_N_QUICKPOLLS - 1: ++ case 0 ... CS_DSP_ACKED_CTL_N_QUICKPOLLS - 1: + usleep_range(1000, 2000); + i++; + break; +@@ -1025,21 +1025,21 @@ static int wm_coeff_write_acked_control(struct wm_coeff_ctl *ctl, + + adsp_warn(dsp, "Acked control @0x%x alg:0x%x %s:0x%x timed out\n", + reg, ctl->alg_region.alg, +- wm_adsp_mem_region_name(ctl->alg_region.type), ++ cs_dsp_mem_region_name(ctl->alg_region.type), + ctl->offset); + + return -ETIMEDOUT; + } + +-static int wm_coeff_write_ctrl_raw(struct wm_coeff_ctl *ctl, +- const void *buf, size_t len) ++static int cs_dsp_coeff_write_ctrl_raw(struct wm_coeff_ctl *ctl, ++ const void *buf, size_t len) + { + struct wm_adsp *dsp = ctl->dsp; + void *scratch; + int ret; + unsigned int reg; + +- ret = wm_coeff_base_reg(ctl, ®); ++ ret = cs_dsp_coeff_base_reg(ctl, ®); + if (ret) + return ret; + +@@ -1062,8 +1062,8 @@ static int wm_coeff_write_ctrl_raw(struct wm_coeff_ctl *ctl, + return 0; + } + +-static int wm_coeff_write_ctrl(struct wm_coeff_ctl *ctl, +- const void *buf, size_t len) ++static int cs_dsp_coeff_write_ctrl(struct wm_coeff_ctl *ctl, ++ const void *buf, size_t len) + { + int ret = 0; + +@@ -1074,7 +1074,7 @@ static int wm_coeff_write_ctrl(struct wm_coeff_ctl *ctl, + + ctl->set = 1; + if (ctl->enabled && ctl->dsp->running) +- ret = wm_coeff_write_ctrl_raw(ctl, buf, len); ++ ret = cs_dsp_coeff_write_ctrl_raw(ctl, buf, len); + + return ret; + } +@@ -1089,7 +1089,7 @@ static int wm_coeff_put(struct snd_kcontrol *kctl, + int ret = 0; + + mutex_lock(&ctl->dsp->pwr_lock); +- ret = wm_coeff_write_ctrl(ctl, p, ctl->len); ++ ret = cs_dsp_coeff_write_ctrl(ctl, p, ctl->len); + mutex_unlock(&ctl->dsp->pwr_lock); + + return ret; +@@ -1108,7 +1108,7 @@ static int wm_coeff_tlv_put(struct snd_kcontrol *kctl, + if (copy_from_user(ctl->cache, bytes, size)) + ret = -EFAULT; + else +- ret = wm_coeff_write_ctrl(ctl, ctl->cache, size); ++ ret = cs_dsp_coeff_write_ctrl(ctl, ctl->cache, size); + + mutex_unlock(&ctl->dsp->pwr_lock); + +@@ -1130,7 +1130,7 @@ static int wm_coeff_put_acked(struct snd_kcontrol *kctl, + mutex_lock(&ctl->dsp->pwr_lock); + + if (ctl->enabled && ctl->dsp->running) +- ret = wm_coeff_write_acked_control(ctl, val); ++ ret = cs_dsp_coeff_write_acked_control(ctl, val); + else + ret = -EPERM; + +@@ -1139,15 +1139,15 @@ static int wm_coeff_put_acked(struct snd_kcontrol *kctl, + return ret; + } + +-static int wm_coeff_read_ctrl_raw(struct wm_coeff_ctl *ctl, +- void *buf, size_t len) ++static int cs_dsp_coeff_read_ctrl_raw(struct wm_coeff_ctl *ctl, ++ void *buf, size_t len) + { + struct wm_adsp *dsp = ctl->dsp; + void *scratch; + int ret; + unsigned int reg; + +- ret = wm_coeff_base_reg(ctl, ®); ++ ret = cs_dsp_coeff_base_reg(ctl, ®); + if (ret) + return ret; + +@@ -1170,18 +1170,18 @@ static int wm_coeff_read_ctrl_raw(struct wm_coeff_ctl *ctl, + return 0; + } + +-static int wm_coeff_read_ctrl(struct wm_coeff_ctl *ctl, void *buf, size_t len) ++static int cs_dsp_coeff_read_ctrl(struct wm_coeff_ctl *ctl, void *buf, size_t len) + { + int ret = 0; + + if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) { + if (ctl->enabled && ctl->dsp->running) +- return wm_coeff_read_ctrl_raw(ctl, buf, len); ++ return cs_dsp_coeff_read_ctrl_raw(ctl, buf, len); + else + return -EPERM; + } else { + if (!ctl->flags && ctl->enabled && ctl->dsp->running) +- ret = wm_coeff_read_ctrl_raw(ctl, ctl->cache, ctl->len); ++ ret = cs_dsp_coeff_read_ctrl_raw(ctl, ctl->cache, ctl->len); + + if (buf != ctl->cache) + memcpy(buf, ctl->cache, len); +@@ -1200,7 +1200,7 @@ static int wm_coeff_get(struct snd_kcontrol *kctl, + int ret; + + mutex_lock(&ctl->dsp->pwr_lock); +- ret = wm_coeff_read_ctrl(ctl, p, ctl->len); ++ ret = cs_dsp_coeff_read_ctrl(ctl, p, ctl->len); + mutex_unlock(&ctl->dsp->pwr_lock); + + return ret; +@@ -1216,7 +1216,7 @@ static int wm_coeff_tlv_get(struct snd_kcontrol *kctl, + + mutex_lock(&ctl->dsp->pwr_lock); + +- ret = wm_coeff_read_ctrl(ctl, ctl->cache, size); ++ ret = cs_dsp_coeff_read_ctrl(ctl, ctl->cache, size); + + if (!ret && copy_to_user(bytes, ctl->cache, size)) + ret = -EFAULT; +@@ -1321,7 +1321,7 @@ static int wmfw_add_ctl(struct wm_adsp *dsp, struct wm_coeff_ctl *ctl) + return ret; + } + +-static int wm_coeff_init_control_caches(struct wm_adsp *dsp) ++static int cs_dsp_coeff_init_control_caches(struct wm_adsp *dsp) + { + struct wm_coeff_ctl *ctl; + int ret; +@@ -1338,7 +1338,7 @@ static int wm_coeff_init_control_caches(struct wm_adsp *dsp) + * created so we don't need to do anything. + */ + if (!ctl->flags || (ctl->flags & WMFW_CTL_FLAG_READABLE)) { +- ret = wm_coeff_read_ctrl_raw(ctl, ctl->cache, ctl->len); ++ ret = cs_dsp_coeff_read_ctrl_raw(ctl, ctl->cache, ctl->len); + if (ret < 0) + return ret; + } +@@ -1347,7 +1347,7 @@ static int wm_coeff_init_control_caches(struct wm_adsp *dsp) + return 0; + } + +-static int wm_coeff_sync_controls(struct wm_adsp *dsp) ++static int cs_dsp_coeff_sync_controls(struct wm_adsp *dsp) + { + struct wm_coeff_ctl *ctl; + int ret; +@@ -1356,8 +1356,8 @@ static int wm_coeff_sync_controls(struct wm_adsp *dsp) + if (!ctl->enabled) + continue; + if (ctl->set && !(ctl->flags & WMFW_CTL_FLAG_VOLATILE)) { +- ret = wm_coeff_write_ctrl_raw(ctl, ctl->cache, +- ctl->len); ++ ret = cs_dsp_coeff_write_ctrl_raw(ctl, ctl->cache, ++ ctl->len); + if (ret < 0) + return ret; + } +@@ -1366,7 +1366,7 @@ static int wm_coeff_sync_controls(struct wm_adsp *dsp) + return 0; + } + +-static void wm_adsp_signal_event_controls(struct wm_adsp *dsp, ++static void cs_dsp_signal_event_controls(struct wm_adsp *dsp, + unsigned int event) + { + struct wm_coeff_ctl *ctl; +@@ -1379,7 +1379,7 @@ static void wm_adsp_signal_event_controls(struct wm_adsp *dsp, + if (!ctl->enabled) + continue; + +- ret = wm_coeff_write_acked_control(ctl, event); ++ ret = cs_dsp_coeff_write_acked_control(ctl, event); + if (ret) + adsp_warn(dsp, + "Failed to send 0x%x event to alg 0x%x (%d)\n", +@@ -1396,7 +1396,7 @@ static void wm_adsp_ctl_work(struct work_struct *work) + wmfw_add_ctl(ctl->dsp, ctl); + } + +-static void wm_adsp_free_ctl_blk(struct wm_coeff_ctl *ctl) ++static void cs_dsp_free_ctl_blk(struct wm_coeff_ctl *ctl) + { + cancel_work_sync(&ctl->work); + +@@ -1406,11 +1406,11 @@ static void wm_adsp_free_ctl_blk(struct wm_coeff_ctl *ctl) + kfree(ctl); + } + +-static int wm_adsp_create_control(struct wm_adsp *dsp, +- const struct wm_adsp_alg_region *alg_region, +- unsigned int offset, unsigned int len, +- const char *subname, unsigned int subname_len, +- unsigned int flags, unsigned int type) ++static int cs_dsp_create_control(struct wm_adsp *dsp, ++ const struct cs_dsp_alg_region *alg_region, ++ unsigned int offset, unsigned int len, ++ const char *subname, unsigned int subname_len, ++ unsigned int flags, unsigned int type) + { + struct wm_coeff_ctl *ctl; + char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; +@@ -1430,7 +1430,7 @@ static int wm_adsp_create_control(struct wm_adsp *dsp, + } + } + +- region_name = wm_adsp_mem_region_name(alg_region->type); ++ region_name = cs_dsp_mem_region_name(alg_region->type); + if (!region_name) { + adsp_err(dsp, "Unknown region type: %d\n", alg_region->type); + return -EINVAL; +@@ -1523,14 +1523,14 @@ static int wm_adsp_create_control(struct wm_adsp *dsp, + return ret; + } + +-struct wm_coeff_parsed_alg { ++struct cs_dsp_coeff_parsed_alg { + int id; + const u8 *name; + int name_len; + int ncoeff; + }; + +-struct wm_coeff_parsed_coeff { ++struct cs_dsp_coeff_parsed_coeff { + int offset; + int mem_type; + const u8 *name; +@@ -1540,7 +1540,7 @@ struct wm_coeff_parsed_coeff { + int len; + }; + +-static int wm_coeff_parse_string(int bytes, const u8 **pos, const u8 **str) ++static int cs_dsp_coeff_parse_string(int bytes, const u8 **pos, const u8 **str) + { + int length; + +@@ -1563,7 +1563,7 @@ static int wm_coeff_parse_string(int bytes, const u8 **pos, const u8 **str) + return length; + } + +-static int wm_coeff_parse_int(int bytes, const u8 **pos) ++static int cs_dsp_coeff_parse_int(int bytes, const u8 **pos) + { + int val = 0; + +@@ -1583,8 +1583,8 @@ static int wm_coeff_parse_int(int bytes, const u8 **pos) + return val; + } + +-static inline void wm_coeff_parse_alg(struct wm_adsp *dsp, const u8 **data, +- struct wm_coeff_parsed_alg *blk) ++static inline void cs_dsp_coeff_parse_alg(struct wm_adsp *dsp, const u8 **data, ++ struct cs_dsp_coeff_parsed_alg *blk) + { + const struct wmfw_adsp_alg_data *raw; + +@@ -1600,11 +1600,11 @@ static inline void wm_coeff_parse_alg(struct wm_adsp *dsp, const u8 **data, + blk->ncoeff = le32_to_cpu(raw->ncoeff); + break; + default: +- blk->id = wm_coeff_parse_int(sizeof(raw->id), data); +- blk->name_len = wm_coeff_parse_string(sizeof(u8), data, +- &blk->name); +- wm_coeff_parse_string(sizeof(u16), data, NULL); +- blk->ncoeff = wm_coeff_parse_int(sizeof(raw->ncoeff), data); ++ blk->id = cs_dsp_coeff_parse_int(sizeof(raw->id), data); ++ blk->name_len = cs_dsp_coeff_parse_string(sizeof(u8), data, ++ &blk->name); ++ cs_dsp_coeff_parse_string(sizeof(u16), data, NULL); ++ blk->ncoeff = cs_dsp_coeff_parse_int(sizeof(raw->ncoeff), data); + break; + } + +@@ -1613,8 +1613,8 @@ static inline void wm_coeff_parse_alg(struct wm_adsp *dsp, const u8 **data, + adsp_dbg(dsp, "# of coefficient descriptors: %#x\n", blk->ncoeff); + } + +-static inline void wm_coeff_parse_coeff(struct wm_adsp *dsp, const u8 **data, +- struct wm_coeff_parsed_coeff *blk) ++static inline void cs_dsp_coeff_parse_coeff(struct wm_adsp *dsp, const u8 **data, ++ struct cs_dsp_coeff_parsed_coeff *blk) + { + const struct wmfw_adsp_coeff_data *raw; + const u8 *tmp; +@@ -1636,16 +1636,16 @@ static inline void wm_coeff_parse_coeff(struct wm_adsp *dsp, const u8 **data, + break; + default: + tmp = *data; +- blk->offset = wm_coeff_parse_int(sizeof(raw->hdr.offset), &tmp); +- blk->mem_type = wm_coeff_parse_int(sizeof(raw->hdr.type), &tmp); +- length = wm_coeff_parse_int(sizeof(raw->hdr.size), &tmp); +- blk->name_len = wm_coeff_parse_string(sizeof(u8), &tmp, +- &blk->name); +- wm_coeff_parse_string(sizeof(u8), &tmp, NULL); +- wm_coeff_parse_string(sizeof(u16), &tmp, NULL); +- blk->ctl_type = wm_coeff_parse_int(sizeof(raw->ctl_type), &tmp); +- blk->flags = wm_coeff_parse_int(sizeof(raw->flags), &tmp); +- blk->len = wm_coeff_parse_int(sizeof(raw->len), &tmp); ++ blk->offset = cs_dsp_coeff_parse_int(sizeof(raw->hdr.offset), &tmp); ++ blk->mem_type = cs_dsp_coeff_parse_int(sizeof(raw->hdr.type), &tmp); ++ length = cs_dsp_coeff_parse_int(sizeof(raw->hdr.size), &tmp); ++ blk->name_len = cs_dsp_coeff_parse_string(sizeof(u8), &tmp, ++ &blk->name); ++ cs_dsp_coeff_parse_string(sizeof(u8), &tmp, NULL); ++ cs_dsp_coeff_parse_string(sizeof(u16), &tmp, NULL); ++ blk->ctl_type = cs_dsp_coeff_parse_int(sizeof(raw->ctl_type), &tmp); ++ blk->flags = cs_dsp_coeff_parse_int(sizeof(raw->flags), &tmp); ++ blk->len = cs_dsp_coeff_parse_int(sizeof(raw->len), &tmp); + + *data = *data + sizeof(raw->hdr) + length; + break; +@@ -1659,10 +1659,10 @@ static inline void wm_coeff_parse_coeff(struct wm_adsp *dsp, const u8 **data, + adsp_dbg(dsp, "\tALSA control len: %#x\n", blk->len); + } + +-static int wm_adsp_check_coeff_flags(struct wm_adsp *dsp, +- const struct wm_coeff_parsed_coeff *coeff_blk, +- unsigned int f_required, +- unsigned int f_illegal) ++static int cs_dsp_check_coeff_flags(struct wm_adsp *dsp, ++ const struct cs_dsp_coeff_parsed_coeff *coeff_blk, ++ unsigned int f_required, ++ unsigned int f_illegal) + { + if ((coeff_blk->flags & f_illegal) || + ((coeff_blk->flags & f_required) != f_required)) { +@@ -1674,18 +1674,18 @@ static int wm_adsp_check_coeff_flags(struct wm_adsp *dsp, + return 0; + } + +-static int wm_adsp_parse_coeff(struct wm_adsp *dsp, +- const struct wmfw_region *region) ++static int cs_dsp_parse_coeff(struct wm_adsp *dsp, ++ const struct wmfw_region *region) + { +- struct wm_adsp_alg_region alg_region = {}; +- struct wm_coeff_parsed_alg alg_blk; +- struct wm_coeff_parsed_coeff coeff_blk; ++ struct cs_dsp_alg_region alg_region = {}; ++ struct cs_dsp_coeff_parsed_alg alg_blk; ++ struct cs_dsp_coeff_parsed_coeff coeff_blk; + const u8 *data = region->data; + int i, ret; + +- wm_coeff_parse_alg(dsp, &data, &alg_blk); ++ cs_dsp_coeff_parse_alg(dsp, &data, &alg_blk); + for (i = 0; i < alg_blk.ncoeff; i++) { +- wm_coeff_parse_coeff(dsp, &data, &coeff_blk); ++ cs_dsp_coeff_parse_coeff(dsp, &data, &coeff_blk); + + switch (coeff_blk.ctl_type) { + case WMFW_CTL_TYPE_BYTES: +@@ -1694,30 +1694,30 @@ static int wm_adsp_parse_coeff(struct wm_adsp *dsp, + if (coeff_blk.flags & WMFW_CTL_FLAG_SYS) + continue; /* ignore */ + +- ret = wm_adsp_check_coeff_flags(dsp, &coeff_blk, +- WMFW_CTL_FLAG_VOLATILE | +- WMFW_CTL_FLAG_WRITEABLE | +- WMFW_CTL_FLAG_READABLE, +- 0); ++ ret = cs_dsp_check_coeff_flags(dsp, &coeff_blk, ++ WMFW_CTL_FLAG_VOLATILE | ++ WMFW_CTL_FLAG_WRITEABLE | ++ WMFW_CTL_FLAG_READABLE, ++ 0); + if (ret) + return -EINVAL; + break; + case WMFW_CTL_TYPE_HOSTEVENT: +- ret = wm_adsp_check_coeff_flags(dsp, &coeff_blk, +- WMFW_CTL_FLAG_SYS | +- WMFW_CTL_FLAG_VOLATILE | +- WMFW_CTL_FLAG_WRITEABLE | +- WMFW_CTL_FLAG_READABLE, +- 0); ++ ret = cs_dsp_check_coeff_flags(dsp, &coeff_blk, ++ WMFW_CTL_FLAG_SYS | ++ WMFW_CTL_FLAG_VOLATILE | ++ WMFW_CTL_FLAG_WRITEABLE | ++ WMFW_CTL_FLAG_READABLE, ++ 0); + if (ret) + return -EINVAL; + break; + case WMFW_CTL_TYPE_HOST_BUFFER: +- ret = wm_adsp_check_coeff_flags(dsp, &coeff_blk, +- WMFW_CTL_FLAG_SYS | +- WMFW_CTL_FLAG_VOLATILE | +- WMFW_CTL_FLAG_READABLE, +- 0); ++ ret = cs_dsp_check_coeff_flags(dsp, &coeff_blk, ++ WMFW_CTL_FLAG_SYS | ++ WMFW_CTL_FLAG_VOLATILE | ++ WMFW_CTL_FLAG_READABLE, ++ 0); + if (ret) + return -EINVAL; + break; +@@ -1730,13 +1730,13 @@ static int wm_adsp_parse_coeff(struct wm_adsp *dsp, + alg_region.type = coeff_blk.mem_type; + alg_region.alg = alg_blk.id; + +- ret = wm_adsp_create_control(dsp, &alg_region, +- coeff_blk.offset, +- coeff_blk.len, +- coeff_blk.name, +- coeff_blk.name_len, +- coeff_blk.flags, +- coeff_blk.ctl_type); ++ ret = cs_dsp_create_control(dsp, &alg_region, ++ coeff_blk.offset, ++ coeff_blk.len, ++ coeff_blk.name, ++ coeff_blk.name_len, ++ coeff_blk.flags, ++ coeff_blk.ctl_type); + if (ret < 0) + adsp_err(dsp, "Failed to create control: %.*s, %d\n", + coeff_blk.name_len, coeff_blk.name, ret); +@@ -1745,10 +1745,10 @@ static int wm_adsp_parse_coeff(struct wm_adsp *dsp, + return 0; + } + +-static unsigned int wm_adsp1_parse_sizes(struct wm_adsp *dsp, +- const char * const file, +- unsigned int pos, +- const struct firmware *firmware) ++static unsigned int cs_dsp_adsp1_parse_sizes(struct wm_adsp *dsp, ++ const char * const file, ++ unsigned int pos, ++ const struct firmware *firmware) + { + const struct wmfw_adsp1_sizes *adsp1_sizes; + +@@ -1761,10 +1761,10 @@ static unsigned int wm_adsp1_parse_sizes(struct wm_adsp *dsp, + return pos + sizeof(*adsp1_sizes); + } + +-static unsigned int wm_adsp2_parse_sizes(struct wm_adsp *dsp, +- const char * const file, +- unsigned int pos, +- const struct firmware *firmware) ++static unsigned int cs_dsp_adsp2_parse_sizes(struct wm_adsp *dsp, ++ const char * const file, ++ unsigned int pos, ++ const struct firmware *firmware) + { + const struct wmfw_adsp2_sizes *adsp2_sizes; + +@@ -1777,7 +1777,7 @@ static unsigned int wm_adsp2_parse_sizes(struct wm_adsp *dsp, + return pos + sizeof(*adsp2_sizes); + } + +-static bool wm_adsp_validate_version(struct wm_adsp *dsp, unsigned int version) ++static bool cs_dsp_validate_version(struct wm_adsp *dsp, unsigned int version) + { + switch (version) { + case 0: +@@ -1791,7 +1791,7 @@ static bool wm_adsp_validate_version(struct wm_adsp *dsp, unsigned int version) + } + } + +-static bool wm_halo_validate_version(struct wm_adsp *dsp, unsigned int version) ++static bool cs_dsp_halo_validate_version(struct wm_adsp *dsp, unsigned int version) + { + switch (version) { + case 3: +@@ -1801,7 +1801,7 @@ static bool wm_halo_validate_version(struct wm_adsp *dsp, unsigned int version) + } + } + +-static int wm_adsp_load(struct wm_adsp *dsp) ++static int cs_dsp_load(struct wm_adsp *dsp) + { + LIST_HEAD(buf_list); + const struct firmware *firmware; +@@ -1811,10 +1811,10 @@ static int wm_adsp_load(struct wm_adsp *dsp) + const struct wmfw_adsp1_sizes *adsp1_sizes; + const struct wmfw_footer *footer; + const struct wmfw_region *region; +- const struct wm_adsp_region *mem; ++ const struct cs_dsp_region *mem; + const char *region_name; + char *file, *text = NULL; +- struct wm_adsp_buf *buf; ++ struct cs_dsp_buf *buf; + unsigned int reg; + int regions = 0; + int ret, offset, type; +@@ -1895,7 +1895,7 @@ static int wm_adsp_load(struct wm_adsp *dsp) + break; + case WMFW_ALGORITHM_DATA: + region_name = "Algorithm"; +- ret = wm_adsp_parse_coeff(dsp, region); ++ ret = cs_dsp_parse_coeff(dsp, region); + if (ret != 0) + goto out_fw; + break; +@@ -1916,14 +1916,14 @@ static int wm_adsp_load(struct wm_adsp *dsp) + case WMFW_HALO_PM_PACKED: + case WMFW_HALO_XM_PACKED: + case WMFW_HALO_YM_PACKED: +- mem = wm_adsp_find_region(dsp, type); ++ mem = cs_dsp_find_region(dsp, type); + if (!mem) { + adsp_err(dsp, "No region of type: %x\n", type); + ret = -EINVAL; + goto out_fw; + } + +- region_name = wm_adsp_mem_region_name(type); ++ region_name = cs_dsp_mem_region_name(type); + reg = dsp->ops->region_to_reg(mem, offset); + break; + default: +@@ -1955,9 +1955,9 @@ static int wm_adsp_load(struct wm_adsp *dsp) + } + + if (reg) { +- buf = wm_adsp_buf_alloc(region->data, +- le32_to_cpu(region->len), +- &buf_list); ++ buf = cs_dsp_buf_alloc(region->data, ++ le32_to_cpu(region->len), ++ &buf_list); + if (!buf) { + adsp_err(dsp, "Out of memory\n"); + ret = -ENOMEM; +@@ -1990,11 +1990,11 @@ static int wm_adsp_load(struct wm_adsp *dsp) + adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", + file, regions, pos - firmware->size); + +- wm_adsp_debugfs_save_wmfwname(dsp, file); ++ cs_dsp_debugfs_save_wmfwname(dsp, file); + + out_fw: + regmap_async_complete(regmap); +- wm_adsp_buf_free(&buf_list); ++ cs_dsp_buf_free(&buf_list); + release_firmware(firmware); + kfree(text); + out: +@@ -2007,9 +2007,9 @@ static int wm_adsp_load(struct wm_adsp *dsp) + * Find wm_coeff_ctl with input name as its subname + * If not found, return NULL + */ +-static struct wm_coeff_ctl *wm_adsp_get_ctl(struct wm_adsp *dsp, +- const char *name, int type, +- unsigned int alg) ++static struct wm_coeff_ctl *cs_dsp_get_ctl(struct wm_adsp *dsp, ++ const char *name, int type, ++ unsigned int alg) + { + struct wm_coeff_ctl *pos, *rslt = NULL; + const char *fw_txt = wm_adsp_fw_text[dsp->fw]; +@@ -2037,14 +2037,14 @@ int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type, + char ctl_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; + int ret; + +- ctl = wm_adsp_get_ctl(dsp, name, type, alg); ++ ctl = cs_dsp_get_ctl(dsp, name, type, alg); + if (!ctl) + return -EINVAL; + + if (len > ctl->len) + return -EINVAL; + +- ret = wm_coeff_write_ctrl(ctl, buf, len); ++ ret = cs_dsp_coeff_write_ctrl(ctl, buf, len); + if (ret) + return ret; + +@@ -2076,19 +2076,19 @@ int wm_adsp_read_ctl(struct wm_adsp *dsp, const char *name, int type, + { + struct wm_coeff_ctl *ctl; + +- ctl = wm_adsp_get_ctl(dsp, name, type, alg); ++ ctl = cs_dsp_get_ctl(dsp, name, type, alg); + if (!ctl) + return -EINVAL; + + if (len > ctl->len) + return -EINVAL; + +- return wm_coeff_read_ctrl(ctl, buf, len); ++ return cs_dsp_coeff_read_ctrl(ctl, buf, len); + } + EXPORT_SYMBOL_GPL(wm_adsp_read_ctl); + +-static void wm_adsp_ctl_fixup_base(struct wm_adsp *dsp, +- const struct wm_adsp_alg_region *alg_region) ++static void cs_dsp_ctl_fixup_base(struct wm_adsp *dsp, ++ const struct cs_dsp_alg_region *alg_region) + { + struct wm_coeff_ctl *ctl; + +@@ -2101,9 +2101,9 @@ static void wm_adsp_ctl_fixup_base(struct wm_adsp *dsp, + } + } + +-static void *wm_adsp_read_algs(struct wm_adsp *dsp, size_t n_algs, +- const struct wm_adsp_region *mem, +- unsigned int pos, unsigned int len) ++static void *cs_dsp_read_algs(struct wm_adsp *dsp, size_t n_algs, ++ const struct cs_dsp_region *mem, ++ unsigned int pos, unsigned int len) + { + void *alg; + unsigned int reg; +@@ -2153,10 +2153,10 @@ static void *wm_adsp_read_algs(struct wm_adsp *dsp, size_t n_algs, + return alg; + } + +-static struct wm_adsp_alg_region * +- wm_adsp_find_alg_region(struct wm_adsp *dsp, int type, unsigned int id) ++static struct cs_dsp_alg_region * ++ cs_dsp_find_alg_region(struct wm_adsp *dsp, int type, unsigned int id) + { +- struct wm_adsp_alg_region *alg_region; ++ struct cs_dsp_alg_region *alg_region; + + list_for_each_entry(alg_region, &dsp->alg_regions, list) { + if (id == alg_region->alg && type == alg_region->type) +@@ -2166,11 +2166,11 @@ static struct wm_adsp_alg_region * + return NULL; + } + +-static struct wm_adsp_alg_region *wm_adsp_create_region(struct wm_adsp *dsp, +- int type, __be32 id, +- __be32 base) ++static struct cs_dsp_alg_region *cs_dsp_create_region(struct wm_adsp *dsp, ++ int type, __be32 id, ++ __be32 base) + { +- struct wm_adsp_alg_region *alg_region; ++ struct cs_dsp_alg_region *alg_region; + + alg_region = kzalloc(sizeof(*alg_region), GFP_KERNEL); + if (!alg_region) +@@ -2183,26 +2183,26 @@ static struct wm_adsp_alg_region *wm_adsp_create_region(struct wm_adsp *dsp, + list_add_tail(&alg_region->list, &dsp->alg_regions); + + if (dsp->fw_ver > 0) +- wm_adsp_ctl_fixup_base(dsp, alg_region); ++ cs_dsp_ctl_fixup_base(dsp, alg_region); + + return alg_region; + } + +-static void wm_adsp_free_alg_regions(struct wm_adsp *dsp) ++static void cs_dsp_free_alg_regions(struct wm_adsp *dsp) + { +- struct wm_adsp_alg_region *alg_region; ++ struct cs_dsp_alg_region *alg_region; + + while (!list_empty(&dsp->alg_regions)) { + alg_region = list_first_entry(&dsp->alg_regions, +- struct wm_adsp_alg_region, ++ struct cs_dsp_alg_region, + list); + list_del(&alg_region->list); + kfree(alg_region); + } + } + +-static void wmfw_parse_id_header(struct wm_adsp *dsp, +- struct wmfw_id_hdr *fw, int nalgs) ++static void cs_dsp_parse_wmfw_id_header(struct wm_adsp *dsp, ++ struct wmfw_id_hdr *fw, int nalgs) + { + dsp->fw_id = be32_to_cpu(fw->id); + dsp->fw_id_version = be32_to_cpu(fw->ver); +@@ -2213,8 +2213,8 @@ static void wmfw_parse_id_header(struct wm_adsp *dsp, + nalgs); + } + +-static void wmfw_v3_parse_id_header(struct wm_adsp *dsp, +- struct wmfw_v3_id_hdr *fw, int nalgs) ++static void cs_dsp_parse_wmfw_v3_id_header(struct wm_adsp *dsp, ++ struct wmfw_v3_id_hdr *fw, int nalgs) + { + dsp->fw_id = be32_to_cpu(fw->id); + dsp->fw_id_version = be32_to_cpu(fw->ver); +@@ -2227,14 +2227,14 @@ static void wmfw_v3_parse_id_header(struct wm_adsp *dsp, + nalgs); + } + +-static int wm_adsp_create_regions(struct wm_adsp *dsp, __be32 id, int nregions, +- const int *type, __be32 *base) ++static int cs_dsp_create_regions(struct wm_adsp *dsp, __be32 id, int nregions, ++ const int *type, __be32 *base) + { +- struct wm_adsp_alg_region *alg_region; ++ struct cs_dsp_alg_region *alg_region; + int i; + + for (i = 0; i < nregions; i++) { +- alg_region = wm_adsp_create_region(dsp, type[i], id, base[i]); ++ alg_region = cs_dsp_create_region(dsp, type[i], id, base[i]); + if (IS_ERR(alg_region)) + return PTR_ERR(alg_region); + } +@@ -2242,17 +2242,17 @@ static int wm_adsp_create_regions(struct wm_adsp *dsp, __be32 id, int nregions, + return 0; + } + +-static int wm_adsp1_setup_algs(struct wm_adsp *dsp) ++static int cs_dsp_adsp1_setup_algs(struct wm_adsp *dsp) + { + struct wmfw_adsp1_id_hdr adsp1_id; + struct wmfw_adsp1_alg_hdr *adsp1_alg; +- struct wm_adsp_alg_region *alg_region; +- const struct wm_adsp_region *mem; ++ struct cs_dsp_alg_region *alg_region; ++ const struct cs_dsp_region *mem; + unsigned int pos, len; + size_t n_algs; + int i, ret; + +- mem = wm_adsp_find_region(dsp, WMFW_ADSP1_DM); ++ mem = cs_dsp_find_region(dsp, WMFW_ADSP1_DM); + if (WARN_ON(!mem)) + return -EINVAL; + +@@ -2266,15 +2266,15 @@ static int wm_adsp1_setup_algs(struct wm_adsp *dsp) + + n_algs = be32_to_cpu(adsp1_id.n_algs); + +- wmfw_parse_id_header(dsp, &adsp1_id.fw, n_algs); ++ cs_dsp_parse_wmfw_id_header(dsp, &adsp1_id.fw, n_algs); + +- alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_ZM, +- adsp1_id.fw.id, adsp1_id.zm); ++ alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_ZM, ++ adsp1_id.fw.id, adsp1_id.zm); + if (IS_ERR(alg_region)) + return PTR_ERR(alg_region); + +- alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_DM, +- adsp1_id.fw.id, adsp1_id.dm); ++ alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_DM, ++ adsp1_id.fw.id, adsp1_id.dm); + if (IS_ERR(alg_region)) + return PTR_ERR(alg_region); + +@@ -2282,7 +2282,7 @@ static int wm_adsp1_setup_algs(struct wm_adsp *dsp) + pos = sizeof(adsp1_id) / sizeof(u32); + len = (sizeof(*adsp1_alg) * n_algs) / sizeof(u32); + +- adsp1_alg = wm_adsp_read_algs(dsp, n_algs, mem, pos, len); ++ adsp1_alg = cs_dsp_read_algs(dsp, n_algs, mem, pos, len); + if (IS_ERR(adsp1_alg)) + return PTR_ERR(adsp1_alg); + +@@ -2295,9 +2295,9 @@ static int wm_adsp1_setup_algs(struct wm_adsp *dsp) + be32_to_cpu(adsp1_alg[i].dm), + be32_to_cpu(adsp1_alg[i].zm)); + +- alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_DM, +- adsp1_alg[i].alg.id, +- adsp1_alg[i].dm); ++ alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_DM, ++ adsp1_alg[i].alg.id, ++ adsp1_alg[i].dm); + if (IS_ERR(alg_region)) { + ret = PTR_ERR(alg_region); + goto out; +@@ -2307,18 +2307,18 @@ static int wm_adsp1_setup_algs(struct wm_adsp *dsp) + len = be32_to_cpu(adsp1_alg[i + 1].dm); + len -= be32_to_cpu(adsp1_alg[i].dm); + len *= 4; +- wm_adsp_create_control(dsp, alg_region, 0, +- len, NULL, 0, 0, +- WMFW_CTL_TYPE_BYTES); ++ cs_dsp_create_control(dsp, alg_region, 0, ++ len, NULL, 0, 0, ++ WMFW_CTL_TYPE_BYTES); + } else { + adsp_warn(dsp, "Missing length info for region DM with ID %x\n", + be32_to_cpu(adsp1_alg[i].alg.id)); + } + } + +- alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_ZM, +- adsp1_alg[i].alg.id, +- adsp1_alg[i].zm); ++ alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_ZM, ++ adsp1_alg[i].alg.id, ++ adsp1_alg[i].zm); + if (IS_ERR(alg_region)) { + ret = PTR_ERR(alg_region); + goto out; +@@ -2328,9 +2328,9 @@ static int wm_adsp1_setup_algs(struct wm_adsp *dsp) + len = be32_to_cpu(adsp1_alg[i + 1].zm); + len -= be32_to_cpu(adsp1_alg[i].zm); + len *= 4; +- wm_adsp_create_control(dsp, alg_region, 0, +- len, NULL, 0, 0, +- WMFW_CTL_TYPE_BYTES); ++ cs_dsp_create_control(dsp, alg_region, 0, ++ len, NULL, 0, 0, ++ WMFW_CTL_TYPE_BYTES); + } else { + adsp_warn(dsp, "Missing length info for region ZM with ID %x\n", + be32_to_cpu(adsp1_alg[i].alg.id)); +@@ -2343,17 +2343,17 @@ static int wm_adsp1_setup_algs(struct wm_adsp *dsp) + return ret; + } + +-static int wm_adsp2_setup_algs(struct wm_adsp *dsp) ++static int cs_dsp_adsp2_setup_algs(struct wm_adsp *dsp) + { + struct wmfw_adsp2_id_hdr adsp2_id; + struct wmfw_adsp2_alg_hdr *adsp2_alg; +- struct wm_adsp_alg_region *alg_region; +- const struct wm_adsp_region *mem; ++ struct cs_dsp_alg_region *alg_region; ++ const struct cs_dsp_region *mem; + unsigned int pos, len; + size_t n_algs; + int i, ret; + +- mem = wm_adsp_find_region(dsp, WMFW_ADSP2_XM); ++ mem = cs_dsp_find_region(dsp, WMFW_ADSP2_XM); + if (WARN_ON(!mem)) + return -EINVAL; + +@@ -2367,20 +2367,20 @@ static int wm_adsp2_setup_algs(struct wm_adsp *dsp) + + n_algs = be32_to_cpu(adsp2_id.n_algs); + +- wmfw_parse_id_header(dsp, &adsp2_id.fw, n_algs); ++ cs_dsp_parse_wmfw_id_header(dsp, &adsp2_id.fw, n_algs); + +- alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_XM, +- adsp2_id.fw.id, adsp2_id.xm); ++ alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_XM, ++ adsp2_id.fw.id, adsp2_id.xm); + if (IS_ERR(alg_region)) + return PTR_ERR(alg_region); + +- alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_YM, +- adsp2_id.fw.id, adsp2_id.ym); ++ alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_YM, ++ adsp2_id.fw.id, adsp2_id.ym); + if (IS_ERR(alg_region)) + return PTR_ERR(alg_region); + +- alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_ZM, +- adsp2_id.fw.id, adsp2_id.zm); ++ alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_ZM, ++ adsp2_id.fw.id, adsp2_id.zm); + if (IS_ERR(alg_region)) + return PTR_ERR(alg_region); + +@@ -2388,7 +2388,7 @@ static int wm_adsp2_setup_algs(struct wm_adsp *dsp) + pos = sizeof(adsp2_id) / sizeof(u32); + len = (sizeof(*adsp2_alg) * n_algs) / sizeof(u32); + +- adsp2_alg = wm_adsp_read_algs(dsp, n_algs, mem, pos, len); ++ adsp2_alg = cs_dsp_read_algs(dsp, n_algs, mem, pos, len); + if (IS_ERR(adsp2_alg)) + return PTR_ERR(adsp2_alg); + +@@ -2403,9 +2403,9 @@ static int wm_adsp2_setup_algs(struct wm_adsp *dsp) + be32_to_cpu(adsp2_alg[i].ym), + be32_to_cpu(adsp2_alg[i].zm)); + +- alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_XM, +- adsp2_alg[i].alg.id, +- adsp2_alg[i].xm); ++ alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_XM, ++ adsp2_alg[i].alg.id, ++ adsp2_alg[i].xm); + if (IS_ERR(alg_region)) { + ret = PTR_ERR(alg_region); + goto out; +@@ -2415,18 +2415,18 @@ static int wm_adsp2_setup_algs(struct wm_adsp *dsp) + len = be32_to_cpu(adsp2_alg[i + 1].xm); + len -= be32_to_cpu(adsp2_alg[i].xm); + len *= 4; +- wm_adsp_create_control(dsp, alg_region, 0, +- len, NULL, 0, 0, +- WMFW_CTL_TYPE_BYTES); ++ cs_dsp_create_control(dsp, alg_region, 0, ++ len, NULL, 0, 0, ++ WMFW_CTL_TYPE_BYTES); + } else { + adsp_warn(dsp, "Missing length info for region XM with ID %x\n", + be32_to_cpu(adsp2_alg[i].alg.id)); + } + } + +- alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_YM, +- adsp2_alg[i].alg.id, +- adsp2_alg[i].ym); ++ alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_YM, ++ adsp2_alg[i].alg.id, ++ adsp2_alg[i].ym); + if (IS_ERR(alg_region)) { + ret = PTR_ERR(alg_region); + goto out; +@@ -2436,18 +2436,18 @@ static int wm_adsp2_setup_algs(struct wm_adsp *dsp) + len = be32_to_cpu(adsp2_alg[i + 1].ym); + len -= be32_to_cpu(adsp2_alg[i].ym); + len *= 4; +- wm_adsp_create_control(dsp, alg_region, 0, +- len, NULL, 0, 0, +- WMFW_CTL_TYPE_BYTES); ++ cs_dsp_create_control(dsp, alg_region, 0, ++ len, NULL, 0, 0, ++ WMFW_CTL_TYPE_BYTES); + } else { + adsp_warn(dsp, "Missing length info for region YM with ID %x\n", + be32_to_cpu(adsp2_alg[i].alg.id)); + } + } + +- alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_ZM, +- adsp2_alg[i].alg.id, +- adsp2_alg[i].zm); ++ alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_ZM, ++ adsp2_alg[i].alg.id, ++ adsp2_alg[i].zm); + if (IS_ERR(alg_region)) { + ret = PTR_ERR(alg_region); + goto out; +@@ -2457,9 +2457,9 @@ static int wm_adsp2_setup_algs(struct wm_adsp *dsp) + len = be32_to_cpu(adsp2_alg[i + 1].zm); + len -= be32_to_cpu(adsp2_alg[i].zm); + len *= 4; +- wm_adsp_create_control(dsp, alg_region, 0, +- len, NULL, 0, 0, +- WMFW_CTL_TYPE_BYTES); ++ cs_dsp_create_control(dsp, alg_region, 0, ++ len, NULL, 0, 0, ++ WMFW_CTL_TYPE_BYTES); + } else { + adsp_warn(dsp, "Missing length info for region ZM with ID %x\n", + be32_to_cpu(adsp2_alg[i].alg.id)); +@@ -2472,8 +2472,8 @@ static int wm_adsp2_setup_algs(struct wm_adsp *dsp) + return ret; + } + +-static int wm_halo_create_regions(struct wm_adsp *dsp, __be32 id, +- __be32 xm_base, __be32 ym_base) ++static int cs_dsp_halo_create_regions(struct wm_adsp *dsp, __be32 id, ++ __be32 xm_base, __be32 ym_base) + { + static const int types[] = { + WMFW_ADSP2_XM, WMFW_HALO_XM_PACKED, +@@ -2481,19 +2481,19 @@ static int wm_halo_create_regions(struct wm_adsp *dsp, __be32 id, + }; + __be32 bases[] = { xm_base, xm_base, ym_base, ym_base }; + +- return wm_adsp_create_regions(dsp, id, ARRAY_SIZE(types), types, bases); ++ return cs_dsp_create_regions(dsp, id, ARRAY_SIZE(types), types, bases); + } + +-static int wm_halo_setup_algs(struct wm_adsp *dsp) ++static int cs_dsp_halo_setup_algs(struct wm_adsp *dsp) + { + struct wmfw_halo_id_hdr halo_id; + struct wmfw_halo_alg_hdr *halo_alg; +- const struct wm_adsp_region *mem; ++ const struct cs_dsp_region *mem; + unsigned int pos, len; + size_t n_algs; + int i, ret; + +- mem = wm_adsp_find_region(dsp, WMFW_ADSP2_XM); ++ mem = cs_dsp_find_region(dsp, WMFW_ADSP2_XM); + if (WARN_ON(!mem)) + return -EINVAL; + +@@ -2507,10 +2507,10 @@ static int wm_halo_setup_algs(struct wm_adsp *dsp) + + n_algs = be32_to_cpu(halo_id.n_algs); + +- wmfw_v3_parse_id_header(dsp, &halo_id.fw, n_algs); ++ cs_dsp_parse_wmfw_v3_id_header(dsp, &halo_id.fw, n_algs); + +- ret = wm_halo_create_regions(dsp, halo_id.fw.id, +- halo_id.xm_base, halo_id.ym_base); ++ ret = cs_dsp_halo_create_regions(dsp, halo_id.fw.id, ++ halo_id.xm_base, halo_id.ym_base); + if (ret) + return ret; + +@@ -2518,7 +2518,7 @@ static int wm_halo_setup_algs(struct wm_adsp *dsp) + pos = sizeof(halo_id) / sizeof(u32); + len = (sizeof(*halo_alg) * n_algs) / sizeof(u32); + +- halo_alg = wm_adsp_read_algs(dsp, n_algs, mem, pos, len); ++ halo_alg = cs_dsp_read_algs(dsp, n_algs, mem, pos, len); + if (IS_ERR(halo_alg)) + return PTR_ERR(halo_alg); + +@@ -2532,9 +2532,9 @@ static int wm_halo_setup_algs(struct wm_adsp *dsp) + be32_to_cpu(halo_alg[i].xm_base), + be32_to_cpu(halo_alg[i].ym_base)); + +- ret = wm_halo_create_regions(dsp, halo_alg[i].alg.id, +- halo_alg[i].xm_base, +- halo_alg[i].ym_base); ++ ret = cs_dsp_halo_create_regions(dsp, halo_alg[i].alg.id, ++ halo_alg[i].xm_base, ++ halo_alg[i].ym_base); + if (ret) + goto out; + } +@@ -2544,19 +2544,19 @@ static int wm_halo_setup_algs(struct wm_adsp *dsp) + return ret; + } + +-static int wm_adsp_load_coeff(struct wm_adsp *dsp) ++static int cs_dsp_load_coeff(struct wm_adsp *dsp) + { + LIST_HEAD(buf_list); + struct regmap *regmap = dsp->regmap; + struct wmfw_coeff_hdr *hdr; + struct wmfw_coeff_item *blk; + const struct firmware *firmware; +- const struct wm_adsp_region *mem; +- struct wm_adsp_alg_region *alg_region; ++ const struct cs_dsp_region *mem; ++ struct cs_dsp_alg_region *alg_region; + const char *region_name; + int ret, pos, blocks, type, offset, reg; + char *file; +- struct wm_adsp_buf *buf; ++ struct cs_dsp_buf *buf; + + file = kzalloc(PAGE_SIZE, GFP_KERNEL); + if (file == NULL) +@@ -2634,7 +2634,7 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp) + if (le32_to_cpu(blk->id) == dsp->fw_id && + offset == 0) { + region_name = "global coefficients"; +- mem = wm_adsp_find_region(dsp, type); ++ mem = cs_dsp_find_region(dsp, type); + if (!mem) { + adsp_err(dsp, "No ZM\n"); + break; +@@ -2658,14 +2658,14 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp) + file, blocks, le32_to_cpu(blk->len), + type, le32_to_cpu(blk->id)); + +- mem = wm_adsp_find_region(dsp, type); ++ mem = cs_dsp_find_region(dsp, type); + if (!mem) { + adsp_err(dsp, "No base for region %x\n", type); + break; + } + +- alg_region = wm_adsp_find_alg_region(dsp, type, +- le32_to_cpu(blk->id)); ++ alg_region = cs_dsp_find_alg_region(dsp, type, ++ le32_to_cpu(blk->id)); + if (alg_region) { + reg = alg_region->base; + reg = dsp->ops->region_to_reg(mem, reg); +@@ -2694,9 +2694,9 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp) + goto out_fw; + } + +- buf = wm_adsp_buf_alloc(blk->data, +- le32_to_cpu(blk->len), +- &buf_list); ++ buf = cs_dsp_buf_alloc(blk->data, ++ le32_to_cpu(blk->len), ++ &buf_list); + if (!buf) { + adsp_err(dsp, "Out of memory\n"); + ret = -ENOMEM; +@@ -2727,18 +2727,18 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp) + adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", + file, blocks, pos - firmware->size); + +- wm_adsp_debugfs_save_binname(dsp, file); ++ cs_dsp_debugfs_save_binname(dsp, file); + + out_fw: + regmap_async_complete(regmap); + release_firmware(firmware); +- wm_adsp_buf_free(&buf_list); ++ cs_dsp_buf_free(&buf_list); + out: + kfree(file); + return ret; + } + +-static int wm_adsp_create_name(struct wm_adsp *dsp) ++static int cs_dsp_create_name(struct wm_adsp *dsp) + { + char *p; + +@@ -2766,7 +2766,7 @@ static int wm_adsp_common_init(struct wm_adsp *dsp) + { + int ret; + +- ret = wm_adsp_create_name(dsp); ++ ret = cs_dsp_create_name(dsp); + if (ret) + return ret; + +@@ -2782,7 +2782,7 @@ static int wm_adsp_common_init(struct wm_adsp *dsp) + + int wm_adsp1_init(struct wm_adsp *dsp) + { +- dsp->ops = &wm_adsp1_ops; ++ dsp->ops = &cs_dsp_adsp1_ops; + + return wm_adsp_common_init(dsp); + } +@@ -2832,25 +2832,25 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, + } + } + +- ret = wm_adsp_load(dsp); ++ ret = cs_dsp_load(dsp); + if (ret != 0) + goto err_ena; + +- ret = wm_adsp1_setup_algs(dsp); ++ ret = cs_dsp_adsp1_setup_algs(dsp); + if (ret != 0) + goto err_ena; + +- ret = wm_adsp_load_coeff(dsp); ++ ret = cs_dsp_load_coeff(dsp); + if (ret != 0) + goto err_ena; + + /* Initialize caches for enabled and unset controls */ +- ret = wm_coeff_init_control_caches(dsp); ++ ret = cs_dsp_coeff_init_control_caches(dsp); + if (ret != 0) + goto err_ena; + + /* Sync set controls */ +- ret = wm_coeff_sync_controls(dsp); ++ ret = cs_dsp_coeff_sync_controls(dsp); + if (ret != 0) + goto err_ena; + +@@ -2882,7 +2882,7 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, + ctl->enabled = 0; + + +- wm_adsp_free_alg_regions(dsp); ++ cs_dsp_free_alg_regions(dsp); + break; + + default: +@@ -2903,7 +2903,7 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, + } + EXPORT_SYMBOL_GPL(wm_adsp1_event); + +-static int wm_adsp2v2_enable_core(struct wm_adsp *dsp) ++static int cs_dsp_adsp2v2_enable_core(struct wm_adsp *dsp) + { + unsigned int val; + int ret, count; +@@ -2930,7 +2930,7 @@ static int wm_adsp2v2_enable_core(struct wm_adsp *dsp) + return 0; + } + +-static int wm_adsp2_enable_core(struct wm_adsp *dsp) ++static int cs_dsp_adsp2_enable_core(struct wm_adsp *dsp) + { + int ret; + +@@ -2939,18 +2939,18 @@ static int wm_adsp2_enable_core(struct wm_adsp *dsp) + if (ret != 0) + return ret; + +- return wm_adsp2v2_enable_core(dsp); ++ return cs_dsp_adsp2v2_enable_core(dsp); + } + +-static int wm_adsp2_lock(struct wm_adsp *dsp, unsigned int lock_regions) ++static int cs_dsp_adsp2_lock(struct wm_adsp *dsp, unsigned int lock_regions) + { + struct regmap *regmap = dsp->regmap; + unsigned int code0, code1, lock_reg; + +- if (!(lock_regions & WM_ADSP2_REGION_ALL)) ++ if (!(lock_regions & CS_ADSP2_REGION_ALL)) + return 0; + +- lock_regions &= WM_ADSP2_REGION_ALL; ++ lock_regions &= CS_ADSP2_REGION_ALL; + lock_reg = dsp->base + ADSP2_LOCK_REGION_1_LOCK_REGION_0; + + while (lock_regions) { +@@ -2972,19 +2972,19 @@ static int wm_adsp2_lock(struct wm_adsp *dsp, unsigned int lock_regions) + return 0; + } + +-static int wm_adsp2_enable_memory(struct wm_adsp *dsp) ++static int cs_dsp_adsp2_enable_memory(struct wm_adsp *dsp) + { + return regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_MEM_ENA, ADSP2_MEM_ENA); + } + +-static void wm_adsp2_disable_memory(struct wm_adsp *dsp) ++static void cs_dsp_adsp2_disable_memory(struct wm_adsp *dsp) + { + regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_MEM_ENA, 0); + } + +-static void wm_adsp2_disable_core(struct wm_adsp *dsp) ++static void cs_dsp_adsp2_disable_core(struct wm_adsp *dsp) + { + regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0); + regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0); +@@ -2994,7 +2994,7 @@ static void wm_adsp2_disable_core(struct wm_adsp *dsp) + ADSP2_SYS_ENA, 0); + } + +-static void wm_adsp2v2_disable_core(struct wm_adsp *dsp) ++static void cs_dsp_adsp2v2_disable_core(struct wm_adsp *dsp) + { + regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0); + regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0); +@@ -3022,7 +3022,7 @@ static void wm_adsp_boot_work(struct work_struct *work) + goto err_mem; + } + +- ret = wm_adsp_load(dsp); ++ ret = cs_dsp_load(dsp); + if (ret != 0) + goto err_ena; + +@@ -3030,12 +3030,12 @@ static void wm_adsp_boot_work(struct work_struct *work) + if (ret != 0) + goto err_ena; + +- ret = wm_adsp_load_coeff(dsp); ++ ret = cs_dsp_load_coeff(dsp); + if (ret != 0) + goto err_ena; + + /* Initialize caches for enabled and unset controls */ +- ret = wm_coeff_init_control_caches(dsp); ++ ret = cs_dsp_coeff_init_control_caches(dsp); + if (ret != 0) + goto err_ena; + +@@ -3058,7 +3058,7 @@ static void wm_adsp_boot_work(struct work_struct *work) + mutex_unlock(&dsp->pwr_lock); + } + +-static int wm_halo_configure_mpu(struct wm_adsp *dsp, unsigned int lock_regions) ++static int cs_dsp_halo_configure_mpu(struct wm_adsp *dsp, unsigned int lock_regions) + { + struct reg_sequence config[] = { + { dsp->base + HALO_MPU_LOCK_CONFIG, 0x5555 }, +@@ -3149,13 +3149,13 @@ int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol, + } + EXPORT_SYMBOL_GPL(wm_adsp2_preloader_put); + +-static void wm_adsp_stop_watchdog(struct wm_adsp *dsp) ++static void cs_dsp_stop_watchdog(struct wm_adsp *dsp) + { + regmap_update_bits(dsp->regmap, dsp->base + ADSP2_WATCHDOG, + ADSP2_WDT_ENA_MASK, 0); + } + +-static void wm_halo_stop_watchdog(struct wm_adsp *dsp) ++static void cs_dsp_halo_stop_watchdog(struct wm_adsp *dsp) + { + regmap_update_bits(dsp->regmap, dsp->base + HALO_WDT_CONTROL, + HALO_WDT_EN_MASK, 0); +@@ -3176,7 +3176,7 @@ int wm_adsp_early_event(struct snd_soc_dapm_widget *w, + case SND_SOC_DAPM_PRE_PMD: + mutex_lock(&dsp->pwr_lock); + +- wm_adsp_debugfs_clear(dsp); ++ cs_dsp_debugfs_clear(dsp); + + dsp->fw_id = 0; + dsp->fw_id_version = 0; +@@ -3189,7 +3189,7 @@ int wm_adsp_early_event(struct snd_soc_dapm_widget *w, + list_for_each_entry(ctl, &dsp->ctl_list, list) + ctl->enabled = 0; + +- wm_adsp_free_alg_regions(dsp); ++ cs_dsp_free_alg_regions(dsp); + + mutex_unlock(&dsp->pwr_lock); + +@@ -3203,14 +3203,14 @@ int wm_adsp_early_event(struct snd_soc_dapm_widget *w, + } + EXPORT_SYMBOL_GPL(wm_adsp_early_event); + +-static int wm_adsp2_start_core(struct wm_adsp *dsp) ++static int cs_dsp_adsp2_start_core(struct wm_adsp *dsp) + { + return regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_CORE_ENA | ADSP2_START, + ADSP2_CORE_ENA | ADSP2_START); + } + +-static void wm_adsp2_stop_core(struct wm_adsp *dsp) ++static void cs_dsp_adsp2_stop_core(struct wm_adsp *dsp) + { + regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_CORE_ENA | ADSP2_START, 0); +@@ -3242,7 +3242,7 @@ int wm_adsp_event(struct snd_soc_dapm_widget *w, + } + + /* Sync set controls */ +- ret = wm_coeff_sync_controls(dsp); ++ ret = cs_dsp_coeff_sync_controls(dsp); + if (ret != 0) + goto err; + +@@ -3274,7 +3274,7 @@ int wm_adsp_event(struct snd_soc_dapm_widget *w, + + case SND_SOC_DAPM_PRE_PMD: + /* Tell the firmware to cleanup */ +- wm_adsp_signal_event_controls(dsp, WM_ADSP_FW_EVENT_SHUTDOWN); ++ cs_dsp_signal_event_controls(dsp, CS_DSP_FW_EVENT_SHUTDOWN); + + if (dsp->ops->stop_watchdog) + dsp->ops->stop_watchdog(dsp); +@@ -3317,7 +3317,7 @@ int wm_adsp_event(struct snd_soc_dapm_widget *w, + } + EXPORT_SYMBOL_GPL(wm_adsp_event); + +-static int wm_halo_start_core(struct wm_adsp *dsp) ++static int cs_dsp_halo_start_core(struct wm_adsp *dsp) + { + return regmap_update_bits(dsp->regmap, + dsp->base + HALO_CCM_CORE_CONTROL, +@@ -3325,7 +3325,7 @@ static int wm_halo_start_core(struct wm_adsp *dsp) + HALO_CORE_RESET | HALO_CORE_EN); + } + +-static void wm_halo_stop_core(struct wm_adsp *dsp) ++static void cs_dsp_halo_stop_core(struct wm_adsp *dsp) + { + regmap_update_bits(dsp->regmap, dsp->base + HALO_CCM_CORE_CONTROL, + HALO_CORE_EN, 0); +@@ -3342,7 +3342,7 @@ int wm_adsp2_component_probe(struct wm_adsp *dsp, struct snd_soc_component *comp + snprintf(preload, ARRAY_SIZE(preload), "%s Preload", dsp->name); + snd_soc_component_disable_pin(component, preload); + +- wm_adsp2_init_debugfs(dsp, component); ++ cs_dsp_init_debugfs(dsp, component); + + dsp->component = component; + +@@ -3352,7 +3352,7 @@ EXPORT_SYMBOL_GPL(wm_adsp2_component_probe); + + int wm_adsp2_component_remove(struct wm_adsp *dsp, struct snd_soc_component *component) + { +- wm_adsp2_cleanup_debugfs(dsp); ++ cs_dsp_cleanup_debugfs(dsp); + + return 0; + } +@@ -3380,13 +3380,13 @@ int wm_adsp2_init(struct wm_adsp *dsp) + return ret; + } + +- dsp->ops = &wm_adsp2_ops[0]; ++ dsp->ops = &cs_dsp_adsp2_ops[0]; + break; + case 1: +- dsp->ops = &wm_adsp2_ops[1]; ++ dsp->ops = &cs_dsp_adsp2_ops[1]; + break; + default: +- dsp->ops = &wm_adsp2_ops[2]; ++ dsp->ops = &cs_dsp_adsp2_ops[2]; + break; + } + +@@ -3404,7 +3404,7 @@ int wm_halo_init(struct wm_adsp *dsp) + if (ret) + return ret; + +- dsp->ops = &wm_halo_ops; ++ dsp->ops = &cs_dsp_halo_ops; + + INIT_WORK(&dsp->boot_work, wm_adsp_boot_work); + +@@ -3420,7 +3420,7 @@ void wm_adsp2_remove(struct wm_adsp *dsp) + ctl = list_first_entry(&dsp->ctl_list, struct wm_coeff_ctl, + list); + list_del(&ctl->list); +- wm_adsp_free_ctl_blk(ctl); ++ cs_dsp_free_ctl_blk(ctl); + } + } + EXPORT_SYMBOL_GPL(wm_adsp2_remove); +@@ -3553,7 +3553,7 @@ static int wm_adsp_compr_check_params(struct snd_compr_stream *stream, + params->buffer.fragment_size > WM_ADSP_MAX_FRAGMENT_SIZE || + params->buffer.fragments < WM_ADSP_MIN_FRAGMENTS || + params->buffer.fragments > WM_ADSP_MAX_FRAGMENTS || +- params->buffer.fragment_size % WM_ADSP_DATA_WORD_SIZE) { ++ params->buffer.fragment_size % CS_DSP_DATA_WORD_SIZE) { + compr_err(compr, "Invalid buffer fragsize=%d fragments=%d\n", + params->buffer.fragment_size, + params->buffer.fragments); +@@ -3592,7 +3592,7 @@ static int wm_adsp_compr_check_params(struct snd_compr_stream *stream, + + static inline unsigned int wm_adsp_compr_frag_words(struct wm_adsp_compr *compr) + { +- return compr->size.fragment_size / WM_ADSP_DATA_WORD_SIZE; ++ return compr->size.fragment_size / CS_DSP_DATA_WORD_SIZE; + } + + int wm_adsp_compr_set_params(struct snd_soc_component *component, +@@ -3648,11 +3648,11 @@ int wm_adsp_compr_get_caps(struct snd_soc_component *component, + } + EXPORT_SYMBOL_GPL(wm_adsp_compr_get_caps); + +-static int wm_adsp_read_raw_data_block(struct wm_adsp *dsp, int mem_type, +- unsigned int mem_addr, +- unsigned int num_words, __be32 *data) ++static int cs_dsp_read_raw_data_block(struct wm_adsp *dsp, int mem_type, ++ unsigned int mem_addr, ++ unsigned int num_words, __be32 *data) + { +- struct wm_adsp_region const *mem = wm_adsp_find_region(dsp, mem_type); ++ struct cs_dsp_region const *mem = cs_dsp_find_region(dsp, mem_type); + unsigned int reg; + int ret; + +@@ -3669,13 +3669,13 @@ static int wm_adsp_read_raw_data_block(struct wm_adsp *dsp, int mem_type, + return 0; + } + +-static inline int wm_adsp_read_data_word(struct wm_adsp *dsp, int mem_type, +- unsigned int mem_addr, u32 *data) ++static inline int cs_dsp_read_data_word(struct wm_adsp *dsp, int mem_type, ++ unsigned int mem_addr, u32 *data) + { + __be32 raw; + int ret; + +- ret = wm_adsp_read_raw_data_block(dsp, mem_type, mem_addr, 1, &raw); ++ ret = cs_dsp_read_raw_data_block(dsp, mem_type, mem_addr, 1, &raw); + if (ret < 0) + return ret; + +@@ -3684,10 +3684,10 @@ static inline int wm_adsp_read_data_word(struct wm_adsp *dsp, int mem_type, + return 0; + } + +-static int wm_adsp_write_data_word(struct wm_adsp *dsp, int mem_type, +- unsigned int mem_addr, u32 data) ++static int cs_dsp_write_data_word(struct wm_adsp *dsp, int mem_type, ++ unsigned int mem_addr, u32 data) + { +- struct wm_adsp_region const *mem = wm_adsp_find_region(dsp, mem_type); ++ struct cs_dsp_region const *mem = cs_dsp_find_region(dsp, mem_type); + __be32 val = cpu_to_be32(data & 0x00ffffffu); + unsigned int reg; + +@@ -3702,18 +3702,18 @@ static int wm_adsp_write_data_word(struct wm_adsp *dsp, int mem_type, + static inline int wm_adsp_buffer_read(struct wm_adsp_compr_buf *buf, + unsigned int field_offset, u32 *data) + { +- return wm_adsp_read_data_word(buf->dsp, buf->host_buf_mem_type, +- buf->host_buf_ptr + field_offset, data); ++ return cs_dsp_read_data_word(buf->dsp, buf->host_buf_mem_type, ++ buf->host_buf_ptr + field_offset, data); + } + + static inline int wm_adsp_buffer_write(struct wm_adsp_compr_buf *buf, + unsigned int field_offset, u32 data) + { +- return wm_adsp_write_data_word(buf->dsp, buf->host_buf_mem_type, +- buf->host_buf_ptr + field_offset, data); ++ return cs_dsp_write_data_word(buf->dsp, buf->host_buf_mem_type, ++ buf->host_buf_ptr + field_offset, data); + } + +-static void wm_adsp_remove_padding(u32 *buf, int nwords) ++static void cs_dsp_remove_padding(u32 *buf, int nwords) + { + const __be32 *pack_in = (__be32 *)buf; + u8 *pack_out = (u8 *)buf; +@@ -3797,12 +3797,12 @@ static struct wm_adsp_compr_buf *wm_adsp_buffer_alloc(struct wm_adsp *dsp) + + static int wm_adsp_buffer_parse_legacy(struct wm_adsp *dsp) + { +- struct wm_adsp_alg_region *alg_region; ++ struct cs_dsp_alg_region *alg_region; + struct wm_adsp_compr_buf *buf; + u32 xmalg, addr, magic; + int i, ret; + +- alg_region = wm_adsp_find_alg_region(dsp, WMFW_ADSP2_XM, dsp->fw_id); ++ alg_region = cs_dsp_find_alg_region(dsp, WMFW_ADSP2_XM, dsp->fw_id); + if (!alg_region) { + adsp_err(dsp, "No algorithm region found\n"); + return -EINVAL; +@@ -3815,7 +3815,7 @@ static int wm_adsp_buffer_parse_legacy(struct wm_adsp *dsp) + xmalg = dsp->ops->sys_config_size / sizeof(__be32); + + addr = alg_region->base + xmalg + ALG_XM_FIELD(magic); +- ret = wm_adsp_read_data_word(dsp, WMFW_ADSP2_XM, addr, &magic); ++ ret = cs_dsp_read_data_word(dsp, WMFW_ADSP2_XM, addr, &magic); + if (ret < 0) + return ret; + +@@ -3824,8 +3824,8 @@ static int wm_adsp_buffer_parse_legacy(struct wm_adsp *dsp) + + addr = alg_region->base + xmalg + ALG_XM_FIELD(host_buf_ptr); + for (i = 0; i < 5; ++i) { +- ret = wm_adsp_read_data_word(dsp, WMFW_ADSP2_XM, addr, +- &buf->host_buf_ptr); ++ ret = cs_dsp_read_data_word(dsp, WMFW_ADSP2_XM, addr, ++ &buf->host_buf_ptr); + if (ret < 0) + return ret; + +@@ -3857,7 +3857,7 @@ static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) + int ret, i; + + for (i = 0; i < 5; ++i) { +- ret = wm_coeff_read_ctrl(ctl, &coeff_v1, sizeof(coeff_v1)); ++ ret = cs_dsp_coeff_read_ctrl(ctl, &coeff_v1, sizeof(coeff_v1)); + if (ret < 0) + return ret; + +@@ -3902,7 +3902,7 @@ static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) + return -EINVAL; + } + +- wm_adsp_remove_padding((u32 *)&coeff_v1.name, ARRAY_SIZE(coeff_v1.name)); ++ cs_dsp_remove_padding((u32 *)&coeff_v1.name, ARRAY_SIZE(coeff_v1.name)); + + buf->name = kasprintf(GFP_KERNEL, "%s-dsp-%s", ctl->dsp->part, + (char *)&coeff_v1.name); +@@ -4078,7 +4078,7 @@ static int wm_adsp_buffer_update_avail(struct wm_adsp_compr_buf *buf) + avail += wm_adsp_buffer_size(buf); + + compr_dbg(buf, "readindex=0x%x, writeindex=0x%x, avail=%d\n", +- buf->read_index, write_index, avail * WM_ADSP_DATA_WORD_SIZE); ++ buf->read_index, write_index, avail * CS_DSP_DATA_WORD_SIZE); + + buf->avail = avail; + +@@ -4199,7 +4199,7 @@ int wm_adsp_compr_pointer(struct snd_soc_component *component, + } + + tstamp->copied_total = compr->copied_total; +- tstamp->copied_total += buf->avail * WM_ADSP_DATA_WORD_SIZE; ++ tstamp->copied_total += buf->avail * CS_DSP_DATA_WORD_SIZE; + tstamp->sampling_rate = compr->sample_rate; + + out: +@@ -4241,12 +4241,12 @@ static int wm_adsp_buffer_capture_block(struct wm_adsp_compr *compr, int target) + return 0; + + /* Read data from DSP */ +- ret = wm_adsp_read_raw_data_block(buf->dsp, mem_type, adsp_addr, +- nwords, (__be32 *)compr->raw_buf); ++ ret = cs_dsp_read_raw_data_block(buf->dsp, mem_type, adsp_addr, ++ nwords, (__be32 *)compr->raw_buf); + if (ret < 0) + return ret; + +- wm_adsp_remove_padding(compr->raw_buf, nwords); ++ cs_dsp_remove_padding(compr->raw_buf, nwords); + + /* update read index to account for words read */ + buf->read_index += nwords; +@@ -4278,7 +4278,7 @@ static int wm_adsp_compr_read(struct wm_adsp_compr *compr, + return -EIO; + } + +- count /= WM_ADSP_DATA_WORD_SIZE; ++ count /= CS_DSP_DATA_WORD_SIZE; + + do { + nwords = wm_adsp_buffer_capture_block(compr, count); +@@ -4288,7 +4288,7 @@ static int wm_adsp_compr_read(struct wm_adsp_compr *compr, + return nwords; + } + +- nbytes = nwords * WM_ADSP_DATA_WORD_SIZE; ++ nbytes = nwords * CS_DSP_DATA_WORD_SIZE; + + compr_dbg(compr, "Read %d bytes\n", nbytes); + +@@ -4479,87 +4479,87 @@ irqreturn_t wm_halo_wdt_expire(int irq, void *data) + } + EXPORT_SYMBOL_GPL(wm_halo_wdt_expire); + +-static const struct wm_adsp_ops wm_adsp1_ops = { +- .validate_version = wm_adsp_validate_version, +- .parse_sizes = wm_adsp1_parse_sizes, +- .region_to_reg = wm_adsp_region_to_reg, ++static const struct cs_dsp_ops cs_dsp_adsp1_ops = { ++ .validate_version = cs_dsp_validate_version, ++ .parse_sizes = cs_dsp_adsp1_parse_sizes, ++ .region_to_reg = cs_dsp_region_to_reg, + }; + +-static const struct wm_adsp_ops wm_adsp2_ops[] = { ++static const struct cs_dsp_ops cs_dsp_adsp2_ops[] = { + { + .sys_config_size = sizeof(struct wm_adsp_system_config_xm_hdr), +- .parse_sizes = wm_adsp2_parse_sizes, +- .validate_version = wm_adsp_validate_version, +- .setup_algs = wm_adsp2_setup_algs, +- .region_to_reg = wm_adsp_region_to_reg, ++ .parse_sizes = cs_dsp_adsp2_parse_sizes, ++ .validate_version = cs_dsp_validate_version, ++ .setup_algs = cs_dsp_adsp2_setup_algs, ++ .region_to_reg = cs_dsp_region_to_reg, + +- .show_fw_status = wm_adsp2_show_fw_status, ++ .show_fw_status = cs_dsp_adsp2_show_fw_status, + +- .enable_memory = wm_adsp2_enable_memory, +- .disable_memory = wm_adsp2_disable_memory, ++ .enable_memory = cs_dsp_adsp2_enable_memory, ++ .disable_memory = cs_dsp_adsp2_disable_memory, + +- .enable_core = wm_adsp2_enable_core, +- .disable_core = wm_adsp2_disable_core, ++ .enable_core = cs_dsp_adsp2_enable_core, ++ .disable_core = cs_dsp_adsp2_disable_core, + +- .start_core = wm_adsp2_start_core, +- .stop_core = wm_adsp2_stop_core, ++ .start_core = cs_dsp_adsp2_start_core, ++ .stop_core = cs_dsp_adsp2_stop_core, + + }, + { + .sys_config_size = sizeof(struct wm_adsp_system_config_xm_hdr), +- .parse_sizes = wm_adsp2_parse_sizes, +- .validate_version = wm_adsp_validate_version, +- .setup_algs = wm_adsp2_setup_algs, +- .region_to_reg = wm_adsp_region_to_reg, ++ .parse_sizes = cs_dsp_adsp2_parse_sizes, ++ .validate_version = cs_dsp_validate_version, ++ .setup_algs = cs_dsp_adsp2_setup_algs, ++ .region_to_reg = cs_dsp_region_to_reg, + +- .show_fw_status = wm_adsp2v2_show_fw_status, ++ .show_fw_status = cs_dsp_adsp2v2_show_fw_status, + +- .enable_memory = wm_adsp2_enable_memory, +- .disable_memory = wm_adsp2_disable_memory, +- .lock_memory = wm_adsp2_lock, ++ .enable_memory = cs_dsp_adsp2_enable_memory, ++ .disable_memory = cs_dsp_adsp2_disable_memory, ++ .lock_memory = cs_dsp_adsp2_lock, + +- .enable_core = wm_adsp2v2_enable_core, +- .disable_core = wm_adsp2v2_disable_core, ++ .enable_core = cs_dsp_adsp2v2_enable_core, ++ .disable_core = cs_dsp_adsp2v2_disable_core, + +- .start_core = wm_adsp2_start_core, +- .stop_core = wm_adsp2_stop_core, ++ .start_core = cs_dsp_adsp2_start_core, ++ .stop_core = cs_dsp_adsp2_stop_core, + }, + { + .sys_config_size = sizeof(struct wm_adsp_system_config_xm_hdr), +- .parse_sizes = wm_adsp2_parse_sizes, +- .validate_version = wm_adsp_validate_version, +- .setup_algs = wm_adsp2_setup_algs, +- .region_to_reg = wm_adsp_region_to_reg, ++ .parse_sizes = cs_dsp_adsp2_parse_sizes, ++ .validate_version = cs_dsp_validate_version, ++ .setup_algs = cs_dsp_adsp2_setup_algs, ++ .region_to_reg = cs_dsp_region_to_reg, + +- .show_fw_status = wm_adsp2v2_show_fw_status, +- .stop_watchdog = wm_adsp_stop_watchdog, ++ .show_fw_status = cs_dsp_adsp2v2_show_fw_status, ++ .stop_watchdog = cs_dsp_stop_watchdog, + +- .enable_memory = wm_adsp2_enable_memory, +- .disable_memory = wm_adsp2_disable_memory, +- .lock_memory = wm_adsp2_lock, ++ .enable_memory = cs_dsp_adsp2_enable_memory, ++ .disable_memory = cs_dsp_adsp2_disable_memory, ++ .lock_memory = cs_dsp_adsp2_lock, + +- .enable_core = wm_adsp2v2_enable_core, +- .disable_core = wm_adsp2v2_disable_core, ++ .enable_core = cs_dsp_adsp2v2_enable_core, ++ .disable_core = cs_dsp_adsp2v2_disable_core, + +- .start_core = wm_adsp2_start_core, +- .stop_core = wm_adsp2_stop_core, ++ .start_core = cs_dsp_adsp2_start_core, ++ .stop_core = cs_dsp_adsp2_stop_core, + }, + }; + +-static const struct wm_adsp_ops wm_halo_ops = { ++static const struct cs_dsp_ops cs_dsp_halo_ops = { + .sys_config_size = sizeof(struct wm_halo_system_config_xm_hdr), +- .parse_sizes = wm_adsp2_parse_sizes, +- .validate_version = wm_halo_validate_version, +- .setup_algs = wm_halo_setup_algs, +- .region_to_reg = wm_halo_region_to_reg, ++ .parse_sizes = cs_dsp_adsp2_parse_sizes, ++ .validate_version = cs_dsp_halo_validate_version, ++ .setup_algs = cs_dsp_halo_setup_algs, ++ .region_to_reg = cs_dsp_halo_region_to_reg, + +- .show_fw_status = wm_halo_show_fw_status, +- .stop_watchdog = wm_halo_stop_watchdog, ++ .show_fw_status = cs_dsp_halo_show_fw_status, ++ .stop_watchdog = cs_dsp_halo_stop_watchdog, + +- .lock_memory = wm_halo_configure_mpu, ++ .lock_memory = cs_dsp_halo_configure_mpu, + +- .start_core = wm_halo_start_core, +- .stop_core = wm_halo_stop_core, ++ .start_core = cs_dsp_halo_start_core, ++ .stop_core = cs_dsp_halo_stop_core, + }; + + MODULE_LICENSE("GPL v2"); +diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h +index f22131d9cc29..114bc41981ef 100644 +--- a/sound/soc/codecs/wm_adsp.h ++++ b/sound/soc/codecs/wm_adsp.h +@@ -20,29 +20,29 @@ + #define WM_ADSP_COMPR_OK 0 + #define WM_ADSP_COMPR_VOICE_TRIGGER 1 + +-#define WM_ADSP2_REGION_0 BIT(0) +-#define WM_ADSP2_REGION_1 BIT(1) +-#define WM_ADSP2_REGION_2 BIT(2) +-#define WM_ADSP2_REGION_3 BIT(3) +-#define WM_ADSP2_REGION_4 BIT(4) +-#define WM_ADSP2_REGION_5 BIT(5) +-#define WM_ADSP2_REGION_6 BIT(6) +-#define WM_ADSP2_REGION_7 BIT(7) +-#define WM_ADSP2_REGION_8 BIT(8) +-#define WM_ADSP2_REGION_9 BIT(9) +-#define WM_ADSP2_REGION_1_9 (WM_ADSP2_REGION_1 | \ +- WM_ADSP2_REGION_2 | WM_ADSP2_REGION_3 | \ +- WM_ADSP2_REGION_4 | WM_ADSP2_REGION_5 | \ +- WM_ADSP2_REGION_6 | WM_ADSP2_REGION_7 | \ +- WM_ADSP2_REGION_8 | WM_ADSP2_REGION_9) +-#define WM_ADSP2_REGION_ALL (WM_ADSP2_REGION_0 | WM_ADSP2_REGION_1_9) +- +-struct wm_adsp_region { ++#define CS_ADSP2_REGION_0 BIT(0) ++#define CS_ADSP2_REGION_1 BIT(1) ++#define CS_ADSP2_REGION_2 BIT(2) ++#define CS_ADSP2_REGION_3 BIT(3) ++#define CS_ADSP2_REGION_4 BIT(4) ++#define CS_ADSP2_REGION_5 BIT(5) ++#define CS_ADSP2_REGION_6 BIT(6) ++#define CS_ADSP2_REGION_7 BIT(7) ++#define CS_ADSP2_REGION_8 BIT(8) ++#define CS_ADSP2_REGION_9 BIT(9) ++#define CS_ADSP2_REGION_1_9 (CS_ADSP2_REGION_1 | \ ++ CS_ADSP2_REGION_2 | CS_ADSP2_REGION_3 | \ ++ CS_ADSP2_REGION_4 | CS_ADSP2_REGION_5 | \ ++ CS_ADSP2_REGION_6 | CS_ADSP2_REGION_7 | \ ++ CS_ADSP2_REGION_8 | CS_ADSP2_REGION_9) ++#define CS_ADSP2_REGION_ALL (CS_ADSP2_REGION_0 | CS_ADSP2_REGION_1_9) ++ ++struct cs_dsp_region { + int type; + unsigned int base; + }; + +-struct wm_adsp_alg_region { ++struct cs_dsp_alg_region { + struct list_head list; + unsigned int alg; + int type; +@@ -51,7 +51,7 @@ struct wm_adsp_alg_region { + + struct wm_adsp_compr; + struct wm_adsp_compr_buf; +-struct wm_adsp_ops; ++struct cs_dsp_ops; + + struct wm_adsp { + const char *part; +@@ -64,7 +64,7 @@ struct wm_adsp { + struct regmap *regmap; + struct snd_soc_component *component; + +- const struct wm_adsp_ops *ops; ++ const struct cs_dsp_ops *ops; + + unsigned int base; + unsigned int base_sysinfo; +@@ -78,7 +78,7 @@ struct wm_adsp { + unsigned int fw_id_version; + unsigned int fw_vendor_id; + +- const struct wm_adsp_region *mem; ++ const struct cs_dsp_region *mem; + int num_mems; + + int fw; +@@ -108,7 +108,7 @@ struct wm_adsp { + + }; + +-struct wm_adsp_ops { ++struct cs_dsp_ops { + unsigned int sys_config_size; + + bool (*validate_version)(struct wm_adsp *dsp, unsigned int version); +@@ -117,7 +117,7 @@ struct wm_adsp_ops { + unsigned int pos, + const struct firmware *firmware); + int (*setup_algs)(struct wm_adsp *dsp); +- unsigned int (*region_to_reg)(struct wm_adsp_region const *mem, ++ unsigned int (*region_to_reg)(struct cs_dsp_region const *mem, + unsigned int offset); + + void (*show_fw_status)(struct wm_adsp *dsp); +-- +2.35.3 + diff --git a/patches.suse/ASoC-wm_adsp-Separate-generic-cs_dsp_coeff_ctl-handl.patch b/patches.suse/ASoC-wm_adsp-Separate-generic-cs_dsp_coeff_ctl-handl.patch new file mode 100644 index 0000000..4626903 --- /dev/null +++ b/patches.suse/ASoC-wm_adsp-Separate-generic-cs_dsp_coeff_ctl-handl.patch @@ -0,0 +1,726 @@ +From 0700bc2fb94c28459f57a10d2ee2c7ef4cb70862 Mon Sep 17 00:00:00 2001 +From: Simon Trimmer +Date: Mon, 13 Sep 2021 17:00:51 +0100 +Subject: [PATCH] ASoC: wm_adsp: Separate generic cs_dsp_coeff_ctl handling +Git-commit: 0700bc2fb94c28459f57a10d2ee2c7ef4cb70862 +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +This is preparation for moving the generic DSP support out of ASoC. The +majority of the handling of firmware controls is generic and this change +separates the generic and ASoC specific details into separate structures +and functions and renames the generic code named wm_* to cs_*. + +Signed-off-by: Simon Trimmer +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20210913160057.103842-11-simont@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/wm_adsp.c | 283 ++++++++++++++++++++----------------- + sound/soc/codecs/wm_adsp.h | 20 +++ + 2 files changed, 176 insertions(+), 127 deletions(-) + +diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c +index 82038cac4286..bd335e4240e5 100644 +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -607,21 +607,8 @@ static const struct { + + struct wm_coeff_ctl { + const char *name; +- const char *fw_name; +- /* Subname is needed to match with firmware */ +- const char *subname; +- unsigned int subname_len; +- struct cs_dsp_alg_region alg_region; +- struct wm_adsp *dsp; +- unsigned int enabled:1; +- struct list_head list; +- void *cache; +- unsigned int offset; +- size_t len; +- unsigned int set:1; ++ struct cs_dsp_coeff_ctl *cs_ctl; + struct soc_bytes_ext bytes_ext; +- unsigned int flags; +- unsigned int type; + struct work_struct work; + }; + +@@ -938,7 +925,7 @@ static inline struct wm_coeff_ctl *bytes_ext_to_ctl(struct soc_bytes_ext *ext) + return container_of(ext, struct wm_coeff_ctl, bytes_ext); + } + +-static int cs_dsp_coeff_base_reg(struct wm_coeff_ctl *ctl, unsigned int *reg) ++static int cs_dsp_coeff_base_reg(struct cs_dsp_coeff_ctl *ctl, unsigned int *reg) + { + const struct cs_dsp_alg_region *alg_region = &ctl->alg_region; + struct wm_adsp *dsp = ctl->dsp; +@@ -962,8 +949,9 @@ static int wm_coeff_info(struct snd_kcontrol *kctl, + struct soc_bytes_ext *bytes_ext = + (struct soc_bytes_ext *)kctl->private_value; + struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); ++ struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl; + +- switch (ctl->type) { ++ switch (cs_ctl->type) { + case WMFW_CTL_TYPE_ACKED: + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->value.integer.min = CS_DSP_ACKED_CTL_MIN_VALUE; +@@ -973,14 +961,14 @@ static int wm_coeff_info(struct snd_kcontrol *kctl, + break; + default: + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; +- uinfo->count = ctl->len; ++ uinfo->count = cs_ctl->len; + break; + } + + return 0; + } + +-static int cs_dsp_coeff_write_acked_control(struct wm_coeff_ctl *ctl, ++static int cs_dsp_coeff_write_acked_control(struct cs_dsp_coeff_ctl *ctl, + unsigned int event_id) + { + struct wm_adsp *dsp = ctl->dsp; +@@ -1040,7 +1028,7 @@ static int cs_dsp_coeff_write_acked_control(struct wm_coeff_ctl *ctl, + return -ETIMEDOUT; + } + +-static int cs_dsp_coeff_write_ctrl_raw(struct wm_coeff_ctl *ctl, ++static int cs_dsp_coeff_write_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, + const void *buf, size_t len) + { + struct wm_adsp *dsp = ctl->dsp; +@@ -1071,7 +1059,7 @@ static int cs_dsp_coeff_write_ctrl_raw(struct wm_coeff_ctl *ctl, + return 0; + } + +-static int cs_dsp_coeff_write_ctrl(struct wm_coeff_ctl *ctl, ++static int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl, + const void *buf, size_t len) + { + int ret = 0; +@@ -1094,12 +1082,13 @@ static int wm_coeff_put(struct snd_kcontrol *kctl, + struct soc_bytes_ext *bytes_ext = + (struct soc_bytes_ext *)kctl->private_value; + struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); ++ struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl; + char *p = ucontrol->value.bytes.data; + int ret = 0; + +- mutex_lock(&ctl->dsp->pwr_lock); +- ret = cs_dsp_coeff_write_ctrl(ctl, p, ctl->len); +- mutex_unlock(&ctl->dsp->pwr_lock); ++ mutex_lock(&cs_ctl->dsp->pwr_lock); ++ ret = cs_dsp_coeff_write_ctrl(cs_ctl, p, cs_ctl->len); ++ mutex_unlock(&cs_ctl->dsp->pwr_lock); + + return ret; + } +@@ -1110,16 +1099,17 @@ static int wm_coeff_tlv_put(struct snd_kcontrol *kctl, + struct soc_bytes_ext *bytes_ext = + (struct soc_bytes_ext *)kctl->private_value; + struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); ++ struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl; + int ret = 0; + +- mutex_lock(&ctl->dsp->pwr_lock); ++ mutex_lock(&cs_ctl->dsp->pwr_lock); + +- if (copy_from_user(ctl->cache, bytes, size)) ++ if (copy_from_user(cs_ctl->cache, bytes, size)) + ret = -EFAULT; + else +- ret = cs_dsp_coeff_write_ctrl(ctl, ctl->cache, size); ++ ret = cs_dsp_coeff_write_ctrl(cs_ctl, cs_ctl->cache, size); + +- mutex_unlock(&ctl->dsp->pwr_lock); ++ mutex_unlock(&cs_ctl->dsp->pwr_lock); + + return ret; + } +@@ -1130,25 +1120,26 @@ static int wm_coeff_put_acked(struct snd_kcontrol *kctl, + struct soc_bytes_ext *bytes_ext = + (struct soc_bytes_ext *)kctl->private_value; + struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); ++ struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl; + unsigned int val = ucontrol->value.integer.value[0]; + int ret; + + if (val == 0) + return 0; /* 0 means no event */ + +- mutex_lock(&ctl->dsp->pwr_lock); ++ mutex_lock(&cs_ctl->dsp->pwr_lock); + +- if (ctl->enabled && ctl->dsp->running) +- ret = cs_dsp_coeff_write_acked_control(ctl, val); ++ if (cs_ctl->enabled && cs_ctl->dsp->running) ++ ret = cs_dsp_coeff_write_acked_control(cs_ctl, val); + else + ret = -EPERM; + +- mutex_unlock(&ctl->dsp->pwr_lock); ++ mutex_unlock(&cs_ctl->dsp->pwr_lock); + + return ret; + } + +-static int cs_dsp_coeff_read_ctrl_raw(struct wm_coeff_ctl *ctl, ++static int cs_dsp_coeff_read_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, + void *buf, size_t len) + { + struct wm_adsp *dsp = ctl->dsp; +@@ -1179,7 +1170,7 @@ static int cs_dsp_coeff_read_ctrl_raw(struct wm_coeff_ctl *ctl, + return 0; + } + +-static int cs_dsp_coeff_read_ctrl(struct wm_coeff_ctl *ctl, void *buf, size_t len) ++static int cs_dsp_coeff_read_ctrl(struct cs_dsp_coeff_ctl *ctl, void *buf, size_t len) + { + int ret = 0; + +@@ -1205,12 +1196,13 @@ static int wm_coeff_get(struct snd_kcontrol *kctl, + struct soc_bytes_ext *bytes_ext = + (struct soc_bytes_ext *)kctl->private_value; + struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); ++ struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl; + char *p = ucontrol->value.bytes.data; + int ret; + +- mutex_lock(&ctl->dsp->pwr_lock); +- ret = cs_dsp_coeff_read_ctrl(ctl, p, ctl->len); +- mutex_unlock(&ctl->dsp->pwr_lock); ++ mutex_lock(&cs_ctl->dsp->pwr_lock); ++ ret = cs_dsp_coeff_read_ctrl(cs_ctl, p, cs_ctl->len); ++ mutex_unlock(&cs_ctl->dsp->pwr_lock); + + return ret; + } +@@ -1221,16 +1213,17 @@ static int wm_coeff_tlv_get(struct snd_kcontrol *kctl, + struct soc_bytes_ext *bytes_ext = + (struct soc_bytes_ext *)kctl->private_value; + struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); ++ struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl; + int ret = 0; + +- mutex_lock(&ctl->dsp->pwr_lock); ++ mutex_lock(&cs_ctl->dsp->pwr_lock); + +- ret = cs_dsp_coeff_read_ctrl(ctl, ctl->cache, size); ++ ret = cs_dsp_coeff_read_ctrl(cs_ctl, cs_ctl->cache, size); + +- if (!ret && copy_to_user(bytes, ctl->cache, size)) ++ if (!ret && copy_to_user(bytes, cs_ctl->cache, size)) + ret = -EFAULT; + +- mutex_unlock(&ctl->dsp->pwr_lock); ++ mutex_unlock(&cs_ctl->dsp->pwr_lock); + + return ret; + } +@@ -1283,12 +1276,10 @@ static unsigned int wmfw_convert_flags(unsigned int in, unsigned int len) + + static int wmfw_add_ctl(struct wm_adsp *dsp, struct wm_coeff_ctl *ctl) + { ++ struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl; + struct snd_kcontrol_new *kcontrol; + int ret; + +- if (!ctl || !ctl->name) +- return -EINVAL; +- + kcontrol = kzalloc(sizeof(*kcontrol), GFP_KERNEL); + if (!kcontrol) + return -ENOMEM; +@@ -1298,16 +1289,16 @@ static int wmfw_add_ctl(struct wm_adsp *dsp, struct wm_coeff_ctl *ctl) + kcontrol->iface = SNDRV_CTL_ELEM_IFACE_MIXER; + kcontrol->tlv.c = snd_soc_bytes_tlv_callback; + kcontrol->private_value = (unsigned long)&ctl->bytes_ext; +- kcontrol->access = wmfw_convert_flags(ctl->flags, ctl->len); ++ kcontrol->access = wmfw_convert_flags(cs_ctl->flags, cs_ctl->len); + +- switch (ctl->type) { ++ switch (cs_ctl->type) { + case WMFW_CTL_TYPE_ACKED: + kcontrol->get = wm_coeff_get_acked; + kcontrol->put = wm_coeff_put_acked; + break; + default: + if (kcontrol->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) { +- ctl->bytes_ext.max = ctl->len; ++ ctl->bytes_ext.max = cs_ctl->len; + ctl->bytes_ext.get = wm_coeff_tlv_get; + ctl->bytes_ext.put = wm_coeff_tlv_put; + } else { +@@ -1332,7 +1323,7 @@ static int wmfw_add_ctl(struct wm_adsp *dsp, struct wm_coeff_ctl *ctl) + + static int cs_dsp_coeff_init_control_caches(struct wm_adsp *dsp) + { +- struct wm_coeff_ctl *ctl; ++ struct cs_dsp_coeff_ctl *ctl; + int ret; + + list_for_each_entry(ctl, &dsp->ctl_list, list) { +@@ -1358,7 +1349,7 @@ static int cs_dsp_coeff_init_control_caches(struct wm_adsp *dsp) + + static int cs_dsp_coeff_sync_controls(struct wm_adsp *dsp) + { +- struct wm_coeff_ctl *ctl; ++ struct cs_dsp_coeff_ctl *ctl; + int ret; + + list_for_each_entry(ctl, &dsp->ctl_list, list) { +@@ -1378,7 +1369,7 @@ static int cs_dsp_coeff_sync_controls(struct wm_adsp *dsp) + static void cs_dsp_signal_event_controls(struct wm_adsp *dsp, + unsigned int event) + { +- struct wm_coeff_ctl *ctl; ++ struct cs_dsp_coeff_ctl *ctl; + int ret; + + list_for_each_entry(ctl, &dsp->ctl_list, list) { +@@ -1401,47 +1392,30 @@ static void wm_adsp_ctl_work(struct work_struct *work) + struct wm_coeff_ctl *ctl = container_of(work, + struct wm_coeff_ctl, + work); +- +- wmfw_add_ctl(ctl->dsp, ctl); ++ wmfw_add_ctl(ctl->cs_ctl->dsp, ctl); + } + +-static void cs_dsp_free_ctl_blk(struct wm_coeff_ctl *ctl) ++static void cs_dsp_free_ctl_blk(struct cs_dsp_coeff_ctl *ctl) + { +- cancel_work_sync(&ctl->work); +- + kfree(ctl->cache); +- kfree(ctl->name); + kfree(ctl->subname); + kfree(ctl); + } + +-static int cs_dsp_create_control(struct wm_adsp *dsp, +- const struct cs_dsp_alg_region *alg_region, +- unsigned int offset, unsigned int len, +- const char *subname, unsigned int subname_len, +- unsigned int flags, unsigned int type) ++static int wm_adsp_control_add(struct cs_dsp_coeff_ctl *cs_ctl) + { ++ struct wm_adsp *dsp = cs_ctl->dsp; + struct wm_coeff_ctl *ctl; + char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; + const char *region_name; + int ret; + +- list_for_each_entry(ctl, &dsp->ctl_list, list) { +- if (ctl->fw_name == wm_adsp_fw_text[dsp->fw] && +- ctl->alg_region.alg == alg_region->alg && +- ctl->alg_region.type == alg_region->type) { +- if ((!subname && !ctl->subname) || +- (subname && !strncmp(ctl->subname, subname, ctl->subname_len))) { +- if (!ctl->enabled) +- ctl->enabled = 1; +- return 0; +- } +- } +- } ++ if (cs_ctl->flags & WMFW_CTL_FLAG_SYS) ++ return 0; + +- region_name = cs_dsp_mem_region_name(alg_region->type); ++ region_name = cs_dsp_mem_region_name(cs_ctl->alg_region.type); + if (!region_name) { +- cs_dsp_err(dsp, "Unknown region type: %d\n", alg_region->type); ++ adsp_err(dsp, "Unknown region type: %d\n", cs_ctl->alg_region.type); + return -EINVAL; + } + +@@ -1449,22 +1423,21 @@ static int cs_dsp_create_control(struct wm_adsp *dsp, + case 0: + case 1: + snprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s %s %x", +- dsp->name, region_name, alg_region->alg); +- subname = NULL; /* don't append subname */ ++ dsp->name, region_name, cs_ctl->alg_region.alg); + break; + case 2: + ret = scnprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, + "%s%c %.12s %x", dsp->name, *region_name, +- wm_adsp_fw_text[dsp->fw], alg_region->alg); ++ wm_adsp_fw_text[dsp->fw], cs_ctl->alg_region.alg); + break; + default: + ret = scnprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, + "%s %.12s %x", dsp->name, +- wm_adsp_fw_text[dsp->fw], alg_region->alg); ++ wm_adsp_fw_text[dsp->fw], cs_ctl->alg_region.alg); + break; + } + +- if (subname) { ++ if (cs_ctl->subname) { + int avail = SNDRV_CTL_ELEM_ID_NAME_MAXLEN - ret - 2; + int skip = 0; + +@@ -1472,30 +1445,81 @@ static int cs_dsp_create_control(struct wm_adsp *dsp, + avail -= strlen(dsp->component->name_prefix) + 1; + + /* Truncate the subname from the start if it is too long */ +- if (subname_len > avail) +- skip = subname_len - avail; ++ if (cs_ctl->subname_len > avail) ++ skip = cs_ctl->subname_len - avail; + + snprintf(name + ret, SNDRV_CTL_ELEM_ID_NAME_MAXLEN - ret, +- " %.*s", subname_len - skip, subname + skip); ++ " %.*s", cs_ctl->subname_len - skip, cs_ctl->subname + skip); + } + + ctl = kzalloc(sizeof(*ctl), GFP_KERNEL); + if (!ctl) + return -ENOMEM; +- ctl->fw_name = wm_adsp_fw_text[dsp->fw]; +- ctl->alg_region = *alg_region; ++ ctl->cs_ctl = cs_ctl; ++ + ctl->name = kmemdup(name, strlen(name) + 1, GFP_KERNEL); + if (!ctl->name) { + ret = -ENOMEM; + goto err_ctl; + } +- if (subname) { ++ ++ cs_ctl->priv = ctl; ++ ++ INIT_WORK(&ctl->work, wm_adsp_ctl_work); ++ schedule_work(&ctl->work); ++ ++ return 0; ++ ++err_ctl: ++ kfree(ctl); ++ ++ return ret; ++} ++ ++static void wm_adsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl) ++{ ++ struct wm_coeff_ctl *ctl = cs_ctl->priv; ++ ++ cancel_work_sync(&ctl->work); ++ ++ kfree(ctl->name); ++ kfree(ctl); ++} ++ ++static int cs_dsp_create_control(struct wm_adsp *dsp, ++ const struct cs_dsp_alg_region *alg_region, ++ unsigned int offset, unsigned int len, ++ const char *subname, unsigned int subname_len, ++ unsigned int flags, unsigned int type) ++{ ++ struct cs_dsp_coeff_ctl *ctl; ++ int ret; ++ ++ list_for_each_entry(ctl, &dsp->ctl_list, list) { ++ if (ctl->fw_name == wm_adsp_fw_text[dsp->fw] && ++ ctl->alg_region.alg == alg_region->alg && ++ ctl->alg_region.type == alg_region->type) { ++ if ((!subname && !ctl->subname) || ++ (subname && !strncmp(ctl->subname, subname, ctl->subname_len))) { ++ if (!ctl->enabled) ++ ctl->enabled = 1; ++ return 0; ++ } ++ } ++ } ++ ++ ctl = kzalloc(sizeof(*ctl), GFP_KERNEL); ++ if (!ctl) ++ return -ENOMEM; ++ ctl->fw_name = wm_adsp_fw_text[dsp->fw]; ++ ctl->alg_region = *alg_region; ++ if (subname && dsp->fw_ver >= 2) { + ctl->subname_len = subname_len; + ctl->subname = kmemdup(subname, + strlen(subname) + 1, GFP_KERNEL); + if (!ctl->subname) { + ret = -ENOMEM; +- goto err_ctl_name; ++ goto err_ctl; + } + } + ctl->enabled = 1; +@@ -1514,18 +1538,17 @@ static int cs_dsp_create_control(struct wm_adsp *dsp, + + list_add(&ctl->list, &dsp->ctl_list); + +- if (flags & WMFW_CTL_FLAG_SYS) +- return 0; +- +- INIT_WORK(&ctl->work, wm_adsp_ctl_work); +- schedule_work(&ctl->work); ++ ret = wm_adsp_control_add(ctl); ++ if (ret) ++ goto err_list_del; + + return 0; + ++err_list_del: ++ list_del(&ctl->list); ++ kfree(ctl->cache); + err_ctl_subname: + kfree(ctl->subname); +-err_ctl_name: +- kfree(ctl->name); + err_ctl: + kfree(ctl); + +@@ -2013,14 +2036,14 @@ static int cs_dsp_load(struct wm_adsp *dsp) + } + + /* +- * Find wm_coeff_ctl with input name as its subname ++ * Find cs_dsp_coeff_ctl with input name as its subname + * If not found, return NULL + */ +-static struct wm_coeff_ctl *cs_dsp_get_ctl(struct wm_adsp *dsp, +- const char *name, int type, +- unsigned int alg) ++static struct cs_dsp_coeff_ctl *cs_dsp_get_ctl(struct wm_adsp *dsp, ++ const char *name, int type, ++ unsigned int alg) + { +- struct wm_coeff_ctl *pos, *rslt = NULL; ++ struct cs_dsp_coeff_ctl *pos, *rslt = NULL; + const char *fw_txt = wm_adsp_fw_text[dsp->fw]; + + list_for_each_entry(pos, &dsp->ctl_list, list) { +@@ -2041,23 +2064,26 @@ static struct wm_coeff_ctl *cs_dsp_get_ctl(struct wm_adsp *dsp, + int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type, + unsigned int alg, void *buf, size_t len) + { ++ struct cs_dsp_coeff_ctl *cs_ctl; + struct wm_coeff_ctl *ctl; + struct snd_kcontrol *kcontrol; + char ctl_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; + int ret; + +- ctl = cs_dsp_get_ctl(dsp, name, type, alg); +- if (!ctl) ++ cs_ctl = cs_dsp_get_ctl(dsp, name, type, alg); ++ if (!cs_ctl) + return -EINVAL; + +- if (len > ctl->len) ++ ctl = cs_ctl->priv; ++ ++ if (len > cs_ctl->len) + return -EINVAL; + +- ret = cs_dsp_coeff_write_ctrl(ctl, buf, len); ++ ret = cs_dsp_coeff_write_ctrl(cs_ctl, buf, len); + if (ret) + return ret; + +- if (ctl->flags & WMFW_CTL_FLAG_SYS) ++ if (cs_ctl->flags & WMFW_CTL_FLAG_SYS) + return 0; + + if (dsp->component->name_prefix) +@@ -2083,23 +2109,23 @@ EXPORT_SYMBOL_GPL(wm_adsp_write_ctl); + int wm_adsp_read_ctl(struct wm_adsp *dsp, const char *name, int type, + unsigned int alg, void *buf, size_t len) + { +- struct wm_coeff_ctl *ctl; ++ struct cs_dsp_coeff_ctl *cs_ctl; + +- ctl = cs_dsp_get_ctl(dsp, name, type, alg); +- if (!ctl) ++ cs_ctl = cs_dsp_get_ctl(dsp, name, type, alg); ++ if (!cs_ctl) + return -EINVAL; + +- if (len > ctl->len) ++ if (len > cs_ctl->len) + return -EINVAL; + +- return cs_dsp_coeff_read_ctrl(ctl, buf, len); ++ return cs_dsp_coeff_read_ctrl(cs_ctl, buf, len); + } + EXPORT_SYMBOL_GPL(wm_adsp_read_ctl); + + static void cs_dsp_ctl_fixup_base(struct wm_adsp *dsp, + const struct cs_dsp_alg_region *alg_region) + { +- struct wm_coeff_ctl *ctl; ++ struct cs_dsp_coeff_ctl *ctl; + + list_for_each_entry(ctl, &dsp->ctl_list, list) { + if (ctl->fw_name == wm_adsp_fw_text[dsp->fw] && +@@ -2885,7 +2911,7 @@ static int cs_dsp_adsp1_power_up(struct wm_adsp *dsp) + + static void cs_dsp_adsp1_power_down(struct wm_adsp *dsp) + { +- struct wm_coeff_ctl *ctl; ++ struct cs_dsp_coeff_ctl *ctl; + + mutex_lock(&dsp->pwr_lock); + +@@ -3199,7 +3225,7 @@ static void cs_dsp_power_up(struct wm_adsp *dsp) + + static void cs_dsp_power_down(struct wm_adsp *dsp) + { +- struct wm_coeff_ctl *ctl; ++ struct cs_dsp_coeff_ctl *ctl; + + mutex_lock(&dsp->pwr_lock); + +@@ -3496,11 +3522,13 @@ EXPORT_SYMBOL_GPL(wm_halo_init); + + static void cs_dsp_remove(struct wm_adsp *dsp) + { +- struct wm_coeff_ctl *ctl; ++ struct cs_dsp_coeff_ctl *ctl; + + while (!list_empty(&dsp->ctl_list)) { +- ctl = list_first_entry(&dsp->ctl_list, struct wm_coeff_ctl, +- list); ++ ctl = list_first_entry(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); ++ ++ wm_adsp_control_remove(ctl); ++ + list_del(&ctl->list); + cs_dsp_free_ctl_blk(ctl); + } +@@ -3936,15 +3964,16 @@ static int wm_adsp_buffer_parse_legacy(struct wm_adsp *dsp) + return 0; + } + +-static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) ++static int wm_adsp_buffer_parse_coeff(struct cs_dsp_coeff_ctl *cs_ctl) + { + struct wm_adsp_host_buf_coeff_v1 coeff_v1; + struct wm_adsp_compr_buf *buf; ++ struct wm_adsp *dsp = cs_ctl->dsp; + unsigned int version; + int ret, i; + + for (i = 0; i < 5; ++i) { +- ret = cs_dsp_coeff_read_ctrl(ctl, &coeff_v1, sizeof(coeff_v1)); ++ ret = cs_dsp_coeff_read_ctrl(cs_ctl, &coeff_v1, sizeof(coeff_v1)); + if (ret < 0) + return ret; + +@@ -3955,15 +3984,15 @@ static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) + } + + if (!coeff_v1.host_buf_ptr) { +- adsp_err(ctl->dsp, "Failed to acquire host buffer\n"); ++ adsp_err(dsp, "Failed to acquire host buffer\n"); + return -EIO; + } + +- buf = wm_adsp_buffer_alloc(ctl->dsp); ++ buf = wm_adsp_buffer_alloc(dsp); + if (!buf) + return -ENOMEM; + +- buf->host_buf_mem_type = ctl->alg_region.type; ++ buf->host_buf_mem_type = cs_ctl->alg_region.type; + buf->host_buf_ptr = be32_to_cpu(coeff_v1.host_buf_ptr); + + ret = wm_adsp_buffer_populate(buf); +@@ -3974,7 +4003,7 @@ static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) + * v0 host_buffer coefficients didn't have versioning, so if the + * control is one word, assume version 0. + */ +- if (ctl->len == 4) { ++ if (cs_ctl->len == 4) { + compr_dbg(buf, "host_buf_ptr=%x\n", buf->host_buf_ptr); + return 0; + } +@@ -3983,7 +4012,7 @@ static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) + version >>= HOST_BUF_COEFF_COMPAT_VER_SHIFT; + + if (version > HOST_BUF_COEFF_SUPPORTED_COMPAT_VER) { +- adsp_err(ctl->dsp, ++ adsp_err(dsp, + "Host buffer coeff ver %u > supported version %u\n", + version, HOST_BUF_COEFF_SUPPORTED_COMPAT_VER); + return -EINVAL; +@@ -3991,7 +4020,7 @@ static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) + + cs_dsp_remove_padding((u32 *)&coeff_v1.name, ARRAY_SIZE(coeff_v1.name)); + +- buf->name = kasprintf(GFP_KERNEL, "%s-dsp-%s", ctl->dsp->part, ++ buf->name = kasprintf(GFP_KERNEL, "%s-dsp-%s", dsp->part, + (char *)&coeff_v1.name); + + compr_dbg(buf, "host_buf_ptr=%x coeff version %u\n", +@@ -4002,17 +4031,17 @@ static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) + + static int wm_adsp_buffer_init(struct wm_adsp *dsp) + { +- struct wm_coeff_ctl *ctl; ++ struct cs_dsp_coeff_ctl *cs_ctl; + int ret; + +- list_for_each_entry(ctl, &dsp->ctl_list, list) { +- if (ctl->type != WMFW_CTL_TYPE_HOST_BUFFER) ++ list_for_each_entry(cs_ctl, &dsp->ctl_list, list) { ++ if (cs_ctl->type != WMFW_CTL_TYPE_HOST_BUFFER) + continue; + +- if (!ctl->enabled) ++ if (!cs_ctl->enabled) + continue; + +- ret = wm_adsp_buffer_parse_coeff(ctl); ++ ret = wm_adsp_buffer_parse_coeff(cs_ctl); + if (ret < 0) { + adsp_err(dsp, "Failed to parse coeff: %d\n", ret); + goto error; +diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h +index 98b12b485916..eee298e94946 100644 +--- a/sound/soc/codecs/wm_adsp.h ++++ b/sound/soc/codecs/wm_adsp.h +@@ -49,10 +49,30 @@ struct cs_dsp_alg_region { + unsigned int base; + }; + ++struct wm_adsp; + struct wm_adsp_compr; + struct wm_adsp_compr_buf; + struct cs_dsp_ops; + ++struct cs_dsp_coeff_ctl { ++ const char *fw_name; ++ /* Subname is needed to match with firmware */ ++ const char *subname; ++ unsigned int subname_len; ++ struct cs_dsp_alg_region alg_region; ++ struct wm_adsp *dsp; ++ unsigned int enabled:1; ++ struct list_head list; ++ void *cache; ++ unsigned int offset; ++ size_t len; ++ unsigned int set:1; ++ unsigned int flags; ++ unsigned int type; ++ ++ void *priv; ++}; ++ + struct wm_adsp { + const char *part; + const char *name; +-- +2.35.3 + diff --git a/patches.suse/ASoC-wm_adsp-Separate-some-ASoC-and-generic-function.patch b/patches.suse/ASoC-wm_adsp-Separate-some-ASoC-and-generic-function.patch new file mode 100644 index 0000000..fc10b03 --- /dev/null +++ b/patches.suse/ASoC-wm_adsp-Separate-some-ASoC-and-generic-function.patch @@ -0,0 +1,250 @@ +From 25ca837ba6f4dd8f969b41aa202a62facdd2370c Mon Sep 17 00:00:00 2001 +From: Simon Trimmer +Date: Mon, 13 Sep 2021 17:00:48 +0100 +Subject: [PATCH] ASoC: wm_adsp: Separate some ASoC and generic functions +Git-commit: 25ca837ba6f4dd8f969b41aa202a62facdd2370c +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +Split some functions into ASoC and generic portions so that existing +interfaces can be retained whilst allowing the implementation to be +moved out of ASoC. + +Signed-off-by: Simon Trimmer +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20210913160057.103842-8-simont@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/wm_adsp.c | 105 ++++++++++++++++++++++++++----------- + 1 file changed, 74 insertions(+), 31 deletions(-) + +diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c +index cfa8f1476c00..c0ca46e04418 100644 +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -2771,7 +2771,7 @@ static int cs_dsp_create_name(struct wm_adsp *dsp) + return 0; + } + +-static int wm_adsp_common_init(struct wm_adsp *dsp) ++static int cs_dsp_common_init(struct wm_adsp *dsp) + { + int ret; + +@@ -2781,19 +2781,30 @@ static int wm_adsp_common_init(struct wm_adsp *dsp) + + INIT_LIST_HEAD(&dsp->alg_regions); + INIT_LIST_HEAD(&dsp->ctl_list); +- INIT_LIST_HEAD(&dsp->compr_list); +- INIT_LIST_HEAD(&dsp->buffer_list); + + mutex_init(&dsp->pwr_lock); + + return 0; + } + +-int wm_adsp1_init(struct wm_adsp *dsp) ++static void wm_adsp_common_init(struct wm_adsp *dsp) ++{ ++ INIT_LIST_HEAD(&dsp->compr_list); ++ INIT_LIST_HEAD(&dsp->buffer_list); ++} ++ ++static int cs_dsp_adsp1_init(struct wm_adsp *dsp) + { + dsp->ops = &cs_dsp_adsp1_ops; + +- return wm_adsp_common_init(dsp); ++ return cs_dsp_common_init(dsp); ++} ++ ++int wm_adsp1_init(struct wm_adsp *dsp) ++{ ++ wm_adsp_common_init(dsp); ++ ++ return cs_dsp_adsp1_init(dsp); + } + EXPORT_SYMBOL_GPL(wm_adsp1_init); + +@@ -3096,11 +3107,8 @@ static int cs_dsp_halo_configure_mpu(struct wm_adsp *dsp, unsigned int lock_regi + return regmap_multi_reg_write(dsp->regmap, config, ARRAY_SIZE(config)); + } + +-int wm_adsp2_set_dspclk(struct snd_soc_dapm_widget *w, unsigned int freq) ++static int cs_dsp_set_dspclk(struct wm_adsp *dsp, unsigned int freq) + { +- struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); +- struct wm_adsp *dsps = snd_soc_component_get_drvdata(component); +- struct wm_adsp *dsp = &dsps[w->shift]; + int ret; + + ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CLOCKING, +@@ -3111,6 +3119,15 @@ int wm_adsp2_set_dspclk(struct snd_soc_dapm_widget *w, unsigned int freq) + + return ret; + } ++ ++int wm_adsp2_set_dspclk(struct snd_soc_dapm_widget *w, unsigned int freq) ++{ ++ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); ++ struct wm_adsp *dsps = snd_soc_component_get_drvdata(component); ++ struct wm_adsp *dsp = &dsps[w->shift]; ++ ++ return cs_dsp_set_dspclk(dsp, freq); ++} + EXPORT_SYMBOL_GPL(wm_adsp2_set_dspclk); + + int wm_adsp2_preloader_get(struct snd_kcontrol *kcontrol, +@@ -3364,14 +3381,10 @@ int wm_adsp2_component_remove(struct wm_adsp *dsp, struct snd_soc_component *com + } + EXPORT_SYMBOL_GPL(wm_adsp2_component_remove); + +-int wm_adsp2_init(struct wm_adsp *dsp) ++static int cs_dsp_adsp2_init(struct wm_adsp *dsp) + { + int ret; + +- ret = wm_adsp_common_init(dsp); +- if (ret) +- return ret; +- + switch (dsp->rev) { + case 0: + /* +@@ -3396,29 +3409,37 @@ int wm_adsp2_init(struct wm_adsp *dsp) + break; + } + ++ return cs_dsp_common_init(dsp); ++} ++ ++int wm_adsp2_init(struct wm_adsp *dsp) ++{ + INIT_WORK(&dsp->boot_work, wm_adsp_boot_work); + +- return 0; ++ wm_adsp_common_init(dsp); ++ ++ return cs_dsp_adsp2_init(dsp); + } + EXPORT_SYMBOL_GPL(wm_adsp2_init); + +-int wm_halo_init(struct wm_adsp *dsp) ++static int cs_dsp_halo_init(struct wm_adsp *dsp) + { +- int ret; +- +- ret = wm_adsp_common_init(dsp); +- if (ret) +- return ret; +- + dsp->ops = &cs_dsp_halo_ops; + ++ return cs_dsp_common_init(dsp); ++} ++ ++int wm_halo_init(struct wm_adsp *dsp) ++{ + INIT_WORK(&dsp->boot_work, wm_adsp_boot_work); + +- return 0; ++ wm_adsp_common_init(dsp); ++ ++ return cs_dsp_halo_init(dsp); + } + EXPORT_SYMBOL_GPL(wm_halo_init); + +-void wm_adsp2_remove(struct wm_adsp *dsp) ++static void cs_dsp_remove(struct wm_adsp *dsp) + { + struct wm_coeff_ctl *ctl; + +@@ -3429,6 +3450,11 @@ void wm_adsp2_remove(struct wm_adsp *dsp) + cs_dsp_free_ctl_blk(ctl); + } + } ++ ++void wm_adsp2_remove(struct wm_adsp *dsp) ++{ ++ cs_dsp_remove(dsp); ++} + EXPORT_SYMBOL_GPL(wm_adsp2_remove); + + static inline int wm_adsp_compr_attached(struct wm_adsp_compr *compr) +@@ -4346,9 +4372,8 @@ static void wm_adsp_fatal_error(struct wm_adsp *dsp) + } + } + +-irqreturn_t wm_adsp2_bus_error(int irq, void *data) ++static void cs_dsp_adsp2_bus_error(struct wm_adsp *dsp) + { +- struct wm_adsp *dsp = (struct wm_adsp *)data; + unsigned int val; + struct regmap *regmap = dsp->regmap; + int ret = 0; +@@ -4407,14 +4432,20 @@ irqreturn_t wm_adsp2_bus_error(int irq, void *data) + + error: + mutex_unlock(&dsp->pwr_lock); ++} ++ ++irqreturn_t wm_adsp2_bus_error(int irq, void *data) ++{ ++ struct wm_adsp *dsp = (struct wm_adsp *)data; ++ ++ cs_dsp_adsp2_bus_error(dsp); + + return IRQ_HANDLED; + } + EXPORT_SYMBOL_GPL(wm_adsp2_bus_error); + +-irqreturn_t wm_halo_bus_error(int irq, void *data) ++static void cs_dsp_halo_bus_error(struct wm_adsp *dsp) + { +- struct wm_adsp *dsp = (struct wm_adsp *)data; + struct regmap *regmap = dsp->regmap; + unsigned int fault[6]; + struct reg_sequence clear[] = { +@@ -4464,15 +4495,20 @@ irqreturn_t wm_halo_bus_error(int irq, void *data) + + exit_unlock: + mutex_unlock(&dsp->pwr_lock); ++} ++ ++irqreturn_t wm_halo_bus_error(int irq, void *data) ++{ ++ struct wm_adsp *dsp = (struct wm_adsp *)data; ++ ++ cs_dsp_halo_bus_error(dsp); + + return IRQ_HANDLED; + } + EXPORT_SYMBOL_GPL(wm_halo_bus_error); + +-irqreturn_t wm_halo_wdt_expire(int irq, void *data) ++static void cs_dsp_halo_wdt_expire(struct wm_adsp *dsp) + { +- struct wm_adsp *dsp = data; +- + mutex_lock(&dsp->pwr_lock); + + cs_dsp_warn(dsp, "WDT Expiry Fault\n"); +@@ -4481,6 +4517,13 @@ irqreturn_t wm_halo_wdt_expire(int irq, void *data) + wm_adsp_fatal_error(dsp); + + mutex_unlock(&dsp->pwr_lock); ++} ++ ++irqreturn_t wm_halo_wdt_expire(int irq, void *data) ++{ ++ struct wm_adsp *dsp = data; ++ ++ cs_dsp_halo_wdt_expire(dsp); + + return IRQ_HANDLED; + } +-- +2.35.3 + diff --git a/patches.suse/ASoC-wm_adsp-Separate-wm_adsp-specifics-in-cs_dsp_cl.patch b/patches.suse/ASoC-wm_adsp-Separate-wm_adsp-specifics-in-cs_dsp_cl.patch new file mode 100644 index 0000000..f046c07 --- /dev/null +++ b/patches.suse/ASoC-wm_adsp-Separate-wm_adsp-specifics-in-cs_dsp_cl.patch @@ -0,0 +1,192 @@ +From 2dd044641ec3672433b9fe3ec47b236621757aa8 Mon Sep 17 00:00:00 2001 +From: Simon Trimmer +Date: Mon, 13 Sep 2021 17:00:56 +0100 +Subject: [PATCH] ASoC: wm_adsp: Separate wm_adsp specifics in cs_dsp_client_ops +Git-commit: 2dd044641ec3672433b9fe3ec47b236621757aa8 +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +This is preparation for moving the generic DSP support out of ASoC. +The event callbacks let the client add custom handling of events. + +Signed-off-by: Simon Trimmer +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20210913160057.103842-16-simont@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/wm_adsp.c | 48 ++++++++++++++++++++++++++++++-------- + sound/soc/codecs/wm_adsp.h | 10 ++++++++ + 2 files changed, 48 insertions(+), 10 deletions(-) + +diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c +index 092df446ff2f..6c5d55b3b311 100644 +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -318,6 +318,9 @@ static const struct cs_dsp_ops cs_dsp_adsp1_ops; + static const struct cs_dsp_ops cs_dsp_adsp2_ops[]; + static const struct cs_dsp_ops cs_dsp_halo_ops; + ++static const struct cs_dsp_client_ops wm_adsp1_client_ops; ++static const struct cs_dsp_client_ops wm_adsp2_client_ops; ++ + struct cs_dsp_buf { + struct list_head list; + void *buf; +@@ -1548,9 +1551,11 @@ static int cs_dsp_create_control(struct cs_dsp *dsp, + + list_add(&ctl->list, &dsp->ctl_list); + +- ret = wm_adsp_control_add(ctl); +- if (ret) +- goto err_list_del; ++ if (dsp->client_ops->control_add) { ++ ret = dsp->client_ops->control_add(ctl); ++ if (ret) ++ goto err_list_del; ++ } + + return 0; + +@@ -2865,6 +2870,8 @@ int wm_adsp1_init(struct wm_adsp *dsp) + { + int ret; + ++ dsp->cs_dsp.client_ops = &wm_adsp1_client_ops; ++ + ret = cs_dsp_adsp1_init(&dsp->cs_dsp); + if (ret) + return ret; +@@ -3436,9 +3443,11 @@ static int cs_dsp_run(struct cs_dsp *dsp) + + dsp->running = true; + +- ret = wm_adsp_event_post_run(dsp); +- if (ret < 0) +- goto err; ++ if (dsp->client_ops->post_run) { ++ ret = dsp->client_ops->post_run(dsp); ++ if (ret) ++ goto err; ++ } + + mutex_unlock(&dsp->pwr_lock); + +@@ -3475,7 +3484,8 @@ static void cs_dsp_stop(struct cs_dsp *dsp) + if (dsp->ops->disable_core) + dsp->ops->disable_core(dsp); + +- wm_adsp_event_post_stop(dsp); ++ if (dsp->client_ops->post_stop) ++ dsp->client_ops->post_stop(dsp); + + mutex_unlock(&dsp->pwr_lock); + +@@ -3585,6 +3595,7 @@ int wm_adsp2_init(struct wm_adsp *dsp) + INIT_WORK(&dsp->boot_work, wm_adsp_boot_work); + + dsp->sys_config_size = sizeof(struct wm_adsp_system_config_xm_hdr); ++ dsp->cs_dsp.client_ops = &wm_adsp2_client_ops; + + ret = cs_dsp_adsp2_init(&dsp->cs_dsp); + if (ret) +@@ -3608,6 +3619,7 @@ int wm_halo_init(struct wm_adsp *dsp) + INIT_WORK(&dsp->boot_work, wm_adsp_boot_work); + + dsp->sys_config_size = sizeof(struct wm_halo_system_config_xm_hdr); ++ dsp->cs_dsp.client_ops = &wm_adsp2_client_ops; + + ret = cs_dsp_halo_init(&dsp->cs_dsp); + if (ret) +@@ -3624,7 +3636,8 @@ static void cs_dsp_remove(struct cs_dsp *dsp) + while (!list_empty(&dsp->ctl_list)) { + ctl = list_first_entry(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); + +- wm_adsp_control_remove(ctl); ++ if (dsp->client_ops->control_remove) ++ dsp->client_ops->control_remove(ctl); + + list_del(&ctl->list); + cs_dsp_free_ctl_blk(ctl); +@@ -4573,7 +4586,8 @@ static void cs_dsp_adsp2_bus_error(struct cs_dsp *dsp) + if (val & ADSP2_WDT_TIMEOUT_STS_MASK) { + cs_dsp_err(dsp, "watchdog timeout error\n"); + dsp->ops->stop_watchdog(dsp); +- wm_adsp_fatal_error(dsp); ++ if (dsp->client_ops->watchdog_expired) ++ dsp->client_ops->watchdog_expired(dsp); + } + + if (val & (ADSP2_ADDR_ERR_MASK | ADSP2_REGION_LOCK_ERR_MASK)) { +@@ -4697,7 +4711,8 @@ static void cs_dsp_halo_wdt_expire(struct cs_dsp *dsp) + cs_dsp_warn(dsp, "WDT Expiry Fault\n"); + + dsp->ops->stop_watchdog(dsp); +- wm_adsp_fatal_error(dsp); ++ if (dsp->client_ops->watchdog_expired) ++ dsp->client_ops->watchdog_expired(dsp); + + mutex_unlock(&dsp->pwr_lock); + } +@@ -4718,6 +4733,11 @@ static const struct cs_dsp_ops cs_dsp_adsp1_ops = { + .region_to_reg = cs_dsp_region_to_reg, + }; + ++static const struct cs_dsp_client_ops wm_adsp1_client_ops = { ++ .control_add = wm_adsp_control_add, ++ .control_remove = wm_adsp_control_remove, ++}; ++ + static const struct cs_dsp_ops cs_dsp_adsp2_ops[] = { + { + .parse_sizes = cs_dsp_adsp2_parse_sizes, +@@ -4791,4 +4811,12 @@ static const struct cs_dsp_ops cs_dsp_halo_ops = { + .stop_core = cs_dsp_halo_stop_core, + }; + ++static const struct cs_dsp_client_ops wm_adsp2_client_ops = { ++ .control_add = wm_adsp_control_add, ++ .control_remove = wm_adsp_control_remove, ++ .post_run = wm_adsp_event_post_run, ++ .post_stop = wm_adsp_event_post_stop, ++ .watchdog_expired = wm_adsp_fatal_error, ++}; ++ + MODULE_LICENSE("GPL v2"); +diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h +index 5a70b6679fa3..25aaef74654c 100644 +--- a/sound/soc/codecs/wm_adsp.h ++++ b/sound/soc/codecs/wm_adsp.h +@@ -52,6 +52,7 @@ struct cs_dsp_alg_region { + struct wm_adsp_compr; + struct wm_adsp_compr_buf; + struct cs_dsp_ops; ++struct cs_dsp_client_ops; + + struct cs_dsp_coeff_ctl { + const char *fw_name; +@@ -81,6 +82,7 @@ struct cs_dsp { + struct regmap *regmap; + + const struct cs_dsp_ops *ops; ++ const struct cs_dsp_client_ops *client_ops; + + unsigned int base; + unsigned int base_sysinfo; +@@ -237,4 +239,12 @@ int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type, + int wm_adsp_read_ctl(struct wm_adsp *dsp, const char *name, int type, + unsigned int alg, void *buf, size_t len); + ++struct cs_dsp_client_ops { ++ int (*control_add)(struct cs_dsp_coeff_ctl *ctl); ++ void (*control_remove)(struct cs_dsp_coeff_ctl *ctl); ++ int (*post_run)(struct cs_dsp *dsp); ++ void (*post_stop)(struct cs_dsp *dsp); ++ void (*watchdog_expired)(struct cs_dsp *dsp); ++}; ++ + #endif +-- +2.35.3 + diff --git a/patches.suse/ASoC-wm_adsp-Split-DSP-power-operations-into-helper-.patch b/patches.suse/ASoC-wm_adsp-Split-DSP-power-operations-into-helper-.patch new file mode 100644 index 0000000..bff9b4d --- /dev/null +++ b/patches.suse/ASoC-wm_adsp-Split-DSP-power-operations-into-helper-.patch @@ -0,0 +1,624 @@ +From 186152df4d431650154c3e3aefc7d3e1004987c8 Mon Sep 17 00:00:00 2001 +From: Simon Trimmer +Date: Mon, 13 Sep 2021 17:00:49 +0100 +Subject: [PATCH] ASoC: wm_adsp: Split DSP power operations into helper functions +Git-commit: 186152df4d431650154c3e3aefc7d3e1004987c8 +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +This is preparation for moving the generic DSP support out of +ASoC. This change separates the generic handling of power and state +transitions from the DAPM API wrapper. + +Signed-off-by: Simon Trimmer +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20210913160057.103842-9-simont@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/wm_adsp.c | 495 ++++++++++++++++++++----------------- + 1 file changed, 273 insertions(+), 222 deletions(-) + +diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c +index c0ca46e04418..1bca3922a6b8 100644 +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -2808,114 +2808,129 @@ int wm_adsp1_init(struct wm_adsp *dsp) + } + EXPORT_SYMBOL_GPL(wm_adsp1_init); + +-int wm_adsp1_event(struct snd_soc_dapm_widget *w, +- struct snd_kcontrol *kcontrol, +- int event) ++static int cs_dsp_adsp1_power_up(struct wm_adsp *dsp) + { +- struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); +- struct wm_adsp *dsps = snd_soc_component_get_drvdata(component); +- struct wm_adsp *dsp = &dsps[w->shift]; +- struct wm_coeff_ctl *ctl; +- int ret; + unsigned int val; +- +- dsp->component = component; ++ int ret; + + mutex_lock(&dsp->pwr_lock); + +- switch (event) { +- case SND_SOC_DAPM_POST_PMU: +- regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, +- ADSP1_SYS_ENA, ADSP1_SYS_ENA); +- +- /* +- * For simplicity set the DSP clock rate to be the +- * SYSCLK rate rather than making it configurable. +- */ +- if (dsp->sysclk_reg) { +- ret = regmap_read(dsp->regmap, dsp->sysclk_reg, &val); +- if (ret != 0) { +- cs_dsp_err(dsp, "Failed to read SYSCLK state: %d\n", ret); +- goto err_mutex; +- } +- +- val = (val & dsp->sysclk_mask) >> dsp->sysclk_shift; ++ regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, ++ ADSP1_SYS_ENA, ADSP1_SYS_ENA); + +- ret = regmap_update_bits(dsp->regmap, +- dsp->base + ADSP1_CONTROL_31, +- ADSP1_CLK_SEL_MASK, val); +- if (ret != 0) { +- cs_dsp_err(dsp, "Failed to set clock rate: %d\n", ret); +- goto err_mutex; +- } ++ /* ++ * For simplicity set the DSP clock rate to be the ++ * SYSCLK rate rather than making it configurable. ++ */ ++ if (dsp->sysclk_reg) { ++ ret = regmap_read(dsp->regmap, dsp->sysclk_reg, &val); ++ if (ret != 0) { ++ cs_dsp_err(dsp, "Failed to read SYSCLK state: %d\n", ret); ++ goto err_mutex; + } + +- ret = cs_dsp_load(dsp); +- if (ret != 0) +- goto err_ena; ++ val = (val & dsp->sysclk_mask) >> dsp->sysclk_shift; + +- ret = cs_dsp_adsp1_setup_algs(dsp); +- if (ret != 0) +- goto err_ena; ++ ret = regmap_update_bits(dsp->regmap, ++ dsp->base + ADSP1_CONTROL_31, ++ ADSP1_CLK_SEL_MASK, val); ++ if (ret != 0) { ++ cs_dsp_err(dsp, "Failed to set clock rate: %d\n", ret); ++ goto err_mutex; ++ } ++ } + +- ret = cs_dsp_load_coeff(dsp); +- if (ret != 0) +- goto err_ena; ++ ret = cs_dsp_load(dsp); ++ if (ret != 0) ++ goto err_ena; + +- /* Initialize caches for enabled and unset controls */ +- ret = cs_dsp_coeff_init_control_caches(dsp); +- if (ret != 0) +- goto err_ena; ++ ret = cs_dsp_adsp1_setup_algs(dsp); ++ if (ret != 0) ++ goto err_ena; + +- /* Sync set controls */ +- ret = cs_dsp_coeff_sync_controls(dsp); +- if (ret != 0) +- goto err_ena; ++ ret = cs_dsp_load_coeff(dsp); ++ if (ret != 0) ++ goto err_ena; + +- dsp->booted = true; ++ /* Initialize caches for enabled and unset controls */ ++ ret = cs_dsp_coeff_init_control_caches(dsp); ++ if (ret != 0) ++ goto err_ena; + +- /* Start the core running */ +- regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, +- ADSP1_CORE_ENA | ADSP1_START, +- ADSP1_CORE_ENA | ADSP1_START); ++ /* Sync set controls */ ++ ret = cs_dsp_coeff_sync_controls(dsp); ++ if (ret != 0) ++ goto err_ena; + +- dsp->running = true; +- break; ++ dsp->booted = true; + +- case SND_SOC_DAPM_PRE_PMD: +- dsp->running = false; +- dsp->booted = false; ++ /* Start the core running */ ++ regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, ++ ADSP1_CORE_ENA | ADSP1_START, ++ ADSP1_CORE_ENA | ADSP1_START); + +- /* Halt the core */ +- regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, +- ADSP1_CORE_ENA | ADSP1_START, 0); ++ dsp->running = true; + +- regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_19, +- ADSP1_WDMA_BUFFER_LENGTH_MASK, 0); ++ mutex_unlock(&dsp->pwr_lock); + +- regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, +- ADSP1_SYS_ENA, 0); ++ return 0; + +- list_for_each_entry(ctl, &dsp->ctl_list, list) +- ctl->enabled = 0; ++err_ena: ++ regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, ++ ADSP1_SYS_ENA, 0); ++err_mutex: ++ mutex_unlock(&dsp->pwr_lock); ++ return ret; ++} + ++static void cs_dsp_adsp1_power_down(struct wm_adsp *dsp) ++{ ++ struct wm_coeff_ctl *ctl; + +- cs_dsp_free_alg_regions(dsp); +- break; ++ mutex_lock(&dsp->pwr_lock); + +- default: +- break; +- } ++ dsp->running = false; ++ dsp->booted = false; + +- mutex_unlock(&dsp->pwr_lock); ++ /* Halt the core */ ++ regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, ++ ADSP1_CORE_ENA | ADSP1_START, 0); + +- return 0; ++ regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_19, ++ ADSP1_WDMA_BUFFER_LENGTH_MASK, 0); + +-err_ena: + regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, + ADSP1_SYS_ENA, 0); +-err_mutex: ++ ++ list_for_each_entry(ctl, &dsp->ctl_list, list) ++ ctl->enabled = 0; ++ ++ cs_dsp_free_alg_regions(dsp); ++ + mutex_unlock(&dsp->pwr_lock); ++} ++ ++int wm_adsp1_event(struct snd_soc_dapm_widget *w, ++ struct snd_kcontrol *kcontrol, ++ int event) ++{ ++ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); ++ struct wm_adsp *dsps = snd_soc_component_get_drvdata(component); ++ struct wm_adsp *dsp = &dsps[w->shift]; ++ int ret = 0; ++ ++ dsp->component = component; ++ ++ switch (event) { ++ case SND_SOC_DAPM_POST_PMU: ++ ret = cs_dsp_adsp1_power_up(dsp); ++ break; ++ case SND_SOC_DAPM_PRE_PMD: ++ cs_dsp_adsp1_power_down(dsp); ++ break; ++ default: ++ break; ++ } + + return ret; + } +@@ -3019,63 +3034,6 @@ static void cs_dsp_adsp2v2_disable_core(struct wm_adsp *dsp) + regmap_write(dsp->regmap, dsp->base + ADSP2V2_WDMA_CONFIG_2, 0); + } + +-static void wm_adsp_boot_work(struct work_struct *work) +-{ +- struct wm_adsp *dsp = container_of(work, +- struct wm_adsp, +- boot_work); +- int ret; +- +- mutex_lock(&dsp->pwr_lock); +- +- if (dsp->ops->enable_memory) { +- ret = dsp->ops->enable_memory(dsp); +- if (ret != 0) +- goto err_mutex; +- } +- +- if (dsp->ops->enable_core) { +- ret = dsp->ops->enable_core(dsp); +- if (ret != 0) +- goto err_mem; +- } +- +- ret = cs_dsp_load(dsp); +- if (ret != 0) +- goto err_ena; +- +- ret = dsp->ops->setup_algs(dsp); +- if (ret != 0) +- goto err_ena; +- +- ret = cs_dsp_load_coeff(dsp); +- if (ret != 0) +- goto err_ena; +- +- /* Initialize caches for enabled and unset controls */ +- ret = cs_dsp_coeff_init_control_caches(dsp); +- if (ret != 0) +- goto err_ena; +- +- if (dsp->ops->disable_core) +- dsp->ops->disable_core(dsp); +- +- dsp->booted = true; +- +- mutex_unlock(&dsp->pwr_lock); +- +- return; +- +-err_ena: +- if (dsp->ops->disable_core) +- dsp->ops->disable_core(dsp); +-err_mem: +- if (dsp->ops->disable_memory) +- dsp->ops->disable_memory(dsp); +-err_mutex: +- mutex_unlock(&dsp->pwr_lock); +-} +- + static int cs_dsp_halo_configure_mpu(struct wm_adsp *dsp, unsigned int lock_regions) + { + struct reg_sequence config[] = { +@@ -3185,39 +3143,108 @@ static void cs_dsp_halo_stop_watchdog(struct wm_adsp *dsp) + HALO_WDT_EN_MASK, 0); + } + ++static void cs_dsp_power_up(struct wm_adsp *dsp) ++{ ++ int ret; ++ ++ mutex_lock(&dsp->pwr_lock); ++ ++ if (dsp->ops->enable_memory) { ++ ret = dsp->ops->enable_memory(dsp); ++ if (ret != 0) ++ goto err_mutex; ++ } ++ ++ if (dsp->ops->enable_core) { ++ ret = dsp->ops->enable_core(dsp); ++ if (ret != 0) ++ goto err_mem; ++ } ++ ++ ret = cs_dsp_load(dsp); ++ if (ret != 0) ++ goto err_ena; ++ ++ ret = dsp->ops->setup_algs(dsp); ++ if (ret != 0) ++ goto err_ena; ++ ++ ret = cs_dsp_load_coeff(dsp); ++ if (ret != 0) ++ goto err_ena; ++ ++ /* Initialize caches for enabled and unset controls */ ++ ret = cs_dsp_coeff_init_control_caches(dsp); ++ if (ret != 0) ++ goto err_ena; ++ ++ if (dsp->ops->disable_core) ++ dsp->ops->disable_core(dsp); ++ ++ dsp->booted = true; ++ ++ mutex_unlock(&dsp->pwr_lock); ++ ++ return; ++ ++err_ena: ++ if (dsp->ops->disable_core) ++ dsp->ops->disable_core(dsp); ++err_mem: ++ if (dsp->ops->disable_memory) ++ dsp->ops->disable_memory(dsp); ++err_mutex: ++ mutex_unlock(&dsp->pwr_lock); ++} ++ ++static void cs_dsp_power_down(struct wm_adsp *dsp) ++{ ++ struct wm_coeff_ctl *ctl; ++ ++ mutex_lock(&dsp->pwr_lock); ++ ++ cs_dsp_debugfs_clear(dsp); ++ ++ dsp->fw_id = 0; ++ dsp->fw_id_version = 0; ++ ++ dsp->booted = false; ++ ++ if (dsp->ops->disable_memory) ++ dsp->ops->disable_memory(dsp); ++ ++ list_for_each_entry(ctl, &dsp->ctl_list, list) ++ ctl->enabled = 0; ++ ++ cs_dsp_free_alg_regions(dsp); ++ ++ mutex_unlock(&dsp->pwr_lock); ++ ++ cs_dsp_dbg(dsp, "Shutdown complete\n"); ++} ++ ++static void wm_adsp_boot_work(struct work_struct *work) ++{ ++ struct wm_adsp *dsp = container_of(work, ++ struct wm_adsp, ++ boot_work); ++ ++ cs_dsp_power_up(dsp); ++} ++ + int wm_adsp_early_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) + { + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + struct wm_adsp *dsps = snd_soc_component_get_drvdata(component); + struct wm_adsp *dsp = &dsps[w->shift]; +- struct wm_coeff_ctl *ctl; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + queue_work(system_unbound_wq, &dsp->boot_work); + break; + case SND_SOC_DAPM_PRE_PMD: +- mutex_lock(&dsp->pwr_lock); +- +- cs_dsp_debugfs_clear(dsp); +- +- dsp->fw_id = 0; +- dsp->fw_id_version = 0; +- +- dsp->booted = false; +- +- if (dsp->ops->disable_memory) +- dsp->ops->disable_memory(dsp); +- +- list_for_each_entry(ctl, &dsp->ctl_list, list) +- ctl->enabled = 0; +- +- cs_dsp_free_alg_regions(dsp); +- +- mutex_unlock(&dsp->pwr_lock); +- +- cs_dsp_dbg(dsp, "Shutdown complete\n"); ++ cs_dsp_power_down(dsp); + break; + default: + break; +@@ -3240,102 +3267,126 @@ static void cs_dsp_adsp2_stop_core(struct wm_adsp *dsp) + ADSP2_CORE_ENA | ADSP2_START, 0); + } + +-int wm_adsp_event(struct snd_soc_dapm_widget *w, +- struct snd_kcontrol *kcontrol, int event) ++static int wm_adsp_event_post_run(struct wm_adsp *dsp) ++{ ++ if (wm_adsp_fw[dsp->fw].num_caps != 0) ++ return wm_adsp_buffer_init(dsp); ++ ++ return 0; ++} ++ ++static void wm_adsp_event_post_stop(struct wm_adsp *dsp) ++{ ++ if (wm_adsp_fw[dsp->fw].num_caps != 0) ++ wm_adsp_buffer_free(dsp); ++ ++ dsp->fatal_error = false; ++} ++ ++static int cs_dsp_run(struct wm_adsp *dsp) + { +- struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); +- struct wm_adsp *dsps = snd_soc_component_get_drvdata(component); +- struct wm_adsp *dsp = &dsps[w->shift]; + int ret; + +- switch (event) { +- case SND_SOC_DAPM_POST_PMU: +- flush_work(&dsp->boot_work); ++ mutex_lock(&dsp->pwr_lock); + +- mutex_lock(&dsp->pwr_lock); ++ if (!dsp->booted) { ++ ret = -EIO; ++ goto err; ++ } + +- if (!dsp->booted) { +- ret = -EIO; ++ if (dsp->ops->enable_core) { ++ ret = dsp->ops->enable_core(dsp); ++ if (ret != 0) + goto err; +- } ++ } + +- if (dsp->ops->enable_core) { +- ret = dsp->ops->enable_core(dsp); +- if (ret != 0) +- goto err; ++ /* Sync set controls */ ++ ret = cs_dsp_coeff_sync_controls(dsp); ++ if (ret != 0) ++ goto err; ++ ++ if (dsp->ops->lock_memory) { ++ ret = dsp->ops->lock_memory(dsp, dsp->lock_regions); ++ if (ret != 0) { ++ cs_dsp_err(dsp, "Error configuring MPU: %d\n", ret); ++ goto err; + } ++ } + +- /* Sync set controls */ +- ret = cs_dsp_coeff_sync_controls(dsp); ++ if (dsp->ops->start_core) { ++ ret = dsp->ops->start_core(dsp); + if (ret != 0) + goto err; ++ } + +- if (dsp->ops->lock_memory) { +- ret = dsp->ops->lock_memory(dsp, dsp->lock_regions); +- if (ret != 0) { +- cs_dsp_err(dsp, "Error configuring MPU: %d\n", ret); +- goto err; +- } +- } ++ dsp->running = true; + +- if (dsp->ops->start_core) { +- ret = dsp->ops->start_core(dsp); +- if (ret != 0) +- goto err; +- } ++ ret = wm_adsp_event_post_run(dsp); ++ if (ret < 0) ++ goto err; + +- dsp->running = true; ++ mutex_unlock(&dsp->pwr_lock); + +- if (wm_adsp_fw[dsp->fw].num_caps != 0) { +- ret = wm_adsp_buffer_init(dsp); +- if (ret < 0) +- goto err; +- } ++ return 0; + +- mutex_unlock(&dsp->pwr_lock); +- break; ++err: ++ if (dsp->ops->stop_core) ++ dsp->ops->stop_core(dsp); ++ if (dsp->ops->disable_core) ++ dsp->ops->disable_core(dsp); ++ mutex_unlock(&dsp->pwr_lock); + +- case SND_SOC_DAPM_PRE_PMD: +- /* Tell the firmware to cleanup */ +- cs_dsp_signal_event_controls(dsp, CS_DSP_FW_EVENT_SHUTDOWN); ++ return ret; ++} ++ ++static void cs_dsp_stop(struct wm_adsp *dsp) ++{ ++ /* Tell the firmware to cleanup */ ++ cs_dsp_signal_event_controls(dsp, CS_DSP_FW_EVENT_SHUTDOWN); + +- if (dsp->ops->stop_watchdog) +- dsp->ops->stop_watchdog(dsp); ++ if (dsp->ops->stop_watchdog) ++ dsp->ops->stop_watchdog(dsp); + +- /* Log firmware state, it can be useful for analysis */ +- if (dsp->ops->show_fw_status) +- dsp->ops->show_fw_status(dsp); ++ /* Log firmware state, it can be useful for analysis */ ++ if (dsp->ops->show_fw_status) ++ dsp->ops->show_fw_status(dsp); + +- mutex_lock(&dsp->pwr_lock); ++ mutex_lock(&dsp->pwr_lock); + +- dsp->running = false; ++ dsp->running = false; + +- if (dsp->ops->stop_core) +- dsp->ops->stop_core(dsp); +- if (dsp->ops->disable_core) +- dsp->ops->disable_core(dsp); ++ if (dsp->ops->stop_core) ++ dsp->ops->stop_core(dsp); ++ if (dsp->ops->disable_core) ++ dsp->ops->disable_core(dsp); + +- if (wm_adsp_fw[dsp->fw].num_caps != 0) +- wm_adsp_buffer_free(dsp); ++ wm_adsp_event_post_stop(dsp); + +- dsp->fatal_error = false; ++ mutex_unlock(&dsp->pwr_lock); + +- mutex_unlock(&dsp->pwr_lock); ++ cs_dsp_dbg(dsp, "Execution stopped\n"); ++} + +- cs_dsp_dbg(dsp, "Execution stopped\n"); +- break; ++int wm_adsp_event(struct snd_soc_dapm_widget *w, ++ struct snd_kcontrol *kcontrol, int event) ++{ ++ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); ++ struct wm_adsp *dsps = snd_soc_component_get_drvdata(component); ++ struct wm_adsp *dsp = &dsps[w->shift]; ++ int ret = 0; + ++ switch (event) { ++ case SND_SOC_DAPM_POST_PMU: ++ flush_work(&dsp->boot_work); ++ ret = cs_dsp_run(dsp); ++ break; ++ case SND_SOC_DAPM_PRE_PMD: ++ cs_dsp_stop(dsp); ++ break; + default: + break; + } + +- return 0; +-err: +- if (dsp->ops->stop_core) +- dsp->ops->stop_core(dsp); +- if (dsp->ops->disable_core) +- dsp->ops->disable_core(dsp); +- mutex_unlock(&dsp->pwr_lock); + return ret; + } + EXPORT_SYMBOL_GPL(wm_adsp_event); +-- +2.35.3 + diff --git a/patches.suse/ASoC-wm_adsp-Split-out-struct-cs_dsp-from-struct-wm_.patch b/patches.suse/ASoC-wm_adsp-Split-out-struct-cs_dsp-from-struct-wm_.patch new file mode 100644 index 0000000..4dee5da --- /dev/null +++ b/patches.suse/ASoC-wm_adsp-Split-out-struct-cs_dsp-from-struct-wm_.patch @@ -0,0 +1,1759 @@ +From e146820215910d889ab16d6c2484fd51a6bb8f1f Mon Sep 17 00:00:00 2001 +From: Simon Trimmer +Date: Mon, 13 Sep 2021 17:00:55 +0100 +Subject: [PATCH] ASoC: wm_adsp: Split out struct cs_dsp from struct wm_adsp +Git-commit: e146820215910d889ab16d6c2484fd51a6bb8f1f +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +In preparation for moving the generic DSP support out of ASoC split +struct wm_adsp into two parts, one will form the structure for the new +generic DSP code and embed that one into wm_adsp. + +Signed-off-by: Simon Trimmer +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20210913160057.103842-15-simont@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs47l15.c | 18 +- + sound/soc/codecs/cs47l24.c | 14 +- + sound/soc/codecs/cs47l35.c | 18 +- + sound/soc/codecs/cs47l85.c | 18 +- + sound/soc/codecs/cs47l90.c | 20 +-- + sound/soc/codecs/cs47l92.c | 18 +- + sound/soc/codecs/madera.c | 18 +- + sound/soc/codecs/wm2200.c | 26 +-- + sound/soc/codecs/wm5102.c | 14 +- + sound/soc/codecs/wm5110.c | 14 +- + sound/soc/codecs/wm_adsp.c | 352 ++++++++++++++++++++----------------- + sound/soc/codecs/wm_adsp.h | 60 ++++--- + 12 files changed, 310 insertions(+), 280 deletions(-) + +diff --git a/sound/soc/codecs/cs47l15.c b/sound/soc/codecs/cs47l15.c +index 07388701f89f..391fd7da331f 100644 +--- a/sound/soc/codecs/cs47l15.c ++++ b/sound/soc/codecs/cs47l15.c +@@ -1402,17 +1402,17 @@ static int cs47l15_probe(struct platform_device *pdev) + dev_warn(&pdev->dev, "Failed to set DSP IRQ wake: %d\n", ret); + + cs47l15->core.adsp[0].part = "cs47l15"; +- cs47l15->core.adsp[0].num = 1; +- cs47l15->core.adsp[0].type = WMFW_ADSP2; +- cs47l15->core.adsp[0].rev = 2; +- cs47l15->core.adsp[0].dev = madera->dev; +- cs47l15->core.adsp[0].regmap = madera->regmap_32bit; ++ cs47l15->core.adsp[0].cs_dsp.num = 1; ++ cs47l15->core.adsp[0].cs_dsp.type = WMFW_ADSP2; ++ cs47l15->core.adsp[0].cs_dsp.rev = 2; ++ cs47l15->core.adsp[0].cs_dsp.dev = madera->dev; ++ cs47l15->core.adsp[0].cs_dsp.regmap = madera->regmap_32bit; + +- cs47l15->core.adsp[0].base = MADERA_DSP1_CONFIG_1; +- cs47l15->core.adsp[0].mem = cs47l15_dsp1_regions; +- cs47l15->core.adsp[0].num_mems = ARRAY_SIZE(cs47l15_dsp1_regions); ++ cs47l15->core.adsp[0].cs_dsp.base = MADERA_DSP1_CONFIG_1; ++ cs47l15->core.adsp[0].cs_dsp.mem = cs47l15_dsp1_regions; ++ cs47l15->core.adsp[0].cs_dsp.num_mems = ARRAY_SIZE(cs47l15_dsp1_regions); + +- cs47l15->core.adsp[0].lock_regions = ++ cs47l15->core.adsp[0].cs_dsp.lock_regions = + CS_ADSP2_REGION_1 | CS_ADSP2_REGION_2 | CS_ADSP2_REGION_3; + + ret = wm_adsp2_init(&cs47l15->core.adsp[0]); +diff --git a/sound/soc/codecs/cs47l24.c b/sound/soc/codecs/cs47l24.c +index be81094dbf1e..6356f81aafc5 100644 +--- a/sound/soc/codecs/cs47l24.c ++++ b/sound/soc/codecs/cs47l24.c +@@ -1234,15 +1234,15 @@ static int cs47l24_probe(struct platform_device *pdev) + + for (i = 1; i <= 2; i++) { + cs47l24->core.adsp[i].part = "cs47l24"; +- cs47l24->core.adsp[i].num = i + 1; +- cs47l24->core.adsp[i].type = WMFW_ADSP2; +- cs47l24->core.adsp[i].dev = arizona->dev; +- cs47l24->core.adsp[i].regmap = arizona->regmap; ++ cs47l24->core.adsp[i].cs_dsp.num = i + 1; ++ cs47l24->core.adsp[i].cs_dsp.type = WMFW_ADSP2; ++ cs47l24->core.adsp[i].cs_dsp.dev = arizona->dev; ++ cs47l24->core.adsp[i].cs_dsp.regmap = arizona->regmap; + +- cs47l24->core.adsp[i].base = ARIZONA_DSP1_CONTROL_1 + ++ cs47l24->core.adsp[i].cs_dsp.base = ARIZONA_DSP1_CONTROL_1 + + (0x100 * i); +- cs47l24->core.adsp[i].mem = cs47l24_dsp_regions[i - 1]; +- cs47l24->core.adsp[i].num_mems = ++ cs47l24->core.adsp[i].cs_dsp.mem = cs47l24_dsp_regions[i - 1]; ++ cs47l24->core.adsp[i].cs_dsp.num_mems = + ARRAY_SIZE(cs47l24_dsp2_regions); + + ret = wm_adsp2_init(&cs47l24->core.adsp[i]); +diff --git a/sound/soc/codecs/cs47l35.c b/sound/soc/codecs/cs47l35.c +index b8d594bf4d13..db2f844b8b17 100644 +--- a/sound/soc/codecs/cs47l35.c ++++ b/sound/soc/codecs/cs47l35.c +@@ -1686,15 +1686,15 @@ static int cs47l35_probe(struct platform_device *pdev) + + for (i = 0; i < CS47L35_NUM_ADSP; i++) { + cs47l35->core.adsp[i].part = "cs47l35"; +- cs47l35->core.adsp[i].num = i + 1; +- cs47l35->core.adsp[i].type = WMFW_ADSP2; +- cs47l35->core.adsp[i].rev = 1; +- cs47l35->core.adsp[i].dev = madera->dev; +- cs47l35->core.adsp[i].regmap = madera->regmap_32bit; +- +- cs47l35->core.adsp[i].base = wm_adsp2_control_bases[i]; +- cs47l35->core.adsp[i].mem = cs47l35_dsp_regions[i]; +- cs47l35->core.adsp[i].num_mems = ++ cs47l35->core.adsp[i].cs_dsp.num = i + 1; ++ cs47l35->core.adsp[i].cs_dsp.type = WMFW_ADSP2; ++ cs47l35->core.adsp[i].cs_dsp.rev = 1; ++ cs47l35->core.adsp[i].cs_dsp.dev = madera->dev; ++ cs47l35->core.adsp[i].cs_dsp.regmap = madera->regmap_32bit; ++ ++ cs47l35->core.adsp[i].cs_dsp.base = wm_adsp2_control_bases[i]; ++ cs47l35->core.adsp[i].cs_dsp.mem = cs47l35_dsp_regions[i]; ++ cs47l35->core.adsp[i].cs_dsp.num_mems = + ARRAY_SIZE(cs47l35_dsp1_regions); + + ret = wm_adsp2_init(&cs47l35->core.adsp[i]); +diff --git a/sound/soc/codecs/cs47l85.c b/sound/soc/codecs/cs47l85.c +index 7ba08ca75c4f..d4fedc5ad516 100644 +--- a/sound/soc/codecs/cs47l85.c ++++ b/sound/soc/codecs/cs47l85.c +@@ -2632,15 +2632,15 @@ static int cs47l85_probe(struct platform_device *pdev) + + for (i = 0; i < CS47L85_NUM_ADSP; i++) { + cs47l85->core.adsp[i].part = "cs47l85"; +- cs47l85->core.adsp[i].num = i + 1; +- cs47l85->core.adsp[i].type = WMFW_ADSP2; +- cs47l85->core.adsp[i].rev = 1; +- cs47l85->core.adsp[i].dev = madera->dev; +- cs47l85->core.adsp[i].regmap = madera->regmap_32bit; +- +- cs47l85->core.adsp[i].base = wm_adsp2_control_bases[i]; +- cs47l85->core.adsp[i].mem = cs47l85_dsp_regions[i]; +- cs47l85->core.adsp[i].num_mems = ++ cs47l85->core.adsp[i].cs_dsp.num = i + 1; ++ cs47l85->core.adsp[i].cs_dsp.type = WMFW_ADSP2; ++ cs47l85->core.adsp[i].cs_dsp.rev = 1; ++ cs47l85->core.adsp[i].cs_dsp.dev = madera->dev; ++ cs47l85->core.adsp[i].cs_dsp.regmap = madera->regmap_32bit; ++ ++ cs47l85->core.adsp[i].cs_dsp.base = wm_adsp2_control_bases[i]; ++ cs47l85->core.adsp[i].cs_dsp.mem = cs47l85_dsp_regions[i]; ++ cs47l85->core.adsp[i].cs_dsp.num_mems = + ARRAY_SIZE(cs47l85_dsp1_regions); + + ret = wm_adsp2_init(&cs47l85->core.adsp[i]); +diff --git a/sound/soc/codecs/cs47l90.c b/sound/soc/codecs/cs47l90.c +index 01d75c32d81e..5aec937a2462 100644 +--- a/sound/soc/codecs/cs47l90.c ++++ b/sound/soc/codecs/cs47l90.c +@@ -2543,18 +2543,18 @@ static int cs47l90_probe(struct platform_device *pdev) + + for (i = 0; i < CS47L90_NUM_ADSP; i++) { + cs47l90->core.adsp[i].part = "cs47l90"; +- cs47l90->core.adsp[i].num = i + 1; +- cs47l90->core.adsp[i].type = WMFW_ADSP2; +- cs47l90->core.adsp[i].rev = 2; +- cs47l90->core.adsp[i].dev = madera->dev; +- cs47l90->core.adsp[i].regmap = madera->regmap_32bit; +- +- cs47l90->core.adsp[i].base = cs47l90_dsp_control_bases[i]; +- cs47l90->core.adsp[i].mem = cs47l90_dsp_regions[i]; +- cs47l90->core.adsp[i].num_mems = ++ cs47l90->core.adsp[i].cs_dsp.num = i + 1; ++ cs47l90->core.adsp[i].cs_dsp.type = WMFW_ADSP2; ++ cs47l90->core.adsp[i].cs_dsp.rev = 2; ++ cs47l90->core.adsp[i].cs_dsp.dev = madera->dev; ++ cs47l90->core.adsp[i].cs_dsp.regmap = madera->regmap_32bit; ++ ++ cs47l90->core.adsp[i].cs_dsp.base = cs47l90_dsp_control_bases[i]; ++ cs47l90->core.adsp[i].cs_dsp.mem = cs47l90_dsp_regions[i]; ++ cs47l90->core.adsp[i].cs_dsp.num_mems = + ARRAY_SIZE(cs47l90_dsp1_regions); + +- cs47l90->core.adsp[i].lock_regions = CS_ADSP2_REGION_1_9; ++ cs47l90->core.adsp[i].cs_dsp.lock_regions = CS_ADSP2_REGION_1_9; + + ret = wm_adsp2_init(&cs47l90->core.adsp[i]); + +diff --git a/sound/soc/codecs/cs47l92.c b/sound/soc/codecs/cs47l92.c +index 05087cc9c44b..a1b8dcdb9f7b 100644 +--- a/sound/soc/codecs/cs47l92.c ++++ b/sound/soc/codecs/cs47l92.c +@@ -2002,17 +2002,17 @@ static int cs47l92_probe(struct platform_device *pdev) + dev_warn(&pdev->dev, "Failed to set DSP IRQ wake: %d\n", ret); + + cs47l92->core.adsp[0].part = "cs47l92"; +- cs47l92->core.adsp[0].num = 1; +- cs47l92->core.adsp[0].type = WMFW_ADSP2; +- cs47l92->core.adsp[0].rev = 2; +- cs47l92->core.adsp[0].dev = madera->dev; +- cs47l92->core.adsp[0].regmap = madera->regmap_32bit; ++ cs47l92->core.adsp[0].cs_dsp.num = 1; ++ cs47l92->core.adsp[0].cs_dsp.type = WMFW_ADSP2; ++ cs47l92->core.adsp[0].cs_dsp.rev = 2; ++ cs47l92->core.adsp[0].cs_dsp.dev = madera->dev; ++ cs47l92->core.adsp[0].cs_dsp.regmap = madera->regmap_32bit; + +- cs47l92->core.adsp[0].base = MADERA_DSP1_CONFIG_1; +- cs47l92->core.adsp[0].mem = cs47l92_dsp1_regions; +- cs47l92->core.adsp[0].num_mems = ARRAY_SIZE(cs47l92_dsp1_regions); ++ cs47l92->core.adsp[0].cs_dsp.base = MADERA_DSP1_CONFIG_1; ++ cs47l92->core.adsp[0].cs_dsp.mem = cs47l92_dsp1_regions; ++ cs47l92->core.adsp[0].cs_dsp.num_mems = ARRAY_SIZE(cs47l92_dsp1_regions); + +- cs47l92->core.adsp[0].lock_regions = CS_ADSP2_REGION_1_9; ++ cs47l92->core.adsp[0].cs_dsp.lock_regions = CS_ADSP2_REGION_1_9; + + ret = wm_adsp2_init(&cs47l92->core.adsp[0]); + if (ret != 0) +diff --git a/sound/soc/codecs/madera.c b/sound/soc/codecs/madera.c +index f4ed7e04673f..272041c6236a 100644 +--- a/sound/soc/codecs/madera.c ++++ b/sound/soc/codecs/madera.c +@@ -905,7 +905,7 @@ static int madera_adsp_rate_put(struct snd_kcontrol *kcontrol, + */ + mutex_lock(&priv->rate_lock); + +- if (!madera_can_change_grp_rate(priv, priv->adsp[adsp_num].base)) { ++ if (!madera_can_change_grp_rate(priv, priv->adsp[adsp_num].cs_dsp.base)) { + dev_warn(priv->madera->dev, + "Cannot change '%s' while in use by active audio paths\n", + kcontrol->id.name); +@@ -964,7 +964,7 @@ static int madera_write_adsp_clk_setting(struct madera_priv *priv, + unsigned int mask = MADERA_DSP_RATE_MASK; + int ret; + +- val = priv->adsp_rate_cache[dsp->num - 1] << MADERA_DSP_RATE_SHIFT; ++ val = priv->adsp_rate_cache[dsp->cs_dsp.num - 1] << MADERA_DSP_RATE_SHIFT; + + switch (priv->madera->type) { + case CS47L35: +@@ -978,15 +978,15 @@ static int madera_write_adsp_clk_setting(struct madera_priv *priv, + /* Configure exact dsp frequency */ + dev_dbg(priv->madera->dev, "Set DSP frequency to 0x%x\n", freq); + +- ret = regmap_write(dsp->regmap, +- dsp->base + MADERA_DSP_CONFIG_2_OFFS, freq); ++ ret = regmap_write(dsp->cs_dsp.regmap, ++ dsp->cs_dsp.base + MADERA_DSP_CONFIG_2_OFFS, freq); + if (ret) + goto err; + break; + } + +- ret = regmap_update_bits(dsp->regmap, +- dsp->base + MADERA_DSP_CONFIG_1_OFFS, ++ ret = regmap_update_bits(dsp->cs_dsp.regmap, ++ dsp->cs_dsp.base + MADERA_DSP_CONFIG_1_OFFS, + mask, val); + if (ret) + goto err; +@@ -996,7 +996,7 @@ static int madera_write_adsp_clk_setting(struct madera_priv *priv, + return 0; + + err: +- dev_err(dsp->dev, "Failed to set DSP%d clock: %d\n", dsp->num, ret); ++ dev_err(dsp->cs_dsp.dev, "Failed to set DSP%d clock: %d\n", dsp->cs_dsp.num, ret); + + return ret; + } +@@ -1018,7 +1018,7 @@ int madera_set_adsp_clk(struct madera_priv *priv, int dsp_num, + * changes are locked out by the domain_group_ref reference count. + */ + +- ret = regmap_read(dsp->regmap, dsp->base, &cur); ++ ret = regmap_read(dsp->cs_dsp.regmap, dsp->cs_dsp.base, &cur); + if (ret) { + dev_err(madera->dev, + "Failed to read current DSP rate: %d\n", ret); +@@ -1027,7 +1027,7 @@ int madera_set_adsp_clk(struct madera_priv *priv, int dsp_num, + + cur &= MADERA_DSP_RATE_MASK; + +- new = priv->adsp_rate_cache[dsp->num - 1] << MADERA_DSP_RATE_SHIFT; ++ new = priv->adsp_rate_cache[dsp->cs_dsp.num - 1] << MADERA_DSP_RATE_SHIFT; + + if (new == cur) { + dev_dbg(madera->dev, "DSP rate not changed\n"); +diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c +index 68355188eb55..8863b533f9c4 100644 +--- a/sound/soc/codecs/wm2200.c ++++ b/sound/soc/codecs/wm2200.c +@@ -2202,23 +2202,23 @@ static int wm2200_i2c_probe(struct i2c_client *i2c, + } + + for (i = 0; i < 2; i++) { +- wm2200->dsp[i].type = WMFW_ADSP1; ++ wm2200->dsp[i].cs_dsp.type = WMFW_ADSP1; + wm2200->dsp[i].part = "wm2200"; +- wm2200->dsp[i].num = i + 1; +- wm2200->dsp[i].dev = &i2c->dev; +- wm2200->dsp[i].regmap = wm2200->regmap; +- wm2200->dsp[i].sysclk_reg = WM2200_CLOCKING_3; +- wm2200->dsp[i].sysclk_mask = WM2200_SYSCLK_FREQ_MASK; +- wm2200->dsp[i].sysclk_shift = WM2200_SYSCLK_FREQ_SHIFT; ++ wm2200->dsp[i].cs_dsp.num = i + 1; ++ wm2200->dsp[i].cs_dsp.dev = &i2c->dev; ++ wm2200->dsp[i].cs_dsp.regmap = wm2200->regmap; ++ wm2200->dsp[i].cs_dsp.sysclk_reg = WM2200_CLOCKING_3; ++ wm2200->dsp[i].cs_dsp.sysclk_mask = WM2200_SYSCLK_FREQ_MASK; ++ wm2200->dsp[i].cs_dsp.sysclk_shift = WM2200_SYSCLK_FREQ_SHIFT; + } + +- wm2200->dsp[0].base = WM2200_DSP1_CONTROL_1; +- wm2200->dsp[0].mem = wm2200_dsp1_regions; +- wm2200->dsp[0].num_mems = ARRAY_SIZE(wm2200_dsp1_regions); ++ wm2200->dsp[0].cs_dsp.base = WM2200_DSP1_CONTROL_1; ++ wm2200->dsp[0].cs_dsp.mem = wm2200_dsp1_regions; ++ wm2200->dsp[0].cs_dsp.num_mems = ARRAY_SIZE(wm2200_dsp1_regions); + +- wm2200->dsp[1].base = WM2200_DSP2_CONTROL_1; +- wm2200->dsp[1].mem = wm2200_dsp2_regions; +- wm2200->dsp[1].num_mems = ARRAY_SIZE(wm2200_dsp2_regions); ++ wm2200->dsp[1].cs_dsp.base = WM2200_DSP2_CONTROL_1; ++ wm2200->dsp[1].cs_dsp.mem = wm2200_dsp2_regions; ++ wm2200->dsp[1].cs_dsp.num_mems = ARRAY_SIZE(wm2200_dsp2_regions); + + for (i = 0; i < ARRAY_SIZE(wm2200->dsp); i++) + wm_adsp1_init(&wm2200->dsp[i]); +diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c +index 26e87c6be35b..da2f8998df87 100644 +--- a/sound/soc/codecs/wm5102.c ++++ b/sound/soc/codecs/wm5102.c +@@ -2046,13 +2046,13 @@ static int wm5102_probe(struct platform_device *pdev) + arizona_init_dvfs(&wm5102->core); + + wm5102->core.adsp[0].part = "wm5102"; +- wm5102->core.adsp[0].num = 1; +- wm5102->core.adsp[0].type = WMFW_ADSP2; +- wm5102->core.adsp[0].base = ARIZONA_DSP1_CONTROL_1; +- wm5102->core.adsp[0].dev = arizona->dev; +- wm5102->core.adsp[0].regmap = arizona->regmap; +- wm5102->core.adsp[0].mem = wm5102_dsp1_regions; +- wm5102->core.adsp[0].num_mems = ARRAY_SIZE(wm5102_dsp1_regions); ++ wm5102->core.adsp[0].cs_dsp.num = 1; ++ wm5102->core.adsp[0].cs_dsp.type = WMFW_ADSP2; ++ wm5102->core.adsp[0].cs_dsp.base = ARIZONA_DSP1_CONTROL_1; ++ wm5102->core.adsp[0].cs_dsp.dev = arizona->dev; ++ wm5102->core.adsp[0].cs_dsp.regmap = arizona->regmap; ++ wm5102->core.adsp[0].cs_dsp.mem = wm5102_dsp1_regions; ++ wm5102->core.adsp[0].cs_dsp.num_mems = ARRAY_SIZE(wm5102_dsp1_regions); + + ret = wm_adsp2_init(&wm5102->core.adsp[0]); + if (ret != 0) +diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c +index e13e66b0ee52..4973ba1ed779 100644 +--- a/sound/soc/codecs/wm5110.c ++++ b/sound/soc/codecs/wm5110.c +@@ -2409,15 +2409,15 @@ static int wm5110_probe(struct platform_device *pdev) + + for (i = 0; i < WM5110_NUM_ADSP; i++) { + wm5110->core.adsp[i].part = "wm5110"; +- wm5110->core.adsp[i].num = i + 1; +- wm5110->core.adsp[i].type = WMFW_ADSP2; +- wm5110->core.adsp[i].dev = arizona->dev; +- wm5110->core.adsp[i].regmap = arizona->regmap; ++ wm5110->core.adsp[i].cs_dsp.num = i + 1; ++ wm5110->core.adsp[i].cs_dsp.type = WMFW_ADSP2; ++ wm5110->core.adsp[i].cs_dsp.dev = arizona->dev; ++ wm5110->core.adsp[i].cs_dsp.regmap = arizona->regmap; + +- wm5110->core.adsp[i].base = ARIZONA_DSP1_CONTROL_1 ++ wm5110->core.adsp[i].cs_dsp.base = ARIZONA_DSP1_CONTROL_1 + + (0x100 * i); +- wm5110->core.adsp[i].mem = wm5110_dsp_regions[i]; +- wm5110->core.adsp[i].num_mems ++ wm5110->core.adsp[i].cs_dsp.mem = wm5110_dsp_regions[i]; ++ wm5110->core.adsp[i].cs_dsp.num_mems + = ARRAY_SIZE(wm5110_dsp1_regions); + + ret = wm_adsp2_init(&wm5110->core.adsp[i]); +diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c +index 3b5b0cce7b35..092df446ff2f 100644 +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -34,15 +34,15 @@ + #include "wm_adsp.h" + + #define adsp_crit(_dsp, fmt, ...) \ +- dev_crit(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) ++ dev_crit(_dsp->cs_dsp.dev, "%s: " fmt, _dsp->cs_dsp.name, ##__VA_ARGS__) + #define adsp_err(_dsp, fmt, ...) \ +- dev_err(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) ++ dev_err(_dsp->cs_dsp.dev, "%s: " fmt, _dsp->cs_dsp.name, ##__VA_ARGS__) + #define adsp_warn(_dsp, fmt, ...) \ +- dev_warn(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) ++ dev_warn(_dsp->cs_dsp.dev, "%s: " fmt, _dsp->cs_dsp.name, ##__VA_ARGS__) + #define adsp_info(_dsp, fmt, ...) \ +- dev_info(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) ++ dev_info(_dsp->cs_dsp.dev, "%s: " fmt, _dsp->cs_dsp.name, ##__VA_ARGS__) + #define adsp_dbg(_dsp, fmt, ...) \ +- dev_dbg(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) ++ dev_dbg(_dsp->cs_dsp.dev, "%s: " fmt, _dsp->cs_dsp.name, ##__VA_ARGS__) + + #define cs_dsp_err(_dsp, fmt, ...) \ + dev_err(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) +@@ -638,7 +638,7 @@ static const char *cs_dsp_mem_region_name(unsigned int type) + } + + #ifdef CONFIG_DEBUG_FS +-static void cs_dsp_debugfs_save_wmfwname(struct wm_adsp *dsp, const char *s) ++static void cs_dsp_debugfs_save_wmfwname(struct cs_dsp *dsp, const char *s) + { + char *tmp = kasprintf(GFP_KERNEL, "%s\n", s); + +@@ -646,7 +646,7 @@ static void cs_dsp_debugfs_save_wmfwname(struct wm_adsp *dsp, const char *s) + dsp->wmfw_file_name = tmp; + } + +-static void cs_dsp_debugfs_save_binname(struct wm_adsp *dsp, const char *s) ++static void cs_dsp_debugfs_save_binname(struct cs_dsp *dsp, const char *s) + { + char *tmp = kasprintf(GFP_KERNEL, "%s\n", s); + +@@ -654,7 +654,7 @@ static void cs_dsp_debugfs_save_binname(struct wm_adsp *dsp, const char *s) + dsp->bin_file_name = tmp; + } + +-static void cs_dsp_debugfs_clear(struct wm_adsp *dsp) ++static void cs_dsp_debugfs_clear(struct cs_dsp *dsp) + { + kfree(dsp->wmfw_file_name); + kfree(dsp->bin_file_name); +@@ -666,7 +666,7 @@ static ssize_t cs_dsp_debugfs_wmfw_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) + { +- struct wm_adsp *dsp = file->private_data; ++ struct cs_dsp *dsp = file->private_data; + ssize_t ret; + + mutex_lock(&dsp->pwr_lock); +@@ -686,7 +686,7 @@ static ssize_t cs_dsp_debugfs_bin_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) + { +- struct wm_adsp *dsp = file->private_data; ++ struct cs_dsp *dsp = file->private_data; + ssize_t ret; + + mutex_lock(&dsp->pwr_lock); +@@ -722,13 +722,13 @@ static const struct { + }, + }; + +-static void cs_dsp_init_debugfs(struct wm_adsp *dsp, +- struct snd_soc_component *component) ++static void cs_dsp_init_debugfs(struct cs_dsp *dsp, ++ struct dentry *debugfs_root) + { + struct dentry *root = NULL; + int i; + +- root = debugfs_create_dir(dsp->name, component->debugfs_root); ++ root = debugfs_create_dir(dsp->name, debugfs_root); + + debugfs_create_bool("booted", 0444, root, &dsp->booted); + debugfs_create_bool("running", 0444, root, &dsp->running); +@@ -742,33 +742,33 @@ static void cs_dsp_init_debugfs(struct wm_adsp *dsp, + dsp->debugfs_root = root; + } + +-static void cs_dsp_cleanup_debugfs(struct wm_adsp *dsp) ++static void cs_dsp_cleanup_debugfs(struct cs_dsp *dsp) + { + cs_dsp_debugfs_clear(dsp); + debugfs_remove_recursive(dsp->debugfs_root); + dsp->debugfs_root = NULL; + } + #else +-static inline void cs_dsp_init_debugfs(struct wm_adsp *dsp, +- struct snd_soc_component *component) ++static inline void cs_dsp_init_debugfs(struct cs_dsp *dsp, ++ struct dentry *debugfs_root) + { + } + +-static inline void cs_dsp_cleanup_debugfs(struct wm_adsp *dsp) ++static inline void cs_dsp_cleanup_debugfs(struct cs_dsp *dsp) + { + } + +-static inline void cs_dsp_debugfs_save_wmfwname(struct wm_adsp *dsp, +- const char *s) ++static inline void cs_dsp_debugfs_save_wmfwname(struct cs_dsp *dsp, ++ const char *s) + { + } + +-static inline void cs_dsp_debugfs_save_binname(struct wm_adsp *dsp, +- const char *s) ++static inline void cs_dsp_debugfs_save_binname(struct cs_dsp *dsp, ++ const char *s) + { + } + +-static inline void cs_dsp_debugfs_clear(struct wm_adsp *dsp) ++static inline void cs_dsp_debugfs_clear(struct cs_dsp *dsp) + { + } + #endif +@@ -800,14 +800,14 @@ int wm_adsp_fw_put(struct snd_kcontrol *kcontrol, + if (ucontrol->value.enumerated.item[0] >= WM_ADSP_NUM_FW) + return -EINVAL; + +- mutex_lock(&dsp[e->shift_l].pwr_lock); ++ mutex_lock(&dsp[e->shift_l].cs_dsp.pwr_lock); + +- if (dsp[e->shift_l].booted || !list_empty(&dsp[e->shift_l].compr_list)) ++ if (dsp[e->shift_l].cs_dsp.booted || !list_empty(&dsp[e->shift_l].compr_list)) + ret = -EBUSY; + else + dsp[e->shift_l].fw = ucontrol->value.enumerated.item[0]; + +- mutex_unlock(&dsp[e->shift_l].pwr_lock); ++ mutex_unlock(&dsp[e->shift_l].cs_dsp.pwr_lock); + + return ret; + } +@@ -824,7 +824,7 @@ const struct soc_enum wm_adsp_fw_enum[] = { + }; + EXPORT_SYMBOL_GPL(wm_adsp_fw_enum); + +-static const struct cs_dsp_region *cs_dsp_find_region(struct wm_adsp *dsp, ++static const struct cs_dsp_region *cs_dsp_find_region(struct cs_dsp *dsp, + int type) + { + int i; +@@ -871,7 +871,7 @@ static unsigned int cs_dsp_halo_region_to_reg(struct cs_dsp_region const *mem, + } + } + +-static void cs_dsp_read_fw_status(struct wm_adsp *dsp, ++static void cs_dsp_read_fw_status(struct cs_dsp *dsp, + int noffs, unsigned int *offs) + { + unsigned int i; +@@ -886,7 +886,7 @@ static void cs_dsp_read_fw_status(struct wm_adsp *dsp, + } + } + +-static void cs_dsp_adsp2_show_fw_status(struct wm_adsp *dsp) ++static void cs_dsp_adsp2_show_fw_status(struct cs_dsp *dsp) + { + unsigned int offs[] = { + ADSP2_SCRATCH0, ADSP2_SCRATCH1, ADSP2_SCRATCH2, ADSP2_SCRATCH3, +@@ -898,7 +898,7 @@ static void cs_dsp_adsp2_show_fw_status(struct wm_adsp *dsp) + offs[0], offs[1], offs[2], offs[3]); + } + +-static void cs_dsp_adsp2v2_show_fw_status(struct wm_adsp *dsp) ++static void cs_dsp_adsp2v2_show_fw_status(struct cs_dsp *dsp) + { + unsigned int offs[] = { ADSP2V2_SCRATCH0_1, ADSP2V2_SCRATCH2_3 }; + +@@ -909,7 +909,7 @@ static void cs_dsp_adsp2v2_show_fw_status(struct wm_adsp *dsp) + offs[1] & 0xFFFF, offs[1] >> 16); + } + +-static void cs_dsp_halo_show_fw_status(struct wm_adsp *dsp) ++static void cs_dsp_halo_show_fw_status(struct cs_dsp *dsp) + { + unsigned int offs[] = { + HALO_SCRATCH1, HALO_SCRATCH2, HALO_SCRATCH3, HALO_SCRATCH4, +@@ -929,7 +929,7 @@ static inline struct wm_coeff_ctl *bytes_ext_to_ctl(struct soc_bytes_ext *ext) + static int cs_dsp_coeff_base_reg(struct cs_dsp_coeff_ctl *ctl, unsigned int *reg) + { + const struct cs_dsp_alg_region *alg_region = &ctl->alg_region; +- struct wm_adsp *dsp = ctl->dsp; ++ struct cs_dsp *dsp = ctl->dsp; + const struct cs_dsp_region *mem; + + mem = cs_dsp_find_region(dsp, alg_region->type); +@@ -972,7 +972,7 @@ static int wm_coeff_info(struct snd_kcontrol *kctl, + static int cs_dsp_coeff_write_acked_control(struct cs_dsp_coeff_ctl *ctl, + unsigned int event_id) + { +- struct wm_adsp *dsp = ctl->dsp; ++ struct cs_dsp *dsp = ctl->dsp; + __be32 val = cpu_to_be32(event_id); + unsigned int reg; + int i, ret; +@@ -1035,7 +1035,7 @@ static int cs_dsp_coeff_write_acked_control(struct cs_dsp_coeff_ctl *ctl, + static int cs_dsp_coeff_write_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, + const void *buf, size_t len) + { +- struct wm_adsp *dsp = ctl->dsp; ++ struct cs_dsp *dsp = ctl->dsp; + void *scratch; + int ret; + unsigned int reg; +@@ -1146,7 +1146,7 @@ static int wm_coeff_put_acked(struct snd_kcontrol *kctl, + static int cs_dsp_coeff_read_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, + void *buf, size_t len) + { +- struct wm_adsp *dsp = ctl->dsp; ++ struct cs_dsp *dsp = ctl->dsp; + void *scratch; + int ret; + unsigned int reg; +@@ -1325,7 +1325,7 @@ static int wmfw_add_ctl(struct wm_adsp *dsp, struct wm_coeff_ctl *ctl) + return ret; + } + +-static int cs_dsp_coeff_init_control_caches(struct wm_adsp *dsp) ++static int cs_dsp_coeff_init_control_caches(struct cs_dsp *dsp) + { + struct cs_dsp_coeff_ctl *ctl; + int ret; +@@ -1351,7 +1351,7 @@ static int cs_dsp_coeff_init_control_caches(struct wm_adsp *dsp) + return 0; + } + +-static int cs_dsp_coeff_sync_controls(struct wm_adsp *dsp) ++static int cs_dsp_coeff_sync_controls(struct cs_dsp *dsp) + { + struct cs_dsp_coeff_ctl *ctl; + int ret; +@@ -1370,8 +1370,8 @@ static int cs_dsp_coeff_sync_controls(struct wm_adsp *dsp) + return 0; + } + +-static void cs_dsp_signal_event_controls(struct wm_adsp *dsp, +- unsigned int event) ++static void cs_dsp_signal_event_controls(struct cs_dsp *dsp, ++ unsigned int event) + { + struct cs_dsp_coeff_ctl *ctl; + int ret; +@@ -1396,7 +1396,11 @@ static void wm_adsp_ctl_work(struct work_struct *work) + struct wm_coeff_ctl *ctl = container_of(work, + struct wm_coeff_ctl, + work); +- wmfw_add_ctl(ctl->cs_ctl->dsp, ctl); ++ struct wm_adsp *dsp = container_of(ctl->cs_ctl->dsp, ++ struct wm_adsp, ++ cs_dsp); ++ ++ wmfw_add_ctl(dsp, ctl); + } + + static void cs_dsp_free_ctl_blk(struct cs_dsp_coeff_ctl *ctl) +@@ -1408,7 +1412,8 @@ static void cs_dsp_free_ctl_blk(struct cs_dsp_coeff_ctl *ctl) + + static int wm_adsp_control_add(struct cs_dsp_coeff_ctl *cs_ctl) + { +- struct wm_adsp *dsp = cs_ctl->dsp; ++ struct wm_adsp *dsp = container_of(cs_ctl->dsp, struct wm_adsp, cs_dsp); ++ struct cs_dsp *cs_dsp = &dsp->cs_dsp; + struct wm_coeff_ctl *ctl; + char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; + const char *region_name; +@@ -1423,20 +1428,20 @@ static int wm_adsp_control_add(struct cs_dsp_coeff_ctl *cs_ctl) + return -EINVAL; + } + +- switch (dsp->fw_ver) { ++ switch (cs_dsp->fw_ver) { + case 0: + case 1: + snprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s %s %x", +- dsp->name, region_name, cs_ctl->alg_region.alg); ++ cs_dsp->name, region_name, cs_ctl->alg_region.alg); + break; + case 2: + ret = scnprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, +- "%s%c %.12s %x", dsp->name, *region_name, ++ "%s%c %.12s %x", cs_dsp->name, *region_name, + wm_adsp_fw_text[dsp->fw], cs_ctl->alg_region.alg); + break; + default: + ret = scnprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, +- "%s %.12s %x", dsp->name, ++ "%s %.12s %x", cs_dsp->name, + wm_adsp_fw_text[dsp->fw], cs_ctl->alg_region.alg); + break; + } +@@ -1490,7 +1495,7 @@ static void wm_adsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl) + kfree(ctl); + } + +-static int cs_dsp_create_control(struct wm_adsp *dsp, ++static int cs_dsp_create_control(struct cs_dsp *dsp, + const struct cs_dsp_alg_region *alg_region, + unsigned int offset, unsigned int len, + const char *subname, unsigned int subname_len, +@@ -1620,7 +1625,7 @@ static int cs_dsp_coeff_parse_int(int bytes, const u8 **pos) + return val; + } + +-static inline void cs_dsp_coeff_parse_alg(struct wm_adsp *dsp, const u8 **data, ++static inline void cs_dsp_coeff_parse_alg(struct cs_dsp *dsp, const u8 **data, + struct cs_dsp_coeff_parsed_alg *blk) + { + const struct wmfw_adsp_alg_data *raw; +@@ -1650,7 +1655,7 @@ static inline void cs_dsp_coeff_parse_alg(struct wm_adsp *dsp, const u8 **data, + cs_dsp_dbg(dsp, "# of coefficient descriptors: %#x\n", blk->ncoeff); + } + +-static inline void cs_dsp_coeff_parse_coeff(struct wm_adsp *dsp, const u8 **data, ++static inline void cs_dsp_coeff_parse_coeff(struct cs_dsp *dsp, const u8 **data, + struct cs_dsp_coeff_parsed_coeff *blk) + { + const struct wmfw_adsp_coeff_data *raw; +@@ -1696,7 +1701,7 @@ static inline void cs_dsp_coeff_parse_coeff(struct wm_adsp *dsp, const u8 **data + cs_dsp_dbg(dsp, "\tALSA control len: %#x\n", blk->len); + } + +-static int cs_dsp_check_coeff_flags(struct wm_adsp *dsp, ++static int cs_dsp_check_coeff_flags(struct cs_dsp *dsp, + const struct cs_dsp_coeff_parsed_coeff *coeff_blk, + unsigned int f_required, + unsigned int f_illegal) +@@ -1711,7 +1716,7 @@ static int cs_dsp_check_coeff_flags(struct wm_adsp *dsp, + return 0; + } + +-static int cs_dsp_parse_coeff(struct wm_adsp *dsp, ++static int cs_dsp_parse_coeff(struct cs_dsp *dsp, + const struct wmfw_region *region) + { + struct cs_dsp_alg_region alg_region = {}; +@@ -1782,7 +1787,7 @@ static int cs_dsp_parse_coeff(struct wm_adsp *dsp, + return 0; + } + +-static unsigned int cs_dsp_adsp1_parse_sizes(struct wm_adsp *dsp, ++static unsigned int cs_dsp_adsp1_parse_sizes(struct cs_dsp *dsp, + const char * const file, + unsigned int pos, + const struct firmware *firmware) +@@ -1818,6 +1823,7 @@ static int wm_adsp_request_firmware_file(struct wm_adsp *dsp, + char **filename, + char *suffix) + { ++ struct cs_dsp *cs_dsp = &dsp->cs_dsp; + int ret = 0; + + *filename = kasprintf(GFP_KERNEL, "%s-%s-%s.%s", dsp->part, dsp->fwf_name, +@@ -1825,7 +1831,7 @@ static int wm_adsp_request_firmware_file(struct wm_adsp *dsp, + if (*filename == NULL) + return -ENOMEM; + +- ret = request_firmware(firmware, *filename, dsp->dev); ++ ret = request_firmware(firmware, *filename, cs_dsp->dev); + if (ret != 0) { + adsp_err(dsp, "Failed to request '%s'\n", *filename); + kfree(*filename); +@@ -1852,7 +1858,7 @@ static int wm_adsp_request_firmware_files(struct wm_adsp *dsp, + return 0; + } + +-static unsigned int cs_dsp_adsp2_parse_sizes(struct wm_adsp *dsp, ++static unsigned int cs_dsp_adsp2_parse_sizes(struct cs_dsp *dsp, + const char * const file, + unsigned int pos, + const struct firmware *firmware) +@@ -1868,7 +1874,7 @@ static unsigned int cs_dsp_adsp2_parse_sizes(struct wm_adsp *dsp, + return pos + sizeof(*adsp2_sizes); + } + +-static bool cs_dsp_validate_version(struct wm_adsp *dsp, unsigned int version) ++static bool cs_dsp_validate_version(struct cs_dsp *dsp, unsigned int version) + { + switch (version) { + case 0: +@@ -1882,7 +1888,7 @@ static bool cs_dsp_validate_version(struct wm_adsp *dsp, unsigned int version) + } + } + +-static bool cs_dsp_halo_validate_version(struct wm_adsp *dsp, unsigned int version) ++static bool cs_dsp_halo_validate_version(struct cs_dsp *dsp, unsigned int version) + { + switch (version) { + case 3: +@@ -1892,7 +1898,7 @@ static bool cs_dsp_halo_validate_version(struct wm_adsp *dsp, unsigned int versi + } + } + +-static int cs_dsp_load(struct wm_adsp *dsp, const struct firmware *firmware, ++static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware, + const char *file) + { + LIST_HEAD(buf_list); +@@ -2082,7 +2088,7 @@ static int cs_dsp_load(struct wm_adsp *dsp, const struct firmware *firmware, + * Find cs_dsp_coeff_ctl with input name as its subname + * If not found, return NULL + */ +-static struct cs_dsp_coeff_ctl *cs_dsp_get_ctl(struct wm_adsp *dsp, ++static struct cs_dsp_coeff_ctl *cs_dsp_get_ctl(struct cs_dsp *dsp, + const char *name, int type, + unsigned int alg) + { +@@ -2112,7 +2118,7 @@ int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type, + char ctl_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; + int ret; + +- cs_ctl = cs_dsp_get_ctl(dsp, name, type, alg); ++ cs_ctl = cs_dsp_get_ctl(&dsp->cs_dsp, name, type, alg); + if (!cs_ctl) + return -EINVAL; + +@@ -2153,7 +2159,7 @@ int wm_adsp_read_ctl(struct wm_adsp *dsp, const char *name, int type, + { + struct cs_dsp_coeff_ctl *cs_ctl; + +- cs_ctl = cs_dsp_get_ctl(dsp, name, type, alg); ++ cs_ctl = cs_dsp_get_ctl(&dsp->cs_dsp, name, type, alg); + if (!cs_ctl) + return -EINVAL; + +@@ -2164,7 +2170,7 @@ int wm_adsp_read_ctl(struct wm_adsp *dsp, const char *name, int type, + } + EXPORT_SYMBOL_GPL(wm_adsp_read_ctl); + +-static void cs_dsp_ctl_fixup_base(struct wm_adsp *dsp, ++static void cs_dsp_ctl_fixup_base(struct cs_dsp *dsp, + const struct cs_dsp_alg_region *alg_region) + { + struct cs_dsp_coeff_ctl *ctl; +@@ -2178,7 +2184,7 @@ static void cs_dsp_ctl_fixup_base(struct wm_adsp *dsp, + } + } + +-static void *cs_dsp_read_algs(struct wm_adsp *dsp, size_t n_algs, ++static void *cs_dsp_read_algs(struct cs_dsp *dsp, size_t n_algs, + const struct cs_dsp_region *mem, + unsigned int pos, unsigned int len) + { +@@ -2231,7 +2237,7 @@ static void *cs_dsp_read_algs(struct wm_adsp *dsp, size_t n_algs, + } + + static struct cs_dsp_alg_region * +- cs_dsp_find_alg_region(struct wm_adsp *dsp, int type, unsigned int id) ++ cs_dsp_find_alg_region(struct cs_dsp *dsp, int type, unsigned int id) + { + struct cs_dsp_alg_region *alg_region; + +@@ -2243,7 +2249,7 @@ static struct cs_dsp_alg_region * + return NULL; + } + +-static struct cs_dsp_alg_region *cs_dsp_create_region(struct wm_adsp *dsp, ++static struct cs_dsp_alg_region *cs_dsp_create_region(struct cs_dsp *dsp, + int type, __be32 id, + __be32 base) + { +@@ -2265,7 +2271,7 @@ static struct cs_dsp_alg_region *cs_dsp_create_region(struct wm_adsp *dsp, + return alg_region; + } + +-static void cs_dsp_free_alg_regions(struct wm_adsp *dsp) ++static void cs_dsp_free_alg_regions(struct cs_dsp *dsp) + { + struct cs_dsp_alg_region *alg_region; + +@@ -2278,7 +2284,7 @@ static void cs_dsp_free_alg_regions(struct wm_adsp *dsp) + } + } + +-static void cs_dsp_parse_wmfw_id_header(struct wm_adsp *dsp, ++static void cs_dsp_parse_wmfw_id_header(struct cs_dsp *dsp, + struct wmfw_id_hdr *fw, int nalgs) + { + dsp->fw_id = be32_to_cpu(fw->id); +@@ -2290,7 +2296,7 @@ static void cs_dsp_parse_wmfw_id_header(struct wm_adsp *dsp, + nalgs); + } + +-static void cs_dsp_parse_wmfw_v3_id_header(struct wm_adsp *dsp, ++static void cs_dsp_parse_wmfw_v3_id_header(struct cs_dsp *dsp, + struct wmfw_v3_id_hdr *fw, int nalgs) + { + dsp->fw_id = be32_to_cpu(fw->id); +@@ -2304,7 +2310,7 @@ static void cs_dsp_parse_wmfw_v3_id_header(struct wm_adsp *dsp, + nalgs); + } + +-static int cs_dsp_create_regions(struct wm_adsp *dsp, __be32 id, int nregions, ++static int cs_dsp_create_regions(struct cs_dsp *dsp, __be32 id, int nregions, + const int *type, __be32 *base) + { + struct cs_dsp_alg_region *alg_region; +@@ -2319,7 +2325,7 @@ static int cs_dsp_create_regions(struct wm_adsp *dsp, __be32 id, int nregions, + return 0; + } + +-static int cs_dsp_adsp1_setup_algs(struct wm_adsp *dsp) ++static int cs_dsp_adsp1_setup_algs(struct cs_dsp *dsp) + { + struct wmfw_adsp1_id_hdr adsp1_id; + struct wmfw_adsp1_alg_hdr *adsp1_alg; +@@ -2420,7 +2426,7 @@ static int cs_dsp_adsp1_setup_algs(struct wm_adsp *dsp) + return ret; + } + +-static int cs_dsp_adsp2_setup_algs(struct wm_adsp *dsp) ++static int cs_dsp_adsp2_setup_algs(struct cs_dsp *dsp) + { + struct wmfw_adsp2_id_hdr adsp2_id; + struct wmfw_adsp2_alg_hdr *adsp2_alg; +@@ -2549,7 +2555,7 @@ static int cs_dsp_adsp2_setup_algs(struct wm_adsp *dsp) + return ret; + } + +-static int cs_dsp_halo_create_regions(struct wm_adsp *dsp, __be32 id, ++static int cs_dsp_halo_create_regions(struct cs_dsp *dsp, __be32 id, + __be32 xm_base, __be32 ym_base) + { + static const int types[] = { +@@ -2561,7 +2567,7 @@ static int cs_dsp_halo_create_regions(struct wm_adsp *dsp, __be32 id, + return cs_dsp_create_regions(dsp, id, ARRAY_SIZE(types), types, bases); + } + +-static int cs_dsp_halo_setup_algs(struct wm_adsp *dsp) ++static int cs_dsp_halo_setup_algs(struct cs_dsp *dsp) + { + struct wmfw_halo_id_hdr halo_id; + struct wmfw_halo_alg_hdr *halo_alg; +@@ -2621,7 +2627,7 @@ static int cs_dsp_halo_setup_algs(struct wm_adsp *dsp) + return ret; + } + +-static int cs_dsp_load_coeff(struct wm_adsp *dsp, const struct firmware *firmware, ++static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware, + const char *file) + { + LIST_HEAD(buf_list); +@@ -2800,10 +2806,8 @@ static int cs_dsp_load_coeff(struct wm_adsp *dsp, const struct firmware *firmwar + return ret; + } + +-static int cs_dsp_create_name(struct wm_adsp *dsp) ++static int cs_dsp_create_name(struct cs_dsp *dsp) + { +- char *p; +- + if (!dsp->name) { + dsp->name = devm_kasprintf(dsp->dev, GFP_KERNEL, "DSP%d", + dsp->num); +@@ -2811,20 +2815,10 @@ static int cs_dsp_create_name(struct wm_adsp *dsp) + return -ENOMEM; + } + +- if (!dsp->fwf_name) { +- p = devm_kstrdup(dsp->dev, dsp->name, GFP_KERNEL); +- if (!p) +- return -ENOMEM; +- +- dsp->fwf_name = p; +- for (; *p != 0; ++p) +- *p = tolower(*p); +- } +- + return 0; + } + +-static int cs_dsp_common_init(struct wm_adsp *dsp) ++static int cs_dsp_common_init(struct cs_dsp *dsp) + { + int ret; + +@@ -2840,13 +2834,27 @@ static int cs_dsp_common_init(struct wm_adsp *dsp) + return 0; + } + +-static void wm_adsp_common_init(struct wm_adsp *dsp) ++static int wm_adsp_common_init(struct wm_adsp *dsp) + { ++ char *p; ++ + INIT_LIST_HEAD(&dsp->compr_list); + INIT_LIST_HEAD(&dsp->buffer_list); ++ ++ if (!dsp->fwf_name) { ++ p = devm_kstrdup(dsp->cs_dsp.dev, dsp->cs_dsp.name, GFP_KERNEL); ++ if (!p) ++ return -ENOMEM; ++ ++ dsp->fwf_name = p; ++ for (; *p != 0; ++p) ++ *p = tolower(*p); ++ } ++ ++ return 0; + } + +-static int cs_dsp_adsp1_init(struct wm_adsp *dsp) ++static int cs_dsp_adsp1_init(struct cs_dsp *dsp) + { + dsp->ops = &cs_dsp_adsp1_ops; + +@@ -2855,13 +2863,17 @@ static int cs_dsp_adsp1_init(struct wm_adsp *dsp) + + int wm_adsp1_init(struct wm_adsp *dsp) + { +- wm_adsp_common_init(dsp); ++ int ret; + +- return cs_dsp_adsp1_init(dsp); ++ ret = cs_dsp_adsp1_init(&dsp->cs_dsp); ++ if (ret) ++ return ret; ++ ++ return wm_adsp_common_init(dsp); + } + EXPORT_SYMBOL_GPL(wm_adsp1_init); + +-static int cs_dsp_adsp1_power_up(struct wm_adsp *dsp, ++static int cs_dsp_adsp1_power_up(struct cs_dsp *dsp, + const struct firmware *wmfw_firmware, char *wmfw_filename, + const struct firmware *coeff_firmware, char *coeff_filename, + const char *fw_name) +@@ -2941,7 +2953,7 @@ static int cs_dsp_adsp1_power_up(struct wm_adsp *dsp, + return ret; + } + +-static void cs_dsp_adsp1_power_down(struct wm_adsp *dsp) ++static void cs_dsp_adsp1_power_down(struct cs_dsp *dsp) + { + struct cs_dsp_coeff_ctl *ctl; + +@@ -2991,7 +3003,7 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, + if (ret) + break; + +- ret = cs_dsp_adsp1_power_up(dsp, ++ ret = cs_dsp_adsp1_power_up(&dsp->cs_dsp, + wmfw_firmware, wmfw_filename, + coeff_firmware, coeff_filename, + wm_adsp_fw_text[dsp->fw]); +@@ -3001,7 +3013,7 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, + coeff_firmware, coeff_filename); + break; + case SND_SOC_DAPM_PRE_PMD: +- cs_dsp_adsp1_power_down(dsp); ++ cs_dsp_adsp1_power_down(&dsp->cs_dsp); + break; + default: + break; +@@ -3011,7 +3023,7 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, + } + EXPORT_SYMBOL_GPL(wm_adsp1_event); + +-static int cs_dsp_adsp2v2_enable_core(struct wm_adsp *dsp) ++static int cs_dsp_adsp2v2_enable_core(struct cs_dsp *dsp) + { + unsigned int val; + int ret, count; +@@ -3038,7 +3050,7 @@ static int cs_dsp_adsp2v2_enable_core(struct wm_adsp *dsp) + return 0; + } + +-static int cs_dsp_adsp2_enable_core(struct wm_adsp *dsp) ++static int cs_dsp_adsp2_enable_core(struct cs_dsp *dsp) + { + int ret; + +@@ -3050,7 +3062,7 @@ static int cs_dsp_adsp2_enable_core(struct wm_adsp *dsp) + return cs_dsp_adsp2v2_enable_core(dsp); + } + +-static int cs_dsp_adsp2_lock(struct wm_adsp *dsp, unsigned int lock_regions) ++static int cs_dsp_adsp2_lock(struct cs_dsp *dsp, unsigned int lock_regions) + { + struct regmap *regmap = dsp->regmap; + unsigned int code0, code1, lock_reg; +@@ -3080,19 +3092,19 @@ static int cs_dsp_adsp2_lock(struct wm_adsp *dsp, unsigned int lock_regions) + return 0; + } + +-static int cs_dsp_adsp2_enable_memory(struct wm_adsp *dsp) ++static int cs_dsp_adsp2_enable_memory(struct cs_dsp *dsp) + { + return regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_MEM_ENA, ADSP2_MEM_ENA); + } + +-static void cs_dsp_adsp2_disable_memory(struct wm_adsp *dsp) ++static void cs_dsp_adsp2_disable_memory(struct cs_dsp *dsp) + { + regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_MEM_ENA, 0); + } + +-static void cs_dsp_adsp2_disable_core(struct wm_adsp *dsp) ++static void cs_dsp_adsp2_disable_core(struct cs_dsp *dsp) + { + regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0); + regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0); +@@ -3102,14 +3114,14 @@ static void cs_dsp_adsp2_disable_core(struct wm_adsp *dsp) + ADSP2_SYS_ENA, 0); + } + +-static void cs_dsp_adsp2v2_disable_core(struct wm_adsp *dsp) ++static void cs_dsp_adsp2v2_disable_core(struct cs_dsp *dsp) + { + regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0); + regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0); + regmap_write(dsp->regmap, dsp->base + ADSP2V2_WDMA_CONFIG_2, 0); + } + +-static int cs_dsp_halo_configure_mpu(struct wm_adsp *dsp, unsigned int lock_regions) ++static int cs_dsp_halo_configure_mpu(struct cs_dsp *dsp, unsigned int lock_regions) + { + struct reg_sequence config[] = { + { dsp->base + HALO_MPU_LOCK_CONFIG, 0x5555 }, +@@ -3140,7 +3152,7 @@ static int cs_dsp_halo_configure_mpu(struct wm_adsp *dsp, unsigned int lock_regi + return regmap_multi_reg_write(dsp->regmap, config, ARRAY_SIZE(config)); + } + +-static int cs_dsp_set_dspclk(struct wm_adsp *dsp, unsigned int freq) ++static int cs_dsp_set_dspclk(struct cs_dsp *dsp, unsigned int freq) + { + int ret; + +@@ -3159,7 +3171,7 @@ int wm_adsp2_set_dspclk(struct snd_soc_dapm_widget *w, unsigned int freq) + struct wm_adsp *dsps = snd_soc_component_get_drvdata(component); + struct wm_adsp *dsp = &dsps[w->shift]; + +- return cs_dsp_set_dspclk(dsp, freq); ++ return cs_dsp_set_dspclk(&dsp->cs_dsp, freq); + } + EXPORT_SYMBOL_GPL(wm_adsp2_set_dspclk); + +@@ -3189,7 +3201,7 @@ int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol, + struct wm_adsp *dsp = &dsps[mc->shift - 1]; + char preload[32]; + +- snprintf(preload, ARRAY_SIZE(preload), "%s Preload", dsp->name); ++ snprintf(preload, ARRAY_SIZE(preload), "%s Preload", dsp->cs_dsp.name); + + dsp->preloaded = ucontrol->value.integer.value[0]; + +@@ -3206,19 +3218,19 @@ int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol, + } + EXPORT_SYMBOL_GPL(wm_adsp2_preloader_put); + +-static void cs_dsp_stop_watchdog(struct wm_adsp *dsp) ++static void cs_dsp_stop_watchdog(struct cs_dsp *dsp) + { + regmap_update_bits(dsp->regmap, dsp->base + ADSP2_WATCHDOG, + ADSP2_WDT_ENA_MASK, 0); + } + +-static void cs_dsp_halo_stop_watchdog(struct wm_adsp *dsp) ++static void cs_dsp_halo_stop_watchdog(struct cs_dsp *dsp) + { + regmap_update_bits(dsp->regmap, dsp->base + HALO_WDT_CONTROL, + HALO_WDT_EN_MASK, 0); + } + +-static int cs_dsp_power_up(struct wm_adsp *dsp, ++static int cs_dsp_power_up(struct cs_dsp *dsp, + const struct firmware *wmfw_firmware, char *wmfw_filename, + const struct firmware *coeff_firmware, char *coeff_filename, + const char *fw_name) +@@ -3278,7 +3290,7 @@ static int cs_dsp_power_up(struct wm_adsp *dsp, + return ret; + } + +-static void cs_dsp_power_down(struct wm_adsp *dsp) ++static void cs_dsp_power_down(struct cs_dsp *dsp) + { + struct cs_dsp_coeff_ctl *ctl; + +@@ -3321,7 +3333,7 @@ static void wm_adsp_boot_work(struct work_struct *work) + if (ret) + return; + +- cs_dsp_power_up(dsp, ++ cs_dsp_power_up(&dsp->cs_dsp, + wmfw_firmware, wmfw_filename, + coeff_firmware, coeff_filename, + wm_adsp_fw_text[dsp->fw]); +@@ -3343,7 +3355,7 @@ int wm_adsp_early_event(struct snd_soc_dapm_widget *w, + queue_work(system_unbound_wq, &dsp->boot_work); + break; + case SND_SOC_DAPM_PRE_PMD: +- cs_dsp_power_down(dsp); ++ cs_dsp_power_down(&dsp->cs_dsp); + break; + default: + break; +@@ -3353,36 +3365,40 @@ int wm_adsp_early_event(struct snd_soc_dapm_widget *w, + } + EXPORT_SYMBOL_GPL(wm_adsp_early_event); + +-static int cs_dsp_adsp2_start_core(struct wm_adsp *dsp) ++static int cs_dsp_adsp2_start_core(struct cs_dsp *dsp) + { + return regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_CORE_ENA | ADSP2_START, + ADSP2_CORE_ENA | ADSP2_START); + } + +-static void cs_dsp_adsp2_stop_core(struct wm_adsp *dsp) ++static void cs_dsp_adsp2_stop_core(struct cs_dsp *dsp) + { + regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_CORE_ENA | ADSP2_START, 0); + } + +-static int wm_adsp_event_post_run(struct wm_adsp *dsp) ++static int wm_adsp_event_post_run(struct cs_dsp *cs_dsp) + { ++ struct wm_adsp *dsp = container_of(cs_dsp, struct wm_adsp, cs_dsp); ++ + if (wm_adsp_fw[dsp->fw].num_caps != 0) + return wm_adsp_buffer_init(dsp); + + return 0; + } + +-static void wm_adsp_event_post_stop(struct wm_adsp *dsp) ++static void wm_adsp_event_post_stop(struct cs_dsp *cs_dsp) + { ++ struct wm_adsp *dsp = container_of(cs_dsp, struct wm_adsp, cs_dsp); ++ + if (wm_adsp_fw[dsp->fw].num_caps != 0) + wm_adsp_buffer_free(dsp); + + dsp->fatal_error = false; + } + +-static int cs_dsp_run(struct wm_adsp *dsp) ++static int cs_dsp_run(struct cs_dsp *dsp) + { + int ret; + +@@ -3438,7 +3454,7 @@ static int cs_dsp_run(struct wm_adsp *dsp) + return ret; + } + +-static void cs_dsp_stop(struct wm_adsp *dsp) ++static void cs_dsp_stop(struct cs_dsp *dsp) + { + /* Tell the firmware to cleanup */ + cs_dsp_signal_event_controls(dsp, CS_DSP_FW_EVENT_SHUTDOWN); +@@ -3477,10 +3493,10 @@ int wm_adsp_event(struct snd_soc_dapm_widget *w, + switch (event) { + case SND_SOC_DAPM_POST_PMU: + flush_work(&dsp->boot_work); +- ret = cs_dsp_run(dsp); ++ ret = cs_dsp_run(&dsp->cs_dsp); + break; + case SND_SOC_DAPM_PRE_PMD: +- cs_dsp_stop(dsp); ++ cs_dsp_stop(&dsp->cs_dsp); + break; + default: + break; +@@ -3490,7 +3506,7 @@ int wm_adsp_event(struct snd_soc_dapm_widget *w, + } + EXPORT_SYMBOL_GPL(wm_adsp_event); + +-static int cs_dsp_halo_start_core(struct wm_adsp *dsp) ++static int cs_dsp_halo_start_core(struct cs_dsp *dsp) + { + return regmap_update_bits(dsp->regmap, + dsp->base + HALO_CCM_CORE_CONTROL, +@@ -3498,7 +3514,7 @@ static int cs_dsp_halo_start_core(struct wm_adsp *dsp) + HALO_CORE_RESET | HALO_CORE_EN); + } + +-static void cs_dsp_halo_stop_core(struct wm_adsp *dsp) ++static void cs_dsp_halo_stop_core(struct cs_dsp *dsp) + { + regmap_update_bits(dsp->regmap, dsp->base + HALO_CCM_CORE_CONTROL, + HALO_CORE_EN, 0); +@@ -3512,10 +3528,10 @@ int wm_adsp2_component_probe(struct wm_adsp *dsp, struct snd_soc_component *comp + { + char preload[32]; + +- snprintf(preload, ARRAY_SIZE(preload), "%s Preload", dsp->name); ++ snprintf(preload, ARRAY_SIZE(preload), "%s Preload", dsp->cs_dsp.name); + snd_soc_component_disable_pin(component, preload); + +- cs_dsp_init_debugfs(dsp, component); ++ cs_dsp_init_debugfs(&dsp->cs_dsp, component->debugfs_root); + + dsp->component = component; + +@@ -3525,13 +3541,13 @@ EXPORT_SYMBOL_GPL(wm_adsp2_component_probe); + + int wm_adsp2_component_remove(struct wm_adsp *dsp, struct snd_soc_component *component) + { +- cs_dsp_cleanup_debugfs(dsp); ++ cs_dsp_cleanup_debugfs(&dsp->cs_dsp); + + return 0; + } + EXPORT_SYMBOL_GPL(wm_adsp2_component_remove); + +-static int cs_dsp_adsp2_init(struct wm_adsp *dsp) ++static int cs_dsp_adsp2_init(struct cs_dsp *dsp) + { + int ret; + +@@ -3564,17 +3580,21 @@ static int cs_dsp_adsp2_init(struct wm_adsp *dsp) + + int wm_adsp2_init(struct wm_adsp *dsp) + { ++ int ret; ++ + INIT_WORK(&dsp->boot_work, wm_adsp_boot_work); + + dsp->sys_config_size = sizeof(struct wm_adsp_system_config_xm_hdr); + +- wm_adsp_common_init(dsp); ++ ret = cs_dsp_adsp2_init(&dsp->cs_dsp); ++ if (ret) ++ return ret; + +- return cs_dsp_adsp2_init(dsp); ++ return wm_adsp_common_init(dsp); + } + EXPORT_SYMBOL_GPL(wm_adsp2_init); + +-static int cs_dsp_halo_init(struct wm_adsp *dsp) ++static int cs_dsp_halo_init(struct cs_dsp *dsp) + { + dsp->ops = &cs_dsp_halo_ops; + +@@ -3583,17 +3603,21 @@ static int cs_dsp_halo_init(struct wm_adsp *dsp) + + int wm_halo_init(struct wm_adsp *dsp) + { ++ int ret; ++ + INIT_WORK(&dsp->boot_work, wm_adsp_boot_work); + + dsp->sys_config_size = sizeof(struct wm_halo_system_config_xm_hdr); + +- wm_adsp_common_init(dsp); ++ ret = cs_dsp_halo_init(&dsp->cs_dsp); ++ if (ret) ++ return ret; + +- return cs_dsp_halo_init(dsp); ++ return wm_adsp_common_init(dsp); + } + EXPORT_SYMBOL_GPL(wm_halo_init); + +-static void cs_dsp_remove(struct wm_adsp *dsp) ++static void cs_dsp_remove(struct cs_dsp *dsp) + { + struct cs_dsp_coeff_ctl *ctl; + +@@ -3609,7 +3633,7 @@ static void cs_dsp_remove(struct wm_adsp *dsp) + + void wm_adsp2_remove(struct wm_adsp *dsp) + { +- cs_dsp_remove(dsp); ++ cs_dsp_remove(&dsp->cs_dsp); + } + EXPORT_SYMBOL_GPL(wm_adsp2_remove); + +@@ -3662,7 +3686,7 @@ int wm_adsp_compr_open(struct wm_adsp *dsp, struct snd_compr_stream *stream) + struct snd_soc_pcm_runtime *rtd = stream->private_data; + int ret = 0; + +- mutex_lock(&dsp->pwr_lock); ++ mutex_lock(&dsp->cs_dsp.pwr_lock); + + if (wm_adsp_fw[dsp->fw].num_caps == 0) { + adsp_err(dsp, "%s: Firmware does not support compressed API\n", +@@ -3702,7 +3726,7 @@ int wm_adsp_compr_open(struct wm_adsp *dsp, struct snd_compr_stream *stream) + stream->runtime->private_data = compr; + + out: +- mutex_unlock(&dsp->pwr_lock); ++ mutex_unlock(&dsp->cs_dsp.pwr_lock); + + return ret; + } +@@ -3714,7 +3738,7 @@ int wm_adsp_compr_free(struct snd_soc_component *component, + struct wm_adsp_compr *compr = stream->runtime->private_data; + struct wm_adsp *dsp = compr->dsp; + +- mutex_lock(&dsp->pwr_lock); ++ mutex_lock(&dsp->cs_dsp.pwr_lock); + + wm_adsp_compr_detach(compr); + list_del(&compr->list); +@@ -3722,7 +3746,7 @@ int wm_adsp_compr_free(struct snd_soc_component *component, + kfree(compr->raw_buf); + kfree(compr); + +- mutex_unlock(&dsp->pwr_lock); ++ mutex_unlock(&dsp->cs_dsp.pwr_lock); + + return 0; + } +@@ -3836,7 +3860,7 @@ int wm_adsp_compr_get_caps(struct snd_soc_component *component, + } + EXPORT_SYMBOL_GPL(wm_adsp_compr_get_caps); + +-static int cs_dsp_read_raw_data_block(struct wm_adsp *dsp, int mem_type, ++static int cs_dsp_read_raw_data_block(struct cs_dsp *dsp, int mem_type, + unsigned int mem_addr, + unsigned int num_words, __be32 *data) + { +@@ -3857,8 +3881,8 @@ static int cs_dsp_read_raw_data_block(struct wm_adsp *dsp, int mem_type, + return 0; + } + +-static inline int cs_dsp_read_data_word(struct wm_adsp *dsp, int mem_type, +- unsigned int mem_addr, u32 *data) ++static int cs_dsp_read_data_word(struct cs_dsp *dsp, int mem_type, ++ unsigned int mem_addr, u32 *data) + { + __be32 raw; + int ret; +@@ -3872,7 +3896,7 @@ static inline int cs_dsp_read_data_word(struct wm_adsp *dsp, int mem_type, + return 0; + } + +-static int cs_dsp_write_data_word(struct wm_adsp *dsp, int mem_type, ++static int cs_dsp_write_data_word(struct cs_dsp *dsp, int mem_type, + unsigned int mem_addr, u32 data) + { + struct cs_dsp_region const *mem = cs_dsp_find_region(dsp, mem_type); +@@ -3890,15 +3914,16 @@ static int cs_dsp_write_data_word(struct wm_adsp *dsp, int mem_type, + static inline int wm_adsp_buffer_read(struct wm_adsp_compr_buf *buf, + unsigned int field_offset, u32 *data) + { +- return cs_dsp_read_data_word(buf->dsp, buf->host_buf_mem_type, ++ return cs_dsp_read_data_word(&buf->dsp->cs_dsp, buf->host_buf_mem_type, + buf->host_buf_ptr + field_offset, data); + } + + static inline int wm_adsp_buffer_write(struct wm_adsp_compr_buf *buf, + unsigned int field_offset, u32 data) + { +- return cs_dsp_write_data_word(buf->dsp, buf->host_buf_mem_type, +- buf->host_buf_ptr + field_offset, data); ++ return cs_dsp_write_data_word(&buf->dsp->cs_dsp, buf->host_buf_mem_type, ++ buf->host_buf_ptr + field_offset, ++ data); + } + + static void cs_dsp_remove_padding(u32 *buf, int nwords) +@@ -3990,7 +4015,7 @@ static int wm_adsp_buffer_parse_legacy(struct wm_adsp *dsp) + u32 xmalg, addr, magic; + int i, ret; + +- alg_region = cs_dsp_find_alg_region(dsp, WMFW_ADSP2_XM, dsp->fw_id); ++ alg_region = cs_dsp_find_alg_region(&dsp->cs_dsp, WMFW_ADSP2_XM, dsp->cs_dsp.fw_id); + if (!alg_region) { + adsp_err(dsp, "No algorithm region found\n"); + return -EINVAL; +@@ -4003,7 +4028,7 @@ static int wm_adsp_buffer_parse_legacy(struct wm_adsp *dsp) + xmalg = dsp->sys_config_size / sizeof(__be32); + + addr = alg_region->base + xmalg + ALG_XM_FIELD(magic); +- ret = cs_dsp_read_data_word(dsp, WMFW_ADSP2_XM, addr, &magic); ++ ret = cs_dsp_read_data_word(&dsp->cs_dsp, WMFW_ADSP2_XM, addr, &magic); + if (ret < 0) + return ret; + +@@ -4012,7 +4037,7 @@ static int wm_adsp_buffer_parse_legacy(struct wm_adsp *dsp) + + addr = alg_region->base + xmalg + ALG_XM_FIELD(host_buf_ptr); + for (i = 0; i < 5; ++i) { +- ret = cs_dsp_read_data_word(dsp, WMFW_ADSP2_XM, addr, ++ ret = cs_dsp_read_data_word(&dsp->cs_dsp, WMFW_ADSP2_XM, addr, + &buf->host_buf_ptr); + if (ret < 0) + return ret; +@@ -4041,7 +4066,7 @@ static int wm_adsp_buffer_parse_coeff(struct cs_dsp_coeff_ctl *cs_ctl) + { + struct wm_adsp_host_buf_coeff_v1 coeff_v1; + struct wm_adsp_compr_buf *buf; +- struct wm_adsp *dsp = cs_ctl->dsp; ++ struct wm_adsp *dsp = container_of(cs_ctl->dsp, struct wm_adsp, cs_dsp); + unsigned int version; + int ret, i; + +@@ -4107,7 +4132,7 @@ static int wm_adsp_buffer_init(struct wm_adsp *dsp) + struct cs_dsp_coeff_ctl *cs_ctl; + int ret; + +- list_for_each_entry(cs_ctl, &dsp->ctl_list, list) { ++ list_for_each_entry(cs_ctl, &dsp->cs_dsp.ctl_list, list) { + if (cs_ctl->type != WMFW_CTL_TYPE_HOST_BUFFER) + continue; + +@@ -4182,7 +4207,7 @@ int wm_adsp_compr_trigger(struct snd_soc_component *component, + + compr_dbg(compr, "Trigger: %d\n", cmd); + +- mutex_lock(&dsp->pwr_lock); ++ mutex_lock(&dsp->cs_dsp.pwr_lock); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: +@@ -4218,7 +4243,7 @@ int wm_adsp_compr_trigger(struct snd_soc_component *component, + break; + } + +- mutex_unlock(&dsp->pwr_lock); ++ mutex_unlock(&dsp->cs_dsp.pwr_lock); + + return ret; + } +@@ -4280,7 +4305,7 @@ int wm_adsp_compr_handle_irq(struct wm_adsp *dsp) + struct wm_adsp_compr *compr; + int ret = 0; + +- mutex_lock(&dsp->pwr_lock); ++ mutex_lock(&dsp->cs_dsp.pwr_lock); + + if (list_empty(&dsp->buffer_list)) { + ret = -ENODEV; +@@ -4318,7 +4343,7 @@ int wm_adsp_compr_handle_irq(struct wm_adsp *dsp) + } + + out: +- mutex_unlock(&dsp->pwr_lock); ++ mutex_unlock(&dsp->cs_dsp.pwr_lock); + + return ret; + } +@@ -4348,7 +4373,7 @@ int wm_adsp_compr_pointer(struct snd_soc_component *component, + + compr_dbg(compr, "Pointer request\n"); + +- mutex_lock(&dsp->pwr_lock); ++ mutex_lock(&dsp->cs_dsp.pwr_lock); + + buf = compr->buf; + +@@ -4392,7 +4417,7 @@ int wm_adsp_compr_pointer(struct snd_soc_component *component, + tstamp->sampling_rate = compr->sample_rate; + + out: +- mutex_unlock(&dsp->pwr_lock); ++ mutex_unlock(&dsp->cs_dsp.pwr_lock); + + return ret; + } +@@ -4430,7 +4455,7 @@ static int wm_adsp_buffer_capture_block(struct wm_adsp_compr *compr, int target) + return 0; + + /* Read data from DSP */ +- ret = cs_dsp_read_raw_data_block(buf->dsp, mem_type, adsp_addr, ++ ret = cs_dsp_read_raw_data_block(&buf->dsp->cs_dsp, mem_type, adsp_addr, + nwords, (__be32 *)compr->raw_buf); + if (ret < 0) + return ret; +@@ -4504,21 +4529,22 @@ int wm_adsp_compr_copy(struct snd_soc_component *component, + struct wm_adsp *dsp = compr->dsp; + int ret; + +- mutex_lock(&dsp->pwr_lock); ++ mutex_lock(&dsp->cs_dsp.pwr_lock); + + if (stream->direction == SND_COMPRESS_CAPTURE) + ret = wm_adsp_compr_read(compr, buf, count); + else + ret = -ENOTSUPP; + +- mutex_unlock(&dsp->pwr_lock); ++ mutex_unlock(&dsp->cs_dsp.pwr_lock); + + return ret; + } + EXPORT_SYMBOL_GPL(wm_adsp_compr_copy); + +-static void wm_adsp_fatal_error(struct wm_adsp *dsp) ++static void wm_adsp_fatal_error(struct cs_dsp *cs_dsp) + { ++ struct wm_adsp *dsp = container_of(cs_dsp, struct wm_adsp, cs_dsp); + struct wm_adsp_compr *compr; + + dsp->fatal_error = true; +@@ -4529,7 +4555,7 @@ static void wm_adsp_fatal_error(struct wm_adsp *dsp) + } + } + +-static void cs_dsp_adsp2_bus_error(struct wm_adsp *dsp) ++static void cs_dsp_adsp2_bus_error(struct cs_dsp *dsp) + { + unsigned int val; + struct regmap *regmap = dsp->regmap; +@@ -4595,13 +4621,13 @@ irqreturn_t wm_adsp2_bus_error(int irq, void *data) + { + struct wm_adsp *dsp = (struct wm_adsp *)data; + +- cs_dsp_adsp2_bus_error(dsp); ++ cs_dsp_adsp2_bus_error(&dsp->cs_dsp); + + return IRQ_HANDLED; + } + EXPORT_SYMBOL_GPL(wm_adsp2_bus_error); + +-static void cs_dsp_halo_bus_error(struct wm_adsp *dsp) ++static void cs_dsp_halo_bus_error(struct cs_dsp *dsp) + { + struct regmap *regmap = dsp->regmap; + unsigned int fault[6]; +@@ -4658,13 +4684,13 @@ irqreturn_t wm_halo_bus_error(int irq, void *data) + { + struct wm_adsp *dsp = (struct wm_adsp *)data; + +- cs_dsp_halo_bus_error(dsp); ++ cs_dsp_halo_bus_error(&dsp->cs_dsp); + + return IRQ_HANDLED; + } + EXPORT_SYMBOL_GPL(wm_halo_bus_error); + +-static void cs_dsp_halo_wdt_expire(struct wm_adsp *dsp) ++static void cs_dsp_halo_wdt_expire(struct cs_dsp *dsp) + { + mutex_lock(&dsp->pwr_lock); + +@@ -4680,7 +4706,7 @@ irqreturn_t wm_halo_wdt_expire(int irq, void *data) + { + struct wm_adsp *dsp = data; + +- cs_dsp_halo_wdt_expire(dsp); ++ cs_dsp_halo_wdt_expire(&dsp->cs_dsp); + + return IRQ_HANDLED; + } +diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h +index 3bad022c4bb1..5a70b6679fa3 100644 +--- a/sound/soc/codecs/wm_adsp.h ++++ b/sound/soc/codecs/wm_adsp.h +@@ -49,7 +49,6 @@ struct cs_dsp_alg_region { + unsigned int base; + }; + +-struct wm_adsp; + struct wm_adsp_compr; + struct wm_adsp_compr_buf; + struct cs_dsp_ops; +@@ -60,7 +59,7 @@ struct cs_dsp_coeff_ctl { + const char *subname; + unsigned int subname_len; + struct cs_dsp_alg_region alg_region; +- struct wm_adsp *dsp; ++ struct cs_dsp *dsp; + unsigned int enabled:1; + struct list_head list; + void *cache; +@@ -73,16 +72,13 @@ struct cs_dsp_coeff_ctl { + void *priv; + }; + +-struct wm_adsp { +- const char *part; ++struct cs_dsp { + const char *name; +- const char *fwf_name; + int rev; + int num; + int type; + struct device *dev; + struct regmap *regmap; +- struct snd_soc_component *component; + + const struct cs_dsp_ops *ops; + +@@ -102,23 +98,13 @@ struct wm_adsp { + const struct cs_dsp_region *mem; + int num_mems; + +- unsigned int sys_config_size; +- +- int fw; + int fw_ver; + +- bool preloaded; + bool booted; + bool running; +- bool fatal_error; + + struct list_head ctl_list; + +- struct work_struct boot_work; +- +- struct list_head compr_list; +- struct list_head buffer_list; +- + struct mutex pwr_lock; + + unsigned int lock_regions; +@@ -128,31 +114,49 @@ struct wm_adsp { + char *wmfw_file_name; + char *bin_file_name; + #endif ++}; + ++struct wm_adsp { ++ struct cs_dsp cs_dsp; ++ const char *part; ++ const char *fwf_name; ++ struct snd_soc_component *component; ++ ++ unsigned int sys_config_size; ++ ++ int fw; ++ ++ struct work_struct boot_work; ++ ++ bool preloaded; ++ bool fatal_error; ++ ++ struct list_head compr_list; ++ struct list_head buffer_list; + }; + + struct cs_dsp_ops { +- bool (*validate_version)(struct wm_adsp *dsp, unsigned int version); +- unsigned int (*parse_sizes)(struct wm_adsp *dsp, ++ bool (*validate_version)(struct cs_dsp *dsp, unsigned int version); ++ unsigned int (*parse_sizes)(struct cs_dsp *dsp, + const char * const file, + unsigned int pos, + const struct firmware *firmware); +- int (*setup_algs)(struct wm_adsp *dsp); ++ int (*setup_algs)(struct cs_dsp *dsp); + unsigned int (*region_to_reg)(struct cs_dsp_region const *mem, + unsigned int offset); + +- void (*show_fw_status)(struct wm_adsp *dsp); +- void (*stop_watchdog)(struct wm_adsp *dsp); ++ void (*show_fw_status)(struct cs_dsp *dsp); ++ void (*stop_watchdog)(struct cs_dsp *dsp); + +- int (*enable_memory)(struct wm_adsp *dsp); +- void (*disable_memory)(struct wm_adsp *dsp); +- int (*lock_memory)(struct wm_adsp *dsp, unsigned int lock_regions); ++ int (*enable_memory)(struct cs_dsp *dsp); ++ void (*disable_memory)(struct cs_dsp *dsp); ++ int (*lock_memory)(struct cs_dsp *dsp, unsigned int lock_regions); + +- int (*enable_core)(struct wm_adsp *dsp); +- void (*disable_core)(struct wm_adsp *dsp); ++ int (*enable_core)(struct cs_dsp *dsp); ++ void (*disable_core)(struct cs_dsp *dsp); + +- int (*start_core)(struct wm_adsp *dsp); +- void (*stop_core)(struct wm_adsp *dsp); ++ int (*start_core)(struct cs_dsp *dsp); ++ void (*stop_core)(struct cs_dsp *dsp); + }; + + #define WM_ADSP1(wname, num) \ +-- +2.35.3 + diff --git a/patches.suse/ASoC-wm_adsp-Switch-to-using-wm_coeff_read_ctrl-for-.patch b/patches.suse/ASoC-wm_adsp-Switch-to-using-wm_coeff_read_ctrl-for-.patch new file mode 100644 index 0000000..cc57bc5 --- /dev/null +++ b/patches.suse/ASoC-wm_adsp-Switch-to-using-wm_coeff_read_ctrl-for-.patch @@ -0,0 +1,103 @@ +From 04ae08596737c4d3872dfb6e617c918d9ecf073e Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Mon, 13 Sep 2021 17:00:44 +0100 +Subject: [PATCH] ASoC: wm_adsp: Switch to using wm_coeff_read_ctrl for compressed buffers +Git-commit: 04ae08596737c4d3872dfb6e617c918d9ecf073e +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +When parsing a compressed buffer from the firmware the driver currently +open codes reading the firmware coefficient containing the buffer +description. Improve this slightly by using the coefficient read +functions already provided by the wm_adsp driver. It is worth noting +this change requires the running variable to be set before +wm_adsp_buffer_init is called, however this is safe, since its all still +under the power lock and nothing in the compressed code gates itself on +running. + +Signed-off-by: Charles Keepax +Signed-off-by: Simon Trimmer +Link: https://lore.kernel.org/r/20210913160057.103842-4-simont@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/wm_adsp.c | 24 +++++++----------------- + 1 file changed, 7 insertions(+), 17 deletions(-) + +diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c +index b300af6fdd41..9c3d4b96fd7c 100644 +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -3277,14 +3277,14 @@ int wm_adsp_event(struct snd_soc_dapm_widget *w, + goto err; + } + ++ dsp->running = true; ++ + if (wm_adsp_fw[dsp->fw].num_caps != 0) { + ret = wm_adsp_buffer_init(dsp); + if (ret < 0) + goto err; + } + +- dsp->running = true; +- + mutex_unlock(&dsp->pwr_lock); + break; + +@@ -3869,26 +3869,21 @@ static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) + { + struct wm_adsp_host_buf_coeff_v1 coeff_v1; + struct wm_adsp_compr_buf *buf; +- unsigned int reg, version; +- __be32 bufp; ++ unsigned int version; + int ret, i; + +- ret = wm_coeff_base_reg(ctl, ®); +- if (ret) +- return ret; +- + for (i = 0; i < 5; ++i) { +- ret = regmap_raw_read(ctl->dsp->regmap, reg, &bufp, sizeof(bufp)); ++ ret = wm_coeff_read_ctrl(ctl, &coeff_v1, sizeof(coeff_v1)); + if (ret < 0) + return ret; + +- if (bufp) ++ if (coeff_v1.host_buf_ptr) + break; + + usleep_range(1000, 2000); + } + +- if (!bufp) { ++ if (!coeff_v1.host_buf_ptr) { + adsp_err(ctl->dsp, "Failed to acquire host buffer\n"); + return -EIO; + } +@@ -3898,7 +3893,7 @@ static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) + return -ENOMEM; + + buf->host_buf_mem_type = ctl->alg_region.type; +- buf->host_buf_ptr = be32_to_cpu(bufp); ++ buf->host_buf_ptr = be32_to_cpu(coeff_v1.host_buf_ptr); + + ret = wm_adsp_buffer_populate(buf); + if (ret < 0) +@@ -3913,11 +3908,6 @@ static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) + return 0; + } + +- ret = regmap_raw_read(ctl->dsp->regmap, reg, &coeff_v1, +- sizeof(coeff_v1)); +- if (ret < 0) +- return ret; +- + version = be32_to_cpu(coeff_v1.versions) & HOST_BUF_COEFF_COMPAT_VER_MASK; + version >>= HOST_BUF_COEFF_COMPAT_VER_SHIFT; + +-- +2.35.3 + diff --git a/patches.suse/ASoC-wm_adsp-move-firmware-loading-to-client.patch b/patches.suse/ASoC-wm_adsp-move-firmware-loading-to-client.patch new file mode 100644 index 0000000..da8d8af --- /dev/null +++ b/patches.suse/ASoC-wm_adsp-move-firmware-loading-to-client.patch @@ -0,0 +1,350 @@ +From a828056fa1fc044beab3cbe32f484fec5f38fe98 Mon Sep 17 00:00:00 2001 +From: Simon Trimmer +Date: Mon, 13 Sep 2021 17:00:54 +0100 +Subject: [PATCH] ASoC: wm_adsp: move firmware loading to client +Git-commit: a828056fa1fc044beab3cbe32f484fec5f38fe98 +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +This is preparation for moving the generic DSP support out of ASoC. +Passing the firmware as parameters into the power_up functions +simplifies the generic code that will be moved out of wm_adsp. + +Signed-off-by: Simon Trimmer +Link: https://lore.kernel.org/r/20210913160057.103842-14-simont@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/wm_adsp.c | 163 +++++++++++++++++++++++++------------ + 1 file changed, 112 insertions(+), 51 deletions(-) + +diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c +index c2e1eb8ff357..3b5b0cce7b35 100644 +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -29,6 +29,7 @@ + #include + #include + #include ++#include + + #include "wm_adsp.h" + +@@ -1797,6 +1798,60 @@ static unsigned int cs_dsp_adsp1_parse_sizes(struct wm_adsp *dsp, + return pos + sizeof(*adsp1_sizes); + } + ++static void wm_adsp_release_firmware_files(struct wm_adsp *dsp, ++ const struct firmware *wmfw_firmware, ++ char *wmfw_filename, ++ const struct firmware *coeff_firmware, ++ char *coeff_filename) ++{ ++ if (wmfw_firmware) ++ release_firmware(wmfw_firmware); ++ kfree(wmfw_filename); ++ ++ if (coeff_firmware) ++ release_firmware(coeff_firmware); ++ kfree(coeff_filename); ++} ++ ++static int wm_adsp_request_firmware_file(struct wm_adsp *dsp, ++ const struct firmware **firmware, ++ char **filename, ++ char *suffix) ++{ ++ int ret = 0; ++ ++ *filename = kasprintf(GFP_KERNEL, "%s-%s-%s.%s", dsp->part, dsp->fwf_name, ++ wm_adsp_fw[dsp->fw].file, suffix); ++ if (*filename == NULL) ++ return -ENOMEM; ++ ++ ret = request_firmware(firmware, *filename, dsp->dev); ++ if (ret != 0) { ++ adsp_err(dsp, "Failed to request '%s'\n", *filename); ++ kfree(*filename); ++ *filename = NULL; ++ } ++ ++ return ret; ++} ++ ++static int wm_adsp_request_firmware_files(struct wm_adsp *dsp, ++ const struct firmware **wmfw_firmware, ++ char **wmfw_filename, ++ const struct firmware **coeff_firmware, ++ char **coeff_filename) ++{ ++ int ret = 0; ++ ++ ret = wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename, "wmfw"); ++ if (ret != 0) ++ return ret; ++ ++ wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename, "bin"); ++ ++ return 0; ++} ++ + static unsigned int cs_dsp_adsp2_parse_sizes(struct wm_adsp *dsp, + const char * const file, + unsigned int pos, +@@ -1837,10 +1892,10 @@ static bool cs_dsp_halo_validate_version(struct wm_adsp *dsp, unsigned int versi + } + } + +-static int cs_dsp_load(struct wm_adsp *dsp, const char *fw_file_name) ++static int cs_dsp_load(struct wm_adsp *dsp, const struct firmware *firmware, ++ const char *file) + { + LIST_HEAD(buf_list); +- const struct firmware *firmware; + struct regmap *regmap = dsp->regmap; + unsigned int pos = 0; + const struct wmfw_header *header; +@@ -1849,25 +1904,12 @@ static int cs_dsp_load(struct wm_adsp *dsp, const char *fw_file_name) + const struct wmfw_region *region; + const struct cs_dsp_region *mem; + const char *region_name; +- char *file, *text = NULL; ++ char *text = NULL; + struct cs_dsp_buf *buf; + unsigned int reg; + int regions = 0; + int ret, offset, type; + +- file = kzalloc(PAGE_SIZE, GFP_KERNEL); +- if (file == NULL) +- return -ENOMEM; +- +- snprintf(file, PAGE_SIZE, "%s-%s-%s.wmfw", dsp->part, dsp->fwf_name, +- fw_file_name); +- file[PAGE_SIZE - 1] = '\0'; +- +- ret = request_firmware(&firmware, file, dsp->dev); +- if (ret != 0) { +- cs_dsp_err(dsp, "Failed to request '%s'\n", file); +- goto out; +- } + ret = -EINVAL; + + pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer); +@@ -2031,10 +2073,7 @@ static int cs_dsp_load(struct wm_adsp *dsp, const char *fw_file_name) + out_fw: + regmap_async_complete(regmap); + cs_dsp_buf_free(&buf_list); +- release_firmware(firmware); + kfree(text); +-out: +- kfree(file); + + return ret; + } +@@ -2582,45 +2621,33 @@ static int cs_dsp_halo_setup_algs(struct wm_adsp *dsp) + return ret; + } + +-static int cs_dsp_load_coeff(struct wm_adsp *dsp, const char *fw_file_name) ++static int cs_dsp_load_coeff(struct wm_adsp *dsp, const struct firmware *firmware, ++ const char *file) + { + LIST_HEAD(buf_list); + struct regmap *regmap = dsp->regmap; + struct wmfw_coeff_hdr *hdr; + struct wmfw_coeff_item *blk; +- const struct firmware *firmware; + const struct cs_dsp_region *mem; + struct cs_dsp_alg_region *alg_region; + const char *region_name; + int ret, pos, blocks, type, offset, reg; +- char *file; + struct cs_dsp_buf *buf; + +- file = kzalloc(PAGE_SIZE, GFP_KERNEL); +- if (file == NULL) +- return -ENOMEM; +- +- snprintf(file, PAGE_SIZE, "%s-%s-%s.bin", dsp->part, dsp->fwf_name, +- fw_file_name); +- file[PAGE_SIZE - 1] = '\0'; ++ if (!firmware) ++ return 0; + +- ret = request_firmware(&firmware, file, dsp->dev); +- if (ret != 0) { +- cs_dsp_warn(dsp, "Failed to request '%s'\n", file); +- ret = 0; +- goto out; +- } + ret = -EINVAL; + + if (sizeof(*hdr) >= firmware->size) { +- cs_dsp_err(dsp, "%s: file too short, %zu bytes\n", ++ cs_dsp_err(dsp, "%s: coefficient file too short, %zu bytes\n", + file, firmware->size); + goto out_fw; + } + + hdr = (void *)&firmware->data[0]; + if (memcmp(hdr->magic, "WMDR", 4) != 0) { +- cs_dsp_err(dsp, "%s: invalid magic\n", file); ++ cs_dsp_err(dsp, "%s: invalid coefficient magic\n", file); + goto out_fw; + } + +@@ -2769,10 +2796,7 @@ static int cs_dsp_load_coeff(struct wm_adsp *dsp, const char *fw_file_name) + + out_fw: + regmap_async_complete(regmap); +- release_firmware(firmware); + cs_dsp_buf_free(&buf_list); +-out: +- kfree(file); + return ret; + } + +@@ -2837,7 +2861,10 @@ int wm_adsp1_init(struct wm_adsp *dsp) + } + EXPORT_SYMBOL_GPL(wm_adsp1_init); + +-static int cs_dsp_adsp1_power_up(struct wm_adsp *dsp, const char *fw_file_name, const char *fw_name) ++static int cs_dsp_adsp1_power_up(struct wm_adsp *dsp, ++ const struct firmware *wmfw_firmware, char *wmfw_filename, ++ const struct firmware *coeff_firmware, char *coeff_filename, ++ const char *fw_name) + { + unsigned int val; + int ret; +@@ -2871,7 +2898,7 @@ static int cs_dsp_adsp1_power_up(struct wm_adsp *dsp, const char *fw_file_name, + } + } + +- ret = cs_dsp_load(dsp, fw_file_name); ++ ret = cs_dsp_load(dsp, wmfw_firmware, wmfw_filename); + if (ret != 0) + goto err_ena; + +@@ -2879,7 +2906,7 @@ static int cs_dsp_adsp1_power_up(struct wm_adsp *dsp, const char *fw_file_name, + if (ret != 0) + goto err_ena; + +- ret = cs_dsp_load_coeff(dsp, fw_file_name); ++ ret = cs_dsp_load_coeff(dsp, coeff_firmware, coeff_filename); + if (ret != 0) + goto err_ena; + +@@ -2949,14 +2976,29 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, + struct wm_adsp *dsps = snd_soc_component_get_drvdata(component); + struct wm_adsp *dsp = &dsps[w->shift]; + int ret = 0; ++ char *wmfw_filename = NULL; ++ const struct firmware *wmfw_firmware = NULL; ++ char *coeff_filename = NULL; ++ const struct firmware *coeff_firmware = NULL; + + dsp->component = component; + + switch (event) { + case SND_SOC_DAPM_POST_PMU: ++ ret = wm_adsp_request_firmware_files(dsp, ++ &wmfw_firmware, &wmfw_filename, ++ &coeff_firmware, &coeff_filename); ++ if (ret) ++ break; ++ + ret = cs_dsp_adsp1_power_up(dsp, +- wm_adsp_fw[dsp->fw].file, ++ wmfw_firmware, wmfw_filename, ++ coeff_firmware, coeff_filename, + wm_adsp_fw_text[dsp->fw]); ++ ++ wm_adsp_release_firmware_files(dsp, ++ wmfw_firmware, wmfw_filename, ++ coeff_firmware, coeff_filename); + break; + case SND_SOC_DAPM_PRE_PMD: + cs_dsp_adsp1_power_down(dsp); +@@ -3176,8 +3218,10 @@ static void cs_dsp_halo_stop_watchdog(struct wm_adsp *dsp) + HALO_WDT_EN_MASK, 0); + } + +-static void cs_dsp_power_up(struct wm_adsp *dsp, const char *fw_file_name, +- const char *fw_name) ++static int cs_dsp_power_up(struct wm_adsp *dsp, ++ const struct firmware *wmfw_firmware, char *wmfw_filename, ++ const struct firmware *coeff_firmware, char *coeff_filename, ++ const char *fw_name) + { + int ret; + +@@ -3197,7 +3241,7 @@ static void cs_dsp_power_up(struct wm_adsp *dsp, const char *fw_file_name, + goto err_mem; + } + +- ret = cs_dsp_load(dsp, fw_file_name); ++ ret = cs_dsp_load(dsp, wmfw_firmware, wmfw_filename); + if (ret != 0) + goto err_ena; + +@@ -3205,7 +3249,7 @@ static void cs_dsp_power_up(struct wm_adsp *dsp, const char *fw_file_name, + if (ret != 0) + goto err_ena; + +- ret = cs_dsp_load_coeff(dsp, fw_file_name); ++ ret = cs_dsp_load_coeff(dsp, coeff_firmware, coeff_filename); + if (ret != 0) + goto err_ena; + +@@ -3221,8 +3265,7 @@ static void cs_dsp_power_up(struct wm_adsp *dsp, const char *fw_file_name, + + mutex_unlock(&dsp->pwr_lock); + +- return; +- ++ return 0; + err_ena: + if (dsp->ops->disable_core) + dsp->ops->disable_core(dsp); +@@ -3231,6 +3274,8 @@ static void cs_dsp_power_up(struct wm_adsp *dsp, const char *fw_file_name, + dsp->ops->disable_memory(dsp); + err_mutex: + mutex_unlock(&dsp->pwr_lock); ++ ++ return ret; + } + + static void cs_dsp_power_down(struct wm_adsp *dsp) +@@ -3264,10 +3309,26 @@ static void wm_adsp_boot_work(struct work_struct *work) + struct wm_adsp *dsp = container_of(work, + struct wm_adsp, + boot_work); ++ int ret = 0; ++ char *wmfw_filename = NULL; ++ const struct firmware *wmfw_firmware = NULL; ++ char *coeff_filename = NULL; ++ const struct firmware *coeff_firmware = NULL; ++ ++ ret = wm_adsp_request_firmware_files(dsp, ++ &wmfw_firmware, &wmfw_filename, ++ &coeff_firmware, &coeff_filename); ++ if (ret) ++ return; + + cs_dsp_power_up(dsp, +- wm_adsp_fw[dsp->fw].file, ++ wmfw_firmware, wmfw_filename, ++ coeff_firmware, coeff_filename, + wm_adsp_fw_text[dsp->fw]); ++ ++ wm_adsp_release_firmware_files(dsp, ++ wmfw_firmware, wmfw_filename, ++ coeff_firmware, coeff_filename); + } + + int wm_adsp_early_event(struct snd_soc_dapm_widget *w, +-- +2.35.3 + diff --git a/patches.suse/ASoC-wm_adsp-remove-a-repeated-including.patch b/patches.suse/ASoC-wm_adsp-remove-a-repeated-including.patch new file mode 100644 index 0000000..2f2b68c --- /dev/null +++ b/patches.suse/ASoC-wm_adsp-remove-a-repeated-including.patch @@ -0,0 +1,35 @@ +From 626605a3dfb5c538256e737a7a7ae3e18f3368ec Mon Sep 17 00:00:00 2001 +From: Guo Zhengkui +Date: Wed, 29 Sep 2021 20:32:15 +0800 +Subject: [PATCH] ASoC: wm_adsp: remove a repeated including +Git-commit: 626605a3dfb5c538256e737a7a7ae3e18f3368ec +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +Remove a repeated "#include " in line 32. + +Signed-off-by: Guo Zhengkui +Acked-by: Simon Trimmer +Link: https://lore.kernel.org/r/20210929123217.5240-1-guozhengkui@vivo.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/wm_adsp.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c +index f17c749c24c3..d4f0d72cbcc8 100644 +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -28,7 +28,6 @@ + #include + #include + #include +-#include + + #include "wm_adsp.h" + +-- +2.35.3 + diff --git a/patches.suse/ASoC-wm_adsp-wm_adsp_control_add-error-uninitialized.patch b/patches.suse/ASoC-wm_adsp-wm_adsp_control_add-error-uninitialized.patch new file mode 100644 index 0000000..42413b6 --- /dev/null +++ b/patches.suse/ASoC-wm_adsp-wm_adsp_control_add-error-uninitialized.patch @@ -0,0 +1,43 @@ +From a6e849d0007b374fc7fbb18d55941c77aa7c3923 Mon Sep 17 00:00:00 2001 +From: Simon Trimmer +Date: Mon, 15 Nov 2021 12:01:54 +0000 +Subject: [PATCH] ASoC: wm_adsp: wm_adsp_control_add() error: uninitialized symbol 'ret' +Git-commit: a6e849d0007b374fc7fbb18d55941c77aa7c3923 +Patch-mainline: v5.16-rc3 +References: bsc#1203699 + +This patch fixes the static analysis warning as it is correctly +indicating a possible code path, it cannot know that for the affected +firmware versions subname would always be NULL. + +Reported-by: kernel test robot +Reported-by: Dan Carpenter +Signed-off-by: Simon Trimmer +Acked-by: Charles Keepax +Link: https://lore.kernel.org/r/20211115120154.56782-1-simont@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/wm_adsp.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c +index d4f0d72cbcc8..6cb01a8e08fb 100644 +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -617,8 +617,9 @@ static int wm_adsp_control_add(struct cs_dsp_coeff_ctl *cs_ctl) + switch (cs_dsp->fw_ver) { + case 0: + case 1: +- snprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s %s %x", +- cs_dsp->name, region_name, cs_ctl->alg_region.alg); ++ ret = scnprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, ++ "%s %s %x", cs_dsp->name, region_name, ++ cs_ctl->alg_region.alg); + break; + case 2: + ret = scnprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, +-- +2.35.3 + diff --git a/patches.suse/Bluetooth-btusb-mediatek-fix-WMT-failure-during-runt.patch b/patches.suse/Bluetooth-btusb-mediatek-fix-WMT-failure-during-runt.patch new file mode 100644 index 0000000..1b0b67b --- /dev/null +++ b/patches.suse/Bluetooth-btusb-mediatek-fix-WMT-failure-during-runt.patch @@ -0,0 +1,62 @@ +From fd3f106677bac70437dc12e76c827294ed495a44 Mon Sep 17 00:00:00 2001 +From: Sean Wang +Date: Thu, 11 Aug 2022 08:49:07 +0800 +Subject: [PATCH] Bluetooth: btusb: mediatek: fix WMT failure during runtime suspend +Git-commit: fd3f106677bac70437dc12e76c827294ed495a44 +Patch-mainline: v6.1-rc1 +References: git-fixes + +WMT cmd/event doesn't follow up the generic HCI cmd/event handling, it +needs constantly polling control pipe until the host received the WMT +event, thus, we should require to specifically acquire PM counter on the +USB to prevent the interface from entering auto suspended while WMT +cmd/event in progress. + +Fixes: a1c49c434e15 ("Bluetooth: btusb: Add protocol support for MediaTek MT7668U USB devices") +Co-developed-by: Jing Cai +Signed-off-by: Jing Cai +Signed-off-by: Sean Wang +Signed-off-by: Luiz Augusto von Dentz +Acked-by: Takashi Iwai + +--- + drivers/bluetooth/btusb.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index 7e87139fc991..ef7726a3e701 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -2482,15 +2482,29 @@ static int btusb_mtk_hci_wmt_sync(struct hci_dev *hdev, + + set_bit(BTUSB_TX_WAIT_VND_EVT, &data->flags); + ++ /* WMT cmd/event doesn't follow up the generic HCI cmd/event handling, ++ * it needs constantly polling control pipe until the host received the ++ * WMT event, thus, we should require to specifically acquire PM counter ++ * on the USB to prevent the interface from entering auto suspended ++ * while WMT cmd/event in progress. ++ */ ++ err = usb_autopm_get_interface(data->intf); ++ if (err < 0) ++ goto err_free_wc; ++ + err = __hci_cmd_send(hdev, 0xfc6f, hlen, wc); + + if (err < 0) { + clear_bit(BTUSB_TX_WAIT_VND_EVT, &data->flags); ++ usb_autopm_put_interface(data->intf); + goto err_free_wc; + } + + /* Submit control IN URB on demand to process the WMT event */ + err = btusb_mtk_submit_wmt_recv_urb(hdev); ++ ++ usb_autopm_put_interface(data->intf); ++ + if (err < 0) + goto err_free_wc; + +-- +2.35.3 + diff --git a/patches.suse/Bluetooth-hci_-ldisc-serdev-check-percpu_init_rwsem-.patch b/patches.suse/Bluetooth-hci_-ldisc-serdev-check-percpu_init_rwsem-.patch new file mode 100644 index 0000000..acdbf8b --- /dev/null +++ b/patches.suse/Bluetooth-hci_-ldisc-serdev-check-percpu_init_rwsem-.patch @@ -0,0 +1,93 @@ +From 3124d320c22f3f4388d9ac5c8f37eaad0cefd6b1 Mon Sep 17 00:00:00 2001 +From: Tetsuo Handa +Date: Mon, 29 Aug 2022 23:58:12 +0900 +Subject: [PATCH] Bluetooth: hci_{ldisc,serdev}: check percpu_init_rwsem() failure +Git-commit: 3124d320c22f3f4388d9ac5c8f37eaad0cefd6b1 +Patch-mainline: v6.1-rc1 +References: git-fixes + +syzbot is reporting NULL pointer dereference at hci_uart_tty_close() [1], +for rcu_sync_enter() is called without rcu_sync_init() due to +hci_uart_tty_open() ignoring percpu_init_rwsem() failure. + +While we are at it, fix that hci_uart_register_device() ignores +percpu_init_rwsem() failure and hci_uart_unregister_device() does not +call percpu_free_rwsem(). + +Link: https://syzkaller.appspot.com/bug?extid=576dfca25381fb6fbc5f [1] +Reported-by: syzbot +Signed-off-by: Tetsuo Handa +Fixes: 67d2f8781b9f00d1 ("Bluetooth: hci_ldisc: Allow sleeping while proto locks are held.") +Fixes: d73e172816652772 ("Bluetooth: hci_serdev: Init hci_uart proto_lock to avoid oops") +Signed-off-by: Luiz Augusto von Dentz +Acked-by: Takashi Iwai + +--- + drivers/bluetooth/hci_ldisc.c | 7 +++++-- + drivers/bluetooth/hci_serdev.c | 10 +++++++--- + 2 files changed, 12 insertions(+), 5 deletions(-) + +diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c +index f537673ede17..865112e96ff9 100644 +--- a/drivers/bluetooth/hci_ldisc.c ++++ b/drivers/bluetooth/hci_ldisc.c +@@ -493,6 +493,11 @@ static int hci_uart_tty_open(struct tty_struct *tty) + BT_ERR("Can't allocate control structure"); + return -ENFILE; + } ++ if (percpu_init_rwsem(&hu->proto_lock)) { ++ BT_ERR("Can't allocate semaphore structure"); ++ kfree(hu); ++ return -ENOMEM; ++ } + + tty->disc_data = hu; + hu->tty = tty; +@@ -505,8 +510,6 @@ static int hci_uart_tty_open(struct tty_struct *tty) + INIT_WORK(&hu->init_ready, hci_uart_init_work); + INIT_WORK(&hu->write_work, hci_uart_write_work); + +- percpu_init_rwsem(&hu->proto_lock); +- + /* Flush any pending characters in the driver */ + tty_driver_flush_buffer(tty); + +diff --git a/drivers/bluetooth/hci_serdev.c b/drivers/bluetooth/hci_serdev.c +index c0e5f42ec6b7..f16fd79bc02b 100644 +--- a/drivers/bluetooth/hci_serdev.c ++++ b/drivers/bluetooth/hci_serdev.c +@@ -310,11 +310,12 @@ int hci_uart_register_device(struct hci_uart *hu, + + serdev_device_set_client_ops(hu->serdev, &hci_serdev_client_ops); + ++ if (percpu_init_rwsem(&hu->proto_lock)) ++ return -ENOMEM; ++ + err = serdev_device_open(hu->serdev); + if (err) +- return err; +- +- percpu_init_rwsem(&hu->proto_lock); ++ goto err_rwsem; + + err = p->open(hu); + if (err) +@@ -389,6 +390,8 @@ int hci_uart_register_device(struct hci_uart *hu, + p->close(hu); + err_open: + serdev_device_close(hu->serdev); ++err_rwsem: ++ percpu_free_rwsem(&hu->proto_lock); + return err; + } + EXPORT_SYMBOL_GPL(hci_uart_register_device); +@@ -410,5 +413,6 @@ void hci_uart_unregister_device(struct hci_uart *hu) + clear_bit(HCI_UART_PROTO_READY, &hu->flags); + serdev_device_close(hu->serdev); + } ++ percpu_free_rwsem(&hu->proto_lock); + } + EXPORT_SYMBOL_GPL(hci_uart_unregister_device); +-- +2.35.3 + diff --git a/patches.suse/Bluetooth-hci_core-Fix-not-handling-link-timeouts-pr.patch b/patches.suse/Bluetooth-hci_core-Fix-not-handling-link-timeouts-pr.patch new file mode 100644 index 0000000..123e053 --- /dev/null +++ b/patches.suse/Bluetooth-hci_core-Fix-not-handling-link-timeouts-pr.patch @@ -0,0 +1,104 @@ +From 116523c8fac05d1d26f748fee7919a4ec5df67ea Mon Sep 17 00:00:00 2001 +From: Luiz Augusto von Dentz +Date: Mon, 26 Sep 2022 15:44:42 -0700 +Subject: [PATCH] Bluetooth: hci_core: Fix not handling link timeouts propertly +Git-commit: 116523c8fac05d1d26f748fee7919a4ec5df67ea +Patch-mainline: v6.1-rc1 +References: git-fixes + +Change that introduced the use of __check_timeout did not account for +link types properly, it always assumes ACL_LINK is used thus causing +hdev->acl_last_tx to be used even in case of LE_LINK and then again +uses ACL_LINK with hci_link_tx_to. + +To fix this __check_timeout now takes the link type as parameter and +then procedure to use the right last_tx based on the link type and pass +it to hci_link_tx_to. + +Fixes: 1b1d29e51499 ("Bluetooth: Make use of __check_timeout on hci_sched_le") +Signed-off-by: Luiz Augusto von Dentz +Tested-by: David Beinder +Acked-by: Takashi Iwai + +--- + net/bluetooth/hci_core.c | 34 +++++++++++++++++++++++----------- + 1 file changed, 23 insertions(+), 11 deletions(-) + +diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c +index 66c7cdba0d32..063fbb8e07ca 100644 +--- a/net/bluetooth/hci_core.c ++++ b/net/bluetooth/hci_core.c +@@ -3485,15 +3485,27 @@ static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb) + return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len); + } + +-static void __check_timeout(struct hci_dev *hdev, unsigned int cnt) ++static void __check_timeout(struct hci_dev *hdev, unsigned int cnt, u8 type) + { +- if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { +- /* ACL tx timeout must be longer than maximum +- * link supervision timeout (40.9 seconds) */ +- if (!cnt && time_after(jiffies, hdev->acl_last_tx + +- HCI_ACL_TX_TIMEOUT)) +- hci_link_tx_to(hdev, ACL_LINK); ++ unsigned long last_tx; ++ ++ if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) ++ return; ++ ++ switch (type) { ++ case LE_LINK: ++ last_tx = hdev->le_last_tx; ++ break; ++ default: ++ last_tx = hdev->acl_last_tx; ++ break; + } ++ ++ /* tx timeout must be longer than maximum link supervision timeout ++ * (40.9 seconds) ++ */ ++ if (!cnt && time_after(jiffies, last_tx + HCI_ACL_TX_TIMEOUT)) ++ hci_link_tx_to(hdev, type); + } + + /* Schedule SCO */ +@@ -3551,7 +3563,7 @@ static void hci_sched_acl_pkt(struct hci_dev *hdev) + struct sk_buff *skb; + int quote; + +- __check_timeout(hdev, cnt); ++ __check_timeout(hdev, cnt, ACL_LINK); + + while (hdev->acl_cnt && + (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { +@@ -3594,8 +3606,6 @@ static void hci_sched_acl_blk(struct hci_dev *hdev) + int quote; + u8 type; + +- __check_timeout(hdev, cnt); +- + BT_DBG("%s", hdev->name); + + if (hdev->dev_type == HCI_AMP) +@@ -3603,6 +3613,8 @@ static void hci_sched_acl_blk(struct hci_dev *hdev) + else + type = ACL_LINK; + ++ __check_timeout(hdev, cnt, type); ++ + while (hdev->block_cnt > 0 && + (chan = hci_chan_sent(hdev, type, "e))) { + u32 priority = (skb_peek(&chan->data_q))->priority; +@@ -3676,7 +3688,7 @@ static void hci_sched_le(struct hci_dev *hdev) + + cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; + +- __check_timeout(hdev, cnt); ++ __check_timeout(hdev, cnt, LE_LINK); + + tmp = cnt; + while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { +-- +2.35.3 + diff --git a/patches.suse/HID-ishtp-hid-clientHID-ishtp-hid-client-Fix-comment.patch b/patches.suse/HID-ishtp-hid-clientHID-ishtp-hid-client-Fix-comment.patch new file mode 100644 index 0000000..5390875 --- /dev/null +++ b/patches.suse/HID-ishtp-hid-clientHID-ishtp-hid-client-Fix-comment.patch @@ -0,0 +1,34 @@ +From 94553f8a218540d676efbf3f7827ed493d1057cf Mon Sep 17 00:00:00 2001 +From: Jason Wang +Date: Thu, 4 Aug 2022 08:58:14 +0800 +Subject: [PATCH] HID: ishtp-hid-clientHID: ishtp-hid-client: Fix comment typo +Git-commit: 94553f8a218540d676efbf3f7827ed493d1057cf +Patch-mainline: v6.0-rc4 +References: git-fixes + +The double `like' is duplicated in the comment, remove one. + +Signed-off-by: Jason Wang +Signed-off-by: Jiri Kosina +Acked-by: Takashi Iwai + +--- + drivers/hid/intel-ish-hid/ishtp-hid.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/hid/intel-ish-hid/ishtp-hid.h b/drivers/hid/intel-ish-hid/ishtp-hid.h +index 6a5cc11aefd8..35dddc5015b3 100644 +--- a/drivers/hid/intel-ish-hid/ishtp-hid.h ++++ b/drivers/hid/intel-ish-hid/ishtp-hid.h +@@ -105,7 +105,7 @@ struct report_list { + * @multi_packet_cnt: Count of fragmented packet count + * + * This structure is used to store completion flags and per client data like +- * like report description, number of HID devices etc. ++ * report description, number of HID devices etc. + */ + struct ishtp_cl_data { + /* completion flags */ +-- +2.35.3 + diff --git a/patches.suse/HID-multitouch-Add-memory-barriers.patch b/patches.suse/HID-multitouch-Add-memory-barriers.patch new file mode 100644 index 0000000..ba748e0 --- /dev/null +++ b/patches.suse/HID-multitouch-Add-memory-barriers.patch @@ -0,0 +1,64 @@ +From be6e2b5734a425941fcdcdbd2a9337be498ce2cf Mon Sep 17 00:00:00 2001 +From: Andri Yngvason +Date: Wed, 7 Sep 2022 15:01:59 +0000 +Subject: [PATCH] HID: multitouch: Add memory barriers +Git-commit: be6e2b5734a425941fcdcdbd2a9337be498ce2cf +Patch-mainline: v6.1-rc1 +References: git-fixes + +This fixes broken atomic checks which cause a race between the +release-timer and processing of hid input. + +I noticed that contacts were sometimes sticking, even with the "sticky +fingers" quirk enabled. This fixes that problem. + +Cc: stable@vger.kernel.org +Fixes: 9609827458c3 ("HID: multitouch: optimize the sticky fingers timer") +Signed-off-by: Andri Yngvason +Signed-off-by: Benjamin Tissoires +Link: https://lore.kernel.org/r/20220907150159.2285460-1-andri@yngvason.is +Acked-by: Takashi Iwai + +--- + drivers/hid/hid-multitouch.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index 2e72922e36f5..91a4d3fc30e0 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -1186,7 +1186,7 @@ static void mt_touch_report(struct hid_device *hid, + int contact_count = -1; + + /* sticky fingers release in progress, abort */ +- if (test_and_set_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags)) ++ if (test_and_set_bit_lock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags)) + return; + + scantime = *app->scantime; +@@ -1267,7 +1267,7 @@ static void mt_touch_report(struct hid_device *hid, + del_timer(&td->release_timer); + } + +- clear_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags); ++ clear_bit_unlock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags); + } + + static int mt_touch_input_configured(struct hid_device *hdev, +@@ -1699,11 +1699,11 @@ static void mt_expired_timeout(struct timer_list *t) + * An input report came in just before we release the sticky fingers, + * it will take care of the sticky fingers. + */ +- if (test_and_set_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags)) ++ if (test_and_set_bit_lock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags)) + return; + if (test_bit(MT_IO_FLAGS_PENDING_SLOTS, &td->mt_io_flags)) + mt_release_contacts(hdev); +- clear_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags); ++ clear_bit_unlock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags); + } + + static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) +-- +2.35.3 + diff --git a/patches.suse/HSI-omap_ssi-Fix-refcount-leak-in-ssi_probe.patch b/patches.suse/HSI-omap_ssi-Fix-refcount-leak-in-ssi_probe.patch new file mode 100644 index 0000000..bbfeca0 --- /dev/null +++ b/patches.suse/HSI-omap_ssi-Fix-refcount-leak-in-ssi_probe.patch @@ -0,0 +1,36 @@ +From 9a2ea132df860177b33c9fd421b26c4e9a0a9396 Mon Sep 17 00:00:00 2001 +From: Miaoqian Lin +Date: Mon, 4 Apr 2022 08:52:32 +0000 +Subject: [PATCH] HSI: omap_ssi: Fix refcount leak in ssi_probe +Git-commit: 9a2ea132df860177b33c9fd421b26c4e9a0a9396 +Patch-mainline: v6.1-rc1 +References: git-fixes + +When returning or breaking early from a +for_each_available_child_of_node() loop, we need to explicitly call +of_node_put() on the child node to possibly release the node. + +Fixes: b209e047bc74 ("HSI: Introduce OMAP SSI driver") +Signed-off-by: Miaoqian Lin +Signed-off-by: Sebastian Reichel +Acked-by: Takashi Iwai + +--- + drivers/hsi/controllers/omap_ssi_core.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/hsi/controllers/omap_ssi_core.c b/drivers/hsi/controllers/omap_ssi_core.c +index 44a3f5660c10..eb9820158318 100644 +--- a/drivers/hsi/controllers/omap_ssi_core.c ++++ b/drivers/hsi/controllers/omap_ssi_core.c +@@ -524,6 +524,7 @@ static int ssi_probe(struct platform_device *pd) + if (!childpdev) { + err = -ENODEV; + dev_err(&pd->dev, "failed to create ssi controller port\n"); ++ of_node_put(child); + goto out3; + } + } +-- +2.35.3 + diff --git a/patches.suse/HSI-omap_ssi_port-Fix-dma_map_sg-error-check.patch b/patches.suse/HSI-omap_ssi_port-Fix-dma_map_sg-error-check.patch new file mode 100644 index 0000000..da5bda7 --- /dev/null +++ b/patches.suse/HSI-omap_ssi_port-Fix-dma_map_sg-error-check.patch @@ -0,0 +1,55 @@ +From 551e325bbd3fb8b5a686ac1e6cf76e5641461cf2 Mon Sep 17 00:00:00 2001 +From: Jack Wang +Date: Fri, 26 Aug 2022 12:12:27 +0200 +Subject: [PATCH] HSI: omap_ssi_port: Fix dma_map_sg error check +Git-commit: 551e325bbd3fb8b5a686ac1e6cf76e5641461cf2 +Patch-mainline: v6.1-rc1 +References: git-fixes + +dma_map_sg return 0 on error, in case of error return -EIO +to caller. + +Cc: Sebastian Reichel +Cc: linux-kernel@vger.kernel.org (open list) +Fixes: b209e047bc74 ("HSI: Introduce OMAP SSI driver") +Signed-off-by: Jack Wang +Signed-off-by: Sebastian Reichel +Acked-by: Takashi Iwai + +--- + drivers/hsi/controllers/omap_ssi_port.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/hsi/controllers/omap_ssi_port.c b/drivers/hsi/controllers/omap_ssi_port.c +index a0cb5be246e1..b9495b720f1b 100644 +--- a/drivers/hsi/controllers/omap_ssi_port.c ++++ b/drivers/hsi/controllers/omap_ssi_port.c +@@ -230,10 +230,10 @@ static int ssi_start_dma(struct hsi_msg *msg, int lch) + if (msg->ttype == HSI_MSG_READ) { + err = dma_map_sg(&ssi->device, msg->sgt.sgl, msg->sgt.nents, + DMA_FROM_DEVICE); +- if (err < 0) { ++ if (!err) { + dev_dbg(&ssi->device, "DMA map SG failed !\n"); + pm_runtime_put_autosuspend(omap_port->pdev); +- return err; ++ return -EIO; + } + csdp = SSI_DST_BURST_4x32_BIT | SSI_DST_MEMORY_PORT | + SSI_SRC_SINGLE_ACCESS0 | SSI_SRC_PERIPHERAL_PORT | +@@ -247,10 +247,10 @@ static int ssi_start_dma(struct hsi_msg *msg, int lch) + } else { + err = dma_map_sg(&ssi->device, msg->sgt.sgl, msg->sgt.nents, + DMA_TO_DEVICE); +- if (err < 0) { ++ if (!err) { + dev_dbg(&ssi->device, "DMA map SG failed !\n"); + pm_runtime_put_autosuspend(omap_port->pdev); +- return err; ++ return -EIO; + } + csdp = SSI_SRC_BURST_4x32_BIT | SSI_SRC_MEMORY_PORT | + SSI_DST_SINGLE_ACCESS0 | SSI_DST_PERIPHERAL_PORT | +-- +2.35.3 + diff --git a/patches.suse/Input-goodix-add-compatible-string-for-GT1158.patch b/patches.suse/Input-goodix-add-compatible-string-for-GT1158.patch new file mode 100644 index 0000000..b647647 --- /dev/null +++ b/patches.suse/Input-goodix-add-compatible-string-for-GT1158.patch @@ -0,0 +1,35 @@ +From 80b9ebd3e478cd41526cbf84f80c3e0eb885d1d3 Mon Sep 17 00:00:00 2001 +From: Jarrah Gosbell +Date: Tue, 23 Aug 2022 10:00:37 -0700 +Subject: [PATCH] Input: goodix - add compatible string for GT1158 +Git-commit: 80b9ebd3e478cd41526cbf84f80c3e0eb885d1d3 +Patch-mainline: v6.0-rc4 +References: git-fixes + +Add compatible string for GT1158 missing from the previous patch. + +Fixes: 425fe4709c76 ("Input: goodix - add support for GT1158") +Signed-off-by: Jarrah Gosbell +Link: https://lore.kernel.org/r/20220813043821.9981-1-kernel@undef.tools +Signed-off-by: Dmitry Torokhov +Acked-by: Takashi Iwai + +--- + drivers/input/touchscreen/goodix.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c +index ab03619d6b50..21c0dddbe41d 100644 +--- a/drivers/input/touchscreen/goodix.c ++++ b/drivers/input/touchscreen/goodix.c +@@ -1509,6 +1509,7 @@ MODULE_DEVICE_TABLE(acpi, goodix_acpi_match); + #ifdef CONFIG_OF + static const struct of_device_id goodix_of_match[] = { + { .compatible = "goodix,gt1151" }, ++ { .compatible = "goodix,gt1158" }, + { .compatible = "goodix,gt5663" }, + { .compatible = "goodix,gt5688" }, + { .compatible = "goodix,gt911" }, +-- +2.35.3 + diff --git a/patches.suse/Input-goodix-add-support-for-GT1158.patch b/patches.suse/Input-goodix-add-support-for-GT1158.patch new file mode 100644 index 0000000..c648154 --- /dev/null +++ b/patches.suse/Input-goodix-add-support-for-GT1158.patch @@ -0,0 +1,37 @@ +From 425fe4709c76e35f93f4c0e50240f0b61b2a2e54 Mon Sep 17 00:00:00 2001 +From: Ondrej Jirman +Date: Thu, 11 Aug 2022 16:16:54 -0700 +Subject: [PATCH] Input: goodix - add support for GT1158 +Git-commit: 425fe4709c76e35f93f4c0e50240f0b61b2a2e54 +Patch-mainline: v6.0-rc4 +References: git-fixes + +This controller is used by PinePhone and PinePhone Pro. Support for +the PinePhone Pro will be added in a later patch set. + +Signed-off-by: Ondrej Jirman +Signed-off-by: Jarrah Gosbell +Reviewed-by: Hans de Goede +Link: https://lore.kernel.org/r/20220809091200.290492-1-kernel@undef.tools +Signed-off-by: Dmitry Torokhov +Acked-by: Takashi Iwai + +--- + drivers/input/touchscreen/goodix.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c +index d016505fc081..ab03619d6b50 100644 +--- a/drivers/input/touchscreen/goodix.c ++++ b/drivers/input/touchscreen/goodix.c +@@ -95,6 +95,7 @@ static const struct goodix_chip_data gt9x_chip_data = { + + static const struct goodix_chip_id goodix_chip_ids[] = { + { .id = "1151", .data = >1x_chip_data }, ++ { .id = "1158", .data = >1x_chip_data }, + { .id = "5663", .data = >1x_chip_data }, + { .id = "5688", .data = >1x_chip_data }, + { .id = "917S", .data = >1x_chip_data }, +-- +2.35.3 + diff --git a/patches.suse/Input-i8042-fix-refount-leak-on-sparc.patch b/patches.suse/Input-i8042-fix-refount-leak-on-sparc.patch new file mode 100644 index 0000000..e0368e8 --- /dev/null +++ b/patches.suse/Input-i8042-fix-refount-leak-on-sparc.patch @@ -0,0 +1,80 @@ +From fe5b6aaef72a0f7daa06e7960e0bee45c2984e41 Mon Sep 17 00:00:00 2001 +From: Liang He +Date: Sat, 1 Oct 2022 14:42:24 -0700 +Subject: [PATCH] Input: i8042 - fix refount leak on sparc +Git-commit: fe5b6aaef72a0f7daa06e7960e0bee45c2984e41 +Patch-mainline: v6.1-rc1 +References: git-fixes + +In i8042_platform_init() and i8042_platform_exit(), we should call +of_node_put() for the reference 'root' returned by +of_find_node_by_path() which has increased the refcount. + +Fixes: f57caaefacc2 ("[SERIO] i8042-sparcio.h: Convert to of_driver framework.") +Signed-off-by: Liang He +Link: https://lore.kernel.org/r/20220711064300.358757-1-windhl@126.com +[dtor: rearranged i8042_is_mr_coffee() a bit] +Signed-off-by: Dmitry Torokhov +Acked-by: Takashi Iwai + +--- + drivers/input/serio/i8042-sparcio.h | 27 +++++++++++++++++++-------- + 1 file changed, 19 insertions(+), 8 deletions(-) + +diff --git a/drivers/input/serio/i8042-sparcio.h b/drivers/input/serio/i8042-sparcio.h +index fce76812843b..c712c1fe0605 100644 +--- a/drivers/input/serio/i8042-sparcio.h ++++ b/drivers/input/serio/i8042-sparcio.h +@@ -3,6 +3,7 @@ + #define _I8042_SPARCIO_H + + #include ++#include + + #include + #include +@@ -103,12 +104,25 @@ static struct platform_driver sparc_i8042_driver = { + .remove = sparc_i8042_remove, + }; + +-static int __init i8042_platform_init(void) ++static bool i8042_is_mr_coffee(void) + { +- struct device_node *root = of_find_node_by_path("/"); +- const char *name = of_get_property(root, "name", NULL); ++ struct device_node *root; ++ const char *name; ++ bool is_mr_coffee; ++ ++ root = of_find_node_by_path("/"); ++ ++ name = of_get_property(root, "name", NULL); ++ is_mr_coffee = name && !strcmp(name, "SUNW,JavaStation-1"); + +- if (name && !strcmp(name, "SUNW,JavaStation-1")) { ++ of_node_put(root); ++ ++ return is_mr_coffee; ++} ++ ++static int __init i8042_platform_init(void) ++{ ++ if (i8042_is_mr_coffee()) { + /* Hardcoded values for MrCoffee. */ + i8042_kbd_irq = i8042_aux_irq = 13 | 0x20; + kbd_iobase = ioremap(0x71300060, 8); +@@ -136,10 +150,7 @@ static int __init i8042_platform_init(void) + + static inline void i8042_platform_exit(void) + { +- struct device_node *root = of_find_node_by_path("/"); +- const char *name = of_get_property(root, "name", NULL); +- +- if (!name || strcmp(name, "SUNW,JavaStation-1")) ++ if (!i8042_is_mr_coffee()) + platform_driver_unregister(&sparc_i8042_driver); + } + +-- +2.35.3 + diff --git a/patches.suse/Input-iforce-add-support-for-Boeder-Force-Feedback-W.patch b/patches.suse/Input-iforce-add-support-for-Boeder-Force-Feedback-W.patch new file mode 100644 index 0000000..615bbfe --- /dev/null +++ b/patches.suse/Input-iforce-add-support-for-Boeder-Force-Feedback-W.patch @@ -0,0 +1,48 @@ +From 9c9c71168f7979f3798b61c65b4530fbfbcf19d1 Mon Sep 17 00:00:00 2001 +From: Greg Tulli +Date: Mon, 29 Aug 2022 11:21:03 -0700 +Subject: [PATCH] Input: iforce - add support for Boeder Force Feedback Wheel +Git-commit: 9c9c71168f7979f3798b61c65b4530fbfbcf19d1 +Patch-mainline: v6.0-rc4 +References: git-fixes + +Add a new iforce_device entry to support the Boeder Force Feedback Wheel +device. + +Signed-off-by: Greg Tulli +Link: https://lore.kernel.org/r/3256420-c8ac-31b-8499-3c488a9880fd@gmail.com +Signed-off-by: Dmitry Torokhov +Acked-by: Takashi Iwai + +--- + Documentation/input/joydev/joystick.rst | 1 + + drivers/input/joystick/iforce/iforce-main.c | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/Documentation/input/joydev/joystick.rst b/Documentation/input/joydev/joystick.rst +index f615906a0821..6d721396717a 100644 +--- a/Documentation/input/joydev/joystick.rst ++++ b/Documentation/input/joydev/joystick.rst +@@ -517,6 +517,7 @@ All I-Force devices are supported by the iforce module. This includes: + * AVB Mag Turbo Force + * AVB Top Shot Pegasus + * AVB Top Shot Force Feedback Racing Wheel ++* Boeder Force Feedback Wheel + * Logitech WingMan Force + * Logitech WingMan Force Wheel + * Guillemot Race Leader Force Feedback +diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c +index b2a68bc9f0b4..b86de1312512 100644 +--- a/drivers/input/joystick/iforce/iforce-main.c ++++ b/drivers/input/joystick/iforce/iforce-main.c +@@ -50,6 +50,7 @@ static struct iforce_device iforce_device[] = { + { 0x046d, 0xc291, "Logitech WingMan Formula Force", btn_wheel, abs_wheel, ff_iforce }, + { 0x05ef, 0x020a, "AVB Top Shot Pegasus", btn_joystick_avb, abs_avb_pegasus, ff_iforce }, + { 0x05ef, 0x8884, "AVB Mag Turbo Force", btn_wheel, abs_wheel, ff_iforce }, ++ { 0x05ef, 0x8886, "Boeder Force Feedback Wheel", btn_wheel, abs_wheel, ff_iforce }, + { 0x05ef, 0x8888, "AVB Top Shot Force Feedback Racing Wheel", btn_wheel, abs_wheel, ff_iforce }, //? + { 0x061c, 0xc0a4, "ACT LABS Force RS", btn_wheel, abs_wheel, ff_iforce }, //? + { 0x061c, 0xc084, "ACT LABS Force RS", btn_wheel, abs_wheel, ff_iforce }, +-- +2.35.3 + diff --git a/patches.suse/Input-iqs62x-keys-drop-unused-device-node-references.patch b/patches.suse/Input-iqs62x-keys-drop-unused-device-node-references.patch new file mode 100644 index 0000000..2ab16e2 --- /dev/null +++ b/patches.suse/Input-iqs62x-keys-drop-unused-device-node-references.patch @@ -0,0 +1,51 @@ +From e336d85e5b08c9d206a89b2b95c0c7bb47c64a56 Mon Sep 17 00:00:00 2001 +From: Jeff LaBundy +Date: Sat, 17 Sep 2022 14:09:22 -0500 +Subject: [PATCH] Input: iqs62x-keys - drop unused device node references +Git-commit: e336d85e5b08c9d206a89b2b95c0c7bb47c64a56 +Patch-mainline: v6.0 +References: git-fixes + +Each call to device/fwnode_get_named_child_node() must be matched +with a call to fwnode_handle_put() once the corresponding node is +no longer in use. This ensures a reference count remains balanced +in the case of dynamic device tree support. + +Currently, the driver never calls fwnode_handle_put(). This patch +adds the missing calls. + +Fixes: ce1cb0eec85b ("input: keyboard: Add support for Azoteq IQS620A/621/622/624/625") +Signed-off-by: Jeff LaBundy +Reviewed-by: Mattijs Korpershoek +Link: https://lore.kernel.org/r/YyYbYvlkq5cy55dc@nixie71 +Signed-off-by: Dmitry Torokhov +Acked-by: Takashi Iwai + +--- + drivers/input/keyboard/iqs62x-keys.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/input/keyboard/iqs62x-keys.c b/drivers/input/keyboard/iqs62x-keys.c +index 93446b21f98f..db793a550c25 100644 +--- a/drivers/input/keyboard/iqs62x-keys.c ++++ b/drivers/input/keyboard/iqs62x-keys.c +@@ -77,6 +77,7 @@ static int iqs62x_keys_parse_prop(struct platform_device *pdev, + if (ret) { + dev_err(&pdev->dev, "Failed to read switch code: %d\n", + ret); ++ fwnode_handle_put(child); + return ret; + } + iqs62x_keys->switches[i].code = val; +@@ -90,6 +91,8 @@ static int iqs62x_keys_parse_prop(struct platform_device *pdev, + iqs62x_keys->switches[i].flag = (i == IQS62X_SW_HALL_N ? + IQS62X_EVENT_HALL_N_T : + IQS62X_EVENT_HALL_S_T); ++ ++ fwnode_handle_put(child); + } + + return 0; +-- +2.35.3 + diff --git a/patches.suse/Input-melfas_mip4-fix-return-value-check-in-mip4_pro.patch b/patches.suse/Input-melfas_mip4-fix-return-value-check-in-mip4_pro.patch new file mode 100644 index 0000000..590c91a --- /dev/null +++ b/patches.suse/Input-melfas_mip4-fix-return-value-check-in-mip4_pro.patch @@ -0,0 +1,37 @@ +From a54dc27bd25f20ee3ea2009584b3166d25178243 Mon Sep 17 00:00:00 2001 +From: Yang Yingliang +Date: Sat, 24 Sep 2022 11:07:15 +0800 +Subject: [PATCH] Input: melfas_mip4 - fix return value check in mip4_probe() +Git-commit: a54dc27bd25f20ee3ea2009584b3166d25178243 +Patch-mainline: v6.0 +References: git-fixes + +devm_gpiod_get_optional() may return ERR_PTR(-EPROBE_DEFER), +add a minus sign to fix it. + +Fixes: 6ccb1d8f78bd ("Input: add MELFAS MIP4 Touchscreen driver") +Signed-off-by: Yang Yingliang +Link: https://lore.kernel.org/r/20220924030715.1653538-1-yangyingliang@huawei.com +Signed-off-by: Dmitry Torokhov +Acked-by: Takashi Iwai + +--- + drivers/input/touchscreen/melfas_mip4.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/input/touchscreen/melfas_mip4.c b/drivers/input/touchscreen/melfas_mip4.c +index 2745bf1aee38..83f4be05e27b 100644 +--- a/drivers/input/touchscreen/melfas_mip4.c ++++ b/drivers/input/touchscreen/melfas_mip4.c +@@ -1453,7 +1453,7 @@ static int mip4_probe(struct i2c_client *client, const struct i2c_device_id *id) + "ce", GPIOD_OUT_LOW); + if (IS_ERR(ts->gpio_ce)) { + error = PTR_ERR(ts->gpio_ce); +- if (error != EPROBE_DEFER) ++ if (error != -EPROBE_DEFER) + dev_err(&client->dev, + "Failed to get gpio: %d\n", error); + return error; +-- +2.35.3 + diff --git a/patches.suse/Input-snvs_pwrkey-fix-SNVS_HPVIDR1-register-address.patch b/patches.suse/Input-snvs_pwrkey-fix-SNVS_HPVIDR1-register-address.patch new file mode 100644 index 0000000..702eba3 --- /dev/null +++ b/patches.suse/Input-snvs_pwrkey-fix-SNVS_HPVIDR1-register-address.patch @@ -0,0 +1,46 @@ +From e62563db857f81d75c5726a35bc0180bed6d1540 Mon Sep 17 00:00:00 2001 +From: Sebastian Krzyszkowiak +Date: Tue, 27 Sep 2022 07:15:45 -0700 +Subject: [PATCH] Input: snvs_pwrkey - fix SNVS_HPVIDR1 register address +Git-commit: e62563db857f81d75c5726a35bc0180bed6d1540 +Patch-mainline: v6.0 +References: git-fixes + +Both i.MX6 and i.MX8 reference manuals list 0xBF8 as SNVS_HPVIDR1 +(chapters 57.9 and 6.4.5 respectively). + +Without this, trying to read the revision number results in 0 on +all revisions, causing the i.MX6 quirk to apply on all platforms, +which in turn causes the driver to synthesise power button release +events instead of passing the real one as they happen even on +platforms like i.MX8 where that's not wanted. + +Fixes: 1a26c920717a ("Input: snvs_pwrkey - send key events for i.MX6 S, DL and Q") +Tested-by: Martin Kepplinger +Signed-off-by: Sebastian Krzyszkowiak +Reviewed-by: Mattijs Korpershoek +Cc: +Link: https://lore.kernel.org/r/4599101.ElGaqSPkdT@pliszka +Signed-off-by: Dmitry Torokhov +Acked-by: Takashi Iwai + +--- + drivers/input/keyboard/snvs_pwrkey.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/input/keyboard/snvs_pwrkey.c b/drivers/input/keyboard/snvs_pwrkey.c +index 65286762b02a..ad8660be0127 100644 +--- a/drivers/input/keyboard/snvs_pwrkey.c ++++ b/drivers/input/keyboard/snvs_pwrkey.c +@@ -20,7 +20,7 @@ + #include + #include + +-#define SNVS_HPVIDR1_REG 0xF8 ++#define SNVS_HPVIDR1_REG 0xBF8 + #define SNVS_LPSR_REG 0x4C /* LP Status Register */ + #define SNVS_LPCR_REG 0x38 /* LP Control Register */ + #define SNVS_HPSR_REG 0x14 +-- +2.35.3 + diff --git a/patches.suse/Input-soc_button_array-add-support-for-Microsoft-Sur.patch b/patches.suse/Input-soc_button_array-add-support-for-Microsoft-Sur.patch index fc13255..14d6b60 100644 --- a/patches.suse/Input-soc_button_array-add-support-for-Microsoft-Sur.patch +++ b/patches.suse/Input-soc_button_array-add-support-for-Microsoft-Sur.patch @@ -42,30 +42,35 @@ Acked-by: Dmitry Torokhov Link: https://lore.kernel.org/r/20220224110241.9613-2-hdegoede@redhat.com Acked-by: Lee, Chun-Yi --- - drivers/acpi/scan.c | 5 +++++ - drivers/input/misc/soc_button_array.c | 24 +++++++++++++++++++++++- + drivers/acpi/scan.c | 5 +++++ + drivers/input/misc/soc_button_array.c | 24 +++++++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) +diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c +index 4463c2eda61e..e993c8b253f5 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c -@@ -1747,6 +1747,11 @@ static bool acpi_device_enumeration_by_p - {"INT33FE", }, +@@ -1749,6 +1749,11 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device) {"INT3515", }, - /* + /* Non-conforming _HID for Cirrus Logic already released */ + {"CLSA0100", }, ++ /* + * Some ACPI devs contain SerialBus resources even though they are not + * attached to a serial bus at all. + */ + {"MSHW0028", }, -+ /* + /* * HIDs of device with an UartSerialBusV2 resource for which userspace * expects a regular tty cdev to be created (instead of the in kernel - * serdev) and which have a kernel driver which expects a platform_dev +diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c +index cb6ec59a045d..cbb1599a520e 100644 --- a/drivers/input/misc/soc_button_array.c +++ b/drivers/input/misc/soc_button_array.c -@@ -470,6 +470,27 @@ static const struct soc_device_data soc_ +@@ -469,6 +469,27 @@ static const struct soc_device_data soc_device_INT33D3 = { + .button_info = soc_button_INT33D3, }; - /* ++/* + * Button info for Microsoft Surface 3 (non pro), this is indentical to + * the PNP0C40 info except that the home button is active-high. + * @@ -86,11 +91,10 @@ Acked-by: Lee, Chun-Yi + .button_info = soc_button_MSHW0028, +}; + -+/* + /* * Special device check for Surface Book 2 and Surface Pro (2017). * Both, the Surface Pro 4 (surfacepro3_button.c) and the above mentioned - * devices use MSHW0040 for power and volume buttons, however the way they -@@ -535,7 +556,8 @@ static const struct acpi_device_id soc_b +@@ -535,7 +556,8 @@ static const struct acpi_device_id soc_button_acpi_match[] = { { "ID9001", (unsigned long)&soc_device_INT33D3 }, { "ACPI0011", 0 }, @@ -100,3 +104,6 @@ Acked-by: Lee, Chun-Yi { "MSHW0040", (unsigned long)&soc_device_MSHW0040 }, { } +-- +2.35.3 + diff --git a/patches.suse/Input-synaptics-rmi4-fix-firmware-update-operations-.patch b/patches.suse/Input-synaptics-rmi4-fix-firmware-update-operations-.patch new file mode 100644 index 0000000..47ceeb5 --- /dev/null +++ b/patches.suse/Input-synaptics-rmi4-fix-firmware-update-operations-.patch @@ -0,0 +1,57 @@ +From 28f677e9d15181556c1f2103d93b9cc093e7b91f Mon Sep 17 00:00:00 2001 +From: Matthias Schiffer +Date: Wed, 8 Jun 2022 14:48:00 +0200 +Subject: [PATCH] Input: synaptics-rmi4 - fix firmware update operations with bootloader v8 +Git-commit: 28f677e9d15181556c1f2103d93b9cc093e7b91f +Patch-mainline: v6.1-rc1 +References: git-fixes + +Commit a6977d758fed ("Input: synaptics-rmi4 - support bootloader v8 in +f34v7") allowed the F34v7 driver to probe with bootloader v8, but it did +not update various other bootloader version checks in the F34 code. + +Fixes: a6977d758fed ("Input: synaptics-rmi4 - support bootloader v8 in f34v7") +Signed-off-by: Matthias Schiffer +Reviewed-by: Lyude Paul +Link: https://lore.kernel.org/r/20220608124808.51402-2-matthias.schiffer@ew.tq-group.com +Signed-off-by: Dmitry Torokhov +Acked-by: Takashi Iwai + +--- + drivers/input/rmi4/rmi_f34.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/input/rmi4/rmi_f34.c b/drivers/input/rmi4/rmi_f34.c +index e5dca9868f87..3afc94f679ed 100644 +--- a/drivers/input/rmi4/rmi_f34.c ++++ b/drivers/input/rmi4/rmi_f34.c +@@ -370,7 +370,7 @@ static int rmi_firmware_update(struct rmi_driver_data *data, + + f34 = dev_get_drvdata(&data->f34_container->dev); + +- if (f34->bl_version == 7) { ++ if (f34->bl_version >= 7) { + if (data->pdt_props & HAS_BSR) { + dev_err(dev, "%s: LTS not supported\n", __func__); + return -ENODEV; +@@ -382,7 +382,7 @@ static int rmi_firmware_update(struct rmi_driver_data *data, + } + + /* Enter flash mode */ +- if (f34->bl_version == 7) ++ if (f34->bl_version >= 7) + ret = rmi_f34v7_start_reflash(f34, fw); + else + ret = rmi_f34_enable_flash(f34); +@@ -413,7 +413,7 @@ static int rmi_firmware_update(struct rmi_driver_data *data, + f34 = dev_get_drvdata(&data->f34_container->dev); + + /* Perform firmware update */ +- if (f34->bl_version == 7) ++ if (f34->bl_version >= 7) + ret = rmi_f34v7_do_reflash(f34, fw); + else + ret = rmi_f34_update_firmware(f34, fw); +-- +2.35.3 + diff --git a/patches.suse/Input-xpad-add-supported-devices-as-contributed-on-g.patch b/patches.suse/Input-xpad-add-supported-devices-as-contributed-on-g.patch new file mode 100644 index 0000000..5b6056b --- /dev/null +++ b/patches.suse/Input-xpad-add-supported-devices-as-contributed-on-g.patch @@ -0,0 +1,109 @@ +From b382c5e37344883dc97525d05f1f6b788f549985 Mon Sep 17 00:00:00 2001 +From: Pavel Rojtberg +Date: Thu, 18 Aug 2022 17:44:08 +0200 +Subject: [PATCH] Input: xpad - add supported devices as contributed on github +Git-commit: b382c5e37344883dc97525d05f1f6b788f549985 +Patch-mainline: v6.1-rc1 +References: git-fixes + +This is based on multiple commits at https://github.com/paroj/xpad + +Cc: stable@vger.kernel.org +Signed-off-by: Jasper Poppe +Signed-off-by: Jeremy Palmer +Signed-off-by: Ruineka +Signed-off-by: Cleber de Mattos Casali +Signed-off-by: Kyle Gospodnetich +Signed-off-by: Pavel Rojtberg +Link: https://lore.kernel.org/r/20220818154411.510308-2-rojtberg@gmail.com +Signed-off-by: Dmitry Torokhov +Acked-by: Takashi Iwai + +--- + drivers/input/joystick/xpad.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c +index 18190b529bca..5af07ded98fc 100644 +--- a/drivers/input/joystick/xpad.c ++++ b/drivers/input/joystick/xpad.c +@@ -113,6 +113,8 @@ static const struct xpad_device { + u8 xtype; + } xpad_device[] = { + { 0x0079, 0x18d4, "GPD Win 2 X-Box Controller", 0, XTYPE_XBOX360 }, ++ { 0x03eb, 0xff01, "Wooting One (Legacy)", 0, XTYPE_XBOX360 }, ++ { 0x03eb, 0xff02, "Wooting Two (Legacy)", 0, XTYPE_XBOX360 }, + { 0x044f, 0x0f00, "Thrustmaster Wheel", 0, XTYPE_XBOX }, + { 0x044f, 0x0f03, "Thrustmaster Wheel", 0, XTYPE_XBOX }, + { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX }, +@@ -244,6 +246,7 @@ static const struct xpad_device { + { 0x0f0d, 0x0063, "Hori Real Arcade Pro Hayabusa (USA) Xbox One", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE }, + { 0x0f0d, 0x0067, "HORIPAD ONE", 0, XTYPE_XBOXONE }, + { 0x0f0d, 0x0078, "Hori Real Arcade Pro V Kai Xbox One", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE }, ++ { 0x0f0d, 0x00c5, "Hori Fighting Commander ONE", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE }, + { 0x0f30, 0x010b, "Philips Recoil", 0, XTYPE_XBOX }, + { 0x0f30, 0x0202, "Joytech Advanced Controller", 0, XTYPE_XBOX }, + { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", 0, XTYPE_XBOX }, +@@ -260,6 +263,7 @@ static const struct xpad_device { + { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, + { 0x1430, 0xf801, "RedOctane Controller", 0, XTYPE_XBOX360 }, + { 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", 0, XTYPE_XBOX360 }, ++ { 0x146b, 0x0604, "Bigben Interactive DAIJA Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, + { 0x1532, 0x0037, "Razer Sabertooth", 0, XTYPE_XBOX360 }, + { 0x1532, 0x0a00, "Razer Atrox Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE }, + { 0x1532, 0x0a03, "Razer Wildcat", 0, XTYPE_XBOXONE }, +@@ -325,6 +329,7 @@ static const struct xpad_device { + { 0x24c6, 0x5502, "Hori Fighting Stick VX Alt", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, + { 0x24c6, 0x5503, "Hori Fighting Edge", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, + { 0x24c6, 0x5506, "Hori SOULCALIBUR V Stick", 0, XTYPE_XBOX360 }, ++ { 0x24c6, 0x5510, "Hori Fighting Commander ONE (Xbox 360/PC Mode)", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, + { 0x24c6, 0x550d, "Hori GEM Xbox controller", 0, XTYPE_XBOX360 }, + { 0x24c6, 0x550e, "Hori Real Arcade Pro V Kai 360", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, + { 0x24c6, 0x551a, "PowerA FUSION Pro Controller", 0, XTYPE_XBOXONE }, +@@ -334,6 +339,14 @@ static const struct xpad_device { + { 0x24c6, 0x5b03, "Thrustmaster Ferrari 458 Racing Wheel", 0, XTYPE_XBOX360 }, + { 0x24c6, 0x5d04, "Razer Sabertooth", 0, XTYPE_XBOX360 }, + { 0x24c6, 0xfafe, "Rock Candy Gamepad for Xbox 360", 0, XTYPE_XBOX360 }, ++ { 0x2563, 0x058d, "OneXPlayer Gamepad", 0, XTYPE_XBOX360 }, ++ { 0x2dc8, 0x2000, "8BitDo Pro 2 Wired Controller fox Xbox", 0, XTYPE_XBOXONE }, ++ { 0x31e3, 0x1100, "Wooting One", 0, XTYPE_XBOX360 }, ++ { 0x31e3, 0x1200, "Wooting Two", 0, XTYPE_XBOX360 }, ++ { 0x31e3, 0x1210, "Wooting Lekker", 0, XTYPE_XBOX360 }, ++ { 0x31e3, 0x1220, "Wooting Two HE", 0, XTYPE_XBOX360 }, ++ { 0x31e3, 0x1300, "Wooting 60HE (AVR)", 0, XTYPE_XBOX360 }, ++ { 0x31e3, 0x1310, "Wooting 60HE (ARM)", 0, XTYPE_XBOX360 }, + { 0x3285, 0x0607, "Nacon GC-100", 0, XTYPE_XBOX360 }, + { 0x3767, 0x0101, "Fanatec Speedster 3 Forceshock Wheel", 0, XTYPE_XBOX }, + { 0xffff, 0xffff, "Chinese-made Xbox Controller", 0, XTYPE_XBOX }, +@@ -419,6 +432,7 @@ static const signed short xpad_abs_triggers[] = { + static const struct usb_device_id xpad_table[] = { + { USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */ + XPAD_XBOX360_VENDOR(0x0079), /* GPD Win 2 Controller */ ++ XPAD_XBOX360_VENDOR(0x03eb), /* Wooting Keyboards (Legacy) */ + XPAD_XBOX360_VENDOR(0x044f), /* Thrustmaster X-Box 360 controllers */ + XPAD_XBOX360_VENDOR(0x045e), /* Microsoft X-Box 360 controllers */ + XPAD_XBOXONE_VENDOR(0x045e), /* Microsoft X-Box One controllers */ +@@ -429,6 +443,7 @@ static const struct usb_device_id xpad_table[] = { + { USB_DEVICE(0x0738, 0x4540) }, /* Mad Catz Beat Pad */ + XPAD_XBOXONE_VENDOR(0x0738), /* Mad Catz FightStick TE 2 */ + XPAD_XBOX360_VENDOR(0x07ff), /* Mad Catz GamePad */ ++ XPAD_XBOX360_VENDOR(0x0c12), /* Zeroplus X-Box 360 controllers */ + XPAD_XBOX360_VENDOR(0x0e6f), /* 0x0e6f X-Box 360 controllers */ + XPAD_XBOXONE_VENDOR(0x0e6f), /* 0x0e6f X-Box One controllers */ + XPAD_XBOX360_VENDOR(0x0f0d), /* Hori Controllers */ +@@ -450,8 +465,12 @@ static const struct usb_device_id xpad_table[] = { + XPAD_XBOXONE_VENDOR(0x20d6), /* PowerA Controllers */ + XPAD_XBOX360_VENDOR(0x24c6), /* PowerA Controllers */ + XPAD_XBOXONE_VENDOR(0x24c6), /* PowerA Controllers */ ++ XPAD_XBOX360_VENDOR(0x2563), /* OneXPlayer Gamepad */ ++ XPAD_XBOX360_VENDOR(0x260d), /* Dareu H101 */ ++ XPAD_XBOXONE_VENDOR(0x2dc8), /* 8BitDo Pro 2 Wired Controller for Xbox */ + XPAD_XBOXONE_VENDOR(0x2e24), /* Hyperkin Duke X-Box One pad */ + XPAD_XBOX360_VENDOR(0x2f24), /* GameSir Controllers */ ++ XPAD_XBOX360_VENDOR(0x31e3), /* Wooting Keyboards */ + XPAD_XBOX360_VENDOR(0x3285), /* Nacon GC-100 */ + { } + }; +-- +2.35.3 + diff --git a/patches.suse/Input-xpad-fix-wireless-360-controller-breaking-afte.patch b/patches.suse/Input-xpad-fix-wireless-360-controller-breaking-afte.patch new file mode 100644 index 0000000..774c570 --- /dev/null +++ b/patches.suse/Input-xpad-fix-wireless-360-controller-breaking-afte.patch @@ -0,0 +1,44 @@ +From a17b9841152e7f4621619902b347e2cc39c32996 Mon Sep 17 00:00:00 2001 +From: Cameron Gutman +Date: Thu, 18 Aug 2022 17:44:09 +0200 +Subject: [PATCH] Input: xpad - fix wireless 360 controller breaking after suspend +Git-commit: a17b9841152e7f4621619902b347e2cc39c32996 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Suspending and resuming the system can sometimes cause the out +URB to get hung after a reset_resume. This causes LED setting +and force feedback to break on resume. To avoid this, just drop +the reset_resume callback so the USB core rebinds xpad to the +wireless pads on resume if a reset happened. + +A nice side effect of this change is the LED ring on wireless +controllers is now set correctly on system resume. + +Cc: stable@vger.kernel.org +Fixes: 4220f7db1e42 ("Input: xpad - workaround dead irq_out after suspend/ resume") +Signed-off-by: Cameron Gutman +Signed-off-by: Pavel Rojtberg +Link: https://lore.kernel.org/r/20220818154411.510308-3-rojtberg@gmail.com +Signed-off-by: Dmitry Torokhov +Acked-by: Takashi Iwai + +--- + drivers/input/joystick/xpad.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c +index 5af07ded98fc..3da5fd5b5aaf 100644 +--- a/drivers/input/joystick/xpad.c ++++ b/drivers/input/joystick/xpad.c +@@ -1991,7 +1991,6 @@ static struct usb_driver xpad_driver = { + .disconnect = xpad_disconnect, + .suspend = xpad_suspend, + .resume = xpad_resume, +- .reset_resume = xpad_resume, + .id_table = xpad_table, + }; + +-- +2.35.3 + diff --git a/patches.suse/KVM-SVM-Create-a-separate-mapping-for-the-GHCB-save-area b/patches.suse/KVM-SVM-Create-a-separate-mapping-for-the-GHCB-save-area new file mode 100644 index 0000000..7ec1501 --- /dev/null +++ b/patches.suse/KVM-SVM-Create-a-separate-mapping-for-the-GHCB-save-area @@ -0,0 +1,109 @@ +From: Tom Lendacky +Date: Mon, 7 Mar 2022 15:33:13 -0600 +Subject: KVM: SVM: Create a separate mapping for the GHCB save area +Git-commit: a4690359eaec985a1351786da887df1ba92440a0 +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +The initial implementation of the GHCB spec was based on trying to keep +the register state offsets the same relative to the VM save area. However, +the save area for SEV-ES has changed within the hardware causing the +relation between the SEV-ES save area to change relative to the GHCB save +area. + +This is the second step in defining the multiple save areas to keep them +separate and ensuring proper operation amongst the different types of +guests. Create a GHCB save area that matches the GHCB specification. + +Signed-off-by: Tom Lendacky +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Reviewed-by: Venu Busireddy +Link: https://lore.kernel.org/r/20220307213356.2797205-4-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/include/asm/svm.h | 48 ++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 45 insertions(+), 3 deletions(-) + +--- a/arch/x86/include/asm/svm.h ++++ b/arch/x86/include/asm/svm.h +@@ -392,11 +392,51 @@ struct sev_es_save_area { + u64 x87_state_gpa; + } __packed; + ++struct ghcb_save_area { ++ u8 reserved_1[203]; ++ u8 cpl; ++ u8 reserved_2[116]; ++ u64 xss; ++ u8 reserved_3[24]; ++ u64 dr7; ++ u8 reserved_4[16]; ++ u64 rip; ++ u8 reserved_5[88]; ++ u64 rsp; ++ u8 reserved_6[24]; ++ u64 rax; ++ u8 reserved_7[264]; ++ u64 rcx; ++ u64 rdx; ++ u64 rbx; ++ u8 reserved_8[8]; ++ u64 rbp; ++ u64 rsi; ++ u64 rdi; ++ u64 r8; ++ u64 r9; ++ u64 r10; ++ u64 r11; ++ u64 r12; ++ u64 r13; ++ u64 r14; ++ u64 r15; ++ u8 reserved_9[16]; ++ u64 sw_exit_code; ++ u64 sw_exit_info_1; ++ u64 sw_exit_info_2; ++ u64 sw_scratch; ++ u8 reserved_10[56]; ++ u64 xcr0; ++ u8 valid_bitmap[16]; ++ u64 x87_state_gpa; ++} __packed; ++ + #define GHCB_SHARED_BUF_SIZE 2032 + + struct ghcb { +- struct sev_es_save_area save; +- u8 reserved_save[2048 - sizeof(struct sev_es_save_area)]; ++ struct ghcb_save_area save; ++ u8 reserved_save[2048 - sizeof(struct ghcb_save_area)]; + + u8 shared_buffer[GHCB_SHARED_BUF_SIZE]; + +@@ -407,6 +447,7 @@ struct ghcb { + + + #define EXPECTED_VMCB_SAVE_AREA_SIZE 740 ++#define EXPECTED_GHCB_SAVE_AREA_SIZE 1032 + #define EXPECTED_SEV_ES_SAVE_AREA_SIZE 1032 + #define EXPECTED_VMCB_CONTROL_AREA_SIZE 1024 + #define EXPECTED_GHCB_SIZE PAGE_SIZE +@@ -414,6 +455,7 @@ struct ghcb { + static inline void __unused_size_checks(void) + { + BUILD_BUG_ON(sizeof(struct vmcb_save_area) != EXPECTED_VMCB_SAVE_AREA_SIZE); ++ BUILD_BUG_ON(sizeof(struct ghcb_save_area) != EXPECTED_GHCB_SAVE_AREA_SIZE); + BUILD_BUG_ON(sizeof(struct sev_es_save_area) != EXPECTED_SEV_ES_SAVE_AREA_SIZE); + BUILD_BUG_ON(sizeof(struct vmcb_control_area) != EXPECTED_VMCB_CONTROL_AREA_SIZE); + BUILD_BUG_ON(sizeof(struct ghcb) != EXPECTED_GHCB_SIZE); +@@ -484,7 +526,7 @@ struct vmcb { + /* GHCB Accessor functions */ + + #define GHCB_BITMAP_IDX(field) \ +- (offsetof(struct sev_es_save_area, field) / sizeof(u64)) ++ (offsetof(struct ghcb_save_area, field) / sizeof(u64)) + + #define DEFINE_GHCB_ACCESSORS(field) \ + static inline bool ghcb_##field##_is_valid(const struct ghcb *ghcb) \ diff --git a/patches.suse/KVM-SVM-Create-a-separate-mapping-for-the-SEV-ES-save-area b/patches.suse/KVM-SVM-Create-a-separate-mapping-for-the-SEV-ES-save-area new file mode 100644 index 0000000..24731c5 --- /dev/null +++ b/patches.suse/KVM-SVM-Create-a-separate-mapping-for-the-SEV-ES-save-area @@ -0,0 +1,251 @@ +From: Tom Lendacky +Date: Tue, 5 Apr 2022 13:27:43 -0500 +Subject: KVM: SVM: Create a separate mapping for the SEV-ES save area +Git-commit: 3dd2775b74c9b1b01d19805877ab45bc47c4a5a5 +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +The save area for SEV-ES/SEV-SNP guests, as used by the hardware, is +different from the save area of a non SEV-ES/SEV-SNP guest. + +This is the first step in defining the multiple save areas to keep them +separate and ensuring proper operation amongst the different types of +guests. Create an SEV-ES/SEV-SNP save area and adjust usage to the new +save area definition where needed. + +Signed-off-by: Tom Lendacky +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Reviewed-by: Venu Busireddy +Link: https://lore.kernel.org/r/20220405182743.308853-1-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/include/asm/svm.h | 87 ++++++++++++++++++++++++++++++++++----------- + arch/x86/kvm/svm/sev.c | 24 ++++++------ + arch/x86/kvm/svm/svm.h | 2 - + 3 files changed, 80 insertions(+), 33 deletions(-) + +--- a/arch/x86/include/asm/svm.h ++++ b/arch/x86/include/asm/svm.h +@@ -265,6 +265,7 @@ struct vmcb_seg { + u64 base; + } __packed; + ++/* Save area definition for legacy and SEV-MEM guests */ + struct vmcb_save_area { + struct vmcb_seg es; + struct vmcb_seg cs; +@@ -281,8 +282,58 @@ struct vmcb_save_area { + u8 cpl; + u8 reserved_2[4]; + u64 efer; ++ u8 reserved_3[112]; ++ u64 cr4; ++ u64 cr3; ++ u64 cr0; ++ u64 dr7; ++ u64 dr6; ++ u64 rflags; ++ u64 rip; ++ u8 reserved_4[88]; ++ u64 rsp; ++ u64 s_cet; ++ u64 ssp; ++ u64 isst_addr; ++ u64 rax; ++ u64 star; ++ u64 lstar; ++ u64 cstar; ++ u64 sfmask; ++ u64 kernel_gs_base; ++ u64 sysenter_cs; ++ u64 sysenter_esp; ++ u64 sysenter_eip; ++ u64 cr2; ++ u8 reserved_5[32]; ++ u64 g_pat; ++ u64 dbgctl; ++ u64 br_from; ++ u64 br_to; ++ u64 last_excp_from; ++ u64 last_excp_to; ++ u8 reserved_6[72]; ++ u32 spec_ctrl; /* Guest version of SPEC_CTRL at 0x2E0 */ ++} __packed; ++ ++/* Save area definition for SEV-ES and SEV-SNP guests */ ++struct sev_es_save_area { ++ struct vmcb_seg es; ++ struct vmcb_seg cs; ++ struct vmcb_seg ss; ++ struct vmcb_seg ds; ++ struct vmcb_seg fs; ++ struct vmcb_seg gs; ++ struct vmcb_seg gdtr; ++ struct vmcb_seg ldtr; ++ struct vmcb_seg idtr; ++ struct vmcb_seg tr; ++ u8 reserved_1[43]; ++ u8 cpl; ++ u8 reserved_2[4]; ++ u64 efer; + u8 reserved_3[104]; +- u64 xss; /* Valid for SEV-ES only */ ++ u64 xss; + u64 cr4; + u64 cr3; + u64 cr0; +@@ -310,22 +361,14 @@ struct vmcb_save_area { + u64 br_to; + u64 last_excp_from; + u64 last_excp_to; +- +- /* +- * The following part of the save area is valid only for +- * SEV-ES guests when referenced through the GHCB or for +- * saving to the host save area. +- */ +- u8 reserved_7[72]; +- u32 spec_ctrl; /* Guest version of SPEC_CTRL at 0x2E0 */ +- u8 reserved_7b[4]; ++ u8 reserved_7[80]; + u32 pkru; +- u8 reserved_7a[20]; +- u64 reserved_8; /* rax already available at 0x01f8 */ ++ u8 reserved_9[20]; ++ u64 reserved_10; /* rax already available at 0x01f8 */ + u64 rcx; + u64 rdx; + u64 rbx; +- u64 reserved_9; /* rsp already available at 0x01d8 */ ++ u64 reserved_11; /* rsp already available at 0x01d8 */ + u64 rbp; + u64 rsi; + u64 rdi; +@@ -337,23 +380,25 @@ struct vmcb_save_area { + u64 r13; + u64 r14; + u64 r15; +- u8 reserved_10[16]; ++ u8 reserved_12[16]; + u64 sw_exit_code; + u64 sw_exit_info_1; + u64 sw_exit_info_2; + u64 sw_scratch; + u64 sev_features; +- u8 reserved_11[48]; ++ u8 reserved_13[48]; + u64 xcr0; + u8 valid_bitmap[16]; + u64 x87_state_gpa; + } __packed; + ++#define GHCB_SHARED_BUF_SIZE 2032 ++ + struct ghcb { +- struct vmcb_save_area save; +- u8 reserved_save[2048 - sizeof(struct vmcb_save_area)]; ++ struct sev_es_save_area save; ++ u8 reserved_save[2048 - sizeof(struct sev_es_save_area)]; + +- u8 shared_buffer[2032]; ++ u8 shared_buffer[GHCB_SHARED_BUF_SIZE]; + + u8 reserved_1[10]; + u16 protocol_version; /* negotiated SEV-ES/GHCB protocol version */ +@@ -361,13 +406,15 @@ struct ghcb { + } __packed; + + +-#define EXPECTED_VMCB_SAVE_AREA_SIZE 1032 ++#define EXPECTED_VMCB_SAVE_AREA_SIZE 740 ++#define EXPECTED_SEV_ES_SAVE_AREA_SIZE 1032 + #define EXPECTED_VMCB_CONTROL_AREA_SIZE 1024 + #define EXPECTED_GHCB_SIZE PAGE_SIZE + + static inline void __unused_size_checks(void) + { + BUILD_BUG_ON(sizeof(struct vmcb_save_area) != EXPECTED_VMCB_SAVE_AREA_SIZE); ++ BUILD_BUG_ON(sizeof(struct sev_es_save_area) != EXPECTED_SEV_ES_SAVE_AREA_SIZE); + BUILD_BUG_ON(sizeof(struct vmcb_control_area) != EXPECTED_VMCB_CONTROL_AREA_SIZE); + BUILD_BUG_ON(sizeof(struct ghcb) != EXPECTED_GHCB_SIZE); + } +@@ -437,7 +484,7 @@ struct vmcb { + /* GHCB Accessor functions */ + + #define GHCB_BITMAP_IDX(field) \ +- (offsetof(struct vmcb_save_area, field) / sizeof(u64)) ++ (offsetof(struct sev_es_save_area, field) / sizeof(u64)) + + #define DEFINE_GHCB_ACCESSORS(field) \ + static inline bool ghcb_##field##_is_valid(const struct ghcb *ghcb) \ +--- a/arch/x86/kvm/svm/sev.c ++++ b/arch/x86/kvm/svm/sev.c +@@ -560,12 +560,20 @@ e_unpin: + + static int sev_es_sync_vmsa(struct vcpu_svm *svm) + { +- struct vmcb_save_area *save = &svm->vmcb->save; ++ struct sev_es_save_area *save = svm->sev_es.vmsa; + + /* Check some debug related fields before encrypting the VMSA */ +- if (svm->vcpu.guest_debug || (save->dr7 & ~DR7_FIXED_1)) ++ if (svm->vcpu.guest_debug || (svm->vmcb->save.dr7 & ~DR7_FIXED_1)) + return -EINVAL; + ++ /* ++ * SEV-ES will use a VMSA that is pointed to by the VMCB, not ++ * the traditional VMSA that is part of the VMCB. Copy the ++ * traditional VMSA as it has been built so far (in prep ++ * for LAUNCH_UPDATE_VMSA) to be the initial SEV-ES state. ++ */ ++ memcpy(save, &svm->vmcb->save, sizeof(svm->vmcb->save)); ++ + /* Sync registgers */ + save->rax = svm->vcpu.arch.regs[VCPU_REGS_RAX]; + save->rbx = svm->vcpu.arch.regs[VCPU_REGS_RBX]; +@@ -592,14 +600,6 @@ static int sev_es_sync_vmsa(struct vcpu_ + save->pkru = svm->vcpu.arch.pkru; + save->xss = svm->vcpu.arch.ia32_xss; + +- /* +- * SEV-ES will use a VMSA that is pointed to by the VMCB, not +- * the traditional VMSA that is part of the VMCB. Copy the +- * traditional VMSA as it has been built so far (in prep +- * for LAUNCH_UPDATE_VMSA) to be the initial SEV-ES state. +- */ +- memcpy(svm->sev_es.vmsa, save, sizeof(*save)); +- + return 0; + } + +@@ -2901,7 +2901,7 @@ void sev_es_create_vcpu(struct vcpu_svm + void sev_es_prepare_guest_switch(struct vcpu_svm *svm, unsigned int cpu) + { + struct svm_cpu_data *sd = per_cpu(svm_data, cpu); +- struct vmcb_save_area *hostsa; ++ struct sev_es_save_area *hostsa; + + /* + * As an SEV-ES guest, hardware will restore the host state on VMEXIT, +@@ -2911,7 +2911,7 @@ void sev_es_prepare_guest_switch(struct + vmsave(__sme_page_pa(sd->save_area)); + + /* XCR0 is restored on VMEXIT, save the current host value */ +- hostsa = (struct vmcb_save_area *)(page_address(sd->save_area) + 0x400); ++ hostsa = (struct sev_es_save_area *)(page_address(sd->save_area) + 0x400); + hostsa->xcr0 = xgetbv(XCR_XFEATURE_ENABLED_MASK); + + /* PKRU is restored on VMEXIT, save the current host value */ +--- a/arch/x86/kvm/svm/svm.h ++++ b/arch/x86/kvm/svm/svm.h +@@ -129,7 +129,7 @@ struct svm_nested_state { + + struct vcpu_sev_es_state { + /* SEV-ES support */ +- struct vmcb_save_area *vmsa; ++ struct sev_es_save_area *vmsa; + struct ghcb *ghcb; + struct kvm_host_map ghcb_map; + bool received_first_sipi; diff --git a/patches.suse/KVM-SVM-Define-sev_features-and-VMPL-field-in-the-VMSA b/patches.suse/KVM-SVM-Define-sev_features-and-VMPL-field-in-the-VMSA new file mode 100644 index 0000000..e9427cd --- /dev/null +++ b/patches.suse/KVM-SVM-Define-sev_features-and-VMPL-field-in-the-VMSA @@ -0,0 +1,62 @@ +From: Brijesh Singh +Date: Mon, 7 Mar 2022 15:33:11 -0600 +Subject: KVM: SVM: Define sev_features and VMPL field in the VMSA +Git-commit: 046f773be106ec8eb92b13414c90f8e279deffe0 +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +The hypervisor uses the sev_features field (offset 3B0h) in the Save State +Area to control the SEV-SNP guest features such as SNPActive, vTOM, +ReflectVC etc. An SEV-SNP guest can read the sev_features field through +the SEV_STATUS MSR. + +While at it, update dump_vmcb() to log the VMPL level. + +See APM2 Table 15-34 and B-4 for more details. + +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Reviewed-by: Venu Busireddy +Link: https://lore.kernel.org/r/20220307213356.2797205-2-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/include/asm/svm.h | 6 ++++-- + arch/x86/kvm/svm/svm.c | 4 ++-- + 2 files changed, 6 insertions(+), 4 deletions(-) + +--- a/arch/x86/include/asm/svm.h ++++ b/arch/x86/include/asm/svm.h +@@ -276,7 +276,8 @@ struct vmcb_save_area { + struct vmcb_seg ldtr; + struct vmcb_seg idtr; + struct vmcb_seg tr; +- u8 reserved_1[43]; ++ u8 reserved_1[42]; ++ u8 vmpl; + u8 cpl; + u8 reserved_2[4]; + u64 efer; +@@ -341,7 +342,8 @@ struct vmcb_save_area { + u64 sw_exit_info_1; + u64 sw_exit_info_2; + u64 sw_scratch; +- u8 reserved_11[56]; ++ u64 sev_features; ++ u8 reserved_11[48]; + u64 xcr0; + u8 valid_bitmap[16]; + u64 x87_state_gpa; +--- a/arch/x86/kvm/svm/svm.c ++++ b/arch/x86/kvm/svm/svm.c +@@ -3290,8 +3290,8 @@ static void dump_vmcb(struct kvm_vcpu *v + "tr:", + save01->tr.selector, save01->tr.attrib, + save01->tr.limit, save01->tr.base); +- pr_err("cpl: %d efer: %016llx\n", +- save->cpl, save->efer); ++ pr_err("vmpl: %d cpl: %d efer: %016llx\n", ++ save->vmpl, save->cpl, save->efer); + pr_err("%-15s %016llx %-13s %016llx\n", + "cr0:", save->cr0, "cr2:", save->cr2); + pr_err("%-15s %016llx %-13s %016llx\n", diff --git a/patches.suse/KVM-SVM-Update-the-SEV-ES-save-area-mapping b/patches.suse/KVM-SVM-Update-the-SEV-ES-save-area-mapping new file mode 100644 index 0000000..cdc9192 --- /dev/null +++ b/patches.suse/KVM-SVM-Update-the-SEV-ES-save-area-mapping @@ -0,0 +1,139 @@ +From: Tom Lendacky +Date: Mon, 7 Mar 2022 15:33:14 -0600 +Subject: KVM: SVM: Update the SEV-ES save area mapping +Git-commit: 6d3b3d34e39eb4ee9a7dbe7e28e2588e160f9c0f +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +This is the final step in defining the multiple save areas to keep them +separate and ensuring proper operation amongst the different types of +guests. Update the SEV-ES/SEV-SNP save area to match the APM. This save +area will be used for the upcoming SEV-SNP AP Creation NAE event support. + +Signed-off-by: Tom Lendacky +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Reviewed-by: Venu Busireddy +Link: https://lore.kernel.org/r/20220307213356.2797205-5-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/include/asm/svm.h | 66 ++++++++++++++++++++++++++++++++++----------- + 1 file changed, 50 insertions(+), 16 deletions(-) + +--- a/arch/x86/include/asm/svm.h ++++ b/arch/x86/include/asm/svm.h +@@ -328,7 +328,13 @@ struct sev_es_save_area { + struct vmcb_seg ldtr; + struct vmcb_seg idtr; + struct vmcb_seg tr; +- u8 reserved_1[43]; ++ u64 vmpl0_ssp; ++ u64 vmpl1_ssp; ++ u64 vmpl2_ssp; ++ u64 vmpl3_ssp; ++ u64 u_cet; ++ u8 reserved_1[2]; ++ u8 vmpl; + u8 cpl; + u8 reserved_2[4]; + u64 efer; +@@ -341,9 +347,19 @@ struct sev_es_save_area { + u64 dr6; + u64 rflags; + u64 rip; +- u8 reserved_4[88]; ++ u64 dr0; ++ u64 dr1; ++ u64 dr2; ++ u64 dr3; ++ u64 dr0_addr_mask; ++ u64 dr1_addr_mask; ++ u64 dr2_addr_mask; ++ u64 dr3_addr_mask; ++ u8 reserved_4[24]; + u64 rsp; +- u8 reserved_5[24]; ++ u64 s_cet; ++ u64 ssp; ++ u64 isst_addr; + u64 rax; + u64 star; + u64 lstar; +@@ -354,7 +370,7 @@ struct sev_es_save_area { + u64 sysenter_esp; + u64 sysenter_eip; + u64 cr2; +- u8 reserved_6[32]; ++ u8 reserved_5[32]; + u64 g_pat; + u64 dbgctl; + u64 br_from; +@@ -363,12 +379,12 @@ struct sev_es_save_area { + u64 last_excp_to; + u8 reserved_7[80]; + u32 pkru; +- u8 reserved_9[20]; +- u64 reserved_10; /* rax already available at 0x01f8 */ ++ u8 reserved_8[20]; ++ u64 reserved_9; /* rax already available at 0x01f8 */ + u64 rcx; + u64 rdx; + u64 rbx; +- u64 reserved_11; /* rsp already available at 0x01d8 */ ++ u64 reserved_10; /* rsp already available at 0x01d8 */ + u64 rbp; + u64 rsi; + u64 rdi; +@@ -380,16 +396,34 @@ struct sev_es_save_area { + u64 r13; + u64 r14; + u64 r15; +- u8 reserved_12[16]; +- u64 sw_exit_code; +- u64 sw_exit_info_1; +- u64 sw_exit_info_2; +- u64 sw_scratch; ++ u8 reserved_11[16]; ++ u64 guest_exit_info_1; ++ u64 guest_exit_info_2; ++ u64 guest_exit_int_info; ++ u64 guest_nrip; + u64 sev_features; +- u8 reserved_13[48]; ++ u64 vintr_ctrl; ++ u64 guest_exit_code; ++ u64 virtual_tom; ++ u64 tlb_id; ++ u64 pcpu_id; ++ u64 event_inj; + u64 xcr0; +- u8 valid_bitmap[16]; +- u64 x87_state_gpa; ++ u8 reserved_12[16]; ++ ++ /* Floating point area */ ++ u64 x87_dp; ++ u32 mxcsr; ++ u16 x87_ftw; ++ u16 x87_fsw; ++ u16 x87_fcw; ++ u16 x87_fop; ++ u16 x87_ds; ++ u16 x87_cs; ++ u64 x87_rip; ++ u8 fpreg_x87[80]; ++ u8 fpreg_xmm[256]; ++ u8 fpreg_ymm[256]; + } __packed; + + struct ghcb_save_area { +@@ -448,7 +482,7 @@ struct ghcb { + + #define EXPECTED_VMCB_SAVE_AREA_SIZE 740 + #define EXPECTED_GHCB_SAVE_AREA_SIZE 1032 +-#define EXPECTED_SEV_ES_SAVE_AREA_SIZE 1032 ++#define EXPECTED_SEV_ES_SAVE_AREA_SIZE 1648 + #define EXPECTED_VMCB_CONTROL_AREA_SIZE 1024 + #define EXPECTED_GHCB_SIZE PAGE_SIZE + diff --git a/patches.suse/KVM-SVM-fix-tsc-scaling-cache-logic.patch b/patches.suse/KVM-SVM-fix-tsc-scaling-cache-logic.patch new file mode 100644 index 0000000..5f7fa50 --- /dev/null +++ b/patches.suse/KVM-SVM-fix-tsc-scaling-cache-logic.patch @@ -0,0 +1,113 @@ +Patch-mainline: v5.19-rc2 +Git-commit: 11d39e8cc43e1c6737af19ca9372e590061b5ad2 +References: bsc#1203263 +From: Maxim Levitsky +Date: Mon, 6 Jun 2022 21:11:49 +0300 +Subject: [PATCH] KVM: SVM: fix tsc scaling cache logic + +SVM uses a per-cpu variable to cache the current value of the +tsc scaling multiplier msr on each cpu. + +Commit 1ab9287add5e2 +("KVM: X86: Add vendor callbacks for writing the TSC multiplier") +broke this caching logic. + +Refactor the code so that all TSC scaling multiplier writes go through +a single function which checks and updates the cache. + +This fixes the following scenario: + +1. A CPU runs a guest with some tsc scaling ratio. + +2. New guest with different tsc scaling ratio starts on this CPU + and terminates almost immediately. + + This ensures that the short running guest had set the tsc scaling ratio just + once when it was set via KVM_SET_TSC_KHZ. Due to the bug, + the per-cpu cache is not updated. + +3. The original guest continues to run, it doesn't restore the msr + value back to its own value, because the cache matches, + and thus continues to run with a wrong tsc scaling ratio. + +Fixes: 1ab9287add5e2 ("KVM: X86: Add vendor callbacks for writing the TSC multiplier") +Signed-off-by: Maxim Levitsky +Message-Id: <20220606181149.103072-1-mlevitsk@redhat.com> +Cc: stable@vger.kernel.org +Signed-off-by: Paolo Bonzini +Signed-off-by: Juergen Gross +--- + arch/x86/kvm/svm/svm.c | 32 ++++++++++++++++++++------------ + 1 file changed, 23 insertions(+), 15 deletions(-) + +diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c +index 63880b33ce37..478e6ee81d88 100644 +--- a/arch/x86/kvm/svm/svm.c ++++ b/arch/x86/kvm/svm/svm.c +@@ -465,11 +465,24 @@ static int has_svm(void) + return 1; + } + ++static void __svm_write_tsc_multiplier(u64 multiplier) ++{ ++ preempt_disable(); ++ ++ if (multiplier == __this_cpu_read(current_tsc_ratio)) ++ goto out; ++ ++ wrmsrl(MSR_AMD64_TSC_RATIO, multiplier); ++ __this_cpu_write(current_tsc_ratio, multiplier); ++out: ++ preempt_enable(); ++} ++ + static void svm_hardware_disable(void) + { + /* Make sure we clean up behind us */ + if (static_cpu_has(X86_FEATURE_TSCRATEMSR)) +- wrmsrl(MSR_AMD64_TSC_RATIO, TSC_RATIO_DEFAULT); ++ __svm_write_tsc_multiplier(TSC_RATIO_DEFAULT); + + cpu_svm_disable(); + +@@ -515,8 +528,7 @@ static int svm_hardware_enable(void) + wrmsrl(MSR_VM_HSAVE_PA, __sme_page_pa(sd->save_area)); + + if (static_cpu_has(X86_FEATURE_TSCRATEMSR)) { +- wrmsrl(MSR_AMD64_TSC_RATIO, TSC_RATIO_DEFAULT); +- __this_cpu_write(current_tsc_ratio, TSC_RATIO_DEFAULT); ++ __svm_write_tsc_multiplier(TSC_RATIO_DEFAULT); + } + + +@@ -999,9 +1011,10 @@ static void svm_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset) + + static void svm_write_tsc_multiplier(struct kvm_vcpu *vcpu, u64 multiplier) + { +- wrmsrl(MSR_AMD64_TSC_RATIO, multiplier); ++ __svm_write_tsc_multiplier(multiplier); + } + ++ + /* Evaluate instruction intercepts that depend on guest CPUID features. */ + static void svm_recalc_instruction_intercepts(struct kvm_vcpu *vcpu, + struct vcpu_svm *svm) +@@ -1363,13 +1376,8 @@ static void svm_prepare_switch_to_guest(struct kvm_vcpu *vcpu) + vmsave(__sme_page_pa(sd->save_area)); + } + +- if (static_cpu_has(X86_FEATURE_TSCRATEMSR)) { +- u64 tsc_ratio = vcpu->arch.tsc_scaling_ratio; +- if (tsc_ratio != __this_cpu_read(current_tsc_ratio)) { +- __this_cpu_write(current_tsc_ratio, tsc_ratio); +- wrmsrl(MSR_AMD64_TSC_RATIO, tsc_ratio); +- } +- } ++ if (static_cpu_has(X86_FEATURE_TSCRATEMSR)) ++ __svm_write_tsc_multiplier(vcpu->arch.tsc_scaling_ratio); + + if (likely(tsc_aux_uret_slot >= 0)) + kvm_set_user_return_msr(tsc_aux_uret_slot, svm->tsc_aux, -1ull); +-- +2.35.3 + diff --git a/patches.suse/KVM-VMX-Heed-the-msr-argument-in-msr_write_intercept.patch b/patches.suse/KVM-VMX-Heed-the-msr-argument-in-msr_write_intercept.patch new file mode 100644 index 0000000..817c67a --- /dev/null +++ b/patches.suse/KVM-VMX-Heed-the-msr-argument-in-msr_write_intercept.patch @@ -0,0 +1,43 @@ +Patch-mainline: v6.0-rc4 +Git-commit: 020dac4187968535f089f83f376a72beb3451311 +References: git-fixes +From: Jim Mattson +Date: Wed, 10 Aug 2022 14:30:50 -0700 +Subject: [PATCH] KVM: VMX: Heed the 'msr' argument in msr_write_intercepted() + +Regardless of the 'msr' argument passed to the VMX version of +msr_write_intercepted(), the function always checks to see if a +specific MSR (IA32_SPEC_CTRL) is intercepted for write. This behavior +seems unintentional and unexpected. + +Modify the function so that it checks to see if the provided 'msr' +index is intercepted for write. + +Fixes: 67f4b9969c30 ("KVM: nVMX: Handle dynamic MSR intercept toggling") +Cc: Sean Christopherson +Signed-off-by: Jim Mattson +Reviewed-by: Sean Christopherson +Message-Id: <20220810213050.2655000-1-jmattson@google.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Juergen Gross +--- + arch/x86/kvm/vmx/vmx.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c +index d7f8331d6f7e..c9b49a09e6b5 100644 +--- a/arch/x86/kvm/vmx/vmx.c ++++ b/arch/x86/kvm/vmx/vmx.c +@@ -843,8 +843,7 @@ static bool msr_write_intercepted(struct vcpu_vmx *vmx, u32 msr) + if (!(exec_controls_get(vmx) & CPU_BASED_USE_MSR_BITMAPS)) + return true; + +- return vmx_test_msr_bitmap_write(vmx->loaded_vmcs->msr_bitmap, +- MSR_IA32_SPEC_CTRL); ++ return vmx_test_msr_bitmap_write(vmx->loaded_vmcs->msr_bitmap, msr); + } + + unsigned int __vmx_vcpu_run_flags(struct vcpu_vmx *vmx) +-- +2.35.3 + diff --git a/patches.suse/KVM-VMX-Inject-PF-on-ENCLS-as-emulated-PF.patch b/patches.suse/KVM-VMX-Inject-PF-on-ENCLS-as-emulated-PF.patch new file mode 100644 index 0000000..d53bc4e --- /dev/null +++ b/patches.suse/KVM-VMX-Inject-PF-on-ENCLS-as-emulated-PF.patch @@ -0,0 +1,39 @@ +Patch-mainline: v6.1-rc1 +Git-commit: bfcb08a0b9e99b959814a329fabace22c3df046d +References: git-fixes +From: Sean Christopherson +Date: Tue, 30 Aug 2022 23:15:59 +0000 +Subject: [PATCH] KVM: VMX: Inject #PF on ENCLS as "emulated" #PF + +Treat #PFs that occur during emulation of ENCLS as, wait for it, emulated +page faults. Practically speaking, this is a glorified nop as the +exception is never of the nested flavor, and it's extremely unlikely the +guest is relying on the side effect of an implicit INVLPG on the faulting +address. + +Fixes: 70210c044b4e ("KVM: VMX: Add SGX ENCLS[ECREATE] handler to enforce CPUID restrictions") +Signed-off-by: Sean Christopherson +Reviewed-by: Maxim Levitsky +Link: https://lore.kernel.org/r/20220830231614.3580124-13-seanjc@google.com +Signed-off-by: Paolo Bonzini +Signed-off-by: Juergen Gross +--- + arch/x86/kvm/vmx/sgx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/x86/kvm/vmx/sgx.c b/arch/x86/kvm/vmx/sgx.c +index aba8cebdc587..8f95c7c01433 100644 +--- a/arch/x86/kvm/vmx/sgx.c ++++ b/arch/x86/kvm/vmx/sgx.c +@@ -129,7 +129,7 @@ static int sgx_inject_fault(struct kvm_vcpu *vcpu, gva_t gva, int trapnr) + ex.address = gva; + ex.error_code_valid = true; + ex.nested_page_fault = false; +- kvm_inject_page_fault(vcpu, &ex); ++ kvm_inject_emulated_page_fault(vcpu, &ex); + } else { + kvm_inject_gp(vcpu, 0); + } +-- +2.35.3 + diff --git a/patches.suse/KVM-X86-Fix-when-shadow_root_level-5-guest-root_leve.patch b/patches.suse/KVM-X86-Fix-when-shadow_root_level-5-guest-root_leve.patch new file mode 100644 index 0000000..a211083 --- /dev/null +++ b/patches.suse/KVM-X86-Fix-when-shadow_root_level-5-guest-root_leve.patch @@ -0,0 +1,39 @@ +Patch-mainline: v5.16-rc4 +Git-commit: 12ec33a705749e18d9588b0a0e69e02821371156 +References: git-fixes +From: Lai Jiangshan +Date: Wed, 24 Nov 2021 20:20:43 +0800 +Subject: [PATCH] KVM: X86: Fix when shadow_root_level=5 && guest root_level<4 + +If the is an L1 with nNPT in 32bit, the shadow walk starts with +pae_root. + +Fixes: a717a780fc4e ("KVM: x86/mmu: Support shadowing NPT when 5-level paging is enabled in host) +Signed-off-by: Lai Jiangshan +Message-Id: <20211124122055.64424-2-jiangshanlai@gmail.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Juergen Gross +--- + arch/x86/kvm/mmu/mmu.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c +index 0c44581721b0..d7ae369ec8c2 100644 +--- a/arch/x86/kvm/mmu/mmu.c ++++ b/arch/x86/kvm/mmu/mmu.c +@@ -2173,10 +2173,10 @@ static void shadow_walk_init_using_root(struct kvm_shadow_walk_iterator *iterato + iterator->shadow_addr = root; + iterator->level = vcpu->arch.mmu->shadow_root_level; + +- if (iterator->level == PT64_ROOT_4LEVEL && ++ if (iterator->level >= PT64_ROOT_4LEVEL && + vcpu->arch.mmu->root_level < PT64_ROOT_4LEVEL && + !vcpu->arch.mmu->direct_map) +- --iterator->level; ++ iterator->level = PT32E_ROOT_LEVEL; + + if (iterator->level == PT32E_ROOT_LEVEL) { + /* +-- +2.35.3 + diff --git a/patches.suse/KVM-avoid-NULL-pointer-dereference-in-kvm_dirty_ring.patch b/patches.suse/KVM-avoid-NULL-pointer-dereference-in-kvm_dirty_ring.patch new file mode 100644 index 0000000..4893b52 --- /dev/null +++ b/patches.suse/KVM-avoid-NULL-pointer-dereference-in-kvm_dirty_ring.patch @@ -0,0 +1,53 @@ +Patch-mainline: v5.18-rc3 +Git-commit: 5593473a1e6c743764b08e3b6071cb43b5cfa6c4 +References: bsc#1198189 CVE-2022-1263 +From: Paolo Bonzini +Date: Wed, 6 Apr 2022 13:13:42 -0400 +Subject: [PATCH] KVM: avoid NULL pointer dereference in kvm_dirty_ring_push + +kvm_vcpu_release() will call kvm_dirty_ring_free(), freeing +ring->dirty_gfns and setting it to NULL. Afterwards, it calls +kvm_arch_vcpu_destroy(). + +However, if closing the file descriptor races with KVM_RUN in such away +that vcpu->arch.st.preempted == 0, the following call stack leads to a +NULL pointer dereference in kvm_dirty_run_push(): + + mark_page_dirty_in_slot+0x192/0x270 arch/x86/kvm/../../../virt/kvm/kvm_main.c:3171 + kvm_steal_time_set_preempted arch/x86/kvm/x86.c:4600 [inline] + kvm_arch_vcpu_put+0x34e/0x5b0 arch/x86/kvm/x86.c:4618 + vcpu_put+0x1b/0x70 arch/x86/kvm/../../../virt/kvm/kvm_main.c:211 + vmx_free_vcpu+0xcb/0x130 arch/x86/kvm/vmx/vmx.c:6985 + kvm_arch_vcpu_destroy+0x76/0x290 arch/x86/kvm/x86.c:11219 + kvm_vcpu_destroy arch/x86/kvm/../../../virt/kvm/kvm_main.c:441 [inline] + +The fix is to release the dirty page ring after kvm_arch_vcpu_destroy +has run. + +Reported-by: Qiuhao Li +Reported-by: Gaoning Pan +Reported-by: Yongkang Jia +Cc: stable@vger.kernel.org +Signed-off-by: Paolo Bonzini +Signed-off-by: Juergen Gross +--- + virt/kvm/kvm_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c +index 70e05af5ebea..b22f380e3347 100644 +--- a/virt/kvm/kvm_main.c ++++ b/virt/kvm/kvm_main.c +@@ -434,8 +434,8 @@ static void kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned id) + + void kvm_vcpu_destroy(struct kvm_vcpu *vcpu) + { +- kvm_dirty_ring_free(&vcpu->dirty_ring); + kvm_arch_vcpu_destroy(vcpu); ++ kvm_dirty_ring_free(&vcpu->dirty_ring); + + /* + * No need for rcu_read_lock as VCPU_RUN is the only place that changes +-- +2.35.3 + diff --git a/patches.suse/KVM-s390-pv-don-t-present-the-ecall-interrupt-twice b/patches.suse/KVM-s390-pv-don-t-present-the-ecall-interrupt-twice new file mode 100644 index 0000000..05e32d9 --- /dev/null +++ b/patches.suse/KVM-s390-pv-don-t-present-the-ecall-interrupt-twice @@ -0,0 +1,98 @@ +From: Nico Boehr +Date: Mon, 18 Jul 2022 15:04:34 +0200 +Subject: KVM: s390: pv: don't present the ecall interrupt twice +Git-commit: c3f0e5fd2d33d80c5a5a8b5e5d2bab2841709cc8 +Patch-mainline: v6.0-rc1 +References: bsc#1203229 LTC#199905 + +When the SIGP interpretation facility is present and a VCPU sends an +ecall to another VCPU in enabled wait, the sending VCPU receives a 56 +intercept (partial execution), so KVM can wake up the receiving CPU. +Note that the SIGP interpretation facility will take care of the +interrupt delivery and KVM's only job is to wake the receiving VCPU. + +For PV, the sending VCPU will receive a 108 intercept (pv notify) and +should continue like in the non-PV case, i.e. wake the receiving VCPU. + +For PV and non-PV guests the interrupt delivery will occur through the +SIGP interpretation facility on SIE entry when SIE finds the X bit in +the status field set. + +However, in handle_pv_notification(), there was no special handling for +SIGP, which leads to interrupt injection being requested by KVM for the +next SIE entry. This results in the interrupt being delivered twice: +once by the SIGP interpretation facility and once by KVM through the +IICTL. + +Add the necessary special handling in handle_pv_notification(), similar +to handle_partial_execution(), which simply wakes the receiving VCPU and +leave interrupt delivery to the SIGP interpretation facility. + +In contrast to external calls, emergency calls are not interpreted but +also cause a 108 intercept, which is why we still need to call +handle_instruction() for SIGP orders other than ecall. + +Since kvm_s390_handle_sigp_pei() is now called for all SIGP orders which +cause a 108 intercept - even if they are actually handled by +handle_instruction() - move the tracepoint in kvm_s390_handle_sigp_pei() +to avoid possibly confusing trace messages. + +Signed-off-by: Nico Boehr +Cc: # 5.7 +Fixes: da24a0cc58ed ("KVM: s390: protvirt: Instruction emulation") +Reviewed-by: Claudio Imbrenda +Reviewed-by: Janosch Frank +Reviewed-by: Christian Borntraeger +Link: https://lore.kernel.org/r/20220718130434.73302-1-nrb@linux.ibm.com +Message-Id: <20220718130434.73302-1-nrb@linux.ibm.com> +Signed-off-by: Claudio Imbrenda +Acked-by: Petr Tesarik +--- + arch/s390/kvm/intercept.c | 15 +++++++++++++++ + arch/s390/kvm/sigp.c | 4 ++-- + 2 files changed, 17 insertions(+), 2 deletions(-) + +--- a/arch/s390/kvm/intercept.c ++++ b/arch/s390/kvm/intercept.c +@@ -526,12 +526,27 @@ static int handle_pv_uvc(struct kvm_vcpu + + static int handle_pv_notification(struct kvm_vcpu *vcpu) + { ++ int ret; ++ + if (vcpu->arch.sie_block->ipa == 0xb210) + return handle_pv_spx(vcpu); + if (vcpu->arch.sie_block->ipa == 0xb220) + return handle_pv_sclp(vcpu); + if (vcpu->arch.sie_block->ipa == 0xb9a4) + return handle_pv_uvc(vcpu); ++ if (vcpu->arch.sie_block->ipa >> 8 == 0xae) { ++ /* ++ * Besides external call, other SIGP orders also cause a ++ * 108 (pv notify) intercept. In contrast to external call, ++ * these orders need to be emulated and hence the appropriate ++ * place to handle them is in handle_instruction(). ++ * So first try kvm_s390_handle_sigp_pei() and if that isn't ++ * successful, go on with handle_instruction(). ++ */ ++ ret = kvm_s390_handle_sigp_pei(vcpu); ++ if (!ret) ++ return ret; ++ } + + return handle_instruction(vcpu); + } +--- a/arch/s390/kvm/sigp.c ++++ b/arch/s390/kvm/sigp.c +@@ -464,9 +464,9 @@ int kvm_s390_handle_sigp_pei(struct kvm_ + struct kvm_vcpu *dest_vcpu; + u8 order_code = kvm_s390_get_base_disp_rs(vcpu, NULL); + +- trace_kvm_s390_handle_sigp_pei(vcpu, order_code, cpu_addr); +- + if (order_code == SIGP_EXTERNAL_CALL) { ++ trace_kvm_s390_handle_sigp_pei(vcpu, order_code, cpu_addr); ++ + dest_vcpu = kvm_get_vcpu_by_id(vcpu->kvm, cpu_addr); + BUG_ON(dest_vcpu == NULL); + diff --git a/patches.suse/KVM-x86-Avoid-theoretical-NULL-pointer-dereference-i.patch b/patches.suse/KVM-x86-Avoid-theoretical-NULL-pointer-dereference-i.patch index ea560f6..73569da 100644 --- a/patches.suse/KVM-x86-Avoid-theoretical-NULL-pointer-dereference-i.patch +++ b/patches.suse/KVM-x86-Avoid-theoretical-NULL-pointer-dereference-i.patch @@ -1,6 +1,6 @@ Patch-mainline: v5.18-rc1 Git-commit: 00b5f37189d24ac3ed46cb7f11742094778c46ce -References: git-fixes +References: bsc#1200788 CVE-2022-2153 From: Vitaly Kuznetsov Date: Fri, 25 Mar 2022 14:21:39 +0100 Subject: [PATCH] KVM: x86: Avoid theoretical NULL pointer dereference in diff --git a/patches.suse/KVM-x86-Check-lapic_in_kernel-before-attempting-to-s.patch b/patches.suse/KVM-x86-Check-lapic_in_kernel-before-attempting-to-s.patch index 4e5e819..f3acdf7 100644 --- a/patches.suse/KVM-x86-Check-lapic_in_kernel-before-attempting-to-s.patch +++ b/patches.suse/KVM-x86-Check-lapic_in_kernel-before-attempting-to-s.patch @@ -1,6 +1,6 @@ Patch-mainline: v5.18-rc1 Git-commit: 7ec37d1cbe17d8189d9562178d8b29167fe1c31a -References: git-fixes +References: bsc#1200788 CVE-2022-2153 From: Vitaly Kuznetsov Date: Fri, 25 Mar 2022 14:21:38 +0100 Subject: [PATCH] KVM: x86: Check lapic_in_kernel() before attempting to set a diff --git a/patches.suse/KVM-x86-Forbid-VMM-to-set-SYNIC-STIMER-MSRs-when-Syn.patch b/patches.suse/KVM-x86-Forbid-VMM-to-set-SYNIC-STIMER-MSRs-when-Syn.patch index e655e0d..6df768b 100644 --- a/patches.suse/KVM-x86-Forbid-VMM-to-set-SYNIC-STIMER-MSRs-when-Syn.patch +++ b/patches.suse/KVM-x86-Forbid-VMM-to-set-SYNIC-STIMER-MSRs-when-Syn.patch @@ -1,6 +1,6 @@ Patch-mainline: v5.18-rc1 Git-commit: b1e34d325397a33d97d845e312d7cf2a8b646b44 -References: git-fixes +References: bsc#1200788 CVE-2022-2153 From: Vitaly Kuznetsov Date: Fri, 25 Mar 2022 14:21:40 +0100 Subject: [PATCH] KVM: x86: Forbid VMM to set SYNIC/STIMER MSRs when SynIC diff --git a/patches.suse/KVM-x86-Inject-UD-on-emulated-XSETBV-if-XSAVES-isn-t.patch b/patches.suse/KVM-x86-Inject-UD-on-emulated-XSETBV-if-XSAVES-isn-t.patch new file mode 100644 index 0000000..8b8ab0e --- /dev/null +++ b/patches.suse/KVM-x86-Inject-UD-on-emulated-XSETBV-if-XSAVES-isn-t.patch @@ -0,0 +1,61 @@ +Patch-mainline: v6.0-rc7 +Git-commit: 50b2d49bafa16e6311ab2da82f5aafc5f9ada99b +References: git-fixes +From: Sean Christopherson +Date: Wed, 24 Aug 2022 03:30:57 +0000 +Subject: [PATCH] KVM: x86: Inject #UD on emulated XSETBV if XSAVES isn't + enabled + +Inject #UD when emulating XSETBV if CR4.OSXSAVE is not set. This also +covers the "XSAVE not supported" check, as setting CR4.OSXSAVE=1 #GPs if +XSAVE is not supported (and userspace gets to keep the pieces if it +forces incoherent vCPU state). + +Add a comment to kvm_emulate_xsetbv() to call out that the CPU checks +CR4.OSXSAVE before checking for intercepts. AMD'S APM implies that #UD +has priority (says that intercepts are checked before #GP exceptions), +while Intel's SDM says nothing about interception priority. However, +testing on hardware shows that both AMD and Intel CPUs prioritize the #UD +over interception. + +Fixes: 02d4160fbd76 ("x86: KVM: add xsetbv to the emulator") +Cc: stable@vger.kernel.org +Cc: Vitaly Kuznetsov +Signed-off-by: Sean Christopherson +Message-Id: <20220824033057.3576315-4-seanjc@google.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Juergen Gross +--- + arch/x86/kvm/emulate.c | 3 +++ + arch/x86/kvm/x86.c | 1 + + 2 files changed, 4 insertions(+) + +diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c +index d5ec3a2ed5a4..aacb28c83e43 100644 +--- a/arch/x86/kvm/emulate.c ++++ b/arch/x86/kvm/emulate.c +@@ -4132,6 +4132,9 @@ static int em_xsetbv(struct x86_emulate_ctxt *ctxt) + { + u32 eax, ecx, edx; + ++ if (!(ctxt->ops->get_cr(ctxt, 4) & X86_CR4_OSXSAVE)) ++ return emulate_ud(ctxt); ++ + eax = reg_read(ctxt, VCPU_REGS_RAX); + edx = reg_read(ctxt, VCPU_REGS_RDX); + ecx = reg_read(ctxt, VCPU_REGS_RCX); +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index c95cf18a796c..b0c47b41c264 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -1065,6 +1065,7 @@ static int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr) + + int kvm_emulate_xsetbv(struct kvm_vcpu *vcpu) + { ++ /* Note, #UD due to CR4.OSXSAVE=0 has priority over the intercept. */ + if (static_call(kvm_x86_get_cpl)(vcpu) != 0 || + __kvm_set_xcr(vcpu, kvm_rcx_read(vcpu), kvm_read_edx_eax(vcpu))) { + kvm_inject_gp(vcpu, 0); +-- +2.35.3 + diff --git a/patches.suse/KVM-x86-Move-lookup-of-indexed-CPUID-leafs-to-helper b/patches.suse/KVM-x86-Move-lookup-of-indexed-CPUID-leafs-to-helper new file mode 100644 index 0000000..709847c --- /dev/null +++ b/patches.suse/KVM-x86-Move-lookup-of-indexed-CPUID-leafs-to-helper @@ -0,0 +1,94 @@ +From: Michael Roth +Date: Thu, 24 Feb 2022 10:56:10 -0600 +Subject: KVM: x86: Move lookup of indexed CPUID leafs to helper +Git-commit: b66370db9a90b3fa4c4a1a732af3e7e38d6d4c7c +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +Determining which CPUID leafs have significant ECX/index values is +also needed by guest kernel code when doing SEV-SNP-validated CPUID +lookups. Move this to common code to keep future updates in sync. + +Signed-off-by: Michael Roth +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Reviewed-by: Venu Busireddy +Link: https://lore.kernel.org/r/20220307213356.2797205-31-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/include/asm/cpuid.h | 34 ++++++++++++++++++++++++++++++++++ + arch/x86/kvm/cpuid.c | 17 ++--------------- + 2 files changed, 36 insertions(+), 15 deletions(-) + +--- /dev/null ++++ b/arch/x86/include/asm/cpuid.h +@@ -0,0 +1,34 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * CPUID-related helpers/definitions ++ * ++ * Derived from arch/x86/kvm/cpuid.c ++ */ ++ ++#ifndef _ASM_X86_CPUID_H ++#define _ASM_X86_CPUID_H ++ ++static __always_inline bool cpuid_function_is_indexed(u32 function) ++{ ++ switch (function) { ++ case 4: ++ case 7: ++ case 0xb: ++ case 0xd: ++ case 0xf: ++ case 0x10: ++ case 0x12: ++ case 0x14: ++ case 0x17: ++ case 0x18: ++ case 0x1d: ++ case 0x1e: ++ case 0x1f: ++ case 0x8000001d: ++ return true; ++ } ++ ++ return false; ++} ++ ++#endif /* _ASM_X86_CPUID_H */ +--- a/arch/x86/kvm/cpuid.c ++++ b/arch/x86/kvm/cpuid.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + #include "cpuid.h" + #include "lapic.h" + #include "mmu.h" +@@ -583,22 +584,8 @@ static struct kvm_cpuid_entry2 *do_host_ + cpuid_count(entry->function, entry->index, + &entry->eax, &entry->ebx, &entry->ecx, &entry->edx); + +- switch (function) { +- case 4: +- case 7: +- case 0xb: +- case 0xd: +- case 0xf: +- case 0x10: +- case 0x12: +- case 0x14: +- case 0x17: +- case 0x18: +- case 0x1f: +- case 0x8000001d: ++ if (cpuid_function_is_indexed(function)) + entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX; +- break; +- } + + return entry; + } diff --git a/patches.suse/KVM-x86-Register-Processor-Trace-interrupt-hook-iff-.patch b/patches.suse/KVM-x86-Register-Processor-Trace-interrupt-hook-iff-.patch index 44aed83..0e51bbb 100644 --- a/patches.suse/KVM-x86-Register-Processor-Trace-interrupt-hook-iff-.patch +++ b/patches.suse/KVM-x86-Register-Processor-Trace-interrupt-hook-iff-.patch @@ -63,25 +63,23 @@ index 50f0cd16f2d4..760c4e3a8326 100644 }; #ifdef CONFIG_X86_64 -@@ -11222,6 +11222,9 @@ int kvm_arch_hardware_setup(void *opaque) +@@ -11222,6 +11222,8 @@ int kvm_arch_hardware_setup(void *opaque) memcpy(&kvm_x86_ops, ops->runtime_ops, sizeof(kvm_x86_ops)); kvm_ops_static_call_update(); + if (ops->intel_pt_intr_in_guest && ops->intel_pt_intr_in_guest()) + kvm_guest_cbs.handle_intel_pt_intr = kvm_handle_intel_pt_intr; -+ - if (!kvm_cpu_cap_has(X86_FEATURE_XSAVES)) - supported_xss = 0; - -@@ -11252,6 +11255,8 @@ int kvm_arch_hardware_setup(void *opaque) + perf_register_guest_info_callbacks(&kvm_guest_cbs); + if (!kvm_cpu_cap_has(X86_FEATURE_XSAVES)) +@@ -11252,6 +11255,7 @@ int kvm_arch_hardware_setup(void *opaque) void kvm_arch_hardware_unsetup(void) { + perf_unregister_guest_info_callbacks(&kvm_guest_cbs); + kvm_guest_cbs.handle_intel_pt_intr = NULL; -+ + static_call(kvm_x86_hardware_unsetup)(); } - -- 2.35.3 diff --git a/patches.suse/KVM-x86-Register-perf-callbacks-after-calling-vendor.patch b/patches.suse/KVM-x86-Register-perf-callbacks-after-calling-vendor.patch new file mode 100644 index 0000000..436bdbf --- /dev/null +++ b/patches.suse/KVM-x86-Register-perf-callbacks-after-calling-vendor.patch @@ -0,0 +1,70 @@ +Patch-mainline: v5.17-rc1 +Git-commit: 5c7df80e2ce4c954c80eb4ecf5fa002a5ff5d2d6 +References: git-fixes +From: Sean Christopherson +Date: Thu, 11 Nov 2021 02:07:23 +0000 +Subject: [PATCH] KVM: x86: Register perf callbacks after calling vendor's + hardware_setup() + +Wait to register perf callbacks until after doing vendor hardaware setup. +VMX's hardware_setup() configures Intel Processor Trace (PT) mode, and a +future fix to register the Intel PT guest interrupt hook if and only if +Intel PT is exposed to the guest will consume the configured PT mode. + +Delaying registration to hardware setup is effectively a nop as KVM's perf +hooks all pivot on the per-CPU current_vcpu, which is non-NULL only when +KVM is handling an IRQ/NMI in a VM-Exit path. I.e. current_vcpu will be +NULL throughout both kvm_arch_init() and kvm_arch_hardware_setup(). + +Signed-off-by: Sean Christopherson +Signed-off-by: Peter Zijlstra (Intel) +Acked-by: Paolo Bonzini +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20211111020738.2512932-3-seanjc@google.com +Signed-off-by: Juergen Gross +--- + arch/x86/kvm/x86.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index dc7eb5fddfd3..50f0cd16f2d4 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -8626,8 +8626,6 @@ int kvm_arch_init(void *opaque) + + kvm_timer_init(); + +- perf_register_guest_info_callbacks(&kvm_guest_cbs); +- + if (boot_cpu_has(X86_FEATURE_XSAVE)) { + host_xcr0 = xgetbv(XCR_XFEATURE_ENABLED_MASK); + supported_xcr0 = host_xcr0 & KVM_SUPPORTED_XCR0; +@@ -8659,7 +8657,6 @@ void kvm_arch_exit(void) + clear_hv_tscchange_cb(); + #endif + kvm_lapic_exit(); +- perf_unregister_guest_info_callbacks(&kvm_guest_cbs); + + if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) + cpufreq_unregister_notifier(&kvmclock_cpufreq_notifier_block, +@@ -11225,6 +11222,8 @@ int kvm_arch_hardware_setup(void *opaque) + memcpy(&kvm_x86_ops, ops->runtime_ops, sizeof(kvm_x86_ops)); + kvm_ops_static_call_update(); + ++ perf_register_guest_info_callbacks(&kvm_guest_cbs); ++ + if (!kvm_cpu_cap_has(X86_FEATURE_XSAVES)) + supported_xss = 0; + +@@ -11252,6 +11251,8 @@ int kvm_arch_hardware_setup(void *opaque) + + void kvm_arch_hardware_unsetup(void) + { ++ perf_unregister_guest_info_callbacks(&kvm_guest_cbs); ++ + static_call(kvm_x86_hardware_unsetup)(); + } + +-- +2.35.3 + diff --git a/patches.suse/KVM-x86-do-not-report-preemption-if-the-steal-time-c.patch b/patches.suse/KVM-x86-do-not-report-preemption-if-the-steal-time-c.patch new file mode 100644 index 0000000..8908584 --- /dev/null +++ b/patches.suse/KVM-x86-do-not-report-preemption-if-the-steal-time-c.patch @@ -0,0 +1,49 @@ +Patch-mainline: v6.0-rc1 +Git-commit: c3c28d24d910a746b02f496d190e0e8c6560224b +References: git-fixes +From: Paolo Bonzini +Date: Thu, 4 Aug 2022 15:28:32 +0200 +Subject: [PATCH] KVM: x86: do not report preemption if the steal time cache is + stale + +Commit 7e2175ebd695 ("KVM: x86: Fix recording of guest steal time +/ preempted status", 2021-11-11) open coded the previous call to +kvm_map_gfn, but in doing so it dropped the comparison between the cached +guest physical address and the one in the MSR. This cause an incorrect +cache hit if the guest modifies the steal time address while the memslots +remain the same. This can happen with kexec, in which case the preempted +bit is written at the address used by the old kernel instead of +the old one. + +Cc: David Woodhouse +Cc: stable@vger.kernel.org +Fixes: 7e2175ebd695 ("KVM: x86: Fix recording of guest steal time / preempted status") +Signed-off-by: Paolo Bonzini +Signed-off-by: Juergen Gross +--- + arch/x86/kvm/x86.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index 0f3c2e034740..8ee4698cb90a 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -4715,6 +4715,7 @@ static void kvm_steal_time_set_preempted(struct kvm_vcpu *vcpu) + struct kvm_steal_time __user *st; + struct kvm_memslots *slots; + static const u8 preempted = KVM_VCPU_PREEMPTED; ++ gpa_t gpa = vcpu->arch.st.msr_val & KVM_STEAL_VALID_BITS; + + /* + * The vCPU can be marked preempted if and only if the VM-Exit was on +@@ -4742,6 +4743,7 @@ static void kvm_steal_time_set_preempted(struct kvm_vcpu *vcpu) + slots = kvm_memslots(vcpu->kvm); + + if (unlikely(slots->generation != ghc->generation || ++ gpa != ghc->gpa || + kvm_is_error_hva(ghc->hva) || !ghc->memslot)) + return; + +-- +2.35.3 + diff --git a/patches.suse/KVM-x86-hyper-v-Drop-redundant-ex-parameter-from-kvm-ipi.patch b/patches.suse/KVM-x86-hyper-v-Drop-redundant-ex-parameter-from-kvm-ipi.patch new file mode 100644 index 0000000..153ec41 --- /dev/null +++ b/patches.suse/KVM-x86-hyper-v-Drop-redundant-ex-parameter-from-kvm-ipi.patch @@ -0,0 +1,64 @@ +Patch-mainline: v5.18-rc1 +Git-commit: 50e523dd79f6a856d793ce5711719abe27cffbf2 +References: git-fixes +From: Vitaly Kuznetsov +Date: Tue, 22 Feb 2022 16:46:39 +0100 +Subject: [PATCH] KVM: x86: hyper-v: Drop redundant 'ex' parameter from + kvm_hv_send_ipi() + +'struct kvm_hv_hcall' has all the required information already, +there's no need to pass 'ex' additionally. + +No functional change intended. + +Cc: stable@vger.kernel.org # 5.14.x +Signed-off-by: Vitaly Kuznetsov +Message-Id: <20220222154642.684285-2-vkuznets@redhat.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Juergen Gross +--- + arch/x86/kvm/hyperv.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c +index 8d8c1cc7cb53..ea9abe45931c 100644 +--- a/arch/x86/kvm/hyperv.c ++++ b/arch/x86/kvm/hyperv.c +@@ -1874,7 +1874,7 @@ static void kvm_send_ipi_to_many(struct kvm *kvm, u32 vector, + } + } + +-static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc, bool ex) ++static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc) + { + struct kvm *kvm = vcpu->kvm; + struct hv_send_ipi_ex send_ipi_ex; +@@ -1888,7 +1888,7 @@ static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc, bool + u32 vector; + bool all_cpus; + +- if (!ex) { ++ if (hc->code == HVCALL_SEND_IPI) { + if (!hc->fast) { + if (unlikely(kvm_read_guest(kvm, hc->ingpa, &send_ipi, + sizeof(send_ipi)))) +@@ -2278,14 +2278,14 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu) + ret = HV_STATUS_INVALID_HYPERCALL_INPUT; + break; + } +- ret = kvm_hv_send_ipi(vcpu, &hc, false); ++ ret = kvm_hv_send_ipi(vcpu, &hc); + break; + case HVCALL_SEND_IPI_EX: + if (unlikely(hc.fast || hc.rep)) { + ret = HV_STATUS_INVALID_HYPERCALL_INPUT; + break; + } +- ret = kvm_hv_send_ipi(vcpu, &hc, true); ++ ret = kvm_hv_send_ipi(vcpu, &hc); + break; + case HVCALL_POST_DEBUG_DATA: + case HVCALL_RETRIEVE_DEBUG_DATA: +-- +2.35.3 + diff --git a/patches.suse/KVM-x86-hyper-v-HVCALL_SEND_IPI_EX-is-an-XMM-fast-hy.patch b/patches.suse/KVM-x86-hyper-v-HVCALL_SEND_IPI_EX-is-an-XMM-fast-hy.patch new file mode 100644 index 0000000..070eedf --- /dev/null +++ b/patches.suse/KVM-x86-hyper-v-HVCALL_SEND_IPI_EX-is-an-XMM-fast-hy.patch @@ -0,0 +1,131 @@ +Patch-mainline: v5.18-rc1 +Git-commit: 47d3e5cdfe607ec6883eb0faa7acf05b8cb3f92a +References: git-fixes +From: Vitaly Kuznetsov +Date: Tue, 22 Feb 2022 16:46:42 +0100 +Subject: [PATCH] KVM: x86: hyper-v: HVCALL_SEND_IPI_EX is an XMM fast + hypercall + +It has been proven on practice that at least Windows Server 2019 tries +using HVCALL_SEND_IPI_EX in 'XMM fast' mode when it has more than 64 vCPUs +and it needs to send an IPI to a vCPU > 63. Similarly to other XMM Fast +hypercalls (HVCALL_FLUSH_VIRTUAL_ADDRESS_{LIST,SPACE}{,_EX}), this +information is missing in TLFS as of 6.0b. Currently, KVM returns an error +(HV_STATUS_INVALID_HYPERCALL_INPUT) and Windows crashes. + +Note, HVCALL_SEND_IPI is a 'standard' fast hypercall (not 'XMM fast') as +all its parameters fit into RDX:R8 and this is handled by KVM correctly. + +Cc: stable@vger.kernel.org # 5.14.x: 3244867af8c0: KVM: x86: Ignore sparse banks size for an "all CPUs", non-sparse IPI req +Cc: stable@vger.kernel.org # 5.14.x +Fixes: d8f5537a8816 ("KVM: hyper-v: Advertise support for fast XMM hypercalls") +Signed-off-by: Vitaly Kuznetsov +Message-Id: <20220222154642.684285-5-vkuznets@redhat.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Juergen Gross +--- + arch/x86/kvm/hyperv.c | 52 ++++++++++++++++++++++++++++--------------- + 1 file changed, 34 insertions(+), 18 deletions(-) + +diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c +index 8f07b13c9f15..edf024f1f141 100644 +--- a/arch/x86/kvm/hyperv.c ++++ b/arch/x86/kvm/hyperv.c +@@ -1889,6 +1889,7 @@ static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc) + int sparse_banks_len; + u32 vector; + bool all_cpus; ++ int i; + + if (hc->code == HVCALL_SEND_IPI) { + if (!hc->fast) { +@@ -1909,9 +1910,15 @@ static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc) + + trace_kvm_hv_send_ipi(vector, sparse_banks[0]); + } else { +- if (unlikely(kvm_read_guest(kvm, hc->ingpa, &send_ipi_ex, +- sizeof(send_ipi_ex)))) +- return HV_STATUS_INVALID_HYPERCALL_INPUT; ++ if (!hc->fast) { ++ if (unlikely(kvm_read_guest(kvm, hc->ingpa, &send_ipi_ex, ++ sizeof(send_ipi_ex)))) ++ return HV_STATUS_INVALID_HYPERCALL_INPUT; ++ } else { ++ send_ipi_ex.vector = (u32)hc->ingpa; ++ send_ipi_ex.vp_set.format = hc->outgpa; ++ send_ipi_ex.vp_set.valid_bank_mask = sse128_lo(hc->xmm[0]); ++ } + + trace_kvm_hv_send_ipi_ex(send_ipi_ex.vector, + send_ipi_ex.vp_set.format, +@@ -1919,8 +1926,7 @@ static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc) + + vector = send_ipi_ex.vector; + valid_bank_mask = send_ipi_ex.vp_set.valid_bank_mask; +- sparse_banks_len = bitmap_weight(&valid_bank_mask, 64) * +- sizeof(sparse_banks[0]); ++ sparse_banks_len = bitmap_weight(&valid_bank_mask, 64); + + all_cpus = send_ipi_ex.vp_set.format == HV_GENERIC_SET_ALL; + +@@ -1930,12 +1936,27 @@ static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc) + if (!sparse_banks_len) + goto ret_success; + +- if (kvm_read_guest(kvm, +- hc->ingpa + offsetof(struct hv_send_ipi_ex, +- vp_set.bank_contents), +- sparse_banks, +- sparse_banks_len)) +- return HV_STATUS_INVALID_HYPERCALL_INPUT; ++ if (!hc->fast) { ++ if (kvm_read_guest(kvm, ++ hc->ingpa + offsetof(struct hv_send_ipi_ex, ++ vp_set.bank_contents), ++ sparse_banks, ++ sparse_banks_len * sizeof(sparse_banks[0]))) ++ return HV_STATUS_INVALID_HYPERCALL_INPUT; ++ } else { ++ /* ++ * The lower half of XMM0 is already consumed, each XMM holds ++ * two sparse banks. ++ */ ++ if (sparse_banks_len > (2 * HV_HYPERCALL_MAX_XMM_REGISTERS - 1)) ++ return HV_STATUS_INVALID_HYPERCALL_INPUT; ++ for (i = 0; i < sparse_banks_len; i++) { ++ if (i % 2) ++ sparse_banks[i] = sse128_lo(hc->xmm[(i + 1) / 2]); ++ else ++ sparse_banks[i] = sse128_hi(hc->xmm[i / 2]); ++ } ++ } + } + + check_and_send_ipi: +@@ -2097,6 +2118,7 @@ static bool is_xmm_fast_hypercall(struct kvm_hv_hcall *hc) + case HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE: + case HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX: + case HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX: ++ case HVCALL_SEND_IPI_EX: + return true; + } + +@@ -2264,14 +2286,8 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu) + ret = kvm_hv_flush_tlb(vcpu, &hc); + break; + case HVCALL_SEND_IPI: +- if (unlikely(hc.rep)) { +- ret = HV_STATUS_INVALID_HYPERCALL_INPUT; +- break; +- } +- ret = kvm_hv_send_ipi(vcpu, &hc); +- break; + case HVCALL_SEND_IPI_EX: +- if (unlikely(hc.fast || hc.rep)) { ++ if (unlikely(hc.rep)) { + ret = HV_STATUS_INVALID_HYPERCALL_INPUT; + break; + } +-- +2.35.3 + diff --git a/patches.suse/Makefile.debug-re-enable-debug-info-for-.S-files.patch b/patches.suse/Makefile.debug-re-enable-debug-info-for-.S-files.patch new file mode 100644 index 0000000..e4d6aa3 --- /dev/null +++ b/patches.suse/Makefile.debug-re-enable-debug-info-for-.S-files.patch @@ -0,0 +1,98 @@ +From e96f326803e59ce0bca4af22334e4035d532ebbd Mon Sep 17 00:00:00 2001 +From: Nick Desaulniers +Date: Mon, 19 Sep 2022 10:45:47 -0700 +Subject: [PATCH] Makefile.debug: re-enable debug info for .S files + +References: git-fixes +Patch-mainline: v6.0-rc7 +Git-commit: 32ef9e5054ec0321b9336058c58ec749e9c6b0fe + +Alexey reported that the fraction of unknown filename instances in +kallsyms grew from ~0.3% to ~10% recently; Bill and Greg tracked it down +to assembler defined symbols, which regressed as a result of: + +commit b8a9092330da ("Kbuild: do not emit debug info for assembly with LLVM_IAS=1") + +In that commit, I allude to restoring debug info for assembler defined +symbols in a follow up patch, but it seems I forgot to do so in + +commit a66049e2cf0e ("Kbuild: make DWARF version a choice") + +Link: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=31bf18645d98b4d3d7357353be840e320649a67d +Fixes: b8a9092330da ("Kbuild: do not emit debug info for assembly with LLVM_IAS=1") +Reported-by: Alexey Alexandrov +Reported-by: Bill Wendling +Reported-by: Greg Thelen +Reviewed-by: Nathan Chancellor +Suggested-by: Masahiro Yamada +Signed-off-by: Nick Desaulniers +Signed-off-by: Masahiro Yamada +[adjust for context: DEBUG_CFLAGS := added upstream is already before +ifdef CONFIG_DEBUG_INFO in the old makefile] +Acked-by: Michal Suchanek +--- + Makefile | 22 +++++++++++----------- + lib/Kconfig.debug | 4 +++- + 2 files changed, 14 insertions(+), 12 deletions(-) + +diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug +index c9a885f6c98e..f880c84f151f 100644 +--- a/lib/Kconfig.debug ++++ b/lib/Kconfig.debug +@@ -286,8 +286,10 @@ config DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT + + config DEBUG_INFO_DWARF4 + bool "Generate DWARF Version 4 debuginfo" ++ depends on !CC_IS_CLANG || (CC_IS_CLANG && (AS_IS_LLVM || (AS_IS_GNU && AS_VERSION >= 23502))) + help +- Generate DWARF v4 debug info. This requires gcc 4.5+ and gdb 7.0+. ++ Generate DWARF v4 debug info. This requires gcc 4.5+, binutils 2.35.2 ++ if using clang without clang's integrated assembler, and gdb 7.0+. + + If you have consumers of DWARF debug info that are not ready for + newer revisions of DWARF, you may wish to choose this or have your +diff --git a/Makefile b/Makefile +index bfbac35bbb8b..b9b2be937f83 100644 +--- a/Makefile ++++ b/Makefile +@@ -869,21 +869,21 @@ endif + + ifdef CONFIG_DEBUG_INFO + ++debug-flags-y := -g ++ + ifdef CONFIG_DEBUG_INFO_SPLIT + DEBUG_CFLAGS += -gsplit-dwarf +-else +-DEBUG_CFLAGS += -g +-endif +- +-ifneq ($(LLVM_IAS),1) +-KBUILD_AFLAGS += -Wa,-gdwarf-2 + endif + +-ifndef CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT +-dwarf-version-$(CONFIG_DEBUG_INFO_DWARF4) := 4 +-dwarf-version-$(CONFIG_DEBUG_INFO_DWARF5) := 5 +-DEBUG_CFLAGS += -gdwarf-$(dwarf-version-y) ++debug-flags-$(CONFIG_DEBUG_INFO_DWARF4) += -gdwarf-4 ++debug-flags-$(CONFIG_DEBUG_INFO_DWARF5) += -gdwarf-5 ++ifeq ($(CONFIG_CC_IS_CLANG)$(CONFIG_AS_IS_GNU),yy) ++# Clang does not pass -g or -gdwarf-* option down to GAS. ++# Add -Wa, prefix to explicitly specify the flags. ++KBUILD_AFLAGS += $(addprefix -Wa$(comma), $(debug-flags-y)) + endif ++DEBUG_CFLAGS += $(debug-flags-y) ++KBUILD_AFLAGS += $(debug-flags-y) + + ifdef CONFIG_DEBUG_INFO_REDUCED + DEBUG_CFLAGS += $(call cc-option, -femit-struct-debug-baseonly) \ +@@ -898,7 +898,7 @@ endif + + endif # CONFIG_DEBUG_INFO + +-KBUILD_CFLAGS += $(DEBUG_CFLAGS) ++KBUILD_CFLAGS += $(DEBUG_CFLAGS) + export DEBUG_CFLAGS + + ifdef CONFIG_FUNCTION_TRACER diff --git a/patches.suse/NFS-Fix-WARN_ON-due-to-unionization-of-nfs_inode.nre.patch b/patches.suse/NFS-Fix-WARN_ON-due-to-unionization-of-nfs_inode.nre.patch new file mode 100644 index 0000000..691f4c6 --- /dev/null +++ b/patches.suse/NFS-Fix-WARN_ON-due-to-unionization-of-nfs_inode.nre.patch @@ -0,0 +1,40 @@ +From: Dave Wysochanski +Date: Sun, 10 Oct 2021 18:23:13 -0400 +Subject: [PATCH] NFS: Fix WARN_ON due to unionization of nfs_inode.nrequests +Git-commit: 0ebeebcf59601bcfa0284f4bb7abdec051eb856d +Patch-mainline: v5.16 +References: git-fixes + +Fixes the following WARN_ON +Warning: CPU: 2 PID: 18678 at fs/nfs/inode.c:123 nfs_clear_inode+0x3b/0x50 [nfs] +... +Call Trace: + nfs4_evict_inode+0x57/0x70 [nfsv4] + evict+0xd1/0x180 + dispose_list+0x48/0x60 + evict_inodes+0x156/0x190 + generic_shutdown_super+0x37/0x110 + nfs_kill_super+0x1d/0x40 [nfs] + deactivate_locked_super+0x36/0xa0 + +Signed-off-by: Dave Wysochanski +Signed-off-by: Trond Myklebust +Acked-by: NeilBrown + +--- + include/linux/nfs_fs.h | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/include/linux/nfs_fs.h ++++ b/include/linux/nfs_fs.h +@@ -579,7 +579,9 @@ bool nfs_commit_end(struct nfs_mds_commi + static inline int + nfs_have_writebacks(struct inode *inode) + { +- return atomic_long_read(&NFS_I(inode)->nrequests) != 0; ++ if (S_ISREG(inode->i_mode)) ++ return atomic_long_read(&NFS_I(inode)->nrequests) != 0; ++ return 0; + } + + /* diff --git a/patches.suse/NFS-Fix-another-fsync-issue-after-a-server-reboot.patch b/patches.suse/NFS-Fix-another-fsync-issue-after-a-server-reboot.patch new file mode 100644 index 0000000..52a69ef --- /dev/null +++ b/patches.suse/NFS-Fix-another-fsync-issue-after-a-server-reboot.patch @@ -0,0 +1,113 @@ +From: Trond Myklebust +Date: Sat, 13 Aug 2022 08:22:25 -0400 +Subject: [PATCH] NFS: Fix another fsync() issue after a server reboot +Git-commit: 67f4b5dc49913abcdb5cc736e73674e2f352f81d +Patch-mainline: v6.0 +References: git-fixes + +Currently, when the writeback code detects a server reboot, it redirties +any pages that were not committed to disk, and it sets the flag +NFS_CONTEXT_RESEND_WRITES in the nfs_open_context of the file descriptor +that dirtied the file. While this allows the file descriptor in question +to redrive its own writes, it violates the fsync() requirement that we +should be synchronising all writes to disk. +While the problem is infrequent, we do see corner cases where an +untimely server reboot causes the fsync() call to abandon its attempt to +sync data to disk and causing data corruption issues due to missed error +conditions or similar. + +In order to tighted up the client's ability to deal with this situation +without introducing livelocks, add a counter that records the number of +times pages are redirtied due to a server reboot-like condition, and use +that in fsync() to redrive the sync to disk. + +Fixes: 2197e9b06c22 ("NFS: Fix up fsync() when the server rebooted") +Cc: stable@vger.kernel.org +Signed-off-by: Trond Myklebust +Acked-by: NeilBrown + +--- + fs/nfs/file.c | 15 ++++++--------- + fs/nfs/inode.c | 1 + + fs/nfs/write.c | 6 ++++-- + include/linux/nfs_fs.h | 1 + + 4 files changed, 12 insertions(+), 11 deletions(-) + +--- a/fs/nfs/file.c ++++ b/fs/nfs/file.c +@@ -234,8 +234,10 @@ nfs_file_fsync_commit(struct file *file, + int + nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync) + { +- struct nfs_open_context *ctx = nfs_file_open_context(file); + struct inode *inode = file_inode(file); ++ struct nfs_inode *nfsi = NFS_I(inode); ++ long save_nredirtied = atomic_long_read(&nfsi->redirtied_pages); ++ long nredirtied; + int ret; + + trace_nfs_fsync_enter(inode); +@@ -250,15 +252,10 @@ nfs_file_fsync(struct file *file, loff_t + ret = pnfs_sync_inode(inode, !!datasync); + if (ret != 0) + break; +- if (!test_and_clear_bit(NFS_CONTEXT_RESEND_WRITES, &ctx->flags)) ++ nredirtied = atomic_long_read(&nfsi->redirtied_pages); ++ if (nredirtied == save_nredirtied) + break; +- /* +- * If nfs_file_fsync_commit detected a server reboot, then +- * resend all dirty pages that might have been covered by +- * the NFS_CONTEXT_RESEND_WRITES flag +- */ +- start = 0; +- end = LLONG_MAX; ++ save_nredirtied = nredirtied; + } + + trace_nfs_fsync_exit(inode, ret); +--- a/fs/nfs/inode.c ++++ b/fs/nfs/inode.c +@@ -2265,6 +2265,7 @@ static void init_once(void *foo) + INIT_LIST_HEAD(&nfsi->access_cache_entry_lru); + INIT_LIST_HEAD(&nfsi->access_cache_inode_lru); + INIT_LIST_HEAD(&nfsi->commit_info.list); ++ atomic_long_set(&nfsi->redirtied_pages, 0); + atomic_long_set(&nfsi->nrequests, 0); + atomic_long_set(&nfsi->commit_info.ncommit, 0); + atomic_set(&nfsi->commit_info.rpcs_out, 0); +--- a/fs/nfs/write.c ++++ b/fs/nfs/write.c +@@ -1400,10 +1400,12 @@ static void nfs_initiate_write(struct nf + */ + static void nfs_redirty_request(struct nfs_page *req) + { ++ struct nfs_inode *nfsi = NFS_I(page_file_mapping(req->wb_page)->host); ++ + /* Bump the transmission count */ + req->wb_nio++; + nfs_mark_request_dirty(req); +- set_bit(NFS_CONTEXT_RESEND_WRITES, &nfs_req_openctx(req)->flags); ++ atomic_long_inc(&nfsi->redirtied_pages); + nfs_end_page_writeback(req); + nfs_release_request(req); + } +@@ -1847,7 +1849,7 @@ static void nfs_commit_release_pages(str + /* We have a mismatch. Write the page again */ + dprintk_cont(" mismatch\n"); + nfs_mark_request_dirty(req); +- set_bit(NFS_CONTEXT_RESEND_WRITES, &nfs_req_openctx(req)->flags); ++ atomic_long_inc(&NFS_I(data->inode)->redirtied_pages); + next: + nfs_unlock_and_release_request(req); + /* Latency breaker */ +--- a/include/linux/nfs_fs.h ++++ b/include/linux/nfs_fs.h +@@ -176,6 +176,7 @@ struct nfs_inode { + __be32 cookieverf[NFS_DIR_VERIFIER_SIZE]; + + atomic_long_t nrequests; ++ atomic_long_t redirtied_pages; + struct nfs_mds_commit_info commit_info; + + /* Open contexts for shared mmap writes */ diff --git a/patches.suse/NFS-LOOKUP_DIRECTORY-is-also-ok-with-symlinks.patch b/patches.suse/NFS-LOOKUP_DIRECTORY-is-also-ok-with-symlinks.patch new file mode 100644 index 0000000..6c9ade9 --- /dev/null +++ b/patches.suse/NFS-LOOKUP_DIRECTORY-is-also-ok-with-symlinks.patch @@ -0,0 +1,42 @@ +From: Trond Myklebust +Date: Tue, 8 Feb 2022 13:38:23 -0500 +Subject: [PATCH] NFS: LOOKUP_DIRECTORY is also ok with symlinks +Git-commit: e0caaf75d443e02e55e146fd75fe2efc8aed5540 +Patch-mainline: v5.17 +References: git-fixes + +Commit ac795161c936 (NFSv4: Handle case where the lookup of a directory +fails) [1], part of Linux since 5.17-rc2, introduced a regression, where +a symbolic link on an NFS mount to a directory on another NFS does not +resolve(?) the first time it is accessed: + +Reported-by: Paul Menzel +Fixes: ac795161c936 ("NFSv4: Handle case where the lookup of a directory fails") +Signed-off-by: Trond Myklebust +Tested-by: Donald Buczek +Signed-off-by: Anna Schumaker +Acked-by: NeilBrown + +--- + fs/nfs/dir.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/fs/nfs/dir.c ++++ b/fs/nfs/dir.c +@@ -1989,14 +1989,14 @@ no_open: + if (!res) { + inode = d_inode(dentry); + if ((lookup_flags & LOOKUP_DIRECTORY) && inode && +- !S_ISDIR(inode->i_mode)) ++ !(S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))) + res = ERR_PTR(-ENOTDIR); + else if (inode && S_ISREG(inode->i_mode)) + res = ERR_PTR(-EOPENSTALE); + } else if (!IS_ERR(res)) { + inode = d_inode(res); + if ((lookup_flags & LOOKUP_DIRECTORY) && inode && +- !S_ISDIR(inode->i_mode)) { ++ !(S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))) { + dput(res); + res = ERR_PTR(-ENOTDIR); + } else if (inode && S_ISREG(inode->i_mode)) { diff --git a/patches.suse/NFSD-Clean-up-the-show_nf_flags-macro.patch b/patches.suse/NFSD-Clean-up-the-show_nf_flags-macro.patch new file mode 100644 index 0000000..ba2e1e6 --- /dev/null +++ b/patches.suse/NFSD-Clean-up-the-show_nf_flags-macro.patch @@ -0,0 +1,32 @@ +From: Chuck Lever +Date: Sun, 27 Mar 2022 16:43:03 -0400 +Subject: [PATCH] NFSD: Clean up the show_nf_flags() macro +Git-commit: bb283ca18d1e67c82d22a329c96c9d6036a74790 +Patch-mainline: v5.19 +References: git-fixes + +The flags are defined using C macros, so TRACE_DEFINE_ENUM is +unnecessary. + +Signed-off-by: Chuck Lever +Acked-by: NeilBrown + +--- + fs/nfsd/trace.h | 6 ------ + 1 file changed, 6 deletions(-) + +--- a/fs/nfsd/trace.h ++++ b/fs/nfsd/trace.h +@@ -639,12 +639,6 @@ DEFINE_CLID_EVENT(confirmed_r); + /* + * from fs/nfsd/filecache.h + */ +-TRACE_DEFINE_ENUM(NFSD_FILE_HASHED); +-TRACE_DEFINE_ENUM(NFSD_FILE_PENDING); +-TRACE_DEFINE_ENUM(NFSD_FILE_BREAK_READ); +-TRACE_DEFINE_ENUM(NFSD_FILE_BREAK_WRITE); +-TRACE_DEFINE_ENUM(NFSD_FILE_REFERENCED); +- + #define show_nf_flags(val) \ + __print_flags(val, "|", \ + { 1 << NFSD_FILE_HASHED, "HASHED" }, \ diff --git a/patches.suse/NFSD-Fix-offset-type-in-I-O-trace-points.patch b/patches.suse/NFSD-Fix-offset-type-in-I-O-trace-points.patch new file mode 100644 index 0000000..0170280 --- /dev/null +++ b/patches.suse/NFSD-Fix-offset-type-in-I-O-trace-points.patch @@ -0,0 +1,58 @@ +From: Chuck Lever +Date: Fri, 4 Feb 2022 17:05:24 -0500 +Subject: [PATCH] NFSD: Fix offset type in I/O trace points +Git-commit: 6a4d333d540041d244b2fca29b8417bfde20af81 +Patch-mainline: v5.17 +References: git-fixes + +NFSv3 and NFSv4 use u64 offset values on the wire. Record these values +verbatim without the implicit type case to loff_t. + +Signed-off-by: Chuck Lever +Acked-by: NeilBrown + +--- + fs/nfsd/trace.h | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +--- a/fs/nfsd/trace.h ++++ b/fs/nfsd/trace.h +@@ -319,14 +319,14 @@ TRACE_EVENT(nfsd_export_update, + DECLARE_EVENT_CLASS(nfsd_io_class, + TP_PROTO(struct svc_rqst *rqstp, + struct svc_fh *fhp, +- loff_t offset, +- unsigned long len), ++ u64 offset, ++ u32 len), + TP_ARGS(rqstp, fhp, offset, len), + TP_STRUCT__entry( + __field(u32, xid) + __field(u32, fh_hash) +- __field(loff_t, offset) +- __field(unsigned long, len) ++ __field(u64, offset) ++ __field(u32, len) + ), + TP_fast_assign( + __entry->xid = be32_to_cpu(rqstp->rq_xid); +@@ -334,7 +334,7 @@ DECLARE_EVENT_CLASS(nfsd_io_class, + __entry->offset = offset; + __entry->len = len; + ), +- TP_printk("xid=0x%08x fh_hash=0x%08x offset=%lld len=%lu", ++ TP_printk("xid=0x%08x fh_hash=0x%08x offset=%llu len=%u", + __entry->xid, __entry->fh_hash, + __entry->offset, __entry->len) + ) +@@ -343,8 +343,8 @@ DECLARE_EVENT_CLASS(nfsd_io_class, + DEFINE_EVENT(nfsd_io_class, nfsd_##name, \ + TP_PROTO(struct svc_rqst *rqstp, \ + struct svc_fh *fhp, \ +- loff_t offset, \ +- unsigned long len), \ ++ u64 offset, \ ++ u32 len), \ + TP_ARGS(rqstp, fhp, offset, len)) + + DEFINE_NFSD_IO_EVENT(read_start); diff --git a/patches.suse/NFSD-restore-EINVAL-error-translation-in-nfsd_commit.patch b/patches.suse/NFSD-restore-EINVAL-error-translation-in-nfsd_commit.patch new file mode 100644 index 0000000..821a444 --- /dev/null +++ b/patches.suse/NFSD-restore-EINVAL-error-translation-in-nfsd_commit.patch @@ -0,0 +1,42 @@ +From: Alexey Khoroshilov +Date: Sat, 25 Jun 2022 23:52:43 +0300 +Subject: [PATCH] NFSD: restore EINVAL error translation in nfsd_commit() +Git-commit: 8a9ffb8c857c2c99403bd6483a5a005fed5c0773 +Patch-mainline: v5.19 +References: git-fixes + +commit 555dbf1a9aac ("nfsd: Replace use of rwsem with errseq_t") +incidentally broke translation of -EINVAL to nfserr_notsupp. +The patch restores that. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Signed-off-by: Alexey Khoroshilov +Fixes: 555dbf1a9aac ("nfsd: Replace use of rwsem with errseq_t") +Signed-off-by: Chuck Lever +Acked-by: NeilBrown + +--- + fs/nfsd/vfs.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/nfsd/vfs.c ++++ b/fs/nfsd/vfs.c +@@ -1174,6 +1174,7 @@ nfsd_commit(struct svc_rqst *rqstp, stru + nfsd_net_id)); + err2 = filemap_check_wb_err(nf->nf_file->f_mapping, + since); ++ err = nfserrno(err2); + break; + case -EINVAL: + err = nfserr_notsupp; +@@ -1181,8 +1182,8 @@ nfsd_commit(struct svc_rqst *rqstp, stru + default: + nfsd_reset_boot_verifier(net_generic(nf->nf_net, + nfsd_net_id)); ++ err = nfserrno(err2); + } +- err = nfserrno(err2); + } else + nfsd_copy_boot_verifier(verf, net_generic(nf->nf_net, + nfsd_net_id)); diff --git a/patches.suse/NFSv4-Fix-races-in-the-legacy-idmapper-upcall.patch b/patches.suse/NFSv4-Fix-races-in-the-legacy-idmapper-upcall.patch new file mode 100644 index 0000000..549b4b0 --- /dev/null +++ b/patches.suse/NFSv4-Fix-races-in-the-legacy-idmapper-upcall.patch @@ -0,0 +1,137 @@ +From: Trond Myklebust +Date: Wed, 13 Jul 2022 17:46:52 -0400 +Subject: [PATCH] NFSv4: Fix races in the legacy idmapper upcall +Git-commit: 51fd2eb52c0ca8275a906eed81878ef50ae94eb0 +Patch-mainline: v6.0 +References: git-fixes + +nfs_idmap_instantiate() will cause the process that is waiting in +request_key_with_auxdata() to wake up and exit. If there is a second +process waiting for the idmap->idmap_mutex, then it may wake up and +start a new call to request_key_with_auxdata(). If the call to +idmap_pipe_downcall() from the first process has not yet finished +calling nfs_idmap_complete_pipe_upcall_locked(), then we may end up +triggering the WARN_ON_ONCE() in nfs_idmap_prepare_pipe_upcall(). + +The fix is to ensure that we clear idmap->idmap_upcall_data before +calling nfs_idmap_instantiate(). + +Fixes: e9ab41b620e4 ("NFSv4: Clean up the legacy idmapper upcall") +Signed-off-by: Trond Myklebust +Acked-by: NeilBrown + +--- + fs/nfs/nfs4idmap.c | 46 ++++++++++++++++++++++++---------------------- + 1 file changed, 24 insertions(+), 22 deletions(-) + +--- a/fs/nfs/nfs4idmap.c ++++ b/fs/nfs/nfs4idmap.c +@@ -561,22 +561,20 @@ nfs_idmap_prepare_pipe_upcall(struct idm + return true; + } + +-static void +-nfs_idmap_complete_pipe_upcall_locked(struct idmap *idmap, int ret) ++static void nfs_idmap_complete_pipe_upcall(struct idmap_legacy_upcalldata *data, ++ int ret) + { +- struct key *authkey = idmap->idmap_upcall_data->authkey; +- +- kfree(idmap->idmap_upcall_data); +- idmap->idmap_upcall_data = NULL; +- complete_request_key(authkey, ret); +- key_put(authkey); ++ complete_request_key(data->authkey, ret); ++ key_put(data->authkey); ++ kfree(data); + } + +-static void +-nfs_idmap_abort_pipe_upcall(struct idmap *idmap, int ret) ++static void nfs_idmap_abort_pipe_upcall(struct idmap *idmap, ++ struct idmap_legacy_upcalldata *data, ++ int ret) + { +- if (idmap->idmap_upcall_data != NULL) +- nfs_idmap_complete_pipe_upcall_locked(idmap, ret); ++ if (cmpxchg(&idmap->idmap_upcall_data, data, NULL) == data) ++ nfs_idmap_complete_pipe_upcall(data, ret); + } + + static int nfs_idmap_legacy_upcall(struct key *authkey, void *aux) +@@ -613,7 +611,7 @@ static int nfs_idmap_legacy_upcall(struc + + ret = rpc_queue_upcall(idmap->idmap_pipe, msg); + if (ret < 0) +- nfs_idmap_abort_pipe_upcall(idmap, ret); ++ nfs_idmap_abort_pipe_upcall(idmap, data, ret); + + return ret; + out2: +@@ -669,6 +667,7 @@ idmap_pipe_downcall(struct file *filp, c + struct request_key_auth *rka; + struct rpc_inode *rpci = RPC_I(file_inode(filp)); + struct idmap *idmap = (struct idmap *)rpci->private; ++ struct idmap_legacy_upcalldata *data; + struct key *authkey; + struct idmap_msg im; + size_t namelen_in; +@@ -678,10 +677,11 @@ idmap_pipe_downcall(struct file *filp, c + * will have been woken up and someone else may now have used + * idmap_key_cons - so after this point we may no longer touch it. + */ +- if (idmap->idmap_upcall_data == NULL) ++ data = xchg(&idmap->idmap_upcall_data, NULL); ++ if (data == NULL) + goto out_noupcall; + +- authkey = idmap->idmap_upcall_data->authkey; ++ authkey = data->authkey; + rka = get_request_key_auth(authkey); + + if (mlen != sizeof(im)) { +@@ -703,18 +703,17 @@ idmap_pipe_downcall(struct file *filp, c + if (namelen_in == 0 || namelen_in == IDMAP_NAMESZ) { + ret = -EINVAL; + goto out; +-} ++ } + +- ret = nfs_idmap_read_and_verify_message(&im, +- &idmap->idmap_upcall_data->idmap_msg, +- rka->target_key, authkey); ++ ret = nfs_idmap_read_and_verify_message(&im, &data->idmap_msg, ++ rka->target_key, authkey); + if (ret >= 0) { + key_set_timeout(rka->target_key, nfs_idmap_cache_timeout); + ret = mlen; + } + + out: +- nfs_idmap_complete_pipe_upcall_locked(idmap, ret); ++ nfs_idmap_complete_pipe_upcall(data, ret); + out_noupcall: + return ret; + } +@@ -728,7 +727,7 @@ idmap_pipe_destroy_msg(struct rpc_pipe_m + struct idmap *idmap = data->idmap; + + if (msg->errno) +- nfs_idmap_abort_pipe_upcall(idmap, msg->errno); ++ nfs_idmap_abort_pipe_upcall(idmap, data, msg->errno); + } + + static void +@@ -736,8 +735,11 @@ idmap_release_pipe(struct inode *inode) + { + struct rpc_inode *rpci = RPC_I(inode); + struct idmap *idmap = (struct idmap *)rpci->private; ++ struct idmap_legacy_upcalldata *data; + +- nfs_idmap_abort_pipe_upcall(idmap, -EPIPE); ++ data = xchg(&idmap->idmap_upcall_data, NULL); ++ if (data) ++ nfs_idmap_complete_pipe_upcall(data, -EPIPE); + } + + int nfs_map_name_to_uid(const struct nfs_server *server, const char *name, size_t namelen, kuid_t *uid) diff --git a/patches.suse/NFSv4-Fixes-for-nfs4_inode_return_delegation.patch b/patches.suse/NFSv4-Fixes-for-nfs4_inode_return_delegation.patch new file mode 100644 index 0000000..ed24b3c --- /dev/null +++ b/patches.suse/NFSv4-Fixes-for-nfs4_inode_return_delegation.patch @@ -0,0 +1,38 @@ +From: Trond Myklebust +Date: Sun, 10 Oct 2021 10:58:12 +0200 +Subject: [PATCH] NFSv4: Fixes for nfs4_inode_return_delegation() +Git-commit: 6e176d47160cec8bcaa28d9aa06926d72d54237c +Patch-mainline: v5.16 +References: git-fixes + +We mustn't call nfs_wb_all() on anything other than a regular file. +Furthermore, we can exit early when we don't hold a delegation. + +Reported-by: David Wysochanski +Signed-off-by: Trond Myklebust +Acked-by: NeilBrown + +--- + fs/nfs/delegation.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/fs/nfs/delegation.c ++++ b/fs/nfs/delegation.c +@@ -755,11 +755,13 @@ int nfs4_inode_return_delegation(struct + struct nfs_delegation *delegation; + + delegation = nfs_start_delegation_return(nfsi); +- /* Synchronous recall of any application leases */ +- break_lease(inode, O_WRONLY | O_RDWR); +- nfs_wb_all(inode); +- if (delegation != NULL) ++ if (delegation != NULL) { ++ /* Synchronous recall of any application leases */ ++ break_lease(inode, O_WRONLY | O_RDWR); ++ if (S_ISREG(inode->i_mode)) ++ nfs_wb_all(inode); + return nfs_end_delegation_return(inode, delegation, 1); ++ } + return 0; + } + diff --git a/patches.suse/NFSv4-Turn-off-open-by-filehandle-and-NFS-re-export-.patch b/patches.suse/NFSv4-Turn-off-open-by-filehandle-and-NFS-re-export-.patch new file mode 100644 index 0000000..d9f3862 --- /dev/null +++ b/patches.suse/NFSv4-Turn-off-open-by-filehandle-and-NFS-re-export-.patch @@ -0,0 +1,64 @@ +From: Trond Myklebust +Date: Thu, 25 Aug 2022 14:49:05 -0400 +Subject: [PATCH] NFSv4: Turn off open-by-filehandle and NFS re-export for + NFSv4.0 +Git-commit: 2a9d683b48c8a87e61a4215792d44c90bcbbb536 +Patch-mainline: v6.0 +References: git-fixes + +The NFSv4.0 protocol only supports open() by name. It cannot therefore +be used with open_by_handle() and friends, nor can it be re-exported by +knfsd. + +Reported-by: Chuck Lever III +Fixes: 20fa19027286 ("nfs: add export operations") +Signed-off-by: Trond Myklebust +Acked-by: NeilBrown + +--- + fs/nfs/super.c | 27 ++++++++++++++++++--------- + 1 file changed, 18 insertions(+), 9 deletions(-) + +--- a/fs/nfs/super.c ++++ b/fs/nfs/super.c +@@ -1044,22 +1044,31 @@ static void nfs_fill_super(struct super_ + if (ctx->bsize) + sb->s_blocksize = nfs_block_size(ctx->bsize, &sb->s_blocksize_bits); + +- if (server->nfs_client->rpc_ops->version != 2) { +- /* The VFS shouldn't apply the umask to mode bits. We will do +- * so ourselves when necessary. ++ switch (server->nfs_client->rpc_ops->version) { ++ case 2: ++ sb->s_time_gran = 1000; ++ sb->s_time_min = 0; ++ sb->s_time_max = U32_MAX; ++ break; ++ case 3: ++ /* ++ * The VFS shouldn't apply the umask to mode bits. ++ * We will do so ourselves when necessary. + */ + sb->s_flags |= SB_POSIXACL; + sb->s_time_gran = 1; +- sb->s_export_op = &nfs_export_ops; +- } else +- sb->s_time_gran = 1000; +- +- if (server->nfs_client->rpc_ops->version != 4) { + sb->s_time_min = 0; + sb->s_time_max = U32_MAX; +- } else { ++ sb->s_export_op = &nfs_export_ops; ++ break; ++ case 4: ++ sb->s_flags |= SB_POSIXACL; ++ sb->s_time_gran = 1; + sb->s_time_min = S64_MIN; + sb->s_time_max = S64_MAX; ++ if (server->caps & NFS_CAP_ATOMIC_OPEN_V1) ++ sb->s_export_op = &nfs_export_ops; ++ break; + } + + sb->s_magic = NFS_SUPER_MAGIC; diff --git a/patches.suse/NFSv4.1-Don-t-decrease-the-value-of-seq_nr_highest_s.patch b/patches.suse/NFSv4.1-Don-t-decrease-the-value-of-seq_nr_highest_s.patch new file mode 100644 index 0000000..4de6f0b --- /dev/null +++ b/patches.suse/NFSv4.1-Don-t-decrease-the-value-of-seq_nr_highest_s.patch @@ -0,0 +1,35 @@ +From: Trond Myklebust +Date: Tue, 12 Jul 2022 09:16:04 -0400 +Subject: [PATCH] NFSv4.1: Don't decrease the value of seq_nr_highest_sent +Git-commit: f07a5d2427fc113dc50c5c818eba8929bc27b8ca +Patch-mainline: v6.0 +References: git-fixes + +When we're trying to figure out what the server may or may not have seen +in terms of request numbers, do not assume that requests with a larger +number were missed, just because we saw a reply to a request with a +smaller number. + +Fixes: 3453d5708b33 ("NFSv4.1: Avoid false retries when RPC calls are interrupted") +Signed-off-by: Trond Myklebust +Acked-by: NeilBrown + +--- + fs/nfs/nfs4proc.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -787,10 +787,9 @@ static void nfs4_slot_sequence_record_se + if ((s32)(seqnr - slot->seq_nr_highest_sent) > 0) + slot->seq_nr_highest_sent = seqnr; + } +-static void nfs4_slot_sequence_acked(struct nfs4_slot *slot, +- u32 seqnr) ++static void nfs4_slot_sequence_acked(struct nfs4_slot *slot, u32 seqnr) + { +- slot->seq_nr_highest_sent = seqnr; ++ nfs4_slot_sequence_record_sent(slot, seqnr); + slot->seq_nr_last_acked = seqnr; + } + diff --git a/patches.suse/NFSv4.1-Handle-NFS4ERR_DELAY-replies-to-OP_SEQUENCE-.patch b/patches.suse/NFSv4.1-Handle-NFS4ERR_DELAY-replies-to-OP_SEQUENCE-.patch new file mode 100644 index 0000000..29ab11f --- /dev/null +++ b/patches.suse/NFSv4.1-Handle-NFS4ERR_DELAY-replies-to-OP_SEQUENCE-.patch @@ -0,0 +1,29 @@ +From: Trond Myklebust +Date: Tue, 12 Jul 2022 09:22:40 -0400 +Subject: [PATCH] NFSv4.1: Handle NFS4ERR_DELAY replies to OP_SEQUENCE + correctly +Git-commit: 7ccafd4b2b9f34e6d8185f796f151c47424e273e +Patch-mainline: v6.0 +References: git-fixes + +Don't assume that the NFS4ERR_DELAY means that the server is processing +this slot id. + +Fixes: 3453d5708b33 ("NFSv4.1: Avoid false retries when RPC calls are interrupted") +Signed-off-by: Trond Myklebust +Acked-by: NeilBrown + +--- + fs/nfs/nfs4proc.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -856,7 +856,6 @@ static int nfs41_sequence_process(struct + __func__, + slot->slot_nr, + slot->seq_nr); +- nfs4_slot_sequence_acked(slot, slot->seq_nr); + goto out_retry; + case -NFS4ERR_RETRY_UNCACHED_REP: + case -NFS4ERR_SEQ_FALSE_RETRY: diff --git a/patches.suse/NFSv4.1-RECLAIM_COMPLETE-must-handle-EACCES.patch b/patches.suse/NFSv4.1-RECLAIM_COMPLETE-must-handle-EACCES.patch new file mode 100644 index 0000000..b366d7a --- /dev/null +++ b/patches.suse/NFSv4.1-RECLAIM_COMPLETE-must-handle-EACCES.patch @@ -0,0 +1,37 @@ +From: Zhang Xianwei +Date: Wed, 27 Jul 2022 18:01:07 +0800 +Subject: [PATCH] NFSv4.1: RECLAIM_COMPLETE must handle EACCES +Git-commit: e35a5e782f67ed76a65ad0f23a484444a95f000f +Patch-mainline: v6.0 +References: git-fixes + +A client should be able to handle getting an EACCES error while doing +a mount operation to reclaim state due to NFS4CLNT_RECLAIM_REBOOT +being set. If the server returns RPC_AUTH_BADCRED because authentication +failed when we execute "exportfs -au", then RECLAIM_COMPLETE will go a +wrong way. After mount succeeds, all OPEN call will fail due to an +NFS4ERR_GRACE error being returned. This patch is to fix it by resending +a RPC request. + +Signed-off-by: Zhang Xianwei +Signed-off-by: Yi Wang +Fixes: aa5190d0ed7d ("NFSv4: Kill nfs4_async_handle_error() abuses by NFSv4.1") +Signed-off-by: Trond Myklebust +Acked-by: NeilBrown + +--- + fs/nfs/nfs4proc.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -9350,6 +9350,9 @@ static int nfs41_reclaim_complete_handle + rpc_delay(task, NFS4_POLL_RETRY_MAX); + fallthrough; + case -NFS4ERR_RETRY_UNCACHED_REP: ++ case -EACCES: ++ dprintk("%s: failed to reclaim complete error %d for server %s, retrying\n", ++ __func__, task->tk_status, clp->cl_hostname); + return -EAGAIN; + case -NFS4ERR_BADSESSION: + case -NFS4ERR_DEADSESSION: diff --git a/patches.suse/NFSv4.2-Update-mode-bits-after-ALLOCATE-and-DEALLOCA.patch b/patches.suse/NFSv4.2-Update-mode-bits-after-ALLOCATE-and-DEALLOCA.patch new file mode 100644 index 0000000..f8a7164 --- /dev/null +++ b/patches.suse/NFSv4.2-Update-mode-bits-after-ALLOCATE-and-DEALLOCA.patch @@ -0,0 +1,113 @@ +From: Anna Schumaker +Date: Wed, 7 Sep 2022 16:34:21 -0400 +Subject: [PATCH] NFSv4.2: Update mode bits after ALLOCATE and DEALLOCATE +Git-commit: d7a5118635e725d195843bda80cc5c964d93ef31 +Patch-mainline: v6.0 +References: git-fixes + +The fallocate call invalidates suid and sgid bits as part of normal +operation. We need to mark the mode bits as invalid when using fallocate +with an suid so these will be updated the next time the user looks at them. + +This fixes xfstests generic/683 and generic/684. + +Reported-by: Yue Cui +Fixes: 913eca1aea87 ("NFS: Fallocate should use the nfs4_fattr_bitmap") +Signed-off-by: Anna Schumaker +Signed-off-by: Trond Myklebust +Acked-by: NeilBrown + +--- + fs/nfs/internal.h | 25 +++++++++++++++++++++++++ + fs/nfs/nfs42proc.c | 9 +++++++-- + fs/nfs/write.c | 25 ------------------------- + 3 files changed, 32 insertions(+), 27 deletions(-) + +--- a/fs/nfs/internal.h ++++ b/fs/nfs/internal.h +@@ -588,6 +588,31 @@ nfs_write_match_verf(const struct nfs_wr + !nfs_write_verifier_cmp(&req->wb_verf, &verf->verifier); + } + ++/* ++ * Special version of should_remove_suid() that ignores capabilities. ++ */ ++static inline int nfs_should_remove_suid(const struct inode *inode) ++{ ++ umode_t mode = inode->i_mode; ++ int kill = 0; ++ ++ /* suid always must be killed */ ++ if (unlikely(mode & S_ISUID)) ++ kill = ATTR_KILL_SUID; ++ ++ /* ++ * sgid without any exec bits is just a mandatory locking mark; leave ++ * it alone. If some exec bits are set, it's a real sgid; kill it. ++ */ ++ if (unlikely((mode & S_ISGID) && (mode & S_IXGRP))) ++ kill |= ATTR_KILL_SGID; ++ ++ if (unlikely(kill && S_ISREG(mode))) ++ return kill; ++ ++ return 0; ++} ++ + /* unlink.c */ + extern struct rpc_task * + nfs_async_rename(struct inode *old_dir, struct inode *new_dir, +--- a/fs/nfs/nfs42proc.c ++++ b/fs/nfs/nfs42proc.c +@@ -79,10 +79,15 @@ static int _nfs42_proc_fallocate(struct + + status = nfs4_call_sync(server->client, server, msg, + &args.seq_args, &res.seq_res, 0); +- if (status == 0) ++ if (status == 0) { ++ if (nfs_should_remove_suid(inode)) { ++ spin_lock(&inode->i_lock); ++ nfs_set_cache_invalid(inode, NFS_INO_INVALID_MODE); ++ spin_unlock(&inode->i_lock); ++ } + status = nfs_post_op_update_inode_force_wcc(inode, + res.falloc_fattr); +- ++ } + kfree(res.falloc_fattr); + return status; + } +--- a/fs/nfs/write.c ++++ b/fs/nfs/write.c +@@ -1476,31 +1476,6 @@ void nfs_commit_prepare(struct rpc_task + NFS_PROTO(data->inode)->commit_rpc_prepare(task, data); + } + +-/* +- * Special version of should_remove_suid() that ignores capabilities. +- */ +-static int nfs_should_remove_suid(const struct inode *inode) +-{ +- umode_t mode = inode->i_mode; +- int kill = 0; +- +- /* suid always must be killed */ +- if (unlikely(mode & S_ISUID)) +- kill = ATTR_KILL_SUID; +- +- /* +- * sgid without any exec bits is just a mandatory locking mark; leave +- * it alone. If some exec bits are set, it's a real sgid; kill it. +- */ +- if (unlikely((mode & S_ISGID) && (mode & S_IXGRP))) +- kill |= ATTR_KILL_SGID; +- +- if (unlikely(kill && S_ISREG(mode))) +- return kill; +- +- return 0; +-} +- + static void nfs_writeback_check_extend(struct nfs_pgio_header *hdr, + struct nfs_fattr *fattr) + { diff --git a/patches.suse/NFSv4.2-fix-problems-with-__nfs42_ssc_open.patch b/patches.suse/NFSv4.2-fix-problems-with-__nfs42_ssc_open.patch new file mode 100644 index 0000000..24ad4b9 --- /dev/null +++ b/patches.suse/NFSv4.2-fix-problems-with-__nfs42_ssc_open.patch @@ -0,0 +1,45 @@ +From: Olga Kornievskaia +Date: Thu, 18 Aug 2022 15:07:05 -0400 +Subject: [PATCH] NFSv4.2 fix problems with __nfs42_ssc_open +Git-commit: fcfc8be1e9cf2f12b50dce8b579b3ae54443a014 +Patch-mainline: v6.0 +References: git-fixes + +A destination server while doing a COPY shouldn't accept using the +passed in filehandle if its not a regular filehandle. + +If alloc_file_pseudo() has failed, we need to decrement a reference +on the newly created inode, otherwise it leaks. + +Reported-by: Al Viro +Fixes: ec4b092508982 ("NFS: inter ssc open") +Signed-off-by: Olga Kornievskaia +Signed-off-by: Trond Myklebust +Acked-by: NeilBrown + +--- + fs/nfs/nfs4file.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/fs/nfs/nfs4file.c ++++ b/fs/nfs/nfs4file.c +@@ -340,6 +340,11 @@ static struct file *__nfs42_ssc_open(str + goto out; + } + ++ if (!S_ISREG(fattr.mode)) { ++ res = ERR_PTR(-EBADF); ++ goto out; ++ } ++ + res = ERR_PTR(-ENOMEM); + len = strlen(SSC_READ_NAME_BODY) + 16; + read_name = kzalloc(len, GFP_NOFS); +@@ -358,6 +363,7 @@ static struct file *__nfs42_ssc_open(str + r_ino->i_fop); + if (IS_ERR(filep)) { + res = ERR_CAST(filep); ++ iput(r_ino); + goto out_free_name; + } + filep->f_mode |= FMODE_READ; diff --git a/patches.suse/PCI-ACPI-PM-Power-up-devices-in-D3cold-before-scanni.patch b/patches.suse/PCI-ACPI-PM-Power-up-devices-in-D3cold-before-scanni.patch new file mode 100644 index 0000000..f31cc5b --- /dev/null +++ b/patches.suse/PCI-ACPI-PM-Power-up-devices-in-D3cold-before-scanni.patch @@ -0,0 +1,57 @@ +From: "Rafael J. Wysocki" +Date: Mon, 4 Apr 2022 17:25:04 +0200 +Subject: PCI: ACPI: PM: Power up devices in D3cold before scanning them +Patch-mainline: v5.19-rc1 +Git-commit: 62d528712c1db609fd5afc319378ca053ac9247e +References: jsc#PED-1408 + +The initial configuration of ACPI power resources on some systems +implies that some PCI devices on them are initially in D3cold. + +In some cases, especially for PCIe Root Ports, this is a "logical" +D3cold, meaning that the configuration space of the device is +accessible, but some of its functionality may be missing, but it +very well may be real D3cold, in which case the device will not +be accessible at all. However, the PCI bus type driver will need +to access its configuration space in order to enumerate it. + +To prevent possible device enumeration failures that may ensue as +a result of ACPI power resources being initially in the "off" +state, power up all children of the host bridge ACPI device object +that hold valid _ADR objects (which indicates that they will be +enumerated by the PCI bus type driver) and do that to all children +of the ACPI device objects corresponding to PCI bridges (including +PCIe ports). + +Signed-off-by: Rafael J. Wysocki +Acked-by: Bjorn Helgaas +Reviewed-by: Mika Westerberg +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/pci_root.c | 2 ++ + drivers/pci/pci-acpi.c | 3 +++ + 2 files changed, 5 insertions(+) + +--- a/drivers/acpi/pci_root.c ++++ b/drivers/acpi/pci_root.c +@@ -927,6 +927,8 @@ struct pci_bus *acpi_pci_root_create(str + host_bridge->preserve_config = 1; + ACPI_FREE(obj); + ++ acpi_dev_power_up_children_with_adr(device); ++ + pci_scan_child_bus(bus); + pci_set_host_bridge_release(host_bridge, acpi_pci_root_release_info, + info); +--- a/drivers/pci/pci-acpi.c ++++ b/drivers/pci/pci-acpi.c +@@ -1376,6 +1376,9 @@ void pci_acpi_setup(struct device *dev, + + acpi_pci_wakeup(pci_dev, false); + acpi_device_power_add_dependent(adev, dev); ++ ++ if (pci_is_bridge(pci_dev)) ++ acpi_dev_power_up_children_with_adr(adev); + } + + void pci_acpi_cleanup(struct device *dev, struct acpi_device *adev) diff --git a/patches.suse/PCI-ACPI-Prefer-CXL-_OSC-instead-of-PCIe-_OSC-for-CX.patch b/patches.suse/PCI-ACPI-Prefer-CXL-_OSC-instead-of-PCIe-_OSC-for-CX.patch new file mode 100644 index 0000000..5c182cb --- /dev/null +++ b/patches.suse/PCI-ACPI-Prefer-CXL-_OSC-instead-of-PCIe-_OSC-for-CX.patch @@ -0,0 +1,215 @@ +From: Dan Williams +Date: Wed, 13 Apr 2022 01:36:17 -0600 +Subject: PCI/ACPI: Prefer CXL _OSC instead of PCIe _OSC for CXL host bridges +Patch-mainline: v5.19-rc1 +Git-commit: 241d26bc26add2e2867c546f7474902406d37c60 +References: jsc#PED-1408 + +OB In preparation for negotiating OS control of CXL _OSC features, do the +minimal enabling to use CXL _OSC to handle the base PCIe feature +negotiation. Recall that CXL _OSC is a super-set of PCIe _OSC and the +CXL 2.0 specification mandates: "If a CXL Host Bridge device exposes CXL +_OSC, CXL aware OSPM shall evaluate CXL _OSC and not evaluate PCIe +_OSC." + +Rather than pass a boolean flag alongside @root to all the helper +functions that need to consider PCIe specifics, add is_pcie() and +is_cxl() helper functions to check the flavor of @root. This also +allows for dynamic fallback to PCIe _OSC in cases where an attempt to +use CXL _OXC fails. This can happen on CXL 1.1 platforms that publish +ACPI0016 devices to indicate CXL host bridges, but do not publish the +optional CXL _OSC method. CXL _OSC is mandatory for CXL 2.0 hosts. + +Cc: Bjorn Helgaas +Cc: "Rafael J. Wysocki" +Cc: Robert Moore +Reviewed-by: Jonathan Cameron +Reviewed-by: Rafael J. Wysocki +Reviewed-by: Davidlohr Bueso +Signed-off-by: Vishal Verma +Link: https://lore.kernel.org/r/20220413073618.291335-3-vishal.l.verma@intel.com +Signed-off-by: Dan Williams +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/pci_root.c | 67 +++++++++++++++++++++++++++++++++++++----------- + include/acpi/acpi_bus.h | 6 ++++ + include/linux/acpi.h | 4 ++ + 3 files changed, 63 insertions(+), 14 deletions(-) + +--- a/drivers/acpi/pci_root.c ++++ b/drivers/acpi/pci_root.c +@@ -168,20 +168,45 @@ static void decode_osc_control(struct ac + ARRAY_SIZE(pci_osc_control_bit)); + } + ++static inline bool is_pcie(struct acpi_pci_root *root) ++{ ++ return root->bridge_type == ACPI_BRIDGE_TYPE_PCIE; ++} ++ ++static inline bool is_cxl(struct acpi_pci_root *root) ++{ ++ return root->bridge_type == ACPI_BRIDGE_TYPE_CXL; ++} ++ + static u8 pci_osc_uuid_str[] = "33DB4D5B-1FF7-401C-9657-7441C03DD766"; ++static u8 cxl_osc_uuid_str[] = "68F2D50B-C469-4d8A-BD3D-941A103FD3FC"; + +-static acpi_status acpi_pci_run_osc(acpi_handle handle, ++static char *to_uuid(struct acpi_pci_root *root) ++{ ++ if (is_cxl(root)) ++ return cxl_osc_uuid_str; ++ return pci_osc_uuid_str; ++} ++ ++static int cap_length(struct acpi_pci_root *root) ++{ ++ if (is_cxl(root)) ++ return sizeof(u32) * OSC_CXL_CAPABILITY_DWORDS; ++ return sizeof(u32) * OSC_PCI_CAPABILITY_DWORDS; ++} ++ ++static acpi_status acpi_pci_run_osc(struct acpi_pci_root *root, + const u32 *capbuf, u32 *retval) + { + struct acpi_osc_context context = { +- .uuid_str = pci_osc_uuid_str, ++ .uuid_str = to_uuid(root), + .rev = 1, +- .cap.length = 12, ++ .cap.length = cap_length(root), + .cap.pointer = (void *)capbuf, + }; + acpi_status status; + +- status = acpi_run_osc(handle, &context); ++ status = acpi_run_osc(root->device->handle, &context); + if (ACPI_SUCCESS(status)) { + *retval = acpi_osc_ctx_get_pci_control(&context); + kfree(context.ret.pointer); +@@ -194,7 +219,7 @@ static acpi_status acpi_pci_query_osc(st + u32 *control) + { + acpi_status status; +- u32 result, capbuf[3]; ++ u32 result, capbuf[OSC_CXL_CAPABILITY_DWORDS]; + + support |= root->osc_support_set; + +@@ -202,10 +227,18 @@ static acpi_status acpi_pci_query_osc(st + capbuf[OSC_SUPPORT_DWORD] = support; + capbuf[OSC_CONTROL_DWORD] = *control | root->osc_control_set; + +- status = acpi_pci_run_osc(root->device->handle, capbuf, &result); ++retry: ++ status = acpi_pci_run_osc(root, capbuf, &result); + if (ACPI_SUCCESS(status)) { + root->osc_support_set = support; + *control = result; ++ } else if (is_cxl(root)) { ++ /* ++ * CXL _OSC is optional on CXL 1.1 hosts. Fall back to PCIe _OSC ++ * upon any failure using CXL _OSC. ++ */ ++ root->bridge_type = ACPI_BRIDGE_TYPE_PCIE; ++ goto retry; + } + return status; + } +@@ -336,7 +369,7 @@ static acpi_status acpi_pci_osc_control_ + u32 req = OSC_PCI_EXPRESS_CAPABILITY_CONTROL; + struct acpi_pci_root *root; + acpi_status status; +- u32 ctrl, capbuf[3]; ++ u32 ctrl, capbuf[OSC_CXL_CAPABILITY_DWORDS]; + + if (!mask) + return AE_BAD_PARAMETER; +@@ -373,7 +406,7 @@ static acpi_status acpi_pci_osc_control_ + capbuf[OSC_QUERY_DWORD] = 0; + capbuf[OSC_SUPPORT_DWORD] = root->osc_support_set; + capbuf[OSC_CONTROL_DWORD] = ctrl; +- status = acpi_pci_run_osc(handle, capbuf, mask); ++ status = acpi_pci_run_osc(root, capbuf, mask); + if (ACPI_FAILURE(status)) + return status; + +@@ -452,8 +485,7 @@ static bool os_control_query_checks(stru + return true; + } + +-static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm, +- bool is_pcie) ++static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm) + { + u32 support, control = 0, requested = 0; + acpi_status status; +@@ -504,7 +536,7 @@ static void negotiate_os_control(struct + *no_aspm = 1; + + /* _OSC is optional for PCI host bridges */ +- if ((status == AE_NOT_FOUND) && !is_pcie) ++ if (status == AE_NOT_FOUND && !is_pcie(root)) + return; + + if (control) { +@@ -527,7 +559,7 @@ static int acpi_pci_root_add(struct acpi + acpi_handle handle = device->handle; + int no_aspm = 0; + bool hotadd = system_state == SYSTEM_RUNNING; +- bool is_pcie; ++ const char *acpi_hid; + + root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); + if (!root) +@@ -585,8 +617,15 @@ static int acpi_pci_root_add(struct acpi + + root->mcfg_addr = acpi_pci_root_get_mcfg_addr(handle); + +- is_pcie = strcmp(acpi_device_hid(device), "PNP0A08") == 0; +- negotiate_os_control(root, &no_aspm, is_pcie); ++ acpi_hid = acpi_device_hid(root->device); ++ if (strcmp(acpi_hid, "PNP0A08") == 0) ++ root->bridge_type = ACPI_BRIDGE_TYPE_PCIE; ++ else if (strcmp(acpi_hid, "ACPI0016") == 0) ++ root->bridge_type = ACPI_BRIDGE_TYPE_CXL; ++ else ++ dev_dbg(&device->dev, "Assuming non-PCIe host bridge\n"); ++ ++ negotiate_os_control(root, &no_aspm); + + /* + * TBD: Need PCI interface for enumeration/configuration of roots. +--- a/include/acpi/acpi_bus.h ++++ b/include/acpi/acpi_bus.h +@@ -586,10 +586,16 @@ int unregister_acpi_bus_type(struct acpi + int acpi_bind_one(struct device *dev, struct acpi_device *adev); + int acpi_unbind_one(struct device *dev); + ++enum acpi_bridge_type { ++ ACPI_BRIDGE_TYPE_PCIE = 1, ++ ACPI_BRIDGE_TYPE_CXL, ++}; ++ + struct acpi_pci_root { + struct acpi_device * device; + struct pci_bus *bus; + u16 segment; ++ int bridge_type; + struct resource secondary; /* downstream bus range */ + + u32 osc_support_set; /* _OSC state of support bits */ +--- a/include/linux/acpi.h ++++ b/include/linux/acpi.h +@@ -550,6 +550,10 @@ struct acpi_osc_context { + + acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context); + ++/* Number of _OSC capability DWORDS depends on bridge type */ ++#define OSC_PCI_CAPABILITY_DWORDS 3 ++#define OSC_CXL_CAPABILITY_DWORDS 5 ++ + /* Indexes into _OSC Capabilities Buffer (DWORDs 2 & 3 are device-specific) */ + #define OSC_QUERY_DWORD 0 /* DWORD 1 */ + #define OSC_SUPPORT_DWORD 1 /* DWORD 2 */ diff --git a/patches.suse/PCI-ACPI-add-a-helper-for-retrieving-_OSC-Control-DW.patch b/patches.suse/PCI-ACPI-add-a-helper-for-retrieving-_OSC-Control-DW.patch new file mode 100644 index 0000000..6a3e3fd --- /dev/null +++ b/patches.suse/PCI-ACPI-add-a-helper-for-retrieving-_OSC-Control-DW.patch @@ -0,0 +1,81 @@ +From: Vishal Verma +Date: Wed, 13 Apr 2022 01:36:16 -0600 +Subject: PCI/ACPI: add a helper for retrieving _OSC Control DWORDs +Patch-mainline: v5.19-rc1 +Git-commit: cc10eee95204579fcd66fd5965073fdcbf629676 +References: jsc#PED-1408 + +During _OSC negotiation, when the 'Control' DWORD is needed from the +result buffer after running _OSC, a couple of places performed manual +pointer arithmetic to offset into the right spot in the raw buffer. +Add a acpi_osc_ctx_get_pci_control() helper to use the #define'd +DWORD offsets to fetch the DWORDs needed from @acpi_osc_context, and +replace the above instances of the open-coded arithmetic. + +Cc: "Rafael J. Wysocki" +Suggested-by: Davidlohr Bueso +Acked-by: Rafael J. Wysocki +Reviewed-by: Rafael J. Wysocki +Reviewed-by: Davidlohr Bueso +Reviewed by: Adam Manzanares +Signed-off-by: Vishal Verma +Link: https://lore.kernel.org/r/20220413073618.291335-2-vishal.l.verma@intel.com +Signed-off-by: Dan Williams +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/bus.c | 2 +- + drivers/acpi/pci_root.c | 2 +- + include/linux/acpi.h | 13 +++++++++++++ + 3 files changed, 15 insertions(+), 2 deletions(-) + +--- a/drivers/acpi/bus.c ++++ b/drivers/acpi/bus.c +@@ -443,7 +443,7 @@ static void acpi_bus_osc_negotiate_usb_c + } + + osc_sb_native_usb4_control = +- control & ((u32 *)context.ret.pointer)[OSC_CONTROL_DWORD]; ++ control & acpi_osc_ctx_get_pci_control(&context); + + acpi_bus_decode_usb_osc("USB4 _OSC: OS supports", control); + acpi_bus_decode_usb_osc("USB4 _OSC: OS controls", +--- a/drivers/acpi/pci_root.c ++++ b/drivers/acpi/pci_root.c +@@ -183,7 +183,7 @@ static acpi_status acpi_pci_run_osc(acpi + + status = acpi_run_osc(handle, &context); + if (ACPI_SUCCESS(status)) { +- *retval = *((u32 *)(context.ret.pointer + 8)); ++ *retval = acpi_osc_ctx_get_pci_control(&context); + kfree(context.ret.pointer); + } + return status; +--- a/include/linux/acpi.h ++++ b/include/linux/acpi.h +@@ -610,6 +610,13 @@ extern u32 osc_sb_native_usb4_control; + #define OSC_PCI_EXPRESS_LTR_CONTROL 0x00000020 + #define OSC_PCI_EXPRESS_DPC_CONTROL 0x00000080 + ++static inline u32 acpi_osc_ctx_get_pci_control(struct acpi_osc_context *context) ++{ ++ u32 *ret = context->ret.pointer; ++ ++ return ret[OSC_CONTROL_DWORD]; ++} ++ + #define ACPI_GSB_ACCESS_ATTRIB_QUICK 0x00000002 + #define ACPI_GSB_ACCESS_ATTRIB_SEND_RCV 0x00000004 + #define ACPI_GSB_ACCESS_ATTRIB_BYTE 0x00000006 +@@ -1006,6 +1013,12 @@ static inline int acpi_register_wakeup_h + static inline void acpi_unregister_wakeup_handler( + bool (*wakeup)(void *context), void *context) { } + ++struct acpi_osc_context; ++static inline u32 acpi_osc_ctx_get_pci_control(struct acpi_osc_context *context) ++{ ++ return 0; ++} ++ + #endif /* !CONFIG_ACPI */ + + #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC diff --git a/patches.suse/PCI-ACPI-negotiate-CXL-_OSC.patch b/patches.suse/PCI-ACPI-negotiate-CXL-_OSC.patch new file mode 100644 index 0000000..8d00841 --- /dev/null +++ b/patches.suse/PCI-ACPI-negotiate-CXL-_OSC.patch @@ -0,0 +1,423 @@ +From: Vishal Verma +Date: Wed, 13 Apr 2022 01:36:18 -0600 +Subject: PCI/ACPI: negotiate CXL _OSC +Patch-mainline: v5.19-rc1 +Git-commit: 56368029d93bbb3246ee2e03268fa6dd9754be05 +References: jsc#PED-1408 + +Add full support for negotiating _OSC as defined in the CXL 2.0 spec, as +applicable to CXL-enabled platforms. Advertise support for the CXL +features we support - 'CXL 2.0 port/device register access', 'Protocol +Error Reporting', and 'CXL Native Hot Plug'. Request control for 'CXL +Memory Error Reporting'. The requests are dependent on CONFIG_* based +prerequisites, and prior PCI enabling, similar to how the standard PCI +_OSC bits are determined. + +The CXL specification does not define any additional constraints on +the hotplug flow beyond PCIe native hotplug, so a kernel that supports +native PCIe hotplug, supports CXL hotplug. For error handling protocol +and link errors just use PCIe AER. There is nascent support for +amending AER events with CXL specific status [1], but there's +otherwise no additional OS responsibility for CXL errors beyond PCIe +AER. CXL Memory Errors behave the same as typical memory errors so +CONFIG_MEMORY_FAILURE is sufficient to indicate support to platform +firmware. + +[1]: https://lore.kernel.org/linux-cxl/164740402242.3912056.8303625392871313860.stgit@dwillia2-desk3.amr.corp.intel.com/ + +Cc: Bjorn Helgaas +Cc: "Rafael J. Wysocki" +Cc: Robert Moore +Cc: Dan Williams +Reviewed-by: Rafael J. Wysocki +Reviewed-by: Davidlohr Bueso +Signed-off-by: Vishal Verma +Link: https://lore.kernel.org/r/20220413073618.291335-4-vishal.l.verma@intel.com +Signed-off-by: Dan Williams +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/pci_root.c | 179 ++++++++++++++++++++++++++++++++++++++++++------ + include/acpi/acpi_bus.h | 6 + + include/linux/acpi.h | 25 ++++++ + 3 files changed, 188 insertions(+), 22 deletions(-) + +--- a/drivers/acpi/pci_root.c ++++ b/drivers/acpi/pci_root.c +@@ -140,6 +140,17 @@ static struct pci_osc_bit_struct pci_osc + { OSC_PCI_EXPRESS_DPC_CONTROL, "DPC" }, + }; + ++static struct pci_osc_bit_struct cxl_osc_support_bit[] = { ++ { OSC_CXL_1_1_PORT_REG_ACCESS_SUPPORT, "CXL11PortRegAccess" }, ++ { OSC_CXL_2_0_PORT_DEV_REG_ACCESS_SUPPORT, "CXL20PortDevRegAccess" }, ++ { OSC_CXL_PROTOCOL_ERR_REPORTING_SUPPORT, "CXLProtocolErrorReporting" }, ++ { OSC_CXL_NATIVE_HP_SUPPORT, "CXLNativeHotPlug" }, ++}; ++ ++static struct pci_osc_bit_struct cxl_osc_control_bit[] = { ++ { OSC_CXL_ERROR_REPORTING_CONTROL, "CXLMemErrorReporting" }, ++}; ++ + static void decode_osc_bits(struct acpi_pci_root *root, char *msg, u32 word, + struct pci_osc_bit_struct *table, int size) + { +@@ -168,6 +179,18 @@ static void decode_osc_control(struct ac + ARRAY_SIZE(pci_osc_control_bit)); + } + ++static void decode_cxl_osc_support(struct acpi_pci_root *root, char *msg, u32 word) ++{ ++ decode_osc_bits(root, msg, word, cxl_osc_support_bit, ++ ARRAY_SIZE(cxl_osc_support_bit)); ++} ++ ++static void decode_cxl_osc_control(struct acpi_pci_root *root, char *msg, u32 word) ++{ ++ decode_osc_bits(root, msg, word, cxl_osc_control_bit, ++ ARRAY_SIZE(cxl_osc_control_bit)); ++} ++ + static inline bool is_pcie(struct acpi_pci_root *root) + { + return root->bridge_type == ACPI_BRIDGE_TYPE_PCIE; +@@ -196,7 +219,8 @@ static int cap_length(struct acpi_pci_ro + } + + static acpi_status acpi_pci_run_osc(struct acpi_pci_root *root, +- const u32 *capbuf, u32 *retval) ++ const u32 *capbuf, u32 *pci_control, ++ u32 *cxl_control) + { + struct acpi_osc_context context = { + .uuid_str = to_uuid(root), +@@ -208,18 +232,20 @@ static acpi_status acpi_pci_run_osc(stru + + status = acpi_run_osc(root->device->handle, &context); + if (ACPI_SUCCESS(status)) { +- *retval = acpi_osc_ctx_get_pci_control(&context); ++ *pci_control = acpi_osc_ctx_get_pci_control(&context); ++ if (is_cxl(root)) ++ *cxl_control = acpi_osc_ctx_get_cxl_control(&context); + kfree(context.ret.pointer); + } + return status; + } + +-static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root, +- u32 support, +- u32 *control) ++static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root, u32 support, ++ u32 *control, u32 cxl_support, ++ u32 *cxl_control) + { + acpi_status status; +- u32 result, capbuf[OSC_CXL_CAPABILITY_DWORDS]; ++ u32 pci_result, cxl_result, capbuf[OSC_CXL_CAPABILITY_DWORDS]; + + support |= root->osc_support_set; + +@@ -227,11 +253,21 @@ static acpi_status acpi_pci_query_osc(st + capbuf[OSC_SUPPORT_DWORD] = support; + capbuf[OSC_CONTROL_DWORD] = *control | root->osc_control_set; + ++ if (is_cxl(root)) { ++ cxl_support |= root->osc_ext_support_set; ++ capbuf[OSC_EXT_SUPPORT_DWORD] = cxl_support; ++ capbuf[OSC_EXT_CONTROL_DWORD] = *cxl_control | root->osc_ext_control_set; ++ } ++ + retry: +- status = acpi_pci_run_osc(root, capbuf, &result); ++ status = acpi_pci_run_osc(root, capbuf, &pci_result, &cxl_result); + if (ACPI_SUCCESS(status)) { + root->osc_support_set = support; +- *control = result; ++ *control = pci_result; ++ if (is_cxl(root)) { ++ root->osc_ext_support_set = cxl_support; ++ *cxl_control = cxl_result; ++ } + } else if (is_cxl(root)) { + /* + * CXL _OSC is optional on CXL 1.1 hosts. Fall back to PCIe _OSC +@@ -354,6 +390,8 @@ EXPORT_SYMBOL_GPL(acpi_get_pci_dev); + * @handle: ACPI handle of a PCI root bridge (or PCIe Root Complex). + * @mask: Mask of _OSC bits to request control of, place to store control mask. + * @support: _OSC supported capability. ++ * @cxl_mask: Mask of CXL _OSC control bits, place to store control mask. ++ * @cxl_support: CXL _OSC supported capability. + * + * Run _OSC query for @mask and if that is successful, compare the returned + * mask of control bits with @req. If all of the @req bits are set in the +@@ -364,12 +402,14 @@ EXPORT_SYMBOL_GPL(acpi_get_pci_dev); + * _OSC bits the BIOS has granted control of, but its contents are meaningless + * on failure. + **/ +-static acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 support) ++static acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, ++ u32 support, u32 *cxl_mask, ++ u32 cxl_support) + { + u32 req = OSC_PCI_EXPRESS_CAPABILITY_CONTROL; + struct acpi_pci_root *root; + acpi_status status; +- u32 ctrl, capbuf[OSC_CXL_CAPABILITY_DWORDS]; ++ u32 ctrl, cxl_ctrl = 0, capbuf[OSC_CXL_CAPABILITY_DWORDS]; + + if (!mask) + return AE_BAD_PARAMETER; +@@ -381,20 +421,42 @@ static acpi_status acpi_pci_osc_control_ + ctrl = *mask; + *mask |= root->osc_control_set; + ++ if (is_cxl(root)) { ++ cxl_ctrl = *cxl_mask; ++ *cxl_mask |= root->osc_ext_control_set; ++ } ++ + /* Need to check the available controls bits before requesting them. */ + do { +- status = acpi_pci_query_osc(root, support, mask); ++ u32 pci_missing = 0, cxl_missing = 0; ++ ++ status = acpi_pci_query_osc(root, support, mask, cxl_support, ++ cxl_mask); + if (ACPI_FAILURE(status)) + return status; +- if (ctrl == *mask) +- break; +- decode_osc_control(root, "platform does not support", +- ctrl & ~(*mask)); ++ if (is_cxl(root)) { ++ if (ctrl == *mask && cxl_ctrl == *cxl_mask) ++ break; ++ pci_missing = ctrl & ~(*mask); ++ cxl_missing = cxl_ctrl & ~(*cxl_mask); ++ } else { ++ if (ctrl == *mask) ++ break; ++ pci_missing = ctrl & ~(*mask); ++ } ++ if (pci_missing) ++ decode_osc_control(root, "platform does not support", ++ pci_missing); ++ if (cxl_missing) ++ decode_cxl_osc_control(root, "CXL platform does not support", ++ cxl_missing); + ctrl = *mask; +- } while (*mask); ++ cxl_ctrl = *cxl_mask; ++ } while (*mask || *cxl_mask); + + /* No need to request _OSC if the control was already granted. */ +- if ((root->osc_control_set & ctrl) == ctrl) ++ if ((root->osc_control_set & ctrl) == ctrl && ++ (root->osc_ext_control_set & cxl_ctrl) == cxl_ctrl) + return AE_OK; + + if ((ctrl & req) != req) { +@@ -406,11 +468,17 @@ static acpi_status acpi_pci_osc_control_ + capbuf[OSC_QUERY_DWORD] = 0; + capbuf[OSC_SUPPORT_DWORD] = root->osc_support_set; + capbuf[OSC_CONTROL_DWORD] = ctrl; +- status = acpi_pci_run_osc(root, capbuf, mask); ++ if (is_cxl(root)) { ++ capbuf[OSC_EXT_SUPPORT_DWORD] = root->osc_ext_support_set; ++ capbuf[OSC_EXT_CONTROL_DWORD] = cxl_ctrl; ++ } ++ ++ status = acpi_pci_run_osc(root, capbuf, mask, cxl_mask); + if (ACPI_FAILURE(status)) + return status; + + root->osc_control_set = *mask; ++ root->osc_ext_control_set = *cxl_mask; + return AE_OK; + } + +@@ -436,6 +504,53 @@ static u32 calculate_support(void) + return support; + } + ++/* ++ * Background on hotplug support, and making it depend on only ++ * CONFIG_HOTPLUG_PCI_PCIE vs. also considering CONFIG_MEMORY_HOTPLUG: ++ * ++ * CONFIG_ACPI_HOTPLUG_MEMORY does depend on CONFIG_MEMORY_HOTPLUG, but ++ * there is no existing _OSC for memory hotplug support. The reason is that ++ * ACPI memory hotplug requires the OS to acknowledge / coordinate with ++ * memory plug events via a scan handler. On the CXL side the equivalent ++ * would be if Linux supported the Mechanical Retention Lock [1], or ++ * otherwise had some coordination for the driver of a PCI device ++ * undergoing hotplug to be consulted on whether the hotplug should ++ * proceed or not. ++ * ++ * The concern is that if Linux says no to supporting CXL hotplug then ++ * the BIOS may say no to giving the OS hotplug control of any other PCIe ++ * device. So the question here is not whether hotplug is enabled, it's ++ * whether it is handled natively by the at all OS, and if ++ * CONFIG_HOTPLUG_PCI_PCIE is enabled then the answer is "yes". ++ * ++ * Otherwise, the plan for CXL coordinated remove, since the kernel does ++ * not support blocking hotplug, is to require the memory device to be ++ * disabled before hotplug is attempted. When CONFIG_MEMORY_HOTPLUG is ++ * disabled that step will fail and the remove attempt cancelled by the ++ * user. If that is not honored and the card is removed anyway then it ++ * does not matter if CONFIG_MEMORY_HOTPLUG is enabled or not, it will ++ * cause a crash and other badness. ++ * ++ * Therefore, just say yes to CXL hotplug and require removal to ++ * be coordinated by userspace unless and until the kernel grows better ++ * mechanisms for doing "managed" removal of devices in consultation with ++ * the driver. ++ * ++ * [1]: https://lore.kernel.org/all/20201122014203.4706-1-ashok.raj@intel.com/ ++ */ ++static u32 calculate_cxl_support(void) ++{ ++ u32 support; ++ ++ support = OSC_CXL_2_0_PORT_DEV_REG_ACCESS_SUPPORT; ++ if (pci_aer_available()) ++ support |= OSC_CXL_PROTOCOL_ERR_REPORTING_SUPPORT; ++ if (IS_ENABLED(CONFIG_HOTPLUG_PCI_PCIE)) ++ support |= OSC_CXL_NATIVE_HP_SUPPORT; ++ ++ return support; ++} ++ + static u32 calculate_control(void) + { + u32 control; +@@ -467,6 +582,16 @@ static u32 calculate_control(void) + return control; + } + ++static u32 calculate_cxl_control(void) ++{ ++ u32 control = 0; ++ ++ if (IS_ENABLED(CONFIG_MEMORY_FAILURE)) ++ control |= OSC_CXL_ERROR_REPORTING_CONTROL; ++ ++ return control; ++} ++ + static bool os_control_query_checks(struct acpi_pci_root *root, u32 support) + { + struct acpi_device *device = root->device; +@@ -488,6 +613,7 @@ static bool os_control_query_checks(stru + static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm) + { + u32 support, control = 0, requested = 0; ++ u32 cxl_support = 0, cxl_control = 0, cxl_requested = 0; + acpi_status status; + struct acpi_device *device = root->device; + acpi_handle handle = device->handle; +@@ -511,10 +637,20 @@ static void negotiate_os_control(struct + if (os_control_query_checks(root, support)) + requested = control = calculate_control(); + +- status = acpi_pci_osc_control_set(handle, &control, support); ++ if (is_cxl(root)) { ++ cxl_support = calculate_cxl_support(); ++ decode_cxl_osc_support(root, "OS supports", cxl_support); ++ cxl_requested = cxl_control = calculate_cxl_control(); ++ } ++ ++ status = acpi_pci_osc_control_set(handle, &control, support, ++ &cxl_control, cxl_support); + if (ACPI_SUCCESS(status)) { + if (control) + decode_osc_control(root, "OS now controls", control); ++ if (cxl_control) ++ decode_cxl_osc_control(root, "OS now controls", ++ cxl_control); + + if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) { + /* +@@ -543,6 +679,11 @@ static void negotiate_os_control(struct + decode_osc_control(root, "OS requested", requested); + decode_osc_control(root, "platform willing to grant", control); + } ++ if (cxl_control) { ++ decode_cxl_osc_control(root, "OS requested", cxl_requested); ++ decode_cxl_osc_control(root, "platform willing to grant", ++ cxl_control); ++ } + + dev_info(&device->dev, "_OSC: platform retains control of PCIe features (%s)\n", + acpi_format_exception(status)); +--- a/include/acpi/acpi_bus.h ++++ b/include/acpi/acpi_bus.h +@@ -598,8 +598,10 @@ struct acpi_pci_root { + int bridge_type; + struct resource secondary; /* downstream bus range */ + +- u32 osc_support_set; /* _OSC state of support bits */ +- u32 osc_control_set; /* _OSC state of control bits */ ++ u32 osc_support_set; /* _OSC state of support bits */ ++ u32 osc_control_set; /* _OSC state of control bits */ ++ u32 osc_ext_support_set; /* _OSC state of extended support bits */ ++ u32 osc_ext_control_set; /* _OSC state of extended control bits */ + phys_addr_t mcfg_addr; + }; + +--- a/include/linux/acpi.h ++++ b/include/linux/acpi.h +@@ -554,10 +554,12 @@ acpi_status acpi_run_osc(acpi_handle han + #define OSC_PCI_CAPABILITY_DWORDS 3 + #define OSC_CXL_CAPABILITY_DWORDS 5 + +-/* Indexes into _OSC Capabilities Buffer (DWORDs 2 & 3 are device-specific) */ ++/* Indexes into _OSC Capabilities Buffer (DWORDs 2 to 5 are device-specific) */ + #define OSC_QUERY_DWORD 0 /* DWORD 1 */ + #define OSC_SUPPORT_DWORD 1 /* DWORD 2 */ + #define OSC_CONTROL_DWORD 2 /* DWORD 3 */ ++#define OSC_EXT_SUPPORT_DWORD 3 /* DWORD 4 */ ++#define OSC_EXT_CONTROL_DWORD 4 /* DWORD 5 */ + + /* _OSC Capabilities DWORD 1: Query/Control and Error Returns (generic) */ + #define OSC_QUERY_ENABLE 0x00000001 /* input */ +@@ -614,6 +616,15 @@ extern u32 osc_sb_native_usb4_control; + #define OSC_PCI_EXPRESS_LTR_CONTROL 0x00000020 + #define OSC_PCI_EXPRESS_DPC_CONTROL 0x00000080 + ++/* CXL _OSC: Capabilities DWORD 4: Support Field */ ++#define OSC_CXL_1_1_PORT_REG_ACCESS_SUPPORT 0x00000001 ++#define OSC_CXL_2_0_PORT_DEV_REG_ACCESS_SUPPORT 0x00000002 ++#define OSC_CXL_PROTOCOL_ERR_REPORTING_SUPPORT 0x00000004 ++#define OSC_CXL_NATIVE_HP_SUPPORT 0x00000008 ++ ++/* CXL _OSC: Capabilities DWORD 5: Control Field */ ++#define OSC_CXL_ERROR_REPORTING_CONTROL 0x00000001 ++ + static inline u32 acpi_osc_ctx_get_pci_control(struct acpi_osc_context *context) + { + u32 *ret = context->ret.pointer; +@@ -621,6 +632,13 @@ static inline u32 acpi_osc_ctx_get_pci_c + return ret[OSC_CONTROL_DWORD]; + } + ++static inline u32 acpi_osc_ctx_get_cxl_control(struct acpi_osc_context *context) ++{ ++ u32 *ret = context->ret.pointer; ++ ++ return ret[OSC_EXT_CONTROL_DWORD]; ++} ++ + #define ACPI_GSB_ACCESS_ATTRIB_QUICK 0x00000002 + #define ACPI_GSB_ACCESS_ATTRIB_SEND_RCV 0x00000004 + #define ACPI_GSB_ACCESS_ATTRIB_BYTE 0x00000006 +@@ -1022,6 +1040,11 @@ static inline u32 acpi_osc_ctx_get_pci_c + { + return 0; + } ++ ++static inline u32 acpi_osc_ctx_get_cxl_control(struct acpi_osc_context *context) ++{ ++ return 0; ++} + + #endif /* !CONFIG_ACPI */ + diff --git a/patches.suse/PCI-ASPM-Correct-LTR_L1.2_THRESHOLD-computation.patch b/patches.suse/PCI-ASPM-Correct-LTR_L1.2_THRESHOLD-computation.patch new file mode 100644 index 0000000..20d4361 --- /dev/null +++ b/patches.suse/PCI-ASPM-Correct-LTR_L1.2_THRESHOLD-computation.patch @@ -0,0 +1,111 @@ +From 7afeb84d14eaaebb71f5c558ed57ca858e4304e7 Mon Sep 17 00:00:00 2001 +From: Bjorn Helgaas +Date: Tue, 4 Oct 2022 21:58:09 -0500 +Subject: [PATCH] PCI/ASPM: Correct LTR_L1.2_THRESHOLD computation +Git-commit: 7afeb84d14eaaebb71f5c558ed57ca858e4304e7 +Patch-mainline: v6.1-rc1 +References: git-fixes + +80d7d7a904fa ("PCI/ASPM: Calculate LTR_L1.2_THRESHOLD from device +characteristics") replaced a fixed value (163840ns) with one computed from +T_POWER_OFF, Common_Mode_Restore_Time, etc., but it encoded the +LTR_L1.2_THRESHOLD value incorrectly. + +This is especially a problem for small thresholds, e.g., 63ns fell into the +"threshold_ns < 1024" case and was encoded as 32ns: + + LTR_L1.2_THRESHOLD_Scale = 1 (multiplier is 32ns) + LTR_L1.2_THRESHOLD_Value = 63 >> 5 = 1 + LTR_L1.2_THRESHOLD = multiplier * value = 32ns * 1 = 32ns + +Correct the algorithm to encode all times of 1023ns (0x3ff) or smaller +exactly and larger times conservatively (the encoded threshold is never +smaller than was requested). This reduces the chance of entering L1.2 +when the device can't tolerate the exit latency. + +Fixes: 80d7d7a904fa ("PCI/ASPM: Calculate LTR_L1.2_THRESHOLD from device characteristics") +Link: https://lore.kernel.org/r/20221005025809.2247547-4-helgaas@kernel.org +Signed-off-by: Bjorn Helgaas +Reviewed-by: Kuppuswamy Sathyanarayanan +Acked-by: Takashi Iwai + +--- + drivers/pci/pcie/aspm.c | 49 +++++++++++++++++++++++++++-------------- + 1 file changed, 32 insertions(+), 17 deletions(-) + +diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c +index f12d117f44e0..53a1fa306e1e 100644 +--- a/drivers/pci/pcie/aspm.c ++++ b/drivers/pci/pcie/aspm.c +@@ -8,6 +8,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -350,29 +351,43 @@ static u32 calc_l1ss_pwron(struct pci_dev *pdev, u32 scale, u32 val) + return 0; + } + ++/* ++ * Encode an LTR_L1.2_THRESHOLD value for the L1 PM Substates Control 1 ++ * register. Ports enter L1.2 when the most recent LTR value is greater ++ * than or equal to LTR_L1.2_THRESHOLD, so we round up to make sure we ++ * don't enter L1.2 too aggressively. ++ * ++ * See PCIe r6.0, sec 5.5.1, 6.18, 7.8.3.3. ++ */ + static void encode_l12_threshold(u32 threshold_us, u32 *scale, u32 *value) + { +- u32 threshold_ns = threshold_us * 1000; ++ u64 threshold_ns = (u64) threshold_us * 1000; + +- /* See PCIe r3.1, sec 7.33.3 and sec 6.18 */ +- if (threshold_ns < 32) { +- *scale = 0; ++ /* ++ * LTR_L1.2_THRESHOLD_Value ("value") is a 10-bit field with max ++ * value of 0x3ff. ++ */ ++ if (threshold_ns <= 0x3ff * 1) { ++ *scale = 0; /* Value times 1ns */ + *value = threshold_ns; +- } else if (threshold_ns < 1024) { +- *scale = 1; +- *value = threshold_ns >> 5; +- } else if (threshold_ns < 32768) { +- *scale = 2; +- *value = threshold_ns >> 10; +- } else if (threshold_ns < 1048576) { +- *scale = 3; +- *value = threshold_ns >> 15; +- } else if (threshold_ns < 33554432) { +- *scale = 4; +- *value = threshold_ns >> 20; ++ } else if (threshold_ns <= 0x3ff * 32) { ++ *scale = 1; /* Value times 32ns */ ++ *value = roundup(threshold_ns, 32) / 32; ++ } else if (threshold_ns <= 0x3ff * 1024) { ++ *scale = 2; /* Value times 1024ns */ ++ *value = roundup(threshold_ns, 1024) / 1024; ++ } else if (threshold_ns <= 0x3ff * 32768) { ++ *scale = 3; /* Value times 32768ns */ ++ *value = roundup(threshold_ns, 32768) / 32768; ++ } else if (threshold_ns <= 0x3ff * 1048576) { ++ *scale = 4; /* Value times 1048576ns */ ++ *value = roundup(threshold_ns, 1048576) / 1048576; ++ } else if (threshold_ns <= 0x3ff * (u64) 33554432) { ++ *scale = 5; /* Value times 33554432ns */ ++ *value = roundup(threshold_ns, 33554432) / 33554432; + } else { + *scale = 5; +- *value = threshold_ns >> 25; ++ *value = 0x3ff; /* Max representable value */ + } + } + +-- +2.35.3 + diff --git a/patches.suse/PCI-ASPM-Ignore-L1-PM-Substates-if-device-lacks-capa.patch b/patches.suse/PCI-ASPM-Ignore-L1-PM-Substates-if-device-lacks-capa.patch new file mode 100644 index 0000000..160868a --- /dev/null +++ b/patches.suse/PCI-ASPM-Ignore-L1-PM-Substates-if-device-lacks-capa.patch @@ -0,0 +1,40 @@ +From cfc0028627cadfa271fab0290f18731193d63d87 Mon Sep 17 00:00:00 2001 +From: Bjorn Helgaas +Date: Tue, 4 Oct 2022 21:58:08 -0500 +Subject: [PATCH] PCI/ASPM: Ignore L1 PM Substates if device lacks capability +Git-commit: cfc0028627cadfa271fab0290f18731193d63d87 +Patch-mainline: v6.1-rc1 +References: git-fixes + +187f91db8237 ("PCI/ASPM: Remove struct aspm_register_info.l1ss_cap") +inadvertently removed a check for existence of the L1 PM Substates (L1SS) +Capability before reading it. + +If there is no L1SS Capability, this means we mistakenly read PCI_COMMAND +and PCI_STATUS (config address 0x04) and interpret that as the PCI_L1SS_CAP +register, so we may incorrectly configure L1SS. + +Make sure the L1SS Capability exists before trying to read it. + +Fixes: 187f91db8237 ("PCI/ASPM: Remove struct aspm_register_info.l1ss_cap") +Link: https://lore.kernel.org/r/20221005025809.2247547-3-helgaas@kernel.org +Signed-off-by: Bjorn Helgaas +Reviewed-by: Kuppuswamy Sathyanarayanan +Acked-by: Takashi Iwai + +--- + drivers/pci/pcie/aspm.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/pci/pcie/aspm.c ++++ b/drivers/pci/pcie/aspm.c +@@ -605,6 +605,9 @@ static void pcie_aspm_cap_init(struct pc + link->latency_up.l1 = calc_l1_latency(parent_lnkcap); + link->latency_dw.l1 = calc_l1_latency(child_lnkcap); + ++ if (!parent->l1ss || !child->l1ss) ++ return; ++ + /* Setup L1 substate */ + pci_read_config_dword(parent, parent->l1ss + PCI_L1SS_CAP, + &parent_l1ss_cap); diff --git a/patches.suse/PCI-Fix-used_buses-calculation-in-pci_scan_child_bus.patch b/patches.suse/PCI-Fix-used_buses-calculation-in-pci_scan_child_bus.patch new file mode 100644 index 0000000..e72d2e0 --- /dev/null +++ b/patches.suse/PCI-Fix-used_buses-calculation-in-pci_scan_child_bus.patch @@ -0,0 +1,49 @@ +From 8066cc86b7aaaf6b4b38a81932459c6450440daa Mon Sep 17 00:00:00 2001 +From: Mika Westerberg +Date: Mon, 5 Sep 2022 11:02:27 +0300 +Subject: [PATCH] PCI: Fix used_buses calculation in pci_scan_child_bus_extend() +Git-commit: 8066cc86b7aaaf6b4b38a81932459c6450440daa +Patch-mainline: v6.1-rc1 +References: git-fixes + +pci_scan_bridge_extend() returns the subordinate bus number needed to cover +all the buses below a bridge. pci_scan_child_bus_extend() computes the +number of buses to reserve by comparing that with the current max bus +number. Previously it did the subtraction in the wrong order, so +'used_buses' was nonsense. + +Subtract 'max' from 'cmax' as is done for the similar +pci_scan_bridge_extend() call in the following block. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=216000 +Fixes: 3374c545c27c ("PCI: Account for all bridges on bus when distributing bus numbers") +Link: https://lore.kernel.org/r/20220905080232.36087-2-mika.westerberg@linux.intel.com +Reported-by: Chris Chiu +Tested-by: Chris Chiu +Signed-off-by: Mika Westerberg +Signed-off-by: Bjorn Helgaas +Reviewed-by: Andy Shevchenko +Acked-by: Takashi Iwai + +--- + drivers/pci/probe.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c +index c5286b027f00..4f940dcd102c 100644 +--- a/drivers/pci/probe.c ++++ b/drivers/pci/probe.c +@@ -2920,8 +2920,8 @@ static unsigned int pci_scan_child_bus_extend(struct pci_bus *bus, + * hotplug bridges too much during the second scan below. + */ + used_buses++; +- if (cmax - max > 1) +- used_buses += cmax - max - 1; ++ if (max - cmax > 1) ++ used_buses += max - cmax - 1; + } + + /* Scan bridges that need to be reconfigured */ +-- +2.35.3 + diff --git a/patches.suse/PCI-Sanitise-firmware-BAR-assignments-behind-a-PCI-P.patch b/patches.suse/PCI-Sanitise-firmware-BAR-assignments-behind-a-PCI-P.patch new file mode 100644 index 0000000..2eef148 --- /dev/null +++ b/patches.suse/PCI-Sanitise-firmware-BAR-assignments-behind-a-PCI-P.patch @@ -0,0 +1,107 @@ +From 0e32818397426a688f598f35d3bc762eca6d7592 Mon Sep 17 00:00:00 2001 +From: "Maciej W. Rozycki" +Date: Wed, 21 Sep 2022 20:49:16 +0100 +Subject: [PATCH] PCI: Sanitise firmware BAR assignments behind a PCI-PCI bridge +Git-commit: 0e32818397426a688f598f35d3bc762eca6d7592 +Patch-mainline: v6.1-rc1 +References: git-fixes + +When pci_assign_resource() is unable to assign resources to a BAR, it uses +pci_revert_fw_address() to fall back to a firmware assignment (if any). +Previously pci_revert_fw_address() assumed all addresses could reach the +device, but this is not true if the device is below a bridge that only +forwards addresses within its windows. + +This problem was observed on a Tyan Tomcat IV S1564D system where the BIOS +did not assign valid addresses to several bridges and USB devices: + + pci 0000:00:11.0: PCI-to-PCIe bridge to [bus 01-ff] + pci 0000:00:11.0: bridge window [io 0xe000-0xefff] + pci 0000:01:00.0: PCIe Upstream Port to [bus 02-ff] + pci 0000:01:00.0: bridge window [io 0x0000-0x0fff] # unreachable + pci 0000:02:02.0: PCIe Downstream Port to [bus 05-ff] + pci 0000:02:02.0: bridge window [io 0x0000-0x0fff] # unreachable + pci 0000:05:00.0: PCIe-to-PCI bridge to [bus 06-ff] + pci 0000:05:00.0: bridge window [io 0x0000-0x0fff] # unreachable + pci 0000:06:08.0: USB UHCI 1.1 + pci 0000:06:08.0: BAR 4: [io 0xfce0-0xfcff] # unreachable + pci 0000:06:08.1: USB UHCI 1.1 + pci 0000:06:08.1: BAR 4: [io 0xfce0-0xfcff] # unreachable + pci 0000:06:08.0: can't claim BAR 4 [io 0xfce0-0xfcff]: no compatible bridge window + pci 0000:06:08.1: can't claim BAR 4 [io 0xfce0-0xfcff]: no compatible bridge window + +During the first pass of assigning unassigned resources, there was not +enough I/O space available, so we couldn't assign the 06:08.0 BAR and +reverted to the firmware assignment (still unreachable). Reverting the +06:08.1 assignment failed because it conflicted with 06:08.0: + + pci 0000:00:11.0: bridge window [io 0xe000-0xefff] + pci 0000:01:00.0: no space for bridge window [io size 0x2000] + pci 0000:02:02.0: no space for bridge window [io size 0x1000] + pci 0000:05:00.0: no space for bridge window [io size 0x1000] + pci 0000:06:08.0: BAR 4: no space for [io size 0x0020] + pci 0000:06:08.0: BAR 4: trying firmware assignment [io 0xfce0-0xfcff] + pci 0000:06:08.1: BAR 4: no space for [io size 0x0020] + pci 0000:06:08.1: BAR 4: trying firmware assignment [io 0xfce0-0xfcff] + pci 0000:06:08.1: BAR 4: [io 0xfce0-0xfcff] conflicts with 0000:06:08.0 [io 0xfce0-0xfcff] + +A subsequent pass assigned valid bridge windows and a valid 06:08.1 BAR, +but left the 06:08.0 BAR alone, so the UHCI device was still unusable: + + pci 0000:00:11.0: bridge window [io 0xe000-0xefff] released + pci 0000:00:11.0: bridge window [io 0x1000-0x2fff] # reassigned + pci 0000:01:00.0: bridge window [io 0x1000-0x2fff] # reassigned + pci 0000:02:02.0: bridge window [io 0x2000-0x2fff] # reassigned + pci 0000:05:00.0: bridge window [io 0x2000-0x2fff] # reassigned + pci 0000:06:08.0: BAR 4: assigned [io 0xfce0-0xfcff] # left alone + pci 0000:06:08.1: BAR 4: assigned [io 0x2000-0x201f] + ... + uhci_hcd 0000:06:08.0: host system error, PCI problems? + uhci_hcd 0000:06:08.0: host controller process error, something bad happened! + uhci_hcd 0000:06:08.0: host controller halted, very bad! + uhci_hcd 0000:06:08.0: HCRESET not completed yet! + uhci_hcd 0000:06:08.0: HC died; cleaning up + +If the address assigned by firmware is not reachable because it's not +within upstream bridge windows, fail instead of assigning the unusable +address from firmware. + +[bhelgaas: commit log, use pci_upstream_bridge()] +Link: https://bugzilla.kernel.org/show_bug.cgi?id=16263 +Link: https://lore.kernel.org/r/alpine.DEB.2.21.2203012338460.46819@angie.orcam.me.uk +Link: https://lore.kernel.org/r/alpine.DEB.2.21.2209211921250.29493@angie.orcam.me.uk +Fixes: 58c84eda0756 ("PCI: fall back to original BIOS BAR addresses") +Signed-off-by: Maciej W. Rozycki +Signed-off-by: Bjorn Helgaas +Cc: stable@vger.kernel.org # v2.6.35+ +Acked-by: Takashi Iwai + +--- + drivers/pci/setup-res.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c +index 439ac5f5907a..b492e67c3d87 100644 +--- a/drivers/pci/setup-res.c ++++ b/drivers/pci/setup-res.c +@@ -214,6 +214,17 @@ static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev, + + root = pci_find_parent_resource(dev, res); + if (!root) { ++ /* ++ * If dev is behind a bridge, accesses will only reach it ++ * if res is inside the relevant bridge window. ++ */ ++ if (pci_upstream_bridge(dev)) ++ return -ENXIO; ++ ++ /* ++ * On the root bus, assume the host bridge will forward ++ * everything. ++ */ + if (res->flags & IORESOURCE_IO) + root = &ioport_resource; + else +-- +2.35.3 + diff --git a/patches.suse/PCI-mediatek-gen3-Change-driver-name-to-mtk-pcie-gen.patch b/patches.suse/PCI-mediatek-gen3-Change-driver-name-to-mtk-pcie-gen.patch new file mode 100644 index 0000000..b864f82 --- /dev/null +++ b/patches.suse/PCI-mediatek-gen3-Change-driver-name-to-mtk-pcie-gen.patch @@ -0,0 +1,40 @@ +From 034fdac01fe5184e63d8af901ddb9c9a329f6902 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Thu, 5 May 2022 10:39:07 +0200 +Subject: [PATCH] PCI: mediatek-gen3: Change driver name to mtk-pcie-gen3 +Git-commit: 034fdac01fe5184e63d8af901ddb9c9a329f6902 +Patch-mainline: v6.1-rc1 +References: git-fixes + +driver_register() will refuse to register another driver with the same name. +This change allows pcie-mediatek-gen3 to coexist with pcie-mediatek built into +the kernel. + +Link: https://lore.kernel.org/r/20220505083907.86598-1-nbd@nbd.name +Fixes: d3bf75b579b9 ("PCI: mediatek-gen3: Add MediaTek Gen3 driver for MT8192") +Signed-off-by: Felix Fietkau +Signed-off-by: Lorenzo Pieralisi +Reviewed-by: AngeloGioacchino Del Regno +Reviewed-by: Jianjun Wang +Acked-by: Takashi Iwai + +--- + drivers/pci/controller/pcie-mediatek-gen3.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c +index 11cdb9b6f109..b8612ce5f4d0 100644 +--- a/drivers/pci/controller/pcie-mediatek-gen3.c ++++ b/drivers/pci/controller/pcie-mediatek-gen3.c +@@ -1071,7 +1071,7 @@ static struct platform_driver mtk_pcie_driver = { + .probe = mtk_pcie_probe, + .remove = mtk_pcie_remove, + .driver = { +- .name = "mtk-pcie", ++ .name = "mtk-pcie-gen3", + .of_match_table = mtk_pcie_of_match, + .pm = &mtk_pcie_pm_ops, + }, +-- +2.35.3 + diff --git a/patches.suse/Revert-ACPICA-executer-exsystem-Warn-about-sleeps-gr.patch b/patches.suse/Revert-ACPICA-executer-exsystem-Warn-about-sleeps-gr.patch new file mode 100644 index 0000000..4076d6e --- /dev/null +++ b/patches.suse/Revert-ACPICA-executer-exsystem-Warn-about-sleeps-gr.patch @@ -0,0 +1,43 @@ +From: "Rafael J. Wysocki" +Date: Sat, 21 May 2022 18:02:26 +0200 +Subject: Revert "ACPICA: executer/exsystem: Warn about sleeps greater than 10 + ms" +Patch-mainline: v5.19-rc1 +Git-commit: c244dc1bc92e94c625325a654337490bb1da871a +References: jsc#PED-1408 + +Commit 6eaf08770ee8 ("ACPICA: executer/exsystem: Warn about sleeps +greater than 10 ms") made acpi_ex_system_do_sleep() log a warning for +sleep times greater than 10 ms, but such sleep times are used in +power management AML because of the PCI specification requirements. + +This results with logging warnings that cannot really be acted on in +any useful way which is annoying and these warnings show up in the logs +on many production systems, so revert commit 6eaf08770ee8. + +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/acpica/exsystem.c | 11 ----------- + 1 file changed, 11 deletions(-) + +--- a/drivers/acpi/acpica/exsystem.c ++++ b/drivers/acpi/acpica/exsystem.c +@@ -170,17 +170,6 @@ acpi_status acpi_ex_system_do_sleep(u64 + acpi_ex_exit_interpreter(); + + /* +- * Warn users about excessive sleep times, so ASL code can be improved to +- * use polling or similar techniques. +- */ +- if (how_long_ms > 10) { +- ACPI_WARNING((AE_INFO, +- "Firmware issue: Excessive sleep time (0x%8.8X%8.8X ms > 10 ms)" +- " in ACPI Control Method", +- ACPI_FORMAT_UINT64(how_long_ms))); +- } +- +- /* + * For compatibility with other ACPI implementations and to prevent + * accidental deep sleeps, limit the sleep time to something reasonable. + */ diff --git a/patches.suse/Revert-ALSA-hda-cs35l41-Allow-compilation-test-on-no.patch b/patches.suse/Revert-ALSA-hda-cs35l41-Allow-compilation-test-on-no.patch new file mode 100644 index 0000000..69199bf --- /dev/null +++ b/patches.suse/Revert-ALSA-hda-cs35l41-Allow-compilation-test-on-no.patch @@ -0,0 +1,47 @@ +From d59d2277febbad93e42137a50673dd1c16199813 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Fri, 15 Jul 2022 20:24:27 +0200 +Subject: [PATCH] Revert "ALSA: hda: cs35l41: Allow compilation test on non-ACPI configurations" +Git-commit: d59d2277febbad93e42137a50673dd1c16199813 +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +Since the recent change in CS35L41 codec requires the reference of +acpi_dev handle, the current Kconfig may lead to a build breakage. + +Revert the Kconfig change and re-introduce the hard dependency on +CONFIG_ACPI again as a temporary workaround. + +Fixes: eef375960210 ("ALSA: hda: cs35l41: Support reading subsystem id from ACPI") +Link: https://lore.kernel.org/r/20220715182427.18891-1-tiwai@suse.de +Signed-off-by: Takashi Iwai + +--- + sound/pci/hda/Kconfig | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig +index 44c33bc0740e..a8e8cf98befa 100644 +--- a/sound/pci/hda/Kconfig ++++ b/sound/pci/hda/Kconfig +@@ -103,7 +103,7 @@ config SND_HDA_CS_DSP_CONTROLS + config SND_HDA_SCODEC_CS35L41_I2C + tristate "Build CS35L41 HD-audio side codec support for I2C Bus" + depends on I2C +- depends on ACPI || COMPILE_TEST ++ depends on ACPI + depends on SND_SOC + select SND_SOC_CS35L41_LIB + select SND_HDA_SCODEC_CS35L41 +@@ -118,7 +118,7 @@ comment "Set to Y if you want auto-loading the side codec driver" + config SND_HDA_SCODEC_CS35L41_SPI + tristate "Build CS35L41 HD-audio codec support for SPI Bus" + depends on SPI_MASTER +- depends on ACPI || COMPILE_TEST ++ depends on ACPI + depends on SND_SOC + select SND_SOC_CS35L41_LIB + select SND_HDA_SCODEC_CS35L41 +-- +2.35.3 + diff --git a/patches.suse/Revert-ALSA-usb-audio-Split-endpoint-setups-for-hw_p.patch b/patches.suse/Revert-ALSA-usb-audio-Split-endpoint-setups-for-hw_p.patch new file mode 100644 index 0000000..22a37de --- /dev/null +++ b/patches.suse/Revert-ALSA-usb-audio-Split-endpoint-setups-for-hw_p.patch @@ -0,0 +1,162 @@ +From 79764ec772bc1346441ae1c4b1f3bd1991d634e8 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 20 Sep 2022 13:39:29 +0200 +Subject: [PATCH] Revert "ALSA: usb-audio: Split endpoint setups for hw_params and prepare" +Git-commit: 79764ec772bc1346441ae1c4b1f3bd1991d634e8 +Patch-mainline: v6.0-rc7 +References: git-fixes + +This reverts commit ff878b408a03bef5d610b7e2302702e16a53636e. + +Unfortunately the recent fix seems bringing another regressions with +PulseAudio / pipewire, at least for Steinberg and MOTU devices. + +As a temporary solution, do a straight revert. The issue for Android +will be revisited again later by another different fix (if any). + +Fixes: ff878b408a03 ("ALSA: usb-audio: Split endpoint setups for hw_params and prepare") +Cc: +Buglink: https://bugzilla.kernel.org/show_bug.cgi?id=216500 +Link: https://lore.kernel.org/r/20220920113929.25162-1-tiwai@suse.de +Signed-off-by: Takashi Iwai + +--- + sound/usb/endpoint.c | 23 ++++++++++++++--------- + sound/usb/endpoint.h | 6 ++---- + sound/usb/pcm.c | 14 ++++---------- + 3 files changed, 20 insertions(+), 23 deletions(-) + +diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c +index 8c8f9a851f89..eb71df9da831 100644 +--- a/sound/usb/endpoint.c ++++ b/sound/usb/endpoint.c +@@ -758,8 +758,7 @@ bool snd_usb_endpoint_compatible(struct snd_usb_audio *chip, + * The endpoint needs to be closed via snd_usb_endpoint_close() later. + * + * Note that this function doesn't configure the endpoint. The substream +- * needs to set it up later via snd_usb_endpoint_set_params() and +- * snd_usb_endpoint_prepare(). ++ * needs to set it up later via snd_usb_endpoint_configure(). + */ + struct snd_usb_endpoint * + snd_usb_endpoint_open(struct snd_usb_audio *chip, +@@ -1293,13 +1292,12 @@ static int sync_ep_set_params(struct snd_usb_endpoint *ep) + /* + * snd_usb_endpoint_set_params: configure an snd_usb_endpoint + * +- * It's called either from hw_params callback. + * Determine the number of URBs to be used on this endpoint. + * An endpoint must be configured before it can be started. + * An endpoint that is already running can not be reconfigured. + */ +-int snd_usb_endpoint_set_params(struct snd_usb_audio *chip, +- struct snd_usb_endpoint *ep) ++static int snd_usb_endpoint_set_params(struct snd_usb_audio *chip, ++ struct snd_usb_endpoint *ep) + { + const struct audioformat *fmt = ep->cur_audiofmt; + int err; +@@ -1382,18 +1380,18 @@ static int init_sample_rate(struct snd_usb_audio *chip, + } + + /* +- * snd_usb_endpoint_prepare: Prepare the endpoint ++ * snd_usb_endpoint_configure: Configure the endpoint + * + * This function sets up the EP to be fully usable state. +- * It's called either from prepare callback. ++ * It's called either from hw_params or prepare callback. + * The function checks need_setup flag, and performs nothing unless needed, + * so it's safe to call this multiple times. + * + * This returns zero if unchanged, 1 if the configuration has changed, + * or a negative error code. + */ +-int snd_usb_endpoint_prepare(struct snd_usb_audio *chip, +- struct snd_usb_endpoint *ep) ++int snd_usb_endpoint_configure(struct snd_usb_audio *chip, ++ struct snd_usb_endpoint *ep) + { + bool iface_first; + int err = 0; +@@ -1414,6 +1412,9 @@ int snd_usb_endpoint_prepare(struct snd_usb_audio *chip, + if (err < 0) + goto unlock; + } ++ err = snd_usb_endpoint_set_params(chip, ep); ++ if (err < 0) ++ goto unlock; + goto done; + } + +@@ -1441,6 +1442,10 @@ int snd_usb_endpoint_prepare(struct snd_usb_audio *chip, + if (err < 0) + goto unlock; + ++ err = snd_usb_endpoint_set_params(chip, ep); ++ if (err < 0) ++ goto unlock; ++ + err = snd_usb_select_mode_quirk(chip, ep->cur_audiofmt); + if (err < 0) + goto unlock; +diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h +index e67ea28faa54..6a9af04cf175 100644 +--- a/sound/usb/endpoint.h ++++ b/sound/usb/endpoint.h +@@ -17,10 +17,8 @@ snd_usb_endpoint_open(struct snd_usb_audio *chip, + bool is_sync_ep); + void snd_usb_endpoint_close(struct snd_usb_audio *chip, + struct snd_usb_endpoint *ep); +-int snd_usb_endpoint_set_params(struct snd_usb_audio *chip, +- struct snd_usb_endpoint *ep); +-int snd_usb_endpoint_prepare(struct snd_usb_audio *chip, +- struct snd_usb_endpoint *ep); ++int snd_usb_endpoint_configure(struct snd_usb_audio *chip, ++ struct snd_usb_endpoint *ep); + int snd_usb_endpoint_get_clock_rate(struct snd_usb_audio *chip, int clock); + + bool snd_usb_endpoint_compatible(struct snd_usb_audio *chip, +diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c +index b604f7e95e82..d45d1d7e6664 100644 +--- a/sound/usb/pcm.c ++++ b/sound/usb/pcm.c +@@ -443,17 +443,17 @@ static int configure_endpoints(struct snd_usb_audio *chip, + if (stop_endpoints(subs, false)) + sync_pending_stops(subs); + if (subs->sync_endpoint) { +- err = snd_usb_endpoint_prepare(chip, subs->sync_endpoint); ++ err = snd_usb_endpoint_configure(chip, subs->sync_endpoint); + if (err < 0) + return err; + } +- err = snd_usb_endpoint_prepare(chip, subs->data_endpoint); ++ err = snd_usb_endpoint_configure(chip, subs->data_endpoint); + if (err < 0) + return err; + snd_usb_set_format_quirk(subs, subs->cur_audiofmt); + } else { + if (subs->sync_endpoint) { +- err = snd_usb_endpoint_prepare(chip, subs->sync_endpoint); ++ err = snd_usb_endpoint_configure(chip, subs->sync_endpoint); + if (err < 0) + return err; + } +@@ -551,13 +551,7 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, + subs->cur_audiofmt = fmt; + mutex_unlock(&chip->mutex); + +- if (subs->sync_endpoint) { +- ret = snd_usb_endpoint_set_params(chip, subs->sync_endpoint); +- if (ret < 0) +- goto unlock; +- } +- +- ret = snd_usb_endpoint_set_params(chip, subs->data_endpoint); ++ ret = configure_endpoints(chip, subs); + + unlock: + if (ret < 0) +-- +2.35.3 + diff --git a/patches.suse/Revert-SUNRPC-Remove-unreachable-error-condition.patch b/patches.suse/Revert-SUNRPC-Remove-unreachable-error-condition.patch new file mode 100644 index 0000000..d7d83f2 --- /dev/null +++ b/patches.suse/Revert-SUNRPC-Remove-unreachable-error-condition.patch @@ -0,0 +1,34 @@ +From: Dan Aloni +Date: Thu, 8 Sep 2022 17:08:51 +0300 +Subject: [PATCH] Revert "SUNRPC: Remove unreachable error condition" +Git-commit: 13bd9014180425f5a35eaf3735971d582c299292 +Patch-mainline: v6.0 +References: git-fixes + +This reverts commit efe57fd58e1cb77f9186152ee12a8aa4ae3348e0. + +The assumption that it is impossible to return an ERR pointer from +rpc_run_task() no longer holds due to commit 25cf32ad5dba ("SUNRPC: +Handle allocation failure in rpc_new_task()"). + +Fixes: 25cf32ad5dba ('SUNRPC: Handle allocation failure in rpc_new_task()') +Fixes: efe57fd58e1c ('SUNRPC: Remove unreachable error condition') +Signed-off-by: Dan Aloni +Signed-off-by: Trond Myklebust +Acked-by: NeilBrown + +--- + net/sunrpc/clnt.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/sunrpc/clnt.c ++++ b/net/sunrpc/clnt.c +@@ -2844,6 +2844,8 @@ int rpc_clnt_test_and_add_xprt(struct rp + + task = rpc_call_null_helper(clnt, xprt, NULL, RPC_TASK_ASYNC, + &rpc_cb_add_xprt_call_ops, data); ++ if (IS_ERR(task)) ++ return PTR_ERR(task); + + rpc_put_task(task); + success: diff --git a/patches.suse/Revert-crypto-qat-reduce-size-of-mapped-region.patch b/patches.suse/Revert-crypto-qat-reduce-size-of-mapped-region.patch new file mode 100644 index 0000000..08e6ca7 --- /dev/null +++ b/patches.suse/Revert-crypto-qat-reduce-size-of-mapped-region.patch @@ -0,0 +1,103 @@ +From 9c5f21b198d259bfe1191b1fedf08e2eab15b33b Mon Sep 17 00:00:00 2001 +From: Giovanni Cabiddu +Date: Fri, 9 Sep 2022 11:49:13 +0100 +Subject: [PATCH] Revert "crypto: qat - reduce size of mapped region" +Git-commit: 9c5f21b198d259bfe1191b1fedf08e2eab15b33b +Patch-mainline: v6.1-rc1 +References: git-fixes + +This reverts commit e48767c17718067ba21fb2ef461779ec2506f845. + +In an attempt to resolve a set of warnings reported by the static +analyzer Smatch, the reverted commit improperly reduced the sizes of the +DMA mappings used for the input and output parameters for both RSA and +DH creating a mismatch (map size=8 bytes, unmap size=64 bytes). + +This issue is reported when CONFIG_DMA_API_DEBUG is selected, when the +crypto self test is run. The function dma_unmap_single() reports a +warning similar to the one below, saying that the `device driver frees +DMA memory with different size`. + + DMA-API: 4xxx 0000:06:00.0: device driver frees DMA memory with different size [device address=0x0000000123206c80] [map size=8 bytes] [unmap size=64 bytes] + WARNING: CPU: 0 PID: 0 at kernel/dma/debug.c:973 check_unmap+0x3d0/0x8c0\ + ... + Call Trace: + + debug_dma_unmap_page+0x5c/0x60 + qat_dh_cb+0xd7/0x110 [intel_qat] + qat_alg_asym_callback+0x1a/0x30 [intel_qat] + adf_response_handler+0xbd/0x1a0 [intel_qat] + tasklet_action_common.constprop.0+0xcd/0xe0 + __do_softirq+0xf8/0x30c + __irq_exit_rcu+0xbf/0x140 + common_interrupt+0xb9/0xd0 + + + +The original commit was correct. + +Cc: +Reported-by: Herbert Xu +Signed-off-by: Giovanni Cabiddu +Signed-off-by: Herbert Xu +Acked-by: Takashi Iwai + +--- + drivers/crypto/qat/qat_common/qat_asym_algs.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/crypto/qat/qat_common/qat_asym_algs.c b/drivers/crypto/qat/qat_common/qat_asym_algs.c +index 095ed2a404d2..85b0f30712e1 100644 +--- a/drivers/crypto/qat/qat_common/qat_asym_algs.c ++++ b/drivers/crypto/qat/qat_common/qat_asym_algs.c +@@ -333,13 +333,13 @@ static int qat_dh_compute_value(struct kpp_request *req) + qat_req->out.dh.out_tab[1] = 0; + /* Mapping in.in.b or in.in_g2.xa is the same */ + qat_req->phy_in = dma_map_single(dev, &qat_req->in.dh.in.b, +- sizeof(qat_req->in.dh.in.b), ++ sizeof(struct qat_dh_input_params), + DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(dev, qat_req->phy_in))) + goto unmap_dst; + + qat_req->phy_out = dma_map_single(dev, &qat_req->out.dh.r, +- sizeof(qat_req->out.dh.r), ++ sizeof(struct qat_dh_output_params), + DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(dev, qat_req->phy_out))) + goto unmap_in_params; +@@ -730,13 +730,13 @@ static int qat_rsa_enc(struct akcipher_request *req) + qat_req->in.rsa.in_tab[3] = 0; + qat_req->out.rsa.out_tab[1] = 0; + qat_req->phy_in = dma_map_single(dev, &qat_req->in.rsa.enc.m, +- sizeof(qat_req->in.rsa.enc.m), ++ sizeof(struct qat_rsa_input_params), + DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(dev, qat_req->phy_in))) + goto unmap_dst; + + qat_req->phy_out = dma_map_single(dev, &qat_req->out.rsa.enc.c, +- sizeof(qat_req->out.rsa.enc.c), ++ sizeof(struct qat_rsa_output_params), + DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(dev, qat_req->phy_out))) + goto unmap_in_params; +@@ -876,13 +876,13 @@ static int qat_rsa_dec(struct akcipher_request *req) + qat_req->in.rsa.in_tab[3] = 0; + qat_req->out.rsa.out_tab[1] = 0; + qat_req->phy_in = dma_map_single(dev, &qat_req->in.rsa.dec.c, +- sizeof(qat_req->in.rsa.dec.c), ++ sizeof(struct qat_rsa_input_params), + DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(dev, qat_req->phy_in))) + goto unmap_dst; + + qat_req->phy_out = dma_map_single(dev, &qat_req->out.rsa.dec.m, +- sizeof(qat_req->out.rsa.dec.m), ++ sizeof(struct qat_rsa_output_params), + DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(dev, qat_req->phy_out))) + goto unmap_in_params; +-- +2.35.3 + diff --git a/patches.suse/Revert-drm-amdgpu-use-dirty-framebuffer-helper.patch b/patches.suse/Revert-drm-amdgpu-use-dirty-framebuffer-helper.patch new file mode 100644 index 0000000..17f077f --- /dev/null +++ b/patches.suse/Revert-drm-amdgpu-use-dirty-framebuffer-helper.patch @@ -0,0 +1,69 @@ +From 17d819e2828cacca2e4c909044eb9798ed379cd2 Mon Sep 17 00:00:00 2001 +From: Hamza Mahfooz +Date: Wed, 5 Oct 2022 11:30:38 -0400 +Subject: [PATCH] Revert "drm/amdgpu: use dirty framebuffer helper" +Git-commit: 17d819e2828cacca2e4c909044eb9798ed379cd2 +Patch-mainline: v6.1-rc1 +References: git-fixes + +This reverts commit 66f99628eb24409cb8feb5061f78283c8b65f820. + +Unfortunately, that commit causes performance regressions on non-PSR +setups. So, just revert it until FB_DAMAGE_CLIPS support can be added. + +Cc: stable@vger.kernel.org +Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2189 +Link: https://bugzilla.kernel.org/show_bug.cgi?id=216554 +Fixes: 66f99628eb2440 ("drm/amdgpu: use dirty framebuffer helper") +Fixes: abbc7a3dafb91b ("drm/amdgpu: don't register a dirty callback for non-atomic") +Signed-off-by: Hamza Mahfooz +Acked-by: Alex Deucher +Signed-off-by: Alex Deucher +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 14 ++------------ + 1 file changed, 2 insertions(+), 12 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +index 23998f727c7f..1a06b8d724f3 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +@@ -38,8 +38,6 @@ + #include + #include + #include +-#include +-#include + #include + #include + #include +@@ -500,12 +498,6 @@ static const struct drm_framebuffer_funcs amdgpu_fb_funcs = { + .create_handle = drm_gem_fb_create_handle, + }; + +-static const struct drm_framebuffer_funcs amdgpu_fb_funcs_atomic = { +- .destroy = drm_gem_fb_destroy, +- .create_handle = drm_gem_fb_create_handle, +- .dirty = drm_atomic_helper_dirtyfb, +-}; +- + uint32_t amdgpu_display_supported_domains(struct amdgpu_device *adev, + uint64_t bo_flags) + { +@@ -1108,10 +1100,8 @@ static int amdgpu_display_gem_fb_verify_and_init(struct drm_device *dev, + if (ret) + goto err; + +- if (drm_drv_uses_atomic_modeset(dev)) +- ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs_atomic); +- else +- ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs); ++ ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs); ++ + if (ret) + goto err; + +-- +2.35.3 + diff --git a/patches.suse/Revert-drm-bridge-analogix-dp-add-panel-prepare-unpr.patch b/patches.suse/Revert-drm-bridge-analogix-dp-add-panel-prepare-unpr.patch new file mode 100644 index 0000000..b89816d --- /dev/null +++ b/patches.suse/Revert-drm-bridge-analogix-dp-add-panel-prepare-unpr.patch @@ -0,0 +1,87 @@ +From cc62d98bd56d45de4531844ca23913a15136c05b Mon Sep 17 00:00:00 2001 +From: Brian Norris +Date: Mon, 22 Aug 2022 18:08:04 -0700 +Subject: [PATCH] Revert "drm: bridge: analogix/dp: add panel prepare/unprepare in suspend/resume time" +Git-commit: cc62d98bd56d45de4531844ca23913a15136c05b +Patch-mainline: v6.0 +References: git-fixes + +This reverts commit 211f276ed3d96e964d2d1106a198c7f4a4b3f4c0. + +For quite some time, core DRM helpers already ensure that any relevant +connectors/CRTCs/etc. are disabled, as well as their associated +components (e.g., bridges) when suspending the system. Thus, +analogix_dp_bridge_{enable,disable}() already get called, which in turn +call drm_panel_{prepare,unprepare}(). This makes these drm_panel_*() +calls redundant. + +Besides redundancy, there are a few problems with this handling: + +(1) drm_panel_{prepare,unprepare}() are *not* reference-counted APIs and +are not in general designed to be handled by multiple callers -- +although some panel drivers have a coarse 'prepared' flag that mitigates +some damage, at least. So at a minimum this is redundant and confusing, +but in some cases, this could be actively harmful. + +(2) The error-handling is a bit non-standard. We ignored errors in +suspend(), but handled errors in resume(). And recently, people noticed +that the clk handling is unbalanced in error paths, and getting *that* +right is not actually trivial, given the current way errors are mostly +ignored. + +(3) In the particular way analogix_dp_{suspend,resume}() get used (e.g., +in rockchip_dp_*(), as a late/early callback), we don't necessarily have +a proper PM relationship between the DP/bridge device and the panel +device. So while the DP bridge gets resumed, the panel's parent device +(e.g., platform_device) may still be suspended, and so any prepare() +calls may fail. + +So remove the superfluous, possibly-harmful suspend()/resume() handling +of panel state. + +Fixes: 211f276ed3d9 ("drm: bridge: analogix/dp: add panel prepare/unprepare in suspend/resume time") +Link: https://lore.kernel.org/all/Yv2CPBD3Picg%2FgVe@google.com/ +Signed-off-by: Brian Norris +Reviewed-by: Douglas Anderson +Signed-off-by: Douglas Anderson +Link: https://patchwork.freedesktop.org/patch/msgid/20220822180729.1.I8ac5abe3a4c1c6fd5c061686c6e883c22f69022c@changeid +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 13 ------------- + 1 file changed, 13 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +index 8aadcc0aa90b..df9370e0ff23 100644 +--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c ++++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +@@ -1864,12 +1864,6 @@ EXPORT_SYMBOL_GPL(analogix_dp_remove); + int analogix_dp_suspend(struct analogix_dp_device *dp) + { + clk_disable_unprepare(dp->clock); +- +- if (dp->plat_data->panel) { +- if (drm_panel_unprepare(dp->plat_data->panel)) +- DRM_ERROR("failed to turnoff the panel\n"); +- } +- + return 0; + } + EXPORT_SYMBOL_GPL(analogix_dp_suspend); +@@ -1884,13 +1878,6 @@ int analogix_dp_resume(struct analogix_dp_device *dp) + return ret; + } + +- if (dp->plat_data->panel) { +- if (drm_panel_prepare(dp->plat_data->panel)) { +- DRM_ERROR("failed to setup the panel\n"); +- return -EBUSY; +- } +- } +- + return 0; + } + EXPORT_SYMBOL_GPL(analogix_dp_resume); +-- +2.35.3 + diff --git a/patches.suse/Revert-drm-udl-Kill-pending-URBs-at-suspend-and-disc.patch b/patches.suse/Revert-drm-udl-Kill-pending-URBs-at-suspend-and-disc.patch index 442a7b3..ec1395f 100644 --- a/patches.suse/Revert-drm-udl-Kill-pending-URBs-at-suspend-and-disc.patch +++ b/patches.suse/Revert-drm-udl-Kill-pending-URBs-at-suspend-and-disc.patch @@ -3,8 +3,7 @@ From: Takashi Iwai Date: Thu, 8 Sep 2022 11:51:07 +0200 Subject: [PATCH] Revert "drm/udl: Kill pending URBs at suspend and disconnect" Git-commit: ed9605a66b62f27513aba1d95f7d470c4abda29f -Git-repo: git://anongit.freedesktop.org/drm/drm-misc -Patch-mainline: Queued in subsystem maintainer repo +Patch-mainline: v6.1-rc1 References: bsc#1195917 This reverts the recent fix commit diff --git a/patches.suse/Revert-firmware-arm_scmi-Add-clock-management-to-the.patch b/patches.suse/Revert-firmware-arm_scmi-Add-clock-management-to-the.patch new file mode 100644 index 0000000..5926a64 --- /dev/null +++ b/patches.suse/Revert-firmware-arm_scmi-Add-clock-management-to-the.patch @@ -0,0 +1,93 @@ +From 3c6656337852e9f1a4079d172f3fddfbf00868f9 Mon Sep 17 00:00:00 2001 +From: Ulf Hansson +Date: Mon, 19 Sep 2022 14:20:33 +0200 +Subject: [PATCH] Revert "firmware: arm_scmi: Add clock management to the SCMI power domain" +Git-commit: 3c6656337852e9f1a4079d172f3fddfbf00868f9 +Patch-mainline: v6.0 +References: git-fixes + +This reverts commit a3b884cef873 ("firmware: arm_scmi: Add clock management +to the SCMI power domain"). + +Using the GENPD_FLAG_PM_CLK tells genpd to gate/ungate the consumer +device's clock(s) during runtime suspend/resume through the PM clock API. +More precisely, in genpd_runtime_resume() the clock(s) for the consumer +device would become ungated prior to the driver-level ->runtime_resume() +callbacks gets invoked. + +This behaviour isn't a good fit for all platforms/drivers. For example, a +driver may need to make some preparations of its device in its +->runtime_resume() callback, like calling clk_set_rate() before the +clock(s) should be ungated. In these cases, it's easier to let the clock(s) +to be managed solely by the driver, rather than at the PM domain level. + +For these reasons, let's drop the use GENPD_FLAG_PM_CLK for the SCMI PM +domain, as to enable it to be more easily adopted across ARM platforms. + +Fixes: a3b884cef873 ("firmware: arm_scmi: Add clock management to the SCMI power domain") +Cc: Nicolas Pitre +Cc: stable@vger.kernel.org +Signed-off-by: Ulf Hansson +Tested-by: Peng Fan +Acked-by: Sudeep Holla +Link: https://lore.kernel.org/r/20220919122033.86126-1-ulf.hansson@linaro.org +Acked-by: Takashi Iwai + +--- + drivers/firmware/arm_scmi/scmi_pm_domain.c | 26 ---------------------- + 1 file changed, 26 deletions(-) + +diff --git a/drivers/firmware/arm_scmi/scmi_pm_domain.c b/drivers/firmware/arm_scmi/scmi_pm_domain.c +index 581d34c95769..d5dee625de78 100644 +--- a/drivers/firmware/arm_scmi/scmi_pm_domain.c ++++ b/drivers/firmware/arm_scmi/scmi_pm_domain.c +@@ -8,7 +8,6 @@ + #include + #include + #include +-#include + #include + #include + +@@ -53,27 +52,6 @@ static int scmi_pd_power_off(struct generic_pm_domain *domain) + return scmi_pd_power(domain, false); + } + +-static int scmi_pd_attach_dev(struct generic_pm_domain *pd, struct device *dev) +-{ +- int ret; +- +- ret = pm_clk_create(dev); +- if (ret) +- return ret; +- +- ret = of_pm_clk_add_clks(dev); +- if (ret >= 0) +- return 0; +- +- pm_clk_destroy(dev); +- return ret; +-} +- +-static void scmi_pd_detach_dev(struct generic_pm_domain *pd, struct device *dev) +-{ +- pm_clk_destroy(dev); +-} +- + static int scmi_pm_domain_probe(struct scmi_device *sdev) + { + int num_domains, i; +@@ -124,10 +102,6 @@ static int scmi_pm_domain_probe(struct scmi_device *sdev) + scmi_pd->genpd.name = scmi_pd->name; + scmi_pd->genpd.power_off = scmi_pd_power_off; + scmi_pd->genpd.power_on = scmi_pd_power_on; +- scmi_pd->genpd.attach_dev = scmi_pd_attach_dev; +- scmi_pd->genpd.detach_dev = scmi_pd_detach_dev; +- scmi_pd->genpd.flags = GENPD_FLAG_PM_CLK | +- GENPD_FLAG_ACTIVE_WAKEUP; + + pm_genpd_init(&scmi_pd->genpd, NULL, + state == SCMI_POWER_STATE_GENERIC_OFF); +-- +2.35.3 + diff --git a/patches.suse/Revert-pNFS-nfs3_set_ds_client-should-set-NFS_CS_NOP.patch b/patches.suse/Revert-pNFS-nfs3_set_ds_client-should-set-NFS_CS_NOP.patch new file mode 100644 index 0000000..ae66213 --- /dev/null +++ b/patches.suse/Revert-pNFS-nfs3_set_ds_client-should-set-NFS_CS_NOP.patch @@ -0,0 +1,30 @@ +From: Trond Myklebust +Date: Wed, 18 May 2022 16:37:56 -0400 +Subject: [PATCH] Revert "pNFS: nfs3_set_ds_client should set NFS_CS_NOPING" +Git-commit: 9597152d98840c2517230740952df97cfcc07e2f +Patch-mainline: v6.0 +References: git-fixes + +This reverts commit c6eb58435b98bd843d3179664a0195ff25adb2c3. +If a transport is down, then we want to fail over to other transports if +they are listed in the GETDEVICEINFO reply. + +Fixes: c6eb58435b98 ("pNFS: nfs3_set_ds_client should set NFS_CS_NOPING") +Cc: stable@vger.kernel.org # 5.11.x +Signed-off-by: Trond Myklebust +Acked-by: NeilBrown + +--- + fs/nfs/nfs3client.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/fs/nfs/nfs3client.c ++++ b/fs/nfs/nfs3client.c +@@ -108,7 +108,6 @@ struct nfs_client *nfs3_set_ds_client(st + if (mds_srv->flags & NFS_MOUNT_NORESVPORT) + __set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags); + +- __set_bit(NFS_CS_NOPING, &cl_init.init_flags); + __set_bit(NFS_CS_DS, &cl_init.init_flags); + + /* Use the MDS nfs_client cl_ipaddr. */ diff --git a/patches.suse/Revert-powerpc-rtas-Implement-reentrant-rtas-call.patch b/patches.suse/Revert-powerpc-rtas-Implement-reentrant-rtas-call.patch new file mode 100644 index 0000000..b084c3d --- /dev/null +++ b/patches.suse/Revert-powerpc-rtas-Implement-reentrant-rtas-call.patch @@ -0,0 +1,289 @@ +From f88aabad33ea22be2ce1c60d8901942e4e2a9edb Mon Sep 17 00:00:00 2001 +From: Nathan Lynch +Date: Wed, 7 Sep 2022 17:01:11 -0500 +Subject: [PATCH] Revert "powerpc/rtas: Implement reentrant rtas call" + +References: bsc#1203664 ltc#199236 +Patch-mainline: v6.1-rc1 +Git-commit: f88aabad33ea22be2ce1c60d8901942e4e2a9edb + +At the time this was submitted by Leonardo, I confirmed -- or thought +I had confirmed -- with PowerVM partition firmware development that +the following RTAS functions: + +- ibm,get-xive +- ibm,int-off +- ibm,int-on +- ibm,set-xive + +were safe to call on multiple CPUs simultaneously, not only with +respect to themselves as indicated by PAPR, but with arbitrary other +RTAS calls: + +https://lore.kernel.org/linuxppc-dev/875zcy2v8o.fsf@linux.ibm.com/ + +Recent discussion with firmware development makes it clear that this +is not true, and that the code in commit b664db8e3f97 ("powerpc/rtas: +Implement reentrant rtas call") is unsafe, likely explaining several +strange bugs we've seen in internal testing involving DLPAR and +LPM. These scenarios use ibm,configure-connector, whose internal state +can be corrupted by the concurrent use of the "reentrant" functions, +leading to symptoms like endless busy statuses from RTAS. + +Fixes: b664db8e3f97 ("powerpc/rtas: Implement reentrant rtas call") +Cc: stable@vger.kernel.org # v5.8+ +Signed-off-by: Nathan Lynch +Reviewed-by: Laurent Dufour +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/20220907220111.223267-1-nathanl@linux.ibm.com +Acked-by: Michal Suchanek +--- + arch/powerpc/include/asm/paca.h | 1 - + arch/powerpc/include/asm/rtas.h | 1 - + arch/powerpc/kernel/paca.c | 32 ----------------- + arch/powerpc/kernel/rtas.c | 54 ----------------------------- + arch/powerpc/sysdev/xics/ics-rtas.c | 22 ++++++------ + 5 files changed, 11 insertions(+), 99 deletions(-) + +diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h +index 4d7aaab82702..3537b0500f4d 100644 +--- a/arch/powerpc/include/asm/paca.h ++++ b/arch/powerpc/include/asm/paca.h +@@ -263,7 +263,6 @@ struct paca_struct { + u64 l1d_flush_size; + #endif + #ifdef CONFIG_PPC_PSERIES +- struct rtas_args *rtas_args_reentrant; + u8 *mce_data_buf; /* buffer to hold per cpu rtas errlog */ + #endif /* CONFIG_PPC_PSERIES */ + +diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h +index 00531af17ce0..56319aea646e 100644 +--- a/arch/powerpc/include/asm/rtas.h ++++ b/arch/powerpc/include/asm/rtas.h +@@ -240,7 +240,6 @@ extern struct rtas_t rtas; + extern int rtas_token(const char *service); + extern int rtas_service_present(const char *service); + extern int rtas_call(int token, int, int, int *, ...); +-int rtas_call_reentrant(int token, int nargs, int nret, int *outputs, ...); + void rtas_call_unlocked(struct rtas_args *args, int token, int nargs, + int nret, ...); + extern void __noreturn rtas_restart(char *cmd); +diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c +--- a/arch/powerpc/kernel/paca.c ++++ b/arch/powerpc/kernel/paca.c +@@ -16,7 +16,6 @@ + #include + #include + #include +-#include + + #include "setup.h" + +@@ -172,30 +171,6 @@ static struct slb_shadow * __init new_sl + + #endif /* CONFIG_PPC_BOOK3S_64 */ + +-#ifdef CONFIG_PPC_PSERIES +-/** +- * new_rtas_args() - Allocates rtas args +- * @cpu: CPU number +- * @limit: Memory limit for this allocation +- * +- * Allocates a struct rtas_args and return it's pointer, +- * if not in Hypervisor mode +- * +- * Return: Pointer to allocated rtas_args +- * NULL if CPU in Hypervisor Mode +- */ +-static struct rtas_args * __init new_rtas_args(int cpu, unsigned long limit) +-{ +- limit = min_t(unsigned long, limit, RTAS_INSTANTIATE_MAX); +- +- if (early_cpu_has_feature(CPU_FTR_HVMODE)) +- return NULL; +- +- return alloc_paca_data(sizeof(struct rtas_args), L1_CACHE_BYTES, +- limit, cpu); +-} +-#endif /* CONFIG_PPC_PSERIES */ +- + /* The Paca is an array with one entry per processor. Each contains an + * lppaca, which contains the information shared between the + * hypervisor and Linux. +@@ -234,10 +209,6 @@ void __init initialise_paca(struct paca_ + /* For now -- if we have threads this will be adjusted later */ + new_paca->tcd_ptr = &new_paca->tcd; + #endif +- +-#ifdef CONFIG_PPC_PSERIES +- new_paca->rtas_args_reentrant = NULL; +-#endif + } + + /* Put the paca pointer into r13 and SPRG_PACA */ +@@ -310,9 +281,6 @@ void __init allocate_paca(int cpu) + #ifdef CONFIG_PPC_BOOK3S_64 + paca->slb_shadow_ptr = new_slb_shadow(cpu, limit); + #endif +-#ifdef CONFIG_PPC_PSERIES +- paca->rtas_args_reentrant = new_rtas_args(cpu, limit); +-#endif + paca_struct_size += sizeof(struct paca_struct); + } + +diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c +--- a/arch/powerpc/kernel/rtas.c ++++ b/arch/powerpc/kernel/rtas.c +@@ -43,7 +43,6 @@ + #include + #include + #include +-#include + + /* This is here deliberately so it's only used in this file */ + void enter_rtas(unsigned long); +@@ -932,59 +931,6 @@ void rtas_activate_firmware(void) + pr_err("ibm,activate-firmware failed (%i)\n", fwrc); + } + +-#ifdef CONFIG_PPC_PSERIES +-/** +- * rtas_call_reentrant() - Used for reentrant rtas calls +- * @token: Token for desired reentrant RTAS call +- * @nargs: Number of Input Parameters +- * @nret: Number of Output Parameters +- * @outputs: Array of outputs +- * @...: Inputs for desired RTAS call +- * +- * According to LoPAR documentation, only "ibm,int-on", "ibm,int-off", +- * "ibm,get-xive" and "ibm,set-xive" are currently reentrant. +- * Reentrant calls need their own rtas_args buffer, so not using rtas.args, but +- * PACA one instead. +- * +- * Return: -1 on error, +- * First output value of RTAS call if (nret > 0), +- * 0 otherwise, +- */ +-int rtas_call_reentrant(int token, int nargs, int nret, int *outputs, ...) +-{ +- va_list list; +- struct rtas_args *args; +- unsigned long flags; +- int i, ret = 0; +- +- if (!rtas.entry || token == RTAS_UNKNOWN_SERVICE) +- return -1; +- +- local_irq_save(flags); +- preempt_disable(); +- +- /* We use the per-cpu (PACA) rtas args buffer */ +- args = local_paca->rtas_args_reentrant; +- +- va_start(list, outputs); +- va_rtas_call_unlocked(args, token, nargs, nret, list); +- va_end(list); +- +- if (nret > 1 && outputs) +- for (i = 0; i < nret - 1; ++i) +- outputs[i] = be32_to_cpu(args->rets[i + 1]); +- +- if (nret > 0) +- ret = be32_to_cpu(args->rets[0]); +- +- local_irq_restore(flags); +- preempt_enable(); +- +- return ret; +-} +- +-#endif /* CONFIG_PPC_PSERIES */ +- + /** + * Find a specific pseries error log in an RTAS extended event log. + * @log: RTAS error/event log +diff --git a/arch/powerpc/sysdev/xics/ics-rtas.c b/arch/powerpc/sysdev/xics/ics-rtas.c +--- a/arch/powerpc/sysdev/xics/ics-rtas.c ++++ b/arch/powerpc/sysdev/xics/ics-rtas.c +@@ -36,8 +36,8 @@ static void ics_rtas_unmask_irq(struct irq_data *d) + + server = xics_get_irq_server(d->irq, irq_data_get_affinity_mask(d), 0); + +- call_status = rtas_call_reentrant(ibm_set_xive, 3, 1, NULL, hw_irq, +- server, DEFAULT_PRIORITY); ++ call_status = rtas_call(ibm_set_xive, 3, 1, NULL, hw_irq, server, ++ DEFAULT_PRIORITY); + if (call_status != 0) { + printk(KERN_ERR + "%s: ibm_set_xive irq %u server %x returned %d\n", +@@ -46,7 +46,7 @@ static void ics_rtas_unmask_irq(struct irq_data *d) + } + + /* Now unmask the interrupt (often a no-op) */ +- call_status = rtas_call_reentrant(ibm_int_on, 1, 1, NULL, hw_irq); ++ call_status = rtas_call(ibm_int_on, 1, 1, NULL, hw_irq); + if (call_status != 0) { + printk(KERN_ERR "%s: ibm_int_on irq=%u returned %d\n", + __func__, hw_irq, call_status); +@@ -68,7 +68,7 @@ static void ics_rtas_mask_real_irq(unsigned int hw_irq) + if (hw_irq == XICS_IPI) + return; + +- call_status = rtas_call_reentrant(ibm_int_off, 1, 1, NULL, hw_irq); ++ call_status = rtas_call(ibm_int_off, 1, 1, NULL, hw_irq); + if (call_status != 0) { + printk(KERN_ERR "%s: ibm_int_off irq=%u returned %d\n", + __func__, hw_irq, call_status); +@@ -76,8 +76,8 @@ static void ics_rtas_mask_real_irq(unsigned int hw_irq) + } + + /* Have to set XIVE to 0xff to be able to remove a slot */ +- call_status = rtas_call_reentrant(ibm_set_xive, 3, 1, NULL, hw_irq, +- xics_default_server, 0xff); ++ call_status = rtas_call(ibm_set_xive, 3, 1, NULL, hw_irq, ++ xics_default_server, 0xff); + if (call_status != 0) { + printk(KERN_ERR "%s: ibm_set_xive(0xff) irq=%u returned %d\n", + __func__, hw_irq, call_status); +@@ -108,7 +108,7 @@ static int ics_rtas_set_affinity(struct irq_data *d, + if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS) + return -1; + +- status = rtas_call_reentrant(ibm_get_xive, 1, 3, xics_status, hw_irq); ++ status = rtas_call(ibm_get_xive, 1, 3, xics_status, hw_irq); + + if (status) { + printk(KERN_ERR "%s: ibm,get-xive irq=%u returns %d\n", +@@ -146,8 +146,8 @@ static int ics_rtas_set_affinity(struct + return -1; + } + +- status = rtas_call_reentrant(ibm_set_xive, 3, 1, NULL, +- hw_irq, irq_server, xics_status[1]); ++ status = rtas_call(ibm_set_xive, 3, 1, NULL, ++ hw_irq, irq_server, xics_status[1]); + + if (status) { + printk(KERN_ERR "%s: ibm,set-xive irq=%u returns %d\n", +@@ -158,7 +158,7 @@ static int ics_rtas_check(struct ics *ics, unsigned int hw_irq) + return -EINVAL; + + /* Check if RTAS knows about this interrupt */ +- rc = rtas_call_reentrant(ibm_get_xive, 1, 3, status, hw_irq); ++ rc = rtas_call(ibm_get_xive, 1, 3, status, hw_irq); + if (rc) + return -ENXIO; + +@@ -174,7 +174,7 @@ static long ics_rtas_get_server(struct ics *ics, unsigned long vec) + { + int rc, status[2]; + +- rc = rtas_call_reentrant(ibm_get_xive, 1, 3, status, vec); ++ rc = rtas_call(ibm_get_xive, 1, 3, status, vec); + if (rc) + return -1; + return status[0]; +-- +2.35.3 + diff --git a/patches.suse/Revert-usb-add-quirks-for-Lenovo-OneLink-Dock.patch b/patches.suse/Revert-usb-add-quirks-for-Lenovo-OneLink-Dock.patch new file mode 100644 index 0000000..4a2da49 --- /dev/null +++ b/patches.suse/Revert-usb-add-quirks-for-Lenovo-OneLink-Dock.patch @@ -0,0 +1,43 @@ +From 58bfe7d8e31014d7ce246788df99c56e3cfe6c68 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Wed, 31 Aug 2022 10:34:25 +0200 +Subject: [PATCH] Revert "usb: add quirks for Lenovo OneLink+ Dock" +Git-commit: 58bfe7d8e31014d7ce246788df99c56e3cfe6c68 +Patch-mainline: v6.0-rc4 +References: git-fixes + +This reverts commit 3d5f70949f1b1168fbb17d06eb5c57e984c56c58. + +The quirk does not work properly, more work is needed to determine what +should be done here. + +Reported-by: Oliver Neukum +Cc: Jean-Francois Le Fillatre +Cc: stable +Fixes: 3d5f70949f1b ("usb: add quirks for Lenovo OneLink+ Dock") +Link: https://lore.kernel.org/r/9a17ea86-079f-510d-e919-01bc53a6d09f@gmx.com +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/usb/core/quirks.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c +index 999b7c9697fc..f99a65a64588 100644 +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -437,10 +437,6 @@ static const struct usb_device_id usb_quirk_list[] = { + { USB_DEVICE(0x1532, 0x0116), .driver_info = + USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL }, + +- /* Lenovo ThinkPad OneLink+ Dock twin hub controllers (VIA Labs VL812) */ +- { USB_DEVICE(0x17ef, 0x1018), .driver_info = USB_QUIRK_RESET_RESUME }, +- { USB_DEVICE(0x17ef, 0x1019), .driver_info = USB_QUIRK_RESET_RESUME }, +- + /* Lenovo USB-C to Ethernet Adapter RTL8153-04 */ + { USB_DEVICE(0x17ef, 0x720c), .driver_info = USB_QUIRK_NO_LPM }, + +-- +2.35.3 + diff --git a/patches.suse/Revert-usb-storage-Add-quirk-for-Samsung-Fit-flash.patch b/patches.suse/Revert-usb-storage-Add-quirk-for-Samsung-Fit-flash.patch new file mode 100644 index 0000000..4806885 --- /dev/null +++ b/patches.suse/Revert-usb-storage-Add-quirk-for-Samsung-Fit-flash.patch @@ -0,0 +1,59 @@ +From ad5dbfc123e6ffbbde194e2a4603323e09f741ee Mon Sep 17 00:00:00 2001 +From: sunghwan jung +Date: Tue, 13 Sep 2022 20:49:13 +0900 +Subject: [PATCH] Revert "usb: storage: Add quirk for Samsung Fit flash" +Git-commit: ad5dbfc123e6ffbbde194e2a4603323e09f741ee +Patch-mainline: v6.1-rc1 +References: git-fixes + +This reverts commit 86d92f5465958752481269348d474414dccb1552, +which fix the timeout issue for "Samsung Fit Flash". + +But the commit affects not only "Samsung Fit Flash" but also other usb +storages that use the same controller and causes severe performance +regression. + + # hdparm -t /dev/sda (without the quirk) + Timing buffered disk reads: 622 MB in 3.01 seconds = 206.66 MB/sec + + # hdparm -t /dev/sda (with the quirk) + Timing buffered disk reads: 220 MB in 3.00 seconds = 73.32 MB/sec + +The commit author mentioned that "Issue was reproduced after device has +bad block", so this quirk should be applied when we have the timeout +issue with a device that has bad blocks. + +We revert the commit so that we apply this quirk by adding kernel +paramters using a bootloader or other ways when we really need it, +without the performance regression with devices that don't have the +issue. + +Signed-off-by: sunghwan jung +Link: https://lore.kernel.org/r/20220913114913.3073-1-onenowy@gmail.com +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/usb/storage/unusual_devs.h | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h +index 4993227ab293..20dcbccb290b 100644 +--- a/drivers/usb/storage/unusual_devs.h ++++ b/drivers/usb/storage/unusual_devs.h +@@ -1275,12 +1275,6 @@ UNUSUAL_DEV( 0x090a, 0x1200, 0x0000, 0x9999, + USB_SC_RBC, USB_PR_BULK, NULL, + 0 ), + +-UNUSUAL_DEV(0x090c, 0x1000, 0x1100, 0x1100, +- "Samsung", +- "Flash Drive FIT", +- USB_SC_DEVICE, USB_PR_DEVICE, NULL, +- US_FL_MAX_SECTORS_64), +- + /* aeb */ + UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff, + "Feiya", +-- +2.35.3 + diff --git a/patches.suse/SUNRPC-Don-t-call-connect-more-than-once-on-a-TCP-so.patch b/patches.suse/SUNRPC-Don-t-call-connect-more-than-once-on-a-TCP-so.patch new file mode 100644 index 0000000..6ce92df --- /dev/null +++ b/patches.suse/SUNRPC-Don-t-call-connect-more-than-once-on-a-TCP-so.patch @@ -0,0 +1,77 @@ +From: Trond Myklebust +Date: Wed, 16 Mar 2022 19:10:43 -0400 +Subject: [PATCH] SUNRPC: Don't call connect() more than once on a TCP socket +Git-commit: 89f42494f92f448747bd8a7ab1ae8b5d5520577d +Patch-mainline: v5.18 +References: git-fixes + +Avoid socket state races due to repeated calls to ->connect() using the +same socket. If connect() returns 0 due to the connection having +completed, but we are in fact in a closing state, then we may leave the +XPRT_CONNECTING flag set on the transport. + +Reported-by: Enrico Scholz +Fixes: 3be232f11a3c ("SUNRPC: Prevent immediate close+reconnect") +Signed-off-by: Trond Myklebust +Acked-by: NeilBrown + +--- + include/linux/sunrpc/xprtsock.h | 1 + + net/sunrpc/xprtsock.c | 22 ++++++++++++---------- + 2 files changed, 13 insertions(+), 10 deletions(-) + +--- a/include/linux/sunrpc/xprtsock.h ++++ b/include/linux/sunrpc/xprtsock.h +@@ -88,5 +88,6 @@ struct sock_xprt { + #define XPRT_SOCK_WAKE_WRITE (5) + #define XPRT_SOCK_WAKE_PENDING (6) + #define XPRT_SOCK_WAKE_DISCONNECT (7) ++#define XPRT_SOCK_CONNECT_SENT (8) + + #endif /* _LINUX_SUNRPC_XPRTSOCK_H */ +--- a/net/sunrpc/xprtsock.c ++++ b/net/sunrpc/xprtsock.c +@@ -2269,6 +2269,7 @@ static int xs_tcp_finish_connecting(stru + fallthrough; + case -EINPROGRESS: + /* SYN_SENT! */ ++ set_bit(XPRT_SOCK_CONNECT_SENT, &transport->sock_state); + if (xprt->reestablish_timeout < XS_TCP_INIT_REEST_TO) + xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; + break; +@@ -2297,10 +2298,15 @@ static void xs_tcp_setup_socket(struct w + + if (atomic_read(&xprt->swapper)) + current->flags |= PF_MEMALLOC; +- if (!sock) { +- sock = xs_create_sock(xprt, transport, +- xs_addr(xprt)->sa_family, SOCK_STREAM, +- IPPROTO_TCP, true); ++ ++ if (xprt_connected(xprt)) ++ goto out; ++ if (test_and_clear_bit(XPRT_SOCK_CONNECT_SENT, ++ &transport->sock_state) || ++ !sock) { ++ xs_reset_transport(transport); ++ sock = xs_create_sock(xprt, transport, xs_addr(xprt)->sa_family, ++ SOCK_STREAM, IPPROTO_TCP, true); + if (IS_ERR(sock)) { + status = PTR_ERR(sock); + goto out; +@@ -2382,13 +2388,9 @@ static void xs_connect(struct rpc_xprt * + + WARN_ON_ONCE(!xprt_lock_connect(xprt, task, transport)); + +- if (transport->sock != NULL && !xprt_connecting(xprt)) { ++ if (transport->sock != NULL) { + dprintk("RPC: xs_connect delayed xprt %p for %lu " +- "seconds\n", +- xprt, xprt->reestablish_timeout / HZ); +- +- /* Start by resetting any existing state */ +- xs_reset_transport(transport); ++ "seconds\n", xprt, xprt->reestablish_timeout / HZ); + + delay = xprt_reconnect_delay(xprt); + xprt_reconnect_backoff(xprt, XS_TCP_INIT_REEST_TO); diff --git a/patches.suse/SUNRPC-Don-t-leak-sockets-in-xs_local_connect.patch b/patches.suse/SUNRPC-Don-t-leak-sockets-in-xs_local_connect.patch new file mode 100644 index 0000000..ebebf15 --- /dev/null +++ b/patches.suse/SUNRPC-Don-t-leak-sockets-in-xs_local_connect.patch @@ -0,0 +1,52 @@ +From: Trond Myklebust +Date: Thu, 28 Apr 2022 11:08:13 -0400 +Subject: [PATCH] SUNRPC: Don't leak sockets in xs_local_connect() +Git-commit: aad41a7d7cf6c6fa804c872a2480f8e541da37cf +Patch-mainline: v5.18 +References: git-fixes + +If there is still a closed socket associated with the transport, then we +need to trigger an autoclose before we can set up a new connection. + +Reported-by: wanghai (M) +Fixes: f00432063db1 ("SUNRPC: Ensure we flush any closed sockets before xs_xprt_free()") +Signed-off-by: Trond Myklebust +Acked-by: NeilBrown + +--- + net/sunrpc/xprtsock.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +--- a/net/sunrpc/xprtsock.c ++++ b/net/sunrpc/xprtsock.c +@@ -1964,7 +1964,10 @@ static void xs_local_connect(struct rpc_ + struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); + int ret; + +- if (RPC_IS_ASYNC(task)) { ++ if (transport->file) ++ goto force_disconnect; ++ ++ if (RPC_IS_ASYNC(task)) { + /* + * We want the AF_LOCAL connect to be resolved in the + * filesystem namespace of the process making the rpc +@@ -1976,11 +1979,17 @@ static void xs_local_connect(struct rpc_ + */ + task->tk_rpc_status = -ENOTCONN; + rpc_exit(task, -ENOTCONN); +- return; ++ goto out_wake; + } + ret = xs_local_setup_socket(transport); + if (ret && !RPC_IS_SOFTCONN(task)) + msleep_interruptible(15000); ++ return; ++force_disconnect: ++ xprt_force_disconnect(xprt); ++out_wake: ++ xprt_clear_connecting(xprt); ++ xprt_wake_pending_tasks(xprt, -ENOTCONN); + } + + #if IS_ENABLED(CONFIG_SUNRPC_SWAP) diff --git a/patches.suse/SUNRPC-Fix-xdr_encode_bool.patch b/patches.suse/SUNRPC-Fix-xdr_encode_bool.patch new file mode 100644 index 0000000..d369e22 --- /dev/null +++ b/patches.suse/SUNRPC-Fix-xdr_encode_bool.patch @@ -0,0 +1,37 @@ +From: Chuck Lever +Date: Tue, 19 Jul 2022 09:18:35 -0400 +Subject: [PATCH] SUNRPC: Fix xdr_encode_bool() +Git-commit: c770f31d8f580ed4b965c64f924ec1cc50e41734 +Patch-mainline: v6.0 +References: git-fixes + +I discovered that xdr_encode_bool() was returning the same address +that was passed in the @p parameter. The documenting comment states +that the intent is to return the address of the next buffer +location, just like the other "xdr_encode_*" helpers. + +The result was the encoded results of NFSv3 PATHCONF operations were +not formed correctly. + +Fixes: ded04a587f6c ("NFSD: Update the NFSv3 PATHCONF3res encoder to use struct xdr_stream") +Signed-off-by: Chuck Lever +Reviewed-by: Jeff Layton +Acked-by: NeilBrown + +--- + include/linux/sunrpc/xdr.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/include/linux/sunrpc/xdr.h ++++ b/include/linux/sunrpc/xdr.h +@@ -404,8 +404,8 @@ static inline int xdr_stream_encode_item + */ + static inline __be32 *xdr_encode_bool(__be32 *p, u32 n) + { +- *p = n ? xdr_one : xdr_zero; +- return p++; ++ *p++ = n ? xdr_one : xdr_zero; ++ return p; + } + + /** diff --git a/patches.suse/SUNRPC-RPC-level-errors-should-set-task-tk_rpc_statu.patch b/patches.suse/SUNRPC-RPC-level-errors-should-set-task-tk_rpc_statu.patch new file mode 100644 index 0000000..45cbec1 --- /dev/null +++ b/patches.suse/SUNRPC-RPC-level-errors-should-set-task-tk_rpc_statu.patch @@ -0,0 +1,29 @@ +From: Trond Myklebust +Date: Wed, 3 Aug 2022 14:55:03 -0400 +Subject: [PATCH] SUNRPC: RPC level errors should set task->tk_rpc_status +Git-commit: ed06fce0b034b2e25bd93430f5c4cbb28036cc1a +Patch-mainline: v6.0 +References: git-fixes + +Fix up a case in call_encode() where we're failing to set +task->tk_rpc_status when an RPC level error occurred. + +Fixes: 9c5948c24869 ("SUNRPC: task should be exit if encode return EKEYEXPIRED more times") +Signed-off-by: Trond Myklebust +Acked-by: NeilBrown + +--- + net/sunrpc/clnt.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/sunrpc/clnt.c ++++ b/net/sunrpc/clnt.c +@@ -1883,7 +1883,7 @@ call_encode(struct rpc_task *task) + break; + case -EKEYEXPIRED: + if (!task->tk_cred_retry) { +- rpc_exit(task, task->tk_status); ++ rpc_call_rpcerror(task, task->tk_status); + } else { + task->tk_action = call_refresh; + task->tk_cred_retry--; diff --git a/patches.suse/SUNRPC-Reinitialise-the-backchannel-request-buffers-.patch b/patches.suse/SUNRPC-Reinitialise-the-backchannel-request-buffers-.patch new file mode 100644 index 0000000..9d6862f --- /dev/null +++ b/patches.suse/SUNRPC-Reinitialise-the-backchannel-request-buffers-.patch @@ -0,0 +1,50 @@ +From: Trond Myklebust +Date: Wed, 27 Jul 2022 12:27:54 -0400 +Subject: [PATCH] SUNRPC: Reinitialise the backchannel request buffers before + reuse +Git-commit: 6622e3a73112fc336c1c2c582428fb5ef18e456a +Patch-mainline: v6.0 +References: git-fixes + +When we're reusing the backchannel requests instead of freeing them, +then we should reinitialise any values of the send/receive xdr_bufs so +that they reflect the available space. + +Fixes: 0d2a970d0ae5 ("SUNRPC: Fix a backchannel race") +Signed-off-by: Trond Myklebust +Acked-by: NeilBrown + +--- + net/sunrpc/backchannel_rqst.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +--- a/net/sunrpc/backchannel_rqst.c ++++ b/net/sunrpc/backchannel_rqst.c +@@ -65,6 +65,17 @@ static void xprt_free_allocation(struct + kfree(req); + } + ++static void xprt_bc_reinit_xdr_buf(struct xdr_buf *buf) ++{ ++ buf->head[0].iov_len = PAGE_SIZE; ++ buf->tail[0].iov_len = 0; ++ buf->pages = NULL; ++ buf->page_len = 0; ++ buf->flags = 0; ++ buf->len = 0; ++ buf->buflen = PAGE_SIZE; ++} ++ + static int xprt_alloc_xdr_buf(struct xdr_buf *buf, gfp_t gfp_flags) + { + struct page *page; +@@ -293,6 +304,9 @@ void xprt_free_bc_rqst(struct rpc_rqst * + */ + spin_lock_bh(&xprt->bc_pa_lock); + if (xprt_need_to_requeue(xprt)) { ++ xprt_bc_reinit_xdr_buf(&req->rq_snd_buf); ++ xprt_bc_reinit_xdr_buf(&req->rq_rcv_buf); ++ req->rq_rcv_buf.len = PAGE_SIZE; + list_add_tail(&req->rq_bc_pa_list, &xprt->bc_pa_list); + xprt->bc_alloc_count++; + atomic_inc(&xprt->bc_slot_count); diff --git a/patches.suse/USB-Fix-ehci-infinite-suspend-resume-loop-issue-in-z.patch b/patches.suse/USB-Fix-ehci-infinite-suspend-resume-loop-issue-in-z.patch new file mode 100644 index 0000000..060b31b --- /dev/null +++ b/patches.suse/USB-Fix-ehci-infinite-suspend-resume-loop-issue-in-z.patch @@ -0,0 +1,101 @@ +From f085bd4bfe0907ce2fad2c787fc65871ec5ca6d6 Mon Sep 17 00:00:00 2001 +From: Weitao Wango +Date: Thu, 24 Mar 2022 20:17:35 +0800 +Subject: [PATCH] USB: Fix ehci infinite suspend-resume loop issue in zhaoxin +Git-commit: f085bd4bfe0907ce2fad2c787fc65871ec5ca6d6 +References: git-fixes +Patch-mainline: v5.18-rc5 + +In zhaoxin platform, some ehci projects will latch a wakeup signal +internal when plug in a device on port during system S0. This wakeup +signal will turn on when ehci runtime suspend, which will trigger a +system control interrupt that will resume ehci back to D0. As no +device connect, ehci will be set to runtime suspend and turn on the +internal latched wakeup signal again. It will cause a suspend-resume +loop and generate system control interrupt continuously. + +Fixed this issue by clear wakeup signal latched in ehci internal when +ehci resume callback is called. + +Acked-by: Alan Stern +Signed-off-by: Weitao Wang +Link: https://lore.kernel.org/r/20220324121735.3803-1-WeitaoWang-oc@zhaoxin.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/usb/host/ehci-hcd.c | 23 +++++++++++++++++++++++ + drivers/usb/host/ehci-pci.c | 4 ++++ + drivers/usb/host/ehci.h | 1 + + 3 files changed, 28 insertions(+) + +diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c +index 3d82e0b853be..684164fa9716 100644 +--- a/drivers/usb/host/ehci-hcd.c ++++ b/drivers/usb/host/ehci-hcd.c +@@ -1103,6 +1103,26 @@ static void ehci_remove_device(struct usb_hcd *hcd, struct usb_device *udev) + + #ifdef CONFIG_PM + ++/* Clear wakeup signal locked in zhaoxin platform when device plug in. */ ++static void ehci_zx_wakeup_clear(struct ehci_hcd *ehci) ++{ ++ u32 __iomem *reg = &ehci->regs->port_status[4]; ++ u32 t1 = ehci_readl(ehci, reg); ++ ++ t1 &= (u32)~0xf0000; ++ t1 |= PORT_TEST_FORCE; ++ ehci_writel(ehci, t1, reg); ++ t1 = ehci_readl(ehci, reg); ++ msleep(1); ++ t1 &= (u32)~0xf0000; ++ ehci_writel(ehci, t1, reg); ++ ehci_readl(ehci, reg); ++ msleep(1); ++ t1 = ehci_readl(ehci, reg); ++ ehci_writel(ehci, t1 | PORT_CSC, reg); ++ ehci_readl(ehci, reg); ++} ++ + /* suspend/resume, section 4.3 */ + + /* These routines handle the generic parts of controller suspend/resume */ +@@ -1154,6 +1174,9 @@ int ehci_resume(struct usb_hcd *hcd, bool force_reset) + if (ehci->shutdown) + return 0; /* Controller is dead */ + ++ if (ehci->zx_wakeup_clear_needed) ++ ehci_zx_wakeup_clear(ehci); ++ + /* + * If CF is still set and reset isn't forced + * then we maintained suspend power. +diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c +index 638f03b89739..9937c5a7efc2 100644 +--- a/drivers/usb/host/ehci-pci.c ++++ b/drivers/usb/host/ehci-pci.c +@@ -231,6 +231,10 @@ static int ehci_pci_setup(struct usb_hcd *hcd) + ehci->is_aspeed = 1; + } + break; ++ case PCI_VENDOR_ID_ZHAOXIN: ++ if (pdev->device == 0x3104 && (pdev->revision & 0xf0) == 0x90) ++ ehci->zx_wakeup_clear_needed = 1; ++ break; + } + + /* optional debug port, normally in the first BAR */ +diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h +index fdd073cc053b..ad3f13a3eaf1 100644 +--- a/drivers/usb/host/ehci.h ++++ b/drivers/usb/host/ehci.h +@@ -220,6 +220,7 @@ struct ehci_hcd { /* one per controller */ + unsigned imx28_write_fix:1; /* For Freescale i.MX28 */ + unsigned spurious_oc:1; + unsigned is_aspeed:1; ++ unsigned zx_wakeup_clear_needed:1; + + /* required for usb32 quirk */ + #define OHCI_CTRL_HCFS (3 << 6) +-- +2.35.3 + diff --git a/patches.suse/USB-add-RESET_RESUME-quirk-for-NVIDIA-Jetson-devices.patch b/patches.suse/USB-add-RESET_RESUME-quirk-for-NVIDIA-Jetson-devices.patch new file mode 100644 index 0000000..cac77ae --- /dev/null +++ b/patches.suse/USB-add-RESET_RESUME-quirk-for-NVIDIA-Jetson-devices.patch @@ -0,0 +1,53 @@ +From fc4ade55c617dc73c7e9756b57f3230b4ff24540 Mon Sep 17 00:00:00 2001 +From: Hannu Hartikainen +Date: Mon, 19 Sep 2022 20:16:10 +0300 +Subject: [PATCH] USB: add RESET_RESUME quirk for NVIDIA Jetson devices in RCM +Git-commit: fc4ade55c617dc73c7e9756b57f3230b4ff24540 +References: git-fixes +Patch-mainline: v6.1-rc1 + +NVIDIA Jetson devices in Force Recovery mode (RCM) do not support +suspending, ie. flashing fails if the device has been suspended. The +devices are still visible in lsusb and seem to work otherwise, making +the issue hard to debug. This has been discovered in various forum +posts, eg. [1]. + +The patch has been tested on NVIDIA Jetson AGX Xavier, but I'm adding +all the Jetson models listed in [2] on the assumption that they all +behave similarly. + +[1]: https://forums.developer.nvidia.com/t/flashing-not-working/72365 +[2]: https://docs.nvidia.com/jetson/archives/l4t-archived/l4t-3271/index.html#page/Tegra%20Linux%20Driver%20Package%20Development%20Guide/quick_start.html + +Signed-off-by: Hannu Hartikainen +Cc: stable # after 6.1-rc3 +Link: https://lore.kernel.org/r/20220919171610.30484-1-hannu@hrtk.in +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/usb/core/quirks.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c +index f99a65a64588..11b27953ccd0 100644 +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -388,6 +388,15 @@ static const struct usb_device_id usb_quirk_list[] = { + /* Kingston DataTraveler 3.0 */ + { USB_DEVICE(0x0951, 0x1666), .driver_info = USB_QUIRK_NO_LPM }, + ++ /* NVIDIA Jetson devices in Force Recovery mode */ ++ { USB_DEVICE(0x0955, 0x7018), .driver_info = USB_QUIRK_RESET_RESUME }, ++ { USB_DEVICE(0x0955, 0x7019), .driver_info = USB_QUIRK_RESET_RESUME }, ++ { USB_DEVICE(0x0955, 0x7418), .driver_info = USB_QUIRK_RESET_RESUME }, ++ { USB_DEVICE(0x0955, 0x7721), .driver_info = USB_QUIRK_RESET_RESUME }, ++ { USB_DEVICE(0x0955, 0x7c18), .driver_info = USB_QUIRK_RESET_RESUME }, ++ { USB_DEVICE(0x0955, 0x7e19), .driver_info = USB_QUIRK_RESET_RESUME }, ++ { USB_DEVICE(0x0955, 0x7f21), .driver_info = USB_QUIRK_RESET_RESUME }, ++ + /* X-Rite/Gretag-Macbeth Eye-One Pro display colorimeter */ + { USB_DEVICE(0x0971, 0x2000), .driver_info = USB_QUIRK_NO_SET_INTF }, + +-- +2.35.3 + diff --git a/patches.suse/USB-core-Fix-RST-error-in-hub.c.patch b/patches.suse/USB-core-Fix-RST-error-in-hub.c.patch new file mode 100644 index 0000000..b0ed2bc --- /dev/null +++ b/patches.suse/USB-core-Fix-RST-error-in-hub.c.patch @@ -0,0 +1,39 @@ +From 766a96dc558385be735a370db867e302c8f22153 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Thu, 1 Sep 2022 10:36:34 -0400 +Subject: [PATCH] USB: core: Fix RST error in hub.c +Git-commit: 766a96dc558385be735a370db867e302c8f22153 +References: git-fixes +Patch-mainline: v6.0-rc7 + +A recent commit added an invalid RST expression to a kerneldoc comment +in hub.c. The fix is trivial. + +Fixes: 9c6d778800b9 ("USB: core: Prevent nested device-reset calls") +Cc: +Reported-by: Stephen Rothwell +Reviewed-by: Bagas Sanjaya +Signed-off-by: Alan Stern +Link: https://lore.kernel.org/r/YxDDcsLtRZ7c20pq@rowland.harvard.edu +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/usb/core/hub.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index d4b1e70d1498..bbab424b0d55 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -6039,7 +6039,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev) + * + * Return: The same as for usb_reset_and_verify_device(). + * However, if a reset is already in progress (for instance, if a +- * driver doesn't have pre_ or post_reset() callbacks, and while ++ * driver doesn't have pre_reset() or post_reset() callbacks, and while + * being unbound or re-bound during the ongoing reset its disconnect() + * or probe() routine tries to perform a second, nested reset), the + * routine returns -EINPROGRESS. +-- +2.35.3 + diff --git a/patches.suse/USB-core-Prevent-nested-device-reset-calls.patch b/patches.suse/USB-core-Prevent-nested-device-reset-calls.patch new file mode 100644 index 0000000..3a72047 --- /dev/null +++ b/patches.suse/USB-core-Prevent-nested-device-reset-calls.patch @@ -0,0 +1,137 @@ +From 9c6d778800b921bde3bff3cff5003d1650f942d1 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Fri, 26 Aug 2022 15:31:32 -0400 +Subject: [PATCH] USB: core: Prevent nested device-reset calls +Git-commit: 9c6d778800b921bde3bff3cff5003d1650f942d1 +References: git-fixes +Patch-mainline: v6.0-rc4 + +Automatic kernel fuzzing revealed a recursive locking violation in +usb-storage: + +============================================ +WARNING: possible recursive locking detected +5.18.0 #3 Not tainted +-------------------------------------------- +kworker/1:3/1205 is trying to acquire lock: +ffff888018638db8 (&us_interface_key[i]){+.+.}-{3:3}, at: +usb_stor_pre_reset+0x35/0x40 drivers/usb/storage/usb.c:230 + +but task is already holding lock: +ffff888018638db8 (&us_interface_key[i]){+.+.}-{3:3}, at: +usb_stor_pre_reset+0x35/0x40 drivers/usb/storage/usb.c:230 + +... + +stack backtrace: +CPU: 1 PID: 1205 Comm: kworker/1:3 Not tainted 5.18.0 #3 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS +1.13.0-1ubuntu1.1 04/01/2014 +Workqueue: usb_hub_wq hub_event +Call Trace: + +__dump_stack lib/dump_stack.c:88 [inline] +dump_stack_lvl+0xcd/0x134 lib/dump_stack.c:106 +print_deadlock_bug kernel/locking/lockdep.c:2988 [inline] +check_deadlock kernel/locking/lockdep.c:3031 [inline] +validate_chain kernel/locking/lockdep.c:3816 [inline] +__lock_acquire.cold+0x152/0x3ca kernel/locking/lockdep.c:5053 +lock_acquire kernel/locking/lockdep.c:5665 [inline] +lock_acquire+0x1ab/0x520 kernel/locking/lockdep.c:5630 +__mutex_lock_common kernel/locking/mutex.c:603 [inline] +__mutex_lock+0x14f/0x1610 kernel/locking/mutex.c:747 +usb_stor_pre_reset+0x35/0x40 drivers/usb/storage/usb.c:230 +usb_reset_device+0x37d/0x9a0 drivers/usb/core/hub.c:6109 +r871xu_dev_remove+0x21a/0x270 drivers/staging/rtl8712/usb_intf.c:622 +usb_unbind_interface+0x1bd/0x890 drivers/usb/core/driver.c:458 +device_remove drivers/base/dd.c:545 [inline] +device_remove+0x11f/0x170 drivers/base/dd.c:537 +__device_release_driver drivers/base/dd.c:1222 [inline] +device_release_driver_internal+0x1a7/0x2f0 drivers/base/dd.c:1248 +usb_driver_release_interface+0x102/0x180 drivers/usb/core/driver.c:627 +usb_forced_unbind_intf+0x4d/0xa0 drivers/usb/core/driver.c:1118 +usb_reset_device+0x39b/0x9a0 drivers/usb/core/hub.c:6114 + +This turned out not to be an error in usb-storage but rather a nested +device reset attempt. That is, as the rtl8712 driver was being +unbound from a composite device in preparation for an unrelated USB +reset (that driver does not have pre_reset or post_reset callbacks), +its ->remove routine called usb_reset_device() -- thus nesting one +reset call within another. + +Performing a reset as part of disconnect processing is a questionable +practice at best. However, the bug report points out that the USB +core does not have any protection against nested resets. Adding a +reset_in_progress flag and testing it will prevent such errors in the +future. + +Link: https://lore.kernel.org/all/CAB7eexKUpvX-JNiLzhXBDWgfg2T9e9_0Tw4HQ6keN==voRbP0g@mail.gmail.com/ +Cc: stable@vger.kernel.org +Reported-and-tested-by: Rondreis +Signed-off-by: Alan Stern +Link: https://lore.kernel.org/r/YwkflDxvg0KWqyZK@rowland.harvard.edu +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/usb/core/hub.c | 10 ++++++++++ + include/linux/usb.h | 2 ++ + 2 files changed, 12 insertions(+) + +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index 2633acde7ac1..d4b1e70d1498 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -6038,6 +6038,11 @@ static int usb_reset_and_verify_device(struct usb_device *udev) + * the reset is over (using their post_reset method). + * + * Return: The same as for usb_reset_and_verify_device(). ++ * However, if a reset is already in progress (for instance, if a ++ * driver doesn't have pre_ or post_reset() callbacks, and while ++ * being unbound or re-bound during the ongoing reset its disconnect() ++ * or probe() routine tries to perform a second, nested reset), the ++ * routine returns -EINPROGRESS. + * + * Note: + * The caller must own the device lock. For example, it's safe to use +@@ -6071,6 +6076,10 @@ int usb_reset_device(struct usb_device *udev) + return -EISDIR; + } + ++ if (udev->reset_in_progress) ++ return -EINPROGRESS; ++ udev->reset_in_progress = 1; ++ + port_dev = hub->ports[udev->portnum - 1]; + + /* +@@ -6135,6 +6144,7 @@ int usb_reset_device(struct usb_device *udev) + + usb_autosuspend_device(udev); + memalloc_noio_restore(noio_flag); ++ udev->reset_in_progress = 0; + return ret; + } + EXPORT_SYMBOL_GPL(usb_reset_device); +diff --git a/include/linux/usb.h b/include/linux/usb.h +index f7a9914fc97f..9ff1ad4dfad1 100644 +--- a/include/linux/usb.h ++++ b/include/linux/usb.h +@@ -575,6 +575,7 @@ struct usb3_lpm_parameters { + * @devaddr: device address, XHCI: assigned by HW, others: same as devnum + * @can_submit: URBs may be submitted + * @persist_enabled: USB_PERSIST enabled for this device ++ * @reset_in_progress: the device is being reset + * @have_langid: whether string_langid is valid + * @authorized: policy has said we can use it; + * (user space) policy determines if we authorize this device to be +@@ -662,6 +663,7 @@ struct usb_device { + + unsigned can_submit:1; + unsigned persist_enabled:1; ++ unsigned reset_in_progress:1; + unsigned have_langid:1; + unsigned authorized:1; + unsigned authenticated:1; +-- +2.35.3 + diff --git a/patches.suse/USB-hcd-pci-Drop-the-unused-id-parameter-from-usb_hc.patch b/patches.suse/USB-hcd-pci-Drop-the-unused-id-parameter-from-usb_hc.patch new file mode 100644 index 0000000..e5074ca --- /dev/null +++ b/patches.suse/USB-hcd-pci-Drop-the-unused-id-parameter-from-usb_hc.patch @@ -0,0 +1,125 @@ +From 4e55e22d3d9aa50ef1ba059bf3a53aa61109c179 Mon Sep 17 00:00:00 2001 +From: Heikki Krogerus +Date: Wed, 31 Aug 2022 15:50:52 +0300 +Subject: [PATCH] USB: hcd-pci: Drop the unused id parameter from + usb_hcd_pci_probe() +Git-commit: 4e55e22d3d9aa50ef1ba059bf3a53aa61109c179 +References: jsc#PED-531 +Patch-mainline: v6.1-rc1 + +Since the HC driver is now passed to the function with its +own parameter (it used to be picked from id->driver_data), +the id parameter serves no purpose. + +Signed-off-by: Heikki Krogerus +Link: https://lore.kernel.org/r/20220831125052.71584-1-heikki.krogerus@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/usb/core/hcd-pci.c | 7 +------ + drivers/usb/host/ehci-pci.c | 2 +- + drivers/usb/host/ohci-pci.c | 2 +- + drivers/usb/host/uhci-pci.c | 2 +- + drivers/usb/host/xhci-pci.c | 2 +- + include/linux/usb/hcd.h | 1 - + 6 files changed, 5 insertions(+), 11 deletions(-) + +diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c +index 482dae72ef1c..9b77f49b3560 100644 +--- a/drivers/usb/core/hcd-pci.c ++++ b/drivers/usb/core/hcd-pci.c +@@ -157,7 +157,6 @@ static void ehci_wait_for_companions(struct pci_dev *pdev, struct usb_hcd *hcd, + /** + * usb_hcd_pci_probe - initialize PCI-based HCDs + * @dev: USB Host Controller being probed +- * @id: pci hotplug id connecting controller to HCD framework + * @driver: USB HC driver handle + * + * Context: task context, might sleep +@@ -170,8 +169,7 @@ static void ehci_wait_for_companions(struct pci_dev *pdev, struct usb_hcd *hcd, + * + * Return: 0 if successful. + */ +-int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id, +- const struct hc_driver *driver) ++int usb_hcd_pci_probe(struct pci_dev *dev, const struct hc_driver *driver) + { + struct usb_hcd *hcd; + int retval; +@@ -180,9 +178,6 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id, + if (usb_disabled()) + return -ENODEV; + +- if (!id) +- return -EINVAL; +- + if (!driver) + return -EINVAL; + +diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c +index 9581952d999a..17f8b6ea0c35 100644 +--- a/drivers/usb/host/ehci-pci.c ++++ b/drivers/usb/host/ehci-pci.c +@@ -382,7 +382,7 @@ static int ehci_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) + { + if (is_bypassed_id(pdev)) + return -ENODEV; +- return usb_hcd_pci_probe(pdev, id, &ehci_pci_hc_driver); ++ return usb_hcd_pci_probe(pdev, &ehci_pci_hc_driver); + } + + static void ehci_pci_remove(struct pci_dev *pdev) +diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c +index a146b2d3ef0b..d7b4f40f9ff4 100644 +--- a/drivers/usb/host/ohci-pci.c ++++ b/drivers/usb/host/ohci-pci.c +@@ -282,7 +282,7 @@ MODULE_DEVICE_TABLE (pci, pci_ids); + + static int ohci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) + { +- return usb_hcd_pci_probe(dev, id, &ohci_pci_hc_driver); ++ return usb_hcd_pci_probe(dev, &ohci_pci_hc_driver); + } + + /* pci driver glue; this is a "new style" PCI driver module */ +diff --git a/drivers/usb/host/uhci-pci.c b/drivers/usb/host/uhci-pci.c +index 9b88745d247f..3592f757fe05 100644 +--- a/drivers/usb/host/uhci-pci.c ++++ b/drivers/usb/host/uhci-pci.c +@@ -294,7 +294,7 @@ MODULE_DEVICE_TABLE(pci, uhci_pci_ids); + + static int uhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) + { +- return usb_hcd_pci_probe(dev, id, &uhci_driver); ++ return usb_hcd_pci_probe(dev, &uhci_driver); + } + + static struct pci_driver uhci_pci_driver = { +diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c +index dce6c0ec8d34..40228a3d77a0 100644 +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -431,7 +431,7 @@ static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) + * to say USB 2.0, but I'm not sure what the implications would be in + * the other parts of the HCD code. + */ +- retval = usb_hcd_pci_probe(dev, id, &xhci_pci_hc_driver); ++ retval = usb_hcd_pci_probe(dev, &xhci_pci_hc_driver); + + if (retval) + goto put_runtime_pm; +diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h +index 67f8713d3fa3..78cd566ee238 100644 +--- a/include/linux/usb/hcd.h ++++ b/include/linux/usb/hcd.h +@@ -479,7 +479,6 @@ static inline int ehset_single_step_set_feature(struct usb_hcd *hcd, int port) + struct pci_dev; + struct pci_device_id; + extern int usb_hcd_pci_probe(struct pci_dev *dev, +- const struct pci_device_id *id, + const struct hc_driver *driver); + extern void usb_hcd_pci_remove(struct pci_dev *dev); + extern void usb_hcd_pci_shutdown(struct pci_dev *dev); +-- +2.35.3 + diff --git a/patches.suse/USB-serial-console-move-mutex_unlock-before-usb_seri.patch b/patches.suse/USB-serial-console-move-mutex_unlock-before-usb_seri.patch new file mode 100644 index 0000000..666f531 --- /dev/null +++ b/patches.suse/USB-serial-console-move-mutex_unlock-before-usb_seri.patch @@ -0,0 +1,39 @@ +From 61dfa797c731754642d1ac500a6ac42f9b47f920 Mon Sep 17 00:00:00 2001 +From: Liang He +Date: Mon, 19 Sep 2022 18:48:24 +0800 +Subject: [PATCH] USB: serial: console: move mutex_unlock() before usb_serial_put() +Git-commit: 61dfa797c731754642d1ac500a6ac42f9b47f920 +Patch-mainline: v6.1-rc1 +References: git-fixes + +While in current version there is no use-after-free as USB serial +core holds another reference when the console is registered, we +should better unlock before dropping the reference in +usb_console_setup(). + +Fixes: 7bd032dc2793 ("USB serial: update the console driver") +Signed-off-by: Liang He +Signed-off-by: Johan Hovold +Acked-by: Takashi Iwai + +--- + drivers/usb/serial/console.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c +index b97aa40ca4d1..da19a5fa414f 100644 +--- a/drivers/usb/serial/console.c ++++ b/drivers/usb/serial/console.c +@@ -189,8 +189,8 @@ static int usb_console_setup(struct console *co, char *options) + info->port = NULL; + usb_autopm_put_interface(serial->interface); + error_get_interface: +- usb_serial_put(serial); + mutex_unlock(&serial->disc_mutex); ++ usb_serial_put(serial); + return retval; + } + +-- +2.35.3 + diff --git a/patches.suse/USB-serial-ftdi_sio-fix-300-bps-rate-for-SIO.patch b/patches.suse/USB-serial-ftdi_sio-fix-300-bps-rate-for-SIO.patch new file mode 100644 index 0000000..26c086b --- /dev/null +++ b/patches.suse/USB-serial-ftdi_sio-fix-300-bps-rate-for-SIO.patch @@ -0,0 +1,36 @@ +From 7bd7ad3c310cd6766f170927381eea0aa6f46c69 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 13 Sep 2022 16:53:12 +0200 +Subject: [PATCH] USB: serial: ftdi_sio: fix 300 bps rate for SIO +Git-commit: 7bd7ad3c310cd6766f170927381eea0aa6f46c69 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The 300 bps rate of SIO devices has been mapped to 9600 bps since +2003... Let's fix the regression. + +Cc: stable@vger.kernel.org +Signed-off-by: Johan Hovold +Acked-by: Takashi Iwai + +--- + drivers/usb/serial/ftdi_sio.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c +index 52d59be92034..787e63fd7f99 100644 +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -1319,8 +1319,7 @@ static u32 get_ftdi_divisor(struct tty_struct *tty, + case 38400: div_value = ftdi_sio_b38400; break; + case 57600: div_value = ftdi_sio_b57600; break; + case 115200: div_value = ftdi_sio_b115200; break; +- } /* baud */ +- if (div_value == 0) { ++ default: + dev_dbg(dev, "%s - Baudrate (%d) requested is not supported\n", + __func__, baud); + div_value = ftdi_sio_b9600; +-- +2.35.3 + diff --git a/patches.suse/USB-serial-option-add-Quectel-BG95-0x0203-compositio.patch b/patches.suse/USB-serial-option-add-Quectel-BG95-0x0203-compositio.patch new file mode 100644 index 0000000..e0d6376 --- /dev/null +++ b/patches.suse/USB-serial-option-add-Quectel-BG95-0x0203-compositio.patch @@ -0,0 +1,63 @@ +From f8f67eff6847f9b8d753fa029723bcc54296055a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Carl=20Yin=28=E6=AE=B7=E5=BC=A0=E6=88=90=29?= +Date: Fri, 2 Sep 2022 09:49:43 +0000 +Subject: [PATCH] USB: serial: option: add Quectel BG95 0x0203 composition +Git-commit: f8f67eff6847f9b8d753fa029723bcc54296055a +Patch-mainline: v6.0-rc7 +References: git-fixes + +Add support for the following Quectel BG95 composition: + +0x0203: Diag + GNSS + Modem + ECM + +usb-devices output: +T: Bus=01 Lev=01 Prnt=01 Port=03 Cnt=01 Dev#= 2 Spd=480 MxCh= 0 +D: Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 +P: Vendor=2c7c ProdID=0203 Rev= 0.00 +S: Manufacturer=Quectel, Incorporated +S: Product=Quectel LPWA Module +S: SerialNumber=71d3a21b +C:* #Ifs= 5 Cfg#= 1 Atr=e0 MxPwr=500mA +A: FirstIf#= 3 IfCount= 2 Cls=02(comm.) Sub=00 Prot=00 +I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option +E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=60 Driver=option +E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=option +E: Ad=83(I) Atr=03(Int.) MxPS= 64 Ivl=2ms +E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 3 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=06 Prot=00 Driver=cdc_ether +E: Ad=85(I) Atr=03(Int.) MxPS= 64 Ivl=2ms +I: If#= 4 Alt= 0 #EPs= 0 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_ether +I:* If#= 4 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_ether +E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms + +Signed-off-by: Carl Yin +Cc: stable@vger.kernel.org +Signed-off-by: Johan Hovold +Acked-by: Takashi Iwai + +--- + drivers/usb/serial/option.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index a5e8374a8d71..50a9cb0791f7 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -1138,6 +1138,8 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG95, 0xff, 0xff, 0xff), + .driver_info = NUMEP2 }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG95, 0xff, 0, 0) }, ++ { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, 0x0203, 0xff), /* BG95-M3 */ ++ .driver_info = ZLP }, + { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96), + .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0xff, 0xff), +-- +2.35.3 + diff --git a/patches.suse/USB-serial-option-add-Quectel-RM520N.patch b/patches.suse/USB-serial-option-add-Quectel-RM520N.patch new file mode 100644 index 0000000..29f820c --- /dev/null +++ b/patches.suse/USB-serial-option-add-Quectel-RM520N.patch @@ -0,0 +1,73 @@ +From d640c4cb8f2f933c0ca896541f9de7fb1ae245f4 Mon Sep 17 00:00:00 2001 +From: jerry meng +Date: Mon, 5 Sep 2022 14:35:33 +0800 +Subject: [PATCH] USB: serial: option: add Quectel RM520N +Git-commit: d640c4cb8f2f933c0ca896541f9de7fb1ae245f4 +Patch-mainline: v6.0-rc7 +References: git-fixes + +add support for Quectel RM520N which is based on Qualcomm SDX62 chip. + +0x0801: DIAG + NMEA + AT + MODEM + RMNET + +T: Bus=03 Lev=01 Prnt=01 Port=01 Cnt=02 Dev#= 10 Spd=480 MxCh= 0 +D: Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 +P: Vendor=2c7c ProdID=0801 Rev= 5.04 +S: Manufacturer=Quectel +S: Product=RM520N-GL +S: SerialNumber=384af524 +C:* #Ifs= 5 Cfg#= 1 Atr=a0 MxPwr=500mA +I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option +E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=40 Driver=option +E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option +E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option +E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan +E: Ad=88(I) Atr=03(Int.) MxPS= 8 Ivl=32ms +E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=0f(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms + +Signed-off-by: jerry meng +Cc: stable@vger.kernel.org +Signed-off-by: Johan Hovold +Acked-by: Takashi Iwai + +--- + drivers/usb/serial/option.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 50a9cb0791f7..697683e3fbff 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -256,6 +256,7 @@ static void option_instat_callback(struct urb *urb); + #define QUECTEL_PRODUCT_EM060K 0x030b + #define QUECTEL_PRODUCT_EM12 0x0512 + #define QUECTEL_PRODUCT_RM500Q 0x0800 ++#define QUECTEL_PRODUCT_RM520N 0x0801 + #define QUECTEL_PRODUCT_EC200S_CN 0x6002 + #define QUECTEL_PRODUCT_EC200T 0x6026 + #define QUECTEL_PRODUCT_RM500K 0x7001 +@@ -1161,6 +1162,9 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x10), + .driver_info = ZLP }, ++ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM520N, 0xff, 0xff, 0x30) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM520N, 0xff, 0, 0x40) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM520N, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200S_CN, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200T, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500K, 0xff, 0x00, 0x00) }, +-- +2.35.3 + diff --git a/patches.suse/USB-serial-qcserial-add-new-usb-id-for-Dell-branded-.patch b/patches.suse/USB-serial-qcserial-add-new-usb-id-for-Dell-branded-.patch new file mode 100644 index 0000000..a0c1cdc --- /dev/null +++ b/patches.suse/USB-serial-qcserial-add-new-usb-id-for-Dell-branded-.patch @@ -0,0 +1,34 @@ +From eee48781ea199e32c1d0c4732641c494833788ca Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Mon, 26 Sep 2022 17:07:39 +0200 +Subject: [PATCH] USB: serial: qcserial: add new usb-id for Dell branded EM7455 +Git-commit: eee48781ea199e32c1d0c4732641c494833788ca +Patch-mainline: v6.1-rc1 +References: git-fixes + +Add support for Dell 5811e (EM7455) with USB-id 0x413c:0x81c2. + +Signed-off-by: Frank Wunderlich +Cc: stable@vger.kernel.org +Signed-off-by: Johan Hovold +Acked-by: Takashi Iwai + +--- + drivers/usb/serial/qcserial.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c +index 586ef5551e76..b1e844bf31f8 100644 +--- a/drivers/usb/serial/qcserial.c ++++ b/drivers/usb/serial/qcserial.c +@@ -177,6 +177,7 @@ static const struct usb_device_id id_table[] = { + {DEVICE_SWI(0x413c, 0x81b3)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card (rev3) */ + {DEVICE_SWI(0x413c, 0x81b5)}, /* Dell Wireless 5811e QDL */ + {DEVICE_SWI(0x413c, 0x81b6)}, /* Dell Wireless 5811e QDL */ ++ {DEVICE_SWI(0x413c, 0x81c2)}, /* Dell Wireless 5811e */ + {DEVICE_SWI(0x413c, 0x81cb)}, /* Dell Wireless 5816e QDL */ + {DEVICE_SWI(0x413c, 0x81cc)}, /* Dell Wireless 5816e */ + {DEVICE_SWI(0x413c, 0x81cf)}, /* Dell Wireless 5819 */ +-- +2.35.3 + diff --git a/patches.suse/USB-xhci-make-xhci_get_endpoint_address-static.patch b/patches.suse/USB-xhci-make-xhci_get_endpoint_address-static.patch new file mode 100644 index 0000000..fa486d2 --- /dev/null +++ b/patches.suse/USB-xhci-make-xhci_get_endpoint_address-static.patch @@ -0,0 +1,47 @@ +From d017aeaf844db21e8e7b22d79de229b746359f3b Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Thu, 1 Sep 2022 15:47:44 +0200 +Subject: [PATCH] USB: xhci: make xhci_get_endpoint_address static +Git-commit: d017aeaf844db21e8e7b22d79de229b746359f3b +References: jsc#PED-531 +Patch-mainline: v6.1-rc1 + +This is only called in the xhci.c file, so make the symbol static. + +Cc: Mathias Nyman +Link: https://lore.kernel.org/r/20220901134744.2039891-1-gregkh@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/usb/host/xhci.c | 2 +- + drivers/usb/host/xhci.h | 1 - + 2 files changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index 38649284ff88..e8837c5d6f5c 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -1482,7 +1482,7 @@ EXPORT_SYMBOL_GPL(xhci_get_endpoint_index); + /* The reverse operation to xhci_get_endpoint_index. Calculate the USB endpoint + * address from the XHCI endpoint index. + */ +-unsigned int xhci_get_endpoint_address(unsigned int ep_index) ++static unsigned int xhci_get_endpoint_address(unsigned int ep_index) + { + unsigned int number = DIV_ROUND_UP(ep_index, 2); + unsigned int direction = ep_index % 2 ? USB_DIR_OUT : USB_DIR_IN; +diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h +index 6dfbf73ee840..2fa7be41a8b5 100644 +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -2042,7 +2042,6 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud + void xhci_copy_ep0_dequeue_into_input_ctx(struct xhci_hcd *xhci, + struct usb_device *udev); + unsigned int xhci_get_endpoint_index(struct usb_endpoint_descriptor *desc); +-unsigned int xhci_get_endpoint_address(unsigned int ep_index); + unsigned int xhci_last_valid_endpoint(u32 added_ctxs); + void xhci_endpoint_zero(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, struct usb_host_endpoint *ep); + void xhci_update_tt_active_eps(struct xhci_hcd *xhci, +-- +2.35.3 + diff --git a/patches.suse/acpi-nfit-rely-on-mce-misc-to-determine-poison-granu.patch b/patches.suse/acpi-nfit-rely-on-mce-misc-to-determine-poison-granu.patch new file mode 100644 index 0000000..7f4e840 --- /dev/null +++ b/patches.suse/acpi-nfit-rely-on-mce-misc-to-determine-poison-granu.patch @@ -0,0 +1,41 @@ +From: Jane Chu +Date: Fri, 22 Apr 2022 16:45:02 -0600 +Subject: acpi/nfit: rely on mce->misc to determine poison granularity +Patch-mainline: v5.19-rc1 +Git-commit: 7917f9cdb5032ac065ac6a5415f5722f215b2608 +References: jsc#PED-1408 + +nfit_handle_mec() hardcode poison granularity at L1_CACHE_BYTES. +Instead, let the driver rely on mce->misc register to determine +the poison granularity. + +Suggested-by: Dan Williams +Reviewed-by: Dan Williams +Signed-off-by: Jane Chu +Link: https://lore.kernel.org/r/20220422224508.440670-2-jane.chu@oracle.com +Signed-off-by: Dan Williams +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/nfit/mce.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/acpi/nfit/mce.c ++++ b/drivers/acpi/nfit/mce.c +@@ -32,6 +32,7 @@ static int nfit_handle_mce(struct notifi + */ + mutex_lock(&acpi_desc_lock); + list_for_each_entry(acpi_desc, &acpi_descs, list) { ++ unsigned int align = 1UL << MCI_MISC_ADDR_LSB(mce->misc); + struct device *dev = acpi_desc->dev; + int found_match = 0; + +@@ -63,8 +64,7 @@ static int nfit_handle_mce(struct notifi + + /* If this fails due to an -ENOMEM, there is little we can do */ + nvdimm_bus_add_badrange(acpi_desc->nvdimm_bus, +- ALIGN(mce->addr, L1_CACHE_BYTES), +- L1_CACHE_BYTES); ++ ALIGN_DOWN(mce->addr, align), align); + nvdimm_region_notify(nfit_spa->nd_region, + NVDIMM_REVALIDATE_POISON); + diff --git a/patches.suse/arm64-dts-qcom-sc7280-Cleanup-the-lpasscc-node.patch b/patches.suse/arm64-dts-qcom-sc7280-Cleanup-the-lpasscc-node.patch new file mode 100644 index 0000000..939f6ba --- /dev/null +++ b/patches.suse/arm64-dts-qcom-sc7280-Cleanup-the-lpasscc-node.patch @@ -0,0 +1,42 @@ +From 8c7ebabd2e3f33ef24378d3cac00d3e59886cecb Mon Sep 17 00:00:00 2001 +From: Satya Priya +Date: Wed, 10 Aug 2022 10:35:07 +0530 +Subject: [PATCH] arm64: dts: qcom: sc7280: Cleanup the lpasscc node +Git-commit: 8c7ebabd2e3f33ef24378d3cac00d3e59886cecb +Patch-mainline: v6.1-rc1 +References: git-fixes + +Remove "cc" regmap from lpasscc node which is overlapping +with the lpass_aon regmap. + +Fixes: 422a295221bb ("arm64: dts: qcom: sc7280: Add clock controller nodes") +Signed-off-by: Satya Priya +Signed-off-by: Taniya Das +Reviewed-by: Stephen Boyd +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/1660107909-27947-2-git-send-email-quic_c_skakit@quicinc.com +Acked-by: Takashi Iwai + +--- + arch/arm64/boot/dts/qcom/sc7280.dtsi | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi +index 89a8e6b9822a..06e144e7a5f3 100644 +--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi ++++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi +@@ -2173,9 +2173,8 @@ tcsr_2: syscon@1fc0000 { + lpasscc: lpasscc@3000000 { + compatible = "qcom,sc7280-lpasscc"; + reg = <0 0x03000000 0 0x40>, +- <0 0x03c04000 0 0x4>, +- <0 0x03389000 0 0x24>; +- reg-names = "qdsp6ss", "top_cc", "cc"; ++ <0 0x03c04000 0 0x4>; ++ reg-names = "qdsp6ss", "top_cc"; + clocks = <&gcc GCC_CFG_NOC_LPASS_CLK>; + clock-names = "iface"; + #clock-cells = <1>; +-- +2.35.3 + diff --git a/patches.suse/arm64-dts-qcom-sm8350-fix-UFS-PHY-serdes-size.patch b/patches.suse/arm64-dts-qcom-sm8350-fix-UFS-PHY-serdes-size.patch new file mode 100644 index 0000000..9902402 --- /dev/null +++ b/patches.suse/arm64-dts-qcom-sm8350-fix-UFS-PHY-serdes-size.patch @@ -0,0 +1,33 @@ +From 40e9541959100e017533e18e44d07eed44f91dc5 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Fri, 16 Sep 2022 11:36:03 +0200 +Subject: [PATCH] arm64: dts: qcom: sm8350: fix UFS PHY serdes size +Git-commit: 40e9541959100e017533e18e44d07eed44f91dc5 +Patch-mainline: v6.0 +References: git-fixes + +The size of the UFS PHY serdes register region is 0x1c4 and the +corresponding 'reg' property should specifically not include the +adjacent regions that are defined in the child node (e.g. tx and rx). + +Fixes: 59c7cf814783 ("arm64: dts: qcom: sm8350: Add UFS nodes") +Signed-off-by: Johan Hovold +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20220916093603.24263-1-johan+linaro@kernel.org +Acked-by: Takashi Iwai + +--- + arch/arm64/boot/dts/qcom/sm8350.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm64/boot/dts/qcom/sm8350.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi +@@ -1068,7 +1068,7 @@ + + ufs_mem_phy: phy@1d87000 { + compatible = "qcom,sm8350-qmp-ufs-phy"; +- reg = <0 0x01d87000 0 0xe10>; ++ reg = <0 0x01d87000 0 0x1c4>; + #address-cells = <2>; + #size-cells = <2>; + #clock-cells = <1>; diff --git a/patches.suse/arm64-dts-rockchip-Fix-typo-in-lisense-text-for-PX30.patch b/patches.suse/arm64-dts-rockchip-Fix-typo-in-lisense-text-for-PX30.patch new file mode 100644 index 0000000..69d695a --- /dev/null +++ b/patches.suse/arm64-dts-rockchip-Fix-typo-in-lisense-text-for-PX30.patch @@ -0,0 +1,39 @@ +From 4a00c43818dcc19be97250d4c3c4a1e2f1ed4f9d Mon Sep 17 00:00:00 2001 +From: Jagan Teki +Date: Mon, 22 Aug 2022 16:05:24 +0530 +Subject: [PATCH] arm64: dts: rockchip: Fix typo in lisense text for PX30.Core +Git-commit: 4a00c43818dcc19be97250d4c3c4a1e2f1ed4f9d +Patch-mainline: v6.0-rc7 +References: git-fixes + +Fix the Amarula Solutions typo mistake in lisense text added +in Engicam PX30.Core SoM dtsi. + +Fixes: d92a7c331f53c ("arm64: dts: rockchip: Add Engicam PX30.Core SOM") +Signed-off-by: Jagan Teki +Link: https://lore.kernel.org/r/20220822103524.266731-1-jagan@amarulasolutions.com +Signed-off-by: Heiko Stuebner +Acked-by: Takashi Iwai + +--- + arch/arm64/boot/dts/rockchip/px30-engicam-px30-core.dtsi | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core.dtsi b/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core.dtsi +index 7249871530ab..5eecbefa8a33 100644 +--- a/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core.dtsi ++++ b/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core.dtsi +@@ -2,8 +2,8 @@ + /* + * Copyright (c) 2020 Fuzhou Rockchip Electronics Co., Ltd + * Copyright (c) 2020 Engicam srl +- * Copyright (c) 2020 Amarula Solutons +- * Copyright (c) 2020 Amarula Solutons(India) ++ * Copyright (c) 2020 Amarula Solutions ++ * Copyright (c) 2020 Amarula Solutions(India) + */ + + #include +-- +2.35.3 + diff --git a/patches.suse/arm64-dts-rockchip-Pull-up-wlan-wake-on-Gru-Bob.patch b/patches.suse/arm64-dts-rockchip-Pull-up-wlan-wake-on-Gru-Bob.patch new file mode 100644 index 0000000..6ff50d7 --- /dev/null +++ b/patches.suse/arm64-dts-rockchip-Pull-up-wlan-wake-on-Gru-Bob.patch @@ -0,0 +1,62 @@ +From e5467359a725de90b6b8d0dd865500f6373828ca Mon Sep 17 00:00:00 2001 +From: Brian Norris +Date: Mon, 22 Aug 2022 16:45:04 -0700 +Subject: [PATCH] arm64: dts: rockchip: Pull up wlan wake# on Gru-Bob +Git-commit: e5467359a725de90b6b8d0dd865500f6373828ca +Patch-mainline: v6.0-rc7 +References: git-fixes + +The Gru-Bob board does not have a pull-up resistor on its +WLAN_HOST_WAKE# pin, but Kevin does. The production/vendor kernel +specified the pin configuration correctly as a pull-up, but this didn't +get ported correctly to upstream. + +This means Bob's WLAN_HOST_WAKE# pin is floating, causing inconsistent +wakeup behavior. + +Note that bt_host_wake_l has a similar dynamic, but apparently the +upstream choice was to redundantly configure both internal and external +pull-up on Kevin (see the "Kevin has an external pull up" comment in +rk3399-gru.dtsi). This doesn't cause any functional problem, although +it's perhaps wasteful. + +Fixes: 8559bbeeb849 ("arm64: dts: rockchip: add Google Bob") +Signed-off-by: Brian Norris +Reviewed-by: Douglas Anderson +Link: https://lore.kernel.org/r/20220822164453.1.I75c57b48b0873766ec993bdfb7bc1e63da5a1637@changeid +Signed-off-by: Heiko Stuebner +Acked-by: Takashi Iwai + +--- + arch/arm64/boot/dts/rockchip/rk3399-gru-bob.dts | 5 +++++ + arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi | 1 + + 2 files changed, 6 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru-bob.dts b/arch/arm64/boot/dts/rockchip/rk3399-gru-bob.dts +index 31ebb4e5fd33..0f9cc042d9bf 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-gru-bob.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3399-gru-bob.dts +@@ -88,3 +88,8 @@ h1_int_od_l: h1-int-od-l { + }; + }; + }; ++ ++&wlan_host_wake_l { ++ /* Kevin has an external pull up, but Bob does not. */ ++ rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>; ++}; +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi +index cd074641884b..45796b9fd94f 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi +@@ -578,6 +578,7 @@ wifi_perst_l: wifi-perst-l { + }; + + wlan_host_wake_l: wlan-host-wake-l { ++ /* Kevin has an external pull up, but Bob does not */ + rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +-- +2.35.3 + diff --git a/patches.suse/arm64-dts-rockchip-Remove-enable-active-low-from-rk3.patch b/patches.suse/arm64-dts-rockchip-Remove-enable-active-low-from-rk3.patch new file mode 100644 index 0000000..aa3f095 --- /dev/null +++ b/patches.suse/arm64-dts-rockchip-Remove-enable-active-low-from-rk3.patch @@ -0,0 +1,40 @@ +From a994b34b9abb9c08ee09e835b4027ff2147f9d94 Mon Sep 17 00:00:00 2001 +From: Fabio Estevam +Date: Sat, 27 Aug 2022 14:51:39 -0300 +Subject: [PATCH] arm64: dts: rockchip: Remove 'enable-active-low' from rk3399-puma +Git-commit: a994b34b9abb9c08ee09e835b4027ff2147f9d94 +Patch-mainline: v6.0-rc7 +References: git-fixes + +The 'enable-active-low' property is not a valid one. + +Only 'enable-active-high' is valid, and when this property is absent +the gpio regulator will act as active low by default. + +Remove the invalid 'enable-active-low' property. + +Fixes: 2c66fc34e945 ("arm64: dts: rockchip: add RK3399-Q7 (Puma) SoM") +Signed-off-by: Fabio Estevam +Link: https://lore.kernel.org/r/20220827175140.1696699-1-festevam@denx.de +Signed-off-by: Heiko Stuebner +Acked-by: Takashi Iwai + +--- + arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi +index b1ac3a89f259..aa3e21bd6c8f 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi +@@ -62,7 +62,6 @@ vcc3v3_sys: vcc3v3-sys { + vcc5v0_host: vcc5v0-host-regulator { + compatible = "regulator-fixed"; + gpio = <&gpio4 RK_PA3 GPIO_ACTIVE_LOW>; +- enable-active-low; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_host_en>; + regulator-name = "vcc5v0_host"; +-- +2.35.3 + diff --git a/patches.suse/arm64-dts-rockchip-Set-RK3399-Gru-PCLK_EDP-to-24-MHz.patch b/patches.suse/arm64-dts-rockchip-Set-RK3399-Gru-PCLK_EDP-to-24-MHz.patch new file mode 100644 index 0000000..8492684 --- /dev/null +++ b/patches.suse/arm64-dts-rockchip-Set-RK3399-Gru-PCLK_EDP-to-24-MHz.patch @@ -0,0 +1,51 @@ +From 8123437cf46ea5a0f6ca5cb3c528d8b6db97b9c2 Mon Sep 17 00:00:00 2001 +From: zain wang +Date: Tue, 30 Aug 2022 13:16:17 -0700 +Subject: [PATCH] arm64: dts: rockchip: Set RK3399-Gru PCLK_EDP to 24 MHz +Git-commit: 8123437cf46ea5a0f6ca5cb3c528d8b6db97b9c2 +Patch-mainline: v6.0-rc7 +References: git-fixes + +We've found the AUX channel to be less reliable with PCLK_EDP at a +higher rate (typically 25 MHz). This is especially important on systems +with PSR-enabled panels (like Gru-Kevin), since we make heavy, constant +use of AUX. + +According to Rockchip, using any rate other than 24 MHz can cause +"problems between syncing the PHY an PCLK", which leads to all sorts of +unreliabilities around register operations. + +Fixes: d67a38c5a623 ("arm64: dts: rockchip: move core edp from rk3399-kevin to shared chromebook") +Reviewed-by: Douglas Anderson +Signed-off-by: zain wang +Signed-off-by: Brian Norris +Link: https://lore.kernel.org/r/20220830131212.v2.1.I98d30623f13b785ca77094d0c0fd4339550553b6@changeid +Signed-off-by: Heiko Stuebner +Acked-by: Takashi Iwai + +--- + arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi +index 45796b9fd94f..ee6095baba4d 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi +@@ -244,6 +244,14 @@ &dmc { + &edp { + status = "okay"; + ++ /* ++ * eDP PHY/clk don't sync reliably at anything other than 24 MHz. Only ++ * set this here, because rk3399-gru.dtsi ensures we can generate this ++ * off GPLL=600MHz, whereas some other RK3399 boards may not. ++ */ ++ assigned-clocks = <&cru PCLK_EDP>; ++ assigned-clock-rates = <24000000>; ++ + ports { + edp_out: port@1 { + reg = <1>; +-- +2.35.3 + diff --git a/patches.suse/arm64-dts-ti-k3-j7200-fix-main-pinmux-range.patch b/patches.suse/arm64-dts-ti-k3-j7200-fix-main-pinmux-range.patch new file mode 100644 index 0000000..352bc43 --- /dev/null +++ b/patches.suse/arm64-dts-ti-k3-j7200-fix-main-pinmux-range.patch @@ -0,0 +1,78 @@ +From 0d0a0b4413460383331088b2203ba09a6971bc3a Mon Sep 17 00:00:00 2001 +From: Matt Ranostay +Date: Mon, 19 Sep 2022 13:57:23 -0700 +Subject: [PATCH] arm64: dts: ti: k3-j7200: fix main pinmux range +Git-commit: 0d0a0b4413460383331088b2203ba09a6971bc3a +Patch-mainline: v6.1-rc1 +References: git-fixes + +Range size of 0x2b4 was incorrect since there isn't 173 configurable +pins for muxing. Additionally there is a non-addressable region in the +mapping which requires splitting into two ranges. + +main_pmx0 -> 67 pins +main_pmx1 -> 3 pins + +Fixes: d361ed88455f ("arm64: dts: ti: Add support for J7200 SoC") +Signed-off-by: Matt Ranostay +Signed-off-by: Vignesh Raghavendra +Tested-by: Vaishnav Achath +Link: https://lore.kernel.org/r/20220919205723.8342-1-mranostay@ti.com +Acked-by: Takashi Iwai + +--- + arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts | 10 ++++++---- + arch/arm64/boot/dts/ti/k3-j7200-main.dtsi | 11 ++++++++++- + 2 files changed, 16 insertions(+), 5 deletions(-) + +diff --git a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts +index 121975dc8239..7e8552fd2b6a 100644 +--- a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts ++++ b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts +@@ -134,15 +134,17 @@ J721E_IOPAD(0xe4, PIN_INPUT, 8) /* (V1) TIMER_IO0.MMC1_SDCD */ + >; + }; + +- main_usbss0_pins_default: main-usbss0-pins-default { ++ vdd_sd_dv_pins_default: vdd-sd-dv-pins-default { + pinctrl-single,pins = < +- J721E_IOPAD(0x120, PIN_OUTPUT, 0) /* (T4) USB0_DRVVBUS */ ++ J721E_IOPAD(0xd0, PIN_OUTPUT, 7) /* (T5) SPI0_D1.GPIO0_55 */ + >; + }; ++}; + +- vdd_sd_dv_pins_default: vdd-sd-dv-pins-default { ++&main_pmx1 { ++ main_usbss0_pins_default: main-usbss0-pins-default { + pinctrl-single,pins = < +- J721E_IOPAD(0xd0, PIN_OUTPUT, 7) /* (T5) SPI0_D1.GPIO0_55 */ ++ J721E_IOPAD(0x04, PIN_OUTPUT, 0) /* (T4) USB0_DRVVBUS */ + >; + }; + }; +diff --git a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi +index cf657ac0bd6a..80a57916bcb3 100644 +--- a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi ++++ b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi +@@ -295,7 +295,16 @@ cpts@310d0000 { + main_pmx0: pinctrl@11c000 { + compatible = "pinctrl-single"; + /* Proxy 0 addressing */ +- reg = <0x00 0x11c000 0x00 0x2b4>; ++ reg = <0x00 0x11c000 0x00 0x10c>; ++ #pinctrl-cells = <1>; ++ pinctrl-single,register-width = <32>; ++ pinctrl-single,function-mask = <0xffffffff>; ++ }; ++ ++ main_pmx1: pinctrl@11c11c { ++ compatible = "pinctrl-single"; ++ /* Proxy 0 addressing */ ++ reg = <0x00 0x11c11c 0x00 0xc>; + #pinctrl-cells = <1>; + pinctrl-single,register-width = <32>; + pinctrl-single,function-mask = <0xffffffff>; +-- +2.35.3 + diff --git a/patches.suse/arm64-ftrace-fix-module-PLTs-with-mcount.patch b/patches.suse/arm64-ftrace-fix-module-PLTs-with-mcount.patch new file mode 100644 index 0000000..5d0aa70 --- /dev/null +++ b/patches.suse/arm64-ftrace-fix-module-PLTs-with-mcount.patch @@ -0,0 +1,127 @@ +From 8cfb08575c6d4585f1ce0deeb189e5c824776b04 Mon Sep 17 00:00:00 2001 +From: Mark Rutland +Date: Thu, 29 Sep 2022 14:45:25 +0100 +Subject: [PATCH] arm64: ftrace: fix module PLTs with mcount +Git-commit: 8cfb08575c6d4585f1ce0deeb189e5c824776b04 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Li Huafei reports that mcount-based ftrace with module PLTs was broken +by commit: + + a6253579977e4c6f ("arm64: ftrace: consistently handle PLTs.") + +When a module PLTs are used and a module is loaded sufficiently far away +from the kernel, we'll create PLTs for any branches which are +out-of-range. These are separate from the special ftrace trampoline +PLTs, which the module PLT code doesn't directly manipulate. + +When mcount is in use this is a problem, as each mcount callsite in a +module will be initialized to point to a module PLT, but since commit +a6253579977e4c6f ftrace_make_nop() will assume that the callsite has +been initialized to point to the special ftrace trampoline PLT, and +ftrace_find_callable_addr() rejects other cases. + +This means that when ftrace tries to initialize a callsite via +ftrace_make_nop(), the call to ftrace_find_callable_addr() will find +that the `_mcount` stub is out-of-range and is not handled by the ftrace +PLT, resulting in a splat: + +| ftrace_test: loading out-of-tree module taints kernel. +| ftrace: no module PLT for _mcount +| ------------[ ftrace bug ]------------ +| ftrace failed to modify +| [] 0xffff800029180014 +| actual: 44:00:00:94 +| Initializing ftrace call sites +| ftrace record flags: 2000000 +| (0) +| expected tramp: ffff80000802eb3c +| ------------[ cut here ]------------ +| WARNING: CPU: 3 PID: 157 at kernel/trace/ftrace.c:2120 ftrace_bug+0x94/0x270 +| Modules linked in: +| CPU: 3 PID: 157 Comm: insmod Tainted: G O 6.0.0-rc6-00151-gcd722513a189-dirty #22 +| Hardware name: linux,dummy-virt (DT) +| pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) +| pc : ftrace_bug+0x94/0x270 +| lr : ftrace_bug+0x21c/0x270 +| sp : ffff80000b2bbaf0 +| x29: ffff80000b2bbaf0 x28: 0000000000000000 x27: ffff0000c4d38000 +| x26: 0000000000000001 x25: ffff800009d7e000 x24: ffff0000c4d86e00 +| x23: 0000000002000000 x22: ffff80000a62b000 x21: ffff8000098ebea8 +| x20: ffff0000c4d38000 x19: ffff80000aa24158 x18: ffffffffffffffff +| x17: 0000000000000000 x16: 0a0d2d2d2d2d2d2d x15: ffff800009aa9118 +| x14: 0000000000000000 x13: 6333626532303830 x12: 3030303866666666 +| x11: 203a706d61727420 x10: 6465746365707865 x9 : 3362653230383030 +| x8 : c0000000ffffefff x7 : 0000000000017fe8 x6 : 000000000000bff4 +| x5 : 0000000000057fa8 x4 : 0000000000000000 x3 : 0000000000000001 +| x2 : ad2cb14bb5438900 x1 : 0000000000000000 x0 : 0000000000000022 +| Call trace: +| ftrace_bug+0x94/0x270 +| ftrace_process_locs+0x308/0x430 +| ftrace_module_init+0x44/0x60 +| load_module+0x15b4/0x1ce8 +| __do_sys_init_module+0x1ec/0x238 +| __arm64_sys_init_module+0x24/0x30 +| invoke_syscall+0x54/0x118 +| el0_svc_common.constprop.4+0x84/0x100 +| do_el0_svc+0x3c/0xd0 +| el0_svc+0x1c/0x50 +| el0t_64_sync_handler+0x90/0xb8 +| el0t_64_sync+0x15c/0x160 +| ---[ end trace 0000000000000000 ]--- +| ---------test_init----------- + +Fix this by reverting to the old behaviour of ignoring the old +instruction when initialising an mcount callsite in a module, which was +the behaviour prior to commit a6253579977e4c6f. + +Signed-off-by: Mark Rutland +Fixes: a6253579977e ("arm64: ftrace: consistently handle PLTs.") +Reported-by: Li Huafei +Link: https://lore.kernel.org/linux-arm-kernel/20220929094134.99512-1-lihuafei1@huawei.com +Cc: Ard Biesheuvel +Cc: Will Deacon +Link: https://lore.kernel.org/r/20220929134525.798593-1-mark.rutland@arm.com +Signed-off-by: Catalin Marinas +Acked-by: Takashi Iwai + +--- + arch/arm64/kernel/ftrace.c | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/kernel/ftrace.c b/arch/arm64/kernel/ftrace.c +index ea5dc7c90f46..b49ba9a24bcc 100644 +--- a/arch/arm64/kernel/ftrace.c ++++ b/arch/arm64/kernel/ftrace.c +@@ -217,11 +217,26 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, + unsigned long pc = rec->ip; + u32 old = 0, new; + ++ new = aarch64_insn_gen_nop(); ++ ++ /* ++ * When using mcount, callsites in modules may have been initalized to ++ * call an arbitrary module PLT (which redirects to the _mcount stub) ++ * rather than the ftrace PLT we'll use at runtime (which redirects to ++ * the ftrace trampoline). We can ignore the old PLT when initializing ++ * the callsite. ++ * ++ * Note: 'mod' is only set at module load time. ++ */ ++ if (!IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_REGS) && ++ IS_ENABLED(CONFIG_ARM64_MODULE_PLTS) && mod) { ++ return aarch64_insn_patch_text_nosync((void *)pc, new); ++ } ++ + if (!ftrace_find_callable_addr(rec, mod, &addr)) + return -EINVAL; + + old = aarch64_insn_gen_branch_imm(pc, addr, AARCH64_INSN_BRANCH_LINK); +- new = aarch64_insn_gen_nop(); + + return ftrace_modify_code(pc, old, new, true); + } +-- +2.35.3 + diff --git a/patches.suse/arm64-kexec_file-use-more-system-keyrings-to-verify-.patch b/patches.suse/arm64-kexec_file-use-more-system-keyrings-to-verify-.patch new file mode 100644 index 0000000..76ec475 --- /dev/null +++ b/patches.suse/arm64-kexec_file-use-more-system-keyrings-to-verify-.patch @@ -0,0 +1,74 @@ +From 0d519cadf75184a24313568e7f489a7fc9b1be3b Mon Sep 17 00:00:00 2001 +From: Coiby Xu +Date: Thu, 14 Jul 2022 21:40:26 +0800 +Subject: [PATCH] arm64: kexec_file: use more system keyrings to verify kernel + image signature + +References: bsc#1196444 +Patch-mainline: v6.0-rc1 +Git-commit: 0d519cadf75184a24313568e7f489a7fc9b1be3b + +Currently, when loading a kernel image via the kexec_file_load() system +call, arm64 can only use the .builtin_trusted_keys keyring to verify +a signature whereas x86 can use three more keyrings i.e. +.secondary_trusted_keys, .machine and .platform keyrings. For example, +one resulting problem is kexec'ing a kernel image would be rejected +with the error "Lockdown: kexec: kexec of unsigned images is restricted; +see man kernel_lockdown.7". + +This patch set enables arm64 to make use of the same keyrings as x86 to +verify the signature kexec'ed kernel image. + +Fixes: 732b7b93d849 ("arm64: kexec_file: add kernel signature verification support") +Cc: stable@vger.kernel.org # 105e10e2cf1c: kexec_file: drop weak attribute from functions +Cc: stable@vger.kernel.org # 34d5960af253: kexec: clean up arch_kexec_kernel_verify_sig +Cc: stable@vger.kernel.org # 83b7bb2d49ae: kexec, KEYS: make the code in bzImage64_verify_sig generic +Acked-by: Baoquan He +Cc: kexec@lists.infradead.org +Cc: keyrings@vger.kernel.org +Cc: linux-security-module@vger.kernel.org +Co-developed-by: Michal Suchanek +Signed-off-by: Michal Suchanek +Acked-by: Will Deacon +Signed-off-by: Coiby Xu +Signed-off-by: Mimi Zohar +Acked-by: Michal Suchanek +--- + arch/arm64/kernel/kexec_image.c | 11 +---------- + 1 file changed, 1 insertion(+), 10 deletions(-) + +diff --git a/arch/arm64/kernel/kexec_image.c b/arch/arm64/kernel/kexec_image.c +index 9ec34690e255..5ed6a585f21f 100644 +--- a/arch/arm64/kernel/kexec_image.c ++++ b/arch/arm64/kernel/kexec_image.c +@@ -14,7 +14,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -130,18 +129,10 @@ static void *image_load(struct kimage *image, + return NULL; + } + +-#ifdef CONFIG_KEXEC_IMAGE_VERIFY_SIG +-static int image_verify_sig(const char *kernel, unsigned long kernel_len) +-{ +- return verify_pefile_signature(kernel, kernel_len, NULL, +- VERIFYING_KEXEC_PE_SIGNATURE); +-} +-#endif +- + const struct kexec_file_ops kexec_image_ops = { + .probe = image_probe, + .load = image_load, + #ifdef CONFIG_KEXEC_IMAGE_VERIFY_SIG +- .verify_sig = image_verify_sig, ++ .verify_sig = kexec_kernel_verify_pe_sig, + #endif + }; +-- +2.35.3 + diff --git a/patches.suse/arm64-mte-Avoid-setting-PG_mte_tagged-if-no-tags-cle.patch b/patches.suse/arm64-mte-Avoid-setting-PG_mte_tagged-if-no-tags-cle.patch new file mode 100644 index 0000000..7b1495d --- /dev/null +++ b/patches.suse/arm64-mte-Avoid-setting-PG_mte_tagged-if-no-tags-cle.patch @@ -0,0 +1,101 @@ +From a8e5e5146ad08d794c58252bab00b261045ef16d Mon Sep 17 00:00:00 2001 +From: Catalin Marinas +Date: Thu, 6 Oct 2022 17:33:54 +0100 +Subject: [PATCH] arm64: mte: Avoid setting PG_mte_tagged if no tags cleared or restored +Git-commit: a8e5e5146ad08d794c58252bab00b261045ef16d +Patch-mainline: v6.1-rc1 +References: git-fixes + +Prior to commit 69e3b846d8a7 ("arm64: mte: Sync tags for pages where PTE +is untagged"), mte_sync_tags() was only called for pte_tagged() entries +(those mapped with PROT_MTE). Therefore mte_sync_tags() could safely use +test_and_set_bit(PG_mte_tagged, &page->flags) without inadvertently +setting PG_mte_tagged on an untagged page. + +The above commit was required as guests may enable MTE without any +control at the stage 2 mapping, nor a PROT_MTE mapping in the VMM. +However, the side-effect was that any page with a PTE that looked like +swap (or migration) was getting PG_mte_tagged set automatically. A +subsequent page copy (e.g. migration) copied the tags to the destination +page even if the tags were owned by KASAN. + +This issue was masked by the page_kasan_tag_reset() call introduced in +commit e5b8d9218951 ("arm64: mte: reset the page tag in page->flags"). +When this commit was reverted (20794545c146), KASAN started reporting +access faults because the overriding tags in a page did not match the +original page->flags (with CONFIG_KASAN_HW_TAGS=y): + + BUG: KASAN: invalid-access in copy_page+0x10/0xd0 arch/arm64/lib/copy_page.S:26 + Read at addr f5ff000017f2e000 by task syz-executor.1/2218 + Pointer tag: [f5], memory tag: [f2] + +Move the PG_mte_tagged bit setting from mte_sync_tags() to the actual +place where tags are cleared (mte_sync_page_tags()) or restored +(mte_restore_tags()). + +Signed-off-by: Catalin Marinas +Reported-by: syzbot+c2c79c6d6eddc5262b77@syzkaller.appspotmail.com +Fixes: 69e3b846d8a7 ("arm64: mte: Sync tags for pages where PTE is untagged") +Cc: # 5.14.x +Cc: Steven Price +Cc: Andrey Konovalov +Cc: Vincenzo Frascino +Cc: Will Deacon +Link: https://lore.kernel.org/r/0000000000004387dc05e5888ae5@google.com/ +Reviewed-by: Steven Price +Link: https://lore.kernel.org/r/20221006163354.3194102-1-catalin.marinas@arm.com +Acked-by: Takashi Iwai + +--- + arch/arm64/kernel/mte.c | 9 +++++++-- + arch/arm64/mm/mteswap.c | 7 ++++++- + 2 files changed, 13 insertions(+), 3 deletions(-) + +diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c +index aca88470fb69..7467217c1eaf 100644 +--- a/arch/arm64/kernel/mte.c ++++ b/arch/arm64/kernel/mte.c +@@ -48,7 +48,12 @@ static void mte_sync_page_tags(struct page *page, pte_t old_pte, + if (!pte_is_tagged) + return; + +- mte_clear_page_tags(page_address(page)); ++ /* ++ * Test PG_mte_tagged again in case it was racing with another ++ * set_pte_at(). ++ */ ++ if (!test_and_set_bit(PG_mte_tagged, &page->flags)) ++ mte_clear_page_tags(page_address(page)); + } + + void mte_sync_tags(pte_t old_pte, pte_t pte) +@@ -64,7 +69,7 @@ void mte_sync_tags(pte_t old_pte, pte_t pte) + + /* if PG_mte_tagged is set, tags have already been initialised */ + for (i = 0; i < nr_pages; i++, page++) { +- if (!test_and_set_bit(PG_mte_tagged, &page->flags)) ++ if (!test_bit(PG_mte_tagged, &page->flags)) + mte_sync_page_tags(page, old_pte, check_swap, + pte_is_tagged); + } +diff --git a/arch/arm64/mm/mteswap.c b/arch/arm64/mm/mteswap.c +index 4334dec93bd4..bed803d8e158 100644 +--- a/arch/arm64/mm/mteswap.c ++++ b/arch/arm64/mm/mteswap.c +@@ -53,7 +53,12 @@ bool mte_restore_tags(swp_entry_t entry, struct page *page) + if (!tags) + return false; + +- mte_restore_page_tags(page_address(page), tags); ++ /* ++ * Test PG_mte_tagged again in case it was racing with another ++ * set_pte_at(). ++ */ ++ if (!test_and_set_bit(PG_mte_tagged, &page->flags)) ++ mte_restore_page_tags(page_address(page), tags); + + return true; + } +-- +2.35.3 + diff --git a/patches.suse/arm64-topology-fix-possible-overflow-in-amu_fie_setu.patch b/patches.suse/arm64-topology-fix-possible-overflow-in-amu_fie_setu.patch new file mode 100644 index 0000000..fef44e6 --- /dev/null +++ b/patches.suse/arm64-topology-fix-possible-overflow-in-amu_fie_setu.patch @@ -0,0 +1,42 @@ +From d4955c0ad77dbc684fc716387070ac24801b8bca Mon Sep 17 00:00:00 2001 +From: Sergey Shtylyov +Date: Fri, 16 Sep 2022 23:17:07 +0300 +Subject: [PATCH] arm64: topology: fix possible overflow in amu_fie_setup() +Git-commit: d4955c0ad77dbc684fc716387070ac24801b8bca +Patch-mainline: v6.0-rc7 +References: git-fixes + +cpufreq_get_hw_max_freq() returns max frequency in kHz as *unsigned int*, +while freq_inv_set_max_ratio() gets passed this frequency in Hz as 'u64'. +Multiplying max frequency by 1000 can potentially result in overflow -- +multiplying by 1000ULL instead should avoid that... + +Found by Linux Verification Center (linuxtesting.org) with the SVACE static +analysis tool. + +Fixes: cd0ed03a8903 ("arm64: use activity monitors for frequency invariance") +Signed-off-by: Sergey Shtylyov +Link: https://lore.kernel.org/r/01493d64-2bce-d968-86dc-11a122a9c07d@omp.ru +Signed-off-by: Will Deacon +Acked-by: Takashi Iwai + +--- + arch/arm64/kernel/topology.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c +index ad2bfc794257..44ebf5b2fc4b 100644 +--- a/arch/arm64/kernel/topology.c ++++ b/arch/arm64/kernel/topology.c +@@ -237,7 +237,7 @@ static void amu_fie_setup(const struct cpumask *cpus) + for_each_cpu(cpu, cpus) { + if (!freq_counters_valid(cpu) || + freq_inv_set_max_ratio(cpu, +- cpufreq_get_hw_max_freq(cpu) * 1000, ++ cpufreq_get_hw_max_freq(cpu) * 1000ULL, + arch_timer_get_rate())) + return; + } +-- +2.35.3 + diff --git a/patches.suse/ata-fix-ata_id_has_devslp.patch b/patches.suse/ata-fix-ata_id_has_devslp.patch new file mode 100644 index 0000000..2d9fd68 --- /dev/null +++ b/patches.suse/ata-fix-ata_id_has_devslp.patch @@ -0,0 +1,57 @@ +From 9c6e09a434e1317e09b78b3b69cd384022ec9a03 Mon Sep 17 00:00:00 2001 +From: Niklas Cassel +Date: Fri, 16 Sep 2022 14:28:33 +0200 +Subject: [PATCH] ata: fix ata_id_has_devslp() +Git-commit: 9c6e09a434e1317e09b78b3b69cd384022ec9a03 +Patch-mainline: v6.1-rc1 +References: git-fixes + +ACS-5 section +7.13.6.36 Word 78: Serial ATA features supported +states that: + +If word 76 is not 0000h or FFFFh, word 78 reports the features supported +by the device. If this word is not supported, the word shall be cleared +to zero. + +(This text also exists in really old ACS standards, e.g. ACS-3.) + +Additionally, move the macro to the other ATA_ID_FEATURE_SUPP macros +(which already have this check), thus making it more likely that the +next ATA_ID_FEATURE_SUPP macro that is added will include this check. + +Fixes: 65fe1f0f66a5 ("ahci: implement aggressive SATA device sleep support") +Signed-off-by: Niklas Cassel +Signed-off-by: Damien Le Moal +Acked-by: Takashi Iwai + +--- + include/linux/ata.h | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/include/linux/ata.h b/include/linux/ata.h +index 868bfd503aee..bc136a43689f 100644 +--- a/include/linux/ata.h ++++ b/include/linux/ata.h +@@ -566,6 +566,10 @@ struct ata_bmdma_prd { + ((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \ + ((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \ + ((id)[ATA_ID_FEATURE_SUPP] & (1 << 2))) ++#define ata_id_has_devslp(id) \ ++ ((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \ ++ ((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \ ++ ((id)[ATA_ID_FEATURE_SUPP] & (1 << 8))) + #define ata_id_iordy_disable(id) ((id)[ATA_ID_CAPABILITY] & (1 << 10)) + #define ata_id_has_iordy(id) ((id)[ATA_ID_CAPABILITY] & (1 << 11)) + #define ata_id_u32(id,n) \ +@@ -578,7 +582,6 @@ struct ata_bmdma_prd { + + #define ata_id_cdb_intr(id) (((id)[ATA_ID_CONFIG] & 0x60) == 0x20) + #define ata_id_has_da(id) ((id)[ATA_ID_SATA_CAPABILITY_2] & (1 << 4)) +-#define ata_id_has_devslp(id) ((id)[ATA_ID_FEATURE_SUPP] & (1 << 8)) + #define ata_id_has_ncq_autosense(id) \ + ((id)[ATA_ID_FEATURE_SUPP] & (1 << 7)) + +-- +2.35.3 + diff --git a/patches.suse/ata-fix-ata_id_has_dipm.patch b/patches.suse/ata-fix-ata_id_has_dipm.patch new file mode 100644 index 0000000..ba086a0 --- /dev/null +++ b/patches.suse/ata-fix-ata_id_has_dipm.patch @@ -0,0 +1,76 @@ +From 630624cb1b5826d753ac8e01a0e42de43d66dedf Mon Sep 17 00:00:00 2001 +From: Niklas Cassel +Date: Fri, 16 Sep 2022 14:28:35 +0200 +Subject: [PATCH] ata: fix ata_id_has_dipm() +Git-commit: 630624cb1b5826d753ac8e01a0e42de43d66dedf +Patch-mainline: v6.1-rc1 +References: git-fixes + +ACS-5 section +7.13.6.36 Word 78: Serial ATA features supported +states that: + +If word 76 is not 0000h or FFFFh, word 78 reports the features supported +by the device. If this word is not supported, the word shall be cleared +to zero. + +(This text also exists in really old ACS standards, e.g. ACS-3.) + +The problem with ata_id_has_dipm() is that the while it performs a +check against 0 and 0xffff, it performs the check against +ATA_ID_FEATURE_SUPP (word 78), the same word where the feature bit +is stored. + +Fix this by performing the check against ATA_ID_SATA_CAPABILITY +(word 76), like required by the spec. The feature bit check itself +is of course still performed against ATA_ID_FEATURE_SUPP (word 78). + +Additionally, move the macro to the other ATA_ID_FEATURE_SUPP macros +(which already have this check), thus making it more likely that the +next ATA_ID_FEATURE_SUPP macro that is added will include this check. + +Fixes: ca77329fb713 ("[libata] Link power management infrastructure") +Signed-off-by: Niklas Cassel +Signed-off-by: Damien Le Moal +Acked-by: Takashi Iwai + +--- + include/linux/ata.h | 15 ++++----------- + 1 file changed, 4 insertions(+), 11 deletions(-) + +diff --git a/include/linux/ata.h b/include/linux/ata.h +index 4845443e0f08..e3050e153a71 100644 +--- a/include/linux/ata.h ++++ b/include/linux/ata.h +@@ -574,6 +574,10 @@ struct ata_bmdma_prd { + ((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \ + ((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \ + ((id)[ATA_ID_FEATURE_SUPP] & (1 << 7))) ++#define ata_id_has_dipm(id) \ ++ ((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \ ++ ((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \ ++ ((id)[ATA_ID_FEATURE_SUPP] & (1 << 3))) + #define ata_id_iordy_disable(id) ((id)[ATA_ID_CAPABILITY] & (1 << 10)) + #define ata_id_has_iordy(id) ((id)[ATA_ID_CAPABILITY] & (1 << 11)) + #define ata_id_u32(id,n) \ +@@ -597,17 +601,6 @@ static inline bool ata_id_has_hipm(const u16 *id) + return val & (1 << 9); + } + +-static inline bool ata_id_has_dipm(const u16 *id) +-{ +- u16 val = id[ATA_ID_FEATURE_SUPP]; +- +- if (val == 0 || val == 0xffff) +- return false; +- +- return val & (1 << 3); +-} +- +- + static inline bool ata_id_has_fua(const u16 *id) + { + if ((id[ATA_ID_CFSSE] & 0xC000) != 0x4000) +-- +2.35.3 + diff --git a/patches.suse/ata-fix-ata_id_has_ncq_autosense.patch b/patches.suse/ata-fix-ata_id_has_ncq_autosense.patch new file mode 100644 index 0000000..4fe6f23 --- /dev/null +++ b/patches.suse/ata-fix-ata_id_has_ncq_autosense.patch @@ -0,0 +1,58 @@ +From a5fb6bf853148974dbde092ec1bde553bea5e49f Mon Sep 17 00:00:00 2001 +From: Niklas Cassel +Date: Fri, 16 Sep 2022 14:28:34 +0200 +Subject: [PATCH] ata: fix ata_id_has_ncq_autosense() +Git-commit: a5fb6bf853148974dbde092ec1bde553bea5e49f +Patch-mainline: v6.1-rc1 +References: git-fixes + +ACS-5 section +7.13.6.36 Word 78: Serial ATA features supported +states that: + +If word 76 is not 0000h or FFFFh, word 78 reports the features supported +by the device. If this word is not supported, the word shall be cleared +to zero. + +(This text also exists in really old ACS standards, e.g. ACS-3.) + +Additionally, move the macro to the other ATA_ID_FEATURE_SUPP macros +(which already have this check), thus making it more likely that the +next ATA_ID_FEATURE_SUPP macro that is added will include this check. + +Fixes: 5b01e4b9efa0 ("libata: Implement NCQ autosense") +Signed-off-by: Niklas Cassel +Signed-off-by: Damien Le Moal +Acked-by: Takashi Iwai + +--- + include/linux/ata.h | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/include/linux/ata.h b/include/linux/ata.h +index bc136a43689f..4845443e0f08 100644 +--- a/include/linux/ata.h ++++ b/include/linux/ata.h +@@ -570,6 +570,10 @@ struct ata_bmdma_prd { + ((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \ + ((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \ + ((id)[ATA_ID_FEATURE_SUPP] & (1 << 8))) ++#define ata_id_has_ncq_autosense(id) \ ++ ((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \ ++ ((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \ ++ ((id)[ATA_ID_FEATURE_SUPP] & (1 << 7))) + #define ata_id_iordy_disable(id) ((id)[ATA_ID_CAPABILITY] & (1 << 10)) + #define ata_id_has_iordy(id) ((id)[ATA_ID_CAPABILITY] & (1 << 11)) + #define ata_id_u32(id,n) \ +@@ -582,8 +586,6 @@ struct ata_bmdma_prd { + + #define ata_id_cdb_intr(id) (((id)[ATA_ID_CONFIG] & 0x60) == 0x20) + #define ata_id_has_da(id) ((id)[ATA_ID_SATA_CAPABILITY_2] & (1 << 4)) +-#define ata_id_has_ncq_autosense(id) \ +- ((id)[ATA_ID_FEATURE_SUPP] & (1 << 7)) + + static inline bool ata_id_has_hipm(const u16 *id) + { +-- +2.35.3 + diff --git a/patches.suse/ata-fix-ata_id_sense_reporting_enabled-and-ata_id_ha.patch b/patches.suse/ata-fix-ata_id_sense_reporting_enabled-and-ata_id_ha.patch new file mode 100644 index 0000000..1c7e9a9 --- /dev/null +++ b/patches.suse/ata-fix-ata_id_sense_reporting_enabled-and-ata_id_ha.patch @@ -0,0 +1,71 @@ +From 690aa8c3ae308bc696ec8b1b357b995193927083 Mon Sep 17 00:00:00 2001 +From: Niklas Cassel +Date: Fri, 16 Sep 2022 14:28:32 +0200 +Subject: [PATCH] ata: fix ata_id_sense_reporting_enabled() and ata_id_has_sense_reporting() +Git-commit: 690aa8c3ae308bc696ec8b1b357b995193927083 +Patch-mainline: v6.1-rc1 +References: git-fixes + +ACS-5 section +7.13.6.41 Words 85..87, 120: Commands and feature sets supported or enabled +states that: + +If bit 15 of word 86 is set to one, bit 14 of word 119 is set to one, +and bit 15 of word 119 is cleared to zero, then word 119 is valid. + +If bit 15 of word 86 is set to one, bit 14 of word 120 is set to one, +and bit 15 of word 120 is cleared to zero, then word 120 is valid. + +(This text also exists in really old ACS standards, e.g. ACS-3.) + +Currently, ata_id_sense_reporting_enabled() and +ata_id_has_sense_reporting() both check bit 15 of word 86, +but neither of them check that bit 14 of word 119 is set to one, +or that bit 15 of word 119 is cleared to zero. + +Additionally, make ata_id_sense_reporting_enabled() return false +if !ata_id_has_sense_reporting(), similar to how e.g. +ata_id_flush_ext_enabled() returns false if !ata_id_has_flush_ext(). + +Fixes: e87fd28cf9a2 ("libata: Implement support for sense data reporting") +Signed-off-by: Niklas Cassel +Signed-off-by: Damien Le Moal +Acked-by: Takashi Iwai + +--- + include/linux/ata.h | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/include/linux/ata.h b/include/linux/ata.h +index 21292b5bbb55..868bfd503aee 100644 +--- a/include/linux/ata.h ++++ b/include/linux/ata.h +@@ -771,16 +771,21 @@ static inline bool ata_id_has_read_log_dma_ext(const u16 *id) + + static inline bool ata_id_has_sense_reporting(const u16 *id) + { +- if (!(id[ATA_ID_CFS_ENABLE_2] & (1 << 15))) ++ if (!(id[ATA_ID_CFS_ENABLE_2] & BIT(15))) ++ return false; ++ if ((id[ATA_ID_COMMAND_SET_3] & (BIT(15) | BIT(14))) != BIT(14)) + return false; +- return id[ATA_ID_COMMAND_SET_3] & (1 << 6); ++ return id[ATA_ID_COMMAND_SET_3] & BIT(6); + } + + static inline bool ata_id_sense_reporting_enabled(const u16 *id) + { +- if (!(id[ATA_ID_CFS_ENABLE_2] & (1 << 15))) ++ if (!ata_id_has_sense_reporting(id)) ++ return false; ++ /* ata_id_has_sense_reporting() == true, word 86 must have bit 15 set */ ++ if ((id[ATA_ID_COMMAND_SET_4] & (BIT(15) | BIT(14))) != BIT(14)) + return false; +- return id[ATA_ID_COMMAND_SET_4] & (1 << 6); ++ return id[ATA_ID_COMMAND_SET_4] & BIT(6); + } + + /** +-- +2.35.3 + diff --git a/patches.suse/batman-adv-Fix-hang-up-with-small-MTU-hard-interface.patch b/patches.suse/batman-adv-Fix-hang-up-with-small-MTU-hard-interface.patch new file mode 100644 index 0000000..1aa0068 --- /dev/null +++ b/patches.suse/batman-adv-Fix-hang-up-with-small-MTU-hard-interface.patch @@ -0,0 +1,60 @@ +From b1cb8a71f1eaec4eb77051590f7f561f25b15e32 Mon Sep 17 00:00:00 2001 +From: Shigeru Yoshida +Date: Sat, 20 Aug 2022 12:25:16 +0900 +Subject: [PATCH] batman-adv: Fix hang up with small MTU hard-interface +Git-commit: b1cb8a71f1eaec4eb77051590f7f561f25b15e32 +Patch-mainline: v6.0-rc7 +References: git-fixes + +The system hangs up when batman-adv soft-interface is created on +hard-interface with small MTU. For example, the following commands +create batman-adv soft-interface on dummy interface with zero MTU: + + # ip link add name dummy0 type dummy + # ip link set mtu 0 dev dummy0 + # ip link set up dev dummy0 + # ip link add name bat0 type batadv + # ip link set dev dummy0 master bat0 + +These commands cause the system hang up with the following messages: + + [ 90.578925][ T6689] batman_adv: bat0: Adding interface: dummy0 + [ 90.580884][ T6689] batman_adv: bat0: The MTU of interface dummy0 is too small (0) to handle the transport of batman-adv packets. Packets going over this interface will be fragmented on layer2 which could impact the performance. Setting the MTU to 1560 would solve the problem. + [ 90.586264][ T6689] batman_adv: bat0: Interface activated: dummy0 + [ 90.590061][ T6689] batman_adv: bat0: Forced to purge local tt entries to fit new maximum fragment MTU (-320) + [ 90.595517][ T6689] batman_adv: bat0: Forced to purge local tt entries to fit new maximum fragment MTU (-320) + [ 90.598499][ T6689] batman_adv: bat0: Forced to purge local tt entries to fit new maximum fragment MTU (-320) + +This patch fixes this issue by returning error when enabling +hard-interface with small MTU size. + +Fixes: c6c8fea29769 ("net: Add batman-adv meshing protocol") +Signed-off-by: Shigeru Yoshida +Signed-off-by: Sven Eckelmann +Signed-off-by: Simon Wunderlich +Acked-by: Takashi Iwai + +--- + net/batman-adv/hard-interface.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/net/batman-adv/hard-interface.c ++++ b/net/batman-adv/hard-interface.c +@@ -9,6 +9,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -702,6 +703,9 @@ int batadv_hardif_enable_interface(struc + int max_header_len = batadv_max_header_len(); + int ret; + ++ if (hard_iface->net_dev->mtu < ETH_MIN_MTU + max_header_len) ++ return -EINVAL; ++ + if (hard_iface->if_status != BATADV_IF_NOT_IN_USE) + goto out; + diff --git a/patches.suse/bonding-ARP-monitor-spams-NETDEV_NOTIFY_PEERS-notifi.patch b/patches.suse/bonding-ARP-monitor-spams-NETDEV_NOTIFY_PEERS-notifi.patch new file mode 100644 index 0000000..8345140 --- /dev/null +++ b/patches.suse/bonding-ARP-monitor-spams-NETDEV_NOTIFY_PEERS-notifi.patch @@ -0,0 +1,48 @@ +From 15390c9683383a930b9a12953ae69f493e9e9c4f Mon Sep 17 00:00:00 2001 +From: Jay Vosburgh +Date: Thu, 16 Jun 2022 12:32:40 -0700 +Subject: [PATCH 23/32] bonding: ARP monitor spams NETDEV_NOTIFY_PEERS + notifiers +Git-commit: 7a9214f3d88cfdb099f3896e102a306b316d8707 +References: git-fixes +Patch-mainline: v5.19-rc4 + +The bonding ARP monitor fails to decrement send_peer_notif, the +number of peer notifications (gratuitous ARP or ND) to be sent. This +results in a continuous series of notifications. + +Correct this by decrementing the counter for each notification. + +Reported-by: Jonathan Toppins +Signed-off-by: Jay Vosburgh +Fixes: b0929915e035 ("bonding: Fix RTNL: assertion failed at net/core/rtnetlink.c for ab arp monitor") +Link: https://lore.kernel.org/netdev/b2fd4147-8f50-bebd-963a-1a3e8d1d9715@redhat.com/ +Tested-by: Jonathan Toppins +Reviewed-by: Jonathan Toppins +Link: https://lore.kernel.org/r/9400.1655407960@famine +Signed-off-by: Jakub Kicinski +Signed-off-by: Denis Kirjanov +--- + drivers/net/bonding/bond_main.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index c5a43db01815..e2b2d8d88a54 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -3402,9 +3402,11 @@ static void bond_activebackup_arp_mon(struct bonding *bond) + if (!rtnl_trylock()) + return; + +- if (should_notify_peers) ++ if (should_notify_peers) { ++ bond->send_peer_notif--; + call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, + bond->dev); ++ } + if (should_notify_rtnl) { + bond_slave_state_notify(bond); + bond_slave_link_notify(bond); +-- +2.16.4 + diff --git a/patches.suse/can-gs_usb-gs_can_open-fix-race-dev-can.state-condit.patch b/patches.suse/can-gs_usb-gs_can_open-fix-race-dev-can.state-condit.patch new file mode 100644 index 0000000..b7f2a57 --- /dev/null +++ b/patches.suse/can-gs_usb-gs_can_open-fix-race-dev-can.state-condit.patch @@ -0,0 +1,55 @@ +From 5440428b3da65408dba0241985acb7a05258b85e Mon Sep 17 00:00:00 2001 +From: Marc Kleine-Budde +Date: Tue, 20 Sep 2022 11:40:56 +0200 +Subject: [PATCH] can: gs_usb: gs_can_open(): fix race dev->can.state condition +Git-commit: 5440428b3da65408dba0241985acb7a05258b85e +Patch-mainline: v6.0-rc7 +References: git-fixes + +The dev->can.state is set to CAN_STATE_ERROR_ACTIVE, after the device +has been started. On busy networks the CAN controller might receive +CAN frame between and go into an error state before the dev->can.state +is assigned. + +Assign dev->can.state before starting the controller to close the race +window. + +Fixes: d08e973a77d1 ("can: gs_usb: Added support for the GS_USB CAN devices") +Link: https://lore.kernel.org/all/20220920195216.232481-1-mkl@pengutronix.de +Signed-off-by: Marc Kleine-Budde +Acked-by: Takashi Iwai + +--- + drivers/net/can/usb/gs_usb.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c +index baf749c8cda3..553e2c7b0b12 100644 +--- a/drivers/net/can/usb/gs_usb.c ++++ b/drivers/net/can/usb/gs_usb.c +@@ -824,6 +824,7 @@ static int gs_can_open(struct net_device *netdev) + flags |= GS_CAN_MODE_TRIPLE_SAMPLE; + + /* finally start device */ ++ dev->can.state = CAN_STATE_ERROR_ACTIVE; + dm->mode = cpu_to_le32(GS_CAN_MODE_START); + dm->flags = cpu_to_le32(flags); + rc = usb_control_msg(interface_to_usbdev(dev->iface), +@@ -835,13 +836,12 @@ static int gs_can_open(struct net_device *netdev) + if (rc < 0) { + netdev_err(netdev, "Couldn't start device (err=%d)\n", rc); + kfree(dm); ++ dev->can.state = CAN_STATE_STOPPED; + return rc; + } + + kfree(dm); + +- dev->can.state = CAN_STATE_ERROR_ACTIVE; +- + parent->active_channels++; + if (!(dev->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)) + netif_start_queue(netdev); +-- +2.35.3 + diff --git a/patches.suse/can-kvaser_usb-Fix-use-of-uninitialized-completion.patch b/patches.suse/can-kvaser_usb-Fix-use-of-uninitialized-completion.patch new file mode 100644 index 0000000..88d8f51 --- /dev/null +++ b/patches.suse/can-kvaser_usb-Fix-use-of-uninitialized-completion.patch @@ -0,0 +1,64 @@ +From cd7f30e174d09a02ca2afa5ef093fb0f0352e0d8 Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +Date: Mon, 10 Oct 2022 17:08:27 +0200 +Subject: [PATCH] can: kvaser_usb: Fix use of uninitialized completion +Git-commit: cd7f30e174d09a02ca2afa5ef093fb0f0352e0d8 +Patch-mainline: v6.1-rc1 +References: git-fixes + +flush_comp is initialized when CMD_FLUSH_QUEUE is sent to the device and +completed when the device sends CMD_FLUSH_QUEUE_RESP. + +This causes completion of uninitialized completion if the device sends +CMD_FLUSH_QUEUE_RESP before CMD_FLUSH_QUEUE is ever sent (e.g. as a +response to a flush by a previously bound driver, or a misbehaving +device). + +Fix that by initializing flush_comp in kvaser_usb_init_one() like the +other completions. + +This issue is only triggerable after RX URBs have been set up, i.e. the +interface has been opened at least once. + +Cc: stable@vger.kernel.org +Fixes: aec5fb2268b7 ("can: kvaser_usb: Add support for Kvaser USB hydra family") +Tested-by: Jimmy Assarsson +Signed-off-by: Anssi Hannula +Signed-off-by: Jimmy Assarsson +Link: https://lore.kernel.org/all/20221010150829.199676-3-extja@kvaser.com +Signed-off-by: Marc Kleine-Budde +Acked-by: Takashi Iwai + +--- + drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c | 1 + + drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +index 824cab80aa02..c2bce6773adc 100644 +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +@@ -729,6 +729,7 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel) + init_usb_anchor(&priv->tx_submitted); + init_completion(&priv->start_comp); + init_completion(&priv->stop_comp); ++ init_completion(&priv->flush_comp); + priv->can.ctrlmode_supported = 0; + + priv->dev = dev; +diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c +index 6871d474dabf..7b52fda73d82 100644 +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c +@@ -1916,7 +1916,7 @@ static int kvaser_usb_hydra_flush_queue(struct kvaser_usb_net_priv *priv) + { + int err; + +- init_completion(&priv->flush_comp); ++ reinit_completion(&priv->flush_comp); + + err = kvaser_usb_hydra_send_simple_cmd(priv->dev, CMD_FLUSH_QUEUE, + priv->channel); +-- +2.35.3 + diff --git a/patches.suse/can-kvaser_usb_leaf-Fix-CAN-state-after-restart.patch b/patches.suse/can-kvaser_usb_leaf-Fix-CAN-state-after-restart.patch new file mode 100644 index 0000000..8e32f23 --- /dev/null +++ b/patches.suse/can-kvaser_usb_leaf-Fix-CAN-state-after-restart.patch @@ -0,0 +1,45 @@ +From 0be1a655fe68c8e6dcadbcbddb69cf2fb29881f5 Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +Date: Mon, 10 Oct 2022 17:08:29 +0200 +Subject: [PATCH] can: kvaser_usb_leaf: Fix CAN state after restart +Git-commit: 0be1a655fe68c8e6dcadbcbddb69cf2fb29881f5 +Patch-mainline: v6.1-rc1 +References: git-fixes + +can_restart() expects CMD_START_CHIP to set the error state to +ERROR_ACTIVE as it calls netif_carrier_on() immediately afterwards. + +Otherwise the user may immediately trigger restart again and hit a +BUG_ON() in can_restart(). + +Fix kvaser_usb_leaf set_mode(CMD_START_CHIP) to set the expected state. + +Cc: stable@vger.kernel.org +Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devices") +Tested-by: Jimmy Assarsson +Signed-off-by: Anssi Hannula +Signed-off-by: Jimmy Assarsson +Link: https://lore.kernel.org/all/20221010150829.199676-5-extja@kvaser.com +Signed-off-by: Marc Kleine-Budde +Acked-by: Takashi Iwai + +--- + drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +index 59c220ef3049..50f2ac8319ff 100644 +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +@@ -1431,6 +1431,8 @@ static int kvaser_usb_leaf_set_mode(struct net_device *netdev, + err = kvaser_usb_leaf_simple_cmd_async(priv, CMD_START_CHIP); + if (err) + return err; ++ ++ priv->can.state = CAN_STATE_ERROR_ACTIVE; + break; + default: + return -EOPNOTSUPP; +-- +2.35.3 + diff --git a/patches.suse/can-kvaser_usb_leaf-Fix-TX-queue-out-of-sync-after-r.patch b/patches.suse/can-kvaser_usb_leaf-Fix-TX-queue-out-of-sync-after-r.patch new file mode 100644 index 0000000..1fa9ceb --- /dev/null +++ b/patches.suse/can-kvaser_usb_leaf-Fix-TX-queue-out-of-sync-after-r.patch @@ -0,0 +1,77 @@ +From 455561fb618fde40558776b5b8435f9420f335db Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +Date: Mon, 10 Oct 2022 17:08:28 +0200 +Subject: [PATCH] can: kvaser_usb_leaf: Fix TX queue out of sync after restart +Git-commit: 455561fb618fde40558776b5b8435f9420f335db +Patch-mainline: v6.1-rc1 +References: git-fixes + +The TX queue seems to be implicitly flushed by the hardware during +bus-off or bus-off recovery, but the driver does not reset the TX +bookkeeping. + +Despite not resetting TX bookkeeping the driver still re-enables TX +queue unconditionally, leading to "cannot find free context" / +NETDEV_TX_BUSY errors if the TX queue was full at bus-off time. + +Fix that by resetting TX bookkeeping on CAN restart. + +Tested with 0bfd:0124 Kvaser Mini PCI Express 2xHS FW 4.18.778. + +Cc: stable@vger.kernel.org +Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devices") +Tested-by: Jimmy Assarsson +Signed-off-by: Anssi Hannula +Signed-off-by: Jimmy Assarsson +Link: https://lore.kernel.org/all/20221010150829.199676-4-extja@kvaser.com +Signed-off-by: Marc Kleine-Budde +Acked-by: Takashi Iwai + +--- + drivers/net/can/usb/kvaser_usb/kvaser_usb.h | 2 ++ + drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c | 2 +- + drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 2 ++ + 3 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h +index 841da29cef93..f6c0938027ec 100644 +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h +@@ -178,6 +178,8 @@ struct kvaser_usb_dev_cfg { + extern const struct kvaser_usb_dev_ops kvaser_usb_hydra_dev_ops; + extern const struct kvaser_usb_dev_ops kvaser_usb_leaf_dev_ops; + ++void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv); ++ + int kvaser_usb_recv_cmd(const struct kvaser_usb *dev, void *cmd, int len, + int *actual_len); + +diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +index c2bce6773adc..e91648ed7386 100644 +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +@@ -477,7 +477,7 @@ static void kvaser_usb_reset_tx_urb_contexts(struct kvaser_usb_net_priv *priv) + /* This method might sleep. Do not call it in the atomic context + * of URB completions. + */ +-static void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv) ++void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv) + { + usb_kill_anchored_urbs(&priv->tx_submitted); + kvaser_usb_reset_tx_urb_contexts(priv); +diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +index 8e11cda85624..59c220ef3049 100644 +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +@@ -1426,6 +1426,8 @@ static int kvaser_usb_leaf_set_mode(struct net_device *netdev, + + switch (mode) { + case CAN_MODE_START: ++ kvaser_usb_unlink_tx_urbs(priv); ++ + err = kvaser_usb_leaf_simple_cmd_async(priv, CMD_START_CHIP); + if (err) + return err; +-- +2.35.3 + diff --git a/patches.suse/can-mcp251xfd-mcp251xfd_register_get_dev_id-fix-endi.patch b/patches.suse/can-mcp251xfd-mcp251xfd_register_get_dev_id-fix-endi.patch new file mode 100644 index 0000000..e3e6c9a --- /dev/null +++ b/patches.suse/can-mcp251xfd-mcp251xfd_register_get_dev_id-fix-endi.patch @@ -0,0 +1,56 @@ +From d589f10fad74a4d71e2afaaf4e616097a92ec759 Mon Sep 17 00:00:00 2001 +From: Marc Kleine-Budde +Date: Mon, 20 Jun 2022 11:49:24 +0200 +Subject: [PATCH 02/28] can: mcp251xfd: mcp251xfd_register_get_dev_id(): fix + endianness conversion +Git-commit: 1c0e78a287e3493e22bde8553d02f3b89177eaf7 +Patch-mainline: v5.19-rc16 +References: git-fixes + +In mcp251xfd_register_get_dev_id() the device ID register is read with +handcrafted SPI transfers. As all registers, this register is in +little endian. Further it is not naturally aligned in struct +mcp251xfd_map_buf_nocrc::data. However after the transfer the register +content is converted from big endian to CPU endianness not taking care +of being unaligned. + +Fix the conversion by converting from little endian to CPU endianness +taking the unaligned source into account. + +Side note: So far the register content is 0x0 on all mcp251xfd +compatible chips, and is only used for an informative printk. + +Link: https://lore.kernel.org/all/20220627092859.809042-1-mkl@pengutronix.de +Fixes: 55e5b97f003e ("can: mcp25xxfd: add driver for Microchip MCP25xxFD SPI CAN") +Reviewed-by: Rasmus Villemoes +Reviewed-by: Manivannan Sadhasivam +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Denis Kirjanov +--- + drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +index 100cd7d3b244..2afb659a0f0c 100644 +--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c ++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +@@ -12,6 +12,7 @@ + // Copyright (c) 2019 Martin Sperl + // + ++#include + #include + #include + #include +@@ -2692,7 +2693,7 @@ mcp251xfd_register_get_dev_id(const struct mcp251xfd_priv *priv, + if (err) + goto out_kfree_buf_tx; + +- *dev_id = be32_to_cpup((__be32 *)buf_rx->data); ++ *dev_id = get_unaligned_le32(buf_rx->data); + *effective_speed_hz = xfer->effective_speed_hz; + + out_kfree_buf_tx: +-- +2.16.4 + diff --git a/patches.suse/can-mcp251xfd-mcp251xfd_register_get_dev_id-use-corr.patch b/patches.suse/can-mcp251xfd-mcp251xfd_register_get_dev_id-use-corr.patch new file mode 100644 index 0000000..b826263 --- /dev/null +++ b/patches.suse/can-mcp251xfd-mcp251xfd_register_get_dev_id-use-corr.patch @@ -0,0 +1,45 @@ +From b72fe9f3cd1b92cbf7dea04ef73a6852a7053fde Mon Sep 17 00:00:00 2001 +From: Marc Kleine-Budde +Date: Thu, 16 Jun 2022 11:38:00 +0200 +Subject: [PATCH 01/28] can: mcp251xfd: mcp251xfd_register_get_dev_id(): use + correct length to read dev_id +Git-commit: 0ff32bfa0e794ccc3601de7158b522bf736fa63c +Patch-mainline: v5.19-rc16 +References: git-fixes + +The device ID register is 32 bits wide. The driver uses incorrectly +the size of a pointer to a u32 to calculate the length of the SPI +transfer. This results in a read of 2 registers on 64 bit platforms. +This is no problem on the Linux side, as the RX buffer of the SPI +transfer is large enough. In the mpc251xfd chip this results in the +read of an undocumented register. So far no problems were observed. + +Fix the length of the SPI transfer to read the device ID register +only. + +Link: https://lore.kernel.org/all/20220616094914.244440-1-mkl@pengutronix.de +Fixes: 55e5b97f003e ("can: mcp25xxfd: add driver for Microchip MCP25xxFD SPI CAN") +Reported-by: Rasmus Villemoes +Reviewed-by: Manivannan Sadhasivam +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Denis Kirjanov +--- + drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +index cb21ff707702..100cd7d3b244 100644 +--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c ++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +@@ -2685,7 +2685,7 @@ mcp251xfd_register_get_dev_id(const struct mcp251xfd_priv *priv, + xfer[0].tx_buf = buf_tx; + xfer[0].len = sizeof(buf_tx->cmd); + xfer[1].rx_buf = buf_rx->data; +- xfer[1].len = sizeof(dev_id); ++ xfer[1].len = sizeof(*dev_id); + + mcp251xfd_spi_cmd_read_nocrc(&buf_tx->cmd, MCP251XFD_REG_DEVID); + err = spi_sync_transfer(priv->spi, xfer, ARRAY_SIZE(xfer)); +-- +2.16.4 + diff --git a/patches.suse/can-rx-offload-can_rx_offload_init_queue-fix-typo.patch b/patches.suse/can-rx-offload-can_rx_offload_init_queue-fix-typo.patch new file mode 100644 index 0000000..fbb4373 --- /dev/null +++ b/patches.suse/can-rx-offload-can_rx_offload_init_queue-fix-typo.patch @@ -0,0 +1,39 @@ +From 766108d91246530d31b42765046f7ec2d1e42581 Mon Sep 17 00:00:00 2001 +From: Marc Kleine-Budde +Date: Wed, 10 Aug 2022 21:38:00 +0200 +Subject: [PATCH] can: rx-offload: can_rx_offload_init_queue(): fix typo +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 766108d91246530d31b42765046f7ec2d1e42581 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Fix typo "rounted" -> "rounded". + +Link: https://lore.kernel.org/all/20220811093617.1861938-2-mkl@pengutronix.de +Fixes: d254586c3453 ("can: rx-offload: Add support for HW fifo based irq offloading") +Reported-by: Uwe Kleine-König +Signed-off-by: Marc Kleine-Budde +Acked-by: Takashi Iwai + +--- + drivers/net/can/dev/rx-offload.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/can/dev/rx-offload.c b/drivers/net/can/dev/rx-offload.c +index a32a01c172d4..ad8eb243fe78 100644 +--- a/drivers/net/can/dev/rx-offload.c ++++ b/drivers/net/can/dev/rx-offload.c +@@ -329,7 +329,7 @@ static int can_rx_offload_init_queue(struct net_device *dev, + { + offload->dev = dev; + +- /* Limit queue len to 4x the weight (rounted to next power of two) */ ++ /* Limit queue len to 4x the weight (rounded to next power of two) */ + offload->skb_queue_len_max = 2 << fls(weight); + offload->skb_queue_len_max *= 4; + skb_queue_head_init(&offload->skb_queue); +-- +2.35.3 + diff --git a/patches.suse/cgroup-Add-missing-cpus_read_lock-to-cgroup_attach_task_all.patch b/patches.suse/cgroup-Add-missing-cpus_read_lock-to-cgroup_attach_task_all.patch new file mode 100644 index 0000000..95686dd --- /dev/null +++ b/patches.suse/cgroup-Add-missing-cpus_read_lock-to-cgroup_attach_task_all.patch @@ -0,0 +1,44 @@ +From: Tetsuo Handa +Date: Thu, 25 Aug 2022 17:38:38 +0900 +Subject: cgroup: Add missing cpus_read_lock() to cgroup_attach_task_all() +Git-commit: 43626dade36fa74d3329046f4ae2d7fdefe401c6 +Patch-mainline: v6.0-rc3 +References: bsc#1196869 + +syzbot is hitting percpu_rwsem_assert_held(&cpu_hotplug_lock) warning at +cpuset_attach() [1], for commit 4f7e7236435ca0ab ("cgroup: Fix +threadgroup_rwsem <-> cpus_read_lock() deadlock") missed that +cpuset_attach() is also called from cgroup_attach_task_all(). +Add cpus_read_lock() like what cgroup_procs_write_start() does. + +Link: https://syzkaller.appspot.com/bug?extid=29d3a3b4d86c8136ad9e [1] +Reported-by: syzbot +Signed-off-by: Tetsuo Handa +Fixes: 4f7e7236435ca0ab ("cgroup: Fix threadgroup_rwsem <-> cpus_read_lock() deadlock") +Signed-off-by: Tejun Heo +Acked-by: Michal Koutný +--- + kernel/cgroup/cgroup-v1.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/kernel/cgroup/cgroup-v1.c b/kernel/cgroup/cgroup-v1.c +index 2ade21b54dc4..ff6a8099eb2a 100644 +--- a/kernel/cgroup/cgroup-v1.c ++++ b/kernel/cgroup/cgroup-v1.c +@@ -59,6 +59,7 @@ int cgroup_attach_task_all(struct task_struct *from, struct task_struct *tsk) + int retval = 0; + + mutex_lock(&cgroup_mutex); ++ cpus_read_lock(); + percpu_down_write(&cgroup_threadgroup_rwsem); + for_each_root(root) { + struct cgroup *from_cgrp; +@@ -72,6 +73,7 @@ int cgroup_attach_task_all(struct task_struct *from, struct task_struct *tsk) + break; + } + percpu_up_write(&cgroup_threadgroup_rwsem); ++ cpus_read_unlock(); + mutex_unlock(&cgroup_mutex); + + return retval; + diff --git a/patches.suse/cgroup-Fix-race-condition-at-rebind_subsystems.patch b/patches.suse/cgroup-Fix-race-condition-at-rebind_subsystems.patch new file mode 100644 index 0000000..6c5dd54 --- /dev/null +++ b/patches.suse/cgroup-Fix-race-condition-at-rebind_subsystems.patch @@ -0,0 +1,45 @@ +From: Jing-Ting Wu +Date: Tue, 23 Aug 2022 13:41:46 +0800 +Subject: cgroup: Fix race condition at rebind_subsystems() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Git-commit: 763f4fb76e24959c370cdaa889b2492ba6175580 +Patch-mainline: v6.0-rc3 +References: bsc#1203902 + +Root cause: +The rebind_subsystems() is no lock held when move css object from A +list to B list,then let B's head be treated as css node at +list_for_each_entry_rcu(). + +Solution: +Add grace period before invalidating the removed rstat_css_node. + +Reported-by: Jing-Ting Wu +Suggested-by: Michal Koutný +Signed-off-by: Jing-Ting Wu +Tested-by: Jing-Ting Wu +Link: https://lore.kernel.org/linux-arm-kernel/d8f0bc5e2fb6ed259f9334c83279b4c011283c41.camel@mediatek.com/T/ +Acked-by: Mukesh Ojha +Fixes: a7df69b81aac ("cgroup: rstat: support cgroup1") +Cc: stable@vger.kernel.org # v5.13+ +Signed-off-by: Tejun Heo +Acked-by: Michal Koutný +--- + kernel/cgroup/cgroup.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c +index e1387499b336..e4bb5d57f4d1 100644 +--- a/kernel/cgroup/cgroup.c ++++ b/kernel/cgroup/cgroup.c +@@ -1820,6 +1820,7 @@ int rebind_subsystems(struct cgroup_root *dst_root, u16 ss_mask) + + if (ss->css_rstat_flush) { + list_del_rcu(&css->rstat_css_node); ++ synchronize_rcu(); + list_add_rcu(&css->rstat_css_node, + &dcgrp->rstat_css_list); + } + diff --git a/patches.suse/cgroup-Fix-threadgroup_rwsem-cpus_read_lock-deadlock.patch b/patches.suse/cgroup-Fix-threadgroup_rwsem-cpus_read_lock-deadlock.patch new file mode 100644 index 0000000..1521a18 --- /dev/null +++ b/patches.suse/cgroup-Fix-threadgroup_rwsem-cpus_read_lock-deadlock.patch @@ -0,0 +1,197 @@ +From: Tejun Heo +Date: Mon, 15 Aug 2022 13:27:38 -1000 +Subject: cgroup: Fix threadgroup_rwsem <-> cpus_read_lock() deadlock +Git-commit: 4f7e7236435ca0abe005c674ebd6892c6e83aeb3 +Patch-mainline: v6.0-rc3 +References: bsc#1196869 + +Bringing up a CPU may involve creating and destroying tasks which requires +read-locking threadgroup_rwsem, so threadgroup_rwsem nests inside +cpus_read_lock(). However, cpuset's ->attach(), which may be called with +thredagroup_rwsem write-locked, also wants to disable CPU hotplug and +acquires cpus_read_lock(), leading to a deadlock. + +Fix it by guaranteeing that ->attach() is always called with CPU hotplug +disabled and removing cpus_read_lock() call from cpuset_attach(). + +Signed-off-by: Tejun Heo +Reviewed-and-tested-by: Imran Khan +Reported-and-tested-by: Xuewen Yan +Fixes: 05c7b7a92cc8 ("cgroup/cpuset: Fix a race between cpuset_attach() and cpu hotplug") +Cc: stable@vger.kernel.org # v5.17+ +[mkoutny: Adjust for missing 671c11f0619e cgroup: Elide write-locking threadgroup_rwsem when updating csses on an empty subtree] +Acked-by: Michal Koutný +--- + kernel/cgroup/cgroup.c | 75 +++++++++++++++++++++++++++++++++++-------------- + kernel/cgroup/cpuset.c | 3 - + 2 files changed, 55 insertions(+), 23 deletions(-) + +--- a/kernel/cgroup/cgroup.c ++++ b/kernel/cgroup/cgroup.c +@@ -2345,6 +2345,47 @@ int task_cgroup_path(struct task_struct + EXPORT_SYMBOL_GPL(task_cgroup_path); + + /** ++ * cgroup_attach_lock - Lock for ->attach() ++ * @lock_threadgroup: whether to down_write cgroup_threadgroup_rwsem ++ * ++ * cgroup migration sometimes needs to stabilize threadgroups against forks and ++ * exits by write-locking cgroup_threadgroup_rwsem. However, some ->attach() ++ * implementations (e.g. cpuset), also need to disable CPU hotplug. ++ * Unfortunately, letting ->attach() operations acquire cpus_read_lock() can ++ * lead to deadlocks. ++ * ++ * Bringing up a CPU may involve creating and destroying tasks which requires ++ * read-locking threadgroup_rwsem, so threadgroup_rwsem nests inside ++ * cpus_read_lock(). If we call an ->attach() which acquires the cpus lock while ++ * write-locking threadgroup_rwsem, the locking order is reversed and we end up ++ * waiting for an on-going CPU hotplug operation which in turn is waiting for ++ * the threadgroup_rwsem to be released to create new tasks. For more details: ++ * ++ * http://lkml.kernel.org/r/20220711174629.uehfmqegcwn2lqzu@wubuntu ++ * ++ * Resolve the situation by always acquiring cpus_read_lock() before optionally ++ * write-locking cgroup_threadgroup_rwsem. This allows ->attach() to assume that ++ * CPU hotplug is disabled on entry. ++ */ ++static void cgroup_attach_lock(bool lock_threadgroup) ++{ ++ cpus_read_lock(); ++ if (lock_threadgroup) ++ percpu_down_write(&cgroup_threadgroup_rwsem); ++} ++ ++/** ++ * cgroup_attach_unlock - Undo cgroup_attach_lock() ++ * @lock_threadgroup: whether to up_write cgroup_threadgroup_rwsem ++ */ ++static void cgroup_attach_unlock(bool lock_threadgroup) ++{ ++ if (lock_threadgroup) ++ percpu_up_write(&cgroup_threadgroup_rwsem); ++ cpus_read_unlock(); ++} ++ ++/** + * cgroup_migrate_add_task - add a migration target task to a migration context + * @task: target task + * @mgctx: target migration context +@@ -2820,8 +2861,7 @@ int cgroup_attach_task(struct cgroup *ds + } + + struct task_struct *cgroup_procs_write_start(char *buf, bool threadgroup, +- bool *locked) +- __acquires(&cgroup_threadgroup_rwsem) ++ bool *threadgroup_locked) + { + struct task_struct *tsk; + pid_t pid; +@@ -2838,12 +2878,8 @@ struct task_struct *cgroup_procs_write_s + * Therefore, we can skip the global lock. + */ + lockdep_assert_held(&cgroup_mutex); +- if (pid || threadgroup) { +- percpu_down_write(&cgroup_threadgroup_rwsem); +- *locked = true; +- } else { +- *locked = false; +- } ++ *threadgroup_locked = pid || threadgroup; ++ cgroup_attach_lock(*threadgroup_locked); + + rcu_read_lock(); + if (pid) { +@@ -2874,17 +2910,14 @@ struct task_struct *cgroup_procs_write_s + goto out_unlock_rcu; + + out_unlock_threadgroup: +- if (*locked) { +- percpu_up_write(&cgroup_threadgroup_rwsem); +- *locked = false; +- } ++ cgroup_attach_unlock(*threadgroup_locked); ++ *threadgroup_locked = false; + out_unlock_rcu: + rcu_read_unlock(); + return tsk; + } + +-void cgroup_procs_write_finish(struct task_struct *task, bool locked) +- __releases(&cgroup_threadgroup_rwsem) ++void cgroup_procs_write_finish(struct task_struct *task, bool threadgroup_locked) + { + struct cgroup_subsys *ss; + int ssid; +@@ -2892,8 +2925,8 @@ void cgroup_procs_write_finish(struct ta + /* release reference from cgroup_procs_write_start() */ + put_task_struct(task); + +- if (locked) +- percpu_up_write(&cgroup_threadgroup_rwsem); ++ cgroup_attach_unlock(threadgroup_locked); ++ + for_each_subsys(ss, ssid) + if (ss->post_attach) + ss->post_attach(); +@@ -2952,7 +2985,7 @@ static int cgroup_update_dfl_csses(struc + + lockdep_assert_held(&cgroup_mutex); + +- percpu_down_write(&cgroup_threadgroup_rwsem); ++ cgroup_attach_lock(true); + + /* look up all csses currently attached to @cgrp's subtree */ + spin_lock_irq(&css_set_lock); +@@ -2983,7 +3016,7 @@ static int cgroup_update_dfl_csses(struc + ret = cgroup_migrate_execute(&mgctx); + out_finish: + cgroup_migrate_finish(&mgctx); +- percpu_up_write(&cgroup_threadgroup_rwsem); ++ cgroup_attach_unlock(true); + return ret; + } + +@@ -4931,13 +4964,13 @@ static ssize_t __cgroup_procs_write(stru + struct task_struct *task; + const struct cred *saved_cred; + ssize_t ret; +- bool locked; ++ bool threadgroup_locked; + + dst_cgrp = cgroup_kn_lock_live(of->kn, false); + if (!dst_cgrp) + return -ENODEV; + +- task = cgroup_procs_write_start(buf, threadgroup, &locked); ++ task = cgroup_procs_write_start(buf, threadgroup, &threadgroup_locked); + ret = PTR_ERR_OR_ZERO(task); + if (ret) + goto out_unlock; +@@ -4963,7 +4996,7 @@ static ssize_t __cgroup_procs_write(stru + ret = cgroup_attach_task(dst_cgrp, task, threadgroup); + + out_finish: +- cgroup_procs_write_finish(task, locked); ++ cgroup_procs_write_finish(task, threadgroup_locked); + out_unlock: + cgroup_kn_unlock(of->kn); + +--- a/kernel/cgroup/cpuset.c ++++ b/kernel/cgroup/cpuset.c +@@ -2254,7 +2254,7 @@ static void cpuset_attach(struct cgroup_ + cgroup_taskset_first(tset, &css); + cs = css_cs(css); + +- cpus_read_lock(); ++ lockdep_assert_cpus_held(); /* see cgroup_attach_lock() */ + percpu_down_write(&cpuset_rwsem); + + /* prepare for attach */ +@@ -2310,7 +2310,6 @@ static void cpuset_attach(struct cgroup_ + wake_up(&cpuset_attach_wq); + + percpu_up_write(&cpuset_rwsem); +- cpus_read_unlock(); + } + + /* The various types of files and directories in a cpuset file system */ diff --git a/patches.suse/cgroup-cgroup_get_from_id-must-check-the-looked-up-kn-is-a-directory.patch b/patches.suse/cgroup-cgroup_get_from_id-must-check-the-looked-up-kn-is-a-directory.patch new file mode 100644 index 0000000..8a47c73 --- /dev/null +++ b/patches.suse/cgroup-cgroup_get_from_id-must-check-the-looked-up-kn-is-a-directory.patch @@ -0,0 +1,41 @@ +From: Ming Lei +Date: Fri, 23 Sep 2022 19:51:19 +0800 +Subject: cgroup: cgroup_get_from_id() must check the looked-up kn is a + directory +Git-commit: df02452f3df069a59bc9e69c84435bf115cb6e37 +Patch-mainline: v6.0-rc7 +References: bsc#1203906 + +cgroup has to be one kernfs dir, otherwise kernel panic is caused, +especially cgroup id is provide from userspace. + +Reported-by: Marco Patalano +Fixes: 6b658c4863c1 ("scsi: cgroup: Add cgroup_get_from_id()") +Cc: Muneendra +Signed-off-by: Ming Lei +Acked-by: Mukesh Ojha +Cc: stable@vger.kernel.org # v5.14+ +Signed-off-by: Tejun Heo +[mkoutny: adjust context] +Acked-by: Michal Koutný +--- + kernel/cgroup/cgroup.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/kernel/cgroup/cgroup.c ++++ b/kernel/cgroup/cgroup.c +@@ -6018,9 +6018,13 @@ struct cgroup *cgroup_get_from_id(u64 id + if (!kn) + goto out_unlock; + ++ if (kernfs_type(kn) != KERNFS_DIR) ++ goto put; ++ + cgrp = kn->priv; + if (cgroup_is_dead(cgrp) || !cgroup_tryget(cgrp)) + cgrp = NULL; ++put: + kernfs_put(kn); + out_unlock: + mutex_unlock(&cgroup_mutex); + diff --git a/patches.suse/char-pcmcia-synclink_cs-Fix-use-after-free-in-mgslpc.patch b/patches.suse/char-pcmcia-synclink_cs-Fix-use-after-free-in-mgslpc.patch new file mode 100644 index 0000000..03ac77e --- /dev/null +++ b/patches.suse/char-pcmcia-synclink_cs-Fix-use-after-free-in-mgslpc.patch @@ -0,0 +1,134 @@ +From: Hyunwoo Kim +Date: Sun, 18 Sep 2022 21:02:51 -0700 +Subject: [PATCH] char: pcmcia: synclink_cs: Fix use-after-free in mgslpc_ops +Message-ID: <20220919040251.GA302541@ubuntu> +Patch-mainline: Submitted, LKML +References: CVE-2022-41848 bsc#1203987 + +A race condition may occur if the user physically removes +the pcmcia device while calling ioctl() for this tty device node. + +This is a race condition between the mgslpc_ioctl() function and +the mgslpc_detach() function, which may eventually result in UAF. + +So, add a refcount check to mgslpc_detach() to free the structure +after the tty device node is close()d. + +Signed-off-by: Hyunwoo Kim +Signed-off-by: Takashi Iwai + +--- + drivers/char/pcmcia/synclink_cs.c | 35 +++++++++++++++++++++++++------ + 1 file changed, 29 insertions(+), 6 deletions(-) + +diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c +index 8fc49b038372..0dfba8833a67 100644 +--- a/drivers/char/pcmcia/synclink_cs.c ++++ b/drivers/char/pcmcia/synclink_cs.c +@@ -216,7 +216,8 @@ typedef struct _mgslpc_info { + + /* PCMCIA support */ + struct pcmcia_device *p_dev; +- int stop; ++ int stop; ++ struct kref refcnt; + + /* SPPP/Cisco HDLC device parts */ + int netcount; +@@ -228,6 +229,8 @@ typedef struct _mgslpc_info { + + } MGSLPC_INFO; + ++static DEFINE_MUTEX(remove_mutex); ++ + #define MGSLPC_MAGIC 0x5402 + + /* +@@ -468,10 +471,21 @@ static void mgslpc_wait_until_sent(struct tty_struct *tty, int timeout); + + /* PCMCIA prototypes */ + ++static void mgslpc_delete(struct kref *kref); + static int mgslpc_config(struct pcmcia_device *link); + static void mgslpc_release(u_long arg); + static void mgslpc_detach(struct pcmcia_device *p_dev); + ++static void mgslpc_delete(struct kref *kref) ++{ ++ MGSLPC_INFO *info = container_of(kref, MGSLPC_INFO, refcnt); ++ struct pcmcia_device *link = info->p_dev; ++ ++ mgslpc_release((u_long)link); ++ ++ mgslpc_remove_device(info); ++} ++ + /* + * 1st function defined in .text section. Calling this function in + * init_module() followed by a breakpoint allows a remote debugger +@@ -534,6 +548,7 @@ static int mgslpc_probe(struct pcmcia_device *link) + init_waitqueue_head(&info->event_wait_q); + spin_lock_init(&info->lock); + spin_lock_init(&info->netlock); ++ kref_init(&info->refcnt); + memcpy(&info->params,&default_params,sizeof(MGSL_PARAMS)); + info->idle_mode = HDLC_TXIDLE_FLAGS; + info->imra_value = 0xffff; +@@ -620,13 +635,15 @@ static void mgslpc_release(u_long arg) + + static void mgslpc_detach(struct pcmcia_device *link) + { ++ MGSLPC_INFO *info = link->priv; ++ ++ mutex_lock(&remove_mutex); + if (debug_level >= DEBUG_LEVEL_INFO) + printk("mgslpc_detach(0x%p)\n", link); + +- ((MGSLPC_INFO *)link->priv)->stop = 1; +- mgslpc_release((u_long)link); +- +- mgslpc_remove_device((MGSLPC_INFO *)link->priv); ++ info->stop = 1; ++ kref_put(&info->refcnt, mgslpc_delete); ++ mutex_unlock(&remove_mutex); + } + + static int mgslpc_suspend(struct pcmcia_device *link) +@@ -2341,10 +2358,13 @@ static void mgslpc_close(struct tty_struct *tty, struct file * filp) + + tty_port_close_end(port, tty); + tty_port_tty_set(port, NULL); ++ + cleanup: + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):mgslpc_close(%s) exit, count=%d\n", __FILE__, __LINE__, + tty->driver->name, port->count); ++ ++ kref_put(&info->refcnt, mgslpc_delete); + } + + /* Wait until the transmitter is empty. +@@ -2465,6 +2485,8 @@ static int mgslpc_open(struct tty_struct *tty, struct file * filp) + int retval, line; + unsigned long flags; + ++ mutex_lock(&remove_mutex); ++ + /* verify range of specified line number */ + line = tty->index; + if (line >= mgslpc_device_count) { +@@ -2517,9 +2539,10 @@ static int mgslpc_open(struct tty_struct *tty, struct file * filp) + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):mgslpc_open(%s) success\n", + __FILE__, __LINE__, info->device_name); +- retval = 0; + ++ kref_get(&info->refcnt); + cleanup: ++ mutex_unlock(&remove_mutex); + return retval; + } + +-- +2.35.3 + diff --git a/patches.suse/clk-ast2600-BCLK-comes-from-EPLL.patch b/patches.suse/clk-ast2600-BCLK-comes-from-EPLL.patch new file mode 100644 index 0000000..fff2af3 --- /dev/null +++ b/patches.suse/clk-ast2600-BCLK-comes-from-EPLL.patch @@ -0,0 +1,38 @@ +From b8c1dc9c00b252b3be853720a71b05ed451ddd9f Mon Sep 17 00:00:00 2001 +From: Joel Stanley +Date: Thu, 21 Apr 2022 13:34:26 +0930 +Subject: [PATCH] clk: ast2600: BCLK comes from EPLL +Git-commit: b8c1dc9c00b252b3be853720a71b05ed451ddd9f +Patch-mainline: v6.1-rc1 +References: git-fixes + +This correction was made in the u-boot SDK recently. There are no +in-tree users of this clock so the impact is minimal. + +Fixes: d3d04f6c330a ("clk: Add support for AST2600 SoC") +Link: https://github.com/AspeedTech-BMC/u-boot/commit/8ad54a5ae15f27fea5e894cc2539a20d90019717 +Signed-off-by: Joel Stanley +Link: https://lore.kernel.org/r/20220421040426.171256-1-joel@jms.id.au +Signed-off-by: Stephen Boyd +Acked-by: Takashi Iwai + +--- + drivers/clk/clk-ast2600.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/clk/clk-ast2600.c b/drivers/clk/clk-ast2600.c +index 24dab2312bc6..9c3305bcb27a 100644 +--- a/drivers/clk/clk-ast2600.c ++++ b/drivers/clk/clk-ast2600.c +@@ -622,7 +622,7 @@ static int aspeed_g6_clk_probe(struct platform_device *pdev) + regmap_write(map, 0x308, 0x12000); /* 3x3 = 9 */ + + /* P-Bus (BCLK) clock divider */ +- hw = clk_hw_register_divider_table(dev, "bclk", "hpll", 0, ++ hw = clk_hw_register_divider_table(dev, "bclk", "epll", 0, + scu_g6_base + ASPEED_G6_CLK_SELECTION1, 20, 3, 0, + ast2600_div_table, + &aspeed_g6_clk_lock); +-- +2.35.3 + diff --git a/patches.suse/clk-at91-fix-the-build-with-binutils-2.27.patch b/patches.suse/clk-at91-fix-the-build-with-binutils-2.27.patch new file mode 100644 index 0000000..a31ef85 --- /dev/null +++ b/patches.suse/clk-at91-fix-the-build-with-binutils-2.27.patch @@ -0,0 +1,52 @@ +From 57d849636a04a12713dd3a10a97cb9658ec7edf6 Mon Sep 17 00:00:00 2001 +From: Kefeng Wang +Date: Wed, 12 Oct 2022 11:06:35 +0800 +Subject: [PATCH] clk: at91: fix the build with binutils 2.27 +Git-commit: 57d849636a04a12713dd3a10a97cb9658ec7edf6 +Patch-mainline: v6.1-rc1 +References: git-fixes + +There is an issue when build with older versions of binutils 2.27.0, + +Arch/arm/mach-at91/pm_suspend.s: Assembler messages: +arch/arm/mach-at91/pm_suspend.S:1086: Error: garbage following instruction -- `ldr tmp1,=0x00020010UL' + +Use UL() macro to fix the issue in assembly file. + +Fixes: 4fd36e458392 ("ARM: at91: pm: add plla disable/enable support for sam9x60") +Signed-off-by: Kefeng Wang +Link: https://lore.kernel.org/r/20221012030635.13140-1-wangkefeng.wang@huawei.com +Signed-off-by: Stephen Boyd +Acked-by: Takashi Iwai + +--- + include/linux/clk/at91_pmc.h | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/include/linux/clk/at91_pmc.h b/include/linux/clk/at91_pmc.h +index 3484309b59bf..7af499bdbecb 100644 +--- a/include/linux/clk/at91_pmc.h ++++ b/include/linux/clk/at91_pmc.h +@@ -12,6 +12,8 @@ + #ifndef AT91_PMC_H + #define AT91_PMC_H + ++#include ++ + #define AT91_PMC_V1 (1) /* PMC version 1 */ + #define AT91_PMC_V2 (2) /* PMC version 2 [SAM9X60] */ + +@@ -45,8 +47,8 @@ + #define AT91_PMC_PCSR 0x18 /* Peripheral Clock Status Register */ + + #define AT91_PMC_PLL_ACR 0x18 /* PLL Analog Control Register [for SAM9X60] */ +-#define AT91_PMC_PLL_ACR_DEFAULT_UPLL 0x12020010UL /* Default PLL ACR value for UPLL */ +-#define AT91_PMC_PLL_ACR_DEFAULT_PLLA 0x00020010UL /* Default PLL ACR value for PLLA */ ++#define AT91_PMC_PLL_ACR_DEFAULT_UPLL UL(0x12020010) /* Default PLL ACR value for UPLL */ ++#define AT91_PMC_PLL_ACR_DEFAULT_PLLA UL(0x00020010) /* Default PLL ACR value for PLLA */ + #define AT91_PMC_PLL_ACR_UTMIVR (1 << 12) /* UPLL Voltage regulator Control */ + #define AT91_PMC_PLL_ACR_UTMIBG (1 << 13) /* UPLL Bandgap Control */ + +-- +2.35.3 + diff --git a/patches.suse/clk-baikal-t1-Add-SATA-internal-ref-clock-buffer.patch b/patches.suse/clk-baikal-t1-Add-SATA-internal-ref-clock-buffer.patch new file mode 100644 index 0000000..7ee7b77 --- /dev/null +++ b/patches.suse/clk-baikal-t1-Add-SATA-internal-ref-clock-buffer.patch @@ -0,0 +1,234 @@ +From 081a9b7c74eae4e12b2cb1b86720f836a8f29247 Mon Sep 17 00:00:00 2001 +From: Serge Semin +Date: Fri, 30 Sep 2022 01:53:58 +0300 +Subject: [PATCH] clk: baikal-t1: Add SATA internal ref clock buffer +Git-commit: 081a9b7c74eae4e12b2cb1b86720f836a8f29247 +Patch-mainline: v6.1-rc1 +References: git-fixes + +It turns out the internal SATA reference clock signal will stay +unavailable for the SATA interface consumer until the buffer on it's way +is ungated. So aside with having the actual clock divider enabled we need +to ungate a buffer placed on the signal way to the SATA controller (most +likely some rudiment from the initial SoC release). Seeing the switch flag +is placed in the same register as the SATA-ref clock divider at a +non-standard ffset, let's implement it as a separate clock controller with +the set-rate propagation to the parental clock divider wrapper. As such +we'll be able to disable/enable and still change the original clock source +rate. + +Fixes: 353afa3a8d2e ("clk: Add Baikal-T1 CCU Dividers driver") +Signed-off-by: Serge Semin +Link: https://lore.kernel.org/r/20220929225402.9696-5-Sergey.Semin@baikalelectronics.ru +Signed-off-by: Stephen Boyd +Acked-by: Takashi Iwai + +--- + drivers/clk/baikal-t1/ccu-div.c | 64 +++++++++++++++++++++++++++++ + drivers/clk/baikal-t1/ccu-div.h | 4 ++ + drivers/clk/baikal-t1/clk-ccu-div.c | 18 +++++++- + 3 files changed, 85 insertions(+), 1 deletion(-) + +diff --git a/drivers/clk/baikal-t1/ccu-div.c b/drivers/clk/baikal-t1/ccu-div.c +index bbfa3526ee10..a6642f3d33d4 100644 +--- a/drivers/clk/baikal-t1/ccu-div.c ++++ b/drivers/clk/baikal-t1/ccu-div.c +@@ -34,6 +34,7 @@ + #define CCU_DIV_CTL_CLKDIV_MASK(_width) \ + GENMASK((_width) + CCU_DIV_CTL_CLKDIV_FLD - 1, CCU_DIV_CTL_CLKDIV_FLD) + #define CCU_DIV_CTL_LOCK_SHIFTED BIT(27) ++#define CCU_DIV_CTL_GATE_REF_BUF BIT(28) + #define CCU_DIV_CTL_LOCK_NORMAL BIT(31) + + #define CCU_DIV_RST_DELAY_US 1 +@@ -170,6 +171,40 @@ static int ccu_div_gate_is_enabled(struct clk_hw *hw) + return !!(val & CCU_DIV_CTL_EN); + } + ++static int ccu_div_buf_enable(struct clk_hw *hw) ++{ ++ struct ccu_div *div = to_ccu_div(hw); ++ unsigned long flags; ++ ++ spin_lock_irqsave(&div->lock, flags); ++ regmap_update_bits(div->sys_regs, div->reg_ctl, ++ CCU_DIV_CTL_GATE_REF_BUF, 0); ++ spin_unlock_irqrestore(&div->lock, flags); ++ ++ return 0; ++} ++ ++static void ccu_div_buf_disable(struct clk_hw *hw) ++{ ++ struct ccu_div *div = to_ccu_div(hw); ++ unsigned long flags; ++ ++ spin_lock_irqsave(&div->lock, flags); ++ regmap_update_bits(div->sys_regs, div->reg_ctl, ++ CCU_DIV_CTL_GATE_REF_BUF, CCU_DIV_CTL_GATE_REF_BUF); ++ spin_unlock_irqrestore(&div->lock, flags); ++} ++ ++static int ccu_div_buf_is_enabled(struct clk_hw *hw) ++{ ++ struct ccu_div *div = to_ccu_div(hw); ++ u32 val = 0; ++ ++ regmap_read(div->sys_regs, div->reg_ctl, &val); ++ ++ return !(val & CCU_DIV_CTL_GATE_REF_BUF); ++} ++ + static unsigned long ccu_div_var_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) + { +@@ -323,6 +358,7 @@ static const struct ccu_div_dbgfs_bit ccu_div_bits[] = { + CCU_DIV_DBGFS_BIT_ATTR("div_en", CCU_DIV_CTL_EN), + CCU_DIV_DBGFS_BIT_ATTR("div_rst", CCU_DIV_CTL_RST), + CCU_DIV_DBGFS_BIT_ATTR("div_bypass", CCU_DIV_CTL_SET_CLKDIV), ++ CCU_DIV_DBGFS_BIT_ATTR("div_buf", CCU_DIV_CTL_GATE_REF_BUF), + CCU_DIV_DBGFS_BIT_ATTR("div_lock", CCU_DIV_CTL_LOCK_NORMAL) + }; + +@@ -441,6 +477,9 @@ static void ccu_div_var_debug_init(struct clk_hw *hw, struct dentry *dentry) + continue; + } + ++ if (!strcmp("div_buf", name)) ++ continue; ++ + bits[didx] = ccu_div_bits[bidx]; + bits[didx].div = div; + +@@ -477,6 +516,21 @@ static void ccu_div_gate_debug_init(struct clk_hw *hw, struct dentry *dentry) + &ccu_div_dbgfs_fixed_clkdiv_fops); + } + ++static void ccu_div_buf_debug_init(struct clk_hw *hw, struct dentry *dentry) ++{ ++ struct ccu_div *div = to_ccu_div(hw); ++ struct ccu_div_dbgfs_bit *bit; ++ ++ bit = kmalloc(sizeof(*bit), GFP_KERNEL); ++ if (!bit) ++ return; ++ ++ *bit = ccu_div_bits[3]; ++ bit->div = div; ++ debugfs_create_file_unsafe(bit->name, ccu_div_dbgfs_mode, dentry, bit, ++ &ccu_div_dbgfs_bit_fops); ++} ++ + static void ccu_div_fixed_debug_init(struct clk_hw *hw, struct dentry *dentry) + { + struct ccu_div *div = to_ccu_div(hw); +@@ -489,6 +543,7 @@ static void ccu_div_fixed_debug_init(struct clk_hw *hw, struct dentry *dentry) + + #define ccu_div_var_debug_init NULL + #define ccu_div_gate_debug_init NULL ++#define ccu_div_buf_debug_init NULL + #define ccu_div_fixed_debug_init NULL + + #endif /* !CONFIG_DEBUG_FS */ +@@ -520,6 +575,13 @@ static const struct clk_ops ccu_div_gate_ops = { + .debug_init = ccu_div_gate_debug_init + }; + ++static const struct clk_ops ccu_div_buf_ops = { ++ .enable = ccu_div_buf_enable, ++ .disable = ccu_div_buf_disable, ++ .is_enabled = ccu_div_buf_is_enabled, ++ .debug_init = ccu_div_buf_debug_init ++}; ++ + static const struct clk_ops ccu_div_fixed_ops = { + .recalc_rate = ccu_div_fixed_recalc_rate, + .round_rate = ccu_div_fixed_round_rate, +@@ -566,6 +628,8 @@ struct ccu_div *ccu_div_hw_register(const struct ccu_div_init_data *div_init) + } else if (div_init->type == CCU_DIV_GATE) { + hw_init.ops = &ccu_div_gate_ops; + div->divider = div_init->divider; ++ } else if (div_init->type == CCU_DIV_BUF) { ++ hw_init.ops = &ccu_div_buf_ops; + } else if (div_init->type == CCU_DIV_FIXED) { + hw_init.ops = &ccu_div_fixed_ops; + div->divider = div_init->divider; +diff --git a/drivers/clk/baikal-t1/ccu-div.h b/drivers/clk/baikal-t1/ccu-div.h +index b6a9c8e45318..4eb49ff4803c 100644 +--- a/drivers/clk/baikal-t1/ccu-div.h ++++ b/drivers/clk/baikal-t1/ccu-div.h +@@ -15,8 +15,10 @@ + + /* + * CCU Divider private clock IDs ++ * @CCU_SYS_SATA_CLK: CCU SATA internal clock + * @CCU_SYS_XGMAC_CLK: CCU XGMAC internal clock + */ ++#define CCU_SYS_SATA_CLK -1 + #define CCU_SYS_XGMAC_CLK -2 + + /* +@@ -37,11 +39,13 @@ + * enum ccu_div_type - CCU Divider types + * @CCU_DIV_VAR: Clocks gate with variable divider. + * @CCU_DIV_GATE: Clocks gate with fixed divider. ++ * @CCU_DIV_BUF: Clock gate with no divider. + * @CCU_DIV_FIXED: Ungateable clock with fixed divider. + */ + enum ccu_div_type { + CCU_DIV_VAR, + CCU_DIV_GATE, ++ CCU_DIV_BUF, + CCU_DIV_FIXED + }; + +diff --git a/drivers/clk/baikal-t1/clk-ccu-div.c b/drivers/clk/baikal-t1/clk-ccu-div.c +index 3953ae5664be..90f4fda406ee 100644 +--- a/drivers/clk/baikal-t1/clk-ccu-div.c ++++ b/drivers/clk/baikal-t1/clk-ccu-div.c +@@ -76,6 +76,16 @@ + .divider = _divider \ + } + ++#define CCU_DIV_BUF_INFO(_id, _name, _pname, _base, _flags) \ ++ { \ ++ .id = _id, \ ++ .name = _name, \ ++ .parent_name = _pname, \ ++ .base = _base, \ ++ .type = CCU_DIV_BUF, \ ++ .flags = _flags \ ++ } ++ + #define CCU_DIV_FIXED_INFO(_id, _name, _pname, _divider) \ + { \ + .id = _id, \ +@@ -188,11 +198,14 @@ static const struct ccu_div_rst_map axi_rst_map[] = { + * for the SoC devices registers IO-operations. + */ + static const struct ccu_div_info sys_info[] = { +- CCU_DIV_VAR_INFO(CCU_SYS_SATA_REF_CLK, "sys_sata_ref_clk", ++ CCU_DIV_VAR_INFO(CCU_SYS_SATA_CLK, "sys_sata_clk", + "sata_clk", CCU_SYS_SATA_REF_BASE, 4, + CLK_SET_RATE_GATE, + CCU_DIV_SKIP_ONE | CCU_DIV_LOCK_SHIFTED | + CCU_DIV_RESET_DOMAIN), ++ CCU_DIV_BUF_INFO(CCU_SYS_SATA_REF_CLK, "sys_sata_ref_clk", ++ "sys_sata_clk", CCU_SYS_SATA_REF_BASE, ++ CLK_SET_RATE_PARENT), + CCU_DIV_VAR_INFO(CCU_SYS_APB_CLK, "sys_apb_clk", + "pcie_clk", CCU_SYS_APB_BASE, 5, + CLK_IS_CRITICAL, CCU_DIV_RESET_DOMAIN), +@@ -398,6 +411,9 @@ static int ccu_div_clk_register(struct ccu_div_data *data) + init.base = info->base; + init.sys_regs = data->sys_regs; + init.divider = info->divider; ++ } else if (init.type == CCU_DIV_BUF) { ++ init.base = info->base; ++ init.sys_regs = data->sys_regs; + } else { + init.divider = info->divider; + } +-- +2.35.3 + diff --git a/patches.suse/clk-baikal-t1-Add-shared-xGMAC-ref-ptp-clocks-intern.patch b/patches.suse/clk-baikal-t1-Add-shared-xGMAC-ref-ptp-clocks-intern.patch new file mode 100644 index 0000000..1e4caad --- /dev/null +++ b/patches.suse/clk-baikal-t1-Add-shared-xGMAC-ref-ptp-clocks-intern.patch @@ -0,0 +1,84 @@ +From e2eef312762e0b5a5a70d29fe59a245c0a3cffa0 Mon Sep 17 00:00:00 2001 +From: Serge Semin +Date: Fri, 30 Sep 2022 01:53:57 +0300 +Subject: [PATCH] clk: baikal-t1: Add shared xGMAC ref/ptp clocks internal parent +Git-commit: e2eef312762e0b5a5a70d29fe59a245c0a3cffa0 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Baikal-T1 CCU reference manual says that both xGMAC reference and xGMAC +PTP clocks are generated by two different wrappers with the same constant +divider thus each producing a 156.25 MHz signal. But for some reason both +of these clock sources are gated by a single switch-flag in the CCU +registers space - CCU_SYS_XGMAC_BASE.BIT(0). In order to make the clocks +handled independently we need to define a shared parental gate so the base +clock signal would be switched off only if both of the child-clocks are +disabled. + +Note the ID is intentionally set to -2 since we are going to add a one +more internal clock identifier in the next commit. + +Fixes: 353afa3a8d2e ("clk: Add Baikal-T1 CCU Dividers driver") +Signed-off-by: Serge Semin +Link: https://lore.kernel.org/r/20220929225402.9696-4-Sergey.Semin@baikalelectronics.ru +Signed-off-by: Stephen Boyd +Acked-by: Takashi Iwai + +--- + drivers/clk/baikal-t1/ccu-div.c | 1 + + drivers/clk/baikal-t1/ccu-div.h | 6 ++++++ + drivers/clk/baikal-t1/clk-ccu-div.c | 8 +++++--- + 3 files changed, 12 insertions(+), 3 deletions(-) + +diff --git a/drivers/clk/baikal-t1/ccu-div.c b/drivers/clk/baikal-t1/ccu-div.c +index 4062092d67f9..bbfa3526ee10 100644 +--- a/drivers/clk/baikal-t1/ccu-div.c ++++ b/drivers/clk/baikal-t1/ccu-div.c +@@ -579,6 +579,7 @@ struct ccu_div *ccu_div_hw_register(const struct ccu_div_init_data *div_init) + goto err_free_div; + } + parent_data.fw_name = div_init->parent_name; ++ parent_data.name = div_init->parent_name; + hw_init.parent_data = &parent_data; + hw_init.num_parents = 1; + +diff --git a/drivers/clk/baikal-t1/ccu-div.h b/drivers/clk/baikal-t1/ccu-div.h +index 795665caefbd..b6a9c8e45318 100644 +--- a/drivers/clk/baikal-t1/ccu-div.h ++++ b/drivers/clk/baikal-t1/ccu-div.h +@@ -13,6 +13,12 @@ + #include + #include + ++/* ++ * CCU Divider private clock IDs ++ * @CCU_SYS_XGMAC_CLK: CCU XGMAC internal clock ++ */ ++#define CCU_SYS_XGMAC_CLK -2 ++ + /* + * CCU Divider private flags + * @CCU_DIV_SKIP_ONE: Due to some reason divider can't be set to 1. +diff --git a/drivers/clk/baikal-t1/clk-ccu-div.c b/drivers/clk/baikal-t1/clk-ccu-div.c +index ea77eec40ddd..3953ae5664be 100644 +--- a/drivers/clk/baikal-t1/clk-ccu-div.c ++++ b/drivers/clk/baikal-t1/clk-ccu-div.c +@@ -204,10 +204,12 @@ static const struct ccu_div_info sys_info[] = { + "eth_clk", CCU_SYS_GMAC1_BASE, 5), + CCU_DIV_FIXED_INFO(CCU_SYS_GMAC1_PTP_CLK, "sys_gmac1_ptp_clk", + "eth_clk", 10), +- CCU_DIV_GATE_INFO(CCU_SYS_XGMAC_REF_CLK, "sys_xgmac_ref_clk", +- "eth_clk", CCU_SYS_XGMAC_BASE, 8), ++ CCU_DIV_GATE_INFO(CCU_SYS_XGMAC_CLK, "sys_xgmac_clk", ++ "eth_clk", CCU_SYS_XGMAC_BASE, 1), ++ CCU_DIV_FIXED_INFO(CCU_SYS_XGMAC_REF_CLK, "sys_xgmac_ref_clk", ++ "sys_xgmac_clk", 8), + CCU_DIV_FIXED_INFO(CCU_SYS_XGMAC_PTP_CLK, "sys_xgmac_ptp_clk", +- "eth_clk", 8), ++ "sys_xgmac_clk", 8), + CCU_DIV_GATE_INFO(CCU_SYS_USB_CLK, "sys_usb_clk", + "eth_clk", CCU_SYS_USB_BASE, 10), + CCU_DIV_VAR_INFO(CCU_SYS_PVT_CLK, "sys_pvt_clk", +-- +2.35.3 + diff --git a/patches.suse/clk-baikal-t1-Fix-invalid-xGMAC-PTP-clock-divider.patch b/patches.suse/clk-baikal-t1-Fix-invalid-xGMAC-PTP-clock-divider.patch new file mode 100644 index 0000000..a4d9c64 --- /dev/null +++ b/patches.suse/clk-baikal-t1-Fix-invalid-xGMAC-PTP-clock-divider.patch @@ -0,0 +1,38 @@ +From 3c742088686ce922704aec5b11d09bcc5a396589 Mon Sep 17 00:00:00 2001 +From: Serge Semin +Date: Fri, 30 Sep 2022 01:53:56 +0300 +Subject: [PATCH] clk: baikal-t1: Fix invalid xGMAC PTP clock divider +Git-commit: 3c742088686ce922704aec5b11d09bcc5a396589 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Most likely due to copy-paste mistake the divider has been set to 10 while +according to the SoC reference manual it's supposed to be 8 thus having +PTP clock frequency of 156.25 MHz. + +Fixes: 353afa3a8d2e ("clk: Add Baikal-T1 CCU Dividers driver") +Signed-off-by: Serge Semin +Link: https://lore.kernel.org/r/20220929225402.9696-3-Sergey.Semin@baikalelectronics.ru +Signed-off-by: Stephen Boyd +Acked-by: Takashi Iwai + +--- + drivers/clk/baikal-t1/clk-ccu-div.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/clk/baikal-t1/clk-ccu-div.c b/drivers/clk/baikal-t1/clk-ccu-div.c +index f141fda12b09..ea77eec40ddd 100644 +--- a/drivers/clk/baikal-t1/clk-ccu-div.c ++++ b/drivers/clk/baikal-t1/clk-ccu-div.c +@@ -207,7 +207,7 @@ static const struct ccu_div_info sys_info[] = { + CCU_DIV_GATE_INFO(CCU_SYS_XGMAC_REF_CLK, "sys_xgmac_ref_clk", + "eth_clk", CCU_SYS_XGMAC_BASE, 8), + CCU_DIV_FIXED_INFO(CCU_SYS_XGMAC_PTP_CLK, "sys_xgmac_ptp_clk", +- "eth_clk", 10), ++ "eth_clk", 8), + CCU_DIV_GATE_INFO(CCU_SYS_USB_CLK, "sys_usb_clk", + "eth_clk", CCU_SYS_USB_BASE, 10), + CCU_DIV_VAR_INFO(CCU_SYS_PVT_CLK, "sys_pvt_clk", +-- +2.35.3 + diff --git a/patches.suse/clk-bcm-rpi-Add-support-for-VEC-clock.patch b/patches.suse/clk-bcm-rpi-Add-support-for-VEC-clock.patch new file mode 100644 index 0000000..c4a243d --- /dev/null +++ b/patches.suse/clk-bcm-rpi-Add-support-for-VEC-clock.patch @@ -0,0 +1,46 @@ +From: Dom Cobley +Date: Mon, 29 Aug 2022 18:21:54 +0300 +Subject: clk: bcm: rpi: Add support for VEC clock +Git-commit: 1777cb60f7df80d9b4ca3385eca1d2c0bed61cb6 +Patch-mainline: v6.0 or v6.0-rc8 (next release) +References: bsc#1196632 + +Platform driver clk-bcm2835 gets an inaccurate clock for VEC (107MHz). +Export VEC clock trough clk-raspberrypi which uses the right PLL to +get an accurate 108MHz. + +Signed-off-by: Dom Cobley +[iivanov: Adapted on top of v5.17-rc6] +Signed-off-by: Ivan T. Ivanov +Link: https://lore.kernel.org/r/20220829152154.147250-4-iivanov@suse.de +Signed-off-by: Stephen Boyd +--- + drivers/clk/bcm/clk-raspberrypi.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/clk/bcm/clk-raspberrypi.c ++++ b/drivers/clk/bcm/clk-raspberrypi.c +@@ -33,6 +33,7 @@ enum rpi_firmware_clk_id { + RPI_FIRMWARE_EMMC2_CLK_ID, + RPI_FIRMWARE_M2MC_CLK_ID, + RPI_FIRMWARE_PIXEL_BVB_CLK_ID, ++ RPI_FIRMWARE_VEC_CLK_ID, + RPI_FIRMWARE_NUM_CLK_ID, + }; + +@@ -51,6 +52,7 @@ static char *rpi_firmware_clk_names[] = + [RPI_FIRMWARE_EMMC2_CLK_ID] = "emmc2", + [RPI_FIRMWARE_M2MC_CLK_ID] = "m2mc", + [RPI_FIRMWARE_PIXEL_BVB_CLK_ID] = "pixel-bvb", ++ [RPI_FIRMWARE_VEC_CLK_ID] = "vec", + }; + + #define RPI_FIRMWARE_STATE_ENABLE_BIT BIT(0) +@@ -277,6 +279,7 @@ static int raspberrypi_discover_clocks(s + case RPI_FIRMWARE_M2MC_CLK_ID: + case RPI_FIRMWARE_V3D_CLK_ID: + case RPI_FIRMWARE_PIXEL_BVB_CLK_ID: ++ case RPI_FIRMWARE_VEC_CLK_ID: + hw = raspberrypi_clk_register(rpi, clks->parent, + clks->id); + if (IS_ERR(hw)) diff --git a/patches.suse/clk-bcm2835-Round-UART-input-clock-up.patch b/patches.suse/clk-bcm2835-Round-UART-input-clock-up.patch new file mode 100644 index 0000000..75b1def --- /dev/null +++ b/patches.suse/clk-bcm2835-Round-UART-input-clock-up.patch @@ -0,0 +1,118 @@ +From: "Ivan T. Ivanov" +Date: Mon, 12 Sep 2022 11:13:04 +0300 +Subject: clk: bcm2835: Round UART input clock up +Git-commit: f690a4d7a8f66430662975511c86819dc9965bcc +Patch-mainline: v6.0 or v6.0-rc8 (next release) +References: bsc#1188238 + +It was reported that RPi3[1] and RPi Zero 2W boards have issues with +the Bluetooth. It turns out that when switching from initial to +operation speed host and device no longer can talk each other because +host uses incorrect UART baud rate. + +The UART driver used in this case is amba-pl011. Original fix, see +below Github link[2], was inside pl011 module, but somehow it didn't +look as the right place to fix. Beside that this original rounding +function is not exactly perfect for all possible clock values. So I +deiced to move the hack to the platform which actually need it. + +The UART clock is initialised to be as close to the requested +frequency as possible without exceeding it. Now that there is a +clock manager that returns the actual frequencies, an expected +48MHz clock is reported as 47999625. If the requested baud rate +== requested clock/16, there is no headroom and the slight +reduction in actual clock rate results in failure. + +If increasing a clock by less than 0.1% changes it from ..999.. +to ..000.., round it up. + +[1] https://bugzilla.suse.com/show_bug.cgi?id=1188238 +[2] https://github.com/raspberrypi/linux/commit/ab3f1b39537f6d3825b8873006fbe2fc5ff057b7 + +Cc: Phil Elwell +Signed-off-by: Ivan T. Ivanov +Reviewed-by: Stefan Wahren +Link: https://lore.kernel.org/r/20220912081306.24662-1-iivanov@suse.de +Signed-off-by: Stephen Boyd +--- + drivers/clk/bcm/clk-bcm2835.c | 35 +++++++++++++++++++++++++++++++++-- + 1 file changed, 33 insertions(+), 2 deletions(-) + +--- a/drivers/clk/bcm/clk-bcm2835.c ++++ b/drivers/clk/bcm/clk-bcm2835.c +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -502,6 +503,8 @@ struct bcm2835_clock_data { + bool low_jitter; + + u32 tcnt_mux; ++ ++ bool round_up; + }; + + struct bcm2835_gate_data { +@@ -994,12 +997,34 @@ static long bcm2835_clock_rate_from_divi + return temp; + } + ++static unsigned long bcm2835_round_rate(unsigned long rate) ++{ ++ unsigned long scaler; ++ unsigned long limit; ++ ++ limit = rate / 100000; ++ ++ scaler = 1; ++ while (scaler < limit) ++ scaler *= 10; ++ ++ /* ++ * If increasing a clock by less than 0.1% changes it ++ * from ..999.. to ..000.., round up. ++ */ ++ if ((rate + scaler - 1) / scaler % 1000 == 0) ++ rate = roundup(rate, scaler); ++ ++ return rate; ++} ++ + static unsigned long bcm2835_clock_get_rate(struct clk_hw *hw, + unsigned long parent_rate) + { + struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); + struct bcm2835_cprman *cprman = clock->cprman; + const struct bcm2835_clock_data *data = clock->data; ++ unsigned long rate; + u32 div; + + if (data->int_bits == 0 && data->frac_bits == 0) +@@ -1007,7 +1032,12 @@ static unsigned long bcm2835_clock_get_r + + div = cprman_read(cprman, data->div_reg); + +- return bcm2835_clock_rate_from_divisor(clock, parent_rate, div); ++ rate = bcm2835_clock_rate_from_divisor(clock, parent_rate, div); ++ ++ if (data->round_up) ++ rate = bcm2835_round_rate(rate); ++ ++ return rate; + } + + static void bcm2835_clock_wait_busy(struct bcm2835_clock *clock) +@@ -2144,7 +2174,8 @@ static const struct bcm2835_clk_desc clk + .div_reg = CM_UARTDIV, + .int_bits = 10, + .frac_bits = 12, +- .tcnt_mux = 28), ++ .tcnt_mux = 28, ++ .round_up = true), + + /* TV encoder clock. Only operating frequency is 108Mhz. */ + [BCM2835_CLOCK_VEC] = REGISTER_PER_CLK( diff --git a/patches.suse/clk-bcm2835-fix-bcm2835_clock_rate_from_divisor-decl.patch b/patches.suse/clk-bcm2835-fix-bcm2835_clock_rate_from_divisor-decl.patch new file mode 100644 index 0000000..560c0fe --- /dev/null +++ b/patches.suse/clk-bcm2835-fix-bcm2835_clock_rate_from_divisor-decl.patch @@ -0,0 +1,43 @@ +From 0b919a3728691c172312dee99ba654055ccd8c84 Mon Sep 17 00:00:00 2001 +From: Stefan Wahren +Date: Sun, 4 Sep 2022 16:10:37 +0200 +Subject: [PATCH] clk: bcm2835: fix bcm2835_clock_rate_from_divisor declaration +Git-commit: 0b919a3728691c172312dee99ba654055ccd8c84 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The return value of bcm2835_clock_rate_from_divisor is always unsigned +and also all caller expect this. So fix the declaration accordingly. + +Fixes: 41691b8862e2 ("clk: bcm2835: Add support for programming the audio domain clocks") +Signed-off-by: Stefan Wahren +Link: https://lore.kernel.org/r/20220904141037.38816-1-stefan.wahren@i2se.com +Reviewed-by: Ivan T. Ivanov +Reviewed-by: Florian Fainelli +Signed-off-by: Stephen Boyd +Acked-by: Takashi Iwai + +--- + drivers/clk/bcm/clk-bcm2835.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c +index 3f2ce20d27ec..e74fe6219d14 100644 +--- a/drivers/clk/bcm/clk-bcm2835.c ++++ b/drivers/clk/bcm/clk-bcm2835.c +@@ -969,9 +969,9 @@ static u32 bcm2835_clock_choose_div(struct clk_hw *hw, + return div; + } + +-static long bcm2835_clock_rate_from_divisor(struct bcm2835_clock *clock, +- unsigned long parent_rate, +- u32 div) ++static unsigned long bcm2835_clock_rate_from_divisor(struct bcm2835_clock *clock, ++ unsigned long parent_rate, ++ u32 div) + { + const struct bcm2835_clock_data *data = clock->data; + u64 temp; +-- +2.35.3 + diff --git a/patches.suse/clk-berlin-Add-of_node_put-for-of_get_parent.patch b/patches.suse/clk-berlin-Add-of_node_put-for-of_get_parent.patch new file mode 100644 index 0000000..64687f8 --- /dev/null +++ b/patches.suse/clk-berlin-Add-of_node_put-for-of_get_parent.patch @@ -0,0 +1,77 @@ +From 37c381b812dcbfde9c3f1f3d3e75fdfc1b40d5bc Mon Sep 17 00:00:00 2001 +From: Liang He +Date: Fri, 8 Jul 2022 16:49:00 +0800 +Subject: [PATCH] clk: berlin: Add of_node_put() for of_get_parent() +Git-commit: 37c381b812dcbfde9c3f1f3d3e75fdfc1b40d5bc +Patch-mainline: v6.1-rc1 +References: git-fixes + +In berlin2_clock_setup() and berlin2q_clock_setup(), we need to +call of_node_put() for the reference returned by of_get_parent() +which has increased the refcount. We should call *_put() in fail +path or when it is not used anymore. + +Fixes: 26b3b6b959b2 ("clk: berlin: prepare simple-mfd conversion") +Signed-off-by: Liang He +Link: https://lore.kernel.org/r/20220708084900.311684-1-windhl@126.com +Signed-off-by: Stephen Boyd +Acked-by: Takashi Iwai + +--- + drivers/clk/berlin/bg2.c | 5 ++++- + drivers/clk/berlin/bg2q.c | 6 +++++- + 2 files changed, 9 insertions(+), 2 deletions(-) + +diff --git a/drivers/clk/berlin/bg2.c b/drivers/clk/berlin/bg2.c +index bccdfa00fd37..67a9edbba29c 100644 +--- a/drivers/clk/berlin/bg2.c ++++ b/drivers/clk/berlin/bg2.c +@@ -500,12 +500,15 @@ static void __init berlin2_clock_setup(struct device_node *np) + int n, ret; + + clk_data = kzalloc(struct_size(clk_data, hws, MAX_CLKS), GFP_KERNEL); +- if (!clk_data) ++ if (!clk_data) { ++ of_node_put(parent_np); + return; ++ } + clk_data->num = MAX_CLKS; + hws = clk_data->hws; + + gbase = of_iomap(parent_np, 0); ++ of_node_put(parent_np); + if (!gbase) + return; + +diff --git a/drivers/clk/berlin/bg2q.c b/drivers/clk/berlin/bg2q.c +index e9518d35f262..dd2784bb75b6 100644 +--- a/drivers/clk/berlin/bg2q.c ++++ b/drivers/clk/berlin/bg2q.c +@@ -286,19 +286,23 @@ static void __init berlin2q_clock_setup(struct device_node *np) + int n, ret; + + clk_data = kzalloc(struct_size(clk_data, hws, MAX_CLKS), GFP_KERNEL); +- if (!clk_data) ++ if (!clk_data) { ++ of_node_put(parent_np); + return; ++ } + clk_data->num = MAX_CLKS; + hws = clk_data->hws; + + gbase = of_iomap(parent_np, 0); + if (!gbase) { ++ of_node_put(parent_np); + pr_err("%pOF: Unable to map global base\n", np); + return; + } + + /* BG2Q CPU PLL is not part of global registers */ + cpupll_base = of_iomap(parent_np, 1); ++ of_node_put(parent_np); + if (!cpupll_base) { + pr_err("%pOF: Unable to map cpupll base\n", np); + iounmap(gbase); +-- +2.35.3 + diff --git a/patches.suse/clk-imx-imx6sx-remove-the-SET_RATE_PARENT-flag-for-Q.patch b/patches.suse/clk-imx-imx6sx-remove-the-SET_RATE_PARENT-flag-for-Q.patch new file mode 100644 index 0000000..21d3a38 --- /dev/null +++ b/patches.suse/clk-imx-imx6sx-remove-the-SET_RATE_PARENT-flag-for-Q.patch @@ -0,0 +1,49 @@ +From b1ff1bfe81e763420afd5f3f25f0b3cbfd97055c Mon Sep 17 00:00:00 2001 +From: Han Xu +Date: Thu, 15 Sep 2022 10:09:59 -0500 +Subject: [PATCH] clk: imx: imx6sx: remove the SET_RATE_PARENT flag for QSPI clocks +Git-commit: b1ff1bfe81e763420afd5f3f25f0b3cbfd97055c +Patch-mainline: v6.0 +References: git-fixes + +There is no dedicate parent clock for QSPI so SET_RATE_PARENT flag +should not be used. For instance, the default parent clock for QSPI is +pll2_bus, which is also the parent clock for quite a few modules, such +as MMDC, once GPMI NAND set clock rate for EDO5 mode can cause system +hang due to pll2_bus rate changed. + +Fixes: f1541e15e38e ("clk: imx6sx: Switch to clk_hw based API") +Signed-off-by: Han Xu +Link: https://lore.kernel.org/r/20220915150959.3646702-1-han.xu@nxp.com +Tested-by: Fabio Estevam +Reviewed-by: Abel Vesa +Signed-off-by: Stephen Boyd +Acked-by: Takashi Iwai + +--- + drivers/clk/imx/clk-imx6sx.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/clk/imx/clk-imx6sx.c b/drivers/clk/imx/clk-imx6sx.c +index fc1bd23d4583..598f3cf4eba4 100644 +--- a/drivers/clk/imx/clk-imx6sx.c ++++ b/drivers/clk/imx/clk-imx6sx.c +@@ -280,13 +280,13 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) + hws[IMX6SX_CLK_SSI3_SEL] = imx_clk_hw_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); + hws[IMX6SX_CLK_SSI2_SEL] = imx_clk_hw_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); + hws[IMX6SX_CLK_SSI1_SEL] = imx_clk_hw_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); +- hws[IMX6SX_CLK_QSPI1_SEL] = imx_clk_hw_mux_flags("qspi1_sel", base + 0x1c, 7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels), CLK_SET_RATE_PARENT); ++ hws[IMX6SX_CLK_QSPI1_SEL] = imx_clk_hw_mux("qspi1_sel", base + 0x1c, 7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels)); + hws[IMX6SX_CLK_PERCLK_SEL] = imx_clk_hw_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels)); + hws[IMX6SX_CLK_VID_SEL] = imx_clk_hw_mux("vid_sel", base + 0x20, 21, 3, vid_sels, ARRAY_SIZE(vid_sels)); + hws[IMX6SX_CLK_ESAI_SEL] = imx_clk_hw_mux("esai_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels)); + hws[IMX6SX_CLK_CAN_SEL] = imx_clk_hw_mux("can_sel", base + 0x20, 8, 2, can_sels, ARRAY_SIZE(can_sels)); + hws[IMX6SX_CLK_UART_SEL] = imx_clk_hw_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels)); +- hws[IMX6SX_CLK_QSPI2_SEL] = imx_clk_hw_mux_flags("qspi2_sel", base + 0x2c, 15, 3, qspi2_sels, ARRAY_SIZE(qspi2_sels), CLK_SET_RATE_PARENT); ++ hws[IMX6SX_CLK_QSPI2_SEL] = imx_clk_hw_mux("qspi2_sel", base + 0x2c, 15, 3, qspi2_sels, ARRAY_SIZE(qspi2_sels)); + hws[IMX6SX_CLK_SPDIF_SEL] = imx_clk_hw_mux("spdif_sel", base + 0x30, 20, 2, audio_sels, ARRAY_SIZE(audio_sels)); + hws[IMX6SX_CLK_AUDIO_SEL] = imx_clk_hw_mux("audio_sel", base + 0x30, 7, 2, audio_sels, ARRAY_SIZE(audio_sels)); + hws[IMX6SX_CLK_ENET_PRE_SEL] = imx_clk_hw_mux("enet_pre_sel", base + 0x34, 15, 3, enet_pre_sels, ARRAY_SIZE(enet_pre_sels)); +-- +2.35.3 + diff --git a/patches.suse/clk-imx-scu-fix-memleak-on-platform_device_add-fails.patch b/patches.suse/clk-imx-scu-fix-memleak-on-platform_device_add-fails.patch new file mode 100644 index 0000000..f58356b --- /dev/null +++ b/patches.suse/clk-imx-scu-fix-memleak-on-platform_device_add-fails.patch @@ -0,0 +1,42 @@ +From 855ae87a2073ebf1b395e020de54fdf9ce7d166f Mon Sep 17 00:00:00 2001 +From: Lin Yujun +Date: Wed, 14 Sep 2022 11:32:06 +0800 +Subject: [PATCH] clk: imx: scu: fix memleak on platform_device_add() fails +Git-commit: 855ae87a2073ebf1b395e020de54fdf9ce7d166f +Patch-mainline: v6.1-rc1 +References: git-fixes + +No error handling is performed when platform_device_add() +fails. Add error processing before return, and modified +the return value. + +Fixes: 77d8f3068c63 ("clk: imx: scu: add two cells binding support") +Signed-off-by: Lin Yujun +Link: https://lore.kernel.org/r/20220914033206.98046-1-linyujun809@huawei.com +Signed-off-by: Stephen Boyd +Acked-by: Takashi Iwai + +--- + drivers/clk/imx/clk-scu.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c +index c56e406138db..1e6870f3671f 100644 +--- a/drivers/clk/imx/clk-scu.c ++++ b/drivers/clk/imx/clk-scu.c +@@ -695,7 +695,11 @@ struct clk_hw *imx_clk_scu_alloc_dev(const char *name, + pr_warn("%s: failed to attached the power domain %d\n", + name, ret); + +- platform_device_add(pdev); ++ ret = platform_device_add(pdev); ++ if (ret) { ++ platform_device_put(pdev); ++ return ERR_PTR(ret); ++ } + + /* For API backwards compatiblilty, simply return NULL for success */ + return NULL; +-- +2.35.3 + diff --git a/patches.suse/clk-ingenic-tcu-Properly-enable-registers-before-acc.patch b/patches.suse/clk-ingenic-tcu-Properly-enable-registers-before-acc.patch new file mode 100644 index 0000000..79bfc2e --- /dev/null +++ b/patches.suse/clk-ingenic-tcu-Properly-enable-registers-before-acc.patch @@ -0,0 +1,81 @@ +From 6726d552a6912e88cf63fe2bda87b2efa0efc7d0 Mon Sep 17 00:00:00 2001 +From: Aidan MacDonald +Date: Fri, 17 Jun 2022 13:22:54 +0100 +Subject: [PATCH] clk: ingenic-tcu: Properly enable registers before accessing timers +Git-commit: 6726d552a6912e88cf63fe2bda87b2efa0efc7d0 +Patch-mainline: v6.0 +References: git-fixes + +Access to registers is guarded by ingenic_tcu_{enable,disable}_regs() +so the stop bit can be cleared before accessing a timer channel, but +those functions did not clear the stop bit on SoCs with a global TCU +clock gate. + +Testing on the X1000 has revealed that the stop bits must be cleared +_and_ the global TCU clock must be ungated to access timer registers. +This appears to be the norm on Ingenic SoCs, and is specified in the +documentation for the X1000 and numerous JZ47xx SoCs. + +If the stop bit isn't cleared, register writes don't take effect and +the system can be left in a broken state, eg. the watchdog timer may +not run. + +The bug probably went unnoticed because stop bits are zeroed when +the SoC is reset, and the kernel does not set them unless a timer +gets disabled at runtime. However, it is possible that a bootloader +or a previous kernel (if using kexec) leaves the stop bits set and +we should not rely on them being cleared. + +Fixing this is easy: have ingenic_tcu_{enable,disable}_regs() always +clear the stop bit, regardless of the presence of a global TCU gate. + +Reviewed-by: Paul Cercueil +Tested-by: Paul Cercueil +Fixes: 4f89e4b8f121 ("clk: ingenic: Add driver for the TCU clocks") +Cc: stable@vger.kernel.org +Signed-off-by: Aidan MacDonald +Link: https://lore.kernel.org/r/20220617122254.738900-1-aidanmacdonald.0x0@gmail.com +Signed-off-by: Stephen Boyd +Acked-by: Takashi Iwai + +--- + drivers/clk/ingenic/tcu.c | 15 +++++---------- + 1 file changed, 5 insertions(+), 10 deletions(-) + +diff --git a/drivers/clk/ingenic/tcu.c b/drivers/clk/ingenic/tcu.c +index 201bf6e6b6e0..d5544cbc5c48 100644 +--- a/drivers/clk/ingenic/tcu.c ++++ b/drivers/clk/ingenic/tcu.c +@@ -101,15 +101,11 @@ static bool ingenic_tcu_enable_regs(struct clk_hw *hw) + bool enabled = false; + + /* +- * If the SoC has no global TCU clock, we must ungate the channel's +- * clock to be able to access its registers. +- * If we have a TCU clock, it will be enabled automatically as it has +- * been attached to the regmap. ++ * According to the programming manual, a timer channel's registers can ++ * only be accessed when the channel's stop bit is clear. + */ +- if (!tcu->clk) { +- enabled = !!ingenic_tcu_is_enabled(hw); +- regmap_write(tcu->map, TCU_REG_TSCR, BIT(info->gate_bit)); +- } ++ enabled = !!ingenic_tcu_is_enabled(hw); ++ regmap_write(tcu->map, TCU_REG_TSCR, BIT(info->gate_bit)); + + return enabled; + } +@@ -120,8 +116,7 @@ static void ingenic_tcu_disable_regs(struct clk_hw *hw) + const struct ingenic_tcu_clk_info *info = tcu_clk->info; + struct ingenic_tcu *tcu = tcu_clk->tcu; + +- if (!tcu->clk) +- regmap_write(tcu->map, TCU_REG_TSSR, BIT(info->gate_bit)); ++ regmap_write(tcu->map, TCU_REG_TSSR, BIT(info->gate_bit)); + } + + static u8 ingenic_tcu_get_parent(struct clk_hw *hw) +-- +2.35.3 + diff --git a/patches.suse/clk-iproc-Do-not-rely-on-node-name-for-correct-PLL-s.patch b/patches.suse/clk-iproc-Do-not-rely-on-node-name-for-correct-PLL-s.patch new file mode 100644 index 0000000..c358027 --- /dev/null +++ b/patches.suse/clk-iproc-Do-not-rely-on-node-name-for-correct-PLL-s.patch @@ -0,0 +1,82 @@ +From 1b24a132eba7a1c19475ba2510ec1c00af3ff914 Mon Sep 17 00:00:00 2001 +From: Florian Fainelli +Date: Mon, 5 Sep 2022 09:15:03 -0700 +Subject: [PATCH] clk: iproc: Do not rely on node name for correct PLL setup +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 1b24a132eba7a1c19475ba2510ec1c00af3ff914 +Patch-mainline: v6.0 +References: git-fixes + +After commit 31fd9b79dc58 ("ARM: dts: BCM5301X: update CRU block +description") a warning from clk-iproc-pll.c was generated due to a +duplicate PLL name as well as the console stopped working. Upon closer +inspection it became clear that iproc_pll_clk_setup() used the Device +Tree node unit name as an unique identifier as well as a parent name to +parent all clocks under the PLL. + +BCM5301X was the first platform on which that got noticed because of the +DT node unit name renaming but the same assumptions hold true for any +user of the iproc_pll_clk_setup() function. + +The first 'clock-output-names' property is always guaranteed to be +unique as well as providing the actual desired PLL clock name, so we +utilize that to register the PLL and as a parent name of all children +clock. + +Fixes: 5fe225c105fd ("clk: iproc: add initial common clock support") +Signed-off-by: Florian Fainelli +Acked-by: Rafał Miłecki +Link: https://lore.kernel.org/r/20220905161504.1526-1-f.fainelli@gmail.com +Signed-off-by: Stephen Boyd +Acked-by: Takashi Iwai + +--- + drivers/clk/bcm/clk-iproc-pll.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/drivers/clk/bcm/clk-iproc-pll.c b/drivers/clk/bcm/clk-iproc-pll.c +index 1a098db12062..680f9d8d357c 100644 +--- a/drivers/clk/bcm/clk-iproc-pll.c ++++ b/drivers/clk/bcm/clk-iproc-pll.c +@@ -726,6 +726,7 @@ void iproc_pll_clk_setup(struct device_node *node, + const char *parent_name; + struct iproc_clk *iclk_array; + struct clk_hw_onecell_data *clk_data; ++ const char *clk_name; + + if (WARN_ON(!pll_ctrl) || WARN_ON(!clk_ctrl)) + return; +@@ -773,7 +774,12 @@ void iproc_pll_clk_setup(struct device_node *node, + iclk = &iclk_array[0]; + iclk->pll = pll; + +- init.name = node->name; ++ ret = of_property_read_string_index(node, "clock-output-names", ++ 0, &clk_name); ++ if (WARN_ON(ret)) ++ goto err_pll_register; ++ ++ init.name = clk_name; + init.ops = &iproc_pll_ops; + init.flags = 0; + parent_name = of_clk_get_parent_name(node, 0); +@@ -793,13 +799,11 @@ void iproc_pll_clk_setup(struct device_node *node, + goto err_pll_register; + + clk_data->hws[0] = &iclk->hw; ++ parent_name = clk_name; + + /* now initialize and register all leaf clocks */ + for (i = 1; i < num_clks; i++) { +- const char *clk_name; +- + memset(&init, 0, sizeof(init)); +- parent_name = node->name; + + ret = of_property_read_string_index(node, "clock-output-names", + i, &clk_name); +-- +2.35.3 + diff --git a/patches.suse/clk-mediatek-mt8183-mfgcfg-Propagate-rate-changes-to.patch b/patches.suse/clk-mediatek-mt8183-mfgcfg-Propagate-rate-changes-to.patch new file mode 100644 index 0000000..9732603 --- /dev/null +++ b/patches.suse/clk-mediatek-mt8183-mfgcfg-Propagate-rate-changes-to.patch @@ -0,0 +1,43 @@ +From 9f94f545f258b15bfa6357eb62e1e307b712851e Mon Sep 17 00:00:00 2001 +From: Chen-Yu Tsai +Date: Tue, 27 Sep 2022 12:11:20 +0200 +Subject: [PATCH] clk: mediatek: mt8183: mfgcfg: Propagate rate changes to parent +Git-commit: 9f94f545f258b15bfa6357eb62e1e307b712851e +Patch-mainline: v6.1-rc1 +References: git-fixes + +The only clock in the MT8183 MFGCFG block feeds the GPU. Propagate its +rate change requests to its parent, so that DVFS for the GPU can work +properly. + +Fixes: acddfc2c261b ("clk: mediatek: Add MT8183 clock support") +Signed-off-by: Chen-Yu Tsai +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20220927101128.44758-3-angelogioacchino.delregno@collabora.com +Acked-by: Takashi Iwai + +--- + drivers/clk/mediatek/clk-mt8183-mfgcfg.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/clk/mediatek/clk-mt8183-mfgcfg.c b/drivers/clk/mediatek/clk-mt8183-mfgcfg.c +index f578b393f41e..730c9ae5ea12 100644 +--- a/drivers/clk/mediatek/clk-mt8183-mfgcfg.c ++++ b/drivers/clk/mediatek/clk-mt8183-mfgcfg.c +@@ -18,9 +18,9 @@ static const struct mtk_gate_regs mfg_cg_regs = { + .sta_ofs = 0x0, + }; + +-#define GATE_MFG(_id, _name, _parent, _shift) \ +- GATE_MTK(_id, _name, _parent, &mfg_cg_regs, _shift, \ +- &mtk_clk_gate_ops_setclr) ++#define GATE_MFG(_id, _name, _parent, _shift) \ ++ GATE_MTK_FLAGS(_id, _name, _parent, &mfg_cg_regs, _shift, \ ++ &mtk_clk_gate_ops_setclr, CLK_SET_RATE_PARENT) + + static const struct mtk_gate mfg_clks[] = { + GATE_MFG(CLK_MFG_BG3D, "mfg_bg3d", "mfg_sel", 0) +-- +2.35.3 + diff --git a/patches.suse/clk-meson-Hold-reference-returned-by-of_get_parent.patch b/patches.suse/clk-meson-Hold-reference-returned-by-of_get_parent.patch new file mode 100644 index 0000000..75acdf6 --- /dev/null +++ b/patches.suse/clk-meson-Hold-reference-returned-by-of_get_parent.patch @@ -0,0 +1,98 @@ +From 89ab396d712f7c91fe94f55cff23460426f5fc81 Mon Sep 17 00:00:00 2001 +From: Liang He +Date: Tue, 28 Jun 2022 22:10:38 +0800 +Subject: [PATCH] clk: meson: Hold reference returned by of_get_parent() +Git-commit: 89ab396d712f7c91fe94f55cff23460426f5fc81 +Patch-mainline: v6.1-rc1 +References: git-fixes + +We should hold the reference returned by of_get_parent() and use it +to call of_node_put() for refcount balance. + +Fixes: 88e2da81241e ("clk: meson: aoclk: refactor common code into dedicated file") +Fixes: 6682bd4d443f ("clk: meson: factorise meson64 peripheral clock controller drivers") +Fixes: bb6eddd1d28c ("clk: meson: meson8b: use the HHI syscon if available") + +Signed-off-by: Liang He +Link: https://lore.kernel.org/r/20220628141038.168383-1-windhl@126.com +Reviewed-by: Neil Armstrong +Reviewed-by: Martin Blumenstingl +Signed-off-by: Stephen Boyd +Acked-by: Takashi Iwai + +--- + drivers/clk/meson/meson-aoclk.c | 5 ++++- + drivers/clk/meson/meson-eeclk.c | 5 ++++- + drivers/clk/meson/meson8b.c | 5 ++++- + 3 files changed, 12 insertions(+), 3 deletions(-) + +diff --git a/drivers/clk/meson/meson-aoclk.c b/drivers/clk/meson/meson-aoclk.c +index 27cd2c1f3f61..434cd8f9de82 100644 +--- a/drivers/clk/meson/meson-aoclk.c ++++ b/drivers/clk/meson/meson-aoclk.c +@@ -38,6 +38,7 @@ int meson_aoclkc_probe(struct platform_device *pdev) + struct meson_aoclk_reset_controller *rstc; + struct meson_aoclk_data *data; + struct device *dev = &pdev->dev; ++ struct device_node *np; + struct regmap *regmap; + int ret, clkid; + +@@ -49,7 +50,9 @@ int meson_aoclkc_probe(struct platform_device *pdev) + if (!rstc) + return -ENOMEM; + +- regmap = syscon_node_to_regmap(of_get_parent(dev->of_node)); ++ np = of_get_parent(dev->of_node); ++ regmap = syscon_node_to_regmap(np); ++ of_node_put(np); + if (IS_ERR(regmap)) { + dev_err(dev, "failed to get regmap\n"); + return PTR_ERR(regmap); +diff --git a/drivers/clk/meson/meson-eeclk.c b/drivers/clk/meson/meson-eeclk.c +index 8d5a5dab955a..0e5e6b57eb20 100644 +--- a/drivers/clk/meson/meson-eeclk.c ++++ b/drivers/clk/meson/meson-eeclk.c +@@ -18,6 +18,7 @@ int meson_eeclkc_probe(struct platform_device *pdev) + { + const struct meson_eeclkc_data *data; + struct device *dev = &pdev->dev; ++ struct device_node *np; + struct regmap *map; + int ret, i; + +@@ -26,7 +27,9 @@ int meson_eeclkc_probe(struct platform_device *pdev) + return -EINVAL; + + /* Get the hhi system controller node */ +- map = syscon_node_to_regmap(of_get_parent(dev->of_node)); ++ np = of_get_parent(dev->of_node); ++ map = syscon_node_to_regmap(np); ++ of_node_put(np); + if (IS_ERR(map)) { + dev_err(dev, + "failed to get HHI regmap\n"); +diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c +index 8f3b7a94a667..827e78fb16a8 100644 +--- a/drivers/clk/meson/meson8b.c ++++ b/drivers/clk/meson/meson8b.c +@@ -3792,12 +3792,15 @@ static void __init meson8b_clkc_init_common(struct device_node *np, + struct clk_hw_onecell_data *clk_hw_onecell_data) + { + struct meson8b_clk_reset *rstc; ++ struct device_node *parent_np; + const char *notifier_clk_name; + struct clk *notifier_clk; + struct regmap *map; + int i, ret; + +- map = syscon_node_to_regmap(of_get_parent(np)); ++ parent_np = of_get_parent(np); ++ map = syscon_node_to_regmap(parent_np); ++ of_node_put(parent_np); + if (IS_ERR(map)) { + pr_err("failed to get HHI regmap - Trying obsolete regs\n"); + return; +-- +2.35.3 + diff --git a/patches.suse/clk-oxnas-Hold-reference-returned-by-of_get_parent.patch b/patches.suse/clk-oxnas-Hold-reference-returned-by-of_get_parent.patch new file mode 100644 index 0000000..276ae45 --- /dev/null +++ b/patches.suse/clk-oxnas-Hold-reference-returned-by-of_get_parent.patch @@ -0,0 +1,44 @@ +From 1d6aa08c54cd0e005210ab8e3b1e92ede70f8a4f Mon Sep 17 00:00:00 2001 +From: Liang He +Date: Tue, 28 Jun 2022 22:31:55 +0800 +Subject: [PATCH] clk: oxnas: Hold reference returned by of_get_parent() +Git-commit: 1d6aa08c54cd0e005210ab8e3b1e92ede70f8a4f +Patch-mainline: v6.1-rc1 +References: git-fixes + +In oxnas_stdclk_probe(), we need to hold the reference returned by +of_get_parent() and use it to call of_node_put() for refcount +balance. + +Fixes: 0bbd72b4c64f ("clk: Add Oxford Semiconductor OXNAS Standard Clocks") +Signed-off-by: Liang He +Link: https://lore.kernel.org/r/20220628143155.170550-1-windhl@126.com +Signed-off-by: Stephen Boyd +Acked-by: Takashi Iwai + +--- + drivers/clk/clk-oxnas.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/clk/clk-oxnas.c ++++ b/drivers/clk/clk-oxnas.c +@@ -207,7 +207,7 @@ static const struct of_device_id oxnas_s + + static int oxnas_stdclk_probe(struct platform_device *pdev) + { +- struct device_node *np = pdev->dev.of_node; ++ struct device_node *np = pdev->dev.of_node, *parent_np; + const struct oxnas_stdclk_data *data; + const struct of_device_id *id; + struct regmap *regmap; +@@ -219,7 +219,9 @@ static int oxnas_stdclk_probe(struct pla + return -ENODEV; + data = id->data; + +- regmap = syscon_node_to_regmap(of_get_parent(np)); ++ parent_np = of_get_parent(np); ++ regmap = syscon_node_to_regmap(parent_np); ++ of_node_put(parent_np); + if (IS_ERR(regmap)) { + dev_err(&pdev->dev, "failed to have parent regmap\n"); + return PTR_ERR(regmap); diff --git a/patches.suse/clk-qcom-apss-ipq6018-mark-apcs_alias0_core_clk-as-c.patch b/patches.suse/clk-qcom-apss-ipq6018-mark-apcs_alias0_core_clk-as-c.patch new file mode 100644 index 0000000..3a6b257 --- /dev/null +++ b/patches.suse/clk-qcom-apss-ipq6018-mark-apcs_alias0_core_clk-as-c.patch @@ -0,0 +1,42 @@ +From 86e78995c93ee182433f965babfccd48417d4dcf Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Fri, 19 Aug 2022 00:06:22 +0200 +Subject: [PATCH] clk: qcom: apss-ipq6018: mark apcs_alias0_core_clk as critical +Git-commit: 86e78995c93ee182433f965babfccd48417d4dcf +Patch-mainline: v6.1-rc1 +References: git-fixes + +While fixing up the driver I noticed that my IPQ8074 board was hanging +after CPUFreq switched the frequency during boot, WDT would eventually +reset it. + +So mark apcs_alias0_core_clk as critical since its the clock feeding the +CPU cluster and must never be disabled. + +Fixes: 5e77b4ef1b19 ("clk: qcom: Add ipq6018 apss clock controller") +Signed-off-by: Robert Marko +Reviewed-by: Dmitry Baryshkov +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20220818220628.339366-3-robimarko@gmail.com +Acked-by: Takashi Iwai + +--- + drivers/clk/qcom/apss-ipq6018.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/clk/qcom/apss-ipq6018.c b/drivers/clk/qcom/apss-ipq6018.c +index be952d417ded..f2f502e2d5a4 100644 +--- a/drivers/clk/qcom/apss-ipq6018.c ++++ b/drivers/clk/qcom/apss-ipq6018.c +@@ -56,7 +56,7 @@ static struct clk_branch apcs_alias0_core_clk = { + .parent_hws = (const struct clk_hw *[]){ + &apcs_alias0_clk_src.clkr.hw }, + .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT, ++ .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +-- +2.35.3 + diff --git a/patches.suse/clk-qcom-gcc-msm8916-use-ARRAY_SIZE-instead-of-speci.patch b/patches.suse/clk-qcom-gcc-msm8916-use-ARRAY_SIZE-instead-of-speci.patch new file mode 100644 index 0000000..91fcbdd --- /dev/null +++ b/patches.suse/clk-qcom-gcc-msm8916-use-ARRAY_SIZE-instead-of-speci.patch @@ -0,0 +1,524 @@ +From 5a6d30675d17b9a984c837e7b31ce6b269e22c32 Mon Sep 17 00:00:00 2001 +From: Dmitry Baryshkov +Date: Mon, 4 Jul 2022 20:24:49 +0300 +Subject: [PATCH] clk: qcom: gcc-msm8916: use ARRAY_SIZE instead of specifying num_parents +Git-commit: 5a6d30675d17b9a984c837e7b31ce6b269e22c32 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Use ARRAY_SIZE() instead of manually specifying num_parents. This makes +adding/removing entries to/from parent_data easy and errorproof. + +This conversion fixes an issue present since the first version of this +driver. For the gp1_clk_src, gp2_clk_src and gp3_clk_src it was +impossible to select sleep_clk as a prent of the clock, since +num_parents was limited to 3 rather than 4. Switching to use num_parents +automatically makes sleep_clk available for selection. + +Fixes: 3966fab8b6ab ("clk: qcom: Add MSM8916 Global Clock Controller support") +Cc: Georgi Djakov +Reviewed-by: Marijn Suijten +Reviewed-by: Konrad Dybcio +Signed-off-by: Dmitry Baryshkov +Acked-by: Georgi Djakov +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20220704172453.838303-4-dmitry.baryshkov@linaro.org +Acked-by: Takashi Iwai + +--- + drivers/clk/qcom/gcc-msm8916.c | 108 ++++++++++++++++----------------- + 1 file changed, 54 insertions(+), 54 deletions(-) + +diff --git a/drivers/clk/qcom/gcc-msm8916.c b/drivers/clk/qcom/gcc-msm8916.c +index 9a46794f6eb8..265df21e24af 100644 +--- a/drivers/clk/qcom/gcc-msm8916.c ++++ b/drivers/clk/qcom/gcc-msm8916.c +@@ -371,7 +371,7 @@ static struct clk_rcg2 pcnoc_bfdcd_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "pcnoc_bfdcd_clk_src", + .parent_names = gcc_xo_gpll0_bimc, +- .num_parents = 3, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0_bimc), + .ops = &clk_rcg2_ops, + }, + }; +@@ -383,7 +383,7 @@ static struct clk_rcg2 system_noc_bfdcd_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "system_noc_bfdcd_clk_src", + .parent_names = gcc_xo_gpll0_bimc, +- .num_parents = 3, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0_bimc), + .ops = &clk_rcg2_ops, + }, + }; +@@ -403,7 +403,7 @@ static struct clk_rcg2 camss_ahb_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "camss_ahb_clk_src", + .parent_names = gcc_xo_gpll0, +- .num_parents = 2, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .ops = &clk_rcg2_ops, + }, + }; +@@ -424,7 +424,7 @@ static struct clk_rcg2 apss_ahb_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "apss_ahb_clk_src", + .parent_names = gcc_xo_gpll0, +- .num_parents = 2, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .ops = &clk_rcg2_ops, + }, + }; +@@ -443,7 +443,7 @@ static struct clk_rcg2 csi0_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi0_clk_src", + .parent_names = gcc_xo_gpll0, +- .num_parents = 2, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .ops = &clk_rcg2_ops, + }, + }; +@@ -456,7 +456,7 @@ static struct clk_rcg2 csi1_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi1_clk_src", + .parent_names = gcc_xo_gpll0, +- .num_parents = 2, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .ops = &clk_rcg2_ops, + }, + }; +@@ -484,7 +484,7 @@ static struct clk_rcg2 gfx3d_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "gfx3d_clk_src", + .parent_names = gcc_xo_gpll0a_gpll1_gpll2a, +- .num_parents = 4, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0a_gpll1_gpll2a), + .ops = &clk_rcg2_ops, + }, + }; +@@ -511,7 +511,7 @@ static struct clk_rcg2 vfe0_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "vfe0_clk_src", + .parent_names = gcc_xo_gpll0_gpll2, +- .num_parents = 3, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll2), + .ops = &clk_rcg2_ops, + }, + }; +@@ -530,7 +530,7 @@ static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup1_i2c_apps_clk_src", + .parent_names = gcc_xo_gpll0, +- .num_parents = 2, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .ops = &clk_rcg2_ops, + }, + }; +@@ -559,7 +559,7 @@ static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup1_spi_apps_clk_src", + .parent_names = gcc_xo_gpll0, +- .num_parents = 2, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .ops = &clk_rcg2_ops, + }, + }; +@@ -572,7 +572,7 @@ static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup2_i2c_apps_clk_src", + .parent_names = gcc_xo_gpll0, +- .num_parents = 2, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .ops = &clk_rcg2_ops, + }, + }; +@@ -586,7 +586,7 @@ static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup2_spi_apps_clk_src", + .parent_names = gcc_xo_gpll0, +- .num_parents = 2, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .ops = &clk_rcg2_ops, + }, + }; +@@ -599,7 +599,7 @@ static struct clk_rcg2 blsp1_qup3_i2c_apps_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup3_i2c_apps_clk_src", + .parent_names = gcc_xo_gpll0, +- .num_parents = 2, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .ops = &clk_rcg2_ops, + }, + }; +@@ -613,7 +613,7 @@ static struct clk_rcg2 blsp1_qup3_spi_apps_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup3_spi_apps_clk_src", + .parent_names = gcc_xo_gpll0, +- .num_parents = 2, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .ops = &clk_rcg2_ops, + }, + }; +@@ -626,7 +626,7 @@ static struct clk_rcg2 blsp1_qup4_i2c_apps_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup4_i2c_apps_clk_src", + .parent_names = gcc_xo_gpll0, +- .num_parents = 2, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .ops = &clk_rcg2_ops, + }, + }; +@@ -640,7 +640,7 @@ static struct clk_rcg2 blsp1_qup4_spi_apps_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup4_spi_apps_clk_src", + .parent_names = gcc_xo_gpll0, +- .num_parents = 2, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .ops = &clk_rcg2_ops, + }, + }; +@@ -653,7 +653,7 @@ static struct clk_rcg2 blsp1_qup5_i2c_apps_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup5_i2c_apps_clk_src", + .parent_names = gcc_xo_gpll0, +- .num_parents = 2, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .ops = &clk_rcg2_ops, + }, + }; +@@ -667,7 +667,7 @@ static struct clk_rcg2 blsp1_qup5_spi_apps_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup5_spi_apps_clk_src", + .parent_names = gcc_xo_gpll0, +- .num_parents = 2, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .ops = &clk_rcg2_ops, + }, + }; +@@ -680,7 +680,7 @@ static struct clk_rcg2 blsp1_qup6_i2c_apps_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup6_i2c_apps_clk_src", + .parent_names = gcc_xo_gpll0, +- .num_parents = 2, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .ops = &clk_rcg2_ops, + }, + }; +@@ -694,7 +694,7 @@ static struct clk_rcg2 blsp1_qup6_spi_apps_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup6_spi_apps_clk_src", + .parent_names = gcc_xo_gpll0, +- .num_parents = 2, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .ops = &clk_rcg2_ops, + }, + }; +@@ -727,7 +727,7 @@ static struct clk_rcg2 blsp1_uart1_apps_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart1_apps_clk_src", + .parent_names = gcc_xo_gpll0, +- .num_parents = 2, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .ops = &clk_rcg2_ops, + }, + }; +@@ -741,7 +741,7 @@ static struct clk_rcg2 blsp1_uart2_apps_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart2_apps_clk_src", + .parent_names = gcc_xo_gpll0, +- .num_parents = 2, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .ops = &clk_rcg2_ops, + }, + }; +@@ -760,7 +760,7 @@ static struct clk_rcg2 cci_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "cci_clk_src", + .parent_names = gcc_xo_gpll0a, +- .num_parents = 2, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0a), + .ops = &clk_rcg2_ops, + }, + }; +@@ -793,7 +793,7 @@ static struct clk_rcg2 camss_gp0_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "camss_gp0_clk_src", + .parent_names = gcc_xo_gpll0_gpll1a_sleep, +- .num_parents = 4, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1a_sleep), + .ops = &clk_rcg2_ops, + }, + }; +@@ -807,7 +807,7 @@ static struct clk_rcg2 camss_gp1_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "camss_gp1_clk_src", + .parent_names = gcc_xo_gpll0_gpll1a_sleep, +- .num_parents = 4, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1a_sleep), + .ops = &clk_rcg2_ops, + }, + }; +@@ -827,7 +827,7 @@ static struct clk_rcg2 jpeg0_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "jpeg0_clk_src", + .parent_names = gcc_xo_gpll0, +- .num_parents = 2, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .ops = &clk_rcg2_ops, + }, + }; +@@ -848,7 +848,7 @@ static struct clk_rcg2 mclk0_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "mclk0_clk_src", + .parent_names = gcc_xo_gpll0_gpll1a_sleep, +- .num_parents = 4, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1a_sleep), + .ops = &clk_rcg2_ops, + }, + }; +@@ -862,7 +862,7 @@ static struct clk_rcg2 mclk1_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "mclk1_clk_src", + .parent_names = gcc_xo_gpll0_gpll1a_sleep, +- .num_parents = 4, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1a_sleep), + .ops = &clk_rcg2_ops, + }, + }; +@@ -881,7 +881,7 @@ static struct clk_rcg2 csi0phytimer_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi0phytimer_clk_src", + .parent_names = gcc_xo_gpll0_gpll1a, +- .num_parents = 3, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1a), + .ops = &clk_rcg2_ops, + }, + }; +@@ -894,7 +894,7 @@ static struct clk_rcg2 csi1phytimer_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi1phytimer_clk_src", + .parent_names = gcc_xo_gpll0_gpll1a, +- .num_parents = 3, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1a), + .ops = &clk_rcg2_ops, + }, + }; +@@ -914,7 +914,7 @@ static struct clk_rcg2 cpp_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "cpp_clk_src", + .parent_names = gcc_xo_gpll0_gpll2, +- .num_parents = 3, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll2), + .ops = &clk_rcg2_ops, + }, + }; +@@ -935,7 +935,7 @@ static struct clk_rcg2 crypto_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "crypto_clk_src", + .parent_names = gcc_xo_gpll0, +- .num_parents = 2, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .ops = &clk_rcg2_ops, + }, + }; +@@ -976,7 +976,7 @@ static struct clk_rcg2 gp1_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp1_clk_src", + .parent_names = gcc_xo_gpll0_gpll1a_sleep, +- .num_parents = 3, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1a_sleep), + .ops = &clk_rcg2_ops, + }, + }; +@@ -990,7 +990,7 @@ static struct clk_rcg2 gp2_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp2_clk_src", + .parent_names = gcc_xo_gpll0_gpll1a_sleep, +- .num_parents = 3, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1a_sleep), + .ops = &clk_rcg2_ops, + }, + }; +@@ -1004,7 +1004,7 @@ static struct clk_rcg2 gp3_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp3_clk_src", + .parent_names = gcc_xo_gpll0_gpll1a_sleep, +- .num_parents = 3, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1a_sleep), + .ops = &clk_rcg2_ops, + }, + }; +@@ -1016,7 +1016,7 @@ static struct clk_rcg2 byte0_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "byte0_clk_src", + .parent_names = gcc_xo_gpll0a_dsibyte, +- .num_parents = 3, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0a_dsibyte), + .ops = &clk_byte2_ops, + .flags = CLK_SET_RATE_PARENT, + }, +@@ -1035,7 +1035,7 @@ static struct clk_rcg2 esc0_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "esc0_clk_src", + .parent_names = gcc_xo_dsibyte, +- .num_parents = 2, ++ .num_parents = ARRAY_SIZE(gcc_xo_dsibyte), + .ops = &clk_rcg2_ops, + }, + }; +@@ -1060,7 +1060,7 @@ static struct clk_rcg2 mdp_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "mdp_clk_src", + .parent_names = gcc_xo_gpll0_dsiphy, +- .num_parents = 3, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0_dsiphy), + .ops = &clk_rcg2_ops, + }, + }; +@@ -1073,7 +1073,7 @@ static struct clk_rcg2 pclk0_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "pclk0_clk_src", + .parent_names = gcc_xo_gpll0a_dsiphy, +- .num_parents = 3, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0a_dsiphy), + .ops = &clk_pixel_ops, + .flags = CLK_SET_RATE_PARENT, + }, +@@ -1092,7 +1092,7 @@ static struct clk_rcg2 vsync_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "vsync_clk_src", + .parent_names = gcc_xo_gpll0a, +- .num_parents = 2, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0a), + .ops = &clk_rcg2_ops, + }, + }; +@@ -1110,7 +1110,7 @@ static struct clk_rcg2 pdm2_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "pdm2_clk_src", + .parent_names = gcc_xo_gpll0, +- .num_parents = 2, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .ops = &clk_rcg2_ops, + }, + }; +@@ -1135,7 +1135,7 @@ static struct clk_rcg2 sdcc1_apps_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "sdcc1_apps_clk_src", + .parent_names = gcc_xo_gpll0, +- .num_parents = 2, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .ops = &clk_rcg2_floor_ops, + }, + }; +@@ -1160,7 +1160,7 @@ static struct clk_rcg2 sdcc2_apps_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "sdcc2_apps_clk_src", + .parent_names = gcc_xo_gpll0, +- .num_parents = 2, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .ops = &clk_rcg2_floor_ops, + }, + }; +@@ -1180,7 +1180,7 @@ static struct clk_rcg2 apss_tcu_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "apss_tcu_clk_src", + .parent_names = gcc_xo_gpll0a_gpll1_gpll2, +- .num_parents = 4, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0a_gpll1_gpll2), + .ops = &clk_rcg2_ops, + }, + }; +@@ -1203,7 +1203,7 @@ static struct clk_rcg2 bimc_gpu_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "bimc_gpu_clk_src", + .parent_names = gcc_xo_gpll0_bimc, +- .num_parents = 3, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0_bimc), + .flags = CLK_GET_RATE_NOCACHE, + .ops = &clk_rcg2_ops, + }, +@@ -1222,7 +1222,7 @@ static struct clk_rcg2 usb_hs_system_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb_hs_system_clk_src", + .parent_names = gcc_xo_gpll0, +- .num_parents = 2, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .ops = &clk_rcg2_ops, + }, + }; +@@ -1248,7 +1248,7 @@ static struct clk_rcg2 ultaudio_ahbfabric_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "ultaudio_ahbfabric_clk_src", + .parent_names = gcc_xo_gpll0_gpll1_sleep, +- .num_parents = 4, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1_sleep), + .ops = &clk_rcg2_ops, + }, + }; +@@ -1327,7 +1327,7 @@ static struct clk_rcg2 ultaudio_lpaif_pri_i2s_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "ultaudio_lpaif_pri_i2s_clk_src", + .parent_names = gcc_xo_gpll1_epi2s_emclk_sleep, +- .num_parents = 5, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll1_epi2s_emclk_sleep), + .ops = &clk_rcg2_ops, + }, + }; +@@ -1358,7 +1358,7 @@ static struct clk_rcg2 ultaudio_lpaif_sec_i2s_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "ultaudio_lpaif_sec_i2s_clk_src", + .parent_names = gcc_xo_gpll1_esi2s_emclk_sleep, +- .num_parents = 5, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll1_esi2s_emclk_sleep), + .ops = &clk_rcg2_ops, + }, + }; +@@ -1389,7 +1389,7 @@ static struct clk_rcg2 ultaudio_lpaif_aux_i2s_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "ultaudio_lpaif_aux_i2s_clk_src", + .parent_names = gcc_xo_gpll1_esi2s_emclk_sleep, +- .num_parents = 5, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll1_esi2s_emclk_sleep), + .ops = &clk_rcg2_ops, + }, + }; +@@ -1424,7 +1424,7 @@ static struct clk_rcg2 ultaudio_xo_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "ultaudio_xo_clk_src", + .parent_names = gcc_xo_sleep, +- .num_parents = 2, ++ .num_parents = ARRAY_SIZE(gcc_xo_sleep), + .ops = &clk_rcg2_ops, + }, + }; +@@ -1480,7 +1480,7 @@ static struct clk_rcg2 codec_digcodec_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "codec_digcodec_clk_src", + .parent_names = gcc_xo_gpll1_emclk_sleep, +- .num_parents = 4, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll1_emclk_sleep), + .ops = &clk_rcg2_ops, + }, + }; +@@ -1550,7 +1550,7 @@ static struct clk_rcg2 vcodec0_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "vcodec0_clk_src", + .parent_names = gcc_xo_gpll0, +- .num_parents = 2, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .ops = &clk_rcg2_ops, + }, + }; +@@ -2806,7 +2806,7 @@ static struct clk_rcg2 bimc_ddr_clk_src = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "bimc_ddr_clk_src", + .parent_names = gcc_xo_gpll0_bimc, +- .num_parents = 3, ++ .num_parents = ARRAY_SIZE(gcc_xo_gpll0_bimc), + .ops = &clk_rcg2_ops, + .flags = CLK_GET_RATE_NOCACHE, + }, +-- +2.35.3 + diff --git a/patches.suse/clk-qoriq-Hold-reference-returned-by-of_get_parent.patch b/patches.suse/clk-qoriq-Hold-reference-returned-by-of_get_parent.patch new file mode 100644 index 0000000..313109e --- /dev/null +++ b/patches.suse/clk-qoriq-Hold-reference-returned-by-of_get_parent.patch @@ -0,0 +1,56 @@ +From a8ea4273bc26256ce3cce83164f0f51c5bf6e127 Mon Sep 17 00:00:00 2001 +From: Liang He +Date: Tue, 28 Jun 2022 22:38:51 +0800 +Subject: [PATCH] clk: qoriq: Hold reference returned by of_get_parent() +Git-commit: a8ea4273bc26256ce3cce83164f0f51c5bf6e127 +Patch-mainline: v6.1-rc1 +References: git-fixes + +In legacy_init_clockgen(), we need to hold the reference returned +by of_get_parent() and use it to call of_node_put() for refcount +balance. + +Beside, in create_sysclk(), we need to call of_node_put() on 'sysclk' +also for refcount balance. + +Fixes: 0dfc86b3173f ("clk: qoriq: Move chip-specific knowledge into driver") +Signed-off-by: Liang He +Link: https://lore.kernel.org/r/20220628143851.171299-1-windhl@126.com +Signed-off-by: Stephen Boyd +Acked-by: Takashi Iwai + +--- + drivers/clk/clk-qoriq.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c +index 88898b97a443..5eddb9f0d6bd 100644 +--- a/drivers/clk/clk-qoriq.c ++++ b/drivers/clk/clk-qoriq.c +@@ -1063,8 +1063,13 @@ static void __init _clockgen_init(struct device_node *np, bool legacy); + */ + static void __init legacy_init_clockgen(struct device_node *np) + { +- if (!clockgen.node) +- _clockgen_init(of_get_parent(np), true); ++ if (!clockgen.node) { ++ struct device_node *parent_np; ++ ++ parent_np = of_get_parent(np); ++ _clockgen_init(parent_np, true); ++ of_node_put(parent_np); ++ } + } + + /* Legacy node */ +@@ -1159,6 +1164,7 @@ static struct clk * __init create_sysclk(const char *name) + sysclk = of_get_child_by_name(clockgen.node, "sysclk"); + if (sysclk) { + clk = sysclk_from_fixed(sysclk, name); ++ of_node_put(sysclk); + if (!IS_ERR(clk)) + return clk; + } +-- +2.35.3 + diff --git a/patches.suse/clk-sprd-Hold-reference-returned-by-of_get_parent.patch b/patches.suse/clk-sprd-Hold-reference-returned-by-of_get_parent.patch new file mode 100644 index 0000000..58a0e0c --- /dev/null +++ b/patches.suse/clk-sprd-Hold-reference-returned-by-of_get_parent.patch @@ -0,0 +1,52 @@ +From 91e6455bf715fb1558a0bf8f645ec1c131254a3c Mon Sep 17 00:00:00 2001 +From: Liang He +Date: Mon, 4 Jul 2022 08:47:29 +0800 +Subject: [PATCH] clk: sprd: Hold reference returned by of_get_parent() +Git-commit: 91e6455bf715fb1558a0bf8f645ec1c131254a3c +Patch-mainline: v6.1-rc1 +References: git-fixes + +We should hold the reference returned by of_get_parent() and use it +to call of_node_put() for refcount balance. + +Fixes: f95e8c7923d1 ("clk: sprd: support to get regmap from parent node") +Signed-off-by: Liang He +Link: https://lore.kernel.org/r/20220704004729.272481-1-windhl@126.com +Reviewed-by: Orson Zhai +Signed-off-by: Stephen Boyd +Acked-by: Takashi Iwai + +--- + drivers/clk/sprd/common.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/drivers/clk/sprd/common.c b/drivers/clk/sprd/common.c +index d620bbbcdfc8..ce81e4087a8f 100644 +--- a/drivers/clk/sprd/common.c ++++ b/drivers/clk/sprd/common.c +@@ -41,7 +41,7 @@ int sprd_clk_regmap_init(struct platform_device *pdev, + { + void __iomem *base; + struct device *dev = &pdev->dev; +- struct device_node *node = dev->of_node; ++ struct device_node *node = dev->of_node, *np; + struct regmap *regmap; + + if (of_find_property(node, "sprd,syscon", NULL)) { +@@ -50,9 +50,10 @@ int sprd_clk_regmap_init(struct platform_device *pdev, + pr_err("%s: failed to get syscon regmap\n", __func__); + return PTR_ERR(regmap); + } +- } else if (of_device_is_compatible(of_get_parent(dev->of_node), +- "syscon")) { +- regmap = device_node_to_regmap(of_get_parent(dev->of_node)); ++ } else if (of_device_is_compatible(np = of_get_parent(node), "syscon") || ++ (of_node_put(np), 0)) { ++ regmap = device_node_to_regmap(np); ++ of_node_put(np); + if (IS_ERR(regmap)) { + dev_err(dev, "failed to get regmap from its parent.\n"); + return PTR_ERR(regmap); +-- +2.35.3 + diff --git a/patches.suse/clk-tegra-Fix-refcount-leak-in-tegra114_clock_init.patch b/patches.suse/clk-tegra-Fix-refcount-leak-in-tegra114_clock_init.patch new file mode 100644 index 0000000..e68c07b --- /dev/null +++ b/patches.suse/clk-tegra-Fix-refcount-leak-in-tegra114_clock_init.patch @@ -0,0 +1,37 @@ +From db16a80c76ea395766913082b1e3f939dde29b2c Mon Sep 17 00:00:00 2001 +From: Miaoqian Lin +Date: Mon, 23 May 2022 18:38:34 +0400 +Subject: [PATCH] clk: tegra: Fix refcount leak in tegra114_clock_init +Git-commit: db16a80c76ea395766913082b1e3f939dde29b2c +Patch-mainline: v6.1-rc1 +References: git-fixes + +of_find_matching_node() returns a node pointer with refcount +incremented, we should use of_node_put() on it when not need anymore. +Add missing of_node_put() to avoid refcount leak. + +Fixes: 2cb5efefd6f7 ("clk: tegra: Implement clocks for Tegra114") +Signed-off-by: Miaoqian Lin +Link: https://lore.kernel.org/r/20220523143834.7587-1-linmq006@gmail.com +Signed-off-by: Stephen Boyd +Acked-by: Takashi Iwai + +--- + drivers/clk/tegra/clk-tegra114.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c +index ef718c4b3826..f7405a58877e 100644 +--- a/drivers/clk/tegra/clk-tegra114.c ++++ b/drivers/clk/tegra/clk-tegra114.c +@@ -1317,6 +1317,7 @@ static void __init tegra114_clock_init(struct device_node *np) + } + + pmc_base = of_iomap(node, 0); ++ of_node_put(node); + if (!pmc_base) { + pr_err("Can't map pmc registers\n"); + WARN_ON(1); +-- +2.35.3 + diff --git a/patches.suse/clk-tegra-Fix-refcount-leak-in-tegra210_clock_init.patch b/patches.suse/clk-tegra-Fix-refcount-leak-in-tegra210_clock_init.patch new file mode 100644 index 0000000..b549f55 --- /dev/null +++ b/patches.suse/clk-tegra-Fix-refcount-leak-in-tegra210_clock_init.patch @@ -0,0 +1,37 @@ +From 56c78cb1f00a9dde8cd762131ce8f4c5eb046fbb Mon Sep 17 00:00:00 2001 +From: Miaoqian Lin +Date: Mon, 23 May 2022 18:26:08 +0400 +Subject: [PATCH] clk: tegra: Fix refcount leak in tegra210_clock_init +Git-commit: 56c78cb1f00a9dde8cd762131ce8f4c5eb046fbb +Patch-mainline: v6.1-rc1 +References: git-fixes + +of_find_matching_node() returns a node pointer with refcount +incremented, we should use of_node_put() on it when not need anymore. +Add missing of_node_put() to avoid refcount leak. + +Fixes: 6b301a059eb2 ("clk: tegra: Add support for Tegra210 clocks") +Signed-off-by: Miaoqian Lin +Link: https://lore.kernel.org/r/20220523142608.65074-1-linmq006@gmail.com +Signed-off-by: Stephen Boyd +Acked-by: Takashi Iwai + +--- + drivers/clk/tegra/clk-tegra210.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c +index b9099012dc7b..499f999e91e1 100644 +--- a/drivers/clk/tegra/clk-tegra210.c ++++ b/drivers/clk/tegra/clk-tegra210.c +@@ -3748,6 +3748,7 @@ static void __init tegra210_clock_init(struct device_node *np) + } + + pmc_base = of_iomap(node, 0); ++ of_node_put(node); + if (!pmc_base) { + pr_err("Can't map pmc registers\n"); + WARN_ON(1); +-- +2.35.3 + diff --git a/patches.suse/clk-tegra20-Fix-refcount-leak-in-tegra20_clock_init.patch b/patches.suse/clk-tegra20-Fix-refcount-leak-in-tegra20_clock_init.patch new file mode 100644 index 0000000..698333b --- /dev/null +++ b/patches.suse/clk-tegra20-Fix-refcount-leak-in-tegra20_clock_init.patch @@ -0,0 +1,37 @@ +From 4e343bafe03ff68a62f48f8235cf98f2c685468b Mon Sep 17 00:00:00 2001 +From: Miaoqian Lin +Date: Mon, 23 May 2022 19:28:11 +0400 +Subject: [PATCH] clk: tegra20: Fix refcount leak in tegra20_clock_init +Git-commit: 4e343bafe03ff68a62f48f8235cf98f2c685468b +Patch-mainline: v6.1-rc1 +References: git-fixes + +of_find_matching_node() returns a node pointer with refcount +incremented, we should use of_node_put() on it when not need anymore. +Add missing of_node_put() to avoid refcount leak. + +Fixes: 37c26a906527 ("clk: tegra: add clock support for Tegra20") +Signed-off-by: Miaoqian Lin +Link: https://lore.kernel.org/r/20220523152811.19692-1-linmq006@gmail.com +Signed-off-by: Stephen Boyd +Acked-by: Takashi Iwai + +--- + drivers/clk/tegra/clk-tegra20.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c +index be3c33441cfc..8a4514f6d503 100644 +--- a/drivers/clk/tegra/clk-tegra20.c ++++ b/drivers/clk/tegra/clk-tegra20.c +@@ -1131,6 +1131,7 @@ static void __init tegra20_clock_init(struct device_node *np) + } + + pmc_base = of_iomap(node, 0); ++ of_node_put(node); + if (!pmc_base) { + pr_err("Can't map pmc registers\n"); + BUG(); +-- +2.35.3 + diff --git a/patches.suse/clk-ti-Stop-using-legacy-clkctrl-names-for-omap4-and.patch b/patches.suse/clk-ti-Stop-using-legacy-clkctrl-names-for-omap4-and.patch deleted file mode 100644 index 7d5cd8b..0000000 --- a/patches.suse/clk-ti-Stop-using-legacy-clkctrl-names-for-omap4-and.patch +++ /dev/null @@ -1,682 +0,0 @@ -From 255584b138343d4a28c6d25bd82d04b09460d672 Mon Sep 17 00:00:00 2001 -From: Tony Lindgren -Date: Wed, 15 Jun 2022 09:43:06 +0300 -Subject: [PATCH] clk: ti: Stop using legacy clkctrl names for omap4 and 5 -Git-commit: 255584b138343d4a28c6d25bd82d04b09460d672 -Patch-mainline: v6.0-rc1 -References: git-fixes - -With the addition of clock-output-names, we can now unify the internal -clock naming for omap4 and 5 to follow the other TI SoCs. - -We are still using legacy clkctrl names for omap4 and 5 based on the clock -manager name which is wrong. Instead, we want to use the clkctrl clock -based naming. - -We must now also drop the legacy TI_CLK_CLKCTRL_COMPAT quirk for the -clkctrl clock. - -This change will allow further devicetree warning cleanup as already -done for am3/4 and dra7. - -Cc: linux-clk@vger.kernel.org -Cc: Stephen Boyd -Cc: Tero Kristo -Signed-off-by: Tony Lindgren -Link: https://lore.kernel.org/r/20220615064306.22254-1-tony@atomide.com -Signed-off-by: Stephen Boyd -Acked-by: Takashi Iwai - ---- - drivers/clk/ti/clk-44xx.c | 210 +++++++++++++++++++------------------- - drivers/clk/ti/clk-54xx.c | 160 ++++++++++++++--------------- - drivers/clk/ti/clkctrl.c | 4 - - 3 files changed, 185 insertions(+), 189 deletions(-) - -diff --git a/drivers/clk/ti/clk-44xx.c b/drivers/clk/ti/clk-44xx.c -index d078e5d73ed9..868bc7af21b0 100644 ---- a/drivers/clk/ti/clk-44xx.c -+++ b/drivers/clk/ti/clk-44xx.c -@@ -56,7 +56,7 @@ static const struct omap_clkctrl_bit_data omap4_aess_bit_data[] __initconst = { - }; - - static const char * const omap4_func_dmic_abe_gfclk_parents[] __initconst = { -- "abe_cm:clk:0018:26", -+ "abe-clkctrl:0018:26", - "pad_clks_ck", - "slimbus_clk", - NULL, -@@ -76,7 +76,7 @@ static const struct omap_clkctrl_bit_data omap4_dmic_bit_data[] __initconst = { - }; - - static const char * const omap4_func_mcasp_abe_gfclk_parents[] __initconst = { -- "abe_cm:clk:0020:26", -+ "abe-clkctrl:0020:26", - "pad_clks_ck", - "slimbus_clk", - NULL, -@@ -89,7 +89,7 @@ static const struct omap_clkctrl_bit_data omap4_mcasp_bit_data[] __initconst = { - }; - - static const char * const omap4_func_mcbsp1_gfclk_parents[] __initconst = { -- "abe_cm:clk:0028:26", -+ "abe-clkctrl:0028:26", - "pad_clks_ck", - "slimbus_clk", - NULL, -@@ -102,7 +102,7 @@ static const struct omap_clkctrl_bit_data omap4_mcbsp1_bit_data[] __initconst = - }; - - static const char * const omap4_func_mcbsp2_gfclk_parents[] __initconst = { -- "abe_cm:clk:0030:26", -+ "abe-clkctrl:0030:26", - "pad_clks_ck", - "slimbus_clk", - NULL, -@@ -115,7 +115,7 @@ static const struct omap_clkctrl_bit_data omap4_mcbsp2_bit_data[] __initconst = - }; - - static const char * const omap4_func_mcbsp3_gfclk_parents[] __initconst = { -- "abe_cm:clk:0038:26", -+ "abe-clkctrl:0038:26", - "pad_clks_ck", - "slimbus_clk", - NULL, -@@ -183,18 +183,18 @@ static const struct omap_clkctrl_bit_data omap4_timer8_bit_data[] __initconst = - - static const struct omap_clkctrl_reg_data omap4_abe_clkctrl_regs[] __initconst = { - { OMAP4_L4_ABE_CLKCTRL, NULL, 0, "ocp_abe_iclk" }, -- { OMAP4_AESS_CLKCTRL, omap4_aess_bit_data, CLKF_SW_SUP, "abe_cm:clk:0008:24" }, -+ { OMAP4_AESS_CLKCTRL, omap4_aess_bit_data, CLKF_SW_SUP, "abe-clkctrl:0008:24" }, - { OMAP4_MCPDM_CLKCTRL, NULL, CLKF_SW_SUP, "pad_clks_ck" }, -- { OMAP4_DMIC_CLKCTRL, omap4_dmic_bit_data, CLKF_SW_SUP, "abe_cm:clk:0018:24" }, -- { OMAP4_MCASP_CLKCTRL, omap4_mcasp_bit_data, CLKF_SW_SUP, "abe_cm:clk:0020:24" }, -- { OMAP4_MCBSP1_CLKCTRL, omap4_mcbsp1_bit_data, CLKF_SW_SUP, "abe_cm:clk:0028:24" }, -- { OMAP4_MCBSP2_CLKCTRL, omap4_mcbsp2_bit_data, CLKF_SW_SUP, "abe_cm:clk:0030:24" }, -- { OMAP4_MCBSP3_CLKCTRL, omap4_mcbsp3_bit_data, CLKF_SW_SUP, "abe_cm:clk:0038:24" }, -- { OMAP4_SLIMBUS1_CLKCTRL, omap4_slimbus1_bit_data, CLKF_SW_SUP, "abe_cm:clk:0040:8" }, -- { OMAP4_TIMER5_CLKCTRL, omap4_timer5_bit_data, CLKF_SW_SUP, "abe_cm:clk:0048:24" }, -- { OMAP4_TIMER6_CLKCTRL, omap4_timer6_bit_data, CLKF_SW_SUP, "abe_cm:clk:0050:24" }, -- { OMAP4_TIMER7_CLKCTRL, omap4_timer7_bit_data, CLKF_SW_SUP, "abe_cm:clk:0058:24" }, -- { OMAP4_TIMER8_CLKCTRL, omap4_timer8_bit_data, CLKF_SW_SUP, "abe_cm:clk:0060:24" }, -+ { OMAP4_DMIC_CLKCTRL, omap4_dmic_bit_data, CLKF_SW_SUP, "abe-clkctrl:0018:24" }, -+ { OMAP4_MCASP_CLKCTRL, omap4_mcasp_bit_data, CLKF_SW_SUP, "abe-clkctrl:0020:24" }, -+ { OMAP4_MCBSP1_CLKCTRL, omap4_mcbsp1_bit_data, CLKF_SW_SUP, "abe-clkctrl:0028:24" }, -+ { OMAP4_MCBSP2_CLKCTRL, omap4_mcbsp2_bit_data, CLKF_SW_SUP, "abe-clkctrl:0030:24" }, -+ { OMAP4_MCBSP3_CLKCTRL, omap4_mcbsp3_bit_data, CLKF_SW_SUP, "abe-clkctrl:0038:24" }, -+ { OMAP4_SLIMBUS1_CLKCTRL, omap4_slimbus1_bit_data, CLKF_SW_SUP, "abe-clkctrl:0040:8" }, -+ { OMAP4_TIMER5_CLKCTRL, omap4_timer5_bit_data, CLKF_SW_SUP, "abe-clkctrl:0048:24" }, -+ { OMAP4_TIMER6_CLKCTRL, omap4_timer6_bit_data, CLKF_SW_SUP, "abe-clkctrl:0050:24" }, -+ { OMAP4_TIMER7_CLKCTRL, omap4_timer7_bit_data, CLKF_SW_SUP, "abe-clkctrl:0058:24" }, -+ { OMAP4_TIMER8_CLKCTRL, omap4_timer8_bit_data, CLKF_SW_SUP, "abe-clkctrl:0060:24" }, - { OMAP4_WD_TIMER3_CLKCTRL, NULL, CLKF_SW_SUP, "sys_32k_ck" }, - { 0 }, - }; -@@ -287,7 +287,7 @@ static const struct omap_clkctrl_bit_data omap4_fdif_bit_data[] __initconst = { - - static const struct omap_clkctrl_reg_data omap4_iss_clkctrl_regs[] __initconst = { - { OMAP4_ISS_CLKCTRL, omap4_iss_bit_data, CLKF_SW_SUP, "ducati_clk_mux_ck" }, -- { OMAP4_FDIF_CLKCTRL, omap4_fdif_bit_data, CLKF_SW_SUP, "iss_cm:clk:0008:24" }, -+ { OMAP4_FDIF_CLKCTRL, omap4_fdif_bit_data, CLKF_SW_SUP, "iss-clkctrl:0008:24" }, - { 0 }, - }; - -@@ -320,7 +320,7 @@ static const struct omap_clkctrl_bit_data omap4_dss_core_bit_data[] __initconst - }; - - static const struct omap_clkctrl_reg_data omap4_l3_dss_clkctrl_regs[] __initconst = { -- { OMAP4_DSS_CORE_CLKCTRL, omap4_dss_core_bit_data, CLKF_SW_SUP, "l3_dss_cm:clk:0000:8" }, -+ { OMAP4_DSS_CORE_CLKCTRL, omap4_dss_core_bit_data, CLKF_SW_SUP, "l3-dss-clkctrl:0000:8" }, - { 0 }, - }; - -@@ -336,7 +336,7 @@ static const struct omap_clkctrl_bit_data omap4_gpu_bit_data[] __initconst = { - }; - - static const struct omap_clkctrl_reg_data omap4_l3_gfx_clkctrl_regs[] __initconst = { -- { OMAP4_GPU_CLKCTRL, omap4_gpu_bit_data, CLKF_SW_SUP, "l3_gfx_cm:clk:0000:24" }, -+ { OMAP4_GPU_CLKCTRL, omap4_gpu_bit_data, CLKF_SW_SUP, "l3-gfx-clkctrl:0000:24" }, - { 0 }, - }; - -@@ -372,12 +372,12 @@ static const struct omap_clkctrl_bit_data omap4_hsi_bit_data[] __initconst = { - }; - - static const char * const omap4_usb_host_hs_utmi_p1_clk_parents[] __initconst = { -- "l3_init_cm:clk:0038:24", -+ "l3-init-clkctrl:0038:24", - NULL, - }; - - static const char * const omap4_usb_host_hs_utmi_p2_clk_parents[] __initconst = { -- "l3_init_cm:clk:0038:25", -+ "l3-init-clkctrl:0038:25", - NULL, - }; - -@@ -418,7 +418,7 @@ static const struct omap_clkctrl_bit_data omap4_usb_host_hs_bit_data[] __initcon - }; - - static const char * const omap4_usb_otg_hs_xclk_parents[] __initconst = { -- "l3_init_cm:clk:0040:24", -+ "l3-init-clkctrl:0040:24", - NULL, - }; - -@@ -452,14 +452,14 @@ static const struct omap_clkctrl_bit_data omap4_ocp2scp_usb_phy_bit_data[] __ini - }; - - static const struct omap_clkctrl_reg_data omap4_l3_init_clkctrl_regs[] __initconst = { -- { OMAP4_MMC1_CLKCTRL, omap4_mmc1_bit_data, CLKF_SW_SUP, "l3_init_cm:clk:0008:24" }, -- { OMAP4_MMC2_CLKCTRL, omap4_mmc2_bit_data, CLKF_SW_SUP, "l3_init_cm:clk:0010:24" }, -- { OMAP4_HSI_CLKCTRL, omap4_hsi_bit_data, CLKF_HW_SUP, "l3_init_cm:clk:0018:24" }, -+ { OMAP4_MMC1_CLKCTRL, omap4_mmc1_bit_data, CLKF_SW_SUP, "l3-init-clkctrl:0008:24" }, -+ { OMAP4_MMC2_CLKCTRL, omap4_mmc2_bit_data, CLKF_SW_SUP, "l3-init-clkctrl:0010:24" }, -+ { OMAP4_HSI_CLKCTRL, omap4_hsi_bit_data, CLKF_HW_SUP, "l3-init-clkctrl:0018:24" }, - { OMAP4_USB_HOST_HS_CLKCTRL, omap4_usb_host_hs_bit_data, CLKF_SW_SUP, "init_60m_fclk" }, - { OMAP4_USB_OTG_HS_CLKCTRL, omap4_usb_otg_hs_bit_data, CLKF_HW_SUP, "l3_div_ck" }, - { OMAP4_USB_TLL_HS_CLKCTRL, omap4_usb_tll_hs_bit_data, CLKF_HW_SUP, "l4_div_ck" }, - { OMAP4_USB_HOST_FS_CLKCTRL, NULL, CLKF_SW_SUP, "func_48mc_fclk" }, -- { OMAP4_OCP2SCP_USB_PHY_CLKCTRL, omap4_ocp2scp_usb_phy_bit_data, CLKF_HW_SUP, "l3_init_cm:clk:00c0:8" }, -+ { OMAP4_OCP2SCP_USB_PHY_CLKCTRL, omap4_ocp2scp_usb_phy_bit_data, CLKF_HW_SUP, "l3-init-clkctrl:00c0:8" }, - { 0 }, - }; - -@@ -530,7 +530,7 @@ static const struct omap_clkctrl_bit_data omap4_gpio6_bit_data[] __initconst = { - }; - - static const char * const omap4_per_mcbsp4_gfclk_parents[] __initconst = { -- "l4_per_cm:clk:00c0:26", -+ "l4-per-clkctrl:00c0:26", - "pad_clks_ck", - NULL, - }; -@@ -570,12 +570,12 @@ static const struct omap_clkctrl_bit_data omap4_slimbus2_bit_data[] __initconst - }; - - static const struct omap_clkctrl_reg_data omap4_l4_per_clkctrl_regs[] __initconst = { -- { OMAP4_TIMER10_CLKCTRL, omap4_timer10_bit_data, CLKF_SW_SUP, "l4_per_cm:clk:0008:24" }, -- { OMAP4_TIMER11_CLKCTRL, omap4_timer11_bit_data, CLKF_SW_SUP, "l4_per_cm:clk:0010:24" }, -- { OMAP4_TIMER2_CLKCTRL, omap4_timer2_bit_data, CLKF_SW_SUP, "l4_per_cm:clk:0018:24" }, -- { OMAP4_TIMER3_CLKCTRL, omap4_timer3_bit_data, CLKF_SW_SUP, "l4_per_cm:clk:0020:24" }, -- { OMAP4_TIMER4_CLKCTRL, omap4_timer4_bit_data, CLKF_SW_SUP, "l4_per_cm:clk:0028:24" }, -- { OMAP4_TIMER9_CLKCTRL, omap4_timer9_bit_data, CLKF_SW_SUP, "l4_per_cm:clk:0030:24" }, -+ { OMAP4_TIMER10_CLKCTRL, omap4_timer10_bit_data, CLKF_SW_SUP, "l4-per-clkctrl:0008:24" }, -+ { OMAP4_TIMER11_CLKCTRL, omap4_timer11_bit_data, CLKF_SW_SUP, "l4-per-clkctrl:0010:24" }, -+ { OMAP4_TIMER2_CLKCTRL, omap4_timer2_bit_data, CLKF_SW_SUP, "l4-per-clkctrl:0018:24" }, -+ { OMAP4_TIMER3_CLKCTRL, omap4_timer3_bit_data, CLKF_SW_SUP, "l4-per-clkctrl:0020:24" }, -+ { OMAP4_TIMER4_CLKCTRL, omap4_timer4_bit_data, CLKF_SW_SUP, "l4-per-clkctrl:0028:24" }, -+ { OMAP4_TIMER9_CLKCTRL, omap4_timer9_bit_data, CLKF_SW_SUP, "l4-per-clkctrl:0030:24" }, - { OMAP4_ELM_CLKCTRL, NULL, 0, "l4_div_ck" }, - { OMAP4_GPIO2_CLKCTRL, omap4_gpio2_bit_data, CLKF_HW_SUP, "l4_div_ck" }, - { OMAP4_GPIO3_CLKCTRL, omap4_gpio3_bit_data, CLKF_HW_SUP, "l4_div_ck" }, -@@ -588,14 +588,14 @@ static const struct omap_clkctrl_reg_data omap4_l4_per_clkctrl_regs[] __initcons - { OMAP4_I2C3_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" }, - { OMAP4_I2C4_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" }, - { OMAP4_L4_PER_CLKCTRL, NULL, 0, "l4_div_ck" }, -- { OMAP4_MCBSP4_CLKCTRL, omap4_mcbsp4_bit_data, CLKF_SW_SUP, "l4_per_cm:clk:00c0:24" }, -+ { OMAP4_MCBSP4_CLKCTRL, omap4_mcbsp4_bit_data, CLKF_SW_SUP, "l4-per-clkctrl:00c0:24" }, - { OMAP4_MCSPI1_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" }, - { OMAP4_MCSPI2_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" }, - { OMAP4_MCSPI3_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" }, - { OMAP4_MCSPI4_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" }, - { OMAP4_MMC3_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" }, - { OMAP4_MMC4_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" }, -- { OMAP4_SLIMBUS2_CLKCTRL, omap4_slimbus2_bit_data, CLKF_SW_SUP, "l4_per_cm:clk:0118:8" }, -+ { OMAP4_SLIMBUS2_CLKCTRL, omap4_slimbus2_bit_data, CLKF_SW_SUP, "l4-per-clkctrl:0118:8" }, - { OMAP4_UART1_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" }, - { OMAP4_UART2_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" }, - { OMAP4_UART3_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" }, -@@ -630,7 +630,7 @@ static const struct omap_clkctrl_reg_data omap4_l4_wkup_clkctrl_regs[] __initcon - { OMAP4_L4_WKUP_CLKCTRL, NULL, 0, "l4_wkup_clk_mux_ck" }, - { OMAP4_WD_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "sys_32k_ck" }, - { OMAP4_GPIO1_CLKCTRL, omap4_gpio1_bit_data, CLKF_HW_SUP, "l4_wkup_clk_mux_ck" }, -- { OMAP4_TIMER1_CLKCTRL, omap4_timer1_bit_data, CLKF_SW_SUP, "l4_wkup_cm:clk:0020:24" }, -+ { OMAP4_TIMER1_CLKCTRL, omap4_timer1_bit_data, CLKF_SW_SUP, "l4-wkup-clkctrl:0020:24" }, - { OMAP4_COUNTER_32K_CLKCTRL, NULL, 0, "sys_32k_ck" }, - { OMAP4_KBD_CLKCTRL, NULL, CLKF_SW_SUP, "sys_32k_ck" }, - { 0 }, -@@ -644,7 +644,7 @@ static const char * const omap4_pmd_stm_clock_mux_ck_parents[] __initconst = { - }; - - static const char * const omap4_trace_clk_div_div_ck_parents[] __initconst = { -- "emu_sys_cm:clk:0000:22", -+ "emu-sys-clkctrl:0000:22", - NULL, - }; - -@@ -662,7 +662,7 @@ static const struct omap_clkctrl_div_data omap4_trace_clk_div_div_ck_data __init - }; - - static const char * const omap4_stm_clk_div_ck_parents[] __initconst = { -- "emu_sys_cm:clk:0000:20", -+ "emu-sys-clkctrl:0000:20", - NULL, - }; - -@@ -716,73 +716,73 @@ static struct ti_dt_clk omap44xx_clks[] = { - * hwmod support. Once hwmod is removed, these can be removed - * also. - */ -- DT_CLK(NULL, "aess_fclk", "abe_cm:0008:24"), -- DT_CLK(NULL, "cm2_dm10_mux", "l4_per_cm:0008:24"), -- DT_CLK(NULL, "cm2_dm11_mux", "l4_per_cm:0010:24"), -- DT_CLK(NULL, "cm2_dm2_mux", "l4_per_cm:0018:24"), -- DT_CLK(NULL, "cm2_dm3_mux", "l4_per_cm:0020:24"), -- DT_CLK(NULL, "cm2_dm4_mux", "l4_per_cm:0028:24"), -- DT_CLK(NULL, "cm2_dm9_mux", "l4_per_cm:0030:24"), -- DT_CLK(NULL, "dmic_sync_mux_ck", "abe_cm:0018:26"), -- DT_CLK(NULL, "dmt1_clk_mux", "l4_wkup_cm:0020:24"), -- DT_CLK(NULL, "dss_48mhz_clk", "l3_dss_cm:0000:9"), -- DT_CLK(NULL, "dss_dss_clk", "l3_dss_cm:0000:8"), -- DT_CLK(NULL, "dss_sys_clk", "l3_dss_cm:0000:10"), -- DT_CLK(NULL, "dss_tv_clk", "l3_dss_cm:0000:11"), -- DT_CLK(NULL, "fdif_fck", "iss_cm:0008:24"), -- DT_CLK(NULL, "func_dmic_abe_gfclk", "abe_cm:0018:24"), -- DT_CLK(NULL, "func_mcasp_abe_gfclk", "abe_cm:0020:24"), -- DT_CLK(NULL, "func_mcbsp1_gfclk", "abe_cm:0028:24"), -- DT_CLK(NULL, "func_mcbsp2_gfclk", "abe_cm:0030:24"), -- DT_CLK(NULL, "func_mcbsp3_gfclk", "abe_cm:0038:24"), -- DT_CLK(NULL, "gpio1_dbclk", "l4_wkup_cm:0018:8"), -- DT_CLK(NULL, "gpio2_dbclk", "l4_per_cm:0040:8"), -- DT_CLK(NULL, "gpio3_dbclk", "l4_per_cm:0048:8"), -- DT_CLK(NULL, "gpio4_dbclk", "l4_per_cm:0050:8"), -- DT_CLK(NULL, "gpio5_dbclk", "l4_per_cm:0058:8"), -- DT_CLK(NULL, "gpio6_dbclk", "l4_per_cm:0060:8"), -- DT_CLK(NULL, "hsi_fck", "l3_init_cm:0018:24"), -- DT_CLK(NULL, "hsmmc1_fclk", "l3_init_cm:0008:24"), -- DT_CLK(NULL, "hsmmc2_fclk", "l3_init_cm:0010:24"), -- DT_CLK(NULL, "iss_ctrlclk", "iss_cm:0000:8"), -- DT_CLK(NULL, "mcasp_sync_mux_ck", "abe_cm:0020:26"), -- DT_CLK(NULL, "mcbsp1_sync_mux_ck", "abe_cm:0028:26"), -- DT_CLK(NULL, "mcbsp2_sync_mux_ck", "abe_cm:0030:26"), -- DT_CLK(NULL, "mcbsp3_sync_mux_ck", "abe_cm:0038:26"), -- DT_CLK(NULL, "mcbsp4_sync_mux_ck", "l4_per_cm:00c0:26"), -- DT_CLK(NULL, "ocp2scp_usb_phy_phy_48m", "l3_init_cm:00c0:8"), -- DT_CLK(NULL, "otg_60m_gfclk", "l3_init_cm:0040:24"), -- DT_CLK(NULL, "per_mcbsp4_gfclk", "l4_per_cm:00c0:24"), -- DT_CLK(NULL, "pmd_stm_clock_mux_ck", "emu_sys_cm:0000:20"), -- DT_CLK(NULL, "pmd_trace_clk_mux_ck", "emu_sys_cm:0000:22"), -- DT_CLK(NULL, "sgx_clk_mux", "l3_gfx_cm:0000:24"), -- DT_CLK(NULL, "slimbus1_fclk_0", "abe_cm:0040:8"), -- DT_CLK(NULL, "slimbus1_fclk_1", "abe_cm:0040:9"), -- DT_CLK(NULL, "slimbus1_fclk_2", "abe_cm:0040:10"), -- DT_CLK(NULL, "slimbus1_slimbus_clk", "abe_cm:0040:11"), -- DT_CLK(NULL, "slimbus2_fclk_0", "l4_per_cm:0118:8"), -- DT_CLK(NULL, "slimbus2_fclk_1", "l4_per_cm:0118:9"), -- DT_CLK(NULL, "slimbus2_slimbus_clk", "l4_per_cm:0118:10"), -- DT_CLK(NULL, "stm_clk_div_ck", "emu_sys_cm:0000:27"), -- DT_CLK(NULL, "timer5_sync_mux", "abe_cm:0048:24"), -- DT_CLK(NULL, "timer6_sync_mux", "abe_cm:0050:24"), -- DT_CLK(NULL, "timer7_sync_mux", "abe_cm:0058:24"), -- DT_CLK(NULL, "timer8_sync_mux", "abe_cm:0060:24"), -- DT_CLK(NULL, "trace_clk_div_div_ck", "emu_sys_cm:0000:24"), -- DT_CLK(NULL, "usb_host_hs_func48mclk", "l3_init_cm:0038:15"), -- DT_CLK(NULL, "usb_host_hs_hsic480m_p1_clk", "l3_init_cm:0038:13"), -- DT_CLK(NULL, "usb_host_hs_hsic480m_p2_clk", "l3_init_cm:0038:14"), -- DT_CLK(NULL, "usb_host_hs_hsic60m_p1_clk", "l3_init_cm:0038:11"), -- DT_CLK(NULL, "usb_host_hs_hsic60m_p2_clk", "l3_init_cm:0038:12"), -- DT_CLK(NULL, "usb_host_hs_utmi_p1_clk", "l3_init_cm:0038:8"), -- DT_CLK(NULL, "usb_host_hs_utmi_p2_clk", "l3_init_cm:0038:9"), -- DT_CLK(NULL, "usb_host_hs_utmi_p3_clk", "l3_init_cm:0038:10"), -- DT_CLK(NULL, "usb_otg_hs_xclk", "l3_init_cm:0040:8"), -- DT_CLK(NULL, "usb_tll_hs_usb_ch0_clk", "l3_init_cm:0048:8"), -- DT_CLK(NULL, "usb_tll_hs_usb_ch1_clk", "l3_init_cm:0048:9"), -- DT_CLK(NULL, "usb_tll_hs_usb_ch2_clk", "l3_init_cm:0048:10"), -- DT_CLK(NULL, "utmi_p1_gfclk", "l3_init_cm:0038:24"), -- DT_CLK(NULL, "utmi_p2_gfclk", "l3_init_cm:0038:25"), -+ DT_CLK(NULL, "aess_fclk", "abe-clkctrl:0008:24"), -+ DT_CLK(NULL, "cm2_dm10_mux", "l4-per-clkctrl:0008:24"), -+ DT_CLK(NULL, "cm2_dm11_mux", "l4-per-clkctrl:0010:24"), -+ DT_CLK(NULL, "cm2_dm2_mux", "l4-per-clkctrl:0018:24"), -+ DT_CLK(NULL, "cm2_dm3_mux", "l4-per-clkctrl:0020:24"), -+ DT_CLK(NULL, "cm2_dm4_mux", "l4-per-clkctrl:0028:24"), -+ DT_CLK(NULL, "cm2_dm9_mux", "l4-per-clkctrl:0030:24"), -+ DT_CLK(NULL, "dmic_sync_mux_ck", "abe-clkctrl:0018:26"), -+ DT_CLK(NULL, "dmt1_clk_mux", "l4-wkup-clkctrl:0020:24"), -+ DT_CLK(NULL, "dss_48mhz_clk", "l3-dss-clkctrl:0000:9"), -+ DT_CLK(NULL, "dss_dss_clk", "l3-dss-clkctrl:0000:8"), -+ DT_CLK(NULL, "dss_sys_clk", "l3-dss-clkctrl:0000:10"), -+ DT_CLK(NULL, "dss_tv_clk", "l3-dss-clkctrl:0000:11"), -+ DT_CLK(NULL, "fdif_fck", "iss-clkctrl:0008:24"), -+ DT_CLK(NULL, "func_dmic_abe_gfclk", "abe-clkctrl:0018:24"), -+ DT_CLK(NULL, "func_mcasp_abe_gfclk", "abe-clkctrl:0020:24"), -+ DT_CLK(NULL, "func_mcbsp1_gfclk", "abe-clkctrl:0028:24"), -+ DT_CLK(NULL, "func_mcbsp2_gfclk", "abe-clkctrl:0030:24"), -+ DT_CLK(NULL, "func_mcbsp3_gfclk", "abe-clkctrl:0038:24"), -+ DT_CLK(NULL, "gpio1_dbclk", "l4-wkup-clkctrl:0018:8"), -+ DT_CLK(NULL, "gpio2_dbclk", "l4-per-clkctrl:0040:8"), -+ DT_CLK(NULL, "gpio3_dbclk", "l4-per-clkctrl:0048:8"), -+ DT_CLK(NULL, "gpio4_dbclk", "l4-per-clkctrl:0050:8"), -+ DT_CLK(NULL, "gpio5_dbclk", "l4-per-clkctrl:0058:8"), -+ DT_CLK(NULL, "gpio6_dbclk", "l4-per-clkctrl:0060:8"), -+ DT_CLK(NULL, "hsi_fck", "l3-init-clkctrl:0018:24"), -+ DT_CLK(NULL, "hsmmc1_fclk", "l3-init-clkctrl:0008:24"), -+ DT_CLK(NULL, "hsmmc2_fclk", "l3-init-clkctrl:0010:24"), -+ DT_CLK(NULL, "iss_ctrlclk", "iss-clkctrl:0000:8"), -+ DT_CLK(NULL, "mcasp_sync_mux_ck", "abe-clkctrl:0020:26"), -+ DT_CLK(NULL, "mcbsp1_sync_mux_ck", "abe-clkctrl:0028:26"), -+ DT_CLK(NULL, "mcbsp2_sync_mux_ck", "abe-clkctrl:0030:26"), -+ DT_CLK(NULL, "mcbsp3_sync_mux_ck", "abe-clkctrl:0038:26"), -+ DT_CLK(NULL, "mcbsp4_sync_mux_ck", "l4-per-clkctrl:00c0:26"), -+ DT_CLK(NULL, "ocp2scp_usb_phy_phy_48m", "l3-init-clkctrl:00c0:8"), -+ DT_CLK(NULL, "otg_60m_gfclk", "l3-init-clkctrl:0040:24"), -+ DT_CLK(NULL, "per_mcbsp4_gfclk", "l4-per-clkctrl:00c0:24"), -+ DT_CLK(NULL, "pmd_stm_clock_mux_ck", "emu-sys-clkctrl:0000:20"), -+ DT_CLK(NULL, "pmd_trace_clk_mux_ck", "emu-sys-clkctrl:0000:22"), -+ DT_CLK(NULL, "sgx_clk_mux", "l3-gfx-clkctrl:0000:24"), -+ DT_CLK(NULL, "slimbus1_fclk_0", "abe-clkctrl:0040:8"), -+ DT_CLK(NULL, "slimbus1_fclk_1", "abe-clkctrl:0040:9"), -+ DT_CLK(NULL, "slimbus1_fclk_2", "abe-clkctrl:0040:10"), -+ DT_CLK(NULL, "slimbus1_slimbus_clk", "abe-clkctrl:0040:11"), -+ DT_CLK(NULL, "slimbus2_fclk_0", "l4-per-clkctrl:0118:8"), -+ DT_CLK(NULL, "slimbus2_fclk_1", "l4-per-clkctrl:0118:9"), -+ DT_CLK(NULL, "slimbus2_slimbus_clk", "l4-per-clkctrl:0118:10"), -+ DT_CLK(NULL, "stm_clk_div_ck", "emu-sys-clkctrl:0000:27"), -+ DT_CLK(NULL, "timer5_sync_mux", "abe-clkctrl:0048:24"), -+ DT_CLK(NULL, "timer6_sync_mux", "abe-clkctrl:0050:24"), -+ DT_CLK(NULL, "timer7_sync_mux", "abe-clkctrl:0058:24"), -+ DT_CLK(NULL, "timer8_sync_mux", "abe-clkctrl:0060:24"), -+ DT_CLK(NULL, "trace_clk_div_div_ck", "emu-sys-clkctrl:0000:24"), -+ DT_CLK(NULL, "usb_host_hs_func48mclk", "l3-init-clkctrl:0038:15"), -+ DT_CLK(NULL, "usb_host_hs_hsic480m_p1_clk", "l3-init-clkctrl:0038:13"), -+ DT_CLK(NULL, "usb_host_hs_hsic480m_p2_clk", "l3-init-clkctrl:0038:14"), -+ DT_CLK(NULL, "usb_host_hs_hsic60m_p1_clk", "l3-init-clkctrl:0038:11"), -+ DT_CLK(NULL, "usb_host_hs_hsic60m_p2_clk", "l3-init-clkctrl:0038:12"), -+ DT_CLK(NULL, "usb_host_hs_utmi_p1_clk", "l3-init-clkctrl:0038:8"), -+ DT_CLK(NULL, "usb_host_hs_utmi_p2_clk", "l3-init-clkctrl:0038:9"), -+ DT_CLK(NULL, "usb_host_hs_utmi_p3_clk", "l3_init-clkctrl:0038:10"), -+ DT_CLK(NULL, "usb_otg_hs_xclk", "l3-init-clkctrl:0040:8"), -+ DT_CLK(NULL, "usb_tll_hs_usb_ch0_clk", "l3-init-clkctrl:0048:8"), -+ DT_CLK(NULL, "usb_tll_hs_usb_ch1_clk", "l3-init-clkctrl:0048:9"), -+ DT_CLK(NULL, "usb_tll_hs_usb_ch2_clk", "l3-init-clkctrl:0048:10"), -+ DT_CLK(NULL, "utmi_p1_gfclk", "l3-init-clkctrl:0038:24"), -+ DT_CLK(NULL, "utmi_p2_gfclk", "l3-init-clkctrl:0038:25"), - { .node_name = NULL }, - }; - -diff --git a/drivers/clk/ti/clk-54xx.c b/drivers/clk/ti/clk-54xx.c -index 90e0a9ea6351..b4aff76eb373 100644 ---- a/drivers/clk/ti/clk-54xx.c -+++ b/drivers/clk/ti/clk-54xx.c -@@ -50,7 +50,7 @@ static const struct omap_clkctrl_bit_data omap5_aess_bit_data[] __initconst = { - }; - - static const char * const omap5_dmic_gfclk_parents[] __initconst = { -- "abe_cm:clk:0018:26", -+ "abe-clkctrl:0018:26", - "pad_clks_ck", - "slimbus_clk", - NULL, -@@ -70,7 +70,7 @@ static const struct omap_clkctrl_bit_data omap5_dmic_bit_data[] __initconst = { - }; - - static const char * const omap5_mcbsp1_gfclk_parents[] __initconst = { -- "abe_cm:clk:0028:26", -+ "abe-clkctrl:0028:26", - "pad_clks_ck", - "slimbus_clk", - NULL, -@@ -83,7 +83,7 @@ static const struct omap_clkctrl_bit_data omap5_mcbsp1_bit_data[] __initconst = - }; - - static const char * const omap5_mcbsp2_gfclk_parents[] __initconst = { -- "abe_cm:clk:0030:26", -+ "abe-clkctrl:0030:26", - "pad_clks_ck", - "slimbus_clk", - NULL, -@@ -96,7 +96,7 @@ static const struct omap_clkctrl_bit_data omap5_mcbsp2_bit_data[] __initconst = - }; - - static const char * const omap5_mcbsp3_gfclk_parents[] __initconst = { -- "abe_cm:clk:0038:26", -+ "abe-clkctrl:0038:26", - "pad_clks_ck", - "slimbus_clk", - NULL, -@@ -136,16 +136,16 @@ static const struct omap_clkctrl_bit_data omap5_timer8_bit_data[] __initconst = - - static const struct omap_clkctrl_reg_data omap5_abe_clkctrl_regs[] __initconst = { - { OMAP5_L4_ABE_CLKCTRL, NULL, 0, "abe_iclk" }, -- { OMAP5_AESS_CLKCTRL, omap5_aess_bit_data, CLKF_SW_SUP, "abe_cm:clk:0008:24" }, -+ { OMAP5_AESS_CLKCTRL, omap5_aess_bit_data, CLKF_SW_SUP, "abe-clkctrl:0008:24" }, - { OMAP5_MCPDM_CLKCTRL, NULL, CLKF_SW_SUP, "pad_clks_ck" }, -- { OMAP5_DMIC_CLKCTRL, omap5_dmic_bit_data, CLKF_SW_SUP, "abe_cm:clk:0018:24" }, -- { OMAP5_MCBSP1_CLKCTRL, omap5_mcbsp1_bit_data, CLKF_SW_SUP, "abe_cm:clk:0028:24" }, -- { OMAP5_MCBSP2_CLKCTRL, omap5_mcbsp2_bit_data, CLKF_SW_SUP, "abe_cm:clk:0030:24" }, -- { OMAP5_MCBSP3_CLKCTRL, omap5_mcbsp3_bit_data, CLKF_SW_SUP, "abe_cm:clk:0038:24" }, -- { OMAP5_TIMER5_CLKCTRL, omap5_timer5_bit_data, CLKF_SW_SUP, "abe_cm:clk:0048:24" }, -- { OMAP5_TIMER6_CLKCTRL, omap5_timer6_bit_data, CLKF_SW_SUP, "abe_cm:clk:0050:24" }, -- { OMAP5_TIMER7_CLKCTRL, omap5_timer7_bit_data, CLKF_SW_SUP, "abe_cm:clk:0058:24" }, -- { OMAP5_TIMER8_CLKCTRL, omap5_timer8_bit_data, CLKF_SW_SUP, "abe_cm:clk:0060:24" }, -+ { OMAP5_DMIC_CLKCTRL, omap5_dmic_bit_data, CLKF_SW_SUP, "abe-clkctrl:0018:24" }, -+ { OMAP5_MCBSP1_CLKCTRL, omap5_mcbsp1_bit_data, CLKF_SW_SUP, "abe-clkctrl:0028:24" }, -+ { OMAP5_MCBSP2_CLKCTRL, omap5_mcbsp2_bit_data, CLKF_SW_SUP, "abe-clkctrl:0030:24" }, -+ { OMAP5_MCBSP3_CLKCTRL, omap5_mcbsp3_bit_data, CLKF_SW_SUP, "abe-clkctrl:0038:24" }, -+ { OMAP5_TIMER5_CLKCTRL, omap5_timer5_bit_data, CLKF_SW_SUP, "abe-clkctrl:0048:24" }, -+ { OMAP5_TIMER6_CLKCTRL, omap5_timer6_bit_data, CLKF_SW_SUP, "abe-clkctrl:0050:24" }, -+ { OMAP5_TIMER7_CLKCTRL, omap5_timer7_bit_data, CLKF_SW_SUP, "abe-clkctrl:0058:24" }, -+ { OMAP5_TIMER8_CLKCTRL, omap5_timer8_bit_data, CLKF_SW_SUP, "abe-clkctrl:0060:24" }, - { 0 }, - }; - -@@ -268,12 +268,12 @@ static const struct omap_clkctrl_bit_data omap5_gpio8_bit_data[] __initconst = { - }; - - static const struct omap_clkctrl_reg_data omap5_l4per_clkctrl_regs[] __initconst = { -- { OMAP5_TIMER10_CLKCTRL, omap5_timer10_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0008:24" }, -- { OMAP5_TIMER11_CLKCTRL, omap5_timer11_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0010:24" }, -- { OMAP5_TIMER2_CLKCTRL, omap5_timer2_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0018:24" }, -- { OMAP5_TIMER3_CLKCTRL, omap5_timer3_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0020:24" }, -- { OMAP5_TIMER4_CLKCTRL, omap5_timer4_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0028:24" }, -- { OMAP5_TIMER9_CLKCTRL, omap5_timer9_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0030:24" }, -+ { OMAP5_TIMER10_CLKCTRL, omap5_timer10_bit_data, CLKF_SW_SUP, "l4per-clkctrl:0008:24" }, -+ { OMAP5_TIMER11_CLKCTRL, omap5_timer11_bit_data, CLKF_SW_SUP, "l4per-clkctrl:0010:24" }, -+ { OMAP5_TIMER2_CLKCTRL, omap5_timer2_bit_data, CLKF_SW_SUP, "l4per-clkctrl:0018:24" }, -+ { OMAP5_TIMER3_CLKCTRL, omap5_timer3_bit_data, CLKF_SW_SUP, "l4per-clkctrl:0020:24" }, -+ { OMAP5_TIMER4_CLKCTRL, omap5_timer4_bit_data, CLKF_SW_SUP, "l4per-clkctrl:0028:24" }, -+ { OMAP5_TIMER9_CLKCTRL, omap5_timer9_bit_data, CLKF_SW_SUP, "l4per-clkctrl:0030:24" }, - { OMAP5_GPIO2_CLKCTRL, omap5_gpio2_bit_data, CLKF_HW_SUP, "l4_root_clk_div" }, - { OMAP5_GPIO3_CLKCTRL, omap5_gpio3_bit_data, CLKF_HW_SUP, "l4_root_clk_div" }, - { OMAP5_GPIO4_CLKCTRL, omap5_gpio4_bit_data, CLKF_HW_SUP, "l4_root_clk_div" }, -@@ -345,7 +345,7 @@ static const struct omap_clkctrl_bit_data omap5_dss_core_bit_data[] __initconst - }; - - static const struct omap_clkctrl_reg_data omap5_dss_clkctrl_regs[] __initconst = { -- { OMAP5_DSS_CORE_CLKCTRL, omap5_dss_core_bit_data, CLKF_SW_SUP, "dss_cm:clk:0000:8" }, -+ { OMAP5_DSS_CORE_CLKCTRL, omap5_dss_core_bit_data, CLKF_SW_SUP, "dss-clkctrl:0000:8" }, - { 0 }, - }; - -@@ -378,7 +378,7 @@ static const struct omap_clkctrl_bit_data omap5_gpu_core_bit_data[] __initconst - }; - - static const struct omap_clkctrl_reg_data omap5_gpu_clkctrl_regs[] __initconst = { -- { OMAP5_GPU_CLKCTRL, omap5_gpu_core_bit_data, CLKF_SW_SUP, "gpu_cm:clk:0000:24" }, -+ { OMAP5_GPU_CLKCTRL, omap5_gpu_core_bit_data, CLKF_SW_SUP, "gpu-clkctrl:0000:24" }, - { 0 }, - }; - -@@ -389,7 +389,7 @@ static const char * const omap5_mmc1_fclk_mux_parents[] __initconst = { - }; - - static const char * const omap5_mmc1_fclk_parents[] __initconst = { -- "l3init_cm:clk:0008:24", -+ "l3init-clkctrl:0008:24", - NULL, - }; - -@@ -405,7 +405,7 @@ static const struct omap_clkctrl_bit_data omap5_mmc1_bit_data[] __initconst = { - }; - - static const char * const omap5_mmc2_fclk_parents[] __initconst = { -- "l3init_cm:clk:0010:24", -+ "l3init-clkctrl:0010:24", - NULL, - }; - -@@ -430,12 +430,12 @@ static const char * const omap5_usb_host_hs_hsic480m_p3_clk_parents[] __initcons - }; - - static const char * const omap5_usb_host_hs_utmi_p1_clk_parents[] __initconst = { -- "l3init_cm:clk:0038:24", -+ "l3init-clkctrl:0038:24", - NULL, - }; - - static const char * const omap5_usb_host_hs_utmi_p2_clk_parents[] __initconst = { -- "l3init_cm:clk:0038:25", -+ "l3init-clkctrl:0038:25", - NULL, - }; - -@@ -494,8 +494,8 @@ static const struct omap_clkctrl_bit_data omap5_usb_otg_ss_bit_data[] __initcons - }; - - static const struct omap_clkctrl_reg_data omap5_l3init_clkctrl_regs[] __initconst = { -- { OMAP5_MMC1_CLKCTRL, omap5_mmc1_bit_data, CLKF_SW_SUP, "l3init_cm:clk:0008:25" }, -- { OMAP5_MMC2_CLKCTRL, omap5_mmc2_bit_data, CLKF_SW_SUP, "l3init_cm:clk:0010:25" }, -+ { OMAP5_MMC1_CLKCTRL, omap5_mmc1_bit_data, CLKF_SW_SUP, "l3init-clkctrl:0008:25" }, -+ { OMAP5_MMC2_CLKCTRL, omap5_mmc2_bit_data, CLKF_SW_SUP, "l3init-clkctrl:0010:25" }, - { OMAP5_USB_HOST_HS_CLKCTRL, omap5_usb_host_hs_bit_data, CLKF_SW_SUP, "l3init_60m_fclk" }, - { OMAP5_USB_TLL_HS_CLKCTRL, omap5_usb_tll_hs_bit_data, CLKF_HW_SUP, "l4_root_clk_div" }, - { OMAP5_SATA_CLKCTRL, omap5_sata_bit_data, CLKF_SW_SUP, "func_48m_fclk" }, -@@ -519,7 +519,7 @@ static const struct omap_clkctrl_reg_data omap5_wkupaon_clkctrl_regs[] __initcon - { OMAP5_L4_WKUP_CLKCTRL, NULL, 0, "wkupaon_iclk_mux" }, - { OMAP5_WD_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "sys_32k_ck" }, - { OMAP5_GPIO1_CLKCTRL, omap5_gpio1_bit_data, CLKF_HW_SUP, "wkupaon_iclk_mux" }, -- { OMAP5_TIMER1_CLKCTRL, omap5_timer1_bit_data, CLKF_SW_SUP, "wkupaon_cm:clk:0020:24" }, -+ { OMAP5_TIMER1_CLKCTRL, omap5_timer1_bit_data, CLKF_SW_SUP, "wkupaon-clkctrl:0020:24" }, - { OMAP5_COUNTER_32K_CLKCTRL, NULL, 0, "wkupaon_iclk_mux" }, - { OMAP5_KBD_CLKCTRL, NULL, CLKF_SW_SUP, "sys_32k_ck" }, - { 0 }, -@@ -549,58 +549,58 @@ const struct omap_clkctrl_data omap5_clkctrl_data[] __initconst = { - static struct ti_dt_clk omap54xx_clks[] = { - DT_CLK(NULL, "timer_32k_ck", "sys_32k_ck"), - DT_CLK(NULL, "sys_clkin_ck", "sys_clkin"), -- DT_CLK(NULL, "dmic_gfclk", "abe_cm:0018:24"), -- DT_CLK(NULL, "dmic_sync_mux_ck", "abe_cm:0018:26"), -- DT_CLK(NULL, "dss_32khz_clk", "dss_cm:0000:11"), -- DT_CLK(NULL, "dss_48mhz_clk", "dss_cm:0000:9"), -- DT_CLK(NULL, "dss_dss_clk", "dss_cm:0000:8"), -- DT_CLK(NULL, "dss_sys_clk", "dss_cm:0000:10"), -- DT_CLK(NULL, "gpio1_dbclk", "wkupaon_cm:0018:8"), -- DT_CLK(NULL, "gpio2_dbclk", "l4per_cm:0040:8"), -- DT_CLK(NULL, "gpio3_dbclk", "l4per_cm:0048:8"), -- DT_CLK(NULL, "gpio4_dbclk", "l4per_cm:0050:8"), -- DT_CLK(NULL, "gpio5_dbclk", "l4per_cm:0058:8"), -- DT_CLK(NULL, "gpio6_dbclk", "l4per_cm:0060:8"), -- DT_CLK(NULL, "gpio7_dbclk", "l4per_cm:00f0:8"), -- DT_CLK(NULL, "gpio8_dbclk", "l4per_cm:00f8:8"), -- DT_CLK(NULL, "mcbsp1_gfclk", "abe_cm:0028:24"), -- DT_CLK(NULL, "mcbsp1_sync_mux_ck", "abe_cm:0028:26"), -- DT_CLK(NULL, "mcbsp2_gfclk", "abe_cm:0030:24"), -- DT_CLK(NULL, "mcbsp2_sync_mux_ck", "abe_cm:0030:26"), -- DT_CLK(NULL, "mcbsp3_gfclk", "abe_cm:0038:24"), -- DT_CLK(NULL, "mcbsp3_sync_mux_ck", "abe_cm:0038:26"), -- DT_CLK(NULL, "mmc1_32khz_clk", "l3init_cm:0008:8"), -- DT_CLK(NULL, "mmc1_fclk", "l3init_cm:0008:25"), -- DT_CLK(NULL, "mmc1_fclk_mux", "l3init_cm:0008:24"), -- DT_CLK(NULL, "mmc2_fclk", "l3init_cm:0010:25"), -- DT_CLK(NULL, "mmc2_fclk_mux", "l3init_cm:0010:24"), -- DT_CLK(NULL, "sata_ref_clk", "l3init_cm:0068:8"), -- DT_CLK(NULL, "timer10_gfclk_mux", "l4per_cm:0008:24"), -- DT_CLK(NULL, "timer11_gfclk_mux", "l4per_cm:0010:24"), -- DT_CLK(NULL, "timer1_gfclk_mux", "wkupaon_cm:0020:24"), -- DT_CLK(NULL, "timer2_gfclk_mux", "l4per_cm:0018:24"), -- DT_CLK(NULL, "timer3_gfclk_mux", "l4per_cm:0020:24"), -- DT_CLK(NULL, "timer4_gfclk_mux", "l4per_cm:0028:24"), -- DT_CLK(NULL, "timer5_gfclk_mux", "abe_cm:0048:24"), -- DT_CLK(NULL, "timer6_gfclk_mux", "abe_cm:0050:24"), -- DT_CLK(NULL, "timer7_gfclk_mux", "abe_cm:0058:24"), -- DT_CLK(NULL, "timer8_gfclk_mux", "abe_cm:0060:24"), -- DT_CLK(NULL, "timer9_gfclk_mux", "l4per_cm:0030:24"), -- DT_CLK(NULL, "usb_host_hs_hsic480m_p1_clk", "l3init_cm:0038:13"), -- DT_CLK(NULL, "usb_host_hs_hsic480m_p2_clk", "l3init_cm:0038:14"), -- DT_CLK(NULL, "usb_host_hs_hsic480m_p3_clk", "l3init_cm:0038:7"), -- DT_CLK(NULL, "usb_host_hs_hsic60m_p1_clk", "l3init_cm:0038:11"), -- DT_CLK(NULL, "usb_host_hs_hsic60m_p2_clk", "l3init_cm:0038:12"), -- DT_CLK(NULL, "usb_host_hs_hsic60m_p3_clk", "l3init_cm:0038:6"), -- DT_CLK(NULL, "usb_host_hs_utmi_p1_clk", "l3init_cm:0038:8"), -- DT_CLK(NULL, "usb_host_hs_utmi_p2_clk", "l3init_cm:0038:9"), -- DT_CLK(NULL, "usb_host_hs_utmi_p3_clk", "l3init_cm:0038:10"), -- DT_CLK(NULL, "usb_otg_ss_refclk960m", "l3init_cm:00d0:8"), -- DT_CLK(NULL, "usb_tll_hs_usb_ch0_clk", "l3init_cm:0048:8"), -- DT_CLK(NULL, "usb_tll_hs_usb_ch1_clk", "l3init_cm:0048:9"), -- DT_CLK(NULL, "usb_tll_hs_usb_ch2_clk", "l3init_cm:0048:10"), -- DT_CLK(NULL, "utmi_p1_gfclk", "l3init_cm:0038:24"), -- DT_CLK(NULL, "utmi_p2_gfclk", "l3init_cm:0038:25"), -+ DT_CLK(NULL, "dmic_gfclk", "abe-clkctrl:0018:24"), -+ DT_CLK(NULL, "dmic_sync_mux_ck", "abe-clkctrl:0018:26"), -+ DT_CLK(NULL, "dss_32khz_clk", "dss-clkctrl:0000:11"), -+ DT_CLK(NULL, "dss_48mhz_clk", "dss-clkctrl:0000:9"), -+ DT_CLK(NULL, "dss_dss_clk", "dss-clkctrl:0000:8"), -+ DT_CLK(NULL, "dss_sys_clk", "dss-clkctrl:0000:10"), -+ DT_CLK(NULL, "gpio1_dbclk", "wkupaon-clkctrl:0018:8"), -+ DT_CLK(NULL, "gpio2_dbclk", "l4per-clkctrl:0040:8"), -+ DT_CLK(NULL, "gpio3_dbclk", "l4per-clkctrl:0048:8"), -+ DT_CLK(NULL, "gpio4_dbclk", "l4per-clkctrl:0050:8"), -+ DT_CLK(NULL, "gpio5_dbclk", "l4per-clkctrl:0058:8"), -+ DT_CLK(NULL, "gpio6_dbclk", "l4per-clkctrl:0060:8"), -+ DT_CLK(NULL, "gpio7_dbclk", "l4per-clkctrl:00f0:8"), -+ DT_CLK(NULL, "gpio8_dbclk", "l4per-clkctrl:00f8:8"), -+ DT_CLK(NULL, "mcbsp1_gfclk", "abe-clkctrl:0028:24"), -+ DT_CLK(NULL, "mcbsp1_sync_mux_ck", "abe-clkctrl:0028:26"), -+ DT_CLK(NULL, "mcbsp2_gfclk", "abe-clkctrl:0030:24"), -+ DT_CLK(NULL, "mcbsp2_sync_mux_ck", "abe-clkctrl:0030:26"), -+ DT_CLK(NULL, "mcbsp3_gfclk", "abe-clkctrl:0038:24"), -+ DT_CLK(NULL, "mcbsp3_sync_mux_ck", "abe-clkctrl:0038:26"), -+ DT_CLK(NULL, "mmc1_32khz_clk", "l3init-clkctrl:0008:8"), -+ DT_CLK(NULL, "mmc1_fclk", "l3init-clkctrl:0008:25"), -+ DT_CLK(NULL, "mmc1_fclk_mux", "l3init-clkctrl:0008:24"), -+ DT_CLK(NULL, "mmc2_fclk", "l3init-clkctrl:0010:25"), -+ DT_CLK(NULL, "mmc2_fclk_mux", "l3init-clkctrl:0010:24"), -+ DT_CLK(NULL, "sata_ref_clk", "l3init-clkctrl:0068:8"), -+ DT_CLK(NULL, "timer10_gfclk_mux", "l4per-clkctrl:0008:24"), -+ DT_CLK(NULL, "timer11_gfclk_mux", "l4per-clkctrl:0010:24"), -+ DT_CLK(NULL, "timer1_gfclk_mux", "wkupaon-clkctrl:0020:24"), -+ DT_CLK(NULL, "timer2_gfclk_mux", "l4per-clkctrl:0018:24"), -+ DT_CLK(NULL, "timer3_gfclk_mux", "l4per-clkctrl:0020:24"), -+ DT_CLK(NULL, "timer4_gfclk_mux", "l4per-clkctrl:0028:24"), -+ DT_CLK(NULL, "timer5_gfclk_mux", "abe-clkctrl:0048:24"), -+ DT_CLK(NULL, "timer6_gfclk_mux", "abe-clkctrl:0050:24"), -+ DT_CLK(NULL, "timer7_gfclk_mux", "abe-clkctrl:0058:24"), -+ DT_CLK(NULL, "timer8_gfclk_mux", "abe-clkctrl:0060:24"), -+ DT_CLK(NULL, "timer9_gfclk_mux", "l4per-clkctrl:0030:24"), -+ DT_CLK(NULL, "usb_host_hs_hsic480m_p1_clk", "l3init-clkctrl:0038:13"), -+ DT_CLK(NULL, "usb_host_hs_hsic480m_p2_clk", "l3init-clkctrl:0038:14"), -+ DT_CLK(NULL, "usb_host_hs_hsic480m_p3_clk", "l3init-clkctrl:0038:7"), -+ DT_CLK(NULL, "usb_host_hs_hsic60m_p1_clk", "l3init-clkctrl:0038:11"), -+ DT_CLK(NULL, "usb_host_hs_hsic60m_p2_clk", "l3init-clkctrl:0038:12"), -+ DT_CLK(NULL, "usb_host_hs_hsic60m_p3_clk", "l3init-clkctrl:0038:6"), -+ DT_CLK(NULL, "usb_host_hs_utmi_p1_clk", "l3init-clkctrl:0038:8"), -+ DT_CLK(NULL, "usb_host_hs_utmi_p2_clk", "l3init-clkctrl:0038:9"), -+ DT_CLK(NULL, "usb_host_hs_utmi_p3_clk", "l3init-clkctrl:0038:10"), -+ DT_CLK(NULL, "usb_otg_ss_refclk960m", "l3init-clkctrl:00d0:8"), -+ DT_CLK(NULL, "usb_tll_hs_usb_ch0_clk", "l3init-clkctrl:0048:8"), -+ DT_CLK(NULL, "usb_tll_hs_usb_ch1_clk", "l3init-clkctrl:0048:9"), -+ DT_CLK(NULL, "usb_tll_hs_usb_ch2_clk", "l3init-clkctrl:0048:10"), -+ DT_CLK(NULL, "utmi_p1_gfclk", "l3init-clkctrl:0038:24"), -+ DT_CLK(NULL, "utmi_p2_gfclk", "l3init-clkctrl:0038:25"), - { .node_name = NULL }, - }; - -diff --git a/drivers/clk/ti/clkctrl.c b/drivers/clk/ti/clkctrl.c -index 617360e20d86..e23bf0458632 100644 ---- a/drivers/clk/ti/clkctrl.c -+++ b/drivers/clk/ti/clkctrl.c -@@ -528,10 +528,6 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node) - char *c; - u16 soc_mask = 0; - -- if (!(ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT) && -- of_node_name_eq(node, "clk")) -- ti_clk_features.flags |= TI_CLK_CLKCTRL_COMPAT; -- - addrp = of_get_address(node, 0, NULL, NULL); - addr = (u32)of_translate_address(node, addrp); - --- -2.35.3 - diff --git a/patches.suse/clk-ti-dra7-atl-Fix-reference-leak-in-of_dra7_atl_cl.patch b/patches.suse/clk-ti-dra7-atl-Fix-reference-leak-in-of_dra7_atl_cl.patch new file mode 100644 index 0000000..9c53d33 --- /dev/null +++ b/patches.suse/clk-ti-dra7-atl-Fix-reference-leak-in-of_dra7_atl_cl.patch @@ -0,0 +1,60 @@ +From 9c59a01caba26ec06fefd6ca1f22d5fd1de57d63 Mon Sep 17 00:00:00 2001 +From: Miaoqian Lin +Date: Thu, 2 Jun 2022 07:08:36 +0400 +Subject: [PATCH] clk: ti: dra7-atl: Fix reference leak in of_dra7_atl_clk_probe +Git-commit: 9c59a01caba26ec06fefd6ca1f22d5fd1de57d63 +Patch-mainline: v6.1-rc1 +References: git-fixes + +pm_runtime_get_sync() will increment pm usage counter. +Forgetting to putting operation will result in reference leak. +Add missing pm_runtime_put_sync in some error paths. + +Fixes: 9ac33b0ce81f ("CLK: TI: Driver for DRA7 ATL (Audio Tracking Logic)") +Signed-off-by: Miaoqian Lin +Link: https://lore.kernel.org/r/20220602030838.52057-1-linmq006@gmail.com +Reviewed-by: Tony Lindgren +Signed-off-by: Stephen Boyd +Acked-by: Takashi Iwai + +--- + drivers/clk/ti/clk-dra7-atl.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/clk/ti/clk-dra7-atl.c b/drivers/clk/ti/clk-dra7-atl.c +index f0f5bf68b6d2..ff4d6a951681 100644 +--- a/drivers/clk/ti/clk-dra7-atl.c ++++ b/drivers/clk/ti/clk-dra7-atl.c +@@ -245,14 +245,16 @@ static int of_dra7_atl_clk_probe(struct platform_device *pdev) + if (rc) { + pr_err("%s: failed to lookup atl clock %d\n", __func__, + i); +- return -EINVAL; ++ ret = -EINVAL; ++ goto pm_put; + } + + clk = of_clk_get_from_provider(&clkspec); + if (IS_ERR(clk)) { + pr_err("%s: failed to get atl clock %d from provider\n", + __func__, i); +- return PTR_ERR(clk); ++ ret = PTR_ERR(clk); ++ goto pm_put; + } + + cdesc = to_atl_desc(__clk_get_hw(clk)); +@@ -285,8 +287,9 @@ static int of_dra7_atl_clk_probe(struct platform_device *pdev) + if (cdesc->enabled) + atl_clk_enable(__clk_get_hw(clk)); + } +- pm_runtime_put_sync(cinfo->dev); + ++pm_put: ++ pm_runtime_put_sync(cinfo->dev); + return ret; + } + +-- +2.35.3 + diff --git a/patches.suse/clk-vc5-Fix-5P49V6901-outputs-disabling-when-enablin.patch b/patches.suse/clk-vc5-Fix-5P49V6901-outputs-disabling-when-enablin.patch new file mode 100644 index 0000000..5446c1d --- /dev/null +++ b/patches.suse/clk-vc5-Fix-5P49V6901-outputs-disabling-when-enablin.patch @@ -0,0 +1,55 @@ +From c388cc804016cf0f65afdc2362b120aa594ff3e6 Mon Sep 17 00:00:00 2001 +From: Serge Semin +Date: Fri, 30 Sep 2022 01:53:55 +0300 +Subject: [PATCH] clk: vc5: Fix 5P49V6901 outputs disabling when enabling FOD +Git-commit: c388cc804016cf0f65afdc2362b120aa594ff3e6 +Patch-mainline: v6.1-rc1 +References: git-fixes + +We have discovered random glitches during the system boot up procedure. +The problem investigation led us to the weird outcomes: when none of the +Renesas 5P49V6901 ports are explicitly enabled by the kernel driver, the +glitches disappeared. It was a mystery since the SoC external clock +domains were fed with different 5P49V6901 outputs. The driver code didn't +seem like bogus either. We almost despaired to find out a root cause when +the solution has been found for a more modern revision of the chip. It +turned out the 5P49V6901 clock generator stopped its output for a short +period of time during the VC5_OUT_DIV_CONTROL register writing. The same +problem was found for the 5P49V6965 revision of the chip and was +successfully fixed in commit fc336ae622df ("clk: vc5: fix output disabling +when enabling a FOD") by enabling the "bypass_sync" flag hidden inside +"Unused Factory Reserved Register". Even though the 5P49V6901 registers +description and programming guide doesn't provide any intel regarding that +flag, setting it up anyway in the officially unused register completely +eliminated the denoted glitches. Thus let's activate the functionality +submitted in commit fc336ae622df ("clk: vc5: fix output disabling when +enabling a FOD") for the Renesas 5P49V6901 chip too in order to remove the +ports implicit inter-dependency. + +Fixes: dbf6b16f5683 ("clk: vc5: Add support for IDT VersaClock 5P49V6901") +Signed-off-by: Serge Semin +Reviewed-by: Luca Ceresoli +Link: https://lore.kernel.org/r/20220929225402.9696-2-Sergey.Semin@baikalelectronics.ru +Signed-off-by: Stephen Boyd +Acked-by: Takashi Iwai + +--- + drivers/clk/clk-versaclock5.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c +index e7be3e54b9be..03cfef494b49 100644 +--- a/drivers/clk/clk-versaclock5.c ++++ b/drivers/clk/clk-versaclock5.c +@@ -1204,7 +1204,7 @@ static const struct vc5_chip_info idt_5p49v6901_info = { + .model = IDT_VC6_5P49V6901, + .clk_fod_cnt = 4, + .clk_out_cnt = 5, +- .flags = VC5_HAS_PFD_FREQ_DBL, ++ .flags = VC5_HAS_PFD_FREQ_DBL | VC5_HAS_BYPASS_SYNC_BIT, + }; + + static const struct vc5_chip_info idt_5p49v6965_info = { +-- +2.35.3 + diff --git a/patches.suse/cpufreq-CPPC-Enable-fast_switch.patch b/patches.suse/cpufreq-CPPC-Enable-fast_switch.patch new file mode 100644 index 0000000..8e75f14 --- /dev/null +++ b/patches.suse/cpufreq-CPPC-Enable-fast_switch.patch @@ -0,0 +1,127 @@ +From: Pierre Gondois +Date: Wed, 18 May 2022 11:09:00 +0200 +Subject: cpufreq: CPPC: Enable fast_switch +Patch-mainline: v5.19-rc1 +Git-commit: 3cc30dd00a580ca0c9c0b01639841cfd72d10129 +References: jsc#PED-1408 + +The communication mean of the _CPC desired performance can be +PCC, System Memory, System IO, or Functional Fixed Hardware. + +commit b7898fda5bc7 ("cpufreq: Support for fast frequency switching") +fast_switching is 'for switching CPU frequencies from interrupt +context'. +Writes to SystemMemory and SystemIo are fast and suitable this. +This is not the case for PCC and might not be the case for FFH. + +Enable fast_switching for the cppc_cpufreq driver in above cases. + +Add cppc_allow_fast_switch() to check the desired performance +register address space and set fast_switching accordingly. + +Signed-off-by: Pierre Gondois +Reviewed-by: Sudeep Holla +Acked-by: Viresh Kumar +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/cppc_acpi.c | 18 ++++++++++++++++++ + drivers/cpufreq/cppc_cpufreq.c | 24 ++++++++++++++++++++++++ + include/acpi/cppc_acpi.h | 5 +++++ + 3 files changed, 47 insertions(+) + +--- a/drivers/acpi/cppc_acpi.c ++++ b/drivers/acpi/cppc_acpi.c +@@ -434,6 +434,24 @@ bool acpi_cpc_valid(void) + } + EXPORT_SYMBOL_GPL(acpi_cpc_valid); + ++bool cppc_allow_fast_switch(void) ++{ ++ struct cpc_register_resource *desired_reg; ++ struct cpc_desc *cpc_ptr; ++ int cpu; ++ ++ for_each_possible_cpu(cpu) { ++ cpc_ptr = per_cpu(cpc_desc_ptr, cpu); ++ desired_reg = &cpc_ptr->cpc_regs[DESIRED_PERF]; ++ if (!CPC_IN_SYSTEM_MEMORY(desired_reg) && ++ !CPC_IN_SYSTEM_IO(desired_reg)) ++ return false; ++ } ++ ++ return true; ++} ++EXPORT_SYMBOL_GPL(cppc_allow_fast_switch); ++ + /** + * acpi_get_psd_map - Map the CPUs in the freq domain of a given cpu + * @cpu: Find all CPUs that share a domain with cpu. +--- a/drivers/cpufreq/cppc_cpufreq.c ++++ b/drivers/cpufreq/cppc_cpufreq.c +@@ -390,6 +390,27 @@ static int cppc_cpufreq_set_target(struc + return ret; + } + ++static unsigned int cppc_cpufreq_fast_switch(struct cpufreq_policy *policy, ++ unsigned int target_freq) ++{ ++ struct cppc_cpudata *cpu_data = policy->driver_data; ++ unsigned int cpu = policy->cpu; ++ u32 desired_perf; ++ int ret; ++ ++ desired_perf = cppc_cpufreq_khz_to_perf(cpu_data, target_freq); ++ cpu_data->perf_ctrls.desired_perf = desired_perf; ++ ret = cppc_set_perf(cpu, &cpu_data->perf_ctrls); ++ ++ if (ret) { ++ pr_debug("Failed to set target on CPU:%d. ret:%d\n", ++ cpu, ret); ++ return 0; ++ } ++ ++ return target_freq; ++} ++ + static int cppc_verify_policy(struct cpufreq_policy_data *policy) + { + cpufreq_verify_within_cpu_limits(policy); +@@ -537,6 +558,8 @@ static int cppc_cpufreq_cpu_init(struct + goto out; + } + ++ policy->fast_switch_possible = cppc_allow_fast_switch(); ++ + /* + * If 'highest_perf' is greater than 'nominal_perf', we assume CPU Boost + * is supported. +@@ -682,6 +705,7 @@ static struct cpufreq_driver cppc_cpufre + .verify = cppc_verify_policy, + .target = cppc_cpufreq_set_target, + .get = cppc_cpufreq_get_rate, ++ .fast_switch = cppc_cpufreq_fast_switch, + .init = cppc_cpufreq_cpu_init, + .exit = cppc_cpufreq_cpu_exit, + .set_boost = cppc_cpufreq_set_boost, +--- a/include/acpi/cppc_acpi.h ++++ b/include/acpi/cppc_acpi.h +@@ -141,6 +141,7 @@ extern int cppc_set_perf(int cpu, struct + extern int cppc_set_enable(int cpu, bool enable); + extern int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps); + extern bool acpi_cpc_valid(void); ++extern bool cppc_allow_fast_switch(void); + extern int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data); + extern unsigned int cppc_get_transition_latency(int cpu); + extern bool cpc_ffh_supported(void); +@@ -175,6 +176,10 @@ static inline bool acpi_cpc_valid(void) + { + return false; + } ++static inline bool cppc_allow_fast_switch(void) ++{ ++ return false; ++} + static inline unsigned int cppc_get_transition_latency(int cpu) + { + return CPUFREQ_ETERNAL; diff --git a/patches.suse/crypto-akcipher-default-implementation-for-setting-a.patch b/patches.suse/crypto-akcipher-default-implementation-for-setting-a.patch new file mode 100644 index 0000000..34df983 --- /dev/null +++ b/patches.suse/crypto-akcipher-default-implementation-for-setting-a.patch @@ -0,0 +1,70 @@ +From bc155c6c188c2f0c5749993b1405673d25a80389 Mon Sep 17 00:00:00 2001 +From: Ignat Korchagin +Date: Wed, 31 Aug 2022 19:37:06 +0100 +Subject: [PATCH] crypto: akcipher - default implementation for setting a private key +Git-commit: bc155c6c188c2f0c5749993b1405673d25a80389 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Changes from v1: + * removed the default implementation from set_pub_key: it is assumed that + an implementation must always have this callback defined as there are + no use case for an algorithm, which doesn't need a public key + +Many akcipher implementations (like ECDSA) support only signature +verifications, so they don't have all callbacks defined. + +Commit 78a0324f4a53 ("crypto: akcipher - default implementations for +request callbacks") introduced default callbacks for sign/verify +operations, which just return an error code. + +However, these are not enough, because before calling sign the caller would +likely call set_priv_key first on the instantiated transform (as the +in-kernel testmgr does). This function does not have a default stub, so the +kernel crashes, when trying to set a private key on an akcipher, which +doesn't support signature generation. + +I've noticed this, when trying to add a KAT vector for ECDSA signature to +the testmgr. + +With this patch the testmgr returns an error in dmesg (as it should) +instead of crashing the kernel NULL ptr dereference. + +Fixes: 78a0324f4a53 ("crypto: akcipher - default implementations for request callbacks") +Signed-off-by: Ignat Korchagin +Signed-off-by: Herbert Xu +Acked-by: Takashi Iwai + +--- + crypto/akcipher.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/crypto/akcipher.c b/crypto/akcipher.c +index f866085c8a4a..ab975a420e1e 100644 +--- a/crypto/akcipher.c ++++ b/crypto/akcipher.c +@@ -120,6 +120,12 @@ static int akcipher_default_op(struct akcipher_request *req) + return -ENOSYS; + } + ++static int akcipher_default_set_key(struct crypto_akcipher *tfm, ++ const void *key, unsigned int keylen) ++{ ++ return -ENOSYS; ++} ++ + int crypto_register_akcipher(struct akcipher_alg *alg) + { + struct crypto_alg *base = &alg->base; +@@ -132,6 +138,8 @@ int crypto_register_akcipher(struct akcipher_alg *alg) + alg->encrypt = akcipher_default_op; + if (!alg->decrypt) + alg->decrypt = akcipher_default_op; ++ if (!alg->set_priv_key) ++ alg->set_priv_key = akcipher_default_set_key; + + akcipher_prepare_alg(alg); + return crypto_register_alg(base); +-- +2.35.3 + diff --git a/patches.suse/crypto-cavium-prevent-integer-overflow-loading-firmw.patch b/patches.suse/crypto-cavium-prevent-integer-overflow-loading-firmw.patch new file mode 100644 index 0000000..4caa6d1 --- /dev/null +++ b/patches.suse/crypto-cavium-prevent-integer-overflow-loading-firmw.patch @@ -0,0 +1,56 @@ +From 2526d6bf27d15054bb0778b2f7bc6625fd934905 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Mon, 19 Sep 2022 09:43:27 +0300 +Subject: [PATCH] crypto: cavium - prevent integer overflow loading firmware +Git-commit: 2526d6bf27d15054bb0778b2f7bc6625fd934905 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The "code_length" value comes from the firmware file. If your firmware +is untrusted realistically there is probably very little you can do to +protect yourself. Still we try to limit the damage as much as possible. +Also Smatch marks any data read from the filesystem as untrusted and +prints warnings if it not capped correctly. + +The "ntohl(ucode->code_length) * 2" multiplication can have an +integer overflow. + +Fixes: 9e2c7d99941d ("crypto: cavium - Add Support for Octeon-tx CPT Engine") +Signed-off-by: Dan Carpenter +Signed-off-by: Herbert Xu +Acked-by: Takashi Iwai + +--- + drivers/crypto/cavium/cpt/cptpf_main.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/crypto/cavium/cpt/cptpf_main.c b/drivers/crypto/cavium/cpt/cptpf_main.c +index 8c32d0eb8fcf..6872ac344001 100644 +--- a/drivers/crypto/cavium/cpt/cptpf_main.c ++++ b/drivers/crypto/cavium/cpt/cptpf_main.c +@@ -253,6 +253,7 @@ static int cpt_ucode_load_fw(struct cpt_device *cpt, const u8 *fw, bool is_ae) + const struct firmware *fw_entry; + struct device *dev = &cpt->pdev->dev; + struct ucode_header *ucode; ++ unsigned int code_length; + struct microcode *mcode; + int j, ret = 0; + +@@ -263,11 +264,12 @@ static int cpt_ucode_load_fw(struct cpt_device *cpt, const u8 *fw, bool is_ae) + ucode = (struct ucode_header *)fw_entry->data; + mcode = &cpt->mcode[cpt->next_mc_idx]; + memcpy(mcode->version, (u8 *)fw_entry->data, CPT_UCODE_VERSION_SZ); +- mcode->code_size = ntohl(ucode->code_length) * 2; +- if (!mcode->code_size) { ++ code_length = ntohl(ucode->code_length); ++ if (code_length == 0 || code_length >= INT_MAX / 2) { + ret = -EINVAL; + goto fw_release; + } ++ mcode->code_size = code_length * 2; + + mcode->is_ae = is_ae; + mcode->core_mask = 0ULL; +-- +2.35.3 + diff --git a/patches.suse/crypto-ccp-Release-dma-channels-before-dmaengine-unr.patch b/patches.suse/crypto-ccp-Release-dma-channels-before-dmaengine-unr.patch new file mode 100644 index 0000000..c083e34 --- /dev/null +++ b/patches.suse/crypto-ccp-Release-dma-channels-before-dmaengine-unr.patch @@ -0,0 +1,54 @@ +From 68dbe80f5b510c66c800b9e8055235c5b07e37d1 Mon Sep 17 00:00:00 2001 +From: Koba Ko +Date: Thu, 1 Sep 2022 22:47:12 +0800 +Subject: [PATCH] crypto: ccp - Release dma channels before dmaengine unrgister +Git-commit: 68dbe80f5b510c66c800b9e8055235c5b07e37d1 +Patch-mainline: v6.1-rc1 +References: git-fixes + +A warning is shown during shutdown, + +__dma_async_device_channel_unregister called while 2 clients hold a reference +Warning: CPU: 15 PID: 1 at drivers/dma/dmaengine.c:1110 __dma_async_device_channel_unregister+0xb7/0xc0 + +Call dma_release_channel for occupied channles before dma_async_device_unregister. + +Fixes: 54cce8ecb925 ("crypto: ccp - ccp_dmaengine_unregister release dma channels") +Reported-by: kernel test robot +Signed-off-by: Koba Ko +Acked-by: Tom Lendacky +Signed-off-by: Herbert Xu +Acked-by: Takashi Iwai + +--- + drivers/crypto/ccp/ccp-dmaengine.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/crypto/ccp/ccp-dmaengine.c b/drivers/crypto/ccp/ccp-dmaengine.c +index 7d4b4ad1db1f..9f753cb4f5f1 100644 +--- a/drivers/crypto/ccp/ccp-dmaengine.c ++++ b/drivers/crypto/ccp/ccp-dmaengine.c +@@ -641,6 +641,10 @@ static void ccp_dma_release(struct ccp_device *ccp) + for (i = 0; i < ccp->cmd_q_count; i++) { + chan = ccp->ccp_dma_chan + i; + dma_chan = &chan->dma_chan; ++ ++ if (dma_chan->client_count) ++ dma_release_channel(dma_chan); ++ + tasklet_kill(&chan->cleanup_tasklet); + list_del_rcu(&dma_chan->device_node); + } +@@ -766,8 +770,8 @@ void ccp_dmaengine_unregister(struct ccp_device *ccp) + if (!dmaengine) + return; + +- dma_async_device_unregister(dma_dev); + ccp_dma_release(ccp); ++ dma_async_device_unregister(dma_dev); + + kmem_cache_destroy(ccp->dma_desc_cache); + kmem_cache_destroy(ccp->dma_cmd_cache); +-- +2.35.3 + diff --git a/patches.suse/crypto-hisilicon-zip-fix-mismatch-in-get-set-sgl_sge.patch b/patches.suse/crypto-hisilicon-zip-fix-mismatch-in-get-set-sgl_sge.patch new file mode 100644 index 0000000..4bdd837 --- /dev/null +++ b/patches.suse/crypto-hisilicon-zip-fix-mismatch-in-get-set-sgl_sge.patch @@ -0,0 +1,53 @@ +From d74f9340097a881869c4c22ca376654cc2516ecc Mon Sep 17 00:00:00 2001 +From: Ye Weihua +Date: Thu, 28 Jul 2022 10:07:58 +0800 +Subject: [PATCH] crypto: hisilicon/zip - fix mismatch in get/set sgl_sge_nr +Git-commit: d74f9340097a881869c4c22ca376654cc2516ecc +Patch-mainline: v6.1-rc1 +References: git-fixes + +KASAN reported this Bug: + + [17619.659757] BUG: KASAN: global-out-of-bounds in param_get_int+0x34/0x60 + [17619.673193] Read of size 4 at addr fffff01332d7ed00 by task read_all/1507958 + ... + [17619.698934] The buggy address belongs to the variable: + [17619.708371] sgl_sge_nr+0x0/0xffffffffffffa300 [hisi_zip] + +There is a mismatch in hisi_zip when get/set the variable sgl_sge_nr. +The type of sgl_sge_nr is u16, and get/set sgl_sge_nr by +param_get/set_int. + +Replacing param_get/set_int to param_get/set_ushort can fix this bug. + +Fixes: f081fda293ffb ("crypto: hisilicon - add sgl_sge_nr module param for zip") +Signed-off-by: Ye Weihua +Signed-off-by: Herbert Xu +Acked-by: Takashi Iwai + +--- + drivers/crypto/hisilicon/zip/zip_crypto.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/crypto/hisilicon/zip/zip_crypto.c b/drivers/crypto/hisilicon/zip/zip_crypto.c +index ad35434a3fdb..06a2d6e81ae9 100644 +--- a/drivers/crypto/hisilicon/zip/zip_crypto.c ++++ b/drivers/crypto/hisilicon/zip/zip_crypto.c +@@ -123,12 +123,12 @@ static int sgl_sge_nr_set(const char *val, const struct kernel_param *kp) + if (ret || n == 0 || n > HISI_ACC_SGL_SGE_NR_MAX) + return -EINVAL; + +- return param_set_int(val, kp); ++ return param_set_ushort(val, kp); + } + + static const struct kernel_param_ops sgl_sge_nr_ops = { + .set = sgl_sge_nr_set, +- .get = param_get_int, ++ .get = param_get_ushort, + }; + + static u16 sgl_sge_nr = HZIP_SGL_SGE_NR; +-- +2.35.3 + diff --git a/patches.suse/crypto-inside-secure-Change-swab-to-swab32.patch b/patches.suse/crypto-inside-secure-Change-swab-to-swab32.patch new file mode 100644 index 0000000..997a520 --- /dev/null +++ b/patches.suse/crypto-inside-secure-Change-swab-to-swab32.patch @@ -0,0 +1,65 @@ +From 664593407e936b6438fbfaaf98876910fd31cf9a Mon Sep 17 00:00:00 2001 +From: Peter Harliman Liem +Date: Tue, 6 Sep 2022 10:51:28 +0800 +Subject: [PATCH] crypto: inside-secure - Change swab to swab32 +Git-commit: 664593407e936b6438fbfaaf98876910fd31cf9a +Patch-mainline: v6.1-rc1 +References: git-fixes + +The use of swab() is causing failures in 64-bit arch, as it +translates to __swab64() instead of the intended __swab32(). +It eventually causes wrong results in xcbcmac & cmac algo. + +Fixes: 78cf1c8bfcb8 ("crypto: inside-secure - Move ipad/opad into safexcel_context") +Signed-off-by: Peter Harliman Liem +Acked-by: Antoine Tenart +Signed-off-by: Herbert Xu +Acked-by: Takashi Iwai + +--- + drivers/crypto/inside-secure/safexcel_hash.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/crypto/inside-secure/safexcel_hash.c b/drivers/crypto/inside-secure/safexcel_hash.c +index bc60b5802256..2124416742f8 100644 +--- a/drivers/crypto/inside-secure/safexcel_hash.c ++++ b/drivers/crypto/inside-secure/safexcel_hash.c +@@ -383,7 +383,7 @@ static int safexcel_ahash_send_req(struct crypto_async_request *async, int ring, + u32 x; + + x = ipad[i] ^ ipad[i + 4]; +- cache[i] ^= swab(x); ++ cache[i] ^= swab32(x); + } + } + cache_len = AES_BLOCK_SIZE; +@@ -821,7 +821,7 @@ static int safexcel_ahash_final(struct ahash_request *areq) + u32 *result = (void *)areq->result; + + /* K3 */ +- result[i] = swab(ctx->base.ipad.word[i + 4]); ++ result[i] = swab32(ctx->base.ipad.word[i + 4]); + } + areq->result[0] ^= 0x80; // 10- padding + crypto_cipher_encrypt_one(ctx->kaes, areq->result, areq->result); +@@ -2106,7 +2106,7 @@ static int safexcel_xcbcmac_setkey(struct crypto_ahash *tfm, const u8 *key, + crypto_cipher_encrypt_one(ctx->kaes, (u8 *)key_tmp + AES_BLOCK_SIZE, + "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"); + for (i = 0; i < 3 * AES_BLOCK_SIZE / sizeof(u32); i++) +- ctx->base.ipad.word[i] = swab(key_tmp[i]); ++ ctx->base.ipad.word[i] = swab32(key_tmp[i]); + + crypto_cipher_clear_flags(ctx->kaes, CRYPTO_TFM_REQ_MASK); + crypto_cipher_set_flags(ctx->kaes, crypto_ahash_get_flags(tfm) & +@@ -2189,7 +2189,7 @@ static int safexcel_cmac_setkey(struct crypto_ahash *tfm, const u8 *key, + return ret; + + for (i = 0; i < len / sizeof(u32); i++) +- ctx->base.ipad.word[i + 8] = swab(aes.key_enc[i]); ++ ctx->base.ipad.word[i + 8] = swab32(aes.key_enc[i]); + + /* precompute the CMAC key material */ + crypto_cipher_clear_flags(ctx->kaes, CRYPTO_TFM_REQ_MASK); +-- +2.35.3 + diff --git a/patches.suse/crypto-inside-secure-Replace-generic-aes-with-libaes.patch b/patches.suse/crypto-inside-secure-Replace-generic-aes-with-libaes.patch new file mode 100644 index 0000000..123be7d --- /dev/null +++ b/patches.suse/crypto-inside-secure-Replace-generic-aes-with-libaes.patch @@ -0,0 +1,219 @@ +From 320406cb60b6408d87f6a5bc729285fc44107352 Mon Sep 17 00:00:00 2001 +From: Peter Harliman Liem +Date: Tue, 13 Sep 2022 16:03:48 +0800 +Subject: [PATCH] crypto: inside-secure - Replace generic aes with libaes +Git-commit: 320406cb60b6408d87f6a5bc729285fc44107352 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Commit 363a90c2d517 ("crypto: safexcel/aes - switch to +library version of key expansion routine") removed +CRYPTO_AES in the config. However, some portions of codes +still rely on generic AES cipher (e.g. refer to +safexcel_aead_gcm_cra_init(), safexcel_xcbcmac_cra_init()). +This causes transform allocation failure for those algos, +if CRYPTO_AES is not manually enabled. + +To resolve that, we replace all existing AES cipher +dependent codes with their AES library counterpart. + +Fixes: 363a90c2d517 ("crypto: safexcel/aes - switch to library version of key expansion routine") +Signed-off-by: Peter Harliman Liem +Signed-off-by: Herbert Xu +Acked-by: Takashi Iwai + +--- + .../crypto/inside-secure/safexcel_cipher.c | 16 +---- + drivers/crypto/inside-secure/safexcel_hash.c | 59 ++++++------------- + 2 files changed, 21 insertions(+), 54 deletions(-) + +diff --git a/drivers/crypto/inside-secure/safexcel_cipher.c b/drivers/crypto/inside-secure/safexcel_cipher.c +index 5a222c228c3b..32a37e3850c5 100644 +--- a/drivers/crypto/inside-secure/safexcel_cipher.c ++++ b/drivers/crypto/inside-secure/safexcel_cipher.c +@@ -63,7 +63,6 @@ struct safexcel_cipher_ctx { + u32 hash_alg; + u32 state_sz; + +- struct crypto_cipher *hkaes; + struct crypto_aead *fback; + }; + +@@ -2607,15 +2606,8 @@ static int safexcel_aead_gcm_setkey(struct crypto_aead *ctfm, const u8 *key, + ctx->key_len = len; + + /* Compute hash key by encrypting zeroes with cipher key */ +- crypto_cipher_clear_flags(ctx->hkaes, CRYPTO_TFM_REQ_MASK); +- crypto_cipher_set_flags(ctx->hkaes, crypto_aead_get_flags(ctfm) & +- CRYPTO_TFM_REQ_MASK); +- ret = crypto_cipher_setkey(ctx->hkaes, key, len); +- if (ret) +- return ret; +- + memset(hashkey, 0, AES_BLOCK_SIZE); +- crypto_cipher_encrypt_one(ctx->hkaes, (u8 *)hashkey, (u8 *)hashkey); ++ aes_encrypt(&aes, (u8 *)hashkey, (u8 *)hashkey); + + if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { + for (i = 0; i < AES_BLOCK_SIZE / sizeof(u32); i++) { +@@ -2644,15 +2636,11 @@ static int safexcel_aead_gcm_cra_init(struct crypto_tfm *tfm) + ctx->xcm = EIP197_XCM_MODE_GCM; + ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XCM; /* override default */ + +- ctx->hkaes = crypto_alloc_cipher("aes", 0, 0); +- return PTR_ERR_OR_ZERO(ctx->hkaes); ++ return 0; + } + + static void safexcel_aead_gcm_cra_exit(struct crypto_tfm *tfm) + { +- struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); +- +- crypto_free_cipher(ctx->hkaes); + safexcel_aead_cra_exit(tfm); + } + +diff --git a/drivers/crypto/inside-secure/safexcel_hash.c b/drivers/crypto/inside-secure/safexcel_hash.c +index 2124416742f8..103fc551d2af 100644 +--- a/drivers/crypto/inside-secure/safexcel_hash.c ++++ b/drivers/crypto/inside-secure/safexcel_hash.c +@@ -30,7 +30,7 @@ struct safexcel_ahash_ctx { + bool fb_init_done; + bool fb_do_setkey; + +- struct crypto_cipher *kaes; ++ struct crypto_aes_ctx *aes; + struct crypto_ahash *fback; + struct crypto_shash *shpre; + struct shash_desc *shdesc; +@@ -824,7 +824,7 @@ static int safexcel_ahash_final(struct ahash_request *areq) + result[i] = swab32(ctx->base.ipad.word[i + 4]); + } + areq->result[0] ^= 0x80; // 10- padding +- crypto_cipher_encrypt_one(ctx->kaes, areq->result, areq->result); ++ aes_encrypt(ctx->aes, areq->result, areq->result); + return 0; + } else if (unlikely(req->hmac && + (req->len == req->block_sz) && +@@ -2083,37 +2083,26 @@ static int safexcel_xcbcmac_setkey(struct crypto_ahash *tfm, const u8 *key, + unsigned int len) + { + struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm)); +- struct crypto_aes_ctx aes; + u32 key_tmp[3 * AES_BLOCK_SIZE / sizeof(u32)]; + int ret, i; + +- ret = aes_expandkey(&aes, key, len); ++ ret = aes_expandkey(ctx->aes, key, len); + if (ret) + return ret; + + /* precompute the XCBC key material */ +- crypto_cipher_clear_flags(ctx->kaes, CRYPTO_TFM_REQ_MASK); +- crypto_cipher_set_flags(ctx->kaes, crypto_ahash_get_flags(tfm) & +- CRYPTO_TFM_REQ_MASK); +- ret = crypto_cipher_setkey(ctx->kaes, key, len); +- if (ret) +- return ret; +- +- crypto_cipher_encrypt_one(ctx->kaes, (u8 *)key_tmp + 2 * AES_BLOCK_SIZE, +- "\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1"); +- crypto_cipher_encrypt_one(ctx->kaes, (u8 *)key_tmp, +- "\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2"); +- crypto_cipher_encrypt_one(ctx->kaes, (u8 *)key_tmp + AES_BLOCK_SIZE, +- "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"); ++ aes_encrypt(ctx->aes, (u8 *)key_tmp + 2 * AES_BLOCK_SIZE, ++ "\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1"); ++ aes_encrypt(ctx->aes, (u8 *)key_tmp, ++ "\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2"); ++ aes_encrypt(ctx->aes, (u8 *)key_tmp + AES_BLOCK_SIZE, ++ "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"); + for (i = 0; i < 3 * AES_BLOCK_SIZE / sizeof(u32); i++) + ctx->base.ipad.word[i] = swab32(key_tmp[i]); + +- crypto_cipher_clear_flags(ctx->kaes, CRYPTO_TFM_REQ_MASK); +- crypto_cipher_set_flags(ctx->kaes, crypto_ahash_get_flags(tfm) & +- CRYPTO_TFM_REQ_MASK); +- ret = crypto_cipher_setkey(ctx->kaes, +- (u8 *)key_tmp + 2 * AES_BLOCK_SIZE, +- AES_MIN_KEY_SIZE); ++ ret = aes_expandkey(ctx->aes, ++ (u8 *)key_tmp + 2 * AES_BLOCK_SIZE, ++ AES_MIN_KEY_SIZE); + if (ret) + return ret; + +@@ -2121,7 +2110,6 @@ static int safexcel_xcbcmac_setkey(struct crypto_ahash *tfm, const u8 *key, + ctx->key_sz = AES_MIN_KEY_SIZE + 2 * AES_BLOCK_SIZE; + ctx->cbcmac = false; + +- memzero_explicit(&aes, sizeof(aes)); + return 0; + } + +@@ -2130,15 +2118,15 @@ static int safexcel_xcbcmac_cra_init(struct crypto_tfm *tfm) + struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(tfm); + + safexcel_ahash_cra_init(tfm); +- ctx->kaes = crypto_alloc_cipher("aes", 0, 0); +- return PTR_ERR_OR_ZERO(ctx->kaes); ++ ctx->aes = kmalloc(sizeof(*ctx->aes), GFP_KERNEL); ++ return PTR_ERR_OR_ZERO(ctx->aes); + } + + static void safexcel_xcbcmac_cra_exit(struct crypto_tfm *tfm) + { + struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(tfm); + +- crypto_free_cipher(ctx->kaes); ++ kfree(ctx->aes); + safexcel_ahash_cra_exit(tfm); + } + +@@ -2178,31 +2166,23 @@ static int safexcel_cmac_setkey(struct crypto_ahash *tfm, const u8 *key, + unsigned int len) + { + struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm)); +- struct crypto_aes_ctx aes; + __be64 consts[4]; + u64 _const[2]; + u8 msb_mask, gfmask; + int ret, i; + +- ret = aes_expandkey(&aes, key, len); ++ /* precompute the CMAC key material */ ++ ret = aes_expandkey(ctx->aes, key, len); + if (ret) + return ret; + + for (i = 0; i < len / sizeof(u32); i++) +- ctx->base.ipad.word[i + 8] = swab32(aes.key_enc[i]); +- +- /* precompute the CMAC key material */ +- crypto_cipher_clear_flags(ctx->kaes, CRYPTO_TFM_REQ_MASK); +- crypto_cipher_set_flags(ctx->kaes, crypto_ahash_get_flags(tfm) & +- CRYPTO_TFM_REQ_MASK); +- ret = crypto_cipher_setkey(ctx->kaes, key, len); +- if (ret) +- return ret; ++ ctx->base.ipad.word[i + 8] = swab32(ctx->aes->key_enc[i]); + + /* code below borrowed from crypto/cmac.c */ + /* encrypt the zero block */ + memset(consts, 0, AES_BLOCK_SIZE); +- crypto_cipher_encrypt_one(ctx->kaes, (u8 *)consts, (u8 *)consts); ++ aes_encrypt(ctx->aes, (u8 *)consts, (u8 *)consts); + + gfmask = 0x87; + _const[0] = be64_to_cpu(consts[1]); +@@ -2234,7 +2214,6 @@ static int safexcel_cmac_setkey(struct crypto_ahash *tfm, const u8 *key, + } + ctx->cbcmac = false; + +- memzero_explicit(&aes, sizeof(aes)); + return 0; + } + +-- +2.35.3 + diff --git a/patches.suse/crypto-marvell-octeontx-prevent-integer-overflows.patch b/patches.suse/crypto-marvell-octeontx-prevent-integer-overflows.patch new file mode 100644 index 0000000..2763b1f --- /dev/null +++ b/patches.suse/crypto-marvell-octeontx-prevent-integer-overflows.patch @@ -0,0 +1,79 @@ +From caca37cf6c749ff0303f68418cfe7b757a4e0697 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Mon, 19 Sep 2022 09:43:19 +0300 +Subject: [PATCH] crypto: marvell/octeontx - prevent integer overflows +Git-commit: caca37cf6c749ff0303f68418cfe7b757a4e0697 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The "code_length" value comes from the firmware file. If your firmware +is untrusted realistically there is probably very little you can do to +protect yourself. Still we try to limit the damage as much as possible. +Also Smatch marks any data read from the filesystem as untrusted and +prints warnings if it not capped correctly. + +The "code_length * 2" can overflow. The round_up(ucode_size, 16) + +sizeof() expression can overflow too. Prevent these overflows. + +Fixes: d9110b0b01ff ("crypto: marvell - add support for OCTEON TX CPT engine") +Signed-off-by: Dan Carpenter +Signed-off-by: Herbert Xu +Acked-by: Takashi Iwai + +--- + .../crypto/marvell/octeontx/otx_cptpf_ucode.c | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +diff --git a/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c b/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c +index 23c6edc70914..df9c2b8747e6 100644 +--- a/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c ++++ b/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c +@@ -286,6 +286,7 @@ static int process_tar_file(struct device *dev, + struct tar_ucode_info_t *tar_info; + struct otx_cpt_ucode_hdr *ucode_hdr; + int ucode_type, ucode_size; ++ unsigned int code_length; + + /* + * If size is less than microcode header size then don't report +@@ -303,7 +304,13 @@ static int process_tar_file(struct device *dev, + if (get_ucode_type(ucode_hdr, &ucode_type)) + return 0; + +- ucode_size = ntohl(ucode_hdr->code_length) * 2; ++ code_length = ntohl(ucode_hdr->code_length); ++ if (code_length >= INT_MAX / 2) { ++ dev_err(dev, "Invalid code_length %u\n", code_length); ++ return -EINVAL; ++ } ++ ++ ucode_size = code_length * 2; + if (!ucode_size || (size < round_up(ucode_size, 16) + + sizeof(struct otx_cpt_ucode_hdr) + OTX_CPT_UCODE_SIGN_LEN)) { + dev_err(dev, "Ucode %s invalid size\n", filename); +@@ -886,6 +893,7 @@ static int ucode_load(struct device *dev, struct otx_cpt_ucode *ucode, + { + struct otx_cpt_ucode_hdr *ucode_hdr; + const struct firmware *fw; ++ unsigned int code_length; + int ret; + + set_ucode_filename(ucode, ucode_filename); +@@ -896,7 +904,13 @@ static int ucode_load(struct device *dev, struct otx_cpt_ucode *ucode, + ucode_hdr = (struct otx_cpt_ucode_hdr *) fw->data; + memcpy(ucode->ver_str, ucode_hdr->ver_str, OTX_CPT_UCODE_VER_STR_SZ); + ucode->ver_num = ucode_hdr->ver_num; +- ucode->size = ntohl(ucode_hdr->code_length) * 2; ++ code_length = ntohl(ucode_hdr->code_length); ++ if (code_length >= INT_MAX / 2) { ++ dev_err(dev, "Ucode invalid code_length %u\n", code_length); ++ ret = -EINVAL; ++ goto release_fw; ++ } ++ ucode->size = code_length * 2; + if (!ucode->size || (fw->size < round_up(ucode->size, 16) + + sizeof(struct otx_cpt_ucode_hdr) + OTX_CPT_UCODE_SIGN_LEN)) { + dev_err(dev, "Ucode %s invalid size\n", ucode_filename); +-- +2.35.3 + diff --git a/patches.suse/crypto-qat-fix-default-value-of-WDT-timer.patch b/patches.suse/crypto-qat-fix-default-value-of-WDT-timer.patch new file mode 100644 index 0000000..eb09f55 --- /dev/null +++ b/patches.suse/crypto-qat-fix-default-value-of-WDT-timer.patch @@ -0,0 +1,41 @@ +From cc40b04c08400d86d2d6ea0159e0617e717f729c Mon Sep 17 00:00:00 2001 +From: Lucas Segarra Fernandez +Date: Thu, 25 Aug 2022 12:32:16 +0200 +Subject: [PATCH] crypto: qat - fix default value of WDT timer +Git-commit: cc40b04c08400d86d2d6ea0159e0617e717f729c +Patch-mainline: v6.1-rc1 +References: git-fixes + +The QAT HW supports an hardware mechanism to detect an accelerator hang. +The reporting of a hang occurs after a watchdog timer (WDT) expires. + +The value of the WDT set previously was too small and was causing false +positives. +Change the default value of the WDT to 0x7000000ULL to avoid this. + +Fixes: 1c4d9d5bbb5a ("crypto: qat - enable detection of accelerators hang") +Reviewed-by: Giovanni Cabiddu +Signed-off-by: Lucas Segarra Fernandez +Signed-off-by: Herbert Xu +Acked-by: Takashi Iwai + +--- + drivers/crypto/qat/qat_common/adf_gen4_hw_data.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h b/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h +index 43b8f864806b..4fb4b3df5a18 100644 +--- a/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h ++++ b/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h +@@ -107,7 +107,7 @@ do { \ + * Timeout is in cycles. Clock speed may vary across products but this + * value should be a few milli-seconds. + */ +-#define ADF_SSM_WDT_DEFAULT_VALUE 0x200000 ++#define ADF_SSM_WDT_DEFAULT_VALUE 0x7000000ULL + #define ADF_SSM_WDT_PKE_DEFAULT_VALUE 0x8000000 + #define ADF_SSMWDTL_OFFSET 0x54 + #define ADF_SSMWDTH_OFFSET 0x5C +-- +2.35.3 + diff --git a/patches.suse/crypto-sahara-don-t-sleep-when-in-softirq.patch b/patches.suse/crypto-sahara-don-t-sleep-when-in-softirq.patch new file mode 100644 index 0000000..dccb1a0 --- /dev/null +++ b/patches.suse/crypto-sahara-don-t-sleep-when-in-softirq.patch @@ -0,0 +1,95 @@ +From 108586eba094b318e6a831f977f4ddcc403a15da Mon Sep 17 00:00:00 2001 +From: Zhengchao Shao +Date: Mon, 25 Jul 2022 12:09:28 +0800 +Subject: [PATCH] crypto: sahara - don't sleep when in softirq +Git-commit: 108586eba094b318e6a831f977f4ddcc403a15da +Patch-mainline: v6.1-rc1 +References: git-fixes + +Function of sahara_aes_crypt maybe could be called by function +of crypto_skcipher_encrypt during the rx softirq, so it is not +allowed to use mutex lock. + +Fixes: c0c3c89ae347 ("crypto: sahara - replace tasklets with...") +Signed-off-by: Zhengchao Shao +Signed-off-by: Herbert Xu +Acked-by: Takashi Iwai + +--- + drivers/crypto/sahara.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +diff --git a/drivers/crypto/sahara.c b/drivers/crypto/sahara.c +index 457084b344c1..b07ae4ba165e 100644 +--- a/drivers/crypto/sahara.c ++++ b/drivers/crypto/sahara.c +@@ -26,10 +26,10 @@ + #include + #include + #include +-#include + #include + #include + #include ++#include + + #define SHA_BUFFER_LEN PAGE_SIZE + #define SAHARA_MAX_SHA_BLOCK_SIZE SHA256_BLOCK_SIZE +@@ -196,7 +196,7 @@ struct sahara_dev { + void __iomem *regs_base; + struct clk *clk_ipg; + struct clk *clk_ahb; +- struct mutex queue_mutex; ++ spinlock_t queue_spinlock; + struct task_struct *kthread; + struct completion dma_completion; + +@@ -642,9 +642,9 @@ static int sahara_aes_crypt(struct skcipher_request *req, unsigned long mode) + + rctx->mode = mode; + +- mutex_lock(&dev->queue_mutex); ++ spin_lock_bh(&dev->queue_spinlock); + err = crypto_enqueue_request(&dev->queue, &req->base); +- mutex_unlock(&dev->queue_mutex); ++ spin_unlock_bh(&dev->queue_spinlock); + + wake_up_process(dev->kthread); + +@@ -1043,10 +1043,10 @@ static int sahara_queue_manage(void *data) + do { + __set_current_state(TASK_INTERRUPTIBLE); + +- mutex_lock(&dev->queue_mutex); ++ spin_lock_bh(&dev->queue_spinlock); + backlog = crypto_get_backlog(&dev->queue); + async_req = crypto_dequeue_request(&dev->queue); +- mutex_unlock(&dev->queue_mutex); ++ spin_unlock_bh(&dev->queue_spinlock); + + if (backlog) + backlog->complete(backlog, -EINPROGRESS); +@@ -1092,9 +1092,9 @@ static int sahara_sha_enqueue(struct ahash_request *req, int last) + rctx->first = 1; + } + +- mutex_lock(&dev->queue_mutex); ++ spin_lock_bh(&dev->queue_spinlock); + ret = crypto_enqueue_request(&dev->queue, &req->base); +- mutex_unlock(&dev->queue_mutex); ++ spin_unlock_bh(&dev->queue_spinlock); + + wake_up_process(dev->kthread); + +@@ -1449,7 +1449,7 @@ static int sahara_probe(struct platform_device *pdev) + + crypto_init_queue(&dev->queue, SAHARA_QUEUE_LENGTH); + +- mutex_init(&dev->queue_mutex); ++ spin_lock_init(&dev->queue_spinlock); + + dev_ptr = dev; + +-- +2.35.3 + diff --git a/patches.suse/device-property-Add-irq_get-to-fwnode-operation.patch b/patches.suse/device-property-Add-irq_get-to-fwnode-operation.patch new file mode 100644 index 0000000..1b6b8c5 --- /dev/null +++ b/patches.suse/device-property-Add-irq_get-to-fwnode-operation.patch @@ -0,0 +1,108 @@ +From: Sakari Ailus +Date: Thu, 31 Mar 2022 15:54:50 +0300 +Subject: device property: Add irq_get to fwnode operation +Patch-mainline: v5.19-rc1 +Git-commit: 99c63707bafd15bcf97fbd6bef1c92d5bfa01d28 +References: jsc#PED-1408 + +Add irq_get() fwnode operation to implement fwnode_irq_get() through +fwnode operations, moving the code in fwnode_irq_get() to OF and ACPI +frameworks. + +Signed-off-by: Sakari Ailus +Acked-by: Rob Herring +Reviewed-by: Andy Shevchenko +Reviewed-by: Heikki Krogerus +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/property.c | 14 ++++++++++++++ + drivers/base/property.c | 12 +----------- + drivers/of/property.c | 7 +++++++ + include/linux/fwnode.h | 1 + + 4 files changed, 23 insertions(+), 11 deletions(-) + +--- a/drivers/acpi/property.c ++++ b/drivers/acpi/property.c +@@ -1394,6 +1394,19 @@ static int acpi_fwnode_graph_parse_endpo + return 0; + } + ++static int acpi_fwnode_irq_get(const struct fwnode_handle *fwnode, ++ unsigned int index) ++{ ++ struct resource res; ++ int ret; ++ ++ ret = acpi_irq_get(ACPI_HANDLE_FWNODE(fwnode), index, &res); ++ if (ret) ++ return ret; ++ ++ return res.start; ++} ++ + #define DECLARE_ACPI_FWNODE_OPS(ops) \ + const struct fwnode_operations ops = { \ + .device_is_available = acpi_fwnode_device_is_available, \ +@@ -1418,6 +1431,7 @@ static int acpi_fwnode_graph_parse_endpo + acpi_graph_get_remote_endpoint, \ + .graph_get_port_parent = acpi_fwnode_get_parent, \ + .graph_parse_endpoint = acpi_fwnode_graph_parse_endpoint, \ ++ .irq_get = acpi_fwnode_irq_get, \ + }; \ + EXPORT_SYMBOL_GPL(ops) + +--- a/drivers/base/property.c ++++ b/drivers/base/property.c +@@ -965,17 +965,7 @@ EXPORT_SYMBOL(fwnode_irq_get_byname); + */ + int fwnode_irq_get(const struct fwnode_handle *fwnode, unsigned int index) + { +- struct resource res; +- int ret; +- +- if (is_of_node(fwnode)) +- return of_irq_get(to_of_node(fwnode), index); +- +- ret = acpi_irq_get(ACPI_HANDLE_FWNODE(fwnode), index, &res); +- if (ret) +- return ret; +- +- return res.start; ++ return fwnode_call_int_op(fwnode, irq_get, index); + } + EXPORT_SYMBOL(fwnode_irq_get); + +--- a/drivers/of/property.c ++++ b/drivers/of/property.c +@@ -1444,6 +1444,12 @@ static int of_link_property(struct devic + return 0; + } + ++static int of_fwnode_irq_get(const struct fwnode_handle *fwnode, ++ unsigned int index) ++{ ++ return of_irq_get(to_of_node(fwnode), index); ++} ++ + static int of_fwnode_add_links(struct fwnode_handle *fwnode) + { + struct property *p; +@@ -1481,6 +1487,7 @@ const struct fwnode_operations of_fwnode + .graph_get_remote_endpoint = of_fwnode_graph_get_remote_endpoint, + .graph_get_port_parent = of_fwnode_graph_get_port_parent, + .graph_parse_endpoint = of_fwnode_graph_parse_endpoint, ++ .irq_get = of_fwnode_irq_get, + .add_links = of_fwnode_add_links, + }; + EXPORT_SYMBOL_GPL(of_fwnode_ops); +--- a/include/linux/fwnode.h ++++ b/include/linux/fwnode.h +@@ -148,6 +148,7 @@ struct fwnode_operations { + (*graph_get_port_parent)(struct fwnode_handle *fwnode); + int (*graph_parse_endpoint)(const struct fwnode_handle *fwnode, + struct fwnode_endpoint *endpoint); ++ int (*irq_get)(const struct fwnode_handle *fwnode, unsigned int index); + int (*add_links)(struct fwnode_handle *fwnode); + }; + diff --git a/patches.suse/device-property-Convert-device_-dma_supported-get_dm.patch b/patches.suse/device-property-Convert-device_-dma_supported-get_dm.patch new file mode 100644 index 0000000..fe9ebb2 --- /dev/null +++ b/patches.suse/device-property-Convert-device_-dma_supported-get_dm.patch @@ -0,0 +1,146 @@ +From: Sakari Ailus +Date: Thu, 31 Mar 2022 15:54:47 +0300 +Subject: device property: Convert device_{dma_supported,get_dma_attr} to + fwnode +Patch-mainline: v5.19-rc1 +Git-commit: 8c756a0a2de17f1535ef885ac7e556e016735eb2 +References: jsc#PED-1408 + +Make the device_dma_supported and device_get_dma_attr functions to use the +fwnode ops, and move the implementation to ACPI and OF frameworks. + +Signed-off-by: Sakari Ailus +Acked-by: Rob Herring +Reviewed-by: Andy Shevchenko +Reviewed-by: Heikki Krogerus +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + drivers/acpi/property.c | 14 ++++++++++++++ + drivers/base/property.c | 25 ++++--------------------- + drivers/of/property.c | 17 +++++++++++++++++ + include/linux/fwnode.h | 3 +++ + 4 files changed, 38 insertions(+), 21 deletions(-) + +--- a/drivers/acpi/property.c ++++ b/drivers/acpi/property.c +@@ -1256,6 +1256,17 @@ static bool acpi_fwnode_device_is_availa + return acpi_device_is_present(to_acpi_device_node(fwnode)); + } + ++static bool acpi_fwnode_device_dma_supported(const struct fwnode_handle *fwnode) ++{ ++ return acpi_dma_supported(to_acpi_device_node(fwnode)); ++} ++ ++static enum dev_dma_attr ++acpi_fwnode_device_get_dma_attr(const struct fwnode_handle *fwnode) ++{ ++ return acpi_get_dma_attr(to_acpi_device_node(fwnode)); ++} ++ + static bool acpi_fwnode_property_present(const struct fwnode_handle *fwnode, + const char *propname) + { +@@ -1387,6 +1398,9 @@ acpi_fwnode_device_get_match_data(const + const struct fwnode_operations ops = { \ + .device_is_available = acpi_fwnode_device_is_available, \ + .device_get_match_data = acpi_fwnode_device_get_match_data, \ ++ .device_dma_supported = \ ++ acpi_fwnode_device_dma_supported, \ ++ .device_get_dma_attr = acpi_fwnode_device_get_dma_attr, \ + .property_present = acpi_fwnode_property_present, \ + .property_read_int_array = \ + acpi_fwnode_property_read_int_array, \ +--- a/drivers/base/property.c ++++ b/drivers/base/property.c +@@ -871,33 +871,16 @@ EXPORT_SYMBOL_GPL(device_get_child_node_ + + bool device_dma_supported(struct device *dev) + { +- const struct fwnode_handle *fwnode = dev_fwnode(dev); +- +- /* For DT, this is always supported. +- * For ACPI, this depends on CCA, which +- * is determined by the acpi_dma_supported(). +- */ +- if (is_of_node(fwnode)) +- return true; +- +- return acpi_dma_supported(to_acpi_device_node(fwnode)); ++ return fwnode_call_bool_op(dev_fwnode(dev), device_dma_supported); + } + EXPORT_SYMBOL_GPL(device_dma_supported); + + enum dev_dma_attr device_get_dma_attr(struct device *dev) + { +- const struct fwnode_handle *fwnode = dev_fwnode(dev); +- enum dev_dma_attr attr = DEV_DMA_NOT_SUPPORTED; +- +- if (is_of_node(fwnode)) { +- if (of_dma_is_coherent(to_of_node(fwnode))) +- attr = DEV_DMA_COHERENT; +- else +- attr = DEV_DMA_NON_COHERENT; +- } else +- attr = acpi_get_dma_attr(to_acpi_device_node(fwnode)); ++ if (!fwnode_has_op(dev_fwnode(dev), device_get_dma_attr)) ++ return DEV_DMA_NOT_SUPPORTED; + +- return attr; ++ return fwnode_call_int_op(dev_fwnode(dev), device_get_dma_attr); + } + EXPORT_SYMBOL_GPL(device_get_dma_attr); + +--- a/drivers/of/property.c ++++ b/drivers/of/property.c +@@ -22,6 +22,7 @@ + #define pr_fmt(fmt) "OF: " fmt + + #include ++#include + #include + #include + #include +@@ -872,6 +873,20 @@ static bool of_fwnode_device_is_availabl + return of_device_is_available(to_of_node(fwnode)); + } + ++static bool of_fwnode_device_dma_supported(const struct fwnode_handle *fwnode) ++{ ++ return true; ++} ++ ++static enum dev_dma_attr ++of_fwnode_device_get_dma_attr(const struct fwnode_handle *fwnode) ++{ ++ if (of_dma_is_coherent(to_of_node(fwnode))) ++ return DEV_DMA_COHERENT; ++ else ++ return DEV_DMA_NON_COHERENT; ++} ++ + static bool of_fwnode_property_present(const struct fwnode_handle *fwnode, + const char *propname) + { +@@ -1451,6 +1466,8 @@ const struct fwnode_operations of_fwnode + .put = of_fwnode_put, + .device_is_available = of_fwnode_device_is_available, + .device_get_match_data = of_fwnode_device_get_match_data, ++ .device_dma_supported = of_fwnode_device_dma_supported, ++ .device_get_dma_attr = of_fwnode_device_get_dma_attr, + .property_present = of_fwnode_property_present, + .property_read_int_array = of_fwnode_property_read_int_array, + .property_read_string_array = of_fwnode_property_read_string_array, +--- a/include/linux/fwnode.h ++++ b/include/linux/fwnode.h +@@ -113,6 +113,9 @@ struct fwnode_operations { + bool (*device_is_available)(const struct fwnode_handle *fwnode); + const void *(*device_get_match_data)(const struct fwnode_handle *fwnode, + const struct device *dev); ++ bool (*device_dma_supported)(const struct fwnode_handle *fwnode); ++ enum dev_dma_attr ++ (*device_get_dma_attr)(const struct fwnode_handle *fwnode); + bool (*property_present)(const struct fwnode_handle *fwnode, + const char *propname); + int (*property_read_int_array)(const struct fwnode_handle *fwnode, diff --git a/patches.suse/dmaengine-hisilicon-Add-multi-thread-support-for-a-D.patch b/patches.suse/dmaengine-hisilicon-Add-multi-thread-support-for-a-D.patch new file mode 100644 index 0000000..abc3fdf --- /dev/null +++ b/patches.suse/dmaengine-hisilicon-Add-multi-thread-support-for-a-D.patch @@ -0,0 +1,102 @@ +From 2cbb95883c990d0002a77e13d3278913ab26ad79 Mon Sep 17 00:00:00 2001 +From: Jie Hai +Date: Tue, 30 Aug 2022 14:22:47 +0800 +Subject: [PATCH] dmaengine: hisilicon: Add multi-thread support for a DMA channel +Git-commit: 2cbb95883c990d0002a77e13d3278913ab26ad79 +Patch-mainline: v6.1-rc1 +References: git-fixes + +When we get a DMA channel and try to use it in multiple threads it +will cause oops and hanging the system. + +% echo 100 > /sys/module/dmatest/parameters/threads_per_chan +% echo 100 > /sys/module/dmatest/parameters/iterations +% echo 1 > /sys/module/dmatest/parameters/run +[383493.327077] Unable to handle kernel paging request at virtual + address dead000000000108 +[383493.335103] Mem abort info: +[383493.335103] ESR = 0x96000044 +[383493.335105] EC = 0x25: DABT (current EL), IL = 32 bits +[383493.335107] SET = 0, FnV = 0 +[383493.335108] EA = 0, S1PTW = 0 +[383493.335109] FSC = 0x04: level 0 translation fault +[383493.335110] Data abort info: +[383493.335111] ISV = 0, ISS = 0x00000044 +[383493.364739] CM = 0, WnR = 1 +[383493.367793] [dead000000000108] address between user and kernel + address ranges +[383493.375021] Internal error: Oops: 96000044 [#1] PREEMPT SMP +[383493.437574] CPU: 63 PID: 27895 Comm: dma0chan0-copy2 Kdump: + loaded Tainted: GO 5.17.0-rc4+ #2 +[383493.457851] pstate: 204000c9 (nzCv daIF +PAN -UAO -TCO -DIT + -SSBS BTYPE=--) +[383493.465331] pc : vchan_tx_submit+0x64/0xa0 +[383493.469957] lr : vchan_tx_submit+0x34/0xa0 + +This occurs because the transmission timed out, and that's due +to data race. Each thread rewrite channels's descriptor as soon as +device_issue_pending is called. It leads to the situation that +the driver thinks that it uses the right descriptor in interrupt +handler while channels's descriptor has been changed by other +thread. The descriptor which in fact reported interrupt will not +be handled any more, as well as its tx->callback. +That's why timeout reports. + +With current fixes channels' descriptor changes it's value only +when it has been used. A new descriptor is acquired from +vc->desc_issued queue that is already filled with descriptors +that are ready to be sent. Threads have no direct access to DMA +channel descriptor. In case of channel's descriptor is busy, try +to submit to HW again when a descriptor is completed. In this case, +vc->desc_issued may be empty when hisi_dma_start_transfer is called, +so delete error reporting on this. Now it is just possible to queue +a descriptor for further processing. + +Fixes: e9f08b65250d ("dmaengine: hisilicon: Add Kunpeng DMA engine support") +Signed-off-by: Jie Hai +Acked-by: Zhou Wang +Link: https://lore.kernel.org/r/20220830062251.52993-4-haijie1@huawei.com +Signed-off-by: Vinod Koul +Acked-by: Takashi Iwai + +--- + drivers/dma/hisi_dma.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/drivers/dma/hisi_dma.c b/drivers/dma/hisi_dma.c +index 837f7e4adfa6..0233b42143c7 100644 +--- a/drivers/dma/hisi_dma.c ++++ b/drivers/dma/hisi_dma.c +@@ -271,7 +271,6 @@ static void hisi_dma_start_transfer(struct hisi_dma_chan *chan) + + vd = vchan_next_desc(&chan->vc); + if (!vd) { +- dev_err(&hdma_dev->pdev->dev, "no issued task!\n"); + chan->desc = NULL; + return; + } +@@ -303,7 +302,7 @@ static void hisi_dma_issue_pending(struct dma_chan *c) + + spin_lock_irqsave(&chan->vc.lock, flags); + +- if (vchan_issue_pending(&chan->vc)) ++ if (vchan_issue_pending(&chan->vc) && !chan->desc) + hisi_dma_start_transfer(chan); + + spin_unlock_irqrestore(&chan->vc.lock, flags); +@@ -441,11 +440,10 @@ static irqreturn_t hisi_dma_irq(int irq, void *data) + chan->qp_num, chan->cq_head); + if (FIELD_GET(STATUS_MASK, cqe->w0) == STATUS_SUCC) { + vchan_cookie_complete(&desc->vd); ++ hisi_dma_start_transfer(chan); + } else { + dev_err(&hdma_dev->pdev->dev, "task error!\n"); + } +- +- chan->desc = NULL; + } + + spin_unlock(&chan->vc.lock); +-- +2.35.3 + diff --git a/patches.suse/dmaengine-hisilicon-Disable-channels-when-unregister.patch b/patches.suse/dmaengine-hisilicon-Disable-channels-when-unregister.patch new file mode 100644 index 0000000..75ce056 --- /dev/null +++ b/patches.suse/dmaengine-hisilicon-Disable-channels-when-unregister.patch @@ -0,0 +1,72 @@ +From e3bdaa04ada31f46d0586df83a2789b8913053c5 Mon Sep 17 00:00:00 2001 +From: Jie Hai +Date: Tue, 30 Aug 2022 14:22:45 +0800 +Subject: [PATCH] dmaengine: hisilicon: Disable channels when unregister hisi_dma +Git-commit: e3bdaa04ada31f46d0586df83a2789b8913053c5 +Patch-mainline: v6.1-rc1 +References: git-fixes + +When hisi_dma is unloaded or unbinded, all of channels should be +disabled. This patch disables DMA channels when driver is unloaded +or unbinded. + +Fixes: e9f08b65250d ("dmaengine: hisilicon: Add Kunpeng DMA engine support") +Signed-off-by: Jie Hai +Acked-by: Zhou Wang +Link: https://lore.kernel.org/r/20220830062251.52993-2-haijie1@huawei.com +Signed-off-by: Vinod Koul +Acked-by: Takashi Iwai + +--- + drivers/dma/hisi_dma.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +diff --git a/drivers/dma/hisi_dma.c b/drivers/dma/hisi_dma.c +index 43817ced3a3e..98bc488893cc 100644 +--- a/drivers/dma/hisi_dma.c ++++ b/drivers/dma/hisi_dma.c +@@ -180,7 +180,8 @@ static void hisi_dma_reset_qp_point(struct hisi_dma_dev *hdma_dev, u32 index) + hisi_dma_chan_write(hdma_dev->base, HISI_DMA_CQ_HEAD_PTR, index, 0); + } + +-static void hisi_dma_reset_hw_chan(struct hisi_dma_chan *chan) ++static void hisi_dma_reset_or_disable_hw_chan(struct hisi_dma_chan *chan, ++ bool disable) + { + struct hisi_dma_dev *hdma_dev = chan->hdma_dev; + u32 index = chan->qp_num, tmp; +@@ -201,8 +202,11 @@ static void hisi_dma_reset_hw_chan(struct hisi_dma_chan *chan) + hisi_dma_do_reset(hdma_dev, index); + hisi_dma_reset_qp_point(hdma_dev, index); + hisi_dma_pause_dma(hdma_dev, index, false); +- hisi_dma_enable_dma(hdma_dev, index, true); +- hisi_dma_unmask_irq(hdma_dev, index); ++ ++ if (!disable) { ++ hisi_dma_enable_dma(hdma_dev, index, true); ++ hisi_dma_unmask_irq(hdma_dev, index); ++ } + + ret = readl_relaxed_poll_timeout(hdma_dev->base + + HISI_DMA_Q_FSM_STS + index * HISI_DMA_OFFSET, tmp, +@@ -218,7 +222,7 @@ static void hisi_dma_free_chan_resources(struct dma_chan *c) + struct hisi_dma_chan *chan = to_hisi_dma_chan(c); + struct hisi_dma_dev *hdma_dev = chan->hdma_dev; + +- hisi_dma_reset_hw_chan(chan); ++ hisi_dma_reset_or_disable_hw_chan(chan, false); + vchan_free_chan_resources(&chan->vc); + + memset(chan->sq, 0, sizeof(struct hisi_dma_sqe) * hdma_dev->chan_depth); +@@ -394,7 +398,7 @@ static void hisi_dma_enable_qp(struct hisi_dma_dev *hdma_dev, u32 qp_index) + + static void hisi_dma_disable_qp(struct hisi_dma_dev *hdma_dev, u32 qp_index) + { +- hisi_dma_reset_hw_chan(&hdma_dev->chan[qp_index]); ++ hisi_dma_reset_or_disable_hw_chan(&hdma_dev->chan[qp_index], true); + } + + static void hisi_dma_enable_qps(struct hisi_dma_dev *hdma_dev) +-- +2.35.3 + diff --git a/patches.suse/dmaengine-hisilicon-Fix-CQ-head-update.patch b/patches.suse/dmaengine-hisilicon-Fix-CQ-head-update.patch new file mode 100644 index 0000000..2c68b06 --- /dev/null +++ b/patches.suse/dmaengine-hisilicon-Fix-CQ-head-update.patch @@ -0,0 +1,55 @@ +From 94477a79cf80e8ab55b68f14bc579a12ddea1e0b Mon Sep 17 00:00:00 2001 +From: Jie Hai +Date: Tue, 30 Aug 2022 14:22:46 +0800 +Subject: [PATCH] dmaengine: hisilicon: Fix CQ head update +Git-commit: 94477a79cf80e8ab55b68f14bc579a12ddea1e0b +Patch-mainline: v6.1-rc1 +References: git-fixes + +After completion of data transfer of one or multiple descriptors, +the completion status and the current head pointer to submission +queue are written into the CQ and interrupt can be generated to +inform the software. In interrupt process CQ is read and cq_head +is updated. + +hisi_dma_irq updates cq_head only when the completion status is +success. When an abnormal interrupt reports, cq_head will not update +which will cause subsequent interrupt processes read the error CQ +and never report the correct status. + +This patch updates cq_head whenever CQ is accessed. + +Fixes: e9f08b65250d ("dmaengine: hisilicon: Add Kunpeng DMA engine support") +Signed-off-by: Jie Hai +Acked-by: Zhou Wang +Link: https://lore.kernel.org/r/20220830062251.52993-3-haijie1@huawei.com +Signed-off-by: Vinod Koul +Acked-by: Takashi Iwai + +--- + drivers/dma/hisi_dma.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/drivers/dma/hisi_dma.c b/drivers/dma/hisi_dma.c +index 98bc488893cc..837f7e4adfa6 100644 +--- a/drivers/dma/hisi_dma.c ++++ b/drivers/dma/hisi_dma.c +@@ -436,12 +436,10 @@ static irqreturn_t hisi_dma_irq(int irq, void *data) + desc = chan->desc; + cqe = chan->cq + chan->cq_head; + if (desc) { ++ chan->cq_head = (chan->cq_head + 1) % hdma_dev->chan_depth; ++ hisi_dma_chan_write(hdma_dev->base, HISI_DMA_CQ_HEAD_PTR, ++ chan->qp_num, chan->cq_head); + if (FIELD_GET(STATUS_MASK, cqe->w0) == STATUS_SUCC) { +- chan->cq_head = (chan->cq_head + 1) % +- hdma_dev->chan_depth; +- hisi_dma_chan_write(hdma_dev->base, +- HISI_DMA_CQ_HEAD_PTR, chan->qp_num, +- chan->cq_head); + vchan_cookie_complete(&desc->vd); + } else { + dev_err(&hdma_dev->pdev->dev, "task error!\n"); +-- +2.35.3 + diff --git a/patches.suse/dmaengine-ioat-stop-mod_timer-from-resurrecting-dele.patch b/patches.suse/dmaengine-ioat-stop-mod_timer-from-resurrecting-dele.patch new file mode 100644 index 0000000..235caf2 --- /dev/null +++ b/patches.suse/dmaengine-ioat-stop-mod_timer-from-resurrecting-dele.patch @@ -0,0 +1,60 @@ +From 898ec89dbb55b8294695ad71694a0684e62b2a73 Mon Sep 17 00:00:00 2001 +From: Dave Jiang +Date: Mon, 19 Sep 2022 09:58:42 -0700 +Subject: [PATCH] dmaengine: ioat: stop mod_timer from resurrecting deleted timer in __cleanup() +Git-commit: 898ec89dbb55b8294695ad71694a0684e62b2a73 +Patch-mainline: v6.1-rc1 +References: git-fixes + +User reports observing timer event report channel halted but no error +observed in CHANERR register. The driver finished self-test and released +channel resources. Debug shows that __cleanup() can call +mod_timer() after the timer has been deleted and thus resurrect the +timer. While harmless, it causes suprious error message to be emitted. +Use mod_timer_pending() call to prevent deleted timer from being +resurrected. + +Fixes: 3372de5813e4 ("dmaengine: ioatdma: removal of dma_v3.c and relevant ioat3 references") +Signed-off-by: Dave Jiang +Link: https://lore.kernel.org/r/166360672197.3851724.17040290563764838369.stgit@djiang5-desk3.ch.intel.com +Signed-off-by: Vinod Koul +Acked-by: Takashi Iwai + +--- + drivers/dma/ioat/dma.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c +index 37ff4ec7db76..e2070df6cad2 100644 +--- a/drivers/dma/ioat/dma.c ++++ b/drivers/dma/ioat/dma.c +@@ -656,7 +656,7 @@ static void __cleanup(struct ioatdma_chan *ioat_chan, dma_addr_t phys_complete) + if (active - i == 0) { + dev_dbg(to_dev(ioat_chan), "%s: cancel completion timeout\n", + __func__); +- mod_timer(&ioat_chan->timer, jiffies + IDLE_TIMEOUT); ++ mod_timer_pending(&ioat_chan->timer, jiffies + IDLE_TIMEOUT); + } + + /* microsecond delay by sysfs variable per pending descriptor */ +@@ -682,7 +682,7 @@ static void ioat_cleanup(struct ioatdma_chan *ioat_chan) + + if (chanerr & + (IOAT_CHANERR_HANDLE_MASK | IOAT_CHANERR_RECOVER_MASK)) { +- mod_timer(&ioat_chan->timer, jiffies + IDLE_TIMEOUT); ++ mod_timer_pending(&ioat_chan->timer, jiffies + IDLE_TIMEOUT); + ioat_eh(ioat_chan); + } + } +@@ -879,7 +879,7 @@ static void check_active(struct ioatdma_chan *ioat_chan) + } + + if (test_and_clear_bit(IOAT_CHAN_ACTIVE, &ioat_chan->state)) +- mod_timer(&ioat_chan->timer, jiffies + IDLE_TIMEOUT); ++ mod_timer_pending(&ioat_chan->timer, jiffies + IDLE_TIMEOUT); + } + + static void ioat_reboot_chan(struct ioatdma_chan *ioat_chan) +-- +2.35.3 + diff --git a/patches.suse/dmaengine-mxs-use-platform_driver_register.patch b/patches.suse/dmaengine-mxs-use-platform_driver_register.patch new file mode 100644 index 0000000..db711ff --- /dev/null +++ b/patches.suse/dmaengine-mxs-use-platform_driver_register.patch @@ -0,0 +1,75 @@ +From 26696d4657167112a1079f86cba1739765c1360e Mon Sep 17 00:00:00 2001 +From: Dario Binacchi +Date: Wed, 21 Sep 2022 19:05:56 +0200 +Subject: [PATCH] dmaengine: mxs: use platform_driver_register +Git-commit: 26696d4657167112a1079f86cba1739765c1360e +Patch-mainline: v6.1-rc1 +References: git-fixes + +Driver registration fails on SOC imx8mn as its supplier, the clock +control module, is probed later than subsys initcall level. This driver +uses platform_driver_probe which is not compatible with deferred probing +and won't be probed again later if probe function fails due to clock not +being available at that time. + +This patch replaces the use of platform_driver_probe with +platform_driver_register which will allow probing the driver later again +when the clock control module will be available. + +The __init annotation has been dropped because it is not compatible with +deferred probing. The code is not executed once and its memory cannot be +freed. + +Fixes: a580b8c5429a ("dmaengine: mxs-dma: add dma support for i.MX23/28") +Co-developed-by: Michael Trimarchi +Signed-off-by: Michael Trimarchi +Signed-off-by: Dario Binacchi +Acked-by: Sascha Hauer +Cc: stable@vger.kernel.org + +Link: https://lore.kernel.org/r/20220921170556.1055962-1-dario.binacchi@amarulasolutions.com +Signed-off-by: Vinod Koul +Acked-by: Takashi Iwai + +--- + drivers/dma/mxs-dma.c | 11 ++++------- + 1 file changed, 4 insertions(+), 7 deletions(-) + +diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c +index 994fc4d2aca4..dc147cc2436e 100644 +--- a/drivers/dma/mxs-dma.c ++++ b/drivers/dma/mxs-dma.c +@@ -670,7 +670,7 @@ static enum dma_status mxs_dma_tx_status(struct dma_chan *chan, + return mxs_chan->status; + } + +-static int __init mxs_dma_init(struct mxs_dma_engine *mxs_dma) ++static int mxs_dma_init(struct mxs_dma_engine *mxs_dma) + { + int ret; + +@@ -741,7 +741,7 @@ static struct dma_chan *mxs_dma_xlate(struct of_phandle_args *dma_spec, + ofdma->of_node); + } + +-static int __init mxs_dma_probe(struct platform_device *pdev) ++static int mxs_dma_probe(struct platform_device *pdev) + { + struct device_node *np = pdev->dev.of_node; + const struct mxs_dma_type *dma_type; +@@ -839,10 +839,7 @@ static struct platform_driver mxs_dma_driver = { + .name = "mxs-dma", + .of_match_table = mxs_dma_dt_ids, + }, ++ .probe = mxs_dma_probe, + }; + +-static int __init mxs_dma_module_init(void) +-{ +- return platform_driver_probe(&mxs_dma_driver, mxs_dma_probe); +-} +-subsys_initcall(mxs_dma_module_init); ++builtin_platform_driver(mxs_dma_driver); +-- +2.35.3 + diff --git a/patches.suse/dmaengine-ti-k3-udma-private-Fix-refcount-leak-bug-i.patch b/patches.suse/dmaengine-ti-k3-udma-private-Fix-refcount-leak-bug-i.patch new file mode 100644 index 0000000..fb302ae --- /dev/null +++ b/patches.suse/dmaengine-ti-k3-udma-private-Fix-refcount-leak-bug-i.patch @@ -0,0 +1,48 @@ +From f9fdb0b86f087c2b7f6c6168dd0985a3c1eda87e Mon Sep 17 00:00:00 2001 +From: Liang He +Date: Wed, 20 Jul 2022 15:32:34 +0800 +Subject: [PATCH] dmaengine: ti: k3-udma-private: Fix refcount leak bug in of_xudma_dev_get() +Git-commit: f9fdb0b86f087c2b7f6c6168dd0985a3c1eda87e +Patch-mainline: v6.0-rc7 +References: git-fixes + +We should call of_node_put() for the reference returned by +of_parse_phandle() in fail path or when it is not used anymore. +Here we only need to move the of_node_put() before the check. + +Fixes: d70241913413 ("dmaengine: ti: k3-udma: Add glue layer for non DMAengine users") +Signed-off-by: Liang He +Acked-by: Peter Ujfalusi +Link: https://lore.kernel.org/r/20220720073234.1255474-1-windhl@126.com +Signed-off-by: Vinod Koul +Acked-by: Takashi Iwai + +--- + drivers/dma/ti/k3-udma-private.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/dma/ti/k3-udma-private.c b/drivers/dma/ti/k3-udma-private.c +index d4f1e4e9603a..85e00701473c 100644 +--- a/drivers/dma/ti/k3-udma-private.c ++++ b/drivers/dma/ti/k3-udma-private.c +@@ -31,14 +31,14 @@ struct udma_dev *of_xudma_dev_get(struct device_node *np, const char *property) + } + + pdev = of_find_device_by_node(udma_node); ++ if (np != udma_node) ++ of_node_put(udma_node); ++ + if (!pdev) { + pr_debug("UDMA device not found\n"); + return ERR_PTR(-EPROBE_DEFER); + } + +- if (np != udma_node) +- of_node_put(udma_node); +- + ud = platform_get_drvdata(pdev); + if (!ud) { + pr_debug("UDMA has not been probed\n"); +-- +2.35.3 + diff --git a/patches.suse/dmaengine-xilinx_dma-Fix-devm_platform_ioremap_resou.patch b/patches.suse/dmaengine-xilinx_dma-Fix-devm_platform_ioremap_resou.patch new file mode 100644 index 0000000..395e891 --- /dev/null +++ b/patches.suse/dmaengine-xilinx_dma-Fix-devm_platform_ioremap_resou.patch @@ -0,0 +1,66 @@ +From 91df7751eb890e970afc08f50b8f0fa5ea39e03d Mon Sep 17 00:00:00 2001 +From: Swati Agarwal +Date: Wed, 17 Aug 2022 11:41:23 +0530 +Subject: [PATCH] dmaengine: xilinx_dma: Fix devm_platform_ioremap_resource error handling +Git-commit: 91df7751eb890e970afc08f50b8f0fa5ea39e03d +Patch-mainline: v6.0-rc7 +References: git-fixes + +Add missing cleanup in devm_platform_ioremap_resource(). +When probe fails remove dma channel resources and disable clocks in +accordance with the order of resources allocated . + +Signed-off-by: Swati Agarwal +Link: https://lore.kernel.org/r/20220817061125.4720-2-swati.agarwal@xilinx.com +Signed-off-by: Vinod Koul +Acked-by: Takashi Iwai + +--- + drivers/dma/xilinx/xilinx_dma.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c +index 6276934d4d2b..97633f0b8114 100644 +--- a/drivers/dma/xilinx/xilinx_dma.c ++++ b/drivers/dma/xilinx/xilinx_dma.c +@@ -3040,9 +3040,10 @@ static int xilinx_dma_probe(struct platform_device *pdev) + + /* Request and map I/O memory */ + xdev->regs = devm_platform_ioremap_resource(pdev, 0); +- if (IS_ERR(xdev->regs)) +- return PTR_ERR(xdev->regs); +- ++ if (IS_ERR(xdev->regs)) { ++ err = PTR_ERR(xdev->regs); ++ goto disable_clks; ++ } + /* Retrieve the DMA engine properties from the device tree */ + xdev->max_buffer_len = GENMASK(XILINX_DMA_MAX_TRANS_LEN_MAX - 1, 0); + xdev->s2mm_chan_id = xdev->dma_config->max_channels / 2; +@@ -3137,7 +3138,7 @@ static int xilinx_dma_probe(struct platform_device *pdev) + for_each_child_of_node(node, child) { + err = xilinx_dma_child_probe(xdev, child); + if (err < 0) +- goto disable_clks; ++ goto error; + } + + if (xdev->dma_config->dmatype == XDMA_TYPE_VDMA) { +@@ -3172,12 +3173,12 @@ static int xilinx_dma_probe(struct platform_device *pdev) + + return 0; + +-disable_clks: +- xdma_disable_allclks(xdev); + error: + for (i = 0; i < xdev->dma_config->max_channels; i++) + if (xdev->chan[i]) + xilinx_dma_chan_remove(xdev->chan[i]); ++disable_clks: ++ xdma_disable_allclks(xdev); + + return err; + } +-- +2.35.3 + diff --git a/patches.suse/dmaengine-xilinx_dma-Report-error-in-case-of-dma_set.patch b/patches.suse/dmaengine-xilinx_dma-Report-error-in-case-of-dma_set.patch new file mode 100644 index 0000000..187390c --- /dev/null +++ b/patches.suse/dmaengine-xilinx_dma-Report-error-in-case-of-dma_set.patch @@ -0,0 +1,46 @@ +From 8f2b6bc79c32f0fa60df000ae387a790ec80eae9 Mon Sep 17 00:00:00 2001 +From: Swati Agarwal +Date: Wed, 17 Aug 2022 11:41:25 +0530 +Subject: [PATCH] dmaengine: xilinx_dma: Report error in case of dma_set_mask_and_coherent API failure +Git-commit: 8f2b6bc79c32f0fa60df000ae387a790ec80eae9 +Patch-mainline: v6.0-rc7 +References: git-fixes + +The driver does not handle the failure case while calling +dma_set_mask_and_coherent API. + +In case of failure, capture the return value of API and then report an +error. + +Addresses-coverity: Unchecked return value (CHECKED_RETURN) + +Signed-off-by: Swati Agarwal +Reviewed-by: Radhey Shyam Pandey +Link: https://lore.kernel.org/r/20220817061125.4720-4-swati.agarwal@xilinx.com +Signed-off-by: Vinod Koul +Acked-by: Takashi Iwai + +--- + drivers/dma/xilinx/xilinx_dma.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c +index 5e6e46437aea..8cd4e69dc7b4 100644 +--- a/drivers/dma/xilinx/xilinx_dma.c ++++ b/drivers/dma/xilinx/xilinx_dma.c +@@ -3091,7 +3091,11 @@ static int xilinx_dma_probe(struct platform_device *pdev) + xdev->ext_addr = false; + + /* Set the dma mask bits */ +- dma_set_mask_and_coherent(xdev->dev, DMA_BIT_MASK(addr_width)); ++ err = dma_set_mask_and_coherent(xdev->dev, DMA_BIT_MASK(addr_width)); ++ if (err < 0) { ++ dev_err(xdev->dev, "DMA mask error %d\n", err); ++ goto disable_clks; ++ } + + /* Initialize the DMA engine */ + xdev->common.dev = &pdev->dev; +-- +2.35.3 + diff --git a/patches.suse/dmaengine-xilinx_dma-cleanup-for-fetching-xlnx-num-f.patch b/patches.suse/dmaengine-xilinx_dma-cleanup-for-fetching-xlnx-num-f.patch new file mode 100644 index 0000000..c169297 --- /dev/null +++ b/patches.suse/dmaengine-xilinx_dma-cleanup-for-fetching-xlnx-num-f.patch @@ -0,0 +1,35 @@ +From 462bce790e6a7e68620a4ce260cc38f7ed0255d5 Mon Sep 17 00:00:00 2001 +From: Swati Agarwal +Date: Wed, 17 Aug 2022 11:41:24 +0530 +Subject: [PATCH] dmaengine: xilinx_dma: cleanup for fetching xlnx,num-fstores property +Git-commit: 462bce790e6a7e68620a4ce260cc38f7ed0255d5 +Patch-mainline: v6.0-rc7 +References: git-fixes + +Free the allocated resources for missing xlnx,num-fstores property. + +Signed-off-by: Swati Agarwal +Link: https://lore.kernel.org/r/20220817061125.4720-3-swati.agarwal@xilinx.com +Signed-off-by: Vinod Koul +Acked-by: Takashi Iwai + +--- + drivers/dma/xilinx/xilinx_dma.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c +index 97633f0b8114..5e6e46437aea 100644 +--- a/drivers/dma/xilinx/xilinx_dma.c ++++ b/drivers/dma/xilinx/xilinx_dma.c +@@ -3071,7 +3071,7 @@ static int xilinx_dma_probe(struct platform_device *pdev) + if (err < 0) { + dev_err(xdev->dev, + "missing xlnx,num-fstores property\n"); +- return err; ++ goto disable_clks; + } + + err = of_property_read_u32(node, "xlnx,flush-fsync", +-- +2.35.3 + diff --git a/patches.suse/docs-update-mediator-information-in-CoC-docs.patch b/patches.suse/docs-update-mediator-information-in-CoC-docs.patch new file mode 100644 index 0000000..bedc39b --- /dev/null +++ b/patches.suse/docs-update-mediator-information-in-CoC-docs.patch @@ -0,0 +1,36 @@ +From 8bfdfa0d6b929ede7b6189e0e546ceb6a124d05d Mon Sep 17 00:00:00 2001 +From: Shuah Khan +Date: Thu, 1 Sep 2022 15:23:19 -0600 +Subject: [PATCH] docs: update mediator information in CoC docs +Git-commit: 8bfdfa0d6b929ede7b6189e0e546ceb6a124d05d +Patch-mainline: v6.1-rc1 +References: git-fixes + +Update mediator information in the CoC interpretation document. + +Signed-off-by: Shuah Khan +Link: https://lore.kernel.org/r/20220901212319.56644-1-skhan@linuxfoundation.org +Cc: stable@vger.kernel.org +Signed-off-by: Jonathan Corbet +Acked-by: Takashi Iwai + +--- + Documentation/process/code-of-conduct-interpretation.rst | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Documentation/process/code-of-conduct-interpretation.rst b/Documentation/process/code-of-conduct-interpretation.rst +index e899f14a4ba2..4f8a06b00f60 100644 +--- a/Documentation/process/code-of-conduct-interpretation.rst ++++ b/Documentation/process/code-of-conduct-interpretation.rst +@@ -51,7 +51,7 @@ the Technical Advisory Board (TAB) or other maintainers if you're + uncertain how to handle situations that come up. It will not be + considered a violation report unless you want it to be. If you are + uncertain about approaching the TAB or any other maintainers, please +-reach out to our conflict mediator, Mishi Choudhary . ++reach out to our conflict mediator, Joanna Lee . + + In the end, "be kind to each other" is really what the end goal is for + everybody. We know everyone is human and we all fail at times, but the +-- +2.35.3 + diff --git a/patches.suse/drivers-serial-jsm-fix-some-leaks-in-probe.patch b/patches.suse/drivers-serial-jsm-fix-some-leaks-in-probe.patch new file mode 100644 index 0000000..ce157c9 --- /dev/null +++ b/patches.suse/drivers-serial-jsm-fix-some-leaks-in-probe.patch @@ -0,0 +1,37 @@ +From 1d5859ef229e381f4db38dce8ed58e4bf862006b Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Thu, 22 Sep 2022 14:22:47 +0300 +Subject: [PATCH] drivers: serial: jsm: fix some leaks in probe +Git-commit: 1d5859ef229e381f4db38dce8ed58e4bf862006b +Patch-mainline: v6.1-rc1 +References: git-fixes + +This error path needs to unwind instead of just returning directly. + +Fixes: 03a8482c17dd ("drivers: serial: jsm: Enable support for Digi Classic adapters") +Signed-off-by: Dan Carpenter +Link: https://lore.kernel.org/r/YyxFh1+lOeZ9WfKO@kili +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/tty/serial/jsm/jsm_driver.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/tty/serial/jsm/jsm_driver.c b/drivers/tty/serial/jsm/jsm_driver.c +index 0ea799bf8dbb..417a5b6bffc3 100644 +--- a/drivers/tty/serial/jsm/jsm_driver.c ++++ b/drivers/tty/serial/jsm/jsm_driver.c +@@ -211,7 +211,8 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent) + + break; + default: +- return -ENXIO; ++ rc = -ENXIO; ++ goto out_kfree_brd; + } + + rc = request_irq(brd->irq, brd->bd_ops->intr, IRQF_SHARED, "JSM", brd); +-- +2.35.3 + diff --git a/patches.suse/drm-amd-amdgpu-fixing-read-wrong-pf2vf-data-in-SRIOV.patch b/patches.suse/drm-amd-amdgpu-fixing-read-wrong-pf2vf-data-in-SRIOV.patch new file mode 100644 index 0000000..9c82f43 --- /dev/null +++ b/patches.suse/drm-amd-amdgpu-fixing-read-wrong-pf2vf-data-in-SRIOV.patch @@ -0,0 +1,100 @@ +From 9a458402fb69bda886aa6cbe067311b6e3d9c52a Mon Sep 17 00:00:00 2001 +From: Jingwen Chen +Date: Thu, 13 Jan 2022 19:06:59 +0800 +Subject: [PATCH] drm/amd/amdgpu: fixing read wrong pf2vf data in SRIOV +Git-commit: 9a458402fb69bda886aa6cbe067311b6e3d9c52a +Alt-commit: 22c16d251a79c3156d17627810557878e600dc6a +Patch-mainline: v5.17-rc1 +References: git-fixes + +[Why] +This fixes 892deb48269c ("drm/amdgpu: Separate vf2pf work item init from virt data exchange"). +we should read pf2vf data based at mman.fw_vram_usage_va after gmc +sw_init. commit 892deb48269c breaks this logic. + +[How] +calling amdgpu_virt_exchange_data in amdgpu_virt_init_data_exchange to +set the right base in the right sequence. + +V2: +call amdgpu_virt_init_data_exchange after gmc sw_init to make data +exchange workqueue run + +V3: +clean up the code logic + +V4: +add some comment and make the code more readable + +Fixes: 892deb48269c ("drm/amdgpu: Separate vf2pf work item init from virt data exchange") +Signed-off-by: Jingwen Chen +Reviewed-by: Horace Chen +Signed-off-by: Alex Deucher +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 +- + drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 20 +++++++------------- + 2 files changed, 8 insertions(+), 14 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +index c4f3c886be55..ed077de426d9 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +@@ -2354,7 +2354,7 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev) + } + + if (amdgpu_sriov_vf(adev)) +- amdgpu_virt_exchange_data(adev); ++ amdgpu_virt_init_data_exchange(adev); + + r = amdgpu_ib_pool_init(adev); + if (r) { +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +index 894444ab0032..07bc0f504713 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +@@ -625,20 +625,20 @@ void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev) + adev->virt.fw_reserve.p_vf2pf = NULL; + adev->virt.vf2pf_update_interval_ms = 0; + +- if (adev->bios != NULL) { +- adev->virt.vf2pf_update_interval_ms = 2000; ++ if (adev->mman.fw_vram_usage_va != NULL) { ++ /* go through this logic in ip_init and reset to init workqueue*/ ++ amdgpu_virt_exchange_data(adev); + ++ INIT_DELAYED_WORK(&adev->virt.vf2pf_work, amdgpu_virt_update_vf2pf_work_item); ++ schedule_delayed_work(&(adev->virt.vf2pf_work), msecs_to_jiffies(adev->virt.vf2pf_update_interval_ms)); ++ } else if (adev->bios != NULL) { ++ /* got through this logic in early init stage to get necessary flags, e.g. rlcg_acc related*/ + adev->virt.fw_reserve.p_pf2vf = + (struct amd_sriov_msg_pf2vf_info_header *) + (adev->bios + (AMD_SRIOV_MSG_PF2VF_OFFSET_KB << 10)); + + amdgpu_virt_read_pf2vf_data(adev); + } +- +- if (adev->virt.vf2pf_update_interval_ms != 0) { +- INIT_DELAYED_WORK(&adev->virt.vf2pf_work, amdgpu_virt_update_vf2pf_work_item); +- schedule_delayed_work(&(adev->virt.vf2pf_work), msecs_to_jiffies(adev->virt.vf2pf_update_interval_ms)); +- } + } + + +@@ -674,12 +674,6 @@ void amdgpu_virt_exchange_data(struct amdgpu_device *adev) + if (adev->virt.ras_init_done) + amdgpu_virt_add_bad_page(adev, bp_block_offset, bp_block_size); + } +- } else if (adev->bios != NULL) { +- adev->virt.fw_reserve.p_pf2vf = +- (struct amd_sriov_msg_pf2vf_info_header *) +- (adev->bios + (AMD_SRIOV_MSG_PF2VF_OFFSET_KB << 10)); +- +- amdgpu_virt_read_pf2vf_data(adev); + } + } + +-- +2.35.3 + diff --git a/patches.suse/drm-amd-amdgpu-skip-ucode-loading-if-ucode_size-0.patch b/patches.suse/drm-amd-amdgpu-skip-ucode-loading-if-ucode_size-0.patch new file mode 100644 index 0000000..f1bce46 --- /dev/null +++ b/patches.suse/drm-amd-amdgpu-skip-ucode-loading-if-ucode_size-0.patch @@ -0,0 +1,35 @@ +From 39c84b8e929dbd4f63be7e04bf1a2bcd92b44177 Mon Sep 17 00:00:00 2001 +From: Chengming Gui +Date: Tue, 30 Aug 2022 16:33:01 +0800 +Subject: [PATCH] drm/amd/amdgpu: skip ucode loading if ucode_size == 0 +Git-commit: 39c84b8e929dbd4f63be7e04bf1a2bcd92b44177 +Patch-mainline: v6.0-rc4 +References: git-fixes + +Restrict the ucode loading check to avoid frontdoor loading error. + +Signed-off-by: Chengming Gui +Reviewed-by: Hawking Zhang +Signed-off-by: Alex Deucher +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +index 1036446abc30..9f7a5e393f85 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +@@ -2401,7 +2401,7 @@ static int psp_load_smu_fw(struct psp_context *psp) + static bool fw_load_skip_check(struct psp_context *psp, + struct amdgpu_firmware_info *ucode) + { +- if (!ucode->fw) ++ if (!ucode->fw || !ucode->ucode_size) + return true; + + if (ucode->ucode_id == AMDGPU_UCODE_ID_SMC && +-- +2.35.3 + diff --git a/patches.suse/drm-amd-display-Assume-an-LTTPR-is-always-present-on.patch b/patches.suse/drm-amd-display-Assume-an-LTTPR-is-always-present-on.patch new file mode 100644 index 0000000..8ad62c0 --- /dev/null +++ b/patches.suse/drm-amd-display-Assume-an-LTTPR-is-always-present-on.patch @@ -0,0 +1,44 @@ +From 29956d0fded036a570bd8e7d4ea4b1a1730307d2 Mon Sep 17 00:00:00 2001 +From: Michael Strauss +Date: Wed, 31 Aug 2022 15:10:43 -0400 +Subject: [PATCH] drm/amd/display: Assume an LTTPR is always present on fixed_vs links +Git-commit: 29956d0fded036a570bd8e7d4ea4b1a1730307d2 +Patch-mainline: v6.0-rc7 +References: git-fixes + +[WHY] +LTTPRs can in very rare instsances fail to increment DPCD LTTPR count. +This results in aux-i LTTPR requests to be sent to the wrong DPCD +address, which causes link training failure. + +[HOW] +Override internal repeater count if fixed_vs flag is set for a given link + +Reviewed-by: George Shen +Acked-by: Wayne Lin +Signed-off-by: Michael Strauss +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +@@ -3697,6 +3697,14 @@ bool dp_retrieve_lttpr_cap(struct dc_lin + lttpr_dpcd_data[DP_PHY_REPEATER_EXTENDED_WAIT_TIMEOUT - + DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV]; + ++ /* If this chip cap is set, at least one retimer must exist in the chain ++ * Override count to 1 if we receive a known bad count (0 or an invalid value) */ ++ if (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN && ++ (dp_convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt) == 0)) { ++ ASSERT(0); ++ link->dpcd_caps.lttpr_caps.phy_repeater_cnt = 0x80; ++ } ++ + /* Attempt to train in LTTPR transparent mode if repeater count exceeds 8. */ + is_lttpr_present = (dp_convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt) != 0 && + link->dpcd_caps.lttpr_caps.max_lane_count > 0 && diff --git a/patches.suse/drm-amd-display-Correct-MPC-split-policy-for-DCN301.patch b/patches.suse/drm-amd-display-Correct-MPC-split-policy-for-DCN301.patch new file mode 100644 index 0000000..9ad9838 --- /dev/null +++ b/patches.suse/drm-amd-display-Correct-MPC-split-policy-for-DCN301.patch @@ -0,0 +1,41 @@ +From ac46d93235074a6c5d280d35771c23fd8620e7d9 Mon Sep 17 00:00:00 2001 +From: Zhan Liu +Date: Wed, 19 Jan 2022 16:55:16 -0500 +Subject: [PATCH] drm/amd/display: Correct MPC split policy for DCN301 +Git-commit: ac46d93235074a6c5d280d35771c23fd8620e7d9 +Patch-mainline: v5.17-rc2 +References: git-fixes + +[Why] +DCN301 has seamless boot enabled. With MPC split enabled +at the same time, system will hang. + +[How] +Revert MPC split policy back to "MPC_SPLIT_AVOID". Since we have +ODM combine enabled on DCN301, pipe split is not necessary here. + +Signed-off-by: Zhan Liu +Reviewed-by: Charlene Liu +Signed-off-by: Alex Deucher +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c +index c1c6e602b06c..b4001233867c 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c +@@ -686,7 +686,7 @@ static const struct dc_debug_options debug_defaults_drv = { + .disable_clock_gate = true, + .disable_pplib_clock_request = true, + .disable_pplib_wm_range = true, +- .pipe_split_policy = MPC_SPLIT_DYNAMIC, ++ .pipe_split_policy = MPC_SPLIT_AVOID, + .force_single_disp_pipe_split = false, + .disable_dcc = DCC_ENABLE, + .vsr_support = true, +-- +2.35.3 + diff --git a/patches.suse/drm-amd-display-Fix-double-cursor-on-non-video-RGB-M.patch b/patches.suse/drm-amd-display-Fix-double-cursor-on-non-video-RGB-M.patch new file mode 100644 index 0000000..a033617 --- /dev/null +++ b/patches.suse/drm-amd-display-Fix-double-cursor-on-non-video-RGB-M.patch @@ -0,0 +1,81 @@ +From b261509952bc19d1012cf732f853659be6ebc61e Mon Sep 17 00:00:00 2001 +From: Leo Li +Date: Tue, 30 Aug 2022 16:38:16 -0400 +Subject: [PATCH] drm/amd/display: Fix double cursor on non-video RGB MPO +Git-commit: b261509952bc19d1012cf732f853659be6ebc61e +Patch-mainline: v6.0-rc7 +References: git-fixes + +[Why] + +DC makes use of layer_index (zpos) when picking the HW plane to enable +HW cursor on. However, some compositors will not attach zpos information +to each DRM plane. Consequently, in amdgpu, we default layer_index to 0 +and do not update it. + +This causes said DC logic to enable HW cursor on all planes of the same +layer_index, which manifests as a double cursor issue if one of the +planes is scaled (and hence scaling the cursor as well). + +[How] + +Use DRM core helpers to calculate a normalized_zpos value for each +drm_plane_state under each crtc, within the atomic state. + +This helper will first consider existing zpos values, and if +identical/unset, fallback to plane ID ordering. + +The normalized_zpos is then passed to dc_plane_info during atomic check +for later use by the cursor logic. + +Reviewed-by: Bhawanpreet Lakha +Acked-by: Wayne Lin +Signed-off-by: Leo Li +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +index 5140d9c2bf3b..1efe7fa5bc58 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -4759,7 +4759,7 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev, + plane_info->visible = true; + plane_info->stereo_format = PLANE_STEREO_FORMAT_NONE; + +- plane_info->layer_index = 0; ++ plane_info->layer_index = plane_state->normalized_zpos; + + ret = fill_plane_color_attributes(plane_state, plane_info->format, + &plane_info->color_space); +@@ -4827,7 +4827,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev, + dc_plane_state->global_alpha = plane_info.global_alpha; + dc_plane_state->global_alpha_value = plane_info.global_alpha_value; + dc_plane_state->dcc = plane_info.dcc; +- dc_plane_state->layer_index = plane_info.layer_index; // Always returns 0 ++ dc_plane_state->layer_index = plane_info.layer_index; + dc_plane_state->flip_int_enabled = true; + + /* +@@ -9485,6 +9485,14 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, + } + } + ++ /* ++ * DC consults the zpos (layer_index in DC terminology) to determine the ++ * hw plane on which to enable the hw cursor (see ++ * `dcn10_can_pipe_disable_cursor`). By now, all modified planes are in ++ * atomic state, so call drm helper to normalize zpos. ++ */ ++ drm_atomic_normalize_zpos(dev, state); ++ + /* Remove exiting planes if they are modified */ + for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) { + ret = dm_update_plane_state(dc, state, plane, +-- +2.35.3 + diff --git a/patches.suse/drm-amd-display-Limit-user-regamma-to-a-valid-value.patch b/patches.suse/drm-amd-display-Limit-user-regamma-to-a-valid-value.patch new file mode 100644 index 0000000..6f52e61 --- /dev/null +++ b/patches.suse/drm-amd-display-Limit-user-regamma-to-a-valid-value.patch @@ -0,0 +1,55 @@ +From 3601d620f22e37740cf73f8278eabf9f2aa19eb7 Mon Sep 17 00:00:00 2001 +From: Yao Wang1 +Date: Mon, 22 Aug 2022 18:30:31 +0800 +Subject: [PATCH] drm/amd/display: Limit user regamma to a valid value +Git-commit: 3601d620f22e37740cf73f8278eabf9f2aa19eb7 +Patch-mainline: v6.0-rc6 +References: git-fixes + +[Why] +For HDR mode, we get total 512 tf_point and after switching to SDR mode +we actually get 400 tf_point and the rest of points(401~512) still use +dirty value from HDR mode. We should limit the rest of the points to max +value. + +[How] +Limit the value when coordinates_x.x > 1, just like what we do in +translate_from_linear_space for other re-gamma build paths. + +Tested-by: Daniel Wheeler +Reviewed-by: Krunoslav Kovac +Reviewed-by: Aric Cyr +Acked-by: Pavle Kotarac +Signed-off-by: Yao Wang1 +Signed-off-by: Alex Deucher +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/amd/display/modules/color/color_gamma.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c +index 859ffd8725c5..04f7656906ca 100644 +--- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c ++++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c +@@ -1600,6 +1600,7 @@ static void interpolate_user_regamma(uint32_t hw_points_num, + struct fixed31_32 lut2; + struct fixed31_32 delta_lut; + struct fixed31_32 delta_index; ++ const struct fixed31_32 one = dc_fixpt_from_int(1); + + i = 0; + /* fixed_pt library has problems handling too small values */ +@@ -1628,6 +1629,9 @@ static void interpolate_user_regamma(uint32_t hw_points_num, + } else + hw_x = coordinates_x[i].x; + ++ if (dc_fixpt_le(one, hw_x)) ++ hw_x = one; ++ + norm_x = dc_fixpt_mul(norm_factor, hw_x); + index = dc_fixpt_floor(norm_x); + if (index < 0 || index > 255) +-- +2.35.3 + diff --git a/patches.suse/drm-amd-display-Mark-dml30-s-UseMinimumDCFCLK-as-noi.patch b/patches.suse/drm-amd-display-Mark-dml30-s-UseMinimumDCFCLK-as-noi.patch new file mode 100644 index 0000000..2fc4429 --- /dev/null +++ b/patches.suse/drm-amd-display-Mark-dml30-s-UseMinimumDCFCLK-as-noi.patch @@ -0,0 +1,61 @@ +From 41012d715d5d7b9751ae84b8fb255e404ac9c5d0 Mon Sep 17 00:00:00 2001 +From: Nathan Chancellor +Date: Tue, 30 Aug 2022 13:34:09 -0700 +Subject: [PATCH] drm/amd/display: Mark dml30's UseMinimumDCFCLK() as noinline for stack usage +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 41012d715d5d7b9751ae84b8fb255e404ac9c5d0 +Patch-mainline: v6.0-rc6 +References: git-fixes + +This function consumes a lot of stack space and it blows up the size of +dml30_ModeSupportAndSystemConfigurationFull() with clang: + + drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn30/display_mode_vba_30.c:3542:6: error: stack frame size (2200) exceeds limit (2048) in 'dml30_ModeSupportAndSystemConfigurationFull' [-Werror,-Wframe-larger-than] + void dml30_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib) + ^ + 1 error generated. + +Commit a0f7e7f759cf ("drm/amd/display: fix i386 frame size warning") +aimed to address this for i386 but it did not help x86_64. + +To reduce the amount of stack space that +dml30_ModeSupportAndSystemConfigurationFull() uses, mark +UseMinimumDCFCLK() as noinline, using the _for_stack variant for +documentation. While this will increase the total amount of stack usage +between the two functions (1632 and 1304 bytes respectively), it will +make sure both stay below the limit of 2048 bytes for these files. The +aforementioned change does help reduce UseMinimumDCFCLK()'s stack usage +so it should not be reverted in favor of this change. + +Link: https://github.com/ClangBuiltLinux/linux/issues/1681 +Reported-by: "Sudip Mukherjee (Codethink)" +Tested-by: Maíra Canal +Reviewed-by: Rodrigo Siqueira +Signed-off-by: Nathan Chancellor +Signed-off-by: Rodrigo Siqueira +Signed-off-by: Alex Deucher +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c +index 876b321b30ca..1cb858dd6ea0 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c ++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c +@@ -6610,8 +6610,7 @@ static double CalculateUrgentLatency( + return ret; + } + +- +-static void UseMinimumDCFCLK( ++static noinline_for_stack void UseMinimumDCFCLK( + struct display_mode_lib *mode_lib, + int MaxInterDCNTileRepeaters, + int MaxPrefetchMode, +-- +2.35.3 + diff --git a/patches.suse/drm-amd-display-Reduce-number-of-arguments-of-dml31--21485d3da659.patch b/patches.suse/drm-amd-display-Reduce-number-of-arguments-of-dml31--21485d3da659.patch new file mode 100644 index 0000000..c25c463 --- /dev/null +++ b/patches.suse/drm-amd-display-Reduce-number-of-arguments-of-dml31--21485d3da659.patch @@ -0,0 +1,308 @@ +From 21485d3da659b66c37d99071623af83ee1c6733d Mon Sep 17 00:00:00 2001 +From: Nathan Chancellor +Date: Tue, 30 Aug 2022 13:34:08 -0700 +Subject: [PATCH] drm/amd/display: Reduce number of arguments of dml31's CalculateFlipSchedule() +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 21485d3da659b66c37d99071623af83ee1c6733d +Patch-mainline: v6.0-rc6 +References: git-fixes + +Most of the arguments are identical between the two call sites and they +can be accessed through the 'struct vba_vars_st' pointer. This reduces +the total amount of stack space that +dml31_ModeSupportAndSystemConfigurationFull() uses by 112 bytes with +LLVM 16 (1976 -> 1864), helping clear up the following clang warning: + + drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn31/display_mode_vba_31.c:3908:6: error: stack frame size (2216) exceeds limit (2048) in 'dml31_ModeSupportAndSystemConfigurationFull' [-Werror,-Wframe-larger-than] + void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib) + ^ + 1 error generated. + +Link: https://github.com/ClangBuiltLinux/linux/issues/1681 +Reported-by: "Sudip Mukherjee (Codethink)" +Tested-by: Maíra Canal +Reviewed-by: Rodrigo Siqueira +Signed-off-by: Nathan Chancellor +Signed-off-by: Rodrigo Siqueira +Signed-off-by: Alex Deucher +Acked-by: Takashi Iwai + +--- + .../dc/dml/dcn31/display_mode_vba_31.c | 172 +++++------------- + 1 file changed, 47 insertions(+), 125 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c +index 6790a18eebc8..8ca66f1644dc 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c ++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c +@@ -251,33 +251,13 @@ static void CalculateRowBandwidth( + + static void CalculateFlipSchedule( + struct display_mode_lib *mode_lib, ++ unsigned int k, + double HostVMInefficiencyFactor, + double UrgentExtraLatency, + double UrgentLatency, +- unsigned int GPUVMMaxPageTableLevels, +- bool HostVMEnable, +- unsigned int HostVMMaxNonCachedPageTableLevels, +- bool GPUVMEnable, +- double HostVMMinPageSize, + double PDEAndMetaPTEBytesPerFrame, + double MetaRowBytes, +- double DPTEBytesPerRow, +- double BandwidthAvailableForImmediateFlip, +- unsigned int TotImmediateFlipBytes, +- enum source_format_class SourcePixelFormat, +- double LineTime, +- double VRatio, +- double VRatioChroma, +- double Tno_bw, +- bool DCCEnable, +- unsigned int dpte_row_height, +- unsigned int meta_row_height, +- unsigned int dpte_row_height_chroma, +- unsigned int meta_row_height_chroma, +- double *DestinationLinesToRequestVMInImmediateFlip, +- double *DestinationLinesToRequestRowInImmediateFlip, +- double *final_flip_bw, +- bool *ImmediateFlipSupportedForPipe); ++ double DPTEBytesPerRow); + static double CalculateWriteBackDelay( + enum source_format_class WritebackPixelFormat, + double WritebackHRatio, +@@ -2868,33 +2848,13 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman + for (k = 0; k < v->NumberOfActivePlanes; ++k) { + CalculateFlipSchedule( + mode_lib, ++ k, + HostVMInefficiencyFactor, + v->UrgentExtraLatency, + v->UrgentLatency, +- v->GPUVMMaxPageTableLevels, +- v->HostVMEnable, +- v->HostVMMaxNonCachedPageTableLevels, +- v->GPUVMEnable, +- v->HostVMMinPageSize, + v->PDEAndMetaPTEBytesFrame[k], + v->MetaRowByte[k], +- v->PixelPTEBytesPerRow[k], +- v->BandwidthAvailableForImmediateFlip, +- v->TotImmediateFlipBytes, +- v->SourcePixelFormat[k], +- v->HTotal[k] / v->PixelClock[k], +- v->VRatio[k], +- v->VRatioChroma[k], +- v->Tno_bw[k], +- v->DCCEnable[k], +- v->dpte_row_height[k], +- v->meta_row_height[k], +- v->dpte_row_height_chroma[k], +- v->meta_row_height_chroma[k], +- &v->DestinationLinesToRequestVMInImmediateFlip[k], +- &v->DestinationLinesToRequestRowInImmediateFlip[k], +- &v->final_flip_bw[k], +- &v->ImmediateFlipSupportedForPipe[k]); ++ v->PixelPTEBytesPerRow[k]); + } + + v->total_dcn_read_bw_with_flip = 0.0; +@@ -3526,61 +3486,43 @@ static void CalculateRowBandwidth( + + static void CalculateFlipSchedule( + struct display_mode_lib *mode_lib, ++ unsigned int k, + double HostVMInefficiencyFactor, + double UrgentExtraLatency, + double UrgentLatency, +- unsigned int GPUVMMaxPageTableLevels, +- bool HostVMEnable, +- unsigned int HostVMMaxNonCachedPageTableLevels, +- bool GPUVMEnable, +- double HostVMMinPageSize, + double PDEAndMetaPTEBytesPerFrame, + double MetaRowBytes, +- double DPTEBytesPerRow, +- double BandwidthAvailableForImmediateFlip, +- unsigned int TotImmediateFlipBytes, +- enum source_format_class SourcePixelFormat, +- double LineTime, +- double VRatio, +- double VRatioChroma, +- double Tno_bw, +- bool DCCEnable, +- unsigned int dpte_row_height, +- unsigned int meta_row_height, +- unsigned int dpte_row_height_chroma, +- unsigned int meta_row_height_chroma, +- double *DestinationLinesToRequestVMInImmediateFlip, +- double *DestinationLinesToRequestRowInImmediateFlip, +- double *final_flip_bw, +- bool *ImmediateFlipSupportedForPipe) ++ double DPTEBytesPerRow) + { ++ struct vba_vars_st *v = &mode_lib->vba; + double min_row_time = 0.0; + unsigned int HostVMDynamicLevelsTrips; + double TimeForFetchingMetaPTEImmediateFlip; + double TimeForFetchingRowInVBlankImmediateFlip; + double ImmediateFlipBW; ++ double LineTime = v->HTotal[k] / v->PixelClock[k]; + +- if (GPUVMEnable == true && HostVMEnable == true) { +- HostVMDynamicLevelsTrips = HostVMMaxNonCachedPageTableLevels; ++ if (v->GPUVMEnable == true && v->HostVMEnable == true) { ++ HostVMDynamicLevelsTrips = v->HostVMMaxNonCachedPageTableLevels; + } else { + HostVMDynamicLevelsTrips = 0; + } + +- if (GPUVMEnable == true || DCCEnable == true) { +- ImmediateFlipBW = (PDEAndMetaPTEBytesPerFrame + MetaRowBytes + DPTEBytesPerRow) * BandwidthAvailableForImmediateFlip / TotImmediateFlipBytes; ++ if (v->GPUVMEnable == true || v->DCCEnable[k] == true) { ++ ImmediateFlipBW = (PDEAndMetaPTEBytesPerFrame + MetaRowBytes + DPTEBytesPerRow) * v->BandwidthAvailableForImmediateFlip / v->TotImmediateFlipBytes; + } + +- if (GPUVMEnable == true) { ++ if (v->GPUVMEnable == true) { + TimeForFetchingMetaPTEImmediateFlip = dml_max3( +- Tno_bw + PDEAndMetaPTEBytesPerFrame * HostVMInefficiencyFactor / ImmediateFlipBW, +- UrgentExtraLatency + UrgentLatency * (GPUVMMaxPageTableLevels * (HostVMDynamicLevelsTrips + 1) - 1), ++ v->Tno_bw[k] + PDEAndMetaPTEBytesPerFrame * HostVMInefficiencyFactor / ImmediateFlipBW, ++ UrgentExtraLatency + UrgentLatency * (v->GPUVMMaxPageTableLevels * (HostVMDynamicLevelsTrips + 1) - 1), + LineTime / 4.0); + } else { + TimeForFetchingMetaPTEImmediateFlip = 0; + } + +- *DestinationLinesToRequestVMInImmediateFlip = dml_ceil(4.0 * (TimeForFetchingMetaPTEImmediateFlip / LineTime), 1) / 4.0; +- if ((GPUVMEnable == true || DCCEnable == true)) { ++ v->DestinationLinesToRequestVMInImmediateFlip[k] = dml_ceil(4.0 * (TimeForFetchingMetaPTEImmediateFlip / LineTime), 1) / 4.0; ++ if ((v->GPUVMEnable == true || v->DCCEnable[k] == true)) { + TimeForFetchingRowInVBlankImmediateFlip = dml_max3( + (MetaRowBytes + DPTEBytesPerRow * HostVMInefficiencyFactor) / ImmediateFlipBW, + UrgentLatency * (HostVMDynamicLevelsTrips + 1), +@@ -3589,54 +3531,54 @@ static void CalculateFlipSchedule( + TimeForFetchingRowInVBlankImmediateFlip = 0; + } + +- *DestinationLinesToRequestRowInImmediateFlip = dml_ceil(4.0 * (TimeForFetchingRowInVBlankImmediateFlip / LineTime), 1) / 4.0; ++ v->DestinationLinesToRequestRowInImmediateFlip[k] = dml_ceil(4.0 * (TimeForFetchingRowInVBlankImmediateFlip / LineTime), 1) / 4.0; + +- if (GPUVMEnable == true) { +- *final_flip_bw = dml_max( +- PDEAndMetaPTEBytesPerFrame * HostVMInefficiencyFactor / (*DestinationLinesToRequestVMInImmediateFlip * LineTime), +- (MetaRowBytes + DPTEBytesPerRow * HostVMInefficiencyFactor) / (*DestinationLinesToRequestRowInImmediateFlip * LineTime)); +- } else if ((GPUVMEnable == true || DCCEnable == true)) { +- *final_flip_bw = (MetaRowBytes + DPTEBytesPerRow * HostVMInefficiencyFactor) / (*DestinationLinesToRequestRowInImmediateFlip * LineTime); ++ if (v->GPUVMEnable == true) { ++ v->final_flip_bw[k] = dml_max( ++ PDEAndMetaPTEBytesPerFrame * HostVMInefficiencyFactor / (v->DestinationLinesToRequestVMInImmediateFlip[k] * LineTime), ++ (MetaRowBytes + DPTEBytesPerRow * HostVMInefficiencyFactor) / (v->DestinationLinesToRequestRowInImmediateFlip[k] * LineTime)); ++ } else if ((v->GPUVMEnable == true || v->DCCEnable[k] == true)) { ++ v->final_flip_bw[k] = (MetaRowBytes + DPTEBytesPerRow * HostVMInefficiencyFactor) / (v->DestinationLinesToRequestRowInImmediateFlip[k] * LineTime); + } else { +- *final_flip_bw = 0; ++ v->final_flip_bw[k] = 0; + } + +- if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10 || SourcePixelFormat == dm_rgbe_alpha) { +- if (GPUVMEnable == true && DCCEnable != true) { +- min_row_time = dml_min(dpte_row_height * LineTime / VRatio, dpte_row_height_chroma * LineTime / VRatioChroma); +- } else if (GPUVMEnable != true && DCCEnable == true) { +- min_row_time = dml_min(meta_row_height * LineTime / VRatio, meta_row_height_chroma * LineTime / VRatioChroma); ++ if (v->SourcePixelFormat[k] == dm_420_8 || v->SourcePixelFormat[k] == dm_420_10 || v->SourcePixelFormat[k] == dm_rgbe_alpha) { ++ if (v->GPUVMEnable == true && v->DCCEnable[k] != true) { ++ min_row_time = dml_min(v->dpte_row_height[k] * LineTime / v->VRatio[k], v->dpte_row_height_chroma[k] * LineTime / v->VRatioChroma[k]); ++ } else if (v->GPUVMEnable != true && v->DCCEnable[k] == true) { ++ min_row_time = dml_min(v->meta_row_height[k] * LineTime / v->VRatio[k], v->meta_row_height_chroma[k] * LineTime / v->VRatioChroma[k]); + } else { + min_row_time = dml_min4( +- dpte_row_height * LineTime / VRatio, +- meta_row_height * LineTime / VRatio, +- dpte_row_height_chroma * LineTime / VRatioChroma, +- meta_row_height_chroma * LineTime / VRatioChroma); ++ v->dpte_row_height[k] * LineTime / v->VRatio[k], ++ v->meta_row_height[k] * LineTime / v->VRatio[k], ++ v->dpte_row_height_chroma[k] * LineTime / v->VRatioChroma[k], ++ v->meta_row_height_chroma[k] * LineTime / v->VRatioChroma[k]); + } + } else { +- if (GPUVMEnable == true && DCCEnable != true) { +- min_row_time = dpte_row_height * LineTime / VRatio; +- } else if (GPUVMEnable != true && DCCEnable == true) { +- min_row_time = meta_row_height * LineTime / VRatio; ++ if (v->GPUVMEnable == true && v->DCCEnable[k] != true) { ++ min_row_time = v->dpte_row_height[k] * LineTime / v->VRatio[k]; ++ } else if (v->GPUVMEnable != true && v->DCCEnable[k] == true) { ++ min_row_time = v->meta_row_height[k] * LineTime / v->VRatio[k]; + } else { +- min_row_time = dml_min(dpte_row_height * LineTime / VRatio, meta_row_height * LineTime / VRatio); ++ min_row_time = dml_min(v->dpte_row_height[k] * LineTime / v->VRatio[k], v->meta_row_height[k] * LineTime / v->VRatio[k]); + } + } + +- if (*DestinationLinesToRequestVMInImmediateFlip >= 32 || *DestinationLinesToRequestRowInImmediateFlip >= 16 ++ if (v->DestinationLinesToRequestVMInImmediateFlip[k] >= 32 || v->DestinationLinesToRequestRowInImmediateFlip[k] >= 16 + || TimeForFetchingMetaPTEImmediateFlip + 2 * TimeForFetchingRowInVBlankImmediateFlip > min_row_time) { +- *ImmediateFlipSupportedForPipe = false; ++ v->ImmediateFlipSupportedForPipe[k] = false; + } else { +- *ImmediateFlipSupportedForPipe = true; ++ v->ImmediateFlipSupportedForPipe[k] = true; + } + + #ifdef __DML_VBA_DEBUG__ +- dml_print("DML::%s: DestinationLinesToRequestVMInImmediateFlip = %f\n", __func__, *DestinationLinesToRequestVMInImmediateFlip); +- dml_print("DML::%s: DestinationLinesToRequestRowInImmediateFlip = %f\n", __func__, *DestinationLinesToRequestRowInImmediateFlip); ++ dml_print("DML::%s: DestinationLinesToRequestVMInImmediateFlip = %f\n", __func__, v->DestinationLinesToRequestVMInImmediateFlip[k]); ++ dml_print("DML::%s: DestinationLinesToRequestRowInImmediateFlip = %f\n", __func__, v->DestinationLinesToRequestRowInImmediateFlip[k]); + dml_print("DML::%s: TimeForFetchingMetaPTEImmediateFlip = %f\n", __func__, TimeForFetchingMetaPTEImmediateFlip); + dml_print("DML::%s: TimeForFetchingRowInVBlankImmediateFlip = %f\n", __func__, TimeForFetchingRowInVBlankImmediateFlip); + dml_print("DML::%s: min_row_time = %f\n", __func__, min_row_time); +- dml_print("DML::%s: ImmediateFlipSupportedForPipe = %d\n", __func__, *ImmediateFlipSupportedForPipe); ++ dml_print("DML::%s: ImmediateFlipSupportedForPipe = %d\n", __func__, v->ImmediateFlipSupportedForPipe[k]); + #endif + + } +@@ -5228,33 +5170,13 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l + for (k = 0; k < v->NumberOfActivePlanes; k++) { + CalculateFlipSchedule( + mode_lib, ++ k, + HostVMInefficiencyFactor, + v->ExtraLatency, + v->UrgLatency[i], +- v->GPUVMMaxPageTableLevels, +- v->HostVMEnable, +- v->HostVMMaxNonCachedPageTableLevels, +- v->GPUVMEnable, +- v->HostVMMinPageSize, + v->PDEAndMetaPTEBytesPerFrame[i][j][k], + v->MetaRowBytes[i][j][k], +- v->DPTEBytesPerRow[i][j][k], +- v->BandwidthAvailableForImmediateFlip, +- v->TotImmediateFlipBytes, +- v->SourcePixelFormat[k], +- v->HTotal[k] / v->PixelClock[k], +- v->VRatio[k], +- v->VRatioChroma[k], +- v->Tno_bw[k], +- v->DCCEnable[k], +- v->dpte_row_height[k], +- v->meta_row_height[k], +- v->dpte_row_height_chroma[k], +- v->meta_row_height_chroma[k], +- &v->DestinationLinesToRequestVMInImmediateFlip[k], +- &v->DestinationLinesToRequestRowInImmediateFlip[k], +- &v->final_flip_bw[k], +- &v->ImmediateFlipSupportedForPipe[k]); ++ v->DPTEBytesPerRow[i][j][k]); + } + v->total_dcn_read_bw_with_flip = 0.0; + for (k = 0; k < v->NumberOfActivePlanes; k++) { +-- +2.35.3 + diff --git a/patches.suse/drm-amd-display-Reduce-number-of-arguments-of-dml31-.patch b/patches.suse/drm-amd-display-Reduce-number-of-arguments-of-dml31-.patch new file mode 100644 index 0000000..ab1e6ea --- /dev/null +++ b/patches.suse/drm-amd-display-Reduce-number-of-arguments-of-dml31-.patch @@ -0,0 +1,511 @@ +From 37934d4118e22bceb80141804391975078f31734 Mon Sep 17 00:00:00 2001 +From: Nathan Chancellor +Date: Tue, 30 Aug 2022 13:34:07 -0700 +Subject: [PATCH] drm/amd/display: Reduce number of arguments of dml31's CalculateWatermarksAndDRAMSpeedChangeSupport() +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 37934d4118e22bceb80141804391975078f31734 +Patch-mainline: v6.0-rc6 +References: git-fixes + +Most of the arguments are identical between the two call sites and they +can be accessed through the 'struct vba_vars_st' pointer. This reduces +the total amount of stack space that +dml31_ModeSupportAndSystemConfigurationFull() uses by 240 bytes with +LLVM 16 (2216 -> 1976), helping clear up the following clang warning: + + drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn31/display_mode_vba_31.c:3908:6: error: stack frame size (2216) exceeds limit (2048) in 'dml31_ModeSupportAndSystemConfigurationFull' [-Werror,-Wframe-larger-than] + void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib) + ^ + 1 error generated. + +Link: https://github.com/ClangBuiltLinux/linux/issues/1681 +Reported-by: "Sudip Mukherjee (Codethink)" +Tested-by: Maíra Canal +Reviewed-by: Rodrigo Siqueira +Signed-off-by: Nathan Chancellor +Signed-off-by: Rodrigo Siqueira +Signed-off-by: Alex Deucher +Acked-by: Takashi Iwai + +--- + .../dc/dml/dcn31/display_mode_vba_31.c | 248 ++++-------------- + 1 file changed, 52 insertions(+), 196 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c +index d63b4209b14c..6790a18eebc8 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c ++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c +@@ -311,64 +311,28 @@ static void CalculateVupdateAndDynamicMetadataParameters( + static void CalculateWatermarksAndDRAMSpeedChangeSupport( + struct display_mode_lib *mode_lib, + unsigned int PrefetchMode, +- unsigned int NumberOfActivePlanes, +- unsigned int MaxLineBufferLines, +- unsigned int LineBufferSize, +- unsigned int WritebackInterfaceBufferSize, + double DCFCLK, + double ReturnBW, +- bool SynchronizedVBlank, +- unsigned int dpte_group_bytes[], +- unsigned int MetaChunkSize, + double UrgentLatency, + double ExtraLatency, +- double WritebackLatency, +- double WritebackChunkSize, + double SOCCLK, +- double DRAMClockChangeLatency, +- double SRExitTime, +- double SREnterPlusExitTime, +- double SRExitZ8Time, +- double SREnterPlusExitZ8Time, + double DCFCLKDeepSleep, + unsigned int DETBufferSizeY[], + unsigned int DETBufferSizeC[], + unsigned int SwathHeightY[], + unsigned int SwathHeightC[], +- unsigned int LBBitPerPixel[], + double SwathWidthY[], + double SwathWidthC[], +- double HRatio[], +- double HRatioChroma[], +- unsigned int vtaps[], +- unsigned int VTAPsChroma[], +- double VRatio[], +- double VRatioChroma[], +- unsigned int HTotal[], +- double PixelClock[], +- unsigned int BlendingAndTiming[], + unsigned int DPPPerPlane[], + double BytePerPixelDETY[], + double BytePerPixelDETC[], +- double DSTXAfterScaler[], +- double DSTYAfterScaler[], +- bool WritebackEnable[], +- enum source_format_class WritebackPixelFormat[], +- double WritebackDestinationWidth[], +- double WritebackDestinationHeight[], +- double WritebackSourceHeight[], + bool UnboundedRequestEnabled, + int unsigned CompressedBufferSizeInkByte, + enum clock_change_support *DRAMClockChangeSupport, +- double *UrgentWatermark, +- double *WritebackUrgentWatermark, +- double *DRAMClockChangeWatermark, +- double *WritebackDRAMClockChangeWatermark, + double *StutterExitWatermark, + double *StutterEnterPlusExitWatermark, + double *Z8StutterExitWatermark, +- double *Z8StutterEnterPlusExitWatermark, +- double *MinActiveDRAMClockChangeLatencySupported); ++ double *Z8StutterEnterPlusExitWatermark); + + static void CalculateDCFCLKDeepSleep( + struct display_mode_lib *mode_lib, +@@ -3017,64 +2981,28 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman + CalculateWatermarksAndDRAMSpeedChangeSupport( + mode_lib, + PrefetchMode, +- v->NumberOfActivePlanes, +- v->MaxLineBufferLines, +- v->LineBufferSize, +- v->WritebackInterfaceBufferSize, + v->DCFCLK, + v->ReturnBW, +- v->SynchronizedVBlank, +- v->dpte_group_bytes, +- v->MetaChunkSize, + v->UrgentLatency, + v->UrgentExtraLatency, +- v->WritebackLatency, +- v->WritebackChunkSize, + v->SOCCLK, +- v->DRAMClockChangeLatency, +- v->SRExitTime, +- v->SREnterPlusExitTime, +- v->SRExitZ8Time, +- v->SREnterPlusExitZ8Time, + v->DCFCLKDeepSleep, + v->DETBufferSizeY, + v->DETBufferSizeC, + v->SwathHeightY, + v->SwathHeightC, +- v->LBBitPerPixel, + v->SwathWidthY, + v->SwathWidthC, +- v->HRatio, +- v->HRatioChroma, +- v->vtaps, +- v->VTAPsChroma, +- v->VRatio, +- v->VRatioChroma, +- v->HTotal, +- v->PixelClock, +- v->BlendingAndTiming, + v->DPPPerPlane, + v->BytePerPixelDETY, + v->BytePerPixelDETC, +- v->DSTXAfterScaler, +- v->DSTYAfterScaler, +- v->WritebackEnable, +- v->WritebackPixelFormat, +- v->WritebackDestinationWidth, +- v->WritebackDestinationHeight, +- v->WritebackSourceHeight, + v->UnboundedRequestEnabled, + v->CompressedBufferSizeInkByte, + &DRAMClockChangeSupport, +- &v->UrgentWatermark, +- &v->WritebackUrgentWatermark, +- &v->DRAMClockChangeWatermark, +- &v->WritebackDRAMClockChangeWatermark, + &v->StutterExitWatermark, + &v->StutterEnterPlusExitWatermark, + &v->Z8StutterExitWatermark, +- &v->Z8StutterEnterPlusExitWatermark, +- &v->MinActiveDRAMClockChangeLatencySupported); ++ &v->Z8StutterEnterPlusExitWatermark); + + for (k = 0; k < v->NumberOfActivePlanes; ++k) { + if (v->WritebackEnable[k] == true) { +@@ -5384,64 +5312,28 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l + CalculateWatermarksAndDRAMSpeedChangeSupport( + mode_lib, + v->PrefetchModePerState[i][j], +- v->NumberOfActivePlanes, +- v->MaxLineBufferLines, +- v->LineBufferSize, +- v->WritebackInterfaceBufferSize, + v->DCFCLKState[i][j], + v->ReturnBWPerState[i][j], +- v->SynchronizedVBlank, +- v->dpte_group_bytes, +- v->MetaChunkSize, + v->UrgLatency[i], + v->ExtraLatency, +- v->WritebackLatency, +- v->WritebackChunkSize, + v->SOCCLKPerState[i], +- v->DRAMClockChangeLatency, +- v->SRExitTime, +- v->SREnterPlusExitTime, +- v->SRExitZ8Time, +- v->SREnterPlusExitZ8Time, + v->ProjectedDCFCLKDeepSleep[i][j], + v->DETBufferSizeYThisState, + v->DETBufferSizeCThisState, + v->SwathHeightYThisState, + v->SwathHeightCThisState, +- v->LBBitPerPixel, + v->SwathWidthYThisState, + v->SwathWidthCThisState, +- v->HRatio, +- v->HRatioChroma, +- v->vtaps, +- v->VTAPsChroma, +- v->VRatio, +- v->VRatioChroma, +- v->HTotal, +- v->PixelClock, +- v->BlendingAndTiming, + v->NoOfDPPThisState, + v->BytePerPixelInDETY, + v->BytePerPixelInDETC, +- v->DSTXAfterScaler, +- v->DSTYAfterScaler, +- v->WritebackEnable, +- v->WritebackPixelFormat, +- v->WritebackDestinationWidth, +- v->WritebackDestinationHeight, +- v->WritebackSourceHeight, + UnboundedRequestEnabledThisState, + CompressedBufferSizeInkByteThisState, + &v->DRAMClockChangeSupport[i][j], +- &v->UrgentWatermark, +- &v->WritebackUrgentWatermark, +- &v->DRAMClockChangeWatermark, +- &v->WritebackDRAMClockChangeWatermark, +- &dummy, + &dummy, + &dummy, + &dummy, +- &v->MinActiveDRAMClockChangeLatencySupported); ++ &dummy); + } + } + +@@ -5566,64 +5458,28 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l + static void CalculateWatermarksAndDRAMSpeedChangeSupport( + struct display_mode_lib *mode_lib, + unsigned int PrefetchMode, +- unsigned int NumberOfActivePlanes, +- unsigned int MaxLineBufferLines, +- unsigned int LineBufferSize, +- unsigned int WritebackInterfaceBufferSize, + double DCFCLK, + double ReturnBW, +- bool SynchronizedVBlank, +- unsigned int dpte_group_bytes[], +- unsigned int MetaChunkSize, + double UrgentLatency, + double ExtraLatency, +- double WritebackLatency, +- double WritebackChunkSize, + double SOCCLK, +- double DRAMClockChangeLatency, +- double SRExitTime, +- double SREnterPlusExitTime, +- double SRExitZ8Time, +- double SREnterPlusExitZ8Time, + double DCFCLKDeepSleep, + unsigned int DETBufferSizeY[], + unsigned int DETBufferSizeC[], + unsigned int SwathHeightY[], + unsigned int SwathHeightC[], +- unsigned int LBBitPerPixel[], + double SwathWidthY[], + double SwathWidthC[], +- double HRatio[], +- double HRatioChroma[], +- unsigned int vtaps[], +- unsigned int VTAPsChroma[], +- double VRatio[], +- double VRatioChroma[], +- unsigned int HTotal[], +- double PixelClock[], +- unsigned int BlendingAndTiming[], + unsigned int DPPPerPlane[], + double BytePerPixelDETY[], + double BytePerPixelDETC[], +- double DSTXAfterScaler[], +- double DSTYAfterScaler[], +- bool WritebackEnable[], +- enum source_format_class WritebackPixelFormat[], +- double WritebackDestinationWidth[], +- double WritebackDestinationHeight[], +- double WritebackSourceHeight[], + bool UnboundedRequestEnabled, + int unsigned CompressedBufferSizeInkByte, + enum clock_change_support *DRAMClockChangeSupport, +- double *UrgentWatermark, +- double *WritebackUrgentWatermark, +- double *DRAMClockChangeWatermark, +- double *WritebackDRAMClockChangeWatermark, + double *StutterExitWatermark, + double *StutterEnterPlusExitWatermark, + double *Z8StutterExitWatermark, +- double *Z8StutterEnterPlusExitWatermark, +- double *MinActiveDRAMClockChangeLatencySupported) ++ double *Z8StutterEnterPlusExitWatermark) + { + struct vba_vars_st *v = &mode_lib->vba; + double EffectiveLBLatencyHidingY; +@@ -5643,103 +5499,103 @@ static void CalculateWatermarksAndDRAMSpeedChangeSupport( + double TotalPixelBW = 0.0; + int k, j; + +- *UrgentWatermark = UrgentLatency + ExtraLatency; ++ v->UrgentWatermark = UrgentLatency + ExtraLatency; + + #ifdef __DML_VBA_DEBUG__ + dml_print("DML::%s: UrgentLatency = %f\n", __func__, UrgentLatency); + dml_print("DML::%s: ExtraLatency = %f\n", __func__, ExtraLatency); +- dml_print("DML::%s: UrgentWatermark = %f\n", __func__, *UrgentWatermark); ++ dml_print("DML::%s: UrgentWatermark = %f\n", __func__, v->UrgentWatermark); + #endif + +- *DRAMClockChangeWatermark = DRAMClockChangeLatency + *UrgentWatermark; ++ v->DRAMClockChangeWatermark = v->DRAMClockChangeLatency + v->UrgentWatermark; + + #ifdef __DML_VBA_DEBUG__ +- dml_print("DML::%s: DRAMClockChangeLatency = %f\n", __func__, DRAMClockChangeLatency); +- dml_print("DML::%s: DRAMClockChangeWatermark = %f\n", __func__, *DRAMClockChangeWatermark); ++ dml_print("DML::%s: v->DRAMClockChangeLatency = %f\n", __func__, v->DRAMClockChangeLatency); ++ dml_print("DML::%s: DRAMClockChangeWatermark = %f\n", __func__, v->DRAMClockChangeWatermark); + #endif + + v->TotalActiveWriteback = 0; +- for (k = 0; k < NumberOfActivePlanes; ++k) { +- if (WritebackEnable[k] == true) { ++ for (k = 0; k < v->NumberOfActivePlanes; ++k) { ++ if (v->WritebackEnable[k] == true) { + v->TotalActiveWriteback = v->TotalActiveWriteback + 1; + } + } + + if (v->TotalActiveWriteback <= 1) { +- *WritebackUrgentWatermark = WritebackLatency; ++ v->WritebackUrgentWatermark = v->WritebackLatency; + } else { +- *WritebackUrgentWatermark = WritebackLatency + WritebackChunkSize * 1024.0 / 32.0 / SOCCLK; ++ v->WritebackUrgentWatermark = v->WritebackLatency + v->WritebackChunkSize * 1024.0 / 32.0 / SOCCLK; + } + + if (v->TotalActiveWriteback <= 1) { +- *WritebackDRAMClockChangeWatermark = DRAMClockChangeLatency + WritebackLatency; ++ v->WritebackDRAMClockChangeWatermark = v->DRAMClockChangeLatency + v->WritebackLatency; + } else { +- *WritebackDRAMClockChangeWatermark = DRAMClockChangeLatency + WritebackLatency + WritebackChunkSize * 1024.0 / 32.0 / SOCCLK; ++ v->WritebackDRAMClockChangeWatermark = v->DRAMClockChangeLatency + v->WritebackLatency + v->WritebackChunkSize * 1024.0 / 32.0 / SOCCLK; + } + +- for (k = 0; k < NumberOfActivePlanes; ++k) { ++ for (k = 0; k < v->NumberOfActivePlanes; ++k) { + TotalPixelBW = TotalPixelBW +- + DPPPerPlane[k] * (SwathWidthY[k] * BytePerPixelDETY[k] * VRatio[k] + SwathWidthC[k] * BytePerPixelDETC[k] * VRatioChroma[k]) +- / (HTotal[k] / PixelClock[k]); ++ + DPPPerPlane[k] * (SwathWidthY[k] * BytePerPixelDETY[k] * v->VRatio[k] + SwathWidthC[k] * BytePerPixelDETC[k] * v->VRatioChroma[k]) ++ / (v->HTotal[k] / v->PixelClock[k]); + } + +- for (k = 0; k < NumberOfActivePlanes; ++k) { ++ for (k = 0; k < v->NumberOfActivePlanes; ++k) { + double EffectiveDETBufferSizeY = DETBufferSizeY[k]; + + v->LBLatencyHidingSourceLinesY = dml_min( +- (double) MaxLineBufferLines, +- dml_floor(LineBufferSize / LBBitPerPixel[k] / (SwathWidthY[k] / dml_max(HRatio[k], 1.0)), 1)) - (vtaps[k] - 1); ++ (double) v->MaxLineBufferLines, ++ dml_floor(v->LineBufferSize / v->LBBitPerPixel[k] / (SwathWidthY[k] / dml_max(v->HRatio[k], 1.0)), 1)) - (v->vtaps[k] - 1); + + v->LBLatencyHidingSourceLinesC = dml_min( +- (double) MaxLineBufferLines, +- dml_floor(LineBufferSize / LBBitPerPixel[k] / (SwathWidthC[k] / dml_max(HRatioChroma[k], 1.0)), 1)) - (VTAPsChroma[k] - 1); ++ (double) v->MaxLineBufferLines, ++ dml_floor(v->LineBufferSize / v->LBBitPerPixel[k] / (SwathWidthC[k] / dml_max(v->HRatioChroma[k], 1.0)), 1)) - (v->VTAPsChroma[k] - 1); + +- EffectiveLBLatencyHidingY = v->LBLatencyHidingSourceLinesY / VRatio[k] * (HTotal[k] / PixelClock[k]); ++ EffectiveLBLatencyHidingY = v->LBLatencyHidingSourceLinesY / v->VRatio[k] * (v->HTotal[k] / v->PixelClock[k]); + +- EffectiveLBLatencyHidingC = v->LBLatencyHidingSourceLinesC / VRatioChroma[k] * (HTotal[k] / PixelClock[k]); ++ EffectiveLBLatencyHidingC = v->LBLatencyHidingSourceLinesC / v->VRatioChroma[k] * (v->HTotal[k] / v->PixelClock[k]); + + if (UnboundedRequestEnabled) { + EffectiveDETBufferSizeY = EffectiveDETBufferSizeY +- + CompressedBufferSizeInkByte * 1024 * SwathWidthY[k] * BytePerPixelDETY[k] * VRatio[k] / (HTotal[k] / PixelClock[k]) / TotalPixelBW; ++ + CompressedBufferSizeInkByte * 1024 * SwathWidthY[k] * BytePerPixelDETY[k] * v->VRatio[k] / (v->HTotal[k] / v->PixelClock[k]) / TotalPixelBW; + } + + LinesInDETY[k] = (double) EffectiveDETBufferSizeY / BytePerPixelDETY[k] / SwathWidthY[k]; + LinesInDETYRoundedDownToSwath[k] = dml_floor(LinesInDETY[k], SwathHeightY[k]); +- FullDETBufferingTimeY = LinesInDETYRoundedDownToSwath[k] * (HTotal[k] / PixelClock[k]) / VRatio[k]; ++ FullDETBufferingTimeY = LinesInDETYRoundedDownToSwath[k] * (v->HTotal[k] / v->PixelClock[k]) / v->VRatio[k]; + if (BytePerPixelDETC[k] > 0) { + LinesInDETC = v->DETBufferSizeC[k] / BytePerPixelDETC[k] / SwathWidthC[k]; + LinesInDETCRoundedDownToSwath = dml_floor(LinesInDETC, SwathHeightC[k]); +- FullDETBufferingTimeC = LinesInDETCRoundedDownToSwath * (HTotal[k] / PixelClock[k]) / VRatioChroma[k]; ++ FullDETBufferingTimeC = LinesInDETCRoundedDownToSwath * (v->HTotal[k] / v->PixelClock[k]) / v->VRatioChroma[k]; + } else { + LinesInDETC = 0; + FullDETBufferingTimeC = 999999; + } + + ActiveDRAMClockChangeLatencyMarginY = EffectiveLBLatencyHidingY + FullDETBufferingTimeY +- - ((double) DSTXAfterScaler[k] / HTotal[k] + DSTYAfterScaler[k]) * HTotal[k] / PixelClock[k] - *UrgentWatermark - *DRAMClockChangeWatermark; ++ - ((double) v->DSTXAfterScaler[k] / v->HTotal[k] + v->DSTYAfterScaler[k]) * v->HTotal[k] / v->PixelClock[k] - v->UrgentWatermark - v->DRAMClockChangeWatermark; + +- if (NumberOfActivePlanes > 1) { ++ if (v->NumberOfActivePlanes > 1) { + ActiveDRAMClockChangeLatencyMarginY = ActiveDRAMClockChangeLatencyMarginY +- - (1 - 1.0 / NumberOfActivePlanes) * SwathHeightY[k] * HTotal[k] / PixelClock[k] / VRatio[k]; ++ - (1 - 1.0 / v->NumberOfActivePlanes) * SwathHeightY[k] * v->HTotal[k] / v->PixelClock[k] / v->VRatio[k]; + } + + if (BytePerPixelDETC[k] > 0) { + ActiveDRAMClockChangeLatencyMarginC = EffectiveLBLatencyHidingC + FullDETBufferingTimeC +- - ((double) DSTXAfterScaler[k] / HTotal[k] + DSTYAfterScaler[k]) * HTotal[k] / PixelClock[k] - *UrgentWatermark - *DRAMClockChangeWatermark; ++ - ((double) v->DSTXAfterScaler[k] / v->HTotal[k] + v->DSTYAfterScaler[k]) * v->HTotal[k] / v->PixelClock[k] - v->UrgentWatermark - v->DRAMClockChangeWatermark; + +- if (NumberOfActivePlanes > 1) { ++ if (v->NumberOfActivePlanes > 1) { + ActiveDRAMClockChangeLatencyMarginC = ActiveDRAMClockChangeLatencyMarginC +- - (1 - 1.0 / NumberOfActivePlanes) * SwathHeightC[k] * HTotal[k] / PixelClock[k] / VRatioChroma[k]; ++ - (1 - 1.0 / v->NumberOfActivePlanes) * SwathHeightC[k] * v->HTotal[k] / v->PixelClock[k] / v->VRatioChroma[k]; + } + v->ActiveDRAMClockChangeLatencyMargin[k] = dml_min(ActiveDRAMClockChangeLatencyMarginY, ActiveDRAMClockChangeLatencyMarginC); + } else { + v->ActiveDRAMClockChangeLatencyMargin[k] = ActiveDRAMClockChangeLatencyMarginY; + } + +- if (WritebackEnable[k] == true) { +- WritebackDRAMClockChangeLatencyHiding = WritebackInterfaceBufferSize * 1024 +- / (WritebackDestinationWidth[k] * WritebackDestinationHeight[k] / (WritebackSourceHeight[k] * HTotal[k] / PixelClock[k]) * 4); +- if (WritebackPixelFormat[k] == dm_444_64) { ++ if (v->WritebackEnable[k] == true) { ++ WritebackDRAMClockChangeLatencyHiding = v->WritebackInterfaceBufferSize * 1024 ++ / (v->WritebackDestinationWidth[k] * v->WritebackDestinationHeight[k] / (v->WritebackSourceHeight[k] * v->HTotal[k] / v->PixelClock[k]) * 4); ++ if (v->WritebackPixelFormat[k] == dm_444_64) { + WritebackDRAMClockChangeLatencyHiding = WritebackDRAMClockChangeLatencyHiding / 2; + } + WritebackDRAMClockChangeLatencyMargin = WritebackDRAMClockChangeLatencyHiding - v->WritebackDRAMClockChangeWatermark; +@@ -5749,14 +5605,14 @@ static void CalculateWatermarksAndDRAMSpeedChangeSupport( + + v->MinActiveDRAMClockChangeMargin = 999999; + PlaneWithMinActiveDRAMClockChangeMargin = 0; +- for (k = 0; k < NumberOfActivePlanes; ++k) { ++ for (k = 0; k < v->NumberOfActivePlanes; ++k) { + if (v->ActiveDRAMClockChangeLatencyMargin[k] < v->MinActiveDRAMClockChangeMargin) { + v->MinActiveDRAMClockChangeMargin = v->ActiveDRAMClockChangeLatencyMargin[k]; +- if (BlendingAndTiming[k] == k) { ++ if (v->BlendingAndTiming[k] == k) { + PlaneWithMinActiveDRAMClockChangeMargin = k; + } else { +- for (j = 0; j < NumberOfActivePlanes; ++j) { +- if (BlendingAndTiming[k] == j) { ++ for (j = 0; j < v->NumberOfActivePlanes; ++j) { ++ if (v->BlendingAndTiming[k] == j) { + PlaneWithMinActiveDRAMClockChangeMargin = j; + } + } +@@ -5764,11 +5620,11 @@ static void CalculateWatermarksAndDRAMSpeedChangeSupport( + } + } + +- *MinActiveDRAMClockChangeLatencySupported = v->MinActiveDRAMClockChangeMargin + DRAMClockChangeLatency; ++ v->MinActiveDRAMClockChangeLatencySupported = v->MinActiveDRAMClockChangeMargin + v->DRAMClockChangeLatency ; + + SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank = 999999; +- for (k = 0; k < NumberOfActivePlanes; ++k) { +- if (!((k == PlaneWithMinActiveDRAMClockChangeMargin) && (BlendingAndTiming[k] == k)) && !(BlendingAndTiming[k] == PlaneWithMinActiveDRAMClockChangeMargin) ++ for (k = 0; k < v->NumberOfActivePlanes; ++k) { ++ if (!((k == PlaneWithMinActiveDRAMClockChangeMargin) && (v->BlendingAndTiming[k] == k)) && !(v->BlendingAndTiming[k] == PlaneWithMinActiveDRAMClockChangeMargin) + && v->ActiveDRAMClockChangeLatencyMargin[k] < SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank) { + SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank = v->ActiveDRAMClockChangeLatencyMargin[k]; + } +@@ -5776,25 +5632,25 @@ static void CalculateWatermarksAndDRAMSpeedChangeSupport( + + v->TotalNumberOfActiveOTG = 0; + +- for (k = 0; k < NumberOfActivePlanes; ++k) { +- if (BlendingAndTiming[k] == k) { ++ for (k = 0; k < v->NumberOfActivePlanes; ++k) { ++ if (v->BlendingAndTiming[k] == k) { + v->TotalNumberOfActiveOTG = v->TotalNumberOfActiveOTG + 1; + } + } + + if (v->MinActiveDRAMClockChangeMargin > 0 && PrefetchMode == 0) { + *DRAMClockChangeSupport = dm_dram_clock_change_vactive; +- } else if ((SynchronizedVBlank == true || v->TotalNumberOfActiveOTG == 1 ++ } else if ((v->SynchronizedVBlank == true || v->TotalNumberOfActiveOTG == 1 + || SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank > 0) && PrefetchMode == 0) { + *DRAMClockChangeSupport = dm_dram_clock_change_vblank; + } else { + *DRAMClockChangeSupport = dm_dram_clock_change_unsupported; + } + +- *StutterExitWatermark = SRExitTime + ExtraLatency + 10 / DCFCLKDeepSleep; +- *StutterEnterPlusExitWatermark = (SREnterPlusExitTime + ExtraLatency + 10 / DCFCLKDeepSleep); +- *Z8StutterExitWatermark = SRExitZ8Time + ExtraLatency + 10 / DCFCLKDeepSleep; +- *Z8StutterEnterPlusExitWatermark = SREnterPlusExitZ8Time + ExtraLatency + 10 / DCFCLKDeepSleep; ++ *StutterExitWatermark = v->SRExitTime + ExtraLatency + 10 / DCFCLKDeepSleep; ++ *StutterEnterPlusExitWatermark = (v->SREnterPlusExitTime + ExtraLatency + 10 / DCFCLKDeepSleep); ++ *Z8StutterExitWatermark = v->SRExitZ8Time + ExtraLatency + 10 / DCFCLKDeepSleep; ++ *Z8StutterEnterPlusExitWatermark = v->SREnterPlusExitZ8Time + ExtraLatency + 10 / DCFCLKDeepSleep; + + #ifdef __DML_VBA_DEBUG__ + dml_print("DML::%s: StutterExitWatermark = %f\n", __func__, *StutterExitWatermark); +-- +2.35.3 + diff --git a/patches.suse/drm-amd-display-skip-audio-setup-when-audio-stream-i.patch b/patches.suse/drm-amd-display-skip-audio-setup-when-audio-stream-i.patch new file mode 100644 index 0000000..c0303f1 --- /dev/null +++ b/patches.suse/drm-amd-display-skip-audio-setup-when-audio-stream-i.patch @@ -0,0 +1,54 @@ +From 65fbfb02c2734cacffec5e3f492e1b4f1dabcf98 Mon Sep 17 00:00:00 2001 +From: zhikzhai +Date: Fri, 26 Aug 2022 19:44:50 +0800 +Subject: [PATCH] drm/amd/display: skip audio setup when audio stream is enabled +Git-commit: 65fbfb02c2734cacffec5e3f492e1b4f1dabcf98 +Patch-mainline: v6.0-rc7 +References: git-fixes + +[why] +We have minimal pipe split transition method to avoid pipe +allocation outage.However, this method will invoke audio setup +which cause audio output stuck once pipe reallocate. + +[how] +skip audio setup for pipelines which audio stream has been enabled + +Reviewed-by: Charlene Liu +Acked-by: Wayne Lin +Signed-off-by: zhikzhai +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +index 38a67051d470..aea49334021c 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c ++++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +@@ -2164,7 +2164,8 @@ static void dce110_setup_audio_dto( + continue; + if (pipe_ctx->stream->signal != SIGNAL_TYPE_HDMI_TYPE_A) + continue; +- if (pipe_ctx->stream_res.audio != NULL) { ++ if (pipe_ctx->stream_res.audio != NULL && ++ pipe_ctx->stream_res.audio->enabled == false) { + struct audio_output audio_output; + + build_audio_output(context, pipe_ctx, &audio_output); +@@ -2204,7 +2205,8 @@ static void dce110_setup_audio_dto( + if (!dc_is_dp_signal(pipe_ctx->stream->signal)) + continue; + +- if (pipe_ctx->stream_res.audio != NULL) { ++ if (pipe_ctx->stream_res.audio != NULL && ++ pipe_ctx->stream_res.audio->enabled == false) { + struct audio_output audio_output; + + build_audio_output(context, pipe_ctx, &audio_output); +-- +2.35.3 + diff --git a/patches.suse/drm-amd-display-update-gamut-remap-if-plane-has-chan.patch b/patches.suse/drm-amd-display-update-gamut-remap-if-plane-has-chan.patch new file mode 100644 index 0000000..29dabcc --- /dev/null +++ b/patches.suse/drm-amd-display-update-gamut-remap-if-plane-has-chan.patch @@ -0,0 +1,43 @@ +From 52bb21499cf54fa65b56d97cd0d68579c90207dd Mon Sep 17 00:00:00 2001 +From: Hugo Hu +Date: Thu, 1 Sep 2022 10:08:35 +0800 +Subject: [PATCH] drm/amd/display: update gamut remap if plane has changed +Git-commit: 52bb21499cf54fa65b56d97cd0d68579c90207dd +Patch-mainline: v6.0-rc7 +References: git-fixes + +[Why] +The desktop plane and full-screen game plane may have different +gamut remap coefficients, if switching between desktop and +full-screen game without updating the gamut remap will cause +incorrect color. + +[How] +Update gamut remap if planes change. + +Reviewed-by: Dmytro Laktyushkin +Acked-by: Wayne Lin +Signed-off-by: Hugo Hu +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +index 884fa060f375..598ce872a8d7 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +@@ -1565,6 +1565,7 @@ static void dcn20_update_dchubp_dpp( + /* Any updates are handled in dc interface, just need + * to apply existing for plane enable / opp change */ + if (pipe_ctx->update_flags.bits.enable || pipe_ctx->update_flags.bits.opp_changed ++ || pipe_ctx->update_flags.bits.plane_changed + || pipe_ctx->stream->update_flags.bits.gamut_remap + || pipe_ctx->stream->update_flags.bits.out_csc) { + /* dpp/cm gamut remap*/ +-- +2.35.3 + diff --git a/patches.suse/drm-amd-pm-disable-BACO-entry-exit-completely-on-sev.patch b/patches.suse/drm-amd-pm-disable-BACO-entry-exit-completely-on-sev.patch new file mode 100644 index 0000000..5d3c914 --- /dev/null +++ b/patches.suse/drm-amd-pm-disable-BACO-entry-exit-completely-on-sev.patch @@ -0,0 +1,44 @@ +From 7c6fb61a400bf3218c6504cb2d48858f98822c9d Mon Sep 17 00:00:00 2001 +From: Guchun Chen +Date: Wed, 7 Sep 2022 20:31:36 +0800 +Subject: [PATCH] drm/amd/pm: disable BACO entry/exit completely on several sienna cichlid cards +Git-commit: 7c6fb61a400bf3218c6504cb2d48858f98822c9d +Patch-mainline: v6.0-rc6 +References: git-fixes + +To avoid hardware intermittent failures. + +Signed-off-by: Guchun Chen +Reviewed-by: Lijo Lazar +Signed-off-by: Alex Deucher +Acked-by: Takashi Iwai + +--- + .../gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +index 6db67f082d91..644ea150e075 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +@@ -368,6 +368,17 @@ static void sienna_cichlid_check_bxco_support(struct smu_context *smu) + smu_baco->platform_support = + (val & RCC_BIF_STRAP0__STRAP_PX_CAPABLE_MASK) ? true : + false; ++ ++ /* ++ * Disable BACO entry/exit completely on below SKUs to ++ * avoid hardware intermittent failures. ++ */ ++ if (((adev->pdev->device == 0x73A1) && ++ (adev->pdev->revision == 0x00)) || ++ ((adev->pdev->device == 0x73BF) && ++ (adev->pdev->revision == 0xCF))) ++ smu_baco->platform_support = false; ++ + } + } + +-- +2.35.3 + diff --git a/patches.suse/drm-amd-pm-smu7_hwmgr-fix-potential-off-by-one-overf.patch b/patches.suse/drm-amd-pm-smu7_hwmgr-fix-potential-off-by-one-overf.patch new file mode 100644 index 0000000..2336528 --- /dev/null +++ b/patches.suse/drm-amd-pm-smu7_hwmgr-fix-potential-off-by-one-overf.patch @@ -0,0 +1,41 @@ +From d2bd0831b51d1123fc86c019db3452d6a1ce5029 Mon Sep 17 00:00:00 2001 +From: Alexey Kodanev +Date: Tue, 4 Oct 2022 11:14:02 +0300 +Subject: [PATCH] drm/amd/pm: smu7_hwmgr: fix potential off-by-one overflow in 'performance_levels' +Git-commit: d2bd0831b51d1123fc86c019db3452d6a1ce5029 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Since 'hardwareActivityPerformanceLevels' is set to the size of the +'performance_levels' array in smu7_hwmgr_backend_init(), using the +'<=' assertion to check for the next index value is incorrect. +Replace it with '<'. + +Detected using the static analysis tool - Svace. + +Fixes: 599a7e9fe1b6 ("drm/amd/powerplay: implement smu7 hwmgr to manager asics with smu ip version 7.") +Reviewed-by: Evan Quan +Signed-off-by: Alexey Kodanev +Signed-off-by: Alex Deucher +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +index e4fcbf8a7eb5..7ef7e81525a3 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +@@ -3603,7 +3603,7 @@ static int smu7_get_pp_table_entry_callback_func_v1(struct pp_hwmgr *hwmgr, + return -EINVAL); + + PP_ASSERT_WITH_CODE( +- (smu7_power_state->performance_level_count <= ++ (smu7_power_state->performance_level_count < + hwmgr->platform_descriptor.hardwareActivityPerformanceLevels), + "Performance levels exceeds Driver limit!", + return -EINVAL); +-- +2.35.3 + diff --git a/patches.suse/drm-amdgpu-Check-num_gfx_rings-for-gfx-v9_0-rb-setup.patch b/patches.suse/drm-amdgpu-Check-num_gfx_rings-for-gfx-v9_0-rb-setup.patch new file mode 100644 index 0000000..5194ea5 --- /dev/null +++ b/patches.suse/drm-amdgpu-Check-num_gfx_rings-for-gfx-v9_0-rb-setup.patch @@ -0,0 +1,36 @@ +From c351938350ab9b5e978dede2c321da43de7eb70c Mon Sep 17 00:00:00 2001 +From: Candice Li +Date: Thu, 18 Aug 2022 10:47:09 +0800 +Subject: [PATCH] drm/amdgpu: Check num_gfx_rings for gfx v9_0 rb setup. +Git-commit: c351938350ab9b5e978dede2c321da43de7eb70c +Patch-mainline: v6.0-rc3 +References: git-fixes + +No need to set up rb when no gfx rings. + +Signed-off-by: Candice Li +Reviewed-by: Hawking Zhang +Signed-off-by: Alex Deucher +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +index c6e0f9313a7f..fc9c1043244c 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +@@ -2587,7 +2587,8 @@ static void gfx_v9_0_constants_init(struct amdgpu_device *adev) + + gfx_v9_0_tiling_mode_table_init(adev); + +- gfx_v9_0_setup_rb(adev); ++ if (adev->gfx.num_gfx_rings) ++ gfx_v9_0_setup_rb(adev); + gfx_v9_0_get_cu_info(adev, &adev->gfx.cu_info); + adev->gfx.config.db_debug2 = RREG32_SOC15(GC, 0, mmDB_DEBUG2); + +-- +2.35.3 + diff --git a/patches.suse/drm-amdgpu-Move-psp_xgmi_terminate-call-from-amdgpu_.patch b/patches.suse/drm-amdgpu-Move-psp_xgmi_terminate-call-from-amdgpu_.patch new file mode 100644 index 0000000..6a07ce6 --- /dev/null +++ b/patches.suse/drm-amdgpu-Move-psp_xgmi_terminate-call-from-amdgpu_.patch @@ -0,0 +1,52 @@ +From 9d705d7741ae70764f3d6d87e67fad3b5c30ffd0 Mon Sep 17 00:00:00 2001 +From: YiPeng Chai +Date: Fri, 12 Aug 2022 13:38:34 +0800 +Subject: [PATCH] drm/amdgpu: Move psp_xgmi_terminate call from amdgpu_xgmi_remove_device to psp_hw_fini +Git-commit: 9d705d7741ae70764f3d6d87e67fad3b5c30ffd0 +Patch-mainline: v6.0-rc3 +References: git-fixes + +V1: +The amdgpu_xgmi_remove_device function will send unload command +to psp through psp ring to terminate xgmi, but psp ring has been +destroyed in psp_hw_fini. + +V2: +1. Change the commit title. +2. Restore amdgpu_xgmi_remove_device to its original calling location. + Move psp_xgmi_terminate call from amdgpu_xgmi_remove_device to + psp_hw_fini. + +Signed-off-by: YiPeng Chai +Reviewed-by: Hawking Zhang +Signed-off-by: Alex Deucher +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 3 +++ + drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c | 2 +- + 2 files changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +@@ -2625,6 +2625,9 @@ static int psp_hw_fini(void *handle) + psp_rap_terminate(psp); + psp_dtm_terminate(psp); + psp_hdcp_terminate(psp); ++ ++ if (adev->gmc.xgmi.num_physical_nodes > 1) ++ psp_xgmi_terminate(psp); + } + + psp_asd_unload(psp); +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c +@@ -626,7 +626,7 @@ int amdgpu_xgmi_remove_device(struct amd + amdgpu_put_xgmi_hive(hive); + } + +- return psp_xgmi_terminate(&adev->psp); ++ return 0; + } + + static int amdgpu_xgmi_ras_late_init(struct amdgpu_device *adev) diff --git a/patches.suse/drm-amdgpu-Separate-vf2pf-work-item-init-from-virt-d.patch b/patches.suse/drm-amdgpu-Separate-vf2pf-work-item-init-from-virt-d.patch new file mode 100644 index 0000000..e7f47f2 --- /dev/null +++ b/patches.suse/drm-amdgpu-Separate-vf2pf-work-item-init-from-virt-d.patch @@ -0,0 +1,134 @@ +From 892deb48269c65376f3eeb5b4c032ff2c2979bd7 Mon Sep 17 00:00:00 2001 +From: Victor Skvortsov +Date: Thu, 16 Dec 2021 17:01:45 +0000 +Subject: [PATCH] drm/amdgpu: Separate vf2pf work item init from virt data exchange +Git-commit: 892deb48269c65376f3eeb5b4c032ff2c2979bd7 +Patch-mainline: v5.17-rc1 +References: git-fixes + +We want to be able to call virt data exchange conditionally +after gmc sw init to reserve bad pages as early as possible. +Since this is a conditional call, we will need +to call it again unconditionally later in the init sequence. + +Refactor the data exchange function so it can be +called multiple times without re-initializing the work item. + +V2: Cleaned up the code. Kept the original call to init_exchange_data() +inside early init to initialize the work item, afterwards call +exchange_data() when needed. + +Signed-off-by: Victor Skvortsov +Reviewed By: Shaoyun.liu + +Signed-off-by: Alex Deucher +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 6 +++- + drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 36 ++++++++++++++-------- + drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h | 1 + + 3 files changed, 30 insertions(+), 13 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +index bd4232691697..0cd2404ca63c 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +@@ -2317,6 +2317,10 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev) + + /* need to do gmc hw init early so we can allocate gpu mem */ + if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC) { ++ /* Try to reserve bad pages early */ ++ if (amdgpu_sriov_vf(adev)) ++ amdgpu_virt_exchange_data(adev); ++ + r = amdgpu_device_vram_scratch_init(adev); + if (r) { + DRM_ERROR("amdgpu_vram_scratch_init failed %d\n", r); +@@ -2348,7 +2352,7 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev) + } + + if (amdgpu_sriov_vf(adev)) +- amdgpu_virt_init_data_exchange(adev); ++ amdgpu_virt_exchange_data(adev); + + r = amdgpu_ib_pool_init(adev); + if (r) { +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +index 3fc49823f527..f8e574cc0e22 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +@@ -622,17 +622,35 @@ void amdgpu_virt_fini_data_exchange(struct amdgpu_device *adev) + + void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev) + { +- uint64_t bp_block_offset = 0; +- uint32_t bp_block_size = 0; +- struct amd_sriov_msg_pf2vf_info *pf2vf_v2 = NULL; +- + adev->virt.fw_reserve.p_pf2vf = NULL; + adev->virt.fw_reserve.p_vf2pf = NULL; + adev->virt.vf2pf_update_interval_ms = 0; + +- if (adev->mman.fw_vram_usage_va != NULL) { ++ if (adev->bios != NULL) { + adev->virt.vf2pf_update_interval_ms = 2000; + ++ adev->virt.fw_reserve.p_pf2vf = ++ (struct amd_sriov_msg_pf2vf_info_header *) ++ (adev->bios + (AMD_SRIOV_MSG_PF2VF_OFFSET_KB << 10)); ++ ++ amdgpu_virt_read_pf2vf_data(adev); ++ } ++ ++ if (adev->virt.vf2pf_update_interval_ms != 0) { ++ INIT_DELAYED_WORK(&adev->virt.vf2pf_work, amdgpu_virt_update_vf2pf_work_item); ++ schedule_delayed_work(&(adev->virt.vf2pf_work), msecs_to_jiffies(adev->virt.vf2pf_update_interval_ms)); ++ } ++} ++ ++ ++void amdgpu_virt_exchange_data(struct amdgpu_device *adev) ++{ ++ uint64_t bp_block_offset = 0; ++ uint32_t bp_block_size = 0; ++ struct amd_sriov_msg_pf2vf_info *pf2vf_v2 = NULL; ++ ++ if (adev->mman.fw_vram_usage_va != NULL) { ++ + adev->virt.fw_reserve.p_pf2vf = + (struct amd_sriov_msg_pf2vf_info_header *) + (adev->mman.fw_vram_usage_va + (AMD_SRIOV_MSG_PF2VF_OFFSET_KB << 10)); +@@ -663,16 +681,10 @@ void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev) + (adev->bios + (AMD_SRIOV_MSG_PF2VF_OFFSET_KB << 10)); + + amdgpu_virt_read_pf2vf_data(adev); +- +- return; +- } +- +- if (adev->virt.vf2pf_update_interval_ms != 0) { +- INIT_DELAYED_WORK(&adev->virt.vf2pf_work, amdgpu_virt_update_vf2pf_work_item); +- schedule_delayed_work(&(adev->virt.vf2pf_work), adev->virt.vf2pf_update_interval_ms); + } + } + ++ + void amdgpu_detect_virtualization(struct amdgpu_device *adev) + { + uint32_t reg; +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h +index 8d4c20bb71c5..9adfb8d63280 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h +@@ -308,6 +308,7 @@ int amdgpu_virt_alloc_mm_table(struct amdgpu_device *adev); + void amdgpu_virt_free_mm_table(struct amdgpu_device *adev); + void amdgpu_virt_release_ras_err_handler_data(struct amdgpu_device *adev); + void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev); ++void amdgpu_virt_exchange_data(struct amdgpu_device *adev); + void amdgpu_virt_fini_data_exchange(struct amdgpu_device *adev); + void amdgpu_detect_virtualization(struct amdgpu_device *adev); + +-- +2.35.3 + diff --git a/patches.suse/drm-amdgpu-add-missing-pci_disable_device-in-amdgpu_.patch b/patches.suse/drm-amdgpu-add-missing-pci_disable_device-in-amdgpu_.patch new file mode 100644 index 0000000..6f58d4e --- /dev/null +++ b/patches.suse/drm-amdgpu-add-missing-pci_disable_device-in-amdgpu_.patch @@ -0,0 +1,39 @@ +From 6b11af6d1c8f5d4135332bb932baaa06e511173d Mon Sep 17 00:00:00 2001 +From: Yang Yingliang +Date: Fri, 26 Aug 2022 16:57:54 +0800 +Subject: [PATCH] drm/amdgpu: add missing pci_disable_device() in amdgpu_pmops_runtime_resume() +Git-commit: 6b11af6d1c8f5d4135332bb932baaa06e511173d +Patch-mainline: v6.1-rc1 +References: git-fixes + +Add missing pci_disable_device() if amdgpu_device_resume() fails. + +Fixes: 8e4d5d43cc6c ("drm/amdgpu: Handling of amdgpu_device_resume return value for graceful teardown") +Signed-off-by: Yang Yingliang +Signed-off-by: Alex Deucher +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +index 429fcdf28836..de7144b06e93 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +@@ -2563,8 +2563,11 @@ static int amdgpu_pmops_runtime_resume(struct device *dev) + amdgpu_device_baco_exit(drm_dev); + } + ret = amdgpu_device_resume(drm_dev, false); +- if (ret) ++ if (ret) { ++ if (amdgpu_device_supports_px(drm_dev)) ++ pci_disable_device(pdev); + return ret; ++ } + + if (amdgpu_device_supports_px(drm_dev)) + drm_dev->switch_power_state = DRM_SWITCH_POWER_ON; +-- +2.35.3 + diff --git a/patches.suse/drm-amdgpu-display-change-pipe-policy-for-DCN-2.0.patch b/patches.suse/drm-amdgpu-display-change-pipe-policy-for-DCN-2.0.patch new file mode 100644 index 0000000..f0a872c --- /dev/null +++ b/patches.suse/drm-amdgpu-display-change-pipe-policy-for-DCN-2.0.patch @@ -0,0 +1,40 @@ +From bcfab8e35ce81e2fd3230c1575024bfde0d28c8b Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Thu, 3 Feb 2022 10:04:58 -0500 +Subject: [PATCH] drm/amdgpu/display: change pipe policy for DCN 2.0 +Git-commit: bcfab8e35ce81e2fd3230c1575024bfde0d28c8b +Alt-commit: 6e7545ddb13416fd200e0b91c0acfd0404e2e27b +Patch-mainline: v5.18-rc1 +References: git-fixes + +Fixes hangs on driver load with multiple displays on +DCN 2.0 parts. + +Bug: https://bugzilla.kernel.org/show_bug.cgi?id=215511 +Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1877 +Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1886 +Fixes: ee2698cf79cc ("drm/amd/display: Changed pipe split policy to allow for multi-display pipe split") +Reviewed-by: Harry Wentland +Signed-off-by: Alex Deucher +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +index b55868a0e0df..dfe2e1c25a26 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +@@ -1069,7 +1069,7 @@ static const struct dc_debug_options debug_defaults_drv = { + .timing_trace = false, + .clock_trace = true, + .disable_pplib_clock_request = true, +- .pipe_split_policy = MPC_SPLIT_DYNAMIC, ++ .pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP, + .force_single_disp_pipe_split = false, + .disable_dcc = DCC_ENABLE, + .vsr_support = true, +-- +2.35.3 + diff --git a/patches.suse/drm-amdgpu-display-change-pipe-policy-for-DCN-2.1.patch b/patches.suse/drm-amdgpu-display-change-pipe-policy-for-DCN-2.1.patch new file mode 100644 index 0000000..7cb566a --- /dev/null +++ b/patches.suse/drm-amdgpu-display-change-pipe-policy-for-DCN-2.1.patch @@ -0,0 +1,38 @@ +From 879791ad8bf3dc5453061cad74776a617b6e3319 Mon Sep 17 00:00:00 2001 +From: Benjamin Marty +Date: Wed, 23 Mar 2022 22:08:26 +0100 +Subject: [PATCH] drm/amdgpu/display: change pipe policy for DCN 2.1 +Git-commit: 879791ad8bf3dc5453061cad74776a617b6e3319 +Alt-commit: fa458eb10dc7218146a84e6d2e072424e64d188a +Patch-mainline: v5.18-rc2 +References: git-fixes + +Fixes crash on MST Hub disconnect. + +Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1849 +Fixes: ee2698cf79cc ("drm/amd/display: Changed pipe split policy to allow for multi-display pipe split") +Signed-off-by: Benjamin Marty +Signed-off-by: Alex Deucher +Cc: stable@vger.kernel.org +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +index 612732656772..3fe4bfbb98a0 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +@@ -644,7 +644,7 @@ static const struct dc_debug_options debug_defaults_drv = { + .clock_trace = true, + .disable_pplib_clock_request = true, + .min_disp_clk_khz = 100000, +- .pipe_split_policy = MPC_SPLIT_DYNAMIC, ++ .pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP, + .force_single_disp_pipe_split = false, + .disable_dcc = DCC_ENABLE, + .vsr_support = true, +-- +2.35.3 + diff --git a/patches.suse/drm-amdgpu-don-t-register-a-dirty-callback-for-non-a.patch b/patches.suse/drm-amdgpu-don-t-register-a-dirty-callback-for-non-a.patch new file mode 100644 index 0000000..17832fa --- /dev/null +++ b/patches.suse/drm-amdgpu-don-t-register-a-dirty-callback-for-non-a.patch @@ -0,0 +1,59 @@ +From abbc7a3dafb91b9d4ec56b70ec9a7520f8e13334 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Mon, 19 Sep 2022 12:26:20 -0400 +Subject: [PATCH] drm/amdgpu: don't register a dirty callback for non-atomic +Git-commit: abbc7a3dafb91b9d4ec56b70ec9a7520f8e13334 +Patch-mainline: v6.0-rc7 +References: git-fixes + +Some asics still support non-atomic code paths. + +Fixes: 66f99628eb2440 ("drm/amdgpu: use dirty framebuffer helper") +Reported-by: Arthur Marsh +Reviewed-by: Hamza Mahfooz +Signed-off-by: Alex Deucher +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +index 5b09c8f4fe95..23998f727c7f 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +@@ -39,6 +39,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -497,6 +498,11 @@ bool amdgpu_display_ddc_probe(struct amdgpu_connector *amdgpu_connector, + static const struct drm_framebuffer_funcs amdgpu_fb_funcs = { + .destroy = drm_gem_fb_destroy, + .create_handle = drm_gem_fb_create_handle, ++}; ++ ++static const struct drm_framebuffer_funcs amdgpu_fb_funcs_atomic = { ++ .destroy = drm_gem_fb_destroy, ++ .create_handle = drm_gem_fb_create_handle, + .dirty = drm_atomic_helper_dirtyfb, + }; + +@@ -1102,7 +1108,10 @@ static int amdgpu_display_gem_fb_verify_and_init(struct drm_device *dev, + if (ret) + goto err; + +- ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs); ++ if (drm_drv_uses_atomic_modeset(dev)) ++ ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs_atomic); ++ else ++ ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs); + if (ret) + goto err; + +-- +2.35.3 + diff --git a/patches.suse/drm-amdgpu-make-sure-to-init-common-IP-before-gmc.patch b/patches.suse/drm-amdgpu-make-sure-to-init-common-IP-before-gmc.patch new file mode 100644 index 0000000..85fe1c2 --- /dev/null +++ b/patches.suse/drm-amdgpu-make-sure-to-init-common-IP-before-gmc.patch @@ -0,0 +1,73 @@ +From a8671493d2074950553da3cf07d1be43185ef6c6 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Tue, 30 Aug 2022 10:59:49 -0400 +Subject: [PATCH] drm/amdgpu: make sure to init common IP before gmc +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: a8671493d2074950553da3cf07d1be43185ef6c6 +Patch-mainline: v6.0-rc6 +References: git-fixes + +Move common IP init before GMC init so that HDP gets +remapped before GMC init which uses it. + +This fixes the Unsupported Request error reported through +AER during driver load. The error happens as a write happens +to the remap offset before real remapping is done. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=216373 + +The error was unnoticed before and got visible because of the commit +referenced below. This doesn't fix anything in the commit below, rather +fixes the issue in amdgpu exposed by the commit. The reference is only +to associate this commit with below one so that both go together. + +Fixes: 8795e182b02d ("PCI/portdrv: Don't disable AER reporting in get_port_device_capability()") + +Acked-by: Christian König +Reviewed-by: Lijo Lazar +Signed-off-by: Alex Deucher +Cc: stable@vger.kernel.org +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +index 1400abee9f40..be7aff2d4a57 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +@@ -2365,8 +2365,16 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev) + } + adev->ip_blocks[i].status.sw = true; + +- /* need to do gmc hw init early so we can allocate gpu mem */ +- if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC) { ++ if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_COMMON) { ++ /* need to do common hw init early so everything is set up for gmc */ ++ r = adev->ip_blocks[i].version->funcs->hw_init((void *)adev); ++ if (r) { ++ DRM_ERROR("hw_init %d failed %d\n", i, r); ++ goto init_failed; ++ } ++ adev->ip_blocks[i].status.hw = true; ++ } else if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC) { ++ /* need to do gmc hw init early so we can allocate gpu mem */ + /* Try to reserve bad pages early */ + if (amdgpu_sriov_vf(adev)) + amdgpu_virt_exchange_data(adev); +@@ -3052,8 +3060,8 @@ static int amdgpu_device_ip_reinit_early_sriov(struct amdgpu_device *adev) + int i, r; + + static enum amd_ip_block_type ip_order[] = { +- AMD_IP_BLOCK_TYPE_GMC, + AMD_IP_BLOCK_TYPE_COMMON, ++ AMD_IP_BLOCK_TYPE_GMC, + AMD_IP_BLOCK_TYPE_PSP, + AMD_IP_BLOCK_TYPE_IH, + }; +-- +2.35.3 + diff --git a/patches.suse/drm-amdgpu-mmVM_L2_CNTL3-register-not-initialized-co.patch b/patches.suse/drm-amdgpu-mmVM_L2_CNTL3-register-not-initialized-co.patch new file mode 100644 index 0000000..5cfea26 --- /dev/null +++ b/patches.suse/drm-amdgpu-mmVM_L2_CNTL3-register-not-initialized-co.patch @@ -0,0 +1,33 @@ +From b8983d42524f10ac6bf35bbce6a7cc8e45f61e04 Mon Sep 17 00:00:00 2001 +From: Qu Huang +Date: Tue, 23 Aug 2022 14:44:06 +0800 +Subject: [PATCH] drm/amdgpu: mmVM_L2_CNTL3 register not initialized correctly +Git-commit: b8983d42524f10ac6bf35bbce6a7cc8e45f61e04 +Patch-mainline: v6.0-rc3 +References: git-fixes + +The mmVM_L2_CNTL3 register is not assigned an initial value + +Signed-off-by: Qu Huang +Signed-off-by: Alex Deucher +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c +index 3f44a099c52a..3e51e773f92b 100644 +--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c +@@ -176,6 +176,7 @@ static void mmhub_v1_0_init_cache_regs(struct amdgpu_device *adev) + tmp = REG_SET_FIELD(tmp, VM_L2_CNTL2, INVALIDATE_L2_CACHE, 1); + WREG32_SOC15(MMHUB, 0, mmVM_L2_CNTL2, tmp); + ++ tmp = mmVM_L2_CNTL3_DEFAULT; + if (adev->gmc.translate_further) { + tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, BANK_SELECT, 12); + tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, +-- +2.35.3 + diff --git a/patches.suse/drm-amdgpu-move-nbio-ih_doorbell_range-into-ih-code-.patch b/patches.suse/drm-amdgpu-move-nbio-ih_doorbell_range-into-ih-code-.patch new file mode 100644 index 0000000..7d85b98 --- /dev/null +++ b/patches.suse/drm-amdgpu-move-nbio-ih_doorbell_range-into-ih-code-.patch @@ -0,0 +1,90 @@ +From dc1d85cb790f2091eea074cee24a704b2d6c4a06 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Fri, 9 Sep 2022 11:47:20 -0400 +Subject: [PATCH] drm/amdgpu: move nbio ih_doorbell_range() into ih code for vega +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: dc1d85cb790f2091eea074cee24a704b2d6c4a06 +Patch-mainline: v6.0-rc6 +References: git-fixes + +This mirrors what we do for other asics and this way we are +sure the ih doorbell range is properly initialized. + +There is a comment about the way doorbells on gfx9 work that +requires that they are initialized for other IPs before GFX +is initialized. In this case IH is initialized before GFX, +so there should be no issue. + +This is a prerequisite for fixing the Unsupported Request error +reported through AER during driver load. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=216373 + +The error was unnoticed before and got visible because of the commit +referenced below. This doesn't fix anything in the commit below, rather +fixes the issue in amdgpu exposed by the commit. The reference is only +to associate this commit with below one so that both go together. + +Fixes: 8795e182b02d ("PCI/portdrv: Don't disable AER reporting in get_port_device_capability()") + +Acked-by: Christian König +Reviewed-by: Lijo Lazar +Signed-off-by: Alex Deucher +Cc: stable@vger.kernel.org +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/amd/amdgpu/soc15.c | 3 --- + drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 4 ++++ + drivers/gpu/drm/amd/amdgpu/vega20_ih.c | 4 ++++ + 3 files changed, 8 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c +index fde6154f2009..7324e304288e 100644 +--- a/drivers/gpu/drm/amd/amdgpu/soc15.c ++++ b/drivers/gpu/drm/amd/amdgpu/soc15.c +@@ -1224,9 +1224,6 @@ static void soc15_doorbell_range_init(struct amdgpu_device *adev) + ring->use_doorbell, ring->doorbell_index, + adev->doorbell_index.sdma_doorbell_range); + } +- +- adev->nbio.funcs->ih_doorbell_range(adev, adev->irq.ih.use_doorbell, +- adev->irq.ih.doorbell_index); + } + } + +diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c +index 03b7066471f9..1e83db0c5438 100644 +--- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c ++++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c +@@ -289,6 +289,10 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev) + } + } + ++ if (!amdgpu_sriov_vf(adev)) ++ adev->nbio.funcs->ih_doorbell_range(adev, adev->irq.ih.use_doorbell, ++ adev->irq.ih.doorbell_index); ++ + pci_set_master(adev->pdev); + + /* enable interrupts */ +diff --git a/drivers/gpu/drm/amd/amdgpu/vega20_ih.c b/drivers/gpu/drm/amd/amdgpu/vega20_ih.c +index 2022ffbb8dba..59dfca093155 100644 +--- a/drivers/gpu/drm/amd/amdgpu/vega20_ih.c ++++ b/drivers/gpu/drm/amd/amdgpu/vega20_ih.c +@@ -340,6 +340,10 @@ static int vega20_ih_irq_init(struct amdgpu_device *adev) + } + } + ++ if (!amdgpu_sriov_vf(adev)) ++ adev->nbio.funcs->ih_doorbell_range(adev, adev->irq.ih.use_doorbell, ++ adev->irq.ih.doorbell_index); ++ + pci_set_master(adev->pdev); + + /* enable interrupts */ +-- +2.35.3 + diff --git a/patches.suse/drm-amdgpu-move-nbio-sdma_doorbell_range-into-sdma-c.patch b/patches.suse/drm-amdgpu-move-nbio-sdma_doorbell_range-into-sdma-c.patch new file mode 100644 index 0000000..3ea1f2c --- /dev/null +++ b/patches.suse/drm-amdgpu-move-nbio-sdma_doorbell_range-into-sdma-c.patch @@ -0,0 +1,103 @@ +From e3163bc8ffdfdb405e10530b140135b2ee487f89 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Fri, 9 Sep 2022 11:53:27 -0400 +Subject: [PATCH] drm/amdgpu: move nbio sdma_doorbell_range() into sdma code for vega +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: e3163bc8ffdfdb405e10530b140135b2ee487f89 +Patch-mainline: v6.0-rc6 +References: git-fixes + +This mirrors what we do for other asics and this way we are +sure the sdma doorbell range is properly initialized. + +There is a comment about the way doorbells on gfx9 work that +requires that they are initialized for other IPs before GFX +is initialized. However, the statement says that it applies to +multimedia as well, but the VCN code currently initializes +doorbells after GFX and there are no known issues there. In my +testing at least I don't see any problems on SDMA. + +This is a prerequisite for fixing the Unsupported Request error +reported through AER during driver load. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=216373 + +The error was unnoticed before and got visible because of the commit +referenced below. This doesn't fix anything in the commit below, rather +fixes the issue in amdgpu exposed by the commit. The reference is only +to associate this commit with below one so that both go together. + +Fixes: 8795e182b02d ("PCI/portdrv: Don't disable AER reporting in get_port_device_capability()") + +Acked-by: Christian König +Reviewed-by: Lijo Lazar +Signed-off-by: Alex Deucher +Cc: stable@vger.kernel.org +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | 5 +++++ + drivers/gpu/drm/amd/amdgpu/soc15.c | 22 ---------------------- + 2 files changed, 5 insertions(+), 22 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +index 65181efba50e..56424f75dd2c 100644 +--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +@@ -1504,6 +1504,11 @@ static int sdma_v4_0_start(struct amdgpu_device *adev) + WREG32_SDMA(i, mmSDMA0_CNTL, temp); + + if (!amdgpu_sriov_vf(adev)) { ++ ring = &adev->sdma.instance[i].ring; ++ adev->nbio.funcs->sdma_doorbell_range(adev, i, ++ ring->use_doorbell, ring->doorbell_index, ++ adev->doorbell_index.sdma_doorbell_range); ++ + /* unhalt engine */ + temp = RREG32_SDMA(i, mmSDMA0_F32_CNTL); + temp = REG_SET_FIELD(temp, SDMA0_F32_CNTL, HALT, 0); +diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c +index 7324e304288e..183024d7c184 100644 +--- a/drivers/gpu/drm/amd/amdgpu/soc15.c ++++ b/drivers/gpu/drm/amd/amdgpu/soc15.c +@@ -1211,22 +1211,6 @@ static int soc15_common_sw_fini(void *handle) + return 0; + } + +-static void soc15_doorbell_range_init(struct amdgpu_device *adev) +-{ +- int i; +- struct amdgpu_ring *ring; +- +- /* sdma/ih doorbell range are programed by hypervisor */ +- if (!amdgpu_sriov_vf(adev)) { +- for (i = 0; i < adev->sdma.num_instances; i++) { +- ring = &adev->sdma.instance[i].ring; +- adev->nbio.funcs->sdma_doorbell_range(adev, i, +- ring->use_doorbell, ring->doorbell_index, +- adev->doorbell_index.sdma_doorbell_range); +- } +- } +-} +- + static int soc15_common_hw_init(void *handle) + { + struct amdgpu_device *adev = (struct amdgpu_device *)handle; +@@ -1246,12 +1230,6 @@ static int soc15_common_hw_init(void *handle) + + /* enable the doorbell aperture */ + soc15_enable_doorbell_aperture(adev, true); +- /* HW doorbell routing policy: doorbell writing not +- * in SDMA/IH/MM/ACV range will be routed to CP. So +- * we need to init SDMA/IH/MM/ACV doorbell range prior +- * to CP ip block init and ring test. +- */ +- soc15_doorbell_range_init(adev); + + return 0; + } +-- +2.35.3 + diff --git a/patches.suse/drm-amdgpu-use-dirty-framebuffer-helper.patch b/patches.suse/drm-amdgpu-use-dirty-framebuffer-helper.patch new file mode 100644 index 0000000..eb1ce1f --- /dev/null +++ b/patches.suse/drm-amdgpu-use-dirty-framebuffer-helper.patch @@ -0,0 +1,44 @@ +From 66f99628eb24409cb8feb5061f78283c8b65f820 Mon Sep 17 00:00:00 2001 +From: Hamza Mahfooz +Date: Tue, 6 Sep 2022 15:01:49 -0400 +Subject: [PATCH] drm/amdgpu: use dirty framebuffer helper +Git-commit: 66f99628eb24409cb8feb5061f78283c8b65f820 +Patch-mainline: v6.0-rc6 +References: git-fixes + +Currently, we aren't handling DRM_IOCTL_MODE_DIRTYFB. So, use +drm_atomic_helper_dirtyfb() as the dirty callback in the amdgpu_fb_funcs +struct. + +Signed-off-by: Hamza Mahfooz +Acked-by: Alex Deucher +Signed-off-by: Alex Deucher +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +index c20922a5af9f..5b09c8f4fe95 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +@@ -38,6 +38,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -496,6 +497,7 @@ bool amdgpu_display_ddc_probe(struct amdgpu_connector *amdgpu_connector, + static const struct drm_framebuffer_funcs amdgpu_fb_funcs = { + .destroy = drm_gem_fb_destroy, + .create_handle = drm_gem_fb_create_handle, ++ .dirty = drm_atomic_helper_dirtyfb, + }; + + uint32_t amdgpu_display_supported_domains(struct amdgpu_device *adev, +-- +2.35.3 + diff --git a/patches.suse/drm-bridge-Avoid-uninitialized-variable-warning.patch b/patches.suse/drm-bridge-Avoid-uninitialized-variable-warning.patch new file mode 100644 index 0000000..8972d02 --- /dev/null +++ b/patches.suse/drm-bridge-Avoid-uninitialized-variable-warning.patch @@ -0,0 +1,49 @@ +From 7d1202738efda60155d98b370b3c70d336be0eea Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Mon, 4 Jul 2022 13:55:40 +0300 +Subject: [PATCH] drm/bridge: Avoid uninitialized variable warning +Git-commit: 7d1202738efda60155d98b370b3c70d336be0eea +Patch-mainline: v6.1-rc1 +References: git-fixes + +This code works, but technically it uses "num_in_bus_fmts" before it +has been initialized so it leads to static checker warnings and probably +KMEMsan warnings at run time. Initialize the variable to zero to +silence the warning. + +Fixes: f32df58acc68 ("drm/bridge: Add the necessary bits to support bus format negotiation") +Signed-off-by: Dan Carpenter +Signed-off-by: Maxime Ripard +Link: https://patchwork.freedesktop.org/patch/msgid/YrrIs3hoGcPVmXc5@kili +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/drm_bridge.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c +index 6abf7a2407e9..1545c50fd1c8 100644 +--- a/drivers/gpu/drm/drm_bridge.c ++++ b/drivers/gpu/drm/drm_bridge.c +@@ -847,8 +847,8 @@ static int select_bus_fmt_recursive(struct drm_bridge *first_bridge, + struct drm_connector_state *conn_state, + u32 out_bus_fmt) + { ++ unsigned int i, num_in_bus_fmts = 0; + struct drm_bridge_state *cur_state; +- unsigned int num_in_bus_fmts, i; + struct drm_bridge *prev_bridge; + u32 *in_bus_fmts; + int ret; +@@ -969,7 +969,7 @@ drm_atomic_bridge_chain_select_bus_fmts(struct drm_bridge *bridge, + struct drm_connector *conn = conn_state->connector; + struct drm_encoder *encoder = bridge->encoder; + struct drm_bridge_state *last_bridge_state; +- unsigned int i, num_out_bus_fmts; ++ unsigned int i, num_out_bus_fmts = 0; + struct drm_bridge *last_bridge; + u32 *out_bus_fmts; + int ret = 0; +-- +2.35.3 + diff --git a/patches.suse/drm-bridge-adv7511-fix-CEC-power-down-control-regist.patch b/patches.suse/drm-bridge-adv7511-fix-CEC-power-down-control-regist.patch new file mode 100644 index 0000000..91328f6 --- /dev/null +++ b/patches.suse/drm-bridge-adv7511-fix-CEC-power-down-control-regist.patch @@ -0,0 +1,69 @@ +From 1d22b6033ea113a4c3850dfa2c0770885c81aec8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Alvin=20=C5=A0ipraga?= +Date: Sun, 12 Jun 2022 16:48:53 +0200 +Subject: [PATCH] drm: bridge: adv7511: fix CEC power down control register offset +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 1d22b6033ea113a4c3850dfa2c0770885c81aec8 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The ADV7511_REG_CEC_CTRL = 0xE2 register is part of the main register +map - not the CEC register map. As such, we shouldn't apply an offset to +the register address. Doing so will cause us to address a bogus register +for chips with a CEC register map offset (e.g. ADV7533). + +Fixes: 3b1b975003e4 ("drm: adv7511/33: add HDMI CEC support") +Signed-off-by: Alvin Šipraga +Reviewed-by: Robert Foss +Signed-off-by: Robert Foss +Link: https://patchwork.freedesktop.org/patch/msgid/20220612144854.2223873-2-alvin@pqrs.dk +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/bridge/adv7511/adv7511.h | 5 +---- + drivers/gpu/drm/bridge/adv7511/adv7511_cec.c | 4 ++-- + 2 files changed, 3 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h +index a031a0cd1f18..94de73cbeb2d 100644 +--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h ++++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h +@@ -394,10 +394,7 @@ void adv7511_cec_irq_process(struct adv7511 *adv7511, unsigned int irq1); + #else + static inline int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511) + { +- unsigned int offset = adv7511->type == ADV7533 ? +- ADV7533_REG_CEC_OFFSET : 0; +- +- regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset, ++ regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL, + ADV7511_CEC_CTRL_POWER_DOWN); + return 0; + } +diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c +index 0b266f28f150..99964f5a5457 100644 +--- a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c ++++ b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c +@@ -359,7 +359,7 @@ int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511) + goto err_cec_alloc; + } + +- regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset, 0); ++ regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL, 0); + /* cec soft reset */ + regmap_write(adv7511->regmap_cec, + ADV7511_REG_CEC_SOFT_RESET + offset, 0x01); +@@ -386,7 +386,7 @@ int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511) + dev_info(dev, "Initializing CEC failed with error %d, disabling CEC\n", + ret); + err_cec_parse_dt: +- regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset, ++ regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL, + ADV7511_CEC_CTRL_POWER_DOWN); + return ret == -EPROBE_DEFER ? ret : 0; + } +-- +2.35.3 + diff --git a/patches.suse/drm-bridge-display-connector-implement-bus-fmts-call.patch b/patches.suse/drm-bridge-display-connector-implement-bus-fmts-call.patch new file mode 100644 index 0000000..450882a --- /dev/null +++ b/patches.suse/drm-bridge-display-connector-implement-bus-fmts-call.patch @@ -0,0 +1,141 @@ +From 7cd70656d1285b79c001f041a017fcfee4292ff9 Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Wed, 20 Oct 2021 14:39:42 +0200 +Subject: [PATCH] drm/bridge: display-connector: implement bus fmts callbacks +Git-commit: 7cd70656d1285b79c001f041a017fcfee4292ff9 +Patch-mainline: v5.17-rc1 +References: git-fixes + +Since this bridge is tied to the connector, it acts like a passthrough, +so concerning the output & input bus formats, either pass the bus formats from the +previous bridge or return fallback data like done in the bridge function: +drm_atomic_bridge_chain_select_bus_fmts() & select_bus_fmt_recursive. + +This permits avoiding skipping the negociation if the remaining bridge chain has +all the bits in place. + +Without this bus fmt negociation breaks on drm/meson HDMI pipeline when attaching +dw-hdmi with DRM_BRIDGE_ATTACH_NO_CONNECTOR, because the last bridge of the +display-connector doesn't implement buf fmt callbacks and MEDIA_BUS_FMT_FIXED +is used leading to select an unsupported default bus format from dw-hdmi. + +Signed-off-by: Neil Armstrong +Reviewed-by: Sam Ravnborg +Link: https://patchwork.freedesktop.org/patch/msgid/20211020123947.2585572-2-narmstrong@baylibre.com +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/bridge/display-connector.c | 86 ++++++++++++++++++++++ + 1 file changed, 86 insertions(+) + +diff --git a/drivers/gpu/drm/bridge/display-connector.c b/drivers/gpu/drm/bridge/display-connector.c +index 847a0dce7f1d..d24f5b90feab 100644 +--- a/drivers/gpu/drm/bridge/display-connector.c ++++ b/drivers/gpu/drm/bridge/display-connector.c +@@ -13,6 +13,7 @@ + #include + #include + ++#include + #include + #include + +@@ -87,10 +88,95 @@ static struct edid *display_connector_get_edid(struct drm_bridge *bridge, + return drm_get_edid(connector, conn->bridge.ddc); + } + ++/* ++ * Since this bridge is tied to the connector, it acts like a passthrough, ++ * so concerning the output bus formats, either pass the bus formats from the ++ * previous bridge or return fallback data like done in the bridge function: ++ * drm_atomic_bridge_chain_select_bus_fmts(). ++ * This supports negotiation if the bridge chain has all bits in place. ++ */ ++static u32 *display_connector_get_output_bus_fmts(struct drm_bridge *bridge, ++ struct drm_bridge_state *bridge_state, ++ struct drm_crtc_state *crtc_state, ++ struct drm_connector_state *conn_state, ++ unsigned int *num_output_fmts) ++{ ++ struct drm_bridge *prev_bridge = drm_bridge_get_prev_bridge(bridge); ++ struct drm_bridge_state *prev_bridge_state; ++ ++ if (!prev_bridge || !prev_bridge->funcs->atomic_get_output_bus_fmts) { ++ struct drm_connector *conn = conn_state->connector; ++ u32 *out_bus_fmts; ++ ++ *num_output_fmts = 1; ++ out_bus_fmts = kmalloc(sizeof(*out_bus_fmts), GFP_KERNEL); ++ if (!out_bus_fmts) ++ return NULL; ++ ++ if (conn->display_info.num_bus_formats && ++ conn->display_info.bus_formats) ++ out_bus_fmts[0] = conn->display_info.bus_formats[0]; ++ else ++ out_bus_fmts[0] = MEDIA_BUS_FMT_FIXED; ++ ++ return out_bus_fmts; ++ } ++ ++ prev_bridge_state = drm_atomic_get_new_bridge_state(crtc_state->state, ++ prev_bridge); ++ ++ return prev_bridge->funcs->atomic_get_output_bus_fmts(prev_bridge, prev_bridge_state, ++ crtc_state, conn_state, ++ num_output_fmts); ++} ++ ++/* ++ * Since this bridge is tied to the connector, it acts like a passthrough, ++ * so concerning the input bus formats, either pass the bus formats from the ++ * previous bridge or MEDIA_BUS_FMT_FIXED (like select_bus_fmt_recursive()) ++ * when atomic_get_input_bus_fmts is not supported. ++ * This supports negotiation if the bridge chain has all bits in place. ++ */ ++static u32 *display_connector_get_input_bus_fmts(struct drm_bridge *bridge, ++ struct drm_bridge_state *bridge_state, ++ struct drm_crtc_state *crtc_state, ++ struct drm_connector_state *conn_state, ++ u32 output_fmt, ++ unsigned int *num_input_fmts) ++{ ++ struct drm_bridge *prev_bridge = drm_bridge_get_prev_bridge(bridge); ++ struct drm_bridge_state *prev_bridge_state; ++ ++ if (!prev_bridge || !prev_bridge->funcs->atomic_get_input_bus_fmts) { ++ u32 *in_bus_fmts; ++ ++ *num_input_fmts = 1; ++ in_bus_fmts = kmalloc(sizeof(*in_bus_fmts), GFP_KERNEL); ++ if (!in_bus_fmts) ++ return NULL; ++ ++ in_bus_fmts[0] = MEDIA_BUS_FMT_FIXED; ++ ++ return in_bus_fmts; ++ } ++ ++ prev_bridge_state = drm_atomic_get_new_bridge_state(crtc_state->state, ++ prev_bridge); ++ ++ return prev_bridge->funcs->atomic_get_input_bus_fmts(prev_bridge, prev_bridge_state, ++ crtc_state, conn_state, output_fmt, ++ num_input_fmts); ++} ++ + static const struct drm_bridge_funcs display_connector_bridge_funcs = { + .attach = display_connector_attach, + .detect = display_connector_detect, + .get_edid = display_connector_get_edid, ++ .atomic_get_output_bus_fmts = display_connector_get_output_bus_fmts, ++ .atomic_get_input_bus_fmts = display_connector_get_input_bus_fmts, ++ .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, ++ .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, ++ .atomic_reset = drm_atomic_helper_bridge_reset, + }; + + static irqreturn_t display_connector_hpd_irq(int irq, void *arg) +-- +2.35.3 + diff --git a/patches.suse/drm-bridge-lt8912b-add-vsync-hsync.patch b/patches.suse/drm-bridge-lt8912b-add-vsync-hsync.patch new file mode 100644 index 0000000..ab76424 --- /dev/null +++ b/patches.suse/drm-bridge-lt8912b-add-vsync-hsync.patch @@ -0,0 +1,66 @@ +From da73a94fa282f78d485bd0aab36c8ac15b6f792c Mon Sep 17 00:00:00 2001 +From: Philippe Schenker +Date: Thu, 22 Sep 2022 14:43:03 +0200 +Subject: [PATCH] drm/bridge: lt8912b: add vsync hsync +Git-commit: da73a94fa282f78d485bd0aab36c8ac15b6f792c +Patch-mainline: v6.0 +References: git-fixes + +Currently the bridge driver does not take care whether or not the display +needs positive/negative vertical/horizontal syncs. Pass these two flags +to the bridge from the EDID that was read out from the display. + +Fixes: 30e2ae943c26 ("drm/bridge: Introduce LT8912B DSI to HDMI bridge") +Signed-off-by: Philippe Schenker +Acked-by: Adrien Grassein +Signed-off-by: Neil Armstrong +Link: https://patchwork.freedesktop.org/patch/msgid/20220922124306.34729-2-dev@pschenker.ch +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/bridge/lontium-lt8912b.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/bridge/lontium-lt8912b.c b/drivers/gpu/drm/bridge/lontium-lt8912b.c +index 28bad30dc4e5..0fd3472e767c 100644 +--- a/drivers/gpu/drm/bridge/lontium-lt8912b.c ++++ b/drivers/gpu/drm/bridge/lontium-lt8912b.c +@@ -268,7 +268,7 @@ static int lt8912_video_setup(struct lt8912 *lt) + u32 hactive, h_total, hpw, hfp, hbp; + u32 vactive, v_total, vpw, vfp, vbp; + u8 settle = 0x08; +- int ret; ++ int ret, hsync_activehigh, vsync_activehigh; + + if (!lt) + return -EINVAL; +@@ -278,12 +278,14 @@ static int lt8912_video_setup(struct lt8912 *lt) + hpw = lt->mode.hsync_len; + hbp = lt->mode.hback_porch; + h_total = hactive + hfp + hpw + hbp; ++ hsync_activehigh = lt->mode.flags & DISPLAY_FLAGS_HSYNC_HIGH; + + vactive = lt->mode.vactive; + vfp = lt->mode.vfront_porch; + vpw = lt->mode.vsync_len; + vbp = lt->mode.vback_porch; + v_total = vactive + vfp + vpw + vbp; ++ vsync_activehigh = lt->mode.flags & DISPLAY_FLAGS_VSYNC_HIGH; + + if (vactive <= 600) + settle = 0x04; +@@ -317,6 +319,11 @@ static int lt8912_video_setup(struct lt8912 *lt) + ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x3e, hfp & 0xff); + ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x3f, hfp >> 8); + ++ ret |= regmap_update_bits(lt->regmap[I2C_MAIN], 0xab, BIT(0), ++ vsync_activehigh ? BIT(0) : 0); ++ ret |= regmap_update_bits(lt->regmap[I2C_MAIN], 0xab, BIT(1), ++ hsync_activehigh ? BIT(1) : 0); ++ + return ret; + } + +-- +2.35.3 + diff --git a/patches.suse/drm-bridge-lt8912b-fix-corrupted-image-output.patch b/patches.suse/drm-bridge-lt8912b-fix-corrupted-image-output.patch new file mode 100644 index 0000000..dc997af --- /dev/null +++ b/patches.suse/drm-bridge-lt8912b-fix-corrupted-image-output.patch @@ -0,0 +1,47 @@ +From 051ad2788d35ca07aec8402542e5d38429f2426a Mon Sep 17 00:00:00 2001 +From: Francesco Dolcini +Date: Thu, 22 Sep 2022 14:43:05 +0200 +Subject: [PATCH] drm/bridge: lt8912b: fix corrupted image output +Git-commit: 051ad2788d35ca07aec8402542e5d38429f2426a +Patch-mainline: v6.0 +References: git-fixes + +Correct I2C address for the register list in lt8912_write_lvds_config(), +these registers are on the first I2C address (0x48), the current +function is just writing garbage to the wrong registers and this creates +multiple issues (artifacts and output completely corrupted) on some HDMI +displays. + +Correct I2C address comes from Lontium documentation and it is the one +used on other out-of-tree LT8912B drivers [1]. + +[1] https://github.com/boundarydevices/linux/blob/boundary-imx_5.10.x_2.0.0/drivers/video/lt8912.c#L296 + +Fixes: 30e2ae943c26 ("drm/bridge: Introduce LT8912B DSI to HDMI bridge") +Signed-off-by: Francesco Dolcini +Signed-off-by: Philippe Schenker +Acked-by: Adrien Grassein +Signed-off-by: Neil Armstrong +Link: https://patchwork.freedesktop.org/patch/msgid/20220922124306.34729-4-dev@pschenker.ch +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/bridge/lontium-lt8912b.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/bridge/lontium-lt8912b.c b/drivers/gpu/drm/bridge/lontium-lt8912b.c +index 6a4bb7422176..5968f4af190b 100644 +--- a/drivers/gpu/drm/bridge/lontium-lt8912b.c ++++ b/drivers/gpu/drm/bridge/lontium-lt8912b.c +@@ -188,7 +188,7 @@ static int lt8912_write_lvds_config(struct lt8912 *lt) + {0x03, 0xff}, + }; + +- return regmap_multi_reg_write(lt->regmap[I2C_CEC_DSI], seq, ARRAY_SIZE(seq)); ++ return regmap_multi_reg_write(lt->regmap[I2C_MAIN], seq, ARRAY_SIZE(seq)); + }; + + static inline struct lt8912 *bridge_to_lt8912(struct drm_bridge *b) +-- +2.35.3 + diff --git a/patches.suse/drm-bridge-lt8912b-set-hdmi-or-dvi-mode.patch b/patches.suse/drm-bridge-lt8912b-set-hdmi-or-dvi-mode.patch new file mode 100644 index 0000000..991c319 --- /dev/null +++ b/patches.suse/drm-bridge-lt8912b-set-hdmi-or-dvi-mode.patch @@ -0,0 +1,38 @@ +From 6dd1de12e1243f2013e4fabf31e99e63b1a860d0 Mon Sep 17 00:00:00 2001 +From: Philippe Schenker +Date: Thu, 22 Sep 2022 14:43:04 +0200 +Subject: [PATCH] drm/bridge: lt8912b: set hdmi or dvi mode +Git-commit: 6dd1de12e1243f2013e4fabf31e99e63b1a860d0 +Patch-mainline: v6.0 +References: git-fixes + +The Lontium LT8912 does have a setting for DVI or HDMI. This patch reads +from EDID what the display needs and sets it accordingly. + +Fixes: 30e2ae943c26 ("drm/bridge: Introduce LT8912B DSI to HDMI bridge") +Signed-off-by: Philippe Schenker +Acked-by: Adrien Grassein +Signed-off-by: Neil Armstrong +Link: https://patchwork.freedesktop.org/patch/msgid/20220922124306.34729-3-dev@pschenker.ch +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/bridge/lontium-lt8912b.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/bridge/lontium-lt8912b.c b/drivers/gpu/drm/bridge/lontium-lt8912b.c +index 0fd3472e767c..6a4bb7422176 100644 +--- a/drivers/gpu/drm/bridge/lontium-lt8912b.c ++++ b/drivers/gpu/drm/bridge/lontium-lt8912b.c +@@ -323,6 +323,8 @@ static int lt8912_video_setup(struct lt8912 *lt) + vsync_activehigh ? BIT(0) : 0); + ret |= regmap_update_bits(lt->regmap[I2C_MAIN], 0xab, BIT(1), + hsync_activehigh ? BIT(1) : 0); ++ ret |= regmap_update_bits(lt->regmap[I2C_MAIN], 0xb2, BIT(0), ++ lt->connector.display_info.is_hdmi ? BIT(0) : 0); + + return ret; + } +-- +2.35.3 + diff --git a/patches.suse/drm-bridge-megachips-Fix-a-null-pointer-dereference-.patch b/patches.suse/drm-bridge-megachips-Fix-a-null-pointer-dereference-.patch new file mode 100644 index 0000000..60d40b1 --- /dev/null +++ b/patches.suse/drm-bridge-megachips-Fix-a-null-pointer-dereference-.patch @@ -0,0 +1,52 @@ +From 1ff673333d46d2c1b053ebd0c1c7c7c79e36943e Mon Sep 17 00:00:00 2001 +From: Zheyu Ma +Date: Tue, 30 Aug 2022 15:34:50 +0800 +Subject: [PATCH] drm/bridge: megachips: Fix a null pointer dereference bug +Git-commit: 1ff673333d46d2c1b053ebd0c1c7c7c79e36943e +Patch-mainline: v6.1-rc1 +References: git-fixes + +When removing the module we will get the following warning: + +[ 31.911505] i2c-core: driver [stdp2690-ge-b850v3-fw] unregistered +[ 31.912484] general protection fault, probably for non-canonical address 0xdffffc0000000001: 0000 [#1] PREEMPT SMP KASAN PTI +[ 31.913338] KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f] +[ 31.915280] RIP: 0010:drm_bridge_remove+0x97/0x130 +[ 31.921825] Call Trace: +[ 31.922533] stdp4028_ge_b850v3_fw_remove+0x34/0x60 [megachips_stdpxxxx_ge_b850v3_fw] +[ 31.923139] i2c_device_remove+0x181/0x1f0 + +The two bridges (stdp2690, stdp4028) do not probe at the same time, so +the driver does not call ge_b850v3_resgiter() when probing, causing the +driver to try to remove the object that has not been initialized. + +Fix this by checking whether both the bridges are probed. + +Fixes: 11632d4aa2b3 ("drm/bridge: megachips: Ensure both bridges are probed before registration") +Signed-off-by: Zheyu Ma +Signed-off-by: Robert Foss +Link: https://patchwork.freedesktop.org/patch/msgid/20220830073450.1897020-1-zheyuma97@gmail.com +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c +index cce98bf2a4e7..72248a565579 100644 +--- a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c ++++ b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c +@@ -296,7 +296,9 @@ static void ge_b850v3_lvds_remove(void) + * This check is to avoid both the drivers + * removing the bridge in their remove() function + */ +- if (!ge_b850v3_lvds_ptr) ++ if (!ge_b850v3_lvds_ptr || ++ !ge_b850v3_lvds_ptr->stdp2690_i2c || ++ !ge_b850v3_lvds_ptr->stdp4028_i2c) + goto out; + + drm_bridge_remove(&ge_b850v3_lvds_ptr->bridge); +-- +2.35.3 + diff --git a/patches.suse/drm-bridge-parade-ps8640-Fix-regulator-supply-order.patch b/patches.suse/drm-bridge-parade-ps8640-Fix-regulator-supply-order.patch new file mode 100644 index 0000000..f5e8e58 --- /dev/null +++ b/patches.suse/drm-bridge-parade-ps8640-Fix-regulator-supply-order.patch @@ -0,0 +1,39 @@ +From fc94224c2e0ae8d83ac511a3ef4962178505469d Mon Sep 17 00:00:00 2001 +From: Chen-Yu Tsai +Date: Thu, 21 Jul 2022 17:22:58 +0800 +Subject: [PATCH] drm/bridge: parade-ps8640: Fix regulator supply order +Git-commit: fc94224c2e0ae8d83ac511a3ef4962178505469d +Patch-mainline: v6.1-rc1 +References: git-fixes + +The datasheet says that VDD12 must be enabled and at full voltage before +VDD33 is enabled. + +Reorder the bulk regulator supply names so that VDD12 is enabled before +VDD33. Any enable ramp delays should be handled by setting proper +constraints on the regulators. + +Fixes: bc1aee7fc8f0 ("drm/bridge: Add I2C based driver for ps8640 bridge") +Signed-off-by: Chen-Yu Tsai +Reviewed-by: Neil Armstrong +Signed-off-by: Robert Foss +Link: https://patchwork.freedesktop.org/patch/msgid/20220721092258.3397461-1-wenst@chromium.org +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/bridge/parade-ps8640.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/bridge/parade-ps8640.c ++++ b/drivers/gpu/drm/bridge/parade-ps8640.c +@@ -333,8 +333,8 @@ static int ps8640_probe(struct i2c_clien + if (IS_ERR(ps_bridge->panel_bridge)) + return PTR_ERR(ps_bridge->panel_bridge); + +- ps_bridge->supplies[0].supply = "vdd33"; +- ps_bridge->supplies[1].supply = "vdd12"; ++ ps_bridge->supplies[0].supply = "vdd12"; ++ ps_bridge->supplies[1].supply = "vdd33"; + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ps_bridge->supplies), + ps_bridge->supplies); + if (ret) diff --git a/patches.suse/drm-fix-drm_mipi_dbi-build-errors.patch b/patches.suse/drm-fix-drm_mipi_dbi-build-errors.patch new file mode 100644 index 0000000..f19dad1 --- /dev/null +++ b/patches.suse/drm-fix-drm_mipi_dbi-build-errors.patch @@ -0,0 +1,65 @@ +From eb7de496451bd969e203f02f66585131228ba4ae Mon Sep 17 00:00:00 2001 +From: Randy Dunlap +Date: Mon, 22 Aug 2022 17:42:43 -0700 +Subject: [PATCH] drm: fix drm_mipi_dbi build errors +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: eb7de496451bd969e203f02f66585131228ba4ae +Patch-mainline: v6.1-rc1 +References: git-fixes + +drm_mipi_dbi needs lots of DRM_KMS_HELPER support, so select +that Kconfig symbol like it is done is most other uses, and +the way that it was before MIPS_DBI was moved from tinydrm +to its core location. + +Fixes these build errors: + +Ld: drivers/gpu/drm/drm_mipi_dbi.o: in function `mipi_dbi_buf_copy': +drivers/gpu/drm/drm_mipi_dbi.c:205: undefined reference to `drm_gem_fb_get_obj' +Ld: drivers/gpu/drm/drm_mipi_dbi.c:211: undefined reference to `drm_gem_fb_begin_cpu_access' +Ld: drivers/gpu/drm/drm_mipi_dbi.c:215: undefined reference to `drm_gem_fb_vmap' +Ld: drivers/gpu/drm/drm_mipi_dbi.c:222: undefined reference to `drm_fb_swab' +Ld: drivers/gpu/drm/drm_mipi_dbi.c:224: undefined reference to `drm_fb_memcpy' +Ld: drivers/gpu/drm/drm_mipi_dbi.c:227: undefined reference to `drm_fb_xrgb8888_to_rgb565' +Ld: drivers/gpu/drm/drm_mipi_dbi.c:235: undefined reference to `drm_gem_fb_vunmap' +Ld: drivers/gpu/drm/drm_mipi_dbi.c:237: undefined reference to `drm_gem_fb_end_cpu_access' +Ld: drivers/gpu/drm/drm_mipi_dbi.o: in function `mipi_dbi_dev_init_with_formats': +Ld: drivers/gpu/drm/drm_mipi_dbi.o:/X64/../drivers/gpu/drm/drm_mipi_dbi.c:469: undefined reference to `drm_gem_fb_create_with_dirty' + +Fixes: 174102f4de23 ("drm/tinydrm: Move mipi-dbi") +Signed-off-by: Randy Dunlap +Reported-by: kernel test robot +Cc: Dillon Min +Cc: Linus Walleij +Cc: Sam Ravnborg +Cc: Noralf Trønnes +Cc: Thomas Zimmermann +Cc: Thierry Reding +Cc: dri-devel@lists.freedesktop.org +Cc: David Airlie +Cc: Daniel Vetter +Signed-off-by: Linus Walleij +Link: https://patchwork.freedesktop.org/patch/msgid/20220823004243.11596-1-rdunlap@infradead.org +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig +index 0b2ad7212ee6..2f52e8941074 100644 +--- a/drivers/gpu/drm/Kconfig ++++ b/drivers/gpu/drm/Kconfig +@@ -31,6 +31,7 @@ menuconfig DRM + config DRM_MIPI_DBI + tristate + depends on DRM ++ select DRM_KMS_HELPER + + config DRM_MIPI_DSI + bool +-- +2.35.3 + diff --git a/patches.suse/drm-gem-Fix-GEM-handle-release-errors.patch b/patches.suse/drm-gem-Fix-GEM-handle-release-errors.patch new file mode 100644 index 0000000..dc70ffb --- /dev/null +++ b/patches.suse/drm-gem-Fix-GEM-handle-release-errors.patch @@ -0,0 +1,137 @@ +From ea2aa97ca37a9044ade001aef71dbc06318e8d44 Mon Sep 17 00:00:00 2001 +From: Jeffy Chen +Date: Fri, 19 Aug 2022 15:28:34 +0800 +Subject: [PATCH] drm/gem: Fix GEM handle release errors +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: ea2aa97ca37a9044ade001aef71dbc06318e8d44 +Patch-mainline: v6.0-rc3 +References: git-fixes + +Currently we are assuming a one to one mapping between dmabuf and +GEM handle when releasing GEM handles. + +But that is not always true, since we would create extra handles for the +GEM obj in cases like gem_open() and getfb{,2}(). + +A similar issue was reported at: +https://lore.kernel.org/all/20211105083308.392156-1-jay.xu@rock-chips.com/ + +Another problem is that the imported dmabuf might not always have +gem_obj->dma_buf set, which would cause leaks in +drm_gem_remove_prime_handles(). + +Let's fix these for now by using handle to find the exact map to remove. + +Signed-off-by: Jeffy Chen +Reviewed-by: Christian König +Signed-off-by: Christian König +Link: https://patchwork.freedesktop.org/patch/msgid/20220819072834.17888-1-jeffy.chen@rock-chips.com +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/drm_gem.c | 17 +---------------- + drivers/gpu/drm/drm_internal.h | 4 ++-- + drivers/gpu/drm/drm_prime.c | 20 ++++++++++++-------- + 3 files changed, 15 insertions(+), 26 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c +index 86d670c71286..ad068865ba20 100644 +--- a/drivers/gpu/drm/drm_gem.c ++++ b/drivers/gpu/drm/drm_gem.c +@@ -168,21 +168,6 @@ void drm_gem_private_object_init(struct drm_device *dev, + } + EXPORT_SYMBOL(drm_gem_private_object_init); + +-static void +-drm_gem_remove_prime_handles(struct drm_gem_object *obj, struct drm_file *filp) +-{ +- /* +- * Note: obj->dma_buf can't disappear as long as we still hold a +- * handle reference in obj->handle_count. +- */ +- mutex_lock(&filp->prime.lock); +- if (obj->dma_buf) { +- drm_prime_remove_buf_handle_locked(&filp->prime, +- obj->dma_buf); +- } +- mutex_unlock(&filp->prime.lock); +-} +- + /** + * drm_gem_object_handle_free - release resources bound to userspace handles + * @obj: GEM object to clean up. +@@ -253,7 +238,7 @@ drm_gem_object_release_handle(int id, void *ptr, void *data) + if (obj->funcs->close) + obj->funcs->close(obj, file_priv); + +- drm_gem_remove_prime_handles(obj, file_priv); ++ drm_prime_remove_buf_handle(&file_priv->prime, id); + drm_vma_node_revoke(&obj->vma_node, file_priv); + + drm_gem_object_handle_put_unlocked(obj); +diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h +index 1fbbc19f1ac0..7bb98e6a446d 100644 +--- a/drivers/gpu/drm/drm_internal.h ++++ b/drivers/gpu/drm/drm_internal.h +@@ -74,8 +74,8 @@ int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data, + + void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv); + void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv); +-void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private *prime_fpriv, +- struct dma_buf *dma_buf); ++void drm_prime_remove_buf_handle(struct drm_prime_file_private *prime_fpriv, ++ uint32_t handle); + + /* drm_drv.c */ + struct drm_minor *drm_minor_acquire(unsigned int minor_id); +diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c +index a3f180653b8b..eb09e86044c6 100644 +--- a/drivers/gpu/drm/drm_prime.c ++++ b/drivers/gpu/drm/drm_prime.c +@@ -190,29 +190,33 @@ static int drm_prime_lookup_buf_handle(struct drm_prime_file_private *prime_fpri + return -ENOENT; + } + +-void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private *prime_fpriv, +- struct dma_buf *dma_buf) ++void drm_prime_remove_buf_handle(struct drm_prime_file_private *prime_fpriv, ++ uint32_t handle) + { + struct rb_node *rb; + +- rb = prime_fpriv->dmabufs.rb_node; ++ mutex_lock(&prime_fpriv->lock); ++ ++ rb = prime_fpriv->handles.rb_node; + while (rb) { + struct drm_prime_member *member; + +- member = rb_entry(rb, struct drm_prime_member, dmabuf_rb); +- if (member->dma_buf == dma_buf) { ++ member = rb_entry(rb, struct drm_prime_member, handle_rb); ++ if (member->handle == handle) { + rb_erase(&member->handle_rb, &prime_fpriv->handles); + rb_erase(&member->dmabuf_rb, &prime_fpriv->dmabufs); + +- dma_buf_put(dma_buf); ++ dma_buf_put(member->dma_buf); + kfree(member); +- return; +- } else if (member->dma_buf < dma_buf) { ++ break; ++ } else if (member->handle < handle) { + rb = rb->rb_right; + } else { + rb = rb->rb_left; + } + } ++ ++ mutex_unlock(&prime_fpriv->lock); + } + + void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv) +-- +2.35.3 + diff --git a/patches.suse/drm-gma500-Fix-BUG-sleeping-function-called-from-inv.patch b/patches.suse/drm-gma500-Fix-BUG-sleeping-function-called-from-inv.patch new file mode 100644 index 0000000..6e5d8ba --- /dev/null +++ b/patches.suse/drm-gma500-Fix-BUG-sleeping-function-called-from-inv.patch @@ -0,0 +1,105 @@ +From 63e37a79f7bd939314997e29c2f5a9f0ef184281 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Tue, 6 Sep 2022 22:38:50 +0200 +Subject: [PATCH] drm/gma500: Fix BUG: sleeping function called from invalid context errors +Git-commit: 63e37a79f7bd939314997e29c2f5a9f0ef184281 +Patch-mainline: v6.0-rc6 +References: git-fixes + +gma_crtc_page_flip() was holding the event_lock spinlock while calling +crtc_funcs->mode_set_base() which takes ww_mutex. + +The only reason to hold event_lock is to clear gma_crtc->page_flip_event +on mode_set_base() errors. + +Instead unlock it after setting gma_crtc->page_flip_event and on +errors re-take the lock and clear gma_crtc->page_flip_event it +it is still set. + +This fixes the following WARN/stacktrace: + +[ 512.122953] BUG: sleeping function called from invalid context at kernel/locking/mutex.c:870 +[ 512.123004] in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 1253, name: gnome-shell +[ 512.123031] preempt_count: 1, expected: 0 +[ 512.123048] RCU nest depth: 0, expected: 0 +[ 512.123066] INFO: lockdep is turned off. +[ 512.123080] irq event stamp: 0 +[ 512.123094] hardirqs last enabled at (0): [<0000000000000000>] 0x0 +[ 512.123134] hardirqs last disabled at (0): [] copy_process+0x9fc/0x1de0 +[ 512.123176] softirqs last enabled at (0): [] copy_process+0x9fc/0x1de0 +[ 512.123207] softirqs last disabled at (0): [<0000000000000000>] 0x0 +[ 512.123233] Preemption disabled at: +[ 512.123241] [<0000000000000000>] 0x0 +[ 512.123275] CPU: 3 PID: 1253 Comm: gnome-shell Tainted: G W 5.19.0+ #1 +[ 512.123304] Hardware name: Packard Bell dot s/SJE01_CT, BIOS V1.10 07/23/2013 +[ 512.123323] Call Trace: +[ 512.123346] +[ 512.123370] dump_stack_lvl+0x5b/0x77 +[ 512.123412] __might_resched.cold+0xff/0x13a +[ 512.123458] ww_mutex_lock+0x1e/0xa0 +[ 512.123495] psb_gem_pin+0x2c/0x150 [gma500_gfx] +[ 512.123601] gma_pipe_set_base+0x76/0x240 [gma500_gfx] +[ 512.123708] gma_crtc_page_flip+0x95/0x130 [gma500_gfx] +[ 512.123808] drm_mode_page_flip_ioctl+0x57d/0x5d0 +[ 512.123897] ? drm_mode_cursor2_ioctl+0x10/0x10 +[ 512.123936] drm_ioctl_kernel+0xa1/0x150 +[ 512.123984] drm_ioctl+0x21f/0x420 +[ 512.124025] ? drm_mode_cursor2_ioctl+0x10/0x10 +[ 512.124070] ? rcu_read_lock_bh_held+0xb/0x60 +[ 512.124104] ? lock_release+0x1ef/0x2d0 +[ 512.124161] __x64_sys_ioctl+0x8d/0xd0 +[ 512.124203] do_syscall_64+0x58/0x80 +[ 512.124239] ? do_syscall_64+0x67/0x80 +[ 512.124267] ? trace_hardirqs_on_prepare+0x55/0xe0 +[ 512.124300] ? do_syscall_64+0x67/0x80 +[ 512.124340] ? rcu_read_lock_sched_held+0x10/0x80 +[ 512.124377] entry_SYSCALL_64_after_hwframe+0x63/0xcd +[ 512.124411] RIP: 0033:0x7fcc4a70740f +[ 512.124442] Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48 89 44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <89> c2 3d 00 f0 ff ff 77 18 48 8b 44 24 18 64 48 2b 04 25 28 00 00 +[ 512.124470] RSP: 002b:00007ffda73f5390 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 +[ 512.124503] RAX: ffffffffffffffda RBX: 000055cc9e474500 RCX: 00007fcc4a70740f +[ 512.124524] RDX: 00007ffda73f5420 RSI: 00000000c01864b0 RDI: 0000000000000009 +[ 512.124544] RBP: 00007ffda73f5420 R08: 000055cc9c0b0cb0 R09: 0000000000000034 +[ 512.124564] R10: 0000000000000000 R11: 0000000000000246 R12: 00000000c01864b0 +[ 512.124584] R13: 0000000000000009 R14: 000055cc9df484d0 R15: 000055cc9af5d0c0 +[ 512.124647] + +Signed-off-by: Hans de Goede +Signed-off-by: Patrik Jakobsson +Link: https://patchwork.freedesktop.org/patch/msgid/20220906203852.527663-2-hdegoede@redhat.com +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/gma500/gma_display.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/gma500/gma_display.c b/drivers/gpu/drm/gma500/gma_display.c +index bd40c040a2c9..2f52eceda3a1 100644 +--- a/drivers/gpu/drm/gma500/gma_display.c ++++ b/drivers/gpu/drm/gma500/gma_display.c +@@ -532,15 +532,18 @@ int gma_crtc_page_flip(struct drm_crtc *crtc, + WARN_ON(drm_crtc_vblank_get(crtc) != 0); + + gma_crtc->page_flip_event = event; ++ spin_unlock_irqrestore(&dev->event_lock, flags); + + /* Call this locked if we want an event at vblank interrupt. */ + ret = crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y, old_fb); + if (ret) { +- gma_crtc->page_flip_event = NULL; +- drm_crtc_vblank_put(crtc); ++ spin_lock_irqsave(&dev->event_lock, flags); ++ if (gma_crtc->page_flip_event) { ++ gma_crtc->page_flip_event = NULL; ++ drm_crtc_vblank_put(crtc); ++ } ++ spin_unlock_irqrestore(&dev->event_lock, flags); + } +- +- spin_unlock_irqrestore(&dev->event_lock, flags); + } else { + ret = crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y, old_fb); + } +-- +2.35.3 + diff --git a/patches.suse/drm-i915-Implement-WaEdpLinkRateDataReload.patch b/patches.suse/drm-i915-Implement-WaEdpLinkRateDataReload.patch new file mode 100644 index 0000000..5e529c8 --- /dev/null +++ b/patches.suse/drm-i915-Implement-WaEdpLinkRateDataReload.patch @@ -0,0 +1,92 @@ +From 672d6ca758651f0ec12cd0d59787067a5bde1c96 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Fri, 2 Sep 2022 10:03:18 +0300 +Subject: [PATCH] drm/i915: Implement WaEdpLinkRateDataReload +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 672d6ca758651f0ec12cd0d59787067a5bde1c96 +Patch-mainline: v6.0-rc5 +Alt-commit: 25899c590cb5ba9b9f284c6ca8e7e9086793d641 +References: git-fixes + +A lot of modern laptops use the Parade PS8461E MUX for eDP +switching. The MUX can operate in jitter cleaning mode or +redriver mode, the first one resulting in higher link +quality. The jitter cleaning mode needs to know the link +rate used and the MUX achieves this by snooping the +LINK_BW_SET, LINK_RATE_SELECT and SUPPORTED_LINK_RATES +DPCD accesses. + +When the MUX is powered down (seems this can happen whenever +the display is turned off) it loses track of the snooped +link rates so when we do the LINK_RATE_SELECT write it no +longer knowns which link rate we're selecting, and thus it +falls back to the lower quality redriver mode. This results +in unstable high link rates (eg. usually 8.1Gbps link rate +no longer works correctly). + +In order to avoid all that let's re-snoop SUPPORTED_LINK_RATES +from the sink at the start of every link training. + +Unfortunately we don't have a way to detect the presence of +the MUX. It looks like the set of laptops equipped with this +MUX is fairly large and contains devices from multiple +manufacturers. It may also still be growing with new models. +So a quirk doesn't seem like a very easily maintainable +option, thus we shall attempt to do this unconditionally on +all machines that use LINK_RATE_SELECT. Hopefully this extra +DPCD read doesn't cause issues for any unaffected machine. +If that turns out to be the case we'll need to convert this +into a quirk in the future. + +Cc: stable@vger.kernel.org +Cc: Jason A. Donenfeld +Cc: Ankit Nautiyal +Cc: Jani Nikula +Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/6205 +Signed-off-by: Ville Syrjälä +Link: https://patchwork.freedesktop.org/patch/msgid/20220902070319.15395-1-ville.syrjala@linux.intel.com +Tested-by: Aaron Ma +Tested-by: Jason A. Donenfeld +Reviewed-by: Jani Nikula +(cherry picked from commit 25899c590cb5ba9b9f284c6ca8e7e9086793d641) + +Signed-off-by: Rodrigo Vivi +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/i915/display/intel_dp_link_training.c | 22 ++++++++++++++++++ + 1 file changed, 22 insertions(+) + +--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c ++++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c +@@ -475,6 +475,28 @@ intel_dp_prepare_link_train(struct intel + intel_dp_compute_rate(intel_dp, crtc_state->port_clock, + &link_bw, &rate_select); + ++ /* ++ * WaEdpLinkRateDataReload ++ * ++ * Parade PS8461E MUX (used on varius TGL+ laptops) needs ++ * to snoop the link rates reported by the sink when we ++ * use LINK_RATE_SET in order to operate in jitter cleaning ++ * mode (as opposed to redriver mode). Unfortunately it ++ * loses track of the snooped link rates when powered down, ++ * so we need to make it re-snoop often. Without this high ++ * link rates are not stable. ++ */ ++ if (!link_bw) { ++ struct intel_connector *connector = intel_dp->attached_connector; ++ __le16 sink_rates[DP_MAX_SUPPORTED_RATES]; ++ ++ drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] Reloading eDP link rates\n", ++ connector->base.base.id, connector->base.name); ++ ++ drm_dp_dpcd_read(&intel_dp->aux, DP_SUPPORTED_LINK_RATES, ++ sink_rates, sizeof(sink_rates)); ++ } ++ + if (link_bw) + drm_dbg_kms(&i915->drm, + "Using LINK_BW_SET value %02x\n", link_bw); diff --git a/patches.suse/drm-i915-Reject-unsupported-TMDS-rates-on-ICL.patch b/patches.suse/drm-i915-Reject-unsupported-TMDS-rates-on-ICL.patch new file mode 100644 index 0000000..b0a8f45 --- /dev/null +++ b/patches.suse/drm-i915-Reject-unsupported-TMDS-rates-on-ICL.patch @@ -0,0 +1,63 @@ +From 9cddf03b2af07443bebdc73cba21acb360c079e8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Fri, 11 Mar 2022 23:28:45 +0200 +Subject: [PATCH] drm/i915: Reject unsupported TMDS rates on ICL+ +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 9cddf03b2af07443bebdc73cba21acb360c079e8 +Patch-mainline: v5.18-rc1 +Alt-commit: e5086cb3f3d3f94091be29eec38cf13f8a75a778 +References: git-fixes + +ICL+ PLLs can't genenerate certain frequencies. Running the PLL +algorithms through for all frequencies 25-594MHz we see a gap just +above 500 MHz. Specifically 500-522.8MHZ for TC PLLs, and 500-533.2 +MHz for combo PHY PLLs. Reject those frequencies hdmi_port_clock_valid() +so that we properly filter out unsupported modes and/or color depths +for HDMI. + +Cc: stable@vger.kernel.org +Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/5247 +Signed-off-by: Ville Syrjälä +Link: https://patchwork.freedesktop.org/patch/msgid/20220311212845.32358-1-ville.syrjala@linux.intel.com +Reviewed-by: Mika Kahola +(cherry picked from commit e5086cb3f3d3f94091be29eec38cf13f8a75a778) + +Signed-off-by: Tvrtko Ursulin +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/i915/display/intel_hdmi.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c +index 1aa5bdc7b0dc..6512f014cad4 100644 +--- a/drivers/gpu/drm/i915/display/intel_hdmi.c ++++ b/drivers/gpu/drm/i915/display/intel_hdmi.c +@@ -1836,6 +1836,7 @@ hdmi_port_clock_valid(struct intel_hdmi *hdmi, + bool has_hdmi_sink) + { + struct drm_i915_private *dev_priv = intel_hdmi_to_i915(hdmi); ++ enum phy phy = intel_port_to_phy(dev_priv, hdmi_to_dig_port(hdmi)->base.port); + + if (clock < 25000) + return MODE_CLOCK_LOW; +@@ -1856,6 +1857,14 @@ hdmi_port_clock_valid(struct intel_hdmi *hdmi, + if (IS_CHERRYVIEW(dev_priv) && clock > 216000 && clock < 240000) + return MODE_CLOCK_RANGE; + ++ /* ICL+ combo PHY PLL can't generate 500-533.2 MHz */ ++ if (intel_phy_is_combo(dev_priv, phy) && clock > 500000 && clock < 533200) ++ return MODE_CLOCK_RANGE; ++ ++ /* ICL+ TC PHY PLL can't generate 500-532.8 MHz */ ++ if (intel_phy_is_tc(dev_priv, phy) && clock > 500000 && clock < 532800) ++ return MODE_CLOCK_RANGE; ++ + /* + * SNPS PHYs' MPLLB table-based programming can only handle a fixed + * set of link rates. +-- +2.35.3 + diff --git a/patches.suse/drm-i915-ehl-Update-MOCS-table-for-EHL.patch b/patches.suse/drm-i915-ehl-Update-MOCS-table-for-EHL.patch new file mode 100644 index 0000000..0018be6 --- /dev/null +++ b/patches.suse/drm-i915-ehl-Update-MOCS-table-for-EHL.patch @@ -0,0 +1,53 @@ +From af4e20d335d4414814030ba26f1689884c831269 Mon Sep 17 00:00:00 2001 +From: Tejas Upadhyay +Date: Fri, 30 Sep 2022 19:02:23 +0530 +Subject: [PATCH] drm/i915/ehl: Update MOCS table for EHL +Git-commit: af4e20d335d4414814030ba26f1689884c831269 +Patch-mainline: v6.1-rc1 +Alt-commit: 6fa964c045a6bc3321a9186e87bfbcfd1059b0f1 +References: git-fixes + +Add these extra EHL entries back since we have +drm-tip commit 13d29c823738 +("drm/i915/ehl: unconditionally flush the pages on acquire") +introduces proper flushing to make it work as expected. + +Cc: Chris Wilson +Cc: Matthew Auld +Fixes: 046091758b50 ("Revert "drm/i915/ehl: Update MOCS table for EHL"") +Signed-off-by: Matt Roper +Signed-off-by: Tejas Upadhyay +Acked-by: Matthew Auld +Signed-off-by: Matthew Auld +Link: https://patchwork.freedesktop.org/patch/msgid/20220930133223.2757282-1-tejas.upadhyay@intel.com +(cherry picked from commit 6fa964c045a6bc3321a9186e87bfbcfd1059b0f1) + +Signed-off-by: Tvrtko Ursulin +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/i915/gt/intel_mocs.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/gpu/drm/i915/gt/intel_mocs.c b/drivers/gpu/drm/i915/gt/intel_mocs.c +index c6ebe2781076..152244d7f62a 100644 +--- a/drivers/gpu/drm/i915/gt/intel_mocs.c ++++ b/drivers/gpu/drm/i915/gt/intel_mocs.c +@@ -207,6 +207,14 @@ static const struct drm_i915_mocs_entry broxton_mocs_table[] = { + MOCS_ENTRY(15, \ + LE_3_WB | LE_TC_1_LLC | LE_LRUM(2) | LE_AOM(1), \ + L3_3_WB), \ ++ /* Bypass LLC - Uncached (EHL+) */ \ ++ MOCS_ENTRY(16, \ ++ LE_1_UC | LE_TC_1_LLC | LE_SCF(1), \ ++ L3_1_UC), \ ++ /* Bypass LLC - L3 (Read-Only) (EHL+) */ \ ++ MOCS_ENTRY(17, \ ++ LE_1_UC | LE_TC_1_LLC | LE_SCF(1), \ ++ L3_3_WB), \ + /* Self-Snoop - L3 + LLC */ \ + MOCS_ENTRY(18, \ + LE_3_WB | LE_TC_1_LLC | LE_LRUM(3) | LE_SSE(3), \ +-- +2.35.3 + diff --git a/patches.suse/drm-i915-gt-Restrict-forced-preemption-to-the-active.patch b/patches.suse/drm-i915-gt-Restrict-forced-preemption-to-the-active.patch new file mode 100644 index 0000000..244d5ff --- /dev/null +++ b/patches.suse/drm-i915-gt-Restrict-forced-preemption-to-the-active.patch @@ -0,0 +1,114 @@ +From 6ef7d362123ecb5bf6d163bb9c7fd6ba2d8c968c Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Wed, 21 Sep 2022 15:52:58 +0200 +Subject: [PATCH] drm/i915/gt: Restrict forced preemption to the active context +Git-commit: 6ef7d362123ecb5bf6d163bb9c7fd6ba2d8c968c +Patch-mainline: v6.0 +Alt-commit: 107ba1a2c705f4358f2602ec2f2fd821bb651f42 +References: git-fixes + +When we submit a new pair of contexts to ELSP for execution, we start a +timer by which point we expect the HW to have switched execution to the +pending contexts. If the promotion to the new pair of contexts has not +occurred, we declare the executing context to have hung and force the +preemption to take place by resetting the engine and resubmitting the +new contexts. + +This can lead to an unfair situation where almost all of the preemption +timeout is consumed by the first context which just switches into the +second context immediately prior to the timer firing and triggering the +preemption reset (assuming that the timer interrupts before we process +the CS events for the context switch). The second context hasn't yet had +a chance to yield to the incoming ELSP (and send the ACk for the +promotion) and so ends up being blamed for the reset. + +If we see that a context switch has occurred since setting the +preemption timeout, but have not yet received the ACK for the ELSP +promotion, rearm the preemption timer and check again. This is +especially significant if the first context was not schedulable and so +we used the shortest timer possible, greatly increasing the chance of +accidentally blaming the second innocent context. + +Fixes: 3a7a92aba8fb ("drm/i915/execlists: Force preemption") +Fixes: d12acee84ffb ("drm/i915/execlists: Cancel banned contexts on schedule-out") +Reported-by: Tvrtko Ursulin +Signed-off-by: Chris Wilson +Cc: Tvrtko Ursulin +Cc: Andi Shyti +Reviewed-by: Andrzej Hajda +Tested-by: Andrzej Hajda +Cc: # v5.5+ +Signed-off-by: Andi Shyti +Link: https://patchwork.freedesktop.org/patch/msgid/20220921135258.1714873-1-andrzej.hajda@intel.com +(cherry picked from commit 107ba1a2c705f4358f2602ec2f2fd821bb651f42) + +Signed-off-by: Rodrigo Vivi +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/i915/gt/intel_engine_types.h | 15 +++++++++++++ + drivers/gpu/drm/i915/gt/intel_execlists_submission.c | 21 ++++++++++++++++++- + 2 files changed, 35 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/i915/gt/intel_engine_types.h ++++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h +@@ -144,6 +144,21 @@ struct intel_engine_execlists { + struct timer_list preempt; + + /** ++ * @preempt_target: active request at the time of the preemption request ++ * ++ * We force a preemption to occur if the pending contexts have not ++ * been promoted to active upon receipt of the CS ack event within ++ * the timeout. This timeout maybe chosen based on the target, ++ * using a very short timeout if the context is no longer schedulable. ++ * That short timeout may not be applicable to other contexts, so ++ * if a context switch should happen within before the preemption ++ * timeout, we may shoot early at an innocent context. To prevent this, ++ * we record which context was active at the time of the preemption ++ * request and only reset that context upon the timeout. ++ */ ++ const struct i915_request *preempt_target; ++ ++ /** + * @ccid: identifier for contexts submitted to this engine + */ + u32 ccid; +--- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c ++++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c +@@ -1225,6 +1225,9 @@ static unsigned long active_preempt_time + if (!rq) + return 0; + ++ /* Only allow ourselves to force reset the currently active context */ ++ engine->execlists.preempt_target = rq; ++ + /* Force a fast reset for terminated contexts (ignoring sysfs!) */ + if (unlikely(intel_context_is_banned(rq->context) || bad_request(rq))) + return 1; +@@ -2401,8 +2404,24 @@ static void execlists_submission_tasklet + GEM_BUG_ON(inactive - post > ARRAY_SIZE(post)); + + if (unlikely(preempt_timeout(engine))) { ++ const struct i915_request *rq = *engine->execlists.active; ++ ++ /* ++ * If after the preempt-timeout expired, we are still on the ++ * same active request/context as before we initiated the ++ * preemption, reset the engine. ++ * ++ * However, if we have processed a CS event to switch contexts, ++ * but not yet processed the CS event for the pending ++ * preemption, reset the timer allowing the new context to ++ * gracefully exit. ++ */ + cancel_timer(&engine->execlists.preempt); +- engine->execlists.error_interrupt |= ERROR_PREEMPT; ++ if (rq == engine->execlists.preempt_target) ++ engine->execlists.error_interrupt |= ERROR_PREEMPT; ++ else ++ set_timer_ms(&engine->execlists.preempt, ++ active_preempt_timeout(engine, rq)); + } + + if (unlikely(READ_ONCE(engine->execlists.error_interrupt))) { diff --git a/patches.suse/drm-i915-gvt-fix-a-memory-leak-in-intel_gvt_init_vgp.patch b/patches.suse/drm-i915-gvt-fix-a-memory-leak-in-intel_gvt_init_vgp.patch new file mode 100644 index 0000000..2294ab2 --- /dev/null +++ b/patches.suse/drm-i915-gvt-fix-a-memory-leak-in-intel_gvt_init_vgp.patch @@ -0,0 +1,52 @@ +From 98828955971363e838149105c268b1fad905f15b Mon Sep 17 00:00:00 2001 +From: Christoph Hellwig +Date: Fri, 23 Sep 2022 11:26:39 +0200 +Subject: [PATCH] drm/i915/gvt: fix a memory leak in intel_gvt_init_vgpu_types +Git-commit: 98828955971363e838149105c268b1fad905f15b +Patch-mainline: v6.1-rc1 +References: git-fixes + +gvt->types needs to be freed on error. + +Fixes: bc90d097ae14 ("drm/i915/gvt: define weight according to vGPU type") +Reported-by: Kevin Tian +Signed-off-by: Christoph Hellwig +Reviewed-by: Jason Gunthorpe +Reviewed-by: Kevin Tian +Reviewed-by: Zhenyu Wang +Link: https://lore.kernel.org/r/20220923092652.100656-2-hch@lst.de +[aw: Correct fixes commit ID as reported by Stephen Rothwell] +Signed-off-by: Alex Williamson +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/i915/gvt/vgpu.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c +index 5c533fbc2c8d..dbb2a971ba5d 100644 +--- a/drivers/gpu/drm/i915/gvt/vgpu.c ++++ b/drivers/gpu/drm/i915/gvt/vgpu.c +@@ -142,7 +142,7 @@ int intel_gvt_init_vgpu_types(struct intel_gvt *gvt) + + if (vgpu_types[i].weight < 1 || + vgpu_types[i].weight > VGPU_MAX_WEIGHT) +- return -EINVAL; ++ goto out_free_types; + + gvt->types[i].weight = vgpu_types[i].weight; + gvt->types[i].resolution = vgpu_types[i].edid; +@@ -167,6 +167,10 @@ int intel_gvt_init_vgpu_types(struct intel_gvt *gvt) + + gvt->num_types = i; + return 0; ++ ++out_free_types: ++ kfree(gvt->types); ++ return -EINVAL; + } + + void intel_gvt_clean_vgpu_types(struct intel_gvt *gvt) +-- +2.35.3 + diff --git a/patches.suse/drm-i915-hdmi-Turn-DP-TMDS-output-buffers-back-on-in.patch b/patches.suse/drm-i915-hdmi-Turn-DP-TMDS-output-buffers-back-on-in.patch index 524ca03..bf33df3 100644 --- a/patches.suse/drm-i915-hdmi-Turn-DP-TMDS-output-buffers-back-on-in.patch +++ b/patches.suse/drm-i915-hdmi-Turn-DP-TMDS-output-buffers-back-on-in.patch @@ -67,7 +67,7 @@ Signed-off-by: Patrik Jakobsson intel_encoder->power_domain = intel_port_to_power_domain(port); --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c -@@ -4432,6 +4432,7 @@ static void intel_ddi_encoder_shutdown(s +@@ -4433,6 +4433,7 @@ static void intel_ddi_encoder_shutdown(s enum phy phy = intel_port_to_phy(i915, encoder->port); intel_dp_encoder_shutdown(encoder); @@ -77,10 +77,10 @@ Signed-off-by: Patrik Jakobsson return; --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c -@@ -1247,12 +1247,13 @@ static void hsw_set_infoframes(struct in +@@ -1246,12 +1246,13 @@ static void hsw_set_infoframes(struct in void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable) { - struct drm_i915_private *dev_priv = to_i915(intel_hdmi_to_dev(hdmi)); + struct drm_i915_private *dev_priv = intel_hdmi_to_i915(hdmi); - struct i2c_adapter *adapter = - intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus); + struct i2c_adapter *adapter; @@ -93,7 +93,7 @@ Signed-off-by: Patrik Jakobsson drm_dbg_kms(&dev_priv->drm, "%s DP dual mode adaptor TMDS output\n", enable ? "Enabling" : "Disabling"); -@@ -2260,6 +2261,17 @@ int intel_hdmi_compute_config(struct int +@@ -2258,6 +2259,17 @@ int intel_hdmi_compute_config(struct int return 0; } diff --git a/patches.suse/drm-mediatek-dsi-Add-atomic-destroy-duplicate-_state.patch b/patches.suse/drm-mediatek-dsi-Add-atomic-destroy-duplicate-_state.patch new file mode 100644 index 0000000..3017c22 --- /dev/null +++ b/patches.suse/drm-mediatek-dsi-Add-atomic-destroy-duplicate-_state.patch @@ -0,0 +1,51 @@ +From eeda05b5e92f51d9a09646ecb493f0a1e872a6ef Mon Sep 17 00:00:00 2001 +From: AngeloGioacchino Del Regno +Date: Thu, 21 Jul 2022 19:27:27 +0200 +Subject: [PATCH] drm/mediatek: dsi: Add atomic {destroy,duplicate}_state, reset callbacks +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: eeda05b5e92f51d9a09646ecb493f0a1e872a6ef +Patch-mainline: v6.0-rc7 +References: git-fixes + +Add callbacks for atomic_destroy_state, atomic_duplicate_state and +atomic_reset to restore functionality of the DSI driver: this solves +vblank timeouts when another bridge is present in the chain. + +Tested bridge chain: DSI <=> ANX7625 => aux-bus panel + +Fixes: 7f6335c6a258 ("drm/mediatek: Modify dsi funcs to atomic operations") +Signed-off-by: AngeloGioacchino Del Regno +Tested-by: Chen-Yu Tsai +Reviewed-by: Nícolas F. R. A. Prado +Tested-by: Nícolas F. R. A. Prado +Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20220721172727.14624-1-angelogioacchino.delregno@collabora.com/ +Signed-off-by: Chun-Kuang Hu +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/mediatek/mtk_dsi.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c +index 9cc406e1eee1..5b624e0f5b0a 100644 +--- a/drivers/gpu/drm/mediatek/mtk_dsi.c ++++ b/drivers/gpu/drm/mediatek/mtk_dsi.c +@@ -808,10 +808,13 @@ static void mtk_dsi_bridge_atomic_post_disable(struct drm_bridge *bridge, + + static const struct drm_bridge_funcs mtk_dsi_bridge_funcs = { + .attach = mtk_dsi_bridge_attach, ++ .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_disable = mtk_dsi_bridge_atomic_disable, ++ .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, + .atomic_enable = mtk_dsi_bridge_atomic_enable, + .atomic_pre_enable = mtk_dsi_bridge_atomic_pre_enable, + .atomic_post_disable = mtk_dsi_bridge_atomic_post_disable, ++ .atomic_reset = drm_atomic_helper_bridge_reset, + .mode_set = mtk_dsi_bridge_mode_set, + }; + +-- +2.35.3 + diff --git a/patches.suse/drm-mediatek-dsi-Move-mtk_dsi_stop-call-back-to-mtk_.patch b/patches.suse/drm-mediatek-dsi-Move-mtk_dsi_stop-call-back-to-mtk_.patch new file mode 100644 index 0000000..7563c45 --- /dev/null +++ b/patches.suse/drm-mediatek-dsi-Move-mtk_dsi_stop-call-back-to-mtk_.patch @@ -0,0 +1,84 @@ +From 90144dd8b0d137d9e78ef34b3c418e51a49299ad Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?= +Date: Thu, 4 Aug 2022 15:43:25 -0400 +Subject: [PATCH] drm/mediatek: dsi: Move mtk_dsi_stop() call back to mtk_dsi_poweroff() +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 90144dd8b0d137d9e78ef34b3c418e51a49299ad +Patch-mainline: v6.0-rc7 +References: git-fixes + +As the comment right before the mtk_dsi_stop() call advises, +mtk_dsi_stop() should only be called after +mtk_drm_crtc_atomic_disable(). That's because that function calls +drm_crtc_wait_one_vblank(), which requires the vblank irq to be enabled. + +Previously mtk_dsi_stop(), being in mtk_dsi_poweroff() and guarded by a +refcount, would only be called at the end of +mtk_drm_crtc_atomic_disable(), through the call to mtk_crtc_ddp_hw_fini(). +Commit cde7e2e35c28 ("drm/mediatek: Separate poweron/poweroff from +enable/disable and define new funcs") moved the mtk_dsi_stop() call to +mtk_output_dsi_disable(), causing it to be called before +mtk_drm_crtc_atomic_disable(), and consequently generating vblank +timeout warnings during suspend. + +Move the mtk_dsi_stop() call back to mtk_dsi_poweroff() so that we have +a working vblank irq during mtk_drm_crtc_atomic_disable() and stop +getting vblank timeout warnings. + +Fixes: cde7e2e35c28 ("drm/mediatek: Separate poweron/poweroff from enable/disable and define new funcs") +Signed-off-by: Nícolas F. R. A. Prado +Tested-by: Hsin-Yi Wang +Reviewed-by: AngeloGioacchino Del Regno +Tested-by: Allen-KH Cheng +Link: http://lists.infradead.org/pipermail/linux-mediatek/2022-August/046713.html +Signed-off-by: Chun-Kuang Hu +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/mediatek/mtk_dsi.c | 21 ++++++++++----------- + 1 file changed, 10 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c +index 5b624e0f5b0a..3b7d13028fb6 100644 +--- a/drivers/gpu/drm/mediatek/mtk_dsi.c ++++ b/drivers/gpu/drm/mediatek/mtk_dsi.c +@@ -685,6 +685,16 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi) + if (--dsi->refcount != 0) + return; + ++ /* ++ * mtk_dsi_stop() and mtk_dsi_start() is asymmetric, since ++ * mtk_dsi_stop() should be called after mtk_drm_crtc_atomic_disable(), ++ * which needs irq for vblank, and mtk_dsi_stop() will disable irq. ++ * mtk_dsi_start() needs to be called in mtk_output_dsi_enable(), ++ * after dsi is fully set. ++ */ ++ mtk_dsi_stop(dsi); ++ ++ mtk_dsi_switch_to_cmd_mode(dsi, VM_DONE_INT_FLAG, 500); + mtk_dsi_reset_engine(dsi); + mtk_dsi_lane0_ulp_mode_enter(dsi); + mtk_dsi_clk_ulp_mode_enter(dsi); +@@ -735,17 +745,6 @@ static void mtk_output_dsi_disable(struct mtk_dsi *dsi) + if (!dsi->enabled) + return; + +- /* +- * mtk_dsi_stop() and mtk_dsi_start() is asymmetric, since +- * mtk_dsi_stop() should be called after mtk_drm_crtc_atomic_disable(), +- * which needs irq for vblank, and mtk_dsi_stop() will disable irq. +- * mtk_dsi_start() needs to be called in mtk_output_dsi_enable(), +- * after dsi is fully set. +- */ +- mtk_dsi_stop(dsi); +- +- mtk_dsi_switch_to_cmd_mode(dsi, VM_DONE_INT_FLAG, 500); +- + dsi->enabled = false; + } + +-- +2.35.3 + diff --git a/patches.suse/drm-meson-Correct-OSD1-global-alpha-value.patch b/patches.suse/drm-meson-Correct-OSD1-global-alpha-value.patch new file mode 100644 index 0000000..a8f5d56 --- /dev/null +++ b/patches.suse/drm-meson-Correct-OSD1-global-alpha-value.patch @@ -0,0 +1,40 @@ +From 6836829c8ea453c9e3e518e61539e35881c8ed5f Mon Sep 17 00:00:00 2001 +From: Stuart Menefy +Date: Thu, 8 Sep 2022 16:51:03 +0100 +Subject: [PATCH] drm/meson: Correct OSD1 global alpha value +Git-commit: 6836829c8ea453c9e3e518e61539e35881c8ed5f +Patch-mainline: v6.0-rc6 +References: git-fixes + +VIU_OSD1_CTRL_STAT.GLOBAL_ALPHA is a 9 bit field, so the maximum +value is 0x100 not 0xff. + +This matches the vendor kernel. + +Signed-off-by: Stuart Menefy +Fixes: bbbe775ec5b5 ("drm: Add support for Amlogic Meson Graphic Controller") +Reviewed-by: Neil Armstrong +Signed-off-by: Neil Armstrong +Link: https://patchwork.freedesktop.org/patch/msgid/20220908155103.686904-1-stuart.menefy@mathembedded.com +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/meson/meson_plane.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c +index b9ac932af8d0..03acc68abf2c 100644 +--- a/drivers/gpu/drm/meson/meson_plane.c ++++ b/drivers/gpu/drm/meson/meson_plane.c +@@ -170,7 +170,7 @@ static void meson_plane_atomic_update(struct drm_plane *plane, + + /* Enable OSD and BLK0, set max global alpha */ + priv->viu.osd1_ctrl_stat = OSD_ENABLE | +- (0xFF << OSD_GLOBAL_ALPHA_SHIFT) | ++ (0x100 << OSD_GLOBAL_ALPHA_SHIFT) | + OSD_BLK0_ENABLE; + + priv->viu.osd1_ctrl_stat2 = readl(priv->io_base + +-- +2.35.3 + diff --git a/patches.suse/drm-meson-Fix-OSD1-RGB-to-YCbCr-coefficient.patch b/patches.suse/drm-meson-Fix-OSD1-RGB-to-YCbCr-coefficient.patch new file mode 100644 index 0000000..88c0d02 --- /dev/null +++ b/patches.suse/drm-meson-Fix-OSD1-RGB-to-YCbCr-coefficient.patch @@ -0,0 +1,47 @@ +From 6463d3930ba5b6addcfc8f80a4543976a2fc7656 Mon Sep 17 00:00:00 2001 +From: Stuart Menefy +Date: Thu, 8 Sep 2022 16:52:43 +0100 +Subject: [PATCH] drm/meson: Fix OSD1 RGB to YCbCr coefficient +Git-commit: 6463d3930ba5b6addcfc8f80a4543976a2fc7656 +Patch-mainline: v6.0-rc6 +References: git-fixes + +VPP_WRAP_OSD1_MATRIX_COEF22.Coeff22 is documented as being bits 0-12, +not 16-28. + +Without this the output tends to have a pink hue, changing it results +in better color accuracy. + +The vendor kernel doesn't use this register. However the code which +sets VIU2_OSD1_MATRIX_COEF22 also uses bits 0-12. There is a slightly +different style of registers for configuring some of the other matrices, +which do use bits 16-28 for this coefficient, but those have names +ending in MATRIX_COEF22_30, and this is not one of those. + +Signed-off-by: Stuart Menefy +Fixes: 728883948b0d ("drm/meson: Add G12A Support for VIU setup") +Reviewed-by: Neil Armstrong +Signed-off-by: Neil Armstrong +Link: https://patchwork.freedesktop.org/patch/msgid/20220908155243.687143-1-stuart.menefy@mathembedded.com +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/meson/meson_viu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/meson/meson_viu.c b/drivers/gpu/drm/meson/meson_viu.c +index bb7e109534de..d4b907889a21 100644 +--- a/drivers/gpu/drm/meson/meson_viu.c ++++ b/drivers/gpu/drm/meson/meson_viu.c +@@ -94,7 +94,7 @@ static void meson_viu_set_g12a_osd1_matrix(struct meson_drm *priv, + priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF11_12)); + writel(((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff), + priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF20_21)); +- writel((m[11] & 0x1fff) << 16, ++ writel((m[11] & 0x1fff), + priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF22)); + + writel(((m[18] & 0xfff) << 16) | (m[19] & 0xfff), +-- +2.35.3 + diff --git a/patches.suse/drm-mipi-dsi-Detach-devices-when-removing-the-host.patch b/patches.suse/drm-mipi-dsi-Detach-devices-when-removing-the-host.patch new file mode 100644 index 0000000..2d37096 --- /dev/null +++ b/patches.suse/drm-mipi-dsi-Detach-devices-when-removing-the-host.patch @@ -0,0 +1,41 @@ +From 668a8f17b5290d04ef7343636a5588a0692731a1 Mon Sep 17 00:00:00 2001 +From: Maxime Ripard +Date: Mon, 11 Jul 2022 19:38:31 +0200 +Subject: [PATCH] drm/mipi-dsi: Detach devices when removing the host +Git-commit: 668a8f17b5290d04ef7343636a5588a0692731a1 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Whenever the MIPI-DSI host is unregistered, the code of +mipi_dsi_host_unregister() loops over every device currently found on that +bus and will unregister it. + +However, it doesn't detach it from the bus first, which leads to all kind +of resource leaks if the host wants to perform some clean up whenever a +device is detached. + +Fixes: 068a00233969 ("drm: Add MIPI DSI bus support") +Acked-by: Thomas Zimmermann +Signed-off-by: Maxime Ripard +Link: https://lore.kernel.org/r/20220711173939.1132294-2-maxime@cerno.tech +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/drm_mipi_dsi.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c +index 2e25804d6ffa..3ec02748d56f 100644 +--- a/drivers/gpu/drm/drm_mipi_dsi.c ++++ b/drivers/gpu/drm/drm_mipi_dsi.c +@@ -346,6 +346,7 @@ static int mipi_dsi_remove_device_fn(struct device *dev, void *priv) + { + struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); + ++ mipi_dsi_detach(dsi); + mipi_dsi_device_unregister(dsi); + + return 0; +-- +2.35.3 + diff --git a/patches.suse/drm-msm-Make-.remove-and-.shutdown-HW-shutdown-consi.patch b/patches.suse/drm-msm-Make-.remove-and-.shutdown-HW-shutdown-consi.patch new file mode 100644 index 0000000..0891bb7 --- /dev/null +++ b/patches.suse/drm-msm-Make-.remove-and-.shutdown-HW-shutdown-consi.patch @@ -0,0 +1,158 @@ +From 0a58d2ae572adaec8d046f8d35b40c2c32ac7468 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Tue, 16 Aug 2022 15:46:12 +0200 +Subject: [PATCH] drm/msm: Make .remove and .shutdown HW shutdown consistent +Git-commit: 0a58d2ae572adaec8d046f8d35b40c2c32ac7468 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Drivers' .remove and .shutdown callbacks are executed on different code +paths. The former is called when a device is removed from the bus, while +the latter is called at system shutdown time to quiesce the device. + +This means that some overlap exists between the two, because both have to +take care of properly shutting down the hardware. But currently the logic +used in these two callbacks isn't consistent in msm drivers, which could +lead to kernel panic. + +For example, on .remove the component is deleted and its .unbind callback +leads to the hardware being shutdown but only if the DRM device has been +marked as registered. + +That check doesn't exist in the .shutdown logic and this can lead to the +driver calling drm_atomic_helper_shutdown() for a DRM device that hasn't +been properly initialized. + +A situation like this can happen if drivers for expected sub-devices fail +to probe, since the .bind callback will never be executed. If that is the +case, drm_atomic_helper_shutdown() will attempt to take mutexes that are +only initialized if drm_mode_config_init() is called during a device bind. + +This bug was attempted to be fixed in commit 623f279c7781 ("drm/msm: fix +shutdown hook in case GPU components failed to bind"), but unfortunately +it still happens in some cases as the one mentioned above, i.e: + + systemd-shutdown[1]: Powering off. + kvm: exiting hardware virtualization + platform wifi-firmware.0: Removing from iommu group 12 + platform video-firmware.0: Removing from iommu group 10 + ------------[ cut here ]------------ + WARNING: CPU: 6 PID: 1 at drivers/gpu/drm/drm_modeset_lock.c:317 drm_modeset_lock_all_ctx+0x3c4/0x3d0 + ... + Hardware name: Google CoachZ (rev3+) (DT) + pstate: a0400009 (NzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) + pc : drm_modeset_lock_all_ctx+0x3c4/0x3d0 + lr : drm_modeset_lock_all_ctx+0x48/0x3d0 + sp : ffff80000805bb80 + x29: ffff80000805bb80 x28: ffff327c00128000 x27: 0000000000000000 + x26: 0000000000000000 x25: 0000000000000001 x24: ffffc95d820ec030 + x23: ffff327c00bbd090 x22: ffffc95d8215eca0 x21: ffff327c039c5800 + x20: ffff327c039c5988 x19: ffff80000805bbe8 x18: 0000000000000034 + x17: 000000040044ffff x16: ffffc95d80cac920 x15: 0000000000000000 + x14: 0000000000000315 x13: 0000000000000315 x12: 0000000000000000 + x11: 0000000000000000 x10: 0000000000000000 x9 : 0000000000000000 + x8 : ffff80000805bc28 x7 : 0000000000000000 x6 : 0000000000000000 + x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000 + x2 : ffff327c00128000 x1 : 0000000000000000 x0 : ffff327c039c59b0 + Call trace: + drm_modeset_lock_all_ctx+0x3c4/0x3d0 + drm_atomic_helper_shutdown+0x70/0x134 + msm_drv_shutdown+0x30/0x40 + platform_shutdown+0x28/0x40 + device_shutdown+0x148/0x350 + kernel_power_off+0x38/0x80 + __do_sys_reboot+0x288/0x2c0 + __arm64_sys_reboot+0x28/0x34 + invoke_syscall+0x48/0x114 + el0_svc_common.constprop.0+0x44/0xec + do_el0_svc+0x2c/0xc0 + el0_svc+0x2c/0x84 + el0t_64_sync_handler+0x11c/0x150 + el0t_64_sync+0x18c/0x190 + ---[ end trace 0000000000000000 ]--- + Unable to handle kernel NULL pointer dereference at virtual address 0000000000000018 + Mem abort info: + ESR = 0x0000000096000004 + EC = 0x25: DABT (current EL), IL = 32 bits + SET = 0, FnV = 0 + EA = 0, S1PTW = 0 + FSC = 0x04: level 0 translation fault + Data abort info: + ISV = 0, ISS = 0x00000004 + CM = 0, WnR = 0 + user pgtable: 4k pages, 48-bit VAs, pgdp=000000010eab1000 + [0000000000000018] pgd=0000000000000000, p4d=0000000000000000 + Internal error: Oops: 96000004 [#1] PREEMPT SMP + ... + Hardware name: Google CoachZ (rev3+) (DT) + pstate: a0400009 (NzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) + pc : ww_mutex_lock+0x28/0x32c + lr : drm_modeset_lock_all_ctx+0x1b0/0x3d0 + sp : ffff80000805bb50 + x29: ffff80000805bb50 x28: ffff327c00128000 x27: 0000000000000000 + x26: 0000000000000000 x25: 0000000000000001 x24: 0000000000000018 + x23: ffff80000805bc10 x22: ffff327c039c5ad8 x21: ffff327c039c5800 + x20: ffff80000805bbe8 x19: 0000000000000018 x18: 0000000000000034 + x17: 000000040044ffff x16: ffffc95d80cac920 x15: 0000000000000000 + x14: 0000000000000315 x13: 0000000000000315 x12: 0000000000000000 + x11: 0000000000000000 x10: 0000000000000000 x9 : 0000000000000000 + x8 : ffff80000805bc28 x7 : 0000000000000000 x6 : 0000000000000000 + x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000 + x2 : ffff327c00128000 x1 : 0000000000000000 x0 : 0000000000000018 + Call trace: + ww_mutex_lock+0x28/0x32c + drm_modeset_lock_all_ctx+0x1b0/0x3d0 + drm_atomic_helper_shutdown+0x70/0x134 + msm_drv_shutdown+0x30/0x40 + platform_shutdown+0x28/0x40 + device_shutdown+0x148/0x350 + kernel_power_off+0x38/0x80 + __do_sys_reboot+0x288/0x2c0 + __arm64_sys_reboot+0x28/0x34 + invoke_syscall+0x48/0x114 + el0_svc_common.constprop.0+0x44/0xec + do_el0_svc+0x2c/0xc0 + el0_svc+0x2c/0x84 + el0t_64_sync_handler+0x11c/0x150 + el0t_64_sync+0x18c/0x190 + Code: aa0103f4 d503201f d2800001 aa0103e3 (c8e37c02) + ---[ end trace 0000000000000000 ]--- + Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b + Kernel Offset: 0x495d77c00000 from 0xffff800008000000 + PHYS_OFFSET: 0xffffcd8500000000 + CPU features: 0x800,00c2a015,19801c82 + Memory Limit: none + ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b ]--- + +Fixes: 9d5cbf5fe46e ("drm/msm: add shutdown support for display platform_driver") +Signed-off-by: Javier Martinez Canillas +Reviewed-by: Abhinav Kumar +Link: https://patchwork.freedesktop.org/patch/msgid/20220816134612.916527-1-javierm@redhat.com +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/msm/msm_drv.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +--- a/drivers/gpu/drm/msm/msm_drv.c ++++ b/drivers/gpu/drm/msm/msm_drv.c +@@ -1358,10 +1358,15 @@ static void msm_pdev_shutdown(struct pla + struct drm_device *drm = platform_get_drvdata(pdev); + struct msm_drm_private *priv = drm ? drm->dev_private : NULL; + +- if (!priv || !priv->kms) +- return; +- +- drm_atomic_helper_shutdown(drm); ++ /* ++ * Shutdown the hw if we're far enough along where things might be on. ++ * If we run this too early, we'll end up panicking in any variety of ++ * places. Since we don't register the drm device until late in ++ * msm_drm_init, drm_dev->registered is used as an indicator that the ++ * shutdown will be successful. ++ */ ++ if (drm && drm->registered) ++ drm_atomic_helper_shutdown(drm); + } + + static const struct of_device_id dt_match[] = { diff --git a/patches.suse/drm-msm-dp-Silence-inconsistent-indent-warning.patch b/patches.suse/drm-msm-dp-Silence-inconsistent-indent-warning.patch new file mode 100644 index 0000000..f102fee --- /dev/null +++ b/patches.suse/drm-msm-dp-Silence-inconsistent-indent-warning.patch @@ -0,0 +1,51 @@ +From e40261156829d66ec4644243bc31e1831733638f Mon Sep 17 00:00:00 2001 +From: Stephen Boyd +Date: Tue, 23 Aug 2022 14:23:02 -0700 +Subject: [PATCH] drm/msm/dp: Silence inconsistent indent warning +Git-commit: e40261156829d66ec4644243bc31e1831733638f +Patch-mainline: v6.1-rc1 +References: git-fixes + +Build robots complain + + smatch warnings: + drivers/gpu/drm/msm/dp/dp_link.c:969 dp_link_process_link_status_update() warn: inconsistent indenting + +Fix it along with a trailing space from the same commit. + +Cc: Kuogee Hsieh +Fixes: ea530388e64b ("drm/msm/dp: skip checking LINK_STATUS_UPDATED bit") +Reported-by: kernel test robot +Signed-off-by: Stephen Boyd +Reviewed-by: Abhinav Kumar +Patchwork: https://patchwork.freedesktop.org/patch/498954/ +Link: https://lore.kernel.org/r/20220823212302.1744145-1-swboyd@chromium.org +Signed-off-by: Dmitry Baryshkov +Signed-off-by: Rob Clark +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/msm/dp/dp_link.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/drivers/gpu/drm/msm/dp/dp_link.c ++++ b/drivers/gpu/drm/msm/dp/dp_link.c +@@ -780,7 +780,7 @@ static int dp_link_process_link_training + link->request.test_lane_count); + + link->dp_link.link_params.num_lanes = link->request.test_lane_count; +- link->dp_link.link_params.rate = ++ link->dp_link.link_params.rate = + drm_dp_bw_code_to_link_rate(link->request.test_link_rate); + + return 0; +@@ -954,8 +954,7 @@ static int dp_link_process_link_status_u + if (channel_eq_done && clock_recovery_done) + return -EINVAL; + +- +- return 0; ++ return 0; + } + + /** diff --git a/patches.suse/drm-msm-dp-correct-1.62G-link-rate-at-dp_catalog_ctr.patch b/patches.suse/drm-msm-dp-correct-1.62G-link-rate-at-dp_catalog_ctr.patch new file mode 100644 index 0000000..cf5f1d0 --- /dev/null +++ b/patches.suse/drm-msm-dp-correct-1.62G-link-rate-at-dp_catalog_ctr.patch @@ -0,0 +1,50 @@ +From aa0bff10af1c4b92e6b56e3e1b7f81c660d3ba78 Mon Sep 17 00:00:00 2001 +From: Kuogee Hsieh +Date: Wed, 24 Aug 2022 13:15:50 -0700 +Subject: [PATCH] drm/msm/dp: correct 1.62G link rate at dp_catalog_ctrl_config_msa() +Git-commit: aa0bff10af1c4b92e6b56e3e1b7f81c660d3ba78 +Patch-mainline: v6.1-rc1 +References: git-fixes + +At current implementation there is an extra 0 at 1.62G link rate which +cause no correct pixel_div selected for 1.62G link rate to calculate +mvid and nvid. This patch delete the extra 0 to have mvid and nvid be +calculated correctly. + +Changes in v2: +-- fix Fixes tag's text + +Changes in v3: +-- fix misspelling of "Reviewed-by" + +Fixes: 937f941ca06f ("drm/msm/dp: Use qmp phy for DP PLL and PHY") +Signed-off-by: Kuogee Hsieh +Reviewed-by: Stephen Boyd +Reviewed-by: Abhinav Kumar +Patchwork: https://patchwork.freedesktop.org/patch/499328/ +Link: https://lore.kernel.org/r/1661372150-3764-1-git-send-email-quic_khsieh@quicinc.com +[db: rewrapped commit message] +Signed-off-by: Dmitry Baryshkov +Signed-off-by: Rob Clark +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/msm/dp/dp_catalog.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c +index 7257515871a9..676279d0ca8d 100644 +--- a/drivers/gpu/drm/msm/dp/dp_catalog.c ++++ b/drivers/gpu/drm/msm/dp/dp_catalog.c +@@ -431,7 +431,7 @@ void dp_catalog_ctrl_config_msa(struct dp_catalog *dp_catalog, + + if (rate == link_rate_hbr3) + pixel_div = 6; +- else if (rate == 1620000 || rate == 270000) ++ else if (rate == 162000 || rate == 270000) + pixel_div = 2; + else if (rate == link_rate_hbr2) + pixel_div = 4; +-- +2.35.3 + diff --git a/patches.suse/drm-msm-dpu-Fix-comment-typo.patch b/patches.suse/drm-msm-dpu-Fix-comment-typo.patch new file mode 100644 index 0000000..47fe862 --- /dev/null +++ b/patches.suse/drm-msm-dpu-Fix-comment-typo.patch @@ -0,0 +1,40 @@ +From fa91ed0c555b0789c24dfa26c169d3f965db656e Mon Sep 17 00:00:00 2001 +From: Jason Wang +Date: Mon, 25 Jul 2022 04:42:42 +0800 +Subject: [PATCH] drm/msm/dpu: Fix comment typo +Git-commit: fa91ed0c555b0789c24dfa26c169d3f965db656e +Patch-mainline: v6.1-rc1 +References: git-fixes + +The double `be' is duplicated in the comment, remove one. + +Signed-off-by: Jason Wang +Fixes: 25fdd5933e4c ("drm/msm: Add SDM845 DPU support") +Reviewed-by: Abhinav Kumar +Reviewed-by: Dmitry Baryshkov +Patchwork: https://patchwork.freedesktop.org/patch/497853/ +Link: https://lore.kernel.org/r/20220724204242.4107-1-wangborong@cdjrlc.com +Signed-off-by: Dmitry Baryshkov +Signed-off-by: Rob Clark +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +index 71fe4c505f5b..38aa38ab1568 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +@@ -76,7 +76,7 @@ enum { + + /** + * MDP TOP BLOCK features +- * @DPU_MDP_PANIC_PER_PIPE Panic configuration needs to be be done per pipe ++ * @DPU_MDP_PANIC_PER_PIPE Panic configuration needs to be done per pipe + * @DPU_MDP_10BIT_SUPPORT, Chipset supports 10 bit pixel formats + * @DPU_MDP_BWC, MDSS HW supports Bandwidth compression. + * @DPU_MDP_UBWC_1_0, This chipsets supports Universal Bandwidth +-- +2.35.3 + diff --git a/patches.suse/drm-msm-dpu-index-dpu_kms-hw_vbif-using-vbif_idx.patch b/patches.suse/drm-msm-dpu-index-dpu_kms-hw_vbif-using-vbif_idx.patch new file mode 100644 index 0000000..9330ff5 --- /dev/null +++ b/patches.suse/drm-msm-dpu-index-dpu_kms-hw_vbif-using-vbif_idx.patch @@ -0,0 +1,126 @@ +From 7538f80ae0d98bf51eb89eee5344aec219902d42 Mon Sep 17 00:00:00 2001 +From: Dmitry Baryshkov +Date: Wed, 15 Jun 2022 15:57:01 +0300 +Subject: [PATCH] drm/msm/dpu: index dpu_kms->hw_vbif using vbif_idx +Git-commit: 7538f80ae0d98bf51eb89eee5344aec219902d42 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Remove loops over hw_vbif. Instead always VBIF's idx as an index in the +array. This fixes an error in dpu_kms_hw_init(), where we fill +dpu_kms->hw_vbif[i], but check for an error pointer at +dpu_kms->hw_vbif[vbif_idx]. + +Fixes: 25fdd5933e4c ("drm/msm: Add SDM845 DPU support") +Signed-off-by: Dmitry Baryshkov +Reviewed-by: Abhinav Kumar +Patchwork: https://patchwork.freedesktop.org/patch/489569/ +Link: https://lore.kernel.org/r/20220615125703.24647-1-dmitry.baryshkov@linaro.org +Signed-off-by: Rob Clark +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 12 ++++------ + drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c | 29 +++++++++++------------- + 2 files changed, 18 insertions(+), 23 deletions(-) + +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +index 8646fd0603cb..c99c7a218ddb 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +@@ -823,12 +823,10 @@ static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms) + _dpu_kms_mmu_destroy(dpu_kms); + + if (dpu_kms->catalog) { +- for (i = 0; i < dpu_kms->catalog->vbif_count; i++) { +- u32 vbif_idx = dpu_kms->catalog->vbif[i].id; +- +- if ((vbif_idx < VBIF_MAX) && dpu_kms->hw_vbif[vbif_idx]) { +- dpu_hw_vbif_destroy(dpu_kms->hw_vbif[vbif_idx]); +- dpu_kms->hw_vbif[vbif_idx] = NULL; ++ for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) { ++ if (dpu_kms->hw_vbif[i]) { ++ dpu_hw_vbif_destroy(dpu_kms->hw_vbif[i]); ++ dpu_kms->hw_vbif[i] = NULL; + } + } + } +@@ -1110,7 +1108,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) + for (i = 0; i < dpu_kms->catalog->vbif_count; i++) { + u32 vbif_idx = dpu_kms->catalog->vbif[i].id; + +- dpu_kms->hw_vbif[i] = dpu_hw_vbif_init(vbif_idx, ++ dpu_kms->hw_vbif[vbif_idx] = dpu_hw_vbif_init(vbif_idx, + dpu_kms->vbif[vbif_idx], dpu_kms->catalog); + if (IS_ERR_OR_NULL(dpu_kms->hw_vbif[vbif_idx])) { + rc = PTR_ERR(dpu_kms->hw_vbif[vbif_idx]); +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c +index 21d20373eb8b..a18fb649301c 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c +@@ -11,6 +11,14 @@ + #include "dpu_hw_vbif.h" + #include "dpu_trace.h" + ++static struct dpu_hw_vbif *dpu_get_vbif(struct dpu_kms *dpu_kms, enum dpu_vbif vbif_idx) ++{ ++ if (vbif_idx < ARRAY_SIZE(dpu_kms->hw_vbif)) ++ return dpu_kms->hw_vbif[vbif_idx]; ++ ++ return NULL; ++} ++ + /** + * _dpu_vbif_wait_for_xin_halt - wait for the xin to halt + * @vbif: Pointer to hardware vbif driver +@@ -148,20 +156,15 @@ static u32 _dpu_vbif_get_ot_limit(struct dpu_hw_vbif *vbif, + void dpu_vbif_set_ot_limit(struct dpu_kms *dpu_kms, + struct dpu_vbif_set_ot_params *params) + { +- struct dpu_hw_vbif *vbif = NULL; ++ struct dpu_hw_vbif *vbif; + struct dpu_hw_mdp *mdp; + bool forced_on = false; + u32 ot_lim; +- int ret, i; ++ int ret; + + mdp = dpu_kms->hw_mdp; + +- for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) { +- if (dpu_kms->hw_vbif[i] && +- dpu_kms->hw_vbif[i]->idx == params->vbif_idx) +- vbif = dpu_kms->hw_vbif[i]; +- } +- ++ vbif = dpu_get_vbif(dpu_kms, params->vbif_idx); + if (!vbif || !mdp) { + DRM_DEBUG_ATOMIC("invalid arguments vbif %d mdp %d\n", + vbif != NULL, mdp != NULL); +@@ -204,7 +207,7 @@ void dpu_vbif_set_ot_limit(struct dpu_kms *dpu_kms, + void dpu_vbif_set_qos_remap(struct dpu_kms *dpu_kms, + struct dpu_vbif_set_qos_params *params) + { +- struct dpu_hw_vbif *vbif = NULL; ++ struct dpu_hw_vbif *vbif; + struct dpu_hw_mdp *mdp; + bool forced_on = false; + const struct dpu_vbif_qos_tbl *qos_tbl; +@@ -216,13 +219,7 @@ void dpu_vbif_set_qos_remap(struct dpu_kms *dpu_kms, + } + mdp = dpu_kms->hw_mdp; + +- for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) { +- if (dpu_kms->hw_vbif[i] && +- dpu_kms->hw_vbif[i]->idx == params->vbif_idx) { +- vbif = dpu_kms->hw_vbif[i]; +- break; +- } +- } ++ vbif = dpu_get_vbif(dpu_kms, params->vbif_idx); + + if (!vbif || !vbif->cap) { + DPU_ERROR("invalid vbif %d\n", params->vbif_idx); +-- +2.35.3 + diff --git a/patches.suse/drm-msm-rd-Fix-FIFO-full-deadlock.patch b/patches.suse/drm-msm-rd-Fix-FIFO-full-deadlock.patch new file mode 100644 index 0000000..c704902 --- /dev/null +++ b/patches.suse/drm-msm-rd-Fix-FIFO-full-deadlock.patch @@ -0,0 +1,34 @@ +From 174974d8463b77c2b4065e98513adb204e64de7d Mon Sep 17 00:00:00 2001 +From: Rob Clark +Date: Sun, 7 Aug 2022 09:09:01 -0700 +Subject: [PATCH] drm/msm/rd: Fix FIFO-full deadlock +Git-commit: 174974d8463b77c2b4065e98513adb204e64de7d +Patch-mainline: v6.0-rc4 +References: git-fixes + +If the previous thing cat'ing $debugfs/rd left the FIFO full, then +subsequent open could deadlock in rd_write() (because open is blocked, +not giving a chance for read() to consume any data in the FIFO). Also +it is generally a good idea to clear out old data from the FIFO. + +Signed-off-by: Rob Clark +Patchwork: https://patchwork.freedesktop.org/patch/496706/ +Link: https://lore.kernel.org/r/20220807160901.2353471-2-robdclark@gmail.com +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/msm/msm_rd.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/gpu/drm/msm/msm_rd.c ++++ b/drivers/gpu/drm/msm/msm_rd.c +@@ -191,6 +191,9 @@ static int rd_open(struct inode *inode, + file->private_data = rd; + rd->open = true; + ++ /* Reset fifo to clear any previously unread data: */ ++ rd->fifo.head = rd->fifo.tail = 0; ++ + /* the parsing tools need to know gpu-id to know which + * register database to load. + */ diff --git a/patches.suse/drm-nouveau-fix-a-use-after-free-in-nouveau_gem_prim.patch b/patches.suse/drm-nouveau-fix-a-use-after-free-in-nouveau_gem_prim.patch new file mode 100644 index 0000000..5cadd54 --- /dev/null +++ b/patches.suse/drm-nouveau-fix-a-use-after-free-in-nouveau_gem_prim.patch @@ -0,0 +1,44 @@ +From 540dfd188ea2940582841c1c220bd035a7db0e51 Mon Sep 17 00:00:00 2001 +From: Jianglei Nie +Date: Tue, 5 Jul 2022 21:25:46 +0800 +Subject: [PATCH] drm/nouveau: fix a use-after-free in nouveau_gem_prime_import_sg_table() +Git-commit: 540dfd188ea2940582841c1c220bd035a7db0e51 +Patch-mainline: v6.1-rc1 +References: git-fixes + +nouveau_bo_init() is backed by ttm_bo_init() and ferries its return code +back to the caller. On failures, ttm will call nouveau_bo_del_ttm() and +free the memory.Thus, when nouveau_bo_init() returns an error, the gem +object has already been released. Then the call to nouveau_bo_ref() will +use the freed "nvbo->bo" and lead to a use-after-free bug. + +We should delete the call to nouveau_bo_ref() to avoid the use-after-free. + +Signed-off-by: Jianglei Nie +Reviewed-by: Lyude Paul +Signed-off-by: Lyude Paul +Fixes: 019cbd4a4feb ("drm/nouveau: Initialize GEM object before TTM object") +Cc: Thierry Reding +Cc: # v5.4+ +Link: https://patchwork.freedesktop.org/patch/msgid/20220705132546.2247677-1-niejianglei2021@163.com +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/nouveau/nouveau_prime.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/gpu/drm/nouveau/nouveau_prime.c b/drivers/gpu/drm/nouveau/nouveau_prime.c +index 347488685f74..9608121e49b7 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_prime.c ++++ b/drivers/gpu/drm/nouveau/nouveau_prime.c +@@ -71,7 +71,6 @@ struct drm_gem_object *nouveau_gem_prime_import_sg_table(struct drm_device *dev, + ret = nouveau_bo_init(nvbo, size, align, NOUVEAU_GEM_DOMAIN_GART, + sg, robj); + if (ret) { +- nouveau_bo_ref(NULL, &nvbo); + obj = ERR_PTR(ret); + goto unlock; + } +-- +2.35.3 + diff --git a/patches.suse/drm-omap-dss-Fix-refcount-leak-bugs.patch b/patches.suse/drm-omap-dss-Fix-refcount-leak-bugs.patch new file mode 100644 index 0000000..61e3072 --- /dev/null +++ b/patches.suse/drm-omap-dss-Fix-refcount-leak-bugs.patch @@ -0,0 +1,51 @@ +From 8b42057e62120813ebe9274f508fa785b7cab33a Mon Sep 17 00:00:00 2001 +From: Liang He +Date: Fri, 22 Jul 2022 22:43:48 +0800 +Subject: [PATCH] drm/omap: dss: Fix refcount leak bugs +Git-commit: 8b42057e62120813ebe9274f508fa785b7cab33a +Patch-mainline: v6.1-rc1 +References: git-fixes + +In dss_init_ports() and __dss_uninit_ports(), we should call +of_node_put() for the reference returned by of_graph_get_port_by_id() +in fail path or when it is not used anymore. + +Fixes: 09bffa6e5192 ("drm: omap: use common OF graph helpers") +Signed-off-by: Liang He +Signed-off-by: Tomi Valkeinen +Link: https://patchwork.freedesktop.org/patch/msgid/20220722144348.1306569-1-windhl@126.com +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/omapdrm/dss/dss.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c +index 0399f3390a0a..c4febb861910 100644 +--- a/drivers/gpu/drm/omapdrm/dss/dss.c ++++ b/drivers/gpu/drm/omapdrm/dss/dss.c +@@ -1176,6 +1176,7 @@ static void __dss_uninit_ports(struct dss_device *dss, unsigned int num_ports) + default: + break; + } ++ of_node_put(port); + } + } + +@@ -1208,11 +1209,13 @@ static int dss_init_ports(struct dss_device *dss) + default: + break; + } ++ of_node_put(port); + } + + return 0; + + error: ++ of_node_put(port); + __dss_uninit_ports(dss, i); + return r; + } +-- +2.35.3 + diff --git a/patches.suse/drm-panel-simple-Fix-innolux_g121i1_l01-bus_format.patch b/patches.suse/drm-panel-simple-Fix-innolux_g121i1_l01-bus_format.patch new file mode 100644 index 0000000..20c28f1 --- /dev/null +++ b/patches.suse/drm-panel-simple-Fix-innolux_g121i1_l01-bus_format.patch @@ -0,0 +1,38 @@ +From a7c48a0ab87ae52c087d663e83e56b8225ac4cce Mon Sep 17 00:00:00 2001 +From: Heiko Schocher +Date: Fri, 26 Aug 2022 13:50:21 -0300 +Subject: [PATCH] drm/panel: simple: Fix innolux_g121i1_l01 bus_format +Git-commit: a7c48a0ab87ae52c087d663e83e56b8225ac4cce +Patch-mainline: v6.0-rc7 +References: git-fixes + +innolux_g121i1_l01 sets bpc to 6, so use the corresponding bus format: +MEDIA_BUS_FMT_RGB666_1X7X3_SPWG. + +Fixes: 4ae13e486866 ("drm/panel: simple: Add more properties to Innolux G121I1-L01") +Signed-off-by: Heiko Schocher +Signed-off-by: Fabio Estevam +Signed-off-by: Marek Vasut +Link: https://patchwork.freedesktop.org/patch/msgid/20220826165021.1592532-1-festevam@denx.de +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/panel/panel-simple.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c +index ff5e1a44c43a..1e716c23019a 100644 +--- a/drivers/gpu/drm/panel/panel-simple.c ++++ b/drivers/gpu/drm/panel/panel-simple.c +@@ -2257,7 +2257,7 @@ static const struct panel_desc innolux_g121i1_l01 = { + .enable = 200, + .disable = 20, + }, +- .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, ++ .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, + .connector_type = DRM_MODE_CONNECTOR_LVDS, + }; + +-- +2.35.3 + diff --git a/patches.suse/drm-panfrost-devfreq-set-opp-to-the-recommended-one-.patch b/patches.suse/drm-panfrost-devfreq-set-opp-to-the-recommended-one-.patch new file mode 100644 index 0000000..bc8dea1 --- /dev/null +++ b/patches.suse/drm-panfrost-devfreq-set-opp-to-the-recommended-one-.patch @@ -0,0 +1,65 @@ +From d76034a427a2660b080bc155e4fd8f6393eefb48 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=A9ron?= +Date: Tue, 6 Sep 2022 17:30:33 +0200 +Subject: [PATCH] drm/panfrost: devfreq: set opp to the recommended one to configure regulator +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: d76034a427a2660b080bc155e4fd8f6393eefb48 +Patch-mainline: v6.0-rc5 +References: git-fixes + +Enabling panfrost GPU OPP with dynamic regulator will make OPP +responsible to enable and configure it. + +Unfortunately OPP configure and enable the regulator when an OPP +is asked to be set, which is not the case during +panfrost_devfreq_init(). + +This leave the regulator unconfigured and if no GPU load is +triggered, no OPP is asked to be set which make the regulator framework +switching it off during regulator_late_cleanup() without +noticing and therefore make the board hang as any access to GPU +memory space make bus locks up. + +Call dev_pm_opp_set_opp() with the recommend OPP in +panfrost_devfreq_init() to enable the regulator, this will properly +configure and enable the regulator and will avoid any switch off +by regulator_late_cleanup(). + +Suggested-by: Viresh Kumar +Signed-off-by: Clément Péron +Reviewed-by: Steven Price +Signed-off-by: Steven Price +Link: https://patchwork.freedesktop.org/patch/msgid/20220906153034.153321-5-peron.clem@gmail.com +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/panfrost/panfrost_devfreq.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c b/drivers/gpu/drm/panfrost/panfrost_devfreq.c +index 5110cd9b2425..fe5f12f16a63 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c ++++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c +@@ -131,6 +131,17 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev) + return PTR_ERR(opp); + + panfrost_devfreq_profile.initial_freq = cur_freq; ++ ++ /* ++ * Set the recommend OPP this will enable and configure the regulator ++ * if any and will avoid a switch off by regulator_late_cleanup() ++ */ ++ ret = dev_pm_opp_set_opp(dev, opp); ++ if (ret) { ++ DRM_DEV_ERROR(dev, "Couldn't set recommended OPP\n"); ++ return ret; ++ } ++ + dev_pm_opp_put(opp); + + /* +-- +2.35.3 + diff --git a/patches.suse/drm-pl111-Add-of_node_put-when-breaking-out-of-for_e.patch b/patches.suse/drm-pl111-Add-of_node_put-when-breaking-out-of-for_e.patch new file mode 100644 index 0000000..5d481d5 --- /dev/null +++ b/patches.suse/drm-pl111-Add-of_node_put-when-breaking-out-of-for_e.patch @@ -0,0 +1,40 @@ +From e0686dc6f2252e009c455fe99e2ce9d62a60eb47 Mon Sep 17 00:00:00 2001 +From: Liang He +Date: Mon, 11 Jul 2022 21:15:50 +0800 +Subject: [PATCH] drm:pl111: Add of_node_put() when breaking out of for_each_available_child_of_node() +Git-commit: e0686dc6f2252e009c455fe99e2ce9d62a60eb47 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The reference 'child' in the iteration of for_each_available_child_of_node() +is only escaped out into a local variable which is only used to check +its value. So we still need to the of_node_put() when breaking of the +for_each_available_child_of_node() which will automatically increase +and decrease the refcount. + +Fixes: ca454bd42dc2 ("drm/pl111: Support the Versatile Express") +Signed-off-by: Liang He +Reviewed-by: Rob Herring +Signed-off-by: Daniel Vetter +Link: https://patchwork.freedesktop.org/patch/msgid/20220711131550.361350-1-windhl@126.com +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/pl111/pl111_versatile.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/pl111/pl111_versatile.c b/drivers/gpu/drm/pl111/pl111_versatile.c +index efb01a554574..1b436b75fd39 100644 +--- a/drivers/gpu/drm/pl111/pl111_versatile.c ++++ b/drivers/gpu/drm/pl111/pl111_versatile.c +@@ -404,6 +404,7 @@ static int pl111_vexpress_clcd_init(struct device *dev, struct device_node *np, + if (of_device_is_compatible(child, "arm,pl111")) { + has_coretile_clcd = true; + ct_clcd = child; ++ of_node_put(child); + break; + } + if (of_device_is_compatible(child, "arm,hdlcd")) { +-- +2.35.3 + diff --git a/patches.suse/drm-radeon-add-a-force-flush-to-delay-work-when-rade.patch b/patches.suse/drm-radeon-add-a-force-flush-to-delay-work-when-rade.patch new file mode 100644 index 0000000..5c15ab1 --- /dev/null +++ b/patches.suse/drm-radeon-add-a-force-flush-to-delay-work-when-rade.patch @@ -0,0 +1,78 @@ +From f461950fdc374a3ada5a63c669d997de4600dffe Mon Sep 17 00:00:00 2001 +From: Zhenneng Li +Date: Thu, 11 Aug 2022 15:25:40 +0800 +Subject: [PATCH] drm/radeon: add a force flush to delay work when radeon +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: f461950fdc374a3ada5a63c669d997de4600dffe +Patch-mainline: v6.0-rc3 +References: git-fixes + +Although radeon card fence and wait for gpu to finish processing current batch rings, +there is still a corner case that radeon lockup work queue may not be fully flushed, +and meanwhile the radeon_suspend_kms() function has called pci_set_power_state() to +put device in D3hot state. +Per PCI spec rev 4.0 on 5.3.1.4.1 D3hot State. +> Configuration and Message requests are the only TLPs accepted by a Function in +> the D3hot state. All other received Requests must be handled as Unsupported Requests, +> and all received Completions may optionally be handled as Unexpected Completions. +This issue will happen in following logs: +Unable to handle kernel paging request at virtual address 00008800e0008010 +CPU 0 kworker/0:3(131): Oops 0 +pc = [] ra = [] ps = 0000 Tainted: G W +pc is at si_gpu_check_soft_reset+0x3c/0x240 +ra is at si_dma_is_lockup+0x34/0xd0 +v0 = 0000000000000000 t0 = fff08800e0008010 t1 = 0000000000010000 +t2 = 0000000000008010 t3 = fff00007e3c00000 t4 = fff00007e3c00258 +t5 = 000000000000ffff t6 = 0000000000000001 t7 = fff00007ef078000 +s0 = fff00007e3c016e8 s1 = fff00007e3c00000 s2 = fff00007e3c00018 +s3 = fff00007e3c00000 s4 = fff00007fff59d80 s5 = 0000000000000000 +s6 = fff00007ef07bd98 +a0 = fff00007e3c00000 a1 = fff00007e3c016e8 a2 = 0000000000000008 +a3 = 0000000000000001 a4 = 8f5c28f5c28f5c29 a5 = ffffffff810f4338 +t8 = 0000000000000275 t9 = ffffffff809b66f8 t10 = ff6769c5d964b800 +t11= 000000000000b886 pv = ffffffff811bea20 at = 0000000000000000 +gp = ffffffff81d89690 sp = 00000000aa814126 +Disabling lock debugging due to kernel taint +Trace: +[] si_dma_is_lockup+0x34/0xd0 +[] radeon_fence_check_lockup+0xd0/0x290 +[] process_one_work+0x280/0x550 +[] worker_thread+0x70/0x7c0 +[] worker_thread+0x130/0x7c0 +[] kthread+0x200/0x210 +[] worker_thread+0x0/0x7c0 +[] kthread+0x14c/0x210 +[] ret_from_kernel_thread+0x18/0x20 +[] kthread+0x0/0x210 + Code: ad3e0008 43f0074a ad7e0018 ad9e0020 8c3001e8 40230101 + <88210000> 4821ed21 +So force lockup work queue flush to fix this problem. + +Acked-by: Christian König +Signed-off-by: Zhenneng Li +Signed-off-by: Alex Deucher +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/radeon/radeon_device.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c +index 2b12389f841a..ee0165687239 100644 +--- a/drivers/gpu/drm/radeon/radeon_device.c ++++ b/drivers/gpu/drm/radeon/radeon_device.c +@@ -1605,6 +1605,9 @@ int radeon_suspend_kms(struct drm_device *dev, bool suspend, + if (r) { + /* delay GPU reset to resume */ + radeon_fence_driver_force_completion(rdev, i); ++ } else { ++ /* finish executing delayed work */ ++ flush_delayed_work(&rdev->fence_drv[i].lockup_work); + } + } + +-- +2.35.3 + diff --git a/patches.suse/drm-rockchip-Fix-return-type-of-cdn_dp_connector_mod.patch b/patches.suse/drm-rockchip-Fix-return-type-of-cdn_dp_connector_mod.patch new file mode 100644 index 0000000..d99b7d9 --- /dev/null +++ b/patches.suse/drm-rockchip-Fix-return-type-of-cdn_dp_connector_mod.patch @@ -0,0 +1,51 @@ +From b0b9408f132623dc88e78adb5282f74e4b64bb57 Mon Sep 17 00:00:00 2001 +From: Nathan Huckleberry +Date: Tue, 13 Sep 2022 13:55:55 -0700 +Subject: [PATCH] drm/rockchip: Fix return type of cdn_dp_connector_mode_valid +Git-commit: b0b9408f132623dc88e78adb5282f74e4b64bb57 +Patch-mainline: v6.0-rc6 +References: git-fixes + +The mode_valid field in drm_connector_helper_funcs is expected to be of +Type: +enum drm_mode_status (* mode_valid) (struct drm_connector *connector, + struct drm_display_mode *mode); + +The mismatched return type breaks forward edge kCFI since the underlying +function definition does not match the function hook definition. + +The return type of cdn_dp_connector_mode_valid should be changed from +int to enum drm_mode_status. + +Reported-by: Dan Carpenter +Link: https://github.com/ClangBuiltLinux/linux/issues/1703 +Cc: llvm@lists.linux.dev +Signed-off-by: Nathan Huckleberry +Reviewed-by: Nathan Chancellor +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20220913205555.155149-1-nhuck@google.com +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/rockchip/cdn-dp-core.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c +index c204e9b95c1f..518ee13b1d6f 100644 +--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c ++++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c +@@ -283,8 +283,9 @@ static int cdn_dp_connector_get_modes(struct drm_connector *connector) + return ret; + } + +-static int cdn_dp_connector_mode_valid(struct drm_connector *connector, +- struct drm_display_mode *mode) ++static enum drm_mode_status ++cdn_dp_connector_mode_valid(struct drm_connector *connector, ++ struct drm_display_mode *mode) + { + struct cdn_dp_device *dp = connector_to_dp(connector); + struct drm_display_info *display_info = &dp->connector.display_info; +-- +2.35.3 + diff --git a/patches.suse/drm-scheduler-quieten-kernel-doc-warnings.patch b/patches.suse/drm-scheduler-quieten-kernel-doc-warnings.patch new file mode 100644 index 0000000..5414712 --- /dev/null +++ b/patches.suse/drm-scheduler-quieten-kernel-doc-warnings.patch @@ -0,0 +1,99 @@ +From f8ad757e40c9c776a13eaa56d73e8e62381517b6 Mon Sep 17 00:00:00 2001 +From: Randy Dunlap +Date: Mon, 4 Apr 2022 14:30:40 -0700 +Subject: [PATCH] drm/scheduler: quieten kernel-doc warnings +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: f8ad757e40c9c776a13eaa56d73e8e62381517b6 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Fix kernel-doc warnings in gpu_scheduler.h and sched_main.c. + +Quashes these warnings: + +include/drm/gpu_scheduler.h:332: warning: missing initial short description on line: + * struct drm_sched_backend_ops +include/drm/gpu_scheduler.h:412: warning: missing initial short description on line: + * struct drm_gpu_scheduler +include/drm/gpu_scheduler.h:461: warning: Function parameter or member 'dev' not described in 'drm_gpu_scheduler' + +drivers/gpu/drm/scheduler/sched_main.c:201: warning: missing initial short description on line: + * drm_sched_dependency_optimized +drivers/gpu/drm/scheduler/sched_main.c:995: warning: Function parameter or member 'dev' not described in 'drm_sched_init' + +Fixes: 2d33948e4e00 ("drm/scheduler: add documentation") +Fixes: 8ab62eda177b ("drm/sched: Add device pointer to drm_gpu_scheduler") +Fixes: 542cff7893a3 ("drm/sched: Avoid lockdep spalt on killing a processes") +Signed-off-by: Randy Dunlap +Cc: David Airlie +Cc: Daniel Vetter +Cc: Andrey Grodzovsky +Cc: Nayan Deshmukh +Cc: Alex Deucher +Cc: Christian König +Cc: Jiawei Gu +Cc: dri-devel@lists.freedesktop.org +Acked-by: Christian König +Signed-off-by: Andrey Grodzovsky +Link: https://patchwork.freedesktop.org/patch/msgid/20220404213040.12912-1-rdunlap@infradead.org +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/scheduler/sched_main.c | 3 ++- + include/drm/gpu_scheduler.h | 9 +++++---- + 2 files changed, 7 insertions(+), 5 deletions(-) + +--- a/drivers/gpu/drm/scheduler/sched_main.c ++++ b/drivers/gpu/drm/scheduler/sched_main.c +@@ -196,7 +196,7 @@ static void drm_sched_job_done_cb(struct + } + + /** +- * drm_sched_dependency_optimized ++ * drm_sched_dependency_optimized - test if the dependency can be optimized + * + * @fence: the dependency fence + * @entity: the entity which depends on the above fence +@@ -848,6 +848,7 @@ static int drm_sched_main(void *param) + * @timeout: timeout value in jiffies for the scheduler + * @score: optional score atomic shared with other schedulers + * @name: name used for debugging ++ * @dev: target &struct device + * + * Return 0 on success, otherwise error code. + */ +--- a/include/drm/gpu_scheduler.h ++++ b/include/drm/gpu_scheduler.h +@@ -213,10 +213,10 @@ enum drm_gpu_sched_stat { + }; + + /** +- * struct drm_sched_backend_ops ++ * struct drm_sched_backend_ops - Define the backend operations ++ * called by the scheduler + * +- * Define the backend operations called by the scheduler, +- * these functions should be implemented in driver side. ++ * These functions should be implemented in the driver side. + */ + struct drm_sched_backend_ops { + /** +@@ -255,7 +255,7 @@ struct drm_sched_backend_ops { + }; + + /** +- * struct drm_gpu_scheduler ++ * struct drm_gpu_scheduler - scheduler instance-specific data + * + * @ops: backend operations provided by the driver. + * @hw_submission_limit: the max size of the hardware queue. +@@ -280,6 +280,7 @@ struct drm_sched_backend_ops { + * @_score: score used when the driver doesn't provide one + * @ready: marks if the underlying HW is ready to work + * @free_guilty: A hit to time out handler to free the guilty job. ++ * @dev: system &struct device + * + * One scheduler is implemented for each hardware ring. + */ diff --git a/patches.suse/drm-tegra-vic-Fix-build-warning-when-CONFIG_PM-n.patch b/patches.suse/drm-tegra-vic-Fix-build-warning-when-CONFIG_PM-n.patch new file mode 100644 index 0000000..3dfedcb --- /dev/null +++ b/patches.suse/drm-tegra-vic-Fix-build-warning-when-CONFIG_PM-n.patch @@ -0,0 +1,48 @@ +From b5d5288a46876f6767950449aea310f71ac86277 Mon Sep 17 00:00:00 2001 +From: YueHaibing +Date: Sat, 5 Mar 2022 20:32:00 +0800 +Subject: [PATCH] drm/tegra: vic: Fix build warning when CONFIG_PM=n +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: b5d5288a46876f6767950449aea310f71ac86277 +Patch-mainline: v6.0-rc1 +References: git-fixes + +drivers/gpu/drm/tegra/vic.c:326:12: error: ‘vic_runtime_suspend’ defined but not used [-Werror=unused-function] + static int vic_runtime_suspend(struct device *dev) + ^~~~~~~~~~~~~~~~~~~ +drivers/gpu/drm/tegra/vic.c:292:12: error: ‘vic_runtime_resume’ defined but not used [-Werror=unused-function] + static int vic_runtime_resume(struct device *dev) + ^~~~~~~~~~~~~~~~~~ + +Mark it as __maybe_unused. + +Signed-off-by: YueHaibing +Signed-off-by: Thierry Reding +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/tegra/vic.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/tegra/vic.c ++++ b/drivers/gpu/drm/tegra/vic.c +@@ -53,7 +53,7 @@ static void vic_writel(struct vic *vic, + writel(value, vic->regs + offset); + } + +-static int vic_runtime_resume(struct device *dev) ++static int __maybe_unused vic_runtime_resume(struct device *dev) + { + struct vic *vic = dev_get_drvdata(dev); + int err; +@@ -77,7 +77,7 @@ disable: + return err; + } + +-static int vic_runtime_suspend(struct device *dev) ++static int __maybe_unused vic_runtime_suspend(struct device *dev) + { + struct vic *vic = dev_get_drvdata(dev); + int err; diff --git a/patches.suse/drm-udl-Add-reset_resume.patch b/patches.suse/drm-udl-Add-reset_resume.patch index d084152..12740b8 100644 --- a/patches.suse/drm-udl-Add-reset_resume.patch +++ b/patches.suse/drm-udl-Add-reset_resume.patch @@ -3,8 +3,7 @@ From: Thomas Zimmermann Date: Thu, 8 Sep 2022 11:51:05 +0200 Subject: [PATCH] drm/udl: Add reset_resume Git-commit: 1ceef996c99f1e8a44df8714fcf12822353ac488 -Git-repo: git://anongit.freedesktop.org/drm/drm-misc -Patch-mainline: Queued in subsystem maintainer repo +Patch-mainline: v6.1-rc1 References: bsc#1195917 Implement the reset_resume callback of struct usb_driver. Set the diff --git a/patches.suse/drm-udl-Don-t-re-initialize-stuff-at-retrying-the-UR.patch b/patches.suse/drm-udl-Don-t-re-initialize-stuff-at-retrying-the-UR.patch index 7c16d04..aa47a37 100644 --- a/patches.suse/drm-udl-Don-t-re-initialize-stuff-at-retrying-the-UR.patch +++ b/patches.suse/drm-udl-Don-t-re-initialize-stuff-at-retrying-the-UR.patch @@ -3,8 +3,7 @@ From: Takashi Iwai Date: Thu, 8 Sep 2022 11:51:14 +0200 Subject: [PATCH] drm/udl: Don't re-initialize stuff at retrying the URB list allocation Git-commit: 2c2705bd09730dba6017b26897a2bcd3c5d21557 -Git-repo: git://anongit.freedesktop.org/drm/drm-misc -Patch-mainline: Queued in subsystem maintainer repo +Patch-mainline: v6.1-rc1 References: bsc#1195917 udl_alloc_urb_list() retires the allocation if there is no enough room diff --git a/patches.suse/drm-udl-Drop-unneeded-alignment.patch b/patches.suse/drm-udl-Drop-unneeded-alignment.patch index d688148..b15abc6 100644 --- a/patches.suse/drm-udl-Drop-unneeded-alignment.patch +++ b/patches.suse/drm-udl-Drop-unneeded-alignment.patch @@ -3,8 +3,7 @@ From: Takashi Iwai Date: Thu, 8 Sep 2022 11:51:10 +0200 Subject: [PATCH] drm/udl: Drop unneeded alignment Git-commit: aeb76f97fcf5bf6c094c62ac5cc22a1949751236 -Git-repo: git://anongit.freedesktop.org/drm/drm-misc -Patch-mainline: Queued in subsystem maintainer repo +Patch-mainline: v6.1-rc1 References: bsc#1195917 The alignment of damaged area was needed for the original udlfb driver diff --git a/patches.suse/drm-udl-Enable-damage-clipping.patch b/patches.suse/drm-udl-Enable-damage-clipping.patch index 7b2d87b..c929caf 100644 --- a/patches.suse/drm-udl-Enable-damage-clipping.patch +++ b/patches.suse/drm-udl-Enable-damage-clipping.patch @@ -3,8 +3,7 @@ From: Thomas Zimmermann Date: Thu, 8 Sep 2022 11:51:06 +0200 Subject: [PATCH] drm/udl: Enable damage clipping Git-commit: 0a80005d3c5fea0a21fa6553724c171495ece9b5 -Git-repo: git://anongit.freedesktop.org/drm/drm-misc -Patch-mainline: Queued in subsystem maintainer repo +Patch-mainline: v6.1-rc1 References: bsc#1195917 Call drm_plane_enable_fb_damage_clips() and give userspace a chance diff --git a/patches.suse/drm-udl-Fix-inconsistent-urbs.count-value-during-udl.patch b/patches.suse/drm-udl-Fix-inconsistent-urbs.count-value-during-udl.patch index 4c5483a..b0af7d2 100644 --- a/patches.suse/drm-udl-Fix-inconsistent-urbs.count-value-during-udl.patch +++ b/patches.suse/drm-udl-Fix-inconsistent-urbs.count-value-during-udl.patch @@ -3,8 +3,7 @@ From: Takashi Iwai Date: Thu, 8 Sep 2022 11:51:13 +0200 Subject: [PATCH] drm/udl: Fix inconsistent urbs.count value during udl_free_urb_list() Git-commit: c5c354a3a4728045e1342166394c615d75d45377 -Git-repo: git://anongit.freedesktop.org/drm/drm-misc -Patch-mainline: Queued in subsystem maintainer repo +Patch-mainline: v6.1-rc1 References: bsc#1195917 In the current design, udl_get_urb() may be called asynchronously diff --git a/patches.suse/drm-udl-Fix-potential-URB-leaks.patch b/patches.suse/drm-udl-Fix-potential-URB-leaks.patch index 485a3bd..943ed71 100644 --- a/patches.suse/drm-udl-Fix-potential-URB-leaks.patch +++ b/patches.suse/drm-udl-Fix-potential-URB-leaks.patch @@ -3,8 +3,7 @@ From: Takashi Iwai Date: Thu, 8 Sep 2022 11:51:12 +0200 Subject: [PATCH] drm/udl: Fix potential URB leaks Git-commit: 046f4f0af7fd1fad06793d863d288c6b2cd84e99 -Git-repo: git://anongit.freedesktop.org/drm/drm-misc -Patch-mainline: Queued in subsystem maintainer repo +Patch-mainline: v6.1-rc1 References: bsc#1195917 A couple of error handlings forgot to process the URB completion. diff --git a/patches.suse/drm-udl-Increase-the-default-URB-list-size-to-20.patch b/patches.suse/drm-udl-Increase-the-default-URB-list-size-to-20.patch index 66552cb..24fa0d3 100644 --- a/patches.suse/drm-udl-Increase-the-default-URB-list-size-to-20.patch +++ b/patches.suse/drm-udl-Increase-the-default-URB-list-size-to-20.patch @@ -3,8 +3,7 @@ From: Takashi Iwai Date: Thu, 8 Sep 2022 11:51:09 +0200 Subject: [PATCH] drm/udl: Increase the default URB list size to 20 Git-commit: 2a07a5ddb135e4bd15bf6468b7d2daa4deeaf07d -Git-repo: git://anongit.freedesktop.org/drm/drm-misc -Patch-mainline: Queued in subsystem maintainer repo +Patch-mainline: v6.1-rc1 References: bsc#1195917 It seems that the current size (4) for the URB list is too small on diff --git a/patches.suse/drm-udl-Kill-pending-URBs-at-suspend-and-disconnect.patch b/patches.suse/drm-udl-Kill-pending-URBs-at-suspend-and-disconnect.patch index 312146a..8c54467 100644 --- a/patches.suse/drm-udl-Kill-pending-URBs-at-suspend-and-disconnect.patch +++ b/patches.suse/drm-udl-Kill-pending-URBs-at-suspend-and-disconnect.patch @@ -3,8 +3,7 @@ From: Takashi Iwai Date: Thu, 4 Aug 2022 09:58:25 +0200 Subject: [PATCH] drm/udl: Kill pending URBs at suspend and disconnect Git-commit: e25d5954264d1871ab2792c7ca2298b811462500 -Patch-mainline: Queued in subsystem maintainer repo -Git-repo: git://anongit.freedesktop.org/drm-tip +Patch-mainline: v6.1-rc1 References: bsc#1195917 At both suspend and disconnect, we should rather cancel the pending diff --git a/patches.suse/drm-udl-Replace-BUG_ON-with-WARN_ON.patch b/patches.suse/drm-udl-Replace-BUG_ON-with-WARN_ON.patch index 2252a07..d7587da 100644 --- a/patches.suse/drm-udl-Replace-BUG_ON-with-WARN_ON.patch +++ b/patches.suse/drm-udl-Replace-BUG_ON-with-WARN_ON.patch @@ -3,8 +3,7 @@ From: Takashi Iwai Date: Thu, 4 Aug 2022 09:58:26 +0200 Subject: [PATCH] drm/udl: Replace BUG_ON() with WARN_ON() Git-commit: 7350b2a3fbc6956b2b2234f6d27d030c70b451bb -Git-repo: git://anongit.freedesktop.org/drm-tip -Patch-mainline: Queued in subsystem maintainer repo +Patch-mainline: v6.1-rc1 References: bsc#1195917 BUG_ON() is a tasteless choice as a sanity check for a driver like UDL diff --git a/patches.suse/drm-udl-Replace-semaphore-with-a-simple-wait-queue.patch b/patches.suse/drm-udl-Replace-semaphore-with-a-simple-wait-queue.patch index e143609..3381a23 100644 --- a/patches.suse/drm-udl-Replace-semaphore-with-a-simple-wait-queue.patch +++ b/patches.suse/drm-udl-Replace-semaphore-with-a-simple-wait-queue.patch @@ -3,8 +3,7 @@ From: Takashi Iwai Date: Thu, 4 Aug 2022 09:58:23 +0200 Subject: [PATCH] drm/udl: Replace semaphore with a simple wait queue Git-commit: acd45c56790a3b558b0b0081678a20b0a0d89b0f -Patch-mainline: Queued in subsystem maintainer repo -Git-repo: git://anongit.freedesktop.org/drm-tip +Patch-mainline: v6.1-rc1 References: bsc#1195917 UDL driver uses a semaphore for controlling the emptiness of FIFO in a diff --git a/patches.suse/drm-udl-Restore-display-mode-on-resume.patch b/patches.suse/drm-udl-Restore-display-mode-on-resume.patch index 9fd21c7..660bdc8 100644 --- a/patches.suse/drm-udl-Restore-display-mode-on-resume.patch +++ b/patches.suse/drm-udl-Restore-display-mode-on-resume.patch @@ -3,8 +3,7 @@ From: Takashi Iwai Date: Thu, 8 Sep 2022 11:51:04 +0200 Subject: [PATCH] drm/udl: Restore display mode on resume Git-commit: 6d6e732835db92e66c28dbcf258a7e3d3c71420d -Git-repo: git://anongit.freedesktop.org/drm/drm-misc -Patch-mainline: Queued in subsystem maintainer repo +Patch-mainline: v6.1-rc1 References: bsc#1195917 Restore the display mode whne resuming from suspend. Currently, the diff --git a/patches.suse/drm-udl-Suppress-error-print-for-EPROTO-at-URB-compl.patch b/patches.suse/drm-udl-Suppress-error-print-for-EPROTO-at-URB-compl.patch index 6c71bea..cd4182e 100644 --- a/patches.suse/drm-udl-Suppress-error-print-for-EPROTO-at-URB-compl.patch +++ b/patches.suse/drm-udl-Suppress-error-print-for-EPROTO-at-URB-compl.patch @@ -3,8 +3,7 @@ From: Takashi Iwai Date: Thu, 8 Sep 2022 11:51:08 +0200 Subject: [PATCH] drm/udl: Suppress error print for -EPROTO at URB completion Git-commit: 53593515ec1a4a5afaaa88fd4522bc4c2d7f5d9b -Git-repo: git://anongit.freedesktop.org/drm/drm-misc -Patch-mainline: Queued in subsystem maintainer repo +Patch-mainline: v6.1-rc1 References: bsc#1195917 The driver may receive -EPROTO at the URB completion when the device diff --git a/patches.suse/drm-udl-Sync-pending-URBs-at-suspend-disconnect.patch b/patches.suse/drm-udl-Sync-pending-URBs-at-suspend-disconnect.patch index 873826a..1138c54 100644 --- a/patches.suse/drm-udl-Sync-pending-URBs-at-suspend-disconnect.patch +++ b/patches.suse/drm-udl-Sync-pending-URBs-at-suspend-disconnect.patch @@ -3,8 +3,7 @@ From: Takashi Iwai Date: Thu, 4 Aug 2022 09:58:24 +0200 Subject: [PATCH] drm/udl: Sync pending URBs at suspend / disconnect Git-commit: 0f7dc324b2e9e55db9323302f944fd952dbed967 -Patch-mainline: Queued in subsystem maintainer repo -Git-repo: git://anongit.freedesktop.org/drm-tip +Patch-mainline: v6.1-rc1 References: bsc#1195917 We need to wait for finishing to process the all URBs after disabling diff --git a/patches.suse/drm-udl-Sync-pending-URBs-at-the-end-of-suspend.patch b/patches.suse/drm-udl-Sync-pending-URBs-at-the-end-of-suspend.patch index 2902ac0..1efc626 100644 --- a/patches.suse/drm-udl-Sync-pending-URBs-at-the-end-of-suspend.patch +++ b/patches.suse/drm-udl-Sync-pending-URBs-at-the-end-of-suspend.patch @@ -3,8 +3,7 @@ From: Takashi Iwai Date: Thu, 8 Sep 2022 11:51:15 +0200 Subject: [PATCH] drm/udl: Sync pending URBs at the end of suspend Git-commit: fa47573b04a35078953be5f81a78f22c96358817 -Git-repo: git://anongit.freedesktop.org/drm/drm-misc -Patch-mainline: Queued in subsystem maintainer repo +Patch-mainline: v6.1-rc1 References: bsc#1195917 It's better to perform the sync at the very last of the suspend diff --git a/patches.suse/drm-virtio-Unlock-reservations-on-virtio_gpu_object_.patch b/patches.suse/drm-virtio-Unlock-reservations-on-virtio_gpu_object_.patch new file mode 100644 index 0000000..1105d22 --- /dev/null +++ b/patches.suse/drm-virtio-Unlock-reservations-on-virtio_gpu_object_.patch @@ -0,0 +1,40 @@ +From fdf0ff4d12cbcd76b53f27c96ce51ddca400884a Mon Sep 17 00:00:00 2001 +From: Dmitry Osipenko +Date: Thu, 30 Jun 2022 23:07:20 +0300 +Subject: [PATCH] drm/virtio: Unlock reservations on virtio_gpu_object_shmem_init() error +Git-commit: fdf0ff4d12cbcd76b53f27c96ce51ddca400884a +Patch-mainline: v6.1-rc1 +References: git-fixes + +Unlock reservations in the error code path of virtio_gpu_object_create() +to silence debug warning splat produced by ww_mutex_destroy(&obj->lock) +when GEM is released with the held lock. + +Cc: stable@vger.kernel.org +Fixes: 30172efbfb84 ("drm/virtio: blob prep: refactor getting pages and attaching backing") +Reviewed-by: Emil Velikov +Signed-off-by: Dmitry Osipenko +Link: http://patchwork.freedesktop.org/patch/msgid/20220630200726.1884320-4-dmitry.osipenko@collabora.com +Signed-off-by: Gerd Hoffmann +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/virtio/virtgpu_object.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c +index 87b19b3b96e0..75a159df0af6 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_object.c ++++ b/drivers/gpu/drm/virtio/virtgpu_object.c +@@ -249,6 +249,8 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, + + ret = virtio_gpu_object_shmem_init(vgdev, bo, &ents, &nents); + if (ret != 0) { ++ if (fence) ++ virtio_gpu_array_unlock_resv(objs); + virtio_gpu_array_put_free(objs); + virtio_gpu_free_object(&shmem_obj->base); + return ret; +-- +2.35.3 + diff --git a/patches.suse/dt-bindings-PCI-microchip-pcie-host-fix-missing-cloc.patch b/patches.suse/dt-bindings-PCI-microchip-pcie-host-fix-missing-cloc.patch new file mode 100644 index 0000000..f3392d2 --- /dev/null +++ b/patches.suse/dt-bindings-PCI-microchip-pcie-host-fix-missing-cloc.patch @@ -0,0 +1,66 @@ +From 05a5741019a524ab9e1d355528c8ebcbd6debfe7 Mon Sep 17 00:00:00 2001 +From: Conor Dooley +Date: Sat, 20 Aug 2022 00:14:11 +0100 +Subject: [PATCH] dt-bindings: PCI: microchip,pcie-host: fix missing clocks properties +Git-commit: 05a5741019a524ab9e1d355528c8ebcbd6debfe7 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Recent versions of dt-schema warn about unevaluatedProperties: +Arch/riscv/boot/dts/microchip/mpfs-icicle-kit.dtb: pcie@2000000000: Unevaluated properties are not allowed ('clock-names', 'clocks', 'legacy-interrupt-controller', 'microchip,axi-m-atr0' were unexpected) From schema: Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml + +The clocks are required to enable interfaces between the FPGA fabric +and the core complex, so add them to the binding. + +Link: https://lore.kernel.org/r/20220819231415.3860210-3-mail@conchuod.ie +Fixes: 6ee6c89aac35 ("dt-bindings: PCI: microchip: Add Microchip PolarFire host binding") +Signed-off-by: Conor Dooley +Signed-off-by: Lorenzo Pieralisi +Reviewed-by: Rob Herring +Acked-by: Takashi Iwai + +--- + .../bindings/pci/microchip,pcie-host.yaml | 27 +++++++++++++++++++ + 1 file changed, 27 insertions(+) + +diff --git a/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml b/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml +index edb4f81253c8..6fbe62f4da93 100644 +--- a/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml ++++ b/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml +@@ -25,6 +25,33 @@ properties: + - const: cfg + - const: apb + ++ clocks: ++ description: ++ Fabric Interface Controllers, FICs, are the interface between the FPGA ++ fabric and the core complex on PolarFire SoC. The FICs require two clocks, ++ one from each side of the interface. The "FIC clocks" described by this ++ property are on the core complex side & communication through a FIC is not ++ possible unless it's corresponding clock is enabled. A clock must be ++ enabled for each of the interfaces the root port is connected through. ++ This could in theory be all 4 interfaces, one interface or any combination ++ in between. ++ minItems: 1 ++ items: ++ - description: FIC0's clock ++ - description: FIC1's clock ++ - description: FIC2's clock ++ - description: FIC3's clock ++ ++ clock-names: ++ description: ++ As any FIC connection combination is possible, the names should match the ++ order in the clocks property and take the form "ficN" where N is a number ++ 0-3 ++ minItems: 1 ++ maxItems: 4 ++ items: ++ pattern: '^fic[0-3]$' ++ + interrupts: + minItems: 1 + items: +-- +2.35.3 + diff --git a/patches.suse/dt-bindings-PCI-microchip-pcie-host-fix-missing-dma-.patch b/patches.suse/dt-bindings-PCI-microchip-pcie-host-fix-missing-dma-.patch new file mode 100644 index 0000000..eac081d --- /dev/null +++ b/patches.suse/dt-bindings-PCI-microchip-pcie-host-fix-missing-dma-.patch @@ -0,0 +1,42 @@ +From 1a7966b33b5bbefd950cffef1ea8ee3f5f1bf076 Mon Sep 17 00:00:00 2001 +From: Conor Dooley +Date: Sat, 20 Aug 2022 00:14:12 +0100 +Subject: [PATCH] dt-bindings: PCI: microchip,pcie-host: fix missing dma-ranges +Git-commit: 1a7966b33b5bbefd950cffef1ea8ee3f5f1bf076 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The dma-ranges property was missed when adding the binding initially. +The root port can use up to 6 address translation tables, depending on +configuration. + +Link: https://www.microsemi.com/document-portal/doc_download/1245812-polarfire-fpga-and-polarfire-soc-fpga-pci-express-user-guide # Section 1.3.3 +Link: https://lore.kernel.org/r/20220819231415.3860210-4-mail@conchuod.ie +Fixes: 6ee6c89aac35 ("dt-bindings: PCI: microchip: Add Microchip PolarFire host binding") +Signed-off-by: Conor Dooley +Signed-off-by: Lorenzo Pieralisi +Reviewed-by: Rob Herring +Acked-by: Takashi Iwai + +--- + .../devicetree/bindings/pci/microchip,pcie-host.yaml | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml b/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml +index 6fbe62f4da93..23d95c65acff 100644 +--- a/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml ++++ b/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml +@@ -67,6 +67,10 @@ properties: + ranges: + maxItems: 1 + ++ dma-ranges: ++ minItems: 1 ++ maxItems: 6 ++ + msi-controller: + description: Identifies the node as an MSI controller. + +-- +2.35.3 + diff --git a/patches.suse/dt-bindings-crypto-ti-sa2ul-drop-dma-coherent-proper.patch b/patches.suse/dt-bindings-crypto-ti-sa2ul-drop-dma-coherent-proper.patch new file mode 100644 index 0000000..e627fd9 --- /dev/null +++ b/patches.suse/dt-bindings-crypto-ti-sa2ul-drop-dma-coherent-proper.patch @@ -0,0 +1,61 @@ +From a536208da6f7d877f1adbad4ff13f63f31f59d91 Mon Sep 17 00:00:00 2001 +From: Jayesh Choudhary +Date: Fri, 26 Aug 2022 14:41:42 +0530 +Subject: [PATCH] dt-bindings: crypto: ti,sa2ul: drop dma-coherent property +Git-commit: a536208da6f7d877f1adbad4ff13f63f31f59d91 +Patch-mainline: v6.1-rc1 +References: git-fixes + +crypto driver itself is not dma-coherent. It is the dmaengine +that moves data and the buffers are to be mapped to the +dmaengine provider. So this property should be dropped. + +Fixes: 2ce9a7299bf6 ('dt-bindings: crypto: Add TI SA2UL crypto accelerator documentation') +Signed-off-by: Jayesh Choudhary +Link: https://lore.kernel.org/r/20220826091142.262325-1-j-choudhary@ti.com +Signed-off-by: Rob Herring +Acked-by: Takashi Iwai + +--- + .../devicetree/bindings/crypto/ti,sa2ul.yaml | 13 ------------- + 1 file changed, 13 deletions(-) + +diff --git a/Documentation/devicetree/bindings/crypto/ti,sa2ul.yaml b/Documentation/devicetree/bindings/crypto/ti,sa2ul.yaml +index 02f47c2e7998..0c15fefb6671 100644 +--- a/Documentation/devicetree/bindings/crypto/ti,sa2ul.yaml ++++ b/Documentation/devicetree/bindings/crypto/ti,sa2ul.yaml +@@ -35,8 +35,6 @@ properties: + - const: rx1 + - const: rx2 + +- dma-coherent: true +- + "#address-cells": + const: 2 + +@@ -72,16 +70,6 @@ required: + - dmas + - dma-names + +-if: +- properties: +- compatible: +- enum: +- - ti,j721e-sa2ul +- - ti,am654-sa2ul +-then: +- required: +- - dma-coherent +- + additionalProperties: false + + examples: +@@ -95,5 +83,4 @@ examples: + dmas = <&main_udmap 0xc000>, <&main_udmap 0x4000>, + <&main_udmap 0x4001>; + dma-names = "tx", "rx1", "rx2"; +- dma-coherent; + }; +-- +2.35.3 + diff --git a/patches.suse/dt-bindings-display-msm-dpu-sc7180-add-missing-DPU-o.patch b/patches.suse/dt-bindings-display-msm-dpu-sc7180-add-missing-DPU-o.patch new file mode 100644 index 0000000..433852e --- /dev/null +++ b/patches.suse/dt-bindings-display-msm-dpu-sc7180-add-missing-DPU-o.patch @@ -0,0 +1,49 @@ +From 5621478dbc0a537a81d887cdbc86d4d12d51bd8f Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +Date: Wed, 17 Aug 2022 09:20:57 +0300 +Subject: [PATCH] dt-bindings: display/msm: dpu-sc7180: add missing DPU opp-table +Git-commit: 5621478dbc0a537a81d887cdbc86d4d12d51bd8f +Patch-mainline: v6.1-rc1 +References: git-fixes + +The 'display-controller' child (DPU) of Display SubSystem (MDSS) uses +opp-table, so reference it which allows restricting DPU schema to fixed +list of properties. + +Fixes: 3d7a0dd8f39b ("dt-bindings: msm: disp: add yaml schemas for DPU bindings") +Signed-off-by: Krzysztof Kozlowski +Reviewed-by: Dmitry Baryshkov +Patchwork: https://patchwork.freedesktop.org/patch/497894/ +Link: https://lore.kernel.org/r/20220817062059.18640-4-krzysztof.kozlowski@linaro.org +Signed-off-by: Dmitry Baryshkov +Signed-off-by: Rob Clark +Acked-by: Takashi Iwai + +--- + Documentation/devicetree/bindings/display/msm/dpu-sc7180.yaml | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/Documentation/devicetree/bindings/display/msm/dpu-sc7180.yaml b/Documentation/devicetree/bindings/display/msm/dpu-sc7180.yaml +index d3c3e4b07897..4890bc25f3fd 100644 +--- a/Documentation/devicetree/bindings/display/msm/dpu-sc7180.yaml ++++ b/Documentation/devicetree/bindings/display/msm/dpu-sc7180.yaml +@@ -73,6 +73,7 @@ patternProperties: + "^display-controller@[0-9a-f]+$": + type: object + description: Node containing the properties of DPU. ++ additionalProperties: false + + properties: + compatible: +@@ -114,6 +115,8 @@ patternProperties: + maxItems: 1 + + operating-points-v2: true ++ opp-table: ++ type: object + + ports: + $ref: /schemas/graph.yaml#/properties/ports +-- +2.35.3 + diff --git a/patches.suse/dt-bindings-display-msm-dpu-sdm845-add-missing-DPU-o.patch b/patches.suse/dt-bindings-display-msm-dpu-sdm845-add-missing-DPU-o.patch new file mode 100644 index 0000000..ff6e649 --- /dev/null +++ b/patches.suse/dt-bindings-display-msm-dpu-sdm845-add-missing-DPU-o.patch @@ -0,0 +1,50 @@ +From feda34d14adf295a6311ffe00e9b89104bcda61b Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +Date: Wed, 17 Aug 2022 09:20:59 +0300 +Subject: [PATCH] dt-bindings: display/msm: dpu-sdm845: add missing DPU opp-table +Git-commit: feda34d14adf295a6311ffe00e9b89104bcda61b +Patch-mainline: v6.1-rc1 +References: git-fixes + +The 'display-controller' child (DPU) of Display SubSystem (MDSS) uses +opp-table, so reference it which allows restricting DPU schema to fixed +list of properties. + +Fixes: 3d7a0dd8f39b ("dt-bindings: msm: disp: add yaml schemas for DPU bindings") +Signed-off-by: Krzysztof Kozlowski +Reviewed-by: Dmitry Baryshkov +Patchwork: https://patchwork.freedesktop.org/patch/499212/ +Link: https://lore.kernel.org/r/20220817062059.18640-6-krzysztof.kozlowski@linaro.org +Signed-off-by: Dmitry Baryshkov +Signed-off-by: Rob Clark +Acked-by: Takashi Iwai + +--- + Documentation/devicetree/bindings/display/msm/dpu-sdm845.yaml | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/Documentation/devicetree/bindings/display/msm/dpu-sdm845.yaml b/Documentation/devicetree/bindings/display/msm/dpu-sdm845.yaml +index 2bb8896beffc..7d1037373175 100644 +--- a/Documentation/devicetree/bindings/display/msm/dpu-sdm845.yaml ++++ b/Documentation/devicetree/bindings/display/msm/dpu-sdm845.yaml +@@ -65,6 +65,7 @@ patternProperties: + "^display-controller@[0-9a-f]+$": + type: object + description: Node containing the properties of DPU. ++ additionalProperties: false + + properties: + compatible: +@@ -102,6 +103,9 @@ patternProperties: + maxItems: 1 + + operating-points-v2: true ++ opp-table: ++ type: object ++ + ports: + $ref: /schemas/graph.yaml#/properties/ports + description: | +-- +2.35.3 + diff --git a/patches.suse/dt-bindings-mtd-intel-lgm-nand-Fix-compatible-string.patch b/patches.suse/dt-bindings-mtd-intel-lgm-nand-Fix-compatible-string.patch new file mode 100644 index 0000000..1d28b3a --- /dev/null +++ b/patches.suse/dt-bindings-mtd-intel-lgm-nand-Fix-compatible-string.patch @@ -0,0 +1,239 @@ +From c6d7ce0a7e0562846431dc3c7c390dde7d0c0c42 Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Sun, 3 Jul 2022 01:12:20 +0200 +Subject: [PATCH] dt-bindings: mtd: intel: lgm-nand: Fix compatible string +Git-commit: c6d7ce0a7e0562846431dc3c7c390dde7d0c0c42 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The driver which was added at the same time as the dt-bindings uses the +compatible string "intel,lgm-ebunand". Use the same compatible string +also in the dt-bindings and rename the bindings file accordingly. + +Fixes: 2f9cea8eae44f5 ("dt-bindings: mtd: Add Nand Flash Controller support for Intel LGM SoC") +Signed-off-by: Martin Blumenstingl +Reviewed-by: Rob Herring +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20220702231227.1579176-2-martin.blumenstingl@googlemail.com +Acked-by: Takashi Iwai + +--- + .../bindings/mtd/intel,lgm-ebunand.yaml | 99 +++++++++++++++++++ + .../bindings/mtd/intel,lgm-nand.yaml | 99 ------------------- + 2 files changed, 99 insertions(+), 99 deletions(-) + create mode 100644 Documentation/devicetree/bindings/mtd/intel,lgm-ebunand.yaml + delete mode 100644 Documentation/devicetree/bindings/mtd/intel,lgm-nand.yaml + +diff --git a/Documentation/devicetree/bindings/mtd/intel,lgm-ebunand.yaml b/Documentation/devicetree/bindings/mtd/intel,lgm-ebunand.yaml +new file mode 100644 +index 000000000000..763ee3e1faf3 +--- /dev/null ++++ b/Documentation/devicetree/bindings/mtd/intel,lgm-ebunand.yaml +@@ -0,0 +1,99 @@ ++# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/mtd/intel,lgm-ebunand.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Intel LGM SoC NAND Controller Device Tree Bindings ++ ++allOf: ++ - $ref: "nand-controller.yaml" ++ ++maintainers: ++ - Ramuthevar Vadivel Murugan ++ ++properties: ++ compatible: ++ const: intel,lgm-ebunand ++ ++ reg: ++ maxItems: 6 ++ ++ reg-names: ++ items: ++ - const: ebunand ++ - const: hsnand ++ - const: nand_cs0 ++ - const: nand_cs1 ++ - const: addr_sel0 ++ - const: addr_sel1 ++ ++ clocks: ++ maxItems: 1 ++ ++ dmas: ++ maxItems: 2 ++ ++ dma-names: ++ items: ++ - const: tx ++ - const: rx ++ ++ "#address-cells": ++ const: 1 ++ ++ "#size-cells": ++ const: 0 ++ ++patternProperties: ++ "^nand@[a-f0-9]+$": ++ type: object ++ properties: ++ reg: ++ minimum: 0 ++ maximum: 7 ++ ++ nand-ecc-mode: true ++ ++ nand-ecc-algo: ++ const: hw ++ ++ additionalProperties: false ++ ++required: ++ - compatible ++ - reg ++ - reg-names ++ - clocks ++ - dmas ++ - dma-names ++ - "#address-cells" ++ - "#size-cells" ++ ++additionalProperties: false ++ ++examples: ++ - | ++ nand-controller@e0f00000 { ++ compatible = "intel,lgm-ebunand"; ++ reg = <0xe0f00000 0x100>, ++ <0xe1000000 0x300>, ++ <0xe1400000 0x8000>, ++ <0xe1c00000 0x1000>, ++ <0x17400000 0x4>, ++ <0x17c00000 0x4>; ++ reg-names = "ebunand", "hsnand", "nand_cs0", "nand_cs1", ++ "addr_sel0", "addr_sel1"; ++ clocks = <&cgu0 125>; ++ dmas = <&dma0 8>, <&dma0 9>; ++ dma-names = "tx", "rx"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ nand@0 { ++ reg = <0>; ++ nand-ecc-mode = "hw"; ++ }; ++ }; ++ ++... +diff --git a/Documentation/devicetree/bindings/mtd/intel,lgm-nand.yaml b/Documentation/devicetree/bindings/mtd/intel,lgm-nand.yaml +deleted file mode 100644 +index 30e0c66ab0eb..000000000000 +--- a/Documentation/devicetree/bindings/mtd/intel,lgm-nand.yaml ++++ /dev/null +@@ -1,99 +0,0 @@ +-# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +-%YAML 1.2 +---- +-$id: http://devicetree.org/schemas/mtd/intel,lgm-nand.yaml# +-$schema: http://devicetree.org/meta-schemas/core.yaml# +- +-title: Intel LGM SoC NAND Controller Device Tree Bindings +- +-allOf: +- - $ref: "nand-controller.yaml" +- +-maintainers: +- - Ramuthevar Vadivel Murugan +- +-properties: +- compatible: +- const: intel,lgm-nand +- +- reg: +- maxItems: 6 +- +- reg-names: +- items: +- - const: ebunand +- - const: hsnand +- - const: nand_cs0 +- - const: nand_cs1 +- - const: addr_sel0 +- - const: addr_sel1 +- +- clocks: +- maxItems: 1 +- +- dmas: +- maxItems: 2 +- +- dma-names: +- items: +- - const: tx +- - const: rx +- +- "#address-cells": +- const: 1 +- +- "#size-cells": +- const: 0 +- +-patternProperties: +- "^nand@[a-f0-9]+$": +- type: object +- properties: +- reg: +- minimum: 0 +- maximum: 7 +- +- nand-ecc-mode: true +- +- nand-ecc-algo: +- const: hw +- +- additionalProperties: false +- +-required: +- - compatible +- - reg +- - reg-names +- - clocks +- - dmas +- - dma-names +- - "#address-cells" +- - "#size-cells" +- +-additionalProperties: false +- +-examples: +- - | +- nand-controller@e0f00000 { +- compatible = "intel,lgm-nand"; +- reg = <0xe0f00000 0x100>, +- <0xe1000000 0x300>, +- <0xe1400000 0x8000>, +- <0xe1c00000 0x1000>, +- <0x17400000 0x4>, +- <0x17c00000 0x4>; +- reg-names = "ebunand", "hsnand", "nand_cs0", "nand_cs1", +- "addr_sel0", "addr_sel1"; +- clocks = <&cgu0 125>; +- dmas = <&dma0 8>, <&dma0 9>; +- dma-names = "tx", "rx"; +- #address-cells = <1>; +- #size-cells = <0>; +- +- nand@0 { +- reg = <0>; +- nand-ecc-mode = "hw"; +- }; +- }; +- +-... +-- +2.35.3 + diff --git a/patches.suse/dt-bindings-mtd-intel-lgm-nand-Fix-maximum-chip-sele.patch b/patches.suse/dt-bindings-mtd-intel-lgm-nand-Fix-maximum-chip-sele.patch new file mode 100644 index 0000000..0ad8859 --- /dev/null +++ b/patches.suse/dt-bindings-mtd-intel-lgm-nand-Fix-maximum-chip-sele.patch @@ -0,0 +1,39 @@ +From 9fac2a193e4553d6ce093a626ef5920c362d0753 Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Sun, 3 Jul 2022 01:12:21 +0200 +Subject: [PATCH] dt-bindings: mtd: intel: lgm-nand: Fix maximum chip select value +Git-commit: 9fac2a193e4553d6ce093a626ef5920c362d0753 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The Intel LGM NAND IP only supports two chip selects: There's only two +CS and ADDR_SEL register sets. Fix the maximum allowed chip select value +according to the dt-bindings. + +Fixes: 2f9cea8eae44f5 ("dt-bindings: mtd: Add Nand Flash Controller support for Intel LGM SoC") +Acked-by: Rob Herring +Signed-off-by: Martin Blumenstingl +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20220702231227.1579176-3-martin.blumenstingl@googlemail.com +Acked-by: Takashi Iwai + +--- + Documentation/devicetree/bindings/mtd/intel,lgm-ebunand.yaml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Documentation/devicetree/bindings/mtd/intel,lgm-ebunand.yaml b/Documentation/devicetree/bindings/mtd/intel,lgm-ebunand.yaml +index 763ee3e1faf3..04f26196c4c1 100644 +--- a/Documentation/devicetree/bindings/mtd/intel,lgm-ebunand.yaml ++++ b/Documentation/devicetree/bindings/mtd/intel,lgm-ebunand.yaml +@@ -51,7 +51,7 @@ patternProperties: + properties: + reg: + minimum: 0 +- maximum: 7 ++ maximum: 1 + + nand-ecc-mode: true + +-- +2.35.3 + diff --git a/patches.suse/dt-bindings-phy-qcom-qmp-fix-bogus-clock-cells-prope.patch b/patches.suse/dt-bindings-phy-qcom-qmp-fix-bogus-clock-cells-prope.patch new file mode 100644 index 0000000..7e91302 --- /dev/null +++ b/patches.suse/dt-bindings-phy-qcom-qmp-fix-bogus-clock-cells-prope.patch @@ -0,0 +1,55 @@ +From 97e72ee4de7e04b31d06fbd36c637dcd085b6e42 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 30 Aug 2022 13:28:54 +0200 +Subject: [PATCH] dt-bindings: phy: qcom,qmp: fix bogus clock-cells property +Git-commit: 97e72ee4de7e04b31d06fbd36c637dcd085b6e42 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The QMP PHY wrapper node is not a clock provider so drop the bogus +'#clock-cells' property that was added when converting to DT schema. + +Fixes: ccf51c1cedfd ("dt-bindings: phy: qcom,qmp: Convert QMP PHY bindings to yaml") +Reviewed-by: Krzysztof Kozlowski +Signed-off-by: Johan Hovold +Link: https://lore.kernel.org/r/20220830112923.3725-2-johan+linaro@kernel.org +Signed-off-by: Vinod Koul +Acked-by: Takashi Iwai + +--- + Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml +index d8a9c205f039..edb53576fc0d 100644 +--- a/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml ++++ b/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml +@@ -68,9 +68,6 @@ properties: + - description: Address and length of PHY's common serdes block. + - description: Address and length of PHY's DP_COM control block. + +- "#clock-cells": +- enum: [ 1, 2 ] +- + "#address-cells": + enum: [ 1, 2 ] + +@@ -118,7 +115,6 @@ patternProperties: + required: + - compatible + - reg +- - "#clock-cells" + - "#address-cells" + - "#size-cells" + - ranges +@@ -472,7 +468,6 @@ examples: + usb_2_qmpphy: phy-wrapper@88eb000 { + compatible = "qcom,sdm845-qmp-usb3-uni-phy"; + reg = <0x088eb000 0x18c>; +- #clock-cells = <1>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x088eb000 0x2000>; +-- +2.35.3 + diff --git a/patches.suse/dt-bindings-phy-qcom-qmp-usb3-dp-fix-bogus-clock-cel.patch b/patches.suse/dt-bindings-phy-qcom-qmp-usb3-dp-fix-bogus-clock-cel.patch new file mode 100644 index 0000000..5a69214 --- /dev/null +++ b/patches.suse/dt-bindings-phy-qcom-qmp-usb3-dp-fix-bogus-clock-cel.patch @@ -0,0 +1,55 @@ +From dc47bcb727cfffb40cf85d54474c57a83aee8a03 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 30 Aug 2022 13:29:16 +0200 +Subject: [PATCH] dt-bindings: phy: qcom,qmp-usb3-dp: fix bogus clock-cells property +Git-commit: dc47bcb727cfffb40cf85d54474c57a83aee8a03 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The QMP PHY wrapper node is not a clock provider so drop the bogus +'#clock-cells' property that was added when converting to DT schema. + +Fixes: 59351049ad15 ("dt-bindings: phy: qcom,qmp-usb3-dp: Add dt bindings for USB3 DP PHY") +Reviewed-by: Krzysztof Kozlowski +Signed-off-by: Johan Hovold +Link: https://lore.kernel.org/r/20220830112923.3725-24-johan+linaro@kernel.org +Signed-off-by: Vinod Koul +Acked-by: Takashi Iwai + +--- + .../devicetree/bindings/phy/qcom,qmp-usb3-dp-phy.yaml | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/Documentation/devicetree/bindings/phy/qcom,qmp-usb3-dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qmp-usb3-dp-phy.yaml +index 31f3ad2ee683..da7d8dfc631c 100644 +--- a/Documentation/devicetree/bindings/phy/qcom,qmp-usb3-dp-phy.yaml ++++ b/Documentation/devicetree/bindings/phy/qcom,qmp-usb3-dp-phy.yaml +@@ -31,9 +31,6 @@ properties: + - const: dp_com + - const: dp + +- "#clock-cells": +- enum: [ 1, 2 ] +- + "#address-cells": + enum: [ 1, 2 ] + +@@ -150,7 +147,6 @@ patternProperties: + required: + - compatible + - reg +- - "#clock-cells" + - "#address-cells" + - "#size-cells" + - ranges +@@ -172,7 +168,6 @@ examples: + <0x088e8000 0x10>, + <0x088ea000 0x40>; + reg-names = "usb", "dp_com", "dp"; +- #clock-cells = <1>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x088e9000 0x2000>; +-- +2.35.3 + diff --git a/patches.suse/edac-dmc520-don-t-print-an-error-for-each-unconfigured-interrupt-line.patch b/patches.suse/edac-dmc520-don-t-print-an-error-for-each-unconfigured-interrupt-line.patch new file mode 100644 index 0000000..2b0eee2 --- /dev/null +++ b/patches.suse/edac-dmc520-don-t-print-an-error-for-each-unconfigured-interrupt-line.patch @@ -0,0 +1,53 @@ +From: Tyler Hicks +Date: Tue, 11 Jan 2022 10:38:00 -0600 +Subject: EDAC/dmc520: Don't print an error for each unconfigured interrupt + line +Git-commit: ad2df24732e8956a45a00894d2163c4ee8fb0e1f +Patch-mainline: v5.19-rc1 +References: bsc#1190497 + +The dmc520 driver requires that at least one interrupt line, out of the +ten possible, is configured. The driver prints an error and returns +-EINVAL from its .probe function if there are no interrupt lines +configured. + +Don't print a KERN_ERR level message for each interrupt line that's +unconfigured as that can confuse users into thinking that there is an +error condition. + +Before this change, the following KERN_ERR level messages would be +reported if only dram_ecc_errc and dram_ecc_errd were configured in the +device tree: + + dmc520 68000000.dmc: IRQ ram_ecc_errc not found + dmc520 68000000.dmc: IRQ ram_ecc_errd not found + dmc520 68000000.dmc: IRQ failed_access not found + dmc520 68000000.dmc: IRQ failed_prog not found + dmc520 68000000.dmc: IRQ link_err not + dmc520 68000000.dmc: IRQ temperature_event not found + dmc520 68000000.dmc: IRQ arch_fsm not found + dmc520 68000000.dmc: IRQ phy_request not found + +Fixes: 1088750d7839 ("EDAC: Add EDAC driver for DMC520") +Reported-by: Sinan Kaya +Signed-off-by: Tyler Hicks +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220111163800.22362-1-tyhicks@linux.microsoft.com +--- + drivers/edac/dmc520_edac.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/edac/dmc520_edac.c b/drivers/edac/dmc520_edac.c +index b8a7d9594afd..1fa5ca57e9ec 100644 +--- a/drivers/edac/dmc520_edac.c ++++ b/drivers/edac/dmc520_edac.c +@@ -489,7 +489,7 @@ static int dmc520_edac_probe(struct platform_device *pdev) + dev = &pdev->dev; + + for (idx = 0; idx < NUMBER_OF_IRQS; idx++) { +- irq = platform_get_irq_byname(pdev, dmc520_irq_configs[idx].name); ++ irq = platform_get_irq_byname_optional(pdev, dmc520_irq_configs[idx].name); + irqs[idx] = irq; + masks[idx] = dmc520_irq_configs[idx].mask; + if (irq >= 0) { + diff --git a/patches.suse/efi-Correct-Macmini-DMI-match-in-uefi-cert-quirk.patch b/patches.suse/efi-Correct-Macmini-DMI-match-in-uefi-cert-quirk.patch new file mode 100644 index 0000000..0a1f75a --- /dev/null +++ b/patches.suse/efi-Correct-Macmini-DMI-match-in-uefi-cert-quirk.patch @@ -0,0 +1,60 @@ +From bab715bdaa9ebf28d99a6d1efb2704a30125e96d Mon Sep 17 00:00:00 2001 +From: Orlando Chamberlain +Date: Thu, 29 Sep 2022 11:49:56 +0000 +Subject: [PATCH] efi: Correct Macmini DMI match in uefi cert quirk +Git-commit: bab715bdaa9ebf28d99a6d1efb2704a30125e96d +Patch-mainline: v6.1-rc1 +References: git-fixes + +It turns out Apple doesn't capitalise the "mini" in "Macmini" in DMI, which +is inconsistent with other model line names. + +Correct the capitalisation of Macmini in the quirk for skipping loading +platform certs on T2 Macs. + +Currently users get: + +------------[ cut here ]------------ +[Firmware Bug]: Page fault caused by firmware at PA: 0xffffa30640054000 +WARNING: CPU: 1 PID: 8 at arch/x86/platform/efi/quirks.c:735 efi_crash_gracefully_on_page_fault+0x55/0xe0 +Modules linked in: +CPU: 1 PID: 8 Comm: kworker/u12:0 Not tainted 5.18.14-arch1-2-t2 #1 4535eb3fc40fd08edab32a509fbf4c9bc52d111e +Hardware name: Apple Inc. Macmini8,1/Mac-7BA5B2DFE22DDD8C, BIOS 1731.120.10.0.0 (iBridge: 19.16.15071.0.0,0) 04/24/2022 +Workqueue: efi_rts_wq efi_call_rts +... +---[ end trace 0000000000000000 ]--- +efi: Froze efi_rts_wq and disabled EFI Runtime Services +integrity: Couldn't get size: 0x8000000000000015 +integrity: MODSIGN: Couldn't get UEFI db list +efi: EFI Runtime Services are disabled! +integrity: Couldn't get size: 0x8000000000000015 +integrity: Couldn't get UEFI dbx list + +Fixes: 155ca952c7ca ("efi: Do not import certificates from UEFI Secure Boot for T2 Macs") +Cc: stable@vger.kernel.org +Cc: Aditya Garg +Tested-by: Samuel Jiang +Signed-off-by: Orlando Chamberlain +Signed-off-by: Mimi Zohar +Acked-by: Takashi Iwai + +--- + security/integrity/platform_certs/load_uefi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/security/integrity/platform_certs/load_uefi.c b/security/integrity/platform_certs/load_uefi.c +index 093894a640dc..b78753d27d8e 100644 +--- a/security/integrity/platform_certs/load_uefi.c ++++ b/security/integrity/platform_certs/load_uefi.c +@@ -31,7 +31,7 @@ static const struct dmi_system_id uefi_skip_cert[] = { + { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookAir8,1") }, + { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookAir8,2") }, + { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookAir9,1") }, +- { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacMini8,1") }, ++ { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "Macmini8,1") }, + { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacPro7,1") }, + { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "iMac20,1") }, + { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "iMac20,2") }, +-- +2.35.3 + diff --git a/patches.suse/efi-capsule-loader-Fix-use-after-free-in-efi_capsule.patch b/patches.suse/efi-capsule-loader-Fix-use-after-free-in-efi_capsule.patch new file mode 100644 index 0000000..77abe9e --- /dev/null +++ b/patches.suse/efi-capsule-loader-Fix-use-after-free-in-efi_capsule.patch @@ -0,0 +1,87 @@ +From 9cb636b5f6a8cc6d1b50809ec8f8d33ae0c84c95 Mon Sep 17 00:00:00 2001 +From: Hyunwoo Kim +Date: Wed, 7 Sep 2022 09:07:14 -0700 +Subject: [PATCH] efi: capsule-loader: Fix use-after-free in efi_capsule_write +Git-commit: 9cb636b5f6a8cc6d1b50809ec8f8d33ae0c84c95 +Patch-mainline: v6.0-rc5 +References: git-fixes + +A race condition may occur if the user calls close() on another thread +during a write() operation on the device node of the efi capsule. + +This is a race condition that occurs between the efi_capsule_write() and +efi_capsule_flush() functions of efi_capsule_fops, which ultimately +results in UAF. + +So, the page freeing process is modified to be done in +efi_capsule_release() instead of efi_capsule_flush(). + +Cc: # v4.9+ +Signed-off-by: Hyunwoo Kim +Link: https://lore.kernel.org/all/20220907102920.GA88602@ubuntu/ +Signed-off-by: Ard Biesheuvel +Acked-by: Takashi Iwai + +--- + drivers/firmware/efi/capsule-loader.c | 31 ++++++--------------------- + 1 file changed, 7 insertions(+), 24 deletions(-) + +diff --git a/drivers/firmware/efi/capsule-loader.c b/drivers/firmware/efi/capsule-loader.c +index 4dde8edd53b6..3e8d4b51a814 100644 +--- a/drivers/firmware/efi/capsule-loader.c ++++ b/drivers/firmware/efi/capsule-loader.c +@@ -242,29 +242,6 @@ static ssize_t efi_capsule_write(struct file *file, const char __user *buff, + return ret; + } + +-/** +- * efi_capsule_flush - called by file close or file flush +- * @file: file pointer +- * @id: not used +- * +- * If a capsule is being partially uploaded then calling this function +- * will be treated as upload termination and will free those completed +- * buffer pages and -ECANCELED will be returned. +- **/ +-static int efi_capsule_flush(struct file *file, fl_owner_t id) +-{ +- int ret = 0; +- struct capsule_info *cap_info = file->private_data; +- +- if (cap_info->index > 0) { +- pr_err("capsule upload not complete\n"); +- efi_free_all_buff_pages(cap_info); +- ret = -ECANCELED; +- } +- +- return ret; +-} +- + /** + * efi_capsule_release - called by file close + * @inode: not used +@@ -277,6 +254,13 @@ static int efi_capsule_release(struct inode *inode, struct file *file) + { + struct capsule_info *cap_info = file->private_data; + ++ if (cap_info->index > 0 && ++ (cap_info->header.headersize == 0 || ++ cap_info->count < cap_info->total_size)) { ++ pr_err("capsule upload not complete\n"); ++ efi_free_all_buff_pages(cap_info); ++ } ++ + kfree(cap_info->pages); + kfree(cap_info->phys); + kfree(file->private_data); +@@ -324,7 +308,6 @@ static const struct file_operations efi_capsule_fops = { + .owner = THIS_MODULE, + .open = efi_capsule_open, + .write = efi_capsule_write, +- .flush = efi_capsule_flush, + .release = efi_capsule_release, + .llseek = no_llseek, + }; +-- +2.35.3 + diff --git a/patches.suse/efi-libstub-Disable-struct-randomization.patch b/patches.suse/efi-libstub-Disable-struct-randomization.patch new file mode 100644 index 0000000..2a1e90f --- /dev/null +++ b/patches.suse/efi-libstub-Disable-struct-randomization.patch @@ -0,0 +1,56 @@ +From 1a3887924a7e6edd331be76da7bf4c1e8eab4b1e Mon Sep 17 00:00:00 2001 +From: Ard Biesheuvel +Date: Mon, 22 Aug 2022 19:20:33 +0200 +Subject: [PATCH] efi: libstub: Disable struct randomization +Git-commit: 1a3887924a7e6edd331be76da7bf4c1e8eab4b1e +Patch-mainline: v6.0-rc5 +References: git-fixes + +The EFI stub is a wrapper around the core kernel that makes it look like +a EFI compatible PE/COFF application to the EFI firmware. EFI +applications run on top of the EFI runtime, which is heavily based on +so-called protocols, which are struct types consisting [mostly] of +function pointer members that are instantiated and recorded in a +protocol database. + +These structs look like the ideal randomization candidates to the +randstruct plugin (as they only carry function pointers), but of course, +these protocols are contracts between the firmware that exposes them, +and the EFI applications (including our stubbed kernel) that invoke +them. This means that struct randomization for EFI protocols is not a +great idea, and given that the stub shares very little data with the +core kernel that is represented as a randomizable struct, we're better +off just disabling it completely here. + +Cc: # v4.14+ +Reported-by: Daniel Marth +Tested-by: Daniel Marth +Signed-off-by: Ard Biesheuvel +Acked-by: Kees Cook +Acked-by: Takashi Iwai + +--- + drivers/firmware/efi/libstub/Makefile | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile +index d0537573501e..2c67f71f2375 100644 +--- a/drivers/firmware/efi/libstub/Makefile ++++ b/drivers/firmware/efi/libstub/Makefile +@@ -37,6 +37,13 @@ KBUILD_CFLAGS := $(cflags-y) -Os -DDISABLE_BRANCH_PROFILING \ + $(call cc-option,-fno-addrsig) \ + -D__DISABLE_EXPORTS + ++# ++# struct randomization only makes sense for Linux internal types, which the EFI ++# stub code never touches, so let's turn off struct randomization for the stub ++# altogether ++# ++KBUILD_CFLAGS := $(filter-out $(RANDSTRUCT_CFLAGS), $(KBUILD_CFLAGS)) ++ + # remove SCS flags from all objects in this directory + KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_SCS), $(KBUILD_CFLAGS)) + # disable LTO +-- +2.35.3 + diff --git a/patches.suse/efi-libstub-drop-pointless-get_memory_map-call.patch b/patches.suse/efi-libstub-drop-pointless-get_memory_map-call.patch new file mode 100644 index 0000000..f073052 --- /dev/null +++ b/patches.suse/efi-libstub-drop-pointless-get_memory_map-call.patch @@ -0,0 +1,42 @@ +From d80ca810f096ff66f451e7a3ed2f0cd9ef1ff519 Mon Sep 17 00:00:00 2001 +From: Ard Biesheuvel +Date: Thu, 15 Sep 2022 19:00:24 +0200 +Subject: [PATCH] efi: libstub: drop pointless get_memory_map() call +Git-commit: d80ca810f096ff66f451e7a3ed2f0cd9ef1ff519 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Currently, the non-x86 stub code calls get_memory_map() redundantly, +given that the data it returns is never used anywhere. So drop the call. + +Cc: # v4.14+ +Fixes: 24d7c494ce46 ("efi/arm-stub: Round up FDT allocation to mapping size") +Signed-off-by: Ard Biesheuvel +Acked-by: Takashi Iwai + +--- + drivers/firmware/efi/libstub/fdt.c | 8 -------- + 1 file changed, 8 deletions(-) + +diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c +index fe567be0f118..804f542be3f2 100644 +--- a/drivers/firmware/efi/libstub/fdt.c ++++ b/drivers/firmware/efi/libstub/fdt.c +@@ -280,14 +280,6 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle, + goto fail; + } + +- /* +- * Now that we have done our final memory allocation (and free) +- * we can get the memory map key needed for exit_boot_services(). +- */ +- status = efi_get_memory_map(&map); +- if (status != EFI_SUCCESS) +- goto fail_free_new_fdt; +- + status = update_fdt((void *)fdt_addr, fdt_size, + (void *)*new_fdt_addr, MAX_FDT_SIZE, cmdline_ptr, + initrd_addr, initrd_size); +-- +2.35.3 + diff --git a/patches.suse/eth-alx-take-rtnl_lock-on-resume.patch b/patches.suse/eth-alx-take-rtnl_lock-on-resume.patch new file mode 100644 index 0000000..1d29961 --- /dev/null +++ b/patches.suse/eth-alx-take-rtnl_lock-on-resume.patch @@ -0,0 +1,78 @@ +From 6ad1c94e1e7e374d88f0cfd77936dddb8339aaba Mon Sep 17 00:00:00 2001 +From: Jakub Kicinski +Date: Wed, 28 Sep 2022 11:12:36 -0700 +Subject: [PATCH] eth: alx: take rtnl_lock on resume +Git-commit: 6ad1c94e1e7e374d88f0cfd77936dddb8339aaba +Patch-mainline: v6.1-rc1 +References: git-fixes + +Zbynek reports that alx trips an rtnl assertion on resume: + + RTNL: assertion failed at net/core/dev.c (2891) + RIP: 0010:netif_set_real_num_tx_queues+0x1ac/0x1c0 + Call Trace: + + __alx_open+0x230/0x570 [alx] + alx_resume+0x54/0x80 [alx] + ? pci_legacy_resume+0x80/0x80 + dpm_run_callback+0x4a/0x150 + device_resume+0x8b/0x190 + async_resume+0x19/0x30 + async_run_entry_fn+0x30/0x130 + process_one_work+0x1e5/0x3b0 + +indeed the driver does not hold rtnl_lock during its internal close +and re-open functions during suspend/resume. Note that this is not +a huge bug as the driver implements its own locking, and does not +implement changing the number of queues, but we need to silence +the splat. + +Fixes: 4a5fe57e7751 ("alx: use fine-grained locking instead of RTNL") +Reported-and-tested-by: Zbynek Michl +Reviewed-by: Niels Dossche +Link: https://lore.kernel.org/r/20220928181236.1053043-1-kuba@kernel.org +Signed-off-by: Jakub Kicinski +Acked-by: Takashi Iwai + +--- + drivers/net/ethernet/atheros/alx/main.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c +index a89b93cb4e26..d5939586c82e 100644 +--- a/drivers/net/ethernet/atheros/alx/main.c ++++ b/drivers/net/ethernet/atheros/alx/main.c +@@ -1912,11 +1912,14 @@ static int alx_suspend(struct device *dev) + + if (!netif_running(alx->dev)) + return 0; ++ ++ rtnl_lock(); + netif_device_detach(alx->dev); + + mutex_lock(&alx->mtx); + __alx_stop(alx); + mutex_unlock(&alx->mtx); ++ rtnl_unlock(); + + return 0; + } +@@ -1927,6 +1930,7 @@ static int alx_resume(struct device *dev) + struct alx_hw *hw = &alx->hw; + int err; + ++ rtnl_lock(); + mutex_lock(&alx->mtx); + alx_reset_phy(hw); + +@@ -1943,6 +1947,7 @@ static int alx_resume(struct device *dev) + + unlock: + mutex_unlock(&alx->mtx); ++ rtnl_unlock(); + return err; + } + +-- +2.35.3 + diff --git a/patches.suse/eth-sun-cassini-remove-dead-code.patch b/patches.suse/eth-sun-cassini-remove-dead-code.patch new file mode 100644 index 0000000..4b10802 --- /dev/null +++ b/patches.suse/eth-sun-cassini-remove-dead-code.patch @@ -0,0 +1,48 @@ +From 01219e363ad95c646ac52f4e3176e3940c047514 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Martin=20Li=C5=A1ka?= +Date: Wed, 18 May 2022 09:18:53 +0200 +Subject: [PATCH 11/19] eth: sun: cassini: remove dead code +Git-commit: 32329216ca1d6ee29c41215f18b3053bb6158541 +Patch-mainline: v5.19-rc1 +References: git-fixes + +Fixes the following GCC warning: + +drivers/net/ethernet/sun/cassini.c:1316:29: error: comparison between two arrays [-Werror=array-compare] +drivers/net/ethernet/sun/cassini.c:3783:34: error: comparison between two arrays [-Werror=array-compare] + +Note that 2 arrays should be compared by comparing of their addresses: +note: use ‘&cas_prog_workaroundtab[0] == &cas_prog_null[0]’ to compare the addresses + +Signed-off-by: Martin Liska +Signed-off-by: David S. Miller +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/sun/cassini.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/sun/cassini.c b/drivers/net/ethernet/sun/cassini.c +index 981685c88308..9c0156069464 100644 +--- a/drivers/net/ethernet/sun/cassini.c ++++ b/drivers/net/ethernet/sun/cassini.c +@@ -1325,7 +1325,7 @@ static void cas_init_rx_dma(struct cas *cp) + writel(val, cp->regs + REG_RX_PAGE_SIZE); + + /* enable the header parser if desired */ +- if (CAS_HP_FIRMWARE == cas_prog_null) ++ if (&CAS_HP_FIRMWARE[0] == &cas_prog_null[0]) + return; + + val = CAS_BASE(HP_CFG_NUM_CPU, CAS_NCPUS > 63 ? 0 : CAS_NCPUS); +@@ -3794,7 +3794,7 @@ static void cas_reset(struct cas *cp, int blkflag) + + /* program header parser */ + if ((cp->cas_flags & CAS_FLAG_TARGET_ABORT) || +- (CAS_HP_ALT_FIRMWARE == cas_prog_null)) { ++ (&CAS_HP_ALT_FIRMWARE[0] == &cas_prog_null[0])) { + cas_load_firmware(cp, CAS_HP_FIRMWARE); + } else { + cas_load_firmware(cp, CAS_HP_ALT_FIRMWARE); +-- +2.16.4 + diff --git a/patches.suse/ethernet-Remove-vf-rate-limit-check-for-drivers.patch b/patches.suse/ethernet-Remove-vf-rate-limit-check-for-drivers.patch new file mode 100644 index 0000000..94028d9 --- /dev/null +++ b/patches.suse/ethernet-Remove-vf-rate-limit-check-for-drivers.patch @@ -0,0 +1,100 @@ +From: Bin Chen +Date: Thu, 9 Jun 2022 10:47:17 +0200 +Subject: ethernet: Remove vf rate limit check for drivers +Git-commit: 10e11aa241b688147e1b8ac908824fc058585154 +Patch-mainline: v6.0-rc1 +References: jsc#PED-1302 + +The commit a14857c27a50 ("rtnetlink: verify rate parameters for calls to +ndo_set_vf_rate") has been merged to master, so we can to remove the +now-duplicate checks in drivers. + +Signed-off-by: Bin Chen +Signed-off-by: Baowen Zheng +Signed-off-by: Simon Horman +Link: https://lore.kernel.org/r/20220609084717.155154-1-simon.horman@corigine.com +Signed-off-by: Jakub Kicinski +Acked-by: Lee Duncan +--- + drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c | 2 +- + drivers/net/ethernet/huawei/hinic/hinic_sriov.c | 6 ------ + drivers/net/ethernet/intel/ice/ice_sriov.c | 10 ---------- + drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c | 6 ++---- + 4 files changed, 3 insertions(+), 21 deletions(-) + +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c +index ddf2f3963abe..c4ed43604ddc 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c +@@ -307,7 +307,7 @@ int bnxt_set_vf_bw(struct net_device *dev, int vf_id, int min_tx_rate, + return -EINVAL; + } + +- if (min_tx_rate > pf_link_speed || min_tx_rate > max_tx_rate) { ++ if (min_tx_rate > pf_link_speed) { + netdev_info(bp->dev, "min tx rate %d is invalid for VF %d\n", + min_tx_rate, vf_id); + return -EINVAL; +diff --git a/drivers/net/ethernet/huawei/hinic/hinic_sriov.c b/drivers/net/ethernet/huawei/hinic/hinic_sriov.c +index 01e7d3c0b68e..df555847afb5 100644 +--- a/drivers/net/ethernet/huawei/hinic/hinic_sriov.c ++++ b/drivers/net/ethernet/huawei/hinic/hinic_sriov.c +@@ -852,12 +852,6 @@ int hinic_ndo_set_vf_bw(struct net_device *netdev, + return -EINVAL; + } + +- if (max_tx_rate < min_tx_rate) { +- netif_err(nic_dev, drv, netdev, "Max rate %d must be greater than or equal to min rate %d\n", +- max_tx_rate, min_tx_rate); +- return -EINVAL; +- } +- + err = hinic_port_link_state(nic_dev, &link_state); + if (err) { + netif_err(nic_dev, drv, netdev, +diff --git a/drivers/net/ethernet/intel/ice/ice_sriov.c b/drivers/net/ethernet/intel/ice/ice_sriov.c +index bb1721f1321d..86093b2511d8 100644 +--- a/drivers/net/ethernet/intel/ice/ice_sriov.c ++++ b/drivers/net/ethernet/intel/ice/ice_sriov.c +@@ -1593,16 +1593,6 @@ ice_set_vf_bw(struct net_device *netdev, int vf_id, int min_tx_rate, + goto out_put_vf; + } + +- /* when max_tx_rate is zero that means no max Tx rate limiting, so only +- * check if max_tx_rate is non-zero +- */ +- if (max_tx_rate && min_tx_rate > max_tx_rate) { +- dev_err(dev, "Cannot set min Tx rate %d Mbps greater than max Tx rate %d Mbps\n", +- min_tx_rate, max_tx_rate); +- ret = -EINVAL; +- goto out_put_vf; +- } +- + if (min_tx_rate && ice_is_dcb_active(pf)) { + dev_err(dev, "DCB on PF is currently enabled. VF min Tx rate limiting not allowed on this PF.\n"); + ret = -EOPNOTSUPP; +diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c +index e90fa97c0ae6..8dd7aa08ecfb 100644 +--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c ++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c +@@ -1869,8 +1869,7 @@ int qlcnic_sriov_set_vf_tx_rate(struct net_device *netdev, int vf, + if (!min_tx_rate) + min_tx_rate = QLC_VF_MIN_TX_RATE; + +- if (max_tx_rate && +- (max_tx_rate >= 10000 || max_tx_rate < min_tx_rate)) { ++ if (max_tx_rate && max_tx_rate >= 10000) { + netdev_err(netdev, + "Invalid max Tx rate, allowed range is [%d - %d]", + min_tx_rate, QLC_VF_MAX_TX_RATE); +@@ -1880,8 +1879,7 @@ int qlcnic_sriov_set_vf_tx_rate(struct net_device *netdev, int vf, + if (!max_tx_rate) + max_tx_rate = 10000; + +- if (min_tx_rate && +- (min_tx_rate > max_tx_rate || min_tx_rate < QLC_VF_MIN_TX_RATE)) { ++ if (min_tx_rate && min_tx_rate < QLC_VF_MIN_TX_RATE) { + netdev_err(netdev, + "Invalid min Tx rate, allowed range is [%d - %d]", + QLC_VF_MIN_TX_RATE, max_tx_rate); + diff --git a/patches.suse/fbdev-chipsfb-Add-missing-pci_disable_device-in-chip.patch b/patches.suse/fbdev-chipsfb-Add-missing-pci_disable_device-in-chip.patch new file mode 100644 index 0000000..91000fb --- /dev/null +++ b/patches.suse/fbdev-chipsfb-Add-missing-pci_disable_device-in-chip.patch @@ -0,0 +1,33 @@ +From 07c55c9803dea748d17a054000cbf1913ce06399 Mon Sep 17 00:00:00 2001 +From: Yang Yingliang +Date: Fri, 19 Aug 2022 16:57:52 +0800 +Subject: [PATCH] fbdev: chipsfb: Add missing pci_disable_device() in chipsfb_pci_init() +Git-commit: 07c55c9803dea748d17a054000cbf1913ce06399 +Patch-mainline: v6.0-rc3 +References: git-fixes + +Add missing pci_disable_device() in error path in chipsfb_pci_init(). + +Signed-off-by: Yang Yingliang +Signed-off-by: Helge Deller +Acked-by: Takashi Iwai + +--- + drivers/video/fbdev/chipsfb.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/video/fbdev/chipsfb.c b/drivers/video/fbdev/chipsfb.c +index 393894af26f8..2b00a9d554fc 100644 +--- a/drivers/video/fbdev/chipsfb.c ++++ b/drivers/video/fbdev/chipsfb.c +@@ -430,6 +430,7 @@ static int chipsfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent) + err_release_fb: + framebuffer_release(p); + err_disable: ++ pci_disable_device(dp); + err_out: + return rc; + } +-- +2.35.3 + diff --git a/patches.suse/fbdev-smscufx-Fix-use-after-free-in-ufx_ops_open.patch b/patches.suse/fbdev-smscufx-Fix-use-after-free-in-ufx_ops_open.patch new file mode 100644 index 0000000..9dcdef7 --- /dev/null +++ b/patches.suse/fbdev-smscufx-Fix-use-after-free-in-ufx_ops_open.patch @@ -0,0 +1,85 @@ +From 6a7bca685c93fd18133d313716e141faac3bddc3 Mon Sep 17 00:00:00 2001 +From: Hyunwoo Kim +Date: Sun, 25 Sep 2022 06:32:43 -0700 +Subject: [PATCH] fbdev: smscufx: Fix use-after-free in ufx_ops_open() +Git-commit: 6a7bca685c93fd18133d313716e141faac3bddc3 +Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/deller/linux-fbdev.git +Patch-mainline: Queued in subsystem maintainer repo +References: CVE-2022-41849 bsc#1203992 + +A race condition may occur if the user physically removes the +USB device while calling open() for this device node. + +This is a race condition between the ufx_ops_open() function and +the ufx_usb_disconnect() function, which may eventually result in UAF. + +So, add a mutex to the ufx_ops_open() and ufx_usb_disconnect() functions +to avoid race contidion of krefs. + +Signed-off-by: Hyunwoo Kim +Cc: stable@vger.kernel.org +Signed-off-by: Helge Deller +Acked-by: Takashi Iwai + +--- + drivers/video/fbdev/smscufx.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/drivers/video/fbdev/smscufx.c b/drivers/video/fbdev/smscufx.c +index d7aa5511c361..e65bdc499c23 100644 +--- a/drivers/video/fbdev/smscufx.c ++++ b/drivers/video/fbdev/smscufx.c +@@ -137,6 +137,8 @@ static int ufx_submit_urb(struct ufx_data *dev, struct urb * urb, size_t len); + static int ufx_alloc_urb_list(struct ufx_data *dev, int count, size_t size); + static void ufx_free_urb_list(struct ufx_data *dev); + ++static DEFINE_MUTEX(disconnect_mutex); ++ + /* reads a control register */ + static int ufx_reg_read(struct ufx_data *dev, u32 index, u32 *data) + { +@@ -1071,9 +1073,13 @@ static int ufx_ops_open(struct fb_info *info, int user) + if (user == 0 && !console) + return -EBUSY; + ++ mutex_lock(&disconnect_mutex); ++ + /* If the USB device is gone, we don't accept new opens */ +- if (dev->virtualized) ++ if (dev->virtualized) { ++ mutex_unlock(&disconnect_mutex); + return -ENODEV; ++ } + + dev->fb_count++; + +@@ -1097,6 +1103,8 @@ static int ufx_ops_open(struct fb_info *info, int user) + pr_debug("open /dev/fb%d user=%d fb_info=%p count=%d", + info->node, user, info, dev->fb_count); + ++ mutex_unlock(&disconnect_mutex); ++ + return 0; + } + +@@ -1741,6 +1749,8 @@ static void ufx_usb_disconnect(struct usb_interface *interface) + { + struct ufx_data *dev; + ++ mutex_lock(&disconnect_mutex); ++ + dev = usb_get_intfdata(interface); + + pr_debug("USB disconnect starting\n"); +@@ -1761,6 +1771,8 @@ static void ufx_usb_disconnect(struct usb_interface *interface) + kref_put(&dev->kref, ufx_free); + + /* consider ufx_data freed */ ++ ++ mutex_unlock(&disconnect_mutex); + } + + static struct usb_driver ufx_driver = { +-- +2.35.3 + diff --git a/patches.suse/firmware-arm_scmi-Add-SCMI-PM-driver-remove-routine.patch b/patches.suse/firmware-arm_scmi-Add-SCMI-PM-driver-remove-routine.patch new file mode 100644 index 0000000..630f026 --- /dev/null +++ b/patches.suse/firmware-arm_scmi-Add-SCMI-PM-driver-remove-routine.patch @@ -0,0 +1,81 @@ +From dea796fcab0a219830831c070b8dc367d7e0f708 Mon Sep 17 00:00:00 2001 +From: Cristian Marussi +Date: Wed, 17 Aug 2022 18:27:31 +0100 +Subject: [PATCH] firmware: arm_scmi: Add SCMI PM driver remove routine +Git-commit: dea796fcab0a219830831c070b8dc367d7e0f708 +Patch-mainline: v6.0-rc7 +References: git-fixes + +Currently, when removing the SCMI PM driver not all the resources +registered with genpd subsystem are properly de-registered. + +As a side effect of this after a driver unload/load cycle you get a +splat with a few warnings like this: + + | debugfs: Directory 'BIG_CPU0' with parent 'pm_genpd' already present! + | debugfs: Directory 'BIG_CPU1' with parent 'pm_genpd' already present! + | debugfs: Directory 'LITTLE_CPU0' with parent 'pm_genpd' already present! + | debugfs: Directory 'LITTLE_CPU1' with parent 'pm_genpd' already present! + | debugfs: Directory 'LITTLE_CPU2' with parent 'pm_genpd' already present! + | debugfs: Directory 'LITTLE_CPU3' with parent 'pm_genpd' already present! + | debugfs: Directory 'BIG_SSTOP' with parent 'pm_genpd' already present! + | debugfs: Directory 'LITTLE_SSTOP' with parent 'pm_genpd' already present! + | debugfs: Directory 'DBGSYS' with parent 'pm_genpd' already present! + | debugfs: Directory 'GPUTOP' with parent 'pm_genpd' already present! + +Add a proper scmi_pm_domain_remove callback to the driver in order to +take care of all the needed cleanups not handled by devres framework. + +Link: https://lore.kernel.org/r/20220817172731.1185305-7-cristian.marussi@arm.com +Signed-off-by: Cristian Marussi +Signed-off-by: Sudeep Holla +Acked-by: Takashi Iwai + +--- + drivers/firmware/arm_scmi/scmi_pm_domain.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/drivers/firmware/arm_scmi/scmi_pm_domain.c b/drivers/firmware/arm_scmi/scmi_pm_domain.c +index 581d34c95769..4e27c3d66a83 100644 +--- a/drivers/firmware/arm_scmi/scmi_pm_domain.c ++++ b/drivers/firmware/arm_scmi/scmi_pm_domain.c +@@ -138,9 +138,28 @@ static int scmi_pm_domain_probe(struct scmi_device *sdev) + scmi_pd_data->domains = domains; + scmi_pd_data->num_domains = num_domains; + ++ dev_set_drvdata(dev, scmi_pd_data); ++ + return of_genpd_add_provider_onecell(np, scmi_pd_data); + } + ++static void scmi_pm_domain_remove(struct scmi_device *sdev) ++{ ++ int i; ++ struct genpd_onecell_data *scmi_pd_data; ++ struct device *dev = &sdev->dev; ++ struct device_node *np = dev->of_node; ++ ++ of_genpd_del_provider(np); ++ ++ scmi_pd_data = dev_get_drvdata(dev); ++ for (i = 0; i < scmi_pd_data->num_domains; i++) { ++ if (!scmi_pd_data->domains[i]) ++ continue; ++ pm_genpd_remove(scmi_pd_data->domains[i]); ++ } ++} ++ + static const struct scmi_device_id scmi_id_table[] = { + { SCMI_PROTOCOL_POWER, "genpd" }, + { }, +@@ -150,6 +169,7 @@ MODULE_DEVICE_TABLE(scmi, scmi_id_table); + static struct scmi_driver scmi_power_domain_driver = { + .name = "scmi-power-domain", + .probe = scmi_pm_domain_probe, ++ .remove = scmi_pm_domain_remove, + .id_table = scmi_id_table, + }; + module_scmi_driver(scmi_power_domain_driver); +-- +2.35.3 + diff --git a/patches.suse/firmware-arm_scmi-Fix-the-asynchronous-reset-request.patch b/patches.suse/firmware-arm_scmi-Fix-the-asynchronous-reset-request.patch new file mode 100644 index 0000000..57a4638 --- /dev/null +++ b/patches.suse/firmware-arm_scmi-Fix-the-asynchronous-reset-request.patch @@ -0,0 +1,56 @@ +From b75c83d9b961fd3abf7310f8d36d5e6e9f573efb Mon Sep 17 00:00:00 2001 +From: Cristian Marussi +Date: Wed, 17 Aug 2022 18:27:30 +0100 +Subject: [PATCH] firmware: arm_scmi: Fix the asynchronous reset requests +Git-commit: b75c83d9b961fd3abf7310f8d36d5e6e9f573efb +Patch-mainline: v6.0-rc7 +References: git-fixes + +SCMI Reset protocol specification allows the asynchronous reset request +only when an autonomous reset action is specified. Reset requests based +on explicit assert/deassert of signals should not be served +asynchronously. + +Current implementation will instead issue an asynchronous request in any +case, as long as the reset domain had advertised to support asynchronous +resets. + +Avoid requesting the asynchronous resets when the reset action is not +of the autonomous type, even if the target reset domain does, in general, +support the asynchronous requests. + +Link: https://lore.kernel.org/r/20220817172731.1185305-6-cristian.marussi@arm.com +Fixes: 95a15d80aa0d ("firmware: arm_scmi: Add RESET protocol in SCMI v2.0") +Signed-off-by: Cristian Marussi +Signed-off-by: Sudeep Holla +Acked-by: Takashi Iwai + +--- + drivers/firmware/arm_scmi/reset.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/firmware/arm_scmi/reset.c b/drivers/firmware/arm_scmi/reset.c +index b0494165b1cb..e9afa8cab730 100644 +--- a/drivers/firmware/arm_scmi/reset.c ++++ b/drivers/firmware/arm_scmi/reset.c +@@ -172,7 +172,7 @@ static int scmi_domain_reset(const struct scmi_protocol_handle *ph, u32 domain, + return -EINVAL; + + rdom = pi->dom_info + domain; +- if (rdom->async_reset) ++ if (rdom->async_reset && flags & AUTONOMOUS_RESET) + flags |= ASYNCHRONOUS_RESET; + + ret = ph->xops->xfer_get_init(ph, RESET, sizeof(*dom), 0, &t); +@@ -184,7 +184,7 @@ static int scmi_domain_reset(const struct scmi_protocol_handle *ph, u32 domain, + dom->flags = cpu_to_le32(flags); + dom->reset_state = cpu_to_le32(state); + +- if (rdom->async_reset) ++ if (flags & ASYNCHRONOUS_RESET) + ret = ph->xops->do_xfer_with_response(ph, t); + else + ret = ph->xops->do_xfer(ph, t); +-- +2.35.3 + diff --git a/patches.suse/firmware-arm_scmi-Harden-accesses-to-the-reset-domai.patch b/patches.suse/firmware-arm_scmi-Harden-accesses-to-the-reset-domai.patch new file mode 100644 index 0000000..d5f3185 --- /dev/null +++ b/patches.suse/firmware-arm_scmi-Harden-accesses-to-the-reset-domai.patch @@ -0,0 +1,45 @@ +From e9076ffbcaed5da6c182b144ef9f6e24554af268 Mon Sep 17 00:00:00 2001 +From: Cristian Marussi +Date: Wed, 17 Aug 2022 18:27:29 +0100 +Subject: [PATCH] firmware: arm_scmi: Harden accesses to the reset domains +Git-commit: e9076ffbcaed5da6c182b144ef9f6e24554af268 +Patch-mainline: v6.0-rc7 +References: git-fixes + +Accessing reset domains descriptors by the index upon the SCMI drivers +requests through the SCMI reset operations interface can potentially +lead to out-of-bound violations if the SCMI driver misbehave. + +Add an internal consistency check before any such domains descriptors +accesses. + +Link: https://lore.kernel.org/r/20220817172731.1185305-5-cristian.marussi@arm.com +Signed-off-by: Cristian Marussi +Signed-off-by: Sudeep Holla +Acked-by: Takashi Iwai + +--- + drivers/firmware/arm_scmi/reset.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/firmware/arm_scmi/reset.c b/drivers/firmware/arm_scmi/reset.c +index 673f3eb498f4..b0494165b1cb 100644 +--- a/drivers/firmware/arm_scmi/reset.c ++++ b/drivers/firmware/arm_scmi/reset.c +@@ -166,8 +166,12 @@ static int scmi_domain_reset(const struct scmi_protocol_handle *ph, u32 domain, + struct scmi_xfer *t; + struct scmi_msg_reset_domain_reset *dom; + struct scmi_reset_info *pi = ph->get_priv(ph); +- struct reset_dom_info *rdom = pi->dom_info + domain; ++ struct reset_dom_info *rdom; + ++ if (domain >= pi->num_domains) ++ return -EINVAL; ++ ++ rdom = pi->dom_info + domain; + if (rdom->async_reset) + flags |= ASYNCHRONOUS_RESET; + +-- +2.35.3 + diff --git a/patches.suse/firmware-arm_scmi-Harden-accesses-to-the-sensor-doma.patch b/patches.suse/firmware-arm_scmi-Harden-accesses-to-the-sensor-doma.patch new file mode 100644 index 0000000..c4c1110 --- /dev/null +++ b/patches.suse/firmware-arm_scmi-Harden-accesses-to-the-sensor-doma.patch @@ -0,0 +1,105 @@ +From 76f89c954788763db575fb512a40bd483864f1e9 Mon Sep 17 00:00:00 2001 +From: Cristian Marussi +Date: Wed, 17 Aug 2022 18:27:28 +0100 +Subject: [PATCH] firmware: arm_scmi: Harden accesses to the sensor domains +Git-commit: 76f89c954788763db575fb512a40bd483864f1e9 +Patch-mainline: v6.0-rc7 +References: git-fixes + +Accessing sensor domains descriptors by the index upon the SCMI drivers +requests through the SCMI sensor operations interface can potentially +lead to out-of-bound violations if the SCMI driver misbehave. + +Add an internal consistency check before any such domains descriptors +accesses. + +Link: https://lore.kernel.org/r/20220817172731.1185305-4-cristian.marussi@arm.com +Signed-off-by: Cristian Marussi +Signed-off-by: Sudeep Holla +Acked-by: Takashi Iwai + +--- + drivers/firmware/arm_scmi/sensors.c | 22 ++++++++++++++++++---- + 1 file changed, 18 insertions(+), 4 deletions(-) + +diff --git a/drivers/firmware/arm_scmi/sensors.c b/drivers/firmware/arm_scmi/sensors.c +index 7d0c7476d206..0b5853fa9d87 100644 +--- a/drivers/firmware/arm_scmi/sensors.c ++++ b/drivers/firmware/arm_scmi/sensors.c +@@ -762,6 +762,10 @@ static int scmi_sensor_config_get(const struct scmi_protocol_handle *ph, + { + int ret; + struct scmi_xfer *t; ++ struct sensors_info *si = ph->get_priv(ph); ++ ++ if (sensor_id >= si->num_sensors) ++ return -EINVAL; + + ret = ph->xops->xfer_get_init(ph, SENSOR_CONFIG_GET, + sizeof(__le32), sizeof(__le32), &t); +@@ -771,7 +775,6 @@ static int scmi_sensor_config_get(const struct scmi_protocol_handle *ph, + put_unaligned_le32(sensor_id, t->tx.buf); + ret = ph->xops->do_xfer(ph, t); + if (!ret) { +- struct sensors_info *si = ph->get_priv(ph); + struct scmi_sensor_info *s = si->sensors + sensor_id; + + *sensor_config = get_unaligned_le64(t->rx.buf); +@@ -788,6 +791,10 @@ static int scmi_sensor_config_set(const struct scmi_protocol_handle *ph, + int ret; + struct scmi_xfer *t; + struct scmi_msg_sensor_config_set *msg; ++ struct sensors_info *si = ph->get_priv(ph); ++ ++ if (sensor_id >= si->num_sensors) ++ return -EINVAL; + + ret = ph->xops->xfer_get_init(ph, SENSOR_CONFIG_SET, + sizeof(*msg), 0, &t); +@@ -800,7 +807,6 @@ static int scmi_sensor_config_set(const struct scmi_protocol_handle *ph, + + ret = ph->xops->do_xfer(ph, t); + if (!ret) { +- struct sensors_info *si = ph->get_priv(ph); + struct scmi_sensor_info *s = si->sensors + sensor_id; + + s->sensor_config = sensor_config; +@@ -831,8 +837,11 @@ static int scmi_sensor_reading_get(const struct scmi_protocol_handle *ph, + int ret; + struct scmi_xfer *t; + struct scmi_msg_sensor_reading_get *sensor; ++ struct scmi_sensor_info *s; + struct sensors_info *si = ph->get_priv(ph); +- struct scmi_sensor_info *s = si->sensors + sensor_id; ++ ++ if (sensor_id >= si->num_sensors) ++ return -EINVAL; + + ret = ph->xops->xfer_get_init(ph, SENSOR_READING_GET, + sizeof(*sensor), 0, &t); +@@ -841,6 +850,7 @@ static int scmi_sensor_reading_get(const struct scmi_protocol_handle *ph, + + sensor = t->tx.buf; + sensor->id = cpu_to_le32(sensor_id); ++ s = si->sensors + sensor_id; + if (s->async) { + sensor->flags = cpu_to_le32(SENSOR_READ_ASYNC); + ret = ph->xops->do_xfer_with_response(ph, t); +@@ -895,9 +905,13 @@ scmi_sensor_reading_get_timestamped(const struct scmi_protocol_handle *ph, + int ret; + struct scmi_xfer *t; + struct scmi_msg_sensor_reading_get *sensor; ++ struct scmi_sensor_info *s; + struct sensors_info *si = ph->get_priv(ph); +- struct scmi_sensor_info *s = si->sensors + sensor_id; + ++ if (sensor_id >= si->num_sensors) ++ return -EINVAL; ++ ++ s = si->sensors + sensor_id; + if (!count || !readings || + (!s->num_axis && count > 1) || (s->num_axis && count > s->num_axis)) + return -EINVAL; +-- +2.35.3 + diff --git a/patches.suse/firmware-arm_scmi-Improve-checks-in-the-info_get-ope.patch b/patches.suse/firmware-arm_scmi-Improve-checks-in-the-info_get-ope.patch new file mode 100644 index 0000000..cb60a33 --- /dev/null +++ b/patches.suse/firmware-arm_scmi-Improve-checks-in-the-info_get-ope.patch @@ -0,0 +1,84 @@ +From 1ecb7d27b1af6705e9a4e94415b4d8cc8cf2fbfb Mon Sep 17 00:00:00 2001 +From: Cristian Marussi +Date: Wed, 17 Aug 2022 18:27:27 +0100 +Subject: [PATCH] firmware: arm_scmi: Improve checks in the info_get operations +Git-commit: 1ecb7d27b1af6705e9a4e94415b4d8cc8cf2fbfb +Patch-mainline: v6.0-rc7 +References: git-fixes + +SCMI protocols abstract and expose a number of protocol specific +resources like clocks, sensors and so on. Information about such +specific domain resources are generally exposed via an `info_get` +protocol operation. + +Improve the sanity check on these operations where needed. + +Link: https://lore.kernel.org/r/20220817172731.1185305-3-cristian.marussi@arm.com +Signed-off-by: Cristian Marussi +Signed-off-by: Sudeep Holla +Acked-by: Takashi Iwai + +--- + drivers/firmware/arm_scmi/clock.c | 6 +++++- + drivers/firmware/arm_scmi/sensors.c | 3 +++ + include/linux/scmi_protocol.h | 4 ++-- + 3 files changed, 10 insertions(+), 3 deletions(-) + +diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/clock.c +index 3ed7ae0d6781..96060bf90a24 100644 +--- a/drivers/firmware/arm_scmi/clock.c ++++ b/drivers/firmware/arm_scmi/clock.c +@@ -450,9 +450,13 @@ static int scmi_clock_count_get(const struct scmi_protocol_handle *ph) + static const struct scmi_clock_info * + scmi_clock_info_get(const struct scmi_protocol_handle *ph, u32 clk_id) + { ++ struct scmi_clock_info *clk; + struct clock_info *ci = ph->get_priv(ph); +- struct scmi_clock_info *clk = ci->clk + clk_id; + ++ if (clk_id >= ci->num_clocks) ++ return NULL; ++ ++ clk = ci->clk + clk_id; + if (!clk->name[0]) + return NULL; + +diff --git a/drivers/firmware/arm_scmi/sensors.c b/drivers/firmware/arm_scmi/sensors.c +index 7288c6117838..7d0c7476d206 100644 +--- a/drivers/firmware/arm_scmi/sensors.c ++++ b/drivers/firmware/arm_scmi/sensors.c +@@ -948,6 +948,9 @@ scmi_sensor_info_get(const struct scmi_protocol_handle *ph, u32 sensor_id) + { + struct sensors_info *si = ph->get_priv(ph); + ++ if (sensor_id >= si->num_sensors) ++ return NULL; ++ + return si->sensors + sensor_id; + } + +diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h +index a193884ecf2b..4f765bc788ff 100644 +--- a/include/linux/scmi_protocol.h ++++ b/include/linux/scmi_protocol.h +@@ -84,7 +84,7 @@ struct scmi_protocol_handle; + struct scmi_clk_proto_ops { + int (*count_get)(const struct scmi_protocol_handle *ph); + +- const struct scmi_clock_info *(*info_get) ++ const struct scmi_clock_info __must_check *(*info_get) + (const struct scmi_protocol_handle *ph, u32 clk_id); + int (*rate_get)(const struct scmi_protocol_handle *ph, u32 clk_id, + u64 *rate); +@@ -466,7 +466,7 @@ enum scmi_sensor_class { + */ + struct scmi_sensor_proto_ops { + int (*count_get)(const struct scmi_protocol_handle *ph); +- const struct scmi_sensor_info *(*info_get) ++ const struct scmi_sensor_info __must_check *(*info_get) + (const struct scmi_protocol_handle *ph, u32 sensor_id); + int (*trip_point_config)(const struct scmi_protocol_handle *ph, + u32 sensor_id, u8 trip_id, u64 trip_value); +-- +2.35.3 + diff --git a/patches.suse/firmware-cs_dsp-Add-lockdep-asserts-to-interface-fun.patch b/patches.suse/firmware-cs_dsp-Add-lockdep-asserts-to-interface-fun.patch new file mode 100644 index 0000000..ebc877f --- /dev/null +++ b/patches.suse/firmware-cs_dsp-Add-lockdep-asserts-to-interface-fun.patch @@ -0,0 +1,91 @@ +From 5065cfabec21a4acf562932f1d0a814c119e0a69 Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Wed, 17 Nov 2021 13:22:52 +0000 +Subject: [PATCH] firmware: cs_dsp: Add lockdep asserts to interface functions +Git-commit: 5065cfabec21a4acf562932f1d0a814c119e0a69 +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +Some of the control functions exposed by the cs_dsp code require the +pwr_lock to be held by the caller. Add lockdep_assert_held calls to +ensure this is done correctly. + +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20211117132300.1290-2-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + drivers/firmware/cirrus/cs_dsp.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c +index 1a0c6c793f6a..0d1ba7d8efa4 100644 +--- a/drivers/firmware/cirrus/cs_dsp.c ++++ b/drivers/firmware/cirrus/cs_dsp.c +@@ -653,6 +653,8 @@ int cs_dsp_coeff_write_acked_control(struct cs_dsp_coeff_ctl *ctl, unsigned int + unsigned int reg; + int i, ret; + ++ lockdep_assert_held(&dsp->pwr_lock); ++ + if (!dsp->running) + return -EPERM; + +@@ -754,6 +756,8 @@ int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl, const void *buf, size_ + { + int ret = 0; + ++ lockdep_assert_held(&ctl->dsp->pwr_lock); ++ + if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) + ret = -EPERM; + else if (buf != ctl->cache) +@@ -811,6 +815,8 @@ int cs_dsp_coeff_read_ctrl(struct cs_dsp_coeff_ctl *ctl, void *buf, size_t len) + { + int ret = 0; + ++ lockdep_assert_held(&ctl->dsp->pwr_lock); ++ + if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) { + if (ctl->enabled && ctl->dsp->running) + return cs_dsp_coeff_read_ctrl_raw(ctl, buf, len); +@@ -1453,6 +1459,8 @@ struct cs_dsp_coeff_ctl *cs_dsp_get_ctl(struct cs_dsp *dsp, const char *name, in + { + struct cs_dsp_coeff_ctl *pos, *rslt = NULL; + ++ lockdep_assert_held(&dsp->pwr_lock); ++ + list_for_each_entry(pos, &dsp->ctl_list, list) { + if (!pos->subname) + continue; +@@ -1548,6 +1556,8 @@ struct cs_dsp_alg_region *cs_dsp_find_alg_region(struct cs_dsp *dsp, + { + struct cs_dsp_alg_region *alg_region; + ++ lockdep_assert_held(&dsp->pwr_lock); ++ + list_for_each_entry(alg_region, &dsp->alg_regions, list) { + if (id == alg_region->alg && type == alg_region->type) + return alg_region; +@@ -2783,6 +2793,8 @@ int cs_dsp_read_raw_data_block(struct cs_dsp *dsp, int mem_type, unsigned int me + unsigned int reg; + int ret; + ++ lockdep_assert_held(&dsp->pwr_lock); ++ + if (!mem) + return -EINVAL; + +@@ -2836,6 +2848,8 @@ int cs_dsp_write_data_word(struct cs_dsp *dsp, int mem_type, unsigned int mem_ad + __be32 val = cpu_to_be32(data & 0x00ffffffu); + unsigned int reg; + ++ lockdep_assert_held(&dsp->pwr_lock); ++ + if (!mem) + return -EINVAL; + +-- +2.35.3 + diff --git a/patches.suse/firmware-cs_dsp-Add-memory-chunk-helpers.patch b/patches.suse/firmware-cs_dsp-Add-memory-chunk-helpers.patch new file mode 100644 index 0000000..d19972c --- /dev/null +++ b/patches.suse/firmware-cs_dsp-Add-memory-chunk-helpers.patch @@ -0,0 +1,237 @@ +From a4b976552f122ea851f556769874022cf097741e Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Fri, 22 Jul 2022 10:48:51 +0100 +Subject: [PATCH] firmware: cs_dsp: Add memory chunk helpers +Git-commit: a4b976552f122ea851f556769874022cf097741e +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +Add helpers that can be layered on top of a buffer read from or to be +written to the DSP to faciliate accessing datastructures within the DSP +memory. These functions handle adding the padding bytes for the DSP, +converting to big endian, and packing arbitrary length data. + +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20220722094851.92521-2-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + drivers/firmware/cirrus/cs_dsp.c | 104 +++++++++++++++++++++++++ + include/linux/firmware/cirrus/cs_dsp.h | 73 +++++++++++++++++ + 2 files changed, 177 insertions(+) + +diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c +index b402f841d72c..81cc3d0f6eec 100644 +--- a/drivers/firmware/cirrus/cs_dsp.c ++++ b/drivers/firmware/cirrus/cs_dsp.c +@@ -3180,6 +3180,110 @@ static const struct cs_dsp_ops cs_dsp_halo_ops = { + .stop_core = cs_dsp_halo_stop_core, + }; + ++/** ++ * cs_dsp_chunk_write() - Format data to a DSP memory chunk ++ * @ch: Pointer to the chunk structure ++ * @nbits: Number of bits to write ++ * @val: Value to write ++ * ++ * This function sequentially writes values into the format required for DSP ++ * memory, it handles both inserting of the padding bytes and converting to ++ * big endian. Note that data is only committed to the chunk when a whole DSP ++ * words worth of data is available. ++ * ++ * Return: Zero for success, a negative number on error. ++ */ ++int cs_dsp_chunk_write(struct cs_dsp_chunk *ch, int nbits, u32 val) ++{ ++ int nwrite, i; ++ ++ nwrite = min(CS_DSP_DATA_WORD_BITS - ch->cachebits, nbits); ++ ++ ch->cache <<= nwrite; ++ ch->cache |= val >> (nbits - nwrite); ++ ch->cachebits += nwrite; ++ nbits -= nwrite; ++ ++ if (ch->cachebits == CS_DSP_DATA_WORD_BITS) { ++ if (cs_dsp_chunk_end(ch)) ++ return -ENOSPC; ++ ++ ch->cache &= 0xFFFFFF; ++ for (i = 0; i < sizeof(ch->cache); i++, ch->cache <<= BITS_PER_BYTE) ++ *ch->data++ = (ch->cache & 0xFF000000) >> CS_DSP_DATA_WORD_BITS; ++ ++ ch->bytes += sizeof(ch->cache); ++ ch->cachebits = 0; ++ } ++ ++ if (nbits) ++ return cs_dsp_chunk_write(ch, nbits, val); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(cs_dsp_chunk_write); ++ ++/** ++ * cs_dsp_chunk_flush() - Pad remaining data with zero and commit to chunk ++ * @ch: Pointer to the chunk structure ++ * ++ * As cs_dsp_chunk_write only writes data when a whole DSP word is ready to ++ * be written out it is possible that some data will remain in the cache, this ++ * function will pad that data with zeros upto a whole DSP word and write out. ++ * ++ * Return: Zero for success, a negative number on error. ++ */ ++int cs_dsp_chunk_flush(struct cs_dsp_chunk *ch) ++{ ++ if (!ch->cachebits) ++ return 0; ++ ++ return cs_dsp_chunk_write(ch, CS_DSP_DATA_WORD_BITS - ch->cachebits, 0); ++} ++EXPORT_SYMBOL_GPL(cs_dsp_chunk_flush); ++ ++/** ++ * cs_dsp_chunk_read() - Parse data from a DSP memory chunk ++ * @ch: Pointer to the chunk structure ++ * @nbits: Number of bits to read ++ * ++ * This function sequentially reads values from a DSP memory formatted buffer, ++ * it handles both removing of the padding bytes and converting from big endian. ++ * ++ * Return: A negative number is returned on error, otherwise the read value. ++ */ ++int cs_dsp_chunk_read(struct cs_dsp_chunk *ch, int nbits) ++{ ++ int nread, i; ++ u32 result; ++ ++ if (!ch->cachebits) { ++ if (cs_dsp_chunk_end(ch)) ++ return -ENOSPC; ++ ++ ch->cache = 0; ++ ch->cachebits = CS_DSP_DATA_WORD_BITS; ++ ++ for (i = 0; i < sizeof(ch->cache); i++, ch->cache <<= BITS_PER_BYTE) ++ ch->cache |= *ch->data++; ++ ++ ch->bytes += sizeof(ch->cache); ++ } ++ ++ nread = min(ch->cachebits, nbits); ++ nbits -= nread; ++ ++ result = ch->cache >> ((sizeof(ch->cache) * BITS_PER_BYTE) - nread); ++ ch->cache <<= nread; ++ ch->cachebits -= nread; ++ ++ if (nbits) ++ result = (result << nbits) | cs_dsp_chunk_read(ch, nbits); ++ ++ return result; ++} ++EXPORT_SYMBOL_GPL(cs_dsp_chunk_read); ++ + MODULE_DESCRIPTION("Cirrus Logic DSP Support"); + MODULE_AUTHOR("Simon Trimmer "); + MODULE_LICENSE("GPL v2"); +diff --git a/include/linux/firmware/cirrus/cs_dsp.h b/include/linux/firmware/cirrus/cs_dsp.h +index 6ab230218df0..cad828e21c72 100644 +--- a/include/linux/firmware/cirrus/cs_dsp.h ++++ b/include/linux/firmware/cirrus/cs_dsp.h +@@ -11,6 +11,7 @@ + #ifndef __CS_DSP_H + #define __CS_DSP_H + ++#include + #include + #include + #include +@@ -34,6 +35,7 @@ + #define CS_ADSP2_REGION_ALL (CS_ADSP2_REGION_0 | CS_ADSP2_REGION_1_9) + + #define CS_DSP_DATA_WORD_SIZE 3 ++#define CS_DSP_DATA_WORD_BITS (3 * BITS_PER_BYTE) + + #define CS_DSP_ACKED_CTL_TIMEOUT_MS 100 + #define CS_DSP_ACKED_CTL_N_QUICKPOLLS 10 +@@ -252,4 +254,75 @@ struct cs_dsp_alg_region *cs_dsp_find_alg_region(struct cs_dsp *dsp, + + const char *cs_dsp_mem_region_name(unsigned int type); + ++/** ++ * struct cs_dsp_chunk - Describes a buffer holding data formatted for the DSP ++ * @data: Pointer to underlying buffer memory ++ * @max: Pointer to end of the buffer memory ++ * @bytes: Number of bytes read/written into the memory chunk ++ * @cache: Temporary holding data as it is formatted ++ * @cachebits: Number of bits of data currently in cache ++ */ ++struct cs_dsp_chunk { ++ u8 *data; ++ u8 *max; ++ int bytes; ++ ++ u32 cache; ++ int cachebits; ++}; ++ ++/** ++ * cs_dsp_chunk() - Create a DSP memory chunk ++ * @data: Pointer to the buffer that will be used to store data ++ * @size: Size of the buffer in bytes ++ * ++ * Return: A cs_dsp_chunk structure ++ */ ++static inline struct cs_dsp_chunk cs_dsp_chunk(void *data, int size) ++{ ++ struct cs_dsp_chunk ch = { ++ .data = data, ++ .max = data + size, ++ }; ++ ++ return ch; ++} ++ ++/** ++ * cs_dsp_chunk_end() - Check if a DSP memory chunk is full ++ * @ch: Pointer to the chunk structure ++ * ++ * Return: True if the whole buffer has been read/written ++ */ ++static inline bool cs_dsp_chunk_end(struct cs_dsp_chunk *ch) ++{ ++ return ch->data == ch->max; ++} ++ ++/** ++ * cs_dsp_chunk_bytes() - Number of bytes written/read from a DSP memory chunk ++ * @ch: Pointer to the chunk structure ++ * ++ * Return: Number of bytes read/written to the buffer ++ */ ++static inline int cs_dsp_chunk_bytes(struct cs_dsp_chunk *ch) ++{ ++ return ch->bytes; ++} ++ ++/** ++ * cs_dsp_chunk_valid_addr() - Check if an address is in a DSP memory chunk ++ * @ch: Pointer to the chunk structure ++ * ++ * Return: True if the given address is within the buffer ++ */ ++static inline bool cs_dsp_chunk_valid_addr(struct cs_dsp_chunk *ch, void *addr) ++{ ++ return (u8 *)addr >= ch->data && (u8 *)addr < ch->max; ++} ++ ++int cs_dsp_chunk_write(struct cs_dsp_chunk *ch, int nbits, u32 val); ++int cs_dsp_chunk_flush(struct cs_dsp_chunk *ch); ++int cs_dsp_chunk_read(struct cs_dsp_chunk *ch, int nbits); ++ + #endif +-- +2.35.3 + diff --git a/patches.suse/firmware-cs_dsp-Add-offset-to-cs_dsp-read-write.patch b/patches.suse/firmware-cs_dsp-Add-offset-to-cs_dsp-read-write.patch new file mode 100644 index 0000000..145641d --- /dev/null +++ b/patches.suse/firmware-cs_dsp-Add-offset-to-cs_dsp-read-write.patch @@ -0,0 +1,272 @@ +From f444da38ac924748de696c393327a44c4b8d727e Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Wed, 17 Nov 2021 13:22:59 +0000 +Subject: [PATCH] firmware: cs_dsp: Add offset to cs_dsp read/write +Git-commit: f444da38ac924748de696c393327a44c4b8d727e +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +Provide a mechanism to access only part of a control through the cs_dsp +interface. + +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20211117132300.1290-9-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + drivers/firmware/cirrus/cs_dsp.c | 44 ++++++++++++++++---------- + include/linux/firmware/cirrus/cs_dsp.h | 6 ++-- + sound/soc/codecs/wm_adsp.c | 14 ++++---- + 3 files changed, 39 insertions(+), 25 deletions(-) + +diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c +index d1bcade2efe2..5fe08de91ecd 100644 +--- a/drivers/firmware/cirrus/cs_dsp.c ++++ b/drivers/firmware/cirrus/cs_dsp.c +@@ -616,7 +616,8 @@ static void cs_dsp_halo_show_fw_status(struct cs_dsp *dsp) + offs[0], offs[1], offs[2], offs[3]); + } + +-static int cs_dsp_coeff_base_reg(struct cs_dsp_coeff_ctl *ctl, unsigned int *reg) ++static int cs_dsp_coeff_base_reg(struct cs_dsp_coeff_ctl *ctl, unsigned int *reg, ++ unsigned int off) + { + const struct cs_dsp_alg_region *alg_region = &ctl->alg_region; + struct cs_dsp *dsp = ctl->dsp; +@@ -629,7 +630,7 @@ static int cs_dsp_coeff_base_reg(struct cs_dsp_coeff_ctl *ctl, unsigned int *reg + return -EINVAL; + } + +- *reg = dsp->ops->region_to_reg(mem, ctl->alg_region.base + ctl->offset); ++ *reg = dsp->ops->region_to_reg(mem, ctl->alg_region.base + ctl->offset + off); + + return 0; + } +@@ -658,7 +659,7 @@ int cs_dsp_coeff_write_acked_control(struct cs_dsp_coeff_ctl *ctl, unsigned int + if (!dsp->running) + return -EPERM; + +- ret = cs_dsp_coeff_base_reg(ctl, ®); ++ ret = cs_dsp_coeff_base_reg(ctl, ®, 0); + if (ret) + return ret; + +@@ -712,14 +713,14 @@ int cs_dsp_coeff_write_acked_control(struct cs_dsp_coeff_ctl *ctl, unsigned int + EXPORT_SYMBOL_GPL(cs_dsp_coeff_write_acked_control); + + static int cs_dsp_coeff_write_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, +- const void *buf, size_t len) ++ unsigned int off, const void *buf, size_t len) + { + struct cs_dsp *dsp = ctl->dsp; + void *scratch; + int ret; + unsigned int reg; + +- ret = cs_dsp_coeff_base_reg(ctl, ®); ++ ret = cs_dsp_coeff_base_reg(ctl, ®, off); + if (ret) + return ret; + +@@ -745,6 +746,7 @@ static int cs_dsp_coeff_write_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, + /** + * cs_dsp_coeff_write_ctrl() - Writes the given buffer to the given coefficient control + * @ctl: pointer to coefficient control ++ * @off: word offset at which data should be written + * @buf: the buffer to write to the given control + * @len: the length of the buffer in bytes + * +@@ -752,7 +754,8 @@ static int cs_dsp_coeff_write_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, + * + * Return: Zero for success, a negative number on error. + */ +-int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl, const void *buf, size_t len) ++int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl, ++ unsigned int off, const void *buf, size_t len) + { + int ret = 0; + +@@ -761,27 +764,31 @@ int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl, const void *buf, size_ + if (!ctl) + return -ENOENT; + ++ if (len + off * sizeof(u32) > ctl->len) ++ return -EINVAL; ++ + if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) + ret = -EPERM; + else if (buf != ctl->cache) +- memcpy(ctl->cache, buf, len); ++ memcpy(ctl->cache + off * sizeof(u32), buf, len); + + ctl->set = 1; + if (ctl->enabled && ctl->dsp->running) +- ret = cs_dsp_coeff_write_ctrl_raw(ctl, buf, len); ++ ret = cs_dsp_coeff_write_ctrl_raw(ctl, off, buf, len); + + return ret; + } + EXPORT_SYMBOL_GPL(cs_dsp_coeff_write_ctrl); + +-static int cs_dsp_coeff_read_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, void *buf, size_t len) ++static int cs_dsp_coeff_read_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, ++ unsigned int off, void *buf, size_t len) + { + struct cs_dsp *dsp = ctl->dsp; + void *scratch; + int ret; + unsigned int reg; + +- ret = cs_dsp_coeff_base_reg(ctl, ®); ++ ret = cs_dsp_coeff_base_reg(ctl, ®, off); + if (ret) + return ret; + +@@ -807,6 +814,7 @@ static int cs_dsp_coeff_read_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, void *buf, s + /** + * cs_dsp_coeff_read_ctrl() - Reads the given coefficient control into the given buffer + * @ctl: pointer to coefficient control ++ * @off: word offset at which data should be read + * @buf: the buffer to store to the given control + * @len: the length of the buffer in bytes + * +@@ -814,7 +822,8 @@ static int cs_dsp_coeff_read_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, void *buf, s + * + * Return: Zero for success, a negative number on error. + */ +-int cs_dsp_coeff_read_ctrl(struct cs_dsp_coeff_ctl *ctl, void *buf, size_t len) ++int cs_dsp_coeff_read_ctrl(struct cs_dsp_coeff_ctl *ctl, ++ unsigned int off, void *buf, size_t len) + { + int ret = 0; + +@@ -823,17 +832,20 @@ int cs_dsp_coeff_read_ctrl(struct cs_dsp_coeff_ctl *ctl, void *buf, size_t len) + if (!ctl) + return -ENOENT; + ++ if (len + off * sizeof(u32) > ctl->len) ++ return -EINVAL; ++ + if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) { + if (ctl->enabled && ctl->dsp->running) +- return cs_dsp_coeff_read_ctrl_raw(ctl, buf, len); ++ return cs_dsp_coeff_read_ctrl_raw(ctl, off, buf, len); + else + return -EPERM; + } else { + if (!ctl->flags && ctl->enabled && ctl->dsp->running) +- ret = cs_dsp_coeff_read_ctrl_raw(ctl, ctl->cache, ctl->len); ++ ret = cs_dsp_coeff_read_ctrl_raw(ctl, 0, ctl->cache, ctl->len); + + if (buf != ctl->cache) +- memcpy(buf, ctl->cache, len); ++ memcpy(buf, ctl->cache + off * sizeof(u32), len); + } + + return ret; +@@ -857,7 +869,7 @@ static int cs_dsp_coeff_init_control_caches(struct cs_dsp *dsp) + * created so we don't need to do anything. + */ + if (!ctl->flags || (ctl->flags & WMFW_CTL_FLAG_READABLE)) { +- ret = cs_dsp_coeff_read_ctrl_raw(ctl, ctl->cache, ctl->len); ++ ret = cs_dsp_coeff_read_ctrl_raw(ctl, 0, ctl->cache, ctl->len); + if (ret < 0) + return ret; + } +@@ -875,7 +887,7 @@ static int cs_dsp_coeff_sync_controls(struct cs_dsp *dsp) + if (!ctl->enabled) + continue; + if (ctl->set && !(ctl->flags & WMFW_CTL_FLAG_VOLATILE)) { +- ret = cs_dsp_coeff_write_ctrl_raw(ctl, ctl->cache, ++ ret = cs_dsp_coeff_write_ctrl_raw(ctl, 0, ctl->cache, + ctl->len); + if (ret < 0) + return ret; +diff --git a/include/linux/firmware/cirrus/cs_dsp.h b/include/linux/firmware/cirrus/cs_dsp.h +index 1ad1b173417a..38b4da3ddfe4 100644 +--- a/include/linux/firmware/cirrus/cs_dsp.h ++++ b/include/linux/firmware/cirrus/cs_dsp.h +@@ -232,8 +232,10 @@ void cs_dsp_init_debugfs(struct cs_dsp *dsp, struct dentry *debugfs_root); + void cs_dsp_cleanup_debugfs(struct cs_dsp *dsp); + + int cs_dsp_coeff_write_acked_control(struct cs_dsp_coeff_ctl *ctl, unsigned int event_id); +-int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl, const void *buf, size_t len); +-int cs_dsp_coeff_read_ctrl(struct cs_dsp_coeff_ctl *ctl, void *buf, size_t len); ++int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl, unsigned int off, ++ const void *buf, size_t len); ++int cs_dsp_coeff_read_ctrl(struct cs_dsp_coeff_ctl *ctl, unsigned int off, ++ void *buf, size_t len); + struct cs_dsp_coeff_ctl *cs_dsp_get_ctl(struct cs_dsp *dsp, const char *name, int type, + unsigned int alg); + +diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c +index 404717e30f44..f084b093cff6 100644 +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -401,7 +401,7 @@ static int wm_coeff_put(struct snd_kcontrol *kctl, + int ret = 0; + + mutex_lock(&cs_ctl->dsp->pwr_lock); +- ret = cs_dsp_coeff_write_ctrl(cs_ctl, p, cs_ctl->len); ++ ret = cs_dsp_coeff_write_ctrl(cs_ctl, 0, p, cs_ctl->len); + mutex_unlock(&cs_ctl->dsp->pwr_lock); + + return ret; +@@ -421,7 +421,7 @@ static int wm_coeff_tlv_put(struct snd_kcontrol *kctl, + if (copy_from_user(cs_ctl->cache, bytes, size)) + ret = -EFAULT; + else +- ret = cs_dsp_coeff_write_ctrl(cs_ctl, cs_ctl->cache, size); ++ ret = cs_dsp_coeff_write_ctrl(cs_ctl, 0, cs_ctl->cache, size); + + mutex_unlock(&cs_ctl->dsp->pwr_lock); + +@@ -464,7 +464,7 @@ static int wm_coeff_get(struct snd_kcontrol *kctl, + int ret; + + mutex_lock(&cs_ctl->dsp->pwr_lock); +- ret = cs_dsp_coeff_read_ctrl(cs_ctl, p, cs_ctl->len); ++ ret = cs_dsp_coeff_read_ctrl(cs_ctl, 0, p, cs_ctl->len); + mutex_unlock(&cs_ctl->dsp->pwr_lock); + + return ret; +@@ -481,7 +481,7 @@ static int wm_coeff_tlv_get(struct snd_kcontrol *kctl, + + mutex_lock(&cs_ctl->dsp->pwr_lock); + +- ret = cs_dsp_coeff_read_ctrl(cs_ctl, cs_ctl->cache, size); ++ ret = cs_dsp_coeff_read_ctrl(cs_ctl, 0, cs_ctl->cache, size); + + if (!ret && copy_to_user(bytes, cs_ctl->cache, size)) + ret = -EFAULT; +@@ -684,7 +684,7 @@ int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type, + if (len > cs_ctl->len) + return -EINVAL; + +- ret = cs_dsp_coeff_write_ctrl(cs_ctl, buf, len); ++ ret = cs_dsp_coeff_write_ctrl(cs_ctl, 0, buf, len); + if (ret) + return ret; + +@@ -723,7 +723,7 @@ int wm_adsp_read_ctl(struct wm_adsp *dsp, const char *name, int type, + if (len > cs_ctl->len) + return -EINVAL; + +- return cs_dsp_coeff_read_ctrl(cs_ctl, buf, len); ++ return cs_dsp_coeff_read_ctrl(cs_ctl, 0, buf, len); + } + EXPORT_SYMBOL_GPL(wm_adsp_read_ctl); + +@@ -1432,7 +1432,7 @@ static int wm_adsp_buffer_parse_coeff(struct cs_dsp_coeff_ctl *cs_ctl) + int ret, i; + + for (i = 0; i < 5; ++i) { +- ret = cs_dsp_coeff_read_ctrl(cs_ctl, &coeff_v1, sizeof(coeff_v1)); ++ ret = cs_dsp_coeff_read_ctrl(cs_ctl, 0, &coeff_v1, sizeof(coeff_v1)); + if (ret < 0) + return ret; + +-- +2.35.3 + diff --git a/patches.suse/firmware-cs_dsp-Add-pre_run-callback.patch b/patches.suse/firmware-cs_dsp-Add-pre_run-callback.patch new file mode 100644 index 0000000..ffc4989 --- /dev/null +++ b/patches.suse/firmware-cs_dsp-Add-pre_run-callback.patch @@ -0,0 +1,70 @@ +From 14055b5a3a23204c4702ae5d3f2a819ee081ce33 Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Wed, 17 Nov 2021 13:22:54 +0000 +Subject: [PATCH] firmware: cs_dsp: Add pre_run callback +Git-commit: 14055b5a3a23204c4702ae5d3f2a819ee081ce33 +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +The code already has a post_run callback, add a matching pre_run +callback to the client_ops that is called before execution is started. +This callback provides a convenient place for the client code to +set DSP controls or hardware that requires configuration before +the DSP core actually starts execution. Note that placing this callback +before cs_dsp_coeff_sync_controls is important to ensure that any +control values are then correctly synced out to the chip. + +Co-authored-by: Simon Trimmer +Signed-off-by: Simon Trimmer +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20211117132300.1290-4-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + drivers/firmware/cirrus/cs_dsp.c | 6 ++++++ + include/linux/firmware/cirrus/cs_dsp.h | 4 +++- + 2 files changed, 9 insertions(+), 1 deletion(-) + +diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c +index 0da454a8498d..ef7afadea42d 100644 +--- a/drivers/firmware/cirrus/cs_dsp.c ++++ b/drivers/firmware/cirrus/cs_dsp.c +@@ -2627,6 +2627,12 @@ int cs_dsp_run(struct cs_dsp *dsp) + goto err; + } + ++ if (dsp->client_ops->pre_run) { ++ ret = dsp->client_ops->pre_run(dsp); ++ if (ret) ++ goto err; ++ } ++ + /* Sync set controls */ + ret = cs_dsp_coeff_sync_controls(dsp); + if (ret != 0) +diff --git a/include/linux/firmware/cirrus/cs_dsp.h b/include/linux/firmware/cirrus/cs_dsp.h +index ce54705e2bec..0bf849baeaa5 100644 +--- a/include/linux/firmware/cirrus/cs_dsp.h ++++ b/include/linux/firmware/cirrus/cs_dsp.h +@@ -187,7 +187,8 @@ struct cs_dsp { + * struct cs_dsp_client_ops - client callbacks + * @control_add: Called under the pwr_lock when a control is created + * @control_remove: Called under the pwr_lock when a control is destroyed +- * @post_run: Called under the pwr_lock by cs_dsp_run() ++ * @pre_run: Called under the pwr_lock by cs_dsp_run() before the core is started ++ * @post_run: Called under the pwr_lock by cs_dsp_run() after the core is started + * @post_stop: Called under the pwr_lock by cs_dsp_stop() + * @watchdog_expired: Called when a watchdog expiry is detected + * +@@ -197,6 +198,7 @@ struct cs_dsp { + struct cs_dsp_client_ops { + int (*control_add)(struct cs_dsp_coeff_ctl *ctl); + void (*control_remove)(struct cs_dsp_coeff_ctl *ctl); ++ int (*pre_run)(struct cs_dsp *dsp); + int (*post_run)(struct cs_dsp *dsp); + void (*post_stop)(struct cs_dsp *dsp); + void (*watchdog_expired)(struct cs_dsp *dsp); +-- +2.35.3 + diff --git a/patches.suse/firmware-cs_dsp-Add-pre_stop-callback.patch b/patches.suse/firmware-cs_dsp-Add-pre_stop-callback.patch new file mode 100644 index 0000000..c9705bb --- /dev/null +++ b/patches.suse/firmware-cs_dsp-Add-pre_stop-callback.patch @@ -0,0 +1,62 @@ +From dea997733575c5793ca77e166bbbf89097987eb4 Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Fri, 22 Jul 2022 10:48:50 +0100 +Subject: [PATCH] firmware: cs_dsp: Add pre_stop callback +Git-commit: dea997733575c5793ca77e166bbbf89097987eb4 +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +The code already has a post_stop callback, add a matching pre_stop +callback to the client_ops that is called before execution is stopped. +This callback provides a convenient place for the client code to +communicate with the DSP before it is stopped. + +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20220722094851.92521-1-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + drivers/firmware/cirrus/cs_dsp.c | 3 +++ + include/linux/firmware/cirrus/cs_dsp.h | 4 +++- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c +index 7dad6f57d970..b402f841d72c 100644 +--- a/drivers/firmware/cirrus/cs_dsp.c ++++ b/drivers/firmware/cirrus/cs_dsp.c +@@ -2725,6 +2725,9 @@ void cs_dsp_stop(struct cs_dsp *dsp) + + mutex_lock(&dsp->pwr_lock); + ++ if (dsp->client_ops->pre_stop) ++ dsp->client_ops->pre_stop(dsp); ++ + dsp->running = false; + + if (dsp->ops->stop_core) +diff --git a/include/linux/firmware/cirrus/cs_dsp.h b/include/linux/firmware/cirrus/cs_dsp.h +index 30055706cce2..6ab230218df0 100644 +--- a/include/linux/firmware/cirrus/cs_dsp.h ++++ b/include/linux/firmware/cirrus/cs_dsp.h +@@ -189,7 +189,8 @@ struct cs_dsp { + * @control_remove: Called under the pwr_lock when a control is destroyed + * @pre_run: Called under the pwr_lock by cs_dsp_run() before the core is started + * @post_run: Called under the pwr_lock by cs_dsp_run() after the core is started +- * @post_stop: Called under the pwr_lock by cs_dsp_stop() ++ * @pre_stop: Called under the pwr_lock by cs_dsp_stop() before the core is stopped ++ * @post_stop: Called under the pwr_lock by cs_dsp_stop() after the core is stopped + * @watchdog_expired: Called when a watchdog expiry is detected + * + * These callbacks give the cs_dsp client an opportunity to respond to events +@@ -200,6 +201,7 @@ struct cs_dsp_client_ops { + void (*control_remove)(struct cs_dsp_coeff_ctl *ctl); + int (*pre_run)(struct cs_dsp *dsp); + int (*post_run)(struct cs_dsp *dsp); ++ void (*pre_stop)(struct cs_dsp *dsp); + void (*post_stop)(struct cs_dsp *dsp); + void (*watchdog_expired)(struct cs_dsp *dsp); + }; +-- +2.35.3 + diff --git a/patches.suse/firmware-cs_dsp-Add-support-for-rev-2-coefficient-fi.patch b/patches.suse/firmware-cs_dsp-Add-support-for-rev-2-coefficient-fi.patch new file mode 100644 index 0000000..693574c --- /dev/null +++ b/patches.suse/firmware-cs_dsp-Add-support-for-rev-2-coefficient-fi.patch @@ -0,0 +1,38 @@ +From dcee767667f44ed0d40a3debf507a3ba027a1994 Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Wed, 17 Nov 2021 13:22:56 +0000 +Subject: [PATCH] firmware: cs_dsp: Add support for rev 2 coefficient files +Git-commit: dcee767667f44ed0d40a3debf507a3ba027a1994 +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +Add support for the revision 2 coefficient file, this format is +identical to revision 1 and was simply added by accident to some +firmware. However unfortunately many firmwares have leaked into +production using this and as such driver support really needs to +be added for it. + +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20211117132300.1290-6-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + drivers/firmware/cirrus/cs_dsp.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c +index 3d21574f3a44..62ba4ebbf11f 100644 +--- a/drivers/firmware/cirrus/cs_dsp.c ++++ b/drivers/firmware/cirrus/cs_dsp.c +@@ -1990,6 +1990,7 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware + + switch (be32_to_cpu(hdr->rev) & 0xff) { + case 1: ++ case 2: + break; + default: + cs_dsp_err(dsp, "%s: Unsupported coefficient file format %d\n", +-- +2.35.3 + diff --git a/patches.suse/firmware-cs_dsp-Add-version-checks-on-coefficient-lo.patch b/patches.suse/firmware-cs_dsp-Add-version-checks-on-coefficient-lo.patch new file mode 100644 index 0000000..9e3928f --- /dev/null +++ b/patches.suse/firmware-cs_dsp-Add-version-checks-on-coefficient-lo.patch @@ -0,0 +1,238 @@ +From 2925748eadc33cba3bded7b69475a1b002b124ac Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Wed, 17 Nov 2021 13:22:53 +0000 +Subject: [PATCH] firmware: cs_dsp: Add version checks on coefficient loading +Git-commit: 2925748eadc33cba3bded7b69475a1b002b124ac +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +The firmware coefficient files contain version information that is +currently ignored by the cs_dsp code. This information specifies which +version of the firmware the coefficient were generated for. Add a check +into the code which prints a warning in the case the coefficient and +firmware differ in version, in many cases this will be ok but it is not +always, so best to let the user know there is a potential issue. + +Co-authored-by: Simon Trimmer +Signed-off-by: Simon Trimmer +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20211117132300.1290-3-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + drivers/firmware/cirrus/cs_dsp.c | 49 +++++++++++++++++++------- + include/linux/firmware/cirrus/cs_dsp.h | 2 ++ + 2 files changed, 38 insertions(+), 13 deletions(-) + +diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c +index 0d1ba7d8efa4..0da454a8498d 100644 +--- a/drivers/firmware/cirrus/cs_dsp.c ++++ b/drivers/firmware/cirrus/cs_dsp.c +@@ -1569,7 +1569,7 @@ EXPORT_SYMBOL_GPL(cs_dsp_find_alg_region); + + static struct cs_dsp_alg_region *cs_dsp_create_region(struct cs_dsp *dsp, + int type, __be32 id, +- __be32 base) ++ __be32 ver, __be32 base) + { + struct cs_dsp_alg_region *alg_region; + +@@ -1579,6 +1579,7 @@ static struct cs_dsp_alg_region *cs_dsp_create_region(struct cs_dsp *dsp, + + alg_region->type = type; + alg_region->alg = be32_to_cpu(id); ++ alg_region->ver = be32_to_cpu(ver); + alg_region->base = be32_to_cpu(base); + + list_add_tail(&alg_region->list, &dsp->alg_regions); +@@ -1628,14 +1629,14 @@ static void cs_dsp_parse_wmfw_v3_id_header(struct cs_dsp *dsp, + nalgs); + } + +-static int cs_dsp_create_regions(struct cs_dsp *dsp, __be32 id, int nregions, +- const int *type, __be32 *base) ++static int cs_dsp_create_regions(struct cs_dsp *dsp, __be32 id, __be32 ver, ++ int nregions, const int *type, __be32 *base) + { + struct cs_dsp_alg_region *alg_region; + int i; + + for (i = 0; i < nregions; i++) { +- alg_region = cs_dsp_create_region(dsp, type[i], id, base[i]); ++ alg_region = cs_dsp_create_region(dsp, type[i], id, ver, base[i]); + if (IS_ERR(alg_region)) + return PTR_ERR(alg_region); + } +@@ -1670,12 +1671,14 @@ static int cs_dsp_adsp1_setup_algs(struct cs_dsp *dsp) + cs_dsp_parse_wmfw_id_header(dsp, &adsp1_id.fw, n_algs); + + alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_ZM, +- adsp1_id.fw.id, adsp1_id.zm); ++ adsp1_id.fw.id, adsp1_id.fw.ver, ++ adsp1_id.zm); + if (IS_ERR(alg_region)) + return PTR_ERR(alg_region); + + alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_DM, +- adsp1_id.fw.id, adsp1_id.dm); ++ adsp1_id.fw.id, adsp1_id.fw.ver, ++ adsp1_id.dm); + if (IS_ERR(alg_region)) + return PTR_ERR(alg_region); + +@@ -1698,6 +1701,7 @@ static int cs_dsp_adsp1_setup_algs(struct cs_dsp *dsp) + + alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_DM, + adsp1_alg[i].alg.id, ++ adsp1_alg[i].alg.ver, + adsp1_alg[i].dm); + if (IS_ERR(alg_region)) { + ret = PTR_ERR(alg_region); +@@ -1719,6 +1723,7 @@ static int cs_dsp_adsp1_setup_algs(struct cs_dsp *dsp) + + alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_ZM, + adsp1_alg[i].alg.id, ++ adsp1_alg[i].alg.ver, + adsp1_alg[i].zm); + if (IS_ERR(alg_region)) { + ret = PTR_ERR(alg_region); +@@ -1771,17 +1776,20 @@ static int cs_dsp_adsp2_setup_algs(struct cs_dsp *dsp) + cs_dsp_parse_wmfw_id_header(dsp, &adsp2_id.fw, n_algs); + + alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_XM, +- adsp2_id.fw.id, adsp2_id.xm); ++ adsp2_id.fw.id, adsp2_id.fw.ver, ++ adsp2_id.xm); + if (IS_ERR(alg_region)) + return PTR_ERR(alg_region); + + alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_YM, +- adsp2_id.fw.id, adsp2_id.ym); ++ adsp2_id.fw.id, adsp2_id.fw.ver, ++ adsp2_id.ym); + if (IS_ERR(alg_region)) + return PTR_ERR(alg_region); + + alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_ZM, +- adsp2_id.fw.id, adsp2_id.zm); ++ adsp2_id.fw.id, adsp2_id.fw.ver, ++ adsp2_id.zm); + if (IS_ERR(alg_region)) + return PTR_ERR(alg_region); + +@@ -1806,6 +1814,7 @@ static int cs_dsp_adsp2_setup_algs(struct cs_dsp *dsp) + + alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_XM, + adsp2_alg[i].alg.id, ++ adsp2_alg[i].alg.ver, + adsp2_alg[i].xm); + if (IS_ERR(alg_region)) { + ret = PTR_ERR(alg_region); +@@ -1827,6 +1836,7 @@ static int cs_dsp_adsp2_setup_algs(struct cs_dsp *dsp) + + alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_YM, + adsp2_alg[i].alg.id, ++ adsp2_alg[i].alg.ver, + adsp2_alg[i].ym); + if (IS_ERR(alg_region)) { + ret = PTR_ERR(alg_region); +@@ -1848,6 +1858,7 @@ static int cs_dsp_adsp2_setup_algs(struct cs_dsp *dsp) + + alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_ZM, + adsp2_alg[i].alg.id, ++ adsp2_alg[i].alg.ver, + adsp2_alg[i].zm); + if (IS_ERR(alg_region)) { + ret = PTR_ERR(alg_region); +@@ -1873,7 +1884,7 @@ static int cs_dsp_adsp2_setup_algs(struct cs_dsp *dsp) + return ret; + } + +-static int cs_dsp_halo_create_regions(struct cs_dsp *dsp, __be32 id, ++static int cs_dsp_halo_create_regions(struct cs_dsp *dsp, __be32 id, __be32 ver, + __be32 xm_base, __be32 ym_base) + { + static const int types[] = { +@@ -1882,7 +1893,7 @@ static int cs_dsp_halo_create_regions(struct cs_dsp *dsp, __be32 id, + }; + __be32 bases[] = { xm_base, xm_base, ym_base, ym_base }; + +- return cs_dsp_create_regions(dsp, id, ARRAY_SIZE(types), types, bases); ++ return cs_dsp_create_regions(dsp, id, ver, ARRAY_SIZE(types), types, bases); + } + + static int cs_dsp_halo_setup_algs(struct cs_dsp *dsp) +@@ -1910,7 +1921,7 @@ static int cs_dsp_halo_setup_algs(struct cs_dsp *dsp) + + cs_dsp_parse_wmfw_v3_id_header(dsp, &halo_id.fw, n_algs); + +- ret = cs_dsp_halo_create_regions(dsp, halo_id.fw.id, ++ ret = cs_dsp_halo_create_regions(dsp, halo_id.fw.id, halo_id.fw.ver, + halo_id.xm_base, halo_id.ym_base); + if (ret) + return ret; +@@ -1934,6 +1945,7 @@ static int cs_dsp_halo_setup_algs(struct cs_dsp *dsp) + be32_to_cpu(halo_alg[i].ym_base)); + + ret = cs_dsp_halo_create_regions(dsp, halo_alg[i].alg.id, ++ halo_alg[i].alg.ver, + halo_alg[i].xm_base, + halo_alg[i].ym_base); + if (ret) +@@ -1955,7 +1967,7 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware + const struct cs_dsp_region *mem; + struct cs_dsp_alg_region *alg_region; + const char *region_name; +- int ret, pos, blocks, type, offset, reg; ++ int ret, pos, blocks, type, offset, reg, version; + struct cs_dsp_buf *buf; + + if (!firmware) +@@ -1999,6 +2011,7 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware + + type = le16_to_cpu(blk->type); + offset = le16_to_cpu(blk->offset); ++ version = le32_to_cpu(blk->ver) >> 8; + + cs_dsp_dbg(dsp, "%s.%d: %x v%d.%d.%d\n", + file, blocks, le32_to_cpu(blk->id), +@@ -2056,6 +2069,16 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware + alg_region = cs_dsp_find_alg_region(dsp, type, + le32_to_cpu(blk->id)); + if (alg_region) { ++ if (version != alg_region->ver) ++ cs_dsp_warn(dsp, ++ "Algorithm coefficient version %d.%d.%d but expected %d.%d.%d\n", ++ (version >> 16) & 0xFF, ++ (version >> 8) & 0xFF, ++ version & 0xFF, ++ (alg_region->ver >> 16) & 0xFF, ++ (alg_region->ver >> 8) & 0xFF, ++ alg_region->ver & 0xFF); ++ + reg = alg_region->base; + reg = dsp->ops->region_to_reg(mem, reg); + reg += offset; +diff --git a/include/linux/firmware/cirrus/cs_dsp.h b/include/linux/firmware/cirrus/cs_dsp.h +index 3a54b1afc48f..ce54705e2bec 100644 +--- a/include/linux/firmware/cirrus/cs_dsp.h ++++ b/include/linux/firmware/cirrus/cs_dsp.h +@@ -54,12 +54,14 @@ struct cs_dsp_region { + * struct cs_dsp_alg_region - Describes a logical algorithm region in DSP address space + * @list: List node for internal use + * @alg: Algorithm id ++ * @ver: Expected algorithm version + * @type: Memory region type + * @base: Address of region + */ + struct cs_dsp_alg_region { + struct list_head list; + unsigned int alg; ++ unsigned int ver; + int type; + unsigned int base; + }; +-- +2.35.3 + diff --git a/patches.suse/firmware-cs_dsp-Allow-creation-of-event-controls.patch b/patches.suse/firmware-cs_dsp-Allow-creation-of-event-controls.patch new file mode 100644 index 0000000..3c04a7f --- /dev/null +++ b/patches.suse/firmware-cs_dsp-Allow-creation-of-event-controls.patch @@ -0,0 +1,50 @@ +From 5c903f64ce97172d63f7591cfa9e37cba58867b2 Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Wed, 17 Nov 2021 13:23:00 +0000 +Subject: [PATCH] firmware: cs_dsp: Allow creation of event controls +Git-commit: 5c903f64ce97172d63f7591cfa9e37cba58867b2 +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +Some firmwares contain controls intended to convey firmware state back +to the host. Whilst more infrastructure will probably be needed for +these in time, as a first step allow creation of the controls, so said +firmwares arn't completely rejected. + +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20211117132300.1290-10-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + drivers/firmware/cirrus/cs_dsp.c | 1 + + include/linux/firmware/cirrus/wmfw.h | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c +index 5fe08de91ecd..3814cbba0a54 100644 +--- a/drivers/firmware/cirrus/cs_dsp.c ++++ b/drivers/firmware/cirrus/cs_dsp.c +@@ -1177,6 +1177,7 @@ static int cs_dsp_parse_coeff(struct cs_dsp *dsp, + return -EINVAL; + break; + case WMFW_CTL_TYPE_HOSTEVENT: ++ case WMFW_CTL_TYPE_FWEVENT: + ret = cs_dsp_check_coeff_flags(dsp, &coeff_blk, + WMFW_CTL_FLAG_SYS | + WMFW_CTL_FLAG_VOLATILE | +diff --git a/include/linux/firmware/cirrus/wmfw.h b/include/linux/firmware/cirrus/wmfw.h +index a19bf7c6fc8b..74e5a4f6c13a 100644 +--- a/include/linux/firmware/cirrus/wmfw.h ++++ b/include/linux/firmware/cirrus/wmfw.h +@@ -29,6 +29,7 @@ + #define WMFW_CTL_TYPE_ACKED 0x1000 /* acked control */ + #define WMFW_CTL_TYPE_HOSTEVENT 0x1001 /* event control */ + #define WMFW_CTL_TYPE_HOST_BUFFER 0x1002 /* host buffer pointer */ ++#define WMFW_CTL_TYPE_FWEVENT 0x1004 /* firmware event control */ + + struct wmfw_header { + char magic[4]; +-- +2.35.3 + diff --git a/patches.suse/firmware-cs_dsp-Clarify-some-kernel-doc-comments.patch b/patches.suse/firmware-cs_dsp-Clarify-some-kernel-doc-comments.patch new file mode 100644 index 0000000..f17cac7 --- /dev/null +++ b/patches.suse/firmware-cs_dsp-Clarify-some-kernel-doc-comments.patch @@ -0,0 +1,58 @@ +From b329b3d39497a9fdb175d7e4fd77ae7170d5d26c Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Wed, 17 Nov 2021 13:22:58 +0000 +Subject: [PATCH] firmware: cs_dsp: Clarify some kernel doc comments +Git-commit: b329b3d39497a9fdb175d7e4fd77ae7170d5d26c +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20211117132300.1290-8-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + drivers/firmware/cirrus/cs_dsp.c | 4 ++-- + include/linux/firmware/cirrus/cs_dsp.h | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c +index 9eecd1626537..d1bcade2efe2 100644 +--- a/drivers/firmware/cirrus/cs_dsp.c ++++ b/drivers/firmware/cirrus/cs_dsp.c +@@ -746,7 +746,7 @@ static int cs_dsp_coeff_write_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, + * cs_dsp_coeff_write_ctrl() - Writes the given buffer to the given coefficient control + * @ctl: pointer to coefficient control + * @buf: the buffer to write to the given control +- * @len: the length of the buffer ++ * @len: the length of the buffer in bytes + * + * Must be called with pwr_lock held. + * +@@ -808,7 +808,7 @@ static int cs_dsp_coeff_read_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, void *buf, s + * cs_dsp_coeff_read_ctrl() - Reads the given coefficient control into the given buffer + * @ctl: pointer to coefficient control + * @buf: the buffer to store to the given control +- * @len: the length of the buffer ++ * @len: the length of the buffer in bytes + * + * Must be called with pwr_lock held. + * +diff --git a/include/linux/firmware/cirrus/cs_dsp.h b/include/linux/firmware/cirrus/cs_dsp.h +index 0bf849baeaa5..1ad1b173417a 100644 +--- a/include/linux/firmware/cirrus/cs_dsp.h ++++ b/include/linux/firmware/cirrus/cs_dsp.h +@@ -76,8 +76,8 @@ struct cs_dsp_alg_region { + * @enabled: Flag indicating whether control is enabled + * @list: List node for internal use + * @cache: Cached value of the control +- * @offset: Offset of control within alg_region +- * @len: Length of the cached value ++ * @offset: Offset of control within alg_region in words ++ * @len: Length of the cached value in bytes + * @set: Flag indicating the value has been written by the user + * @flags: Bitfield of WMFW_CTL_FLAG_ control flags defined in wmfw.h + * @type: One of the WMFW_CTL_TYPE_ control types defined in wmfw.h +-- +2.35.3 + diff --git a/patches.suse/firmware-cs_dsp-Clear-core-reset-for-cache.patch b/patches.suse/firmware-cs_dsp-Clear-core-reset-for-cache.patch new file mode 100644 index 0000000..a4ab564 --- /dev/null +++ b/patches.suse/firmware-cs_dsp-Clear-core-reset-for-cache.patch @@ -0,0 +1,52 @@ +From 7aa1cc1091e0a424e9e7711ca381ebe98b6865bc Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Wed, 5 Jan 2022 11:30:23 +0000 +Subject: [PATCH] firmware: cs_dsp: Clear core reset for cache +Git-commit: 7aa1cc1091e0a424e9e7711ca381ebe98b6865bc +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +If the Halo registers are kept in the register cache the +HALO_CORE_RESET bit will be retained as 1 after reset is triggered in +cs_dsp_halo_start_core. This will cause subsequent writes to reset +the core which is not desired. Apart from this bit the rest of the +register bits are cacheable, so for safety sake clear the bit to +ensure the cache is consistent. + +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20220105113026.18955-6-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + drivers/firmware/cirrus/cs_dsp.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c +index 5af8171d6ced..e48108e694f8 100644 +--- a/drivers/firmware/cirrus/cs_dsp.c ++++ b/drivers/firmware/cirrus/cs_dsp.c +@@ -2744,10 +2744,16 @@ EXPORT_SYMBOL_GPL(cs_dsp_stop); + + static int cs_dsp_halo_start_core(struct cs_dsp *dsp) + { +- return regmap_update_bits(dsp->regmap, +- dsp->base + HALO_CCM_CORE_CONTROL, +- HALO_CORE_RESET | HALO_CORE_EN, +- HALO_CORE_RESET | HALO_CORE_EN); ++ int ret; ++ ++ ret = regmap_update_bits(dsp->regmap, dsp->base + HALO_CCM_CORE_CONTROL, ++ HALO_CORE_RESET | HALO_CORE_EN, ++ HALO_CORE_RESET | HALO_CORE_EN); ++ if (ret) ++ return ret; ++ ++ return regmap_update_bits(dsp->regmap, dsp->base + HALO_CCM_CORE_CONTROL, ++ HALO_CORE_RESET, 0); + } + + static void cs_dsp_halo_stop_core(struct cs_dsp *dsp) +-- +2.35.3 + diff --git a/patches.suse/firmware-cs_dsp-Fix-overrun-of-unterminated-control-.patch b/patches.suse/firmware-cs_dsp-Fix-overrun-of-unterminated-control-.patch new file mode 100644 index 0000000..e20515a --- /dev/null +++ b/patches.suse/firmware-cs_dsp-Fix-overrun-of-unterminated-control-.patch @@ -0,0 +1,44 @@ +From 5b933c7262c5b0ea11ea3c3b3ea81add04895954 Mon Sep 17 00:00:00 2001 +From: Richard Fitzgerald +Date: Tue, 12 Apr 2022 17:39:27 +0100 +Subject: [PATCH] firmware: cs_dsp: Fix overrun of unterminated control name string +Git-commit: 5b933c7262c5b0ea11ea3c3b3ea81add04895954 +Patch-mainline: v5.18-rc4 +References: bsc#1203699 + +For wmfw format v2 and later the coefficient name strings have a length +field and are NOT null-terminated. Use kasprintf() to convert the +unterminated string into a null-terminated string in an allocated buffer. + +The previous code handled this duplication incorrectly using kmemdup() +and getting the length from a strlen() of the (unterminated) source string. +This resulted in creating a string that continued up to the next byte in +the firmware file that just happened to be 0x00. + +Signed-off-by: Richard Fitzgerald +Fixes: f6bc909e7673 ("firmware: cs_dsp: add driver to support firmware loading on Cirrus Logic DSPs") +Link: https://lore.kernel.org/r/20220412163927.1303470-1-rf@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + drivers/firmware/cirrus/cs_dsp.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c +index e48108e694f8..7dad6f57d970 100644 +--- a/drivers/firmware/cirrus/cs_dsp.c ++++ b/drivers/firmware/cirrus/cs_dsp.c +@@ -955,8 +955,7 @@ static int cs_dsp_create_control(struct cs_dsp *dsp, + ctl->alg_region = *alg_region; + if (subname && dsp->fw_ver >= 2) { + ctl->subname_len = subname_len; +- ctl->subname = kmemdup(subname, +- strlen(subname) + 1, GFP_KERNEL); ++ ctl->subname = kasprintf(GFP_KERNEL, "%.*s", subname_len, subname); + if (!ctl->subname) { + ret = -ENOMEM; + goto err_ctl; +-- +2.35.3 + diff --git a/patches.suse/firmware-cs_dsp-Move-lockdep-asserts-to-avoid-potent.patch b/patches.suse/firmware-cs_dsp-Move-lockdep-asserts-to-avoid-potent.patch new file mode 100644 index 0000000..bbbc48f --- /dev/null +++ b/patches.suse/firmware-cs_dsp-Move-lockdep-asserts-to-avoid-potent.patch @@ -0,0 +1,58 @@ +From 043c0a6278ca443b1835726239dc2814c1313a9e Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Tue, 30 Nov 2021 10:28:42 +0000 +Subject: [PATCH] firmware: cs_dsp: Move lockdep asserts to avoid potential null pointer +Git-commit: 043c0a6278ca443b1835726239dc2814c1313a9e +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +Move the lockdep asserts until after the ctl pointer has been checked +for NULL, to avoid potentially NULL pointer dereferences. + +Fixes: fb2f364fb5b9 ("firmware: cs_dsp: Add lockdep asserts to interface functions") +Reported-by: kernel test robot +Reported-by: Dan Carpenter +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20211130102842.26410-1-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + drivers/firmware/cirrus/cs_dsp.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c +index 3814cbba0a54..5af8171d6ced 100644 +--- a/drivers/firmware/cirrus/cs_dsp.c ++++ b/drivers/firmware/cirrus/cs_dsp.c +@@ -759,11 +759,11 @@ int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl, + { + int ret = 0; + +- lockdep_assert_held(&ctl->dsp->pwr_lock); +- + if (!ctl) + return -ENOENT; + ++ lockdep_assert_held(&ctl->dsp->pwr_lock); ++ + if (len + off * sizeof(u32) > ctl->len) + return -EINVAL; + +@@ -827,11 +827,11 @@ int cs_dsp_coeff_read_ctrl(struct cs_dsp_coeff_ctl *ctl, + { + int ret = 0; + +- lockdep_assert_held(&ctl->dsp->pwr_lock); +- + if (!ctl) + return -ENOENT; + ++ lockdep_assert_held(&ctl->dsp->pwr_lock); ++ + if (len + off * sizeof(u32) > ctl->len) + return -EINVAL; + +-- +2.35.3 + diff --git a/patches.suse/firmware-cs_dsp-Perform-NULL-check-in-cs_dsp_coeff_w.patch b/patches.suse/firmware-cs_dsp-Perform-NULL-check-in-cs_dsp_coeff_w.patch new file mode 100644 index 0000000..6290419 --- /dev/null +++ b/patches.suse/firmware-cs_dsp-Perform-NULL-check-in-cs_dsp_coeff_w.patch @@ -0,0 +1,49 @@ +From 86c6080407740937ed2ba0ccd181e947f77e2154 Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Wed, 17 Nov 2021 13:22:57 +0000 +Subject: [PATCH] firmware: cs_dsp: Perform NULL check in cs_dsp_coeff_write/read_ctrl +Git-commit: 86c6080407740937ed2ba0ccd181e947f77e2154 +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +Add a NULL check to the cs_dsp_coeff_write/read_ctrl functions. This is +a major convenience for users of the cs_dsp library as it allows the call +to cs_dsp_get_ctl to be inlined with the call to read/write the control +itself. + +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20211117132300.1290-7-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + drivers/firmware/cirrus/cs_dsp.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c +index 62ba4ebbf11f..9eecd1626537 100644 +--- a/drivers/firmware/cirrus/cs_dsp.c ++++ b/drivers/firmware/cirrus/cs_dsp.c +@@ -758,6 +758,9 @@ int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl, const void *buf, size_ + + lockdep_assert_held(&ctl->dsp->pwr_lock); + ++ if (!ctl) ++ return -ENOENT; ++ + if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) + ret = -EPERM; + else if (buf != ctl->cache) +@@ -817,6 +820,9 @@ int cs_dsp_coeff_read_ctrl(struct cs_dsp_coeff_ctl *ctl, void *buf, size_t len) + + lockdep_assert_held(&ctl->dsp->pwr_lock); + ++ if (!ctl) ++ return -ENOENT; ++ + if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) { + if (ctl->enabled && ctl->dsp->running) + return cs_dsp_coeff_read_ctrl_raw(ctl, buf, len); +-- +2.35.3 + diff --git a/patches.suse/firmware-cs_dsp-Print-messages-from-bin-files.patch b/patches.suse/firmware-cs_dsp-Print-messages-from-bin-files.patch new file mode 100644 index 0000000..eea75e6 --- /dev/null +++ b/patches.suse/firmware-cs_dsp-Print-messages-from-bin-files.patch @@ -0,0 +1,67 @@ +From 40a34ae7308682bbbf5827145afa23dcdfb1f090 Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Wed, 17 Nov 2021 13:22:55 +0000 +Subject: [PATCH] firmware: cs_dsp: Print messages from bin files +Git-commit: 40a34ae7308682bbbf5827145afa23dcdfb1f090 +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +The coefficient file contains various info strings, and the equivalent +strings are printed from the WMFW file as it is loaded. Add support +for printing these from the coefficient file as well. + +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20211117132300.1290-5-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + drivers/firmware/cirrus/cs_dsp.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c +index ef7afadea42d..3d21574f3a44 100644 +--- a/drivers/firmware/cirrus/cs_dsp.c ++++ b/drivers/firmware/cirrus/cs_dsp.c +@@ -1968,6 +1968,7 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware + struct cs_dsp_alg_region *alg_region; + const char *region_name; + int ret, pos, blocks, type, offset, reg, version; ++ char *text = NULL; + struct cs_dsp_buf *buf; + + if (!firmware) +@@ -2025,6 +2026,8 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware + region_name = "Unknown"; + switch (type) { + case (WMFW_NAME_TEXT << 8): ++ text = kzalloc(le32_to_cpu(blk->len) + 1, GFP_KERNEL); ++ break; + case (WMFW_INFO_TEXT << 8): + case (WMFW_METADATA << 8): + break; +@@ -2094,6 +2097,13 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware + break; + } + ++ if (text) { ++ memcpy(text, blk->data, le32_to_cpu(blk->len)); ++ cs_dsp_info(dsp, "%s: %s\n", dsp->fw_name, text); ++ kfree(text); ++ text = NULL; ++ } ++ + if (reg) { + if (le32_to_cpu(blk->len) > + firmware->size - pos - sizeof(*blk)) { +@@ -2144,6 +2154,7 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware + out_fw: + regmap_async_complete(regmap); + cs_dsp_buf_free(&buf_list); ++ kfree(text); + return ret; + } + +-- +2.35.3 + diff --git a/patches.suse/firmware-cs_dsp-add-driver-to-support-firmware-loadi.patch b/patches.suse/firmware-cs_dsp-add-driver-to-support-firmware-loadi.patch new file mode 100644 index 0000000..0f48e74 --- /dev/null +++ b/patches.suse/firmware-cs_dsp-add-driver-to-support-firmware-loadi.patch @@ -0,0 +1,7210 @@ +From f6bc909e7673c30abcbdb329e7d0aa2e83c103d7 Mon Sep 17 00:00:00 2001 +From: Simon Trimmer +Date: Mon, 13 Sep 2021 17:00:57 +0100 +Subject: [PATCH] firmware: cs_dsp: add driver to support firmware loading on Cirrus Logic DSPs +Git-commit: f6bc909e7673c30abcbdb329e7d0aa2e83c103d7 +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +wm_adsp originally provided firmware loading on some audio DSP and was +implemented as an ASoC codec driver. However, the firmware loading now +covers a wider range of DSP cores and peripherals containing them, +beyond just audio. So it needs to be available to non-audio drivers. All +the core firmware loading support has been moved into a new driver +cs_dsp, leaving only the ASoC-specific parts in wm_adsp. + +Signed-off-by: Simon Trimmer +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20210913160057.103842-17-simont@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + MAINTAINERS | 11 + + drivers/firmware/Kconfig | 1 + + drivers/firmware/Makefile | 1 + + drivers/firmware/cirrus/Kconfig | 5 + + drivers/firmware/cirrus/Makefile | 3 + + drivers/firmware/cirrus/cs_dsp.c | 3109 ++++++++++++++++++++++++ + include/linux/firmware/cirrus/cs_dsp.h | 242 ++ + include/linux/firmware/cirrus/wmfw.h | 202 ++ + sound/soc/codecs/Kconfig | 1 + + sound/soc/codecs/wm_adsp.c | 2910 +--------------------- + sound/soc/codecs/wm_adsp.h | 132 +- + sound/soc/codecs/wmfw.h | 202 -- + 12 files changed, 3611 insertions(+), 3208 deletions(-) + create mode 100644 drivers/firmware/cirrus/Kconfig + create mode 100644 drivers/firmware/cirrus/Makefile + create mode 100644 drivers/firmware/cirrus/cs_dsp.c + create mode 100644 include/linux/firmware/cirrus/cs_dsp.h + create mode 100644 include/linux/firmware/cirrus/wmfw.h + delete mode 100644 sound/soc/codecs/wmfw.h + +diff --git a/MAINTAINERS b/MAINTAINERS +index f555bfad3ca0..dd3ed0f809a3 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -4445,6 +4445,17 @@ L: patches@opensource.cirrus.com + S: Maintained + F: sound/soc/codecs/cs* + ++CIRRUS LOGIC DSP FIRMWARE DRIVER ++M: Simon Trimmer ++M: Charles Keepax ++M: Richard Fitzgerald ++L: patches@opensource.cirrus.com ++S: Supported ++W: https://github.com/CirrusLogic/linux-drivers/wiki ++T: git https://github.com/CirrusLogic/linux-drivers.git ++F: drivers/firmware/cirrus/* ++F: include/linux/firmware/cirrus/* ++ + CIRRUS LOGIC EP93XX ETHERNET DRIVER + M: Hartley Sweeten + L: netdev@vger.kernel.org +diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig +index 220a58cf0a44..fd2a5f68acab 100644 +--- a/drivers/firmware/Kconfig ++++ b/drivers/firmware/Kconfig +@@ -298,6 +298,7 @@ config TURRIS_MOX_RWTM + + source "drivers/firmware/arm_ffa/Kconfig" + source "drivers/firmware/broadcom/Kconfig" ++source "drivers/firmware/cirrus/Kconfig" + source "drivers/firmware/google/Kconfig" + source "drivers/firmware/efi/Kconfig" + source "drivers/firmware/imx/Kconfig" +diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile +index 5ced0673d94b..4e58cb474a68 100644 +--- a/drivers/firmware/Makefile ++++ b/drivers/firmware/Makefile +@@ -28,6 +28,7 @@ obj-$(CONFIG_TURRIS_MOX_RWTM) += turris-mox-rwtm.o + obj-y += arm_ffa/ + obj-y += arm_scmi/ + obj-y += broadcom/ ++obj-y += cirrus/ + obj-y += meson/ + obj-$(CONFIG_GOOGLE_FIRMWARE) += google/ + obj-$(CONFIG_EFI) += efi/ +diff --git a/drivers/firmware/cirrus/Kconfig b/drivers/firmware/cirrus/Kconfig +new file mode 100644 +index 000000000000..f9503cb481d2 +--- /dev/null ++++ b/drivers/firmware/cirrus/Kconfig +@@ -0,0 +1,5 @@ ++# SPDX-License-Identifier: GPL-2.0-only ++ ++config CS_DSP ++ tristate ++ default n +diff --git a/drivers/firmware/cirrus/Makefile b/drivers/firmware/cirrus/Makefile +new file mode 100644 +index 000000000000..f074e2638c9c +--- /dev/null ++++ b/drivers/firmware/cirrus/Makefile +@@ -0,0 +1,3 @@ ++# SPDX-License-Identifier: GPL-2.0 ++# ++obj-$(CONFIG_CS_DSP) += cs_dsp.o +diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c +new file mode 100644 +index 000000000000..948dd8382686 +--- /dev/null ++++ b/drivers/firmware/cirrus/cs_dsp.c +@@ -0,0 +1,3109 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * cs_dsp.c -- Cirrus Logic DSP firmware support ++ * ++ * Based on sound/soc/codecs/wm_adsp.c ++ * ++ * Copyright 2012 Wolfson Microelectronics plc ++ * Copyright (C) 2015-2021 Cirrus Logic, Inc. and ++ * Cirrus Logic International Semiconductor Ltd. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#define cs_dsp_err(_dsp, fmt, ...) \ ++ dev_err(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) ++#define cs_dsp_warn(_dsp, fmt, ...) \ ++ dev_warn(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) ++#define cs_dsp_info(_dsp, fmt, ...) \ ++ dev_info(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) ++#define cs_dsp_dbg(_dsp, fmt, ...) \ ++ dev_dbg(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) ++ ++#define ADSP1_CONTROL_1 0x00 ++#define ADSP1_CONTROL_2 0x02 ++#define ADSP1_CONTROL_3 0x03 ++#define ADSP1_CONTROL_4 0x04 ++#define ADSP1_CONTROL_5 0x06 ++#define ADSP1_CONTROL_6 0x07 ++#define ADSP1_CONTROL_7 0x08 ++#define ADSP1_CONTROL_8 0x09 ++#define ADSP1_CONTROL_9 0x0A ++#define ADSP1_CONTROL_10 0x0B ++#define ADSP1_CONTROL_11 0x0C ++#define ADSP1_CONTROL_12 0x0D ++#define ADSP1_CONTROL_13 0x0F ++#define ADSP1_CONTROL_14 0x10 ++#define ADSP1_CONTROL_15 0x11 ++#define ADSP1_CONTROL_16 0x12 ++#define ADSP1_CONTROL_17 0x13 ++#define ADSP1_CONTROL_18 0x14 ++#define ADSP1_CONTROL_19 0x16 ++#define ADSP1_CONTROL_20 0x17 ++#define ADSP1_CONTROL_21 0x18 ++#define ADSP1_CONTROL_22 0x1A ++#define ADSP1_CONTROL_23 0x1B ++#define ADSP1_CONTROL_24 0x1C ++#define ADSP1_CONTROL_25 0x1E ++#define ADSP1_CONTROL_26 0x20 ++#define ADSP1_CONTROL_27 0x21 ++#define ADSP1_CONTROL_28 0x22 ++#define ADSP1_CONTROL_29 0x23 ++#define ADSP1_CONTROL_30 0x24 ++#define ADSP1_CONTROL_31 0x26 ++ ++/* ++ * ADSP1 Control 19 ++ */ ++#define ADSP1_WDMA_BUFFER_LENGTH_MASK 0x00FF /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ ++#define ADSP1_WDMA_BUFFER_LENGTH_SHIFT 0 /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ ++#define ADSP1_WDMA_BUFFER_LENGTH_WIDTH 8 /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ ++ ++/* ++ * ADSP1 Control 30 ++ */ ++#define ADSP1_DBG_CLK_ENA 0x0008 /* DSP1_DBG_CLK_ENA */ ++#define ADSP1_DBG_CLK_ENA_MASK 0x0008 /* DSP1_DBG_CLK_ENA */ ++#define ADSP1_DBG_CLK_ENA_SHIFT 3 /* DSP1_DBG_CLK_ENA */ ++#define ADSP1_DBG_CLK_ENA_WIDTH 1 /* DSP1_DBG_CLK_ENA */ ++#define ADSP1_SYS_ENA 0x0004 /* DSP1_SYS_ENA */ ++#define ADSP1_SYS_ENA_MASK 0x0004 /* DSP1_SYS_ENA */ ++#define ADSP1_SYS_ENA_SHIFT 2 /* DSP1_SYS_ENA */ ++#define ADSP1_SYS_ENA_WIDTH 1 /* DSP1_SYS_ENA */ ++#define ADSP1_CORE_ENA 0x0002 /* DSP1_CORE_ENA */ ++#define ADSP1_CORE_ENA_MASK 0x0002 /* DSP1_CORE_ENA */ ++#define ADSP1_CORE_ENA_SHIFT 1 /* DSP1_CORE_ENA */ ++#define ADSP1_CORE_ENA_WIDTH 1 /* DSP1_CORE_ENA */ ++#define ADSP1_START 0x0001 /* DSP1_START */ ++#define ADSP1_START_MASK 0x0001 /* DSP1_START */ ++#define ADSP1_START_SHIFT 0 /* DSP1_START */ ++#define ADSP1_START_WIDTH 1 /* DSP1_START */ ++ ++/* ++ * ADSP1 Control 31 ++ */ ++#define ADSP1_CLK_SEL_MASK 0x0007 /* CLK_SEL_ENA */ ++#define ADSP1_CLK_SEL_SHIFT 0 /* CLK_SEL_ENA */ ++#define ADSP1_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */ ++ ++#define ADSP2_CONTROL 0x0 ++#define ADSP2_CLOCKING 0x1 ++#define ADSP2V2_CLOCKING 0x2 ++#define ADSP2_STATUS1 0x4 ++#define ADSP2_WDMA_CONFIG_1 0x30 ++#define ADSP2_WDMA_CONFIG_2 0x31 ++#define ADSP2V2_WDMA_CONFIG_2 0x32 ++#define ADSP2_RDMA_CONFIG_1 0x34 ++ ++#define ADSP2_SCRATCH0 0x40 ++#define ADSP2_SCRATCH1 0x41 ++#define ADSP2_SCRATCH2 0x42 ++#define ADSP2_SCRATCH3 0x43 ++ ++#define ADSP2V2_SCRATCH0_1 0x40 ++#define ADSP2V2_SCRATCH2_3 0x42 ++ ++/* ++ * ADSP2 Control ++ */ ++#define ADSP2_MEM_ENA 0x0010 /* DSP1_MEM_ENA */ ++#define ADSP2_MEM_ENA_MASK 0x0010 /* DSP1_MEM_ENA */ ++#define ADSP2_MEM_ENA_SHIFT 4 /* DSP1_MEM_ENA */ ++#define ADSP2_MEM_ENA_WIDTH 1 /* DSP1_MEM_ENA */ ++#define ADSP2_SYS_ENA 0x0004 /* DSP1_SYS_ENA */ ++#define ADSP2_SYS_ENA_MASK 0x0004 /* DSP1_SYS_ENA */ ++#define ADSP2_SYS_ENA_SHIFT 2 /* DSP1_SYS_ENA */ ++#define ADSP2_SYS_ENA_WIDTH 1 /* DSP1_SYS_ENA */ ++#define ADSP2_CORE_ENA 0x0002 /* DSP1_CORE_ENA */ ++#define ADSP2_CORE_ENA_MASK 0x0002 /* DSP1_CORE_ENA */ ++#define ADSP2_CORE_ENA_SHIFT 1 /* DSP1_CORE_ENA */ ++#define ADSP2_CORE_ENA_WIDTH 1 /* DSP1_CORE_ENA */ ++#define ADSP2_START 0x0001 /* DSP1_START */ ++#define ADSP2_START_MASK 0x0001 /* DSP1_START */ ++#define ADSP2_START_SHIFT 0 /* DSP1_START */ ++#define ADSP2_START_WIDTH 1 /* DSP1_START */ ++ ++/* ++ * ADSP2 clocking ++ */ ++#define ADSP2_CLK_SEL_MASK 0x0007 /* CLK_SEL_ENA */ ++#define ADSP2_CLK_SEL_SHIFT 0 /* CLK_SEL_ENA */ ++#define ADSP2_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */ ++ ++/* ++ * ADSP2V2 clocking ++ */ ++#define ADSP2V2_CLK_SEL_MASK 0x70000 /* CLK_SEL_ENA */ ++#define ADSP2V2_CLK_SEL_SHIFT 16 /* CLK_SEL_ENA */ ++#define ADSP2V2_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */ ++ ++#define ADSP2V2_RATE_MASK 0x7800 /* DSP_RATE */ ++#define ADSP2V2_RATE_SHIFT 11 /* DSP_RATE */ ++#define ADSP2V2_RATE_WIDTH 4 /* DSP_RATE */ ++ ++/* ++ * ADSP2 Status 1 ++ */ ++#define ADSP2_RAM_RDY 0x0001 ++#define ADSP2_RAM_RDY_MASK 0x0001 ++#define ADSP2_RAM_RDY_SHIFT 0 ++#define ADSP2_RAM_RDY_WIDTH 1 ++ ++/* ++ * ADSP2 Lock support ++ */ ++#define ADSP2_LOCK_CODE_0 0x5555 ++#define ADSP2_LOCK_CODE_1 0xAAAA ++ ++#define ADSP2_WATCHDOG 0x0A ++#define ADSP2_BUS_ERR_ADDR 0x52 ++#define ADSP2_REGION_LOCK_STATUS 0x64 ++#define ADSP2_LOCK_REGION_1_LOCK_REGION_0 0x66 ++#define ADSP2_LOCK_REGION_3_LOCK_REGION_2 0x68 ++#define ADSP2_LOCK_REGION_5_LOCK_REGION_4 0x6A ++#define ADSP2_LOCK_REGION_7_LOCK_REGION_6 0x6C ++#define ADSP2_LOCK_REGION_9_LOCK_REGION_8 0x6E ++#define ADSP2_LOCK_REGION_CTRL 0x7A ++#define ADSP2_PMEM_ERR_ADDR_XMEM_ERR_ADDR 0x7C ++ ++#define ADSP2_REGION_LOCK_ERR_MASK 0x8000 ++#define ADSP2_ADDR_ERR_MASK 0x4000 ++#define ADSP2_WDT_TIMEOUT_STS_MASK 0x2000 ++#define ADSP2_CTRL_ERR_PAUSE_ENA 0x0002 ++#define ADSP2_CTRL_ERR_EINT 0x0001 ++ ++#define ADSP2_BUS_ERR_ADDR_MASK 0x00FFFFFF ++#define ADSP2_XMEM_ERR_ADDR_MASK 0x0000FFFF ++#define ADSP2_PMEM_ERR_ADDR_MASK 0x7FFF0000 ++#define ADSP2_PMEM_ERR_ADDR_SHIFT 16 ++#define ADSP2_WDT_ENA_MASK 0xFFFFFFFD ++ ++#define ADSP2_LOCK_REGION_SHIFT 16 ++ ++/* ++ * Event control messages ++ */ ++#define CS_DSP_FW_EVENT_SHUTDOWN 0x000001 ++ ++/* ++ * HALO system info ++ */ ++#define HALO_AHBM_WINDOW_DEBUG_0 0x02040 ++#define HALO_AHBM_WINDOW_DEBUG_1 0x02044 ++ ++/* ++ * HALO core ++ */ ++#define HALO_SCRATCH1 0x005c0 ++#define HALO_SCRATCH2 0x005c8 ++#define HALO_SCRATCH3 0x005d0 ++#define HALO_SCRATCH4 0x005d8 ++#define HALO_CCM_CORE_CONTROL 0x41000 ++#define HALO_CORE_SOFT_RESET 0x00010 ++#define HALO_WDT_CONTROL 0x47000 ++ ++/* ++ * HALO MPU banks ++ */ ++#define HALO_MPU_XMEM_ACCESS_0 0x43000 ++#define HALO_MPU_YMEM_ACCESS_0 0x43004 ++#define HALO_MPU_WINDOW_ACCESS_0 0x43008 ++#define HALO_MPU_XREG_ACCESS_0 0x4300C ++#define HALO_MPU_YREG_ACCESS_0 0x43014 ++#define HALO_MPU_XMEM_ACCESS_1 0x43018 ++#define HALO_MPU_YMEM_ACCESS_1 0x4301C ++#define HALO_MPU_WINDOW_ACCESS_1 0x43020 ++#define HALO_MPU_XREG_ACCESS_1 0x43024 ++#define HALO_MPU_YREG_ACCESS_1 0x4302C ++#define HALO_MPU_XMEM_ACCESS_2 0x43030 ++#define HALO_MPU_YMEM_ACCESS_2 0x43034 ++#define HALO_MPU_WINDOW_ACCESS_2 0x43038 ++#define HALO_MPU_XREG_ACCESS_2 0x4303C ++#define HALO_MPU_YREG_ACCESS_2 0x43044 ++#define HALO_MPU_XMEM_ACCESS_3 0x43048 ++#define HALO_MPU_YMEM_ACCESS_3 0x4304C ++#define HALO_MPU_WINDOW_ACCESS_3 0x43050 ++#define HALO_MPU_XREG_ACCESS_3 0x43054 ++#define HALO_MPU_YREG_ACCESS_3 0x4305C ++#define HALO_MPU_XM_VIO_ADDR 0x43100 ++#define HALO_MPU_XM_VIO_STATUS 0x43104 ++#define HALO_MPU_YM_VIO_ADDR 0x43108 ++#define HALO_MPU_YM_VIO_STATUS 0x4310C ++#define HALO_MPU_PM_VIO_ADDR 0x43110 ++#define HALO_MPU_PM_VIO_STATUS 0x43114 ++#define HALO_MPU_LOCK_CONFIG 0x43140 ++ ++/* ++ * HALO_AHBM_WINDOW_DEBUG_1 ++ */ ++#define HALO_AHBM_CORE_ERR_ADDR_MASK 0x0fffff00 ++#define HALO_AHBM_CORE_ERR_ADDR_SHIFT 8 ++#define HALO_AHBM_FLAGS_ERR_MASK 0x000000ff ++ ++/* ++ * HALO_CCM_CORE_CONTROL ++ */ ++#define HALO_CORE_RESET 0x00000200 ++#define HALO_CORE_EN 0x00000001 ++ ++/* ++ * HALO_CORE_SOFT_RESET ++ */ ++#define HALO_CORE_SOFT_RESET_MASK 0x00000001 ++ ++/* ++ * HALO_WDT_CONTROL ++ */ ++#define HALO_WDT_EN_MASK 0x00000001 ++ ++/* ++ * HALO_MPU_?M_VIO_STATUS ++ */ ++#define HALO_MPU_VIO_STS_MASK 0x007e0000 ++#define HALO_MPU_VIO_STS_SHIFT 17 ++#define HALO_MPU_VIO_ERR_WR_MASK 0x00008000 ++#define HALO_MPU_VIO_ERR_SRC_MASK 0x00007fff ++#define HALO_MPU_VIO_ERR_SRC_SHIFT 0 ++ ++struct cs_dsp_ops { ++ bool (*validate_version)(struct cs_dsp *dsp, unsigned int version); ++ unsigned int (*parse_sizes)(struct cs_dsp *dsp, ++ const char * const file, ++ unsigned int pos, ++ const struct firmware *firmware); ++ int (*setup_algs)(struct cs_dsp *dsp); ++ unsigned int (*region_to_reg)(struct cs_dsp_region const *mem, ++ unsigned int offset); ++ ++ void (*show_fw_status)(struct cs_dsp *dsp); ++ void (*stop_watchdog)(struct cs_dsp *dsp); ++ ++ int (*enable_memory)(struct cs_dsp *dsp); ++ void (*disable_memory)(struct cs_dsp *dsp); ++ int (*lock_memory)(struct cs_dsp *dsp, unsigned int lock_regions); ++ ++ int (*enable_core)(struct cs_dsp *dsp); ++ void (*disable_core)(struct cs_dsp *dsp); ++ ++ int (*start_core)(struct cs_dsp *dsp); ++ void (*stop_core)(struct cs_dsp *dsp); ++}; ++ ++static const struct cs_dsp_ops cs_dsp_adsp1_ops; ++static const struct cs_dsp_ops cs_dsp_adsp2_ops[]; ++static const struct cs_dsp_ops cs_dsp_halo_ops; ++ ++struct cs_dsp_buf { ++ struct list_head list; ++ void *buf; ++}; ++ ++static struct cs_dsp_buf *cs_dsp_buf_alloc(const void *src, size_t len, ++ struct list_head *list) ++{ ++ struct cs_dsp_buf *buf = kzalloc(sizeof(*buf), GFP_KERNEL); ++ ++ if (buf == NULL) ++ return NULL; ++ ++ buf->buf = vmalloc(len); ++ if (!buf->buf) { ++ kfree(buf); ++ return NULL; ++ } ++ memcpy(buf->buf, src, len); ++ ++ if (list) ++ list_add_tail(&buf->list, list); ++ ++ return buf; ++} ++ ++static void cs_dsp_buf_free(struct list_head *list) ++{ ++ while (!list_empty(list)) { ++ struct cs_dsp_buf *buf = list_first_entry(list, ++ struct cs_dsp_buf, ++ list); ++ list_del(&buf->list); ++ vfree(buf->buf); ++ kfree(buf); ++ } ++} ++ ++/** ++ * cs_dsp_mem_region_name() - Return a name string for a memory type ++ * @type: the memory type to match ++ * ++ * Return: A const string identifying the memory region. ++ */ ++const char *cs_dsp_mem_region_name(unsigned int type) ++{ ++ switch (type) { ++ case WMFW_ADSP1_PM: ++ return "PM"; ++ case WMFW_HALO_PM_PACKED: ++ return "PM_PACKED"; ++ case WMFW_ADSP1_DM: ++ return "DM"; ++ case WMFW_ADSP2_XM: ++ return "XM"; ++ case WMFW_HALO_XM_PACKED: ++ return "XM_PACKED"; ++ case WMFW_ADSP2_YM: ++ return "YM"; ++ case WMFW_HALO_YM_PACKED: ++ return "YM_PACKED"; ++ case WMFW_ADSP1_ZM: ++ return "ZM"; ++ default: ++ return NULL; ++ } ++} ++EXPORT_SYMBOL_GPL(cs_dsp_mem_region_name); ++ ++#ifdef CONFIG_DEBUG_FS ++static void cs_dsp_debugfs_save_wmfwname(struct cs_dsp *dsp, const char *s) ++{ ++ char *tmp = kasprintf(GFP_KERNEL, "%s\n", s); ++ ++ kfree(dsp->wmfw_file_name); ++ dsp->wmfw_file_name = tmp; ++} ++ ++static void cs_dsp_debugfs_save_binname(struct cs_dsp *dsp, const char *s) ++{ ++ char *tmp = kasprintf(GFP_KERNEL, "%s\n", s); ++ ++ kfree(dsp->bin_file_name); ++ dsp->bin_file_name = tmp; ++} ++ ++static void cs_dsp_debugfs_clear(struct cs_dsp *dsp) ++{ ++ kfree(dsp->wmfw_file_name); ++ kfree(dsp->bin_file_name); ++ dsp->wmfw_file_name = NULL; ++ dsp->bin_file_name = NULL; ++} ++ ++static ssize_t cs_dsp_debugfs_wmfw_read(struct file *file, ++ char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct cs_dsp *dsp = file->private_data; ++ ssize_t ret; ++ ++ mutex_lock(&dsp->pwr_lock); ++ ++ if (!dsp->wmfw_file_name || !dsp->booted) ++ ret = 0; ++ else ++ ret = simple_read_from_buffer(user_buf, count, ppos, ++ dsp->wmfw_file_name, ++ strlen(dsp->wmfw_file_name)); ++ ++ mutex_unlock(&dsp->pwr_lock); ++ return ret; ++} ++ ++static ssize_t cs_dsp_debugfs_bin_read(struct file *file, ++ char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct cs_dsp *dsp = file->private_data; ++ ssize_t ret; ++ ++ mutex_lock(&dsp->pwr_lock); ++ ++ if (!dsp->bin_file_name || !dsp->booted) ++ ret = 0; ++ else ++ ret = simple_read_from_buffer(user_buf, count, ppos, ++ dsp->bin_file_name, ++ strlen(dsp->bin_file_name)); ++ ++ mutex_unlock(&dsp->pwr_lock); ++ return ret; ++} ++ ++static const struct { ++ const char *name; ++ const struct file_operations fops; ++} cs_dsp_debugfs_fops[] = { ++ { ++ .name = "wmfw_file_name", ++ .fops = { ++ .open = simple_open, ++ .read = cs_dsp_debugfs_wmfw_read, ++ }, ++ }, ++ { ++ .name = "bin_file_name", ++ .fops = { ++ .open = simple_open, ++ .read = cs_dsp_debugfs_bin_read, ++ }, ++ }, ++}; ++ ++/** ++ * cs_dsp_init_debugfs() - Create and populate DSP representation in debugfs ++ * @dsp: pointer to DSP structure ++ * @debugfs_root: pointer to debugfs directory in which to create this DSP ++ * representation ++ */ ++void cs_dsp_init_debugfs(struct cs_dsp *dsp, struct dentry *debugfs_root) ++{ ++ struct dentry *root = NULL; ++ int i; ++ ++ root = debugfs_create_dir(dsp->name, debugfs_root); ++ ++ debugfs_create_bool("booted", 0444, root, &dsp->booted); ++ debugfs_create_bool("running", 0444, root, &dsp->running); ++ debugfs_create_x32("fw_id", 0444, root, &dsp->fw_id); ++ debugfs_create_x32("fw_version", 0444, root, &dsp->fw_id_version); ++ ++ for (i = 0; i < ARRAY_SIZE(cs_dsp_debugfs_fops); ++i) ++ debugfs_create_file(cs_dsp_debugfs_fops[i].name, 0444, root, ++ dsp, &cs_dsp_debugfs_fops[i].fops); ++ ++ dsp->debugfs_root = root; ++} ++EXPORT_SYMBOL_GPL(cs_dsp_init_debugfs); ++ ++/** ++ * cs_dsp_cleanup_debugfs() - Removes DSP representation from debugfs ++ * @dsp: pointer to DSP structure ++ */ ++void cs_dsp_cleanup_debugfs(struct cs_dsp *dsp) ++{ ++ cs_dsp_debugfs_clear(dsp); ++ debugfs_remove_recursive(dsp->debugfs_root); ++ dsp->debugfs_root = NULL; ++} ++EXPORT_SYMBOL_GPL(cs_dsp_cleanup_debugfs); ++#else ++void cs_dsp_init_debugfs(struct cs_dsp *dsp, struct dentry *debugfs_root) ++{ ++} ++EXPORT_SYMBOL_GPL(cs_dsp_init_debugfs); ++ ++void cs_dsp_cleanup_debugfs(struct cs_dsp *dsp) ++{ ++} ++EXPORT_SYMBOL_GPL(cs_dsp_cleanup_debugfs); ++ ++static inline void cs_dsp_debugfs_save_wmfwname(struct cs_dsp *dsp, ++ const char *s) ++{ ++} ++ ++static inline void cs_dsp_debugfs_save_binname(struct cs_dsp *dsp, ++ const char *s) ++{ ++} ++ ++static inline void cs_dsp_debugfs_clear(struct cs_dsp *dsp) ++{ ++} ++#endif ++ ++static const struct cs_dsp_region *cs_dsp_find_region(struct cs_dsp *dsp, ++ int type) ++{ ++ int i; ++ ++ for (i = 0; i < dsp->num_mems; i++) ++ if (dsp->mem[i].type == type) ++ return &dsp->mem[i]; ++ ++ return NULL; ++} ++ ++static unsigned int cs_dsp_region_to_reg(struct cs_dsp_region const *mem, ++ unsigned int offset) ++{ ++ switch (mem->type) { ++ case WMFW_ADSP1_PM: ++ return mem->base + (offset * 3); ++ case WMFW_ADSP1_DM: ++ case WMFW_ADSP2_XM: ++ case WMFW_ADSP2_YM: ++ case WMFW_ADSP1_ZM: ++ return mem->base + (offset * 2); ++ default: ++ WARN(1, "Unknown memory region type"); ++ return offset; ++ } ++} ++ ++static unsigned int cs_dsp_halo_region_to_reg(struct cs_dsp_region const *mem, ++ unsigned int offset) ++{ ++ switch (mem->type) { ++ case WMFW_ADSP2_XM: ++ case WMFW_ADSP2_YM: ++ return mem->base + (offset * 4); ++ case WMFW_HALO_XM_PACKED: ++ case WMFW_HALO_YM_PACKED: ++ return (mem->base + (offset * 3)) & ~0x3; ++ case WMFW_HALO_PM_PACKED: ++ return mem->base + (offset * 5); ++ default: ++ WARN(1, "Unknown memory region type"); ++ return offset; ++ } ++} ++ ++static void cs_dsp_read_fw_status(struct cs_dsp *dsp, ++ int noffs, unsigned int *offs) ++{ ++ unsigned int i; ++ int ret; ++ ++ for (i = 0; i < noffs; ++i) { ++ ret = regmap_read(dsp->regmap, dsp->base + offs[i], &offs[i]); ++ if (ret) { ++ cs_dsp_err(dsp, "Failed to read SCRATCH%u: %d\n", i, ret); ++ return; ++ } ++ } ++} ++ ++static void cs_dsp_adsp2_show_fw_status(struct cs_dsp *dsp) ++{ ++ unsigned int offs[] = { ++ ADSP2_SCRATCH0, ADSP2_SCRATCH1, ADSP2_SCRATCH2, ADSP2_SCRATCH3, ++ }; ++ ++ cs_dsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs); ++ ++ cs_dsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", ++ offs[0], offs[1], offs[2], offs[3]); ++} ++ ++static void cs_dsp_adsp2v2_show_fw_status(struct cs_dsp *dsp) ++{ ++ unsigned int offs[] = { ADSP2V2_SCRATCH0_1, ADSP2V2_SCRATCH2_3 }; ++ ++ cs_dsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs); ++ ++ cs_dsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", ++ offs[0] & 0xFFFF, offs[0] >> 16, ++ offs[1] & 0xFFFF, offs[1] >> 16); ++} ++ ++static void cs_dsp_halo_show_fw_status(struct cs_dsp *dsp) ++{ ++ unsigned int offs[] = { ++ HALO_SCRATCH1, HALO_SCRATCH2, HALO_SCRATCH3, HALO_SCRATCH4, ++ }; ++ ++ cs_dsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs); ++ ++ cs_dsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", ++ offs[0], offs[1], offs[2], offs[3]); ++} ++ ++static int cs_dsp_coeff_base_reg(struct cs_dsp_coeff_ctl *ctl, unsigned int *reg) ++{ ++ const struct cs_dsp_alg_region *alg_region = &ctl->alg_region; ++ struct cs_dsp *dsp = ctl->dsp; ++ const struct cs_dsp_region *mem; ++ ++ mem = cs_dsp_find_region(dsp, alg_region->type); ++ if (!mem) { ++ cs_dsp_err(dsp, "No base for region %x\n", ++ alg_region->type); ++ return -EINVAL; ++ } ++ ++ *reg = dsp->ops->region_to_reg(mem, ctl->alg_region.base + ctl->offset); ++ ++ return 0; ++} ++ ++/** ++ * cs_dsp_coeff_write_acked_control() - Sends event_id to the acked control ++ * @ctl: pointer to acked coefficient control ++ * @event_id: the value to write to the given acked control ++ * ++ * Once the value has been written to the control the function shall block ++ * until the running firmware acknowledges the write or timeout is exceeded. ++ * ++ * Must be called with pwr_lock held. ++ * ++ * Return: Zero for success, a negative number on error. ++ */ ++int cs_dsp_coeff_write_acked_control(struct cs_dsp_coeff_ctl *ctl, unsigned int event_id) ++{ ++ struct cs_dsp *dsp = ctl->dsp; ++ __be32 val = cpu_to_be32(event_id); ++ unsigned int reg; ++ int i, ret; ++ ++ if (!dsp->running) ++ return -EPERM; ++ ++ ret = cs_dsp_coeff_base_reg(ctl, ®); ++ if (ret) ++ return ret; ++ ++ cs_dsp_dbg(dsp, "Sending 0x%x to acked control alg 0x%x %s:0x%x\n", ++ event_id, ctl->alg_region.alg, ++ cs_dsp_mem_region_name(ctl->alg_region.type), ctl->offset); ++ ++ ret = regmap_raw_write(dsp->regmap, reg, &val, sizeof(val)); ++ if (ret) { ++ cs_dsp_err(dsp, "Failed to write %x: %d\n", reg, ret); ++ return ret; ++ } ++ ++ /* ++ * Poll for ack, we initially poll at ~1ms intervals for firmwares ++ * that respond quickly, then go to ~10ms polls. A firmware is unlikely ++ * to ack instantly so we do the first 1ms delay before reading the ++ * control to avoid a pointless bus transaction ++ */ ++ for (i = 0; i < CS_DSP_ACKED_CTL_TIMEOUT_MS;) { ++ switch (i) { ++ case 0 ... CS_DSP_ACKED_CTL_N_QUICKPOLLS - 1: ++ usleep_range(1000, 2000); ++ i++; ++ break; ++ default: ++ usleep_range(10000, 20000); ++ i += 10; ++ break; ++ } ++ ++ ret = regmap_raw_read(dsp->regmap, reg, &val, sizeof(val)); ++ if (ret) { ++ cs_dsp_err(dsp, "Failed to read %x: %d\n", reg, ret); ++ return ret; ++ } ++ ++ if (val == 0) { ++ cs_dsp_dbg(dsp, "Acked control ACKED at poll %u\n", i); ++ return 0; ++ } ++ } ++ ++ cs_dsp_warn(dsp, "Acked control @0x%x alg:0x%x %s:0x%x timed out\n", ++ reg, ctl->alg_region.alg, ++ cs_dsp_mem_region_name(ctl->alg_region.type), ++ ctl->offset); ++ ++ return -ETIMEDOUT; ++} ++EXPORT_SYMBOL_GPL(cs_dsp_coeff_write_acked_control); ++ ++static int cs_dsp_coeff_write_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, ++ const void *buf, size_t len) ++{ ++ struct cs_dsp *dsp = ctl->dsp; ++ void *scratch; ++ int ret; ++ unsigned int reg; ++ ++ ret = cs_dsp_coeff_base_reg(ctl, ®); ++ if (ret) ++ return ret; ++ ++ scratch = kmemdup(buf, len, GFP_KERNEL | GFP_DMA); ++ if (!scratch) ++ return -ENOMEM; ++ ++ ret = regmap_raw_write(dsp->regmap, reg, scratch, ++ len); ++ if (ret) { ++ cs_dsp_err(dsp, "Failed to write %zu bytes to %x: %d\n", ++ len, reg, ret); ++ kfree(scratch); ++ return ret; ++ } ++ cs_dsp_dbg(dsp, "Wrote %zu bytes to %x\n", len, reg); ++ ++ kfree(scratch); ++ ++ return 0; ++} ++ ++/** ++ * cs_dsp_coeff_write_ctrl() - Writes the given buffer to the given coefficient control ++ * @ctl: pointer to coefficient control ++ * @buf: the buffer to write to the given control ++ * @len: the length of the buffer ++ * ++ * Must be called with pwr_lock held. ++ * ++ * Return: Zero for success, a negative number on error. ++ */ ++int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl, const void *buf, size_t len) ++{ ++ int ret = 0; ++ ++ if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) ++ ret = -EPERM; ++ else if (buf != ctl->cache) ++ memcpy(ctl->cache, buf, len); ++ ++ ctl->set = 1; ++ if (ctl->enabled && ctl->dsp->running) ++ ret = cs_dsp_coeff_write_ctrl_raw(ctl, buf, len); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(cs_dsp_coeff_write_ctrl); ++ ++static int cs_dsp_coeff_read_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, void *buf, size_t len) ++{ ++ struct cs_dsp *dsp = ctl->dsp; ++ void *scratch; ++ int ret; ++ unsigned int reg; ++ ++ ret = cs_dsp_coeff_base_reg(ctl, ®); ++ if (ret) ++ return ret; ++ ++ scratch = kmalloc(len, GFP_KERNEL | GFP_DMA); ++ if (!scratch) ++ return -ENOMEM; ++ ++ ret = regmap_raw_read(dsp->regmap, reg, scratch, len); ++ if (ret) { ++ cs_dsp_err(dsp, "Failed to read %zu bytes from %x: %d\n", ++ len, reg, ret); ++ kfree(scratch); ++ return ret; ++ } ++ cs_dsp_dbg(dsp, "Read %zu bytes from %x\n", len, reg); ++ ++ memcpy(buf, scratch, len); ++ kfree(scratch); ++ ++ return 0; ++} ++ ++/** ++ * cs_dsp_coeff_read_ctrl() - Reads the given coefficient control into the given buffer ++ * @ctl: pointer to coefficient control ++ * @buf: the buffer to store to the given control ++ * @len: the length of the buffer ++ * ++ * Must be called with pwr_lock held. ++ * ++ * Return: Zero for success, a negative number on error. ++ */ ++int cs_dsp_coeff_read_ctrl(struct cs_dsp_coeff_ctl *ctl, void *buf, size_t len) ++{ ++ int ret = 0; ++ ++ if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) { ++ if (ctl->enabled && ctl->dsp->running) ++ return cs_dsp_coeff_read_ctrl_raw(ctl, buf, len); ++ else ++ return -EPERM; ++ } else { ++ if (!ctl->flags && ctl->enabled && ctl->dsp->running) ++ ret = cs_dsp_coeff_read_ctrl_raw(ctl, ctl->cache, ctl->len); ++ ++ if (buf != ctl->cache) ++ memcpy(buf, ctl->cache, len); ++ } ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(cs_dsp_coeff_read_ctrl); ++ ++static int cs_dsp_coeff_init_control_caches(struct cs_dsp *dsp) ++{ ++ struct cs_dsp_coeff_ctl *ctl; ++ int ret; ++ ++ list_for_each_entry(ctl, &dsp->ctl_list, list) { ++ if (!ctl->enabled || ctl->set) ++ continue; ++ if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) ++ continue; ++ ++ /* ++ * For readable controls populate the cache from the DSP memory. ++ * For non-readable controls the cache was zero-filled when ++ * created so we don't need to do anything. ++ */ ++ if (!ctl->flags || (ctl->flags & WMFW_CTL_FLAG_READABLE)) { ++ ret = cs_dsp_coeff_read_ctrl_raw(ctl, ctl->cache, ctl->len); ++ if (ret < 0) ++ return ret; ++ } ++ } ++ ++ return 0; ++} ++ ++static int cs_dsp_coeff_sync_controls(struct cs_dsp *dsp) ++{ ++ struct cs_dsp_coeff_ctl *ctl; ++ int ret; ++ ++ list_for_each_entry(ctl, &dsp->ctl_list, list) { ++ if (!ctl->enabled) ++ continue; ++ if (ctl->set && !(ctl->flags & WMFW_CTL_FLAG_VOLATILE)) { ++ ret = cs_dsp_coeff_write_ctrl_raw(ctl, ctl->cache, ++ ctl->len); ++ if (ret < 0) ++ return ret; ++ } ++ } ++ ++ return 0; ++} ++ ++static void cs_dsp_signal_event_controls(struct cs_dsp *dsp, ++ unsigned int event) ++{ ++ struct cs_dsp_coeff_ctl *ctl; ++ int ret; ++ ++ list_for_each_entry(ctl, &dsp->ctl_list, list) { ++ if (ctl->type != WMFW_CTL_TYPE_HOSTEVENT) ++ continue; ++ ++ if (!ctl->enabled) ++ continue; ++ ++ ret = cs_dsp_coeff_write_acked_control(ctl, event); ++ if (ret) ++ cs_dsp_warn(dsp, ++ "Failed to send 0x%x event to alg 0x%x (%d)\n", ++ event, ctl->alg_region.alg, ret); ++ } ++} ++ ++static void cs_dsp_free_ctl_blk(struct cs_dsp_coeff_ctl *ctl) ++{ ++ kfree(ctl->cache); ++ kfree(ctl->subname); ++ kfree(ctl); ++} ++ ++static int cs_dsp_create_control(struct cs_dsp *dsp, ++ const struct cs_dsp_alg_region *alg_region, ++ unsigned int offset, unsigned int len, ++ const char *subname, unsigned int subname_len, ++ unsigned int flags, unsigned int type) ++{ ++ struct cs_dsp_coeff_ctl *ctl; ++ int ret; ++ ++ list_for_each_entry(ctl, &dsp->ctl_list, list) { ++ if (ctl->fw_name == dsp->fw_name && ++ ctl->alg_region.alg == alg_region->alg && ++ ctl->alg_region.type == alg_region->type) { ++ if ((!subname && !ctl->subname) || ++ (subname && !strncmp(ctl->subname, subname, ctl->subname_len))) { ++ if (!ctl->enabled) ++ ctl->enabled = 1; ++ return 0; ++ } ++ } ++ } ++ ++ ctl = kzalloc(sizeof(*ctl), GFP_KERNEL); ++ if (!ctl) ++ return -ENOMEM; ++ ++ ctl->fw_name = dsp->fw_name; ++ ctl->alg_region = *alg_region; ++ if (subname && dsp->fw_ver >= 2) { ++ ctl->subname_len = subname_len; ++ ctl->subname = kmemdup(subname, ++ strlen(subname) + 1, GFP_KERNEL); ++ if (!ctl->subname) { ++ ret = -ENOMEM; ++ goto err_ctl; ++ } ++ } ++ ctl->enabled = 1; ++ ctl->set = 0; ++ ctl->dsp = dsp; ++ ++ ctl->flags = flags; ++ ctl->type = type; ++ ctl->offset = offset; ++ ctl->len = len; ++ ctl->cache = kzalloc(ctl->len, GFP_KERNEL); ++ if (!ctl->cache) { ++ ret = -ENOMEM; ++ goto err_ctl_subname; ++ } ++ ++ list_add(&ctl->list, &dsp->ctl_list); ++ ++ if (dsp->client_ops->control_add) { ++ ret = dsp->client_ops->control_add(ctl); ++ if (ret) ++ goto err_list_del; ++ } ++ ++ return 0; ++ ++err_list_del: ++ list_del(&ctl->list); ++ kfree(ctl->cache); ++err_ctl_subname: ++ kfree(ctl->subname); ++err_ctl: ++ kfree(ctl); ++ ++ return ret; ++} ++ ++struct cs_dsp_coeff_parsed_alg { ++ int id; ++ const u8 *name; ++ int name_len; ++ int ncoeff; ++}; ++ ++struct cs_dsp_coeff_parsed_coeff { ++ int offset; ++ int mem_type; ++ const u8 *name; ++ int name_len; ++ unsigned int ctl_type; ++ int flags; ++ int len; ++}; ++ ++static int cs_dsp_coeff_parse_string(int bytes, const u8 **pos, const u8 **str) ++{ ++ int length; ++ ++ switch (bytes) { ++ case 1: ++ length = **pos; ++ break; ++ case 2: ++ length = le16_to_cpu(*((__le16 *)*pos)); ++ break; ++ default: ++ return 0; ++ } ++ ++ if (str) ++ *str = *pos + bytes; ++ ++ *pos += ((length + bytes) + 3) & ~0x03; ++ ++ return length; ++} ++ ++static int cs_dsp_coeff_parse_int(int bytes, const u8 **pos) ++{ ++ int val = 0; ++ ++ switch (bytes) { ++ case 2: ++ val = le16_to_cpu(*((__le16 *)*pos)); ++ break; ++ case 4: ++ val = le32_to_cpu(*((__le32 *)*pos)); ++ break; ++ default: ++ break; ++ } ++ ++ *pos += bytes; ++ ++ return val; ++} ++ ++static inline void cs_dsp_coeff_parse_alg(struct cs_dsp *dsp, const u8 **data, ++ struct cs_dsp_coeff_parsed_alg *blk) ++{ ++ const struct wmfw_adsp_alg_data *raw; ++ ++ switch (dsp->fw_ver) { ++ case 0: ++ case 1: ++ raw = (const struct wmfw_adsp_alg_data *)*data; ++ *data = raw->data; ++ ++ blk->id = le32_to_cpu(raw->id); ++ blk->name = raw->name; ++ blk->name_len = strlen(raw->name); ++ blk->ncoeff = le32_to_cpu(raw->ncoeff); ++ break; ++ default: ++ blk->id = cs_dsp_coeff_parse_int(sizeof(raw->id), data); ++ blk->name_len = cs_dsp_coeff_parse_string(sizeof(u8), data, ++ &blk->name); ++ cs_dsp_coeff_parse_string(sizeof(u16), data, NULL); ++ blk->ncoeff = cs_dsp_coeff_parse_int(sizeof(raw->ncoeff), data); ++ break; ++ } ++ ++ cs_dsp_dbg(dsp, "Algorithm ID: %#x\n", blk->id); ++ cs_dsp_dbg(dsp, "Algorithm name: %.*s\n", blk->name_len, blk->name); ++ cs_dsp_dbg(dsp, "# of coefficient descriptors: %#x\n", blk->ncoeff); ++} ++ ++static inline void cs_dsp_coeff_parse_coeff(struct cs_dsp *dsp, const u8 **data, ++ struct cs_dsp_coeff_parsed_coeff *blk) ++{ ++ const struct wmfw_adsp_coeff_data *raw; ++ const u8 *tmp; ++ int length; ++ ++ switch (dsp->fw_ver) { ++ case 0: ++ case 1: ++ raw = (const struct wmfw_adsp_coeff_data *)*data; ++ *data = *data + sizeof(raw->hdr) + le32_to_cpu(raw->hdr.size); ++ ++ blk->offset = le16_to_cpu(raw->hdr.offset); ++ blk->mem_type = le16_to_cpu(raw->hdr.type); ++ blk->name = raw->name; ++ blk->name_len = strlen(raw->name); ++ blk->ctl_type = le16_to_cpu(raw->ctl_type); ++ blk->flags = le16_to_cpu(raw->flags); ++ blk->len = le32_to_cpu(raw->len); ++ break; ++ default: ++ tmp = *data; ++ blk->offset = cs_dsp_coeff_parse_int(sizeof(raw->hdr.offset), &tmp); ++ blk->mem_type = cs_dsp_coeff_parse_int(sizeof(raw->hdr.type), &tmp); ++ length = cs_dsp_coeff_parse_int(sizeof(raw->hdr.size), &tmp); ++ blk->name_len = cs_dsp_coeff_parse_string(sizeof(u8), &tmp, ++ &blk->name); ++ cs_dsp_coeff_parse_string(sizeof(u8), &tmp, NULL); ++ cs_dsp_coeff_parse_string(sizeof(u16), &tmp, NULL); ++ blk->ctl_type = cs_dsp_coeff_parse_int(sizeof(raw->ctl_type), &tmp); ++ blk->flags = cs_dsp_coeff_parse_int(sizeof(raw->flags), &tmp); ++ blk->len = cs_dsp_coeff_parse_int(sizeof(raw->len), &tmp); ++ ++ *data = *data + sizeof(raw->hdr) + length; ++ break; ++ } ++ ++ cs_dsp_dbg(dsp, "\tCoefficient type: %#x\n", blk->mem_type); ++ cs_dsp_dbg(dsp, "\tCoefficient offset: %#x\n", blk->offset); ++ cs_dsp_dbg(dsp, "\tCoefficient name: %.*s\n", blk->name_len, blk->name); ++ cs_dsp_dbg(dsp, "\tCoefficient flags: %#x\n", blk->flags); ++ cs_dsp_dbg(dsp, "\tALSA control type: %#x\n", blk->ctl_type); ++ cs_dsp_dbg(dsp, "\tALSA control len: %#x\n", blk->len); ++} ++ ++static int cs_dsp_check_coeff_flags(struct cs_dsp *dsp, ++ const struct cs_dsp_coeff_parsed_coeff *coeff_blk, ++ unsigned int f_required, ++ unsigned int f_illegal) ++{ ++ if ((coeff_blk->flags & f_illegal) || ++ ((coeff_blk->flags & f_required) != f_required)) { ++ cs_dsp_err(dsp, "Illegal flags 0x%x for control type 0x%x\n", ++ coeff_blk->flags, coeff_blk->ctl_type); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int cs_dsp_parse_coeff(struct cs_dsp *dsp, ++ const struct wmfw_region *region) ++{ ++ struct cs_dsp_alg_region alg_region = {}; ++ struct cs_dsp_coeff_parsed_alg alg_blk; ++ struct cs_dsp_coeff_parsed_coeff coeff_blk; ++ const u8 *data = region->data; ++ int i, ret; ++ ++ cs_dsp_coeff_parse_alg(dsp, &data, &alg_blk); ++ for (i = 0; i < alg_blk.ncoeff; i++) { ++ cs_dsp_coeff_parse_coeff(dsp, &data, &coeff_blk); ++ ++ switch (coeff_blk.ctl_type) { ++ case WMFW_CTL_TYPE_BYTES: ++ break; ++ case WMFW_CTL_TYPE_ACKED: ++ if (coeff_blk.flags & WMFW_CTL_FLAG_SYS) ++ continue; /* ignore */ ++ ++ ret = cs_dsp_check_coeff_flags(dsp, &coeff_blk, ++ WMFW_CTL_FLAG_VOLATILE | ++ WMFW_CTL_FLAG_WRITEABLE | ++ WMFW_CTL_FLAG_READABLE, ++ 0); ++ if (ret) ++ return -EINVAL; ++ break; ++ case WMFW_CTL_TYPE_HOSTEVENT: ++ ret = cs_dsp_check_coeff_flags(dsp, &coeff_blk, ++ WMFW_CTL_FLAG_SYS | ++ WMFW_CTL_FLAG_VOLATILE | ++ WMFW_CTL_FLAG_WRITEABLE | ++ WMFW_CTL_FLAG_READABLE, ++ 0); ++ if (ret) ++ return -EINVAL; ++ break; ++ case WMFW_CTL_TYPE_HOST_BUFFER: ++ ret = cs_dsp_check_coeff_flags(dsp, &coeff_blk, ++ WMFW_CTL_FLAG_SYS | ++ WMFW_CTL_FLAG_VOLATILE | ++ WMFW_CTL_FLAG_READABLE, ++ 0); ++ if (ret) ++ return -EINVAL; ++ break; ++ default: ++ cs_dsp_err(dsp, "Unknown control type: %d\n", ++ coeff_blk.ctl_type); ++ return -EINVAL; ++ } ++ ++ alg_region.type = coeff_blk.mem_type; ++ alg_region.alg = alg_blk.id; ++ ++ ret = cs_dsp_create_control(dsp, &alg_region, ++ coeff_blk.offset, ++ coeff_blk.len, ++ coeff_blk.name, ++ coeff_blk.name_len, ++ coeff_blk.flags, ++ coeff_blk.ctl_type); ++ if (ret < 0) ++ cs_dsp_err(dsp, "Failed to create control: %.*s, %d\n", ++ coeff_blk.name_len, coeff_blk.name, ret); ++ } ++ ++ return 0; ++} ++ ++static unsigned int cs_dsp_adsp1_parse_sizes(struct cs_dsp *dsp, ++ const char * const file, ++ unsigned int pos, ++ const struct firmware *firmware) ++{ ++ const struct wmfw_adsp1_sizes *adsp1_sizes; ++ ++ adsp1_sizes = (void *)&firmware->data[pos]; ++ ++ cs_dsp_dbg(dsp, "%s: %d DM, %d PM, %d ZM\n", file, ++ le32_to_cpu(adsp1_sizes->dm), le32_to_cpu(adsp1_sizes->pm), ++ le32_to_cpu(adsp1_sizes->zm)); ++ ++ return pos + sizeof(*adsp1_sizes); ++} ++ ++static unsigned int cs_dsp_adsp2_parse_sizes(struct cs_dsp *dsp, ++ const char * const file, ++ unsigned int pos, ++ const struct firmware *firmware) ++{ ++ const struct wmfw_adsp2_sizes *adsp2_sizes; ++ ++ adsp2_sizes = (void *)&firmware->data[pos]; ++ ++ cs_dsp_dbg(dsp, "%s: %d XM, %d YM %d PM, %d ZM\n", file, ++ le32_to_cpu(adsp2_sizes->xm), le32_to_cpu(adsp2_sizes->ym), ++ le32_to_cpu(adsp2_sizes->pm), le32_to_cpu(adsp2_sizes->zm)); ++ ++ return pos + sizeof(*adsp2_sizes); ++} ++ ++static bool cs_dsp_validate_version(struct cs_dsp *dsp, unsigned int version) ++{ ++ switch (version) { ++ case 0: ++ cs_dsp_warn(dsp, "Deprecated file format %d\n", version); ++ return true; ++ case 1: ++ case 2: ++ return true; ++ default: ++ return false; ++ } ++} ++ ++static bool cs_dsp_halo_validate_version(struct cs_dsp *dsp, unsigned int version) ++{ ++ switch (version) { ++ case 3: ++ return true; ++ default: ++ return false; ++ } ++} ++ ++static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware, ++ const char *file) ++{ ++ LIST_HEAD(buf_list); ++ struct regmap *regmap = dsp->regmap; ++ unsigned int pos = 0; ++ const struct wmfw_header *header; ++ const struct wmfw_adsp1_sizes *adsp1_sizes; ++ const struct wmfw_footer *footer; ++ const struct wmfw_region *region; ++ const struct cs_dsp_region *mem; ++ const char *region_name; ++ char *text = NULL; ++ struct cs_dsp_buf *buf; ++ unsigned int reg; ++ int regions = 0; ++ int ret, offset, type; ++ ++ ret = -EINVAL; ++ ++ pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer); ++ if (pos >= firmware->size) { ++ cs_dsp_err(dsp, "%s: file too short, %zu bytes\n", ++ file, firmware->size); ++ goto out_fw; ++ } ++ ++ header = (void *)&firmware->data[0]; ++ ++ if (memcmp(&header->magic[0], "WMFW", 4) != 0) { ++ cs_dsp_err(dsp, "%s: invalid magic\n", file); ++ goto out_fw; ++ } ++ ++ if (!dsp->ops->validate_version(dsp, header->ver)) { ++ cs_dsp_err(dsp, "%s: unknown file format %d\n", ++ file, header->ver); ++ goto out_fw; ++ } ++ ++ cs_dsp_info(dsp, "Firmware version: %d\n", header->ver); ++ dsp->fw_ver = header->ver; ++ ++ if (header->core != dsp->type) { ++ cs_dsp_err(dsp, "%s: invalid core %d != %d\n", ++ file, header->core, dsp->type); ++ goto out_fw; ++ } ++ ++ pos = sizeof(*header); ++ pos = dsp->ops->parse_sizes(dsp, file, pos, firmware); ++ ++ footer = (void *)&firmware->data[pos]; ++ pos += sizeof(*footer); ++ ++ if (le32_to_cpu(header->len) != pos) { ++ cs_dsp_err(dsp, "%s: unexpected header length %d\n", ++ file, le32_to_cpu(header->len)); ++ goto out_fw; ++ } ++ ++ cs_dsp_dbg(dsp, "%s: timestamp %llu\n", file, ++ le64_to_cpu(footer->timestamp)); ++ ++ while (pos < firmware->size && ++ sizeof(*region) < firmware->size - pos) { ++ region = (void *)&(firmware->data[pos]); ++ region_name = "Unknown"; ++ reg = 0; ++ text = NULL; ++ offset = le32_to_cpu(region->offset) & 0xffffff; ++ type = be32_to_cpu(region->type) & 0xff; ++ ++ switch (type) { ++ case WMFW_NAME_TEXT: ++ region_name = "Firmware name"; ++ text = kzalloc(le32_to_cpu(region->len) + 1, ++ GFP_KERNEL); ++ break; ++ case WMFW_ALGORITHM_DATA: ++ region_name = "Algorithm"; ++ ret = cs_dsp_parse_coeff(dsp, region); ++ if (ret != 0) ++ goto out_fw; ++ break; ++ case WMFW_INFO_TEXT: ++ region_name = "Information"; ++ text = kzalloc(le32_to_cpu(region->len) + 1, ++ GFP_KERNEL); ++ break; ++ case WMFW_ABSOLUTE: ++ region_name = "Absolute"; ++ reg = offset; ++ break; ++ case WMFW_ADSP1_PM: ++ case WMFW_ADSP1_DM: ++ case WMFW_ADSP2_XM: ++ case WMFW_ADSP2_YM: ++ case WMFW_ADSP1_ZM: ++ case WMFW_HALO_PM_PACKED: ++ case WMFW_HALO_XM_PACKED: ++ case WMFW_HALO_YM_PACKED: ++ mem = cs_dsp_find_region(dsp, type); ++ if (!mem) { ++ cs_dsp_err(dsp, "No region of type: %x\n", type); ++ ret = -EINVAL; ++ goto out_fw; ++ } ++ ++ region_name = cs_dsp_mem_region_name(type); ++ reg = dsp->ops->region_to_reg(mem, offset); ++ break; ++ default: ++ cs_dsp_warn(dsp, ++ "%s.%d: Unknown region type %x at %d(%x)\n", ++ file, regions, type, pos, pos); ++ break; ++ } ++ ++ cs_dsp_dbg(dsp, "%s.%d: %d bytes at %d in %s\n", file, ++ regions, le32_to_cpu(region->len), offset, ++ region_name); ++ ++ if (le32_to_cpu(region->len) > ++ firmware->size - pos - sizeof(*region)) { ++ cs_dsp_err(dsp, ++ "%s.%d: %s region len %d bytes exceeds file length %zu\n", ++ file, regions, region_name, ++ le32_to_cpu(region->len), firmware->size); ++ ret = -EINVAL; ++ goto out_fw; ++ } ++ ++ if (text) { ++ memcpy(text, region->data, le32_to_cpu(region->len)); ++ cs_dsp_info(dsp, "%s: %s\n", file, text); ++ kfree(text); ++ text = NULL; ++ } ++ ++ if (reg) { ++ buf = cs_dsp_buf_alloc(region->data, ++ le32_to_cpu(region->len), ++ &buf_list); ++ if (!buf) { ++ cs_dsp_err(dsp, "Out of memory\n"); ++ ret = -ENOMEM; ++ goto out_fw; ++ } ++ ++ ret = regmap_raw_write_async(regmap, reg, buf->buf, ++ le32_to_cpu(region->len)); ++ if (ret != 0) { ++ cs_dsp_err(dsp, ++ "%s.%d: Failed to write %d bytes at %d in %s: %d\n", ++ file, regions, ++ le32_to_cpu(region->len), offset, ++ region_name, ret); ++ goto out_fw; ++ } ++ } ++ ++ pos += le32_to_cpu(region->len) + sizeof(*region); ++ regions++; ++ } ++ ++ ret = regmap_async_complete(regmap); ++ if (ret != 0) { ++ cs_dsp_err(dsp, "Failed to complete async write: %d\n", ret); ++ goto out_fw; ++ } ++ ++ if (pos > firmware->size) ++ cs_dsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", ++ file, regions, pos - firmware->size); ++ ++ cs_dsp_debugfs_save_wmfwname(dsp, file); ++ ++out_fw: ++ regmap_async_complete(regmap); ++ cs_dsp_buf_free(&buf_list); ++ kfree(text); ++ ++ return ret; ++} ++ ++/** ++ * cs_dsp_get_ctl() - Finds a matching coefficient control ++ * @dsp: pointer to DSP structure ++ * @name: pointer to string to match with a control's subname ++ * @type: the algorithm type to match ++ * @alg: the algorithm id to match ++ * ++ * Find cs_dsp_coeff_ctl with input name as its subname ++ * ++ * Return: pointer to the control on success, NULL if not found ++ */ ++struct cs_dsp_coeff_ctl *cs_dsp_get_ctl(struct cs_dsp *dsp, const char *name, int type, ++ unsigned int alg) ++{ ++ struct cs_dsp_coeff_ctl *pos, *rslt = NULL; ++ ++ list_for_each_entry(pos, &dsp->ctl_list, list) { ++ if (!pos->subname) ++ continue; ++ if (strncmp(pos->subname, name, pos->subname_len) == 0 && ++ pos->fw_name == dsp->fw_name && ++ pos->alg_region.alg == alg && ++ pos->alg_region.type == type) { ++ rslt = pos; ++ break; ++ } ++ } ++ ++ return rslt; ++} ++EXPORT_SYMBOL_GPL(cs_dsp_get_ctl); ++ ++static void cs_dsp_ctl_fixup_base(struct cs_dsp *dsp, ++ const struct cs_dsp_alg_region *alg_region) ++{ ++ struct cs_dsp_coeff_ctl *ctl; ++ ++ list_for_each_entry(ctl, &dsp->ctl_list, list) { ++ if (ctl->fw_name == dsp->fw_name && ++ alg_region->alg == ctl->alg_region.alg && ++ alg_region->type == ctl->alg_region.type) { ++ ctl->alg_region.base = alg_region->base; ++ } ++ } ++} ++ ++static void *cs_dsp_read_algs(struct cs_dsp *dsp, size_t n_algs, ++ const struct cs_dsp_region *mem, ++ unsigned int pos, unsigned int len) ++{ ++ void *alg; ++ unsigned int reg; ++ int ret; ++ __be32 val; ++ ++ if (n_algs == 0) { ++ cs_dsp_err(dsp, "No algorithms\n"); ++ return ERR_PTR(-EINVAL); ++ } ++ ++ if (n_algs > 1024) { ++ cs_dsp_err(dsp, "Algorithm count %zx excessive\n", n_algs); ++ return ERR_PTR(-EINVAL); ++ } ++ ++ /* Read the terminator first to validate the length */ ++ reg = dsp->ops->region_to_reg(mem, pos + len); ++ ++ ret = regmap_raw_read(dsp->regmap, reg, &val, sizeof(val)); ++ if (ret != 0) { ++ cs_dsp_err(dsp, "Failed to read algorithm list end: %d\n", ++ ret); ++ return ERR_PTR(ret); ++ } ++ ++ if (be32_to_cpu(val) != 0xbedead) ++ cs_dsp_warn(dsp, "Algorithm list end %x 0x%x != 0xbedead\n", ++ reg, be32_to_cpu(val)); ++ ++ /* Convert length from DSP words to bytes */ ++ len *= sizeof(u32); ++ ++ alg = kzalloc(len, GFP_KERNEL | GFP_DMA); ++ if (!alg) ++ return ERR_PTR(-ENOMEM); ++ ++ reg = dsp->ops->region_to_reg(mem, pos); ++ ++ ret = regmap_raw_read(dsp->regmap, reg, alg, len); ++ if (ret != 0) { ++ cs_dsp_err(dsp, "Failed to read algorithm list: %d\n", ret); ++ kfree(alg); ++ return ERR_PTR(ret); ++ } ++ ++ return alg; ++} ++ ++/** ++ * cs_dsp_find_alg_region() - Finds a matching algorithm region ++ * @dsp: pointer to DSP structure ++ * @type: the algorithm type to match ++ * @id: the algorithm id to match ++ * ++ * Return: Pointer to matching algorithm region, or NULL if not found. ++ */ ++struct cs_dsp_alg_region *cs_dsp_find_alg_region(struct cs_dsp *dsp, ++ int type, unsigned int id) ++{ ++ struct cs_dsp_alg_region *alg_region; ++ ++ list_for_each_entry(alg_region, &dsp->alg_regions, list) { ++ if (id == alg_region->alg && type == alg_region->type) ++ return alg_region; ++ } ++ ++ return NULL; ++} ++EXPORT_SYMBOL_GPL(cs_dsp_find_alg_region); ++ ++static struct cs_dsp_alg_region *cs_dsp_create_region(struct cs_dsp *dsp, ++ int type, __be32 id, ++ __be32 base) ++{ ++ struct cs_dsp_alg_region *alg_region; ++ ++ alg_region = kzalloc(sizeof(*alg_region), GFP_KERNEL); ++ if (!alg_region) ++ return ERR_PTR(-ENOMEM); ++ ++ alg_region->type = type; ++ alg_region->alg = be32_to_cpu(id); ++ alg_region->base = be32_to_cpu(base); ++ ++ list_add_tail(&alg_region->list, &dsp->alg_regions); ++ ++ if (dsp->fw_ver > 0) ++ cs_dsp_ctl_fixup_base(dsp, alg_region); ++ ++ return alg_region; ++} ++ ++static void cs_dsp_free_alg_regions(struct cs_dsp *dsp) ++{ ++ struct cs_dsp_alg_region *alg_region; ++ ++ while (!list_empty(&dsp->alg_regions)) { ++ alg_region = list_first_entry(&dsp->alg_regions, ++ struct cs_dsp_alg_region, ++ list); ++ list_del(&alg_region->list); ++ kfree(alg_region); ++ } ++} ++ ++static void cs_dsp_parse_wmfw_id_header(struct cs_dsp *dsp, ++ struct wmfw_id_hdr *fw, int nalgs) ++{ ++ dsp->fw_id = be32_to_cpu(fw->id); ++ dsp->fw_id_version = be32_to_cpu(fw->ver); ++ ++ cs_dsp_info(dsp, "Firmware: %x v%d.%d.%d, %d algorithms\n", ++ dsp->fw_id, (dsp->fw_id_version & 0xff0000) >> 16, ++ (dsp->fw_id_version & 0xff00) >> 8, dsp->fw_id_version & 0xff, ++ nalgs); ++} ++ ++static void cs_dsp_parse_wmfw_v3_id_header(struct cs_dsp *dsp, ++ struct wmfw_v3_id_hdr *fw, int nalgs) ++{ ++ dsp->fw_id = be32_to_cpu(fw->id); ++ dsp->fw_id_version = be32_to_cpu(fw->ver); ++ dsp->fw_vendor_id = be32_to_cpu(fw->vendor_id); ++ ++ cs_dsp_info(dsp, "Firmware: %x vendor: 0x%x v%d.%d.%d, %d algorithms\n", ++ dsp->fw_id, dsp->fw_vendor_id, ++ (dsp->fw_id_version & 0xff0000) >> 16, ++ (dsp->fw_id_version & 0xff00) >> 8, dsp->fw_id_version & 0xff, ++ nalgs); ++} ++ ++static int cs_dsp_create_regions(struct cs_dsp *dsp, __be32 id, int nregions, ++ const int *type, __be32 *base) ++{ ++ struct cs_dsp_alg_region *alg_region; ++ int i; ++ ++ for (i = 0; i < nregions; i++) { ++ alg_region = cs_dsp_create_region(dsp, type[i], id, base[i]); ++ if (IS_ERR(alg_region)) ++ return PTR_ERR(alg_region); ++ } ++ ++ return 0; ++} ++ ++static int cs_dsp_adsp1_setup_algs(struct cs_dsp *dsp) ++{ ++ struct wmfw_adsp1_id_hdr adsp1_id; ++ struct wmfw_adsp1_alg_hdr *adsp1_alg; ++ struct cs_dsp_alg_region *alg_region; ++ const struct cs_dsp_region *mem; ++ unsigned int pos, len; ++ size_t n_algs; ++ int i, ret; ++ ++ mem = cs_dsp_find_region(dsp, WMFW_ADSP1_DM); ++ if (WARN_ON(!mem)) ++ return -EINVAL; ++ ++ ret = regmap_raw_read(dsp->regmap, mem->base, &adsp1_id, ++ sizeof(adsp1_id)); ++ if (ret != 0) { ++ cs_dsp_err(dsp, "Failed to read algorithm info: %d\n", ++ ret); ++ return ret; ++ } ++ ++ n_algs = be32_to_cpu(adsp1_id.n_algs); ++ ++ cs_dsp_parse_wmfw_id_header(dsp, &adsp1_id.fw, n_algs); ++ ++ alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_ZM, ++ adsp1_id.fw.id, adsp1_id.zm); ++ if (IS_ERR(alg_region)) ++ return PTR_ERR(alg_region); ++ ++ alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_DM, ++ adsp1_id.fw.id, adsp1_id.dm); ++ if (IS_ERR(alg_region)) ++ return PTR_ERR(alg_region); ++ ++ /* Calculate offset and length in DSP words */ ++ pos = sizeof(adsp1_id) / sizeof(u32); ++ len = (sizeof(*adsp1_alg) * n_algs) / sizeof(u32); ++ ++ adsp1_alg = cs_dsp_read_algs(dsp, n_algs, mem, pos, len); ++ if (IS_ERR(adsp1_alg)) ++ return PTR_ERR(adsp1_alg); ++ ++ for (i = 0; i < n_algs; i++) { ++ cs_dsp_info(dsp, "%d: ID %x v%d.%d.%d DM@%x ZM@%x\n", ++ i, be32_to_cpu(adsp1_alg[i].alg.id), ++ (be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff0000) >> 16, ++ (be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff00) >> 8, ++ be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff, ++ be32_to_cpu(adsp1_alg[i].dm), ++ be32_to_cpu(adsp1_alg[i].zm)); ++ ++ alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_DM, ++ adsp1_alg[i].alg.id, ++ adsp1_alg[i].dm); ++ if (IS_ERR(alg_region)) { ++ ret = PTR_ERR(alg_region); ++ goto out; ++ } ++ if (dsp->fw_ver == 0) { ++ if (i + 1 < n_algs) { ++ len = be32_to_cpu(adsp1_alg[i + 1].dm); ++ len -= be32_to_cpu(adsp1_alg[i].dm); ++ len *= 4; ++ cs_dsp_create_control(dsp, alg_region, 0, ++ len, NULL, 0, 0, ++ WMFW_CTL_TYPE_BYTES); ++ } else { ++ cs_dsp_warn(dsp, "Missing length info for region DM with ID %x\n", ++ be32_to_cpu(adsp1_alg[i].alg.id)); ++ } ++ } ++ ++ alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_ZM, ++ adsp1_alg[i].alg.id, ++ adsp1_alg[i].zm); ++ if (IS_ERR(alg_region)) { ++ ret = PTR_ERR(alg_region); ++ goto out; ++ } ++ if (dsp->fw_ver == 0) { ++ if (i + 1 < n_algs) { ++ len = be32_to_cpu(adsp1_alg[i + 1].zm); ++ len -= be32_to_cpu(adsp1_alg[i].zm); ++ len *= 4; ++ cs_dsp_create_control(dsp, alg_region, 0, ++ len, NULL, 0, 0, ++ WMFW_CTL_TYPE_BYTES); ++ } else { ++ cs_dsp_warn(dsp, "Missing length info for region ZM with ID %x\n", ++ be32_to_cpu(adsp1_alg[i].alg.id)); ++ } ++ } ++ } ++ ++out: ++ kfree(adsp1_alg); ++ return ret; ++} ++ ++static int cs_dsp_adsp2_setup_algs(struct cs_dsp *dsp) ++{ ++ struct wmfw_adsp2_id_hdr adsp2_id; ++ struct wmfw_adsp2_alg_hdr *adsp2_alg; ++ struct cs_dsp_alg_region *alg_region; ++ const struct cs_dsp_region *mem; ++ unsigned int pos, len; ++ size_t n_algs; ++ int i, ret; ++ ++ mem = cs_dsp_find_region(dsp, WMFW_ADSP2_XM); ++ if (WARN_ON(!mem)) ++ return -EINVAL; ++ ++ ret = regmap_raw_read(dsp->regmap, mem->base, &adsp2_id, ++ sizeof(adsp2_id)); ++ if (ret != 0) { ++ cs_dsp_err(dsp, "Failed to read algorithm info: %d\n", ++ ret); ++ return ret; ++ } ++ ++ n_algs = be32_to_cpu(adsp2_id.n_algs); ++ ++ cs_dsp_parse_wmfw_id_header(dsp, &adsp2_id.fw, n_algs); ++ ++ alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_XM, ++ adsp2_id.fw.id, adsp2_id.xm); ++ if (IS_ERR(alg_region)) ++ return PTR_ERR(alg_region); ++ ++ alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_YM, ++ adsp2_id.fw.id, adsp2_id.ym); ++ if (IS_ERR(alg_region)) ++ return PTR_ERR(alg_region); ++ ++ alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_ZM, ++ adsp2_id.fw.id, adsp2_id.zm); ++ if (IS_ERR(alg_region)) ++ return PTR_ERR(alg_region); ++ ++ /* Calculate offset and length in DSP words */ ++ pos = sizeof(adsp2_id) / sizeof(u32); ++ len = (sizeof(*adsp2_alg) * n_algs) / sizeof(u32); ++ ++ adsp2_alg = cs_dsp_read_algs(dsp, n_algs, mem, pos, len); ++ if (IS_ERR(adsp2_alg)) ++ return PTR_ERR(adsp2_alg); ++ ++ for (i = 0; i < n_algs; i++) { ++ cs_dsp_info(dsp, ++ "%d: ID %x v%d.%d.%d XM@%x YM@%x ZM@%x\n", ++ i, be32_to_cpu(adsp2_alg[i].alg.id), ++ (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff0000) >> 16, ++ (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff00) >> 8, ++ be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff, ++ be32_to_cpu(adsp2_alg[i].xm), ++ be32_to_cpu(adsp2_alg[i].ym), ++ be32_to_cpu(adsp2_alg[i].zm)); ++ ++ alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_XM, ++ adsp2_alg[i].alg.id, ++ adsp2_alg[i].xm); ++ if (IS_ERR(alg_region)) { ++ ret = PTR_ERR(alg_region); ++ goto out; ++ } ++ if (dsp->fw_ver == 0) { ++ if (i + 1 < n_algs) { ++ len = be32_to_cpu(adsp2_alg[i + 1].xm); ++ len -= be32_to_cpu(adsp2_alg[i].xm); ++ len *= 4; ++ cs_dsp_create_control(dsp, alg_region, 0, ++ len, NULL, 0, 0, ++ WMFW_CTL_TYPE_BYTES); ++ } else { ++ cs_dsp_warn(dsp, "Missing length info for region XM with ID %x\n", ++ be32_to_cpu(adsp2_alg[i].alg.id)); ++ } ++ } ++ ++ alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_YM, ++ adsp2_alg[i].alg.id, ++ adsp2_alg[i].ym); ++ if (IS_ERR(alg_region)) { ++ ret = PTR_ERR(alg_region); ++ goto out; ++ } ++ if (dsp->fw_ver == 0) { ++ if (i + 1 < n_algs) { ++ len = be32_to_cpu(adsp2_alg[i + 1].ym); ++ len -= be32_to_cpu(adsp2_alg[i].ym); ++ len *= 4; ++ cs_dsp_create_control(dsp, alg_region, 0, ++ len, NULL, 0, 0, ++ WMFW_CTL_TYPE_BYTES); ++ } else { ++ cs_dsp_warn(dsp, "Missing length info for region YM with ID %x\n", ++ be32_to_cpu(adsp2_alg[i].alg.id)); ++ } ++ } ++ ++ alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_ZM, ++ adsp2_alg[i].alg.id, ++ adsp2_alg[i].zm); ++ if (IS_ERR(alg_region)) { ++ ret = PTR_ERR(alg_region); ++ goto out; ++ } ++ if (dsp->fw_ver == 0) { ++ if (i + 1 < n_algs) { ++ len = be32_to_cpu(adsp2_alg[i + 1].zm); ++ len -= be32_to_cpu(adsp2_alg[i].zm); ++ len *= 4; ++ cs_dsp_create_control(dsp, alg_region, 0, ++ len, NULL, 0, 0, ++ WMFW_CTL_TYPE_BYTES); ++ } else { ++ cs_dsp_warn(dsp, "Missing length info for region ZM with ID %x\n", ++ be32_to_cpu(adsp2_alg[i].alg.id)); ++ } ++ } ++ } ++ ++out: ++ kfree(adsp2_alg); ++ return ret; ++} ++ ++static int cs_dsp_halo_create_regions(struct cs_dsp *dsp, __be32 id, ++ __be32 xm_base, __be32 ym_base) ++{ ++ static const int types[] = { ++ WMFW_ADSP2_XM, WMFW_HALO_XM_PACKED, ++ WMFW_ADSP2_YM, WMFW_HALO_YM_PACKED ++ }; ++ __be32 bases[] = { xm_base, xm_base, ym_base, ym_base }; ++ ++ return cs_dsp_create_regions(dsp, id, ARRAY_SIZE(types), types, bases); ++} ++ ++static int cs_dsp_halo_setup_algs(struct cs_dsp *dsp) ++{ ++ struct wmfw_halo_id_hdr halo_id; ++ struct wmfw_halo_alg_hdr *halo_alg; ++ const struct cs_dsp_region *mem; ++ unsigned int pos, len; ++ size_t n_algs; ++ int i, ret; ++ ++ mem = cs_dsp_find_region(dsp, WMFW_ADSP2_XM); ++ if (WARN_ON(!mem)) ++ return -EINVAL; ++ ++ ret = regmap_raw_read(dsp->regmap, mem->base, &halo_id, ++ sizeof(halo_id)); ++ if (ret != 0) { ++ cs_dsp_err(dsp, "Failed to read algorithm info: %d\n", ++ ret); ++ return ret; ++ } ++ ++ n_algs = be32_to_cpu(halo_id.n_algs); ++ ++ cs_dsp_parse_wmfw_v3_id_header(dsp, &halo_id.fw, n_algs); ++ ++ ret = cs_dsp_halo_create_regions(dsp, halo_id.fw.id, ++ halo_id.xm_base, halo_id.ym_base); ++ if (ret) ++ return ret; ++ ++ /* Calculate offset and length in DSP words */ ++ pos = sizeof(halo_id) / sizeof(u32); ++ len = (sizeof(*halo_alg) * n_algs) / sizeof(u32); ++ ++ halo_alg = cs_dsp_read_algs(dsp, n_algs, mem, pos, len); ++ if (IS_ERR(halo_alg)) ++ return PTR_ERR(halo_alg); ++ ++ for (i = 0; i < n_algs; i++) { ++ cs_dsp_info(dsp, ++ "%d: ID %x v%d.%d.%d XM@%x YM@%x\n", ++ i, be32_to_cpu(halo_alg[i].alg.id), ++ (be32_to_cpu(halo_alg[i].alg.ver) & 0xff0000) >> 16, ++ (be32_to_cpu(halo_alg[i].alg.ver) & 0xff00) >> 8, ++ be32_to_cpu(halo_alg[i].alg.ver) & 0xff, ++ be32_to_cpu(halo_alg[i].xm_base), ++ be32_to_cpu(halo_alg[i].ym_base)); ++ ++ ret = cs_dsp_halo_create_regions(dsp, halo_alg[i].alg.id, ++ halo_alg[i].xm_base, ++ halo_alg[i].ym_base); ++ if (ret) ++ goto out; ++ } ++ ++out: ++ kfree(halo_alg); ++ return ret; ++} ++ ++static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware, ++ const char *file) ++{ ++ LIST_HEAD(buf_list); ++ struct regmap *regmap = dsp->regmap; ++ struct wmfw_coeff_hdr *hdr; ++ struct wmfw_coeff_item *blk; ++ const struct cs_dsp_region *mem; ++ struct cs_dsp_alg_region *alg_region; ++ const char *region_name; ++ int ret, pos, blocks, type, offset, reg; ++ struct cs_dsp_buf *buf; ++ ++ if (!firmware) ++ return 0; ++ ++ ret = -EINVAL; ++ ++ if (sizeof(*hdr) >= firmware->size) { ++ cs_dsp_err(dsp, "%s: coefficient file too short, %zu bytes\n", ++ file, firmware->size); ++ goto out_fw; ++ } ++ ++ hdr = (void *)&firmware->data[0]; ++ if (memcmp(hdr->magic, "WMDR", 4) != 0) { ++ cs_dsp_err(dsp, "%s: invalid coefficient magic\n", file); ++ goto out_fw; ++ } ++ ++ switch (be32_to_cpu(hdr->rev) & 0xff) { ++ case 1: ++ break; ++ default: ++ cs_dsp_err(dsp, "%s: Unsupported coefficient file format %d\n", ++ file, be32_to_cpu(hdr->rev) & 0xff); ++ ret = -EINVAL; ++ goto out_fw; ++ } ++ ++ cs_dsp_dbg(dsp, "%s: v%d.%d.%d\n", file, ++ (le32_to_cpu(hdr->ver) >> 16) & 0xff, ++ (le32_to_cpu(hdr->ver) >> 8) & 0xff, ++ le32_to_cpu(hdr->ver) & 0xff); ++ ++ pos = le32_to_cpu(hdr->len); ++ ++ blocks = 0; ++ while (pos < firmware->size && ++ sizeof(*blk) < firmware->size - pos) { ++ blk = (void *)(&firmware->data[pos]); ++ ++ type = le16_to_cpu(blk->type); ++ offset = le16_to_cpu(blk->offset); ++ ++ cs_dsp_dbg(dsp, "%s.%d: %x v%d.%d.%d\n", ++ file, blocks, le32_to_cpu(blk->id), ++ (le32_to_cpu(blk->ver) >> 16) & 0xff, ++ (le32_to_cpu(blk->ver) >> 8) & 0xff, ++ le32_to_cpu(blk->ver) & 0xff); ++ cs_dsp_dbg(dsp, "%s.%d: %d bytes at 0x%x in %x\n", ++ file, blocks, le32_to_cpu(blk->len), offset, type); ++ ++ reg = 0; ++ region_name = "Unknown"; ++ switch (type) { ++ case (WMFW_NAME_TEXT << 8): ++ case (WMFW_INFO_TEXT << 8): ++ case (WMFW_METADATA << 8): ++ break; ++ case (WMFW_ABSOLUTE << 8): ++ /* ++ * Old files may use this for global ++ * coefficients. ++ */ ++ if (le32_to_cpu(blk->id) == dsp->fw_id && ++ offset == 0) { ++ region_name = "global coefficients"; ++ mem = cs_dsp_find_region(dsp, type); ++ if (!mem) { ++ cs_dsp_err(dsp, "No ZM\n"); ++ break; ++ } ++ reg = dsp->ops->region_to_reg(mem, 0); ++ ++ } else { ++ region_name = "register"; ++ reg = offset; ++ } ++ break; ++ ++ case WMFW_ADSP1_DM: ++ case WMFW_ADSP1_ZM: ++ case WMFW_ADSP2_XM: ++ case WMFW_ADSP2_YM: ++ case WMFW_HALO_XM_PACKED: ++ case WMFW_HALO_YM_PACKED: ++ case WMFW_HALO_PM_PACKED: ++ cs_dsp_dbg(dsp, "%s.%d: %d bytes in %x for %x\n", ++ file, blocks, le32_to_cpu(blk->len), ++ type, le32_to_cpu(blk->id)); ++ ++ mem = cs_dsp_find_region(dsp, type); ++ if (!mem) { ++ cs_dsp_err(dsp, "No base for region %x\n", type); ++ break; ++ } ++ ++ alg_region = cs_dsp_find_alg_region(dsp, type, ++ le32_to_cpu(blk->id)); ++ if (alg_region) { ++ reg = alg_region->base; ++ reg = dsp->ops->region_to_reg(mem, reg); ++ reg += offset; ++ } else { ++ cs_dsp_err(dsp, "No %x for algorithm %x\n", ++ type, le32_to_cpu(blk->id)); ++ } ++ break; ++ ++ default: ++ cs_dsp_err(dsp, "%s.%d: Unknown region type %x at %d\n", ++ file, blocks, type, pos); ++ break; ++ } ++ ++ if (reg) { ++ if (le32_to_cpu(blk->len) > ++ firmware->size - pos - sizeof(*blk)) { ++ cs_dsp_err(dsp, ++ "%s.%d: %s region len %d bytes exceeds file length %zu\n", ++ file, blocks, region_name, ++ le32_to_cpu(blk->len), ++ firmware->size); ++ ret = -EINVAL; ++ goto out_fw; ++ } ++ ++ buf = cs_dsp_buf_alloc(blk->data, ++ le32_to_cpu(blk->len), ++ &buf_list); ++ if (!buf) { ++ cs_dsp_err(dsp, "Out of memory\n"); ++ ret = -ENOMEM; ++ goto out_fw; ++ } ++ ++ cs_dsp_dbg(dsp, "%s.%d: Writing %d bytes at %x\n", ++ file, blocks, le32_to_cpu(blk->len), ++ reg); ++ ret = regmap_raw_write_async(regmap, reg, buf->buf, ++ le32_to_cpu(blk->len)); ++ if (ret != 0) { ++ cs_dsp_err(dsp, ++ "%s.%d: Failed to write to %x in %s: %d\n", ++ file, blocks, reg, region_name, ret); ++ } ++ } ++ ++ pos += (le32_to_cpu(blk->len) + sizeof(*blk) + 3) & ~0x03; ++ blocks++; ++ } ++ ++ ret = regmap_async_complete(regmap); ++ if (ret != 0) ++ cs_dsp_err(dsp, "Failed to complete async write: %d\n", ret); ++ ++ if (pos > firmware->size) ++ cs_dsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", ++ file, blocks, pos - firmware->size); ++ ++ cs_dsp_debugfs_save_binname(dsp, file); ++ ++out_fw: ++ regmap_async_complete(regmap); ++ cs_dsp_buf_free(&buf_list); ++ return ret; ++} ++ ++static int cs_dsp_create_name(struct cs_dsp *dsp) ++{ ++ if (!dsp->name) { ++ dsp->name = devm_kasprintf(dsp->dev, GFP_KERNEL, "DSP%d", ++ dsp->num); ++ if (!dsp->name) ++ return -ENOMEM; ++ } ++ ++ return 0; ++} ++ ++static int cs_dsp_common_init(struct cs_dsp *dsp) ++{ ++ int ret; ++ ++ ret = cs_dsp_create_name(dsp); ++ if (ret) ++ return ret; ++ ++ INIT_LIST_HEAD(&dsp->alg_regions); ++ INIT_LIST_HEAD(&dsp->ctl_list); ++ ++ mutex_init(&dsp->pwr_lock); ++ ++ return 0; ++} ++ ++/** ++ * cs_dsp_adsp1_init() - Initialise a cs_dsp structure representing a ADSP1 device ++ * @dsp: pointer to DSP structure ++ * ++ * Return: Zero for success, a negative number on error. ++ */ ++int cs_dsp_adsp1_init(struct cs_dsp *dsp) ++{ ++ dsp->ops = &cs_dsp_adsp1_ops; ++ ++ return cs_dsp_common_init(dsp); ++} ++EXPORT_SYMBOL_GPL(cs_dsp_adsp1_init); ++ ++/** ++ * cs_dsp_adsp1_power_up() - Load and start the named firmware ++ * @dsp: pointer to DSP structure ++ * @wmfw_firmware: the firmware to be sent ++ * @wmfw_filename: file name of firmware to be sent ++ * @coeff_firmware: the coefficient data to be sent ++ * @coeff_filename: file name of coefficient to data be sent ++ * @fw_name: the user-friendly firmware name ++ * ++ * Return: Zero for success, a negative number on error. ++ */ ++int cs_dsp_adsp1_power_up(struct cs_dsp *dsp, ++ const struct firmware *wmfw_firmware, char *wmfw_filename, ++ const struct firmware *coeff_firmware, char *coeff_filename, ++ const char *fw_name) ++{ ++ unsigned int val; ++ int ret; ++ ++ mutex_lock(&dsp->pwr_lock); ++ ++ dsp->fw_name = fw_name; ++ ++ regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, ++ ADSP1_SYS_ENA, ADSP1_SYS_ENA); ++ ++ /* ++ * For simplicity set the DSP clock rate to be the ++ * SYSCLK rate rather than making it configurable. ++ */ ++ if (dsp->sysclk_reg) { ++ ret = regmap_read(dsp->regmap, dsp->sysclk_reg, &val); ++ if (ret != 0) { ++ cs_dsp_err(dsp, "Failed to read SYSCLK state: %d\n", ret); ++ goto err_mutex; ++ } ++ ++ val = (val & dsp->sysclk_mask) >> dsp->sysclk_shift; ++ ++ ret = regmap_update_bits(dsp->regmap, ++ dsp->base + ADSP1_CONTROL_31, ++ ADSP1_CLK_SEL_MASK, val); ++ if (ret != 0) { ++ cs_dsp_err(dsp, "Failed to set clock rate: %d\n", ret); ++ goto err_mutex; ++ } ++ } ++ ++ ret = cs_dsp_load(dsp, wmfw_firmware, wmfw_filename); ++ if (ret != 0) ++ goto err_ena; ++ ++ ret = cs_dsp_adsp1_setup_algs(dsp); ++ if (ret != 0) ++ goto err_ena; ++ ++ ret = cs_dsp_load_coeff(dsp, coeff_firmware, coeff_filename); ++ if (ret != 0) ++ goto err_ena; ++ ++ /* Initialize caches for enabled and unset controls */ ++ ret = cs_dsp_coeff_init_control_caches(dsp); ++ if (ret != 0) ++ goto err_ena; ++ ++ /* Sync set controls */ ++ ret = cs_dsp_coeff_sync_controls(dsp); ++ if (ret != 0) ++ goto err_ena; ++ ++ dsp->booted = true; ++ ++ /* Start the core running */ ++ regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, ++ ADSP1_CORE_ENA | ADSP1_START, ++ ADSP1_CORE_ENA | ADSP1_START); ++ ++ dsp->running = true; ++ ++ mutex_unlock(&dsp->pwr_lock); ++ ++ return 0; ++ ++err_ena: ++ regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, ++ ADSP1_SYS_ENA, 0); ++err_mutex: ++ mutex_unlock(&dsp->pwr_lock); ++ return ret; ++} ++EXPORT_SYMBOL_GPL(cs_dsp_adsp1_power_up); ++ ++/** ++ * cs_dsp_adsp1_power_down() - Halts the DSP ++ * @dsp: pointer to DSP structure ++ */ ++void cs_dsp_adsp1_power_down(struct cs_dsp *dsp) ++{ ++ struct cs_dsp_coeff_ctl *ctl; ++ ++ mutex_lock(&dsp->pwr_lock); ++ ++ dsp->running = false; ++ dsp->booted = false; ++ ++ /* Halt the core */ ++ regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, ++ ADSP1_CORE_ENA | ADSP1_START, 0); ++ ++ regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_19, ++ ADSP1_WDMA_BUFFER_LENGTH_MASK, 0); ++ ++ regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, ++ ADSP1_SYS_ENA, 0); ++ ++ list_for_each_entry(ctl, &dsp->ctl_list, list) ++ ctl->enabled = 0; ++ ++ cs_dsp_free_alg_regions(dsp); ++ ++ mutex_unlock(&dsp->pwr_lock); ++} ++EXPORT_SYMBOL_GPL(cs_dsp_adsp1_power_down); ++ ++static int cs_dsp_adsp2v2_enable_core(struct cs_dsp *dsp) ++{ ++ unsigned int val; ++ int ret, count; ++ ++ /* Wait for the RAM to start, should be near instantaneous */ ++ for (count = 0; count < 10; ++count) { ++ ret = regmap_read(dsp->regmap, dsp->base + ADSP2_STATUS1, &val); ++ if (ret != 0) ++ return ret; ++ ++ if (val & ADSP2_RAM_RDY) ++ break; ++ ++ usleep_range(250, 500); ++ } ++ ++ if (!(val & ADSP2_RAM_RDY)) { ++ cs_dsp_err(dsp, "Failed to start DSP RAM\n"); ++ return -EBUSY; ++ } ++ ++ cs_dsp_dbg(dsp, "RAM ready after %d polls\n", count); ++ ++ return 0; ++} ++ ++static int cs_dsp_adsp2_enable_core(struct cs_dsp *dsp) ++{ ++ int ret; ++ ++ ret = regmap_update_bits_async(dsp->regmap, dsp->base + ADSP2_CONTROL, ++ ADSP2_SYS_ENA, ADSP2_SYS_ENA); ++ if (ret != 0) ++ return ret; ++ ++ return cs_dsp_adsp2v2_enable_core(dsp); ++} ++ ++static int cs_dsp_adsp2_lock(struct cs_dsp *dsp, unsigned int lock_regions) ++{ ++ struct regmap *regmap = dsp->regmap; ++ unsigned int code0, code1, lock_reg; ++ ++ if (!(lock_regions & CS_ADSP2_REGION_ALL)) ++ return 0; ++ ++ lock_regions &= CS_ADSP2_REGION_ALL; ++ lock_reg = dsp->base + ADSP2_LOCK_REGION_1_LOCK_REGION_0; ++ ++ while (lock_regions) { ++ code0 = code1 = 0; ++ if (lock_regions & BIT(0)) { ++ code0 = ADSP2_LOCK_CODE_0; ++ code1 = ADSP2_LOCK_CODE_1; ++ } ++ if (lock_regions & BIT(1)) { ++ code0 |= ADSP2_LOCK_CODE_0 << ADSP2_LOCK_REGION_SHIFT; ++ code1 |= ADSP2_LOCK_CODE_1 << ADSP2_LOCK_REGION_SHIFT; ++ } ++ regmap_write(regmap, lock_reg, code0); ++ regmap_write(regmap, lock_reg, code1); ++ lock_regions >>= 2; ++ lock_reg += 2; ++ } ++ ++ return 0; ++} ++ ++static int cs_dsp_adsp2_enable_memory(struct cs_dsp *dsp) ++{ ++ return regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, ++ ADSP2_MEM_ENA, ADSP2_MEM_ENA); ++} ++ ++static void cs_dsp_adsp2_disable_memory(struct cs_dsp *dsp) ++{ ++ regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, ++ ADSP2_MEM_ENA, 0); ++} ++ ++static void cs_dsp_adsp2_disable_core(struct cs_dsp *dsp) ++{ ++ regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0); ++ regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0); ++ regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_2, 0); ++ ++ regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, ++ ADSP2_SYS_ENA, 0); ++} ++ ++static void cs_dsp_adsp2v2_disable_core(struct cs_dsp *dsp) ++{ ++ regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0); ++ regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0); ++ regmap_write(dsp->regmap, dsp->base + ADSP2V2_WDMA_CONFIG_2, 0); ++} ++ ++static int cs_dsp_halo_configure_mpu(struct cs_dsp *dsp, unsigned int lock_regions) ++{ ++ struct reg_sequence config[] = { ++ { dsp->base + HALO_MPU_LOCK_CONFIG, 0x5555 }, ++ { dsp->base + HALO_MPU_LOCK_CONFIG, 0xAAAA }, ++ { dsp->base + HALO_MPU_XMEM_ACCESS_0, 0xFFFFFFFF }, ++ { dsp->base + HALO_MPU_YMEM_ACCESS_0, 0xFFFFFFFF }, ++ { dsp->base + HALO_MPU_WINDOW_ACCESS_0, lock_regions }, ++ { dsp->base + HALO_MPU_XREG_ACCESS_0, lock_regions }, ++ { dsp->base + HALO_MPU_YREG_ACCESS_0, lock_regions }, ++ { dsp->base + HALO_MPU_XMEM_ACCESS_1, 0xFFFFFFFF }, ++ { dsp->base + HALO_MPU_YMEM_ACCESS_1, 0xFFFFFFFF }, ++ { dsp->base + HALO_MPU_WINDOW_ACCESS_1, lock_regions }, ++ { dsp->base + HALO_MPU_XREG_ACCESS_1, lock_regions }, ++ { dsp->base + HALO_MPU_YREG_ACCESS_1, lock_regions }, ++ { dsp->base + HALO_MPU_XMEM_ACCESS_2, 0xFFFFFFFF }, ++ { dsp->base + HALO_MPU_YMEM_ACCESS_2, 0xFFFFFFFF }, ++ { dsp->base + HALO_MPU_WINDOW_ACCESS_2, lock_regions }, ++ { dsp->base + HALO_MPU_XREG_ACCESS_2, lock_regions }, ++ { dsp->base + HALO_MPU_YREG_ACCESS_2, lock_regions }, ++ { dsp->base + HALO_MPU_XMEM_ACCESS_3, 0xFFFFFFFF }, ++ { dsp->base + HALO_MPU_YMEM_ACCESS_3, 0xFFFFFFFF }, ++ { dsp->base + HALO_MPU_WINDOW_ACCESS_3, lock_regions }, ++ { dsp->base + HALO_MPU_XREG_ACCESS_3, lock_regions }, ++ { dsp->base + HALO_MPU_YREG_ACCESS_3, lock_regions }, ++ { dsp->base + HALO_MPU_LOCK_CONFIG, 0 }, ++ }; ++ ++ return regmap_multi_reg_write(dsp->regmap, config, ARRAY_SIZE(config)); ++} ++ ++/** ++ * cs_dsp_set_dspclk() - Applies the given frequency to the given cs_dsp ++ * @dsp: pointer to DSP structure ++ * @freq: clock rate to set ++ * ++ * This is only for use on ADSP2 cores. ++ * ++ * Return: Zero for success, a negative number on error. ++ */ ++int cs_dsp_set_dspclk(struct cs_dsp *dsp, unsigned int freq) ++{ ++ int ret; ++ ++ ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CLOCKING, ++ ADSP2_CLK_SEL_MASK, ++ freq << ADSP2_CLK_SEL_SHIFT); ++ if (ret) ++ cs_dsp_err(dsp, "Failed to set clock rate: %d\n", ret); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(cs_dsp_set_dspclk); ++ ++static void cs_dsp_stop_watchdog(struct cs_dsp *dsp) ++{ ++ regmap_update_bits(dsp->regmap, dsp->base + ADSP2_WATCHDOG, ++ ADSP2_WDT_ENA_MASK, 0); ++} ++ ++static void cs_dsp_halo_stop_watchdog(struct cs_dsp *dsp) ++{ ++ regmap_update_bits(dsp->regmap, dsp->base + HALO_WDT_CONTROL, ++ HALO_WDT_EN_MASK, 0); ++} ++ ++/** ++ * cs_dsp_power_up() - Downloads firmware to the DSP ++ * @dsp: pointer to DSP structure ++ * @wmfw_firmware: the firmware to be sent ++ * @wmfw_filename: file name of firmware to be sent ++ * @coeff_firmware: the coefficient data to be sent ++ * @coeff_filename: file name of coefficient to data be sent ++ * @fw_name: the user-friendly firmware name ++ * ++ * This function is used on ADSP2 and Halo DSP cores, it powers-up the DSP core ++ * and downloads the firmware but does not start the firmware running. The ++ * cs_dsp booted flag will be set once completed and if the core has a low-power ++ * memory retention mode it will be put into this state after the firmware is ++ * downloaded. ++ * ++ * Return: Zero for success, a negative number on error. ++ */ ++int cs_dsp_power_up(struct cs_dsp *dsp, ++ const struct firmware *wmfw_firmware, char *wmfw_filename, ++ const struct firmware *coeff_firmware, char *coeff_filename, ++ const char *fw_name) ++{ ++ int ret; ++ ++ mutex_lock(&dsp->pwr_lock); ++ ++ dsp->fw_name = fw_name; ++ ++ if (dsp->ops->enable_memory) { ++ ret = dsp->ops->enable_memory(dsp); ++ if (ret != 0) ++ goto err_mutex; ++ } ++ ++ if (dsp->ops->enable_core) { ++ ret = dsp->ops->enable_core(dsp); ++ if (ret != 0) ++ goto err_mem; ++ } ++ ++ ret = cs_dsp_load(dsp, wmfw_firmware, wmfw_filename); ++ if (ret != 0) ++ goto err_ena; ++ ++ ret = dsp->ops->setup_algs(dsp); ++ if (ret != 0) ++ goto err_ena; ++ ++ ret = cs_dsp_load_coeff(dsp, coeff_firmware, coeff_filename); ++ if (ret != 0) ++ goto err_ena; ++ ++ /* Initialize caches for enabled and unset controls */ ++ ret = cs_dsp_coeff_init_control_caches(dsp); ++ if (ret != 0) ++ goto err_ena; ++ ++ if (dsp->ops->disable_core) ++ dsp->ops->disable_core(dsp); ++ ++ dsp->booted = true; ++ ++ mutex_unlock(&dsp->pwr_lock); ++ ++ return 0; ++err_ena: ++ if (dsp->ops->disable_core) ++ dsp->ops->disable_core(dsp); ++err_mem: ++ if (dsp->ops->disable_memory) ++ dsp->ops->disable_memory(dsp); ++err_mutex: ++ mutex_unlock(&dsp->pwr_lock); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(cs_dsp_power_up); ++ ++/** ++ * cs_dsp_power_down() - Powers-down the DSP ++ * @dsp: pointer to DSP structure ++ * ++ * cs_dsp_stop() must have been called before this function. The core will be ++ * fully powered down and so the memory will not be retained. ++ */ ++void cs_dsp_power_down(struct cs_dsp *dsp) ++{ ++ struct cs_dsp_coeff_ctl *ctl; ++ ++ mutex_lock(&dsp->pwr_lock); ++ ++ cs_dsp_debugfs_clear(dsp); ++ ++ dsp->fw_id = 0; ++ dsp->fw_id_version = 0; ++ ++ dsp->booted = false; ++ ++ if (dsp->ops->disable_memory) ++ dsp->ops->disable_memory(dsp); ++ ++ list_for_each_entry(ctl, &dsp->ctl_list, list) ++ ctl->enabled = 0; ++ ++ cs_dsp_free_alg_regions(dsp); ++ ++ mutex_unlock(&dsp->pwr_lock); ++ ++ cs_dsp_dbg(dsp, "Shutdown complete\n"); ++} ++EXPORT_SYMBOL_GPL(cs_dsp_power_down); ++ ++static int cs_dsp_adsp2_start_core(struct cs_dsp *dsp) ++{ ++ return regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, ++ ADSP2_CORE_ENA | ADSP2_START, ++ ADSP2_CORE_ENA | ADSP2_START); ++} ++ ++static void cs_dsp_adsp2_stop_core(struct cs_dsp *dsp) ++{ ++ regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, ++ ADSP2_CORE_ENA | ADSP2_START, 0); ++} ++ ++/** ++ * cs_dsp_run() - Starts the firmware running ++ * @dsp: pointer to DSP structure ++ * ++ * cs_dsp_power_up() must have previously been called successfully. ++ * ++ * Return: Zero for success, a negative number on error. ++ */ ++int cs_dsp_run(struct cs_dsp *dsp) ++{ ++ int ret; ++ ++ mutex_lock(&dsp->pwr_lock); ++ ++ if (!dsp->booted) { ++ ret = -EIO; ++ goto err; ++ } ++ ++ if (dsp->ops->enable_core) { ++ ret = dsp->ops->enable_core(dsp); ++ if (ret != 0) ++ goto err; ++ } ++ ++ /* Sync set controls */ ++ ret = cs_dsp_coeff_sync_controls(dsp); ++ if (ret != 0) ++ goto err; ++ ++ if (dsp->ops->lock_memory) { ++ ret = dsp->ops->lock_memory(dsp, dsp->lock_regions); ++ if (ret != 0) { ++ cs_dsp_err(dsp, "Error configuring MPU: %d\n", ret); ++ goto err; ++ } ++ } ++ ++ if (dsp->ops->start_core) { ++ ret = dsp->ops->start_core(dsp); ++ if (ret != 0) ++ goto err; ++ } ++ ++ dsp->running = true; ++ ++ if (dsp->client_ops->post_run) { ++ ret = dsp->client_ops->post_run(dsp); ++ if (ret) ++ goto err; ++ } ++ ++ mutex_unlock(&dsp->pwr_lock); ++ ++ return 0; ++ ++err: ++ if (dsp->ops->stop_core) ++ dsp->ops->stop_core(dsp); ++ if (dsp->ops->disable_core) ++ dsp->ops->disable_core(dsp); ++ mutex_unlock(&dsp->pwr_lock); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(cs_dsp_run); ++ ++/** ++ * cs_dsp_stop() - Stops the firmware ++ * @dsp: pointer to DSP structure ++ * ++ * Memory will not be disabled so firmware will remain loaded. ++ */ ++void cs_dsp_stop(struct cs_dsp *dsp) ++{ ++ /* Tell the firmware to cleanup */ ++ cs_dsp_signal_event_controls(dsp, CS_DSP_FW_EVENT_SHUTDOWN); ++ ++ if (dsp->ops->stop_watchdog) ++ dsp->ops->stop_watchdog(dsp); ++ ++ /* Log firmware state, it can be useful for analysis */ ++ if (dsp->ops->show_fw_status) ++ dsp->ops->show_fw_status(dsp); ++ ++ mutex_lock(&dsp->pwr_lock); ++ ++ dsp->running = false; ++ ++ if (dsp->ops->stop_core) ++ dsp->ops->stop_core(dsp); ++ if (dsp->ops->disable_core) ++ dsp->ops->disable_core(dsp); ++ ++ if (dsp->client_ops->post_stop) ++ dsp->client_ops->post_stop(dsp); ++ ++ mutex_unlock(&dsp->pwr_lock); ++ ++ cs_dsp_dbg(dsp, "Execution stopped\n"); ++} ++EXPORT_SYMBOL_GPL(cs_dsp_stop); ++ ++static int cs_dsp_halo_start_core(struct cs_dsp *dsp) ++{ ++ return regmap_update_bits(dsp->regmap, ++ dsp->base + HALO_CCM_CORE_CONTROL, ++ HALO_CORE_RESET | HALO_CORE_EN, ++ HALO_CORE_RESET | HALO_CORE_EN); ++} ++ ++static void cs_dsp_halo_stop_core(struct cs_dsp *dsp) ++{ ++ regmap_update_bits(dsp->regmap, dsp->base + HALO_CCM_CORE_CONTROL, ++ HALO_CORE_EN, 0); ++ ++ /* reset halo core with CORE_SOFT_RESET */ ++ regmap_update_bits(dsp->regmap, dsp->base + HALO_CORE_SOFT_RESET, ++ HALO_CORE_SOFT_RESET_MASK, 1); ++} ++ ++/** ++ * cs_dsp_adsp2_init() - Initialise a cs_dsp structure representing a ADSP2 core ++ * @dsp: pointer to DSP structure ++ * ++ * Return: Zero for success, a negative number on error. ++ */ ++int cs_dsp_adsp2_init(struct cs_dsp *dsp) ++{ ++ int ret; ++ ++ switch (dsp->rev) { ++ case 0: ++ /* ++ * Disable the DSP memory by default when in reset for a small ++ * power saving. ++ */ ++ ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, ++ ADSP2_MEM_ENA, 0); ++ if (ret) { ++ cs_dsp_err(dsp, ++ "Failed to clear memory retention: %d\n", ret); ++ return ret; ++ } ++ ++ dsp->ops = &cs_dsp_adsp2_ops[0]; ++ break; ++ case 1: ++ dsp->ops = &cs_dsp_adsp2_ops[1]; ++ break; ++ default: ++ dsp->ops = &cs_dsp_adsp2_ops[2]; ++ break; ++ } ++ ++ return cs_dsp_common_init(dsp); ++} ++EXPORT_SYMBOL_GPL(cs_dsp_adsp2_init); ++ ++/** ++ * cs_dsp_halo_init() - Initialise a cs_dsp structure representing a HALO Core DSP ++ * @dsp: pointer to DSP structure ++ * ++ * Return: Zero for success, a negative number on error. ++ */ ++int cs_dsp_halo_init(struct cs_dsp *dsp) ++{ ++ dsp->ops = &cs_dsp_halo_ops; ++ ++ return cs_dsp_common_init(dsp); ++} ++EXPORT_SYMBOL_GPL(cs_dsp_halo_init); ++ ++/** ++ * cs_dsp_remove() - Clean a cs_dsp before deletion ++ * @dsp: pointer to DSP structure ++ */ ++void cs_dsp_remove(struct cs_dsp *dsp) ++{ ++ struct cs_dsp_coeff_ctl *ctl; ++ ++ while (!list_empty(&dsp->ctl_list)) { ++ ctl = list_first_entry(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); ++ ++ if (dsp->client_ops->control_remove) ++ dsp->client_ops->control_remove(ctl); ++ ++ list_del(&ctl->list); ++ cs_dsp_free_ctl_blk(ctl); ++ } ++} ++EXPORT_SYMBOL_GPL(cs_dsp_remove); ++ ++/** ++ * cs_dsp_read_raw_data_block() - Reads a block of data from DSP memory ++ * @dsp: pointer to DSP structure ++ * @mem_type: the type of DSP memory containing the data to be read ++ * @mem_addr: the address of the data within the memory region ++ * @num_words: the length of the data to read ++ * @data: a buffer to store the fetched data ++ * ++ * If this is used to read unpacked 24-bit memory, each 24-bit DSP word will ++ * occupy 32-bits in data (MSbyte will be 0). This padding can be removed using ++ * cs_dsp_remove_padding() ++ * ++ * Return: Zero for success, a negative number on error. ++ */ ++int cs_dsp_read_raw_data_block(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, ++ unsigned int num_words, __be32 *data) ++{ ++ struct cs_dsp_region const *mem = cs_dsp_find_region(dsp, mem_type); ++ unsigned int reg; ++ int ret; ++ ++ if (!mem) ++ return -EINVAL; ++ ++ reg = dsp->ops->region_to_reg(mem, mem_addr); ++ ++ ret = regmap_raw_read(dsp->regmap, reg, data, ++ sizeof(*data) * num_words); ++ if (ret < 0) ++ return ret; ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(cs_dsp_read_raw_data_block); ++ ++/** ++ * cs_dsp_read_data_word() - Reads a word from DSP memory ++ * @dsp: pointer to DSP structure ++ * @mem_type: the type of DSP memory containing the data to be read ++ * @mem_addr: the address of the data within the memory region ++ * @data: a buffer to store the fetched data ++ * ++ * Return: Zero for success, a negative number on error. ++ */ ++int cs_dsp_read_data_word(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, u32 *data) ++{ ++ __be32 raw; ++ int ret; ++ ++ ret = cs_dsp_read_raw_data_block(dsp, mem_type, mem_addr, 1, &raw); ++ if (ret < 0) ++ return ret; ++ ++ *data = be32_to_cpu(raw) & 0x00ffffffu; ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(cs_dsp_read_data_word); ++ ++/** ++ * cs_dsp_write_data_word() - Writes a word to DSP memory ++ * @dsp: pointer to DSP structure ++ * @mem_type: the type of DSP memory containing the data to be written ++ * @mem_addr: the address of the data within the memory region ++ * @data: the data to be written ++ * ++ * Return: Zero for success, a negative number on error. ++ */ ++int cs_dsp_write_data_word(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, u32 data) ++{ ++ struct cs_dsp_region const *mem = cs_dsp_find_region(dsp, mem_type); ++ __be32 val = cpu_to_be32(data & 0x00ffffffu); ++ unsigned int reg; ++ ++ if (!mem) ++ return -EINVAL; ++ ++ reg = dsp->ops->region_to_reg(mem, mem_addr); ++ ++ return regmap_raw_write(dsp->regmap, reg, &val, sizeof(val)); ++} ++EXPORT_SYMBOL_GPL(cs_dsp_write_data_word); ++ ++/** ++ * cs_dsp_remove_padding() - Convert unpacked words to packed bytes ++ * @buf: buffer containing DSP words read from DSP memory ++ * @nwords: number of words to convert ++ * ++ * DSP words from the register map have pad bytes and the data bytes ++ * are in swapped order. This swaps to the native endian order and ++ * strips the pad bytes. ++ */ ++void cs_dsp_remove_padding(u32 *buf, int nwords) ++{ ++ const __be32 *pack_in = (__be32 *)buf; ++ u8 *pack_out = (u8 *)buf; ++ int i; ++ ++ for (i = 0; i < nwords; i++) { ++ u32 word = be32_to_cpu(*pack_in++); ++ *pack_out++ = (u8)word; ++ *pack_out++ = (u8)(word >> 8); ++ *pack_out++ = (u8)(word >> 16); ++ } ++} ++EXPORT_SYMBOL_GPL(cs_dsp_remove_padding); ++ ++/** ++ * cs_dsp_adsp2_bus_error() - Handle a DSP bus error interrupt ++ * @dsp: pointer to DSP structure ++ * ++ * The firmware and DSP state will be logged for future analysis. ++ */ ++void cs_dsp_adsp2_bus_error(struct cs_dsp *dsp) ++{ ++ unsigned int val; ++ struct regmap *regmap = dsp->regmap; ++ int ret = 0; ++ ++ mutex_lock(&dsp->pwr_lock); ++ ++ ret = regmap_read(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, &val); ++ if (ret) { ++ cs_dsp_err(dsp, ++ "Failed to read Region Lock Ctrl register: %d\n", ret); ++ goto error; ++ } ++ ++ if (val & ADSP2_WDT_TIMEOUT_STS_MASK) { ++ cs_dsp_err(dsp, "watchdog timeout error\n"); ++ dsp->ops->stop_watchdog(dsp); ++ if (dsp->client_ops->watchdog_expired) ++ dsp->client_ops->watchdog_expired(dsp); ++ } ++ ++ if (val & (ADSP2_ADDR_ERR_MASK | ADSP2_REGION_LOCK_ERR_MASK)) { ++ if (val & ADSP2_ADDR_ERR_MASK) ++ cs_dsp_err(dsp, "bus error: address error\n"); ++ else ++ cs_dsp_err(dsp, "bus error: region lock error\n"); ++ ++ ret = regmap_read(regmap, dsp->base + ADSP2_BUS_ERR_ADDR, &val); ++ if (ret) { ++ cs_dsp_err(dsp, ++ "Failed to read Bus Err Addr register: %d\n", ++ ret); ++ goto error; ++ } ++ ++ cs_dsp_err(dsp, "bus error address = 0x%x\n", ++ val & ADSP2_BUS_ERR_ADDR_MASK); ++ ++ ret = regmap_read(regmap, ++ dsp->base + ADSP2_PMEM_ERR_ADDR_XMEM_ERR_ADDR, ++ &val); ++ if (ret) { ++ cs_dsp_err(dsp, ++ "Failed to read Pmem Xmem Err Addr register: %d\n", ++ ret); ++ goto error; ++ } ++ ++ cs_dsp_err(dsp, "xmem error address = 0x%x\n", ++ val & ADSP2_XMEM_ERR_ADDR_MASK); ++ cs_dsp_err(dsp, "pmem error address = 0x%x\n", ++ (val & ADSP2_PMEM_ERR_ADDR_MASK) >> ++ ADSP2_PMEM_ERR_ADDR_SHIFT); ++ } ++ ++ regmap_update_bits(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, ++ ADSP2_CTRL_ERR_EINT, ADSP2_CTRL_ERR_EINT); ++ ++error: ++ mutex_unlock(&dsp->pwr_lock); ++} ++EXPORT_SYMBOL_GPL(cs_dsp_adsp2_bus_error); ++ ++/** ++ * cs_dsp_halo_bus_error() - Handle a DSP bus error interrupt ++ * @dsp: pointer to DSP structure ++ * ++ * The firmware and DSP state will be logged for future analysis. ++ */ ++void cs_dsp_halo_bus_error(struct cs_dsp *dsp) ++{ ++ struct regmap *regmap = dsp->regmap; ++ unsigned int fault[6]; ++ struct reg_sequence clear[] = { ++ { dsp->base + HALO_MPU_XM_VIO_STATUS, 0x0 }, ++ { dsp->base + HALO_MPU_YM_VIO_STATUS, 0x0 }, ++ { dsp->base + HALO_MPU_PM_VIO_STATUS, 0x0 }, ++ }; ++ int ret; ++ ++ mutex_lock(&dsp->pwr_lock); ++ ++ ret = regmap_read(regmap, dsp->base_sysinfo + HALO_AHBM_WINDOW_DEBUG_1, ++ fault); ++ if (ret) { ++ cs_dsp_warn(dsp, "Failed to read AHB DEBUG_1: %d\n", ret); ++ goto exit_unlock; ++ } ++ ++ cs_dsp_warn(dsp, "AHB: STATUS: 0x%x ADDR: 0x%x\n", ++ *fault & HALO_AHBM_FLAGS_ERR_MASK, ++ (*fault & HALO_AHBM_CORE_ERR_ADDR_MASK) >> ++ HALO_AHBM_CORE_ERR_ADDR_SHIFT); ++ ++ ret = regmap_read(regmap, dsp->base_sysinfo + HALO_AHBM_WINDOW_DEBUG_0, ++ fault); ++ if (ret) { ++ cs_dsp_warn(dsp, "Failed to read AHB DEBUG_0: %d\n", ret); ++ goto exit_unlock; ++ } ++ ++ cs_dsp_warn(dsp, "AHB: SYS_ADDR: 0x%x\n", *fault); ++ ++ ret = regmap_bulk_read(regmap, dsp->base + HALO_MPU_XM_VIO_ADDR, ++ fault, ARRAY_SIZE(fault)); ++ if (ret) { ++ cs_dsp_warn(dsp, "Failed to read MPU fault info: %d\n", ret); ++ goto exit_unlock; ++ } ++ ++ cs_dsp_warn(dsp, "XM: STATUS:0x%x ADDR:0x%x\n", fault[1], fault[0]); ++ cs_dsp_warn(dsp, "YM: STATUS:0x%x ADDR:0x%x\n", fault[3], fault[2]); ++ cs_dsp_warn(dsp, "PM: STATUS:0x%x ADDR:0x%x\n", fault[5], fault[4]); ++ ++ ret = regmap_multi_reg_write(dsp->regmap, clear, ARRAY_SIZE(clear)); ++ if (ret) ++ cs_dsp_warn(dsp, "Failed to clear MPU status: %d\n", ret); ++ ++exit_unlock: ++ mutex_unlock(&dsp->pwr_lock); ++} ++EXPORT_SYMBOL_GPL(cs_dsp_halo_bus_error); ++ ++/** ++ * cs_dsp_halo_wdt_expire() - Handle DSP watchdog expiry ++ * @dsp: pointer to DSP structure ++ * ++ * This is logged for future analysis. ++ */ ++void cs_dsp_halo_wdt_expire(struct cs_dsp *dsp) ++{ ++ mutex_lock(&dsp->pwr_lock); ++ ++ cs_dsp_warn(dsp, "WDT Expiry Fault\n"); ++ ++ dsp->ops->stop_watchdog(dsp); ++ if (dsp->client_ops->watchdog_expired) ++ dsp->client_ops->watchdog_expired(dsp); ++ ++ mutex_unlock(&dsp->pwr_lock); ++} ++EXPORT_SYMBOL_GPL(cs_dsp_halo_wdt_expire); ++ ++static const struct cs_dsp_ops cs_dsp_adsp1_ops = { ++ .validate_version = cs_dsp_validate_version, ++ .parse_sizes = cs_dsp_adsp1_parse_sizes, ++ .region_to_reg = cs_dsp_region_to_reg, ++}; ++ ++static const struct cs_dsp_ops cs_dsp_adsp2_ops[] = { ++ { ++ .parse_sizes = cs_dsp_adsp2_parse_sizes, ++ .validate_version = cs_dsp_validate_version, ++ .setup_algs = cs_dsp_adsp2_setup_algs, ++ .region_to_reg = cs_dsp_region_to_reg, ++ ++ .show_fw_status = cs_dsp_adsp2_show_fw_status, ++ ++ .enable_memory = cs_dsp_adsp2_enable_memory, ++ .disable_memory = cs_dsp_adsp2_disable_memory, ++ ++ .enable_core = cs_dsp_adsp2_enable_core, ++ .disable_core = cs_dsp_adsp2_disable_core, ++ ++ .start_core = cs_dsp_adsp2_start_core, ++ .stop_core = cs_dsp_adsp2_stop_core, ++ ++ }, ++ { ++ .parse_sizes = cs_dsp_adsp2_parse_sizes, ++ .validate_version = cs_dsp_validate_version, ++ .setup_algs = cs_dsp_adsp2_setup_algs, ++ .region_to_reg = cs_dsp_region_to_reg, ++ ++ .show_fw_status = cs_dsp_adsp2v2_show_fw_status, ++ ++ .enable_memory = cs_dsp_adsp2_enable_memory, ++ .disable_memory = cs_dsp_adsp2_disable_memory, ++ .lock_memory = cs_dsp_adsp2_lock, ++ ++ .enable_core = cs_dsp_adsp2v2_enable_core, ++ .disable_core = cs_dsp_adsp2v2_disable_core, ++ ++ .start_core = cs_dsp_adsp2_start_core, ++ .stop_core = cs_dsp_adsp2_stop_core, ++ }, ++ { ++ .parse_sizes = cs_dsp_adsp2_parse_sizes, ++ .validate_version = cs_dsp_validate_version, ++ .setup_algs = cs_dsp_adsp2_setup_algs, ++ .region_to_reg = cs_dsp_region_to_reg, ++ ++ .show_fw_status = cs_dsp_adsp2v2_show_fw_status, ++ .stop_watchdog = cs_dsp_stop_watchdog, ++ ++ .enable_memory = cs_dsp_adsp2_enable_memory, ++ .disable_memory = cs_dsp_adsp2_disable_memory, ++ .lock_memory = cs_dsp_adsp2_lock, ++ ++ .enable_core = cs_dsp_adsp2v2_enable_core, ++ .disable_core = cs_dsp_adsp2v2_disable_core, ++ ++ .start_core = cs_dsp_adsp2_start_core, ++ .stop_core = cs_dsp_adsp2_stop_core, ++ }, ++}; ++ ++static const struct cs_dsp_ops cs_dsp_halo_ops = { ++ .parse_sizes = cs_dsp_adsp2_parse_sizes, ++ .validate_version = cs_dsp_halo_validate_version, ++ .setup_algs = cs_dsp_halo_setup_algs, ++ .region_to_reg = cs_dsp_halo_region_to_reg, ++ ++ .show_fw_status = cs_dsp_halo_show_fw_status, ++ .stop_watchdog = cs_dsp_halo_stop_watchdog, ++ ++ .lock_memory = cs_dsp_halo_configure_mpu, ++ ++ .start_core = cs_dsp_halo_start_core, ++ .stop_core = cs_dsp_halo_stop_core, ++}; ++ ++MODULE_DESCRIPTION("Cirrus Logic DSP Support"); ++MODULE_AUTHOR("Simon Trimmer "); ++MODULE_LICENSE("GPL v2"); +diff --git a/include/linux/firmware/cirrus/cs_dsp.h b/include/linux/firmware/cirrus/cs_dsp.h +new file mode 100644 +index 000000000000..9ad9eaaaa552 +--- /dev/null ++++ b/include/linux/firmware/cirrus/cs_dsp.h +@@ -0,0 +1,242 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * cs_dsp.h -- Cirrus Logic DSP firmware support ++ * ++ * Based on sound/soc/codecs/wm_adsp.h ++ * ++ * Copyright 2012 Wolfson Microelectronics plc ++ * Copyright (C) 2015-2021 Cirrus Logic, Inc. and ++ * Cirrus Logic International Semiconductor Ltd. ++ */ ++#ifndef __CS_DSP_H ++#define __CS_DSP_H ++ ++#define CS_ADSP2_REGION_0 BIT(0) ++#define CS_ADSP2_REGION_1 BIT(1) ++#define CS_ADSP2_REGION_2 BIT(2) ++#define CS_ADSP2_REGION_3 BIT(3) ++#define CS_ADSP2_REGION_4 BIT(4) ++#define CS_ADSP2_REGION_5 BIT(5) ++#define CS_ADSP2_REGION_6 BIT(6) ++#define CS_ADSP2_REGION_7 BIT(7) ++#define CS_ADSP2_REGION_8 BIT(8) ++#define CS_ADSP2_REGION_9 BIT(9) ++#define CS_ADSP2_REGION_1_9 (CS_ADSP2_REGION_1 | \ ++ CS_ADSP2_REGION_2 | CS_ADSP2_REGION_3 | \ ++ CS_ADSP2_REGION_4 | CS_ADSP2_REGION_5 | \ ++ CS_ADSP2_REGION_6 | CS_ADSP2_REGION_7 | \ ++ CS_ADSP2_REGION_8 | CS_ADSP2_REGION_9) ++#define CS_ADSP2_REGION_ALL (CS_ADSP2_REGION_0 | CS_ADSP2_REGION_1_9) ++ ++#define CS_DSP_DATA_WORD_SIZE 3 ++ ++#define CS_DSP_ACKED_CTL_TIMEOUT_MS 100 ++#define CS_DSP_ACKED_CTL_N_QUICKPOLLS 10 ++#define CS_DSP_ACKED_CTL_MIN_VALUE 0 ++#define CS_DSP_ACKED_CTL_MAX_VALUE 0xFFFFFF ++ ++/** ++ * struct cs_dsp_region - Describes a logical memory region in DSP address space ++ * @type: Memory region type ++ * @base: Address of region ++ */ ++struct cs_dsp_region { ++ int type; ++ unsigned int base; ++}; ++ ++/** ++ * struct cs_dsp_alg_region - Describes a logical algorithm region in DSP address space ++ * @list: List node for internal use ++ * @alg: Algorithm id ++ * @type: Memory region type ++ * @base: Address of region ++ */ ++struct cs_dsp_alg_region { ++ struct list_head list; ++ unsigned int alg; ++ int type; ++ unsigned int base; ++}; ++ ++/** ++ * struct cs_dsp_coeff_ctl - Describes a coefficient control ++ * @fw_name: Name of the firmware ++ * @subname: Name of the control parsed from the WMFW ++ * @subname_len: Length of subname ++ * @alg_region: Logical region associated with this control ++ * @dsp: DSP instance associated with this control ++ * @enabled: Flag indicating whether control is enabled ++ * @list: List node for internal use ++ * @cache: Cached value of the control ++ * @offset: Offset of control within alg_region ++ * @len: Length of the cached value ++ * @set: Flag indicating the value has been written by the user ++ * @flags: Bitfield of WMFW_CTL_FLAG_ control flags defined in wmfw.h ++ * @type: One of the WMFW_CTL_TYPE_ control types defined in wmfw.h ++ * @priv: For use by the client ++ */ ++struct cs_dsp_coeff_ctl { ++ const char *fw_name; ++ /* Subname is needed to match with firmware */ ++ const char *subname; ++ unsigned int subname_len; ++ struct cs_dsp_alg_region alg_region; ++ struct cs_dsp *dsp; ++ unsigned int enabled:1; ++ struct list_head list; ++ void *cache; ++ unsigned int offset; ++ size_t len; ++ unsigned int set:1; ++ unsigned int flags; ++ unsigned int type; ++ ++ void *priv; ++}; ++ ++struct cs_dsp_ops; ++struct cs_dsp_client_ops; ++ ++/** ++ * struct cs_dsp - Configuration and state of a Cirrus Logic DSP ++ * @name: The name of the DSP instance ++ * @rev: Revision of the DSP ++ * @num: DSP instance number ++ * @type: Type of DSP ++ * @dev: Driver model representation of the device ++ * @regmap: Register map of the device ++ * @ops: Function pointers for internal callbacks ++ * @client_ops: Function pointers for client callbacks ++ * @base: Address of the DSP registers ++ * @base_sysinfo: Address of the sysinfo register (Halo only) ++ * @sysclk_reg: Address of the sysclk register (ADSP1 only) ++ * @sysclk_mask: Mask of frequency bits within sysclk register (ADSP1 only) ++ * @sysclk_shift: Shift of frequency bits within sysclk register (ADSP1 only) ++ * @alg_regions: List of currently loaded algorithm regions ++ * @fw_file_name: Filename of the current firmware ++ * @fw_name: Name of the current firmware ++ * @fw_id: ID of the current firmware, obtained from the wmfw ++ * @fw_id_version: Version of the firmware, obtained from the wmfw ++ * @fw_vendor_id: Vendor of the firmware, obtained from the wmfw ++ * @mem: DSP memory region descriptions ++ * @num_mems: Number of memory regions in this DSP ++ * @fw_ver: Version of the wmfw file format ++ * @booted: Flag indicating DSP has been configured ++ * @running: Flag indicating DSP is executing firmware ++ * @ctl_list: Controls defined within the loaded DSP firmware ++ * @lock_regions: Enable MPU traps on specified memory regions ++ * @pwr_lock: Lock used to serialize accesses ++ * @debugfs_root: Debugfs directory for this DSP instance ++ * @wmfw_file_name: Filename of the currently loaded firmware ++ * @bin_file_name: Filename of the currently loaded coefficients ++ */ ++struct cs_dsp { ++ const char *name; ++ int rev; ++ int num; ++ int type; ++ struct device *dev; ++ struct regmap *regmap; ++ ++ const struct cs_dsp_ops *ops; ++ const struct cs_dsp_client_ops *client_ops; ++ ++ unsigned int base; ++ unsigned int base_sysinfo; ++ unsigned int sysclk_reg; ++ unsigned int sysclk_mask; ++ unsigned int sysclk_shift; ++ ++ struct list_head alg_regions; ++ ++ const char *fw_name; ++ unsigned int fw_id; ++ unsigned int fw_id_version; ++ unsigned int fw_vendor_id; ++ ++ const struct cs_dsp_region *mem; ++ int num_mems; ++ ++ int fw_ver; ++ ++ bool booted; ++ bool running; ++ ++ struct list_head ctl_list; ++ ++ struct mutex pwr_lock; ++ ++ unsigned int lock_regions; ++ ++#ifdef CONFIG_DEBUG_FS ++ struct dentry *debugfs_root; ++ char *wmfw_file_name; ++ char *bin_file_name; ++#endif ++}; ++ ++/** ++ * struct cs_dsp_client_ops - client callbacks ++ * @control_add: Called under the pwr_lock when a control is created ++ * @control_remove: Called under the pwr_lock when a control is destroyed ++ * @post_run: Called under the pwr_lock by cs_dsp_run() ++ * @post_stop: Called under the pwr_lock by cs_dsp_stop() ++ * @watchdog_expired: Called when a watchdog expiry is detected ++ * ++ * These callbacks give the cs_dsp client an opportunity to respond to events ++ * or to perform actions atomically. ++ */ ++struct cs_dsp_client_ops { ++ int (*control_add)(struct cs_dsp_coeff_ctl *ctl); ++ void (*control_remove)(struct cs_dsp_coeff_ctl *ctl); ++ int (*post_run)(struct cs_dsp *dsp); ++ void (*post_stop)(struct cs_dsp *dsp); ++ void (*watchdog_expired)(struct cs_dsp *dsp); ++}; ++ ++int cs_dsp_adsp1_init(struct cs_dsp *dsp); ++int cs_dsp_adsp2_init(struct cs_dsp *dsp); ++int cs_dsp_halo_init(struct cs_dsp *dsp); ++ ++int cs_dsp_adsp1_power_up(struct cs_dsp *dsp, ++ const struct firmware *wmfw_firmware, char *wmfw_filename, ++ const struct firmware *coeff_firmware, char *coeff_filename, ++ const char *fw_name); ++void cs_dsp_adsp1_power_down(struct cs_dsp *dsp); ++int cs_dsp_power_up(struct cs_dsp *dsp, ++ const struct firmware *wmfw_firmware, char *wmfw_filename, ++ const struct firmware *coeff_firmware, char *coeff_filename, ++ const char *fw_name); ++void cs_dsp_power_down(struct cs_dsp *dsp); ++int cs_dsp_run(struct cs_dsp *dsp); ++void cs_dsp_stop(struct cs_dsp *dsp); ++ ++void cs_dsp_remove(struct cs_dsp *dsp); ++ ++int cs_dsp_set_dspclk(struct cs_dsp *dsp, unsigned int freq); ++void cs_dsp_adsp2_bus_error(struct cs_dsp *dsp); ++void cs_dsp_halo_bus_error(struct cs_dsp *dsp); ++void cs_dsp_halo_wdt_expire(struct cs_dsp *dsp); ++ ++void cs_dsp_init_debugfs(struct cs_dsp *dsp, struct dentry *debugfs_root); ++void cs_dsp_cleanup_debugfs(struct cs_dsp *dsp); ++ ++int cs_dsp_coeff_write_acked_control(struct cs_dsp_coeff_ctl *ctl, unsigned int event_id); ++int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl, const void *buf, size_t len); ++int cs_dsp_coeff_read_ctrl(struct cs_dsp_coeff_ctl *ctl, void *buf, size_t len); ++struct cs_dsp_coeff_ctl *cs_dsp_get_ctl(struct cs_dsp *dsp, const char *name, int type, ++ unsigned int alg); ++ ++int cs_dsp_read_raw_data_block(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, ++ unsigned int num_words, __be32 *data); ++int cs_dsp_read_data_word(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, u32 *data); ++int cs_dsp_write_data_word(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, u32 data); ++void cs_dsp_remove_padding(u32 *buf, int nwords); ++ ++struct cs_dsp_alg_region *cs_dsp_find_alg_region(struct cs_dsp *dsp, ++ int type, unsigned int id); ++ ++const char *cs_dsp_mem_region_name(unsigned int type); ++ ++#endif +diff --git a/include/linux/firmware/cirrus/wmfw.h b/include/linux/firmware/cirrus/wmfw.h +new file mode 100644 +index 000000000000..a19bf7c6fc8b +--- /dev/null ++++ b/include/linux/firmware/cirrus/wmfw.h +@@ -0,0 +1,202 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * wmfw.h - Wolfson firmware format information ++ * ++ * Copyright 2012 Wolfson Microelectronics plc ++ * ++ * Author: Mark Brown ++ */ ++ ++#ifndef __WMFW_H ++#define __WMFW_H ++ ++#include ++ ++#define WMFW_MAX_ALG_NAME 256 ++#define WMFW_MAX_ALG_DESCR_NAME 256 ++ ++#define WMFW_MAX_COEFF_NAME 256 ++#define WMFW_MAX_COEFF_DESCR_NAME 256 ++ ++#define WMFW_CTL_FLAG_SYS 0x8000 ++#define WMFW_CTL_FLAG_VOLATILE 0x0004 ++#define WMFW_CTL_FLAG_WRITEABLE 0x0002 ++#define WMFW_CTL_FLAG_READABLE 0x0001 ++ ++#define WMFW_CTL_TYPE_BYTES 0x0004 /* byte control */ ++ ++/* Non-ALSA coefficient types start at 0x1000 */ ++#define WMFW_CTL_TYPE_ACKED 0x1000 /* acked control */ ++#define WMFW_CTL_TYPE_HOSTEVENT 0x1001 /* event control */ ++#define WMFW_CTL_TYPE_HOST_BUFFER 0x1002 /* host buffer pointer */ ++ ++struct wmfw_header { ++ char magic[4]; ++ __le32 len; ++ __le16 rev; ++ u8 core; ++ u8 ver; ++} __packed; ++ ++struct wmfw_footer { ++ __le64 timestamp; ++ __le32 checksum; ++} __packed; ++ ++struct wmfw_adsp1_sizes { ++ __le32 dm; ++ __le32 pm; ++ __le32 zm; ++} __packed; ++ ++struct wmfw_adsp2_sizes { ++ __le32 xm; ++ __le32 ym; ++ __le32 pm; ++ __le32 zm; ++} __packed; ++ ++struct wmfw_region { ++ union { ++ __be32 type; ++ __le32 offset; ++ }; ++ __le32 len; ++ u8 data[]; ++} __packed; ++ ++struct wmfw_id_hdr { ++ __be32 core_id; ++ __be32 core_rev; ++ __be32 id; ++ __be32 ver; ++} __packed; ++ ++struct wmfw_v3_id_hdr { ++ __be32 core_id; ++ __be32 block_rev; ++ __be32 vendor_id; ++ __be32 id; ++ __be32 ver; ++} __packed; ++ ++struct wmfw_adsp1_id_hdr { ++ struct wmfw_id_hdr fw; ++ __be32 zm; ++ __be32 dm; ++ __be32 n_algs; ++} __packed; ++ ++struct wmfw_adsp2_id_hdr { ++ struct wmfw_id_hdr fw; ++ __be32 zm; ++ __be32 xm; ++ __be32 ym; ++ __be32 n_algs; ++} __packed; ++ ++struct wmfw_halo_id_hdr { ++ struct wmfw_v3_id_hdr fw; ++ __be32 xm_base; ++ __be32 xm_size; ++ __be32 ym_base; ++ __be32 ym_size; ++ __be32 n_algs; ++} __packed; ++ ++struct wmfw_alg_hdr { ++ __be32 id; ++ __be32 ver; ++} __packed; ++ ++struct wmfw_adsp1_alg_hdr { ++ struct wmfw_alg_hdr alg; ++ __be32 zm; ++ __be32 dm; ++} __packed; ++ ++struct wmfw_adsp2_alg_hdr { ++ struct wmfw_alg_hdr alg; ++ __be32 zm; ++ __be32 xm; ++ __be32 ym; ++} __packed; ++ ++struct wmfw_halo_alg_hdr { ++ struct wmfw_alg_hdr alg; ++ __be32 xm_base; ++ __be32 xm_size; ++ __be32 ym_base; ++ __be32 ym_size; ++} __packed; ++ ++struct wmfw_adsp_alg_data { ++ __le32 id; ++ u8 name[WMFW_MAX_ALG_NAME]; ++ u8 descr[WMFW_MAX_ALG_DESCR_NAME]; ++ __le32 ncoeff; ++ u8 data[]; ++} __packed; ++ ++struct wmfw_adsp_coeff_data { ++ struct { ++ __le16 offset; ++ __le16 type; ++ __le32 size; ++ } hdr; ++ u8 name[WMFW_MAX_COEFF_NAME]; ++ u8 descr[WMFW_MAX_COEFF_DESCR_NAME]; ++ __le16 ctl_type; ++ __le16 flags; ++ __le32 len; ++ u8 data[]; ++} __packed; ++ ++struct wmfw_coeff_hdr { ++ u8 magic[4]; ++ __le32 len; ++ union { ++ __be32 rev; ++ __le32 ver; ++ }; ++ union { ++ __be32 core; ++ __le32 core_ver; ++ }; ++ u8 data[]; ++} __packed; ++ ++struct wmfw_coeff_item { ++ __le16 offset; ++ __le16 type; ++ __le32 id; ++ __le32 ver; ++ __le32 sr; ++ __le32 len; ++ u8 data[]; ++} __packed; ++ ++#define WMFW_ADSP1 1 ++#define WMFW_ADSP2 2 ++#define WMFW_HALO 4 ++ ++#define WMFW_ABSOLUTE 0xf0 ++#define WMFW_ALGORITHM_DATA 0xf2 ++#define WMFW_METADATA 0xfc ++#define WMFW_NAME_TEXT 0xfe ++#define WMFW_INFO_TEXT 0xff ++ ++#define WMFW_ADSP1_PM 2 ++#define WMFW_ADSP1_DM 3 ++#define WMFW_ADSP1_ZM 4 ++ ++#define WMFW_ADSP2_PM 2 ++#define WMFW_ADSP2_ZM 4 ++#define WMFW_ADSP2_XM 5 ++#define WMFW_ADSP2_YM 6 ++ ++#define WMFW_HALO_PM_PACKED 0x10 ++#define WMFW_HALO_XM_PACKED 0x11 ++#define WMFW_HALO_YM_PACKED 0x12 ++ ++#endif +diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig +index ab7ac5e0bd68..deda5ee02ebb 100644 +--- a/sound/soc/codecs/Kconfig ++++ b/sound/soc/codecs/Kconfig +@@ -333,6 +333,7 @@ config SND_SOC_WM_HUBS + + config SND_SOC_WM_ADSP + tristate ++ select CS_DSP + select SND_SOC_COMPRESS + default y if SND_SOC_MADERA=y + default y if SND_SOC_CS47L24=y +diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c +index 6c5d55b3b311..f17c749c24c3 100644 +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -19,7 +19,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -44,15 +43,6 @@ + #define adsp_dbg(_dsp, fmt, ...) \ + dev_dbg(_dsp->cs_dsp.dev, "%s: " fmt, _dsp->cs_dsp.name, ##__VA_ARGS__) + +-#define cs_dsp_err(_dsp, fmt, ...) \ +- dev_err(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) +-#define cs_dsp_warn(_dsp, fmt, ...) \ +- dev_warn(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) +-#define cs_dsp_info(_dsp, fmt, ...) \ +- dev_info(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) +-#define cs_dsp_dbg(_dsp, fmt, ...) \ +- dev_dbg(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) +- + #define compr_err(_obj, fmt, ...) \ + adsp_err(_obj->dsp, "%s: " fmt, _obj->name ? _obj->name : "legacy", \ + ##__VA_ARGS__) +@@ -60,305 +50,11 @@ + adsp_dbg(_obj->dsp, "%s: " fmt, _obj->name ? _obj->name : "legacy", \ + ##__VA_ARGS__) + +-#define ADSP1_CONTROL_1 0x00 +-#define ADSP1_CONTROL_2 0x02 +-#define ADSP1_CONTROL_3 0x03 +-#define ADSP1_CONTROL_4 0x04 +-#define ADSP1_CONTROL_5 0x06 +-#define ADSP1_CONTROL_6 0x07 +-#define ADSP1_CONTROL_7 0x08 +-#define ADSP1_CONTROL_8 0x09 +-#define ADSP1_CONTROL_9 0x0A +-#define ADSP1_CONTROL_10 0x0B +-#define ADSP1_CONTROL_11 0x0C +-#define ADSP1_CONTROL_12 0x0D +-#define ADSP1_CONTROL_13 0x0F +-#define ADSP1_CONTROL_14 0x10 +-#define ADSP1_CONTROL_15 0x11 +-#define ADSP1_CONTROL_16 0x12 +-#define ADSP1_CONTROL_17 0x13 +-#define ADSP1_CONTROL_18 0x14 +-#define ADSP1_CONTROL_19 0x16 +-#define ADSP1_CONTROL_20 0x17 +-#define ADSP1_CONTROL_21 0x18 +-#define ADSP1_CONTROL_22 0x1A +-#define ADSP1_CONTROL_23 0x1B +-#define ADSP1_CONTROL_24 0x1C +-#define ADSP1_CONTROL_25 0x1E +-#define ADSP1_CONTROL_26 0x20 +-#define ADSP1_CONTROL_27 0x21 +-#define ADSP1_CONTROL_28 0x22 +-#define ADSP1_CONTROL_29 0x23 +-#define ADSP1_CONTROL_30 0x24 +-#define ADSP1_CONTROL_31 0x26 +- +-/* +- * ADSP1 Control 19 +- */ +-#define ADSP1_WDMA_BUFFER_LENGTH_MASK 0x00FF /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ +-#define ADSP1_WDMA_BUFFER_LENGTH_SHIFT 0 /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ +-#define ADSP1_WDMA_BUFFER_LENGTH_WIDTH 8 /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ +- +- +-/* +- * ADSP1 Control 30 +- */ +-#define ADSP1_DBG_CLK_ENA 0x0008 /* DSP1_DBG_CLK_ENA */ +-#define ADSP1_DBG_CLK_ENA_MASK 0x0008 /* DSP1_DBG_CLK_ENA */ +-#define ADSP1_DBG_CLK_ENA_SHIFT 3 /* DSP1_DBG_CLK_ENA */ +-#define ADSP1_DBG_CLK_ENA_WIDTH 1 /* DSP1_DBG_CLK_ENA */ +-#define ADSP1_SYS_ENA 0x0004 /* DSP1_SYS_ENA */ +-#define ADSP1_SYS_ENA_MASK 0x0004 /* DSP1_SYS_ENA */ +-#define ADSP1_SYS_ENA_SHIFT 2 /* DSP1_SYS_ENA */ +-#define ADSP1_SYS_ENA_WIDTH 1 /* DSP1_SYS_ENA */ +-#define ADSP1_CORE_ENA 0x0002 /* DSP1_CORE_ENA */ +-#define ADSP1_CORE_ENA_MASK 0x0002 /* DSP1_CORE_ENA */ +-#define ADSP1_CORE_ENA_SHIFT 1 /* DSP1_CORE_ENA */ +-#define ADSP1_CORE_ENA_WIDTH 1 /* DSP1_CORE_ENA */ +-#define ADSP1_START 0x0001 /* DSP1_START */ +-#define ADSP1_START_MASK 0x0001 /* DSP1_START */ +-#define ADSP1_START_SHIFT 0 /* DSP1_START */ +-#define ADSP1_START_WIDTH 1 /* DSP1_START */ +- +-/* +- * ADSP1 Control 31 +- */ +-#define ADSP1_CLK_SEL_MASK 0x0007 /* CLK_SEL_ENA */ +-#define ADSP1_CLK_SEL_SHIFT 0 /* CLK_SEL_ENA */ +-#define ADSP1_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */ +- +-#define ADSP2_CONTROL 0x0 +-#define ADSP2_CLOCKING 0x1 +-#define ADSP2V2_CLOCKING 0x2 +-#define ADSP2_STATUS1 0x4 +-#define ADSP2_WDMA_CONFIG_1 0x30 +-#define ADSP2_WDMA_CONFIG_2 0x31 +-#define ADSP2V2_WDMA_CONFIG_2 0x32 +-#define ADSP2_RDMA_CONFIG_1 0x34 +- +-#define ADSP2_SCRATCH0 0x40 +-#define ADSP2_SCRATCH1 0x41 +-#define ADSP2_SCRATCH2 0x42 +-#define ADSP2_SCRATCH3 0x43 +- +-#define ADSP2V2_SCRATCH0_1 0x40 +-#define ADSP2V2_SCRATCH2_3 0x42 +- +-/* +- * ADSP2 Control +- */ +- +-#define ADSP2_MEM_ENA 0x0010 /* DSP1_MEM_ENA */ +-#define ADSP2_MEM_ENA_MASK 0x0010 /* DSP1_MEM_ENA */ +-#define ADSP2_MEM_ENA_SHIFT 4 /* DSP1_MEM_ENA */ +-#define ADSP2_MEM_ENA_WIDTH 1 /* DSP1_MEM_ENA */ +-#define ADSP2_SYS_ENA 0x0004 /* DSP1_SYS_ENA */ +-#define ADSP2_SYS_ENA_MASK 0x0004 /* DSP1_SYS_ENA */ +-#define ADSP2_SYS_ENA_SHIFT 2 /* DSP1_SYS_ENA */ +-#define ADSP2_SYS_ENA_WIDTH 1 /* DSP1_SYS_ENA */ +-#define ADSP2_CORE_ENA 0x0002 /* DSP1_CORE_ENA */ +-#define ADSP2_CORE_ENA_MASK 0x0002 /* DSP1_CORE_ENA */ +-#define ADSP2_CORE_ENA_SHIFT 1 /* DSP1_CORE_ENA */ +-#define ADSP2_CORE_ENA_WIDTH 1 /* DSP1_CORE_ENA */ +-#define ADSP2_START 0x0001 /* DSP1_START */ +-#define ADSP2_START_MASK 0x0001 /* DSP1_START */ +-#define ADSP2_START_SHIFT 0 /* DSP1_START */ +-#define ADSP2_START_WIDTH 1 /* DSP1_START */ +- +-/* +- * ADSP2 clocking +- */ +-#define ADSP2_CLK_SEL_MASK 0x0007 /* CLK_SEL_ENA */ +-#define ADSP2_CLK_SEL_SHIFT 0 /* CLK_SEL_ENA */ +-#define ADSP2_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */ +- +-/* +- * ADSP2V2 clocking +- */ +-#define ADSP2V2_CLK_SEL_MASK 0x70000 /* CLK_SEL_ENA */ +-#define ADSP2V2_CLK_SEL_SHIFT 16 /* CLK_SEL_ENA */ +-#define ADSP2V2_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */ +- +-#define ADSP2V2_RATE_MASK 0x7800 /* DSP_RATE */ +-#define ADSP2V2_RATE_SHIFT 11 /* DSP_RATE */ +-#define ADSP2V2_RATE_WIDTH 4 /* DSP_RATE */ +- +-/* +- * ADSP2 Status 1 +- */ +-#define ADSP2_RAM_RDY 0x0001 +-#define ADSP2_RAM_RDY_MASK 0x0001 +-#define ADSP2_RAM_RDY_SHIFT 0 +-#define ADSP2_RAM_RDY_WIDTH 1 +- +-/* +- * ADSP2 Lock support +- */ +-#define ADSP2_LOCK_CODE_0 0x5555 +-#define ADSP2_LOCK_CODE_1 0xAAAA +- +-#define ADSP2_WATCHDOG 0x0A +-#define ADSP2_BUS_ERR_ADDR 0x52 +-#define ADSP2_REGION_LOCK_STATUS 0x64 +-#define ADSP2_LOCK_REGION_1_LOCK_REGION_0 0x66 +-#define ADSP2_LOCK_REGION_3_LOCK_REGION_2 0x68 +-#define ADSP2_LOCK_REGION_5_LOCK_REGION_4 0x6A +-#define ADSP2_LOCK_REGION_7_LOCK_REGION_6 0x6C +-#define ADSP2_LOCK_REGION_9_LOCK_REGION_8 0x6E +-#define ADSP2_LOCK_REGION_CTRL 0x7A +-#define ADSP2_PMEM_ERR_ADDR_XMEM_ERR_ADDR 0x7C +- +-#define ADSP2_REGION_LOCK_ERR_MASK 0x8000 +-#define ADSP2_ADDR_ERR_MASK 0x4000 +-#define ADSP2_WDT_TIMEOUT_STS_MASK 0x2000 +-#define ADSP2_CTRL_ERR_PAUSE_ENA 0x0002 +-#define ADSP2_CTRL_ERR_EINT 0x0001 +- +-#define ADSP2_BUS_ERR_ADDR_MASK 0x00FFFFFF +-#define ADSP2_XMEM_ERR_ADDR_MASK 0x0000FFFF +-#define ADSP2_PMEM_ERR_ADDR_MASK 0x7FFF0000 +-#define ADSP2_PMEM_ERR_ADDR_SHIFT 16 +-#define ADSP2_WDT_ENA_MASK 0xFFFFFFFD +- +-#define ADSP2_LOCK_REGION_SHIFT 16 +- + #define ADSP_MAX_STD_CTRL_SIZE 512 + +-#define CS_DSP_ACKED_CTL_TIMEOUT_MS 100 +-#define CS_DSP_ACKED_CTL_N_QUICKPOLLS 10 +-#define CS_DSP_ACKED_CTL_MIN_VALUE 0 +-#define CS_DSP_ACKED_CTL_MAX_VALUE 0xFFFFFF +- +-/* +- * Event control messages +- */ +-#define CS_DSP_FW_EVENT_SHUTDOWN 0x000001 +- +-/* +- * HALO system info +- */ +-#define HALO_AHBM_WINDOW_DEBUG_0 0x02040 +-#define HALO_AHBM_WINDOW_DEBUG_1 0x02044 +- +-/* +- * HALO core +- */ +-#define HALO_SCRATCH1 0x005c0 +-#define HALO_SCRATCH2 0x005c8 +-#define HALO_SCRATCH3 0x005d0 +-#define HALO_SCRATCH4 0x005d8 +-#define HALO_CCM_CORE_CONTROL 0x41000 +-#define HALO_CORE_SOFT_RESET 0x00010 +-#define HALO_WDT_CONTROL 0x47000 +- +-/* +- * HALO MPU banks +- */ +-#define HALO_MPU_XMEM_ACCESS_0 0x43000 +-#define HALO_MPU_YMEM_ACCESS_0 0x43004 +-#define HALO_MPU_WINDOW_ACCESS_0 0x43008 +-#define HALO_MPU_XREG_ACCESS_0 0x4300C +-#define HALO_MPU_YREG_ACCESS_0 0x43014 +-#define HALO_MPU_XMEM_ACCESS_1 0x43018 +-#define HALO_MPU_YMEM_ACCESS_1 0x4301C +-#define HALO_MPU_WINDOW_ACCESS_1 0x43020 +-#define HALO_MPU_XREG_ACCESS_1 0x43024 +-#define HALO_MPU_YREG_ACCESS_1 0x4302C +-#define HALO_MPU_XMEM_ACCESS_2 0x43030 +-#define HALO_MPU_YMEM_ACCESS_2 0x43034 +-#define HALO_MPU_WINDOW_ACCESS_2 0x43038 +-#define HALO_MPU_XREG_ACCESS_2 0x4303C +-#define HALO_MPU_YREG_ACCESS_2 0x43044 +-#define HALO_MPU_XMEM_ACCESS_3 0x43048 +-#define HALO_MPU_YMEM_ACCESS_3 0x4304C +-#define HALO_MPU_WINDOW_ACCESS_3 0x43050 +-#define HALO_MPU_XREG_ACCESS_3 0x43054 +-#define HALO_MPU_YREG_ACCESS_3 0x4305C +-#define HALO_MPU_XM_VIO_ADDR 0x43100 +-#define HALO_MPU_XM_VIO_STATUS 0x43104 +-#define HALO_MPU_YM_VIO_ADDR 0x43108 +-#define HALO_MPU_YM_VIO_STATUS 0x4310C +-#define HALO_MPU_PM_VIO_ADDR 0x43110 +-#define HALO_MPU_PM_VIO_STATUS 0x43114 +-#define HALO_MPU_LOCK_CONFIG 0x43140 +- +-/* +- * HALO_AHBM_WINDOW_DEBUG_1 +- */ +-#define HALO_AHBM_CORE_ERR_ADDR_MASK 0x0fffff00 +-#define HALO_AHBM_CORE_ERR_ADDR_SHIFT 8 +-#define HALO_AHBM_FLAGS_ERR_MASK 0x000000ff +- +-/* +- * HALO_CCM_CORE_CONTROL +- */ +-#define HALO_CORE_RESET 0x00000200 +-#define HALO_CORE_EN 0x00000001 +- +-/* +- * HALO_CORE_SOFT_RESET +- */ +-#define HALO_CORE_SOFT_RESET_MASK 0x00000001 +- +-/* +- * HALO_WDT_CONTROL +- */ +-#define HALO_WDT_EN_MASK 0x00000001 +- +-/* +- * HALO_MPU_?M_VIO_STATUS +- */ +-#define HALO_MPU_VIO_STS_MASK 0x007e0000 +-#define HALO_MPU_VIO_STS_SHIFT 17 +-#define HALO_MPU_VIO_ERR_WR_MASK 0x00008000 +-#define HALO_MPU_VIO_ERR_SRC_MASK 0x00007fff +-#define HALO_MPU_VIO_ERR_SRC_SHIFT 0 +- +-static const struct cs_dsp_ops cs_dsp_adsp1_ops; +-static const struct cs_dsp_ops cs_dsp_adsp2_ops[]; +-static const struct cs_dsp_ops cs_dsp_halo_ops; +- + static const struct cs_dsp_client_ops wm_adsp1_client_ops; + static const struct cs_dsp_client_ops wm_adsp2_client_ops; + +-struct cs_dsp_buf { +- struct list_head list; +- void *buf; +-}; +- +-static struct cs_dsp_buf *cs_dsp_buf_alloc(const void *src, size_t len, +- struct list_head *list) +-{ +- struct cs_dsp_buf *buf = kzalloc(sizeof(*buf), GFP_KERNEL); +- +- if (buf == NULL) +- return NULL; +- +- buf->buf = vmalloc(len); +- if (!buf->buf) { +- kfree(buf); +- return NULL; +- } +- memcpy(buf->buf, src, len); +- +- if (list) +- list_add_tail(&buf->list, list); +- +- return buf; +-} +- +-static void cs_dsp_buf_free(struct list_head *list) +-{ +- while (!list_empty(list)) { +- struct cs_dsp_buf *buf = list_first_entry(list, +- struct cs_dsp_buf, +- list); +- list_del(&buf->list); +- vfree(buf->buf); +- kfree(buf); +- } +-} +- + #define WM_ADSP_FW_MBC_VSS 0 + #define WM_ADSP_FW_HIFI 1 + #define WM_ADSP_FW_TX 2 +@@ -483,8 +179,6 @@ struct wm_adsp_compr { + const char *name; + }; + +-#define CS_DSP_DATA_WORD_SIZE 3 +- + #define WM_ADSP_MIN_FRAGMENTS 1 + #define WM_ADSP_MAX_FRAGMENTS 256 + #define WM_ADSP_MIN_FRAGMENT_SIZE (64 * CS_DSP_DATA_WORD_SIZE) +@@ -616,166 +310,6 @@ struct wm_coeff_ctl { + struct work_struct work; + }; + +-static const char *cs_dsp_mem_region_name(unsigned int type) +-{ +- switch (type) { +- case WMFW_ADSP1_PM: +- return "PM"; +- case WMFW_HALO_PM_PACKED: +- return "PM_PACKED"; +- case WMFW_ADSP1_DM: +- return "DM"; +- case WMFW_ADSP2_XM: +- return "XM"; +- case WMFW_HALO_XM_PACKED: +- return "XM_PACKED"; +- case WMFW_ADSP2_YM: +- return "YM"; +- case WMFW_HALO_YM_PACKED: +- return "YM_PACKED"; +- case WMFW_ADSP1_ZM: +- return "ZM"; +- default: +- return NULL; +- } +-} +- +-#ifdef CONFIG_DEBUG_FS +-static void cs_dsp_debugfs_save_wmfwname(struct cs_dsp *dsp, const char *s) +-{ +- char *tmp = kasprintf(GFP_KERNEL, "%s\n", s); +- +- kfree(dsp->wmfw_file_name); +- dsp->wmfw_file_name = tmp; +-} +- +-static void cs_dsp_debugfs_save_binname(struct cs_dsp *dsp, const char *s) +-{ +- char *tmp = kasprintf(GFP_KERNEL, "%s\n", s); +- +- kfree(dsp->bin_file_name); +- dsp->bin_file_name = tmp; +-} +- +-static void cs_dsp_debugfs_clear(struct cs_dsp *dsp) +-{ +- kfree(dsp->wmfw_file_name); +- kfree(dsp->bin_file_name); +- dsp->wmfw_file_name = NULL; +- dsp->bin_file_name = NULL; +-} +- +-static ssize_t cs_dsp_debugfs_wmfw_read(struct file *file, +- char __user *user_buf, +- size_t count, loff_t *ppos) +-{ +- struct cs_dsp *dsp = file->private_data; +- ssize_t ret; +- +- mutex_lock(&dsp->pwr_lock); +- +- if (!dsp->wmfw_file_name || !dsp->booted) +- ret = 0; +- else +- ret = simple_read_from_buffer(user_buf, count, ppos, +- dsp->wmfw_file_name, +- strlen(dsp->wmfw_file_name)); +- +- mutex_unlock(&dsp->pwr_lock); +- return ret; +-} +- +-static ssize_t cs_dsp_debugfs_bin_read(struct file *file, +- char __user *user_buf, +- size_t count, loff_t *ppos) +-{ +- struct cs_dsp *dsp = file->private_data; +- ssize_t ret; +- +- mutex_lock(&dsp->pwr_lock); +- +- if (!dsp->bin_file_name || !dsp->booted) +- ret = 0; +- else +- ret = simple_read_from_buffer(user_buf, count, ppos, +- dsp->bin_file_name, +- strlen(dsp->bin_file_name)); +- +- mutex_unlock(&dsp->pwr_lock); +- return ret; +-} +- +-static const struct { +- const char *name; +- const struct file_operations fops; +-} cs_dsp_debugfs_fops[] = { +- { +- .name = "wmfw_file_name", +- .fops = { +- .open = simple_open, +- .read = cs_dsp_debugfs_wmfw_read, +- }, +- }, +- { +- .name = "bin_file_name", +- .fops = { +- .open = simple_open, +- .read = cs_dsp_debugfs_bin_read, +- }, +- }, +-}; +- +-static void cs_dsp_init_debugfs(struct cs_dsp *dsp, +- struct dentry *debugfs_root) +-{ +- struct dentry *root = NULL; +- int i; +- +- root = debugfs_create_dir(dsp->name, debugfs_root); +- +- debugfs_create_bool("booted", 0444, root, &dsp->booted); +- debugfs_create_bool("running", 0444, root, &dsp->running); +- debugfs_create_x32("fw_id", 0444, root, &dsp->fw_id); +- debugfs_create_x32("fw_version", 0444, root, &dsp->fw_id_version); +- +- for (i = 0; i < ARRAY_SIZE(cs_dsp_debugfs_fops); ++i) +- debugfs_create_file(cs_dsp_debugfs_fops[i].name, 0444, root, +- dsp, &cs_dsp_debugfs_fops[i].fops); +- +- dsp->debugfs_root = root; +-} +- +-static void cs_dsp_cleanup_debugfs(struct cs_dsp *dsp) +-{ +- cs_dsp_debugfs_clear(dsp); +- debugfs_remove_recursive(dsp->debugfs_root); +- dsp->debugfs_root = NULL; +-} +-#else +-static inline void cs_dsp_init_debugfs(struct cs_dsp *dsp, +- struct dentry *debugfs_root) +-{ +-} +- +-static inline void cs_dsp_cleanup_debugfs(struct cs_dsp *dsp) +-{ +-} +- +-static inline void cs_dsp_debugfs_save_wmfwname(struct cs_dsp *dsp, +- const char *s) +-{ +-} +- +-static inline void cs_dsp_debugfs_save_binname(struct cs_dsp *dsp, +- const char *s) +-{ +-} +- +-static inline void cs_dsp_debugfs_clear(struct cs_dsp *dsp) +-{ +-} +-#endif +- + int wm_adsp_fw_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) + { +@@ -827,126 +361,11 @@ const struct soc_enum wm_adsp_fw_enum[] = { + }; + EXPORT_SYMBOL_GPL(wm_adsp_fw_enum); + +-static const struct cs_dsp_region *cs_dsp_find_region(struct cs_dsp *dsp, +- int type) +-{ +- int i; +- +- for (i = 0; i < dsp->num_mems; i++) +- if (dsp->mem[i].type == type) +- return &dsp->mem[i]; +- +- return NULL; +-} +- +-static unsigned int cs_dsp_region_to_reg(struct cs_dsp_region const *mem, +- unsigned int offset) +-{ +- switch (mem->type) { +- case WMFW_ADSP1_PM: +- return mem->base + (offset * 3); +- case WMFW_ADSP1_DM: +- case WMFW_ADSP2_XM: +- case WMFW_ADSP2_YM: +- case WMFW_ADSP1_ZM: +- return mem->base + (offset * 2); +- default: +- WARN(1, "Unknown memory region type"); +- return offset; +- } +-} +- +-static unsigned int cs_dsp_halo_region_to_reg(struct cs_dsp_region const *mem, +- unsigned int offset) +-{ +- switch (mem->type) { +- case WMFW_ADSP2_XM: +- case WMFW_ADSP2_YM: +- return mem->base + (offset * 4); +- case WMFW_HALO_XM_PACKED: +- case WMFW_HALO_YM_PACKED: +- return (mem->base + (offset * 3)) & ~0x3; +- case WMFW_HALO_PM_PACKED: +- return mem->base + (offset * 5); +- default: +- WARN(1, "Unknown memory region type"); +- return offset; +- } +-} +- +-static void cs_dsp_read_fw_status(struct cs_dsp *dsp, +- int noffs, unsigned int *offs) +-{ +- unsigned int i; +- int ret; +- +- for (i = 0; i < noffs; ++i) { +- ret = regmap_read(dsp->regmap, dsp->base + offs[i], &offs[i]); +- if (ret) { +- cs_dsp_err(dsp, "Failed to read SCRATCH%u: %d\n", i, ret); +- return; +- } +- } +-} +- +-static void cs_dsp_adsp2_show_fw_status(struct cs_dsp *dsp) +-{ +- unsigned int offs[] = { +- ADSP2_SCRATCH0, ADSP2_SCRATCH1, ADSP2_SCRATCH2, ADSP2_SCRATCH3, +- }; +- +- cs_dsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs); +- +- cs_dsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", +- offs[0], offs[1], offs[2], offs[3]); +-} +- +-static void cs_dsp_adsp2v2_show_fw_status(struct cs_dsp *dsp) +-{ +- unsigned int offs[] = { ADSP2V2_SCRATCH0_1, ADSP2V2_SCRATCH2_3 }; +- +- cs_dsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs); +- +- cs_dsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", +- offs[0] & 0xFFFF, offs[0] >> 16, +- offs[1] & 0xFFFF, offs[1] >> 16); +-} +- +-static void cs_dsp_halo_show_fw_status(struct cs_dsp *dsp) +-{ +- unsigned int offs[] = { +- HALO_SCRATCH1, HALO_SCRATCH2, HALO_SCRATCH3, HALO_SCRATCH4, +- }; +- +- cs_dsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs); +- +- cs_dsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", +- offs[0], offs[1], offs[2], offs[3]); +-} +- + static inline struct wm_coeff_ctl *bytes_ext_to_ctl(struct soc_bytes_ext *ext) + { + return container_of(ext, struct wm_coeff_ctl, bytes_ext); + } + +-static int cs_dsp_coeff_base_reg(struct cs_dsp_coeff_ctl *ctl, unsigned int *reg) +-{ +- const struct cs_dsp_alg_region *alg_region = &ctl->alg_region; +- struct cs_dsp *dsp = ctl->dsp; +- const struct cs_dsp_region *mem; +- +- mem = cs_dsp_find_region(dsp, alg_region->type); +- if (!mem) { +- cs_dsp_err(dsp, "No base for region %x\n", +- alg_region->type); +- return -EINVAL; +- } +- +- *reg = dsp->ops->region_to_reg(mem, ctl->alg_region.base + ctl->offset); +- +- return 0; +-} +- + static int wm_coeff_info(struct snd_kcontrol *kctl, + struct snd_ctl_elem_info *uinfo) + { +@@ -972,117 +391,6 @@ static int wm_coeff_info(struct snd_kcontrol *kctl, + return 0; + } + +-static int cs_dsp_coeff_write_acked_control(struct cs_dsp_coeff_ctl *ctl, +- unsigned int event_id) +-{ +- struct cs_dsp *dsp = ctl->dsp; +- __be32 val = cpu_to_be32(event_id); +- unsigned int reg; +- int i, ret; +- +- if (!dsp->running) +- return -EPERM; +- +- ret = cs_dsp_coeff_base_reg(ctl, ®); +- if (ret) +- return ret; +- +- cs_dsp_dbg(dsp, "Sending 0x%x to acked control alg 0x%x %s:0x%x\n", +- event_id, ctl->alg_region.alg, +- cs_dsp_mem_region_name(ctl->alg_region.type), ctl->offset); +- +- ret = regmap_raw_write(dsp->regmap, reg, &val, sizeof(val)); +- if (ret) { +- cs_dsp_err(dsp, "Failed to write %x: %d\n", reg, ret); +- return ret; +- } +- +- /* +- * Poll for ack, we initially poll at ~1ms intervals for firmwares +- * that respond quickly, then go to ~10ms polls. A firmware is unlikely +- * to ack instantly so we do the first 1ms delay before reading the +- * control to avoid a pointless bus transaction +- */ +- for (i = 0; i < CS_DSP_ACKED_CTL_TIMEOUT_MS;) { +- switch (i) { +- case 0 ... CS_DSP_ACKED_CTL_N_QUICKPOLLS - 1: +- usleep_range(1000, 2000); +- i++; +- break; +- default: +- usleep_range(10000, 20000); +- i += 10; +- break; +- } +- +- ret = regmap_raw_read(dsp->regmap, reg, &val, sizeof(val)); +- if (ret) { +- cs_dsp_err(dsp, "Failed to read %x: %d\n", reg, ret); +- return ret; +- } +- +- if (val == 0) { +- cs_dsp_dbg(dsp, "Acked control ACKED at poll %u\n", i); +- return 0; +- } +- } +- +- cs_dsp_warn(dsp, "Acked control @0x%x alg:0x%x %s:0x%x timed out\n", +- reg, ctl->alg_region.alg, +- cs_dsp_mem_region_name(ctl->alg_region.type), +- ctl->offset); +- +- return -ETIMEDOUT; +-} +- +-static int cs_dsp_coeff_write_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, +- const void *buf, size_t len) +-{ +- struct cs_dsp *dsp = ctl->dsp; +- void *scratch; +- int ret; +- unsigned int reg; +- +- ret = cs_dsp_coeff_base_reg(ctl, ®); +- if (ret) +- return ret; +- +- scratch = kmemdup(buf, len, GFP_KERNEL | GFP_DMA); +- if (!scratch) +- return -ENOMEM; +- +- ret = regmap_raw_write(dsp->regmap, reg, scratch, +- len); +- if (ret) { +- cs_dsp_err(dsp, "Failed to write %zu bytes to %x: %d\n", +- len, reg, ret); +- kfree(scratch); +- return ret; +- } +- cs_dsp_dbg(dsp, "Wrote %zu bytes to %x\n", len, reg); +- +- kfree(scratch); +- +- return 0; +-} +- +-static int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl, +- const void *buf, size_t len) +-{ +- int ret = 0; +- +- if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) +- ret = -EPERM; +- else if (buf != ctl->cache) +- memcpy(ctl->cache, buf, len); +- +- ctl->set = 1; +- if (ctl->enabled && ctl->dsp->running) +- ret = cs_dsp_coeff_write_ctrl_raw(ctl, buf, len); +- +- return ret; +-} +- + static int wm_coeff_put(struct snd_kcontrol *kctl, + struct snd_ctl_elem_value *ucontrol) + { +@@ -1146,57 +454,6 @@ static int wm_coeff_put_acked(struct snd_kcontrol *kctl, + return ret; + } + +-static int cs_dsp_coeff_read_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, +- void *buf, size_t len) +-{ +- struct cs_dsp *dsp = ctl->dsp; +- void *scratch; +- int ret; +- unsigned int reg; +- +- ret = cs_dsp_coeff_base_reg(ctl, ®); +- if (ret) +- return ret; +- +- scratch = kmalloc(len, GFP_KERNEL | GFP_DMA); +- if (!scratch) +- return -ENOMEM; +- +- ret = regmap_raw_read(dsp->regmap, reg, scratch, len); +- if (ret) { +- cs_dsp_err(dsp, "Failed to read %zu bytes from %x: %d\n", +- len, reg, ret); +- kfree(scratch); +- return ret; +- } +- cs_dsp_dbg(dsp, "Read %zu bytes from %x\n", len, reg); +- +- memcpy(buf, scratch, len); +- kfree(scratch); +- +- return 0; +-} +- +-static int cs_dsp_coeff_read_ctrl(struct cs_dsp_coeff_ctl *ctl, void *buf, size_t len) +-{ +- int ret = 0; +- +- if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) { +- if (ctl->enabled && ctl->dsp->running) +- return cs_dsp_coeff_read_ctrl_raw(ctl, buf, len); +- else +- return -EPERM; +- } else { +- if (!ctl->flags && ctl->enabled && ctl->dsp->running) +- ret = cs_dsp_coeff_read_ctrl_raw(ctl, ctl->cache, ctl->len); +- +- if (buf != ctl->cache) +- memcpy(buf, ctl->cache, len); +- } +- +- return ret; +-} +- + static int wm_coeff_get(struct snd_kcontrol *kctl, + struct snd_ctl_elem_value *ucontrol) + { +@@ -1328,72 +585,6 @@ static int wmfw_add_ctl(struct wm_adsp *dsp, struct wm_coeff_ctl *ctl) + return ret; + } + +-static int cs_dsp_coeff_init_control_caches(struct cs_dsp *dsp) +-{ +- struct cs_dsp_coeff_ctl *ctl; +- int ret; +- +- list_for_each_entry(ctl, &dsp->ctl_list, list) { +- if (!ctl->enabled || ctl->set) +- continue; +- if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) +- continue; +- +- /* +- * For readable controls populate the cache from the DSP memory. +- * For non-readable controls the cache was zero-filled when +- * created so we don't need to do anything. +- */ +- if (!ctl->flags || (ctl->flags & WMFW_CTL_FLAG_READABLE)) { +- ret = cs_dsp_coeff_read_ctrl_raw(ctl, ctl->cache, ctl->len); +- if (ret < 0) +- return ret; +- } +- } +- +- return 0; +-} +- +-static int cs_dsp_coeff_sync_controls(struct cs_dsp *dsp) +-{ +- struct cs_dsp_coeff_ctl *ctl; +- int ret; +- +- list_for_each_entry(ctl, &dsp->ctl_list, list) { +- if (!ctl->enabled) +- continue; +- if (ctl->set && !(ctl->flags & WMFW_CTL_FLAG_VOLATILE)) { +- ret = cs_dsp_coeff_write_ctrl_raw(ctl, ctl->cache, +- ctl->len); +- if (ret < 0) +- return ret; +- } +- } +- +- return 0; +-} +- +-static void cs_dsp_signal_event_controls(struct cs_dsp *dsp, +- unsigned int event) +-{ +- struct cs_dsp_coeff_ctl *ctl; +- int ret; +- +- list_for_each_entry(ctl, &dsp->ctl_list, list) { +- if (ctl->type != WMFW_CTL_TYPE_HOSTEVENT) +- continue; +- +- if (!ctl->enabled) +- continue; +- +- ret = cs_dsp_coeff_write_acked_control(ctl, event); +- if (ret) +- cs_dsp_warn(dsp, +- "Failed to send 0x%x event to alg 0x%x (%d)\n", +- event, ctl->alg_region.alg, ret); +- } +-} +- + static void wm_adsp_ctl_work(struct work_struct *work) + { + struct wm_coeff_ctl *ctl = container_of(work, +@@ -1406,13 +597,6 @@ static void wm_adsp_ctl_work(struct work_struct *work) + wmfw_add_ctl(dsp, ctl); + } + +-static void cs_dsp_free_ctl_blk(struct cs_dsp_coeff_ctl *ctl) +-{ +- kfree(ctl->cache); +- kfree(ctl->subname); +- kfree(ctl); +-} +- + static int wm_adsp_control_add(struct cs_dsp_coeff_ctl *cs_ctl) + { + struct wm_adsp *dsp = container_of(cs_ctl->dsp, struct wm_adsp, cs_dsp); +@@ -1498,622 +682,6 @@ static void wm_adsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl) + kfree(ctl); + } + +-static int cs_dsp_create_control(struct cs_dsp *dsp, +- const struct cs_dsp_alg_region *alg_region, +- unsigned int offset, unsigned int len, +- const char *subname, unsigned int subname_len, +- unsigned int flags, unsigned int type) +-{ +- struct cs_dsp_coeff_ctl *ctl; +- int ret; +- +- list_for_each_entry(ctl, &dsp->ctl_list, list) { +- if (ctl->fw_name == dsp->fw_name && +- ctl->alg_region.alg == alg_region->alg && +- ctl->alg_region.type == alg_region->type) { +- if ((!subname && !ctl->subname) || +- (subname && !strncmp(ctl->subname, subname, ctl->subname_len))) { +- if (!ctl->enabled) +- ctl->enabled = 1; +- return 0; +- } +- } +- } +- +- ctl = kzalloc(sizeof(*ctl), GFP_KERNEL); +- if (!ctl) +- return -ENOMEM; +- +- ctl->fw_name = dsp->fw_name; +- ctl->alg_region = *alg_region; +- if (subname && dsp->fw_ver >= 2) { +- ctl->subname_len = subname_len; +- ctl->subname = kmemdup(subname, +- strlen(subname) + 1, GFP_KERNEL); +- if (!ctl->subname) { +- ret = -ENOMEM; +- goto err_ctl; +- } +- } +- ctl->enabled = 1; +- ctl->set = 0; +- ctl->dsp = dsp; +- +- ctl->flags = flags; +- ctl->type = type; +- ctl->offset = offset; +- ctl->len = len; +- ctl->cache = kzalloc(ctl->len, GFP_KERNEL); +- if (!ctl->cache) { +- ret = -ENOMEM; +- goto err_ctl_subname; +- } +- +- list_add(&ctl->list, &dsp->ctl_list); +- +- if (dsp->client_ops->control_add) { +- ret = dsp->client_ops->control_add(ctl); +- if (ret) +- goto err_list_del; +- } +- +- return 0; +- +-err_list_del: +- list_del(&ctl->list); +- kfree(ctl->cache); +-err_ctl_subname: +- kfree(ctl->subname); +-err_ctl: +- kfree(ctl); +- +- return ret; +-} +- +-struct cs_dsp_coeff_parsed_alg { +- int id; +- const u8 *name; +- int name_len; +- int ncoeff; +-}; +- +-struct cs_dsp_coeff_parsed_coeff { +- int offset; +- int mem_type; +- const u8 *name; +- int name_len; +- unsigned int ctl_type; +- int flags; +- int len; +-}; +- +-static int cs_dsp_coeff_parse_string(int bytes, const u8 **pos, const u8 **str) +-{ +- int length; +- +- switch (bytes) { +- case 1: +- length = **pos; +- break; +- case 2: +- length = le16_to_cpu(*((__le16 *)*pos)); +- break; +- default: +- return 0; +- } +- +- if (str) +- *str = *pos + bytes; +- +- *pos += ((length + bytes) + 3) & ~0x03; +- +- return length; +-} +- +-static int cs_dsp_coeff_parse_int(int bytes, const u8 **pos) +-{ +- int val = 0; +- +- switch (bytes) { +- case 2: +- val = le16_to_cpu(*((__le16 *)*pos)); +- break; +- case 4: +- val = le32_to_cpu(*((__le32 *)*pos)); +- break; +- default: +- break; +- } +- +- *pos += bytes; +- +- return val; +-} +- +-static inline void cs_dsp_coeff_parse_alg(struct cs_dsp *dsp, const u8 **data, +- struct cs_dsp_coeff_parsed_alg *blk) +-{ +- const struct wmfw_adsp_alg_data *raw; +- +- switch (dsp->fw_ver) { +- case 0: +- case 1: +- raw = (const struct wmfw_adsp_alg_data *)*data; +- *data = raw->data; +- +- blk->id = le32_to_cpu(raw->id); +- blk->name = raw->name; +- blk->name_len = strlen(raw->name); +- blk->ncoeff = le32_to_cpu(raw->ncoeff); +- break; +- default: +- blk->id = cs_dsp_coeff_parse_int(sizeof(raw->id), data); +- blk->name_len = cs_dsp_coeff_parse_string(sizeof(u8), data, +- &blk->name); +- cs_dsp_coeff_parse_string(sizeof(u16), data, NULL); +- blk->ncoeff = cs_dsp_coeff_parse_int(sizeof(raw->ncoeff), data); +- break; +- } +- +- cs_dsp_dbg(dsp, "Algorithm ID: %#x\n", blk->id); +- cs_dsp_dbg(dsp, "Algorithm name: %.*s\n", blk->name_len, blk->name); +- cs_dsp_dbg(dsp, "# of coefficient descriptors: %#x\n", blk->ncoeff); +-} +- +-static inline void cs_dsp_coeff_parse_coeff(struct cs_dsp *dsp, const u8 **data, +- struct cs_dsp_coeff_parsed_coeff *blk) +-{ +- const struct wmfw_adsp_coeff_data *raw; +- const u8 *tmp; +- int length; +- +- switch (dsp->fw_ver) { +- case 0: +- case 1: +- raw = (const struct wmfw_adsp_coeff_data *)*data; +- *data = *data + sizeof(raw->hdr) + le32_to_cpu(raw->hdr.size); +- +- blk->offset = le16_to_cpu(raw->hdr.offset); +- blk->mem_type = le16_to_cpu(raw->hdr.type); +- blk->name = raw->name; +- blk->name_len = strlen(raw->name); +- blk->ctl_type = le16_to_cpu(raw->ctl_type); +- blk->flags = le16_to_cpu(raw->flags); +- blk->len = le32_to_cpu(raw->len); +- break; +- default: +- tmp = *data; +- blk->offset = cs_dsp_coeff_parse_int(sizeof(raw->hdr.offset), &tmp); +- blk->mem_type = cs_dsp_coeff_parse_int(sizeof(raw->hdr.type), &tmp); +- length = cs_dsp_coeff_parse_int(sizeof(raw->hdr.size), &tmp); +- blk->name_len = cs_dsp_coeff_parse_string(sizeof(u8), &tmp, +- &blk->name); +- cs_dsp_coeff_parse_string(sizeof(u8), &tmp, NULL); +- cs_dsp_coeff_parse_string(sizeof(u16), &tmp, NULL); +- blk->ctl_type = cs_dsp_coeff_parse_int(sizeof(raw->ctl_type), &tmp); +- blk->flags = cs_dsp_coeff_parse_int(sizeof(raw->flags), &tmp); +- blk->len = cs_dsp_coeff_parse_int(sizeof(raw->len), &tmp); +- +- *data = *data + sizeof(raw->hdr) + length; +- break; +- } +- +- cs_dsp_dbg(dsp, "\tCoefficient type: %#x\n", blk->mem_type); +- cs_dsp_dbg(dsp, "\tCoefficient offset: %#x\n", blk->offset); +- cs_dsp_dbg(dsp, "\tCoefficient name: %.*s\n", blk->name_len, blk->name); +- cs_dsp_dbg(dsp, "\tCoefficient flags: %#x\n", blk->flags); +- cs_dsp_dbg(dsp, "\tALSA control type: %#x\n", blk->ctl_type); +- cs_dsp_dbg(dsp, "\tALSA control len: %#x\n", blk->len); +-} +- +-static int cs_dsp_check_coeff_flags(struct cs_dsp *dsp, +- const struct cs_dsp_coeff_parsed_coeff *coeff_blk, +- unsigned int f_required, +- unsigned int f_illegal) +-{ +- if ((coeff_blk->flags & f_illegal) || +- ((coeff_blk->flags & f_required) != f_required)) { +- cs_dsp_err(dsp, "Illegal flags 0x%x for control type 0x%x\n", +- coeff_blk->flags, coeff_blk->ctl_type); +- return -EINVAL; +- } +- +- return 0; +-} +- +-static int cs_dsp_parse_coeff(struct cs_dsp *dsp, +- const struct wmfw_region *region) +-{ +- struct cs_dsp_alg_region alg_region = {}; +- struct cs_dsp_coeff_parsed_alg alg_blk; +- struct cs_dsp_coeff_parsed_coeff coeff_blk; +- const u8 *data = region->data; +- int i, ret; +- +- cs_dsp_coeff_parse_alg(dsp, &data, &alg_blk); +- for (i = 0; i < alg_blk.ncoeff; i++) { +- cs_dsp_coeff_parse_coeff(dsp, &data, &coeff_blk); +- +- switch (coeff_blk.ctl_type) { +- case WMFW_CTL_TYPE_BYTES: +- break; +- case WMFW_CTL_TYPE_ACKED: +- if (coeff_blk.flags & WMFW_CTL_FLAG_SYS) +- continue; /* ignore */ +- +- ret = cs_dsp_check_coeff_flags(dsp, &coeff_blk, +- WMFW_CTL_FLAG_VOLATILE | +- WMFW_CTL_FLAG_WRITEABLE | +- WMFW_CTL_FLAG_READABLE, +- 0); +- if (ret) +- return -EINVAL; +- break; +- case WMFW_CTL_TYPE_HOSTEVENT: +- ret = cs_dsp_check_coeff_flags(dsp, &coeff_blk, +- WMFW_CTL_FLAG_SYS | +- WMFW_CTL_FLAG_VOLATILE | +- WMFW_CTL_FLAG_WRITEABLE | +- WMFW_CTL_FLAG_READABLE, +- 0); +- if (ret) +- return -EINVAL; +- break; +- case WMFW_CTL_TYPE_HOST_BUFFER: +- ret = cs_dsp_check_coeff_flags(dsp, &coeff_blk, +- WMFW_CTL_FLAG_SYS | +- WMFW_CTL_FLAG_VOLATILE | +- WMFW_CTL_FLAG_READABLE, +- 0); +- if (ret) +- return -EINVAL; +- break; +- default: +- cs_dsp_err(dsp, "Unknown control type: %d\n", +- coeff_blk.ctl_type); +- return -EINVAL; +- } +- +- alg_region.type = coeff_blk.mem_type; +- alg_region.alg = alg_blk.id; +- +- ret = cs_dsp_create_control(dsp, &alg_region, +- coeff_blk.offset, +- coeff_blk.len, +- coeff_blk.name, +- coeff_blk.name_len, +- coeff_blk.flags, +- coeff_blk.ctl_type); +- if (ret < 0) +- cs_dsp_err(dsp, "Failed to create control: %.*s, %d\n", +- coeff_blk.name_len, coeff_blk.name, ret); +- } +- +- return 0; +-} +- +-static unsigned int cs_dsp_adsp1_parse_sizes(struct cs_dsp *dsp, +- const char * const file, +- unsigned int pos, +- const struct firmware *firmware) +-{ +- const struct wmfw_adsp1_sizes *adsp1_sizes; +- +- adsp1_sizes = (void *)&firmware->data[pos]; +- +- cs_dsp_dbg(dsp, "%s: %d DM, %d PM, %d ZM\n", file, +- le32_to_cpu(adsp1_sizes->dm), le32_to_cpu(adsp1_sizes->pm), +- le32_to_cpu(adsp1_sizes->zm)); +- +- return pos + sizeof(*adsp1_sizes); +-} +- +-static void wm_adsp_release_firmware_files(struct wm_adsp *dsp, +- const struct firmware *wmfw_firmware, +- char *wmfw_filename, +- const struct firmware *coeff_firmware, +- char *coeff_filename) +-{ +- if (wmfw_firmware) +- release_firmware(wmfw_firmware); +- kfree(wmfw_filename); +- +- if (coeff_firmware) +- release_firmware(coeff_firmware); +- kfree(coeff_filename); +-} +- +-static int wm_adsp_request_firmware_file(struct wm_adsp *dsp, +- const struct firmware **firmware, +- char **filename, +- char *suffix) +-{ +- struct cs_dsp *cs_dsp = &dsp->cs_dsp; +- int ret = 0; +- +- *filename = kasprintf(GFP_KERNEL, "%s-%s-%s.%s", dsp->part, dsp->fwf_name, +- wm_adsp_fw[dsp->fw].file, suffix); +- if (*filename == NULL) +- return -ENOMEM; +- +- ret = request_firmware(firmware, *filename, cs_dsp->dev); +- if (ret != 0) { +- adsp_err(dsp, "Failed to request '%s'\n", *filename); +- kfree(*filename); +- *filename = NULL; +- } +- +- return ret; +-} +- +-static int wm_adsp_request_firmware_files(struct wm_adsp *dsp, +- const struct firmware **wmfw_firmware, +- char **wmfw_filename, +- const struct firmware **coeff_firmware, +- char **coeff_filename) +-{ +- int ret = 0; +- +- ret = wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename, "wmfw"); +- if (ret != 0) +- return ret; +- +- wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename, "bin"); +- +- return 0; +-} +- +-static unsigned int cs_dsp_adsp2_parse_sizes(struct cs_dsp *dsp, +- const char * const file, +- unsigned int pos, +- const struct firmware *firmware) +-{ +- const struct wmfw_adsp2_sizes *adsp2_sizes; +- +- adsp2_sizes = (void *)&firmware->data[pos]; +- +- cs_dsp_dbg(dsp, "%s: %d XM, %d YM %d PM, %d ZM\n", file, +- le32_to_cpu(adsp2_sizes->xm), le32_to_cpu(adsp2_sizes->ym), +- le32_to_cpu(adsp2_sizes->pm), le32_to_cpu(adsp2_sizes->zm)); +- +- return pos + sizeof(*adsp2_sizes); +-} +- +-static bool cs_dsp_validate_version(struct cs_dsp *dsp, unsigned int version) +-{ +- switch (version) { +- case 0: +- cs_dsp_warn(dsp, "Deprecated file format %d\n", version); +- return true; +- case 1: +- case 2: +- return true; +- default: +- return false; +- } +-} +- +-static bool cs_dsp_halo_validate_version(struct cs_dsp *dsp, unsigned int version) +-{ +- switch (version) { +- case 3: +- return true; +- default: +- return false; +- } +-} +- +-static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware, +- const char *file) +-{ +- LIST_HEAD(buf_list); +- struct regmap *regmap = dsp->regmap; +- unsigned int pos = 0; +- const struct wmfw_header *header; +- const struct wmfw_adsp1_sizes *adsp1_sizes; +- const struct wmfw_footer *footer; +- const struct wmfw_region *region; +- const struct cs_dsp_region *mem; +- const char *region_name; +- char *text = NULL; +- struct cs_dsp_buf *buf; +- unsigned int reg; +- int regions = 0; +- int ret, offset, type; +- +- ret = -EINVAL; +- +- pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer); +- if (pos >= firmware->size) { +- cs_dsp_err(dsp, "%s: file too short, %zu bytes\n", +- file, firmware->size); +- goto out_fw; +- } +- +- header = (void *)&firmware->data[0]; +- +- if (memcmp(&header->magic[0], "WMFW", 4) != 0) { +- cs_dsp_err(dsp, "%s: invalid magic\n", file); +- goto out_fw; +- } +- +- if (!dsp->ops->validate_version(dsp, header->ver)) { +- cs_dsp_err(dsp, "%s: unknown file format %d\n", +- file, header->ver); +- goto out_fw; +- } +- +- cs_dsp_info(dsp, "Firmware version: %d\n", header->ver); +- dsp->fw_ver = header->ver; +- +- if (header->core != dsp->type) { +- cs_dsp_err(dsp, "%s: invalid core %d != %d\n", +- file, header->core, dsp->type); +- goto out_fw; +- } +- +- pos = sizeof(*header); +- pos = dsp->ops->parse_sizes(dsp, file, pos, firmware); +- +- footer = (void *)&firmware->data[pos]; +- pos += sizeof(*footer); +- +- if (le32_to_cpu(header->len) != pos) { +- cs_dsp_err(dsp, "%s: unexpected header length %d\n", +- file, le32_to_cpu(header->len)); +- goto out_fw; +- } +- +- cs_dsp_dbg(dsp, "%s: timestamp %llu\n", file, +- le64_to_cpu(footer->timestamp)); +- +- while (pos < firmware->size && +- sizeof(*region) < firmware->size - pos) { +- region = (void *)&(firmware->data[pos]); +- region_name = "Unknown"; +- reg = 0; +- text = NULL; +- offset = le32_to_cpu(region->offset) & 0xffffff; +- type = be32_to_cpu(region->type) & 0xff; +- +- switch (type) { +- case WMFW_NAME_TEXT: +- region_name = "Firmware name"; +- text = kzalloc(le32_to_cpu(region->len) + 1, +- GFP_KERNEL); +- break; +- case WMFW_ALGORITHM_DATA: +- region_name = "Algorithm"; +- ret = cs_dsp_parse_coeff(dsp, region); +- if (ret != 0) +- goto out_fw; +- break; +- case WMFW_INFO_TEXT: +- region_name = "Information"; +- text = kzalloc(le32_to_cpu(region->len) + 1, +- GFP_KERNEL); +- break; +- case WMFW_ABSOLUTE: +- region_name = "Absolute"; +- reg = offset; +- break; +- case WMFW_ADSP1_PM: +- case WMFW_ADSP1_DM: +- case WMFW_ADSP2_XM: +- case WMFW_ADSP2_YM: +- case WMFW_ADSP1_ZM: +- case WMFW_HALO_PM_PACKED: +- case WMFW_HALO_XM_PACKED: +- case WMFW_HALO_YM_PACKED: +- mem = cs_dsp_find_region(dsp, type); +- if (!mem) { +- cs_dsp_err(dsp, "No region of type: %x\n", type); +- ret = -EINVAL; +- goto out_fw; +- } +- +- region_name = cs_dsp_mem_region_name(type); +- reg = dsp->ops->region_to_reg(mem, offset); +- break; +- default: +- cs_dsp_warn(dsp, +- "%s.%d: Unknown region type %x at %d(%x)\n", +- file, regions, type, pos, pos); +- break; +- } +- +- cs_dsp_dbg(dsp, "%s.%d: %d bytes at %d in %s\n", file, +- regions, le32_to_cpu(region->len), offset, +- region_name); +- +- if (le32_to_cpu(region->len) > +- firmware->size - pos - sizeof(*region)) { +- cs_dsp_err(dsp, +- "%s.%d: %s region len %d bytes exceeds file length %zu\n", +- file, regions, region_name, +- le32_to_cpu(region->len), firmware->size); +- ret = -EINVAL; +- goto out_fw; +- } +- +- if (text) { +- memcpy(text, region->data, le32_to_cpu(region->len)); +- cs_dsp_info(dsp, "%s: %s\n", file, text); +- kfree(text); +- text = NULL; +- } +- +- if (reg) { +- buf = cs_dsp_buf_alloc(region->data, +- le32_to_cpu(region->len), +- &buf_list); +- if (!buf) { +- cs_dsp_err(dsp, "Out of memory\n"); +- ret = -ENOMEM; +- goto out_fw; +- } +- +- ret = regmap_raw_write_async(regmap, reg, buf->buf, +- le32_to_cpu(region->len)); +- if (ret != 0) { +- cs_dsp_err(dsp, +- "%s.%d: Failed to write %d bytes at %d in %s: %d\n", +- file, regions, +- le32_to_cpu(region->len), offset, +- region_name, ret); +- goto out_fw; +- } +- } +- +- pos += le32_to_cpu(region->len) + sizeof(*region); +- regions++; +- } +- +- ret = regmap_async_complete(regmap); +- if (ret != 0) { +- cs_dsp_err(dsp, "Failed to complete async write: %d\n", ret); +- goto out_fw; +- } +- +- if (pos > firmware->size) +- cs_dsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", +- file, regions, pos - firmware->size); +- +- cs_dsp_debugfs_save_wmfwname(dsp, file); +- +-out_fw: +- regmap_async_complete(regmap); +- cs_dsp_buf_free(&buf_list); +- kfree(text); +- +- return ret; +-} +- +-/* +- * Find cs_dsp_coeff_ctl with input name as its subname +- * If not found, return NULL +- */ +-static struct cs_dsp_coeff_ctl *cs_dsp_get_ctl(struct cs_dsp *dsp, +- const char *name, int type, +- unsigned int alg) +-{ +- struct cs_dsp_coeff_ctl *pos, *rslt = NULL; +- +- list_for_each_entry(pos, &dsp->ctl_list, list) { +- if (!pos->subname) +- continue; +- if (strncmp(pos->subname, name, pos->subname_len) == 0 && +- pos->fw_name == dsp->fw_name && +- pos->alg_region.alg == alg && +- pos->alg_region.type == type) { +- rslt = pos; +- break; +- } +- } +- +- return rslt; +-} +- + int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type, + unsigned int alg, void *buf, size_t len) + { +@@ -2175,666 +743,57 @@ int wm_adsp_read_ctl(struct wm_adsp *dsp, const char *name, int type, + } + EXPORT_SYMBOL_GPL(wm_adsp_read_ctl); + +-static void cs_dsp_ctl_fixup_base(struct cs_dsp *dsp, +- const struct cs_dsp_alg_region *alg_region) +-{ +- struct cs_dsp_coeff_ctl *ctl; +- +- list_for_each_entry(ctl, &dsp->ctl_list, list) { +- if (ctl->fw_name == dsp->fw_name && +- alg_region->alg == ctl->alg_region.alg && +- alg_region->type == ctl->alg_region.type) { +- ctl->alg_region.base = alg_region->base; +- } +- } +-} +- +-static void *cs_dsp_read_algs(struct cs_dsp *dsp, size_t n_algs, +- const struct cs_dsp_region *mem, +- unsigned int pos, unsigned int len) +-{ +- void *alg; +- unsigned int reg; +- int ret; +- __be32 val; +- +- if (n_algs == 0) { +- cs_dsp_err(dsp, "No algorithms\n"); +- return ERR_PTR(-EINVAL); +- } +- +- if (n_algs > 1024) { +- cs_dsp_err(dsp, "Algorithm count %zx excessive\n", n_algs); +- return ERR_PTR(-EINVAL); +- } +- +- /* Read the terminator first to validate the length */ +- reg = dsp->ops->region_to_reg(mem, pos + len); +- +- ret = regmap_raw_read(dsp->regmap, reg, &val, sizeof(val)); +- if (ret != 0) { +- cs_dsp_err(dsp, "Failed to read algorithm list end: %d\n", +- ret); +- return ERR_PTR(ret); +- } +- +- if (be32_to_cpu(val) != 0xbedead) +- cs_dsp_warn(dsp, "Algorithm list end %x 0x%x != 0xbedead\n", +- reg, be32_to_cpu(val)); +- +- /* Convert length from DSP words to bytes */ +- len *= sizeof(u32); +- +- alg = kzalloc(len, GFP_KERNEL | GFP_DMA); +- if (!alg) +- return ERR_PTR(-ENOMEM); +- +- reg = dsp->ops->region_to_reg(mem, pos); +- +- ret = regmap_raw_read(dsp->regmap, reg, alg, len); +- if (ret != 0) { +- cs_dsp_err(dsp, "Failed to read algorithm list: %d\n", ret); +- kfree(alg); +- return ERR_PTR(ret); +- } +- +- return alg; +-} +- +-static struct cs_dsp_alg_region * +- cs_dsp_find_alg_region(struct cs_dsp *dsp, int type, unsigned int id) +-{ +- struct cs_dsp_alg_region *alg_region; +- +- list_for_each_entry(alg_region, &dsp->alg_regions, list) { +- if (id == alg_region->alg && type == alg_region->type) +- return alg_region; +- } +- +- return NULL; +-} +- +-static struct cs_dsp_alg_region *cs_dsp_create_region(struct cs_dsp *dsp, +- int type, __be32 id, +- __be32 base) +-{ +- struct cs_dsp_alg_region *alg_region; +- +- alg_region = kzalloc(sizeof(*alg_region), GFP_KERNEL); +- if (!alg_region) +- return ERR_PTR(-ENOMEM); +- +- alg_region->type = type; +- alg_region->alg = be32_to_cpu(id); +- alg_region->base = be32_to_cpu(base); +- +- list_add_tail(&alg_region->list, &dsp->alg_regions); +- +- if (dsp->fw_ver > 0) +- cs_dsp_ctl_fixup_base(dsp, alg_region); +- +- return alg_region; +-} +- +-static void cs_dsp_free_alg_regions(struct cs_dsp *dsp) +-{ +- struct cs_dsp_alg_region *alg_region; +- +- while (!list_empty(&dsp->alg_regions)) { +- alg_region = list_first_entry(&dsp->alg_regions, +- struct cs_dsp_alg_region, +- list); +- list_del(&alg_region->list); +- kfree(alg_region); +- } +-} +- +-static void cs_dsp_parse_wmfw_id_header(struct cs_dsp *dsp, +- struct wmfw_id_hdr *fw, int nalgs) +-{ +- dsp->fw_id = be32_to_cpu(fw->id); +- dsp->fw_id_version = be32_to_cpu(fw->ver); +- +- cs_dsp_info(dsp, "Firmware: %x v%d.%d.%d, %d algorithms\n", +- dsp->fw_id, (dsp->fw_id_version & 0xff0000) >> 16, +- (dsp->fw_id_version & 0xff00) >> 8, dsp->fw_id_version & 0xff, +- nalgs); +-} +- +-static void cs_dsp_parse_wmfw_v3_id_header(struct cs_dsp *dsp, +- struct wmfw_v3_id_hdr *fw, int nalgs) +-{ +- dsp->fw_id = be32_to_cpu(fw->id); +- dsp->fw_id_version = be32_to_cpu(fw->ver); +- dsp->fw_vendor_id = be32_to_cpu(fw->vendor_id); +- +- cs_dsp_info(dsp, "Firmware: %x vendor: 0x%x v%d.%d.%d, %d algorithms\n", +- dsp->fw_id, dsp->fw_vendor_id, +- (dsp->fw_id_version & 0xff0000) >> 16, +- (dsp->fw_id_version & 0xff00) >> 8, dsp->fw_id_version & 0xff, +- nalgs); +-} +- +-static int cs_dsp_create_regions(struct cs_dsp *dsp, __be32 id, int nregions, +- const int *type, __be32 *base) +-{ +- struct cs_dsp_alg_region *alg_region; +- int i; +- +- for (i = 0; i < nregions; i++) { +- alg_region = cs_dsp_create_region(dsp, type[i], id, base[i]); +- if (IS_ERR(alg_region)) +- return PTR_ERR(alg_region); +- } +- +- return 0; +-} +- +-static int cs_dsp_adsp1_setup_algs(struct cs_dsp *dsp) +-{ +- struct wmfw_adsp1_id_hdr adsp1_id; +- struct wmfw_adsp1_alg_hdr *adsp1_alg; +- struct cs_dsp_alg_region *alg_region; +- const struct cs_dsp_region *mem; +- unsigned int pos, len; +- size_t n_algs; +- int i, ret; +- +- mem = cs_dsp_find_region(dsp, WMFW_ADSP1_DM); +- if (WARN_ON(!mem)) +- return -EINVAL; +- +- ret = regmap_raw_read(dsp->regmap, mem->base, &adsp1_id, +- sizeof(adsp1_id)); +- if (ret != 0) { +- cs_dsp_err(dsp, "Failed to read algorithm info: %d\n", +- ret); +- return ret; +- } +- +- n_algs = be32_to_cpu(adsp1_id.n_algs); +- +- cs_dsp_parse_wmfw_id_header(dsp, &adsp1_id.fw, n_algs); +- +- alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_ZM, +- adsp1_id.fw.id, adsp1_id.zm); +- if (IS_ERR(alg_region)) +- return PTR_ERR(alg_region); +- +- alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_DM, +- adsp1_id.fw.id, adsp1_id.dm); +- if (IS_ERR(alg_region)) +- return PTR_ERR(alg_region); +- +- /* Calculate offset and length in DSP words */ +- pos = sizeof(adsp1_id) / sizeof(u32); +- len = (sizeof(*adsp1_alg) * n_algs) / sizeof(u32); +- +- adsp1_alg = cs_dsp_read_algs(dsp, n_algs, mem, pos, len); +- if (IS_ERR(adsp1_alg)) +- return PTR_ERR(adsp1_alg); +- +- for (i = 0; i < n_algs; i++) { +- cs_dsp_info(dsp, "%d: ID %x v%d.%d.%d DM@%x ZM@%x\n", +- i, be32_to_cpu(adsp1_alg[i].alg.id), +- (be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff0000) >> 16, +- (be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff00) >> 8, +- be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff, +- be32_to_cpu(adsp1_alg[i].dm), +- be32_to_cpu(adsp1_alg[i].zm)); +- +- alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_DM, +- adsp1_alg[i].alg.id, +- adsp1_alg[i].dm); +- if (IS_ERR(alg_region)) { +- ret = PTR_ERR(alg_region); +- goto out; +- } +- if (dsp->fw_ver == 0) { +- if (i + 1 < n_algs) { +- len = be32_to_cpu(adsp1_alg[i + 1].dm); +- len -= be32_to_cpu(adsp1_alg[i].dm); +- len *= 4; +- cs_dsp_create_control(dsp, alg_region, 0, +- len, NULL, 0, 0, +- WMFW_CTL_TYPE_BYTES); +- } else { +- cs_dsp_warn(dsp, "Missing length info for region DM with ID %x\n", +- be32_to_cpu(adsp1_alg[i].alg.id)); +- } +- } +- +- alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_ZM, +- adsp1_alg[i].alg.id, +- adsp1_alg[i].zm); +- if (IS_ERR(alg_region)) { +- ret = PTR_ERR(alg_region); +- goto out; +- } +- if (dsp->fw_ver == 0) { +- if (i + 1 < n_algs) { +- len = be32_to_cpu(adsp1_alg[i + 1].zm); +- len -= be32_to_cpu(adsp1_alg[i].zm); +- len *= 4; +- cs_dsp_create_control(dsp, alg_region, 0, +- len, NULL, 0, 0, +- WMFW_CTL_TYPE_BYTES); +- } else { +- cs_dsp_warn(dsp, "Missing length info for region ZM with ID %x\n", +- be32_to_cpu(adsp1_alg[i].alg.id)); +- } +- } +- } +- +-out: +- kfree(adsp1_alg); +- return ret; +-} +- +-static int cs_dsp_adsp2_setup_algs(struct cs_dsp *dsp) +-{ +- struct wmfw_adsp2_id_hdr adsp2_id; +- struct wmfw_adsp2_alg_hdr *adsp2_alg; +- struct cs_dsp_alg_region *alg_region; +- const struct cs_dsp_region *mem; +- unsigned int pos, len; +- size_t n_algs; +- int i, ret; +- +- mem = cs_dsp_find_region(dsp, WMFW_ADSP2_XM); +- if (WARN_ON(!mem)) +- return -EINVAL; +- +- ret = regmap_raw_read(dsp->regmap, mem->base, &adsp2_id, +- sizeof(adsp2_id)); +- if (ret != 0) { +- cs_dsp_err(dsp, "Failed to read algorithm info: %d\n", +- ret); +- return ret; +- } +- +- n_algs = be32_to_cpu(adsp2_id.n_algs); +- +- cs_dsp_parse_wmfw_id_header(dsp, &adsp2_id.fw, n_algs); +- +- alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_XM, +- adsp2_id.fw.id, adsp2_id.xm); +- if (IS_ERR(alg_region)) +- return PTR_ERR(alg_region); +- +- alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_YM, +- adsp2_id.fw.id, adsp2_id.ym); +- if (IS_ERR(alg_region)) +- return PTR_ERR(alg_region); +- +- alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_ZM, +- adsp2_id.fw.id, adsp2_id.zm); +- if (IS_ERR(alg_region)) +- return PTR_ERR(alg_region); +- +- /* Calculate offset and length in DSP words */ +- pos = sizeof(adsp2_id) / sizeof(u32); +- len = (sizeof(*adsp2_alg) * n_algs) / sizeof(u32); +- +- adsp2_alg = cs_dsp_read_algs(dsp, n_algs, mem, pos, len); +- if (IS_ERR(adsp2_alg)) +- return PTR_ERR(adsp2_alg); +- +- for (i = 0; i < n_algs; i++) { +- cs_dsp_info(dsp, +- "%d: ID %x v%d.%d.%d XM@%x YM@%x ZM@%x\n", +- i, be32_to_cpu(adsp2_alg[i].alg.id), +- (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff0000) >> 16, +- (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff00) >> 8, +- be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff, +- be32_to_cpu(adsp2_alg[i].xm), +- be32_to_cpu(adsp2_alg[i].ym), +- be32_to_cpu(adsp2_alg[i].zm)); +- +- alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_XM, +- adsp2_alg[i].alg.id, +- adsp2_alg[i].xm); +- if (IS_ERR(alg_region)) { +- ret = PTR_ERR(alg_region); +- goto out; +- } +- if (dsp->fw_ver == 0) { +- if (i + 1 < n_algs) { +- len = be32_to_cpu(adsp2_alg[i + 1].xm); +- len -= be32_to_cpu(adsp2_alg[i].xm); +- len *= 4; +- cs_dsp_create_control(dsp, alg_region, 0, +- len, NULL, 0, 0, +- WMFW_CTL_TYPE_BYTES); +- } else { +- cs_dsp_warn(dsp, "Missing length info for region XM with ID %x\n", +- be32_to_cpu(adsp2_alg[i].alg.id)); +- } +- } +- +- alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_YM, +- adsp2_alg[i].alg.id, +- adsp2_alg[i].ym); +- if (IS_ERR(alg_region)) { +- ret = PTR_ERR(alg_region); +- goto out; +- } +- if (dsp->fw_ver == 0) { +- if (i + 1 < n_algs) { +- len = be32_to_cpu(adsp2_alg[i + 1].ym); +- len -= be32_to_cpu(adsp2_alg[i].ym); +- len *= 4; +- cs_dsp_create_control(dsp, alg_region, 0, +- len, NULL, 0, 0, +- WMFW_CTL_TYPE_BYTES); +- } else { +- cs_dsp_warn(dsp, "Missing length info for region YM with ID %x\n", +- be32_to_cpu(adsp2_alg[i].alg.id)); +- } +- } +- +- alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_ZM, +- adsp2_alg[i].alg.id, +- adsp2_alg[i].zm); +- if (IS_ERR(alg_region)) { +- ret = PTR_ERR(alg_region); +- goto out; +- } +- if (dsp->fw_ver == 0) { +- if (i + 1 < n_algs) { +- len = be32_to_cpu(adsp2_alg[i + 1].zm); +- len -= be32_to_cpu(adsp2_alg[i].zm); +- len *= 4; +- cs_dsp_create_control(dsp, alg_region, 0, +- len, NULL, 0, 0, +- WMFW_CTL_TYPE_BYTES); +- } else { +- cs_dsp_warn(dsp, "Missing length info for region ZM with ID %x\n", +- be32_to_cpu(adsp2_alg[i].alg.id)); +- } +- } +- } +- +-out: +- kfree(adsp2_alg); +- return ret; +-} +- +-static int cs_dsp_halo_create_regions(struct cs_dsp *dsp, __be32 id, +- __be32 xm_base, __be32 ym_base) ++static void wm_adsp_release_firmware_files(struct wm_adsp *dsp, ++ const struct firmware *wmfw_firmware, ++ char *wmfw_filename, ++ const struct firmware *coeff_firmware, ++ char *coeff_filename) + { +- static const int types[] = { +- WMFW_ADSP2_XM, WMFW_HALO_XM_PACKED, +- WMFW_ADSP2_YM, WMFW_HALO_YM_PACKED +- }; +- __be32 bases[] = { xm_base, xm_base, ym_base, ym_base }; ++ if (wmfw_firmware) ++ release_firmware(wmfw_firmware); ++ kfree(wmfw_filename); + +- return cs_dsp_create_regions(dsp, id, ARRAY_SIZE(types), types, bases); ++ if (coeff_firmware) ++ release_firmware(coeff_firmware); ++ kfree(coeff_filename); + } + +-static int cs_dsp_halo_setup_algs(struct cs_dsp *dsp) ++static int wm_adsp_request_firmware_file(struct wm_adsp *dsp, ++ const struct firmware **firmware, ++ char **filename, ++ char *suffix) + { +- struct wmfw_halo_id_hdr halo_id; +- struct wmfw_halo_alg_hdr *halo_alg; +- const struct cs_dsp_region *mem; +- unsigned int pos, len; +- size_t n_algs; +- int i, ret; ++ struct cs_dsp *cs_dsp = &dsp->cs_dsp; ++ int ret = 0; + +- mem = cs_dsp_find_region(dsp, WMFW_ADSP2_XM); +- if (WARN_ON(!mem)) +- return -EINVAL; ++ *filename = kasprintf(GFP_KERNEL, "%s-%s-%s.%s", dsp->part, dsp->fwf_name, ++ wm_adsp_fw[dsp->fw].file, suffix); ++ if (*filename == NULL) ++ return -ENOMEM; + +- ret = regmap_raw_read(dsp->regmap, mem->base, &halo_id, +- sizeof(halo_id)); ++ ret = request_firmware(firmware, *filename, cs_dsp->dev); + if (ret != 0) { +- cs_dsp_err(dsp, "Failed to read algorithm info: %d\n", +- ret); +- return ret; +- } +- +- n_algs = be32_to_cpu(halo_id.n_algs); +- +- cs_dsp_parse_wmfw_v3_id_header(dsp, &halo_id.fw, n_algs); +- +- ret = cs_dsp_halo_create_regions(dsp, halo_id.fw.id, +- halo_id.xm_base, halo_id.ym_base); +- if (ret) +- return ret; +- +- /* Calculate offset and length in DSP words */ +- pos = sizeof(halo_id) / sizeof(u32); +- len = (sizeof(*halo_alg) * n_algs) / sizeof(u32); +- +- halo_alg = cs_dsp_read_algs(dsp, n_algs, mem, pos, len); +- if (IS_ERR(halo_alg)) +- return PTR_ERR(halo_alg); +- +- for (i = 0; i < n_algs; i++) { +- cs_dsp_info(dsp, +- "%d: ID %x v%d.%d.%d XM@%x YM@%x\n", +- i, be32_to_cpu(halo_alg[i].alg.id), +- (be32_to_cpu(halo_alg[i].alg.ver) & 0xff0000) >> 16, +- (be32_to_cpu(halo_alg[i].alg.ver) & 0xff00) >> 8, +- be32_to_cpu(halo_alg[i].alg.ver) & 0xff, +- be32_to_cpu(halo_alg[i].xm_base), +- be32_to_cpu(halo_alg[i].ym_base)); +- +- ret = cs_dsp_halo_create_regions(dsp, halo_alg[i].alg.id, +- halo_alg[i].xm_base, +- halo_alg[i].ym_base); +- if (ret) +- goto out; ++ adsp_err(dsp, "Failed to request '%s'\n", *filename); ++ kfree(*filename); ++ *filename = NULL; + } + +-out: +- kfree(halo_alg); + return ret; + } + +-static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware, +- const char *file) ++static int wm_adsp_request_firmware_files(struct wm_adsp *dsp, ++ const struct firmware **wmfw_firmware, ++ char **wmfw_filename, ++ const struct firmware **coeff_firmware, ++ char **coeff_filename) + { +- LIST_HEAD(buf_list); +- struct regmap *regmap = dsp->regmap; +- struct wmfw_coeff_hdr *hdr; +- struct wmfw_coeff_item *blk; +- const struct cs_dsp_region *mem; +- struct cs_dsp_alg_region *alg_region; +- const char *region_name; +- int ret, pos, blocks, type, offset, reg; +- struct cs_dsp_buf *buf; +- +- if (!firmware) +- return 0; +- +- ret = -EINVAL; +- +- if (sizeof(*hdr) >= firmware->size) { +- cs_dsp_err(dsp, "%s: coefficient file too short, %zu bytes\n", +- file, firmware->size); +- goto out_fw; +- } +- +- hdr = (void *)&firmware->data[0]; +- if (memcmp(hdr->magic, "WMDR", 4) != 0) { +- cs_dsp_err(dsp, "%s: invalid coefficient magic\n", file); +- goto out_fw; +- } +- +- switch (be32_to_cpu(hdr->rev) & 0xff) { +- case 1: +- break; +- default: +- cs_dsp_err(dsp, "%s: Unsupported coefficient file format %d\n", +- file, be32_to_cpu(hdr->rev) & 0xff); +- ret = -EINVAL; +- goto out_fw; +- } +- +- cs_dsp_dbg(dsp, "%s: v%d.%d.%d\n", file, +- (le32_to_cpu(hdr->ver) >> 16) & 0xff, +- (le32_to_cpu(hdr->ver) >> 8) & 0xff, +- le32_to_cpu(hdr->ver) & 0xff); +- +- pos = le32_to_cpu(hdr->len); +- +- blocks = 0; +- while (pos < firmware->size && +- sizeof(*blk) < firmware->size - pos) { +- blk = (void *)(&firmware->data[pos]); +- +- type = le16_to_cpu(blk->type); +- offset = le16_to_cpu(blk->offset); +- +- cs_dsp_dbg(dsp, "%s.%d: %x v%d.%d.%d\n", +- file, blocks, le32_to_cpu(blk->id), +- (le32_to_cpu(blk->ver) >> 16) & 0xff, +- (le32_to_cpu(blk->ver) >> 8) & 0xff, +- le32_to_cpu(blk->ver) & 0xff); +- cs_dsp_dbg(dsp, "%s.%d: %d bytes at 0x%x in %x\n", +- file, blocks, le32_to_cpu(blk->len), offset, type); +- +- reg = 0; +- region_name = "Unknown"; +- switch (type) { +- case (WMFW_NAME_TEXT << 8): +- case (WMFW_INFO_TEXT << 8): +- case (WMFW_METADATA << 8): +- break; +- case (WMFW_ABSOLUTE << 8): +- /* +- * Old files may use this for global +- * coefficients. +- */ +- if (le32_to_cpu(blk->id) == dsp->fw_id && +- offset == 0) { +- region_name = "global coefficients"; +- mem = cs_dsp_find_region(dsp, type); +- if (!mem) { +- cs_dsp_err(dsp, "No ZM\n"); +- break; +- } +- reg = dsp->ops->region_to_reg(mem, 0); +- +- } else { +- region_name = "register"; +- reg = offset; +- } +- break; +- +- case WMFW_ADSP1_DM: +- case WMFW_ADSP1_ZM: +- case WMFW_ADSP2_XM: +- case WMFW_ADSP2_YM: +- case WMFW_HALO_XM_PACKED: +- case WMFW_HALO_YM_PACKED: +- case WMFW_HALO_PM_PACKED: +- cs_dsp_dbg(dsp, "%s.%d: %d bytes in %x for %x\n", +- file, blocks, le32_to_cpu(blk->len), +- type, le32_to_cpu(blk->id)); +- +- mem = cs_dsp_find_region(dsp, type); +- if (!mem) { +- cs_dsp_err(dsp, "No base for region %x\n", type); +- break; +- } +- +- alg_region = cs_dsp_find_alg_region(dsp, type, +- le32_to_cpu(blk->id)); +- if (alg_region) { +- reg = alg_region->base; +- reg = dsp->ops->region_to_reg(mem, reg); +- reg += offset; +- } else { +- cs_dsp_err(dsp, "No %x for algorithm %x\n", +- type, le32_to_cpu(blk->id)); +- } +- break; +- +- default: +- cs_dsp_err(dsp, "%s.%d: Unknown region type %x at %d\n", +- file, blocks, type, pos); +- break; +- } +- +- if (reg) { +- if (le32_to_cpu(blk->len) > +- firmware->size - pos - sizeof(*blk)) { +- cs_dsp_err(dsp, +- "%s.%d: %s region len %d bytes exceeds file length %zu\n", +- file, blocks, region_name, +- le32_to_cpu(blk->len), +- firmware->size); +- ret = -EINVAL; +- goto out_fw; +- } +- +- buf = cs_dsp_buf_alloc(blk->data, +- le32_to_cpu(blk->len), +- &buf_list); +- if (!buf) { +- cs_dsp_err(dsp, "Out of memory\n"); +- ret = -ENOMEM; +- goto out_fw; +- } +- +- cs_dsp_dbg(dsp, "%s.%d: Writing %d bytes at %x\n", +- file, blocks, le32_to_cpu(blk->len), +- reg); +- ret = regmap_raw_write_async(regmap, reg, buf->buf, +- le32_to_cpu(blk->len)); +- if (ret != 0) { +- cs_dsp_err(dsp, +- "%s.%d: Failed to write to %x in %s: %d\n", +- file, blocks, reg, region_name, ret); +- } +- } +- +- pos += (le32_to_cpu(blk->len) + sizeof(*blk) + 3) & ~0x03; +- blocks++; +- } ++ int ret = 0; + +- ret = regmap_async_complete(regmap); ++ ret = wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename, "wmfw"); + if (ret != 0) +- cs_dsp_err(dsp, "Failed to complete async write: %d\n", ret); +- +- if (pos > firmware->size) +- cs_dsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", +- file, blocks, pos - firmware->size); +- +- cs_dsp_debugfs_save_binname(dsp, file); +- +-out_fw: +- regmap_async_complete(regmap); +- cs_dsp_buf_free(&buf_list); +- return ret; +-} +- +-static int cs_dsp_create_name(struct cs_dsp *dsp) +-{ +- if (!dsp->name) { +- dsp->name = devm_kasprintf(dsp->dev, GFP_KERNEL, "DSP%d", +- dsp->num); +- if (!dsp->name) +- return -ENOMEM; +- } +- +- return 0; +-} +- +-static int cs_dsp_common_init(struct cs_dsp *dsp) +-{ +- int ret; +- +- ret = cs_dsp_create_name(dsp); +- if (ret) + return ret; + +- INIT_LIST_HEAD(&dsp->alg_regions); +- INIT_LIST_HEAD(&dsp->ctl_list); +- +- mutex_init(&dsp->pwr_lock); ++ wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename, "bin"); + + return 0; + } +@@ -2859,13 +818,6 @@ static int wm_adsp_common_init(struct wm_adsp *dsp) + return 0; + } + +-static int cs_dsp_adsp1_init(struct cs_dsp *dsp) +-{ +- dsp->ops = &cs_dsp_adsp1_ops; +- +- return cs_dsp_common_init(dsp); +-} +- + int wm_adsp1_init(struct wm_adsp *dsp) + { + int ret; +@@ -2880,113 +832,6 @@ int wm_adsp1_init(struct wm_adsp *dsp) + } + EXPORT_SYMBOL_GPL(wm_adsp1_init); + +-static int cs_dsp_adsp1_power_up(struct cs_dsp *dsp, +- const struct firmware *wmfw_firmware, char *wmfw_filename, +- const struct firmware *coeff_firmware, char *coeff_filename, +- const char *fw_name) +-{ +- unsigned int val; +- int ret; +- +- mutex_lock(&dsp->pwr_lock); +- +- dsp->fw_name = fw_name; +- +- regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, +- ADSP1_SYS_ENA, ADSP1_SYS_ENA); +- +- /* +- * For simplicity set the DSP clock rate to be the +- * SYSCLK rate rather than making it configurable. +- */ +- if (dsp->sysclk_reg) { +- ret = regmap_read(dsp->regmap, dsp->sysclk_reg, &val); +- if (ret != 0) { +- cs_dsp_err(dsp, "Failed to read SYSCLK state: %d\n", ret); +- goto err_mutex; +- } +- +- val = (val & dsp->sysclk_mask) >> dsp->sysclk_shift; +- +- ret = regmap_update_bits(dsp->regmap, +- dsp->base + ADSP1_CONTROL_31, +- ADSP1_CLK_SEL_MASK, val); +- if (ret != 0) { +- cs_dsp_err(dsp, "Failed to set clock rate: %d\n", ret); +- goto err_mutex; +- } +- } +- +- ret = cs_dsp_load(dsp, wmfw_firmware, wmfw_filename); +- if (ret != 0) +- goto err_ena; +- +- ret = cs_dsp_adsp1_setup_algs(dsp); +- if (ret != 0) +- goto err_ena; +- +- ret = cs_dsp_load_coeff(dsp, coeff_firmware, coeff_filename); +- if (ret != 0) +- goto err_ena; +- +- /* Initialize caches for enabled and unset controls */ +- ret = cs_dsp_coeff_init_control_caches(dsp); +- if (ret != 0) +- goto err_ena; +- +- /* Sync set controls */ +- ret = cs_dsp_coeff_sync_controls(dsp); +- if (ret != 0) +- goto err_ena; +- +- dsp->booted = true; +- +- /* Start the core running */ +- regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, +- ADSP1_CORE_ENA | ADSP1_START, +- ADSP1_CORE_ENA | ADSP1_START); +- +- dsp->running = true; +- +- mutex_unlock(&dsp->pwr_lock); +- +- return 0; +- +-err_ena: +- regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, +- ADSP1_SYS_ENA, 0); +-err_mutex: +- mutex_unlock(&dsp->pwr_lock); +- return ret; +-} +- +-static void cs_dsp_adsp1_power_down(struct cs_dsp *dsp) +-{ +- struct cs_dsp_coeff_ctl *ctl; +- +- mutex_lock(&dsp->pwr_lock); +- +- dsp->running = false; +- dsp->booted = false; +- +- /* Halt the core */ +- regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, +- ADSP1_CORE_ENA | ADSP1_START, 0); +- +- regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_19, +- ADSP1_WDMA_BUFFER_LENGTH_MASK, 0); +- +- regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, +- ADSP1_SYS_ENA, 0); +- +- list_for_each_entry(ctl, &dsp->ctl_list, list) +- ctl->enabled = 0; +- +- cs_dsp_free_alg_regions(dsp); +- +- mutex_unlock(&dsp->pwr_lock); +-} +- + int wm_adsp1_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +@@ -3030,148 +875,6 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, + } + EXPORT_SYMBOL_GPL(wm_adsp1_event); + +-static int cs_dsp_adsp2v2_enable_core(struct cs_dsp *dsp) +-{ +- unsigned int val; +- int ret, count; +- +- /* Wait for the RAM to start, should be near instantaneous */ +- for (count = 0; count < 10; ++count) { +- ret = regmap_read(dsp->regmap, dsp->base + ADSP2_STATUS1, &val); +- if (ret != 0) +- return ret; +- +- if (val & ADSP2_RAM_RDY) +- break; +- +- usleep_range(250, 500); +- } +- +- if (!(val & ADSP2_RAM_RDY)) { +- cs_dsp_err(dsp, "Failed to start DSP RAM\n"); +- return -EBUSY; +- } +- +- cs_dsp_dbg(dsp, "RAM ready after %d polls\n", count); +- +- return 0; +-} +- +-static int cs_dsp_adsp2_enable_core(struct cs_dsp *dsp) +-{ +- int ret; +- +- ret = regmap_update_bits_async(dsp->regmap, dsp->base + ADSP2_CONTROL, +- ADSP2_SYS_ENA, ADSP2_SYS_ENA); +- if (ret != 0) +- return ret; +- +- return cs_dsp_adsp2v2_enable_core(dsp); +-} +- +-static int cs_dsp_adsp2_lock(struct cs_dsp *dsp, unsigned int lock_regions) +-{ +- struct regmap *regmap = dsp->regmap; +- unsigned int code0, code1, lock_reg; +- +- if (!(lock_regions & CS_ADSP2_REGION_ALL)) +- return 0; +- +- lock_regions &= CS_ADSP2_REGION_ALL; +- lock_reg = dsp->base + ADSP2_LOCK_REGION_1_LOCK_REGION_0; +- +- while (lock_regions) { +- code0 = code1 = 0; +- if (lock_regions & BIT(0)) { +- code0 = ADSP2_LOCK_CODE_0; +- code1 = ADSP2_LOCK_CODE_1; +- } +- if (lock_regions & BIT(1)) { +- code0 |= ADSP2_LOCK_CODE_0 << ADSP2_LOCK_REGION_SHIFT; +- code1 |= ADSP2_LOCK_CODE_1 << ADSP2_LOCK_REGION_SHIFT; +- } +- regmap_write(regmap, lock_reg, code0); +- regmap_write(regmap, lock_reg, code1); +- lock_regions >>= 2; +- lock_reg += 2; +- } +- +- return 0; +-} +- +-static int cs_dsp_adsp2_enable_memory(struct cs_dsp *dsp) +-{ +- return regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, +- ADSP2_MEM_ENA, ADSP2_MEM_ENA); +-} +- +-static void cs_dsp_adsp2_disable_memory(struct cs_dsp *dsp) +-{ +- regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, +- ADSP2_MEM_ENA, 0); +-} +- +-static void cs_dsp_adsp2_disable_core(struct cs_dsp *dsp) +-{ +- regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0); +- regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0); +- regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_2, 0); +- +- regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, +- ADSP2_SYS_ENA, 0); +-} +- +-static void cs_dsp_adsp2v2_disable_core(struct cs_dsp *dsp) +-{ +- regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0); +- regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0); +- regmap_write(dsp->regmap, dsp->base + ADSP2V2_WDMA_CONFIG_2, 0); +-} +- +-static int cs_dsp_halo_configure_mpu(struct cs_dsp *dsp, unsigned int lock_regions) +-{ +- struct reg_sequence config[] = { +- { dsp->base + HALO_MPU_LOCK_CONFIG, 0x5555 }, +- { dsp->base + HALO_MPU_LOCK_CONFIG, 0xAAAA }, +- { dsp->base + HALO_MPU_XMEM_ACCESS_0, 0xFFFFFFFF }, +- { dsp->base + HALO_MPU_YMEM_ACCESS_0, 0xFFFFFFFF }, +- { dsp->base + HALO_MPU_WINDOW_ACCESS_0, lock_regions }, +- { dsp->base + HALO_MPU_XREG_ACCESS_0, lock_regions }, +- { dsp->base + HALO_MPU_YREG_ACCESS_0, lock_regions }, +- { dsp->base + HALO_MPU_XMEM_ACCESS_1, 0xFFFFFFFF }, +- { dsp->base + HALO_MPU_YMEM_ACCESS_1, 0xFFFFFFFF }, +- { dsp->base + HALO_MPU_WINDOW_ACCESS_1, lock_regions }, +- { dsp->base + HALO_MPU_XREG_ACCESS_1, lock_regions }, +- { dsp->base + HALO_MPU_YREG_ACCESS_1, lock_regions }, +- { dsp->base + HALO_MPU_XMEM_ACCESS_2, 0xFFFFFFFF }, +- { dsp->base + HALO_MPU_YMEM_ACCESS_2, 0xFFFFFFFF }, +- { dsp->base + HALO_MPU_WINDOW_ACCESS_2, lock_regions }, +- { dsp->base + HALO_MPU_XREG_ACCESS_2, lock_regions }, +- { dsp->base + HALO_MPU_YREG_ACCESS_2, lock_regions }, +- { dsp->base + HALO_MPU_XMEM_ACCESS_3, 0xFFFFFFFF }, +- { dsp->base + HALO_MPU_YMEM_ACCESS_3, 0xFFFFFFFF }, +- { dsp->base + HALO_MPU_WINDOW_ACCESS_3, lock_regions }, +- { dsp->base + HALO_MPU_XREG_ACCESS_3, lock_regions }, +- { dsp->base + HALO_MPU_YREG_ACCESS_3, lock_regions }, +- { dsp->base + HALO_MPU_LOCK_CONFIG, 0 }, +- }; +- +- return regmap_multi_reg_write(dsp->regmap, config, ARRAY_SIZE(config)); +-} +- +-static int cs_dsp_set_dspclk(struct cs_dsp *dsp, unsigned int freq) +-{ +- int ret; +- +- ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CLOCKING, +- ADSP2_CLK_SEL_MASK, +- freq << ADSP2_CLK_SEL_SHIFT); +- if (ret) +- cs_dsp_err(dsp, "Failed to set clock rate: %d\n", ret); +- +- return ret; +-} +- + int wm_adsp2_set_dspclk(struct snd_soc_dapm_widget *w, unsigned int freq) + { + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); +@@ -3225,104 +928,6 @@ int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol, + } + EXPORT_SYMBOL_GPL(wm_adsp2_preloader_put); + +-static void cs_dsp_stop_watchdog(struct cs_dsp *dsp) +-{ +- regmap_update_bits(dsp->regmap, dsp->base + ADSP2_WATCHDOG, +- ADSP2_WDT_ENA_MASK, 0); +-} +- +-static void cs_dsp_halo_stop_watchdog(struct cs_dsp *dsp) +-{ +- regmap_update_bits(dsp->regmap, dsp->base + HALO_WDT_CONTROL, +- HALO_WDT_EN_MASK, 0); +-} +- +-static int cs_dsp_power_up(struct cs_dsp *dsp, +- const struct firmware *wmfw_firmware, char *wmfw_filename, +- const struct firmware *coeff_firmware, char *coeff_filename, +- const char *fw_name) +-{ +- int ret; +- +- mutex_lock(&dsp->pwr_lock); +- +- dsp->fw_name = fw_name; +- +- if (dsp->ops->enable_memory) { +- ret = dsp->ops->enable_memory(dsp); +- if (ret != 0) +- goto err_mutex; +- } +- +- if (dsp->ops->enable_core) { +- ret = dsp->ops->enable_core(dsp); +- if (ret != 0) +- goto err_mem; +- } +- +- ret = cs_dsp_load(dsp, wmfw_firmware, wmfw_filename); +- if (ret != 0) +- goto err_ena; +- +- ret = dsp->ops->setup_algs(dsp); +- if (ret != 0) +- goto err_ena; +- +- ret = cs_dsp_load_coeff(dsp, coeff_firmware, coeff_filename); +- if (ret != 0) +- goto err_ena; +- +- /* Initialize caches for enabled and unset controls */ +- ret = cs_dsp_coeff_init_control_caches(dsp); +- if (ret != 0) +- goto err_ena; +- +- if (dsp->ops->disable_core) +- dsp->ops->disable_core(dsp); +- +- dsp->booted = true; +- +- mutex_unlock(&dsp->pwr_lock); +- +- return 0; +-err_ena: +- if (dsp->ops->disable_core) +- dsp->ops->disable_core(dsp); +-err_mem: +- if (dsp->ops->disable_memory) +- dsp->ops->disable_memory(dsp); +-err_mutex: +- mutex_unlock(&dsp->pwr_lock); +- +- return ret; +-} +- +-static void cs_dsp_power_down(struct cs_dsp *dsp) +-{ +- struct cs_dsp_coeff_ctl *ctl; +- +- mutex_lock(&dsp->pwr_lock); +- +- cs_dsp_debugfs_clear(dsp); +- +- dsp->fw_id = 0; +- dsp->fw_id_version = 0; +- +- dsp->booted = false; +- +- if (dsp->ops->disable_memory) +- dsp->ops->disable_memory(dsp); +- +- list_for_each_entry(ctl, &dsp->ctl_list, list) +- ctl->enabled = 0; +- +- cs_dsp_free_alg_regions(dsp); +- +- mutex_unlock(&dsp->pwr_lock); +- +- cs_dsp_dbg(dsp, "Shutdown complete\n"); +-} +- + static void wm_adsp_boot_work(struct work_struct *work) + { + struct wm_adsp *dsp = container_of(work, +@@ -3372,19 +977,6 @@ int wm_adsp_early_event(struct snd_soc_dapm_widget *w, + } + EXPORT_SYMBOL_GPL(wm_adsp_early_event); + +-static int cs_dsp_adsp2_start_core(struct cs_dsp *dsp) +-{ +- return regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, +- ADSP2_CORE_ENA | ADSP2_START, +- ADSP2_CORE_ENA | ADSP2_START); +-} +- +-static void cs_dsp_adsp2_stop_core(struct cs_dsp *dsp) +-{ +- regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, +- ADSP2_CORE_ENA | ADSP2_START, 0); +-} +- + static int wm_adsp_event_post_run(struct cs_dsp *cs_dsp) + { + struct wm_adsp *dsp = container_of(cs_dsp, struct wm_adsp, cs_dsp); +@@ -3405,93 +997,6 @@ static void wm_adsp_event_post_stop(struct cs_dsp *cs_dsp) + dsp->fatal_error = false; + } + +-static int cs_dsp_run(struct cs_dsp *dsp) +-{ +- int ret; +- +- mutex_lock(&dsp->pwr_lock); +- +- if (!dsp->booted) { +- ret = -EIO; +- goto err; +- } +- +- if (dsp->ops->enable_core) { +- ret = dsp->ops->enable_core(dsp); +- if (ret != 0) +- goto err; +- } +- +- /* Sync set controls */ +- ret = cs_dsp_coeff_sync_controls(dsp); +- if (ret != 0) +- goto err; +- +- if (dsp->ops->lock_memory) { +- ret = dsp->ops->lock_memory(dsp, dsp->lock_regions); +- if (ret != 0) { +- cs_dsp_err(dsp, "Error configuring MPU: %d\n", ret); +- goto err; +- } +- } +- +- if (dsp->ops->start_core) { +- ret = dsp->ops->start_core(dsp); +- if (ret != 0) +- goto err; +- } +- +- dsp->running = true; +- +- if (dsp->client_ops->post_run) { +- ret = dsp->client_ops->post_run(dsp); +- if (ret) +- goto err; +- } +- +- mutex_unlock(&dsp->pwr_lock); +- +- return 0; +- +-err: +- if (dsp->ops->stop_core) +- dsp->ops->stop_core(dsp); +- if (dsp->ops->disable_core) +- dsp->ops->disable_core(dsp); +- mutex_unlock(&dsp->pwr_lock); +- +- return ret; +-} +- +-static void cs_dsp_stop(struct cs_dsp *dsp) +-{ +- /* Tell the firmware to cleanup */ +- cs_dsp_signal_event_controls(dsp, CS_DSP_FW_EVENT_SHUTDOWN); +- +- if (dsp->ops->stop_watchdog) +- dsp->ops->stop_watchdog(dsp); +- +- /* Log firmware state, it can be useful for analysis */ +- if (dsp->ops->show_fw_status) +- dsp->ops->show_fw_status(dsp); +- +- mutex_lock(&dsp->pwr_lock); +- +- dsp->running = false; +- +- if (dsp->ops->stop_core) +- dsp->ops->stop_core(dsp); +- if (dsp->ops->disable_core) +- dsp->ops->disable_core(dsp); +- +- if (dsp->client_ops->post_stop) +- dsp->client_ops->post_stop(dsp); +- +- mutex_unlock(&dsp->pwr_lock); +- +- cs_dsp_dbg(dsp, "Execution stopped\n"); +-} +- + int wm_adsp_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) + { +@@ -3516,24 +1021,6 @@ int wm_adsp_event(struct snd_soc_dapm_widget *w, + } + EXPORT_SYMBOL_GPL(wm_adsp_event); + +-static int cs_dsp_halo_start_core(struct cs_dsp *dsp) +-{ +- return regmap_update_bits(dsp->regmap, +- dsp->base + HALO_CCM_CORE_CONTROL, +- HALO_CORE_RESET | HALO_CORE_EN, +- HALO_CORE_RESET | HALO_CORE_EN); +-} +- +-static void cs_dsp_halo_stop_core(struct cs_dsp *dsp) +-{ +- regmap_update_bits(dsp->regmap, dsp->base + HALO_CCM_CORE_CONTROL, +- HALO_CORE_EN, 0); +- +- /* reset halo core with CORE_SOFT_RESET */ +- regmap_update_bits(dsp->regmap, dsp->base + HALO_CORE_SOFT_RESET, +- HALO_CORE_SOFT_RESET_MASK, 1); +-} +- + int wm_adsp2_component_probe(struct wm_adsp *dsp, struct snd_soc_component *component) + { + char preload[32]; +@@ -3557,37 +1044,6 @@ int wm_adsp2_component_remove(struct wm_adsp *dsp, struct snd_soc_component *com + } + EXPORT_SYMBOL_GPL(wm_adsp2_component_remove); + +-static int cs_dsp_adsp2_init(struct cs_dsp *dsp) +-{ +- int ret; +- +- switch (dsp->rev) { +- case 0: +- /* +- * Disable the DSP memory by default when in reset for a small +- * power saving. +- */ +- ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, +- ADSP2_MEM_ENA, 0); +- if (ret) { +- cs_dsp_err(dsp, +- "Failed to clear memory retention: %d\n", ret); +- return ret; +- } +- +- dsp->ops = &cs_dsp_adsp2_ops[0]; +- break; +- case 1: +- dsp->ops = &cs_dsp_adsp2_ops[1]; +- break; +- default: +- dsp->ops = &cs_dsp_adsp2_ops[2]; +- break; +- } +- +- return cs_dsp_common_init(dsp); +-} +- + int wm_adsp2_init(struct wm_adsp *dsp) + { + int ret; +@@ -3605,13 +1061,6 @@ int wm_adsp2_init(struct wm_adsp *dsp) + } + EXPORT_SYMBOL_GPL(wm_adsp2_init); + +-static int cs_dsp_halo_init(struct cs_dsp *dsp) +-{ +- dsp->ops = &cs_dsp_halo_ops; +- +- return cs_dsp_common_init(dsp); +-} +- + int wm_halo_init(struct wm_adsp *dsp) + { + int ret; +@@ -3629,21 +1078,6 @@ int wm_halo_init(struct wm_adsp *dsp) + } + EXPORT_SYMBOL_GPL(wm_halo_init); + +-static void cs_dsp_remove(struct cs_dsp *dsp) +-{ +- struct cs_dsp_coeff_ctl *ctl; +- +- while (!list_empty(&dsp->ctl_list)) { +- ctl = list_first_entry(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); +- +- if (dsp->client_ops->control_remove) +- dsp->client_ops->control_remove(ctl); +- +- list_del(&ctl->list); +- cs_dsp_free_ctl_blk(ctl); +- } +-} +- + void wm_adsp2_remove(struct wm_adsp *dsp) + { + cs_dsp_remove(&dsp->cs_dsp); +@@ -3873,57 +1307,6 @@ int wm_adsp_compr_get_caps(struct snd_soc_component *component, + } + EXPORT_SYMBOL_GPL(wm_adsp_compr_get_caps); + +-static int cs_dsp_read_raw_data_block(struct cs_dsp *dsp, int mem_type, +- unsigned int mem_addr, +- unsigned int num_words, __be32 *data) +-{ +- struct cs_dsp_region const *mem = cs_dsp_find_region(dsp, mem_type); +- unsigned int reg; +- int ret; +- +- if (!mem) +- return -EINVAL; +- +- reg = dsp->ops->region_to_reg(mem, mem_addr); +- +- ret = regmap_raw_read(dsp->regmap, reg, data, +- sizeof(*data) * num_words); +- if (ret < 0) +- return ret; +- +- return 0; +-} +- +-static int cs_dsp_read_data_word(struct cs_dsp *dsp, int mem_type, +- unsigned int mem_addr, u32 *data) +-{ +- __be32 raw; +- int ret; +- +- ret = cs_dsp_read_raw_data_block(dsp, mem_type, mem_addr, 1, &raw); +- if (ret < 0) +- return ret; +- +- *data = be32_to_cpu(raw) & 0x00ffffffu; +- +- return 0; +-} +- +-static int cs_dsp_write_data_word(struct cs_dsp *dsp, int mem_type, +- unsigned int mem_addr, u32 data) +-{ +- struct cs_dsp_region const *mem = cs_dsp_find_region(dsp, mem_type); +- __be32 val = cpu_to_be32(data & 0x00ffffffu); +- unsigned int reg; +- +- if (!mem) +- return -EINVAL; +- +- reg = dsp->ops->region_to_reg(mem, mem_addr); +- +- return regmap_raw_write(dsp->regmap, reg, &val, sizeof(val)); +-} +- + static inline int wm_adsp_buffer_read(struct wm_adsp_compr_buf *buf, + unsigned int field_offset, u32 *data) + { +@@ -3939,25 +1322,6 @@ static inline int wm_adsp_buffer_write(struct wm_adsp_compr_buf *buf, + data); + } + +-static void cs_dsp_remove_padding(u32 *buf, int nwords) +-{ +- const __be32 *pack_in = (__be32 *)buf; +- u8 *pack_out = (u8 *)buf; +- int i; +- +- /* +- * DSP words from the register map have pad bytes and the data bytes +- * are in swapped order. This swaps back to the original little-endian +- * order and strips the pad bytes. +- */ +- for (i = 0; i < nwords; i++) { +- u32 word = be32_to_cpu(*pack_in++); +- *pack_out++ = (u8)word; +- *pack_out++ = (u8)(word >> 8); +- *pack_out++ = (u8)(word >> 16); +- } +-} +- + static int wm_adsp_buffer_populate(struct wm_adsp_compr_buf *buf) + { + const struct wm_adsp_fw_caps *caps = wm_adsp_fw[buf->dsp->fw].caps; +@@ -4568,69 +1932,6 @@ static void wm_adsp_fatal_error(struct cs_dsp *cs_dsp) + } + } + +-static void cs_dsp_adsp2_bus_error(struct cs_dsp *dsp) +-{ +- unsigned int val; +- struct regmap *regmap = dsp->regmap; +- int ret = 0; +- +- mutex_lock(&dsp->pwr_lock); +- +- ret = regmap_read(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, &val); +- if (ret) { +- cs_dsp_err(dsp, +- "Failed to read Region Lock Ctrl register: %d\n", ret); +- goto error; +- } +- +- if (val & ADSP2_WDT_TIMEOUT_STS_MASK) { +- cs_dsp_err(dsp, "watchdog timeout error\n"); +- dsp->ops->stop_watchdog(dsp); +- if (dsp->client_ops->watchdog_expired) +- dsp->client_ops->watchdog_expired(dsp); +- } +- +- if (val & (ADSP2_ADDR_ERR_MASK | ADSP2_REGION_LOCK_ERR_MASK)) { +- if (val & ADSP2_ADDR_ERR_MASK) +- cs_dsp_err(dsp, "bus error: address error\n"); +- else +- cs_dsp_err(dsp, "bus error: region lock error\n"); +- +- ret = regmap_read(regmap, dsp->base + ADSP2_BUS_ERR_ADDR, &val); +- if (ret) { +- cs_dsp_err(dsp, +- "Failed to read Bus Err Addr register: %d\n", +- ret); +- goto error; +- } +- +- cs_dsp_err(dsp, "bus error address = 0x%x\n", +- val & ADSP2_BUS_ERR_ADDR_MASK); +- +- ret = regmap_read(regmap, +- dsp->base + ADSP2_PMEM_ERR_ADDR_XMEM_ERR_ADDR, +- &val); +- if (ret) { +- cs_dsp_err(dsp, +- "Failed to read Pmem Xmem Err Addr register: %d\n", +- ret); +- goto error; +- } +- +- cs_dsp_err(dsp, "xmem error address = 0x%x\n", +- val & ADSP2_XMEM_ERR_ADDR_MASK); +- cs_dsp_err(dsp, "pmem error address = 0x%x\n", +- (val & ADSP2_PMEM_ERR_ADDR_MASK) >> +- ADSP2_PMEM_ERR_ADDR_SHIFT); +- } +- +- regmap_update_bits(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, +- ADSP2_CTRL_ERR_EINT, ADSP2_CTRL_ERR_EINT); +- +-error: +- mutex_unlock(&dsp->pwr_lock); +-} +- + irqreturn_t wm_adsp2_bus_error(int irq, void *data) + { + struct wm_adsp *dsp = (struct wm_adsp *)data; +@@ -4641,59 +1942,6 @@ irqreturn_t wm_adsp2_bus_error(int irq, void *data) + } + EXPORT_SYMBOL_GPL(wm_adsp2_bus_error); + +-static void cs_dsp_halo_bus_error(struct cs_dsp *dsp) +-{ +- struct regmap *regmap = dsp->regmap; +- unsigned int fault[6]; +- struct reg_sequence clear[] = { +- { dsp->base + HALO_MPU_XM_VIO_STATUS, 0x0 }, +- { dsp->base + HALO_MPU_YM_VIO_STATUS, 0x0 }, +- { dsp->base + HALO_MPU_PM_VIO_STATUS, 0x0 }, +- }; +- int ret; +- +- mutex_lock(&dsp->pwr_lock); +- +- ret = regmap_read(regmap, dsp->base_sysinfo + HALO_AHBM_WINDOW_DEBUG_1, +- fault); +- if (ret) { +- cs_dsp_warn(dsp, "Failed to read AHB DEBUG_1: %d\n", ret); +- goto exit_unlock; +- } +- +- cs_dsp_warn(dsp, "AHB: STATUS: 0x%x ADDR: 0x%x\n", +- *fault & HALO_AHBM_FLAGS_ERR_MASK, +- (*fault & HALO_AHBM_CORE_ERR_ADDR_MASK) >> +- HALO_AHBM_CORE_ERR_ADDR_SHIFT); +- +- ret = regmap_read(regmap, dsp->base_sysinfo + HALO_AHBM_WINDOW_DEBUG_0, +- fault); +- if (ret) { +- cs_dsp_warn(dsp, "Failed to read AHB DEBUG_0: %d\n", ret); +- goto exit_unlock; +- } +- +- cs_dsp_warn(dsp, "AHB: SYS_ADDR: 0x%x\n", *fault); +- +- ret = regmap_bulk_read(regmap, dsp->base + HALO_MPU_XM_VIO_ADDR, +- fault, ARRAY_SIZE(fault)); +- if (ret) { +- cs_dsp_warn(dsp, "Failed to read MPU fault info: %d\n", ret); +- goto exit_unlock; +- } +- +- cs_dsp_warn(dsp, "XM: STATUS:0x%x ADDR:0x%x\n", fault[1], fault[0]); +- cs_dsp_warn(dsp, "YM: STATUS:0x%x ADDR:0x%x\n", fault[3], fault[2]); +- cs_dsp_warn(dsp, "PM: STATUS:0x%x ADDR:0x%x\n", fault[5], fault[4]); +- +- ret = regmap_multi_reg_write(dsp->regmap, clear, ARRAY_SIZE(clear)); +- if (ret) +- cs_dsp_warn(dsp, "Failed to clear MPU status: %d\n", ret); +- +-exit_unlock: +- mutex_unlock(&dsp->pwr_lock); +-} +- + irqreturn_t wm_halo_bus_error(int irq, void *data) + { + struct wm_adsp *dsp = (struct wm_adsp *)data; +@@ -4704,19 +1952,6 @@ irqreturn_t wm_halo_bus_error(int irq, void *data) + } + EXPORT_SYMBOL_GPL(wm_halo_bus_error); + +-static void cs_dsp_halo_wdt_expire(struct cs_dsp *dsp) +-{ +- mutex_lock(&dsp->pwr_lock); +- +- cs_dsp_warn(dsp, "WDT Expiry Fault\n"); +- +- dsp->ops->stop_watchdog(dsp); +- if (dsp->client_ops->watchdog_expired) +- dsp->client_ops->watchdog_expired(dsp); +- +- mutex_unlock(&dsp->pwr_lock); +-} +- + irqreturn_t wm_halo_wdt_expire(int irq, void *data) + { + struct wm_adsp *dsp = data; +@@ -4727,90 +1962,11 @@ irqreturn_t wm_halo_wdt_expire(int irq, void *data) + } + EXPORT_SYMBOL_GPL(wm_halo_wdt_expire); + +-static const struct cs_dsp_ops cs_dsp_adsp1_ops = { +- .validate_version = cs_dsp_validate_version, +- .parse_sizes = cs_dsp_adsp1_parse_sizes, +- .region_to_reg = cs_dsp_region_to_reg, +-}; +- + static const struct cs_dsp_client_ops wm_adsp1_client_ops = { + .control_add = wm_adsp_control_add, + .control_remove = wm_adsp_control_remove, + }; + +-static const struct cs_dsp_ops cs_dsp_adsp2_ops[] = { +- { +- .parse_sizes = cs_dsp_adsp2_parse_sizes, +- .validate_version = cs_dsp_validate_version, +- .setup_algs = cs_dsp_adsp2_setup_algs, +- .region_to_reg = cs_dsp_region_to_reg, +- +- .show_fw_status = cs_dsp_adsp2_show_fw_status, +- +- .enable_memory = cs_dsp_adsp2_enable_memory, +- .disable_memory = cs_dsp_adsp2_disable_memory, +- +- .enable_core = cs_dsp_adsp2_enable_core, +- .disable_core = cs_dsp_adsp2_disable_core, +- +- .start_core = cs_dsp_adsp2_start_core, +- .stop_core = cs_dsp_adsp2_stop_core, +- +- }, +- { +- .parse_sizes = cs_dsp_adsp2_parse_sizes, +- .validate_version = cs_dsp_validate_version, +- .setup_algs = cs_dsp_adsp2_setup_algs, +- .region_to_reg = cs_dsp_region_to_reg, +- +- .show_fw_status = cs_dsp_adsp2v2_show_fw_status, +- +- .enable_memory = cs_dsp_adsp2_enable_memory, +- .disable_memory = cs_dsp_adsp2_disable_memory, +- .lock_memory = cs_dsp_adsp2_lock, +- +- .enable_core = cs_dsp_adsp2v2_enable_core, +- .disable_core = cs_dsp_adsp2v2_disable_core, +- +- .start_core = cs_dsp_adsp2_start_core, +- .stop_core = cs_dsp_adsp2_stop_core, +- }, +- { +- .parse_sizes = cs_dsp_adsp2_parse_sizes, +- .validate_version = cs_dsp_validate_version, +- .setup_algs = cs_dsp_adsp2_setup_algs, +- .region_to_reg = cs_dsp_region_to_reg, +- +- .show_fw_status = cs_dsp_adsp2v2_show_fw_status, +- .stop_watchdog = cs_dsp_stop_watchdog, +- +- .enable_memory = cs_dsp_adsp2_enable_memory, +- .disable_memory = cs_dsp_adsp2_disable_memory, +- .lock_memory = cs_dsp_adsp2_lock, +- +- .enable_core = cs_dsp_adsp2v2_enable_core, +- .disable_core = cs_dsp_adsp2v2_disable_core, +- +- .start_core = cs_dsp_adsp2_start_core, +- .stop_core = cs_dsp_adsp2_stop_core, +- }, +-}; +- +-static const struct cs_dsp_ops cs_dsp_halo_ops = { +- .parse_sizes = cs_dsp_adsp2_parse_sizes, +- .validate_version = cs_dsp_halo_validate_version, +- .setup_algs = cs_dsp_halo_setup_algs, +- .region_to_reg = cs_dsp_halo_region_to_reg, +- +- .show_fw_status = cs_dsp_halo_show_fw_status, +- .stop_watchdog = cs_dsp_halo_stop_watchdog, +- +- .lock_memory = cs_dsp_halo_configure_mpu, +- +- .start_core = cs_dsp_halo_start_core, +- .stop_core = cs_dsp_halo_stop_core, +-}; +- + static const struct cs_dsp_client_ops wm_adsp2_client_ops = { + .control_add = wm_adsp_control_add, + .control_remove = wm_adsp_control_remove, +diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h +index 25aaef74654c..0e2f113bd342 100644 +--- a/sound/soc/codecs/wm_adsp.h ++++ b/sound/soc/codecs/wm_adsp.h +@@ -10,113 +10,19 @@ + #ifndef __WM_ADSP_H + #define __WM_ADSP_H + ++#include ++#include ++ + #include + #include + #include + +-#include "wmfw.h" +- + /* Return values for wm_adsp_compr_handle_irq */ + #define WM_ADSP_COMPR_OK 0 + #define WM_ADSP_COMPR_VOICE_TRIGGER 1 + +-#define CS_ADSP2_REGION_0 BIT(0) +-#define CS_ADSP2_REGION_1 BIT(1) +-#define CS_ADSP2_REGION_2 BIT(2) +-#define CS_ADSP2_REGION_3 BIT(3) +-#define CS_ADSP2_REGION_4 BIT(4) +-#define CS_ADSP2_REGION_5 BIT(5) +-#define CS_ADSP2_REGION_6 BIT(6) +-#define CS_ADSP2_REGION_7 BIT(7) +-#define CS_ADSP2_REGION_8 BIT(8) +-#define CS_ADSP2_REGION_9 BIT(9) +-#define CS_ADSP2_REGION_1_9 (CS_ADSP2_REGION_1 | \ +- CS_ADSP2_REGION_2 | CS_ADSP2_REGION_3 | \ +- CS_ADSP2_REGION_4 | CS_ADSP2_REGION_5 | \ +- CS_ADSP2_REGION_6 | CS_ADSP2_REGION_7 | \ +- CS_ADSP2_REGION_8 | CS_ADSP2_REGION_9) +-#define CS_ADSP2_REGION_ALL (CS_ADSP2_REGION_0 | CS_ADSP2_REGION_1_9) +- +-struct cs_dsp_region { +- int type; +- unsigned int base; +-}; +- +-struct cs_dsp_alg_region { +- struct list_head list; +- unsigned int alg; +- int type; +- unsigned int base; +-}; +- + struct wm_adsp_compr; + struct wm_adsp_compr_buf; +-struct cs_dsp_ops; +-struct cs_dsp_client_ops; +- +-struct cs_dsp_coeff_ctl { +- const char *fw_name; +- /* Subname is needed to match with firmware */ +- const char *subname; +- unsigned int subname_len; +- struct cs_dsp_alg_region alg_region; +- struct cs_dsp *dsp; +- unsigned int enabled:1; +- struct list_head list; +- void *cache; +- unsigned int offset; +- size_t len; +- unsigned int set:1; +- unsigned int flags; +- unsigned int type; +- +- void *priv; +-}; +- +-struct cs_dsp { +- const char *name; +- int rev; +- int num; +- int type; +- struct device *dev; +- struct regmap *regmap; +- +- const struct cs_dsp_ops *ops; +- const struct cs_dsp_client_ops *client_ops; +- +- unsigned int base; +- unsigned int base_sysinfo; +- unsigned int sysclk_reg; +- unsigned int sysclk_mask; +- unsigned int sysclk_shift; +- +- struct list_head alg_regions; +- +- const char *fw_name; +- unsigned int fw_id; +- unsigned int fw_id_version; +- unsigned int fw_vendor_id; +- +- const struct cs_dsp_region *mem; +- int num_mems; +- +- int fw_ver; +- +- bool booted; +- bool running; +- +- struct list_head ctl_list; +- +- struct mutex pwr_lock; +- +- unsigned int lock_regions; +- +-#ifdef CONFIG_DEBUG_FS +- struct dentry *debugfs_root; +- char *wmfw_file_name; +- char *bin_file_name; +-#endif +-}; + + struct wm_adsp { + struct cs_dsp cs_dsp; +@@ -137,30 +43,6 @@ struct wm_adsp { + struct list_head buffer_list; + }; + +-struct cs_dsp_ops { +- bool (*validate_version)(struct cs_dsp *dsp, unsigned int version); +- unsigned int (*parse_sizes)(struct cs_dsp *dsp, +- const char * const file, +- unsigned int pos, +- const struct firmware *firmware); +- int (*setup_algs)(struct cs_dsp *dsp); +- unsigned int (*region_to_reg)(struct cs_dsp_region const *mem, +- unsigned int offset); +- +- void (*show_fw_status)(struct cs_dsp *dsp); +- void (*stop_watchdog)(struct cs_dsp *dsp); +- +- int (*enable_memory)(struct cs_dsp *dsp); +- void (*disable_memory)(struct cs_dsp *dsp); +- int (*lock_memory)(struct cs_dsp *dsp, unsigned int lock_regions); +- +- int (*enable_core)(struct cs_dsp *dsp); +- void (*disable_core)(struct cs_dsp *dsp); +- +- int (*start_core)(struct cs_dsp *dsp); +- void (*stop_core)(struct cs_dsp *dsp); +-}; +- + #define WM_ADSP1(wname, num) \ + SND_SOC_DAPM_PGA_E(wname, SND_SOC_NOPM, num, 0, NULL, 0, \ + wm_adsp1_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD) +@@ -239,12 +121,4 @@ int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type, + int wm_adsp_read_ctl(struct wm_adsp *dsp, const char *name, int type, + unsigned int alg, void *buf, size_t len); + +-struct cs_dsp_client_ops { +- int (*control_add)(struct cs_dsp_coeff_ctl *ctl); +- void (*control_remove)(struct cs_dsp_coeff_ctl *ctl); +- int (*post_run)(struct cs_dsp *dsp); +- void (*post_stop)(struct cs_dsp *dsp); +- void (*watchdog_expired)(struct cs_dsp *dsp); +-}; +- + #endif +diff --git a/sound/soc/codecs/wmfw.h b/sound/soc/codecs/wmfw.h +deleted file mode 100644 +index a19bf7c6fc8b..000000000000 +--- a/sound/soc/codecs/wmfw.h ++++ /dev/null +@@ -1,202 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0-only */ +-/* +- * wmfw.h - Wolfson firmware format information +- * +- * Copyright 2012 Wolfson Microelectronics plc +- * +- * Author: Mark Brown +- */ +- +-#ifndef __WMFW_H +-#define __WMFW_H +- +-#include +- +-#define WMFW_MAX_ALG_NAME 256 +-#define WMFW_MAX_ALG_DESCR_NAME 256 +- +-#define WMFW_MAX_COEFF_NAME 256 +-#define WMFW_MAX_COEFF_DESCR_NAME 256 +- +-#define WMFW_CTL_FLAG_SYS 0x8000 +-#define WMFW_CTL_FLAG_VOLATILE 0x0004 +-#define WMFW_CTL_FLAG_WRITEABLE 0x0002 +-#define WMFW_CTL_FLAG_READABLE 0x0001 +- +-#define WMFW_CTL_TYPE_BYTES 0x0004 /* byte control */ +- +-/* Non-ALSA coefficient types start at 0x1000 */ +-#define WMFW_CTL_TYPE_ACKED 0x1000 /* acked control */ +-#define WMFW_CTL_TYPE_HOSTEVENT 0x1001 /* event control */ +-#define WMFW_CTL_TYPE_HOST_BUFFER 0x1002 /* host buffer pointer */ +- +-struct wmfw_header { +- char magic[4]; +- __le32 len; +- __le16 rev; +- u8 core; +- u8 ver; +-} __packed; +- +-struct wmfw_footer { +- __le64 timestamp; +- __le32 checksum; +-} __packed; +- +-struct wmfw_adsp1_sizes { +- __le32 dm; +- __le32 pm; +- __le32 zm; +-} __packed; +- +-struct wmfw_adsp2_sizes { +- __le32 xm; +- __le32 ym; +- __le32 pm; +- __le32 zm; +-} __packed; +- +-struct wmfw_region { +- union { +- __be32 type; +- __le32 offset; +- }; +- __le32 len; +- u8 data[]; +-} __packed; +- +-struct wmfw_id_hdr { +- __be32 core_id; +- __be32 core_rev; +- __be32 id; +- __be32 ver; +-} __packed; +- +-struct wmfw_v3_id_hdr { +- __be32 core_id; +- __be32 block_rev; +- __be32 vendor_id; +- __be32 id; +- __be32 ver; +-} __packed; +- +-struct wmfw_adsp1_id_hdr { +- struct wmfw_id_hdr fw; +- __be32 zm; +- __be32 dm; +- __be32 n_algs; +-} __packed; +- +-struct wmfw_adsp2_id_hdr { +- struct wmfw_id_hdr fw; +- __be32 zm; +- __be32 xm; +- __be32 ym; +- __be32 n_algs; +-} __packed; +- +-struct wmfw_halo_id_hdr { +- struct wmfw_v3_id_hdr fw; +- __be32 xm_base; +- __be32 xm_size; +- __be32 ym_base; +- __be32 ym_size; +- __be32 n_algs; +-} __packed; +- +-struct wmfw_alg_hdr { +- __be32 id; +- __be32 ver; +-} __packed; +- +-struct wmfw_adsp1_alg_hdr { +- struct wmfw_alg_hdr alg; +- __be32 zm; +- __be32 dm; +-} __packed; +- +-struct wmfw_adsp2_alg_hdr { +- struct wmfw_alg_hdr alg; +- __be32 zm; +- __be32 xm; +- __be32 ym; +-} __packed; +- +-struct wmfw_halo_alg_hdr { +- struct wmfw_alg_hdr alg; +- __be32 xm_base; +- __be32 xm_size; +- __be32 ym_base; +- __be32 ym_size; +-} __packed; +- +-struct wmfw_adsp_alg_data { +- __le32 id; +- u8 name[WMFW_MAX_ALG_NAME]; +- u8 descr[WMFW_MAX_ALG_DESCR_NAME]; +- __le32 ncoeff; +- u8 data[]; +-} __packed; +- +-struct wmfw_adsp_coeff_data { +- struct { +- __le16 offset; +- __le16 type; +- __le32 size; +- } hdr; +- u8 name[WMFW_MAX_COEFF_NAME]; +- u8 descr[WMFW_MAX_COEFF_DESCR_NAME]; +- __le16 ctl_type; +- __le16 flags; +- __le32 len; +- u8 data[]; +-} __packed; +- +-struct wmfw_coeff_hdr { +- u8 magic[4]; +- __le32 len; +- union { +- __be32 rev; +- __le32 ver; +- }; +- union { +- __be32 core; +- __le32 core_ver; +- }; +- u8 data[]; +-} __packed; +- +-struct wmfw_coeff_item { +- __le16 offset; +- __le16 type; +- __le32 id; +- __le32 ver; +- __le32 sr; +- __le32 len; +- u8 data[]; +-} __packed; +- +-#define WMFW_ADSP1 1 +-#define WMFW_ADSP2 2 +-#define WMFW_HALO 4 +- +-#define WMFW_ABSOLUTE 0xf0 +-#define WMFW_ALGORITHM_DATA 0xf2 +-#define WMFW_METADATA 0xfc +-#define WMFW_NAME_TEXT 0xfe +-#define WMFW_INFO_TEXT 0xff +- +-#define WMFW_ADSP1_PM 2 +-#define WMFW_ADSP1_DM 3 +-#define WMFW_ADSP1_ZM 4 +- +-#define WMFW_ADSP2_PM 2 +-#define WMFW_ADSP2_ZM 4 +-#define WMFW_ADSP2_XM 5 +-#define WMFW_ADSP2_YM 6 +- +-#define WMFW_HALO_PM_PACKED 0x10 +-#define WMFW_HALO_XM_PACKED 0x11 +-#define WMFW_HALO_YM_PACKED 0x12 +- +-#endif +-- +2.35.3 + diff --git a/patches.suse/firmware-cs_dsp-tidy-includes-in-cs_dsp.c-and-cs_dsp.patch b/patches.suse/firmware-cs_dsp-tidy-includes-in-cs_dsp.c-and-cs_dsp.patch new file mode 100644 index 0000000..1afe11d --- /dev/null +++ b/patches.suse/firmware-cs_dsp-tidy-includes-in-cs_dsp.c-and-cs_dsp.patch @@ -0,0 +1,63 @@ +From 749303055b78bc38ec0790ccc596cae235446367 Mon Sep 17 00:00:00 2001 +From: Simon Trimmer +Date: Mon, 15 Nov 2021 12:02:15 +0000 +Subject: [PATCH] firmware: cs_dsp: tidy includes in cs_dsp.c and cs_dsp.h +Git-commit: 749303055b78bc38ec0790ccc596cae235446367 +Patch-mainline: v5.17-rc1 +References: bsc#1203699 + +This patch removes unused included header files and moves others into +cs_dsp.h to ensure that types referenced in the header file are properly +described to prevent compiler warnings. + +Signed-off-by: Simon Trimmer +Acked-by: Charles Keepax +Link: https://lore.kernel.org/r/20211115120215.56824-1-simont@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + drivers/firmware/cirrus/cs_dsp.c | 6 ------ + include/linux/firmware/cirrus/cs_dsp.h | 5 +++++ + 2 files changed, 5 insertions(+), 6 deletions(-) + +diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c +index 948dd8382686..1a0c6c793f6a 100644 +--- a/drivers/firmware/cirrus/cs_dsp.c ++++ b/drivers/firmware/cirrus/cs_dsp.c +@@ -12,16 +12,10 @@ + #include + #include + #include +-#include +-#include +-#include +-#include + #include + #include +-#include + #include + #include +-#include + + #include + #include +diff --git a/include/linux/firmware/cirrus/cs_dsp.h b/include/linux/firmware/cirrus/cs_dsp.h +index 9ad9eaaaa552..3a54b1afc48f 100644 +--- a/include/linux/firmware/cirrus/cs_dsp.h ++++ b/include/linux/firmware/cirrus/cs_dsp.h +@@ -11,6 +11,11 @@ + #ifndef __CS_DSP_H + #define __CS_DSP_H + ++#include ++#include ++#include ++#include ++ + #define CS_ADSP2_REGION_0 BIT(0) + #define CS_ADSP2_REGION_1 BIT(1) + #define CS_ADSP2_REGION_2 BIT(2) +-- +2.35.3 + diff --git a/patches.suse/firmware-google-Test-spinlock-on-panic-path-to-avoid.patch b/patches.suse/firmware-google-Test-spinlock-on-panic-path-to-avoid.patch new file mode 100644 index 0000000..a54d0b4 --- /dev/null +++ b/patches.suse/firmware-google-Test-spinlock-on-panic-path-to-avoid.patch @@ -0,0 +1,59 @@ +From 3e081438b8e639cc76ef1a5ce0c1bd8a154082c7 Mon Sep 17 00:00:00 2001 +From: "Guilherme G. Piccoli" +Date: Fri, 9 Sep 2022 17:07:55 -0300 +Subject: [PATCH] firmware: google: Test spinlock on panic path to avoid lockups +Git-commit: 3e081438b8e639cc76ef1a5ce0c1bd8a154082c7 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Currently the gsmi driver registers a panic notifier as well as +reboot and die notifiers. The callbacks registered are called in +atomic and very limited context - for instance, panic disables +preemption and local IRQs, also all secondary CPUs (not executing +the panic path) are shutdown. + +With that said, taking a spinlock in this scenario is a dangerous +invitation for lockup scenarios. So, fix that by checking if the +spinlock is free to acquire in the panic notifier callback - if not, +bail-out and avoid a potential hang. + +Fixes: 74c5b31c6618 ("driver: Google EFI SMI") +Cc: Andrew Morton +Cc: Ard Biesheuvel +Cc: David Gow +Cc: Greg Kroah-Hartman +Cc: Julius Werner +Cc: Petr Mladek +Reviewed-by: Evan Green +Signed-off-by: Guilherme G. Piccoli +Link: https://lore.kernel.org/r/20220909200755.189679-1-gpiccoli@igalia.com +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/firmware/google/gsmi.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/drivers/firmware/google/gsmi.c b/drivers/firmware/google/gsmi.c +index adaa492c3d2d..4e2575dfeb90 100644 +--- a/drivers/firmware/google/gsmi.c ++++ b/drivers/firmware/google/gsmi.c +@@ -681,6 +681,15 @@ static struct notifier_block gsmi_die_notifier = { + static int gsmi_panic_callback(struct notifier_block *nb, + unsigned long reason, void *arg) + { ++ ++ /* ++ * Panic callbacks are executed with all other CPUs stopped, ++ * so we must not attempt to spin waiting for gsmi_dev.lock ++ * to be released. ++ */ ++ if (spin_is_locked(&gsmi_dev.lock)) ++ return NOTIFY_DONE; ++ + gsmi_shutdown_reason(GSMI_SHUTDOWN_PANIC); + return NOTIFY_DONE; + } +-- +2.35.3 + diff --git a/patches.suse/fpga-prevent-integer-overflow-in-dfl_feature_ioctl_s.patch b/patches.suse/fpga-prevent-integer-overflow-in-dfl_feature_ioctl_s.patch new file mode 100644 index 0000000..8f78c13 --- /dev/null +++ b/patches.suse/fpga-prevent-integer-overflow-in-dfl_feature_ioctl_s.patch @@ -0,0 +1,38 @@ +From 939bc5453b8cbdde9f1e5110ce8309aedb1b501a Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Thu, 1 Sep 2022 08:18:45 +0300 +Subject: [PATCH] fpga: prevent integer overflow in dfl_feature_ioctl_set_irq() +Git-commit: 939bc5453b8cbdde9f1e5110ce8309aedb1b501a +Patch-mainline: v6.1-rc1 +References: git-fixes + +The "hdr.count * sizeof(s32)" multiplication can overflow on 32 bit +systems leading to memory corruption. Use array_size() to fix that. + +Fixes: 322b598be4d9 ("fpga: dfl: introduce interrupt trigger setting API") +Signed-off-by: Dan Carpenter +Acked-by: Xu Yilun +Link: https://lore.kernel.org/r/YxBAtYCM38dM7yzI@kili +Signed-off-by: Xu Yilun +Acked-by: Takashi Iwai + +--- + drivers/fpga/dfl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/fpga/dfl.c b/drivers/fpga/dfl.c +index 5498bc337f8b..b9aae85ba930 100644 +--- a/drivers/fpga/dfl.c ++++ b/drivers/fpga/dfl.c +@@ -1866,7 +1866,7 @@ long dfl_feature_ioctl_set_irq(struct platform_device *pdev, + return -EINVAL; + + fds = memdup_user((void __user *)(arg + sizeof(hdr)), +- hdr.count * sizeof(s32)); ++ array_size(hdr.count, sizeof(s32))); + if (IS_ERR(fds)) + return PTR_ERR(fds); + +-- +2.35.3 + diff --git a/patches.suse/fs-fix-UAF-GPF-bug-in-nilfs_mdt_destroy.patch b/patches.suse/fs-fix-UAF-GPF-bug-in-nilfs_mdt_destroy.patch new file mode 100644 index 0000000..634079c --- /dev/null +++ b/patches.suse/fs-fix-UAF-GPF-bug-in-nilfs_mdt_destroy.patch @@ -0,0 +1,66 @@ +From aa5b151dc63fcb97244321257a29da2b8a1511e1 Mon Sep 17 00:00:00 2001 +From: Dongliang Mu +Date: Tue, 16 Aug 2022 12:08:58 +0800 +Subject: [PATCH] fs: fix UAF/GPF bug in nilfs_mdt_destroy +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +References: CVE-2022-2978 bsc#1202700 +Git-commit: 2e488f13755ffbb60f307e991b27024716a33b29 +Patch-mainline: v6.1-rc1 + +In alloc_inode, inode_init_always() could return -ENOMEM if +security_inode_alloc() fails, which causes inode->i_private +uninitialized. Then nilfs_is_metadata_file_inode() returns +true and nilfs_free_inode() wrongly calls nilfs_mdt_destroy(), +which frees the uninitialized inode->i_private +and leads to crashes(e.g., UAF/GPF). + +Fix this by moving security_inode_alloc just prior to +this_cpu_inc(nr_inodes) + +Link: https://lkml.kernel.org/r/CAFcO6XOcf1Jj2SeGt=jJV59wmhESeSKpfR0omdFRq+J9nD1vfQ@mail.gmail.com +Reported-by: butt3rflyh4ck +Reported-by: Hao Sun +Reported-by: Jiacheng Xu +Reviewed-by: Christian Brauner (Microsoft) +Signed-off-by: Dongliang Mu +Cc: Al Viro +Cc: stable@vger.kernel.org +Signed-off-by: Al Viro +Acked-by: David Disseldorp +--- + fs/inode.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/fs/inode.c b/fs/inode.c +index 659e27226feca..8c473c1c93d01 100644 +--- a/fs/inode.c ++++ b/fs/inode.c +@@ -167,8 +167,6 @@ int inode_init_always(struct super_block *sb, struct inode *inode) + inode->i_wb_frn_history = 0; + #endif + +- if (security_inode_alloc(inode)) +- goto out; + spin_lock_init(&inode->i_lock); + lockdep_set_class(&inode->i_lock, &sb->s_type->i_lock_key); + +@@ -205,11 +203,12 @@ int inode_init_always(struct super_block *sb, struct inode *inode) + inode->i_fsnotify_mask = 0; + #endif + inode->i_flctx = NULL; ++ ++ if (unlikely(security_inode_alloc(inode))) ++ return -ENOMEM; + this_cpu_inc(nr_inodes); + + return 0; +-out: +- return -ENOMEM; + } + EXPORT_SYMBOL(inode_init_always); + +-- +2.35.3 + diff --git a/patches.suse/fuse-Remove-the-control-interface-for-virtio-fs.patch b/patches.suse/fuse-Remove-the-control-interface-for-virtio-fs.patch new file mode 100644 index 0000000..9fd6c38 --- /dev/null +++ b/patches.suse/fuse-Remove-the-control-interface-for-virtio-fs.patch @@ -0,0 +1,47 @@ +From: Xie Yongji +Date: Mon, 18 Jul 2022 16:50:12 +0800 +Subject: fuse: Remove the control interface for virtio-fs +Git-commit: c64797809a64c73497082aa05e401a062ec1af34 +Patch-mainline: v6.0-rc1 +References: bsc#1203798 + +The commit 15c8e72e88e0 ("fuse: allow skipping control interface and forced +unmount") tries to remove the control interface for virtio-fs since it does +not support aborting requests which are being processed. But it doesn't +work now. + +This patch fixes it by skipping creating the control interface if +fuse_conn->no_control is set. + +Fixes: 15c8e72e88e0 ("fuse: allow skipping control interface and forced unmount") +Signed-off-by: Xie Yongji +Signed-off-by: Miklos Szeredi +Acked-by: Luis Henriques + +--- + fs/fuse/control.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/fs/fuse/control.c b/fs/fuse/control.c +index 7cede9a3bc96..247ef4f76761 100644 +--- a/fs/fuse/control.c ++++ b/fs/fuse/control.c +@@ -258,7 +258,7 @@ int fuse_ctl_add_conn(struct fuse_conn *fc) + struct dentry *parent; + char name[32]; + +- if (!fuse_control_sb) ++ if (!fuse_control_sb || fc->no_control) + return 0; + + parent = fuse_control_sb->s_root; +@@ -296,7 +296,7 @@ void fuse_ctl_remove_conn(struct fuse_conn *fc) + { + int i; + +- if (!fuse_control_sb) ++ if (!fuse_control_sb || fc->no_control) + return; + + for (i = fc->ctl_ndents - 1; i >= 0; i--) { + diff --git a/patches.suse/gpio-mockup-fix-NULL-pointer-dereference-when-removi.patch b/patches.suse/gpio-mockup-fix-NULL-pointer-dereference-when-removi.patch new file mode 100644 index 0000000..4d94357 --- /dev/null +++ b/patches.suse/gpio-mockup-fix-NULL-pointer-dereference-when-removi.patch @@ -0,0 +1,41 @@ +From b7df41a6f79dfb18ba2203f8c5f0e9c0b9b57f68 Mon Sep 17 00:00:00 2001 +From: Bartosz Golaszewski +Date: Tue, 20 Sep 2022 09:18:41 +0200 +Subject: [PATCH] gpio: mockup: fix NULL pointer dereference when removing debugfs +Git-commit: b7df41a6f79dfb18ba2203f8c5f0e9c0b9b57f68 +Patch-mainline: v6.0-rc7 +References: git-fixes + +We now remove the device's debugfs entries when unbinding the driver. +This now causes a NULL-pointer dereference on module exit because the +platform devices are unregistered *after* the global debugfs directory +has been recursively removed. Fix it by unregistering the devices first. + +Fixes: 303e6da99429 ("gpio: mockup: remove gpio debugfs when remove device") +Cc: Wei Yongjun +Cc: stable@vger.kernel.org +Signed-off-by: Bartosz Golaszewski +Acked-by: Takashi Iwai + +--- + drivers/gpio/gpio-mockup.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpio/gpio-mockup.c b/drivers/gpio/gpio-mockup.c +index a2e505a7545c..ab89cd8ddbd8 100644 +--- a/drivers/gpio/gpio-mockup.c ++++ b/drivers/gpio/gpio-mockup.c +@@ -597,9 +597,9 @@ static int __init gpio_mockup_init(void) + + static void __exit gpio_mockup_exit(void) + { ++ gpio_mockup_unregister_pdevs(); + debugfs_remove_recursive(gpio_mockup_dbg_dir); + platform_driver_unregister(&gpio_mockup_driver); +- gpio_mockup_unregister_pdevs(); + } + + module_init(gpio_mockup_init); +-- +2.35.3 + diff --git a/patches.suse/gpio-mockup-remove-gpio-debugfs-when-remove-device.patch b/patches.suse/gpio-mockup-remove-gpio-debugfs-when-remove-device.patch new file mode 100644 index 0000000..26571e5 --- /dev/null +++ b/patches.suse/gpio-mockup-remove-gpio-debugfs-when-remove-device.patch @@ -0,0 +1,50 @@ +From 303e6da99429510b1e4edf833afe90ac8542e747 Mon Sep 17 00:00:00 2001 +From: Wei Yongjun +Date: Mon, 22 Aug 2022 04:10:25 +0000 +Subject: [PATCH] gpio: mockup: remove gpio debugfs when remove device +Git-commit: 303e6da99429510b1e4edf833afe90ac8542e747 +Patch-mainline: v6.0-rc4 +References: git-fixes + +GPIO mockup debugfs is created in gpio_mockup_probe() but +forgot to remove when remove device. This patch add a devm +managed callback for removing them. + +Signed-off-by: Wei Yongjun +Signed-off-by: Bartosz Golaszewski +Acked-by: Takashi Iwai + +--- + drivers/gpio/gpio-mockup.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpio/gpio-mockup.c b/drivers/gpio/gpio-mockup.c +index 8943cea92764..a2e505a7545c 100644 +--- a/drivers/gpio/gpio-mockup.c ++++ b/drivers/gpio/gpio-mockup.c +@@ -373,6 +373,13 @@ static void gpio_mockup_debugfs_setup(struct device *dev, + } + } + ++static void gpio_mockup_debugfs_cleanup(void *data) ++{ ++ struct gpio_mockup_chip *chip = data; ++ ++ debugfs_remove_recursive(chip->dbg_dir); ++} ++ + static void gpio_mockup_dispose_mappings(void *data) + { + struct gpio_mockup_chip *chip = data; +@@ -455,7 +462,7 @@ static int gpio_mockup_probe(struct platform_device *pdev) + + gpio_mockup_debugfs_setup(dev, chip); + +- return 0; ++ return devm_add_action_or_reset(dev, gpio_mockup_debugfs_cleanup, chip); + } + + static const struct of_device_id gpio_mockup_of_match[] = { +-- +2.35.3 + diff --git a/patches.suse/gpio-mpc8xxx-Fix-support-for-IRQ_TYPE_LEVEL_LOW-flow.patch b/patches.suse/gpio-mpc8xxx-Fix-support-for-IRQ_TYPE_LEVEL_LOW-flow.patch new file mode 100644 index 0000000..802d493 --- /dev/null +++ b/patches.suse/gpio-mpc8xxx-Fix-support-for-IRQ_TYPE_LEVEL_LOW-flow.patch @@ -0,0 +1,47 @@ +From 279c12df8d2efb28def9d037f288cbfb97c30fe2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= +Date: Tue, 6 Sep 2022 12:54:31 +0200 +Subject: [PATCH] gpio: mpc8xxx: Fix support for IRQ_TYPE_LEVEL_LOW flow_type in mpc85xx +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 279c12df8d2efb28def9d037f288cbfb97c30fe2 +Patch-mainline: v6.0-rc6 +References: git-fixes + +Commit e39d5ef67804 ("powerpc/5xxx: extend mpc8xxx_gpio driver to support +mpc512x gpios") implemented support for IRQ_TYPE_LEVEL_LOW flow type in +mpc512x via falling edge type. Do same for mpc85xx which support was added +in commit 345e5c8a1cc3 ("powerpc: Add interrupt support to mpc8xxx_gpio"). + +Fixes probing of lm90 hwmon driver on mpc85xx based board which use level +interrupt. Without it kernel prints error and refuse lm90 to work: + + [ 15.258370] genirq: Setting trigger mode 8 for irq 49 failed (mpc8xxx_irq_set_type+0x0/0xf8) + [ 15.267168] lm90 0-004c: cannot request IRQ 49 + [ 15.272708] lm90: probe of 0-004c failed with error -22 + +Fixes: 345e5c8a1cc3 ("powerpc: Add interrupt support to mpc8xxx_gpio") +Signed-off-by: Pali Rohár +Signed-off-by: Bartosz Golaszewski +Acked-by: Takashi Iwai + +--- + drivers/gpio/gpio-mpc8xxx.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c +index 15049822937a..3eb08cd1fdc0 100644 +--- a/drivers/gpio/gpio-mpc8xxx.c ++++ b/drivers/gpio/gpio-mpc8xxx.c +@@ -169,6 +169,7 @@ static int mpc8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type) + + switch (flow_type) { + case IRQ_TYPE_EDGE_FALLING: ++ case IRQ_TYPE_LEVEL_LOW: + raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags); + gc->write_reg(mpc8xxx_gc->regs + GPIO_ICR, + gc->read_reg(mpc8xxx_gc->regs + GPIO_ICR) +-- +2.35.3 + diff --git a/patches.suse/gpio-mvebu-Fix-check-for-pwm-support-on-non-A8K-plat.patch b/patches.suse/gpio-mvebu-Fix-check-for-pwm-support-on-non-A8K-plat.patch new file mode 100644 index 0000000..ecb083c --- /dev/null +++ b/patches.suse/gpio-mvebu-Fix-check-for-pwm-support-on-non-A8K-plat.patch @@ -0,0 +1,60 @@ +From 4335417da2b8d6d9b2d4411b5f9e248e5bb2d380 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= +Date: Thu, 14 Jul 2022 20:33:25 +0200 +Subject: [PATCH] gpio: mvebu: Fix check for pwm support on non-A8K platforms +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 4335417da2b8d6d9b2d4411b5f9e248e5bb2d380 +Patch-mainline: v6.0 +References: git-fixes + +pwm support incompatible with Armada 80x0/70x0 API is not only in +Armada 370, but also in Armada XP, 38x and 39x. So basically every non-A8K +platform. Fix check for pwm support appropriately. + +Fixes: 85b7d8abfec7 ("gpio: mvebu: add pwm support for Armada 8K/7K") +Signed-off-by: Pali Rohár +Signed-off-by: Bartosz Golaszewski +Acked-by: Takashi Iwai + +--- + drivers/gpio/gpio-mvebu.c | 15 ++++++--------- + 1 file changed, 6 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c +index aa126ab80f0c..1bb317b8dcce 100644 +--- a/drivers/gpio/gpio-mvebu.c ++++ b/drivers/gpio/gpio-mvebu.c +@@ -790,8 +790,12 @@ static int mvebu_pwm_probe(struct platform_device *pdev, + u32 offset; + u32 set; + +- if (of_device_is_compatible(mvchip->chip.of_node, +- "marvell,armada-370-gpio")) { ++ if (mvchip->soc_variant == MVEBU_GPIO_SOC_VARIANT_A8K) { ++ int ret = of_property_read_u32(dev->of_node, ++ "marvell,pwm-offset", &offset); ++ if (ret < 0) ++ return 0; ++ } else { + /* + * There are only two sets of PWM configuration registers for + * all the GPIO lines on those SoCs which this driver reserves +@@ -801,13 +805,6 @@ static int mvebu_pwm_probe(struct platform_device *pdev, + if (!platform_get_resource_byname(pdev, IORESOURCE_MEM, "pwm")) + return 0; + offset = 0; +- } else if (mvchip->soc_variant == MVEBU_GPIO_SOC_VARIANT_A8K) { +- int ret = of_property_read_u32(dev->of_node, +- "marvell,pwm-offset", &offset); +- if (ret < 0) +- return 0; +- } else { +- return 0; + } + + if (IS_ERR(mvchip->clk)) +-- +2.35.3 + diff --git a/patches.suse/gpiolib-cdev-Set-lineevent_state-irq-after-IRQ-regis.patch b/patches.suse/gpiolib-cdev-Set-lineevent_state-irq-after-IRQ-regis.patch new file mode 100644 index 0000000..05c427d --- /dev/null +++ b/patches.suse/gpiolib-cdev-Set-lineevent_state-irq-after-IRQ-regis.patch @@ -0,0 +1,70 @@ +From 69bef19d6b9700e96285f4b4e28691cda3dcd0d1 Mon Sep 17 00:00:00 2001 +From: Meng Li +Date: Wed, 21 Sep 2022 11:20:20 +0800 +Subject: [PATCH] gpiolib: cdev: Set lineevent_state::irq after IRQ register successfully +Git-commit: 69bef19d6b9700e96285f4b4e28691cda3dcd0d1 +Patch-mainline: v6.0-rc7 +References: git-fixes + +When running gpio test on nxp-ls1028 platform with below command +gpiomon --num-events=3 --rising-edge gpiochip1 25 +There will be a warning trace as below: +Call trace: +free_irq+0x204/0x360 +lineevent_free+0x64/0x70 +gpio_ioctl+0x598/0x6a0 +__arm64_sys_ioctl+0xb4/0x100 +invoke_syscall+0x5c/0x130 +...... +el0t_64_sync+0x1a0/0x1a4 +The reason of this issue is that calling request_threaded_irq() +function failed, and then lineevent_free() is invoked to release +the resource. Since the lineevent_state::irq was already set, so +the subsequent invocation of free_irq() would trigger the above +warning call trace. To fix this issue, set the lineevent_state::irq +after the IRQ register successfully. + +Fixes: 468242724143 ("gpiolib: cdev: refactor lineevent cleanup into lineevent_free") +Cc: stable@vger.kernel.org +Signed-off-by: Meng Li +Reviewed-by: Kent Gibson +Signed-off-by: Bartosz Golaszewski +Acked-by: Takashi Iwai + +--- + drivers/gpio/gpiolib-cdev.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c +index f8041d4898d1..92f185575e94 100644 +--- a/drivers/gpio/gpiolib-cdev.c ++++ b/drivers/gpio/gpiolib-cdev.c +@@ -1986,7 +1986,6 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip) + ret = -ENODEV; + goto out_free_le; + } +- le->irq = irq; + + if (eflags & GPIOEVENT_REQUEST_RISING_EDGE) + irqflags |= test_bit(FLAG_ACTIVE_LOW, &desc->flags) ? +@@ -2000,7 +1999,7 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip) + init_waitqueue_head(&le->wait); + + /* Request a thread to read the events */ +- ret = request_threaded_irq(le->irq, ++ ret = request_threaded_irq(irq, + lineevent_irq_handler, + lineevent_irq_thread, + irqflags, +@@ -2009,6 +2008,8 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip) + if (ret) + goto out_free_le; + ++ le->irq = irq; ++ + fd = get_unused_fd_flags(O_RDONLY | O_CLOEXEC); + if (fd < 0) { + ret = fd; +-- +2.35.3 + diff --git a/patches.suse/gve-Fix-GFP-flags-when-allocing-pages-8ccac4edc8da.patch b/patches.suse/gve-Fix-GFP-flags-when-allocing-pages-8ccac4edc8da.patch new file mode 100644 index 0000000..de2519c --- /dev/null +++ b/patches.suse/gve-Fix-GFP-flags-when-allocing-pages-8ccac4edc8da.patch @@ -0,0 +1,42 @@ +From 8ccac4edc8da764389d4fc18b1df740892006557 Mon Sep 17 00:00:00 2001 +From: Shailend Chand +Date: Mon, 12 Sep 2022 17:09:01 -0700 +Subject: [PATCH] gve: Fix GFP flags when allocing pages +Git-commit: 8ccac4edc8da764389d4fc18b1df740892006557 +Patch-mainline: v6.0-rc7 +References: git-fixes + +Use GFP_ATOMIC when allocating pages out of the hotpath, +continue to use GFP_KERNEL when allocating pages during setup. + +GFP_KERNEL will allow blocking which allows it to succeed +more often in a low memory enviornment but in the hotpath we do +not want to allow the allocation to block. + +Fixes: 9b8dd5e5ea48b ("gve: DQO: Add RX path") +Signed-off-by: Shailend Chand +Signed-off-by: Jeroen de Borst +Link: https://lore.kernel.org/r/20220913000901.959546-1-jeroendb@google.com +Signed-off-by: Jakub Kicinski +Acked-by: Takashi Iwai + +--- + drivers/net/ethernet/google/gve/gve_rx_dqo.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/google/gve/gve_rx_dqo.c b/drivers/net/ethernet/google/gve/gve_rx_dqo.c +index 8c939628e2d8..2e6461b0ea8b 100644 +--- a/drivers/net/ethernet/google/gve/gve_rx_dqo.c ++++ b/drivers/net/ethernet/google/gve/gve_rx_dqo.c +@@ -157,7 +157,7 @@ static int gve_alloc_page_dqo(struct gve_priv *priv, + int err; + + err = gve_alloc_page(priv, &priv->pdev->dev, &buf_state->page_info.page, +- &buf_state->addr, DMA_FROM_DEVICE, GFP_KERNEL); ++ &buf_state->addr, DMA_FROM_DEVICE, GFP_ATOMIC); + if (err) + return err; + +-- +2.35.3 + diff --git a/patches.suse/habanalabs-select-CRC32.patch b/patches.suse/habanalabs-select-CRC32.patch new file mode 100644 index 0000000..24e182a --- /dev/null +++ b/patches.suse/habanalabs-select-CRC32.patch @@ -0,0 +1,34 @@ +From f6fb34390cd047543ff00b34b8ad910bf76c8eb3 Mon Sep 17 00:00:00 2001 +From: Vegard Nossum +Date: Mon, 11 Oct 2021 17:14:43 +0200 +Subject: [PATCH] habanalabs: select CRC32 +Git-commit: f6fb34390cd047543ff00b34b8ad910bf76c8eb3 +References: git-fixes +Patch-mainline: v5.16-rc1 + +Fix the following build/link error by adding a dependency on the CRC32 +routines: + + ld: drivers/misc/habanalabs/common/firmware_if.o: in function `hl_fw_dynamic_request_descriptor': + firmware_if.c:(.text.unlikely+0xc89): undefined reference to `crc32_le' + +Fixes: 8a43c83fec12 ("habanalabs: load boot fit to device") +Signed-off-by: Vegard Nossum +Acked-by: Arnd Bergmann +Reviewed-by: Oded Gabbay +Signed-off-by: Oded Gabbay +Signed-off-by: Oliver Neukum +--- + drivers/misc/habanalabs/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/misc/habanalabs/Kconfig ++++ b/drivers/misc/habanalabs/Kconfig +@@ -8,6 +8,7 @@ config HABANA_AI + depends on PCI && HAS_IOMEM + select GENERIC_ALLOCATOR + select HWMON ++ select CRC32 + help + Enables PCIe card driver for Habana's AI Processors (AIP) that are + designed to accelerate Deep Learning inference and training workloads. diff --git a/patches.suse/hid-hid-logitech-hidpp-avoid-unnecessary-assignments.patch b/patches.suse/hid-hid-logitech-hidpp-avoid-unnecessary-assignments.patch new file mode 100644 index 0000000..9bd4576 --- /dev/null +++ b/patches.suse/hid-hid-logitech-hidpp-avoid-unnecessary-assignments.patch @@ -0,0 +1,40 @@ +From 98d67f250472cdd0f8d083830be3ec9dbb0c65a8 Mon Sep 17 00:00:00 2001 +From: Hangyu Hua +Date: Fri, 12 Aug 2022 10:55:15 +0800 +Subject: [PATCH] hid: hid-logitech-hidpp: avoid unnecessary assignments in hidpp_connect_event +Git-commit: 98d67f250472cdd0f8d083830be3ec9dbb0c65a8 +Patch-mainline: v6.1-rc1 +References: git-fixes + +hidpp->delayed_input can't be assigned to an object that already call +input_free_device when input_register_device fails. + +Fixes: c39e3d5fc9dd ("HID: logitech-hidpp: late bind the input device on wireless connection") +Signed-off-by: Hangyu Hua +Signed-off-by: Benjamin Tissoires +Link: https://lore.kernel.org/r/20220812025515.19467-1-hbh25y@gmail.com +Acked-by: Takashi Iwai + +--- + drivers/hid/hid-logitech-hidpp.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c +index 5f8261c7b74c..71a9c258a20b 100644 +--- a/drivers/hid/hid-logitech-hidpp.c ++++ b/drivers/hid/hid-logitech-hidpp.c +@@ -4007,8 +4007,10 @@ static void hidpp_connect_event(struct hidpp_device *hidpp) + hidpp_populate_input(hidpp, input); + + ret = input_register_device(input); +- if (ret) ++ if (ret) { + input_free_device(input); ++ return; ++ } + + hidpp->delayed_input = input; + } +-- +2.35.3 + diff --git a/patches.suse/hid-intel-ish-hid-ishtp-Fix-ishtp-client-sending-dis.patch b/patches.suse/hid-intel-ish-hid-ishtp-Fix-ishtp-client-sending-dis.patch new file mode 100644 index 0000000..669d9f1 --- /dev/null +++ b/patches.suse/hid-intel-ish-hid-ishtp-Fix-ishtp-client-sending-dis.patch @@ -0,0 +1,153 @@ +From e1fa076706209cc447d7a2abd0843a18277e5ef7 Mon Sep 17 00:00:00 2001 +From: Even Xu +Date: Thu, 4 Aug 2022 08:59:19 +0800 +Subject: [PATCH] hid: intel-ish-hid: ishtp: Fix ishtp client sending disordered message +Git-commit: e1fa076706209cc447d7a2abd0843a18277e5ef7 +Patch-mainline: v6.0-rc4 +References: git-fixes + +There is a timing issue captured during ishtp client sending stress tests. +It was observed during stress tests that ISH firmware is getting out of +ordered messages. This is a rare scenario as the current set of ISH client +drivers don't send much data to firmware. But this may not be the case +going forward. + +When message size is bigger than IPC MTU, ishtp splits the message into +fragments and uses serialized async method to send message fragments. +The call stack: +ishtp_cl_send_msg_ipc->ipc_tx_callback(first fregment)-> +ishtp_send_msg(with callback)->write_ipc_to_queue-> +write_ipc_from_queue->callback->ipc_tx_callback(next fregment)...... + +When an ipc write complete interrupt is received, driver also calls +write_ipc_from_queue->ipc_tx_callback in ISR to start sending of next fragment. + +Through ipc_tx_callback uses spin_lock to protect message splitting, as the +serialized sending method will call back to ipc_tx_callback again, so it doesn't +put sending under spin_lock, it causes driver cannot guarantee all fragments +be sent in order. + +Considering this scenario: +ipc_tx_callback just finished a fragment splitting, and not call ishtp_send_msg +yet, there is a write complete interrupt happens, then ISR->write_ipc_from_queue +->ipc_tx_callback->ishtp_send_msg->write_ipc_to_queue...... + +Because ISR has higher exec priority than normal thread, this causes the new +fragment be sent out before previous fragment. This disordered message causes +invalid message to firmware. + +The solution is, to send fragments synchronously: +Use ishtp_write_message writing fragments into tx queue directly one by one, +instead of ishtp_send_msg only writing one fragment with completion callback. +As no completion callback be used, so change ipc_tx_callback to ipc_tx_send. + +Signed-off-by: Even Xu +Acked-by: Srinivas Pandruvada +Signed-off-by: Jiri Kosina +Acked-by: Takashi Iwai + +--- + drivers/hid/intel-ish-hid/ishtp/client.c | 68 ++++++++++++++---------- + 1 file changed, 39 insertions(+), 29 deletions(-) + +diff --git a/drivers/hid/intel-ish-hid/ishtp/client.c b/drivers/hid/intel-ish-hid/ishtp/client.c +index 405e0d5212cc..df0a825694f5 100644 +--- a/drivers/hid/intel-ish-hid/ishtp/client.c ++++ b/drivers/hid/intel-ish-hid/ishtp/client.c +@@ -626,13 +626,14 @@ static void ishtp_cl_read_complete(struct ishtp_cl_rb *rb) + } + + /** +- * ipc_tx_callback() - IPC tx callback function ++ * ipc_tx_send() - IPC tx send function + * @prm: Pointer to client device instance + * +- * Send message over IPC either first time or on callback on previous message +- * completion ++ * Send message over IPC. Message will be split into fragments ++ * if message size is bigger than IPC FIFO size, and all ++ * fragments will be sent one by one. + */ +-static void ipc_tx_callback(void *prm) ++static void ipc_tx_send(void *prm) + { + struct ishtp_cl *cl = prm; + struct ishtp_cl_tx_ring *cl_msg; +@@ -677,32 +678,41 @@ static void ipc_tx_callback(void *prm) + list); + rem = cl_msg->send_buf.size - cl->tx_offs; + +- ishtp_hdr.host_addr = cl->host_client_id; +- ishtp_hdr.fw_addr = cl->fw_client_id; +- ishtp_hdr.reserved = 0; +- pmsg = cl_msg->send_buf.data + cl->tx_offs; ++ while (rem > 0) { ++ ishtp_hdr.host_addr = cl->host_client_id; ++ ishtp_hdr.fw_addr = cl->fw_client_id; ++ ishtp_hdr.reserved = 0; ++ pmsg = cl_msg->send_buf.data + cl->tx_offs; ++ ++ if (rem <= dev->mtu) { ++ /* Last fragment or only one packet */ ++ ishtp_hdr.length = rem; ++ ishtp_hdr.msg_complete = 1; ++ /* Submit to IPC queue with no callback */ ++ ishtp_write_message(dev, &ishtp_hdr, pmsg); ++ cl->tx_offs = 0; ++ cl->sending = 0; + +- if (rem <= dev->mtu) { +- ishtp_hdr.length = rem; +- ishtp_hdr.msg_complete = 1; +- cl->sending = 0; +- list_del_init(&cl_msg->list); /* Must be before write */ +- spin_unlock_irqrestore(&cl->tx_list_spinlock, tx_flags); +- /* Submit to IPC queue with no callback */ +- ishtp_write_message(dev, &ishtp_hdr, pmsg); +- spin_lock_irqsave(&cl->tx_free_list_spinlock, tx_free_flags); +- list_add_tail(&cl_msg->list, &cl->tx_free_list.list); +- ++cl->tx_ring_free_size; +- spin_unlock_irqrestore(&cl->tx_free_list_spinlock, +- tx_free_flags); +- } else { +- /* Send IPC fragment */ +- spin_unlock_irqrestore(&cl->tx_list_spinlock, tx_flags); +- cl->tx_offs += dev->mtu; +- ishtp_hdr.length = dev->mtu; +- ishtp_hdr.msg_complete = 0; +- ishtp_send_msg(dev, &ishtp_hdr, pmsg, ipc_tx_callback, cl); ++ break; ++ } else { ++ /* Send ipc fragment */ ++ ishtp_hdr.length = dev->mtu; ++ ishtp_hdr.msg_complete = 0; ++ /* All fregments submitted to IPC queue with no callback */ ++ ishtp_write_message(dev, &ishtp_hdr, pmsg); ++ cl->tx_offs += dev->mtu; ++ rem = cl_msg->send_buf.size - cl->tx_offs; ++ } + } ++ ++ list_del_init(&cl_msg->list); ++ spin_unlock_irqrestore(&cl->tx_list_spinlock, tx_flags); ++ ++ spin_lock_irqsave(&cl->tx_free_list_spinlock, tx_free_flags); ++ list_add_tail(&cl_msg->list, &cl->tx_free_list.list); ++ ++cl->tx_ring_free_size; ++ spin_unlock_irqrestore(&cl->tx_free_list_spinlock, ++ tx_free_flags); + } + + /** +@@ -720,7 +730,7 @@ static void ishtp_cl_send_msg_ipc(struct ishtp_device *dev, + return; + + cl->tx_offs = 0; +- ipc_tx_callback(cl); ++ ipc_tx_send(cl); + ++cl->send_msg_cnt_ipc; + } + +-- +2.35.3 + diff --git a/patches.suse/hinic-Avoid-some-over-memory-allocation.patch b/patches.suse/hinic-Avoid-some-over-memory-allocation.patch new file mode 100644 index 0000000..093c5ca --- /dev/null +++ b/patches.suse/hinic-Avoid-some-over-memory-allocation.patch @@ -0,0 +1,35 @@ +From 8554b66328fae7955d9eb4e3c69825c58a17a2c9 Mon Sep 17 00:00:00 2001 +From: Christophe JAILLET +Date: Sat, 21 May 2022 08:33:01 +0200 +Subject: [PATCH 05/32] hinic: Avoid some over memory allocation +Git-commit: 15d221d0c345b76947911a3ac91897ffe2f1cc4e +References: git-fixes +Patch-mainline: v5.19-rc1 + +'prod_idx' (atomic_t) is larger than 'shadow_idx' (u16), so some memory is +over-allocated. + +Fixes: b15a9f37be2b ("net-next/hinic: Add wq") +Signed-off-by: Christophe JAILLET +Signed-off-by: David S. Miller +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c +index f7dc7d825f63..4daf6bf291ec 100644 +--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c ++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c +@@ -386,7 +386,7 @@ static int alloc_wqes_shadow(struct hinic_wq *wq) + return -ENOMEM; + + wq->shadow_idx = devm_kcalloc(&pdev->dev, wq->num_q_pages, +- sizeof(wq->prod_idx), GFP_KERNEL); ++ sizeof(*wq->shadow_idx), GFP_KERNEL); + if (!wq->shadow_idx) + goto err_shadow_idx; + +-- +2.16.4 + diff --git a/patches.suse/hwmon-gsc-hwmon-Call-of_node_get-before-of_find_xxx-.patch b/patches.suse/hwmon-gsc-hwmon-Call-of_node_get-before-of_find_xxx-.patch new file mode 100644 index 0000000..0ad9c5c --- /dev/null +++ b/patches.suse/hwmon-gsc-hwmon-Call-of_node_get-before-of_find_xxx-.patch @@ -0,0 +1,35 @@ +From 7f62cf781e6567d59c8935dc8c6068ce2bb904b7 Mon Sep 17 00:00:00 2001 +From: Liang He +Date: Fri, 16 Sep 2022 23:47:08 +0800 +Subject: [PATCH] hwmon: (gsc-hwmon) Call of_node_get() before of_find_xxx API +Git-commit: 7f62cf781e6567d59c8935dc8c6068ce2bb904b7 +Patch-mainline: v6.1-rc1 +References: git-fixes + +In gsc_hwmon_get_devtree_pdata(), we should call of_node_get() before +the of_find_compatible_node() which will automatically call +of_node_put() for the 'from' argument. + +Fixes: 3bce5377ef66 ("hwmon: Add Gateworks System Controller support") +Signed-off-by: Liang He +Co-developed-by: Mengda Chen +Signed-off-by: Mengda Chen +Link: https://lore.kernel.org/r/20220916154708.3084515-1-chenmengda2009@163.com +Cc: stable@vger.kernel.org +Signed-off-by: Guenter Roeck +Acked-by: Takashi Iwai + +--- + drivers/hwmon/gsc-hwmon.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/hwmon/gsc-hwmon.c ++++ b/drivers/hwmon/gsc-hwmon.c +@@ -267,6 +267,7 @@ gsc_hwmon_get_devtree_pdata(struct devic + pdata->nchannels = nchannels; + + /* fan controller base address */ ++ of_node_get(dev->parent->of_node); + fan = of_find_compatible_node(dev->parent->of_node, NULL, "gw,gsc-fan"); + if (fan && of_property_read_u32(fan, "reg", &pdata->fan_base)) { + dev_err(dev, "fan node without base\n"); diff --git a/patches.suse/hwmon-pmbus-mp2888-Fix-sensors-readouts-for-MPS-Mult.patch b/patches.suse/hwmon-pmbus-mp2888-Fix-sensors-readouts-for-MPS-Mult.patch new file mode 100644 index 0000000..5624499 --- /dev/null +++ b/patches.suse/hwmon-pmbus-mp2888-Fix-sensors-readouts-for-MPS-Mult.patch @@ -0,0 +1,80 @@ +From 525dd5aed67a2f4f7278116fb92a24e6a53e2622 Mon Sep 17 00:00:00 2001 +From: Oleksandr Shamray +Date: Thu, 29 Sep 2022 15:16:42 +0300 +Subject: [PATCH] hwmon: (pmbus/mp2888) Fix sensors readouts for MPS Multi-phase mp2888 controller +Git-commit: 525dd5aed67a2f4f7278116fb92a24e6a53e2622 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Fix scale factors for reading MPS Multi-phase mp2888 controller. +Fixed sensors: + - PIN/POUT: based on vendor documentation, set bscale factor 0.5W/LSB + - IOUT: based on vendor documentation, set scale factor 0.25 A/LSB + +Fixes: e4db7719d037 ("hwmon: (pmbus) Add support for MPS Multi-phase mp2888 controller") +Signed-off-by: Oleksandr Shamray +Reviewed-by: Vadim Pasternak +Link: https://lore.kernel.org/r/20220929121642.63051-1-oleksandrs@nvidia.com +Signed-off-by: Guenter Roeck +Acked-by: Takashi Iwai + +--- + drivers/hwmon/pmbus/mp2888.c | 13 ++++++------- + 1 file changed, 6 insertions(+), 7 deletions(-) + +diff --git a/drivers/hwmon/pmbus/mp2888.c b/drivers/hwmon/pmbus/mp2888.c +index 8ecd4adfef40..24e5194706cf 100644 +--- a/drivers/hwmon/pmbus/mp2888.c ++++ b/drivers/hwmon/pmbus/mp2888.c +@@ -34,7 +34,7 @@ struct mp2888_data { + int curr_sense_gain; + }; + +-#define to_mp2888_data(x) container_of(x, struct mp2888_data, info) ++#define to_mp2888_data(x) container_of(x, struct mp2888_data, info) + + static int mp2888_read_byte_data(struct i2c_client *client, int page, int reg) + { +@@ -109,7 +109,7 @@ mp2888_read_phase(struct i2c_client *client, struct mp2888_data *data, int page, + * - Kcs is the DrMOS current sense gain of power stage, which is obtained from the + * register MP2888_MFR_VR_CONFIG1, bits 13-12 with the following selection of DrMOS + * (data->curr_sense_gain): +- * 00b - 5µA/A, 01b - 8.5µA/A, 10b - 9.7µA/A, 11b - 10µA/A. ++ * 00b - 8.5µA/A, 01b - 9.7µA/A, 1b - 10µA/A, 11b - 5µA/A. + * - Rcs is the internal phase current sense resistor. This parameter depends on hardware + * assembly. By default it is set to 1kΩ. In case of different assembly, user should + * scale this parameter by dividing it by Rcs. +@@ -118,10 +118,9 @@ mp2888_read_phase(struct i2c_client *client, struct mp2888_data *data, int page, + * because sampling of current occurrence of bit weight has a big deviation, especially for + * light load. + */ +- ret = DIV_ROUND_CLOSEST(ret * 100 - 9800, data->curr_sense_gain); +- ret = (data->phase_curr_resolution) ? ret * 2 : ret; ++ ret = DIV_ROUND_CLOSEST(ret * 200 - 19600, data->curr_sense_gain); + /* Scale according to total current resolution. */ +- ret = (data->total_curr_resolution) ? ret * 8 : ret * 4; ++ ret = (data->total_curr_resolution) ? ret * 2 : ret; + return ret; + } + +@@ -212,7 +211,7 @@ static int mp2888_read_word_data(struct i2c_client *client, int page, int phase, + ret = pmbus_read_word_data(client, page, phase, reg); + if (ret < 0) + return ret; +- ret = data->total_curr_resolution ? ret * 2 : ret; ++ ret = data->total_curr_resolution ? ret : DIV_ROUND_CLOSEST(ret, 2); + break; + case PMBUS_POUT_OP_WARN_LIMIT: + ret = pmbus_read_word_data(client, page, phase, reg); +@@ -223,7 +222,7 @@ static int mp2888_read_word_data(struct i2c_client *client, int page, int phase, + * set 1. Actual power is reported with 0.5W or 1W respectively resolution. Scaling + * is needed to match both. + */ +- ret = data->total_curr_resolution ? ret * 4 : ret * 2; ++ ret = data->total_curr_resolution ? ret * 2 : ret; + break; + /* + * The below registers are not implemented by device or implemented not according to the +-- +2.35.3 + diff --git a/patches.suse/i2c-acpi-Add-an-i2c_acpi_client_count-helper-functio.patch b/patches.suse/i2c-acpi-Add-an-i2c_acpi_client_count-helper-functio.patch new file mode 100644 index 0000000..e46b598 --- /dev/null +++ b/patches.suse/i2c-acpi-Add-an-i2c_acpi_client_count-helper-functio.patch @@ -0,0 +1,94 @@ +From 20a1b3acfc802ad7b6b327f2bdc0570711538561 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Tue, 3 Aug 2021 18:00:41 +0200 +Subject: [PATCH] i2c: acpi: Add an i2c_acpi_client_count() helper function +Git-commit: 20a1b3acfc802ad7b6b327f2bdc0570711538561 +Patch-mainline: v5.15-rc1 +References: bsc#1203699 + +We have 3 files now which have the need to count the number of +I2cSerialBus resources in an ACPI-device's resource-list. + +Currently all implement their own helper function for this, +add a generic helper function to replace the 3 implementations. + +Signed-off-by: Hans de Goede +Link: https://lore.kernel.org/r/20210803160044.158802-2-hdegoede@redhat.com +Acked-by: Mika Westerberg +Acked-by: Wolfram Sang +Acked-by: Takashi Iwai + +--- + drivers/i2c/i2c-core-acpi.c | 32 ++++++++++++++++++++++++++++++++ + include/linux/i2c.h | 5 +++++ + 2 files changed, 37 insertions(+) + +diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c +index 6f0aa0ed3241..aaeeacc12121 100644 +--- a/drivers/i2c/i2c-core-acpi.c ++++ b/drivers/i2c/i2c-core-acpi.c +@@ -69,6 +69,38 @@ bool i2c_acpi_get_i2c_resource(struct acpi_resource *ares, + } + EXPORT_SYMBOL_GPL(i2c_acpi_get_i2c_resource); + ++static int i2c_acpi_resource_count(struct acpi_resource *ares, void *data) ++{ ++ struct acpi_resource_i2c_serialbus *sb; ++ int *count = data; ++ ++ if (i2c_acpi_get_i2c_resource(ares, &sb)) ++ *count = *count + 1; ++ ++ return 1; ++} ++ ++/** ++ * i2c_acpi_client_count - Count the number of I2cSerialBus resources ++ * @adev: ACPI device ++ * ++ * Returns the number of I2cSerialBus resources in the ACPI-device's ++ * resource-list; or a negative error code. ++ */ ++int i2c_acpi_client_count(struct acpi_device *adev) ++{ ++ int ret, count = 0; ++ LIST_HEAD(r); ++ ++ ret = acpi_dev_get_resources(adev, &r, i2c_acpi_resource_count, &count); ++ if (ret < 0) ++ return ret; ++ ++ acpi_dev_free_resource_list(&r); ++ return count; ++} ++EXPORT_SYMBOL_GPL(i2c_acpi_client_count); ++ + static int i2c_acpi_fill_info(struct acpi_resource *ares, void *data) + { + struct i2c_acpi_lookup *lookup = data; +diff --git a/include/linux/i2c.h b/include/linux/i2c.h +index 3eb60a2e9e61..2ce3efbe9198 100644 +--- a/include/linux/i2c.h ++++ b/include/linux/i2c.h +@@ -1010,6 +1010,7 @@ struct acpi_resource_i2c_serialbus; + #if IS_ENABLED(CONFIG_ACPI) + bool i2c_acpi_get_i2c_resource(struct acpi_resource *ares, + struct acpi_resource_i2c_serialbus **i2c); ++int i2c_acpi_client_count(struct acpi_device *adev); + u32 i2c_acpi_find_bus_speed(struct device *dev); + struct i2c_client *i2c_acpi_new_device(struct device *dev, int index, + struct i2c_board_info *info); +@@ -1020,6 +1021,10 @@ static inline bool i2c_acpi_get_i2c_resource(struct acpi_resource *ares, + { + return false; + } ++static inline int i2c_acpi_client_count(struct acpi_device *adev) ++{ ++ return 0; ++} + static inline u32 i2c_acpi_find_bus_speed(struct device *dev) + { + return 0; +-- +2.35.3 + diff --git a/patches.suse/i2c-designware-Fix-handling-of-real-but-unexpected-d.patch b/patches.suse/i2c-designware-Fix-handling-of-real-but-unexpected-d.patch new file mode 100644 index 0000000..142c026 --- /dev/null +++ b/patches.suse/i2c-designware-Fix-handling-of-real-but-unexpected-d.patch @@ -0,0 +1,116 @@ +From 301c8f5c32c8fb79c67539bc23972dc3ef48024c Mon Sep 17 00:00:00 2001 +From: Jarkko Nikula +Date: Tue, 27 Sep 2022 16:56:44 +0300 +Subject: [PATCH] i2c: designware: Fix handling of real but unexpected device interrupts +Git-commit: 301c8f5c32c8fb79c67539bc23972dc3ef48024c +Patch-mainline: v6.1-rc1 +References: git-fixes + +Commit c7b79a752871 ("mfd: intel-lpss: Add Intel Alder Lake PCH-S PCI +IDs") caused a regression on certain Gigabyte motherboards for Intel +Alder Lake-S where system crashes to NULL pointer dereference in +i2c_dw_xfer_msg() when system resumes from S3 sleep state ("deep"). + +I was able to debug the issue on Gigabyte Z690 AORUS ELITE and made +following notes: + +- Issue happens when resuming from S3 but not when resuming from + "s2idle" +- PCI device 00:15.0 == i2c_designware.0 is already in D0 state when + system enters into pci_pm_resume_noirq() while all other i2c_designware + PCI devices are in D3. Devices were runtime suspended and in D3 prior + entering into suspend +- Interrupt comes after pci_pm_resume_noirq() when device interrupts are + re-enabled +- According to register dump the interrupt really comes from the + i2c_designware.0. Controller is enabled, I2C target address register + points to a one detectable I2C device address 0x60 and the + DW_IC_RAW_INTR_STAT register START_DET, STOP_DET, ACTIVITY and + TX_EMPTY bits are set indicating completed I2C transaction. + +My guess is that the firmware uses this controller to communicate with +an on-board I2C device during resume but does not disable the controller +before giving control to an operating system. + +I was told the UEFI update fixes this but never the less it revealed the +driver is not ready to handle TX_EMPTY (or RX_FULL) interrupt when device +is supposed to be idle and state variables are not set (especially the +dev->msgs pointer which may point to NULL or stale old data). + +Introduce a new software status flag STATUS_ACTIVE indicating when the +controller is active in driver point of view. Now treat all interrupts +that occur when is not set as unexpected and mask all interrupts from +the controller. + +Fixes: c7b79a752871 ("mfd: intel-lpss: Add Intel Alder Lake PCH-S PCI IDs") +Reported-by: Samuel Clark +Link: https://bugzilla.kernel.org/show_bug.cgi?id=215907 +Cc: stable@vger.kernel.org # v5.12+ +Signed-off-by: Jarkko Nikula +Reviewed-by: Andy Shevchenko +Signed-off-by: Wolfram Sang +Acked-by: Takashi Iwai + +--- + drivers/i2c/busses/i2c-designware-core.h | 7 +++++-- + drivers/i2c/busses/i2c-designware-master.c | 13 +++++++++++++ + 2 files changed, 18 insertions(+), 2 deletions(-) + +diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h +index 70b80e710990..4d3a3b464ecd 100644 +--- a/drivers/i2c/busses/i2c-designware-core.h ++++ b/drivers/i2c/busses/i2c-designware-core.h +@@ -126,8 +126,9 @@ + * status codes + */ + #define STATUS_IDLE 0x0 +-#define STATUS_WRITE_IN_PROGRESS 0x1 +-#define STATUS_READ_IN_PROGRESS 0x2 ++#define STATUS_ACTIVE 0x1 ++#define STATUS_WRITE_IN_PROGRESS 0x2 ++#define STATUS_READ_IN_PROGRESS 0x4 + + /* + * operation modes +@@ -334,12 +335,14 @@ void i2c_dw_disable_int(struct dw_i2c_dev *dev); + + static inline void __i2c_dw_enable(struct dw_i2c_dev *dev) + { ++ dev->status |= STATUS_ACTIVE; + regmap_write(dev->map, DW_IC_ENABLE, 1); + } + + static inline void __i2c_dw_disable_nowait(struct dw_i2c_dev *dev) + { + regmap_write(dev->map, DW_IC_ENABLE, 0); ++ dev->status &= ~STATUS_ACTIVE; + } + + void __i2c_dw_disable(struct dw_i2c_dev *dev); +diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c +index 44a94b225ed8..dc3c5a15a95b 100644 +--- a/drivers/i2c/busses/i2c-designware-master.c ++++ b/drivers/i2c/busses/i2c-designware-master.c +@@ -716,6 +716,19 @@ static int i2c_dw_irq_handler_master(struct dw_i2c_dev *dev) + u32 stat; + + stat = i2c_dw_read_clear_intrbits(dev); ++ ++ if (!(dev->status & STATUS_ACTIVE)) { ++ /* ++ * Unexpected interrupt in driver point of view. State ++ * variables are either unset or stale so acknowledge and ++ * disable interrupts for suppressing further interrupts if ++ * interrupt really came from this HW (E.g. firmware has left ++ * the HW active). ++ */ ++ regmap_write(dev->map, DW_IC_INTR_MASK, 0); ++ return 0; ++ } ++ + if (stat & DW_IC_INTR_TX_ABRT) { + dev->cmd_err |= DW_IC_ERR_TX_ABRT; + dev->status = STATUS_IDLE; +-- +2.35.3 + diff --git a/patches.suse/i2c-i801-Add-support-for-Intel-Ice-Lake-PCH-N.patch b/patches.suse/i2c-i801-Add-support-for-Intel-Ice-Lake-PCH-N.patch new file mode 100644 index 0000000..895c572 --- /dev/null +++ b/patches.suse/i2c-i801-Add-support-for-Intel-Ice-Lake-PCH-N.patch @@ -0,0 +1,62 @@ +From 76eb4db611e1012cbdc2461540fe6bb9d40a0f27 Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Fri, 1 Oct 2021 20:21:54 +0300 +Subject: [PATCH] i2c: i801: Add support for Intel Ice Lake PCH-N +Git-commit: 76eb4db611e1012cbdc2461540fe6bb9d40a0f27 +Patch-mainline: v5.16-rc1 +References: jsc#PED-634 + +Add PCI ID of SMBus controller on Intel Ice Lake PCH-N. + +The device can be found on MacBookPro16,2 [1]. + +[1]: https://linux-hardware.org/?probe=f1c5cf0c43 + +Signed-off-by: Andy Shevchenko +Reviewed-by: Jean Delvare +Signed-off-by: Wolfram Sang +Acked-by: Takashi Iwai + +--- + drivers/i2c/busses/i2c-i801.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c +index b6048a571543..05187457f88a 100644 +--- a/drivers/i2c/busses/i2c-i801.c ++++ b/drivers/i2c/busses/i2c-i801.c +@@ -64,6 +64,7 @@ + * Cannon Lake-LP (PCH) 0x9da3 32 hard yes yes yes + * Cedar Fork (PCH) 0x18df 32 hard yes yes yes + * Ice Lake-LP (PCH) 0x34a3 32 hard yes yes yes ++ * Ice Lake-N (PCH) 0x38a3 32 hard yes yes yes + * Comet Lake (PCH) 0x02a3 32 hard yes yes yes + * Comet Lake-H (PCH) 0x06a3 32 hard yes yes yes + * Elkhart Lake (PCH) 0x4b23 32 hard yes yes yes +@@ -218,6 +219,7 @@ + #define PCI_DEVICE_ID_INTEL_COLETOCREEK_SMBUS 0x23b0 + #define PCI_DEVICE_ID_INTEL_GEMINILAKE_SMBUS 0x31d4 + #define PCI_DEVICE_ID_INTEL_ICELAKE_LP_SMBUS 0x34a3 ++#define PCI_DEVICE_ID_INTEL_ICELAKE_N_SMBUS 0x38a3 + #define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS 0x3b30 + #define PCI_DEVICE_ID_INTEL_TIGERLAKE_H_SMBUS 0x43a3 + #define PCI_DEVICE_ID_INTEL_ELKHART_LAKE_SMBUS 0x4b23 +@@ -1042,6 +1044,7 @@ static const struct pci_device_id i801_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CANNONLAKE_H_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CANNONLAKE_LP_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICELAKE_LP_SMBUS) }, ++ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICELAKE_N_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COMETLAKE_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COMETLAKE_H_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COMETLAKE_V_SMBUS) }, +@@ -1701,6 +1704,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) + case PCI_DEVICE_ID_INTEL_CANNONLAKE_LP_SMBUS: + case PCI_DEVICE_ID_INTEL_CDF_SMBUS: + case PCI_DEVICE_ID_INTEL_ICELAKE_LP_SMBUS: ++ case PCI_DEVICE_ID_INTEL_ICELAKE_N_SMBUS: + case PCI_DEVICE_ID_INTEL_COMETLAKE_SMBUS: + case PCI_DEVICE_ID_INTEL_COMETLAKE_H_SMBUS: + case PCI_DEVICE_ID_INTEL_ELKHART_LAKE_SMBUS: +-- +2.35.3 + diff --git a/patches.suse/i2c-i801-Add-support-for-Intel-Meteor-Lake-P.patch b/patches.suse/i2c-i801-Add-support-for-Intel-Meteor-Lake-P.patch new file mode 100644 index 0000000..e13335c --- /dev/null +++ b/patches.suse/i2c-i801-Add-support-for-Intel-Meteor-Lake-P.patch @@ -0,0 +1,77 @@ +From 24fff66f1f26d618d3b16c36603c10175e3d660f Mon Sep 17 00:00:00 2001 +From: Jarkko Nikula +Date: Thu, 30 Jun 2022 10:41:54 +0300 +Subject: [PATCH] i2c: i801: Add support for Intel Meteor Lake-P +Git-commit: 24fff66f1f26d618d3b16c36603c10175e3d660f +Patch-mainline: v6.0-rc1 +References: jsc#PED-732 + +Add SMBus PCI ID on Intel Meteor Lake-P. + +Signed-off-by: Jarkko Nikula +Reviewed-by: Andy Shevchenko +Reviewed-by: Jean Delvare +Signed-off-by: Wolfram Sang +Acked-by: Takashi Iwai + +--- + Documentation/i2c/busses/i2c-i801.rst | 1 + + drivers/i2c/busses/Kconfig | 1 + + drivers/i2c/busses/i2c-i801.c | 3 +++ + 3 files changed, 5 insertions(+) + +diff --git a/Documentation/i2c/busses/i2c-i801.rst b/Documentation/i2c/busses/i2c-i801.rst +index cad59170b2ad..ab9e850e8fe0 100644 +--- a/Documentation/i2c/busses/i2c-i801.rst ++++ b/Documentation/i2c/busses/i2c-i801.rst +@@ -46,6 +46,7 @@ Supported adapters: + * Intel Emmitsburg (PCH) + * Intel Alder Lake (PCH) + * Intel Raptor Lake (PCH) ++ * Intel Meteor Lake (SOC) + + Datasheets: Publicly available at the Intel website + +diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig +index b1d7069dd377..3f6d03073079 100644 +--- a/drivers/i2c/busses/Kconfig ++++ b/drivers/i2c/busses/Kconfig +@@ -156,6 +156,7 @@ config I2C_I801 + Emmitsburg (PCH) + Alder Lake (PCH) + Raptor Lake (PCH) ++ Meteor Lake (SOC) + + This driver can also be built as a module. If so, the module + will be called i2c-i801. +diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c +index ff706349bdfb..9e5b87e107ba 100644 +--- a/drivers/i2c/busses/i2c-i801.c ++++ b/drivers/i2c/busses/i2c-i801.c +@@ -76,6 +76,7 @@ + * Alder Lake-P (PCH) 0x51a3 32 hard yes yes yes + * Alder Lake-M (PCH) 0x54a3 32 hard yes yes yes + * Raptor Lake-S (PCH) 0x7a23 32 hard yes yes yes ++ * Meteor Lake-P (SOC) 0x7e22 32 hard yes yes yes + * + * Features supported by this driver: + * Software PEC no +@@ -231,6 +232,7 @@ + #define PCI_DEVICE_ID_INTEL_BROXTON_SMBUS 0x5ad4 + #define PCI_DEVICE_ID_INTEL_RAPTOR_LAKE_S_SMBUS 0x7a23 + #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_S_SMBUS 0x7aa3 ++#define PCI_DEVICE_ID_INTEL_METEOR_LAKE_P_SMBUS 0x7e22 + #define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS 0x8c22 + #define PCI_DEVICE_ID_INTEL_WILDCATPOINT_SMBUS 0x8ca2 + #define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS 0x8d22 +@@ -1049,6 +1051,7 @@ static const struct pci_device_id i801_ids[] = { + { PCI_DEVICE_DATA(INTEL, ALDER_LAKE_P_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { PCI_DEVICE_DATA(INTEL, ALDER_LAKE_M_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { PCI_DEVICE_DATA(INTEL, RAPTOR_LAKE_S_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, ++ { PCI_DEVICE_DATA(INTEL, METEOR_LAKE_P_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { 0, } + }; + +-- +2.35.3 + diff --git a/patches.suse/i2c-i801-Add-support-for-Intel-Raptor-Lake-PCH-S.patch b/patches.suse/i2c-i801-Add-support-for-Intel-Raptor-Lake-PCH-S.patch new file mode 100644 index 0000000..96d8699 --- /dev/null +++ b/patches.suse/i2c-i801-Add-support-for-Intel-Raptor-Lake-PCH-S.patch @@ -0,0 +1,76 @@ +From 9c02d4011e92b92aa008d6907216a8e501b0443a Mon Sep 17 00:00:00 2001 +From: Jarkko Nikula +Date: Fri, 11 Feb 2022 17:00:01 +0200 +Subject: [PATCH] i2c: i801: Add support for Intel Raptor Lake PCH-S +Git-commit: 9c02d4011e92b92aa008d6907216a8e501b0443a +Patch-mainline: v5.18-rc1 +References: jsc#PED-634 + +Add SMBus PCI ID on Intel Raptor Lake PCH-S. + +Signed-off-by: Jarkko Nikula +Reviewed-by: Jean Delvare +Signed-off-by: Wolfram Sang +Acked-by: Takashi Iwai + +--- + Documentation/i2c/busses/i2c-i801.rst | 1 + + drivers/i2c/busses/Kconfig | 1 + + drivers/i2c/busses/i2c-i801.c | 3 +++ + 3 files changed, 5 insertions(+) + +diff --git a/Documentation/i2c/busses/i2c-i801.rst b/Documentation/i2c/busses/i2c-i801.rst +index 42bbdd6e7fd8..cad59170b2ad 100644 +--- a/Documentation/i2c/busses/i2c-i801.rst ++++ b/Documentation/i2c/busses/i2c-i801.rst +@@ -45,6 +45,7 @@ Supported adapters: + * Intel Jasper Lake (SOC) + * Intel Emmitsburg (PCH) + * Intel Alder Lake (PCH) ++ * Intel Raptor Lake (PCH) + + Datasheets: Publicly available at the Intel website + +diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig +index 1fbb5f1fa7b1..bfe17c42e11d 100644 +--- a/drivers/i2c/busses/Kconfig ++++ b/drivers/i2c/busses/Kconfig +@@ -148,6 +148,7 @@ config I2C_I801 + Jasper Lake (SOC) + Emmitsburg (PCH) + Alder Lake (PCH) ++ Raptor Lake (PCH) + + This driver can also be built as a module. If so, the module + will be called i2c-i801. +diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c +index 7428cc6af5cc..36b086ef1378 100644 +--- a/drivers/i2c/busses/i2c-i801.c ++++ b/drivers/i2c/busses/i2c-i801.c +@@ -75,6 +75,7 @@ + * Alder Lake-S (PCH) 0x7aa3 32 hard yes yes yes + * Alder Lake-P (PCH) 0x51a3 32 hard yes yes yes + * Alder Lake-M (PCH) 0x54a3 32 hard yes yes yes ++ * Raptor Lake-S (PCH) 0x7a23 32 hard yes yes yes + * + * Features supported by this driver: + * Software PEC no +@@ -228,6 +229,7 @@ + #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_P_SMBUS 0x51a3 + #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_M_SMBUS 0x54a3 + #define PCI_DEVICE_ID_INTEL_BROXTON_SMBUS 0x5ad4 ++#define PCI_DEVICE_ID_INTEL_RAPTOR_LAKE_S_SMBUS 0x7a23 + #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_S_SMBUS 0x7aa3 + #define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS 0x8c22 + #define PCI_DEVICE_ID_INTEL_WILDCATPOINT_SMBUS 0x8ca2 +@@ -1041,6 +1043,7 @@ static const struct pci_device_id i801_ids[] = { + { PCI_DEVICE_DATA(INTEL, ALDER_LAKE_S_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { PCI_DEVICE_DATA(INTEL, ALDER_LAKE_P_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { PCI_DEVICE_DATA(INTEL, ALDER_LAKE_M_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, ++ { PCI_DEVICE_DATA(INTEL, RAPTOR_LAKE_S_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { 0, } + }; + +-- +2.35.3 + diff --git a/patches.suse/i2c-i801-Improve-handling-of-chip-specific-feature-d.patch b/patches.suse/i2c-i801-Improve-handling-of-chip-specific-feature-d.patch new file mode 100644 index 0000000..26f5b02 --- /dev/null +++ b/patches.suse/i2c-i801-Improve-handling-of-chip-specific-feature-d.patch @@ -0,0 +1,234 @@ +From 41acd4b03ca9ba9c9a3ab993817112d9b9f7cf44 Mon Sep 17 00:00:00 2001 +From: Heiner Kallweit +Date: Fri, 19 Nov 2021 21:45:54 +0100 +Subject: [PATCH] i2c: i801: Improve handling of chip-specific feature definitions +Git-commit: 41acd4b03ca9ba9c9a3ab993817112d9b9f7cf44 +Patch-mainline: v5.17-rc1 +References: jsc#PED-634 + +Reduce source code and code size by defining the chip features +statically. + +Signed-off-by: Heiner Kallweit +Reviewed-by: Jean Delvare +Tested-by: Jean Delvare +Signed-off-by: Wolfram Sang +Acked-by: Takashi Iwai + +--- + drivers/i2c/busses/i2c-i801.c | 191 ++++++++++++---------------------- + 1 file changed, 66 insertions(+), 125 deletions(-) + +diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c +index 8af502394f46..720f7e9d0de9 100644 +--- a/drivers/i2c/busses/i2c-i801.c ++++ b/drivers/i2c/busses/i2c-i801.c +@@ -997,66 +997,72 @@ static const struct i2c_algorithm smbus_algorithm = { + .functionality = i801_func, + }; + ++#define FEATURES_ICH5 (FEATURE_BLOCK_PROC | FEATURE_I2C_BLOCK_READ | \ ++ FEATURE_IRQ | FEATURE_SMBUS_PEC | \ ++ FEATURE_BLOCK_BUFFER | FEATURE_HOST_NOTIFY) ++#define FEATURES_ICH4 (FEATURE_SMBUS_PEC | FEATURE_BLOCK_BUFFER | \ ++ FEATURE_HOST_NOTIFY) ++ + static const struct pci_device_id i801_ids[] = { +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_3) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_3) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_2) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_3) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_3) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_3) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_4) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_16) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_17) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_17) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_5) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_6) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EP80579_1) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_4) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_5) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_AVOTON_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS0) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS1) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS2) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COLETOCREEK_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_GEMINILAKE_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WILDCATPOINT_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BRASWELL_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CDF_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DNV_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EBG_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BROXTON_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LEWISBURG_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LEWISBURG_SSKU_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_KABYLAKE_PCH_H_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CANNONLAKE_H_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CANNONLAKE_LP_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICELAKE_LP_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICELAKE_N_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COMETLAKE_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COMETLAKE_H_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COMETLAKE_V_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ELKHART_LAKE_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TIGERLAKE_LP_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TIGERLAKE_H_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_JASPER_LAKE_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ALDER_LAKE_S_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ALDER_LAKE_P_SMBUS) }, +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ALDER_LAKE_M_SMBUS) }, ++ { PCI_DEVICE_DATA(INTEL, 82801AA_3, 0) }, ++ { PCI_DEVICE_DATA(INTEL, 82801AB_3, 0) }, ++ { PCI_DEVICE_DATA(INTEL, 82801BA_2, 0) }, ++ { PCI_DEVICE_DATA(INTEL, 82801CA_3, FEATURE_HOST_NOTIFY) }, ++ { PCI_DEVICE_DATA(INTEL, 82801DB_3, FEATURES_ICH4) }, ++ { PCI_DEVICE_DATA(INTEL, 82801EB_3, FEATURES_ICH5) }, ++ { PCI_DEVICE_DATA(INTEL, ESB_4, FEATURES_ICH5) }, ++ { PCI_DEVICE_DATA(INTEL, ICH6_16, FEATURES_ICH5) }, ++ { PCI_DEVICE_DATA(INTEL, ICH7_17, FEATURES_ICH5) }, ++ { PCI_DEVICE_DATA(INTEL, ESB2_17, FEATURES_ICH5) }, ++ { PCI_DEVICE_DATA(INTEL, ICH8_5, FEATURES_ICH5) }, ++ { PCI_DEVICE_DATA(INTEL, ICH9_6, FEATURES_ICH5) }, ++ { PCI_DEVICE_DATA(INTEL, EP80579_1, FEATURES_ICH5) }, ++ { PCI_DEVICE_DATA(INTEL, ICH10_4, FEATURES_ICH5) }, ++ { PCI_DEVICE_DATA(INTEL, ICH10_5, FEATURES_ICH5) }, ++ { PCI_DEVICE_DATA(INTEL, 5_3400_SERIES_SMBUS, FEATURES_ICH5) }, ++ { PCI_DEVICE_DATA(INTEL, COUGARPOINT_SMBUS, FEATURES_ICH5) }, ++ { PCI_DEVICE_DATA(INTEL, PATSBURG_SMBUS, FEATURES_ICH5) }, ++ { PCI_DEVICE_DATA(INTEL, PATSBURG_SMBUS_IDF0, FEATURES_ICH5 | FEATURE_IDF) }, ++ { PCI_DEVICE_DATA(INTEL, PATSBURG_SMBUS_IDF1, FEATURES_ICH5 | FEATURE_IDF) }, ++ { PCI_DEVICE_DATA(INTEL, PATSBURG_SMBUS_IDF2, FEATURES_ICH5 | FEATURE_IDF) }, ++ { PCI_DEVICE_DATA(INTEL, DH89XXCC_SMBUS, FEATURES_ICH5) }, ++ { PCI_DEVICE_DATA(INTEL, PANTHERPOINT_SMBUS, FEATURES_ICH5) }, ++ { PCI_DEVICE_DATA(INTEL, LYNXPOINT_SMBUS, FEATURES_ICH5) }, ++ { PCI_DEVICE_DATA(INTEL, LYNXPOINT_LP_SMBUS, FEATURES_ICH5) }, ++ { PCI_DEVICE_DATA(INTEL, AVOTON_SMBUS, FEATURES_ICH5) }, ++ { PCI_DEVICE_DATA(INTEL, WELLSBURG_SMBUS, FEATURES_ICH5) }, ++ { PCI_DEVICE_DATA(INTEL, WELLSBURG_SMBUS_MS0, FEATURES_ICH5 | FEATURE_IDF) }, ++ { PCI_DEVICE_DATA(INTEL, WELLSBURG_SMBUS_MS1, FEATURES_ICH5 | FEATURE_IDF) }, ++ { PCI_DEVICE_DATA(INTEL, WELLSBURG_SMBUS_MS2, FEATURES_ICH5 | FEATURE_IDF) }, ++ { PCI_DEVICE_DATA(INTEL, COLETOCREEK_SMBUS, FEATURES_ICH5) }, ++ { PCI_DEVICE_DATA(INTEL, GEMINILAKE_SMBUS, FEATURES_ICH5) }, ++ { PCI_DEVICE_DATA(INTEL, WILDCATPOINT_SMBUS, FEATURES_ICH5) }, ++ { PCI_DEVICE_DATA(INTEL, WILDCATPOINT_LP_SMBUS, FEATURES_ICH5) }, ++ { PCI_DEVICE_DATA(INTEL, BAYTRAIL_SMBUS, FEATURES_ICH5) }, ++ { PCI_DEVICE_DATA(INTEL, BRASWELL_SMBUS, FEATURES_ICH5) }, ++ { PCI_DEVICE_DATA(INTEL, SUNRISEPOINT_H_SMBUS, FEATURES_ICH5 | FEATURE_TCO_SPT) }, ++ { PCI_DEVICE_DATA(INTEL, SUNRISEPOINT_LP_SMBUS, FEATURES_ICH5 | FEATURE_TCO_SPT) }, ++ { PCI_DEVICE_DATA(INTEL, CDF_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, ++ { PCI_DEVICE_DATA(INTEL, DNV_SMBUS, FEATURES_ICH5 | FEATURE_TCO_SPT) }, ++ { PCI_DEVICE_DATA(INTEL, EBG_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, ++ { PCI_DEVICE_DATA(INTEL, BROXTON_SMBUS, FEATURES_ICH5) }, ++ { PCI_DEVICE_DATA(INTEL, LEWISBURG_SMBUS, FEATURES_ICH5 | FEATURE_TCO_SPT) }, ++ { PCI_DEVICE_DATA(INTEL, LEWISBURG_SSKU_SMBUS, FEATURES_ICH5 | FEATURE_TCO_SPT) }, ++ { PCI_DEVICE_DATA(INTEL, KABYLAKE_PCH_H_SMBUS, FEATURES_ICH5 | FEATURE_TCO_SPT) }, ++ { PCI_DEVICE_DATA(INTEL, CANNONLAKE_H_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, ++ { PCI_DEVICE_DATA(INTEL, CANNONLAKE_LP_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, ++ { PCI_DEVICE_DATA(INTEL, ICELAKE_LP_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, ++ { PCI_DEVICE_DATA(INTEL, ICELAKE_N_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, ++ { PCI_DEVICE_DATA(INTEL, COMETLAKE_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, ++ { PCI_DEVICE_DATA(INTEL, COMETLAKE_H_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, ++ { PCI_DEVICE_DATA(INTEL, COMETLAKE_V_SMBUS, FEATURES_ICH5 | FEATURE_TCO_SPT) }, ++ { PCI_DEVICE_DATA(INTEL, ELKHART_LAKE_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, ++ { PCI_DEVICE_DATA(INTEL, TIGERLAKE_LP_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, ++ { PCI_DEVICE_DATA(INTEL, TIGERLAKE_H_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, ++ { PCI_DEVICE_DATA(INTEL, JASPER_LAKE_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, ++ { PCI_DEVICE_DATA(INTEL, ALDER_LAKE_S_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, ++ { PCI_DEVICE_DATA(INTEL, ALDER_LAKE_P_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, ++ { PCI_DEVICE_DATA(INTEL, ALDER_LAKE_M_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { 0, } + }; + +@@ -1685,72 +1691,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) + mutex_init(&priv->acpi_lock); + + priv->pci_dev = dev; +- switch (dev->device) { +- case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_SMBUS: +- case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_SMBUS: +- case PCI_DEVICE_ID_INTEL_LEWISBURG_SMBUS: +- case PCI_DEVICE_ID_INTEL_LEWISBURG_SSKU_SMBUS: +- case PCI_DEVICE_ID_INTEL_DNV_SMBUS: +- case PCI_DEVICE_ID_INTEL_KABYLAKE_PCH_H_SMBUS: +- case PCI_DEVICE_ID_INTEL_COMETLAKE_V_SMBUS: +- priv->features |= FEATURE_BLOCK_PROC; +- priv->features |= FEATURE_I2C_BLOCK_READ; +- priv->features |= FEATURE_IRQ; +- priv->features |= FEATURE_SMBUS_PEC; +- priv->features |= FEATURE_BLOCK_BUFFER; +- priv->features |= FEATURE_TCO_SPT; +- priv->features |= FEATURE_HOST_NOTIFY; +- break; +- +- case PCI_DEVICE_ID_INTEL_CANNONLAKE_H_SMBUS: +- case PCI_DEVICE_ID_INTEL_CANNONLAKE_LP_SMBUS: +- case PCI_DEVICE_ID_INTEL_CDF_SMBUS: +- case PCI_DEVICE_ID_INTEL_ICELAKE_LP_SMBUS: +- case PCI_DEVICE_ID_INTEL_ICELAKE_N_SMBUS: +- case PCI_DEVICE_ID_INTEL_COMETLAKE_SMBUS: +- case PCI_DEVICE_ID_INTEL_COMETLAKE_H_SMBUS: +- case PCI_DEVICE_ID_INTEL_ELKHART_LAKE_SMBUS: +- case PCI_DEVICE_ID_INTEL_TIGERLAKE_LP_SMBUS: +- case PCI_DEVICE_ID_INTEL_TIGERLAKE_H_SMBUS: +- case PCI_DEVICE_ID_INTEL_JASPER_LAKE_SMBUS: +- case PCI_DEVICE_ID_INTEL_EBG_SMBUS: +- case PCI_DEVICE_ID_INTEL_ALDER_LAKE_S_SMBUS: +- case PCI_DEVICE_ID_INTEL_ALDER_LAKE_P_SMBUS: +- case PCI_DEVICE_ID_INTEL_ALDER_LAKE_M_SMBUS: +- priv->features |= FEATURE_BLOCK_PROC; +- priv->features |= FEATURE_I2C_BLOCK_READ; +- priv->features |= FEATURE_IRQ; +- priv->features |= FEATURE_SMBUS_PEC; +- priv->features |= FEATURE_BLOCK_BUFFER; +- priv->features |= FEATURE_TCO_CNL; +- priv->features |= FEATURE_HOST_NOTIFY; +- break; +- +- case PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0: +- case PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1: +- case PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2: +- case PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS0: +- case PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS1: +- case PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS2: +- priv->features |= FEATURE_IDF; +- fallthrough; +- default: +- priv->features |= FEATURE_BLOCK_PROC; +- priv->features |= FEATURE_I2C_BLOCK_READ; +- priv->features |= FEATURE_IRQ; +- fallthrough; +- case PCI_DEVICE_ID_INTEL_82801DB_3: +- priv->features |= FEATURE_SMBUS_PEC; +- priv->features |= FEATURE_BLOCK_BUFFER; +- fallthrough; +- case PCI_DEVICE_ID_INTEL_82801CA_3: +- priv->features |= FEATURE_HOST_NOTIFY; +- fallthrough; +- case PCI_DEVICE_ID_INTEL_82801BA_2: +- case PCI_DEVICE_ID_INTEL_82801AB_3: +- case PCI_DEVICE_ID_INTEL_82801AA_3: +- break; +- } ++ priv->features = id->driver_data; + + /* Disable features on user request */ + for (i = 0; i < ARRAY_SIZE(i801_feature_names); i++) { +-- +2.35.3 + diff --git a/patches.suse/i2c-imx-If-pm_runtime_get_sync-returned-1-device-acc.patch b/patches.suse/i2c-imx-If-pm_runtime_get_sync-returned-1-device-acc.patch new file mode 100644 index 0000000..c9d555d --- /dev/null +++ b/patches.suse/i2c-imx-If-pm_runtime_get_sync-returned-1-device-acc.patch @@ -0,0 +1,42 @@ +From 085aacaa73163f4b8a89dec24ecb32cfacd34017 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= +Date: Mon, 12 Sep 2022 15:20:40 +0200 +Subject: [PATCH] i2c: imx: If pm_runtime_get_sync() returned 1 device access is possible +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 085aacaa73163f4b8a89dec24ecb32cfacd34017 +Patch-mainline: v6.0-rc7 +References: git-fixes + +pm_runtime_get_sync() returning 1 also means the device is powered. So +resetting the chip registers in .remove() is possible and should be +done. + +Reported-by: Dan Carpenter +Fixes: d98bdd3a5b50 ("i2c: imx: Make sure to unregister adapter on remove()") +Signed-off-by: Uwe Kleine-König +Acked-by: Oleksij Rempel +Signed-off-by: Wolfram Sang +Acked-by: Takashi Iwai + +--- + drivers/i2c/busses/i2c-imx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c +index e47fa3465671..3082183bd66a 100644 +--- a/drivers/i2c/busses/i2c-imx.c ++++ b/drivers/i2c/busses/i2c-imx.c +@@ -1583,7 +1583,7 @@ static int i2c_imx_remove(struct platform_device *pdev) + if (i2c_imx->dma) + i2c_imx_dma_free(i2c_imx); + +- if (ret == 0) { ++ if (ret >= 0) { + /* setup chip registers to defaults */ + imx_i2c_write_reg(0, i2c_imx, IMX_I2C_IADR); + imx_i2c_write_reg(0, i2c_imx, IMX_I2C_IFDR); +-- +2.35.3 + diff --git a/patches.suse/i2c-mlxbf-Fix-frequency-calculation.patch b/patches.suse/i2c-mlxbf-Fix-frequency-calculation.patch new file mode 100644 index 0000000..ecc832e --- /dev/null +++ b/patches.suse/i2c-mlxbf-Fix-frequency-calculation.patch @@ -0,0 +1,188 @@ +From 37f071ec327b04c83d47637c5e5c2199b39899ca Mon Sep 17 00:00:00 2001 +From: Asmaa Mnebhi +Date: Tue, 20 Sep 2022 13:47:29 -0400 +Subject: [PATCH] i2c: mlxbf: Fix frequency calculation +Git-commit: 37f071ec327b04c83d47637c5e5c2199b39899ca +Patch-mainline: v6.0-rc7 +References: git-fixes + +The i2c-mlxbf.c driver is currently broken because there is a bug +in the calculation of the frequency. core_f, core_r and core_od +are components read from hardware registers and are used to +compute the frequency used to compute different timing parameters. +The shifting mechanism used to get core_f, core_r and core_od is +wrong. Use FIELD_GET to mask and shift the bitfields properly. + +Fixes: b5b5b32081cd206b (i2c: mlxbf: I2C SMBus driver for Mellanox BlueField SoC) +Reviewed-by: Khalil Blaiech +Signed-off-by: Asmaa Mnebhi +Signed-off-by: Wolfram Sang +Acked-by: Takashi Iwai + +--- + drivers/i2c/busses/i2c-mlxbf.c | 63 +++++++++++++--------------------- + 1 file changed, 23 insertions(+), 40 deletions(-) + +diff --git a/drivers/i2c/busses/i2c-mlxbf.c b/drivers/i2c/busses/i2c-mlxbf.c +index ac93c0ccf53c..ad5efd7497d1 100644 +--- a/drivers/i2c/busses/i2c-mlxbf.c ++++ b/drivers/i2c/busses/i2c-mlxbf.c +@@ -6,6 +6,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -63,13 +64,14 @@ + */ + #define MLXBF_I2C_TYU_PLL_OUT_FREQ (400 * 1000 * 1000) + /* Reference clock for Bluefield - 156 MHz. */ +-#define MLXBF_I2C_PLL_IN_FREQ (156 * 1000 * 1000) ++#define MLXBF_I2C_PLL_IN_FREQ 156250000ULL + + /* Constant used to determine the PLL frequency. */ +-#define MLNXBF_I2C_COREPLL_CONST 16384 ++#define MLNXBF_I2C_COREPLL_CONST 16384ULL ++ ++#define MLXBF_I2C_FREQUENCY_1GHZ 1000000000ULL + + /* PLL registers. */ +-#define MLXBF_I2C_CORE_PLL_REG0 0x0 + #define MLXBF_I2C_CORE_PLL_REG1 0x4 + #define MLXBF_I2C_CORE_PLL_REG2 0x8 + +@@ -181,22 +183,15 @@ + #define MLXBF_I2C_COREPLL_FREQ MLXBF_I2C_TYU_PLL_OUT_FREQ + + /* Core PLL TYU configuration. */ +-#define MLXBF_I2C_COREPLL_CORE_F_TYU_MASK GENMASK(12, 0) +-#define MLXBF_I2C_COREPLL_CORE_OD_TYU_MASK GENMASK(3, 0) +-#define MLXBF_I2C_COREPLL_CORE_R_TYU_MASK GENMASK(5, 0) +- +-#define MLXBF_I2C_COREPLL_CORE_F_TYU_SHIFT 3 +-#define MLXBF_I2C_COREPLL_CORE_OD_TYU_SHIFT 16 +-#define MLXBF_I2C_COREPLL_CORE_R_TYU_SHIFT 20 ++#define MLXBF_I2C_COREPLL_CORE_F_TYU_MASK GENMASK(15, 3) ++#define MLXBF_I2C_COREPLL_CORE_OD_TYU_MASK GENMASK(19, 16) ++#define MLXBF_I2C_COREPLL_CORE_R_TYU_MASK GENMASK(25, 20) + + /* Core PLL YU configuration. */ + #define MLXBF_I2C_COREPLL_CORE_F_YU_MASK GENMASK(25, 0) + #define MLXBF_I2C_COREPLL_CORE_OD_YU_MASK GENMASK(3, 0) +-#define MLXBF_I2C_COREPLL_CORE_R_YU_MASK GENMASK(5, 0) ++#define MLXBF_I2C_COREPLL_CORE_R_YU_MASK GENMASK(31, 26) + +-#define MLXBF_I2C_COREPLL_CORE_F_YU_SHIFT 0 +-#define MLXBF_I2C_COREPLL_CORE_OD_YU_SHIFT 1 +-#define MLXBF_I2C_COREPLL_CORE_R_YU_SHIFT 26 + + /* Core PLL frequency. */ + static u64 mlxbf_i2c_corepll_frequency; +@@ -479,8 +474,6 @@ static struct mutex mlxbf_i2c_bus_lock; + #define MLXBF_I2C_MASK_8 GENMASK(7, 0) + #define MLXBF_I2C_MASK_16 GENMASK(15, 0) + +-#define MLXBF_I2C_FREQUENCY_1GHZ 1000000000 +- + /* + * Function to poll a set of bits at a specific address; it checks whether + * the bits are equal to zero when eq_zero is set to 'true', and not equal +@@ -1410,24 +1403,19 @@ static int mlxbf_i2c_init_master(struct platform_device *pdev, + return 0; + } + +-static u64 mlxbf_calculate_freq_from_tyu(struct mlxbf_i2c_resource *corepll_res) ++static u64 mlxbf_i2c_calculate_freq_from_tyu(struct mlxbf_i2c_resource *corepll_res) + { +- u64 core_frequency, pad_frequency; ++ u64 core_frequency; + u8 core_od, core_r; + u32 corepll_val; + u16 core_f; + +- pad_frequency = MLXBF_I2C_PLL_IN_FREQ; +- + corepll_val = readl(corepll_res->io + MLXBF_I2C_CORE_PLL_REG1); + + /* Get Core PLL configuration bits. */ +- core_f = rol32(corepll_val, MLXBF_I2C_COREPLL_CORE_F_TYU_SHIFT) & +- MLXBF_I2C_COREPLL_CORE_F_TYU_MASK; +- core_od = rol32(corepll_val, MLXBF_I2C_COREPLL_CORE_OD_TYU_SHIFT) & +- MLXBF_I2C_COREPLL_CORE_OD_TYU_MASK; +- core_r = rol32(corepll_val, MLXBF_I2C_COREPLL_CORE_R_TYU_SHIFT) & +- MLXBF_I2C_COREPLL_CORE_R_TYU_MASK; ++ core_f = FIELD_GET(MLXBF_I2C_COREPLL_CORE_F_TYU_MASK, corepll_val); ++ core_od = FIELD_GET(MLXBF_I2C_COREPLL_CORE_OD_TYU_MASK, corepll_val); ++ core_r = FIELD_GET(MLXBF_I2C_COREPLL_CORE_R_TYU_MASK, corepll_val); + + /* + * Compute PLL output frequency as follow: +@@ -1439,31 +1427,26 @@ static u64 mlxbf_calculate_freq_from_tyu(struct mlxbf_i2c_resource *corepll_res) + * Where PLL_OUT_FREQ and PLL_IN_FREQ refer to CoreFrequency + * and PadFrequency, respectively. + */ +- core_frequency = pad_frequency * (++core_f); ++ core_frequency = MLXBF_I2C_PLL_IN_FREQ * (++core_f); + core_frequency /= (++core_r) * (++core_od); + + return core_frequency; + } + +-static u64 mlxbf_calculate_freq_from_yu(struct mlxbf_i2c_resource *corepll_res) ++static u64 mlxbf_i2c_calculate_freq_from_yu(struct mlxbf_i2c_resource *corepll_res) + { + u32 corepll_reg1_val, corepll_reg2_val; +- u64 corepll_frequency, pad_frequency; ++ u64 corepll_frequency; + u8 core_od, core_r; + u32 core_f; + +- pad_frequency = MLXBF_I2C_PLL_IN_FREQ; +- + corepll_reg1_val = readl(corepll_res->io + MLXBF_I2C_CORE_PLL_REG1); + corepll_reg2_val = readl(corepll_res->io + MLXBF_I2C_CORE_PLL_REG2); + + /* Get Core PLL configuration bits */ +- core_f = rol32(corepll_reg1_val, MLXBF_I2C_COREPLL_CORE_F_YU_SHIFT) & +- MLXBF_I2C_COREPLL_CORE_F_YU_MASK; +- core_r = rol32(corepll_reg1_val, MLXBF_I2C_COREPLL_CORE_R_YU_SHIFT) & +- MLXBF_I2C_COREPLL_CORE_R_YU_MASK; +- core_od = rol32(corepll_reg2_val, MLXBF_I2C_COREPLL_CORE_OD_YU_SHIFT) & +- MLXBF_I2C_COREPLL_CORE_OD_YU_MASK; ++ core_f = FIELD_GET(MLXBF_I2C_COREPLL_CORE_F_YU_MASK, corepll_reg1_val); ++ core_r = FIELD_GET(MLXBF_I2C_COREPLL_CORE_R_YU_MASK, corepll_reg1_val); ++ core_od = FIELD_GET(MLXBF_I2C_COREPLL_CORE_OD_YU_MASK, corepll_reg2_val); + + /* + * Compute PLL output frequency as follow: +@@ -1475,7 +1458,7 @@ static u64 mlxbf_calculate_freq_from_yu(struct mlxbf_i2c_resource *corepll_res) + * Where PLL_OUT_FREQ and PLL_IN_FREQ refer to CoreFrequency + * and PadFrequency, respectively. + */ +- corepll_frequency = (pad_frequency * core_f) / MLNXBF_I2C_COREPLL_CONST; ++ corepll_frequency = (MLXBF_I2C_PLL_IN_FREQ * core_f) / MLNXBF_I2C_COREPLL_CONST; + corepll_frequency /= (++core_r) * (++core_od); + + return corepll_frequency; +@@ -2183,14 +2166,14 @@ static struct mlxbf_i2c_chip_info mlxbf_i2c_chip[] = { + [1] = &mlxbf_i2c_corepll_res[MLXBF_I2C_CHIP_TYPE_1], + [2] = &mlxbf_i2c_gpio_res[MLXBF_I2C_CHIP_TYPE_1] + }, +- .calculate_freq = mlxbf_calculate_freq_from_tyu ++ .calculate_freq = mlxbf_i2c_calculate_freq_from_tyu + }, + [MLXBF_I2C_CHIP_TYPE_2] = { + .type = MLXBF_I2C_CHIP_TYPE_2, + .shared_res = { + [0] = &mlxbf_i2c_corepll_res[MLXBF_I2C_CHIP_TYPE_2] + }, +- .calculate_freq = mlxbf_calculate_freq_from_yu ++ .calculate_freq = mlxbf_i2c_calculate_freq_from_yu + } + }; + +-- +2.35.3 + diff --git a/patches.suse/i2c-mlxbf-incorrect-base-address-passed-during-io-wr.patch b/patches.suse/i2c-mlxbf-incorrect-base-address-passed-during-io-wr.patch new file mode 100644 index 0000000..eeccd21 --- /dev/null +++ b/patches.suse/i2c-mlxbf-incorrect-base-address-passed-during-io-wr.patch @@ -0,0 +1,40 @@ +From 2a5be6d1340c0fefcee8a6489cff7fd88a0d5b85 Mon Sep 17 00:00:00 2001 +From: Asmaa Mnebhi +Date: Thu, 8 Sep 2022 13:35:38 -0400 +Subject: [PATCH] i2c: mlxbf: incorrect base address passed during io write +Git-commit: 2a5be6d1340c0fefcee8a6489cff7fd88a0d5b85 +Patch-mainline: v6.0-rc7 +References: git-fixes + +Correct the base address used during io write. +This bug had no impact over the overall functionality of the read and write +transactions. MLXBF_I2C_CAUSE_OR_CLEAR=0x18 so writing to (smbus->io + 0x18) +instead of (mst_cause->ioi + 0x18) actually writes to the sc_low_timeout +register which just sets the timeout value before a read/write aborts. + +Fixes: b5b5b32081cd206b (i2c: mlxbf: I2C SMBus driver for Mellanox BlueField SoC) +Reviewed-by: Khalil Blaiech +Signed-off-by: Asmaa Mnebhi +Signed-off-by: Wolfram Sang +Acked-by: Takashi Iwai + +--- + drivers/i2c/busses/i2c-mlxbf.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/i2c/busses/i2c-mlxbf.c b/drivers/i2c/busses/i2c-mlxbf.c +index 8716032f030a..612736906440 100644 +--- a/drivers/i2c/busses/i2c-mlxbf.c ++++ b/drivers/i2c/busses/i2c-mlxbf.c +@@ -669,7 +669,7 @@ static int mlxbf_i2c_smbus_enable(struct mlxbf_i2c_priv *priv, u8 slave, + /* Clear status bits. */ + writel(0x0, priv->smbus->io + MLXBF_I2C_SMBUS_MASTER_STATUS); + /* Set the cause data. */ +- writel(~0x0, priv->smbus->io + MLXBF_I2C_CAUSE_OR_CLEAR); ++ writel(~0x0, priv->mst_cause->io + MLXBF_I2C_CAUSE_OR_CLEAR); + /* Zero PEC byte. */ + writel(0x0, priv->smbus->io + MLXBF_I2C_SMBUS_MASTER_PEC); + /* Zero byte count. */ +-- +2.35.3 + diff --git a/patches.suse/i2c-mlxbf-prevent-stack-overflow-in-mlxbf_i2c_smbus_.patch b/patches.suse/i2c-mlxbf-prevent-stack-overflow-in-mlxbf_i2c_smbus_.patch new file mode 100644 index 0000000..33ea4a9 --- /dev/null +++ b/patches.suse/i2c-mlxbf-prevent-stack-overflow-in-mlxbf_i2c_smbus_.patch @@ -0,0 +1,38 @@ +From de24aceb07d426b6f1c59f33889d6a964770547b Mon Sep 17 00:00:00 2001 +From: Asmaa Mnebhi +Date: Thu, 8 Sep 2022 13:35:39 -0400 +Subject: [PATCH] i2c: mlxbf: prevent stack overflow in mlxbf_i2c_smbus_start_transaction() +Git-commit: de24aceb07d426b6f1c59f33889d6a964770547b +Patch-mainline: v6.0-rc7 +References: git-fixes + +memcpy() is called in a loop while 'operation->length' upper bound +is not checked and 'data_idx' also increments. + +Fixes: b5b5b32081cd206b ("i2c: mlxbf: I2C SMBus driver for Mellanox BlueField SoC") +Reviewed-by: Khalil Blaiech +Signed-off-by: Asmaa Mnebhi +Signed-off-by: Wolfram Sang +Acked-by: Takashi Iwai + +--- + drivers/i2c/busses/i2c-mlxbf.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/i2c/busses/i2c-mlxbf.c b/drivers/i2c/busses/i2c-mlxbf.c +index 612736906440..ac93c0ccf53c 100644 +--- a/drivers/i2c/busses/i2c-mlxbf.c ++++ b/drivers/i2c/busses/i2c-mlxbf.c +@@ -738,6 +738,9 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv, + if (flags & MLXBF_I2C_F_WRITE) { + write_en = 1; + write_len += operation->length; ++ if (data_idx + operation->length > ++ MLXBF_I2C_MASTER_DATA_DESC_SIZE) ++ return -ENOBUFS; + memcpy(data_desc + data_idx, + operation->buffer, operation->length); + data_idx += operation->length; +-- +2.35.3 + diff --git a/patches.suse/i2c-mlxbf-support-lock-mechanism.patch b/patches.suse/i2c-mlxbf-support-lock-mechanism.patch new file mode 100644 index 0000000..56f8208 --- /dev/null +++ b/patches.suse/i2c-mlxbf-support-lock-mechanism.patch @@ -0,0 +1,121 @@ +From 86067ccfa1424a26491542d6f6d7546d40b61a10 Mon Sep 17 00:00:00 2001 +From: Asmaa Mnebhi +Date: Mon, 26 Sep 2022 15:45:04 -0400 +Subject: [PATCH] i2c: mlxbf: support lock mechanism +Git-commit: 86067ccfa1424a26491542d6f6d7546d40b61a10 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Linux is not the only entity using the BlueField I2C busses so +support a lock mechanism provided by hardware to avoid issues +when multiple entities are trying to access the same bus. + +The lock is acquired whenever written explicitely or the lock +register is read. So make sure it is always released at the end +of a successful or failed transaction. + +Fixes: b5b5b32081cd206b (i2c: mlxbf: I2C SMBus driver for Mellanox BlueField SoC) +Reviewed-by: Khalil Blaiech +Signed-off-by: Asmaa Mnebhi +Signed-off-by: Wolfram Sang +Acked-by: Takashi Iwai + +--- + drivers/i2c/busses/i2c-mlxbf.c | 44 ++++++++++++++++++++++++++++++---- + 1 file changed, 39 insertions(+), 5 deletions(-) + +diff --git a/drivers/i2c/busses/i2c-mlxbf.c b/drivers/i2c/busses/i2c-mlxbf.c +index 1a0fc9640c23..78b2bc9b0a34 100644 +--- a/drivers/i2c/busses/i2c-mlxbf.c ++++ b/drivers/i2c/busses/i2c-mlxbf.c +@@ -306,6 +306,7 @@ static u64 mlxbf_i2c_corepll_frequency; + * exact. + */ + #define MLXBF_I2C_SMBUS_TIMEOUT (300 * 1000) /* 300ms */ ++#define MLXBF_I2C_SMBUS_LOCK_POLL_TIMEOUT (300 * 1000) /* 300ms */ + + /* Encapsulates timing parameters. */ + struct mlxbf_i2c_timings { +@@ -514,6 +515,25 @@ static bool mlxbf_smbus_master_wait_for_idle(struct mlxbf_i2c_priv *priv) + return false; + } + ++/* ++ * wait for the lock to be released before acquiring it. ++ */ ++static bool mlxbf_i2c_smbus_master_lock(struct mlxbf_i2c_priv *priv) ++{ ++ if (mlxbf_smbus_poll(priv->smbus->io, MLXBF_I2C_SMBUS_MASTER_GW, ++ MLXBF_I2C_MASTER_LOCK_BIT, true, ++ MLXBF_I2C_SMBUS_LOCK_POLL_TIMEOUT)) ++ return true; ++ ++ return false; ++} ++ ++static void mlxbf_i2c_smbus_master_unlock(struct mlxbf_i2c_priv *priv) ++{ ++ /* Clear the gw to clear the lock */ ++ writel(0, priv->smbus->io + MLXBF_I2C_SMBUS_MASTER_GW); ++} ++ + static bool mlxbf_i2c_smbus_transaction_success(u32 master_status, + u32 cause_status) + { +@@ -705,10 +725,19 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv, + slave = request->slave & GENMASK(6, 0); + addr = slave << 1; + +- /* First of all, check whether the HW is idle. */ +- if (WARN_ON(!mlxbf_smbus_master_wait_for_idle(priv))) ++ /* ++ * Try to acquire the smbus gw lock before any reads of the GW register since ++ * a read sets the lock. ++ */ ++ if (WARN_ON(!mlxbf_i2c_smbus_master_lock(priv))) + return -EBUSY; + ++ /* Check whether the HW is idle */ ++ if (WARN_ON(!mlxbf_smbus_master_wait_for_idle(priv))) { ++ ret = -EBUSY; ++ goto out_unlock; ++ } ++ + /* Set first byte. */ + data_desc[data_idx++] = addr; + +@@ -732,8 +761,10 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv, + write_en = 1; + write_len += operation->length; + if (data_idx + operation->length > +- MLXBF_I2C_MASTER_DATA_DESC_SIZE) +- return -ENOBUFS; ++ MLXBF_I2C_MASTER_DATA_DESC_SIZE) { ++ ret = -ENOBUFS; ++ goto out_unlock; ++ } + memcpy(data_desc + data_idx, + operation->buffer, operation->length); + data_idx += operation->length; +@@ -765,7 +796,7 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv, + ret = mlxbf_i2c_smbus_enable(priv, slave, write_len, block_en, + pec_en, 0); + if (ret) +- return ret; ++ goto out_unlock; + } + + if (read_en) { +@@ -792,6 +823,9 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv, + priv->smbus->io + MLXBF_I2C_SMBUS_MASTER_FSM); + } + ++out_unlock: ++ mlxbf_i2c_smbus_master_unlock(priv); ++ + return ret; + } + +-- +2.35.3 + diff --git a/patches.suse/ieee802154-cc2520-add-rc-code-in-cc2520_tx.patch b/patches.suse/ieee802154-cc2520-add-rc-code-in-cc2520_tx.patch new file mode 100644 index 0000000..14356ac --- /dev/null +++ b/patches.suse/ieee802154-cc2520-add-rc-code-in-cc2520_tx.patch @@ -0,0 +1,35 @@ +From ffd7bdddaab193c38416fd5dd416d065517d266e Mon Sep 17 00:00:00 2001 +From: Li Qiong +Date: Mon, 29 Aug 2022 15:12:59 +0800 +Subject: [PATCH] ieee802154: cc2520: add rc code in cc2520_tx() +Git-commit: ffd7bdddaab193c38416fd5dd416d065517d266e +Patch-mainline: v6.0-rc4 +References: git-fixes + +The rc code is 0 at the error path "status & CC2520_STATUS_TX_UNDERFLOW". +Assign rc code with '-EINVAL' at this error path to fix it. + +Signed-off-by: Li Qiong +Link: https://lore.kernel.org/r/20220829071259.18330-1-liqiong@nfschina.com +Signed-off-by: Stefan Schmidt +Acked-by: Takashi Iwai + +--- + drivers/net/ieee802154/cc2520.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c +index 1e1f40f628a0..c69b87d3837d 100644 +--- a/drivers/net/ieee802154/cc2520.c ++++ b/drivers/net/ieee802154/cc2520.c +@@ -504,6 +504,7 @@ cc2520_tx(struct ieee802154_hw *hw, struct sk_buff *skb) + goto err_tx; + + if (status & CC2520_STATUS_TX_UNDERFLOW) { ++ rc = -EINVAL; + dev_err(&priv->spi->dev, "cc2520 tx underflow exception\n"); + goto err_tx; + } +-- +2.35.3 + diff --git a/patches.suse/iio-ABI-Fix-wrong-format-of-differential-capacitance.patch b/patches.suse/iio-ABI-Fix-wrong-format-of-differential-capacitance.patch new file mode 100644 index 0000000..e433e22 --- /dev/null +++ b/patches.suse/iio-ABI-Fix-wrong-format-of-differential-capacitance.patch @@ -0,0 +1,36 @@ +From 1efc41035f1841acf0af2bab153158e27ce94f10 Mon Sep 17 00:00:00 2001 +From: Jonathan Cameron +Date: Sun, 26 Jun 2022 13:29:23 +0100 +Subject: [PATCH] iio: ABI: Fix wrong format of differential capacitance channel ABI. +Git-commit: 1efc41035f1841acf0af2bab153158e27ce94f10 +Patch-mainline: v6.1-rc1 +References: git-fixes + +in_ only occurs once in these attributes. + +Fixes: 0baf29d658c7 ("staging:iio:documentation Add abi docs for capacitance adcs.") +Signed-off-by: Jonathan Cameron +Reviewed-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20220626122938.582107-3-jic23@kernel.org +Acked-by: Takashi Iwai + +--- + Documentation/ABI/testing/sysfs-bus-iio | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio +index 7faec5b3a553..979f2e2b44f6 100644 +--- a/Documentation/ABI/testing/sysfs-bus-iio ++++ b/Documentation/ABI/testing/sysfs-bus-iio +@@ -196,7 +196,7 @@ Description: + Raw capacitance measurement from channel Y. Units after + application of scale and offset are nanofarads. + +-What: /sys/.../iio:deviceX/in_capacitanceY-in_capacitanceZ_raw ++What: /sys/.../iio:deviceX/in_capacitanceY-capacitanceZ_raw + KernelVersion: 3.2 + Contact: linux-iio@vger.kernel.org + Description: +-- +2.35.3 + diff --git a/patches.suse/iio-adc-ad7923-fix-channel-readings-for-some-variant.patch b/patches.suse/iio-adc-ad7923-fix-channel-readings-for-some-variant.patch new file mode 100644 index 0000000..3d00d9f --- /dev/null +++ b/patches.suse/iio-adc-ad7923-fix-channel-readings-for-some-variant.patch @@ -0,0 +1,53 @@ +From f4f43f01cff2f29779343ade755191afd2581c77 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Nuno=20S=C3=A1?= +Date: Mon, 12 Sep 2022 10:12:21 +0200 +Subject: [PATCH] iio: adc: ad7923: fix channel readings for some variants +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: f4f43f01cff2f29779343ade755191afd2581c77 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Some of the supported devices have 4 or 2 LSB trailing bits that should +not be taken into account. Hence we need to shift these bits out which +fits perfectly on the scan type shift property. This change fixes both +raw and buffered reads. + +Fixes: f2f7a449707e ("iio:adc:ad7923: Add support for the ad7904/ad7914/ad7924") +Fixes: 851644a60d20 ("iio: adc: ad7923: Add support for the ad7908/ad7918/ad7928") +Signed-off-by: Nuno Sá +Link: https://lore.kernel.org/r/20220912081223.173584-2-nuno.sa@analog.com +Cc: +Signed-off-by: Jonathan Cameron +Acked-by: Takashi Iwai + +--- + drivers/iio/adc/ad7923.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/iio/adc/ad7923.c b/drivers/iio/adc/ad7923.c +index edad1f30121d..502253f53d96 100644 +--- a/drivers/iio/adc/ad7923.c ++++ b/drivers/iio/adc/ad7923.c +@@ -93,6 +93,7 @@ enum ad7923_id { + .sign = 'u', \ + .realbits = (bits), \ + .storagebits = 16, \ ++ .shift = 12 - (bits), \ + .endianness = IIO_BE, \ + }, \ + } +@@ -268,7 +269,8 @@ static int ad7923_read_raw(struct iio_dev *indio_dev, + return ret; + + if (chan->address == EXTRACT(ret, 12, 4)) +- *val = EXTRACT(ret, 0, 12); ++ *val = EXTRACT(ret, chan->scan_type.shift, ++ chan->scan_type.realbits); + else + return -EIO; + +-- +2.35.3 + diff --git a/patches.suse/iio-adc-at91-sama5d2_adc-check-return-status-for-pre.patch b/patches.suse/iio-adc-at91-sama5d2_adc-check-return-status-for-pre.patch new file mode 100644 index 0000000..c53cb78 --- /dev/null +++ b/patches.suse/iio-adc-at91-sama5d2_adc-check-return-status-for-pre.patch @@ -0,0 +1,52 @@ +From d84ace944a3b24529798dbae1340dea098473155 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea +Date: Wed, 3 Aug 2022 13:28:38 +0300 +Subject: [PATCH] iio: adc: at91-sama5d2_adc: check return status for pressure and touch +Git-commit: d84ace944a3b24529798dbae1340dea098473155 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Check return status of at91_adc_read_position() and +at91_adc_read_pressure() in at91_adc_read_info_raw(). + +Fixes: 6794e23fa3fe ("iio: adc: at91-sama5d2_adc: add support for oversampling resolution") +Signed-off-by: Claudiu Beznea +Link: https://lore.kernel.org/r/20220803102855.2191070-3-claudiu.beznea@microchip.com +Signed-off-by: Jonathan Cameron +Acked-by: Takashi Iwai + +--- + drivers/iio/adc/at91-sama5d2_adc.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c +index ac9ef89fba17..08d1f806c839 100644 +--- a/drivers/iio/adc/at91-sama5d2_adc.c ++++ b/drivers/iio/adc/at91-sama5d2_adc.c +@@ -1544,8 +1544,10 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev, + *val = tmp_val; + mutex_unlock(&st->lock); + iio_device_release_direct_mode(indio_dev); ++ if (ret > 0) ++ ret = at91_adc_adjust_val_osr(st, val); + +- return at91_adc_adjust_val_osr(st, val); ++ return ret; + } + if (chan->type == IIO_PRESSURE) { + ret = iio_device_claim_direct_mode(indio_dev); +@@ -1558,8 +1560,10 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev, + *val = tmp_val; + mutex_unlock(&st->lock); + iio_device_release_direct_mode(indio_dev); ++ if (ret > 0) ++ ret = at91_adc_adjust_val_osr(st, val); + +- return at91_adc_adjust_val_osr(st, val); ++ return ret; + } + + /* in this case we have a voltage channel */ +-- +2.35.3 + diff --git a/patches.suse/iio-adc-at91-sama5d2_adc-disable-prepare-buffer-on-s.patch b/patches.suse/iio-adc-at91-sama5d2_adc-disable-prepare-buffer-on-s.patch new file mode 100644 index 0000000..95f216d --- /dev/null +++ b/patches.suse/iio-adc-at91-sama5d2_adc-disable-prepare-buffer-on-s.patch @@ -0,0 +1,62 @@ +From 808175e21d9b7f866eda742e8970f27b78afe5db Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea +Date: Wed, 3 Aug 2022 13:28:40 +0300 +Subject: [PATCH] iio: adc: at91-sama5d2_adc: disable/prepare buffer on suspend/resume +Git-commit: 808175e21d9b7f866eda742e8970f27b78afe5db +Patch-mainline: v6.1-rc1 +References: git-fixes + +In case triggered buffers are enabled while system is suspended they will +not work anymore after resume. For this call at91_adc_buffer_postdisable() +on suspend and at91_adc_buffer_prepare() on resume. On tests it has been +seen that at91_adc_buffer_postdisable() call is not necessary but it has +been kept because it also does the book keeping for DMA. On resume path +there is no need to call at91_adc_configure_touch() as it is embedded in +at91_adc_buffer_prepare(). + +Fixes: 073c662017f2f ("iio: adc: at91-sama5d2_adc: add support for DMA") +Signed-off-by: Claudiu Beznea +Link: https://lore.kernel.org/r/20220803102855.2191070-5-claudiu.beznea@microchip.com +Signed-off-by: Jonathan Cameron +Acked-by: Takashi Iwai + +--- + drivers/iio/adc/at91-sama5d2_adc.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c +index 3734ddc82952..e2c82c5a2fac 100644 +--- a/drivers/iio/adc/at91-sama5d2_adc.c ++++ b/drivers/iio/adc/at91-sama5d2_adc.c +@@ -2116,6 +2116,9 @@ static int at91_adc_suspend(struct device *dev) + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct at91_adc_state *st = iio_priv(indio_dev); + ++ if (iio_buffer_enabled(indio_dev)) ++ at91_adc_buffer_postdisable(indio_dev); ++ + /* + * Do a sofware reset of the ADC before we go to suspend. + * this will ensure that all pins are free from being muxed by the ADC +@@ -2159,14 +2162,11 @@ static int at91_adc_resume(struct device *dev) + if (!iio_buffer_enabled(indio_dev)) + return 0; + +- /* check if we are enabling triggered buffer or the touchscreen */ +- if (at91_adc_current_chan_is_touch(indio_dev)) +- return at91_adc_configure_touch(st, true); +- else +- return at91_adc_configure_trigger(st->trig, true); ++ ret = at91_adc_buffer_prepare(indio_dev); ++ if (ret) ++ goto vref_disable_resume; + +- /* not needed but more explicit */ +- return 0; ++ return at91_adc_configure_trigger(st->trig, true); + + vref_disable_resume: + regulator_disable(st->vref); +-- +2.35.3 + diff --git a/patches.suse/iio-adc-at91-sama5d2_adc-fix-AT91_SAMA5D2_MR_TRACKTI.patch b/patches.suse/iio-adc-at91-sama5d2_adc-fix-AT91_SAMA5D2_MR_TRACKTI.patch new file mode 100644 index 0000000..56671b3 --- /dev/null +++ b/patches.suse/iio-adc-at91-sama5d2_adc-fix-AT91_SAMA5D2_MR_TRACKTI.patch @@ -0,0 +1,38 @@ +From bb73d5d9164c57c4bb916739a98e5cd8e0a5ed8c Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea +Date: Wed, 3 Aug 2022 13:28:37 +0300 +Subject: [PATCH] iio: adc: at91-sama5d2_adc: fix AT91_SAMA5D2_MR_TRACKTIM_MAX +Git-commit: bb73d5d9164c57c4bb916739a98e5cd8e0a5ed8c +Patch-mainline: v6.1-rc1 +References: git-fixes + +All ADC HW versions handled by this driver (SAMA5D2, SAM9X60, SAMA7G5) +have MR.TRACKTIM on 4 bits. Fix AT91_SAMA5D2_MR_TRACKTIM_MAX to reflect +this. + +Fixes: 27e177190891 ("iio:adc:at91_adc8xx: introduce new atmel adc driver") +Signed-off-by: Claudiu Beznea +Link: https://lore.kernel.org/r/20220803102855.2191070-2-claudiu.beznea@microchip.com +Signed-off-by: Jonathan Cameron +Acked-by: Takashi Iwai + +--- + drivers/iio/adc/at91-sama5d2_adc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c +index 279430c1d88c..ac9ef89fba17 100644 +--- a/drivers/iio/adc/at91-sama5d2_adc.c ++++ b/drivers/iio/adc/at91-sama5d2_adc.c +@@ -77,7 +77,7 @@ struct at91_adc_reg_layout { + #define AT91_SAMA5D2_MR_ANACH BIT(23) + /* Tracking Time */ + #define AT91_SAMA5D2_MR_TRACKTIM(v) ((v) << 24) +-#define AT91_SAMA5D2_MR_TRACKTIM_MAX 0xff ++#define AT91_SAMA5D2_MR_TRACKTIM_MAX 0xf + /* Transfer Time */ + #define AT91_SAMA5D2_MR_TRANSFER(v) ((v) << 28) + #define AT91_SAMA5D2_MR_TRANSFER_MAX 0x3 +-- +2.35.3 + diff --git a/patches.suse/iio-adc-at91-sama5d2_adc-lock-around-oversampling-an.patch b/patches.suse/iio-adc-at91-sama5d2_adc-lock-around-oversampling-an.patch new file mode 100644 index 0000000..4f3d917 --- /dev/null +++ b/patches.suse/iio-adc-at91-sama5d2_adc-lock-around-oversampling-an.patch @@ -0,0 +1,79 @@ +From 9780a23ed5a0a0a63683e078f576719a98d4fb70 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea +Date: Wed, 3 Aug 2022 13:28:39 +0300 +Subject: [PATCH] iio: adc: at91-sama5d2_adc: lock around oversampling and sample freq +Git-commit: 9780a23ed5a0a0a63683e078f576719a98d4fb70 +Patch-mainline: v6.1-rc1 +References: git-fixes + +.read_raw()/.write_raw() could be called asynchronously from user space +or other in kernel drivers. Without locking on st->lock these could be +called asynchronously while there is a conversion in progress. Read will +be harmless but changing registers while conversion is in progress may +lead to inconsistent results. Thus, to avoid this lock st->lock. + +Fixes: 27e177190891 ("iio:adc:at91_adc8xx: introduce new atmel adc driver") +Fixes: 6794e23fa3fe ("iio: adc: at91-sama5d2_adc: add support for oversampling resolution") +Signed-off-by: Claudiu Beznea +Link: https://lore.kernel.org/r/20220803102855.2191070-4-claudiu.beznea@microchip.com +Signed-off-by: Jonathan Cameron +Acked-by: Takashi Iwai + +--- + drivers/iio/adc/at91-sama5d2_adc.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c +index 08d1f806c839..3734ddc82952 100644 +--- a/drivers/iio/adc/at91-sama5d2_adc.c ++++ b/drivers/iio/adc/at91-sama5d2_adc.c +@@ -1542,10 +1542,10 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev, + ret = at91_adc_read_position(st, chan->channel, + &tmp_val); + *val = tmp_val; +- mutex_unlock(&st->lock); +- iio_device_release_direct_mode(indio_dev); + if (ret > 0) + ret = at91_adc_adjust_val_osr(st, val); ++ mutex_unlock(&st->lock); ++ iio_device_release_direct_mode(indio_dev); + + return ret; + } +@@ -1558,10 +1558,10 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev, + ret = at91_adc_read_pressure(st, chan->channel, + &tmp_val); + *val = tmp_val; +- mutex_unlock(&st->lock); +- iio_device_release_direct_mode(indio_dev); + if (ret > 0) + ret = at91_adc_adjust_val_osr(st, val); ++ mutex_unlock(&st->lock); ++ iio_device_release_direct_mode(indio_dev); + + return ret; + } +@@ -1650,16 +1650,20 @@ static int at91_adc_write_raw(struct iio_dev *indio_dev, + /* if no change, optimize out */ + if (val == st->oversampling_ratio) + return 0; ++ mutex_lock(&st->lock); + st->oversampling_ratio = val; + /* update ratio */ + at91_adc_config_emr(st); ++ mutex_unlock(&st->lock); + return 0; + case IIO_CHAN_INFO_SAMP_FREQ: + if (val < st->soc_info.min_sample_rate || + val > st->soc_info.max_sample_rate) + return -EINVAL; + ++ mutex_lock(&st->lock); + at91_adc_setup_samp_freq(indio_dev, val); ++ mutex_unlock(&st->lock); + return 0; + default: + return -EINVAL; +-- +2.35.3 + diff --git a/patches.suse/iio-dac-ad5593r-Fix-i2c-read-protocol-requirements.patch b/patches.suse/iio-dac-ad5593r-Fix-i2c-read-protocol-requirements.patch new file mode 100644 index 0000000..f5f9ff2 --- /dev/null +++ b/patches.suse/iio-dac-ad5593r-Fix-i2c-read-protocol-requirements.patch @@ -0,0 +1,118 @@ +From 558a25f903b4af6361b7fbeea08a6446a0745653 Mon Sep 17 00:00:00 2001 +From: Michael Hennerich +Date: Tue, 13 Sep 2022 09:34:12 +0200 +Subject: [PATCH] iio: dac: ad5593r: Fix i2c read protocol requirements +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 558a25f903b4af6361b7fbeea08a6446a0745653 +Patch-mainline: v6.1-rc1 +References: git-fixes + +For reliable operation across the full range of supported +interface rates, the AD5593R needs a STOP condition between +address write, and data read (like show in the datasheet Figure 40) +so in turn i2c_smbus_read_word_swapped cannot be used. + +While at it, a simple helper was added to make the code simpler. + +Fixes: 56ca9db862bf ("iio: dac: Add support for the AD5592R/AD5593R ADCs/DACs") +Signed-off-by: Michael Hennerich +Signed-off-by: Nuno Sá +Cc: +Link: https://lore.kernel.org/r/20220913073413.140475-2-nuno.sa@analog.com +Signed-off-by: Jonathan Cameron +Acked-by: Takashi Iwai + +--- + drivers/iio/dac/ad5593r.c | 46 +++++++++++++++++++++++---------------- + 1 file changed, 27 insertions(+), 19 deletions(-) + +diff --git a/drivers/iio/dac/ad5593r.c b/drivers/iio/dac/ad5593r.c +index 34e1319a9712..356dc0bab115 100644 +--- a/drivers/iio/dac/ad5593r.c ++++ b/drivers/iio/dac/ad5593r.c +@@ -13,6 +13,8 @@ + #include + #include + ++#include ++ + #define AD5593R_MODE_CONF (0 << 4) + #define AD5593R_MODE_DAC_WRITE (1 << 4) + #define AD5593R_MODE_ADC_READBACK (4 << 4) +@@ -20,6 +22,24 @@ + #define AD5593R_MODE_GPIO_READBACK (6 << 4) + #define AD5593R_MODE_REG_READBACK (7 << 4) + ++static int ad5593r_read_word(struct i2c_client *i2c, u8 reg, u16 *value) ++{ ++ int ret; ++ u8 buf[2]; ++ ++ ret = i2c_smbus_write_byte(i2c, reg); ++ if (ret < 0) ++ return ret; ++ ++ ret = i2c_master_recv(i2c, buf, sizeof(buf)); ++ if (ret < 0) ++ return ret; ++ ++ *value = get_unaligned_be16(buf); ++ ++ return 0; ++} ++ + static int ad5593r_write_dac(struct ad5592r_state *st, unsigned chan, u16 value) + { + struct i2c_client *i2c = to_i2c_client(st->dev); +@@ -38,13 +58,7 @@ static int ad5593r_read_adc(struct ad5592r_state *st, unsigned chan, u16 *value) + if (val < 0) + return (int) val; + +- val = i2c_smbus_read_word_swapped(i2c, AD5593R_MODE_ADC_READBACK); +- if (val < 0) +- return (int) val; +- +- *value = (u16) val; +- +- return 0; ++ return ad5593r_read_word(i2c, AD5593R_MODE_ADC_READBACK, value); + } + + static int ad5593r_reg_write(struct ad5592r_state *st, u8 reg, u16 value) +@@ -58,25 +72,19 @@ static int ad5593r_reg_write(struct ad5592r_state *st, u8 reg, u16 value) + static int ad5593r_reg_read(struct ad5592r_state *st, u8 reg, u16 *value) + { + struct i2c_client *i2c = to_i2c_client(st->dev); +- s32 val; +- +- val = i2c_smbus_read_word_swapped(i2c, AD5593R_MODE_REG_READBACK | reg); +- if (val < 0) +- return (int) val; + +- *value = (u16) val; +- +- return 0; ++ return ad5593r_read_word(i2c, AD5593R_MODE_REG_READBACK | reg, value); + } + + static int ad5593r_gpio_read(struct ad5592r_state *st, u8 *value) + { + struct i2c_client *i2c = to_i2c_client(st->dev); +- s32 val; ++ u16 val; ++ int ret; + +- val = i2c_smbus_read_word_swapped(i2c, AD5593R_MODE_GPIO_READBACK); +- if (val < 0) +- return (int) val; ++ ret = ad5593r_read_word(i2c, AD5593R_MODE_GPIO_READBACK, &val); ++ if (ret) ++ return ret; + + *value = (u8) val; + +-- +2.35.3 + diff --git a/patches.suse/iio-inkern-fix-return-value-in-devm_of_iio_channel_g.patch b/patches.suse/iio-inkern-fix-return-value-in-devm_of_iio_channel_g.patch new file mode 100644 index 0000000..25c1d02 --- /dev/null +++ b/patches.suse/iio-inkern-fix-return-value-in-devm_of_iio_channel_g.patch @@ -0,0 +1,46 @@ +From 9e878dbc0e8322f8b2f5ab0093c1e89926362dbe Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Nuno=20S=C3=A1?= +Date: Fri, 15 Jul 2022 14:28:50 +0200 +Subject: [PATCH] iio: inkern: fix return value in devm_of_iio_channel_get_by_name() +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 9e878dbc0e8322f8b2f5ab0093c1e89926362dbe +Patch-mainline: v6.1-rc1 +References: git-fixes + +of_iio_channel_get_by_name() can either return NULL or an error pointer +so that only doing IS_ERR() is not enough. Fix it by checking the NULL +pointer case and return -ENODEV in that case. Note this is done like this +so that users of the function (which only check for error pointers) do +not need to be changed. This is not ideal since we are losing error codes +and as such, in a follow up change, things will be unified so that +of_iio_channel_get_by_name() only returns error codes. + +Fixes: 6e39b145cef7 ("iio: provide of_iio_channel_get_by_name() and devm_ version it") +Signed-off-by: Nuno Sá +Reviewed-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20220715122903.332535-3-nuno.sa@analog.com +Signed-off-by: Jonathan Cameron +Acked-by: Takashi Iwai + +--- + drivers/iio/inkern.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c +index 9d87057794fc..87fd2a0d44f2 100644 +--- a/drivers/iio/inkern.c ++++ b/drivers/iio/inkern.c +@@ -412,6 +412,8 @@ struct iio_channel *devm_of_iio_channel_get_by_name(struct device *dev, + channel = of_iio_channel_get_by_name(np, channel_name); + if (IS_ERR(channel)) + return channel; ++ if (!channel) ++ return ERR_PTR(-ENODEV); + + ret = devm_add_action_or_reset(dev, devm_iio_channel_free, channel); + if (ret) +-- +2.35.3 + diff --git a/patches.suse/iio-inkern-only-release-the-device-node-when-done-wi.patch b/patches.suse/iio-inkern-only-release-the-device-node-when-done-wi.patch new file mode 100644 index 0000000..928036a --- /dev/null +++ b/patches.suse/iio-inkern-only-release-the-device-node-when-done-wi.patch @@ -0,0 +1,60 @@ +From 79c3e84874c7d14f04ad58313b64955a0d2e9437 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Nuno=20S=C3=A1?= +Date: Fri, 15 Jul 2022 14:28:49 +0200 +Subject: [PATCH] iio: inkern: only release the device node when done with it +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 79c3e84874c7d14f04ad58313b64955a0d2e9437 +Patch-mainline: v6.1-rc1 +References: git-fixes + +'of_node_put()' can potentially release the memory pointed to by +'iiospec.np' which would leave us with an invalid pointer (and we would +still pass it in 'of_xlate()'). Note that it is not guaranteed for the +of_node lifespan to be attached to the device (to which is attached) +lifespan so that there is (even though very unlikely) the possibility +for the node to be freed while the device is still around. Thus, as there +are indeed some of_xlate users which do access the node, a race is indeed +possible. + +As such, we can only release the node after we are done with it. + +Fixes: 17d82b47a215d ("iio: Add OF support") +Signed-off-by: Nuno Sá +Link: https://lore.kernel.org/r/20220715122903.332535-2-nuno.sa@analog.com +Signed-off-by: Jonathan Cameron +Acked-by: Takashi Iwai + +--- + drivers/iio/inkern.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c +index df74765d33dc..9d87057794fc 100644 +--- a/drivers/iio/inkern.c ++++ b/drivers/iio/inkern.c +@@ -165,9 +165,10 @@ static int __of_iio_channel_get(struct iio_channel *channel, + + idev = bus_find_device(&iio_bus_type, NULL, iiospec.np, + iio_dev_node_match); +- of_node_put(iiospec.np); +- if (idev == NULL) ++ if (idev == NULL) { ++ of_node_put(iiospec.np); + return -EPROBE_DEFER; ++ } + + indio_dev = dev_to_iio_dev(idev); + channel->indio_dev = indio_dev; +@@ -175,6 +176,7 @@ static int __of_iio_channel_get(struct iio_channel *channel, + index = indio_dev->info->of_xlate(indio_dev, &iiospec); + else + index = __of_iio_simple_xlate(indio_dev, &iiospec); ++ of_node_put(iiospec.np); + if (index < 0) + goto err_put; + channel->channel = &indio_dev->channels[index]; +-- +2.35.3 + diff --git a/patches.suse/iio-ltc2497-Fix-reading-conversion-results.patch b/patches.suse/iio-ltc2497-Fix-reading-conversion-results.patch new file mode 100644 index 0000000..6e75b6e --- /dev/null +++ b/patches.suse/iio-ltc2497-Fix-reading-conversion-results.patch @@ -0,0 +1,61 @@ +From 7f4f1096d5921f5d90547596f9ce80e0b924f887 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= +Date: Mon, 15 Aug 2022 09:16:47 +0000 +Subject: [PATCH] iio: ltc2497: Fix reading conversion results +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 7f4f1096d5921f5d90547596f9ce80e0b924f887 +Patch-mainline: v6.1-rc1 +References: git-fixes + +After the result of the previous conversion is read the chip +automatically starts a new conversion and doesn't accept new i2c +transfers until this conversion is completed which makes the function +return failure. + +So add an early return iff the programming of the new address isn't +needed. Note this will not fix the problem in general, but all cases +that are currently used. Once this changes we get the failure back, but +this can be addressed when the need arises. + +Fixes: 69548b7c2c4f ("iio: adc: ltc2497: split protocol independent part in a separate module ") +Reported-by: Meng Li +Signed-off-by: Uwe Kleine-König +Tested-by: Denys Zagorui +Cc: +Link: https://lore.kernel.org/r/20220815091647.1523532-1-dzagorui@cisco.com +Signed-off-by: Jonathan Cameron +Acked-by: Takashi Iwai + +--- + drivers/iio/adc/ltc2497.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/drivers/iio/adc/ltc2497.c b/drivers/iio/adc/ltc2497.c +index f7c786f37ceb..78b93c99cc47 100644 +--- a/drivers/iio/adc/ltc2497.c ++++ b/drivers/iio/adc/ltc2497.c +@@ -41,6 +41,19 @@ static int ltc2497_result_and_measure(struct ltc2497core_driverdata *ddata, + } + + *val = (be32_to_cpu(st->buf) >> 14) - (1 << 17); ++ ++ /* ++ * The part started a new conversion at the end of the above i2c ++ * transfer, so if the address didn't change since the last call ++ * everything is fine and we can return early. ++ * If not (which should only happen when some sort of bulk ++ * conversion is implemented) we have to program the new ++ * address. Note that this probably fails as the conversion that ++ * was triggered above is like not complete yet and the two ++ * operations have to be done in a single transfer. ++ */ ++ if (ddata->addr_prev == address) ++ return 0; + } + + ret = i2c_smbus_write_byte(st->client, +-- +2.35.3 + diff --git a/patches.suse/iio-magnetometer-yas530-Change-data-type-of-hard_off.patch b/patches.suse/iio-magnetometer-yas530-Change-data-type-of-hard_off.patch new file mode 100644 index 0000000..c0d2345 --- /dev/null +++ b/patches.suse/iio-magnetometer-yas530-Change-data-type-of-hard_off.patch @@ -0,0 +1,43 @@ +From e137fafc8985cf152a4bb6f18ae83ebb06816df1 Mon Sep 17 00:00:00 2001 +From: Jakob Hauser +Date: Fri, 12 Aug 2022 23:54:06 +0200 +Subject: [PATCH] iio: magnetometer: yas530: Change data type of hard_offsets to signed +Git-commit: e137fafc8985cf152a4bb6f18ae83ebb06816df1 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The "hard_offsets" are currently unsigned u8 but they should be signed as they +can get negative. They are signed in function yas5xx_meaure_offsets() and in the +Yamaha drivers [1][2]. + +[1] https://github.com/NovaFusion/android_kernel_samsung_golden/blob/cm-12.1/drivers/sensor/compass/yas.h#L156 +[2] https://github.com/msm8916-mainline/android_kernel_qcom_msm8916/blob/GT-I9195I/drivers/iio/magnetometer/yas_mag_drv-yas532.c#L91 + +Fixes: de8860b1ed47 ("iio: magnetometer: Add driver for Yamaha YAS530") +Signed-off-by: Jakob Hauser +Reviewed-by: Linus Walleij +Reviewed-by: Andy Shevchenko +Link: https://lore.kernel.org/r/40f052bf6491457d0c5c0ed4c3534dc6fa251c3c.1660337264.git.jahau@rocketmail.com +Signed-off-by: Jonathan Cameron +Acked-by: Takashi Iwai + +--- + drivers/iio/magnetometer/yamaha-yas530.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/iio/magnetometer/yamaha-yas530.c b/drivers/iio/magnetometer/yamaha-yas530.c +index aeaa4da6923b..d1f16729c60e 100644 +--- a/drivers/iio/magnetometer/yamaha-yas530.c ++++ b/drivers/iio/magnetometer/yamaha-yas530.c +@@ -132,7 +132,7 @@ struct yas5xx { + unsigned int version; + char name[16]; + struct yas5xx_calibration calibration; +- u8 hard_offsets[3]; ++ s8 hard_offsets[3]; + struct iio_mount_matrix orientation; + struct regmap *map; + struct regulator_bulk_data regs[2]; +-- +2.35.3 + diff --git a/patches.suse/intel_th-pci-Add-Raptor-Lake-S-CPU-support.patch b/patches.suse/intel_th-pci-Add-Raptor-Lake-S-CPU-support.patch index 340f2bf..f40d5a1 100644 --- a/patches.suse/intel_th-pci-Add-Raptor-Lake-S-CPU-support.patch +++ b/patches.suse/intel_th-pci-Add-Raptor-Lake-S-CPU-support.patch @@ -4,7 +4,7 @@ Date: Tue, 5 Jul 2022 11:26:37 +0300 Subject: [PATCH] intel_th: pci: Add Raptor Lake-S CPU support Git-commit: ff46a601afc5a66a81c3945b83d0a2caeb88e8bc Patch-mainline: v6.0-rc1 -References: git-fixes +References: jsc#PED-634 git-fixes Add support for the Trace Hub in Raptor Lake-S CPU. diff --git a/patches.suse/intel_th-pci-Add-Raptor-Lake-S-PCH-support.patch b/patches.suse/intel_th-pci-Add-Raptor-Lake-S-PCH-support.patch index f5ef36b..3fe13a7 100644 --- a/patches.suse/intel_th-pci-Add-Raptor-Lake-S-PCH-support.patch +++ b/patches.suse/intel_th-pci-Add-Raptor-Lake-S-PCH-support.patch @@ -4,7 +4,7 @@ Date: Tue, 5 Jul 2022 11:26:36 +0300 Subject: [PATCH] intel_th: pci: Add Raptor Lake-S PCH support Git-commit: 23e2de5826e2fc4dd43e08bab3a2ea1a5338b063 Patch-mainline: v6.0-rc1 -References: git-fixes +References: jsc#PED-634 git-fixes Add support for the Trace Hub in Raptor Lake-S PCH. diff --git a/patches.suse/iommu-vt-d-Acquiring-lock-in-domain-ID-allocation-helpers b/patches.suse/iommu-vt-d-Acquiring-lock-in-domain-ID-allocation-helpers index ad67da2..e847d2b 100644 --- a/patches.suse/iommu-vt-d-Acquiring-lock-in-domain-ID-allocation-helpers +++ b/patches.suse/iommu-vt-d-Acquiring-lock-in-domain-ID-allocation-helpers @@ -15,8 +15,8 @@ Reviewed-by: Kevin Tian Link: https://lore.kernel.org/r/20220706025524.2904370-7-baolu.lu@linux.intel.com Signed-off-by: Joerg Roedel --- - drivers/iommu/intel/iommu.c | 24 +++++++++--------------- - 1 file changed, 9 insertions(+), 15 deletions(-) + drivers/iommu/intel/iommu.c | 29 +++++++++-------------------- + 1 file changed, 9 insertions(+), 20 deletions(-) --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -89,7 +89,25 @@ Signed-off-by: Joerg Roedel if (ret) { spin_unlock_irqrestore(&device_domain_lock, flags); -@@ -4598,7 +4595,6 @@ static int aux_domain_add_dev(struct dma +@@ -4378,7 +4375,6 @@ static void __dmar_remove_one_dev_info(s + { + struct dmar_domain *domain; + struct intel_iommu *iommu; +- unsigned long flags; + + assert_spin_locked(&device_domain_lock); + +@@ -4400,9 +4396,7 @@ static void __dmar_remove_one_dev_info(s + + unlink_domain_info(info); + +- spin_lock_irqsave(&iommu->lock, flags); + domain_detach_iommu(domain, iommu); +- spin_unlock_irqrestore(&iommu->lock, flags); + + free_devinfo_mem(info); + } +@@ -4598,7 +4592,6 @@ static int aux_domain_add_dev(struct dma * iommu->lock must be held to attach domain to iommu and setup the * pasid entry for second level translation. */ @@ -97,7 +115,7 @@ Signed-off-by: Joerg Roedel ret = domain_attach_iommu(domain, iommu); if (ret) goto attach_failed; -@@ -4613,7 +4609,6 @@ static int aux_domain_add_dev(struct dma +@@ -4613,7 +4606,6 @@ static int aux_domain_add_dev(struct dma if (ret) goto table_failed; @@ -105,7 +123,7 @@ Signed-off-by: Joerg Roedel out: spin_unlock_irqrestore(&device_domain_lock, flags); -@@ -4622,7 +4617,6 @@ out: +@@ -4622,7 +4614,6 @@ out: table_failed: domain_detach_iommu(domain, iommu); attach_failed: @@ -113,3 +131,15 @@ Signed-off-by: Joerg Roedel auxiliary_unlink_device(domain, dev); link_failed: spin_unlock_irqrestore(&device_domain_lock, flags); +@@ -4647,11 +4638,9 @@ static void aux_domain_remove_dev(struct + iommu = info->iommu; + + if (!auxiliary_unlink_device(domain, dev)) { +- spin_lock(&iommu->lock); + intel_pasid_tear_down_entry(iommu, dev, + domain->default_pasid, false); + domain_detach_iommu(domain, iommu); +- spin_unlock(&iommu->lock); + } + + spin_unlock_irqrestore(&device_domain_lock, flags); diff --git a/patches.suse/ip-Fix-data-races-around-sysctl_ip_fwd_update_priori.patch b/patches.suse/ip-Fix-data-races-around-sysctl_ip_fwd_update_priori.patch new file mode 100644 index 0000000..2c8cc8f --- /dev/null +++ b/patches.suse/ip-Fix-data-races-around-sysctl_ip_fwd_update_priori.patch @@ -0,0 +1,57 @@ +From 3991d2ba5eaeb45ad9cb62e7a699baf2ce2b3ee0 Mon Sep 17 00:00:00 2001 +From: Kuniyuki Iwashima +Date: Wed, 13 Jul 2022 13:51:54 -0700 +Subject: [PATCH 14/28] ip: Fix data-races around + sysctl_ip_fwd_update_priority. +Git-commit: 7bf9e18d9a5e99e3c83482973557e9f047b051e7 +Patch-mainline: v5.19-rc8 +References: git-fixes + +While reading sysctl_ip_fwd_update_priority, it can be changed +concurrently. Thus, we need to add READ_ONCE() to its readers. + +Fixes: 432e05d32892 ("net: ipv4: Control SKB reprioritization after forwarding") +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: David S. Miller +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 3 ++- + net/ipv4/ip_forward.c | 2 +- + 2 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +index f69cbb3852d5..e2ada534057f 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +@@ -9733,13 +9733,14 @@ static int mlxsw_sp_dscp_init(struct mlxsw_sp *mlxsw_sp) + static int __mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp) + { + struct net *net = mlxsw_sp_net(mlxsw_sp); +- bool usp = net->ipv4.sysctl_ip_fwd_update_priority; + char rgcr_pl[MLXSW_REG_RGCR_LEN]; + u64 max_rifs; ++ bool usp; + + if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_RIFS)) + return -EIO; + max_rifs = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); ++ usp = READ_ONCE(net->ipv4.sysctl_ip_fwd_update_priority); + + mlxsw_reg_rgcr_pack(rgcr_pl, true, true); + mlxsw_reg_rgcr_max_router_interfaces_set(rgcr_pl, max_rifs); +diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c +index 00ec819f949b..29730edda220 100644 +--- a/net/ipv4/ip_forward.c ++++ b/net/ipv4/ip_forward.c +@@ -151,7 +151,7 @@ int ip_forward(struct sk_buff *skb) + !skb_sec_path(skb)) + ip_rt_send_redirect(skb); + +- if (net->ipv4.sysctl_ip_fwd_update_priority) ++ if (READ_ONCE(net->ipv4.sysctl_ip_fwd_update_priority)) + skb->priority = rt_tos2priority(iph->tos); + + return NF_HOOK(NFPROTO_IPV4, NF_INET_FORWARD, +-- +2.16.4 + diff --git a/patches.suse/ipv4-Fix-data-races-around-sysctl_fib_multipath_hash.patch b/patches.suse/ipv4-Fix-data-races-around-sysctl_fib_multipath_hash.patch new file mode 100644 index 0000000..4f3de4c --- /dev/null +++ b/patches.suse/ipv4-Fix-data-races-around-sysctl_fib_multipath_hash.patch @@ -0,0 +1,50 @@ +From a92a7edf38d8df650bb7fb63195c04ce38b88e2a Mon Sep 17 00:00:00 2001 +From: Kuniyuki Iwashima +Date: Mon, 18 Jul 2022 10:26:40 -0700 +Subject: [PATCH 24/28] ipv4: Fix data-races around + sysctl_fib_multipath_hash_policy. +Git-commit: 7998c12a08c97cc26660532c9f90a34bd7d8da5a +Patch-mainline: v5.19-rc8 +References: git-fixes + +While reading sysctl_fib_multipath_hash_policy, it can be changed +concurrently. Thus, we need to add READ_ONCE() to its readers. + +Fixes: bf4e0a3db97e ("net: ipv4: add support for ECMP hash policy choice") +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: David S. Miller +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 2 +- + net/ipv4/route.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +index e2ada534057f..60a231916518 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +@@ -9575,7 +9575,7 @@ static void mlxsw_sp_mp4_hash_init(struct mlxsw_sp *mlxsw_sp, + unsigned long *fields = config->fields; + u32 hash_fields; + +- switch (net->ipv4.sysctl_fib_multipath_hash_policy) { ++ switch (READ_ONCE(net->ipv4.sysctl_fib_multipath_hash_policy)) { + case 0: + mlxsw_sp_mp4_hash_outer_addr(config); + break; +diff --git a/net/ipv4/route.c b/net/ipv4/route.c +index 94e33d3eaf62..c056c58db629 100644 +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -2044,7 +2044,7 @@ int fib_multipath_hash(const struct net *net, const struct flowi4 *fl4, + struct flow_keys hash_keys; + u32 mhash = 0; + +- switch (net->ipv4.sysctl_fib_multipath_hash_policy) { ++ switch (READ_ONCE(net->ipv4.sysctl_fib_multipath_hash_policy)) { + case 0: + memset(&hash_keys, 0, sizeof(hash_keys)); + hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS; +-- +2.16.4 + diff --git a/patches.suse/ipv4-Handle-attempt-to-delete-multipath-route-when-f.patch b/patches.suse/ipv4-Handle-attempt-to-delete-multipath-route-when-f.patch new file mode 100644 index 0000000..cd54687 --- /dev/null +++ b/patches.suse/ipv4-Handle-attempt-to-delete-multipath-route-when-f.patch @@ -0,0 +1,75 @@ +From b26de4499f41b384de7d7bb7559cddae7edf62d1 Mon Sep 17 00:00:00 2001 +From: David Ahern +Date: Thu, 6 Oct 2022 10:48:49 -0600 +Subject: [PATCH] ipv4: Handle attempt to delete multipath route when fib_info + contains an nh reference + +References: bsc#1204171 CVE-2022-3435 +Patch-mainline: queued +Git-repo: https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git +Git-commit: 61b91eb33a69c3be11b259c5ea484505cd79f883 + +Gwangun Jung reported a slab-out-of-bounds access in fib_nh_match: + fib_nh_match+0xf98/0x1130 linux-6.0-rc7/net/ipv4/fib_semantics.c:961 + fib_table_delete+0x5f3/0xa40 linux-6.0-rc7/net/ipv4/fib_trie.c:1753 + inet_rtm_delroute+0x2b3/0x380 linux-6.0-rc7/net/ipv4/fib_frontend.c:874 + +Separate nexthop objects are mutually exclusive with the legacy +multipath spec. Fix fib_nh_match to return if the config for the +to be deleted route contains a multipath spec while the fib_info +is using a nexthop object. + +Fixes: 493ced1ac47c ("ipv4: Allow routes to use nexthop objects") +Fixes: 6bf92d70e690 ("net: ipv4: fix route with nexthop object delete warning") +Reported-by: Gwangun Jung +Signed-off-by: David Ahern +Reviewed-by: Ido Schimmel +Tested-by: Ido Schimmel +Signed-off-by: David S. Miller +Signed-off-by: Denis Kirjanov +--- + net/ipv4/fib_semantics.c | 8 ++++---- + tools/testing/selftests/net/fib_nexthops.sh | 5 +++++ + 2 files changed, 9 insertions(+), 4 deletions(-) + +diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c +index 2dc97583d279..e9a7f70a54df 100644 +--- a/net/ipv4/fib_semantics.c ++++ b/net/ipv4/fib_semantics.c +@@ -888,13 +888,13 @@ int fib_nh_match(struct net *net, struct fib_config *cfg, struct fib_info *fi, + return 1; + } + ++ /* cannot match on nexthop object attributes */ ++ if (fi->nh) ++ return 1; ++ + if (cfg->fc_oif || cfg->fc_gw_family) { + struct fib_nh *nh; + +- /* cannot match on nexthop object attributes */ +- if (fi->nh) +- return 1; +- + nh = fib_info_nh(fi, 0); + if (cfg->fc_encap) { + if (fib_encap_match(net, cfg->fc_encap_type, +diff --git a/tools/testing/selftests/net/fib_nexthops.sh b/tools/testing/selftests/net/fib_nexthops.sh +index d5a0dd548989..ee5e98204d3d 100755 +--- a/tools/testing/selftests/net/fib_nexthops.sh ++++ b/tools/testing/selftests/net/fib_nexthops.sh +@@ -1223,6 +1223,11 @@ ipv4_fcnal() + log_test $rc 0 "Delete nexthop route warning" + run_cmd "$IP route delete 172.16.101.1/32 nhid 12" + run_cmd "$IP nexthop del id 12" ++ ++ run_cmd "$IP nexthop add id 21 via 172.16.1.6 dev veth1" ++ run_cmd "$IP ro add 172.16.101.0/24 nhid 21" ++ run_cmd "$IP ro del 172.16.101.0/24 nexthop via 172.16.1.7 dev veth1 nexthop via 172.16.1.8 dev veth1" ++ log_test $? 2 "Delete multipath route with only nh id based entry" + } + + ipv4_grp_fcnal() +-- +2.16.4 + diff --git a/patches.suse/irqchip-ls-extirq-Fix-invalid-wait-context-by-avoidi.patch b/patches.suse/irqchip-ls-extirq-Fix-invalid-wait-context-by-avoidi.patch new file mode 100644 index 0000000..de215e6 --- /dev/null +++ b/patches.suse/irqchip-ls-extirq-Fix-invalid-wait-context-by-avoidi.patch @@ -0,0 +1,184 @@ +From 1b00adce8afdb842615a5bf3774510f14a9b769a Mon Sep 17 00:00:00 2001 +From: Vladimir Oltean +Date: Thu, 28 Jul 2022 17:42:54 +0300 +Subject: [PATCH] irqchip/ls-extirq: Fix invalid wait context by avoiding to use regmap +Git-commit: 1b00adce8afdb842615a5bf3774510f14a9b769a +Patch-mainline: v6.1-rc1 +References: git-fixes + +The irqchip->irq_set_type method is called by __irq_set_trigger() under +the desc->lock raw spinlock. + +The ls-extirq implementation, ls_extirq_irq_set_type(), uses an MMIO +regmap created by of_syscon_register(), which uses plain spinlocks +(the kind that are sleepable on RT). + +Therefore, this is an invalid locking scheme for which we get a kernel +splat stating just that ("[ BUG: Invalid wait context ]"), because the +context in which the plain spinlock may sleep is atomic due to the raw +spinlock. We need to go raw spinlocks all the way. + +Make this driver ioremap its INTPCR register on its own, and stop +relying on syscon to provide a regmap. + +Fixes: 0dcd9f872769 ("irqchip: Add support for Layerscape external interrupt lines") +Signed-off-by: Vladimir Oltean +[maz: trimmed down commit log] +Signed-off-by: Marc Zyngier +Link: https://lore.kernel.org/r/20220728144254.175385-1-vladimir.oltean@nxp.com +Acked-by: Takashi Iwai + +--- + drivers/irqchip/irq-ls-extirq.c | 87 ++++++++++++++++++++++++--------- + 1 file changed, 63 insertions(+), 24 deletions(-) + +diff --git a/drivers/irqchip/irq-ls-extirq.c b/drivers/irqchip/irq-ls-extirq.c +index 853b3972dbe7..d8d48b1f7c29 100644 +--- a/drivers/irqchip/irq-ls-extirq.c ++++ b/drivers/irqchip/irq-ls-extirq.c +@@ -6,8 +6,7 @@ + #include + #include + #include +-#include +-#include ++#include + #include + + #include +@@ -16,13 +15,41 @@ + #define LS1021A_SCFGREVCR 0x200 + + struct ls_extirq_data { +- struct regmap *syscon; +- u32 intpcr; ++ void __iomem *intpcr; ++ raw_spinlock_t lock; ++ bool big_endian; + bool is_ls1021a_or_ls1043a; + u32 nirq; + struct irq_fwspec map[MAXIRQ]; + }; + ++static void ls_extirq_intpcr_rmw(struct ls_extirq_data *priv, u32 mask, ++ u32 value) ++{ ++ u32 intpcr; ++ ++ /* ++ * Serialize concurrent calls to ls_extirq_set_type() from multiple ++ * IRQ descriptors, making sure the read-modify-write is atomic. ++ */ ++ raw_spin_lock(&priv->lock); ++ ++ if (priv->big_endian) ++ intpcr = ioread32be(priv->intpcr); ++ else ++ intpcr = ioread32(priv->intpcr); ++ ++ intpcr &= ~mask; ++ intpcr |= value; ++ ++ if (priv->big_endian) ++ iowrite32be(intpcr, priv->intpcr); ++ else ++ iowrite32(intpcr, priv->intpcr); ++ ++ raw_spin_unlock(&priv->lock); ++} ++ + static int + ls_extirq_set_type(struct irq_data *data, unsigned int type) + { +@@ -51,7 +78,8 @@ ls_extirq_set_type(struct irq_data *data, unsigned int type) + default: + return -EINVAL; + } +- regmap_update_bits(priv->syscon, priv->intpcr, mask, value); ++ ++ ls_extirq_intpcr_rmw(priv, mask, value); + + return irq_chip_set_type_parent(data, type); + } +@@ -143,7 +171,6 @@ ls_extirq_parse_map(struct ls_extirq_data *priv, struct device_node *node) + static int __init + ls_extirq_of_init(struct device_node *node, struct device_node *parent) + { +- + struct irq_domain *domain, *parent_domain; + struct ls_extirq_data *priv; + int ret; +@@ -151,40 +178,52 @@ ls_extirq_of_init(struct device_node *node, struct device_node *parent) + parent_domain = irq_find_host(parent); + if (!parent_domain) { + pr_err("Cannot find parent domain\n"); +- return -ENODEV; ++ ret = -ENODEV; ++ goto err_irq_find_host; + } + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); +- if (!priv) +- return -ENOMEM; +- +- priv->syscon = syscon_node_to_regmap(node->parent); +- if (IS_ERR(priv->syscon)) { +- ret = PTR_ERR(priv->syscon); +- pr_err("Failed to lookup parent regmap\n"); +- goto out; ++ if (!priv) { ++ ret = -ENOMEM; ++ goto err_alloc_priv; + } +- ret = of_property_read_u32(node, "reg", &priv->intpcr); +- if (ret) { +- pr_err("Missing INTPCR offset value\n"); +- goto out; ++ ++ /* ++ * All extirq OF nodes are under a scfg/syscon node with ++ * the 'ranges' property ++ */ ++ priv->intpcr = of_iomap(node, 0); ++ if (!priv->intpcr) { ++ pr_err("Cannot ioremap OF node %pOF\n", node); ++ ret = -ENOMEM; ++ goto err_iomap; + } + + ret = ls_extirq_parse_map(priv, node); + if (ret) +- goto out; ++ goto err_parse_map; + ++ priv->big_endian = of_device_is_big_endian(parent); + priv->is_ls1021a_or_ls1043a = of_device_is_compatible(node, "fsl,ls1021a-extirq") || + of_device_is_compatible(node, "fsl,ls1043a-extirq"); ++ raw_spin_lock_init(&priv->lock); + + domain = irq_domain_add_hierarchy(parent_domain, 0, priv->nirq, node, + &extirq_domain_ops, priv); +- if (!domain) ++ if (!domain) { + ret = -ENOMEM; ++ goto err_add_hierarchy; ++ } + +-out: +- if (ret) +- kfree(priv); ++ return 0; ++ ++err_add_hierarchy: ++err_parse_map: ++ iounmap(priv->intpcr); ++err_iomap: ++ kfree(priv); ++err_alloc_priv: ++err_irq_find_host: + return ret; + } + +-- +2.35.3 + diff --git a/patches.suse/jfs-prevent-NULL-deref-in-diFree.patch b/patches.suse/jfs-prevent-NULL-deref-in-diFree.patch new file mode 100644 index 0000000..e6e7f9a --- /dev/null +++ b/patches.suse/jfs-prevent-NULL-deref-in-diFree.patch @@ -0,0 +1,48 @@ +From a53046291020ec41e09181396c1e829287b48d47 Mon Sep 17 00:00:00 2001 +From: Haimin Zhang +Date: Tue, 22 Mar 2022 21:59:17 +0800 +Subject: [PATCH] jfs: prevent NULL deref in diFree +Git-commit: a53046291020ec41e09181396c1e829287b48d47 +Patch-mainline: v5.18-rc1 +References: bsc#1203389 CVE-2022-3202 + +Add validation check for JFS_IP(ipimap)->i_imap to prevent a NULL deref +in diFree since diFree uses it without do any validations. +When function jfs_mount calls diMount to initialize fileset inode +allocation map, it can fail and JFS_IP(ipimap)->i_imap won't be +initialized. Then it calls diFreeSpecial to close fileset inode allocation +map inode and it will flow into jfs_evict_inode. Function jfs_evict_inode +just validates JFS_SBI(inode->i_sb)->ipimap, then calls diFree. diFree use +JFS_IP(ipimap)->i_imap directly, then it will cause a NULL deref. + +Reported-by: TCS Robot +Signed-off-by: Haimin Zhang +Signed-off-by: Dave Kleikamp +Acked-by: Anthony Iliopoulos + +--- + fs/jfs/inode.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c +index 57ab424c05ff..072821b50ab9 100644 +--- a/fs/jfs/inode.c ++++ b/fs/jfs/inode.c +@@ -146,12 +146,13 @@ void jfs_evict_inode(struct inode *inode) + dquot_initialize(inode); + + if (JFS_IP(inode)->fileset == FILESYSTEM_I) { ++ struct inode *ipimap = JFS_SBI(inode->i_sb)->ipimap; + truncate_inode_pages_final(&inode->i_data); + + if (test_cflag(COMMIT_Freewmap, inode)) + jfs_free_zero_link(inode); + +- if (JFS_SBI(inode->i_sb)->ipimap) ++ if (ipimap && JFS_IP(ipimap)->i_imap) + diFree(inode); + + /* +-- +2.35.3 + diff --git a/patches.suse/kexec-KEYS-make-the-code-in-bzImage64_verify_sig-gen.patch b/patches.suse/kexec-KEYS-make-the-code-in-bzImage64_verify_sig-gen.patch new file mode 100644 index 0000000..4090a9a --- /dev/null +++ b/patches.suse/kexec-KEYS-make-the-code-in-bzImage64_verify_sig-gen.patch @@ -0,0 +1,128 @@ +From c903dae8941deb55043ee46ded29e84e97cd84bb Mon Sep 17 00:00:00 2001 +From: Coiby Xu +Date: Thu, 14 Jul 2022 21:40:25 +0800 +Subject: [PATCH] kexec, KEYS: make the code in bzImage64_verify_sig generic + +References: bsc#1196444 +Patch-mainline: v6.0-rc1 +Git-commit: c903dae8941deb55043ee46ded29e84e97cd84bb + +commit 278311e417be ("kexec, KEYS: Make use of platform keyring for +signature verify") adds platform keyring support on x86 kexec but not +arm64. + +The code in bzImage64_verify_sig uses the keys on the +.builtin_trusted_keys, .machine, if configured and enabled, +.secondary_trusted_keys, also if configured, and .platform keyrings +to verify the signed kernel image as PE file. + +Cc: kexec@lists.infradead.org +Cc: keyrings@vger.kernel.org +Cc: linux-security-module@vger.kernel.org +Reviewed-by: Michal Suchanek +Signed-off-by: Coiby Xu +Signed-off-by: Mimi Zohar +Acked-by: Michal Suchanek +--- + arch/x86/kernel/kexec-bzimage64.c | 20 +------------------- + include/linux/kexec.h | 7 +++++++ + kernel/kexec_file.c | 17 +++++++++++++++++ + 3 files changed, 25 insertions(+), 19 deletions(-) + +diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c +index 170d0fd68b1f..f299b48f9c9f 100644 +--- a/arch/x86/kernel/kexec-bzimage64.c ++++ b/arch/x86/kernel/kexec-bzimage64.c +@@ -17,7 +17,6 @@ + #include + #include + #include +-#include + + #include + #include +@@ -528,28 +527,11 @@ static int bzImage64_cleanup(void *loader_data) + return 0; + } + +-#ifdef CONFIG_KEXEC_BZIMAGE_VERIFY_SIG +-static int bzImage64_verify_sig(const char *kernel, unsigned long kernel_len) +-{ +- int ret; +- +- ret = verify_pefile_signature(kernel, kernel_len, +- VERIFY_USE_SECONDARY_KEYRING, +- VERIFYING_KEXEC_PE_SIGNATURE); +- if (ret == -ENOKEY && IS_ENABLED(CONFIG_INTEGRITY_PLATFORM_KEYRING)) { +- ret = verify_pefile_signature(kernel, kernel_len, +- VERIFY_USE_PLATFORM_KEYRING, +- VERIFYING_KEXEC_PE_SIGNATURE); +- } +- return ret; +-} +-#endif +- + const struct kexec_file_ops kexec_bzImage64_ops = { + .probe = bzImage64_probe, + .load = bzImage64_load, + .cleanup = bzImage64_cleanup, + #ifdef CONFIG_KEXEC_BZIMAGE_VERIFY_SIG +- .verify_sig = bzImage64_verify_sig, ++ .verify_sig = kexec_kernel_verify_pe_sig, + #endif + }; +diff --git a/include/linux/kexec.h b/include/linux/kexec.h +--- a/include/linux/kexec.h ++++ b/include/linux/kexec.h +@@ -19,6 +19,7 @@ + #include + + #include ++#include + + #ifdef CONFIG_KEXEC_CORE + #include +@@ -212,6 +213,12 @@ static inline void *arch_kexec_kernel_image_load(struct kimage *image) + } + #endif + ++#ifdef CONFIG_KEXEC_SIG ++#ifdef CONFIG_SIGNED_PE_FILE_VERIFICATION ++int kexec_kernel_verify_pe_sig(const char *kernel, unsigned long kernel_len); ++#endif ++#endif ++ + extern int kexec_add_buffer(struct kexec_buf *kbuf); + int kexec_locate_mem_hole(struct kexec_buf *kbuf); + +diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c +index 6dc1294c90fc..a7b411c22f19 100644 +--- a/kernel/kexec_file.c ++++ b/kernel/kexec_file.c +@@ -123,6 +123,23 @@ void kimage_file_post_load_cleanup(struct kimage *image) + } + + #ifdef CONFIG_KEXEC_SIG ++#ifdef CONFIG_SIGNED_PE_FILE_VERIFICATION ++int kexec_kernel_verify_pe_sig(const char *kernel, unsigned long kernel_len) ++{ ++ int ret; ++ ++ ret = verify_pefile_signature(kernel, kernel_len, ++ VERIFY_USE_SECONDARY_KEYRING, ++ VERIFYING_KEXEC_PE_SIGNATURE); ++ if (ret == -ENOKEY && IS_ENABLED(CONFIG_INTEGRITY_PLATFORM_KEYRING)) { ++ ret = verify_pefile_signature(kernel, kernel_len, ++ VERIFY_USE_PLATFORM_KEYRING, ++ VERIFYING_KEXEC_PE_SIGNATURE); ++ } ++ return ret; ++} ++#endif ++ + static int kexec_image_verify_sig(struct kimage *image, void *buf, + unsigned long buf_len) + { +-- +2.35.3 + diff --git a/patches.suse/kexec-KEYS-s390-Make-use-of-built-in-and-secondary-k.patch b/patches.suse/kexec-KEYS-s390-Make-use-of-built-in-and-secondary-k.patch new file mode 100644 index 0000000..9a3bc77 --- /dev/null +++ b/patches.suse/kexec-KEYS-s390-Make-use-of-built-in-and-secondary-k.patch @@ -0,0 +1,72 @@ +From 0828c4a39be57768b8788e8cbd0d84683ea757e5 Mon Sep 17 00:00:00 2001 +From: Michal Suchanek +Date: Thu, 14 Jul 2022 21:40:27 +0800 +Subject: [PATCH] kexec, KEYS, s390: Make use of built-in and secondary keyring + for signature verification + +References: bsc#1196444 +Patch-mainline: v6.0-rc1 +Git-commit: 0828c4a39be57768b8788e8cbd0d84683ea757e5 + +commit e23a8020ce4e ("s390/kexec_file: Signature verification prototype") +adds support for KEXEC_SIG verification with keys from platform keyring +but the built-in keys and secondary keyring are not used. + +Add support for the built-in keys and secondary keyring as x86 does. + +Fixes: e23a8020ce4e ("s390/kexec_file: Signature verification prototype") +Cc: stable@vger.kernel.org +Cc: Philipp Rudo +Cc: kexec@lists.infradead.org +Cc: keyrings@vger.kernel.org +Cc: linux-security-module@vger.kernel.org +Signed-off-by: Michal Suchanek +Reviewed-by: "Lee, Chun-Yi" +Acked-by: Baoquan He +Signed-off-by: Coiby Xu +Acked-by: Heiko Carstens +Signed-off-by: Mimi Zohar +Acked-by: Michal Suchanek +--- + arch/s390/kernel/machine_kexec_file.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +diff --git a/arch/s390/kernel/machine_kexec_file.c b/arch/s390/kernel/machine_kexec_file.c +index 8f43575a4dd3..fc6d5f58debe 100644 +--- a/arch/s390/kernel/machine_kexec_file.c ++++ b/arch/s390/kernel/machine_kexec_file.c +@@ -31,6 +31,7 @@ int s390_verify_sig(const char *kernel, unsigned long kernel_len) + const unsigned long marker_len = sizeof(MODULE_SIG_STRING) - 1; + struct module_signature *ms; + unsigned long sig_len; ++ int ret; + + /* Skip signature verification when not secure IPLed. */ + if (!ipl_secure_flag) +@@ -65,11 +66,18 @@ int s390_verify_sig(const char *kernel, unsigned long kernel_len) + return -EBADMSG; + } + +- return verify_pkcs7_signature(kernel, kernel_len, +- kernel + kernel_len, sig_len, +- VERIFY_USE_PLATFORM_KEYRING, +- VERIFYING_MODULE_SIGNATURE, +- NULL, NULL); ++ ret = verify_pkcs7_signature(kernel, kernel_len, ++ kernel + kernel_len, sig_len, ++ VERIFY_USE_SECONDARY_KEYRING, ++ VERIFYING_MODULE_SIGNATURE, ++ NULL, NULL); ++ if (ret == -ENOKEY && IS_ENABLED(CONFIG_INTEGRITY_PLATFORM_KEYRING)) ++ ret = verify_pkcs7_signature(kernel, kernel_len, ++ kernel + kernel_len, sig_len, ++ VERIFY_USE_PLATFORM_KEYRING, ++ VERIFYING_MODULE_SIGNATURE, ++ NULL, NULL); ++ return ret; + } + #endif /* CONFIG_KEXEC_SIG */ + +-- +2.35.3 + diff --git a/patches.suse/kexec-clean-up-arch_kexec_kernel_verify_sig.patch b/patches.suse/kexec-clean-up-arch_kexec_kernel_verify_sig.patch new file mode 100644 index 0000000..d5c9798 --- /dev/null +++ b/patches.suse/kexec-clean-up-arch_kexec_kernel_verify_sig.patch @@ -0,0 +1,107 @@ +From 689a71493bd2f31c024f8c0395f85a1fd4b2138e Mon Sep 17 00:00:00 2001 +From: Coiby Xu +Date: Thu, 14 Jul 2022 21:40:24 +0800 +Subject: [PATCH] kexec: clean up arch_kexec_kernel_verify_sig + +References: bsc#1196444 +Patch-mainline: v6.0-rc1 +Git-commit: 689a71493bd2f31c024f8c0395f85a1fd4b2138e + +Before commit 105e10e2cf1c ("kexec_file: drop weak attribute from +functions"), there was already no arch-specific implementation +of arch_kexec_kernel_verify_sig. With weak attribute dropped by that +commit, arch_kexec_kernel_verify_sig is completely useless. So clean it +up. + +Note later patches are dependent on this patch so it should be backported +to the stable tree as well. + +Cc: stable@vger.kernel.org +Suggested-by: Eric W. Biederman +Reviewed-by: Michal Suchanek +Acked-by: Baoquan He +Signed-off-by: Coiby Xu +[zohar@linux.ibm.com: reworded patch description "Note"] +Link: https://lore.kernel.org/linux-integrity/20220714134027.394370-1-coxu@redhat.com/ +Signed-off-by: Mimi Zohar +Acked-by: Michal Suchanek +--- + include/linux/kexec.h | 5 ----- + kernel/kexec_file.c | 33 +++++++++++++-------------------- + 2 files changed, 13 insertions(+), 25 deletions(-) + +diff --git a/include/linux/kexec.h b/include/linux/kexec.h +index 8107606ad1e8..7f710fb3712b 100644 +--- a/include/linux/kexec.h ++++ b/include/linux/kexec.h +@@ -212,11 +212,6 @@ static inline void *arch_kexec_kernel_image_load(struct kimage *image) + } + #endif + +-#ifdef CONFIG_KEXEC_SIG +-int arch_kexec_kernel_verify_sig(struct kimage *image, void *buf, +- unsigned long buf_len); +-#endif +- + extern int kexec_add_buffer(struct kexec_buf *kbuf); + int kexec_locate_mem_hole(struct kexec_buf *kbuf); + +diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c +index 0c27c81351ee..6dc1294c90fc 100644 +--- a/kernel/kexec_file.c ++++ b/kernel/kexec_file.c +@@ -81,24 +81,6 @@ int kexec_image_post_load_cleanup_default(struct kimage *image) + return image->fops->cleanup(image->image_loader_data); + } + +-#ifdef CONFIG_KEXEC_SIG +-static int kexec_image_verify_sig_default(struct kimage *image, void *buf, +- unsigned long buf_len) +-{ +- if (!image->fops || !image->fops->verify_sig) { +- pr_debug("kernel loader does not support signature verification.\n"); +- return -EKEYREJECTED; +- } +- +- return image->fops->verify_sig(buf, buf_len); +-} +- +-int arch_kexec_kernel_verify_sig(struct kimage *image, void *buf, unsigned long buf_len) +-{ +- return kexec_image_verify_sig_default(image, buf, buf_len); +-} +-#endif +- + /* + * Free up memory used by kernel, initrd, and command line. This is temporary + * memory allocation which is not needed any more after these buffers have +@@ -141,13 +123,24 @@ void kimage_file_post_load_cleanup(struct kimage *image) + } + + #ifdef CONFIG_KEXEC_SIG ++static int kexec_image_verify_sig(struct kimage *image, void *buf, ++ unsigned long buf_len) ++{ ++ if (!image->fops || !image->fops->verify_sig) { ++ pr_debug("kernel loader does not support signature verification.\n"); ++ return -EKEYREJECTED; ++ } ++ ++ return image->fops->verify_sig(buf, buf_len); ++} ++ + static int + kimage_validate_signature(struct kimage *image) + { + int ret; + +- ret = arch_kexec_kernel_verify_sig(image, image->kernel_buf, +- image->kernel_buf_len); ++ ret = kexec_image_verify_sig(image, image->kernel_buf, ++ image->kernel_buf_len); + if (ret) { + + if (sig_enforce) { +-- +2.35.3 + diff --git a/patches.suse/kexec-drop-weak-attribute-from-functions.patch b/patches.suse/kexec-drop-weak-attribute-from-functions.patch new file mode 100644 index 0000000..e580dbb --- /dev/null +++ b/patches.suse/kexec-drop-weak-attribute-from-functions.patch @@ -0,0 +1,235 @@ +From 0738eceb6201691534df07e0928d0a6168a35787 Mon Sep 17 00:00:00 2001 +From: "Naveen N. Rao" +Date: Fri, 1 Jul 2022 13:04:05 +0530 +Subject: [PATCH] kexec: drop weak attribute from functions + +References: bsc#1196444 +Patch-mainline: v6.0-rc1 +Git-commit: 0738eceb6201691534df07e0928d0a6168a35787 + +Drop __weak attribute from functions in kexec_core.c: +- machine_kexec_post_load() +- arch_kexec_protect_crashkres() +- arch_kexec_unprotect_crashkres() +- crash_free_reserved_phys_range() + +Link: https://lkml.kernel.org/r/c0f6219e03cb399d166d518ab505095218a902dd.1656659357.git.naveen.n.rao@linux.vnet.ibm.com +Signed-off-by: Naveen N. Rao +Suggested-by: Eric Biederman +Signed-off-by: Andrew Morton +Signed-off-by: Mimi Zohar +Acked-by: Michal Suchanek +--- + arch/arm64/include/asm/kexec.h | 16 ++++++++++++++-- + arch/powerpc/include/asm/kexec.h | 5 +++++ + arch/s390/include/asm/kexec.h | 11 +++++++++++ + arch/x86/include/asm/kexec.h | 6 ++++++ + include/linux/kexec.h | 32 ++++++++++++++++++++++++++++---- + kernel/kexec_core.c | 27 --------------------------- + 6 files changed, 64 insertions(+), 33 deletions(-) + +diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h +--- a/arch/arm64/include/asm/kexec.h ++++ b/arch/arm64/include/asm/kexec.h +@@ -84,11 +84,28 @@ static inline void crash_setup_regs(struct pt_regs *newregs, + extern bool crash_is_nosave(unsigned long pfn); + extern void crash_prepare_suspend(void); + extern void crash_post_resume(void); ++ ++void crash_free_reserved_phys_range(unsigned long begin, unsigned long end); ++#define crash_free_reserved_phys_range crash_free_reserved_phys_range + #else + static inline bool crash_is_nosave(unsigned long pfn) {return false; } + static inline void crash_prepare_suspend(void) {} + static inline void crash_post_resume(void) {} + #endif ++ ++struct kimage; ++ ++#if defined(CONFIG_KEXEC_CORE) ++ ++int machine_kexec_post_load(struct kimage *image); ++#define machine_kexec_post_load machine_kexec_post_load ++ ++void arch_kexec_protect_crashkres(void); ++#define arch_kexec_protect_crashkres arch_kexec_protect_crashkres ++ ++void arch_kexec_unprotect_crashkres(void); ++#define arch_kexec_unprotect_crashkres arch_kexec_unprotect_crashkres ++#endif + + #define ARCH_HAS_KIMAGE_ARCH + +@@ -113,8 +127,6 @@ struct kimage_arch { + #ifdef CONFIG_KEXEC_FILE + extern const struct kexec_file_ops kexec_image_ops; + +-struct kimage; +- + int arch_kimage_file_post_load_cleanup(struct kimage *image); + #define arch_kimage_file_post_load_cleanup arch_kimage_file_post_load_cleanup + +diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h +--- a/arch/powerpc/include/asm/kexec.h ++++ b/arch/powerpc/include/asm/kexec.h +@@ -98,6 +98,11 @@ void relocate_new_kernel(unsigned long indirection_page, unsigned long reboot_co + void relocate_new_kernel(unsigned long indirection_page, unsigned long reboot_code_buffer, + unsigned long start_address) __noreturn; + ++#if defined(CONFIG_CRASH_DUMP) && defined(CONFIG_PPC_RTAS) ++void crash_free_reserved_phys_range(unsigned long begin, unsigned long end); ++#define crash_free_reserved_phys_range crash_free_reserved_phys_range ++#endif ++ + #ifdef CONFIG_KEXEC_FILE + extern const struct kexec_file_ops kexec_elf64_ops; + +diff --git a/arch/s390/include/asm/kexec.h b/arch/s390/include/asm/kexec.h +index 8886aadc11a3..1bd08eb56d5f 100644 +--- a/arch/s390/include/asm/kexec.h ++++ b/arch/s390/include/asm/kexec.h +@@ -85,6 +85,17 @@ struct kimage_arch { + extern const struct kexec_file_ops s390_kexec_image_ops; + extern const struct kexec_file_ops s390_kexec_elf_ops; + ++#ifdef CONFIG_CRASH_DUMP ++void crash_free_reserved_phys_range(unsigned long begin, unsigned long end); ++#define crash_free_reserved_phys_range crash_free_reserved_phys_range ++ ++void arch_kexec_protect_crashkres(void); ++#define arch_kexec_protect_crashkres arch_kexec_protect_crashkres ++ ++void arch_kexec_unprotect_crashkres(void); ++#define arch_kexec_unprotect_crashkres arch_kexec_unprotect_crashkres ++#endif ++ + #ifdef CONFIG_KEXEC_FILE + struct purgatory_info; + int arch_kexec_apply_relocations_add(struct purgatory_info *pi, +diff --git a/arch/x86/include/asm/kexec.h b/arch/x86/include/asm/kexec.h +index 5ec359c1b50c..a3760ca796aa 100644 +--- a/arch/x86/include/asm/kexec.h ++++ b/arch/x86/include/asm/kexec.h +@@ -186,6 +186,12 @@ extern int arch_kexec_post_alloc_pages(void *vaddr, unsigned int pages, + extern void arch_kexec_pre_free_pages(void *vaddr, unsigned int pages); + #define arch_kexec_pre_free_pages arch_kexec_pre_free_pages + ++void arch_kexec_protect_crashkres(void); ++#define arch_kexec_protect_crashkres arch_kexec_protect_crashkres ++ ++void arch_kexec_unprotect_crashkres(void); ++#define arch_kexec_unprotect_crashkres arch_kexec_unprotect_crashkres ++ + #ifdef CONFIG_KEXEC_FILE + struct purgatory_info; + int arch_kexec_apply_relocations_add(struct purgatory_info *pi, +diff --git a/include/linux/kexec.h b/include/linux/kexec.h +index 6958c6b471f4..8107606ad1e8 100644 +--- a/include/linux/kexec.h ++++ b/include/linux/kexec.h +@@ -390,7 +390,10 @@ extern void machine_kexec_cleanup(struct kimage *image); + extern int kernel_kexec(void); + extern struct page *kimage_alloc_control_pages(struct kimage *image, + unsigned int order); +-int machine_kexec_post_load(struct kimage *image); ++ ++#ifndef machine_kexec_post_load ++static inline int machine_kexec_post_load(struct kimage *image) { return 0; } ++#endif + + extern void __crash_kexec(struct pt_regs *); + extern void crash_kexec(struct pt_regs *); +@@ -423,10 +426,21 @@ extern bool kexec_in_progress; + + int crash_shrink_memory(unsigned long new_size); + size_t crash_get_memory_size(void); +-void crash_free_reserved_phys_range(unsigned long begin, unsigned long end); + +-void arch_kexec_protect_crashkres(void); +-void arch_kexec_unprotect_crashkres(void); ++#ifndef arch_kexec_protect_crashkres ++/* ++ * Protection mechanism for crashkernel reserved memory after ++ * the kdump kernel is loaded. ++ * ++ * Provide an empty default implementation here -- architecture ++ * code may override this ++ */ ++static inline void arch_kexec_protect_crashkres(void) { } ++#endif ++ ++#ifndef arch_kexec_unprotect_crashkres ++static inline void arch_kexec_unprotect_crashkres(void) { } ++#endif + + #ifndef page_to_boot_pfn + static inline unsigned long page_to_boot_pfn(struct page *page) +@@ -456,6 +470,16 @@ static inline phys_addr_t boot_phys_to_phys(unsigned long boot_phys) + } + #endif + ++#ifndef crash_free_reserved_phys_range ++static inline void crash_free_reserved_phys_range(unsigned long begin, unsigned long end) ++{ ++ unsigned long addr; ++ ++ for (addr = begin; addr < end; addr += PAGE_SIZE) ++ free_reserved_page(boot_pfn_to_page(addr >> PAGE_SHIFT)); ++} ++#endif ++ + static inline unsigned long virt_to_boot_phys(void *addr) + { + return phys_to_boot_phys(__pa((unsigned long)addr)); +diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c +index 4d34c78334ce..acd029b307e4 100644 +--- a/kernel/kexec_core.c ++++ b/kernel/kexec_core.c +@@ -591,11 +591,6 @@ static void kimage_free_extra_pages(struct kimage *image) + + } + +-int __weak machine_kexec_post_load(struct kimage *image) +-{ +- return 0; +-} +- + void kimage_terminate(struct kimage *image) + { + if (*image->entry != 0) +@@ -1020,15 +1015,6 @@ size_t crash_get_memory_size(void) + return size; + } + +-void __weak crash_free_reserved_phys_range(unsigned long begin, +- unsigned long end) +-{ +- unsigned long addr; +- +- for (addr = begin; addr < end; addr += PAGE_SIZE) +- free_reserved_page(boot_pfn_to_page(addr >> PAGE_SHIFT)); +-} +- + int crash_shrink_memory(unsigned long new_size) + { + int ret = 0; +@@ -1225,16 +1211,3 @@ int kernel_kexec(void) + mutex_unlock(&kexec_mutex); + return error; + } +- +-/* +- * Protection mechanism for crashkernel reserved memory after +- * the kdump kernel is loaded. +- * +- * Provide an empty default implementation here -- architecture +- * code may override this +- */ +-void __weak arch_kexec_protect_crashkres(void) +-{} +- +-void __weak arch_kexec_unprotect_crashkres(void) +-{} +-- +2.35.3 + diff --git a/patches.suse/kexec_file-drop-weak-attribute-from-functions.patch b/patches.suse/kexec_file-drop-weak-attribute-from-functions.patch new file mode 100644 index 0000000..efc6ffd --- /dev/null +++ b/patches.suse/kexec_file-drop-weak-attribute-from-functions.patch @@ -0,0 +1,266 @@ +From 20c080830b6f538366d7ff18b64de704dd551e61 Mon Sep 17 00:00:00 2001 +From: "Naveen N. Rao" +Date: Fri, 1 Jul 2022 13:04:04 +0530 +Subject: [PATCH] kexec_file: drop weak attribute from functions + +References: bsc#1196444 +Patch-mainline: v6.0-rc1 +Git-commit: 65d9a9a60fd71be964effb2e94747a6acb6e7015 + +As requested +(http://lkml.kernel.org/r/87ee0q7b92.fsf@email.froward.int.ebiederm.org), +this series converts weak functions in kexec to use the #ifdef approach. + +Quoting the 3e35142ef99fe ("kexec_file: drop weak attribute from +arch_kexec_apply_relocations[_add]") changelog: + +: Since commit d1bcae833b32f1 ("ELF: Don't generate unused section symbols") +: [1], binutils (v2.36+) started dropping section symbols that it thought +: were unused. This isn't an issue in general, but with kexec_file.c, gcc +: is placing kexec_arch_apply_relocations[_add] into a separate +: .text.unlikely section and the section symbol ".text.unlikely" is being +: dropped. Due to this, recordmcount is unable to find a non-weak symbol in +: .text.unlikely to generate a relocation record against. + +This patch (of 2); + +Drop __weak attribute from functions in kexec_file.c: +- arch_kexec_kernel_image_probe() +- arch_kimage_file_post_load_cleanup() +- arch_kexec_kernel_image_load() +- arch_kexec_locate_mem_hole() +- arch_kexec_kernel_verify_sig() + +arch_kexec_kernel_image_load() calls into kexec_image_load_default(), so +drop the static attribute for the latter. + +arch_kexec_kernel_verify_sig() is not overridden by any architecture, so +drop the __weak attribute. + +Link: https://lkml.kernel.org/r/cover.1656659357.git.naveen.n.rao@linux.vnet.ibm.com +Link: https://lkml.kernel.org/r/2cd7ca1fe4d6bb6ca38e3283c717878388ed6788.1656659357.git.naveen.n.rao@linux.vnet.ibm.com +Signed-off-by: Naveen N. Rao +Suggested-by: Eric Biederman +Signed-off-by: Andrew Morton +Signed-off-by: Mimi Zohar +Note: before commit 277c8389386e ("s390/kexec_file: move kernel image size check") +in v 5.16 there is an additional intance of arch_kexec_kernel_image_probe on s390 +Acked-by: Michal Suchanek +--- + arch/arm64/include/asm/kexec.h | 4 ++- + arch/powerpc/include/asm/kexec.h | 9 +++++++ + arch/s390/include/asm/kexec.h | 6 +++++ + arch/x86/include/asm/kexec.h | 6 +++++ + include/linux/kexec.h | 44 +++++++++++++++++++++++++++----- + kernel/kexec_file.c | 35 ++----------------------- + 6 files changed, 64 insertions(+), 40 deletions(-) + +diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h +index d24b527e8c00..6db1051653a4 100644 +--- a/arch/arm64/include/asm/kexec.h ++++ b/arch/arm64/include/asm/kexec.h +@@ -106,7 +106,9 @@ extern const struct kexec_file_ops kexec_image_ops; + + struct kimage; + +-extern int arch_kimage_file_post_load_cleanup(struct kimage *image); ++int arch_kimage_file_post_load_cleanup(struct kimage *image); ++#define arch_kimage_file_post_load_cleanup arch_kimage_file_post_load_cleanup ++ + extern int load_other_segments(struct kimage *image, + unsigned long kernel_load_addr, unsigned long kernel_size, + char *initrd, unsigned long initrd_len, +diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h +index 9ab344d29a54..eb3ea43c5646 100644 +--- a/arch/powerpc/include/asm/kexec.h ++++ b/arch/powerpc/include/asm/kexec.h +@@ -131,6 +131,15 @@ int delete_fdt_mem_rsv(void *fdt, unsigned long start, unsigned long size); + #ifdef CONFIG_PPC64 + struct kexec_buf; + ++int arch_kexec_kernel_image_probe(struct kimage *image, void *buf, unsigned long buf_len); ++#define arch_kexec_kernel_image_probe arch_kexec_kernel_image_probe ++ ++int arch_kimage_file_post_load_cleanup(struct kimage *image); ++#define arch_kimage_file_post_load_cleanup arch_kimage_file_post_load_cleanup ++ ++int arch_kexec_locate_mem_hole(struct kexec_buf *kbuf); ++#define arch_kexec_locate_mem_hole arch_kexec_locate_mem_hole ++ + int load_crashdump_segments_ppc64(struct kimage *image, + struct kexec_buf *kbuf); + int setup_purgatory_ppc64(struct kimage *image, const void *slave_code, +diff --git a/arch/s390/include/asm/kexec.h b/arch/s390/include/asm/kexec.h +index 63098df81c9f..407b649ca519 100644 +--- a/arch/s390/include/asm/kexec.h ++++ b/arch/s390/include/asm/kexec.h +@@ -92,5 +92,11 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi, + const Elf_Shdr *relsec, + const Elf_Shdr *symtab); + #define arch_kexec_apply_relocations_add arch_kexec_apply_relocations_add ++ ++int arch_kexec_kernel_image_probe(struct kimage *image, void *buf, unsigned long buf_len); ++#define arch_kexec_kernel_image_probe arch_kexec_kernel_image_probe ++ ++int arch_kimage_file_post_load_cleanup(struct kimage *image); ++#define arch_kimage_file_post_load_cleanup arch_kimage_file_post_load_cleanup + #endif + #endif /*_S390_KEXEC_H */ +diff --git a/arch/x86/include/asm/kexec.h b/arch/x86/include/asm/kexec.h +index e5fba0be9497..08b7a73083d4 100644 +--- a/arch/x86/include/asm/kexec.h ++++ b/arch/x86/include/asm/kexec.h +@@ -211,6 +211,12 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi, + const Elf_Shdr *relsec, + const Elf_Shdr *symtab); + #define arch_kexec_apply_relocations_add arch_kexec_apply_relocations_add ++ ++void *arch_kexec_kernel_image_load(struct kimage *image); ++#define arch_kexec_kernel_image_load arch_kexec_kernel_image_load ++ ++int arch_kimage_file_post_load_cleanup(struct kimage *image); ++#define arch_kimage_file_post_load_cleanup arch_kimage_file_post_load_cleanup + #endif + #endif + +diff --git a/include/linux/kexec.h b/include/linux/kexec.h +index d76967af6672..422eaa63a0a6 100644 +--- a/include/linux/kexec.h ++++ b/include/linux/kexec.h +@@ -182,21 +182,53 @@ int kexec_purgatory_get_set_symbol(struct kimage *image, const char *name, + void *buf, unsigned int size, + bool get_value); + void *kexec_purgatory_get_symbol_addr(struct kimage *image, const char *name); ++void *kexec_image_load_default(struct kimage *image); ++ ++#ifndef arch_kexec_kernel_image_probe ++static inline int ++arch_kexec_kernel_image_probe(struct kimage *image, void *buf, unsigned long buf_len) ++{ ++ return kexec_image_probe_default(image, buf, buf_len); ++} ++#endif ++ ++#ifndef arch_kimage_file_post_load_cleanup ++static inline int arch_kimage_file_post_load_cleanup(struct kimage *image) ++{ ++ return kexec_image_post_load_cleanup_default(image); ++} ++#endif ++ ++#ifndef arch_kexec_kernel_image_load ++static inline void *arch_kexec_kernel_image_load(struct kimage *image) ++{ ++ return kexec_image_load_default(image); ++} ++#endif + +-/* Architectures may override the below functions */ +-int arch_kexec_kernel_image_probe(struct kimage *image, void *buf, +- unsigned long buf_len); +-void *arch_kexec_kernel_image_load(struct kimage *image); +-int arch_kimage_file_post_load_cleanup(struct kimage *image); + #ifdef CONFIG_KEXEC_SIG + int arch_kexec_kernel_verify_sig(struct kimage *image, void *buf, + unsigned long buf_len); + #endif +-int arch_kexec_locate_mem_hole(struct kexec_buf *kbuf); + + extern int kexec_add_buffer(struct kexec_buf *kbuf); + int kexec_locate_mem_hole(struct kexec_buf *kbuf); + ++#ifndef arch_kexec_locate_mem_hole ++/** ++ * arch_kexec_locate_mem_hole - Find free memory to place the segments. ++ * @kbuf: Parameters for the memory search. ++ * ++ * On success, kbuf->mem will have the start address of the memory region found. ++ * ++ * Return: 0 on success, negative errno on error. ++ */ ++static inline int arch_kexec_locate_mem_hole(struct kexec_buf *kbuf) ++{ ++ return kexec_locate_mem_hole(kbuf); ++} ++#endif ++ + /* Alignment required for elf header segment */ + #define ELF_CORE_HEADER_ALIGN 4096 + +diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c +index 383fc13796b8..d6ecfc337744 100644 +--- a/kernel/kexec_file.c ++++ b/kernel/kexec_file.c +@@ -52,14 +52,7 @@ int kexec_image_probe_default(struct kimage *image, void *buf, + return ret; + } + +-/* Architectures can provide this probe function */ +-int __weak arch_kexec_kernel_image_probe(struct kimage *image, void *buf, +- unsigned long buf_len) +-{ +- return kexec_image_probe_default(image, buf, buf_len); +-} +- +-static void *kexec_image_load_default(struct kimage *image) ++void *kexec_image_load_default(struct kimage *image) + { + if (!image->fops || !image->fops->load) + return ERR_PTR(-ENOEXEC); +@@ -70,11 +63,6 @@ static void *kexec_image_load_default(struct kimage *image) + image->cmdline_buf_len); + } + +-void * __weak arch_kexec_kernel_image_load(struct kimage *image) +-{ +- return kexec_image_load_default(image); +-} +- + int kexec_image_post_load_cleanup_default(struct kimage *image) + { + if (!image->fops || !image->fops->cleanup) +@@ -83,11 +71,6 @@ int kexec_image_post_load_cleanup_default(struct kimage *image) + return image->fops->cleanup(image->image_loader_data); + } + +-int __weak arch_kimage_file_post_load_cleanup(struct kimage *image) +-{ +- return kexec_image_post_load_cleanup_default(image); +-} +- + #ifdef CONFIG_KEXEC_SIG + static int kexec_image_verify_sig_default(struct kimage *image, void *buf, + unsigned long buf_len) +@@ -100,8 +83,7 @@ static int kexec_image_verify_sig_default(struct kimage *image, void *buf, + return image->fops->verify_sig(buf, buf_len); + } + +-int __weak arch_kexec_kernel_verify_sig(struct kimage *image, void *buf, +- unsigned long buf_len) ++int arch_kexec_kernel_verify_sig(struct kimage *image, void *buf, unsigned long buf_len) + { + return kexec_image_verify_sig_default(image, buf, buf_len); + } +@@ -619,19 +601,6 @@ int kexec_locate_mem_hole(struct kexec_buf *kbuf) + return ret == 1 ? 0 : -EADDRNOTAVAIL; + } + +-/** +- * arch_kexec_locate_mem_hole - Find free memory to place the segments. +- * @kbuf: Parameters for the memory search. +- * +- * On success, kbuf->mem will have the start address of the memory region found. +- * +- * Return: 0 on success, negative errno on error. +- */ +-int __weak arch_kexec_locate_mem_hole(struct kexec_buf *kbuf) +-{ +- return kexec_locate_mem_hole(kbuf); +-} +- + /** + * kexec_add_buffer - place a buffer in a kexec segment + * @kbuf: Buffer contents and memory parameters. +-- +2.35.3 + diff --git a/patches.suse/lib-sg_pool-change-module_init-sg_pool_init-to-subsy.patch b/patches.suse/lib-sg_pool-change-module_init-sg_pool_init-to-subsy.patch new file mode 100644 index 0000000..f5cde71 --- /dev/null +++ b/patches.suse/lib-sg_pool-change-module_init-sg_pool_init-to-subsy.patch @@ -0,0 +1,75 @@ +From f7f04d198334d6f69c76c8f8675194551a3da574 Mon Sep 17 00:00:00 2001 +From: Masahiro Yamada +Date: Fri, 23 Sep 2022 20:38:35 +0900 +Subject: [PATCH] lib/sg_pool: change module_init(sg_pool_init) to subsys_initcall +Git-commit: f7f04d198334d6f69c76c8f8675194551a3da574 +Patch-mainline: v6.1-rc1 +References: git-fixes + +sg_alloc_table_chained() is called by several drivers, but if it is +called before sg_pool_init(), it results in a NULL pointer dereference +in sg_pool_alloc(). + +Since commit 9b1d6c895002 ("lib: scatterlist: move SG pool code from +SCSI driver to lib/sg_pool.c"), we rely on module_init(sg_pool_init) +is invoked before other module_init calls but this assumption is +fragile. + +I slightly changed the link order while refactoring Kbuild, then +uncovered this issue. I should keep the current link order, but +depending on a specific call order among module_init is so fragile. + +We usually define the init order by specifying *_initcall correctly, +or delay the driver probing by returning -EPROBE_DEFER. + +Change module_initcall() to subsys_initcall(), and also delete the +pointless module_exit() because lib/sg_pool.c is always compiled as +built-in. (CONFIG_SG_POOL is bool) + +Link: https://lore.kernel.org/all/20220921043946.GA1355561@roeck-us.net/ +Link: https://lore.kernel.org/all/8e70837d-d859-dfb2-bf7f-83f8b31467bc@samsung.com/ +Fixes: 9b1d6c895002 ("lib: scatterlist: move SG pool code from SCSI driver to lib/sg_pool.c") +Reported-by: Guenter Roeck +Reported-by: Marek Szyprowski +Signed-off-by: Masahiro Yamada +Reviewed-by: Robin Murphy +Tested-by: Marek Szyprowski +Signed-off-by: Christoph Hellwig +Acked-by: Takashi Iwai + +--- + lib/sg_pool.c | 16 ++-------------- + 1 file changed, 2 insertions(+), 14 deletions(-) + +diff --git a/lib/sg_pool.c b/lib/sg_pool.c +index a0b1a52cd6f7..9bfe60ca3f37 100644 +--- a/lib/sg_pool.c ++++ b/lib/sg_pool.c +@@ -1,5 +1,5 @@ + // SPDX-License-Identifier: GPL-2.0-only +-#include ++#include + #include + #include + #include +@@ -177,16 +177,4 @@ static __init int sg_pool_init(void) + return -ENOMEM; + } + +-static __exit void sg_pool_exit(void) +-{ +- int i; +- +- for (i = 0; i < SG_MEMPOOL_NR; i++) { +- struct sg_pool *sgp = sg_pools + i; +- mempool_destroy(sgp->pool); +- kmem_cache_destroy(sgp->slab); +- } +-} +- +-module_init(sg_pool_init); +-module_exit(sg_pool_exit); ++subsys_initcall(sg_pool_init); +-- +2.35.3 + diff --git a/patches.suse/libata-add-ATA_HORKAGE_NOLPM-for-Pioneer-BDR-207M-an.patch b/patches.suse/libata-add-ATA_HORKAGE_NOLPM-for-Pioneer-BDR-207M-an.patch new file mode 100644 index 0000000..cf16cc2 --- /dev/null +++ b/patches.suse/libata-add-ATA_HORKAGE_NOLPM-for-Pioneer-BDR-207M-an.patch @@ -0,0 +1,63 @@ +From ea08aec7e77bfd6599489ec430f9f859ab84575a Mon Sep 17 00:00:00 2001 +From: Niklas Cassel +Date: Mon, 26 Sep 2022 18:38:09 +0000 +Subject: [PATCH] libata: add ATA_HORKAGE_NOLPM for Pioneer BDR-207M and BDR-205 +Git-commit: ea08aec7e77bfd6599489ec430f9f859ab84575a +Patch-mainline: v6.0 +References: git-fixes + +Commit 1527f69204fe ("ata: ahci: Add Green Sardine vendor ID as +board_ahci_mobile") added an explicit entry for AMD Green Sardine +AHCI controller using the board_ahci_mobile configuration (this +configuration has later been renamed to board_ahci_low_power). + +The board_ahci_low_power configuration enables support for low power +modes. + +This explicit entry takes precedence over the generic AHCI controller +entry, which does not enable support for low power modes. + +Therefore, when commit 1527f69204fe ("ata: ahci: Add Green Sardine +vendor ID as board_ahci_mobile") was backported to stable kernels, +it make some Pioneer optical drives, which was working perfectly fine +before the commit was backported, stop working. + +The real problem is that the Pioneer optical drives do not handle low +power modes correctly. If these optical drives would have been tested +on another AHCI controller using the board_ahci_low_power configuration, +this issue would have been detected earlier. + +Unfortunately, the board_ahci_low_power configuration is only used in +less than 15% of the total AHCI controller entries, so many devices +have never been tested with an AHCI controller with low power modes. + +Fixes: 1527f69204fe ("ata: ahci: Add Green Sardine vendor ID as board_ahci_mobile") +Cc: stable@vger.kernel.org +Reported-by: Jaap Berkhout +Signed-off-by: Niklas Cassel +Reviewed-by: Mario Limonciello +Signed-off-by: Damien Le Moal +Acked-by: Takashi Iwai + +--- + drivers/ata/libata-core.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c +index 826d41f341e4..c9a9aa607b62 100644 +--- a/drivers/ata/libata-core.c ++++ b/drivers/ata/libata-core.c +@@ -3988,6 +3988,10 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { + { "PIONEER DVD-RW DVR-212D", NULL, ATA_HORKAGE_NOSETXFER }, + { "PIONEER DVD-RW DVR-216D", NULL, ATA_HORKAGE_NOSETXFER }, + ++ /* These specific Pioneer models have LPM issues */ ++ { "PIONEER BD-RW BDR-207M", NULL, ATA_HORKAGE_NOLPM }, ++ { "PIONEER BD-RW BDR-205", NULL, ATA_HORKAGE_NOLPM }, ++ + /* Crucial BX100 SSD 500GB has broken LPM support */ + { "CT500BX100SSD1", NULL, ATA_HORKAGE_NOLPM }, + +-- +2.35.3 + diff --git a/patches.suse/lockd-detect-and-reject-lock-arguments-that-overflow.patch b/patches.suse/lockd-detect-and-reject-lock-arguments-that-overflow.patch new file mode 100644 index 0000000..5e6ddec --- /dev/null +++ b/patches.suse/lockd-detect-and-reject-lock-arguments-that-overflow.patch @@ -0,0 +1,117 @@ +From: Jeff Layton +Date: Mon, 1 Aug 2022 15:57:26 -0400 +Subject: [PATCH] lockd: detect and reject lock arguments that overflow +Git-commit: 6930bcbfb6ceda63e298c6af6d733ecdf6bd4cde +Patch-mainline: v6.0 +References: git-fixes + +lockd doesn't currently vet the start and length in nlm4 requests like +it should, and can end up generating lock requests with arguments that +overflow when passed to the filesystem. + +The NLM4 protocol uses unsigned 64-bit arguments for both start and +length, whereas struct file_lock tracks the start and end as loff_t +values. By the time we get around to calling nlm4svc_retrieve_args, +we've lost the information that would allow us to determine if there was +an overflow. + +Start tracking the actual start and len for NLM4 requests in the +nlm_lock. In nlm4svc_retrieve_args, vet these values to ensure they +won't cause an overflow, and return NLM4_FBIG if they do. + +Link: https://bugzilla.linux-nfs.org/show_bug.cgi?id=392 +Reported-by: Jan Kasiak +Signed-off-by: Jeff Layton +Signed-off-by: Chuck Lever +Cc: # 5.14+ +Acked-by: NeilBrown + +--- + fs/lockd/svc4proc.c | 8 ++++++++ + fs/lockd/xdr4.c | 19 ++----------------- + include/linux/lockd/xdr.h | 2 ++ + 3 files changed, 12 insertions(+), 17 deletions(-) + +--- a/fs/lockd/svc4proc.c ++++ b/fs/lockd/svc4proc.c +@@ -32,6 +32,10 @@ nlm4svc_retrieve_args(struct svc_rqst *r + if (!nlmsvc_ops) + return nlm_lck_denied_nolocks; + ++ if (lock->lock_start > OFFSET_MAX || ++ (lock->lock_len && ((lock->lock_len - 1) > (OFFSET_MAX - lock->lock_start)))) ++ return nlm4_fbig; ++ + /* Obtain host handle */ + if (!(host = nlmsvc_lookup_host(rqstp, lock->caller, lock->len)) + || (argp->monitor && nsm_monitor(host) < 0)) +@@ -47,6 +51,10 @@ nlm4svc_retrieve_args(struct svc_rqst *r + /* Set up the missing parts of the file_lock structure */ + lock->fl.fl_file = file->f_file; + lock->fl.fl_pid = current->tgid; ++ lock->fl.fl_start = (loff_t)lock->lock_start; ++ lock->fl.fl_end = lock->lock_len ? ++ (loff_t)(lock->lock_start + lock->lock_len - 1) : ++ OFFSET_MAX; + lock->fl.fl_lmops = &nlmsvc_lock_operations; + nlmsvc_locks_init_private(&lock->fl, host, (pid_t)lock->svid); + if (!lock->fl.fl_owner) { +--- a/fs/lockd/xdr4.c ++++ b/fs/lockd/xdr4.c +@@ -20,13 +20,6 @@ + + #include "svcxdr.h" + +-static inline loff_t +-s64_to_loff_t(__s64 offset) +-{ +- return (loff_t)offset; +-} +- +- + static inline s64 + loff_t_to_s64(loff_t offset) + { +@@ -70,8 +63,6 @@ static bool + svcxdr_decode_lock(struct xdr_stream *xdr, struct nlm_lock *lock) + { + struct file_lock *fl = &lock->fl; +- u64 len, start; +- s64 end; + + if (!svcxdr_decode_string(xdr, &lock->caller, &lock->len)) + return false; +@@ -81,20 +72,14 @@ svcxdr_decode_lock(struct xdr_stream *xd + return false; + if (xdr_stream_decode_u32(xdr, &lock->svid) < 0) + return false; +- if (xdr_stream_decode_u64(xdr, &start) < 0) ++ if (xdr_stream_decode_u64(xdr, &lock->lock_start) < 0) + return false; +- if (xdr_stream_decode_u64(xdr, &len) < 0) ++ if (xdr_stream_decode_u64(xdr, &lock->lock_len) < 0) + return false; + + locks_init_lock(fl); + fl->fl_flags = FL_POSIX; + fl->fl_type = F_RDLCK; +- end = start + len - 1; +- fl->fl_start = s64_to_loff_t(start); +- if (len == 0 || end < 0) +- fl->fl_end = OFFSET_MAX; +- else +- fl->fl_end = s64_to_loff_t(end); + + return true; + } +--- a/include/linux/lockd/xdr.h ++++ b/include/linux/lockd/xdr.h +@@ -41,6 +41,8 @@ struct nlm_lock { + struct nfs_fh fh; + struct xdr_netobj oh; + u32 svid; ++ u64 lock_start; ++ u64 lock_len; + struct file_lock fl; + }; + diff --git a/patches.suse/lpfc-decouple-port_template-and-vport_template.patch b/patches.suse/lpfc-decouple-port_template-and-vport_template.patch deleted file mode 100644 index b11a4f1..0000000 --- a/patches.suse/lpfc-decouple-port_template-and-vport_template.patch +++ /dev/null @@ -1,153 +0,0 @@ -From: Daniel Wagner -Date: Fri, 21 May 2021 14:05:13 +0200 -Subject: lpfc: Decouple port_template and vport_template -Patch-mainline: Submitted, Broadcom will pick the patch up eventually -References: bsc#1185032 - -The problem here is that the lpfc_hba structure has been freed but the -Scsi_Host's hostt pointer is still pointing to the (v) port template -area inside the freed hba structure - through which the module is -accessed. - -Basically we need to ensure that the access to the module structure -(via the host template or otherwise) stays valid even after the HBA -structure is freed (or delay that free). - -Patch provided by IBM. - -Signed-off-by: Daniel Wagner ---- - drivers/scsi/lpfc/lpfc.h | 5 ----- - drivers/scsi/lpfc/lpfc_crtn.h | 1 + - drivers/scsi/lpfc/lpfc_init.c | 22 +++++++--------------- - drivers/scsi/lpfc/lpfc_scsi.c | 27 +++++++++++++++++++++++++++ - 4 files changed, 35 insertions(+), 20 deletions(-) - -diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h -index f8de0d10620b..f8622cd5bb4f 100644 ---- a/drivers/scsi/lpfc/lpfc.h -+++ b/drivers/scsi/lpfc/lpfc.h -@@ -1253,11 +1253,6 @@ struct lpfc_hba { - #define LPFC_POLL_SLOWPATH 1 /* called from slowpath */ - - char os_host_name[MAXHOSTNAMELEN]; -- -- /* SCSI host template information - for physical port */ -- struct scsi_host_template port_template; -- /* SCSI host template information - for all vports */ -- struct scsi_host_template vport_template; - atomic_t dbg_log_idx; - atomic_t dbg_log_cnt; - atomic_t dbg_log_dmping; -diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h -index eb4cf36229d5..672f4e87a20b 100644 ---- a/drivers/scsi/lpfc/lpfc_crtn.h -+++ b/drivers/scsi/lpfc/lpfc_crtn.h -@@ -411,6 +411,7 @@ extern struct device_attribute *lpfc_hba_attrs[]; - extern struct device_attribute *lpfc_vport_attrs[]; - extern struct scsi_host_template lpfc_template; - extern struct scsi_host_template lpfc_template_nvme; -+extern struct scsi_host_template lpfc_vport_template; - extern struct fc_function_template lpfc_transport_functions; - extern struct fc_function_template lpfc_vport_transport_functions; - -diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c -index 5ea43c527e08..f6d10ccf1d26 100644 ---- a/drivers/scsi/lpfc/lpfc_init.c -+++ b/drivers/scsi/lpfc/lpfc_init.c -@@ -4339,7 +4339,7 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev) - { - struct lpfc_vport *vport; - struct Scsi_Host *shost = NULL; -- struct scsi_host_template *template; -+ struct scsi_host_template *template, *vport_template; - int error = 0; - int i; - uint64_t wwn; -@@ -4371,42 +4371,34 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev) - - /* Seed template for SCSI host registration */ - if (dev == &phba->pcidev->dev) { -- template = &phba->port_template; -- - if (phba->cfg_enable_fc4_type & LPFC_ENABLE_FCP) { - /* Seed physical port template */ -- memcpy(template, &lpfc_template, sizeof(*template)); -+ template = &lpfc_template; - - if (use_no_reset_hba) - /* template is for a no reset SCSI Host */ - template->eh_host_reset_handler = NULL; - - /* Template for all vports this physical port creates */ -- memcpy(&phba->vport_template, &lpfc_template, -- sizeof(*template)); -- phba->vport_template.shost_attrs = lpfc_vport_attrs; -- phba->vport_template.eh_bus_reset_handler = NULL; -- phba->vport_template.eh_host_reset_handler = NULL; -- phba->vport_template.vendor_id = 0; -+ vport_template = &lpfc_vport_template; - - /* Initialize the host templates with updated value */ - if (phba->sli_rev == LPFC_SLI_REV4) { - template->sg_tablesize = phba->cfg_scsi_seg_cnt; -- phba->vport_template.sg_tablesize = -+ vport_template->sg_tablesize = - phba->cfg_scsi_seg_cnt; - } else { - template->sg_tablesize = phba->cfg_sg_seg_cnt; -- phba->vport_template.sg_tablesize = -+ vport_template->sg_tablesize = - phba->cfg_sg_seg_cnt; - } - - } else { - /* NVMET is for physical port only */ -- memcpy(template, &lpfc_template_nvme, -- sizeof(*template)); -+ template = &lpfc_template_nvme; - } - } else { -- template = &phba->vport_template; -+ template = &lpfc_vport_template; - } - - shost = scsi_host_alloc(template, sizeof(struct lpfc_vport)); -diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c -index ba8908e5d4f1..2ae13df2b218 100644 ---- a/drivers/scsi/lpfc/lpfc_scsi.c -+++ b/drivers/scsi/lpfc/lpfc_scsi.c -@@ -6740,3 +6740,30 @@ struct scsi_host_template lpfc_template = { - .change_queue_depth = scsi_change_queue_depth, - .track_queue_depth = 1, - }; -+ -+/* Template for all vports this physical port creates */ -+struct scsi_host_template lpfc_vport_template = { -+ .module = THIS_MODULE, -+ .name = LPFC_DRIVER_NAME, -+ .proc_name = LPFC_DRIVER_NAME, -+ .info = lpfc_info, -+ .queuecommand = lpfc_queuecommand, -+ .eh_timed_out = fc_eh_timed_out, -+ .eh_abort_handler = lpfc_abort_handler, -+ .eh_device_reset_handler = lpfc_device_reset_handler, -+ .eh_target_reset_handler = lpfc_target_reset_handler, -+ .eh_bus_reset_handler = NULL, -+ .eh_host_reset_handler = NULL, -+ .slave_alloc = lpfc_slave_alloc, -+ .slave_configure = lpfc_slave_configure, -+ .slave_destroy = lpfc_slave_destroy, -+ .scan_finished = lpfc_scan_finished, -+ .this_id = -1, -+ .sg_tablesize = LPFC_DEFAULT_SG_SEG_CNT, -+ .cmd_per_lun = LPFC_CMD_PER_LUN, -+ .shost_attrs = lpfc_vport_attrs, -+ .max_sectors = 0xFFFFFFFF, -+ .vendor_id = 0, -+ .change_queue_depth = scsi_change_queue_depth, -+ .track_queue_depth = 1, -+}; --- -2.29.2 - diff --git a/patches.suse/mISDN-fix-use-after-free-bugs-in-l1oip-timer-handler.patch b/patches.suse/mISDN-fix-use-after-free-bugs-in-l1oip-timer-handler.patch new file mode 100644 index 0000000..7a789a1 --- /dev/null +++ b/patches.suse/mISDN-fix-use-after-free-bugs-in-l1oip-timer-handler.patch @@ -0,0 +1,97 @@ +From 2568a7e0832ee30b0a351016d03062ab4e0e0a3f Mon Sep 17 00:00:00 2001 +From: Duoming Zhou +Date: Wed, 28 Sep 2022 21:39:38 +0800 +Subject: [PATCH] mISDN: fix use-after-free bugs in l1oip timer handlers +Git-commit: 2568a7e0832ee30b0a351016d03062ab4e0e0a3f +Patch-mainline: v6.1-rc1 +References: git-fixes + +The l1oip_cleanup() traverses the l1oip_ilist and calls +release_card() to cleanup module and stack. However, +release_card() calls del_timer() to delete the timers +such as keep_tl and timeout_tl. If the timer handler is +running, the del_timer() will not stop it and result in +UAF bugs. One of the processes is shown below: + + (cleanup routine) | (timer handler) +release_card() | l1oip_timeout() + ... | + del_timer() | ... + ... | + kfree(hc) //FREE | + | hc->timeout_on = 0 //USE + +Fix by calling del_timer_sync() in release_card(), which +makes sure the timer handlers have finished before the +resources, such as l1oip and so on, have been deallocated. + +What's more, the hc->workq and hc->socket_thread can kick +those timers right back in. We add a bool flag to show +if card is released. Then, check this flag in hc->workq +and hc->socket_thread. + +Fixes: 3712b42d4b1b ("Add layer1 over IP support") +Signed-off-by: Duoming Zhou +Reviewed-by: Leon Romanovsky +Signed-off-by: David S. Miller +Acked-by: Takashi Iwai + +--- + drivers/isdn/mISDN/l1oip.h | 1 + + drivers/isdn/mISDN/l1oip_core.c | 13 +++++++------ + 2 files changed, 8 insertions(+), 6 deletions(-) + +diff --git a/drivers/isdn/mISDN/l1oip.h b/drivers/isdn/mISDN/l1oip.h +index 7ea10db20e3a..48133d022812 100644 +--- a/drivers/isdn/mISDN/l1oip.h ++++ b/drivers/isdn/mISDN/l1oip.h +@@ -59,6 +59,7 @@ struct l1oip { + int bundle; /* bundle channels in one frm */ + int codec; /* codec to use for transmis. */ + int limit; /* limit number of bchannels */ ++ bool shutdown; /* if card is released */ + + /* timer */ + struct timer_list keep_tl; +diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c +index 2c40412466e6..a77195e378b7 100644 +--- a/drivers/isdn/mISDN/l1oip_core.c ++++ b/drivers/isdn/mISDN/l1oip_core.c +@@ -275,7 +275,7 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask, + p = frame; + + /* restart timer */ +- if (time_before(hc->keep_tl.expires, jiffies + 5 * HZ)) ++ if (time_before(hc->keep_tl.expires, jiffies + 5 * HZ) && !hc->shutdown) + mod_timer(&hc->keep_tl, jiffies + L1OIP_KEEPALIVE * HZ); + else + hc->keep_tl.expires = jiffies + L1OIP_KEEPALIVE * HZ; +@@ -601,7 +601,9 @@ l1oip_socket_parse(struct l1oip *hc, struct sockaddr_in *sin, u8 *buf, int len) + goto multiframe; + + /* restart timer */ +- if (time_before(hc->timeout_tl.expires, jiffies + 5 * HZ) || !hc->timeout_on) { ++ if ((time_before(hc->timeout_tl.expires, jiffies + 5 * HZ) || ++ !hc->timeout_on) && ++ !hc->shutdown) { + hc->timeout_on = 1; + mod_timer(&hc->timeout_tl, jiffies + L1OIP_TIMEOUT * HZ); + } else /* only adjust timer */ +@@ -1232,11 +1234,10 @@ release_card(struct l1oip *hc) + { + int ch; + +- if (timer_pending(&hc->keep_tl)) +- del_timer(&hc->keep_tl); ++ hc->shutdown = true; + +- if (timer_pending(&hc->timeout_tl)) +- del_timer(&hc->timeout_tl); ++ del_timer_sync(&hc->keep_tl); ++ del_timer_sync(&hc->timeout_tl); + + cancel_work_sync(&hc->workq); + +-- +2.35.3 + diff --git a/patches.suse/mISDN-hfcpci-Fix-use-after-free-bug-in-hfcpci_softir.patch b/patches.suse/mISDN-hfcpci-Fix-use-after-free-bug-in-hfcpci_softir.patch new file mode 100644 index 0000000..1d6cbe6 --- /dev/null +++ b/patches.suse/mISDN-hfcpci-Fix-use-after-free-bug-in-hfcpci_softir.patch @@ -0,0 +1,59 @@ +From 175302f6b79ebbb207c2d58d6d3e679465de23b0 Mon Sep 17 00:00:00 2001 +From: Duoming Zhou +Date: Sun, 9 Oct 2022 14:37:31 +0800 +Subject: [PATCH] mISDN: hfcpci: Fix use-after-free bug in hfcpci_softirq +Git-commit: 175302f6b79ebbb207c2d58d6d3e679465de23b0 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The function hfcpci_softirq() is a timer handler. If it +is running, the timer_pending() will return 0 and the +del_timer_sync() in HFC_cleanup() will not be executed. +As a result, the use-after-free bug will happen. The +process is shown below: + + (cleanup routine) | (timer handler) +HFC_cleanup() | hfcpci_softirq() + if (timer_pending(&hfc_tl)) | + del_timer_sync() | + ... | ... + pci_unregister_driver(hc) | + driver_unregister | driver_for_each_device + bus_remove_driver | _hfcpci_softirq + driver_detach | ... + put_device(dev) //[1]FREE | + | dev_get_drvdata(dev) //[2]USE + +The device is deallocated is position [1] and used in +position [2]. + +Fix by removing the "timer_pending" check in HFC_cleanup(), +which makes sure that the hfcpci_softirq() have finished +before the resource is deallocated. + +Fixes: 009fc857c5f6 ("mISDN: fix possible use-after-free in HFC_cleanup()") +Signed-off-by: Duoming Zhou +Signed-off-by: David S. Miller +Acked-by: Takashi Iwai + +--- + drivers/isdn/hardware/mISDN/hfcpci.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c +index af17459c1a5c..e964a8dd8512 100644 +--- a/drivers/isdn/hardware/mISDN/hfcpci.c ++++ b/drivers/isdn/hardware/mISDN/hfcpci.c +@@ -2345,8 +2345,7 @@ HFC_init(void) + static void __exit + HFC_cleanup(void) + { +- if (timer_pending(&hfc_tl)) +- del_timer_sync(&hfc_tl); ++ del_timer_sync(&hfc_tl); + + pci_unregister_driver(&hfc_driver); + } +-- +2.35.3 + diff --git a/patches.suse/mac80211-always-allocate-struct-ieee802_11_elems.patch b/patches.suse/mac80211-always-allocate-struct-ieee802_11_elems.patch new file mode 100644 index 0000000..483daa3 --- /dev/null +++ b/patches.suse/mac80211-always-allocate-struct-ieee802_11_elems.patch @@ -0,0 +1,1161 @@ +From 5d24828d05f37ad770599de00b53d5386e35aa61 Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Mon, 20 Sep 2021 15:40:10 +0200 +Subject: [PATCH] mac80211: always allocate struct ieee802_11_elems +Git-commit: 5d24828d05f37ad770599de00b53d5386e35aa61 +Patch-mainline: v5.16-rc1 +References: CVE-2022-42719 bsc#1204051 + +As the 802.11 spec evolves, we need to parse more and more +elements. This is causing the struct to grow, and we can no +longer get away with putting it on the stack. + +Change the API to always dynamically allocate and return an +allocated pointer that must be kfree()d later. + +As an alternative, I contemplated a scheme whereby we'd say +in the code which elements we needed, e.g. + + DECLARE_ELEMENT_PARSER(elems, + SUPPORTED_CHANNELS, + CHANNEL_SWITCH, + EXT(KEY_DELIVERY)); + + ieee802_11_parse_elems(..., &elems, ...); + +and while I think this is possible and will save us a lot +since most individual places only care about a small subset +of the elements, it ended up being a bit more work since a +lot of places do the parsing and then pass the struct to +other functions, sometimes with multiple levels. + +Link: https://lore.kernel.org/r/20210920154009.26caff6b5998.I05ae58768e990e611aee8eca8abefd9d7bc15e05@changeid +Signed-off-by: Johannes Berg +Acked-by: Takashi Iwai + +--- + net/mac80211/agg-rx.c | 11 +- + net/mac80211/ibss.c | 27 ++++-- + net/mac80211/ieee80211_i.h | 22 ++--- + net/mac80211/mesh.c | 86 ++++++++++++--------- + net/mac80211/mesh_hwmp.c | 44 ++++++----- + net/mac80211/mesh_plink.c | 11 +- + net/mac80211/mlme.c | 176 +++++++++++++++++++++++++-------------------- + net/mac80211/scan.c | 16 ++-- + net/mac80211/tdls.c | 63 +++++++++------- + net/mac80211/util.c | 20 +++-- + 10 files changed, 274 insertions(+), 202 deletions(-) + +--- a/net/mac80211/agg-rx.c ++++ b/net/mac80211/agg-rx.c +@@ -478,7 +478,7 @@ void ieee80211_process_addba_request(str + size_t len) + { + u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num; +- struct ieee802_11_elems elems = { }; ++ struct ieee802_11_elems *elems = NULL; + u8 dialog_token; + int ies_len; + +@@ -496,16 +496,17 @@ void ieee80211_process_addba_request(str + ies_len = len - offsetof(struct ieee80211_mgmt, + u.action.u.addba_req.variable); + if (ies_len) { +- ieee802_11_parse_elems(mgmt->u.action.u.addba_req.variable, +- ies_len, true, &elems, mgmt->bssid, NULL); +- if (elems.parse_error) ++ elems = ieee802_11_parse_elems(mgmt->u.action.u.addba_req.variable, ++ ies_len, true, mgmt->bssid, NULL); ++ if (!elems || elems->parse_error) + return; + } + + __ieee80211_start_rx_ba_session(sta, dialog_token, timeout, + start_seq_num, ba_policy, tid, + buf_size, true, false, +- elems.addba_ext_ie); ++ elems ? elems->addba_ext_ie : NULL); ++ kfree(elems); + } + + void ieee80211_manage_rx_ba_offl(struct ieee80211_vif *vif, +--- a/net/mac80211/ibss.c ++++ b/net/mac80211/ibss.c +@@ -9,7 +9,7 @@ + * Copyright 2009, Johannes Berg + * Copyright 2013-2014 Intel Mobile Communications GmbH + * Copyright(c) 2016 Intel Deutschland GmbH +- * Copyright(c) 2018-2020 Intel Corporation ++ * Copyright(c) 2018-2021 Intel Corporation + */ + + #include +@@ -1600,7 +1600,7 @@ void ieee80211_rx_mgmt_probe_beacon(stru + struct ieee80211_rx_status *rx_status) + { + size_t baselen; +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems; + + BUILD_BUG_ON(offsetof(typeof(mgmt->u.probe_resp), variable) != + offsetof(typeof(mgmt->u.beacon), variable)); +@@ -1613,10 +1613,14 @@ void ieee80211_rx_mgmt_probe_beacon(stru + if (baselen > len) + return; + +- ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, +- false, &elems, mgmt->bssid, NULL); +- +- ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems); ++ elems = ieee802_11_parse_elems(mgmt->u.probe_resp.variable, ++ len - baselen, false, ++ mgmt->bssid, NULL); ++ ++ if (elems) { ++ ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, elems); ++ kfree(elems); ++ } + } + + void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, +@@ -1625,7 +1629,7 @@ void ieee80211_ibss_rx_queued_mgmt(struc + struct ieee80211_rx_status *rx_status; + struct ieee80211_mgmt *mgmt; + u16 fc; +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems; + int ies_len; + + rx_status = IEEE80211_SKB_RXCB(skb); +@@ -1662,15 +1666,16 @@ void ieee80211_ibss_rx_queued_mgmt(struc + if (ies_len < 0) + break; + +- ieee802_11_parse_elems( ++ elems = ieee802_11_parse_elems( + mgmt->u.action.u.chan_switch.variable, +- ies_len, true, &elems, mgmt->bssid, NULL); ++ ies_len, true, mgmt->bssid, NULL); + +- if (elems.parse_error) ++ if (!elems || elems->parse_error) + break; + + ieee80211_rx_mgmt_spectrum_mgmt(sdata, mgmt, skb->len, +- rx_status, &elems); ++ rx_status, elems); ++ kfree(elems); + break; + } + } +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -2197,18 +2197,18 @@ static inline void ieee80211_tx_skb(stru + ieee80211_tx_skb_tid(sdata, skb, 7); + } + +-void ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, +- struct ieee802_11_elems *elems, +- u64 filter, u32 crc, u8 *transmitter_bssid, +- u8 *bss_bssid); +-static inline void ieee802_11_parse_elems(const u8 *start, size_t len, +- bool action, +- struct ieee802_11_elems *elems, +- u8 *transmitter_bssid, +- u8 *bss_bssid) ++struct ieee802_11_elems *ieee802_11_parse_elems_crc(const u8 *start, size_t len, ++ bool action, ++ u64 filter, u32 crc, ++ const u8 *transmitter_bssid, ++ const u8 *bss_bssid); ++static inline struct ieee802_11_elems * ++ieee802_11_parse_elems(const u8 *start, size_t len, bool action, ++ const u8 *transmitter_bssid, ++ const u8 *bss_bssid) + { +- ieee802_11_parse_elems_crc(start, len, action, elems, 0, 0, +- transmitter_bssid, bss_bssid); ++ return ieee802_11_parse_elems_crc(start, len, action, 0, 0, ++ transmitter_bssid, bss_bssid); + } + + +--- a/net/mac80211/mesh.c ++++ b/net/mac80211/mesh.c +@@ -1247,7 +1247,7 @@ ieee80211_mesh_rx_probe_req(struct ieee8 + struct sk_buff *presp; + struct beacon_data *bcn; + struct ieee80211_mgmt *hdr; +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems; + size_t baselen; + u8 *pos; + +@@ -1256,22 +1256,24 @@ ieee80211_mesh_rx_probe_req(struct ieee8 + if (baselen > len) + return; + +- ieee802_11_parse_elems(pos, len - baselen, false, &elems, mgmt->bssid, +- NULL); +- +- if (!elems.mesh_id) ++ elems = ieee802_11_parse_elems(pos, len - baselen, false, mgmt->bssid, ++ NULL); ++ if (!elems) + return; + ++ if (!elems->mesh_id) ++ goto free; ++ + /* 802.11-2012 10.1.4.3.2 */ + if ((!ether_addr_equal(mgmt->da, sdata->vif.addr) && + !is_broadcast_ether_addr(mgmt->da)) || +- elems.ssid_len != 0) +- return; ++ elems->ssid_len != 0) ++ goto free; + +- if (elems.mesh_id_len != 0 && +- (elems.mesh_id_len != ifmsh->mesh_id_len || +- memcmp(elems.mesh_id, ifmsh->mesh_id, ifmsh->mesh_id_len))) +- return; ++ if (elems->mesh_id_len != 0 && ++ (elems->mesh_id_len != ifmsh->mesh_id_len || ++ memcmp(elems->mesh_id, ifmsh->mesh_id, ifmsh->mesh_id_len))) ++ goto free; + + rcu_read_lock(); + bcn = rcu_dereference(ifmsh->beacon); +@@ -1295,6 +1297,8 @@ ieee80211_mesh_rx_probe_req(struct ieee8 + ieee80211_tx_skb(sdata, presp); + out: + rcu_read_unlock(); ++free: ++ kfree(elems); + } + + static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, +@@ -1305,7 +1309,7 @@ static void ieee80211_mesh_rx_bcn_presp( + { + struct ieee80211_local *local = sdata->local; + struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems; + struct ieee80211_channel *channel; + size_t baselen; + int freq; +@@ -1320,42 +1324,48 @@ static void ieee80211_mesh_rx_bcn_presp( + if (baselen > len) + return; + +- ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, +- false, &elems, mgmt->bssid, NULL); ++ elems = ieee802_11_parse_elems(mgmt->u.probe_resp.variable, ++ len - baselen, ++ false, mgmt->bssid, NULL); ++ if (!elems) ++ return; + + /* ignore non-mesh or secure / unsecure mismatch */ +- if ((!elems.mesh_id || !elems.mesh_config) || +- (elems.rsn && sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) || +- (!elems.rsn && sdata->u.mesh.security != IEEE80211_MESH_SEC_NONE)) +- return; ++ if ((!elems->mesh_id || !elems->mesh_config) || ++ (elems->rsn && sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) || ++ (!elems->rsn && sdata->u.mesh.security != IEEE80211_MESH_SEC_NONE)) ++ goto free; + +- if (elems.ds_params) +- freq = ieee80211_channel_to_frequency(elems.ds_params[0], band); ++ if (elems->ds_params) ++ freq = ieee80211_channel_to_frequency(elems->ds_params[0], band); + else + freq = rx_status->freq; + + channel = ieee80211_get_channel(local->hw.wiphy, freq); + + if (!channel || channel->flags & IEEE80211_CHAN_DISABLED) +- return; ++ goto free; + +- if (mesh_matches_local(sdata, &elems)) { ++ if (mesh_matches_local(sdata, elems)) { + mpl_dbg(sdata, "rssi_threshold=%d,rx_status->signal=%d\n", + sdata->u.mesh.mshcfg.rssi_threshold, rx_status->signal); + if (!sdata->u.mesh.user_mpm || + sdata->u.mesh.mshcfg.rssi_threshold == 0 || + sdata->u.mesh.mshcfg.rssi_threshold < rx_status->signal) +- mesh_neighbour_update(sdata, mgmt->sa, &elems, ++ mesh_neighbour_update(sdata, mgmt->sa, elems, + rx_status); + + if (ifmsh->csa_role != IEEE80211_MESH_CSA_ROLE_INIT && + !sdata->vif.csa_active) +- ieee80211_mesh_process_chnswitch(sdata, &elems, true); ++ ieee80211_mesh_process_chnswitch(sdata, elems, true); + } + + if (ifmsh->sync_ops) + ifmsh->sync_ops->rx_bcn_presp(sdata, +- stype, mgmt, &elems, rx_status); ++ stype, mgmt, elems, rx_status); ++ ++free: ++ kfree(elems); + } + + int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata) +@@ -1447,7 +1457,7 @@ static void mesh_rx_csa_frame(struct iee + struct ieee80211_mgmt *mgmt, size_t len) + { + struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems; + u16 pre_value; + bool fwd_csa = true; + size_t baselen; +@@ -1460,33 +1470,37 @@ static void mesh_rx_csa_frame(struct iee + pos = mgmt->u.action.u.chan_switch.variable; + baselen = offsetof(struct ieee80211_mgmt, + u.action.u.chan_switch.variable); +- ieee802_11_parse_elems(pos, len - baselen, true, &elems, +- mgmt->bssid, NULL); +- +- if (!mesh_matches_local(sdata, &elems)) ++ elems = ieee802_11_parse_elems(pos, len - baselen, true, ++ mgmt->bssid, NULL); ++ if (!elems) + return; + +- ifmsh->chsw_ttl = elems.mesh_chansw_params_ie->mesh_ttl; ++ if (!mesh_matches_local(sdata, elems)) ++ goto free; ++ ++ ifmsh->chsw_ttl = elems->mesh_chansw_params_ie->mesh_ttl; + if (!--ifmsh->chsw_ttl) + fwd_csa = false; + +- pre_value = le16_to_cpu(elems.mesh_chansw_params_ie->mesh_pre_value); ++ pre_value = le16_to_cpu(elems->mesh_chansw_params_ie->mesh_pre_value); + if (ifmsh->pre_value >= pre_value) +- return; ++ goto free; + + ifmsh->pre_value = pre_value; + + if (!sdata->vif.csa_active && +- !ieee80211_mesh_process_chnswitch(sdata, &elems, false)) { ++ !ieee80211_mesh_process_chnswitch(sdata, elems, false)) { + mcsa_dbg(sdata, "Failed to process CSA action frame"); +- return; ++ goto free; + } + + /* forward or re-broadcast the CSA frame */ + if (fwd_csa) { +- if (mesh_fwd_csa_frame(sdata, mgmt, len, &elems) < 0) ++ if (mesh_fwd_csa_frame(sdata, mgmt, len, elems) < 0) + mcsa_dbg(sdata, "Failed to forward the CSA frame"); + } ++free: ++ kfree(elems); + } + + static void ieee80211_mesh_rx_mgmt_action(struct ieee80211_sub_if_data *sdata, +--- a/net/mac80211/mesh_hwmp.c ++++ b/net/mac80211/mesh_hwmp.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0-only + /* + * Copyright (c) 2008, 2009 open80211s Ltd. +- * Copyright (C) 2019 Intel Corporation ++ * Copyright (C) 2019, 2021 Intel Corporation + * Author: Luis Carlos Cobo + */ + +@@ -908,7 +908,7 @@ static void hwmp_rann_frame_process(stru + void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata, + struct ieee80211_mgmt *mgmt, size_t len) + { +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems; + size_t baselen; + u32 path_metric; + struct sta_info *sta; +@@ -926,37 +926,41 @@ void mesh_rx_path_sel_frame(struct ieee8 + rcu_read_unlock(); + + baselen = (u8 *) mgmt->u.action.u.mesh_action.variable - (u8 *) mgmt; +- ieee802_11_parse_elems(mgmt->u.action.u.mesh_action.variable, +- len - baselen, false, &elems, mgmt->bssid, NULL); ++ elems = ieee802_11_parse_elems(mgmt->u.action.u.mesh_action.variable, ++ len - baselen, false, mgmt->bssid, NULL); ++ if (!elems) ++ return; + +- if (elems.preq) { +- if (elems.preq_len != 37) ++ if (elems->preq) { ++ if (elems->preq_len != 37) + /* Right now we support just 1 destination and no AE */ +- return; +- path_metric = hwmp_route_info_get(sdata, mgmt, elems.preq, ++ goto free; ++ path_metric = hwmp_route_info_get(sdata, mgmt, elems->preq, + MPATH_PREQ); + if (path_metric) +- hwmp_preq_frame_process(sdata, mgmt, elems.preq, ++ hwmp_preq_frame_process(sdata, mgmt, elems->preq, + path_metric); + } +- if (elems.prep) { +- if (elems.prep_len != 31) ++ if (elems->prep) { ++ if (elems->prep_len != 31) + /* Right now we support no AE */ +- return; +- path_metric = hwmp_route_info_get(sdata, mgmt, elems.prep, ++ goto free; ++ path_metric = hwmp_route_info_get(sdata, mgmt, elems->prep, + MPATH_PREP); + if (path_metric) +- hwmp_prep_frame_process(sdata, mgmt, elems.prep, ++ hwmp_prep_frame_process(sdata, mgmt, elems->prep, + path_metric); + } +- if (elems.perr) { +- if (elems.perr_len != 15) ++ if (elems->perr) { ++ if (elems->perr_len != 15) + /* Right now we support only one destination per PERR */ +- return; +- hwmp_perr_frame_process(sdata, mgmt, elems.perr); ++ goto free; ++ hwmp_perr_frame_process(sdata, mgmt, elems->perr); + } +- if (elems.rann) +- hwmp_rann_frame_process(sdata, mgmt, elems.rann); ++ if (elems->rann) ++ hwmp_rann_frame_process(sdata, mgmt, elems->rann); ++free: ++ kfree(elems); + } + + /** +--- a/net/mac80211/mesh_plink.c ++++ b/net/mac80211/mesh_plink.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0-only + /* + * Copyright (c) 2008, 2009 open80211s Ltd. +- * Copyright (C) 2019 Intel Corporation ++ * Copyright (C) 2019, 2021 Intel Corporation + * Author: Luis Carlos Cobo + */ + #include +@@ -1200,7 +1200,7 @@ void mesh_rx_plink_frame(struct ieee8021 + struct ieee80211_mgmt *mgmt, size_t len, + struct ieee80211_rx_status *rx_status) + { +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems; + size_t baselen; + u8 *baseaddr; + +@@ -1228,7 +1228,8 @@ void mesh_rx_plink_frame(struct ieee8021 + if (baselen > len) + return; + } +- ieee802_11_parse_elems(baseaddr, len - baselen, true, &elems, +- mgmt->bssid, NULL); +- mesh_process_plink_frame(sdata, mgmt, &elems, rx_status); ++ elems = ieee802_11_parse_elems(baseaddr, len - baselen, true, ++ mgmt->bssid, NULL); ++ mesh_process_plink_frame(sdata, mgmt, elems, rx_status); ++ kfree(elems); + } +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -3312,8 +3312,11 @@ static bool ieee80211_assoc_success(stru + aid = 0; /* TODO */ + } + capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info); +- ieee802_11_parse_elems(pos, len - (pos - (u8 *)mgmt), false, elems, +- mgmt->bssid, assoc_data->bss->bssid); ++ elems = ieee802_11_parse_elems(pos, len - (pos - (u8 *)mgmt), false, ++ mgmt->bssid, assoc_data->bss->bssid); ++ ++ if (!elems) ++ return false; + + if (elems->aid_resp) + aid = le16_to_cpu(elems->aid_resp->aid); +@@ -3335,7 +3338,8 @@ static bool ieee80211_assoc_success(stru + + if (!is_s1g && !elems->supp_rates) { + sdata_info(sdata, "no SuppRates element in AssocResp\n"); +- return false; ++ ret = false; ++ goto out; + } + + sdata->vif.bss_conf.aid = aid; +@@ -3357,7 +3361,7 @@ static bool ieee80211_assoc_success(stru + (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) && + (!elems->vht_cap_elem || !elems->vht_operation)))) { + const struct cfg80211_bss_ies *ies; +- struct ieee802_11_elems bss_elems; ++ struct ieee802_11_elems *bss_elems; + + rcu_read_lock(); + ies = rcu_dereference(cbss->ies); +@@ -3368,13 +3372,17 @@ static bool ieee80211_assoc_success(stru + if (!bss_ies) + return false; + +- ieee802_11_parse_elems(bss_ies->data, bss_ies->len, +- false, &bss_elems, +- mgmt->bssid, +- assoc_data->bss->bssid); ++ bss_elems = ieee802_11_parse_elems(bss_ies->data, bss_ies->len, ++ false, mgmt->bssid, ++ assoc_data->bss->bssid); ++ if (!bss_elems) { ++ ret = false; ++ goto out; ++ } ++ + if (assoc_data->wmm && +- !elems->wmm_param && bss_elems.wmm_param) { +- elems->wmm_param = bss_elems.wmm_param; ++ !elems->wmm_param && bss_elems->wmm_param) { ++ elems->wmm_param = bss_elems->wmm_param; + sdata_info(sdata, + "AP bug: WMM param missing from AssocResp\n"); + } +@@ -3383,30 +3391,32 @@ static bool ieee80211_assoc_success(stru + * Also check if we requested HT/VHT, otherwise the AP doesn't + * have to include the IEs in the (re)association response. + */ +- if (!elems->ht_cap_elem && bss_elems.ht_cap_elem && ++ if (!elems->ht_cap_elem && bss_elems->ht_cap_elem && + !(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) { +- elems->ht_cap_elem = bss_elems.ht_cap_elem; ++ elems->ht_cap_elem = bss_elems->ht_cap_elem; + sdata_info(sdata, + "AP bug: HT capability missing from AssocResp\n"); + } +- if (!elems->ht_operation && bss_elems.ht_operation && ++ if (!elems->ht_operation && bss_elems->ht_operation && + !(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) { +- elems->ht_operation = bss_elems.ht_operation; ++ elems->ht_operation = bss_elems->ht_operation; + sdata_info(sdata, + "AP bug: HT operation missing from AssocResp\n"); + } +- if (!elems->vht_cap_elem && bss_elems.vht_cap_elem && ++ if (!elems->vht_cap_elem && bss_elems->vht_cap_elem && + !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) { +- elems->vht_cap_elem = bss_elems.vht_cap_elem; ++ elems->vht_cap_elem = bss_elems->vht_cap_elem; + sdata_info(sdata, + "AP bug: VHT capa missing from AssocResp\n"); + } +- if (!elems->vht_operation && bss_elems.vht_operation && ++ if (!elems->vht_operation && bss_elems->vht_operation && + !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) { +- elems->vht_operation = bss_elems.vht_operation; ++ elems->vht_operation = bss_elems->vht_operation; + sdata_info(sdata, + "AP bug: VHT operation missing from AssocResp\n"); + } ++ ++ kfree(bss_elems); + } + + /* +@@ -3660,6 +3670,7 @@ static bool ieee80211_assoc_success(stru + + ret = true; + out: ++ kfree(elems); + kfree(bss_ies); + return ret; + } +@@ -3671,7 +3682,7 @@ static void ieee80211_rx_mgmt_assoc_resp + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data; + u16 capab_info, status_code, aid; +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems; + int ac, uapsd_queues = -1; + u8 *pos; + bool reassoc; +@@ -3728,14 +3739,16 @@ static void ieee80211_rx_mgmt_assoc_resp + fils_decrypt_assoc_resp(sdata, (u8 *)mgmt, &len, assoc_data) < 0) + return; + +- ieee802_11_parse_elems(pos, len - (pos - (u8 *)mgmt), false, &elems, +- mgmt->bssid, assoc_data->bss->bssid); ++ elems = ieee802_11_parse_elems(pos, len - (pos - (u8 *)mgmt), false, ++ mgmt->bssid, assoc_data->bss->bssid); ++ if (!elems) ++ goto notify_driver; + + if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY && +- elems.timeout_int && +- elems.timeout_int->type == WLAN_TIMEOUT_ASSOC_COMEBACK) { ++ elems->timeout_int && ++ elems->timeout_int->type == WLAN_TIMEOUT_ASSOC_COMEBACK) { + u32 tu, ms; +- tu = le32_to_cpu(elems.timeout_int->value); ++ tu = le32_to_cpu(elems->timeout_int->value); + ms = tu * 1024 / 1000; + sdata_info(sdata, + "%pM rejected association temporarily; comeback duration %u TU (%u ms)\n", +@@ -3755,7 +3768,7 @@ static void ieee80211_rx_mgmt_assoc_resp + event.u.mlme.reason = status_code; + drv_event_callback(sdata->local, sdata, &event); + } else { +- if (!ieee80211_assoc_success(sdata, cbss, mgmt, len, &elems)) { ++ if (!ieee80211_assoc_success(sdata, cbss, mgmt, len, elems)) { + /* oops -- internal error -- send timeout for now */ + ieee80211_destroy_assoc_data(sdata, false, false); + cfg80211_assoc_timeout(sdata->dev, cbss); +@@ -3785,6 +3798,7 @@ static void ieee80211_rx_mgmt_assoc_resp + ifmgd->assoc_req_ies, ifmgd->assoc_req_ies_len); + notify_driver: + drv_mgd_complete_tx(sdata->local, sdata, &info); ++ kfree(elems); + } + + static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, +@@ -3989,7 +4003,7 @@ static void ieee80211_rx_mgmt_beacon(str + struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; + struct ieee80211_mgmt *mgmt = (void *) hdr; + size_t baselen; +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems; + struct ieee80211_local *local = sdata->local; + struct ieee80211_chanctx_conf *chanctx_conf; + struct ieee80211_channel *chan; +@@ -4035,15 +4049,16 @@ static void ieee80211_rx_mgmt_beacon(str + + if (ifmgd->assoc_data && ifmgd->assoc_data->need_beacon && + ieee80211_rx_our_beacon(bssid, ifmgd->assoc_data->bss)) { +- ieee802_11_parse_elems(variable, +- len - baselen, false, &elems, +- bssid, +- ifmgd->assoc_data->bss->bssid); ++ elems = ieee802_11_parse_elems(variable, len - baselen, false, ++ bssid, ++ ifmgd->assoc_data->bss->bssid); ++ if (!elems) ++ return; + + ieee80211_rx_bss_info(sdata, mgmt, len, rx_status); + +- if (elems.dtim_period) +- ifmgd->dtim_period = elems.dtim_period; ++ if (elems->dtim_period) ++ ifmgd->dtim_period = elems->dtim_period; + ifmgd->have_beacon = true; + ifmgd->assoc_data->need_beacon = false; + if (ieee80211_hw_check(&local->hw, TIMING_BEACON_ONLY)) { +@@ -4051,17 +4066,17 @@ static void ieee80211_rx_mgmt_beacon(str + le64_to_cpu(mgmt->u.beacon.timestamp); + sdata->vif.bss_conf.sync_device_ts = + rx_status->device_timestamp; +- sdata->vif.bss_conf.sync_dtim_count = elems.dtim_count; ++ sdata->vif.bss_conf.sync_dtim_count = elems->dtim_count; + } + +- if (elems.mbssid_config_ie) ++ if (elems->mbssid_config_ie) + bss_conf->profile_periodicity = +- elems.mbssid_config_ie->profile_periodicity; ++ elems->mbssid_config_ie->profile_periodicity; + else + bss_conf->profile_periodicity = 0; + +- if (elems.ext_capab_len >= 11 && +- (elems.ext_capab[10] & WLAN_EXT_CAPA11_EMA_SUPPORT)) ++ if (elems->ext_capab_len >= 11 && ++ (elems->ext_capab[10] & WLAN_EXT_CAPA11_EMA_SUPPORT)) + bss_conf->ema_ap = true; + else + bss_conf->ema_ap = false; +@@ -4070,6 +4085,7 @@ static void ieee80211_rx_mgmt_beacon(str + ifmgd->assoc_data->timeout = jiffies; + ifmgd->assoc_data->timeout_started = true; + run_again(sdata, ifmgd->assoc_data->timeout); ++ kfree(elems); + return; + } + +@@ -4101,14 +4117,15 @@ static void ieee80211_rx_mgmt_beacon(str + */ + if (!ieee80211_is_s1g_beacon(hdr->frame_control)) + ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4); +- ieee802_11_parse_elems_crc(variable, +- len - baselen, false, &elems, +- care_about_ies, ncrc, +- mgmt->bssid, bssid); +- ncrc = elems.crc; ++ elems = ieee802_11_parse_elems_crc(variable, len - baselen, ++ false, care_about_ies, ncrc, ++ mgmt->bssid, bssid); ++ if (!elems) ++ return; ++ ncrc = elems->crc; + + if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK) && +- ieee80211_check_tim(elems.tim, elems.tim_len, bss_conf->aid)) { ++ ieee80211_check_tim(elems->tim, elems->tim_len, bss_conf->aid)) { + if (local->hw.conf.dynamic_ps_timeout > 0) { + if (local->hw.conf.flags & IEEE80211_CONF_PS) { + local->hw.conf.flags &= ~IEEE80211_CONF_PS; +@@ -4178,12 +4195,12 @@ static void ieee80211_rx_mgmt_beacon(str + le64_to_cpu(mgmt->u.beacon.timestamp); + sdata->vif.bss_conf.sync_device_ts = + rx_status->device_timestamp; +- sdata->vif.bss_conf.sync_dtim_count = elems.dtim_count; ++ sdata->vif.bss_conf.sync_dtim_count = elems->dtim_count; + } + + if ((ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid) || + ieee80211_is_s1g_short_beacon(mgmt->frame_control)) +- return; ++ goto free; + ifmgd->beacon_crc = ncrc; + ifmgd->beacon_crc_valid = true; + +@@ -4191,12 +4208,12 @@ static void ieee80211_rx_mgmt_beacon(str + + ieee80211_sta_process_chanswitch(sdata, rx_status->mactime, + rx_status->device_timestamp, +- &elems, true); ++ elems, true); + + if (!(ifmgd->flags & IEEE80211_STA_DISABLE_WMM) && +- ieee80211_sta_wmm_params(local, sdata, elems.wmm_param, +- elems.wmm_param_len, +- elems.mu_edca_param_set)) ++ ieee80211_sta_wmm_params(local, sdata, elems->wmm_param, ++ elems->wmm_param_len, ++ elems->mu_edca_param_set)) + changed |= BSS_CHANGED_QOS; + + /* +@@ -4205,7 +4222,7 @@ static void ieee80211_rx_mgmt_beacon(str + */ + if (!ifmgd->have_beacon) { + /* a few bogus AP send dtim_period = 0 or no TIM IE */ +- bss_conf->dtim_period = elems.dtim_period ?: 1; ++ bss_conf->dtim_period = elems->dtim_period ?: 1; + + changed |= BSS_CHANGED_BEACON_INFO; + ifmgd->have_beacon = true; +@@ -4217,9 +4234,9 @@ static void ieee80211_rx_mgmt_beacon(str + ieee80211_recalc_ps_vif(sdata); + } + +- if (elems.erp_info) { ++ if (elems->erp_info) { + erp_valid = true; +- erp_value = elems.erp_info[0]; ++ erp_value = elems->erp_info[0]; + } else { + erp_valid = false; + } +@@ -4232,12 +4249,12 @@ static void ieee80211_rx_mgmt_beacon(str + mutex_lock(&local->sta_mtx); + sta = sta_info_get(sdata, bssid); + +- changed |= ieee80211_recalc_twt_req(sdata, sta, &elems); ++ changed |= ieee80211_recalc_twt_req(sdata, sta, elems); + +- if (ieee80211_config_bw(sdata, sta, elems.ht_cap_elem, +- elems.vht_cap_elem, elems.ht_operation, +- elems.vht_operation, elems.he_operation, +- elems.s1g_oper, bssid, &changed)) { ++ if (ieee80211_config_bw(sdata, sta, elems->ht_cap_elem, ++ elems->vht_cap_elem, elems->ht_operation, ++ elems->vht_operation, elems->he_operation, ++ elems->s1g_oper, bssid, &changed)) { + mutex_unlock(&local->sta_mtx); + sdata_info(sdata, + "failed to follow AP %pM bandwidth change, disconnect\n", +@@ -4249,21 +4266,23 @@ static void ieee80211_rx_mgmt_beacon(str + sizeof(deauth_buf), true, + WLAN_REASON_DEAUTH_LEAVING, + false); +- return; ++ goto free; + } + +- if (sta && elems.opmode_notif) +- ieee80211_vht_handle_opmode(sdata, sta, *elems.opmode_notif, ++ if (sta && elems->opmode_notif) ++ ieee80211_vht_handle_opmode(sdata, sta, *elems->opmode_notif, + rx_status->band); + mutex_unlock(&local->sta_mtx); + + changed |= ieee80211_handle_pwr_constr(sdata, chan, mgmt, +- elems.country_elem, +- elems.country_elem_len, +- elems.pwr_constr_elem, +- elems.cisco_dtpc_elem); ++ elems->country_elem, ++ elems->country_elem_len, ++ elems->pwr_constr_elem, ++ elems->cisco_dtpc_elem); + + ieee80211_bss_info_change_notify(sdata, changed); ++free: ++ kfree(elems); + } + + void ieee80211_sta_rx_queued_ext(struct ieee80211_sub_if_data *sdata, +@@ -4292,7 +4311,6 @@ void ieee80211_sta_rx_queued_mgmt(struct + struct ieee80211_rx_status *rx_status; + struct ieee80211_mgmt *mgmt; + u16 fc; +- struct ieee802_11_elems elems; + int ies_len; + + rx_status = (struct ieee80211_rx_status *) skb->cb; +@@ -4324,6 +4342,8 @@ void ieee80211_sta_rx_queued_mgmt(struct + break; + case IEEE80211_STYPE_ACTION: + if (mgmt->u.action.category == WLAN_CATEGORY_SPECTRUM_MGMT) { ++ struct ieee802_11_elems *elems; ++ + ies_len = skb->len - + offsetof(struct ieee80211_mgmt, + u.action.u.chan_switch.variable); +@@ -4332,18 +4352,21 @@ void ieee80211_sta_rx_queued_mgmt(struct + break; + + /* CSA IE cannot be overridden, no need for BSSID */ +- ieee802_11_parse_elems( +- mgmt->u.action.u.chan_switch.variable, +- ies_len, true, &elems, mgmt->bssid, NULL); ++ elems = ieee802_11_parse_elems( ++ mgmt->u.action.u.chan_switch.variable, ++ ies_len, true, mgmt->bssid, NULL); + +- if (elems.parse_error) ++ if (!elems || elems->parse_error) + break; + + ieee80211_sta_process_chanswitch(sdata, + rx_status->mactime, + rx_status->device_timestamp, +- &elems, false); ++ elems, false); ++ kfree(elems); + } else if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) { ++ struct ieee802_11_elems *elems; ++ + ies_len = skb->len - + offsetof(struct ieee80211_mgmt, + u.action.u.ext_chan_switch.variable); +@@ -4355,21 +4378,22 @@ void ieee80211_sta_rx_queued_mgmt(struct + * extended CSA IE can't be overridden, no need for + * BSSID + */ +- ieee802_11_parse_elems( +- mgmt->u.action.u.ext_chan_switch.variable, +- ies_len, true, &elems, mgmt->bssid, NULL); ++ elems = ieee802_11_parse_elems( ++ mgmt->u.action.u.ext_chan_switch.variable, ++ ies_len, true, mgmt->bssid, NULL); + +- if (elems.parse_error) ++ if (!elems || elems->parse_error) + break; + + /* for the handling code pretend this was also an IE */ +- elems.ext_chansw_ie = ++ elems->ext_chansw_ie = + &mgmt->u.action.u.ext_chan_switch.data; + + ieee80211_sta_process_chanswitch(sdata, + rx_status->mactime, + rx_status->device_timestamp, +- &elems, false); ++ elems, false); ++ kfree(elems); + } + break; + } +--- a/net/mac80211/scan.c ++++ b/net/mac80211/scan.c +@@ -9,7 +9,7 @@ + * Copyright 2007, Michael Wu + * Copyright 2013-2015 Intel Mobile Communications GmbH + * Copyright 2016-2017 Intel Deutschland GmbH +- * Copyright (C) 2018-2020 Intel Corporation ++ * Copyright (C) 2018-2021 Intel Corporation + */ + + #include +@@ -155,7 +155,7 @@ ieee80211_bss_info_update(struct ieee802 + }; + bool signal_valid; + struct ieee80211_sub_if_data *scan_sdata; +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems; + size_t baselen; + u8 *elements; + +@@ -209,8 +209,10 @@ ieee80211_bss_info_update(struct ieee802 + if (baselen > len) + return NULL; + +- ieee802_11_parse_elems(elements, len - baselen, false, &elems, +- mgmt->bssid, cbss->bssid); ++ elems = ieee802_11_parse_elems(elements, len - baselen, false, ++ mgmt->bssid, cbss->bssid); ++ if (!elems) ++ return NULL; + + /* In case the signal is invalid update the status */ + signal_valid = channel == cbss->channel; +@@ -218,15 +220,17 @@ ieee80211_bss_info_update(struct ieee802 + rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL; + + bss = (void *)cbss->priv; +- ieee80211_update_bss_from_elems(local, bss, &elems, rx_status, beacon); ++ ieee80211_update_bss_from_elems(local, bss, elems, rx_status, beacon); + + list_for_each_entry(non_tx_cbss, &cbss->nontrans_list, nontrans_list) { + non_tx_bss = (void *)non_tx_cbss->priv; + +- ieee80211_update_bss_from_elems(local, non_tx_bss, &elems, ++ ieee80211_update_bss_from_elems(local, non_tx_bss, elems, + rx_status, beacon); + } + ++ kfree(elems); ++ + return bss; + } + +--- a/net/mac80211/tdls.c ++++ b/net/mac80211/tdls.c +@@ -6,7 +6,7 @@ + * Copyright 2014, Intel Corporation + * Copyright 2014 Intel Mobile Communications GmbH + * Copyright 2015 - 2016 Intel Deutschland GmbH +- * Copyright (C) 2019 Intel Corporation ++ * Copyright (C) 2019, 2021 Intel Corporation + */ + + #include +@@ -1684,7 +1684,7 @@ ieee80211_process_tdls_channel_switch_re + struct sk_buff *skb) + { + struct ieee80211_local *local = sdata->local; +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems = NULL; + struct sta_info *sta; + struct ieee80211_tdls_data *tf = (void *)skb->data; + bool local_initiator; +@@ -1718,16 +1718,20 @@ ieee80211_process_tdls_channel_switch_re + goto call_drv; + } + +- ieee802_11_parse_elems(tf->u.chan_switch_resp.variable, +- skb->len - baselen, false, &elems, +- NULL, NULL); +- if (elems.parse_error) { ++ elems = ieee802_11_parse_elems(tf->u.chan_switch_resp.variable, ++ skb->len - baselen, false, NULL, NULL); ++ if (!elems) { ++ ret = -ENOMEM; ++ goto out; ++ } ++ ++ if (elems->parse_error) { + tdls_dbg(sdata, "Invalid IEs in TDLS channel switch resp\n"); + ret = -EINVAL; + goto out; + } + +- if (!elems.ch_sw_timing || !elems.lnk_id) { ++ if (!elems->ch_sw_timing || !elems->lnk_id) { + tdls_dbg(sdata, "TDLS channel switch resp - missing IEs\n"); + ret = -EINVAL; + goto out; +@@ -1735,15 +1739,15 @@ ieee80211_process_tdls_channel_switch_re + + /* validate the initiator is set correctly */ + local_initiator = +- !memcmp(elems.lnk_id->init_sta, sdata->vif.addr, ETH_ALEN); ++ !memcmp(elems->lnk_id->init_sta, sdata->vif.addr, ETH_ALEN); + if (local_initiator == sta->sta.tdls_initiator) { + tdls_dbg(sdata, "TDLS chan switch invalid lnk-id initiator\n"); + ret = -EINVAL; + goto out; + } + +- params.switch_time = le16_to_cpu(elems.ch_sw_timing->switch_time); +- params.switch_timeout = le16_to_cpu(elems.ch_sw_timing->switch_timeout); ++ params.switch_time = le16_to_cpu(elems->ch_sw_timing->switch_time); ++ params.switch_timeout = le16_to_cpu(elems->ch_sw_timing->switch_timeout); + + params.tmpl_skb = + ieee80211_tdls_ch_sw_resp_tmpl_get(sta, ¶ms.ch_sw_tm_ie); +@@ -1763,6 +1767,7 @@ call_drv: + out: + mutex_unlock(&local->sta_mtx); + dev_kfree_skb_any(params.tmpl_skb); ++ kfree(elems); + return ret; + } + +@@ -1771,7 +1776,7 @@ ieee80211_process_tdls_channel_switch_re + struct sk_buff *skb) + { + struct ieee80211_local *local = sdata->local; +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems; + struct cfg80211_chan_def chandef; + struct ieee80211_channel *chan; + enum nl80211_channel_type chan_type; +@@ -1831,22 +1836,27 @@ ieee80211_process_tdls_channel_switch_re + return -EINVAL; + } + +- ieee802_11_parse_elems(tf->u.chan_switch_req.variable, +- skb->len - baselen, false, &elems, NULL, NULL); +- if (elems.parse_error) { ++ elems = ieee802_11_parse_elems(tf->u.chan_switch_req.variable, ++ skb->len - baselen, false, NULL, NULL); ++ if (!elems) ++ return -ENOMEM; ++ ++ if (elems->parse_error) { + tdls_dbg(sdata, "Invalid IEs in TDLS channel switch req\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto free; + } + +- if (!elems.ch_sw_timing || !elems.lnk_id) { ++ if (!elems->ch_sw_timing || !elems->lnk_id) { + tdls_dbg(sdata, "TDLS channel switch req - missing IEs\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto free; + } + +- if (!elems.sec_chan_offs) { ++ if (!elems->sec_chan_offs) { + chan_type = NL80211_CHAN_HT20; + } else { +- switch (elems.sec_chan_offs->sec_chan_offs) { ++ switch (elems->sec_chan_offs->sec_chan_offs) { + case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: + chan_type = NL80211_CHAN_HT40PLUS; + break; +@@ -1865,7 +1875,8 @@ ieee80211_process_tdls_channel_switch_re + if (!cfg80211_reg_can_beacon_relax(sdata->local->hw.wiphy, &chandef, + sdata->wdev.iftype)) { + tdls_dbg(sdata, "TDLS chan switch to forbidden channel\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto free; + } + + mutex_lock(&local->sta_mtx); +@@ -1881,7 +1892,7 @@ ieee80211_process_tdls_channel_switch_re + + /* validate the initiator is set correctly */ + local_initiator = +- !memcmp(elems.lnk_id->init_sta, sdata->vif.addr, ETH_ALEN); ++ !memcmp(elems->lnk_id->init_sta, sdata->vif.addr, ETH_ALEN); + if (local_initiator == sta->sta.tdls_initiator) { + tdls_dbg(sdata, "TDLS chan switch invalid lnk-id initiator\n"); + ret = -EINVAL; +@@ -1889,16 +1900,16 @@ ieee80211_process_tdls_channel_switch_re + } + + /* peer should have known better */ +- if (!sta->sta.ht_cap.ht_supported && elems.sec_chan_offs && +- elems.sec_chan_offs->sec_chan_offs) { ++ if (!sta->sta.ht_cap.ht_supported && elems->sec_chan_offs && ++ elems->sec_chan_offs->sec_chan_offs) { + tdls_dbg(sdata, "TDLS chan switch - wide chan unsupported\n"); + ret = -ENOTSUPP; + goto out; + } + + params.chandef = &chandef; +- params.switch_time = le16_to_cpu(elems.ch_sw_timing->switch_time); +- params.switch_timeout = le16_to_cpu(elems.ch_sw_timing->switch_timeout); ++ params.switch_time = le16_to_cpu(elems->ch_sw_timing->switch_time); ++ params.switch_timeout = le16_to_cpu(elems->ch_sw_timing->switch_timeout); + + params.tmpl_skb = + ieee80211_tdls_ch_sw_resp_tmpl_get(sta, +@@ -1917,6 +1928,8 @@ ieee80211_process_tdls_channel_switch_re + out: + mutex_unlock(&local->sta_mtx); + dev_kfree_skb_any(params.tmpl_skb); ++free: ++ kfree(elems); + return ret; + } + +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -1384,8 +1384,8 @@ _ieee802_11_parse_elems_crc(const u8 *st + + static size_t ieee802_11_find_bssid_profile(const u8 *start, size_t len, + struct ieee802_11_elems *elems, +- u8 *transmitter_bssid, +- u8 *bss_bssid, ++ const u8 *transmitter_bssid, ++ const u8 *bss_bssid, + u8 *nontransmitted_profile) + { + const struct element *elem, *sub; +@@ -1452,16 +1452,20 @@ static size_t ieee802_11_find_bssid_prof + return found ? profile_len : 0; + } + +-void ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, +- struct ieee802_11_elems *elems, +- u64 filter, u32 crc, u8 *transmitter_bssid, +- u8 *bss_bssid) ++struct ieee802_11_elems *ieee802_11_parse_elems_crc(const u8 *start, size_t len, ++ bool action, u64 filter, ++ u32 crc, ++ const u8 *transmitter_bssid, ++ const u8 *bss_bssid) + { ++ struct ieee802_11_elems *elems; + const struct element *non_inherit = NULL; + u8 *nontransmitted_profile; + int nontransmitted_profile_len = 0; + +- memset(elems, 0, sizeof(*elems)); ++ elems = kzalloc(sizeof(*elems), GFP_ATOMIC); ++ if (!elems) ++ return NULL; + elems->ie_start = start; + elems->total_len = len; + +@@ -1508,6 +1512,8 @@ void ieee802_11_parse_elems_crc(const u8 + kfree(nontransmitted_profile); + + elems->crc = crc; ++ ++ return elems; + } + + void ieee80211_regulatory_limit_wmm_params(struct ieee80211_sub_if_data *sdata, diff --git a/patches.suse/mac80211-fix-memory-leaks-with-element-parsing.patch b/patches.suse/mac80211-fix-memory-leaks-with-element-parsing.patch new file mode 100644 index 0000000..bbdb09d --- /dev/null +++ b/patches.suse/mac80211-fix-memory-leaks-with-element-parsing.patch @@ -0,0 +1,130 @@ +From 8223ac199a3849257e86ec27865dc63f034b1cf1 Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Fri, 1 Oct 2021 21:11:08 +0200 +Subject: [PATCH] mac80211: fix memory leaks with element parsing +Git-commit: 8223ac199a3849257e86ec27865dc63f034b1cf1 +Patch-mainline: v5.16-rc1 +References: CVE-2022-42719 bsc#1204051 + +My previous commit 5d24828d05f3 ("mac80211: always allocate +struct ieee802_11_elems") had a few bugs and leaked the new +allocated struct in a few error cases, fix that. + +Fixes: 5d24828d05f3 ("mac80211: always allocate struct ieee802_11_elems") +Signed-off-by: Johannes Berg +Link: https://lore.kernel.org/r/20211001211108.9839928e42e0.Ib81ca187d3d3af7ed1bfeac2e00d08a4637c8025@changeid +Acked-by: Takashi Iwai + +--- + net/mac80211/agg-rx.c | 3 ++- + net/mac80211/ibss.c | 10 +++++----- + net/mac80211/mlme.c | 36 ++++++++++++++++++------------------ + 3 files changed, 25 insertions(+), 24 deletions(-) + +diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c +index 94c65def102c..470ff0ce3dc7 100644 +--- a/net/mac80211/agg-rx.c ++++ b/net/mac80211/agg-rx.c +@@ -498,13 +498,14 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, + elems = ieee802_11_parse_elems(mgmt->u.action.u.addba_req.variable, + ies_len, true, mgmt->bssid, NULL); + if (!elems || elems->parse_error) +- return; ++ goto free; + } + + __ieee80211_start_rx_ba_session(sta, dialog_token, timeout, + start_seq_num, ba_policy, tid, + buf_size, true, false, + elems ? elems->addba_ext_ie : NULL); ++free: + kfree(elems); + } + +diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c +index 66b00046f0c2..0416c4d22292 100644 +--- a/net/mac80211/ibss.c ++++ b/net/mac80211/ibss.c +@@ -1659,11 +1659,11 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, + mgmt->u.action.u.chan_switch.variable, + ies_len, true, mgmt->bssid, NULL); + +- if (!elems || elems->parse_error) +- break; +- +- ieee80211_rx_mgmt_spectrum_mgmt(sdata, mgmt, skb->len, +- rx_status, elems); ++ if (elems && !elems->parse_error) ++ ieee80211_rx_mgmt_spectrum_mgmt(sdata, mgmt, ++ skb->len, ++ rx_status, ++ elems); + kfree(elems); + break; + } +diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c +index 0ec183a92a01..40b29cfb7cfe 100644 +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -3353,8 +3353,10 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, + bss_ies = kmemdup(ies, sizeof(*ies) + ies->len, + GFP_ATOMIC); + rcu_read_unlock(); +- if (!bss_ies) +- return false; ++ if (!bss_ies) { ++ ret = false; ++ goto out; ++ } + + bss_elems = ieee802_11_parse_elems(bss_ies->data, bss_ies->len, + false, mgmt->bssid, +@@ -4331,13 +4333,11 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, + mgmt->u.action.u.chan_switch.variable, + ies_len, true, mgmt->bssid, NULL); + +- if (!elems || elems->parse_error) +- break; +- +- ieee80211_sta_process_chanswitch(sdata, +- rx_status->mactime, +- rx_status->device_timestamp, +- elems, false); ++ if (elems && !elems->parse_error) ++ ieee80211_sta_process_chanswitch(sdata, ++ rx_status->mactime, ++ rx_status->device_timestamp, ++ elems, false); + kfree(elems); + } else if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) { + struct ieee802_11_elems *elems; +@@ -4357,17 +4357,17 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, + mgmt->u.action.u.ext_chan_switch.variable, + ies_len, true, mgmt->bssid, NULL); + +- if (!elems || elems->parse_error) +- break; ++ if (elems && !elems->parse_error) { ++ /* for the handling code pretend it was an IE */ ++ elems->ext_chansw_ie = ++ &mgmt->u.action.u.ext_chan_switch.data; + +- /* for the handling code pretend this was also an IE */ +- elems->ext_chansw_ie = +- &mgmt->u.action.u.ext_chan_switch.data; ++ ieee80211_sta_process_chanswitch(sdata, ++ rx_status->mactime, ++ rx_status->device_timestamp, ++ elems, false); ++ } + +- ieee80211_sta_process_chanswitch(sdata, +- rx_status->mactime, +- rx_status->device_timestamp, +- elems, false); + kfree(elems); + } + break; +-- +2.35.3 + diff --git a/patches.suse/mac80211-mlme-find-auth-challenge-directly.patch b/patches.suse/mac80211-mlme-find-auth-challenge-directly.patch new file mode 100644 index 0000000..27cd0bd --- /dev/null +++ b/patches.suse/mac80211-mlme-find-auth-challenge-directly.patch @@ -0,0 +1,97 @@ +From 49a765d6785e99157ff5091cc37485732496864e Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Mon, 20 Sep 2021 15:40:09 +0200 +Subject: [PATCH] mac80211: mlme: find auth challenge directly +Git-commit: 49a765d6785e99157ff5091cc37485732496864e +Patch-mainline: v5.16-rc1 +References: CVE-2022-42719 bsc#1204051 + +There's no need to parse all elements etc. just to find the +authentication challenge - use cfg80211_find_elem() instead. +This also allows us to remove WLAN_EID_CHALLENGE handling +from the element parsing entirely. + +Link: https://lore.kernel.org/r/20210920154009.45f9b3a15722.Ice3159ffad03a007d6154cbf1fb3a8c48489e86f@changeid +Signed-off-by: Johannes Berg +Acked-by: Takashi Iwai + +--- + net/mac80211/ieee80211_i.h | 2 -- + net/mac80211/mlme.c | 11 ++++++----- + net/mac80211/util.c | 4 ---- + 3 files changed, 6 insertions(+), 11 deletions(-) + +diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h +index 6a129a08bc9b..7a9e529f8366 100644 +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -1517,7 +1517,6 @@ struct ieee802_11_elems { + const u8 *supp_rates; + const u8 *ds_params; + const struct ieee80211_tim_ie *tim; +- const u8 *challenge; + const u8 *rsn; + const u8 *rsnx; + const u8 *erp_info; +@@ -1571,7 +1570,6 @@ struct ieee802_11_elems { + u8 ssid_len; + u8 supp_rates_len; + u8 tim_len; +- u8 challenge_len; + u8 rsn_len; + u8 rsnx_len; + u8 ext_supp_rates_len; +diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c +index 39b3ed89e0da..e18bd07f6822 100644 +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -2870,17 +2870,17 @@ static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata, + { + struct ieee80211_local *local = sdata->local; + struct ieee80211_mgd_auth_data *auth_data = sdata->u.mgd.auth_data; ++ const struct element *challenge; + u8 *pos; +- struct ieee802_11_elems elems; + u32 tx_flags = 0; + struct ieee80211_prep_tx_info info = { + .subtype = IEEE80211_STYPE_AUTH, + }; + + pos = mgmt->u.auth.variable; +- ieee802_11_parse_elems(pos, len - (pos - (u8 *)mgmt), false, &elems, +- mgmt->bssid, auth_data->bss->bssid); +- if (!elems.challenge) ++ challenge = cfg80211_find_elem(WLAN_EID_CHALLENGE, pos, ++ len - (pos - (u8 *)mgmt)); ++ if (!challenge) + return; + auth_data->expected_transaction = 4; + drv_mgd_prepare_tx(sdata->local, sdata, &info); +@@ -2888,7 +2888,8 @@ static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata, + tx_flags = IEEE80211_TX_CTL_REQ_TX_STATUS | + IEEE80211_TX_INTFL_MLME_CONN_TX; + ieee80211_send_auth(sdata, 3, auth_data->algorithm, 0, +- elems.challenge - 2, elems.challenge_len + 2, ++ (void *)challenge, ++ challenge->datalen + sizeof(*challenge), + auth_data->bss->bssid, auth_data->bss->bssid, + auth_data->key, auth_data->key_len, + auth_data->key_idx, tx_flags); +diff --git a/net/mac80211/util.c b/net/mac80211/util.c +index 43ccad8b24c7..dce841228297 100644 +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -1112,10 +1112,6 @@ _ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, + } else + elem_parse_failed = true; + break; +- case WLAN_EID_CHALLENGE: +- elems->challenge = pos; +- elems->challenge_len = elen; +- break; + case WLAN_EID_VENDOR_SPECIFIC: + if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 && + pos[2] == 0xf2) { +-- +2.35.3 + diff --git a/patches.suse/mac80211-move-CRC-into-struct-ieee802_11_elems.patch b/patches.suse/mac80211-move-CRC-into-struct-ieee802_11_elems.patch new file mode 100644 index 0000000..1327441 --- /dev/null +++ b/patches.suse/mac80211-move-CRC-into-struct-ieee802_11_elems.patch @@ -0,0 +1,99 @@ +From c6e37ed498f958254b5459253199e816b6bfc52f Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Mon, 20 Sep 2021 15:40:08 +0200 +Subject: [PATCH] mac80211: move CRC into struct ieee802_11_elems +Git-commit: c6e37ed498f958254b5459253199e816b6bfc52f +Patch-mainline: v5.16-rc1 +References: CVE-2022-42719 bsc#1204051 + +We're currently returning this value, but to prepare for +returning the allocated structure, move it into there. + +Link: https://lore.kernel.org/r/20210920154009.479b8ebf999d.If0d4ba75ee38998dc3eeae25058aa748efcb2fc9@changeid +Signed-off-by: Johannes Berg +Acked-by: Takashi Iwai + +--- + net/mac80211/ieee80211_i.h | 9 +++++---- + net/mac80211/mlme.c | 9 +++++---- + net/mac80211/util.c | 10 +++++----- + 3 files changed, 15 insertions(+), 13 deletions(-) + +diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h +index d74031bb4ae6..6a129a08bc9b 100644 +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -1507,6 +1507,7 @@ struct ieee80211_csa_ie { + struct ieee802_11_elems { + const u8 *ie_start; + size_t total_len; ++ u32 crc; + + /* pointers to IEs */ + const struct ieee80211_tdls_lnkie *lnk_id; +@@ -2193,10 +2194,10 @@ static inline void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, + ieee80211_tx_skb_tid(sdata, skb, 7); + } + +-u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, +- struct ieee802_11_elems *elems, +- u64 filter, u32 crc, u8 *transmitter_bssid, +- u8 *bss_bssid); ++void ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, ++ struct ieee802_11_elems *elems, ++ u64 filter, u32 crc, u8 *transmitter_bssid, ++ u8 *bss_bssid); + static inline void ieee802_11_parse_elems(const u8 *start, size_t len, + bool action, + struct ieee802_11_elems *elems, +diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c +index c0ea3b1aa9e1..39b3ed89e0da 100644 +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -4070,10 +4070,11 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, + */ + if (!ieee80211_is_s1g_beacon(hdr->frame_control)) + ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4); +- ncrc = ieee802_11_parse_elems_crc(variable, +- len - baselen, false, &elems, +- care_about_ies, ncrc, +- mgmt->bssid, bssid); ++ ieee802_11_parse_elems_crc(variable, ++ len - baselen, false, &elems, ++ care_about_ies, ncrc, ++ mgmt->bssid, bssid); ++ ncrc = elems.crc; + + if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK) && + ieee80211_check_tim(elems.tim, elems.tim_len, bss_conf->aid)) { +diff --git a/net/mac80211/util.c b/net/mac80211/util.c +index 49cb96d25169..43ccad8b24c7 100644 +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -1461,10 +1461,10 @@ static size_t ieee802_11_find_bssid_profile(const u8 *start, size_t len, + return found ? profile_len : 0; + } + +-u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, +- struct ieee802_11_elems *elems, +- u64 filter, u32 crc, u8 *transmitter_bssid, +- u8 *bss_bssid) ++void ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, ++ struct ieee802_11_elems *elems, ++ u64 filter, u32 crc, u8 *transmitter_bssid, ++ u8 *bss_bssid) + { + const struct element *non_inherit = NULL; + u8 *nontransmitted_profile; +@@ -1516,7 +1516,7 @@ u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, + + kfree(nontransmitted_profile); + +- return crc; ++ elems->crc = crc; + } + + void ieee80211_regulatory_limit_wmm_params(struct ieee80211_sub_if_data *sdata, +-- +2.35.3 + diff --git a/patches.suse/macvlan-Fix-leaking-skb-in-source-mode-with-nodst-op.patch b/patches.suse/macvlan-Fix-leaking-skb-in-source-mode-with-nodst-op.patch index e9faef0..094ebf8 100644 --- a/patches.suse/macvlan-Fix-leaking-skb-in-source-mode-with-nodst-op.patch +++ b/patches.suse/macvlan-Fix-leaking-skb-in-source-mode-with-nodst-op.patch @@ -4,7 +4,7 @@ Date: Tue, 12 Apr 2022 11:34:57 +0200 Subject: [PATCH] macvlan: Fix leaking skb in source mode with nodst option Git-commit: e16b859872b87650bb55b12cca5a5fcdc49c1442 Patch-mainline: v5.18-rc3 -References: git-fixes +References: CVE-2022-3526 bsc#1204353 git-fixes The MACVLAN receive handler clones skbs to all matching source MACVLAN interfaces, before it passes the packet along to match on destination diff --git a/patches.suse/macvlan-enforce-a-consistent-minimal-mtu.patch b/patches.suse/macvlan-enforce-a-consistent-minimal-mtu.patch new file mode 100644 index 0000000..f06d5c1 --- /dev/null +++ b/patches.suse/macvlan-enforce-a-consistent-minimal-mtu.patch @@ -0,0 +1,47 @@ +From b64085b00044bdf3cd1c9825e9ef5b2e0feae91a Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Fri, 7 Oct 2022 15:57:43 -0700 +Subject: [PATCH] macvlan: enforce a consistent minimal mtu +Git-commit: b64085b00044bdf3cd1c9825e9ef5b2e0feae91a +Patch-mainline: v6.1-rc1 +References: git-fixes + +macvlan should enforce a minimal mtu of 68, even at link creation. + +This patch avoids the current behavior (which could lead to crashes +in ipv6 stack if the link is brought up) + +$ ip link add macvlan1 link eno1 mtu 8 type macvlan # This should fail ! +$ ip link sh dev macvlan1 +5: macvlan1@eno1: mtu 8 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 02:47:6c:24:74:82 brd ff:ff:ff:ff:ff:ff +$ ip link set macvlan1 mtu 67 +Error: mtu less than device minimum. +$ ip link set macvlan1 mtu 68 +$ ip link set macvlan1 mtu 8 + +Fixes: 91572088e3fd ("net: use core MTU range checking in core net infra") +Reported-by: syzbot +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Acked-by: Takashi Iwai + +--- + drivers/net/macvlan.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c +index 713e3354cb2e..8f8f73099de8 100644 +--- a/drivers/net/macvlan.c ++++ b/drivers/net/macvlan.c +@@ -1192,7 +1192,7 @@ void macvlan_common_setup(struct net_device *dev) + { + ether_setup(dev); + +- dev->min_mtu = 0; ++ /* ether_setup() has set dev->min_mtu to ETH_MIN_MTU. */ + dev->max_mtu = ETH_MAX_MTU; + dev->priv_flags &= ~IFF_TX_SKB_SHARING; + netif_keep_dst(dev); +-- +2.35.3 + diff --git a/patches.suse/mailbox-bcm-ferxrm-mailbox-Fix-error-check-for-dma_m.patch b/patches.suse/mailbox-bcm-ferxrm-mailbox-Fix-error-check-for-dma_m.patch new file mode 100644 index 0000000..0b3c5af --- /dev/null +++ b/patches.suse/mailbox-bcm-ferxrm-mailbox-Fix-error-check-for-dma_m.patch @@ -0,0 +1,47 @@ +From 6b207ce8a96a71e966831e3a13c38143ba9a73c1 Mon Sep 17 00:00:00 2001 +From: Jack Wang +Date: Fri, 26 Aug 2022 12:13:35 +0200 +Subject: [PATCH] mailbox: bcm-ferxrm-mailbox: Fix error check for dma_map_sg +Git-commit: 6b207ce8a96a71e966831e3a13c38143ba9a73c1 +Patch-mainline: v6.1-rc1 +References: git-fixes + +dma_map_sg return 0 on error, fix the error check, and return -EIO +to caller. + +Fixes: dbc049eee730 ("mailbox: Add driver for Broadcom FlexRM ring manager") +Signed-off-by: Jack Wang +Signed-off-by: Jassi Brar +Acked-by: Takashi Iwai + +--- + drivers/mailbox/bcm-flexrm-mailbox.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/mailbox/bcm-flexrm-mailbox.c b/drivers/mailbox/bcm-flexrm-mailbox.c +index fda16f76401e..bf6e86b0ed09 100644 +--- a/drivers/mailbox/bcm-flexrm-mailbox.c ++++ b/drivers/mailbox/bcm-flexrm-mailbox.c +@@ -622,15 +622,15 @@ static int flexrm_spu_dma_map(struct device *dev, struct brcm_message *msg) + + rc = dma_map_sg(dev, msg->spu.src, sg_nents(msg->spu.src), + DMA_TO_DEVICE); +- if (rc < 0) +- return rc; ++ if (!rc) ++ return -EIO; + + rc = dma_map_sg(dev, msg->spu.dst, sg_nents(msg->spu.dst), + DMA_FROM_DEVICE); +- if (rc < 0) { ++ if (!rc) { + dma_unmap_sg(dev, msg->spu.src, sg_nents(msg->spu.src), + DMA_TO_DEVICE); +- return rc; ++ return -EIO; + } + + return 0; +-- +2.35.3 + diff --git a/patches.suse/mailbox-mpfs-account-for-mbox-offsets-while-sending.patch b/patches.suse/mailbox-mpfs-account-for-mbox-offsets-while-sending.patch new file mode 100644 index 0000000..bd9a888 --- /dev/null +++ b/patches.suse/mailbox-mpfs-account-for-mbox-offsets-while-sending.patch @@ -0,0 +1,60 @@ +From 0d1aadfe10ba17ebdeb96abb9638eb0f623f9b55 Mon Sep 17 00:00:00 2001 +From: Conor Dooley +Date: Wed, 24 Aug 2022 08:08:12 +0100 +Subject: [PATCH] mailbox: mpfs: account for mbox offsets while sending +Git-commit: 0d1aadfe10ba17ebdeb96abb9638eb0f623f9b55 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The mailbox offset is not only used for receiving messages, but it is +also used by messages sent to the system controller by Linux that have a +payload, such as the "digital signature service". It is also overloaded +by certain other services (reprogramming of the FPGA fabric, see Link:) +to have a meaning other than the offset the system controller should +read from. +When the driver was written, no such services of the latter type were +in use & those of the former used an offset of zero so this has gone +un-noticed. + +Link: https://www.microsemi.com/document-portal/doc_download/1245815-polarfire-fpga-and-polarfire-soc-fpga-system-services-user-guide # Section 5.2 +Fixes: 83d7b1560810 ("mbox: add polarfire soc system controller mailbox") +Signed-off-by: Conor Dooley +Signed-off-by: Jassi Brar +Acked-by: Takashi Iwai + +--- + drivers/mailbox/mailbox-mpfs.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/drivers/mailbox/mailbox-mpfs.c b/drivers/mailbox/mailbox-mpfs.c +index e432a8f0d148..cfacb3f320a6 100644 +--- a/drivers/mailbox/mailbox-mpfs.c ++++ b/drivers/mailbox/mailbox-mpfs.c +@@ -100,21 +100,20 @@ static int mpfs_mbox_send_data(struct mbox_chan *chan, void *data) + + for (index = 0; index < (msg->cmd_data_size / 4); index++) + writel_relaxed(word_buf[index], +- mbox->mbox_base + index * 0x4); ++ mbox->mbox_base + msg->mbox_offset + index * 0x4); + if (extra_bits) { + u8 i; + u8 byte_off = ALIGN_DOWN(msg->cmd_data_size, 4); + u8 *byte_buf = msg->cmd_data + byte_off; + +- val = readl_relaxed(mbox->mbox_base + index * 0x4); ++ val = readl_relaxed(mbox->mbox_base + msg->mbox_offset + index * 0x4); + + for (i = 0u; i < extra_bits; i++) { + val &= ~(0xffu << (i * 8u)); + val |= (byte_buf[i] << (i * 8u)); + } + +- writel_relaxed(val, +- mbox->mbox_base + index * 0x4); ++ writel_relaxed(val, mbox->mbox_base + msg->mbox_offset + index * 0x4); + } + } + +-- +2.35.3 + diff --git a/patches.suse/mailbox-mpfs-fix-handling-of-the-reg-property.patch b/patches.suse/mailbox-mpfs-fix-handling-of-the-reg-property.patch new file mode 100644 index 0000000..bc07508 --- /dev/null +++ b/patches.suse/mailbox-mpfs-fix-handling-of-the-reg-property.patch @@ -0,0 +1,113 @@ +From 2e10289d1f304f5082a4dda55a677b72b3bdb581 Mon Sep 17 00:00:00 2001 +From: Conor Dooley +Date: Wed, 24 Aug 2022 08:08:11 +0100 +Subject: [PATCH] mailbox: mpfs: fix handling of the reg property +Git-commit: 2e10289d1f304f5082a4dda55a677b72b3bdb581 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The "data" region of the PolarFire SoC's system controller mailbox is +not one continuous register space - the system controller's QSPI sits +between the control and data registers. Split the "data" reg into two +Parts: "data" & "control". Optionally get the "data" register address +from the 3rd reg property in the devicetree & fall back to using the +old base + MAILBOX_REG_OFFSET that the current code uses. + +Fixes: 83d7b1560810 ("mbox: add polarfire soc system controller mailbox") +Signed-off-by: Conor Dooley +Signed-off-by: Jassi Brar +Acked-by: Takashi Iwai + +--- + drivers/mailbox/mailbox-mpfs.c | 24 ++++++++++++++---------- + 1 file changed, 14 insertions(+), 10 deletions(-) + +diff --git a/drivers/mailbox/mailbox-mpfs.c b/drivers/mailbox/mailbox-mpfs.c +index 4e34854d1238..e432a8f0d148 100644 +--- a/drivers/mailbox/mailbox-mpfs.c ++++ b/drivers/mailbox/mailbox-mpfs.c +@@ -62,6 +62,7 @@ struct mpfs_mbox { + struct mbox_controller controller; + struct device *dev; + int irq; ++ void __iomem *ctrl_base; + void __iomem *mbox_base; + void __iomem *int_reg; + struct mbox_chan chans[1]; +@@ -73,7 +74,7 @@ static bool mpfs_mbox_busy(struct mpfs_mbox *mbox) + { + u32 status; + +- status = readl_relaxed(mbox->mbox_base + SERVICES_SR_OFFSET); ++ status = readl_relaxed(mbox->ctrl_base + SERVICES_SR_OFFSET); + + return status & SCB_STATUS_BUSY_MASK; + } +@@ -99,14 +100,13 @@ static int mpfs_mbox_send_data(struct mbox_chan *chan, void *data) + + for (index = 0; index < (msg->cmd_data_size / 4); index++) + writel_relaxed(word_buf[index], +- mbox->mbox_base + MAILBOX_REG_OFFSET + index * 0x4); ++ mbox->mbox_base + index * 0x4); + if (extra_bits) { + u8 i; + u8 byte_off = ALIGN_DOWN(msg->cmd_data_size, 4); + u8 *byte_buf = msg->cmd_data + byte_off; + +- val = readl_relaxed(mbox->mbox_base + +- MAILBOX_REG_OFFSET + index * 0x4); ++ val = readl_relaxed(mbox->mbox_base + index * 0x4); + + for (i = 0u; i < extra_bits; i++) { + val &= ~(0xffu << (i * 8u)); +@@ -114,14 +114,14 @@ static int mpfs_mbox_send_data(struct mbox_chan *chan, void *data) + } + + writel_relaxed(val, +- mbox->mbox_base + MAILBOX_REG_OFFSET + index * 0x4); ++ mbox->mbox_base + index * 0x4); + } + } + + opt_sel = ((msg->mbox_offset << 7u) | (msg->cmd_opcode & 0x7fu)); + tx_trigger = (opt_sel << SCB_CTRL_POS) & SCB_CTRL_MASK; + tx_trigger |= SCB_CTRL_REQ_MASK | SCB_STATUS_NOTIFY_MASK; +- writel_relaxed(tx_trigger, mbox->mbox_base + SERVICES_CR_OFFSET); ++ writel_relaxed(tx_trigger, mbox->ctrl_base + SERVICES_CR_OFFSET); + + return 0; + } +@@ -141,7 +141,7 @@ static void mpfs_mbox_rx_data(struct mbox_chan *chan) + if (!mpfs_mbox_busy(mbox)) { + for (i = 0; i < num_words; i++) { + response->resp_msg[i] = +- readl_relaxed(mbox->mbox_base + MAILBOX_REG_OFFSET ++ readl_relaxed(mbox->mbox_base + + mbox->resp_offset + i * 0x4); + } + } +@@ -200,14 +200,18 @@ static int mpfs_mbox_probe(struct platform_device *pdev) + if (!mbox) + return -ENOMEM; + +- mbox->mbox_base = devm_platform_get_and_ioremap_resource(pdev, 0, ®s); +- if (IS_ERR(mbox->mbox_base)) +- return PTR_ERR(mbox->mbox_base); ++ mbox->ctrl_base = devm_platform_get_and_ioremap_resource(pdev, 0, ®s); ++ if (IS_ERR(mbox->ctrl_base)) ++ return PTR_ERR(mbox->ctrl_base); + + mbox->int_reg = devm_platform_get_and_ioremap_resource(pdev, 1, ®s); + if (IS_ERR(mbox->int_reg)) + return PTR_ERR(mbox->int_reg); + ++ mbox->mbox_base = devm_platform_get_and_ioremap_resource(pdev, 2, ®s); ++ if (IS_ERR(mbox->mbox_base)) // account for the old dt-binding w/ 2 regs ++ mbox->mbox_base = mbox->ctrl_base + MAILBOX_REG_OFFSET; ++ + mbox->irq = platform_get_irq(pdev, 0); + if (mbox->irq < 0) + return mbox->irq; +-- +2.35.3 + diff --git a/patches.suse/md-call-__md_stop_writes-in-md_stop.patch b/patches.suse/md-call-__md_stop_writes-in-md_stop.patch new file mode 100644 index 0000000..14ec2ac --- /dev/null +++ b/patches.suse/md-call-__md_stop_writes-in-md_stop.patch @@ -0,0 +1,35 @@ +From: Guoqing Jiang +Date: Wed, 17 Aug 2022 20:05:14 +0800 +Subject: [PATCH] md: call __md_stop_writes in md_stop +Git-commit: 0dd84b319352bb8ba64752d4e45396d8b13e6018 +Patch-mainline: v6.0 +References: git-fixes + +From the link [1], we can see raid1d was running even after the path +raid_dtr -> md_stop -> __md_stop. + +Let's stop write first in destructor to align with normal md-raid to +fix the KASAN issue. + +[1]. https://lore.kernel.org/linux-raid/CAPhsuW5gc4AakdGNdF8ubpezAuDLFOYUO_sfMZcec6hQFm8nhg@mail.gmail.com/T/#m7f12bf90481c02c6d2da68c64aeed4779b7df74a + +Fixes: 48df498daf62 ("md: move bitmap_destroy to the beginning of __md_stop") +Reported-by: Mikulas Patocka +Signed-off-by: Guoqing Jiang +Signed-off-by: Song Liu +Acked-by: NeilBrown + +--- + drivers/md/md.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -6308,6 +6308,7 @@ void md_stop(struct mddev *mddev) + /* stop the array and free an attached data structures. + * This is called from dm-raid + */ ++ __md_stop_writes(mddev); + __md_stop(mddev); + bioset_exit(&mddev->bio_set); + bioset_exit(&mddev->sync_set); diff --git a/patches.suse/md-raid10-fix-KASAN-warning.patch b/patches.suse/md-raid10-fix-KASAN-warning.patch new file mode 100644 index 0000000..c114752 --- /dev/null +++ b/patches.suse/md-raid10-fix-KASAN-warning.patch @@ -0,0 +1,147 @@ +From: Mikulas Patocka +Date: Tue, 26 Jul 2022 04:33:12 -0400 +Subject: [PATCH] md-raid10: fix KASAN warning +Git-commit: d17f744e883b2f8d13cca252d71cfe8ace346f7d +Patch-mainline: v6.0 +References: git-fixes + +There's a KASAN warning in raid10_remove_disk when running the lvm +test lvconvert-raid-reshape.sh. We fix this warning by verifying that the +value "number" is valid. + +Bug: KASAN: slab-out-of-bounds in raid10_remove_disk+0x61/0x2a0 [raid10] +Read of size 8 at addr ffff889108f3d300 by task mdX_raid10/124682 + +Cpu: 3 PID: 124682 Comm: mdX_raid10 Not tainted 5.19.0-rc6 #1 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014 +Call Trace: + + dump_stack_lvl+0x34/0x44 + print_report.cold+0x45/0x57a + ? __lock_text_start+0x18/0x18 + ? raid10_remove_disk+0x61/0x2a0 [raid10] + kasan_report+0xa8/0xe0 + ? raid10_remove_disk+0x61/0x2a0 [raid10] + raid10_remove_disk+0x61/0x2a0 [raid10] +Buffer I/O error on dev dm-76, logical block 15344, async page read + ? __mutex_unlock_slowpath.constprop.0+0x1e0/0x1e0 + remove_and_add_spares+0x367/0x8a0 [md_mod] + ? super_written+0x1c0/0x1c0 [md_mod] + ? mutex_trylock+0xac/0x120 + ? _raw_spin_lock+0x72/0xc0 + ? _raw_spin_lock_bh+0xc0/0xc0 + md_check_recovery+0x848/0x960 [md_mod] + raid10d+0xcf/0x3360 [raid10] + ? sched_clock_cpu+0x185/0x1a0 + ? rb_erase+0x4d4/0x620 + ? var_wake_function+0xe0/0xe0 + ? psi_group_change+0x411/0x500 + ? preempt_count_sub+0xf/0xc0 + ? _raw_spin_lock_irqsave+0x78/0xc0 + ? __lock_text_start+0x18/0x18 + ? raid10_sync_request+0x36c0/0x36c0 [raid10] + ? preempt_count_sub+0xf/0xc0 + ? _raw_spin_unlock_irqrestore+0x19/0x40 + ? del_timer_sync+0xa9/0x100 + ? try_to_del_timer_sync+0xc0/0xc0 + ? _raw_spin_lock_irqsave+0x78/0xc0 + ? __lock_text_start+0x18/0x18 + ? _raw_spin_unlock_irq+0x11/0x24 + ? __list_del_entry_valid+0x68/0xa0 + ? finish_wait+0xa3/0x100 + md_thread+0x161/0x260 [md_mod] + ? unregister_md_personality+0xa0/0xa0 [md_mod] + ? _raw_spin_lock_irqsave+0x78/0xc0 + ? prepare_to_wait_event+0x2c0/0x2c0 + ? unregister_md_personality+0xa0/0xa0 [md_mod] + kthread+0x148/0x180 + ? kthread_complete_and_exit+0x20/0x20 + ret_from_fork+0x1f/0x30 + + +Allocated by task 124495: + kasan_save_stack+0x1e/0x40 + __kasan_kmalloc+0x80/0xa0 + setup_conf+0x140/0x5c0 [raid10] + raid10_run+0x4cd/0x740 [raid10] + md_run+0x6f9/0x1300 [md_mod] + raid_ctr+0x2531/0x4ac0 [dm_raid] + dm_table_add_target+0x2b0/0x620 [dm_mod] + table_load+0x1c8/0x400 [dm_mod] + ctl_ioctl+0x29e/0x560 [dm_mod] + dm_compat_ctl_ioctl+0x7/0x20 [dm_mod] + __do_compat_sys_ioctl+0xfa/0x160 + do_syscall_64+0x90/0xc0 + entry_SYSCALL_64_after_hwframe+0x46/0xb0 + +Last potentially related work creation: + kasan_save_stack+0x1e/0x40 + __kasan_record_aux_stack+0x9e/0xc0 + kvfree_call_rcu+0x84/0x480 + timerfd_release+0x82/0x140 +L __fput+0xfa/0x400 + task_work_run+0x80/0xc0 + exit_to_user_mode_prepare+0x155/0x160 + syscall_exit_to_user_mode+0x12/0x40 + do_syscall_64+0x42/0xc0 + entry_SYSCALL_64_after_hwframe+0x46/0xb0 + +Second to last potentially related work creation: + kasan_save_stack+0x1e/0x40 + __kasan_record_aux_stack+0x9e/0xc0 + kvfree_call_rcu+0x84/0x480 + timerfd_release+0x82/0x140 + __fput+0xfa/0x400 + task_work_run+0x80/0xc0 + exit_to_user_mode_prepare+0x155/0x160 + syscall_exit_to_user_mode+0x12/0x40 + do_syscall_64+0x42/0xc0 + entry_SYSCALL_64_after_hwframe+0x46/0xb0 + +The buggy address belongs to the object at ffff889108f3d200 + which belongs to the cache kmalloc-256 of size 256 +The buggy address is located 0 bytes to the right of + 256-byte region [ffff889108f3d200, ffff889108f3d300) + +The buggy address belongs to the physical page: +page:000000007ef2a34c refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x1108f3c +head:000000007ef2a34c order:2 compound_mapcount:0 compound_pincount:0 +Flags: 0x4000000000010200(slab|head|zone=2) +Raw: 4000000000010200 0000000000000000 dead000000000001 ffff889100042b40 +Raw: 0000000000000000 0000000080200020 00000001ffffffff 0000000000000000 +page dumped because: kasan: bad access detected + +Memory state around the buggy address: + ffff889108f3d200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + ffff889108f3d280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +>ffff889108f3d300: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc + ^ + ffff889108f3d380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc + ffff889108f3d400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + +Signed-off-by: Mikulas Patocka +Cc: stable@vger.kernel.org +Signed-off-by: Song Liu +Signed-off-by: Jens Axboe +Acked-by: NeilBrown + +--- + drivers/md/raid10.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/md/raid10.c ++++ b/drivers/md/raid10.c +@@ -2151,9 +2151,12 @@ static int raid10_remove_disk(struct mdd + int err = 0; + int number = rdev->raid_disk; + struct md_rdev **rdevp; +- struct raid10_info *p = conf->mirrors + number; ++ struct raid10_info *p; + + print_conf(conf); ++ if (unlikely(number >= mddev->raid_disks)) ++ return 0; ++ p = conf->mirrors + number; + if (rdev == p->rdev) + rdevp = &p->rdev; + else if (rdev == p->replacement) diff --git a/patches.suse/md-unlock-mddev-before-reap-sync_thread-in-action_st.patch b/patches.suse/md-unlock-mddev-before-reap-sync_thread-in-action_st.patch new file mode 100644 index 0000000..e5fa7d1 --- /dev/null +++ b/patches.suse/md-unlock-mddev-before-reap-sync_thread-in-action_st.patch @@ -0,0 +1,101 @@ +From 9dfbdafda3b34e262e43e786077bab8e476a89d1 Mon Sep 17 00:00:00 2001 +From: Guoqing Jiang +Date: Tue, 21 Jun 2022 11:11:29 +0800 +Subject: [PATCH] md: unlock mddev before reap sync_thread in action_store +Git-commit: 9dfbdafda3b34e262e43e786077bab8e476a89d1 +Patch-mainline: v6.0-rc1 +References: bsc#1197659 + +Since the bug which commit 8b48ec23cc51a ("md: don't unregister sync_thread +with reconfig_mutex held") fixed is related with action_store path, other +callers which reap sync_thread didn't need to be changed. + +Let's pull md_unregister_thread from md_reap_sync_thread, then fix previous +bug with belows. + +1. unlock mddev before md_reap_sync_thread in action_store. +2. save reshape_position before unlock, then restore it to ensure position + not changed accidentally by others. + +Signed-off-by: Guoqing Jiang +Signed-off-by: Song Liu +Signed-off-by: Jens Axboe +Signed-off-by: Coly Li +--- + drivers/md/dm-raid.c | 1 + + drivers/md/md.c | 19 +++++++++++++++++-- + 2 files changed, 18 insertions(+), 2 deletions(-) + +diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c +index 1ec17c32867f..c640be453313 100644 +--- a/drivers/md/dm-raid.c ++++ b/drivers/md/dm-raid.c +@@ -3728,6 +3728,7 @@ static int raid_message(struct dm_target *ti, unsigned int argc, char **argv, + if (!strcasecmp(argv[0], "idle") || !strcasecmp(argv[0], "frozen")) { + if (mddev->sync_thread) { + set_bit(MD_RECOVERY_INTR, &mddev->recovery); ++ md_unregister_thread(&mddev->sync_thread); + md_reap_sync_thread(mddev); + } + } else if (decipher_sync_action(mddev, mddev->recovery) != st_idle) +diff --git a/drivers/md/md.c b/drivers/md/md.c +index f511f183aca6..7bc967131ac5 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -4830,6 +4830,19 @@ action_store(struct mddev *mddev, const char *page, size_t len) + if (work_pending(&mddev->del_work)) + flush_workqueue(md_misc_wq); + if (mddev->sync_thread) { ++ sector_t save_rp = mddev->reshape_position; ++ ++ mddev_unlock(mddev); ++ set_bit(MD_RECOVERY_INTR, &mddev->recovery); ++ md_unregister_thread(&mddev->sync_thread); ++ mddev_lock_nointr(mddev); ++ /* ++ * set RECOVERY_INTR again and restore reshape ++ * position in case others changed them after ++ * got lock, eg, reshape_position_store and ++ * md_check_recovery. ++ */ ++ mddev->reshape_position = save_rp; + set_bit(MD_RECOVERY_INTR, &mddev->recovery); + md_reap_sync_thread(mddev); + } +@@ -6197,6 +6210,7 @@ static void __md_stop_writes(struct mddev *mddev) + flush_workqueue(md_misc_wq); + if (mddev->sync_thread) { + set_bit(MD_RECOVERY_INTR, &mddev->recovery); ++ md_unregister_thread(&mddev->sync_thread); + md_reap_sync_thread(mddev); + } + +@@ -9309,6 +9323,7 @@ void md_check_recovery(struct mddev *mddev) + * ->spare_active and clear saved_raid_disk + */ + set_bit(MD_RECOVERY_INTR, &mddev->recovery); ++ md_unregister_thread(&mddev->sync_thread); + md_reap_sync_thread(mddev); + clear_bit(MD_RECOVERY_RECOVER, &mddev->recovery); + clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery); +@@ -9344,6 +9359,7 @@ void md_check_recovery(struct mddev *mddev) + goto unlock; + } + if (mddev->sync_thread) { ++ md_unregister_thread(&mddev->sync_thread); + md_reap_sync_thread(mddev); + goto unlock; + } +@@ -9423,8 +9439,7 @@ void md_reap_sync_thread(struct mddev *mddev) + sector_t old_dev_sectors = mddev->dev_sectors; + bool is_reshaped = false; + +- /* resync has finished, collect result */ +- md_unregister_thread(&mddev->sync_thread); ++ /* sync_thread should be unregistered, collect result */ + if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery) && + !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery) && + mddev->degraded != mddev->raid_disks) { +-- +2.35.3 + diff --git a/patches.suse/media-aspeed-Fix-an-error-handling-path-in-aspeed_vi.patch b/patches.suse/media-aspeed-Fix-an-error-handling-path-in-aspeed_vi.patch new file mode 100644 index 0000000..0aa38bf --- /dev/null +++ b/patches.suse/media-aspeed-Fix-an-error-handling-path-in-aspeed_vi.patch @@ -0,0 +1,51 @@ +From 310fda622bbd38be17fb444f7f049b137af3bc0d Mon Sep 17 00:00:00 2001 +From: Christophe JAILLET +Date: Sun, 6 Mar 2022 19:08:07 +0100 +Subject: [PATCH] media: aspeed: Fix an error handling path in + aspeed_video_probe() +Git-commit: 310fda622bbd38be17fb444f7f049b137af3bc0d +References: git-fixes +Patch-mainline: v5.19-rc1 + +A dma_free_coherent() call is missing in the error handling path of the +probe, as already done in the remove function. + +In fact, this call is included in aspeed_video_free_buf(). So use the +latter both in the error handling path of the probe and in the remove +function. +It is easier to see the relation with aspeed_video_alloc_buf() this way. + +Fixes: d2b4387f3bdf ("media: platform: Add Aspeed Video Engine driver") +Signed-off-by: Christophe JAILLET +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Oliver Neukum +--- + drivers/media/platform/aspeed/aspeed-video.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/media/platform/aspeed/aspeed-video.c b/drivers/media/platform/aspeed/aspeed-video.c +index b937dbcbe9e0..20f795ccc11b 100644 +--- a/drivers/media/platform/aspeed-video.c ++++ b/drivers/media/platform/aspeed-video.c +@@ -1993,6 +1993,7 @@ static int aspeed_video_probe(struct platform_device *pdev) + + rc = aspeed_video_setup_video(video); + if (rc) { ++ aspeed_video_free_buf(video, &video->jpeg); + clk_unprepare(video->vclk); + clk_unprepare(video->eclk); + return rc; +@@ -2024,8 +2025,7 @@ static int aspeed_video_remove(struct platform_device *pdev) + + v4l2_device_unregister(v4l2_dev); + +- dma_free_coherent(video->dev, VE_JPEG_HEADER_SIZE, video->jpeg.virt, +- video->jpeg.dma); ++ aspeed_video_free_buf(video, &video->jpeg); + + of_reserved_mem_device_release(dev); + +-- +2.35.3 + diff --git a/patches.suse/media-cedrus-Fix-endless-loop-in-cedrus_h265_skip_bi.patch b/patches.suse/media-cedrus-Fix-endless-loop-in-cedrus_h265_skip_bi.patch new file mode 100644 index 0000000..3188081 --- /dev/null +++ b/patches.suse/media-cedrus-Fix-endless-loop-in-cedrus_h265_skip_bi.patch @@ -0,0 +1,46 @@ +From 91db7a3fc7fe670cf1770a398a43bb4a1f776bf1 Mon Sep 17 00:00:00 2001 +From: Dmitry Osipenko +Date: Thu, 18 Aug 2022 22:33:08 +0200 +Subject: [PATCH] media: cedrus: Fix endless loop in cedrus_h265_skip_bits() +Git-commit: 91db7a3fc7fe670cf1770a398a43bb4a1f776bf1 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The busy status bit may never de-assert if number of programmed skip +bits is incorrect, resulting in a kernel hang because the bit is polled +endlessly in the code. Fix it by adding timeout for the bit-polling. +This problem is reproducible by setting the data_bit_offset field of +the HEVC slice params to a wrong value by userspace. + +Cc: stable@vger.kernel.org +Fixes: 7678c5462680 (media: cedrus: Fix decoding for some HEVC videos) +Reported-by: Nicolas Dufresne +Signed-off-by: Dmitry Osipenko +Signed-off-by: Nicolas Dufresne +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Acked-by: Takashi Iwai + +--- + drivers/staging/media/sunxi/cedrus/cedrus_h265.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c +index f703c585d91c..4952fc17f3e6 100644 +--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c ++++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c +@@ -234,8 +234,9 @@ static void cedrus_h265_skip_bits(struct cedrus_dev *dev, int num) + cedrus_write(dev, VE_DEC_H265_TRIGGER, + VE_DEC_H265_TRIGGER_FLUSH_BITS | + VE_DEC_H265_TRIGGER_TYPE_N_BITS(tmp)); +- while (cedrus_read(dev, VE_DEC_H265_STATUS) & VE_DEC_H265_STATUS_VLD_BUSY) +- udelay(1); ++ ++ if (cedrus_wait_for(dev, VE_DEC_H265_STATUS, VE_DEC_H265_STATUS_VLD_BUSY)) ++ dev_err_ratelimited(dev->dev, "timed out waiting to skip bits\n"); + + count += tmp; + } +-- +2.35.3 + diff --git a/patches.suse/media-cedrus-Set-the-platform-driver-data-earlier.patch b/patches.suse/media-cedrus-Set-the-platform-driver-data-earlier.patch new file mode 100644 index 0000000..b5b5736 --- /dev/null +++ b/patches.suse/media-cedrus-Set-the-platform-driver-data-earlier.patch @@ -0,0 +1,51 @@ +From 708938f8495147fe2e77a9a3e1015d8e6899323e Mon Sep 17 00:00:00 2001 +From: Dmitry Osipenko +Date: Thu, 18 Aug 2022 22:33:07 +0200 +Subject: [PATCH] media: cedrus: Set the platform driver data earlier +Git-commit: 708938f8495147fe2e77a9a3e1015d8e6899323e +Patch-mainline: v6.1-rc1 +References: git-fixes + +The cedrus_hw_resume() crashes with NULL deference on driver probe if +runtime PM is disabled because it uses platform data that hasn't been +set up yet. Fix this by setting the platform data earlier during probe. + +Cc: stable@vger.kernel.org +Fixes: 50e761516f2b (media: platform: Add Cedrus VPU decoder driver) +Signed-off-by: Dmitry Osipenko +Signed-off-by: Nicolas Dufresne +Reviewed-by: Samuel Holland +Acked-by: Paul Kocialkowski +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Acked-by: Takashi Iwai + +--- + drivers/staging/media/sunxi/cedrus/cedrus.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c +index 960a0130cd62..55c54dfdc585 100644 +--- a/drivers/staging/media/sunxi/cedrus/cedrus.c ++++ b/drivers/staging/media/sunxi/cedrus/cedrus.c +@@ -448,6 +448,8 @@ static int cedrus_probe(struct platform_device *pdev) + if (!dev) + return -ENOMEM; + ++ platform_set_drvdata(pdev, dev); ++ + dev->vfd = cedrus_video_device; + dev->dev = &pdev->dev; + dev->pdev = pdev; +@@ -521,8 +523,6 @@ static int cedrus_probe(struct platform_device *pdev) + goto err_m2m_mc; + } + +- platform_set_drvdata(pdev, dev); +- + return 0; + + err_m2m_mc: +-- +2.35.3 + diff --git a/patches.suse/media-coda-Add-more-H264-levels-for-CODA960.patch b/patches.suse/media-coda-Add-more-H264-levels-for-CODA960.patch new file mode 100644 index 0000000..fb54571 --- /dev/null +++ b/patches.suse/media-coda-Add-more-H264-levels-for-CODA960.patch @@ -0,0 +1,55 @@ +From eb2fd187abc878a2dfad46902becb74963473c7d Mon Sep 17 00:00:00 2001 +From: Nicolas Dufresne +Date: Wed, 6 Apr 2022 21:23:43 +0100 +Subject: [PATCH] media: coda: Add more H264 levels for CODA960 +Git-commit: eb2fd187abc878a2dfad46902becb74963473c7d +References: git-fixes +Patch-mainline: v5.19-rc1 + +Add H264 level 1.0, 4.1, 4.2 to the list of supported formats. +While the hardware does not fully support these levels, it does support +most of them. The constraints on frame size and pixel formats already +cover the limitation. + +This fixes negotiation of level on GStreamer 1.17.1. + +Cc: stable@vger.kernel.org +Fixes: 42a68012e67c2 ("media: coda: add read-only h.264 decoder profile/level controls") +Suggested-by: Philipp Zabel +Signed-off-by: Nicolas Dufresne +Signed-off-by: Ezequiel Garcia +Signed-off-by: Fabio Estevam +Reviewed-by: Philipp Zabel +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Oliver Neukum +--- + drivers/media/platform/chips-media/coda-common.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/media/platform/chips-media/coda-common.c b/drivers/media/platform/chips-media/coda-common.c +index 36ec5a50a491..d246afcb3f49 100644 +--- a/drivers/media/platform/coda/coda-common.c ++++ b/drivers/media/platform/coda/coda-common.c +@@ -2347,12 +2347,15 @@ static void coda_encode_ctrls(struct coda_ctx *ctx) + if (ctx->dev->devtype->product == CODA_960) { + v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, + V4L2_CID_MPEG_VIDEO_H264_LEVEL, +- V4L2_MPEG_VIDEO_H264_LEVEL_4_0, +- ~((1 << V4L2_MPEG_VIDEO_H264_LEVEL_2_0) | ++ V4L2_MPEG_VIDEO_H264_LEVEL_4_2, ++ ~((1 << V4L2_MPEG_VIDEO_H264_LEVEL_1_0) | ++ (1 << V4L2_MPEG_VIDEO_H264_LEVEL_2_0) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_3_0) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_3_1) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_3_2) | +- (1 << V4L2_MPEG_VIDEO_H264_LEVEL_4_0)), ++ (1 << V4L2_MPEG_VIDEO_H264_LEVEL_4_0) | ++ (1 << V4L2_MPEG_VIDEO_H264_LEVEL_4_1) | ++ (1 << V4L2_MPEG_VIDEO_H264_LEVEL_4_2)), + V4L2_MPEG_VIDEO_H264_LEVEL_4_0); + } + v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, +-- +2.35.3 + diff --git a/patches.suse/media-coda-Fix-reported-H264-profile.patch b/patches.suse/media-coda-Fix-reported-H264-profile.patch new file mode 100644 index 0000000..72bf5c7 --- /dev/null +++ b/patches.suse/media-coda-Fix-reported-H264-profile.patch @@ -0,0 +1,60 @@ +From 7110c08ea71953a7fc342f0b76046f72442cf26c Mon Sep 17 00:00:00 2001 +From: Nicolas Dufresne +Date: Wed, 6 Apr 2022 21:23:42 +0100 +Subject: [PATCH] media: coda: Fix reported H264 profile +Git-commit: 7110c08ea71953a7fc342f0b76046f72442cf26c +References: git-fixes +Patch-mainline: v5.19-rc1 + +The CODA960 manual states that ASO/FMO features of baseline are not +supported, so for this reason this driver should only report +constrained baseline support. + +This fixes negotiation issue with constrained baseline content +on GStreamer 1.17.1. + +ASO/FMO features are unsupported for the encoder and untested for the +decoder because there is currently no userspace support. Neither GStreamer +parsers nor FFMPEG parsers support ASO/FMO. + +Cc: stable@vger.kernel.org +Fixes: 42a68012e67c2 ("media: coda: add read-only h.264 decoder profile/level controls") +Signed-off-by: Nicolas Dufresne +Signed-off-by: Ezequiel Garcia +Tested-by: Pascal Speck +Signed-off-by: Fabio Estevam +Reviewed-by: Philipp Zabel +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Oliver Neukum +--- + drivers/media/platform/chips-media/coda-common.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/media/platform/chips-media/coda-common.c b/drivers/media/platform/chips-media/coda-common.c +index 7b4942bb6c2c..36ec5a50a491 100644 +--- a/drivers/media/platform/coda/coda-common.c ++++ b/drivers/media/platform/coda/coda-common.c +@@ -2332,8 +2332,8 @@ static void coda_encode_ctrls(struct coda_ctx *ctx) + V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET, -12, 12, 1, 0); + v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, + V4L2_CID_MPEG_VIDEO_H264_PROFILE, +- V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE, 0x0, +- V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE); ++ V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE, 0x0, ++ V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE); + if (ctx->dev->devtype->product == CODA_HX4 || + ctx->dev->devtype->product == CODA_7541) { + v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, +@@ -2414,7 +2414,7 @@ static void coda_decode_ctrls(struct coda_ctx *ctx) + ctx->h264_profile_ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrls, + &coda_ctrl_ops, V4L2_CID_MPEG_VIDEO_H264_PROFILE, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, +- ~((1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) | ++ ~((1 << V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) | + (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) | + (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)), + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH); +-- +2.35.3 + diff --git a/patches.suse/media-dvb-core-Fix-UAF-due-to-refcount-races-at-rele.patch b/patches.suse/media-dvb-core-Fix-UAF-due-to-refcount-races-at-rele.patch new file mode 100644 index 0000000..ce930ca --- /dev/null +++ b/patches.suse/media-dvb-core-Fix-UAF-due-to-refcount-races-at-rele.patch @@ -0,0 +1,68 @@ +From: Takashi Iwai +Date: Wed, 7 Sep 2022 13:13:07 +0200 +Subject: [PATCH] media: dvb-core: Fix UAF due to refcount races at releasing +Message-Id: <20220908132754.30532-1-tiwai@suse.de> +Patch-mainline: Submitted, linux-media ML +References: CVE-2022-41218 bsc#1202960 + +The dvb-core tries to sync the releases of opened files at +dvb_dmxdev_release() with two refcounts: dvbdev->users and +dvr_dvbdev->users. A problem is present in those two syncs: when yet +another dvb_demux_open() is called during those sync waits, +dvb_demux_open() continues to process even if the device is being +closed. This includes the increment of the former refcount, resulting +in the leftover refcount after the sync of the latter refcount at +dvb_dmxdev_release(). It ends up with use-after-free, since the +function believes that all usages were gone and releases the +resources. + +This patch addresses the problem by adding the check of dmxdev->exit +flag at dvb_demux_open(), just like dvb_dvr_open() already does. With +the exit flag check, the second call of dvb_demux_open() fails, hence +the further corruption can be avoided. + +Also for avoiding the races of the dmxdev->exit flag reference, this +patch serializes the dmxdev->exit set up and the sync waits with the +dmxdev->mutex lock at dvb_dmxdev_release(). Without the mutex lock, +dvb_demux_open() (or dvb_dvr_open()) may run concurrently with +dvb_dmxdev_release(), which allows to skip the exit flag check and +continue the open process that is being closed. + +Reported-by: Hyunwoo Kim +Cc: +Signed-off-by: Takashi Iwai + +--- + drivers/media/dvb-core/dmxdev.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c +index f6ee678107d3..9ce5f010de3f 100644 +--- a/drivers/media/dvb-core/dmxdev.c ++++ b/drivers/media/dvb-core/dmxdev.c +@@ -790,6 +790,11 @@ static int dvb_demux_open(struct inode *inode, struct file *file) + if (mutex_lock_interruptible(&dmxdev->mutex)) + return -ERESTARTSYS; + ++ if (dmxdev->exit) { ++ mutex_unlock(&dmxdev->mutex); ++ return -ENODEV; ++ } ++ + for (i = 0; i < dmxdev->filternum; i++) + if (dmxdev->filter[i].state == DMXDEV_STATE_FREE) + break; +@@ -1448,7 +1453,10 @@ EXPORT_SYMBOL(dvb_dmxdev_init); + + void dvb_dmxdev_release(struct dmxdev *dmxdev) + { ++ mutex_lock(&dmxdev->mutex); + dmxdev->exit = 1; ++ mutex_unlock(&dmxdev->mutex); ++ + if (dmxdev->dvbdev->users > 1) { + wait_event(dmxdev->dvbdev->wait_queue, + dmxdev->dvbdev->users == 1); +-- +2.35.3 + diff --git a/patches.suse/media-dvb_vb2-fix-possible-out-of-bound-access.patch b/patches.suse/media-dvb_vb2-fix-possible-out-of-bound-access.patch new file mode 100644 index 0000000..e69b567 --- /dev/null +++ b/patches.suse/media-dvb_vb2-fix-possible-out-of-bound-access.patch @@ -0,0 +1,58 @@ +From 37238699073e7e93f05517e529661151173cd458 Mon Sep 17 00:00:00 2001 +From: Hangyu Hua +Date: Thu, 19 May 2022 03:17:43 +0100 +Subject: [PATCH] media: dvb_vb2: fix possible out of bound access +Git-commit: 37238699073e7e93f05517e529661151173cd458 +Patch-mainline: v6.0 +References: git-fixes + +vb2_core_qbuf and vb2_core_querybuf don't check the range of b->index +controlled by the user. + +Fix this by adding range checking code before using them. + +Fixes: 57868acc369a ("media: videobuf2: Add new uAPI for DVB streaming I/O") +Signed-off-by: Hangyu Hua +Reviewed-by: Sergey Senozhatsky +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Acked-by: Takashi Iwai + +--- + drivers/media/dvb-core/dvb_vb2.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/drivers/media/dvb-core/dvb_vb2.c b/drivers/media/dvb-core/dvb_vb2.c +index a1bd6d9c9223..909df82fed33 100644 +--- a/drivers/media/dvb-core/dvb_vb2.c ++++ b/drivers/media/dvb-core/dvb_vb2.c +@@ -354,6 +354,12 @@ int dvb_vb2_reqbufs(struct dvb_vb2_ctx *ctx, struct dmx_requestbuffers *req) + + int dvb_vb2_querybuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b) + { ++ struct vb2_queue *q = &ctx->vb_q; ++ ++ if (b->index >= q->num_buffers) { ++ dprintk(1, "[%s] buffer index out of range\n", ctx->name); ++ return -EINVAL; ++ } + vb2_core_querybuf(&ctx->vb_q, b->index, b); + dprintk(3, "[%s] index=%d\n", ctx->name, b->index); + return 0; +@@ -378,8 +384,13 @@ int dvb_vb2_expbuf(struct dvb_vb2_ctx *ctx, struct dmx_exportbuffer *exp) + + int dvb_vb2_qbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b) + { ++ struct vb2_queue *q = &ctx->vb_q; + int ret; + ++ if (b->index >= q->num_buffers) { ++ dprintk(1, "[%s] buffer index out of range\n", ctx->name); ++ return -EINVAL; ++ } + ret = vb2_core_qbuf(&ctx->vb_q, b->index, b, NULL); + if (ret) { + dprintk(1, "[%s] index=%d errno=%d\n", ctx->name, +-- +2.35.3 + diff --git a/patches.suse/media-em28xx-initialize-refcount-before-kref_get.patch b/patches.suse/media-em28xx-initialize-refcount-before-kref_get.patch index 309e2be..d133adf 100644 --- a/patches.suse/media-em28xx-initialize-refcount-before-kref_get.patch +++ b/patches.suse/media-em28xx-initialize-refcount-before-kref_get.patch @@ -4,7 +4,7 @@ Date: Sat, 22 Jan 2022 15:44:59 +0800 Subject: [PATCH] media: em28xx: initialize refcount before kref_get Git-commit: c08eadca1bdfa099e20a32f8fa4b52b2f672236d Patch-mainline: v5.18-rc1 -References: git-fixes +References: CVE-2022-3239 bsc#1203552 git-fixes The commit 47677e51e2a4("[media] em28xx: Only deallocate struct em28xx after finishing all extensions") adds kref_get to many init diff --git a/patches.suse/media-exynos4-is-Change-clk_disable-to-clk_disable_u.patch b/patches.suse/media-exynos4-is-Change-clk_disable-to-clk_disable_u.patch new file mode 100644 index 0000000..b66bcb3 --- /dev/null +++ b/patches.suse/media-exynos4-is-Change-clk_disable-to-clk_disable_u.patch @@ -0,0 +1,39 @@ +From 9fadab72a6916c7507d7fedcd644859eef995078 Mon Sep 17 00:00:00 2001 +From: Miaoqian Lin +Date: Fri, 18 Mar 2022 12:01:01 +0100 +Subject: [PATCH] media: exynos4-is: Change clk_disable to + clk_disable_unprepare +Git-commit: 9fadab72a6916c7507d7fedcd644859eef995078 +References: git-fixes +Patch-mainline: v5.19-rc1 + +The corresponding API for clk_prepare_enable is clk_disable_unprepare, +other than clk_disable. + +Fix this by changing clk_disable to clk_disable_unprepare. + +Fixes: b4155d7d5b2c ("[media] exynos4-is: Ensure fimc-is clocks are not enabled until properly configured") +Signed-off-by: Miaoqian Lin +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Oliver Neukum +--- + drivers/media/platform/samsung/exynos4-is/fimc-is.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-is.c b/drivers/media/platform/samsung/exynos4-is/fimc-is.c +index 81b290dace3a..e3072d69c49f 100644 +--- a/drivers/media/platform/exynos4-is/fimc-is.c ++++ b/drivers/media/platform/exynos4-is/fimc-is.c +@@ -140,7 +140,7 @@ static int fimc_is_enable_clocks(struct fimc_is *is) + dev_err(&is->pdev->dev, "clock %s enable failed\n", + fimc_is_clocks[i]); + for (--i; i >= 0; i--) +- clk_disable(is->clocks[i]); ++ clk_disable_unprepare(is->clocks[i]); + return ret; + } + pr_debug("enabled clock: %s\n", fimc_is_clocks[i]); +-- +2.35.3 + diff --git a/patches.suse/media-exynos4-is-Fix-PM-disable-depth-imbalance-in-f.patch b/patches.suse/media-exynos4-is-Fix-PM-disable-depth-imbalance-in-f.patch new file mode 100644 index 0000000..88a3a00 --- /dev/null +++ b/patches.suse/media-exynos4-is-Fix-PM-disable-depth-imbalance-in-f.patch @@ -0,0 +1,48 @@ +From 5c0db68ce0faeb000c3540d095eb272d671a6e03 Mon Sep 17 00:00:00 2001 +From: Miaoqian Lin +Date: Mon, 7 Mar 2022 08:52:06 +0100 +Subject: [PATCH] media: exynos4-is: Fix PM disable depth imbalance in + fimc_is_probe +Git-commit: 5c0db68ce0faeb000c3540d095eb272d671a6e03 +References: git-fixes +Patch-mainline: v5.19-rc1 + +If probe fails then we need to call pm_runtime_disable() to balance +out the previous pm_runtime_enable() call. + +Fixes: 9a761e436843 ("[media] exynos4-is: Add Exynos4x12 FIMC-IS driver") +Signed-off-by: Miaoqian Lin +Reviewed-by: Krzysztof Kozlowski +Reviewed-by: Alim Akhtar +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Oliver Neukum +--- + drivers/media/platform/samsung/exynos4-is/fimc-is.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-is.c b/drivers/media/platform/samsung/exynos4-is/fimc-is.c +index e55e411038f4..81b290dace3a 100644 +--- a/drivers/media/platform/exynos4-is/fimc-is.c ++++ b/drivers/media/platform/exynos4-is/fimc-is.c +@@ -830,7 +830,7 @@ static int fimc_is_probe(struct platform_device *pdev) + + ret = pm_runtime_resume_and_get(dev); + if (ret < 0) +- goto err_irq; ++ goto err_pm_disable; + + vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32)); + +@@ -864,6 +864,8 @@ static int fimc_is_probe(struct platform_device *pdev) + pm_runtime_put_noidle(dev); + if (!pm_runtime_enabled(dev)) + fimc_is_runtime_suspend(dev); ++err_pm_disable: ++ pm_runtime_disable(dev); + err_irq: + free_irq(is->irq, is); + err_clk: +-- +2.35.3 + diff --git a/patches.suse/media-flexcop-usb-fix-endpoint-type-check.patch b/patches.suse/media-flexcop-usb-fix-endpoint-type-check.patch new file mode 100644 index 0000000..dd3f658 --- /dev/null +++ b/patches.suse/media-flexcop-usb-fix-endpoint-type-check.patch @@ -0,0 +1,44 @@ +From 763679f0eeff0185fc431498849bbc1c24460875 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 22 Aug 2022 17:10:27 +0200 +Subject: [PATCH] media: flexcop-usb: fix endpoint type check +Git-commit: 763679f0eeff0185fc431498849bbc1c24460875 +Patch-mainline: v6.0-rc7 +References: git-fixes + +Commit d725d20e81c2 ("media: flexcop-usb: sanity checking of endpoint +type") tried to add an endpoint type sanity check for the single +isochronous endpoint but instead broke the driver by checking the wrong +descriptor or random data beyond the last endpoint descriptor. + +Make sure to check the right endpoint descriptor. + +Fixes: d725d20e81c2 ("media: flexcop-usb: sanity checking of endpoint type") +Cc: Oliver Neukum +Cc: stable@vger.kernel.org # 5.9 +Reported-by: Dongliang Mu +Signed-off-by: Johan Hovold +Link: https://lore.kernel.org/r/20220822151027.27026-1-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/media/usb/b2c2/flexcop-usb.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/media/usb/b2c2/flexcop-usb.c b/drivers/media/usb/b2c2/flexcop-usb.c +index 7835bb0f32fc..e012b21c4fd7 100644 +--- a/drivers/media/usb/b2c2/flexcop-usb.c ++++ b/drivers/media/usb/b2c2/flexcop-usb.c +@@ -511,7 +511,7 @@ static int flexcop_usb_init(struct flexcop_usb *fc_usb) + + if (fc_usb->uintf->cur_altsetting->desc.bNumEndpoints < 1) + return -ENODEV; +- if (!usb_endpoint_is_isoc_in(&fc_usb->uintf->cur_altsetting->endpoint[1].desc)) ++ if (!usb_endpoint_is_isoc_in(&fc_usb->uintf->cur_altsetting->endpoint[0].desc)) + return -ENODEV; + + switch (fc_usb->udev->speed) { +-- +2.35.3 + diff --git a/patches.suse/media-imx-jpeg-Add-pm-sleep-support-for-imx-jpeg.patch b/patches.suse/media-imx-jpeg-Add-pm-sleep-support-for-imx-jpeg.patch new file mode 100644 index 0000000..d2fcae7 --- /dev/null +++ b/patches.suse/media-imx-jpeg-Add-pm-sleep-support-for-imx-jpeg.patch @@ -0,0 +1,60 @@ +From 7aa65a75f894a2974422fe2bc8281295310f7eb6 Mon Sep 17 00:00:00 2001 +From: Ming Qian +Date: Wed, 6 Apr 2022 10:47:03 +0100 +Subject: [PATCH] media: imx-jpeg: Add pm-sleep support for imx-jpeg +Git-commit: 7aa65a75f894a2974422fe2bc8281295310f7eb6 +References: git-fixes +Patch-mainline: v5.19-rc1 + +Wait finishing jpeg job before system sleep, +otherwise the encoding/decoding can't be resumed after suspend. + +Signed-off-by: Ming Qian +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Oliver Neukum +--- + .../media/platform/nxp/imx-jpeg/mxc-jpeg.c | 24 +++++++++++++++++++ + 1 file changed, 24 insertions(+) + +diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c +index c9ca7577140c..9ce1e78f5d30 100644 +--- a/drivers/media/platform/imx-jpeg/mxc-jpeg.c ++++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.c +@@ -2209,9 +2209,33 @@ static int mxc_jpeg_runtime_suspend(struct device *dev) + } + #endif + ++#ifdef CONFIG_PM_SLEEP ++static int mxc_jpeg_suspend(struct device *dev) ++{ ++ struct mxc_jpeg_dev *jpeg = dev_get_drvdata(dev); ++ ++ v4l2_m2m_suspend(jpeg->m2m_dev); ++ return pm_runtime_force_suspend(dev); ++} ++ ++static int mxc_jpeg_resume(struct device *dev) ++{ ++ struct mxc_jpeg_dev *jpeg = dev_get_drvdata(dev); ++ int ret; ++ ++ ret = pm_runtime_force_resume(dev); ++ if (ret < 0) ++ return ret; ++ ++ v4l2_m2m_resume(jpeg->m2m_dev); ++ return ret; ++} ++#endif ++ + static const struct dev_pm_ops mxc_jpeg_pm_ops = { + SET_RUNTIME_PM_OPS(mxc_jpeg_runtime_suspend, + mxc_jpeg_runtime_resume, NULL) ++ SET_SYSTEM_SLEEP_PM_OPS(mxc_jpeg_suspend, mxc_jpeg_resume) + }; + + static int mxc_jpeg_remove(struct platform_device *pdev) +-- +2.35.3 + diff --git a/patches.suse/media-imx-jpeg-Correct-some-definition-according-spe.patch b/patches.suse/media-imx-jpeg-Correct-some-definition-according-spe.patch new file mode 100644 index 0000000..685c07d --- /dev/null +++ b/patches.suse/media-imx-jpeg-Correct-some-definition-according-spe.patch @@ -0,0 +1,46 @@ +From 5a601f89e846c1b6005ab274d039e5036fc22015 Mon Sep 17 00:00:00 2001 +From: Ming Qian +Date: Mon, 30 May 2022 08:47:31 +0100 +Subject: [PATCH] media: imx-jpeg: Correct some definition according + specification +Git-commit: 5a601f89e846c1b6005ab274d039e5036fc22015 +References: git-fixes +Patch-mainline: v6.0-rc1 + +the register CAST_NOMFRSIZE_LO should be equal to CAST_STATUS16 +the register CAST_NOMFRSIZE_HI should be equal to CAST_STATUS17 +the register CAST_OFBSIZE_LO should be equal to CAST_STATUS18 +the register CAST_OFBSIZE_HI should be equal to CAST_STATUS19 + +Fixes: 2db16c6ed72ce ("media: imx-jpeg: Add V4L2 driver for i.MX8 JPEG Encoder/Decoder") +Signed-off-by: Ming Qian +Reviewed-by: Mirela Rabulea +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Oliver Neukum +--- + drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h +index e7e8954754b1..07655502f4bd 100644 +--- a/drivers/media/platform/imx-jpeg/mxc-jpeg-hw.h ++++ b/drivers/media/platform/imx-jpeg/mxc-jpeg-hw.h +@@ -53,10 +53,10 @@ + #define CAST_REC_REGS_SEL CAST_STATUS4 + #define CAST_LUMTH CAST_STATUS5 + #define CAST_CHRTH CAST_STATUS6 +-#define CAST_NOMFRSIZE_LO CAST_STATUS7 +-#define CAST_NOMFRSIZE_HI CAST_STATUS8 +-#define CAST_OFBSIZE_LO CAST_STATUS9 +-#define CAST_OFBSIZE_HI CAST_STATUS10 ++#define CAST_NOMFRSIZE_LO CAST_STATUS16 ++#define CAST_NOMFRSIZE_HI CAST_STATUS17 ++#define CAST_OFBSIZE_LO CAST_STATUS18 ++#define CAST_OFBSIZE_HI CAST_STATUS19 + + #define MXC_MAX_SLOTS 1 /* TODO use all 4 slots*/ + /* JPEG-Decoder Wrapper Slot Registers 0..3 */ +-- +2.35.3 + diff --git a/patches.suse/media-imx-jpeg-Disable-slot-interrupt-when-frame-don.patch b/patches.suse/media-imx-jpeg-Disable-slot-interrupt-when-frame-don.patch new file mode 100644 index 0000000..c660842 --- /dev/null +++ b/patches.suse/media-imx-jpeg-Disable-slot-interrupt-when-frame-don.patch @@ -0,0 +1,78 @@ +From 22a2bc88c139dc9757bdb1d0a3665ac27edc79a5 Mon Sep 17 00:00:00 2001 +From: Ming Qian +Date: Fri, 10 Jun 2022 03:00:57 +0100 +Subject: [PATCH] media: imx-jpeg: Disable slot interrupt when frame done +Git-commit: 22a2bc88c139dc9757bdb1d0a3665ac27edc79a5 +References: git-fixes +Patch-mainline: v6.0-rc1 + +The interrupt STMBUF_HALF may be triggered after frame done. +It may led to system hang if driver try to access the register after +power off. + +Disable the slot interrupt when frame done. + +Fixes: 2db16c6ed72ce ("media: imx-jpeg: Add V4L2 driver for i.MX8 JPEG Encoder/Decoder") +Signed-off-by: Ming Qian +Reviewed-by: Mirela Rabulea +Tested-by: Mirela Rabulea +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Oliver Neukum +--- + drivers/media/platform/imx-jpeg/mxc-jpeg-hw.c | 5 +++++ + drivers/media/platform/imx-jpeg/mxc-jpeg-hw.h | 1 + + drivers/media/platform/imx-jpeg/mxc-jpeg.c | 10 ++-------- + 3 files changed, 8 insertions(+), 8 deletions(-) + +--- a/drivers/media/platform/imx-jpeg/mxc-jpeg-hw.c ++++ b/drivers/media/platform/imx-jpeg/mxc-jpeg-hw.c +@@ -79,6 +79,11 @@ void mxc_jpeg_enable_irq(void __iomem *r + writel(0xFFFFFFFF, reg + MXC_SLOT_OFFSET(slot, SLOT_IRQ_EN)); + } + ++void mxc_jpeg_disable_irq(void __iomem *reg, int slot) ++{ ++ writel(0x0, reg + MXC_SLOT_OFFSET(slot, SLOT_IRQ_EN)); ++} ++ + void mxc_jpeg_sw_reset(void __iomem *reg) + { + /* +--- a/drivers/media/platform/imx-jpeg/mxc-jpeg-hw.h ++++ b/drivers/media/platform/imx-jpeg/mxc-jpeg-hw.h +@@ -125,6 +125,7 @@ u32 mxc_jpeg_get_offset(void __iomem *re + void mxc_jpeg_enable_slot(void __iomem *reg, int slot); + void mxc_jpeg_set_l_endian(void __iomem *reg, int le); + void mxc_jpeg_enable_irq(void __iomem *reg, int slot); ++void mxc_jpeg_disable_irq(void __iomem *reg, int slot); + int mxc_jpeg_set_input(void __iomem *reg, u32 in_buf, u32 bufsize); + int mxc_jpeg_set_output(void __iomem *reg, u16 out_pitch, u32 out_buf, + u16 w, u16 h); +--- a/drivers/media/platform/imx-jpeg/mxc-jpeg.c ++++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.c +@@ -555,15 +555,8 @@ static irqreturn_t mxc_jpeg_dec_irq(int + dev_dbg(dev, "Irq %d on slot %d.\n", irq, slot); + + ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev); +- if (!ctx) { +- dev_err(dev, +- "Instance released before the end of transaction.\n"); +- /* soft reset only resets internal state, not registers */ +- mxc_jpeg_sw_reset(reg); +- /* clear all interrupts */ +- writel(0xFFFFFFFF, reg + MXC_SLOT_OFFSET(slot, SLOT_STATUS)); ++ if (WARN_ON(!ctx)) + goto job_unlock; +- } + + if (slot != ctx->slot) { + /* TODO investigate when adding multi-instance support */ +@@ -634,6 +627,7 @@ static irqreturn_t mxc_jpeg_dec_irq(int + buf_state = VB2_BUF_STATE_DONE; + + buffers_done: ++ mxc_jpeg_disable_irq(reg, ctx->slot); + jpeg->slot_data[slot].used = false; /* unused, but don't free */ + v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); + v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); diff --git a/patches.suse/media-imx-jpeg-Fix-potential-array-out-of-bounds-in-.patch b/patches.suse/media-imx-jpeg-Fix-potential-array-out-of-bounds-in-.patch new file mode 100644 index 0000000..7c07182 --- /dev/null +++ b/patches.suse/media-imx-jpeg-Fix-potential-array-out-of-bounds-in-.patch @@ -0,0 +1,40 @@ +From e490fa1be5fe820029aa2ff2f70bcbbcebc11d28 Mon Sep 17 00:00:00 2001 +From: Mirela Rabulea +Date: Tue, 8 Mar 2022 14:16:57 +0100 +Subject: [PATCH] media: imx-jpeg: Fix potential array out of bounds in + queue_setup +Git-commit: e490fa1be5fe820029aa2ff2f70bcbbcebc11d28 +References: git-fixes +Patch-mainline: v5.19-rc1 + +Fix smatch warning in mxc_jpeg_queue_setup, check *nplanes against +current format: + +drivers/media/platform/imx-jpeg/mxc-jpeg.c:1070 +mxc_jpeg_queue_setup() + warn: potential user controlled iterator 'i' (array size 2 vs 7) + +Signed-off-by: Mirela Rabulea +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Oliver Neukum +--- + drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c +index 8b33a3bca867..87d91e927747 100644 +--- a/drivers/media/platform/imx-jpeg/mxc-jpeg.c ++++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.c +@@ -1081,6 +1081,8 @@ static int mxc_jpeg_queue_setup(struct vb2_queue *q, + + /* Handle CREATE_BUFS situation - *nplanes != 0 */ + if (*nplanes) { ++ if (*nplanes != q_data->fmt->colplanes) ++ return -EINVAL; + for (i = 0; i < *nplanes; i++) { + if (sizes[i] < q_data->sizeimage[i]) + return -EINVAL; +-- +2.35.3 + diff --git a/patches.suse/media-imx-jpeg-Leave-a-blank-space-before-the-config.patch b/patches.suse/media-imx-jpeg-Leave-a-blank-space-before-the-config.patch new file mode 100644 index 0000000..8d0b0ce --- /dev/null +++ b/patches.suse/media-imx-jpeg-Leave-a-blank-space-before-the-config.patch @@ -0,0 +1,59 @@ +From 6285cdea19daf764bf00f662a59fc83ef67345cf Mon Sep 17 00:00:00 2001 +From: Ming Qian +Date: Mon, 30 May 2022 08:48:37 +0100 +Subject: [PATCH] media: imx-jpeg: Leave a blank space before the configuration + data +Git-commit: 6285cdea19daf764bf00f662a59fc83ef67345cf +References: git-fixes +Patch-mainline: v6.0-rc1 + +There is a hardware bug that it will load +the first 128 bytes of configuration data twice, +it will led to some configure error. +so shift the configuration data 128 bytes, +and make the first 128 bytes all zero, +then hardware will load the 128 zero twice, +and ignore them as garbage. +then the configuration data can be loaded correctly + +Fixes: 2db16c6ed72ce ("media: imx-jpeg: Add V4L2 driver for i.MX8 JPEG Encoder/Decoder") +Signed-off-by: Ming Qian +Reviewed-by: Mirela Rabulea +Reviewed-by: Tommaso Merciai +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Oliver Neukum +--- + drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c +index 734e1b65fbc7..c0fd030d0f19 100644 +--- a/drivers/media/platform/imx-jpeg/mxc-jpeg.c ++++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.c +@@ -519,6 +519,7 @@ static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg, + GFP_ATOMIC); + if (!cfg_stm) + goto err; ++ memset(cfg_stm, 0, MXC_JPEG_MAX_CFG_STREAM); + jpeg->slot_data[slot].cfg_stream_vaddr = cfg_stm; + + skip_alloc: +@@ -755,7 +756,13 @@ static unsigned int mxc_jpeg_setup_cfg_stream(void *cfg_stream_vaddr, + u32 fourcc, + u16 w, u16 h) + { +- unsigned int offset = 0; ++ /* ++ * There is a hardware issue that first 128 bytes of configuration data ++ * can't be loaded correctly. ++ * To avoid this issue, we need to write the configuration from ++ * an offset which should be no less than 0x80 (128 bytes). ++ */ ++ unsigned int offset = 0x80; + u8 *cfg = (u8 *)cfg_stream_vaddr; + struct mxc_jpeg_sof *sof; + struct mxc_jpeg_sos *sos; +-- +2.35.3 + diff --git a/patches.suse/media-imx-jpeg-Refactor-function-mxc_jpeg_parse.patch b/patches.suse/media-imx-jpeg-Refactor-function-mxc_jpeg_parse.patch new file mode 100644 index 0000000..e6aea36 --- /dev/null +++ b/patches.suse/media-imx-jpeg-Refactor-function-mxc_jpeg_parse.patch @@ -0,0 +1,67 @@ +From 8dd504a3a0a5f73b4c137ce3afc35936a4ecd871 Mon Sep 17 00:00:00 2001 +From: Ming Qian +Date: Wed, 23 Mar 2022 10:05:54 +0100 +Subject: [PATCH] media: imx-jpeg: Refactor function mxc_jpeg_parse +Git-commit: 8dd504a3a0a5f73b4c137ce3afc35936a4ecd871 +References: git-fixes +Patch-mainline: v5.19-rc1 + +Refine code to support dynamic resolution change + +Signed-off-by: Ming Qian +Reviewed-by: Mirela Rabulea +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Oliver Neukum +--- + drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c | 13 ++++++------- + 1 file changed, 6 insertions(+), 7 deletions(-) + +diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c +index 87d91e927747..dda508aedac0 100644 +--- a/drivers/media/platform/imx-jpeg/mxc-jpeg.c ++++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.c +@@ -1247,8 +1247,7 @@ static void mxc_jpeg_sizeimage(struct mxc_jpeg_q_data *q) + } + } + +-static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx, +- u8 *src_addr, u32 size, bool *dht_needed) ++static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx, struct vb2_buffer *vb) + { + struct device *dev = ctx->mxc_jpeg->dev; + struct mxc_jpeg_q_data *q_data_out, *q_data_cap; +@@ -1258,6 +1257,9 @@ static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx, + struct v4l2_jpeg_header header; + struct mxc_jpeg_sof *psof = NULL; + struct mxc_jpeg_sos *psos = NULL; ++ struct mxc_jpeg_src_buf *jpeg_src_buf = vb2_to_mxc_buf(vb); ++ u8 *src_addr = (u8 *)vb2_plane_vaddr(vb, 0); ++ u32 size = vb2_get_plane_payload(vb, 0); + int ret; + + memset(&header, 0, sizeof(header)); +@@ -1268,7 +1270,7 @@ static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx, + } + + /* if DHT marker present, no need to inject default one */ +- *dht_needed = (header.num_dht == 0); ++ jpeg_src_buf->dht_needed = (header.num_dht == 0); + + q_data_out = mxc_jpeg_get_q_data(ctx, + V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); +@@ -1383,10 +1385,7 @@ static void mxc_jpeg_buf_queue(struct vb2_buffer *vb) + + jpeg_src_buf = vb2_to_mxc_buf(vb); + jpeg_src_buf->jpeg_parse_error = false; +- ret = mxc_jpeg_parse(ctx, +- (u8 *)vb2_plane_vaddr(vb, 0), +- vb2_get_plane_payload(vb, 0), +- &jpeg_src_buf->dht_needed); ++ ret = mxc_jpeg_parse(ctx, vb); + if (ret) + jpeg_src_buf->jpeg_parse_error = true; + +-- +2.35.3 + diff --git a/patches.suse/media-meson-vdec-add-missing-clk_disable_unprepare-o.patch b/patches.suse/media-meson-vdec-add-missing-clk_disable_unprepare-o.patch new file mode 100644 index 0000000..1e88fb6 --- /dev/null +++ b/patches.suse/media-meson-vdec-add-missing-clk_disable_unprepare-o.patch @@ -0,0 +1,46 @@ +From 4029372233e13e281f8c387f279f9f064ced3810 Mon Sep 17 00:00:00 2001 +From: Xu Qiang +Date: Thu, 18 Aug 2022 08:57:53 +0200 +Subject: [PATCH] media: meson: vdec: add missing clk_disable_unprepare on error in vdec_hevc_start() +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 4029372233e13e281f8c387f279f9f064ced3810 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Add the missing clk_disable_unprepare() before return +from vdec_hevc_start() in the error handling case. + +Fixes: 823a7300340e (“media: meson: vdec: add common HEVC decoder support”) +Signed-off-by: Xu Qiang +Reviewed-by: Neil Armstrong +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Acked-by: Takashi Iwai + +--- + drivers/staging/media/meson/vdec/vdec_hevc.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/staging/media/meson/vdec/vdec_hevc.c b/drivers/staging/media/meson/vdec/vdec_hevc.c +index 9530e580e57a..afced435c907 100644 +--- a/drivers/staging/media/meson/vdec/vdec_hevc.c ++++ b/drivers/staging/media/meson/vdec/vdec_hevc.c +@@ -167,8 +167,12 @@ static int vdec_hevc_start(struct amvdec_session *sess) + + clk_set_rate(core->vdec_hevc_clk, 666666666); + ret = clk_prepare_enable(core->vdec_hevc_clk); +- if (ret) ++ if (ret) { ++ if (core->platform->revision == VDEC_REVISION_G12A || ++ core->platform->revision == VDEC_REVISION_SM1) ++ clk_disable_unprepare(core->vdec_hevcf_clk); + return ret; ++ } + + if (core->platform->revision == VDEC_REVISION_SM1) + regmap_update_bits(core->regmap_ao, AO_RTI_GEN_PWR_SLEEP0, +-- +2.35.3 + diff --git a/patches.suse/media-platform-mtk-mdp-Fix-mdp_ipi_comm-structure-al.patch b/patches.suse/media-platform-mtk-mdp-Fix-mdp_ipi_comm-structure-al.patch new file mode 100644 index 0000000..c0be249 --- /dev/null +++ b/patches.suse/media-platform-mtk-mdp-Fix-mdp_ipi_comm-structure-al.patch @@ -0,0 +1,57 @@ +From ab14c99c035da7156a3b66fa171171295bc4b89a Mon Sep 17 00:00:00 2001 +From: AngeloGioacchino Del Regno +Date: Thu, 23 Jun 2022 14:55:46 +0100 +Subject: [PATCH] media: platform: mtk-mdp: Fix mdp_ipi_comm structure + alignment +Git-commit: ab14c99c035da7156a3b66fa171171295bc4b89a +REferences: git-fixes +Patch-mainline: v6.0-rc1 + +The mdp_ipi_comm structure defines a command that is either +PROCESS (start processing) or DEINIT (destroy instance); we +are using this one to send PROCESS or DEINIT commands from Linux +to an MDP instance through a VPU write but, while the first wants +us to stay 4-bytes aligned, the VPU instead requires an 8-bytes +data alignment. + +Keeping in mind that these commands are executed immediately +after sending them (hence not chained with others before the +VPU/MDP "actually" start executing), it is fine to simply add +a padding of 4 bytes to this structure: this keeps the same +performance as before, as we're still stack-allocating it, +while avoiding hackery inside of mtk-vpu to ensure alignment +bringing a definitely bigger performance impact. + +Fixes: c8eb2d7e8202 ("[media] media: Add Mediatek MDP Driver") +Signed-off-by: AngeloGioacchino Del Regno +Reviewed-by: Houlong Wei +Reviewed-by: Irui Wang +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Oliver Neukum +--- + drivers/media/platform/mediatek/mdp/mtk_mdp_ipi.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/media/platform/mediatek/mdp/mtk_mdp_ipi.h b/drivers/media/platform/mediatek/mdp/mtk_mdp_ipi.h +index 2cb8cecb3077..b810c96695c8 100644 +--- a/drivers/media/platform/mtk-mdp/mtk_mdp_ipi.h ++++ b/drivers/media/platform/mtk-mdp/mtk_mdp_ipi.h +@@ -40,12 +40,14 @@ struct mdp_ipi_init { + * @ipi_id : IPI_MDP + * @ap_inst : AP mtk_mdp_vpu address + * @vpu_inst_addr : VPU MDP instance address ++ * @padding : Alignment padding + */ + struct mdp_ipi_comm { + uint32_t msg_id; + uint32_t ipi_id; + uint64_t ap_inst; + uint32_t vpu_inst_addr; ++ uint32_t padding; + }; + + /** +-- +2.35.3 + diff --git a/patches.suse/media-rkvdec-Disable-H.264-error-detection.patch b/patches.suse/media-rkvdec-Disable-H.264-error-detection.patch new file mode 100644 index 0000000..40acdb9 --- /dev/null +++ b/patches.suse/media-rkvdec-Disable-H.264-error-detection.patch @@ -0,0 +1,48 @@ +From 3a99c4474112f49a5459933d8758614002ca0ddc Mon Sep 17 00:00:00 2001 +From: Nicolas Dufresne +Date: Fri, 10 Jun 2022 13:52:11 +0100 +Subject: [PATCH] media: rkvdec: Disable H.264 error detection +Git-commit: 3a99c4474112f49a5459933d8758614002ca0ddc +Patch-mainline: v6.0 +References: git-fixes + +Quite often, the HW get stuck in error condition if a stream error +was detected. As documented, the HW should stop immediately and self +reset. There is likely a problem or a miss-understanding of the self +reset mechanism, as unless we make a long pause, the next command +will then report an error even if there is no error in it. + +Disabling error detection fixes the issue, and let the decoder continue +after an error. This patch is safe for backport into older kernels. + +Fixes: cd33c830448b ("media: rkvdec: Add the rkvdec driver") +Signed-off-by: Nicolas Dufresne +Reviewed-by: Brian Norris +Tested-by: Brian Norris +Reviewed-by: Ezequiel Garcia +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Acked-by: Takashi Iwai + +--- + drivers/staging/media/rkvdec/rkvdec-h264.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/staging/media/rkvdec/rkvdec-h264.c b/drivers/staging/media/rkvdec/rkvdec-h264.c +index 4af5a831bde0..4fc167b42cf0 100644 +--- a/drivers/staging/media/rkvdec/rkvdec-h264.c ++++ b/drivers/staging/media/rkvdec/rkvdec-h264.c +@@ -1162,8 +1162,8 @@ static int rkvdec_h264_run(struct rkvdec_ctx *ctx) + + schedule_delayed_work(&rkvdec->watchdog_work, msecs_to_jiffies(2000)); + +- writel(0xffffffff, rkvdec->regs + RKVDEC_REG_STRMD_ERR_EN); +- writel(0xffffffff, rkvdec->regs + RKVDEC_REG_H264_ERR_E); ++ writel(0, rkvdec->regs + RKVDEC_REG_STRMD_ERR_EN); ++ writel(0, rkvdec->regs + RKVDEC_REG_H264_ERR_E); + writel(1, rkvdec->regs + RKVDEC_REG_PREF_LUMA_CACHE_COMMAND); + writel(1, rkvdec->regs + RKVDEC_REG_PREF_CHR_CACHE_COMMAND); + +-- +2.35.3 + diff --git a/patches.suse/media-st-delta-Fix-PM-disable-depth-imbalance-in-del.patch b/patches.suse/media-st-delta-Fix-PM-disable-depth-imbalance-in-del.patch new file mode 100644 index 0000000..e9b079e --- /dev/null +++ b/patches.suse/media-st-delta-Fix-PM-disable-depth-imbalance-in-del.patch @@ -0,0 +1,57 @@ +From 94e3dba710fe0afc772172305444250023fc2d30 Mon Sep 17 00:00:00 2001 +From: Miaoqian Lin +Date: Mon, 7 Mar 2022 09:08:59 +0100 +Subject: [PATCH] media: st-delta: Fix PM disable depth imbalance in + delta_probe +Git-commit: 94e3dba710fe0afc772172305444250023fc2d30 +References: git-fixes +Patch-mainline: v5.19-rc1 + +The pm_runtime_enable will decrease power disable depth. +If the probe fails, we should use pm_runtime_disable() to balance +pm_runtime_enable(). + +Fixes: f386509e4959 ("[media] st-delta: STiH4xx multi-format video decoder v4l2 driver") +Signed-off-by: Miaoqian Lin +Acked-by: Hugues Fruchet +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Oliver Neukum +--- + drivers/media/platform/st/sti/delta/delta-v4l2.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/media/platform/st/sti/delta/delta-v4l2.c b/drivers/media/platform/st/sti/delta/delta-v4l2.c +index c887a31ebb54..420ad4d8df5d 100644 +--- a/drivers/media/platform/sti/delta/delta-v4l2.c ++++ b/drivers/media/platform/sti/delta/delta-v4l2.c +@@ -1859,7 +1859,7 @@ static int delta_probe(struct platform_device *pdev) + if (ret) { + dev_err(delta->dev, "%s failed to initialize firmware ipc channel\n", + DELTA_PREFIX); +- goto err; ++ goto err_pm_disable; + } + + /* register all available decoders */ +@@ -1873,7 +1873,7 @@ static int delta_probe(struct platform_device *pdev) + if (ret) { + dev_err(delta->dev, "%s failed to register V4L2 device\n", + DELTA_PREFIX); +- goto err; ++ goto err_pm_disable; + } + + delta->work_queue = create_workqueue(DELTA_NAME); +@@ -1898,6 +1898,8 @@ static int delta_probe(struct platform_device *pdev) + destroy_workqueue(delta->work_queue); + err_v4l2: + v4l2_device_unregister(&delta->v4l2_dev); ++err_pm_disable: ++ pm_runtime_disable(dev); + err: + return ret; + } +-- +2.35.3 + diff --git a/patches.suse/media-uvcvideo-Fix-memory-leak-in-uvc_gpio_parse.patch b/patches.suse/media-uvcvideo-Fix-memory-leak-in-uvc_gpio_parse.patch new file mode 100644 index 0000000..59b06be --- /dev/null +++ b/patches.suse/media-uvcvideo-Fix-memory-leak-in-uvc_gpio_parse.patch @@ -0,0 +1,58 @@ +From f0f078457f18f10696888f8d0e6aba9deb9cde92 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= +Date: Sat, 8 Jan 2022 18:04:39 +0100 +Subject: [PATCH] media: uvcvideo: Fix memory leak in uvc_gpio_parse +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: f0f078457f18f10696888f8d0e6aba9deb9cde92 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Previously the unit buffer was allocated before checking the IRQ for +privacy GPIO. In case of error, the unit buffer was leaked. + +Allocate the unit buffer after the IRQ to avoid it. + +Addresses-coverity-id: 1474639 ("Resource leak") + +Fixes: 2886477ff987 ("media: uvcvideo: Implement UVC_EXT_GPIO_UNIT") +Signed-off-by: José Expósito +Reviewed-by: Ricardo Ribalda +Signed-off-by: Laurent Pinchart +Signed-off-by: Mauro Carvalho Chehab +Acked-by: Takashi Iwai + +--- + drivers/media/usb/uvc/uvc_driver.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c +index 9c05776f11d1..ccc825607437 100644 +--- a/drivers/media/usb/uvc/uvc_driver.c ++++ b/drivers/media/usb/uvc/uvc_driver.c +@@ -1553,10 +1553,6 @@ static int uvc_gpio_parse(struct uvc_device *dev) + if (IS_ERR_OR_NULL(gpio_privacy)) + return PTR_ERR_OR_ZERO(gpio_privacy); + +- unit = uvc_alloc_entity(UVC_EXT_GPIO_UNIT, UVC_EXT_GPIO_UNIT_ID, 0, 1); +- if (!unit) +- return -ENOMEM; +- + irq = gpiod_to_irq(gpio_privacy); + if (irq < 0) { + if (irq != EPROBE_DEFER) +@@ -1565,6 +1561,10 @@ static int uvc_gpio_parse(struct uvc_device *dev) + return irq; + } + ++ unit = uvc_alloc_entity(UVC_EXT_GPIO_UNIT, UVC_EXT_GPIO_UNIT_ID, 0, 1); ++ if (!unit) ++ return -ENOMEM; ++ + unit->gpio.gpio_privacy = gpio_privacy; + unit->gpio.irq = irq; + unit->gpio.bControlSize = 1; +-- +2.35.3 + diff --git a/patches.suse/media-uvcvideo-Use-entity-get_cur-in-uvc_ctrl_set.patch b/patches.suse/media-uvcvideo-Use-entity-get_cur-in-uvc_ctrl_set.patch new file mode 100644 index 0000000..31032f3 --- /dev/null +++ b/patches.suse/media-uvcvideo-Use-entity-get_cur-in-uvc_ctrl_set.patch @@ -0,0 +1,134 @@ +From 5f36851c36b30f713f588ed2b60aa7b4512e2c76 Mon Sep 17 00:00:00 2001 +From: Yunke Cao +Date: Thu, 7 Jul 2022 10:53:31 +0200 +Subject: [PATCH] media: uvcvideo: Use entity get_cur in uvc_ctrl_set +Git-commit: 5f36851c36b30f713f588ed2b60aa7b4512e2c76 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Entity controls should get_cur using an entity-defined function +instead of via a query. Fix this in uvc_ctrl_set. + +Fixes: 65900c581d01 ("media: uvcvideo: Allow entity-defined get_info and get_cur") +Signed-off-by: Yunke Cao +Reviewed-by: Ricardo Ribalda +Signed-off-by: Laurent Pinchart +Signed-off-by: Mauro Carvalho Chehab +Acked-by: Takashi Iwai + +--- + drivers/media/usb/uvc/uvc_ctrl.c | 83 ++++++++++++++++++-------------- + 1 file changed, 46 insertions(+), 37 deletions(-) + +diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c +index 5c33b0b7ef9a..97f312020516 100644 +--- a/drivers/media/usb/uvc/uvc_ctrl.c ++++ b/drivers/media/usb/uvc/uvc_ctrl.c +@@ -985,36 +985,56 @@ static s32 __uvc_ctrl_get_value(struct uvc_control_mapping *mapping, + return value; + } + +-static int __uvc_ctrl_get(struct uvc_video_chain *chain, +- struct uvc_control *ctrl, struct uvc_control_mapping *mapping, +- s32 *value) ++static int __uvc_ctrl_load_cur(struct uvc_video_chain *chain, ++ struct uvc_control *ctrl) + { ++ u8 *data; + int ret; + +- if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) +- return -EACCES; ++ if (ctrl->loaded) ++ return 0; + +- if (!ctrl->loaded) { +- if (ctrl->entity->get_cur) { +- ret = ctrl->entity->get_cur(chain->dev, +- ctrl->entity, +- ctrl->info.selector, +- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), +- ctrl->info.size); +- } else { +- ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, +- ctrl->entity->id, +- chain->dev->intfnum, +- ctrl->info.selector, +- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), +- ctrl->info.size); +- } +- if (ret < 0) +- return ret; ++ data = uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT); + ++ if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) { ++ memset(data, 0, ctrl->info.size); + ctrl->loaded = 1; ++ ++ return 0; + } + ++ if (ctrl->entity->get_cur) ++ ret = ctrl->entity->get_cur(chain->dev, ctrl->entity, ++ ctrl->info.selector, data, ++ ctrl->info.size); ++ else ++ ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, ++ ctrl->entity->id, chain->dev->intfnum, ++ ctrl->info.selector, data, ++ ctrl->info.size); ++ ++ if (ret < 0) ++ return ret; ++ ++ ctrl->loaded = 1; ++ ++ return ret; ++} ++ ++static int __uvc_ctrl_get(struct uvc_video_chain *chain, ++ struct uvc_control *ctrl, ++ struct uvc_control_mapping *mapping, ++ s32 *value) ++{ ++ int ret; ++ ++ if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) ++ return -EACCES; ++ ++ ret = __uvc_ctrl_load_cur(chain, ctrl); ++ if (ret < 0) ++ return ret; ++ + *value = __uvc_ctrl_get_value(mapping, + uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT)); + +@@ -1810,21 +1830,10 @@ int uvc_ctrl_set(struct uvc_fh *handle, + * needs to be loaded from the device to perform the read-modify-write + * operation. + */ +- if (!ctrl->loaded && (ctrl->info.size * 8) != mapping->size) { +- if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) { +- memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), +- 0, ctrl->info.size); +- } else { +- ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, +- ctrl->entity->id, chain->dev->intfnum, +- ctrl->info.selector, +- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), +- ctrl->info.size); +- if (ret < 0) +- return ret; +- } +- +- ctrl->loaded = 1; ++ if ((ctrl->info.size * 8) != mapping->size) { ++ ret = __uvc_ctrl_load_cur(chain, ctrl); ++ if (ret < 0) ++ return ret; + } + + /* Backup the current value in case we need to rollback later. */ +-- +2.35.3 + diff --git a/patches.suse/media-v4l2-compat-ioctl32.c-zero-buffer-passed-to-v4.patch b/patches.suse/media-v4l2-compat-ioctl32.c-zero-buffer-passed-to-v4.patch new file mode 100644 index 0000000..ddfe416 --- /dev/null +++ b/patches.suse/media-v4l2-compat-ioctl32.c-zero-buffer-passed-to-v4.patch @@ -0,0 +1,38 @@ +From 4e768c8e34e639cff66a0f175bc4aebf472e4305 Mon Sep 17 00:00:00 2001 +From: Hans Verkuil +Date: Mon, 21 Mar 2022 08:33:56 +0000 +Subject: [PATCH] media: v4l2-compat-ioctl32.c: zero buffer passed to v4l2_compat_get_array_args() +Git-commit: 4e768c8e34e639cff66a0f175bc4aebf472e4305 +Patch-mainline: v6.0 +References: git-fixes + +The v4l2_compat_get_array_args() function can leave uninitialized memory in the +buffer it is passed. So zero it before copying array elements from userspace +into the buffer. + +Signed-off-by: Hans Verkuil +Reported-by: syzbot+ff18193ff05f3f87f226@syzkaller.appspotmail.com +Reviewed-by: Laurent Pinchart +Signed-off-by: Mauro Carvalho Chehab +Acked-by: Takashi Iwai + +--- + drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +index 0f3d6b5667b0..55c26e7d370e 100644 +--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c ++++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +@@ -1040,6 +1040,8 @@ int v4l2_compat_get_array_args(struct file *file, void *mbuf, + { + int err = 0; + ++ memset(mbuf, 0, array_size); ++ + switch (cmd) { + case VIDIOC_G_FMT32: + case VIDIOC_S_FMT32: +-- +2.35.3 + diff --git a/patches.suse/media-vsp1-Fix-offset-calculation-for-plane-cropping.patch b/patches.suse/media-vsp1-Fix-offset-calculation-for-plane-cropping.patch new file mode 100644 index 0000000..7cbb5da --- /dev/null +++ b/patches.suse/media-vsp1-Fix-offset-calculation-for-plane-cropping.patch @@ -0,0 +1,50 @@ +From 5f25abec8f21b7527c1223a354d23c270befddb3 Mon Sep 17 00:00:00 2001 +From: Michael Rodin +Date: Tue, 23 Nov 2021 12:50:36 +0100 +Subject: [PATCH] media: vsp1: Fix offset calculation for plane cropping +Git-commit: 5f25abec8f21b7527c1223a354d23c270befddb3 +REferences: git-fixes +Patch-mainline: v5.19-rc1 + +The vertical subsampling factor is currently not considered in the +offset calculation for plane cropping done in rpf_configure_partition. +This causes a distortion (shift of the color plane) when formats with +the vsub factor larger than 1 are used (e.g. NV12, see +vsp1_video_formats in vsp1_pipe.c). This commit considers vsub factor +for all planes except plane 0 (luminance). + +Drop generalization of the offset calculation to reduce the binary size. + +Fixes: e5ad37b64de9 ("[media] v4l: vsp1: Add cropping support") +Signed-off-by: Michael Rodin +Signed-off-by: LUU HOAI +Signed-off-by: Laurent Pinchart +Reviewed-by: Kieran Bingham +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Oliver Neukum +--- + drivers/media/platform/renesas/vsp1/vsp1_rpf.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/media/platform/renesas/vsp1/vsp1_rpf.c b/drivers/media/platform/renesas/vsp1/vsp1_rpf.c +index 85587c1b6a37..75083cb234fe 100644 +--- a/drivers/media/platform/vsp1/vsp1_rpf.c ++++ b/drivers/media/platform/vsp1/vsp1_rpf.c +@@ -291,11 +291,11 @@ static void rpf_configure_partition(struct vsp1_entity *entity, + + crop.left * fmtinfo->bpp[0] / 8; + + if (format->num_planes > 1) { ++ unsigned int bpl = format->plane_fmt[1].bytesperline; + unsigned int offset; + +- offset = crop.top * format->plane_fmt[1].bytesperline +- + crop.left / fmtinfo->hsub +- * fmtinfo->bpp[1] / 8; ++ offset = crop.top / fmtinfo->vsub * bpl ++ + crop.left / fmtinfo->hsub * fmtinfo->bpp[1] / 8; + mem.addr[1] += offset; + mem.addr[2] += offset; + } +-- +2.35.3 + diff --git a/patches.suse/media-xilinx-vipp-Fix-refcount-leak-in-xvip_graph_dm.patch b/patches.suse/media-xilinx-vipp-Fix-refcount-leak-in-xvip_graph_dm.patch new file mode 100644 index 0000000..c4e3484 --- /dev/null +++ b/patches.suse/media-xilinx-vipp-Fix-refcount-leak-in-xvip_graph_dm.patch @@ -0,0 +1,56 @@ +From 1c78f19c3a0ea312a8178a6bfd8934eb93e9b10a Mon Sep 17 00:00:00 2001 +From: Miaoqian Lin +Date: Wed, 1 Jun 2022 06:25:14 +0200 +Subject: [PATCH] media: xilinx: vipp: Fix refcount leak in xvip_graph_dma_init +Git-commit: 1c78f19c3a0ea312a8178a6bfd8934eb93e9b10a +Patch-mainline: v6.1-rc1 +References: git-fixes + +of_get_child_by_name() returns a node pointer with refcount +incremented, we should use of_node_put() on it when not need anymore. +Add missing of_node_put() to avoid refcount leak. + +Fixes: df3305156f98 ("[media] v4l: xilinx: Add Xilinx Video IP core") +Signed-off-by: Miaoqian Lin +Signed-off-by: Laurent Pinchart +Signed-off-by: Mauro Carvalho Chehab +Acked-by: Takashi Iwai + +--- + drivers/media/platform/xilinx/xilinx-vipp.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c +index f34f8b077e03..0a16c218a50a 100644 +--- a/drivers/media/platform/xilinx/xilinx-vipp.c ++++ b/drivers/media/platform/xilinx/xilinx-vipp.c +@@ -471,7 +471,7 @@ static int xvip_graph_dma_init(struct xvip_composite_device *xdev) + { + struct device_node *ports; + struct device_node *port; +- int ret; ++ int ret = 0; + + ports = of_get_child_by_name(xdev->dev->of_node, "ports"); + if (ports == NULL) { +@@ -481,13 +481,14 @@ static int xvip_graph_dma_init(struct xvip_composite_device *xdev) + + for_each_child_of_node(ports, port) { + ret = xvip_graph_dma_init_one(xdev, port); +- if (ret < 0) { ++ if (ret) { + of_node_put(port); +- return ret; ++ break; + } + } + +- return 0; ++ of_node_put(ports); ++ return ret; + } + + static void xvip_graph_cleanup(struct xvip_composite_device *xdev) +-- +2.35.3 + diff --git a/patches.suse/memory-of-Fix-refcount-leak-bug-in-of_get_ddr_timing.patch b/patches.suse/memory-of-Fix-refcount-leak-bug-in-of_get_ddr_timing.patch new file mode 100644 index 0000000..ee915a4 --- /dev/null +++ b/patches.suse/memory-of-Fix-refcount-leak-bug-in-of_get_ddr_timing.patch @@ -0,0 +1,37 @@ +From 05215fb32010d4afb68fbdbb4d237df6e2d4567b Mon Sep 17 00:00:00 2001 +From: Liang He +Date: Tue, 19 Jul 2022 16:56:39 +0800 +Subject: [PATCH] memory: of: Fix refcount leak bug in of_get_ddr_timings() +Git-commit: 05215fb32010d4afb68fbdbb4d237df6e2d4567b +Patch-mainline: v6.1-rc1 +References: git-fixes + +We should add the of_node_put() when breaking out of +for_each_child_of_node() as it will automatically increase +and decrease the refcount. + +Fixes: e6b42eb6a66c ("memory: emif: add device tree support to emif driver") +Signed-off-by: Liang He +Signed-off-by: Krzysztof Kozlowski +Link: https://lore.kernel.org/r/20220719085640.1210583-1-windhl@126.com +Acked-by: Takashi Iwai + +--- + drivers/memory/of_memory.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/memory/of_memory.c b/drivers/memory/of_memory.c +index dbdf87bc0b78..8e2ef4bf6b17 100644 +--- a/drivers/memory/of_memory.c ++++ b/drivers/memory/of_memory.c +@@ -134,6 +134,7 @@ const struct lpddr2_timings *of_get_ddr_timings(struct device_node *np_ddr, + for_each_child_of_node(np_ddr, np_tim) { + if (of_device_is_compatible(np_tim, tim_compat)) { + if (of_do_get_timings(np_tim, &timings[i])) { ++ of_node_put(np_tim); + devm_kfree(dev, timings); + goto default_timings; + } +-- +2.35.3 + diff --git a/patches.suse/memory-of-Fix-refcount-leak-bug-in-of_lpddr3_get_ddr.patch b/patches.suse/memory-of-Fix-refcount-leak-bug-in-of_lpddr3_get_ddr.patch new file mode 100644 index 0000000..c913fe9 --- /dev/null +++ b/patches.suse/memory-of-Fix-refcount-leak-bug-in-of_lpddr3_get_ddr.patch @@ -0,0 +1,37 @@ +From 48af14fb0eaa63d9aa68f59fb0b205ec55a95636 Mon Sep 17 00:00:00 2001 +From: Liang He +Date: Tue, 19 Jul 2022 16:56:40 +0800 +Subject: [PATCH] memory: of: Fix refcount leak bug in of_lpddr3_get_ddr_timings() +Git-commit: 48af14fb0eaa63d9aa68f59fb0b205ec55a95636 +Patch-mainline: v6.1-rc1 +References: git-fixes + +We should add the of_node_put() when breaking out of +for_each_child_of_node() as it will automatically increase +and decrease the refcount. + +Fixes: 976897dd96db ("memory: Extend of_memory with LPDDR3 support") +Signed-off-by: Liang He +Signed-off-by: Krzysztof Kozlowski +Link: https://lore.kernel.org/r/20220719085640.1210583-2-windhl@126.com +Acked-by: Takashi Iwai + +--- + drivers/memory/of_memory.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/memory/of_memory.c b/drivers/memory/of_memory.c +index 8e2ef4bf6b17..fcd20d85d385 100644 +--- a/drivers/memory/of_memory.c ++++ b/drivers/memory/of_memory.c +@@ -285,6 +285,7 @@ const struct lpddr3_timings + if (of_device_is_compatible(np_tim, tim_compat)) { + if (of_lpddr3_do_get_timings(np_tim, &timings[i])) { + devm_kfree(dev, timings); ++ of_node_put(np_tim); + goto default_timings; + } + i++; +-- +2.35.3 + diff --git a/patches.suse/memory-pl353-smc-Fix-refcount-leak-bug-in-pl353_smc_.patch b/patches.suse/memory-pl353-smc-Fix-refcount-leak-bug-in-pl353_smc_.patch new file mode 100644 index 0000000..692289f --- /dev/null +++ b/patches.suse/memory-pl353-smc-Fix-refcount-leak-bug-in-pl353_smc_.patch @@ -0,0 +1,41 @@ +From 61b3c876c1cbdb1efd1f52a1f348580e6e14efb6 Mon Sep 17 00:00:00 2001 +From: Liang He +Date: Sat, 16 Jul 2022 11:13:24 +0800 +Subject: [PATCH] memory: pl353-smc: Fix refcount leak bug in pl353_smc_probe() +Git-commit: 61b3c876c1cbdb1efd1f52a1f348580e6e14efb6 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The break of for_each_available_child_of_node() needs a +corresponding of_node_put() when the reference 'child' is not +used anymore. Here we do not need to call of_node_put() in +fail path as '!match' means no break. + +While the of_platform_device_create() will created a new +reference by 'child' but it has considered the refcounting. + +Fixes: fee10bd22678 ("memory: pl353: Add driver for arm pl353 static memory controller") +Signed-off-by: Liang He +Signed-off-by: Krzysztof Kozlowski +Link: https://lore.kernel.org/r/20220716031324.447680-1-windhl@126.com +Acked-by: Takashi Iwai + +--- + drivers/memory/pl353-smc.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/memory/pl353-smc.c b/drivers/memory/pl353-smc.c +index f84b98278745..d39ee7d06665 100644 +--- a/drivers/memory/pl353-smc.c ++++ b/drivers/memory/pl353-smc.c +@@ -122,6 +122,7 @@ static int pl353_smc_probe(struct amba_device *adev, const struct amba_id *id) + } + + of_platform_device_create(child, NULL, &adev->dev); ++ of_node_put(child); + + return 0; + +-- +2.35.3 + diff --git a/patches.suse/mfd-fsl-imx25-Fix-an-error-handling-path-in-mx25_tsa.patch b/patches.suse/mfd-fsl-imx25-Fix-an-error-handling-path-in-mx25_tsa.patch new file mode 100644 index 0000000..c194e49 --- /dev/null +++ b/patches.suse/mfd-fsl-imx25-Fix-an-error-handling-path-in-mx25_tsa.patch @@ -0,0 +1,82 @@ +From 3fa9e4cfb55da512ebfd57336fde468830719298 Mon Sep 17 00:00:00 2001 +From: Christophe JAILLET +Date: Sun, 31 Jul 2022 14:06:23 +0200 +Subject: [PATCH] mfd: fsl-imx25: Fix an error handling path in mx25_tsadc_setup_irq() +Git-commit: 3fa9e4cfb55da512ebfd57336fde468830719298 +Patch-mainline: v6.1-rc1 +References: git-fixes + +If devm_of_platform_populate() fails, some resources need to be +released. + +Introduce a mx25_tsadc_unset_irq() function that undoes +mx25_tsadc_setup_irq() and call it both from the new error handling path +of the probe and in the remove function. + +Fixes: a55196eff6d6 ("mfd: fsl-imx25: Use devm_of_platform_populate()") +Signed-off-by: Christophe JAILLET +Signed-off-by: Lee Jones +Link: https://lore.kernel.org/r/d404e04828fc06bcfddf81f9f3e9b4babbe35415.1659269156.git.christophe.jaillet@wanadoo.fr +Acked-by: Takashi Iwai + +--- + drivers/mfd/fsl-imx25-tsadc.c | 32 ++++++++++++++++++++++++-------- + 1 file changed, 24 insertions(+), 8 deletions(-) + +diff --git a/drivers/mfd/fsl-imx25-tsadc.c b/drivers/mfd/fsl-imx25-tsadc.c +index 37e5e02a1d05..85f7982d26d2 100644 +--- a/drivers/mfd/fsl-imx25-tsadc.c ++++ b/drivers/mfd/fsl-imx25-tsadc.c +@@ -84,6 +84,19 @@ static int mx25_tsadc_setup_irq(struct platform_device *pdev, + return 0; + } + ++static int mx25_tsadc_unset_irq(struct platform_device *pdev) ++{ ++ struct mx25_tsadc *tsadc = platform_get_drvdata(pdev); ++ int irq = platform_get_irq(pdev, 0); ++ ++ if (irq) { ++ irq_set_chained_handler_and_data(irq, NULL, NULL); ++ irq_domain_remove(tsadc->domain); ++ } ++ ++ return 0; ++} ++ + static void mx25_tsadc_setup_clk(struct platform_device *pdev, + struct mx25_tsadc *tsadc) + { +@@ -171,18 +184,21 @@ static int mx25_tsadc_probe(struct platform_device *pdev) + + platform_set_drvdata(pdev, tsadc); + +- return devm_of_platform_populate(dev); ++ ret = devm_of_platform_populate(dev); ++ if (ret) ++ goto err_irq; ++ ++ return 0; ++ ++err_irq: ++ mx25_tsadc_unset_irq(pdev); ++ ++ return ret; + } + + static int mx25_tsadc_remove(struct platform_device *pdev) + { +- struct mx25_tsadc *tsadc = platform_get_drvdata(pdev); +- int irq = platform_get_irq(pdev, 0); +- +- if (irq) { +- irq_set_chained_handler_and_data(irq, NULL, NULL); +- irq_domain_remove(tsadc->domain); +- } ++ mx25_tsadc_unset_irq(pdev); + + return 0; + } +-- +2.35.3 + diff --git a/patches.suse/mfd-fsl-imx25-Fix-check-for-platform_get_irq-errors.patch b/patches.suse/mfd-fsl-imx25-Fix-check-for-platform_get_irq-errors.patch new file mode 100644 index 0000000..dc14c36 --- /dev/null +++ b/patches.suse/mfd-fsl-imx25-Fix-check-for-platform_get_irq-errors.patch @@ -0,0 +1,49 @@ +From 75db7907355ca5e2ff606e9dd3e86b6c3a455fe2 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Thu, 11 Aug 2022 13:53:05 +0300 +Subject: [PATCH] mfd: fsl-imx25: Fix check for platform_get_irq() errors +Git-commit: 75db7907355ca5e2ff606e9dd3e86b6c3a455fe2 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The mx25_tsadc_remove() function assumes all non-zero returns are success +but the platform_get_irq() function returns negative on error and +positive non-zero values on success. It never returns zero, but if it +did then treat that as a success. + +Fixes: 18f773937968 ("mfd: fsl-imx25: Clean up irq settings during removal") +Signed-off-by: Dan Carpenter +Reviewed-by: Martin Kaiser +Signed-off-by: Lee Jones +Link: https://lore.kernel.org/r/YvTfkbVQWYKMKS/t@kili +Acked-by: Takashi Iwai + +--- + drivers/mfd/fsl-imx25-tsadc.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/mfd/fsl-imx25-tsadc.c b/drivers/mfd/fsl-imx25-tsadc.c +index 85f7982d26d2..823595bcc9b7 100644 +--- a/drivers/mfd/fsl-imx25-tsadc.c ++++ b/drivers/mfd/fsl-imx25-tsadc.c +@@ -69,7 +69,7 @@ static int mx25_tsadc_setup_irq(struct platform_device *pdev, + int irq; + + irq = platform_get_irq(pdev, 0); +- if (irq <= 0) ++ if (irq < 0) + return irq; + + tsadc->domain = irq_domain_add_simple(np, 2, 0, &mx25_tsadc_domain_ops, +@@ -89,7 +89,7 @@ static int mx25_tsadc_unset_irq(struct platform_device *pdev) + struct mx25_tsadc *tsadc = platform_get_drvdata(pdev); + int irq = platform_get_irq(pdev, 0); + +- if (irq) { ++ if (irq >= 0) { + irq_set_chained_handler_and_data(irq, NULL, NULL); + irq_domain_remove(tsadc->domain); + } +-- +2.35.3 + diff --git a/patches.suse/mfd-intel-lpss-Add-Intel-Raptor-Lake-PCH-S-PCI-IDs.patch b/patches.suse/mfd-intel-lpss-Add-Intel-Raptor-Lake-PCH-S-PCI-IDs.patch new file mode 100644 index 0000000..957aa97 --- /dev/null +++ b/patches.suse/mfd-intel-lpss-Add-Intel-Raptor-Lake-PCH-S-PCI-IDs.patch @@ -0,0 +1,49 @@ +From 8c70bd5802f4f51979f3b8a887088837edd56341 Mon Sep 17 00:00:00 2001 +From: Jarkko Nikula +Date: Fri, 11 Feb 2022 16:50:55 +0200 +Subject: [PATCH] mfd: intel-lpss: Add Intel Raptor Lake PCH-S PCI IDs +Git-commit: 8c70bd5802f4f51979f3b8a887088837edd56341 +Patch-mainline: v5.18-rc1 +References: jsc#PED-634 + +Add Intel Raptor Lake PCH-S LPSS PCI IDs. + +Signed-off-by: Jarkko Nikula +Reviewed-by: Andy Shevchenko +Signed-off-by: Lee Jones +Link: https://lore.kernel.org/r/20220211145055.992179-1-jarkko.nikula@linux.intel.com +Acked-by: Takashi Iwai + +--- + drivers/mfd/intel-lpss-pci.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/drivers/mfd/intel-lpss-pci.c b/drivers/mfd/intel-lpss-pci.c +index 5513fae6be92..962ee14c62dd 100644 +--- a/drivers/mfd/intel-lpss-pci.c ++++ b/drivers/mfd/intel-lpss-pci.c +@@ -353,6 +353,21 @@ static const struct pci_device_id intel_lpss_pci_ids[] = { + { PCI_VDEVICE(INTEL, 0x5ac4), (kernel_ulong_t)&bxt_info }, + { PCI_VDEVICE(INTEL, 0x5ac6), (kernel_ulong_t)&bxt_info }, + { PCI_VDEVICE(INTEL, 0x5aee), (kernel_ulong_t)&bxt_uart_info }, ++ /* RPL-S */ ++ { PCI_VDEVICE(INTEL, 0x7a28), (kernel_ulong_t)&bxt_uart_info }, ++ { PCI_VDEVICE(INTEL, 0x7a29), (kernel_ulong_t)&bxt_uart_info }, ++ { PCI_VDEVICE(INTEL, 0x7a2a), (kernel_ulong_t)&bxt_info }, ++ { PCI_VDEVICE(INTEL, 0x7a2b), (kernel_ulong_t)&bxt_info }, ++ { PCI_VDEVICE(INTEL, 0x7a4c), (kernel_ulong_t)&bxt_i2c_info }, ++ { PCI_VDEVICE(INTEL, 0x7a4d), (kernel_ulong_t)&bxt_i2c_info }, ++ { PCI_VDEVICE(INTEL, 0x7a4e), (kernel_ulong_t)&bxt_i2c_info }, ++ { PCI_VDEVICE(INTEL, 0x7a4f), (kernel_ulong_t)&bxt_i2c_info }, ++ { PCI_VDEVICE(INTEL, 0x7a5c), (kernel_ulong_t)&bxt_uart_info }, ++ { PCI_VDEVICE(INTEL, 0x7a79), (kernel_ulong_t)&bxt_info }, ++ { PCI_VDEVICE(INTEL, 0x7a7b), (kernel_ulong_t)&bxt_info }, ++ { PCI_VDEVICE(INTEL, 0x7a7c), (kernel_ulong_t)&bxt_i2c_info }, ++ { PCI_VDEVICE(INTEL, 0x7a7d), (kernel_ulong_t)&bxt_i2c_info }, ++ { PCI_VDEVICE(INTEL, 0x7a7e), (kernel_ulong_t)&bxt_uart_info }, + /* ADL-S */ + { PCI_VDEVICE(INTEL, 0x7aa8), (kernel_ulong_t)&bxt_uart_info }, + { PCI_VDEVICE(INTEL, 0x7aa9), (kernel_ulong_t)&bxt_uart_info }, +-- +2.35.3 + diff --git a/patches.suse/mfd-intel_soc_pmic-Fix-an-error-handling-path-in-int.patch b/patches.suse/mfd-intel_soc_pmic-Fix-an-error-handling-path-in-int.patch new file mode 100644 index 0000000..bf2b5a9 --- /dev/null +++ b/patches.suse/mfd-intel_soc_pmic-Fix-an-error-handling-path-in-int.patch @@ -0,0 +1,41 @@ +From 48749cabba109397b4e7dd556e85718ec0ec114d Mon Sep 17 00:00:00 2001 +From: Christophe JAILLET +Date: Mon, 1 Aug 2022 14:42:02 +0300 +Subject: [PATCH] mfd: intel_soc_pmic: Fix an error handling path in intel_soc_pmic_i2c_probe() +Git-commit: 48749cabba109397b4e7dd556e85718ec0ec114d +Patch-mainline: v6.1-rc1 +References: git-fixes + +The commit in Fixes: has added a pwm_add_table() call in the probe() and +a pwm_remove_table() call in the remove(), but forget to update the error +handling path of the probe. + +Add the missing pwm_remove_table() call. + +Fixes: a3aa9a93df9f ("mfd: intel_soc_pmic_core: ADD PWM lookup table for CRC PMIC based PWM") +Signed-off-by: Christophe JAILLET +Signed-off-by: Andy Shevchenko +Reviewed-by: Hans de Goede +Signed-off-by: Lee Jones +Link: https://lore.kernel.org/r/20220801114211.36267-1-andriy.shevchenko@linux.intel.com +Acked-by: Takashi Iwai + +--- + drivers/mfd/intel_soc_pmic_core.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/mfd/intel_soc_pmic_core.c b/drivers/mfd/intel_soc_pmic_core.c +index 5e8c94e008ed..85d070bce0e2 100644 +--- a/drivers/mfd/intel_soc_pmic_core.c ++++ b/drivers/mfd/intel_soc_pmic_core.c +@@ -77,6 +77,7 @@ static int intel_soc_pmic_i2c_probe(struct i2c_client *i2c, + return 0; + + err_del_irq_chip: ++ pwm_remove_table(crc_pwm_lookup, ARRAY_SIZE(crc_pwm_lookup)); + regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data); + return ret; + } +-- +2.35.3 + diff --git a/patches.suse/mfd-lp8788-Fix-an-error-handling-path-in-lp8788_irq_.patch b/patches.suse/mfd-lp8788-Fix-an-error-handling-path-in-lp8788_irq_.patch new file mode 100644 index 0000000..d43b159 --- /dev/null +++ b/patches.suse/mfd-lp8788-Fix-an-error-handling-path-in-lp8788_irq_.patch @@ -0,0 +1,47 @@ +From 557244f6284f30613f2d61f14b579303165876c3 Mon Sep 17 00:00:00 2001 +From: Christophe JAILLET +Date: Sun, 31 Jul 2022 11:55:38 +0200 +Subject: [PATCH] mfd: lp8788: Fix an error handling path in lp8788_irq_init() and lp8788_irq_init() +Git-commit: 557244f6284f30613f2d61f14b579303165876c3 +Patch-mainline: v6.1-rc1 +References: git-fixes + +In lp8788_irq_init(), if an error occurs after a successful +irq_domain_add_linear() call, it must be undone by a corresponding +irq_domain_remove() call. + +irq_domain_remove() should also be called in lp8788_irq_exit() for the same +reason. + +Fixes: eea6b7cc53aa ("mfd: Add lp8788 mfd driver") +Signed-off-by: Christophe JAILLET +Signed-off-by: Lee Jones +Link: https://lore.kernel.org/r/bcd5a72c9c1c383dd6324680116426e32737655a.1659261275.git.christophe.jaillet@wanadoo.fr +Acked-by: Takashi Iwai + +--- + drivers/mfd/lp8788-irq.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/mfd/lp8788-irq.c b/drivers/mfd/lp8788-irq.c +index 348439a3fbbd..39006297f3d2 100644 +--- a/drivers/mfd/lp8788-irq.c ++++ b/drivers/mfd/lp8788-irq.c +@@ -175,6 +175,7 @@ int lp8788_irq_init(struct lp8788 *lp, int irq) + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + "lp8788-irq", irqd); + if (ret) { ++ irq_domain_remove(lp->irqdm); + dev_err(lp->dev, "failed to create a thread for IRQ_N\n"); + return ret; + } +@@ -188,4 +189,6 @@ void lp8788_irq_exit(struct lp8788 *lp) + { + if (lp->irq) + free_irq(lp->irq, lp->irqdm); ++ if (lp->irqdm) ++ irq_domain_remove(lp->irqdm); + } +-- +2.35.3 + diff --git a/patches.suse/mfd-lp8788-Fix-an-error-handling-path-in-lp8788_prob.patch b/patches.suse/mfd-lp8788-Fix-an-error-handling-path-in-lp8788_prob.patch new file mode 100644 index 0000000..fe06c7e --- /dev/null +++ b/patches.suse/mfd-lp8788-Fix-an-error-handling-path-in-lp8788_prob.patch @@ -0,0 +1,50 @@ +From becfdcd75126b20b8ec10066c5e85b34f8994ad5 Mon Sep 17 00:00:00 2001 +From: Christophe JAILLET +Date: Sun, 31 Jul 2022 11:55:27 +0200 +Subject: [PATCH] mfd: lp8788: Fix an error handling path in lp8788_probe() +Git-commit: becfdcd75126b20b8ec10066c5e85b34f8994ad5 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Should an error occurs in mfd_add_devices(), some resources need to be +released, as already done in the .remove() function. + +Add an error handling path and a lp8788_irq_exit() call to undo a previous +lp8788_irq_init(). + +Fixes: eea6b7cc53aa ("mfd: Add lp8788 mfd driver") +Signed-off-by: Christophe JAILLET +Signed-off-by: Lee Jones +Link: https://lore.kernel.org/r/18398722da9df9490722d853e4797350189ae79b.1659261275.git.christophe.jaillet@wanadoo.fr +Acked-by: Takashi Iwai + +--- + drivers/mfd/lp8788.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/drivers/mfd/lp8788.c b/drivers/mfd/lp8788.c +index c223d2c6a363..998e8cc408a0 100644 +--- a/drivers/mfd/lp8788.c ++++ b/drivers/mfd/lp8788.c +@@ -195,8 +195,16 @@ static int lp8788_probe(struct i2c_client *cl, const struct i2c_device_id *id) + if (ret) + return ret; + +- return mfd_add_devices(lp->dev, -1, lp8788_devs, +- ARRAY_SIZE(lp8788_devs), NULL, 0, NULL); ++ ret = mfd_add_devices(lp->dev, -1, lp8788_devs, ++ ARRAY_SIZE(lp8788_devs), NULL, 0, NULL); ++ if (ret) ++ goto err_exit_irq; ++ ++ return 0; ++ ++err_exit_irq: ++ lp8788_irq_exit(lp); ++ return ret; + } + + static int lp8788_remove(struct i2c_client *cl) +-- +2.35.3 + diff --git a/patches.suse/mfd-sm501-Add-check-for-platform_driver_register.patch b/patches.suse/mfd-sm501-Add-check-for-platform_driver_register.patch new file mode 100644 index 0000000..c1df81e --- /dev/null +++ b/patches.suse/mfd-sm501-Add-check-for-platform_driver_register.patch @@ -0,0 +1,43 @@ +From 8325a6c24ad78b8c1acc3c42b098ee24105d68e5 Mon Sep 17 00:00:00 2001 +From: Jiasheng Jiang +Date: Tue, 13 Sep 2022 17:11:12 +0800 +Subject: [PATCH] mfd: sm501: Add check for platform_driver_register() +Git-commit: 8325a6c24ad78b8c1acc3c42b098ee24105d68e5 +Patch-mainline: v6.1-rc1 +References: git-fixes + +As platform_driver_register() can return error numbers, +it should be better to check platform_driver_register() +and deal with the exception. + +Fixes: b6d6454fdb66 ("[PATCH] mfd: SM501 core driver") +Signed-off-by: Jiasheng Jiang +Signed-off-by: Lee Jones +Link: https://lore.kernel.org/r/20220913091112.1739138-1-jiasheng@iscas.ac.cn +Acked-by: Takashi Iwai + +--- + drivers/mfd/sm501.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c +index bc0a2c38653e..3ac4508a6742 100644 +--- a/drivers/mfd/sm501.c ++++ b/drivers/mfd/sm501.c +@@ -1720,7 +1720,12 @@ static struct platform_driver sm501_plat_driver = { + + static int __init sm501_base_init(void) + { +- platform_driver_register(&sm501_plat_driver); ++ int ret; ++ ++ ret = platform_driver_register(&sm501_plat_driver); ++ if (ret < 0) ++ return ret; ++ + return pci_register_driver(&sm501_pci_driver); + } + +-- +2.35.3 + diff --git a/patches.suse/misc-cs35l41-Remove-unused-pdn-variable.patch b/patches.suse/misc-cs35l41-Remove-unused-pdn-variable.patch new file mode 100644 index 0000000..9924c5c --- /dev/null +++ b/patches.suse/misc-cs35l41-Remove-unused-pdn-variable.patch @@ -0,0 +1,43 @@ +From c6d1fa6c8f663bd49bfe7a20eccb0dc7e43db63a Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Thu, 16 Sep 2021 09:23:46 +0100 +Subject: [PATCH] misc: cs35l41: Remove unused pdn variable +Git-commit: c6d1fa6c8f663bd49bfe7a20eccb0dc7e43db63a +Patch-mainline: v5.16-rc1 +References: bsc#1203699 + +Remove pdn variable that was made redundant in an earlier patch. + +Fixes: c2f14cc2bcdd ("ASoC: cs35l41: Fix use of an uninitialised variable") +Signed-off-by: Charles Keepax +Link: https://lore.kernel.org/r/20210916082346.12001-1-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + sound/soc/codecs/cs35l41.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index ad86c030d9cb..b16eb6610c0e 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -564,7 +564,6 @@ static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w, + struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component); + unsigned int val; + int ret = 0; +- bool pdn; + + switch (event) { + case SND_SOC_DAPM_POST_PMU: +@@ -582,7 +581,6 @@ static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w, + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL1, + CS35L41_GLOBAL_EN_MASK, 0); + +- pdn = false; + ret = regmap_read_poll_timeout(cs35l41->regmap, CS35L41_IRQ1_STATUS1, + val, val & CS35L41_PDN_DONE_MASK, + 1000, 100000); +-- +2.35.3 + diff --git a/patches.suse/misc-ocxl-fix-possible-refcount-leak-in-afu_ioctl.patch b/patches.suse/misc-ocxl-fix-possible-refcount-leak-in-afu_ioctl.patch new file mode 100644 index 0000000..54f0b21 --- /dev/null +++ b/patches.suse/misc-ocxl-fix-possible-refcount-leak-in-afu_ioctl.patch @@ -0,0 +1,38 @@ +From c3b69ba5114c860d730870c03ab4ee45276e5e35 Mon Sep 17 00:00:00 2001 +From: Hangyu Hua +Date: Wed, 24 Aug 2022 16:26:00 +0800 +Subject: [PATCH] misc: ocxl: fix possible refcount leak in afu_ioctl() +Git-commit: c3b69ba5114c860d730870c03ab4ee45276e5e35 +Patch-mainline: v6.1-rc1 +References: git-fixes + +eventfd_ctx_put need to be called to put the refcount that gotten by +eventfd_ctx_fdget when ocxl_irq_set_handler fails. + +Fixes: 060146614643 ("ocxl: move event_fd handling to frontend") +Acked-by: Frederic Barrat +Signed-off-by: Hangyu Hua +Link: https://lore.kernel.org/r/20220824082600.36159-1-hbh25y@gmail.com +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/misc/ocxl/file.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/misc/ocxl/file.c b/drivers/misc/ocxl/file.c +index 6777c419a8da..d46dba2df5a1 100644 +--- a/drivers/misc/ocxl/file.c ++++ b/drivers/misc/ocxl/file.c +@@ -257,6 +257,8 @@ static long afu_ioctl(struct file *file, unsigned int cmd, + if (IS_ERR(ev_ctx)) + return PTR_ERR(ev_ctx); + rc = ocxl_irq_set_handler(ctx, irq_id, irq_handler, irq_free, ev_ctx); ++ if (rc) ++ eventfd_ctx_put(ev_ctx); + break; + + case OCXL_IOCTL_GET_METADATA: +-- +2.35.3 + diff --git a/patches.suse/misc-pci_endpoint_test-Aggregate-params-checking-for.patch b/patches.suse/misc-pci_endpoint_test-Aggregate-params-checking-for.patch new file mode 100644 index 0000000..12b6b3c --- /dev/null +++ b/patches.suse/misc-pci_endpoint_test-Aggregate-params-checking-for.patch @@ -0,0 +1,88 @@ +From 3e42deaac06567c7e86d287c305ccda24db4ae3d Mon Sep 17 00:00:00 2001 +From: Shunsuke Mie +Date: Wed, 7 Sep 2022 11:00:59 +0900 +Subject: [PATCH] misc: pci_endpoint_test: Aggregate params checking for xfer +Git-commit: 3e42deaac06567c7e86d287c305ccda24db4ae3d +Patch-mainline: v6.1-rc1 +References: git-fixes + +Each transfer test functions have same parameter checking code. This patch +unites those to an introduced function. + +Signed-off-by: Shunsuke Mie +Cc: stable +Link: https://lore.kernel.org/r/20220907020100.122588-1-mie@igel.co.jp +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/misc/pci_endpoint_test.c | 29 +++++++++++++++++++++++------ + 1 file changed, 23 insertions(+), 6 deletions(-) + +diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c +index 8f786a225dcf..39d477bb0989 100644 +--- a/drivers/misc/pci_endpoint_test.c ++++ b/drivers/misc/pci_endpoint_test.c +@@ -332,6 +332,17 @@ static bool pci_endpoint_test_msi_irq(struct pci_endpoint_test *test, + return false; + } + ++static int pci_endpoint_test_validate_xfer_params(struct device *dev, ++ struct pci_endpoint_test_xfer_param *param, size_t alignment) ++{ ++ if (param->size > SIZE_MAX - alignment) { ++ dev_dbg(dev, "Maximum transfer data size exceeded\n"); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ + static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, + unsigned long arg) + { +@@ -363,9 +374,11 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, + return false; + } + ++ err = pci_endpoint_test_validate_xfer_params(dev, ¶m, alignment); ++ if (err) ++ return false; ++ + size = param.size; +- if (size > SIZE_MAX - alignment) +- goto err; + + use_dma = !!(param.flags & PCITEST_FLAGS_USE_DMA); + if (use_dma) +@@ -497,9 +510,11 @@ static bool pci_endpoint_test_write(struct pci_endpoint_test *test, + return false; + } + ++ err = pci_endpoint_test_validate_xfer_params(dev, ¶m, alignment); ++ if (err) ++ return false; ++ + size = param.size; +- if (size > SIZE_MAX - alignment) +- goto err; + + use_dma = !!(param.flags & PCITEST_FLAGS_USE_DMA); + if (use_dma) +@@ -595,9 +610,11 @@ static bool pci_endpoint_test_read(struct pci_endpoint_test *test, + return false; + } + ++ err = pci_endpoint_test_validate_xfer_params(dev, ¶m, alignment); ++ if (err) ++ return false; ++ + size = param.size; +- if (size > SIZE_MAX - alignment) +- goto err; + + use_dma = !!(param.flags & PCITEST_FLAGS_USE_DMA); + if (use_dma) +-- +2.35.3 + diff --git a/patches.suse/misc-pci_endpoint_test-Fix-pci_endpoint_test_-copy-w.patch b/patches.suse/misc-pci_endpoint_test-Fix-pci_endpoint_test_-copy-w.patch new file mode 100644 index 0000000..db91bfb --- /dev/null +++ b/patches.suse/misc-pci_endpoint_test-Fix-pci_endpoint_test_-copy-w.patch @@ -0,0 +1,82 @@ +From 8e30538eca016de8e252bef174beadecd64239f0 Mon Sep 17 00:00:00 2001 +From: Shunsuke Mie +Date: Wed, 7 Sep 2022 11:01:00 +0900 +Subject: [PATCH] misc: pci_endpoint_test: Fix pci_endpoint_test_{copy,write,read}() panic +Git-commit: 8e30538eca016de8e252bef174beadecd64239f0 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The dma_map_single() doesn't permit zero length mapping. It causes a follow +panic. + +A panic was reported on arm64: + +[ 60.137988] ------------[ cut here ]------------ +[ 60.142630] kernel BUG at kernel/dma/swiotlb.c:624! +[ 60.147508] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP +[ 60.152992] Modules linked in: dw_hdmi_cec crct10dif_ce simple_bridge rcar_fdp1 vsp1 rcar_vin videobuf2_vmalloc rcar_csi2 v4l +2_mem2mem videobuf2_dma_contig videobuf2_memops pci_endpoint_test videobuf2_v4l2 videobuf2_common rcar_fcp v4l2_fwnode v4l2_asyn +c videodev mc gpio_bd9571mwv max9611 pwm_rcar ccree at24 authenc libdes phy_rcar_gen3_usb3 usb_dmac display_connector pwm_bl +[ 60.186252] CPU: 0 PID: 508 Comm: pcitest Not tainted 6.0.0-rc1rpci-dev+ #237 +[ 60.193387] Hardware name: Renesas Salvator-X 2nd version board based on r8a77951 (DT) +[ 60.201302] pstate: 00000005 (nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) +[ 60.208263] pc : swiotlb_tbl_map_single+0x2c0/0x590 +[ 60.213149] lr : swiotlb_map+0x88/0x1f0 +[ 60.216982] sp : ffff80000a883bc0 +[ 60.220292] x29: ffff80000a883bc0 x28: 0000000000000000 x27: 0000000000000000 +[ 60.227430] x26: 0000000000000000 x25: ffff0004c0da20d0 x24: ffff80000a1f77c0 +[ 60.234567] x23: 0000000000000002 x22: 0001000040000010 x21: 000000007a000000 +[ 60.241703] x20: 0000000000200000 x19: 0000000000000000 x18: 0000000000000000 +[ 60.248840] x17: 0000000000000000 x16: 0000000000000000 x15: ffff0006ff7b9180 +[ 60.255977] x14: ffff0006ff7b9180 x13: 0000000000000000 x12: 0000000000000000 +[ 60.263113] x11: 0000000000000000 x10: 0000000000000000 x9 : 0000000000000000 +[ 60.270249] x8 : 0001000000000010 x7 : ffff0004c6754b20 x6 : 0000000000000000 +[ 60.277385] x5 : ffff0004c0da2090 x4 : 0000000000000000 x3 : 0000000000000001 +[ 60.284521] x2 : 0000000040000000 x1 : 0000000000000000 x0 : 0000000040000010 +[ 60.291658] Call trace: +[ 60.294100] swiotlb_tbl_map_single+0x2c0/0x590 +[ 60.298629] swiotlb_map+0x88/0x1f0 +[ 60.302115] dma_map_page_attrs+0x188/0x230 +[ 60.306299] pci_endpoint_test_ioctl+0x5e4/0xd90 [pci_endpoint_test] +[ 60.312660] __arm64_sys_ioctl+0xa8/0xf0 +[ 60.316583] invoke_syscall+0x44/0x108 +[ 60.320334] el0_svc_common.constprop.0+0xcc/0xf0 +[ 60.325038] do_el0_svc+0x2c/0xb8 +[ 60.328351] el0_svc+0x2c/0x88 +[ 60.331406] el0t_64_sync_handler+0xb8/0xc0 +[ 60.335587] el0t_64_sync+0x18c/0x190 +[ 60.339251] Code: 52800013 d2e00414 35fff45c d503201f (d4210000) +[ 60.345344] ---[ end trace 0000000000000000 ]--- + +To fix it, this patch adds a checking the payload length if it is zero. + +Fixes: 343dc693f7b7 ("misc: pci_endpoint_test: Prevent some integer overflows") +Cc: stable +Signed-off-by: Shunsuke Mie +Link: https://lore.kernel.org/r/20220907020100.122588-2-mie@igel.co.jp +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/misc/pci_endpoint_test.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c +index 39d477bb0989..11530b4ec389 100644 +--- a/drivers/misc/pci_endpoint_test.c ++++ b/drivers/misc/pci_endpoint_test.c +@@ -335,6 +335,11 @@ static bool pci_endpoint_test_msi_irq(struct pci_endpoint_test *test, + static int pci_endpoint_test_validate_xfer_params(struct device *dev, + struct pci_endpoint_test_xfer_param *param, size_t alignment) + { ++ if (!param->size) { ++ dev_dbg(dev, "Data size is zero\n"); ++ return -EINVAL; ++ } ++ + if (param->size > SIZE_MAX - alignment) { + dev_dbg(dev, "Maximum transfer data size exceeded\n"); + return -EINVAL; +-- +2.35.3 + diff --git a/patches.suse/misc-sgi-gru-fix-use-after-free-error-in-gru_set_con.patch b/patches.suse/misc-sgi-gru-fix-use-after-free-error-in-gru_set_con.patch new file mode 100644 index 0000000..faec977 --- /dev/null +++ b/patches.suse/misc-sgi-gru-fix-use-after-free-error-in-gru_set_con.patch @@ -0,0 +1,144 @@ +From: Zheng Wang +Date: Thu, 6 Oct 2022 23:26:43 +0800 +Subject: [PATCH] misc: sgi-gru: fix use-after-free error in + gru_set_context_option, gru_fault and gru_handle_user_call_os +Message-Id: <20221006152643.1694235-1-zyytlz.wz@163.com> +Patch-mainline: Submitted, LKML +References: CVE-2022-3424 bsc#1204166 + +Gts may be freed in gru_check_chiplet_assignment. +The caller still use it after that, UAF happens. + +Fix it by introducing a return value to see if it's in error path or not. +Free the gts in caller if gru_check_chiplet_assignment check failed. + +Fixes: 55484c45dbec ("gru: allow users to specify gru chiplet 2") +Reported-by: Zheng Wang +Signed-off-by: Zheng Wang +Signed-off-by: Takashi Iwai + +--- + drivers/misc/sgi-gru/grufault.c | 15 ++++++++++++--- + drivers/misc/sgi-gru/grumain.c | 17 +++++++++++++---- + drivers/misc/sgi-gru/grutables.h | 2 +- + 3 files changed, 26 insertions(+), 8 deletions(-) + +diff --git a/drivers/misc/sgi-gru/grufault.c b/drivers/misc/sgi-gru/grufault.c +index d7ef61e602ed..f1e5b96fef4b 100644 +--- a/drivers/misc/sgi-gru/grufault.c ++++ b/drivers/misc/sgi-gru/grufault.c +@@ -656,7 +656,9 @@ int gru_handle_user_call_os(unsigned long cb) + if (ucbnum >= gts->ts_cbr_au_count * GRU_CBR_AU_SIZE) + goto exit; + +- gru_check_context_placement(gts); ++ ret = gru_check_context_placement(gts); ++ if (ret) ++ goto err; + + /* + * CCH may contain stale data if ts_force_cch_reload is set. +@@ -677,6 +679,10 @@ int gru_handle_user_call_os(unsigned long cb) + exit: + gru_unlock_gts(gts); + return ret; ++err: ++ gru_unlock_gts(gts); ++ gru_unload_context(gts, 1); ++ return -EINVAL; + } + + /* +@@ -874,7 +880,7 @@ int gru_set_context_option(unsigned long arg) + } else { + gts->ts_user_blade_id = req.val1; + gts->ts_user_chiplet_id = req.val0; +- gru_check_context_placement(gts); ++ ret = gru_check_context_placement(gts); + } + break; + case sco_gseg_owner: +@@ -889,6 +895,9 @@ int gru_set_context_option(unsigned long arg) + ret = -EINVAL; + } + gru_unlock_gts(gts); +- ++ if (ret) { ++ gru_unload_context(gts, 1); ++ ret = -EINVAL; ++ } + return ret; + } +diff --git a/drivers/misc/sgi-gru/grumain.c b/drivers/misc/sgi-gru/grumain.c +index 9afda47efbf2..79903cf7e706 100644 +--- a/drivers/misc/sgi-gru/grumain.c ++++ b/drivers/misc/sgi-gru/grumain.c +@@ -716,9 +716,10 @@ static int gru_check_chiplet_assignment(struct gru_state *gru, + * chiplet. Misassignment can occur if the process migrates to a different + * blade or if the user changes the selected blade/chiplet. + */ +-void gru_check_context_placement(struct gru_thread_state *gts) ++int gru_check_context_placement(struct gru_thread_state *gts) + { + struct gru_state *gru; ++ int ret = 0; + + /* + * If the current task is the context owner, verify that the +@@ -727,14 +728,16 @@ void gru_check_context_placement(struct gru_thread_state *gts) + */ + gru = gts->ts_gru; + if (!gru || gts->ts_tgid_owner != current->tgid) +- return; ++ return ret; + + if (!gru_check_chiplet_assignment(gru, gts)) { + STAT(check_context_unload); +- gru_unload_context(gts, 1); ++ ret = -EINVAL; + } else if (gru_retarget_intr(gts)) { + STAT(check_context_retarget_intr); + } ++ ++ return ret; + } + + +@@ -919,6 +922,7 @@ vm_fault_t gru_fault(struct vm_fault *vmf) + struct gru_thread_state *gts; + unsigned long paddr, vaddr; + unsigned long expires; ++ int ret; + + vaddr = vmf->address; + gru_dbg(grudev, "vma %p, vaddr 0x%lx (0x%lx)\n", +@@ -934,7 +938,12 @@ vm_fault_t gru_fault(struct vm_fault *vmf) + mutex_lock(>s->ts_ctxlock); + preempt_disable(); + +- gru_check_context_placement(gts); ++ ret = gru_check_context_placement(gts); ++ if (ret) { ++ mutex_unlock(>s->ts_ctxlock); ++ gru_unload_context(gts, 1); ++ return ret; ++ } + + if (!gts->ts_gru) { + STAT(load_user_context); +diff --git a/drivers/misc/sgi-gru/grutables.h b/drivers/misc/sgi-gru/grutables.h +index 5efc869fe59a..f4a5a787685f 100644 +--- a/drivers/misc/sgi-gru/grutables.h ++++ b/drivers/misc/sgi-gru/grutables.h +@@ -632,7 +632,7 @@ extern int gru_user_flush_tlb(unsigned long arg); + extern int gru_user_unload_context(unsigned long arg); + extern int gru_get_exception_detail(unsigned long arg); + extern int gru_set_context_option(unsigned long address); +-extern void gru_check_context_placement(struct gru_thread_state *gts); ++extern int gru_check_context_placement(struct gru_thread_state *gts); + extern int gru_cpu_fault_map_id(void); + extern struct vm_area_struct *gru_find_vma(unsigned long vaddr); + extern void gru_flush_all_tlb(struct gru_state *gru); +-- +2.35.3 + diff --git a/patches.suse/mlxsw-spectrum_cnt-Reorder-counter-pools.patch b/patches.suse/mlxsw-spectrum_cnt-Reorder-counter-pools.patch new file mode 100644 index 0000000..9a4ac4c --- /dev/null +++ b/patches.suse/mlxsw-spectrum_cnt-Reorder-counter-pools.patch @@ -0,0 +1,50 @@ +From e7cb8ce7cfe1a4afcb9b684894c7755bd4f84f8e Mon Sep 17 00:00:00 2001 +From: Petr Machata +Date: Mon, 13 Jun 2022 15:50:17 +0300 +Subject: [PATCH 20/32] mlxsw: spectrum_cnt: Reorder counter pools +Git-commit: 4b7a632ac4e7101ceefee8484d5c2ca505d347b3 +References: git-fixes +Patch-mainline: v5.19-rc3 + +Both RIF and ACL flow counters use a 24-bit SW-managed counter address to +communicate which counter they want to bind. + +In a number of Spectrum FW releases, binding a RIF counter is broken and +slices the counter index to 16 bits. As a result, on Spectrum-2 and above, +no more than about 410 RIF counters can be effectively used. This +translates to 205 netdevices for which L3 HW stats can be enabled. (This +does not happen on Spectrum-1, because there are fewer counters available +overall and the counter index never exceeds 16 bits.) + +Binding counters to ACLs does not have this issue. Therefore reorder the +counter allocation scheme so that RIF counters come first and therefore get +lower indices that are below the 16-bit barrier. + +Fixes: 98e60dce4da1 ("Merge branch 'mlxsw-Introduce-initial-Spectrum-2-support'") +Reported-by: Maksym Yaremchuk +Signed-off-by: Petr Machata +Signed-off-by: Ido Schimmel +Link: https://lore.kernel.org/r/20220613125017.2018162-1-idosch@nvidia.com +Signed-off-by: Paolo Abeni +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.h +index a68d931090dd..15c8d4de8350 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.h ++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.h +@@ -8,8 +8,8 @@ + #include "spectrum.h" + + enum mlxsw_sp_counter_sub_pool_id { +- MLXSW_SP_COUNTER_SUB_POOL_FLOW, + MLXSW_SP_COUNTER_SUB_POOL_RIF, ++ MLXSW_SP_COUNTER_SUB_POOL_FLOW, + }; + + int mlxsw_sp_counter_alloc(struct mlxsw_sp *mlxsw_sp, +-- +2.16.4 + diff --git a/patches.suse/mlxsw-spectrum_router-Fix-IPv4-nexthop-gateway-indic.patch b/patches.suse/mlxsw-spectrum_router-Fix-IPv4-nexthop-gateway-indic.patch new file mode 100644 index 0000000..7d0a2c9 --- /dev/null +++ b/patches.suse/mlxsw-spectrum_router-Fix-IPv4-nexthop-gateway-indic.patch @@ -0,0 +1,49 @@ +From 979651a2ef24131f8cf637a6421f09f3fa7cfdbf Mon Sep 17 00:00:00 2001 +From: Ido Schimmel +Date: Tue, 19 Jul 2022 15:26:26 +0300 +Subject: [PATCH 25/28] mlxsw: spectrum_router: Fix IPv4 nexthop gateway + indication +Git-commit: e5ec6a2513383fe2ecc2ee3b5f51d97acbbcd4d8 +Patch-mainline: v5.19-rc8 +References: git-fixes + +mlxsw needs to distinguish nexthops with a gateway from connected +nexthops in order to write the former to the adjacency table of the +device. The check used to rely on the fact that nexthops with a gateway +have a 'link' scope whereas connected nexthops have a 'host' scope. This +is no longer correct after commit 747c14307214 ("ip: fix dflt addr +selection for connected nexthop"). + +Fix that by instead checking the address family of the gateway IP. This +is a more direct way and also consistent with the IPv6 counterpart in +mlxsw_sp_rt6_is_gateway(). + +Cc: stable@vger.kernel.org +Fixes: 747c14307214 ("ip: fix dflt addr selection for connected nexthop") +Fixes: 597cfe4fc339 ("nexthop: Add support for IPv4 nexthops") +Signed-off-by: Ido Schimmel +Reviewed-by: Amit Cohen +Reviewed-by: Nicolas Dichtel +Reviewed-by: David Ahern +Signed-off-by: David S. Miller +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +index 60a231916518..77716048d36d 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +@@ -5194,7 +5194,7 @@ static bool mlxsw_sp_fi_is_gateway(const struct mlxsw_sp *mlxsw_sp, + { + const struct fib_nh *nh = fib_info_nh(fi, 0); + +- return nh->fib_nh_scope == RT_SCOPE_LINK || ++ return nh->fib_nh_gw_family || + mlxsw_sp_nexthop4_ipip_type(mlxsw_sp, nh, NULL); + } + +-- +2.16.4 + diff --git a/patches.suse/mm-Fix-PASID-use-after-free-issue.patch b/patches.suse/mm-Fix-PASID-use-after-free-issue.patch new file mode 100644 index 0000000..c5dada7 --- /dev/null +++ b/patches.suse/mm-Fix-PASID-use-after-free-issue.patch @@ -0,0 +1,71 @@ +From: Fenghua Yu +Date: Thu, 28 Apr 2022 11:00:41 -0700 +Subject: mm: Fix PASID use-after-free issue +Git-commit: 2667ed10d9f01e250ba806276740782c89d77fda +Patch-mainline: v5.18-rc6 +References: bsc#1203908 + +The PASID is being freed too early. It needs to stay around until after +device drivers that might be using it have had a chance to clear it out +of the hardware. + +The relevant refcounts are: + + mmget() /mmput() refcount the mm's address space + mmgrab()/mmdrop() refcount the mm itself + +The PASID is currently tied to the life of the mm's address space and freed +in __mmput(). This makes logical sense because the PASID can't be used +once the address space is gone. + +But, this misses an important point: even after the address space is gone, +the PASID will still be programmed into a device. Device drivers might, +for instance, still need to flush operations that are outstanding and need +to use that PASID. They do this at file->release() time. + +Device drivers call the IOMMU driver to hold a reference on the mm itself +and drop it at file->release() time. But, the IOMMU driver holds a +reference on the mm itself, not the address space. The address space (and +the PASID) is long gone by the time the driver tries to clean up. This is +effectively a use-after-free bug on the PASID. + +To fix this, move the PASID free operation from __mmput() to __mmdrop(). +This ensures that the IOMMU driver's existing mmgrab() keeps the PASID +allocated until it drops its mm reference. + +Fixes: 701fac40384f ("iommu/sva: Assign a PASID to mm on PASID allocation and free it on mm exit") +Reported-by: Zhangfei Gao +Suggested-by: Jean-Philippe Brucker +Suggested-by: Jacob Pan +Signed-off-by: Fenghua Yu +Signed-off-by: Thomas Gleixner +Tested-by: Zhangfei Gao +Reviewed-by: Jean-Philippe Brucker +Link: https://lore.kernel.org/r/20220428180041.806809-1-fenghua.yu@intel.com + +Acked-by: Michal Koutný +--- + kernel/fork.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/fork.c b/kernel/fork.c +index 9796897560ab..35a3beff140b 100644 +--- a/kernel/fork.c ++++ b/kernel/fork.c +@@ -792,6 +792,7 @@ void __mmdrop(struct mm_struct *mm) + mmu_notifier_subscriptions_destroy(mm); + check_mm(mm); + put_user_ns(mm->user_ns); ++ mm_pasid_drop(mm); + free_mm(mm); + } + EXPORT_SYMBOL_GPL(__mmdrop); +@@ -1190,7 +1191,6 @@ static inline void __mmput(struct mm_struct *mm) + } + if (mm->binfmt) + module_put(mm->binfmt->module); +- mm_pasid_drop(mm); + mmdrop(mm); + } + + diff --git a/patches.suse/mm-rmap-Fix-anon_vma-degree-ambiguity-leading-to-double-reuse.patch b/patches.suse/mm-rmap-Fix-anon_vma-degree-ambiguity-leading-to-double-reuse.patch index f5873c9..99b30c2 100644 --- a/patches.suse/mm-rmap-Fix-anon_vma-degree-ambiguity-leading-to-double-reuse.patch +++ b/patches.suse/mm-rmap-Fix-anon_vma-degree-ambiguity-leading-to-double-reuse.patch @@ -3,7 +3,7 @@ Date: Wed, 31 Aug 2022 19:06:00 +0200 Subject: mm/rmap: Fix anon_vma->degree ambiguity leading to double-reuse Git-commit: 2555283eb40df89945557273121e9393ef9b542b Patch-mainline: v6.0-rc4 -References: git-fixes, bsc#1203098 +References: CVE-2022-42703, bsc#1204168, git-fixes, bsc#1203098 anon_vma->degree tracks the combined number of child anon_vmas and VMAs that use the anon_vma as their ->anon_vma. diff --git a/patches.suse/mmc-au1xmmc-Fix-an-error-handling-path-in-au1xmmc_pr.patch b/patches.suse/mmc-au1xmmc-Fix-an-error-handling-path-in-au1xmmc_pr.patch new file mode 100644 index 0000000..234282a --- /dev/null +++ b/patches.suse/mmc-au1xmmc-Fix-an-error-handling-path-in-au1xmmc_pr.patch @@ -0,0 +1,41 @@ +From 5cbedf52608cc3cbc1c2a9a861fb671620427a20 Mon Sep 17 00:00:00 2001 +From: Christophe JAILLET +Date: Thu, 25 Aug 2022 09:33:57 +0200 +Subject: [PATCH] mmc: au1xmmc: Fix an error handling path in au1xmmc_probe() +Git-commit: 5cbedf52608cc3cbc1c2a9a861fb671620427a20 +Patch-mainline: v6.1-rc1 +References: git-fixes + +If clk_prepare_enable() fails, there is no point in calling +clk_disable_unprepare() in the error handling path. + +Move the out_clk label at the right place. + +Fixes: b6507596dfd6 ("MIPS: Alchemy: au1xmmc: use clk framework") +Signed-off-by: Christophe JAILLET +Link: https://lore.kernel.org/r/21d99886d07fa7fcbec74992657dabad98c935c4.1661412818.git.christophe.jaillet@wanadoo.fr +Signed-off-by: Ulf Hansson +Acked-by: Takashi Iwai + +--- + drivers/mmc/host/au1xmmc.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c +index a9a0837153d8..c88b039dc9fb 100644 +--- a/drivers/mmc/host/au1xmmc.c ++++ b/drivers/mmc/host/au1xmmc.c +@@ -1097,8 +1097,9 @@ static int au1xmmc_probe(struct platform_device *pdev) + if (host->platdata && host->platdata->cd_setup && + !(mmc->caps & MMC_CAP_NEEDS_POLL)) + host->platdata->cd_setup(mmc, 0); +-out_clk: ++ + clk_disable_unprepare(host->clk); ++out_clk: + clk_put(host->clk); + out_irq: + free_irq(host->irq, host); +-- +2.35.3 + diff --git a/patches.suse/mmc-core-Replace-with-already-defined-values-for-rea.patch b/patches.suse/mmc-core-Replace-with-already-defined-values-for-rea.patch new file mode 100644 index 0000000..9b98062 --- /dev/null +++ b/patches.suse/mmc-core-Replace-with-already-defined-values-for-rea.patch @@ -0,0 +1,37 @@ +From e427266460826bea21b70f9b2bb29decfb2c2620 Mon Sep 17 00:00:00 2001 +From: ChanWoo Lee +Date: Wed, 6 Jul 2022 09:48:40 +0900 +Subject: [PATCH] mmc: core: Replace with already defined values for readability +Git-commit: e427266460826bea21b70f9b2bb29decfb2c2620 +Patch-mainline: v6.0-rc1 +References: git-fixes + +SD_ROCR_S18A is already defined and is used to check the rocr value, so +let's replace with already defined values for readability. + +Signed-off-by: ChanWoo Lee +Reviewed-by: Linus Walleij +Link: https://lore.kernel.org/r/20220706004840.24812-1-cw9316.lee@samsung.com +Signed-off-by: Ulf Hansson +Acked-by: Takashi Iwai + +--- + drivers/mmc/core/sd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c +index c5f1df6ce4c0..d2023837dd72 100644 +--- a/drivers/mmc/core/sd.c ++++ b/drivers/mmc/core/sd.c +@@ -870,7 +870,7 @@ int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr) + * the CCS bit is set as well. We deliberately deviate from the spec in + * regards to this, which allows UHS-I to be supported for SDSC cards. + */ +- if (!mmc_host_is_spi(host) && rocr && (*rocr & 0x01000000)) { ++ if (!mmc_host_is_spi(host) && rocr && (*rocr & SD_ROCR_S18A)) { + err = mmc_set_uhs_voltage(host, pocr); + if (err == -EAGAIN) { + retries--; +-- +2.35.3 + diff --git a/patches.suse/mmc-core-Terminate-infinite-loop-in-SD-UHS-voltage-s.patch b/patches.suse/mmc-core-Terminate-infinite-loop-in-SD-UHS-voltage-s.patch new file mode 100644 index 0000000..f528b59 --- /dev/null +++ b/patches.suse/mmc-core-Terminate-infinite-loop-in-SD-UHS-voltage-s.patch @@ -0,0 +1,68 @@ +From e9233917a7e53980664efbc565888163c0a33c3f Mon Sep 17 00:00:00 2001 +From: Brian Norris +Date: Tue, 13 Sep 2022 18:40:10 -0700 +Subject: [PATCH] mmc: core: Terminate infinite loop in SD-UHS voltage switch +Git-commit: e9233917a7e53980664efbc565888163c0a33c3f +Patch-mainline: v6.0 +References: git-fixes + +This loop intends to retry a max of 10 times, with some implicit +termination based on the SD_{R,}OCR_S18A bit. Unfortunately, the +termination condition depends on the value reported by the SD card +(*rocr), which may or may not correctly reflect what we asked it to do. + +Needless to say, it's not wise to rely on the card doing what we expect; +we should at least terminate the loop regardless. So, check both the +input and output values, so we ensure we will terminate regardless of +the SD card behavior. + +Note that SDIO learned a similar retry loop in commit 0797e5f1453b +("mmc: core: Fixup signal voltage switch"), but that used the 'ocr' +result, and so the current pre-terminating condition looks like: + + rocr & ocr & R4_18V_PRESENT + +(i.e., it doesn't have the same bug.) + +This addresses a number of crash reports seen on ChromeOS that look +like the following: + + ... // lots of repeated: ... + <4>[13142.846061] mmc1: Skipping voltage switch + <4>[13143.406087] mmc1: Skipping voltage switch + <4>[13143.964724] mmc1: Skipping voltage switch + <4>[13144.526089] mmc1: Skipping voltage switch + <4>[13145.086088] mmc1: Skipping voltage switch + <4>[13145.645941] mmc1: Skipping voltage switch + <3>[13146.153969] INFO: task halt:30352 blocked for more than 122 seconds. + ... + +Fixes: f2119df6b764 ("mmc: sd: add support for signal voltage switch procedure") +Cc: +Signed-off-by: Brian Norris +Reviewed-by: Guenter Roeck +Link: https://lore.kernel.org/r/20220914014010.2076169-1-briannorris@chromium.org +Signed-off-by: Ulf Hansson +Acked-by: Takashi Iwai + +--- + drivers/mmc/core/sd.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c +index 06aa62ce0ed1..3662bf5320ce 100644 +--- a/drivers/mmc/core/sd.c ++++ b/drivers/mmc/core/sd.c +@@ -870,7 +870,8 @@ int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr) + * the CCS bit is set as well. We deliberately deviate from the spec in + * regards to this, which allows UHS-I to be supported for SDSC cards. + */ +- if (!mmc_host_is_spi(host) && rocr && (*rocr & SD_ROCR_S18A)) { ++ if (!mmc_host_is_spi(host) && (ocr & SD_OCR_S18R) && ++ rocr && (*rocr & SD_ROCR_S18A)) { + err = mmc_set_uhs_voltage(host, pocr); + if (err == -EAGAIN) { + retries--; +-- +2.35.3 + diff --git a/patches.suse/mmc-hsq-Fix-data-stomping-during-mmc-recovery.patch b/patches.suse/mmc-hsq-Fix-data-stomping-during-mmc-recovery.patch new file mode 100644 index 0000000..f9c7f49 --- /dev/null +++ b/patches.suse/mmc-hsq-Fix-data-stomping-during-mmc-recovery.patch @@ -0,0 +1,43 @@ +From e7afa79a3b35a27a046a2139f8b20bd6b98155c2 Mon Sep 17 00:00:00 2001 +From: Wenchao Chen +Date: Fri, 16 Sep 2022 17:05:06 +0800 +Subject: [PATCH] mmc: hsq: Fix data stomping during mmc recovery +Git-commit: e7afa79a3b35a27a046a2139f8b20bd6b98155c2 +Patch-mainline: v6.0 +References: git-fixes + +The block device uses multiple queues to access emmc. There will be up to 3 +requests in the hsq of the host. The current code will check whether there +is a request doing recovery before entering the queue, but it will not check +whether there is a request when the lock is issued. The request is in recovery +mode. If there is a request in recovery, then a read and write request is +initiated at this time, and the conflict between the request and the recovery +request will cause the data to be trampled. + +Signed-off-by: Wenchao Chen +Fixes: 511ce378e16f ("mmc: Add MMC host software queue support") +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20220916090506.10662-1-wenchao.chen666@gmail.com +Signed-off-by: Ulf Hansson +Acked-by: Takashi Iwai + +--- + drivers/mmc/host/mmc_hsq.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/mmc/host/mmc_hsq.c b/drivers/mmc/host/mmc_hsq.c +index a5e05ed0fda3..9d35453e7371 100644 +--- a/drivers/mmc/host/mmc_hsq.c ++++ b/drivers/mmc/host/mmc_hsq.c +@@ -34,7 +34,7 @@ static void mmc_hsq_pump_requests(struct mmc_hsq *hsq) + spin_lock_irqsave(&hsq->lock, flags); + + /* Make sure we are not already running a request now */ +- if (hsq->mrq) { ++ if (hsq->mrq || hsq->recovery_halt) { + spin_unlock_irqrestore(&hsq->lock, flags); + return; + } +-- +2.35.3 + diff --git a/patches.suse/mmc-moxart-fix-4-bit-bus-width-and-remove-8-bit-bus-.patch b/patches.suse/mmc-moxart-fix-4-bit-bus-width-and-remove-8-bit-bus-.patch new file mode 100644 index 0000000..8acfa6e --- /dev/null +++ b/patches.suse/mmc-moxart-fix-4-bit-bus-width-and-remove-8-bit-bus-.patch @@ -0,0 +1,80 @@ +From 35ca91d1338ae158f6dcc0de5d1e86197924ffda Mon Sep 17 00:00:00 2001 +From: Sergei Antonov +Date: Wed, 7 Sep 2022 23:57:53 +0300 +Subject: [PATCH] mmc: moxart: fix 4-bit bus width and remove 8-bit bus width +Git-commit: 35ca91d1338ae158f6dcc0de5d1e86197924ffda +Patch-mainline: v6.0 +References: git-fixes + +According to the datasheet [1] at page 377, 4-bit bus width is turned on by +bit 2 of the Bus Width Register. Thus the current bitmask is wrong: define +BUS_WIDTH_4 BIT(1) + +BIT(1) does not work but BIT(2) works. This has been verified on real MOXA +hardware with FTSDC010 controller revision 1_6_0. + +The corrected value of BUS_WIDTH_4 mask collides with: define BUS_WIDTH_8 +BIT(2). Additionally, 8-bit bus width mode isn't supported according to the +datasheet, so let's remove the corresponding code. + +[1] +https://bitbucket.org/Kasreyn/mkrom-uc7112lx/src/master/documents/FIC8120_DS_v1.2.pdf + +Fixes: 1b66e94e6b99 ("mmc: moxart: Add MOXA ART SD/MMC driver") +Signed-off-by: Sergei Antonov +Cc: Jonas Jensen +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20220907205753.1577434-1-saproj@gmail.com +Signed-off-by: Ulf Hansson +Acked-by: Takashi Iwai + +--- + drivers/mmc/host/moxart-mmc.c | 17 +++-------------- + 1 file changed, 3 insertions(+), 14 deletions(-) + +diff --git a/drivers/mmc/host/moxart-mmc.c b/drivers/mmc/host/moxart-mmc.c +index b6eb75f4bbfc..dfc3ffd5b1f8 100644 +--- a/drivers/mmc/host/moxart-mmc.c ++++ b/drivers/mmc/host/moxart-mmc.c +@@ -111,8 +111,8 @@ + #define CLK_DIV_MASK 0x7f + + /* REG_BUS_WIDTH */ +-#define BUS_WIDTH_8 BIT(2) +-#define BUS_WIDTH_4 BIT(1) ++#define BUS_WIDTH_4_SUPPORT BIT(3) ++#define BUS_WIDTH_4 BIT(2) + #define BUS_WIDTH_1 BIT(0) + + #define MMC_VDD_360 23 +@@ -524,9 +524,6 @@ static void moxart_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) + case MMC_BUS_WIDTH_4: + writel(BUS_WIDTH_4, host->base + REG_BUS_WIDTH); + break; +- case MMC_BUS_WIDTH_8: +- writel(BUS_WIDTH_8, host->base + REG_BUS_WIDTH); +- break; + default: + writel(BUS_WIDTH_1, host->base + REG_BUS_WIDTH); + break; +@@ -651,16 +648,8 @@ static int moxart_probe(struct platform_device *pdev) + dmaengine_slave_config(host->dma_chan_rx, &cfg); + } + +- switch ((readl(host->base + REG_BUS_WIDTH) >> 3) & 3) { +- case 1: ++ if (readl(host->base + REG_BUS_WIDTH) & BUS_WIDTH_4_SUPPORT) + mmc->caps |= MMC_CAP_4_BIT_DATA; +- break; +- case 2: +- mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA; +- break; +- default: +- break; +- } + + writel(0, host->base + REG_INTERRUPT_MASK); + +-- +2.35.3 + diff --git a/patches.suse/mmc-sdhci-pci-Add-PCI-ID-for-Intel-ADL.patch b/patches.suse/mmc-sdhci-pci-Add-PCI-ID-for-Intel-ADL.patch index 01c208b..447e926 100644 --- a/patches.suse/mmc-sdhci-pci-Add-PCI-ID-for-Intel-ADL.patch +++ b/patches.suse/mmc-sdhci-pci-Add-PCI-ID-for-Intel-ADL.patch @@ -4,7 +4,7 @@ Date: Wed, 24 Nov 2021 11:48:50 +0200 Subject: [PATCH] mmc: sdhci-pci: Add PCI ID for Intel ADL Git-commit: e53e97f805cb1abeea000a61549d42f92cb10804 Patch-mainline: v5.17-rc1 -References: git-fixes +References: jsc#PED-676 git-fixes Add PCI ID for Intel ADL eMMC host controller. diff --git a/patches.suse/mmc-sdhci-sprd-Fix-minimum-clock-limit.patch b/patches.suse/mmc-sdhci-sprd-Fix-minimum-clock-limit.patch new file mode 100644 index 0000000..2457907 --- /dev/null +++ b/patches.suse/mmc-sdhci-sprd-Fix-minimum-clock-limit.patch @@ -0,0 +1,44 @@ +From 6e141772e6465f937458b35ddcfd0a981b6f5280 Mon Sep 17 00:00:00 2001 +From: Wenchao Chen +Date: Tue, 11 Oct 2022 18:49:35 +0800 +Subject: [PATCH] mmc: sdhci-sprd: Fix minimum clock limit +Git-commit: 6e141772e6465f937458b35ddcfd0a981b6f5280 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The Spreadtrum controller supports 100KHz minimal clock rate, which means +that the current value 400KHz is wrong. + +Unfortunately this has also lead to fail to initialize some cards, which +are allowed to require 100KHz to work. So, let's fix the problem by +changing the minimal supported clock rate to 100KHz. + +Signed-off-by: Wenchao Chen +Acked-by: Adrian Hunter +Fixes: fb8bd90f83c4 ("mmc: sdhci-sprd: Add Spreadtrum's initial host controller") +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20221011104935.10980-1-wenchao.chen666@gmail.com +[ulf: Clarified to commit-message] +Signed-off-by: Ulf Hansson +Acked-by: Takashi Iwai + +--- + drivers/mmc/host/sdhci-sprd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/mmc/host/sdhci-sprd.c b/drivers/mmc/host/sdhci-sprd.c +index 46c55ab4884c..b92a408f138d 100644 +--- a/drivers/mmc/host/sdhci-sprd.c ++++ b/drivers/mmc/host/sdhci-sprd.c +@@ -309,7 +309,7 @@ static unsigned int sdhci_sprd_get_max_clock(struct sdhci_host *host) + + static unsigned int sdhci_sprd_get_min_clock(struct sdhci_host *host) + { +- return 400000; ++ return 100000; + } + + static void sdhci_sprd_set_uhs_signaling(struct sdhci_host *host, +-- +2.35.3 + diff --git a/patches.suse/mmc-wmt-sdmmc-Fix-an-error-handling-path-in-wmt_mci_.patch b/patches.suse/mmc-wmt-sdmmc-Fix-an-error-handling-path-in-wmt_mci_.patch new file mode 100644 index 0000000..a23df0c --- /dev/null +++ b/patches.suse/mmc-wmt-sdmmc-Fix-an-error-handling-path-in-wmt_mci_.patch @@ -0,0 +1,48 @@ +From cb58188ad90a61784a56a64f5107faaf2ad323e7 Mon Sep 17 00:00:00 2001 +From: Christophe JAILLET +Date: Thu, 22 Sep 2022 21:06:40 +0200 +Subject: [PATCH] mmc: wmt-sdmmc: Fix an error handling path in wmt_mci_probe() +Git-commit: cb58188ad90a61784a56a64f5107faaf2ad323e7 +Patch-mainline: v6.1-rc1 +References: git-fixes + +A dma_free_coherent() call is missing in the error handling path of the +probe, as already done in the remove function. + +Fixes: 3a96dff0f828 ("mmc: SD/MMC Host Controller for Wondermedia WM8505/WM8650") +Signed-off-by: Christophe JAILLET +Reviewed-by: Dan Carpenter +Link: https://lore.kernel.org/r/53fc6ffa5d1c428fefeae7d313cf4a669c3a1e98.1663873255.git.christophe.jaillet@wanadoo.fr +Signed-off-by: Ulf Hansson +Acked-by: Takashi Iwai + +--- + drivers/mmc/host/wmt-sdmmc.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/mmc/host/wmt-sdmmc.c b/drivers/mmc/host/wmt-sdmmc.c +index 163ac9df8cca..9b5c503e3a3f 100644 +--- a/drivers/mmc/host/wmt-sdmmc.c ++++ b/drivers/mmc/host/wmt-sdmmc.c +@@ -846,7 +846,7 @@ static int wmt_mci_probe(struct platform_device *pdev) + if (IS_ERR(priv->clk_sdmmc)) { + dev_err(&pdev->dev, "Error getting clock\n"); + ret = PTR_ERR(priv->clk_sdmmc); +- goto fail5; ++ goto fail5_and_a_half; + } + + ret = clk_prepare_enable(priv->clk_sdmmc); +@@ -863,6 +863,9 @@ static int wmt_mci_probe(struct platform_device *pdev) + return 0; + fail6: + clk_put(priv->clk_sdmmc); ++fail5_and_a_half: ++ dma_free_coherent(&pdev->dev, mmc->max_blk_count * 16, ++ priv->dma_desc_buffer, priv->dma_desc_device_addr); + fail5: + free_irq(dma_irq, priv); + fail4: +-- +2.35.3 + diff --git a/patches.suse/msft-hv-2623-net-mana-Add-the-Linux-MANA-PF-driver.patch b/patches.suse/msft-hv-2623-net-mana-Add-the-Linux-MANA-PF-driver.patch new file mode 100644 index 0000000..3af1f72 --- /dev/null +++ b/patches.suse/msft-hv-2623-net-mana-Add-the-Linux-MANA-PF-driver.patch @@ -0,0 +1,488 @@ +From: Dexuan Cui +Date: Tue, 14 Jun 2022 13:28:54 -0700 +Patch-mainline: v6.0-rc1 +Subject: net: mana: Add the Linux MANA PF driver +Git-commit: 1566e7d6206fed959258a17c694834a4b801a3b5 +References: bug#1201309, jsc#PED-529 + +This minimal PF driver runs on bare metal. +Currently Ethernet TX/RX works. SR-IOV management is not supported yet. + +Signed-off-by: Dexuan Cui +Co-developed-by: Haiyang Zhang +Signed-off-by: Haiyang Zhang +Signed-off-by: Paolo Abeni +Acked-by: Olaf Hering +--- + drivers/net/ethernet/microsoft/mana/gdma.h | 10 ++ + drivers/net/ethernet/microsoft/mana/gdma_main.c | 39 ++++++- + drivers/net/ethernet/microsoft/mana/hw_channel.c | 18 ++- + drivers/net/ethernet/microsoft/mana/hw_channel.h | 5 + + drivers/net/ethernet/microsoft/mana/mana.h | 64 ++++++++++ + drivers/net/ethernet/microsoft/mana/mana_en.c | 135 ++++++++++++++++++++++ + 6 files changed, 267 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/ethernet/microsoft/mana/gdma.h b/drivers/net/ethernet/microsoft/mana/gdma.h +--- a/drivers/net/ethernet/microsoft/mana/gdma.h ++++ b/drivers/net/ethernet/microsoft/mana/gdma.h +@@ -348,6 +348,7 @@ struct gdma_context { + struct completion eq_test_event; + u32 test_event_eq_id; + ++ bool is_pf; + void __iomem *bar0_va; + void __iomem *shm_base; + void __iomem *db_page_base; +@@ -469,6 +470,15 @@ struct gdma_eqe { + #define GDMA_REG_DB_PAGE_SIZE 0x10 + #define GDMA_REG_SHM_OFFSET 0x18 + ++#define GDMA_PF_REG_DB_PAGE_SIZE 0xD0 ++#define GDMA_PF_REG_DB_PAGE_OFF 0xC8 ++#define GDMA_PF_REG_SHM_OFF 0x70 ++ ++#define GDMA_SRIOV_REG_CFG_BASE_OFF 0x108 ++ ++#define MANA_PF_DEVICE_ID 0x00B9 ++#define MANA_VF_DEVICE_ID 0x00BA ++ + struct gdma_posted_wqe_info { + u32 wqe_size_in_bu; + }; +diff --git a/drivers/net/ethernet/microsoft/mana/gdma_main.c b/drivers/net/ethernet/microsoft/mana/gdma_main.c +--- a/drivers/net/ethernet/microsoft/mana/gdma_main.c ++++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c +@@ -18,7 +18,24 @@ static u64 mana_gd_r64(struct gdma_context *g, u64 offset) + return readq(g->bar0_va + offset); + } + +-static void mana_gd_init_registers(struct pci_dev *pdev) ++static void mana_gd_init_pf_regs(struct pci_dev *pdev) ++{ ++ struct gdma_context *gc = pci_get_drvdata(pdev); ++ void __iomem *sriov_base_va; ++ u64 sriov_base_off; ++ ++ gc->db_page_size = mana_gd_r32(gc, GDMA_PF_REG_DB_PAGE_SIZE) & 0xFFFF; ++ gc->db_page_base = gc->bar0_va + ++ mana_gd_r64(gc, GDMA_PF_REG_DB_PAGE_OFF); ++ ++ sriov_base_off = mana_gd_r64(gc, GDMA_SRIOV_REG_CFG_BASE_OFF); ++ ++ sriov_base_va = gc->bar0_va + sriov_base_off; ++ gc->shm_base = sriov_base_va + ++ mana_gd_r64(gc, sriov_base_off + GDMA_PF_REG_SHM_OFF); ++} ++ ++static void mana_gd_init_vf_regs(struct pci_dev *pdev) + { + struct gdma_context *gc = pci_get_drvdata(pdev); + +@@ -30,6 +47,16 @@ static void mana_gd_init_registers(struct pci_dev *pdev) + gc->shm_base = gc->bar0_va + mana_gd_r64(gc, GDMA_REG_SHM_OFFSET); + } + ++static void mana_gd_init_registers(struct pci_dev *pdev) ++{ ++ struct gdma_context *gc = pci_get_drvdata(pdev); ++ ++ if (gc->is_pf) ++ mana_gd_init_pf_regs(pdev); ++ else ++ mana_gd_init_vf_regs(pdev); ++} ++ + static int mana_gd_query_max_resources(struct pci_dev *pdev) + { + struct gdma_context *gc = pci_get_drvdata(pdev); +@@ -1304,6 +1331,11 @@ static void mana_gd_cleanup(struct pci_dev *pdev) + mana_gd_remove_irqs(pdev); + } + ++static bool mana_is_pf(unsigned short dev_id) ++{ ++ return dev_id == MANA_PF_DEVICE_ID; ++} ++ + static int mana_gd_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + { + struct gdma_context *gc; +@@ -1340,10 +1372,10 @@ static int mana_gd_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + if (!bar0_va) + goto free_gc; + ++ gc->is_pf = mana_is_pf(pdev->device); + gc->bar0_va = bar0_va; + gc->dev = &pdev->dev; + +- + err = mana_gd_setup(pdev); + if (err) + goto unmap_bar; +@@ -1438,7 +1470,8 @@ static void mana_gd_shutdown(struct pci_dev *pdev) + #endif + + static const struct pci_device_id mana_id_table[] = { +- { PCI_DEVICE(PCI_VENDOR_ID_MICROSOFT, 0x00BA) }, ++ { PCI_DEVICE(PCI_VENDOR_ID_MICROSOFT, MANA_PF_DEVICE_ID) }, ++ { PCI_DEVICE(PCI_VENDOR_ID_MICROSOFT, MANA_VF_DEVICE_ID) }, + { } + }; + +diff --git a/drivers/net/ethernet/microsoft/mana/hw_channel.c b/drivers/net/ethernet/microsoft/mana/hw_channel.c +--- a/drivers/net/ethernet/microsoft/mana/hw_channel.c ++++ b/drivers/net/ethernet/microsoft/mana/hw_channel.c +@@ -158,6 +158,14 @@ static void mana_hwc_init_event_handler(void *ctx, struct gdma_queue *q_self, + hwc->rxq->msg_buf->gpa_mkey = val; + hwc->txq->msg_buf->gpa_mkey = val; + break; ++ ++ case HWC_INIT_DATA_PF_DEST_RQ_ID: ++ hwc->pf_dest_vrq_id = val; ++ break; ++ ++ case HWC_INIT_DATA_PF_DEST_CQ_ID: ++ hwc->pf_dest_vrcq_id = val; ++ break; + } + + break; +@@ -773,10 +781,13 @@ void mana_hwc_destroy_channel(struct gdma_context *gc) + int mana_hwc_send_request(struct hw_channel_context *hwc, u32 req_len, + const void *req, u32 resp_len, void *resp) + { ++ struct gdma_context *gc = hwc->gdma_dev->gdma_context; + struct hwc_work_request *tx_wr; + struct hwc_wq *txq = hwc->txq; + struct gdma_req_hdr *req_msg; + struct hwc_caller_ctx *ctx; ++ u32 dest_vrcq = 0; ++ u32 dest_vrq = 0; + u16 msg_id; + int err; + +@@ -803,7 +814,12 @@ int mana_hwc_send_request(struct hw_channel_context *hwc, u32 req_len, + + tx_wr->msg_size = req_len; + +- err = mana_hwc_post_tx_wqe(txq, tx_wr, 0, 0, false); ++ if (gc->is_pf) { ++ dest_vrq = hwc->pf_dest_vrq_id; ++ dest_vrcq = hwc->pf_dest_vrcq_id; ++ } ++ ++ err = mana_hwc_post_tx_wqe(txq, tx_wr, dest_vrq, dest_vrcq, false); + if (err) { + dev_err(hwc->dev, "HWC: Failed to post send WQE: %d\n", err); + goto out; +diff --git a/drivers/net/ethernet/microsoft/mana/hw_channel.h b/drivers/net/ethernet/microsoft/mana/hw_channel.h +--- a/drivers/net/ethernet/microsoft/mana/hw_channel.h ++++ b/drivers/net/ethernet/microsoft/mana/hw_channel.h +@@ -20,6 +20,8 @@ + #define HWC_INIT_DATA_MAX_NUM_CQS 7 + #define HWC_INIT_DATA_PDID 8 + #define HWC_INIT_DATA_GPA_MKEY 9 ++#define HWC_INIT_DATA_PF_DEST_RQ_ID 10 ++#define HWC_INIT_DATA_PF_DEST_CQ_ID 11 + + /* Structures labeled with "HW DATA" are exchanged with the hardware. All of + * them are naturally aligned and hence don't need __packed. +@@ -178,6 +180,9 @@ struct hw_channel_context { + struct semaphore sema; + struct gdma_resource inflight_msg_res; + ++ u32 pf_dest_vrq_id; ++ u32 pf_dest_vrcq_id; ++ + struct hwc_caller_ctx *caller_ctx; + }; + +diff --git a/drivers/net/ethernet/microsoft/mana/mana.h b/drivers/net/ethernet/microsoft/mana/mana.h +--- a/drivers/net/ethernet/microsoft/mana/mana.h ++++ b/drivers/net/ethernet/microsoft/mana/mana.h +@@ -374,6 +374,7 @@ struct mana_port_context { + unsigned int num_queues; + + mana_handle_t port_handle; ++ mana_handle_t pf_filter_handle; + + u16 port_idx; + +@@ -420,6 +421,12 @@ enum mana_command_code { + MANA_FENCE_RQ = 0x20006, + MANA_CONFIG_VPORT_RX = 0x20007, + MANA_QUERY_VPORT_CONFIG = 0x20008, ++ ++ /* Privileged commands for the PF mode */ ++ MANA_REGISTER_FILTER = 0x28000, ++ MANA_DEREGISTER_FILTER = 0x28001, ++ MANA_REGISTER_HW_PORT = 0x28003, ++ MANA_DEREGISTER_HW_PORT = 0x28004, + }; + + /* Query Device Configuration */ +@@ -547,6 +554,63 @@ struct mana_cfg_rx_steer_resp { + struct gdma_resp_hdr hdr; + }; /* HW DATA */ + ++/* Register HW vPort */ ++struct mana_register_hw_vport_req { ++ struct gdma_req_hdr hdr; ++ u16 attached_gfid; ++ u8 is_pf_default_vport; ++ u8 reserved1; ++ u8 allow_all_ether_types; ++ u8 reserved2; ++ u8 reserved3; ++ u8 reserved4; ++}; /* HW DATA */ ++ ++struct mana_register_hw_vport_resp { ++ struct gdma_resp_hdr hdr; ++ mana_handle_t hw_vport_handle; ++}; /* HW DATA */ ++ ++/* Deregister HW vPort */ ++struct mana_deregister_hw_vport_req { ++ struct gdma_req_hdr hdr; ++ mana_handle_t hw_vport_handle; ++}; /* HW DATA */ ++ ++struct mana_deregister_hw_vport_resp { ++ struct gdma_resp_hdr hdr; ++}; /* HW DATA */ ++ ++/* Register filter */ ++struct mana_register_filter_req { ++ struct gdma_req_hdr hdr; ++ mana_handle_t vport; ++ u8 mac_addr[6]; ++ u8 reserved1; ++ u8 reserved2; ++ u8 reserved3; ++ u8 reserved4; ++ u16 reserved5; ++ u32 reserved6; ++ u32 reserved7; ++ u32 reserved8; ++}; /* HW DATA */ ++ ++struct mana_register_filter_resp { ++ struct gdma_resp_hdr hdr; ++ mana_handle_t filter_handle; ++}; /* HW DATA */ ++ ++/* Deregister filter */ ++struct mana_deregister_filter_req { ++ struct gdma_req_hdr hdr; ++ mana_handle_t filter_handle; ++}; /* HW DATA */ ++ ++struct mana_deregister_filter_resp { ++ struct gdma_resp_hdr hdr; ++}; /* HW DATA */ ++ + #define MANA_MAX_NUM_QUEUES 64 + + #define MANA_SHORT_VPORT_OFFSET_MAX ((1U << 8) - 1) +diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c +--- a/drivers/net/ethernet/microsoft/mana/mana_en.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c +@@ -446,6 +446,119 @@ static int mana_verify_resp_hdr(const struct gdma_resp_hdr *resp_hdr, + return 0; + } + ++static int mana_pf_register_hw_vport(struct mana_port_context *apc) ++{ ++ struct mana_register_hw_vport_resp resp = {}; ++ struct mana_register_hw_vport_req req = {}; ++ int err; ++ ++ mana_gd_init_req_hdr(&req.hdr, MANA_REGISTER_HW_PORT, ++ sizeof(req), sizeof(resp)); ++ req.attached_gfid = 1; ++ req.is_pf_default_vport = 1; ++ req.allow_all_ether_types = 1; ++ ++ err = mana_send_request(apc->ac, &req, sizeof(req), &resp, ++ sizeof(resp)); ++ if (err) { ++ netdev_err(apc->ndev, "Failed to register hw vPort: %d\n", err); ++ return err; ++ } ++ ++ err = mana_verify_resp_hdr(&resp.hdr, MANA_REGISTER_HW_PORT, ++ sizeof(resp)); ++ if (err || resp.hdr.status) { ++ netdev_err(apc->ndev, "Failed to register hw vPort: %d, 0x%x\n", ++ err, resp.hdr.status); ++ return err ? err : -EPROTO; ++ } ++ ++ apc->port_handle = resp.hw_vport_handle; ++ return 0; ++} ++ ++static void mana_pf_deregister_hw_vport(struct mana_port_context *apc) ++{ ++ struct mana_deregister_hw_vport_resp resp = {}; ++ struct mana_deregister_hw_vport_req req = {}; ++ int err; ++ ++ mana_gd_init_req_hdr(&req.hdr, MANA_DEREGISTER_HW_PORT, ++ sizeof(req), sizeof(resp)); ++ req.hw_vport_handle = apc->port_handle; ++ ++ err = mana_send_request(apc->ac, &req, sizeof(req), &resp, ++ sizeof(resp)); ++ if (err) { ++ netdev_err(apc->ndev, "Failed to unregister hw vPort: %d\n", ++ err); ++ return; ++ } ++ ++ err = mana_verify_resp_hdr(&resp.hdr, MANA_DEREGISTER_HW_PORT, ++ sizeof(resp)); ++ if (err || resp.hdr.status) ++ netdev_err(apc->ndev, ++ "Failed to deregister hw vPort: %d, 0x%x\n", ++ err, resp.hdr.status); ++} ++ ++static int mana_pf_register_filter(struct mana_port_context *apc) ++{ ++ struct mana_register_filter_resp resp = {}; ++ struct mana_register_filter_req req = {}; ++ int err; ++ ++ mana_gd_init_req_hdr(&req.hdr, MANA_REGISTER_FILTER, ++ sizeof(req), sizeof(resp)); ++ req.vport = apc->port_handle; ++ memcpy(req.mac_addr, apc->mac_addr, ETH_ALEN); ++ ++ err = mana_send_request(apc->ac, &req, sizeof(req), &resp, ++ sizeof(resp)); ++ if (err) { ++ netdev_err(apc->ndev, "Failed to register filter: %d\n", err); ++ return err; ++ } ++ ++ err = mana_verify_resp_hdr(&resp.hdr, MANA_REGISTER_FILTER, ++ sizeof(resp)); ++ if (err || resp.hdr.status) { ++ netdev_err(apc->ndev, "Failed to register filter: %d, 0x%x\n", ++ err, resp.hdr.status); ++ return err ? err : -EPROTO; ++ } ++ ++ apc->pf_filter_handle = resp.filter_handle; ++ return 0; ++} ++ ++static void mana_pf_deregister_filter(struct mana_port_context *apc) ++{ ++ struct mana_deregister_filter_resp resp = {}; ++ struct mana_deregister_filter_req req = {}; ++ int err; ++ ++ mana_gd_init_req_hdr(&req.hdr, MANA_DEREGISTER_FILTER, ++ sizeof(req), sizeof(resp)); ++ req.filter_handle = apc->pf_filter_handle; ++ ++ err = mana_send_request(apc->ac, &req, sizeof(req), &resp, ++ sizeof(resp)); ++ if (err) { ++ netdev_err(apc->ndev, "Failed to unregister filter: %d\n", ++ err); ++ return; ++ } ++ ++ err = mana_verify_resp_hdr(&resp.hdr, MANA_DEREGISTER_FILTER, ++ sizeof(resp)); ++ if (err || resp.hdr.status) ++ netdev_err(apc->ndev, ++ "Failed to deregister filter: %d, 0x%x\n", ++ err, resp.hdr.status); ++} ++ + static int mana_query_device_cfg(struct mana_context *ac, u32 proto_major_ver, + u32 proto_minor_ver, u32 proto_micro_ver, + u16 *max_num_vports) +@@ -1653,6 +1766,7 @@ out: + + static void mana_destroy_vport(struct mana_port_context *apc) + { ++ struct gdma_dev *gd = apc->ac->gdma_dev; + struct mana_rxq *rxq; + u32 rxq_idx; + +@@ -1666,6 +1780,9 @@ static void mana_destroy_vport(struct mana_port_context *apc) + } + + mana_destroy_txq(apc); ++ ++ if (gd->gdma_context->is_pf) ++ mana_pf_deregister_hw_vport(apc); + } + + static int mana_create_vport(struct mana_port_context *apc, +@@ -1676,6 +1793,12 @@ static int mana_create_vport(struct mana_port_context *apc, + + apc->default_rxobj = INVALID_MANA_HANDLE; + ++ if (gd->gdma_context->is_pf) { ++ err = mana_pf_register_hw_vport(apc); ++ if (err) ++ return err; ++ } ++ + err = mana_cfg_vport(apc, gd->pdid, gd->doorbell); + if (err) + return err; +@@ -1755,6 +1878,7 @@ reset_apc: + int mana_alloc_queues(struct net_device *ndev) + { + struct mana_port_context *apc = netdev_priv(ndev); ++ struct gdma_dev *gd = apc->ac->gdma_dev; + int err; + + err = mana_create_vport(apc, ndev); +@@ -1781,6 +1905,12 @@ int mana_alloc_queues(struct net_device *ndev) + if (err) + goto destroy_vport; + ++ if (gd->gdma_context->is_pf) { ++ err = mana_pf_register_filter(apc); ++ if (err) ++ goto destroy_vport; ++ } ++ + mana_chn_setxdp(apc, mana_xdp_get(apc)); + + return 0; +@@ -1825,6 +1955,7 @@ int mana_attach(struct net_device *ndev) + static int mana_dealloc_queues(struct net_device *ndev) + { + struct mana_port_context *apc = netdev_priv(ndev); ++ struct gdma_dev *gd = apc->ac->gdma_dev; + struct mana_txq *txq; + int i, err; + +@@ -1833,6 +1964,9 @@ static int mana_dealloc_queues(struct net_device *ndev) + + mana_chn_setxdp(apc, NULL); + ++ if (gd->gdma_context->is_pf) ++ mana_pf_deregister_filter(apc); ++ + /* No packet can be transmitted now since apc->port_is_up is false. + * There is still a tiny chance that mana_poll_tx_cq() can re-enable + * a txq because it may not timely see apc->port_is_up being cleared +@@ -1915,6 +2049,7 @@ static int mana_probe_port(struct mana_context *ac, int port_idx, + apc->max_queues = gc->max_num_queues; + apc->num_queues = gc->max_num_queues; + apc->port_handle = INVALID_MANA_HANDLE; ++ apc->pf_filter_handle = INVALID_MANA_HANDLE; + apc->port_idx = port_idx; + + ndev->netdev_ops = &mana_devops; diff --git a/patches.suse/msft-hv-2624-net-mana-Add-support-of-XDP_REDIRECT-action.patch b/patches.suse/msft-hv-2624-net-mana-Add-support-of-XDP_REDIRECT-action.patch new file mode 100644 index 0000000..73931ff --- /dev/null +++ b/patches.suse/msft-hv-2624-net-mana-Add-support-of-XDP_REDIRECT-action.patch @@ -0,0 +1,272 @@ +From: Haiyang Zhang +Date: Tue, 14 Jun 2022 13:28:55 -0700 +Patch-mainline: v6.0-rc1 +Subject: net: mana: Add support of XDP_REDIRECT action +Git-commit: 7a8938cd024d383c12bb1e08025db6ea3d551103 +References: bug#1201310, jsc#PED-529 + +Add a handler of the XDP_REDIRECT return code from a XDP program. The +packets will be flushed at the end of each RX/CQ NAPI poll cycle. +ndo_xdp_xmit() is implemented by sharing the code in mana_xdp_tx(). +Ethtool per queue counters are added for XDP redirect and xmit operations. + +Signed-off-by: Haiyang Zhang +Signed-off-by: Paolo Abeni +Acked-by: Olaf Hering +--- + drivers/net/ethernet/microsoft/mana/mana.h | 6 ++ + drivers/net/ethernet/microsoft/mana/mana_bpf.c | 64 ++++++++++++++++++++++ + drivers/net/ethernet/microsoft/mana/mana_en.c | 13 ++++- + drivers/net/ethernet/microsoft/mana/mana_ethtool.c | 12 +++- + 4 files changed, 93 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/microsoft/mana/mana.h b/drivers/net/ethernet/microsoft/mana/mana.h +--- a/drivers/net/ethernet/microsoft/mana/mana.h ++++ b/drivers/net/ethernet/microsoft/mana/mana.h +@@ -53,12 +53,14 @@ struct mana_stats_rx { + u64 bytes; + u64 xdp_drop; + u64 xdp_tx; ++ u64 xdp_redirect; + struct u64_stats_sync syncp; + }; + + struct mana_stats_tx { + u64 packets; + u64 bytes; ++ u64 xdp_xmit; + struct u64_stats_sync syncp; + }; + +@@ -311,6 +313,8 @@ struct mana_rxq { + struct bpf_prog __rcu *bpf_prog; + struct xdp_rxq_info xdp_rxq; + struct page *xdp_save_page; ++ bool xdp_flush; ++ int xdp_rc; /* XDP redirect return code */ + + /* MUST BE THE LAST MEMBER: + * Each receive buffer has an associated mana_recv_buf_oob. +@@ -396,6 +400,8 @@ int mana_probe(struct gdma_dev *gd, bool resuming); + void mana_remove(struct gdma_dev *gd, bool suspending); + + void mana_xdp_tx(struct sk_buff *skb, struct net_device *ndev); ++int mana_xdp_xmit(struct net_device *ndev, int n, struct xdp_frame **frames, ++ u32 flags); + u32 mana_run_xdp(struct net_device *ndev, struct mana_rxq *rxq, + struct xdp_buff *xdp, void *buf_va, uint pkt_len); + struct bpf_prog *mana_xdp_get(struct mana_port_context *apc); +diff --git a/drivers/net/ethernet/microsoft/mana/mana_bpf.c b/drivers/net/ethernet/microsoft/mana/mana_bpf.c +--- a/drivers/net/ethernet/microsoft/mana/mana_bpf.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_bpf.c +@@ -32,9 +32,55 @@ void mana_xdp_tx(struct sk_buff *skb, struct net_device *ndev) + ndev->stats.tx_dropped++; + } + ++static int mana_xdp_xmit_fm(struct net_device *ndev, struct xdp_frame *frame, ++ u16 q_idx) ++{ ++ struct sk_buff *skb; ++ ++ skb = xdp_build_skb_from_frame(frame, ndev); ++ if (unlikely(!skb)) ++ return -ENOMEM; ++ ++ skb_set_queue_mapping(skb, q_idx); ++ ++ mana_xdp_tx(skb, ndev); ++ ++ return 0; ++} ++ ++int mana_xdp_xmit(struct net_device *ndev, int n, struct xdp_frame **frames, ++ u32 flags) ++{ ++ struct mana_port_context *apc = netdev_priv(ndev); ++ struct mana_stats_tx *tx_stats; ++ int i, count = 0; ++ u16 q_idx; ++ ++ if (unlikely(!apc->port_is_up)) ++ return 0; ++ ++ q_idx = smp_processor_id() % ndev->real_num_tx_queues; ++ ++ for (i = 0; i < n; i++) { ++ if (mana_xdp_xmit_fm(ndev, frames[i], q_idx)) ++ break; ++ ++ count++; ++ } ++ ++ tx_stats = &apc->tx_qp[q_idx].txq.stats; ++ ++ u64_stats_update_begin(&tx_stats->syncp); ++ tx_stats->xdp_xmit += count; ++ u64_stats_update_end(&tx_stats->syncp); ++ ++ return count; ++} ++ + u32 mana_run_xdp(struct net_device *ndev, struct mana_rxq *rxq, + struct xdp_buff *xdp, void *buf_va, uint pkt_len) + { ++ struct mana_stats_rx *rx_stats; + struct bpf_prog *prog; + u32 act = XDP_PASS; + +@@ -49,12 +95,30 @@ u32 mana_run_xdp(struct net_device *ndev, struct mana_rxq *rxq, + + act = bpf_prog_run_xdp(prog, xdp); + ++ rx_stats = &rxq->stats; ++ + switch (act) { + case XDP_PASS: + case XDP_TX: + case XDP_DROP: + break; + ++ case XDP_REDIRECT: ++ rxq->xdp_rc = xdp_do_redirect(ndev, xdp, prog); ++ if (!rxq->xdp_rc) { ++ rxq->xdp_flush = true; ++ ++ u64_stats_update_begin(&rx_stats->syncp); ++ rx_stats->packets++; ++ rx_stats->bytes += pkt_len; ++ rx_stats->xdp_redirect++; ++ u64_stats_update_end(&rx_stats->syncp); ++ ++ break; ++ } ++ ++ fallthrough; ++ + case XDP_ABORTED: + trace_xdp_exception(ndev, prog, act); + break; +diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c +--- a/drivers/net/ethernet/microsoft/mana/mana_en.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include + #include + + #include +@@ -382,6 +383,7 @@ static const struct net_device_ops mana_devops = { + .ndo_validate_addr = eth_validate_addr, + .ndo_get_stats64 = mana_get_stats64, + .ndo_bpf = mana_bpf, ++ .ndo_xdp_xmit = mana_xdp_xmit, + }; + + static void mana_cleanup_port_context(struct mana_port_context *apc) +@@ -1120,6 +1122,9 @@ static void mana_rx_skb(void *buf_va, struct mana_rxcomp_oob *cqe, + + act = mana_run_xdp(ndev, rxq, &xdp, buf_va, pkt_len); + ++ if (act == XDP_REDIRECT && !rxq->xdp_rc) ++ return; ++ + if (act != XDP_PASS && act != XDP_TX) + goto drop_xdp; + +@@ -1275,11 +1280,14 @@ drop: + static void mana_poll_rx_cq(struct mana_cq *cq) + { + struct gdma_comp *comp = cq->gdma_comp_buf; ++ struct mana_rxq *rxq = cq->rxq; + int comp_read, i; + + comp_read = mana_gd_poll_cq(cq->gdma_cq, comp, CQE_POLLING_BUFFER); + WARN_ON_ONCE(comp_read > CQE_POLLING_BUFFER); + ++ rxq->xdp_flush = false; ++ + for (i = 0; i < comp_read; i++) { + if (WARN_ON_ONCE(comp[i].is_sq)) + return; +@@ -1288,8 +1296,11 @@ static void mana_poll_rx_cq(struct mana_cq *cq) + if (WARN_ON_ONCE(comp[i].wq_num != cq->rxq->gdma_id)) + return; + +- mana_process_rx_cqe(cq->rxq, cq, &comp[i]); ++ mana_process_rx_cqe(rxq, cq, &comp[i]); + } ++ ++ if (rxq->xdp_flush) ++ xdp_do_flush(); + } + + static void mana_cq_handler(void *context, struct gdma_queue *gdma_queue) +diff --git a/drivers/net/ethernet/microsoft/mana/mana_ethtool.c b/drivers/net/ethernet/microsoft/mana/mana_ethtool.c +--- a/drivers/net/ethernet/microsoft/mana/mana_ethtool.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_ethtool.c +@@ -23,7 +23,7 @@ static int mana_get_sset_count(struct net_device *ndev, int stringset) + if (stringset != ETH_SS_STATS) + return -EINVAL; + +- return ARRAY_SIZE(mana_eth_stats) + num_queues * 6; ++ return ARRAY_SIZE(mana_eth_stats) + num_queues * 8; + } + + static void mana_get_strings(struct net_device *ndev, u32 stringset, u8 *data) +@@ -50,6 +50,8 @@ static void mana_get_strings(struct net_device *ndev, u32 stringset, u8 *data) + p += ETH_GSTRING_LEN; + sprintf(p, "rx_%d_xdp_tx", i); + p += ETH_GSTRING_LEN; ++ sprintf(p, "rx_%d_xdp_redirect", i); ++ p += ETH_GSTRING_LEN; + } + + for (i = 0; i < num_queues; i++) { +@@ -57,6 +59,8 @@ static void mana_get_strings(struct net_device *ndev, u32 stringset, u8 *data) + p += ETH_GSTRING_LEN; + sprintf(p, "tx_%d_bytes", i); + p += ETH_GSTRING_LEN; ++ sprintf(p, "tx_%d_xdp_xmit", i); ++ p += ETH_GSTRING_LEN; + } + } + +@@ -70,6 +74,8 @@ static void mana_get_ethtool_stats(struct net_device *ndev, + struct mana_stats_tx *tx_stats; + unsigned int start; + u64 packets, bytes; ++ u64 xdp_redirect; ++ u64 xdp_xmit; + u64 xdp_drop; + u64 xdp_tx; + int q, i = 0; +@@ -89,12 +95,14 @@ static void mana_get_ethtool_stats(struct net_device *ndev, + 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)); + + data[i++] = packets; + data[i++] = bytes; + data[i++] = xdp_drop; + data[i++] = xdp_tx; ++ data[i++] = xdp_redirect; + } + + for (q = 0; q < num_queues; q++) { +@@ -104,10 +112,12 @@ static void mana_get_ethtool_stats(struct net_device *ndev, + start = u64_stats_fetch_begin_irq(&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)); + + data[i++] = packets; + data[i++] = bytes; ++ data[i++] = xdp_xmit; + } + } + diff --git a/patches.suse/msft-hv-2644-net-mana-Add-rmb-after-checking-owner-bits.patch b/patches.suse/msft-hv-2644-net-mana-Add-rmb-after-checking-owner-bits.patch new file mode 100644 index 0000000..2afa7cd --- /dev/null +++ b/patches.suse/msft-hv-2644-net-mana-Add-rmb-after-checking-owner-bits.patch @@ -0,0 +1,51 @@ +From: Haiyang Zhang +Date: Sun, 11 Sep 2022 13:40:05 -0700 +Patch-mainline: v6.0-rc7 +Subject: net: mana: Add rmb after checking owner bits +Git-commit: 6fd2c68da55c552f86e401ebe40c4a619025ef69 +References: git-fixes + +Per GDMA spec, rmb is necessary after checking owner_bits, before +reading EQ or CQ entries. + +Add rmb in these two places to comply with the specs. + +Cc: stable@vger.kernel.org +Fixes: ca9c54d2d6a5 ("net: mana: Add a driver for Microsoft Azure Network Adapter (MANA)") +Reported-by: Sinan Kaya +Signed-off-by: Haiyang Zhang +Reviewed-by: Dexuan Cui +Link: https://lore.kernel.org/r/1662928805-15861-1-git-send-email-haiyangz@microsoft.com +Signed-off-by: Jakub Kicinski +Acked-by: Olaf Hering +--- + drivers/net/ethernet/microsoft/mana/gdma_main.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/net/ethernet/microsoft/mana/gdma_main.c b/drivers/net/ethernet/microsoft/mana/gdma_main.c +--- a/drivers/net/ethernet/microsoft/mana/gdma_main.c ++++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c +@@ -397,6 +397,11 @@ static void mana_gd_process_eq_events(void *arg) + break; + } + ++ /* Per GDMA spec, rmb is necessary after checking owner_bits, before ++ * reading eqe. ++ */ ++ rmb(); ++ + mana_gd_process_eqe(eq); + + eq->head++; +@@ -1134,6 +1139,11 @@ static int mana_gd_read_cqe(struct gdma_queue *cq, struct gdma_comp *comp) + if (WARN_ON_ONCE(owner_bits != new_bits)) + return -1; + ++ /* Per GDMA spec, rmb is necessary after checking owner_bits, before ++ * reading completion info ++ */ ++ rmb(); ++ + comp->wq_num = cqe->cqe_info.wq_num; + comp->is_sq = cqe->cqe_info.is_sq; + memcpy(comp->cqe_data, cqe->cqe_data, GDMA_COMP_DATA_SIZE); diff --git a/patches.suse/mtd-devices-docg3-check-the-return-value-of-devm_ior.patch b/patches.suse/mtd-devices-docg3-check-the-return-value-of-devm_ior.patch new file mode 100644 index 0000000..d4257f1 --- /dev/null +++ b/patches.suse/mtd-devices-docg3-check-the-return-value-of-devm_ior.patch @@ -0,0 +1,45 @@ +From 26e784433e6c65735cd6d93a8db52531970d9a60 Mon Sep 17 00:00:00 2001 +From: William Dean +Date: Fri, 22 Jul 2022 17:16:44 +0800 +Subject: [PATCH] mtd: devices: docg3: check the return value of devm_ioremap() in the probe +Git-commit: 26e784433e6c65735cd6d93a8db52531970d9a60 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The function devm_ioremap() in docg3_probe() can fail, so +its return value should be checked. + +Fixes: 82402aeb8c81e ("mtd: docg3: Use devm_*() functions") +Reported-by: Hacash Robot +Signed-off-by: William Dean +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20220722091644.2937953-1-williamsukatube@163.com +Acked-by: Takashi Iwai + +--- + drivers/mtd/devices/docg3.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c +index 5b0ae5ddad74..27c08f22dec8 100644 +--- a/drivers/mtd/devices/docg3.c ++++ b/drivers/mtd/devices/docg3.c +@@ -1974,9 +1974,14 @@ static int __init docg3_probe(struct platform_device *pdev) + dev_err(dev, "No I/O memory resource defined\n"); + return ret; + } +- base = devm_ioremap(dev, ress->start, DOC_IOSPACE_SIZE); + + ret = -ENOMEM; ++ base = devm_ioremap(dev, ress->start, DOC_IOSPACE_SIZE); ++ if (!base) { ++ dev_err(dev, "devm_ioremap dev failed\n"); ++ return ret; ++ } ++ + cascade = devm_kcalloc(dev, DOC_MAX_NBFLOORS, sizeof(*cascade), + GFP_KERNEL); + if (!cascade) +-- +2.35.3 + diff --git a/patches.suse/mtd-rawnand-atmel-Unmap-streaming-DMA-mappings.patch b/patches.suse/mtd-rawnand-atmel-Unmap-streaming-DMA-mappings.patch new file mode 100644 index 0000000..5aae15b --- /dev/null +++ b/patches.suse/mtd-rawnand-atmel-Unmap-streaming-DMA-mappings.patch @@ -0,0 +1,44 @@ +From 1161703c9bd664da5e3b2eb1a3bb40c210e026ea Mon Sep 17 00:00:00 2001 +From: Tudor Ambarus +Date: Thu, 28 Jul 2022 10:40:14 +0300 +Subject: [PATCH] mtd: rawnand: atmel: Unmap streaming DMA mappings +Git-commit: 1161703c9bd664da5e3b2eb1a3bb40c210e026ea +Patch-mainline: v6.1-rc1 +References: git-fixes + +Every dma_map_single() call should have its dma_unmap_single() counterpart, +because the DMA address space is a shared resource and one could render the +machine unusable by consuming all DMA addresses. + +Link: https://lore.kernel.org/lkml/13c6c9a2-6db5-c3bf-349b-4c127ad3496a@axentia.se/ +Cc: stable@vger.kernel.org +Fixes: f88fc122cc34 ("mtd: nand: Cleanup/rework the atmel_nand driver") +Signed-off-by: Tudor Ambarus +Acked-by: Alexander Dahl +Reported-by: Peter Rosin +Tested-by: Alexander Dahl +Reviewed-by: Boris Brezillon +Tested-by: Peter Rosin +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20220728074014.145406-1-tudor.ambarus@microchip.com +Acked-by: Takashi Iwai + +--- + drivers/mtd/nand/raw/atmel/nand-controller.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c +index c9ac3baf68c0..41c6bd6e2d72 100644 +--- a/drivers/mtd/nand/raw/atmel/nand-controller.c ++++ b/drivers/mtd/nand/raw/atmel/nand-controller.c +@@ -405,6 +405,7 @@ static int atmel_nand_dma_transfer(struct atmel_nand_controller *nc, + + dma_async_issue_pending(nc->dmac); + wait_for_completion(&finished); ++ dma_unmap_single(nc->dev, buf_dma, len, dir); + + return 0; + +-- +2.35.3 + diff --git a/patches.suse/mtd-rawnand-fsl_elbc-Fix-none-ECC-mode.patch b/patches.suse/mtd-rawnand-fsl_elbc-Fix-none-ECC-mode.patch new file mode 100644 index 0000000..b73df67 --- /dev/null +++ b/patches.suse/mtd-rawnand-fsl_elbc-Fix-none-ECC-mode.patch @@ -0,0 +1,97 @@ +From 049e43b9fd8fd2966940485da163d67e96ee3fea Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= +Date: Thu, 7 Jul 2022 20:43:28 +0200 +Subject: [PATCH] mtd: rawnand: fsl_elbc: Fix none ECC mode +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 049e43b9fd8fd2966940485da163d67e96ee3fea +Patch-mainline: v6.1-rc1 +References: git-fixes + +Commit f6424c22aa36 ("mtd: rawnand: fsl_elbc: Make SW ECC work") added +support for specifying ECC mode via DTS and skipping autodetection. + +But it broke explicit specification of HW ECC mode in DTS as correct +settings for HW ECC mode are applied only when NONE mode or nothing was +specified in DTS file. + +Also it started aliasing NONE mode to be same as when ECC mode was not +specified and disallowed usage of ON_DIE mode. + +Fix all these issues. Use autodetection of ECC mode only in case when mode +was really not specified in DTS file by checking that ecc value is invalid. +Set HW ECC settings either when HW ECC was specified in DTS or it was +autodetected. And do not fail when ON_DIE mode is set. + +Fixes: f6424c22aa36 ("mtd: rawnand: fsl_elbc: Make SW ECC work") +Signed-off-by: Pali Rohár +Reviewed-by: Marek Behún +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20220707184328.3845-1-pali@kernel.org +Acked-by: Takashi Iwai + +--- + drivers/mtd/nand/raw/fsl_elbc_nand.c | 28 ++++++++++++++++------------ + 1 file changed, 16 insertions(+), 12 deletions(-) + +diff --git a/drivers/mtd/nand/raw/fsl_elbc_nand.c b/drivers/mtd/nand/raw/fsl_elbc_nand.c +index aab93b9e6052..a18d121396aa 100644 +--- a/drivers/mtd/nand/raw/fsl_elbc_nand.c ++++ b/drivers/mtd/nand/raw/fsl_elbc_nand.c +@@ -726,36 +726,40 @@ static int fsl_elbc_attach_chip(struct nand_chip *chip) + struct fsl_lbc_regs __iomem *lbc = ctrl->regs; + unsigned int al; + +- switch (chip->ecc.engine_type) { + /* + * if ECC was not chosen in DT, decide whether to use HW or SW ECC from + * CS Base Register + */ +- case NAND_ECC_ENGINE_TYPE_NONE: ++ if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_INVALID) { + /* If CS Base Register selects full hardware ECC then use it */ + if ((in_be32(&lbc->bank[priv->bank].br) & BR_DECC) == + BR_DECC_CHK_GEN) { +- chip->ecc.read_page = fsl_elbc_read_page; +- chip->ecc.write_page = fsl_elbc_write_page; +- chip->ecc.write_subpage = fsl_elbc_write_subpage; +- + chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; +- mtd_set_ooblayout(mtd, &fsl_elbc_ooblayout_ops); +- chip->ecc.size = 512; +- chip->ecc.bytes = 3; +- chip->ecc.strength = 1; + } else { + /* otherwise fall back to default software ECC */ + chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; + chip->ecc.algo = NAND_ECC_ALGO_HAMMING; + } ++ } ++ ++ switch (chip->ecc.engine_type) { ++ /* if HW ECC was chosen, setup ecc and oob layout */ ++ case NAND_ECC_ENGINE_TYPE_ON_HOST: ++ chip->ecc.read_page = fsl_elbc_read_page; ++ chip->ecc.write_page = fsl_elbc_write_page; ++ chip->ecc.write_subpage = fsl_elbc_write_subpage; ++ mtd_set_ooblayout(mtd, &fsl_elbc_ooblayout_ops); ++ chip->ecc.size = 512; ++ chip->ecc.bytes = 3; ++ chip->ecc.strength = 1; + break; + +- /* if SW ECC was chosen in DT, we do not need to set anything here */ ++ /* if none or SW ECC was chosen, we do not need to set anything here */ ++ case NAND_ECC_ENGINE_TYPE_NONE: + case NAND_ECC_ENGINE_TYPE_SOFT: ++ case NAND_ECC_ENGINE_TYPE_ON_DIE: + break; + +- /* should we also implement *_ECC_ENGINE_CONTROLLER to do as above? */ + default: + return -EINVAL; + } +-- +2.35.3 + diff --git a/patches.suse/mtd-rawnand-intel-Don-t-re-define-NAND_DATA_IFACE_CH.patch b/patches.suse/mtd-rawnand-intel-Don-t-re-define-NAND_DATA_IFACE_CH.patch new file mode 100644 index 0000000..b4fbaea --- /dev/null +++ b/patches.suse/mtd-rawnand-intel-Don-t-re-define-NAND_DATA_IFACE_CH.patch @@ -0,0 +1,33 @@ +From ebe0cd60fcffd499f8020fde9b3b74acba9c22af Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Sun, 3 Jul 2022 01:12:24 +0200 +Subject: [PATCH] mtd: rawnand: intel: Don't re-define NAND_DATA_IFACE_CHECK_ONLY +Git-commit: ebe0cd60fcffd499f8020fde9b3b74acba9c22af +Patch-mainline: v6.1-rc1 +References: git-fixes + +NAND_DATA_IFACE_CHECK_ONLY is already defined in +include/linux/mtd/rawnand.h which is also included by the driver. Drop +the re-definition from the intel-nand-controller driver. + +Fixes: 0b1039f016e8a3 ("mtd: rawnand: Add NAND controller support on Intel LGM SoC") +Signed-off-by: Martin Blumenstingl +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20220702231227.1579176-6-martin.blumenstingl@googlemail.com +Acked-by: Takashi Iwai + +--- + drivers/mtd/nand/raw/intel-nand-controller.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/mtd/nand/raw/intel-nand-controller.c ++++ b/drivers/mtd/nand/raw/intel-nand-controller.c +@@ -99,8 +99,6 @@ + + #define HSNAND_ECC_OFFSET 0x008 + +-#define NAND_DATA_IFACE_CHECK_ONLY -1 +- + #define MAX_CS 2 + + #define HZ_PER_MHZ 1000000L diff --git a/patches.suse/mtd-rawnand-intel-Read-the-chip-select-line-from-the.patch b/patches.suse/mtd-rawnand-intel-Read-the-chip-select-line-from-the.patch new file mode 100644 index 0000000..466e28e --- /dev/null +++ b/patches.suse/mtd-rawnand-intel-Read-the-chip-select-line-from-the.patch @@ -0,0 +1,67 @@ +From bfc618fcc3f167ad082053e81e9d664e724c6288 Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Sun, 3 Jul 2022 01:12:22 +0200 +Subject: [PATCH] mtd: rawnand: intel: Read the chip-select line from the correct OF node +Git-commit: bfc618fcc3f167ad082053e81e9d664e724c6288 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The chip select has to be read from the flash node which is a child node +of the NAND controller. + +Fixes: 0b1039f016e8a3 ("mtd: rawnand: Add NAND controller support on Intel LGM SoC") +Signed-off-by: Martin Blumenstingl +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20220702231227.1579176-4-martin.blumenstingl@googlemail.com +Acked-by: Takashi Iwai + +--- + drivers/mtd/nand/raw/intel-nand-controller.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/drivers/mtd/nand/raw/intel-nand-controller.c b/drivers/mtd/nand/raw/intel-nand-controller.c +index e91b879b32bd..3df3f32423f9 100644 +--- a/drivers/mtd/nand/raw/intel-nand-controller.c ++++ b/drivers/mtd/nand/raw/intel-nand-controller.c +@@ -16,6 +16,7 @@ + #include + #include + ++#include + #include + #include + #include +@@ -580,6 +581,7 @@ static int ebu_nand_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; + struct ebu_nand_controller *ebu_host; ++ struct device_node *chip_np; + struct nand_chip *nand; + struct mtd_info *mtd; + struct resource *res; +@@ -604,7 +606,12 @@ static int ebu_nand_probe(struct platform_device *pdev) + if (IS_ERR(ebu_host->hsnand)) + return PTR_ERR(ebu_host->hsnand); + +- ret = device_property_read_u32(dev, "reg", &cs); ++ chip_np = of_get_next_child(dev->of_node, NULL); ++ if (!chip_np) ++ return dev_err_probe(dev, -EINVAL, ++ "Could not find child node for the NAND chip\n"); ++ ++ ret = of_property_read_u32(chip_np, "reg", &cs); + if (ret) { + dev_err(dev, "failed to get chip select: %d\n", ret); + return ret; +@@ -660,7 +667,7 @@ static int ebu_nand_probe(struct platform_device *pdev) + writel(ebu_host->cs[cs].addr_sel | EBU_ADDR_MASK(5) | EBU_ADDR_SEL_REGEN, + ebu_host->ebu + EBU_ADDR_SEL(cs)); + +- nand_set_flash_node(&ebu_host->chip, dev->of_node); ++ nand_set_flash_node(&ebu_host->chip, chip_np); + + mtd = nand_to_mtd(&ebu_host->chip); + if (!mtd->name) { +-- +2.35.3 + diff --git a/patches.suse/mtd-rawnand-intel-Remove-undocumented-compatible-str.patch b/patches.suse/mtd-rawnand-intel-Remove-undocumented-compatible-str.patch new file mode 100644 index 0000000..2f17592 --- /dev/null +++ b/patches.suse/mtd-rawnand-intel-Remove-undocumented-compatible-str.patch @@ -0,0 +1,37 @@ +From 68c02ebaa34d41063ccbbc789a352537ddc3cd8a Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Sun, 3 Jul 2022 01:12:23 +0200 +Subject: [PATCH] mtd: rawnand: intel: Remove undocumented compatible string +Git-commit: 68c02ebaa34d41063ccbbc789a352537ddc3cd8a +Patch-mainline: v6.1-rc1 +References: git-fixes + +The "intel,nand-controller" compatible string is not part of the +dt-bindings. Remove it from the driver as it's not supposed to be used +without any documentation for it. + +Fixes: 0b1039f016e8a3 ("mtd: rawnand: Add NAND controller support on Intel LGM SoC") +Signed-off-by: Martin Blumenstingl +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20220702231227.1579176-5-martin.blumenstingl@googlemail.com +Acked-by: Takashi Iwai + +--- + drivers/mtd/nand/raw/intel-nand-controller.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/mtd/nand/raw/intel-nand-controller.c b/drivers/mtd/nand/raw/intel-nand-controller.c +index 3df3f32423f9..056835fd4562 100644 +--- a/drivers/mtd/nand/raw/intel-nand-controller.c ++++ b/drivers/mtd/nand/raw/intel-nand-controller.c +@@ -723,7 +723,6 @@ static int ebu_nand_remove(struct platform_device *pdev) + } + + static const struct of_device_id ebu_nand_match[] = { +- { .compatible = "intel,nand-controller" }, + { .compatible = "intel,lgm-ebunand" }, + {} + }; +-- +2.35.3 + diff --git a/patches.suse/mtd-rawnand-meson-fix-bit-map-use-in-meson_nfc_ecc_c.patch b/patches.suse/mtd-rawnand-meson-fix-bit-map-use-in-meson_nfc_ecc_c.patch new file mode 100644 index 0000000..a639454 --- /dev/null +++ b/patches.suse/mtd-rawnand-meson-fix-bit-map-use-in-meson_nfc_ecc_c.patch @@ -0,0 +1,49 @@ +From 3e4ad3212cf22687410b1e8f4e68feec50646113 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Thu, 28 Jul 2022 10:12:12 +0300 +Subject: [PATCH] mtd: rawnand: meson: fix bit map use in meson_nfc_ecc_correct() +Git-commit: 3e4ad3212cf22687410b1e8f4e68feec50646113 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The meson_nfc_ecc_correct() function accidentally does a right shift +instead of a left shift so it only works for BIT(0). Also use +BIT_ULL() because "correct_bitmap" is a u64 and we want to avoid +shift wrapping bugs. + +Fixes: 8fae856c5350 ("mtd: rawnand: meson: add support for Amlogic NAND flash controller") +Signed-off-by: Dan Carpenter +Acked-by: Liang Yang +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/YuI2zF1hP65+LE7r@kili +Acked-by: Takashi Iwai + +--- + drivers/mtd/nand/raw/meson_nand.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c +index 829b76b303aa..ad2ffd0ca800 100644 +--- a/drivers/mtd/nand/raw/meson_nand.c ++++ b/drivers/mtd/nand/raw/meson_nand.c +@@ -454,7 +454,7 @@ static int meson_nfc_ecc_correct(struct nand_chip *nand, u32 *bitflips, + if (ECC_ERR_CNT(*info) != ECC_UNCORRECTABLE) { + mtd->ecc_stats.corrected += ECC_ERR_CNT(*info); + *bitflips = max_t(u32, *bitflips, ECC_ERR_CNT(*info)); +- *correct_bitmap |= 1 >> i; ++ *correct_bitmap |= BIT_ULL(i); + continue; + } + if ((nand->options & NAND_NEED_SCRAMBLING) && +@@ -800,7 +800,7 @@ static int meson_nfc_read_page_hwecc(struct nand_chip *nand, u8 *buf, + u8 *data = buf + i * ecc->size; + u8 *oob = nand->oob_poi + i * (ecc->bytes + 2); + +- if (correct_bitmap & (1 << i)) ++ if (correct_bitmap & BIT_ULL(i)) + continue; + ret = nand_check_erased_ecc_chunk(data, ecc->size, + oob, ecc->bytes + 2, +-- +2.35.3 + diff --git a/patches.suse/mwifiex-fix-sleep-in-atomic-context-bugs-caused-by-d.patch b/patches.suse/mwifiex-fix-sleep-in-atomic-context-bugs-caused-by-d.patch new file mode 100644 index 0000000..1daf22b --- /dev/null +++ b/patches.suse/mwifiex-fix-sleep-in-atomic-context-bugs-caused-by-d.patch @@ -0,0 +1,174 @@ +From 551e4745c7f218da7070b36a06318592913676ff Mon Sep 17 00:00:00 2001 +From: Duoming Zhou +Date: Tue, 23 Aug 2022 19:21:27 +0800 +Subject: [PATCH] mwifiex: fix sleep in atomic context bugs caused by dev_coredumpv +Git-commit: 551e4745c7f218da7070b36a06318592913676ff +Patch-mainline: v6.1-rc1 +References: git-fixes + +There are sleep in atomic context bugs when uploading device dump +data in mwifiex. The root cause is that dev_coredumpv could not +be used in atomic contexts, because it calls dev_set_name which +include operations that may sleep. The call tree shows execution +paths that could lead to bugs: + + (Interrupt context) +fw_dump_timer_fn + mwifiex_upload_device_dump + dev_coredumpv(..., GFP_KERNEL) + dev_coredumpm() + kzalloc(sizeof(*devcd), gfp); //may sleep + dev_set_name + kobject_set_name_vargs + kvasprintf_const(GFP_KERNEL, ...); //may sleep + kstrdup(s, GFP_KERNEL); //may sleep + +The corresponding fail log is shown below: + +[ 135.275938] usb 1-1: == mwifiex dump information to /sys/class/devcoredump start +[ 135.281029] BUG: sleeping function called from invalid context at include/linux/sched/mm.h:265 +... +[ 135.293613] Call Trace: +[ 135.293613] +[ 135.293613] dump_stack_lvl+0x57/0x7d +[ 135.293613] __might_resched.cold+0x138/0x173 +[ 135.293613] ? dev_coredumpm+0xca/0x2e0 +[ 135.293613] kmem_cache_alloc_trace+0x189/0x1f0 +[ 135.293613] ? devcd_match_failing+0x30/0x30 +[ 135.293613] dev_coredumpm+0xca/0x2e0 +[ 135.293613] ? devcd_freev+0x10/0x10 +[ 135.293613] dev_coredumpv+0x1c/0x20 +[ 135.293613] ? devcd_match_failing+0x30/0x30 +[ 135.293613] mwifiex_upload_device_dump+0x65/0xb0 +[ 135.293613] ? mwifiex_dnld_fw+0x1b0/0x1b0 +[ 135.293613] call_timer_fn+0x122/0x3d0 +[ 135.293613] ? msleep_interruptible+0xb0/0xb0 +[ 135.293613] ? lock_downgrade+0x3c0/0x3c0 +[ 135.293613] ? __next_timer_interrupt+0x13c/0x160 +[ 135.293613] ? lockdep_hardirqs_on_prepare+0xe/0x220 +[ 135.293613] ? mwifiex_dnld_fw+0x1b0/0x1b0 +[ 135.293613] __run_timers.part.0+0x3f8/0x540 +[ 135.293613] ? call_timer_fn+0x3d0/0x3d0 +[ 135.293613] ? arch_restore_msi_irqs+0x10/0x10 +[ 135.293613] ? lapic_next_event+0x31/0x40 +[ 135.293613] run_timer_softirq+0x4f/0xb0 +[ 135.293613] __do_softirq+0x1c2/0x651 +... +[ 135.293613] RIP: 0010:default_idle+0xb/0x10 +[ 135.293613] RSP: 0018:ffff888006317e68 EFLAGS: 00000246 +[ 135.293613] RAX: ffffffff82ad8d10 RBX: ffff888006301cc0 RCX: ffffffff82ac90e1 +[ 135.293613] RDX: ffffed100d9ff1b4 RSI: ffffffff831ad140 RDI: ffffffff82ad8f20 +[ 135.293613] RBP: 0000000000000003 R08: 0000000000000000 R09: ffff88806cff8d9b +[ 135.293613] R10: ffffed100d9ff1b3 R11: 0000000000000001 R12: ffffffff84593410 +[ 135.293613] R13: 0000000000000000 R14: 0000000000000000 R15: 1ffff11000c62fd2 +... +[ 135.389205] usb 1-1: == mwifiex dump information to /sys/class/devcoredump end + +This patch uses delayed work to replace timer and moves the operations +that may sleep into a delayed work in order to mitigate bugs, it was +tested on Marvell 88W8801 chip whose port is usb and the firmware is +usb8801_uapsta.bin. The following is the result after using delayed +work to replace timer. + +[ 134.936453] usb 1-1: == mwifiex dump information to /sys/class/devcoredump start +[ 135.043344] usb 1-1: == mwifiex dump information to /sys/class/devcoredump end + +As we can see, there is no bug now. + +Fixes: f5ecd02a8b20 ("mwifiex: device dump support for usb interface") +Signed-off-by: Duoming Zhou +Reviewed-by: Brian Norris +Acked-by: Greg Kroah-Hartman +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/5cfa5c473ff6d069cb67760ffa04a2f84ef450a8.1661252818.git.duoming@zju.edu.cn +Acked-by: Takashi Iwai + +--- + drivers/net/wireless/marvell/mwifiex/init.c | 9 +++++---- + drivers/net/wireless/marvell/mwifiex/main.h | 3 ++- + drivers/net/wireless/marvell/mwifiex/sta_event.c | 6 +++--- + 3 files changed, 10 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/wireless/marvell/mwifiex/init.c b/drivers/net/wireless/marvell/mwifiex/init.c +index fc77489cc511..7dddb4b5dea1 100644 +--- a/drivers/net/wireless/marvell/mwifiex/init.c ++++ b/drivers/net/wireless/marvell/mwifiex/init.c +@@ -51,9 +51,10 @@ static void wakeup_timer_fn(struct timer_list *t) + adapter->if_ops.card_reset(adapter); + } + +-static void fw_dump_timer_fn(struct timer_list *t) ++static void fw_dump_work(struct work_struct *work) + { +- struct mwifiex_adapter *adapter = from_timer(adapter, t, devdump_timer); ++ struct mwifiex_adapter *adapter = ++ container_of(work, struct mwifiex_adapter, devdump_work.work); + + mwifiex_upload_device_dump(adapter); + } +@@ -309,7 +310,7 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) + adapter->active_scan_triggered = false; + timer_setup(&adapter->wakeup_timer, wakeup_timer_fn, 0); + adapter->devdump_len = 0; +- timer_setup(&adapter->devdump_timer, fw_dump_timer_fn, 0); ++ INIT_DELAYED_WORK(&adapter->devdump_work, fw_dump_work); + } + + /* +@@ -388,7 +389,7 @@ static void + mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter) + { + del_timer(&adapter->wakeup_timer); +- del_timer_sync(&adapter->devdump_timer); ++ cancel_delayed_work_sync(&adapter->devdump_work); + mwifiex_cancel_all_pending_cmd(adapter); + wake_up_interruptible(&adapter->cmd_wait_q.wait); + wake_up_interruptible(&adapter->hs_activate_wait_q); +diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h +index 87729d251fed..63f861e6b28a 100644 +--- a/drivers/net/wireless/marvell/mwifiex/main.h ++++ b/drivers/net/wireless/marvell/mwifiex/main.h +@@ -37,6 +37,7 @@ + #include + #include + #include ++#include + + #include "decl.h" + #include "ioctl.h" +@@ -1043,7 +1044,7 @@ struct mwifiex_adapter { + /* Device dump data/length */ + void *devdump_data; + int devdump_len; +- struct timer_list devdump_timer; ++ struct delayed_work devdump_work; + + bool ignore_btcoex_events; + }; +diff --git a/drivers/net/wireless/marvell/mwifiex/sta_event.c b/drivers/net/wireless/marvell/mwifiex/sta_event.c +index b6315fccd1bb..df9cdd10a494 100644 +--- a/drivers/net/wireless/marvell/mwifiex/sta_event.c ++++ b/drivers/net/wireless/marvell/mwifiex/sta_event.c +@@ -611,8 +611,8 @@ mwifiex_fw_dump_info_event(struct mwifiex_private *priv, + * transmission event get lost, in this cornel case, + * user would still get partial of the dump. + */ +- mod_timer(&adapter->devdump_timer, +- jiffies + msecs_to_jiffies(MWIFIEX_TIMER_10S)); ++ schedule_delayed_work(&adapter->devdump_work, ++ msecs_to_jiffies(MWIFIEX_TIMER_10S)); + } + + /* Overflow check */ +@@ -631,7 +631,7 @@ mwifiex_fw_dump_info_event(struct mwifiex_private *priv, + return; + + upload_dump: +- del_timer_sync(&adapter->devdump_timer); ++ cancel_delayed_work_sync(&adapter->devdump_work); + mwifiex_upload_device_dump(adapter); + } + +-- +2.35.3 + diff --git a/patches.suse/net-add-skb_-inner_-tcp_all_headers-helpers.patch b/patches.suse/net-add-skb_-inner_-tcp_all_headers-helpers.patch new file mode 100644 index 0000000..ed93d1e --- /dev/null +++ b/patches.suse/net-add-skb_-inner_-tcp_all_headers-helpers.patch @@ -0,0 +1,897 @@ +From: Eric Dumazet +Date: Thu, 30 Jun 2022 15:07:50 +0000 +Subject: net: add skb_[inner_]tcp_all_headers helpers +Git-commit: 504148fedb854299972d164b001357b888a9193e +Patch-mainline: v6.0-rc1 +References: jsc#PED-1302 + +Most drivers use "skb_transport_offset(skb) + tcp_hdrlen(skb)" +to compute headers length for a TCP packet, but others +use more convoluted (but equivalent) ways. + +Add skb_tcp_all_headers() and skb_inner_tcp_all_headers() +helpers to harmonize this a bit. + +[lduncan: hand refreshed to apply correctly.] + +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Acked-by: Lee Duncan +--- + drivers/infiniband/ulp/ipoib/ipoib_ib.c | 2 + drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 6 -- + drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 9 +-- + drivers/net/ethernet/atheros/atl1e/atl1e_main.c | 8 +- + drivers/net/ethernet/atheros/atlx/atl1.c | 7 +- + drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 17 ++--- + drivers/net/ethernet/broadcom/bnxt/bnxt.c | 7 -- + drivers/net/ethernet/broadcom/tg3.c | 2 + drivers/net/ethernet/brocade/bna/bnad.c | 6 -- + drivers/net/ethernet/cadence/macb_main.c | 2 + drivers/net/ethernet/cavium/thunder/nicvf_queues.c | 4 - + drivers/net/ethernet/chelsio/cxgb4/sge.c | 2 + drivers/net/ethernet/chelsio/inline_crypto/ch_ktls/chcr_ktls.c | 6 +- + drivers/net/ethernet/cisco/enic/enic_main.c | 5 - + drivers/net/ethernet/emulex/benet/be_main.c | 6 +- + drivers/net/ethernet/freescale/fec_main.c | 2 + drivers/net/ethernet/google/gve/gve_tx_dqo.c | 4 - + drivers/net/ethernet/hisilicon/hns/hns_enet.c | 6 -- + drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 4 - + drivers/net/ethernet/hisilicon/hns3/hns3_trace.h | 3 - + drivers/net/ethernet/ibm/ehea/ehea_main.c | 2 + drivers/net/ethernet/intel/e1000/e1000_main.c | 4 - + drivers/net/ethernet/intel/e1000e/netdev.c | 4 - + drivers/net/ethernet/intel/ixgb/ixgb_main.c | 2 + drivers/net/ethernet/marvell/mv643xx_eth.c | 2 + drivers/net/ethernet/marvell/mvneta.c | 4 - + drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c | 4 - + drivers/net/ethernet/marvell/sky2.c | 2 + drivers/net/ethernet/mellanox/mlx4/en_tx.c | 4 - + drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c | 2 + drivers/net/ethernet/mellanox/mlx5/core/en_tx.c | 4 - + drivers/net/ethernet/myricom/myri10ge/myri10ge.c | 2 + drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 7 +- + drivers/net/ethernet/pensando/ionic/ionic_txrx.c | 5 - + drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c | 2 + drivers/net/ethernet/qlogic/qede/qede_fp.c | 8 +- + drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c | 2 + drivers/net/ethernet/qualcomm/emac/emac-mac.c | 4 - + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 + drivers/net/ethernet/synopsys/dwc-xlgmac-net.c | 2 + drivers/net/wireless/ath/wil6210/txrx.c | 4 - + drivers/net/xen-netback/netback.c | 4 - + drivers/staging/qlge/qlge_main.c | 2 + include/linux/tcp.h | 30 ++++++++++ + net/tls/tls_device_fallback.c | 6 +- + 45 files changed, 114 insertions(+), 108 deletions(-) + +--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c ++++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c +@@ -573,7 +573,7 @@ int ipoib_send(struct net_device *dev, s + unsigned int usable_sge = priv->max_send_sge - !!skb_headlen(skb); + + if (skb_is_gso(skb)) { +- hlen = skb_transport_offset(skb) + tcp_hdrlen(skb); ++ hlen = skb_tcp_all_headers(skb); + phead = skb->data; + if (unlikely(!skb_pull(skb, hlen))) { + ipoib_warn(priv, "linear data too small\n"); +--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c ++++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c +@@ -1676,12 +1676,10 @@ static int xgbe_prep_tso(struct sk_buff + return ret; + + if (XGMAC_GET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES, VXLAN)) { +- packet->header_len = skb_inner_transport_offset(skb) + +- inner_tcp_hdrlen(skb); ++ packet->header_len = skb_inner_tcp_all_headers(skb); + packet->tcp_header_len = inner_tcp_hdrlen(skb); + } else { +- packet->header_len = skb_transport_offset(skb) + +- tcp_hdrlen(skb); ++ packet->header_len = skb_tcp_all_headers(skb); + packet->tcp_header_len = tcp_hdrlen(skb); + } + packet->tcp_payload_len = skb->len - packet->header_len; +--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c ++++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +@@ -2072,7 +2072,7 @@ static u16 atl1c_cal_tpd_req(const struc + tpd_req = skb_shinfo(skb)->nr_frags + 1; + + if (skb_is_gso(skb)) { +- proto_hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); ++ proto_hdr_len = skb_tcp_all_headers(skb); + if (proto_hdr_len < skb_headlen(skb)) + tpd_req++; + if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) +@@ -2107,7 +2107,7 @@ static int atl1c_tso_csum(struct atl1c_a + if (real_len < skb->len) + pskb_trim(skb, real_len); + +- hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb)); ++ hdr_len = skb_tcp_all_headers(skb); + if (unlikely(skb->len == hdr_len)) { + /* only xsum need */ + if (netif_msg_tx_queued(adapter)) +@@ -2132,7 +2132,7 @@ static int atl1c_tso_csum(struct atl1c_a + *tpd = atl1c_get_tpd(adapter, queue); + ipv6_hdr(skb)->payload_len = 0; + /* check payload == 0 byte ? */ +- hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb)); ++ hdr_len = skb_tcp_all_headers(skb); + if (unlikely(skb->len == hdr_len)) { + /* only xsum need */ + if (netif_msg_tx_queued(adapter)) +@@ -2219,7 +2219,8 @@ static int atl1c_tx_map(struct atl1c_ada + tso = (tpd->word1 >> TPD_LSO_EN_SHIFT) & TPD_LSO_EN_MASK; + if (tso) { + /* TSO */ +- map_len = hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); ++ hdr_len = skb_tcp_all_headers(skb); ++ map_len = hdr_len; + use_tpd = tpd; + + buffer_info = atl1c_get_tx_buffer(adapter, use_tpd); +--- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c ++++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +@@ -1609,8 +1609,7 @@ static u16 atl1e_cal_tdp_req(const struc + if (skb_is_gso(skb)) { + if (skb->protocol == htons(ETH_P_IP) || + (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6)) { +- proto_hdr_len = skb_transport_offset(skb) + +- tcp_hdrlen(skb); ++ proto_hdr_len = skb_tcp_all_headers(skb); + if (proto_hdr_len < skb_headlen(skb)) { + tpd_req += ((skb_headlen(skb) - proto_hdr_len + + MAX_TX_BUF_LEN - 1) >> +@@ -1645,7 +1644,7 @@ static int atl1e_tso_csum(struct atl1e_a + if (real_len < skb->len) + pskb_trim(skb, real_len); + +- hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb)); ++ hdr_len = skb_tcp_all_headers(skb); + if (unlikely(skb->len == hdr_len)) { + /* only xsum need */ + netdev_warn(adapter->netdev, +@@ -1713,7 +1712,8 @@ static int atl1e_tx_map(struct atl1e_ada + segment = (tpd->word3 >> TPD_SEGMENT_EN_SHIFT) & TPD_SEGMENT_EN_MASK; + if (segment) { + /* TSO */ +- map_len = hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); ++ hdr_len = skb_tcp_all_headers(skb); ++ map_len = hdr_len; + use_tpd = tpd; + + tx_buffer = atl1e_get_tx_buffer(adapter, use_tpd); +--- a/drivers/net/ethernet/atheros/atlx/atl1.c ++++ b/drivers/net/ethernet/atheros/atlx/atl1.c +@@ -2115,7 +2115,7 @@ static int atl1_tso(struct atl1_adapter + ntohs(iph->tot_len)); + if (real_len < skb->len) + pskb_trim(skb, real_len); +- hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb)); ++ hdr_len = skb_tcp_all_headers(skb); + if (skb->len == hdr_len) { + iph->check = 0; + tcp_hdr(skb)->check = +@@ -2206,7 +2206,7 @@ static void atl1_tx_map(struct atl1_adap + retval = (ptpd->word3 >> TPD_SEGMENT_EN_SHIFT) & TPD_SEGMENT_EN_MASK; + if (retval) { + /* TSO */ +- hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); ++ hdr_len = skb_tcp_all_headers(skb); + buffer_info->length = hdr_len; + page = virt_to_page(skb->data); + offset = offset_in_page(skb->data); +@@ -2367,8 +2367,7 @@ static netdev_tx_t atl1_xmit_frame(struc + mss = skb_shinfo(skb)->gso_size; + if (mss) { + if (skb->protocol == htons(ETH_P_IP)) { +- proto_hdr_len = (skb_transport_offset(skb) + +- tcp_hdrlen(skb)); ++ proto_hdr_len = skb_tcp_all_headers(skb); + if (unlikely(proto_hdr_len > len)) { + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; +--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c ++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +@@ -3421,12 +3421,9 @@ static int bnx2x_pkt_req_lin(struct bnx2 + + /* Headers length */ + if (xmit_type & XMIT_GSO_ENC) +- hlen = (int)(skb_inner_transport_header(skb) - +- skb->data) + +- inner_tcp_hdrlen(skb); ++ hlen = skb_inner_tcp_all_headers(skb); + else +- hlen = (int)(skb_transport_header(skb) - +- skb->data) + tcp_hdrlen(skb); ++ hlen = skb_tcp_all_headers(skb); + + /* Amount of data (w/o headers) on linear part of SKB*/ + first_bd_sz = skb_headlen(skb) - hlen; +@@ -3534,15 +3531,13 @@ static u8 bnx2x_set_pbd_csum_enc(struct + ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT) & + ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW; + +- return skb_inner_transport_header(skb) + +- inner_tcp_hdrlen(skb) - skb->data; ++ return skb_inner_tcp_all_headers(skb); + } + + /* We support checksum offload for TCP and UDP only. + * No need to pass the UDP header length - it's a constant. + */ +- return skb_inner_transport_header(skb) + +- sizeof(struct udphdr) - skb->data; ++ return skb_inner_transport_offset(skb) + sizeof(struct udphdr); + } + + /** +@@ -3568,12 +3563,12 @@ static u8 bnx2x_set_pbd_csum_e2(struct b + ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT) & + ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW; + +- return skb_transport_header(skb) + tcp_hdrlen(skb) - skb->data; ++ return skb_tcp_all_headers(skb); + } + /* We support checksum offload for TCP and UDP only. + * No need to pass the UDP header length - it's a constant. + */ +- return skb_transport_header(skb) + sizeof(struct udphdr) - skb->data; ++ return skb_transport_offset(skb) + sizeof(struct udphdr); + } + + /* set FW indication according to inner or outer protocols if tunneled */ +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -535,12 +535,9 @@ normal_tx: + u32 hdr_len; + + if (skb->encapsulation) +- hdr_len = skb_inner_network_offset(skb) + +- skb_inner_network_header_len(skb) + +- inner_tcp_hdrlen(skb); ++ hdr_len = skb_inner_tcp_all_headers(skb); + else +- hdr_len = skb_transport_offset(skb) + +- tcp_hdrlen(skb); ++ hdr_len = skb_tcp_all_headers(skb); + + txbd1->tx_bd_hsize_lflags |= cpu_to_le32(TX_BD_FLAGS_LSO | + TX_BD_FLAGS_T_IPID | +--- a/drivers/net/ethernet/broadcom/tg3.c ++++ b/drivers/net/ethernet/broadcom/tg3.c +@@ -7944,7 +7944,7 @@ static netdev_tx_t tg3_start_xmit(struct + iph = ip_hdr(skb); + tcp_opt_len = tcp_optlen(skb); + +- hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb) - ETH_HLEN; ++ hdr_len = skb_tcp_all_headers(skb) - ETH_HLEN; + + /* HW/FW can not correctly segment packets that have been + * vlan encapsulated. +--- a/drivers/net/ethernet/brocade/bna/bnad.c ++++ b/drivers/net/ethernet/brocade/bna/bnad.c +@@ -2824,8 +2824,7 @@ bnad_txq_wi_prepare(struct bnad *bnad, s + BNAD_UPDATE_CTR(bnad, tx_skb_mss_too_long); + return -EINVAL; + } +- if (unlikely((gso_size + skb_transport_offset(skb) + +- tcp_hdrlen(skb)) >= skb->len)) { ++ if (unlikely((gso_size + skb_tcp_all_headers(skb)) >= skb->len)) { + txqent->hdr.wi.opcode = htons(BNA_TXQ_WI_SEND); + txqent->hdr.wi.lso_mss = 0; + BNAD_UPDATE_CTR(bnad, tx_skb_tso_too_short); +@@ -2873,8 +2872,7 @@ bnad_txq_wi_prepare(struct bnad *bnad, s + BNAD_UPDATE_CTR(bnad, tcpcsum_offload); + + if (unlikely(skb_headlen(skb) < +- skb_transport_offset(skb) + +- tcp_hdrlen(skb))) { ++ skb_tcp_all_headers(skb))) { + BNAD_UPDATE_CTR(bnad, tx_skb_tcp_hdr); + return -EINVAL; + } +--- a/drivers/net/ethernet/cadence/macb_main.c ++++ b/drivers/net/ethernet/cadence/macb_main.c +@@ -2227,7 +2227,7 @@ static netdev_tx_t macb_start_xmit(struc + /* only queue eth + ip headers separately for UDP */ + hdrlen = skb_transport_offset(skb); + else +- hdrlen = skb_transport_offset(skb) + tcp_hdrlen(skb); ++ hdrlen = skb_tcp_all_headers(skb); + if (skb_headlen(skb) < hdrlen) { + netdev_err(bp->dev, "Error - LSO headers fragmented!!!\n"); + /* if this is required, would need to copy to single buffer */ +--- a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c ++++ b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c +@@ -1260,7 +1260,7 @@ int nicvf_xdp_sq_append_pkt(struct nicvf + static int nicvf_tso_count_subdescs(struct sk_buff *skb) + { + struct skb_shared_info *sh = skb_shinfo(skb); +- unsigned int sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb); ++ unsigned int sh_len = skb_tcp_all_headers(skb); + unsigned int data_len = skb->len - sh_len; + unsigned int p_len = sh->gso_size; + long f_id = -1; /* id of the current fragment */ +@@ -1381,7 +1381,7 @@ nicvf_sq_add_hdr_subdesc(struct nicvf *n + + if (nic->hw_tso && skb_shinfo(skb)->gso_size) { + hdr->tso = 1; +- hdr->tso_start = skb_transport_offset(skb) + tcp_hdrlen(skb); ++ hdr->tso_start = skb_tcp_all_headers(skb); + hdr->tso_max_paysize = skb_shinfo(skb)->gso_size; + /* For non-tunneled pkts, point this to L2 ethertype */ + hdr->inner_l3_offset = skb_network_offset(skb) - 2; +--- a/drivers/net/ethernet/chelsio/cxgb4/sge.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c +@@ -1531,7 +1531,7 @@ static netdev_tx_t cxgb4_eth_xmit(struct + + #if IS_ENABLED(CONFIG_CHELSIO_TLS_DEVICE) + if (cxgb4_is_ktls_skb(skb) && +- (skb->len - (skb_transport_offset(skb) + tcp_hdrlen(skb)))) ++ (skb->len - skb_tcp_all_headers(skb))) + return adap->uld[CXGB4_ULD_KTLS].tx_handler(skb, dev); + #endif /* CHELSIO_TLS_DEVICE */ + +--- a/drivers/net/ethernet/chelsio/inline_crypto/ch_ktls/chcr_ktls.c ++++ b/drivers/net/ethernet/chelsio/inline_crypto/ch_ktls/chcr_ktls.c +@@ -1012,7 +1012,7 @@ chcr_ktls_write_tcp_options(struct chcr_ + /* packet length = eth hdr len + ip hdr len + tcp hdr len + * (including options). + */ +- pktlen = skb_transport_offset(skb) + tcp_hdrlen(skb); ++ pktlen = skb_tcp_all_headers(skb); + + ctrl = sizeof(*cpl) + pktlen; + len16 = DIV_ROUND_UP(sizeof(*wr) + ctrl, 16); +@@ -1907,7 +1907,7 @@ static int chcr_ktls_sw_fallback(struct + return 0; + + th = tcp_hdr(nskb); +- skb_offset = skb_transport_offset(nskb) + tcp_hdrlen(nskb); ++ skb_offset = skb_tcp_all_headers(nskb); + data_len = nskb->len - skb_offset; + skb_tx_timestamp(nskb); + +@@ -1938,7 +1938,7 @@ static int chcr_ktls_xmit(struct sk_buff + unsigned long flags; + + tcp_seq = ntohl(th->seq); +- skb_offset = skb_transport_offset(skb) + tcp_hdrlen(skb); ++ skb_offset = skb_tcp_all_headers(skb); + skb_data_len = skb->len - skb_offset; + data_len = skb_data_len; + +--- a/drivers/net/ethernet/cisco/enic/enic_main.c ++++ b/drivers/net/ethernet/cisco/enic/enic_main.c +@@ -680,11 +680,10 @@ static int enic_queue_wq_skb_tso(struct + skb_frag_t *frag; + + if (skb->encapsulation) { +- hdr_len = skb_inner_transport_header(skb) - skb->data; +- hdr_len += inner_tcp_hdrlen(skb); ++ hdr_len = skb_inner_tcp_all_headers(skb); + enic_preload_tcp_csum_encap(skb); + } else { +- hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); ++ hdr_len = skb_tcp_all_headers(skb); + enic_preload_tcp_csum(skb); + } + +--- a/drivers/net/ethernet/emulex/benet/be_main.c ++++ b/drivers/net/ethernet/emulex/benet/be_main.c +@@ -737,9 +737,9 @@ void be_link_status_update(struct be_ada + static int be_gso_hdr_len(struct sk_buff *skb) + { + if (skb->encapsulation) +- return skb_inner_transport_offset(skb) + +- inner_tcp_hdrlen(skb); +- return skb_transport_offset(skb) + tcp_hdrlen(skb); ++ return skb_inner_tcp_all_headers(skb); ++ ++ return skb_tcp_all_headers(skb); + } + + static void be_tx_stats_update(struct be_tx_obj *txo, struct sk_buff *skb) +--- a/drivers/net/ethernet/freescale/fec_main.c ++++ b/drivers/net/ethernet/freescale/fec_main.c +@@ -661,7 +661,7 @@ fec_enet_txq_put_hdr_tso(struct fec_enet + struct bufdesc *bdp, int index) + { + struct fec_enet_private *fep = netdev_priv(ndev); +- int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); ++ int hdr_len = skb_tcp_all_headers(skb); + struct bufdesc_ex *ebdp = container_of(bdp, struct bufdesc_ex, desc); + void *bufaddr; + unsigned long dmabuf; +--- a/drivers/net/ethernet/google/gve/gve_tx_dqo.c ++++ b/drivers/net/ethernet/google/gve/gve_tx_dqo.c +@@ -386,7 +386,7 @@ static int gve_prep_tso(struct sk_buff * + (__force __wsum)htonl(paylen)); + + /* Compute length of segmentation header. */ +- header_len = skb_transport_offset(skb) + tcp_hdrlen(skb); ++ header_len = skb_tcp_all_headers(skb); + break; + default: + return -EINVAL; +@@ -598,9 +598,9 @@ static int gve_num_buffer_descs_needed(c + */ + static bool gve_can_send_tso(const struct sk_buff *skb) + { +- const int header_len = skb_checksum_start_offset(skb) + tcp_hdrlen(skb); + const int max_bufs_per_seg = GVE_TX_MAX_DATA_DESCS - 1; + const struct skb_shared_info *shinfo = skb_shinfo(skb); ++ const int header_len = skb_tcp_all_headers(skb); + const int gso_size = shinfo->gso_size; + int cur_seg_num_bufs; + int cur_seg_size; +--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c ++++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c +@@ -31,8 +31,6 @@ + #define HNS_BUFFER_SIZE_2048 2048 + + #define BD_MAX_SEND_SIZE 8191 +-#define SKB_TMP_LEN(SKB) \ +- (((SKB)->transport_header - (SKB)->mac_header) + tcp_hdrlen(SKB)) + + static void fill_v2_desc_hw(struct hnae_ring *ring, void *priv, int size, + int send_sz, dma_addr_t dma, int frag_end, +@@ -94,7 +92,7 @@ static void fill_v2_desc_hw(struct hnae_ + HNSV2_TXD_TSE_B, 1); + l4_len = tcp_hdrlen(skb); + mss = skb_shinfo(skb)->gso_size; +- paylen = skb->len - SKB_TMP_LEN(skb); ++ paylen = skb->len - skb_tcp_all_headers(skb); + } + } else if (skb->protocol == htons(ETH_P_IPV6)) { + hnae_set_bit(tvsvsn, HNSV2_TXD_IPV6_B, 1); +@@ -108,7 +106,7 @@ static void fill_v2_desc_hw(struct hnae_ + HNSV2_TXD_TSE_B, 1); + l4_len = tcp_hdrlen(skb); + mss = skb_shinfo(skb)->gso_size; +- paylen = skb->len - SKB_TMP_LEN(skb); ++ paylen = skb->len - skb_tcp_all_headers(skb); + } + } + desc->tx.ip_offset = ip_offset; +--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +@@ -1797,9 +1797,9 @@ static unsigned int hns3_tx_bd_num(struc + static unsigned int hns3_gso_hdr_len(struct sk_buff *skb) + { + if (!skb->encapsulation) +- return skb_transport_offset(skb) + tcp_hdrlen(skb); ++ return skb_tcp_all_headers(skb); + +- return skb_inner_transport_offset(skb) + inner_tcp_hdrlen(skb); ++ return skb_inner_tcp_all_headers(skb); + } + + /* HW need every continuous max_non_tso_bd_num buffer data to be larger +--- a/drivers/net/ethernet/hisilicon/hns3/hns3_trace.h ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_trace.h +@@ -37,8 +37,7 @@ DECLARE_EVENT_CLASS(hns3_skb_template, + __entry->gso_segs = skb_shinfo(skb)->gso_segs; + __entry->gso_type = skb_shinfo(skb)->gso_type; + __entry->hdr_len = skb->encapsulation ? +- skb_inner_transport_offset(skb) + inner_tcp_hdrlen(skb) : +- skb_transport_offset(skb) + tcp_hdrlen(skb); ++ skb_inner_tcp_all_headers(skb) : skb_tcp_all_headers(skb); + __entry->ip_summed = skb->ip_summed; + __entry->fraglist = skb_has_frag_list(skb); + hns3_shinfo_pack(skb_shinfo(skb), __entry->size); +--- a/drivers/net/ethernet/ibm/ehea/ehea_main.c ++++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c +@@ -1615,7 +1615,7 @@ static void write_swqe2_immediate(struct + * For TSO packets we only copy the headers into the + * immediate area. + */ +- immediate_len = ETH_HLEN + ip_hdrlen(skb) + tcp_hdrlen(skb); ++ immediate_len = skb_tcp_all_headers(skb); + } + + if (skb_is_gso(skb) || skb_data_size >= SWQE2_MAX_IMM) { +--- a/drivers/net/ethernet/intel/e1000/e1000_main.c ++++ b/drivers/net/ethernet/intel/e1000/e1000_main.c +@@ -2707,7 +2707,7 @@ static int e1000_tso(struct e1000_adapte + if (err < 0) + return err; + +- hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); ++ hdr_len = skb_tcp_all_headers(skb); + mss = skb_shinfo(skb)->gso_size; + if (protocol == htons(ETH_P_IP)) { + struct iphdr *iph = ip_hdr(skb); +@@ -3138,7 +3138,7 @@ static netdev_tx_t e1000_xmit_frame(stru + max_per_txd = min(mss << 2, max_per_txd); + max_txd_pwr = fls(max_per_txd) - 1; + +- hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); ++ hdr_len = skb_tcp_all_headers(skb); + if (skb->data_len && hdr_len == len) { + switch (hw->mac_type) { + case e1000_82544: { +--- a/drivers/net/ethernet/intel/e1000e/netdev.c ++++ b/drivers/net/ethernet/intel/e1000e/netdev.c +@@ -5478,7 +5478,7 @@ static int e1000_tso(struct e1000_ring * + if (err < 0) + return err; + +- hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); ++ hdr_len = skb_tcp_all_headers(skb); + mss = skb_shinfo(skb)->gso_size; + if (protocol == htons(ETH_P_IP)) { + struct iphdr *iph = ip_hdr(skb); +@@ -5850,7 +5850,7 @@ static netdev_tx_t e1000_xmit_frame(stru + * points to just header, pull a few bytes of payload from + * frags into skb->data + */ +- hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); ++ hdr_len = skb_tcp_all_headers(skb); + /* we do this workaround for ES2LAN, but it is un-necessary, + * avoiding it could save a lot of cycles + */ +--- a/drivers/net/ethernet/intel/ixgb/ixgb_main.c ++++ b/drivers/net/ethernet/intel/ixgb/ixgb_main.c +@@ -1196,7 +1196,7 @@ ixgb_tso(struct ixgb_adapter *adapter, s + if (err < 0) + return err; + +- hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); ++ hdr_len = skb_tcp_all_headers(skb); + mss = skb_shinfo(skb)->gso_size; + iph = ip_hdr(skb); + iph->tot_len = 0; +--- a/drivers/net/ethernet/marvell/mv643xx_eth.c ++++ b/drivers/net/ethernet/marvell/mv643xx_eth.c +@@ -775,7 +775,7 @@ txq_put_hdr_tso(struct sk_buff *skb, str + u32 *first_cmd_sts, bool first_desc) + { + struct mv643xx_eth_private *mp = txq_to_mp(txq); +- int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); ++ int hdr_len = skb_tcp_all_headers(skb); + int tx_index; + struct tx_desc *desc; + int ret; +--- a/drivers/net/ethernet/marvell/mvneta.c ++++ b/drivers/net/ethernet/marvell/mvneta.c +@@ -2598,8 +2598,8 @@ static inline void + mvneta_tso_put_hdr(struct sk_buff *skb, + struct mvneta_port *pp, struct mvneta_tx_queue *txq) + { +- int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); + struct mvneta_tx_buf *buf = &txq->buf[txq->txq_put_index]; ++ int hdr_len = skb_tcp_all_headers(skb); + struct mvneta_tx_desc *tx_desc; + + tx_desc = mvneta_txq_next_desc_get(txq); +@@ -2661,7 +2661,7 @@ static int mvneta_tx_tso(struct sk_buff + if ((txq->count + tso_count_descs(skb)) >= txq->size) + return 0; + +- if (skb_headlen(skb) < (skb_transport_offset(skb) + tcp_hdrlen(skb))) { ++ if (skb_headlen(skb) < skb_tcp_all_headers(skb)) { + pr_info("*** Is this even possible???!?!?\n"); + return 0; + } +--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c +@@ -624,7 +624,7 @@ static void otx2_sqe_add_ext(struct otx2 + ext->subdc = NIX_SUBDC_EXT; + if (skb_shinfo(skb)->gso_size) { + ext->lso = 1; +- ext->lso_sb = skb_transport_offset(skb) + tcp_hdrlen(skb); ++ ext->lso_sb = skb_tcp_all_headers(skb); + ext->lso_mps = skb_shinfo(skb)->gso_size; + + /* Only TSOv4 and TSOv6 GSO offloads are supported */ +@@ -931,7 +931,7 @@ static bool is_hw_tso_supported(struct o + * be correctly modified, hence don't offload such TSO segments. + */ + +- payload_len = skb->len - (skb_transport_offset(skb) + tcp_hdrlen(skb)); ++ payload_len = skb->len - skb_tcp_all_headers(skb); + last_seg_size = payload_len % skb_shinfo(skb)->gso_size; + if (last_seg_size && last_seg_size < 16) + return false; +--- a/drivers/net/ethernet/marvell/sky2.c ++++ b/drivers/net/ethernet/marvell/sky2.c +@@ -1864,7 +1864,7 @@ static netdev_tx_t sky2_xmit_frame(struc + if (mss != 0) { + + if (!(hw->flags & SKY2_HW_NEW_LE)) +- mss += ETH_HLEN + ip_hdrlen(skb) + tcp_hdrlen(skb); ++ mss += skb_tcp_all_headers(skb); + + if (mss != sky2->tx_last_mss) { + le = get_tx_le(sky2, &slot); +--- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c ++++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c +@@ -642,9 +642,9 @@ static int get_real_size(const struct sk + if (shinfo->gso_size) { + *inline_ok = false; + if (skb->encapsulation) +- *lso_header_size = (skb_inner_transport_header(skb) - skb->data) + inner_tcp_hdrlen(skb); ++ *lso_header_size = skb_inner_tcp_all_headers(skb); + else +- *lso_header_size = skb_transport_offset(skb) + tcp_hdrlen(skb); ++ *lso_header_size = skb_tcp_all_headers(skb); + real_size = CTRL_SIZE + shinfo->nr_frags * DS_SIZE + + ALIGN(*lso_header_size + 4, DS_SIZE); + if (unlikely(*lso_header_size != skb_headlen(skb))) { +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c +@@ -457,7 +457,7 @@ bool mlx5e_ktls_handle_tx_skb(struct net + int datalen; + u32 seq; + +- datalen = skb->len - (skb_transport_offset(skb) + tcp_hdrlen(skb)); ++ datalen = skb->len - skb_tcp_all_headers(skb); + if (!datalen) + return true; + +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c +@@ -137,14 +137,14 @@ mlx5e_tx_get_gso_ihs(struct mlx5e_txqsq + u16 ihs; + + if (skb->encapsulation) { +- ihs = skb_inner_transport_offset(skb) + inner_tcp_hdrlen(skb); ++ ihs = skb_tcp_all_headers(skb); + stats->tso_inner_packets++; + stats->tso_inner_bytes += skb->len - ihs; + } else { + if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4) + ihs = skb_transport_offset(skb) + sizeof(struct udphdr); + else +- ihs = skb_transport_offset(skb) + tcp_hdrlen(skb); ++ ihs = skb_tcp_all_headers(skb); + stats->tso_packets++; + stats->tso_bytes += skb->len - ihs; + } +--- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c ++++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c +@@ -2691,7 +2691,7 @@ again: + * send loop that we are still in the + * header portion of the TSO packet. + * TSO header can be at most 1KB long */ +- cum_len = -(skb_transport_offset(skb) + tcp_hdrlen(skb)); ++ cum_len = -skb_tcp_all_headers(skb); + + /* for IPv6 TSO, the checksum offset stores the + * TCP header length, to save the firmware from +--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c ++++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c +@@ -838,7 +838,7 @@ nfp_net_tls_tx(struct nfp_net_dp *dp, st + if (!skb->sk || !tls_is_sk_tx_device_offloaded(skb->sk)) + return skb; + +- datalen = skb->len - (skb_transport_offset(skb) + tcp_hdrlen(skb)); ++ datalen = skb->len - skb_tcp_all_headers(skb); + seq = ntohl(tcp_hdr(skb)->seq); + ntls = tls_driver_ctx(skb->sk, TLS_OFFLOAD_CTX_DIR_TX); + resync_pending = tls_offload_tx_resync_pending(skb->sk); +@@ -906,7 +906,7 @@ static void nfp_net_tls_tx_undo(struct s + if (WARN_ON_ONCE(!skb->sk || !tls_is_sk_tx_device_offloaded(skb->sk))) + return; + +- datalen = skb->len - (skb_transport_offset(skb) + tcp_hdrlen(skb)); ++ datalen = skb->len - skb_tcp_all_headers(skb); + seq = ntohl(tcp_hdr(skb)->seq); + + ntls = tls_driver_ctx(skb->sk, TLS_OFFLOAD_CTX_DIR_TX); +@@ -3499,8 +3499,7 @@ nfp_net_features_check(struct sk_buff *s + if (skb_is_gso(skb)) { + u32 hdrlen; + +- hdrlen = skb_inner_transport_header(skb) - skb->data + +- inner_tcp_hdrlen(skb); ++ hdrlen = skb_inner_tcp_all_headers(skb); + + /* Assume worst case scenario of having longest possible + * metadata prepend - 8B +--- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c ++++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c +@@ -948,10 +948,9 @@ static int ionic_tx_tso(struct ionic_que + } + + if (encap) +- hdrlen = skb_inner_transport_header(skb) - skb->data + +- inner_tcp_hdrlen(skb); ++ hdrlen = skb_inner_tcp_all_headers(skb); + else +- hdrlen = skb_transport_offset(skb) + tcp_hdrlen(skb); ++ hdrlen = skb_tcp_all_headers(skb); + + tso_rem = len; + seg_rem = min(tso_rem, hdrlen + mss); +--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c ++++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +@@ -1877,7 +1877,7 @@ netxen_tso_check(struct net_device *netd + if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) && + skb_shinfo(skb)->gso_size > 0) { + +- hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); ++ hdr_len = skb_tcp_all_headers(skb); + + first_desc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size); + first_desc->total_hdr_length = hdr_len; +--- a/drivers/net/ethernet/qlogic/qede/qede_fp.c ++++ b/drivers/net/ethernet/qlogic/qede/qede_fp.c +@@ -260,11 +260,9 @@ static int map_frag_to_bd(struct qede_tx + static u16 qede_get_skb_hlen(struct sk_buff *skb, bool is_encap_pkt) + { + if (is_encap_pkt) +- return (skb_inner_transport_header(skb) + +- inner_tcp_hdrlen(skb) - skb->data); +- else +- return (skb_transport_header(skb) + +- tcp_hdrlen(skb) - skb->data); ++ return skb_inner_tcp_all_headers(skb); ++ ++ return skb_tcp_all_headers(skb); + } + + /* +2 for 1st BD for headers and 2nd BD for headlen (if required) */ +--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c ++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c +@@ -497,7 +497,7 @@ set_flags: + } + opcode = QLCNIC_TX_ETHER_PKT; + if (skb_is_gso(skb)) { +- hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); ++ hdr_len = skb_tcp_all_headers(skb); + first_desc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size); + first_desc->hdr_length = hdr_len; + opcode = (protocol == ETH_P_IPV6) ? QLCNIC_TX_TCP_LSO6 : +--- a/drivers/net/ethernet/qualcomm/emac/emac-mac.c ++++ b/drivers/net/ethernet/qualcomm/emac/emac-mac.c +@@ -1264,7 +1264,7 @@ static int emac_tso_csum(struct emac_ada + pskb_trim(skb, pkt_len); + } + +- hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); ++ hdr_len = skb_tcp_all_headers(skb); + if (unlikely(skb->len == hdr_len)) { + /* we only need to do csum */ + netif_warn(adpt, tx_err, adpt->netdev, +@@ -1339,7 +1339,7 @@ static void emac_tx_fill_tpd(struct emac + + /* if Large Segment Offload is (in TCP Segmentation Offload struct) */ + if (TPD_LSO(tpd)) { +- mapped_len = skb_transport_offset(skb) + tcp_hdrlen(skb); ++ mapped_len = skb_tcp_all_headers(skb); + + tpbuf = GET_TPD_BUFFER(tx_q, tx_q->tpd.produce_idx); + tpbuf->length = mapped_len; +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -4014,7 +4014,7 @@ static netdev_tx_t stmmac_tso_xmit(struc + proto_hdr_len = skb_transport_offset(skb) + sizeof(struct udphdr); + hdr = sizeof(struct udphdr); + } else { +- proto_hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); ++ proto_hdr_len = skb_tcp_all_headers(skb); + hdr = tcp_hdrlen(skb); + } + +--- a/drivers/net/ethernet/synopsys/dwc-xlgmac-net.c ++++ b/drivers/net/ethernet/synopsys/dwc-xlgmac-net.c +@@ -81,7 +81,7 @@ static int xlgmac_prep_tso(struct sk_buf + if (ret) + return ret; + +- pkt_info->header_len = skb_transport_offset(skb) + tcp_hdrlen(skb); ++ pkt_info->header_len = skb_tcp_all_headers(skb); + pkt_info->tcp_header_len = tcp_hdrlen(skb); + pkt_info->tcp_payload_len = skb->len - pkt_info->header_len; + pkt_info->mss = skb_shinfo(skb)->gso_size; +--- a/drivers/net/wireless/ath/wil6210/txrx.c ++++ b/drivers/net/wireless/ath/wil6210/txrx.c +@@ -1782,9 +1782,7 @@ static int __wil_tx_vring_tso(struct wil + } + + /* Header Length = MAC header len + IP header len + TCP header len*/ +- hdrlen = ETH_HLEN + +- (int)skb_network_header_len(skb) + +- tcp_hdrlen(skb); ++ hdrlen = skb_tcp_all_headers(skb); + + gso_type = skb_shinfo(skb)->gso_type & (SKB_GSO_TCPV6 | SKB_GSO_TCPV4); + switch (gso_type) { +--- a/drivers/net/xen-netback/netback.c ++++ b/drivers/net/xen-netback/netback.c +@@ -1199,9 +1199,7 @@ static int xenvif_tx_submit(struct xenvi + } + + mss = skb_shinfo(skb)->gso_size; +- hdrlen = skb_transport_header(skb) - +- skb_mac_header(skb) + +- tcp_hdrlen(skb); ++ hdrlen = skb_tcp_all_headers(skb); + + skb_shinfo(skb)->gso_segs = + DIV_ROUND_UP(skb->len - hdrlen, mss); +--- a/drivers/staging/qlge/qlge_main.c ++++ b/drivers/staging/qlge/qlge_main.c +@@ -2461,7 +2461,7 @@ static int qlge_tso(struct sk_buff *skb, + mac_iocb_ptr->flags3 |= OB_MAC_TSO_IOCB_IC; + mac_iocb_ptr->frame_len = cpu_to_le32((u32)skb->len); + mac_iocb_ptr->total_hdrs_len = +- cpu_to_le16(skb_transport_offset(skb) + tcp_hdrlen(skb)); ++ cpu_to_le16(skb_tcp_all_headers(skb)); + mac_iocb_ptr->net_trans_offset = + cpu_to_le16(skb_network_offset(skb) | + skb_transport_offset(skb) +--- a/include/linux/tcp.h ++++ b/include/linux/tcp.h +@@ -46,6 +46,36 @@ static inline unsigned int inner_tcp_hdr + return inner_tcp_hdr(skb)->doff * 4; + } + ++/** ++ * skb_tcp_all_headers - Returns size of all headers for a TCP packet ++ * @skb: buffer ++ * ++ * Used in TX path, for a packet known to be a TCP one. ++ * ++ * if (skb_is_gso(skb)) { ++ * int hlen = skb_tcp_all_headers(skb); ++ * ... ++ */ ++static inline int skb_tcp_all_headers(const struct sk_buff *skb) ++{ ++ return skb_transport_offset(skb) + tcp_hdrlen(skb); ++} ++ ++/** ++ * skb_inner_tcp_all_headers - Returns size of all headers for an encap TCP packet ++ * @skb: buffer ++ * ++ * Used in TX path, for a packet known to be a TCP one. ++ * ++ * if (skb_is_gso(skb) && skb->encapsulation) { ++ * int hlen = skb_inner_tcp_all_headers(skb); ++ * ... ++ */ ++static inline int skb_inner_tcp_all_headers(const struct sk_buff *skb) ++{ ++ return skb_inner_transport_offset(skb) + inner_tcp_hdrlen(skb); ++} ++ + static inline unsigned int tcp_optlen(const struct sk_buff *skb) + { + return (tcp_hdr(skb)->doff - 5) * 4; +--- a/net/tls/tls_device_fallback.c ++++ b/net/tls/tls_device_fallback.c +@@ -232,7 +232,7 @@ static int fill_sg_in(struct scatterlist + s32 *sync_size, + int *resync_sgs) + { +- int tcp_payload_offset = skb_transport_offset(skb) + tcp_hdrlen(skb); ++ int tcp_payload_offset = skb_tcp_all_headers(skb); + int payload_len = skb->len - tcp_payload_offset; + u32 tcp_seq = ntohl(tcp_hdr(skb)->seq); + struct tls_record_info *record; +@@ -310,8 +310,8 @@ static struct sk_buff *tls_enc_skb(struc + struct sk_buff *skb, + s32 sync_size, u64 rcd_sn) + { +- int tcp_payload_offset = skb_transport_offset(skb) + tcp_hdrlen(skb); + struct tls_offload_context_tx *ctx = tls_offload_ctx_tx(tls_ctx); ++ int tcp_payload_offset = skb_tcp_all_headers(skb); + int payload_len = skb->len - tcp_payload_offset; + void *buf, *iv, *aad, *dummy_buf; + struct aead_request *aead_req; +@@ -372,7 +372,7 @@ free_nskb: + + static struct sk_buff *tls_sw_fallback(struct sock *sk, struct sk_buff *skb) + { +- int tcp_payload_offset = skb_transport_offset(skb) + tcp_hdrlen(skb); ++ int tcp_payload_offset = skb_tcp_all_headers(skb); + struct tls_context *tls_ctx = tls_get_ctx(sk); + struct tls_offload_context_tx *ctx = tls_offload_ctx_tx(tls_ctx); + int payload_len = skb->len - tcp_payload_offset; diff --git a/patches.suse/net-altera-Fix-refcount-leak-in-altera_tse_mdio_crea.patch b/patches.suse/net-altera-Fix-refcount-leak-in-altera_tse_mdio_crea.patch new file mode 100644 index 0000000..2aa0b61 --- /dev/null +++ b/patches.suse/net-altera-Fix-refcount-leak-in-altera_tse_mdio_crea.patch @@ -0,0 +1,59 @@ +From c4b6e2befc37c2840ba1b2d451f3fb92163d5bff Mon Sep 17 00:00:00 2001 +From: Miaoqian Lin +Date: Tue, 7 Jun 2022 08:11:43 +0400 +Subject: [PATCH 13/32] net: altera: Fix refcount leak in + altera_tse_mdio_create +Git-commit: 11ec18b1d8d92b9df307d31950dcba0b3dd7283c +References: git-fixes +Patch-mainline: v5.19-rc2 + +Every iteration of for_each_child_of_node() decrements +the reference count of the previous node. +When break from a for_each_child_of_node() loop, +we need to explicitly call of_node_put() on the child node when +not need anymore. +Add missing of_node_put() to avoid refcount leak. + +Fixes: bbd2190ce96d ("Altera TSE: Add main and header file for Altera Ethernet Driver") +Signed-off-by: Miaoqian Lin +Link: https://lore.kernel.org/r/20220607041144.7553-1-linmq006@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/altera/altera_tse_main.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/altera/altera_tse_main.c b/drivers/net/ethernet/altera/altera_tse_main.c +index 804b37c76b1e..b51f5b9577e0 100644 +--- a/drivers/net/ethernet/altera/altera_tse_main.c ++++ b/drivers/net/ethernet/altera/altera_tse_main.c +@@ -163,7 +163,8 @@ static int altera_tse_mdio_create(struct net_device *dev, unsigned int id) + mdio = mdiobus_alloc(); + if (mdio == NULL) { + netdev_err(dev, "Error allocating MDIO bus\n"); +- return -ENOMEM; ++ ret = -ENOMEM; ++ goto put_node; + } + + mdio->name = ALTERA_TSE_RESOURCE_NAME; +@@ -180,6 +181,7 @@ static int altera_tse_mdio_create(struct net_device *dev, unsigned int id) + mdio->id); + goto out_free_mdio; + } ++ of_node_put(mdio_node); + + if (netif_msg_drv(priv)) + netdev_info(dev, "MDIO bus %s: created\n", mdio->id); +@@ -189,6 +191,8 @@ static int altera_tse_mdio_create(struct net_device *dev, unsigned int id) + out_free_mdio: + mdiobus_free(mdio); + mdio = NULL; ++put_node: ++ of_node_put(mdio_node); + return ret; + } + +-- +2.16.4 + diff --git a/patches.suse/net-bgmac-Fix-an-erroneous-kfree-in-bgmac_remove.patch b/patches.suse/net-bgmac-Fix-an-erroneous-kfree-in-bgmac_remove.patch new file mode 100644 index 0000000..315595d --- /dev/null +++ b/patches.suse/net-bgmac-Fix-an-erroneous-kfree-in-bgmac_remove.patch @@ -0,0 +1,38 @@ +From 34d519d9a034af1163004d33f8fc744d0f070a77 Mon Sep 17 00:00:00 2001 +From: Christophe JAILLET +Date: Mon, 13 Jun 2022 22:53:50 +0200 +Subject: [PATCH 21/32] net: bgmac: Fix an erroneous kfree() in bgmac_remove() +Git-commit: d7dd6eccfbc95ac47a12396f84e7e1b361db654b +References: git-fixes +Patch-mainline: v5.19-rc3 + +'bgmac' is part of a managed resource allocated with bgmac_alloc(). It +should not be freed explicitly. + +Remove the erroneous kfree() from the .remove() function. + +Fixes: 34a5102c3235 ("net: bgmac: allocate struct bgmac just once & don't copy it") +Signed-off-by: Christophe JAILLET +Reviewed-by: Florian Fainelli +Link: https://lore.kernel.org/r/a026153108dd21239036a032b95c25b5cece253b.1655153616.git.christophe.jaillet@wanadoo.fr +Signed-off-by: Jakub Kicinski +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/broadcom/bgmac-bcma.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/net/ethernet/broadcom/bgmac-bcma.c b/drivers/net/ethernet/broadcom/bgmac-bcma.c +index 28759062d68d..b9e1b76f1823 100644 +--- a/drivers/net/ethernet/broadcom/bgmac-bcma.c ++++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c +@@ -323,7 +323,6 @@ static void bgmac_remove(struct bcma_device *core) + bcma_mdio_mii_unregister(bgmac->mii_bus); + bgmac_enet_remove(bgmac); + bcma_set_drvdata(core, NULL); +- kfree(bgmac); + } + + static struct bcma_driver bgmac_bcma_driver = { +-- +2.16.4 + diff --git a/patches.suse/net-bgmac-support-MDIO-described-in-DT.patch b/patches.suse/net-bgmac-support-MDIO-described-in-DT.patch new file mode 100644 index 0000000..e899c86 --- /dev/null +++ b/patches.suse/net-bgmac-support-MDIO-described-in-DT.patch @@ -0,0 +1,60 @@ +From 8b3856ccc80c75f4cc1b603f8623a9586e31219d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Sat, 2 Oct 2021 19:58:12 +0200 +Subject: [PATCH 08/32] net: bgmac: support MDIO described in DT +Git-commit: 45c9d966688e7fad7f24bfc450547d91e4304d0b +References: git-fixes +Patch-mainline: v5.16-rc1 + +Check ethernet controller DT node for "mdio" subnode and use it with +of_mdiobus_register() when present. That allows specifying MDIO and its +PHY devices in a standard DT based way. + +This is required for BCM53573 SoC support. That family is sometimes +called Northstar (by marketing?) but is quite different from it. It uses +different CPU(s) and many different hw blocks. + +One of shared blocks in BCM53573 is Ethernet controller. Switch however +is not SRAB accessible (as it Northstar) but is MDIO attached. + +Signed-off-by: Rafał Miłecki +Signed-off-by: David S. Miller +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c b/drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c +index 6ce80cbcb48e..086739e4f40a 100644 +--- a/drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c ++++ b/drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c +@@ -10,6 +10,7 @@ + + #include + #include ++#include + #include "bgmac.h" + + static bool bcma_mdio_wait_value(struct bcma_device *core, u16 reg, u32 mask, +@@ -211,6 +212,7 @@ struct mii_bus *bcma_mdio_mii_register(struct bgmac *bgmac) + { + struct bcma_device *core = bgmac->bcma.core; + struct mii_bus *mii_bus; ++ struct device_node *np; + int err; + + mii_bus = mdiobus_alloc(); +@@ -229,7 +231,9 @@ struct mii_bus *bcma_mdio_mii_register(struct bgmac *bgmac) + mii_bus->parent = &core->dev; + mii_bus->phy_mask = ~(1 << bgmac->phyaddr); + +- err = mdiobus_register(mii_bus); ++ np = of_get_child_by_name(core->dev.of_node, "mdio"); ++ ++ err = of_mdiobus_register(mii_bus, np); + if (err) { + dev_err(&core->dev, "Registration of mii bus failed\n"); + goto err_free_bus; +-- +2.16.4 + diff --git a/patches.suse/net-bonding-fix-possible-NULL-deref-in-rlb-code.patch b/patches.suse/net-bonding-fix-possible-NULL-deref-in-rlb-code.patch new file mode 100644 index 0000000..01abfb6 --- /dev/null +++ b/patches.suse/net-bonding-fix-possible-NULL-deref-in-rlb-code.patch @@ -0,0 +1,144 @@ +From 5d37d7b20bcab6db50e19290587824ae848916b4 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Mon, 27 Jun 2022 10:28:13 +0000 +Subject: [PATCH 30/32] net: bonding: fix possible NULL deref in rlb code +Git-commit: ab84db251c04d38b8dc7ee86e13d4050bedb1c88 +References: git-fixes +Patch-mainline: v5.19-rc5 + +syzbot has two reports involving the same root cause. + +bond_alb_initialize() must not set bond->alb_info.rlb_enabled +if a memory allocation error is detected. + +Report 1: + +general protection fault, probably for non-canonical address 0xdffffc0000000002: 0000 [#1] PREEMPT SMP KASAN +KASAN: null-ptr-deref in range [0x0000000000000010-0x0000000000000017] +CPU: 0 PID: 12276 Comm: kworker/u4:10 Not tainted 5.19.0-rc3-syzkaller-00132-g3b89b511ea0c #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +Workqueue: netns cleanup_net +RIP: 0010:rlb_clear_slave+0x10e/0x690 drivers/net/bonding/bond_alb.c:393 +Code: 8e fc 83 fb ff 0f 84 74 02 00 00 e8 cc 2a 8e fc 48 8b 44 24 08 89 dd 48 c1 e5 06 4c 8d 34 28 49 8d 7e 14 48 89 f8 48 c1 e8 03 <42> 0f b6 14 20 48 89 f8 83 e0 07 83 c0 03 38 d0 7c 08 84 d2 0f 85 +RSP: 0018:ffffc90018a8f678 EFLAGS: 00010203 +RAX: 0000000000000002 RBX: 0000000000000000 RCX: 0000000000000000 +RDX: ffff88803375bb00 RSI: ffffffff84ec4ac4 RDI: 0000000000000014 +RBP: 0000000000000000 R08: 0000000000000005 R09: 00000000ffffffff +R10: 0000000000000000 R11: 0000000000000000 R12: dffffc0000000000 +R13: ffff8880ac889000 R14: 0000000000000000 R15: ffff88815a668c80 +FS: 0000000000000000(0000) GS:ffff8880b9a00000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00005597077e10b0 CR3: 0000000026668000 CR4: 00000000003506f0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +Call Trace: + +bond_alb_deinit_slave+0x43c/0x6b0 drivers/net/bonding/bond_alb.c:1663 +__bond_release_one.cold+0x383/0xd53 drivers/net/bonding/bond_main.c:2370 +bond_slave_netdev_event drivers/net/bonding/bond_main.c:3778 [inline] +bond_netdev_event+0x993/0xad0 drivers/net/bonding/bond_main.c:3889 +notifier_call_chain+0xb5/0x200 kernel/notifier.c:87 +call_netdevice_notifiers_info+0xb5/0x130 net/core/dev.c:1945 +call_netdevice_notifiers_extack net/core/dev.c:1983 [inline] +call_netdevice_notifiers net/core/dev.c:1997 [inline] +unregister_netdevice_many+0x948/0x18b0 net/core/dev.c:10839 +default_device_exit_batch+0x449/0x590 net/core/dev.c:11333 +ops_exit_list+0x125/0x170 net/core/net_namespace.c:167 +cleanup_net+0x4ea/0xb00 net/core/net_namespace.c:594 +process_one_work+0x996/0x1610 kernel/workqueue.c:2289 +worker_thread+0x665/0x1080 kernel/workqueue.c:2436 +kthread+0x2e9/0x3a0 kernel/kthread.c:376 +ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:302 + + +Report 2: + +general protection fault, probably for non-canonical address 0xdffffc0000000006: 0000 [#1] PREEMPT SMP KASAN +KASAN: null-ptr-deref in range [0x0000000000000030-0x0000000000000037] +CPU: 1 PID: 5206 Comm: syz-executor.1 Not tainted 5.18.0-syzkaller-12108-g58f9d52ff689 #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +RIP: 0010:rlb_req_update_slave_clients+0x109/0x2f0 drivers/net/bonding/bond_alb.c:502 +Code: 5d 18 8f fc 41 80 3e 00 0f 85 a5 01 00 00 89 d8 48 c1 e0 06 49 03 84 24 68 01 00 00 48 8d 78 30 49 89 c7 48 89 fa 48 c1 ea 03 <80> 3c 2a 00 0f 85 98 01 00 00 4d 39 6f 30 75 83 e8 22 18 8f fc 49 +RSP: 0018:ffffc9000300ee80 EFLAGS: 00010206 +RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffc90016c11000 +RDX: 0000000000000006 RSI: ffffffff84eb6bf3 RDI: 0000000000000030 +RBP: dffffc0000000000 R08: 0000000000000005 R09: 00000000ffffffff +R10: 0000000000000000 R11: 0000000000000000 R12: ffff888027c80c80 +R13: ffff88807d7ff800 R14: ffffed1004f901bd R15: 0000000000000000 +FS: 00007f6f46c58700(0000) GS:ffff8880b9b00000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 0000000020010000 CR3: 00000000516cc000 CR4: 00000000003506e0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +Call Trace: + + alb_fasten_mac_swap+0x886/0xa80 drivers/net/bonding/bond_alb.c:1070 + bond_alb_handle_active_change+0x624/0x1050 drivers/net/bonding/bond_alb.c:1765 + bond_change_active_slave+0xfa1/0x29b0 drivers/net/bonding/bond_main.c:1173 + bond_select_active_slave+0x23f/0xa50 drivers/net/bonding/bond_main.c:1253 + bond_enslave+0x3b34/0x53b0 drivers/net/bonding/bond_main.c:2159 + do_set_master+0x1c8/0x220 net/core/rtnetlink.c:2577 + rtnl_newlink_create net/core/rtnetlink.c:3380 [inline] + __rtnl_newlink+0x13ac/0x17e0 net/core/rtnetlink.c:3580 + rtnl_newlink+0x64/0xa0 net/core/rtnetlink.c:3593 + rtnetlink_rcv_msg+0x43a/0xc90 net/core/rtnetlink.c:6089 + netlink_rcv_skb+0x153/0x420 net/netlink/af_netlink.c:2501 + netlink_unicast_kernel net/netlink/af_netlink.c:1319 [inline] + netlink_unicast+0x543/0x7f0 net/netlink/af_netlink.c:1345 + netlink_sendmsg+0x917/0xe10 net/netlink/af_netlink.c:1921 + sock_sendmsg_nosec net/socket.c:714 [inline] + sock_sendmsg+0xcf/0x120 net/socket.c:734 + ____sys_sendmsg+0x6eb/0x810 net/socket.c:2492 + ___sys_sendmsg+0xf3/0x170 net/socket.c:2546 + __sys_sendmsg net/socket.c:2575 [inline] + __do_sys_sendmsg net/socket.c:2584 [inline] + __se_sys_sendmsg net/socket.c:2582 [inline] + __x64_sys_sendmsg+0x132/0x220 net/socket.c:2582 + do_syscall_x64 arch/x86/entry/common.c:50 [inline] + do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80 + entry_SYSCALL_64_after_hwframe+0x46/0xb0 +RIP: 0033:0x7f6f45a89109 +Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48 +RSP: 002b:00007f6f46c58168 EFLAGS: 00000246 ORIG_RAX: 000000000000002e +RAX: ffffffffffffffda RBX: 00007f6f45b9c030 RCX: 00007f6f45a89109 +RDX: 0000000000000000 RSI: 0000000020000080 RDI: 0000000000000006 +RBP: 00007f6f45ae308d R08: 0000000000000000 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 +R13: 00007ffed99029af R14: 00007f6f46c58300 R15: 0000000000022000 + + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reported-by: syzbot +Signed-off-by: Eric Dumazet +Cc: Jay Vosburgh +Cc: Veaceslav Falico +Cc: Andy Gospodarek +Acked-by: Jay Vosburgh +Link: https://lore.kernel.org/r/20220627102813.126264-1-edumazet@google.com +Signed-off-by: Paolo Abeni +Signed-off-by: Denis Kirjanov +--- + drivers/net/bonding/bond_alb.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c +index 866cd72f5279..0f9ebb1bad4b 100644 +--- a/drivers/net/bonding/bond_alb.c ++++ b/drivers/net/bonding/bond_alb.c +@@ -1282,12 +1282,12 @@ int bond_alb_initialize(struct bonding *bond, int rlb_enabled) + return res; + + if (rlb_enabled) { +- bond->alb_info.rlb_enabled = 1; + res = rlb_initialize(bond); + if (res) { + tlb_deinitialize(bond); + return res; + } ++ bond->alb_info.rlb_enabled = 1; + } else { + bond->alb_info.rlb_enabled = 0; + } +-- +2.16.4 + diff --git a/patches.suse/net-bonding-fix-use-after-free-after-802.3ad-slave-u.patch b/patches.suse/net-bonding-fix-use-after-free-after-802.3ad-slave-u.patch new file mode 100644 index 0000000..c39ca5c --- /dev/null +++ b/patches.suse/net-bonding-fix-use-after-free-after-802.3ad-slave-u.patch @@ -0,0 +1,68 @@ +From 1fbe8ff1af2063b1d416d904855aba4ca61a2348 Mon Sep 17 00:00:00 2001 +From: Yevhen Orlov +Date: Wed, 29 Jun 2022 04:29:14 +0300 +Subject: [PATCH 31/32] net: bonding: fix use-after-free after 802.3ad slave + unbind +Git-commit: 050133e1aa2cb49bb17be847d48a4431598ef562 +References: git-fixes +Patch-mainline: v5.19-rc5 + +commit 0622cab0341c ("bonding: fix 802.3ad aggregator reselection"), +resolve case, when there is several aggregation groups in the same bond. +bond_3ad_unbind_slave will invalidate (clear) aggregator when +__agg_active_ports return zero. So, ad_clear_agg can be executed even, when +num_of_ports!=0. Than bond_3ad_unbind_slave can be executed again for, +previously cleared aggregator. NOTE: at this time bond_3ad_unbind_slave +will not update slave ports list, because lag_ports==NULL. So, here we +got slave ports, pointing to freed aggregator memory. + +Fix with checking actual number of ports in group (as was before +commit 0622cab0341c ("bonding: fix 802.3ad aggregator reselection") ), +before ad_clear_agg(). + +The KASAN logs are as follows: + +[ 767.617392] ================================================================== +[ 767.630776] BUG: KASAN: use-after-free in bond_3ad_state_machine_handler+0x13dc/0x1470 +[ 767.638764] Read of size 2 at addr ffff00011ba9d430 by task kworker/u8:7/767 +[ 767.647361] CPU: 3 PID: 767 Comm: kworker/u8:7 Tainted: G O 5.15.11 #15 +[ 767.655329] Hardware name: DNI AmazonGo1 A7040 board (DT) +[ 767.660760] Workqueue: lacp_1 bond_3ad_state_machine_handler +[ 767.666468] Call trace: +[ 767.668930] dump_backtrace+0x0/0x2d0 +[ 767.672625] show_stack+0x24/0x30 +[ 767.675965] dump_stack_lvl+0x68/0x84 +[ 767.679659] print_address_description.constprop.0+0x74/0x2b8 +[ 767.685451] kasan_report+0x1f0/0x260 +[ 767.689148] __asan_load2+0x94/0xd0 +[ 767.692667] bond_3ad_state_machine_handler+0x13dc/0x1470 + +Fixes: 0622cab0341c ("bonding: fix 802.3ad aggregator reselection") +Co-developed-by: Maksym Glubokiy +Signed-off-by: Maksym Glubokiy +Signed-off-by: Yevhen Orlov +Acked-by: Jay Vosburgh +Link: https://lore.kernel.org/r/20220629012914.361-1-yevhen.orlov@plvision.eu +Signed-off-by: Jakub Kicinski +Signed-off-by: Denis Kirjanov +--- + drivers/net/bonding/bond_3ad.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c +index c0172c09c90a..7ba2d0aae61b 100644 +--- a/drivers/net/bonding/bond_3ad.c ++++ b/drivers/net/bonding/bond_3ad.c +@@ -2227,7 +2227,8 @@ void bond_3ad_unbind_slave(struct slave *slave) + temp_aggregator->num_of_ports--; + if (__agg_active_ports(temp_aggregator) == 0) { + select_new_active_agg = temp_aggregator->is_active; +- ad_clear_agg(temp_aggregator); ++ if (temp_aggregator->num_of_ports == 0) ++ ad_clear_agg(temp_aggregator); + if (select_new_active_agg) { + slave_info(bond->dev, slave->dev, "Removing an active aggregator\n"); + /* select new active aggregator */ +-- +2.16.4 + diff --git a/patches.suse/net-delete-redundant-function-declaration.patch b/patches.suse/net-delete-redundant-function-declaration.patch new file mode 100644 index 0000000..ec8bade --- /dev/null +++ b/patches.suse/net-delete-redundant-function-declaration.patch @@ -0,0 +1,38 @@ +From 9974cb5c879048f5144d0660c4932d98176213c4 Mon Sep 17 00:00:00 2001 +From: Chen Wandun +Date: Wed, 13 Oct 2021 17:47:02 +0800 +Subject: [PATCH] net: delete redundant function declaration +Git-commit: 9974cb5c879048f5144d0660c4932d98176213c4 +References: git-fixes +Patch-mainline: v5.16-rc1 + +The implement of function netdev_all_upper_get_next_dev_rcu has been +removed in: + commit f1170fd462c6 ("net: Remove all_adj_list and its references") +so delete redundant declaration in header file. + +Fixes: f1170fd462c6 ("net: Remove all_adj_list and its references") +Signed-off-by: Chen Wandun +Link: https://lore.kernel.org/r/20211013094702.3931071-1-chenwandun@huawei.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Oliver Neukum +--- + include/linux/netdevice.h | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h +index f33af341bfb2..173984414f38 100644 +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -4801,8 +4801,6 @@ struct netdev_nested_priv { + bool netdev_has_upper_dev(struct net_device *dev, struct net_device *upper_dev); + struct net_device *netdev_upper_get_next_dev_rcu(struct net_device *dev, + struct list_head **iter); +-struct net_device *netdev_all_upper_get_next_dev_rcu(struct net_device *dev, +- struct list_head **iter); + + #ifdef CONFIG_LOCKDEP + static LIST_HEAD(net_unlink_list); +-- +2.35.3 + diff --git a/patches.suse/net-dp83822-disable-false-carrier-interrupt.patch b/patches.suse/net-dp83822-disable-false-carrier-interrupt.patch new file mode 100644 index 0000000..e90213e --- /dev/null +++ b/patches.suse/net-dp83822-disable-false-carrier-interrupt.patch @@ -0,0 +1,45 @@ +From da6b39a0db2e7e25affebc10cdd72c680c50d64f Mon Sep 17 00:00:00 2001 +From: Enguerrand de Ribaucourt +Date: Thu, 23 Jun 2022 15:46:44 +0200 +Subject: [PATCH 28/32] net: dp83822: disable false carrier interrupt +Git-commit: c96614eeab663646f57f67aa591e015abd8bd0ba +References: git-fixes +Patch-mainline: v5.19-rc5 + +When unplugging an Ethernet cable, false carrier events were produced by +the PHY at a very high rate. Once the false carrier counter full, an +interrupt was triggered every few clock cycles until the cable was +replugged. This resulted in approximately 10k/s interrupts. + +Since the false carrier counter (FCSCR) is never used, we can safely +disable this interrupt. + +In addition to improving performance, this also solved MDIO read +timeouts I was randomly encountering with an i.MX8 fec MAC because of +the interrupt flood. The interrupt count and MDIO timeout fix were +tested on a v5.4.110 kernel. + +Fixes: 87461f7a58ab ("net: phy: DP83822 initial driver submission") +Signed-off-by: Enguerrand de Ribaucourt +Reviewed-by: Andrew Lunn +Signed-off-by: Jakub Kicinski +Signed-off-by: Denis Kirjanov +--- + drivers/net/phy/dp83822.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/net/phy/dp83822.c b/drivers/net/phy/dp83822.c +index ce17b2af3218..ab13699c20bc 100644 +--- a/drivers/net/phy/dp83822.c ++++ b/drivers/net/phy/dp83822.c +@@ -229,7 +229,6 @@ static int dp83822_config_intr(struct phy_device *phydev) + return misr_status; + + misr_status |= (DP83822_RX_ERR_HF_INT_EN | +- DP83822_FALSE_CARRIER_HF_INT_EN | + DP83822_LINK_STAT_INT_EN | + DP83822_ENERGY_DET_INT_EN | + DP83822_LINK_QUAL_INT_EN); +-- +2.16.4 + diff --git a/patches.suse/net-dp83822-disable-rx-error-interrupt.patch b/patches.suse/net-dp83822-disable-rx-error-interrupt.patch new file mode 100644 index 0000000..8598ed2 --- /dev/null +++ b/patches.suse/net-dp83822-disable-rx-error-interrupt.patch @@ -0,0 +1,42 @@ +From 33d98c68503e633501562fcc4fdb8b3cccc5f06a Mon Sep 17 00:00:00 2001 +From: Enguerrand de Ribaucourt +Date: Thu, 23 Jun 2022 15:46:45 +0200 +Subject: [PATCH 29/32] net: dp83822: disable rx error interrupt +Git-commit: 0e597e2affb90d6ea48df6890d882924acf71e19 +References: git-fixes +Patch-mainline: v5.19-rc5 + +Some RX errors, notably when disconnecting the cable, increase the RCSR +register. Once half full (0x7fff), an interrupt flood is generated. I +measured ~3k/s interrupts even after the RX errors transfer was +stopped. + +Since we don't read and clear the RCSR register, we should disable this +interrupt. + +Fixes: 87461f7a58ab ("net: phy: DP83822 initial driver submission") +Signed-off-by: Enguerrand de Ribaucourt +Reviewed-by: Andrew Lunn +Signed-off-by: Jakub Kicinski +Signed-off-by: Denis Kirjanov +--- + drivers/net/phy/dp83822.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/net/phy/dp83822.c b/drivers/net/phy/dp83822.c +index ab13699c20bc..a792dd6d2ec3 100644 +--- a/drivers/net/phy/dp83822.c ++++ b/drivers/net/phy/dp83822.c +@@ -228,8 +228,7 @@ static int dp83822_config_intr(struct phy_device *phydev) + if (misr_status < 0) + return misr_status; + +- misr_status |= (DP83822_RX_ERR_HF_INT_EN | +- DP83822_LINK_STAT_INT_EN | ++ misr_status |= (DP83822_LINK_STAT_INT_EN | + DP83822_ENERGY_DET_INT_EN | + DP83822_LINK_QUAL_INT_EN); + +-- +2.16.4 + diff --git a/patches.suse/net-dsa-bcm_sf2-force-pause-link-settings.patch b/patches.suse/net-dsa-bcm_sf2-force-pause-link-settings.patch new file mode 100644 index 0000000..dd38cf7 --- /dev/null +++ b/patches.suse/net-dsa-bcm_sf2-force-pause-link-settings.patch @@ -0,0 +1,41 @@ +From 7a5da0873a7f0bbe99efba75541f38624d7da987 Mon Sep 17 00:00:00 2001 +From: Doug Berger +Date: Wed, 22 Jun 2022 20:02:04 -0700 +Subject: [PATCH 27/32] net: dsa: bcm_sf2: force pause link settings +Git-commit: 7c97bc0128b2eecc703106112679a69d446d1a12 +References: git-fixes +Patch-mainline: v5.19-rc5 + +The pause settings reported by the PHY should also be applied to the GMII port +status override otherwise the switch will not generate pause frames towards the +link partner despite the advertisement saying otherwise. + +Fixes: 246d7f773c13 ("net: dsa: add Broadcom SF2 switch driver") +Signed-off-by: Doug Berger +Signed-off-by: Florian Fainelli +Link: https://lore.kernel.org/r/20220623030204.1966851-1-f.fainelli@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Denis Kirjanov +--- + drivers/net/dsa/bcm_sf2.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c +index b3a43a3d90e4..d76b2377d66e 100644 +--- a/drivers/net/dsa/bcm_sf2.c ++++ b/drivers/net/dsa/bcm_sf2.c +@@ -865,6 +865,11 @@ static void bcm_sf2_sw_mac_link_up(struct dsa_switch *ds, int port, + if (duplex == DUPLEX_FULL) + reg |= DUPLX_MODE; + ++ if (tx_pause) ++ reg |= TXFLOW_CNTL; ++ if (rx_pause) ++ reg |= RXFLOW_CNTL; ++ + core_writel(priv, reg, offset); + } + +-- +2.16.4 + diff --git a/patches.suse/net-dsa-felix-fix-tagging-protocol-changes-with-mult.patch b/patches.suse/net-dsa-felix-fix-tagging-protocol-changes-with-mult.patch new file mode 100644 index 0000000..9ed1be4 --- /dev/null +++ b/patches.suse/net-dsa-felix-fix-tagging-protocol-changes-with-mult.patch @@ -0,0 +1,87 @@ +From cb28852efade2b14ae5ca539aa8b9164402c9c25 Mon Sep 17 00:00:00 2001 +From: Vladimir Oltean +Date: Tue, 12 Apr 2022 20:22:09 +0300 +Subject: [PATCH 07/19] net: dsa: felix: fix tagging protocol changes with + multiple CPU ports +Git-commit: 00fa91bc9cc2a9d340f963af5e457610ad4b2f9c +Patch-mainline: v5.18-rc3 +References: git-fixes + +When the device tree has 2 CPU ports defined, a single one is active +(has any dp->cpu_dp pointers point to it). Yet the second one is still a +CPU port, and DSA still calls ->change_tag_protocol on it. + +On the NXP LS1028A, the CPU ports are ports 4 and 5. Port 4 is the +active CPU port and port 5 is inactive. + +After the following commands: + + # Initial setting + cat /sys/class/net/eno2/dsa/tagging + ocelot + echo ocelot-8021q > /sys/class/net/eno2/dsa/tagging + echo ocelot > /sys/class/net/eno2/dsa/tagging + +traffic is now broken, because the driver has moved the NPI port from +port 4 to port 5, unbeknown to DSA. + +The problem can be avoided by detecting that the second CPU port is +unused, and not doing anything for it. Further rework will be needed +when proper support for multiple CPU ports is added. + +Treat this as a bug and prepare current kernels to work in single-CPU +mode with multiple-CPU DT blobs. + +Fixes: adb3dccf090b ("net: dsa: felix: convert to the new .change_tag_protocol DSA API") +Signed-off-by: Vladimir Oltean +Link: https://lore.kernel.org/r/20220412172209.2531865-1-vladimir.oltean@nxp.com +Signed-off-by: Paolo Abeni +Signed-off-by: Denis Kirjanov +--- + drivers/net/dsa/ocelot/felix.c | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c +index 6d930e582283..b03ef5f147a2 100644 +--- a/drivers/net/dsa/ocelot/felix.c ++++ b/drivers/net/dsa/ocelot/felix.c +@@ -612,6 +612,8 @@ static int felix_change_tag_protocol(struct dsa_switch *ds, int cpu, + struct ocelot *ocelot = ds->priv; + struct felix *felix = ocelot_to_felix(ocelot); + enum dsa_tag_protocol old_proto = felix->tag_proto; ++ bool cpu_port_active = false; ++ struct dsa_port *dp; + int err; + + if (proto != DSA_TAG_PROTO_SEVILLE && +@@ -619,6 +621,27 @@ static int felix_change_tag_protocol(struct dsa_switch *ds, int cpu, + proto != DSA_TAG_PROTO_OCELOT_8021Q) + return -EPROTONOSUPPORT; + ++ /* We don't support multiple CPU ports, yet the DT blob may have ++ * multiple CPU ports defined. The first CPU port is the active one, ++ * the others are inactive. In this case, DSA will call ++ * ->change_tag_protocol() multiple times, once per CPU port. ++ * Since we implement the tagging protocol change towards "ocelot" or ++ * "seville" as effectively initializing the NPI port, what we are ++ * doing is effectively changing who the NPI port is to the last @cpu ++ * argument passed, which is an unused DSA CPU port and not the one ++ * that should actively pass traffic. ++ * Suppress DSA's calls on CPU ports that are inactive. ++ */ ++ dsa_switch_for_each_user_port(dp, ds) { ++ if (dp->cpu_dp->index == cpu) { ++ cpu_port_active = true; ++ break; ++ } ++ } ++ ++ if (!cpu_port_active) ++ return 0; ++ + felix_del_tag_protocol(ds, cpu, old_proto); + + err = felix_set_tag_protocol(ds, cpu, proto); +-- +2.16.4 + diff --git a/patches.suse/net-dsa-hirschmann-Add-missing-of_node_get-in-hellcr.patch b/patches.suse/net-dsa-hirschmann-Add-missing-of_node_get-in-hellcr.patch new file mode 100644 index 0000000..7df1c4d --- /dev/null +++ b/patches.suse/net-dsa-hirschmann-Add-missing-of_node_get-in-hellcr.patch @@ -0,0 +1,36 @@ +From a06bb5f266bb8c66944e3c080eb30671e414f849 Mon Sep 17 00:00:00 2001 +From: Liang He +Date: Wed, 22 Jun 2022 12:06:21 +0800 +Subject: [PATCH 26/32] net/dsa/hirschmann: Add missing of_node_get() in + hellcreek_led_setup() +Git-commit: 16d584d2fc8f4ea36203af45a76becd7093586f1 +References: git-fixes +Patch-mainline: v5.19-rc5 + +of_find_node_by_name() will decrease the refcount of its first arg and +we need a of_node_get() to keep refcount balance. + +Fixes: 7d9ee2e8ff15 ("net: dsa: hellcreek: Add PTP status LEDs") +Signed-off-by: Liang He +Link: https://lore.kernel.org/r/20220622040621.4094304-1-windhl@126.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Denis Kirjanov +--- + drivers/net/dsa/hirschmann/hellcreek_ptp.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/dsa/hirschmann/hellcreek_ptp.c b/drivers/net/dsa/hirschmann/hellcreek_ptp.c +index 2572c6087bb5..b28baab6d56a 100644 +--- a/drivers/net/dsa/hirschmann/hellcreek_ptp.c ++++ b/drivers/net/dsa/hirschmann/hellcreek_ptp.c +@@ -300,6 +300,7 @@ static int hellcreek_led_setup(struct hellcreek *hellcreek) + const char *label, *state; + int ret = -EINVAL; + ++ of_node_get(hellcreek->dev->of_node); + leds = of_find_node_by_name(hellcreek->dev->of_node, "leds"); + if (!leds) { + dev_err(hellcreek->dev, "No LEDs specified in device tree!\n"); +-- +2.16.4 + diff --git a/patches.suse/net-dsa-introduce-helpers-for-iterating-through-port.patch b/patches.suse/net-dsa-introduce-helpers-for-iterating-through-port.patch new file mode 100644 index 0000000..99488ee --- /dev/null +++ b/patches.suse/net-dsa-introduce-helpers-for-iterating-through-port.patch @@ -0,0 +1,77 @@ +From 528b8f20eafa55d48749a6bcb80937aa0c810c2a Mon Sep 17 00:00:00 2001 +From: Vladimir Oltean +Date: Wed, 20 Oct 2021 20:49:49 +0300 +Subject: [PATCH 06/19] net: dsa: introduce helpers for iterating through ports + using dp +Git-commit: 82b318983c515f29b8b3a0dad9f6a5fe8a68a7f4 +Patch-mainline: v5.16-rc1 +References: git-fixes + +Since the DSA conversion from the ds->ports array into the dst->ports +list, the DSA API has encouraged driver writers, as well as the core +itself, to write inefficient code. + +Currently, code that wants to filter by a specific type of port when +iterating, like {!unused, user, cpu, dsa}, uses the dsa_is_*_port helper. +Under the hood, this uses dsa_to_port which iterates again through +dst->ports. But the driver iterates through the port list already, so +the complexity is quadratic for the typical case of a single-switch +tree. + +This patch introduces some iteration helpers where the iterator is +already a struct dsa_port *dp, so that the other variant of the +filtering functions, dsa_port_is_{unused,user,cpu_dsa}, can be used +directly on the iterator. This eliminates the second lookup. + +These functions can be used both by the core and by drivers. + +Signed-off-by: Vladimir Oltean +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +Signed-off-by: Denis Kirjanov +--- + include/net/dsa.h | 28 ++++++++++++++++++++++++++++ + 1 file changed, 28 insertions(+) + +diff --git a/include/net/dsa.h b/include/net/dsa.h +index e483012b5522..85681498f2e2 100644 +--- a/include/net/dsa.h ++++ b/include/net/dsa.h +@@ -462,6 +462,34 @@ static inline bool dsa_is_user_port(struct dsa_switch *ds, int p) + return dsa_to_port(ds, p)->type == DSA_PORT_TYPE_USER; + } + ++#define dsa_tree_for_each_user_port(_dp, _dst) \ ++ list_for_each_entry((_dp), &(_dst)->ports, list) \ ++ if (dsa_port_is_user((_dp))) ++ ++#define dsa_switch_for_each_port(_dp, _ds) \ ++ list_for_each_entry((_dp), &(_ds)->dst->ports, list) \ ++ if ((_dp)->ds == (_ds)) ++ ++#define dsa_switch_for_each_port_safe(_dp, _next, _ds) \ ++ list_for_each_entry_safe((_dp), (_next), &(_ds)->dst->ports, list) \ ++ if ((_dp)->ds == (_ds)) ++ ++#define dsa_switch_for_each_port_continue_reverse(_dp, _ds) \ ++ list_for_each_entry_continue_reverse((_dp), &(_ds)->dst->ports, list) \ ++ if ((_dp)->ds == (_ds)) ++ ++#define dsa_switch_for_each_available_port(_dp, _ds) \ ++ dsa_switch_for_each_port((_dp), (_ds)) \ ++ if (!dsa_port_is_unused((_dp))) ++ ++#define dsa_switch_for_each_user_port(_dp, _ds) \ ++ dsa_switch_for_each_port((_dp), (_ds)) \ ++ if (dsa_port_is_user((_dp))) ++ ++#define dsa_switch_for_each_cpu_port(_dp, _ds) \ ++ dsa_switch_for_each_port((_dp), (_ds)) \ ++ if (dsa_port_is_cpu((_dp))) ++ + static inline u32 dsa_user_ports(struct dsa_switch *ds) + { + u32 mask = 0; +-- +2.16.4 + diff --git a/patches.suse/net-dsa-ksz9477-port-mirror-sniffing-limited-to-one-.patch b/patches.suse/net-dsa-ksz9477-port-mirror-sniffing-limited-to-one-.patch new file mode 100644 index 0000000..9231d74 --- /dev/null +++ b/patches.suse/net-dsa-ksz9477-port-mirror-sniffing-limited-to-one-.patch @@ -0,0 +1,98 @@ +From 59ccdf80f8fde1ea15db4e96ec8ae40cf143090b Mon Sep 17 00:00:00 2001 +From: Denis Kirjanov +Date: Thu, 6 Oct 2022 13:50:00 +0300 +Subject: [PATCH 01/32] net: dsa: ksz9477: port mirror sniffing limited to one + port +Git-commit: fee34dd199384a483f84806a5cbcf8d657a481cc +References: git-fixes +Patch-mainline: v5.18-rc6 + +This patch limits the sniffing to only one port during the mirror add. +And during the mirror_del it checks for all the ports using the sniff, +if and only if no other ports are referring, sniffing is disabled. +The code is updated based on the review comments of LAN937x port mirror +patch. + +Link: https://patchwork.kernel.org/project/netdevbpf/patch/20210422094257.1641396-8-prasanna.vengateshan@microchip.com/ +Fixes: b987e98e50ab ("dsa: add DSA switch driver for Microchip KSZ9477") +Signed-off-by: Prasanna Vengateshan +Signed-off-by: Arun Ramadoss +Link: https://lore.kernel.org/r/20220428070709.7094-1-arun.ramadoss@microchip.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Denis Kirjanov +--- + drivers/net/dsa/microchip/ksz9477.c | 37 +++++++++++++++++++++++++++++++++---- + 1 file changed, 33 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c +index 353b5f981740..970c587ac9b0 100644 +--- a/drivers/net/dsa/microchip/ksz9477.c ++++ b/drivers/net/dsa/microchip/ksz9477.c +@@ -896,14 +896,31 @@ static int ksz9477_port_mirror_add(struct dsa_switch *ds, int port, + bool ingress) + { + struct ksz_device *dev = ds->priv; ++ u8 data; ++ int p; ++ ++ /* Limit to one sniffer port ++ * Check if any of the port is already set for sniffing ++ * If yes, instruct the user to remove the previous entry & exit ++ */ ++ for (p = 0; p < dev->port_cnt; p++) { ++ /* Skip the current sniffing port */ ++ if (p == mirror->to_local_port) ++ continue; ++ ++ ksz_pread8(dev, p, P_MIRROR_CTRL, &data); ++ ++ if (data & PORT_MIRROR_SNIFFER) { ++ dev_dbg(dev->dev, "Sniffer port is already configured, delete existing rules & retry"); ++ return -EBUSY; ++ } ++ } + + if (ingress) + ksz_port_cfg(dev, port, P_MIRROR_CTRL, PORT_MIRROR_RX, true); + else + ksz_port_cfg(dev, port, P_MIRROR_CTRL, PORT_MIRROR_TX, true); + +- ksz_port_cfg(dev, port, P_MIRROR_CTRL, PORT_MIRROR_SNIFFER, false); +- + /* configure mirror port */ + ksz_port_cfg(dev, mirror->to_local_port, P_MIRROR_CTRL, + PORT_MIRROR_SNIFFER, true); +@@ -917,16 +934,28 @@ static void ksz9477_port_mirror_del(struct dsa_switch *ds, int port, + struct dsa_mall_mirror_tc_entry *mirror) + { + struct ksz_device *dev = ds->priv; ++ bool in_use = false; + u8 data; ++ int p; + + if (mirror->ingress) + ksz_port_cfg(dev, port, P_MIRROR_CTRL, PORT_MIRROR_RX, false); + else + ksz_port_cfg(dev, port, P_MIRROR_CTRL, PORT_MIRROR_TX, false); + +- ksz_pread8(dev, port, P_MIRROR_CTRL, &data); + +- if (!(data & (PORT_MIRROR_RX | PORT_MIRROR_TX))) ++ /* Check if any of the port is still referring to sniffer port */ ++ for (p = 0; p < dev->port_cnt; p++) { ++ ksz_pread8(dev, p, P_MIRROR_CTRL, &data); ++ ++ if ((data & (PORT_MIRROR_RX | PORT_MIRROR_TX))) { ++ in_use = true; ++ break; ++ } ++ } ++ ++ /* delete sniffing if there are no other mirroring rules */ ++ if (!in_use) + ksz_port_cfg(dev, mirror->to_local_port, P_MIRROR_CTRL, + PORT_MIRROR_SNIFFER, false); + } +-- +2.16.4 + diff --git a/patches.suse/net-dsa-lantiq_gswip-Fix-refcount-leak-in-gswip_gphy.patch b/patches.suse/net-dsa-lantiq_gswip-Fix-refcount-leak-in-gswip_gphy.patch new file mode 100644 index 0000000..95aa07e --- /dev/null +++ b/patches.suse/net-dsa-lantiq_gswip-Fix-refcount-leak-in-gswip_gphy.patch @@ -0,0 +1,43 @@ +From 435b0761a47fa8293b3ec772e1275954fc304878 Mon Sep 17 00:00:00 2001 +From: Miaoqian Lin +Date: Sun, 5 Jun 2022 11:23:34 +0400 +Subject: [PATCH 11/32] net: dsa: lantiq_gswip: Fix refcount leak in + gswip_gphy_fw_list +Git-commit: 0737e018a05e2aa352828c52bdeed3b02cff2930 +References: git-fixes +Patch-mainline: v5.19-rc2 + +Every iteration of for_each_available_child_of_node() decrements +the reference count of the previous node. +when breaking early from a for_each_available_child_of_node() loop, +we need to explicitly call of_node_put() on the gphy_fw_np. +Add missing of_node_put() to avoid refcount leak. + +Fixes: 14fceff4771e ("net: dsa: Add Lantiq / Intel DSA driver for vrx200") +Signed-off-by: Miaoqian Lin +Link: https://lore.kernel.org/r/20220605072335.11257-1-linmq006@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Denis Kirjanov +--- + drivers/net/dsa/lantiq_gswip.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/dsa/lantiq_gswip.c b/drivers/net/dsa/lantiq_gswip.c +index 8a8f392813d8..2240a3d35122 100644 +--- a/drivers/net/dsa/lantiq_gswip.c ++++ b/drivers/net/dsa/lantiq_gswip.c +@@ -2047,8 +2047,10 @@ static int gswip_gphy_fw_list(struct gswip_priv *priv, + for_each_available_child_of_node(gphy_fw_list_np, gphy_fw_np) { + err = gswip_gphy_fw_probe(priv, &priv->gphy_fw[i], + gphy_fw_np, i); +- if (err) ++ if (err) { ++ of_node_put(gphy_fw_np); + goto remove_gphy; ++ } + i++; + } + +-- +2.16.4 + diff --git a/patches.suse/net-dsa-microchip-ksz_common-Fix-refcount-leak-bug.patch b/patches.suse/net-dsa-microchip-ksz_common-Fix-refcount-leak-bug.patch new file mode 100644 index 0000000..2852a00 --- /dev/null +++ b/patches.suse/net-dsa-microchip-ksz_common-Fix-refcount-leak-bug.patch @@ -0,0 +1,52 @@ +From 792ad8961c4e7e2e39c0c2e732bf8919526d817e Mon Sep 17 00:00:00 2001 +From: Liang He +Date: Thu, 14 Jul 2022 23:31:38 +0800 +Subject: [PATCH 17/28] net: dsa: microchip: ksz_common: Fix refcount leak bug +Git-commit: a14bd7475452c51835dd5a0cee4c8fa48dd0b539 +Patch-mainline: v5.19-rc8 +References: git-fixes + +In ksz_switch_register(), we should call of_node_put() for the +reference returned by of_get_child_by_name() which has increased +the refcount. + +Fixes: 912aae27c6af ("net: dsa: microchip: really look for phy-mode in port nodes") +Signed-off-by: Liang He +Reviewed-by: Vladimir Oltean +Link: https://lore.kernel.org/r/20220714153138.375919-1-windhl@126.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Denis Kirjanov +--- + drivers/net/dsa/microchip/ksz_common.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c +index 824430cdb9ac..f4d98a7f91a6 100644 +--- a/drivers/net/dsa/microchip/ksz_common.c ++++ b/drivers/net/dsa/microchip/ksz_common.c +@@ -456,18 +456,21 @@ int ksz_switch_register(struct ksz_device *dev, + ports = of_get_child_by_name(dev->dev->of_node, "ethernet-ports"); + if (!ports) + ports = of_get_child_by_name(dev->dev->of_node, "ports"); +- if (ports) ++ if (ports) { + for_each_available_child_of_node(ports, port) { + if (of_property_read_u32(port, "reg", + &port_num)) + continue; + if (!(dev->port_mask & BIT(port_num))) { + of_node_put(port); ++ of_node_put(ports); + return -EINVAL; + } + of_get_phy_mode(port, + &dev->ports[port_num].interface); + } ++ of_node_put(ports); ++ } + dev->synclko_125 = of_property_read_bool(dev->dev->of_node, + "microchip,synclko-125"); + } +-- +2.16.4 + diff --git a/patches.suse/net-dsa-mv88e6xxx-Fix-refcount-leak-in-mv88e6xxx_mdi.patch b/patches.suse/net-dsa-mv88e6xxx-Fix-refcount-leak-in-mv88e6xxx_mdi.patch new file mode 100644 index 0000000..e99302c --- /dev/null +++ b/patches.suse/net-dsa-mv88e6xxx-Fix-refcount-leak-in-mv88e6xxx_mdi.patch @@ -0,0 +1,41 @@ +From 6616f3a515c9b69ff0bf21fd12dfa0cd06c24b73 Mon Sep 17 00:00:00 2001 +From: Miaoqian Lin +Date: Thu, 26 May 2022 18:52:08 +0400 +Subject: [PATCH 16/19] net: dsa: mv88e6xxx: Fix refcount leak in + mv88e6xxx_mdios_register +Git-commit: 02ded5a173619b11728b8bf75a3fd995a2c1ff28 +Patch-mainline: v5.19-rc1 +References: git-fixes + +of_get_child_by_name() returns a node pointer with refcount +incremented, we should use of_node_put() on it when done. + +mv88e6xxx_mdio_register() pass the device node to of_mdiobus_register(). +We don't need the device node after it. + +Add missing of_node_put() to avoid refcount leak. + +Fixes: a3c53be55c95 ("net: dsa: mv88e6xxx: Support multiple MDIO busses") +Signed-off-by: Miaoqian Lin +Reviewed-by: Marek Behún +Signed-off-by: David S. Miller +Signed-off-by: Denis Kirjanov +--- + drivers/net/dsa/mv88e6xxx/chip.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c +index 2923ce39c9ea..4974038b667b 100644 +--- a/drivers/net/dsa/mv88e6xxx/chip.c ++++ b/drivers/net/dsa/mv88e6xxx/chip.c +@@ -3349,6 +3349,7 @@ static int mv88e6xxx_mdios_register(struct mv88e6xxx_chip *chip, + */ + child = of_get_child_by_name(np, "mdio"); + err = mv88e6xxx_mdio_register(chip, child, false); ++ of_node_put(child); + if (err) + return err; + +-- +2.16.4 + diff --git a/patches.suse/net-dsa-mv88e6xxx-use-BMSR_ANEGCOMPLETE-bit-for-fill.patch b/patches.suse/net-dsa-mv88e6xxx-use-BMSR_ANEGCOMPLETE-bit-for-fill.patch new file mode 100644 index 0000000..124b820 --- /dev/null +++ b/patches.suse/net-dsa-mv88e6xxx-use-BMSR_ANEGCOMPLETE-bit-for-fill.patch @@ -0,0 +1,113 @@ +From 8e77f311c4b7521ff511b1f4260cdd2126f66fd3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marek=20Beh=C3=BAn?= +Date: Tue, 7 Jun 2022 12:28:42 +0100 +Subject: [PATCH 14/32] net: dsa: mv88e6xxx: use BMSR_ANEGCOMPLETE bit for + filling an_complete +Git-commit: 47e96930d6e6106d5252e85b868d3c7e29296de0 +References: git-fixes +Patch-mainline: v5.19-rc2 + +Commit ede359d8843a ("net: dsa: mv88e6xxx: Link in pcs_get_state() if AN +is bypassed") added the ability to link if AN was bypassed, and added +filling of state->an_complete field, but set it to true if AN was +enabled in BMCR, not when AN was reported complete in BMSR. + +This was done because for some reason, when I wanted to use BMSR value +to infer an_complete, I was looking at BMSR_ANEGCAPABLE bit (which was +always 1), instead of BMSR_ANEGCOMPLETE bit. + +Use BMSR_ANEGCOMPLETE for filling state->an_complete. + +Fixes: ede359d8843a ("net: dsa: mv88e6xxx: Link in pcs_get_state() if AN is bypassed") +Signed-off-by: Marek Behún +Signed-off-by: Russell King (Oracle) +Signed-off-by: Jakub Kicinski +Signed-off-by: Denis Kirjanov +--- + drivers/net/dsa/mv88e6xxx/serdes.c | 27 +++++++++++---------------- + 1 file changed, 11 insertions(+), 16 deletions(-) + +diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c +index 2b05ead515cd..6ae7a0ed9e0b 100644 +--- a/drivers/net/dsa/mv88e6xxx/serdes.c ++++ b/drivers/net/dsa/mv88e6xxx/serdes.c +@@ -50,22 +50,17 @@ static int mv88e6390_serdes_write(struct mv88e6xxx_chip *chip, + } + + static int mv88e6xxx_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, +- u16 ctrl, u16 status, u16 lpa, ++ u16 bmsr, u16 lpa, u16 status, + struct phylink_link_state *state) + { + state->link = !!(status & MV88E6390_SGMII_PHY_STATUS_LINK); ++ state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE); + + if (status & MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID) { + /* The Spped and Duplex Resolved register is 1 if AN is enabled + * and complete, or if AN is disabled. So with disabled AN we +- * still get here on link up. But we want to set an_complete +- * only if AN was enabled, thus we look at BMCR_ANENABLE. +- * (According to 802.3-2008 section 22.2.4.2.10, we should be +- * able to get this same value from BMSR_ANEGCAPABLE, but tests +- * show that these Marvell PHYs don't conform to this part of +- * the specificaion - BMSR_ANEGCAPABLE is simply always 1.) ++ * still get here on link up. + */ +- state->an_complete = !!(ctrl & BMCR_ANENABLE); + state->duplex = status & + MV88E6390_SGMII_PHY_STATUS_DUPLEX_FULL ? + DUPLEX_FULL : DUPLEX_HALF; +@@ -191,12 +186,12 @@ int mv88e6352_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port, + int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port, + int lane, struct phylink_link_state *state) + { +- u16 lpa, status, ctrl; ++ u16 bmsr, lpa, status; + int err; + +- err = mv88e6352_serdes_read(chip, MII_BMCR, &ctrl); ++ err = mv88e6352_serdes_read(chip, MII_BMSR, &bmsr); + if (err) { +- dev_err(chip->dev, "can't read Serdes PHY control: %d\n", err); ++ dev_err(chip->dev, "can't read Serdes BMSR: %d\n", err); + return err; + } + +@@ -212,7 +207,7 @@ int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port, + return err; + } + +- return mv88e6xxx_serdes_pcs_get_state(chip, ctrl, status, lpa, state); ++ return mv88e6xxx_serdes_pcs_get_state(chip, bmsr, lpa, status, state); + } + + int mv88e6352_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port, +@@ -915,13 +910,13 @@ int mv88e6390_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port, + static int mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip *chip, + int port, int lane, struct phylink_link_state *state) + { +- u16 lpa, status, ctrl; ++ u16 bmsr, lpa, status; + int err; + + err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, +- MV88E6390_SGMII_BMCR, &ctrl); ++ MV88E6390_SGMII_BMSR, &bmsr); + if (err) { +- dev_err(chip->dev, "can't read Serdes PHY control: %d\n", err); ++ dev_err(chip->dev, "can't read Serdes PHY BMSR: %d\n", err); + return err; + } + +@@ -939,7 +934,7 @@ static int mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip *chip, + return err; + } + +- return mv88e6xxx_serdes_pcs_get_state(chip, ctrl, status, lpa, state); ++ return mv88e6xxx_serdes_pcs_get_state(chip, bmsr, lpa, status, state); + } + + static int mv88e6390_serdes_pcs_get_state_10g(struct mv88e6xxx_chip *chip, +-- +2.16.4 + diff --git a/patches.suse/net-dsa-restrict-SMSC_LAN9303_I2C-kconfig.patch b/patches.suse/net-dsa-restrict-SMSC_LAN9303_I2C-kconfig.patch new file mode 100644 index 0000000..adef960 --- /dev/null +++ b/patches.suse/net-dsa-restrict-SMSC_LAN9303_I2C-kconfig.patch @@ -0,0 +1,73 @@ +From dd0a9e7dc69936ececb31b8438e155a95bb0be07 Mon Sep 17 00:00:00 2001 +From: Randy Dunlap +Date: Thu, 19 May 2022 22:15:23 -0700 +Subject: [PATCH 15/19] net: dsa: restrict SMSC_LAN9303_I2C kconfig +Git-commit: 0a3ad7d323686fbaae8688326cc5ea0d185c6fca +Patch-mainline: v5.19-rc1 +References: git-fixes + +Since kconfig 'select' does not follow dependency chains, if symbol KSA +selects KSB, then KSA should also depend on the same symbols that KSB +depends on, in order to prevent Kconfig warnings and possible build +errors. + +Change NET_DSA_SMSC_LAN9303_I2C and NET_DSA_SMSC_LAN9303_MDIO so that +they are limited to VLAN_8021Q if the latter is enabled. This prevents +the Kconfig warning: + +WARNING: unmet direct dependencies detected for NET_DSA_SMSC_LAN9303 + Depends on [m]: NETDEVICES [=y] && NET_DSA [=y] && (VLAN_8021Q [=m] || VLAN_8021Q [=m]=n) + Selected by [y]: + - NET_DSA_SMSC_LAN9303_I2C [=y] && NETDEVICES [=y] && NET_DSA [=y] && I2C [=y] + +Fixes: 430065e26719 ("net: dsa: lan9303: add VLAN IDs to master device") +Signed-off-by: Randy Dunlap +Cc: Andrew Lunn +Cc: Vivien Didelot +Cc: Florian Fainelli +Cc: Vladimir Oltean +Cc: Juergen Borleis +Cc: "David S. Miller" +Cc: Eric Dumazet +Cc: Jakub Kicinski +Cc: Paolo Abeni +Cc: Mans Rullgard +Reviewed-by: Vladimir Oltean +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +Signed-off-by: Denis Kirjanov +--- + drivers/net/dsa/Kconfig | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig +index 9428aac4a686..6117d4537f88 100644 +--- a/drivers/net/dsa/Kconfig ++++ b/drivers/net/dsa/Kconfig +@@ -81,7 +81,6 @@ config NET_DSA_REALTEK_SMI + + config NET_DSA_SMSC_LAN9303 + tristate +- depends on VLAN_8021Q || VLAN_8021Q=n + select NET_DSA_TAG_LAN9303 + select REGMAP + help +@@ -91,6 +90,7 @@ config NET_DSA_SMSC_LAN9303 + config NET_DSA_SMSC_LAN9303_I2C + tristate "SMSC/Microchip LAN9303 3-ports 10/100 ethernet switch in I2C managed mode" + depends on I2C ++ depends on VLAN_8021Q || VLAN_8021Q=n + select NET_DSA_SMSC_LAN9303 + select REGMAP_I2C + help +@@ -100,6 +100,7 @@ config NET_DSA_SMSC_LAN9303_I2C + config NET_DSA_SMSC_LAN9303_MDIO + tristate "SMSC/Microchip LAN9303 3-ports 10/100 ethernet switch in MDIO managed mode" + select NET_DSA_SMSC_LAN9303 ++ depends on VLAN_8021Q || VLAN_8021Q=n + help + Enable access functions if the SMSC/Microchip LAN9303 is configured + for MDIO managed mode. +-- +2.16.4 + diff --git a/patches.suse/net-dsa-sja1105-silent-spi_device_id-warnings.patch b/patches.suse/net-dsa-sja1105-silent-spi_device_id-warnings.patch new file mode 100644 index 0000000..b7339f2 --- /dev/null +++ b/patches.suse/net-dsa-sja1105-silent-spi_device_id-warnings.patch @@ -0,0 +1,67 @@ +From cfe10cd92eb998a5ab6315d9db4e5801df5dfe57 Mon Sep 17 00:00:00 2001 +From: Oleksij Rempel +Date: Sun, 17 Jul 2022 15:58:30 +0200 +Subject: [PATCH 21/28] net: dsa: sja1105: silent spi_device_id warnings +Git-commit: 855fe49984a8a3899f07ae1d149d46cd8d4acb52 +Patch-mainline: v5.19-rc8 +References: git-fixes + +Add spi_device_id entries to silent following warnings: + SPI driver sja1105 has no spi_device_id for nxp,sja1105e + SPI driver sja1105 has no spi_device_id for nxp,sja1105t + SPI driver sja1105 has no spi_device_id for nxp,sja1105p + SPI driver sja1105 has no spi_device_id for nxp,sja1105q + SPI driver sja1105 has no spi_device_id for nxp,sja1105r + SPI driver sja1105 has no spi_device_id for nxp,sja1105s + SPI driver sja1105 has no spi_device_id for nxp,sja1110a + SPI driver sja1105 has no spi_device_id for nxp,sja1110b + SPI driver sja1105 has no spi_device_id for nxp,sja1110c + SPI driver sja1105 has no spi_device_id for nxp,sja1110d + +Fixes: 5fa6863ba692 ("spi: Check we have a spi_device_id for each DT compatible") +Signed-off-by: Oleksij Rempel +Reviewed-by: Vladimir Oltean +Reviewed-by: Florian Fainelli +Link: https://lore.kernel.org/r/20220717135831.2492844-1-o.rempel@pengutronix.de +Signed-off-by: Paolo Abeni +Signed-off-by: Denis Kirjanov +--- + drivers/net/dsa/sja1105/sja1105_main.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c +index e454008efd55..d491ef9e10a5 100644 +--- a/drivers/net/dsa/sja1105/sja1105_main.c ++++ b/drivers/net/dsa/sja1105/sja1105_main.c +@@ -3925,12 +3925,28 @@ static const struct of_device_id sja1105_dt_ids[] = { + }; + MODULE_DEVICE_TABLE(of, sja1105_dt_ids); + ++static const struct spi_device_id sja1105_spi_ids[] = { ++ { "sja1105e" }, ++ { "sja1105t" }, ++ { "sja1105p" }, ++ { "sja1105q" }, ++ { "sja1105r" }, ++ { "sja1105s" }, ++ { "sja1110a" }, ++ { "sja1110b" }, ++ { "sja1110c" }, ++ { "sja1110d" }, ++ { }, ++}; ++MODULE_DEVICE_TABLE(spi, sja1105_spi_ids); ++ + static struct spi_driver sja1105_driver = { + .driver = { + .name = "sja1105", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(sja1105_dt_ids), + }, ++ .id_table = sja1105_spi_ids, + .probe = sja1105_probe, + .remove = sja1105_remove, + .shutdown = sja1105_shutdown, +-- +2.16.4 + diff --git a/patches.suse/net-dsa-vitesse-vsc73xx-silent-spi_device_id-warning.patch b/patches.suse/net-dsa-vitesse-vsc73xx-silent-spi_device_id-warning.patch new file mode 100644 index 0000000..49d6aa2 --- /dev/null +++ b/patches.suse/net-dsa-vitesse-vsc73xx-silent-spi_device_id-warning.patch @@ -0,0 +1,49 @@ +From 4067979346601b5198214d484d636e36ac859b6b Mon Sep 17 00:00:00 2001 +From: Oleksij Rempel +Date: Sun, 17 Jul 2022 15:58:31 +0200 +Subject: [PATCH 22/28] net: dsa: vitesse-vsc73xx: silent spi_device_id + warnings +Git-commit: 1774559f07993e1cac33c2406e99049d4bdea6c8 +Patch-mainline: v5.19-rc8 +References: git-fixes + +Add spi_device_id entries to silent SPI warnings. + +Fixes: 5fa6863ba692 ("spi: Check we have a spi_device_id for each DT compatible") +Signed-off-by: Oleksij Rempel +Reviewed-by: Vladimir Oltean +Link: https://lore.kernel.org/r/20220717135831.2492844-2-o.rempel@pengutronix.de +Signed-off-by: Paolo Abeni +Signed-off-by: Denis Kirjanov +--- + drivers/net/dsa/vitesse-vsc73xx-spi.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/net/dsa/vitesse-vsc73xx-spi.c b/drivers/net/dsa/vitesse-vsc73xx-spi.c +index 645398901e05..922ae22fad66 100644 +--- a/drivers/net/dsa/vitesse-vsc73xx-spi.c ++++ b/drivers/net/dsa/vitesse-vsc73xx-spi.c +@@ -207,10 +207,20 @@ static const struct of_device_id vsc73xx_of_match[] = { + }; + MODULE_DEVICE_TABLE(of, vsc73xx_of_match); + ++static const struct spi_device_id vsc73xx_spi_ids[] = { ++ { "vsc7385" }, ++ { "vsc7388" }, ++ { "vsc7395" }, ++ { "vsc7398" }, ++ { }, ++}; ++MODULE_DEVICE_TABLE(spi, vsc73xx_spi_ids); ++ + static struct spi_driver vsc73xx_spi_driver = { + .probe = vsc73xx_spi_probe, + .remove = vsc73xx_spi_remove, + .shutdown = vsc73xx_spi_shutdown, ++ .id_table = vsc73xx_spi_ids, + .driver = { + .name = "vsc73xx-spi", + .of_match_table = vsc73xx_of_match, +-- +2.16.4 + diff --git a/patches.suse/net-enetc-Use-pci_release_region-to-release-some-res.patch b/patches.suse/net-enetc-Use-pci_release_region-to-release-some-res.patch new file mode 100644 index 0000000..1ef8aec --- /dev/null +++ b/patches.suse/net-enetc-Use-pci_release_region-to-release-some-res.patch @@ -0,0 +1,46 @@ +From 6d43214331717d4bee3f54eb1a0c46ca51df0bd9 Mon Sep 17 00:00:00 2001 +From: Christophe JAILLET +Date: Fri, 27 May 2022 11:25:47 +0200 +Subject: [PATCH 17/19] net: enetc: Use pci_release_region() to release some + resources +Git-commit: 18eeb4dea65cb587057740d6b7b71a13bcfececd +Patch-mainline: v5.19-rc1 +References: git-fixes + +Some resources are allocated using pci_request_region(). +It is more straightforward to release them with pci_release_region(). + +Fixes: 231ece36f50d ("enetc: Add mdio bus driver for the PCIe MDIO endpoint") +Signed-off-by: Christophe JAILLET +Reviewed-by: Claudiu Manoil +Signed-off-by: David S. Miller +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/freescale/enetc/enetc_pci_mdio.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pci_mdio.c b/drivers/net/ethernet/freescale/enetc/enetc_pci_mdio.c +index 15f37c5b8dc1..dafb26f81f95 100644 +--- a/drivers/net/ethernet/freescale/enetc/enetc_pci_mdio.c ++++ b/drivers/net/ethernet/freescale/enetc/enetc_pci_mdio.c +@@ -69,7 +69,7 @@ static int enetc_pci_mdio_probe(struct pci_dev *pdev, + return 0; + + err_mdiobus_reg: +- pci_release_mem_regions(pdev); ++ pci_release_region(pdev, 0); + err_pci_mem_reg: + pci_disable_device(pdev); + err_pci_enable: +@@ -88,7 +88,7 @@ static void enetc_pci_mdio_remove(struct pci_dev *pdev) + mdiobus_unregister(bus); + mdio_priv = bus->priv; + iounmap(mdio_priv->hw->port); +- pci_release_mem_regions(pdev); ++ pci_release_region(pdev, 0); + pci_disable_device(pdev); + } + +-- +2.16.4 + diff --git a/patches.suse/net-ethernet-bgmac-Fix-refcount-leak-in-bcma_mdio_mi.patch b/patches.suse/net-ethernet-bgmac-Fix-refcount-leak-in-bcma_mdio_mi.patch new file mode 100644 index 0000000..437f113 --- /dev/null +++ b/patches.suse/net-ethernet-bgmac-Fix-refcount-leak-in-bcma_mdio_mi.patch @@ -0,0 +1,38 @@ +From 33abfa9a5c25ec6537fa9523e8cb723cb580f29a Mon Sep 17 00:00:00 2001 +From: Miaoqian Lin +Date: Fri, 3 Jun 2022 17:32:38 +0400 +Subject: [PATCH 09/32] net: ethernet: bgmac: Fix refcount leak in + bcma_mdio_mii_register +Git-commit: b8d91399775c55162073bb2aca061ec42e3d4bc1 +References: git-fixes +Patch-mainline: v5.19-rc2 + +of_get_child_by_name() returns a node pointer with refcount +incremented, we should use of_node_put() on it when not need anymore. +Add missing of_node_put() to avoid refcount leak. + +Fixes: 55954f3bfdac ("net: ethernet: bgmac: move BCMA MDIO Phy code into a separate file") +Signed-off-by: Miaoqian Lin +Reviewed-by: Andrew Lunn +Link: https://lore.kernel.org/r/20220603133238.44114-1-linmq006@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c b/drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c +index 086739e4f40a..9b83d5361699 100644 +--- a/drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c ++++ b/drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c +@@ -234,6 +234,7 @@ struct mii_bus *bcma_mdio_mii_register(struct bgmac *bgmac) + np = of_get_child_by_name(core->dev.of_node, "mdio"); + + err = of_mdiobus_register(mii_bus, np); ++ of_node_put(np); + if (err) { + dev_err(&core->dev, "Registration of mii bus failed\n"); + goto err_free_bus; +-- +2.16.4 + diff --git a/patches.suse/net-ethernet-move-from-strlcpy-with-unused-retval-to-strscpy.patch b/patches.suse/net-ethernet-move-from-strlcpy-with-unused-retval-to-strscpy.patch new file mode 100644 index 0000000..6cd8be9 --- /dev/null +++ b/patches.suse/net-ethernet-move-from-strlcpy-with-unused-retval-to-strscpy.patch @@ -0,0 +1,3233 @@ +From: Wolfram Sang +Date: Tue, 30 Aug 2022 22:14:54 +0200 +Subject: net: ethernet: move from strlcpy with unused retval to strscpy +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Git-commit: f029c781dd6d8e2f13593c927c66db7e8826ed28 +Patch-mainline: v6.0 or v6.0-rc8 (next release) +References: jsc#PED-1302 + +Follow the advice of the below link and prefer 'strscpy' in this +subsystem. Conversion is 1:1 because the return value is not used. +Generated by a coccinelle script. + +[lduncan: hand refreshed to apply correctly.] + +Link: https://lore.kernel.org/r/CAHk-=wgfRnXz0W3D37d01q3JFkr_i_uTL=V6A6G1oUZcprmknw@mail.gmail.com/ +Signed-off-by: Wolfram Sang +Reviewed-by: Petr Machata # For drivers/net/ethernet/mellanox/mlxsw +Acked-by: Geoff Levand # For ps3_gelic_net and spider_net_ethtool +Acked-by: Tom Lendacky # For drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c +Acked-by: Marcin Wojtas # For drivers/net/ethernet/marvell/mvpp2 +Reviewed-by: Leon Romanovsky # For drivers/net/ethernet/mellanox/mlx{4|5} +Reviewed-by: Shay Agroskin # For drivers/net/ethernet/amazon/ena +Acked-by: Krzysztof Hałasa # For IXP4xx Ethernet +Link: https://lore.kernel.org/r/20220830201457.7984-3-wsa+renesas@sang-engineering.com +Signed-off-by: Jakub Kicinski +Acked-by: Lee Duncan +--- + drivers/net/ethernet/3com/3c509.c | 2 - + drivers/net/ethernet/3com/3c515.c | 2 - + drivers/net/ethernet/3com/3c589_cs.c | 2 - + drivers/net/ethernet/3com/3c59x.c | 6 +-- + drivers/net/ethernet/3com/typhoon.c | 8 ++--- + drivers/net/ethernet/8390/ax88796.c | 6 +-- + drivers/net/ethernet/8390/etherh.c | 6 +-- + drivers/net/ethernet/adaptec/starfire.c | 4 +- + drivers/net/ethernet/aeroflex/greth.c | 4 +- + drivers/net/ethernet/agere/et131x.c | 4 +- + drivers/net/ethernet/alacritech/slicoss.c | 4 +- + drivers/net/ethernet/allwinner/sun4i-emac.c | 4 +- + drivers/net/ethernet/alteon/acenic.c | 4 +- + drivers/net/ethernet/amazon/ena/ena_ethtool.c | 4 +- + drivers/net/ethernet/amazon/ena/ena_netdev.c | 2 - + drivers/net/ethernet/amd/amd8111e.c | 4 +- + drivers/net/ethernet/amd/au1000_eth.c | 2 - + drivers/net/ethernet/amd/nmclan_cs.c | 2 - + drivers/net/ethernet/amd/pcnet32.c | 4 +- + drivers/net/ethernet/amd/sunlance.c | 2 - + drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c | 4 +- + drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c | 2 - + drivers/net/ethernet/arc/emac_main.c | 2 - + drivers/net/ethernet/atheros/ag71xx.c | 4 +- + drivers/net/ethernet/atheros/atl1c/atl1c_ethtool.c | 4 +- + drivers/net/ethernet/atheros/atl1e/atl1e_ethtool.c | 6 +-- + drivers/net/ethernet/atheros/atlx/atl1.c | 4 +- + drivers/net/ethernet/atheros/atlx/atl2.c | 6 +-- + drivers/net/ethernet/broadcom/b44.c | 6 +-- + drivers/net/ethernet/broadcom/bcm63xx_enet.c | 4 +- + drivers/net/ethernet/broadcom/bcmsysport.c | 4 +- + drivers/net/ethernet/broadcom/bgmac.c | 6 +-- + drivers/net/ethernet/broadcom/bnx2.c | 6 +-- + drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 2 - + drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 6 +-- + drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 2 - + drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h | 2 - + drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c | 2 - + drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 8 ++--- + drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c | 2 - + drivers/net/ethernet/broadcom/genet/bcmgenet.c | 2 - + drivers/net/ethernet/broadcom/tg3.c | 6 +-- + drivers/net/ethernet/brocade/bna/bnad_ethtool.c | 6 +-- + drivers/net/ethernet/cavium/octeon/octeon_mgmt.c | 2 - + drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c | 4 +- + drivers/net/ethernet/chelsio/cxgb/cxgb2.c | 4 +- + drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c | 4 +- + drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c | 4 +- + drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 4 +- + drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c | 4 +- + drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_main.c | 2 - + drivers/net/ethernet/cirrus/ep93xx_eth.c | 2 - + drivers/net/ethernet/cisco/enic/enic_ethtool.c | 6 +-- + drivers/net/ethernet/davicom/dm9000.c | 4 +- + drivers/net/ethernet/dec/tulip/de2104x.c | 4 +- + drivers/net/ethernet/dec/tulip/dmfe.c | 4 +- + drivers/net/ethernet/dec/tulip/tulip_core.c | 4 +- + drivers/net/ethernet/dec/tulip/uli526x.c | 4 +- + drivers/net/ethernet/dec/tulip/winbond-840.c | 4 +- + drivers/net/ethernet/dlink/dl2k.c | 4 +- + drivers/net/ethernet/dlink/sundance.c | 4 +- + drivers/net/ethernet/dnet.c | 4 +- + drivers/net/ethernet/emulex/benet/be_cmds.c | 12 +++---- + drivers/net/ethernet/emulex/benet/be_ethtool.c | 6 +-- + drivers/net/ethernet/faraday/ftgmac100.c | 4 +- + drivers/net/ethernet/faraday/ftmac100.c | 4 +- + drivers/net/ethernet/fealnx.c | 4 +- + drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c | 4 +- + drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c | 2 - + drivers/net/ethernet/freescale/enetc/enetc_ethtool.c | 4 +- + drivers/net/ethernet/freescale/fec_main.c | 8 ++--- + drivers/net/ethernet/freescale/fec_ptp.c | 2 - + drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c | 2 - + drivers/net/ethernet/freescale/gianfar_ethtool.c | 2 - + drivers/net/ethernet/freescale/ucc_geth_ethtool.c | 4 +- + drivers/net/ethernet/fujitsu/fmvj18x_cs.c | 4 +- + drivers/net/ethernet/hisilicon/hip04_eth.c | 4 +- + drivers/net/ethernet/ibm/ehea/ehea_ethtool.c | 4 +- + drivers/net/ethernet/ibm/emac/core.c | 4 +- + drivers/net/ethernet/ibm/ibmveth.c | 4 +- + drivers/net/ethernet/intel/e100.c | 4 +- + drivers/net/ethernet/intel/e1000/e1000_ethtool.c | 4 +- + drivers/net/ethernet/intel/e1000e/ethtool.c | 4 +- + drivers/net/ethernet/intel/e1000e/netdev.c | 6 +-- + drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 6 +-- + drivers/net/ethernet/intel/i40e/i40e_main.c | 16 +++++----- + drivers/net/ethernet/intel/i40e/i40e_ptp.c | 2 - + drivers/net/ethernet/intel/iavf/iavf_ethtool.c | 6 +-- + drivers/net/ethernet/intel/igb/igb_ethtool.c | 6 +-- + drivers/net/ethernet/intel/igb/igb_main.c | 2 - + drivers/net/ethernet/intel/igbvf/ethtool.c | 4 +- + drivers/net/ethernet/intel/ixgb/ixgb_ethtool.c | 4 +- + drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 6 +-- + drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c | 2 - + drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 4 +- + drivers/net/ethernet/intel/ixgbevf/ethtool.c | 4 +- + drivers/net/ethernet/jme.c | 6 +-- + drivers/net/ethernet/korina.c | 6 +-- + drivers/net/ethernet/marvell/mv643xx_eth.c | 8 ++--- + drivers/net/ethernet/marvell/mvneta.c | 6 +-- + drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 6 +-- + drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c | 8 ++--- + drivers/net/ethernet/marvell/prestera/prestera_ethtool.c | 4 +- + drivers/net/ethernet/marvell/pxa168_eth.c | 8 ++--- + drivers/net/ethernet/marvell/skge.c | 6 +-- + drivers/net/ethernet/marvell/sky2.c | 6 +-- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 +- + drivers/net/ethernet/mediatek/mtk_star_emac.c | 2 - + drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 6 +-- + drivers/net/ethernet/mellanox/mlx4/fw.c | 2 - + drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c | 4 +- + drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 2 - + drivers/net/ethernet/mellanox/mlx5/core/ipoib/ethtool.c | 2 - + drivers/net/ethernet/mellanox/mlxsw/core.c | 2 - + drivers/net/ethernet/mellanox/mlxsw/minimal.c | 4 +- + drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c | 6 +-- + drivers/net/ethernet/micrel/ks8851_common.c | 6 +-- + drivers/net/ethernet/micrel/ksz884x.c | 6 +-- + drivers/net/ethernet/microchip/enc28j60.c | 6 +-- + drivers/net/ethernet/microchip/encx24j600.c | 6 +-- + drivers/net/ethernet/microchip/lan743x_ethtool.c | 4 +- + drivers/net/ethernet/myricom/myri10ge/myri10ge.c | 8 ++--- + drivers/net/ethernet/natsemi/natsemi.c | 6 +-- + drivers/net/ethernet/natsemi/ns83820.c | 6 +-- + drivers/net/ethernet/neterion/s2io.c | 6 +-- + drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c | 6 +-- + drivers/net/ethernet/ni/nixge.c | 4 +- + drivers/net/ethernet/nvidia/forcedeth.c | 6 +-- + drivers/net/ethernet/nxp/lpc_eth.c | 6 +-- + drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_ethtool.c | 6 +-- + drivers/net/ethernet/packetengines/hamachi.c | 6 +-- + drivers/net/ethernet/packetengines/yellowfin.c | 6 +-- + drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c | 6 +-- + drivers/net/ethernet/qlogic/qed/qed_int.c | 2 - + drivers/net/ethernet/qlogic/qede/qede_ethtool.c | 4 +- + drivers/net/ethernet/qlogic/qede/qede_main.c | 2 - + drivers/net/ethernet/qlogic/qla3xxx.c | 6 +-- + drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | 6 +-- + drivers/net/ethernet/qualcomm/qca_debug.c | 8 ++--- + drivers/net/ethernet/rdc/r6040.c | 6 +-- + drivers/net/ethernet/realtek/8139cp.c | 6 +-- + drivers/net/ethernet/realtek/8139too.c | 6 +-- + drivers/net/ethernet/realtek/r8169_main.c | 6 +-- + drivers/net/ethernet/rocker/rocker_main.c | 4 +- + drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c | 4 +- + drivers/net/ethernet/sfc/efx.c | 2 - + drivers/net/ethernet/sfc/efx_common.c | 2 - + drivers/net/ethernet/sfc/ethtool_common.c | 6 +-- + drivers/net/ethernet/sfc/falcon/efx.c | 4 +- + drivers/net/ethernet/sfc/falcon/ethtool.c | 8 ++--- + drivers/net/ethernet/sfc/falcon/falcon.c | 2 - + drivers/net/ethernet/sfc/falcon/nic.c | 2 - + drivers/net/ethernet/sfc/mcdi_mon.c | 2 - + drivers/net/ethernet/sfc/nic.c | 2 - + drivers/net/ethernet/sfc/siena/efx.c | 2 - + drivers/net/ethernet/sfc/siena/efx_common.c | 2 - + drivers/net/ethernet/sfc/siena/ethtool_common.c | 6 +-- + drivers/net/ethernet/sfc/siena/mcdi_mon.c | 2 - + drivers/net/ethernet/sfc/siena/nic.c | 2 - + drivers/net/ethernet/sgi/ioc3-eth.c | 6 +-- + drivers/net/ethernet/sis/sis190.c | 6 +-- + drivers/net/ethernet/sis/sis900.c | 6 +-- + drivers/net/ethernet/smsc/epic100.c | 6 +-- + drivers/net/ethernet/smsc/smc911x.c | 6 +-- + drivers/net/ethernet/smsc/smc91c92_cs.c | 4 +- + drivers/net/ethernet/smsc/smc91x.c | 6 +-- + drivers/net/ethernet/smsc/smsc911x.c | 6 +-- + drivers/net/ethernet/smsc/smsc9420.c | 6 +-- + drivers/net/ethernet/socionext/netsec.c | 4 +- + drivers/net/ethernet/socionext/sni_ave.c | 4 +- + drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 8 ++--- + drivers/net/ethernet/sun/cassini.c | 6 +-- + drivers/net/ethernet/sun/ldmvsw.c | 4 +- + drivers/net/ethernet/sun/niu.c | 6 +-- + drivers/net/ethernet/sun/sunbmac.c | 4 +- + drivers/net/ethernet/sun/sungem.c | 6 +-- + drivers/net/ethernet/sun/sunhme.c | 6 +-- + drivers/net/ethernet/sun/sunqe.c | 4 +- + drivers/net/ethernet/sun/sunvnet.c | 4 +- + drivers/net/ethernet/synopsys/dwc-xlgmac-common.c | 4 +- + drivers/net/ethernet/synopsys/dwc-xlgmac-ethtool.c | 6 +-- + drivers/net/ethernet/tehuti/tehuti.c | 8 ++--- + drivers/net/ethernet/ti/am65-cpsw-ethtool.c | 4 +- + drivers/net/ethernet/ti/cpmac.c | 4 +- + drivers/net/ethernet/ti/cpsw.c | 6 +-- + drivers/net/ethernet/ti/cpsw_new.c | 6 +-- + drivers/net/ethernet/ti/davinci_emac.c | 4 +- + drivers/net/ethernet/ti/tlan.c | 6 +-- + drivers/net/ethernet/toshiba/ps3_gelic_net.c | 4 +- + drivers/net/ethernet/toshiba/spider_net_ethtool.c | 8 ++--- + drivers/net/ethernet/toshiba/tc35815.c | 6 +-- + drivers/net/ethernet/via/via-rhine.c | 4 +- + drivers/net/ethernet/via/via-velocity.c | 8 ++--- + drivers/net/ethernet/wiznet/w5100.c | 6 +-- + drivers/net/ethernet/wiznet/w5300.c | 6 +-- + drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 4 +- + drivers/net/ethernet/xilinx/xilinx_emaclite.c | 2 - + drivers/net/ethernet/xircom/xirc2ps_cs.c | 2 - + drivers/net/ethernet/xscale/ixp4xx_eth.c | 4 +- + 199 files changed, 457 insertions(+), 457 deletions(-) + +--- a/drivers/net/ethernet/3com/3c509.c ++++ b/drivers/net/ethernet/3com/3c509.c +@@ -1136,7 +1136,7 @@ el3_netdev_set_ecmd(struct net_device *d + + static void el3_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); + } + + static int el3_get_link_ksettings(struct net_device *dev, +--- a/drivers/net/ethernet/3com/3c515.c ++++ b/drivers/net/ethernet/3com/3c515.c +@@ -1526,7 +1526,7 @@ static void set_rx_mode(struct net_devic + static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); + snprintf(info->bus_info, sizeof(info->bus_info), "ISA 0x%lx", + dev->base_addr); + } +--- a/drivers/net/ethernet/3com/3c589_cs.c ++++ b/drivers/net/ethernet/3com/3c589_cs.c +@@ -480,7 +480,7 @@ static void tc589_reset(struct net_devic + static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); + snprintf(info->bus_info, sizeof(info->bus_info), + "PCMCIA 0x%lx", dev->base_addr); + } +--- a/drivers/net/ethernet/3com/3c59x.c ++++ b/drivers/net/ethernet/3com/3c59x.c +@@ -2959,13 +2959,13 @@ static void vortex_get_drvinfo(struct ne + { + struct vortex_private *vp = netdev_priv(dev); + +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); + if (VORTEX_PCI(vp)) { +- strlcpy(info->bus_info, pci_name(VORTEX_PCI(vp)), ++ strscpy(info->bus_info, pci_name(VORTEX_PCI(vp)), + sizeof(info->bus_info)); + } else { + if (VORTEX_EISA(vp)) +- strlcpy(info->bus_info, dev_name(vp->gendev), ++ strscpy(info->bus_info, dev_name(vp->gendev), + sizeof(info->bus_info)); + else + snprintf(info->bus_info, sizeof(info->bus_info), +--- a/drivers/net/ethernet/3com/typhoon.c ++++ b/drivers/net/ethernet/3com/typhoon.c +@@ -974,12 +974,12 @@ typhoon_get_drvinfo(struct net_device *d + + smp_rmb(); + if (tp->card_state == Sleeping) { +- strlcpy(info->fw_version, "Sleep image", ++ strscpy(info->fw_version, "Sleep image", + sizeof(info->fw_version)); + } else { + INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_READ_VERSIONS); + if (typhoon_issue_command(tp, 1, &xp_cmd, 3, xp_resp) < 0) { +- strlcpy(info->fw_version, "Unknown runtime", ++ strscpy(info->fw_version, "Unknown runtime", + sizeof(info->fw_version)); + } else { + u32 sleep_ver = le32_to_cpu(xp_resp[0].parm2); +@@ -989,8 +989,8 @@ typhoon_get_drvinfo(struct net_device *d + } + } + +- strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); +- strlcpy(info->bus_info, pci_name(pci_dev), sizeof(info->bus_info)); ++ strscpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); ++ strscpy(info->bus_info, pci_name(pci_dev), sizeof(info->bus_info)); + } + + static int +--- a/drivers/net/ethernet/8390/ax88796.c ++++ b/drivers/net/ethernet/8390/ax88796.c +@@ -579,9 +579,9 @@ static void ax_get_drvinfo(struct net_de + { + struct platform_device *pdev = to_platform_device(dev->dev.parent); + +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->version, DRV_VERSION, sizeof(info->version)); +- strlcpy(info->bus_info, pdev->name, sizeof(info->bus_info)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->version, DRV_VERSION, sizeof(info->version)); ++ strscpy(info->bus_info, pdev->name, sizeof(info->bus_info)); + } + + static u32 ax_get_msglevel(struct net_device *dev) +--- a/drivers/net/ethernet/8390/etherh.c ++++ b/drivers/net/ethernet/8390/etherh.c +@@ -555,9 +555,9 @@ static int __init etherm_addr(char *addr + + static void etherh_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->version, DRV_VERSION, sizeof(info->version)); +- strlcpy(info->bus_info, dev_name(dev->dev.parent), ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->version, DRV_VERSION, sizeof(info->version)); ++ strscpy(info->bus_info, dev_name(dev->dev.parent), + sizeof(info->bus_info)); + } + +--- a/drivers/net/ethernet/adaptec/starfire.c ++++ b/drivers/net/ethernet/adaptec/starfire.c +@@ -1844,8 +1844,8 @@ static int check_if_running(struct net_d + static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) + { + struct netdev_private *np = netdev_priv(dev); +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->bus_info, pci_name(np->pci_dev), sizeof(info->bus_info)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->bus_info, pci_name(np->pci_dev), sizeof(info->bus_info)); + } + + static int get_link_ksettings(struct net_device *dev, +--- a/drivers/net/ethernet/aeroflex/greth.c ++++ b/drivers/net/ethernet/aeroflex/greth.c +@@ -1112,9 +1112,9 @@ static void greth_get_drvinfo(struct net + { + struct greth_private *greth = netdev_priv(dev); + +- strlcpy(info->driver, dev_driver_string(greth->dev), ++ strscpy(info->driver, dev_driver_string(greth->dev), + sizeof(info->driver)); +- strlcpy(info->bus_info, greth->dev->bus->name, sizeof(info->bus_info)); ++ strscpy(info->bus_info, greth->dev->bus->name, sizeof(info->bus_info)); + } + + static void greth_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) +--- a/drivers/net/ethernet/agere/et131x.c ++++ b/drivers/net/ethernet/agere/et131x.c +@@ -2953,8 +2953,8 @@ static void et131x_get_drvinfo(struct ne + { + struct et131x_adapter *adapter = netdev_priv(netdev); + +- strlcpy(info->driver, DRIVER_NAME, sizeof(info->driver)); +- strlcpy(info->bus_info, pci_name(adapter->pdev), ++ strscpy(info->driver, DRIVER_NAME, sizeof(info->driver)); ++ strscpy(info->bus_info, pci_name(adapter->pdev), + sizeof(info->bus_info)); + } + +--- a/drivers/net/ethernet/alacritech/slicoss.c ++++ b/drivers/net/ethernet/alacritech/slicoss.c +@@ -1531,8 +1531,8 @@ static void slic_get_drvinfo(struct net_ + { + struct slic_device *sdev = netdev_priv(dev); + +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->bus_info, pci_name(sdev->pdev), sizeof(info->bus_info)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->bus_info, pci_name(sdev->pdev), sizeof(info->bus_info)); + } + + static const struct ethtool_ops slic_ethtool_ops = { +--- a/drivers/net/ethernet/allwinner/sun4i-emac.c ++++ b/drivers/net/ethernet/allwinner/sun4i-emac.c +@@ -210,8 +210,8 @@ static void emac_inblk_32bit(void __iome + static void emac_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->bus_info, dev_name(&dev->dev), sizeof(info->bus_info)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->bus_info, dev_name(&dev->dev), sizeof(info->bus_info)); + } + + static u32 emac_get_msglevel(struct net_device *dev) +--- a/drivers/net/ethernet/alteon/acenic.c ++++ b/drivers/net/ethernet/alteon/acenic.c +@@ -2696,12 +2696,12 @@ static void ace_get_drvinfo(struct net_d + { + struct ace_private *ap = netdev_priv(dev); + +- strlcpy(info->driver, "acenic", sizeof(info->driver)); ++ strscpy(info->driver, "acenic", sizeof(info->driver)); + snprintf(info->fw_version, sizeof(info->version), "%i.%i.%i", + ap->firmware_major, ap->firmware_minor, ap->firmware_fix); + + if (ap->pdev) +- strlcpy(info->bus_info, pci_name(ap->pdev), ++ strscpy(info->bus_info, pci_name(ap->pdev), + sizeof(info->bus_info)); + + } +--- a/drivers/net/ethernet/amazon/ena/ena_ethtool.c ++++ b/drivers/net/ethernet/amazon/ena/ena_ethtool.c +@@ -459,8 +459,8 @@ static void ena_get_drvinfo(struct net_d + { + struct ena_adapter *adapter = netdev_priv(dev); + +- strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); +- strlcpy(info->bus_info, pci_name(adapter->pdev), ++ strscpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); ++ strscpy(info->bus_info, pci_name(adapter->pdev), + sizeof(info->bus_info)); + } + +--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -3179,7 +3179,7 @@ static void ena_config_host_info(struct + host_info->bdf = (pdev->bus->number << 8) | pdev->devfn; + host_info->os_type = ENA_ADMIN_OS_LINUX; + host_info->kernel_ver = LINUX_VERSION_CODE; +- strlcpy(host_info->kernel_ver_str, utsname()->version, ++ strscpy(host_info->kernel_ver_str, utsname()->version, + sizeof(host_info->kernel_ver_str) - 1); + host_info->os_dist = 0; + strncpy(host_info->os_dist_str, utsname()->release, +--- a/drivers/net/ethernet/amd/amd8111e.c ++++ b/drivers/net/ethernet/amd/amd8111e.c +@@ -1364,10 +1364,10 @@ static void amd8111e_get_drvinfo(struct + { + struct amd8111e_priv *lp = netdev_priv(dev); + struct pci_dev *pci_dev = lp->pci_dev; +- strlcpy(info->driver, MODULE_NAME, sizeof(info->driver)); ++ strscpy(info->driver, MODULE_NAME, sizeof(info->driver)); + snprintf(info->fw_version, sizeof(info->fw_version), + "%u", chip_version); +- strlcpy(info->bus_info, pci_name(pci_dev), sizeof(info->bus_info)); ++ strscpy(info->bus_info, pci_name(pci_dev), sizeof(info->bus_info)); + } + + static int amd8111e_get_regs_len(struct net_device *dev) +--- a/drivers/net/ethernet/amd/au1000_eth.c ++++ b/drivers/net/ethernet/amd/au1000_eth.c +@@ -650,7 +650,7 @@ au1000_get_drvinfo(struct net_device *de + { + struct au1000_private *aup = netdev_priv(dev); + +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); + snprintf(info->bus_info, sizeof(info->bus_info), "%s %d", DRV_NAME, + aup->mac_id); + } +--- a/drivers/net/ethernet/amd/nmclan_cs.c ++++ b/drivers/net/ethernet/amd/nmclan_cs.c +@@ -815,7 +815,7 @@ static int mace_close(struct net_device + static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); + snprintf(info->bus_info, sizeof(info->bus_info), + "PCMCIA 0x%lx", dev->base_addr); + } +--- a/drivers/net/ethernet/amd/pcnet32.c ++++ b/drivers/net/ethernet/amd/pcnet32.c +@@ -797,9 +797,9 @@ static void pcnet32_get_drvinfo(struct n + { + struct pcnet32_private *lp = netdev_priv(dev); + +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); + if (lp->pci_dev) +- strlcpy(info->bus_info, pci_name(lp->pci_dev), ++ strscpy(info->bus_info, pci_name(lp->pci_dev), + sizeof(info->bus_info)); + else + snprintf(info->bus_info, sizeof(info->bus_info), +--- a/drivers/net/ethernet/amd/sunlance.c ++++ b/drivers/net/ethernet/amd/sunlance.c +@@ -1276,7 +1276,7 @@ static void lance_free_hwresources(struc + /* Ethtool support... */ + static void sparc_lance_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, "sunlance", sizeof(info->driver)); ++ strscpy(info->driver, "sunlance", sizeof(info->driver)); + } + + static const struct ethtool_ops sparc_lance_ethtool_ops = { +--- a/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c ++++ b/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c +@@ -404,8 +404,8 @@ static void xgbe_get_drvinfo(struct net_ + struct xgbe_prv_data *pdata = netdev_priv(netdev); + struct xgbe_hw_features *hw_feat = &pdata->hw_feat; + +- strlcpy(drvinfo->driver, XGBE_DRV_NAME, sizeof(drvinfo->driver)); +- strlcpy(drvinfo->bus_info, dev_name(pdata->dev), ++ strscpy(drvinfo->driver, XGBE_DRV_NAME, sizeof(drvinfo->driver)); ++ strscpy(drvinfo->bus_info, dev_name(pdata->dev), + sizeof(drvinfo->bus_info)); + snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), "%d.%d.%d", + XGMAC_GET_BITS(hw_feat->version, MAC_VR, USERVER), +--- a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c ++++ b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c +@@ -229,7 +229,7 @@ static void aq_ethtool_get_drvinfo(struc + "%u.%u.%u", firmware_version >> 24, + (firmware_version >> 16) & 0xFFU, firmware_version & 0xFFFFU); + +- strlcpy(drvinfo->bus_info, pdev ? pci_name(pdev) : "", ++ strscpy(drvinfo->bus_info, pdev ? pci_name(pdev) : "", + sizeof(drvinfo->bus_info)); + drvinfo->n_stats = aq_ethtool_n_stats(ndev); + drvinfo->testinfo_len = 0; +--- a/drivers/net/ethernet/arc/emac_main.c ++++ b/drivers/net/ethernet/arc/emac_main.c +@@ -91,7 +91,7 @@ static void arc_emac_get_drvinfo(struct + { + struct arc_emac_priv *priv = netdev_priv(ndev); + +- strlcpy(info->driver, priv->drv_name, sizeof(info->driver)); ++ strscpy(info->driver, priv->drv_name, sizeof(info->driver)); + } + + static const struct ethtool_ops arc_emac_ethtool_ops = { +--- a/drivers/net/ethernet/atheros/ag71xx.c ++++ b/drivers/net/ethernet/atheros/ag71xx.c +@@ -451,8 +451,8 @@ static void ag71xx_get_drvinfo(struct ne + { + struct ag71xx *ag = netdev_priv(ndev); + +- strlcpy(info->driver, "ag71xx", sizeof(info->driver)); +- strlcpy(info->bus_info, of_node_full_name(ag->pdev->dev.of_node), ++ strscpy(info->driver, "ag71xx", sizeof(info->driver)); ++ strscpy(info->bus_info, of_node_full_name(ag->pdev->dev.of_node), + sizeof(info->bus_info)); + } + +--- a/drivers/net/ethernet/atheros/atl1c/atl1c_ethtool.c ++++ b/drivers/net/ethernet/atheros/atl1c/atl1c_ethtool.c +@@ -220,8 +220,8 @@ static void atl1c_get_drvinfo(struct net + { + struct atl1c_adapter *adapter = netdev_priv(netdev); + +- strlcpy(drvinfo->driver, atl1c_driver_name, sizeof(drvinfo->driver)); +- strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), ++ strscpy(drvinfo->driver, atl1c_driver_name, sizeof(drvinfo->driver)); ++ strscpy(drvinfo->bus_info, pci_name(adapter->pdev), + sizeof(drvinfo->bus_info)); + } + +--- a/drivers/net/ethernet/atheros/atl1e/atl1e_ethtool.c ++++ b/drivers/net/ethernet/atheros/atl1e/atl1e_ethtool.c +@@ -306,9 +306,9 @@ static void atl1e_get_drvinfo(struct net + { + struct atl1e_adapter *adapter = netdev_priv(netdev); + +- strlcpy(drvinfo->driver, atl1e_driver_name, sizeof(drvinfo->driver)); +- strlcpy(drvinfo->fw_version, "L1e", sizeof(drvinfo->fw_version)); +- strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), ++ strscpy(drvinfo->driver, atl1e_driver_name, sizeof(drvinfo->driver)); ++ strscpy(drvinfo->fw_version, "L1e", sizeof(drvinfo->fw_version)); ++ strscpy(drvinfo->bus_info, pci_name(adapter->pdev), + sizeof(drvinfo->bus_info)); + } + +--- a/drivers/net/ethernet/atheros/atlx/atl1.c ++++ b/drivers/net/ethernet/atheros/atlx/atl1.c +@@ -3340,8 +3340,8 @@ static void atl1_get_drvinfo(struct net_ + { + struct atl1_adapter *adapter = netdev_priv(netdev); + +- strlcpy(drvinfo->driver, ATLX_DRIVER_NAME, sizeof(drvinfo->driver)); +- strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), ++ strscpy(drvinfo->driver, ATLX_DRIVER_NAME, sizeof(drvinfo->driver)); ++ strscpy(drvinfo->bus_info, pci_name(adapter->pdev), + sizeof(drvinfo->bus_info)); + } + +--- a/drivers/net/ethernet/atheros/atlx/atl2.c ++++ b/drivers/net/ethernet/atheros/atlx/atl2.c +@@ -1980,9 +1980,9 @@ static void atl2_get_drvinfo(struct net_ + { + struct atl2_adapter *adapter = netdev_priv(netdev); + +- strlcpy(drvinfo->driver, atl2_driver_name, sizeof(drvinfo->driver)); +- strlcpy(drvinfo->fw_version, "L2", sizeof(drvinfo->fw_version)); +- strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), ++ strscpy(drvinfo->driver, atl2_driver_name, sizeof(drvinfo->driver)); ++ strscpy(drvinfo->fw_version, "L2", sizeof(drvinfo->fw_version)); ++ strscpy(drvinfo->bus_info, pci_name(adapter->pdev), + sizeof(drvinfo->bus_info)); + } + +--- a/drivers/net/ethernet/broadcom/b44.c ++++ b/drivers/net/ethernet/broadcom/b44.c +@@ -1790,13 +1790,13 @@ static void b44_get_drvinfo (struct net_ + struct b44 *bp = netdev_priv(dev); + struct ssb_bus *bus = bp->sdev->bus; + +- strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); ++ strscpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); + switch (bus->bustype) { + case SSB_BUSTYPE_PCI: +- strlcpy(info->bus_info, pci_name(bus->host_pci), sizeof(info->bus_info)); ++ strscpy(info->bus_info, pci_name(bus->host_pci), sizeof(info->bus_info)); + break; + case SSB_BUSTYPE_SSB: +- strlcpy(info->bus_info, "SSB", sizeof(info->bus_info)); ++ strscpy(info->bus_info, "SSB", sizeof(info->bus_info)); + break; + case SSB_BUSTYPE_PCMCIA: + case SSB_BUSTYPE_SDIO: +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c +@@ -1321,8 +1321,8 @@ static const u32 unused_mib_regs[] = { + static void bcm_enet_get_drvinfo(struct net_device *netdev, + struct ethtool_drvinfo *drvinfo) + { +- strlcpy(drvinfo->driver, bcm_enet_driver_name, sizeof(drvinfo->driver)); +- strlcpy(drvinfo->bus_info, "bcm63xx", sizeof(drvinfo->bus_info)); ++ strscpy(drvinfo->driver, bcm_enet_driver_name, sizeof(drvinfo->driver)); ++ strscpy(drvinfo->bus_info, "bcm63xx", sizeof(drvinfo->bus_info)); + } + + static int bcm_enet_get_sset_count(struct net_device *netdev, +--- a/drivers/net/ethernet/broadcom/bcmsysport.c ++++ b/drivers/net/ethernet/broadcom/bcmsysport.c +@@ -308,8 +308,8 @@ static const struct bcm_sysport_stats bc + static void bcm_sysport_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); +- strlcpy(info->bus_info, "platform", sizeof(info->bus_info)); ++ strscpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); ++ strscpy(info->bus_info, "platform", sizeof(info->bus_info)); + } + + static u32 bcm_sysport_get_msglvl(struct net_device *dev) +--- a/drivers/net/ethernet/broadcom/bgmac.c ++++ b/drivers/net/ethernet/broadcom/bgmac.c +@@ -1367,7 +1367,7 @@ static void bgmac_get_strings(struct net + return; + + for (i = 0; i < BGMAC_STATS_LEN; i++) +- strlcpy(data + i * ETH_GSTRING_LEN, ++ strscpy(data + i * ETH_GSTRING_LEN, + bgmac_get_strings_stats[i].name, ETH_GSTRING_LEN); + } + +@@ -1395,8 +1395,8 @@ static void bgmac_get_ethtool_stats(stru + static void bgmac_get_drvinfo(struct net_device *net_dev, + struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); +- strlcpy(info->bus_info, "AXI", sizeof(info->bus_info)); ++ strscpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); ++ strscpy(info->bus_info, "AXI", sizeof(info->bus_info)); + } + + static const struct ethtool_ops bgmac_ethtool_ops = { +--- a/drivers/net/ethernet/broadcom/bnx2.c ++++ b/drivers/net/ethernet/broadcom/bnx2.c +@@ -7042,9 +7042,9 @@ bnx2_get_drvinfo(struct net_device *dev, + { + struct bnx2 *bp = netdev_priv(dev); + +- strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); +- strlcpy(info->bus_info, pci_name(bp->pdev), sizeof(info->bus_info)); +- strlcpy(info->fw_version, bp->fw_version, sizeof(info->fw_version)); ++ strscpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); ++ strscpy(info->bus_info, pci_name(bp->pdev), sizeof(info->bus_info)); ++ strscpy(info->fw_version, bp->fw_version, sizeof(info->fw_version)); + } + + #define BNX2_REGDUMP_LEN (32 * 1024) +--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c ++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +@@ -150,7 +150,7 @@ void bnx2x_fill_fw_str(struct bnx2x *bp, + phy_fw_ver[0] = '\0'; + bnx2x_get_ext_phy_fw_version(&bp->link_params, + phy_fw_ver, PHY_FW_VER_LEN); +- strlcpy(buf, bp->fw_ver, buf_len); ++ strscpy(buf, bp->fw_ver, buf_len); + snprintf(buf + strlen(bp->fw_ver), 32 - strlen(bp->fw_ver), + "bc %d.%d.%d%s%s", + (bp->common.bc_ver & 0xff0000) >> 16, +--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c ++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +@@ -1112,7 +1112,7 @@ static void bnx2x_get_drvinfo(struct net + int ext_dev_info_offset; + u32 mbi; + +- strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); ++ strscpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); + + if (SHMEM2_HAS(bp, extended_dev_info_shared_addr)) { + ext_dev_info_offset = SHMEM2_RD(bp, +@@ -1126,7 +1126,7 @@ static void bnx2x_get_drvinfo(struct net + (mbi & 0xff000000) >> 24, + (mbi & 0x00ff0000) >> 16, + (mbi & 0x0000ff00) >> 8); +- strlcpy(info->fw_version, version, ++ strscpy(info->fw_version, version, + sizeof(info->fw_version)); + } + } +@@ -1135,7 +1135,7 @@ static void bnx2x_get_drvinfo(struct net + bnx2x_fill_fw_str(bp, version, ETHTOOL_FWVERS_LEN); + strlcat(info->fw_version, version, sizeof(info->fw_version)); + +- strlcpy(info->bus_info, pci_name(bp->pdev), sizeof(info->bus_info)); ++ strscpy(info->bus_info, pci_name(bp->pdev), sizeof(info->bus_info)); + } + + static void bnx2x_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) +--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c ++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +@@ -3385,7 +3385,7 @@ static void bnx2x_drv_info_ether_stat(st + &bp->sp_objs->mac_obj; + int i; + +- strlcpy(ether_stat->version, DRV_MODULE_VERSION, ++ strscpy(ether_stat->version, DRV_MODULE_VERSION, + ETH_STAT_INFO_VERSION_LEN); + + /* get DRV_INFO_ETH_STAT_NUM_MACS_REQUIRED macs, placing them in the +--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h ++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h +@@ -518,7 +518,7 @@ int bnx2x_vfpf_storm_rx_mode(struct bnx2 + static inline void bnx2x_vf_fill_fw_str(struct bnx2x *bp, char *buf, + size_t buf_len) + { +- strlcpy(buf, bp->acquire_resp.pfdev_info.fw_ver, buf_len); ++ strscpy(buf, bp->acquire_resp.pfdev_info.fw_ver, buf_len); + } + + static inline int bnx2x_vf_ustorm_prods_offset(struct bnx2x *bp, +--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c ++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c +@@ -380,7 +380,7 @@ int bnx2x_vfpf_acquire(struct bnx2x *bp, + bp->igu_base_sb = bp->acquire_resp.resc.hw_sbs[0].hw_sb_id; + bp->vlan_credit = bp->acquire_resp.resc.num_vlan_filters; + +- strlcpy(bp->fw_ver, bp->acquire_resp.pfdev_info.fw_ver, ++ strscpy(bp->fw_ver, bp->acquire_resp.pfdev_info.fw_ver, + sizeof(bp->fw_ver)); + + if (is_valid_ether_addr(bp->acquire_resp.resc.current_mac_addr)) +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +@@ -1370,9 +1370,9 @@ static void bnxt_get_drvinfo(struct net_ + { + struct bnxt *bp = netdev_priv(dev); + +- strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); +- strlcpy(info->fw_version, bp->fw_ver_str, sizeof(info->fw_version)); +- strlcpy(info->bus_info, pci_name(bp->pdev), sizeof(info->bus_info)); ++ strscpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); ++ strscpy(info->fw_version, bp->fw_ver_str, sizeof(info->fw_version)); ++ strscpy(info->bus_info, pci_name(bp->pdev), sizeof(info->bus_info)); + info->n_stats = bnxt_get_num_stats(bp); + info->testinfo_len = bp->num_tests; + /* TODO CHIMP_FW: eeprom dump details */ +@@ -3870,7 +3870,7 @@ void bnxt_ethtool_init(struct bnxt *bp) + } else if (i == BNXT_IRQ_TEST_IDX) { + strcpy(str, "Interrupt_test (offline)"); + } else { +- strlcpy(str, fw_str, ETH_GSTRING_LEN); ++ strscpy(str, fw_str, ETH_GSTRING_LEN); + strncat(str, " test", ETH_GSTRING_LEN - strlen(str)); + if (test_info->offline_mask & (1 << i)) + strncat(str, " (offline)", +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c +@@ -222,7 +222,7 @@ static int bnxt_vf_rep_get_phys_port_nam + static void bnxt_vf_rep_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); ++ strscpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); + } + + static int bnxt_vf_rep_get_port_parent_id(struct net_device *dev, +--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c ++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c +@@ -1104,7 +1104,7 @@ static const struct bcmgenet_stats bcmge + static void bcmgenet_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, "bcmgenet", sizeof(info->driver)); ++ strscpy(info->driver, "bcmgenet", sizeof(info->driver)); + } + + static int bcmgenet_get_sset_count(struct net_device *dev, int string_set) +--- a/drivers/net/ethernet/broadcom/tg3.c ++++ b/drivers/net/ethernet/broadcom/tg3.c +@@ -12302,9 +12302,9 @@ static void tg3_get_drvinfo(struct net_d + { + struct tg3 *tp = netdev_priv(dev); + +- strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); +- strlcpy(info->fw_version, tp->fw_ver, sizeof(info->fw_version)); +- strlcpy(info->bus_info, pci_name(tp->pdev), sizeof(info->bus_info)); ++ strscpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); ++ strscpy(info->fw_version, tp->fw_ver, sizeof(info->fw_version)); ++ strscpy(info->bus_info, pci_name(tp->pdev), sizeof(info->bus_info)); + } + + static void tg3_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) +--- a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c ++++ b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c +@@ -283,7 +283,7 @@ bnad_get_drvinfo(struct net_device *netd + struct bfa_ioc_attr *ioc_attr; + unsigned long flags; + +- strlcpy(drvinfo->driver, BNAD_NAME, sizeof(drvinfo->driver)); ++ strscpy(drvinfo->driver, BNAD_NAME, sizeof(drvinfo->driver)); + + ioc_attr = kzalloc(sizeof(*ioc_attr), GFP_KERNEL); + if (ioc_attr) { +@@ -291,12 +291,12 @@ bnad_get_drvinfo(struct net_device *netd + bfa_nw_ioc_get_attr(&bnad->bna.ioceth.ioc, ioc_attr); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + +- strlcpy(drvinfo->fw_version, ioc_attr->adapter_attr.fw_ver, ++ strscpy(drvinfo->fw_version, ioc_attr->adapter_attr.fw_ver, + sizeof(drvinfo->fw_version)); + kfree(ioc_attr); + } + +- strlcpy(drvinfo->bus_info, pci_name(bnad->pcidev), ++ strscpy(drvinfo->bus_info, pci_name(bnad->pcidev), + sizeof(drvinfo->bus_info)); + } + +--- a/drivers/net/ethernet/cavium/octeon/octeon_mgmt.c ++++ b/drivers/net/ethernet/cavium/octeon/octeon_mgmt.c +@@ -1345,7 +1345,7 @@ static void octeon_mgmt_poll_controller( + static void octeon_mgmt_get_drvinfo(struct net_device *netdev, + struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); + } + + static int octeon_mgmt_nway_reset(struct net_device *dev) +--- a/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c ++++ b/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c +@@ -191,8 +191,8 @@ static void nicvf_get_drvinfo(struct net + { + struct nicvf *nic = netdev_priv(netdev); + +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->bus_info, pci_name(nic->pdev), sizeof(info->bus_info)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->bus_info, pci_name(nic->pdev), sizeof(info->bus_info)); + } + + static u32 nicvf_get_msglevel(struct net_device *netdev) +--- a/drivers/net/ethernet/chelsio/cxgb/cxgb2.c ++++ b/drivers/net/ethernet/chelsio/cxgb/cxgb2.c +@@ -429,8 +429,8 @@ static void get_drvinfo(struct net_devic + { + struct adapter *adapter = dev->ml_priv; + +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->bus_info, pci_name(adapter->pdev), ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->bus_info, pci_name(adapter->pdev), + sizeof(info->bus_info)); + } + +--- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c ++++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c +@@ -1627,8 +1627,8 @@ static void get_drvinfo(struct net_devic + t3_get_tp_version(adapter, &tp_vers); + spin_unlock(&adapter->stats_lock); + +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->bus_info, pci_name(adapter->pdev), ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->bus_info, pci_name(adapter->pdev), + sizeof(info->bus_info)); + if (fw_vers) + snprintf(info->fw_version, sizeof(info->fw_version), +--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c +@@ -199,8 +199,8 @@ static void get_drvinfo(struct net_devic + struct adapter *adapter = netdev2adap(dev); + u32 exprom_vers; + +- strlcpy(info->driver, cxgb4_driver_name, sizeof(info->driver)); +- strlcpy(info->bus_info, pci_name(adapter->pdev), ++ strscpy(info->driver, cxgb4_driver_name, sizeof(info->driver)); ++ strscpy(info->bus_info, pci_name(adapter->pdev), + sizeof(info->bus_info)); + info->regdump_len = get_regs_len(dev); + +--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +@@ -3903,8 +3903,8 @@ static void cxgb4_mgmt_get_drvinfo(struc + { + struct adapter *adapter = netdev2adap(dev); + +- strlcpy(info->driver, cxgb4_driver_name, sizeof(info->driver)); +- strlcpy(info->bus_info, pci_name(adapter->pdev), ++ strscpy(info->driver, cxgb4_driver_name, sizeof(info->driver)); ++ strscpy(info->bus_info, pci_name(adapter->pdev), + sizeof(info->bus_info)); + } + +--- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c ++++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +@@ -1553,8 +1553,8 @@ static void cxgb4vf_get_drvinfo(struct n + { + struct adapter *adapter = netdev2adap(dev); + +- strlcpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver)); +- strlcpy(drvinfo->bus_info, pci_name(to_pci_dev(dev->dev.parent)), ++ strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver)); ++ strscpy(drvinfo->bus_info, pci_name(to_pci_dev(dev->dev.parent)), + sizeof(drvinfo->bus_info)); + snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), + "%u.%u.%u.%u, TP %u.%u.%u.%u", +--- a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_main.c ++++ b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_main.c +@@ -193,7 +193,7 @@ static void chtls_register_dev(struct ch + { + struct tls_toe_device *tlsdev = &cdev->tlsdev; + +- strlcpy(tlsdev->name, "chtls", TLS_TOE_DEVICE_NAME_MAX); ++ strscpy(tlsdev->name, "chtls", TLS_TOE_DEVICE_NAME_MAX); + strlcat(tlsdev->name, cdev->lldi->ports[0]->name, + TLS_TOE_DEVICE_NAME_MAX); + tlsdev->feature = chtls_inline_feature; +--- a/drivers/net/ethernet/cirrus/ep93xx_eth.c ++++ b/drivers/net/ethernet/cirrus/ep93xx_eth.c +@@ -689,7 +689,7 @@ static int ep93xx_ioctl(struct net_devic + + static void ep93xx_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); ++ strscpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); + } + + static int ep93xx_get_link_ksettings(struct net_device *dev, +--- a/drivers/net/ethernet/cisco/enic/enic_ethtool.c ++++ b/drivers/net/ethernet/cisco/enic/enic_ethtool.c +@@ -146,10 +146,10 @@ static void enic_get_drvinfo(struct net_ + if (err == -ENOMEM) + return; + +- strlcpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver)); +- strlcpy(drvinfo->fw_version, fw_info->fw_version, ++ strscpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver)); ++ strscpy(drvinfo->fw_version, fw_info->fw_version, + sizeof(drvinfo->fw_version)); +- strlcpy(drvinfo->bus_info, pci_name(enic->pdev), ++ strscpy(drvinfo->bus_info, pci_name(enic->pdev), + sizeof(drvinfo->bus_info)); + } + +--- a/drivers/net/ethernet/davicom/dm9000.c ++++ b/drivers/net/ethernet/davicom/dm9000.c +@@ -540,8 +540,8 @@ static void dm9000_get_drvinfo(struct ne + { + struct board_info *dm = to_dm9000_board(dev); + +- strlcpy(info->driver, CARDNAME, sizeof(info->driver)); +- strlcpy(info->bus_info, to_platform_device(dm->dev)->name, ++ strscpy(info->driver, CARDNAME, sizeof(info->driver)); ++ strscpy(info->bus_info, to_platform_device(dm->dev)->name, + sizeof(info->bus_info)); + } + +--- a/drivers/net/ethernet/dec/tulip/de2104x.c ++++ b/drivers/net/ethernet/dec/tulip/de2104x.c +@@ -1606,8 +1606,8 @@ static void de_get_drvinfo (struct net_d + { + struct de_private *de = netdev_priv(dev); + +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->bus_info, pci_name(de->pdev), sizeof(info->bus_info)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->bus_info, pci_name(de->pdev), sizeof(info->bus_info)); + } + + static int de_get_regs_len(struct net_device *dev) +--- a/drivers/net/ethernet/dec/tulip/dmfe.c ++++ b/drivers/net/ethernet/dec/tulip/dmfe.c +@@ -1074,8 +1074,8 @@ static void dmfe_ethtool_get_drvinfo(str + { + struct dmfe_board_info *np = netdev_priv(dev); + +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->bus_info, pci_name(np->pdev), sizeof(info->bus_info)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->bus_info, pci_name(np->pdev), sizeof(info->bus_info)); + } + + static int dmfe_ethtool_set_wol(struct net_device *dev, +--- a/drivers/net/ethernet/dec/tulip/tulip_core.c ++++ b/drivers/net/ethernet/dec/tulip/tulip_core.c +@@ -858,8 +858,8 @@ static struct net_device_stats *tulip_ge + static void tulip_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) + { + struct tulip_private *np = netdev_priv(dev); +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->bus_info, pci_name(np->pdev), sizeof(info->bus_info)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->bus_info, pci_name(np->pdev), sizeof(info->bus_info)); + } + + +--- a/drivers/net/ethernet/dec/tulip/uli526x.c ++++ b/drivers/net/ethernet/dec/tulip/uli526x.c +@@ -971,8 +971,8 @@ static void netdev_get_drvinfo(struct ne + { + struct uli526x_board_info *np = netdev_priv(dev); + +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->bus_info, pci_name(np->pdev), sizeof(info->bus_info)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->bus_info, pci_name(np->pdev), sizeof(info->bus_info)); + } + + static int netdev_get_link_ksettings(struct net_device *dev, +--- a/drivers/net/ethernet/dec/tulip/winbond-840.c ++++ b/drivers/net/ethernet/dec/tulip/winbond-840.c +@@ -1376,8 +1376,8 @@ static void netdev_get_drvinfo (struct n + { + struct netdev_private *np = netdev_priv(dev); + +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->bus_info, pci_name(np->pci_dev), sizeof(info->bus_info)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->bus_info, pci_name(np->pci_dev), sizeof(info->bus_info)); + } + + static int netdev_get_link_ksettings(struct net_device *dev, +--- a/drivers/net/ethernet/dlink/dl2k.c ++++ b/drivers/net/ethernet/dlink/dl2k.c +@@ -1235,8 +1235,8 @@ static void rio_get_drvinfo(struct net_d + { + struct netdev_private *np = netdev_priv(dev); + +- strlcpy(info->driver, "dl2k", sizeof(info->driver)); +- strlcpy(info->bus_info, pci_name(np->pdev), sizeof(info->bus_info)); ++ strscpy(info->driver, "dl2k", sizeof(info->driver)); ++ strscpy(info->bus_info, pci_name(np->pdev), sizeof(info->bus_info)); + } + + static int rio_get_link_ksettings(struct net_device *dev, +--- a/drivers/net/ethernet/dlink/sundance.c ++++ b/drivers/net/ethernet/dlink/sundance.c +@@ -1644,8 +1644,8 @@ static int check_if_running(struct net_d + static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) + { + struct netdev_private *np = netdev_priv(dev); +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->bus_info, pci_name(np->pci_dev), sizeof(info->bus_info)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->bus_info, pci_name(np->pci_dev), sizeof(info->bus_info)); + } + + static int get_link_ksettings(struct net_device *dev, +--- a/drivers/net/ethernet/dnet.c ++++ b/drivers/net/ethernet/dnet.c +@@ -725,8 +725,8 @@ static struct net_device_stats *dnet_get + static void dnet_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->bus_info, "0", sizeof(info->bus_info)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->bus_info, "0", sizeof(info->bus_info)); + } + + static const struct ethtool_ops dnet_ethtool_ops = { +--- a/drivers/net/ethernet/emulex/benet/be_cmds.c ++++ b/drivers/net/ethernet/emulex/benet/be_cmds.c +@@ -1878,9 +1878,9 @@ int be_cmd_get_fw_ver(struct be_adapter + if (!status) { + struct be_cmd_resp_get_fw_version *resp = embedded_payload(wrb); + +- strlcpy(adapter->fw_ver, resp->firmware_version_string, ++ strscpy(adapter->fw_ver, resp->firmware_version_string, + sizeof(adapter->fw_ver)); +- strlcpy(adapter->fw_on_flash, resp->fw_on_flash_version_string, ++ strscpy(adapter->fw_on_flash, resp->fw_on_flash_version_string, + sizeof(adapter->fw_on_flash)); + } + err: +@@ -2373,7 +2373,7 @@ static int lancer_cmd_write_object(struc + + be_dws_cpu_to_le(ctxt, sizeof(req->context)); + req->write_offset = cpu_to_le32(data_offset); +- strlcpy(req->object_name, obj_name, sizeof(req->object_name)); ++ strscpy(req->object_name, obj_name, sizeof(req->object_name)); + req->descriptor_count = cpu_to_le32(1); + req->buf_len = cpu_to_le32(data_size); + req->addr_low = cpu_to_le32((cmd->dma + +@@ -2442,9 +2442,9 @@ int be_cmd_query_sfp_info(struct be_adap + status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0, + 0, PAGE_DATA_LEN, page_data); + if (!status) { +- strlcpy(adapter->phy.vendor_name, page_data + ++ strscpy(adapter->phy.vendor_name, page_data + + SFP_VENDOR_NAME_OFFSET, SFP_VENDOR_NAME_LEN - 1); +- strlcpy(adapter->phy.vendor_pn, ++ strscpy(adapter->phy.vendor_pn, + page_data + SFP_VENDOR_PN_OFFSET, + SFP_VENDOR_NAME_LEN - 1); + } +@@ -2473,7 +2473,7 @@ static int lancer_cmd_delete_object(stru + OPCODE_COMMON_DELETE_OBJECT, + sizeof(*req), wrb, NULL); + +- strlcpy(req->object_name, obj_name, sizeof(req->object_name)); ++ strscpy(req->object_name, obj_name, sizeof(req->object_name)); + + status = be_mcc_notify_wait(adapter); + err: +--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c ++++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c +@@ -220,15 +220,15 @@ static void be_get_drvinfo(struct net_de + { + struct be_adapter *adapter = netdev_priv(netdev); + +- strlcpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver)); ++ strscpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver)); + if (!memcmp(adapter->fw_ver, adapter->fw_on_flash, FW_VER_LEN)) +- strlcpy(drvinfo->fw_version, adapter->fw_ver, ++ strscpy(drvinfo->fw_version, adapter->fw_ver, + sizeof(drvinfo->fw_version)); + else + snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), + "%s [%s]", adapter->fw_ver, adapter->fw_on_flash); + +- strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), ++ strscpy(drvinfo->bus_info, pci_name(adapter->pdev), + sizeof(drvinfo->bus_info)); + } + +--- a/drivers/net/ethernet/faraday/ftgmac100.c ++++ b/drivers/net/ethernet/faraday/ftgmac100.c +@@ -1175,8 +1175,8 @@ static int ftgmac100_mdiobus_write(struc + static void ftgmac100_get_drvinfo(struct net_device *netdev, + struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->bus_info, dev_name(&netdev->dev), sizeof(info->bus_info)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->bus_info, dev_name(&netdev->dev), sizeof(info->bus_info)); + } + + static void +--- a/drivers/net/ethernet/faraday/ftmac100.c ++++ b/drivers/net/ethernet/faraday/ftmac100.c +@@ -807,8 +807,8 @@ static void ftmac100_mdio_write(struct n + static void ftmac100_get_drvinfo(struct net_device *netdev, + struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->bus_info, dev_name(&netdev->dev), sizeof(info->bus_info)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->bus_info, dev_name(&netdev->dev), sizeof(info->bus_info)); + } + + static int ftmac100_get_link_ksettings(struct net_device *netdev, +--- a/drivers/net/ethernet/fealnx.c ++++ b/drivers/net/ethernet/fealnx.c +@@ -1809,8 +1809,8 @@ static void netdev_get_drvinfo(struct ne + { + struct netdev_private *np = netdev_priv(dev); + +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->bus_info, pci_name(np->pci_dev), sizeof(info->bus_info)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->bus_info, pci_name(np->pci_dev), sizeof(info->bus_info)); + } + + static int netdev_get_link_ksettings(struct net_device *dev, +--- a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c ++++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c +@@ -106,9 +106,9 @@ static int dpaa_set_link_ksettings(struc + static void dpaa_get_drvinfo(struct net_device *net_dev, + struct ethtool_drvinfo *drvinfo) + { +- strlcpy(drvinfo->driver, KBUILD_MODNAME, ++ strscpy(drvinfo->driver, KBUILD_MODNAME, + sizeof(drvinfo->driver)); +- strlcpy(drvinfo->bus_info, dev_name(net_dev->dev.parent->parent), ++ strscpy(drvinfo->bus_info, dev_name(net_dev->dev.parent->parent), + sizeof(drvinfo->bus_info)); + } + +--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c ++++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c +@@ -463,7 +463,7 @@ void dpaa2_mac_get_strings(u8 *data) + int i; + + for (i = 0; i < DPAA2_MAC_NUM_STATS; i++) { +- strlcpy(p, dpaa2_mac_ethtool_stats[i], ETH_GSTRING_LEN); ++ strscpy(p, dpaa2_mac_ethtool_stats[i], ETH_GSTRING_LEN); + p += ETH_GSTRING_LEN; + } + } +--- a/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c ++++ b/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c +@@ -235,7 +235,7 @@ static void enetc_get_strings(struct net + switch (stringset) { + case ETH_SS_STATS: + for (i = 0; i < ARRAY_SIZE(enetc_si_counters); i++) { +- strlcpy(p, enetc_si_counters[i].name, ETH_GSTRING_LEN); ++ strscpy(p, enetc_si_counters[i].name, ETH_GSTRING_LEN); + p += ETH_GSTRING_LEN; + } + for (i = 0; i < priv->num_tx_rings; i++) { +@@ -257,7 +257,7 @@ static void enetc_get_strings(struct net + break; + + for (i = 0; i < ARRAY_SIZE(enetc_port_counters); i++) { +- strlcpy(p, enetc_port_counters[i].name, ++ strscpy(p, enetc_port_counters[i].name, + ETH_GSTRING_LEN); + p += ETH_GSTRING_LEN; + } +--- a/drivers/net/ethernet/freescale/fec_main.c ++++ b/drivers/net/ethernet/freescale/fec_main.c +@@ -2018,13 +2018,13 @@ static int fec_enet_mii_probe(struct net + continue; + if (dev_id--) + continue; +- strlcpy(mdio_bus_id, fep->mii_bus->id, MII_BUS_ID_SIZE); ++ strscpy(mdio_bus_id, fep->mii_bus->id, MII_BUS_ID_SIZE); + break; + } + + if (phy_id >= PHY_MAX_ADDR) { + netdev_info(ndev, "no PHY, assuming direct connection to switch\n"); +- strlcpy(mdio_bus_id, "fixed-0", MII_BUS_ID_SIZE); ++ strscpy(mdio_bus_id, "fixed-0", MII_BUS_ID_SIZE); + phy_id = 0; + } + +@@ -2208,9 +2208,9 @@ static void fec_enet_get_drvinfo(struct + { + struct fec_enet_private *fep = netdev_priv(ndev); + +- strlcpy(info->driver, fep->pdev->dev.driver->name, ++ strscpy(info->driver, fep->pdev->dev.driver->name, + sizeof(info->driver)); +- strlcpy(info->bus_info, dev_name(&ndev->dev), sizeof(info->bus_info)); ++ strscpy(info->bus_info, dev_name(&ndev->dev), sizeof(info->bus_info)); + } + + static int fec_enet_get_regs_len(struct net_device *ndev) +--- a/drivers/net/ethernet/freescale/fec_ptp.c ++++ b/drivers/net/ethernet/freescale/fec_ptp.c +@@ -587,7 +587,7 @@ void fec_ptp_init(struct platform_device + int ret; + + fep->ptp_caps.owner = THIS_MODULE; +- strlcpy(fep->ptp_caps.name, "fec ptp", sizeof(fep->ptp_caps.name)); ++ strscpy(fep->ptp_caps.name, "fec ptp", sizeof(fep->ptp_caps.name)); + + fep->ptp_caps.max_adj = 250000000; + fep->ptp_caps.n_alarm = 0; +--- a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c ++++ b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c +@@ -791,7 +791,7 @@ static int fs_enet_close(struct net_devi + static void fs_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); ++ strscpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); + } + + static int fs_get_regs_len(struct net_device *dev) +--- a/drivers/net/ethernet/freescale/gianfar_ethtool.c ++++ b/drivers/net/ethernet/freescale/gianfar_ethtool.c +@@ -163,7 +163,7 @@ static int gfar_sset_count(struct net_de + static void gfar_gdrvinfo(struct net_device *dev, + struct ethtool_drvinfo *drvinfo) + { +- strlcpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver)); ++ strscpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver)); + } + + /* Return the length of the register structure */ +--- a/drivers/net/ethernet/freescale/ucc_geth_ethtool.c ++++ b/drivers/net/ethernet/freescale/ucc_geth_ethtool.c +@@ -337,8 +337,8 @@ static void + uec_get_drvinfo(struct net_device *netdev, + struct ethtool_drvinfo *drvinfo) + { +- strlcpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver)); +- strlcpy(drvinfo->bus_info, "QUICC ENGINE", sizeof(drvinfo->bus_info)); ++ strscpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver)); ++ strscpy(drvinfo->bus_info, "QUICC ENGINE", sizeof(drvinfo->bus_info)); + } + + #ifdef CONFIG_PM +--- a/drivers/net/ethernet/fujitsu/fmvj18x_cs.c ++++ b/drivers/net/ethernet/fujitsu/fmvj18x_cs.c +@@ -1046,8 +1046,8 @@ static void fjn_rx(struct net_device *de + static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->version, DRV_VERSION, sizeof(info->version)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->version, DRV_VERSION, sizeof(info->version)); + snprintf(info->bus_info, sizeof(info->bus_info), + "PCMCIA 0x%lx", dev->base_addr); + } +--- a/drivers/net/ethernet/hisilicon/hip04_eth.c ++++ b/drivers/net/ethernet/hisilicon/hip04_eth.c +@@ -830,8 +830,8 @@ static int hip04_set_coalesce(struct net + static void hip04_get_drvinfo(struct net_device *netdev, + struct ethtool_drvinfo *drvinfo) + { +- strlcpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver)); +- strlcpy(drvinfo->version, DRV_VERSION, sizeof(drvinfo->version)); ++ strscpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver)); ++ strscpy(drvinfo->version, DRV_VERSION, sizeof(drvinfo->version)); + } + + static const struct ethtool_ops hip04_ethtool_ops = { +--- a/drivers/net/ethernet/ibm/ehea/ehea_ethtool.c ++++ b/drivers/net/ethernet/ibm/ehea/ehea_ethtool.c +@@ -159,8 +159,8 @@ static int ehea_nway_reset(struct net_de + static void ehea_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->version, DRV_VERSION, sizeof(info->version)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->version, DRV_VERSION, sizeof(info->version)); + } + + static u32 ehea_get_msglevel(struct net_device *dev) +--- a/drivers/net/ethernet/ibm/emac/core.c ++++ b/drivers/net/ethernet/ibm/emac/core.c +@@ -2284,8 +2284,8 @@ static void emac_ethtool_get_drvinfo(str + { + struct emac_instance *dev = netdev_priv(ndev); + +- strlcpy(info->driver, "ibm_emac", sizeof(info->driver)); +- strlcpy(info->version, DRV_VERSION, sizeof(info->version)); ++ strscpy(info->driver, "ibm_emac", sizeof(info->driver)); ++ strscpy(info->version, DRV_VERSION, sizeof(info->version)); + snprintf(info->bus_info, sizeof(info->bus_info), "PPC 4xx EMAC-%d %pOF", + dev->cell_index, dev->ofdev->dev.of_node); + } +--- a/drivers/net/ethernet/ibm/ibmveth.c ++++ b/drivers/net/ethernet/ibm/ibmveth.c +@@ -734,8 +734,8 @@ static void ibmveth_init_link_settings(s + static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, ibmveth_driver_name, sizeof(info->driver)); +- strlcpy(info->version, ibmveth_driver_version, sizeof(info->version)); ++ strscpy(info->driver, ibmveth_driver_name, sizeof(info->driver)); ++ strscpy(info->version, ibmveth_driver_version, sizeof(info->version)); + } + + static netdev_features_t ibmveth_fix_features(struct net_device *dev, +--- a/drivers/net/ethernet/intel/e100.c ++++ b/drivers/net/ethernet/intel/e100.c +@@ -2431,8 +2431,8 @@ static void e100_get_drvinfo(struct net_ + struct ethtool_drvinfo *info) + { + struct nic *nic = netdev_priv(netdev); +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->bus_info, pci_name(nic->pdev), ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->bus_info, pci_name(nic->pdev), + sizeof(info->bus_info)); + } + +--- a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c ++++ b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c +@@ -531,10 +531,10 @@ static void e1000_get_drvinfo(struct net + { + struct e1000_adapter *adapter = netdev_priv(netdev); + +- strlcpy(drvinfo->driver, e1000_driver_name, ++ strscpy(drvinfo->driver, e1000_driver_name, + sizeof(drvinfo->driver)); + +- strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), ++ strscpy(drvinfo->bus_info, pci_name(adapter->pdev), + sizeof(drvinfo->bus_info)); + } + +--- a/drivers/net/ethernet/intel/e1000e/ethtool.c ++++ b/drivers/net/ethernet/intel/e1000e/ethtool.c +@@ -639,7 +639,7 @@ static void e1000_get_drvinfo(struct net + { + struct e1000_adapter *adapter = netdev_priv(netdev); + +- strlcpy(drvinfo->driver, e1000e_driver_name, sizeof(drvinfo->driver)); ++ strscpy(drvinfo->driver, e1000e_driver_name, sizeof(drvinfo->driver)); + + /* EEPROM image version # is reported as firmware version # for + * PCI-E controllers +@@ -650,7 +650,7 @@ static void e1000_get_drvinfo(struct net + (adapter->eeprom_vers & 0x0FF0) >> 4, + (adapter->eeprom_vers & 0x000F)); + +- strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), ++ strscpy(drvinfo->bus_info, pci_name(adapter->pdev), + sizeof(drvinfo->bus_info)); + } + +--- a/drivers/net/ethernet/intel/e1000e/netdev.c ++++ b/drivers/net/ethernet/intel/e1000e/netdev.c +@@ -7271,7 +7271,7 @@ static void e1000_print_device_info(stru + ret_val = e1000_read_pba_string_generic(hw, pba_str, + E1000_PBANUM_LENGTH); + if (ret_val) +- strlcpy((char *)pba_str, "Unknown", sizeof(pba_str)); ++ strscpy((char *)pba_str, "Unknown", sizeof(pba_str)); + e_info("MAC: %d, PHY: %d, PBA No: %s\n", + hw->mac.type, hw->phy.type, pba_str); + } +@@ -7484,7 +7484,7 @@ static int e1000_probe(struct pci_dev *p + e1000e_set_ethtool_ops(netdev); + netdev->watchdog_timeo = 5 * HZ; + netif_napi_add(netdev, &adapter->napi, e1000e_poll, 64); +- strlcpy(netdev->name, pci_name(pdev), sizeof(netdev->name)); ++ strscpy(netdev->name, pci_name(pdev), sizeof(netdev->name)); + + netdev->mem_start = mmio_start; + netdev->mem_end = mmio_start + mmio_len; +@@ -7680,7 +7680,7 @@ static int e1000_probe(struct pci_dev *p + if (hw->mac.type >= e1000_pch_cnp) + adapter->flags2 |= FLAG2_ENABLE_S0IX_FLOWS; + +- strlcpy(netdev->name, "eth%d", sizeof(netdev->name)); ++ strscpy(netdev->name, "eth%d", sizeof(netdev->name)); + err = register_netdev(netdev); + if (err) + goto err_register; +--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +@@ -2001,10 +2001,10 @@ static void i40e_get_drvinfo(struct net_ + struct i40e_vsi *vsi = np->vsi; + struct i40e_pf *pf = vsi->back; + +- strlcpy(drvinfo->driver, i40e_driver_name, sizeof(drvinfo->driver)); +- strlcpy(drvinfo->fw_version, i40e_nvm_version_str(&pf->hw), ++ strscpy(drvinfo->driver, i40e_driver_name, sizeof(drvinfo->driver)); ++ strscpy(drvinfo->fw_version, i40e_nvm_version_str(&pf->hw), + sizeof(drvinfo->fw_version)); +- strlcpy(drvinfo->bus_info, pci_name(pf->pdev), ++ strscpy(drvinfo->bus_info, pci_name(pf->pdev), + sizeof(drvinfo->bus_info)); + drvinfo->n_priv_flags = I40E_PRIV_FLAGS_STR_LEN; + if (pf->hw.pf_id == 0) +--- a/drivers/net/ethernet/intel/i40e/i40e_main.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c +@@ -10701,7 +10701,7 @@ static void i40e_send_version(struct i40 + dv.minor_version = 0xff; + dv.build_version = 0xff; + dv.subbuild_version = 0; +- strlcpy(dv.driver_string, UTS_RELEASE, sizeof(dv.driver_string)); ++ strscpy(dv.driver_string, UTS_RELEASE, sizeof(dv.driver_string)); + i40e_aq_send_driver_version(&pf->hw, &dv, NULL); + } + +@@ -16049,23 +16049,23 @@ static int i40e_probe(struct pci_dev *pd + + switch (hw->bus.speed) { + case i40e_bus_speed_8000: +- strlcpy(speed, "8.0", PCI_SPEED_SIZE); break; ++ strscpy(speed, "8.0", PCI_SPEED_SIZE); break; + case i40e_bus_speed_5000: +- strlcpy(speed, "5.0", PCI_SPEED_SIZE); break; ++ strscpy(speed, "5.0", PCI_SPEED_SIZE); break; + case i40e_bus_speed_2500: +- strlcpy(speed, "2.5", PCI_SPEED_SIZE); break; ++ strscpy(speed, "2.5", PCI_SPEED_SIZE); break; + default: + break; + } + switch (hw->bus.width) { + case i40e_bus_width_pcie_x8: +- strlcpy(width, "8", PCI_WIDTH_SIZE); break; ++ strscpy(width, "8", PCI_WIDTH_SIZE); break; + case i40e_bus_width_pcie_x4: +- strlcpy(width, "4", PCI_WIDTH_SIZE); break; ++ strscpy(width, "4", PCI_WIDTH_SIZE); break; + case i40e_bus_width_pcie_x2: +- strlcpy(width, "2", PCI_WIDTH_SIZE); break; ++ strscpy(width, "2", PCI_WIDTH_SIZE); break; + case i40e_bus_width_pcie_x1: +- strlcpy(width, "1", PCI_WIDTH_SIZE); break; ++ strscpy(width, "1", PCI_WIDTH_SIZE); break; + default: + break; + } +--- a/drivers/net/ethernet/intel/i40e/i40e_ptp.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_ptp.c +@@ -1394,7 +1394,7 @@ static long i40e_ptp_create_clock(struct + if (!IS_ERR_OR_NULL(pf->ptp_clock)) + return 0; + +- strlcpy(pf->ptp_caps.name, i40e_driver_name, ++ strscpy(pf->ptp_caps.name, i40e_driver_name, + sizeof(pf->ptp_caps.name) - 1); + pf->ptp_caps.owner = THIS_MODULE; + pf->ptp_caps.max_adj = 999999999; +--- a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c ++++ b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c +@@ -581,9 +581,9 @@ static void iavf_get_drvinfo(struct net_ + { + struct iavf_adapter *adapter = netdev_priv(netdev); + +- strlcpy(drvinfo->driver, iavf_driver_name, 32); +- strlcpy(drvinfo->fw_version, "N/A", 4); +- strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), 32); ++ strscpy(drvinfo->driver, iavf_driver_name, 32); ++ strscpy(drvinfo->fw_version, "N/A", 4); ++ strscpy(drvinfo->bus_info, pci_name(adapter->pdev), 32); + drvinfo->n_priv_flags = IAVF_PRIV_FLAGS_STR_LEN; + } + +--- a/drivers/net/ethernet/intel/igb/igb_ethtool.c ++++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c +@@ -850,14 +850,14 @@ static void igb_get_drvinfo(struct net_d + { + struct igb_adapter *adapter = netdev_priv(netdev); + +- strlcpy(drvinfo->driver, igb_driver_name, sizeof(drvinfo->driver)); ++ strscpy(drvinfo->driver, igb_driver_name, sizeof(drvinfo->driver)); + + /* EEPROM image version # is reported as firmware version # for + * 82575 controllers + */ +- strlcpy(drvinfo->fw_version, adapter->fw_version, ++ strscpy(drvinfo->fw_version, adapter->fw_version, + sizeof(drvinfo->fw_version)); +- strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), ++ strscpy(drvinfo->bus_info, pci_name(adapter->pdev), + sizeof(drvinfo->bus_info)); + + drvinfo->n_priv_flags = IGB_PRIV_FLAGS_STR_LEN; +--- a/drivers/net/ethernet/intel/igb/igb_main.c ++++ b/drivers/net/ethernet/intel/igb/igb_main.c +@@ -3138,7 +3138,7 @@ static s32 igb_init_i2c(struct igb_adapt + adapter->i2c_algo.data = adapter; + adapter->i2c_adap.algo_data = &adapter->i2c_algo; + adapter->i2c_adap.dev.parent = &adapter->pdev->dev; +- strlcpy(adapter->i2c_adap.name, "igb BB", ++ strscpy(adapter->i2c_adap.name, "igb BB", + sizeof(adapter->i2c_adap.name)); + status = i2c_bit_add_bus(&adapter->i2c_adap); + return status; +--- a/drivers/net/ethernet/intel/igbvf/ethtool.c ++++ b/drivers/net/ethernet/intel/igbvf/ethtool.c +@@ -169,8 +169,8 @@ static void igbvf_get_drvinfo(struct net + { + struct igbvf_adapter *adapter = netdev_priv(netdev); + +- strlcpy(drvinfo->driver, igbvf_driver_name, sizeof(drvinfo->driver)); +- strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), ++ strscpy(drvinfo->driver, igbvf_driver_name, sizeof(drvinfo->driver)); ++ strscpy(drvinfo->bus_info, pci_name(adapter->pdev), + sizeof(drvinfo->bus_info)); + } + +--- a/drivers/net/ethernet/intel/ixgb/ixgb_ethtool.c ++++ b/drivers/net/ethernet/intel/ixgb/ixgb_ethtool.c +@@ -456,9 +456,9 @@ ixgb_get_drvinfo(struct net_device *netd + { + struct ixgb_adapter *adapter = netdev_priv(netdev); + +- strlcpy(drvinfo->driver, ixgb_driver_name, ++ strscpy(drvinfo->driver, ixgb_driver_name, + sizeof(drvinfo->driver)); +- strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), ++ strscpy(drvinfo->bus_info, pci_name(adapter->pdev), + sizeof(drvinfo->bus_info)); + } + +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +@@ -1107,12 +1107,12 @@ static void ixgbe_get_drvinfo(struct net + { + struct ixgbe_adapter *adapter = netdev_priv(netdev); + +- strlcpy(drvinfo->driver, ixgbe_driver_name, sizeof(drvinfo->driver)); ++ strscpy(drvinfo->driver, ixgbe_driver_name, sizeof(drvinfo->driver)); + +- strlcpy(drvinfo->fw_version, adapter->eeprom_id, ++ strscpy(drvinfo->fw_version, adapter->eeprom_id, + sizeof(drvinfo->fw_version)); + +- strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), ++ strscpy(drvinfo->bus_info, pci_name(adapter->pdev), + sizeof(drvinfo->bus_info)); + + drvinfo->n_priv_flags = IXGBE_PRIV_FLAGS_STR_LEN; +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c +@@ -1004,7 +1004,7 @@ int ixgbe_fcoe_get_hbainfo(struct net_de + ixgbe_driver_name, + UTS_RELEASE); + /* Firmware Version */ +- strlcpy(info->firmware_version, adapter->eeprom_id, ++ strscpy(info->firmware_version, adapter->eeprom_id, + sizeof(info->firmware_version)); + + /* Model */ +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +@@ -10849,7 +10849,7 @@ static int ixgbe_probe(struct pci_dev *p + netdev->netdev_ops = &ixgbe_netdev_ops; + ixgbe_set_ethtool_ops(netdev); + netdev->watchdog_timeo = 5 * HZ; +- strlcpy(netdev->name, pci_name(pdev), sizeof(netdev->name)); ++ strscpy(netdev->name, pci_name(pdev), sizeof(netdev->name)); + + /* Setup hw api */ + hw->mac.ops = *ii->mac_ops; +@@ -11140,7 +11140,7 @@ skip_sriov: + + err = ixgbe_read_pba_string_generic(hw, part_str, sizeof(part_str)); + if (err) +- strlcpy(part_str, "Unknown", sizeof(part_str)); ++ strscpy(part_str, "Unknown", sizeof(part_str)); + if (ixgbe_is_sfp(hw) && hw->phy.sfp_type != ixgbe_sfp_type_not_present) + e_dev_info("MAC: %d, PHY: %d, SFP+: %d, PBA No: %s\n", + hw->mac.type, hw->phy.type, hw->phy.sfp_type, +--- a/drivers/net/ethernet/intel/ixgbevf/ethtool.c ++++ b/drivers/net/ethernet/intel/ixgbevf/ethtool.c +@@ -213,8 +213,8 @@ static void ixgbevf_get_drvinfo(struct n + { + struct ixgbevf_adapter *adapter = netdev_priv(netdev); + +- strlcpy(drvinfo->driver, ixgbevf_driver_name, sizeof(drvinfo->driver)); +- strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), ++ strscpy(drvinfo->driver, ixgbevf_driver_name, sizeof(drvinfo->driver)); ++ strscpy(drvinfo->bus_info, pci_name(adapter->pdev), + sizeof(drvinfo->bus_info)); + + drvinfo->n_priv_flags = IXGBEVF_PRIV_FLAGS_STR_LEN; +--- a/drivers/net/ethernet/jme.c ++++ b/drivers/net/ethernet/jme.c +@@ -2346,9 +2346,9 @@ jme_get_drvinfo(struct net_device *netde + { + struct jme_adapter *jme = netdev_priv(netdev); + +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->version, DRV_VERSION, sizeof(info->version)); +- strlcpy(info->bus_info, pci_name(jme->pdev), sizeof(info->bus_info)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->version, DRV_VERSION, sizeof(info->version)); ++ strscpy(info->bus_info, pci_name(jme->pdev), sizeof(info->bus_info)); + } + + static int +--- a/drivers/net/ethernet/korina.c ++++ b/drivers/net/ethernet/korina.c +@@ -938,9 +938,9 @@ static void netdev_get_drvinfo(struct ne + { + struct korina_private *lp = netdev_priv(dev); + +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->version, DRV_VERSION, sizeof(info->version)); +- strlcpy(info->bus_info, lp->dev->name, sizeof(info->bus_info)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->version, DRV_VERSION, sizeof(info->version)); ++ strscpy(info->bus_info, lp->dev->name, sizeof(info->bus_info)); + } + + static int netdev_get_link_ksettings(struct net_device *dev, +--- a/drivers/net/ethernet/marvell/mv643xx_eth.c ++++ b/drivers/net/ethernet/marvell/mv643xx_eth.c +@@ -1603,12 +1603,12 @@ mv643xx_eth_set_link_ksettings(struct ne + static void mv643xx_eth_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *drvinfo) + { +- strlcpy(drvinfo->driver, mv643xx_eth_driver_name, ++ strscpy(drvinfo->driver, mv643xx_eth_driver_name, + sizeof(drvinfo->driver)); +- strlcpy(drvinfo->version, mv643xx_eth_driver_version, ++ strscpy(drvinfo->version, mv643xx_eth_driver_version, + sizeof(drvinfo->version)); +- strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version)); +- strlcpy(drvinfo->bus_info, "platform", sizeof(drvinfo->bus_info)); ++ strscpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version)); ++ strscpy(drvinfo->bus_info, "platform", sizeof(drvinfo->bus_info)); + } + + static int mv643xx_eth_get_coalesce(struct net_device *dev, +--- a/drivers/net/ethernet/marvell/mvneta.c ++++ b/drivers/net/ethernet/marvell/mvneta.c +@@ -4539,11 +4539,11 @@ mvneta_ethtool_get_coalesce(struct net_d + static void mvneta_ethtool_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *drvinfo) + { +- strlcpy(drvinfo->driver, MVNETA_DRIVER_NAME, ++ strscpy(drvinfo->driver, MVNETA_DRIVER_NAME, + sizeof(drvinfo->driver)); +- strlcpy(drvinfo->version, MVNETA_DRIVER_VERSION, ++ strscpy(drvinfo->version, MVNETA_DRIVER_VERSION, + sizeof(drvinfo->version)); +- strlcpy(drvinfo->bus_info, dev_name(&dev->dev), ++ strscpy(drvinfo->bus_info, dev_name(&dev->dev), + sizeof(drvinfo->bus_info)); + } + +--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c ++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +@@ -5425,11 +5425,11 @@ mvpp2_ethtool_get_coalesce(struct net_de + static void mvpp2_ethtool_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *drvinfo) + { +- strlcpy(drvinfo->driver, MVPP2_DRIVER_NAME, ++ strscpy(drvinfo->driver, MVPP2_DRIVER_NAME, + sizeof(drvinfo->driver)); +- strlcpy(drvinfo->version, MVPP2_DRIVER_VERSION, ++ strscpy(drvinfo->version, MVPP2_DRIVER_VERSION, + sizeof(drvinfo->version)); +- strlcpy(drvinfo->bus_info, dev_name(&dev->dev), ++ strscpy(drvinfo->bus_info, dev_name(&dev->dev), + sizeof(drvinfo->bus_info)); + } + +--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c +@@ -76,8 +76,8 @@ static void otx2_get_drvinfo(struct net_ + { + struct otx2_nic *pfvf = netdev_priv(netdev); + +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->bus_info, pci_name(pfvf->pdev), sizeof(info->bus_info)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->bus_info, pci_name(pfvf->pdev), sizeof(info->bus_info)); + } + + static void otx2_get_qset_strings(struct otx2_nic *pfvf, u8 **data, int qset) +@@ -1288,8 +1288,8 @@ static void otx2vf_get_drvinfo(struct ne + { + struct otx2_nic *vf = netdev_priv(netdev); + +- strlcpy(info->driver, DRV_VF_NAME, sizeof(info->driver)); +- strlcpy(info->bus_info, pci_name(vf->pdev), sizeof(info->bus_info)); ++ strscpy(info->driver, DRV_VF_NAME, sizeof(info->driver)); ++ strscpy(info->bus_info, pci_name(vf->pdev), sizeof(info->bus_info)); + } + + static void otx2vf_get_strings(struct net_device *netdev, u32 sset, u8 *data) +--- a/drivers/net/ethernet/marvell/prestera/prestera_ethtool.c ++++ b/drivers/net/ethernet/marvell/prestera/prestera_ethtool.c +@@ -300,8 +300,8 @@ static void prestera_ethtool_get_drvinfo + struct prestera_port *port = netdev_priv(dev); + struct prestera_switch *sw = port->sw; + +- strlcpy(drvinfo->driver, driver_kind, sizeof(drvinfo->driver)); +- strlcpy(drvinfo->bus_info, dev_name(prestera_dev(sw)), ++ strscpy(drvinfo->driver, driver_kind, sizeof(drvinfo->driver)); ++ strscpy(drvinfo->bus_info, dev_name(prestera_dev(sw)), + sizeof(drvinfo->bus_info)); + snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), + "%d.%d.%d", +--- a/drivers/net/ethernet/marvell/pxa168_eth.c ++++ b/drivers/net/ethernet/marvell/pxa168_eth.c +@@ -1355,10 +1355,10 @@ static void pxa168_eth_netpoll(struct ne + static void pxa168_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, DRIVER_NAME, sizeof(info->driver)); +- strlcpy(info->version, DRIVER_VERSION, sizeof(info->version)); +- strlcpy(info->fw_version, "N/A", sizeof(info->fw_version)); +- strlcpy(info->bus_info, "N/A", sizeof(info->bus_info)); ++ strscpy(info->driver, DRIVER_NAME, sizeof(info->driver)); ++ strscpy(info->version, DRIVER_VERSION, sizeof(info->version)); ++ strscpy(info->fw_version, "N/A", sizeof(info->fw_version)); ++ strscpy(info->bus_info, "N/A", sizeof(info->bus_info)); + } + + static const struct ethtool_ops pxa168_ethtool_ops = { +--- a/drivers/net/ethernet/marvell/skge.c ++++ b/drivers/net/ethernet/marvell/skge.c +@@ -395,9 +395,9 @@ static void skge_get_drvinfo(struct net_ + { + struct skge_port *skge = netdev_priv(dev); + +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->version, DRV_VERSION, sizeof(info->version)); +- strlcpy(info->bus_info, pci_name(skge->hw->pdev), ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->version, DRV_VERSION, sizeof(info->version)); ++ strscpy(info->bus_info, pci_name(skge->hw->pdev), + sizeof(info->bus_info)); + } + +--- a/drivers/net/ethernet/marvell/sky2.c ++++ b/drivers/net/ethernet/marvell/sky2.c +@@ -3688,9 +3688,9 @@ static void sky2_get_drvinfo(struct net_ + { + struct sky2_port *sky2 = netdev_priv(dev); + +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->version, DRV_VERSION, sizeof(info->version)); +- strlcpy(info->bus_info, pci_name(sky2->hw->pdev), ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->version, DRV_VERSION, sizeof(info->version)); ++ strscpy(info->bus_info, pci_name(sky2->hw->pdev), + sizeof(info->bus_info)); + } + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -2795,8 +2795,8 @@ static void mtk_get_drvinfo(struct net_d + { + struct mtk_mac *mac = netdev_priv(dev); + +- strlcpy(info->driver, mac->hw->dev->driver->name, sizeof(info->driver)); +- strlcpy(info->bus_info, dev_name(mac->hw->dev), sizeof(info->bus_info)); ++ strscpy(info->driver, mac->hw->dev->driver->name, sizeof(info->driver)); ++ strscpy(info->bus_info, dev_name(mac->hw->dev), sizeof(info->bus_info)); + info->n_stats = ARRAY_SIZE(mtk_ethtool_stats); + } + +--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c ++++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c +@@ -1170,7 +1170,7 @@ static const struct net_device_ops mtk_s + static void mtk_star_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, MTK_STAR_DRVNAME, sizeof(info->driver)); ++ strscpy(info->driver, MTK_STAR_DRVNAME, sizeof(info->driver)); + } + + /* TODO Add ethtool stats. */ +--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c ++++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +@@ -88,15 +88,15 @@ mlx4_en_get_drvinfo(struct net_device *d + struct mlx4_en_priv *priv = netdev_priv(dev); + struct mlx4_en_dev *mdev = priv->mdev; + +- strlcpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver)); +- strlcpy(drvinfo->version, DRV_VERSION, ++ strscpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver)); ++ strscpy(drvinfo->version, DRV_VERSION, + sizeof(drvinfo->version)); + snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), + "%d.%d.%d", + (u16) (mdev->dev->caps.fw_ver >> 32), + (u16) ((mdev->dev->caps.fw_ver >> 16) & 0xffff), + (u16) (mdev->dev->caps.fw_ver & 0xffff)); +- strlcpy(drvinfo->bus_info, pci_name(mdev->dev->persist->pdev), ++ strscpy(drvinfo->bus_info, pci_name(mdev->dev->persist->pdev), + sizeof(drvinfo->bus_info)); + } + +--- a/drivers/net/ethernet/mellanox/mlx4/fw.c ++++ b/drivers/net/ethernet/mellanox/mlx4/fw.c +@@ -1779,7 +1779,7 @@ static void get_board_id(void *vsd, char + + if (be16_to_cpup(vsd + VSD_OFFSET_SIG1) == VSD_SIGNATURE_TOPSPIN && + be16_to_cpup(vsd + VSD_OFFSET_SIG2) == VSD_SIGNATURE_TOPSPIN) { +- strlcpy(board_id, vsd + VSD_OFFSET_TS_BOARD_ID, MLX4_BOARD_ID_LEN); ++ strscpy(board_id, vsd + VSD_OFFSET_TS_BOARD_ID, MLX4_BOARD_ID_LEN); + } else { + /* + * The board ID is a string but the firmware byte +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +@@ -44,12 +44,12 @@ void mlx5e_ethtool_get_drvinfo(struct ml + { + struct mlx5_core_dev *mdev = priv->mdev; + +- strlcpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver)); ++ strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver)); + snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), + "%d.%d.%04d (%.16s)", + fw_rev_maj(mdev), fw_rev_min(mdev), fw_rev_sub(mdev), + mdev->board_id); +- strlcpy(drvinfo->bus_info, dev_name(mdev->device), ++ strscpy(drvinfo->bus_info, dev_name(mdev->device), + sizeof(drvinfo->bus_info)); + } + +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +@@ -69,7 +69,7 @@ static void mlx5e_rep_get_drvinfo(struct + struct mlx5e_priv *priv = netdev_priv(dev); + struct mlx5_core_dev *mdev = priv->mdev; + +- strlcpy(drvinfo->driver, mlx5e_rep_driver_name, ++ strscpy(drvinfo->driver, mlx5e_rep_driver_name, + sizeof(drvinfo->driver)); + snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), + "%d.%d.%04d (%.16s)", +--- a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ethtool.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ethtool.c +@@ -39,7 +39,7 @@ static void mlx5i_get_drvinfo(struct net + struct mlx5e_priv *priv = mlx5i_epriv(dev); + + mlx5e_ethtool_get_drvinfo(priv, drvinfo); +- strlcpy(drvinfo->driver, KBUILD_MODNAME "[ib_ipoib]", ++ strscpy(drvinfo->driver, KBUILD_MODNAME "[ib_ipoib]", + sizeof(drvinfo->driver)); + } + +--- a/drivers/net/ethernet/mellanox/mlxsw/core.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/core.c +@@ -605,7 +605,7 @@ static void mlxsw_emad_process_string_tl + return; + + string = mlxsw_emad_string_tlv_string_data(string_tlv); +- strlcpy(trans->emad_err_string, string, ++ strscpy(trans->emad_err_string, string, + MLXSW_EMAD_STRING_TLV_STRING_LEN); + } + +--- a/drivers/net/ethernet/mellanox/mlxsw/minimal.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/minimal.c +@@ -93,14 +93,14 @@ static void mlxsw_m_module_get_drvinfo(s + struct mlxsw_m_port *mlxsw_m_port = netdev_priv(dev); + struct mlxsw_m *mlxsw_m = mlxsw_m_port->mlxsw_m; + +- strlcpy(drvinfo->driver, mlxsw_m->bus_info->device_kind, ++ strscpy(drvinfo->driver, mlxsw_m->bus_info->device_kind, + sizeof(drvinfo->driver)); + snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), + "%d.%d.%d", + mlxsw_m->bus_info->fw_rev.major, + mlxsw_m->bus_info->fw_rev.minor, + mlxsw_m->bus_info->fw_rev.subminor); +- strlcpy(drvinfo->bus_info, mlxsw_m->bus_info->device_name, ++ strscpy(drvinfo->bus_info, mlxsw_m->bus_info->device_name, + sizeof(drvinfo->bus_info)); + } + +--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c +@@ -14,16 +14,16 @@ static void mlxsw_sp_port_get_drvinfo(st + struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev); + struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; + +- strlcpy(drvinfo->driver, mlxsw_sp->bus_info->device_kind, ++ strscpy(drvinfo->driver, mlxsw_sp->bus_info->device_kind, + sizeof(drvinfo->driver)); +- strlcpy(drvinfo->version, mlxsw_sp_driver_version, ++ strscpy(drvinfo->version, mlxsw_sp_driver_version, + sizeof(drvinfo->version)); + snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), + "%d.%d.%d", + mlxsw_sp->bus_info->fw_rev.major, + mlxsw_sp->bus_info->fw_rev.minor, + mlxsw_sp->bus_info->fw_rev.subminor); +- strlcpy(drvinfo->bus_info, mlxsw_sp->bus_info->device_name, ++ strscpy(drvinfo->bus_info, mlxsw_sp->bus_info->device_name, + sizeof(drvinfo->bus_info)); + } + +--- a/drivers/net/ethernet/micrel/ks8851_common.c ++++ b/drivers/net/ethernet/micrel/ks8851_common.c +@@ -703,9 +703,9 @@ static const struct net_device_ops ks885 + static void ks8851_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *di) + { +- strlcpy(di->driver, "KS8851", sizeof(di->driver)); +- strlcpy(di->version, "1.00", sizeof(di->version)); +- strlcpy(di->bus_info, dev_name(dev->dev.parent), sizeof(di->bus_info)); ++ strscpy(di->driver, "KS8851", sizeof(di->driver)); ++ strscpy(di->version, "1.00", sizeof(di->version)); ++ strscpy(di->bus_info, dev_name(dev->dev.parent), sizeof(di->bus_info)); + } + + static u32 ks8851_get_msglevel(struct net_device *dev) +--- a/drivers/net/ethernet/micrel/ksz884x.c ++++ b/drivers/net/ethernet/micrel/ksz884x.c +@@ -6000,9 +6000,9 @@ static void netdev_get_drvinfo(struct ne + struct dev_priv *priv = netdev_priv(dev); + struct dev_info *hw_priv = priv->adapter; + +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->version, DRV_VERSION, sizeof(info->version)); +- strlcpy(info->bus_info, pci_name(hw_priv->pdev), ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->version, DRV_VERSION, sizeof(info->version)); ++ strscpy(info->bus_info, pci_name(hw_priv->pdev), + sizeof(info->bus_info)); + } + +--- a/drivers/net/ethernet/microchip/enc28j60.c ++++ b/drivers/net/ethernet/microchip/enc28j60.c +@@ -1467,9 +1467,9 @@ static void enc28j60_restart_work_handle + static void + enc28j60_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->version, DRV_VERSION, sizeof(info->version)); +- strlcpy(info->bus_info, ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->version, DRV_VERSION, sizeof(info->version)); ++ strscpy(info->bus_info, + dev_name(dev->dev.parent), sizeof(info->bus_info)); + } + +--- a/drivers/net/ethernet/microchip/encx24j600.c ++++ b/drivers/net/ethernet/microchip/encx24j600.c +@@ -925,9 +925,9 @@ static void encx24j600_get_regs(struct n + static void encx24j600_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->version, DRV_VERSION, sizeof(info->version)); +- strlcpy(info->bus_info, dev_name(dev->dev.parent), ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->version, DRV_VERSION, sizeof(info->version)); ++ strscpy(info->bus_info, dev_name(dev->dev.parent), + sizeof(info->bus_info)); + } + +--- a/drivers/net/ethernet/microchip/lan743x_ethtool.c ++++ b/drivers/net/ethernet/microchip/lan743x_ethtool.c +@@ -268,8 +268,8 @@ static void lan743x_ethtool_get_drvinfo( + { + struct lan743x_adapter *adapter = netdev_priv(netdev); + +- strlcpy(info->driver, DRIVER_NAME, sizeof(info->driver)); +- strlcpy(info->bus_info, ++ strscpy(info->driver, DRIVER_NAME, sizeof(info->driver)); ++ strscpy(info->bus_info, + pci_name(adapter->pdev), sizeof(info->bus_info)); + } + +--- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c ++++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c +@@ -1646,10 +1646,10 @@ myri10ge_get_drvinfo(struct net_device * + { + struct myri10ge_priv *mgp = netdev_priv(netdev); + +- strlcpy(info->driver, "myri10ge", sizeof(info->driver)); +- strlcpy(info->version, MYRI10GE_VERSION_STR, sizeof(info->version)); +- strlcpy(info->fw_version, mgp->fw_version, sizeof(info->fw_version)); +- strlcpy(info->bus_info, pci_name(mgp->pdev), sizeof(info->bus_info)); ++ strscpy(info->driver, "myri10ge", sizeof(info->driver)); ++ strscpy(info->version, MYRI10GE_VERSION_STR, sizeof(info->version)); ++ strscpy(info->fw_version, mgp->fw_version, sizeof(info->fw_version)); ++ strscpy(info->bus_info, pci_name(mgp->pdev), sizeof(info->bus_info)); + } + + static int myri10ge_get_coalesce(struct net_device *netdev, +--- a/drivers/net/ethernet/natsemi/natsemi.c ++++ b/drivers/net/ethernet/natsemi/natsemi.c +@@ -2566,9 +2566,9 @@ static void set_rx_mode(struct net_devic + static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) + { + struct netdev_private *np = netdev_priv(dev); +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->version, DRV_VERSION, sizeof(info->version)); +- strlcpy(info->bus_info, pci_name(np->pci_dev), sizeof(info->bus_info)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->version, DRV_VERSION, sizeof(info->version)); ++ strscpy(info->bus_info, pci_name(np->pci_dev), sizeof(info->bus_info)); + } + + static int get_regs_len(struct net_device *dev) +--- a/drivers/net/ethernet/natsemi/ns83820.c ++++ b/drivers/net/ethernet/natsemi/ns83820.c +@@ -1351,9 +1351,9 @@ static int ns83820_set_link_ksettings(st + static void ns83820_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info) + { + struct ns83820 *dev = PRIV(ndev); +- strlcpy(info->driver, "ns83820", sizeof(info->driver)); +- strlcpy(info->version, VERSION, sizeof(info->version)); +- strlcpy(info->bus_info, pci_name(dev->pci_dev), sizeof(info->bus_info)); ++ strscpy(info->driver, "ns83820", sizeof(info->driver)); ++ strscpy(info->version, VERSION, sizeof(info->version)); ++ strscpy(info->bus_info, pci_name(dev->pci_dev), sizeof(info->bus_info)); + } + + static u32 ns83820_get_link(struct net_device *ndev) +--- a/drivers/net/ethernet/neterion/s2io.c ++++ b/drivers/net/ethernet/neterion/s2io.c +@@ -5348,9 +5348,9 @@ static void s2io_ethtool_gdrvinfo(struct + { + struct s2io_nic *sp = netdev_priv(dev); + +- strlcpy(info->driver, s2io_driver_name, sizeof(info->driver)); +- strlcpy(info->version, s2io_driver_version, sizeof(info->version)); +- strlcpy(info->bus_info, pci_name(sp->pdev), sizeof(info->bus_info)); ++ strscpy(info->driver, s2io_driver_name, sizeof(info->driver)); ++ strscpy(info->version, s2io_driver_version, sizeof(info->version)); ++ strscpy(info->bus_info, pci_name(sp->pdev), sizeof(info->bus_info)); + } + + /** +--- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c ++++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c +@@ -202,7 +202,7 @@ nfp_get_drvinfo(struct nfp_app *app, str + { + char nsp_version[ETHTOOL_FWVERS_LEN] = {}; + +- strlcpy(drvinfo->driver, pdev->driver->name, sizeof(drvinfo->driver)); ++ strscpy(drvinfo->driver, pdev->driver->name, sizeof(drvinfo->driver)); + nfp_net_get_nspinfo(app, nsp_version); + snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), + "%s %s %s %s", vnic_version, nsp_version, +@@ -218,7 +218,7 @@ nfp_net_get_drvinfo(struct net_device *n + snprintf(vnic_version, sizeof(vnic_version), "%d.%d.%d.%d", + nn->fw_ver.resv, nn->fw_ver.class, + nn->fw_ver.major, nn->fw_ver.minor); +- strlcpy(drvinfo->bus_info, pci_name(nn->pdev), ++ strscpy(drvinfo->bus_info, pci_name(nn->pdev), + sizeof(drvinfo->bus_info)); + + nfp_get_drvinfo(nn->app, nn->pdev, vnic_version, drvinfo); +@@ -229,7 +229,7 @@ nfp_app_get_drvinfo(struct net_device *n + { + struct nfp_app *app = nfp_app_from_netdev(netdev); + +- strlcpy(drvinfo->bus_info, pci_name(app->pdev), ++ strscpy(drvinfo->bus_info, pci_name(app->pdev), + sizeof(drvinfo->bus_info)); + nfp_get_drvinfo(app, app->pdev, "*", drvinfo); + } +--- a/drivers/net/ethernet/ni/nixge.c ++++ b/drivers/net/ethernet/ni/nixge.c +@@ -989,8 +989,8 @@ static const struct net_device_ops nixge + static void nixge_ethtools_get_drvinfo(struct net_device *ndev, + struct ethtool_drvinfo *ed) + { +- strlcpy(ed->driver, "nixge", sizeof(ed->driver)); +- strlcpy(ed->bus_info, "platform", sizeof(ed->bus_info)); ++ strscpy(ed->driver, "nixge", sizeof(ed->driver)); ++ strscpy(ed->bus_info, "platform", sizeof(ed->bus_info)); + } + + static int +--- a/drivers/net/ethernet/nvidia/forcedeth.c ++++ b/drivers/net/ethernet/nvidia/forcedeth.c +@@ -4291,9 +4291,9 @@ static void nv_do_stats_poll(struct time + static void nv_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) + { + struct fe_priv *np = netdev_priv(dev); +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->version, FORCEDETH_VERSION, sizeof(info->version)); +- strlcpy(info->bus_info, pci_name(np->pci_dev), sizeof(info->bus_info)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->version, FORCEDETH_VERSION, sizeof(info->version)); ++ strscpy(info->bus_info, pci_name(np->pci_dev), sizeof(info->bus_info)); + } + + static void nv_get_wol(struct net_device *dev, struct ethtool_wolinfo *wolinfo) +--- a/drivers/net/ethernet/nxp/lpc_eth.c ++++ b/drivers/net/ethernet/nxp/lpc_eth.c +@@ -1184,9 +1184,9 @@ static int lpc_eth_open(struct net_devic + static void lpc_eth_ethtool_getdrvinfo(struct net_device *ndev, + struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, MODNAME, sizeof(info->driver)); +- strlcpy(info->version, DRV_VERSION, sizeof(info->version)); +- strlcpy(info->bus_info, dev_name(ndev->dev.parent), ++ strscpy(info->driver, MODNAME, sizeof(info->driver)); ++ strscpy(info->version, DRV_VERSION, sizeof(info->version)); ++ strscpy(info->bus_info, dev_name(ndev->dev.parent), + sizeof(info->bus_info)); + } + +--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_ethtool.c ++++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_ethtool.c +@@ -169,9 +169,9 @@ static void pch_gbe_get_drvinfo(struct n + { + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + +- strlcpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver)); +- strlcpy(drvinfo->version, pch_driver_version, sizeof(drvinfo->version)); +- strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), ++ strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver)); ++ strscpy(drvinfo->version, pch_driver_version, sizeof(drvinfo->version)); ++ strscpy(drvinfo->bus_info, pci_name(adapter->pdev), + sizeof(drvinfo->bus_info)); + } + +--- a/drivers/net/ethernet/packetengines/hamachi.c ++++ b/drivers/net/ethernet/packetengines/hamachi.c +@@ -1819,9 +1819,9 @@ static void hamachi_get_drvinfo(struct n + { + struct hamachi_private *np = netdev_priv(dev); + +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->version, DRV_VERSION, sizeof(info->version)); +- strlcpy(info->bus_info, pci_name(np->pci_dev), sizeof(info->bus_info)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->version, DRV_VERSION, sizeof(info->version)); ++ strscpy(info->bus_info, pci_name(np->pci_dev), sizeof(info->bus_info)); + } + + static int hamachi_get_link_ksettings(struct net_device *dev, +--- a/drivers/net/ethernet/packetengines/yellowfin.c ++++ b/drivers/net/ethernet/packetengines/yellowfin.c +@@ -1340,9 +1340,9 @@ static void yellowfin_get_drvinfo(struct + { + struct yellowfin_private *np = netdev_priv(dev); + +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->version, DRV_VERSION, sizeof(info->version)); +- strlcpy(info->bus_info, pci_name(np->pci_dev), sizeof(info->bus_info)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->version, DRV_VERSION, sizeof(info->version)); ++ strscpy(info->bus_info, pci_name(np->pci_dev), sizeof(info->bus_info)); + } + + static const struct ethtool_ops ethtool_ops = { +--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c ++++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c +@@ -65,9 +65,9 @@ netxen_nic_get_drvinfo(struct net_device + u32 fw_minor = 0; + u32 fw_build = 0; + +- strlcpy(drvinfo->driver, netxen_nic_driver_name, ++ strscpy(drvinfo->driver, netxen_nic_driver_name, + sizeof(drvinfo->driver)); +- strlcpy(drvinfo->version, NETXEN_NIC_LINUX_VERSIONID, ++ strscpy(drvinfo->version, NETXEN_NIC_LINUX_VERSIONID, + sizeof(drvinfo->version)); + fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR); + fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR); +@@ -75,7 +75,7 @@ netxen_nic_get_drvinfo(struct net_device + snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), + "%d.%d.%d", fw_major, fw_minor, fw_build); + +- strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), ++ strscpy(drvinfo->bus_info, pci_name(adapter->pdev), + sizeof(drvinfo->bus_info)); + } + +--- a/drivers/net/ethernet/qlogic/qed/qed_int.c ++++ b/drivers/net/ethernet/qlogic/qed/qed_int.c +@@ -1119,7 +1119,7 @@ static int qed_int_deassertion(struct qe + snprintf(bit_name, 30, + p_aeu->bit_name, num); + else +- strlcpy(bit_name, ++ strscpy(bit_name, + p_aeu->bit_name, 30); + + /* We now need to pass bitmask in its +--- a/drivers/net/ethernet/qlogic/qede/qede_ethtool.c ++++ b/drivers/net/ethernet/qlogic/qede/qede_ethtool.c +@@ -624,7 +624,7 @@ static void qede_get_drvinfo(struct net_ + struct qede_dev *edev = netdev_priv(ndev); + char mbi[ETHTOOL_FWVERS_LEN]; + +- strlcpy(info->driver, "qede", sizeof(info->driver)); ++ strscpy(info->driver, "qede", sizeof(info->driver)); + + snprintf(storm, ETHTOOL_FWVERS_LEN, "%d.%d.%d.%d", + edev->dev_info.common.fw_major, +@@ -661,7 +661,7 @@ static void qede_get_drvinfo(struct net_ + "mfw %s", mfw); + } + +- strlcpy(info->bus_info, pci_name(edev->pdev), sizeof(info->bus_info)); ++ strscpy(info->bus_info, pci_name(edev->pdev), sizeof(info->bus_info)); + } + + static void qede_get_wol(struct net_device *ndev, struct ethtool_wolinfo *wol) +--- a/drivers/net/ethernet/qlogic/qede/qede_main.c ++++ b/drivers/net/ethernet/qlogic/qede/qede_main.c +@@ -1214,7 +1214,7 @@ static int __qede_probe(struct pci_dev * + /* Start the Slowpath-process */ + memset(&sp_params, 0, sizeof(sp_params)); + sp_params.int_mode = QED_INT_MODE_MSIX; +- strlcpy(sp_params.name, "qede LAN", QED_DRV_VER_STR_SIZE); ++ strscpy(sp_params.name, "qede LAN", QED_DRV_VER_STR_SIZE); + rc = qed_ops->common->slowpath_start(cdev, &sp_params); + if (rc) { + pr_notice("Cannot start slowpath\n"); +--- a/drivers/net/ethernet/qlogic/qla3xxx.c ++++ b/drivers/net/ethernet/qlogic/qla3xxx.c +@@ -1736,10 +1736,10 @@ static void ql_get_drvinfo(struct net_de + struct ethtool_drvinfo *drvinfo) + { + struct ql3_adapter *qdev = netdev_priv(ndev); +- strlcpy(drvinfo->driver, ql3xxx_driver_name, sizeof(drvinfo->driver)); +- strlcpy(drvinfo->version, ql3xxx_driver_version, ++ strscpy(drvinfo->driver, ql3xxx_driver_name, sizeof(drvinfo->driver)); ++ strscpy(drvinfo->version, ql3xxx_driver_version, + sizeof(drvinfo->version)); +- strlcpy(drvinfo->bus_info, pci_name(qdev->pdev), ++ strscpy(drvinfo->bus_info, pci_name(qdev->pdev), + sizeof(drvinfo->bus_info)); + } + +--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c ++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c +@@ -277,10 +277,10 @@ qlcnic_get_drvinfo(struct net_device *de + snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), + "%d.%d.%d", fw_major, fw_minor, fw_build); + +- strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), ++ strscpy(drvinfo->bus_info, pci_name(adapter->pdev), + sizeof(drvinfo->bus_info)); +- strlcpy(drvinfo->driver, qlcnic_driver_name, sizeof(drvinfo->driver)); +- strlcpy(drvinfo->version, QLCNIC_LINUX_VERSIONID, ++ strscpy(drvinfo->driver, qlcnic_driver_name, sizeof(drvinfo->driver)); ++ strscpy(drvinfo->version, QLCNIC_LINUX_VERSIONID, + sizeof(drvinfo->version)); + } + +--- a/drivers/net/ethernet/qualcomm/qca_debug.c ++++ b/drivers/net/ethernet/qualcomm/qca_debug.c +@@ -164,10 +164,10 @@ qcaspi_get_drvinfo(struct net_device *de + { + struct qcaspi *qca = netdev_priv(dev); + +- strlcpy(p->driver, QCASPI_DRV_NAME, sizeof(p->driver)); +- strlcpy(p->version, QCASPI_DRV_VERSION, sizeof(p->version)); +- strlcpy(p->fw_version, "QCA7000", sizeof(p->fw_version)); +- strlcpy(p->bus_info, dev_name(&qca->spi_dev->dev), ++ strscpy(p->driver, QCASPI_DRV_NAME, sizeof(p->driver)); ++ strscpy(p->version, QCASPI_DRV_VERSION, sizeof(p->version)); ++ strscpy(p->fw_version, "QCA7000", sizeof(p->fw_version)); ++ strscpy(p->bus_info, dev_name(&qca->spi_dev->dev), + sizeof(p->bus_info)); + } + +--- a/drivers/net/ethernet/rdc/r6040.c ++++ b/drivers/net/ethernet/rdc/r6040.c +@@ -939,9 +939,9 @@ static void netdev_get_drvinfo(struct ne + { + struct r6040_private *rp = netdev_priv(dev); + +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->version, DRV_VERSION, sizeof(info->version)); +- strlcpy(info->bus_info, pci_name(rp->pdev), sizeof(info->bus_info)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->version, DRV_VERSION, sizeof(info->version)); ++ strscpy(info->bus_info, pci_name(rp->pdev), sizeof(info->bus_info)); + } + + static const struct ethtool_ops netdev_ethtool_ops = { +--- a/drivers/net/ethernet/realtek/8139cp.c ++++ b/drivers/net/ethernet/realtek/8139cp.c +@@ -1382,9 +1382,9 @@ static void cp_get_drvinfo (struct net_d + { + struct cp_private *cp = netdev_priv(dev); + +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->version, DRV_VERSION, sizeof(info->version)); +- strlcpy(info->bus_info, pci_name(cp->pdev), sizeof(info->bus_info)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->version, DRV_VERSION, sizeof(info->version)); ++ strscpy(info->bus_info, pci_name(cp->pdev), sizeof(info->bus_info)); + } + + static void cp_get_ringparam(struct net_device *dev, +--- a/drivers/net/ethernet/realtek/8139too.c ++++ b/drivers/net/ethernet/realtek/8139too.c +@@ -2380,9 +2380,9 @@ static int rtl8139_set_wol(struct net_de + static void rtl8139_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) + { + struct rtl8139_private *tp = netdev_priv(dev); +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->version, DRV_VERSION, sizeof(info->version)); +- strlcpy(info->bus_info, pci_name(tp->pci_dev), sizeof(info->bus_info)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->version, DRV_VERSION, sizeof(info->version)); ++ strscpy(info->bus_info, pci_name(tp->pci_dev), sizeof(info->bus_info)); + } + + static int rtl8139_get_link_ksettings(struct net_device *dev, +--- a/drivers/net/ethernet/realtek/r8169_main.c ++++ b/drivers/net/ethernet/realtek/r8169_main.c +@@ -1453,11 +1453,11 @@ static void rtl8169_get_drvinfo(struct n + struct rtl8169_private *tp = netdev_priv(dev); + struct rtl_fw *rtl_fw = tp->rtl_fw; + +- strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); +- strlcpy(info->bus_info, pci_name(tp->pci_dev), sizeof(info->bus_info)); ++ strscpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); ++ strscpy(info->bus_info, pci_name(tp->pci_dev), sizeof(info->bus_info)); + BUILD_BUG_ON(sizeof(info->fw_version) < sizeof(rtl_fw->version)); + if (rtl_fw) +- strlcpy(info->fw_version, rtl_fw->version, ++ strscpy(info->fw_version, rtl_fw->version, + sizeof(info->fw_version)); + } + +--- a/drivers/net/ethernet/rocker/rocker_main.c ++++ b/drivers/net/ethernet/rocker/rocker_main.c +@@ -2237,8 +2237,8 @@ rocker_port_set_link_ksettings(struct ne + static void rocker_port_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *drvinfo) + { +- strlcpy(drvinfo->driver, rocker_driver_name, sizeof(drvinfo->driver)); +- strlcpy(drvinfo->version, UTS_RELEASE, sizeof(drvinfo->version)); ++ strscpy(drvinfo->driver, rocker_driver_name, sizeof(drvinfo->driver)); ++ strscpy(drvinfo->version, UTS_RELEASE, sizeof(drvinfo->version)); + } + + static struct rocker_port_stats { +--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c ++++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c +@@ -175,8 +175,8 @@ static int sxgbe_set_eee(struct net_devi + static void sxgbe_getdrvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); +- strlcpy(info->version, DRV_VERSION, sizeof(info->version)); ++ strscpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); ++ strscpy(info->version, DRV_VERSION, sizeof(info->version)); + } + + static u32 sxgbe_getmsglevel(struct net_device *dev) +--- a/drivers/net/ethernet/sfc/efx.c ++++ b/drivers/net/ethernet/sfc/efx.c +@@ -778,7 +778,7 @@ static void efx_unregister_netdev(struct + return; + + if (efx_dev_registered(efx)) { +- strlcpy(efx->name, pci_name(efx->pci_dev), sizeof(efx->name)); ++ strscpy(efx->name, pci_name(efx->pci_dev), sizeof(efx->name)); + efx_fini_mcdi_logging(efx); + device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_type); + unregister_netdev(efx->net_dev); +--- a/drivers/net/ethernet/sfc/efx_common.c ++++ b/drivers/net/ethernet/sfc/efx_common.c +@@ -996,7 +996,7 @@ int efx_init_struct(struct efx_nic *efx, + efx->pci_dev = pci_dev; + efx->msg_enable = debug; + efx->state = STATE_UNINIT; +- strlcpy(efx->name, pci_name(pci_dev), sizeof(efx->name)); ++ strscpy(efx->name, pci_name(pci_dev), sizeof(efx->name)); + + efx->rx_prefix_size = efx->type->rx_prefix_size; + efx->rx_ip_align = +--- a/drivers/net/ethernet/sfc/ethtool_common.c ++++ b/drivers/net/ethernet/sfc/ethtool_common.c +@@ -106,10 +106,10 @@ void efx_ethtool_get_drvinfo(struct net_ + { + struct efx_nic *efx = efx_netdev_priv(net_dev); + +- strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); ++ strscpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); + efx_mcdi_print_fwver(efx, info->fw_version, + sizeof(info->fw_version)); +- strlcpy(info->bus_info, pci_name(efx->pci_dev), sizeof(info->bus_info)); ++ strscpy(info->bus_info, pci_name(efx->pci_dev), sizeof(info->bus_info)); + } + + u32 efx_ethtool_get_msglevel(struct net_device *net_dev) +@@ -468,7 +468,7 @@ void efx_ethtool_get_strings(struct net_ + strings += (efx->type->describe_stats(efx, strings) * + ETH_GSTRING_LEN); + for (i = 0; i < EFX_ETHTOOL_SW_STAT_COUNT; i++) +- strlcpy(strings + i * ETH_GSTRING_LEN, ++ strscpy(strings + i * ETH_GSTRING_LEN, + efx_sw_stat_desc[i].name, ETH_GSTRING_LEN); + strings += EFX_ETHTOOL_SW_STAT_COUNT * ETH_GSTRING_LEN; + strings += (efx_describe_per_queue_stats(efx, strings) * +--- a/drivers/net/ethernet/sfc/falcon/efx.c ++++ b/drivers/net/ethernet/sfc/falcon/efx.c +@@ -2335,7 +2335,7 @@ static void ef4_unregister_netdev(struct + BUG_ON(netdev_priv(efx->net_dev) != efx); + + if (ef4_dev_registered(efx)) { +- strlcpy(efx->name, pci_name(efx->pci_dev), sizeof(efx->name)); ++ strscpy(efx->name, pci_name(efx->pci_dev), sizeof(efx->name)); + device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_type); + unregister_netdev(efx->net_dev); + } +@@ -2646,7 +2646,7 @@ static int ef4_init_struct(struct ef4_ni + efx->pci_dev = pci_dev; + efx->msg_enable = debug; + efx->state = STATE_UNINIT; +- strlcpy(efx->name, pci_name(pci_dev), sizeof(efx->name)); ++ strscpy(efx->name, pci_name(pci_dev), sizeof(efx->name)); + + efx->net_dev = net_dev; + efx->rx_prefix_size = efx->type->rx_prefix_size; +--- a/drivers/net/ethernet/sfc/falcon/ethtool.c ++++ b/drivers/net/ethernet/sfc/falcon/ethtool.c +@@ -162,9 +162,9 @@ static void ef4_ethtool_get_drvinfo(stru + { + struct ef4_nic *efx = netdev_priv(net_dev); + +- strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); +- strlcpy(info->version, EF4_DRIVER_VERSION, sizeof(info->version)); +- strlcpy(info->bus_info, pci_name(efx->pci_dev), sizeof(info->bus_info)); ++ strscpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); ++ strscpy(info->version, EF4_DRIVER_VERSION, sizeof(info->version)); ++ strscpy(info->bus_info, pci_name(efx->pci_dev), sizeof(info->bus_info)); + } + + static int ef4_ethtool_get_regs_len(struct net_device *net_dev) +@@ -412,7 +412,7 @@ static void ef4_ethtool_get_strings(stru + strings += (efx->type->describe_stats(efx, strings) * + ETH_GSTRING_LEN); + for (i = 0; i < EF4_ETHTOOL_SW_STAT_COUNT; i++) +- strlcpy(strings + i * ETH_GSTRING_LEN, ++ strscpy(strings + i * ETH_GSTRING_LEN, + ef4_sw_stat_desc[i].name, ETH_GSTRING_LEN); + strings += EF4_ETHTOOL_SW_STAT_COUNT * ETH_GSTRING_LEN; + strings += (ef4_describe_per_queue_stats(efx, strings) * +--- a/drivers/net/ethernet/sfc/falcon/falcon.c ++++ b/drivers/net/ethernet/sfc/falcon/falcon.c +@@ -2387,7 +2387,7 @@ static int falcon_probe_nic(struct ef4_n + board->i2c_data.data = efx; + board->i2c_adap.algo_data = &board->i2c_data; + board->i2c_adap.dev.parent = &efx->pci_dev->dev; +- strlcpy(board->i2c_adap.name, "SFC4000 GPIO", ++ strscpy(board->i2c_adap.name, "SFC4000 GPIO", + sizeof(board->i2c_adap.name)); + rc = i2c_bit_add_bus(&board->i2c_adap); + if (rc) +--- a/drivers/net/ethernet/sfc/falcon/nic.c ++++ b/drivers/net/ethernet/sfc/falcon/nic.c +@@ -452,7 +452,7 @@ size_t ef4_nic_describe_stats(const stru + for_each_set_bit(index, mask, count) { + if (desc[index].name) { + if (names) { +- strlcpy(names, desc[index].name, ++ strscpy(names, desc[index].name, + ETH_GSTRING_LEN); + names += ETH_GSTRING_LEN; + } +--- a/drivers/net/ethernet/sfc/mcdi_mon.c ++++ b/drivers/net/ethernet/sfc/mcdi_mon.c +@@ -285,7 +285,7 @@ efx_mcdi_mon_add_attr(struct efx_nic *ef + struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx); + struct efx_mcdi_mon_attribute *attr = &hwmon->attrs[hwmon->n_attrs]; + +- strlcpy(attr->name, name, sizeof(attr->name)); ++ strscpy(attr->name, name, sizeof(attr->name)); + attr->index = index; + attr->type = type; + if (type < ARRAY_SIZE(efx_mcdi_sensor_type)) +--- a/drivers/net/ethernet/sfc/nic.c ++++ b/drivers/net/ethernet/sfc/nic.c +@@ -465,7 +465,7 @@ size_t efx_nic_describe_stats(const stru + for_each_set_bit(index, mask, count) { + if (desc[index].name) { + if (names) { +- strlcpy(names, desc[index].name, ++ strscpy(names, desc[index].name, + ETH_GSTRING_LEN); + names += ETH_GSTRING_LEN; + } +--- a/drivers/net/ethernet/sfc/siena/efx.c ++++ b/drivers/net/ethernet/sfc/siena/efx.c +@@ -775,7 +775,7 @@ static void efx_unregister_netdev(struct + BUG_ON(netdev_priv(efx->net_dev) != efx); + + if (efx_dev_registered(efx)) { +- strlcpy(efx->name, pci_name(efx->pci_dev), sizeof(efx->name)); ++ strscpy(efx->name, pci_name(efx->pci_dev), sizeof(efx->name)); + efx_siena_fini_mcdi_logging(efx); + device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_type); + unregister_netdev(efx->net_dev); +--- a/drivers/net/ethernet/sfc/siena/efx_common.c ++++ b/drivers/net/ethernet/sfc/siena/efx_common.c +@@ -1006,7 +1006,7 @@ int efx_siena_init_struct(struct efx_nic + efx->pci_dev = pci_dev; + efx->msg_enable = debug; + efx->state = STATE_UNINIT; +- strlcpy(efx->name, pci_name(pci_dev), sizeof(efx->name)); ++ strscpy(efx->name, pci_name(pci_dev), sizeof(efx->name)); + + efx->net_dev = net_dev; + efx->rx_prefix_size = efx->type->rx_prefix_size; +--- a/drivers/net/ethernet/sfc/siena/ethtool_common.c ++++ b/drivers/net/ethernet/sfc/siena/ethtool_common.c +@@ -105,10 +105,10 @@ void efx_siena_ethtool_get_drvinfo(struc + { + struct efx_nic *efx = netdev_priv(net_dev); + +- strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); ++ strscpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); + efx_siena_mcdi_print_fwver(efx, info->fw_version, + sizeof(info->fw_version)); +- strlcpy(info->bus_info, pci_name(efx->pci_dev), sizeof(info->bus_info)); ++ strscpy(info->bus_info, pci_name(efx->pci_dev), sizeof(info->bus_info)); + } + + u32 efx_siena_ethtool_get_msglevel(struct net_device *net_dev) +@@ -467,7 +467,7 @@ void efx_siena_ethtool_get_strings(struc + strings += (efx->type->describe_stats(efx, strings) * + ETH_GSTRING_LEN); + for (i = 0; i < EFX_ETHTOOL_SW_STAT_COUNT; i++) +- strlcpy(strings + i * ETH_GSTRING_LEN, ++ strscpy(strings + i * ETH_GSTRING_LEN, + efx_sw_stat_desc[i].name, ETH_GSTRING_LEN); + strings += EFX_ETHTOOL_SW_STAT_COUNT * ETH_GSTRING_LEN; + strings += (efx_describe_per_queue_stats(efx, strings) * +--- a/drivers/net/ethernet/sfc/siena/mcdi_mon.c ++++ b/drivers/net/ethernet/sfc/siena/mcdi_mon.c +@@ -285,7 +285,7 @@ efx_mcdi_mon_add_attr(struct efx_nic *ef + struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx); + struct efx_mcdi_mon_attribute *attr = &hwmon->attrs[hwmon->n_attrs]; + +- strlcpy(attr->name, name, sizeof(attr->name)); ++ strscpy(attr->name, name, sizeof(attr->name)); + attr->index = index; + attr->type = type; + if (type < ARRAY_SIZE(efx_mcdi_sensor_type)) +--- a/drivers/net/ethernet/sfc/siena/nic.c ++++ b/drivers/net/ethernet/sfc/siena/nic.c +@@ -458,7 +458,7 @@ size_t efx_siena_describe_stats(const st + for_each_set_bit(index, mask, count) { + if (desc[index].name) { + if (names) { +- strlcpy(names, desc[index].name, ++ strscpy(names, desc[index].name, + ETH_GSTRING_LEN); + names += ETH_GSTRING_LEN; + } +--- a/drivers/net/ethernet/sgi/ioc3-eth.c ++++ b/drivers/net/ethernet/sgi/ioc3-eth.c +@@ -1158,9 +1158,9 @@ static inline unsigned int ioc3_hash(con + static void ioc3_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, IOC3_NAME, sizeof(info->driver)); +- strlcpy(info->version, IOC3_VERSION, sizeof(info->version)); +- strlcpy(info->bus_info, pci_name(to_pci_dev(dev->dev.parent)), ++ strscpy(info->driver, IOC3_NAME, sizeof(info->driver)); ++ strscpy(info->version, IOC3_VERSION, sizeof(info->version)); ++ strscpy(info->bus_info, pci_name(to_pci_dev(dev->dev.parent)), + sizeof(info->bus_info)); + } + +--- a/drivers/net/ethernet/sis/sis190.c ++++ b/drivers/net/ethernet/sis/sis190.c +@@ -1769,9 +1769,9 @@ static void sis190_get_drvinfo(struct ne + { + struct sis190_private *tp = netdev_priv(dev); + +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->version, DRV_VERSION, sizeof(info->version)); +- strlcpy(info->bus_info, pci_name(tp->pci_dev), ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->version, DRV_VERSION, sizeof(info->version)); ++ strscpy(info->bus_info, pci_name(tp->pci_dev), + sizeof(info->bus_info)); + } + +--- a/drivers/net/ethernet/sis/sis900.c ++++ b/drivers/net/ethernet/sis/sis900.c +@@ -2025,9 +2025,9 @@ static void sis900_get_drvinfo(struct ne + { + struct sis900_private *sis_priv = netdev_priv(net_dev); + +- strlcpy(info->driver, SIS900_MODULE_NAME, sizeof(info->driver)); +- strlcpy(info->version, SIS900_DRV_VERSION, sizeof(info->version)); +- strlcpy(info->bus_info, pci_name(sis_priv->pci_dev), ++ strscpy(info->driver, SIS900_MODULE_NAME, sizeof(info->driver)); ++ strscpy(info->version, SIS900_DRV_VERSION, sizeof(info->version)); ++ strscpy(info->bus_info, pci_name(sis_priv->pci_dev), + sizeof(info->bus_info)); + } + +--- a/drivers/net/ethernet/smsc/epic100.c ++++ b/drivers/net/ethernet/smsc/epic100.c +@@ -1392,9 +1392,9 @@ static void netdev_get_drvinfo (struct n + { + struct epic_private *np = netdev_priv(dev); + +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->version, DRV_VERSION, sizeof(info->version)); +- strlcpy(info->bus_info, pci_name(np->pci_dev), sizeof(info->bus_info)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->version, DRV_VERSION, sizeof(info->version)); ++ strscpy(info->bus_info, pci_name(np->pci_dev), sizeof(info->bus_info)); + } + + static int netdev_get_link_ksettings(struct net_device *dev, +--- a/drivers/net/ethernet/smsc/smc911x.c ++++ b/drivers/net/ethernet/smsc/smc911x.c +@@ -1509,9 +1509,9 @@ smc911x_ethtool_set_link_ksettings(struc + static void + smc911x_ethtool_getdrvinfo(struct net_device *dev, struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, CARDNAME, sizeof(info->driver)); +- strlcpy(info->version, version, sizeof(info->version)); +- strlcpy(info->bus_info, dev_name(dev->dev.parent), ++ strscpy(info->driver, CARDNAME, sizeof(info->driver)); ++ strscpy(info->version, version, sizeof(info->version)); ++ strscpy(info->bus_info, dev_name(dev->dev.parent), + sizeof(info->bus_info)); + } + +--- a/drivers/net/ethernet/smsc/smc91c92_cs.c ++++ b/drivers/net/ethernet/smsc/smc91c92_cs.c +@@ -1909,8 +1909,8 @@ static int check_if_running(struct net_d + + static void smc_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->version, DRV_VERSION, sizeof(info->version)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->version, DRV_VERSION, sizeof(info->version)); + } + + static int smc_get_link_ksettings(struct net_device *dev, +--- a/drivers/net/ethernet/smsc/smc91x.c ++++ b/drivers/net/ethernet/smsc/smc91x.c +@@ -1588,9 +1588,9 @@ smc_ethtool_set_link_ksettings(struct ne + static void + smc_ethtool_getdrvinfo(struct net_device *dev, struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, CARDNAME, sizeof(info->driver)); +- strlcpy(info->version, version, sizeof(info->version)); +- strlcpy(info->bus_info, dev_name(dev->dev.parent), ++ strscpy(info->driver, CARDNAME, sizeof(info->driver)); ++ strscpy(info->version, version, sizeof(info->version)); ++ strscpy(info->bus_info, dev_name(dev->dev.parent), + sizeof(info->bus_info)); + } + +--- a/drivers/net/ethernet/smsc/smsc911x.c ++++ b/drivers/net/ethernet/smsc/smsc911x.c +@@ -1953,9 +1953,9 @@ static int smsc911x_set_mac_address(stru + static void smsc911x_ethtool_getdrvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, SMSC_CHIPNAME, sizeof(info->driver)); +- strlcpy(info->version, SMSC_DRV_VERSION, sizeof(info->version)); +- strlcpy(info->bus_info, dev_name(dev->dev.parent), ++ strscpy(info->driver, SMSC_CHIPNAME, sizeof(info->driver)); ++ strscpy(info->version, SMSC_DRV_VERSION, sizeof(info->version)); ++ strscpy(info->bus_info, dev_name(dev->dev.parent), + sizeof(info->bus_info)); + } + +--- a/drivers/net/ethernet/smsc/smsc9420.c ++++ b/drivers/net/ethernet/smsc/smsc9420.c +@@ -215,10 +215,10 @@ static void smsc9420_ethtool_get_drvinfo + { + struct smsc9420_pdata *pd = netdev_priv(netdev); + +- strlcpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver)); +- strlcpy(drvinfo->bus_info, pci_name(pd->pdev), ++ strscpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver)); ++ strscpy(drvinfo->bus_info, pci_name(pd->pdev), + sizeof(drvinfo->bus_info)); +- strlcpy(drvinfo->version, DRV_VERSION, sizeof(drvinfo->version)); ++ strscpy(drvinfo->version, DRV_VERSION, sizeof(drvinfo->version)); + } + + static u32 smsc9420_ethtool_get_msglevel(struct net_device *netdev) +--- a/drivers/net/ethernet/socionext/netsec.c ++++ b/drivers/net/ethernet/socionext/netsec.c +@@ -526,8 +526,8 @@ static int netsec_phy_read(struct mii_bu + static void netsec_et_get_drvinfo(struct net_device *net_device, + struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, "netsec", sizeof(info->driver)); +- strlcpy(info->bus_info, dev_name(net_device->dev.parent), ++ strscpy(info->driver, "netsec", sizeof(info->driver)); ++ strscpy(info->bus_info, dev_name(net_device->dev.parent), + sizeof(info->bus_info)); + } + +--- a/drivers/net/ethernet/socionext/sni_ave.c ++++ b/drivers/net/ethernet/socionext/sni_ave.c +@@ -395,8 +395,8 @@ static void ave_ethtool_get_drvinfo(stru + { + struct device *dev = ndev->dev.parent; + +- strlcpy(info->driver, dev->driver->name, sizeof(info->driver)); +- strlcpy(info->bus_info, dev_name(dev), sizeof(info->bus_info)); ++ strscpy(info->driver, dev->driver->name, sizeof(info->driver)); ++ strscpy(info->bus_info, dev_name(dev), sizeof(info->bus_info)); + ave_hw_read_version(ndev, info->fw_version, sizeof(info->fw_version)); + } + +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +@@ -275,15 +275,15 @@ static void stmmac_ethtool_getdrvinfo(st + struct stmmac_priv *priv = netdev_priv(dev); + + if (priv->plat->has_gmac || priv->plat->has_gmac4) +- strlcpy(info->driver, GMAC_ETHTOOL_NAME, sizeof(info->driver)); ++ strscpy(info->driver, GMAC_ETHTOOL_NAME, sizeof(info->driver)); + else if (priv->plat->has_xgmac) +- strlcpy(info->driver, XGMAC_ETHTOOL_NAME, sizeof(info->driver)); ++ strscpy(info->driver, XGMAC_ETHTOOL_NAME, sizeof(info->driver)); + else +- strlcpy(info->driver, MAC100_ETHTOOL_NAME, ++ strscpy(info->driver, MAC100_ETHTOOL_NAME, + sizeof(info->driver)); + + if (priv->plat->pdev) { +- strlcpy(info->bus_info, pci_name(priv->plat->pdev), ++ strscpy(info->bus_info, pci_name(priv->plat->pdev), + sizeof(info->bus_info)); + } + strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version)); +--- a/drivers/net/ethernet/sun/cassini.c ++++ b/drivers/net/ethernet/sun/cassini.c +@@ -4499,9 +4499,9 @@ static void cas_set_multicast(struct net + static void cas_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) + { + struct cas *cp = netdev_priv(dev); +- strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); +- strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version)); +- strlcpy(info->bus_info, pci_name(cp->pdev), sizeof(info->bus_info)); ++ strscpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); ++ strscpy(info->version, DRV_MODULE_VERSION, sizeof(info->version)); ++ strscpy(info->bus_info, pci_name(cp->pdev), sizeof(info->bus_info)); + } + + static int cas_get_link_ksettings(struct net_device *dev, +--- a/drivers/net/ethernet/sun/ldmvsw.c ++++ b/drivers/net/ethernet/sun/ldmvsw.c +@@ -63,8 +63,8 @@ static struct vio_version vsw_versions[] + static void vsw_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); +- strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version)); ++ strscpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); ++ strscpy(info->version, DRV_MODULE_VERSION, sizeof(info->version)); + } + + static u32 vsw_get_msglevel(struct net_device *dev) +--- a/drivers/net/ethernet/sun/niu.c ++++ b/drivers/net/ethernet/sun/niu.c +@@ -6780,12 +6780,12 @@ static void niu_get_drvinfo(struct net_d + struct niu *np = netdev_priv(dev); + struct niu_vpd *vpd = &np->vpd; + +- strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); +- strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version)); ++ strscpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); ++ strscpy(info->version, DRV_MODULE_VERSION, sizeof(info->version)); + snprintf(info->fw_version, sizeof(info->fw_version), "%d.%d", + vpd->fcode_major, vpd->fcode_minor); + if (np->parent->plat_type != PLAT_TYPE_NIU) +- strlcpy(info->bus_info, pci_name(np->pdev), ++ strscpy(info->bus_info, pci_name(np->pdev), + sizeof(info->bus_info)); + } + +--- a/drivers/net/ethernet/sun/sunbmac.c ++++ b/drivers/net/ethernet/sun/sunbmac.c +@@ -1038,8 +1038,8 @@ static void bigmac_set_multicast(struct + /* Ethtool support... */ + static void bigmac_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, "sunbmac", sizeof(info->driver)); +- strlcpy(info->version, "2.0", sizeof(info->version)); ++ strscpy(info->driver, "sunbmac", sizeof(info->driver)); ++ strscpy(info->version, "2.0", sizeof(info->version)); + } + + static u32 bigmac_get_link(struct net_device *dev) +--- a/drivers/net/ethernet/sun/sungem.c ++++ b/drivers/net/ethernet/sun/sungem.c +@@ -2522,9 +2522,9 @@ static void gem_get_drvinfo(struct net_d + { + struct gem *gp = netdev_priv(dev); + +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->version, DRV_VERSION, sizeof(info->version)); +- strlcpy(info->bus_info, pci_name(gp->pdev), sizeof(info->bus_info)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->version, DRV_VERSION, sizeof(info->version)); ++ strscpy(info->bus_info, pci_name(gp->pdev), sizeof(info->bus_info)); + } + + static int gem_get_link_ksettings(struct net_device *dev, +--- a/drivers/net/ethernet/sun/sunhme.c ++++ b/drivers/net/ethernet/sun/sunhme.c +@@ -2510,11 +2510,11 @@ static void hme_get_drvinfo(struct net_d + { + struct happy_meal *hp = netdev_priv(dev); + +- strlcpy(info->driver, "sunhme", sizeof(info->driver)); +- strlcpy(info->version, "2.02", sizeof(info->version)); ++ strscpy(info->driver, "sunhme", sizeof(info->driver)); ++ strscpy(info->version, "2.02", sizeof(info->version)); + if (hp->happy_flags & HFLAG_PCI) { + struct pci_dev *pdev = hp->happy_dev; +- strlcpy(info->bus_info, pci_name(pdev), sizeof(info->bus_info)); ++ strscpy(info->bus_info, pci_name(pdev), sizeof(info->bus_info)); + } + #ifdef CONFIG_SBUS + else { +--- a/drivers/net/ethernet/sun/sunqe.c ++++ b/drivers/net/ethernet/sun/sunqe.c +@@ -684,8 +684,8 @@ static void qe_get_drvinfo(struct net_de + struct sunqe *qep = netdev_priv(dev); + struct platform_device *op; + +- strlcpy(info->driver, "sunqe", sizeof(info->driver)); +- strlcpy(info->version, "3.0", sizeof(info->version)); ++ strscpy(info->driver, "sunqe", sizeof(info->driver)); ++ strscpy(info->version, "3.0", sizeof(info->version)); + + op = qep->op; + regs = of_get_property(op->dev.of_node, "reg", NULL); +--- a/drivers/net/ethernet/sun/sunvnet.c ++++ b/drivers/net/ethernet/sun/sunvnet.c +@@ -60,8 +60,8 @@ static struct vio_version vnet_versions[ + static void vnet_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); +- strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version)); ++ strscpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); ++ strscpy(info->version, DRV_MODULE_VERSION, sizeof(info->version)); + } + + static u32 vnet_get_msglevel(struct net_device *dev) +--- a/drivers/net/ethernet/synopsys/dwc-xlgmac-common.c ++++ b/drivers/net/ethernet/synopsys/dwc-xlgmac-common.c +@@ -54,8 +54,8 @@ static void xlgmac_default_config(struct + pdata->phy_speed = SPEED_25000; + pdata->sysclk_rate = XLGMAC_SYSCLOCK; + +- strlcpy(pdata->drv_name, XLGMAC_DRV_NAME, sizeof(pdata->drv_name)); +- strlcpy(pdata->drv_ver, XLGMAC_DRV_VERSION, sizeof(pdata->drv_ver)); ++ strscpy(pdata->drv_name, XLGMAC_DRV_NAME, sizeof(pdata->drv_name)); ++ strscpy(pdata->drv_ver, XLGMAC_DRV_VERSION, sizeof(pdata->drv_ver)); + } + + static void xlgmac_init_all_ops(struct xlgmac_pdata *pdata) +--- a/drivers/net/ethernet/synopsys/dwc-xlgmac-ethtool.c ++++ b/drivers/net/ethernet/synopsys/dwc-xlgmac-ethtool.c +@@ -102,9 +102,9 @@ static void xlgmac_ethtool_get_drvinfo(s + u32 ver = pdata->hw_feat.version; + u32 snpsver, devid, userver; + +- strlcpy(drvinfo->driver, pdata->drv_name, sizeof(drvinfo->driver)); +- strlcpy(drvinfo->version, pdata->drv_ver, sizeof(drvinfo->version)); +- strlcpy(drvinfo->bus_info, dev_name(pdata->dev), ++ strscpy(drvinfo->driver, pdata->drv_name, sizeof(drvinfo->driver)); ++ strscpy(drvinfo->version, pdata->drv_ver, sizeof(drvinfo->version)); ++ strscpy(drvinfo->bus_info, dev_name(pdata->dev), + sizeof(drvinfo->bus_info)); + /* S|SNPSVER: Synopsys-defined Version + * D|DEVID: Indicates the Device family +--- a/drivers/net/ethernet/tehuti/tehuti.c ++++ b/drivers/net/ethernet/tehuti/tehuti.c +@@ -2149,10 +2149,10 @@ bdx_get_drvinfo(struct net_device *netde + { + struct bdx_priv *priv = netdev_priv(netdev); + +- strlcpy(drvinfo->driver, BDX_DRV_NAME, sizeof(drvinfo->driver)); +- strlcpy(drvinfo->version, BDX_DRV_VERSION, sizeof(drvinfo->version)); +- strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version)); +- strlcpy(drvinfo->bus_info, pci_name(priv->pdev), ++ strscpy(drvinfo->driver, BDX_DRV_NAME, sizeof(drvinfo->driver)); ++ strscpy(drvinfo->version, BDX_DRV_VERSION, sizeof(drvinfo->version)); ++ strscpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version)); ++ strscpy(drvinfo->bus_info, pci_name(priv->pdev), + sizeof(drvinfo->bus_info)); + } + +--- a/drivers/net/ethernet/ti/am65-cpsw-ethtool.c ++++ b/drivers/net/ethernet/ti/am65-cpsw-ethtool.c +@@ -404,9 +404,9 @@ static void am65_cpsw_get_drvinfo(struct + { + struct am65_cpsw_common *common = am65_ndev_to_common(ndev); + +- strlcpy(info->driver, dev_driver_string(common->dev), ++ strscpy(info->driver, dev_driver_string(common->dev), + sizeof(info->driver)); +- strlcpy(info->bus_info, dev_name(common->dev), sizeof(info->bus_info)); ++ strscpy(info->bus_info, dev_name(common->dev), sizeof(info->bus_info)); + } + + static u32 am65_cpsw_get_msglevel(struct net_device *ndev) +--- a/drivers/net/ethernet/ti/cpmac.c ++++ b/drivers/net/ethernet/ti/cpmac.c +@@ -851,8 +851,8 @@ static int cpmac_set_ringparam(struct ne + static void cpmac_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, "cpmac", sizeof(info->driver)); +- strlcpy(info->version, CPMAC_VERSION, sizeof(info->version)); ++ strscpy(info->driver, "cpmac", sizeof(info->driver)); ++ strscpy(info->version, CPMAC_VERSION, sizeof(info->version)); + snprintf(info->bus_info, sizeof(info->bus_info), "%s", "cpmac"); + } + +--- a/drivers/net/ethernet/ti/cpsw.c ++++ b/drivers/net/ethernet/ti/cpsw.c +@@ -1180,9 +1180,9 @@ static void cpsw_get_drvinfo(struct net_ + struct cpsw_common *cpsw = ndev_to_cpsw(ndev); + struct platform_device *pdev = to_platform_device(cpsw->dev); + +- strlcpy(info->driver, "cpsw", sizeof(info->driver)); +- strlcpy(info->version, "1.0", sizeof(info->version)); +- strlcpy(info->bus_info, pdev->name, sizeof(info->bus_info)); ++ strscpy(info->driver, "cpsw", sizeof(info->driver)); ++ strscpy(info->version, "1.0", sizeof(info->version)); ++ strscpy(info->bus_info, pdev->name, sizeof(info->bus_info)); + } + + static int cpsw_set_pauseparam(struct net_device *ndev, +--- a/drivers/net/ethernet/ti/cpsw_new.c ++++ b/drivers/net/ethernet/ti/cpsw_new.c +@@ -1151,9 +1151,9 @@ static void cpsw_get_drvinfo(struct net_ + struct platform_device *pdev; + + pdev = to_platform_device(cpsw->dev); +- strlcpy(info->driver, "cpsw-switch", sizeof(info->driver)); +- strlcpy(info->version, "2.0", sizeof(info->version)); +- strlcpy(info->bus_info, pdev->name, sizeof(info->bus_info)); ++ strscpy(info->driver, "cpsw-switch", sizeof(info->driver)); ++ strscpy(info->version, "2.0", sizeof(info->version)); ++ strscpy(info->bus_info, pdev->name, sizeof(info->bus_info)); + } + + static int cpsw_set_pauseparam(struct net_device *ndev, +--- a/drivers/net/ethernet/ti/davinci_emac.c ++++ b/drivers/net/ethernet/ti/davinci_emac.c +@@ -375,8 +375,8 @@ static char *emac_rxhost_errcodes[16] = + static void emac_get_drvinfo(struct net_device *ndev, + struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, emac_version_string, sizeof(info->driver)); +- strlcpy(info->version, EMAC_MODULE_VERSION, sizeof(info->version)); ++ strscpy(info->driver, emac_version_string, sizeof(info->driver)); ++ strscpy(info->version, EMAC_MODULE_VERSION, sizeof(info->version)); + } + + /** +--- a/drivers/net/ethernet/ti/tlan.c ++++ b/drivers/net/ethernet/ti/tlan.c +@@ -762,12 +762,12 @@ static void tlan_get_drvinfo(struct net_ + { + struct tlan_priv *priv = netdev_priv(dev); + +- strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); ++ strscpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); + if (priv->pci_dev) +- strlcpy(info->bus_info, pci_name(priv->pci_dev), ++ strscpy(info->bus_info, pci_name(priv->pci_dev), + sizeof(info->bus_info)); + else +- strlcpy(info->bus_info, "EISA", sizeof(info->bus_info)); ++ strscpy(info->bus_info, "EISA", sizeof(info->bus_info)); + } + + static int tlan_get_eeprom_len(struct net_device *dev) +--- a/drivers/net/ethernet/toshiba/ps3_gelic_net.c ++++ b/drivers/net/ethernet/toshiba/ps3_gelic_net.c +@@ -1187,8 +1187,8 @@ int gelic_net_open(struct net_device *ne + void gelic_net_get_drvinfo(struct net_device *netdev, + struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->version, DRV_VERSION, sizeof(info->version)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->version, DRV_VERSION, sizeof(info->version)); + } + + static int gelic_ether_get_link_ksettings(struct net_device *netdev, +--- a/drivers/net/ethernet/toshiba/spider_net_ethtool.c ++++ b/drivers/net/ethernet/toshiba/spider_net_ethtool.c +@@ -63,12 +63,12 @@ spider_net_ethtool_get_drvinfo(struct ne + card = netdev_priv(netdev); + + /* clear and fill out info */ +- strlcpy(drvinfo->driver, spider_net_driver_name, ++ strscpy(drvinfo->driver, spider_net_driver_name, + sizeof(drvinfo->driver)); +- strlcpy(drvinfo->version, VERSION, sizeof(drvinfo->version)); +- strlcpy(drvinfo->fw_version, "no information", ++ strscpy(drvinfo->version, VERSION, sizeof(drvinfo->version)); ++ strscpy(drvinfo->fw_version, "no information", + sizeof(drvinfo->fw_version)); +- strlcpy(drvinfo->bus_info, pci_name(card->pdev), ++ strscpy(drvinfo->bus_info, pci_name(card->pdev), + sizeof(drvinfo->bus_info)); + } + +--- a/drivers/net/ethernet/toshiba/tc35815.c ++++ b/drivers/net/ethernet/toshiba/tc35815.c +@@ -1956,9 +1956,9 @@ static void tc35815_get_drvinfo(struct n + { + struct tc35815_local *lp = netdev_priv(dev); + +- strlcpy(info->driver, MODNAME, sizeof(info->driver)); +- strlcpy(info->version, DRV_VERSION, sizeof(info->version)); +- strlcpy(info->bus_info, pci_name(lp->pci_dev), sizeof(info->bus_info)); ++ strscpy(info->driver, MODNAME, sizeof(info->driver)); ++ strscpy(info->version, DRV_VERSION, sizeof(info->version)); ++ strscpy(info->bus_info, pci_name(lp->pci_dev), sizeof(info->bus_info)); + } + + static u32 tc35815_get_msglevel(struct net_device *dev) +--- a/drivers/net/ethernet/via/via-rhine.c ++++ b/drivers/net/ethernet/via/via-rhine.c +@@ -2286,8 +2286,8 @@ static void netdev_get_drvinfo(struct ne + { + struct device *hwdev = dev->dev.parent; + +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->bus_info, dev_name(hwdev), sizeof(info->bus_info)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->bus_info, dev_name(hwdev), sizeof(info->bus_info)); + } + + static int netdev_get_link_ksettings(struct net_device *dev, +--- a/drivers/net/ethernet/via/via-velocity.c ++++ b/drivers/net/ethernet/via/via-velocity.c +@@ -3422,13 +3422,13 @@ static void velocity_get_drvinfo(struct + { + struct velocity_info *vptr = netdev_priv(dev); + +- strlcpy(info->driver, VELOCITY_NAME, sizeof(info->driver)); +- strlcpy(info->version, VELOCITY_VERSION, sizeof(info->version)); ++ strscpy(info->driver, VELOCITY_NAME, sizeof(info->driver)); ++ strscpy(info->version, VELOCITY_VERSION, sizeof(info->version)); + if (vptr->pdev) +- strlcpy(info->bus_info, pci_name(vptr->pdev), ++ strscpy(info->bus_info, pci_name(vptr->pdev), + sizeof(info->bus_info)); + else +- strlcpy(info->bus_info, "platform", sizeof(info->bus_info)); ++ strscpy(info->bus_info, "platform", sizeof(info->bus_info)); + } + + static void velocity_ethtool_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) +--- a/drivers/net/ethernet/wiznet/w5100.c ++++ b/drivers/net/ethernet/wiznet/w5100.c +@@ -719,9 +719,9 @@ static void w5100_hw_close(struct w5100_ + static void w5100_get_drvinfo(struct net_device *ndev, + struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->version, DRV_VERSION, sizeof(info->version)); +- strlcpy(info->bus_info, dev_name(ndev->dev.parent), ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->version, DRV_VERSION, sizeof(info->version)); ++ strscpy(info->bus_info, dev_name(ndev->dev.parent), + sizeof(info->bus_info)); + } + +--- a/drivers/net/ethernet/wiznet/w5300.c ++++ b/drivers/net/ethernet/wiznet/w5300.c +@@ -282,9 +282,9 @@ static void w5300_hw_close(struct w5300_ + static void w5300_get_drvinfo(struct net_device *ndev, + struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); +- strlcpy(info->version, DRV_VERSION, sizeof(info->version)); +- strlcpy(info->bus_info, dev_name(ndev->dev.parent), ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->version, DRV_VERSION, sizeof(info->version)); ++ strscpy(info->bus_info, dev_name(ndev->dev.parent), + sizeof(info->bus_info)); + } + +--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c ++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +@@ -1284,8 +1284,8 @@ static const struct net_device_ops axien + static void axienet_ethtools_get_drvinfo(struct net_device *ndev, + struct ethtool_drvinfo *ed) + { +- strlcpy(ed->driver, DRIVER_NAME, sizeof(ed->driver)); +- strlcpy(ed->version, DRIVER_VERSION, sizeof(ed->version)); ++ strscpy(ed->driver, DRIVER_NAME, sizeof(ed->driver)); ++ strscpy(ed->version, DRIVER_VERSION, sizeof(ed->version)); + } + + /** +--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c ++++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c +@@ -1094,7 +1094,7 @@ static bool get_bool(struct platform_dev + static void xemaclite_ethtools_get_drvinfo(struct net_device *ndev, + struct ethtool_drvinfo *ed) + { +- strlcpy(ed->driver, DRIVER_NAME, sizeof(ed->driver)); ++ strscpy(ed->driver, DRIVER_NAME, sizeof(ed->driver)); + } + + static const struct ethtool_ops xemaclite_ethtool_ops = { +--- a/drivers/net/ethernet/xircom/xirc2ps_cs.c ++++ b/drivers/net/ethernet/xircom/xirc2ps_cs.c +@@ -1402,7 +1402,7 @@ do_open(struct net_device *dev) + static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) + { +- strlcpy(info->driver, "xirc2ps_cs", sizeof(info->driver)); ++ strscpy(info->driver, "xirc2ps_cs", sizeof(info->driver)); + snprintf(info->bus_info, sizeof(info->bus_info), "PCMCIA 0x%lx", + dev->base_addr); + } +--- a/drivers/net/ethernet/xscale/ixp4xx_eth.c ++++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c +@@ -981,11 +981,11 @@ static void ixp4xx_get_drvinfo(struct ne + { + struct port *port = netdev_priv(dev); + +- strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); ++ strscpy(info->driver, DRV_NAME, sizeof(info->driver)); + snprintf(info->fw_version, sizeof(info->fw_version), "%u:%u:%u:%u", + port->firmware[0], port->firmware[1], + port->firmware[2], port->firmware[3]); +- strlcpy(info->bus_info, "internal", sizeof(info->bus_info)); ++ strscpy(info->bus_info, "internal", sizeof(info->bus_info)); + } + + int ixp46x_phc_index = -1; diff --git a/patches.suse/net-ethernet-stmmac-fix-write-to-sgmii_adapter_base.patch b/patches.suse/net-ethernet-stmmac-fix-write-to-sgmii_adapter_base.patch new file mode 100644 index 0000000..18949a2 --- /dev/null +++ b/patches.suse/net-ethernet-stmmac-fix-write-to-sgmii_adapter_base.patch @@ -0,0 +1,60 @@ +From e29bc4463e51d1c045eb804fde84e94be39c1dca Mon Sep 17 00:00:00 2001 +From: Dinh Nguyen +Date: Wed, 20 Apr 2022 10:23:45 -0500 +Subject: [PATCH 08/19] net: ethernet: stmmac: fix write to sgmii_adapter_base +Git-commit: 5fd1fe4807f91ea0cca043114d929faa11bd4190 +Patch-mainline: v5.18-rc5 +References: git-fixes + +I made a mistake with the commit a6aaa0032424 ("net: ethernet: stmmac: +fix altr_tse_pcs function when using a fixed-link"). I should have +tested against both scenario of having a SGMII interface and one +without. + +Without the SGMII PCS TSE adpater, the sgmii_adapter_base address is +NULL, thus a write to this address will fail. + +Cc: stable@vger.kernel.org +Fixes: a6aaa0032424 ("net: ethernet: stmmac: fix altr_tse_pcs function when using a fixed-link") +Signed-off-by: Dinh Nguyen +Link: https://lore.kernel.org/r/20220420152345.27415-1-dinguyen@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c +index ac9e6c7a33b5..6b447d8f0bd8 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c +@@ -65,8 +65,9 @@ static void socfpga_dwmac_fix_mac_speed(void *priv, unsigned int speed) + struct phy_device *phy_dev = ndev->phydev; + u32 val; + +- writew(SGMII_ADAPTER_DISABLE, +- sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG); ++ if (sgmii_adapter_base) ++ writew(SGMII_ADAPTER_DISABLE, ++ sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG); + + if (splitter_base) { + val = readl(splitter_base + EMAC_SPLITTER_CTRL_REG); +@@ -88,10 +89,11 @@ static void socfpga_dwmac_fix_mac_speed(void *priv, unsigned int speed) + writel(val, splitter_base + EMAC_SPLITTER_CTRL_REG); + } + +- writew(SGMII_ADAPTER_ENABLE, +- sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG); +- if (phy_dev) ++ if (phy_dev && sgmii_adapter_base) { ++ writew(SGMII_ADAPTER_ENABLE, ++ sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG); + tse_pcs_fix_mac_speed(&dwmac->pcs, phy_dev, speed); ++ } + } + + static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *dev) +-- +2.16.4 + diff --git a/patches.suse/net-ethernet-ti-am65-cpsw-Fix-devlink-port-register-.patch b/patches.suse/net-ethernet-ti-am65-cpsw-Fix-devlink-port-register-.patch new file mode 100644 index 0000000..eeca81f --- /dev/null +++ b/patches.suse/net-ethernet-ti-am65-cpsw-Fix-devlink-port-register-.patch @@ -0,0 +1,95 @@ +From 153e68b10d21e3063eed9492eebf6e53714c89be Mon Sep 17 00:00:00 2001 +From: Siddharth Vadapalli +Date: Wed, 6 Jul 2022 12:32:08 +0530 +Subject: [PATCH 03/28] net: ethernet: ti: am65-cpsw: Fix devlink port register + sequence +Git-commit: 0680e20af5fbf41df8a11b11bd9a7c25b2ca0746 +Patch-mainline: v5.19-rc7 +References: git-fixes + +Renaming interfaces using udevd depends on the interface being registered +before its netdev is registered. Otherwise, udevd reads an empty +phys_port_name value, resulting in the interface not being renamed. + +Fix this by registering the interface before registering its netdev +by invoking am65_cpsw_nuss_register_devlink() before invoking +register_netdev() for the interface. + +Move the function call to devlink_port_type_eth_set(), invoking it after +register_netdev() is invoked, to ensure that netlink notification for the +port state change is generated after the netdev is completely initialized. + +Fixes: 58356eb31d60 ("net: ti: am65-cpsw-nuss: Add devlink support") +Signed-off-by: Siddharth Vadapalli +Link: https://lore.kernel.org/r/20220706070208.12207-1-s-vadapalli@ti.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/ti/am65-cpsw-nuss.c | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c +index fca47649fcba..7b6ef93b7e25 100644 +--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c ++++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c +@@ -2446,7 +2446,6 @@ static int am65_cpsw_nuss_register_devlink(struct am65_cpsw_common *common) + port->port_id, ret); + goto dl_port_unreg; + } +- devlink_port_type_eth_set(dl_port, port->ndev); + } + devlink_register(common->devlink); + return ret; +@@ -2490,6 +2489,7 @@ static void am65_cpsw_unregister_devlink(struct am65_cpsw_common *common) + static int am65_cpsw_nuss_register_ndevs(struct am65_cpsw_common *common) + { + struct device *dev = common->dev; ++ struct devlink_port *dl_port; + struct am65_cpsw_port *port; + int ret = 0, i; + +@@ -2506,6 +2506,10 @@ static int am65_cpsw_nuss_register_ndevs(struct am65_cpsw_common *common) + return ret; + } + ++ ret = am65_cpsw_nuss_register_devlink(common); ++ if (ret) ++ return ret; ++ + for (i = 0; i < common->port_num; i++) { + port = &common->ports[i]; + +@@ -2518,25 +2522,24 @@ static int am65_cpsw_nuss_register_ndevs(struct am65_cpsw_common *common) + i, ret); + goto err_cleanup_ndev; + } ++ ++ dl_port = &port->devlink_port; ++ devlink_port_type_eth_set(dl_port, port->ndev); + } + + ret = am65_cpsw_register_notifiers(common); + if (ret) + goto err_cleanup_ndev; + +- ret = am65_cpsw_nuss_register_devlink(common); +- if (ret) +- goto clean_unregister_notifiers; +- + /* can't auto unregister ndev using devm_add_action() due to + * devres release sequence in DD core for DMA + */ + + return 0; +-clean_unregister_notifiers: +- am65_cpsw_unregister_notifiers(common); ++ + err_cleanup_ndev: + am65_cpsw_nuss_cleanup_ndev(common); ++ am65_cpsw_unregister_devlink(common); + + return ret; + } +-- +2.16.4 + diff --git a/patches.suse/net-ftgmac100-Hold-reference-returned-by-of_get_chil.patch b/patches.suse/net-ftgmac100-Hold-reference-returned-by-of_get_chil.patch new file mode 100644 index 0000000..c67ef39 --- /dev/null +++ b/patches.suse/net-ftgmac100-Hold-reference-returned-by-of_get_chil.patch @@ -0,0 +1,57 @@ +From 439b1fc5d61e0770415da026e545b7cba21c7ae6 Mon Sep 17 00:00:00 2001 +From: Liang He +Date: Tue, 12 Jul 2022 14:14:17 +0800 +Subject: [PATCH 10/28] net: ftgmac100: Hold reference returned by + of_get_child_by_name() +Git-commit: 49b9f431ff0d845a36be0b3ede35ec324f2e5fee +Patch-mainline: v5.19-rc7 +References: git-fixes + +In ftgmac100_probe(), we should hold the refernece returned by +of_get_child_by_name() and use it to call of_node_put() for +reference balance. + +Fixes: 39bfab8844a0 ("net: ftgmac100: Add support for DT phy-handle property") +Signed-off-by: Liang He +Signed-off-by: David S. Miller +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/faraday/ftgmac100.c | 15 ++++++++++++++- + 1 file changed, 14 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c +index 469032009261..465cacc647c9 100644 +--- a/drivers/net/ethernet/faraday/ftgmac100.c ++++ b/drivers/net/ethernet/faraday/ftgmac100.c +@@ -1746,6 +1746,19 @@ static int ftgmac100_setup_clk(struct ftgmac100 *priv) + return rc; + } + ++static bool ftgmac100_has_child_node(struct device_node *np, const char *name) ++{ ++ struct device_node *child_np = of_get_child_by_name(np, name); ++ bool ret = false; ++ ++ if (child_np) { ++ ret = true; ++ of_node_put(child_np); ++ } ++ ++ return ret; ++} ++ + static int ftgmac100_probe(struct platform_device *pdev) + { + struct resource *res; +@@ -1865,7 +1878,7 @@ static int ftgmac100_probe(struct platform_device *pdev) + + /* Display what we found */ + phy_attached_info(phy); +- } else if (np && !of_get_child_by_name(np, "mdio")) { ++ } else if (np && !ftgmac100_has_child_node(np, "mdio")) { + /* Support legacy ASPEED devicetree descriptions that decribe a + * MAC with an embedded MDIO controller but have no "mdio" + * child node. Automatically scan the MDIO bus for available +-- +2.16.4 + diff --git a/patches.suse/net-hns3-add-netdev-reset-check-for-hns3_set_tunable.patch b/patches.suse/net-hns3-add-netdev-reset-check-for-hns3_set_tunable.patch new file mode 100644 index 0000000..257415e --- /dev/null +++ b/patches.suse/net-hns3-add-netdev-reset-check-for-hns3_set_tunable.patch @@ -0,0 +1,42 @@ +From b019223d0ac1b9b3c078892edb3a57e199ecde9b Mon Sep 17 00:00:00 2001 +From: Hao Chen +Date: Sat, 26 Mar 2022 17:51:03 +0800 +Subject: [PATCH 04/19] net: hns3: add netdev reset check for + hns3_set_tunable() +Git-commit: f5cd60169f981ca737c9e49c446506dfafc90a35 +Patch-mainline: v5.18-rc1 +References: git-fixes + +When pci device reset failed, it does uninit operation and priv->ring +is NULL, it causes accessing NULL pointer error. + +Add netdev reset check for hns3_set_tunable() to fix it. + +Fixes: 99f6b5fb5f63 ("net: hns3: use bounce buffer when rx page can not be reused") +Signed-off-by: Hao Chen +Signed-off-by: Guangbin Huang +Signed-off-by: David S. Miller +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c +index 0a81bcc7d61c..759d2949c7d7 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c +@@ -1730,6 +1730,11 @@ static int hns3_set_tunable(struct net_device *netdev, + struct hnae3_handle *h = priv->ae_handle; + int i, ret = 0; + ++ if (hns3_nic_resetting(netdev) || !priv->ring) { ++ netdev_err(netdev, "failed to set tunable value, dev resetting!"); ++ return -EBUSY; ++ } ++ + switch (tuna->id) { + case ETHTOOL_TX_COPYBREAK: + priv->tx_copybreak = *(u32 *)data; +-- +2.16.4 + diff --git a/patches.suse/net-hns3-don-t-push-link-state-to-VF-if-unalive.patch b/patches.suse/net-hns3-don-t-push-link-state-to-VF-if-unalive.patch new file mode 100644 index 0000000..de169cd --- /dev/null +++ b/patches.suse/net-hns3-don-t-push-link-state-to-VF-if-unalive.patch @@ -0,0 +1,40 @@ +From ec12646383ca7cafcd7dc6f0a13967c8eeeb43b3 Mon Sep 17 00:00:00 2001 +From: Jian Shen +Date: Sat, 11 Jun 2022 20:25:25 +0800 +Subject: [PATCH 19/32] net: hns3: don't push link state to VF if unalive +Git-commit: 283847e3ef6dbf79bf67083b5ce7b8033e8b6f34 +References: git-fixes +Patch-mainline: v5.19-rc3 + +It's unnecessary to push link state to unalive VF, and the VF will +query link state from PF when it being start works. + +Fixes: 18b6e31f8bf4 ("net: hns3: PF add support for pushing link status to VFs") +Signed-off-by: Jian Shen +Signed-off-by: Guangbin Huang +Signed-off-by: David S. Miller +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +index 667b1ad5f95e..6dabcf1fdc98 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +@@ -3471,6 +3471,12 @@ static int hclge_set_vf_link_state(struct hnae3_handle *handle, int vf, + link_state_old = vport->vf_info.link_state; + vport->vf_info.link_state = link_state; + ++ /* return success directly if the VF is unalive, VF will ++ * query link state itself when it starts work. ++ */ ++ if (!test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state)) ++ return 0; ++ + ret = hclge_push_vf_link_status(vport); + if (ret) { + vport->vf_info.link_state = link_state_old; +-- +2.16.4 + diff --git a/patches.suse/net-hns3-set-port-base-vlan-tbl_sta-to-false-before-.patch b/patches.suse/net-hns3-set-port-base-vlan-tbl_sta-to-false-before-.patch new file mode 100644 index 0000000..8b49b94 --- /dev/null +++ b/patches.suse/net-hns3-set-port-base-vlan-tbl_sta-to-false-before-.patch @@ -0,0 +1,35 @@ +From 84dd39ee302a7d1dd799c3b192cf5df6a55914cb Mon Sep 17 00:00:00 2001 +From: Guangbin Huang +Date: Sat, 11 Jun 2022 20:25:24 +0800 +Subject: [PATCH 18/32] net: hns3: set port base vlan tbl_sta to false before + removing old vlan +Git-commit: 9eda7d8bcbdb6909f202edeedff51948f1cad1e5 +References: git-fixes +Patch-mainline: v5.19-rc3 + +When modify port base vlan, the port base vlan tbl_sta needs to set to +false before removing old vlan, to indicate this operation is not finish. + +Fixes: c0f46de30c96 ("net: hns3: fix port base vlan add fail when concurrent with reset") +Signed-off-by: Guangbin Huang +Signed-off-by: David S. Miller +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +index c081fc1231a5..667b1ad5f95e 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +@@ -10569,6 +10569,7 @@ int hclge_update_port_base_vlan_cfg(struct hclge_vport *vport, u16 state, + if (ret) + return ret; + ++ vport->port_base_vlan_cfg.tbl_sta = false; + /* remove old VLAN tag */ + if (old_vlan_info->vlan_tag == 0) + ret = hclge_set_vf_vlan_common(hdev, vport->vport_id, +-- +2.16.4 + diff --git a/patches.suse/net-huawei-hinic-Use-devm_kcalloc-instead-of-devm_kz.patch b/patches.suse/net-huawei-hinic-Use-devm_kcalloc-instead-of-devm_kz.patch new file mode 100644 index 0000000..afb34c4 --- /dev/null +++ b/patches.suse/net-huawei-hinic-Use-devm_kcalloc-instead-of-devm_kz.patch @@ -0,0 +1,257 @@ +From ab22f8d11adbb16d051e66376f6d14c1b5a0c037 Mon Sep 17 00:00:00 2001 +From: "Gustavo A. R. Silva" +Date: Tue, 7 Dec 2021 22:03:11 -0600 +Subject: [PATCH 04/32] net: huawei: hinic: Use devm_kcalloc() instead of + devm_kzalloc() +Git-commit: 9d922f5df53844228b9f7c62f2593f4f06c0b69b +References: git-fixes +Patch-mainline: v5.17-rc1 + +Use 2-factor multiplication argument form devm_kcalloc() instead +of devm_kzalloc(). + +Link: https://github.com/KSPP/linux/issues/162 +Signed-off-by: Gustavo A. R. Silva +Reviewed-by: Kees Cook +Link: https://lore.kernel.org/r/20211208040311.GA169838@embeddedor +Signed-off-by: Jakub Kicinski +Signed-off-by: Denis Kirjanov +--- + .../net/ethernet/huawei/hinic/hinic_hw_api_cmd.c | 5 ++--- + drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c | 10 ++++------ + drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c | 5 ++--- + drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.c | 9 ++++----- + drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c | 23 +++++++++++----------- + drivers/net/ethernet/huawei/hinic/hinic_main.c | 10 ++++------ + drivers/net/ethernet/huawei/hinic/hinic_tx.c | 9 ++++----- + 7 files changed, 31 insertions(+), 40 deletions(-) + +diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.c +index 06586173add7..998717f02136 100644 +--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.c ++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.c +@@ -814,7 +814,6 @@ static int api_chain_init(struct hinic_api_cmd_chain *chain, + { + struct hinic_hwif *hwif = attr->hwif; + struct pci_dev *pdev = hwif->pdev; +- size_t cell_ctxt_size; + + chain->hwif = hwif; + chain->chain_type = attr->chain_type; +@@ -826,8 +825,8 @@ static int api_chain_init(struct hinic_api_cmd_chain *chain, + + sema_init(&chain->sem, 1); + +- cell_ctxt_size = chain->num_cells * sizeof(*chain->cell_ctxt); +- chain->cell_ctxt = devm_kzalloc(&pdev->dev, cell_ctxt_size, GFP_KERNEL); ++ chain->cell_ctxt = devm_kcalloc(&pdev->dev, chain->num_cells, ++ sizeof(*chain->cell_ctxt), GFP_KERNEL); + if (!chain->cell_ctxt) + return -ENOMEM; + +diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c +index 307a6d4af993..a627237f694b 100644 +--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c ++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c +@@ -796,11 +796,10 @@ static int init_cmdqs_ctxt(struct hinic_hwdev *hwdev, + struct hinic_cmdq_ctxt *cmdq_ctxts; + struct pci_dev *pdev = hwif->pdev; + struct hinic_pfhwdev *pfhwdev; +- size_t cmdq_ctxts_size; + int err; + +- cmdq_ctxts_size = HINIC_MAX_CMDQ_TYPES * sizeof(*cmdq_ctxts); +- cmdq_ctxts = devm_kzalloc(&pdev->dev, cmdq_ctxts_size, GFP_KERNEL); ++ cmdq_ctxts = devm_kcalloc(&pdev->dev, HINIC_MAX_CMDQ_TYPES, ++ sizeof(*cmdq_ctxts), GFP_KERNEL); + if (!cmdq_ctxts) + return -ENOMEM; + +@@ -884,7 +883,6 @@ int hinic_init_cmdqs(struct hinic_cmdqs *cmdqs, struct hinic_hwif *hwif, + struct hinic_func_to_io *func_to_io = cmdqs_to_func_to_io(cmdqs); + struct pci_dev *pdev = hwif->pdev; + struct hinic_hwdev *hwdev; +- size_t saved_wqs_size; + u16 max_wqe_size; + int err; + +@@ -895,8 +893,8 @@ int hinic_init_cmdqs(struct hinic_cmdqs *cmdqs, struct hinic_hwif *hwif, + if (!cmdqs->cmdq_buf_pool) + return -ENOMEM; + +- saved_wqs_size = HINIC_MAX_CMDQ_TYPES * sizeof(struct hinic_wq); +- cmdqs->saved_wqs = devm_kzalloc(&pdev->dev, saved_wqs_size, GFP_KERNEL); ++ cmdqs->saved_wqs = devm_kcalloc(&pdev->dev, HINIC_MAX_CMDQ_TYPES, ++ sizeof(*cmdqs->saved_wqs), GFP_KERNEL); + if (!cmdqs->saved_wqs) { + err = -ENOMEM; + goto err_saved_wqs; +diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c +index b2ece3adbc72..1db602091b39 100644 +--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c ++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c +@@ -162,7 +162,6 @@ static int init_msix(struct hinic_hwdev *hwdev) + struct hinic_hwif *hwif = hwdev->hwif; + struct pci_dev *pdev = hwif->pdev; + int nr_irqs, num_aeqs, num_ceqs; +- size_t msix_entries_size; + int i, err; + + num_aeqs = HINIC_HWIF_NUM_AEQS(hwif); +@@ -171,8 +170,8 @@ static int init_msix(struct hinic_hwdev *hwdev) + if (nr_irqs > HINIC_HWIF_NUM_IRQS(hwif)) + nr_irqs = HINIC_HWIF_NUM_IRQS(hwif); + +- msix_entries_size = nr_irqs * sizeof(*hwdev->msix_entries); +- hwdev->msix_entries = devm_kzalloc(&pdev->dev, msix_entries_size, ++ hwdev->msix_entries = devm_kcalloc(&pdev->dev, nr_irqs, ++ sizeof(*hwdev->msix_entries), + GFP_KERNEL); + if (!hwdev->msix_entries) + return -ENOMEM; +diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.c +index d3fc05a07fdb..045c47786a04 100644 +--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.c ++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.c +@@ -631,16 +631,15 @@ static int alloc_eq_pages(struct hinic_eq *eq) + struct hinic_hwif *hwif = eq->hwif; + struct pci_dev *pdev = hwif->pdev; + u32 init_val, addr, val; +- size_t addr_size; + int err, pg; + +- addr_size = eq->num_pages * sizeof(*eq->dma_addr); +- eq->dma_addr = devm_kzalloc(&pdev->dev, addr_size, GFP_KERNEL); ++ eq->dma_addr = devm_kcalloc(&pdev->dev, eq->num_pages, ++ sizeof(*eq->dma_addr), GFP_KERNEL); + if (!eq->dma_addr) + return -ENOMEM; + +- addr_size = eq->num_pages * sizeof(*eq->virt_addr); +- eq->virt_addr = devm_kzalloc(&pdev->dev, addr_size, GFP_KERNEL); ++ eq->virt_addr = devm_kcalloc(&pdev->dev, eq->num_pages, ++ sizeof(*eq->virt_addr), GFP_KERNEL); + if (!eq->virt_addr) { + err = -ENOMEM; + goto err_virt_addr_alloc; +diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c +index 0c1b0a91b1ae..f7dc7d825f63 100644 +--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c ++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c +@@ -193,20 +193,20 @@ static int alloc_page_arrays(struct hinic_wqs *wqs) + { + struct hinic_hwif *hwif = wqs->hwif; + struct pci_dev *pdev = hwif->pdev; +- size_t size; + +- size = wqs->num_pages * sizeof(*wqs->page_paddr); +- wqs->page_paddr = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); ++ wqs->page_paddr = devm_kcalloc(&pdev->dev, wqs->num_pages, ++ sizeof(*wqs->page_paddr), GFP_KERNEL); + if (!wqs->page_paddr) + return -ENOMEM; + +- size = wqs->num_pages * sizeof(*wqs->page_vaddr); +- wqs->page_vaddr = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); ++ wqs->page_vaddr = devm_kcalloc(&pdev->dev, wqs->num_pages, ++ sizeof(*wqs->page_vaddr), GFP_KERNEL); + if (!wqs->page_vaddr) + goto err_page_vaddr; + +- size = wqs->num_pages * sizeof(*wqs->shadow_page_vaddr); +- wqs->shadow_page_vaddr = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); ++ wqs->shadow_page_vaddr = devm_kcalloc(&pdev->dev, wqs->num_pages, ++ sizeof(*wqs->shadow_page_vaddr), ++ GFP_KERNEL); + if (!wqs->shadow_page_vaddr) + goto err_page_shadow_vaddr; + +@@ -379,15 +379,14 @@ static int alloc_wqes_shadow(struct hinic_wq *wq) + { + struct hinic_hwif *hwif = wq->hwif; + struct pci_dev *pdev = hwif->pdev; +- size_t size; + +- size = wq->num_q_pages * wq->max_wqe_size; +- wq->shadow_wqe = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); ++ wq->shadow_wqe = devm_kcalloc(&pdev->dev, wq->num_q_pages, ++ wq->max_wqe_size, GFP_KERNEL); + if (!wq->shadow_wqe) + return -ENOMEM; + +- size = wq->num_q_pages * sizeof(wq->prod_idx); +- wq->shadow_idx = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); ++ wq->shadow_idx = devm_kcalloc(&pdev->dev, wq->num_q_pages, ++ sizeof(wq->prod_idx), GFP_KERNEL); + if (!wq->shadow_idx) + goto err_shadow_idx; + +diff --git a/drivers/net/ethernet/huawei/hinic/hinic_main.c b/drivers/net/ethernet/huawei/hinic/hinic_main.c +index 30b9c5bd0c85..866604a3a0e9 100644 +--- a/drivers/net/ethernet/huawei/hinic/hinic_main.c ++++ b/drivers/net/ethernet/huawei/hinic/hinic_main.c +@@ -144,13 +144,12 @@ static int create_txqs(struct hinic_dev *nic_dev) + { + int err, i, j, num_txqs = hinic_hwdev_num_qps(nic_dev->hwdev); + struct net_device *netdev = nic_dev->netdev; +- size_t txq_size; + + if (nic_dev->txqs) + return -EINVAL; + +- txq_size = num_txqs * sizeof(*nic_dev->txqs); +- nic_dev->txqs = devm_kzalloc(&netdev->dev, txq_size, GFP_KERNEL); ++ nic_dev->txqs = devm_kcalloc(&netdev->dev, num_txqs, ++ sizeof(*nic_dev->txqs), GFP_KERNEL); + if (!nic_dev->txqs) + return -ENOMEM; + +@@ -241,13 +240,12 @@ static int create_rxqs(struct hinic_dev *nic_dev) + { + int err, i, j, num_rxqs = hinic_hwdev_num_qps(nic_dev->hwdev); + struct net_device *netdev = nic_dev->netdev; +- size_t rxq_size; + + if (nic_dev->rxqs) + return -EINVAL; + +- rxq_size = num_rxqs * sizeof(*nic_dev->rxqs); +- nic_dev->rxqs = devm_kzalloc(&netdev->dev, rxq_size, GFP_KERNEL); ++ nic_dev->rxqs = devm_kcalloc(&netdev->dev, num_rxqs, ++ sizeof(*nic_dev->rxqs), GFP_KERNEL); + if (!nic_dev->rxqs) + return -ENOMEM; + +diff --git a/drivers/net/ethernet/huawei/hinic/hinic_tx.c b/drivers/net/ethernet/huawei/hinic/hinic_tx.c +index c5bdb0d374ef..a984a7a6dd2e 100644 +--- a/drivers/net/ethernet/huawei/hinic/hinic_tx.c ++++ b/drivers/net/ethernet/huawei/hinic/hinic_tx.c +@@ -862,7 +862,6 @@ int hinic_init_txq(struct hinic_txq *txq, struct hinic_sq *sq, + struct hinic_dev *nic_dev = netdev_priv(netdev); + struct hinic_hwdev *hwdev = nic_dev->hwdev; + int err, irqname_len; +- size_t sges_size; + + txq->netdev = netdev; + txq->sq = sq; +@@ -871,13 +870,13 @@ int hinic_init_txq(struct hinic_txq *txq, struct hinic_sq *sq, + + txq->max_sges = HINIC_MAX_SQ_BUFDESCS; + +- sges_size = txq->max_sges * sizeof(*txq->sges); +- txq->sges = devm_kzalloc(&netdev->dev, sges_size, GFP_KERNEL); ++ txq->sges = devm_kcalloc(&netdev->dev, txq->max_sges, ++ sizeof(*txq->sges), GFP_KERNEL); + if (!txq->sges) + return -ENOMEM; + +- sges_size = txq->max_sges * sizeof(*txq->free_sges); +- txq->free_sges = devm_kzalloc(&netdev->dev, sges_size, GFP_KERNEL); ++ txq->free_sges = devm_kcalloc(&netdev->dev, txq->max_sges, ++ sizeof(*txq->free_sges), GFP_KERNEL); + if (!txq->free_sges) { + err = -ENOMEM; + goto err_alloc_free_sges; +-- +2.16.4 + diff --git a/patches.suse/net-ieee802154-fix-uninit-value-bug-in-dgram_sendmsg.patch b/patches.suse/net-ieee802154-fix-uninit-value-bug-in-dgram_sendmsg.patch new file mode 100644 index 0000000..3ad7fa4 --- /dev/null +++ b/patches.suse/net-ieee802154-fix-uninit-value-bug-in-dgram_sendmsg.patch @@ -0,0 +1,173 @@ +From 94160108a70c8af17fa1484a37e05181c0e094af Mon Sep 17 00:00:00 2001 +From: Haimin Zhang +Date: Thu, 8 Sep 2022 20:19:27 +0800 +Subject: [PATCH] net/ieee802154: fix uninit value bug in dgram_sendmsg +Git-commit: 94160108a70c8af17fa1484a37e05181c0e094af +Patch-mainline: v6.0-rc7 +References: git-fixes + +There is uninit value bug in dgram_sendmsg function in +net/ieee802154/socket.c when the length of valid data pointed by the +msg->msg_name isn't verified. + +We introducing a helper function ieee802154_sockaddr_check_size to +check namelen. First we check there is addr_type in ieee802154_addr_sa. +Then, we check namelen according to addr_type. + +Also fixed in raw_bind, dgram_bind, dgram_connect. + +Signed-off-by: Haimin Zhang +Signed-off-by: David S. Miller +Acked-by: Takashi Iwai + +--- + include/net/ieee802154_netdev.h | 37 +++++++++++++++++++++++++++++ + net/ieee802154/socket.c | 42 ++++++++++++++++++--------------- + 2 files changed, 60 insertions(+), 19 deletions(-) + +diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h +index d0d188c3294b..a8994f307fc3 100644 +--- a/include/net/ieee802154_netdev.h ++++ b/include/net/ieee802154_netdev.h +@@ -15,6 +15,22 @@ + #ifndef IEEE802154_NETDEVICE_H + #define IEEE802154_NETDEVICE_H + ++#define IEEE802154_REQUIRED_SIZE(struct_type, member) \ ++ (offsetof(typeof(struct_type), member) + \ ++ sizeof(((typeof(struct_type) *)(NULL))->member)) ++ ++#define IEEE802154_ADDR_OFFSET \ ++ offsetof(typeof(struct sockaddr_ieee802154), addr) ++ ++#define IEEE802154_MIN_NAMELEN (IEEE802154_ADDR_OFFSET + \ ++ IEEE802154_REQUIRED_SIZE(struct ieee802154_addr_sa, addr_type)) ++ ++#define IEEE802154_NAMELEN_SHORT (IEEE802154_ADDR_OFFSET + \ ++ IEEE802154_REQUIRED_SIZE(struct ieee802154_addr_sa, short_addr)) ++ ++#define IEEE802154_NAMELEN_LONG (IEEE802154_ADDR_OFFSET + \ ++ IEEE802154_REQUIRED_SIZE(struct ieee802154_addr_sa, hwaddr)) ++ + #include + #include + #include +@@ -165,6 +181,27 @@ static inline void ieee802154_devaddr_to_raw(void *raw, __le64 addr) + memcpy(raw, &temp, IEEE802154_ADDR_LEN); + } + ++static inline int ++ieee802154_sockaddr_check_size(struct sockaddr_ieee802154 *daddr, int len) ++{ ++ struct ieee802154_addr_sa *sa; ++ ++ sa = &daddr->addr; ++ if (len < IEEE802154_MIN_NAMELEN) ++ return -EINVAL; ++ switch (sa->addr_type) { ++ case IEEE802154_ADDR_SHORT: ++ if (len < IEEE802154_NAMELEN_SHORT) ++ return -EINVAL; ++ break; ++ case IEEE802154_ADDR_LONG: ++ if (len < IEEE802154_NAMELEN_LONG) ++ return -EINVAL; ++ break; ++ } ++ return 0; ++} ++ + static inline void ieee802154_addr_from_sa(struct ieee802154_addr *a, + const struct ieee802154_addr_sa *sa) + { +diff --git a/net/ieee802154/socket.c b/net/ieee802154/socket.c +index 718fb77bb372..7889e1ef7fad 100644 +--- a/net/ieee802154/socket.c ++++ b/net/ieee802154/socket.c +@@ -200,8 +200,9 @@ static int raw_bind(struct sock *sk, struct sockaddr *_uaddr, int len) + int err = 0; + struct net_device *dev = NULL; + +- if (len < sizeof(*uaddr)) +- return -EINVAL; ++ err = ieee802154_sockaddr_check_size(uaddr, len); ++ if (err < 0) ++ return err; + + uaddr = (struct sockaddr_ieee802154 *)_uaddr; + if (uaddr->family != AF_IEEE802154) +@@ -493,7 +494,8 @@ static int dgram_bind(struct sock *sk, struct sockaddr *uaddr, int len) + + ro->bound = 0; + +- if (len < sizeof(*addr)) ++ err = ieee802154_sockaddr_check_size(addr, len); ++ if (err < 0) + goto out; + + if (addr->family != AF_IEEE802154) +@@ -564,8 +566,9 @@ static int dgram_connect(struct sock *sk, struct sockaddr *uaddr, + struct dgram_sock *ro = dgram_sk(sk); + int err = 0; + +- if (len < sizeof(*addr)) +- return -EINVAL; ++ err = ieee802154_sockaddr_check_size(addr, len); ++ if (err < 0) ++ return err; + + if (addr->family != AF_IEEE802154) + return -EINVAL; +@@ -604,6 +607,7 @@ static int dgram_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) + struct ieee802154_mac_cb *cb; + struct dgram_sock *ro = dgram_sk(sk); + struct ieee802154_addr dst_addr; ++ DECLARE_SOCKADDR(struct sockaddr_ieee802154*, daddr, msg->msg_name); + int hlen, tlen; + int err; + +@@ -612,10 +616,20 @@ static int dgram_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) + return -EOPNOTSUPP; + } + +- if (!ro->connected && !msg->msg_name) +- return -EDESTADDRREQ; +- else if (ro->connected && msg->msg_name) +- return -EISCONN; ++ if (msg->msg_name) { ++ if (ro->connected) ++ return -EISCONN; ++ if (msg->msg_namelen < IEEE802154_MIN_NAMELEN) ++ return -EINVAL; ++ err = ieee802154_sockaddr_check_size(daddr, msg->msg_namelen); ++ if (err < 0) ++ return err; ++ ieee802154_addr_from_sa(&dst_addr, &daddr->addr); ++ } else { ++ if (!ro->connected) ++ return -EDESTADDRREQ; ++ dst_addr = ro->dst_addr; ++ } + + if (!ro->bound) + dev = dev_getfirstbyhwtype(sock_net(sk), ARPHRD_IEEE802154); +@@ -651,16 +665,6 @@ static int dgram_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) + cb = mac_cb_init(skb); + cb->type = IEEE802154_FC_TYPE_DATA; + cb->ackreq = ro->want_ack; +- +- if (msg->msg_name) { +- DECLARE_SOCKADDR(struct sockaddr_ieee802154*, +- daddr, msg->msg_name); +- +- ieee802154_addr_from_sa(&dst_addr, &daddr->addr); +- } else { +- dst_addr = ro->dst_addr; +- } +- + cb->secen = ro->secen; + cb->secen_override = ro->secen_override; + cb->seclevel = ro->seclevel; +-- +2.35.3 + diff --git a/patches.suse/net-ieee802154-return-EINVAL-for-unknown-addr-type.patch b/patches.suse/net-ieee802154-return-EINVAL-for-unknown-addr-type.patch new file mode 100644 index 0000000..490b551 --- /dev/null +++ b/patches.suse/net-ieee802154-return-EINVAL-for-unknown-addr-type.patch @@ -0,0 +1,59 @@ +From 30393181fdbc1608cc683b4ee99dcce05ffcc8c7 Mon Sep 17 00:00:00 2001 +From: Alexander Aring +Date: Wed, 5 Oct 2022 22:02:37 -0400 +Subject: [PATCH] net: ieee802154: return -EINVAL for unknown addr type +Git-commit: 30393181fdbc1608cc683b4ee99dcce05ffcc8c7 +Patch-mainline: v6.1-rc1 +References: git-fixes + +This patch adds handling to return -EINVAL for an unknown addr type. The +current behaviour is to return 0 as successful but the size of an +unknown addr type is not defined and should return an error like -EINVAL. + +Fixes: 94160108a70c ("net/ieee802154: fix uninit value bug in dgram_sendmsg") +Signed-off-by: Alexander Aring +Signed-off-by: David S. Miller +Acked-by: Takashi Iwai + +--- + include/net/ieee802154_netdev.h | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h +index a8994f307fc3..03b64bf876a4 100644 +--- a/include/net/ieee802154_netdev.h ++++ b/include/net/ieee802154_netdev.h +@@ -185,21 +185,27 @@ static inline int + ieee802154_sockaddr_check_size(struct sockaddr_ieee802154 *daddr, int len) + { + struct ieee802154_addr_sa *sa; ++ int ret = 0; + + sa = &daddr->addr; + if (len < IEEE802154_MIN_NAMELEN) + return -EINVAL; + switch (sa->addr_type) { ++ case IEEE802154_ADDR_NONE: ++ break; + case IEEE802154_ADDR_SHORT: + if (len < IEEE802154_NAMELEN_SHORT) +- return -EINVAL; ++ ret = -EINVAL; + break; + case IEEE802154_ADDR_LONG: + if (len < IEEE802154_NAMELEN_LONG) +- return -EINVAL; ++ ret = -EINVAL; ++ break; ++ default: ++ ret = -EINVAL; + break; + } +- return 0; ++ return ret; + } + + static inline void ieee802154_addr_from_sa(struct ieee802154_addr *a, +-- +2.35.3 + diff --git a/patches.suse/net-ipa-kill-ipa_cmd_pipeline_clear.patch b/patches.suse/net-ipa-kill-ipa_cmd_pipeline_clear.patch new file mode 100644 index 0000000..7fee90a --- /dev/null +++ b/patches.suse/net-ipa-kill-ipa_cmd_pipeline_clear.patch @@ -0,0 +1,109 @@ +From 57a6a37fcdb808368e311a0096737f458dae8434 Mon Sep 17 00:00:00 2001 +From: Alex Elder +Date: Mon, 22 Nov 2021 19:16:40 -0600 +Subject: [PATCH 01/19] net: ipa: kill ipa_cmd_pipeline_clear() +Git-commit: e4e9bfb7c93d7e78aa4ad7e1c411a8df15386062 +Patch-mainline: v5.16-rc3 +References: git-fixes + +Calling ipa_cmd_pipeline_clear() after stopping the channel +underlying the AP<-modem RX endpoint can lead to a deadlock. + +This occurs in the ->runtime_suspend device power operation for the +IPA driver. While this callback is in progress, any other requests +for power will block until the callback returns. + +Stopping the AP<-modem RX channel does not prevent the modem from +sending another packet to this endpoint. If a packet arrives for an +RX channel when the channel is stopped, an SUSPEND IPA interrupt +condition will be pending. Handling an IPA interrupt requires +power, so ipa_isr_thread() calls pm_runtime_get_sync() first thing. + +The problem occurs because a "pipeline clear" command will not +complete while such a SUSPEND interrupt condition exists. So the +SUSPEND IPA interrupt handler won't proceed until it gets power; +that won't happen until the ->runtime_suspend callback (and its +"pipeline clear" command) completes; and that can't happen while +the SUSPEND interrupt condition exists. + +It turns out that in this case there is no need to use the "pipeline +clear" command. There are scenarios in which clearing the pipeline +is required while suspending, but those are not (yet) supported +upstream. So a simple fix, avoiding the potential deadlock, is to +stop calling ipa_cmd_pipeline_clear() in ipa_endpoint_suspend(). +This removes the only user of ipa_cmd_pipeline_clear(), so get rid +of that function. It can be restored again whenever it's needed. + +This is basically a manual revert along with an explanation for +commit 6cb63ea6a39ea ("net: ipa: introduce ipa_cmd_tag_process()"). + +Fixes: 6cb63ea6a39ea ("net: ipa: introduce ipa_cmd_tag_process()") +Signed-off-by: Alex Elder +Signed-off-by: David S. Miller +Signed-off-by: Denis Kirjanov +--- + drivers/net/ipa/ipa_cmd.c | 16 ---------------- + drivers/net/ipa/ipa_cmd.h | 6 ------ + drivers/net/ipa/ipa_endpoint.c | 2 -- + 3 files changed, 24 deletions(-) + +diff --git a/drivers/net/ipa/ipa_cmd.c b/drivers/net/ipa/ipa_cmd.c +index bda8677eae88..1d4d4c247897 100644 +--- a/drivers/net/ipa/ipa_cmd.c ++++ b/drivers/net/ipa/ipa_cmd.c +@@ -664,22 +664,6 @@ void ipa_cmd_pipeline_clear_wait(struct ipa *ipa) + wait_for_completion(&ipa->completion); + } + +-void ipa_cmd_pipeline_clear(struct ipa *ipa) +-{ +- u32 count = ipa_cmd_pipeline_clear_count(); +- struct gsi_trans *trans; +- +- trans = ipa_cmd_trans_alloc(ipa, count); +- if (trans) { +- ipa_cmd_pipeline_clear_add(trans); +- gsi_trans_commit_wait(trans); +- ipa_cmd_pipeline_clear_wait(ipa); +- } else { +- dev_err(&ipa->pdev->dev, +- "error allocating %u entry tag transaction\n", count); +- } +-} +- + static struct ipa_cmd_info * + ipa_cmd_info_alloc(struct ipa_endpoint *endpoint, u32 tre_count) + { +diff --git a/drivers/net/ipa/ipa_cmd.h b/drivers/net/ipa/ipa_cmd.h +index ea723419c826..cbea68d94c51 100644 +--- a/drivers/net/ipa/ipa_cmd.h ++++ b/drivers/net/ipa/ipa_cmd.h +@@ -174,12 +174,6 @@ u32 ipa_cmd_pipeline_clear_count(void); + */ + void ipa_cmd_pipeline_clear_wait(struct ipa *ipa); + +-/** +- * ipa_cmd_pipeline_clear() - Clear the hardware pipeline +- * @ipa: - IPA pointer +- */ +-void ipa_cmd_pipeline_clear(struct ipa *ipa); +- + /** + * ipa_cmd_trans_alloc() - Allocate a transaction for the command TX endpoint + * @ipa: IPA pointer +diff --git a/drivers/net/ipa/ipa_endpoint.c b/drivers/net/ipa/ipa_endpoint.c +index 7b8d0f560534..5182907c9c18 100644 +--- a/drivers/net/ipa/ipa_endpoint.c ++++ b/drivers/net/ipa/ipa_endpoint.c +@@ -1653,8 +1653,6 @@ void ipa_endpoint_suspend(struct ipa *ipa) + if (ipa->modem_netdev) + ipa_modem_suspend(ipa->modem_netdev); + +- ipa_cmd_pipeline_clear(ipa); +- + ipa_endpoint_suspend_one(ipa->name_map[IPA_ENDPOINT_AP_LAN_RX]); + ipa_endpoint_suspend_one(ipa->name_map[IPA_ENDPOINT_AP_COMMAND_TX]); + } +-- +2.16.4 + diff --git a/patches.suse/net-ipv4-fix-route-with-nexthop-object-delete-warnin.patch b/patches.suse/net-ipv4-fix-route-with-nexthop-object-delete-warnin.patch new file mode 100644 index 0000000..c39eb47 --- /dev/null +++ b/patches.suse/net-ipv4-fix-route-with-nexthop-object-delete-warnin.patch @@ -0,0 +1,115 @@ +From 6bf92d70e690b7ff12b24f4bfff5e5434d019b82 Mon Sep 17 00:00:00 2001 +From: Nikolay Aleksandrov +Date: Fri, 1 Apr 2022 10:33:42 +0300 +Subject: [PATCH] net: ipv4: fix route with nexthop object delete warning +Git-commit: 6bf92d70e690b7ff12b24f4bfff5e5434d019b82 +Patch-mainline: v5.18-rc2 +References: bsc#1204171 CVE-2022-3435 + +FRR folks have hit a kernel warning[1] while deleting routes[2] which is +caused by trying to delete a route pointing to a nexthop id without +specifying nhid but matching on an interface. That is, a route is found +but we hit a warning while matching it. The warning is from +fib_info_nh() in include/net/nexthop.h because we run it on a fib_info +with nexthop object. The call chain is: + inet_rtm_delroute -> fib_table_delete -> fib_nh_match (called with a +nexthop fib_info and also with fc_oif set thus calling fib_info_nh on +the fib_info and triggering the warning). The fix is to not do any +matching in that branch if the fi has a nexthop object because those are +managed separately. I.e. we should match when deleting without nh spec and +should fail when deleting a nexthop route with old-style nh spec because +nexthop objects are managed separately, e.g.: + $ ip r show 1.2.3.4/32 + 1.2.3.4 nhid 12 via 192.168.11.2 dev dummy0 + + $ ip r del 1.2.3.4/32 + $ ip r del 1.2.3.4/32 nhid 12 + + + $ ip r del 1.2.3.4/32 dev dummy0 + + +[1] + [ 523.462226] ------------[ cut here ]------------ + [ 523.462230] WARNING: CPU: 14 PID: 22893 at include/net/nexthop.h:468 fib_nh_match+0x210/0x460 + [ 523.462236] Modules linked in: dummy rpcsec_gss_krb5 xt_socket nf_socket_ipv4 nf_socket_ipv6 ip6table_raw iptable_raw bpf_preload xt_statistic ip_set ip_vs_sh ip_vs_wrr ip_vs_rr ip_vs xt_mark nf_tables xt_nat veth nf_conntrack_netlink nfnetlink xt_addrtype br_netfilter overlay dm_crypt nfsv3 nfs fscache netfs vhost_net vhost vhost_iotlb tap tun xt_CHECKSUM xt_MASQUERADE xt_conntrack 8021q garp mrp ipt_REJECT nf_reject_ipv4 ip6table_mangle ip6table_nat iptable_mangle iptable_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 iptable_filter bridge stp llc rfcomm snd_seq_dummy snd_hrtimer rpcrdma rdma_cm iw_cm ib_cm ib_core ip6table_filter xt_comment ip6_tables vboxnetadp(OE) vboxnetflt(OE) vboxdrv(OE) qrtr bnep binfmt_misc xfs vfat fat squashfs loop nvidia_drm(POE) nvidia_modeset(POE) nvidia_uvm(POE) nvidia(POE) intel_rapl_msr intel_rapl_common snd_hda_codec_realtek snd_hda_codec_generic ledtrig_audio snd_hda_codec_hdmi btusb btrtl iwlmvm uvcvideo btbcm snd_hda_intel edac_mce_amd + [ 523.462274] videobuf2_vmalloc videobuf2_memops btintel snd_intel_dspcfg videobuf2_v4l2 snd_intel_sdw_acpi bluetooth snd_usb_audio snd_hda_codec mac80211 snd_usbmidi_lib joydev snd_hda_core videobuf2_common kvm_amd snd_rawmidi snd_hwdep snd_seq videodev ccp snd_seq_device libarc4 ecdh_generic mc snd_pcm kvm iwlwifi snd_timer drm_kms_helper snd cfg80211 cec soundcore irqbypass rapl wmi_bmof i2c_piix4 rfkill k10temp pcspkr acpi_cpufreq nfsd auth_rpcgss nfs_acl lockd grace sunrpc drm zram ip_tables crct10dif_pclmul crc32_pclmul crc32c_intel ghash_clmulni_intel nvme sp5100_tco r8169 nvme_core wmi ipmi_devintf ipmi_msghandler fuse + [ 523.462300] CPU: 14 PID: 22893 Comm: ip Tainted: P OE 5.16.18-200.fc35.x86_64 #1 + [ 523.462302] Hardware name: Micro-Star International Co., Ltd. MS-7C37/MPG X570 GAMING EDGE WIFI (MS-7C37), BIOS 1.C0 10/29/2020 + [ 523.462303] RIP: 0010:fib_nh_match+0x210/0x460 + [ 523.462304] Code: 7c 24 20 48 8b b5 90 00 00 00 e8 bb ee f4 ff 48 8b 7c 24 20 41 89 c4 e8 ee eb f4 ff 45 85 e4 0f 85 2e fe ff ff e9 4c ff ff ff <0f> 0b e9 17 ff ff ff 3c 0a 0f 85 61 fe ff ff 48 8b b5 98 00 00 00 + [ 523.462306] RSP: 0018:ffffaa53d4d87928 EFLAGS: 00010286 + [ 523.462307] RAX: 0000000000000000 RBX: ffffaa53d4d87a90 RCX: ffffaa53d4d87bb0 + [ 523.462308] RDX: ffff9e3d2ee6be80 RSI: ffffaa53d4d87a90 RDI: ffffffff920ed380 + [ 523.462309] RBP: ffff9e3d2ee6be80 R08: 0000000000000064 R09: 0000000000000000 + [ 523.462310] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000031 + [ 523.462310] R13: 0000000000000020 R14: 0000000000000000 R15: ffff9e3d331054e0 + [ 523.462311] FS: 00007f245517c1c0(0000) GS:ffff9e492ed80000(0000) knlGS:0000000000000000 + [ 523.462313] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + [ 523.462313] CR2: 000055e5dfdd8268 CR3: 00000003ef488000 CR4: 0000000000350ee0 + [ 523.462315] Call Trace: + [ 523.462316] + [ 523.462320] fib_table_delete+0x1a9/0x310 + [ 523.462323] inet_rtm_delroute+0x93/0x110 + [ 523.462325] rtnetlink_rcv_msg+0x133/0x370 + [ 523.462327] ? _copy_to_iter+0xb5/0x6f0 + [ 523.462330] ? rtnl_calcit.isra.0+0x110/0x110 + [ 523.462331] netlink_rcv_skb+0x50/0xf0 + [ 523.462334] netlink_unicast+0x211/0x330 + [ 523.462336] netlink_sendmsg+0x23f/0x480 + [ 523.462338] sock_sendmsg+0x5e/0x60 + [ 523.462340] ____sys_sendmsg+0x22c/0x270 + [ 523.462341] ? import_iovec+0x17/0x20 + [ 523.462343] ? sendmsg_copy_msghdr+0x59/0x90 + [ 523.462344] ? __mod_lruvec_page_state+0x85/0x110 + [ 523.462348] ___sys_sendmsg+0x81/0xc0 + [ 523.462350] ? netlink_seq_start+0x70/0x70 + [ 523.462352] ? __dentry_kill+0x13a/0x180 + [ 523.462354] ? __fput+0xff/0x250 + [ 523.462356] __sys_sendmsg+0x49/0x80 + [ 523.462358] do_syscall_64+0x3b/0x90 + [ 523.462361] entry_SYSCALL_64_after_hwframe+0x44/0xae + [ 523.462364] RIP: 0033:0x7f24552aa337 + [ 523.462365] Code: 0e 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b9 0f 1f 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 b8 2e 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 51 c3 48 83 ec 28 89 54 24 1c 48 89 74 24 10 + [ 523.462366] RSP: 002b:00007fff7f05a838 EFLAGS: 00000246 ORIG_RAX: 000000000000002e + [ 523.462368] RAX: ffffffffffffffda RBX: 000000006245bf91 RCX: 00007f24552aa337 + [ 523.462368] RDX: 0000000000000000 RSI: 00007fff7f05a8a0 RDI: 0000000000000003 + [ 523.462369] RBP: 0000000000000000 R08: 0000000000000001 R09: 0000000000000000 + [ 523.462370] R10: 0000000000000008 R11: 0000000000000246 R12: 0000000000000001 + [ 523.462370] R13: 00007fff7f05ce08 R14: 0000000000000000 R15: 000055e5dfdd1040 + [ 523.462373] + [ 523.462374] ---[ end trace ba537bc16f6bf4ed ]--- + +[2] https://github.com/FRRouting/frr/issues/6412 + +Fixes: 4c7e8084fd46 ("ipv4: Plumb support for nexthop object in a fib_info") +Signed-off-by: Nikolay Aleksandrov +Reviewed-by: David Ahern +Signed-off-by: David S. Miller +Signed-off-by: Denis Kirjanov +--- + net/ipv4/fib_semantics.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c +index cc8e84ef2ae4..ccb62038f6a4 100644 +--- a/net/ipv4/fib_semantics.c ++++ b/net/ipv4/fib_semantics.c +@@ -889,8 +889,13 @@ int fib_nh_match(struct net *net, struct fib_config *cfg, struct fib_info *fi, + } + + if (cfg->fc_oif || cfg->fc_gw_family) { +- struct fib_nh *nh = fib_info_nh(fi, 0); ++ struct fib_nh *nh; ++ ++ /* cannot match on nexthop object attributes */ ++ if (fi->nh) ++ return 1; + ++ nh = fib_info_nh(fi, 0); + if (cfg->fc_encap) { + if (fib_encap_match(net, cfg->fc_encap_type, + cfg->fc_encap, nh, cfg, extack)) +-- +2.16.4 + diff --git a/patches.suse/net-macb-Fix-PTP-one-step-sync-support.patch b/patches.suse/net-macb-Fix-PTP-one-step-sync-support.patch new file mode 100644 index 0000000..44e01e9 --- /dev/null +++ b/patches.suse/net-macb-Fix-PTP-one-step-sync-support.patch @@ -0,0 +1,143 @@ +From 07f5bb5c2476978d1142e37fcb9b2945e1406483 Mon Sep 17 00:00:00 2001 +From: Harini Katakam +Date: Wed, 18 May 2022 22:37:56 +0530 +Subject: [PATCH 13/19] net: macb: Fix PTP one step sync support +Git-commit: 5cebb40bc9554aafcc492431181f43c6231b0459 +Patch-mainline: v5.19-rc1 +References: git-fixes + +PTP one step sync packets cannot have CSUM padding and insertion in +SW since time stamp is inserted on the fly by HW. +In addition, ptp4l version 3.0 and above report an error when skb +timestamps are reported for packets that not processed for TX TS +after transmission. +Add a helper to identify PTP one step sync and fix the above two +errors. Add a common mask for PTP header flag field "twoStepflag". +Also reset ptp OSS bit when one step is not selected. + +Fixes: ab91f0a9b5f4 ("net: macb: Add hardware PTP support") +Fixes: 653e92a9175e ("net: macb: add support for padding and fcs computation") +Signed-off-by: Harini Katakam +Reviewed-by: Radhey Shyam Pandey +Reviewed-by: Claudiu Beznea +Link: https://lore.kernel.org/r/20220518170756.7752-1-harini.katakam@xilinx.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/cadence/macb_main.c | 40 ++++++++++++++++++++++++++++---- + drivers/net/ethernet/cadence/macb_ptp.c | 4 +++- + include/linux/ptp_classify.h | 3 +++ + 3 files changed, 42 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c +index 89c253739822..606770d4bd33 100644 +--- a/drivers/net/ethernet/cadence/macb_main.c ++++ b/drivers/net/ethernet/cadence/macb_main.c +@@ -35,6 +35,7 @@ + #include + #include + #include ++#include + #include "macb.h" + + /* This structure is only used for MACB on SiFive FU540 devices */ +@@ -1155,6 +1156,36 @@ static void macb_tx_error_task(struct work_struct *work) + spin_unlock_irqrestore(&bp->lock, flags); + } + ++static bool ptp_one_step_sync(struct sk_buff *skb) ++{ ++ struct ptp_header *hdr; ++ unsigned int ptp_class; ++ u8 msgtype; ++ ++ /* No need to parse packet if PTP TS is not involved */ ++ if (likely(!(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))) ++ goto not_oss; ++ ++ /* Identify and return whether PTP one step sync is being processed */ ++ ptp_class = ptp_classify_raw(skb); ++ if (ptp_class == PTP_CLASS_NONE) ++ goto not_oss; ++ ++ hdr = ptp_parse_header(skb, ptp_class); ++ if (!hdr) ++ goto not_oss; ++ ++ if (hdr->flag_field[0] & PTP_FLAG_TWOSTEP) ++ goto not_oss; ++ ++ msgtype = ptp_get_msgtype(hdr, ptp_class); ++ if (msgtype == PTP_MSGTYPE_SYNC) ++ return true; ++ ++not_oss: ++ return false; ++} ++ + static void macb_tx_interrupt(struct macb_queue *queue) + { + unsigned int tail; +@@ -1199,8 +1230,8 @@ static void macb_tx_interrupt(struct macb_queue *queue) + + /* First, update TX stats if needed */ + if (skb) { +- if (unlikely(skb_shinfo(skb)->tx_flags & +- SKBTX_HW_TSTAMP) && ++ if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) && ++ !ptp_one_step_sync(skb) && + gem_ptp_do_txstamp(queue, skb, desc) == 0) { + /* skb now belongs to timestamp buffer + * and will be removed later +@@ -2022,7 +2053,8 @@ static unsigned int macb_tx_map(struct macb *bp, + ctrl |= MACB_BF(TX_LSO, lso_ctrl); + ctrl |= MACB_BF(TX_TCP_SEQ_SRC, seq_ctrl); + if ((bp->dev->features & NETIF_F_HW_CSUM) && +- skb->ip_summed != CHECKSUM_PARTIAL && !lso_ctrl) ++ skb->ip_summed != CHECKSUM_PARTIAL && !lso_ctrl && ++ !ptp_one_step_sync(skb)) + ctrl |= MACB_BIT(TX_NOCRC); + } else + /* Only set MSS/MFS on payload descriptors +@@ -2120,7 +2152,7 @@ static int macb_pad_and_fcs(struct sk_buff **skb, struct net_device *ndev) + + if (!(ndev->features & NETIF_F_HW_CSUM) || + !((*skb)->ip_summed != CHECKSUM_PARTIAL) || +- skb_shinfo(*skb)->gso_size) /* Not available for GSO */ ++ skb_shinfo(*skb)->gso_size || ptp_one_step_sync(*skb)) + return 0; + + if (padlen <= 0) { +diff --git a/drivers/net/ethernet/cadence/macb_ptp.c b/drivers/net/ethernet/cadence/macb_ptp.c +index c2e1f163bb14..c52ec1cc8a08 100644 +--- a/drivers/net/ethernet/cadence/macb_ptp.c ++++ b/drivers/net/ethernet/cadence/macb_ptp.c +@@ -469,8 +469,10 @@ int gem_set_hwtst(struct net_device *dev, struct ifreq *ifr, int cmd) + case HWTSTAMP_TX_ONESTEP_SYNC: + if (gem_ptp_set_one_step_sync(bp, 1) != 0) + return -ERANGE; +- fallthrough; ++ tx_bd_control = TSTAMP_ALL_FRAMES; ++ break; + case HWTSTAMP_TX_ON: ++ gem_ptp_set_one_step_sync(bp, 0); + tx_bd_control = TSTAMP_ALL_FRAMES; + break; + default: +diff --git a/include/linux/ptp_classify.h b/include/linux/ptp_classify.h +index 9afd34a2d36c..b760373524fe 100644 +--- a/include/linux/ptp_classify.h ++++ b/include/linux/ptp_classify.h +@@ -43,6 +43,9 @@ + #define OFF_PTP_SOURCE_UUID 22 /* PTPv1 only */ + #define OFF_PTP_SEQUENCE_ID 30 + ++/* PTP header flag fields */ ++#define PTP_FLAG_TWOSTEP BIT(1) ++ + /* Below defines should actually be removed at some point in time. */ + #define IP6_HLEN 40 + #define UDP_HLEN 8 +-- +2.16.4 + diff --git a/patches.suse/net-make-drivers-set-the-TSO-limit-not-the-GSO-limit.patch b/patches.suse/net-make-drivers-set-the-TSO-limit-not-the-GSO-limit.patch index 674abca..051fec3 100644 --- a/patches.suse/net-make-drivers-set-the-TSO-limit-not-the-GSO-limit.patch +++ b/patches.suse/net-make-drivers-set-the-TSO-limit-not-the-GSO-limit.patch @@ -391,7 +391,7 @@ Acked-by: Thomas Bogendoerfer + netif_set_tso_max_size(card->dev, PAGE_SIZE * (QETH_MAX_BUFFER_ELEMENTS(card) - 1)); - netif_napi_add(card->dev, &card->napi, qeth_poll, QETH_NAPI_WEIGHT); + netif_napi_add(card->dev, &card->napi, qeth_poll, NAPI_POLL_WEIGHT); --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -519,16 +519,16 @@ void br_mtu_auto_adjust(struct net_bridg diff --git a/patches.suse/net-pcs-xpcs-propagate-xpcs_read-error-to-xpcs_get_s.patch b/patches.suse/net-pcs-xpcs-propagate-xpcs_read-error-to-xpcs_get_s.patch new file mode 100644 index 0000000..439ef47 --- /dev/null +++ b/patches.suse/net-pcs-xpcs-propagate-xpcs_read-error-to-xpcs_get_s.patch @@ -0,0 +1,42 @@ +From a50ce2907a81e979329340bfc52d8332ffd58cef Mon Sep 17 00:00:00 2001 +From: Vladimir Oltean +Date: Wed, 20 Jul 2022 14:20:57 +0300 +Subject: [PATCH 26/28] net: pcs: xpcs: propagate xpcs_read error to + xpcs_get_state_c37_sgmii +Git-commit: 27161db0904ee48e59140aa8d0835939a666c1f1 +Patch-mainline: v5.19 +References: git-fixes + +While phylink_pcs_ops :: pcs_get_state does return void, xpcs_get_state() +does check for a non-zero return code from xpcs_get_state_c37_sgmii() +and prints that as a message to the kernel log. + +However, a non-zero return code from xpcs_read() is translated into +"return false" (i.e. zero as int) and the I/O error is therefore not +printed. Fix that. + +Fixes: b97b5331b8ab ("net: pcs: add C37 SGMII AN support for intel mGbE controller") +Signed-off-by: Vladimir Oltean +Link: https://lore.kernel.org/r/20220720112057.3504398-1-vladimir.oltean@nxp.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Denis Kirjanov +--- + drivers/net/pcs/pcs-xpcs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c +index d4ab03a92fb5..b6ac2baa8d43 100644 +--- a/drivers/net/pcs/pcs-xpcs.c ++++ b/drivers/net/pcs/pcs-xpcs.c +@@ -886,7 +886,7 @@ static int xpcs_get_state_c37_sgmii(struct dw_xpcs *xpcs, + */ + ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_INTR_STS); + if (ret < 0) +- return false; ++ return ret; + + if (ret & DW_VR_MII_C37_ANSGM_SP_LNKSTS) { + int speed_value; +-- +2.16.4 + diff --git a/patches.suse/net-phy-Don-t-WARN-for-PHY_UP-state-in-mdio_bus_phy_.patch b/patches.suse/net-phy-Don-t-WARN-for-PHY_UP-state-in-mdio_bus_phy_.patch new file mode 100644 index 0000000..cffd3e9 --- /dev/null +++ b/patches.suse/net-phy-Don-t-WARN-for-PHY_UP-state-in-mdio_bus_phy_.patch @@ -0,0 +1,63 @@ +From ea64cdfad124922c931633e39287c5a31a9b14a1 Mon Sep 17 00:00:00 2001 +From: Lukas Wunner +Date: Fri, 23 Sep 2022 06:09:52 +0200 +Subject: [PATCH] net: phy: Don't WARN for PHY_UP state in mdio_bus_phy_resume() +Git-commit: ea64cdfad124922c931633e39287c5a31a9b14a1 +Patch-mainline: v6.0 +References: git-fixes + +Commit 744d23c71af3 ("net: phy: Warn about incorrect mdio_bus_phy_resume() +state") introduced a WARN() on resume from system sleep if a PHY is not +in PHY_HALTED state. + +Commit 6dbe852c379f ("net: phy: Don't WARN for PHY_READY state in +mdio_bus_phy_resume()") added an exemption for PHY_READY state from +the WARN(). + +It turns out PHY_UP state needs to be exempted as well because the +following may happen on suspend: + + mdio_bus_phy_suspend() + phy_stop_machine() + phydev->state = PHY_UP # if (phydev->state >= PHY_UP) + +Fixes: 744d23c71af3 ("net: phy: Warn about incorrect mdio_bus_phy_resume() state") +Reported-by: Marek Szyprowski +Tested-by: Marek Szyprowski +Link: https://lore.kernel.org/netdev/2b1a1588-505e-dff3-301d-bfc1fb14d685@samsung.com/ +Signed-off-by: Lukas Wunner +Acked-by: Florian Fainelli +Cc: Xiaolei Wang +Link: https://lore.kernel.org/r/8128fdb51eeebc9efbf3776a4097363a1317aaf1.1663905575.git.lukas@wunner.de +Signed-off-by: Paolo Abeni +Acked-by: Takashi Iwai + +--- + drivers/net/phy/phy_device.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c +index 12ff276b80ae..4df8c337221b 100644 +--- a/drivers/net/phy/phy_device.c ++++ b/drivers/net/phy/phy_device.c +@@ -316,11 +316,13 @@ static __maybe_unused int mdio_bus_phy_resume(struct device *dev) + + phydev->suspended_by_mdio_bus = 0; + +- /* If we manged to get here with the PHY state machine in a state neither +- * PHY_HALTED nor PHY_READY this is an indication that something went wrong +- * and we should most likely be using MAC managed PM and we are not. ++ /* If we managed to get here with the PHY state machine in a state ++ * neither PHY_HALTED, PHY_READY nor PHY_UP, this is an indication ++ * that something went wrong and we should most likely be using ++ * MAC managed PM, but we are not. + */ +- WARN_ON(phydev->state != PHY_HALTED && phydev->state != PHY_READY); ++ WARN_ON(phydev->state != PHY_HALTED && phydev->state != PHY_READY && ++ phydev->state != PHY_UP); + + ret = phy_init_hw(phydev); + if (ret < 0) +-- +2.35.3 + diff --git a/patches.suse/net-phy-aquantia-wait-for-the-suspend-resume-operati.patch b/patches.suse/net-phy-aquantia-wait-for-the-suspend-resume-operati.patch new file mode 100644 index 0000000..019d1a2 --- /dev/null +++ b/patches.suse/net-phy-aquantia-wait-for-the-suspend-resume-operati.patch @@ -0,0 +1,122 @@ +From ca2dccdeeb49a7e408112d681bf447984c845292 Mon Sep 17 00:00:00 2001 +From: Ioana Ciornei +Date: Tue, 6 Sep 2022 16:04:51 +0300 +Subject: [PATCH] net: phy: aquantia: wait for the suspend/resume operations to finish +Git-commit: ca2dccdeeb49a7e408112d681bf447984c845292 +Patch-mainline: v6.0-rc7 +References: git-fixes + +The Aquantia datasheet notes that after issuing a Processor-Intensive +MDIO operation, like changing the low-power state of the device, the +driver should wait for the operation to finish before issuing a new MDIO +command. + +The new aqr107_wait_processor_intensive_op() function is added which can +be used after these kind of MDIO operations. At the moment, we are only +adding it at the end of the suspend/resume calls. + +The issue was identified on a board featuring the AQR113C PHY, on +which commands like 'ip link (..) up / down' issued without any delays +between them would render the link on the PHY to remain down. +The issue was easy to reproduce with a one-liner: + $ ip link set dev ethX down; ip link set dev ethX up; \ + ip link set dev ethX down; ip link set dev ethX up; + +Fixes: ac9e81c230eb ("net: phy: aquantia: add suspend / resume callbacks for AQR107 family") +Signed-off-by: Ioana Ciornei +Reviewed-by: Andrew Lunn +Link: https://lore.kernel.org/r/20220906130451.1483448-1-ioana.ciornei@nxp.com +Signed-off-by: Paolo Abeni +Acked-by: Takashi Iwai + +--- + drivers/net/phy/aquantia_main.c | 53 ++++++++++++++++++++++++++++++--- + 1 file changed, 49 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/phy/aquantia_main.c b/drivers/net/phy/aquantia_main.c +index 8b7a46db30e0..7111e2e958e9 100644 +--- a/drivers/net/phy/aquantia_main.c ++++ b/drivers/net/phy/aquantia_main.c +@@ -91,6 +91,9 @@ + #define VEND1_GLOBAL_FW_ID_MAJOR GENMASK(15, 8) + #define VEND1_GLOBAL_FW_ID_MINOR GENMASK(7, 0) + ++#define VEND1_GLOBAL_GEN_STAT2 0xc831 ++#define VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG BIT(15) ++ + #define VEND1_GLOBAL_RSVD_STAT1 0xc885 + #define VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID GENMASK(7, 4) + #define VEND1_GLOBAL_RSVD_STAT1_PROV_ID GENMASK(3, 0) +@@ -125,6 +128,12 @@ + #define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL2 BIT(1) + #define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 BIT(0) + ++/* Sleep and timeout for checking if the Processor-Intensive ++ * MDIO operation is finished ++ */ ++#define AQR107_OP_IN_PROG_SLEEP 1000 ++#define AQR107_OP_IN_PROG_TIMEOUT 100000 ++ + struct aqr107_hw_stat { + const char *name; + int reg; +@@ -597,16 +606,52 @@ static void aqr107_link_change_notify(struct phy_device *phydev) + phydev_info(phydev, "Aquantia 1000Base-T2 mode active\n"); + } + ++static int aqr107_wait_processor_intensive_op(struct phy_device *phydev) ++{ ++ int val, err; ++ ++ /* The datasheet notes to wait at least 1ms after issuing a ++ * processor intensive operation before checking. ++ * We cannot use the 'sleep_before_read' parameter of read_poll_timeout ++ * because that just determines the maximum time slept, not the minimum. ++ */ ++ usleep_range(1000, 5000); ++ ++ err = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, ++ VEND1_GLOBAL_GEN_STAT2, val, ++ !(val & VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG), ++ AQR107_OP_IN_PROG_SLEEP, ++ AQR107_OP_IN_PROG_TIMEOUT, false); ++ if (err) { ++ phydev_err(phydev, "timeout: processor-intensive MDIO operation\n"); ++ return err; ++ } ++ ++ return 0; ++} ++ + static int aqr107_suspend(struct phy_device *phydev) + { +- return phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1, +- MDIO_CTRL1_LPOWER); ++ int err; ++ ++ err = phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1, ++ MDIO_CTRL1_LPOWER); ++ if (err) ++ return err; ++ ++ return aqr107_wait_processor_intensive_op(phydev); + } + + static int aqr107_resume(struct phy_device *phydev) + { +- return phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1, +- MDIO_CTRL1_LPOWER); ++ int err; ++ ++ err = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1, ++ MDIO_CTRL1_LPOWER); ++ if (err) ++ return err; ++ ++ return aqr107_wait_processor_intensive_op(phydev); + } + + static int aqr107_probe(struct phy_device *phydev) +-- +2.35.3 + diff --git a/patches.suse/net-phy-at803x-move-page-selection-fix-to-config_ini.patch b/patches.suse/net-phy-at803x-move-page-selection-fix-to-config_ini.patch new file mode 100644 index 0000000..3a0c417 --- /dev/null +++ b/patches.suse/net-phy-at803x-move-page-selection-fix-to-config_ini.patch @@ -0,0 +1,91 @@ +From 9b754c55a823ce4d319f1dda3651ac7c2f5be6ee Mon Sep 17 00:00:00 2001 +From: Robert Hancock +Date: Tue, 25 Jan 2022 10:54:08 -0600 +Subject: [PATCH 03/19] net: phy: at803x: move page selection fix to + config_init +Git-commit: 4f3a00c7f5b2cfe4e127fd3fe49b55e1b318c01f +Patch-mainline: v5.18-rc1 +References: git-fixes + +The fix to select the copper page on AR8031 was being done in the probe +function rather than config_init, so it would not be redone after resume +from suspend. Move this to config_init so it is always redone when +needed. + +Fixes: c329e5afb42f ("net: phy: at803x: select correct page on config init") +Signed-off-by: Robert Hancock +Signed-off-by: David S. Miller +Signed-off-by: Denis Kirjanov +--- + drivers/net/phy/at803x.c | 40 ++++++++++++++++------------------------ + 1 file changed, 16 insertions(+), 24 deletions(-) + +diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c +index 30c70503de5b..270e0658f435 100644 +--- a/drivers/net/phy/at803x.c ++++ b/drivers/net/phy/at803x.c +@@ -672,25 +672,7 @@ static int at803x_probe(struct phy_device *phydev) + return ret; + } + +- /* Some bootloaders leave the fiber page selected. +- * Switch to the copper page, as otherwise we read +- * the PHY capabilities from the fiber side. +- */ +- if (at803x_match_phy_id(phydev, ATH8031_PHY_ID)) { +- phy_lock_mdio_bus(phydev); +- ret = at803x_write_page(phydev, AT803X_PAGE_COPPER); +- phy_unlock_mdio_bus(phydev); +- if (ret) +- goto err; +- } +- + return 0; +- +-err: +- if (priv->vddio) +- regulator_disable(priv->vddio); +- +- return ret; + } + + static void at803x_remove(struct phy_device *phydev) +@@ -791,6 +773,22 @@ static int at803x_config_init(struct phy_device *phydev) + { + int ret; + ++ if (phydev->drv->phy_id == ATH8031_PHY_ID) { ++ /* Some bootloaders leave the fiber page selected. ++ * Switch to the copper page, as otherwise we read ++ * the PHY capabilities from the fiber side. ++ */ ++ phy_lock_mdio_bus(phydev); ++ ret = at803x_write_page(phydev, AT803X_PAGE_COPPER); ++ phy_unlock_mdio_bus(phydev); ++ if (ret) ++ return ret; ++ ++ ret = at8031_pll_config(phydev); ++ if (ret < 0) ++ return ret; ++ } ++ + /* The RX and TX delay default is: + * after HW reset: RX delay enabled and TX delay disabled + * after SW reset: RX delay enabled, while TX delay retains the +@@ -820,12 +818,6 @@ static int at803x_config_init(struct phy_device *phydev) + if (ret < 0) + return ret; + +- if (at803x_match_phy_id(phydev, ATH8031_PHY_ID)) { +- ret = at8031_pll_config(phydev); +- if (ret < 0) +- return ret; +- } +- + /* Ar803x extended next page bit is enabled by default. Cisco + * multigig switches read this bit and attempt to negotiate 10Gbps + * rates even if the next page bit is disabled. This is incorrect +-- +2.16.4 + diff --git a/patches.suse/net-qlcnic-use-time_is_before_jiffies-instead-of-open-coding-it.patch b/patches.suse/net-qlcnic-use-time_is_before_jiffies-instead-of-open-coding-it.patch new file mode 100644 index 0000000..f24e7a6 --- /dev/null +++ b/patches.suse/net-qlcnic-use-time_is_before_jiffies-instead-of-open-coding-it.patch @@ -0,0 +1,39 @@ +From: Wang Qing +Date: Sun, 27 Feb 2022 19:13:00 -0800 +Subject: net: qlcnic: use time_is_before_jiffies() instead of open coding it +Git-commit: 3b6cab7b5a2feed11f3d6ad90e0ad8ea03f87670 +Patch-mainline: v5.18-rc1 +References: jsc#PED-1302 + +Use the helper function time_is_{before,after}_jiffies() to improve +code readability. + +Signed-off-by: Wang Qing +Signed-off-by: David S. Miller +Acked-by: Lee Duncan +--- + drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c +index 29cdcb2285b1..bcf3746220df 100644 +--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c ++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + + #include "qlcnic.h" + +@@ -332,7 +333,7 @@ static void qlcnic_send_filter(struct qlcnic_adapter *adapter, + hlist_for_each_entry_safe(tmp_fil, n, head, fnode) { + if (ether_addr_equal(tmp_fil->faddr, (u8 *)&src_addr) && + tmp_fil->vlan_id == vlan_id) { +- if (jiffies > (QLCNIC_READD_AGE * HZ + tmp_fil->ftime)) ++ if (time_is_before_jiffies(QLCNIC_READD_AGE * HZ + tmp_fil->ftime)) + qlcnic_change_filter(adapter, &src_addr, + vlan_id, tx_ring); + tmp_fil->ftime = jiffies; + diff --git a/patches.suse/net-s390-constify-and-use-eth_hw_addr_set b/patches.suse/net-s390-constify-and-use-eth_hw_addr_set new file mode 100644 index 0000000..07a5699 --- /dev/null +++ b/patches.suse/net-s390-constify-and-use-eth_hw_addr_set @@ -0,0 +1,96 @@ +From: Jakub Kicinski +Date: Thu, 21 Oct 2021 06:12:11 -0700 +Subject: net: s390: constify and use eth_hw_addr_set() +Git-commit: 978bb0ae8b83097b2889f19907d2b519528ef235 +Patch-mainline: v5.16-rc1 +References: jsc#PED-448 LTC#198619 + +Commit 406f42fa0d3c ("net-next: When a bond have a massive amount +of VLANs...") introduced a rbtree for faster Ethernet address look +up. To maintain netdev->dev_addr in this tree we need to make all +the writes to it got through appropriate helpers. + +Make sure local references to netdev->dev_addr are constant. + +Acked-by: Julian Wiedmann +Signed-off-by: Jakub Kicinski +Acked-by: Petr Tesarik +--- + drivers/s390/net/lcs.c | 2 +- + drivers/s390/net/qeth_core_main.c | 4 ++-- + drivers/s390/net/qeth_l2_main.c | 6 +++--- + drivers/s390/net/qeth_l3_main.c | 3 +-- + 4 files changed, 7 insertions(+), 8 deletions(-) + +--- a/drivers/s390/net/lcs.c ++++ b/drivers/s390/net/lcs.c +@@ -2162,7 +2162,7 @@ lcs_new_device(struct ccwgroup_device *c + card->dev->ml_priv = card; + card->dev->netdev_ops = &lcs_netdev_ops; + card->dev->dev_port = card->portno; +- memcpy(card->dev->dev_addr, card->mac, LCS_MAC_LENGTH); ++ eth_hw_addr_set(card->dev, card->mac); + #ifdef CONFIG_IP_MULTICAST + if (!lcs_check_multicast_support(card)) + card->dev->netdev_ops = &lcs_mc_netdev_ops; +--- a/drivers/s390/net/qeth_core_main.c ++++ b/drivers/s390/net/qeth_core_main.c +@@ -4400,7 +4400,7 @@ static int qeth_setadpparms_change_macad + !(adp_cmd->hdr.flags & QETH_SETADP_FLAGS_VIRTUAL_MAC)) + return -EADDRNOTAVAIL; + +- ether_addr_copy(card->dev->dev_addr, adp_cmd->data.change_addr.addr); ++ eth_hw_addr_set(card->dev, adp_cmd->data.change_addr.addr); + return 0; + } + +@@ -5072,7 +5072,7 @@ int qeth_vm_request_mac(struct qeth_card + QETH_CARD_TEXT(card, 2, "badmac"); + QETH_CARD_HEX(card, 2, response->mac, ETH_ALEN); + } else { +- ether_addr_copy(card->dev->dev_addr, response->mac); ++ eth_hw_addr_set(card->dev, response->mac); + } + + out: +--- a/drivers/s390/net/qeth_l2_main.c ++++ b/drivers/s390/net/qeth_l2_main.c +@@ -71,7 +71,7 @@ static int qeth_l2_send_setdelmac_cb(str + return qeth_l2_setdelmac_makerc(card, cmd->hdr.return_code); + } + +-static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac, ++static int qeth_l2_send_setdelmac(struct qeth_card *card, const __u8 *mac, + enum qeth_ipa_cmds ipacmd) + { + struct qeth_ipa_cmd *cmd; +@@ -88,7 +88,7 @@ static int qeth_l2_send_setdelmac(struct + return qeth_send_ipa_cmd(card, iob, qeth_l2_send_setdelmac_cb, NULL); + } + +-static int qeth_l2_send_setmac(struct qeth_card *card, __u8 *mac) ++static int qeth_l2_send_setmac(struct qeth_card *card, const __u8 *mac) + { + int rc; + +@@ -378,7 +378,7 @@ static int qeth_l2_set_mac_address(struc + if (rc) + return rc; + ether_addr_copy(old_addr, dev->dev_addr); +- ether_addr_copy(dev->dev_addr, addr->sa_data); ++ eth_hw_addr_set(dev, addr->sa_data); + + if (card->info.dev_addr_is_registered) + qeth_l2_remove_mac(card, old_addr); +--- a/drivers/s390/net/qeth_l3_main.c ++++ b/drivers/s390/net/qeth_l3_main.c +@@ -913,8 +913,7 @@ static int qeth_l3_iqd_read_initial_mac_ + if (!is_valid_ether_addr(cmd->data.create_destroy_addr.mac_addr)) + return -EADDRNOTAVAIL; + +- ether_addr_copy(card->dev->dev_addr, +- cmd->data.create_destroy_addr.mac_addr); ++ eth_hw_addr_set(card->dev, cmd->data.create_destroy_addr.mac_addr); + return 0; + } + diff --git a/patches.suse/net-stmmac-fix-dma-queue-left-shift-overflow-issue.patch b/patches.suse/net-stmmac-fix-dma-queue-left-shift-overflow-issue.patch new file mode 100644 index 0000000..8b8abda --- /dev/null +++ b/patches.suse/net-stmmac-fix-dma-queue-left-shift-overflow-issue.patch @@ -0,0 +1,81 @@ +From 335ee1367c6e419ed175a7fa1b8141df2c60f7aa Mon Sep 17 00:00:00 2001 +From: Junxiao Chang +Date: Fri, 15 Jul 2022 15:47:01 +0800 +Subject: [PATCH 18/28] net: stmmac: fix dma queue left shift overflow issue +Git-commit: 613b065ca32e90209024ec4a6bb5ca887ee70980 +Patch-mainline: v5.19-rc8 +References: git-fixes + +When queue number is > 4, left shift overflows due to 32 bits +integer variable. Mask calculation is wrong for MTL_RXQ_DMA_MAP1. + +If CONFIG_UBSAN is enabled, kernel dumps below warning: +[ 10.363842] ================================================================== +[ 10.363882] UBSAN: shift-out-of-bounds in /build/linux-intel-iotg-5.15-8e6Tf4/ +linux-intel-iotg-5.15-5.15.0/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c:224:12 +[ 10.363929] shift exponent 40 is too large for 32-bit type 'unsigned int' +[ 10.363953] CPU: 1 PID: 599 Comm: NetworkManager Not tainted 5.15.0-1003-intel-iotg +[ 10.363956] Hardware name: ADLINK Technology Inc. LEC-EL/LEC-EL, BIOS 0.15.11 12/22/2021 +[ 10.363958] Call Trace: +[ 10.363960] +[ 10.363963] dump_stack_lvl+0x4a/0x5f +[ 10.363971] dump_stack+0x10/0x12 +[ 10.363974] ubsan_epilogue+0x9/0x45 +[ 10.363976] __ubsan_handle_shift_out_of_bounds.cold+0x61/0x10e +[ 10.363979] ? wake_up_klogd+0x4a/0x50 +[ 10.363983] ? vprintk_emit+0x8f/0x240 +[ 10.363986] dwmac4_map_mtl_dma.cold+0x42/0x91 [stmmac] +[ 10.364001] stmmac_mtl_configuration+0x1ce/0x7a0 [stmmac] +[ 10.364009] ? dwmac410_dma_init_channel+0x70/0x70 [stmmac] +[ 10.364020] stmmac_hw_setup.cold+0xf/0xb14 [stmmac] +[ 10.364030] ? page_pool_alloc_pages+0x4d/0x70 +[ 10.364034] ? stmmac_clear_tx_descriptors+0x6e/0xe0 [stmmac] +[ 10.364042] stmmac_open+0x39e/0x920 [stmmac] +[ 10.364050] __dev_open+0xf0/0x1a0 +[ 10.364054] __dev_change_flags+0x188/0x1f0 +[ 10.364057] dev_change_flags+0x26/0x60 +[ 10.364059] do_setlink+0x908/0xc40 +[ 10.364062] ? do_setlink+0xb10/0xc40 +[ 10.364064] ? __nla_validate_parse+0x4c/0x1a0 +[ 10.364068] __rtnl_newlink+0x597/0xa10 +[ 10.364072] ? __nla_reserve+0x41/0x50 +[ 10.364074] ? __kmalloc_node_track_caller+0x1d0/0x4d0 +[ 10.364079] ? pskb_expand_head+0x75/0x310 +[ 10.364082] ? nla_reserve_64bit+0x21/0x40 +[ 10.364086] ? skb_free_head+0x65/0x80 +[ 10.364089] ? security_sock_rcv_skb+0x2c/0x50 +[ 10.364094] ? __cond_resched+0x19/0x30 +[ 10.364097] ? kmem_cache_alloc_trace+0x15a/0x420 +[ 10.364100] rtnl_newlink+0x49/0x70 + +This change fixes MTL_RXQ_DMA_MAP1 mask issue and channel/queue +mapping warning. + +Fixes: d43042f4da3e ("net: stmmac: mapping mtl rx to dma channel") +BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=216195 +Reported-by: Cedric Wassenaar +Signed-off-by: Junxiao Chang +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +index b21745368983..412abfabd28b 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +@@ -219,6 +219,9 @@ static void dwmac4_map_mtl_dma(struct mac_device_info *hw, u32 queue, u32 chan) + if (queue == 0 || queue == 4) { + value &= ~MTL_RXQ_DMA_Q04MDMACH_MASK; + value |= MTL_RXQ_DMA_Q04MDMACH(chan); ++ } else if (queue > 4) { ++ value &= ~MTL_RXQ_DMA_QXMDMACH_MASK(queue - 4); ++ value |= MTL_RXQ_DMA_QXMDMACH(chan, queue - 4); + } else { + value &= ~MTL_RXQ_DMA_QXMDMACH_MASK(queue); + value |= MTL_RXQ_DMA_QXMDMACH(chan, queue); +-- +2.16.4 + diff --git a/patches.suse/net-stmmac-fix-leaks-in-probe.patch b/patches.suse/net-stmmac-fix-leaks-in-probe.patch new file mode 100644 index 0000000..a7f7c27 --- /dev/null +++ b/patches.suse/net-stmmac-fix-leaks-in-probe.patch @@ -0,0 +1,45 @@ +From 0c5a0b3dd66f132c408299ce0b5079ab0f473b9b Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Tue, 12 Jul 2022 17:42:25 +0300 +Subject: [PATCH 11/28] net: stmmac: fix leaks in probe +Git-commit: 23aa6d5088e3bd65de77c5c307237b9937f8b48a +Patch-mainline: v5.19-rc7 +References: git-fixes + +These two error paths should clean up before returning. + +Fixes: 2bb4b98b60d7 ("net: stmmac: Add Ingenic SoCs MAC support.") +Signed-off-by: Dan Carpenter +Signed-off-by: David S. Miller +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/stmicro/stmmac/dwmac-ingenic.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-ingenic.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-ingenic.c +index 9a6d819b84ae..378b4dd826bb 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-ingenic.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ingenic.c +@@ -273,7 +273,8 @@ static int ingenic_mac_probe(struct platform_device *pdev) + mac->tx_delay = tx_delay_ps * 1000; + } else { + dev_err(&pdev->dev, "Invalid TX clock delay: %dps\n", tx_delay_ps); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err_remove_config_dt; + } + } + +@@ -283,7 +284,8 @@ static int ingenic_mac_probe(struct platform_device *pdev) + mac->rx_delay = rx_delay_ps * 1000; + } else { + dev_err(&pdev->dev, "Invalid RX clock delay: %dps\n", rx_delay_ps); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err_remove_config_dt; + } + } + +-- +2.16.4 + diff --git a/patches.suse/net-stmmac-fix-out-of-bounds-access-in-a-selftest.patch b/patches.suse/net-stmmac-fix-out-of-bounds-access-in-a-selftest.patch new file mode 100644 index 0000000..b2591d1 --- /dev/null +++ b/patches.suse/net-stmmac-fix-out-of-bounds-access-in-a-selftest.patch @@ -0,0 +1,73 @@ +From 002184fd1a0c6c7c76102db7d813a771cb358b8c Mon Sep 17 00:00:00 2001 +From: Jakub Kicinski +Date: Wed, 18 May 2022 17:43:05 -0700 +Subject: [PATCH 14/19] net: stmmac: fix out-of-bounds access in a selftest +Git-commit: fe5c5fc145edcf98a759b895f52b646730eeb7be +Patch-mainline: v5.19-rc1 +References: git-fixes + +GCC 12 points out that struct tc_action is smaller than +struct tcf_action: + +drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c: In function ‘stmmac_test_rxp’: +drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c:1132:21: warning: array subscript ‘struct tcf_gact[0]’ is partly outside array bounds of ‘unsigned char[272]’ [-Warray-bounds] + 1132 | gact->tcf_action = TC_ACT_SHOT; + | ^~ + +Fixes: ccfc639a94f2 ("net: stmmac: selftests: Add a selftest for Flexible RX Parser") +Link: https://lore.kernel.org/r/20220519004305.2109708-1-kuba@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c | 13 ++++++------- + 1 file changed, 6 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c +index 0462dcc93e53..aa6d09302b5c 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c +@@ -1084,8 +1084,9 @@ static int stmmac_test_rxp(struct stmmac_priv *priv) + unsigned char addr[ETH_ALEN] = {0xde, 0xad, 0xbe, 0xef, 0x00, 0x00}; + struct tc_cls_u32_offload cls_u32 = { }; + struct stmmac_packet_attrs attr = { }; +- struct tc_action **actions, *act; ++ struct tc_action **actions; + struct tc_u32_sel *sel; ++ struct tcf_gact *gact; + struct tcf_exts *exts; + int ret, i, nk = 1; + +@@ -1110,8 +1111,8 @@ static int stmmac_test_rxp(struct stmmac_priv *priv) + goto cleanup_exts; + } + +- act = kzalloc(nk * sizeof(*act), GFP_KERNEL); +- if (!act) { ++ gact = kcalloc(nk, sizeof(*gact), GFP_KERNEL); ++ if (!gact) { + ret = -ENOMEM; + goto cleanup_actions; + } +@@ -1126,9 +1127,7 @@ static int stmmac_test_rxp(struct stmmac_priv *priv) + exts->nr_actions = nk; + exts->actions = actions; + for (i = 0; i < nk; i++) { +- struct tcf_gact *gact = to_gact(&act[i]); +- +- actions[i] = &act[i]; ++ actions[i] = (struct tc_action *)&gact[i]; + gact->tcf_action = TC_ACT_SHOT; + } + +@@ -1152,7 +1151,7 @@ static int stmmac_test_rxp(struct stmmac_priv *priv) + stmmac_tc_setup_cls_u32(priv, priv, &cls_u32); + + cleanup_act: +- kfree(act); ++ kfree(gact); + cleanup_actions: + kfree(actions); + cleanup_exts: +-- +2.16.4 + diff --git a/patches.suse/net-stmmac-fix-pm-runtime-issue-in-stmmac_dvr_remove.patch b/patches.suse/net-stmmac-fix-pm-runtime-issue-in-stmmac_dvr_remove.patch new file mode 100644 index 0000000..f9e2234 --- /dev/null +++ b/patches.suse/net-stmmac-fix-pm-runtime-issue-in-stmmac_dvr_remove.patch @@ -0,0 +1,59 @@ +From 82e46111176fb2d7b63d6a6f21220578d8a3764b Mon Sep 17 00:00:00 2001 +From: Biao Huang +Date: Thu, 14 Jul 2022 14:00:13 +0800 +Subject: [PATCH 15/28] net: stmmac: fix pm runtime issue in + stmmac_dvr_remove() +Git-commit: 0d9a15913b871e03fdd3b3d90a2e665fb22f9bcf +Patch-mainline: v5.19-rc8 +References: git-fixes + +If netif is running when stmmac_dvr_remove is invoked, +the unregister_netdev will call ndo_stop(stmmac_release) and +vlan_kill_rx_filter(stmmac_vlan_rx_kill_vid). + +Currently, stmmac_dvr_remove() will disable pm runtime before +unregister_netdev. When stmmac_vlan_rx_kill_vid is invoked, +pm_runtime_resume_and_get in it returns EACCESS error number, +and reports: + + dwmac-mediatek 11021000.ethernet eth0: stmmac_dvr_remove: removing driver + dwmac-mediatek 11021000.ethernet eth0: FPE workqueue stop + dwmac-mediatek 11021000.ethernet eth0: failed to kill vid 0081/0 + +Move the pm_runtime_disable to the end of stmmac_dvr_remove +to fix this issue. + +Fixes: 6449520391dfc ("net: stmmac: properly handle with runtime pm in stmmac_dvr_remove()") +Signed-off-by: Biao Huang +Signed-off-by: David S. Miller +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index 3e50097c0c26..2f06f46e1b7a 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -7274,8 +7274,6 @@ int stmmac_dvr_remove(struct device *dev) + netdev_info(priv->dev, "%s: removing driver", __func__); + + pm_runtime_get_sync(dev); +- pm_runtime_disable(dev); +- pm_runtime_put_noidle(dev); + + stmmac_stop_all_dma(priv); + stmmac_mac_set(priv, priv->ioaddr, false); +@@ -7302,6 +7300,9 @@ int stmmac_dvr_remove(struct device *dev) + mutex_destroy(&priv->lock); + bitmap_free(priv->af_xdp_zc_qps); + ++ pm_runtime_disable(dev); ++ pm_runtime_put_noidle(dev); ++ + return 0; + } + EXPORT_SYMBOL_GPL(stmmac_dvr_remove); +-- +2.16.4 + diff --git a/patches.suse/net-stmmac-fix-unbalanced-ptp-clock-issue-in-suspend.patch b/patches.suse/net-stmmac-fix-unbalanced-ptp-clock-issue-in-suspend.patch new file mode 100644 index 0000000..ce6b545 --- /dev/null +++ b/patches.suse/net-stmmac-fix-unbalanced-ptp-clock-issue-in-suspend.patch @@ -0,0 +1,92 @@ +From 99b58f4f8ac3b3219a7de0412db209b61167d61f Mon Sep 17 00:00:00 2001 +From: Biao Huang +Date: Thu, 14 Jul 2022 14:00:14 +0800 +Subject: [PATCH 16/28] net: stmmac: fix unbalanced ptp clock issue in + suspend/resume flow +Git-commit: f4c7d8948e866918d61493264dbbd67e45ef2bda +Patch-mainline: v5.19-rc8 +References: git-fixes + +Current stmmac driver will prepare/enable ptp_ref clock in +stmmac_init_tstamp_counter(). + +The stmmac_pltfr_noirq_suspend will disable it once in suspend flow. + +But in resume flow, + stmmac_pltfr_noirq_resume --> stmmac_init_tstamp_counter + stmmac_resume --> stmmac_hw_setup --> stmmac_init_ptp --> stmmac_init_tstamp_counter +ptp_ref clock reference counter increases twice, which leads to unbalance +ptp clock when resume back. + +Move ptp_ref clock prepare/enable out of stmmac_init_tstamp_counter to fix it. + +Fixes: 0735e639f129d ("net: stmmac: skip only stmmac_ptp_register when resume from suspend") +Signed-off-by: Biao Huang +Signed-off-by: David S. Miller +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 17 ++++++++--------- + drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 8 +++++++- + 2 files changed, 15 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index 2f06f46e1b7a..5f2f25de6639 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -843,19 +843,10 @@ int stmmac_init_tstamp_counter(struct stmmac_priv *priv, u32 systime_flags) + struct timespec64 now; + u32 sec_inc = 0; + u64 temp = 0; +- int ret; + + if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp)) + return -EOPNOTSUPP; + +- ret = clk_prepare_enable(priv->plat->clk_ptp_ref); +- if (ret < 0) { +- netdev_warn(priv->dev, +- "failed to enable PTP reference clock: %pe\n", +- ERR_PTR(ret)); +- return ret; +- } +- + stmmac_config_hw_tstamping(priv, priv->ptpaddr, systime_flags); + priv->systime_flags = systime_flags; + +@@ -3320,6 +3311,14 @@ static int stmmac_hw_setup(struct net_device *dev, bool ptp_register) + + stmmac_mmc_setup(priv); + ++ if (ptp_register) { ++ ret = clk_prepare_enable(priv->plat->clk_ptp_ref); ++ if (ret < 0) ++ netdev_warn(priv->dev, ++ "failed to enable PTP reference clock: %pe\n", ++ ERR_PTR(ret)); ++ } ++ + ret = stmmac_init_ptp(priv); + if (ret == -EOPNOTSUPP) + netdev_warn(priv->dev, "PTP not supported by HW\n"); +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +index 11e1055e8260..9f5cac4000da 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +@@ -815,7 +815,13 @@ static int __maybe_unused stmmac_pltfr_noirq_resume(struct device *dev) + if (ret) + return ret; + +- stmmac_init_tstamp_counter(priv, priv->systime_flags); ++ ret = clk_prepare_enable(priv->plat->clk_ptp_ref); ++ if (ret < 0) { ++ netdev_warn(priv->dev, ++ "failed to enable PTP reference clock: %pe\n", ++ ERR_PTR(ret)); ++ return ret; ++ } + } + + return 0; +-- +2.16.4 + diff --git a/patches.suse/net-stmmac-remove-redunctant-disable-xPCS-EEE-call.patch b/patches.suse/net-stmmac-remove-redunctant-disable-xPCS-EEE-call.patch new file mode 100644 index 0000000..843f3b4 --- /dev/null +++ b/patches.suse/net-stmmac-remove-redunctant-disable-xPCS-EEE-call.patch @@ -0,0 +1,44 @@ +From 67e500f7f681d7e6aa5636b84ffe11c00c87ba4a Mon Sep 17 00:00:00 2001 +From: Wong Vee Khee +Date: Fri, 15 Jul 2022 20:24:02 +0800 +Subject: [PATCH 20/28] net: stmmac: remove redunctant disable xPCS EEE call +Git-commit: da791bac104a3169b05b54270afe75daacba4641 +Patch-mainline: v5.19-rc8 +References: git-fixes + +Disable is done in stmmac_init_eee() on the event of MAC link down. +Since setting enable/disable EEE via ethtool will eventually trigger +a MAC down, removing this redunctant call in stmmac_ethtool.c to avoid +calling xpcs_config_eee() twice. + +Fixes: d4aeaed80b0e ("net: stmmac: trigger PCS EEE to turn off on link down") +Signed-off-by: Wong Vee Khee +Link: https://lore.kernel.org/r/20220715122402.1017470-1-vee.khee.wong@linux.intel.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 8 -------- + 1 file changed, 8 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +index 9acd955a61e1..c494ccd04250 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +@@ -735,14 +735,6 @@ static int stmmac_ethtool_op_set_eee(struct net_device *dev, + netdev_warn(priv->dev, + "Setting EEE tx-lpi is not supported\n"); + +- if (priv->hw->xpcs) { +- ret = xpcs_config_eee(priv->hw->xpcs, +- priv->plat->mult_fact_100ns, +- edata->eee_enabled); +- if (ret) +- return ret; +- } +- + if (!edata->eee_enabled) + stmmac_disable_eee_mode(priv); + +-- +2.16.4 + diff --git a/patches.suse/net-stmmac-remove-unused-get_addr-callback.patch b/patches.suse/net-stmmac-remove-unused-get_addr-callback.patch new file mode 100644 index 0000000..2f56a6e --- /dev/null +++ b/patches.suse/net-stmmac-remove-unused-get_addr-callback.patch @@ -0,0 +1,148 @@ +From 97cc8884ac81e05479c33d21829977998c1c7aed Mon Sep 17 00:00:00 2001 +From: Vincent Whitchurch +Date: Tue, 17 May 2022 10:16:01 +0200 +Subject: [PATCH 10/19] net: stmmac: remove unused get_addr() callback +Git-commit: e991d0ed0b7a4c135236ec41ba7df7ea99ea9247 +Patch-mainline: v5.19-rc1 +References: git-fixes + +The last caller of the stmmac_desc_ops::get_addr() callback was removed +a while ago, so remove the unused callback. + +Note that the callback also only gets half the descriptor address on +systems with 64-bit descriptor addresses, so that should be fixed if it +needs to be resurrected later. + +Fixes: ec222003bd948de8f3 ("net: stmmac: Prepare to add Split Header support") +Signed-off-by: Vincent Whitchurch +Signed-off-by: David S. Miller +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c | 6 ------ + drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c | 6 ------ + drivers/net/ethernet/stmicro/stmmac/enh_desc.c | 6 ------ + drivers/net/ethernet/stmicro/stmmac/hwif.h | 4 ---- + drivers/net/ethernet/stmicro/stmmac/norm_desc.c | 6 ------ + 5 files changed, 28 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c +index cbf4429fb1d2..34958ed200af 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c +@@ -460,11 +460,6 @@ static void dwmac4_set_mss_ctxt(struct dma_desc *p, unsigned int mss) + p->des3 = cpu_to_le32(TDES3_CONTEXT_TYPE | TDES3_CTXT_TCMSSV); + } + +-static void dwmac4_get_addr(struct dma_desc *p, unsigned int *addr) +-{ +- *addr = le32_to_cpu(p->des0); +-} +- + static void dwmac4_set_addr(struct dma_desc *p, dma_addr_t addr) + { + p->des0 = cpu_to_le32(lower_32_bits(addr)); +@@ -573,7 +568,6 @@ const struct stmmac_desc_ops dwmac4_desc_ops = { + .init_tx_desc = dwmac4_rd_init_tx_desc, + .display_ring = dwmac4_display_ring, + .set_mss = dwmac4_set_mss_ctxt, +- .get_addr = dwmac4_get_addr, + .set_addr = dwmac4_set_addr, + .clear = dwmac4_clear, + .set_sarc = dwmac4_set_sarc, +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c +index ccfb0102dde4..b1f0c3984a09 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c +@@ -239,11 +239,6 @@ static void dwxgmac2_set_mss(struct dma_desc *p, unsigned int mss) + p->des3 = cpu_to_le32(XGMAC_TDES3_CTXT | XGMAC_TDES3_TCMSSV); + } + +-static void dwxgmac2_get_addr(struct dma_desc *p, unsigned int *addr) +-{ +- *addr = le32_to_cpu(p->des0); +-} +- + static void dwxgmac2_set_addr(struct dma_desc *p, dma_addr_t addr) + { + p->des0 = cpu_to_le32(lower_32_bits(addr)); +@@ -366,7 +361,6 @@ const struct stmmac_desc_ops dwxgmac210_desc_ops = { + .init_rx_desc = dwxgmac2_init_rx_desc, + .init_tx_desc = dwxgmac2_init_tx_desc, + .set_mss = dwxgmac2_set_mss, +- .get_addr = dwxgmac2_get_addr, + .set_addr = dwxgmac2_set_addr, + .clear = dwxgmac2_clear, + .get_rx_hash = dwxgmac2_get_rx_hash, +diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c +index 6650edfab5bc..1bcbbd724fb5 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c ++++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c +@@ -440,11 +440,6 @@ static void enh_desc_display_ring(void *head, unsigned int size, bool rx, + pr_info("\n"); + } + +-static void enh_desc_get_addr(struct dma_desc *p, unsigned int *addr) +-{ +- *addr = le32_to_cpu(p->des2); +-} +- + static void enh_desc_set_addr(struct dma_desc *p, dma_addr_t addr) + { + p->des2 = cpu_to_le32(addr); +@@ -475,7 +470,6 @@ const struct stmmac_desc_ops enh_desc_ops = { + .get_timestamp = enh_desc_get_timestamp, + .get_rx_timestamp_status = enh_desc_get_rx_timestamp_status, + .display_ring = enh_desc_display_ring, +- .get_addr = enh_desc_get_addr, + .set_addr = enh_desc_set_addr, + .clear = enh_desc_clear, + }; +diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h +index fe2660d5694d..12fbe47c3c3a 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/hwif.h ++++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h +@@ -82,8 +82,6 @@ struct stmmac_desc_ops { + dma_addr_t dma_rx_phy, unsigned int desc_size); + /* set MSS via context descriptor */ + void (*set_mss)(struct dma_desc *p, unsigned int mss); +- /* get descriptor skbuff address */ +- void (*get_addr)(struct dma_desc *p, unsigned int *addr); + /* set descriptor skbuff address */ + void (*set_addr)(struct dma_desc *p, dma_addr_t addr); + /* clear descriptor */ +@@ -142,8 +140,6 @@ struct stmmac_desc_ops { + stmmac_do_void_callback(__priv, desc, display_ring, __args) + #define stmmac_set_mss(__priv, __args...) \ + stmmac_do_void_callback(__priv, desc, set_mss, __args) +-#define stmmac_get_desc_addr(__priv, __args...) \ +- stmmac_do_void_callback(__priv, desc, get_addr, __args) + #define stmmac_set_desc_addr(__priv, __args...) \ + stmmac_do_void_callback(__priv, desc, set_addr, __args) + #define stmmac_clear_desc(__priv, __args...) \ +diff --git a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c +index 98ef43f35802..e3da4da242ee 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c ++++ b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c +@@ -292,11 +292,6 @@ static void ndesc_display_ring(void *head, unsigned int size, bool rx, + pr_info("\n"); + } + +-static void ndesc_get_addr(struct dma_desc *p, unsigned int *addr) +-{ +- *addr = le32_to_cpu(p->des2); +-} +- + static void ndesc_set_addr(struct dma_desc *p, dma_addr_t addr) + { + p->des2 = cpu_to_le32(addr); +@@ -326,7 +321,6 @@ const struct stmmac_desc_ops ndesc_ops = { + .get_timestamp = ndesc_get_timestamp, + .get_rx_timestamp_status = ndesc_get_rx_timestamp_status, + .display_ring = ndesc_display_ring, +- .get_addr = ndesc_get_addr, + .set_addr = ndesc_set_addr, + .clear = ndesc_clear, + }; +-- +2.16.4 + diff --git a/patches.suse/net-sungem_phy-Add-of_node_put-for-reference-returne.patch b/patches.suse/net-sungem_phy-Add-of_node_put-for-reference-returne.patch new file mode 100644 index 0000000..7039c18 --- /dev/null +++ b/patches.suse/net-sungem_phy-Add-of_node_put-for-reference-returne.patch @@ -0,0 +1,36 @@ +From 434e2b7d26bbf67e4515411e36539a8821e6c735 Mon Sep 17 00:00:00 2001 +From: Liang He +Date: Wed, 20 Jul 2022 21:10:03 +0800 +Subject: [PATCH 27/28] net: sungem_phy: Add of_node_put() for reference + returned by of_get_parent() +Git-commit: ebbbe23fdf6070e31509638df3321688358cc211 +Patch-mainline: v5.19 +References: git-fixes + +In bcm5421_init(), we should call of_node_put() for the reference +returned by of_get_parent() which has increased the refcount. + +Fixes: 3c326fe9cb7a ("[PATCH] ppc64: Add new PHY to sungem") +Signed-off-by: Liang He +Link: https://lore.kernel.org/r/20220720131003.1287426-1-windhl@126.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Denis Kirjanov +--- + drivers/net/sungem_phy.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/sungem_phy.c b/drivers/net/sungem_phy.c +index 291fa449993f..45f295403cb5 100644 +--- a/drivers/net/sungem_phy.c ++++ b/drivers/net/sungem_phy.c +@@ -454,6 +454,7 @@ static int bcm5421_init(struct mii_phy* phy) + int can_low_power = 1; + if (np == NULL || of_get_property(np, "no-autolowpower", NULL)) + can_low_power = 0; ++ of_node_put(np); + if (can_low_power) { + /* Enable automatic low-power */ + sungem_phy_write(phy, 0x1c, 0x9002); +-- +2.16.4 + diff --git a/patches.suse/net-sunrpc-fix-potential-memory-leaks-in-rpc_sysfs_x.patch b/patches.suse/net-sunrpc-fix-potential-memory-leaks-in-rpc_sysfs_x.patch new file mode 100644 index 0000000..3939ea5 --- /dev/null +++ b/patches.suse/net-sunrpc-fix-potential-memory-leaks-in-rpc_sysfs_x.patch @@ -0,0 +1,43 @@ +From: Xin Xiong +Date: Wed, 10 Aug 2022 23:29:13 +0800 +Subject: [PATCH] net/sunrpc: fix potential memory leaks in + rpc_sysfs_xprt_state_change() +Git-commit: bfc48f1b0505ffcb03a6d749139b7577d6b81ae0 +Patch-mainline: v6.0 +References: git-fixes + +The issue happens on some error handling paths. When the function +fails to grab the object `xprt`, it simply returns 0, forgetting to +decrease the reference count of another object `xps`, which is +increased by rpc_sysfs_xprt_kobj_get_xprt_switch(), causing refcount +leaks. Also, the function forgets to check whether `xps` is valid +before using it, which may result in NULL-dereferencing issues. + +Fix it by adding proper error handling code when either `xprt` or +`xps` is NULL. + +Fixes: 5b7eb78486cd ("SUNRPC: take a xprt offline using sysfs") +Signed-off-by: Xin Xiong +Signed-off-by: Xin Tan +Signed-off-by: David S. Miller +Acked-by: NeilBrown + +--- + net/sunrpc/sysfs.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/net/sunrpc/sysfs.c ++++ b/net/sunrpc/sysfs.c +@@ -263,8 +263,10 @@ static ssize_t rpc_sysfs_xprt_state_chan + int offline = 0, online = 0, remove = 0; + struct rpc_xprt_switch *xps = rpc_sysfs_xprt_kobj_get_xprt_switch(kobj); + +- if (!xprt) +- return 0; ++ if (!xprt || !xps) { ++ count = 0; ++ goto out_put; ++ } + + if (!strncmp(buf, "offline", 7)) + offline = 1; diff --git a/patches.suse/net-switch-to-netif_napi_add_tx.patch b/patches.suse/net-switch-to-netif_napi_add_tx.patch new file mode 100644 index 0000000..9e8daf5 --- /dev/null +++ b/patches.suse/net-switch-to-netif_napi_add_tx.patch @@ -0,0 +1,275 @@ +From: Jakub Kicinski +Date: Wed, 4 May 2022 09:37:24 -0700 +Subject: net: switch to netif_napi_add_tx() +Git-commit: 16d083e28f1a4f6deef82be92d6a0f5aa2fe7e08 +Patch-mainline: v5.19-rc1 +References: jsc#PED-1302 + +Switch net callers to the new API not requiring +the NAPI_POLL_WEIGHT argument. + +[lduncan: refreshed to apply.] + +Acked-by: Florian Fainelli +Reviewed-by: Alex Elder +Acked-by: Mat Martineau +Acked-by: Alexandra Winter +Link: https://lore.kernel.org/r/20220504163725.550782-1-kuba@kernel.org +Signed-off-by: Jakub Kicinski +Acked-by: Lee Duncan +--- + drivers/net/ethernet/broadcom/bcm4908_enet.c | 2 +- + drivers/net/ethernet/broadcom/bcmsysport.c | 2 +- + drivers/net/ethernet/broadcom/genet/bcmgenet.c | 3 +-- + drivers/net/ethernet/lantiq_xrx200.c | 3 ++- + drivers/net/ethernet/mellanox/mlx4/en_cq.c | 3 +-- + drivers/net/ethernet/microsoft/mana/mana_en.c | 2 +- + drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c | 9 ++++----- + drivers/net/ethernet/rocker/rocker_main.c | 3 +-- + drivers/net/ethernet/socionext/sni_ave.c | 3 +-- + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 5 ++--- + drivers/net/ethernet/ti/am65-cpsw-nuss.c | 4 ++-- + drivers/net/ethernet/ti/cpsw.c | 5 ++--- + drivers/net/ethernet/ti/cpsw_new.c | 5 ++--- + drivers/net/ethernet/ti/netcp_core.c | 2 +- + drivers/net/ipa/gsi.c | 4 ++-- + drivers/net/tun.c | 3 +-- + drivers/s390/net/qeth_core_main.c | 3 +-- + net/mptcp/protocol.c | 4 ++-- + 18 files changed, 28 insertions(+), 37 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bcm4908_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm4908_enet.c +@@ -724,7 +724,7 @@ static int bcm4908_enet_probe(struct pla + netdev->min_mtu = ETH_ZLEN; + netdev->mtu = ETH_DATA_LEN; + netdev->max_mtu = ENET_MTU_MAX; +- netif_tx_napi_add(netdev, &enet->tx_ring.napi, bcm4908_enet_poll_tx, NAPI_POLL_WEIGHT); ++ netif_napi_add_tx(netdev, &enet->tx_ring.napi, bcm4908_enet_poll_tx); + netif_napi_add(netdev, &enet->rx_ring.napi, bcm4908_enet_poll_rx, NAPI_POLL_WEIGHT); + + err = register_netdev(netdev); +--- a/drivers/net/ethernet/broadcom/bcmsysport.c ++++ b/drivers/net/ethernet/broadcom/bcmsysport.c +@@ -1517,7 +1517,7 @@ static int bcm_sysport_init_tx_ring(stru + /* Initialize SW view of the ring */ + spin_lock_init(&ring->lock); + ring->priv = priv; +- netif_tx_napi_add(priv->netdev, &ring->napi, bcm_sysport_tx_poll, 64); ++ netif_napi_add_tx(priv->netdev, &ring->napi, bcm_sysport_tx_poll); + ring->index = index; + ring->size = size; + ring->clean_index = 0; +--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c ++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c +@@ -2627,8 +2627,7 @@ static void bcmgenet_init_tx_ring(struct + DMA_END_ADDR); + + /* Initialize Tx NAPI */ +- netif_tx_napi_add(priv->dev, &ring->napi, bcmgenet_tx_poll, +- NAPI_POLL_WEIGHT); ++ netif_napi_add_tx(priv->dev, &ring->napi, bcmgenet_tx_poll); + } + + /* Initialize a RDMA ring */ +--- a/drivers/net/ethernet/lantiq_xrx200.c ++++ b/drivers/net/ethernet/lantiq_xrx200.c +@@ -499,7 +499,8 @@ static int xrx200_probe(struct platform_ + + /* setup NAPI */ + netif_napi_add(net_dev, &priv->chan_rx.napi, xrx200_poll_rx, 32); +- netif_tx_napi_add(net_dev, &priv->chan_tx.napi, xrx200_tx_housekeeping, 32); ++ netif_napi_add_tx(net_dev, &priv->chan_tx.napi, ++ xrx200_tx_housekeeping); + + platform_set_drvdata(pdev, priv); + +--- a/drivers/net/ethernet/mellanox/mlx4/en_cq.c ++++ b/drivers/net/ethernet/mellanox/mlx4/en_cq.c +@@ -147,8 +147,7 @@ int mlx4_en_activate_cq(struct mlx4_en_p + switch (cq->type) { + case TX: + cq->mcq.comp = mlx4_en_tx_irq; +- netif_tx_napi_add(cq->dev, &cq->napi, mlx4_en_poll_tx_cq, +- NAPI_POLL_WEIGHT); ++ netif_napi_add_tx(cq->dev, &cq->napi, mlx4_en_poll_tx_cq); + napi_enable(&cq->napi); + break; + case RX: +--- a/drivers/net/ethernet/microsoft/mana/mana_en.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c +@@ -1369,7 +1369,7 @@ static int mana_create_txq(struct mana_p + + gc->cq_table[cq->gdma_id] = cq->gdma_cq; + +- netif_tx_napi_add(net, &cq->napi, mana_poll, NAPI_POLL_WEIGHT); ++ netif_napi_add_tx(net, &cq->napi, mana_poll); + napi_enable(&cq->napi); + + mana_gd_ring_cq(cq->gdma_cq, SET_ARM_BIT); +--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c ++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c +@@ -1608,8 +1608,8 @@ int qlcnic_82xx_napi_add(struct qlcnic_a + if (qlcnic_check_multi_tx(adapter) && !adapter->ahw->diag_test) { + for (ring = 0; ring < adapter->drv_tx_rings; ring++) { + tx_ring = &adapter->tx_ring[ring]; +- netif_tx_napi_add(netdev, &tx_ring->napi, qlcnic_tx_poll, +- NAPI_POLL_WEIGHT); ++ netif_napi_add_tx(netdev, &tx_ring->napi, ++ qlcnic_tx_poll); + } + } + +@@ -2138,9 +2138,8 @@ int qlcnic_83xx_napi_add(struct qlcnic_a + !(adapter->flags & QLCNIC_TX_INTR_SHARED)) { + for (ring = 0; ring < adapter->drv_tx_rings; ring++) { + tx_ring = &adapter->tx_ring[ring]; +- netif_tx_napi_add(netdev, &tx_ring->napi, +- qlcnic_83xx_msix_tx_poll, +- NAPI_POLL_WEIGHT); ++ netif_napi_add_tx(netdev, &tx_ring->napi, ++ qlcnic_83xx_msix_tx_poll); + } + } + +--- a/drivers/net/ethernet/rocker/rocker_main.c ++++ b/drivers/net/ethernet/rocker/rocker_main.c +@@ -2584,8 +2584,7 @@ static int rocker_probe_port(struct rock + rocker_port_dev_addr_init(rocker_port); + dev->netdev_ops = &rocker_port_netdev_ops; + dev->ethtool_ops = &rocker_port_ethtool_ops; +- netif_tx_napi_add(dev, &rocker_port->napi_tx, rocker_port_poll_tx, +- NAPI_POLL_WEIGHT); ++ netif_napi_add_tx(dev, &rocker_port->napi_tx, rocker_port_poll_tx); + netif_napi_add(dev, &rocker_port->napi_rx, rocker_port_poll_rx, + NAPI_POLL_WEIGHT); + rocker_carrier_init(rocker_port); +--- a/drivers/net/ethernet/socionext/sni_ave.c ++++ b/drivers/net/ethernet/socionext/sni_ave.c +@@ -1689,8 +1689,7 @@ static int ave_probe(struct platform_dev + /* Register as a NAPI supported driver */ + netif_napi_add(ndev, &priv->napi_rx, ave_napi_poll_rx, + NAPI_POLL_WEIGHT); +- netif_tx_napi_add(ndev, &priv->napi_tx, ave_napi_poll_tx, +- NAPI_POLL_WEIGHT); ++ netif_napi_add_tx(ndev, &priv->napi_tx, ave_napi_poll_tx); + + platform_set_drvdata(pdev, ndev); + +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -6824,9 +6824,8 @@ static void stmmac_napi_add(struct net_d + NAPI_POLL_WEIGHT); + } + if (queue < priv->plat->tx_queues_to_use) { +- netif_tx_napi_add(dev, &ch->tx_napi, +- stmmac_napi_poll_tx, +- NAPI_POLL_WEIGHT); ++ netif_napi_add_tx(dev, &ch->tx_napi, ++ stmmac_napi_poll_tx); + } + if (queue < priv->plat->rx_queues_to_use && + queue < priv->plat->tx_queues_to_use) { +--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c ++++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c +@@ -2027,8 +2027,8 @@ static int am65_cpsw_nuss_ndev_add_tx_na + for (i = 0; i < common->tx_ch_num; i++) { + struct am65_cpsw_tx_chn *tx_chn = &common->tx_chns[i]; + +- netif_tx_napi_add(common->dma_ndev, &tx_chn->napi_tx, +- am65_cpsw_nuss_tx_poll, NAPI_POLL_WEIGHT); ++ netif_napi_add_tx(common->dma_ndev, &tx_chn->napi_tx, ++ am65_cpsw_nuss_tx_poll); + + ret = devm_request_irq(dev, tx_chn->irq, + am65_cpsw_nuss_tx_irq, +--- a/drivers/net/ethernet/ti/cpsw.c ++++ b/drivers/net/ethernet/ti/cpsw.c +@@ -1650,9 +1650,8 @@ static int cpsw_probe(struct platform_de + netif_napi_add(ndev, &cpsw->napi_rx, + cpsw->quirk_irq ? cpsw_rx_poll : cpsw_rx_mq_poll, + CPSW_POLL_WEIGHT); +- netif_tx_napi_add(ndev, &cpsw->napi_tx, +- cpsw->quirk_irq ? cpsw_tx_poll : cpsw_tx_mq_poll, +- CPSW_POLL_WEIGHT); ++ netif_napi_add_tx(ndev, &cpsw->napi_tx, ++ cpsw->quirk_irq ? cpsw_tx_poll : cpsw_tx_mq_poll); + + /* register the network device */ + SET_NETDEV_DEV(ndev, dev); +--- a/drivers/net/ethernet/ti/cpsw_new.c ++++ b/drivers/net/ethernet/ti/cpsw_new.c +@@ -1425,10 +1425,9 @@ static int cpsw_create_ports(struct cpsw + cpsw->quirk_irq ? + cpsw_rx_poll : cpsw_rx_mq_poll, + CPSW_POLL_WEIGHT); +- netif_tx_napi_add(ndev, &cpsw->napi_tx, ++ netif_napi_add_tx(ndev, &cpsw->napi_tx, + cpsw->quirk_irq ? +- cpsw_tx_poll : cpsw_tx_mq_poll, +- CPSW_POLL_WEIGHT); ++ cpsw_tx_poll : cpsw_tx_mq_poll); + } + + napi_ndev = ndev; +--- a/drivers/net/ethernet/ti/netcp_core.c ++++ b/drivers/net/ethernet/ti/netcp_core.c +@@ -2097,7 +2097,7 @@ static int netcp_create_interface(struct + + /* NAPI register */ + netif_napi_add(ndev, &netcp->rx_napi, netcp_rx_poll, NETCP_NAPI_WEIGHT); +- netif_tx_napi_add(ndev, &netcp->tx_napi, netcp_tx_poll, NETCP_NAPI_WEIGHT); ++ netif_napi_add_tx(ndev, &netcp->tx_napi, netcp_tx_poll); + + /* Register the network device */ + ndev->dev_id = 0; +--- a/drivers/net/ipa/gsi.c ++++ b/drivers/net/ipa/gsi.c +@@ -1689,8 +1689,8 @@ static int gsi_channel_setup_one(struct + gsi_channel_program(channel, true); + + if (channel->toward_ipa) +- netif_tx_napi_add(&gsi->dummy_dev, &channel->napi, +- gsi_channel_poll, NAPI_POLL_WEIGHT); ++ netif_napi_add_tx(&gsi->dummy_dev, &channel->napi, ++ gsi_channel_poll); + else + netif_napi_add(&gsi->dummy_dev, &channel->napi, + gsi_channel_poll, NAPI_POLL_WEIGHT); +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -268,8 +268,7 @@ static void tun_napi_init(struct tun_str + tfile->napi_enabled = napi_en; + tfile->napi_frags_enabled = napi_en && napi_frags; + if (napi_en) { +- netif_tx_napi_add(tun->dev, &tfile->napi, tun_napi_poll, +- NAPI_POLL_WEIGHT); ++ netif_napi_add_tx(tun->dev, &tfile->napi, tun_napi_poll); + napi_enable(&tfile->napi); + } + } +--- a/drivers/s390/net/qeth_core_main.c ++++ b/drivers/s390/net/qeth_core_main.c +@@ -7190,8 +7190,7 @@ int qeth_open(struct net_device *dev) + + local_bh_disable(); + qeth_for_each_output_queue(card, queue, i) { +- netif_tx_napi_add(dev, &queue->napi, qeth_tx_poll, +- NAPI_POLL_WEIGHT); ++ netif_napi_add_tx(dev, &queue->napi, qeth_tx_poll); + napi_enable(&queue->napi); + napi_schedule(&queue->napi); + } +--- a/net/mptcp/protocol.c ++++ b/net/mptcp/protocol.c +@@ -3379,8 +3379,8 @@ void __init mptcp_proto_init(void) + for_each_possible_cpu(cpu) { + delegated = per_cpu_ptr(&mptcp_delegated_actions, cpu); + INIT_LIST_HEAD(&delegated->head); +- netif_tx_napi_add(&mptcp_napi_dev, &delegated->napi, mptcp_napi_poll, +- NAPI_POLL_WEIGHT); ++ netif_napi_add_tx(&mptcp_napi_dev, &delegated->napi, ++ mptcp_napi_poll); + napi_enable(&delegated->napi); + } + diff --git a/patches.suse/net-thunderbolt-Enable-DMA-paths-only-after-rings-ar.patch b/patches.suse/net-thunderbolt-Enable-DMA-paths-only-after-rings-ar.patch new file mode 100644 index 0000000..739f486 --- /dev/null +++ b/patches.suse/net-thunderbolt-Enable-DMA-paths-only-after-rings-ar.patch @@ -0,0 +1,83 @@ +From ff7cd07f306406493f7b78890475e85b6d0811ed Mon Sep 17 00:00:00 2001 +From: Mika Westerberg +Date: Tue, 30 Aug 2022 18:32:46 +0300 +Subject: [PATCH] net: thunderbolt: Enable DMA paths only after rings are enabled +Git-commit: ff7cd07f306406493f7b78890475e85b6d0811ed +Patch-mainline: v6.1-rc1 +References: git-fixes + +If the other host starts sending packets early on it is possible that we +are still in the middle of populating the initial Rx ring packets to the +ring. This causes the tbnet_poll() to mess over the queue and causes +list corruption. This happens specifically when connected with macOS as +it seems start sending various IP discovery packets as soon as its side +of the paths are configured. + +To prevent this we move the DMA path enabling to happen after we have +primed the Rx ring. This makes sure no incoming packets can arrive +before we are ready to handle them. + +Fixes: e69b6c02b4c3 ("net: Add support for networking over Thunderbolt cable") +Cc: stable@vger.kernel.org +Signed-off-by: Mika Westerberg +Signed-off-by: David S. Miller +Acked-by: Takashi Iwai + +--- + drivers/net/thunderbolt.c | 28 +++++++++++++++++----------- + 1 file changed, 17 insertions(+), 11 deletions(-) + +diff --git a/drivers/net/thunderbolt.c b/drivers/net/thunderbolt.c +index ff5d0e98a088..ab3f04562980 100644 +--- a/drivers/net/thunderbolt.c ++++ b/drivers/net/thunderbolt.c +@@ -612,18 +612,13 @@ static void tbnet_connected_work(struct work_struct *work) + return; + } + +- /* Both logins successful so enable the high-speed DMA paths and +- * start the network device queue. ++ /* Both logins successful so enable the rings, high-speed DMA ++ * paths and start the network device queue. ++ * ++ * Note we enable the DMA paths last to make sure we have primed ++ * the Rx ring before any incoming packets are allowed to ++ * arrive. + */ +- ret = tb_xdomain_enable_paths(net->xd, net->local_transmit_path, +- net->rx_ring.ring->hop, +- net->remote_transmit_path, +- net->tx_ring.ring->hop); +- if (ret) { +- netdev_err(net->dev, "failed to enable DMA paths\n"); +- return; +- } +- + tb_ring_start(net->tx_ring.ring); + tb_ring_start(net->rx_ring.ring); + +@@ -635,10 +630,21 @@ static void tbnet_connected_work(struct work_struct *work) + if (ret) + goto err_free_rx_buffers; + ++ ret = tb_xdomain_enable_paths(net->xd, net->local_transmit_path, ++ net->rx_ring.ring->hop, ++ net->remote_transmit_path, ++ net->tx_ring.ring->hop); ++ if (ret) { ++ netdev_err(net->dev, "failed to enable DMA paths\n"); ++ goto err_free_tx_buffers; ++ } ++ + netif_carrier_on(net->dev); + netif_start_queue(net->dev); + return; + ++err_free_tx_buffers: ++ tbnet_free_buffers(&net->tx_ring); + err_free_rx_buffers: + tbnet_free_buffers(&net->rx_ring); + err_stop_rings: +-- +2.35.3 + diff --git a/patches.suse/net-usb-qmi_wwan-Add-new-usb-id-for-Dell-branded-EM7.patch b/patches.suse/net-usb-qmi_wwan-Add-new-usb-id-for-Dell-branded-EM7.patch new file mode 100644 index 0000000..40440d5 --- /dev/null +++ b/patches.suse/net-usb-qmi_wwan-Add-new-usb-id-for-Dell-branded-EM7.patch @@ -0,0 +1,39 @@ +From 797666cd5af041ffb66642fff62f7389f08566a2 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Mon, 26 Sep 2022 17:07:40 +0200 +Subject: [PATCH] net: usb: qmi_wwan: Add new usb-id for Dell branded EM7455 +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 797666cd5af041ffb66642fff62f7389f08566a2 +Patch-mainline: v6.0 +References: git-fixes + +Add support for Dell 5811e (EM7455) with USB-id 0x413c:0x81c2. + +Signed-off-by: Frank Wunderlich +Cc: stable@vger.kernel.org +Acked-by: Bjørn Mork +Link: https://lore.kernel.org/r/20220926150740.6684-3-linux@fw-web.de +Signed-off-by: Jakub Kicinski +Acked-by: Takashi Iwai + +--- + drivers/net/usb/qmi_wwan.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c +index 0cb187def5bc..26c34a7c21bd 100644 +--- a/drivers/net/usb/qmi_wwan.c ++++ b/drivers/net/usb/qmi_wwan.c +@@ -1402,6 +1402,7 @@ static const struct usb_device_id products[] = { + {QMI_FIXED_INTF(0x413c, 0x81b3, 8)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card (rev3) */ + {QMI_FIXED_INTF(0x413c, 0x81b6, 8)}, /* Dell Wireless 5811e */ + {QMI_FIXED_INTF(0x413c, 0x81b6, 10)}, /* Dell Wireless 5811e */ ++ {QMI_FIXED_INTF(0x413c, 0x81c2, 8)}, /* Dell Wireless 5811e */ + {QMI_FIXED_INTF(0x413c, 0x81cc, 8)}, /* Dell Wireless 5816e */ + {QMI_FIXED_INTF(0x413c, 0x81d7, 0)}, /* Dell Wireless 5821e */ + {QMI_FIXED_INTF(0x413c, 0x81d7, 1)}, /* Dell Wireless 5821e preproduction config */ +-- +2.35.3 + diff --git a/patches.suse/net-usb-qmi_wwan-add-Quectel-RM520N.patch b/patches.suse/net-usb-qmi_wwan-add-Quectel-RM520N.patch new file mode 100644 index 0000000..45c70c2 --- /dev/null +++ b/patches.suse/net-usb-qmi_wwan-add-Quectel-RM520N.patch @@ -0,0 +1,67 @@ +From e1091e226a2bab4ded1fe26efba2aee1aab06450 Mon Sep 17 00:00:00 2001 +From: "jerry.meng" +Date: Mon, 5 Sep 2022 09:24:52 +0800 +Subject: [PATCH] net: usb: qmi_wwan: add Quectel RM520N +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: e1091e226a2bab4ded1fe26efba2aee1aab06450 +Patch-mainline: v6.0-rc5 +References: git-fixes + +add support for Quectel RM520N which is based on Qualcomm SDX62 chip. + +0x0801: DIAG + NMEA + AT + MODEM + RMNET + +T: Bus=03 Lev=01 Prnt=01 Port=01 Cnt=02 Dev#= 10 Spd=480 MxCh= 0 +D: Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 +P: Vendor=2c7c ProdID=0801 Rev= 5.04 +S: Manufacturer=Quectel +S: Product=RM520N-GL +S: SerialNumber=384af524 +C:* #Ifs= 5 Cfg#= 1 Atr=a0 MxPwr=500mA +I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option +E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=40 Driver=option +E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option +E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option +E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan +E: Ad=88(I) Atr=03(Int.) MxPS= 8 Ivl=32ms +E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=0f(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms + +Signed-off-by: jerry.meng +Acked-by: Bjørn Mork +Link: https://lore.kernel.org/r/tencent_E50CA8A206904897C2D20DDAE90731183C05@qq.com +Signed-off-by: Paolo Abeni +Acked-by: Takashi Iwai + +--- + drivers/net/usb/qmi_wwan.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c +index 709e3c59e340..0cb187def5bc 100644 +--- a/drivers/net/usb/qmi_wwan.c ++++ b/drivers/net/usb/qmi_wwan.c +@@ -1087,6 +1087,7 @@ static const struct usb_device_id products[] = { + {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0512)}, /* Quectel EG12/EM12 */ + {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0620)}, /* Quectel EM160R-GL */ + {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0800)}, /* Quectel RM500Q-GL */ ++ {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0801)}, /* Quectel RM520N */ + + /* 3. Combined interface devices matching on interface number */ + {QMI_FIXED_INTF(0x0408, 0xea42, 4)}, /* Yota / Megafon M100-1 */ +-- +2.35.3 + diff --git a/patches.suse/net-wwan-iosm-Call-mutex_init-before-locking-it.patch b/patches.suse/net-wwan-iosm-Call-mutex_init-before-locking-it.patch new file mode 100644 index 0000000..bbcc962 --- /dev/null +++ b/patches.suse/net-wwan-iosm-Call-mutex_init-before-locking-it.patch @@ -0,0 +1,50 @@ +From ba0fbdb95da5ddd8db457ce6ba09d16dd979a294 Mon Sep 17 00:00:00 2001 +From: Maxim Mikityanskiy +Date: Sat, 1 Oct 2022 13:57:13 +0300 +Subject: [PATCH] net: wwan: iosm: Call mutex_init before locking it +Git-commit: ba0fbdb95da5ddd8db457ce6ba09d16dd979a294 +Patch-mainline: v6.1-rc1 +References: git-fixes + +wwan_register_ops calls wwan_create_default_link, which ends up in the +ipc_wwan_newlink callback that locks ipc_wwan->if_mutex. However, this +mutex is not yet initialized by that point. Fix it by moving mutex_init +above the wwan_register_ops call. This also makes the order of +operations in ipc_wwan_init symmetric to ipc_wwan_deinit. + +Fixes: 83068395bbfc ("net: iosm: create default link via WWAN core") +Signed-off-by: Maxim Mikityanskiy +Reviewed-by: M Chetan Kumar +Signed-off-by: David S. Miller +Acked-by: Takashi Iwai + +--- + drivers/net/wwan/iosm/iosm_ipc_wwan.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wwan/iosm/iosm_ipc_wwan.c b/drivers/net/wwan/iosm/iosm_ipc_wwan.c +index 27151148c782..4712f01a7e33 100644 +--- a/drivers/net/wwan/iosm/iosm_ipc_wwan.c ++++ b/drivers/net/wwan/iosm/iosm_ipc_wwan.c +@@ -323,15 +323,16 @@ struct iosm_wwan *ipc_wwan_init(struct iosm_imem *ipc_imem, struct device *dev) + ipc_wwan->dev = dev; + ipc_wwan->ipc_imem = ipc_imem; + ++ mutex_init(&ipc_wwan->if_mutex); ++ + /* WWAN core will create a netdev for the default IP MUX channel */ + if (wwan_register_ops(ipc_wwan->dev, &iosm_wwan_ops, ipc_wwan, + IP_MUX_SESSION_DEFAULT)) { ++ mutex_destroy(&ipc_wwan->if_mutex); + kfree(ipc_wwan); + return NULL; + } + +- mutex_init(&ipc_wwan->if_mutex); +- + return ipc_wwan; + } + +-- +2.35.3 + diff --git a/patches.suse/net-wwan-iosm-remove-pointless-null-check.patch b/patches.suse/net-wwan-iosm-remove-pointless-null-check.patch new file mode 100644 index 0000000..77dcdd2 --- /dev/null +++ b/patches.suse/net-wwan-iosm-remove-pointless-null-check.patch @@ -0,0 +1,58 @@ +From 5eb0cb765e49ee454f6e4f4fc9fecebb900c847c Mon Sep 17 00:00:00 2001 +From: Jakub Kicinski +Date: Wed, 18 May 2022 17:43:42 -0700 +Subject: [PATCH 12/19] net: wwan: iosm: remove pointless null check +Git-commit: dbbc7d04c549a43ad343c69e17b27a57e2102041 +Patch-mainline: v5.19-rc1 +References: git-fixes + +GCC 12 warns: + +drivers/net/wwan/iosm/iosm_ipc_protocol_ops.c: In function ‘ipc_protocol_dl_td_process’: +drivers/net/wwan/iosm/iosm_ipc_protocol_ops.c:406:13: warning: the comparison will always evaluate as ‘true’ for the address of ‘cb’ will never be NULL [-Waddress] + 406 | if (!IPC_CB(skb)) { + | ^ + +Indeed the check seems entirely pointless. Hopefully the other +validation checks will catch if the cb is bad, but it can't be +NULL. + +Reviewed-by: M Chetan Kumar +Link: https://lore.kernel.org/r/20220519004342.2109832-1-kuba@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Denis Kirjanov +--- + drivers/net/wwan/iosm/iosm_ipc_protocol_ops.c | 10 ---------- + 1 file changed, 10 deletions(-) + +diff --git a/drivers/net/wwan/iosm/iosm_ipc_protocol_ops.c b/drivers/net/wwan/iosm/iosm_ipc_protocol_ops.c +index 35d590743d3a..6dc975dc2a4d 100644 +--- a/drivers/net/wwan/iosm/iosm_ipc_protocol_ops.c ++++ b/drivers/net/wwan/iosm/iosm_ipc_protocol_ops.c +@@ -372,8 +372,6 @@ bool ipc_protocol_dl_td_prepare(struct iosm_protocol *ipc_protocol, + struct sk_buff *ipc_protocol_dl_td_process(struct iosm_protocol *ipc_protocol, + struct ipc_pipe *pipe) + { +- u32 tail = +- le32_to_cpu(ipc_protocol->p_ap_shm->tail_array[pipe->pipe_nr]); + struct ipc_protocol_td *p_td; + struct sk_buff *skb; + +@@ -403,14 +401,6 @@ struct sk_buff *ipc_protocol_dl_td_process(struct iosm_protocol *ipc_protocol, + goto ret; + } + +- if (!IPC_CB(skb)) { +- dev_err(ipc_protocol->dev, "pipe# %d, tail: %d skb_cb is NULL", +- pipe->pipe_nr, tail); +- ipc_pcie_kfree_skb(ipc_protocol->pcie, skb); +- skb = NULL; +- goto ret; +- } +- + if (p_td->buffer.address != IPC_CB(skb)->mapping) { + dev_err(ipc_protocol->dev, "invalid buf=%llx or skb=%p", + (unsigned long long)p_td->buffer.address, skb->data); +-- +2.16.4 + diff --git a/patches.suse/nfsd-eliminate-the-NFSD_FILE_BREAK_-flags.patch b/patches.suse/nfsd-eliminate-the-NFSD_FILE_BREAK_-flags.patch new file mode 100644 index 0000000..99bc321 --- /dev/null +++ b/patches.suse/nfsd-eliminate-the-NFSD_FILE_BREAK_-flags.patch @@ -0,0 +1,109 @@ +From: Jeff Layton +Date: Fri, 29 Jul 2022 17:01:07 -0400 +Subject: [PATCH] nfsd: eliminate the NFSD_FILE_BREAK_* flags +Git-commit: 23ba98de6dcec665e15c0ca19244379bb0d30932 +Patch-mainline: v6.0 +References: git-fixes + +We had a report from the spring Bake-a-thon of data corruption in some +nfstest_interop tests. Looking at the traces showed the NFS server +allowing a v3 WRITE to proceed while a read delegation was still +outstanding. + +Currently, we only set NFSD_FILE_BREAK_* flags if +NFSD_MAY_NOT_BREAK_LEASE was set when we call nfsd_file_alloc. +NFSD_MAY_NOT_BREAK_LEASE was intended to be set when finding files for +COMMIT ops, where we need a writeable filehandle but don't need to +break read leases. + +It doesn't make any sense to consult that flag when allocating a file +since the file may be used on subsequent calls where we do want to break +the lease (and the usage of it here seems to be reverse from what it +should be anyway). + +Also, after calling nfsd_open_break_lease, we don't want to clear the +BREAK_* bits. A lease could end up being set on it later (more than +once) and we need to be able to break those leases as well. + +This means that the NFSD_FILE_BREAK_* flags now just mirror +NFSD_MAY_{READ,WRITE} flags, so there's no need for them at all. Just +drop those flags and unconditionally call nfsd_open_break_lease every +time. + +Reported-by: Olga Kornieskaia +Link: https://bugzilla.redhat.com/show_bug.cgi?id=2107360 +Fixes: 65294c1f2c5e (nfsd: add a new struct file caching facility to nfsd) +Cc: # 5.4.x : bb283ca18d1e NFSD: Clean up the show_nf_flags() macro +Cc: # 5.4.x +Signed-off-by: Jeff Layton +Signed-off-by: Chuck Lever +Acked-by: NeilBrown + +--- + fs/nfsd/filecache.c | 22 +--------------------- + fs/nfsd/filecache.h | 4 +--- + fs/nfsd/trace.h | 2 -- + 3 files changed, 2 insertions(+), 26 deletions(-) + +--- a/fs/nfsd/filecache.c ++++ b/fs/nfsd/filecache.c +@@ -187,12 +187,6 @@ nfsd_file_alloc(struct inode *inode, uns + nf->nf_hashval = hashval; + refcount_set(&nf->nf_ref, 1); + nf->nf_may = may & NFSD_FILE_MAY_MASK; +- if (may & NFSD_MAY_NOT_BREAK_LEASE) { +- if (may & NFSD_MAY_WRITE) +- __set_bit(NFSD_FILE_BREAK_WRITE, &nf->nf_flags); +- if (may & NFSD_MAY_READ) +- __set_bit(NFSD_FILE_BREAK_READ, &nf->nf_flags); +- } + nf->nf_mark = NULL; + trace_nfsd_file_alloc(nf); + } +@@ -1002,21 +996,7 @@ wait_for_construction: + + this_cpu_inc(nfsd_file_cache_hits); + +- if (!(may_flags & NFSD_MAY_NOT_BREAK_LEASE)) { +- bool write = (may_flags & NFSD_MAY_WRITE); +- +- if (test_bit(NFSD_FILE_BREAK_READ, &nf->nf_flags) || +- (test_bit(NFSD_FILE_BREAK_WRITE, &nf->nf_flags) && write)) { +- status = nfserrno(nfsd_open_break_lease( +- file_inode(nf->nf_file), may_flags)); +- if (status == nfs_ok) { +- clear_bit(NFSD_FILE_BREAK_READ, &nf->nf_flags); +- if (write) +- clear_bit(NFSD_FILE_BREAK_WRITE, +- &nf->nf_flags); +- } +- } +- } ++ status = nfserrno(nfsd_open_break_lease(file_inode(nf->nf_file), may_flags)); + out: + if (status == nfs_ok) { + *pnf = nf; +--- a/fs/nfsd/filecache.h ++++ b/fs/nfsd/filecache.h +@@ -37,9 +37,7 @@ struct nfsd_file { + struct net *nf_net; + #define NFSD_FILE_HASHED (0) + #define NFSD_FILE_PENDING (1) +-#define NFSD_FILE_BREAK_READ (2) +-#define NFSD_FILE_BREAK_WRITE (3) +-#define NFSD_FILE_REFERENCED (4) ++#define NFSD_FILE_REFERENCED (2) + unsigned long nf_flags; + struct inode *nf_inode; + unsigned int nf_hashval; +--- a/fs/nfsd/trace.h ++++ b/fs/nfsd/trace.h +@@ -643,8 +643,6 @@ DEFINE_CLID_EVENT(confirmed_r); + __print_flags(val, "|", \ + { 1 << NFSD_FILE_HASHED, "HASHED" }, \ + { 1 << NFSD_FILE_PENDING, "PENDING" }, \ +- { 1 << NFSD_FILE_BREAK_READ, "BREAK_READ" }, \ +- { 1 << NFSD_FILE_BREAK_WRITE, "BREAK_WRITE" }, \ + { 1 << NFSD_FILE_REFERENCED, "REFERENCED"}) + + DECLARE_EVENT_CLASS(nfsd_file_class, diff --git a/patches.suse/nvme-don-t-print-verbose-errors-for-internal-passthr.patch b/patches.suse/nvme-don-t-print-verbose-errors-for-internal-passthr.patch new file mode 100644 index 0000000..cc5f8c6 --- /dev/null +++ b/patches.suse/nvme-don-t-print-verbose-errors-for-internal-passthr.patch @@ -0,0 +1,44 @@ +From: Chaitanya Kulkarni +Date: Sun, 10 Apr 2022 20:12:49 -0700 +Subject: nvme: don't print verbose errors for internal passthrough requests +Patch-mainline: v5.18-rc3 +Git-commit: b42b6f4485e3f0970e11f73df6202eeaf9f53a3e +References: bsc#1202187 + +Use the RQF_QUIET flag to skip the newly added verbose error reporting, +and set the flag in __nvme_submit_sync_cmd, which is used for most +internal passthrough requests where we do expect errors (e.g. due to +probing for optional functionality). This is similar to what the SCSI +verbose error logging does. + +Signed-off-by: Chaitanya Kulkarni +Reviewed-by: Alan Adamson +Reviewed-by: Keith Busch +Reviewed-by: Sagi Grimberg +Tested-by: Alan Adamson +Tested-by: Yi Zhang +Signed-off-by: Christoph Hellwig +Acked-by: Daniel Wagner +--- + drivers/nvme/host/core.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -361,7 +361,7 @@ static inline void nvme_end_req(struct r + { + blk_status_t status = nvme_error_status(nvme_req(req)->status); + +- if (unlikely(nvme_req(req)->status != NVME_SC_SUCCESS)) ++ if (unlikely(nvme_req(req)->status && !(req->rq_flags & RQF_QUIET))) + nvme_log_error(req); + + if (IS_ENABLED(CONFIG_BLK_DEV_ZONED) && +@@ -1099,6 +1099,7 @@ int __nvme_submit_sync_cmd(struct reques + goto out; + } + ++ req->rq_flags |= RQF_QUIET; + ret = nvme_execute_rq(NULL, req, at_head); + if (result && ret >= 0) + *result = nvme_req(req)->result; diff --git a/patches.suse/nvme-ensure-subsystem-reset-is-single-threaded.patch b/patches.suse/nvme-ensure-subsystem-reset-is-single-threaded.patch new file mode 100644 index 0000000..d8a86f3 --- /dev/null +++ b/patches.suse/nvme-ensure-subsystem-reset-is-single-threaded.patch @@ -0,0 +1,69 @@ +From: Keith Busch +Date: Thu, 22 Sep 2022 08:13:47 -0700 +Subject: nvme: ensure subsystem reset is single threaded +Patch-mainline: v6.1-rc1 +Git-commit: 1e866afd4bcdd01a70a5eddb4371158d3035ce03 +References: bsc#1203290 CVE-2022-3169 + +The subsystem reset writes to a register, so we have to ensure the +device state is capable of handling that otherwise the driver may access +unmapped registers. Use the state machine to ensure the subsystem reset +doesn't try to write registers on a device already undergoing this type +of reset. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=214771 +Signed-off-by: Keith Busch +Signed-off-by: Christoph Hellwig +Acked-by: Daniel Wagner +--- + drivers/nvme/host/nvme.h | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h +index a0bf9560cf67..70555022cb44 100644 +--- a/drivers/nvme/host/nvme.h ++++ b/drivers/nvme/host/nvme.h +@@ -602,11 +602,23 @@ static inline void nvme_fault_inject_fini(struct nvme_fault_inject *fault_inj) + static inline void nvme_should_fail(struct request *req) {} + #endif + ++bool nvme_wait_reset(struct nvme_ctrl *ctrl); ++int nvme_try_sched_reset(struct nvme_ctrl *ctrl); ++ + static inline int nvme_reset_subsystem(struct nvme_ctrl *ctrl) + { ++ int ret; ++ + if (!ctrl->subsystem) + return -ENOTTY; +- return ctrl->ops->reg_write32(ctrl, NVME_REG_NSSR, 0x4E564D65); ++ if (!nvme_wait_reset(ctrl)) ++ return -EBUSY; ++ ++ ret = ctrl->ops->reg_write32(ctrl, NVME_REG_NSSR, 0x4E564D65); ++ if (ret) ++ return ret; ++ ++ return nvme_try_sched_reset(ctrl); + } + + /* +@@ -712,7 +724,6 @@ void nvme_cancel_tagset(struct nvme_ctrl *ctrl); + void nvme_cancel_admin_tagset(struct nvme_ctrl *ctrl); + bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl, + enum nvme_ctrl_state new_state); +-bool nvme_wait_reset(struct nvme_ctrl *ctrl); + int nvme_disable_ctrl(struct nvme_ctrl *ctrl); + int nvme_enable_ctrl(struct nvme_ctrl *ctrl); + int nvme_shutdown_ctrl(struct nvme_ctrl *ctrl); +@@ -802,7 +813,6 @@ int nvme_set_queue_count(struct nvme_ctrl *ctrl, int *count); + void nvme_stop_keep_alive(struct nvme_ctrl *ctrl); + int nvme_reset_ctrl(struct nvme_ctrl *ctrl); + int nvme_reset_ctrl_sync(struct nvme_ctrl *ctrl); +-int nvme_try_sched_reset(struct nvme_ctrl *ctrl); + int nvme_delete_ctrl(struct nvme_ctrl *ctrl); + void nvme_queue_scan(struct nvme_ctrl *ctrl); + int nvme_get_log(struct nvme_ctrl *ctrl, u32 nsid, u8 log_page, u8 lsp, u8 csi, +-- +2.35.3 + diff --git a/patches.suse/nvme-restrict-management-ioctls-to-admin.patch b/patches.suse/nvme-restrict-management-ioctls-to-admin.patch new file mode 100644 index 0000000..2aef023 --- /dev/null +++ b/patches.suse/nvme-restrict-management-ioctls-to-admin.patch @@ -0,0 +1,43 @@ +From: Keith Busch +Date: Thu, 22 Sep 2022 07:54:06 -0700 +Subject: nvme: restrict management ioctls to admin +Patch-mainline: v6.1-rc1 +Git-commit: 23e085b2dead13b51fe86d27069895b740f749c0 +References: bsc#1203290 CVE-2022-3169 + +The passthrough commands already have this restriction, but the other +operations do not. Require the same capabilities for all users as all of +these operations, which include resets and rescans, can be disruptive. + +Signed-off-by: Keith Busch +Signed-off-by: Christoph Hellwig +Acked-by: Daniel Wagner +--- + drivers/nvme/host/ioctl.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c +index d3281f87cd6e..a48a79ed5c4c 100644 +--- a/drivers/nvme/host/ioctl.c ++++ b/drivers/nvme/host/ioctl.c +@@ -764,11 +764,17 @@ long nvme_dev_ioctl(struct file *file, unsigned int cmd, + case NVME_IOCTL_IO_CMD: + return nvme_dev_user_cmd(ctrl, argp); + case NVME_IOCTL_RESET: ++ if (!capable(CAP_SYS_ADMIN)) ++ return -EACCES; + dev_warn(ctrl->device, "resetting controller\n"); + return nvme_reset_ctrl_sync(ctrl); + case NVME_IOCTL_SUBSYS_RESET: ++ if (!capable(CAP_SYS_ADMIN)) ++ return -EACCES; + return nvme_reset_subsystem(ctrl); + case NVME_IOCTL_RESCAN: ++ if (!capable(CAP_SYS_ADMIN)) ++ return -EACCES; + nvme_queue_scan(ctrl); + return 0; + default: +-- +2.35.3 + diff --git a/patches.suse/nvmem-core-Check-input-parameter-for-NULL-in-nvmem_u.patch b/patches.suse/nvmem-core-Check-input-parameter-for-NULL-in-nvmem_u.patch new file mode 100644 index 0000000..ccf7233 --- /dev/null +++ b/patches.suse/nvmem-core-Check-input-parameter-for-NULL-in-nvmem_u.patch @@ -0,0 +1,39 @@ +From 8c751e0d9a5264376935a84429a2d468c8877d99 Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Sun, 20 Feb 2022 15:15:17 +0000 +Subject: [PATCH] nvmem: core: Check input parameter for NULL in + nvmem_unregister() +Git-commit: 8c751e0d9a5264376935a84429a2d468c8877d99 +References: bsc#1204241 +Patch-mainline: v5.18-rc1 + +nvmem_unregister() frees resources and standard pattern is to allow +caller to not care if it's NULL or not. This will reduce burden on +the callers to perform this check. + +Signed-off-by: Andy Shevchenko +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20220220151527.17216-4-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/nvmem/core.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c +index 68db7d3303ac..53a43d843743 100644 +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -903,7 +903,8 @@ static void nvmem_device_release(struct kref *kref) + */ + void nvmem_unregister(struct nvmem_device *nvmem) + { +- kref_put(&nvmem->refcnt, nvmem_device_release); ++ if (nvmem) ++ kref_put(&nvmem->refcnt, nvmem_device_release); + } + EXPORT_SYMBOL_GPL(nvmem_unregister); + +-- +2.35.3 + diff --git a/patches.suse/octeontx2-pf-cn10k-Fix-egress-ratelimit-configuratio.patch b/patches.suse/octeontx2-pf-cn10k-Fix-egress-ratelimit-configuratio.patch new file mode 100644 index 0000000..f9ffca1 --- /dev/null +++ b/patches.suse/octeontx2-pf-cn10k-Fix-egress-ratelimit-configuratio.patch @@ -0,0 +1,184 @@ +From d702950fbde38e0e3a3bc85d61854eeadbe2f425 Mon Sep 17 00:00:00 2001 +From: Sunil Goutham +Date: Sun, 24 Jul 2022 13:51:13 +0530 +Subject: [PATCH 28/28] octeontx2-pf: cn10k: Fix egress ratelimit configuration +Git-commit: b354eaeec8637d87003945439209251d76a2bb95 +Patch-mainline: v5.19 +References: git-fixes + +NIX_AF_TLXX_PIR/CIR register format has changed from OcteonTx2 +to CN10K. CN10K supports larger burst size. Fix burst exponent +and burst mantissa configuration for CN10K. + +Also fixed 'maxrate' from u32 to u64 since 'police.rate_bytes_ps' +passed by stack is also u64. + +Fixes: e638a83f167e ("octeontx2-pf: TC_MATCHALL egress ratelimiting offload") +Signed-off-by: Sunil Goutham +Signed-off-by: Subbaraya Sundeep +Signed-off-by: Paolo Abeni +Signed-off-by: Denis Kirjanov +--- + .../net/ethernet/marvell/octeontx2/nic/otx2_tc.c | 76 ++++++++++++++++------ + 1 file changed, 55 insertions(+), 21 deletions(-) + +diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c +index 0593106d7161..88ffdda8a6c3 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c +@@ -28,6 +28,9 @@ + #define MAX_RATE_EXPONENT 0x0FULL + #define MAX_RATE_MANTISSA 0xFFULL + ++#define CN10K_MAX_BURST_MANTISSA 0x7FFFULL ++#define CN10K_MAX_BURST_SIZE 8453888ULL ++ + /* Bitfields in NIX_TLX_PIR register */ + #define TLX_RATE_MANTISSA GENMASK_ULL(8, 1) + #define TLX_RATE_EXPONENT GENMASK_ULL(12, 9) +@@ -35,6 +38,9 @@ + #define TLX_BURST_MANTISSA GENMASK_ULL(36, 29) + #define TLX_BURST_EXPONENT GENMASK_ULL(40, 37) + ++#define CN10K_TLX_BURST_MANTISSA GENMASK_ULL(43, 29) ++#define CN10K_TLX_BURST_EXPONENT GENMASK_ULL(47, 44) ++ + struct otx2_tc_flow_stats { + u64 bytes; + u64 pkts; +@@ -77,33 +83,42 @@ int otx2_tc_alloc_ent_bitmap(struct otx2_nic *nic) + } + EXPORT_SYMBOL(otx2_tc_alloc_ent_bitmap); + +-static void otx2_get_egress_burst_cfg(u32 burst, u32 *burst_exp, +- u32 *burst_mantissa) ++static void otx2_get_egress_burst_cfg(struct otx2_nic *nic, u32 burst, ++ u32 *burst_exp, u32 *burst_mantissa) + { ++ int max_burst, max_mantissa; + unsigned int tmp; + ++ if (is_dev_otx2(nic->pdev)) { ++ max_burst = MAX_BURST_SIZE; ++ max_mantissa = MAX_BURST_MANTISSA; ++ } else { ++ max_burst = CN10K_MAX_BURST_SIZE; ++ max_mantissa = CN10K_MAX_BURST_MANTISSA; ++ } ++ + /* Burst is calculated as + * ((256 + BURST_MANTISSA) << (1 + BURST_EXPONENT)) / 256 + * Max supported burst size is 130,816 bytes. + */ +- burst = min_t(u32, burst, MAX_BURST_SIZE); ++ burst = min_t(u32, burst, max_burst); + if (burst) { + *burst_exp = ilog2(burst) ? ilog2(burst) - 1 : 0; + tmp = burst - rounddown_pow_of_two(burst); +- if (burst < MAX_BURST_MANTISSA) ++ if (burst < max_mantissa) + *burst_mantissa = tmp * 2; + else + *burst_mantissa = tmp / (1ULL << (*burst_exp - 7)); + } else { + *burst_exp = MAX_BURST_EXPONENT; +- *burst_mantissa = MAX_BURST_MANTISSA; ++ *burst_mantissa = max_mantissa; + } + } + +-static void otx2_get_egress_rate_cfg(u32 maxrate, u32 *exp, ++static void otx2_get_egress_rate_cfg(u64 maxrate, u32 *exp, + u32 *mantissa, u32 *div_exp) + { +- unsigned int tmp; ++ u64 tmp; + + /* Rate calculation by hardware + * +@@ -132,21 +147,44 @@ static void otx2_get_egress_rate_cfg(u32 maxrate, u32 *exp, + } + } + +-static int otx2_set_matchall_egress_rate(struct otx2_nic *nic, u32 burst, u32 maxrate) ++static u64 otx2_get_txschq_rate_regval(struct otx2_nic *nic, ++ u64 maxrate, u32 burst) + { +- struct otx2_hw *hw = &nic->hw; +- struct nix_txschq_config *req; + u32 burst_exp, burst_mantissa; + u32 exp, mantissa, div_exp; ++ u64 regval = 0; ++ ++ /* Get exponent and mantissa values from the desired rate */ ++ otx2_get_egress_burst_cfg(nic, burst, &burst_exp, &burst_mantissa); ++ otx2_get_egress_rate_cfg(maxrate, &exp, &mantissa, &div_exp); ++ ++ if (is_dev_otx2(nic->pdev)) { ++ regval = FIELD_PREP(TLX_BURST_EXPONENT, (u64)burst_exp) | ++ FIELD_PREP(TLX_BURST_MANTISSA, (u64)burst_mantissa) | ++ FIELD_PREP(TLX_RATE_DIVIDER_EXPONENT, div_exp) | ++ FIELD_PREP(TLX_RATE_EXPONENT, exp) | ++ FIELD_PREP(TLX_RATE_MANTISSA, mantissa) | BIT_ULL(0); ++ } else { ++ regval = FIELD_PREP(CN10K_TLX_BURST_EXPONENT, (u64)burst_exp) | ++ FIELD_PREP(CN10K_TLX_BURST_MANTISSA, (u64)burst_mantissa) | ++ FIELD_PREP(TLX_RATE_DIVIDER_EXPONENT, div_exp) | ++ FIELD_PREP(TLX_RATE_EXPONENT, exp) | ++ FIELD_PREP(TLX_RATE_MANTISSA, mantissa) | BIT_ULL(0); ++ } ++ ++ return regval; ++} ++ ++static int otx2_set_matchall_egress_rate(struct otx2_nic *nic, ++ u32 burst, u64 maxrate) ++{ ++ struct otx2_hw *hw = &nic->hw; ++ struct nix_txschq_config *req; + int txschq, err; + + /* All SQs share the same TL4, so pick the first scheduler */ + txschq = hw->txschq_list[NIX_TXSCH_LVL_TL4][0]; + +- /* Get exponent and mantissa values from the desired rate */ +- otx2_get_egress_burst_cfg(burst, &burst_exp, &burst_mantissa); +- otx2_get_egress_rate_cfg(maxrate, &exp, &mantissa, &div_exp); +- + mutex_lock(&nic->mbox.lock); + req = otx2_mbox_alloc_msg_nix_txschq_cfg(&nic->mbox); + if (!req) { +@@ -157,11 +195,7 @@ static int otx2_set_matchall_egress_rate(struct otx2_nic *nic, u32 burst, u32 ma + req->lvl = NIX_TXSCH_LVL_TL4; + req->num_regs = 1; + req->reg[0] = NIX_AF_TL4X_PIR(txschq); +- req->regval[0] = FIELD_PREP(TLX_BURST_EXPONENT, burst_exp) | +- FIELD_PREP(TLX_BURST_MANTISSA, burst_mantissa) | +- FIELD_PREP(TLX_RATE_DIVIDER_EXPONENT, div_exp) | +- FIELD_PREP(TLX_RATE_EXPONENT, exp) | +- FIELD_PREP(TLX_RATE_MANTISSA, mantissa) | BIT_ULL(0); ++ req->regval[0] = otx2_get_txschq_rate_regval(nic, maxrate, burst); + + err = otx2_sync_mbox_msg(&nic->mbox); + mutex_unlock(&nic->mbox.lock); +@@ -196,7 +230,7 @@ static int otx2_tc_egress_matchall_install(struct otx2_nic *nic, + struct netlink_ext_ack *extack = cls->common.extack; + struct flow_action *actions = &cls->rule->action; + struct flow_action_entry *entry; +- u32 rate; ++ u64 rate; + int err; + + err = otx2_tc_validate_flow(nic, actions, extack); +@@ -218,7 +252,7 @@ static int otx2_tc_egress_matchall_install(struct otx2_nic *nic, + } + /* Convert bytes per second to Mbps */ + rate = entry->police.rate_bytes_ps * 8; +- rate = max_t(u32, rate / 1000000, 1); ++ rate = max_t(u64, rate / 1000000, 1); + err = otx2_set_matchall_egress_rate(nic, entry->police.burst, rate); + if (err) + return err; +-- +2.16.4 + diff --git a/patches.suse/of-device-Fix-up-of_dma_configure_id-stub.patch b/patches.suse/of-device-Fix-up-of_dma_configure_id-stub.patch new file mode 100644 index 0000000..e5791b3 --- /dev/null +++ b/patches.suse/of-device-Fix-up-of_dma_configure_id-stub.patch @@ -0,0 +1,45 @@ +From 40bfe7a86d84cf08ac6a8fe2f0c8bf7a43edd110 Mon Sep 17 00:00:00 2001 +From: Thierry Reding +Date: Wed, 24 Aug 2022 17:32:56 +0200 +Subject: [PATCH] of/device: Fix up of_dma_configure_id() stub +Git-commit: 40bfe7a86d84cf08ac6a8fe2f0c8bf7a43edd110 +Patch-mainline: v6.0-rc6 +References: git-fixes + +Since the stub version of of_dma_configure_id() was added in commit +a081bd4af4ce ("of/device: Add input id to of_dma_configure()"), it has +not matched the signature of the full function, leading to build failure +reports when code using this function is built on !OF configurations. + +Fixes: a081bd4af4ce ("of/device: Add input id to of_dma_configure()") +Cc: stable@vger.kernel.org +Signed-off-by: Thierry Reding +Reviewed-by: Frank Rowand +Acked-by: Lorenzo Pieralisi +Link: https://lore.kernel.org/r/20220824153256.1437483-1-thierry.reding@gmail.com +Signed-off-by: Rob Herring +Acked-by: Takashi Iwai + +--- + include/linux/of_device.h | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/include/linux/of_device.h b/include/linux/of_device.h +index 1d7992a02e36..1a803e4335d3 100644 +--- a/include/linux/of_device.h ++++ b/include/linux/of_device.h +@@ -101,8 +101,9 @@ static inline struct device_node *of_cpu_device_node_get(int cpu) + } + + static inline int of_dma_configure_id(struct device *dev, +- struct device_node *np, +- bool force_dma) ++ struct device_node *np, ++ bool force_dma, ++ const u32 *id) + { + return 0; + } +-- +2.35.3 + diff --git a/patches.suse/of-fdt-fix-off-by-one-error-in-unflatten_dt_nodes.patch b/patches.suse/of-fdt-fix-off-by-one-error-in-unflatten_dt_nodes.patch new file mode 100644 index 0000000..786d0bf --- /dev/null +++ b/patches.suse/of-fdt-fix-off-by-one-error-in-unflatten_dt_nodes.patch @@ -0,0 +1,41 @@ +From 2f945a792f67815abca26fa8a5e863ccf3fa1181 Mon Sep 17 00:00:00 2001 +From: Sergey Shtylyov +Date: Sat, 13 Aug 2022 23:34:16 +0300 +Subject: [PATCH] of: fdt: fix off-by-one error in unflatten_dt_nodes() +Git-commit: 2f945a792f67815abca26fa8a5e863ccf3fa1181 +Patch-mainline: v6.0-rc6 +References: git-fixes + +Commit 78c44d910d3e ("drivers/of: Fix depth when unflattening devicetree") +forgot to fix up the depth check in the loop body in unflatten_dt_nodes() +which makes it possible to overflow the nps[] buffer... + +Found by Linux Verification Center (linuxtesting.org) with the SVACE static +analysis tool. + +Fixes: 78c44d910d3e ("drivers/of: Fix depth when unflattening devicetree") +Signed-off-by: Sergey Shtylyov +Signed-off-by: Rob Herring +Link: https://lore.kernel.org/r/7c354554-006f-6b31-c195-cdfe4caee392@omp.ru +Acked-by: Takashi Iwai + +--- + drivers/of/fdt.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c +index 7bc92923104c..1c573e7a60bc 100644 +--- a/drivers/of/fdt.c ++++ b/drivers/of/fdt.c +@@ -314,7 +314,7 @@ static int unflatten_dt_nodes(const void *blob, + for (offset = 0; + offset >= 0 && depth >= initial_depth; + offset = fdt_next_node(blob, offset, &depth)) { +- if (WARN_ON_ONCE(depth >= FDT_MAX_DEPTH)) ++ if (WARN_ON_ONCE(depth >= FDT_MAX_DEPTH - 1)) + continue; + + if (!IS_ENABLED(CONFIG_OF_KOBJ) && +-- +2.35.3 + diff --git a/patches.suse/openvswitch-add-nf_ct_is_confirmed-check-before-assi.patch b/patches.suse/openvswitch-add-nf_ct_is_confirmed-check-before-assi.patch new file mode 100644 index 0000000..401d4c1 --- /dev/null +++ b/patches.suse/openvswitch-add-nf_ct_is_confirmed-check-before-assi.patch @@ -0,0 +1,67 @@ +From 3c1860543fccc1d0cfe3fd6b190e414a418fe60e Mon Sep 17 00:00:00 2001 +From: Xin Long +Date: Thu, 6 Oct 2022 15:45:02 -0400 +Subject: [PATCH] openvswitch: add nf_ct_is_confirmed check before assigning the helper +Git-commit: 3c1860543fccc1d0cfe3fd6b190e414a418fe60e +Patch-mainline: v6.1-rc1 +References: git-fixes + +A WARN_ON call trace would be triggered when 'ct(commit, alg=helper)' +applies on a confirmed connection: + + WARNING: CPU: 0 PID: 1251 at net/netfilter/nf_conntrack_extend.c:98 + RIP: 0010:nf_ct_ext_add+0x12d/0x150 [nf_conntrack] + Call Trace: + + nf_ct_helper_ext_add+0x12/0x60 [nf_conntrack] + __nf_ct_try_assign_helper+0xc4/0x160 [nf_conntrack] + __ovs_ct_lookup+0x72e/0x780 [openvswitch] + ovs_ct_execute+0x1d8/0x920 [openvswitch] + do_execute_actions+0x4e6/0xb60 [openvswitch] + ovs_execute_actions+0x60/0x140 [openvswitch] + ovs_packet_cmd_execute+0x2ad/0x310 [openvswitch] + genl_family_rcv_msg_doit.isra.15+0x113/0x150 + genl_rcv_msg+0xef/0x1f0 + +which can be reproduced with these OVS flows: + + table=0, in_port=veth1,tcp,tcp_dst=2121,ct_state=-trk + actions=ct(commit, table=1) + table=1, in_port=veth1,tcp,tcp_dst=2121,ct_state=+trk+new + actions=ct(commit, alg=ftp),normal + +The issue was introduced by commit 248d45f1e193 ("openvswitch: Allow +attaching helper in later commit") where it somehow removed the check +of nf_ct_is_confirmed before asigning the helper. This patch is to fix +it by bringing it back. + +Fixes: 248d45f1e193 ("openvswitch: Allow attaching helper in later commit") +Reported-by: Pablo Neira Ayuso +Signed-off-by: Xin Long +Acked-by: Aaron Conole +Tested-by: Aaron Conole +Link: https://lore.kernel.org/r/c5c9092a22a2194650222bffaf786902613deb16.1665085502.git.lucien.xin@gmail.com +Signed-off-by: Jakub Kicinski +Acked-by: Takashi Iwai + +--- + net/openvswitch/conntrack.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c +index cb255d8ed99a..c7b10234cf7c 100644 +--- a/net/openvswitch/conntrack.c ++++ b/net/openvswitch/conntrack.c +@@ -1015,7 +1015,8 @@ static int __ovs_ct_lookup(struct net *net, struct sw_flow_key *key, + * connections which we will commit, we may need to attach + * the helper here. + */ +- if (info->commit && info->helper && !nfct_help(ct)) { ++ if (!nf_ct_is_confirmed(ct) && info->commit && ++ info->helper && !nfct_help(ct)) { + int err = __nf_ct_try_assign_helper(ct, info->ct, + GFP_ATOMIC); + if (err) +-- +2.35.3 + diff --git a/patches.suse/pNFS-flexfiles-Report-RDMA-connection-errors-to-the-.patch b/patches.suse/pNFS-flexfiles-Report-RDMA-connection-errors-to-the-.patch new file mode 100644 index 0000000..241b596 --- /dev/null +++ b/patches.suse/pNFS-flexfiles-Report-RDMA-connection-errors-to-the-.patch @@ -0,0 +1,41 @@ +From: Trond Myklebust +Date: Wed, 18 May 2022 16:09:06 -0400 +Subject: [PATCH] pNFS/flexfiles: Report RDMA connection errors to the server +Git-commit: 7836d75467e9d214bdf5c693b32721de729a6e38 +Patch-mainline: v6.0 +References: git-fixes + +The RPC/RDMA driver will return -EPROTO and -ENODEV as connection errors +under certain circumstances. Make sure that we handle them and report +them to the server. If not, we can end up cycling forever in a +LAYOUTGET/LAYOUTRETURN loop. + +Fixes: a12f996d3413 ("NFSv4/pNFS: Use connections to a DS that are all of the same protocol family") +Cc: stable@vger.kernel.org # 5.11.x +Signed-off-by: Trond Myklebust +Acked-by: NeilBrown + +--- + fs/nfs/flexfilelayout/flexfilelayout.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/fs/nfs/flexfilelayout/flexfilelayout.c ++++ b/fs/nfs/flexfilelayout/flexfilelayout.c +@@ -1140,6 +1140,8 @@ static int ff_layout_async_handle_error_ + case -EIO: + case -ETIMEDOUT: + case -EPIPE: ++ case -EPROTO: ++ case -ENODEV: + dprintk("%s DS connection error %d\n", __func__, + task->tk_status); + nfs4_delete_deviceid(devid->ld, devid->nfs_client, +@@ -1245,6 +1247,8 @@ static void ff_layout_io_track_ds_error( + case -ENOBUFS: + case -EPIPE: + case -EPERM: ++ case -EPROTO: ++ case -ENODEV: + *op_status = status = NFS4ERR_NXIO; + break; + case -EACCES: diff --git a/patches.suse/phy-amlogic-phy-meson-axg-mipi-pcie-analog-Hold-refe.patch b/patches.suse/phy-amlogic-phy-meson-axg-mipi-pcie-analog-Hold-refe.patch new file mode 100644 index 0000000..8a3968a --- /dev/null +++ b/patches.suse/phy-amlogic-phy-meson-axg-mipi-pcie-analog-Hold-refe.patch @@ -0,0 +1,50 @@ +From c4c349be07aeec5f397a349046dc5fc0f2657691 Mon Sep 17 00:00:00 2001 +From: Liang He +Date: Thu, 15 Sep 2022 17:35:06 +0800 +Subject: [PATCH] phy: amlogic: phy-meson-axg-mipi-pcie-analog: Hold reference returned by of_get_parent() +Git-commit: c4c349be07aeec5f397a349046dc5fc0f2657691 +Patch-mainline: v6.1-rc1 +References: git-fixes + +As the of_get_parent() will increase the refcount of the node->parent +and the reference will be discarded, so we should hold the reference +with which we can decrease the refcount when done. + +Fixes: 8eff8b4e22d9 ("phy: amlogic: phy-meson-axg-mipi-pcie-analog: add support for MIPI DSI analog") +Signed-off-by: Liang He + +Link: https://lore.kernel.org/r/20220915093506.4009456-1-windhl@126.com +Signed-off-by: Vinod Koul +Acked-by: Takashi Iwai + +--- + drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c b/drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c +index 1027ece6ca12..a3e1108b736d 100644 +--- a/drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c ++++ b/drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c +@@ -197,7 +197,7 @@ static int phy_axg_mipi_pcie_analog_probe(struct platform_device *pdev) + struct phy_provider *phy; + struct device *dev = &pdev->dev; + struct phy_axg_mipi_pcie_analog_priv *priv; +- struct device_node *np = dev->of_node; ++ struct device_node *np = dev->of_node, *parent_np; + struct regmap *map; + int ret; + +@@ -206,7 +206,9 @@ static int phy_axg_mipi_pcie_analog_probe(struct platform_device *pdev) + return -ENOMEM; + + /* Get the hhi system controller node */ +- map = syscon_node_to_regmap(of_get_parent(dev->of_node)); ++ parent_np = of_get_parent(dev->of_node); ++ map = syscon_node_to_regmap(parent_np); ++ of_node_put(parent_np); + if (IS_ERR(map)) { + dev_err(dev, + "failed to get HHI regmap\n"); +-- +2.35.3 + diff --git a/patches.suse/phy-qualcomm-call-clk_disable_unprepare-in-the-error.patch b/patches.suse/phy-qualcomm-call-clk_disable_unprepare-in-the-error.patch new file mode 100644 index 0000000..8aa6a1f --- /dev/null +++ b/patches.suse/phy-qualcomm-call-clk_disable_unprepare-in-the-error.patch @@ -0,0 +1,53 @@ +From c3966ced8eb8dc53b6c8d7f97d32cc8a2107d83e Mon Sep 17 00:00:00 2001 +From: Dongliang Mu +Date: Wed, 14 Sep 2022 13:13:33 +0800 +Subject: [PATCH] phy: qualcomm: call clk_disable_unprepare in the error handling +Git-commit: c3966ced8eb8dc53b6c8d7f97d32cc8a2107d83e +Patch-mainline: v6.1-rc1 +References: git-fixes + +Smatch reports the following error: + +drivers/phy/qualcomm/phy-qcom-usb-hsic.c:82 qcom_usb_hsic_phy_power_on() +Warn: 'uphy->cal_clk' from clk_prepare_enable() not released on lines: +58. +drivers/phy/qualcomm/phy-qcom-usb-hsic.c:82 qcom_usb_hsic_phy_power_on() +Warn: 'uphy->cal_sleep_clk' from clk_prepare_enable() not released on +Lines: 58. +drivers/phy/qualcomm/phy-qcom-usb-hsic.c:82 qcom_usb_hsic_phy_power_on() +Warn: 'uphy->phy_clk' from clk_prepare_enable() not released on lines: +58. + +Fix this by calling proper clk_disable_unprepare calls. + +Fixes: 0b56e9a7e835 ("phy: Group vendor specific phy drivers") +Signed-off-by: Dongliang Mu +Reviewed-by: Neil Armstrong +Link: https://lore.kernel.org/r/20220914051334.69282-1-dzm91@hust.edu.cn +Signed-off-by: Vinod Koul +Acked-by: Takashi Iwai + +--- + drivers/phy/qualcomm/phy-qcom-usb-hsic.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/phy/qualcomm/phy-qcom-usb-hsic.c b/drivers/phy/qualcomm/phy-qcom-usb-hsic.c +index 716a77748ed8..20f6dd37c7c1 100644 +--- a/drivers/phy/qualcomm/phy-qcom-usb-hsic.c ++++ b/drivers/phy/qualcomm/phy-qcom-usb-hsic.c +@@ -54,8 +54,10 @@ static int qcom_usb_hsic_phy_power_on(struct phy *phy) + + /* Configure pins for HSIC functionality */ + pins_default = pinctrl_lookup_state(uphy->pctl, PINCTRL_STATE_DEFAULT); +- if (IS_ERR(pins_default)) +- return PTR_ERR(pins_default); ++ if (IS_ERR(pins_default)) { ++ ret = PTR_ERR(pins_default); ++ goto err_ulpi; ++ } + + ret = pinctrl_select_state(uphy->pctl, pins_default); + if (ret) +-- +2.35.3 + diff --git a/patches.suse/pinctrl-alderlake-Add-Intel-Alder-Lake-N-pin-control.patch b/patches.suse/pinctrl-alderlake-Add-Intel-Alder-Lake-N-pin-control.patch new file mode 100644 index 0000000..c0ef2ae --- /dev/null +++ b/patches.suse/pinctrl-alderlake-Add-Intel-Alder-Lake-N-pin-control.patch @@ -0,0 +1,364 @@ +From 114b610b9048c6a622c857e044ff105cbc46fab1 Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Tue, 15 Feb 2022 17:27:59 +0200 +Subject: [PATCH] pinctrl: alderlake: Add Intel Alder Lake-N pin controller support +Git-commit: 114b610b9048c6a622c857e044ff105cbc46fab1 +Patch-mainline: v5.18-rc1 +References: jsc#PED-676 + +This change driver adds pinctrl/GPIO support for Intel Alder Lake-N SoC. The +GPIO controller is based on the next generation GPIO hardware but still +compatible with the one supported by the Intel core pinctrl/GPIO driver. + +Signed-off-by: Andy Shevchenko +Acked-by: Mika Westerberg +Acked-by: Takashi Iwai + +--- + drivers/pinctrl/intel/pinctrl-alderlake.c | 316 +++++++++++++++++++++- + 1 file changed, 315 insertions(+), 1 deletion(-) + +diff --git a/drivers/pinctrl/intel/pinctrl-alderlake.c b/drivers/pinctrl/intel/pinctrl-alderlake.c +index 51fb99cd64a2..32ba50efbceb 100644 +--- a/drivers/pinctrl/intel/pinctrl-alderlake.c ++++ b/drivers/pinctrl/intel/pinctrl-alderlake.c +@@ -2,7 +2,7 @@ + /* + * Intel Alder Lake PCH pinctrl/GPIO driver + * +- * Copyright (C) 2020, Intel Corporation ++ * Copyright (C) 2020, 2022 Intel Corporation + * Author: Andy Shevchenko + */ + +@@ -42,6 +42,319 @@ + .ngpps = ARRAY_SIZE(g), \ + } + ++/* Alder Lake-N */ ++static const struct pinctrl_pin_desc adln_pins[] = { ++ /* GPP_B */ ++ PINCTRL_PIN(0, "CORE_VID_0"), ++ PINCTRL_PIN(1, "CORE_VID_1"), ++ PINCTRL_PIN(2, "GPPC_B_2"), ++ PINCTRL_PIN(3, "GPPC_B_3"), ++ PINCTRL_PIN(4, "GPPC_B_4"), ++ PINCTRL_PIN(5, "GPPC_B_5"), ++ PINCTRL_PIN(6, "GPPC_B_6"), ++ PINCTRL_PIN(7, "GPPC_B_7"), ++ PINCTRL_PIN(8, "GPPC_B_8"), ++ PINCTRL_PIN(9, "GPPC_B_9"), ++ PINCTRL_PIN(10, "GPPC_B_10"), ++ PINCTRL_PIN(11, "GPPC_B_11"), ++ PINCTRL_PIN(12, "SLP_S0B"), ++ PINCTRL_PIN(13, "PLTRSTB"), ++ PINCTRL_PIN(14, "GPPC_B_14"), ++ PINCTRL_PIN(15, "GPPC_B_15"), ++ PINCTRL_PIN(16, "GPPC_B_16"), ++ PINCTRL_PIN(17, "GPPC_B_17"), ++ PINCTRL_PIN(18, "GPPC_B_18"), ++ PINCTRL_PIN(19, "GPPC_B_19"), ++ PINCTRL_PIN(20, "GPPC_B_20"), ++ PINCTRL_PIN(21, "GPPC_B_21"), ++ PINCTRL_PIN(22, "GPPC_B_22"), ++ PINCTRL_PIN(23, "GPPC_B_23"), ++ PINCTRL_PIN(24, "GSPI0_CLK_LOOPBK"), ++ PINCTRL_PIN(25, "GSPI1_CLK_LOOPBK"), ++ /* GPP_T */ ++ PINCTRL_PIN(26, "GPPC_T_0"), ++ PINCTRL_PIN(27, "GPPC_T_1"), ++ PINCTRL_PIN(28, "FUSA_DIAGTEST_EN"), ++ PINCTRL_PIN(29, "FUSA_DIAGTEST_MODE"), ++ PINCTRL_PIN(30, "GPPC_T_4"), ++ PINCTRL_PIN(31, "GPPC_T_5"), ++ PINCTRL_PIN(32, "GPPC_T_6"), ++ PINCTRL_PIN(33, "GPPC_T_7"), ++ PINCTRL_PIN(34, "GPPC_T_8"), ++ PINCTRL_PIN(35, "GPPC_T_9"), ++ PINCTRL_PIN(36, "GPPC_T_10"), ++ PINCTRL_PIN(37, "GPPC_T_11"), ++ PINCTRL_PIN(38, "GPPC_T_12"), ++ PINCTRL_PIN(39, "GPPC_T_13"), ++ PINCTRL_PIN(40, "GPPC_T_14"), ++ PINCTRL_PIN(41, "GPPC_T_15"), ++ /* GPP_A */ ++ PINCTRL_PIN(42, "ESPI_IO_0"), ++ PINCTRL_PIN(43, "ESPI_IO_1"), ++ PINCTRL_PIN(44, "ESPI_IO_2"), ++ PINCTRL_PIN(45, "ESPI_IO_3"), ++ PINCTRL_PIN(46, "ESPI_CS0B"), ++ PINCTRL_PIN(47, "ESPI_ALERT0B"), ++ PINCTRL_PIN(48, "ESPI_ALERT1B"), ++ PINCTRL_PIN(49, "GPPC_A_7"), ++ PINCTRL_PIN(50, "GPPC_A_8"), ++ PINCTRL_PIN(51, "ESPI_CLK"), ++ PINCTRL_PIN(52, "ESPI_RESETB"), ++ PINCTRL_PIN(53, "GPPC_A_11"), ++ PINCTRL_PIN(54, "GPPC_A_12"), ++ PINCTRL_PIN(55, "GPPC_A_13"), ++ PINCTRL_PIN(56, "GPPC_A_14"), ++ PINCTRL_PIN(57, "GPPC_A_15"), ++ PINCTRL_PIN(58, "GPPC_A_16"), ++ PINCTRL_PIN(59, "GPPC_A_17"), ++ PINCTRL_PIN(60, "GPPC_A_18"), ++ PINCTRL_PIN(61, "GPPC_A_19"), ++ PINCTRL_PIN(62, "GPPC_A_20"), ++ PINCTRL_PIN(63, "GPPC_A_21"), ++ PINCTRL_PIN(64, "GPPC_A_22"), ++ PINCTRL_PIN(65, "ESPI_CS1B"), ++ PINCTRL_PIN(66, "ESPI_CLK_LOOPBK"), ++ /* GPP_S */ ++ PINCTRL_PIN(67, "GPP_S_0"), ++ PINCTRL_PIN(68, "GPP_S_1"), ++ PINCTRL_PIN(69, "GPP_S_2"), ++ PINCTRL_PIN(70, "GPP_S_3"), ++ PINCTRL_PIN(71, "GPP_S_4"), ++ PINCTRL_PIN(72, "GPP_S_5"), ++ PINCTRL_PIN(73, "GPP_S_6"), ++ PINCTRL_PIN(74, "GPP_S_7"), ++ /* GPP_I */ ++ PINCTRL_PIN(75, "GPP_F_0_CNV_BRI_DT_UART0_RTSB"), ++ PINCTRL_PIN(76, "GPP_F_1_CNV_BRI_RSP_UART0_RXD"), ++ PINCTRL_PIN(77, "GPP_F_2_CNV_RGI_DT_UART0_TXD"), ++ PINCTRL_PIN(78, "GPP_F_3_CNV_RGI_RSP_UART0_CTSB"), ++ PINCTRL_PIN(79, "GPP_F_4_CNV_RF_RESET_B"), ++ PINCTRL_PIN(80, "GPP_F_5_MODEM_CLKREQ"), ++ PINCTRL_PIN(81, "GPP_F_6_CNV_PA_BLANKING"), ++ PINCTRL_PIN(82, "GPP_F_7_EMMC_CMD"), ++ PINCTRL_PIN(83, "GPP_F_8_EMMC_DATA0"), ++ PINCTRL_PIN(84, "GPP_F_9_EMMC_DATA1"), ++ PINCTRL_PIN(85, "GPP_F_10_EMMC_DATA2"), ++ PINCTRL_PIN(86, "GPP_F_11_EMMC_DATA3"), ++ PINCTRL_PIN(87, "GPP_F_12_EMMC_DATA4"), ++ PINCTRL_PIN(88, "GPP_F_13_EMMC_DATA5"), ++ PINCTRL_PIN(89, "GPP_F_14_EMMC_DATA6"), ++ PINCTRL_PIN(90, "GPP_F_15_EMMC_DATA7"), ++ PINCTRL_PIN(91, "GPP_F_16_EMMC_RCLK"), ++ PINCTRL_PIN(92, "GPP_F_17_EMMC_CLK"), ++ PINCTRL_PIN(93, "GPP_F_18_EMMC_RESETB"), ++ PINCTRL_PIN(94, "GPP_F_19_A4WP_PRESENT"), ++ /* GPP_H */ ++ PINCTRL_PIN(95, "GPPC_H_0"), ++ PINCTRL_PIN(96, "GPPC_H_1"), ++ PINCTRL_PIN(97, "GPPC_H_2"), ++ PINCTRL_PIN(98, "GPPC_H_3"), ++ PINCTRL_PIN(99, "GPPC_H_4"), ++ PINCTRL_PIN(100, "GPPC_H_5"), ++ PINCTRL_PIN(101, "GPPC_H_6"), ++ PINCTRL_PIN(102, "GPPC_H_7"), ++ PINCTRL_PIN(103, "GPPC_H_8"), ++ PINCTRL_PIN(104, "GPPC_H_9"), ++ PINCTRL_PIN(105, "GPPC_H_10"), ++ PINCTRL_PIN(106, "GPPC_H_11"), ++ PINCTRL_PIN(107, "I2C7_SDA"), ++ PINCTRL_PIN(108, "I2C7_SCL"), ++ PINCTRL_PIN(109, "GPPC_H_14"), ++ PINCTRL_PIN(110, "GPPC_H_15"), ++ PINCTRL_PIN(111, "GPPC_H_16"), ++ PINCTRL_PIN(112, "GPPC_H_17"), ++ PINCTRL_PIN(113, "CPU_C10_GATEB"), ++ PINCTRL_PIN(114, "GPPC_H_19"), ++ PINCTRL_PIN(115, "GPPC_H_20"), ++ PINCTRL_PIN(116, "GPPC_H_21"), ++ PINCTRL_PIN(117, "GPPC_H_22"), ++ PINCTRL_PIN(118, "GPPC_H_23"), ++ /* GPP_D */ ++ PINCTRL_PIN(119, "GPPC_D_0"), ++ PINCTRL_PIN(120, "GPPC_D_1"), ++ PINCTRL_PIN(121, "GPPC_D_2"), ++ PINCTRL_PIN(122, "GPPC_D_3"), ++ PINCTRL_PIN(123, "GPPC_D_4"), ++ PINCTRL_PIN(124, "GPPC_D_5"), ++ PINCTRL_PIN(125, "GPPC_D_6"), ++ PINCTRL_PIN(126, "GPPC_D_7"), ++ PINCTRL_PIN(127, "GPPC_D_8"), ++ PINCTRL_PIN(128, "BSSB_LS2_RX"), ++ PINCTRL_PIN(129, "BSSB_LS2_TX"), ++ PINCTRL_PIN(130, "BSSB_LS3_RX"), ++ PINCTRL_PIN(131, "BSSB_LS3_TX"), ++ PINCTRL_PIN(132, "GPPC_D_13"), ++ PINCTRL_PIN(133, "GPPC_D_14"), ++ PINCTRL_PIN(134, "GPPC_D_15"), ++ PINCTRL_PIN(135, "GPPC_D_16"), ++ PINCTRL_PIN(136, "GPPC_D_17"), ++ PINCTRL_PIN(137, "GPPC_D_18"), ++ PINCTRL_PIN(138, "GPPC_D_19"), ++ PINCTRL_PIN(139, "GSPI2_CLK_LOOPBK"), ++ /* vGPIO */ ++ PINCTRL_PIN(140, "CNV_BTEN"), ++ PINCTRL_PIN(141, "CNV_BT_HOST_WAKEB"), ++ PINCTRL_PIN(142, "CNV_BT_IF_SELECT"), ++ PINCTRL_PIN(143, "vCNV_BT_UART_TXD"), ++ PINCTRL_PIN(144, "vCNV_BT_UART_RXD"), ++ PINCTRL_PIN(145, "vCNV_BT_UART_CTS_B"), ++ PINCTRL_PIN(146, "vCNV_BT_UART_RTS_B"), ++ PINCTRL_PIN(147, "vCNV_MFUART1_TXD"), ++ PINCTRL_PIN(148, "vCNV_MFUART1_RXD"), ++ PINCTRL_PIN(149, "vCNV_MFUART1_CTS_B"), ++ PINCTRL_PIN(150, "vCNV_MFUART1_RTS_B"), ++ PINCTRL_PIN(151, "vUART0_TXD"), ++ PINCTRL_PIN(152, "vUART0_RXD"), ++ PINCTRL_PIN(153, "vUART0_CTS_B"), ++ PINCTRL_PIN(154, "vUART0_RTS_B"), ++ PINCTRL_PIN(155, "vISH_UART0_TXD"), ++ PINCTRL_PIN(156, "vISH_UART0_RXD"), ++ PINCTRL_PIN(157, "vISH_UART0_CTS_B"), ++ PINCTRL_PIN(158, "vISH_UART0_RTS_B"), ++ PINCTRL_PIN(159, "vCNV_BT_I2S_BCLK"), ++ PINCTRL_PIN(160, "vCNV_BT_I2S_WS_SYNC"), ++ PINCTRL_PIN(161, "vCNV_BT_I2S_SDO"), ++ PINCTRL_PIN(162, "vCNV_BT_I2S_SDI"), ++ PINCTRL_PIN(163, "vI2S2_SCLK"), ++ PINCTRL_PIN(164, "vI2S2_SFRM"), ++ PINCTRL_PIN(165, "vI2S2_TXD"), ++ PINCTRL_PIN(166, "vI2S2_RXD"), ++ PINCTRL_PIN(167, "THC0_WOT_INT"), ++ PINCTRL_PIN(168, "THC1_WOT_INT"), ++ /* GPP_C */ ++ PINCTRL_PIN(169, "SMBCLK"), ++ PINCTRL_PIN(170, "SMBDATA"), ++ PINCTRL_PIN(171, "SMBALERTB"), ++ PINCTRL_PIN(172, "SML0CLK"), ++ PINCTRL_PIN(173, "SML0DATA"), ++ PINCTRL_PIN(174, "GPPC_C_5"), ++ PINCTRL_PIN(175, "GPPC_C_6"), ++ PINCTRL_PIN(176, "GPPC_C_7"), ++ PINCTRL_PIN(177, "GPPC_C_8"), ++ PINCTRL_PIN(178, "GPPC_C_9"), ++ PINCTRL_PIN(179, "GPPC_C_10"), ++ PINCTRL_PIN(180, "GPPC_C_11"), ++ PINCTRL_PIN(181, "GPPC_C_12"), ++ PINCTRL_PIN(182, "GPPC_C_13"), ++ PINCTRL_PIN(183, "GPPC_C_14"), ++ PINCTRL_PIN(184, "GPPC_C_15"), ++ PINCTRL_PIN(185, "GPPC_C_16"), ++ PINCTRL_PIN(186, "GPPC_C_17"), ++ PINCTRL_PIN(187, "GPPC_C_18"), ++ PINCTRL_PIN(188, "GPPC_C_19"), ++ PINCTRL_PIN(189, "GPPC_C_20"), ++ PINCTRL_PIN(190, "GPPC_C_21"), ++ PINCTRL_PIN(191, "GPPC_C_22"), ++ PINCTRL_PIN(192, "GPPC_C_23"), ++ /* GPP_F */ ++ PINCTRL_PIN(193, "CNV_BRI_DT"), ++ PINCTRL_PIN(194, "CNV_BRI_RSP"), ++ PINCTRL_PIN(195, "CNV_RGI_DT"), ++ PINCTRL_PIN(196, "CNV_RGI_RSP"), ++ PINCTRL_PIN(197, "CNV_RF_RESET_B"), ++ PINCTRL_PIN(198, "MODEM_CLKREQ"), ++ PINCTRL_PIN(199, "GPPC_F_6"), ++ PINCTRL_PIN(200, "GPPC_F_7"), ++ PINCTRL_PIN(201, "GPPC_F_8"), ++ PINCTRL_PIN(202, "BOOTMPC"), ++ PINCTRL_PIN(203, "GPPC_F_10"), ++ PINCTRL_PIN(204, "GPPC_F_11"), ++ PINCTRL_PIN(205, "GPPC_F_12"), ++ PINCTRL_PIN(206, "GPPC_F_13"), ++ PINCTRL_PIN(207, "GPPC_F_14"), ++ PINCTRL_PIN(208, "GPPC_F_15"), ++ PINCTRL_PIN(209, "GPPC_F_16"), ++ PINCTRL_PIN(210, "GPPC_F_17"), ++ PINCTRL_PIN(211, "GPPC_F_18"), ++ PINCTRL_PIN(212, "GPPC_F_19"), ++ PINCTRL_PIN(213, "EXT_PWR_GATEB"), ++ PINCTRL_PIN(214, "EXT_PWR_GATE2B"), ++ PINCTRL_PIN(215, "GPPC_F_22"), ++ PINCTRL_PIN(216, "GPPC_F_23"), ++ PINCTRL_PIN(217, "GPPF_CLK_LOOPBACK"), ++ /* HVCMOS */ ++ PINCTRL_PIN(218, "L_BKLTEN"), ++ PINCTRL_PIN(219, "L_BKLTCTL"), ++ PINCTRL_PIN(220, "L_VDDEN"), ++ PINCTRL_PIN(221, "SYS_PWROK"), ++ PINCTRL_PIN(222, "SYS_RESETB"), ++ PINCTRL_PIN(223, "MLK_RSTB"), ++ /* GPP_E */ ++ PINCTRL_PIN(224, "GPPC_E_0"), ++ PINCTRL_PIN(225, "GPPC_E_1"), ++ PINCTRL_PIN(226, "GPPC_E_2"), ++ PINCTRL_PIN(227, "GPPC_E_3"), ++ PINCTRL_PIN(228, "GPPC_E_4"), ++ PINCTRL_PIN(229, "GPPC_E_5"), ++ PINCTRL_PIN(230, "GPPC_E_6"), ++ PINCTRL_PIN(231, "GPPC_E_7"), ++ PINCTRL_PIN(232, "GPPC_E_8"), ++ PINCTRL_PIN(233, "GPPC_E_9"), ++ PINCTRL_PIN(234, "GPPC_E_10"), ++ PINCTRL_PIN(235, "GPPC_E_11"), ++ PINCTRL_PIN(236, "GPPC_E_12"), ++ PINCTRL_PIN(237, "GPPC_E_13"), ++ PINCTRL_PIN(238, "GPPC_E_14"), ++ PINCTRL_PIN(239, "FIVR_DIGPB_0"), ++ PINCTRL_PIN(240, "FIVR_DIGPB_1"), ++ PINCTRL_PIN(241, "GPPC_E_17"), ++ PINCTRL_PIN(242, "BSSB_LS0_RX"), ++ PINCTRL_PIN(243, "BSSB_LS0_TX"), ++ PINCTRL_PIN(244, "BSSB_LS1_RX"), ++ PINCTRL_PIN(245, "BSSB_LS1_TX"), ++ PINCTRL_PIN(246, "DNX_FORCE_RELOAD"), ++ PINCTRL_PIN(247, "GPPC_E_23"), ++ PINCTRL_PIN(248, "GPPE_CLK_LOOPBACK"), ++ /* GPP_R */ ++ PINCTRL_PIN(249, "HDA_BCLK"), ++ PINCTRL_PIN(250, "HDA_SYNC"), ++ PINCTRL_PIN(251, "HDA_SDO"), ++ PINCTRL_PIN(252, "HDA_SDI_0"), ++ PINCTRL_PIN(253, "HDA_RSTB"), ++ PINCTRL_PIN(254, "GPP_R_5"), ++ PINCTRL_PIN(255, "GPP_R_6"), ++ PINCTRL_PIN(256, "GPP_R_7"), ++}; ++ ++static const struct intel_padgroup adln_community0_gpps[] = { ++ ADL_GPP(0, 0, 25, 0), /* GPP_B */ ++ ADL_GPP(1, 26, 41, 32), /* GPP_T */ ++ ADL_GPP(2, 42, 66, 64), /* GPP_A */ ++}; ++ ++static const struct intel_padgroup adln_community1_gpps[] = { ++ ADL_GPP(0, 67, 74, 96), /* GPP_S */ ++ ADL_GPP(1, 75, 94, 128), /* GPP_I */ ++ ADL_GPP(2, 95, 118, 160), /* GPP_H */ ++ ADL_GPP(3, 119, 139, 192), /* GPP_D */ ++ ADL_GPP(4, 140, 168, 224), /* vGPIO */ ++}; ++ ++static const struct intel_padgroup adln_community4_gpps[] = { ++ ADL_GPP(0, 169, 192, 256), /* GPP_C */ ++ ADL_GPP(1, 193, 217, 288), /* GPP_F */ ++ ADL_GPP(2, 218, 223, INTEL_GPIO_BASE_NOMAP), /* HVCMOS */ ++ ADL_GPP(3, 224, 248, 320), /* GPP_E */ ++}; ++ ++static const struct intel_padgroup adln_community5_gpps[] = { ++ ADL_GPP(0, 249, 256, 352), /* GPP_R */ ++}; ++ ++static const struct intel_community adln_communities[] = { ++ ADL_COMMUNITY(0, 0, 66, adln_community0_gpps), ++ ADL_COMMUNITY(1, 67, 168, adln_community1_gpps), ++ ADL_COMMUNITY(2, 169, 248, adln_community4_gpps), ++ ADL_COMMUNITY(3, 249, 256, adln_community5_gpps), ++}; ++ ++static const struct intel_pinctrl_soc_data adln_soc_data = { ++ .pins = adln_pins, ++ .npins = ARRAY_SIZE(adln_pins), ++ .communities = adln_communities, ++ .ncommunities = ARRAY_SIZE(adln_communities), ++}; ++ + /* Alder Lake-S */ + static const struct pinctrl_pin_desc adls_pins[] = { + /* GPP_I */ +@@ -416,6 +729,7 @@ static const struct intel_pinctrl_soc_data adls_soc_data = { + + static const struct acpi_device_id adl_pinctrl_acpi_match[] = { + { "INTC1056", (kernel_ulong_t)&adls_soc_data }, ++ { "INTC1057", (kernel_ulong_t)&adln_soc_data }, + { "INTC1085", (kernel_ulong_t)&adls_soc_data }, + { } + }; +-- +2.35.3 + diff --git a/patches.suse/pinctrl-alderlake-Add-Raptor-Lake-S-ACPI-ID.patch b/patches.suse/pinctrl-alderlake-Add-Raptor-Lake-S-ACPI-ID.patch new file mode 100644 index 0000000..3386fee --- /dev/null +++ b/patches.suse/pinctrl-alderlake-Add-Raptor-Lake-S-ACPI-ID.patch @@ -0,0 +1,35 @@ +From ddfdd1304e5996d8f49320cf09843d979912ab29 Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Tue, 15 Feb 2022 17:27:58 +0200 +Subject: [PATCH] pinctrl: alderlake: Add Raptor Lake-S ACPI ID +Git-commit: ddfdd1304e5996d8f49320cf09843d979912ab29 +Patch-mainline: v5.18-rc1 +References: jsc#PED-634 + +Intel Raptor Lake-S PCH has the same GPIO hardware than Alder Lake-S PCH +but the ACPI ID is different. Add this new ACPI ID to the list of supported +devices. + +Signed-off-by: Andy Shevchenko +Acked-by: Mika Westerberg +Acked-by: Takashi Iwai + +--- + drivers/pinctrl/intel/pinctrl-alderlake.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/pinctrl/intel/pinctrl-alderlake.c b/drivers/pinctrl/intel/pinctrl-alderlake.c +index efb664f12b5d..51fb99cd64a2 100644 +--- a/drivers/pinctrl/intel/pinctrl-alderlake.c ++++ b/drivers/pinctrl/intel/pinctrl-alderlake.c +@@ -416,6 +416,7 @@ static const struct intel_pinctrl_soc_data adls_soc_data = { + + static const struct acpi_device_id adl_pinctrl_acpi_match[] = { + { "INTC1056", (kernel_ulong_t)&adls_soc_data }, ++ { "INTC1085", (kernel_ulong_t)&adls_soc_data }, + { } + }; + MODULE_DEVICE_TABLE(acpi, adl_pinctrl_acpi_match); +-- +2.35.3 + diff --git a/patches.suse/pinctrl-alderlake-Fix-register-offsets-for-ADL-N-var.patch b/patches.suse/pinctrl-alderlake-Fix-register-offsets-for-ADL-N-var.patch new file mode 100644 index 0000000..1afb7de --- /dev/null +++ b/patches.suse/pinctrl-alderlake-Fix-register-offsets-for-ADL-N-var.patch @@ -0,0 +1,118 @@ +From 0be0b70df6611205ac392d0e21f7e077f3230ee6 Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Tue, 5 Apr 2022 20:02:51 +0300 +Subject: [PATCH] pinctrl: alderlake: Fix register offsets for ADL-N variant +Git-commit: 0be0b70df6611205ac392d0e21f7e077f3230ee6 +Patch-mainline: v5.18-rc5 +References: jsc#PED-676 + +It appears that almost traditionally the N variants have deviations +in the register offsets in comparison to S one. This is the case +for Intel Alder Lake as well. Fix register offsets for ADL-N variant. + +Fixes: 114b610b9048 ("pinctrl: alderlake: Add Intel Alder Lake-N pin controller support") +Signed-off-by: Andy Shevchenko +Acked-by: Mika Westerberg +Acked-by: Takashi Iwai + +--- + drivers/pinctrl/intel/pinctrl-alderlake.c | 60 +++++++++++++++-------- + 1 file changed, 40 insertions(+), 20 deletions(-) + +diff --git a/drivers/pinctrl/intel/pinctrl-alderlake.c b/drivers/pinctrl/intel/pinctrl-alderlake.c +index 32ba50efbceb..62dbd1e67513 100644 +--- a/drivers/pinctrl/intel/pinctrl-alderlake.c ++++ b/drivers/pinctrl/intel/pinctrl-alderlake.c +@@ -14,11 +14,17 @@ + + #include "pinctrl-intel.h" + +-#define ADL_PAD_OWN 0x0a0 +-#define ADL_PADCFGLOCK 0x110 +-#define ADL_HOSTSW_OWN 0x150 +-#define ADL_GPI_IS 0x200 +-#define ADL_GPI_IE 0x220 ++#define ADL_N_PAD_OWN 0x020 ++#define ADL_N_PADCFGLOCK 0x080 ++#define ADL_N_HOSTSW_OWN 0x0b0 ++#define ADL_N_GPI_IS 0x100 ++#define ADL_N_GPI_IE 0x120 ++ ++#define ADL_S_PAD_OWN 0x0a0 ++#define ADL_S_PADCFGLOCK 0x110 ++#define ADL_S_HOSTSW_OWN 0x150 ++#define ADL_S_GPI_IS 0x200 ++#define ADL_S_GPI_IE 0x220 + + #define ADL_GPP(r, s, e, g) \ + { \ +@@ -28,14 +34,28 @@ + .gpio_base = (g), \ + } + +-#define ADL_COMMUNITY(b, s, e, g) \ ++#define ADL_N_COMMUNITY(b, s, e, g) \ ++ { \ ++ .barno = (b), \ ++ .padown_offset = ADL_N_PAD_OWN, \ ++ .padcfglock_offset = ADL_N_PADCFGLOCK, \ ++ .hostown_offset = ADL_N_HOSTSW_OWN, \ ++ .is_offset = ADL_N_GPI_IS, \ ++ .ie_offset = ADL_N_GPI_IE, \ ++ .pin_base = (s), \ ++ .npins = ((e) - (s) + 1), \ ++ .gpps = (g), \ ++ .ngpps = ARRAY_SIZE(g), \ ++ } ++ ++#define ADL_S_COMMUNITY(b, s, e, g) \ + { \ + .barno = (b), \ +- .padown_offset = ADL_PAD_OWN, \ +- .padcfglock_offset = ADL_PADCFGLOCK, \ +- .hostown_offset = ADL_HOSTSW_OWN, \ +- .is_offset = ADL_GPI_IS, \ +- .ie_offset = ADL_GPI_IE, \ ++ .padown_offset = ADL_S_PAD_OWN, \ ++ .padcfglock_offset = ADL_S_PADCFGLOCK, \ ++ .hostown_offset = ADL_S_HOSTSW_OWN, \ ++ .is_offset = ADL_S_GPI_IS, \ ++ .ie_offset = ADL_S_GPI_IE, \ + .pin_base = (s), \ + .npins = ((e) - (s) + 1), \ + .gpps = (g), \ +@@ -342,10 +362,10 @@ static const struct intel_padgroup adln_community5_gpps[] = { + }; + + static const struct intel_community adln_communities[] = { +- ADL_COMMUNITY(0, 0, 66, adln_community0_gpps), +- ADL_COMMUNITY(1, 67, 168, adln_community1_gpps), +- ADL_COMMUNITY(2, 169, 248, adln_community4_gpps), +- ADL_COMMUNITY(3, 249, 256, adln_community5_gpps), ++ ADL_N_COMMUNITY(0, 0, 66, adln_community0_gpps), ++ ADL_N_COMMUNITY(1, 67, 168, adln_community1_gpps), ++ ADL_N_COMMUNITY(2, 169, 248, adln_community4_gpps), ++ ADL_N_COMMUNITY(3, 249, 256, adln_community5_gpps), + }; + + static const struct intel_pinctrl_soc_data adln_soc_data = { +@@ -713,11 +733,11 @@ static const struct intel_padgroup adls_community5_gpps[] = { + }; + + static const struct intel_community adls_communities[] = { +- ADL_COMMUNITY(0, 0, 94, adls_community0_gpps), +- ADL_COMMUNITY(1, 95, 150, adls_community1_gpps), +- ADL_COMMUNITY(2, 151, 199, adls_community3_gpps), +- ADL_COMMUNITY(3, 200, 269, adls_community4_gpps), +- ADL_COMMUNITY(4, 270, 303, adls_community5_gpps), ++ ADL_S_COMMUNITY(0, 0, 94, adls_community0_gpps), ++ ADL_S_COMMUNITY(1, 95, 150, adls_community1_gpps), ++ ADL_S_COMMUNITY(2, 151, 199, adls_community3_gpps), ++ ADL_S_COMMUNITY(3, 200, 269, adls_community4_gpps), ++ ADL_S_COMMUNITY(4, 270, 303, adls_community5_gpps), + }; + + static const struct intel_pinctrl_soc_data adls_soc_data = { +-- +2.35.3 + diff --git a/patches.suse/pinctrl-armada-37xx-Add-missing-GPIO-only-pins.patch b/patches.suse/pinctrl-armada-37xx-Add-missing-GPIO-only-pins.patch new file mode 100644 index 0000000..8d300df --- /dev/null +++ b/patches.suse/pinctrl-armada-37xx-Add-missing-GPIO-only-pins.patch @@ -0,0 +1,65 @@ +From 0ca6e30e4dd1d97416a7febcc8bf06f72e19f063 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= +Date: Fri, 5 Aug 2022 14:21:59 +0200 +Subject: [PATCH] pinctrl: armada-37xx: Add missing GPIO-only pins +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 0ca6e30e4dd1d97416a7febcc8bf06f72e19f063 +Patch-mainline: v6.1-rc1 +References: git-fixes + +gpio1_5 and gpio2_2 are GPIO-only pins. Add them into MPP groups table +so they are properly exported as valid pin numbers. + +Fixes: 87466ccd9401 ("pinctrl: armada-37xx: Add pin controller support for Armada 37xx") +Signed-off-by: Pali Rohár +Reviewed-by: Andrew Lunn +Link: https://lore.kernel.org/r/20220805122202.23174-1-pali@kernel.org +Signed-off-by: Linus Walleij +Acked-by: Takashi Iwai + +--- + drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +index bcde042d29dc..2a9425847a92 100644 +--- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c ++++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +@@ -122,6 +122,16 @@ struct armada_37xx_pinctrl { + .funcs = {_func1, _func2} \ + } + ++#define PIN_GRP_GPIO_0(_name, _start, _nr) \ ++ { \ ++ .name = _name, \ ++ .start_pin = _start, \ ++ .npins = _nr, \ ++ .reg_mask = 0, \ ++ .val = {0}, \ ++ .funcs = {"gpio"} \ ++ } ++ + #define PIN_GRP_GPIO(_name, _start, _nr, _mask, _func1) \ + { \ + .name = _name, \ +@@ -179,6 +189,7 @@ static struct armada_37xx_pin_group armada_37xx_nb_groups[] = { + "pwm", "led"), + PIN_GRP_GPIO("pmic1", 7, 1, BIT(7), "pmic"), + PIN_GRP_GPIO("pmic0", 6, 1, BIT(8), "pmic"), ++ PIN_GRP_GPIO_0("gpio1_5", 5, 1), + PIN_GRP_GPIO("i2c2", 2, 2, BIT(9), "i2c"), + PIN_GRP_GPIO("i2c1", 0, 2, BIT(10), "i2c"), + PIN_GRP_GPIO("spi_cs1", 17, 1, BIT(12), "spi"), +@@ -195,6 +206,7 @@ static struct armada_37xx_pin_group armada_37xx_nb_groups[] = { + static struct armada_37xx_pin_group armada_37xx_sb_groups[] = { + PIN_GRP_GPIO("usb32_drvvbus0", 0, 1, BIT(0), "drvbus"), + PIN_GRP_GPIO("usb2_drvvbus1", 1, 1, BIT(1), "drvbus"), ++ PIN_GRP_GPIO_0("gpio2_2", 2, 1), + PIN_GRP_GPIO("sdio_sb", 24, 6, BIT(2), "sdio"), + PIN_GRP_GPIO("rgmii", 6, 12, BIT(3), "mii"), + PIN_GRP_GPIO("smi", 18, 2, BIT(4), "smi"), +-- +2.35.3 + diff --git a/patches.suse/pinctrl-armada-37xx-Checks-for-errors-in-gpio_reques.patch b/patches.suse/pinctrl-armada-37xx-Checks-for-errors-in-gpio_reques.patch new file mode 100644 index 0000000..19069fd --- /dev/null +++ b/patches.suse/pinctrl-armada-37xx-Checks-for-errors-in-gpio_reques.patch @@ -0,0 +1,52 @@ +From 6b262b32faf0abf74062e2e2b72cbbea4572b9f3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= +Date: Fri, 5 Aug 2022 14:22:01 +0200 +Subject: [PATCH] pinctrl: armada-37xx: Checks for errors in gpio_request_enable callback +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 6b262b32faf0abf74062e2e2b72cbbea4572b9f3 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Now when all MPP pins are properly defined and every MPP pin has GPIO +function, always checks for errors in armada_37xx_gpio_request_enable() +function when calling armada_37xx_pmx_set_by_name(). Function +armada_37xx_pmx_set_by_name() should not return "not supported" error +anymore for any GPIO pin when requesting GPIO mode. + +Fixes: 87466ccd9401 ("pinctrl: armada-37xx: Add pin controller support for Armada 37xx") +Signed-off-by: Pali Rohár +Link: https://lore.kernel.org/r/20220805122202.23174-3-pali@kernel.org +Signed-off-by: Linus Walleij +Acked-by: Takashi Iwai + +--- + drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +index 3a39c670615f..7f5665e598bf 100644 +--- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c ++++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +@@ -500,11 +500,15 @@ static int armada_37xx_gpio_request_enable(struct pinctrl_dev *pctldev, + struct armada_37xx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + struct armada_37xx_pin_group *group; + int grp = 0; ++ int ret; + + dev_dbg(info->dev, "requesting gpio %d\n", offset); + +- while ((group = armada_37xx_find_next_grp_by_pin(info, offset, &grp))) +- armada_37xx_pmx_set_by_name(pctldev, "gpio", group); ++ while ((group = armada_37xx_find_next_grp_by_pin(info, offset, &grp))) { ++ ret = armada_37xx_pmx_set_by_name(pctldev, "gpio", group); ++ if (ret) ++ return ret; ++ } + + return 0; + } +-- +2.35.3 + diff --git a/patches.suse/pinctrl-armada-37xx-Fix-definitions-for-MPP-pins-20-.patch b/patches.suse/pinctrl-armada-37xx-Fix-definitions-for-MPP-pins-20-.patch new file mode 100644 index 0000000..a793569 --- /dev/null +++ b/patches.suse/pinctrl-armada-37xx-Fix-definitions-for-MPP-pins-20-.patch @@ -0,0 +1,49 @@ +From 2fa9933d685ee9bcab056c81ef5f7fa242ba90e3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= +Date: Fri, 5 Aug 2022 14:22:00 +0200 +Subject: [PATCH] pinctrl: armada-37xx: Fix definitions for MPP pins 20-22 +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 2fa9933d685ee9bcab056c81ef5f7fa242ba90e3 +Patch-mainline: v6.1-rc1 +References: git-fixes + +All 3 MPP pins (20, 21 and 22) can be configured individually and also can +be configured to GPIO functions. Fix definitions for these MPP pins in +existing pin groups. After this change GPIO function can be enabled just +for one of these 3 pins. + +Fixes: 87466ccd9401 ("pinctrl: armada-37xx: Add pin controller support for Armada 37xx") +Signed-off-by: Pali Rohár +Reviewed-by: Andrew Lunn +Link: https://lore.kernel.org/r/20220805122202.23174-2-pali@kernel.org +Signed-off-by: Linus Walleij +Acked-by: Takashi Iwai + +--- + drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +index 2a9425847a92..3a39c670615f 100644 +--- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c ++++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +@@ -213,9 +213,11 @@ static struct armada_37xx_pin_group armada_37xx_sb_groups[] = { + PIN_GRP_GPIO("pcie1", 3, 1, BIT(5), "pcie"), /* this actually controls "pcie1_reset" */ + PIN_GRP_GPIO("pcie1_clkreq", 4, 1, BIT(9), "pcie"), + PIN_GRP_GPIO("pcie1_wakeup", 5, 1, BIT(10), "pcie"), +- PIN_GRP_GPIO("ptp", 20, 3, BIT(11) | BIT(12) | BIT(13), "ptp"), +- PIN_GRP("ptp_clk", 21, 1, BIT(6), "ptp", "mii"), +- PIN_GRP("ptp_trig", 22, 1, BIT(7), "ptp", "mii"), ++ PIN_GRP_GPIO("ptp", 20, 1, BIT(11), "ptp"), ++ PIN_GRP_GPIO_3("ptp_clk", 21, 1, BIT(6) | BIT(12), 0, BIT(6), BIT(12), ++ "ptp", "mii"), ++ PIN_GRP_GPIO_3("ptp_trig", 22, 1, BIT(7) | BIT(13), 0, BIT(7), BIT(13), ++ "ptp", "mii"), + PIN_GRP_GPIO_3("mii_col", 23, 1, BIT(8) | BIT(14), 0, BIT(8), BIT(14), + "mii", "mii_err"), + }; +-- +2.35.3 + diff --git a/patches.suse/pinctrl-microchip-sgpio-Correct-the-fwnode_irq_get-r.patch b/patches.suse/pinctrl-microchip-sgpio-Correct-the-fwnode_irq_get-r.patch new file mode 100644 index 0000000..9fb25b1 --- /dev/null +++ b/patches.suse/pinctrl-microchip-sgpio-Correct-the-fwnode_irq_get-r.patch @@ -0,0 +1,37 @@ +From 6323f916686d4e9d299a53114b28ecaf833422cd Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Tue, 6 Sep 2022 14:50:21 +0300 +Subject: [PATCH] pinctrl: microchip-sgpio: Correct the fwnode_irq_get() return value check +Git-commit: 6323f916686d4e9d299a53114b28ecaf833422cd +Patch-mainline: v6.1-rc1 +References: git-fixes + +fwnode_irq_get() may return all possible signed values, such as Linux +error code. Fix the code to handle this properly. + +Fixes: be2dc859abd4 ("pinctrl: pinctrl-microchip-sgpio: Add irq support (for sparx5)") +Signed-off-by: Andy Shevchenko +Reviewed-by: Michael Walle +Link: https://lore.kernel.org/r/20220906115021.8661-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Linus Walleij +Acked-by: Takashi Iwai + +--- + drivers/pinctrl/pinctrl-microchip-sgpio.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/pinctrl/pinctrl-microchip-sgpio.c ++++ b/drivers/pinctrl/pinctrl-microchip-sgpio.c +@@ -777,9 +777,10 @@ static int microchip_sgpio_register_bank + gc->ngpio = ngpios; + + if (bank->is_input && priv->properties->flags & SGPIO_FLAGS_HAS_IRQ) { +- int irq = fwnode_irq_get(fwnode, 0); ++ int irq; + +- if (irq) { ++ irq = fwnode_irq_get(fwnode, 0); ++ if (irq > 0) { + struct gpio_irq_chip *girq = &gc->irq; + + girq->chip = devm_kmemdup(dev, µchip_sgpio_irqchip, diff --git a/patches.suse/pinctrl-qcom-sc8180x-Fix-gpio_wakeirq_map.patch b/patches.suse/pinctrl-qcom-sc8180x-Fix-gpio_wakeirq_map.patch new file mode 100644 index 0000000..21248c2 --- /dev/null +++ b/patches.suse/pinctrl-qcom-sc8180x-Fix-gpio_wakeirq_map.patch @@ -0,0 +1,40 @@ +From 6124cec530c7d8faab96d340ab2df5161e5d1c8a Mon Sep 17 00:00:00 2001 +From: Molly Sophia +Date: Sun, 7 Aug 2022 20:26:44 +0800 +Subject: [PATCH] pinctrl: qcom: sc8180x: Fix gpio_wakeirq_map +Git-commit: 6124cec530c7d8faab96d340ab2df5161e5d1c8a +Patch-mainline: v6.0-rc6 +References: git-fixes + +Currently in the wakeirq_map, gpio36 and gpio37 have the same wakeirq +number, resulting in gpio37 being unable to trigger interrupts. +It looks like that this is a typo in the wakeirq map. So fix it. + +Signed-off-by: Molly Sophia +Fixes: 97423113ec4b ("pinctrl: qcom: Add sc8180x TLMM driver") +Tested-by: Bjorn Andersson +Reviewed-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20220807122645.13830-2-mollysophia379@gmail.com +Signed-off-by: Linus Walleij +Acked-by: Takashi Iwai + +--- + drivers/pinctrl/qcom/pinctrl-sc8180x.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/pinctrl/qcom/pinctrl-sc8180x.c b/drivers/pinctrl/qcom/pinctrl-sc8180x.c +index 6bec7f143134..b4bf009fe23e 100644 +--- a/drivers/pinctrl/qcom/pinctrl-sc8180x.c ++++ b/drivers/pinctrl/qcom/pinctrl-sc8180x.c +@@ -1582,7 +1582,7 @@ static const int sc8180x_acpi_reserved_gpios[] = { + static const struct msm_gpio_wakeirq_map sc8180x_pdc_map[] = { + { 3, 31 }, { 5, 32 }, { 8, 33 }, { 9, 34 }, { 10, 100 }, { 12, 104 }, + { 24, 37 }, { 26, 38 }, { 27, 41 }, { 28, 42 }, { 30, 39 }, { 36, 43 }, +- { 37, 43 }, { 38, 45 }, { 39, 118 }, { 39, 125 }, { 41, 47 }, ++ { 37, 44 }, { 38, 45 }, { 39, 118 }, { 39, 125 }, { 41, 47 }, + { 42, 48 }, { 46, 50 }, { 47, 49 }, { 48, 51 }, { 49, 53 }, { 50, 52 }, + { 51, 116 }, { 51, 123 }, { 53, 54 }, { 54, 55 }, { 55, 56 }, + { 56, 57 }, { 58, 58 }, { 60, 60 }, { 68, 62 }, { 70, 63 }, { 76, 86 }, +-- +2.35.3 + diff --git a/patches.suse/pinctrl-qcom-sc8180x-Fix-wrong-pin-numbers.patch b/patches.suse/pinctrl-qcom-sc8180x-Fix-wrong-pin-numbers.patch new file mode 100644 index 0000000..e5b6dfe --- /dev/null +++ b/patches.suse/pinctrl-qcom-sc8180x-Fix-wrong-pin-numbers.patch @@ -0,0 +1,45 @@ +From 48ec73395887694f13c9452b4dcfb43710451757 Mon Sep 17 00:00:00 2001 +From: Molly Sophia +Date: Sun, 7 Aug 2022 20:26:45 +0800 +Subject: [PATCH] pinctrl: qcom: sc8180x: Fix wrong pin numbers +Git-commit: 48ec73395887694f13c9452b4dcfb43710451757 +Patch-mainline: v6.0-rc6 +References: git-fixes + +The pin numbers for UFS_RESET and SDC2_* are not +consistent in the pinctrl driver for sc8180x. +So fix it. + +Signed-off-by: Molly Sophia +Fixes: 97423113ec4b ("pinctrl: qcom: Add sc8180x TLMM driver") +Reviewed-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20220807122645.13830-3-mollysophia379@gmail.com +Signed-off-by: Linus Walleij +Acked-by: Takashi Iwai + +--- + drivers/pinctrl/qcom/pinctrl-sc8180x.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/pinctrl/qcom/pinctrl-sc8180x.c b/drivers/pinctrl/qcom/pinctrl-sc8180x.c +index b4bf009fe23e..704a99d2f93c 100644 +--- a/drivers/pinctrl/qcom/pinctrl-sc8180x.c ++++ b/drivers/pinctrl/qcom/pinctrl-sc8180x.c +@@ -530,10 +530,10 @@ DECLARE_MSM_GPIO_PINS(187); + DECLARE_MSM_GPIO_PINS(188); + DECLARE_MSM_GPIO_PINS(189); + +-static const unsigned int sdc2_clk_pins[] = { 190 }; +-static const unsigned int sdc2_cmd_pins[] = { 191 }; +-static const unsigned int sdc2_data_pins[] = { 192 }; +-static const unsigned int ufs_reset_pins[] = { 193 }; ++static const unsigned int ufs_reset_pins[] = { 190 }; ++static const unsigned int sdc2_clk_pins[] = { 191 }; ++static const unsigned int sdc2_cmd_pins[] = { 192 }; ++static const unsigned int sdc2_data_pins[] = { 193 }; + + enum sc8180x_functions { + msm_mux_adsp_ext, +-- +2.35.3 + diff --git a/patches.suse/pinctrl-sunxi-Fix-name-for-A100-R_PIO.patch b/patches.suse/pinctrl-sunxi-Fix-name-for-A100-R_PIO.patch new file mode 100644 index 0000000..b3f3e42 --- /dev/null +++ b/patches.suse/pinctrl-sunxi-Fix-name-for-A100-R_PIO.patch @@ -0,0 +1,38 @@ +From 76648c867c6c03b8a468d9c9222025873ecc613d Mon Sep 17 00:00:00 2001 +From: Michael Wu +Date: Fri, 19 Aug 2022 10:45:41 +0800 +Subject: [PATCH] pinctrl: sunxi: Fix name for A100 R_PIO +Git-commit: 76648c867c6c03b8a468d9c9222025873ecc613d +Patch-mainline: v6.0-rc6 +References: git-fixes + +The name of A100 R_PIO driver should be sun50i-a100-r-pinctrl, +not sun50iw10p1-r-pinctrl. + +Fixes: 473436e7647d6 ("pinctrl: sunxi: add support for the Allwinner A100 pin controller") +Signed-off-by: Michael Wu +Acked-by: Samuel Holland +Link: https://lore.kernel.org/r/20220819024541.74191-1-michael@allwinnertech.com +Signed-off-by: Linus Walleij +Acked-by: Takashi Iwai + +--- + drivers/pinctrl/sunxi/pinctrl-sun50i-a100-r.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/pinctrl/sunxi/pinctrl-sun50i-a100-r.c b/drivers/pinctrl/sunxi/pinctrl-sun50i-a100-r.c +index afc1f5df7545..b82ad135bf2a 100644 +--- a/drivers/pinctrl/sunxi/pinctrl-sun50i-a100-r.c ++++ b/drivers/pinctrl/sunxi/pinctrl-sun50i-a100-r.c +@@ -99,7 +99,7 @@ MODULE_DEVICE_TABLE(of, a100_r_pinctrl_match); + static struct platform_driver a100_r_pinctrl_driver = { + .probe = a100_r_pinctrl_probe, + .driver = { +- .name = "sun50iw10p1-r-pinctrl", ++ .name = "sun50i-a100-r-pinctrl", + .of_match_table = a100_r_pinctrl_match, + }, + }; +-- +2.35.3 + diff --git a/patches.suse/platform-chrome-cros_ec_proto-Update-version-on-GET_.patch b/patches.suse/platform-chrome-cros_ec_proto-Update-version-on-GET_.patch new file mode 100644 index 0000000..998ddf8 --- /dev/null +++ b/patches.suse/platform-chrome-cros_ec_proto-Update-version-on-GET_.patch @@ -0,0 +1,87 @@ +From f74c7557ed0d321947e8bb4e9d47c1013f8b2227 Mon Sep 17 00:00:00 2001 +From: Patryk Duda +Date: Tue, 2 Aug 2022 17:41:28 +0200 +Subject: [PATCH] platform/chrome: cros_ec_proto: Update version on GET_NEXT_EVENT failure +Git-commit: f74c7557ed0d321947e8bb4e9d47c1013f8b2227 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Some EC based devices (e.g. Fingerpint MCU) can jump to RO part of the +firmware (intentionally or due to device reboot). The RO part doesn't +change during the device lifecycle, so it won't support newer version +of EC_CMD_GET_NEXT_EVENT command. + +Function cros_ec_query_all() is responsible for finding maximum +supported MKBP event version. It's usually called when the device is +running RW part of the firmware, so the command version can be +potentially higher than version supported by the RO. + +The problem was fixed by updating maximum supported version when the +device returns EC_RES_INVALID_VERSION (mapped to -ENOPROTOOPT). That way +the kernel will use highest common version supported by RO and RW. + +Fixes: 3300fdd630d4 ("platform/chrome: cros_ec: handle MKBP more events flag") +Cc: # 5.10+ +Reviewed-by: Guenter Roeck +Signed-off-by: Patryk Duda +Signed-off-by: Tzung-Bi Shih +Link: https://lore.kernel.org/r/20220802154128.21175-1-pdk@semihalf.com +Acked-by: Takashi Iwai + +--- + drivers/platform/chrome/cros_ec_proto.c | 32 +++++++++++++++++++++++++ + 1 file changed, 32 insertions(+) + +diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c +index 05d2e8765a66..475a6dd72db6 100644 +--- a/drivers/platform/chrome/cros_ec_proto.c ++++ b/drivers/platform/chrome/cros_ec_proto.c +@@ -773,6 +773,7 @@ int cros_ec_get_next_event(struct cros_ec_device *ec_dev, + u8 event_type; + u32 host_event; + int ret; ++ u32 ver_mask; + + /* + * Default value for wake_event. +@@ -794,6 +795,37 @@ int cros_ec_get_next_event(struct cros_ec_device *ec_dev, + return get_keyboard_state_event(ec_dev); + + ret = get_next_event(ec_dev); ++ /* ++ * -ENOPROTOOPT is returned when EC returns EC_RES_INVALID_VERSION. ++ * This can occur when EC based device (e.g. Fingerprint MCU) jumps to ++ * the RO image which doesn't support newer version of the command. In ++ * this case we will attempt to update maximum supported version of the ++ * EC_CMD_GET_NEXT_EVENT. ++ */ ++ if (ret == -ENOPROTOOPT) { ++ dev_dbg(ec_dev->dev, ++ "GET_NEXT_EVENT returned invalid version error.\n"); ++ ret = cros_ec_get_host_command_version_mask(ec_dev, ++ EC_CMD_GET_NEXT_EVENT, ++ &ver_mask); ++ if (ret < 0 || ver_mask == 0) ++ /* ++ * Do not change the MKBP supported version if we can't ++ * obtain supported version correctly. Please note that ++ * calling EC_CMD_GET_NEXT_EVENT returned ++ * EC_RES_INVALID_VERSION which means that the command ++ * is present. ++ */ ++ return -ENOPROTOOPT; ++ ++ ec_dev->mkbp_event_supported = fls(ver_mask); ++ dev_dbg(ec_dev->dev, "MKBP support version changed to %u\n", ++ ec_dev->mkbp_event_supported - 1); ++ ++ /* Try to get next event with new MKBP support version set. */ ++ ret = get_next_event(ec_dev); ++ } ++ + if (ret <= 0) + return ret; + +-- +2.35.3 + diff --git a/patches.suse/platform-chrome-cros_ec_typec-Correct-alt-mode-index.patch b/patches.suse/platform-chrome-cros_ec_typec-Correct-alt-mode-index.patch new file mode 100644 index 0000000..766080e --- /dev/null +++ b/patches.suse/platform-chrome-cros_ec_typec-Correct-alt-mode-index.patch @@ -0,0 +1,40 @@ +From 4e477663e396f48c5cfc5f2d75d4b514f409516a Mon Sep 17 00:00:00 2001 +From: Prashant Malani +Date: Fri, 19 Aug 2022 19:08:03 +0000 +Subject: [PATCH] platform/chrome: cros_ec_typec: Correct alt mode index +Git-commit: 4e477663e396f48c5cfc5f2d75d4b514f409516a +Patch-mainline: v6.1-rc1 +References: git-fixes + +Alt mode indices used by USB PD (Power Delivery) start with 1, not 0. + +Update the alt mdoe registration code to factor this in to the alt mode +descriptor. + +Fixes: de0f49487db3 ("platform/chrome: cros_ec_typec: Register partner altmodes") +Signed-off-by: Prashant Malani +Acked-by: Heikki Krogerus +Reviewed-by: Tzung-Bi Shih +Link: https://lore.kernel.org/r/20220819190807.1275937-3-pmalani@chromium.org +Acked-by: Takashi Iwai + +--- + drivers/platform/chrome/cros_ec_typec.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chrome/cros_ec_typec.c +index d4dbca5d91af..00208ffbe2e7 100644 +--- a/drivers/platform/chrome/cros_ec_typec.c ++++ b/drivers/platform/chrome/cros_ec_typec.c +@@ -734,7 +734,7 @@ static int cros_typec_register_altmodes(struct cros_typec_data *typec, int port_ + for (j = 0; j < sop_disc->svids[i].mode_count; j++) { + memset(&desc, 0, sizeof(desc)); + desc.svid = sop_disc->svids[i].svid; +- desc.mode = j; ++ desc.mode = j + 1; + desc.vdo = sop_disc->svids[i].mode_vdo[j]; + + if (is_partner) +-- +2.35.3 + diff --git a/patches.suse/platform-chrome-fix-double-free-in-chromeos_laptop_p.patch b/patches.suse/platform-chrome-fix-double-free-in-chromeos_laptop_p.patch new file mode 100644 index 0000000..a5fcb05 --- /dev/null +++ b/patches.suse/platform-chrome-fix-double-free-in-chromeos_laptop_p.patch @@ -0,0 +1,88 @@ +From 6ad4194d6a1e1d11b285989cd648ef695b4a93c0 Mon Sep 17 00:00:00 2001 +From: Rustam Subkhankulov +Date: Sun, 14 Aug 2022 01:08:43 +0300 +Subject: [PATCH] platform/chrome: fix double-free in chromeos_laptop_prepare() +Git-commit: 6ad4194d6a1e1d11b285989cd648ef695b4a93c0 +Patch-mainline: v6.1-rc1 +References: git-fixes + +If chromeos_laptop_prepare_i2c_peripherals() fails after allocating memory +for 'cros_laptop->i2c_peripherals', this memory is freed at 'err_out' label +and nonzero value is returned. Then chromeos_laptop_destroy() is called, +resulting in double-free error. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Signed-off-by: Rustam Subkhankulov +Fixes: 5020cd29d8bf ("platform/chrome: chromeos_laptop - supply properties for ACPI devices") +Reviewed-by: Dmitry Torokhov +Signed-off-by: Tzung-Bi Shih +Link: https://lore.kernel.org/r/20220813220843.2373004-1-subkhankulov@ispras.ru +Acked-by: Takashi Iwai + +--- + drivers/platform/chrome/chromeos_laptop.c | 24 ++++++++++++----------- + 1 file changed, 13 insertions(+), 11 deletions(-) + +diff --git a/drivers/platform/chrome/chromeos_laptop.c b/drivers/platform/chrome/chromeos_laptop.c +index 4e14b4d6635d..a2cdbfbaeae6 100644 +--- a/drivers/platform/chrome/chromeos_laptop.c ++++ b/drivers/platform/chrome/chromeos_laptop.c +@@ -740,6 +740,7 @@ static int __init + chromeos_laptop_prepare_i2c_peripherals(struct chromeos_laptop *cros_laptop, + const struct chromeos_laptop *src) + { ++ struct i2c_peripheral *i2c_peripherals; + struct i2c_peripheral *i2c_dev; + struct i2c_board_info *info; + int i; +@@ -748,17 +749,15 @@ chromeos_laptop_prepare_i2c_peripherals(struct chromeos_laptop *cros_laptop, + if (!src->num_i2c_peripherals) + return 0; + +- cros_laptop->i2c_peripherals = kmemdup(src->i2c_peripherals, +- src->num_i2c_peripherals * +- sizeof(*src->i2c_peripherals), +- GFP_KERNEL); +- if (!cros_laptop->i2c_peripherals) ++ i2c_peripherals = kmemdup(src->i2c_peripherals, ++ src->num_i2c_peripherals * ++ sizeof(*src->i2c_peripherals), ++ GFP_KERNEL); ++ if (!i2c_peripherals) + return -ENOMEM; + +- cros_laptop->num_i2c_peripherals = src->num_i2c_peripherals; +- +- for (i = 0; i < cros_laptop->num_i2c_peripherals; i++) { +- i2c_dev = &cros_laptop->i2c_peripherals[i]; ++ for (i = 0; i < src->num_i2c_peripherals; i++) { ++ i2c_dev = &i2c_peripherals[i]; + info = &i2c_dev->board_info; + + error = chromeos_laptop_setup_irq(i2c_dev); +@@ -775,16 +774,19 @@ chromeos_laptop_prepare_i2c_peripherals(struct chromeos_laptop *cros_laptop, + } + } + ++ cros_laptop->i2c_peripherals = i2c_peripherals; ++ cros_laptop->num_i2c_peripherals = src->num_i2c_peripherals; ++ + return 0; + + err_out: + while (--i >= 0) { +- i2c_dev = &cros_laptop->i2c_peripherals[i]; ++ i2c_dev = &i2c_peripherals[i]; + info = &i2c_dev->board_info; + if (!IS_ERR_OR_NULL(info->fwnode)) + fwnode_remove_software_node(info->fwnode); + } +- kfree(cros_laptop->i2c_peripherals); ++ kfree(i2c_peripherals); + return error; + } + +-- +2.35.3 + diff --git a/patches.suse/platform-chrome-fix-memory-corruption-in-ioctl.patch b/patches.suse/platform-chrome-fix-memory-corruption-in-ioctl.patch new file mode 100644 index 0000000..0c286ad --- /dev/null +++ b/patches.suse/platform-chrome-fix-memory-corruption-in-ioctl.patch @@ -0,0 +1,39 @@ +From 8a07b45fd3c2dda24fad43639be5335a4595196a Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Fri, 19 Aug 2022 08:20:36 +0300 +Subject: [PATCH] platform/chrome: fix memory corruption in ioctl +Git-commit: 8a07b45fd3c2dda24fad43639be5335a4595196a +Patch-mainline: v6.1-rc1 +References: git-fixes + +If "s_mem.bytes" is larger than the buffer size it leads to memory +corruption. + +Fixes: eda2e30c6684 ("mfd / platform: cros_ec: Miscellaneous character device to talk with the EC") +Signed-off-by: Dan Carpenter +Reviewed-by: Guenter Roeck +Signed-off-by: Tzung-Bi Shih +Link: https://lore.kernel.org/r/Yv8dpCFZJdbUT5ye@kili +Acked-by: Takashi Iwai + +--- + drivers/platform/chrome/cros_ec_chardev.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/platform/chrome/cros_ec_chardev.c b/drivers/platform/chrome/cros_ec_chardev.c +index fd33de546aee..0de7c255254e 100644 +--- a/drivers/platform/chrome/cros_ec_chardev.c ++++ b/drivers/platform/chrome/cros_ec_chardev.c +@@ -327,6 +327,9 @@ static long cros_ec_chardev_ioctl_readmem(struct cros_ec_dev *ec, + if (copy_from_user(&s_mem, arg, sizeof(s_mem))) + return -EFAULT; + ++ if (s_mem.bytes > sizeof(s_mem.buffer)) ++ return -EINVAL; ++ + num = ec_dev->cmd_readmem(ec_dev, s_mem.offset, s_mem.bytes, + s_mem.buffer); + if (num <= 0) +-- +2.35.3 + diff --git a/patches.suse/platform-surface-aggregator_registry-Add-support-for-84b8e403435c.patch b/patches.suse/platform-surface-aggregator_registry-Add-support-for-84b8e403435c.patch new file mode 100644 index 0000000..f59f820 --- /dev/null +++ b/patches.suse/platform-surface-aggregator_registry-Add-support-for-84b8e403435c.patch @@ -0,0 +1,37 @@ +From 84b8e403435c8fb94b872309673764a447961e00 Mon Sep 17 00:00:00 2001 +From: Maximilian Luz +Date: Wed, 10 Aug 2022 16:01:33 +0200 +Subject: [PATCH] platform/surface: aggregator_registry: Add support for Surface Laptop Go 2 +Git-commit: 84b8e403435c8fb94b872309673764a447961e00 +Patch-mainline: v6.0-rc4 +References: git-fixes + +The Surface Laptop Go 2 seems to have the same SAM client devices as the +Surface Laptop Go 1, so re-use its node group. + +Signed-off-by: Maximilian Luz +Link: https://lore.kernel.org/r/20220810140133.99087-1-luzmaximilian@gmail.com +Signed-off-by: Hans de Goede +Acked-by: Takashi Iwai + +--- + drivers/platform/surface/surface_aggregator_registry.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/platform/surface/surface_aggregator_registry.c b/drivers/platform/surface/surface_aggregator_registry.c +index d5655f6a4a41..93ab62eb393d 100644 +--- a/drivers/platform/surface/surface_aggregator_registry.c ++++ b/drivers/platform/surface/surface_aggregator_registry.c +@@ -325,6 +325,9 @@ static const struct acpi_device_id ssam_platform_hub_match[] = { + /* Surface Laptop Go 1 */ + { "MSHW0118", (unsigned long)ssam_node_group_slg1 }, + ++ /* Surface Laptop Go 2 */ ++ { "MSHW0290", (unsigned long)ssam_node_group_slg1 }, ++ + /* Surface Laptop Studio */ + { "MSHW0123", (unsigned long)ssam_node_group_sls }, + +-- +2.35.3 + diff --git a/patches.suse/platform-x86-acer-wmi-Acer-Aspire-One-AOD270-Packard.patch b/patches.suse/platform-x86-acer-wmi-Acer-Aspire-One-AOD270-Packard.patch new file mode 100644 index 0000000..a5a1114 --- /dev/null +++ b/patches.suse/platform-x86-acer-wmi-Acer-Aspire-One-AOD270-Packard.patch @@ -0,0 +1,58 @@ +From c3b82d26bc85f5fc2fef5ec8cce17c89633a55a8 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Mon, 29 Aug 2022 18:35:44 +0200 +Subject: [PATCH] platform/x86: acer-wmi: Acer Aspire One AOD270/Packard Bell Dot keymap fixes +Git-commit: c3b82d26bc85f5fc2fef5ec8cce17c89633a55a8 +Patch-mainline: v6.0-rc4 +References: git-fixes + +2 keymap fixes for the Acer Aspire One AOD270 and the same hardware +rebranded as Packard Bell Dot SC: + +1. The F2 key is marked with a big '?' symbol on the Packard Bell Dot SC, +this sends WMID_HOTKEY_EVENTs with a scancode of 0x27 add a mapping +for this. + +2. Scancode 0x61 is KEY_SWITCHVIDEOMODE. Usually this is a duplicate +input event with the "Video Bus" input device events. But on these devices +the "Video Bus" does not send events for this key. Map 0x61 to KEY_UNKNOWN +instead of using KE_IGNORE so that udev/hwdb can override it on these devs. + +Signed-off-by: Hans de Goede +Link: https://lore.kernel.org/r/20220829163544.5288-1-hdegoede@redhat.com +Acked-by: Takashi Iwai + +--- + drivers/platform/x86/acer-wmi.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c +index e0230ea0cb7e..f1259d81d86d 100644 +--- a/drivers/platform/x86/acer-wmi.c ++++ b/drivers/platform/x86/acer-wmi.c +@@ -99,6 +99,7 @@ static const struct key_entry acer_wmi_keymap[] __initconst = { + {KE_KEY, 0x22, {KEY_PROG2} }, /* Arcade */ + {KE_KEY, 0x23, {KEY_PROG3} }, /* P_Key */ + {KE_KEY, 0x24, {KEY_PROG4} }, /* Social networking_Key */ ++ {KE_KEY, 0x27, {KEY_HELP} }, + {KE_KEY, 0x29, {KEY_PROG3} }, /* P_Key for TM8372 */ + {KE_IGNORE, 0x41, {KEY_MUTE} }, + {KE_IGNORE, 0x42, {KEY_PREVIOUSSONG} }, +@@ -112,7 +113,13 @@ static const struct key_entry acer_wmi_keymap[] __initconst = { + {KE_IGNORE, 0x48, {KEY_VOLUMEUP} }, + {KE_IGNORE, 0x49, {KEY_VOLUMEDOWN} }, + {KE_IGNORE, 0x4a, {KEY_VOLUMEDOWN} }, +- {KE_IGNORE, 0x61, {KEY_SWITCHVIDEOMODE} }, ++ /* ++ * 0x61 is KEY_SWITCHVIDEOMODE. Usually this is a duplicate input event ++ * with the "Video Bus" input device events. But sometimes it is not ++ * a dup. Map it to KEY_UNKNOWN instead of using KE_IGNORE so that ++ * udev/hwdb can override it on systems where it is not a dup. ++ */ ++ {KE_KEY, 0x61, {KEY_UNKNOWN} }, + {KE_IGNORE, 0x62, {KEY_BRIGHTNESSUP} }, + {KE_IGNORE, 0x63, {KEY_BRIGHTNESSDOWN} }, + {KE_KEY, 0x64, {KEY_SWITCHVIDEOMODE} }, /* Display Switch */ +-- +2.35.3 + diff --git a/patches.suse/platform-x86-asus-wmi-Document-the-dgpu_disable-sysf.patch b/patches.suse/platform-x86-asus-wmi-Document-the-dgpu_disable-sysf.patch new file mode 100644 index 0000000..67a668f --- /dev/null +++ b/patches.suse/platform-x86-asus-wmi-Document-the-dgpu_disable-sysf.patch @@ -0,0 +1,42 @@ +From 7e64c486e807c8edfbd3a0c8e44ad7a1896dbec8 Mon Sep 17 00:00:00 2001 +From: "Luke D. Jones" +Date: Sat, 13 Aug 2022 10:25:04 +1200 +Subject: [PATCH] platform/x86: asus-wmi: Document the dgpu_disable sysfs attribute +Git-commit: 7e64c486e807c8edfbd3a0c8e44ad7a1896dbec8 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The dgpu_disable attribute was not documented, this adds the +required documentation. + +Fixes: 98829e84dc67 ("asus-wmi: Add dgpu disable method") +Signed-off-by: Luke D. Jones +Link: https://lore.kernel.org/r/20220812222509.292692-2-luke@ljones.dev +Reviewed-by: Hans de Goede +Signed-off-by: Hans de Goede +Acked-by: Takashi Iwai + +--- + Documentation/ABI/testing/sysfs-platform-asus-wmi | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/Documentation/ABI/testing/sysfs-platform-asus-wmi b/Documentation/ABI/testing/sysfs-platform-asus-wmi +index 04885738cf15..0f8f0772d6f3 100644 +--- a/Documentation/ABI/testing/sysfs-platform-asus-wmi ++++ b/Documentation/ABI/testing/sysfs-platform-asus-wmi +@@ -57,3 +57,12 @@ Description: + * 0 - default, + * 1 - overboost, + * 2 - silent ++ ++What: /sys/devices/platform//dgpu_disable ++Date: Aug 2022 ++KernelVersion: 5.17 ++Contact: "Luke Jones" ++Description: ++ Disable discrete GPU: ++ * 0 - Enable dGPU, ++ * 1 - Disable dGPU +-- +2.35.3 + diff --git a/patches.suse/platform-x86-asus-wmi-Document-the-egpu_enable-sysfs.patch b/patches.suse/platform-x86-asus-wmi-Document-the-egpu_enable-sysfs.patch new file mode 100644 index 0000000..e45eb11 --- /dev/null +++ b/patches.suse/platform-x86-asus-wmi-Document-the-egpu_enable-sysfs.patch @@ -0,0 +1,44 @@ +From 3206376f099d9c74d9938b9c41cfc0b85ea6e1b0 Mon Sep 17 00:00:00 2001 +From: "Luke D. Jones" +Date: Sat, 13 Aug 2022 10:25:05 +1200 +Subject: [PATCH] platform/x86: asus-wmi: Document the egpu_enable sysfs attribute +Git-commit: 3206376f099d9c74d9938b9c41cfc0b85ea6e1b0 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The egpu_enable attribute was not documented, this adds the +required documentation. + +Fixes: 382b91db8044 ("asus-wmi: Add egpu enable method") +Signed-off-by: Luke D. Jones +Link: https://lore.kernel.org/r/20220812222509.292692-3-luke@ljones.dev +Reviewed-by: Hans de Goede +Signed-off-by: Hans de Goede +Acked-by: Takashi Iwai + +--- + Documentation/ABI/testing/sysfs-platform-asus-wmi | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/Documentation/ABI/testing/sysfs-platform-asus-wmi b/Documentation/ABI/testing/sysfs-platform-asus-wmi +index 0f8f0772d6f3..ac5ec3a17c51 100644 +--- a/Documentation/ABI/testing/sysfs-platform-asus-wmi ++++ b/Documentation/ABI/testing/sysfs-platform-asus-wmi +@@ -66,3 +66,14 @@ Description: + Disable discrete GPU: + * 0 - Enable dGPU, + * 1 - Disable dGPU ++ ++What: /sys/devices/platform//egpu_enable ++Date: Aug 2022 ++KernelVersion: 5.17 ++Contact: "Luke Jones" ++Description: ++ Enable the external GPU paired with ROG X-Flow laptops. ++ Toggling this setting will also trigger ACPI to disable the dGPU: ++ ++ * 0 - Disable, ++ * 1 - Enable +-- +2.35.3 + diff --git a/patches.suse/platform-x86-asus-wmi-Document-the-panel_od-sysfs-at.patch b/patches.suse/platform-x86-asus-wmi-Document-the-panel_od-sysfs-at.patch new file mode 100644 index 0000000..f570458 --- /dev/null +++ b/patches.suse/platform-x86-asus-wmi-Document-the-panel_od-sysfs-at.patch @@ -0,0 +1,42 @@ +From d956c889be804742e39fbb3291b054b3cbf505be Mon Sep 17 00:00:00 2001 +From: "Luke D. Jones" +Date: Sat, 13 Aug 2022 10:25:06 +1200 +Subject: [PATCH] platform/x86: asus-wmi: Document the panel_od sysfs attribute +Git-commit: d956c889be804742e39fbb3291b054b3cbf505be +Patch-mainline: v6.1-rc1 +References: git-fixes + +The panel_od attribute was not documented, this adds the +required documentation. + +Fixes: ca91ea34778f ("asus-wmi: Add panel overdrive functionality") +Signed-off-by: Luke D. Jones +Link: https://lore.kernel.org/r/20220812222509.292692-4-luke@ljones.dev +Reviewed-by: Hans de Goede +Signed-off-by: Hans de Goede +Acked-by: Takashi Iwai + +--- + Documentation/ABI/testing/sysfs-platform-asus-wmi | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/Documentation/ABI/testing/sysfs-platform-asus-wmi b/Documentation/ABI/testing/sysfs-platform-asus-wmi +index ac5ec3a17c51..4d63824713ac 100644 +--- a/Documentation/ABI/testing/sysfs-platform-asus-wmi ++++ b/Documentation/ABI/testing/sysfs-platform-asus-wmi +@@ -77,3 +77,12 @@ Description: + + * 0 - Disable, + * 1 - Enable ++ ++What: /sys/devices/platform//panel_od ++Date: Aug 2022 ++KernelVersion: 5.17 ++Contact: "Luke Jones" ++Description: ++ Enable an LCD response-time boost to reduce or remove ghosting: ++ * 0 - Disable, ++ * 1 - Enable +-- +2.35.3 + diff --git a/patches.suse/platform-x86-i2c-multi-instantiate-Rename-it-for-a-g.patch b/patches.suse/platform-x86-i2c-multi-instantiate-Rename-it-for-a-g.patch new file mode 100644 index 0000000..048c5ad --- /dev/null +++ b/patches.suse/platform-x86-i2c-multi-instantiate-Rename-it-for-a-g.patch @@ -0,0 +1,277 @@ +From 5e63b2ea3dfbab9307e197004a3c5ee4e1442582 Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Fri, 21 Jan 2022 17:24:27 +0000 +Subject: [PATCH] platform/x86: i2c-multi-instantiate: Rename it for a generic serial driver name +Git-commit: 5e63b2ea3dfbab9307e197004a3c5ee4e1442582 +Patch-mainline: v5.18-rc1 +References: bsc#1203699 + +Rename I2C multi instantiate driver to serial-multi-instantiate for +upcoming addition of SPI support + +Signed-off-by: Lucas Tanure +Signed-off-by: Stefan Binding +Link: https://lore.kernel.org/r/20220121172431.6876-6-sbinding@opensource.cirrus.com +Reviewed-by: Hans de Goede +Signed-off-by: Hans de Goede +Acked-by: Takashi Iwai + +--- + MAINTAINERS | 4 + drivers/acpi/scan.c | 13 - + drivers/platform/x86/Kconfig | 10 - + drivers/platform/x86/Makefile | 2 + drivers/platform/x86/serial-multi-instantiate.c | 173 ++++++++++++++++++++++++ + 5 files changed, 188 insertions(+), 14 deletions(-) + delete mode 100644 drivers/platform/x86/i2c-multi-instantiate.c + create mode 100644 drivers/platform/x86/serial-multi-instantiate.c + +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -396,11 +396,11 @@ L: linux-arm-kernel@lists.infradead.org + S: Maintained + F: drivers/acpi/arm64 + +-ACPI I2C MULTI INSTANTIATE DRIVER ++ACPI SERIAL MULTI INSTANTIATE DRIVER + M: Hans de Goede + L: platform-driver-x86@vger.kernel.org + S: Maintained +-F: drivers/platform/x86/i2c-multi-instantiate.c ++F: drivers/platform/x86/serial-multi-instantiate.c + + ACPI PMIC DRIVERS + M: "Rafael J. Wysocki" +--- a/drivers/acpi/scan.c ++++ b/drivers/acpi/scan.c +@@ -1692,12 +1692,13 @@ static bool acpi_device_enumeration_by_p + bool is_serial_bus_slave = false; + static const struct acpi_device_id ignore_serial_bus_ids[] = { + /* +- * These devices have multiple I2cSerialBus resources and an i2c-client +- * must be instantiated for each, each with its own i2c_device_id. +- * Normally we only instantiate an i2c-client for the first resource, +- * using the ACPI HID as id. These special cases are handled by the +- * drivers/platform/x86/i2c-multi-instantiate.c driver, which knows +- * which i2c_device_id to use for each resource. ++ * These devices have multiple SerialBus resources and a client ++ * device must be instantiated for each of them, each with ++ * its own device id. ++ * Normally we only instantiate one client device for the first ++ * resource, using the ACPI HID as id. These special cases are handled ++ * by the drivers/platform/x86/serial-multi-instantiate.c driver, which ++ * knows which client device id to use for each resource. + */ + {"BSG1160", }, + {"BSG2150", }, +--- a/drivers/platform/x86/Kconfig ++++ b/drivers/platform/x86/Kconfig +@@ -1037,16 +1037,16 @@ config TOPSTAR_LAPTOP + + If you have a Topstar laptop, say Y or M here. + +-config I2C_MULTI_INSTANTIATE +- tristate "I2C multi instantiate pseudo device driver" ++config SERIAL_MULTI_INSTANTIATE ++ tristate "Serial bus multi instantiate pseudo device driver" + depends on I2C && ACPI + help +- Some ACPI-based systems list multiple i2c-devices in a single ACPI +- firmware-node. This driver will instantiate separate i2c-clients ++ Some ACPI-based systems list multiple devices in a single ACPI ++ firmware-node. This driver will instantiate separate clients + for each device in the firmware-node. + + To compile this driver as a module, choose M here: the module +- will be called i2c-multi-instantiate. ++ will be called serial-multi-instantiate. + + config MLX_PLATFORM + tristate "Mellanox Technologies platform support" +--- a/drivers/platform/x86/Makefile ++++ b/drivers/platform/x86/Makefile +@@ -111,7 +111,7 @@ obj-$(CONFIG_TOPSTAR_LAPTOP) += topstar- + + # Platform drivers + obj-$(CONFIG_FW_ATTR_CLASS) += firmware_attributes_class.o +-obj-$(CONFIG_I2C_MULTI_INSTANTIATE) += i2c-multi-instantiate.o ++obj-$(CONFIG_SERIAL_MULTI_INSTANTIATE) += serial-multi-instantiate.o + obj-$(CONFIG_MLX_PLATFORM) += mlx-platform.o + obj-$(CONFIG_TOUCHSCREEN_DMI) += touchscreen_dmi.o + obj-$(CONFIG_WIRELESS_HOTKEY) += wireless-hotkey.o +--- /dev/null ++++ b/drivers/platform/x86/serial-multi-instantiate.c +@@ -0,0 +1,173 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Serial multi-instantiate driver, pseudo driver to instantiate multiple ++ * client devices from a single fwnode. ++ * ++ * Copyright 2018 Hans de Goede ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define IRQ_RESOURCE_TYPE GENMASK(1, 0) ++#define IRQ_RESOURCE_NONE 0 ++#define IRQ_RESOURCE_GPIO 1 ++#define IRQ_RESOURCE_APIC 2 ++ ++struct smi_instance { ++ const char *type; ++ unsigned int flags; ++ int irq_idx; ++}; ++ ++struct smi { ++ int i2c_num; ++ struct i2c_client *i2c_devs[]; ++}; ++ ++static int smi_probe(struct platform_device *pdev) ++{ ++ struct i2c_board_info board_info = {}; ++ const struct smi_instance *inst; ++ struct device *dev = &pdev->dev; ++ struct acpi_device *adev; ++ struct smi *smi; ++ char name[32]; ++ int i, ret; ++ ++ inst = device_get_match_data(dev); ++ if (!inst) { ++ dev_err(dev, "Error ACPI match data is missing\n"); ++ return -ENODEV; ++ } ++ ++ adev = ACPI_COMPANION(dev); ++ ++ /* Count number of clients to instantiate */ ++ ret = i2c_acpi_client_count(adev); ++ if (ret < 0) ++ return ret; ++ ++ smi = devm_kmalloc(dev, struct_size(smi, i2c_devs, ret), GFP_KERNEL); ++ if (!smi) ++ return -ENOMEM; ++ ++ smi->i2c_num = ret; ++ ++ for (i = 0; i < smi->i2c_num && inst[i].type; i++) { ++ memset(&board_info, 0, sizeof(board_info)); ++ strlcpy(board_info.type, inst[i].type, I2C_NAME_SIZE); ++ snprintf(name, sizeof(name), "%s-%s.%d", dev_name(dev), inst[i].type, i); ++ board_info.dev_name = name; ++ switch (inst[i].flags & IRQ_RESOURCE_TYPE) { ++ case IRQ_RESOURCE_GPIO: ++ ret = acpi_dev_gpio_irq_get(adev, inst[i].irq_idx); ++ if (ret < 0) { ++ dev_err(dev, "Error requesting irq at index %d: %d\n", ++ inst[i].irq_idx, ret); ++ goto error; ++ } ++ board_info.irq = ret; ++ break; ++ case IRQ_RESOURCE_APIC: ++ ret = platform_get_irq(pdev, inst[i].irq_idx); ++ if (ret < 0) { ++ dev_dbg(dev, "Error requesting irq at index %d: %d\n", ++ inst[i].irq_idx, ret); ++ goto error; ++ } ++ board_info.irq = ret; ++ break; ++ default: ++ board_info.irq = 0; ++ break; ++ } ++ smi->i2c_devs[i] = i2c_acpi_new_device(dev, i, &board_info); ++ if (IS_ERR(smi->i2c_devs[i])) { ++ ret = dev_err_probe(dev, PTR_ERR(smi->i2c_devs[i]), ++ "Error creating i2c-client, idx %d\n", i); ++ goto error; ++ } ++ } ++ if (i < smi->i2c_num) { ++ dev_err(dev, "Error finding driver, idx %d\n", i); ++ ret = -ENODEV; ++ goto error; ++ } ++ ++ platform_set_drvdata(pdev, smi); ++ return 0; ++ ++error: ++ while (--i >= 0) ++ i2c_unregister_device(smi->i2c_devs[i]); ++ ++ return ret; ++} ++ ++static int smi_remove(struct platform_device *pdev) ++{ ++ struct smi *smi = platform_get_drvdata(pdev); ++ int i; ++ ++ for (i = 0; i < smi->i2c_num; i++) ++ i2c_unregister_device(smi->i2c_devs[i]); ++ ++ return 0; ++} ++ ++static const struct smi_instance bsg1160_data[] = { ++ { "bmc150_accel", IRQ_RESOURCE_GPIO, 0 }, ++ { "bmc150_magn" }, ++ { "bmg160" }, ++ {} ++}; ++ ++static const struct smi_instance bsg2150_data[] = { ++ { "bmc150_accel", IRQ_RESOURCE_GPIO, 0 }, ++ { "bmc150_magn" }, ++ /* The resources describe a 3th client, but it is not really there. */ ++ { "bsg2150_dummy_dev" }, ++ {} ++}; ++ ++static const struct smi_instance int3515_data[] = { ++ { "tps6598x", IRQ_RESOURCE_APIC, 0 }, ++ { "tps6598x", IRQ_RESOURCE_APIC, 1 }, ++ { "tps6598x", IRQ_RESOURCE_APIC, 2 }, ++ { "tps6598x", IRQ_RESOURCE_APIC, 3 }, ++ {} ++}; ++ ++/* ++ * Note new device-ids must also be added to ignore_serial_bus_ids in ++ * drivers/acpi/scan.c: acpi_device_enumeration_by_parent(). ++ */ ++static const struct acpi_device_id smi_acpi_ids[] = { ++ { "BSG1160", (unsigned long)bsg1160_data }, ++ { "BSG2150", (unsigned long)bsg2150_data }, ++ { "INT3515", (unsigned long)int3515_data }, ++ { } ++}; ++MODULE_DEVICE_TABLE(acpi, smi_acpi_ids); ++ ++static struct platform_driver smi_driver = { ++ .driver = { ++ .name = "Serial bus multi instantiate pseudo device driver", ++ .acpi_match_table = smi_acpi_ids, ++ }, ++ .probe = smi_probe, ++ .remove = smi_remove, ++}; ++module_platform_driver(smi_driver); ++ ++MODULE_DESCRIPTION("Serial multi instantiate pseudo device driver"); ++MODULE_AUTHOR("Hans de Goede "); ++MODULE_LICENSE("GPL"); diff --git a/patches.suse/platform-x86-msi-laptop-Fix-old-ec-check-for-backlig.patch b/patches.suse/platform-x86-msi-laptop-Fix-old-ec-check-for-backlig.patch new file mode 100644 index 0000000..e2dac18 --- /dev/null +++ b/patches.suse/platform-x86-msi-laptop-Fix-old-ec-check-for-backlig.patch @@ -0,0 +1,58 @@ +From 83ac7a1c2ed5f17caa07cbbc84bad3c05dc3bf22 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Thu, 25 Aug 2022 16:13:34 +0200 +Subject: [PATCH] platform/x86: msi-laptop: Fix old-ec check for backlight registering +Git-commit: 83ac7a1c2ed5f17caa07cbbc84bad3c05dc3bf22 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Commit 2cc6c717799f ("msi-laptop: Port to new backlight interface +selection API") replaced this check: + + if (!quirks->old_ec_model || acpi_video_backlight_support()) + pr_info("Brightness ignored, ..."); + else + do_register(); + +With: + + if (quirks->old_ec_model || + acpi_video_get_backlight_type() == acpi_backlight_vendor) + do_register(); + +But since the do_register() part was part of the else branch, the entire +condition should be inverted. So not only the 2 statements on either +side of the || should be inverted, but the || itself should be replaced +with a &&. + +In practice this has likely not been an issue because the new-ec models +(old_ec_model==false) likely all support ACPI video backlight control, +making acpi_video_get_backlight_type() return acpi_backlight_video +turning the second part of the || also false when old_ec_model == false. + +Fixes: 2cc6c717799f ("msi-laptop: Port to new backlight interface selection API") +Signed-off-by: Hans de Goede +Link: https://lore.kernel.org/r/20220825141336.208597-1-hdegoede@redhat.com +Acked-by: Takashi Iwai + +--- + drivers/platform/x86/msi-laptop.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c +index 93ef8851b93e..54170172a666 100644 +--- a/drivers/platform/x86/msi-laptop.c ++++ b/drivers/platform/x86/msi-laptop.c +@@ -1047,8 +1047,7 @@ static int __init msi_init(void) + return -EINVAL; + + /* Register backlight stuff */ +- +- if (quirks->old_ec_model || ++ if (quirks->old_ec_model && + acpi_video_get_backlight_type() == acpi_backlight_vendor) { + struct backlight_properties props; + memset(&props, 0, sizeof(struct backlight_properties)); +-- +2.35.3 + diff --git a/patches.suse/platform-x86-msi-laptop-Fix-resource-cleanup.patch b/patches.suse/platform-x86-msi-laptop-Fix-resource-cleanup.patch new file mode 100644 index 0000000..133e271 --- /dev/null +++ b/patches.suse/platform-x86-msi-laptop-Fix-resource-cleanup.patch @@ -0,0 +1,40 @@ +From 5523632aa10f906dfe2eb714ee748590dc7fc6b1 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Thu, 25 Aug 2022 16:13:36 +0200 +Subject: [PATCH] platform/x86: msi-laptop: Fix resource cleanup +Git-commit: 5523632aa10f906dfe2eb714ee748590dc7fc6b1 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Fix the input-device not getting free-ed on probe-errors and +fix the msi_touchpad_dwork not getting cancelled on neither +probe-errors nor on remove. + +Fixes: 143a4c0284dc ("msi-laptop: send out touchpad on/off key") +Signed-off-by: Hans de Goede +Link: https://lore.kernel.org/r/20220825141336.208597-3-hdegoede@redhat.com +Acked-by: Takashi Iwai + +--- + drivers/platform/x86/msi-laptop.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/platform/x86/msi-laptop.c ++++ b/drivers/platform/x86/msi-laptop.c +@@ -1116,6 +1116,8 @@ fail_create_attr: + fail_create_group: + if (quirks->load_scm_model) { + i8042_remove_filter(msi_laptop_i8042_filter); ++ cancel_delayed_work_sync(&msi_touchpad_dwork); ++ input_unregister_device(msi_laptop_input_dev); + cancel_delayed_work_sync(&msi_rfkill_dwork); + cancel_work_sync(&msi_rfkill_work); + rfkill_cleanup(); +@@ -1136,6 +1138,7 @@ static void __exit msi_cleanup(void) + { + if (quirks->load_scm_model) { + i8042_remove_filter(msi_laptop_i8042_filter); ++ cancel_delayed_work_sync(&msi_touchpad_dwork); + input_unregister_device(msi_laptop_input_dev); + cancel_delayed_work_sync(&msi_rfkill_dwork); + cancel_work_sync(&msi_rfkill_work); diff --git a/patches.suse/platform-x86-serial-multi-instantiate-Add-CLSA0101-L.patch b/patches.suse/platform-x86-serial-multi-instantiate-Add-CLSA0101-L.patch new file mode 100644 index 0000000..dc4818c --- /dev/null +++ b/patches.suse/platform-x86-serial-multi-instantiate-Add-CLSA0101-L.patch @@ -0,0 +1,35 @@ +From 88392a0dd0ab263edb4ca416ebdecabd8289158a Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Wed, 27 Jul 2022 10:59:24 +0100 +Subject: [PATCH] platform/x86: serial-multi-instantiate: Add CLSA0101 Laptop +Git-commit: 88392a0dd0ab263edb4ca416ebdecabd8289158a +Patch-mainline: v6.0-rc2 +References: bsc#1203699 + +The device CLSA0101 has two instances of CS35L41 +connected by I2C. + +Signed-off-by: Lucas Tanure +Link: https://lore.kernel.org/r/20220727095924.80884-5-tanureal@opensource.cirrus.com +Link: https://lore.kernel.org/r/20220816194639.13870-1-cam@neo-zeon.de +Signed-off-by: Takashi Iwai + +--- + drivers/platform/x86/serial-multi-instantiate.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/platform/x86/serial-multi-instantiate.c b/drivers/platform/x86/serial-multi-instantiate.c +index 1e8063b7c169..e98007197cf5 100644 +--- a/drivers/platform/x86/serial-multi-instantiate.c ++++ b/drivers/platform/x86/serial-multi-instantiate.c +@@ -329,6 +329,7 @@ static const struct acpi_device_id smi_acpi_ids[] = { + { "CSC3551", (unsigned long)&cs35l41_hda }, + /* Non-conforming _HID for Cirrus Logic already released */ + { "CLSA0100", (unsigned long)&cs35l41_hda }, ++ { "CLSA0101", (unsigned long)&cs35l41_hda }, + { } + }; + MODULE_DEVICE_TABLE(acpi, smi_acpi_ids); +-- +2.35.3 + diff --git a/patches.suse/platform-x86-serial-multi-instantiate-Add-SPI-suppor.patch b/patches.suse/platform-x86-serial-multi-instantiate-Add-SPI-suppor.patch new file mode 100644 index 0000000..e7bef4e --- /dev/null +++ b/patches.suse/platform-x86-serial-multi-instantiate-Add-SPI-suppor.patch @@ -0,0 +1,299 @@ +From 68f201f9061c000d7a4a9f359f021b1cd535d62b Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Fri, 21 Jan 2022 17:24:29 +0000 +Subject: [PATCH] platform/x86: serial-multi-instantiate: Add SPI support +Git-commit: 68f201f9061c000d7a4a9f359f021b1cd535d62b +Patch-mainline: v5.18-rc1 +References: bsc#1203699 + +Add support for spi bus in serial-multi-instantiate driver + +Some peripherals can have either a I2C or a SPI connection +to the host (but not both) but use the same HID for both +types. So it is not possible to use the HID to determine +whether it is I2C or SPI. The driver must check the node +to see if it contains I2cSerialBus or SpiSerialBus entries. + +For backwards-compatibility with the existing nodes I2C is +checked first and if such entries are found ONLY I2C devices +are created. Since some existing nodes that were already +handled by this driver could also contain unrelated +SpiSerialBus nodes that were previously ignored, and this +preserves that behavior. If there is ever a need to handle +a node where both I2C and SPI devices must be instantiated +this can be added in future. + +Signed-off-by: Stefan Binding +Link: https://lore.kernel.org/r/20220121172431.6876-8-sbinding@opensource.cirrus.com +Reviewed-by: Hans de Goede +Signed-off-by: Hans de Goede +Acked-by: Takashi Iwai + +--- + drivers/platform/x86/Kconfig | 2 +- + .../platform/x86/serial-multi-instantiate.c | 173 +++++++++++++++--- + 2 files changed, 150 insertions(+), 25 deletions(-) + +diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig +index 2e656909a866..8d1eec208854 100644 +--- a/drivers/platform/x86/Kconfig ++++ b/drivers/platform/x86/Kconfig +@@ -992,7 +992,7 @@ config TOPSTAR_LAPTOP + + config SERIAL_MULTI_INSTANTIATE + tristate "Serial bus multi instantiate pseudo device driver" +- depends on I2C && ACPI ++ depends on I2C && SPI && ACPI + help + Some ACPI-based systems list multiple devices in a single ACPI + firmware-node. This driver will instantiate separate clients +diff --git a/drivers/platform/x86/serial-multi-instantiate.c b/drivers/platform/x86/serial-multi-instantiate.c +index 1eb29bec405f..e2fd73905312 100644 +--- a/drivers/platform/x86/serial-multi-instantiate.c ++++ b/drivers/platform/x86/serial-multi-instantiate.c +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + #include + + #define IRQ_RESOURCE_TYPE GENMASK(1, 0) +@@ -21,15 +22,28 @@ + #define IRQ_RESOURCE_GPIO 1 + #define IRQ_RESOURCE_APIC 2 + ++enum smi_bus_type { ++ SMI_I2C, ++ SMI_SPI, ++ SMI_AUTO_DETECT, ++}; ++ + struct smi_instance { + const char *type; + unsigned int flags; + int irq_idx; + }; + ++struct smi_node { ++ enum smi_bus_type bus_type; ++ struct smi_instance instances[]; ++}; ++ + struct smi { + int i2c_num; ++ int spi_num; + struct i2c_client **i2c_devs; ++ struct spi_device **spi_devs; + }; + + static int smi_get_irq(struct platform_device *pdev, struct acpi_device *adev, +@@ -59,6 +73,94 @@ static void smi_devs_unregister(struct smi *smi) + { + while (smi->i2c_num > 0) + i2c_unregister_device(smi->i2c_devs[--smi->i2c_num]); ++ ++ while (smi->spi_num > 0) ++ spi_unregister_device(smi->spi_devs[--smi->spi_num]); ++} ++ ++/** ++ * smi_spi_probe - Instantiate multiple SPI devices from inst array ++ * @pdev: Platform device ++ * @adev: ACPI device ++ * @smi: Internal struct for Serial multi instantiate driver ++ * @inst_array: Array of instances to probe ++ * ++ * Returns the number of SPI devices instantiate, Zero if none is found or a negative error code. ++ */ ++static int smi_spi_probe(struct platform_device *pdev, struct acpi_device *adev, struct smi *smi, ++ const struct smi_instance *inst_array) ++{ ++ struct device *dev = &pdev->dev; ++ struct spi_controller *ctlr; ++ struct spi_device *spi_dev; ++ char name[50]; ++ int i, ret, count; ++ ++ ret = acpi_spi_count_resources(adev); ++ if (ret < 0) ++ return ret; ++ else if (!ret) ++ return -ENODEV; ++ ++ count = ret; ++ ++ smi->spi_devs = devm_kcalloc(dev, count, sizeof(*smi->spi_devs), GFP_KERNEL); ++ if (!smi->spi_devs) ++ return -ENOMEM; ++ ++ for (i = 0; i < count && inst_array[i].type; i++) { ++ ++ spi_dev = acpi_spi_device_alloc(NULL, adev, i); ++ if (IS_ERR(spi_dev)) { ++ ret = PTR_ERR(spi_dev); ++ dev_err_probe(dev, ret, "failed to allocate SPI device %s from ACPI: %d\n", ++ dev_name(&adev->dev), ret); ++ goto error; ++ } ++ ++ ctlr = spi_dev->controller; ++ ++ strscpy(spi_dev->modalias, inst_array[i].type, sizeof(spi_dev->modalias)); ++ ++ ret = smi_get_irq(pdev, adev, &inst_array[i]); ++ if (ret < 0) { ++ spi_dev_put(spi_dev); ++ goto error; ++ } ++ spi_dev->irq = ret; ++ ++ snprintf(name, sizeof(name), "%s-%s-%s.%d", dev_name(&ctlr->dev), dev_name(dev), ++ inst_array[i].type, i); ++ spi_dev->dev.init_name = name; ++ ++ ret = spi_add_device(spi_dev); ++ if (ret) { ++ dev_err_probe(&ctlr->dev, ret, ++ "failed to add SPI device %s from ACPI: %d\n", ++ dev_name(&adev->dev), ret); ++ spi_dev_put(spi_dev); ++ goto error; ++ } ++ ++ dev_dbg(dev, "SPI device %s using chip select %u", name, spi_dev->chip_select); ++ ++ smi->spi_devs[i] = spi_dev; ++ smi->spi_num++; ++ } ++ ++ if (smi->spi_num < count) { ++ dev_dbg(dev, "Error finding driver, idx %d\n", i); ++ ret = -ENODEV; ++ goto error; ++ } ++ ++ dev_info(dev, "Instantiated %d SPI devices.\n", smi->spi_num); ++ ++ return 0; ++error: ++ smi_devs_unregister(smi); ++ ++ return ret; + } + + /** +@@ -126,8 +228,8 @@ static int smi_i2c_probe(struct platform_device *pdev, struct acpi_device *adev, + + static int smi_probe(struct platform_device *pdev) + { +- const struct smi_instance *inst_array; + struct device *dev = &pdev->dev; ++ const struct smi_node *node; + struct acpi_device *adev; + struct smi *smi; + +@@ -135,8 +237,8 @@ static int smi_probe(struct platform_device *pdev) + if (!adev) + return -ENODEV; + +- inst_array = device_get_match_data(dev); +- if (!inst_array) { ++ node = device_get_match_data(dev); ++ if (!node) { + dev_dbg(dev, "Error ACPI match data is missing\n"); + return -ENODEV; + } +@@ -147,7 +249,21 @@ static int smi_probe(struct platform_device *pdev) + + platform_set_drvdata(pdev, smi); + +- return smi_i2c_probe(pdev, adev, smi, inst_array); ++ switch (node->bus_type) { ++ case SMI_I2C: ++ return smi_i2c_probe(pdev, adev, smi, node->instances); ++ case SMI_SPI: ++ return smi_spi_probe(pdev, adev, smi, node->instances); ++ case SMI_AUTO_DETECT: ++ if (i2c_acpi_client_count(adev) > 0) ++ return smi_i2c_probe(pdev, adev, smi, node->instances); ++ else ++ return smi_spi_probe(pdev, adev, smi, node->instances); ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; /* never reached */ + } + + static int smi_remove(struct platform_device *pdev) +@@ -159,27 +275,36 @@ static int smi_remove(struct platform_device *pdev) + return 0; + } + +-static const struct smi_instance bsg1160_data[] = { +- { "bmc150_accel", IRQ_RESOURCE_GPIO, 0 }, +- { "bmc150_magn" }, +- { "bmg160" }, +- {} ++static const struct smi_node bsg1160_data = { ++ .instances = { ++ { "bmc150_accel", IRQ_RESOURCE_GPIO, 0 }, ++ { "bmc150_magn" }, ++ { "bmg160" }, ++ {} ++ }, ++ .bus_type = SMI_I2C, + }; + +-static const struct smi_instance bsg2150_data[] = { +- { "bmc150_accel", IRQ_RESOURCE_GPIO, 0 }, +- { "bmc150_magn" }, +- /* The resources describe a 3th client, but it is not really there. */ +- { "bsg2150_dummy_dev" }, +- {} ++static const struct smi_node bsg2150_data = { ++ .instances = { ++ { "bmc150_accel", IRQ_RESOURCE_GPIO, 0 }, ++ { "bmc150_magn" }, ++ /* The resources describe a 3th client, but it is not really there. */ ++ { "bsg2150_dummy_dev" }, ++ {} ++ }, ++ .bus_type = SMI_I2C, + }; + +-static const struct smi_instance int3515_data[] = { +- { "tps6598x", IRQ_RESOURCE_APIC, 0 }, +- { "tps6598x", IRQ_RESOURCE_APIC, 1 }, +- { "tps6598x", IRQ_RESOURCE_APIC, 2 }, +- { "tps6598x", IRQ_RESOURCE_APIC, 3 }, +- {} ++static const struct smi_node int3515_data = { ++ .instances = { ++ { "tps6598x", IRQ_RESOURCE_APIC, 0 }, ++ { "tps6598x", IRQ_RESOURCE_APIC, 1 }, ++ { "tps6598x", IRQ_RESOURCE_APIC, 2 }, ++ { "tps6598x", IRQ_RESOURCE_APIC, 3 }, ++ {} ++ }, ++ .bus_type = SMI_I2C, + }; + + /* +@@ -187,9 +312,9 @@ static const struct smi_instance int3515_data[] = { + * drivers/acpi/scan.c: acpi_device_enumeration_by_parent(). + */ + static const struct acpi_device_id smi_acpi_ids[] = { +- { "BSG1160", (unsigned long)bsg1160_data }, +- { "BSG2150", (unsigned long)bsg2150_data }, +- { "INT3515", (unsigned long)int3515_data }, ++ { "BSG1160", (unsigned long)&bsg1160_data }, ++ { "BSG2150", (unsigned long)&bsg2150_data }, ++ { "INT3515", (unsigned long)&int3515_data }, + { } + }; + MODULE_DEVICE_TABLE(acpi, smi_acpi_ids); +-- +2.35.3 + diff --git a/patches.suse/platform-x86-serial-multi-instantiate-Reorganize-I2C.patch b/patches.suse/platform-x86-serial-multi-instantiate-Reorganize-I2C.patch new file mode 100644 index 0000000..7d66cb4 --- /dev/null +++ b/patches.suse/platform-x86-serial-multi-instantiate-Reorganize-I2C.patch @@ -0,0 +1,218 @@ +From 35a36cbb7b1ce7596fc03962f7ce261b2e908d1f Mon Sep 17 00:00:00 2001 +From: Lucas Tanure +Date: Fri, 21 Jan 2022 17:24:28 +0000 +Subject: [PATCH] platform/x86: serial-multi-instantiate: Reorganize I2C functions +Git-commit: 35a36cbb7b1ce7596fc03962f7ce261b2e908d1f +Patch-mainline: v5.18-rc1 +References: bsc#1203699 + +Reorganize I2C functions to accommodate SPI support +Split the probe and factor out parts of the code +that will be used in the SPI support +Also switched from strlcpy() to strscpy() + +Signed-off-by: Lucas Tanure +Signed-off-by: Stefan Binding +Link: https://lore.kernel.org/r/20220121172431.6876-7-sbinding@opensource.cirrus.com +Reviewed-by: Hans de Goede +Signed-off-by: Hans de Goede +Acked-by: Takashi Iwai + +--- + .../platform/x86/serial-multi-instantiate.c | 144 +++++++++++------- + 1 file changed, 90 insertions(+), 54 deletions(-) + +diff --git a/drivers/platform/x86/serial-multi-instantiate.c b/drivers/platform/x86/serial-multi-instantiate.c +index 9af5bcd466d1..1eb29bec405f 100644 +--- a/drivers/platform/x86/serial-multi-instantiate.c ++++ b/drivers/platform/x86/serial-multi-instantiate.c +@@ -29,96 +29,132 @@ struct smi_instance { + + struct smi { + int i2c_num; +- struct i2c_client *i2c_devs[]; ++ struct i2c_client **i2c_devs; + }; + +-static int smi_probe(struct platform_device *pdev) ++static int smi_get_irq(struct platform_device *pdev, struct acpi_device *adev, ++ const struct smi_instance *inst) ++{ ++ int ret; ++ ++ switch (inst->flags & IRQ_RESOURCE_TYPE) { ++ case IRQ_RESOURCE_GPIO: ++ ret = acpi_dev_gpio_irq_get(adev, inst->irq_idx); ++ break; ++ case IRQ_RESOURCE_APIC: ++ ret = platform_get_irq(pdev, inst->irq_idx); ++ break; ++ default: ++ return 0; ++ } ++ ++ if (ret < 0) ++ dev_err_probe(&pdev->dev, ret, "Error requesting irq at index %d: %d\n", ++ inst->irq_idx, ret); ++ ++ return ret; ++} ++ ++static void smi_devs_unregister(struct smi *smi) ++{ ++ while (smi->i2c_num > 0) ++ i2c_unregister_device(smi->i2c_devs[--smi->i2c_num]); ++} ++ ++/** ++ * smi_i2c_probe - Instantiate multiple I2C devices from inst array ++ * @pdev: Platform device ++ * @adev: ACPI device ++ * @smi: Internal struct for Serial multi instantiate driver ++ * @inst_array: Array of instances to probe ++ * ++ * Returns the number of I2C devices instantiate, Zero if none is found or a negative error code. ++ */ ++static int smi_i2c_probe(struct platform_device *pdev, struct acpi_device *adev, struct smi *smi, ++ const struct smi_instance *inst_array) + { + struct i2c_board_info board_info = {}; +- const struct smi_instance *inst; + struct device *dev = &pdev->dev; +- struct acpi_device *adev; +- struct smi *smi; + char name[32]; +- int i, ret; ++ int i, ret, count; + +- inst = device_get_match_data(dev); +- if (!inst) { +- dev_err(dev, "Error ACPI match data is missing\n"); +- return -ENODEV; +- } +- +- adev = ACPI_COMPANION(dev); +- +- /* Count number of clients to instantiate */ + ret = i2c_acpi_client_count(adev); + if (ret < 0) + return ret; ++ else if (!ret) ++ return -ENODEV; + +- smi = devm_kmalloc(dev, struct_size(smi, i2c_devs, ret), GFP_KERNEL); +- if (!smi) +- return -ENOMEM; ++ count = ret; + +- smi->i2c_num = ret; ++ smi->i2c_devs = devm_kcalloc(dev, count, sizeof(*smi->i2c_devs), GFP_KERNEL); ++ if (!smi->i2c_devs) ++ return -ENOMEM; + +- for (i = 0; i < smi->i2c_num && inst[i].type; i++) { ++ for (i = 0; i < count && inst_array[i].type; i++) { + memset(&board_info, 0, sizeof(board_info)); +- strlcpy(board_info.type, inst[i].type, I2C_NAME_SIZE); +- snprintf(name, sizeof(name), "%s-%s.%d", dev_name(dev), inst[i].type, i); ++ strscpy(board_info.type, inst_array[i].type, I2C_NAME_SIZE); ++ snprintf(name, sizeof(name), "%s-%s.%d", dev_name(dev), inst_array[i].type, i); + board_info.dev_name = name; +- switch (inst[i].flags & IRQ_RESOURCE_TYPE) { +- case IRQ_RESOURCE_GPIO: +- ret = acpi_dev_gpio_irq_get(adev, inst[i].irq_idx); +- if (ret < 0) { +- dev_err(dev, "Error requesting irq at index %d: %d\n", +- inst[i].irq_idx, ret); +- goto error; +- } +- board_info.irq = ret; +- break; +- case IRQ_RESOURCE_APIC: +- ret = platform_get_irq(pdev, inst[i].irq_idx); +- if (ret < 0) { +- dev_dbg(dev, "Error requesting irq at index %d: %d\n", +- inst[i].irq_idx, ret); +- goto error; +- } +- board_info.irq = ret; +- break; +- default: +- board_info.irq = 0; +- break; +- } ++ ++ ret = smi_get_irq(pdev, adev, &inst_array[i]); ++ if (ret < 0) ++ goto error; ++ board_info.irq = ret; ++ + smi->i2c_devs[i] = i2c_acpi_new_device(dev, i, &board_info); + if (IS_ERR(smi->i2c_devs[i])) { + ret = dev_err_probe(dev, PTR_ERR(smi->i2c_devs[i]), + "Error creating i2c-client, idx %d\n", i); + goto error; + } ++ smi->i2c_num++; + } +- if (i < smi->i2c_num) { +- dev_err(dev, "Error finding driver, idx %d\n", i); ++ if (smi->i2c_num < count) { ++ dev_dbg(dev, "Error finding driver, idx %d\n", i); + ret = -ENODEV; + goto error; + } + +- platform_set_drvdata(pdev, smi); +- return 0; ++ dev_info(dev, "Instantiated %d I2C devices.\n", smi->i2c_num); + ++ return 0; + error: +- while (--i >= 0) +- i2c_unregister_device(smi->i2c_devs[i]); ++ smi_devs_unregister(smi); + + return ret; + } + ++static int smi_probe(struct platform_device *pdev) ++{ ++ const struct smi_instance *inst_array; ++ struct device *dev = &pdev->dev; ++ struct acpi_device *adev; ++ struct smi *smi; ++ ++ adev = ACPI_COMPANION(dev); ++ if (!adev) ++ return -ENODEV; ++ ++ inst_array = device_get_match_data(dev); ++ if (!inst_array) { ++ dev_dbg(dev, "Error ACPI match data is missing\n"); ++ return -ENODEV; ++ } ++ ++ smi = devm_kzalloc(dev, sizeof(*smi), GFP_KERNEL); ++ if (!smi) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, smi); ++ ++ return smi_i2c_probe(pdev, adev, smi, inst_array); ++} ++ + static int smi_remove(struct platform_device *pdev) + { + struct smi *smi = platform_get_drvdata(pdev); +- int i; + +- for (i = 0; i < smi->i2c_num; i++) +- i2c_unregister_device(smi->i2c_devs[i]); ++ smi_devs_unregister(smi); + + return 0; + } +-- +2.35.3 + diff --git a/patches.suse/powercap-Add-Power-Limit4-support-for-Alder-Lake-SoC.patch b/patches.suse/powercap-Add-Power-Limit4-support-for-Alder-Lake-SoC.patch new file mode 100644 index 0000000..898476a --- /dev/null +++ b/patches.suse/powercap-Add-Power-Limit4-support-for-Alder-Lake-SoC.patch @@ -0,0 +1,28 @@ +From: Sumeet Pawnikar +Subject: powercap: Add Power Limit4 support for Alder Lake SoC +References: jsc#PED-769 +Patch-Mainline: v5.15-rc1 +Git-commit: 1cc5b9a411e43aa2cb5060429ede6c50217bad90 + + +Add Power Limit4 support for Alder Lake SoC. + +Signed-off-by: Sumeet Pawnikar +Acked-by: Zhang Rui +Signed-off-by: Rafael J. Wysocki + + +Signed-off-by: +diff --git a/drivers/powercap/intel_rapl_msr.c b/drivers/powercap/intel_rapl_msr.c +index cc3b22881bfe..1be45f36ab6c 100644 +--- a/drivers/powercap/intel_rapl_msr.c ++++ b/drivers/powercap/intel_rapl_msr.c +@@ -138,6 +138,8 @@ static int rapl_msr_write_raw(int cpu, struct reg_action *ra) + /* List of verified CPUs. */ + static const struct x86_cpu_id pl4_support_ids[] = { + { X86_VENDOR_INTEL, 6, INTEL_FAM6_TIGERLAKE_L, X86_FEATURE_ANY }, ++ { X86_VENDOR_INTEL, 6, INTEL_FAM6_ALDERLAKE, X86_FEATURE_ANY }, ++ { X86_VENDOR_INTEL, 6, INTEL_FAM6_ALDERLAKE_L, X86_FEATURE_ANY }, + {} + }; + diff --git a/patches.suse/powercap-RAPL-Add-Power-Limit4-support-for-Alder-Lake-N-and-Raptor-Lake-P.patch b/patches.suse/powercap-RAPL-Add-Power-Limit4-support-for-Alder-Lake-N-and-Raptor-Lake-P.patch new file mode 100644 index 0000000..5307701 --- /dev/null +++ b/patches.suse/powercap-RAPL-Add-Power-Limit4-support-for-Alder-Lake-N-and-Raptor-Lake-P.patch @@ -0,0 +1,33 @@ +From: Sumeet Pawnikar +Subject: powercap: RAPL: Add Power Limit4 support for Alder Lake-N and Raptor Lake-P +References: jsc#PED-769 +Patch-Mainline: v6.0-rc1 +Git-commit: b08b95cf30f53b674bdef510d4cfd0623199b036 + + +Add Alder Lake-N and Raptor Lake-P to the list of processor models +for which Power Limit4 is supported by the Intel RAPL driver. + +Signed-off-by: Sumeet Pawnikar +Reviewed-by: Srinivas Pandruvada +Reviewed-by: Andy Shevchenko +Signed-off-by: Rafael J. Wysocki + + +Signed-off-by: +--- + drivers/powercap/intel_rapl_msr.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/powercap/intel_rapl_msr.c ++++ b/drivers/powercap/intel_rapl_msr.c +@@ -140,7 +140,9 @@ static const struct x86_cpu_id pl4_suppo + { X86_VENDOR_INTEL, 6, INTEL_FAM6_TIGERLAKE_L, X86_FEATURE_ANY }, + { X86_VENDOR_INTEL, 6, INTEL_FAM6_ALDERLAKE, X86_FEATURE_ANY }, + { X86_VENDOR_INTEL, 6, INTEL_FAM6_ALDERLAKE_L, X86_FEATURE_ANY }, ++ { X86_VENDOR_INTEL, 6, INTEL_FAM6_ALDERLAKE_N, X86_FEATURE_ANY }, + { X86_VENDOR_INTEL, 6, INTEL_FAM6_RAPTORLAKE, X86_FEATURE_ANY }, ++ { X86_VENDOR_INTEL, 6, INTEL_FAM6_RAPTORLAKE_P, X86_FEATURE_ANY }, + {} + }; + diff --git a/patches.suse/powercap-RAPL-Add-Power-Limit4-support-for-RaptorLake.patch b/patches.suse/powercap-RAPL-Add-Power-Limit4-support-for-RaptorLake.patch new file mode 100644 index 0000000..0395ddb --- /dev/null +++ b/patches.suse/powercap-RAPL-Add-Power-Limit4-support-for-RaptorLake.patch @@ -0,0 +1,30 @@ +From: Sumeet Pawnikar +Subject: powercap: RAPL: Add Power Limit4 support for RaptorLake +References: jsc#PED-769 +Patch-Mainline: v5.19-rc1 +Git-commit: 515755906921fa9393d6c9de18fac4343882a88d + + +Add RaptorLake to the list of processor models for which Power Limit4 +is supported by the Intel RAPL driver. + +Signed-off-by: Sumeet Pawnikar +[ rjw: Changelog rewrite ] +Signed-off-by: Rafael J. Wysocki + + +Signed-off-by: +--- + drivers/powercap/intel_rapl_msr.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/powercap/intel_rapl_msr.c ++++ b/drivers/powercap/intel_rapl_msr.c +@@ -140,6 +140,7 @@ static const struct x86_cpu_id pl4_suppo + { X86_VENDOR_INTEL, 6, INTEL_FAM6_TIGERLAKE_L, X86_FEATURE_ANY }, + { X86_VENDOR_INTEL, 6, INTEL_FAM6_ALDERLAKE, X86_FEATURE_ANY }, + { X86_VENDOR_INTEL, 6, INTEL_FAM6_ALDERLAKE_L, X86_FEATURE_ANY }, ++ { X86_VENDOR_INTEL, 6, INTEL_FAM6_RAPTORLAKE, X86_FEATURE_ANY }, + {} + }; + diff --git a/patches.suse/powercap-intel_rapl-Add-support-for-RAPTORLAKE_P.patch b/patches.suse/powercap-intel_rapl-Add-support-for-RAPTORLAKE_P.patch new file mode 100644 index 0000000..2c7beb4 --- /dev/null +++ b/patches.suse/powercap-intel_rapl-Add-support-for-RAPTORLAKE_P.patch @@ -0,0 +1,32 @@ +From: George D Sworo +Subject: powercap: intel_rapl: Add support for RAPTORLAKE_P +References: jsc#PED-686 +Patch-Mainline: v6.0-rc1 +Git-commit: 2755714656d0f2f41adfe231f3865e72da2cbe39 + + +Add RAPTORLAKE_P to the list of supported processor models in the Intel +RAPL power capping driver. + +Signed-off-by: George D Sworo +Acked-by: Zhang Rui +Tested-by: Sumeet Pawnikar +[ rjw: Minor changelog edits ] +Signed-off-by: Rafael J. Wysocki + + +Signed-off-by: +--- + drivers/powercap/intel_rapl_common.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/powercap/intel_rapl_common.c ++++ b/drivers/powercap/intel_rapl_common.c +@@ -1109,6 +1109,7 @@ static const struct x86_cpu_id rapl_ids[ + X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, &rapl_defaults_core), + X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_N, &rapl_defaults_core), + X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE, &rapl_defaults_core), ++ X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_P, &rapl_defaults_core), + X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, &rapl_defaults_spr_server), + X86_MATCH_INTEL_FAM6_MODEL(LAKEFIELD, &rapl_defaults_core), + diff --git a/patches.suse/powercap-intel_rapl-add-support-for-ALDERLAKE_N.patch b/patches.suse/powercap-intel_rapl-add-support-for-ALDERLAKE_N.patch new file mode 100644 index 0000000..2aa976e --- /dev/null +++ b/patches.suse/powercap-intel_rapl-add-support-for-ALDERLAKE_N.patch @@ -0,0 +1,30 @@ +From: Zhang Rui +Subject: powercap: intel_rapl: add support for ALDERLAKE_N +References: jsc#PED-695 +Patch-Mainline: v5.19-rc1 +Git-commit: f125bdbdd6bd4a88f3697e5850359d3ffe43a3f2 + + +Add ALDERLAKE_N to the list of supported processor models in the Intel +RAPL power capping driver. + +Signed-off-by: Zhang Rui +[ rjw: Changelog ] +Signed-off-by: Rafael J. Wysocki + + +Signed-off-by: +--- + drivers/powercap/intel_rapl_common.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/powercap/intel_rapl_common.c ++++ b/drivers/powercap/intel_rapl_common.c +@@ -1107,6 +1107,7 @@ static const struct x86_cpu_id rapl_ids[ + X86_MATCH_INTEL_FAM6_MODEL(ROCKETLAKE, &rapl_defaults_core), + X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, &rapl_defaults_core), + X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, &rapl_defaults_core), ++ X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_N, &rapl_defaults_core), + X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE, &rapl_defaults_core), + X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, &rapl_defaults_spr_server), + X86_MATCH_INTEL_FAM6_MODEL(LAKEFIELD, &rapl_defaults_core), diff --git a/patches.suse/powercap-intel_rapl-add-support-for-RaptorLake.patch b/patches.suse/powercap-intel_rapl-add-support-for-RaptorLake.patch new file mode 100644 index 0000000..9ec97fb --- /dev/null +++ b/patches.suse/powercap-intel_rapl-add-support-for-RaptorLake.patch @@ -0,0 +1,28 @@ +From: Zhang Rui +Subject: powercap: intel_rapl: add support for RaptorLake +References: jsc#PED-769 +Patch-Mainline: v5.19-rc1 +Git-commit: ae0dc7ed1a7c713ee9ba563a328d3b4d59223d7c + + +Add intel_rapl support for the RaptorLake platform. + +Signed-off-by: Zhang Rui +Signed-off-by: Rafael J. Wysocki + + +Signed-off-by: +--- + drivers/powercap/intel_rapl_common.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/powercap/intel_rapl_common.c ++++ b/drivers/powercap/intel_rapl_common.c +@@ -1107,6 +1107,7 @@ static const struct x86_cpu_id rapl_ids[ + X86_MATCH_INTEL_FAM6_MODEL(ROCKETLAKE, &rapl_defaults_core), + X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, &rapl_defaults_core), + X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, &rapl_defaults_core), ++ X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE, &rapl_defaults_core), + X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, &rapl_defaults_spr_server), + X86_MATCH_INTEL_FAM6_MODEL(LAKEFIELD, &rapl_defaults_core), + diff --git a/patches.suse/powercap-intel_rapl-support-new-layout-of-Psys-PowerLimit-Register-on-SPR.patch b/patches.suse/powercap-intel_rapl-support-new-layout-of-Psys-PowerLimit-Register-on-SPR.patch new file mode 100644 index 0000000..88eb3d3 --- /dev/null +++ b/patches.suse/powercap-intel_rapl-support-new-layout-of-Psys-PowerLimit-Register-on-SPR.patch @@ -0,0 +1,150 @@ +From: Zhang Rui +Subject: powercap: intel_rapl: support new layout of Psys PowerLimit Register on SPR +References: jsc#PED-648 +Patch-Mainline: v5.17-rc1 +Git-commit: 931da6a0de5d620425af4425344259e6ff46b654 + + +On Sapphire Rapids, the layout of the Psys domain Power Limit Register +is different from from what it was before. + +Enhance the code to support the new Psys PL register layout. + +Signed-off-by: Zhang Rui +Reported-and-tested-by: Alkattan Dana +[ rjw: Subject and changelog edits ] +Signed-off-by: Rafael J. Wysocki + + +Signed-off-by: +--- + drivers/powercap/intel_rapl_common.c | 61 +++++++++++++++++++++++++++++++++-- + include/linux/intel_rapl.h | 6 +++ + 2 files changed, 65 insertions(+), 2 deletions(-) + +--- a/drivers/powercap/intel_rapl_common.c ++++ b/drivers/powercap/intel_rapl_common.c +@@ -61,6 +61,20 @@ + #define PERF_STATUS_THROTTLE_TIME_MASK 0xffffffff + #define PP_POLICY_MASK 0x1F + ++/* ++ * SPR has different layout for Psys Domain PowerLimit registers. ++ * There are 17 bits of PL1 and PL2 instead of 15 bits. ++ * The Enable bits and TimeWindow bits are also shifted as a result. ++ */ ++#define PSYS_POWER_LIMIT1_MASK 0x1FFFF ++#define PSYS_POWER_LIMIT1_ENABLE BIT(17) ++ ++#define PSYS_POWER_LIMIT2_MASK (0x1FFFFULL<<32) ++#define PSYS_POWER_LIMIT2_ENABLE BIT_ULL(49) ++ ++#define PSYS_TIME_WINDOW1_MASK (0x7FULL<<19) ++#define PSYS_TIME_WINDOW2_MASK (0x7FULL<<51) ++ + /* Non HW constants */ + #define RAPL_PRIMITIVE_DERIVED BIT(1) /* not from raw data */ + #define RAPL_PRIMITIVE_DUMMY BIT(2) +@@ -97,6 +111,7 @@ struct rapl_defaults { + bool to_raw); + unsigned int dram_domain_energy_unit; + unsigned int psys_domain_energy_unit; ++ bool spr_psys_bits; + }; + static struct rapl_defaults *rapl_defaults; + +@@ -669,12 +684,51 @@ static struct rapl_primitive_info rpi[] + RAPL_DOMAIN_REG_PERF, TIME_UNIT, 0), + PRIMITIVE_INFO_INIT(PRIORITY_LEVEL, PP_POLICY_MASK, 0, + RAPL_DOMAIN_REG_POLICY, ARBITRARY_UNIT, 0), ++ PRIMITIVE_INFO_INIT(PSYS_POWER_LIMIT1, PSYS_POWER_LIMIT1_MASK, 0, ++ RAPL_DOMAIN_REG_LIMIT, POWER_UNIT, 0), ++ PRIMITIVE_INFO_INIT(PSYS_POWER_LIMIT2, PSYS_POWER_LIMIT2_MASK, 32, ++ RAPL_DOMAIN_REG_LIMIT, POWER_UNIT, 0), ++ PRIMITIVE_INFO_INIT(PSYS_PL1_ENABLE, PSYS_POWER_LIMIT1_ENABLE, 17, ++ RAPL_DOMAIN_REG_LIMIT, ARBITRARY_UNIT, 0), ++ PRIMITIVE_INFO_INIT(PSYS_PL2_ENABLE, PSYS_POWER_LIMIT2_ENABLE, 49, ++ RAPL_DOMAIN_REG_LIMIT, ARBITRARY_UNIT, 0), ++ PRIMITIVE_INFO_INIT(PSYS_TIME_WINDOW1, PSYS_TIME_WINDOW1_MASK, 19, ++ RAPL_DOMAIN_REG_LIMIT, TIME_UNIT, 0), ++ PRIMITIVE_INFO_INIT(PSYS_TIME_WINDOW2, PSYS_TIME_WINDOW2_MASK, 51, ++ RAPL_DOMAIN_REG_LIMIT, TIME_UNIT, 0), + /* non-hardware */ + PRIMITIVE_INFO_INIT(AVERAGE_POWER, 0, 0, 0, POWER_UNIT, + RAPL_PRIMITIVE_DERIVED), + {NULL, 0, 0, 0}, + }; + ++static enum rapl_primitives ++prim_fixups(struct rapl_domain *rd, enum rapl_primitives prim) ++{ ++ if (!rapl_defaults->spr_psys_bits) ++ return prim; ++ ++ if (rd->id != RAPL_DOMAIN_PLATFORM) ++ return prim; ++ ++ switch (prim) { ++ case POWER_LIMIT1: ++ return PSYS_POWER_LIMIT1; ++ case POWER_LIMIT2: ++ return PSYS_POWER_LIMIT2; ++ case PL1_ENABLE: ++ return PSYS_PL1_ENABLE; ++ case PL2_ENABLE: ++ return PSYS_PL2_ENABLE; ++ case TIME_WINDOW1: ++ return PSYS_TIME_WINDOW1; ++ case TIME_WINDOW2: ++ return PSYS_TIME_WINDOW2; ++ default: ++ return prim; ++ } ++} ++ + /* Read primitive data based on its related struct rapl_primitive_info. + * if xlate flag is set, return translated data based on data units, i.e. + * time, energy, and power. +@@ -692,7 +746,8 @@ static int rapl_read_data_raw(struct rap + enum rapl_primitives prim, bool xlate, u64 *data) + { + u64 value; +- struct rapl_primitive_info *rp = &rpi[prim]; ++ enum rapl_primitives prim_fixed = prim_fixups(rd, prim); ++ struct rapl_primitive_info *rp = &rpi[prim_fixed]; + struct reg_action ra; + int cpu; + +@@ -738,7 +793,8 @@ static int rapl_write_data_raw(struct ra + enum rapl_primitives prim, + unsigned long long value) + { +- struct rapl_primitive_info *rp = &rpi[prim]; ++ enum rapl_primitives prim_fixed = prim_fixups(rd, prim); ++ struct rapl_primitive_info *rp = &rpi[prim_fixed]; + int cpu; + u64 bits; + struct reg_action ra; +@@ -981,6 +1037,7 @@ static const struct rapl_defaults rapl_d + .compute_time_window = rapl_compute_time_window_core, + .dram_domain_energy_unit = 15300, + .psys_domain_energy_unit = 1000000000, ++ .spr_psys_bits = true, + }; + + static const struct rapl_defaults rapl_defaults_byt = { +--- a/include/linux/intel_rapl.h ++++ b/include/linux/intel_rapl.h +@@ -58,6 +58,12 @@ enum rapl_primitives { + THROTTLED_TIME, + PRIORITY_LEVEL, + ++ PSYS_POWER_LIMIT1, ++ PSYS_POWER_LIMIT2, ++ PSYS_PL1_ENABLE, ++ PSYS_PL2_ENABLE, ++ PSYS_TIME_WINDOW1, ++ PSYS_TIME_WINDOW2, + /* below are not raw primitive data */ + AVERAGE_POWER, + NR_RAPL_PRIMITIVES, diff --git a/patches.suse/powerpc-64-Remove-unused-SYS_CALL_TABLE-symbol.patch b/patches.suse/powerpc-64-Remove-unused-SYS_CALL_TABLE-symbol.patch new file mode 100644 index 0000000..1d3d0c0 --- /dev/null +++ b/patches.suse/powerpc-64-Remove-unused-SYS_CALL_TABLE-symbol.patch @@ -0,0 +1,48 @@ +From e74611aa91bb9939dfc4a41b045a1a19227cff98 Mon Sep 17 00:00:00 2001 +From: Michael Ellerman +Date: Tue, 13 Sep 2022 22:45:45 +1000 +Subject: [PATCH] powerpc/64: Remove unused SYS_CALL_TABLE symbol + +References: jsc#SLE-9246 git-fixes +Patch-mainline: v6.1-rc1 +Git-commit: e74611aa91bb9939dfc4a41b045a1a19227cff98 + +In interrupt_64.S, formerly entry_64.S, there are two toc entries +created for sys_call_table and compat_sys_call_table. + +These are no longer used, since the system call entry was converted from +asm to C, so remove them. + +Fixes: 68b34588e202 ("powerpc/64/sycall: Implement syscall entry/exit logic in C") +Acked-by: Nicholas Piggin +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/20220913124545.2817825-1-mpe@ellerman.id.au +Acked-by: Michal Suchanek +--- + arch/powerpc/kernel/interrupt_64.S | 10 ---------- + 1 file changed, 10 deletions(-) + +diff --git a/arch/powerpc/kernel/interrupt_64.S b/arch/powerpc/kernel/interrupt_64.S +index ce25b28cf418..4b4ba3364665 100644 +--- a/arch/powerpc/kernel/interrupt_64.S ++++ b/arch/powerpc/kernel/interrupt_64.S +@@ -13,16 +13,6 @@ + #include + #include + +- .section ".toc","aw" +-SYS_CALL_TABLE: +- .tc sys_call_table[TC],sys_call_table +- +-#ifdef CONFIG_COMPAT +-COMPAT_SYS_CALL_TABLE: +- .tc compat_sys_call_table[TC],compat_sys_call_table +-#endif +- .previous +- + .align 7 + + .macro DEBUG_SRR_VALID srr +-- +2.35.3 + diff --git a/patches.suse/powerpc-kprobes-Fix-null-pointer-reference-in-arch_p.patch b/patches.suse/powerpc-kprobes-Fix-null-pointer-reference-in-arch_p.patch new file mode 100644 index 0000000..c63c21b --- /dev/null +++ b/patches.suse/powerpc-kprobes-Fix-null-pointer-reference-in-arch_p.patch @@ -0,0 +1,99 @@ +From 97f88a3d723162781d6cbfdc7b9617eefab55b19 Mon Sep 17 00:00:00 2001 +From: Li Huafei +Date: Fri, 23 Sep 2022 17:32:53 +0800 +Subject: [PATCH] powerpc/kprobes: Fix null pointer reference in + arch_prepare_kprobe() + +References: jsc#SLE-13847 git-fixes +Patch-mainline: v6.1-rc1 +Git-commit: 97f88a3d723162781d6cbfdc7b9617eefab55b19 + +I found a null pointer reference in arch_prepare_kprobe(): + + # echo 'p cmdline_proc_show' > kprobe_events + # echo 'p cmdline_proc_show+16' >> kprobe_events + Kernel attempted to read user page (0) - exploit attempt? (uid: 0) + BUG: Kernel NULL pointer dereference on read at 0x00000000 + Faulting instruction address: 0xc000000000050bfc + Oops: Kernel access of bad area, sig: 11 [#1] + LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=2048 NUMA PowerNV + Modules linked in: + CPU: 0 PID: 122 Comm: sh Not tainted 6.0.0-rc3-00007-gdcf8e5633e2e #10 + NIP: c000000000050bfc LR: c000000000050bec CTR: 0000000000005bdc + REGS: c0000000348475b0 TRAP: 0300 Not tainted (6.0.0-rc3-00007-gdcf8e5633e2e) + MSR: 9000000000009033 CR: 88002444 XER: 20040006 + CFAR: c00000000022d100 DAR: 0000000000000000 DSISR: 40000000 IRQMASK: 0 + ... + NIP arch_prepare_kprobe+0x10c/0x2d0 + LR arch_prepare_kprobe+0xfc/0x2d0 + Call Trace: + 0xc0000000012f77a0 (unreliable) + register_kprobe+0x3c0/0x7a0 + __register_trace_kprobe+0x140/0x1a0 + __trace_kprobe_create+0x794/0x1040 + trace_probe_create+0xc4/0xe0 + create_or_delete_trace_kprobe+0x2c/0x80 + trace_parse_run_command+0xf0/0x210 + probes_write+0x20/0x40 + vfs_write+0xfc/0x450 + ksys_write+0x84/0x140 + system_call_exception+0x17c/0x3a0 + system_call_vectored_common+0xe8/0x278 + --- interrupt: 3000 at 0x7fffa5682de0 + NIP: 00007fffa5682de0 LR: 0000000000000000 CTR: 0000000000000000 + REGS: c000000034847e80 TRAP: 3000 Not tainted (6.0.0-rc3-00007-gdcf8e5633e2e) + MSR: 900000000280f033 CR: 44002408 XER: 00000000 + +The address being probed has some special: + + cmdline_proc_show: Probe based on ftrace + cmdline_proc_show+16: Probe for the next instruction at the ftrace location + +The ftrace-based kprobe does not generate kprobe::ainsn::insn, it gets +set to NULL. In arch_prepare_kprobe() it will check for: + + ... + prev = get_kprobe(p->addr - 1); + preempt_enable_no_resched(); + if (prev && ppc_inst_prefixed(ppc_inst_read(prev->ainsn.insn))) { + ... + +If prev is based on ftrace, 'ppc_inst_read(prev->ainsn.insn)' will occur +with a null pointer reference. At this point prev->addr will not be a +prefixed instruction, so the check can be skipped. + +Check if prev is ftrace-based kprobe before reading 'prev->ainsn.insn' +to fix this problem. + +Fixes: b4657f7650ba ("powerpc/kprobes: Don't allow breakpoints on suffixes") +Signed-off-by: Li Huafei +[mpe: Trim oops] +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/20220923093253.177298-1-lihuafei1@huawei.com +Acked-by: Michal Suchanek +--- + arch/powerpc/kernel/kprobes.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c +index 912d4f8a13be..bd7b1a035459 100644 +--- a/arch/powerpc/kernel/kprobes.c ++++ b/arch/powerpc/kernel/kprobes.c +@@ -161,7 +161,13 @@ int arch_prepare_kprobe(struct kprobe *p) + preempt_disable(); + prev = get_kprobe(p->addr - 1); + preempt_enable_no_resched(); +- if (prev && ppc_inst_prefixed(ppc_inst_read(prev->ainsn.insn))) { ++ ++ /* ++ * When prev is a ftrace-based kprobe, we don't have an insn, and it ++ * doesn't probe for prefixed instruction. ++ */ ++ if (prev && !kprobe_ftrace(prev) && ++ ppc_inst_prefixed(ppc_inst_read(prev->ainsn.insn))) { + printk("Cannot register a kprobe on the second word of prefixed instruction\n"); + ret = -EINVAL; + } +-- +2.35.3 + diff --git a/patches.suse/powerpc-kvm-Remove-obsolete-and-unneeded-select.patch b/patches.suse/powerpc-kvm-Remove-obsolete-and-unneeded-select.patch new file mode 100644 index 0000000..32bb5cc --- /dev/null +++ b/patches.suse/powerpc-kvm-Remove-obsolete-and-unneeded-select.patch @@ -0,0 +1,43 @@ +From c26d4c5d4f0df7207da3975458261927f9305465 Mon Sep 17 00:00:00 2001 +From: Lukas Bulwahn +Date: Thu, 19 Aug 2021 13:39:53 +0200 +Subject: [PATCH] powerpc/kvm: Remove obsolete and unneeded select +Git-commit: c26d4c5d4f0df7207da3975458261927f9305465 +References: git-fixes +Patch-mainline: v5.15-rc1 + +Commit a278e7ea608b ("powerpc: Fix compile issue with force DAWR") +selects the non-existing config PPC_DAWR_FORCE_ENABLE for config +KVM_BOOK3S_64_HANDLER. As this commit also introduces a config PPC_DAWR +and this config PPC_DAWR is selected with PPC if PPC64, there is no +need for any further select in the KVM_BOOK3S_64_HANDLER. + +Remove an obsolete and unneeded select in config KVM_BOOK3S_64_HANDLER. + +The issue was identified with ./scripts/checkkconfigsymbols.py. + +Fixes: a278e7ea608b ("powerpc: Fix compile issue with force DAWR") +Signed-off-by: Lukas Bulwahn +Reviewed-by: Daniel Axtens +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/20210819113954.17515-2-lukas.bulwahn@gmail.com +Signed-off-by: Oliver Neukum +--- + arch/powerpc/kvm/Kconfig | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig +index e45644657d49..ff581d70f20c 100644 +--- a/arch/powerpc/kvm/Kconfig ++++ b/arch/powerpc/kvm/Kconfig +@@ -38,7 +38,6 @@ config KVM_BOOK3S_32_HANDLER + config KVM_BOOK3S_64_HANDLER + bool + select KVM_BOOK3S_HANDLER +- select PPC_DAWR_FORCE_ENABLE + + config KVM_BOOK3S_PR_POSSIBLE + bool +-- +2.35.3 + diff --git a/patches.suse/powerpc-mm-64s-Drop-pgd_huge.patch b/patches.suse/powerpc-mm-64s-Drop-pgd_huge.patch new file mode 100644 index 0000000..400bd5c --- /dev/null +++ b/patches.suse/powerpc-mm-64s-Drop-pgd_huge.patch @@ -0,0 +1,115 @@ +From 51da853e3708852f47cd95e6f5e1821c3d54c3ef Mon Sep 17 00:00:00 2001 +From: Michael Ellerman +Date: Sat, 3 Sep 2022 22:36:39 +1000 +Subject: [PATCH] powerpc/mm/64s: Drop pgd_huge() + +References: bsc#1065729 +Patch-mainline: v6.1-rc1 +Git-commit: 51da853e3708852f47cd95e6f5e1821c3d54c3ef + +On powerpc there are two ways for huge pages to be represented in the +top level page table, aka PGD (Page Global Directory). + +If the address space mapped by an individual PGD entry does not +correspond to a given huge page size, then the PGD entry points to a +non-standard page table, known as a "hugepd" (Huge Page Directory). +The hugepd contains some number of huge page PTEs sufficient to map the +address space with the given huge page size. + +On the other hand, if the address space mapped by an individual PGD +entry does correspond exactly to a given huge page size, that PGD entry +is used to directly encode the huge page PTE in place. In this case the +pgd_huge() wrapper indicates to generic code that the PGD entry is +actually a huge page PTE. + +This commit deals with the pgd_huge() case only, it does nothing with +respect to the hugepd case. + +Over time the size of the virtual address space supported on powerpc has +increased several times, which means the location at which huge pages +can sit in the tree has also changed. There have also been new huge page +sizes added, with the introduction of the Radix MMU. + +On Power9 and later with the Radix MMU, the largest huge page size in +any implementation is 1GB. + +Since the introduction of Radix, 1GB entries have been supported at the +PUD level, with both 4K and 64K base page size. Radix has never had a +supported huge page size at the PGD level. + +On Power8 or earlier, which uses the Hash MMU, or Power9 or later with +the Hash MMU enabled, the largest huge page size is 16GB. + +Using the Hash MMU and a base page size of 4K, 16GB has never been a +supported huge page size at the PGD level, due to the geometry being +incompatible. The two supported huge page sizes (16M & 16GB) both use +the hugepd format. + +Using the Hash MMU and a base page size of 64K, 16GB pages were +supported in the past at the PGD level. + +However in commit ba95b5d03596 ("powerpc/mm/book3s/64: Rework page table +geometry for lower memory usage") the page table layout was reworked to +shrink the size of the PGD. + +As a result the 16GB page size now fits at the PUD level when using 64K +base page size. + +Therefore there are no longer any supported configurations where +pgd_huge() can be true, so drop the definitions for pgd_huge(), and +fallback to the generic definition which is always false. + +Fixes: ba95b5d03596 ("powerpc/mm/book3s/64: Rework page table geometry for lower memory usage") +Reviewed-by: Aneesh Kumar K.V +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/20220903123640.719846-1-mpe@ellerman.id.au +Acked-by: Michal Suchanek +--- + arch/powerpc/include/asm/book3s/64/pgtable-4k.h | 10 ---------- + arch/powerpc/include/asm/book3s/64/pgtable-64k.h | 9 --------- + 2 files changed, 19 deletions(-) + +diff --git a/arch/powerpc/include/asm/book3s/64/pgtable-4k.h b/arch/powerpc/include/asm/book3s/64/pgtable-4k.h +index 4e697bc2f4cd..48f21820afe2 100644 +--- a/arch/powerpc/include/asm/book3s/64/pgtable-4k.h ++++ b/arch/powerpc/include/asm/book3s/64/pgtable-4k.h +@@ -26,16 +26,6 @@ static inline int pud_huge(pud_t pud) + return 0; + } + +-static inline int pgd_huge(pgd_t pgd) +-{ +- /* +- * leaf pte for huge page +- */ +- if (radix_enabled()) +- return !!(pgd_raw(pgd) & cpu_to_be64(_PAGE_PTE)); +- return 0; +-} +-#define pgd_huge pgd_huge + /* + * With radix , we have hugepage ptes in the pud and pmd entries. We don't + * need to setup hugepage directory for them. Our pte and page directory format +diff --git a/arch/powerpc/include/asm/book3s/64/pgtable-64k.h b/arch/powerpc/include/asm/book3s/64/pgtable-64k.h +index 34d1018896b3..2fce3498b000 100644 +--- a/arch/powerpc/include/asm/book3s/64/pgtable-64k.h ++++ b/arch/powerpc/include/asm/book3s/64/pgtable-64k.h +@@ -30,15 +30,6 @@ static inline int pud_huge(pud_t pud) + return !!(pud_raw(pud) & cpu_to_be64(_PAGE_PTE)); + } + +-static inline int pgd_huge(pgd_t pgd) +-{ +- /* +- * leaf pte for huge page +- */ +- return !!(pgd_raw(pgd) & cpu_to_be64(_PAGE_PTE)); +-} +-#define pgd_huge pgd_huge +- + /* + * With 64k page size, we have hugepage ptes in the pgd and pmd entries. We don't + * need to setup hugepage directory for them. Our pte and page directory format +-- +2.35.3 + diff --git a/patches.suse/powerpc-pci_dn-Add-missing-of_node_put.patch b/patches.suse/powerpc-pci_dn-Add-missing-of_node_put.patch new file mode 100644 index 0000000..16595fd --- /dev/null +++ b/patches.suse/powerpc-pci_dn-Add-missing-of_node_put.patch @@ -0,0 +1,38 @@ +From 110a1fcb6c4d55144d8179983a475f17a1d6f832 Mon Sep 17 00:00:00 2001 +From: Liang He +Date: Fri, 1 Jul 2022 21:17:50 +0800 +Subject: [PATCH] powerpc/pci_dn: Add missing of_node_put() + +References: bsc#1065729 +Patch-mainline: v6.1-rc1 +Git-commit: 110a1fcb6c4d55144d8179983a475f17a1d6f832 + +In pci_add_device_node_info(), use of_node_put() to drop the reference +to 'parent' returned by of_get_parent() to keep refcount balance. + +Fixes: cca87d303c85 ("powerpc/pci: Refactor pci_dn") +Co-authored-by: Miaoqian Lin +Signed-off-by: Liang He +Signed-off-by: Michael Ellerman +Reviewed-by: Tyrel Datwyler +Link: https://lore.kernel.org/r/20220701131750.240170-1-windhl@126.com +Acked-by: Michal Suchanek +--- + arch/powerpc/kernel/pci_dn.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c +index 7a35fc25a304..38561d6a2079 100644 +--- a/arch/powerpc/kernel/pci_dn.c ++++ b/arch/powerpc/kernel/pci_dn.c +@@ -330,6 +330,7 @@ struct pci_dn *pci_add_device_node_info(struct pci_controller *hose, + INIT_LIST_HEAD(&pdn->list); + parent = of_get_parent(dn); + pdn->parent = parent ? PCI_DN(parent) : NULL; ++ of_node_put(parent); + if (pdn->parent) + list_add_tail(&pdn->list, &pdn->parent->child_list); + +-- +2.35.3 + diff --git a/patches.suse/powerpc-powernv-add-missing-of_node_put-in-opal_expo.patch b/patches.suse/powerpc-powernv-add-missing-of_node_put-in-opal_expo.patch new file mode 100644 index 0000000..fba3d94 --- /dev/null +++ b/patches.suse/powerpc-powernv-add-missing-of_node_put-in-opal_expo.patch @@ -0,0 +1,37 @@ +From 71a92e99c47900cc164620948b3863382cec4f1a Mon Sep 17 00:00:00 2001 +From: Zheng Yongjun +Date: Tue, 6 Sep 2022 14:17:03 +0000 +Subject: [PATCH] powerpc/powernv: add missing of_node_put() in + opal_export_attrs() + +References: bsc#1065729 +Patch-mainline: v6.1-rc1 +Git-commit: 71a92e99c47900cc164620948b3863382cec4f1a + +After using 'np' returned by of_find_node_by_path(), of_node_put() +need be called to decrease the refcount. + +Fixes: 11fe909d2362 ("powerpc/powernv: Add OPAL exports attributes to sysfs") +Signed-off-by: Zheng Yongjun +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/20220906141703.118192-1-zhengyongjun3@huawei.com +Acked-by: Michal Suchanek +--- + arch/powerpc/platforms/powernv/opal.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c +index e536a6a3c801..cdf3838f08d3 100644 +--- a/arch/powerpc/platforms/powernv/opal.c ++++ b/arch/powerpc/platforms/powernv/opal.c +@@ -892,6 +892,7 @@ static void opal_export_attrs(void) + kobj = kobject_create_and_add("exports", opal_kobj); + if (!kobj) { + pr_warn("kobject_create_and_add() of exports failed\n"); ++ of_node_put(np); + return; + } + +-- +2.35.3 + diff --git a/patches.suse/powerpc-pseries-vas-Pass-hw_cpu_id-to-node-associati.patch b/patches.suse/powerpc-pseries-vas-Pass-hw_cpu_id-to-node-associati.patch new file mode 100644 index 0000000..d6c6629 --- /dev/null +++ b/patches.suse/powerpc-pseries-vas-Pass-hw_cpu_id-to-node-associati.patch @@ -0,0 +1,51 @@ +From f3e5d9e53e74d77e711a2c90a91a8b0836a9e0b3 Mon Sep 17 00:00:00 2001 +From: Haren Myneni +Date: Wed, 28 Sep 2022 18:57:33 -0700 +Subject: [PATCH] powerpc/pseries/vas: Pass hw_cpu_id to node associativity + HCALL + +References: bsc#1194869 +Patch-mainline: v6.1-rc1 +Git-commit: f3e5d9e53e74d77e711a2c90a91a8b0836a9e0b3 + +Generally the hypervisor decides to allocate a window on different +VAS instances. But if user space wishes to allocate on the current VAS +instance where the process is executing, the kernel has to pass +associativity domain IDs to allocate VAS window HCALL. + +To determine the associativity domain IDs for the current CPU, +smp_processor_id() is passed to node associativity HCALL which may +return H_P2 (-55) error during DLPAR CPU event. This is because Linux +CPU numbers (smp_processor_id()) are not the same as the hypervisor's +view of CPU numbers. + +Fix the issue by passing hard_smp_processor_id() with +VPHN_FLAG_VCPU flag (PAPR 14.11.6.1 H_HOME_NODE_ASSOCIATIVITY). + +Fixes: b22f2d88e435 ("powerpc/pseries/vas: Integrate API with open/close windows") +Reviewed-by: Nathan Lynch +Signed-off-by: Haren Myneni +[mpe: Update change log to mention Linux vs HV CPU numbers] +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/55380253ea0c11341824cd4c0fc6bbcfc5752689.camel@linux.ibm.com +Acked-by: Michal Suchanek +--- + arch/powerpc/platforms/pseries/vas.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/powerpc/platforms/pseries/vas.c b/arch/powerpc/platforms/pseries/vas.c +index 46ea4e252f97..0e0524cbe20c 100644 +--- a/arch/powerpc/platforms/pseries/vas.c ++++ b/arch/powerpc/platforms/pseries/vas.c +@@ -333,7 +333,7 @@ static struct vas_window *vas_allocate_window(int vas_id, u64 flags, + * So no unpacking needs to be done. + */ + rc = plpar_hcall9(H_HOME_NODE_ASSOCIATIVITY, domain, +- VPHN_FLAG_VCPU, smp_processor_id()); ++ VPHN_FLAG_VCPU, hard_smp_processor_id()); + if (rc != H_SUCCESS) { + pr_err("H_HOME_NODE_ASSOCIATIVITY error: %d\n", rc); + goto out; +-- +2.35.3 + diff --git a/patches.suse/qeth-remove-a-copy-of-the-NAPI_POLL_WEIGHT-define b/patches.suse/qeth-remove-a-copy-of-the-NAPI_POLL_WEIGHT-define new file mode 100644 index 0000000..ecf37bd --- /dev/null +++ b/patches.suse/qeth-remove-a-copy-of-the-NAPI_POLL_WEIGHT-define @@ -0,0 +1,65 @@ +From: Jakub Kicinski +Date: Thu, 28 Apr 2022 14:23:23 -0700 +Subject: qeth: remove a copy of the NAPI_POLL_WEIGHT define +Git-commit: 4bb0c7f09a1962330e9edf5dd6cfe44113aeee45 +Patch-mainline: v5.19-rc1 +References: jsc#PED-448 LTC#198619 + +Defining local versions of NAPI_POLL_WEIGHT with the same +values in the drivers just makes refactoring harder. + +Signed-off-by: Jakub Kicinski +Acked-by: Alexandra Winter +Signed-off-by: David S. Miller +Acked-by: Petr Tesarik +--- + drivers/s390/net/qeth_core.h | 2 -- + drivers/s390/net/qeth_core_main.c | 2 +- + drivers/s390/net/qeth_l2_main.c | 2 +- + drivers/s390/net/qeth_l3_main.c | 2 +- + 4 files changed, 3 insertions(+), 5 deletions(-) + +--- a/drivers/s390/net/qeth_core.h ++++ b/drivers/s390/net/qeth_core.h +@@ -819,8 +819,6 @@ struct qeth_priv { + u32 brport_features; + }; + +-#define QETH_NAPI_WEIGHT NAPI_POLL_WEIGHT +- + struct qeth_card { + enum qeth_card_states state; + spinlock_t lock; +--- a/drivers/s390/net/qeth_core_main.c ++++ b/drivers/s390/net/qeth_core_main.c +@@ -7189,7 +7189,7 @@ int qeth_open(struct net_device *dev) + local_bh_disable(); + qeth_for_each_output_queue(card, queue, i) { + netif_tx_napi_add(dev, &queue->napi, qeth_tx_poll, +- QETH_NAPI_WEIGHT); ++ NAPI_POLL_WEIGHT); + napi_enable(&queue->napi); + napi_schedule(&queue->napi); + } +--- a/drivers/s390/net/qeth_l2_main.c ++++ b/drivers/s390/net/qeth_l2_main.c +@@ -1192,7 +1192,7 @@ static int qeth_l2_setup_netdev(struct q + } + + add_napi: +- netif_napi_add(card->dev, &card->napi, qeth_poll, QETH_NAPI_WEIGHT); ++ netif_napi_add(card->dev, &card->napi, qeth_poll, NAPI_POLL_WEIGHT); + return register_netdev(card->dev); + } + +--- a/drivers/s390/net/qeth_l3_main.c ++++ b/drivers/s390/net/qeth_l3_main.c +@@ -1910,7 +1910,7 @@ static int qeth_l3_setup_netdev(struct q + netif_set_gso_max_size(card->dev, + PAGE_SIZE * (QETH_MAX_BUFFER_ELEMENTS(card) - 1)); + +- netif_napi_add(card->dev, &card->napi, qeth_poll, QETH_NAPI_WEIGHT); ++ netif_napi_add(card->dev, &card->napi, qeth_poll, NAPI_POLL_WEIGHT); + return register_netdev(card->dev); + } + diff --git a/patches.suse/qlcnic-Remove-redundant-initialization-of-variable-ret.patch b/patches.suse/qlcnic-Remove-redundant-initialization-of-variable-ret.patch new file mode 100644 index 0000000..797ffca --- /dev/null +++ b/patches.suse/qlcnic-Remove-redundant-initialization-of-variable-ret.patch @@ -0,0 +1,35 @@ +From: Colin Ian King +Date: Fri, 10 Sep 2021 12:15:11 +0100 +Subject: qlcnic: Remove redundant initialization of variable ret +Git-commit: 666eb96d85dcbc93aacc186a037db2e05b92b9f5 +Patch-mainline: v5.15-rc2 +References: jsc#PED-1302 + +The variable ret is being initialized with a value that is never read, it +is being updated later on. The assignment is redundant and can be removed. + +Addresses-Coverity: ("Unused value") +Signed-off-by: Colin Ian King +Signed-off-by: David S. Miller +Acked-by: Lee Duncan +--- + drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c +index 0a2f34fc8b24..27dffa299ca6 100644 +--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c ++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c +@@ -1354,10 +1354,10 @@ static int qlcnic_83xx_copy_fw_file(struct qlcnic_adapter *adapter) + struct qlc_83xx_fw_info *fw_info = adapter->ahw->fw_info; + const struct firmware *fw = fw_info->fw; + u32 dest, *p_cache, *temp; +- int i, ret = -EIO; + __le32 *temp_le; + u8 data[16]; + size_t size; ++ int i, ret; + u64 addr; + + temp = vzalloc(fw->size); + diff --git a/patches.suse/qlcnic-Simplify-DMA-setting.patch b/patches.suse/qlcnic-Simplify-DMA-setting.patch new file mode 100644 index 0000000..18f0f86 --- /dev/null +++ b/patches.suse/qlcnic-Simplify-DMA-setting.patch @@ -0,0 +1,237 @@ +From: Christophe JAILLET +Date: Sat, 8 Jan 2022 14:48:59 +0100 +Subject: qlcnic: Simplify DMA setting +Git-commit: a72dc1992de85ca712836c845458fa72824e355e +Patch-mainline: v5.17-rc1 +References: jsc#PED-1302 + +As stated in [1], dma_set_mask() with a 64-bit mask will never fail if +dev->dma_mask is non-NULL. +So, if it fails, the 32 bits case will also fail for the same reason. + +So qlcnic_set_dma_mask(), (in qlcnic_main.c) can be simplified a lot and +inlined directly in its only caller. + +If dma_set_mask_and_coherent() succeeds, 'pci_using_dac' is known to be 1. +So it can be removed from all the calling chain. + +qlcnic_setup_netdev() can finally be simplified as-well. + +[1]: https://lkml.org/lkml/2021/6/7/398 + +Signed-off-by: Christophe JAILLET +Link: https://lore.kernel.org/r/4996ab0337d62ec6a54b2edf234cd5ced4b4d7ad.1641649611.git.christophe.jaillet@wanadoo.fr +Signed-off-by: Jakub Kicinski +Acked-by: Lee Duncan +--- + drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 2 +- + .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | 2 +- + .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 4 +-- + drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 38 ++++++---------------- + drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h | 2 +- + .../ethernet/qlogic/qlcnic/qlcnic_sriov_common.c | 9 +++-- + 6 files changed, 19 insertions(+), 38 deletions(-) + +diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +index be7abee160e7..b25102fded7b 100644 +--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h ++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +@@ -1698,7 +1698,7 @@ int qlcnic_set_vxlan_port(struct qlcnic_adapter *adapter, u16 port); + int qlcnic_set_vxlan_parsing(struct qlcnic_adapter *adapter, u16 port); + int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter); + int qlcnic_read_mac_addr(struct qlcnic_adapter *); +-int qlcnic_setup_netdev(struct qlcnic_adapter *, struct net_device *, int); ++int qlcnic_setup_netdev(struct qlcnic_adapter *, struct net_device *); + void qlcnic_set_netdev_features(struct qlcnic_adapter *, + struct qlcnic_esw_func_cfg *); + void qlcnic_sriov_vf_set_multi(struct net_device *); +diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h +index 6f1d9c1fd1b0..23cd47d588e5 100644 +--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h ++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h +@@ -609,7 +609,7 @@ int qlcnic_83xx_read_flash_descriptor_table(struct qlcnic_adapter *); + int qlcnic_83xx_flash_read32(struct qlcnic_adapter *, u32, u8 *, int); + int qlcnic_83xx_lockless_flash_read32(struct qlcnic_adapter *, + u32, u8 *, int); +-int qlcnic_83xx_init(struct qlcnic_adapter *, int); ++int qlcnic_83xx_init(struct qlcnic_adapter *); + int qlcnic_83xx_idc_ready_state_entry(struct qlcnic_adapter *); + void qlcnic_83xx_idc_poll_dev_state(struct work_struct *); + void qlcnic_83xx_idc_exit(struct qlcnic_adapter *); +diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c +index 27dffa299ca6..dbb800769cb6 100644 +--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c ++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c +@@ -2432,7 +2432,7 @@ static void qlcnic_83xx_init_rings(struct qlcnic_adapter *adapter) + qlcnic_set_sds_ring_count(adapter, rx_cnt); + } + +-int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac) ++int qlcnic_83xx_init(struct qlcnic_adapter *adapter) + { + struct qlcnic_hardware_context *ahw = adapter->ahw; + int err = 0; +@@ -2466,7 +2466,7 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac) + goto exit; + + if (qlcnic_sriov_vf_check(adapter)) { +- err = qlcnic_sriov_vf_init(adapter, pci_using_dac); ++ err = qlcnic_sriov_vf_init(adapter); + if (err) + goto detach_mbx; + else +diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +index ed84f0f97623..d320567b2cca 100644 +--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c ++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +@@ -2258,8 +2258,7 @@ static int qlcnic_set_real_num_queues(struct qlcnic_adapter *adapter, + } + + int +-qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev, +- int pci_using_dac) ++qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev) + { + int err; + struct pci_dev *pdev = adapter->pdev; +@@ -2278,20 +2277,15 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev, + + netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM | + NETIF_F_IPV6_CSUM | NETIF_F_GRO | +- NETIF_F_HW_VLAN_CTAG_RX); ++ NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HIGHDMA); + netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | +- NETIF_F_IPV6_CSUM); ++ NETIF_F_IPV6_CSUM | NETIF_F_HIGHDMA); + + if (QLCNIC_IS_TSO_CAPABLE(adapter)) { + netdev->features |= (NETIF_F_TSO | NETIF_F_TSO6); + netdev->vlan_features |= (NETIF_F_TSO | NETIF_F_TSO6); + } + +- if (pci_using_dac) { +- netdev->features |= NETIF_F_HIGHDMA; +- netdev->vlan_features |= NETIF_F_HIGHDMA; +- } +- + if (qlcnic_vlan_tx_check(adapter)) + netdev->features |= (NETIF_F_HW_VLAN_CTAG_TX); + +@@ -2341,20 +2335,6 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev, + return 0; + } + +-static int qlcnic_set_dma_mask(struct pci_dev *pdev, int *pci_using_dac) +-{ +- if (!dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64))) +- *pci_using_dac = 1; +- else if (!dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) +- *pci_using_dac = 0; +- else { +- dev_err(&pdev->dev, "Unable to set DMA mask, aborting\n"); +- return -EIO; +- } +- +- return 0; +-} +- + void qlcnic_free_tx_rings(struct qlcnic_adapter *adapter) + { + int ring; +@@ -2441,8 +2421,8 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + struct net_device *netdev = NULL; + struct qlcnic_adapter *adapter = NULL; + struct qlcnic_hardware_context *ahw; +- int err, pci_using_dac = -1; + char board_name[QLCNIC_MAX_BOARD_NAME_LEN + 19]; /* MAC + ": " + name */ ++ int err; + + err = pci_enable_device(pdev); + if (err) +@@ -2453,9 +2433,11 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + goto err_out_disable_pdev; + } + +- err = qlcnic_set_dma_mask(pdev, &pci_using_dac); +- if (err) ++ err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); ++ if (err) { ++ dev_err(&pdev->dev, "Unable to set DMA mask, aborting\n"); + goto err_out_disable_pdev; ++ } + + err = pci_request_regions(pdev, qlcnic_driver_name); + if (err) +@@ -2569,7 +2551,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + } else if (qlcnic_83xx_check(adapter)) { + qlcnic_83xx_check_vf(adapter, ent); + adapter->portnum = adapter->ahw->pci_func; +- err = qlcnic_83xx_init(adapter, pci_using_dac); ++ err = qlcnic_83xx_init(adapter); + if (err) { + switch (err) { + case -ENOTRECOVERABLE: +@@ -2633,7 +2615,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + if (adapter->portnum == 0) + qlcnic_set_drv_version(adapter); + +- err = qlcnic_setup_netdev(adapter, netdev, pci_using_dac); ++ err = qlcnic_setup_netdev(adapter, netdev); + if (err) + goto err_out_disable_mbx_intr; + +diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h +index d0111cb3b40e..c42b99cd58bd 100644 +--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h ++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h +@@ -188,7 +188,7 @@ int qlcnic_sriov_init(struct qlcnic_adapter *, int); + void qlcnic_sriov_cleanup(struct qlcnic_adapter *); + void __qlcnic_sriov_cleanup(struct qlcnic_adapter *); + void qlcnic_sriov_vf_register_map(struct qlcnic_hardware_context *); +-int qlcnic_sriov_vf_init(struct qlcnic_adapter *, int); ++int qlcnic_sriov_vf_init(struct qlcnic_adapter *); + void qlcnic_sriov_vf_set_ops(struct qlcnic_adapter *); + int qlcnic_sriov_func_to_index(struct qlcnic_adapter *, u8); + void qlcnic_sriov_handle_bc_event(struct qlcnic_adapter *, u32); +diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c +index 42a44c97572a..9282321c2e7f 100644 +--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c ++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c +@@ -525,8 +525,7 @@ static int qlcnic_sriov_vf_init_driver(struct qlcnic_adapter *adapter) + return 0; + } + +-static int qlcnic_sriov_setup_vf(struct qlcnic_adapter *adapter, +- int pci_using_dac) ++static int qlcnic_sriov_setup_vf(struct qlcnic_adapter *adapter) + { + int err; + +@@ -571,7 +570,7 @@ static int qlcnic_sriov_setup_vf(struct qlcnic_adapter *adapter, + if (err) + goto err_out_send_channel_term; + +- err = qlcnic_setup_netdev(adapter, adapter->netdev, pci_using_dac); ++ err = qlcnic_setup_netdev(adapter, adapter->netdev); + if (err) + goto err_out_send_channel_term; + +@@ -614,7 +613,7 @@ static int qlcnic_sriov_check_dev_ready(struct qlcnic_adapter *adapter) + return 0; + } + +-int qlcnic_sriov_vf_init(struct qlcnic_adapter *adapter, int pci_using_dac) ++int qlcnic_sriov_vf_init(struct qlcnic_adapter *adapter) + { + struct qlcnic_hardware_context *ahw = adapter->ahw; + int err; +@@ -631,7 +630,7 @@ int qlcnic_sriov_vf_init(struct qlcnic_adapter *adapter, int pci_using_dac) + if (err) + return err; + +- err = qlcnic_sriov_setup_vf(adapter, pci_using_dac); ++ err = qlcnic_sriov_setup_vf(adapter); + if (err) + return err; + + diff --git a/patches.suse/qlcnic-make-the-array-random_data-static-const-makes-object-smaller.patch b/patches.suse/qlcnic-make-the-array-random_data-static-const-makes-object-smaller.patch new file mode 100644 index 0000000..ac38931 --- /dev/null +++ b/patches.suse/qlcnic-make-the-array-random_data-static-const-makes-object-smaller.patch @@ -0,0 +1,42 @@ +From: Colin Ian King +Date: Sun, 1 Aug 2021 16:16:59 +0100 +Subject: qlcnic: make the array random_data static const, makes object smaller +Git-commit: a6afdb041a2d7f514711b3bd27227e83d3cd9cf4 +Patch-mainline: v5.15-rc1 +References: jsc#PED-1302 + +Don't populate the array random_data on the stack but instead it +static const. Makes the object code smaller by 66 bytes. + +Before: + text data bss dec hex filename + 52895 10976 0 63871 f97f ../qlogic/qlcnic/qlcnic_ethtool.o + +After: + text data bss dec hex filename + 52701 11104 0 63805 f93d ../qlogic//qlcnic/qlcnic_ethtool.o + +(gcc version 10.2.0) + +Signed-off-by: Colin Ian King +Link: https://lore.kernel.org/r/20210801151659.146113-1-colin.king@canonical.com +Signed-off-by: Jakub Kicinski +Acked-by: Lee Duncan +--- + drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c +index d8f0863b3934..f6b6651decf3 100644 +--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c ++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c +@@ -1021,7 +1021,7 @@ static int qlcnic_irq_test(struct net_device *netdev) + + static void qlcnic_create_loopback_buff(unsigned char *data, u8 mac[]) + { +- unsigned char random_data[] = {0xa8, 0x06, 0x45, 0x00}; ++ static const unsigned char random_data[] = {0xa8, 0x06, 0x45, 0x00}; + + memset(data, 0x4e, QLCNIC_ILB_PKT_SIZE); + + diff --git a/patches.suse/qlcnic-remove-redundant-assignment-to-variable-index.patch b/patches.suse/qlcnic-remove-redundant-assignment-to-variable-index.patch new file mode 100644 index 0000000..8e769b3 --- /dev/null +++ b/patches.suse/qlcnic-remove-redundant-assignment-to-variable-index.patch @@ -0,0 +1,38 @@ +From: Colin Ian King +Date: Fri, 18 Mar 2022 01:20:35 +0000 +Subject: qlcnic: remove redundant assignment to variable index +Git-commit: 79fdce0513aceff7666e2e4dfa8fc28ea381d3a7 +Patch-mainline: v5.18-rc1 +References: jsc#PED-1302 + +Variable index is being assigned a value that is never read, it is being +re-assigned later in a following for-loop. The assignment is redundant +and can be removed. + +Cleans up clang scan build warning: +drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c:1358:17: warning: +Although the value stored to 'index' is used in the enclosing expression, +the value is never actually read from 'index' [deadcode.DeadStores] + +Signed-off-by: Colin Ian King +Link: https://lore.kernel.org/r/20220318012035.89482-1-colin.i.king@gmail.com +Signed-off-by: Jakub Kicinski +Acked-by: Lee Duncan +--- + drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c +index e10fe071a40f..54a2d653be63 100644 +--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c ++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c +@@ -1355,7 +1355,7 @@ static void qlcnic_get_ethtool_stats(struct net_device *dev, + + memset(data, 0, stats->n_stats * sizeof(u64)); + +- for (ring = 0, index = 0; ring < adapter->drv_tx_rings; ring++) { ++ for (ring = 0; ring < adapter->drv_tx_rings; ring++) { + if (adapter->is_up == QLCNIC_ADAPTER_UP_MAGIC) { + tx_ring = &adapter->tx_ring[ring]; + data = qlcnic_fill_tx_queue_stats(data, tx_ring); + diff --git a/patches.suse/qlcnic-switch-from-pci_-to-dma_-API.patch b/patches.suse/qlcnic-switch-from-pci_-to-dma_-API.patch new file mode 100644 index 0000000..5c30fd0 --- /dev/null +++ b/patches.suse/qlcnic-switch-from-pci_-to-dma_-API.patch @@ -0,0 +1,288 @@ +From: Christophe JAILLET +Date: Sun, 22 Aug 2021 22:42:45 +0200 +Subject: qlcnic: switch from 'pci_' to 'dma_' API +Git-commit: a14e39041b20187f9f74b638fabc6f5ef5aef92d +Patch-mainline: v5.15-rc1 +References: jsc#PED-1302 + +The wrappers in include/linux/pci-dma-compat.h should go away. + +The patch has been generated with the coccinelle script below. + +It has been hand modified to use 'dma_set_mask_and_coherent()' instead of +'pci_set_dma_mask()/pci_set_consistent_dma_mask()' when applicable. +This is less verbose. + +It has been compile tested. + +@@ +@@ +- PCI_DMA_BIDIRECTIONAL ++ DMA_BIDIRECTIONAL + +@@ +@@ +- PCI_DMA_TODEVICE ++ DMA_TO_DEVICE + +@@ +@@ +- PCI_DMA_FROMDEVICE ++ DMA_FROM_DEVICE + +@@ +@@ +- PCI_DMA_NONE ++ DMA_NONE + +@@ +expression e1, e2, e3; +@@ +- pci_alloc_consistent(e1, e2, e3) ++ dma_alloc_coherent(&e1->dev, e2, e3, GFP_) + +@@ +expression e1, e2, e3; +@@ +- pci_zalloc_consistent(e1, e2, e3) ++ dma_alloc_coherent(&e1->dev, e2, e3, GFP_) + +@@ +expression e1, e2, e3, e4; +@@ +- pci_free_consistent(e1, e2, e3, e4) ++ dma_free_coherent(&e1->dev, e2, e3, e4) + +@@ +expression e1, e2, e3, e4; +@@ +- pci_map_single(e1, e2, e3, e4) ++ dma_map_single(&e1->dev, e2, e3, e4) + +@@ +expression e1, e2, e3, e4; +@@ +- pci_unmap_single(e1, e2, e3, e4) ++ dma_unmap_single(&e1->dev, e2, e3, e4) + +@@ +expression e1, e2, e3, e4, e5; +@@ +- pci_map_page(e1, e2, e3, e4, e5) ++ dma_map_page(&e1->dev, e2, e3, e4, e5) + +@@ +expression e1, e2, e3, e4; +@@ +- pci_unmap_page(e1, e2, e3, e4) ++ dma_unmap_page(&e1->dev, e2, e3, e4) + +@@ +expression e1, e2, e3, e4; +@@ +- pci_map_sg(e1, e2, e3, e4) ++ dma_map_sg(&e1->dev, e2, e3, e4) + +@@ +expression e1, e2, e3, e4; +@@ +- pci_unmap_sg(e1, e2, e3, e4) ++ dma_unmap_sg(&e1->dev, e2, e3, e4) + +@@ +expression e1, e2, e3, e4; +@@ +- pci_dma_sync_single_for_cpu(e1, e2, e3, e4) ++ dma_sync_single_for_cpu(&e1->dev, e2, e3, e4) + +@@ +expression e1, e2, e3, e4; +@@ +- pci_dma_sync_single_for_device(e1, e2, e3, e4) ++ dma_sync_single_for_device(&e1->dev, e2, e3, e4) + +@@ +expression e1, e2, e3, e4; +@@ +- pci_dma_sync_sg_for_cpu(e1, e2, e3, e4) ++ dma_sync_sg_for_cpu(&e1->dev, e2, e3, e4) + +@@ +expression e1, e2, e3, e4; +@@ +- pci_dma_sync_sg_for_device(e1, e2, e3, e4) ++ dma_sync_sg_for_device(&e1->dev, e2, e3, e4) + +@@ +expression e1, e2; +@@ +- pci_dma_mapping_error(e1, e2) ++ dma_mapping_error(&e1->dev, e2) + +@@ +expression e1, e2; +@@ +- pci_set_dma_mask(e1, e2) ++ dma_set_mask(&e1->dev, e2) + +@@ +expression e1, e2; +@@ +- pci_set_consistent_dma_mask(e1, e2) ++ dma_set_coherent_mask(&e1->dev, e2) + +Signed-off-by: Christophe JAILLET +Signed-off-by: David S. Miller +Acked-by: Lee Duncan +--- + drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c | 16 ++++++------ + drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c | 32 ++++++++++++------------ + drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 6 ++--- + 3 files changed, 25 insertions(+), 29 deletions(-) + +diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c +index e6784023bce4..3d61a767a8a3 100644 +--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c ++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c +@@ -94,10 +94,8 @@ void qlcnic_release_rx_buffers(struct qlcnic_adapter *adapter) + if (rx_buf->skb == NULL) + continue; + +- pci_unmap_single(adapter->pdev, +- rx_buf->dma, +- rds_ring->dma_size, +- PCI_DMA_FROMDEVICE); ++ dma_unmap_single(&adapter->pdev->dev, rx_buf->dma, ++ rds_ring->dma_size, DMA_FROM_DEVICE); + + dev_kfree_skb_any(rx_buf->skb); + } +@@ -139,16 +137,16 @@ void qlcnic_release_tx_buffers(struct qlcnic_adapter *adapter, + for (i = 0; i < tx_ring->num_desc; i++) { + buffrag = cmd_buf->frag_array; + if (buffrag->dma) { +- pci_unmap_single(adapter->pdev, buffrag->dma, +- buffrag->length, PCI_DMA_TODEVICE); ++ dma_unmap_single(&adapter->pdev->dev, buffrag->dma, ++ buffrag->length, DMA_TO_DEVICE); + buffrag->dma = 0ULL; + } + for (j = 1; j < cmd_buf->frag_count; j++) { + buffrag++; + if (buffrag->dma) { +- pci_unmap_page(adapter->pdev, buffrag->dma, +- buffrag->length, +- PCI_DMA_TODEVICE); ++ dma_unmap_page(&adapter->pdev->dev, ++ buffrag->dma, buffrag->length, ++ DMA_TO_DEVICE); + buffrag->dma = 0ULL; + } + } +diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c +index af4c516a9e7c..29cdcb2285b1 100644 +--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c ++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c +@@ -587,9 +587,9 @@ static int qlcnic_map_tx_skb(struct pci_dev *pdev, struct sk_buff *skb, + nr_frags = skb_shinfo(skb)->nr_frags; + nf = &pbuf->frag_array[0]; + +- map = pci_map_single(pdev, skb->data, skb_headlen(skb), +- PCI_DMA_TODEVICE); +- if (pci_dma_mapping_error(pdev, map)) ++ map = dma_map_single(&pdev->dev, skb->data, skb_headlen(skb), ++ DMA_TO_DEVICE); ++ if (dma_mapping_error(&pdev->dev, map)) + goto out_err; + + nf->dma = map; +@@ -612,11 +612,11 @@ static int qlcnic_map_tx_skb(struct pci_dev *pdev, struct sk_buff *skb, + unwind: + while (--i >= 0) { + nf = &pbuf->frag_array[i+1]; +- pci_unmap_page(pdev, nf->dma, nf->length, PCI_DMA_TODEVICE); ++ dma_unmap_page(&pdev->dev, nf->dma, nf->length, DMA_TO_DEVICE); + } + + nf = &pbuf->frag_array[0]; +- pci_unmap_single(pdev, nf->dma, skb_headlen(skb), PCI_DMA_TODEVICE); ++ dma_unmap_single(&pdev->dev, nf->dma, skb_headlen(skb), DMA_TO_DEVICE); + + out_err: + return -ENOMEM; +@@ -630,11 +630,11 @@ static void qlcnic_unmap_buffers(struct pci_dev *pdev, struct sk_buff *skb, + + for (i = 0; i < nr_frags; i++) { + nf = &pbuf->frag_array[i+1]; +- pci_unmap_page(pdev, nf->dma, nf->length, PCI_DMA_TODEVICE); ++ dma_unmap_page(&pdev->dev, nf->dma, nf->length, DMA_TO_DEVICE); + } + + nf = &pbuf->frag_array[0]; +- pci_unmap_single(pdev, nf->dma, skb_headlen(skb), PCI_DMA_TODEVICE); ++ dma_unmap_single(&pdev->dev, nf->dma, skb_headlen(skb), DMA_TO_DEVICE); + pbuf->skb = NULL; + } + +@@ -825,10 +825,10 @@ static int qlcnic_alloc_rx_skb(struct qlcnic_adapter *adapter, + } + + skb_reserve(skb, NET_IP_ALIGN); +- dma = pci_map_single(pdev, skb->data, +- rds_ring->dma_size, PCI_DMA_FROMDEVICE); ++ dma = dma_map_single(&pdev->dev, skb->data, rds_ring->dma_size, ++ DMA_FROM_DEVICE); + +- if (pci_dma_mapping_error(pdev, dma)) { ++ if (dma_mapping_error(&pdev->dev, dma)) { + adapter->stats.rx_dma_map_error++; + dev_kfree_skb_any(skb); + return -ENOMEM; +@@ -903,13 +903,13 @@ static int qlcnic_process_cmd_ring(struct qlcnic_adapter *adapter, + buffer = &tx_ring->cmd_buf_arr[sw_consumer]; + if (buffer->skb) { + frag = &buffer->frag_array[0]; +- pci_unmap_single(pdev, frag->dma, frag->length, +- PCI_DMA_TODEVICE); ++ dma_unmap_single(&pdev->dev, frag->dma, frag->length, ++ DMA_TO_DEVICE); + frag->dma = 0ULL; + for (i = 1; i < buffer->frag_count; i++) { + frag++; +- pci_unmap_page(pdev, frag->dma, frag->length, +- PCI_DMA_TODEVICE); ++ dma_unmap_page(&pdev->dev, frag->dma, ++ frag->length, DMA_TO_DEVICE); + frag->dma = 0ULL; + } + tx_ring->tx_stats.xmit_finished++; +@@ -1147,8 +1147,8 @@ static struct sk_buff *qlcnic_process_rxbuf(struct qlcnic_adapter *adapter, + return NULL; + } + +- pci_unmap_single(adapter->pdev, buffer->dma, ring->dma_size, +- PCI_DMA_FROMDEVICE); ++ dma_unmap_single(&adapter->pdev->dev, buffer->dma, ring->dma_size, ++ DMA_FROM_DEVICE); + + skb = buffer->skb; + if (likely((adapter->netdev->features & NETIF_F_RXCSUM) && +diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +index a4fa507903ee..75960a29f80e 100644 +--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c ++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +@@ -2343,11 +2343,9 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev, + + static int qlcnic_set_dma_mask(struct pci_dev *pdev, int *pci_using_dac) + { +- if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) && +- !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) ++ if (!dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64))) + *pci_using_dac = 1; +- else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) && +- !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) ++ else if (!dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) + *pci_using_dac = 0; + else { + dev_err(&pdev->dev, "Unable to set DMA mask, aborting\n"); + diff --git a/patches.suse/regulator-pfuze100-Fix-the-global-out-of-bounds-acce.patch b/patches.suse/regulator-pfuze100-Fix-the-global-out-of-bounds-acce.patch new file mode 100644 index 0000000..6c040b1 --- /dev/null +++ b/patches.suse/regulator-pfuze100-Fix-the-global-out-of-bounds-acce.patch @@ -0,0 +1,41 @@ +From 78e1e867f44e6bdc72c0e6a2609a3407642fb30b Mon Sep 17 00:00:00 2001 +From: Xiaolei Wang +Date: Thu, 25 Aug 2022 19:19:22 +0800 +Subject: [PATCH] regulator: pfuze100: Fix the global-out-of-bounds access in pfuze100_regulator_probe() +Git-commit: 78e1e867f44e6bdc72c0e6a2609a3407642fb30b +Patch-mainline: v6.0-rc5 +References: git-fixes + +The pfuze_chip::regulator_descs is an array of size +PFUZE100_MAX_REGULATOR, the pfuze_chip::pfuze_regulators +is the pointer to the real regulators of a specific device. +The number of real regulator is supposed to be less than +the PFUZE100_MAX_REGULATOR, so we should use the size of +'regulator_num * sizeof(struct pfuze_regulator)' in memcpy(). +This fixes the out of bounds access bug reported by KASAN. + +Signed-off-by: Xiaolei Wang +Link: https://lore.kernel.org/r/20220825111922.1368055-1-xiaolei.wang@windriver.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + drivers/regulator/pfuze100-regulator.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/regulator/pfuze100-regulator.c b/drivers/regulator/pfuze100-regulator.c +index 6b617024a67d..d899d6e98fb8 100644 +--- a/drivers/regulator/pfuze100-regulator.c ++++ b/drivers/regulator/pfuze100-regulator.c +@@ -766,7 +766,7 @@ static int pfuze100_regulator_probe(struct i2c_client *client, + ((pfuze_chip->chip_id == PFUZE3000) ? "3000" : "3001")))); + + memcpy(pfuze_chip->regulator_descs, pfuze_chip->pfuze_regulators, +- sizeof(pfuze_chip->regulator_descs)); ++ regulator_num * sizeof(struct pfuze_regulator)); + + ret = pfuze_parse_regulators_dt(pfuze_chip); + if (ret) +-- +2.35.3 + diff --git a/patches.suse/regulator-qcom_rpm-Fix-circular-deferral-regression.patch b/patches.suse/regulator-qcom_rpm-Fix-circular-deferral-regression.patch new file mode 100644 index 0000000..fa35cc7 --- /dev/null +++ b/patches.suse/regulator-qcom_rpm-Fix-circular-deferral-regression.patch @@ -0,0 +1,104 @@ +From 8478ed5844588703a1a4c96a004b1525fbdbdd5e Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Fri, 9 Sep 2022 13:25:29 +0200 +Subject: [PATCH] regulator: qcom_rpm: Fix circular deferral regression +Git-commit: 8478ed5844588703a1a4c96a004b1525fbdbdd5e +Patch-mainline: v6.1-rc1 +References: git-fixes + +On recent kernels, the PM8058 L16 (or any other PM8058 LDO-regulator) +does not come up if they are supplied by an SMPS-regulator. This +is not very strange since the regulators are registered in a long +array and the L-regulators are registered before the S-regulators, +and if an L-regulator defers, it will never get around to registering +the S-regulator that it needs. + +See arch/arm/boot/dts/qcom-apq8060-dragonboard.dts: + +pm8058-regulators { + (...) + vdd_l13_l16-supply = <&pm8058_s4>; + (...) + +Ooops. + +Fix this by moving the PM8058 S-regulators first in the array. + +Do the same for the PM8901 S-regulators (though this is currently +not causing any problems with out device trees) so that the pattern +of registration order is the same on all PMnnnn chips. + +Fixes: 087a1b5cdd55 ("regulator: qcom: Rework to single platform device") +Cc: stable@vger.kernel.org +Cc: Andy Gross +Cc: Bjorn Andersson +Cc: Konrad Dybcio +Cc: linux-arm-msm@vger.kernel.org +Signed-off-by: Linus Walleij +Link: https://lore.kernel.org/r/20220909112529.239143-1-linus.walleij@linaro.org +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + drivers/regulator/qcom_rpm-regulator.c | 24 ++++++++++++------------ + 1 file changed, 12 insertions(+), 12 deletions(-) + +diff --git a/drivers/regulator/qcom_rpm-regulator.c b/drivers/regulator/qcom_rpm-regulator.c +index 7f9d66ac37ff..3c41b71a1f52 100644 +--- a/drivers/regulator/qcom_rpm-regulator.c ++++ b/drivers/regulator/qcom_rpm-regulator.c +@@ -802,6 +802,12 @@ static const struct rpm_regulator_data rpm_pm8018_regulators[] = { + }; + + static const struct rpm_regulator_data rpm_pm8058_regulators[] = { ++ { "s0", QCOM_RPM_PM8058_SMPS0, &pm8058_smps, "vdd_s0" }, ++ { "s1", QCOM_RPM_PM8058_SMPS1, &pm8058_smps, "vdd_s1" }, ++ { "s2", QCOM_RPM_PM8058_SMPS2, &pm8058_smps, "vdd_s2" }, ++ { "s3", QCOM_RPM_PM8058_SMPS3, &pm8058_smps, "vdd_s3" }, ++ { "s4", QCOM_RPM_PM8058_SMPS4, &pm8058_smps, "vdd_s4" }, ++ + { "l0", QCOM_RPM_PM8058_LDO0, &pm8058_nldo, "vdd_l0_l1_lvs" }, + { "l1", QCOM_RPM_PM8058_LDO1, &pm8058_nldo, "vdd_l0_l1_lvs" }, + { "l2", QCOM_RPM_PM8058_LDO2, &pm8058_pldo, "vdd_l2_l11_l12" }, +@@ -829,12 +835,6 @@ static const struct rpm_regulator_data rpm_pm8058_regulators[] = { + { "l24", QCOM_RPM_PM8058_LDO24, &pm8058_nldo, "vdd_l23_l24_l25" }, + { "l25", QCOM_RPM_PM8058_LDO25, &pm8058_nldo, "vdd_l23_l24_l25" }, + +- { "s0", QCOM_RPM_PM8058_SMPS0, &pm8058_smps, "vdd_s0" }, +- { "s1", QCOM_RPM_PM8058_SMPS1, &pm8058_smps, "vdd_s1" }, +- { "s2", QCOM_RPM_PM8058_SMPS2, &pm8058_smps, "vdd_s2" }, +- { "s3", QCOM_RPM_PM8058_SMPS3, &pm8058_smps, "vdd_s3" }, +- { "s4", QCOM_RPM_PM8058_SMPS4, &pm8058_smps, "vdd_s4" }, +- + { "lvs0", QCOM_RPM_PM8058_LVS0, &pm8058_switch, "vdd_l0_l1_lvs" }, + { "lvs1", QCOM_RPM_PM8058_LVS1, &pm8058_switch, "vdd_l0_l1_lvs" }, + +@@ -843,6 +843,12 @@ static const struct rpm_regulator_data rpm_pm8058_regulators[] = { + }; + + static const struct rpm_regulator_data rpm_pm8901_regulators[] = { ++ { "s0", QCOM_RPM_PM8901_SMPS0, &pm8901_ftsmps, "vdd_s0" }, ++ { "s1", QCOM_RPM_PM8901_SMPS1, &pm8901_ftsmps, "vdd_s1" }, ++ { "s2", QCOM_RPM_PM8901_SMPS2, &pm8901_ftsmps, "vdd_s2" }, ++ { "s3", QCOM_RPM_PM8901_SMPS3, &pm8901_ftsmps, "vdd_s3" }, ++ { "s4", QCOM_RPM_PM8901_SMPS4, &pm8901_ftsmps, "vdd_s4" }, ++ + { "l0", QCOM_RPM_PM8901_LDO0, &pm8901_nldo, "vdd_l0" }, + { "l1", QCOM_RPM_PM8901_LDO1, &pm8901_pldo, "vdd_l1" }, + { "l2", QCOM_RPM_PM8901_LDO2, &pm8901_pldo, "vdd_l2" }, +@@ -851,12 +857,6 @@ static const struct rpm_regulator_data rpm_pm8901_regulators[] = { + { "l5", QCOM_RPM_PM8901_LDO5, &pm8901_pldo, "vdd_l5" }, + { "l6", QCOM_RPM_PM8901_LDO6, &pm8901_pldo, "vdd_l6" }, + +- { "s0", QCOM_RPM_PM8901_SMPS0, &pm8901_ftsmps, "vdd_s0" }, +- { "s1", QCOM_RPM_PM8901_SMPS1, &pm8901_ftsmps, "vdd_s1" }, +- { "s2", QCOM_RPM_PM8901_SMPS2, &pm8901_ftsmps, "vdd_s2" }, +- { "s3", QCOM_RPM_PM8901_SMPS3, &pm8901_ftsmps, "vdd_s3" }, +- { "s4", QCOM_RPM_PM8901_SMPS4, &pm8901_ftsmps, "vdd_s4" }, +- + { "lvs0", QCOM_RPM_PM8901_LVS0, &pm8901_switch, "lvs0_in" }, + { "lvs1", QCOM_RPM_PM8901_LVS1, &pm8901_switch, "lvs1_in" }, + { "lvs2", QCOM_RPM_PM8901_LVS2, &pm8901_switch, "lvs2_in" }, +-- +2.35.3 + diff --git a/patches.suse/remoteproc-imx_rproc-Simplify-some-error-message.patch b/patches.suse/remoteproc-imx_rproc-Simplify-some-error-message.patch new file mode 100644 index 0000000..3da311e --- /dev/null +++ b/patches.suse/remoteproc-imx_rproc-Simplify-some-error-message.patch @@ -0,0 +1,63 @@ +From a1c3611dcfb08e62e165ab5c00122dd13f210166 Mon Sep 17 00:00:00 2001 +From: Christophe JAILLET +Date: Sat, 6 Aug 2022 00:02:32 +0200 +Subject: [PATCH] remoteproc: imx_rproc: Simplify some error message +Git-commit: a1c3611dcfb08e62e165ab5c00122dd13f210166 +Patch-mainline: v6.1-rc1 +References: git-fixes + +dev_err_probe() already prints the error code in a human readable way, so +there is no need to duplicate it as a numerical value at the end of the +message. + +While at it, remove 'ret' that is mostly useless. + +Fixes: 2df7062002d0 ("remoteproc: imx_proc: enable virtio/mailbox") +Signed-off-by: Christophe JAILLET +Link: https://lore.kernel.org/r/6b9343c2688117a340661d8ee491c2962c54a09a.1659736936.git.christophe.jaillet@wanadoo.fr +Signed-off-by: Mathieu Poirier +Acked-by: Takashi Iwai + +--- + drivers/remoteproc/imx_rproc.c | 14 +++++--------- + 1 file changed, 5 insertions(+), 9 deletions(-) + +diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c +index 38383e7de3c1..7cc4fd207e2d 100644 +--- a/drivers/remoteproc/imx_rproc.c ++++ b/drivers/remoteproc/imx_rproc.c +@@ -646,7 +646,6 @@ static int imx_rproc_xtr_mbox_init(struct rproc *rproc) + struct imx_rproc *priv = rproc->priv; + struct device *dev = priv->dev; + struct mbox_client *cl; +- int ret; + + if (!of_get_property(dev->of_node, "mbox-names", NULL)) + return 0; +@@ -659,18 +658,15 @@ static int imx_rproc_xtr_mbox_init(struct rproc *rproc) + cl->rx_callback = imx_rproc_rx_callback; + + priv->tx_ch = mbox_request_channel_byname(cl, "tx"); +- if (IS_ERR(priv->tx_ch)) { +- ret = PTR_ERR(priv->tx_ch); +- return dev_err_probe(cl->dev, ret, +- "failed to request tx mailbox channel: %d\n", ret); +- } ++ if (IS_ERR(priv->tx_ch)) ++ return dev_err_probe(cl->dev, PTR_ERR(priv->tx_ch), ++ "failed to request tx mailbox channel\n"); + + priv->rx_ch = mbox_request_channel_byname(cl, "rx"); + if (IS_ERR(priv->rx_ch)) { + mbox_free_channel(priv->tx_ch); +- ret = PTR_ERR(priv->rx_ch); +- return dev_err_probe(cl->dev, ret, +- "failed to request rx mailbox channel: %d\n", ret); ++ return dev_err_probe(cl->dev, PTR_ERR(priv->rx_ch), ++ "failed to request rx mailbox channel\n"); + } + + return 0; +-- +2.35.3 + diff --git a/patches.suse/reset-imx7-Fix-the-iMX8MP-PCIe-PHY-PERST-support.patch b/patches.suse/reset-imx7-Fix-the-iMX8MP-PCIe-PHY-PERST-support.patch new file mode 100644 index 0000000..9d08804 --- /dev/null +++ b/patches.suse/reset-imx7-Fix-the-iMX8MP-PCIe-PHY-PERST-support.patch @@ -0,0 +1,44 @@ +From 051d9eb403887bb11852b7a4f744728a6a4b1b58 Mon Sep 17 00:00:00 2001 +From: Richard Zhu +Date: Tue, 30 Aug 2022 15:46:01 +0800 +Subject: [PATCH] reset: imx7: Fix the iMX8MP PCIe PHY PERST support +Git-commit: 051d9eb403887bb11852b7a4f744728a6a4b1b58 +Patch-mainline: v6.0 +References: git-fixes + +On i.MX7/iMX8MM/iMX8MQ, the initialized default value of PERST bit(BIT3) +of SRC_PCIEPHY_RCR is 1b'1. +But i.MX8MP has one inversed default value 1b'0 of PERST bit. + +And the PERST bit should be kept 1b'1 after power and clocks are stable. +So fix the i.MX8MP PCIe PHY PERST support here. + +Fixes: e08672c03981 ("reset: imx7: Add support for i.MX8MP SoC") +Signed-off-by: Richard Zhu +Reviewed-by: Philipp Zabel +Tested-by: Marek Vasut +Tested-by: Richard Leitner +Tested-by: Alexander Stein +Signed-off-by: Philipp Zabel +Link: https://lore.kernel.org/r/1661845564-11373-5-git-send-email-hongxing.zhu@nxp.com +Acked-by: Takashi Iwai + +--- + drivers/reset/reset-imx7.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/reset/reset-imx7.c b/drivers/reset/reset-imx7.c +index 185a333df66c..d2408725eb2c 100644 +--- a/drivers/reset/reset-imx7.c ++++ b/drivers/reset/reset-imx7.c +@@ -329,6 +329,7 @@ static int imx8mp_reset_set(struct reset_controller_dev *rcdev, + break; + + case IMX8MP_RESET_PCIE_CTRL_APPS_EN: ++ case IMX8MP_RESET_PCIEPHY_PERST: + value = assert ? 0 : bit; + break; + } +-- +2.35.3 + diff --git a/patches.suse/revert-x86-sev-expose-sev_es_ghcb_hv_call-for-use-by-hyperv.patch b/patches.suse/revert-x86-sev-expose-sev_es_ghcb_hv_call-for-use-by-hyperv.patch index 3ab6ff0..83668e0 100644 --- a/patches.suse/revert-x86-sev-expose-sev_es_ghcb_hv_call-for-use-by-hyperv.patch +++ b/patches.suse/revert-x86-sev-expose-sev_es_ghcb_hv_call-for-use-by-hyperv.patch @@ -21,14 +21,14 @@ Signed-off-by: Borislav Petkov Reviewed-by:Tianyu Lan Link: https://lore.kernel.org/r/20220614014553.1915929-1-ltykernel@gmail.com --- - arch/x86/include/asm/sev.h | 7 +------ + arch/x86/include/asm/sev.h | 6 ------ arch/x86/kernel/sev-shared.c | 25 +++++++++---------------- - arch/x86/kernel/sev.c | 13 ++++++------- - 3 files changed, 16 insertions(+), 29 deletions(-) + arch/x86/kernel/sev.c | 17 ++++++++--------- + 3 files changed, 17 insertions(+), 31 deletions(-) --- a/arch/x86/include/asm/sev.h +++ b/arch/x86/include/asm/sev.h -@@ -53,7 +53,6 @@ static inline u64 lower_bits(u64 val, un +@@ -72,7 +72,6 @@ static inline u64 lower_bits(u64 val, un struct real_mode_header; enum stack_type; @@ -36,7 +36,7 @@ Link: https://lore.kernel.org/r/20220614014553.1915929-1-ltykernel@gmail.com /* Early IDT entry points for #VC handler */ extern void vc_no_ghcb(void); -@@ -82,11 +81,7 @@ static __always_inline void sev_es_nmi_c +@@ -117,11 +116,6 @@ static __always_inline void sev_es_nmi_c __sev_es_nmi_complete(); } extern int __init sev_es_efi_map_ghcbs(pgd_t *pgd); @@ -45,70 +45,12 @@ Link: https://lore.kernel.org/r/20220614014553.1915929-1-ltykernel@gmail.com - struct es_em_ctxt *ctxt, - u64 exit_code, u64 exit_info_1, - u64 exit_info_2); -+ - #else - static inline void sev_es_ist_enter(struct pt_regs *regs) { } - static inline void sev_es_ist_exit(void) { } ---- a/arch/x86/kernel/sev.c -+++ b/arch/x86/kernel/sev.c -@@ -633,8 +633,7 @@ static enum es_result vc_handle_msr(stru - ghcb_set_rdx(ghcb, regs->dx); - } - -- ret = sev_es_ghcb_hv_call(ghcb, true, ctxt, SVM_EXIT_MSR, -- exit_info_1, 0); -+ ret = sev_es_ghcb_hv_call(ghcb, ctxt, SVM_EXIT_MSR, exit_info_1, 0); - - if ((ret == ES_OK) && (!exit_info_1)) { - regs->ax = ghcb->save.rax; -@@ -852,7 +851,7 @@ static enum es_result vc_do_mmio(struct - - ghcb_set_sw_scratch(ghcb, ghcb_pa + offsetof(struct ghcb, shared_buffer)); - -- return sev_es_ghcb_hv_call(ghcb, true, ctxt, exit_code, exit_info_1, exit_info_2); -+ return sev_es_ghcb_hv_call(ghcb, ctxt, exit_code, exit_info_1, exit_info_2); - } - - static enum es_result vc_handle_mmio_twobyte_ops(struct ghcb *ghcb, -@@ -1102,7 +1101,7 @@ static enum es_result vc_handle_dr7_writ - - /* Using a value of 0 for ExitInfo1 means RAX holds the value */ - ghcb_set_rax(ghcb, val); -- ret = sev_es_ghcb_hv_call(ghcb, true, ctxt, SVM_EXIT_WRITE_DR7, 0, 0); -+ ret = sev_es_ghcb_hv_call(ghcb, ctxt, SVM_EXIT_WRITE_DR7, 0, 0); - if (ret != ES_OK) - return ret; - -@@ -1132,7 +1131,7 @@ static enum es_result vc_handle_dr7_read - static enum es_result vc_handle_wbinvd(struct ghcb *ghcb, - struct es_em_ctxt *ctxt) + static inline int rmpadjust(unsigned long vaddr, bool rmp_psize, unsigned long attrs) { -- return sev_es_ghcb_hv_call(ghcb, true, ctxt, SVM_EXIT_WBINVD, 0, 0); -+ return sev_es_ghcb_hv_call(ghcb, ctxt, SVM_EXIT_WBINVD, 0, 0); - } - - static enum es_result vc_handle_rdpmc(struct ghcb *ghcb, struct es_em_ctxt *ctxt) -@@ -1141,7 +1140,7 @@ static enum es_result vc_handle_rdpmc(st - - ghcb_set_rcx(ghcb, ctxt->regs->cx); - -- ret = sev_es_ghcb_hv_call(ghcb, true, ctxt, SVM_EXIT_RDPMC, 0, 0); -+ ret = sev_es_ghcb_hv_call(ghcb, ctxt, SVM_EXIT_RDPMC, 0, 0); - if (ret != ES_OK) - return ret; - -@@ -1182,7 +1181,7 @@ static enum es_result vc_handle_vmmcall( - if (x86_platform.hyper.sev_es_hcall_prepare) - x86_platform.hyper.sev_es_hcall_prepare(ghcb, ctxt->regs); - -- ret = sev_es_ghcb_hv_call(ghcb, true, ctxt, SVM_EXIT_VMMCALL, 0, 0); -+ ret = sev_es_ghcb_hv_call(ghcb, ctxt, SVM_EXIT_VMMCALL, 0, 0); - if (ret != ES_OK) - return ret; - + int rc; --- a/arch/x86/kernel/sev-shared.c +++ b/arch/x86/kernel/sev-shared.c -@@ -133,9 +133,10 @@ static enum es_result verify_exception_i +@@ -222,9 +222,10 @@ static enum es_result verify_exception_i return ES_VMM_ERROR; } @@ -122,7 +64,7 @@ Link: https://lore.kernel.org/r/20220614014553.1915929-1-ltykernel@gmail.com { /* Fill in protocol and format specifiers */ ghcb->protocol_version = ghcb_version; -@@ -145,14 +146,7 @@ enum es_result sev_es_ghcb_hv_call(struc +@@ -234,14 +235,7 @@ enum es_result sev_es_ghcb_hv_call(struc ghcb_set_sw_exit_info_1(ghcb, exit_info_1); ghcb_set_sw_exit_info_2(ghcb, exit_info_2); @@ -138,7 +80,7 @@ Link: https://lore.kernel.org/r/20220614014553.1915929-1-ltykernel@gmail.com VMGEXIT(); return verify_exception_info(ghcb, ctxt); -@@ -432,7 +426,7 @@ static enum es_result vc_handle_ioio(str +@@ -798,7 +792,7 @@ static enum es_result vc_handle_ioio(str */ sw_scratch = __pa(ghcb) + offsetof(struct ghcb, shared_buffer); ghcb_set_sw_scratch(ghcb, sw_scratch); @@ -147,7 +89,7 @@ Link: https://lore.kernel.org/r/20220614014553.1915929-1-ltykernel@gmail.com exit_info_1, exit_info_2); if (ret != ES_OK) return ret; -@@ -474,8 +468,7 @@ static enum es_result vc_handle_ioio(str +@@ -840,8 +834,7 @@ static enum es_result vc_handle_ioio(str ghcb_set_rax(ghcb, rax); @@ -157,7 +99,7 @@ Link: https://lore.kernel.org/r/20220614014553.1915929-1-ltykernel@gmail.com if (ret != ES_OK) return ret; -@@ -506,7 +499,7 @@ static enum es_result vc_handle_cpuid(st +@@ -897,7 +890,7 @@ static enum es_result vc_handle_cpuid(st /* xgetbv will cause #GP - use reset value for xcr0 */ ghcb_set_xcr0(ghcb, 1); @@ -166,7 +108,7 @@ Link: https://lore.kernel.org/r/20220614014553.1915929-1-ltykernel@gmail.com if (ret != ES_OK) return ret; -@@ -531,7 +524,7 @@ static enum es_result vc_handle_rdtsc(st +@@ -922,7 +915,7 @@ static enum es_result vc_handle_rdtsc(st bool rdtscp = (exit_code == SVM_EXIT_RDTSCP); enum es_result ret; @@ -175,3 +117,78 @@ Link: https://lore.kernel.org/r/20220614014553.1915929-1-ltykernel@gmail.com if (ret != ES_OK) return ret; +--- a/arch/x86/kernel/sev.c ++++ b/arch/x86/kernel/sev.c +@@ -728,7 +728,7 @@ static int vmgexit_psc(struct snp_psc_de + ghcb_set_sw_scratch(ghcb, (u64)__pa(data)); + + /* This will advance the shared buffer data points to. */ +- ret = sev_es_ghcb_hv_call(ghcb, true, &ctxt, SVM_VMGEXIT_PSC, 0, 0); ++ ret = sev_es_ghcb_hv_call(ghcb, &ctxt, SVM_VMGEXIT_PSC, 0, 0); + + /* + * Page State Change VMGEXIT can pass error code through +@@ -1154,8 +1154,7 @@ static enum es_result vc_handle_msr(stru + ghcb_set_rdx(ghcb, regs->dx); + } + +- ret = sev_es_ghcb_hv_call(ghcb, true, ctxt, SVM_EXIT_MSR, +- exit_info_1, 0); ++ ret = sev_es_ghcb_hv_call(ghcb, ctxt, SVM_EXIT_MSR, exit_info_1, 0); + + if ((ret == ES_OK) && (!exit_info_1)) { + regs->ax = ghcb->save.rax; +@@ -1410,7 +1409,7 @@ static enum es_result vc_do_mmio(struct + + ghcb_set_sw_scratch(ghcb, ghcb_pa + offsetof(struct ghcb, shared_buffer)); + +- return sev_es_ghcb_hv_call(ghcb, true, ctxt, exit_code, exit_info_1, exit_info_2); ++ return sev_es_ghcb_hv_call(ghcb, ctxt, exit_code, exit_info_1, exit_info_2); + } + + static enum es_result vc_handle_mmio_twobyte_ops(struct ghcb *ghcb, +@@ -1660,7 +1659,7 @@ static enum es_result vc_handle_dr7_writ + + /* Using a value of 0 for ExitInfo1 means RAX holds the value */ + ghcb_set_rax(ghcb, val); +- ret = sev_es_ghcb_hv_call(ghcb, true, ctxt, SVM_EXIT_WRITE_DR7, 0, 0); ++ ret = sev_es_ghcb_hv_call(ghcb, ctxt, SVM_EXIT_WRITE_DR7, 0, 0); + if (ret != ES_OK) + return ret; + +@@ -1690,7 +1689,7 @@ static enum es_result vc_handle_dr7_read + static enum es_result vc_handle_wbinvd(struct ghcb *ghcb, + struct es_em_ctxt *ctxt) + { +- return sev_es_ghcb_hv_call(ghcb, true, ctxt, SVM_EXIT_WBINVD, 0, 0); ++ return sev_es_ghcb_hv_call(ghcb, ctxt, SVM_EXIT_WBINVD, 0, 0); + } + + static enum es_result vc_handle_rdpmc(struct ghcb *ghcb, struct es_em_ctxt *ctxt) +@@ -1699,7 +1698,7 @@ static enum es_result vc_handle_rdpmc(st + + ghcb_set_rcx(ghcb, ctxt->regs->cx); + +- ret = sev_es_ghcb_hv_call(ghcb, true, ctxt, SVM_EXIT_RDPMC, 0, 0); ++ ret = sev_es_ghcb_hv_call(ghcb, ctxt, SVM_EXIT_RDPMC, 0, 0); + if (ret != ES_OK) + return ret; + +@@ -1740,7 +1739,7 @@ static enum es_result vc_handle_vmmcall( + if (x86_platform.hyper.sev_es_hcall_prepare) + x86_platform.hyper.sev_es_hcall_prepare(ghcb, ctxt->regs); + +- ret = sev_es_ghcb_hv_call(ghcb, true, ctxt, SVM_EXIT_VMMCALL, 0, 0); ++ ret = sev_es_ghcb_hv_call(ghcb, ctxt, SVM_EXIT_VMMCALL, 0, 0); + if (ret != ES_OK) + return ret; + +@@ -2230,7 +2229,7 @@ int snp_issue_guest_request(u64 exit_cod + ghcb_set_rbx(ghcb, input->data_npages); + } + +- ret = sev_es_ghcb_hv_call(ghcb, true, &ctxt, exit_code, input->req_gpa, input->resp_gpa); ++ ret = sev_es_ghcb_hv_call(ghcb, &ctxt, exit_code, input->req_gpa, input->resp_gpa); + if (ret) + goto e_put; + diff --git a/patches.suse/rpmsg-qcom-glink-replace-strncpy-with-strscpy_pad.patch b/patches.suse/rpmsg-qcom-glink-replace-strncpy-with-strscpy_pad.patch new file mode 100644 index 0000000..1261934 --- /dev/null +++ b/patches.suse/rpmsg-qcom-glink-replace-strncpy-with-strscpy_pad.patch @@ -0,0 +1,72 @@ +From 766279a8f85df32345dbda03b102ca1ee3d5ddea Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +Date: Thu, 19 May 2022 09:33:28 +0200 +Subject: [PATCH] rpmsg: qcom: glink: replace strncpy() with strscpy_pad() +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 766279a8f85df32345dbda03b102ca1ee3d5ddea +Patch-mainline: v6.0-rc1 +References: git-fixes + +The use of strncpy() is considered deprecated for NUL-terminated +strings[1]. Replace strncpy() with strscpy_pad(), to keep existing +pad-behavior of strncpy, similarly to commit 08de420a8014 ("rpmsg: +Glink: Replace strncpy() with strscpy_pad()"). This fixes W=1 warning: + + In function ‘qcom_glink_rx_close’, + inlined from ‘qcom_glink_work’ at ../drivers/rpmsg/qcom_glink_native.c:1638:4: + drivers/rpmsg/qcom_glink_native.c:1549:17: warning: ‘strncpy’ specified bound 32 equals destination size [-Wstringop-truncation] + 1549 | strncpy(chinfo.name, channel->name, sizeof(chinfo.name)); + +[1] https://www.kernel.org/doc/html/latest/process/deprecated.html#strncpy-on-nul-terminated-strings + +Signed-off-by: Krzysztof Kozlowski +Reviewed-by: Stephen Boyd +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20220519073330.7187-1-krzysztof.kozlowski@linaro.org +Acked-by: Takashi Iwai + +--- + drivers/rpmsg/qcom_glink_native.c | 2 +- + drivers/rpmsg/qcom_smd.c | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c +index 07586514991f..5bc5a0a6a8a7 100644 +--- a/drivers/rpmsg/qcom_glink_native.c ++++ b/drivers/rpmsg/qcom_glink_native.c +@@ -1546,7 +1546,7 @@ static void qcom_glink_rx_close(struct qcom_glink *glink, unsigned int rcid) + cancel_work_sync(&channel->intent_work); + + if (channel->rpdev) { +- strncpy(chinfo.name, channel->name, sizeof(chinfo.name)); ++ strscpy_pad(chinfo.name, channel->name, sizeof(chinfo.name)); + chinfo.src = RPMSG_ADDR_ANY; + chinfo.dst = RPMSG_ADDR_ANY; + +diff --git a/drivers/rpmsg/qcom_smd.c b/drivers/rpmsg/qcom_smd.c +index 1957b27c4cf3..f41a065ed007 100644 +--- a/drivers/rpmsg/qcom_smd.c ++++ b/drivers/rpmsg/qcom_smd.c +@@ -1089,7 +1089,7 @@ static int qcom_smd_create_device(struct qcom_smd_channel *channel) + + /* Assign public information to the rpmsg_device */ + rpdev = &qsdev->rpdev; +- strncpy(rpdev->id.name, channel->name, RPMSG_NAME_SIZE); ++ strscpy_pad(rpdev->id.name, channel->name, RPMSG_NAME_SIZE); + rpdev->src = RPMSG_ADDR_ANY; + rpdev->dst = RPMSG_ADDR_ANY; + +@@ -1323,7 +1323,7 @@ static void qcom_channel_state_worker(struct work_struct *work) + + spin_unlock_irqrestore(&edge->channels_lock, flags); + +- strncpy(chinfo.name, channel->name, sizeof(chinfo.name)); ++ strscpy_pad(chinfo.name, channel->name, sizeof(chinfo.name)); + chinfo.src = RPMSG_ADDR_ANY; + chinfo.dst = RPMSG_ADDR_ANY; + rpmsg_unregister_device(&edge->dev, &chinfo); +-- +2.35.3 + diff --git a/patches.suse/rtc-stmp3xxx-Add-failure-handling-for-stmp3xxx_wdt_r.patch b/patches.suse/rtc-stmp3xxx-Add-failure-handling-for-stmp3xxx_wdt_r.patch new file mode 100644 index 0000000..505ba36 --- /dev/null +++ b/patches.suse/rtc-stmp3xxx-Add-failure-handling-for-stmp3xxx_wdt_r.patch @@ -0,0 +1,38 @@ +From 0759011157b0d666b02b03b986d3de005d84027e Mon Sep 17 00:00:00 2001 +From: Lin Yujun +Date: Thu, 15 Sep 2022 14:52:53 +0800 +Subject: [PATCH] rtc: stmp3xxx: Add failure handling for stmp3xxx_wdt_register() +Git-commit: 0759011157b0d666b02b03b986d3de005d84027e +Patch-mainline: v6.1-rc1 +References: git-fixes + +Use platform_device_put() to free platform device before print +error message when platform_device_add() fails to run. + +Fixes: 1a71fb84fda6 ("rtc: stmp3xxx: add wdt-accessor function") +Signed-off-by: Lin Yujun +Reviewed-by: Wolfram Sang +Link: https://lore.kernel.org/r/20220915065253.43668-1-linyujun809@huawei.com +Signed-off-by: Alexandre Belloni +Acked-by: Takashi Iwai + +--- + drivers/rtc/rtc-stmp3xxx.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/rtc/rtc-stmp3xxx.c b/drivers/rtc/rtc-stmp3xxx.c +index 40c0f7ed36e0..aae40d20d086 100644 +--- a/drivers/rtc/rtc-stmp3xxx.c ++++ b/drivers/rtc/rtc-stmp3xxx.c +@@ -107,6 +107,8 @@ static void stmp3xxx_wdt_register(struct platform_device *rtc_pdev) + wdt_pdev->dev.parent = &rtc_pdev->dev; + wdt_pdev->dev.platform_data = &wdt_pdata; + rc = platform_device_add(wdt_pdev); ++ if (rc) ++ platform_device_put(wdt_pdev); + } + + if (rc) +-- +2.35.3 + diff --git a/patches.suse/rtnetlink-add-extack-support-in-fdb-del-handlers.patch b/patches.suse/rtnetlink-add-extack-support-in-fdb-del-handlers.patch new file mode 100644 index 0000000..644ab3c --- /dev/null +++ b/patches.suse/rtnetlink-add-extack-support-in-fdb-del-handlers.patch @@ -0,0 +1,147 @@ +From: Alaa Mohamed +Date: Thu, 5 May 2022 17:09:57 +0200 +Subject: rtnetlink: add extack support in fdb del handlers +Git-commit: ca4567f1e6f660f86fcd04f3563c0045b0d4772f +Patch-mainline: v5.19-rc1 +References: jsc#PED-1302 + +Add extack support to .ndo_fdb_del in netdevice.h and +all related methods. + +[lduncan: hand refreshed to apply correctly in several files.] + +Signed-off-by: Alaa Mohamed +Signed-off-by: David S. Miller +Acked-by: Lee Duncan +--- + drivers/net/ethernet/intel/ice/ice_main.c | 3 ++- + drivers/net/ethernet/mscc/ocelot_net.c | 3 ++- + drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 3 ++- + drivers/net/macvlan.c | 3 ++- + drivers/net/vxlan.c | 3 ++- + include/linux/netdevice.h | 2 +- + net/bridge/br_fdb.c | 3 ++- + net/bridge/br_private.h | 3 ++- + net/core/rtnetlink.c | 5 ++--- + 9 files changed, 17 insertions(+), 11 deletions(-) + +--- a/drivers/net/ethernet/intel/ice/ice_main.c ++++ b/drivers/net/ethernet/intel/ice/ice_main.c +@@ -5690,11 +5690,12 @@ ice_fdb_add(struct ndmsg *ndm, struct nl + * @dev: the net device pointer + * @addr: the MAC address entry being added + * @vid: VLAN ID ++ * @extack: netlink extended ack + */ + static int + ice_fdb_del(struct ndmsg *ndm, __always_unused struct nlattr *tb[], + struct net_device *dev, const unsigned char *addr, +- __always_unused u16 vid) ++ __always_unused u16 vid, struct netlink_ext_ack *extack) + { + int err; + +--- a/drivers/net/ethernet/mscc/ocelot_net.c ++++ b/drivers/net/ethernet/mscc/ocelot_net.c +@@ -710,7 +710,8 @@ static int ocelot_port_fdb_add(struct nd + + static int ocelot_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], + struct net_device *dev, +- const unsigned char *addr, u16 vid) ++ const unsigned char *addr, u16 vid, ++ struct netlink_ext_ack *extack) + { + struct ocelot_port_private *priv = netdev_priv(dev); + struct ocelot *ocelot = priv->port.ocelot; +--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c ++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +@@ -368,7 +368,8 @@ static int qlcnic_set_mac(struct net_dev + + static int qlcnic_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], + struct net_device *netdev, +- const unsigned char *addr, u16 vid) ++ const unsigned char *addr, u16 vid, ++ struct netlink_ext_ack *extack) + { + struct qlcnic_adapter *adapter = netdev_priv(netdev); + int err = -EOPNOTSUPP; +--- a/drivers/net/macvlan.c ++++ b/drivers/net/macvlan.c +@@ -1017,7 +1017,8 @@ static int macvlan_fdb_add(struct ndmsg + + static int macvlan_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], + struct net_device *dev, +- const unsigned char *addr, u16 vid) ++ const unsigned char *addr, u16 vid, ++ struct netlink_ext_ack *extack) + { + struct macvlan_dev *vlan = netdev_priv(dev); + int err = -EINVAL; +--- a/drivers/net/vxlan.c ++++ b/drivers/net/vxlan.c +@@ -1343,7 +1343,8 @@ out: + /* Delete entry (via netlink) */ + static int vxlan_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[], + struct net_device *dev, +- const unsigned char *addr, u16 vid) ++ const unsigned char *addr, u16 vid, ++ struct netlink_ext_ack *extack) + { + struct vxlan_dev *vxlan = netdev_priv(dev); + union vxlan_addr ip; +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -1497,7 +1497,7 @@ struct net_device_ops { + struct nlattr *tb[], + struct net_device *dev, + const unsigned char *addr, +- u16 vid); ++ u16 vid, struct netlink_ext_ack *extack); + int (*ndo_fdb_dump)(struct sk_buff *skb, + struct netlink_callback *cb, + struct net_device *dev, +--- a/net/bridge/br_fdb.c ++++ b/net/bridge/br_fdb.c +@@ -1173,7 +1173,8 @@ static int __br_fdb_delete(struct net_br + /* Remove neighbor entry with RTM_DELNEIGH */ + int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[], + struct net_device *dev, +- const unsigned char *addr, u16 vid) ++ const unsigned char *addr, u16 vid, ++ struct netlink_ext_ack *extack) + { + struct net_bridge_vlan_group *vg; + struct net_bridge_port *p = NULL; +--- a/net/bridge/br_private.h ++++ b/net/bridge/br_private.h +@@ -699,7 +699,8 @@ void br_fdb_update(struct net_bridge *br + const unsigned char *addr, u16 vid, unsigned long flags); + + int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[], +- struct net_device *dev, const unsigned char *addr, u16 vid); ++ struct net_device *dev, const unsigned char *addr, u16 vid, ++ struct netlink_ext_ack *extack); + int br_fdb_add(struct ndmsg *nlh, struct nlattr *tb[], struct net_device *dev, + const unsigned char *addr, u16 vid, u16 nlh_flags, + struct netlink_ext_ack *extack); +--- a/net/core/rtnetlink.c ++++ b/net/core/rtnetlink.c +@@ -4181,7 +4181,7 @@ static int rtnl_fdb_del(struct sk_buff * + const struct net_device_ops *ops = br_dev->netdev_ops; + + if (ops->ndo_fdb_del) +- err = ops->ndo_fdb_del(ndm, tb, dev, addr, vid); ++ err = ops->ndo_fdb_del(ndm, tb, dev, addr, vid, extack); + + if (err) + goto out; +@@ -4192,8 +4192,7 @@ static int rtnl_fdb_del(struct sk_buff * + /* Embedded bridge, macvlan, and any other device support */ + if (ndm->ndm_flags & NTF_SELF) { + if (dev->netdev_ops->ndo_fdb_del) +- err = dev->netdev_ops->ndo_fdb_del(ndm, tb, dev, addr, +- vid); ++ err = dev->netdev_ops->ndo_fdb_del(ndm, tb, dev, addr, vid, extack); + else + err = ndo_dflt_fdb_del(ndm, tb, dev, addr, vid); + diff --git a/patches.suse/s390-ctcm-add-__printf-format-attribute-to-ctcm_dbf_longtext b/patches.suse/s390-ctcm-add-__printf-format-attribute-to-ctcm_dbf_longtext new file mode 100644 index 0000000..c1cd415 --- /dev/null +++ b/patches.suse/s390-ctcm-add-__printf-format-attribute-to-ctcm_dbf_longtext @@ -0,0 +1,38 @@ +From: Heiko Carstens +Date: Thu, 18 Nov 2021 17:06:06 +0100 +Subject: s390/ctcm: add __printf format attribute to ctcm_dbf_longtext +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Git-commit: dddbf91387a04a03a8e071cb4857403df219382e +Patch-mainline: v5.17-rc1 +References: jsc#PED-448 LTC#198619 + +Allow the compiler to recognize and check format strings and parameters. + +As reported with allmodconfig and W=1: + +drivers/s390/net/ctcm_dbug.c: In function ‘ctcm_dbf_longtext’: +drivers/s390/net/ctcm_dbug.c:73:9: error: function ‘ctcm_dbf_longtext’ might be a candidate for ‘gnu_printf’ format attribute [-Werror=suggest-attribute=format] + 73 | vsnprintf(dbf_txt_buf, sizeof(dbf_txt_buf), fmt, args); + | ^~~~~~~~~ + +Acked-by: Julian Wiedmann +Signed-off-by: Heiko Carstens +Signed-off-by: Karsten Graul +Signed-off-by: David S. Miller +Acked-by: Petr Tesarik +--- + drivers/s390/net/ctcm_dbug.h | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/s390/net/ctcm_dbug.h ++++ b/drivers/s390/net/ctcm_dbug.h +@@ -65,6 +65,7 @@ extern struct ctcm_dbf_info ctcm_dbf[CTC + + int ctcm_register_dbf_views(void); + void ctcm_unregister_dbf_views(void); ++__printf(3, 4) + void ctcm_dbf_longtext(enum ctcm_dbf_names dbf_nix, int level, char *text, ...); + + static inline const char *strtail(const char *s, int n) diff --git a/patches.suse/s390-ctcm-fix-format-string b/patches.suse/s390-ctcm-fix-format-string new file mode 100644 index 0000000..f3f087b --- /dev/null +++ b/patches.suse/s390-ctcm-fix-format-string @@ -0,0 +1,30 @@ +From: Heiko Carstens +Date: Thu, 18 Nov 2021 17:06:05 +0100 +Subject: s390/ctcm: fix format string +Git-commit: 9961d6d50b7f53ab75049ebf3bea1ff560014bed +Patch-mainline: v5.17-rc1 +References: jsc#PED-448 LTC#198619 + +The second parameter as specified by the format string is actually a +string not an integer. + +Acked-by: Julian Wiedmann +Signed-off-by: Heiko Carstens +Signed-off-by: Karsten Graul +Signed-off-by: David S. Miller +Acked-by: Petr Tesarik +--- + drivers/s390/net/ctcm_fsms.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/s390/net/ctcm_fsms.c ++++ b/drivers/s390/net/ctcm_fsms.c +@@ -1406,7 +1406,7 @@ static void ctcmpc_chx_rx(fsm_instance * + + if (new_skb == NULL) { + CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR, +- "%s(%d): skb allocation failed", ++ "%s(%s): skb allocation failed", + CTCM_FUNTAIL, dev->name); + fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev); + goto again; diff --git a/patches.suse/s390-ctcm-fix-typo-length-to-short-length-too-short b/patches.suse/s390-ctcm-fix-typo-length-to-short-length-too-short new file mode 100644 index 0000000..971fbc6 --- /dev/null +++ b/patches.suse/s390-ctcm-fix-typo-length-to-short-length-too-short @@ -0,0 +1,27 @@ +From: Tong Zhang +Date: Mon, 21 Mar 2022 00:17:57 -0700 +Subject: s390/ctcm: fix typo "length to short" -> "length too short" +Git-commit: 4f3dda8b4c4be154a0dacf063156c362268f5288 +Patch-mainline: v5.18-rc1 +References: jsc#PED-448 LTC#198619 + +"packet length to short" -> "packet length too short" + +Signed-off-by: Tong Zhang +Signed-off-by: David S. Miller +Acked-by: Petr Tesarik +--- + drivers/s390/net/ctcm_fsms.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/s390/net/ctcm_fsms.c ++++ b/drivers/s390/net/ctcm_fsms.c +@@ -1394,7 +1394,7 @@ static void ctcmpc_chx_rx(fsm_instance * + + if (len < TH_HEADER_LENGTH) { + CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR, +- "%s(%s): packet length %d to short", ++ "%s(%s): packet length %d too short", + CTCM_FUNTAIL, dev->name, len); + priv->stats.rx_dropped++; + priv->stats.rx_length_errors++; diff --git a/patches.suse/s390-ctcm-remove-incorrect-kernel-doc-indicators b/patches.suse/s390-ctcm-remove-incorrect-kernel-doc-indicators new file mode 100644 index 0000000..e7a573d --- /dev/null +++ b/patches.suse/s390-ctcm-remove-incorrect-kernel-doc-indicators @@ -0,0 +1,510 @@ +From: Heiko Carstens +Date: Tue, 14 Sep 2021 10:33:17 +0200 +Subject: s390/ctcm: remove incorrect kernel doc indicators +Git-commit: a962cc4ba1a10fa7285137d63f551a634a6d83bc +Patch-mainline: v5.16-rc1 +References: jsc#PED-448 LTC#198619 + +Many comments above functions start with a kernel doc indicator, but +the comments are not using kernel doc style. Get rid of the warnings +by simply removing the indicator. + +E.g.: + +drivers/s390/net/ctcm_main.c:979: warning: + This comment starts with '/**', but isn't a kernel-doc comment. + +Acked-by: Alexandra Winter +Signed-off-by: Heiko Carstens +Signed-off-by: Karsten Graul +Signed-off-by: David S. Miller +Acked-by: Petr Tesarik +--- + drivers/s390/net/ctcm_fsms.c | 60 +++++++++++++++++++++---------------------- + drivers/s390/net/ctcm_main.c | 38 +++++++++++++-------------- + drivers/s390/net/ctcm_mpc.c | 8 ++--- + 3 files changed, 53 insertions(+), 53 deletions(-) + +--- a/drivers/s390/net/ctcm_fsms.c ++++ b/drivers/s390/net/ctcm_fsms.c +@@ -182,7 +182,7 @@ static void ctcmpc_chx_attnbusy(fsm_inst + static void ctcmpc_chx_resend(fsm_instance *, int, void *); + static void ctcmpc_chx_send_sweep(fsm_instance *fsm, int event, void *arg); + +-/** ++/* + * Check return code of a preceding ccw_device call, halt_IO etc... + * + * ch : The channel, the error belongs to. +@@ -223,7 +223,7 @@ void ctcm_purge_skb_queue(struct sk_buff + } + } + +-/** ++/* + * NOP action for statemachines + */ + static void ctcm_action_nop(fsm_instance *fi, int event, void *arg) +@@ -234,7 +234,7 @@ static void ctcm_action_nop(fsm_instance + * Actions for channel - statemachines. + */ + +-/** ++/* + * Normal data has been send. Free the corresponding + * skb (it's in io_queue), reset dev->tbusy and + * revert to idle state. +@@ -322,7 +322,7 @@ static void chx_txdone(fsm_instance *fi, + ctcm_clear_busy_do(dev); + } + +-/** ++/* + * Initial data is sent. + * Notify device statemachine that we are up and + * running. +@@ -344,7 +344,7 @@ void ctcm_chx_txidle(fsm_instance *fi, i + fsm_event(priv->fsm, DEV_EVENT_TXUP, ch->netdev); + } + +-/** ++/* + * Got normal data, check for sanity, queue it up, allocate new buffer + * trigger bottom half, and initiate next read. + * +@@ -421,7 +421,7 @@ static void chx_rx(fsm_instance *fi, int + ctcm_ccw_check_rc(ch, rc, "normal RX"); + } + +-/** ++/* + * Initialize connection by sending a __u16 of value 0. + * + * fi An instance of a channel statemachine. +@@ -497,7 +497,7 @@ static void chx_firstio(fsm_instance *fi + } + } + +-/** ++/* + * Got initial data, check it. If OK, + * notify device statemachine that we are up and + * running. +@@ -538,7 +538,7 @@ static void chx_rxidle(fsm_instance *fi, + } + } + +-/** ++/* + * Set channel into extended mode. + * + * fi An instance of a channel statemachine. +@@ -578,7 +578,7 @@ static void ctcm_chx_setmode(fsm_instanc + ch->retry = 0; + } + +-/** ++/* + * Setup channel. + * + * fi An instance of a channel statemachine. +@@ -641,7 +641,7 @@ static void ctcm_chx_start(fsm_instance + } + } + +-/** ++/* + * Shutdown a channel. + * + * fi An instance of a channel statemachine. +@@ -682,7 +682,7 @@ static void ctcm_chx_haltio(fsm_instance + } + } + +-/** ++/* + * Cleanup helper for chx_fail and chx_stopped + * cleanup channels queue and notify interface statemachine. + * +@@ -728,7 +728,7 @@ static void ctcm_chx_cleanup(fsm_instanc + } + } + +-/** ++/* + * A channel has successfully been halted. + * Cleanup it's queue and notify interface statemachine. + * +@@ -741,7 +741,7 @@ static void ctcm_chx_stopped(fsm_instanc + ctcm_chx_cleanup(fi, CTC_STATE_STOPPED, arg); + } + +-/** ++/* + * A stop command from device statemachine arrived and we are in + * not operational mode. Set state to stopped. + * +@@ -754,7 +754,7 @@ static void ctcm_chx_stop(fsm_instance * + fsm_newstate(fi, CTC_STATE_STOPPED); + } + +-/** ++/* + * A machine check for no path, not operational status or gone device has + * happened. + * Cleanup queue and notify interface statemachine. +@@ -768,7 +768,7 @@ static void ctcm_chx_fail(fsm_instance * + ctcm_chx_cleanup(fi, CTC_STATE_NOTOP, arg); + } + +-/** ++/* + * Handle error during setup of channel. + * + * fi An instance of a channel statemachine. +@@ -817,7 +817,7 @@ static void ctcm_chx_setuperr(fsm_instan + } + } + +-/** ++/* + * Restart a channel after an error. + * + * fi An instance of a channel statemachine. +@@ -858,7 +858,7 @@ static void ctcm_chx_restart(fsm_instanc + } + } + +-/** ++/* + * Handle error during RX initial handshake (exchange of + * 0-length block header) + * +@@ -893,7 +893,7 @@ static void ctcm_chx_rxiniterr(fsm_insta + } + } + +-/** ++/* + * Notify device statemachine if we gave up initialization + * of RX channel. + * +@@ -914,7 +914,7 @@ static void ctcm_chx_rxinitfail(fsm_inst + fsm_event(priv->fsm, DEV_EVENT_RXDOWN, dev); + } + +-/** ++/* + * Handle RX Unit check remote reset (remote disconnected) + * + * fi An instance of a channel statemachine. +@@ -946,7 +946,7 @@ static void ctcm_chx_rxdisc(fsm_instance + ccw_device_halt(ch2->cdev, 0); + } + +-/** ++/* + * Handle error during TX channel initialization. + * + * fi An instance of a channel statemachine. +@@ -978,7 +978,7 @@ static void ctcm_chx_txiniterr(fsm_insta + } + } + +-/** ++/* + * Handle TX timeout by retrying operation. + * + * fi An instance of a channel statemachine. +@@ -1050,7 +1050,7 @@ done: + return; + } + +-/** ++/* + * Handle fatal errors during an I/O command. + * + * fi An instance of a channel statemachine. +@@ -1198,7 +1198,7 @@ int ch_fsm_len = ARRAY_SIZE(ch_fsm); + * Actions for mpc channel statemachine. + */ + +-/** ++/* + * Normal data has been send. Free the corresponding + * skb (it's in io_queue), reset dev->tbusy and + * revert to idle state. +@@ -1361,7 +1361,7 @@ done: + return; + } + +-/** ++/* + * Got normal data, check for sanity, queue it up, allocate new buffer + * trigger bottom half, and initiate next read. + * +@@ -1464,7 +1464,7 @@ again: + + } + +-/** ++/* + * Initialize connection by sending a __u16 of value 0. + * + * fi An instance of a channel statemachine. +@@ -1516,7 +1516,7 @@ done: + return; + } + +-/** ++/* + * Got initial data, check it. If OK, + * notify device statemachine that we are up and + * running. +@@ -2043,7 +2043,7 @@ int mpc_ch_fsm_len = ARRAY_SIZE(ctcmpc_c + * Actions for interface - statemachine. + */ + +-/** ++/* + * Startup channels by sending CTC_EVENT_START to each channel. + * + * fi An instance of an interface statemachine. +@@ -2068,7 +2068,7 @@ static void dev_action_start(fsm_instanc + } + } + +-/** ++/* + * Shutdown channels by sending CTC_EVENT_STOP to each channel. + * + * fi An instance of an interface statemachine. +@@ -2122,7 +2122,7 @@ static void dev_action_restart(fsm_insta + DEV_EVENT_START, dev); + } + +-/** ++/* + * Called from channel statemachine + * when a channel is up and running. + * +@@ -2183,7 +2183,7 @@ static void dev_action_chup(fsm_instance + } + } + +-/** ++/* + * Called from device statemachine + * when a channel has been shutdown. + * +--- a/drivers/s390/net/ctcm_main.c ++++ b/drivers/s390/net/ctcm_main.c +@@ -55,7 +55,7 @@ + + /* Some common global variables */ + +-/** ++/* + * The root device for ctcm group devices + */ + static struct device *ctcm_root_dev; +@@ -65,7 +65,7 @@ static struct device *ctcm_root_dev; + */ + struct channel *channels; + +-/** ++/* + * Unpack a just received skb and hand it over to + * upper layers. + * +@@ -180,7 +180,7 @@ void ctcm_unpack_skb(struct channel *ch, + } + } + +-/** ++/* + * Release a specific channel in the channel list. + * + * ch Pointer to channel struct to be released. +@@ -192,7 +192,7 @@ static void channel_free(struct channel + fsm_newstate(ch->fsm, CTC_STATE_IDLE); + } + +-/** ++/* + * Remove a specific channel in the channel list. + * + * ch Pointer to channel struct to be released. +@@ -240,7 +240,7 @@ static void channel_remove(struct channe + chid, ok ? "OK" : "failed"); + } + +-/** ++/* + * Get a specific channel from the channel list. + * + * type Type of channel we are interested in. +@@ -300,7 +300,7 @@ static long ctcm_check_irb_error(struct + } + + +-/** ++/* + * Check sense of a unit check. + * + * ch The channel, the sense code belongs to. +@@ -414,7 +414,7 @@ int ctcm_ch_alloc_buffer(struct channel + * Interface API for upper network layers + */ + +-/** ++/* + * Open an interface. + * Called from generic network layer when ifconfig up is run. + * +@@ -432,7 +432,7 @@ int ctcm_open(struct net_device *dev) + return 0; + } + +-/** ++/* + * Close an interface. + * Called from generic network layer when ifconfig down is run. + * +@@ -451,7 +451,7 @@ int ctcm_close(struct net_device *dev) + } + + +-/** ++/* + * Transmit a packet. + * This is a helper function for ctcm_tx(). + * +@@ -822,7 +822,7 @@ done: + return rc; + } + +-/** ++/* + * Start transmission of a packet. + * Called from generic network device layer. + * +@@ -975,7 +975,7 @@ done: + } + + +-/** ++/* + * Sets MTU of an interface. + * + * dev Pointer to interface struct. +@@ -1007,7 +1007,7 @@ static int ctcm_change_mtu(struct net_de + return 0; + } + +-/** ++/* + * Returns interface statistics of a device. + * + * dev Pointer to interface struct. +@@ -1144,7 +1144,7 @@ static struct net_device *ctcm_init_netd + return dev; + } + +-/** ++/* + * Main IRQ handler. + * + * cdev The ccw_device the interrupt is for. +@@ -1257,7 +1257,7 @@ static const struct device_type ctcm_dev + .groups = ctcm_attr_groups, + }; + +-/** ++/* + * Add ctcm specific attributes. + * Add ctcm private data. + * +@@ -1293,7 +1293,7 @@ static int ctcm_probe_device(struct ccwg + return 0; + } + +-/** ++/* + * Add a new channel to the list of channels. + * Keeps the channel list sorted. + * +@@ -1343,7 +1343,7 @@ static int add_channel(struct ccw_device + snprintf(ch->id, CTCM_ID_SIZE, "ch-%s", dev_name(&cdev->dev)); + ch->type = type; + +- /** ++ /* + * "static" ccws are used in the following way: + * + * ccw[0..2] (Channel program for generic I/O): +@@ -1471,7 +1471,7 @@ static enum ctcm_channel_types get_chann + return type; + } + +-/** ++/* + * + * Setup an interface. + * +@@ -1595,7 +1595,7 @@ out_err_result: + return result; + } + +-/** ++/* + * Shutdown an interface. + * + * cgdev Device to be shut down. +@@ -1738,7 +1738,7 @@ static void print_banner(void) + pr_info("CTCM driver initialized\n"); + } + +-/** ++/* + * Initialize module. + * This is called just after the module is loaded. + * +--- a/drivers/s390/net/ctcm_mpc.c ++++ b/drivers/s390/net/ctcm_mpc.c +@@ -1016,7 +1016,7 @@ done: + CTCM_PR_DEBUG("exit %s: ch=0x%p id=%s\n", __func__, ch, ch->id); + } + +-/** ++/* + * Unpack a just received skb and hand it over to + * upper layers. + * special MPC version of unpack_skb. +@@ -1211,7 +1211,7 @@ done: + __func__, dev->name, ch, ch->id); + } + +-/** ++/* + * tasklet helper for mpc's skb unpacking. + * + * ch The channel to work on. +@@ -1320,7 +1320,7 @@ struct mpc_group *ctcmpc_init_mpc_group( + * CTCM_PROTO_MPC only + */ + +-/** ++/* + * NOP action for statemachines + */ + static void mpc_action_nop(fsm_instance *fi, int event, void *arg) +@@ -1426,7 +1426,7 @@ static void mpc_action_go_inop(fsm_insta + } + } + +-/** ++/* + * Handle mpc group action timeout. + * MPC Group Station FSM action + * CTCM_PROTO_MPC only diff --git a/patches.suse/s390-lcs-add-braces-around-empty-function-body b/patches.suse/s390-lcs-add-braces-around-empty-function-body new file mode 100644 index 0000000..fba1fbb --- /dev/null +++ b/patches.suse/s390-lcs-add-braces-around-empty-function-body @@ -0,0 +1,54 @@ +From: Heiko Carstens +Date: Thu, 18 Nov 2021 17:06:07 +0100 +Subject: s390/lcs: add braces around empty function body +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Git-commit: 09ae598271f8cfe46148cece8e03509b9da16334 +Patch-mainline: v5.17-rc1 +References: jsc#PED-448 LTC#198619 + +Fix allmodconfig + W=1 compile breakage: + +drivers/s390/net/lcs.c: In function ‘lcs_get_frames_cb’: +drivers/s390/net/lcs.c:1823:25: error: suggest braces around empty body in an ‘else’ statement [-Werror=empty-body] + 1823 | ; // FIXME: error message ? + | ^ + +Acked-by: Julian Wiedmann +Signed-off-by: Heiko Carstens +Signed-off-by: Karsten Graul +Signed-off-by: David S. Miller +Acked-by: Petr Tesarik +--- + drivers/s390/net/lcs.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +--- a/drivers/s390/net/lcs.c ++++ b/drivers/s390/net/lcs.c +@@ -1808,19 +1808,20 @@ lcs_get_frames_cb(struct lcs_channel *ch + return; + } + /* What kind of frame is it? */ +- if (lcs_hdr->type == LCS_FRAME_TYPE_CONTROL) ++ if (lcs_hdr->type == LCS_FRAME_TYPE_CONTROL) { + /* Control frame. */ + lcs_get_control(card, (struct lcs_cmd *) lcs_hdr); +- else if (lcs_hdr->type == LCS_FRAME_TYPE_ENET || +- lcs_hdr->type == LCS_FRAME_TYPE_TR || +- lcs_hdr->type == LCS_FRAME_TYPE_FDDI) ++ } else if (lcs_hdr->type == LCS_FRAME_TYPE_ENET || ++ lcs_hdr->type == LCS_FRAME_TYPE_TR || ++ lcs_hdr->type == LCS_FRAME_TYPE_FDDI) { + /* Normal network packet. */ + lcs_get_skb(card, (char *)(lcs_hdr + 1), + lcs_hdr->offset - offset - + sizeof(struct lcs_header)); +- else ++ } else { + /* Unknown frame type. */ + ; // FIXME: error message ? ++ } + /* Proceed to next frame. */ + offset = lcs_hdr->offset; + lcs_hdr->offset = LCS_ILLEGAL_OFFSET; diff --git a/patches.suse/s390-lcs-remove-incorrect-kernel-doc-indicators b/patches.suse/s390-lcs-remove-incorrect-kernel-doc-indicators new file mode 100644 index 0000000..1dff46c --- /dev/null +++ b/patches.suse/s390-lcs-remove-incorrect-kernel-doc-indicators @@ -0,0 +1,562 @@ +From: Heiko Carstens +Date: Tue, 14 Sep 2021 10:33:18 +0200 +Subject: s390/lcs: remove incorrect kernel doc indicators +Git-commit: 239686c11f6acbb35c5c74fe2a3d172f22fcac70 +Patch-mainline: v5.16-rc1 +References: jsc#PED-448 LTC#198619 + +Many comments above functions start with a kernel doc indicator, but +the comments are not using kernel doc style. Get rid of the warnings +by simply removing the indicator. + +E.g.: + +drivers/s390/net/lcs.c:2355: warning: + This comment starts with '/**', but isn't a kernel-doc comment. + +Acked-by: Alexandra Winter +Signed-off-by: Heiko Carstens +Signed-off-by: Karsten Graul +Signed-off-by: David S. Miller +Acked-by: Petr Tesarik +--- + drivers/s390/net/lcs.c | 121 ++++++++++++++++++++++++------------------------- + 1 file changed, 61 insertions(+), 60 deletions(-) + +--- a/drivers/s390/net/lcs.c ++++ b/drivers/s390/net/lcs.c +@@ -40,18 +40,18 @@ + #error Cannot compile lcs.c without some net devices switched on. + #endif + +-/** ++/* + * initialization string for output + */ + + static char version[] __initdata = "LCS driver"; + +-/** ++/* + * the root device for lcs group devices + */ + static struct device *lcs_root_dev; + +-/** ++/* + * Some prototypes. + */ + static void lcs_tasklet(unsigned long); +@@ -62,14 +62,14 @@ static int lcs_send_delipm(struct lcs_ca + #endif /* CONFIG_IP_MULTICAST */ + static int lcs_recovery(void *ptr); + +-/** ++/* + * Debug Facility Stuff + */ + static char debug_buffer[255]; + static debug_info_t *lcs_dbf_setup; + static debug_info_t *lcs_dbf_trace; + +-/** ++/* + * LCS Debug Facility functions + */ + static void +@@ -96,7 +96,7 @@ lcs_register_debug_facility(void) + return 0; + } + +-/** ++/* + * Allocate io buffers. + */ + static int +@@ -123,7 +123,7 @@ lcs_alloc_channel(struct lcs_channel *ch + return 0; + } + +-/** ++/* + * Free io buffers. + */ + static void +@@ -151,7 +151,7 @@ lcs_cleanup_channel(struct lcs_channel * + lcs_free_channel(channel); + } + +-/** ++/* + * LCS free memory for card and channels. + */ + static void +@@ -162,7 +162,7 @@ lcs_free_card(struct lcs_card *card) + kfree(card); + } + +-/** ++/* + * LCS alloc memory for card and channels + */ + static struct lcs_card * +@@ -402,7 +402,7 @@ lcs_do_start_thread(struct lcs_card *car + return rc; + } + +-/** ++/* + * Initialize channels,card and state machines. + */ + static void +@@ -451,7 +451,8 @@ static void lcs_clear_multicast_list(str + spin_unlock_irqrestore(&card->ipm_lock, flags); + #endif + } +-/** ++ ++/* + * Cleanup channels,card and state machines. + */ + static void +@@ -468,7 +469,7 @@ lcs_cleanup_card(struct lcs_card *card) + lcs_cleanup_channel(&card->read); + } + +-/** ++/* + * Start channel. + */ + static int +@@ -517,7 +518,7 @@ lcs_clear_channel(struct lcs_channel *ch + } + + +-/** ++/* + * Stop channel. + */ + static int +@@ -545,7 +546,7 @@ lcs_stop_channel(struct lcs_channel *cha + return 0; + } + +-/** ++/* + * start read and write channel + */ + static int +@@ -565,7 +566,7 @@ lcs_start_channels(struct lcs_card *card + return rc; + } + +-/** ++/* + * stop read and write channel + */ + static int +@@ -577,7 +578,7 @@ lcs_stop_channels(struct lcs_card *card) + return 0; + } + +-/** ++/* + * Get empty buffer. + */ + static struct lcs_buffer * +@@ -610,7 +611,7 @@ lcs_get_buffer(struct lcs_channel *chann + return buffer; + } + +-/** ++/* + * Resume channel program if the channel is suspended. + */ + static int +@@ -636,7 +637,7 @@ __lcs_resume_channel(struct lcs_channel + + } + +-/** ++/* + * Make a buffer ready for processing. + */ + static void __lcs_ready_buffer_bits(struct lcs_channel *channel, int index) +@@ -678,7 +679,7 @@ lcs_ready_buffer(struct lcs_channel *cha + return rc; + } + +-/** ++/* + * Mark the buffer as processed. Take care of the suspend bit + * of the previous buffer. This function is called from + * interrupt context, so the lock must not be taken. +@@ -712,7 +713,7 @@ __lcs_processed_buffer(struct lcs_channe + return __lcs_resume_channel(channel); + } + +-/** ++/* + * Put a processed buffer back to state empty. + */ + static void +@@ -728,7 +729,7 @@ lcs_release_buffer(struct lcs_channel *c + spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags); + } + +-/** ++/* + * Get buffer for a lan command. + */ + static struct lcs_buffer * +@@ -785,7 +786,7 @@ lcs_alloc_reply(struct lcs_cmd *cmd) + return reply; + } + +-/** ++/* + * Notifier function for lancmd replies. Called from read irq. + */ + static void +@@ -813,7 +814,7 @@ lcs_notify_lancmd_waiters(struct lcs_car + spin_unlock(&card->lock); + } + +-/** ++/* + * Emit buffer of a lan command. + */ + static void +@@ -877,7 +878,7 @@ lcs_send_lancmd(struct lcs_card *card, s + return rc ? -EIO : 0; + } + +-/** ++/* + * LCS startup command + */ + static int +@@ -895,7 +896,7 @@ lcs_send_startup(struct lcs_card *card, + return lcs_send_lancmd(card, buffer, NULL); + } + +-/** ++/* + * LCS shutdown command + */ + static int +@@ -912,7 +913,7 @@ lcs_send_shutdown(struct lcs_card *card) + return lcs_send_lancmd(card, buffer, NULL); + } + +-/** ++/* + * LCS lanstat command + */ + static void +@@ -939,7 +940,7 @@ lcs_send_lanstat(struct lcs_card *card) + return lcs_send_lancmd(card, buffer, __lcs_lanstat_cb); + } + +-/** ++/* + * send stoplan command + */ + static int +@@ -958,7 +959,7 @@ lcs_send_stoplan(struct lcs_card *card, + return lcs_send_lancmd(card, buffer, NULL); + } + +-/** ++/* + * send startlan command + */ + static void +@@ -986,7 +987,7 @@ lcs_send_startlan(struct lcs_card *card, + } + + #ifdef CONFIG_IP_MULTICAST +-/** ++/* + * send setipm command (Multicast) + */ + static int +@@ -1010,7 +1011,7 @@ lcs_send_setipm(struct lcs_card *card,st + return lcs_send_lancmd(card, buffer, NULL); + } + +-/** ++/* + * send delipm command (Multicast) + */ + static int +@@ -1034,7 +1035,7 @@ lcs_send_delipm(struct lcs_card *card,st + return lcs_send_lancmd(card, buffer, NULL); + } + +-/** ++/* + * check if multicast is supported by LCS + */ + static void +@@ -1074,7 +1075,7 @@ lcs_check_multicast_support(struct lcs_c + return -EOPNOTSUPP; + } + +-/** ++/* + * set or del multicast address on LCS card + */ + static void +@@ -1129,7 +1130,7 @@ list_modified: + spin_unlock_irqrestore(&card->ipm_lock, flags); + } + +-/** ++/* + * get mac address for the relevant Multicast address + */ + static void +@@ -1139,7 +1140,7 @@ lcs_get_mac_for_ipm(__be32 ipm, char *ma + ip_eth_mc_map(ipm, mac); + } + +-/** ++/* + * function called by net device to handle multicast address relevant things + */ + static void lcs_remove_mc_addresses(struct lcs_card *card, +@@ -1260,7 +1261,7 @@ out: + } + #endif /* CONFIG_IP_MULTICAST */ + +-/** ++/* + * function called by net device to + * handle multicast address relevant things + */ +@@ -1355,7 +1356,7 @@ lcs_schedule_recovery(struct lcs_card *c + schedule_work(&card->kernel_thread_starter); + } + +-/** ++/* + * IRQ Handler for LCS channels + */ + static void +@@ -1439,7 +1440,7 @@ lcs_irq(struct ccw_device *cdev, unsigne + tasklet_schedule(&channel->irq_tasklet); + } + +-/** ++/* + * Tasklet for IRQ handler + */ + static void +@@ -1476,7 +1477,7 @@ lcs_tasklet(unsigned long data) + wake_up(&channel->wait_q); + } + +-/** ++/* + * Finish current tx buffer and make it ready for transmit. + */ + static void +@@ -1490,7 +1491,7 @@ __lcs_emit_txbuffer(struct lcs_card *car + card->tx_emitted++; + } + +-/** ++/* + * Callback for finished tx buffers. + */ + static void +@@ -1515,7 +1516,7 @@ lcs_txbuffer_cb(struct lcs_channel *chan + spin_unlock(&card->lock); + } + +-/** ++/* + * Packet transmit function called by network stack + */ + static int +@@ -1593,7 +1594,7 @@ lcs_start_xmit(struct sk_buff *skb, stru + return rc; + } + +-/** ++/* + * send startlan and lanstat command to make LCS device ready + */ + static int +@@ -1648,7 +1649,7 @@ lcs_startlan(struct lcs_card *card) + return rc; + } + +-/** ++/* + * LCS detect function + * setup channels and make them I/O ready + */ +@@ -1680,7 +1681,7 @@ lcs_detect(struct lcs_card *card) + return rc; + } + +-/** ++/* + * LCS Stop card + */ + static int +@@ -1705,7 +1706,7 @@ lcs_stopcard(struct lcs_card *card) + return rc; + } + +-/** ++/* + * Kernel Thread helper functions for LGW initiated commands + */ + static void +@@ -1721,7 +1722,7 @@ lcs_start_kernel_thread(struct work_stru + #endif + } + +-/** ++/* + * Process control frames. + */ + static void +@@ -1748,7 +1749,7 @@ lcs_get_control(struct lcs_card *card, s + lcs_notify_lancmd_waiters(card, cmd); + } + +-/** ++/* + * Unpack network packet. + */ + static void +@@ -1779,7 +1780,7 @@ lcs_get_skb(struct lcs_card *card, char + netif_rx(skb); + } + +-/** ++/* + * LCS main routine to get packets and lancmd replies from the buffers + */ + static void +@@ -1829,7 +1830,7 @@ lcs_get_frames_cb(struct lcs_channel *ch + lcs_ready_buffer(&card->read, buffer); + } + +-/** ++/* + * get network statistics for ifconfig and other user programs + */ + static struct net_device_stats * +@@ -1842,7 +1843,7 @@ lcs_getstats(struct net_device *dev) + return &card->stats; + } + +-/** ++/* + * stop lcs device + * This function will be called by user doing ifconfig xxx down + */ +@@ -1866,7 +1867,7 @@ lcs_stop_device(struct net_device *dev) + return rc; + } + +-/** ++/* + * start lcs device and make it runnable + * This function will be called by user doing ifconfig xxx up + */ +@@ -1892,7 +1893,7 @@ lcs_open_device(struct net_device *dev) + return rc; + } + +-/** ++/* + * show function for portno called by cat or similar things + */ + static ssize_t +@@ -1908,7 +1909,7 @@ lcs_portno_show (struct device *dev, str + return sprintf(buf, "%d\n", card->portno); + } + +-/** ++/* + * store the value which is piped to file portno + */ + static ssize_t +@@ -2033,7 +2034,7 @@ static const struct device_type lcs_devt + .groups = lcs_attr_groups, + }; + +-/** ++/* + * lcs_probe_device is called on establishing a new ccwgroup_device. + */ + static int +@@ -2077,7 +2078,7 @@ lcs_register_netdev(struct ccwgroup_devi + return register_netdev(card->dev); + } + +-/** ++/* + * lcs_new_device will be called by setting the group device online. + */ + static const struct net_device_ops lcs_netdev_ops = { +@@ -2199,7 +2200,7 @@ out_err: + return -ENODEV; + } + +-/** ++/* + * lcs_shutdown_device, called when setting the group device offline. + */ + static int +@@ -2240,7 +2241,7 @@ lcs_shutdown_device(struct ccwgroup_devi + return __lcs_shutdown_device(ccwgdev, 0); + } + +-/** ++/* + * drive lcs recovery after startup and startlan initiated by Lan Gateway + */ + static int +@@ -2271,7 +2272,7 @@ lcs_recovery(void *ptr) + return 0; + } + +-/** ++/* + * lcs_remove_device, free buffers and card + */ + static void +@@ -2315,7 +2316,7 @@ static struct ccw_driver lcs_ccw_driver + .int_class = IRQIO_LCS, + }; + +-/** ++/* + * LCS ccwgroup driver registration + */ + static struct ccwgroup_driver lcs_group_driver = { +@@ -2351,7 +2352,7 @@ static const struct attribute_group *lcs + NULL, + }; + +-/** ++/* + * LCS Module/Kernel initialization function + */ + static int +@@ -2389,7 +2390,7 @@ out_err: + } + + +-/** ++/* + * LCS module cleanup function + */ + static void diff --git a/patches.suse/s390-net-replace-in_irq-with-in_hardirq b/patches.suse/s390-net-replace-in_irq-with-in_hardirq new file mode 100644 index 0000000..508c459 --- /dev/null +++ b/patches.suse/s390-net-replace-in_irq-with-in_hardirq @@ -0,0 +1,40 @@ +From: Changbin Du +Date: Sat, 14 Aug 2021 09:03:34 +0800 +Subject: s390/net: replace in_irq() with in_hardirq() +Git-commit: e871ee6941842d4e52a7d81a9986cb6daf441dae +Patch-mainline: v5.15-rc1 +References: jsc#PED-448 LTC#198619 + +Replace the obsolete and ambiguos macro in_irq() with new +macro in_hardirq(). + +Signed-off-by: Changbin Du +Signed-off-by: David S. Miller +Acked-by: Petr Tesarik +--- + drivers/s390/net/ctcm_fsms.c | 2 +- + drivers/s390/net/ctcm_mpc.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/s390/net/ctcm_fsms.c ++++ b/drivers/s390/net/ctcm_fsms.c +@@ -1444,7 +1444,7 @@ again: + if (do_debug_ccw) + ctcmpc_dumpit((char *)&ch->ccw[0], + sizeof(struct ccw1) * 3); +- dolock = !in_irq(); ++ dolock = !in_hardirq(); + if (dolock) + spin_lock_irqsave( + get_ccwdev_lock(ch->cdev), saveflags); +--- a/drivers/s390/net/ctcm_mpc.c ++++ b/drivers/s390/net/ctcm_mpc.c +@@ -1773,7 +1773,7 @@ static void mpc_action_side_xid(fsm_inst + CTCM_D3_DUMP((char *)ch->xid, XID2_LENGTH); + CTCM_D3_DUMP((char *)ch->xid_id, 4); + +- if (!in_irq()) { ++ if (!in_hardirq()) { + /* Such conditional locking is a known problem for + * sparse because its static undeterministic. + * Warnings should be ignored here. */ diff --git a/patches.suse/s390-net-sort-out-physical-vs-virtual-pointers-usage b/patches.suse/s390-net-sort-out-physical-vs-virtual-pointers-usage new file mode 100644 index 0000000..d36a71f --- /dev/null +++ b/patches.suse/s390-net-sort-out-physical-vs-virtual-pointers-usage @@ -0,0 +1,66 @@ +From: Alexander Gordeev +Date: Mon, 21 Feb 2022 15:56:33 +0100 +Subject: s390/net: sort out physical vs virtual pointers usage +Git-commit: 1bb7e8dff89690e2da98608da04b0c75085c2576 +Patch-mainline: v5.18-rc1 +References: jsc#PED-448 LTC#198619 + +Fix virtual vs physical address confusion (which currently are the same). + +Reviewed-by: Alexandra Winter +Reviewed-by: Wenjia Zhang +Signed-off-by: Alexander Gordeev +Signed-off-by: Alexandra Winter +Signed-off-by: Jakub Kicinski +Acked-by: Petr Tesarik +--- + drivers/s390/net/lcs.c | 8 ++++---- + drivers/s390/net/qeth_core_main.c | 2 +- + 2 files changed, 5 insertions(+), 5 deletions(-) + +--- a/drivers/s390/net/lcs.c ++++ b/drivers/s390/net/lcs.c +@@ -223,7 +223,7 @@ lcs_setup_read_ccws(struct lcs_card *car + * we do not need to do set_normalized_cda. + */ + card->read.ccws[cnt].cda = +- (__u32) __pa(card->read.iob[cnt].data); ++ (__u32)virt_to_phys(card->read.iob[cnt].data); + ((struct lcs_header *) + card->read.iob[cnt].data)->offset = LCS_ILLEGAL_OFFSET; + card->read.iob[cnt].callback = lcs_get_frames_cb; +@@ -236,7 +236,7 @@ lcs_setup_read_ccws(struct lcs_card *car + /* Last ccw is a tic (transfer in channel). */ + card->read.ccws[LCS_NUM_BUFFS].cmd_code = LCS_CCW_TRANSFER; + card->read.ccws[LCS_NUM_BUFFS].cda = +- (__u32) __pa(card->read.ccws); ++ (__u32)virt_to_phys(card->read.ccws); + /* Setg initial state of the read channel. */ + card->read.state = LCS_CH_STATE_INIT; + +@@ -278,12 +278,12 @@ lcs_setup_write_ccws(struct lcs_card *ca + * we do not need to do set_normalized_cda. + */ + card->write.ccws[cnt].cda = +- (__u32) __pa(card->write.iob[cnt].data); ++ (__u32)virt_to_phys(card->write.iob[cnt].data); + } + /* Last ccw is a tic (transfer in channel). */ + card->write.ccws[LCS_NUM_BUFFS].cmd_code = LCS_CCW_TRANSFER; + card->write.ccws[LCS_NUM_BUFFS].cda = +- (__u32) __pa(card->write.ccws); ++ (__u32)virt_to_phys(card->write.ccws); + /* Set initial state of the write channel. */ + card->read.state = LCS_CH_STATE_INIT; + +--- a/drivers/s390/net/qeth_core_main.c ++++ b/drivers/s390/net/qeth_core_main.c +@@ -424,7 +424,7 @@ static void qeth_setup_ccw(struct ccw1 * + ccw->cmd_code = cmd_code; + ccw->flags = flags | CCW_FLAG_SLI; + ccw->count = len; +- ccw->cda = (__u32) __pa(data); ++ ccw->cda = (__u32)virt_to_phys(data); + } + + static int __qeth_issue_next_read(struct qeth_card *card) diff --git a/patches.suse/s390-netiucv-remove-incorrect-kernel-doc-indicators b/patches.suse/s390-netiucv-remove-incorrect-kernel-doc-indicators new file mode 100644 index 0000000..4ee9e72 --- /dev/null +++ b/patches.suse/s390-netiucv-remove-incorrect-kernel-doc-indicators @@ -0,0 +1,467 @@ +From: Heiko Carstens +Date: Tue, 14 Sep 2021 10:33:19 +0200 +Subject: s390/netiucv: remove incorrect kernel doc indicators +Git-commit: 478a31403b365d2f7b35a0cae8ee3e0594dc5bb1 +Patch-mainline: v5.16-rc1 +References: jsc#PED-448 LTC#198619 + +Many comments above functions start with a kernel doc indicator, but +the comments are not using kernel doc style. Get rid of the warnings +by simply removing the indicator. + +E.g.: + +drivers/s390/net/netiucv.c:1852: warning: + This comment starts with '/**', but isn't a kernel-doc comment. + +Reviewed-by: Alexandra Winter +Signed-off-by: Heiko Carstens +Signed-off-by: Karsten Graul +Signed-off-by: David S. Miller +Acked-by: Petr Tesarik +--- + drivers/s390/net/fsm.c | 2 + drivers/s390/net/netiucv.c | 104 ++++++++++++++++++++++----------------------- + 2 files changed, 53 insertions(+), 53 deletions(-) + +--- a/drivers/s390/net/fsm.c ++++ b/drivers/s390/net/fsm.c +@@ -1,5 +1,5 @@ + // SPDX-License-Identifier: GPL-2.0 +-/** ++/* + * A generic FSM based on fsm used in isdn4linux + * + */ +--- a/drivers/s390/net/netiucv.c ++++ b/drivers/s390/net/netiucv.c +@@ -58,7 +58,7 @@ MODULE_AUTHOR + ("(C) 2001 IBM Corporation by Fritz Elfert (felfert@millenux.com)"); + MODULE_DESCRIPTION ("Linux for S/390 IUCV network driver"); + +-/** ++/* + * Debug Facility stuff + */ + #define IUCV_DBF_SETUP_NAME "iucv_setup" +@@ -107,7 +107,7 @@ DECLARE_PER_CPU(char[256], iucv_dbf_txt_ + debug_sprintf_event(iucv_dbf_trace, level, text ); \ + } while (0) + +-/** ++/* + * some more debug stuff + */ + #define PRINTK_HEADER " iucv: " /* for debugging */ +@@ -118,7 +118,7 @@ static struct device_driver netiucv_driv + .bus = &iucv_bus, + }; + +-/** ++/* + * Per connection profiling data + */ + struct connection_profile { +@@ -133,7 +133,7 @@ struct connection_profile { + unsigned long tx_max_pending; + }; + +-/** ++/* + * Representation of one iucv connection + */ + struct iucv_connection { +@@ -154,13 +154,13 @@ struct iucv_connection { + char userdata[17]; + }; + +-/** ++/* + * Linked list of all connection structs. + */ + static LIST_HEAD(iucv_connection_list); + static DEFINE_RWLOCK(iucv_connection_rwlock); + +-/** ++/* + * Representation of event-data for the + * connection state machine. + */ +@@ -169,7 +169,7 @@ struct iucv_event { + void *data; + }; + +-/** ++/* + * Private part of the network device structure + */ + struct netiucv_priv { +@@ -180,7 +180,7 @@ struct netiucv_priv { + struct device *dev; + }; + +-/** ++/* + * Link level header for a packet. + */ + struct ll_header { +@@ -195,7 +195,7 @@ struct ll_header { + #define NETIUCV_QUEUELEN_DEFAULT 50 + #define NETIUCV_TIMEOUT_5SEC 5000 + +-/** ++/* + * Compatibility macros for busy handling + * of network devices. + */ +@@ -223,7 +223,7 @@ static u8 iucvMagic_ebcdic[16] = { + 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 + }; + +-/** ++/* + * Convert an iucv userId to its printable + * form (strip whitespace at end). + * +@@ -262,7 +262,7 @@ static char *netiucv_printuser(struct iu + return netiucv_printname(conn->userid, 8); + } + +-/** ++/* + * States of the interface statemachine. + */ + enum dev_states { +@@ -270,7 +270,7 @@ enum dev_states { + DEV_STATE_STARTWAIT, + DEV_STATE_STOPWAIT, + DEV_STATE_RUNNING, +- /** ++ /* + * MUST be always the last element!! + */ + NR_DEV_STATES +@@ -283,7 +283,7 @@ static const char *dev_state_names[] = { + "Running", + }; + +-/** ++/* + * Events of the interface statemachine. + */ + enum dev_events { +@@ -291,7 +291,7 @@ enum dev_events { + DEV_EVENT_STOP, + DEV_EVENT_CONUP, + DEV_EVENT_CONDOWN, +- /** ++ /* + * MUST be always the last element!! + */ + NR_DEV_EVENTS +@@ -304,11 +304,11 @@ static const char *dev_event_names[] = { + "Connection down", + }; + +-/** ++/* + * Events of the connection statemachine + */ + enum conn_events { +- /** ++ /* + * Events, representing callbacks from + * lowlevel iucv layer) + */ +@@ -320,23 +320,23 @@ enum conn_events { + CONN_EVENT_RX, + CONN_EVENT_TXDONE, + +- /** ++ /* + * Events, representing errors return codes from + * calls to lowlevel iucv layer + */ + +- /** ++ /* + * Event, representing timer expiry. + */ + CONN_EVENT_TIMER, + +- /** ++ /* + * Events, representing commands from upper levels. + */ + CONN_EVENT_START, + CONN_EVENT_STOP, + +- /** ++ /* + * MUST be always the last element!! + */ + NR_CONN_EVENTS, +@@ -357,55 +357,55 @@ static const char *conn_event_names[] = + "Stop", + }; + +-/** ++/* + * States of the connection statemachine. + */ + enum conn_states { +- /** ++ /* + * Connection not assigned to any device, + * initial state, invalid + */ + CONN_STATE_INVALID, + +- /** ++ /* + * Userid assigned but not operating + */ + CONN_STATE_STOPPED, + +- /** ++ /* + * Connection registered, + * no connection request sent yet, + * no connection request received + */ + CONN_STATE_STARTWAIT, + +- /** ++ /* + * Connection registered and connection request sent, + * no acknowledge and no connection request received yet. + */ + CONN_STATE_SETUPWAIT, + +- /** ++ /* + * Connection up and running idle + */ + CONN_STATE_IDLE, + +- /** ++ /* + * Data sent, awaiting CONN_EVENT_TXDONE + */ + CONN_STATE_TX, + +- /** ++ /* + * Error during registration. + */ + CONN_STATE_REGERR, + +- /** ++ /* + * Error during registration. + */ + CONN_STATE_CONNERR, + +- /** ++ /* + * MUST be always the last element!! + */ + NR_CONN_STATES, +@@ -424,7 +424,7 @@ static const char *conn_state_names[] = + }; + + +-/** ++/* + * Debug Facility Stuff + */ + static debug_info_t *iucv_dbf_setup = NULL; +@@ -556,7 +556,7 @@ static void netiucv_callback_connres(str + fsm_event(conn->fsm, CONN_EVENT_CONN_RES, conn); + } + +-/** ++/* + * NOP action for statemachines + */ + static void netiucv_action_nop(fsm_instance *fi, int event, void *arg) +@@ -567,7 +567,7 @@ static void netiucv_action_nop(fsm_insta + * Actions of the connection statemachine + */ + +-/** ++/* + * netiucv_unpack_skb + * @conn: The connection where this skb has been received. + * @pskb: The received skb. +@@ -993,7 +993,7 @@ static const int CONN_FSM_LEN = sizeof(c + * Actions for interface - statemachine. + */ + +-/** ++/* + * dev_action_start + * @fi: An instance of an interface statemachine. + * @event: The event, just happened. +@@ -1012,7 +1012,7 @@ static void dev_action_start(fsm_instanc + fsm_event(privptr->conn->fsm, CONN_EVENT_START, privptr->conn); + } + +-/** ++/* + * Shutdown connection by sending CONN_EVENT_STOP to it. + * + * @param fi An instance of an interface statemachine. +@@ -1034,7 +1034,7 @@ dev_action_stop(fsm_instance *fi, int ev + fsm_event(privptr->conn->fsm, CONN_EVENT_STOP, &ev); + } + +-/** ++/* + * Called from connection statemachine + * when a connection is up and running. + * +@@ -1067,7 +1067,7 @@ dev_action_connup(fsm_instance *fi, int + } + } + +-/** ++/* + * Called from connection statemachine + * when a connection has been shutdown. + * +@@ -1107,7 +1107,7 @@ static const fsm_node dev_fsm[] = { + + static const int DEV_FSM_LEN = sizeof(dev_fsm) / sizeof(fsm_node); + +-/** ++/* + * Transmit a packet. + * This is a helper function for netiucv_tx(). + * +@@ -1144,7 +1144,7 @@ static int netiucv_transmit_skb(struct i + spin_unlock_irqrestore(&conn->collect_lock, saveflags); + } else { + struct sk_buff *nskb = skb; +- /** ++ /* + * Copy the skb to a new allocated skb in lowmem only if the + * data is located above 2G in memory or tailroom is < 2. + */ +@@ -1164,7 +1164,7 @@ static int netiucv_transmit_skb(struct i + } + copied = 1; + } +- /** ++ /* + * skb now is below 2G and has enough room. Add headers. + */ + header.next = nskb->len + NETIUCV_HDRLEN; +@@ -1194,7 +1194,7 @@ static int netiucv_transmit_skb(struct i + if (copied) + dev_kfree_skb(nskb); + else { +- /** ++ /* + * Remove our headers. They get added + * again on retransmit. + */ +@@ -1217,7 +1217,7 @@ static int netiucv_transmit_skb(struct i + * Interface API for upper network layers + */ + +-/** ++/* + * Open an interface. + * Called from generic network layer when ifconfig up is run. + * +@@ -1233,7 +1233,7 @@ static int netiucv_open(struct net_devic + return 0; + } + +-/** ++/* + * Close an interface. + * Called from generic network layer when ifconfig down is run. + * +@@ -1249,7 +1249,7 @@ static int netiucv_close(struct net_devi + return 0; + } + +-/** ++/* + * Start transmission of a packet. + * Called from generic network device layer. + * +@@ -1266,7 +1266,7 @@ static int netiucv_tx(struct sk_buff *sk + int rc; + + IUCV_DBF_TEXT(trace, 4, __func__); +- /** ++ /* + * Some sanity checks ... + */ + if (skb == NULL) { +@@ -1282,7 +1282,7 @@ static int netiucv_tx(struct sk_buff *sk + return NETDEV_TX_OK; + } + +- /** ++ /* + * If connection is not running, try to restart it + * and throw away packet. + */ +@@ -1304,7 +1304,7 @@ static int netiucv_tx(struct sk_buff *sk + return rc ? NETDEV_TX_BUSY : NETDEV_TX_OK; + } + +-/** ++/* + * netiucv_stats + * @dev: Pointer to interface struct. + * +@@ -1745,7 +1745,7 @@ static void netiucv_unregister_device(st + device_unregister(dev); + } + +-/** ++/* + * Allocate and initialize a new connection structure. + * Add it to the list of netiucv connections; + */ +@@ -1802,7 +1802,7 @@ out: + return NULL; + } + +-/** ++/* + * Release a connection structure and remove it from the + * list of netiucv connections. + */ +@@ -1826,7 +1826,7 @@ static void netiucv_remove_connection(st + kfree_skb(conn->tx_buff); + } + +-/** ++/* + * Release everything of a net device. + */ + static void netiucv_free_netdevice(struct net_device *dev) +@@ -1848,7 +1848,7 @@ static void netiucv_free_netdevice(struc + } + } + +-/** ++/* + * Initialize a net device. (Called from kernel in alloc_netdev()) + */ + static const struct net_device_ops netiucv_netdev_ops = { +@@ -1873,7 +1873,7 @@ static void netiucv_setup_netdevice(stru + dev->netdev_ops = &netiucv_netdev_ops; + } + +-/** ++/* + * Allocate and initialize everything of a net device. + */ + static struct net_device *netiucv_init_netdevice(char *username, char *userdata) diff --git a/patches.suse/s390-qdio-Fix-spelling-mistake b/patches.suse/s390-qdio-Fix-spelling-mistake new file mode 100644 index 0000000..fcf90b9 --- /dev/null +++ b/patches.suse/s390-qdio-Fix-spelling-mistake @@ -0,0 +1,34 @@ +From: Zhang Jiaming +Date: Thu, 23 Jun 2022 14:05:43 +0800 +Subject: s390/qdio: Fix spelling mistake +Git-commit: d7d488f41b41a1b7a1df3c74f2f65eb4585f5d55 +Patch-mainline: v5.19-rc5 +References: jsc#PED-455 bsc#1203836 LTC#198623 + +Change 'defineable' to 'definable'. +Change 'paramater' to 'parameter'. + +Signed-off-by: Zhang Jiaming +Reviewed-by: Benjamin Block +Link: https://lore.kernel.org/r/20220623060543.12870-1-jiaming@nfschina.com +Signed-off-by: Alexander Gordeev +Acked-by: Petr Tesarik +--- + arch/s390/include/asm/qdio.h | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/arch/s390/include/asm/qdio.h ++++ b/arch/s390/include/asm/qdio.h +@@ -133,9 +133,9 @@ struct slibe { + * @sb_count: number of storage blocks + * @sba: storage block element addresses + * @dcount: size of storage block elements +- * @user0: user defineable value +- * @res4: reserved paramater +- * @user1: user defineable value ++ * @user0: user definable value ++ * @res4: reserved parameter ++ * @user1: user definable value + */ + struct qaob { + u64 res0[6]; diff --git a/patches.suse/s390-qdio-avoid-allocating-the-qdio_irq-with-GFP_DMA b/patches.suse/s390-qdio-avoid-allocating-the-qdio_irq-with-GFP_DMA new file mode 100644 index 0000000..4d38acd --- /dev/null +++ b/patches.suse/s390-qdio-avoid-allocating-the-qdio_irq-with-GFP_DMA @@ -0,0 +1,132 @@ +From: Julian Wiedmann +Date: Tue, 24 Aug 2021 09:37:06 +0300 +Subject: s390/qdio: avoid allocating the qdio_irq with GFP_DMA +Git-commit: 718ce9e10171f70f2d00c3c89ceb7e406a892bb6 +Patch-mainline: v5.17-rc1 +References: jsc#PED-455 bsc#1203836 LTC#198623 + +The qdio_irq contains only two fields that are directly exposed to the +HW (ccw and qib). And only the ccw needs to reside in 31-bit memory. So +allocate it separately, and remove the GFP_DMA constraint from the +qdio_irq allocation. + +Signed-off-by: Julian Wiedmann +Reviewed-by: Benjamin Block +Signed-off-by: Heiko Carstens +Acked-by: Petr Tesarik +--- + drivers/s390/cio/qdio.h | 2 +- + drivers/s390/cio/qdio_main.c | 34 ++++++++++++++++++++++------------ + drivers/s390/cio/qdio_setup.c | 1 - + 3 files changed, 23 insertions(+), 14 deletions(-) + +--- a/drivers/s390/cio/qdio.h ++++ b/drivers/s390/cio/qdio.h +@@ -236,7 +236,7 @@ struct qdio_irq { + int nr_input_qs; + int nr_output_qs; + +- struct ccw1 ccw; ++ struct ccw1 *ccw; + + struct qdio_ssqd_desc ssqd_desc; + void (*orig_handler) (struct ccw_device *, unsigned long, struct irb *); +--- a/drivers/s390/cio/qdio_main.c ++++ b/drivers/s390/cio/qdio_main.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -874,6 +875,7 @@ int qdio_free(struct ccw_device *cdev) + qdio_free_queues(irq_ptr); + free_page((unsigned long) irq_ptr->qdr); + free_page(irq_ptr->chsc_page); ++ kfree(irq_ptr->ccw); + free_page((unsigned long) irq_ptr); + return 0; + } +@@ -899,11 +901,17 @@ int qdio_allocate(struct ccw_device *cde + no_output_qs > QDIO_MAX_QUEUES_PER_IRQ) + return -EINVAL; + +- /* irq_ptr must be in GFP_DMA since it contains ccw1.cda */ +- irq_ptr = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA); ++ irq_ptr = (void *) get_zeroed_page(GFP_KERNEL); + if (!irq_ptr) + return -ENOMEM; + ++ irq_ptr->ccw = kmalloc(sizeof(*irq_ptr->ccw), GFP_KERNEL | GFP_DMA); ++ if (!irq_ptr->ccw) ++ goto err_ccw; ++ ++ /* kmemleak doesn't scan the page-allocated irq_ptr: */ ++ kmemleak_not_leak(irq_ptr->ccw); ++ + irq_ptr->cdev = cdev; + mutex_init(&irq_ptr->setup_mutex); + if (qdio_allocate_dbf(irq_ptr)) +@@ -941,6 +949,8 @@ err_qdr: + free_page(irq_ptr->chsc_page); + err_chsc: + err_dbf: ++ kfree(irq_ptr->ccw); ++err_ccw: + free_page((unsigned long) irq_ptr); + return rc; + } +@@ -1012,15 +1022,15 @@ int qdio_establish(struct ccw_device *cd + goto err_thinint; + + /* establish q */ +- irq_ptr->ccw.cmd_code = ciw->cmd; +- irq_ptr->ccw.flags = CCW_FLAG_SLI; +- irq_ptr->ccw.count = ciw->count; +- irq_ptr->ccw.cda = (u32) virt_to_phys(irq_ptr->qdr); ++ irq_ptr->ccw->cmd_code = ciw->cmd; ++ irq_ptr->ccw->flags = CCW_FLAG_SLI; ++ irq_ptr->ccw->count = ciw->count; ++ irq_ptr->ccw->cda = (u32) virt_to_phys(irq_ptr->qdr); + + spin_lock_irq(get_ccwdev_lock(cdev)); + ccw_device_set_options_mask(cdev, 0); + +- rc = ccw_device_start(cdev, &irq_ptr->ccw, QDIO_DOING_ESTABLISH, 0, 0); ++ rc = ccw_device_start(cdev, irq_ptr->ccw, QDIO_DOING_ESTABLISH, 0, 0); + spin_unlock_irq(get_ccwdev_lock(cdev)); + if (rc) { + DBF_ERROR("%4x est IO ERR", irq_ptr->schid.sch_no); +@@ -1093,15 +1103,15 @@ int qdio_activate(struct ccw_device *cde + goto out; + } + +- irq_ptr->ccw.cmd_code = ciw->cmd; +- irq_ptr->ccw.flags = CCW_FLAG_SLI; +- irq_ptr->ccw.count = ciw->count; +- irq_ptr->ccw.cda = 0; ++ irq_ptr->ccw->cmd_code = ciw->cmd; ++ irq_ptr->ccw->flags = CCW_FLAG_SLI; ++ irq_ptr->ccw->count = ciw->count; ++ irq_ptr->ccw->cda = 0; + + spin_lock_irq(get_ccwdev_lock(cdev)); + ccw_device_set_options(cdev, CCWDEV_REPORT_ALL); + +- rc = ccw_device_start(cdev, &irq_ptr->ccw, QDIO_DOING_ACTIVATE, ++ rc = ccw_device_start(cdev, irq_ptr->ccw, QDIO_DOING_ACTIVATE, + 0, DOIO_DENY_PREFETCH); + spin_unlock_irq(get_ccwdev_lock(cdev)); + if (rc) { +--- a/drivers/s390/cio/qdio_setup.c ++++ b/drivers/s390/cio/qdio_setup.c +@@ -369,7 +369,6 @@ void qdio_setup_irq(struct qdio_irq *irq + struct ccw_device *cdev = irq_ptr->cdev; + + irq_ptr->qdioac1 = 0; +- memset(&irq_ptr->ccw, 0, sizeof(irq_ptr->ccw)); + memset(&irq_ptr->ssqd_desc, 0, sizeof(irq_ptr->ssqd_desc)); + memset(&irq_ptr->perf_stat, 0, sizeof(irq_ptr->perf_stat)); + diff --git a/patches.suse/s390-qdio-clarify-handler-logic-for-qdio_handle_activate_check b/patches.suse/s390-qdio-clarify-handler-logic-for-qdio_handle_activate_check new file mode 100644 index 0000000..feb7cdc --- /dev/null +++ b/patches.suse/s390-qdio-clarify-handler-logic-for-qdio_handle_activate_check @@ -0,0 +1,107 @@ +From: Julian Wiedmann +Date: Mon, 15 Nov 2021 08:28:08 +0100 +Subject: s390/qdio: clarify handler logic for qdio_handle_activate_check() +Git-commit: 513251fe25d304d1ca628c581bd0cc0422de150a +Patch-mainline: v5.17-rc1 +References: jsc#PED-455 bsc#1203836 LTC#198623 + +qdio_handle_activate_check() tries to re-use one of the queue-specific +handlers to report that the ACTIVATE ccw has been terminated. But the +logic to select that handler is overly complex - in practice both +qdio drivers have at least one Input Queue, so we never take the other +paths. + +Make things more obvious by removing this unused code, and clearly +spelling out that we re-use the Input Handler for generic error +reporting. This also paves the way for a world without queue-specific +error handlers. + +Signed-off-by: Julian Wiedmann +Reviewed-by: Benjamin Block +Signed-off-by: Heiko Carstens +Acked-by: Petr Tesarik +--- + arch/s390/include/asm/qdio.h | 2 +- + drivers/s390/cio/qdio.h | 1 + + drivers/s390/cio/qdio_main.c | 25 +++++++++++-------------- + drivers/s390/cio/qdio_setup.c | 1 + + 4 files changed, 14 insertions(+), 15 deletions(-) + +--- a/arch/s390/include/asm/qdio.h ++++ b/arch/s390/include/asm/qdio.h +@@ -312,7 +312,7 @@ typedef void qdio_handler_t(struct ccw_d + * @qib_rflags: rflags to set + * @no_input_qs: number of input queues + * @no_output_qs: number of output queues +- * @input_handler: handler to be called for input queues ++ * @input_handler: handler to be called for input queues, and device-wide errors + * @output_handler: handler to be called for output queues + * @irq_poll: Data IRQ polling handler + * @scan_threshold: # of in-use buffers that triggers scan on output queue +--- a/drivers/s390/cio/qdio.h ++++ b/drivers/s390/cio/qdio.h +@@ -240,6 +240,7 @@ struct qdio_irq { + + struct qdio_ssqd_desc ssqd_desc; + void (*orig_handler) (struct ccw_device *, unsigned long, struct irb *); ++ qdio_handler_t (*error_handler); + + int perf_stat_enabled; + +--- a/drivers/s390/cio/qdio_main.c ++++ b/drivers/s390/cio/qdio_main.c +@@ -654,24 +654,18 @@ static void qdio_handle_activate_check(s + unsigned long intparm, int cstat, + int dstat) + { +- struct qdio_q *q; ++ unsigned int first_to_check = 0; + + DBF_ERROR("%4x ACT CHECK", irq_ptr->schid.sch_no); + DBF_ERROR("intp :%lx", intparm); + DBF_ERROR("ds: %2x cs:%2x", dstat, cstat); + +- if (irq_ptr->nr_input_qs) { +- q = irq_ptr->input_qs[0]; +- } else if (irq_ptr->nr_output_qs) { +- q = irq_ptr->output_qs[0]; +- } else { +- dump_stack(); +- goto no_handler; +- } ++ /* zfcp wants this: */ ++ if (irq_ptr->nr_input_qs) ++ first_to_check = irq_ptr->input_qs[0]->first_to_check; + +- q->handler(irq_ptr->cdev, QDIO_ERROR_ACTIVATE, 0, q->first_to_check, +- 0, irq_ptr->int_parm); +-no_handler: ++ irq_ptr->error_handler(irq_ptr->cdev, QDIO_ERROR_ACTIVATE, 0, ++ first_to_check, 0, irq_ptr->int_parm); + qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED); + /* + * In case of z/VM LGR (Live Guest Migration) QDIO recovery will happen. +@@ -996,8 +990,11 @@ int qdio_establish(struct ccw_device *cd + init_data->no_output_qs > irq_ptr->max_output_qs) + return -EINVAL; + +- if ((init_data->no_input_qs && !init_data->input_handler) || +- (init_data->no_output_qs && !init_data->output_handler)) ++ /* Needed as error_handler: */ ++ if (!init_data->input_handler) ++ return -EINVAL; ++ ++ if (init_data->no_output_qs && !init_data->output_handler) + return -EINVAL; + + if (!init_data->input_sbal_addr_array || +--- a/drivers/s390/cio/qdio_setup.c ++++ b/drivers/s390/cio/qdio_setup.c +@@ -375,6 +375,7 @@ void qdio_setup_irq(struct qdio_irq *irq + irq_ptr->debugfs_dev = NULL; + irq_ptr->sch_token = irq_ptr->perf_stat_enabled = 0; + irq_ptr->state = QDIO_IRQ_STATE_INACTIVE; ++ irq_ptr->error_handler = init_data->input_handler; + + irq_ptr->int_parm = init_data->int_parm; + irq_ptr->nr_input_qs = init_data->no_input_qs; diff --git a/patches.suse/s390-qdio-clarify-logical-vs-absolute-in-QIB-s-kerneldoc b/patches.suse/s390-qdio-clarify-logical-vs-absolute-in-QIB-s-kerneldoc new file mode 100644 index 0000000..916844f --- /dev/null +++ b/patches.suse/s390-qdio-clarify-logical-vs-absolute-in-QIB-s-kerneldoc @@ -0,0 +1,32 @@ +From: Julian Wiedmann +Date: Thu, 20 Aug 2020 15:19:42 +0300 +Subject: s390/qdio: clarify logical vs absolute in QIB's kerneldoc +Git-commit: 32ddf3e124ee35b70c86e239b31d30827f993d3f +Patch-mainline: v5.17-rc1 +References: jsc#PED-455 bsc#1203836 LTC#198623 + +qib.isliba and qib.osliba are actually logical addresses, and this is +also how the relevant code sets up these fields. Fix up the +documentation. + +Signed-off-by: Julian Wiedmann +Reviewed-by: Alexandra Winter +Signed-off-by: Heiko Carstens +Acked-by: Petr Tesarik +--- + arch/s390/include/asm/qdio.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/s390/include/asm/qdio.h ++++ b/arch/s390/include/asm/qdio.h +@@ -91,8 +91,8 @@ struct qdr { + * @pfmt: implementation dependent parameter format + * @rflags: QEBSM + * @ac: adapter characteristics +- * @isliba: absolute address of first input SLIB +- * @osliba: absolute address of first output SLIB ++ * @isliba: logical address of first input SLIB ++ * @osliba: logical address of first output SLIB + * @ebcnam: adapter identifier in EBCDIC + * @parm: implementation dependent parameters + */ diff --git a/patches.suse/s390-qdio-clarify-reporting-of-errors-to-the-drivers b/patches.suse/s390-qdio-clarify-reporting-of-errors-to-the-drivers new file mode 100644 index 0000000..ce3da3c --- /dev/null +++ b/patches.suse/s390-qdio-clarify-reporting-of-errors-to-the-drivers @@ -0,0 +1,83 @@ +From: Julian Wiedmann +Date: Wed, 14 Jul 2021 18:03:51 +0200 +Subject: s390/qdio: clarify reporting of errors to the drivers +Git-commit: bdfd740c1ddac2ec331af9bf79da79d097082882 +Patch-mainline: v5.15-rc1 +References: jsc#PED-455 bsc#1203836 LTC#198623 + +Now that all drivers use qdio_inspect_queue() and qdio's internal +queue tasklets are gone, the driver-specified queue handlers are +only called for async error reporting (eg. for an error condition in +the QEBSM code). + +So take a moment to clean up the Output Queue handlers (they are +_always_ called with qdio_error != 0), and clarify which error types +can be reported through what interface. As Benjamin already suggested +a while ago, we should turn these into distinct enums at some point. + +Signed-off-by: Julian Wiedmann +Reviewed-by: Benjamin Block +Signed-off-by: Heiko Carstens +Acked-by: Petr Tesarik +--- + arch/s390/include/asm/qdio.h | 7 +++---- + drivers/s390/net/qeth_core_main.c | 10 +++------- + drivers/s390/scsi/zfcp_qdio.c | 5 +---- + 3 files changed, 7 insertions(+), 15 deletions(-) + +--- a/arch/s390/include/asm/qdio.h ++++ b/arch/s390/include/asm/qdio.h +@@ -291,16 +291,15 @@ struct qdio_ssqd_desc { + typedef void qdio_handler_t(struct ccw_device *, unsigned int, int, + int, int, unsigned long); + +-/* qdio errors reported to the upper-layer program */ ++/* qdio errors reported through the queue handlers: */ + #define QDIO_ERROR_ACTIVATE 0x0001 + #define QDIO_ERROR_GET_BUF_STATE 0x0002 + #define QDIO_ERROR_SET_BUF_STATE 0x0004 ++ ++/* extra info for completed SBALs: */ + #define QDIO_ERROR_SLSB_STATE 0x0100 + #define QDIO_ERROR_SLSB_PENDING 0x0200 + +-#define QDIO_ERROR_FATAL 0x00ff +-#define QDIO_ERROR_TEMPORARY 0xff00 +- + /* for qdio_cleanup */ + #define QDIO_FLAG_CLEANUP_USING_CLEAR 0x01 + #define QDIO_FLAG_CLEANUP_USING_HALT 0x02 +--- a/drivers/s390/net/qeth_core_main.c ++++ b/drivers/s390/net/qeth_core_main.c +@@ -3804,14 +3804,10 @@ static void qeth_qdio_output_handler(str + unsigned long card_ptr) + { + struct qeth_card *card = (struct qeth_card *) card_ptr; +- struct net_device *dev = card->dev; + +- QETH_CARD_TEXT(card, 6, "qdouhdl"); +- if (qdio_error & QDIO_ERROR_FATAL) { +- QETH_CARD_TEXT(card, 2, "achkcond"); +- netif_tx_stop_all_queues(dev); +- qeth_schedule_recovery(card); +- } ++ QETH_CARD_TEXT(card, 2, "achkcond"); ++ netif_tx_stop_all_queues(card->dev); ++ qeth_schedule_recovery(card); + } + + /** +--- a/drivers/s390/scsi/zfcp_qdio.c ++++ b/drivers/s390/scsi/zfcp_qdio.c +@@ -69,10 +69,7 @@ static void zfcp_qdio_int_req(struct ccw + { + struct zfcp_qdio *qdio = (struct zfcp_qdio *) parm; + +- if (unlikely(qdio_err)) { +- zfcp_qdio_handler_error(qdio, "qdireq1", qdio_err); +- return; +- } ++ zfcp_qdio_handler_error(qdio, "qdireq1", qdio_err); + } + + static void zfcp_qdio_request_tasklet(struct tasklet_struct *tasklet) diff --git a/patches.suse/s390-qdio-clean-up-SIGA-capability-tracking b/patches.suse/s390-qdio-clean-up-SIGA-capability-tracking new file mode 100644 index 0000000..dbf63a1 --- /dev/null +++ b/patches.suse/s390-qdio-clean-up-SIGA-capability-tracking @@ -0,0 +1,169 @@ +From: Julian Wiedmann +Date: Fri, 23 Jul 2021 08:06:50 +0200 +Subject: s390/qdio: clean up SIGA capability tracking +Git-commit: 10376b53502ef14661274c40a78cb860b54455fa +Patch-mainline: v5.15-rc1 +References: jsc#PED-455 bsc#1203836 LTC#198623 + +Don't bother with translating the SIGA-related capability bits into +our own internal format, just cache the full qdioac1 field instead. + +Also adjust the helper macros so that they take a qdio_irq argument +and can be used everywhere, instead of taking a qdio_q and then +internally dereferencing the parent pointer. + +Signed-off-by: Julian Wiedmann +Reviewed-by: Benjamin Block +Signed-off-by: Vasily Gorbik +Acked-by: Petr Tesarik +--- + drivers/s390/cio/qdio.h | 16 ++++------------ + drivers/s390/cio/qdio_main.c | 12 ++++++------ + drivers/s390/cio/qdio_setup.c | 20 +++++--------------- + 3 files changed, 15 insertions(+), 33 deletions(-) + +--- a/drivers/s390/cio/qdio.h ++++ b/drivers/s390/cio/qdio.h +@@ -126,13 +126,6 @@ static inline int do_eqbs(u64 token, uns + + struct qdio_irq; + +-struct siga_flag { +- u8 input:1; +- u8 output:1; +- u8 sync:1; +- u8:5; +-} __attribute__ ((packed)); +- + struct qdio_dev_perf_stat { + unsigned int adapter_int; + unsigned int qdio_int; +@@ -238,8 +231,7 @@ struct qdio_irq { + unsigned long sch_token; /* QEBSM facility */ + + enum qdio_irq_states state; +- +- struct siga_flag siga_flag; /* siga sync information from qdioac */ ++ u8 qdioac1; + + int nr_input_qs; + int nr_output_qs; +@@ -312,9 +304,9 @@ static inline void qdio_deliver_irq(stru + #define pci_out_supported(irq) ((irq)->qib.ac & QIB_AC_OUTBOUND_PCI_SUPPORTED) + #define is_qebsm(q) (q->irq_ptr->sch_token != 0) + +-#define need_siga_in(q) (q->irq_ptr->siga_flag.input) +-#define need_siga_out(q) (q->irq_ptr->siga_flag.output) +-#define need_siga_sync(q) (unlikely(q->irq_ptr->siga_flag.sync)) ++#define qdio_need_siga_in(irq) ((irq)->qdioac1 & AC1_SIGA_INPUT_NEEDED) ++#define qdio_need_siga_out(irq) ((irq)->qdioac1 & AC1_SIGA_OUTPUT_NEEDED) ++#define qdio_need_siga_sync(irq) (unlikely((irq)->qdioac1 & AC1_SIGA_SYNC_NEEDED)) + + #define for_each_input_queue(irq_ptr, q, i) \ + for (i = 0; i < irq_ptr->nr_input_qs && \ +--- a/drivers/s390/cio/qdio_main.c ++++ b/drivers/s390/cio/qdio_main.c +@@ -375,7 +375,7 @@ static inline int qdio_siga_input(struct + int debug_get_buf_state(struct qdio_q *q, unsigned int bufnr, + unsigned char *state) + { +- if (need_siga_sync(q)) ++ if (qdio_need_siga_sync(q->irq_ptr)) + qdio_siga_sync_q(q); + return get_buf_state(q, bufnr, state, 0); + } +@@ -497,7 +497,7 @@ static inline int qdio_inbound_q_done(st + if (!atomic_read(&q->nr_buf_used)) + return 1; + +- if (need_siga_sync(q)) ++ if (qdio_need_siga_sync(q->irq_ptr)) + qdio_siga_sync_q(q); + get_buf_state(q, start, &state, 0); + +@@ -572,7 +572,7 @@ static int qdio_kick_outbound_q(struct q + int retries = 0, cc; + unsigned int busy_bit; + +- if (!need_siga_out(q)) ++ if (!qdio_need_siga_out(q->irq_ptr)) + return 0; + + DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w:%1d", q->nr); +@@ -1127,7 +1127,7 @@ static int handle_inbound(struct qdio_q + count = set_buf_states(q, bufnr, SLSB_CU_INPUT_EMPTY, count); + atomic_add(count, &q->nr_buf_used); + +- if (need_siga_in(q)) ++ if (qdio_need_siga_in(q->irq_ptr)) + return qdio_siga_input(q); + + return 0; +@@ -1159,7 +1159,7 @@ static int handle_outbound(struct qdio_q + + WARN_ON_ONCE(!IS_ALIGNED(phys_aob, 256)); + rc = qdio_kick_outbound_q(q, count, phys_aob); +- } else if (need_siga_sync(q)) { ++ } else if (qdio_need_siga_sync(q->irq_ptr)) { + rc = qdio_siga_sync_q(q); + } else if (count < QDIO_MAX_BUFFERS_PER_Q && + get_buf_state(q, prev_buf(bufnr), &state, 0) > 0 && +@@ -1283,7 +1283,7 @@ int qdio_inspect_queue(struct ccw_device + return -ENODEV; + q = is_input ? irq_ptr->input_qs[nr] : irq_ptr->output_qs[nr]; + +- if (need_siga_sync(q)) ++ if (qdio_need_siga_sync(irq_ptr)) + qdio_siga_sync_q(q); + + return __qdio_inspect_queue(q, bufnr, error); +--- a/drivers/s390/cio/qdio_setup.c ++++ b/drivers/s390/cio/qdio_setup.c +@@ -270,16 +270,6 @@ static void setup_queues(struct qdio_irq + } + } + +-static void process_ac_flags(struct qdio_irq *irq_ptr, unsigned char qdioac) +-{ +- if (qdioac & AC1_SIGA_INPUT_NEEDED) +- irq_ptr->siga_flag.input = 1; +- if (qdioac & AC1_SIGA_OUTPUT_NEEDED) +- irq_ptr->siga_flag.output = 1; +- if (qdioac & AC1_SIGA_SYNC_NEEDED) +- irq_ptr->siga_flag.sync = 1; +-} +- + static void check_and_setup_qebsm(struct qdio_irq *irq_ptr, + unsigned char qdioac, unsigned long token) + { +@@ -356,7 +346,7 @@ void qdio_setup_ssqd_info(struct qdio_ir + qdioac = irq_ptr->ssqd_desc.qdioac1; + + check_and_setup_qebsm(irq_ptr, qdioac, irq_ptr->ssqd_desc.sch_token); +- process_ac_flags(irq_ptr, qdioac); ++ irq_ptr->qdioac1 = qdioac; + DBF_EVENT("ac 1:%2x 2:%4x", qdioac, irq_ptr->ssqd_desc.qdioac2); + DBF_EVENT("3:%4x qib:%4x", irq_ptr->ssqd_desc.qdioac3, irq_ptr->qib.ac); + } +@@ -420,7 +410,7 @@ int qdio_setup_irq(struct qdio_irq *irq_ + struct ciw *ciw; + + memset(&irq_ptr->qib, 0, sizeof(irq_ptr->qib)); +- memset(&irq_ptr->siga_flag, 0, sizeof(irq_ptr->siga_flag)); ++ irq_ptr->qdioac1 = 0; + memset(&irq_ptr->ccw, 0, sizeof(irq_ptr->ccw)); + memset(&irq_ptr->ssqd_desc, 0, sizeof(irq_ptr->ssqd_desc)); + memset(&irq_ptr->perf_stat, 0, sizeof(irq_ptr->perf_stat)); +@@ -500,9 +490,9 @@ void qdio_print_subchannel_info(struct q + (irq_ptr->sch_token) ? 1 : 0, + pci_out_supported(irq_ptr) ? 1 : 0, + css_general_characteristics.aif_tdd, +- (irq_ptr->siga_flag.input) ? "R" : " ", +- (irq_ptr->siga_flag.output) ? "W" : " ", +- (irq_ptr->siga_flag.sync) ? "S" : " "); ++ qdio_need_siga_in(irq_ptr) ? "R" : " ", ++ qdio_need_siga_out(irq_ptr) ? "W" : " ", ++ qdio_need_siga_sync(irq_ptr) ? "S" : " "); + printk(KERN_INFO "%s", s); + } + diff --git a/patches.suse/s390-qdio-clean-up-access-to-queue-in-qdio_handle_activate_check b/patches.suse/s390-qdio-clean-up-access-to-queue-in-qdio_handle_activate_check new file mode 100644 index 0000000..f993e2e --- /dev/null +++ b/patches.suse/s390-qdio-clean-up-access-to-queue-in-qdio_handle_activate_check @@ -0,0 +1,34 @@ +From: Julian Wiedmann +Date: Mon, 15 Nov 2021 08:21:38 +0100 +Subject: s390/qdio: clean up access to queue in qdio_handle_activate_check() +Git-commit: 0a86cdcb4ce297f543d13d0bbd4f0c86f00626e5 +Patch-mainline: v5.17-rc1 +References: jsc#PED-455 bsc#1203836 LTC#198623 + +qdio_handle_activate_check() re-uses a queue-specific handler to report +that the ACTIVATE ccw has been terminated. It uses either the first +input or output queue, so we can hard-code q->nr as 0. Also don't +access the q->irq_ptr parent pointer, we already have a pointer to +the qdio_irq. + +Signed-off-by: Julian Wiedmann +Reviewed-by: Benjamin Block +Signed-off-by: Heiko Carstens +Acked-by: Petr Tesarik +--- + drivers/s390/cio/qdio_main.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/s390/cio/qdio_main.c ++++ b/drivers/s390/cio/qdio_main.c +@@ -669,8 +669,8 @@ static void qdio_handle_activate_check(s + goto no_handler; + } + +- q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE, +- q->nr, q->first_to_check, 0, irq_ptr->int_parm); ++ q->handler(irq_ptr->cdev, QDIO_ERROR_ACTIVATE, 0, q->first_to_check, ++ 0, irq_ptr->int_parm); + no_handler: + qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED); + /* diff --git a/patches.suse/s390-qdio-consolidate-QIB-code b/patches.suse/s390-qdio-consolidate-QIB-code new file mode 100644 index 0000000..afbf393 --- /dev/null +++ b/patches.suse/s390-qdio-consolidate-QIB-code @@ -0,0 +1,137 @@ +From: Julian Wiedmann +Date: Mon, 26 Jul 2021 08:25:41 +0200 +Subject: s390/qdio: consolidate QIB code +Git-commit: 44d9a21a19bd40c063a9a7ae823ec570f9ea4850 +Patch-mainline: v5.15-rc1 +References: jsc#PED-455 bsc#1203836 LTC#198623 + +Move all QIB-related code into qdio_setup_qib(), and slightly re-order +it according to the order of the struct's fields. This makes it easier +to understand what the QIB actually looks like before we send it to HW. + +Also get rid of the qebsm_possible() helper - as 31-bit support is long +gone, the comment doesn't make any sense. And while removing some stale +QIB-related comment, also move the clearing of the QDR into its proper +place. + +Signed-off-by: Julian Wiedmann +Reviewed-by: Benjamin Block +Signed-off-by: Vasily Gorbik +Acked-by: Petr Tesarik +--- + drivers/s390/cio/qdio_setup.c | 42 +++++++++++++++--------------------------- + 1 file changed, 15 insertions(+), 27 deletions(-) + +--- a/drivers/s390/cio/qdio_setup.c ++++ b/drivers/s390/cio/qdio_setup.c +@@ -90,21 +90,10 @@ void qdio_reset_buffers(struct qdio_buff + EXPORT_SYMBOL_GPL(qdio_reset_buffers); + + /* +- * qebsm is only available under 64bit but the adapter sets the feature +- * flag anyway, so we manually override it. +- */ +-static inline int qebsm_possible(void) +-{ +- return css_general_characteristics.qebsm; +-} +- +-/* + * qib_param_field: pointer to 128 bytes or NULL, if no param field + * nr_input_qs: pointer to nr_queues*128 words of data or NULL + */ + static void set_impl_params(struct qdio_irq *irq_ptr, +- unsigned int qib_param_field_format, +- unsigned char *qib_param_field, + unsigned long *input_slib_elements, + unsigned long *output_slib_elements) + { +@@ -114,11 +103,6 @@ static void set_impl_params(struct qdio_ + if (!irq_ptr) + return; + +- irq_ptr->qib.pfmt = qib_param_field_format; +- if (qib_param_field) +- memcpy(irq_ptr->qib.parm, qib_param_field, +- sizeof(irq_ptr->qib.parm)); +- + if (!input_slib_elements) + goto output; + +@@ -369,6 +353,8 @@ static void setup_qdr(struct qdio_irq *i + struct qdesfmt0 *desc = &irq_ptr->qdr->qdf0[0]; + int i; + ++ memset(irq_ptr->qdr, 0, sizeof(struct qdr)); ++ + irq_ptr->qdr->qfmt = qdio_init->q_format; + irq_ptr->qdr->ac = qdio_init->qdr_ac; + irq_ptr->qdr->iqdcnt = qdio_init->no_input_qs; +@@ -388,12 +374,15 @@ static void setup_qdr(struct qdio_irq *i + static void setup_qib(struct qdio_irq *irq_ptr, + struct qdio_initialize *init_data) + { +- if (qebsm_possible()) +- irq_ptr->qib.rflags |= QIB_RFLAGS_ENABLE_QEBSM; +- +- irq_ptr->qib.rflags |= init_data->qib_rflags; ++ memset(&irq_ptr->qib, 0, sizeof(irq_ptr->qib)); + + irq_ptr->qib.qfmt = init_data->q_format; ++ irq_ptr->qib.pfmt = init_data->qib_param_field_format; ++ ++ irq_ptr->qib.rflags = init_data->qib_rflags; ++ if (css_general_characteristics.qebsm) ++ irq_ptr->qib.rflags |= QIB_RFLAGS_ENABLE_QEBSM; ++ + if (init_data->no_input_qs) + irq_ptr->qib.isliba = + (unsigned long)(irq_ptr->input_qs[0]->slib); +@@ -402,6 +391,10 @@ static void setup_qib(struct qdio_irq *i + (unsigned long)(irq_ptr->output_qs[0]->slib); + memcpy(irq_ptr->qib.ebcnam, dev_name(&irq_ptr->cdev->dev), 8); + ASCEBC(irq_ptr->qib.ebcnam, 8); ++ ++ if (init_data->qib_param_field) ++ memcpy(irq_ptr->qib.parm, init_data->qib_param_field, ++ sizeof(irq_ptr->qib.parm)); + } + + int qdio_setup_irq(struct qdio_irq *irq_ptr, struct qdio_initialize *init_data) +@@ -409,7 +402,6 @@ int qdio_setup_irq(struct qdio_irq *irq_ + struct ccw_device *cdev = irq_ptr->cdev; + struct ciw *ciw; + +- memset(&irq_ptr->qib, 0, sizeof(irq_ptr->qib)); + irq_ptr->qdioac1 = 0; + memset(&irq_ptr->ccw, 0, sizeof(irq_ptr->ccw)); + memset(&irq_ptr->ssqd_desc, 0, sizeof(irq_ptr->ssqd_desc)); +@@ -419,9 +411,6 @@ int qdio_setup_irq(struct qdio_irq *irq_ + irq_ptr->sch_token = irq_ptr->perf_stat_enabled = 0; + irq_ptr->state = QDIO_IRQ_STATE_INACTIVE; + +- /* wipes qib.ac, required by ar7063 */ +- memset(irq_ptr->qdr, 0, sizeof(struct qdr)); +- + irq_ptr->int_parm = init_data->int_parm; + irq_ptr->nr_input_qs = init_data->no_input_qs; + irq_ptr->nr_output_qs = init_data->no_output_qs; +@@ -432,8 +421,7 @@ int qdio_setup_irq(struct qdio_irq *irq_ + set_bit(QDIO_IRQ_DISABLED, &irq_ptr->poll_state); + + setup_qib(irq_ptr, init_data); +- set_impl_params(irq_ptr, init_data->qib_param_field_format, +- init_data->qib_param_field, ++ set_impl_params(irq_ptr, + init_data->input_slib_elements, + init_data->output_slib_elements); + +@@ -517,7 +505,7 @@ int __init qdio_setup_init(void) + (css_general_characteristics.aif_osa) ? 1 : 0); + + /* Check for QEBSM support in general (bit 58). */ +- DBF_EVENT("cssQEBSM:%1d", (qebsm_possible()) ? 1 : 0); ++ DBF_EVENT("cssQEBSM:%1d", css_general_characteristics.qebsm); + rc = 0; + out: + return rc; diff --git a/patches.suse/s390-qdio-fine-tune-the-queue-sync b/patches.suse/s390-qdio-fine-tune-the-queue-sync new file mode 100644 index 0000000..9da559d --- /dev/null +++ b/patches.suse/s390-qdio-fine-tune-the-queue-sync @@ -0,0 +1,102 @@ +From: Julian Wiedmann +Date: Fri, 23 Jul 2021 10:02:17 +0200 +Subject: s390/qdio: fine-tune the queue sync +Git-commit: 87e225bfa0015aee2812246de56a09126a743192 +Patch-mainline: v5.15-rc1 +References: jsc#PED-455 bsc#1203836 LTC#198623 + +Push the sync check from qdio_inspect_queue() down into the two +get_*_buffer_frontier() code paths, where we actually need the sync to +look at the current queue state. This lets us avoid the check when we +know that there is no work on the queue (ie. when q->nr_buf_used is 0). + +While at it introduce the qdio_sync_*_queue() helpers, so that we can +avoid the branch on q->is_input_q when we already know the queue type. + +Signed-off-by: Julian Wiedmann +Reviewed-by: Benjamin Block +Signed-off-by: Vasily Gorbik +Acked-by: Petr Tesarik +--- + drivers/s390/cio/qdio_main.c | 31 ++++++++++++++++++++----------- + 1 file changed, 20 insertions(+), 11 deletions(-) + +--- a/drivers/s390/cio/qdio_main.c ++++ b/drivers/s390/cio/qdio_main.c +@@ -303,12 +303,22 @@ static inline int qdio_siga_sync(struct + return (cc) ? -EIO : 0; + } + ++static inline int qdio_sync_input_queue(struct qdio_q *q) ++{ ++ return qdio_siga_sync(q, 0, q->mask); ++} ++ ++static inline int qdio_sync_output_queue(struct qdio_q *q) ++{ ++ return qdio_siga_sync(q, q->mask, 0); ++} ++ + static inline int qdio_siga_sync_q(struct qdio_q *q) + { + if (q->is_input_q) +- return qdio_siga_sync(q, 0, q->mask); ++ return qdio_sync_input_queue(q); + else +- return qdio_siga_sync(q, q->mask, 0); ++ return qdio_sync_output_queue(q); + } + + static int qdio_siga_output(struct qdio_q *q, unsigned int count, +@@ -442,10 +452,9 @@ static int get_inbound_buffer_frontier(s + if (!count) + return 0; + +- /* +- * No siga sync here, as a PCI or we after a thin interrupt +- * already sync'ed the queues. +- */ ++ if (qdio_need_siga_sync(q->irq_ptr)) ++ qdio_sync_input_queue(q); ++ + count = get_buf_states(q, start, &state, count, 1); + if (!count) + return 0; +@@ -498,7 +507,7 @@ static inline int qdio_inbound_q_done(st + return 1; + + if (qdio_need_siga_sync(q->irq_ptr)) +- qdio_siga_sync_q(q); ++ qdio_sync_input_queue(q); + get_buf_state(q, start, &state, 0); + + if (state == SLSB_P_INPUT_PRIMED || state == SLSB_P_INPUT_ERROR) +@@ -520,6 +529,9 @@ static int get_outbound_buffer_frontier( + if (!count) + return 0; + ++ if (qdio_need_siga_sync(q->irq_ptr)) ++ qdio_sync_output_queue(q); ++ + count = get_buf_states(q, start, &state, count, 0); + if (!count) + return 0; +@@ -1160,7 +1172,7 @@ static int handle_outbound(struct qdio_q + WARN_ON_ONCE(!IS_ALIGNED(phys_aob, 256)); + rc = qdio_kick_outbound_q(q, count, phys_aob); + } else if (qdio_need_siga_sync(q->irq_ptr)) { +- rc = qdio_siga_sync_q(q); ++ rc = qdio_sync_output_queue(q); + } else if (count < QDIO_MAX_BUFFERS_PER_Q && + get_buf_state(q, prev_buf(bufnr), &state, 0) > 0 && + state == SLSB_CU_OUTPUT_PRIMED) { +@@ -1283,9 +1295,6 @@ int qdio_inspect_queue(struct ccw_device + return -ENODEV; + q = is_input ? irq_ptr->input_qs[nr] : irq_ptr->output_qs[nr]; + +- if (qdio_need_siga_sync(irq_ptr)) +- qdio_siga_sync_q(q); +- + return __qdio_inspect_queue(q, bufnr, error); + } + EXPORT_SYMBOL_GPL(qdio_inspect_queue); diff --git a/patches.suse/s390-qdio-improve-handling-of-CIWs b/patches.suse/s390-qdio-improve-handling-of-CIWs new file mode 100644 index 0000000..51b5819 --- /dev/null +++ b/patches.suse/s390-qdio-improve-handling-of-CIWs @@ -0,0 +1,149 @@ +From: Julian Wiedmann +Date: Thu, 8 Jul 2021 08:49:28 +0200 +Subject: s390/qdio: improve handling of CIWs +Git-commit: bd3a025dd22c500d33960b0a1fcf92e27514332c +Patch-mainline: v5.17-rc1 +References: jsc#PED-455 bsc#1203836 LTC#198623 + +Fetch the individual CIWs when we actually need them, rather than +fetching both of them in qdio_setup_irq() and then needing to cache +them inside the qdio_irq. + +Also deal with the error when a CIW is not available, instead of +silently dropping this error condition in qdio_setup_irq()'s caller. + +Signed-off-by: Julian Wiedmann +Reviewed-by: Benjamin Block +Signed-off-by: Heiko Carstens +Acked-by: Petr Tesarik +--- + drivers/s390/cio/qdio.h | 4 +--- + drivers/s390/cio/qdio_main.c | 22 ++++++++++++++++++---- + drivers/s390/cio/qdio_setup.c | 20 +------------------- + 3 files changed, 20 insertions(+), 26 deletions(-) + +--- a/drivers/s390/cio/qdio.h ++++ b/drivers/s390/cio/qdio.h +@@ -237,8 +237,6 @@ struct qdio_irq { + int nr_output_qs; + + struct ccw1 ccw; +- struct ciw equeue; +- struct ciw aqueue; + + struct qdio_ssqd_desc ssqd_desc; + void (*orig_handler) (struct ccw_device *, unsigned long, struct irb *); +@@ -338,7 +336,7 @@ void qdio_setup_ssqd_info(struct qdio_ir + int qdio_setup_get_ssqd(struct qdio_irq *irq_ptr, + struct subchannel_id *schid, + struct qdio_ssqd_desc *data); +-int qdio_setup_irq(struct qdio_irq *irq_ptr, struct qdio_initialize *init_data); ++void qdio_setup_irq(struct qdio_irq *irq_ptr, struct qdio_initialize *init_data); + void qdio_shutdown_irq(struct qdio_irq *irq); + void qdio_print_subchannel_info(struct qdio_irq *irq_ptr); + void qdio_free_queues(struct qdio_irq *irq_ptr); +--- a/drivers/s390/cio/qdio_main.c ++++ b/drivers/s390/cio/qdio_main.c +@@ -972,6 +972,7 @@ int qdio_establish(struct ccw_device *cd + { + struct qdio_irq *irq_ptr = cdev->private->qdio_data; + struct subchannel_id schid; ++ struct ciw *ciw; + long timeout; + int rc; + +@@ -996,6 +997,12 @@ int qdio_establish(struct ccw_device *cd + if (!init_data->irq_poll) + return -EINVAL; + ++ ciw = ccw_device_get_ciw(cdev, CIW_TYPE_EQUEUE); ++ if (!ciw) { ++ DBF_ERROR("%4x NO EQ", schid.sch_no); ++ return -EIO; ++ } ++ + mutex_lock(&irq_ptr->setup_mutex); + qdio_trace_init_data(irq_ptr, init_data); + qdio_setup_irq(irq_ptr, init_data); +@@ -1005,9 +1012,9 @@ int qdio_establish(struct ccw_device *cd + goto err_thinint; + + /* establish q */ +- irq_ptr->ccw.cmd_code = irq_ptr->equeue.cmd; ++ irq_ptr->ccw.cmd_code = ciw->cmd; + irq_ptr->ccw.flags = CCW_FLAG_SLI; +- irq_ptr->ccw.count = irq_ptr->equeue.count; ++ irq_ptr->ccw.count = ciw->count; + irq_ptr->ccw.cda = (u32) virt_to_phys(irq_ptr->qdr); + + spin_lock_irq(get_ccwdev_lock(cdev)); +@@ -1065,6 +1072,7 @@ int qdio_activate(struct ccw_device *cde + { + struct qdio_irq *irq_ptr = cdev->private->qdio_data; + struct subchannel_id schid; ++ struct ciw *ciw; + int rc; + + ccw_device_get_schid(cdev, &schid); +@@ -1073,15 +1081,21 @@ int qdio_activate(struct ccw_device *cde + if (!irq_ptr) + return -ENODEV; + ++ ciw = ccw_device_get_ciw(cdev, CIW_TYPE_AQUEUE); ++ if (!ciw) { ++ DBF_ERROR("%4x NO AQ", schid.sch_no); ++ return -EIO; ++ } ++ + mutex_lock(&irq_ptr->setup_mutex); + if (irq_ptr->state == QDIO_IRQ_STATE_INACTIVE) { + rc = -EBUSY; + goto out; + } + +- irq_ptr->ccw.cmd_code = irq_ptr->aqueue.cmd; ++ irq_ptr->ccw.cmd_code = ciw->cmd; + irq_ptr->ccw.flags = CCW_FLAG_SLI; +- irq_ptr->ccw.count = irq_ptr->aqueue.count; ++ irq_ptr->ccw.count = ciw->count; + irq_ptr->ccw.cda = 0; + + spin_lock_irq(get_ccwdev_lock(cdev)); +--- a/drivers/s390/cio/qdio_setup.c ++++ b/drivers/s390/cio/qdio_setup.c +@@ -364,10 +364,9 @@ static void setup_qib(struct qdio_irq *i + sizeof(irq_ptr->qib.parm)); + } + +-int qdio_setup_irq(struct qdio_irq *irq_ptr, struct qdio_initialize *init_data) ++void qdio_setup_irq(struct qdio_irq *irq_ptr, struct qdio_initialize *init_data) + { + struct ccw_device *cdev = irq_ptr->cdev; +- struct ciw *ciw; + + irq_ptr->qdioac1 = 0; + memset(&irq_ptr->ccw, 0, sizeof(irq_ptr->ccw)); +@@ -399,23 +398,6 @@ int qdio_setup_irq(struct qdio_irq *irq_ + irq_ptr->orig_handler = cdev->handler; + cdev->handler = qdio_int_handler; + spin_unlock_irq(get_ccwdev_lock(cdev)); +- +- /* get qdio commands */ +- ciw = ccw_device_get_ciw(cdev, CIW_TYPE_EQUEUE); +- if (!ciw) { +- DBF_ERROR("%4x NO EQ", irq_ptr->schid.sch_no); +- return -EINVAL; +- } +- irq_ptr->equeue = *ciw; +- +- ciw = ccw_device_get_ciw(cdev, CIW_TYPE_AQUEUE); +- if (!ciw) { +- DBF_ERROR("%4x NO AQ", irq_ptr->schid.sch_no); +- return -EINVAL; +- } +- irq_ptr->aqueue = *ciw; +- +- return 0; + } + + void qdio_shutdown_irq(struct qdio_irq *irq) diff --git a/patches.suse/s390-qdio-remove-QDIO_SBAL_SIZE-macro b/patches.suse/s390-qdio-remove-QDIO_SBAL_SIZE-macro new file mode 100644 index 0000000..2db4bdb --- /dev/null +++ b/patches.suse/s390-qdio-remove-QDIO_SBAL_SIZE-macro @@ -0,0 +1,27 @@ +From: Julian Wiedmann +Date: Fri, 12 Nov 2021 09:15:15 +0100 +Subject: s390/qdio: remove QDIO_SBAL_SIZE macro +Git-commit: 764fc3187c3fae5e620a435b42c9cc0e813a903d +Patch-mainline: v5.17-rc1 +References: jsc#PED-455 bsc#1203836 LTC#198623 + +It's unused, and duplicates sizeof(struct qdio_buffer). + +Signed-off-by: Julian Wiedmann +Reviewed-by: Benjamin Block +Signed-off-by: Heiko Carstens +Acked-by: Petr Tesarik +--- + arch/s390/include/asm/qdio.h | 1 - + 1 file changed, 1 deletion(-) + +--- a/arch/s390/include/asm/qdio.h ++++ b/arch/s390/include/asm/qdio.h +@@ -18,7 +18,6 @@ + #define QDIO_MAX_BUFFERS_MASK (QDIO_MAX_BUFFERS_PER_Q - 1) + #define QDIO_BUFNR(num) ((num) & QDIO_MAX_BUFFERS_MASK) + #define QDIO_MAX_ELEMENTS_PER_BUFFER 16 +-#define QDIO_SBAL_SIZE 256 + + #define QDIO_QETH_QFMT 0 + #define QDIO_ZFCP_QFMT 1 diff --git a/patches.suse/s390-qdio-remove-remaining-tasklet-timer-code b/patches.suse/s390-qdio-remove-remaining-tasklet-timer-code new file mode 100644 index 0000000..4c427a6 --- /dev/null +++ b/patches.suse/s390-qdio-remove-remaining-tasklet-timer-code @@ -0,0 +1,453 @@ +From: Julian Wiedmann +Date: Mon, 15 Mar 2021 19:39:20 +0100 +Subject: s390/qdio: remove remaining tasklet & timer code +Git-commit: d01fad2c6a3d2b4962b9195747b07535d2eb3e41 +Patch-mainline: v5.15-rc1 +References: jsc#PED-455 bsc#1203836 LTC#198623 + +Both qdio drivers have moved away from using qdio's internal tasklet +and timer mechanisms for Output Queues. Rip out all the leftovers. + +Signed-off-by: Julian Wiedmann +Reviewed-by: Benjamin Block +Signed-off-by: Heiko Carstens +Acked-by: Petr Tesarik +--- + arch/s390/include/asm/qdio.h | 3 + drivers/s390/cio/qdio.h | 13 -- + drivers/s390/cio/qdio_debug.c | 3 + drivers/s390/cio/qdio_main.c | 198 +----------------------------------------- + drivers/s390/cio/qdio_setup.c | 4 + 5 files changed, 5 insertions(+), 216 deletions(-) + +--- a/arch/s390/include/asm/qdio.h ++++ b/arch/s390/include/asm/qdio.h +@@ -337,7 +337,6 @@ struct qdio_initialize { + qdio_handler_t *input_handler; + qdio_handler_t *output_handler; + void (*irq_poll)(struct ccw_device *cdev, unsigned long data); +- unsigned int scan_threshold; + unsigned long int_parm; + struct qdio_buffer ***input_sbal_addr_array; + struct qdio_buffer ***output_sbal_addr_array; +@@ -350,7 +349,6 @@ struct qdio_initialize { + + #define QDIO_FLAG_SYNC_INPUT 0x01 + #define QDIO_FLAG_SYNC_OUTPUT 0x02 +-#define QDIO_FLAG_PCI_OUT 0x10 + + int qdio_alloc_buffers(struct qdio_buffer **buf, unsigned int count); + void qdio_free_buffers(struct qdio_buffer **buf, unsigned int count); +@@ -367,7 +365,6 @@ extern int do_QDIO(struct ccw_device *cd + unsigned int bufnr, unsigned int count, struct qaob *aob); + extern int qdio_start_irq(struct ccw_device *cdev); + extern int qdio_stop_irq(struct ccw_device *cdev); +-extern int qdio_get_next_buffers(struct ccw_device *, int, int *, int *); + extern int qdio_inspect_queue(struct ccw_device *cdev, unsigned int nr, + bool is_input, unsigned int *bufnr, + unsigned int *error); +--- a/drivers/s390/cio/qdio.h ++++ b/drivers/s390/cio/qdio.h +@@ -138,9 +138,6 @@ struct siga_flag { + struct qdio_dev_perf_stat { + unsigned int adapter_int; + unsigned int qdio_int; +- unsigned int pci_request_int; +- +- unsigned int tasklet_outbound; + + unsigned int siga_read; + unsigned int siga_write; +@@ -150,7 +147,6 @@ struct qdio_dev_perf_stat { + unsigned int stop_polling; + unsigned int inbound_queue_full; + unsigned int outbound_call; +- unsigned int outbound_handler; + unsigned int outbound_queue_full; + unsigned int fast_requeue; + unsigned int target_full; +@@ -180,12 +176,6 @@ struct qdio_input_q { + }; + + struct qdio_output_q { +- /* PCIs are enabled for the queue */ +- int pci_out_enabled; +- /* timer to check for more outbound work */ +- struct timer_list timer; +- /* tasklet to check for completions */ +- struct tasklet_struct tasklet; + }; + + /* +@@ -263,7 +253,6 @@ struct qdio_irq { + struct qdio_ssqd_desc ssqd_desc; + void (*orig_handler) (struct ccw_device *, unsigned long, struct irb *); + +- unsigned int scan_threshold; /* used SBALs before tasklet schedule */ + int perf_stat_enabled; + + struct qdr *qdr; +@@ -360,8 +349,6 @@ void qdio_thinint_exit(void); + int test_nonshared_ind(struct qdio_irq *); + + /* prototypes for setup */ +-void qdio_outbound_tasklet(struct tasklet_struct *t); +-void qdio_outbound_timer(struct timer_list *t); + void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm, + struct irb *irb); + int qdio_allocate_qs(struct qdio_irq *irq_ptr, int nr_input_qs, +--- a/drivers/s390/cio/qdio_debug.c ++++ b/drivers/s390/cio/qdio_debug.c +@@ -197,8 +197,6 @@ DEFINE_SHOW_ATTRIBUTE(ssqd); + static char *qperf_names[] = { + "Assumed adapter interrupts", + "QDIO interrupts", +- "Requested PCIs", +- "Outbound tasklet runs", + "SIGA read", + "SIGA write", + "SIGA sync", +@@ -206,7 +204,6 @@ static char *qperf_names[] = { + "Inbound stop_polling", + "Inbound queue full", + "Outbound calls", +- "Outbound handler", + "Outbound queue full", + "Outbound fast_requeue", + "Outbound target_full", +--- a/drivers/s390/cio/qdio_main.c ++++ b/drivers/s390/cio/qdio_main.c +@@ -10,7 +10,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -373,18 +372,6 @@ static inline int qdio_siga_input(struct + return (cc) ? -EIO : 0; + } + +-#define qdio_siga_sync_out(q) qdio_siga_sync(q, ~0U, 0) +-#define qdio_siga_sync_all(q) qdio_siga_sync(q, ~0U, ~0U) +- +-static inline void qdio_sync_queues(struct qdio_q *q) +-{ +- /* PCI capable outbound queues will also be scanned so sync them too */ +- if (pci_out_supported(q->irq_ptr)) +- qdio_siga_sync_all(q); +- else +- qdio_siga_sync_q(q); +-} +- + int debug_get_buf_state(struct qdio_q *q, unsigned int bufnr, + unsigned char *state) + { +@@ -521,15 +508,6 @@ static inline int qdio_inbound_q_done(st + return 1; + } + +-static inline int qdio_tasklet_schedule(struct qdio_q *q) +-{ +- if (likely(q->irq_ptr->state == QDIO_IRQ_STATE_ACTIVE)) { +- tasklet_schedule(&q->u.out.tasklet); +- return 0; +- } +- return -EPERM; +-} +- + static int get_outbound_buffer_frontier(struct qdio_q *q, unsigned int start, + unsigned int *error) + { +@@ -595,12 +573,6 @@ static int get_outbound_buffer_frontier( + } + } + +-/* all buffers processed? */ +-static inline int qdio_outbound_q_done(struct qdio_q *q) +-{ +- return atomic_read(&q->nr_buf_used) == 0; +-} +- + static int qdio_kick_outbound_q(struct qdio_q *q, unsigned int count, + unsigned long aob) + { +@@ -644,75 +616,6 @@ retry: + return cc; + } + +-void qdio_outbound_tasklet(struct tasklet_struct *t) +-{ +- struct qdio_output_q *out_q = from_tasklet(out_q, t, tasklet); +- struct qdio_q *q = container_of(out_q, struct qdio_q, u.out); +- unsigned int start = q->first_to_check; +- unsigned int error = 0; +- int count; +- +- qperf_inc(q, tasklet_outbound); +- WARN_ON_ONCE(atomic_read(&q->nr_buf_used) < 0); +- +- count = get_outbound_buffer_frontier(q, start, &error); +- if (count) { +- q->first_to_check = add_buf(start, count); +- +- if (q->irq_ptr->state == QDIO_IRQ_STATE_ACTIVE) { +- qperf_inc(q, outbound_handler); +- DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "koh: s:%02x c:%02x", +- start, count); +- +- q->handler(q->irq_ptr->cdev, error, q->nr, start, +- count, q->irq_ptr->int_parm); +- } +- } +- +- if (queue_type(q) == QDIO_ZFCP_QFMT && !pci_out_supported(q->irq_ptr) && +- !qdio_outbound_q_done(q)) +- goto sched; +- +- if (q->u.out.pci_out_enabled) +- return; +- +- /* +- * Now we know that queue type is either qeth without pci enabled +- * or HiperSockets. Make sure buffer switch from PRIMED to EMPTY +- * is noticed and outbound_handler is called after some time. +- */ +- if (qdio_outbound_q_done(q)) +- del_timer_sync(&q->u.out.timer); +- else +- if (!timer_pending(&q->u.out.timer) && +- likely(q->irq_ptr->state == QDIO_IRQ_STATE_ACTIVE)) +- mod_timer(&q->u.out.timer, jiffies + 10 * HZ); +- return; +- +-sched: +- qdio_tasklet_schedule(q); +-} +- +-void qdio_outbound_timer(struct timer_list *t) +-{ +- struct qdio_q *q = from_timer(q, t, u.out.timer); +- +- qdio_tasklet_schedule(q); +-} +- +-static inline void qdio_check_outbound_pci_queues(struct qdio_irq *irq) +-{ +- struct qdio_q *out; +- int i; +- +- if (!pci_out_supported(irq) || !irq->scan_threshold) +- return; +- +- for_each_output_queue(irq, out, i) +- if (!qdio_outbound_q_done(out)) +- qdio_tasklet_schedule(out); +-} +- + static inline void qdio_set_state(struct qdio_irq *irq_ptr, + enum qdio_irq_states state) + { +@@ -734,25 +637,11 @@ static void qdio_irq_check_sense(struct + /* PCI interrupt handler */ + static void qdio_int_handler_pci(struct qdio_irq *irq_ptr) + { +- int i; +- struct qdio_q *q; +- + if (unlikely(irq_ptr->state != QDIO_IRQ_STATE_ACTIVE)) + return; + + qdio_deliver_irq(irq_ptr); + irq_ptr->last_data_irq_time = S390_lowcore.int_clock; +- +- if (!pci_out_supported(irq_ptr) || !irq_ptr->scan_threshold) +- return; +- +- for_each_output_queue(irq_ptr, q, i) { +- if (qdio_outbound_q_done(q)) +- continue; +- if (need_siga_sync(q) && need_siga_sync_out_after_pci(q)) +- qdio_siga_sync_q(q); +- qdio_tasklet_schedule(q); +- } + } + + static void qdio_handle_activate_check(struct qdio_irq *irq_ptr, +@@ -879,17 +768,6 @@ int qdio_get_ssqd_desc(struct ccw_device + } + EXPORT_SYMBOL_GPL(qdio_get_ssqd_desc); + +-static void qdio_shutdown_queues(struct qdio_irq *irq_ptr) +-{ +- struct qdio_q *q; +- int i; +- +- for_each_output_queue(irq_ptr, q, i) { +- del_timer_sync(&q->u.out.timer); +- tasklet_kill(&q->u.out.tasklet); +- } +-} +- + static int qdio_cancel_ccw(struct qdio_irq *irq, int how) + { + struct ccw_device *cdev = irq->cdev; +@@ -949,12 +827,10 @@ int qdio_shutdown(struct ccw_device *cde + } + + /* +- * Indicate that the device is going down. Scheduling the queue +- * tasklets is forbidden from here on. ++ * Indicate that the device is going down. + */ + qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED); + +- qdio_shutdown_queues(irq_ptr); + qdio_shutdown_debug_entries(irq_ptr); + + rc = qdio_cancel_ccw(irq_ptr, how); +@@ -1238,12 +1114,10 @@ EXPORT_SYMBOL_GPL(qdio_activate); + /** + * handle_inbound - reset processed input buffers + * @q: queue containing the buffers +- * @callflags: flags + * @bufnr: first buffer to process + * @count: how many buffers are emptied + */ +-static int handle_inbound(struct qdio_q *q, unsigned int callflags, +- int bufnr, int count) ++static int handle_inbound(struct qdio_q *q, int bufnr, int count) + { + int overlap; + +@@ -1269,16 +1143,13 @@ static int handle_inbound(struct qdio_q + /** + * handle_outbound - process filled outbound buffers + * @q: queue containing the buffers +- * @callflags: flags + * @bufnr: first buffer to process + * @count: how many buffers are filled + * @aob: asynchronous operation block + */ +-static int handle_outbound(struct qdio_q *q, unsigned int callflags, +- unsigned int bufnr, unsigned int count, ++static int handle_outbound(struct qdio_q *q, unsigned int bufnr, unsigned int count, + struct qaob *aob) + { +- const unsigned int scan_threshold = q->irq_ptr->scan_threshold; + unsigned char state = 0; + int used, rc = 0; + +@@ -1290,12 +1161,6 @@ static int handle_outbound(struct qdio_q + if (used == QDIO_MAX_BUFFERS_PER_Q) + qperf_inc(q, outbound_queue_full); + +- if (callflags & QDIO_FLAG_PCI_OUT) { +- q->u.out.pci_out_enabled = 1; +- qperf_inc(q, pci_request_int); +- } else +- q->u.out.pci_out_enabled = 0; +- + if (queue_type(q) == QDIO_IQDIO_QFMT) { + unsigned long phys_aob = aob ? virt_to_phys(aob) : 0; + +@@ -1312,18 +1177,6 @@ static int handle_outbound(struct qdio_q + rc = qdio_kick_outbound_q(q, count, 0); + } + +- /* Let drivers implement their own completion scanning: */ +- if (!scan_threshold) +- return rc; +- +- /* in case of SIGA errors we must process the error immediately */ +- if (used >= scan_threshold || rc) +- qdio_tasklet_schedule(q); +- else +- /* free the SBALs in case of no further traffic */ +- if (!timer_pending(&q->u.out.timer) && +- likely(q->irq_ptr->state == QDIO_IRQ_STATE_ACTIVE)) +- mod_timer(&q->u.out.timer, jiffies + HZ); + return rc; + } + +@@ -1355,11 +1208,9 @@ int do_QDIO(struct ccw_device *cdev, uns + if (!count) + return 0; + if (callflags & QDIO_FLAG_SYNC_INPUT) +- return handle_inbound(irq_ptr->input_qs[q_nr], +- callflags, bufnr, count); ++ return handle_inbound(irq_ptr->input_qs[q_nr], bufnr, count); + else if (callflags & QDIO_FLAG_SYNC_OUTPUT) +- return handle_outbound(irq_ptr->output_qs[q_nr], +- callflags, bufnr, count, aob); ++ return handle_outbound(irq_ptr->output_qs[q_nr], bufnr, count, aob); + return -EINVAL; + } + EXPORT_SYMBOL_GPL(do_QDIO); +@@ -1447,45 +1298,6 @@ int qdio_inspect_queue(struct ccw_device + EXPORT_SYMBOL_GPL(qdio_inspect_queue); + + /** +- * qdio_get_next_buffers - process input buffers +- * @cdev: associated ccw_device for the qdio subchannel +- * @nr: input queue number +- * @bufnr: first filled buffer number +- * @error: buffers are in error state +- * +- * Return codes +- * < 0 - error +- * = 0 - no new buffers found +- * > 0 - number of processed buffers +- */ +-int qdio_get_next_buffers(struct ccw_device *cdev, int nr, int *bufnr, +- int *error) +-{ +- struct qdio_q *q; +- struct qdio_irq *irq_ptr = cdev->private->qdio_data; +- +- if (!irq_ptr) +- return -ENODEV; +- q = irq_ptr->input_qs[nr]; +- +- /* +- * Cannot rely on automatic sync after interrupt since queues may +- * also be examined without interrupt. +- */ +- if (need_siga_sync(q)) +- qdio_sync_queues(q); +- +- qdio_check_outbound_pci_queues(irq_ptr); +- +- /* Note: upper-layer MUST stop processing immediately here ... */ +- if (unlikely(q->irq_ptr->state != QDIO_IRQ_STATE_ACTIVE)) +- return -EIO; +- +- return __qdio_inspect_queue(q, bufnr, error); +-} +-EXPORT_SYMBOL(qdio_get_next_buffers); +- +-/** + * qdio_stop_irq - disable interrupt processing for the device + * @cdev: associated ccw_device for the qdio subchannel + * +--- a/drivers/s390/cio/qdio_setup.c ++++ b/drivers/s390/cio/qdio_setup.c +@@ -267,9 +267,6 @@ static void setup_queues(struct qdio_irq + q->is_input_q = 0; + setup_storage_lists(q, irq_ptr, + qdio_init->output_sbal_addr_array[i], i); +- +- tasklet_setup(&q->u.out.tasklet, qdio_outbound_tasklet); +- timer_setup(&q->u.out.timer, qdio_outbound_timer, 0); + } + } + +@@ -442,7 +439,6 @@ int qdio_setup_irq(struct qdio_irq *irq_ + irq_ptr->int_parm = init_data->int_parm; + irq_ptr->nr_input_qs = init_data->no_input_qs; + irq_ptr->nr_output_qs = init_data->no_output_qs; +- irq_ptr->scan_threshold = init_data->scan_threshold; + ccw_device_get_schid(cdev, &irq_ptr->schid); + setup_queues(irq_ptr, init_data); + diff --git a/patches.suse/s390-qdio-remove-unneeded-sanity-check-in-qdio_do_sqbs b/patches.suse/s390-qdio-remove-unneeded-sanity-check-in-qdio_do_sqbs new file mode 100644 index 0000000..daf1754 --- /dev/null +++ b/patches.suse/s390-qdio-remove-unneeded-sanity-check-in-qdio_do_sqbs @@ -0,0 +1,33 @@ +From: Julian Wiedmann +Date: Wed, 24 Nov 2021 10:16:53 +0100 +Subject: s390/qdio: remove unneeded sanity check in qdio_do_sqbs() +Git-commit: e628f28793033ff760c82e04a73abe415b10a66c +Patch-mainline: v5.17-rc1 +References: jsc#PED-455 bsc#1203836 LTC#198623 + +All callers of set_buf_states() are already making sure that 'count' +is not 0. So don't check it an additional time. + +Note that our own code also doesn't _require_ the count to be sane +(ie. we can't overrun an array or similar). So worst case HW would +simply reject the SQBS operation and report an error. + +Signed-off-by: Julian Wiedmann +Reviewed-by: Benjamin Block +Signed-off-by: Heiko Carstens +Acked-by: Petr Tesarik +--- + drivers/s390/cio/qdio_main.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/s390/cio/qdio_main.c ++++ b/drivers/s390/cio/qdio_main.c +@@ -170,8 +170,6 @@ static int qdio_do_sqbs(struct qdio_q *q + int tmp_count = count, tmp_start = start; + int nr = q->nr; + +- if (!count) +- return 0; + qperf_inc(q, sqbs); + + if (!q->is_input_q) diff --git a/patches.suse/s390-qdio-remove-unneeded-siga-sync-for-Output-Queue b/patches.suse/s390-qdio-remove-unneeded-siga-sync-for-Output-Queue new file mode 100644 index 0000000..b440664 --- /dev/null +++ b/patches.suse/s390-qdio-remove-unneeded-siga-sync-for-Output-Queue @@ -0,0 +1,34 @@ +From: Julian Wiedmann +Date: Mon, 12 Jul 2021 08:29:32 +0200 +Subject: s390/qdio: remove unneeded siga-sync for Output Queue +Git-commit: 0ae8f2af262a371d9c49c67a0f5e48982c57cdf4 +Patch-mainline: v5.15-rc1 +References: jsc#PED-455 bsc#1203836 LTC#198623 + +get_outbound_buffer_frontier() is only reached via qdio_inspect_queue(), +and there we already call qdio_siga_sync_q() unconditionally. + +Signed-off-by: Julian Wiedmann +Reviewed-by: Benjamin Block +Signed-off-by: Heiko Carstens +Acked-by: Petr Tesarik +--- + drivers/s390/cio/qdio_main.c | 7 ------- + 1 file changed, 7 deletions(-) + +--- a/drivers/s390/cio/qdio_main.c ++++ b/drivers/s390/cio/qdio_main.c +@@ -516,13 +516,6 @@ static int get_outbound_buffer_frontier( + + q->timestamp = get_tod_clock_fast(); + +- if (need_siga_sync(q)) +- if (((queue_type(q) != QDIO_IQDIO_QFMT) && +- !pci_out_supported(q->irq_ptr)) || +- (queue_type(q) == QDIO_IQDIO_QFMT && +- multicast_outbound(q))) +- qdio_siga_sync_q(q); +- + count = atomic_read(&q->nr_buf_used); + if (!count) + return 0; diff --git a/patches.suse/s390-qdio-remove-unused-macros b/patches.suse/s390-qdio-remove-unused-macros new file mode 100644 index 0000000..cf2d97b --- /dev/null +++ b/patches.suse/s390-qdio-remove-unused-macros @@ -0,0 +1,47 @@ +From: Julian Wiedmann +Date: Mon, 22 Feb 2021 10:18:33 +0100 +Subject: s390/qdio: remove unused macros +Git-commit: 0d374381d00b92ad73771bb9b09db21e7bb64500 +Patch-mainline: v5.15-rc1 +References: jsc#PED-455 bsc#1203836 LTC#198623 + +These macros haven't seen any use in a long time. Also note that the +queue_irqs_*() ones wouldn't even compile anymore. + +Signed-off-by: Julian Wiedmann +Reviewed-by: Benjamin Block +Signed-off-by: Heiko Carstens +Acked-by: Petr Tesarik +--- + arch/s390/include/asm/qdio.h | 5 ----- + drivers/s390/cio/qdio.h | 5 ----- + 2 files changed, 10 deletions(-) + +--- a/arch/s390/include/asm/qdio.h ++++ b/arch/s390/include/asm/qdio.h +@@ -341,11 +341,6 @@ struct qdio_initialize { + struct qdio_buffer ***output_sbal_addr_array; + }; + +-#define QDIO_STATE_INACTIVE 0x00000002 /* after qdio_cleanup */ +-#define QDIO_STATE_ESTABLISHED 0x00000004 /* after qdio_establish */ +-#define QDIO_STATE_ACTIVE 0x00000008 /* after qdio_activate */ +-#define QDIO_STATE_STOPPED 0x00000010 /* after queues went down */ +- + #define QDIO_FLAG_SYNC_INPUT 0x01 + #define QDIO_FLAG_SYNC_OUTPUT 0x02 + +--- a/drivers/s390/cio/qdio.h ++++ b/drivers/s390/cio/qdio.h +@@ -334,11 +334,6 @@ static inline void qdio_deliver_irq(stru + #define sub_buf(bufnr, dec) QDIO_BUFNR((bufnr) - (dec)) + #define prev_buf(bufnr) sub_buf(bufnr, 1) + +-#define queue_irqs_enabled(q) \ +- (test_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state) == 0) +-#define queue_irqs_disabled(q) \ +- (test_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state) != 0) +- + extern u64 last_ai_time; + + /* prototypes for thin interrupt */ diff --git a/patches.suse/s390-qdio-remove-unused-support-for-SLIB-parameters b/patches.suse/s390-qdio-remove-unused-support-for-SLIB-parameters new file mode 100644 index 0000000..d4f91cf --- /dev/null +++ b/patches.suse/s390-qdio-remove-unused-support-for-SLIB-parameters @@ -0,0 +1,103 @@ +From: Julian Wiedmann +Date: Mon, 26 Jul 2021 08:27:58 +0200 +Subject: s390/qdio: remove unused support for SLIB parameters +Git-commit: 9f79b5495145e295af8519a90c456fd3ab3c50c4 +Patch-mainline: v5.15-rc1 +References: jsc#PED-455 bsc#1203836 LTC#198623 + +Neither of the two drivers provides any SLIB parameter data, so get rid +of the dead code. + +Signed-off-by: Julian Wiedmann +Reviewed-by: Benjamin Block +Signed-off-by: Vasily Gorbik +Acked-by: Petr Tesarik +--- + arch/s390/include/asm/qdio.h | 4 ---- + drivers/s390/cio/qdio_main.c | 2 -- + drivers/s390/cio/qdio_setup.c | 36 ------------------------------------ + 3 files changed, 42 deletions(-) + +--- a/arch/s390/include/asm/qdio.h ++++ b/arch/s390/include/asm/qdio.h +@@ -311,8 +311,6 @@ typedef void qdio_handler_t(struct ccw_d + * @qib_param_field_format: format for qib_parm_field + * @qib_param_field: pointer to 128 bytes or NULL, if no param field + * @qib_rflags: rflags to set +- * @input_slib_elements: pointer to no_input_qs * 128 words of data or NULL +- * @output_slib_elements: pointer to no_output_qs * 128 words of data or NULL + * @no_input_qs: number of input queues + * @no_output_qs: number of output queues + * @input_handler: handler to be called for input queues +@@ -329,8 +327,6 @@ struct qdio_initialize { + unsigned int qib_param_field_format; + unsigned char *qib_param_field; + unsigned char qib_rflags; +- unsigned long *input_slib_elements; +- unsigned long *output_slib_elements; + unsigned int no_input_qs; + unsigned int no_output_qs; + qdio_handler_t *input_handler; +--- a/drivers/s390/cio/qdio_main.c ++++ b/drivers/s390/cio/qdio_main.c +@@ -952,8 +952,6 @@ static void qdio_trace_init_data(struct + DBF_DEV_EVENT(DBF_ERR, irq, "qfmt:%1u", data->q_format); + DBF_DEV_EVENT(DBF_ERR, irq, "qpff%4x", data->qib_param_field_format); + DBF_DEV_HEX(irq, &data->qib_param_field, sizeof(void *), DBF_ERR); +- DBF_DEV_HEX(irq, &data->input_slib_elements, sizeof(void *), DBF_ERR); +- DBF_DEV_HEX(irq, &data->output_slib_elements, sizeof(void *), DBF_ERR); + DBF_DEV_EVENT(DBF_ERR, irq, "niq:%1u noq:%1u", data->no_input_qs, + data->no_output_qs); + DBF_DEV_HEX(irq, &data->input_handler, sizeof(void *), DBF_ERR); +--- a/drivers/s390/cio/qdio_setup.c ++++ b/drivers/s390/cio/qdio_setup.c +@@ -89,39 +89,6 @@ void qdio_reset_buffers(struct qdio_buff + } + EXPORT_SYMBOL_GPL(qdio_reset_buffers); + +-/* +- * qib_param_field: pointer to 128 bytes or NULL, if no param field +- * nr_input_qs: pointer to nr_queues*128 words of data or NULL +- */ +-static void set_impl_params(struct qdio_irq *irq_ptr, +- unsigned long *input_slib_elements, +- unsigned long *output_slib_elements) +-{ +- struct qdio_q *q; +- int i, j; +- +- if (!irq_ptr) +- return; +- +- if (!input_slib_elements) +- goto output; +- +- for_each_input_queue(irq_ptr, q, i) { +- for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++) +- q->slib->slibe[j].parms = +- input_slib_elements[i * QDIO_MAX_BUFFERS_PER_Q + j]; +- } +-output: +- if (!output_slib_elements) +- return; +- +- for_each_output_queue(irq_ptr, q, i) { +- for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++) +- q->slib->slibe[j].parms = +- output_slib_elements[i * QDIO_MAX_BUFFERS_PER_Q + j]; +- } +-} +- + static void __qdio_free_queues(struct qdio_q **queues, unsigned int count) + { + struct qdio_q *q; +@@ -421,9 +388,6 @@ int qdio_setup_irq(struct qdio_irq *irq_ + set_bit(QDIO_IRQ_DISABLED, &irq_ptr->poll_state); + + setup_qib(irq_ptr, init_data); +- set_impl_params(irq_ptr, +- init_data->input_slib_elements, +- init_data->output_slib_elements); + + /* fill input and output descriptors */ + setup_qdr(irq_ptr, init_data); diff --git a/patches.suse/s390-qdio-remove-unused-sync-after-IRQ-infrastructure b/patches.suse/s390-qdio-remove-unused-sync-after-IRQ-infrastructure new file mode 100644 index 0000000..2532a2f --- /dev/null +++ b/patches.suse/s390-qdio-remove-unused-sync-after-IRQ-infrastructure @@ -0,0 +1,81 @@ +From: Julian Wiedmann +Date: Tue, 23 Mar 2021 23:43:02 +0100 +Subject: s390/qdio: remove unused sync-after-IRQ infrastructure +Git-commit: e2af48df5cc6bd6327697af44cc3f0d5e88611a2 +Patch-mainline: v5.15-rc1 +References: jsc#PED-455 bsc#1203836 LTC#198623 + +The queue processing is fully decoupled from any preceding interrupt, +so we're no longer making any use of the sync-after-IRQ HW capabilities. + +And as SIGA-sync is a legacy feature, there's also not much point in +re-designing the driver & qdio-layer code just so that we can +potentially avoid a few syncs. So just remove all the leftover code. + +Signed-off-by: Julian Wiedmann +Reviewed-by: Benjamin Block +Signed-off-by: Vasily Gorbik +Acked-by: Petr Tesarik +--- + drivers/s390/cio/qdio.h | 8 +------- + drivers/s390/cio/qdio_setup.c | 11 ++--------- + 2 files changed, 3 insertions(+), 16 deletions(-) + +--- a/drivers/s390/cio/qdio.h ++++ b/drivers/s390/cio/qdio.h +@@ -130,9 +130,7 @@ struct siga_flag { + u8 input:1; + u8 output:1; + u8 sync:1; +- u8 sync_after_ai:1; +- u8 sync_out_after_pci:1; +- u8:3; ++ u8:5; + } __attribute__ ((packed)); + + struct qdio_dev_perf_stat { +@@ -317,10 +315,6 @@ static inline void qdio_deliver_irq(stru + #define need_siga_in(q) (q->irq_ptr->siga_flag.input) + #define need_siga_out(q) (q->irq_ptr->siga_flag.output) + #define need_siga_sync(q) (unlikely(q->irq_ptr->siga_flag.sync)) +-#define need_siga_sync_after_ai(q) \ +- (unlikely(q->irq_ptr->siga_flag.sync_after_ai)) +-#define need_siga_sync_out_after_pci(q) \ +- (unlikely(q->irq_ptr->siga_flag.sync_out_after_pci)) + + #define for_each_input_queue(irq_ptr, q, i) \ + for (i = 0; i < irq_ptr->nr_input_qs && \ +--- a/drivers/s390/cio/qdio_setup.c ++++ b/drivers/s390/cio/qdio_setup.c +@@ -278,10 +278,6 @@ static void process_ac_flags(struct qdio + irq_ptr->siga_flag.output = 1; + if (qdioac & AC1_SIGA_SYNC_NEEDED) + irq_ptr->siga_flag.sync = 1; +- if (!(qdioac & AC1_AUTOMATIC_SYNC_ON_THININT)) +- irq_ptr->siga_flag.sync_after_ai = 1; +- if (!(qdioac & AC1_AUTOMATIC_SYNC_ON_OUT_PCI)) +- irq_ptr->siga_flag.sync_out_after_pci = 1; + } + + static void check_and_setup_qebsm(struct qdio_irq *irq_ptr, +@@ -495,8 +491,7 @@ void qdio_print_subchannel_info(struct q + { + char s[80]; + +- snprintf(s, 80, "qdio: %s %s on SC %x using " +- "AI:%d QEBSM:%d PRI:%d TDD:%d SIGA:%s%s%s%s%s\n", ++ snprintf(s, 80, "qdio: %s %s on SC %x using AI:%d QEBSM:%d PRI:%d TDD:%d SIGA:%s%s%s\n", + dev_name(&irq_ptr->cdev->dev), + (irq_ptr->qib.qfmt == QDIO_QETH_QFMT) ? "OSA" : + ((irq_ptr->qib.qfmt == QDIO_ZFCP_QFMT) ? "ZFCP" : "HS"), +@@ -507,9 +502,7 @@ void qdio_print_subchannel_info(struct q + css_general_characteristics.aif_tdd, + (irq_ptr->siga_flag.input) ? "R" : " ", + (irq_ptr->siga_flag.output) ? "W" : " ", +- (irq_ptr->siga_flag.sync) ? "S" : " ", +- (irq_ptr->siga_flag.sync_after_ai) ? "A" : " ", +- (irq_ptr->siga_flag.sync_out_after_pci) ? "P" : " "); ++ (irq_ptr->siga_flag.sync) ? "S" : " "); + printk(KERN_INFO "%s", s); + } + diff --git a/patches.suse/s390-qdio-split-do_QDIO b/patches.suse/s390-qdio-split-do_QDIO new file mode 100644 index 0000000..d5f2d7f --- /dev/null +++ b/patches.suse/s390-qdio-split-do_QDIO @@ -0,0 +1,243 @@ +From: Julian Wiedmann +Date: Mon, 30 Aug 2021 15:28:36 +0300 +Subject: s390/qdio: split do_QDIO() +Git-commit: a60bffe536f90834ddedc0ed4ddf81af943eb061 +Patch-mainline: v5.17-rc1 +References: jsc#PED-455 bsc#1203836 LTC#198623 + +The callers know what type of queue they want to work with. Introduce +type-specific variants to add buffers on an {Input,Output} queue, so +that we can avoid some function parameters and the de-muxing into +type-specific hot paths. + +Signed-off-by: Julian Wiedmann +Reviewed-by: Benjamin Block +Signed-off-by: Heiko Carstens +Acked-by: Petr Tesarik +--- + arch/s390/include/asm/qdio.h | 11 ++++---- + drivers/s390/cio/qdio_main.c | 51 ++++++++++++++++++++++++++++---------- + drivers/s390/net/qeth_core_main.c | 21 ++++++++------- + drivers/s390/scsi/zfcp_qdio.c | 15 ++++++----- + 4 files changed, 64 insertions(+), 34 deletions(-) + +--- a/arch/s390/include/asm/qdio.h ++++ b/arch/s390/include/asm/qdio.h +@@ -336,9 +336,6 @@ struct qdio_initialize { + struct qdio_buffer ***output_sbal_addr_array; + }; + +-#define QDIO_FLAG_SYNC_INPUT 0x01 +-#define QDIO_FLAG_SYNC_OUTPUT 0x02 +- + int qdio_alloc_buffers(struct qdio_buffer **buf, unsigned int count); + void qdio_free_buffers(struct qdio_buffer **buf, unsigned int count); + void qdio_reset_buffers(struct qdio_buffer **buf, unsigned int count); +@@ -350,14 +347,18 @@ extern int qdio_establish(struct ccw_dev + extern int qdio_establish(struct ccw_device *cdev, + struct qdio_initialize *init_data); + extern int qdio_activate(struct ccw_device *); +-extern int do_QDIO(struct ccw_device *cdev, unsigned int callflags, int q_nr, +- unsigned int bufnr, unsigned int count, struct qaob *aob); + extern int qdio_start_irq(struct ccw_device *cdev); + extern int qdio_stop_irq(struct ccw_device *cdev); + extern int qdio_inspect_input_queue(struct ccw_device *cdev, unsigned int nr, + unsigned int *bufnr, unsigned int *error); + extern int qdio_inspect_output_queue(struct ccw_device *cdev, unsigned int nr, + unsigned int *bufnr, unsigned int *error); ++extern int qdio_add_bufs_to_input_queue(struct ccw_device *cdev, ++ unsigned int q_nr, unsigned int bufnr, ++ unsigned int count); ++extern int qdio_add_bufs_to_output_queue(struct ccw_device *cdev, ++ unsigned int q_nr, unsigned int bufnr, ++ unsigned int count, struct qaob *aob); + extern int qdio_shutdown(struct ccw_device *, int); + extern int qdio_free(struct ccw_device *); + extern int qdio_get_ssqd_desc(struct ccw_device *, struct qdio_ssqd_desc *); +--- a/drivers/s390/cio/qdio_main.c ++++ b/drivers/s390/cio/qdio_main.c +@@ -1215,6 +1215,35 @@ static int handle_inbound(struct qdio_q + } + + /** ++ * qdio_add_bufs_to_input_queue - process buffers on an Input Queue ++ * @cdev: associated ccw_device for the qdio subchannel ++ * @q_nr: queue number ++ * @bufnr: buffer number ++ * @count: how many buffers to process ++ */ ++int qdio_add_bufs_to_input_queue(struct ccw_device *cdev, unsigned int q_nr, ++ unsigned int bufnr, unsigned int count) ++{ ++ struct qdio_irq *irq_ptr = cdev->private->qdio_data; ++ ++ if (bufnr >= QDIO_MAX_BUFFERS_PER_Q || count > QDIO_MAX_BUFFERS_PER_Q) ++ return -EINVAL; ++ ++ if (!irq_ptr) ++ return -ENODEV; ++ ++ DBF_DEV_EVENT(DBF_INFO, irq_ptr, "addi b:%02x c:%02x", bufnr, count); ++ ++ if (irq_ptr->state != QDIO_IRQ_STATE_ACTIVE) ++ return -EIO; ++ if (!count) ++ return 0; ++ ++ return handle_inbound(irq_ptr->input_qs[q_nr], bufnr, count); ++} ++EXPORT_SYMBOL_GPL(qdio_add_bufs_to_input_queue); ++ ++/** + * handle_outbound - process filled outbound buffers + * @q: queue containing the buffers + * @bufnr: first buffer to process +@@ -1255,16 +1284,16 @@ static int handle_outbound(struct qdio_q + } + + /** +- * do_QDIO - process input or output buffers ++ * qdio_add_bufs_to_output_queue - process buffers on an Output Queue + * @cdev: associated ccw_device for the qdio subchannel +- * @callflags: input or output and special flags from the program + * @q_nr: queue number + * @bufnr: buffer number + * @count: how many buffers to process +- * @aob: asynchronous operation block (outbound only) ++ * @aob: asynchronous operation block + */ +-int do_QDIO(struct ccw_device *cdev, unsigned int callflags, +- int q_nr, unsigned int bufnr, unsigned int count, struct qaob *aob) ++int qdio_add_bufs_to_output_queue(struct ccw_device *cdev, unsigned int q_nr, ++ unsigned int bufnr, unsigned int count, ++ struct qaob *aob) + { + struct qdio_irq *irq_ptr = cdev->private->qdio_data; + +@@ -1274,20 +1303,16 @@ int do_QDIO(struct ccw_device *cdev, uns + if (!irq_ptr) + return -ENODEV; + +- DBF_DEV_EVENT(DBF_INFO, irq_ptr, +- "do%02x b:%02x c:%02x", callflags, bufnr, count); ++ DBF_DEV_EVENT(DBF_INFO, irq_ptr, "addo b:%02x c:%02x", bufnr, count); + + if (irq_ptr->state != QDIO_IRQ_STATE_ACTIVE) + return -EIO; + if (!count) + return 0; +- if (callflags & QDIO_FLAG_SYNC_INPUT) +- return handle_inbound(irq_ptr->input_qs[q_nr], bufnr, count); +- else if (callflags & QDIO_FLAG_SYNC_OUTPUT) +- return handle_outbound(irq_ptr->output_qs[q_nr], bufnr, count, aob); +- return -EINVAL; ++ ++ return handle_outbound(irq_ptr->output_qs[q_nr], bufnr, count, aob); + } +-EXPORT_SYMBOL_GPL(do_QDIO); ++EXPORT_SYMBOL_GPL(qdio_add_bufs_to_output_queue); + + /** + * qdio_start_irq - enable interrupt processing for the device +--- a/drivers/s390/net/qeth_core_main.c ++++ b/drivers/s390/net/qeth_core_main.c +@@ -359,8 +359,8 @@ static int qeth_cq_init(struct qeth_card + qdio_reset_buffers(card->qdio.c_q->qdio_bufs, + QDIO_MAX_BUFFERS_PER_Q); + card->qdio.c_q->next_buf_to_init = 127; +- rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 1, 0, 127, +- NULL); ++ ++ rc = qdio_add_bufs_to_input_queue(CARD_DDEV(card), 1, 0, 127); + if (rc) { + QETH_CARD_TEXT_(card, 2, "1err%d", rc); + goto out; +@@ -2953,8 +2954,7 @@ static int qeth_init_qdio_queues(struct + } + + card->qdio.in_q->next_buf_to_init = QDIO_BUFNR(rx_bufs); +- rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 0, 0, rx_bufs, +- NULL); ++ rc = qdio_add_bufs_to_input_queue(CARD_DDEV(card), 0, 0, rx_bufs); + if (rc) { + QETH_CARD_TEXT_(card, 2, "1err%d", rc); + return rc; +@@ -3445,8 +3445,9 @@ static unsigned int qeth_rx_refill_queue + return 0; + } + +- rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 0, +- queue->next_buf_to_init, count, NULL); ++ rc = qdio_add_bufs_to_input_queue(CARD_DDEV(card), 0, ++ queue->next_buf_to_init, ++ count); + if (rc) { + QETH_CARD_TEXT(card, 2, "qinberr"); + } +@@ -3617,8 +3618,8 @@ static void qeth_flush_buffers(struct qe + } + + QETH_TXQ_STAT_INC(queue, doorbell); +- rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_OUTPUT, queue->queue_no, +- index, count, aob); ++ rc = qdio_add_bufs_to_output_queue(CARD_DDEV(card), queue->queue_no, ++ index, count, aob); + + switch (rc) { + case 0: +@@ -3768,8 +3769,8 @@ static void qeth_qdio_cq_handler(struct + } + qeth_scrub_qdio_buffer(buffer, QDIO_MAX_ELEMENTS_PER_BUFFER); + } +- rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, queue, +- cq->next_buf_to_init, count, NULL); ++ rc = qdio_add_bufs_to_input_queue(CARD_DDEV(card), queue, ++ cq->next_buf_to_init, count); + if (rc) { + dev_warn(&card->gdev->dev, + "QDIO reported an error, rc=%i\n", rc); +--- a/drivers/s390/scsi/zfcp_qdio.c ++++ b/drivers/s390/scsi/zfcp_qdio.c +@@ -154,7 +154,7 @@ static void zfcp_qdio_int_resp(struct cc + /* + * put SBALs back to response queue + */ +- if (do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, idx, count, NULL)) ++ if (qdio_add_bufs_to_input_queue(cdev, 0, idx, count)) + zfcp_erp_adapter_reopen(qdio->adapter, 0, "qdires2"); + } + +@@ -326,8 +326,9 @@ int zfcp_qdio_send(struct zfcp_qdio *qdi + + atomic_sub(sbal_number, &qdio->req_q_free); + +- retval = do_QDIO(qdio->adapter->ccw_device, QDIO_FLAG_SYNC_OUTPUT, 0, +- q_req->sbal_first, sbal_number, NULL); ++ retval = qdio_add_bufs_to_output_queue(qdio->adapter->ccw_device, 0, ++ q_req->sbal_first, sbal_number, ++ NULL); + + if (unlikely(retval)) { + /* Failed to submit the IO, roll back our modifications. */ +@@ -395,7 +396,10 @@ void zfcp_qdio_close(struct zfcp_qdio *q + if (!(atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP)) + return; + +- /* clear QDIOUP flag, thus do_QDIO is not called during qdio_shutdown */ ++ /* ++ * Clear QDIOUP flag, thus qdio_add_bufs_to_output_queue() is not called ++ * during qdio_shutdown(). ++ */ + spin_lock_irq(&qdio->req_q_lock); + atomic_andnot(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status); + spin_unlock_irq(&qdio->req_q_lock); +@@ -498,8 +502,7 @@ int zfcp_qdio_open(struct zfcp_qdio *qdi + sbale->addr = 0; + } + +- if (do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, 0, QDIO_MAX_BUFFERS_PER_Q, +- NULL)) ++ if (qdio_add_bufs_to_input_queue(cdev, 0, 0, QDIO_MAX_BUFFERS_PER_Q)) + goto failed_qdio; + + /* set index of first available SBALS / number of available SBALS */ diff --git a/patches.suse/s390-qdio-split-qdio_inspect_queue b/patches.suse/s390-qdio-split-qdio_inspect_queue new file mode 100644 index 0000000..41c7cbb --- /dev/null +++ b/patches.suse/s390-qdio-split-qdio_inspect_queue @@ -0,0 +1,205 @@ +From: Julian Wiedmann +Date: Fri, 23 Jul 2021 09:16:10 +0200 +Subject: s390/qdio: split qdio_inspect_queue() +Git-commit: b44995e515227e68af8a337c0538e17b05ae560f +Patch-mainline: v5.17-rc1 +References: jsc#PED-455 bsc#1203836 LTC#198623 + +The callers know what type of queue they want to inspect. Introduce +type-specific variants to inspect an {Input,Output} queue, so that we +can avoid one function parameter and some conditional branches in the +hot paths. + +Signed-off-by: Julian Wiedmann +Reviewed-by: Benjamin Block +Signed-off-by: Heiko Carstens +Acked-by: Petr Tesarik +--- + arch/s390/include/asm/qdio.h | 7 +-- + drivers/s390/cio/qdio_main.c | 84 ++++++++++++++++++++++---------------- + drivers/s390/net/qeth_core_main.c | 16 +++---- + drivers/s390/scsi/zfcp_qdio.c | 4 - + 4 files changed, 64 insertions(+), 47 deletions(-) + +--- a/arch/s390/include/asm/qdio.h ++++ b/arch/s390/include/asm/qdio.h +@@ -354,9 +354,10 @@ extern int do_QDIO(struct ccw_device *cd + unsigned int bufnr, unsigned int count, struct qaob *aob); + extern int qdio_start_irq(struct ccw_device *cdev); + extern int qdio_stop_irq(struct ccw_device *cdev); +-extern int qdio_inspect_queue(struct ccw_device *cdev, unsigned int nr, +- bool is_input, unsigned int *bufnr, +- unsigned int *error); ++extern int qdio_inspect_input_queue(struct ccw_device *cdev, unsigned int nr, ++ unsigned int *bufnr, unsigned int *error); ++extern int qdio_inspect_output_queue(struct ccw_device *cdev, unsigned int nr, ++ unsigned int *bufnr, unsigned int *error); + extern int qdio_shutdown(struct ccw_device *, int); + extern int qdio_free(struct ccw_device *); + extern int qdio_get_ssqd_desc(struct ccw_device *, struct qdio_ssqd_desc *); +--- a/drivers/s390/cio/qdio_main.c ++++ b/drivers/s390/cio/qdio_main.c +@@ -500,6 +500,31 @@ static int get_inbound_buffer_frontier(s + } + } + ++int qdio_inspect_input_queue(struct ccw_device *cdev, unsigned int nr, ++ unsigned int *bufnr, unsigned int *error) ++{ ++ struct qdio_irq *irq = cdev->private->qdio_data; ++ unsigned int start; ++ struct qdio_q *q; ++ int count; ++ ++ if (!irq) ++ return -ENODEV; ++ ++ q = irq->input_qs[nr]; ++ start = q->first_to_check; ++ *error = 0; ++ ++ count = get_inbound_buffer_frontier(q, start, error); ++ if (count == 0) ++ return 0; ++ ++ *bufnr = start; ++ q->first_to_check = add_buf(start, count); ++ return count; ++} ++EXPORT_SYMBOL_GPL(qdio_inspect_input_queue); ++ + static inline int qdio_inbound_q_done(struct qdio_q *q, unsigned int start) + { + unsigned char state = 0; +@@ -579,6 +604,31 @@ static int get_outbound_buffer_frontier( + } + } + ++int qdio_inspect_output_queue(struct ccw_device *cdev, unsigned int nr, ++ unsigned int *bufnr, unsigned int *error) ++{ ++ struct qdio_irq *irq = cdev->private->qdio_data; ++ unsigned int start; ++ struct qdio_q *q; ++ int count; ++ ++ if (!irq) ++ return -ENODEV; ++ ++ q = irq->output_qs[nr]; ++ start = q->first_to_check; ++ *error = 0; ++ ++ count = get_outbound_buffer_frontier(q, start, error); ++ if (count == 0) ++ return 0; ++ ++ *bufnr = start; ++ q->first_to_check = add_buf(start, count); ++ return count; ++} ++EXPORT_SYMBOL_GPL(qdio_inspect_output_queue); ++ + static int qdio_kick_outbound_q(struct qdio_q *q, unsigned int count, + unsigned long aob) + { +@@ -1284,40 +1334,6 @@ rescan: + } + EXPORT_SYMBOL(qdio_start_irq); + +-static int __qdio_inspect_queue(struct qdio_q *q, unsigned int *bufnr, +- unsigned int *error) +-{ +- unsigned int start = q->first_to_check; +- int count; +- +- *error = 0; +- count = q->is_input_q ? get_inbound_buffer_frontier(q, start, error) : +- get_outbound_buffer_frontier(q, start, error); +- if (count == 0) +- return 0; +- +- *bufnr = start; +- +- /* for the next time */ +- q->first_to_check = add_buf(start, count); +- +- return count; +-} +- +-int qdio_inspect_queue(struct ccw_device *cdev, unsigned int nr, bool is_input, +- unsigned int *bufnr, unsigned int *error) +-{ +- struct qdio_irq *irq_ptr = cdev->private->qdio_data; +- struct qdio_q *q; +- +- if (!irq_ptr) +- return -ENODEV; +- q = is_input ? irq_ptr->input_qs[nr] : irq_ptr->output_qs[nr]; +- +- return __qdio_inspect_queue(q, bufnr, error); +-} +-EXPORT_SYMBOL_GPL(qdio_inspect_queue); +- + /** + * qdio_stop_irq - disable interrupt processing for the device + * @cdev: associated ccw_device for the qdio subchannel +--- a/drivers/s390/net/qeth_core_main.c ++++ b/drivers/s390/net/qeth_core_main.c +@@ -5898,10 +5898,10 @@ static unsigned int qeth_rx_poll(struct + /* Fetch completed RX buffers: */ + if (!card->rx.b_count) { + card->rx.qdio_err = 0; +- card->rx.b_count = qdio_inspect_queue(CARD_DDEV(card), +- 0, true, +- &card->rx.b_index, +- &card->rx.qdio_err); ++ card->rx.b_count = ++ qdio_inspect_input_queue(CARD_DDEV(card), 0, ++ &card->rx.b_index, ++ &card->rx.qdio_err); + if (card->rx.b_count <= 0) { + card->rx.b_count = 0; + break; +@@ -5948,8 +5948,8 @@ static void qeth_cq_poll(struct qeth_car + unsigned int start, error; + int completed; + +- completed = qdio_inspect_queue(CARD_DDEV(card), 1, true, &start, +- &error); ++ completed = qdio_inspect_input_queue(CARD_DDEV(card), 1, &start, ++ &error); + if (completed <= 0) + return; + +@@ -6086,8 +6086,8 @@ static int qeth_tx_poll(struct napi_stru + return 0; + } + +- completed = qdio_inspect_queue(CARD_DDEV(card), queue_no, false, +- &start, &error); ++ completed = qdio_inspect_output_queue(CARD_DDEV(card), queue_no, ++ &start, &error); + if (completed <= 0) { + /* Ensure we see TX completion for pending work: */ + if (napi_complete_done(napi, 0) && +--- a/drivers/s390/scsi/zfcp_qdio.c ++++ b/drivers/s390/scsi/zfcp_qdio.c +@@ -79,7 +79,7 @@ static void zfcp_qdio_request_tasklet(st + unsigned int start, error; + int completed; + +- completed = qdio_inspect_queue(cdev, 0, false, &start, &error); ++ completed = qdio_inspect_output_queue(cdev, 0, &start, &error); + if (completed > 0) { + if (error) { + zfcp_qdio_handler_error(qdio, "qdreqt1", error); +@@ -169,7 +169,7 @@ static void zfcp_qdio_irq_tasklet(struct + tasklet_schedule(&qdio->request_tasklet); + + /* Check the Response Queue: */ +- completed = qdio_inspect_queue(cdev, 0, true, &start, &error); ++ completed = qdio_inspect_input_queue(cdev, 0, &start, &error); + if (completed < 0) + return; + if (completed > 0) diff --git a/patches.suse/s390-qdio-use-absolute-data-address-in-ESTABLISH-ccw b/patches.suse/s390-qdio-use-absolute-data-address-in-ESTABLISH-ccw new file mode 100644 index 0000000..365f45d --- /dev/null +++ b/patches.suse/s390-qdio-use-absolute-data-address-in-ESTABLISH-ccw @@ -0,0 +1,29 @@ +From: Julian Wiedmann +Date: Thu, 8 Jul 2021 08:32:46 +0200 +Subject: s390/qdio: use absolute data address in ESTABLISH ccw +Git-commit: eade5f61a56f7589ebc5d321bfa2fdf349552e45 +Patch-mainline: v5.15-rc1 +References: jsc#PED-455 bsc#1203836 LTC#198623 + +Clean up yet another path where HW wants an absolute address, and we've +been implicitly relying on V=R. + +Signed-off-by: Julian Wiedmann +Reviewed-by: Benjamin Block +Signed-off-by: Vasily Gorbik +Acked-by: Petr Tesarik +--- + drivers/s390/cio/qdio_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/s390/cio/qdio_main.c ++++ b/drivers/s390/cio/qdio_main.c +@@ -998,7 +998,7 @@ int qdio_establish(struct ccw_device *cd + irq_ptr->ccw.cmd_code = irq_ptr->equeue.cmd; + irq_ptr->ccw.flags = CCW_FLAG_SLI; + irq_ptr->ccw.count = irq_ptr->equeue.count; +- irq_ptr->ccw.cda = (u32)((addr_t)irq_ptr->qdr); ++ irq_ptr->ccw.cda = (u32) virt_to_phys(irq_ptr->qdr); + + spin_lock_irq(get_ccwdev_lock(cdev)); + ccw_device_set_options_mask(cdev, 0); diff --git a/patches.suse/s390-qdio-use-dev_info-in-qdio_print_subchannel_info b/patches.suse/s390-qdio-use-dev_info-in-qdio_print_subchannel_info new file mode 100644 index 0000000..ac46772 --- /dev/null +++ b/patches.suse/s390-qdio-use-dev_info-in-qdio_print_subchannel_info @@ -0,0 +1,47 @@ +From: Julian Wiedmann +Date: Mon, 12 Jul 2021 09:39:57 +0200 +Subject: s390/qdio: use dev_info() in qdio_print_subchannel_info() +Git-commit: f86991b3a95ab245510ccd111926d1f40ae13b91 +Patch-mainline: v5.15-rc1 +References: jsc#PED-455 bsc#1203836 LTC#198623 + +Prefer dev_info() over a raw printk. This also adds the device and +driver names into the output, so that we have: + +Before: + qdio: 0.0.17c0 ZFCP on SC 17 using [...] + +After: + zfcp 0.0.17c0: qdio: ZFCP on SC 17 using [...] + +Signed-off-by: Julian Wiedmann +Reviewed-by: Benjamin Block +Signed-off-by: Vasily Gorbik +Acked-by: Petr Tesarik +--- + drivers/s390/cio/qdio_setup.c | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +--- a/drivers/s390/cio/qdio_setup.c ++++ b/drivers/s390/cio/qdio_setup.c +@@ -479,10 +479,8 @@ void qdio_shutdown_irq(struct qdio_irq * + + void qdio_print_subchannel_info(struct qdio_irq *irq_ptr) + { +- char s[80]; +- +- snprintf(s, 80, "qdio: %s %s on SC %x using AI:%d QEBSM:%d PRI:%d TDD:%d SIGA:%s%s%s\n", +- dev_name(&irq_ptr->cdev->dev), ++ dev_info(&irq_ptr->cdev->dev, ++ "qdio: %s on SC %x using AI:%d QEBSM:%d PRI:%d TDD:%d SIGA:%s%s%s\n", + (irq_ptr->qib.qfmt == QDIO_QETH_QFMT) ? "OSA" : + ((irq_ptr->qib.qfmt == QDIO_ZFCP_QFMT) ? "ZFCP" : "HS"), + irq_ptr->schid.sch_no, +@@ -493,7 +491,6 @@ void qdio_print_subchannel_info(struct q + qdio_need_siga_in(irq_ptr) ? "R" : " ", + qdio_need_siga_out(irq_ptr) ? "W" : " ", + qdio_need_siga_sync(irq_ptr) ? "S" : " "); +- printk(KERN_INFO "%s", s); + } + + int __init qdio_setup_init(void) diff --git a/patches.suse/s390-qeth-Fix-typo-the-the-in-comment b/patches.suse/s390-qeth-Fix-typo-the-the-in-comment new file mode 100644 index 0000000..894a936 --- /dev/null +++ b/patches.suse/s390-qeth-Fix-typo-the-the-in-comment @@ -0,0 +1,27 @@ +From: Slark Xiao +Date: Fri, 22 Jul 2022 17:38:34 +0800 +Subject: s390/qeth: Fix typo 'the the' in comment +Git-commit: 1aaa62c4838a140d0592935c51985158963d5971 +Patch-mainline: v5.19 +References: jsc#PED-448 LTC#198619 + +Replace 'the the' with 'the' in the comment. + +Signed-off-by: Slark Xiao +Signed-off-by: David S. Miller +Acked-by: Petr Tesarik +--- + drivers/s390/net/qeth_core_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/s390/net/qeth_core_main.c ++++ b/drivers/s390/net/qeth_core_main.c +@@ -3590,7 +3590,7 @@ static void qeth_flush_buffers(struct qe + if (!atomic_read(&queue->set_pci_flags_count)) { + /* + * there's no outstanding PCI any more, so we +- * have to request a PCI to be sure the the PCI ++ * have to request a PCI to be sure the PCI + * will wake at some time in the future then we + * can flush packed buffers that might still be + * hanging around, which can happen if no diff --git a/patches.suse/s390-qeth-Register-switchdev-event-handler b/patches.suse/s390-qeth-Register-switchdev-event-handler index b62044c..691ad8b 100644 --- a/patches.suse/s390-qeth-Register-switchdev-event-handler +++ b/patches.suse/s390-qeth-Register-switchdev-event-handler @@ -80,7 +80,7 @@ Acked-by: Petr Tesarik struct qeth_card *card = dev_get_drvdata(&gdev->dev); + struct qeth_priv *priv; - if (gdev->dev.type == &qeth_generic_devtype) + if (gdev->dev.type != &qeth_l2_devtype) device_remove_groups(&gdev->dev, qeth_l2_attr_groups); @@ -2219,8 +2248,15 @@ static void qeth_l2_remove_device(struct qeth_set_offline(card, card->discipline, false); diff --git a/patches.suse/s390-qeth-Remove-redundant-flush_workqueue-calls b/patches.suse/s390-qeth-Remove-redundant-flush_workqueue-calls new file mode 100644 index 0000000..b31ed65 --- /dev/null +++ b/patches.suse/s390-qeth-Remove-redundant-flush_workqueue-calls @@ -0,0 +1,31 @@ +From: Xu Wang +Date: Wed, 16 Feb 2022 07:51:55 +0000 +Subject: s390/qeth: Remove redundant 'flush_workqueue()' calls +Git-commit: 129c77b5692d4a95a00aa7d58075afe77179623e +Patch-mainline: v5.18-rc1 +References: jsc#PED-448 LTC#198619 + +'destroy_workqueue()' already drains the queue before destroying it, so +there is no need to flush it explicitly. + +Remove the redundant 'flush_workqueue()' calls. + +Signed-off-by: Xu Wang +Acked-by: Alexandra Winter +Link: https://lore.kernel.org/r/20220216075155.940-1-vulab@iscas.ac.cn +Signed-off-by: Jakub Kicinski +Acked-by: Petr Tesarik +--- + drivers/s390/net/qeth_l3_main.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/s390/net/qeth_l3_main.c ++++ b/drivers/s390/net/qeth_l3_main.c +@@ -1961,7 +1961,6 @@ static void qeth_l3_remove_device(struct + if (card->dev->reg_state == NETREG_REGISTERED) + unregister_netdev(card->dev); + +- flush_workqueue(card->cmd_wq); + destroy_workqueue(card->cmd_wq); + qeth_l3_clear_ip_htable(card, 0); + qeth_l3_clear_ipato_list(card); diff --git a/patches.suse/s390-qeth-add-__printf-format-attribute-to-qeth_dbf_longtext b/patches.suse/s390-qeth-add-__printf-format-attribute-to-qeth_dbf_longtext new file mode 100644 index 0000000..b026b36 --- /dev/null +++ b/patches.suse/s390-qeth-add-__printf-format-attribute-to-qeth_dbf_longtext @@ -0,0 +1,38 @@ +From: Heiko Carstens +Date: Mon, 25 Oct 2021 11:56:56 +0200 +Subject: s390/qeth: add __printf format attribute to qeth_dbf_longtext +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Git-commit: 79140e22d245aa3d06e2991f397c187b3ab07df3 +Patch-mainline: v5.16-rc1 +References: jsc#PED-448 LTC#198619 + +Allow the compiler to recognize and check format strings and parameters. + +As reported with allmodconfig and W=1: + +drivers/s390/net/qeth_core_main.c: In function ‘qeth_dbf_longtext’: +drivers/s390/net/qeth_core_main.c:6190:9: error: function ‘qeth_dbf_longtext’ might be a candidate for ‘gnu_printf’ format attribute [-Werror=suggest-attribute=format] + 6190 | vsnprintf(dbf_txt_buf, sizeof(dbf_txt_buf), fmt, args); + | ^~~~~~~~~ + +Acked-by: Julian Wiedmann +Signed-off-by: Heiko Carstens +Signed-off-by: Julian Wiedmann +Signed-off-by: David S. Miller +Acked-by: Petr Tesarik +--- + drivers/s390/net/qeth_core.h | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/s390/net/qeth_core.h ++++ b/drivers/s390/net/qeth_core.h +@@ -1121,6 +1121,7 @@ int qeth_do_send_packet(struct qeth_card + int qeth_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); + int qeth_siocdevprivate(struct net_device *dev, struct ifreq *rq, + void __user *data, int cmd); ++__printf(3, 4) + void qeth_dbf_longtext(debug_info_t *id, int level, char *text, ...); + int qeth_configure_cq(struct qeth_card *, enum qeth_cq); + int qeth_hw_trap(struct qeth_card *, enum qeth_diags_trap_action); diff --git a/patches.suse/s390-qeth-allocate-RX-queue-at-probe-time b/patches.suse/s390-qeth-allocate-RX-queue-at-probe-time new file mode 100644 index 0000000..37b91b5 --- /dev/null +++ b/patches.suse/s390-qeth-allocate-RX-queue-at-probe-time @@ -0,0 +1,118 @@ +From: Julian Wiedmann +Date: Thu, 18 Nov 2021 17:06:02 +0100 +Subject: s390/qeth: allocate RX queue at probe time +Git-commit: 832585d2172fdaa29ee6497a94c0b9da0ab97eec +Patch-mainline: v5.17-rc1 +References: jsc#PED-448 LTC#198619 + +We always need an RX queue, and there's no reconfig situation either +where we would need to free & rebuild the queue. + +So allocate the RX queue right from the start, and avoid freeing it +during unrelated qeth_free_qdio_queues() calls. + +Signed-off-by: Julian Wiedmann +Signed-off-by: Karsten Graul +Signed-off-by: David S. Miller +Acked-by: Petr Tesarik +--- + drivers/s390/net/qeth_core_main.c | 35 +++++++++++++++++------------------ + 1 file changed, 17 insertions(+), 18 deletions(-) + +--- a/drivers/s390/net/qeth_core_main.c ++++ b/drivers/s390/net/qeth_core_main.c +@@ -199,9 +199,6 @@ static void qeth_clear_working_pool_list + &card->qdio.in_buf_pool.entry_list, list) + list_del(&pool_entry->list); + +- if (!queue) +- return; +- + for (i = 0; i < ARRAY_SIZE(queue->bufs); i++) + queue->bufs[i].pool_entry = NULL; + } +@@ -280,8 +277,8 @@ int qeth_resize_buffer_pool(struct qeth_ + + QETH_CARD_TEXT(card, 2, "realcbp"); + +- /* Defer until queue is allocated: */ +- if (!card->qdio.in_q) ++ /* Defer until pool is allocated: */ ++ if (list_empty(&pool->entry_list)) + goto out; + + /* Remove entries from the pool: */ +@@ -2579,14 +2576,9 @@ static int qeth_alloc_qdio_queues(struct + QETH_QDIO_ALLOCATED) != QETH_QDIO_UNINITIALIZED) + return 0; + +- QETH_CARD_TEXT(card, 2, "inq"); +- card->qdio.in_q = qeth_alloc_qdio_queue(); +- if (!card->qdio.in_q) +- goto out_nomem; +- + /* inbound buffer pool */ + if (qeth_alloc_buffer_pool(card)) +- goto out_freeinq; ++ goto out_buffer_pool; + + /* outbound */ + for (i = 0; i < card->qdio.no_out_queues; ++i) { +@@ -2627,10 +2619,7 @@ out_freeoutq: + card->qdio.out_qs[i] = NULL; + } + qeth_free_buffer_pool(card); +-out_freeinq: +- qeth_free_qdio_queue(card->qdio.in_q); +- card->qdio.in_q = NULL; +-out_nomem: ++out_buffer_pool: + atomic_set(&card->qdio.state, QETH_QDIO_UNINITIALIZED); + return -ENOMEM; + } +@@ -2645,11 +2634,12 @@ static void qeth_free_qdio_queues(struct + + qeth_free_cq(card); + for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) { +- if (card->qdio.in_q->bufs[j].rx_skb) ++ if (card->qdio.in_q->bufs[j].rx_skb) { + consume_skb(card->qdio.in_q->bufs[j].rx_skb); ++ card->qdio.in_q->bufs[j].rx_skb = NULL; ++ } + } +- qeth_free_qdio_queue(card->qdio.in_q); +- card->qdio.in_q = NULL; ++ + /* inbound buffer pool */ + qeth_free_buffer_pool(card); + /* free outbound qdio_qs */ +@@ -6508,6 +6498,12 @@ static int qeth_core_probe_device(struct + qeth_determine_capabilities(card); + qeth_set_blkt_defaults(card); + ++ card->qdio.in_q = qeth_alloc_qdio_queue(); ++ if (!card->qdio.in_q) { ++ rc = -ENOMEM; ++ goto err_rx_queue; ++ } ++ + card->qdio.no_out_queues = card->dev->num_tx_queues; + rc = qeth_update_from_chp_desc(card); + if (rc) +@@ -6537,6 +6533,8 @@ static int qeth_core_probe_device(struct + + err_setup_disc: + err_chp_desc: ++ qeth_free_qdio_queue(card->qdio.in_q); ++err_rx_queue: + free_netdev(card->dev); + err_card: + qeth_core_free_card(card); +@@ -6558,6 +6556,7 @@ static void qeth_core_remove_device(stru + + qeth_free_qdio_queues(card); + ++ qeth_free_qdio_queue(card->qdio.in_q); + free_netdev(card->dev); + qeth_core_free_card(card); + put_device(&gdev->dev); diff --git a/patches.suse/s390-qeth-clarify-remaining-dev_kfree_skb_any-users b/patches.suse/s390-qeth-clarify-remaining-dev_kfree_skb_any-users new file mode 100644 index 0000000..afc739e --- /dev/null +++ b/patches.suse/s390-qeth-clarify-remaining-dev_kfree_skb_any-users @@ -0,0 +1,50 @@ +From: Julian Wiedmann +Date: Mon, 25 Oct 2021 11:56:53 +0200 +Subject: s390/qeth: clarify remaining dev_kfree_skb_any() users +Git-commit: fdd3c5f076b69cba2e53e00d9b5191724c7d62f3 +Patch-mainline: v5.16-rc1 +References: jsc#PED-448 LTC#198619 + +For none of the users we are under risk of running in HW IRQ context or +or with IRQs disabled. Thus we always end up in consume_skb(). + +But the two occurences in the RX path should really report the dropped +packet to dropmon, so have them use kfree_skb() instead. That's also +consistent with what napi_free_frags() does internally. + +Signed-off-by: Julian Wiedmann +Signed-off-by: David S. Miller +Acked-by: Petr Tesarik +--- + drivers/s390/net/qeth_core_main.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/s390/net/qeth_core_main.c ++++ b/drivers/s390/net/qeth_core_main.c +@@ -2652,7 +2652,7 @@ static void qeth_free_qdio_queues(struct + qeth_free_cq(card); + for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) { + if (card->qdio.in_q->bufs[j].rx_skb) +- dev_kfree_skb_any(card->qdio.in_q->bufs[j].rx_skb); ++ consume_skb(card->qdio.in_q->bufs[j].rx_skb); + } + qeth_free_qdio_queue(card->qdio.in_q); + card->qdio.in_q = NULL; +@@ -5644,7 +5644,7 @@ static void qeth_receive_skb(struct qeth + if (uses_frags) + napi_free_frags(napi); + else +- dev_kfree_skb_any(skb); ++ kfree_skb(skb); + return; + } + +@@ -5846,7 +5846,7 @@ walk_packet: + if (uses_frags) + napi_free_frags(napi); + else +- dev_kfree_skb_any(skb); ++ kfree_skb(skb); + QETH_CARD_STAT_INC(card, + rx_length_errors); + } diff --git a/patches.suse/s390-qeth-clean-up-QETH_PROT_-naming b/patches.suse/s390-qeth-clean-up-QETH_PROT_-naming new file mode 100644 index 0000000..05653d4 --- /dev/null +++ b/patches.suse/s390-qeth-clean-up-QETH_PROT_-naming @@ -0,0 +1,50 @@ +From: Julian Wiedmann +Date: Tue, 20 Jul 2021 08:38:48 +0200 +Subject: s390/qeth: clean up QETH_PROT_* naming +Git-commit: a37cfa28ebdc6a2286569ef783c4ba5c719f4902 +Patch-mainline: v5.15-rc1 +References: jsc#PED-448 LTC#198619 + +The QETH_PROT_* naming is shared among two unrelated areas - one is +the MPC-level protocol identifiers, the other is the qeth_prot_version +enum. + +Rename the MPC definitions to use QETH_MPC_PROT_*. + +Signed-off-by: Julian Wiedmann +Reviewed-by: Alexandra Winter +Signed-off-by: David S. Miller +Acked-by: Petr Tesarik +--- + drivers/s390/net/qeth_core_main.c | 2 +- + drivers/s390/net/qeth_core_mpc.h | 8 ++++---- + 2 files changed, 5 insertions(+), 5 deletions(-) + +--- a/drivers/s390/net/qeth_core_main.c ++++ b/drivers/s390/net/qeth_core_main.c +@@ -2444,7 +2444,7 @@ static u8 qeth_mpc_select_prot_type(stru + { + if (IS_OSN(card)) + return QETH_PROT_OSN2; +- return IS_LAYER2(card) ? QETH_PROT_LAYER2 : QETH_PROT_TCPIP; ++ return IS_LAYER2(card) ? QETH_MPC_PROT_L2 : QETH_MPC_PROT_L3; + } + + static int qeth_ulp_enable(struct qeth_card *card) +--- a/drivers/s390/net/qeth_core_mpc.h ++++ b/drivers/s390/net/qeth_core_mpc.h +@@ -919,10 +919,10 @@ extern const unsigned char ULP_ENABLE[]; + (PDU_ENCAPSULATION(buffer) + 0x17) + #define QETH_ULP_ENABLE_RESP_LINK_TYPE(buffer) \ + (PDU_ENCAPSULATION(buffer) + 0x2b) +-/* Layer 2 definitions */ +-#define QETH_PROT_LAYER2 0x08 +-#define QETH_PROT_TCPIP 0x03 +-#define QETH_PROT_OSN2 0x0a ++ ++#define QETH_MPC_PROT_L2 0x08 ++#define QETH_MPC_PROT_L3 0x03 ++#define QETH_PROT_OSN2 0x0a + #define QETH_ULP_ENABLE_PROT_TYPE(buffer) (buffer + 0x50) + #define QETH_IPA_CMD_PROT_TYPE(buffer) (buffer + 0x19) + diff --git a/patches.suse/s390-qeth-clean-up-device_type-management b/patches.suse/s390-qeth-clean-up-device_type-management new file mode 100644 index 0000000..a59de2e --- /dev/null +++ b/patches.suse/s390-qeth-clean-up-device_type-management @@ -0,0 +1,157 @@ +From: Julian Wiedmann +Date: Tue, 20 Jul 2021 08:38:49 +0200 +Subject: s390/qeth: clean up device_type management +Git-commit: ae57ea7a19b784e5982ae25bdba3cdf7c98f3067 +Patch-mainline: v5.15-rc1 +References: jsc#PED-448 LTC#198619 + +qeth uses three device_type structs - a generic one, and one for each +sub-driver (which is used for fixed-layer devices only). Instead of +exporting these device_types back&forth between the driver's modules, +make all the logic self-contained within the sub-drivers. + +On disc->setup() they either install their own device_type, or add the +sysfs attributes that are missing in the generic device_type. Later on +disc->remove() these attributes are removed again from any device that +has the generic device_type. + +Signed-off-by: Julian Wiedmann +Signed-off-by: David S. Miller +[ ptesarik: qeth_l2_probe_device() had to be extended, and + qeth_osn_devtype was moved to another file, because OSN + support has not been dropped from SLE15-SP5. ] +Signed-off-by: Petr Tesarik +--- + drivers/s390/net/qeth_core.h | 2 -- + drivers/s390/net/qeth_core_main.c | 9 +-------- + drivers/s390/net/qeth_l2_main.c | 13 ++++++++++--- + drivers/s390/net/qeth_l3_main.c | 7 ++++--- + 4 files changed, 15 insertions(+), 16 deletions(-) + +--- a/drivers/s390/net/qeth_core.h ++++ b/drivers/s390/net/qeth_core.h +@@ -785,7 +785,6 @@ struct qeth_osn_info { + }; + + struct qeth_discipline { +- const struct device_type *devtype; + int (*setup) (struct ccwgroup_device *); + void (*remove) (struct ccwgroup_device *); + int (*set_online)(struct qeth_card *card, bool carrier_ok); +@@ -1061,7 +1060,6 @@ extern const struct ethtool_ops qeth_eth + extern const struct ethtool_ops qeth_osn_ethtool_ops; + extern const struct attribute_group *qeth_dev_groups[]; + extern const struct attribute_group *qeth_osn_dev_groups[]; +-extern const struct device_type qeth_generic_devtype; + + const char *qeth_get_cardname_short(struct qeth_card *); + int qeth_resize_buffer_pool(struct qeth_card *card, unsigned int count); +--- a/drivers/s390/net/qeth_core_main.c ++++ b/drivers/s390/net/qeth_core_main.c +@@ -6331,14 +6331,9 @@ void qeth_remove_discipline(struct qeth_ + card->discipline = NULL; + } + +-const struct device_type qeth_generic_devtype = { ++static const struct device_type qeth_generic_devtype = { + .name = "qeth_generic", + }; +-EXPORT_SYMBOL_GPL(qeth_generic_devtype); +- +-static const struct device_type qeth_osn_devtype = { +- .name = "qeth_osn", +-}; + + #define DBF_NAME_LEN 20 + +@@ -6534,8 +6529,6 @@ static int qeth_core_probe_device(struct + if (rc) + goto err_setup_disc; + +- gdev->dev.type = IS_OSN(card) ? &qeth_osn_devtype : +- card->discipline->devtype; + break; + } + +--- a/drivers/s390/net/qeth_l2_main.c ++++ b/drivers/s390/net/qeth_l2_main.c +@@ -2185,6 +2185,10 @@ static const struct device_type qeth_l2_ + .groups = qeth_l2_attr_groups, + }; + ++static const struct device_type qeth_osn_devtype = { ++ .name = "qeth_osn", ++}; ++ + static int qeth_l2_probe_device(struct ccwgroup_device *gdev) + { + struct qeth_card *card = dev_get_drvdata(&gdev->dev); +@@ -2196,10 +2200,13 @@ static int qeth_l2_probe_device(struct c + qeth_l2_vnicc_set_defaults(card); + mutex_init(&card->sbp_lock); + +- if (gdev->dev.type == &qeth_generic_devtype) { ++ if (gdev->dev.type) { + rc = device_add_groups(&gdev->dev, qeth_l2_attr_groups); + if (rc) + return rc; ++ } else { ++ gdev->dev.type = IS_OSN(card) ? &qeth_osn_devtype : ++ &qeth_l2_devtype; + } + + INIT_WORK(&card->rx_mode_work, qeth_l2_rx_mode_work); +@@ -2210,8 +2217,9 @@ static void qeth_l2_remove_device(struct + { + struct qeth_card *card = dev_get_drvdata(&gdev->dev); + +- if (gdev->dev.type == &qeth_generic_devtype) ++ if (gdev->dev.type != &qeth_l2_devtype) + device_remove_groups(&gdev->dev, qeth_l2_attr_groups); ++ + qeth_set_allowed_threads(card, 0, 1); + wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0); + +@@ -2331,7 +2339,6 @@ static int qeth_l2_control_event(struct + } + + const struct qeth_discipline qeth_l2_discipline = { +- .devtype = &qeth_l2_devtype, + .setup = qeth_l2_probe_device, + .remove = qeth_l2_remove_device, + .set_online = qeth_l2_set_online, +--- a/drivers/s390/net/qeth_l3_main.c ++++ b/drivers/s390/net/qeth_l3_main.c +@@ -1940,12 +1940,14 @@ static int qeth_l3_probe_device(struct c + if (!card->cmd_wq) + return -ENOMEM; + +- if (gdev->dev.type == &qeth_generic_devtype) { ++ if (gdev->dev.type) { + rc = device_add_groups(&gdev->dev, qeth_l3_attr_groups); + if (rc) { + destroy_workqueue(card->cmd_wq); + return rc; + } ++ } else { ++ gdev->dev.type = &qeth_l3_devtype; + } + + INIT_WORK(&card->rx_mode_work, qeth_l3_rx_mode_work); +@@ -1956,7 +1958,7 @@ static void qeth_l3_remove_device(struct + { + struct qeth_card *card = dev_get_drvdata(&cgdev->dev); + +- if (cgdev->dev.type == &qeth_generic_devtype) ++ if (cgdev->dev.type != &qeth_l3_devtype) + device_remove_groups(&cgdev->dev, qeth_l3_attr_groups); + + qeth_set_allowed_threads(card, 0, 1); +@@ -2065,7 +2067,6 @@ static int qeth_l3_control_event(struct + } + + const struct qeth_discipline qeth_l3_discipline = { +- .devtype = &qeth_l3_devtype, + .setup = qeth_l3_probe_device, + .remove = qeth_l3_remove_device, + .set_online = qeth_l3_set_online, diff --git a/patches.suse/s390-qeth-don-t-keep-track-of-Input-Queue-count b/patches.suse/s390-qeth-don-t-keep-track-of-Input-Queue-count new file mode 100644 index 0000000..36206c2 --- /dev/null +++ b/patches.suse/s390-qeth-don-t-keep-track-of-Input-Queue-count @@ -0,0 +1,103 @@ +From: Julian Wiedmann +Date: Mon, 25 Oct 2021 11:56:54 +0200 +Subject: s390/qeth: don't keep track of Input Queue count +Git-commit: dc15012bb083c70502b625cf56fbf32b6cf17fe4 +Patch-mainline: v5.16-rc1 +References: jsc#PED-448 LTC#198619 + +The only actual user of qdio.no_input_queues is qeth_qdio_establish(), +and there we already have full awareness of the current Input Queue +configuration (1 RX queue, plus potentially 1 TX Completion queue). + +So avoid this state tracking, and the ambiguity it brings with it. + +Signed-off-by: Julian Wiedmann +Signed-off-by: David S. Miller +Acked-by: Petr Tesarik +--- + drivers/s390/net/qeth_core.h | 1 - + drivers/s390/net/qeth_core_main.c | 17 +++++++---------- + 2 files changed, 7 insertions(+), 11 deletions(-) + +--- a/drivers/s390/net/qeth_core.h ++++ b/drivers/s390/net/qeth_core.h +@@ -558,7 +558,6 @@ static inline bool qeth_out_queue_is_emp + struct qeth_qdio_info { + atomic_t state; + /* input */ +- int no_in_queues; + struct qeth_qdio_q *in_q; + struct qeth_qdio_q *c_q; + struct qeth_qdio_buffer_pool in_buf_pool; +--- a/drivers/s390/net/qeth_core_main.c ++++ b/drivers/s390/net/qeth_core_main.c +@@ -360,8 +360,8 @@ static int qeth_cq_init(struct qeth_card + qdio_reset_buffers(card->qdio.c_q->qdio_bufs, + QDIO_MAX_BUFFERS_PER_Q); + card->qdio.c_q->next_buf_to_init = 127; +- rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, +- card->qdio.no_in_queues - 1, 0, 127, NULL); ++ rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 1, 0, 127, ++ NULL); + if (rc) { + QETH_CARD_TEXT_(card, 2, "1err%d", rc); + goto out; +@@ -381,21 +381,16 @@ static int qeth_alloc_cq(struct qeth_car + dev_err(&card->gdev->dev, "Failed to create completion queue\n"); + return -ENOMEM; + } +- +- card->qdio.no_in_queues = 2; + } else { + QETH_CARD_TEXT(card, 2, "nocq"); + card->qdio.c_q = NULL; +- card->qdio.no_in_queues = 1; + } +- QETH_CARD_TEXT_(card, 2, "iqc%d", card->qdio.no_in_queues); + return 0; + } + + static void qeth_free_cq(struct qeth_card *card) + { + if (card->qdio.c_q) { +- --card->qdio.no_in_queues; + qeth_free_qdio_queue(card->qdio.c_q); + card->qdio.c_q = NULL; + } +@@ -1478,7 +1473,6 @@ static void qeth_init_qdio_info(struct q + card->qdio.default_out_queue = QETH_DEFAULT_QUEUE; + + /* inbound */ +- card->qdio.no_in_queues = 1; + card->qdio.in_buf_size = QETH_IN_BUF_SIZE_DEFAULT; + if (IS_IQD(card)) + card->qdio.init_pool.buf_count = QETH_IN_BUF_COUNT_HSDEFAULT; +@@ -5167,6 +5161,7 @@ static int qeth_qdio_establish(struct qe + struct qdio_buffer **in_sbal_ptrs[QETH_MAX_IN_QUEUES]; + struct qeth_qib_parms *qib_parms = NULL; + struct qdio_initialize init_data; ++ unsigned int no_input_qs = 1; + unsigned int i; + int rc = 0; + +@@ -5181,8 +5176,10 @@ static int qeth_qdio_establish(struct qe + } + + in_sbal_ptrs[0] = card->qdio.in_q->qdio_bufs; +- if (card->options.cq == QETH_CQ_ENABLED) ++ if (card->options.cq == QETH_CQ_ENABLED) { + in_sbal_ptrs[1] = card->qdio.c_q->qdio_bufs; ++ no_input_qs++; ++ } + + for (i = 0; i < card->qdio.no_out_queues; i++) + out_sbal_ptrs[i] = card->qdio.out_qs[i]->qdio_bufs; +@@ -5192,7 +5189,7 @@ static int qeth_qdio_establish(struct qe + QDIO_QETH_QFMT; + init_data.qib_param_field_format = 0; + init_data.qib_param_field = (void *)qib_parms; +- init_data.no_input_qs = card->qdio.no_in_queues; ++ init_data.no_input_qs = no_input_qs; + init_data.no_output_qs = card->qdio.no_out_queues; + init_data.input_handler = qeth_qdio_input_handler; + init_data.output_handler = qeth_qdio_output_handler; diff --git a/patches.suse/s390-qeth-don-t-offer-.ndo_bridge_-ops-for-OSA-devices b/patches.suse/s390-qeth-don-t-offer-.ndo_bridge_-ops-for-OSA-devices new file mode 100644 index 0000000..66cf34a --- /dev/null +++ b/patches.suse/s390-qeth-don-t-offer-.ndo_bridge_-ops-for-OSA-devices @@ -0,0 +1,31 @@ +From: Julian Wiedmann +Date: Tue, 7 Dec 2021 10:04:50 +0100 +Subject: s390/qeth: don't offer .ndo_bridge_* ops for OSA devices +Git-commit: cdf8df5b42e7d9e2f6e660e672d42edb0514b862 +Patch-mainline: v5.17-rc1 +References: jsc#PED-448 LTC#198619 + +qeth_l2_detect_dev2br_support() will only set brport_hw_features for IQD +devices. So qeth_l2_bridge_getlink() and qeth_l2_bridge_setlink() will +always return -EOPNOTSUPP on OSA devices. Just don't offer these +callbacks instead. + +Signed-off-by: Julian Wiedmann +Signed-off-by: Alexandra Winter +Signed-off-by: Jakub Kicinski +Acked-by: Petr Tesarik +--- + drivers/s390/net/qeth_l2_main.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/s390/net/qeth_l2_main.c ++++ b/drivers/s390/net/qeth_l2_main.c +@@ -1113,8 +1113,6 @@ static const struct net_device_ops qeth_ + .ndo_tx_timeout = qeth_tx_timeout, + .ndo_fix_features = qeth_fix_features, + .ndo_set_features = qeth_set_features, +- .ndo_bridge_getlink = qeth_l2_bridge_getlink, +- .ndo_bridge_setlink = qeth_l2_bridge_setlink, + }; + + static const struct net_device_ops qeth_l2_osa_netdev_ops = { diff --git a/patches.suse/s390-qeth-fine-tune-.ndo_select_queue b/patches.suse/s390-qeth-fine-tune-.ndo_select_queue new file mode 100644 index 0000000..5f2be74 --- /dev/null +++ b/patches.suse/s390-qeth-fine-tune-.ndo_select_queue @@ -0,0 +1,152 @@ +From: Julian Wiedmann +Date: Tue, 7 Dec 2021 10:04:51 +0100 +Subject: s390/qeth: fine-tune .ndo_select_queue() +Git-commit: 1b9e410f45bf68c068fa3422ca7b65ce4d08e5ed +Patch-mainline: v5.17-rc1 +References: jsc#PED-448 LTC#198619 + +Avoid a conditional branch for L2 devices when selecting the TX queue, +and have shared logic for OSA devices. + +Signed-off-by: Julian Wiedmann +Signed-off-by: Alexandra Winter +Signed-off-by: Jakub Kicinski +Acked-by: Petr Tesarik +--- + drivers/s390/net/qeth_core.h | 4 ++-- + drivers/s390/net/qeth_core_main.c | 15 +++++++++++++-- + drivers/s390/net/qeth_l2_main.c | 20 ++++++-------------- + drivers/s390/net/qeth_l3_main.c | 13 +------------ + 4 files changed, 22 insertions(+), 30 deletions(-) + +--- a/drivers/s390/net/qeth_core.h ++++ b/drivers/s390/net/qeth_core.h +@@ -1049,8 +1049,6 @@ static inline int qeth_send_simple_setas + data, QETH_PROT_IPV6); + } + +-int qeth_get_priority_queue(struct qeth_card *card, struct sk_buff *skb); +- + extern const struct qeth_discipline qeth_l2_discipline; + extern const struct qeth_discipline qeth_l3_discipline; + extern const struct ethtool_ops qeth_ethtool_ops; +@@ -1136,6 +1134,8 @@ void qeth_get_stats64(struct net_device + int qeth_set_real_num_tx_queues(struct qeth_card *card, unsigned int count); + u16 qeth_iqd_select_queue(struct net_device *dev, struct sk_buff *skb, + u8 cast_type, struct net_device *sb_dev); ++u16 qeth_osa_select_queue(struct net_device *dev, struct sk_buff *skb, ++ struct net_device *sb_dev); + int qeth_open(struct net_device *dev); + int qeth_stop(struct net_device *dev); + +--- a/drivers/s390/net/qeth_core_main.c ++++ b/drivers/s390/net/qeth_core_main.c +@@ -3794,7 +3794,7 @@ static void qeth_qdio_output_handler(str + /* + * Note: Function assumes that we have 4 outbound queues. + */ +-int qeth_get_priority_queue(struct qeth_card *card, struct sk_buff *skb) ++static int qeth_get_priority_queue(struct qeth_card *card, struct sk_buff *skb) + { + struct vlan_ethhdr *veth = vlan_eth_hdr(skb); + u8 tos; +@@ -3839,7 +3839,6 @@ int qeth_get_priority_queue(struct qeth_ + } + return card->qdio.default_out_queue; + } +-EXPORT_SYMBOL_GPL(qeth_get_priority_queue); + + /** + * qeth_get_elements_for_frags() - find number of SBALEs for skb frags. +@@ -7167,6 +7166,18 @@ u16 qeth_iqd_select_queue(struct net_dev + } + EXPORT_SYMBOL_GPL(qeth_iqd_select_queue); + ++u16 qeth_osa_select_queue(struct net_device *dev, struct sk_buff *skb, ++ struct net_device *sb_dev) ++{ ++ struct qeth_card *card = dev->ml_priv; ++ ++ if (qeth_uses_tx_prio_queueing(card)) ++ return qeth_get_priority_queue(card, skb); ++ ++ return netdev_pick_tx(dev, skb, sb_dev); ++} ++EXPORT_SYMBOL_GPL(qeth_osa_select_queue); ++ + int qeth_open(struct net_device *dev) + { + struct qeth_card *card = dev->ml_priv; +--- a/drivers/s390/net/qeth_l2_main.c ++++ b/drivers/s390/net/qeth_l2_main.c +@@ -562,19 +562,11 @@ static netdev_tx_t qeth_l2_hard_start_xm + return NETDEV_TX_OK; + } + +-static u16 qeth_l2_select_queue(struct net_device *dev, struct sk_buff *skb, +- struct net_device *sb_dev) ++static u16 qeth_l2_iqd_select_queue(struct net_device *dev, struct sk_buff *skb, ++ struct net_device *sb_dev) + { +- struct qeth_card *card = dev->ml_priv; +- +- if (IS_IQD(card)) +- return qeth_iqd_select_queue(dev, skb, +- qeth_get_ether_cast_type(skb), +- sb_dev); +- if (qeth_uses_tx_prio_queueing(card)) +- return qeth_get_priority_queue(card, skb); +- +- return netdev_pick_tx(dev, skb, sb_dev); ++ return qeth_iqd_select_queue(dev, skb, qeth_get_ether_cast_type(skb), ++ sb_dev); + } + + static void qeth_l2_set_rx_mode(struct net_device *dev) +@@ -1102,7 +1094,7 @@ static const struct net_device_ops qeth_ + .ndo_get_stats64 = qeth_get_stats64, + .ndo_start_xmit = qeth_l2_hard_start_xmit, + .ndo_features_check = qeth_features_check, +- .ndo_select_queue = qeth_l2_select_queue, ++ .ndo_select_queue = qeth_l2_iqd_select_queue, + .ndo_validate_addr = qeth_l2_validate_addr, + .ndo_set_rx_mode = qeth_l2_set_rx_mode, + .ndo_eth_ioctl = qeth_do_ioctl, +@@ -1121,7 +1113,7 @@ static const struct net_device_ops qeth_ + .ndo_get_stats64 = qeth_get_stats64, + .ndo_start_xmit = qeth_l2_hard_start_xmit, + .ndo_features_check = qeth_features_check, +- .ndo_select_queue = qeth_l2_select_queue, ++ .ndo_select_queue = qeth_osa_select_queue, + .ndo_validate_addr = qeth_l2_validate_addr, + .ndo_set_rx_mode = qeth_l2_set_rx_mode, + .ndo_eth_ioctl = qeth_do_ioctl, +--- a/drivers/s390/net/qeth_l3_main.c ++++ b/drivers/s390/net/qeth_l3_main.c +@@ -1822,17 +1822,6 @@ static u16 qeth_l3_iqd_select_queue(stru + qeth_l3_get_cast_type(skb, proto), sb_dev); + } + +-static u16 qeth_l3_osa_select_queue(struct net_device *dev, struct sk_buff *skb, +- struct net_device *sb_dev) +-{ +- struct qeth_card *card = dev->ml_priv; +- +- if (qeth_uses_tx_prio_queueing(card)) +- return qeth_get_priority_queue(card, skb); +- +- return netdev_pick_tx(dev, skb, sb_dev); +-} +- + static const struct net_device_ops qeth_l3_netdev_ops = { + .ndo_open = qeth_open, + .ndo_stop = qeth_stop, +@@ -1854,7 +1843,7 @@ static const struct net_device_ops qeth_ + .ndo_get_stats64 = qeth_get_stats64, + .ndo_start_xmit = qeth_l3_hard_start_xmit, + .ndo_features_check = qeth_l3_osa_features_check, +- .ndo_select_queue = qeth_l3_osa_select_queue, ++ .ndo_select_queue = qeth_osa_select_queue, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_rx_mode = qeth_l3_set_rx_mode, + .ndo_eth_ioctl = qeth_do_ioctl, diff --git a/patches.suse/s390-qeth-fix-kernel-doc-comments b/patches.suse/s390-qeth-fix-kernel-doc-comments new file mode 100644 index 0000000..a6702cc --- /dev/null +++ b/patches.suse/s390-qeth-fix-kernel-doc-comments @@ -0,0 +1,63 @@ +From: Heiko Carstens +Date: Mon, 25 Oct 2021 11:56:57 +0200 +Subject: s390/qeth: fix kernel doc comments +Git-commit: 7ffaef824c9a80950fba9f93ce4636a34148c5f0 +Patch-mainline: v5.16-rc1 +References: jsc#PED-448 LTC#198619 + +Fix kernel doc comments and remove incorrect kernel doc indicators. + +Acked-by: Julian Wiedmann +Signed-off-by: Heiko Carstens +Signed-off-by: Julian Wiedmann +Signed-off-by: David S. Miller +Acked-by: Petr Tesarik +--- + drivers/s390/net/qeth_core_main.c | 10 +++++----- + drivers/s390/net/qeth_l3_main.c | 2 +- + 2 files changed, 6 insertions(+), 6 deletions(-) + +--- a/drivers/s390/net/qeth_core_main.c ++++ b/drivers/s390/net/qeth_core_main.c +@@ -1945,9 +1945,9 @@ static struct qeth_cmd_buffer *qeth_mpc_ + * @card: qeth_card structure pointer + * @iob: qeth_cmd_buffer pointer + * @reply_cb: callback function pointer +- * @cb_card: pointer to the qeth_card structure +- * @cb_reply: pointer to the qeth_reply structure +- * @cb_cmd: pointer to the original iob for non-IPA ++ * cb_card: pointer to the qeth_card structure ++ * cb_reply: pointer to the qeth_reply structure ++ * cb_cmd: pointer to the original iob for non-IPA + * commands, or to the qeth_ipa_cmd structure + * for the IPA commands. + * @reply_param: private pointer passed to the callback +@@ -3059,7 +3059,7 @@ static int qeth_send_ipa_cmd_cb(struct q + return (cmd->hdr.return_code) ? -EIO : 0; + } + +-/** ++/* + * qeth_send_ipa_cmd() - send an IPA command + * + * See qeth_send_control_data() for explanation of the arguments. +@@ -3801,7 +3801,7 @@ static void qeth_qdio_output_handler(str + qeth_schedule_recovery(card); + } + +-/** ++/* + * Note: Function assumes that we have 4 outbound queues. + */ + int qeth_get_priority_queue(struct qeth_card *card, struct sk_buff *skb) +--- a/drivers/s390/net/qeth_l3_main.c ++++ b/drivers/s390/net/qeth_l3_main.c +@@ -492,7 +492,7 @@ int qeth_l3_setrouting_v6(struct qeth_ca + * IP address takeover related functions + */ + +-/** ++/* + * qeth_l3_update_ipato() - Update 'takeover' property, for all NORMAL IPs. + * + * Caller must hold ip_lock. diff --git a/patches.suse/s390-qeth-fix-various-format-strings b/patches.suse/s390-qeth-fix-various-format-strings new file mode 100644 index 0000000..1416854 --- /dev/null +++ b/patches.suse/s390-qeth-fix-various-format-strings @@ -0,0 +1,75 @@ +From: Heiko Carstens +Date: Mon, 25 Oct 2021 11:56:55 +0200 +Subject: s390/qeth: fix various format strings +Git-commit: 22e2b5cdb0b9b59d4df6da5ca9bc5773a4f8e3ea +Patch-mainline: v5.16-rc1 +References: jsc#PED-448 LTC#198619 + +Various format strings don't match with types of parameters. +Fix all of them. + +Acked-by: Julian Wiedmann +Signed-off-by: Heiko Carstens +Signed-off-by: Julian Wiedmann +Signed-off-by: David S. Miller +Acked-by: Petr Tesarik +--- + drivers/s390/net/qeth_l2_main.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +--- a/drivers/s390/net/qeth_l2_main.c ++++ b/drivers/s390/net/qeth_l2_main.c +@@ -704,13 +704,13 @@ static void qeth_l2_dev2br_fdb_notify(st + card->dev, &info.info, NULL); + QETH_CARD_TEXT(card, 4, "andelmac"); + QETH_CARD_TEXT_(card, 4, +- "mc%012lx", ether_addr_to_u64(ntfy_mac)); ++ "mc%012llx", ether_addr_to_u64(ntfy_mac)); + } else { + call_switchdev_notifiers(SWITCHDEV_FDB_ADD_TO_BRIDGE, + card->dev, &info.info, NULL); + QETH_CARD_TEXT(card, 4, "anaddmac"); + QETH_CARD_TEXT_(card, 4, +- "mc%012lx", ether_addr_to_u64(ntfy_mac)); ++ "mc%012llx", ether_addr_to_u64(ntfy_mac)); + } + } + +@@ -808,8 +808,8 @@ static void qeth_l2_br2dev_worker(struct + int err = 0; + + kfree(br2dev_event_work); +- QETH_CARD_TEXT_(card, 4, "b2dw%04x", event); +- QETH_CARD_TEXT_(card, 4, "ma%012lx", ether_addr_to_u64(addr)); ++ QETH_CARD_TEXT_(card, 4, "b2dw%04lx", event); ++ QETH_CARD_TEXT_(card, 4, "ma%012llx", ether_addr_to_u64(addr)); + + rcu_read_lock(); + /* Verify preconditions are still valid: */ +@@ -838,7 +838,7 @@ static void qeth_l2_br2dev_worker(struct + if (err) { + QETH_CARD_TEXT(card, 2, "b2derris"); + QETH_CARD_TEXT_(card, 2, +- "err%02x%03d", event, ++ "err%02lx%03d", event, + lowerdev->ifindex); + } + } +@@ -856,7 +856,7 @@ static void qeth_l2_br2dev_worker(struct + break; + } + if (err) +- QETH_CARD_TEXT_(card, 2, "b2derr%02x", event); ++ QETH_CARD_TEXT_(card, 2, "b2derr%02lx", event); + } + + unlock: +@@ -921,7 +921,7 @@ static int qeth_l2_switchdev_event(struc + while (lowerdev) { + if (qeth_l2_must_learn(lowerdev, dstdev)) { + card = lowerdev->ml_priv; +- QETH_CARD_TEXT_(card, 4, "b2dqw%03x", event); ++ QETH_CARD_TEXT_(card, 4, "b2dqw%03lx", event); + rc = qeth_l2_br2dev_queue_work(brdev, lowerdev, + dstdev, event, + fdb_info->addr); diff --git a/patches.suse/s390-qeth-improve-trace-entries-for-MAC-address-un-registration b/patches.suse/s390-qeth-improve-trace-entries-for-MAC-address-un-registration new file mode 100644 index 0000000..7fcd7d3 --- /dev/null +++ b/patches.suse/s390-qeth-improve-trace-entries-for-MAC-address-un-registration @@ -0,0 +1,47 @@ +From: Julian Wiedmann +Date: Mon, 25 Oct 2021 11:56:50 +0200 +Subject: s390/qeth: improve trace entries for MAC address (un)registration +Git-commit: 0969becb5f7661fb0db1a5d6b60f3d7f046ff6a7 +Patch-mainline: v5.16-rc1 +References: jsc#PED-448 LTC#198619 + +Add the failed MAC address into the trace message. Also fix up one +format string to use %x instead of %u for the CARD_DEVID. + +Signed-off-by: Julian Wiedmann +Reviewed-by: Alexandra Winter +Signed-off-by: David S. Miller +Acked-by: Petr Tesarik +--- + drivers/s390/net/qeth_l2_main.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/drivers/s390/net/qeth_l2_main.c ++++ b/drivers/s390/net/qeth_l2_main.c +@@ -121,11 +121,11 @@ static int qeth_l2_write_mac(struct qeth + QETH_CARD_TEXT(card, 2, "L2Wmac"); + rc = qeth_l2_send_setdelmac(card, mac, cmd); + if (rc == -EADDRINUSE) +- QETH_DBF_MESSAGE(2, "MAC already registered on device %x\n", +- CARD_DEVID(card)); ++ QETH_DBF_MESSAGE(2, "MAC address %012llx is already registered on device %x\n", ++ ether_addr_to_u64(mac), CARD_DEVID(card)); + else if (rc) +- QETH_DBF_MESSAGE(2, "Failed to register MAC on device %x: %d\n", +- CARD_DEVID(card), rc); ++ QETH_DBF_MESSAGE(2, "Failed to register MAC address %012llx on device %x: %d\n", ++ ether_addr_to_u64(mac), CARD_DEVID(card), rc); + return rc; + } + +@@ -138,8 +138,8 @@ static int qeth_l2_remove_mac(struct qet + QETH_CARD_TEXT(card, 2, "L2Rmac"); + rc = qeth_l2_send_setdelmac(card, mac, cmd); + if (rc) +- QETH_DBF_MESSAGE(2, "Failed to delete MAC on device %u: %d\n", +- CARD_DEVID(card), rc); ++ QETH_DBF_MESSAGE(2, "Failed to delete MAC address %012llx on device %x: %d\n", ++ ether_addr_to_u64(mac), CARD_DEVID(card), rc); + return rc; + } + diff --git a/patches.suse/s390-qeth-move-qdio-s-QAOB-cache-into-qeth b/patches.suse/s390-qeth-move-qdio-s-QAOB-cache-into-qeth new file mode 100644 index 0000000..f2d655c --- /dev/null +++ b/patches.suse/s390-qeth-move-qdio-s-QAOB-cache-into-qeth @@ -0,0 +1,163 @@ +From: Julian Wiedmann +Date: Mon, 25 Oct 2021 11:56:52 +0200 +Subject: s390/qeth: move qdio's QAOB cache into qeth +Git-commit: a18c28f0aeeb0f03c7176cd328c7b79e9f8e59e9 +Patch-mainline: v5.16-rc1 +References: jsc#PED-448 LTC#198619 + +qdio.ko no longer needs to care about how the QAOBs are allocated, +from its perspective they are merely another parameter to do_QDIO(). + +So for a start, shift the cache into the only qdio driver that uses +QAOBs (ie. qeth). Here there's further opportunity to optimize its +usage in the future - eg. make it per-{device, TX queue}, or only +compile it when the driver is built with CQ/QAOB support. + +Signed-off-by: Julian Wiedmann +Reviewed-by: Benjamin Block +Signed-off-by: David S. Miller +Acked-by: Petr Tesarik +--- + arch/s390/include/asm/qdio.h | 2 -- + drivers/s390/cio/qdio_setup.c | 34 ++-------------------------------- + drivers/s390/net/qeth_core_main.c | 19 +++++++++++++++++-- + 3 files changed, 19 insertions(+), 36 deletions(-) + +--- a/arch/s390/include/asm/qdio.h ++++ b/arch/s390/include/asm/qdio.h +@@ -349,8 +349,6 @@ extern int qdio_allocate(struct ccw_devi + extern int qdio_establish(struct ccw_device *cdev, + struct qdio_initialize *init_data); + extern int qdio_activate(struct ccw_device *); +-extern struct qaob *qdio_allocate_aob(void); +-extern void qdio_release_aob(struct qaob *); + extern int do_QDIO(struct ccw_device *cdev, unsigned int callflags, int q_nr, + unsigned int bufnr, unsigned int count, struct qaob *aob); + extern int qdio_start_irq(struct ccw_device *cdev); +--- a/drivers/s390/cio/qdio_setup.c ++++ b/drivers/s390/cio/qdio_setup.c +@@ -24,19 +24,6 @@ + #define QBUFF_PER_PAGE (PAGE_SIZE / sizeof(struct qdio_buffer)) + + static struct kmem_cache *qdio_q_cache; +-static struct kmem_cache *qdio_aob_cache; +- +-struct qaob *qdio_allocate_aob(void) +-{ +- return kmem_cache_zalloc(qdio_aob_cache, GFP_ATOMIC); +-} +-EXPORT_SYMBOL_GPL(qdio_allocate_aob); +- +-void qdio_release_aob(struct qaob *aob) +-{ +- kmem_cache_free(qdio_aob_cache, aob); +-} +-EXPORT_SYMBOL_GPL(qdio_release_aob); + + /** + * qdio_free_buffers() - free qdio buffers +@@ -447,39 +434,22 @@ void qdio_print_subchannel_info(struct q + + int __init qdio_setup_init(void) + { +- int rc; +- + qdio_q_cache = kmem_cache_create("qdio_q", sizeof(struct qdio_q), + 256, 0, NULL); + if (!qdio_q_cache) + return -ENOMEM; + +- qdio_aob_cache = kmem_cache_create("qdio_aob", +- sizeof(struct qaob), +- sizeof(struct qaob), +- 0, +- NULL); +- if (!qdio_aob_cache) { +- rc = -ENOMEM; +- goto free_qdio_q_cache; +- } +- + /* Check for OSA/FCP thin interrupts (bit 67). */ + DBF_EVENT("thinint:%1d", + (css_general_characteristics.aif_osa) ? 1 : 0); + + /* Check for QEBSM support in general (bit 58). */ + DBF_EVENT("cssQEBSM:%1d", css_general_characteristics.qebsm); +- rc = 0; +-out: +- return rc; +-free_qdio_q_cache: +- kmem_cache_destroy(qdio_q_cache); +- goto out; ++ ++ return 0; + } + + void qdio_setup_exit(void) + { +- kmem_cache_destroy(qdio_aob_cache); + kmem_cache_destroy(qdio_q_cache); + } +--- a/drivers/s390/net/qeth_core_main.c ++++ b/drivers/s390/net/qeth_core_main.c +@@ -60,6 +60,7 @@ EXPORT_SYMBOL_GPL(qeth_dbf); + struct kmem_cache *qeth_core_header_cache; + EXPORT_SYMBOL_GPL(qeth_core_header_cache); + static struct kmem_cache *qeth_qdio_outbuf_cache; ++static struct kmem_cache *qeth_qaob_cache; + + static struct device *qeth_core_root_dev; + static struct dentry *qeth_debugfs_root; +@@ -1357,7 +1358,7 @@ static void qeth_clear_output_buffer(str + static void qeth_free_out_buf(struct qeth_qdio_out_buffer *buf) + { + if (buf->aob) +- qdio_release_aob(buf->aob); ++ kmem_cache_free(qeth_qaob_cache, buf->aob); + kmem_cache_free(qeth_qdio_outbuf_cache, buf); + } + +@@ -3579,7 +3580,8 @@ static void qeth_flush_buffers(struct qe + !qeth_iqd_is_mcast_queue(card, queue) && + count == 1) { + if (!buf->aob) +- buf->aob = qdio_allocate_aob(); ++ buf->aob = kmem_cache_zalloc(qeth_qaob_cache, ++ GFP_ATOMIC); + if (buf->aob) { + struct qeth_qaob_priv1 *priv; + +@@ -7253,6 +7255,16 @@ static int __init qeth_core_init(void) + rc = -ENOMEM; + goto cqslab_err; + } ++ ++ qeth_qaob_cache = kmem_cache_create("qeth_qaob", ++ sizeof(struct qaob), ++ sizeof(struct qaob), ++ 0, NULL); ++ if (!qeth_qaob_cache) { ++ rc = -ENOMEM; ++ goto qaob_err; ++ } ++ + rc = ccw_driver_register(&qeth_ccw_driver); + if (rc) + goto ccw_err; +@@ -7265,6 +7277,8 @@ static int __init qeth_core_init(void) + ccwgroup_err: + ccw_driver_unregister(&qeth_ccw_driver); + ccw_err: ++ kmem_cache_destroy(qeth_qaob_cache); ++qaob_err: + kmem_cache_destroy(qeth_qdio_outbuf_cache); + cqslab_err: + kmem_cache_destroy(qeth_core_header_cache); +@@ -7283,6 +7297,7 @@ static void __exit qeth_core_exit(void) + qeth_clear_dbf_list(); + ccwgroup_driver_unregister(&qeth_core_ccwgroup_driver); + ccw_driver_unregister(&qeth_ccw_driver); ++ kmem_cache_destroy(qeth_qaob_cache); + kmem_cache_destroy(qeth_qdio_outbuf_cache); + kmem_cache_destroy(qeth_core_header_cache); + root_device_unregister(qeth_core_root_dev); diff --git a/patches.suse/s390-qeth-remove-.do_ioctl-callback-from-driver-discipline b/patches.suse/s390-qeth-remove-.do_ioctl-callback-from-driver-discipline new file mode 100644 index 0000000..de583c3 --- /dev/null +++ b/patches.suse/s390-qeth-remove-.do_ioctl-callback-from-driver-discipline @@ -0,0 +1,109 @@ +From: Julian Wiedmann +Date: Mon, 25 Oct 2021 11:56:51 +0200 +Subject: s390/qeth: remove .do_ioctl() callback from driver discipline +Git-commit: 2decb0b7ba2d1310d85a9fa12e8ed007b7dd6b45 +Patch-mainline: v5.16-rc1 +References: jsc#PED-448 LTC#198619 + +With commit 18787eeebd71 ("qeth: use ndo_siocdevprivate") this callback +is now actually used to handle transport mode-specific _private_ ioctls. + +We only have such ioctls for L3 devices. So wire up a L3-specific +.ndo_siocdevprivate() callback that handles those ioctls, and defers to +the core qeth_siocdevprivate() for all other private ioctls. + +This takes the discipline one step closer to its original purpose of +providing an internal extension for the qeth_core_ccwgroup_driver. + +Signed-off-by: Julian Wiedmann +Signed-off-by: David S. Miller +Acked-by: Petr Tesarik +--- + drivers/s390/net/qeth_core.h | 2 -- + drivers/s390/net/qeth_core_main.c | 5 +---- + drivers/s390/net/qeth_l2_main.c | 1 - + drivers/s390/net/qeth_l3_main.c | 10 +++++----- + 4 files changed, 6 insertions(+), 12 deletions(-) + +--- a/drivers/s390/net/qeth_core.h ++++ b/drivers/s390/net/qeth_core.h +@@ -789,8 +789,6 @@ struct qeth_discipline { + void (*remove) (struct ccwgroup_device *); + int (*set_online)(struct qeth_card *card, bool carrier_ok); + void (*set_offline)(struct qeth_card *card); +- int (*do_ioctl)(struct net_device *dev, struct ifreq *rq, +- void __user *data, int cmd); + int (*control_event_handler)(struct qeth_card *card, + struct qeth_ipa_cmd *cmd); + }; +--- a/drivers/s390/net/qeth_core_main.c ++++ b/drivers/s390/net/qeth_core_main.c +@@ -6679,10 +6679,7 @@ int qeth_siocdevprivate(struct net_devic + rc = qeth_query_oat_command(card, data); + break; + default: +- if (card->discipline->do_ioctl) +- rc = card->discipline->do_ioctl(dev, rq, data, cmd); +- else +- rc = -EOPNOTSUPP; ++ rc = -EOPNOTSUPP; + } + if (rc) + QETH_CARD_TEXT_(card, 2, "ioce%x", rc); +--- a/drivers/s390/net/qeth_l2_main.c ++++ b/drivers/s390/net/qeth_l2_main.c +@@ -2571,7 +2571,6 @@ const struct qeth_discipline qeth_l2_dis + .remove = qeth_l2_remove_device, + .set_online = qeth_l2_set_online, + .set_offline = qeth_l2_set_offline, +- .do_ioctl = NULL, + .control_event_handler = qeth_l2_control_event, + }; + EXPORT_SYMBOL_GPL(qeth_l2_discipline); +--- a/drivers/s390/net/qeth_l3_main.c ++++ b/drivers/s390/net/qeth_l3_main.c +@@ -1511,7 +1511,8 @@ static int qeth_l3_arp_flush_cache(struc + return rc; + } + +-static int qeth_l3_do_ioctl(struct net_device *dev, struct ifreq *rq, void __user *data, int cmd) ++static int qeth_l3_ndo_siocdevprivate(struct net_device *dev, struct ifreq *rq, ++ void __user *data, int cmd) + { + struct qeth_card *card = dev->ml_priv; + struct qeth_arp_cache_entry arp_entry; +@@ -1552,7 +1553,7 @@ static int qeth_l3_do_ioctl(struct net_d + rc = qeth_l3_arp_flush_cache(card); + break; + default: +- rc = -EOPNOTSUPP; ++ rc = qeth_siocdevprivate(dev, rq, data, cmd); + } + return rc; + } +@@ -1841,7 +1842,7 @@ static const struct net_device_ops qeth_ + .ndo_validate_addr = eth_validate_addr, + .ndo_set_rx_mode = qeth_l3_set_rx_mode, + .ndo_eth_ioctl = qeth_do_ioctl, +- .ndo_siocdevprivate = qeth_siocdevprivate, ++ .ndo_siocdevprivate = qeth_l3_ndo_siocdevprivate, + .ndo_fix_features = qeth_fix_features, + .ndo_set_features = qeth_set_features, + .ndo_tx_timeout = qeth_tx_timeout, +@@ -1857,7 +1858,7 @@ static const struct net_device_ops qeth_ + .ndo_validate_addr = eth_validate_addr, + .ndo_set_rx_mode = qeth_l3_set_rx_mode, + .ndo_eth_ioctl = qeth_do_ioctl, +- .ndo_siocdevprivate = qeth_siocdevprivate, ++ .ndo_siocdevprivate = qeth_l3_ndo_siocdevprivate, + .ndo_fix_features = qeth_fix_features, + .ndo_set_features = qeth_set_features, + .ndo_tx_timeout = qeth_tx_timeout, +@@ -2071,7 +2072,6 @@ const struct qeth_discipline qeth_l3_dis + .remove = qeth_l3_remove_device, + .set_online = qeth_l3_set_online, + .set_offline = qeth_l3_set_offline, +- .do_ioctl = qeth_l3_do_ioctl, + .control_event_handler = qeth_l3_control_event, + }; + EXPORT_SYMBOL_GPL(qeth_l3_discipline); diff --git a/patches.suse/s390-qeth-remove-OSN-deprecation-notice.patch b/patches.suse/s390-qeth-remove-OSN-deprecation-notice.patch new file mode 100644 index 0000000..9d6a542 --- /dev/null +++ b/patches.suse/s390-qeth-remove-OSN-deprecation-notice.patch @@ -0,0 +1,26 @@ +From: Petr Tesarik +Date: Fri, 14 Oct 2022 16:19:00 +0200 +Subject: s390/qeth: Remove OSN deprecation notice +Patch-mainline: never, upstream has already removed OSN support +References: jsc#PED-448 LTC#198619 + +The notice is confusing. It is 2022 already, and OSN is still supported +in SLE15 SP5, based on a discussion with IBM. + +Signed-off-by: Petr Tesarik +--- + drivers/s390/net/qeth_l2_main.c | 3 --- + 1 file changed, 3 deletions(-) + +--- a/drivers/s390/net/qeth_l2_main.c ++++ b/drivers/s390/net/qeth_l2_main.c +@@ -2429,9 +2429,6 @@ static int qeth_l2_probe_device(struct c + struct qeth_card *card = dev_get_drvdata(&gdev->dev); + int rc; + +- if (IS_OSN(card)) +- dev_notice(&gdev->dev, "OSN support will be dropped in 2021\n"); +- + qeth_l2_vnicc_set_defaults(card); + mutex_init(&card->sbp_lock); + diff --git a/patches.suse/s390-qeth-remove-check-for-packing-mode-in-qeth_check_outbound_queue b/patches.suse/s390-qeth-remove-check-for-packing-mode-in-qeth_check_outbound_queue new file mode 100644 index 0000000..71c9114 --- /dev/null +++ b/patches.suse/s390-qeth-remove-check-for-packing-mode-in-qeth_check_outbound_queue @@ -0,0 +1,48 @@ +From: Julian Wiedmann +Date: Tue, 7 Dec 2021 10:04:52 +0100 +Subject: s390/qeth: remove check for packing mode in + qeth_check_outbound_queue() +Git-commit: 6dc490e80ca33e4e49ed5b81df0ec9bfad6bf1b6 +Patch-mainline: v5.17-rc1 +References: jsc#PED-448 LTC#198619 + +If qeth_check_outbound_queue() finds a partially filled TX buffer on +the queue and flushes it, then the queue _must_ have been in packing +mode. + +Remove the redundant check when updating the relevant statistics. + +Signed-off-by: Julian Wiedmann +Reviewed-by: Alexandra Winter +Signed-off-by: Alexandra Winter +Signed-off-by: Jakub Kicinski +Acked-by: Petr Tesarik +--- + drivers/s390/net/qeth_core_main.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +--- a/drivers/s390/net/qeth_core_main.c ++++ b/drivers/s390/net/qeth_core_main.c +@@ -3660,12 +3660,10 @@ static void qeth_check_outbound_queue(st + if ((atomic_read(&queue->used_buffers) <= QETH_LOW_WATERMARK_PACK) || + !atomic_read(&queue->set_pci_flags_count)) { + unsigned int index, flush_cnt; +- bool q_was_packing; + + spin_lock(&queue->lock); + + index = queue->next_buf_to_fill; +- q_was_packing = queue->do_pack; + + flush_cnt = qeth_switch_to_nonpacking_if_needed(queue); + if (!flush_cnt && !atomic_read(&queue->set_pci_flags_count)) +@@ -3673,8 +3671,7 @@ static void qeth_check_outbound_queue(st + + if (flush_cnt) { + qeth_flush_buffers(queue, index, flush_cnt); +- if (q_was_packing) +- QETH_TXQ_STAT_ADD(queue, bufs_pack, flush_cnt); ++ QETH_TXQ_STAT_ADD(queue, bufs_pack, flush_cnt); + } + + spin_unlock(&queue->lock); diff --git a/patches.suse/s390-qeth-split-up-L2-netdev_ops b/patches.suse/s390-qeth-split-up-L2-netdev_ops new file mode 100644 index 0000000..7eb8d65 --- /dev/null +++ b/patches.suse/s390-qeth-split-up-L2-netdev_ops @@ -0,0 +1,82 @@ +From: Julian Wiedmann +Date: Tue, 7 Dec 2021 10:04:49 +0100 +Subject: s390/qeth: split up L2 netdev_ops +Git-commit: 2dbc7a1dde9e853b2a346fd811fec8cc45bce911 +Patch-mainline: v5.17-rc1 +References: jsc#PED-448 LTC#198619 + +Splitting up the netdev_ops allows for fine-tuning some of the ndo's +in subsequent patches. + +Signed-off-by: Julian Wiedmann +Reviewed-by: Wenjia Zhang +Signed-off-by: Alexandra Winter +Signed-off-by: Jakub Kicinski +Acked-by: Petr Tesarik +--- + drivers/s390/net/qeth_l2_main.c | 32 ++++++++++++++++++++++++++++---- + 1 file changed, 28 insertions(+), 4 deletions(-) + +--- a/drivers/s390/net/qeth_l2_main.c ++++ b/drivers/s390/net/qeth_l2_main.c +@@ -769,7 +769,8 @@ struct qeth_l2_br2dev_event_work { + unsigned char addr[ETH_ALEN]; + }; + +-static const struct net_device_ops qeth_l2_netdev_ops; ++static const struct net_device_ops qeth_l2_iqd_netdev_ops; ++static const struct net_device_ops qeth_l2_osa_netdev_ops; + + static bool qeth_l2_must_learn(struct net_device *netdev, + struct net_device *dstdev) +@@ -781,7 +782,8 @@ static bool qeth_l2_must_learn(struct ne + (priv->brport_features & BR_LEARNING_SYNC) && + !(br_port_flag_is_set(netdev, BR_ISOLATED) && + br_port_flag_is_set(dstdev, BR_ISOLATED)) && +- netdev->netdev_ops == &qeth_l2_netdev_ops); ++ (netdev->netdev_ops == &qeth_l2_iqd_netdev_ops || ++ netdev->netdev_ops == &qeth_l2_osa_netdev_ops)); + } + + /** +@@ -1094,7 +1096,28 @@ static int qeth_l2_bridge_setlink(struct + return rc; + } + +-static const struct net_device_ops qeth_l2_netdev_ops = { ++static const struct net_device_ops qeth_l2_iqd_netdev_ops = { ++ .ndo_open = qeth_open, ++ .ndo_stop = qeth_stop, ++ .ndo_get_stats64 = qeth_get_stats64, ++ .ndo_start_xmit = qeth_l2_hard_start_xmit, ++ .ndo_features_check = qeth_features_check, ++ .ndo_select_queue = qeth_l2_select_queue, ++ .ndo_validate_addr = qeth_l2_validate_addr, ++ .ndo_set_rx_mode = qeth_l2_set_rx_mode, ++ .ndo_eth_ioctl = qeth_do_ioctl, ++ .ndo_siocdevprivate = qeth_siocdevprivate, ++ .ndo_set_mac_address = qeth_l2_set_mac_address, ++ .ndo_vlan_rx_add_vid = qeth_l2_vlan_rx_add_vid, ++ .ndo_vlan_rx_kill_vid = qeth_l2_vlan_rx_kill_vid, ++ .ndo_tx_timeout = qeth_tx_timeout, ++ .ndo_fix_features = qeth_fix_features, ++ .ndo_set_features = qeth_set_features, ++ .ndo_bridge_getlink = qeth_l2_bridge_getlink, ++ .ndo_bridge_setlink = qeth_l2_bridge_setlink, ++}; ++ ++static const struct net_device_ops qeth_l2_osa_netdev_ops = { + .ndo_open = qeth_open, + .ndo_stop = qeth_stop, + .ndo_get_stats64 = qeth_get_stats64, +@@ -1132,8 +1155,9 @@ static int qeth_l2_setup_netdev(struct q + goto add_napi; + } + ++ card->dev->netdev_ops = IS_IQD(card) ? &qeth_l2_iqd_netdev_ops : ++ &qeth_l2_osa_netdev_ops; + card->dev->needed_headroom = sizeof(struct qeth_hdr); +- card->dev->netdev_ops = &qeth_l2_netdev_ops; + card->dev->priv_flags |= IFF_UNICAST_FLT; + + if (IS_OSM(card)) { diff --git a/patches.suse/s390-qeth-update-kerneldoc-for-qeth_add_hw_header b/patches.suse/s390-qeth-update-kerneldoc-for-qeth_add_hw_header new file mode 100644 index 0000000..0927a46 --- /dev/null +++ b/patches.suse/s390-qeth-update-kerneldoc-for-qeth_add_hw_header @@ -0,0 +1,35 @@ +From: Julian Wiedmann +Date: Mon, 25 Oct 2021 11:56:58 +0200 +Subject: s390/qeth: update kerneldoc for qeth_add_hw_header() +Git-commit: 56c5af2566a7f012e689002032f2356267a08eb3 +Patch-mainline: v5.16-rc1 +References: jsc#PED-448 LTC#198619 + +qeth_add_hw_header() is missing documentation for some of its +parameters, fix that up. + +Reported-by: Heiko Carstens +Signed-off-by: Julian Wiedmann +Signed-off-by: David S. Miller +Acked-by: Petr Tesarik +--- + drivers/s390/net/qeth_core_main.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/s390/net/qeth_core_main.c ++++ b/drivers/s390/net/qeth_core_main.c +@@ -3898,12 +3898,14 @@ EXPORT_SYMBOL_GPL(qeth_count_elements); + + /** + * qeth_add_hw_header() - add a HW header to an skb. ++ * @queue: TX queue that the skb will be placed on. + * @skb: skb that the HW header should be added to. + * @hdr: double pointer to a qeth_hdr. When returning with >= 0, + * it contains a valid pointer to a qeth_hdr. + * @hdr_len: length of the HW header. + * @proto_len: length of protocol headers that need to be in same page as the + * HW header. ++ * @elements: returns the required number of buffer elements for this skb. + * + * Returns the pushed length. If the header can't be pushed on + * (eg. because it would cross a page boundary), it is allocated from diff --git a/patches.suse/s390-smp-enforce-lowcore-protection-on-CPU-restart b/patches.suse/s390-smp-enforce-lowcore-protection-on-CPU-restart new file mode 100644 index 0000000..7503f96 --- /dev/null +++ b/patches.suse/s390-smp-enforce-lowcore-protection-on-CPU-restart @@ -0,0 +1,35 @@ +From: Alexander Gordeev +Date: Wed, 20 Jul 2022 07:24:03 +0200 +Subject: s390/smp: enforce lowcore protection on CPU restart +Git-commit: 8d96bba75a43ba564bf8732e955d9f519d2bbaec +Patch-mainline: v6.0-rc5 +References: git-fixes + +As result of commit 915fea04f932 ("s390/smp: enable DAT before +CPU restart callback is called") the low-address protection bit +gets mistakenly unset in control register 0 save area of the +absolute zero memory. That area is used when manual PSW restart +happened to hit an offline CPU. In this case the low-address +protection for that CPU will be dropped. + +Reviewed-by: Heiko Carstens +Fixes: 915fea04f932 ("s390/smp: enable DAT before CPU restart callback is called") +Signed-off-by: Alexander Gordeev +Signed-off-by: Vasily Gorbik +Acked-by: Petr Tesarik +--- + arch/s390/kernel/setup.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/s390/kernel/setup.c ++++ b/arch/s390/kernel/setup.c +@@ -462,8 +462,8 @@ static void __init setup_lowcore_dat_on( + S390_lowcore.svc_new_psw.mask |= PSW_MASK_DAT; + S390_lowcore.program_new_psw.mask |= PSW_MASK_DAT; + S390_lowcore.io_new_psw.mask |= PSW_MASK_DAT; +- __ctl_store(S390_lowcore.cregs_save_area, 0, 15); + __ctl_set_bit(0, 28); ++ __ctl_store(S390_lowcore.cregs_save_area, 0, 15); + mem_assign_absolute(S390_lowcore.restart_flags, RESTART_FLAG_CTLREGS); + mem_assign_absolute(S390_lowcore.program_new_psw, lc->program_new_psw); + memcpy_absolute(&S390_lowcore.cregs_save_area, lc->cregs_save_area, diff --git a/patches.suse/sbitmap-Avoid-leaving-waitqueue-in-invalid-state-in-.patch b/patches.suse/sbitmap-Avoid-leaving-waitqueue-in-invalid-state-in-.patch new file mode 100644 index 0000000..1d7d66f --- /dev/null +++ b/patches.suse/sbitmap-Avoid-leaving-waitqueue-in-invalid-state-in-.patch @@ -0,0 +1,77 @@ +From 48c033314f372478548203c583529f53080fd078 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 8 Sep 2022 15:09:37 +0200 +Subject: [PATCH] sbitmap: Avoid leaving waitqueue in invalid state in __sbq_wake_up() +Git-commit: 48c033314f372478548203c583529f53080fd078 +Patch-mainline: v6.1-rc1 +References: git-fixes + +When __sbq_wake_up() decrements wait_cnt to 0 but races with someone +else waking the waiter on the waitqueue (so the waitqueue becomes +empty), it exits without reseting wait_cnt to wake_batch number. Once +wait_cnt is 0, nobody will ever reset the wait_cnt or wake the new +waiters resulting in possible deadlocks or busyloops. Fix the problem by +making sure we reset wait_cnt even if we didn't wake up anybody in the +end. + +Fixes: 040b83fcecfb ("sbitmap: fix possible io hung due to lost wakeup") +Reported-by: Keith Busch +Signed-off-by: Jan Kara +Link: https://lore.kernel.org/r/20220908130937.2795-1-jack@suse.cz +Signed-off-by: Jens Axboe +Acked-by: Takashi Iwai + +--- + lib/sbitmap.c | 18 +++++++++++++++--- + 1 file changed, 15 insertions(+), 3 deletions(-) + +diff --git a/lib/sbitmap.c b/lib/sbitmap.c +index a39b1a877366..47cd8fb894ba 100644 +--- a/lib/sbitmap.c ++++ b/lib/sbitmap.c +@@ -604,6 +604,7 @@ static bool __sbq_wake_up(struct sbitmap_queue *sbq) + struct sbq_wait_state *ws; + unsigned int wake_batch; + int wait_cnt; ++ bool ret; + + ws = sbq_wake_ptr(sbq); + if (!ws) +@@ -614,12 +615,23 @@ static bool __sbq_wake_up(struct sbitmap_queue *sbq) + * For concurrent callers of this, callers should call this function + * again to wakeup a new batch on a different 'ws'. + */ +- if (wait_cnt < 0 || !waitqueue_active(&ws->wait)) ++ if (wait_cnt < 0) + return true; + ++ /* ++ * If we decremented queue without waiters, retry to avoid lost ++ * wakeups. ++ */ + if (wait_cnt > 0) +- return false; ++ return !waitqueue_active(&ws->wait); + ++ /* ++ * When wait_cnt == 0, we have to be particularly careful as we are ++ * responsible to reset wait_cnt regardless whether we've actually ++ * woken up anybody. But in case we didn't wakeup anybody, we still ++ * need to retry. ++ */ ++ ret = !waitqueue_active(&ws->wait); + wake_batch = READ_ONCE(sbq->wake_batch); + + /* +@@ -648,7 +660,7 @@ static bool __sbq_wake_up(struct sbitmap_queue *sbq) + sbq_index_atomic_inc(&sbq->wake_index); + atomic_set(&ws->wait_cnt, wake_batch); + +- return false; ++ return ret; + } + + void sbitmap_queue_wake_up(struct sbitmap_queue *sbq) +-- +2.35.3 + diff --git a/patches.suse/sbitmap-fix-possible-io-hung-due-to-lost-wakeup.patch b/patches.suse/sbitmap-fix-possible-io-hung-due-to-lost-wakeup.patch new file mode 100644 index 0000000..9ff6678 --- /dev/null +++ b/patches.suse/sbitmap-fix-possible-io-hung-due-to-lost-wakeup.patch @@ -0,0 +1,141 @@ +From 040b83fcecfb86f3225d3a5de7fd9b3fbccf83b4 Mon Sep 17 00:00:00 2001 +From: Yu Kuai +Date: Wed, 3 Aug 2022 20:15:04 +0800 +Subject: [PATCH] sbitmap: fix possible io hung due to lost wakeup +Git-commit: 040b83fcecfb86f3225d3a5de7fd9b3fbccf83b4 +Patch-mainline: v6.1-rc1 +References: git-fixes + +There are two problems can lead to lost wakeup: + +1) invalid wakeup on the wrong waitqueue: + +For example, 2 * wake_batch tags are put, while only wake_batch threads +are woken: + +__sbq_wake_up + atomic_cmpxchg -> reset wait_cnt + __sbq_wake_up -> decrease wait_cnt + ... + __sbq_wake_up -> wait_cnt is decreased to 0 again + atomic_cmpxchg + sbq_index_atomic_inc -> increase wake_index + wake_up_nr -> wake up and waitqueue might be empty + sbq_index_atomic_inc -> increase again, one waitqueue is skipped + wake_up_nr -> invalid wake up because old wakequeue might be empty + +To fix the problem, increasing 'wake_index' before resetting 'wait_cnt'. + +2) 'wait_cnt' can be decreased while waitqueue is empty + +As pointed out by Jan Kara, following race is possible: + +CPU1 CPU2 +__sbq_wake_up __sbq_wake_up + sbq_wake_ptr() sbq_wake_ptr() -> the same + wait_cnt = atomic_dec_return() + /* decreased to 0 */ + sbq_index_atomic_inc() + /* move to next waitqueue */ + atomic_set() + /* reset wait_cnt */ + wake_up_nr() + /* wake up on the old waitqueue */ + wait_cnt = atomic_dec_return() + /* + * decrease wait_cnt in the old + * waitqueue, while it can be + * empty. + */ + +Fix the problem by waking up before updating 'wake_index' and +'wait_cnt'. + +With this patch, noted that 'wait_cnt' is still decreased in the old +empty waitqueue, however, the wakeup is redirected to a active waitqueue, +and the extra decrement on the old empty waitqueue is not handled. + +Fixes: 88459642cba4 ("blk-mq: abstract tag allocation out into sbitmap library") +Signed-off-by: Yu Kuai +Reviewed-by: Jan Kara +Link: https://lore.kernel.org/r/20220803121504.212071-1-yukuai1@huaweicloud.com +Signed-off-by: Jens Axboe +Acked-by: Takashi Iwai + +--- + lib/sbitmap.c | 55 ++++++++++++++++++++++++++++++--------------------- + 1 file changed, 33 insertions(+), 22 deletions(-) + +diff --git a/lib/sbitmap.c b/lib/sbitmap.c +index 29eb0484215a..1f31147872e6 100644 +--- a/lib/sbitmap.c ++++ b/lib/sbitmap.c +@@ -611,32 +611,43 @@ static bool __sbq_wake_up(struct sbitmap_queue *sbq) + return false; + + wait_cnt = atomic_dec_return(&ws->wait_cnt); +- if (wait_cnt <= 0) { +- int ret; ++ /* ++ * For concurrent callers of this, callers should call this function ++ * again to wakeup a new batch on a different 'ws'. ++ */ ++ if (wait_cnt < 0 || !waitqueue_active(&ws->wait)) ++ return true; + +- wake_batch = READ_ONCE(sbq->wake_batch); ++ if (wait_cnt > 0) ++ return false; + +- /* +- * Pairs with the memory barrier in sbitmap_queue_resize() to +- * ensure that we see the batch size update before the wait +- * count is reset. +- */ +- smp_mb__before_atomic(); ++ wake_batch = READ_ONCE(sbq->wake_batch); + +- /* +- * For concurrent callers of this, the one that failed the +- * atomic_cmpxhcg() race should call this function again +- * to wakeup a new batch on a different 'ws'. +- */ +- ret = atomic_cmpxchg(&ws->wait_cnt, wait_cnt, wake_batch); +- if (ret == wait_cnt) { +- sbq_index_atomic_inc(&sbq->wake_index); +- wake_up_nr(&ws->wait, wake_batch); +- return false; +- } ++ /* ++ * Wake up first in case that concurrent callers decrease wait_cnt ++ * while waitqueue is empty. ++ */ ++ wake_up_nr(&ws->wait, wake_batch); + +- return true; +- } ++ /* ++ * Pairs with the memory barrier in sbitmap_queue_resize() to ++ * ensure that we see the batch size update before the wait ++ * count is reset. ++ * ++ * Also pairs with the implicit barrier between decrementing wait_cnt ++ * and checking for waitqueue_active() to make sure waitqueue_active() ++ * sees result of the wakeup if atomic_dec_return() has seen the result ++ * of atomic_set(). ++ */ ++ smp_mb__before_atomic(); ++ ++ /* ++ * Increase wake_index before updating wait_cnt, otherwise concurrent ++ * callers can see valid wait_cnt in old waitqueue, which can cause ++ * invalid wakeup on the old waitqueue. ++ */ ++ sbq_index_atomic_inc(&sbq->wake_index); ++ atomic_set(&ws->wait_cnt, wake_batch); + + return false; + } +-- +2.35.3 + diff --git a/patches.suse/scsi-Revert-scsi-qla2xxx-Fix-disk-failure-to-rediscover.patch b/patches.suse/scsi-Revert-scsi-qla2xxx-Fix-disk-failure-to-rediscover.patch new file mode 100644 index 0000000..01eefe8 --- /dev/null +++ b/patches.suse/scsi-Revert-scsi-qla2xxx-Fix-disk-failure-to-rediscover.patch @@ -0,0 +1,70 @@ +From: Nilesh Javali +Date: Tue, 12 Jul 2022 22:20:36 -0700 +Subject: scsi: Revert "scsi: qla2xxx: Fix disk failure to rediscover" +Git-commit: 5bc7b01c513a4a9b4cfe306e8d1720cfcfd3b8a3 +Patch-mainline: v6.0-rc1 +References: git-fixes + +This fixes the regression of NVMe discovery failure during driver load +time. + +This reverts commit 6a45c8e137d4e2c72eecf1ac7cf64f2fdfcead99. + +Link: https://lore.kernel.org/r/20220713052045.10683-2-njavali@marvell.com +Cc: stable@vger.kernel.org +Reviewed-by: Himanshu Madhani +Signed-off-by: Nilesh Javali +Signed-off-by: Martin K. Petersen +Acked-by: Lee Duncan +--- + drivers/scsi/qla2xxx/qla_init.c | 5 ++--- + drivers/scsi/qla2xxx/qla_nvme.c | 5 ----- + 2 files changed, 2 insertions(+), 8 deletions(-) + +diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c +index 41ffad65d29e..e9bc93395e2f 100644 +--- a/drivers/scsi/qla2xxx/qla_init.c ++++ b/drivers/scsi/qla2xxx/qla_init.c +@@ -5789,8 +5789,6 @@ qla2x00_reg_remote_port(scsi_qla_host_t *vha, fc_port_t *fcport) + if (atomic_read(&fcport->state) == FCS_ONLINE) + return; + +- qla2x00_set_fcport_state(fcport, FCS_ONLINE); +- + rport_ids.node_name = wwn_to_u64(fcport->node_name); + rport_ids.port_name = wwn_to_u64(fcport->port_name); + rport_ids.port_id = fcport->d_id.b.domain << 16 | +@@ -5891,7 +5889,6 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport) + qla2x00_reg_remote_port(vha, fcport); + break; + case MODE_TARGET: +- qla2x00_set_fcport_state(fcport, FCS_ONLINE); + if (!vha->vha_tgt.qla_tgt->tgt_stop && + !vha->vha_tgt.qla_tgt->tgt_stopped) + qlt_fc_port_added(vha, fcport); +@@ -5909,6 +5906,8 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport) + if (NVME_TARGET(vha->hw, fcport)) + qla_nvme_register_remote(vha, fcport); + ++ qla2x00_set_fcport_state(fcport, FCS_ONLINE); ++ + if (IS_IIDMA_CAPABLE(vha->hw) && vha->hw->flags.gpsc_supported) { + if (fcport->id_changed) { + fcport->id_changed = 0; +diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c +index 87c9404aa401..7450c3458be7 100644 +--- a/drivers/scsi/qla2xxx/qla_nvme.c ++++ b/drivers/scsi/qla2xxx/qla_nvme.c +@@ -37,11 +37,6 @@ int qla_nvme_register_remote(struct scsi_qla_host *vha, struct fc_port *fcport) + (fcport->nvme_flag & NVME_FLAG_REGISTERED)) + return 0; + +- if (atomic_read(&fcport->state) == FCS_ONLINE) +- return 0; +- +- qla2x00_set_fcport_state(fcport, FCS_ONLINE); +- + fcport->nvme_flag &= ~NVME_FLAG_RESETTING; + + memset(&req, 0, sizeof(struct nvme_fc_port_info)); + diff --git a/patches.suse/scsi-core-Add-BLIST_NO_ASK_VPD_SIZE-for-some-VDASD.patch b/patches.suse/scsi-core-Add-BLIST_NO_ASK_VPD_SIZE-for-some-VDASD.patch new file mode 100644 index 0000000..0061598 --- /dev/null +++ b/patches.suse/scsi-core-Add-BLIST_NO_ASK_VPD_SIZE-for-some-VDASD.patch @@ -0,0 +1,146 @@ +From cc747b68f5a124cd641b449e2cf6e7aebb686c9b Mon Sep 17 00:00:00 2001 +From: Lee Duncan +Date: Wed, 28 Sep 2022 09:19:16 -0700 +Subject: [PATCH] scsi: core: Add BLIST_NO_ASK_VPD_SIZE for some VDASD +References: bsc#1203039 +Patch-mainline: submitted https://www.spinics.net/lists/linux-scsi/msg177618.html + +Some storage, such as AIX VDASD (virtual storage) and IBM 2076 +(front end) do not like the recent commit: + +commit c92a6b5d6335 ("scsi: core: Query VPD size before getting full page") + +That commit changed getting SCSI VPD pages so that we now read +just enough of the page to get the actual page size, then read +the whole page in a second read. The problem is that the above +mentioned hardware returns zero for the page size, because of +a firmware error. In such cases, until the firmware is fixed, +this new black flag says to revert to the original method of +reading the VPD pages, i.e. try to read as a whole buffer's +worth on the first try. + +[lduncan: refreshed to apply. Will need kABI mitigation.] + +Fixes: c92a6b5d6335 ("scsi: core: Query VPD size before getting full page") +Reported-by: Martin Wilck +Suggested-by: Hannes Reinecke +Signed-off-by: Lee Duncan +--- + drivers/scsi/scsi.c | 14 +++++++++++--- + drivers/scsi/scsi_devinfo.c | 3 ++- + drivers/scsi/scsi_scan.c | 3 +++ + include/scsi/scsi_device.h | 2 ++ + include/scsi/scsi_devinfo.h | 4 ++-- + 5 files changed, 20 insertions(+), 6 deletions(-) + +--- a/drivers/scsi/scsi.c ++++ b/drivers/scsi/scsi.c +@@ -330,12 +330,20 @@ static int scsi_vpd_inquiry(struct scsi_ + return get_unaligned_be16(&buffer[2]) + 4; + } + +-static int scsi_get_vpd_size(struct scsi_device *sdev, u8 page) ++static int scsi_get_vpd_size(struct scsi_device *sdev, u8 page, int buf_len) + { + unsigned char vpd_header[SCSI_VPD_HEADER_SIZE] __aligned(4); + int result; + + /* ++ * if this hardware is blacklisted then don't bother asking ++ * the page size, since it will repy with zero -- just assume it ++ * is the buffer size ++ */ ++ if (sdev->no_ask_vpd_sz_first) ++ return buf_len; ++ ++ /* + * Fetch the VPD page header to find out how big the page + * is. This is done to prevent problems on legacy devices + * which can not handle allocation lengths as large as +@@ -376,7 +384,7 @@ int scsi_get_vpd_page(struct scsi_device + if (!scsi_device_supports_vpd(sdev)) + return -EINVAL; + +- vpd_len = scsi_get_vpd_size(sdev, page); ++ vpd_len = scsi_get_vpd_size(sdev, page, buf_len); + if (vpd_len <= 0) + return -EINVAL; + +@@ -411,7 +419,7 @@ static struct scsi_vpd *scsi_get_vpd_buf + struct scsi_vpd *vpd_buf; + int vpd_len, result; + +- vpd_len = scsi_get_vpd_size(sdev, page); ++ vpd_len = scsi_get_vpd_size(sdev, page, SCSI_VPD_PG_LEN); + if (vpd_len <= 0) + return NULL; + +--- a/drivers/scsi/scsi_devinfo.c ++++ b/drivers/scsi/scsi_devinfo.c +@@ -134,7 +134,7 @@ static struct { + {"3PARdata", "VV", NULL, BLIST_REPORTLUN2}, + {"ADAPTEC", "AACRAID", NULL, BLIST_FORCELUN}, + {"ADAPTEC", "Adaptec 5400S", NULL, BLIST_FORCELUN}, +- {"AIX", "VDASD", NULL, BLIST_TRY_VPD_PAGES}, ++ {"AIX", "VDASD", NULL, BLIST_TRY_VPD_PAGES | BLIST_NO_ASK_VPD_SIZE}, + {"AFT PRO", "-IX CF", "0.0>", BLIST_FORCELUN}, + {"BELKIN", "USB 2 HS-CF", "1.95", BLIST_FORCELUN | BLIST_INQUIRY_36}, + {"BROWNIE", "1200U3P", NULL, BLIST_NOREPORTLUN}, +@@ -187,6 +187,7 @@ static struct { + {"HPE", "OPEN-", "*", BLIST_REPORTLUN2 | BLIST_TRY_VPD_PAGES}, + {"IBM", "AuSaV1S2", NULL, BLIST_FORCELUN}, + {"IBM", "ProFibre 4000R", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, ++ {"IBM", "2076", NULL, BLIST_NO_ASK_VPD_SIZE}, + {"IBM", "2105", NULL, BLIST_RETRY_HWERROR}, + {"iomega", "jaz 1GB", "J.86", BLIST_NOTQ | BLIST_NOLUN}, + {"IOMEGA", "ZIP", NULL, BLIST_NOTQ | BLIST_NOLUN}, +--- a/drivers/scsi/scsi_scan.c ++++ b/drivers/scsi/scsi_scan.c +@@ -981,6 +981,9 @@ static int scsi_add_lun(struct scsi_devi + else if (*bflags & BLIST_SKIP_VPD_PAGES) + sdev->skip_vpd_pages = 1; + ++ if (*bflags & BLIST_NO_ASK_VPD_SIZE) ++ sdev->no_ask_vpd_sz_first = 1; ++ + transport_configure_device(&sdev->sdev_gendev); + + if (sdev->host->hostt->slave_configure) { +--- a/include/scsi/scsi_device.h ++++ b/include/scsi/scsi_device.h +@@ -144,6 +144,7 @@ struct scsi_device { + const char * model; /* ... after scan; point to static string */ + const char * rev; /* ... "nullnullnullnull" before scan */ + ++#define SCSI_VPD_PG_LEN 255 /* default SCSI VPD page size (max) */ + struct scsi_vpd __rcu *vpd_pg0; + struct scsi_vpd __rcu *vpd_pg83; + struct scsi_vpd __rcu *vpd_pg80; +@@ -209,6 +210,7 @@ struct scsi_device { + unsigned rpm_autosuspend:1; /* Enable runtime autosuspend at device + * creation time */ + unsigned silence_suspend:1; /* Do not print runtime PM related messages */ ++ unsigned no_ask_vpd_sz_first:1; /* Do not ask for VPD size first */ + + unsigned int queue_stopped; /* request queue is quiesced */ + bool offline_already; /* Device offline message logged */ +--- a/include/scsi/scsi_devinfo.h ++++ b/include/scsi/scsi_devinfo.h +@@ -31,7 +31,8 @@ + #define __BLIST_UNUSED_11 ((__force blist_flags_t)(1ULL << 11)) + /* do not do automatic start on add */ + #define BLIST_NOSTARTONADD ((__force blist_flags_t)(1ULL << 12)) +-#define __BLIST_UNUSED_13 ((__force blist_flags_t)(1ULL << 13)) ++/* do not ask for VPD page size first on some broken targets */ ++#define BLIST_NO_ASK_VPD_SIZE ((__force blist_flags_t)(1ULL << 13)) + #define __BLIST_UNUSED_14 ((__force blist_flags_t)(1ULL << 14)) + #define __BLIST_UNUSED_15 ((__force blist_flags_t)(1ULL << 15)) + #define __BLIST_UNUSED_16 ((__force blist_flags_t)(1ULL << 16)) +@@ -74,7 +75,6 @@ + (__force blist_flags_t) \ + ((__force __u64)__BLIST_LAST_USED - 1ULL))) + #define __BLIST_UNUSED_MASK (__BLIST_UNUSED_11 | \ +- __BLIST_UNUSED_13 | \ + __BLIST_UNUSED_14 | \ + __BLIST_UNUSED_15 | \ + __BLIST_UNUSED_16 | \ diff --git a/patches.suse/scsi-lpfc-Add-missing-destroy_workqueue-in-error-pat.patch b/patches.suse/scsi-lpfc-Add-missing-destroy_workqueue-in-error-pat.patch new file mode 100644 index 0000000..09811e1 --- /dev/null +++ b/patches.suse/scsi-lpfc-Add-missing-destroy_workqueue-in-error-pat.patch @@ -0,0 +1,41 @@ +From: Yang Yingliang +Date: Tue, 23 Aug 2022 12:42:37 +0800 +Subject: scsi: lpfc: Add missing destroy_workqueue() in error path +Patch-mainline: v6.0-rc5 +Git-commit: da6d507f5ff328f346b3c50e19e19993027b8ffd +References: bsc#1203939 + +Add the missing destroy_workqueue() before return from +lpfc_sli4_driver_resource_setup() in the error path. + +Link: https://lore.kernel.org/r/20220823044237.285643-1-yangyingliang@huawei.com +Fixes: 3cee98db2610 ("scsi: lpfc: Fix crash on driver unload in wq free") +Reviewed-by: James Smart +Signed-off-by: Yang Yingliang +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/lpfc/lpfc_init.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/scsi/lpfc/lpfc_init.c ++++ b/drivers/scsi/lpfc/lpfc_init.c +@@ -8052,7 +8052,7 @@ lpfc_sli4_driver_resource_setup(struct l + /* Allocate device driver memory */ + rc = lpfc_mem_alloc(phba, SGL_ALIGN_SZ); + if (rc) +- return -ENOMEM; ++ goto out_destroy_workqueue; + + /* IF Type 2 ports get initialized now. */ + if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) >= +@@ -8480,6 +8480,9 @@ lpfc_sli4_driver_resource_setup(struct l + lpfc_destroy_bootstrap_mbox(phba); + out_free_mem: + lpfc_mem_free(phba); ++out_destroy_workqueue: ++ destroy_workqueue(phba->wq); ++ phba->wq = NULL; + return rc; + } + diff --git a/patches.suse/scsi-lpfc-Add-warning-notification-period-to-CMF_SYN.patch b/patches.suse/scsi-lpfc-Add-warning-notification-period-to-CMF_SYN.patch index 3165266..19e6f63 100644 --- a/patches.suse/scsi-lpfc-Add-warning-notification-period-to-CMF_SYN.patch +++ b/patches.suse/scsi-lpfc-Add-warning-notification-period-to-CMF_SYN.patch @@ -1,8 +1,7 @@ From: James Smart Date: Thu, 18 Aug 2022 18:17:33 -0700 Subject: scsi: lpfc: Add warning notification period to CMF_SYNC_WQE -Patch-mainline: Queued in subsystem maintainer repository -Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git +Patch-mainline: v6.1-rc1 Git-commit: 71ddeeaf5bd5122713ca64601ef19ee2dba04e30 References: bsc#1203063 diff --git a/patches.suse/scsi-lpfc-Copyright-updates-for-14.2.0.6-patches.patch b/patches.suse/scsi-lpfc-Copyright-updates-for-14.2.0.6-patches.patch index 3cd282e..3be8561 100644 --- a/patches.suse/scsi-lpfc-Copyright-updates-for-14.2.0.6-patches.patch +++ b/patches.suse/scsi-lpfc-Copyright-updates-for-14.2.0.6-patches.patch @@ -1,8 +1,7 @@ From: James Smart Date: Thu, 18 Aug 2022 18:17:36 -0700 Subject: scsi: lpfc: Copyright updates for 14.2.0.6 patches -Patch-mainline: Queued in subsystem maintainer repository -Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git +Patch-mainline: v6.1-rc1 Git-commit: 1775c2080eb177928e64b924f30db32a36027a0e References: bsc#1203063 diff --git a/patches.suse/scsi-lpfc-Fix-null-ndlp-ptr-dereference-in-abnormal-.patch b/patches.suse/scsi-lpfc-Fix-null-ndlp-ptr-dereference-in-abnormal-.patch index 49e0b63..0eedf66 100644 --- a/patches.suse/scsi-lpfc-Fix-null-ndlp-ptr-dereference-in-abnormal-.patch +++ b/patches.suse/scsi-lpfc-Fix-null-ndlp-ptr-dereference-in-abnormal-.patch @@ -2,8 +2,7 @@ From: James Smart Date: Thu, 18 Aug 2022 18:17:31 -0700 Subject: scsi: lpfc: Fix null ndlp ptr dereference in abnormal exit path for GFT_ID -Patch-mainline: Queued in subsystem maintainer repository -Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git +Patch-mainline: v6.1-rc1 Git-commit: 59b7e210a522b836a01516c71ee85d1d92c1f075 References: bsc#1203063 diff --git a/patches.suse/scsi-lpfc-Fix-unsolicited-FLOGI-receive-handling-dur.patch b/patches.suse/scsi-lpfc-Fix-unsolicited-FLOGI-receive-handling-dur.patch index cfa8047..660349b 100644 --- a/patches.suse/scsi-lpfc-Fix-unsolicited-FLOGI-receive-handling-dur.patch +++ b/patches.suse/scsi-lpfc-Fix-unsolicited-FLOGI-receive-handling-dur.patch @@ -2,8 +2,7 @@ From: James Smart Date: Thu, 18 Aug 2022 18:17:30 -0700 Subject: scsi: lpfc: Fix unsolicited FLOGI receive handling during PT2PT discovery -Patch-mainline: Queued in subsystem maintainer repository -Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git +Patch-mainline: v6.1-rc1 Git-commit: 439b93293ff202dae9661937a73af03374ec0ed0 References: bsc#1203063 diff --git a/patches.suse/scsi-lpfc-Remove-SANDiags-related-code.patch b/patches.suse/scsi-lpfc-Remove-SANDiags-related-code.patch index c29d4cf..372cd2b 100644 --- a/patches.suse/scsi-lpfc-Remove-SANDiags-related-code.patch +++ b/patches.suse/scsi-lpfc-Remove-SANDiags-related-code.patch @@ -1,8 +1,7 @@ From: James Smart Date: Thu, 18 Aug 2022 18:17:34 -0700 Subject: scsi: lpfc: Remove SANDiags related code -Patch-mainline: Queued in subsystem maintainer repository -Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git +Patch-mainline: v6.1-rc1 Git-commit: 2af33e5a031f7eb13f79cb33f5ede30607f772f0 References: bsc#1203063 diff --git a/patches.suse/scsi-lpfc-Return-DID_TRANSPORT_DISRUPTED-instead-of-.patch b/patches.suse/scsi-lpfc-Return-DID_TRANSPORT_DISRUPTED-instead-of-.patch new file mode 100644 index 0000000..9b6699c --- /dev/null +++ b/patches.suse/scsi-lpfc-Return-DID_TRANSPORT_DISRUPTED-instead-of-.patch @@ -0,0 +1,42 @@ +From: Hannes Reinecke +Date: Wed, 24 Aug 2022 08:00:33 +0200 +Subject: scsi: lpfc: Return DID_TRANSPORT_DISRUPTED instead of DID_REQUEUE +Patch-mainline: v6.0-rc5 +Git-commit: c0a50cd389c3ed54831e240023dd12bafa56b3a6 +References: bsc#1203939 + +When the driver hits an internal error condition returning DID_REQUEUE the +I/O will be retried on the same ITL nexus. This will inhibit multipathing, +resulting in endless retries even if the error could have been resolved by +using a different ITL nexus. Return DID_TRANSPORT_DISRUPTED to allow for +multipath to engage and route I/O to another ITL nexus. + +Link: https://lore.kernel.org/r/20220824060033.138661-1-hare@suse.de +Reviewed-by: James Smart +Signed-off-by: Hannes Reinecke +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/lpfc/lpfc_scsi.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/scsi/lpfc/lpfc_scsi.c ++++ b/drivers/scsi/lpfc/lpfc_scsi.c +@@ -4272,7 +4272,7 @@ lpfc_fcp_io_cmd_wqe_cmpl(struct lpfc_hba + lpfc_cmd->result == IOERR_ABORT_REQUESTED || + lpfc_cmd->result == IOERR_RPI_SUSPENDED || + lpfc_cmd->result == IOERR_SLER_CMD_RCV_FAILURE) { +- cmd->result = DID_REQUEUE << 16; ++ cmd->result = DID_TRANSPORT_DISRUPTED << 16; + break; + } + if ((lpfc_cmd->result == IOERR_RX_DMA_FAILED || +@@ -4562,7 +4562,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba + lpfc_cmd->result == IOERR_NO_RESOURCES || + lpfc_cmd->result == IOERR_ABORT_REQUESTED || + lpfc_cmd->result == IOERR_SLER_CMD_RCV_FAILURE) { +- cmd->result = DID_REQUEUE << 16; ++ cmd->result = DID_TRANSPORT_DISRUPTED << 16; + break; + } + if ((lpfc_cmd->result == IOERR_RX_DMA_FAILED || diff --git a/patches.suse/scsi-lpfc-Rework-MIB-Rx-Monitor-debug-info-logic.patch b/patches.suse/scsi-lpfc-Rework-MIB-Rx-Monitor-debug-info-logic.patch index 133db7b..b824c98 100644 --- a/patches.suse/scsi-lpfc-Rework-MIB-Rx-Monitor-debug-info-logic.patch +++ b/patches.suse/scsi-lpfc-Rework-MIB-Rx-Monitor-debug-info-logic.patch @@ -1,8 +1,7 @@ From: James Smart Date: Thu, 18 Aug 2022 18:17:32 -0700 Subject: scsi: lpfc: Rework MIB Rx Monitor debug info logic -Patch-mainline: Queued in subsystem maintainer repository -Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git +Patch-mainline: v6.1-rc1 Git-commit: bd269188ea94e40ab002cad7b0df8f12b8f0de54 References: bsc#1203063 diff --git a/patches.suse/scsi-lpfc-Update-lpfc-version-to-14.2.0.6.patch b/patches.suse/scsi-lpfc-Update-lpfc-version-to-14.2.0.6.patch index e7a2612..002986b 100644 --- a/patches.suse/scsi-lpfc-Update-lpfc-version-to-14.2.0.6.patch +++ b/patches.suse/scsi-lpfc-Update-lpfc-version-to-14.2.0.6.patch @@ -1,8 +1,7 @@ From: James Smart Date: Thu, 18 Aug 2022 18:17:35 -0700 Subject: scsi: lpfc: Update lpfc version to 14.2.0.6 -Patch-mainline: Queued in subsystem maintainer repository -Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git +Patch-mainline: v6.1-rc1 Git-commit: b5c6c88e5809a90635ddea0aadb96e1522a3dcb0 References: bsc#1203063 diff --git a/patches.suse/scsi-lpfc-add-missing-free-iocb-and-nlp-kref-put-for-early-return.patch b/patches.suse/scsi-lpfc-add-missing-free-iocb-and-nlp-kref-put-for-early-return.patch new file mode 100644 index 0000000..a239ec8 --- /dev/null +++ b/patches.suse/scsi-lpfc-add-missing-free-iocb-and-nlp-kref-put-for-early-return.patch @@ -0,0 +1,80 @@ +From: James Smart +Date: Sun, 11 Sep 2022 15:14:56 -0700 +Subject: scsi: lpfc: Add missing free iocb and nlp kref put for early return + VMID cases +Patch-mainline: v6.1-rc1 +Git-commit: 0630a1f7ea14452124392b883302713de31da3d0 +References: bsc#1203939 + +Sometimes VMID targets are not getting rediscovered after a port reset. + +The iocb is not freed in lpfc_cmpl_ct_cmd_vmid(), which is the completion +function for the appid CT commands. So after a port reset, the count of +sges is less than the expected count of 250. This causes post reset +operation logic to fail and keep the port offline. + +Fix by freeing the iocb and kref put for the lpfc_cmpl_ct_cmd_vmid() early +return cases. + +Link: https://lore.kernel.org/r/20220911221505.117655-5-jsmart2021@gmail.com +Co-developed-by: Justin Tee +Signed-off-by: Justin Tee +Signed-off-by: James Smart +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/lpfc/lpfc_ct.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c +index b555ccb5ae34..aad63adfc9ce 100644 +--- a/drivers/scsi/lpfc/lpfc_ct.c ++++ b/drivers/scsi/lpfc/lpfc_ct.c +@@ -3909,6 +3909,7 @@ lpfc_cmpl_ct_cmd_vmid(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, + struct lpfc_sli_ct_request *ctrsp = outp->virt; + u16 rsp = ctrsp->CommandResponse.bits.CmdRsp; + struct app_id_object *app; ++ struct lpfc_nodelist *ndlp = cmdiocb->ndlp; + u32 cmd, hash, bucket; + struct lpfc_vmid *vmp, *cur; + u8 *data = outp->virt; +@@ -3920,7 +3921,7 @@ lpfc_cmpl_ct_cmd_vmid(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, + + if (lpfc_els_chk_latt(vport) || get_job_ulpstatus(phba, rspiocb)) { + if (cmd != SLI_CTAS_DALLAPP_ID) +- return; ++ goto free_res; + } + /* Check for a CT LS_RJT response */ + if (rsp == be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) { +@@ -3935,7 +3936,7 @@ lpfc_cmpl_ct_cmd_vmid(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, + /* If DALLAPP_ID failed retry later */ + if (cmd == SLI_CTAS_DALLAPP_ID) + vport->load_flag |= FC_DEREGISTER_ALL_APP_ID; +- return; ++ goto free_res; + } + } + +@@ -3949,7 +3950,7 @@ lpfc_cmpl_ct_cmd_vmid(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, + app->obj.entity_id_len); + + if (app->obj.entity_id_len == 0 || app->port_id == 0) +- return; ++ goto free_res; + + hash = lpfc_vmid_hash_fn(app->obj.entity_id, + app->obj.entity_id_len); +@@ -3996,6 +3997,9 @@ lpfc_cmpl_ct_cmd_vmid(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, + lpfc_printf_vlog(vport, KERN_DEBUG, LOG_DISCOVERY, + "8857 Invalid command code\n"); + } ++free_res: ++ lpfc_ct_free_iocb(phba, cmdiocb); ++ lpfc_nlp_put(ndlp); + } + + /** +-- +2.35.3 + diff --git a/patches.suse/scsi-lpfc-add-reporting-capability-for-link-degrade-signaling.patch b/patches.suse/scsi-lpfc-add-reporting-capability-for-link-degrade-signaling.patch new file mode 100644 index 0000000..9367383 --- /dev/null +++ b/patches.suse/scsi-lpfc-add-reporting-capability-for-link-degrade-signaling.patch @@ -0,0 +1,663 @@ +From: James Smart +Date: Sun, 11 Sep 2022 15:15:03 -0700 +Subject: scsi: lpfc: Add reporting capability for Link Degrade Signaling +Patch-mainline: v6.1-rc1 +Git-commit: dbb1e2ff87a63b665e93ffee54b46076e9c73d5f +References: bsc#1203939 + +Firmware reports link degrade signaling via ACQES. + +Handlers and new additions to the SET_FEATURES mbox command are implemented +so that link degrade parameters for 64GB capable links are reported through +EDC ELS frames. + +Link: https://lore.kernel.org/r/20220911221505.117655-12-jsmart2021@gmail.com +Co-developed-by: Justin Tee +Signed-off-by: Justin Tee +Signed-off-by: James Smart +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/lpfc/lpfc.h | 6 ++ + drivers/scsi/lpfc/lpfc_crtn.h | 1 + + drivers/scsi/lpfc/lpfc_els.c | 154 ++++++++++++++++++++++--------- + drivers/scsi/lpfc/lpfc_hbadisc.c | 10 +- + drivers/scsi/lpfc/lpfc_hw4.h | 30 +++--- + drivers/scsi/lpfc/lpfc_init.c | 26 +++++- + drivers/scsi/lpfc/lpfc_logmsg.h | 2 +- + drivers/scsi/lpfc/lpfc_sli.c | 63 ++++++++++++- + 8 files changed, 224 insertions(+), 68 deletions(-) + +diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h +index 68b3bd70dd52..9ad233b40a9e 100644 +--- a/drivers/scsi/lpfc/lpfc.h ++++ b/drivers/scsi/lpfc/lpfc.h +@@ -403,6 +403,7 @@ struct lpfc_trunk_link { + link1, + link2, + link3; ++ u32 phy_lnk_speed; + }; + + /* Format of congestion module parameters */ +@@ -1596,6 +1597,11 @@ struct lpfc_hba { + + char os_host_name[MAXHOSTNAMELEN]; + ++ /* LD Signaling */ ++ u32 degrade_activate_threshold; ++ u32 degrade_deactivate_threshold; ++ u32 fec_degrade_interval; ++ + atomic_t dbg_log_idx; + atomic_t dbg_log_cnt; + atomic_t dbg_log_dmping; +diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h +index 84880b567dbb..d2d207791056 100644 +--- a/drivers/scsi/lpfc/lpfc_crtn.h ++++ b/drivers/scsi/lpfc/lpfc_crtn.h +@@ -78,6 +78,7 @@ int lpfc_init_iocb_list(struct lpfc_hba *phba, int cnt); + void lpfc_free_iocb_list(struct lpfc_hba *phba); + int lpfc_post_rq_buffer(struct lpfc_hba *phba, struct lpfc_queue *hrq, + struct lpfc_queue *drq, int count, int idx); ++int lpfc_read_lds_params(struct lpfc_hba *phba); + uint32_t lpfc_calc_cmf_latency(struct lpfc_hba *phba); + void lpfc_cmf_signal_init(struct lpfc_hba *phba); + void lpfc_cmf_start(struct lpfc_hba *phba); +diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c +index 642d90af4f09..863b2125fed6 100644 +--- a/drivers/scsi/lpfc/lpfc_els.c ++++ b/drivers/scsi/lpfc/lpfc_els.c +@@ -3988,7 +3988,8 @@ lpfc_cmpl_els_edc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, + goto out; + + /* ELS cmd tag completes */ +- lpfc_printf_log(phba, KERN_INFO, LOG_ELS | LOG_CGN_MGMT, ++ lpfc_printf_log(phba, KERN_INFO, ++ LOG_ELS | LOG_CGN_MGMT | LOG_LDS_EVENT, + "4676 Fabric EDC Rsp: " + "0x%02x, 0x%08x\n", + edc_rsp->acc_hdr.la_cmd, +@@ -4025,18 +4026,18 @@ lpfc_cmpl_els_edc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, + if (bytes_remain < FC_TLV_DESC_SZ_FROM_LENGTH(tlv) || + FC_TLV_DESC_SZ_FROM_LENGTH(tlv) != + sizeof(struct fc_diag_lnkflt_desc)) { +- lpfc_printf_log( +- phba, KERN_WARNING, LOG_CGN_MGMT, ++ lpfc_printf_log(phba, KERN_WARNING, ++ LOG_ELS | LOG_CGN_MGMT | LOG_LDS_EVENT, + "6462 Truncated Link Fault Diagnostic " + "descriptor[%d]: %d vs 0x%zx 0x%zx\n", + desc_cnt, bytes_remain, + FC_TLV_DESC_SZ_FROM_LENGTH(tlv), +- sizeof(struct fc_diag_cg_sig_desc)); ++ sizeof(struct fc_diag_lnkflt_desc)); + goto out; + } + plnkflt = (struct fc_diag_lnkflt_desc *)tlv; +- lpfc_printf_log( +- phba, KERN_INFO, LOG_ELS | LOG_CGN_MGMT, ++ lpfc_printf_log(phba, KERN_INFO, ++ LOG_ELS | LOG_LDS_EVENT, + "4617 Link Fault Desc Data: 0x%08x 0x%08x " + "0x%08x 0x%08x 0x%08x\n", + be32_to_cpu(plnkflt->desc_tag), +@@ -4116,8 +4117,26 @@ lpfc_cmpl_els_edc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, + } + + static void +-lpfc_format_edc_cgn_desc(struct lpfc_hba *phba, struct fc_diag_cg_sig_desc *cgd) ++lpfc_format_edc_lft_desc(struct lpfc_hba *phba, struct fc_tlv_desc *tlv) + { ++ struct fc_diag_lnkflt_desc *lft = (struct fc_diag_lnkflt_desc *)tlv; ++ ++ lft->desc_tag = cpu_to_be32(ELS_DTAG_LNK_FAULT_CAP); ++ lft->desc_len = cpu_to_be32( ++ FC_TLV_DESC_LENGTH_FROM_SZ(struct fc_diag_lnkflt_desc)); ++ ++ lft->degrade_activate_threshold = ++ cpu_to_be32(phba->degrade_activate_threshold); ++ lft->degrade_deactivate_threshold = ++ cpu_to_be32(phba->degrade_deactivate_threshold); ++ lft->fec_degrade_interval = cpu_to_be32(phba->fec_degrade_interval); ++} ++ ++static void ++lpfc_format_edc_cgn_desc(struct lpfc_hba *phba, struct fc_tlv_desc *tlv) ++{ ++ struct fc_diag_cg_sig_desc *cgd = (struct fc_diag_cg_sig_desc *)tlv; ++ + /* We are assuming cgd was zero'ed before calling this routine */ + + /* Configure the congestion detection capability */ +@@ -4161,6 +4180,23 @@ lpfc_format_edc_cgn_desc(struct lpfc_hba *phba, struct fc_diag_cg_sig_desc *cgd) + cpu_to_be16(EDC_CG_SIGFREQ_MSEC); + } + ++static bool ++lpfc_link_is_lds_capable(struct lpfc_hba *phba) ++{ ++ if (!(phba->lmt & LMT_64Gb)) ++ return false; ++ if (phba->sli_rev != LPFC_SLI_REV4) ++ return false; ++ ++ if (phba->sli4_hba.conf_trunk) { ++ if (phba->trunk_link.phy_lnk_speed == LPFC_USER_LINK_SPEED_64G) ++ return true; ++ } else if (phba->fc_linkspeed == LPFC_LINK_SPEED_64GHZ) { ++ return true; ++ } ++ return false; ++} ++ + /** + * lpfc_issue_els_edc - Exchange Diagnostic Capabilities with the fabric. + * @vport: pointer to a host virtual N_Port data structure. +@@ -4188,12 +4224,12 @@ lpfc_issue_els_edc(struct lpfc_vport *vport, uint8_t retry) + { + struct lpfc_hba *phba = vport->phba; + struct lpfc_iocbq *elsiocb; +- struct lpfc_els_edc_req *edc_req; +- struct fc_diag_cg_sig_desc *cgn_desc; ++ struct fc_els_edc *edc_req; ++ struct fc_tlv_desc *tlv; + u16 cmdsize; + struct lpfc_nodelist *ndlp; + u8 *pcmd = NULL; +- u32 edc_req_size, cgn_desc_size; ++ u32 cgn_desc_size, lft_desc_size; + int rc; + + if (vport->port_type == LPFC_NPIV_PORT) +@@ -4203,13 +4239,17 @@ lpfc_issue_els_edc(struct lpfc_vport *vport, uint8_t retry) + if (!ndlp || ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) + return -ENODEV; + +- /* If HBA doesn't support signals, drop into RDF */ +- if (!phba->cgn_init_reg_signal) ++ cgn_desc_size = (phba->cgn_init_reg_signal) ? ++ sizeof(struct fc_diag_cg_sig_desc) : 0; ++ lft_desc_size = (lpfc_link_is_lds_capable(phba)) ? ++ sizeof(struct fc_diag_lnkflt_desc) : 0; ++ cmdsize = cgn_desc_size + lft_desc_size; ++ ++ /* Skip EDC if no applicable descriptors */ ++ if (!cmdsize) + goto try_rdf; + +- edc_req_size = sizeof(struct fc_els_edc); +- cgn_desc_size = sizeof(struct fc_diag_cg_sig_desc); +- cmdsize = edc_req_size + cgn_desc_size; ++ cmdsize += sizeof(struct fc_els_edc); + elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, + ndlp->nlp_DID, ELS_CMD_EDC); + if (!elsiocb) +@@ -4218,15 +4258,19 @@ lpfc_issue_els_edc(struct lpfc_vport *vport, uint8_t retry) + /* Configure the payload for the supported Diagnostics capabilities. */ + pcmd = (u8 *)elsiocb->cmd_dmabuf->virt; + memset(pcmd, 0, cmdsize); +- edc_req = (struct lpfc_els_edc_req *)pcmd; +- edc_req->edc.desc_len = cpu_to_be32(cgn_desc_size); +- edc_req->edc.edc_cmd = ELS_EDC; +- +- cgn_desc = &edc_req->cgn_desc; ++ edc_req = (struct fc_els_edc *)pcmd; ++ edc_req->desc_len = cpu_to_be32(cgn_desc_size + lft_desc_size); ++ edc_req->edc_cmd = ELS_EDC; ++ tlv = edc_req->desc; + +- lpfc_format_edc_cgn_desc(phba, cgn_desc); ++ if (cgn_desc_size) { ++ lpfc_format_edc_cgn_desc(phba, tlv); ++ phba->cgn_sig_freq = lpfc_fabric_cgn_frequency; ++ tlv = fc_tlv_next_desc(tlv); ++ } + +- phba->cgn_sig_freq = lpfc_fabric_cgn_frequency; ++ if (lft_desc_size) ++ lpfc_format_edc_lft_desc(phba, tlv); + + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS | LOG_CGN_MGMT, + "4623 Xmit EDC to remote " +@@ -5780,14 +5824,21 @@ lpfc_issue_els_edc_rsp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, + struct lpfc_nodelist *ndlp) + { + struct lpfc_hba *phba = vport->phba; +- struct lpfc_els_edc_rsp *edc_rsp; ++ struct fc_els_edc_resp *edc_rsp; ++ struct fc_tlv_desc *tlv; + struct lpfc_iocbq *elsiocb; + IOCB_t *icmd, *cmd; + union lpfc_wqe128 *wqe; ++ u32 cgn_desc_size, lft_desc_size; ++ u16 cmdsize; + uint8_t *pcmd; +- int cmdsize, rc; ++ int rc; + +- cmdsize = sizeof(struct lpfc_els_edc_rsp); ++ cmdsize = sizeof(struct fc_els_edc_resp); ++ cgn_desc_size = sizeof(struct fc_diag_cg_sig_desc); ++ lft_desc_size = (lpfc_link_is_lds_capable(phba)) ? ++ sizeof(struct fc_diag_lnkflt_desc) : 0; ++ cmdsize += cgn_desc_size + lft_desc_size; + elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, cmdiocb->retry, + ndlp, ndlp->nlp_DID, ELS_CMD_ACC); + if (!elsiocb) +@@ -5809,15 +5860,19 @@ lpfc_issue_els_edc_rsp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, + pcmd = elsiocb->cmd_dmabuf->virt; + memset(pcmd, 0, cmdsize); + +- edc_rsp = (struct lpfc_els_edc_rsp *)pcmd; +- edc_rsp->edc_rsp.acc_hdr.la_cmd = ELS_LS_ACC; +- edc_rsp->edc_rsp.desc_list_len = cpu_to_be32( +- FC_TLV_DESC_LENGTH_FROM_SZ(struct lpfc_els_edc_rsp)); +- edc_rsp->edc_rsp.lsri.desc_tag = cpu_to_be32(ELS_DTAG_LS_REQ_INFO); +- edc_rsp->edc_rsp.lsri.desc_len = cpu_to_be32( ++ edc_rsp = (struct fc_els_edc_resp *)pcmd; ++ edc_rsp->acc_hdr.la_cmd = ELS_LS_ACC; ++ edc_rsp->desc_list_len = cpu_to_be32(sizeof(struct fc_els_lsri_desc) + ++ cgn_desc_size + lft_desc_size); ++ edc_rsp->lsri.desc_tag = cpu_to_be32(ELS_DTAG_LS_REQ_INFO); ++ edc_rsp->lsri.desc_len = cpu_to_be32( + FC_TLV_DESC_LENGTH_FROM_SZ(struct fc_els_lsri_desc)); +- edc_rsp->edc_rsp.lsri.rqst_w0.cmd = ELS_EDC; +- lpfc_format_edc_cgn_desc(phba, &edc_rsp->cgn_desc); ++ edc_rsp->lsri.rqst_w0.cmd = ELS_EDC; ++ tlv = edc_rsp->desc; ++ lpfc_format_edc_cgn_desc(phba, tlv); ++ tlv = fc_tlv_next_desc(tlv); ++ if (lft_desc_size) ++ lpfc_format_edc_lft_desc(phba, tlv); + + lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP, + "Issue EDC ACC: did:x%x flg:x%x refcnt %d", +@@ -9082,7 +9137,7 @@ lpfc_els_rcv_edc(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, + uint32_t *ptr, dtag; + const char *dtag_nm; + int desc_cnt = 0, bytes_remain; +- bool rcv_cap_desc = false; ++ struct fc_diag_lnkflt_desc *plnkflt; + + payload = cmdiocb->cmd_dmabuf->virt; + +@@ -9090,7 +9145,8 @@ lpfc_els_rcv_edc(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, + bytes_remain = be32_to_cpu(edc_req->desc_len); + + ptr = (uint32_t *)payload; +- lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS | LOG_CGN_MGMT, ++ lpfc_printf_vlog(vport, KERN_INFO, ++ LOG_ELS | LOG_CGN_MGMT | LOG_LDS_EVENT, + "3319 Rcv EDC payload len %d: x%x x%x x%x\n", + bytes_remain, be32_to_cpu(*ptr), + be32_to_cpu(*(ptr + 1)), be32_to_cpu(*(ptr + 2))); +@@ -9109,9 +9165,10 @@ lpfc_els_rcv_edc(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, + * cycle through EDC diagnostic descriptors to find the + * congestion signaling capability descriptor + */ +- while (bytes_remain && !rcv_cap_desc) { ++ while (bytes_remain) { + if (bytes_remain < FC_TLV_DESC_HDR_SZ) { +- lpfc_printf_log(phba, KERN_WARNING, LOG_CGN_MGMT, ++ lpfc_printf_log(phba, KERN_WARNING, ++ LOG_ELS | LOG_CGN_MGMT | LOG_LDS_EVENT, + "6464 Truncated TLV hdr on " + "Diagnostic descriptor[%d]\n", + desc_cnt); +@@ -9124,16 +9181,27 @@ lpfc_els_rcv_edc(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, + if (bytes_remain < FC_TLV_DESC_SZ_FROM_LENGTH(tlv) || + FC_TLV_DESC_SZ_FROM_LENGTH(tlv) != + sizeof(struct fc_diag_lnkflt_desc)) { +- lpfc_printf_log( +- phba, KERN_WARNING, LOG_CGN_MGMT, ++ lpfc_printf_log(phba, KERN_WARNING, ++ LOG_ELS | LOG_CGN_MGMT | LOG_LDS_EVENT, + "6465 Truncated Link Fault Diagnostic " + "descriptor[%d]: %d vs 0x%zx 0x%zx\n", + desc_cnt, bytes_remain, + FC_TLV_DESC_SZ_FROM_LENGTH(tlv), +- sizeof(struct fc_diag_cg_sig_desc)); ++ sizeof(struct fc_diag_lnkflt_desc)); + goto out; + } +- /* No action for Link Fault descriptor for now */ ++ plnkflt = (struct fc_diag_lnkflt_desc *)tlv; ++ lpfc_printf_log(phba, KERN_INFO, ++ LOG_ELS | LOG_LDS_EVENT, ++ "4626 Link Fault Desc Data: x%08x len x%x " ++ "da x%x dd x%x interval x%x\n", ++ be32_to_cpu(plnkflt->desc_tag), ++ be32_to_cpu(plnkflt->desc_len), ++ be32_to_cpu( ++ plnkflt->degrade_activate_threshold), ++ be32_to_cpu( ++ plnkflt->degrade_deactivate_threshold), ++ be32_to_cpu(plnkflt->fec_degrade_interval)); + break; + case ELS_DTAG_CG_SIGNAL_CAP: + if (bytes_remain < FC_TLV_DESC_SZ_FROM_LENGTH(tlv) || +@@ -9160,11 +9228,11 @@ lpfc_els_rcv_edc(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, + + lpfc_least_capable_settings( + phba, (struct fc_diag_cg_sig_desc *)tlv); +- rcv_cap_desc = true; + break; + default: + dtag_nm = lpfc_get_tlv_dtag_nm(dtag); +- lpfc_printf_log(phba, KERN_WARNING, LOG_CGN_MGMT, ++ lpfc_printf_log(phba, KERN_WARNING, ++ LOG_ELS | LOG_CGN_MGMT | LOG_LDS_EVENT, + "6467 unknown Diagnostic " + "Descriptor[%d]: tag x%x (%s)\n", + desc_cnt, dtag, dtag_nm); +diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c +index 24d533c0b729..2b79351dfd11 100644 +--- a/drivers/scsi/lpfc/lpfc_hbadisc.c ++++ b/drivers/scsi/lpfc/lpfc_hbadisc.c +@@ -1242,6 +1242,8 @@ lpfc_linkdown(struct lpfc_hba *phba) + phba->trunk_link.link1.state = 0; + phba->trunk_link.link2.state = 0; + phba->trunk_link.link3.state = 0; ++ phba->trunk_link.phy_lnk_speed = ++ LPFC_LINK_SPEED_UNKNOWN; + phba->sli4_hba.link_state.logical_speed = + LPFC_LINK_SPEED_UNKNOWN; + } +@@ -3794,6 +3796,9 @@ lpfc_mbx_cmpl_read_topology(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) + if (phba->cmf_active_mode != LPFC_CFG_OFF) + lpfc_cmf_signal_init(phba); + ++ if (phba->lmt & LMT_64Gb) ++ lpfc_read_lds_params(phba); ++ + } else if (attn_type == LPFC_ATT_LINK_DOWN || + attn_type == LPFC_ATT_UNEXP_WWPN) { + phba->fc_stat.LinkDown++; +@@ -4393,8 +4398,11 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) + rc = lpfc_issue_els_edc(vport, 0); + lpfc_printf_log(phba, KERN_INFO, + LOG_INIT | LOG_ELS | LOG_DISCOVERY, +- "4220 EDC issue error x%x, Data: x%x\n", ++ "4220 Issue EDC status x%x Data x%x\n", + rc, phba->cgn_init_reg_signal); ++ } else if (phba->lmt & LMT_64Gb) { ++ /* may send link fault capability descriptor */ ++ lpfc_issue_els_edc(vport, 0); + } else { + lpfc_issue_els_rdf(vport, 0); + } +diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h +index ca49679e87b9..5288fc69908a 100644 +--- a/drivers/scsi/lpfc/lpfc_hw4.h ++++ b/drivers/scsi/lpfc/lpfc_hw4.h +@@ -3484,9 +3484,10 @@ struct lpfc_sli4_parameters { + + #define LPFC_SET_UE_RECOVERY 0x10 + #define LPFC_SET_MDS_DIAGS 0x12 +-#define LPFC_SET_CGN_SIGNAL 0x1f + #define LPFC_SET_DUAL_DUMP 0x1e ++#define LPFC_SET_CGN_SIGNAL 0x1f + #define LPFC_SET_ENABLE_MI 0x21 ++#define LPFC_SET_LD_SIGNAL 0x23 + #define LPFC_SET_ENABLE_CMF 0x24 + struct lpfc_mbx_set_feature { + struct mbox_header header; +@@ -3517,13 +3518,17 @@ struct lpfc_mbx_set_feature { + #define lpfc_mbx_set_feature_cmf_SHIFT 0 + #define lpfc_mbx_set_feature_cmf_MASK 0x00000001 + #define lpfc_mbx_set_feature_cmf_WORD word6 ++#define lpfc_mbx_set_feature_lds_qry_SHIFT 0 ++#define lpfc_mbx_set_feature_lds_qry_MASK 0x00000001 ++#define lpfc_mbx_set_feature_lds_qry_WORD word6 ++#define LPFC_QUERY_LDS_OP 1 + #define lpfc_mbx_set_feature_mi_SHIFT 0 + #define lpfc_mbx_set_feature_mi_MASK 0x0000ffff + #define lpfc_mbx_set_feature_mi_WORD word6 + #define lpfc_mbx_set_feature_milunq_SHIFT 16 + #define lpfc_mbx_set_feature_milunq_MASK 0x0000ffff + #define lpfc_mbx_set_feature_milunq_WORD word6 +- uint32_t word7; ++ u32 word7; + #define lpfc_mbx_set_feature_UERP_SHIFT 0 + #define lpfc_mbx_set_feature_UERP_MASK 0x0000ffff + #define lpfc_mbx_set_feature_UERP_WORD word7 +@@ -3537,6 +3542,8 @@ struct lpfc_mbx_set_feature { + #define lpfc_mbx_set_feature_CGN_acqe_freq_SHIFT 0 + #define lpfc_mbx_set_feature_CGN_acqe_freq_MASK 0x000000ff + #define lpfc_mbx_set_feature_CGN_acqe_freq_WORD word8 ++ u32 word9; ++ u32 word10; + }; + + +@@ -4314,7 +4321,7 @@ struct lpfc_acqe_cgn_signal { + struct lpfc_acqe_sli { + uint32_t event_data1; + uint32_t event_data2; +- uint32_t reserved; ++ uint32_t event_data3; + uint32_t trailer; + #define LPFC_SLI_EVENT_TYPE_PORT_ERROR 0x1 + #define LPFC_SLI_EVENT_TYPE_OVER_TEMP 0x2 +@@ -4327,6 +4334,7 @@ struct lpfc_acqe_sli { + #define LPFC_SLI_EVENT_TYPE_MISCONF_FAWWN 0xF + #define LPFC_SLI_EVENT_TYPE_EEPROM_FAILURE 0x10 + #define LPFC_SLI_EVENT_TYPE_CGN_SIGNAL 0x11 ++#define LPFC_SLI_EVENT_TYPE_RD_SIGNAL 0x12 + }; + + /* +@@ -5050,22 +5058,6 @@ struct lpfc_grp_hdr { + { FPIN_CONGN_SEVERITY_ERROR, "Alarm" }, \ + } + +-/* EDC supports two descriptors. When allocated, it is the +- * size of this structure plus each supported descriptor. +- */ +-struct lpfc_els_edc_req { +- struct fc_els_edc edc; /* hdr up to descriptors */ +- struct fc_diag_cg_sig_desc cgn_desc; /* 1st descriptor */ +-}; +- +-/* Minimum structure defines for the EDC response. +- * Balance is in buffer. +- */ +-struct lpfc_els_edc_rsp { +- struct fc_els_edc_resp edc_rsp; /* hdr up to descriptors */ +- struct fc_diag_cg_sig_desc cgn_desc; /* 1st descriptor */ +-}; +- + /* Used for logging FPIN messages */ + #define LPFC_FPIN_WWPN_LINE_SZ 128 + #define LPFC_FPIN_WWPN_LINE_CNT 6 +diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c +index b170e9e9f167..511220aa43f5 100644 +--- a/drivers/scsi/lpfc/lpfc_init.c ++++ b/drivers/scsi/lpfc/lpfc_init.c +@@ -6185,6 +6185,7 @@ lpfc_update_trunk_link_status(struct lpfc_hba *phba, + { + uint8_t port_fault = bf_get(lpfc_acqe_fc_la_trunk_linkmask, acqe_fc); + uint8_t err = bf_get(lpfc_acqe_fc_la_trunk_fault, acqe_fc); ++ u8 cnt = 0; + + phba->sli4_hba.link_state.speed = + lpfc_sli4_port_speed_parse(phba, LPFC_TRAILER_CODE_FC, +@@ -6203,26 +6204,36 @@ lpfc_update_trunk_link_status(struct lpfc_hba *phba, + bf_get(lpfc_acqe_fc_la_trunk_link_status_port0, acqe_fc) + ? LPFC_LINK_UP : LPFC_LINK_DOWN; + phba->trunk_link.link0.fault = port_fault & 0x1 ? err : 0; ++ cnt++; + } + if (bf_get(lpfc_acqe_fc_la_trunk_config_port1, acqe_fc)) { + phba->trunk_link.link1.state = + bf_get(lpfc_acqe_fc_la_trunk_link_status_port1, acqe_fc) + ? LPFC_LINK_UP : LPFC_LINK_DOWN; + phba->trunk_link.link1.fault = port_fault & 0x2 ? err : 0; ++ cnt++; + } + if (bf_get(lpfc_acqe_fc_la_trunk_config_port2, acqe_fc)) { + phba->trunk_link.link2.state = + bf_get(lpfc_acqe_fc_la_trunk_link_status_port2, acqe_fc) + ? LPFC_LINK_UP : LPFC_LINK_DOWN; + phba->trunk_link.link2.fault = port_fault & 0x4 ? err : 0; ++ cnt++; + } + if (bf_get(lpfc_acqe_fc_la_trunk_config_port3, acqe_fc)) { + phba->trunk_link.link3.state = + bf_get(lpfc_acqe_fc_la_trunk_link_status_port3, acqe_fc) + ? LPFC_LINK_UP : LPFC_LINK_DOWN; + phba->trunk_link.link3.fault = port_fault & 0x8 ? err : 0; ++ cnt++; + } + ++ if (cnt) ++ phba->trunk_link.phy_lnk_speed = ++ phba->sli4_hba.link_state.logical_speed / (cnt * 1000); ++ else ++ phba->trunk_link.phy_lnk_speed = LPFC_LINK_SPEED_UNKNOWN; ++ + lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, + "2910 Async FC Trunking Event - Speed:%d\n" + "\tLogical speed:%d " +@@ -6300,7 +6311,7 @@ lpfc_sli4_async_fc_evt(struct lpfc_hba *phba, struct lpfc_acqe_fc_la *acqe_fc) + if (bf_get(lpfc_acqe_fc_la_att_type, acqe_fc) == + LPFC_FC_LA_TYPE_LINK_DOWN) + phba->sli4_hba.link_state.logical_speed = 0; +- else if (!phba->sli4_hba.conf_trunk) ++ else if (!phba->sli4_hba.conf_trunk) + phba->sli4_hba.link_state.logical_speed = + bf_get(lpfc_acqe_fc_la_llink_spd, acqe_fc) * 10; + +@@ -6418,7 +6429,7 @@ lpfc_sli4_async_sli_evt(struct lpfc_hba *phba, struct lpfc_acqe_sli *acqe_sli) + "2901 Async SLI event - Type:%d, Event Data: x%08x " + "x%08x x%08x x%08x\n", evt_type, + acqe_sli->event_data1, acqe_sli->event_data2, +- acqe_sli->reserved, acqe_sli->trailer); ++ acqe_sli->event_data3, acqe_sli->trailer); + + port_name = phba->Port[0]; + if (port_name == 0x00) +@@ -6447,7 +6458,7 @@ lpfc_sli4_async_sli_evt(struct lpfc_hba *phba, struct lpfc_acqe_sli *acqe_sli) + temp_event_data.event_code = LPFC_NORMAL_TEMP; + temp_event_data.data = (uint32_t)acqe_sli->event_data1; + +- lpfc_printf_log(phba, KERN_INFO, LOG_SLI, ++ lpfc_printf_log(phba, KERN_INFO, LOG_SLI | LOG_LDS_EVENT, + "3191 Normal Temperature:%d Celsius - Port Name %c\n", + acqe_sli->event_data1, port_name); + +@@ -6625,6 +6636,15 @@ lpfc_sli4_async_sli_evt(struct lpfc_hba *phba, struct lpfc_acqe_sli *acqe_sli) + } + } + break; ++ case LPFC_SLI_EVENT_TYPE_RD_SIGNAL: ++ /* May be accompanied by a temperature event */ ++ lpfc_printf_log(phba, KERN_INFO, ++ LOG_SLI | LOG_LINK_EVENT | LOG_LDS_EVENT, ++ "2902 Remote Degrade Signaling: x%08x x%08x " ++ "x%08x\n", ++ acqe_sli->event_data1, acqe_sli->event_data2, ++ acqe_sli->event_data3); ++ break; + default: + lpfc_printf_log(phba, KERN_INFO, LOG_SLI, + "3193 Unrecognized SLI event, type: 0x%x", +diff --git a/drivers/scsi/lpfc/lpfc_logmsg.h b/drivers/scsi/lpfc/lpfc_logmsg.h +index 4d455da9cd69..b39cefcd8703 100644 +--- a/drivers/scsi/lpfc/lpfc_logmsg.h ++++ b/drivers/scsi/lpfc/lpfc_logmsg.h +@@ -35,7 +35,7 @@ + #define LOG_FCP_ERROR 0x00001000 /* log errors, not underruns */ + #define LOG_LIBDFC 0x00002000 /* Libdfc events */ + #define LOG_VPORT 0x00004000 /* NPIV events */ +-#define LOG_SECURITY 0x00008000 /* Security events */ ++#define LOG_LDS_EVENT 0x00008000 /* Link Degrade Signaling events */ + #define LOG_EVENT 0x00010000 /* CT,TEMP,DUMP, logging */ + #define LOG_FIP 0x00020000 /* FIP events */ + #define LOG_FCP_UNDER 0x00040000 /* FCP underruns errors */ +diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c +index 002794975cd9..06987d4013d5 100644 +--- a/drivers/scsi/lpfc/lpfc_sli.c ++++ b/drivers/scsi/lpfc/lpfc_sli.c +@@ -6830,8 +6830,13 @@ lpfc_set_features(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox, + bf_set(lpfc_mbx_set_feature_mi, &mbox->u.mqe.un.set_feature, + phba->sli4_hba.pc_sli4_params.mi_ver); + break; ++ case LPFC_SET_LD_SIGNAL: ++ mbox->u.mqe.un.set_feature.feature = LPFC_SET_LD_SIGNAL; ++ mbox->u.mqe.un.set_feature.param_len = 16; ++ bf_set(lpfc_mbx_set_feature_lds_qry, ++ &mbox->u.mqe.un.set_feature, LPFC_QUERY_LDS_OP); ++ break; + case LPFC_SET_ENABLE_CMF: +- bf_set(lpfc_mbx_set_feature_dd, &mbox->u.mqe.un.set_feature, 1); + mbox->u.mqe.un.set_feature.feature = LPFC_SET_ENABLE_CMF; + mbox->u.mqe.un.set_feature.param_len = 4; + bf_set(lpfc_mbx_set_feature_cmf, +@@ -7826,6 +7831,62 @@ lpfc_post_rq_buffer(struct lpfc_hba *phba, struct lpfc_queue *hrq, + return 1; + } + ++static void ++lpfc_mbx_cmpl_read_lds_params(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) ++{ ++ union lpfc_sli4_cfg_shdr *shdr; ++ u32 shdr_status, shdr_add_status; ++ ++ shdr = (union lpfc_sli4_cfg_shdr *) ++ &pmb->u.mqe.un.sli4_config.header.cfg_shdr; ++ shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); ++ shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); ++ if (shdr_status || shdr_add_status || pmb->u.mb.mbxStatus) { ++ lpfc_printf_log(phba, KERN_INFO, LOG_LDS_EVENT | LOG_MBOX, ++ "4622 SET_FEATURE (x%x) mbox failed, " ++ "status x%x add_status x%x, mbx status x%x\n", ++ LPFC_SET_LD_SIGNAL, shdr_status, ++ shdr_add_status, pmb->u.mb.mbxStatus); ++ phba->degrade_activate_threshold = 0; ++ phba->degrade_deactivate_threshold = 0; ++ phba->fec_degrade_interval = 0; ++ goto out; ++ } ++ ++ phba->degrade_activate_threshold = pmb->u.mqe.un.set_feature.word7; ++ phba->degrade_deactivate_threshold = pmb->u.mqe.un.set_feature.word8; ++ phba->fec_degrade_interval = pmb->u.mqe.un.set_feature.word10; ++ ++ lpfc_printf_log(phba, KERN_INFO, LOG_LDS_EVENT, ++ "4624 Success: da x%x dd x%x interval x%x\n", ++ phba->degrade_activate_threshold, ++ phba->degrade_deactivate_threshold, ++ phba->fec_degrade_interval); ++out: ++ mempool_free(pmb, phba->mbox_mem_pool); ++} ++ ++int ++lpfc_read_lds_params(struct lpfc_hba *phba) ++{ ++ LPFC_MBOXQ_t *mboxq; ++ int rc; ++ ++ mboxq = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); ++ if (!mboxq) ++ return -ENOMEM; ++ ++ lpfc_set_features(phba, mboxq, LPFC_SET_LD_SIGNAL); ++ mboxq->vport = phba->pport; ++ mboxq->mbox_cmpl = lpfc_mbx_cmpl_read_lds_params; ++ rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT); ++ if (rc == MBX_NOT_FINISHED) { ++ mempool_free(mboxq, phba->mbox_mem_pool); ++ return -EIO; ++ } ++ return 0; ++} ++ + static void + lpfc_mbx_cmpl_cgn_set_ftrs(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) + { +-- +2.35.3 + diff --git a/patches.suse/scsi-lpfc-fix-flogi-acc-with-wrong-sid-in-pt2pt-topology.patch b/patches.suse/scsi-lpfc-fix-flogi-acc-with-wrong-sid-in-pt2pt-topology.patch new file mode 100644 index 0000000..e7cd7a2 --- /dev/null +++ b/patches.suse/scsi-lpfc-fix-flogi-acc-with-wrong-sid-in-pt2pt-topology.patch @@ -0,0 +1,51 @@ +From: James Smart +Date: Sun, 11 Sep 2022 15:14:54 -0700 +Subject: scsi: lpfc: Fix FLOGI ACC with wrong SID in PT2PT topology +Patch-mainline: v6.1-rc1 +Git-commit: 11d6583d811fb044597d366349f0dda0278dda3f +References: bsc#1203939 + +When a FLOGI is received before we have issued our FLOGI, the ACC response +to the received FLOGI is issued with SID 2 instead of the expected fabric +controller SID. Certain target vendors ignore the malformed ACC with SID 2 +and wait for a properly filled ACC with a fabric controller SID. + +The lpfc_sli_prep_wqe() routine depends on the FC_PT2PT flag to fill in the +fabric controller SID when in PT2PT mode, but due to a previous commit the +flag was getting cleared. Fix by adding a check for the defer_flogi_acc +flag to know whether or not to clear the FC_PT2PT flag on link up. + +Link: https://lore.kernel.org/r/20220911221505.117655-3-jsmart2021@gmail.com +Fixes: 439b93293ff2 ("scsi: lpfc: Fix unsolicited FLOGI receive handling during PT2PT discovery") +Co-developed-by: Justin Tee +Signed-off-by: Justin Tee +Signed-off-by: James Smart +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/lpfc/lpfc_hbadisc.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c +index 83d2b29ee2a6..24d533c0b729 100644 +--- a/drivers/scsi/lpfc/lpfc_hbadisc.c ++++ b/drivers/scsi/lpfc/lpfc_hbadisc.c +@@ -1353,8 +1353,13 @@ lpfc_linkup_port(struct lpfc_vport *vport) + FCH_EVT_LINKUP, 0); + + spin_lock_irq(shost->host_lock); +- vport->fc_flag &= ~(FC_PT2PT | FC_PT2PT_PLOGI | FC_ABORT_DISCOVERY | +- FC_RSCN_MODE | FC_NLP_MORE | FC_RSCN_DISCOVERY); ++ if (phba->defer_flogi_acc_flag) ++ vport->fc_flag &= ~(FC_ABORT_DISCOVERY | FC_RSCN_MODE | ++ FC_NLP_MORE | FC_RSCN_DISCOVERY); ++ else ++ vport->fc_flag &= ~(FC_PT2PT | FC_PT2PT_PLOGI | ++ FC_ABORT_DISCOVERY | FC_RSCN_MODE | ++ FC_NLP_MORE | FC_RSCN_DISCOVERY); + vport->fc_flag |= FC_NDISC_ACTIVE; + vport->fc_ns_retry = 0; + spin_unlock_irq(shost->host_lock); +-- +2.35.3 + diff --git a/patches.suse/scsi-lpfc-fix-mbuf-pool-resource-detected-as-busy-at-driver-unload.patch b/patches.suse/scsi-lpfc-fix-mbuf-pool-resource-detected-as-busy-at-driver-unload.patch new file mode 100644 index 0000000..2a08cd1 --- /dev/null +++ b/patches.suse/scsi-lpfc-fix-mbuf-pool-resource-detected-as-busy-at-driver-unload.patch @@ -0,0 +1,53 @@ +From: James Smart +Date: Sun, 11 Sep 2022 15:14:55 -0700 +Subject: scsi: lpfc: Fix mbuf pool resource detected as busy at driver unload +Patch-mainline: v6.1-rc1 +Git-commit: b873d1037283b5082863b97443dd25e592c40684 +References: bsc#1203939 + +In a situation where the node state changes while a REG_LOGIN is in +progress, the LPFC_MBOXQ_t structure is cleared and reused for an +UNREG_LOGIN command to release RPI resources without first freeing the mbuf +pool resource allocated for REG_LOGIN. + +Release mbuf pool resource prior to repurposing of the mailbox command +structure from REG_LOGIN to UNREG_LOGIN. + +Link: https://lore.kernel.org/r/20220911221505.117655-4-jsmart2021@gmail.com +Co-developed-by: Justin Tee +Signed-off-by: Justin Tee +Signed-off-by: James Smart +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/lpfc/lpfc_sli.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c +index 33373b20f819..002794975cd9 100644 +--- a/drivers/scsi/lpfc/lpfc_sli.c ++++ b/drivers/scsi/lpfc/lpfc_sli.c +@@ -2856,6 +2856,7 @@ void + lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) + { + struct lpfc_vport *vport = pmb->vport; ++ struct lpfc_dmabuf *mp; + struct lpfc_nodelist *ndlp; + struct Scsi_Host *shost; + uint16_t rpi, vpi; +@@ -2868,6 +2869,12 @@ lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) + if (!(phba->pport->load_flag & FC_UNLOADING) && + pmb->u.mb.mbxCommand == MBX_REG_LOGIN64 && + !pmb->u.mb.mbxStatus) { ++ mp = (struct lpfc_dmabuf *)pmb->ctx_buf; ++ if (mp) { ++ pmb->ctx_buf = NULL; ++ lpfc_mbuf_free(phba, mp->virt, mp->phys); ++ kfree(mp); ++ } + rpi = pmb->u.mb.un.varWords[0]; + vpi = pmb->u.mb.un.varRegLogin.vpi; + if (phba->sli_rev == LPFC_SLI_REV4) +-- +2.35.3 + diff --git a/patches.suse/scsi-lpfc-fix-multiple-nvme-remoteport-registration-calls-for-the.patch b/patches.suse/scsi-lpfc-fix-multiple-nvme-remoteport-registration-calls-for-the.patch new file mode 100644 index 0000000..baa64f7 --- /dev/null +++ b/patches.suse/scsi-lpfc-fix-multiple-nvme-remoteport-registration-calls-for-the.patch @@ -0,0 +1,167 @@ +From: James Smart +Date: Sun, 11 Sep 2022 15:14:57 -0700 +Subject: scsi: lpfc: Fix multiple NVMe remoteport registration calls for the + same NPort ID +Patch-mainline: v6.1-rc1 +Git-commit: 845363516bb75bc35089b4093d1fae139f2fffc6 +References: bsc#1203939 + +When a target makes the mistake of registering a FC4 type with the fabric, +but then rejects a PRLI of that type, the lpfc driver incorrectly retries +the PRLI causing multiple registrations with the transport. The driver +needs to detect the reject reason data and stop any retry. + +Rework the PRLI reject scenarios. + +Link: https://lore.kernel.org/r/20220911221505.117655-6-jsmart2021@gmail.com +Co-developed-by: Justin Tee +Signed-off-by: Justin Tee +Signed-off-by: James Smart +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/lpfc/lpfc_disc.h | 1 - + drivers/scsi/lpfc/lpfc_els.c | 76 +++++++++++++++++------------------ + drivers/scsi/lpfc/lpfc_hw.h | 1 + + 3 files changed, 37 insertions(+), 41 deletions(-) + +diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h +index fb945692d683..f82615d87c4b 100644 +--- a/drivers/scsi/lpfc/lpfc_disc.h ++++ b/drivers/scsi/lpfc/lpfc_disc.h +@@ -187,7 +187,6 @@ struct lpfc_node_rrq { + #define NLP_RNID_SND 0x00000400 /* sent RNID request for this entry */ + #define NLP_ELS_SND_MASK 0x000007e0 /* sent ELS request for this entry */ + #define NLP_NVMET_RECOV 0x00001000 /* NVMET auditing node for recovery. */ +-#define NLP_FCP_PRLI_RJT 0x00002000 /* Rport does not support FCP PRLI. */ + #define NLP_UNREG_INP 0x00008000 /* UNREG_RPI cmd is in progress */ + #define NLP_DROPPED 0x00010000 /* Init ref count has been dropped */ + #define NLP_DELAY_TMO 0x00020000 /* delay timeout is running for node */ +diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c +index 4c372553e2aa..642d90af4f09 100644 +--- a/drivers/scsi/lpfc/lpfc_els.c ++++ b/drivers/scsi/lpfc/lpfc_els.c +@@ -2200,10 +2200,6 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry) + if (!elsiocb) + return 1; + +- spin_lock_irq(&ndlp->lock); +- ndlp->nlp_flag &= ~NLP_FCP_PRLI_RJT; +- spin_unlock_irq(&ndlp->lock); +- + pcmd = (uint8_t *)elsiocb->cmd_dmabuf->virt; + + /* For PLOGI request, remainder of payload is service parameters */ +@@ -4676,47 +4672,52 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, + } + switch (stat.un.b.lsRjtRsnCode) { + case LSRJT_UNABLE_TPC: +- /* The driver has a VALID PLOGI but the rport has +- * rejected the PRLI - can't do it now. Delay +- * for 1 second and try again. +- * +- * However, if explanation is REQ_UNSUPPORTED there's +- * no point to retry PRLI. ++ /* Special case for PRLI LS_RJTs. Recall that lpfc ++ * uses a single routine to issue both PRLI FC4 types. ++ * If the PRLI is rejected because that FC4 type ++ * isn't really supported, don't retry and cause ++ * multiple transport registrations. Otherwise, parse ++ * the reason code/reason code explanation and take the ++ * appropriate action. + */ +- if ((cmd == ELS_CMD_PRLI || cmd == ELS_CMD_NVMEPRLI) && +- stat.un.b.lsRjtRsnCodeExp != +- LSEXP_REQ_UNSUPPORTED) { +- delay = 1000; +- maxretry = lpfc_max_els_tries + 1; +- retry = 1; +- break; +- } +- +- /* Legacy bug fix code for targets with PLOGI delays. */ +- if (stat.un.b.lsRjtRsnCodeExp == +- LSEXP_CMD_IN_PROGRESS) { ++ lpfc_printf_vlog(vport, KERN_INFO, ++ LOG_DISCOVERY | LOG_ELS | LOG_NODE, ++ "0153 ELS cmd x%x LS_RJT by x%x. " ++ "RsnCode x%x RsnCodeExp x%x\n", ++ cmd, did, stat.un.b.lsRjtRsnCode, ++ stat.un.b.lsRjtRsnCodeExp); ++ ++ switch (stat.un.b.lsRjtRsnCodeExp) { ++ case LSEXP_CANT_GIVE_DATA: ++ case LSEXP_CMD_IN_PROGRESS: + if (cmd == ELS_CMD_PLOGI) { + delay = 1000; + maxretry = 48; + } + retry = 1; + break; +- } +- if (stat.un.b.lsRjtRsnCodeExp == +- LSEXP_CANT_GIVE_DATA) { +- if (cmd == ELS_CMD_PLOGI) { ++ case LSEXP_REQ_UNSUPPORTED: ++ case LSEXP_NO_RSRC_ASSIGN: ++ /* These explanation codes get no retry. */ ++ if (cmd == ELS_CMD_PRLI || ++ cmd == ELS_CMD_NVMEPRLI) ++ break; ++ fallthrough; ++ default: ++ /* Limit the delay and retry action to a limited ++ * cmd set. There are other ELS commands where ++ * a retry is not expected. ++ */ ++ if (cmd == ELS_CMD_PLOGI || ++ cmd == ELS_CMD_PRLI || ++ cmd == ELS_CMD_NVMEPRLI) { + delay = 1000; +- maxretry = 48; ++ maxretry = lpfc_max_els_tries + 1; ++ retry = 1; + } +- retry = 1; +- break; +- } +- if (cmd == ELS_CMD_PLOGI) { +- delay = 1000; +- maxretry = lpfc_max_els_tries + 1; +- retry = 1; + break; + } ++ + if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) && + (cmd == ELS_CMD_FDISC) && + (stat.un.b.lsRjtRsnCodeExp == LSEXP_OUT_OF_RESOURCE)){ +@@ -4797,13 +4798,8 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, + */ + if (stat.un.b.lsRjtRsnCodeExp == + LSEXP_REQ_UNSUPPORTED) { +- if (cmd == ELS_CMD_PRLI) { +- spin_lock_irq(&ndlp->lock); +- ndlp->nlp_flag |= NLP_FCP_PRLI_RJT; +- spin_unlock_irq(&ndlp->lock); +- retry = 0; ++ if (cmd == ELS_CMD_PRLI) + goto out_retry; +- } + } + break; + } +diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h +index 071983e2cdfe..cbaf9a0f12c3 100644 +--- a/drivers/scsi/lpfc/lpfc_hw.h ++++ b/drivers/scsi/lpfc/lpfc_hw.h +@@ -703,6 +703,7 @@ struct ls_rjt { /* Structure is in Big Endian format */ + #define LSEXP_OUT_OF_RESOURCE 0x29 + #define LSEXP_CANT_GIVE_DATA 0x2A + #define LSEXP_REQ_UNSUPPORTED 0x2C ++#define LSEXP_NO_RSRC_ASSIGN 0x52 + uint8_t vendorUnique; /* FC Word 0, bit 0: 7 */ + } b; + } un; +-- +2.35.3 + diff --git a/patches.suse/scsi-lpfc-fix-prli_fc4_req-checks-in-prli-handling.patch b/patches.suse/scsi-lpfc-fix-prli_fc4_req-checks-in-prli-handling.patch new file mode 100644 index 0000000..64b7d86 --- /dev/null +++ b/patches.suse/scsi-lpfc-fix-prli_fc4_req-checks-in-prli-handling.patch @@ -0,0 +1,50 @@ +From: James Smart +Date: Sun, 11 Sep 2022 15:14:53 -0700 +Subject: scsi: lpfc: Fix prli_fc4_req checks in PRLI handling +Patch-mainline: v6.1-rc1 +Git-commit: 16ece56986638b8de22f47d009e9b0feec53c031 +References: bsc#1203939 + +The if statment check (prli_fc4_req & PRLI_NVME_TYPE) evaluates to true +when receiving a PRLI request for bogus FC4 type codes that happen to have +the 3rd or 5th bit set because PRLI_NVME_TYPE is 0x28. This leads to +sending a PRLI_NVME_ACC even for bogus FC4 type codes. + +Change the bitwise & check to an exact == type code check to ensure we send +PRLI_NVME_ACC only for NVME type coded PRLI requests. + +Link: https://lore.kernel.org/r/20220911221505.117655-2-jsmart2021@gmail.com +Co-developed-by: Justin Tee +Signed-off-by: Justin Tee +Signed-off-by: James Smart +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/lpfc/lpfc_els.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c +index 9e69de9eb992..4c372553e2aa 100644 +--- a/drivers/scsi/lpfc/lpfc_els.c ++++ b/drivers/scsi/lpfc/lpfc_els.c +@@ -6006,7 +6006,7 @@ lpfc_els_rsp_prli_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb, + if (prli_fc4_req == PRLI_FCP_TYPE) { + cmdsize = sizeof(uint32_t) + sizeof(PRLI); + elsrspcmd = (ELS_CMD_ACC | (ELS_CMD_PRLI & ~ELS_RSP_MASK)); +- } else if (prli_fc4_req & PRLI_NVME_TYPE) { ++ } else if (prli_fc4_req == PRLI_NVME_TYPE) { + cmdsize = sizeof(uint32_t) + sizeof(struct lpfc_nvme_prli); + elsrspcmd = (ELS_CMD_ACC | (ELS_CMD_NVMEPRLI & ~ELS_RSP_MASK)); + } else { +@@ -6069,7 +6069,7 @@ lpfc_els_rsp_prli_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb, + npr->ConfmComplAllowed = 1; + npr->prliType = PRLI_FCP_TYPE; + npr->initiatorFunc = 1; +- } else if (prli_fc4_req & PRLI_NVME_TYPE) { ++ } else if (prli_fc4_req == PRLI_NVME_TYPE) { + /* Respond with an NVME PRLI Type */ + npr_nvme = (struct lpfc_nvme_prli *) pcmd; + bf_set(prli_type_code, npr_nvme, PRLI_NVME_TYPE); +-- +2.35.3 + diff --git a/patches.suse/scsi-lpfc-fix-various-issues-reported-by-tools.patch b/patches.suse/scsi-lpfc-fix-various-issues-reported-by-tools.patch new file mode 100644 index 0000000..4a1473a --- /dev/null +++ b/patches.suse/scsi-lpfc-fix-various-issues-reported-by-tools.patch @@ -0,0 +1,523 @@ +From: James Smart +Date: Sun, 11 Sep 2022 15:15:04 -0700 +Subject: scsi: lpfc: Fix various issues reported by tools +Patch-mainline: v6.1-rc1 +Git-commit: a4de8356b68e54149ebdbe6e748e2726152b650c +References: bsc#1203939 + +This patch fixes below Smatch reported issues: + + 1. lpfc_hbadisc.c:3020 lpfc_mbx_cmpl_fcf_rr_read_fcf_rec() + error: uninitialized symbol 'vlan_id'. + + 2. lpfc_hbadisc.c:3121 lpfc_mbx_cmpl_read_fcf_rec() + error: uninitialized symbol 'vlan_id'. + + 3. lpfc_init.c:335 lpfc_dump_wakeup_param_cmpl() + warn: always true condition '(prg->dist < 4) => (0-3 < 4)' + + 4. lpfc_init.c:2419 lpfc_parse_vpd() + warn: inconsistent indenting. + + 5. lpfc_init.c:13248 lpfc_sli4_enable_msi() + warn: 'phba->pcidev->irq' 2147483648 can't fit into 65535 + 'eqhdl->irq' + + 6. lpfc_debugfs.c:5300 lpfc_idiag_extacc_avail_get() + error: uninitialized symbol 'ext_cnt' + + 7. lpfc_debugfs.c:5300 lpfc_idiag_extacc_avail_get() + error: uninitialized symbol 'ext_size' + + 8. lpfc_vmid.c:248 lpfc_vmid_get_appid() + warn: sleeping in atomic context. + + 9. lpfc_init.c:8342 lpfc_sli4_driver_resource_setup() + warn: missing error code 'rc'. + +10. lpfc_init.c:13573 lpfc_sli4_hba_unset() + warn: variable dereferenced before check 'phba->pport' (see + line 13546) + +11. lpfc_auth.c:1923 lpfc_auth_handle_dhchap_reply() + error: double free of 'hash_value' + +Fixes: + + 1. Initialize vlan_id to LPFC_FCOE_NULL_VID. + + 2. Initialize vlan_id to LPFC_FCOE_NULL_VID. + + 3. prg->dist is a 2 bit field. Its value can only be between 0-3. + Remove redundent check 'if (prg->dist < 4)'. + + 4. Fix inconsistent indenting. Moved logic into helper function + lpfc_fill_vpd(). + + 5. Define 'eqhdl->irq' as int value as pci_irq_vector() returns int. + Also, check for return value of pci_irq_vector() and log message in + case of failure. + + 6. Initialize 'ext_cnt' to 0. + + 7. Initialize 'ext_size' to 0. + + 8. Use alloc_percpu_gfp() with GFP_ATOMIC flag. + + 9. 'rc' was not updated when dma_pool_create() fails. Update 'rc = + -ENOMEM' when dma_pool_create() fails before calling goto statement. + +10. Add check for 'phba->pport' in lpfc_cpuhp_remove(). + +11. Initialize 'hash_value' to NULL, same like 'aug_chal' variable. + +Link: https://lore.kernel.org/r/20220911221505.117655-13-jsmart2021@gmail.com +Co-developed-by: Justin Tee +Signed-off-by: Justin Tee +Signed-off-by: James Smart +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/lpfc/lpfc_debugfs.c | 2 +- + drivers/scsi/lpfc/lpfc_hbadisc.c | 4 +- + drivers/scsi/lpfc/lpfc_init.c | 249 +++++++++++++++++-------------- + drivers/scsi/lpfc/lpfc_sli.c | 3 + + drivers/scsi/lpfc/lpfc_sli4.h | 4 +- + drivers/scsi/lpfc/lpfc_vmid.c | 4 +- + 6 files changed, 148 insertions(+), 118 deletions(-) + +diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c +index e37b028eae5f..f5252e45a48a 100644 +--- a/drivers/scsi/lpfc/lpfc_debugfs.c ++++ b/drivers/scsi/lpfc/lpfc_debugfs.c +@@ -5156,7 +5156,7 @@ lpfc_idiag_mbxacc_write(struct file *file, const char __user *buf, + static int + lpfc_idiag_extacc_avail_get(struct lpfc_hba *phba, char *pbuffer, int len) + { +- uint16_t ext_cnt, ext_size; ++ uint16_t ext_cnt = 0, ext_size = 0; + + len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, + "\nAvailable Extents Information:\n"); +diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c +index 2b79351dfd11..c7f834ba8edb 100644 +--- a/drivers/scsi/lpfc/lpfc_hbadisc.c ++++ b/drivers/scsi/lpfc/lpfc_hbadisc.c +@@ -2970,7 +2970,7 @@ lpfc_mbx_cmpl_fcf_rr_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) + uint32_t boot_flag, addr_mode; + uint16_t next_fcf_index, fcf_index; + uint16_t current_fcf_index; +- uint16_t vlan_id; ++ uint16_t vlan_id = LPFC_FCOE_NULL_VID; + int rc; + + /* If link state is not up, stop the roundrobin failover process */ +@@ -3075,7 +3075,7 @@ lpfc_mbx_cmpl_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) + struct fcf_record *new_fcf_record; + uint32_t boot_flag, addr_mode; + uint16_t fcf_index, next_fcf_index; +- uint16_t vlan_id; ++ uint16_t vlan_id = LPFC_FCOE_NULL_VID; + int rc; + + /* If link state is not up, no need to proceed */ +diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c +index 511220aa43f5..844dc8a75907 100644 +--- a/drivers/scsi/lpfc/lpfc_init.c ++++ b/drivers/scsi/lpfc/lpfc_init.c +@@ -325,8 +325,7 @@ lpfc_dump_wakeup_param_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq) + prog_id_word = pmboxq->u.mb.un.varWords[7]; + + /* Decode the Option rom version word to a readable string */ +- if (prg->dist < 4) +- dist = dist_char[prg->dist]; ++ dist = dist_char[prg->dist]; + + if ((prg->dist == 3) && (prg->num == 0)) + snprintf(phba->OptionROMVersion, 32, "%d.%d%d", +@@ -2258,6 +2257,101 @@ lpfc_handle_latt(struct lpfc_hba *phba) + return; + } + ++static void ++lpfc_fill_vpd(struct lpfc_hba *phba, uint8_t *vpd, int length, int *pindex) ++{ ++ int i, j; ++ ++ while (length > 0) { ++ /* Look for Serial Number */ ++ if ((vpd[*pindex] == 'S') && (vpd[*pindex + 1] == 'N')) { ++ *pindex += 2; ++ i = vpd[*pindex]; ++ *pindex += 1; ++ j = 0; ++ length -= (3+i); ++ while (i--) { ++ phba->SerialNumber[j++] = vpd[(*pindex)++]; ++ if (j == 31) ++ break; ++ } ++ phba->SerialNumber[j] = 0; ++ continue; ++ } else if ((vpd[*pindex] == 'V') && (vpd[*pindex + 1] == '1')) { ++ phba->vpd_flag |= VPD_MODEL_DESC; ++ *pindex += 2; ++ i = vpd[*pindex]; ++ *pindex += 1; ++ j = 0; ++ length -= (3+i); ++ while (i--) { ++ phba->ModelDesc[j++] = vpd[(*pindex)++]; ++ if (j == 255) ++ break; ++ } ++ phba->ModelDesc[j] = 0; ++ continue; ++ } else if ((vpd[*pindex] == 'V') && (vpd[*pindex + 1] == '2')) { ++ phba->vpd_flag |= VPD_MODEL_NAME; ++ *pindex += 2; ++ i = vpd[*pindex]; ++ *pindex += 1; ++ j = 0; ++ length -= (3+i); ++ while (i--) { ++ phba->ModelName[j++] = vpd[(*pindex)++]; ++ if (j == 79) ++ break; ++ } ++ phba->ModelName[j] = 0; ++ continue; ++ } else if ((vpd[*pindex] == 'V') && (vpd[*pindex + 1] == '3')) { ++ phba->vpd_flag |= VPD_PROGRAM_TYPE; ++ *pindex += 2; ++ i = vpd[*pindex]; ++ *pindex += 1; ++ j = 0; ++ length -= (3+i); ++ while (i--) { ++ phba->ProgramType[j++] = vpd[(*pindex)++]; ++ if (j == 255) ++ break; ++ } ++ phba->ProgramType[j] = 0; ++ continue; ++ } else if ((vpd[*pindex] == 'V') && (vpd[*pindex + 1] == '4')) { ++ phba->vpd_flag |= VPD_PORT; ++ *pindex += 2; ++ i = vpd[*pindex]; ++ *pindex += 1; ++ j = 0; ++ length -= (3 + i); ++ while (i--) { ++ if ((phba->sli_rev == LPFC_SLI_REV4) && ++ (phba->sli4_hba.pport_name_sta == ++ LPFC_SLI4_PPNAME_GET)) { ++ j++; ++ (*pindex)++; ++ } else ++ phba->Port[j++] = vpd[(*pindex)++]; ++ if (j == 19) ++ break; ++ } ++ if ((phba->sli_rev != LPFC_SLI_REV4) || ++ (phba->sli4_hba.pport_name_sta == ++ LPFC_SLI4_PPNAME_NON)) ++ phba->Port[j] = 0; ++ continue; ++ } else { ++ *pindex += 2; ++ i = vpd[*pindex]; ++ *pindex += 1; ++ *pindex += i; ++ length -= (3 + i); ++ } ++ } ++} ++ + /** + * lpfc_parse_vpd - Parse VPD (Vital Product Data) + * @phba: pointer to lpfc hba data structure. +@@ -2277,7 +2371,7 @@ lpfc_parse_vpd(struct lpfc_hba *phba, uint8_t *vpd, int len) + { + uint8_t lenlo, lenhi; + int Length; +- int i, j; ++ int i; + int finished = 0; + int index = 0; + +@@ -2310,101 +2404,10 @@ lpfc_parse_vpd(struct lpfc_hba *phba, uint8_t *vpd, int len) + Length = ((((unsigned short)lenhi) << 8) + lenlo); + if (Length > len - index) + Length = len - index; +- while (Length > 0) { +- /* Look for Serial Number */ +- if ((vpd[index] == 'S') && (vpd[index+1] == 'N')) { +- index += 2; +- i = vpd[index]; +- index += 1; +- j = 0; +- Length -= (3+i); +- while(i--) { +- phba->SerialNumber[j++] = vpd[index++]; +- if (j == 31) +- break; +- } +- phba->SerialNumber[j] = 0; +- continue; +- } +- else if ((vpd[index] == 'V') && (vpd[index+1] == '1')) { +- phba->vpd_flag |= VPD_MODEL_DESC; +- index += 2; +- i = vpd[index]; +- index += 1; +- j = 0; +- Length -= (3+i); +- while(i--) { +- phba->ModelDesc[j++] = vpd[index++]; +- if (j == 255) +- break; +- } +- phba->ModelDesc[j] = 0; +- continue; +- } +- else if ((vpd[index] == 'V') && (vpd[index+1] == '2')) { +- phba->vpd_flag |= VPD_MODEL_NAME; +- index += 2; +- i = vpd[index]; +- index += 1; +- j = 0; +- Length -= (3+i); +- while(i--) { +- phba->ModelName[j++] = vpd[index++]; +- if (j == 79) +- break; +- } +- phba->ModelName[j] = 0; +- continue; +- } +- else if ((vpd[index] == 'V') && (vpd[index+1] == '3')) { +- phba->vpd_flag |= VPD_PROGRAM_TYPE; +- index += 2; +- i = vpd[index]; +- index += 1; +- j = 0; +- Length -= (3+i); +- while(i--) { +- phba->ProgramType[j++] = vpd[index++]; +- if (j == 255) +- break; +- } +- phba->ProgramType[j] = 0; +- continue; +- } +- else if ((vpd[index] == 'V') && (vpd[index+1] == '4')) { +- phba->vpd_flag |= VPD_PORT; +- index += 2; +- i = vpd[index]; +- index += 1; +- j = 0; +- Length -= (3+i); +- while(i--) { +- if ((phba->sli_rev == LPFC_SLI_REV4) && +- (phba->sli4_hba.pport_name_sta == +- LPFC_SLI4_PPNAME_GET)) { +- j++; +- index++; +- } else +- phba->Port[j++] = vpd[index++]; +- if (j == 19) +- break; +- } +- if ((phba->sli_rev != LPFC_SLI_REV4) || +- (phba->sli4_hba.pport_name_sta == +- LPFC_SLI4_PPNAME_NON)) +- phba->Port[j] = 0; +- continue; +- } +- else { +- index += 2; +- i = vpd[index]; +- index += 1; +- index += i; +- Length -= (3 + i); +- } +- } +- finished = 0; +- break; ++ ++ lpfc_fill_vpd(phba, vpd, Length, &index); ++ finished = 0; ++ break; + case 0x78: + finished = 1; + break; +@@ -8304,8 +8307,10 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) + &phba->pcidev->dev, + phba->cfg_sg_dma_buf_size, + i, 0); +- if (!phba->lpfc_sg_dma_buf_pool) ++ if (!phba->lpfc_sg_dma_buf_pool) { ++ rc = -ENOMEM; + goto out_free_bsmbx; ++ } + + phba->lpfc_cmd_rsp_buf_pool = + dma_pool_create("lpfc_cmd_rsp_buf_pool", +@@ -8313,8 +8318,10 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) + sizeof(struct fcp_cmnd) + + sizeof(struct fcp_rsp), + i, 0); +- if (!phba->lpfc_cmd_rsp_buf_pool) ++ if (!phba->lpfc_cmd_rsp_buf_pool) { ++ rc = -ENOMEM; + goto out_free_sg_dma_buf; ++ } + + mempool_free(mboxq, phba->mbox_mem_pool); + +@@ -12402,7 +12409,7 @@ lpfc_hba_eq_hdl_array_init(struct lpfc_hba *phba) + + for (i = 0; i < phba->cfg_irq_chann; i++) { + eqhdl = lpfc_get_eq_hdl(i); +- eqhdl->irq = LPFC_VECTOR_MAP_EMPTY; ++ eqhdl->irq = LPFC_IRQ_EMPTY; + eqhdl->phba = phba; + } + } +@@ -12775,7 +12782,7 @@ static void __lpfc_cpuhp_remove(struct lpfc_hba *phba) + + static void lpfc_cpuhp_remove(struct lpfc_hba *phba) + { +- if (phba->pport->fc_flag & FC_OFFLINE_MODE) ++ if (phba->pport && (phba->pport->fc_flag & FC_OFFLINE_MODE)) + return; + + __lpfc_cpuhp_remove(phba); +@@ -13039,9 +13046,17 @@ lpfc_sli4_enable_msix(struct lpfc_hba *phba) + LPFC_DRIVER_HANDLER_NAME"%d", index); + + eqhdl->idx = index; +- rc = request_irq(pci_irq_vector(phba->pcidev, index), +- &lpfc_sli4_hba_intr_handler, 0, +- name, eqhdl); ++ rc = pci_irq_vector(phba->pcidev, index); ++ if (rc < 0) { ++ lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, ++ "0489 MSI-X fast-path (%d) " ++ "pci_irq_vec failed (%d)\n", index, rc); ++ goto cfg_fail_out; ++ } ++ eqhdl->irq = rc; ++ ++ rc = request_irq(eqhdl->irq, &lpfc_sli4_hba_intr_handler, 0, ++ name, eqhdl); + if (rc) { + lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, + "0486 MSI-X fast-path (%d) " +@@ -13049,8 +13064,6 @@ lpfc_sli4_enable_msix(struct lpfc_hba *phba) + goto cfg_fail_out; + } + +- eqhdl->irq = pci_irq_vector(phba->pcidev, index); +- + if (aff_mask) { + /* If found a neighboring online cpu, set affinity */ + if (cpu_select < nr_cpu_ids) +@@ -13167,7 +13180,14 @@ lpfc_sli4_enable_msi(struct lpfc_hba *phba) + } + + eqhdl = lpfc_get_eq_hdl(0); +- eqhdl->irq = pci_irq_vector(phba->pcidev, 0); ++ rc = pci_irq_vector(phba->pcidev, 0); ++ if (rc < 0) { ++ pci_free_irq_vectors(phba->pcidev); ++ lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, ++ "0496 MSI pci_irq_vec failed (%d)\n", rc); ++ return rc; ++ } ++ eqhdl->irq = rc; + + cpu = cpumask_first(cpu_present_mask); + lpfc_assign_eq_map_info(phba, 0, LPFC_CPU_FIRST_IRQ, cpu); +@@ -13194,8 +13214,8 @@ lpfc_sli4_enable_msi(struct lpfc_hba *phba) + * MSI-X -> MSI -> IRQ. + * + * Return codes +- * 0 - successful +- * other values - error ++ * Interrupt mode (2, 1, 0) - successful ++ * LPFC_INTR_ERROR - error + **/ + static uint32_t + lpfc_sli4_enable_intr(struct lpfc_hba *phba, uint32_t cfg_mode) +@@ -13240,7 +13260,14 @@ lpfc_sli4_enable_intr(struct lpfc_hba *phba, uint32_t cfg_mode) + intr_mode = 0; + + eqhdl = lpfc_get_eq_hdl(0); +- eqhdl->irq = pci_irq_vector(phba->pcidev, 0); ++ retval = pci_irq_vector(phba->pcidev, 0); ++ if (retval < 0) { ++ lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, ++ "0502 INTR pci_irq_vec failed (%d)\n", ++ retval); ++ return LPFC_INTR_ERROR; ++ } ++ eqhdl->irq = retval; + + cpu = cpumask_first(cpu_present_mask); + lpfc_assign_eq_map_info(phba, 0, LPFC_CPU_FIRST_IRQ, +diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c +index 06987d4013d5..99d06dc7ddf6 100644 +--- a/drivers/scsi/lpfc/lpfc_sli.c ++++ b/drivers/scsi/lpfc/lpfc_sli.c +@@ -6215,6 +6215,9 @@ lpfc_sli4_get_avail_extnt_rsrc(struct lpfc_hba *phba, uint16_t type, + struct lpfc_mbx_get_rsrc_extent_info *rsrc_info; + LPFC_MBOXQ_t *mbox; + ++ *extnt_count = 0; ++ *extnt_size = 0; ++ + mbox = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); + if (!mbox) + return -ENOMEM; +diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h +index 1ddad5b170a6..cbb1aa1cf025 100644 +--- a/drivers/scsi/lpfc/lpfc_sli4.h ++++ b/drivers/scsi/lpfc/lpfc_sli4.h +@@ -489,7 +489,7 @@ struct lpfc_hba; + #define LPFC_SLI4_HANDLER_NAME_SZ 16 + struct lpfc_hba_eq_hdl { + uint32_t idx; +- uint16_t irq; ++ int irq; + char handler_name[LPFC_SLI4_HANDLER_NAME_SZ]; + struct lpfc_hba *phba; + struct lpfc_queue *eq; +@@ -611,6 +611,8 @@ struct lpfc_vector_map_info { + }; + #define LPFC_VECTOR_MAP_EMPTY 0xffff + ++#define LPFC_IRQ_EMPTY 0xffffffff ++ + /* Multi-XRI pool */ + #define XRI_BATCH 8 + +diff --git a/drivers/scsi/lpfc/lpfc_vmid.c b/drivers/scsi/lpfc/lpfc_vmid.c +index f64ced04b912..ed1d7f7b88a3 100644 +--- a/drivers/scsi/lpfc/lpfc_vmid.c ++++ b/drivers/scsi/lpfc/lpfc_vmid.c +@@ -245,9 +245,7 @@ int lpfc_vmid_get_appid(struct lpfc_vport *vport, char *uuid, + /* allocate the per cpu variable for holding */ + /* the last access time stamp only if VMID is enabled */ + if (!vmp->last_io_time) +- vmp->last_io_time = __alloc_percpu(sizeof(u64), +- __alignof__(struct +- lpfc_vmid)); ++ vmp->last_io_time = alloc_percpu_gfp(u64, GFP_ATOMIC); + if (!vmp->last_io_time) { + hash_del(&vmp->hnode); + vmp->flag = LPFC_VMID_SLOT_FREE; +-- +2.35.3 + diff --git a/patches.suse/scsi-lpfc-move-scsi_host_template-outside-dynamically.patch b/patches.suse/scsi-lpfc-move-scsi_host_template-outside-dynamically.patch new file mode 100644 index 0000000..405f846 --- /dev/null +++ b/patches.suse/scsi-lpfc-move-scsi_host_template-outside-dynamically.patch @@ -0,0 +1,181 @@ +From: James Smart +Date: Sun, 11 Sep 2022 15:14:58 -0700 +Subject: scsi: lpfc: Move scsi_host_template outside dynamically + allocated/freed phba +Patch-mainline: v6.1-rc1 +Git-commit: 6e5c5d246e6c16127327eeecf61ef2cf21a94ce5 +References: bsc#1185032 bsc#1203939 + +On a PCI hotplug capable system, it is possible for scsi_device_put() to +happen after lpfc_pci_remove_one() is called. As a result, the +sdev->host->hostt->module dereference is for a previously freed memory +location because the phba structure containing the hostt template was +already freed when lpfc_pci_remove_one() returned. + +Since the lpfc module is still loaded during power slot disable, all +scsi_host_templates should be declared as part of the global data segment +instead of inside the heap allocated phba structure. This way the +sdev->host->hostt memory area is always valid as long as the module is +loaded regardless if PCI hotplug dynamically allocates or frees phba +structures. + +Move all scsi_host_templates in the phba structure to global variables. +Create a small helper routine to determine appropriate sg_tablesize during +shost allocation. + +Link: https://lore.kernel.org/r/20220911221505.117655-7-jsmart2021@gmail.com +Co-developed-by: Dwip N. Banerjee +Signed-off-by: Dwip N. Banerjee +Co-developed-by: Daniel Wagner +Signed-off-by: Daniel Wagner +Co-developed-by: Justin Tee +Signed-off-by: Justin Tee +Signed-off-by: James Smart +Signed-off-by: Martin K. Petersen +--- + drivers/scsi/lpfc/lpfc.h | 4 --- + drivers/scsi/lpfc/lpfc_crtn.h | 1 + drivers/scsi/lpfc/lpfc_init.c | 50 ++++++++++++++++-------------------------- + drivers/scsi/lpfc/lpfc_scsi.c | 27 ++++++++++++++++++++++ + 4 files changed, 48 insertions(+), 34 deletions(-) + +--- a/drivers/scsi/lpfc/lpfc_crtn.h ++++ b/drivers/scsi/lpfc/lpfc_crtn.h +@@ -462,6 +462,7 @@ extern struct device_attribute *lpfc_hba + extern struct device_attribute *lpfc_vport_attrs[]; + extern struct scsi_host_template lpfc_template; + extern struct scsi_host_template lpfc_template_nvme; ++extern struct scsi_host_template lpfc_vport_template; + extern struct fc_function_template lpfc_transport_functions; + extern struct fc_function_template lpfc_vport_transport_functions; + +--- a/drivers/scsi/lpfc/lpfc.h ++++ b/drivers/scsi/lpfc/lpfc.h +@@ -1597,10 +1597,6 @@ struct lpfc_hba { + + char os_host_name[MAXHOSTNAMELEN]; + +- /* SCSI host template information - for physical port */ +- struct scsi_host_template port_template; +- /* SCSI host template information - for all vports */ +- struct scsi_host_template vport_template; + atomic_t dbg_log_idx; + atomic_t dbg_log_cnt; + atomic_t dbg_log_dmping; +--- a/drivers/scsi/lpfc/lpfc_init.c ++++ b/drivers/scsi/lpfc/lpfc_init.c +@@ -4613,6 +4613,17 @@ lpfc_get_wwpn(struct lpfc_hba *phba) + return rol64(wwn, 32); + } + ++static unsigned short lpfc_get_sg_tablesize(struct lpfc_hba *phba) ++{ ++ if (phba->sli_rev == LPFC_SLI_REV4) ++ if (phba->cfg_xpsgl && !phba->nvmet_support) ++ return LPFC_MAX_SG_TABLESIZE; ++ else ++ return phba->cfg_scsi_seg_cnt; ++ else ++ return phba->cfg_sg_seg_cnt; ++} ++ + /** + * lpfc_vmid_res_alloc - Allocates resources for VMID + * @phba: pointer to lpfc hba data structure. +@@ -4715,42 +4726,26 @@ lpfc_create_port(struct lpfc_hba *phba, + + /* Seed template for SCSI host registration */ + if (dev == &phba->pcidev->dev) { +- template = &phba->port_template; +- + if (phba->cfg_enable_fc4_type & LPFC_ENABLE_FCP) { + /* Seed physical port template */ +- memcpy(template, &lpfc_template, sizeof(*template)); ++ template = &lpfc_template; + + if (use_no_reset_hba) + /* template is for a no reset SCSI Host */ + template->eh_host_reset_handler = NULL; + +- /* Template for all vports this physical port creates */ +- memcpy(&phba->vport_template, &lpfc_template, +- sizeof(*template)); +- phba->vport_template.shost_attrs = lpfc_vport_attrs; +- phba->vport_template.eh_bus_reset_handler = NULL; +- phba->vport_template.eh_host_reset_handler = NULL; +- phba->vport_template.vendor_id = 0; +- +- /* Initialize the host templates with updated value */ +- if (phba->sli_rev == LPFC_SLI_REV4) { +- template->sg_tablesize = phba->cfg_scsi_seg_cnt; +- phba->vport_template.sg_tablesize = +- phba->cfg_scsi_seg_cnt; +- } else { +- template->sg_tablesize = phba->cfg_sg_seg_cnt; +- phba->vport_template.sg_tablesize = +- phba->cfg_sg_seg_cnt; +- } +- ++ /* Seed updated value of sg_tablesize */ ++ template->sg_tablesize = lpfc_get_sg_tablesize(phba); + } else { + /* NVMET is for physical port only */ +- memcpy(template, &lpfc_template_nvme, +- sizeof(*template)); ++ template = &lpfc_template_nvme; + } + } else { +- template = &phba->vport_template; ++ /* Seed vport template */ ++ template = &lpfc_vport_template; ++ ++ /* Seed updated value of sg_tablesize */ ++ template->sg_tablesize = lpfc_get_sg_tablesize(phba); + } + + shost = scsi_host_alloc(template, sizeof(struct lpfc_vport)); +@@ -4783,11 +4778,6 @@ lpfc_create_port(struct lpfc_hba *phba, + + shost->dma_boundary = + phba->sli4_hba.pc_sli4_params.sge_supp_len-1; +- +- if (phba->cfg_xpsgl && !phba->nvmet_support) +- shost->sg_tablesize = LPFC_MAX_SG_TABLESIZE; +- else +- shost->sg_tablesize = phba->cfg_scsi_seg_cnt; + } else + /* SLI-3 has a limited number of hardware queues (3), + * thus there is only one for FCP processing. +--- a/drivers/scsi/lpfc/lpfc_scsi.c ++++ b/drivers/scsi/lpfc/lpfc_scsi.c +@@ -6806,3 +6806,30 @@ struct scsi_host_template lpfc_template + .change_queue_depth = scsi_change_queue_depth, + .track_queue_depth = 1, + }; ++ ++struct scsi_host_template lpfc_vport_template = { ++ .module = THIS_MODULE, ++ .name = LPFC_DRIVER_NAME, ++ .proc_name = LPFC_DRIVER_NAME, ++ .info = lpfc_info, ++ .queuecommand = lpfc_queuecommand, ++ .eh_timed_out = fc_eh_timed_out, ++ .eh_should_retry_cmd = fc_eh_should_retry_cmd, ++ .eh_abort_handler = lpfc_abort_handler, ++ .eh_device_reset_handler = lpfc_device_reset_handler, ++ .eh_target_reset_handler = lpfc_target_reset_handler, ++ .eh_bus_reset_handler = NULL, ++ .eh_host_reset_handler = NULL, ++ .slave_alloc = lpfc_slave_alloc, ++ .slave_configure = lpfc_slave_configure, ++ .slave_destroy = lpfc_slave_destroy, ++ .scan_finished = lpfc_scan_finished, ++ .this_id = -1, ++ .sg_tablesize = LPFC_DEFAULT_SG_SEG_CNT, ++ .cmd_per_lun = LPFC_CMD_PER_LUN, ++ .shost_attrs = lpfc_hba_attrs, ++ .max_sectors = 0xFFFFFFFF, ++ .vendor_id = 0, ++ .change_queue_depth = scsi_change_queue_depth, ++ .track_queue_depth = 1, ++}; diff --git a/patches.suse/scsi-lpfc-remove-the-unneeded-result-variable.patch b/patches.suse/scsi-lpfc-remove-the-unneeded-result-variable.patch new file mode 100644 index 0000000..5f3346d --- /dev/null +++ b/patches.suse/scsi-lpfc-remove-the-unneeded-result-variable.patch @@ -0,0 +1,41 @@ +From: ye xingchen +Date: Wed, 24 Aug 2022 07:50:17 +0000 +Subject: scsi: lpfc: Remove the unneeded result variable +Patch-mainline: v6.1-rc1 +Git-commit: 7fd080e19cb841244fe36085e41331cd04b85515 +References: bsc#1203939 + +Return the value from lpfc_sli4_issue_wqe() directly instead of storing it +in another redundant variable. + +Link: https://lore.kernel.org/r/20220824075017.221244-1-ye.xingchen@zte.com.cn +Reported-by: Zeal Robot +Reviewed-by: James Smart +Signed-off-by: ye xingchen +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/lpfc/lpfc_sli.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c +index 0f2b6ac56baf..33373b20f819 100644 +--- a/drivers/scsi/lpfc/lpfc_sli.c ++++ b/drivers/scsi/lpfc/lpfc_sli.c +@@ -10504,12 +10504,10 @@ static int + __lpfc_sli_issue_fcp_io_s4(struct lpfc_hba *phba, uint32_t ring_number, + struct lpfc_iocbq *piocb, uint32_t flag) + { +- int rc; + struct lpfc_io_buf *lpfc_cmd = piocb->io_buf; + + lpfc_prep_embed_io(phba, lpfc_cmd); +- rc = lpfc_sli4_issue_wqe(phba, lpfc_cmd->hdwq, piocb); +- return rc; ++ return lpfc_sli4_issue_wqe(phba, lpfc_cmd->hdwq, piocb); + } + + void +-- +2.35.3 + diff --git a/patches.suse/scsi-lpfc-remove-unneeded-result-variable.patch b/patches.suse/scsi-lpfc-remove-unneeded-result-variable.patch new file mode 100644 index 0000000..8abb795 --- /dev/null +++ b/patches.suse/scsi-lpfc-remove-unneeded-result-variable.patch @@ -0,0 +1,46 @@ +From: ye xingchen +Date: Wed, 24 Aug 2022 07:51:23 +0000 +Subject: scsi: lpfc: Remove unneeded result variable +Patch-mainline: v6.1-rc1 +Git-commit: de05e4843cce5f4b385f60acfa690eb94af923b8 +References: bsc#1203939 + +Return the value from lpfc_issue_reg_vfi() directly instead of storing it +in another redundant variable. + +Link: https://lore.kernel.org/r/20220824075123.221316-1-ye.xingchen@zte.com.cn +Reported-by: Zeal Robot +Reviewed-by: James Smart +Signed-off-by: ye xingchen +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/lpfc/lpfc_bsg.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c +index 9be3bb01a8ec..ac0c7ccf2eae 100644 +--- a/drivers/scsi/lpfc/lpfc_bsg.c ++++ b/drivers/scsi/lpfc/lpfc_bsg.c +@@ -1977,8 +1977,6 @@ lpfc_sli4_bsg_set_loopback_mode(struct lpfc_hba *phba, int mode, + static int + lpfc_sli4_diag_fcport_reg_setup(struct lpfc_hba *phba) + { +- int rc; +- + if (phba->pport->fc_flag & FC_VFI_REGISTERED) { + lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC, + "3136 Port still had vfi registered: " +@@ -1988,8 +1986,7 @@ lpfc_sli4_diag_fcport_reg_setup(struct lpfc_hba *phba) + phba->vpi_ids[phba->pport->vpi]); + return -EINVAL; + } +- rc = lpfc_issue_reg_vfi(phba->pport); +- return rc; ++ return lpfc_issue_reg_vfi(phba->pport); + } + + /** +-- +2.35.3 + diff --git a/patches.suse/scsi-lpfc-rename-mp-bmp-dma-buffers-to-rq-rsp-in-lpfc_fdmi_cmd.patch b/patches.suse/scsi-lpfc-rename-mp-bmp-dma-buffers-to-rq-rsp-in-lpfc_fdmi_cmd.patch new file mode 100644 index 0000000..ea498c8 --- /dev/null +++ b/patches.suse/scsi-lpfc-rename-mp-bmp-dma-buffers-to-rq-rsp-in-lpfc_fdmi_cmd.patch @@ -0,0 +1,141 @@ +From: James Smart +Date: Sun, 11 Sep 2022 15:15:00 -0700 +Subject: scsi: lpfc: Rename mp/bmp dma buffers to rq/rsp in lpfc_fdmi_cmd +Patch-mainline: v6.1-rc1 +Git-commit: d8cdd33a66dc8cc8d7f83b743bbdcef30a5624c0 +References: bsc#1203939 + +Clarify naming of the mp/bmp dma buffers: + + - Rename mp to rq as it is the request buffer + + - Rename bmp to rsp as it is the response buffer + +This reduces confusion about what the buffer content is based on their +name. + +Link: https://lore.kernel.org/r/20220911221505.117655-9-jsmart2021@gmail.com +Co-developed-by: Justin Tee +Signed-off-by: Justin Tee +Signed-off-by: James Smart +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/lpfc/lpfc_ct.c | 63 +++++++++++++++++++------------------ + 1 file changed, 32 insertions(+), 31 deletions(-) + +diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c +index aad63adfc9ce..44c2ec543845 100644 +--- a/drivers/scsi/lpfc/lpfc_ct.c ++++ b/drivers/scsi/lpfc/lpfc_ct.c +@@ -3524,9 +3524,9 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, + int cmdcode, uint32_t new_mask) + { + struct lpfc_hba *phba = vport->phba; +- struct lpfc_dmabuf *mp, *bmp; ++ struct lpfc_dmabuf *rq, *rsp; + struct lpfc_sli_ct_request *CtReq; +- struct ulp_bde64 *bpl; ++ struct ulp_bde64_le *bde; + uint32_t bit_pos; + uint32_t size; + uint32_t rsp_size; +@@ -3546,25 +3546,25 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, + + /* fill in BDEs for command */ + /* Allocate buffer for command payload */ +- mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); +- if (!mp) ++ rq = kmalloc(sizeof(*rq), GFP_KERNEL); ++ if (!rq) + goto fdmi_cmd_exit; + +- mp->virt = lpfc_mbuf_alloc(phba, 0, &(mp->phys)); +- if (!mp->virt) +- goto fdmi_cmd_free_mp; ++ rq->virt = lpfc_mbuf_alloc(phba, 0, &rq->phys); ++ if (!rq->virt) ++ goto fdmi_cmd_free_rq; + + /* Allocate buffer for Buffer ptr list */ +- bmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); +- if (!bmp) +- goto fdmi_cmd_free_mpvirt; ++ rsp = kmalloc(sizeof(*rsp), GFP_KERNEL); ++ if (!rsp) ++ goto fdmi_cmd_free_rqvirt; + +- bmp->virt = lpfc_mbuf_alloc(phba, 0, &(bmp->phys)); +- if (!bmp->virt) +- goto fdmi_cmd_free_bmp; ++ rsp->virt = lpfc_mbuf_alloc(phba, 0, &rsp->phys); ++ if (!rsp->virt) ++ goto fdmi_cmd_free_rsp; + +- INIT_LIST_HEAD(&mp->list); +- INIT_LIST_HEAD(&bmp->list); ++ INIT_LIST_HEAD(&rq->list); ++ INIT_LIST_HEAD(&rsp->list); + + /* FDMI request */ + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, +@@ -3572,7 +3572,7 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, + cmdcode, new_mask, vport->fdmi_port_mask, + vport->fc_flag, vport->port_state); + +- CtReq = (struct lpfc_sli_ct_request *)mp->virt; ++ CtReq = (struct lpfc_sli_ct_request *)rq->virt; + + /* First populate the CT_IU preamble */ + memset(CtReq, 0, sizeof(struct lpfc_sli_ct_request)); +@@ -3730,31 +3730,32 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, + lpfc_printf_vlog(vport, KERN_WARNING, LOG_DISCOVERY, + "0298 FDMI cmdcode x%x not supported\n", + cmdcode); +- goto fdmi_cmd_free_bmpvirt; ++ goto fdmi_cmd_free_rspvirt; + } + CtReq->CommandResponse.bits.Size = cpu_to_be16(rsp_size); + +- bpl = (struct ulp_bde64 *)bmp->virt; +- bpl->addrHigh = le32_to_cpu(putPaddrHigh(mp->phys)); +- bpl->addrLow = le32_to_cpu(putPaddrLow(mp->phys)); +- bpl->tus.f.bdeFlags = 0; +- bpl->tus.f.bdeSize = size; ++ bde = (struct ulp_bde64_le *)rsp->virt; ++ bde->addr_high = cpu_to_le32(putPaddrHigh(rq->phys)); ++ bde->addr_low = cpu_to_le32(putPaddrLow(rq->phys)); ++ bde->type_size = cpu_to_le32(ULP_BDE64_TYPE_BDE_64 << ++ ULP_BDE64_TYPE_SHIFT); ++ bde->type_size |= cpu_to_le32(size); + + /* + * The lpfc_ct_cmd/lpfc_get_req shall increment ndlp reference count + * to hold ndlp reference for the corresponding callback function. + */ +- if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, rsp_size, 0)) ++ if (!lpfc_ct_cmd(vport, rq, rsp, ndlp, cmpl, rsp_size, 0)) + return 0; + +-fdmi_cmd_free_bmpvirt: +- lpfc_mbuf_free(phba, bmp->virt, bmp->phys); +-fdmi_cmd_free_bmp: +- kfree(bmp); +-fdmi_cmd_free_mpvirt: +- lpfc_mbuf_free(phba, mp->virt, mp->phys); +-fdmi_cmd_free_mp: +- kfree(mp); ++fdmi_cmd_free_rspvirt: ++ lpfc_mbuf_free(phba, rsp->virt, rsp->phys); ++fdmi_cmd_free_rsp: ++ kfree(rsp); ++fdmi_cmd_free_rqvirt: ++ lpfc_mbuf_free(phba, rq->virt, rq->phys); ++fdmi_cmd_free_rq: ++ kfree(rq); + fdmi_cmd_exit: + /* Issue FDMI request failed */ + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, +-- +2.35.3 + diff --git a/patches.suse/scsi-lpfc-rework-fdmi-attribute-registration-for-unintential.patch b/patches.suse/scsi-lpfc-rework-fdmi-attribute-registration-for-unintential.patch new file mode 100644 index 0000000..6313682 --- /dev/null +++ b/patches.suse/scsi-lpfc-rework-fdmi-attribute-registration-for-unintential.patch @@ -0,0 +1,1435 @@ +From: James Smart +Date: Sun, 11 Sep 2022 15:15:02 -0700 +Subject: scsi: lpfc: Rework FDMI attribute registration for unintential + padding +Patch-mainline: v6.1-rc1 +Git-commit: 045c58c87560b2f9e44fe84e62ce68625a937fa7 +References: bsc#1203939 + +Removed the lpfc_fdmi_attr_entry and lpfc_fdmi_attr_def structures that had +a union causing unintentional zero padding, which required the usage of +__packed. They are replaced with explicit lpfc_fdmi_attr_u32, +lpfc_fdmi_attr_wwn, lpfc_fdmi_attr_fc4types, and lpfc_fdmi_attr_string +structure defines instead of living in a union. This rids of ambiguous +compiler zero padding, and entailed cleaning up bitwise endian +declarations. + +As such, all FDMI attribute registration routines are replaced with generic +void *arg and handlers for each of the newly defined attribute structure +types. + +Link: https://lore.kernel.org/r/20220911221505.117655-11-jsmart2021@gmail.com +Co-developed-by: Justin Tee +Signed-off-by: Justin Tee +Signed-off-by: James Smart +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/lpfc/lpfc_ct.c | 961 ++++++++++++------------------------ + drivers/scsi/lpfc/lpfc_hw.h | 58 ++- + 2 files changed, 350 insertions(+), 669 deletions(-) + +diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c +index 8979e0e164b3..75fd2bfc212b 100644 +--- a/drivers/scsi/lpfc/lpfc_ct.c ++++ b/drivers/scsi/lpfc/lpfc_ct.c +@@ -2501,420 +2501,298 @@ lpfc_fdmi_change_check(struct lpfc_vport *vport) + } + } + +-/* Routines for all individual HBA attributes */ +-static int +-lpfc_fdmi_hba_attr_wwnn(struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad) ++static inline int ++lpfc_fdmi_set_attr_u32(void *attr, uint16_t attrtype, uint32_t attrval) + { +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t size; ++ struct lpfc_fdmi_attr_u32 *ae = attr; ++ int size = sizeof(*ae); + +- ae = &ad->AttrValue; +- memset(ae, 0, sizeof(*ae)); ++ ae->type = cpu_to_be16(attrtype); ++ ae->len = cpu_to_be16(size); ++ ae->value_u32 = cpu_to_be32(attrval); + +- memcpy(&ae->un.AttrWWN, &vport->fc_sparam.nodeName, +- sizeof(struct lpfc_name)); +- size = FOURBYTES + sizeof(struct lpfc_name); +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RHBA_NODENAME); + return size; + } +-static int +-lpfc_fdmi_hba_attr_manufacturer(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++ ++static inline int ++lpfc_fdmi_set_attr_wwn(void *attr, uint16_t attrtype, struct lpfc_name *wwn) + { +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t len, size; ++ struct lpfc_fdmi_attr_wwn *ae = attr; ++ int size = sizeof(*ae); + +- ae = &ad->AttrValue; +- memset(ae, 0, sizeof(*ae)); ++ ae->type = cpu_to_be16(attrtype); ++ ae->len = cpu_to_be16(size); ++ /* WWN's assumed to be bytestreams - Big Endian presentation */ ++ memcpy(ae->name, wwn, ++ min_t(size_t, sizeof(struct lpfc_name), sizeof(__be64))); + +- /* This string MUST be consistent with other FC platforms +- * supported by Broadcom. +- */ +- strncpy(ae->un.AttrString, +- "Emulex Corporation", +- sizeof(ae->un.AttrString)); +- len = strnlen(ae->un.AttrString, +- sizeof(ae->un.AttrString)); +- len += (len & 3) ? (4 - (len & 3)) : 4; +- size = FOURBYTES + len; +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RHBA_MANUFACTURER); + return size; + } + +-static int +-lpfc_fdmi_hba_attr_sn(struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad) ++static inline int ++lpfc_fdmi_set_attr_fullwwn(void *attr, uint16_t attrtype, ++ struct lpfc_name *wwnn, struct lpfc_name *wwpn) + { +- struct lpfc_hba *phba = vport->phba; +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t len, size; ++ struct lpfc_fdmi_attr_fullwwn *ae = attr; ++ u8 *nname = ae->nname; ++ u8 *pname = ae->pname; ++ int size = sizeof(*ae); + +- ae = &ad->AttrValue; +- memset(ae, 0, sizeof(*ae)); ++ ae->type = cpu_to_be16(attrtype); ++ ae->len = cpu_to_be16(size); ++ /* WWN's assumed to be bytestreams - Big Endian presentation */ ++ memcpy(nname, wwnn, ++ min_t(size_t, sizeof(struct lpfc_name), sizeof(__be64))); ++ memcpy(pname, wwpn, ++ min_t(size_t, sizeof(struct lpfc_name), sizeof(__be64))); + +- strncpy(ae->un.AttrString, phba->SerialNumber, +- sizeof(ae->un.AttrString)); +- len = strnlen(ae->un.AttrString, +- sizeof(ae->un.AttrString)); +- len += (len & 3) ? (4 - (len & 3)) : 4; +- size = FOURBYTES + len; +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RHBA_SERIAL_NUMBER); + return size; + } + +-static int +-lpfc_fdmi_hba_attr_model(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++static inline int ++lpfc_fdmi_set_attr_string(void *attr, uint16_t attrtype, char *attrstring) + { +- struct lpfc_hba *phba = vport->phba; +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t len, size; ++ struct lpfc_fdmi_attr_string *ae = attr; ++ int len, size; + +- ae = &ad->AttrValue; +- memset(ae, 0, sizeof(*ae)); ++ /* ++ * We are trusting the caller that if a fdmi string field ++ * is capped at 64 bytes, the caller passes in a string of ++ * 64 bytes or less. ++ */ + +- strncpy(ae->un.AttrString, phba->ModelName, +- sizeof(ae->un.AttrString)); +- len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString)); ++ strncpy(ae->value_string, attrstring, sizeof(ae->value_string)); ++ len = strnlen(ae->value_string, sizeof(ae->value_string)); ++ /* round string length to a 32bit boundary. Ensure there's a NULL */ + len += (len & 3) ? (4 - (len & 3)) : 4; ++ /* size is Type/Len (4 bytes) plus string length */ + size = FOURBYTES + len; +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RHBA_MODEL); ++ ++ ae->type = cpu_to_be16(attrtype); ++ ae->len = cpu_to_be16(size); ++ + return size; + } + +-static int +-lpfc_fdmi_hba_attr_description(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++/* Bitfields for FC4 Types that can be reported */ ++#define ATTR_FC4_CT 0x00000001 ++#define ATTR_FC4_FCP 0x00000002 ++#define ATTR_FC4_NVME 0x00000004 ++ ++static inline int ++lpfc_fdmi_set_attr_fc4types(void *attr, uint16_t attrtype, uint32_t typemask) + { +- struct lpfc_hba *phba = vport->phba; +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t len, size; ++ struct lpfc_fdmi_attr_fc4types *ae = attr; ++ int size = sizeof(*ae); + +- ae = &ad->AttrValue; +- memset(ae, 0, sizeof(*ae)); ++ ae->type = cpu_to_be16(attrtype); ++ ae->len = cpu_to_be16(size); ++ ++ if (typemask & ATTR_FC4_FCP) ++ ae->value_types[2] = 0x01; /* Type 0x8 - FCP */ ++ ++ if (typemask & ATTR_FC4_CT) ++ ae->value_types[7] = 0x01; /* Type 0x20 - CT */ ++ ++ if (typemask & ATTR_FC4_NVME) ++ ae->value_types[6] = 0x01; /* Type 0x28 - NVME */ + +- strncpy(ae->un.AttrString, phba->ModelDesc, +- sizeof(ae->un.AttrString)); +- len = strnlen(ae->un.AttrString, +- sizeof(ae->un.AttrString)); +- len += (len & 3) ? (4 - (len & 3)) : 4; +- size = FOURBYTES + len; +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RHBA_MODEL_DESCRIPTION); + return size; + } + ++/* Routines for all individual HBA attributes */ + static int +-lpfc_fdmi_hba_attr_hdw_ver(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_hba_attr_wwnn(struct lpfc_vport *vport, void *attr) + { +- struct lpfc_hba *phba = vport->phba; +- lpfc_vpd_t *vp = &phba->vpd; +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t i, j, incr, size; +- +- ae = &ad->AttrValue; +- memset(ae, 0, sizeof(*ae)); +- +- /* Convert JEDEC ID to ascii for hardware version */ +- incr = vp->rev.biuRev; +- for (i = 0; i < 8; i++) { +- j = (incr & 0xf); +- if (j <= 9) +- ae->un.AttrString[7 - i] = +- (char)((uint8_t) 0x30 + +- (uint8_t) j); +- else +- ae->un.AttrString[7 - i] = +- (char)((uint8_t) 0x61 + +- (uint8_t) (j - 10)); +- incr = (incr >> 4); +- } +- size = FOURBYTES + 8; +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RHBA_HARDWARE_VERSION); +- return size; ++ return lpfc_fdmi_set_attr_wwn(attr, RHBA_NODENAME, ++ &vport->fc_sparam.nodeName); + } + + static int +-lpfc_fdmi_hba_attr_drvr_ver(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_hba_attr_manufacturer(struct lpfc_vport *vport, void *attr) + { +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t len, size; ++ /* This string MUST be consistent with other FC platforms ++ * supported by Broadcom. ++ */ ++ return lpfc_fdmi_set_attr_string(attr, RHBA_MANUFACTURER, ++ "Emulex Corporation"); ++} + +- ae = &ad->AttrValue; +- memset(ae, 0, sizeof(*ae)); ++static int ++lpfc_fdmi_hba_attr_sn(struct lpfc_vport *vport, void *attr) ++{ ++ struct lpfc_hba *phba = vport->phba; + +- strncpy(ae->un.AttrString, lpfc_release_version, +- sizeof(ae->un.AttrString)); +- len = strnlen(ae->un.AttrString, +- sizeof(ae->un.AttrString)); +- len += (len & 3) ? (4 - (len & 3)) : 4; +- size = FOURBYTES + len; +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RHBA_DRIVER_VERSION); +- return size; ++ return lpfc_fdmi_set_attr_string(attr, RHBA_SERIAL_NUMBER, ++ phba->SerialNumber); + } + + static int +-lpfc_fdmi_hba_attr_rom_ver(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_hba_attr_model(struct lpfc_vport *vport, void *attr) + { + struct lpfc_hba *phba = vport->phba; +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t len, size; +- +- ae = &ad->AttrValue; +- memset(ae, 0, sizeof(*ae)); + +- if (phba->sli_rev == LPFC_SLI_REV4) +- lpfc_decode_firmware_rev(phba, ae->un.AttrString, 1); +- else +- strncpy(ae->un.AttrString, phba->OptionROMVersion, +- sizeof(ae->un.AttrString)); +- len = strnlen(ae->un.AttrString, +- sizeof(ae->un.AttrString)); +- len += (len & 3) ? (4 - (len & 3)) : 4; +- size = FOURBYTES + len; +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RHBA_OPTION_ROM_VERSION); +- return size; ++ return lpfc_fdmi_set_attr_string(attr, RHBA_MODEL, ++ phba->ModelName); + } + + static int +-lpfc_fdmi_hba_attr_fmw_ver(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_hba_attr_description(struct lpfc_vport *vport, void *attr) + { + struct lpfc_hba *phba = vport->phba; +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t len, size; +- +- ae = &ad->AttrValue; +- memset(ae, 0, sizeof(*ae)); + +- lpfc_decode_firmware_rev(phba, ae->un.AttrString, 1); +- len = strnlen(ae->un.AttrString, +- sizeof(ae->un.AttrString)); +- len += (len & 3) ? (4 - (len & 3)) : 4; +- size = FOURBYTES + len; +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RHBA_FIRMWARE_VERSION); +- return size; ++ return lpfc_fdmi_set_attr_string(attr, RHBA_MODEL_DESCRIPTION, ++ phba->ModelDesc); + } + + static int +-lpfc_fdmi_hba_attr_os_ver(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_hba_attr_hdw_ver(struct lpfc_vport *vport, void *attr) + { +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t len, size; ++ struct lpfc_hba *phba = vport->phba; ++ lpfc_vpd_t *vp = &phba->vpd; ++ char buf[16] = { 0 }; + +- ae = &ad->AttrValue; +- memset(ae, 0, sizeof(*ae)); ++ snprintf(buf, sizeof(buf), "%08x", vp->rev.biuRev); + +- snprintf(ae->un.AttrString, sizeof(ae->un.AttrString), "%s %s %s", +- init_utsname()->sysname, +- init_utsname()->release, +- init_utsname()->version); ++ return lpfc_fdmi_set_attr_string(attr, RHBA_HARDWARE_VERSION, buf); ++} + +- len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString)); +- len += (len & 3) ? (4 - (len & 3)) : 4; +- size = FOURBYTES + len; +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RHBA_OS_NAME_VERSION); +- return size; ++static int ++lpfc_fdmi_hba_attr_drvr_ver(struct lpfc_vport *vport, void *attr) ++{ ++ return lpfc_fdmi_set_attr_string(attr, RHBA_DRIVER_VERSION, ++ lpfc_release_version); + } + + static int +-lpfc_fdmi_hba_attr_ct_len(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_hba_attr_rom_ver(struct lpfc_vport *vport, void *attr) + { +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t size; ++ struct lpfc_hba *phba = vport->phba; ++ char buf[64] = { 0 }; + +- ae = &ad->AttrValue; ++ if (phba->sli_rev == LPFC_SLI_REV4) { ++ lpfc_decode_firmware_rev(phba, buf, 1); + +- ae->un.AttrInt = cpu_to_be32(LPFC_MAX_CT_SIZE); +- size = FOURBYTES + sizeof(uint32_t); +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RHBA_MAX_CT_PAYLOAD_LEN); +- return size; ++ return lpfc_fdmi_set_attr_string(attr, RHBA_OPTION_ROM_VERSION, ++ buf); ++ } ++ ++ return lpfc_fdmi_set_attr_string(attr, RHBA_OPTION_ROM_VERSION, ++ phba->OptionROMVersion); + } + + static int +-lpfc_fdmi_hba_attr_symbolic_name(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_hba_attr_fmw_ver(struct lpfc_vport *vport, void *attr) + { +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t len, size; ++ struct lpfc_hba *phba = vport->phba; ++ char buf[64] = { 0 }; + +- ae = &ad->AttrValue; +- memset(ae, 0, sizeof(*ae)); ++ lpfc_decode_firmware_rev(phba, buf, 1); + +- len = lpfc_vport_symbolic_node_name(vport, +- ae->un.AttrString, 256); +- len += (len & 3) ? (4 - (len & 3)) : 4; +- size = FOURBYTES + len; +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RHBA_SYM_NODENAME); +- return size; ++ return lpfc_fdmi_set_attr_string(attr, RHBA_FIRMWARE_VERSION, buf); + } + + static int +-lpfc_fdmi_hba_attr_vendor_info(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_hba_attr_os_ver(struct lpfc_vport *vport, void *attr) + { +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t size; ++ char buf[256] = { 0 }; ++ ++ snprintf(buf, sizeof(buf), "%s %s %s", ++ init_utsname()->sysname, ++ init_utsname()->release, ++ init_utsname()->version); + +- ae = &ad->AttrValue; ++ return lpfc_fdmi_set_attr_string(attr, RHBA_OS_NAME_VERSION, buf); ++} + +- /* Nothing is defined for this currently */ +- ae->un.AttrInt = cpu_to_be32(0); +- size = FOURBYTES + sizeof(uint32_t); +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RHBA_VENDOR_INFO); +- return size; ++static int ++lpfc_fdmi_hba_attr_ct_len(struct lpfc_vport *vport, void *attr) ++{ ++ return lpfc_fdmi_set_attr_u32(attr, RHBA_MAX_CT_PAYLOAD_LEN, ++ LPFC_MAX_CT_SIZE); + } + + static int +-lpfc_fdmi_hba_attr_num_ports(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_hba_attr_symbolic_name(struct lpfc_vport *vport, void *attr) + { +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t size; ++ char buf[256] = { 0 }; + +- ae = &ad->AttrValue; ++ lpfc_vport_symbolic_node_name(vport, buf, sizeof(buf)); + +- /* Each driver instance corresponds to a single port */ +- ae->un.AttrInt = cpu_to_be32(1); +- size = FOURBYTES + sizeof(uint32_t); +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RHBA_NUM_PORTS); +- return size; ++ return lpfc_fdmi_set_attr_string(attr, RHBA_SYM_NODENAME, buf); + } + + static int +-lpfc_fdmi_hba_attr_fabric_wwnn(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_hba_attr_vendor_info(struct lpfc_vport *vport, void *attr) + { +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t size; ++ return lpfc_fdmi_set_attr_u32(attr, RHBA_VENDOR_INFO, 0); ++} + +- ae = &ad->AttrValue; +- memset(ae, 0, sizeof(*ae)); ++static int ++lpfc_fdmi_hba_attr_num_ports(struct lpfc_vport *vport, void *attr) ++{ ++ /* Each driver instance corresponds to a single port */ ++ return lpfc_fdmi_set_attr_u32(attr, RHBA_NUM_PORTS, 1); ++} + +- memcpy(&ae->un.AttrWWN, &vport->fabric_nodename, +- sizeof(struct lpfc_name)); +- size = FOURBYTES + sizeof(struct lpfc_name); +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RHBA_FABRIC_WWNN); +- return size; ++static int ++lpfc_fdmi_hba_attr_fabric_wwnn(struct lpfc_vport *vport, void *attr) ++{ ++ return lpfc_fdmi_set_attr_wwn(attr, RHBA_FABRIC_WWNN, ++ &vport->fabric_nodename); + } + + static int +-lpfc_fdmi_hba_attr_bios_ver(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_hba_attr_bios_ver(struct lpfc_vport *vport, void *attr) + { + struct lpfc_hba *phba = vport->phba; +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t len, size; +- +- ae = &ad->AttrValue; +- memset(ae, 0, sizeof(*ae)); + +- strlcat(ae->un.AttrString, phba->BIOSVersion, +- sizeof(ae->un.AttrString)); +- len = strnlen(ae->un.AttrString, +- sizeof(ae->un.AttrString)); +- len += (len & 3) ? (4 - (len & 3)) : 4; +- size = FOURBYTES + len; +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RHBA_BIOS_VERSION); +- return size; ++ return lpfc_fdmi_set_attr_string(attr, RHBA_BIOS_VERSION, ++ phba->BIOSVersion); + } + + static int +-lpfc_fdmi_hba_attr_bios_state(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_hba_attr_bios_state(struct lpfc_vport *vport, void *attr) + { +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t size; +- +- ae = &ad->AttrValue; +- + /* Driver doesn't have access to this information */ +- ae->un.AttrInt = cpu_to_be32(0); +- size = FOURBYTES + sizeof(uint32_t); +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RHBA_BIOS_STATE); +- return size; ++ return lpfc_fdmi_set_attr_u32(attr, RHBA_BIOS_STATE, 0); + } + + static int +-lpfc_fdmi_hba_attr_vendor_id(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_hba_attr_vendor_id(struct lpfc_vport *vport, void *attr) + { +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t len, size; +- +- ae = &ad->AttrValue; +- memset(ae, 0, sizeof(*ae)); +- +- strncpy(ae->un.AttrString, "EMULEX", +- sizeof(ae->un.AttrString)); +- len = strnlen(ae->un.AttrString, +- sizeof(ae->un.AttrString)); +- len += (len & 3) ? (4 - (len & 3)) : 4; +- size = FOURBYTES + len; +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RHBA_VENDOR_ID); +- return size; ++ return lpfc_fdmi_set_attr_string(attr, RHBA_VENDOR_ID, "EMULEX"); + } + +-/* Routines for all individual PORT attributes */ ++/* ++ * Routines for all individual PORT attributes ++ */ ++ + static int +-lpfc_fdmi_port_attr_fc4type(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_port_attr_fc4type(struct lpfc_vport *vport, void *attr) + { + struct lpfc_hba *phba = vport->phba; +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t size; +- +- ae = &ad->AttrValue; +- memset(ae, 0, sizeof(*ae)); ++ u32 fc4types; + +- ae->un.AttrTypes[2] = 0x01; /* Type 0x8 - FCP */ +- ae->un.AttrTypes[7] = 0x01; /* Type 0x20 - CT */ ++ fc4types = (ATTR_FC4_CT | ATTR_FC4_FCP); + + /* Check to see if Firmware supports NVME and on physical port */ + if ((phba->sli_rev == LPFC_SLI_REV4) && (vport == phba->pport) && + phba->sli4_hba.pc_sli4_params.nvme) +- ae->un.AttrTypes[6] = 0x01; /* Type 0x28 - NVME */ ++ fc4types |= ATTR_FC4_NVME; + +- size = FOURBYTES + 32; +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_FC4_TYPES); +- return size; ++ return lpfc_fdmi_set_attr_fc4types(attr, RPRT_SUPPORTED_FC4_TYPES, ++ fc4types); + } + + static int +-lpfc_fdmi_port_attr_support_speed(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_port_attr_support_speed(struct lpfc_vport *vport, void *attr) + { +- struct lpfc_hba *phba = vport->phba; +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t size; ++ struct lpfc_hba *phba = vport->phba; ++ u32 speeds = 0; + u32 tcfg; + u8 i, cnt; + +- ae = &ad->AttrValue; +- +- ae->un.AttrInt = 0; + if (!(phba->hba_flag & HBA_FCOE_MODE)) { + cnt = 0; + if (phba->sli_rev == LPFC_SLI_REV4) { +@@ -2926,539 +2804,314 @@ lpfc_fdmi_port_attr_support_speed(struct lpfc_vport *vport, + + if (cnt > 2) { /* 4 lane trunk group */ + if (phba->lmt & LMT_64Gb) +- ae->un.AttrInt |= HBA_PORTSPEED_256GFC; ++ speeds |= HBA_PORTSPEED_256GFC; + if (phba->lmt & LMT_32Gb) +- ae->un.AttrInt |= HBA_PORTSPEED_128GFC; ++ speeds |= HBA_PORTSPEED_128GFC; + if (phba->lmt & LMT_16Gb) +- ae->un.AttrInt |= HBA_PORTSPEED_64GFC; ++ speeds |= HBA_PORTSPEED_64GFC; + } else if (cnt) { /* 2 lane trunk group */ + if (phba->lmt & LMT_128Gb) +- ae->un.AttrInt |= HBA_PORTSPEED_256GFC; ++ speeds |= HBA_PORTSPEED_256GFC; + if (phba->lmt & LMT_64Gb) +- ae->un.AttrInt |= HBA_PORTSPEED_128GFC; ++ speeds |= HBA_PORTSPEED_128GFC; + if (phba->lmt & LMT_32Gb) +- ae->un.AttrInt |= HBA_PORTSPEED_64GFC; ++ speeds |= HBA_PORTSPEED_64GFC; + if (phba->lmt & LMT_16Gb) +- ae->un.AttrInt |= HBA_PORTSPEED_32GFC; ++ speeds |= HBA_PORTSPEED_32GFC; + } else { + if (phba->lmt & LMT_256Gb) +- ae->un.AttrInt |= HBA_PORTSPEED_256GFC; ++ speeds |= HBA_PORTSPEED_256GFC; + if (phba->lmt & LMT_128Gb) +- ae->un.AttrInt |= HBA_PORTSPEED_128GFC; ++ speeds |= HBA_PORTSPEED_128GFC; + if (phba->lmt & LMT_64Gb) +- ae->un.AttrInt |= HBA_PORTSPEED_64GFC; ++ speeds |= HBA_PORTSPEED_64GFC; + if (phba->lmt & LMT_32Gb) +- ae->un.AttrInt |= HBA_PORTSPEED_32GFC; ++ speeds |= HBA_PORTSPEED_32GFC; + if (phba->lmt & LMT_16Gb) +- ae->un.AttrInt |= HBA_PORTSPEED_16GFC; ++ speeds |= HBA_PORTSPEED_16GFC; + if (phba->lmt & LMT_10Gb) +- ae->un.AttrInt |= HBA_PORTSPEED_10GFC; ++ speeds |= HBA_PORTSPEED_10GFC; + if (phba->lmt & LMT_8Gb) +- ae->un.AttrInt |= HBA_PORTSPEED_8GFC; ++ speeds |= HBA_PORTSPEED_8GFC; + if (phba->lmt & LMT_4Gb) +- ae->un.AttrInt |= HBA_PORTSPEED_4GFC; ++ speeds |= HBA_PORTSPEED_4GFC; + if (phba->lmt & LMT_2Gb) +- ae->un.AttrInt |= HBA_PORTSPEED_2GFC; ++ speeds |= HBA_PORTSPEED_2GFC; + if (phba->lmt & LMT_1Gb) +- ae->un.AttrInt |= HBA_PORTSPEED_1GFC; ++ speeds |= HBA_PORTSPEED_1GFC; + } + } else { + /* FCoE links support only one speed */ + switch (phba->fc_linkspeed) { + case LPFC_ASYNC_LINK_SPEED_10GBPS: +- ae->un.AttrInt = HBA_PORTSPEED_10GE; ++ speeds = HBA_PORTSPEED_10GE; + break; + case LPFC_ASYNC_LINK_SPEED_25GBPS: +- ae->un.AttrInt = HBA_PORTSPEED_25GE; ++ speeds = HBA_PORTSPEED_25GE; + break; + case LPFC_ASYNC_LINK_SPEED_40GBPS: +- ae->un.AttrInt = HBA_PORTSPEED_40GE; ++ speeds = HBA_PORTSPEED_40GE; + break; + case LPFC_ASYNC_LINK_SPEED_100GBPS: +- ae->un.AttrInt = HBA_PORTSPEED_100GE; ++ speeds = HBA_PORTSPEED_100GE; + break; + } + } +- ae->un.AttrInt = cpu_to_be32(ae->un.AttrInt); +- size = FOURBYTES + sizeof(uint32_t); +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_SPEED); +- return size; ++ ++ return lpfc_fdmi_set_attr_u32(attr, RPRT_SUPPORTED_SPEED, speeds); + } + + static int +-lpfc_fdmi_port_attr_speed(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_port_attr_speed(struct lpfc_vport *vport, void *attr) + { + struct lpfc_hba *phba = vport->phba; +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t size; +- +- ae = &ad->AttrValue; ++ u32 speeds = 0; + + if (!(phba->hba_flag & HBA_FCOE_MODE)) { + switch (phba->fc_linkspeed) { + case LPFC_LINK_SPEED_1GHZ: +- ae->un.AttrInt = HBA_PORTSPEED_1GFC; ++ speeds = HBA_PORTSPEED_1GFC; + break; + case LPFC_LINK_SPEED_2GHZ: +- ae->un.AttrInt = HBA_PORTSPEED_2GFC; ++ speeds = HBA_PORTSPEED_2GFC; + break; + case LPFC_LINK_SPEED_4GHZ: +- ae->un.AttrInt = HBA_PORTSPEED_4GFC; ++ speeds = HBA_PORTSPEED_4GFC; + break; + case LPFC_LINK_SPEED_8GHZ: +- ae->un.AttrInt = HBA_PORTSPEED_8GFC; ++ speeds = HBA_PORTSPEED_8GFC; + break; + case LPFC_LINK_SPEED_10GHZ: +- ae->un.AttrInt = HBA_PORTSPEED_10GFC; ++ speeds = HBA_PORTSPEED_10GFC; + break; + case LPFC_LINK_SPEED_16GHZ: +- ae->un.AttrInt = HBA_PORTSPEED_16GFC; ++ speeds = HBA_PORTSPEED_16GFC; + break; + case LPFC_LINK_SPEED_32GHZ: +- ae->un.AttrInt = HBA_PORTSPEED_32GFC; ++ speeds = HBA_PORTSPEED_32GFC; + break; + case LPFC_LINK_SPEED_64GHZ: +- ae->un.AttrInt = HBA_PORTSPEED_64GFC; ++ speeds = HBA_PORTSPEED_64GFC; + break; + case LPFC_LINK_SPEED_128GHZ: +- ae->un.AttrInt = HBA_PORTSPEED_128GFC; ++ speeds = HBA_PORTSPEED_128GFC; + break; + case LPFC_LINK_SPEED_256GHZ: +- ae->un.AttrInt = HBA_PORTSPEED_256GFC; ++ speeds = HBA_PORTSPEED_256GFC; + break; + default: +- ae->un.AttrInt = HBA_PORTSPEED_UNKNOWN; ++ speeds = HBA_PORTSPEED_UNKNOWN; + break; + } + } else { + switch (phba->fc_linkspeed) { + case LPFC_ASYNC_LINK_SPEED_10GBPS: +- ae->un.AttrInt = HBA_PORTSPEED_10GE; ++ speeds = HBA_PORTSPEED_10GE; + break; + case LPFC_ASYNC_LINK_SPEED_25GBPS: +- ae->un.AttrInt = HBA_PORTSPEED_25GE; ++ speeds = HBA_PORTSPEED_25GE; + break; + case LPFC_ASYNC_LINK_SPEED_40GBPS: +- ae->un.AttrInt = HBA_PORTSPEED_40GE; ++ speeds = HBA_PORTSPEED_40GE; + break; + case LPFC_ASYNC_LINK_SPEED_100GBPS: +- ae->un.AttrInt = HBA_PORTSPEED_100GE; ++ speeds = HBA_PORTSPEED_100GE; + break; + default: +- ae->un.AttrInt = HBA_PORTSPEED_UNKNOWN; ++ speeds = HBA_PORTSPEED_UNKNOWN; + break; + } + } + +- ae->un.AttrInt = cpu_to_be32(ae->un.AttrInt); +- size = FOURBYTES + sizeof(uint32_t); +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RPRT_PORT_SPEED); +- return size; ++ return lpfc_fdmi_set_attr_u32(attr, RPRT_PORT_SPEED, speeds); + } + + static int +-lpfc_fdmi_port_attr_max_frame(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_port_attr_max_frame(struct lpfc_vport *vport, void *attr) + { +- struct serv_parm *hsp; +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t size; +- +- ae = &ad->AttrValue; ++ struct serv_parm *hsp = (struct serv_parm *)&vport->fc_sparam; + +- hsp = (struct serv_parm *)&vport->fc_sparam; +- ae->un.AttrInt = (((uint32_t) hsp->cmn.bbRcvSizeMsb & 0x0F) << 8) | +- (uint32_t) hsp->cmn.bbRcvSizeLsb; +- ae->un.AttrInt = cpu_to_be32(ae->un.AttrInt); +- size = FOURBYTES + sizeof(uint32_t); +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RPRT_MAX_FRAME_SIZE); +- return size; ++ return lpfc_fdmi_set_attr_u32(attr, RPRT_MAX_FRAME_SIZE, ++ (((uint32_t)hsp->cmn.bbRcvSizeMsb & 0x0F) << 8) | ++ (uint32_t)hsp->cmn.bbRcvSizeLsb); + } + + static int +-lpfc_fdmi_port_attr_os_devname(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_port_attr_os_devname(struct lpfc_vport *vport, void *attr) + { + struct Scsi_Host *shost = lpfc_shost_from_vport(vport); +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t len, size; ++ char buf[64] = { 0 }; + +- ae = &ad->AttrValue; +- memset(ae, 0, sizeof(*ae)); ++ snprintf(buf, sizeof(buf), "/sys/class/scsi_host/host%d", ++ shost->host_no); + +- snprintf(ae->un.AttrString, sizeof(ae->un.AttrString), +- "/sys/class/scsi_host/host%d", shost->host_no); +- len = strnlen((char *)ae->un.AttrString, +- sizeof(ae->un.AttrString)); +- len += (len & 3) ? (4 - (len & 3)) : 4; +- size = FOURBYTES + len; +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RPRT_OS_DEVICE_NAME); +- return size; ++ return lpfc_fdmi_set_attr_string(attr, RPRT_OS_DEVICE_NAME, buf); + } + + static int +-lpfc_fdmi_port_attr_host_name(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_port_attr_host_name(struct lpfc_vport *vport, void *attr) + { +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t len, size; ++ char buf[64] = { 0 }; + +- ae = &ad->AttrValue; +- memset(ae, 0, sizeof(*ae)); ++ scnprintf(buf, sizeof(buf), "%s", vport->phba->os_host_name); + +- scnprintf(ae->un.AttrString, sizeof(ae->un.AttrString), "%s", +- vport->phba->os_host_name); +- +- len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString)); +- len += (len & 3) ? (4 - (len & 3)) : 4; +- size = FOURBYTES + len; +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RPRT_HOST_NAME); +- return size; ++ return lpfc_fdmi_set_attr_string(attr, RPRT_HOST_NAME, buf); + } + + static int +-lpfc_fdmi_port_attr_wwnn(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_port_attr_wwnn(struct lpfc_vport *vport, void *attr) + { +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t size; +- +- ae = &ad->AttrValue; +- memset(ae, 0, sizeof(*ae)); +- +- memcpy(&ae->un.AttrWWN, &vport->fc_sparam.nodeName, +- sizeof(struct lpfc_name)); +- size = FOURBYTES + sizeof(struct lpfc_name); +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RPRT_NODENAME); +- return size; ++ return lpfc_fdmi_set_attr_wwn(attr, RPRT_NODENAME, ++ &vport->fc_sparam.nodeName); + } + + static int +-lpfc_fdmi_port_attr_wwpn(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_port_attr_wwpn(struct lpfc_vport *vport, void *attr) + { +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t size; +- +- ae = &ad->AttrValue; +- memset(ae, 0, sizeof(*ae)); +- +- memcpy(&ae->un.AttrWWN, &vport->fc_sparam.portName, +- sizeof(struct lpfc_name)); +- size = FOURBYTES + sizeof(struct lpfc_name); +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RPRT_PORTNAME); +- return size; ++ return lpfc_fdmi_set_attr_wwn(attr, RPRT_PORTNAME, ++ &vport->fc_sparam.portName); + } + + static int +-lpfc_fdmi_port_attr_symbolic_name(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_port_attr_symbolic_name(struct lpfc_vport *vport, void *attr) + { +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t len, size; ++ char buf[256] = { 0 }; + +- ae = &ad->AttrValue; +- memset(ae, 0, sizeof(*ae)); ++ lpfc_vport_symbolic_port_name(vport, buf, sizeof(buf)); + +- len = lpfc_vport_symbolic_port_name(vport, ae->un.AttrString, 256); +- len += (len & 3) ? (4 - (len & 3)) : 4; +- size = FOURBYTES + len; +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RPRT_SYM_PORTNAME); +- return size; ++ return lpfc_fdmi_set_attr_string(attr, RPRT_SYM_PORTNAME, buf); + } + + static int +-lpfc_fdmi_port_attr_port_type(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_port_attr_port_type(struct lpfc_vport *vport, void *attr) + { + struct lpfc_hba *phba = vport->phba; +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t size; + +- ae = &ad->AttrValue; +- if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) +- ae->un.AttrInt = cpu_to_be32(LPFC_FDMI_PORTTYPE_NLPORT); +- else +- ae->un.AttrInt = cpu_to_be32(LPFC_FDMI_PORTTYPE_NPORT); +- size = FOURBYTES + sizeof(uint32_t); +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RPRT_PORT_TYPE); +- return size; ++ return lpfc_fdmi_set_attr_u32(attr, RPRT_PORT_TYPE, ++ (phba->fc_topology == LPFC_TOPOLOGY_LOOP) ? ++ LPFC_FDMI_PORTTYPE_NLPORT : ++ LPFC_FDMI_PORTTYPE_NPORT); + } + + static int +-lpfc_fdmi_port_attr_class(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_port_attr_class(struct lpfc_vport *vport, void *attr) + { +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t size; +- +- ae = &ad->AttrValue; +- ae->un.AttrInt = cpu_to_be32(FC_COS_CLASS2 | FC_COS_CLASS3); +- size = FOURBYTES + sizeof(uint32_t); +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_CLASS); +- return size; ++ return lpfc_fdmi_set_attr_u32(attr, RPRT_SUPPORTED_CLASS, ++ FC_COS_CLASS2 | FC_COS_CLASS3); + } + + static int +-lpfc_fdmi_port_attr_fabric_wwpn(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_port_attr_fabric_wwpn(struct lpfc_vport *vport, void *attr) + { +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t size; +- +- ae = &ad->AttrValue; +- memset(ae, 0, sizeof(*ae)); +- +- memcpy(&ae->un.AttrWWN, &vport->fabric_portname, +- sizeof(struct lpfc_name)); +- size = FOURBYTES + sizeof(struct lpfc_name); +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RPRT_FABRICNAME); +- return size; ++ return lpfc_fdmi_set_attr_wwn(attr, RPRT_FABRICNAME, ++ &vport->fabric_portname); + } + + static int +-lpfc_fdmi_port_attr_active_fc4type(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_port_attr_active_fc4type(struct lpfc_vport *vport, void *attr) + { + struct lpfc_hba *phba = vport->phba; +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t size; ++ u32 fc4types; + +- ae = &ad->AttrValue; +- memset(ae, 0, sizeof(*ae)); +- +- ae->un.AttrTypes[2] = 0x01; /* Type 0x8 - FCP */ +- ae->un.AttrTypes[7] = 0x01; /* Type 0x20 - CT */ ++ fc4types = (ATTR_FC4_CT | ATTR_FC4_FCP); + + /* Check to see if NVME is configured or not */ + if (vport == phba->pport && + phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) +- ae->un.AttrTypes[6] = 0x1; /* Type 0x28 - NVME */ ++ fc4types |= ATTR_FC4_NVME; + +- size = FOURBYTES + 32; +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RPRT_ACTIVE_FC4_TYPES); +- return size; ++ return lpfc_fdmi_set_attr_fc4types(attr, RPRT_ACTIVE_FC4_TYPES, ++ fc4types); + } + + static int +-lpfc_fdmi_port_attr_port_state(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_port_attr_port_state(struct lpfc_vport *vport, void *attr) + { +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t size; +- +- ae = &ad->AttrValue; +- /* Link Up - operational */ +- ae->un.AttrInt = cpu_to_be32(LPFC_FDMI_PORTSTATE_ONLINE); +- size = FOURBYTES + sizeof(uint32_t); +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RPRT_PORT_STATE); +- return size; ++ return lpfc_fdmi_set_attr_u32(attr, RPRT_PORT_STATE, ++ LPFC_FDMI_PORTSTATE_ONLINE); + } + + static int +-lpfc_fdmi_port_attr_num_disc(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_port_attr_num_disc(struct lpfc_vport *vport, void *attr) + { +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t size; +- +- ae = &ad->AttrValue; + vport->fdmi_num_disc = lpfc_find_map_node(vport); +- ae->un.AttrInt = cpu_to_be32(vport->fdmi_num_disc); +- size = FOURBYTES + sizeof(uint32_t); +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RPRT_DISC_PORT); +- return size; ++ ++ return lpfc_fdmi_set_attr_u32(attr, RPRT_DISC_PORT, ++ vport->fdmi_num_disc); + } + + static int +-lpfc_fdmi_port_attr_nportid(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_port_attr_nportid(struct lpfc_vport *vport, void *attr) + { +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t size; +- +- ae = &ad->AttrValue; +- ae->un.AttrInt = cpu_to_be32(vport->fc_myDID); +- size = FOURBYTES + sizeof(uint32_t); +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RPRT_PORT_ID); +- return size; ++ return lpfc_fdmi_set_attr_u32(attr, RPRT_PORT_ID, vport->fc_myDID); + } + + static int +-lpfc_fdmi_smart_attr_service(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_smart_attr_service(struct lpfc_vport *vport, void *attr) + { +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t len, size; +- +- ae = &ad->AttrValue; +- memset(ae, 0, sizeof(*ae)); +- +- strncpy(ae->un.AttrString, "Smart SAN Initiator", +- sizeof(ae->un.AttrString)); +- len = strnlen(ae->un.AttrString, +- sizeof(ae->un.AttrString)); +- len += (len & 3) ? (4 - (len & 3)) : 4; +- size = FOURBYTES + len; +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RPRT_SMART_SERVICE); +- return size; ++ return lpfc_fdmi_set_attr_string(attr, RPRT_SMART_SERVICE, ++ "Smart SAN Initiator"); + } + + static int +-lpfc_fdmi_smart_attr_guid(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_smart_attr_guid(struct lpfc_vport *vport, void *attr) + { +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t size; +- +- ae = &ad->AttrValue; +- memset(ae, 0, sizeof(*ae)); +- +- memcpy(&ae->un.AttrString, &vport->fc_sparam.nodeName, +- sizeof(struct lpfc_name)); +- memcpy((((uint8_t *)&ae->un.AttrString) + +- sizeof(struct lpfc_name)), +- &vport->fc_sparam.portName, sizeof(struct lpfc_name)); +- size = FOURBYTES + (2 * sizeof(struct lpfc_name)); +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RPRT_SMART_GUID); +- return size; ++ return lpfc_fdmi_set_attr_fullwwn(attr, RPRT_SMART_GUID, ++ &vport->fc_sparam.nodeName, ++ &vport->fc_sparam.portName); + } + + static int +-lpfc_fdmi_smart_attr_version(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_smart_attr_version(struct lpfc_vport *vport, void *attr) + { +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t len, size; +- +- ae = &ad->AttrValue; +- memset(ae, 0, sizeof(*ae)); +- +- strncpy(ae->un.AttrString, "Smart SAN Version 2.0", +- sizeof(ae->un.AttrString)); +- len = strnlen(ae->un.AttrString, +- sizeof(ae->un.AttrString)); +- len += (len & 3) ? (4 - (len & 3)) : 4; +- size = FOURBYTES + len; +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RPRT_SMART_VERSION); +- return size; ++ return lpfc_fdmi_set_attr_string(attr, RPRT_SMART_VERSION, ++ "Smart SAN Version 2.0"); + } + + static int +-lpfc_fdmi_smart_attr_model(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_smart_attr_model(struct lpfc_vport *vport, void *attr) + { + struct lpfc_hba *phba = vport->phba; +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t len, size; +- +- ae = &ad->AttrValue; +- memset(ae, 0, sizeof(*ae)); + +- strncpy(ae->un.AttrString, phba->ModelName, +- sizeof(ae->un.AttrString)); +- len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString)); +- len += (len & 3) ? (4 - (len & 3)) : 4; +- size = FOURBYTES + len; +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RPRT_SMART_MODEL); +- return size; ++ return lpfc_fdmi_set_attr_string(attr, RPRT_SMART_MODEL, ++ phba->ModelName); + } + + static int +-lpfc_fdmi_smart_attr_port_info(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_smart_attr_port_info(struct lpfc_vport *vport, void *attr) + { +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t size; +- +- ae = &ad->AttrValue; +- + /* SRIOV (type 3) is not supported */ +- if (vport->vpi) +- ae->un.AttrInt = cpu_to_be32(2); /* NPIV */ +- else +- ae->un.AttrInt = cpu_to_be32(1); /* Physical */ +- size = FOURBYTES + sizeof(uint32_t); +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RPRT_SMART_PORT_INFO); +- return size; ++ ++ return lpfc_fdmi_set_attr_u32(attr, RPRT_SMART_PORT_INFO, ++ (vport->vpi) ? 2 /* NPIV */ : 1 /* Physical */); + } + + static int +-lpfc_fdmi_smart_attr_qos(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_smart_attr_qos(struct lpfc_vport *vport, void *attr) + { +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t size; +- +- ae = &ad->AttrValue; +- ae->un.AttrInt = cpu_to_be32(0); +- size = FOURBYTES + sizeof(uint32_t); +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RPRT_SMART_QOS); +- return size; ++ return lpfc_fdmi_set_attr_u32(attr, RPRT_SMART_QOS, 0); + } + + static int +-lpfc_fdmi_smart_attr_security(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_smart_attr_security(struct lpfc_vport *vport, void *attr) + { +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t size; +- +- ae = &ad->AttrValue; +- ae->un.AttrInt = cpu_to_be32(1); +- size = FOURBYTES + sizeof(uint32_t); +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RPRT_SMART_SECURITY); +- return size; ++ return lpfc_fdmi_set_attr_u32(attr, RPRT_SMART_SECURITY, 1); + } + + static int +-lpfc_fdmi_vendor_attr_mi(struct lpfc_vport *vport, +- struct lpfc_fdmi_attr_def *ad) ++lpfc_fdmi_vendor_attr_mi(struct lpfc_vport *vport, void *attr) + { + struct lpfc_hba *phba = vport->phba; +- struct lpfc_fdmi_attr_entry *ae; +- uint32_t len, size; +- char mibrevision[16]; +- +- ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; +- memset(ae, 0, 256); +- sprintf(mibrevision, "ELXE2EM:%04d", +- phba->sli4_hba.pc_sli4_params.mi_ver); +- strncpy(ae->un.AttrString, &mibrevision[0], sizeof(ae->un.AttrString)); +- len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString)); +- len += (len & 3) ? (4 - (len & 3)) : 4; +- size = FOURBYTES + len; +- ad->AttrLen = cpu_to_be16(size); +- ad->AttrType = cpu_to_be16(RPRT_VENDOR_MI); +- return size; ++ char buf[32] = { 0 }; ++ ++ sprintf(buf, "ELXE2EM:%04d", phba->sli4_hba.pc_sli4_params.mi_ver); ++ ++ return lpfc_fdmi_set_attr_string(attr, RPRT_VENDOR_MI, buf); + } + + /* RHBA attribute jump table */ + int (*lpfc_fdmi_hba_action[]) +- (struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad) = { ++ (struct lpfc_vport *vport, void *attrbuf) = { + /* Action routine Mask bit Attribute type */ + lpfc_fdmi_hba_attr_wwnn, /* bit0 RHBA_NODENAME */ + lpfc_fdmi_hba_attr_manufacturer, /* bit1 RHBA_MANUFACTURER */ +@@ -3482,7 +3135,7 @@ int (*lpfc_fdmi_hba_action[]) + + /* RPA / RPRT attribute jump table */ + int (*lpfc_fdmi_port_action[]) +- (struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad) = { ++ (struct lpfc_vport *vport, void *attrbuf) = { + /* Action routine Mask bit Attribute type */ + lpfc_fdmi_port_attr_fc4type, /* bit0 RPRT_SUPPORT_FC4_TYPES */ + lpfc_fdmi_port_attr_support_speed, /* bit1 RPRT_SUPPORTED_SPEED */ +@@ -3528,16 +3181,16 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, + struct lpfc_sli_ct_request *CtReq; + struct ulp_bde64_le *bde; + uint32_t bit_pos; +- uint32_t size; ++ uint32_t size, addsz; + uint32_t rsp_size; + uint32_t mask; + struct lpfc_fdmi_reg_hba *rh; + struct lpfc_fdmi_port_entry *pe; + struct lpfc_fdmi_reg_portattr *pab = NULL, *base = NULL; + struct lpfc_fdmi_attr_block *ab = NULL; +- int (*func)(struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad); +- void (*cmpl)(struct lpfc_hba *, struct lpfc_iocbq *, +- struct lpfc_iocbq *); ++ int (*func)(struct lpfc_vport *vport, void *attrbuf); ++ void (*cmpl)(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ++ struct lpfc_iocbq *rspiocb); + + if (!ndlp) + return 0; +@@ -3623,12 +3276,13 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, + while (mask) { + if (mask & 0x1) { + func = lpfc_fdmi_hba_action[bit_pos]; +- size += func(vport, +- (struct lpfc_fdmi_attr_def *) +- ((uint8_t *)rh + size)); +- ab->EntryCnt++; ++ addsz = func(vport, ((uint8_t *)rh + size)); ++ if (addsz) { ++ ab->EntryCnt++; ++ size += addsz; ++ } + /* check if another attribute fits */ +- if ((size + 256) > ++ if ((size + FDMI_MAX_ATTRLEN) > + (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) + goto hba_out; + } +@@ -3682,12 +3336,13 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, + while (mask) { + if (mask & 0x1) { + func = lpfc_fdmi_port_action[bit_pos]; +- size += func(vport, +- (struct lpfc_fdmi_attr_def *) +- ((uint8_t *)base + size)); +- pab->ab.EntryCnt++; ++ addsz = func(vport, ((uint8_t *)base + size)); ++ if (addsz) { ++ pab->ab.EntryCnt++; ++ size += addsz; ++ } + /* check if another attribute fits */ +- if ((size + 256) > ++ if ((size + FDMI_MAX_ATTRLEN) > + (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) + goto port_out; + } +diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h +index cbaf9a0f12c3..5c283936ff08 100644 +--- a/drivers/scsi/lpfc/lpfc_hw.h ++++ b/drivers/scsi/lpfc/lpfc_hw.h +@@ -1442,30 +1442,56 @@ struct lpfc_vmid_gallapp_ident_list { + + /* Definitions for HBA / Port attribute entries */ + +-/* Attribute Entry */ +-struct lpfc_fdmi_attr_entry { +- union { +- uint32_t AttrInt; +- uint8_t AttrTypes[32]; +- uint8_t AttrString[256]; +- struct lpfc_name AttrWWN; +- } un; ++/* Attribute Entry Structures */ ++ ++struct lpfc_fdmi_attr_u32 { ++ __be16 type; ++ __be16 len; ++ __be32 value_u32; + }; + +-struct lpfc_fdmi_attr_def { /* Defined in TLV format */ +- /* Structure is in Big Endian format */ +- uint32_t AttrType:16; +- uint32_t AttrLen:16; +- /* Marks start of Value (ATTRIBUTE_ENTRY) */ +- struct lpfc_fdmi_attr_entry AttrValue; +-} __packed; ++struct lpfc_fdmi_attr_wwn { ++ __be16 type; ++ __be16 len; ++ ++ /* Keep as u8[8] instead of __be64 to avoid accidental zero padding ++ * by compiler ++ */ ++ u8 name[8]; ++}; ++ ++struct lpfc_fdmi_attr_fullwwn { ++ __be16 type; ++ __be16 len; ++ ++ /* Keep as u8[8] instead of __be64 to avoid accidental zero padding ++ * by compiler ++ */ ++ u8 nname[8]; ++ u8 pname[8]; ++}; ++ ++struct lpfc_fdmi_attr_fc4types { ++ __be16 type; ++ __be16 len; ++ u8 value_types[32]; ++}; ++ ++struct lpfc_fdmi_attr_string { ++ __be16 type; ++ __be16 len; ++ char value_string[256]; ++}; ++ ++/* Maximum FDMI attribute length is Type+Len (4 bytes) + 256 byte string */ ++#define FDMI_MAX_ATTRLEN sizeof(struct lpfc_fdmi_attr_string) + + /* + * HBA Attribute Block + */ + struct lpfc_fdmi_attr_block { + uint32_t EntryCnt; /* Number of HBA attribute entries */ +- struct lpfc_fdmi_attr_entry Entry; /* Variable-length array */ ++ /* Variable Length Attribute Entry TLV's follow */ + }; + + /* +-- +2.35.3 + diff --git a/patches.suse/scsi-lpfc-rework-lpfc_fdmi_cmd-routine-for-cleanup-and.patch b/patches.suse/scsi-lpfc-rework-lpfc_fdmi_cmd-routine-for-cleanup-and.patch new file mode 100644 index 0000000..6d753f2 --- /dev/null +++ b/patches.suse/scsi-lpfc-rework-lpfc_fdmi_cmd-routine-for-cleanup-and.patch @@ -0,0 +1,188 @@ +From: James Smart +Date: Sun, 11 Sep 2022 15:15:01 -0700 +Subject: scsi: lpfc: Rework lpfc_fdmi_cmd() routine for cleanup and + consistency +Patch-mainline: v6.1-rc1 +Git-commit: 2649809cd1b432e5623d9841dc69a4b8d26e2365 +References: bsc#1203939 + +Switch case logics are reworked so they appear more similar and +consistent. This eliminates compiler errors indicating unaligned pointer +values and packed members. + +Added comments to explain previous size offset accumulations. + +Link: https://lore.kernel.org/r/20220911221505.117655-10-jsmart2021@gmail.com +Co-developed-by: Justin Tee +Signed-off-by: Justin Tee +Signed-off-by: James Smart +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/lpfc/lpfc_ct.c | 53 ++++++++++++++++++++++++-------------------- + 1 file changed, 30 insertions(+), 23 deletions(-) + +--- a/drivers/scsi/lpfc/lpfc_ct.c ++++ b/drivers/scsi/lpfc/lpfc_ct.c +@@ -3533,7 +3533,7 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, + uint32_t mask; + struct lpfc_fdmi_reg_hba *rh; + struct lpfc_fdmi_port_entry *pe; +- struct lpfc_fdmi_reg_portattr *pab = NULL; ++ struct lpfc_fdmi_reg_portattr *pab = NULL, *base = NULL; + struct lpfc_fdmi_attr_block *ab = NULL; + int (*func)(struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad); + void (*cmpl)(struct lpfc_hba *, struct lpfc_iocbq *, +@@ -3566,6 +3566,10 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, + INIT_LIST_HEAD(&rq->list); + INIT_LIST_HEAD(&rsp->list); + ++ /* mbuf buffers are 1K in length - aka LPFC_BPL_SIZE */ ++ memset(rq->virt, 0, LPFC_BPL_SIZE); ++ rsp_size = LPFC_BPL_SIZE; ++ + /* FDMI request */ + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "0218 FDMI Request x%x mask x%x Data: x%x x%x x%x\n", +@@ -3575,7 +3579,6 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, + CtReq = (struct lpfc_sli_ct_request *)rq->virt; + + /* First populate the CT_IU preamble */ +- memset(CtReq, 0, sizeof(struct lpfc_sli_ct_request)); + CtReq->RevisionId.bits.Revision = SLI_CT_REVISION; + CtReq->RevisionId.bits.InId = 0; + +@@ -3583,17 +3586,18 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, + CtReq->FsSubType = SLI_CT_FDMI_Subtypes; + + CtReq->CommandResponse.bits.CmdRsp = cpu_to_be16(cmdcode); +- rsp_size = LPFC_BPL_SIZE; ++ + size = 0; + + /* Next fill in the specific FDMI cmd information */ + switch (cmdcode) { + case SLI_MGMT_RHAT: + case SLI_MGMT_RHBA: +- rh = (struct lpfc_fdmi_reg_hba *)&CtReq->un.PortID; ++ rh = (struct lpfc_fdmi_reg_hba *)&CtReq->un; + /* HBA Identifier */ + memcpy(&rh->hi.PortName, &phba->pport->fc_sparam.portName, + sizeof(struct lpfc_name)); ++ size += sizeof(struct lpfc_fdmi_hba_ident); + + if (cmdcode == SLI_MGMT_RHBA) { + /* Registered Port List */ +@@ -3602,16 +3606,13 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, + memcpy(&rh->rpl.pe.PortName, + &phba->pport->fc_sparam.portName, + sizeof(struct lpfc_name)); +- +- /* point to the HBA attribute block */ +- size = 2 * sizeof(struct lpfc_name) + +- FOURBYTES; +- } else { +- size = sizeof(struct lpfc_name); ++ size += sizeof(struct lpfc_fdmi_reg_port_list); + } ++ + ab = (struct lpfc_fdmi_attr_block *)((uint8_t *)rh + size); + ab->EntryCnt = 0; +- size += FOURBYTES; ++ size += FOURBYTES; /* add length of EntryCnt field */ ++ + bit_pos = 0; + if (new_mask) + mask = new_mask; +@@ -3626,6 +3627,7 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, + (struct lpfc_fdmi_attr_def *) + ((uint8_t *)rh + size)); + ab->EntryCnt++; ++ /* check if another attribute fits */ + if ((size + 256) > + (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) + goto hba_out; +@@ -3636,7 +3638,7 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, + hba_out: + ab->EntryCnt = cpu_to_be32(ab->EntryCnt); + /* Total size */ +- size = GID_REQUEST_SZ - 4 + size; ++ size += GID_REQUEST_SZ - 4; + break; + + case SLI_MGMT_RPRT: +@@ -3647,22 +3649,29 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, + } + fallthrough; + case SLI_MGMT_RPA: +- pab = (struct lpfc_fdmi_reg_portattr *)&CtReq->un.PortID; ++ /* Store base ptr right after preamble */ ++ base = (struct lpfc_fdmi_reg_portattr *)&CtReq->un; ++ + if (cmdcode == SLI_MGMT_RPRT) { +- rh = (struct lpfc_fdmi_reg_hba *)pab; ++ rh = (struct lpfc_fdmi_reg_hba *)base; + /* HBA Identifier */ + memcpy(&rh->hi.PortName, + &phba->pport->fc_sparam.portName, + sizeof(struct lpfc_name)); + pab = (struct lpfc_fdmi_reg_portattr *) +- ((uint8_t *)pab + sizeof(struct lpfc_name)); ++ ((uint8_t *)base + sizeof(struct lpfc_name)); ++ size += sizeof(struct lpfc_name); ++ } else { ++ pab = base; + } + + memcpy((uint8_t *)&pab->PortName, + (uint8_t *)&vport->fc_sparam.portName, + sizeof(struct lpfc_name)); +- size += sizeof(struct lpfc_name) + FOURBYTES; + pab->ab.EntryCnt = 0; ++ /* add length of name and EntryCnt field */ ++ size += sizeof(struct lpfc_name) + FOURBYTES; ++ + bit_pos = 0; + if (new_mask) + mask = new_mask; +@@ -3675,8 +3684,9 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, + func = lpfc_fdmi_port_action[bit_pos]; + size += func(vport, + (struct lpfc_fdmi_attr_def *) +- ((uint8_t *)pab + size)); ++ ((uint8_t *)base + size)); + pab->ab.EntryCnt++; ++ /* check if another attribute fits */ + if ((size + 256) > + (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) + goto port_out; +@@ -3686,10 +3696,7 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, + } + port_out: + pab->ab.EntryCnt = cpu_to_be32(pab->ab.EntryCnt); +- /* Total size */ +- if (cmdcode == SLI_MGMT_RPRT) +- size += sizeof(struct lpfc_name); +- size = GID_REQUEST_SZ - 4 + size; ++ size += GID_REQUEST_SZ - 4; + break; + + case SLI_MGMT_GHAT: +@@ -3698,7 +3705,7 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, + fallthrough; + case SLI_MGMT_DHBA: + case SLI_MGMT_DHAT: +- pe = (struct lpfc_fdmi_port_entry *)&CtReq->un.PortID; ++ pe = (struct lpfc_fdmi_port_entry *)&CtReq->un; + memcpy((uint8_t *)&pe->PortName, + (uint8_t *)&vport->fc_sparam.portName, + sizeof(struct lpfc_name)); +@@ -3717,7 +3724,7 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, + } + fallthrough; + case SLI_MGMT_DPA: +- pe = (struct lpfc_fdmi_port_entry *)&CtReq->un.PortID; ++ pe = (struct lpfc_fdmi_port_entry *)&CtReq->un; + memcpy((uint8_t *)&pe->PortName, + (uint8_t *)&vport->fc_sparam.portName, + sizeof(struct lpfc_name)); diff --git a/patches.suse/scsi-lpfc-update-congestion-mode-logging-for-emulex-san-manager.patch b/patches.suse/scsi-lpfc-update-congestion-mode-logging-for-emulex-san-manager.patch new file mode 100644 index 0000000..ca126c3 --- /dev/null +++ b/patches.suse/scsi-lpfc-update-congestion-mode-logging-for-emulex-san-manager.patch @@ -0,0 +1,89 @@ +From: James Smart +Date: Sun, 11 Sep 2022 15:14:59 -0700 +Subject: scsi: lpfc: Update congestion mode logging for Emulex SAN Manager + application +Patch-mainline: v6.1-rc1 +Git-commit: 21828e3c9169e9664c916c61eb592db8b8830bd6 +References: bsc#1203939 + +If there is a congestion or automated congestion response mode change, then +log the reported change to kmsg. + +Link: https://lore.kernel.org/r/20220911221505.117655-8-jsmart2021@gmail.com +Co-developed-by: Justin Tee +Signed-off-by: Justin Tee +Signed-off-by: James Smart +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/lpfc/lpfc_init.c | 28 ++++++++++++++++++++++------ + 1 file changed, 22 insertions(+), 6 deletions(-) + +diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c +index 0a4a82f5df5c..b170e9e9f167 100644 +--- a/drivers/scsi/lpfc/lpfc_init.c ++++ b/drivers/scsi/lpfc/lpfc_init.c +@@ -7038,6 +7038,12 @@ lpfc_cgn_params_val(struct lpfc_hba *phba, struct lpfc_cgn_param *p_cfg_param) + spin_unlock_irq(&phba->hbalock); + } + ++static const char * const lpfc_cmf_mode_to_str[] = { ++ "OFF", ++ "MANAGED", ++ "MONITOR", ++}; ++ + /** + * lpfc_cgn_params_parse - Process a FW cong parm change event + * @phba: pointer to lpfc hba data structure. +@@ -7057,6 +7063,7 @@ lpfc_cgn_params_parse(struct lpfc_hba *phba, + { + struct lpfc_cgn_info *cp; + uint32_t crc, oldmode; ++ char acr_string[4] = {0}; + + /* Make sure the FW has encoded the correct magic number to + * validate the congestion parameter in FW memory. +@@ -7133,9 +7140,6 @@ lpfc_cgn_params_parse(struct lpfc_hba *phba, + lpfc_issue_els_edc(phba->pport, 0); + break; + case LPFC_CFG_MONITOR: +- lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT, +- "4661 Switch from MANAGED to " +- "`MONITOR mode\n"); + phba->cmf_max_bytes_per_interval = + phba->cmf_link_byte_count; + +@@ -7154,14 +7158,26 @@ lpfc_cgn_params_parse(struct lpfc_hba *phba, + lpfc_issue_els_edc(phba->pport, 0); + break; + case LPFC_CFG_MANAGED: +- lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT, +- "4662 Switch from MONITOR to " +- "MANAGED mode\n"); + lpfc_cmf_signal_init(phba); + break; + } + break; + } ++ if (oldmode != LPFC_CFG_OFF || ++ oldmode != phba->cgn_p.cgn_param_mode) { ++ if (phba->cgn_p.cgn_param_mode == LPFC_CFG_MANAGED) ++ scnprintf(acr_string, sizeof(acr_string), "%u", ++ phba->cgn_p.cgn_param_level0); ++ else ++ scnprintf(acr_string, sizeof(acr_string), "NA"); ++ ++ dev_info(&phba->pcidev->dev, "%d: " ++ "4663 CMF: Mode %s acr %s\n", ++ phba->brd_no, ++ lpfc_cmf_mode_to_str ++ [phba->cgn_p.cgn_param_mode], ++ acr_string); ++ } + } else { + lpfc_printf_log(phba, KERN_ERR, LOG_CGN_MGMT | LOG_INIT, + "4669 FW cgn parm buf wrong magic 0x%x " +-- +2.35.3 + diff --git a/patches.suse/scsi-lpfc-update-lpfc-version-to-14.2.0.7.patch b/patches.suse/scsi-lpfc-update-lpfc-version-to-14.2.0.7.patch new file mode 100644 index 0000000..8b0f61a --- /dev/null +++ b/patches.suse/scsi-lpfc-update-lpfc-version-to-14.2.0.7.patch @@ -0,0 +1,35 @@ +From: James Smart +Date: Sun, 11 Sep 2022 15:15:05 -0700 +Subject: scsi: lpfc: Update lpfc version to 14.2.0.7 +Patch-mainline: v6.1-rc1 +Git-commit: 7170cb1a85e65d31b8b5b96fa7b502e559304946 +References: bsc#1203939 + +Update lpfc version to 14.2.0.7 + +Link: https://lore.kernel.org/r/20220911221505.117655-14-jsmart2021@gmail.com +Co-developed-by: Justin Tee +Signed-off-by: Justin Tee +Signed-off-by: James Smart +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/lpfc/lpfc_version.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h +index aa89225e0595..192d5630a44d 100644 +--- a/drivers/scsi/lpfc/lpfc_version.h ++++ b/drivers/scsi/lpfc/lpfc_version.h +@@ -20,7 +20,7 @@ + * included with this package. * + *******************************************************************/ + +-#define LPFC_DRIVER_VERSION "14.2.0.6" ++#define LPFC_DRIVER_VERSION "14.2.0.7" + #define LPFC_DRIVER_NAME "lpfc" + + /* Used for SLI 2/3 */ +-- +2.35.3 + diff --git a/patches.suse/scsi-mpt3sas-Fix-use-after-free-warning.patch b/patches.suse/scsi-mpt3sas-Fix-use-after-free-warning.patch new file mode 100644 index 0000000..9eff902 --- /dev/null +++ b/patches.suse/scsi-mpt3sas-Fix-use-after-free-warning.patch @@ -0,0 +1,42 @@ +From: Sreekanth Reddy +Date: Tue, 6 Sep 2022 19:19:08 +0530 +Subject: scsi: mpt3sas: Fix use-after-free warning +Git-commit: 991df3dd5144f2e6b1c38b8d20ed3d4d21e20b34 +Patch-mainline: v6.0-rc5 +References: git-fixes + +Fix the following use-after-free warning which is observed during +controller reset: + +refcount_t: underflow; use-after-free. +WARNING: CPU: 23 PID: 5399 at lib/refcount.c:28 refcount_warn_saturate+0xa6/0xf0 + +Link: https://lore.kernel.org/r/20220906134908.1039-2-sreekanth.reddy@broadcom.com +Signed-off-by: Sreekanth Reddy +Signed-off-by: Martin K. Petersen +Acked-by: Lee Duncan +--- + drivers/scsi/mpt3sas/mpt3sas_scsih.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +index def37a7e5980..bd6a5f1bd532 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +@@ -3670,6 +3670,7 @@ static struct fw_event_work *dequeue_next_fw_event(struct MPT3SAS_ADAPTER *ioc) + fw_event = list_first_entry(&ioc->fw_event_list, + struct fw_event_work, list); + list_del_init(&fw_event->list); ++ fw_event_work_put(fw_event); + } + spin_unlock_irqrestore(&ioc->fw_event_lock, flags); + +@@ -3751,7 +3752,6 @@ _scsih_fw_event_cleanup_queue(struct MPT3SAS_ADAPTER *ioc) + if (cancel_work_sync(&fw_event->work)) + fw_event_work_put(fw_event); + +- fw_event_work_put(fw_event); + } + ioc->fw_events_cleanup = 0; + } + diff --git a/patches.suse/scsi-qla2xxx-Disable-ATIO-interrupt-coalesce-for-qua.patch b/patches.suse/scsi-qla2xxx-Disable-ATIO-interrupt-coalesce-for-qua.patch new file mode 100644 index 0000000..53ece0f --- /dev/null +++ b/patches.suse/scsi-qla2xxx-Disable-ATIO-interrupt-coalesce-for-qua.patch @@ -0,0 +1,47 @@ +From: Tony Battersby +Date: Thu, 7 Jul 2022 15:08:01 -0400 +Subject: scsi: qla2xxx: Disable ATIO interrupt coalesce for quad port ISP27XX +Patch-mainline: v6.0-rc3 +Git-commit: 53661ded2460b414644532de6b99bd87f71987e9 +References: bsc#1203935 + +This partially reverts commit d2b292c3f6fd ("scsi: qla2xxx: Enable ATIO +interrupt handshake for ISP27XX") + +For some workloads where the host sends a batch of commands and then +pauses, ATIO interrupt coalesce can cause some incoming ATIO entries to be +ignored for extended periods of time, resulting in slow performance, +timeouts, and aborted commands. + +Disable interrupt coalesce and re-enable the dedicated ATIO MSI-X +interrupt. + +Link: https://lore.kernel.org/r/97dcf365-89ff-014d-a3e5-1404c6af511c@cybernetics.com +Reviewed-by: Himanshu Madhani +Reviewed-by: Nilesh Javali +Signed-off-by: Tony Battersby +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/qla2xxx/qla_target.c | 10 ++-------- + 1 file changed, 2 insertions(+), 8 deletions(-) + +--- a/drivers/scsi/qla2xxx/qla_target.c ++++ b/drivers/scsi/qla2xxx/qla_target.c +@@ -6935,14 +6935,8 @@ qlt_24xx_config_rings(struct scsi_qla_ho + + if (ha->flags.msix_enabled) { + if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) { +- if (IS_QLA2071(ha)) { +- /* 4 ports Baker: Enable Interrupt Handshake */ +- icb->msix_atio = 0; +- icb->firmware_options_2 |= cpu_to_le32(BIT_26); +- } else { +- icb->msix_atio = cpu_to_le16(msix->entry); +- icb->firmware_options_2 &= cpu_to_le32(~BIT_26); +- } ++ icb->msix_atio = cpu_to_le16(msix->entry); ++ icb->firmware_options_2 &= cpu_to_le32(~BIT_26); + ql_dbg(ql_dbg_init, vha, 0xf072, + "Registering ICB vector 0x%x for atio que.\n", + msix->entry); diff --git a/patches.suse/scsi-qla2xxx-Fix-disk-failure-to-rediscover.patch b/patches.suse/scsi-qla2xxx-Fix-disk-failure-to-rediscover.patch new file mode 100644 index 0000000..1efdfde --- /dev/null +++ b/patches.suse/scsi-qla2xxx-Fix-disk-failure-to-rediscover.patch @@ -0,0 +1,77 @@ +From: Quinn Tran +Date: Thu, 10 Mar 2022 01:25:53 -0800 +Subject: scsi: qla2xxx: Fix disk failure to rediscover +Git-commit: 6a45c8e137d4e2c72eecf1ac7cf64f2fdfcead99 +Patch-mainline: v5.18-rc1 +References: git-fixes + +User experienced some of the LUN failed to get rediscovered after long +cable pull test. The issue is triggered by a race condition between driver +setting session online state vs starting the LUN scan process at the same +time. Current code set the online state after notifying the session is +available. In this case, trigger to start the LUN scan process happened +before driver could set the session in online state. LUN scan ends up with +failure due to the session online check was failing. + +Set the online state before reporting of the availability of the session. + +Link: https://lore.kernel.org/r/20220310092604.22950-3-njavali@marvell.com +Fixes: aecf043443d3 ("scsi: qla2xxx: Fix Remote port registration") +Cc: stable@vger.kernel.org +Reviewed-by: Himanshu Madhani +Signed-off-by: Quinn Tran +Signed-off-by: Nilesh Javali +Signed-off-by: Martin K. Petersen +Acked-by: Lee Duncan +--- + drivers/scsi/qla2xxx/qla_init.c | 5 +++-- + drivers/scsi/qla2xxx/qla_nvme.c | 5 +++++ + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c +index 2f3a3cd31bd6..e468b05f90c0 100644 +--- a/drivers/scsi/qla2xxx/qla_init.c ++++ b/drivers/scsi/qla2xxx/qla_init.c +@@ -5758,6 +5758,8 @@ qla2x00_reg_remote_port(scsi_qla_host_t *vha, fc_port_t *fcport) + if (atomic_read(&fcport->state) == FCS_ONLINE) + return; + ++ qla2x00_set_fcport_state(fcport, FCS_ONLINE); ++ + rport_ids.node_name = wwn_to_u64(fcport->node_name); + rport_ids.port_name = wwn_to_u64(fcport->port_name); + rport_ids.port_id = fcport->d_id.b.domain << 16 | +@@ -5858,6 +5860,7 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport) + qla2x00_reg_remote_port(vha, fcport); + break; + case MODE_TARGET: ++ qla2x00_set_fcport_state(fcport, FCS_ONLINE); + if (!vha->vha_tgt.qla_tgt->tgt_stop && + !vha->vha_tgt.qla_tgt->tgt_stopped) + qlt_fc_port_added(vha, fcport); +@@ -5875,8 +5878,6 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport) + if (NVME_TARGET(vha->hw, fcport)) + qla_nvme_register_remote(vha, fcport); + +- qla2x00_set_fcport_state(fcport, FCS_ONLINE); +- + if (IS_IIDMA_CAPABLE(vha->hw) && vha->hw->flags.gpsc_supported) { + if (fcport->id_changed) { + fcport->id_changed = 0; +diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c +index 718c761ff5f8..5723082d94d6 100644 +--- a/drivers/scsi/qla2xxx/qla_nvme.c ++++ b/drivers/scsi/qla2xxx/qla_nvme.c +@@ -37,6 +37,11 @@ int qla_nvme_register_remote(struct scsi_qla_host *vha, struct fc_port *fcport) + (fcport->nvme_flag & NVME_FLAG_REGISTERED)) + return 0; + ++ if (atomic_read(&fcport->state) == FCS_ONLINE) ++ return 0; ++ ++ qla2x00_set_fcport_state(fcport, FCS_ONLINE); ++ + fcport->nvme_flag &= ~NVME_FLAG_RESETTING; + + memset(&req, 0, sizeof(struct nvme_fc_port_info)); + diff --git a/patches.suse/scsi-qla2xxx-Fix-memory-leak-in-__qlt_24xx_handle_ab.patch b/patches.suse/scsi-qla2xxx-Fix-memory-leak-in-__qlt_24xx_handle_ab.patch new file mode 100644 index 0000000..74e046c --- /dev/null +++ b/patches.suse/scsi-qla2xxx-Fix-memory-leak-in-__qlt_24xx_handle_ab.patch @@ -0,0 +1,36 @@ +From: Rafael Mendonca +Date: Tue, 13 Sep 2022 23:49:24 -0300 +Subject: scsi: qla2xxx: Fix memory leak in __qlt_24xx_handle_abts() +Patch-mainline: v6.0-rc7 +Git-commit: 601be20fc6a1b762044d2398befffd6bf236cebf +References: bsc#1203935 + +Commit 8f394da36a36 ("scsi: qla2xxx: Drop TARGET_SCF_LOOKUP_LUN_FROM_TAG") +made the __qlt_24xx_handle_abts() function return early if +tcm_qla2xxx_find_cmd_by_tag() didn't find a command, but it missed to clean +up the allocated memory for the management command. + +Link: https://lore.kernel.org/r/20220914024924.695604-1-rafaelmendsr@gmail.com +Fixes: 8f394da36a36 ("scsi: qla2xxx: Drop TARGET_SCF_LOOKUP_LUN_FROM_TAG") +Reviewed-by: Himanshu Madhani +Signed-off-by: Rafael Mendonca +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/qla2xxx/qla_target.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/scsi/qla2xxx/qla_target.c ++++ b/drivers/scsi/qla2xxx/qla_target.c +@@ -2151,8 +2151,10 @@ static int __qlt_24xx_handle_abts(struct + + abort_cmd = ha->tgt.tgt_ops->find_cmd_by_tag(sess, + le32_to_cpu(abts->exchange_addr_to_abort)); +- if (!abort_cmd) ++ if (!abort_cmd) { ++ mempool_free(mcmd, qla_tgt_mgmt_cmd_mempool); + return -EIO; ++ } + mcmd->unpacked_lun = abort_cmd->se_cmd.orig_fe_lun; + + if (abort_cmd->qpair) { diff --git a/patches.suse/scsi-qla2xxx-add-debugfs-create-delete-helpers.patch b/patches.suse/scsi-qla2xxx-add-debugfs-create-delete-helpers.patch new file mode 100644 index 0000000..09f03f6 --- /dev/null +++ b/patches.suse/scsi-qla2xxx-add-debugfs-create-delete-helpers.patch @@ -0,0 +1,143 @@ +From: Arun Easi +Date: Fri, 26 Aug 2022 03:25:55 -0700 +Subject: scsi: qla2xxx: Add debugfs create/delete helpers +Patch-mainline: v6.1-rc1 +Git-commit: 389f179b868e43121c6cfccfbf5e495842a766fd +References: bsc#1203935 + +Define a few helpful macros for creating debugfs files. + +Link: https://lore.kernel.org/r/20220826102559.17474-4-njavali@marvell.com +Reviewed-by: Himanshu Madhani +Signed-off-by: Arun Easi +Signed-off-by: Nilesh Javali +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/qla2xxx/qla_def.h | 5 ++ + drivers/scsi/qla2xxx/qla_dfs.c | 93 ++++++++++++++++++++++++++++++++++ + 2 files changed, 98 insertions(+) + +diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h +index 3ec6a200942e..22274b405d01 100644 +--- a/drivers/scsi/qla2xxx/qla_def.h ++++ b/drivers/scsi/qla2xxx/qla_def.h +@@ -35,6 +35,11 @@ + + #include + ++#define QLA_DFS_DEFINE_DENTRY(_debugfs_file_name) \ ++ struct dentry *dfs_##_debugfs_file_name ++#define QLA_DFS_ROOT_DEFINE_DENTRY(_debugfs_file_name) \ ++ struct dentry *qla_dfs_##_debugfs_file_name ++ + /* Big endian Fibre Channel S_ID (source ID) or D_ID (destination ID). */ + typedef struct { + uint8_t domain; +diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c +index 85bd0e468d43..777808af5634 100644 +--- a/drivers/scsi/qla2xxx/qla_dfs.c ++++ b/drivers/scsi/qla2xxx/qla_dfs.c +@@ -489,6 +489,99 @@ qla_dfs_naqp_show(struct seq_file *s, void *unused) + return 0; + } + ++/* ++ * Helper macros for setting up debugfs entries. ++ * _name: The name of the debugfs entry ++ * _ctx_struct: The context that was passed when creating the debugfs file ++ * ++ * QLA_DFS_SETUP_RD could be used when there is only a show function. ++ * - show function take the name qla_dfs__show ++ * ++ * QLA_DFS_SETUP_RW could be used when there are both show and write functions. ++ * - show function take the name qla_dfs__show ++ * - write function take the name qla_dfs__write ++ * ++ * To have a new debugfs entry, do: ++ * 1. Create a "struct dentry *" in the appropriate structure in the format ++ * dfs_ ++ * 2. Setup debugfs entries using QLA_DFS_SETUP_RD / QLA_DFS_SETUP_RW ++ * 3. Create debugfs file in qla2x00_dfs_setup() using QLA_DFS_CREATE_FILE ++ * or QLA_DFS_ROOT_CREATE_FILE ++ * 4. Remove debugfs file in qla2x00_dfs_remove() using QLA_DFS_REMOVE_FILE ++ * or QLA_DFS_ROOT_REMOVE_FILE ++ * ++ * Example for creating "TEST" sysfs file: ++ * 1. struct qla_hw_data { ... struct dentry *dfs_TEST; } ++ * 2. QLA_DFS_SETUP_RD(TEST, scsi_qla_host_t); ++ * 3. In qla2x00_dfs_setup(): ++ * QLA_DFS_CREATE_FILE(ha, TEST, 0600, ha->dfs_dir, vha); ++ * 4. In qla2x00_dfs_remove(): ++ * QLA_DFS_REMOVE_FILE(ha, TEST); ++ */ ++#define QLA_DFS_SETUP_RD(_name, _ctx_struct) \ ++static int \ ++qla_dfs_##_name##_open(struct inode *inode, struct file *file) \ ++{ \ ++ _ctx_struct *__ctx = inode->i_private; \ ++ \ ++ return single_open(file, qla_dfs_##_name##_show, __ctx); \ ++} \ ++ \ ++static const struct file_operations qla_dfs_##_name##_ops = { \ ++ .open = qla_dfs_##_name##_open, \ ++ .read = seq_read, \ ++ .llseek = seq_lseek, \ ++ .release = single_release, \ ++}; ++ ++#define QLA_DFS_SETUP_RW(_name, _ctx_struct) \ ++static int \ ++qla_dfs_##_name##_open(struct inode *inode, struct file *file) \ ++{ \ ++ _ctx_struct *__ctx = inode->i_private; \ ++ \ ++ return single_open(file, qla_dfs_##_name##_show, __ctx); \ ++} \ ++ \ ++static const struct file_operations qla_dfs_##_name##_ops = { \ ++ .open = qla_dfs_##_name##_open, \ ++ .read = seq_read, \ ++ .llseek = seq_lseek, \ ++ .release = single_release, \ ++ .write = qla_dfs_##_name##_write, \ ++}; ++ ++#define QLA_DFS_ROOT_CREATE_FILE(_name, _perm, _ctx) \ ++ do { \ ++ if (!qla_dfs_##_name) \ ++ qla_dfs_##_name = debugfs_create_file(#_name, \ ++ _perm, qla2x00_dfs_root, _ctx, \ ++ &qla_dfs_##_name##_ops); \ ++ } while (0) ++ ++#define QLA_DFS_ROOT_REMOVE_FILE(_name) \ ++ do { \ ++ if (qla_dfs_##_name) { \ ++ debugfs_remove(qla_dfs_##_name); \ ++ qla_dfs_##_name = NULL; \ ++ } \ ++ } while (0) ++ ++#define QLA_DFS_CREATE_FILE(_struct, _name, _perm, _parent, _ctx) \ ++ do { \ ++ (_struct)->dfs_##_name = debugfs_create_file(#_name, \ ++ _perm, _parent, _ctx, \ ++ &qla_dfs_##_name##_ops) \ ++ } while (0) ++ ++#define QLA_DFS_REMOVE_FILE(_struct, _name) \ ++ do { \ ++ if ((_struct)->dfs_##_name) { \ ++ debugfs_remove((_struct)->dfs_##_name); \ ++ (_struct)->dfs_##_name = NULL; \ ++ } \ ++ } while (0) ++ + static int + qla_dfs_naqp_open(struct inode *inode, struct file *file) + { +-- +2.35.3 + diff --git a/patches.suse/scsi-qla2xxx-add-nvme-parameters-support-in-auxiliary-image-status.patch b/patches.suse/scsi-qla2xxx-add-nvme-parameters-support-in-auxiliary-image-status.patch new file mode 100644 index 0000000..4f68287 --- /dev/null +++ b/patches.suse/scsi-qla2xxx-add-nvme-parameters-support-in-auxiliary-image-status.patch @@ -0,0 +1,141 @@ +From: Anil Gurumurthy +Date: Fri, 26 Aug 2022 03:25:56 -0700 +Subject: scsi: qla2xxx: Add NVMe parameters support in Auxiliary Image Status +Patch-mainline: v6.1-rc1 +Git-commit: d9ba85efc3fc743aa3c958efa996f397719cdc2a +References: bsc#1203935 + +Add new API to obtain the NVMe Parameters region status from the Auxiliary +Image Status bitmap. + +Link: https://lore.kernel.org/r/20220826102559.17474-5-njavali@marvell.com +Reviewed-by: Himanshu Madhani +Signed-off-by: Anil Gurumurthy +Signed-off-by: Nilesh Javali +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/qla2xxx/qla_bsg.c | 8 ++++++-- + drivers/scsi/qla2xxx/qla_bsg.h | 3 ++- + drivers/scsi/qla2xxx/qla_def.h | 2 ++ + drivers/scsi/qla2xxx/qla_fw.h | 3 +++ + drivers/scsi/qla2xxx/qla_init.c | 8 ++++++-- + 5 files changed, 19 insertions(+), 5 deletions(-) + +diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c +index 5db9bf69dcff..cd75b179410d 100644 +--- a/drivers/scsi/qla2xxx/qla_bsg.c ++++ b/drivers/scsi/qla2xxx/qla_bsg.c +@@ -2519,19 +2519,23 @@ qla2x00_get_flash_image_status(struct bsg_job *bsg_job) + qla27xx_get_active_image(vha, &active_regions); + regions.global_image = active_regions.global; + ++ if (IS_QLA27XX(ha)) ++ regions.nvme_params = QLA27XX_PRIMARY_IMAGE; ++ + if (IS_QLA28XX(ha)) { + qla28xx_get_aux_images(vha, &active_regions); + regions.board_config = active_regions.aux.board_config; + regions.vpd_nvram = active_regions.aux.vpd_nvram; + regions.npiv_config_0_1 = active_regions.aux.npiv_config_0_1; + regions.npiv_config_2_3 = active_regions.aux.npiv_config_2_3; ++ regions.nvme_params = active_regions.aux.nvme_params; + } + + ql_dbg(ql_dbg_user, vha, 0x70e1, +- "%s(%lu): FW=%u BCFG=%u VPDNVR=%u NPIV01=%u NPIV02=%u\n", ++ "%s(%lu): FW=%u BCFG=%u VPDNVR=%u NPIV01=%u NPIV02=%u NVME_PARAMS=%u\n", + __func__, vha->host_no, regions.global_image, + regions.board_config, regions.vpd_nvram, +- regions.npiv_config_0_1, regions.npiv_config_2_3); ++ regions.npiv_config_0_1, regions.npiv_config_2_3, regions.nvme_params); + + sg_copy_from_buffer(bsg_job->reply_payload.sg_list, + bsg_job->reply_payload.sg_cnt, ®ions, sizeof(regions)); +diff --git a/drivers/scsi/qla2xxx/qla_bsg.h b/drivers/scsi/qla2xxx/qla_bsg.h +index bb64b9c5a74b..d38dab0a07e8 100644 +--- a/drivers/scsi/qla2xxx/qla_bsg.h ++++ b/drivers/scsi/qla2xxx/qla_bsg.h +@@ -314,7 +314,8 @@ struct qla_active_regions { + uint8_t vpd_nvram; + uint8_t npiv_config_0_1; + uint8_t npiv_config_2_3; +- uint8_t reserved[32]; ++ uint8_t nvme_params; ++ uint8_t reserved[31]; + } __packed; + + #include "qla_edif_bsg.h" +diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h +index 22274b405d01..802eec6407d9 100644 +--- a/drivers/scsi/qla2xxx/qla_def.h ++++ b/drivers/scsi/qla2xxx/qla_def.h +@@ -4773,6 +4773,7 @@ struct active_regions { + uint8_t vpd_nvram; + uint8_t npiv_config_0_1; + uint8_t npiv_config_2_3; ++ uint8_t nvme_params; + } aux; + }; + +@@ -5057,6 +5058,7 @@ struct qla27xx_image_status { + #define QLA28XX_AUX_IMG_VPD_NVRAM BIT_1 + #define QLA28XX_AUX_IMG_NPIV_CONFIG_0_1 BIT_2 + #define QLA28XX_AUX_IMG_NPIV_CONFIG_2_3 BIT_3 ++#define QLA28XX_AUX_IMG_NVME_PARAMS BIT_4 + + #define SET_VP_IDX 1 + #define SET_AL_PA 2 +diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h +index 361015b5763e..f307beed9d29 100644 +--- a/drivers/scsi/qla2xxx/qla_fw.h ++++ b/drivers/scsi/qla2xxx/qla_fw.h +@@ -1675,6 +1675,7 @@ struct qla_flt_location { + #define FLT_REG_VPD_SEC_27XX_1 0x52 + #define FLT_REG_VPD_SEC_27XX_2 0xD8 + #define FLT_REG_VPD_SEC_27XX_3 0xDA ++#define FLT_REG_NVME_PARAMS_27XX 0x21 + + /* 28xx */ + #define FLT_REG_AUX_IMG_PRI_28XX 0x125 +@@ -1691,6 +1692,8 @@ struct qla_flt_location { + #define FLT_REG_MPI_SEC_28XX 0xF0 + #define FLT_REG_PEP_PRI_28XX 0xD1 + #define FLT_REG_PEP_SEC_28XX 0xF1 ++#define FLT_REG_NVME_PARAMS_PRI_28XX 0x14E ++#define FLT_REG_NVME_PARAMS_SEC_28XX 0x179 + + struct qla_flt_region { + __le16 code; +diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c +index e7fe0e52c11d..e12db95de688 100644 +--- a/drivers/scsi/qla2xxx/qla_init.c ++++ b/drivers/scsi/qla2xxx/qla_init.c +@@ -7933,6 +7933,9 @@ qla28xx_component_status( + + active_regions->aux.npiv_config_2_3 = + qla28xx_component_bitmask(aux, QLA28XX_AUX_IMG_NPIV_CONFIG_2_3); ++ ++ active_regions->aux.nvme_params = ++ qla28xx_component_bitmask(aux, QLA28XX_AUX_IMG_NVME_PARAMS); + } + + static int +@@ -8041,11 +8044,12 @@ qla28xx_get_aux_images( + } + + ql_dbg(ql_dbg_init, vha, 0x018f, +- "aux images active: BCFG=%u VPD/NVR=%u NPIV0/1=%u NPIV2/3=%u\n", ++ "aux images active: BCFG=%u VPD/NVR=%u NPIV0/1=%u NPIV2/3=%u, NVME=%u\n", + active_regions->aux.board_config, + active_regions->aux.vpd_nvram, + active_regions->aux.npiv_config_0_1, +- active_regions->aux.npiv_config_2_3); ++ active_regions->aux.npiv_config_2_3, ++ active_regions->aux.nvme_params); + } + + void +-- +2.35.3 + diff --git a/patches.suse/scsi-qla2xxx-always-wait-for-qlt_sess_work_fn-from.patch b/patches.suse/scsi-qla2xxx-always-wait-for-qlt_sess_work_fn-from.patch new file mode 100644 index 0000000..d77941d --- /dev/null +++ b/patches.suse/scsi-qla2xxx-always-wait-for-qlt_sess_work_fn-from.patch @@ -0,0 +1,48 @@ +From: Tetsuo Handa +Date: Sun, 21 Aug 2022 12:59:00 +0900 +Subject: scsi: qla2xxx: Always wait for qlt_sess_work_fn() from + qlt_stop_phase1() +Patch-mainline: v6.1-rc1 +Git-commit: a4345557527f7d9dab6684fc2d1dd7800e99d73a +References: bsc#1203935 + +Currently qlt_stop_phase1() may fail to call flush_scheduled_work(), for +list_empty() may return true as soon as qlt_sess_work_fn() called +list_del(). In order to close this race window, check list_empty() after +calling flush_scheduled_work(). + +If this patch causes problems, please check commit c4f135d64382 +("workqueue: Wrap flush_workqueue() using a macro"). We are on the way to +remove all flush_scheduled_work() calls from the kernel. + +Link: https://lore.kernel.org/r/7f24469d-9e39-3398-d851-329b54c0b923@I-love.SAKURA.ne.jp +Tested-by: Himanshu Madhani +Reviewed-by: Himanshu Madhani +Signed-off-by: Tetsuo Handa +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/qla2xxx/qla_target.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c +index b170ebbd05b7..9013c162d4aa 100644 +--- a/drivers/scsi/qla2xxx/qla_target.c ++++ b/drivers/scsi/qla2xxx/qla_target.c +@@ -1557,11 +1557,11 @@ int qlt_stop_phase1(struct qla_tgt *tgt) + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf009, + "Waiting for sess works (tgt %p)", tgt); + spin_lock_irqsave(&tgt->sess_work_lock, flags); +- while (!list_empty(&tgt->sess_works_list)) { ++ do { + spin_unlock_irqrestore(&tgt->sess_work_lock, flags); + flush_scheduled_work(); + spin_lock_irqsave(&tgt->sess_work_lock, flags); +- } ++ } while (!list_empty(&tgt->sess_works_list)); + spin_unlock_irqrestore(&tgt->sess_work_lock, flags); + + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00a, +-- +2.35.3 + diff --git a/patches.suse/scsi-qla2xxx-avoid-flush_scheduled_work-usage.patch b/patches.suse/scsi-qla2xxx-avoid-flush_scheduled_work-usage.patch new file mode 100644 index 0000000..aed1081 --- /dev/null +++ b/patches.suse/scsi-qla2xxx-avoid-flush_scheduled_work-usage.patch @@ -0,0 +1,38 @@ +From: Tetsuo Handa +Date: Sun, 21 Aug 2022 12:59:44 +0900 +Subject: scsi: qla2xxx: Avoid flush_scheduled_work() usage +Patch-mainline: v6.1-rc1 +Git-commit: 3cb0643a9aae7cf360102a6a9db47f5ce9fefdb1 +References: bsc#1203935 + +Although qla2xxx driver is calling schedule_{,delayed}_work() from 10 +locations, I assume that flush_scheduled_work() from qlt_stop_phase1() +needs to flush only works scheduled by qlt_sched_sess_work(), for this loop +continues while "struct qla_tgt"->sess_works_list is not empty. + +Link: https://lore.kernel.org/r/133c6723-90b6-5c8b-72b4-cc01eeb3a8c0@I-love.SAKURA.ne.jp +Tested-by: Himanshu Madhani +Reviewed-by: Himanshu Madhani +Signed-off-by: Tetsuo Handa +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/qla2xxx/qla_target.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c +index 9013c162d4aa..b0cb463cf032 100644 +--- a/drivers/scsi/qla2xxx/qla_target.c ++++ b/drivers/scsi/qla2xxx/qla_target.c +@@ -1559,7 +1559,7 @@ int qlt_stop_phase1(struct qla_tgt *tgt) + spin_lock_irqsave(&tgt->sess_work_lock, flags); + do { + spin_unlock_irqrestore(&tgt->sess_work_lock, flags); +- flush_scheduled_work(); ++ flush_work(&tgt->sess_work); + spin_lock_irqsave(&tgt->sess_work_lock, flags); + } while (!list_empty(&tgt->sess_works_list)); + spin_unlock_irqrestore(&tgt->sess_work_lock, flags); +-- +2.35.3 + diff --git a/patches.suse/scsi-qla2xxx-define-static-symbols.patch b/patches.suse/scsi-qla2xxx-define-static-symbols.patch new file mode 100644 index 0000000..7706baf --- /dev/null +++ b/patches.suse/scsi-qla2xxx-define-static-symbols.patch @@ -0,0 +1,52 @@ +From: Nilesh Javali +Date: Fri, 26 Aug 2022 03:25:58 -0700 +Subject: scsi: qla2xxx: Define static symbols +Patch-mainline: v6.1-rc1 +Git-commit: 2c57d0defa22b2339c06364a275bcc9048a77255 +References: bsc#1203935 + +drivers/scsi/qla2xxx/qla_os.c:40:20: warning: symbol 'qla_trc_array' +was not declared. Should it be static? +drivers/scsi/qla2xxx/qla_os.c:345:5: warning: symbol +'ql2xdelay_before_pci_error_handling' was not declared. +Should it be static? + +Define qla_trc_array and ql2xdelay_before_pci_error_handling as static to +fix sparse warnings. + +Link: https://lore.kernel.org/r/20220826102559.17474-7-njavali@marvell.com +Cc: stable@vger.kernel.org +Reported-by: kernel test robot +Reviewed-by: Himanshu Madhani +Signed-off-by: Nilesh Javali +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/qla2xxx/qla_os.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c +index f76ae8a64ea9..0ccaeea4e1bd 100644 +--- a/drivers/scsi/qla2xxx/qla_os.c ++++ b/drivers/scsi/qla2xxx/qla_os.c +@@ -37,7 +37,7 @@ static int apidev_major; + */ + struct kmem_cache *srb_cachep; + +-struct trace_array *qla_trc_array; ++static struct trace_array *qla_trc_array; + + int ql2xfulldump_on_mpifail; + module_param(ql2xfulldump_on_mpifail, int, S_IRUGO | S_IWUSR); +@@ -342,7 +342,7 @@ MODULE_PARM_DESC(ql2xabts_wait_nvme, + "To wait for ABTS response on I/O timeouts for NVMe. (default: 1)"); + + +-u32 ql2xdelay_before_pci_error_handling = 5; ++static u32 ql2xdelay_before_pci_error_handling = 5; + module_param(ql2xdelay_before_pci_error_handling, uint, 0644); + MODULE_PARM_DESC(ql2xdelay_before_pci_error_handling, + "Number of seconds delayed before qla begin PCI error self-handling (default: 5).\n"); +-- +2.35.3 + diff --git a/patches.suse/scsi-qla2xxx-drop-did_target_failure-use.patch b/patches.suse/scsi-qla2xxx-drop-did_target_failure-use.patch new file mode 100644 index 0000000..b844726 --- /dev/null +++ b/patches.suse/scsi-qla2xxx-drop-did_target_failure-use.patch @@ -0,0 +1,45 @@ +From: Mike Christie +Date: Thu, 11 Aug 2022 20:00:23 -0500 +Subject: scsi: qla2xxx: Drop DID_TARGET_FAILURE use +Patch-mainline: v6.1-rc1 +Git-commit: a965d35c8741724eb69050948024f35d268645ab +References: bsc#1203935 + +DID_TARGET_FAILURE is internal to the SCSI layer. Drivers must not use it +because: + + 1. It's not propagated upwards, so SG IO/passthrough users will not see an + error and think a command was successful. + + 2. There is no handling for it in scsi_decide_disposition() so it + results in entering SCSI error handling. + +This has qla2xxx use DID_NO_CONNECT because it looks like we hit this error +when we can't find a port. It will give us the same hard error behavior and +it seems to match the error where we can't find the endpoint. + +Link: https://lore.kernel.org/r/20220812010027.8251-7-michael.christie@oracle.com +Reviewed-by: Himanshu Madhani +Signed-off-by: Mike Christie +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/qla2xxx/qla_edif.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c +index 400a8b6f3982..00ccc41cef14 100644 +--- a/drivers/scsi/qla2xxx/qla_edif.c ++++ b/drivers/scsi/qla2xxx/qla_edif.c +@@ -1551,7 +1551,7 @@ qla24xx_sadb_update(struct bsg_job *bsg_job) + ql_dbg(ql_dbg_edif, vha, 0x70a3, "Failed to find port= %06x\n", + sa_frame.port_id.b24); + rval = -EINVAL; +- SET_DID_STATUS(bsg_reply->result, DID_TARGET_FAILURE); ++ SET_DID_STATUS(bsg_reply->result, DID_NO_CONNECT); + goto done; + } + +-- +2.35.3 + diff --git a/patches.suse/scsi-qla2xxx-enhance-driver-tracing-with-separate-tunable-and-more.patch b/patches.suse/scsi-qla2xxx-enhance-driver-tracing-with-separate-tunable-and-more.patch new file mode 100644 index 0000000..074b1bb --- /dev/null +++ b/patches.suse/scsi-qla2xxx-enhance-driver-tracing-with-separate-tunable-and-more.patch @@ -0,0 +1,337 @@ +From: Arun Easi +Date: Fri, 26 Aug 2022 03:25:57 -0700 +Subject: scsi: qla2xxx: Enhance driver tracing with separate tunable and more +Patch-mainline: v6.1-rc1 +Git-commit: 8bfc149ba24cb985d593c0b2ddcf03ce42febe0c +References: bsc#1203935 + +Older tracing of driver messages was to: + + - log only debug messages to kernel main trace buffer; and + + - log only if extended logging bits corresponding to this message is + off + +This has been modified and extended as follows: + + - Tracing is now controlled via ql2xextended_error_logging_ktrace + module parameter. Bit usages same as ql2xextended_error_logging. + + - Tracing uses "qla2xxx" trace instance, unless instance creation have + issues. + + - Tracing is enabled (compile time tunable). + + - All driver messages, include debug and log messages are now traced in + kernel trace buffer. + +Trace messages can be viewed by looking at the qla2xxx instance at: + + /sys/kernel/tracing/instances/qla2xxx/trace + +Trace tunable that takes the same bit mask as ql2xextended_error_logging +is: + + ql2xextended_error_logging_ktrace (default=1) + +Link: https://lore.kernel.org/r/20220826102559.17474-6-njavali@marvell.com +Suggested-by: Daniel Wagner +Suggested-by: Steven Rostedt +Tested-by: Himanshu Madhani +Reviewed-by: Himanshu Madhani +Reviewed-by: Daniel Wagner +Signed-off-by: Arun Easi +Signed-off-by: Nilesh Javali +Signed-off-by: Martin K. Petersen +--- + drivers/scsi/qla2xxx/qla_dbg.c | 50 ++++++++++++++++++++++++---------- + drivers/scsi/qla2xxx/qla_dbg.h | 43 +++++++++++++++++++++++++++++ + drivers/scsi/qla2xxx/qla_gbl.h | 1 + + drivers/scsi/qla2xxx/qla_os.c | 35 ++++++++++++++++++++++++ + 4 files changed, 115 insertions(+), 14 deletions(-) + +diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c +index 7cf1f78cbaee..d7e8454304ce 100644 +--- a/drivers/scsi/qla2xxx/qla_dbg.c ++++ b/drivers/scsi/qla2xxx/qla_dbg.c +@@ -2455,7 +2455,7 @@ qla83xx_fw_dump(scsi_qla_host_t *vha) + /****************************************************************************/ + + /* Write the debug message prefix into @pbuf. */ +-static void ql_dbg_prefix(char *pbuf, int pbuf_size, ++static void ql_dbg_prefix(char *pbuf, int pbuf_size, struct pci_dev *pdev, + const scsi_qla_host_t *vha, uint msg_id) + { + if (vha) { +@@ -2464,6 +2464,9 @@ static void ql_dbg_prefix(char *pbuf, int pbuf_size, + /* []-:: */ + snprintf(pbuf, pbuf_size, "%s [%s]-%04x:%lu: ", QL_MSGHDR, + dev_name(&(pdev->dev)), msg_id, vha->host_no); ++ } else if (pdev) { ++ snprintf(pbuf, pbuf_size, "%s [%s]-%04x: : ", QL_MSGHDR, ++ dev_name(&pdev->dev), msg_id); + } else { + /* []-: : */ + snprintf(pbuf, pbuf_size, "%s [%s]-%04x: : ", QL_MSGHDR, +@@ -2491,20 +2494,20 @@ ql_dbg(uint level, scsi_qla_host_t *vha, uint id, const char *fmt, ...) + struct va_format vaf; + char pbuf[64]; + +- if (!ql_mask_match(level) && !trace_ql_dbg_log_enabled()) ++ ql_ktrace(1, level, pbuf, NULL, vha, id, fmt); ++ ++ if (!ql_mask_match(level)) + return; + ++ if (!pbuf[0]) /* set by ql_ktrace */ ++ ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), NULL, vha, id); ++ + va_start(va, fmt); + + vaf.fmt = fmt; + vaf.va = &va; + +- ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), vha, id); +- +- if (!ql_mask_match(level)) +- trace_ql_dbg_log(pbuf, &vaf); +- else +- pr_warn("%s%pV", pbuf, &vaf); ++ pr_warn("%s%pV", pbuf, &vaf); + + va_end(va); + +@@ -2533,6 +2536,9 @@ ql_dbg_pci(uint level, struct pci_dev *pdev, uint id, const char *fmt, ...) + + if (pdev == NULL) + return; ++ ++ ql_ktrace(1, level, pbuf, pdev, NULL, id, fmt); ++ + if (!ql_mask_match(level)) + return; + +@@ -2541,7 +2547,9 @@ ql_dbg_pci(uint level, struct pci_dev *pdev, uint id, const char *fmt, ...) + vaf.fmt = fmt; + vaf.va = &va; + +- ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), NULL, id + ql_dbg_offset); ++ if (!pbuf[0]) /* set by ql_ktrace */ ++ ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), pdev, NULL, ++ id + ql_dbg_offset); + pr_warn("%s%pV", pbuf, &vaf); + + va_end(va); +@@ -2570,7 +2578,10 @@ ql_log(uint level, scsi_qla_host_t *vha, uint id, const char *fmt, ...) + if (level > ql_errlev) + return; + +- ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), vha, id); ++ ql_ktrace(0, level, pbuf, NULL, vha, id, fmt); ++ ++ if (!pbuf[0]) /* set by ql_ktrace */ ++ ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), NULL, vha, id); + + va_start(va, fmt); + +@@ -2621,7 +2632,10 @@ ql_log_pci(uint level, struct pci_dev *pdev, uint id, const char *fmt, ...) + if (level > ql_errlev) + return; + +- ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), NULL, id); ++ ql_ktrace(0, level, pbuf, pdev, NULL, id, fmt); ++ ++ if (!pbuf[0]) /* set by ql_ktrace */ ++ ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), pdev, NULL, id); + + va_start(va, fmt); + +@@ -2716,7 +2730,11 @@ ql_log_qp(uint32_t level, struct qla_qpair *qpair, int32_t id, + if (level > ql_errlev) + return; + +- ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), qpair ? qpair->vha : NULL, id); ++ ql_ktrace(0, level, pbuf, NULL, qpair ? qpair->vha : NULL, id, fmt); ++ ++ if (!pbuf[0]) /* set by ql_ktrace */ ++ ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), NULL, ++ qpair ? qpair->vha : NULL, id); + + va_start(va, fmt); + +@@ -2762,6 +2780,8 @@ ql_dbg_qp(uint32_t level, struct qla_qpair *qpair, int32_t id, + struct va_format vaf; + char pbuf[128]; + ++ ql_ktrace(1, level, pbuf, NULL, qpair ? qpair->vha : NULL, id, fmt); ++ + if (!ql_mask_match(level)) + return; + +@@ -2770,8 +2790,10 @@ ql_dbg_qp(uint32_t level, struct qla_qpair *qpair, int32_t id, + vaf.fmt = fmt; + vaf.va = &va; + +- ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), qpair ? qpair->vha : NULL, +- id + ql_dbg_offset); ++ if (!pbuf[0]) /* set by ql_ktrace */ ++ ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), NULL, ++ qpair ? qpair->vha : NULL, id + ql_dbg_offset); ++ + pr_warn("%s%pV", pbuf, &vaf); + + va_end(va); +diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h +index feeb1666227f..70482b55d240 100644 +--- a/drivers/scsi/qla2xxx/qla_dbg.h ++++ b/drivers/scsi/qla2xxx/qla_dbg.h +@@ -385,3 +385,46 @@ ql_mask_match(uint level) + + return level && ((level & ql2xextended_error_logging) == level); + } ++ ++static inline int ++ql_mask_match_ext(uint level, int *log_tunable) ++{ ++ if (*log_tunable == 1) ++ *log_tunable = QL_DBG_DEFAULT1_MASK; ++ ++ return (level & *log_tunable) == level; ++} ++ ++/* Assumes local variable pbuf and pbuf_ready present. */ ++#define ql_ktrace(dbg_msg, level, pbuf, pdev, vha, id, fmt) do { \ ++ struct va_format _vaf; \ ++ va_list _va; \ ++ u32 dbg_off = dbg_msg ? ql_dbg_offset : 0; \ ++ \ ++ pbuf[0] = 0; \ ++ if (!trace_ql_dbg_log_enabled()) \ ++ break; \ ++ \ ++ if (dbg_msg && !ql_mask_match_ext(level, \ ++ &ql2xextended_error_logging_ktrace)) \ ++ break; \ ++ \ ++ ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), pdev, vha, id + dbg_off); \ ++ \ ++ va_start(_va, fmt); \ ++ _vaf.fmt = fmt; \ ++ _vaf.va = &_va; \ ++ \ ++ trace_ql_dbg_log(pbuf, &_vaf); \ ++ \ ++ va_end(_va); \ ++} while (0) ++ ++#define QLA_ENABLE_KERNEL_TRACING ++ ++#ifdef QLA_ENABLE_KERNEL_TRACING ++#define QLA_TRACE_ENABLE(_tr) \ ++ trace_array_set_clr_event(_tr, "qla", NULL, true) ++#else /* QLA_ENABLE_KERNEL_TRACING */ ++#define QLA_TRACE_ENABLE(_tr) ++#endif /* QLA_ENABLE_KERNEL_TRACING */ +diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h +index bb69fa8b956a..2fc280e61306 100644 +--- a/drivers/scsi/qla2xxx/qla_gbl.h ++++ b/drivers/scsi/qla2xxx/qla_gbl.h +@@ -163,6 +163,7 @@ extern int ql2xrdpenable; + extern int ql2xsmartsan; + extern int ql2xallocfwdump; + extern int ql2xextended_error_logging; ++extern int ql2xextended_error_logging_ktrace; + extern int ql2xiidmaenable; + extern int ql2xmqsupport; + extern int ql2xfwloadbin; +diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c +index ce7cf7750f62..f76ae8a64ea9 100644 +--- a/drivers/scsi/qla2xxx/qla_os.c ++++ b/drivers/scsi/qla2xxx/qla_os.c +@@ -15,6 +15,8 @@ + #include + #include + #include ++#include ++#include + + #include + #include +@@ -35,6 +37,8 @@ static int apidev_major; + */ + struct kmem_cache *srb_cachep; + ++struct trace_array *qla_trc_array; ++ + int ql2xfulldump_on_mpifail; + module_param(ql2xfulldump_on_mpifail, int, S_IRUGO | S_IWUSR); + MODULE_PARM_DESC(ql2xfulldump_on_mpifail, +@@ -117,6 +121,11 @@ MODULE_PARM_DESC(ql2xextended_error_logging, + "ql2xextended_error_logging=1).\n" + "\t\tDo LOGICAL OR of the value to enable more than one level"); + ++int ql2xextended_error_logging_ktrace = 1; ++module_param(ql2xextended_error_logging_ktrace, int, S_IRUGO|S_IWUSR); ++MODULE_PARM_DESC(ql2xextended_error_logging_ktrace, ++ "Same BIT definiton as ql2xextended_error_logging, but used to control logging to kernel trace buffer (default=1).\n"); ++ + int ql2xshiftctondsd = 6; + module_param(ql2xshiftctondsd, int, S_IRUGO); + MODULE_PARM_DESC(ql2xshiftctondsd, +@@ -2839,6 +2848,27 @@ static void qla2x00_iocb_work_fn(struct work_struct *work) + spin_unlock_irqrestore(&vha->work_lock, flags); + } + ++static void ++qla_trace_init(void) ++{ ++ qla_trc_array = trace_array_get_by_name("qla2xxx"); ++ if (!qla_trc_array) { ++ ql_log(ql_log_fatal, NULL, 0x0001, ++ "Unable to create qla2xxx trace instance, instance logging will be disabled.\n"); ++ return; ++ } ++ ++ QLA_TRACE_ENABLE(qla_trc_array); ++} ++ ++static void ++qla_trace_uninit(void) ++{ ++ if (!qla_trc_array) ++ return; ++ trace_array_put(qla_trc_array); ++} ++ + /* + * PCI driver interface + */ +@@ -8181,6 +8211,8 @@ qla2x00_module_init(void) + BUILD_BUG_ON(sizeof(sw_info_t) != 32); + BUILD_BUG_ON(sizeof(target_id_t) != 2); + ++ qla_trace_init(); ++ + /* Allocate cache for SRBs. */ + srb_cachep = kmem_cache_create("qla2xxx_srbs", sizeof(srb_t), 0, + SLAB_HWCACHE_ALIGN, NULL); +@@ -8259,6 +8291,8 @@ qla2x00_module_init(void) + + destroy_cache: + kmem_cache_destroy(srb_cachep); ++ ++ qla_trace_uninit(); + return ret; + } + +@@ -8277,6 +8311,7 @@ qla2x00_module_exit(void) + fc_release_transport(qla2xxx_transport_template); + qlt_exit(); + kmem_cache_destroy(srb_cachep); ++ qla_trace_uninit(); + } + + module_init(qla2x00_module_init); +-- +2.35.3 + diff --git a/patches.suse/scsi-qla2xxx-fix-response-queue-handler-reading-stale-packets.patch b/patches.suse/scsi-qla2xxx-fix-response-queue-handler-reading-stale-packets.patch new file mode 100644 index 0000000..bed9416 --- /dev/null +++ b/patches.suse/scsi-qla2xxx-fix-response-queue-handler-reading-stale-packets.patch @@ -0,0 +1,68 @@ +From: Arun Easi +Date: Fri, 26 Aug 2022 03:25:54 -0700 +Subject: scsi: qla2xxx: Fix response queue handler reading stale packets +Patch-mainline: v6.1-rc1 +Git-commit: e4f8a29deb3ba30e414dfb6b09e3ae3bf6dbe74a +References: bsc#1203935 + +On some platforms, the current logic of relying on finding new packet +solely based on signature pattern can lead to driver reading stale +packets. Though this is a bug in those platforms, reduce such exposures by +limiting reading packets until the IN pointer. + +Link: https://lore.kernel.org/r/20220826102559.17474-3-njavali@marvell.com +Cc: stable@vger.kernel.org +Reviewed-by: Himanshu Madhani +Signed-off-by: Arun Easi +Signed-off-by: Nilesh Javali +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/qla2xxx/qla_isr.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c +index ede76357ccb6..e19fde304e5c 100644 +--- a/drivers/scsi/qla2xxx/qla_isr.c ++++ b/drivers/scsi/qla2xxx/qla_isr.c +@@ -3763,7 +3763,8 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha, + struct qla_hw_data *ha = vha->hw; + struct purex_entry_24xx *purex_entry; + struct purex_item *pure_item; +- u16 cur_ring_index; ++ u16 rsp_in = 0, cur_ring_index; ++ int is_shadow_hba; + + if (!ha->flags.fw_started) + return; +@@ -3773,7 +3774,18 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha, + qla_cpu_update(rsp->qpair, smp_processor_id()); + } + +- while (rsp->ring_ptr->signature != RESPONSE_PROCESSED) { ++#define __update_rsp_in(_is_shadow_hba, _rsp, _rsp_in) \ ++ do { \ ++ _rsp_in = _is_shadow_hba ? *(_rsp)->in_ptr : \ ++ rd_reg_dword_relaxed((_rsp)->rsp_q_in); \ ++ } while (0) ++ ++ is_shadow_hba = IS_SHADOW_REG_CAPABLE(ha); ++ ++ __update_rsp_in(is_shadow_hba, rsp, rsp_in); ++ ++ while (rsp->ring_index != rsp_in && ++ rsp->ring_ptr->signature != RESPONSE_PROCESSED) { + pkt = (struct sts_entry_24xx *)rsp->ring_ptr; + cur_ring_index = rsp->ring_index; + +@@ -3887,6 +3899,7 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha, + } + pure_item = qla27xx_copy_fpin_pkt(vha, + (void **)&pkt, &rsp); ++ __update_rsp_in(is_shadow_hba, rsp, rsp_in); + if (!pure_item) + break; + qla24xx_queue_purex_item(vha, pure_item, +-- +2.35.3 + diff --git a/patches.suse/scsi-qla2xxx-fix-spelling-mistake-definiton-definition.patch b/patches.suse/scsi-qla2xxx-fix-spelling-mistake-definiton-definition.patch new file mode 100644 index 0000000..ac992a4 --- /dev/null +++ b/patches.suse/scsi-qla2xxx-fix-spelling-mistake-definiton-definition.patch @@ -0,0 +1,33 @@ +From: Colin Ian King +Date: Tue, 6 Sep 2022 15:00:10 +0100 +Subject: scsi: qla2xxx: Fix spelling mistake "definiton" -> "definition" +Patch-mainline: v6.1-rc1 +Git-commit: efca52749564601de2045eb71dbe756b7bade4e8 +References: bsc#1203935 + +There is a spelling mistake in a MODULE_PARM_DESC description. Fix it. + +Link: https://lore.kernel.org/r/20220906140010.194273-1-colin.i.king@gmail.com +Signed-off-by: Colin Ian King +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/qla2xxx/qla_os.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c +index 0ccaeea4e1bd..c437ac5e3b85 100644 +--- a/drivers/scsi/qla2xxx/qla_os.c ++++ b/drivers/scsi/qla2xxx/qla_os.c +@@ -124,7 +124,7 @@ MODULE_PARM_DESC(ql2xextended_error_logging, + int ql2xextended_error_logging_ktrace = 1; + module_param(ql2xextended_error_logging_ktrace, int, S_IRUGO|S_IWUSR); + MODULE_PARM_DESC(ql2xextended_error_logging_ktrace, +- "Same BIT definiton as ql2xextended_error_logging, but used to control logging to kernel trace buffer (default=1).\n"); ++ "Same BIT definition as ql2xextended_error_logging, but used to control logging to kernel trace buffer (default=1).\n"); + + int ql2xshiftctondsd = 6; + module_param(ql2xshiftctondsd, int, S_IRUGO); +-- +2.35.3 + diff --git a/patches.suse/scsi-qla2xxx-log-message-skipping-scsi_scan_host-as.patch b/patches.suse/scsi-qla2xxx-log-message-skipping-scsi_scan_host-as.patch new file mode 100644 index 0000000..caca4e9 --- /dev/null +++ b/patches.suse/scsi-qla2xxx-log-message-skipping-scsi_scan_host-as.patch @@ -0,0 +1,66 @@ +From: Mauricio Faria de Oliveira +Date: Thu, 25 Aug 2022 09:01:59 -0300 +Subject: scsi: qla2xxx: Log message "skipping scsi_scan_host()" as + informational +Patch-mainline: v6.1-rc1 +Git-commit: eee8bb4a2b58212843aec92dd6c8c1cc193209e0 +References: bsc#1203935 + +This message is helpful to troubleshoot missing LUNs/SAN boot errors. It'd +be nice to log it by default instead of only being enabled with debug. + +This user had an accidental/forgotten file modprobe.d/qla2xxx.conf w/ +option qlini_mode=disabled from experiments with FC target mode, and their +boot LUN didn't come up, as it skips SCSI scan, of course. + +However, their boot log didn't provide any clues to help understand that. + +The issue/message could be figured out w/ ql2xextended_error_logging, but +it would have been simpler (or even deflected/addressed by user) if it had +been there by default. And it also would help support/triage/deflection +tooling. + +Expected change: + + scsi host15: qla2xxx ++qla2xxx [0000:3b:00.0]-00fb:15: skipping scsi_scan_host() for non-initiator port + qla2xxx [0000:3b:00.0]-00fb:15: QLogic QLE2692 - QLE2692 Dual Port 16Gb FC to PCIe Gen3 x8 Adapter. + +According to: + + qla2x00_probe_one() + ... + ret = scsi_add_host(...); + ... + ql_log(ql_log_info, ... + "skipping scsi_scan_host() for non-initiator port\n"); + ... + ql_log(ql_log_info, ... + "QLogic %s - %s.\n", ha->model_number, ha->model_desc); + +Link: https://lore.kernel.org/r/20220825120159.275051-1-mfo@canonical.com +Tested-by: Himanshu Madhani +Reviewed-by: Himanshu Madhani +Signed-off-by: Mauricio Faria de Oliveira +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/qla2xxx/qla_os.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c +index 0bd0fd1042df..f19cd2b59ad5 100644 +--- a/drivers/scsi/qla2xxx/qla_os.c ++++ b/drivers/scsi/qla2xxx/qla_os.c +@@ -3530,7 +3530,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) + qla_dual_mode_enabled(base_vha)) + scsi_scan_host(host); + else +- ql_dbg(ql_dbg_init, base_vha, 0x0122, ++ ql_log(ql_log_info, base_vha, 0x0122, + "skipping scsi_scan_host() for non-initiator port\n"); + + qla2x00_alloc_sysfs_attr(base_vha); +-- +2.35.3 + diff --git a/patches.suse/scsi-qla2xxx-remove-unused-declarations-for-qla2xxx.patch b/patches.suse/scsi-qla2xxx-remove-unused-declarations-for-qla2xxx.patch new file mode 100644 index 0000000..5e5e480 --- /dev/null +++ b/patches.suse/scsi-qla2xxx-remove-unused-declarations-for-qla2xxx.patch @@ -0,0 +1,106 @@ +From: Gaosheng Cui +Date: Tue, 13 Sep 2022 10:37:21 +0800 +Subject: scsi: qla2xxx: Remove unused declarations for qla2xxx +Patch-mainline: v6.1-rc1 +Git-commit: 1b80addaae099dc33e683d971aba90eeeaf887a3 +References: bsc#1203935 + +qla2x00_get_fw_version_str() has been removed since commit abbd8870b9cb +("[SCSI] qla2xxx: Factor-out ISP specific functions to method-based call +tables."). + +qla2x00_release_nvram_protection() has been removed since commit +459c537807bd ("[SCSI] qla2xxx: Add ISP24xx flash-manipulation routines."). + +qla82xx_rdmem() and qla82xx_wrmem() have been removed since commit +3711333dfbee ("[SCSI] qla2xxx: Updates for ISP82xx."). + +qla25xx_rd_req_reg(), qla24xx_rd_req_reg(), qla25xx_wrt_rsp_reg(), +qla24xx_wrt_rsp_reg(), qla25xx_wrt_req_reg() and qla24xx_wrt_req_reg() have +been removed since commit 08029990b25b ("[SCSI] qla2xxx: Refactor +request/response-queue register handling."). + +qla2x00_async_login_done() has been removed since commit 726b85487067 +("qla2xxx: Add framework for async fabric discovery"). + +qlt_24xx_process_response_error() has been removed since commit +c5419e2618b9 ("scsi: qla2xxx: Combine Active command arrays."). + +Remove the declarations for them from header file. + +Link: https://lore.kernel.org/r/20220913023722.547249-2-cuigaosheng1@huawei.com +Signed-off-by: Gaosheng Cui +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/qla2xxx/qla_gbl.h | 12 ------------ + drivers/scsi/qla2xxx/qla_target.h | 2 -- + 2 files changed, 14 deletions(-) + +diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h +index 2fc280e61306..e3256e721be1 100644 +--- a/drivers/scsi/qla2xxx/qla_gbl.h ++++ b/drivers/scsi/qla2xxx/qla_gbl.h +@@ -70,8 +70,6 @@ extern int qla2x00_async_prlo(struct scsi_qla_host *, fc_port_t *); + extern int qla2x00_async_adisc(struct scsi_qla_host *, fc_port_t *, + uint16_t *); + extern int qla2x00_async_tm_cmd(fc_port_t *, uint32_t, uint32_t, uint32_t); +-extern void qla2x00_async_login_done(struct scsi_qla_host *, fc_port_t *, +- uint16_t *); + struct qla_work_evt *qla2x00_alloc_work(struct scsi_qla_host *, + enum qla_work_type); + extern int qla24xx_async_gnl(struct scsi_qla_host *, fc_port_t *); +@@ -278,7 +276,6 @@ extern int qla24xx_vport_create_req_sanity_check(struct fc_vport *); + extern scsi_qla_host_t *qla24xx_create_vhost(struct fc_vport *); + + extern void qla2x00_sp_free_dma(srb_t *sp); +-extern char *qla2x00_get_fw_version_str(struct scsi_qla_host *, char *); + + extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int); + extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *); +@@ -615,7 +612,6 @@ void __qla_consume_iocb(struct scsi_qla_host *vha, void **pkt, struct rsp_que ** + /* + * Global Function Prototypes in qla_sup.c source file. + */ +-extern void qla2x00_release_nvram_protection(scsi_qla_host_t *); + extern int qla24xx_read_flash_data(scsi_qla_host_t *, uint32_t *, + uint32_t, uint32_t); + extern uint8_t *qla2x00_read_nvram_data(scsi_qla_host_t *, void *, uint32_t, +@@ -787,12 +783,6 @@ extern void qla2x00_init_response_q_entries(struct rsp_que *); + extern int qla25xx_delete_req_que(struct scsi_qla_host *, struct req_que *); + extern int qla25xx_delete_rsp_que(struct scsi_qla_host *, struct rsp_que *); + extern int qla25xx_delete_queues(struct scsi_qla_host *); +-extern uint16_t qla24xx_rd_req_reg(struct qla_hw_data *, uint16_t); +-extern uint16_t qla25xx_rd_req_reg(struct qla_hw_data *, uint16_t); +-extern void qla24xx_wrt_req_reg(struct qla_hw_data *, uint16_t, uint16_t); +-extern void qla25xx_wrt_req_reg(struct qla_hw_data *, uint16_t, uint16_t); +-extern void qla25xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t); +-extern void qla24xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t); + + /* qlafx00 related functions */ + extern int qlafx00_pci_config(struct scsi_qla_host *); +@@ -877,8 +867,6 @@ extern void qla82xx_init_flags(struct qla_hw_data *); + extern void qla82xx_set_drv_active(scsi_qla_host_t *); + extern int qla82xx_wr_32(struct qla_hw_data *, ulong, u32); + extern int qla82xx_rd_32(struct qla_hw_data *, ulong); +-extern int qla82xx_rdmem(struct qla_hw_data *, u64, void *, int); +-extern int qla82xx_wrmem(struct qla_hw_data *, u64, void *, int); + + /* ISP 8021 IDC */ + extern void qla82xx_clear_drv_active(struct qla_hw_data *); +diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h +index 080c46eb8245..7df86578214f 100644 +--- a/drivers/scsi/qla2xxx/qla_target.h ++++ b/drivers/scsi/qla2xxx/qla_target.h +@@ -1075,8 +1075,6 @@ extern void qlt_81xx_config_nvram_stage2(struct scsi_qla_host *, + struct init_cb_81xx *); + extern void qlt_81xx_config_nvram_stage1(struct scsi_qla_host *, + struct nvram_81xx *); +-extern int qlt_24xx_process_response_error(struct scsi_qla_host *, +- struct sts_entry_24xx *); + extern void qlt_modify_vp_config(struct scsi_qla_host *, + struct vp_config_entry_24xx *); + extern void qlt_probe_one_stage1(struct scsi_qla_host *, struct qla_hw_data *); +-- +2.35.3 + diff --git a/patches.suse/scsi-qla2xxx-remove-unused-del_sess_list-field.patch b/patches.suse/scsi-qla2xxx-remove-unused-del_sess_list-field.patch new file mode 100644 index 0000000..c885424 --- /dev/null +++ b/patches.suse/scsi-qla2xxx-remove-unused-del_sess_list-field.patch @@ -0,0 +1,50 @@ +From: Tetsuo Handa +Date: Sun, 21 Aug 2022 12:57:50 +0900 +Subject: scsi: qla2xxx: Remove unused del_sess_list field +Patch-mainline: v6.1-rc1 +Git-commit: e6852b41b560129bb000538490ca39a0be2b591c +References: bsc#1203935 + +"struct qla_tgt"->del_sess_list is no longer used since commit +726b85487067 ("qla2xxx: Add framework for async fabric discovery"). + +Link: https://lore.kernel.org/r/0c335e86-5624-b599-5137-f1377419fb0c@I-love.SAKURA.ne.jp +Tested-by: Himanshu Madhani +Reviewed-by: Himanshu Madhani +Signed-off-by: Tetsuo Handa +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/qla2xxx/qla_target.c | 1 - + drivers/scsi/qla2xxx/qla_target.h | 3 --- + 2 files changed, 4 deletions(-) + +diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c +index 2b2f68288375..d9e0e7ffe130 100644 +--- a/drivers/scsi/qla2xxx/qla_target.c ++++ b/drivers/scsi/qla2xxx/qla_target.c +@@ -6512,7 +6512,6 @@ int qlt_add_target(struct qla_hw_data *ha, struct scsi_qla_host *base_vha) + tgt->ha = ha; + tgt->vha = base_vha; + init_waitqueue_head(&tgt->waitQ); +- INIT_LIST_HEAD(&tgt->del_sess_list); + spin_lock_init(&tgt->sess_work_lock); + INIT_WORK(&tgt->sess_work, qlt_sess_work_fn); + INIT_LIST_HEAD(&tgt->sess_works_list); +diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h +index de3942b8efc4..e899e13696e9 100644 +--- a/drivers/scsi/qla2xxx/qla_target.h ++++ b/drivers/scsi/qla2xxx/qla_target.h +@@ -813,9 +813,6 @@ struct qla_tgt { + /* Count of sessions refering qla_tgt. Protected by hardware_lock. */ + int sess_count; + +- /* Protected by hardware_lock */ +- struct list_head del_sess_list; +- + spinlock_t sess_work_lock; + struct list_head sess_works_list; + struct work_struct sess_work; +-- +2.35.3 + diff --git a/patches.suse/scsi-qla2xxx-remove-unused-qlt_tmr_work.patch b/patches.suse/scsi-qla2xxx-remove-unused-qlt_tmr_work.patch new file mode 100644 index 0000000..2da2318 --- /dev/null +++ b/patches.suse/scsi-qla2xxx-remove-unused-qlt_tmr_work.patch @@ -0,0 +1,120 @@ +From: Tetsuo Handa +Date: Sun, 21 Aug 2022 12:58:24 +0900 +Subject: scsi: qla2xxx: Remove unused qlt_tmr_work() +Patch-mainline: v6.1-rc1 +Git-commit: 1b2b8d45ccd6a61f88c0d5a55c9119c3b710bfa5 +References: bsc#1203935 + +qlt_tmr_work() is no longer used since commit fb35265b12bb ("scsi: +qla2xxx: Remove session creation redundant code"). + +Link: https://lore.kernel.org/r/a0e53c70-b801-adf5-0549-b2b1e421a819@I-love.SAKURA.ne.jp +Tested-by: Himanshu Madhani +Reviewed-by: Himanshu Madhani +Signed-off-by: Tetsuo Handa +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/qla2xxx/qla_target.c | 66 ------------------------------- + drivers/scsi/qla2xxx/qla_target.h | 1 - + 2 files changed, 67 deletions(-) + +diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c +index d9e0e7ffe130..b170ebbd05b7 100644 +--- a/drivers/scsi/qla2xxx/qla_target.c ++++ b/drivers/scsi/qla2xxx/qla_target.c +@@ -6334,69 +6334,6 @@ static void qlt_abort_work(struct qla_tgt *tgt, + spin_unlock_irqrestore(&ha->hardware_lock, flags); + } + +-static void qlt_tmr_work(struct qla_tgt *tgt, +- struct qla_tgt_sess_work_param *prm) +-{ +- struct atio_from_isp *a = &prm->tm_iocb2; +- struct scsi_qla_host *vha = tgt->vha; +- struct qla_hw_data *ha = vha->hw; +- struct fc_port *sess; +- unsigned long flags; +- be_id_t s_id; +- int rc; +- u64 unpacked_lun; +- int fn; +- void *iocb; +- +- spin_lock_irqsave(&ha->tgt.sess_lock, flags); +- +- if (tgt->tgt_stop) +- goto out_term2; +- +- s_id = prm->tm_iocb2.u.isp24.fcp_hdr.s_id; +- sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, s_id); +- if (!sess) { +- spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); +- +- sess = qlt_make_local_sess(vha, s_id); +- /* sess has got an extra creation ref */ +- +- spin_lock_irqsave(&ha->tgt.sess_lock, flags); +- if (!sess) +- goto out_term2; +- } else { +- if (sess->deleted) { +- goto out_term2; +- } +- +- if (!kref_get_unless_zero(&sess->sess_kref)) { +- ql_dbg(ql_dbg_tgt_tmr, vha, 0xf020, +- "%s: kref_get fail %8phC\n", +- __func__, sess->port_name); +- goto out_term2; +- } +- } +- +- iocb = a; +- fn = a->u.isp24.fcp_cmnd.task_mgmt_flags; +- unpacked_lun = +- scsilun_to_int((struct scsi_lun *)&a->u.isp24.fcp_cmnd.lun); +- +- rc = qlt_issue_task_mgmt(sess, unpacked_lun, fn, iocb, 0); +- spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); +- +- ha->tgt.tgt_ops->put_sess(sess); +- +- if (rc != 0) +- goto out_term; +- return; +- +-out_term2: +- spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); +-out_term: +- qlt_send_term_exchange(ha->base_qpair, NULL, &prm->tm_iocb2, 1, 0); +-} +- + static void qlt_sess_work_fn(struct work_struct *work) + { + struct qla_tgt *tgt = container_of(work, struct qla_tgt, sess_work); +@@ -6423,9 +6360,6 @@ static void qlt_sess_work_fn(struct work_struct *work) + case QLA_TGT_SESS_WORK_ABORT: + qlt_abort_work(tgt, prm); + break; +- case QLA_TGT_SESS_WORK_TM: +- qlt_tmr_work(tgt, prm); +- break; + default: + BUG_ON(1); + break; +diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h +index e899e13696e9..080c46eb8245 100644 +--- a/drivers/scsi/qla2xxx/qla_target.h ++++ b/drivers/scsi/qla2xxx/qla_target.h +@@ -942,7 +942,6 @@ struct qla_tgt_sess_work_param { + struct list_head sess_works_list_entry; + + #define QLA_TGT_SESS_WORK_ABORT 1 +-#define QLA_TGT_SESS_WORK_TM 2 + int type; + + union { +-- +2.35.3 + diff --git a/patches.suse/scsi-qla2xxx-revert-scsi-qla2xxx-fix-response-queue-handler.patch b/patches.suse/scsi-qla2xxx-revert-scsi-qla2xxx-fix-response-queue-handler.patch new file mode 100644 index 0000000..c5c25fb --- /dev/null +++ b/patches.suse/scsi-qla2xxx-revert-scsi-qla2xxx-fix-response-queue-handler.patch @@ -0,0 +1,115 @@ +From: Arun Easi +Date: Fri, 26 Aug 2022 03:25:53 -0700 +Subject: scsi: qla2xxx: Revert "scsi: qla2xxx: Fix response queue handler + reading stale packets" +Patch-mainline: v6.1-rc1 +Git-commit: 6dc45a7322cb9db48a5b6696597a00ef7c778ef9 +References: bsc#1203935 + +Reverting this commit so that a fixed up patch, without adding new module +parameters, can be submitted. + + Link: https://lore.kernel.org/stable/166039743723771@kroah.com/ + +This reverts commit b1f707146923335849fb70237eec27d4d1ae7d62. + +Link: https://lore.kernel.org/r/20220826102559.17474-2-njavali@marvell.com +Cc: stable@vger.kernel.org +Reviewed-by: Himanshu Madhani +Signed-off-by: Arun Easi +Signed-off-by: Nilesh Javali +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/qla2xxx/qla_gbl.h | 2 -- + drivers/scsi/qla2xxx/qla_isr.c | 25 ++----------------------- + drivers/scsi/qla2xxx/qla_os.c | 10 ---------- + 3 files changed, 2 insertions(+), 35 deletions(-) + +diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h +index 5dd2932382ee..bb69fa8b956a 100644 +--- a/drivers/scsi/qla2xxx/qla_gbl.h ++++ b/drivers/scsi/qla2xxx/qla_gbl.h +@@ -193,8 +193,6 @@ extern int ql2xsecenable; + extern int ql2xenforce_iocb_limit; + extern int ql2xabts_wait_nvme; + extern u32 ql2xnvme_queues; +-extern int ql2xrspq_follow_inptr; +-extern int ql2xrspq_follow_inptr_legacy; + + extern int qla2x00_loop_reset(scsi_qla_host_t *); + extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int); +diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c +index 76e79f350a22..ede76357ccb6 100644 +--- a/drivers/scsi/qla2xxx/qla_isr.c ++++ b/drivers/scsi/qla2xxx/qla_isr.c +@@ -3763,8 +3763,7 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha, + struct qla_hw_data *ha = vha->hw; + struct purex_entry_24xx *purex_entry; + struct purex_item *pure_item; +- u16 rsp_in = 0, cur_ring_index; +- int follow_inptr, is_shadow_hba; ++ u16 cur_ring_index; + + if (!ha->flags.fw_started) + return; +@@ -3774,25 +3773,7 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha, + qla_cpu_update(rsp->qpair, smp_processor_id()); + } + +-#define __update_rsp_in(_update, _is_shadow_hba, _rsp, _rsp_in) \ +- do { \ +- if (_update) { \ +- _rsp_in = _is_shadow_hba ? *(_rsp)->in_ptr : \ +- rd_reg_dword_relaxed((_rsp)->rsp_q_in); \ +- } \ +- } while (0) +- +- is_shadow_hba = IS_SHADOW_REG_CAPABLE(ha); +- follow_inptr = is_shadow_hba ? ql2xrspq_follow_inptr : +- ql2xrspq_follow_inptr_legacy; +- +- __update_rsp_in(follow_inptr, is_shadow_hba, rsp, rsp_in); +- +- while ((likely(follow_inptr && +- rsp->ring_index != rsp_in && +- rsp->ring_ptr->signature != RESPONSE_PROCESSED)) || +- (!follow_inptr && +- rsp->ring_ptr->signature != RESPONSE_PROCESSED)) { ++ while (rsp->ring_ptr->signature != RESPONSE_PROCESSED) { + pkt = (struct sts_entry_24xx *)rsp->ring_ptr; + cur_ring_index = rsp->ring_index; + +@@ -3906,8 +3887,6 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha, + } + pure_item = qla27xx_copy_fpin_pkt(vha, + (void **)&pkt, &rsp); +- __update_rsp_in(follow_inptr, is_shadow_hba, +- rsp, rsp_in); + if (!pure_item) + break; + qla24xx_queue_purex_item(vha, pure_item, +diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c +index f19cd2b59ad5..ce7cf7750f62 100644 +--- a/drivers/scsi/qla2xxx/qla_os.c ++++ b/drivers/scsi/qla2xxx/qla_os.c +@@ -338,16 +338,6 @@ module_param(ql2xdelay_before_pci_error_handling, uint, 0644); + MODULE_PARM_DESC(ql2xdelay_before_pci_error_handling, + "Number of seconds delayed before qla begin PCI error self-handling (default: 5).\n"); + +-int ql2xrspq_follow_inptr = 1; +-module_param(ql2xrspq_follow_inptr, int, 0644); +-MODULE_PARM_DESC(ql2xrspq_follow_inptr, +- "Follow RSP IN pointer for RSP updates for HBAs 27xx and newer (default: 1)."); +- +-int ql2xrspq_follow_inptr_legacy = 1; +-module_param(ql2xrspq_follow_inptr_legacy, int, 0644); +-MODULE_PARM_DESC(ql2xrspq_follow_inptr_legacy, +- "Follow RSP IN pointer for RSP updates for HBAs older than 27XX. (default: 1)."); +- + static void qla2x00_clear_drv_active(struct qla_hw_data *); + static void qla2x00_free_device(scsi_qla_host_t *); + static int qla2xxx_map_queues(struct Scsi_Host *shost); +-- +2.35.3 + diff --git a/patches.suse/scsi-qla2xxx-update-version-to-10.02.07.900-k.patch b/patches.suse/scsi-qla2xxx-update-version-to-10.02.07.900-k.patch new file mode 100644 index 0000000..a8bd23d --- /dev/null +++ b/patches.suse/scsi-qla2xxx-update-version-to-10.02.07.900-k.patch @@ -0,0 +1,35 @@ +From: Nilesh Javali +Date: Fri, 26 Aug 2022 03:25:59 -0700 +Subject: scsi: qla2xxx: Update version to 10.02.07.900-k +Patch-mainline: v6.1-rc1 +Git-commit: fed842d04dad979f0e74926720474ab0b037e7e8 +References: bsc#1203935 + +Link: https://lore.kernel.org/r/20220826102559.17474-8-njavali@marvell.com +Reviewed-by: Himanshu Madhani +Signed-off-by: Nilesh Javali +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/qla2xxx/qla_version.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h +index f3257d46b6d2..03f3e2cd62b5 100644 +--- a/drivers/scsi/qla2xxx/qla_version.h ++++ b/drivers/scsi/qla2xxx/qla_version.h +@@ -6,9 +6,9 @@ + /* + * Driver version + */ +-#define QLA2XXX_VERSION "10.02.07.800-k" ++#define QLA2XXX_VERSION "10.02.07.900-k" + + #define QLA_DRIVER_MAJOR_VER 10 + #define QLA_DRIVER_MINOR_VER 2 + #define QLA_DRIVER_PATCH_VER 7 +-#define QLA_DRIVER_BETA_VER 800 ++#define QLA_DRIVER_BETA_VER 900 +-- +2.35.3 + diff --git a/patches.suse/scsi-smartpqi-Add-module-param-to-disable-managed-ints.patch b/patches.suse/scsi-smartpqi-Add-module-param-to-disable-managed-ints.patch new file mode 100644 index 0000000..1c75eef --- /dev/null +++ b/patches.suse/scsi-smartpqi-Add-module-param-to-disable-managed-ints.patch @@ -0,0 +1,89 @@ +From: Mike McGowen +Date: Fri, 8 Jul 2022 13:47:46 -0500 +Subject: scsi: smartpqi: Add module param to disable managed ints +Git-commit: cf15c3e734e8d25de7b4d9170f5a69ace633a583 +Patch-mainline: v6.0-rc1 +References: bsc#1203893 + +Allow SMP affinity to be changeable by disabling managed interrupts. + +On distributions where the driver is enabled for multi-queue support the +driver utilizes kernel managed interrupts, which automatically distributes +interrupts to all available CPUs and assigns SMP affinity. + +On most distributions, the affinity can not be changed by the user. + +This change will allow managed interrupts to be disabled by the user via a +module parameter while still allowing multi-queue support to function +properly. + +Use the module parameter disable_managed_interrupts=1 + +Link: https://lore.kernel.org/r/165730606638.177165.12846020942931640329.stgit@brunhilda +Reviewed-by: Scott Benesh +Reviewed-by: Scott Teel +Reviewed-by: Kevin Barnett +Signed-off-by: Mike McGowen +Signed-off-by: Don Brace +Signed-off-by: Martin K. Petersen +Acked-by: Lee Duncan +--- + drivers/scsi/smartpqi/smartpqi.h | 2 +- + drivers/scsi/smartpqi/smartpqi_init.c | 13 ++++++++++++- + 2 files changed, 13 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h +index f1145ded843e..49d3a8a275f3 100644 +--- a/drivers/scsi/smartpqi/smartpqi.h ++++ b/drivers/scsi/smartpqi/smartpqi.h +@@ -1351,7 +1351,7 @@ struct pqi_ctrl_info { + u8 enable_r6_writes : 1; + u8 lv_drive_type_mix_valid : 1; + u8 enable_stream_detection : 1; +- ++ u8 disable_managed_interrupts : 1; + u8 ciss_report_log_flags; + u32 max_transfer_encrypted_sas_sata; + u32 max_transfer_encrypted_nvme; +diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c +index e07282ed0f34..2df1e8453029 100644 +--- a/drivers/scsi/smartpqi/smartpqi_init.c ++++ b/drivers/scsi/smartpqi/smartpqi_init.c +@@ -175,6 +175,12 @@ module_param_named(hide_vsep, + pqi_hide_vsep, int, 0644); + MODULE_PARM_DESC(hide_vsep, "Hide the virtual SEP for direct attached drives."); + ++static int pqi_disable_managed_interrupts; ++module_param_named(disable_managed_interrupts, ++ pqi_disable_managed_interrupts, int, 0644); ++MODULE_PARM_DESC(disable_managed_interrupts, ++ "Disable the kernel automatically assigning SMP affinity to IRQs."); ++ + static char *raid_levels[] = { + "RAID-0", + "RAID-4", +@@ -4039,10 +4045,14 @@ static void pqi_free_irqs(struct pqi_ctrl_info *ctrl_info) + static int pqi_enable_msix_interrupts(struct pqi_ctrl_info *ctrl_info) + { + int num_vectors_enabled; ++ unsigned int flags = PCI_IRQ_MSIX; ++ ++ if (!pqi_disable_managed_interrupts) ++ flags |= PCI_IRQ_AFFINITY; + + num_vectors_enabled = pci_alloc_irq_vectors(ctrl_info->pci_dev, + PQI_MIN_MSIX_VECTORS, ctrl_info->num_queue_groups, +- PCI_IRQ_MSIX | PCI_IRQ_AFFINITY); ++ flags); + if (num_vectors_enabled < 0) { + dev_err(&ctrl_info->pci_dev->dev, + "MSI-X init failed with error %d\n", +@@ -8588,6 +8598,7 @@ static struct pqi_ctrl_info *pqi_alloc_ctrl_info(int numa_node) + ctrl_info->max_write_raid_5_6 = PQI_DEFAULT_MAX_WRITE_RAID_5_6; + ctrl_info->max_write_raid_1_10_2drive = ~0; + ctrl_info->max_write_raid_1_10_3drive = ~0; ++ ctrl_info->disable_managed_interrupts = pqi_disable_managed_interrupts; + + return ctrl_info; + } + diff --git a/patches.suse/scsi-smartpqi-Shorten-drive-visibility-after-removal.patch b/patches.suse/scsi-smartpqi-Shorten-drive-visibility-after-removal.patch new file mode 100644 index 0000000..ee4cc91 --- /dev/null +++ b/patches.suse/scsi-smartpqi-Shorten-drive-visibility-after-removal.patch @@ -0,0 +1,77 @@ +From 4e7d26029ee7558badad4188ddb3a79566da69c0 Mon Sep 17 00:00:00 2001 +From: Mike McGowen +Date: Fri, 8 Jul 2022 13:46:50 -0500 +Subject: [PATCH] scsi: smartpqi: Shorten drive visibility after removal +Git-commit: 4e7d26029ee7558badad4188ddb3a79566da69c0 +References: bsc#1200622 +Patch-mainline: v6.0-rc1 + +Check the response code returned from the LUN reset task management +function and if it indicates the LUN is not valid, do not retry. + +Reduce rescan worker delay to 5 seconds for the event handler only. + +The removal of a drive from the OS could have been delayed up to 30 seconds +after being physically pulled. + +The driver was retrying a LUN reset 3 times even though the return code +indiciated the LUN was no longer valid. There was a 10 second delay between +each retry. Additionally, the rescan worker was scheduled to run 10 seconds +after the driver received the event. + +Link: https://lore.kernel.org/r/165730601025.177165.9416869335174437006.stgit@brunhilda +Reviewed-by: Scott Teel +Reviewed-by: Kevin Barnett +Signed-off-by: Mike McGowen +Signed-off-by: Don Brace +Signed-off-by: Martin K. Petersen +Acked-by: Ali Abdallah +--- + drivers/scsi/smartpqi/smartpqi.h | 1 + + drivers/scsi/smartpqi/smartpqi_init.c | 10 ++++++++-- + 2 files changed, 9 insertions(+), 2 deletions(-) + +--- a/drivers/scsi/smartpqi/smartpqi.h ++++ b/drivers/scsi/smartpqi/smartpqi.h +@@ -697,6 +697,7 @@ typedef u32 pqi_index_t; + #define SOP_TMF_COMPLETE 0x0 + #define SOP_TMF_REJECTED 0x4 + #define SOP_TMF_FUNCTION_SUCCEEDED 0x8 ++#define SOP_RC_INCORRECT_LOGICAL_UNIT 0x9 + + /* additional CDB bytes usage field codes */ + #define SOP_ADDITIONAL_CDB_BYTES_0 0 /* 16-byte CDB */ +--- a/drivers/scsi/smartpqi/smartpqi_init.c ++++ b/drivers/scsi/smartpqi/smartpqi_init.c +@@ -3122,6 +3122,9 @@ static int pqi_interpret_task_management + case SOP_TMF_REJECTED: + rc = -EAGAIN; + break; ++ case SOP_RC_INCORRECT_LOGICAL_UNIT: ++ rc = -ENODEV; ++ break; + default: + rc = -EIO; + break; +@@ -3494,8 +3497,11 @@ static void pqi_event_worker(struct work + event++; + } + ++#define PQI_RESCAN_WORK_FOR_EVENT_DELAY (5 * HZ) ++ + if (rescan_needed) +- pqi_schedule_rescan_worker_delayed(ctrl_info); ++ pqi_schedule_rescan_worker_with_delay(ctrl_info, ++ PQI_RESCAN_WORK_FOR_EVENT_DELAY); + + out: + pqi_ctrl_unbusy(ctrl_info); +@@ -6016,7 +6022,7 @@ static int pqi_lun_reset_with_retries(st + + for (retries = 0;;) { + reset_rc = pqi_lun_reset(ctrl_info, device); +- if (reset_rc == 0 || ++retries > PQI_LUN_RESET_RETRIES) ++ if (reset_rc == 0 || reset_rc == -ENODEV || ++retries > PQI_LUN_RESET_RETRIES) + break; + msleep(PQI_LUN_RESET_RETRY_INTERVAL_MSECS); + } diff --git a/patches.suse/scsi-stex-Properly-zero-out-the-passthrough-command-structure.patch b/patches.suse/scsi-stex-Properly-zero-out-the-passthrough-command-structure.patch new file mode 100644 index 0000000..a31789c --- /dev/null +++ b/patches.suse/scsi-stex-Properly-zero-out-the-passthrough-command-structure.patch @@ -0,0 +1,71 @@ +From: Linus Torvalds +Date: Fri, 9 Sep 2022 08:54:47 +0200 +Subject: scsi: stex: Properly zero out the passthrough command structure +Git-commit: 6022f210461fef67e6e676fd8544ca02d1bcfa7a +Patch-mainline: v6.0 or v6.0-rc8 (next release) +References: bsc#1203514 CVE-2022-40768 + +The passthrough structure is declared off of the stack, so it needs to be +set to zero before copied back to userspace to prevent any unintentional +data leakage. Switch things to be statically allocated which will fill the +unused fields with 0 automatically. + +Link: https://lore.kernel.org/r/YxrjN3OOw2HHl9tx@kroah.com +Cc: stable@kernel.org +Cc: "James E.J. Bottomley" +Cc: "Martin K. Petersen" +Cc: Dan Carpenter +Reported-by: hdthky +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Martin K. Petersen +Acked-by: Lee Duncan +--- + drivers/scsi/stex.c | 17 +++++++++-------- + include/scsi/scsi_cmnd.h | 2 +- + 2 files changed, 10 insertions(+), 9 deletions(-) + +diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c +index e6420f2127ce..8def242675ef 100644 +--- a/drivers/scsi/stex.c ++++ b/drivers/scsi/stex.c +@@ -665,16 +665,17 @@ static int stex_queuecommand_lck(struct scsi_cmnd *cmd) + return 0; + case PASSTHRU_CMD: + if (cmd->cmnd[1] == PASSTHRU_GET_DRVVER) { +- struct st_drvver ver; ++ const struct st_drvver ver = { ++ .major = ST_VER_MAJOR, ++ .minor = ST_VER_MINOR, ++ .oem = ST_OEM, ++ .build = ST_BUILD_VER, ++ .signature[0] = PASSTHRU_SIGNATURE, ++ .console_id = host->max_id - 1, ++ .host_no = hba->host->host_no, ++ }; + size_t cp_len = sizeof(ver); + +- ver.major = ST_VER_MAJOR; +- ver.minor = ST_VER_MINOR; +- ver.oem = ST_OEM; +- ver.build = ST_BUILD_VER; +- ver.signature[0] = PASSTHRU_SIGNATURE; +- ver.console_id = host->max_id - 1; +- ver.host_no = hba->host->host_no; + cp_len = scsi_sg_copy_from_buffer(cmd, &ver, cp_len); + if (sizeof(ver) == cp_len) + cmd->result = DID_OK << 16; +diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h +index bac55decf900..7d3622db38ed 100644 +--- a/include/scsi/scsi_cmnd.h ++++ b/include/scsi/scsi_cmnd.h +@@ -201,7 +201,7 @@ static inline unsigned int scsi_get_resid(struct scsi_cmnd *cmd) + for_each_sg(scsi_sglist(cmd), sg, nseg, __i) + + static inline int scsi_sg_copy_from_buffer(struct scsi_cmnd *cmd, +- void *buf, int buflen) ++ const void *buf, int buflen) + { + return sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), + buf, buflen); + diff --git a/patches.suse/scsi-ufs-ufs-pci-Add-support-for-Intel-ADL.patch b/patches.suse/scsi-ufs-ufs-pci-Add-support-for-Intel-ADL.patch new file mode 100644 index 0000000..aa11250 --- /dev/null +++ b/patches.suse/scsi-ufs-ufs-pci-Add-support-for-Intel-ADL.patch @@ -0,0 +1,62 @@ +From 7dc9fb47bc9a95f1cc6c5655341860c5e50f91d4 Mon Sep 17 00:00:00 2001 +From: Adrian Hunter +Date: Wed, 24 Nov 2021 22:42:18 +0200 +Subject: [PATCH] scsi: ufs: ufs-pci: Add support for Intel ADL +Git-commit: 7dc9fb47bc9a95f1cc6c5655341860c5e50f91d4 +Patch-mainline: v5.16-rc4 +References: jsc#PED-707 + +Add PCI ID and callbacks to support Intel Alder Lake. + +Link: https://lore.kernel.org/r/20211124204218.1784559-1-adrian.hunter@intel.com +Cc: stable@vger.kernel.org # v5.15+ +Reviewed-by: Bart Van Assche +Signed-off-by: Adrian Hunter +Signed-off-by: Martin K. Petersen +Acked-by: Takashi Iwai + +--- + drivers/scsi/ufs/ufshcd-pci.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +--- a/drivers/scsi/ufs/ufshcd-pci.c ++++ b/drivers/scsi/ufs/ufshcd-pci.c +@@ -435,6 +435,13 @@ static int ufs_intel_lkf_init(struct ufs + return err; + } + ++static int ufs_intel_adl_init(struct ufs_hba *hba) ++{ ++ hba->nop_out_timeout = 200; ++ hba->quirks |= UFSHCD_QUIRK_BROKEN_AUTO_HIBERN8; ++ return ufs_intel_common_init(hba); ++} ++ + static struct ufs_hba_variant_ops ufs_intel_cnl_hba_vops = { + .name = "intel-pci", + .init = ufs_intel_common_init, +@@ -463,6 +470,15 @@ static struct ufs_hba_variant_ops ufs_in + .device_reset = ufs_intel_device_reset, + }; + ++static struct ufs_hba_variant_ops ufs_intel_adl_hba_vops = { ++ .name = "intel-pci", ++ .init = ufs_intel_adl_init, ++ .exit = ufs_intel_common_exit, ++ .link_startup_notify = ufs_intel_link_startup_notify, ++ .resume = ufs_intel_resume, ++ .device_reset = ufs_intel_device_reset, ++}; ++ + #ifdef CONFIG_PM_SLEEP + /** + * ufshcd_pci_suspend - suspend power management function +@@ -602,6 +618,8 @@ static const struct pci_device_id ufshcd + { PCI_VDEVICE(INTEL, 0x4B41), (kernel_ulong_t)&ufs_intel_ehl_hba_vops }, + { PCI_VDEVICE(INTEL, 0x4B43), (kernel_ulong_t)&ufs_intel_ehl_hba_vops }, + { PCI_VDEVICE(INTEL, 0x98FA), (kernel_ulong_t)&ufs_intel_lkf_hba_vops }, ++ { PCI_VDEVICE(INTEL, 0x51FF), (kernel_ulong_t)&ufs_intel_adl_hba_vops }, ++ { PCI_VDEVICE(INTEL, 0x54FF), (kernel_ulong_t)&ufs_intel_adl_hba_vops }, + { } /* terminate list */ + }; + diff --git a/patches.suse/scsi-ufs-ufs-pci-Add-support-for-Intel-MTL.patch b/patches.suse/scsi-ufs-ufs-pci-Add-support-for-Intel-MTL.patch new file mode 100644 index 0000000..1423a37 --- /dev/null +++ b/patches.suse/scsi-ufs-ufs-pci-Add-support-for-Intel-MTL.patch @@ -0,0 +1,62 @@ +From 4049f7acef3eb37c1ea0df45f3ffc29404f4e708 Mon Sep 17 00:00:00 2001 +From: Adrian Hunter +Date: Mon, 4 Apr 2022 08:50:38 +0300 +Subject: [PATCH] scsi: ufs: ufs-pci: Add support for Intel MTL +Git-commit: 4049f7acef3eb37c1ea0df45f3ffc29404f4e708 +Patch-mainline: v5.18-rc2 +References: jsc#PED-732 + +Add PCI ID and callbacks to support Intel Meteor Lake (MTL). + +Link: https://lore.kernel.org/r/20220404055038.2208051-1-adrian.hunter@intel.com +Cc: stable@vger.kernel.org # v5.15+ +Reviewed-by: Avri Altman +Reviewed-by: Bart Van Assche +Signed-off-by: Adrian Hunter +Signed-off-by: Martin K. Petersen +Acked-by: Takashi Iwai + +--- + drivers/scsi/ufs/ufshcd-pci.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +--- a/drivers/scsi/ufs/ufshcd-pci.c ++++ b/drivers/scsi/ufs/ufshcd-pci.c +@@ -442,6 +442,12 @@ static int ufs_intel_adl_init(struct ufs + return ufs_intel_common_init(hba); + } + ++static int ufs_intel_mtl_init(struct ufs_hba *hba) ++{ ++ hba->caps |= UFSHCD_CAP_CRYPTO | UFSHCD_CAP_WB_EN; ++ return ufs_intel_common_init(hba); ++} ++ + static struct ufs_hba_variant_ops ufs_intel_cnl_hba_vops = { + .name = "intel-pci", + .init = ufs_intel_common_init, +@@ -479,6 +485,16 @@ static struct ufs_hba_variant_ops ufs_in + .device_reset = ufs_intel_device_reset, + }; + ++static struct ufs_hba_variant_ops ufs_intel_mtl_hba_vops = { ++ .name = "intel-pci", ++ .init = ufs_intel_mtl_init, ++ .exit = ufs_intel_common_exit, ++ .hce_enable_notify = ufs_intel_hce_enable_notify, ++ .link_startup_notify = ufs_intel_link_startup_notify, ++ .resume = ufs_intel_resume, ++ .device_reset = ufs_intel_device_reset, ++}; ++ + #ifdef CONFIG_PM_SLEEP + /** + * ufshcd_pci_suspend - suspend power management function +@@ -620,6 +636,7 @@ static const struct pci_device_id ufshcd + { PCI_VDEVICE(INTEL, 0x98FA), (kernel_ulong_t)&ufs_intel_lkf_hba_vops }, + { PCI_VDEVICE(INTEL, 0x51FF), (kernel_ulong_t)&ufs_intel_adl_hba_vops }, + { PCI_VDEVICE(INTEL, 0x54FF), (kernel_ulong_t)&ufs_intel_adl_hba_vops }, ++ { PCI_VDEVICE(INTEL, 0x7E47), (kernel_ulong_t)&ufs_intel_mtl_hba_vops }, + { } /* terminate list */ + }; + diff --git a/patches.suse/scsi-zfcp-Use-scsi_cmd_to_rq-instead-of-scsi_cmnd.request b/patches.suse/scsi-zfcp-Use-scsi_cmd_to_rq-instead-of-scsi_cmnd.request new file mode 100644 index 0000000..e7b6ba7 --- /dev/null +++ b/patches.suse/scsi-zfcp-Use-scsi_cmd_to_rq-instead-of-scsi_cmnd.request @@ -0,0 +1,31 @@ +From: Bart Van Assche +Date: Mon, 9 Aug 2021 16:03:13 -0700 +Subject: scsi: zfcp: Use scsi_cmd_to_rq() instead of scsi_cmnd.request +Git-commit: d78f31ce7ef9a3bccb63ecb668d124166e591dfc +Patch-mainline: v5.15-rc1 +References: jsc#PED-455 bsc#1203836 LTC#198623 + +Prepare for removal of the request pointer by using scsi_cmd_to_rq() +instead. This patch does not change any functionality. + +Link: https://lore.kernel.org/r/20210809230355.8186-11-bvanassche@acm.org +Acked-by: Benjamin Block +Reviewed-by: Hannes Reinecke +Signed-off-by: Bart Van Assche +Signed-off-by: Martin K. Petersen +Acked-by: Petr Tesarik +--- + drivers/s390/scsi/zfcp_fsf.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/s390/scsi/zfcp_fsf.c ++++ b/drivers/s390/scsi/zfcp_fsf.c +@@ -2377,7 +2377,7 @@ static void zfcp_fsf_req_trace(struct zf + } + } + +- blk_add_driver_data(scsi->request, &blktrc, sizeof(blktrc)); ++ blk_add_driver_data(scsi_cmd_to_rq(scsi), &blktrc, sizeof(blktrc)); + } + + /** diff --git a/patches.suse/scsi-zfcp-Use-the-proper-SCSI-midlayer-interfaces-for-PI b/patches.suse/scsi-zfcp-Use-the-proper-SCSI-midlayer-interfaces-for-PI new file mode 100644 index 0000000..0fb5cc6 --- /dev/null +++ b/patches.suse/scsi-zfcp-Use-the-proper-SCSI-midlayer-interfaces-for-PI @@ -0,0 +1,33 @@ +From: "Martin K. Petersen" +Date: Tue, 8 Jun 2021 23:39:20 -0400 +Subject: scsi: zfcp: Use the proper SCSI midlayer interfaces for PI +Git-commit: 73e61d5c22bfad25573a5373739ee1be8bb7d63d +Patch-mainline: v5.15-rc1 +References: jsc#PED-455 bsc#1203836 LTC#198623 + +Use scsi_prot_ref_tag() and scsi_prot_interval() instead scsi_get_lba() and +sector_size. + +Link: https://lore.kernel.org/r/20210609033929.3815-7-martin.petersen@oracle.com +Reviewed-by: Benjamin Block +Signed-off-by: Martin K. Petersen +Message-Id: <20210609033929.3815-7-martin.petersen@oracle.com> + +Acked-by: Petr Tesarik +--- + drivers/s390/scsi/zfcp_fsf.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/s390/scsi/zfcp_fsf.c ++++ b/drivers/s390/scsi/zfcp_fsf.c +@@ -2599,8 +2599,8 @@ int zfcp_fsf_fcp_cmnd(struct scsi_cmnd * + io->fcp_cmnd_length = FCP_CMND_LEN; + + if (scsi_get_prot_op(scsi_cmnd) != SCSI_PROT_NORMAL) { +- io->data_block_length = scsi_cmnd->device->sector_size; +- io->ref_tag_value = scsi_get_lba(scsi_cmnd) & 0xFFFFFFFF; ++ io->data_block_length = scsi_prot_interval(scsi_cmnd); ++ io->ref_tag_value = scsi_prot_ref_tag(scsi_cmnd); + } + + if (zfcp_fsf_set_data_dir(scsi_cmnd, &io->data_direction)) diff --git a/patches.suse/scsi-zfcp-fix-kernel-doc-comments b/patches.suse/scsi-zfcp-fix-kernel-doc-comments new file mode 100644 index 0000000..2acb5d8 --- /dev/null +++ b/patches.suse/scsi-zfcp-fix-kernel-doc-comments @@ -0,0 +1,76 @@ +From: Heiko Carstens +Date: Mon, 6 Sep 2021 22:28:16 +0200 +Subject: scsi: zfcp: fix kernel doc comments +Git-commit: f6beebb15eeede0c39bb2d25aefa61f9ddcf2395 +Patch-mainline: v5.15-rc1 +References: jsc#PED-455 bsc#1203836 LTC#198623 + +A couple of function names don't match what the kernel doc comments +indicate. + +Acked-by: Benjamin Block +Signed-off-by: Heiko Carstens +Acked-by: Petr Tesarik +--- + drivers/s390/scsi/zfcp_dbf.c | 4 ++-- + drivers/s390/scsi/zfcp_fsf.c | 2 +- + drivers/s390/scsi/zfcp_qdio.c | 2 +- + drivers/s390/scsi/zfcp_unit.c | 4 ++-- + 4 files changed, 6 insertions(+), 6 deletions(-) + +--- a/drivers/s390/scsi/zfcp_dbf.c ++++ b/drivers/s390/scsi/zfcp_dbf.c +@@ -766,7 +766,7 @@ static void zfcp_dbf_unregister(struct z + } + + /** +- * zfcp_adapter_debug_register - registers debug feature for an adapter ++ * zfcp_dbf_adapter_register - registers debug feature for an adapter + * @adapter: pointer to adapter for which debug features should be registered + * return: -ENOMEM on error, 0 otherwise + */ +@@ -824,7 +824,7 @@ err_out: + } + + /** +- * zfcp_adapter_debug_unregister - unregisters debug feature for an adapter ++ * zfcp_dbf_adapter_unregister - unregisters debug feature for an adapter + * @adapter: pointer to adapter for which debug features should be unregistered + */ + void zfcp_dbf_adapter_unregister(struct zfcp_adapter *adapter) +--- a/drivers/s390/scsi/zfcp_fsf.c ++++ b/drivers/s390/scsi/zfcp_fsf.c +@@ -2275,7 +2275,7 @@ static void zfcp_fsf_close_lun_handler(s + } + + /** +- * zfcp_fsf_close_LUN - close LUN ++ * zfcp_fsf_close_lun - close LUN + * @erp_action: pointer to erp_action triggering the "close LUN" + * Returns: 0 on success, error otherwise + */ +--- a/drivers/s390/scsi/zfcp_qdio.c ++++ b/drivers/s390/scsi/zfcp_qdio.c +@@ -384,7 +384,7 @@ free_req_q: + } + + /** +- * zfcp_close_qdio - close qdio queues for an adapter ++ * zfcp_qdio_close - close qdio queues for an adapter + * @qdio: pointer to structure zfcp_qdio + */ + void zfcp_qdio_close(struct zfcp_qdio *qdio) +--- a/drivers/s390/scsi/zfcp_unit.c ++++ b/drivers/s390/scsi/zfcp_unit.c +@@ -111,9 +111,9 @@ static void zfcp_unit_release(struct dev + } + + /** +- * zfcp_unit_enqueue - enqueue unit to unit list of a port. ++ * zfcp_unit_add - add unit to unit list of a port. + * @port: pointer to port where unit is added +- * @fcp_lun: FCP LUN of unit to be enqueued ++ * @fcp_lun: FCP LUN of unit to be added + * Returns: 0 success + * + * Sets up some unit internal structures and creates sysfs entry. diff --git a/patches.suse/secure_seq-use-the-64-bits-of-the-siphash-for-port-o.patch b/patches.suse/secure_seq-use-the-64-bits-of-the-siphash-for-port-o.patch index d0e1ea7..94b6a44 100644 --- a/patches.suse/secure_seq-use-the-64-bits-of-the-siphash-for-port-o.patch +++ b/patches.suse/secure_seq-use-the-64-bits-of-the-siphash-for-port-o.patch @@ -3,7 +3,7 @@ Date: Mon, 2 May 2022 10:46:08 +0200 Subject: secure_seq: use the 64 bits of the siphash for port offset calculation Patch-mainline: v5.18-rc6 Git-commit: b2d057560b8107c633b39aabe517ff9d93f285e3 -References: CVE-2022-1012 bsc#1199482 +References: CVE-2022-1012 CVE-2022-32296 bsc#1199482 bsc#1200288 SipHash replaced MD5 in secure_ipv{4,6}_port_ephemeral() via commit 7cd23e5300c1 ("secure_seq: use SipHash in place of MD5"), but the output diff --git a/patches.suse/selftest-tpm2-Add-Client.__del__-to-close-dev-tpm-ha.patch b/patches.suse/selftest-tpm2-Add-Client.__del__-to-close-dev-tpm-ha.patch new file mode 100644 index 0000000..2bbc4df --- /dev/null +++ b/patches.suse/selftest-tpm2-Add-Client.__del__-to-close-dev-tpm-ha.patch @@ -0,0 +1,49 @@ +From 2d869f0b458547386fbcd8cf3004b271b7347b7f Mon Sep 17 00:00:00 2001 +From: Stefan Berger +Date: Tue, 20 Sep 2022 09:15:18 -0400 +Subject: [PATCH] selftest: tpm2: Add Client.__del__() to close /dev/tpm* handle +Git-commit: 2d869f0b458547386fbcd8cf3004b271b7347b7f +Patch-mainline: v6.1-rc1 +References: git-fixes + +The following output can bee seen when the test is executed: + + test_flush_context (tpm2_tests.SpaceTest) ... \ + /usr/lib64/python3.6/unittest/case.py:605: ResourceWarning: \ + unclosed file <_io.FileIO name='/dev/tpmrm0' mode='rb+' closefd=True> + +An instance of Client does not implicitly close /dev/tpm* handle, once it +gets destroyed. Close the file handle in the class destructor +Client.__del__(). + +Fixes: 6ea3dfe1e0732 ("selftests: add TPM 2.0 tests") +Cc: Shuah Khan +Cc: linux-kselftest@vger.kernel.org +Cc: Jarkko Sakkinen +Signed-off-by: Stefan Berger +Reviewed-by: Jarkko Sakkinen +Signed-off-by: Jarkko Sakkinen +Acked-by: Takashi Iwai + +--- + tools/testing/selftests/tpm2/tpm2.py | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/tools/testing/selftests/tpm2/tpm2.py b/tools/testing/selftests/tpm2/tpm2.py +index 057a4f49c79d..c7363c6764fc 100644 +--- a/tools/testing/selftests/tpm2/tpm2.py ++++ b/tools/testing/selftests/tpm2/tpm2.py +@@ -371,6 +371,10 @@ class Client: + fcntl.fcntl(self.tpm, fcntl.F_SETFL, flags) + self.tpm_poll = select.poll() + ++ def __del__(self): ++ if self.tpm: ++ self.tpm.close() ++ + def close(self): + self.tpm.close() + +-- +2.35.3 + diff --git a/patches.suse/selftests-Fix-the-if-conditions-of-in-test_extra_fil.patch b/patches.suse/selftests-Fix-the-if-conditions-of-in-test_extra_fil.patch new file mode 100644 index 0000000..1f35507 --- /dev/null +++ b/patches.suse/selftests-Fix-the-if-conditions-of-in-test_extra_fil.patch @@ -0,0 +1,37 @@ +From bc7a319844891746135dc1f34ab9df78d636a3ac Mon Sep 17 00:00:00 2001 +From: Wang Yufen +Date: Fri, 23 Sep 2022 15:02:37 +0800 +Subject: [PATCH] selftests: Fix the if conditions of in test_extra_filter() +Git-commit: bc7a319844891746135dc1f34ab9df78d636a3ac +Patch-mainline: v6.0 +References: git-fixes + +The socket 2 bind the addr in use, bind should fail with EADDRINUSE. So +if bind success or errno != EADDRINUSE, testcase should be failed. + +Fixes: 3ca8e4029969 ("soreuseport: BPF selection functional test") +Signed-off-by: Wang Yufen +Link: https://lore.kernel.org/r/1663916557-10730-1-git-send-email-wangyufen@huawei.com +Signed-off-by: Paolo Abeni +Acked-by: Takashi Iwai + +--- + tools/testing/selftests/net/reuseport_bpf.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/net/reuseport_bpf.c b/tools/testing/selftests/net/reuseport_bpf.c +index 072d709c96b4..65aea27d761c 100644 +--- a/tools/testing/selftests/net/reuseport_bpf.c ++++ b/tools/testing/selftests/net/reuseport_bpf.c +@@ -328,7 +328,7 @@ static void test_extra_filter(const struct test_params p) + if (bind(fd1, addr, sockaddr_size())) + error(1, errno, "failed to bind recv socket 1"); + +- if (!bind(fd2, addr, sockaddr_size()) && errno != EADDRINUSE) ++ if (!bind(fd2, addr, sockaddr_size()) || errno != EADDRINUSE) + error(1, errno, "bind socket 2 should fail with EADDRINUSE"); + + free(addr); +-- +2.35.3 + diff --git a/patches.suse/selftests-forwarding-Fix-failing-tests-with-old-libn.patch b/patches.suse/selftests-forwarding-Fix-failing-tests-with-old-libn.patch new file mode 100644 index 0000000..332675f --- /dev/null +++ b/patches.suse/selftests-forwarding-Fix-failing-tests-with-old-libn.patch @@ -0,0 +1,260 @@ +From 8bcfb4ae4d970b9a9724ddfbac26c387934e0e94 Mon Sep 17 00:00:00 2001 +From: Ido Schimmel +Date: Tue, 9 Aug 2022 14:33:20 +0300 +Subject: [PATCH] selftests: forwarding: Fix failing tests with old libnet +Git-commit: 8bcfb4ae4d970b9a9724ddfbac26c387934e0e94 +Patch-mainline: v6.0-rc1 +References: git-fixes + +The custom multipath hash tests use mausezahn in order to test how +changes in various packet fields affect the packet distribution across +the available nexthops. + +The tool uses the libnet library for various low-level packet +construction and injection. The library started using the +"SO_BINDTODEVICE" socket option for IPv6 sockets in version 1.1.6 and +for IPv4 sockets in version 1.2. + +When the option is not set, packets are not routed according to the +table associated with the VRF master device and tests fail. + +Fix this by prefixing the command with "ip vrf exec", which will cause +the route lookup to occur in the VRF routing table. This makes the tests +pass regardless of the libnet library version. + +Fixes: 511e8db54036 ("selftests: forwarding: Add test for custom multipath hash") +Fixes: 185b0c190bb6 ("selftests: forwarding: Add test for custom multipath hash with IPv4 GRE") +Fixes: b7715acba4d3 ("selftests: forwarding: Add test for custom multipath hash with IPv6 GRE") +Reported-by: Ivan Vecera +Tested-by: Ivan Vecera +Signed-off-by: Ido Schimmel +Reviewed-by: Amit Cohen +Link: https://lore.kernel.org/r/20220809113320.751413-1-idosch@nvidia.com +Signed-off-by: Jakub Kicinski +Acked-by: Takashi Iwai + +--- + .../net/forwarding/custom_multipath_hash.sh | 24 ++++++++++++------- + .../forwarding/gre_custom_multipath_hash.sh | 24 ++++++++++++------- + .../ip6gre_custom_multipath_hash.sh | 24 ++++++++++++------- + 3 files changed, 48 insertions(+), 24 deletions(-) + +diff --git a/tools/testing/selftests/net/forwarding/custom_multipath_hash.sh b/tools/testing/selftests/net/forwarding/custom_multipath_hash.sh +index a15d21dc035a..56eb83d1a3bd 100755 +--- a/tools/testing/selftests/net/forwarding/custom_multipath_hash.sh ++++ b/tools/testing/selftests/net/forwarding/custom_multipath_hash.sh +@@ -181,37 +181,43 @@ ping_ipv6() + + send_src_ipv4() + { +- $MZ $h1 -q -p 64 -A "198.51.100.2-198.51.100.253" -B 203.0.113.2 \ ++ ip vrf exec v$h1 $MZ $h1 -q -p 64 \ ++ -A "198.51.100.2-198.51.100.253" -B 203.0.113.2 \ + -d 1msec -c 50 -t udp "sp=20000,dp=30000" + } + + send_dst_ipv4() + { +- $MZ $h1 -q -p 64 -A 198.51.100.2 -B "203.0.113.2-203.0.113.253" \ ++ ip vrf exec v$h1 $MZ $h1 -q -p 64 \ ++ -A 198.51.100.2 -B "203.0.113.2-203.0.113.253" \ + -d 1msec -c 50 -t udp "sp=20000,dp=30000" + } + + send_src_udp4() + { +- $MZ $h1 -q -p 64 -A 198.51.100.2 -B 203.0.113.2 \ ++ ip vrf exec v$h1 $MZ $h1 -q -p 64 \ ++ -A 198.51.100.2 -B 203.0.113.2 \ + -d 1msec -t udp "sp=0-32768,dp=30000" + } + + send_dst_udp4() + { +- $MZ $h1 -q -p 64 -A 198.51.100.2 -B 203.0.113.2 \ ++ ip vrf exec v$h1 $MZ $h1 -q -p 64 \ ++ -A 198.51.100.2 -B 203.0.113.2 \ + -d 1msec -t udp "sp=20000,dp=0-32768" + } + + send_src_ipv6() + { +- $MZ -6 $h1 -q -p 64 -A "2001:db8:1::2-2001:db8:1::fd" -B 2001:db8:4::2 \ ++ ip vrf exec v$h1 $MZ -6 $h1 -q -p 64 \ ++ -A "2001:db8:1::2-2001:db8:1::fd" -B 2001:db8:4::2 \ + -d 1msec -c 50 -t udp "sp=20000,dp=30000" + } + + send_dst_ipv6() + { +- $MZ -6 $h1 -q -p 64 -A 2001:db8:1::2 -B "2001:db8:4::2-2001:db8:4::fd" \ ++ ip vrf exec v$h1 $MZ -6 $h1 -q -p 64 \ ++ -A 2001:db8:1::2 -B "2001:db8:4::2-2001:db8:4::fd" \ + -d 1msec -c 50 -t udp "sp=20000,dp=30000" + } + +@@ -226,13 +232,15 @@ send_flowlabel() + + send_src_udp6() + { +- $MZ -6 $h1 -q -p 64 -A 2001:db8:1::2 -B 2001:db8:4::2 \ ++ ip vrf exec v$h1 $MZ -6 $h1 -q -p 64 \ ++ -A 2001:db8:1::2 -B 2001:db8:4::2 \ + -d 1msec -t udp "sp=0-32768,dp=30000" + } + + send_dst_udp6() + { +- $MZ -6 $h1 -q -p 64 -A 2001:db8:1::2 -B 2001:db8:4::2 \ ++ ip vrf exec v$h1 $MZ -6 $h1 -q -p 64 \ ++ -A 2001:db8:1::2 -B 2001:db8:4::2 \ + -d 1msec -t udp "sp=20000,dp=0-32768" + } + +diff --git a/tools/testing/selftests/net/forwarding/gre_custom_multipath_hash.sh b/tools/testing/selftests/net/forwarding/gre_custom_multipath_hash.sh +index a73f52efcb6c..0446db9c6f74 100755 +--- a/tools/testing/selftests/net/forwarding/gre_custom_multipath_hash.sh ++++ b/tools/testing/selftests/net/forwarding/gre_custom_multipath_hash.sh +@@ -276,37 +276,43 @@ ping_ipv6() + + send_src_ipv4() + { +- $MZ $h1 -q -p 64 -A "198.51.100.2-198.51.100.253" -B 203.0.113.2 \ ++ ip vrf exec v$h1 $MZ $h1 -q -p 64 \ ++ -A "198.51.100.2-198.51.100.253" -B 203.0.113.2 \ + -d 1msec -c 50 -t udp "sp=20000,dp=30000" + } + + send_dst_ipv4() + { +- $MZ $h1 -q -p 64 -A 198.51.100.2 -B "203.0.113.2-203.0.113.253" \ ++ ip vrf exec v$h1 $MZ $h1 -q -p 64 \ ++ -A 198.51.100.2 -B "203.0.113.2-203.0.113.253" \ + -d 1msec -c 50 -t udp "sp=20000,dp=30000" + } + + send_src_udp4() + { +- $MZ $h1 -q -p 64 -A 198.51.100.2 -B 203.0.113.2 \ ++ ip vrf exec v$h1 $MZ $h1 -q -p 64 \ ++ -A 198.51.100.2 -B 203.0.113.2 \ + -d 1msec -t udp "sp=0-32768,dp=30000" + } + + send_dst_udp4() + { +- $MZ $h1 -q -p 64 -A 198.51.100.2 -B 203.0.113.2 \ ++ ip vrf exec v$h1 $MZ $h1 -q -p 64 \ ++ -A 198.51.100.2 -B 203.0.113.2 \ + -d 1msec -t udp "sp=20000,dp=0-32768" + } + + send_src_ipv6() + { +- $MZ -6 $h1 -q -p 64 -A "2001:db8:1::2-2001:db8:1::fd" -B 2001:db8:2::2 \ ++ ip vrf exec v$h1 $MZ -6 $h1 -q -p 64 \ ++ -A "2001:db8:1::2-2001:db8:1::fd" -B 2001:db8:2::2 \ + -d 1msec -c 50 -t udp "sp=20000,dp=30000" + } + + send_dst_ipv6() + { +- $MZ -6 $h1 -q -p 64 -A 2001:db8:1::2 -B "2001:db8:2::2-2001:db8:2::fd" \ ++ ip vrf exec v$h1 $MZ -6 $h1 -q -p 64 \ ++ -A 2001:db8:1::2 -B "2001:db8:2::2-2001:db8:2::fd" \ + -d 1msec -c 50 -t udp "sp=20000,dp=30000" + } + +@@ -321,13 +327,15 @@ send_flowlabel() + + send_src_udp6() + { +- $MZ -6 $h1 -q -p 64 -A 2001:db8:1::2 -B 2001:db8:2::2 \ ++ ip vrf exec v$h1 $MZ -6 $h1 -q -p 64 \ ++ -A 2001:db8:1::2 -B 2001:db8:2::2 \ + -d 1msec -t udp "sp=0-32768,dp=30000" + } + + send_dst_udp6() + { +- $MZ -6 $h1 -q -p 64 -A 2001:db8:1::2 -B 2001:db8:2::2 \ ++ ip vrf exec v$h1 $MZ -6 $h1 -q -p 64 \ ++ -A 2001:db8:1::2 -B 2001:db8:2::2 \ + -d 1msec -t udp "sp=20000,dp=0-32768" + } + +diff --git a/tools/testing/selftests/net/forwarding/ip6gre_custom_multipath_hash.sh b/tools/testing/selftests/net/forwarding/ip6gre_custom_multipath_hash.sh +index 8fea2c2e0b25..d40183b4eccc 100755 +--- a/tools/testing/selftests/net/forwarding/ip6gre_custom_multipath_hash.sh ++++ b/tools/testing/selftests/net/forwarding/ip6gre_custom_multipath_hash.sh +@@ -278,37 +278,43 @@ ping_ipv6() + + send_src_ipv4() + { +- $MZ $h1 -q -p 64 -A "198.51.100.2-198.51.100.253" -B 203.0.113.2 \ ++ ip vrf exec v$h1 $MZ $h1 -q -p 64 \ ++ -A "198.51.100.2-198.51.100.253" -B 203.0.113.2 \ + -d 1msec -c 50 -t udp "sp=20000,dp=30000" + } + + send_dst_ipv4() + { +- $MZ $h1 -q -p 64 -A 198.51.100.2 -B "203.0.113.2-203.0.113.253" \ ++ ip vrf exec v$h1 $MZ $h1 -q -p 64 \ ++ -A 198.51.100.2 -B "203.0.113.2-203.0.113.253" \ + -d 1msec -c 50 -t udp "sp=20000,dp=30000" + } + + send_src_udp4() + { +- $MZ $h1 -q -p 64 -A 198.51.100.2 -B 203.0.113.2 \ ++ ip vrf exec v$h1 $MZ $h1 -q -p 64 \ ++ -A 198.51.100.2 -B 203.0.113.2 \ + -d 1msec -t udp "sp=0-32768,dp=30000" + } + + send_dst_udp4() + { +- $MZ $h1 -q -p 64 -A 198.51.100.2 -B 203.0.113.2 \ ++ ip vrf exec v$h1 $MZ $h1 -q -p 64 \ ++ -A 198.51.100.2 -B 203.0.113.2 \ + -d 1msec -t udp "sp=20000,dp=0-32768" + } + + send_src_ipv6() + { +- $MZ -6 $h1 -q -p 64 -A "2001:db8:1::2-2001:db8:1::fd" -B 2001:db8:2::2 \ ++ ip vrf exec v$h1 $MZ -6 $h1 -q -p 64 \ ++ -A "2001:db8:1::2-2001:db8:1::fd" -B 2001:db8:2::2 \ + -d 1msec -c 50 -t udp "sp=20000,dp=30000" + } + + send_dst_ipv6() + { +- $MZ -6 $h1 -q -p 64 -A 2001:db8:1::2 -B "2001:db8:2::2-2001:db8:2::fd" \ ++ ip vrf exec v$h1 $MZ -6 $h1 -q -p 64 \ ++ -A 2001:db8:1::2 -B "2001:db8:2::2-2001:db8:2::fd" \ + -d 1msec -c 50 -t udp "sp=20000,dp=30000" + } + +@@ -323,13 +329,15 @@ send_flowlabel() + + send_src_udp6() + { +- $MZ -6 $h1 -q -p 64 -A 2001:db8:1::2 -B 2001:db8:2::2 \ ++ ip vrf exec v$h1 $MZ -6 $h1 -q -p 64 \ ++ -A 2001:db8:1::2 -B 2001:db8:2::2 \ + -d 1msec -t udp "sp=0-32768,dp=30000" + } + + send_dst_udp6() + { +- $MZ -6 $h1 -q -p 64 -A 2001:db8:1::2 -B 2001:db8:2::2 \ ++ ip vrf exec v$h1 $MZ -6 $h1 -q -p 64 \ ++ -A 2001:db8:1::2 -B 2001:db8:2::2 \ + -d 1msec -t udp "sp=20000,dp=0-32768" + } + +-- +2.35.3 + diff --git a/patches.suse/selftests-forwarding-add-shebang-for-sch_red.sh.patch b/patches.suse/selftests-forwarding-add-shebang-for-sch_red.sh.patch new file mode 100644 index 0000000..fb8c504 --- /dev/null +++ b/patches.suse/selftests-forwarding-add-shebang-for-sch_red.sh.patch @@ -0,0 +1,38 @@ +From 83e4b196838d90799a8879e5054a3beecf9ed256 Mon Sep 17 00:00:00 2001 +From: Hangbin Liu +Date: Thu, 22 Sep 2022 10:44:53 +0800 +Subject: [PATCH] selftests: forwarding: add shebang for sch_red.sh +Git-commit: 83e4b196838d90799a8879e5054a3beecf9ed256 +Patch-mainline: v6.0-rc7 +References: git-fixes + +RHEL/Fedora RPM build checks are stricter, and complain when executable +files don't have a shebang line, e.g. + +*** WARNING: ./kselftests/net/forwarding/sch_red.sh is executable but has no shebang, removing executable bit + +Fix it by adding shebang line. + +Fixes: 6cf0291f9517 ("selftests: forwarding: Add a RED test for SW datapath") +Signed-off-by: Hangbin Liu +Reviewed-by: Petr Machata +Link: https://lore.kernel.org/r/20220922024453.437757-1-liuhangbin@gmail.com +Signed-off-by: Jakub Kicinski +Acked-by: Takashi Iwai + +--- + tools/testing/selftests/net/forwarding/sch_red.sh | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tools/testing/selftests/net/forwarding/sch_red.sh b/tools/testing/selftests/net/forwarding/sch_red.sh +index e714bae473fb..81f31179ac88 100755 +--- a/tools/testing/selftests/net/forwarding/sch_red.sh ++++ b/tools/testing/selftests/net/forwarding/sch_red.sh +@@ -1,3 +1,4 @@ ++#!/bin/bash + # SPDX-License-Identifier: GPL-2.0 + + # This test sends one stream of traffic from H1 through a TBF shaper, to a RED +-- +2.35.3 + diff --git a/patches.suse/selftests-net-add-delete-nexthop-route-warning-test.patch b/patches.suse/selftests-net-add-delete-nexthop-route-warning-test.patch new file mode 100644 index 0000000..01b2d44 --- /dev/null +++ b/patches.suse/selftests-net-add-delete-nexthop-route-warning-test.patch @@ -0,0 +1,58 @@ +From 392baa339c6a42a2cb088e5e5df2b59b8f89be24 Mon Sep 17 00:00:00 2001 +From: Nikolay Aleksandrov +Date: Fri, 1 Apr 2022 10:33:43 +0300 +Subject: [PATCH] selftests: net: add delete nexthop route warning test +Git-commit: 392baa339c6a42a2cb088e5e5df2b59b8f89be24 +Patch-mainline: v5.18-rc2 +References: bsc#1204171 CVE-2022-3435 + +Add a test which causes a WARNING on kernels which treat a +nexthop route like a normal route when comparing for deletion and a +device is specified. That is, a route is found but we hit a warning while +matching it. The warning is from fib_info_nh() in include/net/nexthop.h +because we run it on a fib_info with nexthop object. The call chain is: + inet_rtm_delroute -> fib_table_delete -> fib_nh_match (called with a +nexthop fib_info and also with fc_oif set thus calling fib_info_nh on +the fib_info and triggering the warning). + +Repro steps: + $ ip nexthop add id 12 via 172.16.1.3 dev veth1 + $ ip route add 172.16.101.1/32 nhid 12 + $ ip route delete 172.16.101.1/32 dev veth1 + +Signed-off-by: Nikolay Aleksandrov +Reviewed-by: David Ahern +Signed-off-by: David S. Miller +Signed-off-by: Denis Kirjanov +--- + tools/testing/selftests/net/fib_nexthops.sh | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/tools/testing/selftests/net/fib_nexthops.sh b/tools/testing/selftests/net/fib_nexthops.sh +index d444ee6aa3cb..d8ede0c81ac1 100755 +--- a/tools/testing/selftests/net/fib_nexthops.sh ++++ b/tools/testing/selftests/net/fib_nexthops.sh +@@ -1208,6 +1208,20 @@ ipv4_fcnal() + set +e + check_nexthop "dev veth1" "" + log_test $? 0 "Nexthops removed on admin down" ++ ++ # nexthop route delete warning: route add with nhid and delete ++ # using device ++ run_cmd "$IP li set dev veth1 up" ++ run_cmd "$IP nexthop add id 12 via 172.16.1.3 dev veth1" ++ out1=`dmesg | grep "WARNING:.*fib_nh_match.*" | wc -l` ++ run_cmd "$IP route add 172.16.101.1/32 nhid 12" ++ run_cmd "$IP route delete 172.16.101.1/32 dev veth1" ++ out2=`dmesg | grep "WARNING:.*fib_nh_match.*" | wc -l` ++ [ $out1 -eq $out2 ] ++ rc=$? ++ log_test $rc 0 "Delete nexthop route warning" ++ run_cmd "$IP ip route delete 172.16.101.1/32 nhid 12" ++ run_cmd "$IP ip nexthop del id 12" + } + + ipv4_grp_fcnal() +-- +2.16.4 + diff --git a/patches.suse/selftests-net-fix-nexthop-warning-cleanup-double-ip-.patch b/patches.suse/selftests-net-fix-nexthop-warning-cleanup-double-ip-.patch new file mode 100644 index 0000000..3064a60 --- /dev/null +++ b/patches.suse/selftests-net-fix-nexthop-warning-cleanup-double-ip-.patch @@ -0,0 +1,39 @@ +From 692930cc435099580a4b9e32fa781b0688c18439 Mon Sep 17 00:00:00 2001 +From: Nikolay Aleksandrov +Date: Fri, 1 Apr 2022 18:54:27 +0300 +Subject: [PATCH] selftests: net: fix nexthop warning cleanup double ip typo +Git-commit: 692930cc435099580a4b9e32fa781b0688c18439 +Patch-mainline: v5.18-rc2 +References: bsc#1204171 CVE-2022-3435 + +I made a stupid typo when adding the nexthop route warning selftest and +added both $IP and ip after it (double ip) on the cleanup path. The +error doesn't show up when running the test, but obviously it doesn't +cleanup properly after it. + +Fixes: 392baa339c6a ("selftests: net: add delete nexthop route warning test") +Signed-off-by: Nikolay Aleksandrov +Signed-off-by: David S. Miller +Signed-off-by: Denis Kirjanov +--- + tools/testing/selftests/net/fib_nexthops.sh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/testing/selftests/net/fib_nexthops.sh b/tools/testing/selftests/net/fib_nexthops.sh +index d8ede0c81ac1..b3bf5319bb0e 100755 +--- a/tools/testing/selftests/net/fib_nexthops.sh ++++ b/tools/testing/selftests/net/fib_nexthops.sh +@@ -1220,8 +1220,8 @@ ipv4_fcnal() + [ $out1 -eq $out2 ] + rc=$? + log_test $rc 0 "Delete nexthop route warning" +- run_cmd "$IP ip route delete 172.16.101.1/32 nhid 12" +- run_cmd "$IP ip nexthop del id 12" ++ run_cmd "$IP route delete 172.16.101.1/32 nhid 12" ++ run_cmd "$IP nexthop del id 12" + } + + ipv4_grp_fcnal() +-- +2.16.4 + diff --git a/patches.suse/selftests-netfilter-Fix-nft_fib.sh-for-all.rp_filter.patch b/patches.suse/selftests-netfilter-Fix-nft_fib.sh-for-all.rp_filter.patch new file mode 100644 index 0000000..ccd1d9c --- /dev/null +++ b/patches.suse/selftests-netfilter-Fix-nft_fib.sh-for-all.rp_filter.patch @@ -0,0 +1,37 @@ +From 6a91e7270936c5a504af7e0a197d7021e169d281 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 5 Oct 2022 17:34:36 +0200 +Subject: [PATCH] selftests: netfilter: Fix nft_fib.sh for all.rp_filter=1 +Git-commit: 6a91e7270936c5a504af7e0a197d7021e169d281 +Patch-mainline: v6.1-rc1 +References: git-fixes + +If net.ipv4.conf.all.rp_filter is set, it overrides the per-interface +setting and thus defeats the fix from bbe4c0896d250 ("selftests: +Netfilter: disable rp_filter on router"). Unset it as well to cover that +case. + +Fixes: bbe4c0896d250 ("selftests: netfilter: disable rp_filter on router") +Signed-off-by: Phil Sutter +Signed-off-by: Florian Westphal +Acked-by: Takashi Iwai + +--- + tools/testing/selftests/netfilter/nft_fib.sh | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tools/testing/selftests/netfilter/nft_fib.sh b/tools/testing/selftests/netfilter/nft_fib.sh +index fd76b69635a4..dff476e45e77 100755 +--- a/tools/testing/selftests/netfilter/nft_fib.sh ++++ b/tools/testing/selftests/netfilter/nft_fib.sh +@@ -188,6 +188,7 @@ test_ping() { + ip netns exec ${nsrouter} sysctl net.ipv6.conf.all.forwarding=1 > /dev/null + ip netns exec ${nsrouter} sysctl net.ipv4.conf.veth0.forwarding=1 > /dev/null + ip netns exec ${nsrouter} sysctl net.ipv4.conf.veth1.forwarding=1 > /dev/null ++ip netns exec ${nsrouter} sysctl net.ipv4.conf.all.rp_filter=0 > /dev/null + ip netns exec ${nsrouter} sysctl net.ipv4.conf.veth0.rp_filter=0 > /dev/null + + sleep 3 +-- +2.35.3 + diff --git a/patches.suse/selftests-powerpc-Skip-energy_scale_info-test-on-old.patch b/patches.suse/selftests-powerpc-Skip-energy_scale_info-test-on-old.patch new file mode 100644 index 0000000..04aa7ab --- /dev/null +++ b/patches.suse/selftests-powerpc-Skip-energy_scale_info-test-on-old.patch @@ -0,0 +1,105 @@ +From 4228a996b072d36f3baafb4afdc2d2d66d2cbadf Mon Sep 17 00:00:00 2001 +From: Michael Ellerman +Date: Mon, 20 Jun 2022 09:31:03 +1000 +Subject: [PATCH] selftests/powerpc: Skip energy_scale_info test on older + firmware + +References: git-fixes +Patch-mainline: v6.0-rc1 +Git-commit: 4228a996b072d36f3baafb4afdc2d2d66d2cbadf + +Older machines don't have the firmware feature that enables the code +this test is testing. Skip the test if the sysfs directory doesn't +exist. Also use the FAIL_IF() macro to provide more verbose error +reporting if an error is encountered. + +Fixes: 57201d657eb7 ("selftest/powerpc: Add PAPR sysfs attributes sniff test") +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/20220619233103.2666171-1-mpe@ellerman.id.au +Acked-by: Michal Suchanek +--- + .../powerpc/papr_attributes/attr_test.c | 30 +++++++++++-------- + 1 file changed, 18 insertions(+), 12 deletions(-) + +diff --git a/tools/testing/selftests/powerpc/papr_attributes/attr_test.c b/tools/testing/selftests/powerpc/papr_attributes/attr_test.c +index bab0dc06e90b..9b655be641c9 100644 +--- a/tools/testing/selftests/powerpc/papr_attributes/attr_test.c ++++ b/tools/testing/selftests/powerpc/papr_attributes/attr_test.c +@@ -7,6 +7,7 @@ + * Copyright 2022, Pratik Rajesh Sampat, IBM Corp. + */ + ++#include + #include + #include + #include +@@ -32,7 +33,7 @@ enum type { + NUM_VAL + }; + +-int value_type(int id) ++static int value_type(int id) + { + int val_type; + +@@ -54,15 +55,21 @@ int value_type(int id) + return val_type; + } + +-int verify_energy_info(void) ++static int verify_energy_info(void) + { + const char *path = "/sys/firmware/papr/energy_scale_info"; + struct dirent *entry; + struct stat s; + DIR *dirp; + +- if (stat(path, &s) || !S_ISDIR(s.st_mode)) +- return -1; ++ errno = 0; ++ if (stat(path, &s)) { ++ SKIP_IF(errno == ENOENT); ++ FAIL_IF(errno); ++ } ++ ++ FAIL_IF(!S_ISDIR(s.st_mode)); ++ + dirp = opendir(path); + + while ((entry = readdir(dirp)) != NULL) { +@@ -76,25 +83,24 @@ int verify_energy_info(void) + + id = atoi(entry->d_name); + attr_type = value_type(id); +- if (attr_type == INVALID) +- return -1; ++ FAIL_IF(attr_type == INVALID); + + /* Check if the files exist and have data in them */ + sprintf(file_name, "%s/%d/desc", path, id); + f = fopen(file_name, "r"); +- if (!f || fgetc(f) == EOF) +- return -1; ++ FAIL_IF(!f); ++ FAIL_IF(fgetc(f) == EOF); + + sprintf(file_name, "%s/%d/value", path, id); + f = fopen(file_name, "r"); +- if (!f || fgetc(f) == EOF) +- return -1; ++ FAIL_IF(!f); ++ FAIL_IF(fgetc(f) == EOF); + + if (attr_type == STR_VAL) { + sprintf(file_name, "%s/%d/value_desc", path, id); + f = fopen(file_name, "r"); +- if (!f || fgetc(f) == EOF) +- return -1; ++ FAIL_IF(!f); ++ FAIL_IF(fgetc(f) == EOF); + } + } + +-- +2.35.3 + diff --git a/patches.suse/serial-8250-Fix-restoring-termios-speed-after-suspen.patch b/patches.suse/serial-8250-Fix-restoring-termios-speed-after-suspen.patch new file mode 100644 index 0000000..4c53ced --- /dev/null +++ b/patches.suse/serial-8250-Fix-restoring-termios-speed-after-suspen.patch @@ -0,0 +1,54 @@ +From 379a33786d489ab81885ff0b3935cfeb36137fea Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= +Date: Sat, 24 Sep 2022 12:43:24 +0200 +Subject: [PATCH] serial: 8250: Fix restoring termios speed after suspend +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 379a33786d489ab81885ff0b3935cfeb36137fea +Patch-mainline: v6.1-rc1 +References: git-fixes + +Since commit edc6afc54968 ("tty: switch to ktermios and new framework") +termios speed is no longer stored only in c_cflag member but also in new +additional c_ispeed and c_ospeed members. If BOTHER flag is set in c_cflag +then termios speed is stored only in these new members. + +Since commit 027b57170bf8 ("serial: core: Fix initializing and restoring +termios speed") termios speed is available also in struct console. + +So properly restore also c_ispeed and c_ospeed members after suspend to fix +restoring termios speed which is not represented by Bnnn constant. + +Fixes: 4516d50aabed ("serial: 8250: Use canary to restart console after suspend") +Signed-off-by: Pali Rohár +Link: https://lore.kernel.org/r/20220924104324.4035-1-pali@kernel.org +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/tty/serial/8250/8250_port.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c +index dfdd2db95cb3..fe8662cd9402 100644 +--- a/drivers/tty/serial/8250/8250_port.c ++++ b/drivers/tty/serial/8250/8250_port.c +@@ -3321,8 +3321,13 @@ static void serial8250_console_restore(struct uart_8250_port *up) + unsigned int baud, quot, frac = 0; + + termios.c_cflag = port->cons->cflag; +- if (port->state->port.tty && termios.c_cflag == 0) ++ termios.c_ispeed = port->cons->ispeed; ++ termios.c_ospeed = port->cons->ospeed; ++ if (port->state->port.tty && termios.c_cflag == 0) { + termios.c_cflag = port->state->port.tty->termios.c_cflag; ++ termios.c_ispeed = port->state->port.tty->termios.c_ispeed; ++ termios.c_ospeed = port->state->port.tty->termios.c_ospeed; ++ } + + baud = serial8250_get_baud_rate(port, &termios, NULL); + quot = serial8250_get_divisor(port, baud, &frac); +-- +2.35.3 + diff --git a/patches.suse/serial-Create-uart_xmit_advance.patch b/patches.suse/serial-Create-uart_xmit_advance.patch new file mode 100644 index 0000000..21206f2 --- /dev/null +++ b/patches.suse/serial-Create-uart_xmit_advance.patch @@ -0,0 +1,57 @@ +From e77cab77f2cb3a1ca2ba8df4af45bb35617ac16d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= +Date: Thu, 1 Sep 2022 17:39:32 +0300 +Subject: [PATCH] serial: Create uart_xmit_advance() +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: e77cab77f2cb3a1ca2ba8df4af45bb35617ac16d +Patch-mainline: v6.0-rc7 +References: git-fixes + +A very common pattern in the drivers is to advance xmit tail +index and do bookkeeping of Tx'ed characters. Create +uart_xmit_advance() to handle it. + +Reviewed-by: Andy Shevchenko +Cc: stable +Signed-off-by: Ilpo Järvinen +Link: https://lore.kernel.org/r/20220901143934.8850-2-ilpo.jarvinen@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + include/linux/serial_core.h | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h +index 6e4f4765d209..1eaea9fe44d8 100644 +--- a/include/linux/serial_core.h ++++ b/include/linux/serial_core.h +@@ -624,6 +624,23 @@ struct uart_state { + /* number of characters left in xmit buffer before we ask for more */ + #define WAKEUP_CHARS 256 + ++/** ++ * uart_xmit_advance - Advance xmit buffer and account Tx'ed chars ++ * @up: uart_port structure describing the port ++ * @chars: number of characters sent ++ * ++ * This function advances the tail of circular xmit buffer by the number of ++ * @chars transmitted and handles accounting of transmitted bytes (into ++ * @up's icount.tx). ++ */ ++static inline void uart_xmit_advance(struct uart_port *up, unsigned int chars) ++{ ++ struct circ_buf *xmit = &up->state->xmit; ++ ++ xmit->tail = (xmit->tail + chars) & (UART_XMIT_SIZE - 1); ++ up->icount.tx += chars; ++} ++ + struct module; + struct tty_driver; + +-- +2.35.3 + diff --git a/patches.suse/serial-atmel-remove-redundant-assignment-in-rs485_co.patch b/patches.suse/serial-atmel-remove-redundant-assignment-in-rs485_co.patch new file mode 100644 index 0000000..0d733e0 --- /dev/null +++ b/patches.suse/serial-atmel-remove-redundant-assignment-in-rs485_co.patch @@ -0,0 +1,45 @@ +From 60efd0513916f195dd85bfbf21653f74f9ab019c Mon Sep 17 00:00:00 2001 +From: Lino Sanfilippo +Date: Sun, 10 Apr 2022 12:46:42 +0200 +Subject: [PATCH] serial: atmel: remove redundant assignment in rs485_config +Git-commit: 60efd0513916f195dd85bfbf21653f74f9ab019c +Patch-mainline: v5.19-rc1 +References: git-fixes + +In uart_set_rs485_config() the serial core already assigns the passed +serial_rs485 struct to the uart port. + +So remove the assignment from the drivers rs485_config() function to avoid +redundancy. + +Reviewed-by: Claudiu Beznea +Acked-by: Richard Genoud +Signed-off-by: Lino Sanfilippo +Link: https://lore.kernel.org/r/20220410104642.32195-10-LinoSanfilippo@gmx.de +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/tty/serial/atmel_serial.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c +index 3a45e4fc7993..dd1c7e4bd1c9 100644 +--- a/drivers/tty/serial/atmel_serial.c ++++ b/drivers/tty/serial/atmel_serial.c +@@ -299,11 +299,9 @@ static int atmel_config_rs485(struct uart_port *port, + /* Resetting serial mode to RS232 (0x0) */ + mode &= ~ATMEL_US_USMODE; + +- port->rs485 = *rs485conf; +- + if (rs485conf->flags & SER_RS485_ENABLED) { + dev_dbg(port->dev, "Setting UART to RS485\n"); +- if (port->rs485.flags & SER_RS485_RX_DURING_TX) ++ if (rs485conf->flags & SER_RS485_RX_DURING_TX) + atmel_port->tx_done_mask = ATMEL_US_TXRDY; + else + atmel_port->tx_done_mask = ATMEL_US_TXEMPTY; +-- +2.35.3 + diff --git a/patches.suse/serial-fsl_lpuart-Reset-prior-to-registration.patch b/patches.suse/serial-fsl_lpuart-Reset-prior-to-registration.patch new file mode 100644 index 0000000..29d3e70 --- /dev/null +++ b/patches.suse/serial-fsl_lpuart-Reset-prior-to-registration.patch @@ -0,0 +1,69 @@ +From 60f361722ad2ae5ee667d0b0545d40c42f754daf Mon Sep 17 00:00:00 2001 +From: Lukas Wunner +Date: Sun, 11 Sep 2022 10:22:01 +0200 +Subject: [PATCH] serial: fsl_lpuart: Reset prior to registration +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 60f361722ad2ae5ee667d0b0545d40c42f754daf +Patch-mainline: v6.0-rc7 +References: git-fixes + +Since commit bd5305dcabbc ("tty: serial: fsl_lpuart: do software reset +for imx7ulp and imx8qxp"), certain i.MX UARTs are reset after they've +already been registered. Register state may thus be clobbered after +user space has begun to open and access the UART. + +Avoid by performing the reset prior to registration. + +Fixes: bd5305dcabbc ("tty: serial: fsl_lpuart: do software reset for imx7ulp and imx8qxp") +Cc: stable@vger.kernel.org # v5.15+ +Cc: Fugang Duan +Cc: Sherry Sun +Reviewed-by: Ilpo Järvinen +Signed-off-by: Lukas Wunner +Link: https://lore.kernel.org/r/72fb646c1b0b11c989850c55f52f9ff343d1b2fa.1662884345.git.lukas@wunner.de +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/tty/serial/fsl_lpuart.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c +index b20f6f2fa51c..fbc4b071b330 100644 +--- a/drivers/tty/serial/fsl_lpuart.c ++++ b/drivers/tty/serial/fsl_lpuart.c +@@ -2724,14 +2724,15 @@ static int lpuart_probe(struct platform_device *pdev) + lpuart_reg.cons = LPUART_CONSOLE; + handler = lpuart_int; + } +- ret = uart_add_one_port(&lpuart_reg, &sport->port); +- if (ret) +- goto failed_attach_port; + + ret = lpuart_global_reset(sport); + if (ret) + goto failed_reset; + ++ ret = uart_add_one_port(&lpuart_reg, &sport->port); ++ if (ret) ++ goto failed_attach_port; ++ + ret = uart_get_rs485_mode(&sport->port); + if (ret) + goto failed_get_rs485; +@@ -2747,9 +2748,9 @@ static int lpuart_probe(struct platform_device *pdev) + + failed_irq_request: + failed_get_rs485: +-failed_reset: + uart_remove_one_port(&lpuart_reg, &sport->port); + failed_attach_port: ++failed_reset: + lpuart_disable_clks(sport); + return ret; + } +-- +2.35.3 + diff --git a/patches.suse/serial-tegra-Use-uart_xmit_advance-fixes-icount.tx-a.patch b/patches.suse/serial-tegra-Use-uart_xmit_advance-fixes-icount.tx-a.patch new file mode 100644 index 0000000..309efad --- /dev/null +++ b/patches.suse/serial-tegra-Use-uart_xmit_advance-fixes-icount.tx-a.patch @@ -0,0 +1,59 @@ +From 754f68044c7dd6c52534ba3e0f664830285c4b15 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= +Date: Thu, 1 Sep 2022 17:39:33 +0300 +Subject: [PATCH] serial: tegra: Use uart_xmit_advance(), fixes icount.tx accounting +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 754f68044c7dd6c52534ba3e0f664830285c4b15 +Patch-mainline: v6.0-rc7 +References: git-fixes + +DMA complete & stop paths did not correctly account Tx'ed characters +into icount.tx. Using uart_xmit_advance() fixes the problem. + +Fixes: e9ea096dd225 ("serial: tegra: add serial driver") +Cc: # serial: Create uart_xmit_advance() +Reviewed-by: Andy Shevchenko +Signed-off-by: Ilpo Järvinen +Link: https://lore.kernel.org/r/20220901143934.8850-3-ilpo.jarvinen@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/tty/serial/serial-tegra.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c +index ad4f3567ff90..a5748e41483b 100644 +--- a/drivers/tty/serial/serial-tegra.c ++++ b/drivers/tty/serial/serial-tegra.c +@@ -525,7 +525,7 @@ static void tegra_uart_tx_dma_complete(void *args) + count = tup->tx_bytes_requested - state.residue; + async_tx_ack(tup->tx_dma_desc); + spin_lock_irqsave(&tup->uport.lock, flags); +- xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1); ++ uart_xmit_advance(&tup->uport, count); + tup->tx_in_progress = 0; + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) + uart_write_wakeup(&tup->uport); +@@ -613,7 +613,6 @@ static unsigned int tegra_uart_tx_empty(struct uart_port *u) + static void tegra_uart_stop_tx(struct uart_port *u) + { + struct tegra_uart_port *tup = to_tegra_uport(u); +- struct circ_buf *xmit = &tup->uport.state->xmit; + struct dma_tx_state state; + unsigned int count; + +@@ -624,7 +623,7 @@ static void tegra_uart_stop_tx(struct uart_port *u) + dmaengine_tx_status(tup->tx_dma_chan, tup->tx_cookie, &state); + count = tup->tx_bytes_requested - state.residue; + async_tx_ack(tup->tx_dma_desc); +- xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1); ++ uart_xmit_advance(&tup->uport, count); + tup->tx_in_progress = 0; + } + +-- +2.35.3 + diff --git a/patches.suse/serial-tegra-tcu-Use-uart_xmit_advance-fixes-icount..patch b/patches.suse/serial-tegra-tcu-Use-uart_xmit_advance-fixes-icount..patch new file mode 100644 index 0000000..d715b0e --- /dev/null +++ b/patches.suse/serial-tegra-tcu-Use-uart_xmit_advance-fixes-icount..patch @@ -0,0 +1,42 @@ +From 1d10cd4da593bc0196a239dcc54dac24b6b0a74e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= +Date: Thu, 1 Sep 2022 17:39:34 +0300 +Subject: [PATCH] serial: tegra-tcu: Use uart_xmit_advance(), fixes icount.tx accounting +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 1d10cd4da593bc0196a239dcc54dac24b6b0a74e +Patch-mainline: v6.0-rc7 +References: git-fixes + +Tx'ing does not correctly account Tx'ed characters into icount.tx. +Using uart_xmit_advance() fixes the problem. + +Fixes: 2d908b38d409 ("serial: Add Tegra Combined UART driver") +Cc: # serial: Create uart_xmit_advance() +Reviewed-by: Andy Shevchenko +Signed-off-by: Ilpo Järvinen +Link: https://lore.kernel.org/r/20220901143934.8850-4-ilpo.jarvinen@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/tty/serial/tegra-tcu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/tty/serial/tegra-tcu.c b/drivers/tty/serial/tegra-tcu.c +index 4877c54c613d..889b701ba7c6 100644 +--- a/drivers/tty/serial/tegra-tcu.c ++++ b/drivers/tty/serial/tegra-tcu.c +@@ -101,7 +101,7 @@ static void tegra_tcu_uart_start_tx(struct uart_port *port) + break; + + tegra_tcu_write(tcu, &xmit->buf[xmit->tail], count); +- xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1); ++ uart_xmit_advance(port, count); + } + + uart_write_wakeup(port); +-- +2.35.3 + diff --git a/patches.suse/slimbus-qcom-ngd-cleanup-in-probe-error-path.patch b/patches.suse/slimbus-qcom-ngd-cleanup-in-probe-error-path.patch new file mode 100644 index 0000000..e97ae5d --- /dev/null +++ b/patches.suse/slimbus-qcom-ngd-cleanup-in-probe-error-path.patch @@ -0,0 +1,84 @@ +From 16f14551d0df9e7cd283545d7d748829594d912f Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +Date: Fri, 16 Sep 2022 13:29:08 +0100 +Subject: [PATCH] slimbus: qcom-ngd: cleanup in probe error path +Git-commit: 16f14551d0df9e7cd283545d7d748829594d912f +Patch-mainline: v6.1-rc1 +References: git-fixes + +Add proper error path in probe() to cleanup resources previously +acquired/allocated to fix warnings visible during probe deferral: + + notifier callback qcom_slim_ngd_ssr_notify already registered + WARNING: CPU: 6 PID: 70 at kernel/notifier.c:28 notifier_chain_register+0x5c/0x90 + Modules linked in: + CPU: 6 PID: 70 Comm: kworker/u16:1 Not tainted 6.0.0-rc3-next-20220830 #380 + Call trace: + notifier_chain_register+0x5c/0x90 + srcu_notifier_chain_register+0x44/0x90 + qcom_register_ssr_notifier+0x38/0x4c + qcom_slim_ngd_ctrl_probe+0xd8/0x400 + platform_probe+0x6c/0xe0 + really_probe+0xbc/0x2d4 + __driver_probe_device+0x78/0xe0 + driver_probe_device+0x3c/0x12c + __device_attach_driver+0xb8/0x120 + bus_for_each_drv+0x78/0xd0 + __device_attach+0xa8/0x1c0 + device_initial_probe+0x18/0x24 + bus_probe_device+0xa0/0xac + deferred_probe_work_func+0x88/0xc0 + process_one_work+0x1d4/0x320 + worker_thread+0x2cc/0x44c + kthread+0x110/0x114 + ret_from_fork+0x10/0x20 + +Fixes: e1ae85e1830e ("slimbus: qcom-ngd-ctrl: add Protection Domain Restart Support") +Cc: +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20220916122910.170730-3-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/slimbus/qcom-ngd-ctrl.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +diff --git a/drivers/slimbus/qcom-ngd-ctrl.c b/drivers/slimbus/qcom-ngd-ctrl.c +index f4f330b9fa72..bacc6af1d51e 100644 +--- a/drivers/slimbus/qcom-ngd-ctrl.c ++++ b/drivers/slimbus/qcom-ngd-ctrl.c +@@ -1576,18 +1576,27 @@ static int qcom_slim_ngd_ctrl_probe(struct platform_device *pdev) + ctrl->pdr = pdr_handle_alloc(slim_pd_status, ctrl); + if (IS_ERR(ctrl->pdr)) { + dev_err(dev, "Failed to init PDR handle\n"); +- return PTR_ERR(ctrl->pdr); ++ ret = PTR_ERR(ctrl->pdr); ++ goto err_pdr_alloc; + } + + pds = pdr_add_lookup(ctrl->pdr, "avs/audio", "msm/adsp/audio_pd"); + if (IS_ERR(pds) && PTR_ERR(pds) != -EALREADY) { + ret = PTR_ERR(pds); + dev_err(dev, "pdr add lookup failed: %d\n", ret); +- return ret; ++ goto err_pdr_lookup; + } + + platform_driver_register(&qcom_slim_ngd_driver); + return of_qcom_slim_ngd_register(dev, ctrl); ++ ++err_pdr_alloc: ++ qcom_unregister_ssr_notifier(ctrl->notifier, &ctrl->nb); ++ ++err_pdr_lookup: ++ pdr_handle_release(ctrl->pdr); ++ ++ return ret; + } + + static int qcom_slim_ngd_ctrl_remove(struct platform_device *pdev) +-- +2.35.3 + diff --git a/patches.suse/slimbus-qcom-ngd-use-correct-error-in-message-of-pdr.patch b/patches.suse/slimbus-qcom-ngd-use-correct-error-in-message-of-pdr.patch new file mode 100644 index 0000000..61e9ccd --- /dev/null +++ b/patches.suse/slimbus-qcom-ngd-use-correct-error-in-message-of-pdr.patch @@ -0,0 +1,41 @@ +From 5038d21dde818fe74ba1fcb6f2cee35b8c2ebbf2 Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +Date: Fri, 16 Sep 2022 13:29:07 +0100 +Subject: [PATCH] slimbus: qcom-ngd: use correct error in message of pdr_add_lookup() failure +Git-commit: 5038d21dde818fe74ba1fcb6f2cee35b8c2ebbf2 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Use correct error code, instead of previous 'ret' value, when printing +error from pdr_add_lookup() failure. + +Fixes: e1ae85e1830e ("slimbus: qcom-ngd-ctrl: add Protection Domain Restart Support") +Cc: +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20220916122910.170730-2-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/slimbus/qcom-ngd-ctrl.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/slimbus/qcom-ngd-ctrl.c b/drivers/slimbus/qcom-ngd-ctrl.c +index 0aa8408464ad..f4f330b9fa72 100644 +--- a/drivers/slimbus/qcom-ngd-ctrl.c ++++ b/drivers/slimbus/qcom-ngd-ctrl.c +@@ -1581,8 +1581,9 @@ static int qcom_slim_ngd_ctrl_probe(struct platform_device *pdev) + + pds = pdr_add_lookup(ctrl->pdr, "avs/audio", "msm/adsp/audio_pd"); + if (IS_ERR(pds) && PTR_ERR(pds) != -EALREADY) { ++ ret = PTR_ERR(pds); + dev_err(dev, "pdr add lookup failed: %d\n", ret); +- return PTR_ERR(pds); ++ return ret; + } + + platform_driver_register(&qcom_slim_ngd_driver); +-- +2.35.3 + diff --git a/patches.suse/soc-qcom-smem_state-Add-refcounting-for-the-state-of.patch b/patches.suse/soc-qcom-smem_state-Add-refcounting-for-the-state-of.patch new file mode 100644 index 0000000..cabb31f --- /dev/null +++ b/patches.suse/soc-qcom-smem_state-Add-refcounting-for-the-state-of.patch @@ -0,0 +1,46 @@ +From 90681f53b9381c23ff7762a3b13826d620c272de Mon Sep 17 00:00:00 2001 +From: Liang He +Date: Thu, 21 Jul 2022 21:52:17 +0800 +Subject: [PATCH] soc: qcom: smem_state: Add refcounting for the 'state->of_node' +Git-commit: 90681f53b9381c23ff7762a3b13826d620c272de +Patch-mainline: v6.1-rc1 +References: git-fixes + +In qcom_smem_state_register() and qcom_smem_state_release(), we +should better use of_node_get() and of_node_put() for the reference +creation and destruction of 'device_node'. + +Fixes: 9460ae2ff308 ("soc: qcom: Introduce common SMEM state machine code") +Signed-off-by: Liang He +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20220721135217.1301039-2-windhl@126.com +Acked-by: Takashi Iwai + +--- + drivers/soc/qcom/smem_state.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/soc/qcom/smem_state.c b/drivers/soc/qcom/smem_state.c +index 31faf4aa868e..e848cc9a3cf8 100644 +--- a/drivers/soc/qcom/smem_state.c ++++ b/drivers/soc/qcom/smem_state.c +@@ -136,6 +136,7 @@ static void qcom_smem_state_release(struct kref *ref) + struct qcom_smem_state *state = container_of(ref, struct qcom_smem_state, refcount); + + list_del(&state->list); ++ of_node_put(state->of_node); + kfree(state); + } + +@@ -205,7 +206,7 @@ struct qcom_smem_state *qcom_smem_state_register(struct device_node *of_node, + + kref_init(&state->refcount); + +- state->of_node = of_node; ++ state->of_node = of_node_get(of_node); + state->ops = *ops; + state->priv = priv; + +-- +2.35.3 + diff --git a/patches.suse/soc-qcom-smsm-Fix-refcount-leak-bugs-in-qcom_smsm_pr.patch b/patches.suse/soc-qcom-smsm-Fix-refcount-leak-bugs-in-qcom_smsm_pr.patch new file mode 100644 index 0000000..cbe094d --- /dev/null +++ b/patches.suse/soc-qcom-smsm-Fix-refcount-leak-bugs-in-qcom_smsm_pr.patch @@ -0,0 +1,107 @@ +From af8f6f39b8afd772fda4f8e61823ef8c021bf382 Mon Sep 17 00:00:00 2001 +From: Liang He +Date: Thu, 21 Jul 2022 21:52:16 +0800 +Subject: [PATCH] soc: qcom: smsm: Fix refcount leak bugs in qcom_smsm_probe() +Git-commit: af8f6f39b8afd772fda4f8e61823ef8c021bf382 +Patch-mainline: v6.1-rc1 +References: git-fixes + +There are two refcount leak bugs in qcom_smsm_probe(): + +(1) The 'local_node' is escaped out from for_each_child_of_node() as +the break of iteration, we should call of_node_put() for it in error +path or when it is not used anymore. +(2) The 'node' is escaped out from for_each_available_child_of_node() +as the 'goto', we should call of_node_put() for it in goto target. + +Fixes: c97c4090ff72 ("soc: qcom: smsm: Add driver for Qualcomm SMSM") +Signed-off-by: Liang He +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20220721135217.1301039-1-windhl@126.com +Acked-by: Takashi Iwai + +--- + drivers/soc/qcom/smsm.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +diff --git a/drivers/soc/qcom/smsm.c b/drivers/soc/qcom/smsm.c +index 9df9bba242f3..3e8994d6110e 100644 +--- a/drivers/soc/qcom/smsm.c ++++ b/drivers/soc/qcom/smsm.c +@@ -526,7 +526,7 @@ static int qcom_smsm_probe(struct platform_device *pdev) + for (id = 0; id < smsm->num_hosts; id++) { + ret = smsm_parse_ipc(smsm, id); + if (ret < 0) +- return ret; ++ goto out_put; + } + + /* Acquire the main SMSM state vector */ +@@ -534,13 +534,14 @@ static int qcom_smsm_probe(struct platform_device *pdev) + smsm->num_entries * sizeof(u32)); + if (ret < 0 && ret != -EEXIST) { + dev_err(&pdev->dev, "unable to allocate shared state entry\n"); +- return ret; ++ goto out_put; + } + + states = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_SMSM_SHARED_STATE, NULL); + if (IS_ERR(states)) { + dev_err(&pdev->dev, "Unable to acquire shared state entry\n"); +- return PTR_ERR(states); ++ ret = PTR_ERR(states); ++ goto out_put; + } + + /* Acquire the list of interrupt mask vectors */ +@@ -548,13 +549,14 @@ static int qcom_smsm_probe(struct platform_device *pdev) + ret = qcom_smem_alloc(QCOM_SMEM_HOST_ANY, SMEM_SMSM_CPU_INTR_MASK, size); + if (ret < 0 && ret != -EEXIST) { + dev_err(&pdev->dev, "unable to allocate smsm interrupt mask\n"); +- return ret; ++ goto out_put; + } + + intr_mask = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_SMSM_CPU_INTR_MASK, NULL); + if (IS_ERR(intr_mask)) { + dev_err(&pdev->dev, "unable to acquire shared memory interrupt mask\n"); +- return PTR_ERR(intr_mask); ++ ret = PTR_ERR(intr_mask); ++ goto out_put; + } + + /* Setup the reference to the local state bits */ +@@ -565,7 +567,8 @@ static int qcom_smsm_probe(struct platform_device *pdev) + smsm->state = qcom_smem_state_register(local_node, &smsm_state_ops, smsm); + if (IS_ERR(smsm->state)) { + dev_err(smsm->dev, "failed to register qcom_smem_state\n"); +- return PTR_ERR(smsm->state); ++ ret = PTR_ERR(smsm->state); ++ goto out_put; + } + + /* Register handlers for remote processor entries of interest. */ +@@ -595,16 +598,19 @@ static int qcom_smsm_probe(struct platform_device *pdev) + } + + platform_set_drvdata(pdev, smsm); ++ of_node_put(local_node); + + return 0; + + unwind_interfaces: ++ of_node_put(node); + for (id = 0; id < smsm->num_entries; id++) + if (smsm->entries[id].domain) + irq_domain_remove(smsm->entries[id].domain); + + qcom_smem_state_unregister(smsm->state); +- ++out_put: ++ of_node_put(local_node); + return ret; + } + +-- +2.35.3 + diff --git a/patches.suse/soc-sunxi-sram-Actually-claim-SRAM-regions.patch b/patches.suse/soc-sunxi-sram-Actually-claim-SRAM-regions.patch new file mode 100644 index 0000000..4a04ad7 --- /dev/null +++ b/patches.suse/soc-sunxi-sram-Actually-claim-SRAM-regions.patch @@ -0,0 +1,40 @@ +From fd362baad2e659ef0fb5652f023a606b248f1781 Mon Sep 17 00:00:00 2001 +From: Samuel Holland +Date: Sun, 14 Aug 2022 23:12:40 -0500 +Subject: [PATCH] soc: sunxi: sram: Actually claim SRAM regions +Git-commit: fd362baad2e659ef0fb5652f023a606b248f1781 +Patch-mainline: v6.0 +References: git-fixes + +sunxi_sram_claim() checks the sram_desc->claimed flag before updating +the register, with the intent that only one device can claim a region. +However, this was ineffective because the flag was never set. + +Fixes: 4af34b572a85 ("drivers: soc: sunxi: Introduce SoC driver to map SRAMs") +Reviewed-by: Jernej Skrabec +Signed-off-by: Samuel Holland +Reviewed-by: Heiko Stuebner +Tested-by: Heiko Stuebner +Signed-off-by: Jernej Skrabec +Link: https://lore.kernel.org/r/20220815041248.53268-4-samuel@sholland.org +Acked-by: Takashi Iwai + +--- + drivers/soc/sunxi/sunxi_sram.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c +index a8f3876963a0..f3d3f9259df9 100644 +--- a/drivers/soc/sunxi/sunxi_sram.c ++++ b/drivers/soc/sunxi/sunxi_sram.c +@@ -254,6 +254,7 @@ int sunxi_sram_claim(struct device *dev) + writel(val | ((device << sram_data->offset) & mask), + base + sram_data->reg); + ++ sram_desc->claimed = true; + spin_unlock(&sram_lock); + + return 0; +-- +2.35.3 + diff --git a/patches.suse/soc-sunxi-sram-Fix-debugfs-info-for-A64-SRAM-C.patch b/patches.suse/soc-sunxi-sram-Fix-debugfs-info-for-A64-SRAM-C.patch new file mode 100644 index 0000000..e5874d0 --- /dev/null +++ b/patches.suse/soc-sunxi-sram-Fix-debugfs-info-for-A64-SRAM-C.patch @@ -0,0 +1,40 @@ +From e3c95edb1bd8b9c2cb0caa6ae382fc8080f6a0ed Mon Sep 17 00:00:00 2001 +From: Samuel Holland +Date: Sun, 14 Aug 2022 23:12:43 -0500 +Subject: [PATCH] soc: sunxi: sram: Fix debugfs info for A64 SRAM C +Git-commit: e3c95edb1bd8b9c2cb0caa6ae382fc8080f6a0ed +Patch-mainline: v6.0 +References: git-fixes + +The labels were backward with respect to the register values. The SRAM +is mapped to the CPU when the register value is 1. + +Fixes: 5e4fb6429761 ("drivers: soc: sunxi: add support for A64 and its SRAM C") +Acked-by: Jernej Skrabec +Signed-off-by: Samuel Holland +Signed-off-by: Jernej Skrabec +Link: https://lore.kernel.org/r/20220815041248.53268-7-samuel@sholland.org +Acked-by: Takashi Iwai + +--- + drivers/soc/sunxi/sunxi_sram.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c +index 52d07bed7664..09754cd1d57d 100644 +--- a/drivers/soc/sunxi/sunxi_sram.c ++++ b/drivers/soc/sunxi/sunxi_sram.c +@@ -78,8 +78,8 @@ static struct sunxi_sram_desc sun4i_a10_sram_d = { + + static struct sunxi_sram_desc sun50i_a64_sram_c = { + .data = SUNXI_SRAM_DATA("C", 0x4, 24, 1, +- SUNXI_SRAM_MAP(0, 1, "cpu"), +- SUNXI_SRAM_MAP(1, 0, "de2")), ++ SUNXI_SRAM_MAP(1, 0, "cpu"), ++ SUNXI_SRAM_MAP(0, 1, "de2")), + }; + + static const struct of_device_id sunxi_sram_dt_ids[] = { +-- +2.35.3 + diff --git a/patches.suse/soc-sunxi-sram-Fix-probe-function-ordering-issues.patch b/patches.suse/soc-sunxi-sram-Fix-probe-function-ordering-issues.patch new file mode 100644 index 0000000..9f4d71b --- /dev/null +++ b/patches.suse/soc-sunxi-sram-Fix-probe-function-ordering-issues.patch @@ -0,0 +1,74 @@ +From 49fad91a7b8941979c3e9a35f9894ac45bc5d3d6 Mon Sep 17 00:00:00 2001 +From: Samuel Holland +Date: Sun, 14 Aug 2022 23:12:42 -0500 +Subject: [PATCH] soc: sunxi: sram: Fix probe function ordering issues +Git-commit: 49fad91a7b8941979c3e9a35f9894ac45bc5d3d6 +Patch-mainline: v6.0 +References: git-fixes + +Errors from debugfs are intended to be non-fatal, and should not prevent +the driver from probing. + +Since debugfs file creation is treated as infallible, move it below the +parts of the probe function that can fail. This prevents an error +elsewhere in the probe function from causing the file to leak. Do the +same for the call to of_platform_populate(). + +Finally, checkpatch suggests an octal literal for the file permissions. + +Fixes: 4af34b572a85 ("drivers: soc: sunxi: Introduce SoC driver to map SRAMs") +Fixes: 5828729bebbb ("soc: sunxi: export a regmap for EMAC clock reg on A64") +Reviewed-by: Jernej Skrabec +Signed-off-by: Samuel Holland +Tested-by: Heiko Stuebner +Signed-off-by: Jernej Skrabec +Link: https://lore.kernel.org/r/20220815041248.53268-6-samuel@sholland.org +Acked-by: Takashi Iwai + +--- + drivers/soc/sunxi/sunxi_sram.c | 13 +++++-------- + 1 file changed, 5 insertions(+), 8 deletions(-) + +diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c +index a858a37fcdd4..52d07bed7664 100644 +--- a/drivers/soc/sunxi/sunxi_sram.c ++++ b/drivers/soc/sunxi/sunxi_sram.c +@@ -332,9 +332,9 @@ static struct regmap_config sunxi_sram_emac_clock_regmap = { + + static int __init sunxi_sram_probe(struct platform_device *pdev) + { +- struct dentry *d; + struct regmap *emac_clock; + const struct sunxi_sramc_variant *variant; ++ struct device *dev = &pdev->dev; + + sram_dev = &pdev->dev; + +@@ -346,13 +346,6 @@ static int __init sunxi_sram_probe(struct platform_device *pdev) + if (IS_ERR(base)) + return PTR_ERR(base); + +- of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); +- +- d = debugfs_create_file("sram", S_IRUGO, NULL, NULL, +- &sunxi_sram_fops); +- if (!d) +- return -ENOMEM; +- + if (variant->num_emac_clocks > 0) { + emac_clock = devm_regmap_init_mmio(&pdev->dev, base, + &sunxi_sram_emac_clock_regmap); +@@ -361,6 +354,10 @@ static int __init sunxi_sram_probe(struct platform_device *pdev) + return PTR_ERR(emac_clock); + } + ++ of_platform_populate(dev->of_node, NULL, NULL, dev); ++ ++ debugfs_create_file("sram", 0444, NULL, NULL, &sunxi_sram_fops); ++ + return 0; + } + +-- +2.35.3 + diff --git a/patches.suse/soc-sunxi-sram-Prevent-the-driver-from-being-unbound.patch b/patches.suse/soc-sunxi-sram-Prevent-the-driver-from-being-unbound.patch new file mode 100644 index 0000000..c24bed7 --- /dev/null +++ b/patches.suse/soc-sunxi-sram-Prevent-the-driver-from-being-unbound.patch @@ -0,0 +1,48 @@ +From 90e10a1fcd9b24b4ba8c0d35136127473dcd829e Mon Sep 17 00:00:00 2001 +From: Samuel Holland +Date: Sun, 14 Aug 2022 23:12:41 -0500 +Subject: [PATCH] soc: sunxi: sram: Prevent the driver from being unbound +Git-commit: 90e10a1fcd9b24b4ba8c0d35136127473dcd829e +Patch-mainline: v6.0 +References: git-fixes + +This driver exports a regmap tied to the platform device (as opposed to +a syscon, which exports a regmap tied to the OF node). Because of this, +the driver can never be unbound, as that would destroy the regmap. Use +builtin_platform_driver_probe() to enforce this limitation. + +Fixes: 5828729bebbb ("soc: sunxi: export a regmap for EMAC clock reg on A64") +Reviewed-by: Jernej Skrabec +Signed-off-by: Samuel Holland +Reviewed-by: Heiko Stuebner +Tested-by: Heiko Stuebner +Signed-off-by: Jernej Skrabec +Link: https://lore.kernel.org/r/20220815041248.53268-5-samuel@sholland.org +Acked-by: Takashi Iwai + +--- + drivers/soc/sunxi/sunxi_sram.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/drivers/soc/sunxi/sunxi_sram.c ++++ b/drivers/soc/sunxi/sunxi_sram.c +@@ -330,7 +330,7 @@ static struct regmap_config sunxi_sram_e + .writeable_reg = sunxi_sram_regmap_accessible_reg, + }; + +-static int sunxi_sram_probe(struct platform_device *pdev) ++static int __init sunxi_sram_probe(struct platform_device *pdev) + { + struct dentry *d; + struct regmap *emac_clock; +@@ -410,9 +410,8 @@ static struct platform_driver sunxi_sram + .name = "sunxi-sram", + .of_match_table = sunxi_sram_dt_match, + }, +- .probe = sunxi_sram_probe, + }; +-module_platform_driver(sunxi_sram_driver); ++builtin_platform_driver_probe(sunxi_sram_driver, sunxi_sram_probe); + + MODULE_AUTHOR("Maxime Ripard "); + MODULE_DESCRIPTION("Allwinner sunXi SRAM Controller Driver"); diff --git a/patches.suse/soc-sunxi_sram-Make-use-of-the-helper-function-devm_.patch b/patches.suse/soc-sunxi_sram-Make-use-of-the-helper-function-devm_.patch new file mode 100644 index 0000000..6fa5b9a --- /dev/null +++ b/patches.suse/soc-sunxi_sram-Make-use-of-the-helper-function-devm_.patch @@ -0,0 +1,41 @@ +From 1f3753a5f042fea6539986f9caf2552877527d8a Mon Sep 17 00:00:00 2001 +From: Cai Huoqing +Date: Wed, 8 Sep 2021 15:17:15 +0800 +Subject: [PATCH] soc: sunxi_sram: Make use of the helper function devm_platform_ioremap_resource() +Git-commit: 1f3753a5f042fea6539986f9caf2552877527d8a +Patch-mainline: v5.16-rc1 +References: git-fixes + +Use the devm_platform_ioremap_resource() helper instead of +calling platform_get_resource() and devm_ioremap_resource() +separately + +Signed-off-by: Cai Huoqing +Signed-off-by: Maxime Ripard +Link: https://lore.kernel.org/r/20210908071716.772-1-caihuoqing@baidu.com +Acked-by: Takashi Iwai + +--- + drivers/soc/sunxi/sunxi_sram.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/drivers/soc/sunxi/sunxi_sram.c ++++ b/drivers/soc/sunxi/sunxi_sram.c +@@ -331,7 +331,6 @@ static struct regmap_config sunxi_sram_e + + static int sunxi_sram_probe(struct platform_device *pdev) + { +- struct resource *res; + struct dentry *d; + struct regmap *emac_clock; + const struct sunxi_sramc_variant *variant; +@@ -342,8 +341,7 @@ static int sunxi_sram_probe(struct platf + if (!variant) + return -EINVAL; + +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- base = devm_ioremap_resource(&pdev->dev, res); ++ base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + diff --git a/patches.suse/spi-Add-API-to-count-spi-acpi-resources.patch b/patches.suse/spi-Add-API-to-count-spi-acpi-resources.patch new file mode 100644 index 0000000..6df54bb --- /dev/null +++ b/patches.suse/spi-Add-API-to-count-spi-acpi-resources.patch @@ -0,0 +1,89 @@ +From e612af7acef2459f1afd885f4107748995a05963 Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Fri, 21 Jan 2022 17:24:26 +0000 +Subject: [PATCH] spi: Add API to count spi acpi resources +Git-commit: e612af7acef2459f1afd885f4107748995a05963 +Patch-mainline: v5.18-rc1 +References: bsc#1203699 + +Some ACPI nodes may have more than one Spi Resource. +To be able to handle these case, its necessary to have +a way of counting these resources. + +Signed-off-by: Stefan Binding +Reviewed-by: Hans de Goede +Link: https://lore.kernel.org/r/20220121172431.6876-5-sbinding@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + drivers/spi/spi.c | 40 ++++++++++++++++++++++++++++++++++++++++ + include/linux/spi/spi.h | 1 + + 2 files changed, 41 insertions(+) + +diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c +index 06c0a308b38b..ec9f2ed579e3 100644 +--- a/drivers/spi/spi.c ++++ b/drivers/spi/spi.c +@@ -2324,6 +2324,46 @@ struct acpi_spi_lookup { + int index; + }; + ++static int acpi_spi_count(struct acpi_resource *ares, void *data) ++{ ++ struct acpi_resource_spi_serialbus *sb; ++ int *count = data; ++ ++ if (ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS) ++ return 1; ++ ++ sb = &ares->data.spi_serial_bus; ++ if (sb->type != ACPI_RESOURCE_SERIAL_TYPE_SPI) ++ return 1; ++ ++ *count = *count + 1; ++ ++ return 1; ++} ++ ++/** ++ * acpi_spi_count_resources - Count the number of SpiSerialBus resources ++ * @adev: ACPI device ++ * ++ * Returns the number of SpiSerialBus resources in the ACPI-device's ++ * resource-list; or a negative error code. ++ */ ++int acpi_spi_count_resources(struct acpi_device *adev) ++{ ++ LIST_HEAD(r); ++ int count = 0; ++ int ret; ++ ++ ret = acpi_dev_get_resources(adev, &r, acpi_spi_count, &count); ++ if (ret < 0) ++ return ret; ++ ++ acpi_dev_free_resource_list(&r); ++ ++ return count; ++} ++EXPORT_SYMBOL_GPL(acpi_spi_count_resources); ++ + static void acpi_spi_parse_apple_properties(struct acpi_device *dev, + struct acpi_spi_lookup *lookup) + { +diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h +index e5bbb9cbd3d7..394b4241d989 100644 +--- a/include/linux/spi/spi.h ++++ b/include/linux/spi/spi.h +@@ -764,6 +764,7 @@ extern void spi_unregister_controller(struct spi_controller *ctlr); + extern struct spi_device *acpi_spi_device_alloc(struct spi_controller *ctlr, + struct acpi_device *adev, + int index); ++int acpi_spi_count_resources(struct acpi_device *adev); + #endif + + /* +-- +2.35.3 + diff --git a/patches.suse/spi-Create-helper-API-to-lookup-ACPI-info-for-spi-de.patch b/patches.suse/spi-Create-helper-API-to-lookup-ACPI-info-for-spi-de.patch new file mode 100644 index 0000000..2413864 --- /dev/null +++ b/patches.suse/spi-Create-helper-API-to-lookup-ACPI-info-for-spi-de.patch @@ -0,0 +1,134 @@ +From 000bee0ed70af79e610444096fb453430220960f Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Fri, 21 Jan 2022 17:24:24 +0000 +Subject: [PATCH] spi: Create helper API to lookup ACPI info for spi device +Git-commit: 000bee0ed70af79e610444096fb453430220960f +Patch-mainline: v5.18-rc1 +References: bsc#1203699 + +This can then be used to find a spi resource inside an +ACPI node, and allocate a spi device. + +Signed-off-by: Stefan Binding +Reviewed-by: Hans de Goede +Link: https://lore.kernel.org/r/20220121172431.6876-3-sbinding@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + drivers/spi/spi.c | 46 ++++++++++++++++++++++++++++++++++++---------- + include/linux/spi/spi.h | 6 ++++++ + 2 files changed, 42 insertions(+), 10 deletions(-) + +--- a/drivers/spi/spi.c ++++ b/drivers/spi/spi.c +@@ -2335,8 +2335,18 @@ static int acpi_spi_add_resource(struct + return 1; + } + +-static acpi_status acpi_register_spi_device(struct spi_controller *ctlr, +- struct acpi_device *adev) ++/** ++ * acpi_spi_device_alloc - Allocate a spi device, and fill it in with ACPI information ++ * @ctlr: controller to which the spi device belongs ++ * @adev: ACPI Device for the spi device ++ * ++ * This should be used to allocate a new spi device from and ACPI Node. ++ * The caller is responsible for calling spi_add_device to register the spi device. ++ * ++ * Return: a pointer to the new device, or ERR_PTR on error. ++ */ ++struct spi_device *acpi_spi_device_alloc(struct spi_controller *ctlr, ++ struct acpi_device *adev) + { + acpi_handle parent_handle = NULL; + struct list_head resource_list; +@@ -2344,10 +2354,6 @@ static acpi_status acpi_register_spi_dev + struct spi_device *spi; + int ret; + +- if (acpi_bus_get_status(adev) || !adev->status.present || +- acpi_device_enumerated(adev)) +- return AE_OK; +- + lookup.ctlr = ctlr; + lookup.irq = -1; + +@@ -2358,7 +2364,7 @@ static acpi_status acpi_register_spi_dev + + if (ret < 0) + /* found SPI in _CRS but it points to another controller */ +- return AE_OK; ++ return ERR_PTR(-ENODEV); + + if (!lookup.max_speed_hz && + ACPI_SUCCESS(acpi_get_parent(adev->handle, &parent_handle)) && +@@ -2368,16 +2374,15 @@ static acpi_status acpi_register_spi_dev + } + + if (!lookup.max_speed_hz) +- return AE_OK; ++ return ERR_PTR(-ENODEV); + + spi = spi_alloc_device(ctlr); + if (!spi) { + dev_err(&ctlr->dev, "failed to allocate SPI device for %s\n", + dev_name(&adev->dev)); +- return AE_NO_MEMORY; ++ return ERR_PTR(-ENOMEM); + } + +- + ACPI_COMPANION_SET(&spi->dev, adev); + spi->max_speed_hz = lookup.max_speed_hz; + spi->mode |= lookup.mode; +@@ -2385,6 +2390,27 @@ static acpi_status acpi_register_spi_dev + spi->bits_per_word = lookup.bits_per_word; + spi->chip_select = lookup.chip_select; + ++ return spi; ++} ++EXPORT_SYMBOL_GPL(acpi_spi_device_alloc); ++ ++static acpi_status acpi_register_spi_device(struct spi_controller *ctlr, ++ struct acpi_device *adev) ++{ ++ struct spi_device *spi; ++ ++ if (acpi_bus_get_status(adev) || !adev->status.present || ++ acpi_device_enumerated(adev)) ++ return AE_OK; ++ ++ spi = acpi_spi_device_alloc(ctlr, adev); ++ if (IS_ERR(spi)) { ++ if (PTR_ERR(spi) == -ENOMEM) ++ return AE_NO_MEMORY; ++ else ++ return AE_OK; ++ } ++ + acpi_set_modalias(adev, acpi_device_hid(adev), spi->modalias, + sizeof(spi->modalias)); + +--- a/include/linux/spi/spi.h ++++ b/include/linux/spi/spi.h +@@ -17,6 +17,7 @@ + #include + + #include ++#include + + struct dma_chan; + struct software_node; +@@ -768,6 +769,11 @@ extern void spi_unregister_controller(st + + extern struct spi_controller *spi_busnum_to_master(u16 busnum); + ++#if IS_ENABLED(CONFIG_ACPI) ++extern struct spi_device *acpi_spi_device_alloc(struct spi_controller *ctlr, ++ struct acpi_device *adev); ++#endif ++ + /* + * SPI resource management while processing a SPI message + */ diff --git a/patches.suse/spi-Return-deferred-probe-error-when-controller-isn-.patch b/patches.suse/spi-Return-deferred-probe-error-when-controller-isn-.patch new file mode 100644 index 0000000..b39c4cc --- /dev/null +++ b/patches.suse/spi-Return-deferred-probe-error-when-controller-isn-.patch @@ -0,0 +1,39 @@ +From 9c22ec4ac27bcc5a54dd406da168f403327a5b55 Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Sun, 10 Jul 2022 00:29:56 +0300 +Subject: [PATCH] spi: Return deferred probe error when controller isn't yet available +Git-commit: 9c22ec4ac27bcc5a54dd406da168f403327a5b55 +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +If the controller is not available, it might be in the future and +we would like to re-probe the peripheral again. For that purpose +return deferred probe. + +Buglink: https://bugzilla.kernel.org/show_bug.cgi?id=215993 +Fixes: 87e59b36e5e2 ("spi: Support selection of the index of the ACPI Spi Resource before alloc") +Signed-off-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20220709212956.25530-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + drivers/spi/spi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c +index ebc47f63239f..2ec508ad8c2b 100644 +--- a/drivers/spi/spi.c ++++ b/drivers/spi/spi.c +@@ -2475,7 +2475,7 @@ static int acpi_spi_add_resource(struct acpi_resource *ares, void *data) + + ctlr = acpi_spi_find_controller_by_adev(adev); + if (!ctlr) +- return -ENODEV; ++ return -EPROBE_DEFER; + + lookup->ctlr = ctlr; + } +-- +2.35.3 + diff --git a/patches.suse/spi-Support-selection-of-the-index-of-the-ACPI-Spi-R.patch b/patches.suse/spi-Support-selection-of-the-index-of-the-ACPI-Spi-R.patch new file mode 100644 index 0000000..964d194 --- /dev/null +++ b/patches.suse/spi-Support-selection-of-the-index-of-the-ACPI-Spi-R.patch @@ -0,0 +1,166 @@ +From 87e59b36e5e26122efd55d77adb9fac827987db0 Mon Sep 17 00:00:00 2001 +From: Stefan Binding +Date: Fri, 21 Jan 2022 17:24:25 +0000 +Subject: [PATCH] spi: Support selection of the index of the ACPI Spi Resource before alloc +Git-commit: 87e59b36e5e26122efd55d77adb9fac827987db0 +Patch-mainline: v5.18-rc1 +References: bsc#1203699 + +If a node contains more than one SPI resource it may be necessary to +use an index to select which one you want to allocate a spi device for. + +Signed-off-by: Stefan Binding +Reviewed-by: Hans de Goede +Link: https://lore.kernel.org/r/20220121172431.6876-4-sbinding@opensource.cirrus.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + drivers/spi/spi.c | 51 +++++++++++++++++++++++++++++++++++------ + include/linux/spi/spi.h | 3 ++- + 2 files changed, 46 insertions(+), 8 deletions(-) + +diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c +index 13f4701f0694..06c0a308b38b 100644 +--- a/drivers/spi/spi.c ++++ b/drivers/spi/spi.c +@@ -2320,6 +2320,8 @@ struct acpi_spi_lookup { + int irq; + u8 bits_per_word; + u8 chip_select; ++ int n; ++ int index; + }; + + static void acpi_spi_parse_apple_properties(struct acpi_device *dev, +@@ -2351,6 +2353,8 @@ static void acpi_spi_parse_apple_properties(struct acpi_device *dev, + lookup->mode |= SPI_CPHA; + } + ++static struct spi_controller *acpi_spi_find_controller_by_adev(struct acpi_device *adev); ++ + static int acpi_spi_add_resource(struct acpi_resource *ares, void *data) + { + struct acpi_spi_lookup *lookup = data; +@@ -2364,14 +2368,35 @@ static int acpi_spi_add_resource(struct acpi_resource *ares, void *data) + sb = &ares->data.spi_serial_bus; + if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_SPI) { + ++ if (lookup->index != -1 && lookup->n++ != lookup->index) ++ return 1; ++ ++ if (lookup->index == -1 && !ctlr) ++ return -ENODEV; ++ + status = acpi_get_handle(NULL, + sb->resource_source.string_ptr, + &parent_handle); + +- if (ACPI_FAILURE(status) || +- ACPI_HANDLE(ctlr->dev.parent) != parent_handle) ++ if (ACPI_FAILURE(status)) + return -ENODEV; + ++ if (ctlr) { ++ if (ACPI_HANDLE(ctlr->dev.parent) != parent_handle) ++ return -ENODEV; ++ } else { ++ struct acpi_device *adev; ++ ++ if (acpi_bus_get_device(parent_handle, &adev)) ++ return -ENODEV; ++ ++ ctlr = acpi_spi_find_controller_by_adev(adev); ++ if (!ctlr) ++ return -ENODEV; ++ ++ lookup->ctlr = ctlr; ++ } ++ + /* + * ACPI DeviceSelection numbering is handled by the + * host controller driver in Windows and can vary +@@ -2414,14 +2439,21 @@ static int acpi_spi_add_resource(struct acpi_resource *ares, void *data) + * acpi_spi_device_alloc - Allocate a spi device, and fill it in with ACPI information + * @ctlr: controller to which the spi device belongs + * @adev: ACPI Device for the spi device ++ * @index: Index of the spi resource inside the ACPI Node + * + * This should be used to allocate a new spi device from and ACPI Node. + * The caller is responsible for calling spi_add_device to register the spi device. + * ++ * If ctlr is set to NULL, the Controller for the spi device will be looked up ++ * using the resource. ++ * If index is set to -1, index is not used. ++ * Note: If index is -1, ctlr must be set. ++ * + * Return: a pointer to the new device, or ERR_PTR on error. + */ + struct spi_device *acpi_spi_device_alloc(struct spi_controller *ctlr, +- struct acpi_device *adev) ++ struct acpi_device *adev, ++ int index) + { + acpi_handle parent_handle = NULL; + struct list_head resource_list; +@@ -2429,8 +2461,13 @@ struct spi_device *acpi_spi_device_alloc(struct spi_controller *ctlr, + struct spi_device *spi; + int ret; + ++ if (!ctlr && index == -1) ++ return ERR_PTR(-EINVAL); ++ + lookup.ctlr = ctlr; + lookup.irq = -1; ++ lookup.index = index; ++ lookup.n = 0; + + INIT_LIST_HEAD(&resource_list); + ret = acpi_dev_get_resources(adev, &resource_list, +@@ -2443,7 +2480,7 @@ struct spi_device *acpi_spi_device_alloc(struct spi_controller *ctlr, + + if (!lookup.max_speed_hz && + ACPI_SUCCESS(acpi_get_parent(adev->handle, &parent_handle)) && +- ACPI_HANDLE(ctlr->dev.parent) == parent_handle) { ++ ACPI_HANDLE(lookup.ctlr->dev.parent) == parent_handle) { + /* Apple does not use _CRS but nested devices for SPI slaves */ + acpi_spi_parse_apple_properties(adev, &lookup); + } +@@ -2451,9 +2488,9 @@ struct spi_device *acpi_spi_device_alloc(struct spi_controller *ctlr, + if (!lookup.max_speed_hz) + return ERR_PTR(-ENODEV); + +- spi = spi_alloc_device(ctlr); ++ spi = spi_alloc_device(lookup.ctlr); + if (!spi) { +- dev_err(&ctlr->dev, "failed to allocate SPI device for %s\n", ++ dev_err(&lookup.ctlr->dev, "failed to allocate SPI device for %s\n", + dev_name(&adev->dev)); + return ERR_PTR(-ENOMEM); + } +@@ -2478,7 +2515,7 @@ static acpi_status acpi_register_spi_device(struct spi_controller *ctlr, + acpi_device_enumerated(adev)) + return AE_OK; + +- spi = acpi_spi_device_alloc(ctlr, adev); ++ spi = acpi_spi_device_alloc(ctlr, adev, -1); + if (IS_ERR(spi)) { + if (PTR_ERR(spi) == -ENOMEM) + return AE_NO_MEMORY; +diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h +index d159cef12f1a..e5bbb9cbd3d7 100644 +--- a/include/linux/spi/spi.h ++++ b/include/linux/spi/spi.h +@@ -762,7 +762,8 @@ extern void spi_unregister_controller(struct spi_controller *ctlr); + + #if IS_ENABLED(CONFIG_ACPI) + extern struct spi_device *acpi_spi_device_alloc(struct spi_controller *ctlr, +- struct acpi_device *adev); ++ struct acpi_device *adev, ++ int index); + #endif + + /* +-- +2.35.3 + diff --git a/patches.suse/spi-dw-Fix-PM-disable-depth-imbalance-in-dw_spi_bt1_.patch b/patches.suse/spi-dw-Fix-PM-disable-depth-imbalance-in-dw_spi_bt1_.patch new file mode 100644 index 0000000..4f30fec --- /dev/null +++ b/patches.suse/spi-dw-Fix-PM-disable-depth-imbalance-in-dw_spi_bt1_.patch @@ -0,0 +1,42 @@ +From 618d815fc93477b1675878f3c04ff32657cc18b4 Mon Sep 17 00:00:00 2001 +From: Zhang Qilong +Date: Sat, 24 Sep 2022 20:13:08 +0800 +Subject: [PATCH] spi: dw: Fix PM disable depth imbalance in dw_spi_bt1_probe +Git-commit: 618d815fc93477b1675878f3c04ff32657cc18b4 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The pm_runtime_enable will increase power disable depth. Thus +a pairing decrement is needed on the error handling path to +keep it balanced according to context. + +Fixes:abf00907538e2 ("spi: dw: Add Baikal-T1 SPI Controller glue driver") + +Signed-off-by: Zhang Qilong +Link: https://lore.kernel.org/r/20220924121310.78331-3-zhangqilong3@huawei.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + drivers/spi/spi-dw-bt1.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/spi/spi-dw-bt1.c b/drivers/spi/spi-dw-bt1.c +index c06553416123..3fb89dee595e 100644 +--- a/drivers/spi/spi-dw-bt1.c ++++ b/drivers/spi/spi-dw-bt1.c +@@ -293,8 +293,10 @@ static int dw_spi_bt1_probe(struct platform_device *pdev) + pm_runtime_enable(&pdev->dev); + + ret = dw_spi_add_host(&pdev->dev, dws); +- if (ret) ++ if (ret) { ++ pm_runtime_disable(&pdev->dev); + goto err_disable_clk; ++ } + + platform_set_drvdata(pdev, dwsbt1); + +-- +2.35.3 + diff --git a/patches.suse/spi-meson-spicc-do-not-rely-on-busy-flag-in-pow2-clk.patch b/patches.suse/spi-meson-spicc-do-not-rely-on-busy-flag-in-pow2-clk.patch new file mode 100644 index 0000000..a80fa36 --- /dev/null +++ b/patches.suse/spi-meson-spicc-do-not-rely-on-busy-flag-in-pow2-clk.patch @@ -0,0 +1,66 @@ +From 36acf80fc0c4b5ebe6fa010b524d442ee7f08fd3 Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Thu, 8 Sep 2022 14:18:03 +0200 +Subject: [PATCH] spi: meson-spicc: do not rely on busy flag in pow2 clk ops +Git-commit: 36acf80fc0c4b5ebe6fa010b524d442ee7f08fd3 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Since [1], controller's busy flag isn't set anymore when the +__spi_transfer_message_noqueue() is used instead of the +__spi_pump_transfer_message() logic for spi_sync transfers. + +Since the pow2 clock ops were limited to only be available when a +transfer is ongoing (between prepare_transfer_hardware and +unprepare_transfer_hardware callbacks), the only way to track this +down is to check for the controller cur_msg. + +[1] ae7d2346dc89 ("spi: Don't use the message queue if possible in spi_sync") + +Fixes: 09992025dacd ("spi: meson-spicc: add local pow2 clock ops to preserve rate between messages") +Fixes: ae7d2346dc89 ("spi: Don't use the message queue if possible in spi_sync") +Reported-by: Markus Schneider-Pargmann +Signed-off-by: Neil Armstrong +Tested-by: Markus Schneider-Pargmann +Link: https://lore.kernel.org/r/20220908121803.919943-1-narmstrong@baylibre.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + drivers/spi/spi-meson-spicc.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/spi/spi-meson-spicc.c b/drivers/spi/spi-meson-spicc.c +index e4cb52e1fe26..6974a1c947aa 100644 +--- a/drivers/spi/spi-meson-spicc.c ++++ b/drivers/spi/spi-meson-spicc.c +@@ -537,7 +537,7 @@ static unsigned long meson_spicc_pow2_recalc_rate(struct clk_hw *hw, + struct clk_divider *divider = to_clk_divider(hw); + struct meson_spicc_device *spicc = pow2_clk_to_spicc(divider); + +- if (!spicc->master->cur_msg || !spicc->master->busy) ++ if (!spicc->master->cur_msg) + return 0; + + return clk_divider_ops.recalc_rate(hw, parent_rate); +@@ -549,7 +549,7 @@ static int meson_spicc_pow2_determine_rate(struct clk_hw *hw, + struct clk_divider *divider = to_clk_divider(hw); + struct meson_spicc_device *spicc = pow2_clk_to_spicc(divider); + +- if (!spicc->master->cur_msg || !spicc->master->busy) ++ if (!spicc->master->cur_msg) + return -EINVAL; + + return clk_divider_ops.determine_rate(hw, req); +@@ -561,7 +561,7 @@ static int meson_spicc_pow2_set_rate(struct clk_hw *hw, unsigned long rate, + struct clk_divider *divider = to_clk_divider(hw); + struct meson_spicc_device *spicc = pow2_clk_to_spicc(divider); + +- if (!spicc->master->cur_msg || !spicc->master->busy) ++ if (!spicc->master->cur_msg) + return -EINVAL; + + return clk_divider_ops.set_rate(hw, rate, parent_rate); +-- +2.35.3 + diff --git a/patches.suse/spi-mt7621-Fix-an-error-message-in-mt7621_spi_probe.patch b/patches.suse/spi-mt7621-Fix-an-error-message-in-mt7621_spi_probe.patch new file mode 100644 index 0000000..e8fc261 --- /dev/null +++ b/patches.suse/spi-mt7621-Fix-an-error-message-in-mt7621_spi_probe.patch @@ -0,0 +1,48 @@ +From 2b2bf6b7faa9010fae10dc7de76627a3fdb525b3 Mon Sep 17 00:00:00 2001 +From: Christophe JAILLET +Date: Sat, 27 Aug 2022 13:42:07 +0200 +Subject: [PATCH] spi: mt7621: Fix an error message in mt7621_spi_probe() +Git-commit: 2b2bf6b7faa9010fae10dc7de76627a3fdb525b3 +Patch-mainline: v6.1-rc1 +References: git-fixes + +'status' is known to be 0 at this point. The expected error code is +PTR_ERR(clk). + +Switch to dev_err_probe() in order to display the expected error code (in a +human readable way). +This also filters -EPROBE_DEFER cases, should it happen. + +Fixes: 1ab7f2a43558 ("staging: mt7621-spi: add mt7621 support") +Signed-off-by: Christophe JAILLET +Reviewed-by: Matthias Brugger +Link: https://lore.kernel.org/r/928f3fb507d53ba0774df27cea0bbba4b055993b.1661599671.git.christophe.jaillet@wanadoo.fr +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + drivers/spi/spi-mt7621.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/drivers/spi/spi-mt7621.c b/drivers/spi/spi-mt7621.c +index b4b9b7309b5e..351b0ef52bbc 100644 +--- a/drivers/spi/spi-mt7621.c ++++ b/drivers/spi/spi-mt7621.c +@@ -340,11 +340,9 @@ static int mt7621_spi_probe(struct platform_device *pdev) + return PTR_ERR(base); + + clk = devm_clk_get(&pdev->dev, NULL); +- if (IS_ERR(clk)) { +- dev_err(&pdev->dev, "unable to get SYS clock, err=%d\n", +- status); +- return PTR_ERR(clk); +- } ++ if (IS_ERR(clk)) ++ return dev_err_probe(&pdev->dev, PTR_ERR(clk), ++ "unable to get SYS clock\n"); + + status = clk_prepare_enable(clk); + if (status) +-- +2.35.3 + diff --git a/patches.suse/spi-omap100k-Fix-PM-disable-depth-imbalance-in-omap1.patch b/patches.suse/spi-omap100k-Fix-PM-disable-depth-imbalance-in-omap1.patch new file mode 100644 index 0000000..cf133d2 --- /dev/null +++ b/patches.suse/spi-omap100k-Fix-PM-disable-depth-imbalance-in-omap1.patch @@ -0,0 +1,38 @@ +From 29f65f2171c85a9633daa380df14009a365f42f2 Mon Sep 17 00:00:00 2001 +From: Zhang Qilong +Date: Sat, 24 Sep 2022 20:13:09 +0800 +Subject: [PATCH] spi/omap100k:Fix PM disable depth imbalance in omap1_spi100k_probe +Git-commit: 29f65f2171c85a9633daa380df14009a365f42f2 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The pm_runtime_enable will increase power disable depth. Thus +a pairing decrement is needed on the error handling path to +keep it balanced according to context. + +Fixes:db91841b58f9a ("spi/omap100k: Convert to runtime PM") + +Signed-off-by: Zhang Qilong +Link: https://lore.kernel.org/r/20220924121310.78331-4-zhangqilong3@huawei.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + drivers/spi/spi-omap-100k.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/spi/spi-omap-100k.c b/drivers/spi/spi-omap-100k.c +index 20b047172965..061f7394e5b9 100644 +--- a/drivers/spi/spi-omap-100k.c ++++ b/drivers/spi/spi-omap-100k.c +@@ -412,6 +412,7 @@ static int omap1_spi100k_probe(struct platform_device *pdev) + return status; + + err_fck: ++ pm_runtime_disable(&pdev->dev); + clk_disable_unprepare(spi100k->fck); + err_ick: + clk_disable_unprepare(spi100k->ick); +-- +2.35.3 + diff --git a/patches.suse/spi-propagate-error-code-to-the-caller-of-acpi_spi_d.patch b/patches.suse/spi-propagate-error-code-to-the-caller-of-acpi_spi_d.patch new file mode 100644 index 0000000..e18cbc3 --- /dev/null +++ b/patches.suse/spi-propagate-error-code-to-the-caller-of-acpi_spi_d.patch @@ -0,0 +1,34 @@ +From b6747f4fba399a73a87fac80ac1d0c952a44b222 Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Sat, 9 Jul 2022 03:07:08 +0300 +Subject: [PATCH] spi: propagate error code to the caller of acpi_spi_device_alloc() +Git-commit: b6747f4fba399a73a87fac80ac1d0c952a44b222 +Patch-mainline: v6.0-rc1 +References: bsc#1203699 + +Since acpi_spi_device_alloc() has been designed to return an error +pointer we may now properly propagate error codes to the caller of +it. It helps debugging a lot. + +Signed-off-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20220709000709.35622-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + drivers/spi/spi.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/spi/spi.c ++++ b/drivers/spi/spi.c +@@ -2440,8 +2440,8 @@ struct spi_device *acpi_spi_device_alloc + acpi_dev_free_resource_list(&resource_list); + + if (ret < 0) +- /* found SPI in _CRS but it points to another controller */ +- return ERR_PTR(-ENODEV); ++ /* Found SPI in _CRS but it points to another controller */ ++ return ERR_PTR(ret); + + if (!lookup.max_speed_hz && + ACPI_SUCCESS(acpi_get_parent(adev->handle, &parent_handle)) && diff --git a/patches.suse/spi-pxa2xx-Add-support-for-Intel-Meteor-Lake-P.patch b/patches.suse/spi-pxa2xx-Add-support-for-Intel-Meteor-Lake-P.patch new file mode 100644 index 0000000..b2e533e --- /dev/null +++ b/patches.suse/spi-pxa2xx-Add-support-for-Intel-Meteor-Lake-P.patch @@ -0,0 +1,42 @@ +From 3190d4be3764fd847d57e26197158940e89272ae Mon Sep 17 00:00:00 2001 +From: Jarkko Nikula +Date: Thu, 30 Jun 2022 10:33:05 +0300 +Subject: [PATCH] spi: pxa2xx: Add support for Intel Meteor Lake-P +Git-commit: 3190d4be3764fd847d57e26197158940e89272ae +Patch-mainline: v6.0-rc1 +References: jsc#PED-732 + +Add support for LPSS SPI on Intel Meteor Lake-P. It has three +controllers each having two chip selects. + +This squashes a fix from Ap, Kamal fixing incorrect +PCI ID of 3rd controller. + +Signed-off-by: Jarkko Nikula +Reviewed-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20220630073305.632850-1-jarkko.nikula@linux.intel.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + drivers/spi/spi-pxa2xx.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c +index edb42d08857d..838d12e65144 100644 +--- a/drivers/spi/spi-pxa2xx.c ++++ b/drivers/spi/spi-pxa2xx.c +@@ -1404,6 +1404,10 @@ static const struct pci_device_id pxa2xx_spi_pci_compound_match[] = { + { PCI_VDEVICE(INTEL, 0x7aab), LPSS_CNL_SSP }, + { PCI_VDEVICE(INTEL, 0x7af9), LPSS_CNL_SSP }, + { PCI_VDEVICE(INTEL, 0x7afb), LPSS_CNL_SSP }, ++ /* MTL-P */ ++ { PCI_VDEVICE(INTEL, 0x7e27), LPSS_CNL_SSP }, ++ { PCI_VDEVICE(INTEL, 0x7e30), LPSS_CNL_SSP }, ++ { PCI_VDEVICE(INTEL, 0x7e46), LPSS_CNL_SSP }, + /* CNL-LP */ + { PCI_VDEVICE(INTEL, 0x9daa), LPSS_CNL_SSP }, + { PCI_VDEVICE(INTEL, 0x9dab), LPSS_CNL_SSP }, +-- +2.35.3 + diff --git a/patches.suse/spi-pxa2xx-Add-support-for-Intel-Raptor-Lake-PCH-S.patch b/patches.suse/spi-pxa2xx-Add-support-for-Intel-Raptor-Lake-PCH-S.patch new file mode 100644 index 0000000..241cb88 --- /dev/null +++ b/patches.suse/spi-pxa2xx-Add-support-for-Intel-Raptor-Lake-PCH-S.patch @@ -0,0 +1,39 @@ +From 54d0fd06e2bd52d3b17648de787157a7c0625adb Mon Sep 17 00:00:00 2001 +From: Jarkko Nikula +Date: Wed, 16 Feb 2022 11:13:17 +0200 +Subject: [PATCH] spi: pxa2xx: Add support for Intel Raptor Lake PCH-S +Git-commit: 54d0fd06e2bd52d3b17648de787157a7c0625adb +Patch-mainline: v5.18-rc1 +References: jsc#PED-634 + +Add support for LPSS SPI on Intel Raptor Lake PCH-S. It has four +controllers each having two chip selects. + +Signed-off-by: Jarkko Nikula +Link: https://lore.kernel.org/r/20220216091317.1302254-1-jarkko.nikula@linux.intel.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + drivers/spi/spi-pxa2xx.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c +index abb9f0ffd377..edb42d08857d 100644 +--- a/drivers/spi/spi-pxa2xx.c ++++ b/drivers/spi/spi-pxa2xx.c +@@ -1394,6 +1394,11 @@ static const struct pci_device_id pxa2xx_spi_pci_compound_match[] = { + { PCI_VDEVICE(INTEL, 0x5ac2), LPSS_BXT_SSP }, + { PCI_VDEVICE(INTEL, 0x5ac4), LPSS_BXT_SSP }, + { PCI_VDEVICE(INTEL, 0x5ac6), LPSS_BXT_SSP }, ++ /* RPL-S */ ++ { PCI_VDEVICE(INTEL, 0x7a2a), LPSS_CNL_SSP }, ++ { PCI_VDEVICE(INTEL, 0x7a2b), LPSS_CNL_SSP }, ++ { PCI_VDEVICE(INTEL, 0x7a79), LPSS_CNL_SSP }, ++ { PCI_VDEVICE(INTEL, 0x7a7b), LPSS_CNL_SSP }, + /* ADL-S */ + { PCI_VDEVICE(INTEL, 0x7aaa), LPSS_CNL_SSP }, + { PCI_VDEVICE(INTEL, 0x7aab), LPSS_CNL_SSP }, +-- +2.35.3 + diff --git a/patches.suse/spi-qup-add-missing-clk_disable_unprepare-on-error-i-494a22765ce4.patch b/patches.suse/spi-qup-add-missing-clk_disable_unprepare-on-error-i-494a22765ce4.patch new file mode 100644 index 0000000..b98c8df --- /dev/null +++ b/patches.suse/spi-qup-add-missing-clk_disable_unprepare-on-error-i-494a22765ce4.patch @@ -0,0 +1,43 @@ +From 494a22765ce479c9f8ad181c5d24cffda9f534bb Mon Sep 17 00:00:00 2001 +From: Xu Qiang +Date: Thu, 25 Aug 2022 06:53:24 +0000 +Subject: [PATCH] spi: qup: add missing clk_disable_unprepare on error in spi_qup_pm_resume_runtime() +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 494a22765ce479c9f8ad181c5d24cffda9f534bb +Patch-mainline: v6.1-rc1 +References: git-fixes + +Add the missing clk_disable_unprepare() before return +from spi_qup_pm_resume_runtime() in the error handling case. + +Fixes: dae1a7700b34 (“spi: qup: Handle clocks in pm_runtime suspend and resume”) +Signed-off-by: Xu Qiang +Link: https://lore.kernel.org/r/20220825065324.68446-2-xuqiang36@huawei.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + drivers/spi/spi-qup.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c +index ae4e67f152ec..7d89510dc3f0 100644 +--- a/drivers/spi/spi-qup.c ++++ b/drivers/spi/spi-qup.c +@@ -1198,8 +1198,10 @@ static int spi_qup_pm_resume_runtime(struct device *device) + return ret; + + ret = clk_prepare_enable(controller->cclk); +- if (ret) ++ if (ret) { ++ clk_disable_unprepare(controller->iclk); + return ret; ++ } + + /* Disable clocks auto gaiting */ + config = readl_relaxed(controller->base + QUP_CONFIG); +-- +2.35.3 + diff --git a/patches.suse/spi-qup-add-missing-clk_disable_unprepare-on-error-i.patch b/patches.suse/spi-qup-add-missing-clk_disable_unprepare-on-error-i.patch new file mode 100644 index 0000000..e846954 --- /dev/null +++ b/patches.suse/spi-qup-add-missing-clk_disable_unprepare-on-error-i.patch @@ -0,0 +1,60 @@ +From 70034320fdc597b8f58b4a43bb547f17c4c5557a Mon Sep 17 00:00:00 2001 +From: Xu Qiang +Date: Thu, 25 Aug 2022 06:53:23 +0000 +Subject: [PATCH] spi: qup: add missing clk_disable_unprepare on error in spi_qup_resume() +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 70034320fdc597b8f58b4a43bb547f17c4c5557a +Patch-mainline: v6.1-rc1 +References: git-fixes + +Add the missing clk_disable_unprepare() before return +from spi_qup_resume() in the error handling case. + +Fixes: 64ff247a978f (“spi: Add Qualcomm QUP SPI controller support”) +Signed-off-by: Xu Qiang +Link: https://lore.kernel.org/r/20220825065324.68446-1-xuqiang36@huawei.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + drivers/spi/spi-qup.c | 17 ++++++++++++++--- + 1 file changed, 14 insertions(+), 3 deletions(-) + +diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c +index 00d6084306b4..ae4e67f152ec 100644 +--- a/drivers/spi/spi-qup.c ++++ b/drivers/spi/spi-qup.c +@@ -1245,14 +1245,25 @@ static int spi_qup_resume(struct device *device) + return ret; + + ret = clk_prepare_enable(controller->cclk); +- if (ret) ++ if (ret) { ++ clk_disable_unprepare(controller->iclk); + return ret; ++ } + + ret = spi_qup_set_state(controller, QUP_STATE_RESET); + if (ret) +- return ret; ++ goto disable_clk; ++ ++ ret = spi_master_resume(master); ++ if (ret) ++ goto disable_clk; + +- return spi_master_resume(master); ++ return 0; ++ ++disable_clk: ++ clk_disable_unprepare(controller->cclk); ++ clk_disable_unprepare(controller->iclk); ++ return ret; + } + #endif /* CONFIG_PM_SLEEP */ + +-- +2.35.3 + diff --git a/patches.suse/spi-s3c64xx-Fix-large-transfers-with-DMA.patch b/patches.suse/spi-s3c64xx-Fix-large-transfers-with-DMA.patch new file mode 100644 index 0000000..865ece6 --- /dev/null +++ b/patches.suse/spi-s3c64xx-Fix-large-transfers-with-DMA.patch @@ -0,0 +1,55 @@ +From 1224e29572f655facfcd850cf0f0a4784f36a903 Mon Sep 17 00:00:00 2001 +From: Vincent Whitchurch +Date: Tue, 27 Sep 2022 13:21:17 +0200 +Subject: [PATCH] spi: s3c64xx: Fix large transfers with DMA +Git-commit: 1224e29572f655facfcd850cf0f0a4784f36a903 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The COUNT_VALUE in the PACKET_CNT register is 16-bit so the maximum +value is 65535. Asking the driver to transfer a larger size currently +leads to the DMA transfer timing out. Implement ->max_transfer_size() +and have the core split the transfer as needed. + +Fixes: 230d42d422e7 ("spi: Add s3c64xx SPI Controller driver") +Signed-off-by: Vincent Whitchurch +Link: https://lore.kernel.org/r/20220927112117.77599-5-vincent.whitchurch@axis.com +Signed-off-by: Mark Brown +Acked-by: Takashi Iwai + +--- + drivers/spi/spi-s3c64xx.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/drivers/spi/spi-s3c64xx.c ++++ b/drivers/spi/spi-s3c64xx.c +@@ -85,6 +85,7 @@ + #define S3C64XX_SPI_ST_TX_FIFORDY (1<<0) + + #define S3C64XX_SPI_PACKET_CNT_EN (1<<16) ++#define S3C64XX_SPI_PACKET_CNT_MASK GENMASK(15, 0) + + #define S3C64XX_SPI_PND_TX_UNDERRUN_CLR (1<<4) + #define S3C64XX_SPI_PND_TX_OVERRUN_CLR (1<<3) +@@ -661,6 +662,13 @@ static int s3c64xx_spi_prepare_message(s + return 0; + } + ++static size_t s3c64xx_spi_max_transfer_size(struct spi_device *spi) ++{ ++ struct spi_controller *ctlr = spi->controller; ++ ++ return ctlr->can_dma ? S3C64XX_SPI_PACKET_CNT_MASK : SIZE_MAX; ++} ++ + static int s3c64xx_spi_transfer_one(struct spi_master *master, + struct spi_device *spi, + struct spi_transfer *xfer) +@@ -1130,6 +1138,7 @@ static int s3c64xx_spi_probe(struct plat + master->prepare_transfer_hardware = s3c64xx_spi_prepare_transfer; + master->prepare_message = s3c64xx_spi_prepare_message; + master->transfer_one = s3c64xx_spi_transfer_one; ++ master->max_transfer_size = s3c64xx_spi_max_transfer_size; + master->num_chipselect = sci->num_cs; + master->dma_alignment = 8; + master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(16) | diff --git a/patches.suse/spmi-pmic-arb-correct-duplicate-APID-to-PPID-mapping.patch b/patches.suse/spmi-pmic-arb-correct-duplicate-APID-to-PPID-mapping.patch new file mode 100644 index 0000000..51fc88f --- /dev/null +++ b/patches.suse/spmi-pmic-arb-correct-duplicate-APID-to-PPID-mapping.patch @@ -0,0 +1,65 @@ +From 1f1693118c2476cb1666ad357edcf3cf48bf9b16 Mon Sep 17 00:00:00 2001 +From: David Collins +Date: Thu, 29 Sep 2022 17:50:16 -0700 +Subject: [PATCH] spmi: pmic-arb: correct duplicate APID to PPID mapping logic +Git-commit: 1f1693118c2476cb1666ad357edcf3cf48bf9b16 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Correct the way that duplicate PPID mappings are handled for PMIC +arbiter v5. The final APID mapped to a given PPID should be the +one which has write owner = APPS EE, if it exists, or if not +that, then the first APID mapped to the PPID, if it exists. + +Fixes: 40f318f0ed67 ("spmi: pmic-arb: add support for HW version 5") +Signed-off-by: David Collins +Signed-off-by: Fenglin Wu +Link: https://lore.kernel.org/r/1655004286-11493-7-git-send-email-quic_fenglinw@quicinc.com +Signed-off-by: Stephen Boyd +Link: https://lore.kernel.org/r/20220930005019.2663064-8-sboyd@kernel.org +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/spmi/spmi-pmic-arb.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c +index 56f22941d570..cf92abc51689 100644 +--- a/drivers/spmi/spmi-pmic-arb.c ++++ b/drivers/spmi/spmi-pmic-arb.c +@@ -1031,7 +1031,8 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb) + * version 5, there is more than one APID mapped to each PPID. + * The owner field for each of these mappings specifies the EE which is + * allowed to write to the APID. The owner of the last (highest) APID +- * for a given PPID will receive interrupts from the PPID. ++ * which has the IRQ owner bit set for a given PPID will receive ++ * interrupts from the PPID. + */ + for (i = 0; ; i++, apidd++) { + offset = pmic_arb->ver_ops->apid_map_offset(i); +@@ -1054,16 +1055,16 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb) + apid = pmic_arb->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID; + prev_apidd = &pmic_arb->apid_data[apid]; + +- if (valid && is_irq_ee && +- prev_apidd->write_ee == pmic_arb->ee) { ++ if (!valid || apidd->write_ee == pmic_arb->ee) { ++ /* First PPID mapping or one for this EE */ ++ pmic_arb->ppid_to_apid[ppid] = i | PMIC_ARB_APID_VALID; ++ } else if (valid && is_irq_ee && ++ prev_apidd->write_ee == pmic_arb->ee) { + /* + * Duplicate PPID mapping after the one for this EE; + * override the irq owner + */ + prev_apidd->irq_ee = apidd->irq_ee; +- } else if (!valid || is_irq_ee) { +- /* First PPID mapping or duplicate for another EE */ +- pmic_arb->ppid_to_apid[ppid] = i | PMIC_ARB_APID_VALID; + } + + apidd->ppid = ppid; +-- +2.35.3 + diff --git a/patches.suse/spmi-pmic-arb-do-not-ack-and-clear-peripheral-interr.patch b/patches.suse/spmi-pmic-arb-do-not-ack-and-clear-peripheral-interr.patch new file mode 100644 index 0000000..fff28dd --- /dev/null +++ b/patches.suse/spmi-pmic-arb-do-not-ack-and-clear-peripheral-interr.patch @@ -0,0 +1,85 @@ +From b6c1761721193c52234e3ed048e4d16ab527bb74 Mon Sep 17 00:00:00 2001 +From: Subbaraman Narayanamurthy +Date: Thu, 29 Sep 2022 17:50:13 -0700 +Subject: [PATCH] spmi: pmic-arb: do not ack and clear peripheral interrupts in cleanup_irq +Git-commit: b6c1761721193c52234e3ed048e4d16ab527bb74 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Currently, cleanup_irq() is invoked when a peripheral's interrupt +fires and there is no mapping present in the interrupt domain of +spmi interrupt controller. + +The cleanup_irq clears the arbiter bit, clears the pmic interrupt +and disables it at the pmic in that order. The last disable in +cleanup_irq races with request_irq() in that it stomps over the +enable issued by request_irq. Fix this by not writing to the pmic +in cleanup_irq. The latched bit will be left set in the pmic, +which will not send us more interrupts even if the enable bit +stays enabled. + +When a client wants to request an interrupt, use the activate +callback on the irq_domain to clear latched bit. This ensures +that the latched, if set due to the above changes in cleanup_irq +or when the bootloader leaves it set, gets cleaned up, paving way +for upcoming interrupts to trigger. + +With this, there is a possibility of unwanted triggering of +interrupt right after the latched bit is cleared - the interrupt +may be left enabled too. To avoid that, clear the enable first +followed by clearing the latched bit in the activate callback. + +Fixes: 6bc546e71e50 ("spmi: pmic-arb: cleanup unrequested irqs") +Fixes: 02abec3616c1 ("spmi: pmic-arb: rename pa_xx to pmic_arb_xx and other cleanup") +Signed-off-by: Subbaraman Narayanamurthy +[collinsd@codeaurora.org: fix merge conflict] +Signed-off-by: David Collins +Signed-off-by: Fenglin Wu +Link: https://lore.kernel.org/r/1655004286-11493-4-git-send-email-quic_fenglinw@quicinc.com +Signed-off-by: Stephen Boyd +Link: https://lore.kernel.org/r/20220930005019.2663064-5-sboyd@kernel.org +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/spmi/spmi-pmic-arb.c | 15 +++++---------- + 1 file changed, 5 insertions(+), 10 deletions(-) + +--- a/drivers/spmi/spmi-pmic-arb.c ++++ b/drivers/spmi/spmi-pmic-arb.c +@@ -490,16 +490,6 @@ static void cleanup_irq(struct spmi_pmic + u8 irq_mask = BIT(id); + + writel_relaxed(irq_mask, pmic_arb->ver_ops->irq_clear(pmic_arb, apid)); +- +- if (pmic_arb_write_cmd(pmic_arb->spmic, SPMI_CMD_EXT_WRITEL, sid, +- (per << 8) + QPNPINT_REG_LATCHED_CLR, &irq_mask, 1)) +- dev_err_ratelimited(&pmic_arb->spmic->dev, "failed to ack irq_mask = 0x%x for ppid = %x\n", +- irq_mask, ppid); +- +- if (pmic_arb_write_cmd(pmic_arb->spmic, SPMI_CMD_EXT_WRITEL, sid, +- (per << 8) + QPNPINT_REG_EN_CLR, &irq_mask, 1)) +- dev_err_ratelimited(&pmic_arb->spmic->dev, "failed to ack irq_mask = 0x%x for ppid = %x\n", +- irq_mask, ppid); + } + + static void periph_interrupt(struct spmi_pmic_arb *pmic_arb, u16 apid) +@@ -665,6 +655,7 @@ static int qpnpint_irq_domain_activate(s + u16 apid = hwirq_to_apid(d->hwirq); + u16 sid = hwirq_to_sid(d->hwirq); + u16 irq = hwirq_to_irq(d->hwirq); ++ u8 buf; + + if (pmic_arb->apid_data[apid].irq_ee != pmic_arb->ee) { + dev_err(&pmic_arb->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u: ee=%u but owner=%u\n", +@@ -673,6 +664,10 @@ static int qpnpint_irq_domain_activate(s + return -ENODEV; + } + ++ buf = BIT(irq); ++ qpnpint_spmi_write(d, QPNPINT_REG_EN_CLR, &buf, 1); ++ qpnpint_spmi_write(d, QPNPINT_REG_LATCHED_CLR, &buf, 1); ++ + return 0; + } + diff --git a/patches.suse/staging-vt6655-fix-some-erroneous-memory-clean-up-lo.patch b/patches.suse/staging-vt6655-fix-some-erroneous-memory-clean-up-lo.patch new file mode 100644 index 0000000..c733254 --- /dev/null +++ b/patches.suse/staging-vt6655-fix-some-erroneous-memory-clean-up-lo.patch @@ -0,0 +1,68 @@ +From 2a2db520e3ca5aafba7c211abfd397666c9b5f9d Mon Sep 17 00:00:00 2001 +From: Nam Cao +Date: Mon, 12 Sep 2022 19:04:31 +0200 +Subject: [PATCH] staging: vt6655: fix some erroneous memory clean-up loops +Git-commit: 2a2db520e3ca5aafba7c211abfd397666c9b5f9d +Patch-mainline: v6.1-rc1 +References: git-fixes + +In some initialization functions of this driver, memory is allocated with +'i' acting as an index variable and increasing from 0. The commit in +"Fixes" introduces some clean-up codes in case of allocation failure, +which free memory in reverse order with 'i' decreasing to 0. However, +there are some problems: + - The case i=0 is left out. Thus memory is leaked. + - In case memory allocation fails right from the start, the memory + freeing loops will start with i=-1 and invalid memory locations will + be accessed. + +One of these loops has been fixed in commit c8ff91535880 ("staging: +Vt6655: fix potential memory leak"). Fix the remaining erroneous loops. + +Link: https://lore.kernel.org/linux-staging/Yx9H1zSpxmNqx6Xc@kadam/ +Fixes: 5341ee0adb17 ("staging: vt6655: check for memory allocation failures") +Reported-by: Dan Carpenter +Tested-by: Philipp Hortmann +Signed-off-by: Nam Cao +Link: https://lore.kernel.org/r/20220912170429.29852-1-namcaov@gmail.com +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/staging/vt6655/device_main.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c +index 04d737012cef..56c3cf3ba53d 100644 +--- a/drivers/staging/vt6655/device_main.c ++++ b/drivers/staging/vt6655/device_main.c +@@ -631,7 +631,7 @@ static int device_init_rd0_ring(struct vnt_private *priv) + kfree(desc->rd_info); + + err_free_desc: +- while (--i) { ++ while (i--) { + desc = &priv->aRD0Ring[i]; + device_free_rx_buf(priv, desc); + kfree(desc->rd_info); +@@ -677,7 +677,7 @@ static int device_init_rd1_ring(struct vnt_private *priv) + kfree(desc->rd_info); + + err_free_desc: +- while (--i) { ++ while (i--) { + desc = &priv->aRD1Ring[i]; + device_free_rx_buf(priv, desc); + kfree(desc->rd_info); +@@ -782,7 +782,7 @@ static int device_init_td1_ring(struct vnt_private *priv) + return 0; + + err_free_desc: +- while (--i) { ++ while (i--) { + desc = &priv->apTD1Rings[i]; + kfree(desc->td_info); + } +-- +2.35.3 + diff --git a/patches.suse/stmmac-intel-Fix-an-error-handling-path-in-intel_eth.patch b/patches.suse/stmmac-intel-Fix-an-error-handling-path-in-intel_eth.patch new file mode 100644 index 0000000..2a98f1b --- /dev/null +++ b/patches.suse/stmmac-intel-Fix-an-error-handling-path-in-intel_eth.patch @@ -0,0 +1,49 @@ +From db7848f69aebf9d193de75e5200c56aeb5958365 Mon Sep 17 00:00:00 2001 +From: Christophe JAILLET +Date: Sun, 5 Jun 2022 22:50:48 +0200 +Subject: [PATCH 10/32] stmmac: intel: Fix an error handling path in + intel_eth_pci_probe() +Git-commit: 5e74a4b3ec1816e3bbfd715d46ae29d2508079cb +References: git-fixes +Patch-mainline: v5.19-rc2 + +When the managed API is used, there is no need to explicitly call +pci_free_irq_vectors(). + +This looks to be a left-over from the commit in the Fixes tag. Only the +.remove() function had been updated. + +So remove this unused function call and update goto label accordingly. + +Fixes: 8accc467758e ("stmmac: intel: use managed PCI function on probe and resume") +Signed-off-by: Christophe JAILLET +Reviewed-by: Wong Vee Khee +Link: https://lore.kernel.org/r/1ac9b6787b0db83b0095711882c55c77c8ea8da0.1654462241.git.christophe.jaillet@wanadoo.fr +Signed-off-by: Paolo Abeni +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c +index 6f87e296a410..502fbbc082fb 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c +@@ -1073,13 +1073,11 @@ static int intel_eth_pci_probe(struct pci_dev *pdev, + + ret = stmmac_dvr_probe(&pdev->dev, plat, &res); + if (ret) { +- goto err_dvr_probe; ++ goto err_alloc_irq; + } + + return 0; + +-err_dvr_probe: +- pci_free_irq_vectors(pdev); + err_alloc_irq: + clk_disable_unprepare(plat->stmmac_clk); + clk_unregister_fixed_rate(plat->stmmac_clk); +-- +2.16.4 + diff --git a/patches.suse/sunrpc-fix-expiry-of-auth-creds.patch b/patches.suse/sunrpc-fix-expiry-of-auth-creds.patch new file mode 100644 index 0000000..ab44022 --- /dev/null +++ b/patches.suse/sunrpc-fix-expiry-of-auth-creds.patch @@ -0,0 +1,31 @@ +From: Dan Aloni +Date: Mon, 4 Jul 2022 15:56:57 +0300 +Subject: [PATCH] sunrpc: fix expiry of auth creds +Git-commit: f1bafa7375c01ff71fb7cb97c06caadfcfe815f3 +Patch-mainline: v6.0 +References: git-fixes + +Before this commit, with a large enough LRU of expired items (100), the +loop skipped all the expired items and was entirely ineffectual in +trimming the LRU list. + +Fixes: 95cd623250ad ('SUNRPC: Clean up the AUTH cache code') +Signed-off-by: Dan Aloni +Signed-off-by: Trond Myklebust +Acked-by: NeilBrown + +--- + net/sunrpc/auth.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/sunrpc/auth.c ++++ b/net/sunrpc/auth.c +@@ -445,7 +445,7 @@ rpcauth_prune_expired(struct list_head * + * Enforce a 60 second garbage collection moratorium + * Note that the cred_unused list must be time-ordered. + */ +- if (!time_in_range(cred->cr_expire, expired, jiffies)) ++ if (time_in_range(cred->cr_expire, expired, jiffies)) + continue; + if (!rpcauth_unhash_cred(cred)) + continue; diff --git a/patches.suse/tcp-add-small-random-increments-to-the-source-port.patch b/patches.suse/tcp-add-small-random-increments-to-the-source-port.patch index 97b9b39..1c09b02 100644 --- a/patches.suse/tcp-add-small-random-increments-to-the-source-port.patch +++ b/patches.suse/tcp-add-small-random-increments-to-the-source-port.patch @@ -3,7 +3,7 @@ Date: Mon, 2 May 2022 10:46:11 +0200 Subject: tcp: add small random increments to the source port Patch-mainline: v5.18-rc6 Git-commit: ca7af0402550f9a0b3316d5f1c30904e42ed257d -References: CVE-2022-1012 bsc#1199482 +References: CVE-2022-1012 CVE-2022-32296 bsc#1199482 bsc#1200288 Here we're randomly adding between 0 and 7 random increments to the selected source port in order to add some noise in the source port diff --git a/patches.suse/tcp-drop-the-hash_32-part-from-the-index-calculation.patch b/patches.suse/tcp-drop-the-hash_32-part-from-the-index-calculation.patch index c9156f9..5f8061c 100644 --- a/patches.suse/tcp-drop-the-hash_32-part-from-the-index-calculation.patch +++ b/patches.suse/tcp-drop-the-hash_32-part-from-the-index-calculation.patch @@ -3,7 +3,7 @@ Date: Mon, 2 May 2022 10:46:14 +0200 Subject: tcp: drop the hash_32() part from the index calculation Patch-mainline: v5.18-rc6 Git-commit: e8161345ddbb66e449abde10d2fdce93f867eba9 -References: CVE-2022-1012 bsc#1199482 +References: CVE-2022-1012 CVE-2022-32296 bsc#1199482 bsc#1200288 In commit 190cc82489f4 ("tcp: change source port randomizarion at connect() time"), the table_perturb[] array was introduced and an diff --git a/patches.suse/tcp-dynamically-allocate-the-perturb-table-used-by-s.patch b/patches.suse/tcp-dynamically-allocate-the-perturb-table-used-by-s.patch index 6edc22f..d8f88cc 100644 --- a/patches.suse/tcp-dynamically-allocate-the-perturb-table-used-by-s.patch +++ b/patches.suse/tcp-dynamically-allocate-the-perturb-table-used-by-s.patch @@ -3,7 +3,7 @@ Date: Mon, 2 May 2022 10:46:12 +0200 Subject: tcp: dynamically allocate the perturb table used by source ports Patch-mainline: v5.18-rc6 Git-commit: e9261476184be1abd486c9434164b2acbe0ed6c2 -References: CVE-2022-1012 bsc#1199482 +References: CVE-2022-1012 CVE-2022-32296 bsc#1199482 bsc#1200288 We'll need to further increase the size of this table and it's likely that at some point its size will not be suitable anymore for a static diff --git a/patches.suse/tcp-increase-source-port-perturb-table-to-2-16.patch b/patches.suse/tcp-increase-source-port-perturb-table-to-2-16.patch index 519245e..aff692a 100644 --- a/patches.suse/tcp-increase-source-port-perturb-table-to-2-16.patch +++ b/patches.suse/tcp-increase-source-port-perturb-table-to-2-16.patch @@ -3,7 +3,7 @@ Date: Mon, 2 May 2022 10:46:13 +0200 Subject: tcp: increase source port perturb table to 2^16 Patch-mainline: v5.18-rc6 Git-commit: 4c2c8f03a5ab7cb04ec64724d7d176d00bcc91e5 -References: CVE-2022-1012 bsc#1199482 +References: CVE-2022-1012 CVE-2022-32296 bsc#1199482 bsc#1200288 Moshe Kol, Amit Klein, and Yossi Gilad reported being able to accurately identify a client by forcing it to emit only 40 times more connections diff --git a/patches.suse/tcp-resalt-the-secret-every-10-seconds.patch b/patches.suse/tcp-resalt-the-secret-every-10-seconds.patch index 757ad6b..d70fb54 100644 --- a/patches.suse/tcp-resalt-the-secret-every-10-seconds.patch +++ b/patches.suse/tcp-resalt-the-secret-every-10-seconds.patch @@ -3,7 +3,7 @@ Date: Mon, 2 May 2022 10:46:10 +0200 Subject: tcp: resalt the secret every 10 seconds Patch-mainline: v5.18-rc6 Git-commit: 4dfa9b438ee34caca4e6a4e5e961641807367f6f -References: CVE-2022-1012 bsc#1199482 +References: CVE-2022-1012 CVE-2022-32296 bsc#1199482 bsc#1200288 In order to limit the ability for an observer to recognize the source ports sequence used to contact a set of destinations, we should diff --git a/patches.suse/tcp-use-different-parts-of-the-port_offset-for-index.patch b/patches.suse/tcp-use-different-parts-of-the-port_offset-for-index.patch index aaf2f9b..053d614 100644 --- a/patches.suse/tcp-use-different-parts-of-the-port_offset-for-index.patch +++ b/patches.suse/tcp-use-different-parts-of-the-port_offset-for-index.patch @@ -3,7 +3,7 @@ Date: Mon, 2 May 2022 10:46:09 +0200 Subject: tcp: use different parts of the port_offset for index and offset Patch-mainline: v5.18-rc6 Git-commit: 9e9b70ae923baf2b5e8a0ea4fd0c8451801ac526 -References: CVE-2022-1012 bsc#1199482 +References: CVE-2022-1012 CVE-2022-32296 bsc#1199482 bsc#1200288 Amit Klein suggests that we use different parts of port_offset for the table's index and the port offset so that there is no direct relation diff --git a/patches.suse/thermal-int340x-Mode-setting-with-new-OS-handshake.patch b/patches.suse/thermal-int340x-Mode-setting-with-new-OS-handshake.patch new file mode 100644 index 0000000..de29d7e --- /dev/null +++ b/patches.suse/thermal-int340x-Mode-setting-with-new-OS-handshake.patch @@ -0,0 +1,128 @@ +From 7b145802ba545ecf9446ce6d67d6011b73dac0e0 Mon Sep 17 00:00:00 2001 +From: Srinivas Pandruvada +Date: Tue, 10 May 2022 11:22:21 -0700 +Subject: [PATCH] thermal: int340x: Mode setting with new OS handshake +Git-commit: 7b145802ba545ecf9446ce6d67d6011b73dac0e0 +Patch-mainline: v5.18 +References: jsc#PED-678 + +With the new OS handshake introduced by commit: "c7ff29763989 ("thermal: +Int340x: Update OS policy capability handshake")", the "enabled" thermal +zone mode doesn't work in the same way as previously. + +The "enabled" mode fails with -EINVAL when the new handshake is used. + +To address this issue, when the new OS UUID mask is set: + + - When the mode is "enabled", return 0 as the firmware already has the + latest policy mask. + + - When the mode is "disabled", update the firmware with the UUID mask + of zero. + +This way, the firmware can take over the thermal control. + +Also reset the OS UUID mask, which allows user space to update with new +set of policies. + +Fixes: c7ff29763989 ("thermal: int340x: Update OS policy capability handshake") +Signed-off-by: Srinivas Pandruvada +[ rjw: Changelog edits, removed unneeded parens ] + +Signed-off-by: Rafael J. Wysocki +Acked-by: Takashi Iwai + +--- + .../intel/int340x_thermal/int3400_thermal.c | 48 ++++++++++++------- + 1 file changed, 32 insertions(+), 16 deletions(-) + +diff --git a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c +index d97f496bab9b..79931ddc582a 100644 +--- a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c ++++ b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c +@@ -194,12 +194,31 @@ static int int3400_thermal_run_osc(acpi_handle handle, char *uuid_str, int *enab + return result; + } + ++static int set_os_uuid_mask(struct int3400_thermal_priv *priv, u32 mask) ++{ ++ int cap = 0; ++ ++ /* ++ * Capability bits: ++ * Bit 0: set to 1 to indicate DPTF is active ++ * Bi1 1: set to 1 to active cooling is supported by user space daemon ++ * Bit 2: set to 1 to passive cooling is supported by user space daemon ++ * Bit 3: set to 1 to critical trip is handled by user space daemon ++ */ ++ if (mask) ++ cap = (priv->os_uuid_mask << 1) | 0x01; ++ ++ return int3400_thermal_run_osc(priv->adev->handle, ++ "b23ba85d-c8b7-3542-88de-8de2ffcfd698", ++ &cap); ++} ++ + static ssize_t current_uuid_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) + { + struct int3400_thermal_priv *priv = dev_get_drvdata(dev); +- int i; ++ int ret, i; + + for (i = 0; i < INT3400_THERMAL_MAXIMUM_UUID; ++i) { + if (!strncmp(buf, int3400_thermal_uuids[i], +@@ -231,19 +250,7 @@ static ssize_t current_uuid_store(struct device *dev, + } + + if (priv->os_uuid_mask) { +- int cap, ret; +- +- /* +- * Capability bits: +- * Bit 0: set to 1 to indicate DPTF is active +- * Bi1 1: set to 1 to active cooling is supported by user space daemon +- * Bit 2: set to 1 to passive cooling is supported by user space daemon +- * Bit 3: set to 1 to critical trip is handled by user space daemon +- */ +- cap = ((priv->os_uuid_mask << 1) | 0x01); +- ret = int3400_thermal_run_osc(priv->adev->handle, +- "b23ba85d-c8b7-3542-88de-8de2ffcfd698", +- &cap); ++ ret = set_os_uuid_mask(priv, priv->os_uuid_mask); + if (ret) + return ret; + } +@@ -469,17 +476,26 @@ static int int3400_thermal_change_mode(struct thermal_zone_device *thermal, + if (mode != thermal->mode) { + int enabled; + ++ enabled = mode == THERMAL_DEVICE_ENABLED; ++ ++ if (priv->os_uuid_mask) { ++ if (!enabled) { ++ priv->os_uuid_mask = 0; ++ result = set_os_uuid_mask(priv, priv->os_uuid_mask); ++ } ++ goto eval_odvp; ++ } ++ + if (priv->current_uuid_index < 0 || + priv->current_uuid_index >= INT3400_THERMAL_MAXIMUM_UUID) + return -EINVAL; + +- enabled = (mode == THERMAL_DEVICE_ENABLED); + result = int3400_thermal_run_osc(priv->adev->handle, + int3400_thermal_uuids[priv->current_uuid_index], + &enabled); + } + +- ++eval_odvp: + evaluate_odvp(priv); + + return result; +-- +2.35.3 + diff --git a/patches.suse/thermal-int340x-Update-OS-policy-capability-handshak.patch b/patches.suse/thermal-int340x-Update-OS-policy-capability-handshak.patch new file mode 100644 index 0000000..9443221 --- /dev/null +++ b/patches.suse/thermal-int340x-Update-OS-policy-capability-handshak.patch @@ -0,0 +1,288 @@ +From c7ff29763989bd09c433f73fae3c1e1c15d9cda4 Mon Sep 17 00:00:00 2001 +From: Srinivas Pandruvada +Date: Mon, 14 Mar 2022 15:09:37 -0700 +Subject: [PATCH] thermal: int340x: Update OS policy capability handshake +Git-commit: c7ff29763989bd09c433f73fae3c1e1c15d9cda4 +Patch-mainline: v5.18-rc1 +References: jsc#PED-678 + +Update the firmware with OS supported policies mask, so that firmware can +relinquish its internal controls. Without this update several Tiger Lake +laptops gets performance limited with in few seconds of executing in +turbo region. + +The existing way of enumerating firmware policies via IDSP method and +selecting policy by directly writing those policy UUIDS via _OSC method +is not supported in newer generation of hardware. + +There is a new UUID "B23BA85D-C8B7-3542-88DE-8DE2FFCFD698" is defined for +updating policy capabilities. As part of ACPI _OSC method: + +Arg0 - UUID: B23BA85D-C8B7-3542-88DE-8DE2FFCFD698 +Arg1 - Rev ID: 1 +Arg2 - Count: 2 +Arg3 - Capability buffers: Array of Arg2 DWORDS + +Dword1: As defined in the ACPI 5.0 Specification +- Bit 0: Query Flag +- Bits 1-3: Always 0 +- Bits 4-31: Reserved + +DWORD2 and beyond: +- Bit0: set to 1 to indicate Intel(R) Dynamic Tuning is active, 0 to +indicate it is disabled and legacy thermal mechanism should +be enabled. +- Bit1: set to 1 to indicate Intel(R) Dynamic Tuning is controlling +active cooling, 0 to indicate bios shall enable legacy thermal +zone with active trip point. +- Bit2: set to 1 to indicate Intel(R) Dynamic Tuning is controlling +passive cooling, 0 to indicate bios shall enable legacy thermal +zone with passive trip point. +- Bit3: set to 1 to indicate Intel(R) Dynamic Tuning is handling +critical trip point, 0 to indicate bios shall enable legacy +thermal zone with critical trip point. +- Bits 4:31: Reserved + +From sysfs interface, there is an existing interface to update policy +UUID using attribute "current_uuid". User space can write the same UUID +for ACTIVE, PASSIVE and CRITICAL policy. Driver converts these UUIDs to +DWORD2 Bit 1 to Bit 3. When any of the policy is activated by user +space it is assumed that dynamic tuning is active. + +For example +$cd /sys/bus/platform/devices/INTC1040:00/uuids +To support active policy +$echo "3A95C389-E4B8-4629-A526-C52C88626BAE" > current_uuid +To support passive policy +$echo "42A441D6-AE6A-462b-A84B-4A8CE79027D3" > current_uuid +To support critical policy +$echo "97C68AE7-15FA-499c-B8C9-5DA81D606E0A" > current_uuid + +To check all the supported policies +$cat current_uuid +3A95C389-E4B8-4629-A526-C52C88626BAE +42A441D6-AE6A-462b-A84B-4A8CE79027D3 +97C68AE7-15FA-499c-B8C9-5DA81D606E0A + +To match the bit format for DWORD2, rearranged enum int3400_thermal_uuid +and int3400_thermal_uuids[] by swapping current INT3400_THERMAL_ACTIVE +and INT3400_THERMAL_PASSIVE_1. + +If the policies are enumerated via IDSP method then legacy method is +used, if not the new method is used to update policy support. + +Signed-off-by: Srinivas Pandruvada +Signed-off-by: Rafael J. Wysocki +Acked-by: Takashi Iwai + +--- + drivers/thermal/intel/int340x_thermal/int3400_thermal.c | 146 ++++++++++------ + 1 file changed, 97 insertions(+), 49 deletions(-) + +--- a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c ++++ b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c +@@ -17,8 +17,8 @@ + #define INT3400_KEEP_ALIVE 0xA0 + + enum int3400_thermal_uuid { ++ INT3400_THERMAL_ACTIVE = 0, + INT3400_THERMAL_PASSIVE_1, +- INT3400_THERMAL_ACTIVE, + INT3400_THERMAL_CRITICAL, + INT3400_THERMAL_ADAPTIVE_PERFORMANCE, + INT3400_THERMAL_EMERGENCY_CALL_MODE, +@@ -31,8 +31,8 @@ enum int3400_thermal_uuid { + }; + + static char *int3400_thermal_uuids[INT3400_THERMAL_MAXIMUM_UUID] = { +- "42A441D6-AE6A-462b-A84B-4A8CE79027D3", + "3A95C389-E4B8-4629-A526-C52C88626BAE", ++ "42A441D6-AE6A-462b-A84B-4A8CE79027D3", + "97C68AE7-15FA-499c-B8C9-5DA81D606E0A", + "63BE270F-1C11-48FD-A6F7-3AF253FF3E2D", + "5349962F-71E6-431D-9AE8-0A635B710AEE", +@@ -59,6 +59,7 @@ struct int3400_thermal_priv { + char *data_vault; + int odvp_count; + int *odvp; ++ u32 os_uuid_mask; + struct odvp_attr *odvp_attrs; + }; + +@@ -140,12 +141,55 @@ static ssize_t current_uuid_show(struct + struct device_attribute *devattr, char *buf) + { + struct int3400_thermal_priv *priv = dev_get_drvdata(dev); ++ int i, length = 0; ++ ++ if (priv->current_uuid_index > 0) ++ return sprintf(buf, "%s\n", ++ int3400_thermal_uuids[priv->current_uuid_index]); ++ ++ for (i = 0; i <= INT3400_THERMAL_CRITICAL; i++) { ++ if (priv->os_uuid_mask & BIT(i)) ++ length += scnprintf(&buf[length], ++ PAGE_SIZE - length, ++ "%s\n", ++ int3400_thermal_uuids[i]); ++ } + +- if (priv->current_uuid_index == -1) +- return sprintf(buf, "INVALID\n"); ++ if (length) ++ return length; + +- return sprintf(buf, "%s\n", +- int3400_thermal_uuids[priv->current_uuid_index]); ++ return sprintf(buf, "INVALID\n"); ++} ++ ++static int int3400_thermal_run_osc(acpi_handle handle, char *uuid_str, int *enable) ++{ ++ u32 ret, buf[2]; ++ acpi_status status; ++ int result = 0; ++ struct acpi_osc_context context = { ++ .uuid_str = NULL, ++ .rev = 1, ++ .cap.length = 8, ++ }; ++ ++ context.uuid_str = uuid_str; ++ ++ buf[OSC_QUERY_DWORD] = 0; ++ buf[OSC_SUPPORT_DWORD] = *enable; ++ ++ context.cap.pointer = buf; ++ ++ status = acpi_run_osc(handle, &context); ++ if (ACPI_SUCCESS(status)) { ++ ret = *((u32 *)(context.ret.pointer + 4)); ++ if (ret != *enable) ++ result = -EPERM; ++ } else ++ result = -EPERM; ++ ++ kfree(context.ret.pointer); ++ ++ return result; + } + + static ssize_t current_uuid_store(struct device *dev, +@@ -162,16 +206,47 @@ static ssize_t current_uuid_store(struct + * If we have a list of supported UUIDs, make sure + * this one is supported. + */ +- if (priv->uuid_bitmap && +- !(priv->uuid_bitmap & (1 << i))) ++ if (priv->uuid_bitmap & BIT(i)) { ++ priv->current_uuid_index = i; ++ return count; ++ } ++ ++ /* ++ * There is support of only 3 policies via the new ++ * _OSC to inform OS capability: ++ * INT3400_THERMAL_ACTIVE ++ * INT3400_THERMAL_PASSIVE_1 ++ * INT3400_THERMAL_CRITICAL ++ */ ++ ++ if (i > INT3400_THERMAL_CRITICAL) + return -EINVAL; + +- priv->current_uuid_index = i; +- return count; ++ priv->os_uuid_mask |= BIT(i); ++ ++ break; + } + } + +- return -EINVAL; ++ if (priv->os_uuid_mask) { ++ int cap, ret; ++ ++ /* ++ * Capability bits: ++ * Bit 0: set to 1 to indicate DPTF is active ++ * Bi1 1: set to 1 to active cooling is supported by user space daemon ++ * Bit 2: set to 1 to passive cooling is supported by user space daemon ++ * Bit 3: set to 1 to critical trip is handled by user space daemon ++ */ ++ cap = ((priv->os_uuid_mask << 1) | 0x01); ++ ret = int3400_thermal_run_osc(priv->adev->handle, ++ "b23ba85d-c8b7-3542-88de-8de2ffcfd698", ++ &cap); ++ if (ret) ++ return ret; ++ } ++ ++ return count; + } + + static DEVICE_ATTR_RW(current_uuid); +@@ -234,41 +309,6 @@ end: + return result; + } + +-static int int3400_thermal_run_osc(acpi_handle handle, +- enum int3400_thermal_uuid uuid, bool enable) +-{ +- u32 ret, buf[2]; +- acpi_status status; +- int result = 0; +- struct acpi_osc_context context = { +- .uuid_str = NULL, +- .rev = 1, +- .cap.length = 8, +- }; +- +- if (uuid < 0 || uuid >= INT3400_THERMAL_MAXIMUM_UUID) +- return -EINVAL; +- +- context.uuid_str = int3400_thermal_uuids[uuid]; +- +- buf[OSC_QUERY_DWORD] = 0; +- buf[OSC_SUPPORT_DWORD] = enable; +- +- context.cap.pointer = buf; +- +- status = acpi_run_osc(handle, &context); +- if (ACPI_SUCCESS(status)) { +- ret = *((u32 *)(context.ret.pointer + 4)); +- if (ret != enable) +- result = -EPERM; +- } else +- result = -EPERM; +- +- kfree(context.ret.pointer); +- +- return result; +-} +- + static ssize_t odvp_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) + { +@@ -424,10 +464,18 @@ static int int3400_thermal_change_mode(s + if (!priv) + return -EINVAL; + +- if (mode != thermal->mode) ++ if (mode != thermal->mode) { ++ int enabled; ++ ++ if (priv->current_uuid_index < 0 || ++ priv->current_uuid_index >= INT3400_THERMAL_MAXIMUM_UUID) ++ return -EINVAL; ++ ++ enabled = (mode == THERMAL_DEVICE_ENABLED); + result = int3400_thermal_run_osc(priv->adev->handle, +- priv->current_uuid_index, +- mode == THERMAL_DEVICE_ENABLED); ++ int3400_thermal_uuids[priv->current_uuid_index], ++ &enabled); ++ } + + + evaluate_odvp(priv); diff --git a/patches.suse/thunderbolt-Add-internal-xHCI-connect-flows-for-Thun.patch b/patches.suse/thunderbolt-Add-internal-xHCI-connect-flows-for-Thun.patch new file mode 100644 index 0000000..5562cb2 --- /dev/null +++ b/patches.suse/thunderbolt-Add-internal-xHCI-connect-flows-for-Thun.patch @@ -0,0 +1,332 @@ +From 30a4eca69b76c0ed5a2f34dd2a3e195c9bf6bed1 Mon Sep 17 00:00:00 2001 +From: Mika Westerberg +Date: Fri, 7 Jan 2022 13:00:47 +0200 +Subject: [PATCH] thunderbolt: Add internal xHCI connect flows for Thunderbolt + 3 devices +Git-commit: 30a4eca69b76c0ed5a2f34dd2a3e195c9bf6bed1 +References: jsc#PED-531 +Patch-mainline: v5.18-rc1 + +Both Alpine Ridge and Titan Ridge require special flows in order to +activate the internal xHCI controller when there is USB device connected +to the downstream type-C port. This implements the missing flows for +both. + +Signed-off-by: Mika Westerberg +Signed-off-by: Oliver Neukum +--- + drivers/thunderbolt/lc.c | 110 ++++++++++++++++++++++++++++++++++ + drivers/thunderbolt/switch.c | 71 +++++++++++++++++++++- + drivers/thunderbolt/tb.c | 11 ++++ + drivers/thunderbolt/tb.h | 7 +++ + drivers/thunderbolt/tb_regs.h | 8 +++ + 5 files changed, 206 insertions(+), 1 deletion(-) + +diff --git a/drivers/thunderbolt/lc.c b/drivers/thunderbolt/lc.c +index 53495a38b4eb..633970fbe9b0 100644 +--- a/drivers/thunderbolt/lc.c ++++ b/drivers/thunderbolt/lc.c +@@ -217,6 +217,116 @@ bool tb_lc_is_clx_supported(struct tb_port *port) + return !!(val & TB_LC_LINK_ATTR_CPS); + } + ++/** ++ * tb_lc_is_usb_plugged() - Is there USB device connected to port ++ * @port: Device router lane 0 adapter ++ * ++ * Returns true if the @port has USB type-C device connected. ++ */ ++bool tb_lc_is_usb_plugged(struct tb_port *port) ++{ ++ struct tb_switch *sw = port->sw; ++ int cap, ret; ++ u32 val; ++ ++ if (sw->generation != 3) ++ return false; ++ ++ cap = find_port_lc_cap(port); ++ if (cap < 0) ++ return false; ++ ++ ret = tb_sw_read(sw, &val, TB_CFG_SWITCH, cap + TB_LC_CS_42, 1); ++ if (ret) ++ return false; ++ ++ return !!(val & TB_LC_CS_42_USB_PLUGGED); ++} ++ ++/** ++ * tb_lc_is_xhci_connected() - Is the internal xHCI connected ++ * @port: Device router lane 0 adapter ++ * ++ * Returns true if the internal xHCI has been connected to @port. ++ */ ++bool tb_lc_is_xhci_connected(struct tb_port *port) ++{ ++ struct tb_switch *sw = port->sw; ++ int cap, ret; ++ u32 val; ++ ++ if (sw->generation != 3) ++ return false; ++ ++ cap = find_port_lc_cap(port); ++ if (cap < 0) ++ return false; ++ ++ ret = tb_sw_read(sw, &val, TB_CFG_SWITCH, cap + TB_LC_LINK_REQ, 1); ++ if (ret) ++ return false; ++ ++ return !!(val & TB_LC_LINK_REQ_XHCI_CONNECT); ++} ++ ++static int __tb_lc_xhci_connect(struct tb_port *port, bool connect) ++{ ++ struct tb_switch *sw = port->sw; ++ int cap, ret; ++ u32 val; ++ ++ if (sw->generation != 3) ++ return -EINVAL; ++ ++ cap = find_port_lc_cap(port); ++ if (cap < 0) ++ return cap; ++ ++ ret = tb_sw_read(sw, &val, TB_CFG_SWITCH, cap + TB_LC_LINK_REQ, 1); ++ if (ret) ++ return ret; ++ ++ if (connect) ++ val |= TB_LC_LINK_REQ_XHCI_CONNECT; ++ else ++ val &= ~TB_LC_LINK_REQ_XHCI_CONNECT; ++ ++ return tb_sw_write(sw, &val, TB_CFG_SWITCH, cap + TB_LC_LINK_REQ, 1); ++} ++ ++/** ++ * tb_lc_xhci_connect() - Connect internal xHCI ++ * @port: Device router lane 0 adapter ++ * ++ * Tells LC to connect the internal xHCI to @port. Returns %0 on success ++ * and negative errno in case of failure. Can be called for Thunderbolt 3 ++ * routers only. ++ */ ++int tb_lc_xhci_connect(struct tb_port *port) ++{ ++ int ret; ++ ++ ret = __tb_lc_xhci_connect(port, true); ++ if (ret) ++ return ret; ++ ++ tb_port_dbg(port, "xHCI connected\n"); ++ return 0; ++} ++ ++/** ++ * tb_lc_xhci_disconnect() - Disconnect internal xHCI ++ * @port: Device router lane 0 adapter ++ * ++ * Tells LC to disconnect the internal xHCI from @port. Can be called ++ * for Thunderbolt 3 routers only. ++ */ ++void tb_lc_xhci_disconnect(struct tb_port *port) ++{ ++ __tb_lc_xhci_connect(port, false); ++ tb_port_dbg(port, "xHCI disconnected\n"); ++} ++ + static int tb_lc_set_wake_one(struct tb_switch *sw, unsigned int offset, + unsigned int flags) + { +diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c +index d026e305fe5d..b5fb3e76ed09 100644 +--- a/drivers/thunderbolt/switch.c ++++ b/drivers/thunderbolt/switch.c +@@ -1528,7 +1528,13 @@ static int tb_plug_events_active(struct tb_switch *sw, bool active) + case PCI_DEVICE_ID_INTEL_PORT_RIDGE: + break; + default: +- data |= 4; ++ /* ++ * Skip Alpine Ridge, it needs to have vendor ++ * specific USB hotplug event enabled for the ++ * internal xHCI to work. ++ */ ++ if (!tb_switch_is_alpine_ridge(sw)) ++ data |= TB_PLUG_EVENTS_USB_DISABLE; + } + } else { + data = data | 0x7c; +@@ -3689,3 +3695,66 @@ int tb_switch_pcie_l1_enable(struct tb_switch *sw) + /* Write to Upstream PCIe bridge #0 aka Up0 */ + return tb_switch_pcie_bridge_write(sw, 0, 0x143, 0x0c5806b1); + } ++ ++/** ++ * tb_switch_xhci_connect() - Connect internal xHCI ++ * @sw: Router whose xHCI to connect ++ * ++ * Can be called to any router. For Alpine Ridge and Titan Ridge ++ * performs special flows that bring the xHCI functional for any device ++ * connected to the type-C port. Call only after PCIe tunnel has been ++ * established. The function only does the connect if not done already ++ * so can be called several times for the same router. ++ */ ++int tb_switch_xhci_connect(struct tb_switch *sw) ++{ ++ bool usb_port1, usb_port3, xhci_port1, xhci_port3; ++ struct tb_port *port1, *port3; ++ int ret; ++ ++ port1 = &sw->ports[1]; ++ port3 = &sw->ports[3]; ++ ++ if (tb_switch_is_alpine_ridge(sw)) { ++ usb_port1 = tb_lc_is_usb_plugged(port1); ++ usb_port3 = tb_lc_is_usb_plugged(port3); ++ xhci_port1 = tb_lc_is_xhci_connected(port1); ++ xhci_port3 = tb_lc_is_xhci_connected(port3); ++ ++ /* Figure out correct USB port to connect */ ++ if (usb_port1 && !xhci_port1) { ++ ret = tb_lc_xhci_connect(port1); ++ if (ret) ++ return ret; ++ } ++ if (usb_port3 && !xhci_port3) ++ return tb_lc_xhci_connect(port3); ++ } else if (tb_switch_is_titan_ridge(sw)) { ++ ret = tb_lc_xhci_connect(port1); ++ if (ret) ++ return ret; ++ return tb_lc_xhci_connect(port3); ++ } ++ ++ return 0; ++} ++ ++/** ++ * tb_switch_xhci_disconnect() - Disconnect internal xHCI ++ * @sw: Router whose xHCI to disconnect ++ * ++ * The opposite of tb_switch_xhci_connect(). Disconnects xHCI on both ++ * ports. ++ */ ++void tb_switch_xhci_disconnect(struct tb_switch *sw) ++{ ++ if (sw->generation == 3) { ++ struct tb_port *port1 = &sw->ports[1]; ++ struct tb_port *port3 = &sw->ports[3]; ++ ++ tb_lc_xhci_disconnect(port1); ++ tb_port_dbg(port1, "disconnected xHCI\n"); ++ tb_lc_xhci_disconnect(port3); ++ tb_port_dbg(port3, "disconnected xHCI\n"); ++ } ++} +diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c +index cbd0ad85ffb1..9beb47b31c75 100644 +--- a/drivers/thunderbolt/tb.c ++++ b/drivers/thunderbolt/tb.c +@@ -1054,6 +1054,8 @@ static int tb_disconnect_pci(struct tb *tb, struct tb_switch *sw) + if (WARN_ON(!tunnel)) + return -ENODEV; + ++ tb_switch_xhci_disconnect(sw); ++ + tb_tunnel_deactivate(tunnel); + list_del(&tunnel->list); + tb_tunnel_free(tunnel); +@@ -1099,6 +1101,9 @@ static int tb_tunnel_pci(struct tb *tb, struct tb_switch *sw) + if (tb_switch_pcie_l1_enable(sw)) + tb_sw_warn(sw, "failed to enable PCIe L1 for Titan Ridge\n"); + ++ if (tb_switch_xhci_connect(sw)) ++ tb_sw_warn(sw, "failed to connect xHCI\n"); ++ + list_add_tail(&tunnel->list, &tcm->tunnel_list); + return 0; + } +@@ -1256,12 +1261,18 @@ static void tb_handle_hotplug(struct work_struct *work) + tb_port_unconfigure_xdomain(port); + } else if (tb_port_is_dpout(port) || tb_port_is_dpin(port)) { + tb_dp_resource_unavailable(tb, port); ++ } else if (!port->port) { ++ tb_sw_dbg(sw, "xHCI disconnect request\n"); ++ tb_switch_xhci_disconnect(sw); + } else { + tb_port_dbg(port, + "got unplug event for disconnected port, ignoring\n"); + } + } else if (port->remote) { + tb_port_dbg(port, "got plug event for connected port, ignoring\n"); ++ } else if (!port->port && sw->authorized) { ++ tb_sw_dbg(sw, "xHCI connect request\n"); ++ tb_switch_xhci_connect(sw); + } else { + if (tb_port_is_null(port)) { + tb_port_dbg(port, "hotplug: scanning\n"); +diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h +index 44e36498b261..b6fcd8d45324 100644 +--- a/drivers/thunderbolt/tb.h ++++ b/drivers/thunderbolt/tb.h +@@ -988,6 +988,9 @@ int tb_switch_mask_clx_objections(struct tb_switch *sw); + + int tb_switch_pcie_l1_enable(struct tb_switch *sw); + ++int tb_switch_xhci_connect(struct tb_switch *sw); ++void tb_switch_xhci_disconnect(struct tb_switch *sw); ++ + int tb_wait_for_port(struct tb_port *port, bool wait_if_unplugged); + int tb_port_add_nfc_credits(struct tb_port *port, int credits); + int tb_port_clear_counter(struct tb_port *port, int counter); +@@ -1082,6 +1085,10 @@ int tb_lc_configure_xdomain(struct tb_port *port); + void tb_lc_unconfigure_xdomain(struct tb_port *port); + int tb_lc_start_lane_initialization(struct tb_port *port); + bool tb_lc_is_clx_supported(struct tb_port *port); ++bool tb_lc_is_usb_plugged(struct tb_port *port); ++bool tb_lc_is_xhci_connected(struct tb_port *port); ++int tb_lc_xhci_connect(struct tb_port *port); ++void tb_lc_xhci_disconnect(struct tb_port *port); + int tb_lc_set_wake(struct tb_switch *sw, unsigned int flags); + int tb_lc_set_sleep(struct tb_switch *sw); + bool tb_lc_lane_bonding_possible(struct tb_switch *sw); +diff --git a/drivers/thunderbolt/tb_regs.h b/drivers/thunderbolt/tb_regs.h +index 9693a6ec5950..70795a2aa9bb 100644 +--- a/drivers/thunderbolt/tb_regs.h ++++ b/drivers/thunderbolt/tb_regs.h +@@ -463,6 +463,8 @@ struct tb_regs_hop { + #define TMU_ADP_CS_6_DISABLE_TMU_OBJ_CL2 BIT(3) + + /* Plug Events registers */ ++#define TB_PLUG_EVENTS_USB_DISABLE BIT(2) ++ + #define TB_PLUG_EVENTS_PCIE_WR_DATA 0x1b + #define TB_PLUG_EVENTS_PCIE_CMD 0x1c + #define TB_PLUG_EVENTS_PCIE_CMD_DW_OFFSET_MASK GENMASK(9, 0) +@@ -502,6 +504,9 @@ struct tb_regs_hop { + #define TB_LC_POWER 0x740 + + /* Link controller registers */ ++#define TB_LC_CS_42 0x2a ++#define TB_LC_CS_42_USB_PLUGGED BIT(31) ++ + #define TB_LC_PORT_ATTR 0x8d + #define TB_LC_PORT_ATTR_BE BIT(12) + +@@ -522,4 +527,7 @@ struct tb_regs_hop { + #define TB_LC_LINK_ATTR 0x97 + #define TB_LC_LINK_ATTR_CPS BIT(18) + ++#define TB_LC_LINK_REQ 0xad ++#define TB_LC_LINK_REQ_XHCI_CONNECT BIT(31) ++ + #endif +-- +2.35.3 + diff --git a/patches.suse/thunderbolt-Add-missing-device-ID-to-tb_switch_is_al.patch b/patches.suse/thunderbolt-Add-missing-device-ID-to-tb_switch_is_al.patch new file mode 100644 index 0000000..f665d7d --- /dev/null +++ b/patches.suse/thunderbolt-Add-missing-device-ID-to-tb_switch_is_al.patch @@ -0,0 +1,33 @@ +From f1d5ec3e0eabaf961ed16516bf35e24b48cda483 Mon Sep 17 00:00:00 2001 +From: Mika Westerberg +Date: Fri, 7 Jan 2022 12:59:01 +0200 +Subject: [PATCH] thunderbolt: Add missing device ID to + tb_switch_is_alpine_ridge() +Git-commit: f1d5ec3e0eabaf961ed16516bf35e24b48cda483 +References: git-fixes +Patch-mainline: v5.18-rc1 + +tb_switch_is_alpine_ridge() is missing device ID for Intel Alpine Ridge +dual port version so add this. + +Signed-off-by: Mika Westerberg +Signed-off-by: Oliver Neukum +--- + drivers/thunderbolt/tb.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h +index 74d3b14f004e..44e36498b261 100644 +--- a/drivers/thunderbolt/tb.h ++++ b/drivers/thunderbolt/tb.h +@@ -855,6 +855,7 @@ static inline bool tb_switch_is_alpine_ridge(const struct tb_switch *sw) + if (sw->config.vendor_id == PCI_VENDOR_ID_INTEL) { + switch (sw->config.device_id) { + case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_2C_BRIDGE: ++ case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_4C_BRIDGE: + case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_LP_BRIDGE: + case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_4C_BRIDGE: + case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_2C_BRIDGE: +-- +2.35.3 + diff --git a/patches.suse/thunderbolt-Add-support-for-Intel-Maple-Ridge-single.patch b/patches.suse/thunderbolt-Add-support-for-Intel-Maple-Ridge-single.patch new file mode 100644 index 0000000..95e64ae --- /dev/null +++ b/patches.suse/thunderbolt-Add-support-for-Intel-Maple-Ridge-single.patch @@ -0,0 +1,49 @@ +From 14c7d905283744809e6b82efae2f490660a11cda Mon Sep 17 00:00:00 2001 +From: Gil Fine +Date: Thu, 8 Sep 2022 13:43:20 +0300 +Subject: [PATCH] thunderbolt: Add support for Intel Maple Ridge single port controller +Git-commit: 14c7d905283744809e6b82efae2f490660a11cda +Patch-mainline: v6.0-rc7 +References: git-fixes + +Add support for Maple Ridge discrete USB4 host controller from Intel +which has a single USB4 port (versus the already supported dual port +Maple Ridge USB4 host controller). + +Cc: stable@vger.kernel.org +Signed-off-by: Gil Fine +Signed-off-by: Mika Westerberg +Acked-by: Takashi Iwai + +--- + drivers/thunderbolt/icm.c | 1 + + drivers/thunderbolt/nhi.h | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/drivers/thunderbolt/icm.c b/drivers/thunderbolt/icm.c +index ae38f0d25a8d..572b5896caa3 100644 +--- a/drivers/thunderbolt/icm.c ++++ b/drivers/thunderbolt/icm.c +@@ -2529,6 +2529,7 @@ struct tb *icm_probe(struct tb_nhi *nhi) + tb->cm_ops = &icm_icl_ops; + break; + ++ case PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_2C_NHI: + case PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_4C_NHI: + icm->is_supported = icm_tgl_is_supported; + icm->get_mode = icm_ar_get_mode; +diff --git a/drivers/thunderbolt/nhi.h b/drivers/thunderbolt/nhi.h +index f09da5b62233..01190d9ced16 100644 +--- a/drivers/thunderbolt/nhi.h ++++ b/drivers/thunderbolt/nhi.h +@@ -55,6 +55,7 @@ extern const struct tb_nhi_ops icl_nhi_ops; + * need for the PCI quirk anymore as we will use ICM also on Apple + * hardware. + */ ++#define PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_2C_NHI 0x1134 + #define PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_4C_NHI 0x1137 + #define PCI_DEVICE_ID_INTEL_WIN_RIDGE_2C_NHI 0x157d + #define PCI_DEVICE_ID_INTEL_WIN_RIDGE_2C_BRIDGE 0x157e +-- +2.35.3 + diff --git a/patches.suse/thunderbolt-Add-support-for-Intel-Raptor-Lake.patch b/patches.suse/thunderbolt-Add-support-for-Intel-Raptor-Lake.patch new file mode 100644 index 0000000..06b0f9d --- /dev/null +++ b/patches.suse/thunderbolt-Add-support-for-Intel-Raptor-Lake.patch @@ -0,0 +1,66 @@ +From 7ec58378a985618909ffae18e4ac0de2ae625f33 Mon Sep 17 00:00:00 2001 +From: George D Sworo +Date: Wed, 1 Jun 2022 15:41:02 -0700 +Subject: [PATCH] thunderbolt: Add support for Intel Raptor Lake +Git-commit: 7ec58378a985618909ffae18e4ac0de2ae625f33 +Patch-mainline: v6.0-rc1 +References: jsc#PED-634 + +Intel Raptor Lake has the same integrated Thunderbolt/USB4 controller as +Intel Alder Lake. By default it is still using firmware based connection +manager so we can use most of the Alder Lake flows. + +Signed-off-by: George D Sworo +Signed-off-by: Mika Westerberg +Acked-by: Takashi Iwai + +--- + drivers/thunderbolt/icm.c | 2 ++ + drivers/thunderbolt/nhi.c | 4 ++++ + drivers/thunderbolt/nhi.h | 2 ++ + 3 files changed, 8 insertions(+) + +diff --git a/drivers/thunderbolt/icm.c b/drivers/thunderbolt/icm.c +index fff0c740c8f3..ae38f0d25a8d 100644 +--- a/drivers/thunderbolt/icm.c ++++ b/drivers/thunderbolt/icm.c +@@ -2516,6 +2516,8 @@ struct tb *icm_probe(struct tb_nhi *nhi) + case PCI_DEVICE_ID_INTEL_TGL_H_NHI1: + case PCI_DEVICE_ID_INTEL_ADL_NHI0: + case PCI_DEVICE_ID_INTEL_ADL_NHI1: ++ case PCI_DEVICE_ID_INTEL_RPL_NHI0: ++ case PCI_DEVICE_ID_INTEL_RPL_NHI1: + icm->is_supported = icm_tgl_is_supported; + icm->driver_ready = icm_icl_driver_ready; + icm->set_uuid = icm_icl_set_uuid; +diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c +index 1333b158a95e..cb8c9c4ae93a 100644 +--- a/drivers/thunderbolt/nhi.c ++++ b/drivers/thunderbolt/nhi.c +@@ -1410,6 +1410,10 @@ static struct pci_device_id nhi_ids[] = { + .driver_data = (kernel_ulong_t)&icl_nhi_ops }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ADL_NHI1), + .driver_data = (kernel_ulong_t)&icl_nhi_ops }, ++ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_RPL_NHI0), ++ .driver_data = (kernel_ulong_t)&icl_nhi_ops }, ++ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_RPL_NHI1), ++ .driver_data = (kernel_ulong_t)&icl_nhi_ops }, + + /* Any USB4 compliant host */ + { PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_USB4, ~0) }, +diff --git a/drivers/thunderbolt/nhi.h b/drivers/thunderbolt/nhi.h +index 69083aab2736..f09da5b62233 100644 +--- a/drivers/thunderbolt/nhi.h ++++ b/drivers/thunderbolt/nhi.h +@@ -80,6 +80,8 @@ extern const struct tb_nhi_ops icl_nhi_ops; + #define PCI_DEVICE_ID_INTEL_TGL_NHI1 0x9a1d + #define PCI_DEVICE_ID_INTEL_TGL_H_NHI0 0x9a1f + #define PCI_DEVICE_ID_INTEL_TGL_H_NHI1 0x9a21 ++#define PCI_DEVICE_ID_INTEL_RPL_NHI0 0xa73e ++#define PCI_DEVICE_ID_INTEL_RPL_NHI1 0xa76d + + #define PCI_CLASS_SERIAL_USB_USB4 0x0c0340 + +-- +2.35.3 + diff --git a/patches.suse/thunderbolt-Clarify-register-definitions-for-tb_cap_.patch b/patches.suse/thunderbolt-Clarify-register-definitions-for-tb_cap_.patch new file mode 100644 index 0000000..97a053d --- /dev/null +++ b/patches.suse/thunderbolt-Clarify-register-definitions-for-tb_cap_.patch @@ -0,0 +1,63 @@ +From 51d4d64c7ce50a501db4688b36448819755ae74d Mon Sep 17 00:00:00 2001 +From: Mario Limonciello +Date: Thu, 3 Mar 2022 07:13:27 -0600 +Subject: [PATCH] thunderbolt: Clarify register definitions for + `tb_cap_plug_events` +Git-commit: 51d4d64c7ce50a501db4688b36448819755ae74d +References: jsc#PED-531 +Patch-mainline: v5.18-rc1 + +The USB4 1.0 specification outlines the `cap_plug_events` structure as +`VSC_CS_1`. This shows that 4 bits of `VSC_CS_1` are TBT3 compatible in +USB4, but TBT3 controllers also support disabling XHCI. + +Update the names and comments to more closely match the specification. +This should not change anything functionally. + +Signed-off-by: Mario Limonciello +Signed-off-by: Mika Westerberg +Signed-off-by: Oliver Neukum +--- + drivers/thunderbolt/tb_regs.h | 18 +++++++++++------- + 1 file changed, 11 insertions(+), 7 deletions(-) + +diff --git a/drivers/thunderbolt/tb_regs.h b/drivers/thunderbolt/tb_regs.h +index 70795a2aa9bb..db3005cba203 100644 +--- a/drivers/thunderbolt/tb_regs.h ++++ b/drivers/thunderbolt/tb_regs.h +@@ -146,14 +146,14 @@ struct tb_eeprom_ctl { + + struct tb_cap_plug_events { + struct tb_cap_extended_short cap_header; +- u32 __unknown1:2; +- u32 plug_events:5; +- u32 __unknown2:25; +- u32 __unknown3; +- u32 __unknown4; ++ u32 __unknown1:2; /* VSC_CS_1 */ ++ u32 plug_events:5; /* VSC_CS_1 */ ++ u32 __unknown2:25; /* VSC_CS_1 */ ++ u32 vsc_cs_2; ++ u32 vsc_cs_3; + struct tb_eeprom_ctl eeprom_ctl; +- u32 __unknown5[7]; +- u32 drom_offset; /* 32 bit register, but eeprom addresses are 16 bit */ ++ u32 __unknown5[7]; /* VSC_CS_5 -> VSC_CS_11 */ ++ u32 drom_offset; /* VSC_CS_12: 32 bit register, but eeprom addresses are 16 bit */ + } __packed; + + /* device headers */ +@@ -464,6 +464,10 @@ struct tb_regs_hop { + + /* Plug Events registers */ + #define TB_PLUG_EVENTS_USB_DISABLE BIT(2) ++#define TB_PLUG_EVENTS_CS_1_LANE_DISABLE BIT(3) ++#define TB_PLUG_EVENTS_CS_1_DPOUT_DISABLE BIT(4) ++#define TB_PLUG_EVENTS_CS_1_LOW_DPIN_DISABLE BIT(5) ++#define TB_PLUG_EVENTS_CS_1_HIGH_DPIN_DISABLE BIT(6) + + #define TB_PLUG_EVENTS_PCIE_WR_DATA 0x1b + #define TB_PLUG_EVENTS_PCIE_CMD 0x1c +-- +2.35.3 + diff --git a/patches.suse/thunderbolt-Disable-LTTPR-on-Intel-Titan-Ridge.patch b/patches.suse/thunderbolt-Disable-LTTPR-on-Intel-Titan-Ridge.patch new file mode 100644 index 0000000..7f4e5a5 --- /dev/null +++ b/patches.suse/thunderbolt-Disable-LTTPR-on-Intel-Titan-Ridge.patch @@ -0,0 +1,55 @@ +From 3eddfc121f90e174253031594b354e5764f8a318 Mon Sep 17 00:00:00 2001 +From: Mika Westerberg +Date: Wed, 27 Oct 2021 13:29:09 +0300 +Subject: [PATCH] thunderbolt: Disable LTTPR on Intel Titan Ridge +Git-commit: 3eddfc121f90e174253031594b354e5764f8a318 +References: git-fixes +Patch-mainline: v5.18-rc1 + +Intel Titan Ridge does not disable AUX timers when it gets SET_CONFIG +with SET_LTTPR_MODE set which makes DP tunneling to fail. For this +reason disable LTTPR on Titan Ridge device side. + +Signed-off-by: Mika Westerberg +Signed-off-by: Oliver Neukum +--- + drivers/thunderbolt/tb_regs.h | 1 + + drivers/thunderbolt/tunnel.c | 10 ++++++++++ + 2 files changed, 11 insertions(+) + +diff --git a/drivers/thunderbolt/tb_regs.h b/drivers/thunderbolt/tb_regs.h +index a74f4878d3e7..9693a6ec5950 100644 +--- a/drivers/thunderbolt/tb_regs.h ++++ b/drivers/thunderbolt/tb_regs.h +@@ -389,6 +389,7 @@ struct tb_regs_port_header { + #define DP_COMMON_CAP_1_LANE 0x0 + #define DP_COMMON_CAP_2_LANES 0x1 + #define DP_COMMON_CAP_4_LANES 0x2 ++#define DP_COMMON_CAP_LTTPR_NS BIT(27) + #define DP_COMMON_CAP_DPRX_DONE BIT(31) + + /* PCIe adapter registers */ +diff --git a/drivers/thunderbolt/tunnel.c b/drivers/thunderbolt/tunnel.c +index a473cc7d9a8d..118742ec93ed 100644 +--- a/drivers/thunderbolt/tunnel.c ++++ b/drivers/thunderbolt/tunnel.c +@@ -580,6 +580,16 @@ static int tb_dp_xchg_caps(struct tb_tunnel *tunnel) + out_dp_cap = tb_dp_cap_set_lanes(out_dp_cap, new_lanes); + } + ++ /* ++ * Titan Ridge does not disable AUX timers when it gets ++ * SET_CONFIG with SET_LTTPR_MODE set. This causes problems with ++ * DP tunneling. ++ */ ++ if (tb_route(out->sw) && tb_switch_is_titan_ridge(out->sw)) { ++ out_dp_cap |= DP_COMMON_CAP_LTTPR_NS; ++ tb_port_dbg(out, "disabling LTTPR\n"); ++ } ++ + return tb_port_write(in, &out_dp_cap, TB_CFG_PORT, + in->cap_adap + DP_REMOTE_CAP, 1); + } +-- +2.35.3 + diff --git a/patches.suse/thunderbolt-Do-not-make-DROM-read-success-compulsory.patch b/patches.suse/thunderbolt-Do-not-make-DROM-read-success-compulsory.patch new file mode 100644 index 0000000..86a523f --- /dev/null +++ b/patches.suse/thunderbolt-Do-not-make-DROM-read-success-compulsory.patch @@ -0,0 +1,44 @@ +From 6915812bbd109787ebdb865561dc9164d4b01f56 Mon Sep 17 00:00:00 2001 +From: Mario Limonciello +Date: Thu, 3 Mar 2022 07:13:26 -0600 +Subject: [PATCH] thunderbolt: Do not make DROM read success compulsory +Git-commit: 6915812bbd109787ebdb865561dc9164d4b01f56 +References: jsc#PED-531 +Patch-mainline: v5.18-rc1 + +The USB4 specification doesn't make any requirements that reading +a device router's DROM is needed for the operation of the device. + +Other connection manager solutions don't necessarily read it or gate +the usability of the device on whether it was read. + +So make failures when reading the DROM show warnings but not +fail the initialization of the router. + +Signed-off-by: Mario Limonciello +Signed-off-by: Mika Westerberg +Signed-off-by: Oliver Neukum +--- + drivers/thunderbolt/switch.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c +index 294518af4ee4..ac87e8b50e52 100644 +--- a/drivers/thunderbolt/switch.c ++++ b/drivers/thunderbolt/switch.c +@@ -2784,10 +2784,8 @@ int tb_switch_add(struct tb_switch *sw) + + /* read drom */ + ret = tb_drom_read(sw); +- if (ret) { +- dev_err(&sw->dev, "reading DROM failed\n"); +- return ret; +- } ++ if (ret) ++ dev_warn(&sw->dev, "reading DROM failed: %d\n", ret); + tb_sw_dbg(sw, "uid: %#llx\n", sw->uid); + + tb_check_quirks(sw); +-- +2.35.3 + diff --git a/patches.suse/thunderbolt-Do-not-resume-routers-if-UID-is-not-set.patch b/patches.suse/thunderbolt-Do-not-resume-routers-if-UID-is-not-set.patch new file mode 100644 index 0000000..2677f52 --- /dev/null +++ b/patches.suse/thunderbolt-Do-not-resume-routers-if-UID-is-not-set.patch @@ -0,0 +1,46 @@ +From a283de3ec646f19b09f3c8e4c8f57c0e017c9b2b Mon Sep 17 00:00:00 2001 +From: Mario Limonciello +Date: Thu, 3 Mar 2022 07:13:25 -0600 +Subject: [PATCH] thunderbolt: Do not resume routers if UID is not set +Git-commit: a283de3ec646f19b09f3c8e4c8f57c0e017c9b2b +References: jsc#PED-531 +Patch-mainline: v5.18-rc1 + +Routers might not have a UID set if the DROM read failed during +initialization previously. + +Normally upon resume the UID is re-read to confirm it's the same +device connected. +* If the DROM read failed during init but then succeeded during + resume it could either be a new device or faulty device +* If the DROM read failed during init and also failed during resume + it might be a different device plugged in all together. + +Detect this situation and prevent re-using the same configuration in +these cirucmstances. + +Signed-off-by: Mario Limonciello +Signed-off-by: Mika Westerberg +Signed-off-by: Oliver Neukum +--- + drivers/thunderbolt/switch.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c +index b5fb3e76ed09..294518af4ee4 100644 +--- a/drivers/thunderbolt/switch.c ++++ b/drivers/thunderbolt/switch.c +@@ -2980,6 +2980,10 @@ int tb_switch_resume(struct tb_switch *sw) + return err; + } + ++ /* We don't have any way to confirm this was the same device */ ++ if (!sw->uid) ++ return -ENODEV; ++ + if (tb_switch_is_usb4(sw)) + err = usb4_switch_read_uid(sw, &uid); + else +-- +2.35.3 + diff --git a/patches.suse/thunderbolt-Drop-duplicate-NULL-checks-around-nvmem_.patch b/patches.suse/thunderbolt-Drop-duplicate-NULL-checks-around-nvmem_.patch new file mode 100644 index 0000000..369f6d0 --- /dev/null +++ b/patches.suse/thunderbolt-Drop-duplicate-NULL-checks-around-nvmem_.patch @@ -0,0 +1,42 @@ +From 4c49300d8e676702cc097784007bf11735821d6d Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Sun, 20 Feb 2022 15:15:27 +0000 +Subject: [PATCH] thunderbolt: Drop duplicate NULL checks around + nvmem_unregister() +Git-commit: 4c49300d8e676702cc097784007bf11735821d6d +References: jsc#PED-531 +Patch-mainline: v5.18-rc1 + +Since nvmem_unregister() checks for NULL, no need to repeat in +the caller. Drop duplicate NULL checks. + +Acked-by: Mika Westerberg +Signed-off-by: Andy Shevchenko +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20220220151527.17216-14-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/thunderbolt/nvm.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/drivers/thunderbolt/nvm.c b/drivers/thunderbolt/nvm.c +index 3a5336913cca..b3f310389378 100644 +--- a/drivers/thunderbolt/nvm.c ++++ b/drivers/thunderbolt/nvm.c +@@ -154,10 +154,8 @@ int tb_nvm_add_non_active(struct tb_nvm *nvm, size_t size, + void tb_nvm_free(struct tb_nvm *nvm) + { + if (nvm) { +- if (nvm->non_active) +- nvmem_unregister(nvm->non_active); +- if (nvm->active) +- nvmem_unregister(nvm->active); ++ nvmem_unregister(nvm->non_active); ++ nvmem_unregister(nvm->active); + vfree(nvm->buf); + ida_simple_remove(&nvm_ida, nvm->id); + } +-- +2.35.3 + diff --git a/patches.suse/thunderbolt-Explicitly-reset-plug-events-delay-back-.patch b/patches.suse/thunderbolt-Explicitly-reset-plug-events-delay-back-.patch new file mode 100644 index 0000000..16ad609 --- /dev/null +++ b/patches.suse/thunderbolt-Explicitly-reset-plug-events-delay-back-.patch @@ -0,0 +1,40 @@ +From 31f87f705b3c1635345d8e8a493697099b43e508 Mon Sep 17 00:00:00 2001 +From: Mario Limonciello +Date: Wed, 21 Sep 2022 09:54:32 -0500 +Subject: [PATCH] thunderbolt: Explicitly reset plug events delay back to USB4 spec value +Git-commit: 31f87f705b3c1635345d8e8a493697099b43e508 +Patch-mainline: v6.0 +References: git-fixes + +If any software has interacted with the USB4 registers before the Linux +USB4 CM runs, it may have modified the plug events delay. It has been +observed that if this value too large, it's possible that hotplugged +devices will negotiate a fallback mode instead in Linux. + +To prevent this, explicitly align the plug events delay with the USB4 +spec value of 10ms. + +Cc: stable@vger.kernel.org +Signed-off-by: Mario Limonciello +Signed-off-by: Mika Westerberg +Acked-by: Takashi Iwai + +--- + drivers/thunderbolt/switch.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c +index c63c1f4ff9dc..77d7f07ca075 100644 +--- a/drivers/thunderbolt/switch.c ++++ b/drivers/thunderbolt/switch.c +@@ -2413,6 +2413,7 @@ int tb_switch_configure(struct tb_switch *sw) + * additional capabilities. + */ + sw->config.cmuv = USB4_VERSION_1_0; ++ sw->config.plug_events_delay = 0xa; + + /* Enumerate the switch */ + ret = tb_sw_write(sw, (u32 *)&sw->config + 1, TB_CFG_SWITCH, +-- +2.35.3 + diff --git a/patches.suse/thunderbolt-Fix-buffer-allocation-of-devices-with-no.patch b/patches.suse/thunderbolt-Fix-buffer-allocation-of-devices-with-no.patch new file mode 100644 index 0000000..84ca8f6 --- /dev/null +++ b/patches.suse/thunderbolt-Fix-buffer-allocation-of-devices-with-no.patch @@ -0,0 +1,40 @@ +From 93bf344f66995ef816bd63c165fa9ac1ea4fcb3d Mon Sep 17 00:00:00 2001 +From: Gil Fine +Date: Mon, 9 May 2022 23:49:03 +0300 +Subject: [PATCH] thunderbolt: Fix buffer allocation of devices with no + DisplayPort adapters +Git-commit: 93bf344f66995ef816bd63c165fa9ac1ea4fcb3d +References: git-fixes +Patch-mainline: v5.19-rc1 + +For the case of a device without DisplayPort adapters we calculate +incorrectly the amount of buffers. Fix the calculation for this case. + +Signed-off-by: Gil Fine +Signed-off-by: Mika Westerberg +Signed-off-by: Oliver Neukum +--- + drivers/thunderbolt/tunnel.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/thunderbolt/tunnel.c b/drivers/thunderbolt/tunnel.c +index 8ccd70920b6a..2c3cf7fc3357 100644 +--- a/drivers/thunderbolt/tunnel.c ++++ b/drivers/thunderbolt/tunnel.c +@@ -102,8 +102,11 @@ static unsigned int tb_available_credits(const struct tb_port *port, + * Maximum number of DP streams possible through the + * lane adapter. + */ +- ndp = (credits - (usb3 + pcie + spare)) / +- (sw->min_dp_aux_credits + sw->min_dp_main_credits); ++ if (sw->min_dp_aux_credits + sw->min_dp_main_credits) ++ ndp = (credits - (usb3 + pcie + spare)) / ++ (sw->min_dp_aux_credits + sw->min_dp_main_credits); ++ else ++ ndp = 0; + } else { + ndp = 0; + } +-- +2.35.3 + diff --git a/patches.suse/thunderbolt-Remove-useless-DMA-32-fallback-configura.patch b/patches.suse/thunderbolt-Remove-useless-DMA-32-fallback-configura.patch new file mode 100644 index 0000000..cf04048 --- /dev/null +++ b/patches.suse/thunderbolt-Remove-useless-DMA-32-fallback-configura.patch @@ -0,0 +1,50 @@ +From 97486e981ffb865f8845af3c24d5fb19f1ea37e8 Mon Sep 17 00:00:00 2001 +From: Christophe JAILLET +Date: Sun, 9 Jan 2022 13:51:31 +0100 +Subject: [PATCH] thunderbolt: Remove useless DMA-32 fallback configuration +Git-commit: 97486e981ffb865f8845af3c24d5fb19f1ea37e8 +References: jsc#PED-531 +Patch-mainline: v5.18-rc1 + +As stated in [1], dma_set_mask() with a 64-bit mask never fails if +dev->dma_mask is non-NULL. +So, if it fails, the 32 bits case will also fail for the same reason. + +Simplify code and remove some dead code accordingly. + +While at it, include directly instead on relying on +indirect inclusion. + +[1]: https://lkml.org/lkml/2021/6/7/398 + +Signed-off-by: Christophe JAILLET +Signed-off-by: Mika Westerberg +Signed-off-by: Oliver Neukum +--- + drivers/thunderbolt/nhi.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c +index c73da0532be4..4a582183f675 100644 +--- a/drivers/thunderbolt/nhi.c ++++ b/drivers/thunderbolt/nhi.c +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -1229,8 +1230,6 @@ static int nhi_probe(struct pci_dev *pdev, const struct pci_device_id *id) + spin_lock_init(&nhi->lock); + + res = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); +- if (res) +- res = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); + if (res) { + dev_err(&pdev->dev, "failed to set DMA mask\n"); + return res; +-- +2.35.3 + diff --git a/patches.suse/thunderbolt-Replace-acpi_bus_get_device.patch b/patches.suse/thunderbolt-Replace-acpi_bus_get_device.patch new file mode 100644 index 0000000..890004d --- /dev/null +++ b/patches.suse/thunderbolt-Replace-acpi_bus_get_device.patch @@ -0,0 +1,45 @@ +From 7f7b571becf3731dfa9aa50bed420e0c988e511d Mon Sep 17 00:00:00 2001 +From: "Rafael J. Wysocki" +Date: Tue, 1 Feb 2022 20:12:30 +0100 +Subject: [PATCH] thunderbolt: Replace acpi_bus_get_device() +Git-commit: 7f7b571becf3731dfa9aa50bed420e0c988e511d +References: jsc#PED-531 +Patch-mainline: v5.18-rc1 + +Replace acpi_bus_get_device() that is going to be dropped with +acpi_fetch_acpi_dev(). + +No intentional functional impact. + +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Mika Westerberg +Signed-off-by: Oliver Neukum +--- + drivers/thunderbolt/acpi.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/thunderbolt/acpi.c b/drivers/thunderbolt/acpi.c +index 79b5abf9d042..c89daac0ad8c 100644 +--- a/drivers/thunderbolt/acpi.c ++++ b/drivers/thunderbolt/acpi.c +@@ -14,15 +14,15 @@ + static acpi_status tb_acpi_add_link(acpi_handle handle, u32 level, void *data, + void **return_value) + { ++ struct acpi_device *adev = acpi_fetch_acpi_dev(handle); + struct fwnode_reference_args args; + struct fwnode_handle *fwnode; + struct tb_nhi *nhi = data; +- struct acpi_device *adev; + struct pci_dev *pdev; + struct device *dev; + int ret; + +- if (acpi_bus_get_device(handle, &adev)) ++ if (!adev) + return AE_OK; + + fwnode = acpi_fwnode_handle(adev); +-- +2.35.3 + diff --git a/patches.suse/thunderbolt-Replace-usage-of-found-with-dedicated-li.patch b/patches.suse/thunderbolt-Replace-usage-of-found-with-dedicated-li.patch new file mode 100644 index 0000000..9e5ecc7 --- /dev/null +++ b/patches.suse/thunderbolt-Replace-usage-of-found-with-dedicated-li.patch @@ -0,0 +1,64 @@ +From 03941ed91c7231e4973fb50de6c349974405df4e Mon Sep 17 00:00:00 2001 +From: Jakob Koschel +Date: Thu, 24 Mar 2022 08:27:00 +0100 +Subject: [PATCH] thunderbolt: Replace usage of found with dedicated list + iterator variable +Git-commit: 03941ed91c7231e4973fb50de6c349974405df4e +References: jsc#PED-531 jsc#PED-1211 +Patch-mainline: v5.19-rc1 + +To move the list iterator variable into the list_for_each_entry_*() +macro in the future it should be avoided to use the list iterator +variable after the loop body. + +To *never* use the list iterator variable after the loop it was +concluded to use a separate iterator variable instead of a +found boolean [1]. + +This removes the need to use a found variable and simply checking if +the variable was set, can determine if the break/goto was hit. + +Link: https://lore.kernel.org/all/CAHk-=wgRr_D8CB-D9Kg-c=EHreAsk5SqXPwr9Y7k9sA6cWXJ6w@mail.gmail.com/ +Signed-off-by: Jakob Koschel +Signed-off-by: Mika Westerberg +Signed-off-by: Oliver Neukum +--- + drivers/thunderbolt/ctl.c | 15 +++++++-------- + 1 file changed, 7 insertions(+), 8 deletions(-) + +diff --git a/drivers/thunderbolt/ctl.c b/drivers/thunderbolt/ctl.c +index 4986edfbdf67..e92c658dba1c 100644 +--- a/drivers/thunderbolt/ctl.c ++++ b/drivers/thunderbolt/ctl.c +@@ -158,21 +158,20 @@ static bool tb_cfg_request_is_active(struct tb_cfg_request *req) + static struct tb_cfg_request * + tb_cfg_request_find(struct tb_ctl *ctl, struct ctl_pkg *pkg) + { +- struct tb_cfg_request *req; +- bool found = false; ++ struct tb_cfg_request *req = NULL, *iter; + + mutex_lock(&pkg->ctl->request_queue_lock); +- list_for_each_entry(req, &pkg->ctl->request_queue, list) { +- tb_cfg_request_get(req); +- if (req->match(req, pkg)) { +- found = true; ++ list_for_each_entry(iter, &pkg->ctl->request_queue, list) { ++ tb_cfg_request_get(iter); ++ if (iter->match(iter, pkg)) { ++ req = iter; + break; + } +- tb_cfg_request_put(req); ++ tb_cfg_request_put(iter); + } + mutex_unlock(&pkg->ctl->request_queue_lock); + +- return found ? req : NULL; ++ return req; + } + + /* utility functions */ +-- +2.35.3 + diff --git a/patches.suse/thunderbolt-Retry-DROM-reads-for-more-failure-scenar.patch b/patches.suse/thunderbolt-Retry-DROM-reads-for-more-failure-scenar.patch new file mode 100644 index 0000000..0c57061 --- /dev/null +++ b/patches.suse/thunderbolt-Retry-DROM-reads-for-more-failure-scenar.patch @@ -0,0 +1,75 @@ +From e87491a9fd4e33eaf18ef69d8295bb07b31452b2 Mon Sep 17 00:00:00 2001 +From: Mario Limonciello +Date: Thu, 3 Mar 2022 07:13:24 -0600 +Subject: [PATCH] thunderbolt: Retry DROM reads for more failure scenarios +Git-commit: e87491a9fd4e33eaf18ef69d8295bb07b31452b2 +References: jsc#PED-531 +Patch-mainline: v5.18-rc1 + +Currently DROM reads are only retried in the case that parsing failed. +However if the size or CRC fails, then there should also be a retry. + +This helps with reading the DROM on TBT3 devices connected to AMD +Yellow Carp which will sometimes fail on the first attempt. + +Signed-off-by: Mario Limonciello +Signed-off-by: Mika Westerberg +Signed-off-by: Oliver Neukum +--- + drivers/thunderbolt/eeprom.c | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +diff --git a/drivers/thunderbolt/eeprom.c b/drivers/thunderbolt/eeprom.c +index 470885e6f1c8..10cdbcb55df9 100644 +--- a/drivers/thunderbolt/eeprom.c ++++ b/drivers/thunderbolt/eeprom.c +@@ -553,9 +553,9 @@ static int tb_drom_parse(struct tb_switch *sw) + crc = tb_crc8((u8 *) &header->uid, 8); + if (crc != header->uid_crc8) { + tb_sw_warn(sw, +- "DROM UID CRC8 mismatch (expected: %#x, got: %#x), aborting\n", ++ "DROM UID CRC8 mismatch (expected: %#x, got: %#x)\n", + header->uid_crc8, crc); +- return -EINVAL; ++ return -EILSEQ; + } + if (!sw->uid) + sw->uid = header->uid; +@@ -654,6 +654,7 @@ int tb_drom_read(struct tb_switch *sw) + sw->drom = kzalloc(size, GFP_KERNEL); + if (!sw->drom) + return -ENOMEM; ++read: + res = tb_drom_read_n(sw, 0, sw->drom, size); + if (res) + goto err; +@@ -662,7 +663,11 @@ int tb_drom_read(struct tb_switch *sw) + header = (void *) sw->drom; + + if (header->data_len + TB_DROM_DATA_START != size) { +- tb_sw_warn(sw, "drom size mismatch, aborting\n"); ++ tb_sw_warn(sw, "drom size mismatch\n"); ++ if (retries--) { ++ msleep(100); ++ goto read; ++ } + goto err; + } + +@@ -683,11 +688,9 @@ int tb_drom_read(struct tb_switch *sw) + + /* If the DROM parsing fails, wait a moment and retry once */ + if (res == -EILSEQ && retries--) { +- tb_sw_warn(sw, "parsing DROM failed, retrying\n"); ++ tb_sw_warn(sw, "parsing DROM failed\n"); + msleep(100); +- res = tb_drom_read_n(sw, 0, sw->drom, size); +- if (!res) +- goto parse; ++ goto read; + } + + if (!res) +-- +2.35.3 + diff --git a/patches.suse/thunderbolt-Use-decimal-number-with-port-numbers.patch b/patches.suse/thunderbolt-Use-decimal-number-with-port-numbers.patch new file mode 100644 index 0000000..1ecf5cd --- /dev/null +++ b/patches.suse/thunderbolt-Use-decimal-number-with-port-numbers.patch @@ -0,0 +1,33 @@ +From ebe99c0f297dfc0f349f54dae850b83985539de5 Mon Sep 17 00:00:00 2001 +From: Mika Westerberg +Date: Fri, 1 Apr 2022 13:36:47 +0300 +Subject: [PATCH] thunderbolt: Use decimal number with port numbers +Git-commit: ebe99c0f297dfc0f349f54dae850b83985539de5 +References: jsc#PED-531 jsc#PED-1211 +Patch-mainline: v5.19-rc1 + +This makes it consistent with the other logging functions. + +Signed-off-by: Mika Westerberg +Tested-by: Brad Campbell +Signed-off-by: Oliver Neukum +--- + drivers/thunderbolt/tb.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h +index b6fcd8d45324..ad025ff142ba 100644 +--- a/drivers/thunderbolt/tb.h ++++ b/drivers/thunderbolt/tb.h +@@ -674,7 +674,7 @@ static inline int tb_port_write(struct tb_port *port, const void *buffer, + #define __TB_PORT_PRINT(level, _port, fmt, arg...) \ + do { \ + const struct tb_port *__port = (_port); \ +- level(__port->sw->tb, "%llx:%x: " fmt, \ ++ level(__port->sw->tb, "%llx:%u: " fmt, \ + tb_route(__port->sw), __port->port, ## arg); \ + } while (0) + #define tb_port_WARN(port, fmt, arg...) \ +-- +2.35.3 + diff --git a/patches.suse/tools-headers-cpufeatures-Sync-with-the-kernel-sourc.patch b/patches.suse/tools-headers-cpufeatures-Sync-with-the-kernel-sourc.patch new file mode 100644 index 0000000..eed7c1a --- /dev/null +++ b/patches.suse/tools-headers-cpufeatures-Sync-with-the-kernel-sourc.patch @@ -0,0 +1,39 @@ +From: Arnaldo Carvalho de Melo +Date: Thu, 1 Jul 2021 13:39:15 -0300 +Subject: tools headers cpufeatures: Sync with the kernel sources +Patch-mainline: v5.17-rc1 +Git-commit: 486e5ed88827dabd295cd55f368d513ee8c30eb1 +References: jsc#PED-1408 + +To pick the changes from: + + d341db8f48ea4331 ("x86/cpufeatures: Add AMD Collaborative Processor Performance Control feature flag") + +This only causes these perf files to be rebuilt: + + CC /tmp/build/perf/bench/mem-memcpy-x86-64-asm.o + CC /tmp/build/perf/bench/mem-memset-x86-64-asm.o + +And addresses this perf build warning: + + Warning: Kernel ABI header at 'tools/arch/x86/include/asm/cpufeatures.h' differs from latest version at 'arch/x86/include/asm/cpufeatures.h' + diff -u tools/arch/x86/include/asm/cpufeatures.h arch/x86/include/asm/cpufeatures.h + +Cc: Huang Rui +Cc: Rafael J. Wysocki +Signed-off-by: Arnaldo Carvalho de Melo +Acked-by: Lee, Chun-Yi +--- + tools/arch/x86/include/asm/cpufeatures.h | 1 + + 1 file changed, 1 insertion(+) + +--- a/tools/arch/x86/include/asm/cpufeatures.h ++++ b/tools/arch/x86/include/asm/cpufeatures.h +@@ -313,6 +313,7 @@ + #define X86_FEATURE_AMD_SSBD (13*32+24) /* "" Speculative Store Bypass Disable */ + #define X86_FEATURE_VIRT_SSBD (13*32+25) /* Virtualized Speculative Store Bypass Disable */ + #define X86_FEATURE_AMD_SSB_NO (13*32+26) /* "" Speculative Store Bypass is fixed in hardware. */ ++#define X86_FEATURE_CPPC (13*32+27) /* Collaborative Processor Performance Control */ + + /* Thermal and Power Management Leaf, CPUID level 0x00000006 (EAX), word 14 */ + #define X86_FEATURE_DTHERM (14*32+ 0) /* Digital Thermal Sensor */ diff --git a/patches.suse/tracing-Fix-smatch-warning-for-do-while-check-in-eve.patch b/patches.suse/tracing-Fix-smatch-warning-for-do-while-check-in-eve.patch new file mode 100644 index 0000000..c0a96a3 --- /dev/null +++ b/patches.suse/tracing-Fix-smatch-warning-for-do-while-check-in-eve.patch @@ -0,0 +1,48 @@ +From b59f2f2b865cedd6d1641394b9cd84399bd738ff Mon Sep 17 00:00:00 2001 +From: Tom Zanussi +Date: Thu, 27 Jan 2022 15:44:16 -0600 +Subject: [PATCH] tracing: Fix smatch warning for do while check in + event_hist_trigger_parse() +Git-commit: b59f2f2b865cedd6d1641394b9cd84399bd738ff +References: git-fixes +Patch-mainline: v5.17-rc2 + +The patch ec5ce0987541: "tracing: Allow whitespace to surround hist +trigger filter" from Jan 15, 2018, leads to the following Smatch +static checker warning: + + kernel/trace/trace_events_hist.c:6199 event_hist_trigger_parse() + warn: 'p' can't be NULL. + +Since p is always checked for a NULL value at the top of loop and +nothing in the rest of the loop will set it to NULL, the warning +is correct and might as well be 1 to silence the warning. + +Link: https://lkml.kernel.org/r/a1d4c79766c0cf61e20438dc35244d216633fef6.1643319703.git.zanussi@kernel.org + +Fixes: ec5ce09875410 ("tracing: Allow whitespace to surround hist trigger filter") +Reported-by: kernel test robot +Reported-by: Dan Carpenter +Signed-off-by: Tom Zanussi +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Oliver Neukum +--- + kernel/trace/trace_events_hist.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c +index e0860146dd39..b894d68082ea 100644 +--- a/kernel/trace/trace_events_hist.c ++++ b/kernel/trace/trace_events_hist.c +@@ -6199,7 +6199,7 @@ static int event_hist_trigger_parse(struct event_command *cmd_ops, + continue; + } + break; +- } while (p); ++ } while (1); + + if (!p) + param = NULL; +-- +2.35.3 + diff --git a/patches.suse/tracing-Tag-trace_percpu_buffer-as-a-percpu-pointer.patch b/patches.suse/tracing-Tag-trace_percpu_buffer-as-a-percpu-pointer.patch new file mode 100644 index 0000000..bf420ae --- /dev/null +++ b/patches.suse/tracing-Tag-trace_percpu_buffer-as-a-percpu-pointer.patch @@ -0,0 +1,54 @@ +From f28439db470cca8b6b082239314e9fd10bd39034 Mon Sep 17 00:00:00 2001 +From: "Naveen N. Rao" +Date: Thu, 23 Dec 2021 16:04:39 +0530 +Subject: [PATCH] tracing: Tag trace_percpu_buffer as a percpu pointer +Git-commit: f28439db470cca8b6b082239314e9fd10bd39034 +References: git-fixes +Patch-mainline: v5.16 + +Tag trace_percpu_buffer as a percpu pointer to resolve warnings +reported by sparse: + /linux/kernel/trace/trace.c:3218:46: warning: incorrect type in initializer (different address spaces) + /linux/kernel/trace/trace.c:3218:46: expected void const [noderef] __percpu *__vpp_verify + /linux/kernel/trace/trace.c:3218:46: got struct trace_buffer_struct * + /linux/kernel/trace/trace.c:3234:9: warning: incorrect type in initializer (different address spaces) + /linux/kernel/trace/trace.c:3234:9: expected void const [noderef] __percpu *__vpp_verify + /linux/kernel/trace/trace.c:3234:9: got int * + +Link: https://lkml.kernel.org/r/ebabd3f23101d89cb75671b68b6f819f5edc830b.1640255304.git.naveen.n.rao@linux.vnet.ibm.com + +Cc: stable@vger.kernel.org +Reported-by: kernel test robot +Fixes: 07d777fe8c398 ("tracing: Add percpu buffers for trace_printk()") +Signed-off-by: Naveen N. Rao +Signed-off-by: Steven Rostedt +Signed-off-by: Oliver Neukum +--- + kernel/trace/trace.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c +index e1f55851e53f..78ea542ce3bc 100644 +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -3207,7 +3207,7 @@ struct trace_buffer_struct { + char buffer[4][TRACE_BUF_SIZE]; + }; + +-static struct trace_buffer_struct *trace_percpu_buffer; ++static struct trace_buffer_struct __percpu *trace_percpu_buffer; + + /* + * This allows for lockless recording. If we're nested too deeply, then +@@ -3236,7 +3236,7 @@ static void put_trace_buf(void) + + static int alloc_percpu_trace_buffer(void) + { +- struct trace_buffer_struct *buffers; ++ struct trace_buffer_struct __percpu *buffers; + + if (trace_percpu_buffer) + return 0; +-- +2.35.3 + diff --git a/patches.suse/tty-serial-atmel-Preserve-previous-USART-mode-if-RS4.patch b/patches.suse/tty-serial-atmel-Preserve-previous-USART-mode-if-RS4.patch new file mode 100644 index 0000000..99d5e1b --- /dev/null +++ b/patches.suse/tty-serial-atmel-Preserve-previous-USART-mode-if-RS4.patch @@ -0,0 +1,74 @@ +From 692a8ebcfc24f4a5bea0eb2967e450f584193da6 Mon Sep 17 00:00:00 2001 +From: Sergiu Moga +Date: Wed, 24 Aug 2022 17:29:03 +0300 +Subject: [PATCH] tty: serial: atmel: Preserve previous USART mode if RS485 disabled +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 692a8ebcfc24f4a5bea0eb2967e450f584193da6 +Patch-mainline: v6.0-rc4 +References: git-fixes + +Whenever the atmel_rs485_config() driver method would be called, +the USART mode is reset to normal mode before even checking if +RS485 flag is set, thus resulting in losing the previous USART +mode in the case where the checking fails. + +Some tools, such as `linux-serial-test`, lead to the driver calling +this method when doing the setup of the serial port: after setting the +port mode (Hardware Flow Control, Normal Mode, RS485 Mode, etc.), +`linux-serial-test` tries to enable/disable RS485 depending on +the commandline arguments that were passed. + +Example of how this issue could reveal itself: +When doing a serial communication with Hardware Flow Control through +`linux-serial-test`, the tool would lead to the driver roughly doing +the following: +- set the corresponding bit to 1 (ATMEL_US_USMODE_HWHS bit in the +ATMEL_US_MR register) through the atmel_set_termios() to enable +Hardware Flow Control +- disable RS485 through the atmel_config_rs485() method +Thus, when the latter is called, the mode will be reset and the +previously set bit is unset, leaving USART in normal mode instead of +the expected Hardware Flow Control mode. + +This fix ensures that this reset is only done if the checking for +RS485 succeeds and that the previous mode is preserved otherwise. + +Fixes: e8faff7330a35 ("ARM: 6092/1: atmel_serial: support for RS485 communications") +Cc: stable +Reviewed-by: Ilpo Järvinen +Signed-off-by: Sergiu Moga +Link: https://lore.kernel.org/r/20220824142902.502596-1-sergiu.moga@microchip.com +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/tty/serial/atmel_serial.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c +index 30ba9eef7b39..7450d3853031 100644 +--- a/drivers/tty/serial/atmel_serial.c ++++ b/drivers/tty/serial/atmel_serial.c +@@ -294,9 +294,6 @@ static int atmel_config_rs485(struct uart_port *port, struct ktermios *termios, + + mode = atmel_uart_readl(port, ATMEL_US_MR); + +- /* Resetting serial mode to RS232 (0x0) */ +- mode &= ~ATMEL_US_USMODE; +- + if (rs485conf->flags & SER_RS485_ENABLED) { + dev_dbg(port->dev, "Setting UART to RS485\n"); + if (rs485conf->flags & SER_RS485_RX_DURING_TX) +@@ -306,6 +303,7 @@ static int atmel_config_rs485(struct uart_port *port, struct ktermios *termios, + + atmel_uart_writel(port, ATMEL_US_TTGR, + rs485conf->delay_rts_after_send); ++ mode &= ~ATMEL_US_USMODE; + mode |= ATMEL_US_USMODE_RS485; + } else { + dev_dbg(port->dev, "Setting UART to RS232\n"); +-- +2.35.3 + diff --git a/patches.suse/tty-serial-fsl_lpuart-disable-dma-rx-tx-use-flags-in.patch b/patches.suse/tty-serial-fsl_lpuart-disable-dma-rx-tx-use-flags-in.patch new file mode 100644 index 0000000..c352530 --- /dev/null +++ b/patches.suse/tty-serial-fsl_lpuart-disable-dma-rx-tx-use-flags-in.patch @@ -0,0 +1,102 @@ +From 316ae95c175a7d770d1bfe4c011192712f57aa4a Mon Sep 17 00:00:00 2001 +From: Sherry Sun +Date: Tue, 20 Sep 2022 19:17:03 +0800 +Subject: [PATCH] tty: serial: fsl_lpuart: disable dma rx/tx use flags in lpuart_dma_shutdown +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 316ae95c175a7d770d1bfe4c011192712f57aa4a +Patch-mainline: v6.1-rc1 +References: git-fixes + +lpuart_dma_shutdown tears down lpuart dma, but lpuart_flush_buffer can +still occur which in turn tries to access dma apis if lpuart_dma_tx_use +flag is true. At this point since dma is torn down, these dma apis can +abort. Set lpuart_dma_tx_use and the corresponding rx flag +lpuart_dma_rx_use to false in lpuart_dma_shutdown so that dmas are not +accessed after they are relinquished. + +Otherwise, when try to kill btattach, kernel may panic. This patch may +fix this issue. +root@imx8ulpevk:~# btattach -B /dev/ttyLP2 -S 115200 +^C[ 90.182296] Internal error: synchronous external abort: 96000210 [#1] PREEMPT SMP +[ 90.189806] Modules linked in: moal(O) mlan(O) +[ 90.194258] CPU: 0 PID: 503 Comm: btattach Tainted: G O 5.15.32-06136-g34eecdf2f9e4 #37 +[ 90.203554] Hardware name: NXP i.MX8ULP 9X9 EVK (DT) +[ 90.208513] pstate: 600000c5 (nZCv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--) +[ 90.215470] pc : fsl_edma3_disable_request+0x8/0x60 +[ 90.220358] lr : fsl_edma3_terminate_all+0x34/0x20c +[ 90.225237] sp : ffff800013f0bac0 +[ 90.228548] x29: ffff800013f0bac0 x28: 0000000000000001 x27: ffff000008404800 +[ 90.235681] x26: ffff000008404960 x25: ffff000008404a08 x24: ffff000008404a00 +[ 90.242813] x23: ffff000008404a60 x22: 0000000000000002 x21: 0000000000000000 +[ 90.249946] x20: ffff800013f0baf8 x19: ffff00000559c800 x18: 0000000000000000 +[ 90.257078] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000 +[ 90.264211] x14: 0000000000000003 x13: 0000000000000000 x12: 0000000000000040 +[ 90.271344] x11: ffff00000600c248 x10: ffff800013f0bb10 x9 : ffff000057bcb090 +[ 90.278477] x8 : fffffc0000241a08 x7 : ffff00000534ee00 x6 : ffff000008404804 +[ 90.285609] x5 : 0000000000000000 x4 : 0000000000000000 x3 : ffff0000055b3480 +[ 90.292742] x2 : ffff8000135c0000 x1 : ffff00000534ee00 x0 : ffff00000559c800 +[ 90.299876] Call trace: +[ 90.302321] fsl_edma3_disable_request+0x8/0x60 +[ 90.306851] lpuart_flush_buffer+0x40/0x160 +[ 90.311037] uart_flush_buffer+0x88/0x120 +[ 90.315050] tty_driver_flush_buffer+0x20/0x30 +[ 90.319496] hci_uart_flush+0x44/0x90 +[ 90.323162] +0x34/0x12c +[ 90.327253] tty_ldisc_close+0x38/0x70 +[ 90.331005] tty_ldisc_release+0xa8/0x190 +[ 90.335018] tty_release_struct+0x24/0x8c +[ 90.339022] tty_release+0x3ec/0x4c0 +[ 90.342593] __fput+0x70/0x234 +[ 90.345652] ____fput+0x14/0x20 +[ 90.348790] task_work_run+0x84/0x17c +[ 90.352455] do_exit+0x310/0x96c +[ 90.355688] do_group_exit+0x3c/0xa0 +[ 90.359259] __arm64_sys_exit_group+0x1c/0x20 +[ 90.363609] invoke_syscall+0x48/0x114 +[ 90.367362] el0_svc_common.constprop.0+0xd4/0xfc +[ 90.372068] do_el0_svc+0x2c/0x94 +[ 90.375379] el0_svc+0x28/0x80 +[ 90.378438] el0t_64_sync_handler+0xa8/0x130 +[ 90.382711] el0t_64_sync+0x1a0/0x1a4 +[ 90.386376] Code: 17ffffda d503201f d503233f f9409802 (b9400041) +[ 90.392467] ---[ end trace 2f60524b4a43f1f6 ]--- +[ 90.397073] note: btattach[503] exited with preempt_count 1 +[ 90.402636] Fixing recursive fault but reboot is needed! + +Fixes: 6250cc30c4c4 ("tty: serial: fsl_lpuart: Use scatter/gather DMA for Tx") +Reviewed-by: Ilpo Järvinen +Signed-off-by: Thara Gopinath +Signed-off-by: Sherry Sun +Link: https://lore.kernel.org/r/20220920111703.1532-1-sherry.sun@nxp.com +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/tty/serial/fsl_lpuart.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c +index f21915015d67..064bd1f33c21 100644 +--- a/drivers/tty/serial/fsl_lpuart.c ++++ b/drivers/tty/serial/fsl_lpuart.c +@@ -1771,6 +1771,7 @@ static void lpuart_dma_shutdown(struct lpuart_port *sport) + if (sport->lpuart_dma_rx_use) { + del_timer_sync(&sport->lpuart_timer); + lpuart_dma_rx_free(&sport->port); ++ sport->lpuart_dma_rx_use = false; + } + + if (sport->lpuart_dma_tx_use) { +@@ -1779,6 +1780,7 @@ static void lpuart_dma_shutdown(struct lpuart_port *sport) + sport->dma_tx_in_progress = false; + dmaengine_terminate_all(sport->dma_tx_chan); + } ++ sport->lpuart_dma_tx_use = false; + } + + if (sport->dma_tx_chan) +-- +2.35.3 + diff --git a/patches.suse/tty-xilinx_uartps-Fix-the-ignore_status.patch b/patches.suse/tty-xilinx_uartps-Fix-the-ignore_status.patch new file mode 100644 index 0000000..90d6a33 --- /dev/null +++ b/patches.suse/tty-xilinx_uartps-Fix-the-ignore_status.patch @@ -0,0 +1,37 @@ +From b8a6c3b3d4654fba19881cc77da61eac29f57cae Mon Sep 17 00:00:00 2001 +From: Shubhrajyoti Datta +Date: Fri, 29 Jul 2022 17:17:45 +0530 +Subject: [PATCH] tty: xilinx_uartps: Fix the ignore_status +Git-commit: b8a6c3b3d4654fba19881cc77da61eac29f57cae +Patch-mainline: v6.1-rc1 +References: git-fixes + +Currently the ignore_status is not considered in the isr. +Add a check to add the ignore_status. + +Fixes: 61ec9016988f ("tty/serial: add support for Xilinx PS UART") +Signed-off-by: Shubhrajyoti Datta +Link: https://lore.kernel.org/r/20220729114748.18332-5-shubhrajyoti.datta@xilinx.com +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/tty/serial/xilinx_uartps.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c +index 94e1bc694457..ae99e1164f0c 100644 +--- a/drivers/tty/serial/xilinx_uartps.c ++++ b/drivers/tty/serial/xilinx_uartps.c +@@ -361,6 +361,8 @@ static irqreturn_t cdns_uart_isr(int irq, void *dev_id) + isrstatus &= ~CDNS_UART_IXR_TXEMPTY; + } + ++ isrstatus &= port->read_status_mask; ++ isrstatus &= ~port->ignore_status_mask; + /* + * Skip RX processing if RX is disabled as RXEMPTY will never be set + * as read bytes will not be removed from the FIFO. +-- +2.35.3 + diff --git a/patches.suse/uas-add-no-uas-quirk-for-Hiksemi-usb_disk.patch b/patches.suse/uas-add-no-uas-quirk-for-Hiksemi-usb_disk.patch new file mode 100644 index 0000000..e707059 --- /dev/null +++ b/patches.suse/uas-add-no-uas-quirk-for-Hiksemi-usb_disk.patch @@ -0,0 +1,56 @@ +From a625a4b8806cc1e928b7dd2cca1fee709c9de56e Mon Sep 17 00:00:00 2001 +From: Hongling Zeng +Date: Fri, 23 Sep 2022 10:46:13 +0800 +Subject: [PATCH] uas: add no-uas quirk for Hiksemi usb_disk +Git-commit: a625a4b8806cc1e928b7dd2cca1fee709c9de56e +Patch-mainline: v6.0 +References: git-fixes + +The UAS mode of Hiksemi is reported to fail to work on several platforms +with the following error message, then after re-connecting the device will +be offlined and not working at all. + +[ 592.518442][ 2] sd 8:0:0:0: [sda] tag#17 uas_eh_abort_handler 0 uas-tag 18 + inflight: CMD +[ 592.527575][ 2] sd 8:0:0:0: [sda] tag#17 CDB: Write(10) 2a 00 03 6f 88 00 00 + 04 00 00 +[ 592.536330][ 2] sd 8:0:0:0: [sda] tag#0 uas_eh_abort_handler 0 uas-tag 1 + inflight: CMD +[ 592.545266][ 2] sd 8:0:0:0: [sda] tag#0 CDB: Write(10) 2a 00 07 44 1a 88 00 + 00 08 00 + +These disks have a broken uas implementation, the tag field of the status +iu-s is not set properly,so we need to fall-back to usb-storage. + +Acked-by: Alan Stern +Cc: stable +Signed-off-by: Hongling Zeng +Link: https://lore.kernel.org/r/1663901173-21020-1-git-send-email-zenghongling@kylinos.cn +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/usb/storage/unusual_uas.h | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h +index 23ab3b048d9b..c967b3b62dce 100644 +--- a/drivers/usb/storage/unusual_uas.h ++++ b/drivers/usb/storage/unusual_uas.h +@@ -52,6 +52,13 @@ UNUSUAL_DEV(0x059f, 0x1061, 0x0000, 0x9999, + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_REPORT_OPCODES | US_FL_NO_SAME), + ++/* Reported-by: Hongling Zeng */ ++UNUSUAL_DEV(0x090c, 0x2000, 0x0000, 0x9999, ++ "Hiksemi", ++ "External HDD", ++ USB_SC_DEVICE, USB_PR_DEVICE, NULL, ++ US_FL_IGNORE_UAS), ++ + /* + * Apricorn USB3 dongle sometimes returns "USBSUSBSUSBS" in response to SCSI + * commands in UAS mode. Observed with the 1.28 firmware; are there others? +-- +2.35.3 + diff --git a/patches.suse/uas-ignore-UAS-for-Thinkplus-chips.patch b/patches.suse/uas-ignore-UAS-for-Thinkplus-chips.patch new file mode 100644 index 0000000..8f14297 --- /dev/null +++ b/patches.suse/uas-ignore-UAS-for-Thinkplus-chips.patch @@ -0,0 +1,66 @@ +From 0fb9703a3eade0bb84c635705d9c795345e55053 Mon Sep 17 00:00:00 2001 +From: Hongling Zeng +Date: Fri, 23 Sep 2022 10:46:35 +0800 +Subject: [PATCH] uas: ignore UAS for Thinkplus chips +Git-commit: 0fb9703a3eade0bb84c635705d9c795345e55053 +Patch-mainline: v6.0 +References: git-fixes + +The UAS mode of Thinkplus(0x17ef, 0x3899) is reported to influence +performance and trigger kernel panic on several platforms with the +following error message: + +[ 39.702439] xhci_hcd 0000:0c:00.3: ERROR Transfer event for disabled + endpoint or incorrect stream ring +[ 39.702442] xhci_hcd 0000:0c:00.3: @000000026c61f810 00000000 00000000 + 1b000000 05038000 + +[ 720.545894][13] Workqueue: usb_hub_wq hub_event +[ 720.550971][13] ffff88026c143c38 0000000000016300 ffff8802755bb900 ffff880 + 26cb80000 +[ 720.559673][13] ffff88026c144000 ffff88026ca88100 0000000000000000 ffff880 + 26cb80000 +[ 720.568374][13] ffff88026cb80000 ffff88026c143c50 ffffffff8186ae25 ffff880 + 26ca880f8 +[ 720.577076][13] Call Trace: +[ 720.580201][13] [] schedule+0x35/0x80 +[ 720.586137][13] [] schedule_preempt_disabled+0xe/0x10 +[ 720.593623][13] [] __mutex_lock_slowpath+0x164/0x1e0 +[ 720.601012][13] [] mutex_lock+0x2f/0x40 +[ 720.607141][13] [] usb_disconnect+0x59/0x290 + +Falling back to USB mass storage can solve this problem, so ignore UAS +function of this chip. + +Acked-by: Alan Stern +Cc: stable +Signed-off-by: Hongling Zeng +Link: https://lore.kernel.org/r/1663902249837086.19.seg@mailgw +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/usb/storage/unusual_uas.h | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h +index e5960b29f902..251778d14e2d 100644 +--- a/drivers/usb/storage/unusual_uas.h ++++ b/drivers/usb/storage/unusual_uas.h +@@ -132,6 +132,13 @@ UNUSUAL_DEV(0x154b, 0xf00d, 0x0000, 0x9999, + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_ATA_1X), + ++/* Reported-by: Hongling Zeng */ ++UNUSUAL_DEV(0x17ef, 0x3899, 0x0000, 0x9999, ++ "Thinkplus", ++ "External HDD", ++ USB_SC_DEVICE, USB_PR_DEVICE, NULL, ++ US_FL_IGNORE_UAS), ++ + /* Reported-by: Hans de Goede */ + UNUSUAL_DEV(0x2109, 0x0711, 0x0000, 0x9999, + "VIA", +-- +2.35.3 + diff --git a/patches.suse/usb-Drop-commas-after-SoC-match-table-sentinels.patch b/patches.suse/usb-Drop-commas-after-SoC-match-table-sentinels.patch new file mode 100644 index 0000000..e6234a4 --- /dev/null +++ b/patches.suse/usb-Drop-commas-after-SoC-match-table-sentinels.patch @@ -0,0 +1,49 @@ +From f8a98c45569a2bf2bf6c07fe83f41ee1f04bb29b Mon Sep 17 00:00:00 2001 +From: Geert Uytterhoeven +Date: Thu, 3 Mar 2022 13:50:21 +0100 +Subject: [PATCH] usb: Drop commas after SoC match table sentinels +Git-commit: f8a98c45569a2bf2bf6c07fe83f41ee1f04bb29b +References: git-fixes +Patch-mainline: v5.18-rc1 + +It does not make sense to have a comma after a sentinel, as any new +elements must be added before the sentinel. + +Signed-off-by: Geert Uytterhoeven +Link: https://lore.kernel.org/r/5cae409f647272a5679291ebc0000bfeccc14160.1646311762.git.geert+renesas@glider.be +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/usb/gadget/udc/renesas_usb3.c | 2 +- + drivers/usb/host/xhci-rcar.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c +index 601829a6b4ba..648be3fd476a 100644 +--- a/drivers/usb/gadget/udc/renesas_usb3.c ++++ b/drivers/usb/gadget/udc/renesas_usb3.c +@@ -2730,7 +2730,7 @@ static const struct soc_device_attribute renesas_usb3_quirks_match[] = { + .soc_id = "r8a7795", .revision = "ES1.*", + .data = &renesas_usb3_priv_r8a7795_es1, + }, +- { /* sentinel */ }, ++ { /* sentinel */ } + }; + + static const unsigned int renesas_usb3_cable[] = { +diff --git a/drivers/usb/host/xhci-rcar.c b/drivers/usb/host/xhci-rcar.c +index 9888ba7d85b6..aef0258a7160 100644 +--- a/drivers/usb/host/xhci-rcar.c ++++ b/drivers/usb/host/xhci-rcar.c +@@ -82,7 +82,7 @@ static const struct soc_device_attribute rcar_quirks_match[] = { + .soc_id = "r8a7795", .revision = "ES1.*", + .data = (void *)RCAR_XHCI_FIRMWARE_V2, + }, +- { /* sentinel */ }, ++ { /* sentinel */ } + }; + + static void xhci_rcar_start_gen2(struct usb_hcd *hcd) +-- +2.35.3 + diff --git a/patches.suse/usb-add-quirks-for-Lenovo-OneLink-Dock.patch b/patches.suse/usb-add-quirks-for-Lenovo-OneLink-Dock.patch new file mode 100644 index 0000000..5b8e097 --- /dev/null +++ b/patches.suse/usb-add-quirks-for-Lenovo-OneLink-Dock.patch @@ -0,0 +1,51 @@ +From 3d5f70949f1b1168fbb17d06eb5c57e984c56c58 Mon Sep 17 00:00:00 2001 +From: Jean-Francois Le Fillatre +Date: Wed, 24 Aug 2022 21:13:21 +0200 +Subject: [PATCH] usb: add quirks for Lenovo OneLink+ Dock +Git-commit: 3d5f70949f1b1168fbb17d06eb5c57e984c56c58 +Patch-mainline: v6.0-rc4 +References: git-fixes + +The Lenovo OneLink+ Dock contains two VL812 USB3.0 controllers: +17ef:1018 upstream +17ef:1019 downstream + +Those two controllers both have problems with some USB3.0 devices, +particularly self-powered ones. Typical error messages include: + + Timeout while waiting for setup device command + device not accepting address X, error -62 + unable to enumerate USB device + +By process of elimination the controllers themselves were identified as +the cause of the problem. Through trial and error the issue was solved +by using USB_QUIRK_RESET_RESUME for both chips. + +Signed-off-by: Jean-Francois Le Fillatre +Cc: stable +Link: https://lore.kernel.org/r/20220824191320.17883-1-jflf_kernel@gmx.com +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/usb/core/quirks.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c +index f99a65a64588..999b7c9697fc 100644 +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -437,6 +437,10 @@ static const struct usb_device_id usb_quirk_list[] = { + { USB_DEVICE(0x1532, 0x0116), .driver_info = + USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL }, + ++ /* Lenovo ThinkPad OneLink+ Dock twin hub controllers (VIA Labs VL812) */ ++ { USB_DEVICE(0x17ef, 0x1018), .driver_info = USB_QUIRK_RESET_RESUME }, ++ { USB_DEVICE(0x17ef, 0x1019), .driver_info = USB_QUIRK_RESET_RESUME }, ++ + /* Lenovo USB-C to Ethernet Adapter RTL8153-04 */ + { USB_DEVICE(0x17ef, 0x720c), .driver_info = USB_QUIRK_NO_LPM }, + +-- +2.35.3 + diff --git a/patches.suse/usb-common-debug-Check-non-standard-control-requests.patch b/patches.suse/usb-common-debug-Check-non-standard-control-requests.patch new file mode 100644 index 0000000..ae2a0cc --- /dev/null +++ b/patches.suse/usb-common-debug-Check-non-standard-control-requests.patch @@ -0,0 +1,139 @@ +From b6155eaf6b05e558218b44b88a6cad03f15a586c Mon Sep 17 00:00:00 2001 +From: Thinh Nguyen +Date: Wed, 27 Jul 2022 18:38:01 -0700 +Subject: [PATCH] usb: common: debug: Check non-standard control requests +Git-commit: b6155eaf6b05e558218b44b88a6cad03f15a586c +Patch-mainline: v6.1-rc1 +References: git-fixes + +Previously usb_decode_ctrl() only decodes standard control requests, but +it was used for non-standard requests also. If it's non-standard or +unknown standard bRequest, print the Setup data values. + +Fixes: af32423a2d86 ("usb: dwc3: trace: decode ctrl request") +Signed-off-by: Thinh Nguyen +Link: https://lore.kernel.org/r/8d6a30f2f2f953eff833a5bc5aac640a4cc2fc9f.1658971571.git.Thinh.Nguyen@synopsys.com +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/usb/common/debug.c | 96 +++++++++++++++++++++++++------------- + 1 file changed, 64 insertions(+), 32 deletions(-) + +diff --git a/drivers/usb/common/debug.c b/drivers/usb/common/debug.c +index 075f6b1b2a1a..f204cec8d380 100644 +--- a/drivers/usb/common/debug.c ++++ b/drivers/usb/common/debug.c +@@ -208,30 +208,28 @@ static void usb_decode_set_isoch_delay(__u8 wValue, char *str, size_t size) + snprintf(str, size, "Set Isochronous Delay(Delay = %d ns)", wValue); + } + +-/** +- * usb_decode_ctrl - Returns human readable representation of control request. +- * @str: buffer to return a human-readable representation of control request. +- * This buffer should have about 200 bytes. +- * @size: size of str buffer. +- * @bRequestType: matches the USB bmRequestType field +- * @bRequest: matches the USB bRequest field +- * @wValue: matches the USB wValue field (CPU byte order) +- * @wIndex: matches the USB wIndex field (CPU byte order) +- * @wLength: matches the USB wLength field (CPU byte order) +- * +- * Function returns decoded, formatted and human-readable description of +- * control request packet. +- * +- * The usage scenario for this is for tracepoints, so function as a return +- * use the same value as in parameters. This approach allows to use this +- * function in TP_printk +- * +- * Important: wValue, wIndex, wLength parameters before invoking this function +- * should be processed by le16_to_cpu macro. +- */ +-const char *usb_decode_ctrl(char *str, size_t size, __u8 bRequestType, +- __u8 bRequest, __u16 wValue, __u16 wIndex, +- __u16 wLength) ++static void usb_decode_ctrl_generic(char *str, size_t size, __u8 bRequestType, ++ __u8 bRequest, __u16 wValue, __u16 wIndex, ++ __u16 wLength) ++{ ++ u8 recip = bRequestType & USB_RECIP_MASK; ++ u8 type = bRequestType & USB_TYPE_MASK; ++ ++ snprintf(str, size, ++ "Type=%s Recipient=%s Dir=%s bRequest=%u wValue=%u wIndex=%u wLength=%u", ++ (type == USB_TYPE_STANDARD) ? "Standard" : ++ (type == USB_TYPE_VENDOR) ? "Vendor" : ++ (type == USB_TYPE_CLASS) ? "Class" : "Unknown", ++ (recip == USB_RECIP_DEVICE) ? "Device" : ++ (recip == USB_RECIP_INTERFACE) ? "Interface" : ++ (recip == USB_RECIP_ENDPOINT) ? "Endpoint" : "Unknown", ++ (bRequestType & USB_DIR_IN) ? "IN" : "OUT", ++ bRequest, wValue, wIndex, wLength); ++} ++ ++static void usb_decode_ctrl_standard(char *str, size_t size, __u8 bRequestType, ++ __u8 bRequest, __u16 wValue, __u16 wIndex, ++ __u16 wLength) + { + switch (bRequest) { + case USB_REQ_GET_STATUS: +@@ -272,14 +270,48 @@ const char *usb_decode_ctrl(char *str, size_t size, __u8 bRequestType, + usb_decode_set_isoch_delay(wValue, str, size); + break; + default: +- snprintf(str, size, "%02x %02x %02x %02x %02x %02x %02x %02x", +- bRequestType, bRequest, +- (u8)(cpu_to_le16(wValue) & 0xff), +- (u8)(cpu_to_le16(wValue) >> 8), +- (u8)(cpu_to_le16(wIndex) & 0xff), +- (u8)(cpu_to_le16(wIndex) >> 8), +- (u8)(cpu_to_le16(wLength) & 0xff), +- (u8)(cpu_to_le16(wLength) >> 8)); ++ usb_decode_ctrl_generic(str, size, bRequestType, bRequest, ++ wValue, wIndex, wLength); ++ break; ++ } ++} ++ ++/** ++ * usb_decode_ctrl - Returns human readable representation of control request. ++ * @str: buffer to return a human-readable representation of control request. ++ * This buffer should have about 200 bytes. ++ * @size: size of str buffer. ++ * @bRequestType: matches the USB bmRequestType field ++ * @bRequest: matches the USB bRequest field ++ * @wValue: matches the USB wValue field (CPU byte order) ++ * @wIndex: matches the USB wIndex field (CPU byte order) ++ * @wLength: matches the USB wLength field (CPU byte order) ++ * ++ * Function returns decoded, formatted and human-readable description of ++ * control request packet. ++ * ++ * The usage scenario for this is for tracepoints, so function as a return ++ * use the same value as in parameters. This approach allows to use this ++ * function in TP_printk ++ * ++ * Important: wValue, wIndex, wLength parameters before invoking this function ++ * should be processed by le16_to_cpu macro. ++ */ ++const char *usb_decode_ctrl(char *str, size_t size, __u8 bRequestType, ++ __u8 bRequest, __u16 wValue, __u16 wIndex, ++ __u16 wLength) ++{ ++ switch (bRequestType & USB_TYPE_MASK) { ++ case USB_TYPE_STANDARD: ++ usb_decode_ctrl_standard(str, size, bRequestType, bRequest, ++ wValue, wIndex, wLength); ++ break; ++ case USB_TYPE_VENDOR: ++ case USB_TYPE_CLASS: ++ default: ++ usb_decode_ctrl_generic(str, size, bRequestType, bRequest, ++ wValue, wIndex, wLength); ++ break; + } + + return str; +-- +2.35.3 + diff --git a/patches.suse/usb-dwc3-core-leave-default-DMA-if-the-controller-do.patch b/patches.suse/usb-dwc3-core-leave-default-DMA-if-the-controller-do.patch new file mode 100644 index 0000000..8b80788 --- /dev/null +++ b/patches.suse/usb-dwc3-core-leave-default-DMA-if-the-controller-do.patch @@ -0,0 +1,64 @@ +From 91062e663b261815573ce00967b1895a99e668df Mon Sep 17 00:00:00 2001 +From: William Wu +Date: Thu, 1 Sep 2022 16:34:46 +0800 +Subject: [PATCH] usb: dwc3: core: leave default DMA if the controller does not support 64-bit DMA +Git-commit: 91062e663b261815573ce00967b1895a99e668df +Patch-mainline: v6.0-rc7 +References: git-fixes + +On some DWC3 controllers (e.g. Rockchip SoCs), the DWC3 core +doesn't support 64-bit DMA address width. In this case, this +driver should use the default 32-bit mask. Otherwise, the DWC3 +controller will break if it runs on above 4GB physical memory +environment. + +This patch reads the DWC_USB3_AWIDTH bits of GHWPARAMS0 which +used for the DMA address width, and only configure 64-bit DMA +mask if the DWC_USB3_AWIDTH is 64. + +Fixes: 45d39448b4d0 ("usb: dwc3: support 64 bit DMA in platform driver") +Cc: stable +Reviewed-by: Sven Peter +Signed-off-by: William Wu +Link: https://lore.kernel.org/r/20220901083446.3799754-1-william.wu@rock-chips.com +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/usb/dwc3/core.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c +index 8c8e32651473..d0237b30c9be 100644 +--- a/drivers/usb/dwc3/core.c ++++ b/drivers/usb/dwc3/core.c +@@ -1752,12 +1752,6 @@ static int dwc3_probe(struct platform_device *pdev) + + dwc3_get_properties(dwc); + +- if (!dwc->sysdev_is_parent) { +- ret = dma_set_mask_and_coherent(dwc->sysdev, DMA_BIT_MASK(64)); +- if (ret) +- return ret; +- } +- + dwc->reset = devm_reset_control_array_get_optional_shared(dev); + if (IS_ERR(dwc->reset)) + return PTR_ERR(dwc->reset); +@@ -1823,6 +1817,13 @@ static int dwc3_probe(struct platform_device *pdev) + platform_set_drvdata(pdev, dwc); + dwc3_cache_hwparams(dwc); + ++ if (!dwc->sysdev_is_parent && ++ DWC3_GHWPARAMS0_AWIDTH(dwc->hwparams.hwparams0) == 64) { ++ ret = dma_set_mask_and_coherent(dwc->sysdev, DMA_BIT_MASK(64)); ++ if (ret) ++ goto disable_clks; ++ } ++ + spin_lock_init(&dwc->lock); + mutex_init(&dwc->mutex); + +-- +2.35.3 + diff --git a/patches.suse/usb-dwc3-disable-USB-core-PHY-management.patch b/patches.suse/usb-dwc3-disable-USB-core-PHY-management.patch new file mode 100644 index 0000000..4acac76 --- /dev/null +++ b/patches.suse/usb-dwc3-disable-USB-core-PHY-management.patch @@ -0,0 +1,57 @@ +From 6000b8d900cd5f52fbcd0776d0cc396e88c8c2ea Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Thu, 25 Aug 2022 15:18:36 +0200 +Subject: [PATCH] usb: dwc3: disable USB core PHY management +Git-commit: 6000b8d900cd5f52fbcd0776d0cc396e88c8c2ea +References: git-fixes +Patch-mainline: v6.0-rc4 + +The dwc3 driver manages its PHYs itself so the USB core PHY management +needs to be disabled. + +Use the struct xhci_plat_priv hack added by commits 46034a999c07 ("usb: +host: xhci-plat: add platform data support") and f768e718911e ("usb: +host: xhci-plat: add priv quirk for skip PHY initialization") to +propagate the setting for now. + +Fixes: 4e88d4c08301 ("usb: add a flag to skip PHY initialization to struct usb_hcd") +Fixes: 178a0bce05cb ("usb: core: hcd: integrate the PHY wrapper into the HCD core") +Tested-by: Matthias Kaehlcke +Cc: stable +Reviewed-by: Matthias Kaehlcke +Signed-off-by: Johan Hovold +Link: https://lore.kernel.org/r/20220825131836.19769-1-johan+linaro@kernel.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/usb/dwc3/host.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/drivers/usb/dwc3/host.c ++++ b/drivers/usb/dwc3/host.c +@@ -10,8 +10,13 @@ + #include + #include + ++#include "../host/xhci-plat.h" + #include "core.h" + ++static const struct xhci_plat_priv dwc3_xhci_plat_priv = { ++ .quirks = XHCI_SKIP_PHY_INIT, ++}; ++ + static int dwc3_host_get_irq(struct dwc3 *dwc) + { + struct platform_device *dwc3_pdev = to_platform_device(dwc->dev); +@@ -87,6 +92,11 @@ int dwc3_host_init(struct dwc3 *dwc) + goto err; + } + ++ ret = platform_device_add_data(xhci, &dwc3_xhci_plat_priv, ++ sizeof(dwc3_xhci_plat_priv)); ++ if (ret) ++ goto err; ++ + memset(props, 0, sizeof(struct property_entry) * ARRAY_SIZE(props)); + + if (dwc->usb3_lpm_capable) diff --git a/patches.suse/usb-dwc3-gadget-Avoid-duplicate-requests-to-enable-R.patch b/patches.suse/usb-dwc3-gadget-Avoid-duplicate-requests-to-enable-R.patch index c27ed66..0bba31e 100644 --- a/patches.suse/usb-dwc3-gadget-Avoid-duplicate-requests-to-enable-R.patch +++ b/patches.suse/usb-dwc3-gadget-Avoid-duplicate-requests-to-enable-R.patch @@ -28,25 +28,25 @@ Signed-off-by: Oliver Neukum --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c -@@ -2301,9 +2301,6 @@ static int dwc3_gadget_pullup(struct usb +@@ -2328,9 +2328,6 @@ static int dwc3_gadget_pullup(struct usb is_on = !!is_on; - if (dwc->pullups_connected == is_on) - return 0; - + dwc->softconnect = is_on; /* * Per databook, when we want to stop the gadget, if a control transfer - * is still in process, complete it and get the core into setup phase. -@@ -2347,6 +2344,11 @@ static int dwc3_gadget_pullup(struct usb - - spin_lock_irqsave(&dwc->lock, flags); - +@@ -2366,6 +2363,11 @@ static int dwc3_gadget_pullup(struct usb + pm_runtime_put(dwc->dev); + return 0; + } ++ + if (dwc->pullups_connected == is_on) { + pm_runtime_put(dwc->dev); + return 0; + } -+ - if (!is_on) { - u32 count; + if (!is_on) { + ret = dwc3_gadget_soft_disconnect(dwc); diff --git a/patches.suse/usb-dwc3-gadget-Avoid-starting-DWC3-gadget-during-UD.patch b/patches.suse/usb-dwc3-gadget-Avoid-starting-DWC3-gadget-during-UD.patch new file mode 100644 index 0000000..902429e --- /dev/null +++ b/patches.suse/usb-dwc3-gadget-Avoid-starting-DWC3-gadget-during-UD.patch @@ -0,0 +1,82 @@ +From 8217f07a50236779880f13e87f99224cd9117f83 Mon Sep 17 00:00:00 2001 +From: Wesley Cheng +Date: Thu, 16 Sep 2021 19:18:52 -0700 +Subject: [PATCH] usb: dwc3: gadget: Avoid starting DWC3 gadget during UDC unbind +Git-commit: 8217f07a50236779880f13e87f99224cd9117f83 +Patch-mainline: v5.16-rc1 +References: git-fixes + +There is a race present where the DWC3 runtime resume runs in parallel +to the UDC unbind sequence. This will eventually lead to a possible +scenario where we are enabling the run/stop bit, without a valid +composition defined. + +Thread#1 (handling UDC unbind): +usb_gadget_remove_driver() +-->usb_gadget_disconnect() + -->dwc3_gadget_pullup(0) +--> continue UDC unbind sequence +-->Thread#2 is running in parallel here + +Thread#2 (handing next cable connect) +__dwc3_set_mode() + -->pm_runtime_get_sync() + -->dwc3_gadget_resume() + -->dwc->gadget_driver is NOT NULL yet + -->dwc3_gadget_run_stop(1) + --> _dwc3gadget_start() +... + +Fix this by tracking the pullup disable routine, and avoiding resuming +of the DWC3 gadget. Once the UDC is re-binded, that will trigger the +pullup enable routine, which would handle enabling the DWC3 gadget. + +Acked-by: Felipe Balbi +Signed-off-by: Wesley Cheng +Link: https://lore.kernel.org/r/20210917021852.2037-1-wcheng@codeaurora.org +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/usb/dwc3/core.h | 2 ++ + drivers/usb/dwc3/gadget.c | 4 ++-- + 2 files changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/usb/dwc3/core.h ++++ b/drivers/usb/dwc3/core.h +@@ -1027,6 +1027,7 @@ struct dwc3_scratchpad_array { + * @tx_max_burst_prd: max periodic ESS transmit burst size + * @hsphy_interface: "utmi" or "ulpi" + * @connected: true when we're connected to a host, false otherwise ++ * @softconnect: true when gadget connect is called, false when disconnect runs + * @delayed_status: true when gadget driver asks for delayed status + * @ep0_bounced: true when we used bounce buffer + * @ep0_expect_in: true when we expect a DATA IN transfer +@@ -1239,6 +1240,7 @@ struct dwc3 { + const char *hsphy_interface; + + unsigned connected:1; ++ unsigned softconnect:1; + unsigned delayed_status:1; + unsigned ep0_bounced:1; + unsigned ep0_expect_in:1; +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -2300,7 +2300,7 @@ static int dwc3_gadget_pullup(struct usb + int ret; + + is_on = !!is_on; +- ++ dwc->softconnect = is_on; + /* + * Per databook, when we want to stop the gadget, if a control transfer + * is still in process, complete it and get the core into setup phase. +@@ -4233,7 +4233,7 @@ int dwc3_gadget_resume(struct dwc3 *dwc) + { + int ret; + +- if (!dwc->gadget_driver) ++ if (!dwc->gadget_driver || !dwc->softconnect) + return 0; + + ret = __dwc3_gadget_start(dwc); diff --git a/patches.suse/usb-dwc3-gadget-Don-t-modify-GEVNTCOUNT-in-pullup.patch b/patches.suse/usb-dwc3-gadget-Don-t-modify-GEVNTCOUNT-in-pullup.patch new file mode 100644 index 0000000..dd00489 --- /dev/null +++ b/patches.suse/usb-dwc3-gadget-Don-t-modify-GEVNTCOUNT-in-pullup.patch @@ -0,0 +1,110 @@ +From 8f8034f493b5eb1ad21ff392fd30c0cf9e71f73f Mon Sep 17 00:00:00 2001 +From: Thinh Nguyen +Date: Thu, 21 Apr 2022 19:22:44 -0700 +Subject: [PATCH] usb: dwc3: gadget: Don't modify GEVNTCOUNT in pullup() +Git-commit: 8f8034f493b5eb1ad21ff392fd30c0cf9e71f73f +Patch-mainline: v5.19-rc1 +References: git-fixes + +If the GEVNTCOUNT indicates events in the event buffer, the driver needs +to acknowledge them before the controller can halt. Simply let the +interrupt handler acknowledges the remaining event generated by the +controller while polling for DSTS.DEVCTLHLT. This avoids disabling irq +and taking care of race condition between the interrupt handlers and +pullup(). + +Signed-off-by: Thinh Nguyen +Link: https://lore.kernel.org/r/ea306ec93c41ccafbdb5d16404ff3b6eca299613.1650593829.git.Thinh.Nguyen@synopsys.com +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/usb/dwc3/gadget.c | 35 ++++++++--------------------------- + 1 file changed, 8 insertions(+), 27 deletions(-) + +diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c +index a53460eae789..3c0a6c83ea43 100644 +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -2509,8 +2509,9 @@ static int __dwc3_gadget_start(struct dwc3 *dwc); + + static int dwc3_gadget_soft_disconnect(struct dwc3 *dwc) + { +- u32 count; ++ unsigned long flags; + ++ spin_lock_irqsave(&dwc->lock, flags); + dwc->connected = false; + + /* +@@ -2522,29 +2523,21 @@ static int dwc3_gadget_soft_disconnect(struct dwc3 *dwc) + */ + dwc3_stop_active_transfers(dwc); + __dwc3_gadget_stop(dwc); ++ spin_unlock_irqrestore(&dwc->lock, flags); + + /* +- * In the Synopsys DesignWare Cores USB3 Databook Rev. 3.30a +- * Section 1.3.4, it mentions that for the DEVCTRLHLT bit, the +- * "software needs to acknowledge the events that are generated +- * (by writing to GEVNTCOUNTn) while it is waiting for this bit +- * to be set to '1'." ++ * Note: if the GEVNTCOUNT indicates events in the event buffer, the ++ * driver needs to acknowledge them before the controller can halt. ++ * Simply let the interrupt handler acknowledges and handle the ++ * remaining event generated by the controller while polling for ++ * DSTS.DEVCTLHLT. + */ +- count = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0)); +- count &= DWC3_GEVNTCOUNT_MASK; +- if (count > 0) { +- dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), count); +- dwc->ev_buf->lpos = (dwc->ev_buf->lpos + count) % +- dwc->ev_buf->length; +- } +- + return dwc3_gadget_run_stop(dwc, false, false); + } + + static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) + { + struct dwc3 *dwc = gadget_to_dwc(g); +- unsigned long flags; + int ret; + + is_on = !!is_on; +@@ -2588,14 +2581,6 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) + return 0; + } + +- /* +- * Synchronize and disable any further event handling while controller +- * is being enabled/disabled. +- */ +- disable_irq(dwc->irq_gadget); +- +- spin_lock_irqsave(&dwc->lock, flags); +- + if (!is_on) { + ret = dwc3_gadget_soft_disconnect(dwc); + } else { +@@ -2605,16 +2590,12 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) + * device-initiated disconnect requires a core soft reset + * (DCTL.CSftRst) before enabling the run/stop bit. + */ +- spin_unlock_irqrestore(&dwc->lock, flags); + dwc3_core_soft_reset(dwc); +- spin_lock_irqsave(&dwc->lock, flags); + + dwc3_event_buffers_setup(dwc); + __dwc3_gadget_start(dwc); + ret = dwc3_gadget_run_stop(dwc, true, false); + } +- spin_unlock_irqrestore(&dwc->lock, flags); +- enable_irq(dwc->irq_gadget); + + pm_runtime_put(dwc->dev); + +-- +2.35.3 + diff --git a/patches.suse/usb-dwc3-gadget-Prevent-repeat-pullup.patch b/patches.suse/usb-dwc3-gadget-Prevent-repeat-pullup.patch index 8ad8324..b5da8fd 100644 --- a/patches.suse/usb-dwc3-gadget-Prevent-repeat-pullup.patch +++ b/patches.suse/usb-dwc3-gadget-Prevent-repeat-pullup.patch @@ -20,18 +20,19 @@ Link: https://lore.kernel.org/r/1c1345bd66c97a9d32f77d63aaadd04b7b037143.1650593 Signed-off-by: Greg Kroah-Hartman Signed-off-by: Oliver Neukum --- - drivers/usb/dwc3/gadget.c | 3 +++ - 1 file changed, 3 insertions(+) + drivers/usb/dwc3/gadget.c | 4 ++++ + 1 file changed, 4 insertions(+) --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c -@@ -2313,6 +2313,9 @@ static int dwc3_gadget_pullup(struct usb +@@ -2312,6 +2312,10 @@ static int dwc3_gadget_pullup(struct usb + int ret; is_on = !!is_on; - ++ + if (dwc->pullups_connected == is_on) + return 0; + + dwc->softconnect = is_on; /* * Per databook, when we want to stop the gadget, if a control transfer - * is still in process, complete it and get the core into setup phase. diff --git a/patches.suse/usb-dwc3-gadget-Refactor-pullup.patch b/patches.suse/usb-dwc3-gadget-Refactor-pullup.patch new file mode 100644 index 0000000..e03b0e4 --- /dev/null +++ b/patches.suse/usb-dwc3-gadget-Refactor-pullup.patch @@ -0,0 +1,109 @@ +From 861c010a2ee1bc4a66d23f0da4aa22e75d8eaa24 Mon Sep 17 00:00:00 2001 +From: Thinh Nguyen +Date: Thu, 21 Apr 2022 19:22:38 -0700 +Subject: [PATCH] usb: dwc3: gadget: Refactor pullup() +Git-commit: 861c010a2ee1bc4a66d23f0da4aa22e75d8eaa24 +Patch-mainline: v5.19-rc1 +References: git-fixes + +Move soft-disconnect sequence out of dwc3_gadget_pullup(). No +functional change here. + +Signed-off-by: Thinh Nguyen +Link: https://lore.kernel.org/r/4c0f259b17d95acaaa931f90276683a48a32fe22.1650593829.git.Thinh.Nguyen@synopsys.com +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/usb/dwc3/gadget.c | 65 +++++++++++++++++++++++++--------------------- + 1 file changed, 36 insertions(+), 29 deletions(-) + +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -2305,6 +2305,40 @@ static void dwc3_gadget_disable_irq(stru + static void __dwc3_gadget_stop(struct dwc3 *dwc); + static int __dwc3_gadget_start(struct dwc3 *dwc); + ++static int dwc3_gadget_soft_disconnect(struct dwc3 *dwc) ++{ ++ u32 count; ++ ++ dwc->connected = false; ++ ++ /* ++ * In the Synopsys DesignWare Cores USB3 Databook Rev. 3.30a ++ * Section 4.1.8 Table 4-7, it states that for a device-initiated ++ * disconnect, the SW needs to ensure that it sends "a DEPENDXFER ++ * command for any active transfers" before clearing the RunStop ++ * bit. ++ */ ++ dwc3_stop_active_transfers(dwc); ++ __dwc3_gadget_stop(dwc); ++ ++ /* ++ * In the Synopsys DesignWare Cores USB3 Databook Rev. 3.30a ++ * Section 1.3.4, it mentions that for the DEVCTRLHLT bit, the ++ * "software needs to acknowledge the events that are generated ++ * (by writing to GEVNTCOUNTn) while it is waiting for this bit ++ * to be set to '1'." ++ */ ++ count = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0)); ++ count &= DWC3_GEVNTCOUNT_MASK; ++ if (count > 0) { ++ dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), count); ++ dwc->ev_buf->lpos = (dwc->ev_buf->lpos + count) % ++ dwc->ev_buf->length; ++ } ++ ++ return dwc3_gadget_run_stop(dwc, false, false); ++} ++ + static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) + { + struct dwc3 *dwc = gadget_to_dwc(g); +@@ -2361,33 +2395,7 @@ static int dwc3_gadget_pullup(struct usb + spin_lock_irqsave(&dwc->lock, flags); + + if (!is_on) { +- u32 count; +- +- dwc->connected = false; +- /* +- * In the Synopsis DesignWare Cores USB3 Databook Rev. 3.30a +- * Section 4.1.8 Table 4-7, it states that for a device-initiated +- * disconnect, the SW needs to ensure that it sends "a DEPENDXFER +- * command for any active transfers" before clearing the RunStop +- * bit. +- */ +- dwc3_stop_active_transfers(dwc); +- __dwc3_gadget_stop(dwc); +- +- /* +- * In the Synopsis DesignWare Cores USB3 Databook Rev. 3.30a +- * Section 1.3.4, it mentions that for the DEVCTRLHLT bit, the +- * "software needs to acknowledge the events that are generated +- * (by writing to GEVNTCOUNTn) while it is waiting for this bit +- * to be set to '1'." +- */ +- count = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0)); +- count &= DWC3_GEVNTCOUNT_MASK; +- if (count > 0) { +- dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), count); +- dwc->ev_buf->lpos = (dwc->ev_buf->lpos + count) % +- dwc->ev_buf->length; +- } ++ ret = dwc3_gadget_soft_disconnect(dwc); + } else { + /* + * In the Synopsys DWC_usb31 1.90a programming guide section +@@ -2401,9 +2409,8 @@ static int dwc3_gadget_pullup(struct usb + + dwc3_event_buffers_setup(dwc); + __dwc3_gadget_start(dwc); ++ ret = dwc3_gadget_run_stop(dwc, true, false); + } +- +- ret = dwc3_gadget_run_stop(dwc, is_on, false); + spin_unlock_irqrestore(&dwc->lock, flags); + enable_irq(dwc->irq_gadget); + diff --git a/patches.suse/usb-dwc3-pci-add-support-for-the-Intel-Meteor-Lake-P.patch b/patches.suse/usb-dwc3-pci-add-support-for-the-Intel-Meteor-Lake-P.patch index def47bd..a5629a0 100644 --- a/patches.suse/usb-dwc3-pci-add-support-for-the-Intel-Meteor-Lake-P.patch +++ b/patches.suse/usb-dwc3-pci-add-support-for-the-Intel-Meteor-Lake-P.patch @@ -4,7 +4,7 @@ Date: Mon, 25 Apr 2022 13:35:18 +0300 Subject: [PATCH] usb: dwc3: pci: add support for the Intel Meteor Lake-P Git-commit: 973e0f7a847ef13ade840d4c30729ce329a66895 Patch-mainline: v5.18-rc5 -References: git-fixes +References: jsc#PED-732 git-fixes This patch adds the necessary PCI IDs for Intel Meteor Lake-P devices. diff --git a/patches.suse/usb-ehci-Fix-a-function-name-in-comments.patch b/patches.suse/usb-ehci-Fix-a-function-name-in-comments.patch new file mode 100644 index 0000000..614d32e --- /dev/null +++ b/patches.suse/usb-ehci-Fix-a-function-name-in-comments.patch @@ -0,0 +1,36 @@ +From 1cd27268561a9a7e466baf61e2de2295933648c8 Mon Sep 17 00:00:00 2001 +From: Cai Huoqing +Date: Sat, 25 Sep 2021 20:49:17 +0800 +Subject: [PATCH] usb: ehci: Fix a function name in comments +Git-commit: 1cd27268561a9a7e466baf61e2de2295933648c8 +References: git-fixes +Patch-mainline: v5.16-rc1 + +Use dma_map_single() instead of pci_map_single(), +because only dma_map_single() is called here. + +Acked-by: Alan Stern +Signed-off-by: Cai Huoqing +Link: https://lore.kernel.org/r/20210925124920.1564-1-caihuoqing@baidu.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/usb/host/ehci-hcd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c +index 144080321629..3d82e0b853be 100644 +--- a/drivers/usb/host/ehci-hcd.c ++++ b/drivers/usb/host/ehci-hcd.c +@@ -588,7 +588,7 @@ static int ehci_run (struct usb_hcd *hcd) + * hcc_params controls whether ehci->regs->segment must (!!!) + * be used; it constrains QH/ITD/SITD and QTD locations. + * dma_pool consistent memory always uses segment zero. +- * streaming mappings for I/O buffers, like pci_map_single(), ++ * streaming mappings for I/O buffers, like dma_map_single(), + * can return segments above 4GB, if the device allows. + * + * NOTE: the dma mask is visible through dev->dma_mask, so +-- +2.35.3 + diff --git a/patches.suse/usb-gadget-function-fix-dangling-pnp_string-in-f_pri.patch b/patches.suse/usb-gadget-function-fix-dangling-pnp_string-in-f_pri.patch new file mode 100644 index 0000000..b14acae --- /dev/null +++ b/patches.suse/usb-gadget-function-fix-dangling-pnp_string-in-f_pri.patch @@ -0,0 +1,76 @@ +From 24b7ba2f88e04800b54d462f376512e8c41b8a3c Mon Sep 17 00:00:00 2001 +From: Albert Briscoe +Date: Sun, 11 Sep 2022 15:37:55 -0700 +Subject: [PATCH] usb: gadget: function: fix dangling pnp_string in f_printer.c +Git-commit: 24b7ba2f88e04800b54d462f376512e8c41b8a3c +Patch-mainline: v6.1-rc1 +References: git-fixes + +When opts->pnp_string is changed with configfs, new memory is allocated for +the string. It does not, however, update dev->pnp_string, even though the +memory is freed. When rquesting the string, the host then gets old or +corrupted data rather than the new string. The ieee 1284 id string should +be allowed to change while the device is connected. + +The bug was introduced in commit fdc01cc286be ("usb: gadget: printer: +Remove pnp_string static buffer"), which changed opts->pnp_string from a +char[] to a char*. +This patch changes dev->pnp_string from a char* to a char** pointing to +opts->pnp_string. + +Fixes: fdc01cc286be ("usb: gadget: printer: Remove pnp_string static buffer") +Signed-off-by: Albert Briscoe +Link: https://lore.kernel.org/r/20220911223753.20417-1-albertsbriscoe@gmail.com +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/usb/gadget/function/f_printer.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c +index abec5c58f525..a881c69b1f2b 100644 +--- a/drivers/usb/gadget/function/f_printer.c ++++ b/drivers/usb/gadget/function/f_printer.c +@@ -89,7 +89,7 @@ struct printer_dev { + u8 printer_cdev_open; + wait_queue_head_t wait; + unsigned q_len; +- char *pnp_string; /* We don't own memory! */ ++ char **pnp_string; /* We don't own memory! */ + struct usb_function function; + }; + +@@ -1000,16 +1000,16 @@ static int printer_func_setup(struct usb_function *f, + if ((wIndex>>8) != dev->interface) + break; + +- if (!dev->pnp_string) { ++ if (!*dev->pnp_string) { + value = 0; + break; + } +- value = strlen(dev->pnp_string); ++ value = strlen(*dev->pnp_string); + buf[0] = (value >> 8) & 0xFF; + buf[1] = value & 0xFF; +- memcpy(buf + 2, dev->pnp_string, value); ++ memcpy(buf + 2, *dev->pnp_string, value); + DBG(dev, "1284 PNP String: %x %s\n", value, +- dev->pnp_string); ++ *dev->pnp_string); + break; + + case GET_PORT_STATUS: /* Get Port Status */ +@@ -1475,7 +1475,7 @@ static struct usb_function *gprinter_alloc(struct usb_function_instance *fi) + kref_init(&dev->kref); + ++opts->refcnt; + dev->minor = opts->minor; +- dev->pnp_string = opts->pnp_string; ++ dev->pnp_string = &opts->pnp_string; + dev->q_len = opts->q_len; + mutex_unlock(&opts->lock); + +-- +2.35.3 + diff --git a/patches.suse/usb-hcd-Fix-dma_map_sg-error-check.patch b/patches.suse/usb-hcd-Fix-dma_map_sg-error-check.patch new file mode 100644 index 0000000..d40d21b --- /dev/null +++ b/patches.suse/usb-hcd-Fix-dma_map_sg-error-check.patch @@ -0,0 +1,43 @@ +From 4dce3b375179fdd4aba2191be11ace90ef0ec6d6 Mon Sep 17 00:00:00 2001 +From: Jack Wang +Date: Fri, 19 Aug 2022 08:07:48 +0200 +Subject: [PATCH] usb/hcd: Fix dma_map_sg error check +Git-commit: 4dce3b375179fdd4aba2191be11ace90ef0ec6d6 +References: git-fixes +Patch-mainline: v6.1-rc1 + +dma_map_sg return 0 on error. + +Cc: Alan Stern +Cc: Kishon Vijay Abraham I +Cc: Alexey Sheplyakov +Cc: Stephen Boyd +Cc: Weitao Wang +Cc: Matthias Kaehlcke +Cc: Arnd Bergmann +Cc: linux-usb@vger.kernel.org +Cc: linux-kernel@vger.kernel.org +Signed-off-by: Jack Wang +Link: https://lore.kernel.org/r/20220819060801.10443-7-jinpu.wang@ionos.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/usb/core/hcd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c +index 94b305bbd621..90dd32a24e5b 100644 +--- a/drivers/usb/core/hcd.c ++++ b/drivers/usb/core/hcd.c +@@ -1474,7 +1474,7 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, + urb->sg, + urb->num_sgs, + dir); +- if (n <= 0) ++ if (!n) + ret = -EAGAIN; + else + urb->transfer_flags |= URB_DMA_MAP_SG; +-- +2.35.3 + diff --git a/patches.suse/usb-host-Initiate-urb-ep-with-udev-ep0.patch b/patches.suse/usb-host-Initiate-urb-ep-with-udev-ep0.patch new file mode 100644 index 0000000..a9bb3ee --- /dev/null +++ b/patches.suse/usb-host-Initiate-urb-ep-with-udev-ep0.patch @@ -0,0 +1,52 @@ +From 9013d8fc0ad91dc369f5b8ea708b9b068aa5d434 Mon Sep 17 00:00:00 2001 +From: Khalid Masum +Date: Thu, 25 Aug 2022 02:31:07 +0600 +Subject: [PATCH] usb: host: Initiate urb ep with udev ep0 +Git-commit: 9013d8fc0ad91dc369f5b8ea708b9b068aa5d434 +References: jsc#PED-531 +Patch-mainline: v6.1-rc1 + +Currently we look up for endpoint in a table and initate urb endpoint +with it. This is unnecessary because the lookup will always result in +endpoint 0. + +Suggested-by: Alan Stern +Acked-by: Alan Stern +Signed-off-by: Khalid Masum +Link: https://lore.kernel.org/r/20220824203107.14908-1-khalid.masum.92@gmail.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/usb/core/hcd.c | 9 +-------- + 1 file changed, 1 insertion(+), 8 deletions(-) + +diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c +index 90dd32a24e5b..faeaace0d197 100644 +--- a/drivers/usb/core/hcd.c ++++ b/drivers/usb/core/hcd.c +@@ -2158,21 +2158,14 @@ static struct urb *request_single_step_set_feature_urb( + { + struct urb *urb; + struct usb_hcd *hcd = bus_to_hcd(udev->bus); +- struct usb_host_endpoint *ep; + + urb = usb_alloc_urb(0, GFP_KERNEL); + if (!urb) + return NULL; + + urb->pipe = usb_rcvctrlpipe(udev, 0); +- ep = (usb_pipein(urb->pipe) ? udev->ep_in : udev->ep_out) +- [usb_pipeendpoint(urb->pipe)]; +- if (!ep) { +- usb_free_urb(urb); +- return NULL; +- } + +- urb->ep = ep; ++ urb->ep = &udev->ep0; + urb->dev = udev; + urb->setup_packet = (void *)dr; + urb->transfer_buffer = buf; +-- +2.35.3 + diff --git a/patches.suse/usb-host-remove-dead-EHCI-support-for-on-chip-PMC-MS.patch b/patches.suse/usb-host-remove-dead-EHCI-support-for-on-chip-PMC-MS.patch new file mode 100644 index 0000000..529b849 --- /dev/null +++ b/patches.suse/usb-host-remove-dead-EHCI-support-for-on-chip-PMC-MS.patch @@ -0,0 +1,399 @@ +From b2582996a74799c84fd19473c7b914565249b050 Mon Sep 17 00:00:00 2001 +From: Lukas Bulwahn +Date: Wed, 18 Aug 2021 09:11:35 +0200 +Subject: [PATCH] usb: host: remove dead EHCI support for on-chip PMC MSP71xx + USB controller +Git-commit: b2582996a74799c84fd19473c7b914565249b050 +References: jsc#PED-531 +Patch-mainline: v5.15-rc1 + +Commit 1b00767fd8e1 ("MIPS: Remove PMC MSP71xx platform") deletes +./arch/mips/pmcs-msp71xx/Kconfig, including its config MSP_HAS_USB. + +Hence, since then, the corresponding EHCI support for on-chip PMC MSP71xx +USB controller is dead code. Remove this dead driver. + +Signed-off-by: Lukas Bulwahn +Link: https://lore.kernel.org/r/20210818071137.22711-2-lukas.bulwahn@gmail.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/usb/host/Kconfig | 9 - + drivers/usb/host/ehci-hcd.c | 5 - + drivers/usb/host/ehci-pmcmsp.c | 328 --------------------------------- + 3 files changed, 342 deletions(-) + delete mode 100644 drivers/usb/host/ehci-pmcmsp.c + +diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig +index df9428f1dc5e..c4736d1d020c 100644 +--- a/drivers/usb/host/Kconfig ++++ b/drivers/usb/host/Kconfig +@@ -187,15 +187,6 @@ config USB_EHCI_PCI + depends on USB_PCI + default y + +-config USB_EHCI_HCD_PMC_MSP +- tristate "EHCI support for on-chip PMC MSP71xx USB controller" +- depends on MSP_HAS_USB +- select USB_EHCI_BIG_ENDIAN_DESC +- select USB_EHCI_BIG_ENDIAN_MMIO +- help +- Enables support for the onchip USB controller on the PMC_MSP7100 Family SoC's. +- If unsure, say N. +- + config XPS_USB_HCD_XILINX + bool "Use Xilinx usb host EHCI controller core" + depends on (PPC32 || MICROBLAZE) +diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c +index 10b0365f3439..6bdc6d6bf74d 100644 +--- a/drivers/usb/host/ehci-hcd.c ++++ b/drivers/usb/host/ehci-hcd.c +@@ -1296,11 +1296,6 @@ MODULE_LICENSE ("GPL"); + #define XILINX_OF_PLATFORM_DRIVER ehci_hcd_xilinx_of_driver + #endif + +-#ifdef CONFIG_USB_EHCI_HCD_PMC_MSP +-#include "ehci-pmcmsp.c" +-#define PLATFORM_DRIVER ehci_hcd_msp_driver +-#endif +- + #ifdef CONFIG_SPARC_LEON + #include "ehci-grlib.c" + #define PLATFORM_DRIVER ehci_grlib_driver +diff --git a/drivers/usb/host/ehci-pmcmsp.c b/drivers/usb/host/ehci-pmcmsp.c +deleted file mode 100644 +index 5fb92b956cc7..000000000000 +--- a/drivers/usb/host/ehci-pmcmsp.c ++++ /dev/null +@@ -1,328 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0 +-/* +- * PMC MSP EHCI (Host Controller Driver) for USB. +- * +- * (C) Copyright 2006-2010 PMC-Sierra Inc +- */ +- +-/* includes */ +-#include +-#include +-#include +-#include +- +-/* stream disable*/ +-#define USB_CTRL_MODE_STREAM_DISABLE 0x10 +- +-/* threshold */ +-#define USB_CTRL_FIFO_THRESH 0x00300000 +- +-/* register offset for usb_mode */ +-#define USB_EHCI_REG_USB_MODE 0x68 +- +-/* register offset for usb fifo */ +-#define USB_EHCI_REG_USB_FIFO 0x24 +- +-/* register offset for usb status */ +-#define USB_EHCI_REG_USB_STATUS 0x44 +- +-/* serial/parallel transceiver */ +-#define USB_EHCI_REG_BIT_STAT_STS (1<<29) +- +-/* TWI USB0 host device pin */ +-#define MSP_PIN_USB0_HOST_DEV 49 +- +-/* TWI USB1 host device pin */ +-#define MSP_PIN_USB1_HOST_DEV 50 +- +- +-static void usb_hcd_tdi_set_mode(struct ehci_hcd *ehci) +-{ +- u8 *base; +- u8 *statreg; +- u8 *fiforeg; +- u32 val; +- struct ehci_regs *reg_base = ehci->regs; +- +- /* get register base */ +- base = (u8 *)reg_base + USB_EHCI_REG_USB_MODE; +- statreg = (u8 *)reg_base + USB_EHCI_REG_USB_STATUS; +- fiforeg = (u8 *)reg_base + USB_EHCI_REG_USB_FIFO; +- +- /* Disable controller mode stream */ +- val = ehci_readl(ehci, (u32 *)base); +- ehci_writel(ehci, (val | USB_CTRL_MODE_STREAM_DISABLE), +- (u32 *)base); +- +- /* clear STS to select parallel transceiver interface */ +- val = ehci_readl(ehci, (u32 *)statreg); +- val = val & ~USB_EHCI_REG_BIT_STAT_STS; +- ehci_writel(ehci, val, (u32 *)statreg); +- +- /* write to set the proper fifo threshold */ +- ehci_writel(ehci, USB_CTRL_FIFO_THRESH, (u32 *)fiforeg); +- +- /* set TWI GPIO USB_HOST_DEV pin high */ +- gpio_direction_output(MSP_PIN_USB0_HOST_DEV, 1); +-} +- +-/* called during probe() after chip reset completes */ +-static int ehci_msp_setup(struct usb_hcd *hcd) +-{ +- struct ehci_hcd *ehci = hcd_to_ehci(hcd); +- int retval; +- +- ehci->big_endian_mmio = 1; +- ehci->big_endian_desc = 1; +- +- ehci->caps = hcd->regs; +- hcd->has_tt = 1; +- +- retval = ehci_setup(hcd); +- if (retval) +- return retval; +- +- usb_hcd_tdi_set_mode(ehci); +- +- return retval; +-} +- +- +-/* configure so an HC device and id are always provided +- * always called with process context; sleeping is OK +- */ +- +-static int usb_hcd_msp_map_regs(struct mspusb_device *dev) +-{ +- struct resource *res; +- struct platform_device *pdev = &dev->dev; +- u32 res_len; +- int retval; +- +- /* MAB register space */ +- res = platform_get_resource(pdev, IORESOURCE_MEM, 1); +- if (res == NULL) +- return -ENOMEM; +- res_len = resource_size(res); +- if (!request_mem_region(res->start, res_len, "mab regs")) +- return -EBUSY; +- +- dev->mab_regs = ioremap(res->start, res_len); +- if (dev->mab_regs == NULL) { +- retval = -ENOMEM; +- goto err1; +- } +- +- /* MSP USB register space */ +- res = platform_get_resource(pdev, IORESOURCE_MEM, 2); +- if (res == NULL) { +- retval = -ENOMEM; +- goto err2; +- } +- res_len = resource_size(res); +- if (!request_mem_region(res->start, res_len, "usbid regs")) { +- retval = -EBUSY; +- goto err2; +- } +- dev->usbid_regs = ioremap(res->start, res_len); +- if (dev->usbid_regs == NULL) { +- retval = -ENOMEM; +- goto err3; +- } +- +- return 0; +-err3: +- res = platform_get_resource(pdev, IORESOURCE_MEM, 2); +- res_len = resource_size(res); +- release_mem_region(res->start, res_len); +-err2: +- iounmap(dev->mab_regs); +-err1: +- res = platform_get_resource(pdev, IORESOURCE_MEM, 1); +- res_len = resource_size(res); +- release_mem_region(res->start, res_len); +- dev_err(&pdev->dev, "Failed to map non-EHCI regs.\n"); +- return retval; +-} +- +-/** +- * usb_hcd_msp_probe - initialize PMC MSP-based HCDs +- * @driver: Pointer to hc driver instance +- * @dev: USB controller to probe +- * +- * Context: task context, might sleep +- * +- * Allocates basic resources for this USB host controller, and +- * then invokes the start() method for the HCD associated with it +- * through the hotplug entry's driver_data. +- */ +-int usb_hcd_msp_probe(const struct hc_driver *driver, +- struct platform_device *dev) +-{ +- int retval; +- struct usb_hcd *hcd; +- struct resource *res; +- struct ehci_hcd *ehci ; +- +- hcd = usb_create_hcd(driver, &dev->dev, "pmcmsp"); +- if (!hcd) +- return -ENOMEM; +- +- res = platform_get_resource(dev, IORESOURCE_MEM, 0); +- if (res == NULL) { +- pr_debug("No IOMEM resource info for %s.\n", dev->name); +- retval = -ENOMEM; +- goto err1; +- } +- hcd->rsrc_start = res->start; +- hcd->rsrc_len = resource_size(res); +- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, dev->name)) { +- retval = -EBUSY; +- goto err1; +- } +- hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); +- if (!hcd->regs) { +- pr_debug("ioremap failed"); +- retval = -ENOMEM; +- goto err2; +- } +- +- res = platform_get_resource(dev, IORESOURCE_IRQ, 0); +- if (res == NULL) { +- dev_err(&dev->dev, "No IRQ resource info for %s.\n", dev->name); +- retval = -ENOMEM; +- goto err3; +- } +- +- /* Map non-EHCI register spaces */ +- retval = usb_hcd_msp_map_regs(to_mspusb_device(dev)); +- if (retval != 0) +- goto err3; +- +- ehci = hcd_to_ehci(hcd); +- ehci->big_endian_mmio = 1; +- ehci->big_endian_desc = 1; +- +- +- retval = usb_add_hcd(hcd, res->start, IRQF_SHARED); +- if (retval == 0) { +- device_wakeup_enable(hcd->self.controller); +- return 0; +- } +- +- usb_remove_hcd(hcd); +-err3: +- iounmap(hcd->regs); +-err2: +- release_mem_region(hcd->rsrc_start, hcd->rsrc_len); +-err1: +- usb_put_hcd(hcd); +- +- return retval; +-} +- +- +- +-/** +- * usb_hcd_msp_remove - shutdown processing for PMC MSP-based HCDs +- * @hcd: USB Host Controller being removed +- * +- * Context: task context, might sleep +- * +- * Reverses the effect of usb_hcd_msp_probe(), first invoking +- * the HCD's stop() method. It is always called from a thread +- * context, normally "rmmod", "apmd", or something similar. +- * +- * may be called without controller electrically present +- * may be called with controller, bus, and devices active +- */ +-static void usb_hcd_msp_remove(struct usb_hcd *hcd) +-{ +- usb_remove_hcd(hcd); +- iounmap(hcd->regs); +- release_mem_region(hcd->rsrc_start, hcd->rsrc_len); +- usb_put_hcd(hcd); +-} +- +-static const struct hc_driver ehci_msp_hc_driver = { +- .description = hcd_name, +- .product_desc = "PMC MSP EHCI", +- .hcd_priv_size = sizeof(struct ehci_hcd), +- +- /* +- * generic hardware linkage +- */ +- .irq = ehci_irq, +- .flags = HCD_MEMORY | HCD_DMA | HCD_USB2 | HCD_BH, +- +- /* +- * basic lifecycle operations +- */ +- .reset = ehci_msp_setup, +- .shutdown = ehci_shutdown, +- .start = ehci_run, +- .stop = ehci_stop, +- +- /* +- * managing i/o requests and associated device resources +- */ +- .urb_enqueue = ehci_urb_enqueue, +- .urb_dequeue = ehci_urb_dequeue, +- .endpoint_disable = ehci_endpoint_disable, +- .endpoint_reset = ehci_endpoint_reset, +- +- /* +- * scheduling support +- */ +- .get_frame_number = ehci_get_frame, +- +- /* +- * root hub support +- */ +- .hub_status_data = ehci_hub_status_data, +- .hub_control = ehci_hub_control, +- .bus_suspend = ehci_bus_suspend, +- .bus_resume = ehci_bus_resume, +- .relinquish_port = ehci_relinquish_port, +- .port_handed_over = ehci_port_handed_over, +- +- .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, +-}; +- +-static int ehci_hcd_msp_drv_probe(struct platform_device *pdev) +-{ +- int ret; +- +- pr_debug("In ehci_hcd_msp_drv_probe"); +- +- if (usb_disabled()) +- return -ENODEV; +- +- gpio_request(MSP_PIN_USB0_HOST_DEV, "USB0_HOST_DEV_GPIO"); +- +- ret = usb_hcd_msp_probe(&ehci_msp_hc_driver, pdev); +- +- return ret; +-} +- +-static int ehci_hcd_msp_drv_remove(struct platform_device *pdev) +-{ +- struct usb_hcd *hcd = platform_get_drvdata(pdev); +- +- usb_hcd_msp_remove(hcd); +- +- /* free TWI GPIO USB_HOST_DEV pin */ +- gpio_free(MSP_PIN_USB0_HOST_DEV); +- +- return 0; +-} +- +-MODULE_ALIAS("pmcmsp-ehci"); +- +-static struct platform_driver ehci_hcd_msp_driver = { +- .probe = ehci_hcd_msp_drv_probe, +- .remove = ehci_hcd_msp_drv_remove, +- .driver = { +- .name = "pmcmsp-ehci", +- }, +-}; +-- +2.35.3 + diff --git a/patches.suse/usb-host-xhci-fix-a-comment-typo-in-xhci_mem_init.patch b/patches.suse/usb-host-xhci-fix-a-comment-typo-in-xhci_mem_init.patch new file mode 100644 index 0000000..ef433d7 --- /dev/null +++ b/patches.suse/usb-host-xhci-fix-a-comment-typo-in-xhci_mem_init.patch @@ -0,0 +1,35 @@ +From ddfaee6255945a59f897033ffb55cfcdc5bcf946 Mon Sep 17 00:00:00 2001 +From: Linyu Yuan +Date: Thu, 3 Mar 2022 13:09:00 +0200 +Subject: [PATCH] usb: host: xhci: fix a comment typo in xhci_mem_init() +Git-commit: ddfaee6255945a59f897033ffb55cfcdc5bcf946 +References: git-fixes +Patch-mainline: v5.18-rc1 + +It should be Device Context, not doorbell. + +Signed-off-by: Linyu Yuan +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20220303110903.1662404-7-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/usb/host/xhci-mem.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c +index 938eb2b907ab..bbb27ee2c6a3 100644 +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -2417,7 +2417,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) + writel(val, &xhci->op_regs->config_reg); + + /* +- * xHCI section 5.4.6 - doorbell array must be ++ * xHCI section 5.4.6 - Device Context array must be + * "physically contiguous and 64-byte (cache line) aligned". + */ + xhci->dcbaa = dma_alloc_coherent(dev, sizeof(*xhci->dcbaa), &dma, +-- +2.35.3 + diff --git a/patches.suse/usb-host-xhci-use-ffs-in-xhci_mem_init.patch b/patches.suse/usb-host-xhci-use-ffs-in-xhci_mem_init.patch new file mode 100644 index 0000000..0e79ac2 --- /dev/null +++ b/patches.suse/usb-host-xhci-use-ffs-in-xhci_mem_init.patch @@ -0,0 +1,39 @@ +From 81720ec5320c3a02a4b2faf597127de5478cbf02 Mon Sep 17 00:00:00 2001 +From: Linyu Yuan +Date: Thu, 3 Mar 2022 13:08:59 +0200 +Subject: [PATCH] usb: host: xhci: use ffs() in xhci_mem_init() +Git-commit: 81720ec5320c3a02a4b2faf597127de5478cbf02 +References: git-fixes +Patch-mainline: v5.18-rc1 + +The for loop to find page size bit can be replaced with ffs(). + +Signed-off-by: Linyu Yuan +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20220303110903.1662404-6-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/usb/host/xhci-mem.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c +index 48114a462908..938eb2b907ab 100644 +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -2391,11 +2391,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) + page_size = readl(&xhci->op_regs->page_size); + xhci_dbg_trace(xhci, trace_xhci_dbg_init, + "Supported page size register = 0x%x", page_size); +- for (i = 0; i < 16; i++) { +- if ((0x1 & page_size) != 0) +- break; +- page_size = page_size >> 1; +- } ++ i = ffs(page_size); + if (i < 16) + xhci_dbg_trace(xhci, trace_xhci_dbg_init, + "Supported page size of %iK", (1 << (i+12)) / 1024); +-- +2.35.3 + diff --git a/patches.suse/usb-mon-make-mmapped-memory-read-only.patch b/patches.suse/usb-mon-make-mmapped-memory-read-only.patch new file mode 100644 index 0000000..ff530f7 --- /dev/null +++ b/patches.suse/usb-mon-make-mmapped-memory-read-only.patch @@ -0,0 +1,53 @@ +From a659daf63d16aa883be42f3f34ff84235c302198 Mon Sep 17 00:00:00 2001 +From: Tadeusz Struk +Date: Mon, 19 Sep 2022 14:59:57 -0700 +Subject: [PATCH] usb: mon: make mmapped memory read only +Git-commit: a659daf63d16aa883be42f3f34ff84235c302198 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Syzbot found an issue in usbmon module, where the user space client can +corrupt the monitor's internal memory, causing the usbmon module to +crash the kernel with segfault, UAF, etc. + +The reproducer mmaps the /dev/usbmon memory to user space, and +overwrites it with arbitrary data, which causes all kinds of issues. + +Return an -EPERM error from mon_bin_mmap() if the flag VM_WRTIE is set. +Also clear VM_MAYWRITE to make it impossible to change it to writable +later. + +Cc: "Dmitry Vyukov" +Cc: stable +Fixes: 6f23ee1fefdc ("USB: add binary API to usbmon") +Suggested-by: PaX Team # for the VM_MAYRITE portion +Link: https://syzkaller.appspot.com/bug?id=2eb1f35d6525fa4a74d75b4244971e5b1411c95a +Reported-by: syzbot+23f57c5ae902429285d7@syzkaller.appspotmail.com +Signed-off-by: Tadeusz Struk +Link: https://lore.kernel.org/r/20220919215957.205681-1-tadeusz.struk@linaro.org +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/usb/mon/mon_bin.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c +index f48a23adbc35..094e812e9e69 100644 +--- a/drivers/usb/mon/mon_bin.c ++++ b/drivers/usb/mon/mon_bin.c +@@ -1268,6 +1268,11 @@ static int mon_bin_mmap(struct file *filp, struct vm_area_struct *vma) + { + /* don't do anything here: "fault" will set up page table entries */ + vma->vm_ops = &mon_bin_vm_ops; ++ ++ if (vma->vm_flags & VM_WRITE) ++ return -EPERM; ++ ++ vma->vm_flags &= ~VM_MAYWRITE; + vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP; + vma->vm_private_data = filp->private_data; + mon_bin_vma_open(vma); +-- +2.35.3 + diff --git a/patches.suse/usb-mtu3-fix-failed-runtime-suspend-in-host-only-mod.patch b/patches.suse/usb-mtu3-fix-failed-runtime-suspend-in-host-only-mod.patch new file mode 100644 index 0000000..056280c --- /dev/null +++ b/patches.suse/usb-mtu3-fix-failed-runtime-suspend-in-host-only-mod.patch @@ -0,0 +1,55 @@ +From 1c703e29da5efac6180e4c189029fa34b7e48e97 Mon Sep 17 00:00:00 2001 +From: Chunfeng Yun +Date: Thu, 29 Sep 2022 14:44:59 +0800 +Subject: [PATCH] usb: mtu3: fix failed runtime suspend in host only mode +Git-commit: 1c703e29da5efac6180e4c189029fa34b7e48e97 +Patch-mainline: v6.1-rc1 +References: git-fixes + +When the dr_mode is "host", after the host enter runtime suspend, +the mtu3 can't do it, because the mtu3's device wakeup function is +not enabled, instead it's enabled in gadget init function, to fix +the issue, init wakeup early in mtu3's probe() + +Fixes: 6b587394c65c ("usb: mtu3: support suspend/resume for dual-role mode") +Reviewed-by: AngeloGioacchino Del Regno +Reported-by: Tianping Fang +Signed-off-by: Chunfeng Yun +Link: https://lore.kernel.org/r/20220929064459.32522-1-chunfeng.yun@mediatek.com +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/usb/mtu3/mtu3_core.c | 2 -- + drivers/usb/mtu3/mtu3_plat.c | 2 ++ + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/usb/mtu3/mtu3_core.c b/drivers/usb/mtu3/mtu3_core.c +index 0ca173af87bb..a3a6282893d0 100644 +--- a/drivers/usb/mtu3/mtu3_core.c ++++ b/drivers/usb/mtu3/mtu3_core.c +@@ -978,8 +978,6 @@ int ssusb_gadget_init(struct ssusb_mtk *ssusb) + goto irq_err; + } + +- device_init_wakeup(dev, true); +- + /* power down device IP for power saving by default */ + mtu3_stop(mtu); + +diff --git a/drivers/usb/mtu3/mtu3_plat.c b/drivers/usb/mtu3/mtu3_plat.c +index 4cb65346789d..d78ae52b4e26 100644 +--- a/drivers/usb/mtu3/mtu3_plat.c ++++ b/drivers/usb/mtu3/mtu3_plat.c +@@ -356,6 +356,8 @@ static int mtu3_probe(struct platform_device *pdev) + pm_runtime_enable(dev); + pm_runtime_get_sync(dev); + ++ device_init_wakeup(dev, true); ++ + ret = ssusb_rscs_init(ssusb); + if (ret) + goto comm_init_err; +-- +2.35.3 + diff --git a/patches.suse/usb-renesas-xhci-Do-not-print-any-log-while-fw-verif.patch b/patches.suse/usb-renesas-xhci-Do-not-print-any-log-while-fw-verif.patch new file mode 100644 index 0000000..a07e11a --- /dev/null +++ b/patches.suse/usb-renesas-xhci-Do-not-print-any-log-while-fw-verif.patch @@ -0,0 +1,44 @@ +From b2d0dd5155c437ec5aad2141d74a8fac97ef755f Mon Sep 17 00:00:00 2001 +From: Chen Xingdi +Date: Wed, 27 Jul 2022 11:11:46 +0800 +Subject: [PATCH] usb: renesas-xhci: Do not print any log while fw verif + success +Git-commit: b2d0dd5155c437ec5aad2141d74a8fac97ef755f +References: jsc#PED-531 +Patch-mainline: v6.0-rc1 + +When drivers are working properly, they should be quiet. + +Signed-off-by: Chen Xingdi +Link: https://lore.kernel.org/r/20220727031146.19345-1-chenxingdi@huawei.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/usb/host/xhci-pci-renesas.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/drivers/usb/host/xhci-pci-renesas.c b/drivers/usb/host/xhci-pci-renesas.c +index 52599d96634f..93f8b355bc70 100644 +--- a/drivers/usb/host/xhci-pci-renesas.c ++++ b/drivers/usb/host/xhci-pci-renesas.c +@@ -120,7 +120,6 @@ static int renesas_fw_verify(const void *fw_data, + size_t length) + { + u16 fw_version_pointer; +- u16 fw_version; + + /* + * The Firmware's Data Format is describe in +@@ -150,9 +149,6 @@ static int renesas_fw_verify(const void *fw_data, + return -EINVAL; + } + +- fw_version = get_unaligned_le16(fw_data + fw_version_pointer); +- pr_err("got firmware version: %02x.", fw_version); +- + return 0; + } + +-- +2.35.3 + diff --git a/patches.suse/usb-storage-Add-ASUS-0x0b05-0x1932-to-IGNORE_UAS.patch b/patches.suse/usb-storage-Add-ASUS-0x0b05-0x1932-to-IGNORE_UAS.patch new file mode 100644 index 0000000..f289694 --- /dev/null +++ b/patches.suse/usb-storage-Add-ASUS-0x0b05-0x1932-to-IGNORE_UAS.patch @@ -0,0 +1,45 @@ +From c61feaee68b9735be06f162bc046c7f1959efb0c Mon Sep 17 00:00:00 2001 +From: Hu Xiaoying +Date: Thu, 1 Sep 2022 12:57:37 +0800 +Subject: [PATCH] usb: storage: Add ASUS <0x0b05:0x1932> to IGNORE_UAS +Git-commit: c61feaee68b9735be06f162bc046c7f1959efb0c +Patch-mainline: v6.0-rc4 +References: git-fixes + +USB external storage device(0x0b05:1932), use gnome-disk-utility tools +to test usb write < 30MB/s. +if does not to load module of uas for this device, can increase the +write speed from 20MB/s to >40MB/s. + +Suggested-by: Matthias Kaehlcke +Acked-by: Alan Stern +Signed-off-by: Hu Xiaoying +Link: https://lore.kernel.org/r/20220901045737.3438046-1-huxiaoying@kylinos.cn +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/usb/storage/unusual_uas.h | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h +index 4051c8cd0cd8..23ab3b048d9b 100644 +--- a/drivers/usb/storage/unusual_uas.h ++++ b/drivers/usb/storage/unusual_uas.h +@@ -62,6 +62,13 @@ UNUSUAL_DEV(0x0984, 0x0301, 0x0128, 0x0128, + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_UAS), + ++/* Reported-by: Tom Hu */ ++UNUSUAL_DEV(0x0b05, 0x1932, 0x0000, 0x9999, ++ "ASUS", ++ "External HDD", ++ USB_SC_DEVICE, USB_PR_DEVICE, NULL, ++ US_FL_IGNORE_UAS), ++ + /* Reported-by: David Webb */ + UNUSUAL_DEV(0x0bc2, 0x331a, 0x0000, 0x9999, + "Seagate", +-- +2.35.3 + diff --git a/patches.suse/usb-storage-Add-Hiksemi-USB3-FW-to-IGNORE_UAS.patch b/patches.suse/usb-storage-Add-Hiksemi-USB3-FW-to-IGNORE_UAS.patch new file mode 100644 index 0000000..91d1773 --- /dev/null +++ b/patches.suse/usb-storage-Add-Hiksemi-USB3-FW-to-IGNORE_UAS.patch @@ -0,0 +1,56 @@ +From e00b488e813f0f1ad9f778e771b7cd2fe2877023 Mon Sep 17 00:00:00 2001 +From: Hongling Zeng +Date: Fri, 23 Sep 2022 10:46:25 +0800 +Subject: [PATCH] usb-storage: Add Hiksemi USB3-FW to IGNORE_UAS +Git-commit: e00b488e813f0f1ad9f778e771b7cd2fe2877023 +Patch-mainline: v6.0 +References: git-fixes + +The UAS mode of Hiksemi USB_HDD is reported to fail to work on several +platforms with the following error message, then after re-connecting the +device will be offlined and not working at all. + +[ 592.518442][ 2] sd 8:0:0:0: [sda] tag#17 uas_eh_abort_handler 0 uas-tag 18 + inflight: CMD +[ 592.527575][ 2] sd 8:0:0:0: [sda] tag#17 CDB: Write(10) 2a 00 03 6f 88 00 00 + 04 00 00 +[ 592.536330][ 2] sd 8:0:0:0: [sda] tag#0 uas_eh_abort_handler 0 uas-tag 1 + inflight: CMD +[ 592.545266][ 2] sd 8:0:0:0: [sda] tag#0 CDB: Write(10) 2a 00 07 44 1a 88 00 + 00 08 00 + +These disks have a broken uas implementation, the tag field of the status +iu-s is not set properly,so we need to fall-back to usb-storage. + +Acked-by: Alan Stern +Cc: stable +Signed-off-by: Hongling Zeng +Link: https://lore.kernel.org/r/1663901185-21067-1-git-send-email-zenghongling@kylinos.cn +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/usb/storage/unusual_uas.h | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h +index c967b3b62dce..e5960b29f902 100644 +--- a/drivers/usb/storage/unusual_uas.h ++++ b/drivers/usb/storage/unusual_uas.h +@@ -83,6 +83,13 @@ UNUSUAL_DEV(0x0bc2, 0x331a, 0x0000, 0x9999, + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_REPORT_LUNS), + ++/* Reported-by: Hongling Zeng */ ++UNUSUAL_DEV(0x0bda, 0x9210, 0x0000, 0x9999, ++ "Hiksemi", ++ "External HDD", ++ USB_SC_DEVICE, USB_PR_DEVICE, NULL, ++ US_FL_IGNORE_UAS), ++ + /* Reported-by: Benjamin Tissoires */ + UNUSUAL_DEV(0x13fd, 0x3940, 0x0000, 0x9999, + "Initio Corporation", +-- +2.35.3 + diff --git a/patches.suse/usb-typec-ucsi-Remove-incorrect-warning.patch b/patches.suse/usb-typec-ucsi-Remove-incorrect-warning.patch new file mode 100644 index 0000000..ede5423 --- /dev/null +++ b/patches.suse/usb-typec-ucsi-Remove-incorrect-warning.patch @@ -0,0 +1,41 @@ +From: Heikki Krogerus +Date: Thu, 22 Sep 2022 17:59:24 +0300 +Subject: usb: typec: ucsi: Remove incorrect warning +Git-commit: 415ba26cb73f7d22a892043301b91b57ae54db02 +Patch-mainline: v6.0 +References: git-fixes + +Sink only devices do not have any source capabilities, so +the driver should not warn about that. Also DRP (Dual Role +Power) capable devices, such as USB Type-C docking stations, +do not return any source capabilities unless they are +plugged to a power supply themselves. + +Fixes: 1f4642b72be7 ("usb: typec: ucsi: Retrieve all the PDOs instead of just the first 4") +Reported-by: Paul Menzel +Cc: +Signed-off-by: Heikki Krogerus +Link: https://lore.kernel.org/r/20220922145924.80667-1-heikki.krogerus@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/usb/typec/ucsi/ucsi.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c +index 7f2624f42724..6364f0d467ea 100644 +--- a/drivers/usb/typec/ucsi/ucsi.c ++++ b/drivers/usb/typec/ucsi/ucsi.c +@@ -588,8 +588,6 @@ static int ucsi_get_pdos(struct ucsi_connector *con, int is_partner, + num_pdos * sizeof(u32)); + if (ret < 0 && ret != -ETIMEDOUT) + dev_err(ucsi->dev, "UCSI_GET_PDOS failed (%d)\n", ret); +- if (ret == 0 && offset == 0) +- dev_warn(ucsi->dev, "UCSI_GET_PDOS returned 0 bytes\n"); + + return ret; + } +-- +2.35.3 + diff --git a/patches.suse/usb-typec-wcove-Drop-wrong-dependency-to-INTEL_SOC_P.patch b/patches.suse/usb-typec-wcove-Drop-wrong-dependency-to-INTEL_SOC_P.patch new file mode 100644 index 0000000..741d584 --- /dev/null +++ b/patches.suse/usb-typec-wcove-Drop-wrong-dependency-to-INTEL_SOC_P.patch @@ -0,0 +1,44 @@ +From 9ef165406308515dcf2e3f6e97b39a1c56d86db5 Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Mon, 20 Jun 2022 13:43:16 +0300 +Subject: [PATCH] usb: typec: wcove: Drop wrong dependency to INTEL_SOC_PMIC +Git-commit: 9ef165406308515dcf2e3f6e97b39a1c56d86db5 +References: git-fixes +Patch-mainline: v5.19-rc4 + +Intel SoC PMIC is a generic name for all PMICs that are used +on Intel platforms. In particular, INTEL_SOC_PMIC kernel configuration +option refers to Crystal Cove PMIC, which has never been a part +of any Intel Broxton hardware. Drop wrong dependency from Kconfig. + +Note, the correct dependency is satisfied via ACPI PMIC OpRegion driver, +which the Type-C depends on. + +Fixes: d2061f9cc32d ("usb: typec: add driver for Intel Whiskey Cove PMIC USB Type-C PHY") +Reported-by: Hans de Goede +Reviewed-by: Guenter Roeck +Reviewed-by: Heikki Krogerus +Reviewed-by: Hans de Goede +Signed-off-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20220620104316.57592-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/usb/typec/tcpm/Kconfig | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/usb/typec/tcpm/Kconfig b/drivers/usb/typec/tcpm/Kconfig +index 557f392fe24d..073fd2ea5e0b 100644 +--- a/drivers/usb/typec/tcpm/Kconfig ++++ b/drivers/usb/typec/tcpm/Kconfig +@@ -56,7 +56,6 @@ config TYPEC_WCOVE + tristate "Intel WhiskeyCove PMIC USB Type-C PHY driver" + depends on ACPI + depends on MFD_INTEL_PMC_BXT +- depends on INTEL_SOC_PMIC + depends on BXT_WC_PMIC_OPREGION + help + This driver adds support for USB Type-C on Intel Broxton platforms +-- +2.35.3 + diff --git a/patches.suse/usbnet-Fix-memory-leak-in-usbnet_disconnect.patch b/patches.suse/usbnet-Fix-memory-leak-in-usbnet_disconnect.patch new file mode 100644 index 0000000..98a70eb --- /dev/null +++ b/patches.suse/usbnet-Fix-memory-leak-in-usbnet_disconnect.patch @@ -0,0 +1,56 @@ +From a43206156263fbaf1f2b7f96257441f331e91bb7 Mon Sep 17 00:00:00 2001 +From: Peilin Ye +Date: Thu, 22 Sep 2022 21:25:51 -0700 +Subject: [PATCH] usbnet: Fix memory leak in usbnet_disconnect() +Git-commit: a43206156263fbaf1f2b7f96257441f331e91bb7 +Patch-mainline: v6.0 +References: git-fixes + +Currently usbnet_disconnect() unanchors and frees all deferred URBs +using usb_scuttle_anchored_urbs(), which does not free urb->context, +causing a memory leak as reported by syzbot. + +Use a usb_get_from_anchor() while loop instead, similar to what we did +in commit 19cfe912c37b ("Bluetooth: btusb: Fix memory leak in +play_deferred"). Also free urb->sg. + +Reported-and-tested-by: syzbot+dcd3e13cf4472f2e0ba1@syzkaller.appspotmail.com +Fixes: 69ee472f2706 ("usbnet & cdc-ether: Autosuspend for online devices") +Fixes: 638c5115a794 ("USBNET: support DMA SG") +Signed-off-by: Peilin Ye +Link: https://lore.kernel.org/r/20220923042551.2745-1-yepeilin.cs@gmail.com +Signed-off-by: Jakub Kicinski +Acked-by: Takashi Iwai + +--- + drivers/net/usb/usbnet.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c +index aaa89b4cfd50..e368b0780753 100644 +--- a/drivers/net/usb/usbnet.c ++++ b/drivers/net/usb/usbnet.c +@@ -1598,6 +1598,7 @@ void usbnet_disconnect (struct usb_interface *intf) + struct usbnet *dev; + struct usb_device *xdev; + struct net_device *net; ++ struct urb *urb; + + dev = usb_get_intfdata(intf); + usb_set_intfdata(intf, NULL); +@@ -1614,7 +1615,11 @@ void usbnet_disconnect (struct usb_interface *intf) + net = dev->net; + unregister_netdev (net); + +- usb_scuttle_anchored_urbs(&dev->deferred); ++ while ((urb = usb_get_from_anchor(&dev->deferred))) { ++ dev_kfree_skb(urb->context); ++ kfree(urb->sg); ++ usb_free_urb(urb); ++ } + + if (dev->driver_info->unbind) + dev->driver_info->unbind(dev, intf); +-- +2.35.3 + diff --git a/patches.suse/vfio-type1-Unpin-zero-pages.patch b/patches.suse/vfio-type1-Unpin-zero-pages.patch new file mode 100644 index 0000000..521040a --- /dev/null +++ b/patches.suse/vfio-type1-Unpin-zero-pages.patch @@ -0,0 +1,58 @@ +From 873aefb376bbc0ed1dd2381ea1d6ec88106fdbd4 Mon Sep 17 00:00:00 2001 +From: Alex Williamson +Date: Mon, 29 Aug 2022 21:05:40 -0600 +Subject: [PATCH] vfio/type1: Unpin zero pages +Git-commit: 873aefb376bbc0ed1dd2381ea1d6ec88106fdbd4 +Patch-mainline: v6.0-rc5 +References: git-fixes + +There's currently a reference count leak on the zero page. We increment +the reference via pin_user_pages_remote(), but the page is later handled +as an invalid/reserved page, therefore it's not accounted against the +user and not unpinned by our put_pfn(). + +Introducing special zero page handling in put_pfn() would resolve the +leak, but without accounting of the zero page, a single user could +still create enough mappings to generate a reference count overflow. + +The zero page is always resident, so for our purposes there's no reason +to keep it pinned. Therefore, add a loop to walk pages returned from +pin_user_pages_remote() and unpin any zero pages. + +Cc: stable@vger.kernel.org +Reported-by: Luboslav Pivarc +Reviewed-by: David Hildenbrand +Link: https://lore.kernel.org/r/166182871735.3518559.8884121293045337358.stgit@omen +Signed-off-by: Alex Williamson +Acked-by: Takashi Iwai + +--- + drivers/vfio/vfio_iommu_type1.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c +index db516c90a977..8706482665d1 100644 +--- a/drivers/vfio/vfio_iommu_type1.c ++++ b/drivers/vfio/vfio_iommu_type1.c +@@ -558,6 +558,18 @@ static int vaddr_get_pfns(struct mm_struct *mm, unsigned long vaddr, + ret = pin_user_pages_remote(mm, vaddr, npages, flags | FOLL_LONGTERM, + pages, NULL, NULL); + if (ret > 0) { ++ int i; ++ ++ /* ++ * The zero page is always resident, we don't need to pin it ++ * and it falls into our invalid/reserved test so we don't ++ * unpin in put_pfn(). Unpin all zero pages in the batch here. ++ */ ++ for (i = 0 ; i < ret; i++) { ++ if (unlikely(is_zero_pfn(page_to_pfn(pages[i])))) ++ unpin_user_page(pages[i]); ++ } ++ + *pfn = page_to_pfn(pages[0]); + goto done; + } +-- +2.35.3 + diff --git a/patches.suse/vhost-vsock-Use-kvmalloc-kvfree-for-larger-packets.patch b/patches.suse/vhost-vsock-Use-kvmalloc-kvfree-for-larger-packets.patch new file mode 100644 index 0000000..420136b --- /dev/null +++ b/patches.suse/vhost-vsock-Use-kvmalloc-kvfree-for-larger-packets.patch @@ -0,0 +1,73 @@ +From 0e3f72931fc47bb81686020cc643cde5d9cd0bb8 Mon Sep 17 00:00:00 2001 +From: Junichi Uekawa +Date: Wed, 28 Sep 2022 15:45:38 +0900 +Subject: [PATCH] vhost/vsock: Use kvmalloc/kvfree for larger packets. +Git-commit: 0e3f72931fc47bb81686020cc643cde5d9cd0bb8 +Patch-mainline: v6.1-rc1 +References: git-fixes + +When copying a large file over sftp over vsock, data size is usually 32kB, +and kmalloc seems to fail to try to allocate 32 32kB regions. + + vhost-5837: page allocation failure: order:4, mode:0x24040c0 + Call Trace: + [] dump_stack+0x97/0xdb + [] warn_alloc_failed+0x10f/0x138 + [] ? __alloc_pages_direct_compact+0x38/0xc8 + [] __alloc_pages_nodemask+0x84c/0x90d + [] alloc_kmem_pages+0x17/0x19 + [] kmalloc_order_trace+0x2b/0xdb + [] __kmalloc+0x177/0x1f7 + [] ? copy_from_iter+0x8d/0x31d + [] vhost_vsock_handle_tx_kick+0x1fa/0x301 [vhost_vsock] + [] vhost_worker+0xf7/0x157 [vhost] + [] kthread+0xfd/0x105 + [] ? vhost_dev_set_owner+0x22e/0x22e [vhost] + [] ? flush_kthread_worker+0xf3/0xf3 + [] ret_from_fork+0x4e/0x80 + [] ? flush_kthread_worker+0xf3/0xf3 + +Work around by doing kvmalloc instead. + +Fixes: 433fc58e6bf2 ("VSOCK: Introduce vhost_vsock.ko") +Signed-off-by: Junichi Uekawa +Reviewed-by: Stefano Garzarella +Acked-by: Michael S. Tsirkin +Link: https://lore.kernel.org/r/20220928064538.667678-1-uekawa@chromium.org +Signed-off-by: Jakub Kicinski +Acked-by: Takashi Iwai + +--- + drivers/vhost/vsock.c | 2 +- + net/vmw_vsock/virtio_transport_common.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c +index 368330417bde..5703775af129 100644 +--- a/drivers/vhost/vsock.c ++++ b/drivers/vhost/vsock.c +@@ -393,7 +393,7 @@ vhost_vsock_alloc_pkt(struct vhost_virtqueue *vq, + return NULL; + } + +- pkt->buf = kmalloc(pkt->len, GFP_KERNEL); ++ pkt->buf = kvmalloc(pkt->len, GFP_KERNEL); + if (!pkt->buf) { + kfree(pkt); + return NULL; +diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c +index ec2c2afbf0d0..3a12aee33e92 100644 +--- a/net/vmw_vsock/virtio_transport_common.c ++++ b/net/vmw_vsock/virtio_transport_common.c +@@ -1342,7 +1342,7 @@ EXPORT_SYMBOL_GPL(virtio_transport_recv_pkt); + + void virtio_transport_free_pkt(struct virtio_vsock_pkt *pkt) + { +- kfree(pkt->buf); ++ kvfree(pkt->buf); + kfree(pkt); + } + EXPORT_SYMBOL_GPL(virtio_transport_free_pkt); +-- +2.35.3 + diff --git a/patches.suse/video-fbdev-i740fb-Error-out-if-pixclock-equals-zero.patch b/patches.suse/video-fbdev-i740fb-Error-out-if-pixclock-equals-zero.patch new file mode 100644 index 0000000..c18a66d --- /dev/null +++ b/patches.suse/video-fbdev-i740fb-Error-out-if-pixclock-equals-zero.patch @@ -0,0 +1,52 @@ +From 15cf0b82271b1823fb02ab8c377badba614d95d5 Mon Sep 17 00:00:00 2001 +From: Zheyu Ma +Date: Mon, 4 Apr 2022 16:47:17 +0800 +Subject: [PATCH] video: fbdev: i740fb: Error out if 'pixclock' equals zero +Git-commit: 15cf0b82271b1823fb02ab8c377badba614d95d5 +Patch-mainline: v5.18-rc5 +References: git-fixes + +The userspace program could pass any values to the driver through +ioctl() interface. If the driver doesn't check the value of 'pixclock', +it may cause divide error. + +Fix this by checking whether 'pixclock' is zero in the function +i740fb_check_var(). + +The following log reveals it: + +divide error: 0000 [#1] PREEMPT SMP KASAN PTI +Rip: 0010:i740fb_decode_var drivers/video/fbdev/i740fb.c:444 [inline] +Rip: 0010:i740fb_set_par+0x272f/0x3bb0 drivers/video/fbdev/i740fb.c:739 +Call Trace: + fb_set_var+0x604/0xeb0 drivers/video/fbdev/core/fbmem.c:1036 + do_fb_ioctl+0x234/0x670 drivers/video/fbdev/core/fbmem.c:1112 + fb_ioctl+0xdd/0x130 drivers/video/fbdev/core/fbmem.c:1191 + vfs_ioctl fs/ioctl.c:51 [inline] + __do_sys_ioctl fs/ioctl.c:874 [inline] + +Signed-off-by: Zheyu Ma +Signed-off-by: Helge Deller +Acked-by: Takashi Iwai + +--- + drivers/video/fbdev/i740fb.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/video/fbdev/i740fb.c b/drivers/video/fbdev/i740fb.c +index dd45ea8203be..09dd85553d4f 100644 +--- a/drivers/video/fbdev/i740fb.c ++++ b/drivers/video/fbdev/i740fb.c +@@ -657,6 +657,9 @@ static int i740fb_decode_var(const struct fb_var_screeninfo *var, + + static int i740fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) + { ++ if (!var->pixclock) ++ return -EINVAL; ++ + switch (var->bits_per_pixel) { + case 8: + var->red.offset = var->green.offset = var->blue.offset = 0; +-- +2.35.3 + diff --git a/patches.suse/video-fbdev-pxa3xx-gcu-Fix-integer-overflow-in-pxa3x.patch b/patches.suse/video-fbdev-pxa3xx-gcu-Fix-integer-overflow-in-pxa3x.patch new file mode 100644 index 0000000..a903ed1 --- /dev/null +++ b/patches.suse/video-fbdev-pxa3xx-gcu-Fix-integer-overflow-in-pxa3x.patch @@ -0,0 +1,36 @@ +From a09d2d00af53b43c6f11e6ab3cb58443c2cac8a7 Mon Sep 17 00:00:00 2001 +From: Hyunwoo Kim +Date: Mon, 20 Jun 2022 07:17:46 -0700 +Subject: [PATCH] video: fbdev: pxa3xx-gcu: Fix integer overflow in pxa3xx_gcu_write +Git-commit: a09d2d00af53b43c6f11e6ab3cb58443c2cac8a7 +Patch-mainline: v5.19-rc4 +References: git-fixes + +In pxa3xx_gcu_write, a count parameter of type size_t is passed to words of +type int. Then, copy_from_user() may cause a heap overflow because it is used +as the third argument of copy_from_user(). + +Signed-off-by: Hyunwoo Kim +Signed-off-by: Helge Deller +Acked-by: Takashi Iwai + +--- + drivers/video/fbdev/pxa3xx-gcu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/video/fbdev/pxa3xx-gcu.c b/drivers/video/fbdev/pxa3xx-gcu.c +index 043cc8f9ef1c..c3cd1e1cc01b 100644 +--- a/drivers/video/fbdev/pxa3xx-gcu.c ++++ b/drivers/video/fbdev/pxa3xx-gcu.c +@@ -381,7 +381,7 @@ pxa3xx_gcu_write(struct file *file, const char *buff, + struct pxa3xx_gcu_batch *buffer; + struct pxa3xx_gcu_priv *priv = to_pxa3xx_gcu_priv(file); + +- int words = count / 4; ++ size_t words = count / 4; + + /* Does not need to be atomic. There's a lock in user space, + * but anyhow, this is just for statistics. */ +-- +2.35.3 + diff --git a/patches.suse/virt-Add-SEV-SNP-guest-driver b/patches.suse/virt-Add-SEV-SNP-guest-driver new file mode 100644 index 0000000..2410fed --- /dev/null +++ b/patches.suse/virt-Add-SEV-SNP-guest-driver @@ -0,0 +1,942 @@ +From: Brijesh Singh +Date: Mon, 7 Mar 2022 15:33:53 -0600 +Subject: virt: Add SEV-SNP guest driver +Git-commit: fce96cf0443083e37455eff8f78fd240c621dae3 +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +The SEV-SNP specification provides the guest a mechanism to communicate +with the PSP without risk from a malicious hypervisor who wishes to +read, alter, drop or replay the messages sent. The driver uses +snp_issue_guest_request() to issue GHCB SNP_GUEST_REQUEST or +SNP_EXT_GUEST_REQUEST NAE events to submit the request to PSP. + +The PSP requires that all communication should be encrypted using key +specified through a struct snp_guest_platform_data descriptor. + +Userspace can use SNP_GET_REPORT ioctl() to query the guest attestation +report. + +See SEV-SNP spec section Guest Messages for more details. + + [ bp: Remove the "what" from the commit message, massage. ] + +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220307213356.2797205-44-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + Documentation/virt/coco/sevguest.rst | 86 ++++ + Documentation/virt/index.rst | 1 + drivers/virt/Kconfig | 3 + drivers/virt/Makefile | 1 + drivers/virt/coco/sevguest/Kconfig | 14 + drivers/virt/coco/sevguest/Makefile | 2 + drivers/virt/coco/sevguest/sevguest.c | 607 ++++++++++++++++++++++++++++++++++ + drivers/virt/coco/sevguest/sevguest.h | 98 +++++ + include/uapi/linux/sev-guest.h | 50 ++ + 9 files changed, 862 insertions(+) + +--- /dev/null ++++ b/Documentation/virt/coco/sevguest.rst +@@ -0,0 +1,86 @@ ++.. SPDX-License-Identifier: GPL-2.0 ++ ++=================================================================== ++The Definitive SEV Guest API Documentation ++=================================================================== ++ ++1. General description ++====================== ++ ++The SEV API is a set of ioctls that are used by the guest or hypervisor ++to get or set a certain aspect of the SEV virtual machine. The ioctls belong ++to the following classes: ++ ++ - Hypervisor ioctls: These query and set global attributes which affect the ++ whole SEV firmware. These ioctl are used by platform provisioning tools. ++ ++ - Guest ioctls: These query and set attributes of the SEV virtual machine. ++ ++2. API description ++================== ++ ++This section describes ioctls that is used for querying the SEV guest report ++from the SEV firmware. For each ioctl, the following information is provided ++along with a description: ++ ++ Technology: ++ which SEV technology provides this ioctl. SEV, SEV-ES, SEV-SNP or all. ++ ++ Type: ++ hypervisor or guest. The ioctl can be used inside the guest or the ++ hypervisor. ++ ++ Parameters: ++ what parameters are accepted by the ioctl. ++ ++ Returns: ++ the return value. General error numbers (-ENOMEM, -EINVAL) ++ are not detailed, but errors with specific meanings are. ++ ++The guest ioctl should be issued on a file descriptor of the /dev/sev-guest device. ++The ioctl accepts struct snp_user_guest_request. The input and output structure is ++specified through the req_data and resp_data field respectively. If the ioctl fails ++to execute due to a firmware error, then fw_err code will be set otherwise the ++fw_err will be set to 0x00000000000000ff. ++ ++The firmware checks that the message sequence counter is one greater than ++the guests message sequence counter. If guest driver fails to increment message ++counter (e.g. counter overflow), then -EIO will be returned. ++ ++:: ++ ++ struct snp_guest_request_ioctl { ++ /* Message version number */ ++ __u32 msg_version; ++ ++ /* Request and response structure address */ ++ __u64 req_data; ++ __u64 resp_data; ++ ++ /* firmware error code on failure (see psp-sev.h) */ ++ __u64 fw_err; ++ }; ++ ++2.1 SNP_GET_REPORT ++------------------ ++ ++:Technology: sev-snp ++:Type: guest ioctl ++:Parameters (in): struct snp_report_req ++:Returns (out): struct snp_report_resp on success, -negative on error ++ ++The SNP_GET_REPORT ioctl can be used to query the attestation report from the ++SEV-SNP firmware. The ioctl uses the SNP_GUEST_REQUEST (MSG_REPORT_REQ) command ++provided by the SEV-SNP firmware to query the attestation report. ++ ++On success, the snp_report_resp.data will contains the report. The report ++contain the format described in the SEV-SNP specification. See the SEV-SNP ++specification for further details. ++ ++ ++Reference ++--------- ++ ++SEV-SNP and GHCB specification: developer.amd.com/sev ++ ++The driver is based on SEV-SNP firmware spec 0.9 and GHCB spec version 2.0. +--- a/Documentation/virt/index.rst ++++ b/Documentation/virt/index.rst +@@ -13,6 +13,7 @@ Linux Virtualization Support + guest-halt-polling + ne_overview + acrn/index ++ coco/sevguest + + .. only:: html and subproject + +--- a/drivers/virt/Kconfig ++++ b/drivers/virt/Kconfig +@@ -36,4 +36,7 @@ source "drivers/virt/vboxguest/Kconfig" + source "drivers/virt/nitro_enclaves/Kconfig" + + source "drivers/virt/acrn/Kconfig" ++ ++source "drivers/virt/coco/sevguest/Kconfig" ++ + endif +--- a/drivers/virt/Makefile ++++ b/drivers/virt/Makefile +@@ -8,3 +8,4 @@ obj-y += vboxguest/ + + obj-$(CONFIG_NITRO_ENCLAVES) += nitro_enclaves/ + obj-$(CONFIG_ACRN_HSM) += acrn/ ++obj-$(CONFIG_SEV_GUEST) += coco/sevguest/ +--- /dev/null ++++ b/drivers/virt/coco/sevguest/Kconfig +@@ -0,0 +1,14 @@ ++config SEV_GUEST ++ tristate "AMD SEV Guest driver" ++ default m ++ depends on AMD_MEM_ENCRYPT ++ select CRYPTO_AEAD2 ++ select CRYPTO_GCM ++ help ++ SEV-SNP firmware provides the guest a mechanism to communicate with ++ the PSP without risk from a malicious hypervisor who wishes to read, ++ alter, drop or replay the messages sent. The driver provides ++ userspace interface to communicate with the PSP to request the ++ attestation report and more. ++ ++ If you choose 'M' here, this module will be called sevguest. +--- /dev/null ++++ b/drivers/virt/coco/sevguest/Makefile +@@ -0,0 +1,2 @@ ++# SPDX-License-Identifier: GPL-2.0-only ++obj-$(CONFIG_SEV_GUEST) += sevguest.o +--- /dev/null ++++ b/drivers/virt/coco/sevguest/sevguest.c +@@ -0,0 +1,607 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * AMD Secure Encrypted Virtualization Nested Paging (SEV-SNP) guest request interface ++ * ++ * Copyright (C) 2021 Advanced Micro Devices, Inc. ++ * ++ * Author: Brijesh Singh ++ */ ++ ++#define pr_fmt(fmt) "SNP: GUEST: " fmt ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include "sevguest.h" ++ ++#define DEVICE_NAME "sev-guest" ++#define AAD_LEN 48 ++#define MSG_HDR_VER 1 ++ ++struct snp_guest_crypto { ++ struct crypto_aead *tfm; ++ u8 *iv, *authtag; ++ int iv_len, a_len; ++}; ++ ++struct snp_guest_dev { ++ struct device *dev; ++ struct miscdevice misc; ++ ++ struct snp_guest_crypto *crypto; ++ struct snp_guest_msg *request, *response; ++ struct snp_secrets_page_layout *layout; ++ struct snp_req_data input; ++ u32 *os_area_msg_seqno; ++ u8 *vmpck; ++}; ++ ++static u32 vmpck_id; ++module_param(vmpck_id, uint, 0444); ++MODULE_PARM_DESC(vmpck_id, "The VMPCK ID to use when communicating with the PSP."); ++ ++/* Mutex to serialize the shared buffer access and command handling. */ ++static DEFINE_MUTEX(snp_cmd_mutex); ++ ++static bool is_vmpck_empty(struct snp_guest_dev *snp_dev) ++{ ++ char zero_key[VMPCK_KEY_LEN] = {0}; ++ ++ if (snp_dev->vmpck) ++ return !memcmp(snp_dev->vmpck, zero_key, VMPCK_KEY_LEN); ++ ++ return true; ++} ++ ++static void snp_disable_vmpck(struct snp_guest_dev *snp_dev) ++{ ++ memzero_explicit(snp_dev->vmpck, VMPCK_KEY_LEN); ++ snp_dev->vmpck = NULL; ++} ++ ++static inline u64 __snp_get_msg_seqno(struct snp_guest_dev *snp_dev) ++{ ++ u64 count; ++ ++ lockdep_assert_held(&snp_cmd_mutex); ++ ++ /* Read the current message sequence counter from secrets pages */ ++ count = *snp_dev->os_area_msg_seqno; ++ ++ return count + 1; ++} ++ ++/* Return a non-zero on success */ ++static u64 snp_get_msg_seqno(struct snp_guest_dev *snp_dev) ++{ ++ u64 count = __snp_get_msg_seqno(snp_dev); ++ ++ /* ++ * The message sequence counter for the SNP guest request is a 64-bit ++ * value but the version 2 of GHCB specification defines a 32-bit storage ++ * for it. If the counter exceeds the 32-bit value then return zero. ++ * The caller should check the return value, but if the caller happens to ++ * not check the value and use it, then the firmware treats zero as an ++ * invalid number and will fail the message request. ++ */ ++ if (count >= UINT_MAX) { ++ dev_err(snp_dev->dev, "request message sequence counter overflow\n"); ++ return 0; ++ } ++ ++ return count; ++} ++ ++static void snp_inc_msg_seqno(struct snp_guest_dev *snp_dev) ++{ ++ /* ++ * The counter is also incremented by the PSP, so increment it by 2 ++ * and save in secrets page. ++ */ ++ *snp_dev->os_area_msg_seqno += 2; ++} ++ ++static inline struct snp_guest_dev *to_snp_dev(struct file *file) ++{ ++ struct miscdevice *dev = file->private_data; ++ ++ return container_of(dev, struct snp_guest_dev, misc); ++} ++ ++static struct snp_guest_crypto *init_crypto(struct snp_guest_dev *snp_dev, u8 *key, size_t keylen) ++{ ++ struct snp_guest_crypto *crypto; ++ ++ crypto = kzalloc(sizeof(*crypto), GFP_KERNEL_ACCOUNT); ++ if (!crypto) ++ return NULL; ++ ++ crypto->tfm = crypto_alloc_aead("gcm(aes)", 0, 0); ++ if (IS_ERR(crypto->tfm)) ++ goto e_free; ++ ++ if (crypto_aead_setkey(crypto->tfm, key, keylen)) ++ goto e_free_crypto; ++ ++ crypto->iv_len = crypto_aead_ivsize(crypto->tfm); ++ crypto->iv = kmalloc(crypto->iv_len, GFP_KERNEL_ACCOUNT); ++ if (!crypto->iv) ++ goto e_free_crypto; ++ ++ if (crypto_aead_authsize(crypto->tfm) > MAX_AUTHTAG_LEN) { ++ if (crypto_aead_setauthsize(crypto->tfm, MAX_AUTHTAG_LEN)) { ++ dev_err(snp_dev->dev, "failed to set authsize to %d\n", MAX_AUTHTAG_LEN); ++ goto e_free_iv; ++ } ++ } ++ ++ crypto->a_len = crypto_aead_authsize(crypto->tfm); ++ crypto->authtag = kmalloc(crypto->a_len, GFP_KERNEL_ACCOUNT); ++ if (!crypto->authtag) ++ goto e_free_auth; ++ ++ return crypto; ++ ++e_free_auth: ++ kfree(crypto->authtag); ++e_free_iv: ++ kfree(crypto->iv); ++e_free_crypto: ++ crypto_free_aead(crypto->tfm); ++e_free: ++ kfree(crypto); ++ ++ return NULL; ++} ++ ++static void deinit_crypto(struct snp_guest_crypto *crypto) ++{ ++ crypto_free_aead(crypto->tfm); ++ kfree(crypto->iv); ++ kfree(crypto->authtag); ++ kfree(crypto); ++} ++ ++static int enc_dec_message(struct snp_guest_crypto *crypto, struct snp_guest_msg *msg, ++ u8 *src_buf, u8 *dst_buf, size_t len, bool enc) ++{ ++ struct snp_guest_msg_hdr *hdr = &msg->hdr; ++ struct scatterlist src[3], dst[3]; ++ DECLARE_CRYPTO_WAIT(wait); ++ struct aead_request *req; ++ int ret; ++ ++ req = aead_request_alloc(crypto->tfm, GFP_KERNEL); ++ if (!req) ++ return -ENOMEM; ++ ++ /* ++ * AEAD memory operations: ++ * +------ AAD -------+------- DATA -----+---- AUTHTAG----+ ++ * | msg header | plaintext | hdr->authtag | ++ * | bytes 30h - 5Fh | or | | ++ * | | cipher | | ++ * +------------------+------------------+----------------+ ++ */ ++ sg_init_table(src, 3); ++ sg_set_buf(&src[0], &hdr->algo, AAD_LEN); ++ sg_set_buf(&src[1], src_buf, hdr->msg_sz); ++ sg_set_buf(&src[2], hdr->authtag, crypto->a_len); ++ ++ sg_init_table(dst, 3); ++ sg_set_buf(&dst[0], &hdr->algo, AAD_LEN); ++ sg_set_buf(&dst[1], dst_buf, hdr->msg_sz); ++ sg_set_buf(&dst[2], hdr->authtag, crypto->a_len); ++ ++ aead_request_set_ad(req, AAD_LEN); ++ aead_request_set_tfm(req, crypto->tfm); ++ aead_request_set_callback(req, 0, crypto_req_done, &wait); ++ ++ aead_request_set_crypt(req, src, dst, len, crypto->iv); ++ ret = crypto_wait_req(enc ? crypto_aead_encrypt(req) : crypto_aead_decrypt(req), &wait); ++ ++ aead_request_free(req); ++ return ret; ++} ++ ++static int __enc_payload(struct snp_guest_dev *snp_dev, struct snp_guest_msg *msg, ++ void *plaintext, size_t len) ++{ ++ struct snp_guest_crypto *crypto = snp_dev->crypto; ++ struct snp_guest_msg_hdr *hdr = &msg->hdr; ++ ++ memset(crypto->iv, 0, crypto->iv_len); ++ memcpy(crypto->iv, &hdr->msg_seqno, sizeof(hdr->msg_seqno)); ++ ++ return enc_dec_message(crypto, msg, plaintext, msg->payload, len, true); ++} ++ ++static int dec_payload(struct snp_guest_dev *snp_dev, struct snp_guest_msg *msg, ++ void *plaintext, size_t len) ++{ ++ struct snp_guest_crypto *crypto = snp_dev->crypto; ++ struct snp_guest_msg_hdr *hdr = &msg->hdr; ++ ++ /* Build IV with response buffer sequence number */ ++ memset(crypto->iv, 0, crypto->iv_len); ++ memcpy(crypto->iv, &hdr->msg_seqno, sizeof(hdr->msg_seqno)); ++ ++ return enc_dec_message(crypto, msg, msg->payload, plaintext, len, false); ++} ++ ++static int verify_and_dec_payload(struct snp_guest_dev *snp_dev, void *payload, u32 sz) ++{ ++ struct snp_guest_crypto *crypto = snp_dev->crypto; ++ struct snp_guest_msg *resp = snp_dev->response; ++ struct snp_guest_msg *req = snp_dev->request; ++ struct snp_guest_msg_hdr *req_hdr = &req->hdr; ++ struct snp_guest_msg_hdr *resp_hdr = &resp->hdr; ++ ++ dev_dbg(snp_dev->dev, "response [seqno %lld type %d version %d sz %d]\n", ++ resp_hdr->msg_seqno, resp_hdr->msg_type, resp_hdr->msg_version, resp_hdr->msg_sz); ++ ++ /* Verify that the sequence counter is incremented by 1 */ ++ if (unlikely(resp_hdr->msg_seqno != (req_hdr->msg_seqno + 1))) ++ return -EBADMSG; ++ ++ /* Verify response message type and version number. */ ++ if (resp_hdr->msg_type != (req_hdr->msg_type + 1) || ++ resp_hdr->msg_version != req_hdr->msg_version) ++ return -EBADMSG; ++ ++ /* ++ * If the message size is greater than our buffer length then return ++ * an error. ++ */ ++ if (unlikely((resp_hdr->msg_sz + crypto->a_len) > sz)) ++ return -EBADMSG; ++ ++ /* Decrypt the payload */ ++ return dec_payload(snp_dev, resp, payload, resp_hdr->msg_sz + crypto->a_len); ++} ++ ++static bool enc_payload(struct snp_guest_dev *snp_dev, u64 seqno, int version, u8 type, ++ void *payload, size_t sz) ++{ ++ struct snp_guest_msg *req = snp_dev->request; ++ struct snp_guest_msg_hdr *hdr = &req->hdr; ++ ++ memset(req, 0, sizeof(*req)); ++ ++ hdr->algo = SNP_AEAD_AES_256_GCM; ++ hdr->hdr_version = MSG_HDR_VER; ++ hdr->hdr_sz = sizeof(*hdr); ++ hdr->msg_type = type; ++ hdr->msg_version = version; ++ hdr->msg_seqno = seqno; ++ hdr->msg_vmpck = vmpck_id; ++ hdr->msg_sz = sz; ++ ++ /* Verify the sequence number is non-zero */ ++ if (!hdr->msg_seqno) ++ return -ENOSR; ++ ++ dev_dbg(snp_dev->dev, "request [seqno %lld type %d version %d sz %d]\n", ++ hdr->msg_seqno, hdr->msg_type, hdr->msg_version, hdr->msg_sz); ++ ++ return __enc_payload(snp_dev, req, payload, sz); ++} ++ ++static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, int msg_ver, ++ u8 type, void *req_buf, size_t req_sz, void *resp_buf, ++ u32 resp_sz, __u64 *fw_err) ++{ ++ unsigned long err; ++ u64 seqno; ++ int rc; ++ ++ /* Get message sequence and verify that its a non-zero */ ++ seqno = snp_get_msg_seqno(snp_dev); ++ if (!seqno) ++ return -EIO; ++ ++ memset(snp_dev->response, 0, sizeof(struct snp_guest_msg)); ++ ++ /* Encrypt the userspace provided payload */ ++ rc = enc_payload(snp_dev, seqno, msg_ver, type, req_buf, req_sz); ++ if (rc) ++ return rc; ++ ++ /* Call firmware to process the request */ ++ rc = snp_issue_guest_request(exit_code, &snp_dev->input, &err); ++ if (fw_err) ++ *fw_err = err; ++ ++ if (rc) ++ return rc; ++ ++ /* ++ * The verify_and_dec_payload() will fail only if the hypervisor is ++ * actively modifying the message header or corrupting the encrypted payload. ++ * This hints that hypervisor is acting in a bad faith. Disable the VMPCK so that ++ * the key cannot be used for any communication. The key is disabled to ensure ++ * that AES-GCM does not use the same IV while encrypting the request payload. ++ */ ++ rc = verify_and_dec_payload(snp_dev, resp_buf, resp_sz); ++ if (rc) { ++ dev_alert(snp_dev->dev, ++ "Detected unexpected decode failure, disabling the vmpck_id %d\n", ++ vmpck_id); ++ snp_disable_vmpck(snp_dev); ++ return rc; ++ } ++ ++ /* Increment to new message sequence after payload decryption was successful. */ ++ snp_inc_msg_seqno(snp_dev); ++ ++ return 0; ++} ++ ++static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_ioctl *arg) ++{ ++ struct snp_guest_crypto *crypto = snp_dev->crypto; ++ struct snp_report_resp *resp; ++ struct snp_report_req req; ++ int rc, resp_len; ++ ++ lockdep_assert_held(&snp_cmd_mutex); ++ ++ if (!arg->req_data || !arg->resp_data) ++ return -EINVAL; ++ ++ if (copy_from_user(&req, (void __user *)arg->req_data, sizeof(req))) ++ return -EFAULT; ++ ++ /* ++ * The intermediate response buffer is used while decrypting the ++ * response payload. Make sure that it has enough space to cover the ++ * authtag. ++ */ ++ resp_len = sizeof(resp->data) + crypto->a_len; ++ resp = kzalloc(resp_len, GFP_KERNEL_ACCOUNT); ++ if (!resp) ++ return -ENOMEM; ++ ++ rc = handle_guest_request(snp_dev, SVM_VMGEXIT_GUEST_REQUEST, arg->msg_version, ++ SNP_MSG_REPORT_REQ, &req, sizeof(req), resp->data, ++ resp_len, &arg->fw_err); ++ if (rc) ++ goto e_free; ++ ++ if (copy_to_user((void __user *)arg->resp_data, resp, sizeof(*resp))) ++ rc = -EFAULT; ++ ++e_free: ++ kfree(resp); ++ return rc; ++} ++ ++static long snp_guest_ioctl(struct file *file, unsigned int ioctl, unsigned long arg) ++{ ++ struct snp_guest_dev *snp_dev = to_snp_dev(file); ++ void __user *argp = (void __user *)arg; ++ struct snp_guest_request_ioctl input; ++ int ret = -ENOTTY; ++ ++ if (copy_from_user(&input, argp, sizeof(input))) ++ return -EFAULT; ++ ++ input.fw_err = 0xff; ++ ++ /* Message version must be non-zero */ ++ if (!input.msg_version) ++ return -EINVAL; ++ ++ mutex_lock(&snp_cmd_mutex); ++ ++ /* Check if the VMPCK is not empty */ ++ if (is_vmpck_empty(snp_dev)) { ++ dev_err_ratelimited(snp_dev->dev, "VMPCK is disabled\n"); ++ mutex_unlock(&snp_cmd_mutex); ++ return -ENOTTY; ++ } ++ ++ switch (ioctl) { ++ case SNP_GET_REPORT: ++ ret = get_report(snp_dev, &input); ++ break; ++ default: ++ break; ++ } ++ ++ mutex_unlock(&snp_cmd_mutex); ++ ++ if (input.fw_err && copy_to_user(argp, &input, sizeof(input))) ++ return -EFAULT; ++ ++ return ret; ++} ++ ++static void free_shared_pages(void *buf, size_t sz) ++{ ++ unsigned int npages = PAGE_ALIGN(sz) >> PAGE_SHIFT; ++ int ret; ++ ++ if (!buf) ++ return; ++ ++ ret = set_memory_encrypted((unsigned long)buf, npages); ++ if (ret) { ++ WARN_ONCE(ret, "failed to restore encryption mask (leak it)\n"); ++ return; ++ } ++ ++ __free_pages(virt_to_page(buf), get_order(sz)); ++} ++ ++static void *alloc_shared_pages(size_t sz) ++{ ++ unsigned int npages = PAGE_ALIGN(sz) >> PAGE_SHIFT; ++ struct page *page; ++ int ret; ++ ++ page = alloc_pages(GFP_KERNEL_ACCOUNT, get_order(sz)); ++ if (IS_ERR(page)) ++ return NULL; ++ ++ ret = set_memory_decrypted((unsigned long)page_address(page), npages); ++ if (ret) { ++ pr_err("failed to mark page shared, ret=%d\n", ret); ++ __free_pages(page, get_order(sz)); ++ return NULL; ++ } ++ ++ return page_address(page); ++} ++ ++static const struct file_operations snp_guest_fops = { ++ .owner = THIS_MODULE, ++ .unlocked_ioctl = snp_guest_ioctl, ++}; ++ ++static u8 *get_vmpck(int id, struct snp_secrets_page_layout *layout, u32 **seqno) ++{ ++ u8 *key = NULL; ++ ++ switch (id) { ++ case 0: ++ *seqno = &layout->os_area.msg_seqno_0; ++ key = layout->vmpck0; ++ break; ++ case 1: ++ *seqno = &layout->os_area.msg_seqno_1; ++ key = layout->vmpck1; ++ break; ++ case 2: ++ *seqno = &layout->os_area.msg_seqno_2; ++ key = layout->vmpck2; ++ break; ++ case 3: ++ *seqno = &layout->os_area.msg_seqno_3; ++ key = layout->vmpck3; ++ break; ++ default: ++ break; ++ } ++ ++ return key; ++} ++ ++static int __init snp_guest_probe(struct platform_device *pdev) ++{ ++ struct snp_secrets_page_layout *layout; ++ struct snp_guest_platform_data *data; ++ struct device *dev = &pdev->dev; ++ struct snp_guest_dev *snp_dev; ++ struct miscdevice *misc; ++ int ret; ++ ++ if (!dev->platform_data) ++ return -ENODEV; ++ ++ data = (struct snp_guest_platform_data *)dev->platform_data; ++ layout = (__force void *)ioremap_encrypted(data->secrets_gpa, PAGE_SIZE); ++ if (!layout) ++ return -ENODEV; ++ ++ ret = -ENOMEM; ++ snp_dev = devm_kzalloc(&pdev->dev, sizeof(struct snp_guest_dev), GFP_KERNEL); ++ if (!snp_dev) ++ goto e_unmap; ++ ++ ret = -EINVAL; ++ snp_dev->vmpck = get_vmpck(vmpck_id, layout, &snp_dev->os_area_msg_seqno); ++ if (!snp_dev->vmpck) { ++ dev_err(dev, "invalid vmpck id %d\n", vmpck_id); ++ goto e_unmap; ++ } ++ ++ /* Verify that VMPCK is not zero. */ ++ if (is_vmpck_empty(snp_dev)) { ++ dev_err(dev, "vmpck id %d is null\n", vmpck_id); ++ goto e_unmap; ++ } ++ ++ platform_set_drvdata(pdev, snp_dev); ++ snp_dev->dev = dev; ++ snp_dev->layout = layout; ++ ++ /* Allocate the shared page used for the request and response message. */ ++ snp_dev->request = alloc_shared_pages(sizeof(struct snp_guest_msg)); ++ if (!snp_dev->request) ++ goto e_unmap; ++ ++ snp_dev->response = alloc_shared_pages(sizeof(struct snp_guest_msg)); ++ if (!snp_dev->response) ++ goto e_free_request; ++ ++ ret = -EIO; ++ snp_dev->crypto = init_crypto(snp_dev, snp_dev->vmpck, VMPCK_KEY_LEN); ++ if (!snp_dev->crypto) ++ goto e_free_response; ++ ++ misc = &snp_dev->misc; ++ misc->minor = MISC_DYNAMIC_MINOR; ++ misc->name = DEVICE_NAME; ++ misc->fops = &snp_guest_fops; ++ ++ /* initial the input address for guest request */ ++ snp_dev->input.req_gpa = __pa(snp_dev->request); ++ snp_dev->input.resp_gpa = __pa(snp_dev->response); ++ ++ ret = misc_register(misc); ++ if (ret) ++ goto e_free_response; ++ ++ dev_info(dev, "Initialized SNP guest driver (using vmpck_id %d)\n", vmpck_id); ++ return 0; ++ ++e_free_response: ++ free_shared_pages(snp_dev->response, sizeof(struct snp_guest_msg)); ++e_free_request: ++ free_shared_pages(snp_dev->request, sizeof(struct snp_guest_msg)); ++e_unmap: ++ iounmap(layout); ++ return ret; ++} ++ ++static int __exit snp_guest_remove(struct platform_device *pdev) ++{ ++ struct snp_guest_dev *snp_dev = platform_get_drvdata(pdev); ++ ++ free_shared_pages(snp_dev->response, sizeof(struct snp_guest_msg)); ++ free_shared_pages(snp_dev->request, sizeof(struct snp_guest_msg)); ++ deinit_crypto(snp_dev->crypto); ++ misc_deregister(&snp_dev->misc); ++ ++ return 0; ++} ++ ++static struct platform_driver snp_guest_driver = { ++ .remove = __exit_p(snp_guest_remove), ++ .driver = { ++ .name = "snp-guest", ++ }, ++}; ++ ++module_platform_driver_probe(snp_guest_driver, snp_guest_probe); ++ ++MODULE_AUTHOR("Brijesh Singh "); ++MODULE_LICENSE("GPL"); ++MODULE_VERSION("1.0.0"); ++MODULE_DESCRIPTION("AMD SNP Guest Driver"); +--- /dev/null ++++ b/drivers/virt/coco/sevguest/sevguest.h +@@ -0,0 +1,98 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * Copyright (C) 2021 Advanced Micro Devices, Inc. ++ * ++ * Author: Brijesh Singh ++ * ++ * SEV-SNP API spec is available at https://developer.amd.com/sev ++ */ ++ ++#ifndef __VIRT_SEVGUEST_H__ ++#define __VIRT_SEVGUEST_H__ ++ ++#include ++ ++#define MAX_AUTHTAG_LEN 32 ++ ++/* See SNP spec SNP_GUEST_REQUEST section for the structure */ ++enum msg_type { ++ SNP_MSG_TYPE_INVALID = 0, ++ SNP_MSG_CPUID_REQ, ++ SNP_MSG_CPUID_RSP, ++ SNP_MSG_KEY_REQ, ++ SNP_MSG_KEY_RSP, ++ SNP_MSG_REPORT_REQ, ++ SNP_MSG_REPORT_RSP, ++ SNP_MSG_EXPORT_REQ, ++ SNP_MSG_EXPORT_RSP, ++ SNP_MSG_IMPORT_REQ, ++ SNP_MSG_IMPORT_RSP, ++ SNP_MSG_ABSORB_REQ, ++ SNP_MSG_ABSORB_RSP, ++ SNP_MSG_VMRK_REQ, ++ SNP_MSG_VMRK_RSP, ++ ++ SNP_MSG_TYPE_MAX ++}; ++ ++enum aead_algo { ++ SNP_AEAD_INVALID, ++ SNP_AEAD_AES_256_GCM, ++}; ++ ++struct snp_guest_msg_hdr { ++ u8 authtag[MAX_AUTHTAG_LEN]; ++ u64 msg_seqno; ++ u8 rsvd1[8]; ++ u8 algo; ++ u8 hdr_version; ++ u16 hdr_sz; ++ u8 msg_type; ++ u8 msg_version; ++ u16 msg_sz; ++ u32 rsvd2; ++ u8 msg_vmpck; ++ u8 rsvd3[35]; ++} __packed; ++ ++struct snp_guest_msg { ++ struct snp_guest_msg_hdr hdr; ++ u8 payload[4000]; ++} __packed; ++ ++/* ++ * The secrets page contains 96-bytes of reserved field that can be used by ++ * the guest OS. The guest OS uses the area to save the message sequence ++ * number for each VMPCK. ++ * ++ * See the GHCB spec section Secret page layout for the format for this area. ++ */ ++struct secrets_os_area { ++ u32 msg_seqno_0; ++ u32 msg_seqno_1; ++ u32 msg_seqno_2; ++ u32 msg_seqno_3; ++ u64 ap_jump_table_pa; ++ u8 rsvd[40]; ++ u8 guest_usage[32]; ++} __packed; ++ ++#define VMPCK_KEY_LEN 32 ++ ++/* See the SNP spec version 0.9 for secrets page format */ ++struct snp_secrets_page_layout { ++ u32 version; ++ u32 imien : 1, ++ rsvd1 : 31; ++ u32 fms; ++ u32 rsvd2; ++ u8 gosvw[16]; ++ u8 vmpck0[VMPCK_KEY_LEN]; ++ u8 vmpck1[VMPCK_KEY_LEN]; ++ u8 vmpck2[VMPCK_KEY_LEN]; ++ u8 vmpck3[VMPCK_KEY_LEN]; ++ struct secrets_os_area os_area; ++ u8 rsvd3[3840]; ++} __packed; ++ ++#endif /* __VIRT_SEVGUEST_H__ */ +--- /dev/null ++++ b/include/uapi/linux/sev-guest.h +@@ -0,0 +1,50 @@ ++/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ ++/* ++ * Userspace interface for AMD SEV and SNP guest driver. ++ * ++ * Copyright (C) 2021 Advanced Micro Devices, Inc. ++ * ++ * Author: Brijesh Singh ++ * ++ * SEV API specification is available at: https://developer.amd.com/sev/ ++ */ ++ ++#ifndef __UAPI_LINUX_SEV_GUEST_H_ ++#define __UAPI_LINUX_SEV_GUEST_H_ ++ ++#include ++ ++struct snp_report_req { ++ /* user data that should be included in the report */ ++ __u8 user_data[64]; ++ ++ /* The vmpl level to be included in the report */ ++ __u32 vmpl; ++ ++ /* Must be zero filled */ ++ __u8 rsvd[28]; ++}; ++ ++struct snp_report_resp { ++ /* response data, see SEV-SNP spec for the format */ ++ __u8 data[4000]; ++}; ++ ++struct snp_guest_request_ioctl { ++ /* message version number (must be non-zero) */ ++ __u8 msg_version; ++ ++ /* Request and response structure address */ ++ __u64 req_data; ++ __u64 resp_data; ++ ++ /* firmware error code on failure (see psp-sev.h) */ ++ __u64 fw_err; ++}; ++ ++#define SNP_GUEST_REQ_IOC_TYPE 'S' ++ ++/* Get SNP attestation report */ ++#define SNP_GET_REPORT _IOWR(SNP_GUEST_REQ_IOC_TYPE, 0x0, struct snp_guest_request_ioctl) ++ ++#endif /* __UAPI_LINUX_SEV_GUEST_H_ */ diff --git a/patches.suse/virt-sevguest-Add-documentation-for-SEV-SNP-CPUID-Enforcement b/patches.suse/virt-sevguest-Add-documentation-for-SEV-SNP-CPUID-Enforcement new file mode 100644 index 0000000..38c731c --- /dev/null +++ b/patches.suse/virt-sevguest-Add-documentation-for-SEV-SNP-CPUID-Enforcement @@ -0,0 +1,58 @@ +From: Michael Roth +Date: Thu, 24 Feb 2022 10:56:25 -0600 +Subject: virt: sevguest: Add documentation for SEV-SNP CPUID Enforcement +Git-commit: 92a99584d965b930988b28f36d925bd9675828b3 +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +Update the documentation with information regarding SEV-SNP CPUID +Enforcement details and what sort of assurances it provides to guests. + +Signed-off-by: Michael Roth +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220307213356.2797205-47-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + Documentation/virt/coco/sevguest.rst | 29 +++++++++++++++++++++++++++++ + 1 file changed, 29 insertions(+) + +--- a/Documentation/virt/coco/sevguest.rst ++++ b/Documentation/virt/coco/sevguest.rst +@@ -118,6 +118,35 @@ be updated with the expected value. + + See GHCB specification for further detail on how to parse the certificate blob. + ++3. SEV-SNP CPUID Enforcement ++============================ ++ ++SEV-SNP guests can access a special page that contains a table of CPUID values ++that have been validated by the PSP as part of the SNP_LAUNCH_UPDATE firmware ++command. It provides the following assurances regarding the validity of CPUID ++values: ++ ++ - Its address is obtained via bootloader/firmware (via CC blob), and those ++ binaries will be measured as part of the SEV-SNP attestation report. ++ - Its initial state will be encrypted/pvalidated, so attempts to modify ++ it during run-time will result in garbage being written, or #VC exceptions ++ being generated due to changes in validation state if the hypervisor tries ++ to swap the backing page. ++ - Attempts to bypass PSP checks by the hypervisor by using a normal page, or ++ a non-CPUID encrypted page will change the measurement provided by the ++ SEV-SNP attestation report. ++ - The CPUID page contents are *not* measured, but attempts to modify the ++ expected contents of a CPUID page as part of guest initialization will be ++ gated by the PSP CPUID enforcement policy checks performed on the page ++ during SNP_LAUNCH_UPDATE, and noticeable later if the guest owner ++ implements their own checks of the CPUID values. ++ ++It is important to note that this last assurance is only useful if the kernel ++has taken care to make use of the SEV-SNP CPUID throughout all stages of boot. ++Otherwise, guest owner attestation provides no assurance that the kernel wasn't ++fed incorrect values at some point during boot. ++ ++ + Reference + --------- + diff --git a/patches.suse/virt-sevguest-Add-support-to-derive-key b/patches.suse/virt-sevguest-Add-support-to-derive-key new file mode 100644 index 0000000..9232c9a --- /dev/null +++ b/patches.suse/virt-sevguest-Add-support-to-derive-key @@ -0,0 +1,146 @@ +From: Brijesh Singh +Date: Thu, 24 Feb 2022 10:56:23 -0600 +Subject: virt: sevguest: Add support to derive key +Git-commit: 68de0b2f938642079c0c853b219bdb88c4dc4d13 +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +The SNP_GET_DERIVED_KEY ioctl interface can be used by the SNP guest to +ask the firmware to provide a key derived from a root key. The derived +key may be used by the guest for any purposes it chooses, such as a +sealing key or communicating with the external entities. + +See SEV-SNP firmware spec for more information. + + [ bp: No need to memset "req" - it will get overwritten. ] + +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Reviewed-by: Liam Merwick +Link: https://lore.kernel.org/r/20220307213356.2797205-45-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + Documentation/virt/coco/sevguest.rst | 17 ++++++++++++ + drivers/virt/coco/sevguest/sevguest.c | 45 ++++++++++++++++++++++++++++++++++ + include/uapi/linux/sev-guest.h | 17 ++++++++++++ + 3 files changed, 79 insertions(+) + +--- a/Documentation/virt/coco/sevguest.rst ++++ b/Documentation/virt/coco/sevguest.rst +@@ -77,6 +77,23 @@ On success, the snp_report_resp.data wil + contain the format described in the SEV-SNP specification. See the SEV-SNP + specification for further details. + ++2.2 SNP_GET_DERIVED_KEY ++----------------------- ++:Technology: sev-snp ++:Type: guest ioctl ++:Parameters (in): struct snp_derived_key_req ++:Returns (out): struct snp_derived_key_resp on success, -negative on error ++ ++The SNP_GET_DERIVED_KEY ioctl can be used to get a key derive from a root key. ++The derived key can be used by the guest for any purpose, such as sealing keys ++or communicating with external entities. ++ ++The ioctl uses the SNP_GUEST_REQUEST (MSG_KEY_REQ) command provided by the ++SEV-SNP firmware to derive the key. See SEV-SNP specification for further details ++on the various fields passed in the key derivation request. ++ ++On success, the snp_derived_key_resp.data contains the derived key value. See ++the SEV-SNP specification for further details. + + Reference + --------- +--- a/drivers/virt/coco/sevguest/sevguest.c ++++ b/drivers/virt/coco/sevguest/sevguest.c +@@ -391,6 +391,48 @@ e_free: + return rc; + } + ++static int get_derived_key(struct snp_guest_dev *snp_dev, struct snp_guest_request_ioctl *arg) ++{ ++ struct snp_guest_crypto *crypto = snp_dev->crypto; ++ struct snp_derived_key_resp resp = {0}; ++ struct snp_derived_key_req req; ++ int rc, resp_len; ++ /* Response data is 64 bytes and max authsize for GCM is 16 bytes. */ ++ u8 buf[64 + 16]; ++ ++ lockdep_assert_held(&snp_cmd_mutex); ++ ++ if (!arg->req_data || !arg->resp_data) ++ return -EINVAL; ++ ++ /* ++ * The intermediate response buffer is used while decrypting the ++ * response payload. Make sure that it has enough space to cover the ++ * authtag. ++ */ ++ resp_len = sizeof(resp.data) + crypto->a_len; ++ if (sizeof(buf) < resp_len) ++ return -ENOMEM; ++ ++ if (copy_from_user(&req, (void __user *)arg->req_data, sizeof(req))) ++ return -EFAULT; ++ ++ rc = handle_guest_request(snp_dev, SVM_VMGEXIT_GUEST_REQUEST, arg->msg_version, ++ SNP_MSG_KEY_REQ, &req, sizeof(req), buf, resp_len, ++ &arg->fw_err); ++ if (rc) ++ return rc; ++ ++ memcpy(resp.data, buf, sizeof(resp.data)); ++ if (copy_to_user((void __user *)arg->resp_data, &resp, sizeof(resp))) ++ rc = -EFAULT; ++ ++ /* The response buffer contains the sensitive data, explicitly clear it. */ ++ memzero_explicit(buf, sizeof(buf)); ++ memzero_explicit(&resp, sizeof(resp)); ++ return rc; ++} ++ + static long snp_guest_ioctl(struct file *file, unsigned int ioctl, unsigned long arg) + { + struct snp_guest_dev *snp_dev = to_snp_dev(file); +@@ -420,6 +462,9 @@ static long snp_guest_ioctl(struct file + case SNP_GET_REPORT: + ret = get_report(snp_dev, &input); + break; ++ case SNP_GET_DERIVED_KEY: ++ ret = get_derived_key(snp_dev, &input); ++ break; + default: + break; + } +--- a/include/uapi/linux/sev-guest.h ++++ b/include/uapi/linux/sev-guest.h +@@ -30,6 +30,20 @@ struct snp_report_resp { + __u8 data[4000]; + }; + ++struct snp_derived_key_req { ++ __u32 root_key_select; ++ __u32 rsvd; ++ __u64 guest_field_select; ++ __u32 vmpl; ++ __u32 guest_svn; ++ __u64 tcb_version; ++}; ++ ++struct snp_derived_key_resp { ++ /* response data, see SEV-SNP spec for the format */ ++ __u8 data[64]; ++}; ++ + struct snp_guest_request_ioctl { + /* message version number (must be non-zero) */ + __u8 msg_version; +@@ -47,4 +61,7 @@ struct snp_guest_request_ioctl { + /* Get SNP attestation report */ + #define SNP_GET_REPORT _IOWR(SNP_GUEST_REQ_IOC_TYPE, 0x0, struct snp_guest_request_ioctl) + ++/* Get a derived key from the root */ ++#define SNP_GET_DERIVED_KEY _IOWR(SNP_GUEST_REQ_IOC_TYPE, 0x1, struct snp_guest_request_ioctl) ++ + #endif /* __UAPI_LINUX_SEV_GUEST_H_ */ diff --git a/patches.suse/virt-sevguest-Add-support-to-get-extended-report b/patches.suse/virt-sevguest-Add-support-to-get-extended-report new file mode 100644 index 0000000..501bb69 --- /dev/null +++ b/patches.suse/virt-sevguest-Add-support-to-get-extended-report @@ -0,0 +1,234 @@ +From: Brijesh Singh +Date: Mon, 7 Mar 2022 15:33:55 -0600 +Subject: virt: sevguest: Add support to get extended report +Git-commit: d80b494f712317493d464a55652698c4d1b7bb0f +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +Version 2 of GHCB specification defines Non-Automatic-Exit (NAE) to get +extended guest report which is similar to the SNP_GET_REPORT ioctl. The +main difference is related to the additional data that will be returned. + +That additional data returned is a certificate blob that can be used by +the SNP guest user. The certificate blob layout is defined in the GHCB +specification. The driver simply treats the blob as a opaque data and +copies it to userspace. + + [ bp: Massage commit message, cast 1st arg of access_ok() ] + +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220307213356.2797205-46-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + Documentation/virt/coco/sevguest.rst | 23 ++++++++ + drivers/virt/coco/sevguest/sevguest.c | 92 +++++++++++++++++++++++++++++++++- + include/uapi/linux/sev-guest.h | 13 ++++ + 3 files changed, 126 insertions(+), 2 deletions(-) + +--- a/Documentation/virt/coco/sevguest.rst ++++ b/Documentation/virt/coco/sevguest.rst +@@ -95,6 +95,29 @@ on the various fields passed in the key + On success, the snp_derived_key_resp.data contains the derived key value. See + the SEV-SNP specification for further details. + ++ ++2.3 SNP_GET_EXT_REPORT ++---------------------- ++:Technology: sev-snp ++:Type: guest ioctl ++:Parameters (in/out): struct snp_ext_report_req ++:Returns (out): struct snp_report_resp on success, -negative on error ++ ++The SNP_GET_EXT_REPORT ioctl is similar to the SNP_GET_REPORT. The difference is ++related to the additional certificate data that is returned with the report. ++The certificate data returned is being provided by the hypervisor through the ++SNP_SET_EXT_CONFIG. ++ ++The ioctl uses the SNP_GUEST_REQUEST (MSG_REPORT_REQ) command provided by the SEV-SNP ++firmware to get the attestation report. ++ ++On success, the snp_ext_report_resp.data will contain the attestation report ++and snp_ext_report_req.certs_address will contain the certificate blob. If the ++length of the blob is smaller than expected then snp_ext_report_req.certs_len will ++be updated with the expected value. ++ ++See GHCB specification for further detail on how to parse the certificate blob. ++ + Reference + --------- + +--- a/drivers/virt/coco/sevguest/sevguest.c ++++ b/drivers/virt/coco/sevguest/sevguest.c +@@ -43,6 +43,7 @@ struct snp_guest_dev { + struct device *dev; + struct miscdevice misc; + ++ void *certs_data; + struct snp_guest_crypto *crypto; + struct snp_guest_msg *request, *response; + struct snp_secrets_page_layout *layout; +@@ -433,6 +434,82 @@ static int get_derived_key(struct snp_gu + return rc; + } + ++static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_ioctl *arg) ++{ ++ struct snp_guest_crypto *crypto = snp_dev->crypto; ++ struct snp_ext_report_req req; ++ struct snp_report_resp *resp; ++ int ret, npages = 0, resp_len; ++ ++ lockdep_assert_held(&snp_cmd_mutex); ++ ++ if (!arg->req_data || !arg->resp_data) ++ return -EINVAL; ++ ++ if (copy_from_user(&req, (void __user *)arg->req_data, sizeof(req))) ++ return -EFAULT; ++ ++ /* userspace does not want certificate data */ ++ if (!req.certs_len || !req.certs_address) ++ goto cmd; ++ ++ if (req.certs_len > SEV_FW_BLOB_MAX_SIZE || ++ !IS_ALIGNED(req.certs_len, PAGE_SIZE)) ++ return -EINVAL; ++ ++ if (!access_ok((const void __user *)req.certs_address, req.certs_len)) ++ return -EFAULT; ++ ++ /* ++ * Initialize the intermediate buffer with all zeros. This buffer ++ * is used in the guest request message to get the certs blob from ++ * the host. If host does not supply any certs in it, then copy ++ * zeros to indicate that certificate data was not provided. ++ */ ++ memset(snp_dev->certs_data, 0, req.certs_len); ++ npages = req.certs_len >> PAGE_SHIFT; ++cmd: ++ /* ++ * The intermediate response buffer is used while decrypting the ++ * response payload. Make sure that it has enough space to cover the ++ * authtag. ++ */ ++ resp_len = sizeof(resp->data) + crypto->a_len; ++ resp = kzalloc(resp_len, GFP_KERNEL_ACCOUNT); ++ if (!resp) ++ return -ENOMEM; ++ ++ snp_dev->input.data_npages = npages; ++ ret = handle_guest_request(snp_dev, SVM_VMGEXIT_EXT_GUEST_REQUEST, arg->msg_version, ++ SNP_MSG_REPORT_REQ, &req.data, ++ sizeof(req.data), resp->data, resp_len, &arg->fw_err); ++ ++ /* If certs length is invalid then copy the returned length */ ++ if (arg->fw_err == SNP_GUEST_REQ_INVALID_LEN) { ++ req.certs_len = snp_dev->input.data_npages << PAGE_SHIFT; ++ ++ if (copy_to_user((void __user *)arg->req_data, &req, sizeof(req))) ++ ret = -EFAULT; ++ } ++ ++ if (ret) ++ goto e_free; ++ ++ if (npages && ++ copy_to_user((void __user *)req.certs_address, snp_dev->certs_data, ++ req.certs_len)) { ++ ret = -EFAULT; ++ goto e_free; ++ } ++ ++ if (copy_to_user((void __user *)arg->resp_data, resp, sizeof(*resp))) ++ ret = -EFAULT; ++ ++e_free: ++ kfree(resp); ++ return ret; ++} ++ + static long snp_guest_ioctl(struct file *file, unsigned int ioctl, unsigned long arg) + { + struct snp_guest_dev *snp_dev = to_snp_dev(file); +@@ -465,6 +542,9 @@ static long snp_guest_ioctl(struct file + case SNP_GET_DERIVED_KEY: + ret = get_derived_key(snp_dev, &input); + break; ++ case SNP_GET_EXT_REPORT: ++ ret = get_ext_report(snp_dev, &input); ++ break; + default: + break; + } +@@ -595,10 +675,14 @@ static int __init snp_guest_probe(struct + if (!snp_dev->response) + goto e_free_request; + ++ snp_dev->certs_data = alloc_shared_pages(SEV_FW_BLOB_MAX_SIZE); ++ if (!snp_dev->certs_data) ++ goto e_free_response; ++ + ret = -EIO; + snp_dev->crypto = init_crypto(snp_dev, snp_dev->vmpck, VMPCK_KEY_LEN); + if (!snp_dev->crypto) +- goto e_free_response; ++ goto e_free_cert_data; + + misc = &snp_dev->misc; + misc->minor = MISC_DYNAMIC_MINOR; +@@ -608,14 +692,17 @@ static int __init snp_guest_probe(struct + /* initial the input address for guest request */ + snp_dev->input.req_gpa = __pa(snp_dev->request); + snp_dev->input.resp_gpa = __pa(snp_dev->response); ++ snp_dev->input.data_gpa = __pa(snp_dev->certs_data); + + ret = misc_register(misc); + if (ret) +- goto e_free_response; ++ goto e_free_cert_data; + + dev_info(dev, "Initialized SNP guest driver (using vmpck_id %d)\n", vmpck_id); + return 0; + ++e_free_cert_data: ++ free_shared_pages(snp_dev->certs_data, SEV_FW_BLOB_MAX_SIZE); + e_free_response: + free_shared_pages(snp_dev->response, sizeof(struct snp_guest_msg)); + e_free_request: +@@ -629,6 +716,7 @@ static int __exit snp_guest_remove(struc + { + struct snp_guest_dev *snp_dev = platform_get_drvdata(pdev); + ++ free_shared_pages(snp_dev->certs_data, SEV_FW_BLOB_MAX_SIZE); + free_shared_pages(snp_dev->response, sizeof(struct snp_guest_msg)); + free_shared_pages(snp_dev->request, sizeof(struct snp_guest_msg)); + deinit_crypto(snp_dev->crypto); +--- a/include/uapi/linux/sev-guest.h ++++ b/include/uapi/linux/sev-guest.h +@@ -56,6 +56,16 @@ struct snp_guest_request_ioctl { + __u64 fw_err; + }; + ++struct snp_ext_report_req { ++ struct snp_report_req data; ++ ++ /* where to copy the certificate blob */ ++ __u64 certs_address; ++ ++ /* length of the certificate blob */ ++ __u32 certs_len; ++}; ++ + #define SNP_GUEST_REQ_IOC_TYPE 'S' + + /* Get SNP attestation report */ +@@ -64,4 +74,7 @@ struct snp_guest_request_ioctl { + /* Get a derived key from the root */ + #define SNP_GET_DERIVED_KEY _IOWR(SNP_GUEST_REQ_IOC_TYPE, 0x1, struct snp_guest_request_ioctl) + ++/* Get SNP extended report as defined in the GHCB specification version 2. */ ++#define SNP_GET_EXT_REPORT _IOWR(SNP_GUEST_REQ_IOC_TYPE, 0x2, struct snp_guest_request_ioctl) ++ + #endif /* __UAPI_LINUX_SEV_GUEST_H_ */ diff --git a/patches.suse/virt-sevguest-Fix-bool-function-returning-negative-value b/patches.suse/virt-sevguest-Fix-bool-function-returning-negative-value new file mode 100644 index 0000000..2928b6a --- /dev/null +++ b/patches.suse/virt-sevguest-Fix-bool-function-returning-negative-value @@ -0,0 +1,33 @@ +From: Haowen Bai +Date: Thu, 14 Apr 2022 18:04:17 +0800 +Subject: virt: sevguest: Fix bool function returning negative value +Git-commit: 101826e02ac6c829bf4e768295e79ae9c37b4b2a +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +The function enc_payload() is wrongly declared bool but returns an +integer value. Correct it. + + [ bp: Massage commit message. ] + +Fixes: fce96cf04430 ("virt: Add SEV-SNP guest driver") +Signed-off-by: Haowen Bai +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/1649930657-10837-1-git-send-email-baihaowen@meizu.com + +Acked-by: Joerg Roedel +--- + drivers/virt/coco/sevguest/sevguest.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/virt/coco/sevguest/sevguest.c ++++ b/drivers/virt/coco/sevguest/sevguest.c +@@ -276,7 +276,7 @@ static int verify_and_dec_payload(struct + return dec_payload(snp_dev, resp, payload, resp_hdr->msg_sz + crypto->a_len); + } + +-static bool enc_payload(struct snp_guest_dev *snp_dev, u64 seqno, int version, u8 type, ++static int enc_payload(struct snp_guest_dev *snp_dev, u64 seqno, int version, u8 type, + void *payload, size_t sz) + { + struct snp_guest_msg *req = snp_dev->request; diff --git a/patches.suse/virt-sevguest-Fix-return-value-check-in-alloc_shared_pages b/patches.suse/virt-sevguest-Fix-return-value-check-in-alloc_shared_pages new file mode 100644 index 0000000..b8f3223 --- /dev/null +++ b/patches.suse/virt-sevguest-Fix-return-value-check-in-alloc_shared_pages @@ -0,0 +1,33 @@ +From: Yang Yingliang +Date: Mon, 11 Apr 2022 19:12:13 +0800 +Subject: virt: sevguest: Fix return value check in alloc_shared_pages() +Git-commit: e50abbf788c239d529f9ab81e325f8e8f8432c9d +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +If alloc_pages() fails, it returns a NULL pointer. Replace the wrong +IS_ERR() check with the proper NULL pointer check. + +Fixes: fce96cf04430 ("virt: Add SEV-SNP guest driver") +Reported-by: Hulk Robot +Signed-off-by: Yang Yingliang +Signed-off-by: Borislav Petkov +Reviewed-by: Brijesh Singh +Link: https://lore.kernel.org/r/20220411111213.1477853-1-yangyingliang@huawei.com + +Acked-by: Joerg Roedel +--- + drivers/virt/coco/sevguest/sevguest.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/virt/coco/sevguest/sevguest.c ++++ b/drivers/virt/coco/sevguest/sevguest.c +@@ -581,7 +581,7 @@ static void *alloc_shared_pages(size_t s + int ret; + + page = alloc_pages(GFP_KERNEL_ACCOUNT, get_order(sz)); +- if (IS_ERR(page)) ++ if (!page) + return NULL; + + ret = set_memory_decrypted((unsigned long)page_address(page), npages); diff --git a/patches.suse/virt-vbox-convert-to-use-dev_groups.patch b/patches.suse/virt-vbox-convert-to-use-dev_groups.patch new file mode 100644 index 0000000..d505df5 --- /dev/null +++ b/patches.suse/virt-vbox-convert-to-use-dev_groups.patch @@ -0,0 +1,71 @@ +From d4d2c58bdb9190baa1d5e1719c1339fcb2c17642 Mon Sep 17 00:00:00 2001 +From: Jiasheng Jiang +Date: Thu, 1 Sep 2022 22:46:10 +0800 +Subject: [PATCH] virt: vbox: convert to use dev_groups +Git-commit: d4d2c58bdb9190baa1d5e1719c1339fcb2c17642 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The driver core supports the ability to handle the creation and removal +of device-specific sysfs files in a race-free manner. Moreover, it can +guarantee the success of creation. Therefore, it should be better to +convert to use dev_groups. + +Fixes: 0ba002bc4393 ("virt: Add vboxguest driver for Virtual Box Guest integration") +Reviewed-by: Hans de Goede +Signed-off-by: Jiasheng Jiang +Link: https://lore.kernel.org/r/20220901144610.3550300-1-jiasheng@iscas.ac.cn +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/virt/vboxguest/vboxguest_linux.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/drivers/virt/vboxguest/vboxguest_linux.c b/drivers/virt/vboxguest/vboxguest_linux.c +index 4ccfd30c2a30..6fc81347ae72 100644 +--- a/drivers/virt/vboxguest/vboxguest_linux.c ++++ b/drivers/virt/vboxguest/vboxguest_linux.c +@@ -270,6 +270,13 @@ static ssize_t host_features_show(struct device *dev, + static DEVICE_ATTR_RO(host_version); + static DEVICE_ATTR_RO(host_features); + ++static struct attribute *vbg_pci_attrs[] = { ++ &dev_attr_host_version.attr, ++ &dev_attr_host_features.attr, ++ NULL, ++}; ++ATTRIBUTE_GROUPS(vbg_pci); ++ + /** + * Does the PCI detection and init of the device. + * +@@ -390,8 +397,6 @@ static int vbg_pci_probe(struct pci_dev *pci, const struct pci_device_id *id) + } + + pci_set_drvdata(pci, gdev); +- device_create_file(dev, &dev_attr_host_version); +- device_create_file(dev, &dev_attr_host_features); + + vbg_info("vboxguest: misc device minor %d, IRQ %d, I/O port %x, MMIO at %pap (size %pap)\n", + gdev->misc_device.minor, pci->irq, gdev->io_port, +@@ -422,8 +427,6 @@ static void vbg_pci_remove(struct pci_dev *pci) + mutex_unlock(&vbg_gdev_mutex); + + free_irq(pci->irq, gdev); +- device_remove_file(gdev->dev, &dev_attr_host_features); +- device_remove_file(gdev->dev, &dev_attr_host_version); + misc_deregister(&gdev->misc_device_user); + misc_deregister(&gdev->misc_device); + vbg_core_exit(gdev); +@@ -488,6 +491,7 @@ MODULE_DEVICE_TABLE(pci, vbg_pci_ids); + + static struct pci_driver vbg_pci_driver = { + .name = DEVICE_NAME, ++ .dev_groups = vbg_pci_groups, + .id_table = vbg_pci_ids, + .probe = vbg_pci_probe, + .remove = vbg_pci_remove, +-- +2.35.3 + diff --git a/patches.suse/watchdog-armada_37xx_wdt-Fix-.set_timeout-callback.patch b/patches.suse/watchdog-armada_37xx_wdt-Fix-.set_timeout-callback.patch new file mode 100644 index 0000000..7706efe --- /dev/null +++ b/patches.suse/watchdog-armada_37xx_wdt-Fix-.set_timeout-callback.patch @@ -0,0 +1,48 @@ +From 8007935305610d577746b888bd1864b34fb0ea13 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= +Date: Tue, 26 Jul 2022 10:56:12 +0200 +Subject: [PATCH] watchdog: armada_37xx_wdt: Fix .set_timeout callback +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 8007935305610d577746b888bd1864b34fb0ea13 +Patch-mainline: v6.1-rc1 +References: git-fixes + +ioctl(WDIOC_SETTIMEOUT) calls .set_timeout and .ping callbacks and it is +expected that it changes current watchdog timeout. + +armada_37xx_wdt's .ping callback just reping counter 0 and does not touch +counter 1 used for timeout. So it is needed to set counter 1 to the new +value in .set_timeout callback to ensure ioctl(WDIOC_SETTIMEOUT) +functionality. Fix it. + +Fixes: 54e3d9b518c8 ("watchdog: Add support for Armada 37xx CPU watchdog") +Signed-off-by: Pali Rohár +Reviewed-by: Guenter Roeck +Reviewed-by: Marek Behún +Link: https://lore.kernel.org/r/20220726085612.10672-1-pali@kernel.org +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Acked-by: Takashi Iwai + +--- + drivers/watchdog/armada_37xx_wdt.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/watchdog/armada_37xx_wdt.c b/drivers/watchdog/armada_37xx_wdt.c +index 854b1cc723cb..ac9fed1ef681 100644 +--- a/drivers/watchdog/armada_37xx_wdt.c ++++ b/drivers/watchdog/armada_37xx_wdt.c +@@ -179,6 +179,8 @@ static int armada_37xx_wdt_set_timeout(struct watchdog_device *wdt, + dev->timeout = (u64)dev->clk_rate * timeout; + do_div(dev->timeout, CNTR_CTRL_PRESCALE_MIN); + ++ set_counter_value(dev, CNTR_ID_WDOG, dev->timeout); ++ + return 0; + } + +-- +2.35.3 + diff --git a/patches.suse/watchdog-ftwdt010_wdt-fix-test-for-platform_get_irq-.patch b/patches.suse/watchdog-ftwdt010_wdt-fix-test-for-platform_get_irq-.patch new file mode 100644 index 0000000..cbe23bc --- /dev/null +++ b/patches.suse/watchdog-ftwdt010_wdt-fix-test-for-platform_get_irq-.patch @@ -0,0 +1,40 @@ +From 695bfff55327caf6e9b098ada32b39b1d81dafc4 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Thu, 11 Aug 2022 13:56:06 +0300 +Subject: [PATCH] watchdog: ftwdt010_wdt: fix test for platform_get_irq() failure +Git-commit: 695bfff55327caf6e9b098ada32b39b1d81dafc4 +Patch-mainline: v6.1-rc1 +References: git-fixes + +This code assumes that platform_get_irq() function returns zero on +failure. In fact, platform_get_irq() never returns zero. It returns +negative error codes or positive non-zero values on success. + +Fixes: eca10ae6000d ("watchdog: add driver for Cortina Gemini watchdog") +Signed-off-by: Dan Carpenter +Reviewed-by: Guenter Roeck +Link: https://lore.kernel.org/r/YvTgRk/ABp62/hNA@kili +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Acked-by: Takashi Iwai + +--- + drivers/watchdog/ftwdt010_wdt.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/watchdog/ftwdt010_wdt.c b/drivers/watchdog/ftwdt010_wdt.c +index 0a5bbfd2823f..442c5bf63ff4 100644 +--- a/drivers/watchdog/ftwdt010_wdt.c ++++ b/drivers/watchdog/ftwdt010_wdt.c +@@ -171,7 +171,7 @@ static int ftwdt010_wdt_probe(struct platform_device *pdev) + } + + irq = platform_get_irq(pdev, 0); +- if (irq) { ++ if (irq > 0) { + ret = devm_request_irq(dev, irq, ftwdt010_wdt_interrupt, 0, + "watchdog bark", gwdt); + if (ret) +-- +2.35.3 + diff --git a/patches.suse/watchdog-hpwdt-Include-nmi.h-only-if-CONFIG_HPWDT_NM.patch b/patches.suse/watchdog-hpwdt-Include-nmi.h-only-if-CONFIG_HPWDT_NM.patch new file mode 100644 index 0000000..af787ce --- /dev/null +++ b/patches.suse/watchdog-hpwdt-Include-nmi.h-only-if-CONFIG_HPWDT_NM.patch @@ -0,0 +1,43 @@ +From ed835d8171fc884c7750cdd54128df16d4571e3a Mon Sep 17 00:00:00 2001 +From: Jerry Hoemann +Date: Sat, 20 Aug 2022 14:28:20 -0600 +Subject: [PATCH] watchdog/hpwdt: Include nmi.h only if CONFIG_HPWDT_NMI_DECODING +Git-commit: ed835d8171fc884c7750cdd54128df16d4571e3a +Patch-mainline: v6.1-rc1 +References: git-fixes + +Fixes: d48b0e173715 ("x86, nmi, drivers: Fix nmi splitup build bug") + +Arm64 does not support NMI and has no . + +Include only if CONFIG_HPWDT_NMI_DECODING is defined to +avoid build failure on non-existent header file on Arm64. + +Signed-off-by: Jerry Hoemann +Reviewed-by: Guenter Roeck +Link: https://lore.kernel.org/r/20220820202821.1263837-2-jerry.hoemann@hpe.com +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Acked-by: Takashi Iwai + +--- + drivers/watchdog/hpwdt.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c +index a5006a58e0db..f79f932bca14 100644 +--- a/drivers/watchdog/hpwdt.c ++++ b/drivers/watchdog/hpwdt.c +@@ -20,7 +20,9 @@ + #include + #include + #include ++#ifdef CONFIG_HPWDT_NMI_DECODING + #include ++#endif + #include + + #define HPWDT_VERSION "2.0.4" +-- +2.35.3 + diff --git a/patches.suse/wifi-ath10k-add-peer-map-clean-up-for-peer-delete-in.patch b/patches.suse/wifi-ath10k-add-peer-map-clean-up-for-peer-delete-in.patch new file mode 100644 index 0000000..5572d04 --- /dev/null +++ b/patches.suse/wifi-ath10k-add-peer-map-clean-up-for-peer-delete-in.patch @@ -0,0 +1,205 @@ +From f020d9570a04df0762a2ac5c50cf1d8c511c9164 Mon Sep 17 00:00:00 2001 +From: Wen Gong +Date: Mon, 1 Aug 2022 10:19:30 -0400 +Subject: [PATCH] wifi: ath10k: add peer map clean up for peer delete in ath10k_sta_state() +Git-commit: f020d9570a04df0762a2ac5c50cf1d8c511c9164 +Patch-mainline: v6.1-rc1 +References: git-fixes + +When peer delete failed in a disconnect operation, use-after-free +detected by KFENCE in below log. It is because for each vdev_id and +address, it has only one struct ath10k_peer, it is allocated in +ath10k_peer_map_event(). When connected to an AP, it has more than +one HTT_T2H_MSG_TYPE_PEER_MAP reported from firmware, then the +array peer_map of struct ath10k will be set muti-elements to the +same ath10k_peer in ath10k_peer_map_event(). When peer delete failed +in ath10k_sta_state(), the ath10k_peer will be free for the 1st peer +id in array peer_map of struct ath10k, and then use-after-free happened +for the 2nd peer id because they map to the same ath10k_peer. + +And clean up all peers in array peer_map for the ath10k_peer, then +user-after-free disappeared + +peer map event log: +[ 306.911021] wlan0: authenticate with b0:2a:43:e6:75:0e +[ 306.957187] ath10k_pci 0000:01:00.0: mac vdev 0 peer create b0:2a:43:e6:75:0e (new sta) sta 1 / 32 peer 1 / 33 +[ 306.957395] ath10k_pci 0000:01:00.0: htt peer map vdev 0 peer b0:2a:43:e6:75:0e id 246 +[ 306.957404] ath10k_pci 0000:01:00.0: htt peer map vdev 0 peer b0:2a:43:e6:75:0e id 198 +[ 306.986924] ath10k_pci 0000:01:00.0: htt peer map vdev 0 peer b0:2a:43:e6:75:0e id 166 + +peer unmap event log: +[ 435.715691] wlan0: deauthenticating from b0:2a:43:e6:75:0e by local choice (Reason: 3=DEAUTH_LEAVING) +[ 435.716802] ath10k_pci 0000:01:00.0: mac vdev 0 peer delete b0:2a:43:e6:75:0e sta ffff990e0e9c2b50 (sta gone) +[ 435.717177] ath10k_pci 0000:01:00.0: htt peer unmap vdev 0 peer b0:2a:43:e6:75:0e id 246 +[ 435.717186] ath10k_pci 0000:01:00.0: htt peer unmap vdev 0 peer b0:2a:43:e6:75:0e id 198 +[ 435.717193] ath10k_pci 0000:01:00.0: htt peer unmap vdev 0 peer b0:2a:43:e6:75:0e id 166 + +use-after-free log: +[21705.888627] wlan0: deauthenticating from d0:76:8f:82:be:75 by local choice (Reason: 3=DEAUTH_LEAVING) +[21713.799910] ath10k_pci 0000:01:00.0: failed to delete peer d0:76:8f:82:be:75 for vdev 0: -110 +[21713.799925] ath10k_pci 0000:01:00.0: found sta peer d0:76:8f:82:be:75 (ptr 0000000000000000 id 102) entry on vdev 0 after it was supposedly removed +[21713.799968] ================================================================== +[21713.799991] BUG: KFENCE: use-after-free read in ath10k_sta_state+0x265/0xb8a [ath10k_core] +[21713.799991] +[21713.799997] Use-after-free read at 0x00000000abe1c75e (in kfence-#69): +[21713.800010] ath10k_sta_state+0x265/0xb8a [ath10k_core] +[21713.800041] drv_sta_state+0x115/0x677 [mac80211] +[21713.800059] __sta_info_destroy_part2+0xb1/0x133 [mac80211] +[21713.800076] __sta_info_flush+0x11d/0x162 [mac80211] +[21713.800093] ieee80211_set_disassoc+0x12d/0x2f4 [mac80211] +[21713.800110] ieee80211_mgd_deauth+0x26c/0x29b [mac80211] +[21713.800137] cfg80211_mlme_deauth+0x13f/0x1bb [cfg80211] +[21713.800153] nl80211_deauthenticate+0xf8/0x121 [cfg80211] +[21713.800161] genl_rcv_msg+0x38e/0x3be +[21713.800166] netlink_rcv_skb+0x89/0xf7 +[21713.800171] genl_rcv+0x28/0x36 +[21713.800176] netlink_unicast+0x179/0x24b +[21713.800181] netlink_sendmsg+0x3a0/0x40e +[21713.800187] sock_sendmsg+0x72/0x76 +[21713.800192] ____sys_sendmsg+0x16d/0x1e3 +[21713.800196] ___sys_sendmsg+0x95/0xd1 +[21713.800200] __sys_sendmsg+0x85/0xbf +[21713.800205] do_syscall_64+0x43/0x55 +[21713.800210] entry_SYSCALL_64_after_hwframe+0x44/0xa9 +[21713.800213] +[21713.800219] kfence-#69: 0x000000009149b0d5-0x000000004c0697fb, size=1064, cache=kmalloc-2k +[21713.800219] +[21713.800224] allocated by task 13 on cpu 0 at 21705.501373s: +[21713.800241] ath10k_peer_map_event+0x7e/0x154 [ath10k_core] +[21713.800254] ath10k_htt_t2h_msg_handler+0x586/0x1039 [ath10k_core] +[21713.800265] ath10k_htt_htc_t2h_msg_handler+0x12/0x28 [ath10k_core] +[21713.800277] ath10k_htc_rx_completion_handler+0x14c/0x1b5 [ath10k_core] +[21713.800283] ath10k_pci_process_rx_cb+0x195/0x1df [ath10k_pci] +[21713.800294] ath10k_ce_per_engine_service+0x55/0x74 [ath10k_core] +[21713.800305] ath10k_ce_per_engine_service_any+0x76/0x84 [ath10k_core] +[21713.800310] ath10k_pci_napi_poll+0x49/0x144 [ath10k_pci] +[21713.800316] net_rx_action+0xdc/0x361 +[21713.800320] __do_softirq+0x163/0x29a +[21713.800325] asm_call_irq_on_stack+0x12/0x20 +[21713.800331] do_softirq_own_stack+0x3c/0x48 +[21713.800337] __irq_exit_rcu+0x9b/0x9d +[21713.800342] common_interrupt+0xc9/0x14d +[21713.800346] asm_common_interrupt+0x1e/0x40 +[21713.800351] ksoftirqd_should_run+0x5/0x16 +[21713.800357] smpboot_thread_fn+0x148/0x211 +[21713.800362] kthread+0x150/0x15f +[21713.800367] ret_from_fork+0x22/0x30 +[21713.800370] +[21713.800374] freed by task 708 on cpu 1 at 21713.799953s: +[21713.800498] ath10k_sta_state+0x2c6/0xb8a [ath10k_core] +[21713.800515] drv_sta_state+0x115/0x677 [mac80211] +[21713.800532] __sta_info_destroy_part2+0xb1/0x133 [mac80211] +[21713.800548] __sta_info_flush+0x11d/0x162 [mac80211] +[21713.800565] ieee80211_set_disassoc+0x12d/0x2f4 [mac80211] +[21713.800581] ieee80211_mgd_deauth+0x26c/0x29b [mac80211] +[21713.800598] cfg80211_mlme_deauth+0x13f/0x1bb [cfg80211] +[21713.800614] nl80211_deauthenticate+0xf8/0x121 [cfg80211] +[21713.800619] genl_rcv_msg+0x38e/0x3be +[21713.800623] netlink_rcv_skb+0x89/0xf7 +[21713.800628] genl_rcv+0x28/0x36 +[21713.800632] netlink_unicast+0x179/0x24b +[21713.800637] netlink_sendmsg+0x3a0/0x40e +[21713.800642] sock_sendmsg+0x72/0x76 +[21713.800646] ____sys_sendmsg+0x16d/0x1e3 +[21713.800651] ___sys_sendmsg+0x95/0xd1 +[21713.800655] __sys_sendmsg+0x85/0xbf +[21713.800659] do_syscall_64+0x43/0x55 +[21713.800663] entry_SYSCALL_64_after_hwframe+0x44/0xa9 + +Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00288-QCARMSWPZ-1 + +Fixes: d0eeafad1189 ("ath10k: Clean up peer when sta goes away.") +Signed-off-by: Wen Gong +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20220801141930.16794-1-quic_wgong@quicinc.com +Acked-by: Takashi Iwai + +--- + drivers/net/wireless/ath/ath10k/mac.c | 54 ++++++++++++++------------- + 1 file changed, 29 insertions(+), 25 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c +index 9dd3b8fba4b0..23381a9db6ae 100644 +--- a/drivers/net/wireless/ath/ath10k/mac.c ++++ b/drivers/net/wireless/ath/ath10k/mac.c +@@ -864,11 +864,36 @@ static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr) + return 0; + } + ++static void ath10k_peer_map_cleanup(struct ath10k *ar, struct ath10k_peer *peer) ++{ ++ int peer_id, i; ++ ++ lockdep_assert_held(&ar->conf_mutex); ++ ++ for_each_set_bit(peer_id, peer->peer_ids, ++ ATH10K_MAX_NUM_PEER_IDS) { ++ ar->peer_map[peer_id] = NULL; ++ } ++ ++ /* Double check that peer is properly un-referenced from ++ * the peer_map ++ */ ++ for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) { ++ if (ar->peer_map[i] == peer) { ++ ath10k_warn(ar, "removing stale peer_map entry for %pM (ptr %pK idx %d)\n", ++ peer->addr, peer, i); ++ ar->peer_map[i] = NULL; ++ } ++ } ++ ++ list_del(&peer->list); ++ kfree(peer); ++ ar->num_peers--; ++} ++ + static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id) + { + struct ath10k_peer *peer, *tmp; +- int peer_id; +- int i; + + lockdep_assert_held(&ar->conf_mutex); + +@@ -880,25 +905,7 @@ static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id) + ath10k_warn(ar, "removing stale peer %pM from vdev_id %d\n", + peer->addr, vdev_id); + +- for_each_set_bit(peer_id, peer->peer_ids, +- ATH10K_MAX_NUM_PEER_IDS) { +- ar->peer_map[peer_id] = NULL; +- } +- +- /* Double check that peer is properly un-referenced from +- * the peer_map +- */ +- for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) { +- if (ar->peer_map[i] == peer) { +- ath10k_warn(ar, "removing stale peer_map entry for %pM (ptr %pK idx %d)\n", +- peer->addr, peer, i); +- ar->peer_map[i] = NULL; +- } +- } +- +- list_del(&peer->list); +- kfree(peer); +- ar->num_peers--; ++ ath10k_peer_map_cleanup(ar, peer); + } + spin_unlock_bh(&ar->data_lock); + } +@@ -7621,10 +7628,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw, + /* Clean up the peer object as well since we + * must have failed to do this above. + */ +- list_del(&peer->list); +- ar->peer_map[i] = NULL; +- kfree(peer); +- ar->num_peers--; ++ ath10k_peer_map_cleanup(ar, peer); + } + } + spin_unlock_bh(&ar->data_lock); +-- +2.35.3 + diff --git a/patches.suse/wifi-ath11k-fix-number-of-VHT-beamformee-spatial-str.patch b/patches.suse/wifi-ath11k-fix-number-of-VHT-beamformee-spatial-str.patch new file mode 100644 index 0000000..a0e250a --- /dev/null +++ b/patches.suse/wifi-ath11k-fix-number-of-VHT-beamformee-spatial-str.patch @@ -0,0 +1,101 @@ +From 55b5ee3357d7bb98ee578cf9b84a652e7a1bc199 Mon Sep 17 00:00:00 2001 +From: Jesus Fernandez Manzano +Date: Thu, 22 Sep 2022 10:35:14 +0300 +Subject: [PATCH] wifi: ath11k: fix number of VHT beamformee spatial streams +Git-commit: 55b5ee3357d7bb98ee578cf9b84a652e7a1bc199 +Patch-mainline: v6.1-rc1 +References: git-fixes + +The number of spatial streams used when acting as a beamformee in VHT +mode are reported by the firmware as 7 (8 sts - 1) both in IPQ6018 and +IPQ8074 which respectively have 2 and 4 sts each. So the firmware should +report 1 (2 - 1) and 3 (4 - 1). + +Fix this by checking that the number of VHT beamformee sts reported by +the firmware is not greater than the number of receiving antennas - 1. +The fix is based on the same approach used in this same function for +sanitizing the number of sounding dimensions reported by the firmware. + +Without this change, acting as a beamformee in VHT mode is not working +properly. + +Tested-on: IPQ6018 hw1.0 AHB WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1 +Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1 + +Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices") +Signed-off-by: Jesus Fernandez Manzano +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20220616173947.21901-1-jesus.manzano@galgus.net +Acked-by: Takashi Iwai + +--- + drivers/net/wireless/ath/ath11k/mac.c | 25 ++++++++++++++++++++----- + 1 file changed, 20 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c +index 2cd1e6f8b3c1..dc391609e952 100644 +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -4959,6 +4959,8 @@ static int ath11k_mac_set_txbf_conf(struct ath11k_vif *arvif) + if (vht_cap & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)) { + nsts = vht_cap & IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK; + nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT; ++ if (nsts > (ar->num_rx_chains - 1)) ++ nsts = ar->num_rx_chains - 1; + value |= SM(nsts, WMI_TXBF_STS_CAP_OFFSET); + } + +@@ -4999,7 +5001,7 @@ static int ath11k_mac_set_txbf_conf(struct ath11k_vif *arvif) + static void ath11k_set_vht_txbf_cap(struct ath11k *ar, u32 *vht_cap) + { + bool subfer, subfee; +- int sound_dim = 0; ++ int sound_dim = 0, nsts = 0; + + subfer = !!(*vht_cap & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)); + subfee = !!(*vht_cap & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)); +@@ -5009,6 +5011,11 @@ static void ath11k_set_vht_txbf_cap(struct ath11k *ar, u32 *vht_cap) + subfer = false; + } + ++ if (ar->num_rx_chains < 2) { ++ *vht_cap &= ~(IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE); ++ subfee = false; ++ } ++ + /* If SU Beaformer is not set, then disable MU Beamformer Capability */ + if (!subfer) + *vht_cap &= ~(IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE); +@@ -5021,7 +5028,9 @@ static void ath11k_set_vht_txbf_cap(struct ath11k *ar, u32 *vht_cap) + sound_dim >>= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT; + *vht_cap &= ~IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK; + +- /* TODO: Need to check invalid STS and Sound_dim values set by FW? */ ++ nsts = (*vht_cap & IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK); ++ nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT; ++ *vht_cap &= ~IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK; + + /* Enable Sounding Dimension Field only if SU BF is enabled */ + if (subfer) { +@@ -5033,9 +5042,15 @@ static void ath11k_set_vht_txbf_cap(struct ath11k *ar, u32 *vht_cap) + *vht_cap |= sound_dim; + } + +- /* Use the STS advertised by FW unless SU Beamformee is not supported*/ +- if (!subfee) +- *vht_cap &= ~(IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK); ++ /* Enable Beamformee STS Field only if SU BF is enabled */ ++ if (subfee) { ++ if (nsts > (ar->num_rx_chains - 1)) ++ nsts = ar->num_rx_chains - 1; ++ ++ nsts <<= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT; ++ nsts &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK; ++ *vht_cap |= nsts; ++ } + } + + static struct ieee80211_sta_vht_cap +-- +2.35.3 + diff --git a/patches.suse/wifi-cfg80211-avoid-nontransmitted-BSS-list-corrupti.patch b/patches.suse/wifi-cfg80211-avoid-nontransmitted-BSS-list-corrupti.patch new file mode 100644 index 0000000..ffdf97e --- /dev/null +++ b/patches.suse/wifi-cfg80211-avoid-nontransmitted-BSS-list-corrupti.patch @@ -0,0 +1,58 @@ +From bcca852027e5878aec911a347407ecc88d6fff7f Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Sat, 1 Oct 2022 00:01:44 +0200 +Subject: [PATCH] wifi: cfg80211: avoid nontransmitted BSS list corruption +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: bcca852027e5878aec911a347407ecc88d6fff7f +Patch-mainline: v6.1-rc1 +References: CVE-2022-42721 bsc#1204060 + +If a non-transmitted BSS shares enough information (both +SSID and BSSID!) with another non-transmitted BSS of a +different AP, then we can find and update it, and then +try to add it to the non-transmitted BSS list. We do a +search for it on the transmitted BSS, but if it's not +there (but belongs to another transmitted BSS), the list +gets corrupted. + +Since this is an erroneous situation, simply fail the +list insertion in this case and free the non-transmitted +BSS. + +This fixes CVE-2022-42721. + +Reported-by: Sönke Huster +Tested-by: Sönke Huster +Fixes: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning") +Signed-off-by: Johannes Berg +Signed-off-by: Takashi Iwai + +--- + net/wireless/scan.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/net/wireless/scan.c b/net/wireless/scan.c +index 249107212c09..703b05c6c43e 100644 +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -423,6 +423,15 @@ cfg80211_add_nontrans_list(struct cfg80211_bss *trans_bss, + + rcu_read_unlock(); + ++ /* ++ * This is a bit weird - it's not on the list, but already on another ++ * one! The only way that could happen is if there's some BSSID/SSID ++ * shared by multiple APs in their multi-BSSID profiles, potentially ++ * with hidden SSID mixed in ... ignore it. ++ */ ++ if (!list_empty(&nontrans_bss->nontrans_list)) ++ return -EINVAL; ++ + /* add to the list */ + list_add_tail(&nontrans_bss->nontrans_list, &trans_bss->nontrans_list); + return 0; +-- +2.35.3 + diff --git a/patches.suse/wifi-cfg80211-ensure-length-byte-is-present-before-a.patch b/patches.suse/wifi-cfg80211-ensure-length-byte-is-present-before-a.patch new file mode 100644 index 0000000..be7dba0 --- /dev/null +++ b/patches.suse/wifi-cfg80211-ensure-length-byte-is-present-before-a.patch @@ -0,0 +1,51 @@ +From 567e14e39e8f8c6997a1378bc3be615afca86063 Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Thu, 29 Sep 2022 21:50:44 +0200 +Subject: [PATCH] wifi: cfg80211: ensure length byte is present before access +Git-commit: 567e14e39e8f8c6997a1378bc3be615afca86063 +Patch-mainline: v6.1-rc1 +References: CVE-2022-41674 bsc#1203770 + +When iterating the elements here, ensure the length byte is +present before checking it to see if the entire element will +fit into the buffer. + +Longer term, we should rewrite this code using the type-safe +element iteration macros that check all of this. + +Fixes: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning") +Reported-by: Soenke Huster +Signed-off-by: Johannes Berg +Signed-off-by: Takashi Iwai + +--- + net/wireless/scan.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/net/wireless/scan.c b/net/wireless/scan.c +index 5dab33e1f3a8..a183f2b75874 100644 +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -304,7 +304,8 @@ static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen, + tmp_old = cfg80211_find_ie(WLAN_EID_SSID, ie, ielen); + tmp_old = (tmp_old) ? tmp_old + tmp_old[1] + 2 : ie; + +- while (tmp_old + tmp_old[1] + 2 - ie <= ielen) { ++ while (tmp_old + 2 - ie <= ielen && ++ tmp_old + tmp_old[1] + 2 - ie <= ielen) { + if (tmp_old[0] == 0) { + tmp_old++; + continue; +@@ -364,7 +365,8 @@ static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen, + * copied to new ie, skip ssid, capability, bssid-index ie + */ + tmp_new = sub_copy; +- while (tmp_new + tmp_new[1] + 2 - sub_copy <= subie_len) { ++ while (tmp_new + 2 - sub_copy <= subie_len && ++ tmp_new + tmp_new[1] + 2 - sub_copy <= subie_len) { + if (!(tmp_new[0] == WLAN_EID_NON_TX_BSSID_CAP || + tmp_new[0] == WLAN_EID_SSID)) { + memcpy(pos, tmp_new, tmp_new[1] + 2); +-- +2.35.3 + diff --git a/patches.suse/wifi-cfg80211-fix-BSS-refcounting-bugs.patch b/patches.suse/wifi-cfg80211-fix-BSS-refcounting-bugs.patch new file mode 100644 index 0000000..03896db --- /dev/null +++ b/patches.suse/wifi-cfg80211-fix-BSS-refcounting-bugs.patch @@ -0,0 +1,98 @@ +From 0b7808818cb9df6680f98996b8e9a439fa7bcc2f Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Fri, 30 Sep 2022 23:44:23 +0200 +Subject: [PATCH] wifi: cfg80211: fix BSS refcounting bugs +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 0b7808818cb9df6680f98996b8e9a439fa7bcc2f +Patch-mainline: v6.1-rc1 +References: CVE-2022-42720 bsc#1204059 + +There are multiple refcounting bugs related to multi-BSSID: + - In bss_ref_get(), if the BSS has a hidden_beacon_bss, then + the bss pointer is overwritten before checking for the + transmitted BSS, which is clearly wrong. Fix this by using + the bss_from_pub() macro. + + - In cfg80211_bss_update() we copy the transmitted_bss pointer + from tmp into new, but then if we release new, we'll unref + it erroneously. We already set the pointer and ref it, but + need to NULL it since it was copied from the tmp data. + + - In cfg80211_inform_single_bss_data(), if adding to the non- + transmitted list fails, we unlink the BSS and yet still we + return it, but this results in returning an entry without + a reference. We shouldn't return it anyway if it was broken + enough to not get added there. + +This fixes CVE-2022-42720. + +Reported-by: Sönke Huster +Tested-by: Sönke Huster +Fixes: a3584f56de1c ("cfg80211: Properly track transmitting and non-transmitting BSS") +Signed-off-by: Johannes Berg +Signed-off-by: Takashi Iwai + +--- + net/wireless/scan.c | 27 ++++++++++++++------------- + 1 file changed, 14 insertions(+), 13 deletions(-) + +diff --git a/net/wireless/scan.c b/net/wireless/scan.c +index a183f2b75874..249107212c09 100644 +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -143,18 +143,12 @@ static inline void bss_ref_get(struct cfg80211_registered_device *rdev, + lockdep_assert_held(&rdev->bss_lock); + + bss->refcount++; +- if (bss->pub.hidden_beacon_bss) { +- bss = container_of(bss->pub.hidden_beacon_bss, +- struct cfg80211_internal_bss, +- pub); +- bss->refcount++; +- } +- if (bss->pub.transmitted_bss) { +- bss = container_of(bss->pub.transmitted_bss, +- struct cfg80211_internal_bss, +- pub); +- bss->refcount++; +- } ++ ++ if (bss->pub.hidden_beacon_bss) ++ bss_from_pub(bss->pub.hidden_beacon_bss)->refcount++; ++ ++ if (bss->pub.transmitted_bss) ++ bss_from_pub(bss->pub.transmitted_bss)->refcount++; + } + + static inline void bss_ref_put(struct cfg80211_registered_device *rdev, +@@ -1741,6 +1735,8 @@ cfg80211_bss_update(struct cfg80211_registered_device *rdev, + new->refcount = 1; + INIT_LIST_HEAD(&new->hidden_list); + INIT_LIST_HEAD(&new->pub.nontrans_list); ++ /* we'll set this later if it was non-NULL */ ++ new->pub.transmitted_bss = NULL; + + if (rcu_access_pointer(tmp->pub.proberesp_ies)) { + hidden = rb_find_bss(rdev, tmp, BSS_CMP_HIDE_ZLEN); +@@ -2023,10 +2019,15 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy, + spin_lock_bh(&rdev->bss_lock); + if (cfg80211_add_nontrans_list(non_tx_data->tx_bss, + &res->pub)) { +- if (__cfg80211_unlink_bss(rdev, res)) ++ if (__cfg80211_unlink_bss(rdev, res)) { + rdev->bss_generation++; ++ res = NULL; ++ } + } + spin_unlock_bh(&rdev->bss_lock); ++ ++ if (!res) ++ return NULL; + } + + trace_cfg80211_return_bss(&res->pub); +-- +2.35.3 + diff --git a/patches.suse/wifi-cfg80211-fix-ieee80211_data_to_8023_exthdr-hand.patch b/patches.suse/wifi-cfg80211-fix-ieee80211_data_to_8023_exthdr-hand.patch new file mode 100644 index 0000000..1c92811 --- /dev/null +++ b/patches.suse/wifi-cfg80211-fix-ieee80211_data_to_8023_exthdr-hand.patch @@ -0,0 +1,108 @@ +From d9e249704084982ac7581a560ffa284e11621d43 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Fri, 7 Oct 2022 14:56:11 +0200 +Subject: [PATCH] wifi: cfg80211: fix ieee80211_data_to_8023_exthdr handling of small packets +Git-commit: d9e249704084982ac7581a560ffa284e11621d43 +Patch-mainline: v6.1-rc1 +References: git-fixes + +STP topology change notification packets only have a payload of 7 bytes, +so they get dropped due to the skb->len < hdrlen + 8 check. +Fix this by removing the extra 8 from the skb->len check and checking the +return code on the skb_copy_bits calls. + +Fixes: 2d1c304cb2d5 ("cfg80211: add function for 802.3 conversion with separate output buffer") +Reported-by: Chad Monroe +Signed-off-by: Felix Fietkau +Signed-off-by: Johannes Berg +Acked-by: Takashi Iwai + +--- + net/wireless/util.c | 40 +++++++++++++++++++++------------------- + 1 file changed, 21 insertions(+), 19 deletions(-) + +diff --git a/net/wireless/util.c b/net/wireless/util.c +index 01493568a21d..1f285b515028 100644 +--- a/net/wireless/util.c ++++ b/net/wireless/util.c +@@ -559,7 +559,7 @@ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr, + return -1; + + hdrlen = ieee80211_hdrlen(hdr->frame_control) + data_offset; +- if (skb->len < hdrlen + 8) ++ if (skb->len < hdrlen) + return -1; + + /* convert IEEE 802.11 header + possible LLC headers into Ethernet +@@ -574,8 +574,9 @@ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr, + memcpy(tmp.h_dest, ieee80211_get_DA(hdr), ETH_ALEN); + memcpy(tmp.h_source, ieee80211_get_SA(hdr), ETH_ALEN); + +- if (iftype == NL80211_IFTYPE_MESH_POINT) +- skb_copy_bits(skb, hdrlen, &mesh_flags, 1); ++ if (iftype == NL80211_IFTYPE_MESH_POINT && ++ skb_copy_bits(skb, hdrlen, &mesh_flags, 1) < 0) ++ return -1; + + mesh_flags &= MESH_FLAGS_AE; + +@@ -595,11 +596,12 @@ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr, + if (iftype == NL80211_IFTYPE_MESH_POINT) { + if (mesh_flags == MESH_FLAGS_AE_A4) + return -1; +- if (mesh_flags == MESH_FLAGS_AE_A5_A6) { +- skb_copy_bits(skb, hdrlen + +- offsetof(struct ieee80211s_hdr, eaddr1), +- tmp.h_dest, 2 * ETH_ALEN); +- } ++ if (mesh_flags == MESH_FLAGS_AE_A5_A6 && ++ skb_copy_bits(skb, hdrlen + ++ offsetof(struct ieee80211s_hdr, eaddr1), ++ tmp.h_dest, 2 * ETH_ALEN) < 0) ++ return -1; ++ + hdrlen += __ieee80211_get_mesh_hdrlen(mesh_flags); + } + break; +@@ -613,10 +615,11 @@ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr, + if (iftype == NL80211_IFTYPE_MESH_POINT) { + if (mesh_flags == MESH_FLAGS_AE_A5_A6) + return -1; +- if (mesh_flags == MESH_FLAGS_AE_A4) +- skb_copy_bits(skb, hdrlen + +- offsetof(struct ieee80211s_hdr, eaddr1), +- tmp.h_source, ETH_ALEN); ++ if (mesh_flags == MESH_FLAGS_AE_A4 && ++ skb_copy_bits(skb, hdrlen + ++ offsetof(struct ieee80211s_hdr, eaddr1), ++ tmp.h_source, ETH_ALEN) < 0) ++ return -1; + hdrlen += __ieee80211_get_mesh_hdrlen(mesh_flags); + } + break; +@@ -628,16 +631,15 @@ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr, + break; + } + +- skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)); +- tmp.h_proto = payload.proto; +- +- if (likely((!is_amsdu && ether_addr_equal(payload.hdr, rfc1042_header) && +- tmp.h_proto != htons(ETH_P_AARP) && +- tmp.h_proto != htons(ETH_P_IPX)) || +- ether_addr_equal(payload.hdr, bridge_tunnel_header))) { ++ if (likely(skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)) == 0 && ++ ((!is_amsdu && ether_addr_equal(payload.hdr, rfc1042_header) && ++ payload.proto != htons(ETH_P_AARP) && ++ payload.proto != htons(ETH_P_IPX)) || ++ ether_addr_equal(payload.hdr, bridge_tunnel_header)))) { + /* remove RFC1042 or Bridge-Tunnel encapsulation and + * replace EtherType */ + hdrlen += ETH_ALEN + 2; ++ tmp.h_proto = payload.proto; + skb_postpull_rcsum(skb, &payload, ETH_ALEN + 2); + } else { + tmp.h_proto = htons(skb->len - hdrlen); +-- +2.35.3 + diff --git a/patches.suse/wifi-cfg80211-fix-u8-overflow-in-cfg80211_update_not.patch b/patches.suse/wifi-cfg80211-fix-u8-overflow-in-cfg80211_update_not.patch new file mode 100644 index 0000000..4d156ca --- /dev/null +++ b/patches.suse/wifi-cfg80211-fix-u8-overflow-in-cfg80211_update_not.patch @@ -0,0 +1,51 @@ +From aebe9f4639b13a1f4e9a6b42cdd2e38c617b442d Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Wed, 28 Sep 2022 21:56:15 +0200 +Subject: [PATCH] wifi: cfg80211: fix u8 overflow in cfg80211_update_notlisted_nontrans() +Git-commit: aebe9f4639b13a1f4e9a6b42cdd2e38c617b442d +Patch-mainline: v6.1-rc1 +References: CVE-2022-41674 bsc#1203770 + +In the copy code of the elements, we do the following calculation +to reach the end of the MBSSID element: + + /* copy the IEs after MBSSID */ + cpy_len = mbssid[1] + 2; + +This looks fine, however, cpy_len is a u8, the same as mbssid[1], +so the addition of two can overflow. In this case the subsequent +memcpy() will overflow the allocated buffer, since it copies 256 +bytes too much due to the way the allocation and memcpy() sizes +are calculated. + +Fix this by using size_t for the cpy_len variable. + +This fixes CVE-2022-41674. + +Reported-by: Soenke Huster +Tested-by: Soenke Huster +Fixes: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning") +Reviewed-by: Kees Cook +Signed-off-by: Johannes Berg +Signed-off-by: Takashi Iwai + +--- + net/wireless/scan.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/wireless/scan.c b/net/wireless/scan.c +index 5382fc2003db..62f8c10412ad 100644 +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -2279,7 +2279,7 @@ cfg80211_update_notlisted_nontrans(struct wiphy *wiphy, + size_t new_ie_len; + struct cfg80211_bss_ies *new_ies; + const struct cfg80211_bss_ies *old; +- u8 cpy_len; ++ size_t cpy_len; + + lockdep_assert_held(&wiphy_to_rdev(wiphy)->bss_lock); + +-- +2.35.3 + diff --git a/patches.suse/wifi-cfg80211-mac80211-reject-bad-MBSSID-elements.patch b/patches.suse/wifi-cfg80211-mac80211-reject-bad-MBSSID-elements.patch new file mode 100644 index 0000000..2132de3 --- /dev/null +++ b/patches.suse/wifi-cfg80211-mac80211-reject-bad-MBSSID-elements.patch @@ -0,0 +1,61 @@ +From 8f033d2becc24aa6bfd2a5c104407963560caabc Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Wed, 28 Sep 2022 22:01:37 +0200 +Subject: [PATCH] wifi: cfg80211/mac80211: reject bad MBSSID elements +Git-commit: 8f033d2becc24aa6bfd2a5c104407963560caabc +Patch-mainline: v6.1-rc1 +References: CVE-2022-41674 bsc#1203770 + +Per spec, the maximum value for the MaxBSSID ('n') indicator is 8, +and the minimum is 1 since a multiple BSSID set with just one BSSID +doesn't make sense (the # of BSSIDs is limited by 2^n). + +Limit this in the parsing in both cfg80211 and mac80211, rejecting +any elements with an invalid value. + +This fixes potentially bad shifts in the processing of these inside +the cfg80211_gen_new_bssid() function later. + +I found this during the investigation of CVE-2022-41674 fixed by the +previous patch. + +Fixes: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning") +Fixes: 78ac51f81532 ("mac80211: support multi-bssid") +Reviewed-by: Kees Cook +Signed-off-by: Johannes Berg +Signed-off-by: Takashi Iwai + +--- + net/mac80211/util.c | 2 ++ + net/wireless/scan.c | 2 ++ + 2 files changed, 4 insertions(+) + +diff --git a/net/mac80211/util.c b/net/mac80211/util.c +index bf7461c41bef..f61289c5fed2 100644 +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -1445,6 +1445,8 @@ static size_t ieee802_11_find_bssid_profile(const u8 *start, size_t len, + for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, start, len) { + if (elem->datalen < 2) + continue; ++ if (elem->data[0] < 1 || elem->data[0] > 8) ++ continue; + + for_each_element(sub, elem->data + 1, elem->datalen - 1) { + u8 new_bssid[ETH_ALEN]; +diff --git a/net/wireless/scan.c b/net/wireless/scan.c +index 62f8c10412ad..5dab33e1f3a8 100644 +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -2143,6 +2143,8 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy, + for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, ie, ielen) { + if (elem->datalen < 4) + continue; ++ if (elem->data[0] < 1 || (int)elem->data[0] > 8) ++ continue; + for_each_element(sub, elem->data + 1, elem->datalen - 1) { + u8 profile_len; + +-- +2.35.3 + diff --git a/patches.suse/wifi-cfg80211-update-hidden-BSSes-to-avoid-WARN_ON.patch b/patches.suse/wifi-cfg80211-update-hidden-BSSes-to-avoid-WARN_ON.patch new file mode 100644 index 0000000..8661c7b --- /dev/null +++ b/patches.suse/wifi-cfg80211-update-hidden-BSSes-to-avoid-WARN_ON.patch @@ -0,0 +1,96 @@ +From c90b93b5b782891ebfda49d4e5da36632fefd5d1 Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Wed, 5 Oct 2022 23:11:43 +0200 +Subject: [PATCH] wifi: cfg80211: update hidden BSSes to avoid WARN_ON +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: c90b93b5b782891ebfda49d4e5da36632fefd5d1 +Patch-mainline: v6.1-rc1 +References: git-fixes + +When updating beacon elements in a non-transmitted BSS, +also update the hidden sub-entries to the same beacon +elements, so that a future update through other paths +won't trigger a WARN_ON(). + +The warning is triggered because the beacon elements in +the hidden BSSes that are children of the BSS should +always be the same as in the parent. + +Reported-by: Sönke Huster +Tested-by: Sönke Huster +Fixes: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning") +Signed-off-by: Johannes Berg +Acked-by: Takashi Iwai + +--- + net/wireless/scan.c | 31 ++++++++++++++++++++----------- + 1 file changed, 20 insertions(+), 11 deletions(-) + +diff --git a/net/wireless/scan.c b/net/wireless/scan.c +index 703b05c6c43e..806a5f1330ff 100644 +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -1607,6 +1607,23 @@ struct cfg80211_non_tx_bss { + u8 bssid_index; + }; + ++static void cfg80211_update_hidden_bsses(struct cfg80211_internal_bss *known, ++ const struct cfg80211_bss_ies *new_ies, ++ const struct cfg80211_bss_ies *old_ies) ++{ ++ struct cfg80211_internal_bss *bss; ++ ++ /* Assign beacon IEs to all sub entries */ ++ list_for_each_entry(bss, &known->hidden_list, hidden_list) { ++ const struct cfg80211_bss_ies *ies; ++ ++ ies = rcu_access_pointer(bss->pub.beacon_ies); ++ WARN_ON(ies != old_ies); ++ ++ rcu_assign_pointer(bss->pub.beacon_ies, new_ies); ++ } ++} ++ + static bool + cfg80211_update_known_bss(struct cfg80211_registered_device *rdev, + struct cfg80211_internal_bss *known, +@@ -1630,7 +1647,6 @@ cfg80211_update_known_bss(struct cfg80211_registered_device *rdev, + kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head); + } else if (rcu_access_pointer(new->pub.beacon_ies)) { + const struct cfg80211_bss_ies *old; +- struct cfg80211_internal_bss *bss; + + if (known->pub.hidden_beacon_bss && + !list_empty(&known->hidden_list)) { +@@ -1658,16 +1674,7 @@ cfg80211_update_known_bss(struct cfg80211_registered_device *rdev, + if (old == rcu_access_pointer(known->pub.ies)) + rcu_assign_pointer(known->pub.ies, new->pub.beacon_ies); + +- /* Assign beacon IEs to all sub entries */ +- list_for_each_entry(bss, &known->hidden_list, hidden_list) { +- const struct cfg80211_bss_ies *ies; +- +- ies = rcu_access_pointer(bss->pub.beacon_ies); +- WARN_ON(ies != old); +- +- rcu_assign_pointer(bss->pub.beacon_ies, +- new->pub.beacon_ies); +- } ++ cfg80211_update_hidden_bsses(known, new->pub.beacon_ies, old); + + if (old) + kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head); +@@ -2360,6 +2367,8 @@ cfg80211_update_notlisted_nontrans(struct wiphy *wiphy, + } else { + old = rcu_access_pointer(nontrans_bss->beacon_ies); + rcu_assign_pointer(nontrans_bss->beacon_ies, new_ies); ++ cfg80211_update_hidden_bsses(bss_from_pub(nontrans_bss), ++ new_ies, old); + rcu_assign_pointer(nontrans_bss->ies, new_ies); + if (old) + kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head); +-- +2.35.3 + diff --git a/patches.suse/wifi-iwlwifi-mvm-fix-double-list_add-at-iwl_mvm_mac_-95b0f66649bb.patch b/patches.suse/wifi-iwlwifi-mvm-fix-double-list_add-at-iwl_mvm_mac_-95b0f66649bb.patch new file mode 100644 index 0000000..3ae87ae --- /dev/null +++ b/patches.suse/wifi-iwlwifi-mvm-fix-double-list_add-at-iwl_mvm_mac_-95b0f66649bb.patch @@ -0,0 +1,78 @@ +From 95b0f66649bb04c6c9c15e461ecf9522efe9555c Mon Sep 17 00:00:00 2001 +From: Jose Ignacio Tornos Martinez +Date: Mon, 10 Oct 2022 10:16:11 +0200 +Subject: [PATCH] wifi: iwlwifi: mvm: fix double list_add at iwl_mvm_mac_wake_tx_queue (other cases) +Git-commit: 95b0f66649bb04c6c9c15e461ecf9522efe9555c +Patch-mainline: v6.1-rc1 +References: git-fixes + +BUGs like this are still reproducible: + +[ 31.509616] list_add corruption. prev->next should be next (ffff8f8644242300), but was ffff8f86493fd300. (prev=ffff8f86493fd300). +[ 31.521544] ------------[ cut here ]------------ +[ 31.526248] kernel BUG at lib/list_debug.c:30! +[ 31.530781] invalid opcode: 0000 [#1] PREEMPT SMP PTI +[ 31.535831] CPU: 1 PID: 626 Comm: wpa_supplicant Not tainted 6.0.0+ #7 +[ 31.542450] Hardware name: Dell Inc. Inspiron 660s/0478VN , BIOS A07 08/24/2012 +[ 31.550484] RIP: 0010:__list_add_valid.cold+0x3a/0x5b +[ 31.555537] Code: f2 4c 89 c1 48 89 fe 48 c7 c7 28 20 69 89 e8 4c e3 fd ff 0f 0b 48 89 d1 4c 89 c6 4c 89 ca 48 c7 c7 d0 1f 69 89 e8 35 e3 fd ff <0f> 0b 4c 89 c1 48 c7 c7 78 1f 69 89 e8 24 e3 fd ff 0f 0b 48 c7 c7 +[ 31.574605] RSP: 0018:ffff9f6f00dc3748 EFLAGS: 00010286 +[ 31.579990] RAX: 0000000000000075 RBX: ffff8f8644242080 RCX: 0000000000000000 +[ 31.587155] RDX: 0000000000000201 RSI: ffffffff8967862d RDI: 00000000ffffffff +[ 31.594482] RBP: ffff8f86493fd2e8 R08: 0000000000000000 R09: 00000000ffffdfff +[ 31.601735] R10: ffff9f6f00dc3608 R11: ffffffff89f46128 R12: ffff8f86493fd300 +[ 31.608986] R13: ffff8f86493fd300 R14: ffff8f8644242300 R15: ffff8f8643dd3f2c +[ 31.616151] FS: 00007f3bb9a707c0(0000) GS:ffff8f865a300000(0000) knlGS:0000000000000000 +[ 31.624447] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 31.630286] CR2: 00007fe3647d5600 CR3: 00000001125a6002 CR4: 00000000000606e0 +[ 31.637539] Call Trace: +[ 31.639936] +[ 31.642143] iwl_mvm_mac_wake_tx_queue+0x71/0x90 [iwlmvm] +[ 31.647569] ieee80211_queue_skb+0x4b6/0x720 [mac80211] +... + +So, it is necessary to extend the applied solution with commit 14a3aacf517a9 +("iwlwifi: mvm: fix double list_add at iwl_mvm_mac_wake_tx_queue") +to all other cases where the station queues are invalidated and the related +lists are not emptied. Because, otherwise as before, if some new element is +added later to the list in iwl_mvm_mac_wake_tx_queue, it can match with the +old one and produce the same commented BUG. + +That is, in order to avoid this problem completely, we must also remove the +related lists for the other cases when station queues are invalidated. + +Fixes: cfbc6c4c5b91c ("iwlwifi: mvm: support mac80211 TXQs model") +Reported-by: Petr Stourac +Tested-by: Petr Stourac +Signed-off-by: Jose Ignacio Tornos Martinez +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20221010081611.145027-1-jtornosm@redhat.com +Acked-by: Takashi Iwai + +--- + drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +index cc92706b3d16..cbd8053a9e35 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +@@ -384,6 +384,7 @@ static int iwl_mvm_disable_txq(struct iwl_mvm *mvm, struct ieee80211_sta *sta, + iwl_mvm_txq_from_tid(sta, tid); + + mvmtxq->txq_id = IWL_MVM_INVALID_QUEUE; ++ list_del_init(&mvmtxq->list); + } + + /* Regardless if this is a reserved TXQ for a STA - mark it as false */ +@@ -478,6 +479,7 @@ static int iwl_mvm_remove_sta_queue_marking(struct iwl_mvm *mvm, int queue) + mvmsta->tid_data[tid].txq_id = IWL_MVM_INVALID_QUEUE; + + mvmtxq->txq_id = IWL_MVM_INVALID_QUEUE; ++ list_del_init(&mvmtxq->list); + } + + mvmsta->tfd_queue_msk &= ~BIT(queue); /* Don't use this queue anymore */ +-- +2.35.3 + diff --git a/patches.suse/wifi-mac80211-allow-bw-change-during-channel-switch-.patch b/patches.suse/wifi-mac80211-allow-bw-change-during-channel-switch-.patch new file mode 100644 index 0000000..6846266 --- /dev/null +++ b/patches.suse/wifi-mac80211-allow-bw-change-during-channel-switch-.patch @@ -0,0 +1,47 @@ +From 6b75f133fe05c36c52d691ff21545d5757fff721 Mon Sep 17 00:00:00 2001 +From: Hari Chandrakanthan +Date: Wed, 27 Jul 2022 12:02:29 +0530 +Subject: [PATCH] wifi: mac80211: allow bw change during channel switch in mesh +Git-commit: 6b75f133fe05c36c52d691ff21545d5757fff721 +Patch-mainline: v6.1-rc1 +References: git-fixes + +From 'IEEE Std 802.11-2020 section 11.8.8.4.1': + The mesh channel switch may be triggered by the need to avoid + interference to a detected radar signal, or to reassign mesh STA + channels to ensure the MBSS connectivity. + + A 20/40 MHz MBSS may be changed to a 20 MHz MBSS and a 20 MHz + MBSS may be changed to a 20/40 MHz MBSS. + +Since the standard allows the change of bandwidth during +the channel switch in mesh, remove the bandwidth check present in +ieee80211_set_csa_beacon. + +Fixes: c6da674aff94 ("{nl,cfg,mac}80211: enable the triggering of CSA frame in mesh") +Signed-off-by: Hari Chandrakanthan +Link: https://lore.kernel.org/r/1658903549-21218-1-git-send-email-quic_haric@quicinc.com +Signed-off-by: Johannes Berg +Acked-by: Takashi Iwai + +--- + net/mac80211/cfg.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c +index 854becd00468..960d5c4a5940 100644 +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -3683,9 +3683,6 @@ static int ieee80211_set_csa_beacon(struct ieee80211_sub_if_data *sdata, + case NL80211_IFTYPE_MESH_POINT: { + struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; + +- if (params->chandef.width != sdata->vif.bss_conf.chandef.width) +- return -EINVAL; +- + /* changes into another band are not supported */ + if (sdata->vif.bss_conf.chandef.chan->band != + params->chandef.chan->band) +-- +2.35.3 + diff --git a/patches.suse/wifi-mac80211-do-not-drop-packets-smaller-than-the-L.patch b/patches.suse/wifi-mac80211-do-not-drop-packets-smaller-than-the-L.patch new file mode 100644 index 0000000..3943ced --- /dev/null +++ b/patches.suse/wifi-mac80211-do-not-drop-packets-smaller-than-the-L.patch @@ -0,0 +1,38 @@ +From f5369dcf5c0a76260cd301bd5c25d59c451d62c1 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Fri, 7 Oct 2022 11:05:09 +0200 +Subject: [PATCH] wifi: mac80211: do not drop packets smaller than the LLC-SNAP header on fast-rx +Git-commit: f5369dcf5c0a76260cd301bd5c25d59c451d62c1 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Since STP TCN frames are only 7 bytes, the pskb_may_pull call returns an error. +Instead of dropping those packets, bump them back to the slow path for proper +processing. + +Fixes: 49ddf8e6e234 ("mac80211: add fast-rx path") +Reported-by: Chad Monroe +Signed-off-by: Felix Fietkau +Signed-off-by: Johannes Berg +Acked-by: Takashi Iwai + +--- + net/mac80211/rx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c +index bd215fe3c796..333adad47482 100644 +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -4708,7 +4708,7 @@ static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx, + + if (!(status->rx_flags & IEEE80211_RX_AMSDU)) { + if (!pskb_may_pull(skb, snap_offs + sizeof(*payload))) +- goto drop; ++ return false; + + payload = (void *)(skb->data + snap_offs); + +-- +2.35.3 + diff --git a/patches.suse/wifi-mac80211-fix-MBSSID-parsing-use-after-free.patch b/patches.suse/wifi-mac80211-fix-MBSSID-parsing-use-after-free.patch new file mode 100644 index 0000000..982d9e0 --- /dev/null +++ b/patches.suse/wifi-mac80211-fix-MBSSID-parsing-use-after-free.patch @@ -0,0 +1,105 @@ +From ff05d4b45dd89b922578dac497dcabf57cf771c6 Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Wed, 28 Sep 2022 22:07:15 +0200 +Subject: [PATCH] wifi: mac80211: fix MBSSID parsing use-after-free +Git-commit: ff05d4b45dd89b922578dac497dcabf57cf771c6 +Patch-mainline: v6.1-rc1 +References: CVE-2022-42719 bsc#1204051 + +When we parse a multi-BSSID element, we might point some +element pointers into the allocated nontransmitted_profile. +However, we free this before returning, causing UAF when the +relevant pointers in the parsed elements are accessed. + +Fix this by not allocating the scratch buffer separately but +as part of the returned structure instead, that way, there +are no lifetime issues with it. + +The scratch buffer introduction as part of the returned data +here is taken from MLO feature work done by Ilan. + +This fixes CVE-2022-42719. + +Fixes: 5023b14cf4df ("mac80211: support profile split between elements") +Co-developed-by: Ilan Peer +Signed-off-by: Ilan Peer +Reviewed-by: Kees Cook +Signed-off-by: Johannes Berg +Signed-off-by: Takashi Iwai + +--- + net/mac80211/ieee80211_i.h | 8 ++++++++ + net/mac80211/util.c | 32 ++++++++++++++++---------------- + 2 files changed, 24 insertions(+), 16 deletions(-) + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -1601,6 +1601,14 @@ struct ieee802_11_elems { + + /* whether a parse error occurred while retrieving these elements */ + bool parse_error; ++ ++ /* ++ * scratch buffer that can be used for various element parsing related ++ * tasks, e.g., element de-fragmentation etc. ++ */ ++ size_t scratch_len; ++ u8 *scratch_pos; ++ u8 scratch[]; + }; + + static inline struct ieee80211_local *hw_to_local( +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -1459,26 +1459,28 @@ ieee802_11_parse_elems_full(struct ieee8 + const struct element *non_inherit = NULL; + u8 *nontransmitted_profile; + int nontransmitted_profile_len = 0; ++ size_t scratch_len = params->len; + +- elems = kzalloc(sizeof(*elems), GFP_ATOMIC); ++ elems = kzalloc(sizeof(*elems) + scratch_len, GFP_ATOMIC); + if (!elems) + return NULL; + elems->ie_start = params->start; + elems->total_len = params->len; ++ elems->scratch_len = scratch_len; ++ elems->scratch_pos = elems->scratch; + +- nontransmitted_profile = kmalloc(params->len, GFP_ATOMIC); +- if (nontransmitted_profile) { +- nontransmitted_profile_len = +- ieee802_11_find_bssid_profile(params->start, params->len, +- elems, +- params->transmitter_bssid, +- params->bss_bssid, +- nontransmitted_profile); +- non_inherit = +- cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE, +- nontransmitted_profile, +- nontransmitted_profile_len); +- } ++ nontransmitted_profile = elems->scratch_pos; ++ nontransmitted_profile_len = ++ ieee802_11_find_bssid_profile(params->start, params->len, ++ elems, ++ params->transmitter_bssid, ++ params->bss_bssid, ++ nontransmitted_profile); ++ elems->scratch_pos += nontransmitted_profile_len; ++ elems->scratch_len -= nontransmitted_profile_len; ++ non_inherit = cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE, ++ nontransmitted_profile, ++ nontransmitted_profile_len); + + elems->crc = _ieee802_11_parse_elems_full(params, elems, non_inherit); + +@@ -1511,8 +1513,6 @@ ieee802_11_parse_elems_full(struct ieee8 + offsetofend(struct ieee80211_bssid_index, dtim_count)) + elems->dtim_count = elems->bssid_index->dtim_count; + +- kfree(nontransmitted_profile); +- + return elems; + } + diff --git a/patches.suse/wifi-mac80211-fix-crash-in-beacon-protection-for-P2P.patch b/patches.suse/wifi-mac80211-fix-crash-in-beacon-protection-for-P2P.patch new file mode 100644 index 0000000..a7ea4d2 --- /dev/null +++ b/patches.suse/wifi-mac80211-fix-crash-in-beacon-protection-for-P2P.patch @@ -0,0 +1,62 @@ +From b2d03cabe2b2e150ff5a381731ea0355459be09f Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Wed, 5 Oct 2022 21:24:10 +0200 +Subject: [PATCH] wifi: mac80211: fix crash in beacon protection for P2P-device +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: b2d03cabe2b2e150ff5a381731ea0355459be09f +Patch-mainline: v6.1-rc1 +References: CVE-2022-42722 bsc#1204125 + +If beacon protection is active but the beacon cannot be +decrypted or is otherwise malformed, we call the cfg80211 +API to report this to userspace, but that uses a netdev +pointer, which isn't present for P2P-Device. Fix this to +call it only conditionally to ensure cfg80211 won't crash +in the case of P2P-Device. + +This fixes CVE-2022-42722. + +Reported-by: Sönke Huster +Fixes: 9eaf183af741 ("mac80211: Report beacon protection failures to user space") +Signed-off-by: Johannes Berg +Signed-off-by: Takashi Iwai + +--- + net/mac80211/rx.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c +index bd215fe3c796..6001adc0a00e 100644 +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -1978,10 +1978,11 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) + + if (mmie_keyidx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS || + mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS + +- NUM_DEFAULT_BEACON_KEYS) { +- cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev, +- skb->data, +- skb->len); ++ NUM_DEFAULT_BEACON_KEYS) { ++ if (rx->sdata->dev) ++ cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev, ++ skb->data, ++ skb->len); + return RX_DROP_MONITOR; /* unexpected BIP keyidx */ + } + +@@ -2131,7 +2132,8 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) + /* either the frame has been decrypted or will be dropped */ + status->flag |= RX_FLAG_DECRYPTED; + +- if (unlikely(ieee80211_is_beacon(fc) && result == RX_DROP_UNUSABLE)) ++ if (unlikely(ieee80211_is_beacon(fc) && result == RX_DROP_UNUSABLE && ++ rx->sdata->dev)) + cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev, + skb->data, skb->len); + +-- +2.35.3 + diff --git a/patches.suse/wifi-mac80211-fix-decap-offload-for-stations-on-AP_V.patch b/patches.suse/wifi-mac80211-fix-decap-offload-for-stations-on-AP_V.patch new file mode 100644 index 0000000..a8c43f6 --- /dev/null +++ b/patches.suse/wifi-mac80211-fix-decap-offload-for-stations-on-AP_V.patch @@ -0,0 +1,50 @@ +From 3bf9e30e493356912f9cb600f59b51133680639e Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Sat, 1 Oct 2022 12:01:13 +0200 +Subject: [PATCH] wifi: mac80211: fix decap offload for stations on AP_VLAN interfaces +Git-commit: 3bf9e30e493356912f9cb600f59b51133680639e +Patch-mainline: v6.1-rc1 +References: git-fixes + +Since AP_VLAN interfaces are not passed to the driver, check offload_flags +on the bss vif instead. + +Reported-by: Howard Hsu +Fixes: 80a915ec4427 ("mac80211: add rx decapsulation offload support") +Signed-off-by: Felix Fietkau +Signed-off-by: Johannes Berg +Acked-by: Takashi Iwai + +--- + net/mac80211/rx.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c +index 333adad47482..589521717c35 100644 +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -4352,6 +4352,7 @@ void ieee80211_check_fast_rx(struct sta_info *sta) + .vif_type = sdata->vif.type, + .control_port_protocol = sdata->control_port_protocol, + }, *old, *new = NULL; ++ u32 offload_flags; + bool set_offload = false; + bool assign = false; + bool offload; +@@ -4467,10 +4468,10 @@ void ieee80211_check_fast_rx(struct sta_info *sta) + if (assign) + new = kmemdup(&fastrx, sizeof(fastrx), GFP_KERNEL); + +- offload = assign && +- (sdata->vif.offload_flags & IEEE80211_OFFLOAD_DECAP_ENABLED); ++ offload_flags = get_bss_sdata(sdata)->vif.offload_flags; ++ offload = offload_flags & IEEE80211_OFFLOAD_DECAP_ENABLED; + +- if (offload) ++ if (assign && offload) + set_offload = !test_and_set_sta_flag(sta, WLAN_STA_DECAP_OFFLOAD); + else + set_offload = test_and_clear_sta_flag(sta, WLAN_STA_DECAP_OFFLOAD); +-- +2.35.3 + diff --git a/patches.suse/wifi-mac80211-fix-probe-req-HE-capabilities-access.patch b/patches.suse/wifi-mac80211-fix-probe-req-HE-capabilities-access.patch new file mode 100644 index 0000000..c44965b --- /dev/null +++ b/patches.suse/wifi-mac80211-fix-probe-req-HE-capabilities-access.patch @@ -0,0 +1,41 @@ +From b650009fcb701ea99aa133bbe18dbfc5305ddf1a Mon Sep 17 00:00:00 2001 +From: James Prestwood +Date: Wed, 28 Sep 2022 15:49:10 -0700 +Subject: [PATCH] wifi: mac80211: fix probe req HE capabilities access +Git-commit: b650009fcb701ea99aa133bbe18dbfc5305ddf1a +Patch-mainline: v6.1-rc1 +References: git-fixes + +When building the probe request IEs HE support is checked for +the 6GHz band (wiphy->bands[NL80211_BAND_6GHZ]). If supported +the HE capability IE should be included according to the spec. +The problem is the 16-bit capability is obtained from the +band object (sband) that was passed in, not the 6GHz band +object (sband6). If the sband object doesn't support HE it will +result in a warning. + +Fixes: 7d29bc50b30e ("mac80211: always include HE 6GHz capability in probe request") +Signed-off-by: James Prestwood +Signed-off-by: Johannes Berg +Acked-by: Takashi Iwai + +--- + net/mac80211/util.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/mac80211/util.c b/net/mac80211/util.c +index bf7461c41bef..1e929b82deef 100644 +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -2046,7 +2046,7 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_sub_if_data *sdata, + if (he_cap) { + enum nl80211_iftype iftype = + ieee80211_vif_type_p2p(&sdata->vif); +- __le16 cap = ieee80211_get_he_6ghz_capa(sband, iftype); ++ __le16 cap = ieee80211_get_he_6ghz_capa(sband6, iftype); + + pos = ieee80211_write_he_6ghz_cap(pos, cap, end); + } +-- +2.35.3 + diff --git a/patches.suse/wifi-mac80211-fix-regression-with-non-QoS-drivers.patch b/patches.suse/wifi-mac80211-fix-regression-with-non-QoS-drivers.patch new file mode 100644 index 0000000..9419855 --- /dev/null +++ b/patches.suse/wifi-mac80211-fix-regression-with-non-QoS-drivers.patch @@ -0,0 +1,60 @@ +From d873697ef2b7e1b6fdd8e9d449d9354bd5d29a4a Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Sun, 18 Sep 2022 21:20:52 +0200 +Subject: [PATCH] wifi: mac80211: fix regression with non-QoS drivers +Git-commit: d873697ef2b7e1b6fdd8e9d449d9354bd5d29a4a +Patch-mainline: v6.0 +References: git-fixes + +Commit 10cb8e617560 ("mac80211: enable QoS support for nl80211 ctrl port") +changed ieee80211_tx_control_port() to aways call +__ieee80211_select_queue() without checking local->hw.queues. + +__ieee80211_select_queue() returns a queue-id between 0 and 3, which means +that now ieee80211_tx_control_port() may end up setting the queue-mapping +for a skb to a value higher then local->hw.queues if local->hw.queues +is less then 4. + +Specifically this is a problem for ralink rt2500-pci cards where +local->hw.queues is 2. There this causes rt2x00queue_get_tx_queue() to +return NULL and the following error to be logged: "ieee80211 phy0: +Rt2x00mac_tx: Error - Attempt to send packet over invalid queue 2", +after which association with the AP fails. + +Other callers of __ieee80211_select_queue() skip calling it when +local->hw.queues < IEEE80211_NUM_ACS, add the same check to +ieee80211_tx_control_port(). This fixes ralink rt2500-pci and +similar cards when less then 4 tx-queues no longer working. + +Fixes: 10cb8e617560 ("mac80211: enable QoS support for nl80211 ctrl port") +Cc: Markus Theil +Suggested-by: Stanislaw Gruszka +Signed-off-by: Hans de Goede +Link: https://lore.kernel.org/r/20220918192052.443529-1-hdegoede@redhat.com +Signed-off-by: Johannes Berg +Acked-by: Takashi Iwai + +--- + net/mac80211/tx.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -5712,6 +5712,9 @@ int ieee80211_tx_control_port(struct wip + skb_reset_network_header(skb); + skb_reset_mac_header(skb); + ++ if (local->hw.queues < IEEE80211_NUM_ACS) ++ goto start_xmit; ++ + /* update QoS header to prioritize control port frames if possible, + * priorization also happens for control port frames send over + * AF_PACKET +@@ -5727,6 +5730,7 @@ int ieee80211_tx_control_port(struct wip + + rcu_read_unlock(); + ++start_xmit: + /* mutex lock is only needed for incrementing the cookie counter */ + mutex_lock(&local->mtx); + diff --git a/patches.suse/wifi-mac80211-refactor-elements-parsing-with-paramet.patch b/patches.suse/wifi-mac80211-refactor-elements-parsing-with-paramet.patch new file mode 100644 index 0000000..030384a --- /dev/null +++ b/patches.suse/wifi-mac80211-refactor-elements-parsing-with-paramet.patch @@ -0,0 +1,221 @@ +From fd17bf041b40e3dac705c4313854becbe07b7557 Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Tue, 28 Jun 2022 17:49:12 +0200 +Subject: [PATCH] wifi: mac80211: refactor elements parsing with parameter struct +Git-commit: fd17bf041b40e3dac705c4313854becbe07b7557 +Patch-mainline: v6.0-rc1 +References: CVE-2022-42719 bsc#1204051 + +Refactor the element parsing into a version that has +a parameter struct so we can add more parameters more +easily in the future. + +Signed-off-by: Johannes Berg +Acked-by: Takashi Iwai + +--- + net/mac80211/ieee80211_i.h | 50 ++++++++++++++++++++++++++++---- + net/mac80211/util.c | 58 +++++++++++++++++++------------------- + 2 files changed, 74 insertions(+), 34 deletions(-) + +diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h +index a0743c78d171..2cf13ea4c9f7 100644 +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -2138,11 +2138,51 @@ static inline void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, + ieee80211_tx_skb_tid(sdata, skb, 7); + } + +-struct ieee802_11_elems *ieee802_11_parse_elems_crc(const u8 *start, size_t len, +- bool action, +- u64 filter, u32 crc, +- const u8 *transmitter_bssid, +- const u8 *bss_bssid); ++/** ++ * struct ieee80211_elems_parse_params - element parsing parameters ++ * @start: pointer to the elements ++ * @len: length of the elements ++ * @action: %true if the elements came from an action frame ++ * @filter: bitmap of element IDs to filter out while calculating ++ * the element CRC ++ * @crc: CRC starting value ++ * @transmitter_bssid: transmitter BSSID to parse the multi-BSSID ++ * element ++ * @bss_bssid: BSSID of the BSS we want to obtain elements for ++ * when parsing the multi-BSSID element ++ */ ++struct ieee80211_elems_parse_params { ++ const u8 *start; ++ size_t len; ++ bool action; ++ u64 filter; ++ u32 crc; ++ const u8 *transmitter_bssid; ++ const u8 *bss_bssid; ++}; ++ ++struct ieee802_11_elems * ++ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params); ++ ++static inline struct ieee802_11_elems * ++ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, ++ u64 filter, u32 crc, ++ const u8 *transmitter_bssid, ++ const u8 *bss_bssid) ++{ ++ struct ieee80211_elems_parse_params params = { ++ .start = start, ++ .len = len, ++ .action = action, ++ .filter = filter, ++ .crc = crc, ++ .transmitter_bssid = transmitter_bssid, ++ .bss_bssid = bss_bssid, ++ }; ++ ++ return ieee802_11_parse_elems_full(¶ms); ++} ++ + static inline struct ieee802_11_elems * + ieee802_11_parse_elems(const u8 *start, size_t len, bool action, + const u8 *transmitter_bssid, +diff --git a/net/mac80211/util.c b/net/mac80211/util.c +index 2b2c8e1472f3..0ff09c639c50 100644 +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -1026,19 +1026,19 @@ static void ieee80211_parse_extension_element(u32 *crc, + } + + static u32 +-_ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, +- struct ieee802_11_elems *elems, +- u64 filter, u32 crc, +- const struct element *check_inherit) ++_ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params, ++ struct ieee802_11_elems *elems, ++ const struct element *check_inherit) + { + const struct element *elem; +- bool calc_crc = filter != 0; ++ bool calc_crc = params->filter != 0; + DECLARE_BITMAP(seen_elems, 256); ++ u32 crc = params->crc; + const u8 *ie; + + bitmap_zero(seen_elems, 256); + +- for_each_element(elem, start, len) { ++ for_each_element(elem, params->start, params->len) { + bool elem_parse_failed; + u8 id = elem->id; + u8 elen = elem->datalen; +@@ -1101,7 +1101,7 @@ _ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, + break; + } + +- if (calc_crc && id < 64 && (filter & (1ULL << id))) ++ if (calc_crc && id < 64 && (params->filter & (1ULL << id))) + crc = crc32_be(crc, pos - 2, elen + 2); + + elem_parse_failed = false; +@@ -1282,7 +1282,7 @@ _ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, + elems->mesh_chansw_params_ie = (void *)pos; + break; + case WLAN_EID_WIDE_BW_CHANNEL_SWITCH: +- if (!action || ++ if (!params->action || + elen < sizeof(*elems->wide_bw_chansw_ie)) { + elem_parse_failed = true; + break; +@@ -1290,7 +1290,7 @@ _ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, + elems->wide_bw_chansw_ie = (void *)pos; + break; + case WLAN_EID_CHANNEL_SWITCH_WRAPPER: +- if (action) { ++ if (params->action) { + elem_parse_failed = true; + break; + } +@@ -1417,7 +1417,7 @@ _ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, + __set_bit(id, seen_elems); + } + +- if (!for_each_element_completed(elem, start, len)) ++ if (!for_each_element_completed(elem, params->start, params->len)) + elems->parse_error = true; + + return crc; +@@ -1491,11 +1491,8 @@ static size_t ieee802_11_find_bssid_profile(const u8 *start, size_t len, + return found ? profile_len : 0; + } + +-struct ieee802_11_elems *ieee802_11_parse_elems_crc(const u8 *start, size_t len, +- bool action, u64 filter, +- u32 crc, +- const u8 *transmitter_bssid, +- const u8 *bss_bssid) ++struct ieee802_11_elems * ++ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params) + { + struct ieee802_11_elems *elems; + const struct element *non_inherit = NULL; +@@ -1505,15 +1502,16 @@ struct ieee802_11_elems *ieee802_11_parse_elems_crc(const u8 *start, size_t len, + elems = kzalloc(sizeof(*elems), GFP_ATOMIC); + if (!elems) + return NULL; +- elems->ie_start = start; +- elems->total_len = len; ++ elems->ie_start = params->start; ++ elems->total_len = params->len; + +- nontransmitted_profile = kmalloc(len, GFP_ATOMIC); ++ nontransmitted_profile = kmalloc(params->len, GFP_ATOMIC); + if (nontransmitted_profile) { + nontransmitted_profile_len = +- ieee802_11_find_bssid_profile(start, len, elems, +- transmitter_bssid, +- bss_bssid, ++ ieee802_11_find_bssid_profile(params->start, params->len, ++ elems, ++ params->transmitter_bssid, ++ params->bss_bssid, + nontransmitted_profile); + non_inherit = + cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE, +@@ -1521,14 +1519,18 @@ struct ieee802_11_elems *ieee802_11_parse_elems_crc(const u8 *start, size_t len, + nontransmitted_profile_len); + } + +- crc = _ieee802_11_parse_elems_crc(start, len, action, elems, filter, +- crc, non_inherit); ++ elems->crc = _ieee802_11_parse_elems_full(params, elems, non_inherit); + + /* Override with nontransmitted profile, if found */ +- if (nontransmitted_profile_len) +- _ieee802_11_parse_elems_crc(nontransmitted_profile, +- nontransmitted_profile_len, +- action, elems, 0, 0, NULL); ++ if (nontransmitted_profile_len) { ++ struct ieee80211_elems_parse_params sub = { ++ .start = nontransmitted_profile, ++ .len = nontransmitted_profile_len, ++ .action = params->action, ++ }; ++ ++ _ieee802_11_parse_elems_full(&sub, elems, NULL); ++ } + + if (elems->tim && !elems->parse_error) { + const struct ieee80211_tim_ie *tim_ie = elems->tim; +@@ -1550,8 +1552,6 @@ struct ieee802_11_elems *ieee802_11_parse_elems_crc(const u8 *start, size_t len, + + kfree(nontransmitted_profile); + +- elems->crc = crc; +- + return elems; + } + +-- +2.35.3 + diff --git a/patches.suse/wifi-mac80211_hwsim-avoid-mac80211-warning-on-bad-ra.patch b/patches.suse/wifi-mac80211_hwsim-avoid-mac80211-warning-on-bad-ra.patch new file mode 100644 index 0000000..d6821f1 --- /dev/null +++ b/patches.suse/wifi-mac80211_hwsim-avoid-mac80211-warning-on-bad-ra.patch @@ -0,0 +1,36 @@ +From 1833b6f46d7e2830251a063935ab464256defe22 Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Wed, 5 Oct 2022 15:10:09 +0200 +Subject: [PATCH] wifi: mac80211_hwsim: avoid mac80211 warning on bad rate +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 1833b6f46d7e2830251a063935ab464256defe22 +Patch-mainline: v6.1-rc1 +References: git-fixes + +If the tool on the other side (e.g. wmediumd) gets confused +about the rate, we hit a warning in mac80211. Silence that +by effectively duplicating the check here and dropping the +frame silently (in mac80211 it's dropped with the warning). + +Reported-by: Sönke Huster +Tested-by: Sönke Huster +Signed-off-by: Johannes Berg +Acked-by: Takashi Iwai + +--- + drivers/net/wireless/mac80211_hwsim.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/wireless/mac80211_hwsim.c ++++ b/drivers/net/wireless/mac80211_hwsim.c +@@ -3749,6 +3749,8 @@ static int hwsim_cloned_frame_received_n + + rx_status.band = channel->band; + rx_status.rate_idx = nla_get_u32(info->attrs[HWSIM_ATTR_RX_RATE]); ++ if (rx_status.rate_idx >= data2->hw->wiphy->bands[rx_status.band]->n_bitrates) ++ goto out; + rx_status.signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]); + + hdr = (void *)skb->data; diff --git a/patches.suse/wifi-mac80211_hwsim-check-length-for-virtio-packets.patch b/patches.suse/wifi-mac80211_hwsim-check-length-for-virtio-packets.patch new file mode 100644 index 0000000..56253dd --- /dev/null +++ b/patches.suse/wifi-mac80211_hwsim-check-length-for-virtio-packets.patch @@ -0,0 +1,71 @@ +From 8c0427842aaef161a38ac83b7e8d8fe050b4be04 Mon Sep 17 00:00:00 2001 +From: Soenke Huster +Date: Fri, 2 Sep 2022 10:19:58 +0200 +Subject: [PATCH] wifi: mac80211_hwsim: check length for virtio packets +Git-commit: 8c0427842aaef161a38ac83b7e8d8fe050b4be04 +Patch-mainline: v6.0-rc5 +References: git-fixes + +An invalid packet with a length shorter than the specified length in the +netlink header can lead to use-after-frees and slab-out-of-bounds in the +processing of the netlink attributes, such as the following: + + BUG: KASAN: slab-out-of-bounds in __nla_validate_parse+0x1258/0x2010 + Read of size 2 at addr ffff88800ac7952c by task kworker/0:1/12 + + Workqueue: events hwsim_virtio_rx_work + Call Trace: + + dump_stack_lvl+0x45/0x5d + print_report.cold+0x5e/0x5e5 + kasan_report+0xb1/0x1c0 + __nla_validate_parse+0x1258/0x2010 + __nla_parse+0x22/0x30 + hwsim_virtio_handle_cmd.isra.0+0x13f/0x2d0 + hwsim_virtio_rx_work+0x1b2/0x370 + process_one_work+0x8df/0x1530 + worker_thread+0x575/0x11a0 + kthread+0x29d/0x340 + ret_from_fork+0x22/0x30 + + +Discarding packets with an invalid length solves this. +Therefore, skb->len must be set at reception. + +Change-id: Ieaeb9a4c62d3beede274881a7c2722c6c6f477b6 +Signed-off-by: Soenke Huster +Signed-off-by: Johannes Berg +Acked-by: Takashi Iwai + +--- + drivers/net/wireless/mac80211_hwsim.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c +index 6e55f153ff26..1f301a5fb396 100644 +--- a/drivers/net/wireless/mac80211_hwsim.c ++++ b/drivers/net/wireless/mac80211_hwsim.c +@@ -5060,6 +5060,10 @@ static int hwsim_virtio_handle_cmd(struct sk_buff *skb) + + nlh = nlmsg_hdr(skb); + gnlh = nlmsg_data(nlh); ++ ++ if (skb->len < nlh->nlmsg_len) ++ return -EINVAL; ++ + err = genlmsg_parse(nlh, &hwsim_genl_family, tb, HWSIM_ATTR_MAX, + hwsim_genl_policy, NULL); + if (err) { +@@ -5102,7 +5106,8 @@ static void hwsim_virtio_rx_work(struct work_struct *work) + spin_unlock_irqrestore(&hwsim_virtio_lock, flags); + + skb->data = skb->head; +- skb_set_tail_pointer(skb, len); ++ skb_reset_tail_pointer(skb); ++ skb_put(skb, len); + hwsim_virtio_handle_cmd(skb); + + spin_lock_irqsave(&hwsim_virtio_lock, flags); +-- +2.35.3 + diff --git a/patches.suse/wifi-mt76-fix-reading-current-per-tid-starting-seque.patch b/patches.suse/wifi-mt76-fix-reading-current-per-tid-starting-seque.patch new file mode 100644 index 0000000..6bcc923 --- /dev/null +++ b/patches.suse/wifi-mt76-fix-reading-current-per-tid-starting-seque.patch @@ -0,0 +1,38 @@ +From c3a510e2b53785df31d882a773c4c0780b4c825f Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Fri, 26 Aug 2022 20:23:29 +0200 +Subject: [PATCH] wifi: mt76: fix reading current per-tid starting sequence number for aggregation +Git-commit: c3a510e2b53785df31d882a773c4c0780b4c825f +Patch-mainline: v6.0-rc7 +References: git-fixes + +The code was accidentally shifting register values down by tid % 32 instead of +(tid * field_size) % 32. + +Cc: stable@vger.kernel.org +Fixes: a28bef561a5c ("mt76: mt7615: re-enable offloading of sequence number assignment") +Signed-off-by: Felix Fietkau +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20220826182329.18155-1-nbd@nbd.name +Acked-by: Takashi Iwai + +--- + drivers/net/wireless/mediatek/mt76/mt7615/mac.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c +index ad6c7d632eed..d6aae60c440d 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c +@@ -1088,7 +1088,7 @@ u32 mt7615_mac_get_sta_tid_sn(struct mt7615_dev *dev, int wcid, u8 tid) + offset %= 32; + + val = mt76_rr(dev, addr); +- val >>= (tid % 32); ++ val >>= offset; + + if (offset > 20) { + addr += 4; +-- +2.35.3 + diff --git a/patches.suse/wifi-mt76-mt7615-add-mt7615_mutex_acquire-release-in.patch b/patches.suse/wifi-mt76-mt7615-add-mt7615_mutex_acquire-release-in.patch new file mode 100644 index 0000000..86863f6 --- /dev/null +++ b/patches.suse/wifi-mt76-mt7615-add-mt7615_mutex_acquire-release-in.patch @@ -0,0 +1,45 @@ +From 765c69d477a44c088e5d19e7758dfa4db418e3ba Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Mon, 25 Jul 2022 10:26:40 +0200 +Subject: [PATCH] wifi: mt76: mt7615: add mt7615_mutex_acquire/release in mt7615_sta_set_decap_offload +Git-commit: 765c69d477a44c088e5d19e7758dfa4db418e3ba +Patch-mainline: v6.1-rc1 +References: git-fixes + +Similar to mt7921 driver, introduce mt7615_mutex_acquire/release in +mt7615_sta_set_decap_offload in order to avoid sending mcu commands +while the device is in low-power state. + +Fixes: d4b98c63d7a77 ("mt76: mt7615: add support for rx decapsulation offload") +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Felix Fietkau +Acked-by: Takashi Iwai + +--- + drivers/net/wireless/mediatek/mt76/mt7615/main.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c +index 9bf8545c8c17..8d4733f87cda 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c +@@ -1195,12 +1195,16 @@ static void mt7615_sta_set_decap_offload(struct ieee80211_hw *hw, + struct mt7615_dev *dev = mt7615_hw_dev(hw); + struct mt7615_sta *msta = (struct mt7615_sta *)sta->drv_priv; + ++ mt7615_mutex_acquire(dev); ++ + if (enabled) + set_bit(MT_WCID_FLAG_HDR_TRANS, &msta->wcid.flags); + else + clear_bit(MT_WCID_FLAG_HDR_TRANS, &msta->wcid.flags); + + mt7615_mcu_set_sta_decap_offload(dev, vif, sta); ++ ++ mt7615_mutex_release(dev); + } + + #ifdef CONFIG_PM +-- +2.35.3 + diff --git a/patches.suse/wifi-mt76-mt7915-do-not-check-state-before-configuri.patch b/patches.suse/wifi-mt76-mt7915-do-not-check-state-before-configuri.patch new file mode 100644 index 0000000..80a398c --- /dev/null +++ b/patches.suse/wifi-mt76-mt7915-do-not-check-state-before-configuri.patch @@ -0,0 +1,42 @@ +From d2b5bb6dfab29fe32bedefaade88dcd182c03a00 Mon Sep 17 00:00:00 2001 +From: Howard Hsu +Date: Thu, 18 Aug 2022 10:44:07 +0800 +Subject: [PATCH] wifi: mt76: mt7915: do not check state before configuring implicit beamform +Git-commit: d2b5bb6dfab29fe32bedefaade88dcd182c03a00 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Do not need to check running state before configuring implicit Tx +beamform. It is okay to configure implicit Tx beamform in run time. +Noted that the existing connected stations will be applied for new +configuration only if they reconnected to the interface. + +Fixes: 6d6dc980e07d ("mt76: mt7915: add implicit Tx beamforming support") +Signed-off-by: Howard Hsu +Signed-off-by: Felix Fietkau +Acked-by: Takashi Iwai + +--- + drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c +index fd76db8f5269..6ef3431cad64 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c +@@ -23,9 +23,9 @@ mt7915_implicit_txbf_set(void *data, u64 val) + { + struct mt7915_dev *dev = data; + +- if (test_bit(MT76_STATE_RUNNING, &dev->mphy.state)) +- return -EBUSY; +- ++ /* The existing connected stations shall reconnect to apply ++ * new implicit txbf configuration. ++ */ + dev->ibf = !!val; + + return mt7915_mcu_set_txbf(dev, MT_BF_TYPE_UPDATE); +-- +2.35.3 + diff --git a/patches.suse/wifi-mt76-sdio-fix-transmitting-packet-hangs.patch b/patches.suse/wifi-mt76-sdio-fix-transmitting-packet-hangs.patch new file mode 100644 index 0000000..691b8f1 --- /dev/null +++ b/patches.suse/wifi-mt76-sdio-fix-transmitting-packet-hangs.patch @@ -0,0 +1,37 @@ +From 250b1827205846ff346a76044955cb79d4963f70 Mon Sep 17 00:00:00 2001 +From: YN Chen +Date: Sat, 23 Jul 2022 05:59:23 +0800 +Subject: [PATCH] wifi: mt76: sdio: fix transmitting packet hangs +Git-commit: 250b1827205846ff346a76044955cb79d4963f70 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Fix transmitting packets hangs with continuing to pull the pending packet +from mac80211 queues when receiving Tx status notification from the device. + +Fixes: aac5104bf631 ("mt76: sdio: do not run mt76_txq_schedule directly") +Acked-by: Sean Wang +Signed-off-by: YN Chen +Signed-off-by: Felix Fietkau +Acked-by: Takashi Iwai + +--- + drivers/net/wireless/mediatek/mt76/sdio.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/sdio.c b/drivers/net/wireless/mediatek/mt76/sdio.c +index ece4e4bb94a1..0ec308f99af5 100644 +--- a/drivers/net/wireless/mediatek/mt76/sdio.c ++++ b/drivers/net/wireless/mediatek/mt76/sdio.c +@@ -485,7 +485,7 @@ static void mt76s_status_worker(struct mt76_worker *w) + } while (nframes > 0); + + if (resched) +- mt76_worker_schedule(&dev->sdio.txrx_worker); ++ mt76_worker_schedule(&dev->tx_worker); + } + + static void mt76s_tx_status_data(struct work_struct *work) +-- +2.35.3 + diff --git a/patches.suse/wifi-rtl8xxxu-Fix-AIFS-written-to-REG_EDCA_-_PARAM.patch b/patches.suse/wifi-rtl8xxxu-Fix-AIFS-written-to-REG_EDCA_-_PARAM.patch new file mode 100644 index 0000000..150a61f --- /dev/null +++ b/patches.suse/wifi-rtl8xxxu-Fix-AIFS-written-to-REG_EDCA_-_PARAM.patch @@ -0,0 +1,93 @@ +From 5574d3290449916397f3092dcd2bac92415498e1 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Sun, 18 Sep 2022 15:42:25 +0300 +Subject: [PATCH] wifi: rtl8xxxu: Fix AIFS written to REG_EDCA_*_PARAM +Git-commit: 5574d3290449916397f3092dcd2bac92415498e1 +Patch-mainline: v6.1-rc1 +References: git-fixes + +ieee80211_tx_queue_params.aifs is not supposed to be written directly +to the REG_EDCA_*_PARAM registers. Instead process it like the vendor +drivers do. It's kinda hacky but it works. + +This change boosts the download speed and makes it more stable. + +Tested with RTL8188FU but all the other supported chips should also +benefit. + +Fixes: 26f1fad29ad9 ("New driver: rtl8xxxu (mac80211)") +Signed-off-by: Bitterblue Smith +Acked-by: Jes Sorensen +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/038cc03f-3567-77ba-a7bd-c4930e3b2fad@gmail.com +Acked-by: Takashi Iwai + +--- + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 49 ++++++++++++++++++ + 1 file changed, 49 insertions(+) + +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -4507,6 +4507,53 @@ rtl8xxxu_wireless_mode(struct ieee80211_ + return network_type; + } + ++static void rtl8xxxu_set_aifs(struct rtl8xxxu_priv *priv, u8 slot_time) ++{ ++ u32 reg_edca_param[IEEE80211_NUM_ACS] = { ++ [IEEE80211_AC_VO] = REG_EDCA_VO_PARAM, ++ [IEEE80211_AC_VI] = REG_EDCA_VI_PARAM, ++ [IEEE80211_AC_BE] = REG_EDCA_BE_PARAM, ++ [IEEE80211_AC_BK] = REG_EDCA_BK_PARAM, ++ }; ++ u32 val32; ++ u16 wireless_mode = 0; ++ u8 aifs, aifsn, sifs; ++ int i; ++ ++ if (priv->vif) { ++ struct ieee80211_sta *sta; ++ ++ rcu_read_lock(); ++ sta = ieee80211_find_sta(priv->vif, priv->vif->bss_conf.bssid); ++ if (sta) ++ wireless_mode = rtl8xxxu_wireless_mode(priv->hw, sta); ++ rcu_read_unlock(); ++ } ++ ++ if (priv->hw->conf.chandef.chan->band == NL80211_BAND_5GHZ || ++ (wireless_mode & WIRELESS_MODE_N_24G)) ++ sifs = 16; ++ else ++ sifs = 10; ++ ++ for (i = 0; i < IEEE80211_NUM_ACS; i++) { ++ val32 = rtl8xxxu_read32(priv, reg_edca_param[i]); ++ ++ /* It was set in conf_tx. */ ++ aifsn = val32 & 0xff; ++ ++ /* aifsn not set yet or already fixed */ ++ if (aifsn < 2 || aifsn > 15) ++ continue; ++ ++ aifs = aifsn * slot_time + sifs; ++ ++ val32 &= ~0xff; ++ val32 |= aifs; ++ rtl8xxxu_write32(priv, reg_edca_param[i], val32); ++ } ++} ++ + static void + rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf, u32 changed) +@@ -4592,6 +4639,8 @@ rtl8xxxu_bss_info_changed(struct ieee802 + else + val8 = 20; + rtl8xxxu_write8(priv, REG_SLOT, val8); ++ ++ rtl8xxxu_set_aifs(priv, val8); + } + + if (changed & BSS_CHANGED_BSSID) { diff --git a/patches.suse/wifi-rtl8xxxu-Fix-skb-misuse-in-TX-queue-selection.patch b/patches.suse/wifi-rtl8xxxu-Fix-skb-misuse-in-TX-queue-selection.patch new file mode 100644 index 0000000..74a0382 --- /dev/null +++ b/patches.suse/wifi-rtl8xxxu-Fix-skb-misuse-in-TX-queue-selection.patch @@ -0,0 +1,47 @@ +From edd5747aa12ed61a5ecbfa58d3908623fddbf1e8 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 31 Aug 2022 19:12:36 +0300 +Subject: [PATCH] wifi: rtl8xxxu: Fix skb misuse in TX queue selection +Git-commit: edd5747aa12ed61a5ecbfa58d3908623fddbf1e8 +Patch-mainline: v6.1-rc1 +References: git-fixes + +rtl8xxxu_queue_select() selects the wrong TX queues because it's +reading memory from the wrong address. It expects to find ieee80211_hdr +at skb->data, but that's not the case after skb_push(). Move the call +to rtl8xxxu_queue_select() before the call to skb_push(). + +Fixes: 26f1fad29ad9 ("New driver: rtl8xxxu (mac80211)") +Signed-off-by: Bitterblue Smith +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/7fa4819a-4f20-b2af-b7a6-8ee01ac49295@gmail.com +Acked-by: Takashi Iwai + +--- + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +index 862e9c711ac2..070ec3cb067e 100644 +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -5062,6 +5062,8 @@ static void rtl8xxxu_tx(struct ieee80211_hw *hw, + if (control && control->sta) + sta = control->sta; + ++ queue = rtl8xxxu_queue_select(hw, skb); ++ + tx_desc = skb_push(skb, tx_desc_size); + + memset(tx_desc, 0, tx_desc_size); +@@ -5074,7 +5076,6 @@ static void rtl8xxxu_tx(struct ieee80211_hw *hw, + is_broadcast_ether_addr(ieee80211_get_DA(hdr))) + tx_desc->txdw0 |= TXDESC_BROADMULTICAST; + +- queue = rtl8xxxu_queue_select(hw, skb); + tx_desc->txdw1 = cpu_to_le32(queue << TXDESC_QUEUE_SHIFT); + + if (tx_info->control.hw_key) { +-- +2.35.3 + diff --git a/patches.suse/wifi-rtl8xxxu-Improve-rtl8xxxu_queue_select.patch b/patches.suse/wifi-rtl8xxxu-Improve-rtl8xxxu_queue_select.patch new file mode 100644 index 0000000..3006f94 --- /dev/null +++ b/patches.suse/wifi-rtl8xxxu-Improve-rtl8xxxu_queue_select.patch @@ -0,0 +1,52 @@ +From 2fc6de5c6924aea5e84d2edaa40ed744f0720844 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Sun, 18 Sep 2022 15:47:05 +0300 +Subject: [PATCH] wifi: rtl8xxxu: Improve rtl8xxxu_queue_select +Git-commit: 2fc6de5c6924aea5e84d2edaa40ed744f0720844 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Remove the unused ieee80211_hw* parameter, and pass ieee80211_hdr* +instead of relying on skb->data having the right value at the time +the function is called. + +This doesn't change the functionality at all. + +Fixes: 26f1fad29ad9 ("New driver: rtl8xxxu (mac80211)") +Signed-off-by: Bitterblue Smith +Acked-by: Jes Sorensen +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/2af44c28-1c12-46b9-85b9-011560bf7f7e@gmail.com +Acked-by: Takashi Iwai + +--- + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +index 731aba24bb38..ac641a56efb0 100644 +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -4767,9 +4767,8 @@ static u32 rtl8xxxu_80211_to_rtl_queue(u32 queue) + return rtlqueue; + } + +-static u32 rtl8xxxu_queue_select(struct ieee80211_hw *hw, struct sk_buff *skb) ++static u32 rtl8xxxu_queue_select(struct ieee80211_hdr *hdr, struct sk_buff *skb) + { +- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + u32 queue; + + if (ieee80211_is_mgmt(hdr->frame_control)) +@@ -5119,7 +5118,7 @@ static void rtl8xxxu_tx(struct ieee80211_hw *hw, + if (control && control->sta) + sta = control->sta; + +- queue = rtl8xxxu_queue_select(hw, skb); ++ queue = rtl8xxxu_queue_select(hdr, skb); + + tx_desc = skb_push(skb, tx_desc_size); + +-- +2.35.3 + diff --git a/patches.suse/wifi-rtl8xxxu-Remove-copy-paste-leftover-in-gen2_upd.patch b/patches.suse/wifi-rtl8xxxu-Remove-copy-paste-leftover-in-gen2_upd.patch new file mode 100644 index 0000000..585490c --- /dev/null +++ b/patches.suse/wifi-rtl8xxxu-Remove-copy-paste-leftover-in-gen2_upd.patch @@ -0,0 +1,49 @@ +From d5350756c03cdf18696295c6b11d7acc4dbf825c Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Fri, 2 Sep 2022 16:15:30 +0300 +Subject: [PATCH] wifi: rtl8xxxu: Remove copy-paste leftover in gen2_update_rate_mask +Git-commit: d5350756c03cdf18696295c6b11d7acc4dbf825c +Patch-mainline: v6.1-rc1 +References: git-fixes + +It looks like a leftover from copying rtl8xxxu_update_rate_mask, +which is used with the gen1 chips. + +It wasn't causing any problems for my RTL8188FU test device, but it's +clearly a mistake, so remove it. + +Fixes: f653e69009c6 ("rtl8xxxu: Implement basic 8723b specific update_rate_mask() function") +Signed-off-by: Bitterblue Smith +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/d5544fe8-9798-28f1-54bd-6839a1974b10@gmail.com +Acked-by: Takashi Iwai + +--- + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +index 0cc29988ae67..02ea75354908 100644 +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -4353,15 +4353,14 @@ void rtl8xxxu_gen2_update_rate_mask(struct rtl8xxxu_priv *priv, + h2c.b_macid_cfg.ramask2 = (ramask >> 16) & 0xff; + h2c.b_macid_cfg.ramask3 = (ramask >> 24) & 0xff; + +- h2c.ramask.arg = 0x80; + h2c.b_macid_cfg.data1 = rateid; + if (sgi) + h2c.b_macid_cfg.data1 |= BIT(7); + + h2c.b_macid_cfg.data2 = bw; + +- dev_dbg(&priv->udev->dev, "%s: rate mask %08x, arg %02x, size %zi\n", +- __func__, ramask, h2c.ramask.arg, sizeof(h2c.b_macid_cfg)); ++ dev_dbg(&priv->udev->dev, "%s: rate mask %08x, rateid %02x, sgi %d, size %zi\n", ++ __func__, ramask, rateid, sgi, sizeof(h2c.b_macid_cfg)); + rtl8xxxu_gen2_h2c_cmd(priv, &h2c, sizeof(h2c.b_macid_cfg)); + } + +-- +2.35.3 + diff --git a/patches.suse/wifi-rtl8xxxu-gen2-Fix-mistake-in-path-B-IQ-calibrat.patch b/patches.suse/wifi-rtl8xxxu-gen2-Fix-mistake-in-path-B-IQ-calibrat.patch new file mode 100644 index 0000000..28200a4 --- /dev/null +++ b/patches.suse/wifi-rtl8xxxu-gen2-Fix-mistake-in-path-B-IQ-calibrat.patch @@ -0,0 +1,46 @@ +From e963a19c64ac0d2f8785d36a27391abd91ac77aa Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Fri, 2 Sep 2022 14:48:32 +0300 +Subject: [PATCH] wifi: rtl8xxxu: gen2: Fix mistake in path B IQ calibration +Git-commit: e963a19c64ac0d2f8785d36a27391abd91ac77aa +Patch-mainline: v6.1-rc1 +References: git-fixes + +Found by comparing with the vendor driver. Currently this affects +only the RTL8192EU, which is the only gen2 chip with 2 TX paths +supported by this driver. It's unclear what kind of effect the +mistake had in practice, since I don't have any RTL8192EU devices +to test it. + +Fixes: e1547c535ede ("rtl8xxxu: First stab at adding IQK calibration for 8723bu parts") +Signed-off-by: Bitterblue Smith +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/30a59f3a-cfa9-8379-7af0-78a8f4c77cfd@gmail.com +Acked-by: Takashi Iwai + +--- + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +index 070ec3cb067e..0cc29988ae67 100644 +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -2929,12 +2929,12 @@ bool rtl8xxxu_gen2_simularity_compare(struct rtl8xxxu_priv *priv, + } + + if (!(simubitmap & 0x30) && priv->tx_paths > 1) { +- /* path B RX OK */ ++ /* path B TX OK */ + for (i = 4; i < 6; i++) + result[3][i] = result[c1][i]; + } + +- if (!(simubitmap & 0x30) && priv->tx_paths > 1) { ++ if (!(simubitmap & 0xc0) && priv->tx_paths > 1) { + /* path B RX OK */ + for (i = 6; i < 8; i++) + result[3][i] = result[c1][i]; +-- +2.35.3 + diff --git a/patches.suse/wifi-rtl8xxxu-tighten-bounds-checking-in-rtl8xxxu_re.patch b/patches.suse/wifi-rtl8xxxu-tighten-bounds-checking-in-rtl8xxxu_re.patch new file mode 100644 index 0000000..99181cb --- /dev/null +++ b/patches.suse/wifi-rtl8xxxu-tighten-bounds-checking-in-rtl8xxxu_re.patch @@ -0,0 +1,59 @@ +From 620d5eaeb9059636864bda83ca1c68c20ede34a5 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Fri, 19 Aug 2022 08:22:32 +0300 +Subject: [PATCH] wifi: rtl8xxxu: tighten bounds checking in rtl8xxxu_read_efuse() +Git-commit: 620d5eaeb9059636864bda83ca1c68c20ede34a5 +Patch-mainline: v6.1-rc1 +References: git-fixes + +There some bounds checking to ensure that "map_addr" is not out of +bounds before the start of the loop. But the checking needs to be +done as we iterate through the loop because "map_addr" gets larger as +we iterate. + +Fixes: 26f1fad29ad9 ("New driver: rtl8xxxu (mac80211)") +Signed-off-by: Dan Carpenter +Acked-by: Jes Sorensen +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/Yv8eGLdBslLAk3Ct@kili +Acked-by: Takashi Iwai + +--- + .../net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +index c66f0726b253..f3a107f19cf5 100644 +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -1878,13 +1878,6 @@ static int rtl8xxxu_read_efuse(struct rtl8xxxu_priv *priv) + + /* We have 8 bits to indicate validity */ + map_addr = offset * 8; +- if (map_addr >= EFUSE_MAP_LEN) { +- dev_warn(dev, "%s: Illegal map_addr (%04x), " +- "efuse corrupt!\n", +- __func__, map_addr); +- ret = -EINVAL; +- goto exit; +- } + for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) { + /* Check word enable condition in the section */ + if (word_mask & BIT(i)) { +@@ -1895,6 +1888,13 @@ static int rtl8xxxu_read_efuse(struct rtl8xxxu_priv *priv) + ret = rtl8xxxu_read_efuse8(priv, efuse_addr++, &val8); + if (ret) + goto exit; ++ if (map_addr >= EFUSE_MAP_LEN - 1) { ++ dev_warn(dev, "%s: Illegal map_addr (%04x), " ++ "efuse corrupt!\n", ++ __func__, map_addr); ++ ret = -EINVAL; ++ goto exit; ++ } + priv->efuse_wifi.raw[map_addr++] = val8; + + ret = rtl8xxxu_read_efuse8(priv, efuse_addr++, &val8); +-- +2.35.3 + diff --git a/patches.suse/wifi-rtlwifi-8192de-correct-checking-of-IQK-reload.patch b/patches.suse/wifi-rtlwifi-8192de-correct-checking-of-IQK-reload.patch new file mode 100644 index 0000000..3641ed8 --- /dev/null +++ b/patches.suse/wifi-rtlwifi-8192de-correct-checking-of-IQK-reload.patch @@ -0,0 +1,52 @@ +From 93fbc1ebd978cf408ef5765e9c1630fce9a8621b Mon Sep 17 00:00:00 2001 +From: Ping-Ke Shih +Date: Mon, 1 Aug 2022 19:33:45 +0800 +Subject: [PATCH] wifi: rtlwifi: 8192de: correct checking of IQK reload +Git-commit: 93fbc1ebd978cf408ef5765e9c1630fce9a8621b +Patch-mainline: v6.1-rc1 +References: git-fixes + +Since IQK could spend time, we make a cache of IQK result matrix that looks +like iqk_matrix[channel_idx].val[x][y], and we can reload the matrix if we +have made a cache. To determine a cache is made, we check +iqk_matrix[channel_idx].val[0][0]. + +The initial commit 7274a8c22980 ("rtlwifi: rtl8192de: Merge phy routines") +make a mistake that checks incorrect iqk_matrix[channel_idx].val[0] that +is always true, and this mistake is found by commit ee3db469dd31 +("wifi: rtlwifi: remove always-true condition pointed out by GCC 12"), so +I recall the vendor driver to find fix and apply the correctness. + +Fixes: 7274a8c22980 ("rtlwifi: rtl8192de: Merge phy routines") +Signed-off-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20220801113345.42016-1-pkshih@realtek.com +Acked-by: Takashi Iwai + +--- + drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c +index 15e6a6aded31..d18c092b6142 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c +@@ -2386,11 +2386,10 @@ void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel) + rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, + "Just Read IQK Matrix reg for channel:%d....\n", + channel); +- _rtl92d_phy_patha_fill_iqk_matrix(hw, true, +- rtlphy->iqk_matrix[ +- indexforchannel].value, 0, +- (rtlphy->iqk_matrix[ +- indexforchannel].value[0][2] == 0)); ++ if (rtlphy->iqk_matrix[indexforchannel].value[0][0] != 0) ++ _rtl92d_phy_patha_fill_iqk_matrix(hw, true, ++ rtlphy->iqk_matrix[indexforchannel].value, 0, ++ rtlphy->iqk_matrix[indexforchannel].value[0][2] == 0); + if (IS_92D_SINGLEPHY(rtlhal->version)) { + if ((rtlphy->iqk_matrix[ + indexforchannel].value[0][4] != 0) +-- +2.35.3 + diff --git a/patches.suse/wifi-rtw88-add-missing-destroy_workqueue-on-error-pa.patch b/patches.suse/wifi-rtw88-add-missing-destroy_workqueue-on-error-pa.patch new file mode 100644 index 0000000..aab9815 --- /dev/null +++ b/patches.suse/wifi-rtw88-add-missing-destroy_workqueue-on-error-pa.patch @@ -0,0 +1,55 @@ +From b0ea758b30bbdf7c4323c78b7c50c05d2e1224d5 Mon Sep 17 00:00:00 2001 +From: Yang Yingliang +Date: Fri, 26 Aug 2022 10:38:17 +0800 +Subject: [PATCH] wifi: rtw88: add missing destroy_workqueue() on error path in rtw_core_init() +Git-commit: b0ea758b30bbdf7c4323c78b7c50c05d2e1224d5 +Patch-mainline: v6.1-rc1 +References: git-fixes + +Add the missing destroy_workqueue() before return from rtw_core_init() +in error path. + +Fixes: fe101716c7c9 ("rtw88: replace tx tasklet with work queue") +Signed-off-by: Yang Yingliang +Reviewed-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20220826023817.3908255-1-yangyingliang@huawei.com +Acked-by: Takashi Iwai + +--- + drivers/net/wireless/realtek/rtw88/main.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c +index 5a74dda97756..67151dbf8384 100644 +--- a/drivers/net/wireless/realtek/rtw88/main.c ++++ b/drivers/net/wireless/realtek/rtw88/main.c +@@ -2093,7 +2093,7 @@ int rtw_core_init(struct rtw_dev *rtwdev) + ret = rtw_load_firmware(rtwdev, RTW_NORMAL_FW); + if (ret) { + rtw_warn(rtwdev, "no firmware loaded\n"); +- return ret; ++ goto out; + } + + if (chip->wow_fw_name) { +@@ -2103,11 +2103,15 @@ int rtw_core_init(struct rtw_dev *rtwdev) + wait_for_completion(&rtwdev->fw.completion); + if (rtwdev->fw.firmware) + release_firmware(rtwdev->fw.firmware); +- return ret; ++ goto out; + } + } + + return 0; ++ ++out: ++ destroy_workqueue(rtwdev->tx_wq); ++ return ret; + } + EXPORT_SYMBOL(rtw_core_init); + +-- +2.35.3 + diff --git a/patches.suse/workqueue-don-t-skip-lockdep-work-dependency-in-canc.patch b/patches.suse/workqueue-don-t-skip-lockdep-work-dependency-in-canc.patch new file mode 100644 index 0000000..0b7b180 --- /dev/null +++ b/patches.suse/workqueue-don-t-skip-lockdep-work-dependency-in-canc.patch @@ -0,0 +1,98 @@ +From c0feea594e058223973db94c1c32a830c9807c86 Mon Sep 17 00:00:00 2001 +From: Tetsuo Handa +Date: Fri, 29 Jul 2022 13:30:23 +0900 +Subject: [PATCH] workqueue: don't skip lockdep work dependency in cancel_work_sync() +Git-commit: c0feea594e058223973db94c1c32a830c9807c86 +Patch-mainline: v6.0-rc7 +References: git-fixes + +Like Hillf Danton mentioned + + syzbot should have been able to catch cancel_work_sync() in work context + by checking lockdep_map in __flush_work() for both flush and cancel. + +in [1], being unable to report an obvious deadlock scenario shown below is +broken. From locking dependency perspective, sync version of cancel request +should behave as if flush request, for it waits for completion of work if +that work has already started execution. + + ---------- + #include + #include + static DEFINE_MUTEX(mutex); + static void work_fn(struct work_struct *work) + { + schedule_timeout_uninterruptible(HZ / 5); + mutex_lock(&mutex); + mutex_unlock(&mutex); + } + static DECLARE_WORK(work, work_fn); + static int __init test_init(void) + { + schedule_work(&work); + schedule_timeout_uninterruptible(HZ / 10); + mutex_lock(&mutex); + cancel_work_sync(&work); + mutex_unlock(&mutex); + return -EINVAL; + } + module_init(test_init); + MODULE_LICENSE("GPL"); + ---------- + +The check this patch restores was added by commit 0976dfc1d0cd80a4 +("workqueue: Catch more locking problems with flush_work()"). + +Then, lockdep's crossrelease feature was added by commit b09be676e0ff25bd +("locking/lockdep: Implement the 'crossrelease' feature"). As a result, +this check was once removed by commit fd1a5b04dfb899f8 ("workqueue: Remove +now redundant lock acquisitions wrt. workqueue flushes"). + +But lockdep's crossrelease feature was removed by commit e966eaeeb623f099 +("locking/lockdep: Remove the cross-release locking checks"). At this +point, this check should have been restored. + +Then, commit d6e89786bed977f3 ("workqueue: skip lockdep wq dependency in +cancel_work_sync()") introduced a boolean flag in order to distinguish +flush_work() and cancel_work_sync(), for checking "struct workqueue_struct" +dependency when called from cancel_work_sync() was causing false positives. + +Then, commit 87915adc3f0acdf0 ("workqueue: re-add lockdep dependencies for +flushing") tried to restore "struct work_struct" dependency check, but by +error checked this boolean flag. Like an example shown above indicates, +"struct work_struct" dependency needs to be checked for both flush_work() +and cancel_work_sync(). + +Link: https://lkml.kernel.org/r/20220504044800.4966-1-hdanton@sina.com [1] +Reported-by: Hillf Danton +Suggested-by: Lai Jiangshan +Fixes: 87915adc3f0acdf0 ("workqueue: re-add lockdep dependencies for flushing") +Cc: Johannes Berg +Signed-off-by: Tetsuo Handa +Signed-off-by: Tejun Heo +Acked-by: Takashi Iwai + +--- + kernel/workqueue.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/kernel/workqueue.c b/kernel/workqueue.c +index aeea9731ef80..39060a5d0905 100644 +--- a/kernel/workqueue.c ++++ b/kernel/workqueue.c +@@ -3066,10 +3066,8 @@ static bool __flush_work(struct work_struct *work, bool from_cancel) + if (WARN_ON(!work->func)) + return false; + +- if (!from_cancel) { +- lock_map_acquire(&work->lockdep_map); +- lock_map_release(&work->lockdep_map); +- } ++ lock_map_acquire(&work->lockdep_map); ++ lock_map_release(&work->lockdep_map); + + if (start_flush_work(work, &barr, from_cancel)) { + wait_for_completion(&barr.done); +-- +2.35.3 + diff --git a/patches.suse/x86-ACPI-Make-mp_config_acpi_gsi-a-void-function.patch b/patches.suse/x86-ACPI-Make-mp_config_acpi_gsi-a-void-function.patch new file mode 100644 index 0000000..b43f813 --- /dev/null +++ b/patches.suse/x86-ACPI-Make-mp_config_acpi_gsi-a-void-function.patch @@ -0,0 +1,49 @@ +From: Li kunyu +Date: Wed, 11 May 2022 13:16:05 +0800 +Subject: x86: ACPI: Make mp_config_acpi_gsi() a void function +Patch-mainline: v5.19-rc1 +Git-commit: 24773e6c7a27bfc724a8ed5523dc31bbfc9543d5 +References: jsc#PED-1408 + +Because the return value of mp_config_acpi_gsi() is not use, change it +into a void function. + +Signed-off-by: Li kunyu +[ rjw: Subject and changelog rewrite ] +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + arch/x86/kernel/acpi/boot.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +--- a/arch/x86/kernel/acpi/boot.c ++++ b/arch/x86/kernel/acpi/boot.c +@@ -375,7 +375,7 @@ static void __init mp_override_legacy_ir + isa_irq_to_gsi[bus_irq] = gsi; + } + +-static int mp_config_acpi_gsi(struct device *dev, u32 gsi, int trigger, ++static void mp_config_acpi_gsi(struct device *dev, u32 gsi, int trigger, + int polarity) + { + #ifdef CONFIG_X86_MPPARSE +@@ -387,9 +387,9 @@ static int mp_config_acpi_gsi(struct dev + u8 pin; + + if (!acpi_ioapic) +- return 0; ++ return; + if (!dev || !dev_is_pci(dev)) +- return 0; ++ return; + + pdev = to_pci_dev(dev); + number = pdev->bus->number; +@@ -408,7 +408,6 @@ static int mp_config_acpi_gsi(struct dev + + mp_save_irq(&mp_irq); + #endif +- return 0; + } + + static int __init mp_register_ioapic_irq(u8 bus_irq, u8 polarity, diff --git a/patches.suse/x86-ACPI-Preserve-ACPI-table-override-during-hiberna.patch b/patches.suse/x86-ACPI-Preserve-ACPI-table-override-during-hiberna.patch new file mode 100644 index 0000000..939b031 --- /dev/null +++ b/patches.suse/x86-ACPI-Preserve-ACPI-table-override-during-hiberna.patch @@ -0,0 +1,45 @@ +From: =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= +Date: Tue, 29 Mar 2022 15:33:52 +0200 + +Subject: x86/ACPI: Preserve ACPI-table override during hibernation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Patch-mainline: v5.19-rc1 +Git-commit: 84958f38d897f85b34036356f64e908e4754170f +References: jsc#PED-1408 + +When overriding NHLT ACPI-table tests show that on some platforms +there is problem that NHLT contains garbage after hibernation/resume +cycle. + +Problem stems from the fact that ACPI override performs early memory +allocation using memblock_phys_alloc_range() in +memblock_phys_alloc_range(). This memory block is later being marked as +ACPI memory block in arch_reserve_mem_area(). Later when memory areas +are considered for hibernation it is being marked as nosave in +e820__register_nosave_regions(). + +Fix this by marking ACPI override memory area as ACPI NVS +(Non-Volatile-Sleeping), which according to specification needs to be +saved on entering S4 and restored when leaving and is implemented as +such in kernel. + +Signed-off-by: Amadeusz Sławiński +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + arch/x86/kernel/acpi/boot.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/x86/kernel/acpi/boot.c ++++ b/arch/x86/kernel/acpi/boot.c +@@ -1771,7 +1771,7 @@ int __acpi_release_global_lock(unsigned + + void __init arch_reserve_mem_area(acpi_physical_address addr, size_t size) + { +- e820__range_add(addr, size, E820_TYPE_ACPI); ++ e820__range_add(addr, size, E820_TYPE_NVS); + e820__update_table_print(); + } + diff --git a/patches.suse/x86-Kconfig-Fix-an-unused-variable-error-in-dell-smm.patch b/patches.suse/x86-Kconfig-Fix-an-unused-variable-error-in-dell-smm.patch new file mode 100644 index 0000000..97d821a --- /dev/null +++ b/patches.suse/x86-Kconfig-Fix-an-unused-variable-error-in-dell-smm.patch @@ -0,0 +1,54 @@ +From ef775a0e36c6a81c5b07cb228c02f967133fe768 Mon Sep 17 00:00:00 2001 +From: Randy Dunlap +Date: Fri, 10 Sep 2021 00:19:21 -0700 +Subject: [PATCH] x86/Kconfig: Fix an unused variable error in dell-smm-hwmon +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Git-commit: ef775a0e36c6a81c5b07cb228c02f967133fe768 +References: git-fixes +Patch-mainline: v5.16-rc1 + +When CONFIG_PROC_FS is not set, there is a build warning (turned +into an error): + + ../drivers/hwmon/dell-smm-hwmon.c: In function 'i8k_init_procfs': + ../drivers/hwmon/dell-smm-hwmon.c:624:24: error: unused variable 'data' [-Werror=unused-variable] + struct dell_smm_data *data = dev_get_drvdata(dev); + +Make I8K depend on PROC_FS and HWMON (instead of selecting HWMON -- it +is strongly preferred to not select entire subsystems). + +Build tested in all possible combinations of SENSORS_DELL_SMM, I8K, and +PROC_FS. + +Fixes: 039ae58503f3 ("hwmon: Allow to compile dell-smm-hwmon driver without /proc/i8k") +Reported-by: Arnd Bergmann +Signed-off-by: Randy Dunlap +Signed-off-by: Borislav Petkov +Reviewed-by: Arnd Bergmann +Acked-by: Guenter Roeck +Acked-by: Pali Rohár +Link: https://lkml.kernel.org/r/20210910071921.16777-1-rdunlap@infradead.org +Signed-off-by: Oliver Neukum +--- + arch/x86/Kconfig | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig +index ab83c22d274e..16e216b57863 100644 +--- a/arch/x86/Kconfig ++++ b/arch/x86/Kconfig +@@ -1256,7 +1256,8 @@ config TOSHIBA + + config I8K + tristate "Dell i8k legacy laptop support" +- select HWMON ++ depends on HWMON ++ depends on PROC_FS + select SENSORS_DELL_SMM + help + This option enables legacy /proc/i8k userspace interface in hwmon +-- +2.35.3 + diff --git a/patches.suse/x86-Log-resource-clipping-for-E820-regions.patch b/patches.suse/x86-Log-resource-clipping-for-E820-regions.patch new file mode 100644 index 0000000..cfccd04 --- /dev/null +++ b/patches.suse/x86-Log-resource-clipping-for-E820-regions.patch @@ -0,0 +1,45 @@ +From: Bjorn Helgaas +Date: Thu, 7 Apr 2022 17:42:02 -0500 +Subject: x86: Log resource clipping for E820 regions +Patch-mainline: v5.19-rc1 +Git-commit: 31bf0f4333254469ebf34d7f17d64a57bce516d4 +References: jsc#PED-1408 + +When remove_e820_regions() clips a resource because an E820 region overlaps +it, log a note in dmesg to add in debugging. + +Signed-off-by: Bjorn Helgaas +Acked-by: Lee, Chun-Yi +--- + arch/x86/kernel/resource.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/arch/x86/kernel/resource.c ++++ b/arch/x86/kernel/resource.c +@@ -1,5 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0 + #include ++#include + #include + + static void resource_clip(struct resource *res, resource_size_t start, +@@ -28,6 +29,7 @@ static void remove_e820_regions(struct r + int i; + struct e820_entry *entry; + u64 e820_start, e820_end; ++ struct resource orig = *avail; + + for (i = 0; i < e820_table->nr_entries; i++) { + entry = &e820_table->entries[i]; +@@ -35,6 +37,11 @@ static void remove_e820_regions(struct r + e820_end = entry->addr + entry->size - 1; + + resource_clip(avail, e820_start, e820_end); ++ if (orig.start != avail->start || orig.end != avail->end) { ++ pr_info("clipped %pR to %pR for e820 entry [mem %#010Lx-%#010Lx]\n", ++ &orig, avail, e820_start, e820_end); ++ orig = *avail; ++ } + } + } + diff --git a/patches.suse/x86-PCI-Add-kernel-cmdline-options-to-use-ignore-E82.patch b/patches.suse/x86-PCI-Add-kernel-cmdline-options-to-use-ignore-E82.patch new file mode 100644 index 0000000..e0ef4e5 --- /dev/null +++ b/patches.suse/x86-PCI-Add-kernel-cmdline-options-to-use-ignore-E82.patch @@ -0,0 +1,146 @@ +From: Hans de Goede +Date: Thu, 19 May 2022 17:21:48 +0200 +Subject: x86/PCI: Add kernel cmdline options to use/ignore E820 reserved + regions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Patch-mainline: v5.19-rc1 +Git-commit: fa6dae5d82081e8d9f8e6a2baf7149442a6c1ba5 +References: jsc#PED-1408 + +Some firmware supplies PCI host bridge _CRS that includes address space +unusable by PCI devices, e.g., space occupied by host bridge registers or +used by hidden PCI devices. + +To avoid this unusable space, Linux currently excludes E820 reserved +regions from _CRS windows; see 4dc2287c1805 ("x86: avoid E820 regions when +allocating address space"). + +However, this use of E820 reserved regions to clip things out of _CRS is +not supported by ACPI, UEFI, or PCI Firmware specs, and some systems have +E820 reserved regions that cover the entire memory window from _CRS. +4dc2287c1805 clips the entire window, leaving no space for hot-added or +uninitialized PCI devices. + +For example, from a Lenovo IdeaPad 3 15IIL 81WE: + + BIOS-e820: [mem 0x4bc50000-0xcfffffff] reserved + pci_bus 0000:00: root bus resource [mem 0x65400000-0xbfffffff window] + pci 0000:00:15.0: BAR 0: [mem 0x00000000-0x00000fff 64bit] + pci 0000:00:15.0: BAR 0: no space for [mem size 0x00001000 64bit] + +Future patches will add quirks to enable/disable E820 clipping +automatically. + +Add a "pci=no_e820" kernel command line option to disable clipping with +E820 reserved regions. Also add a matching "pci=use_e820" option to enable +clipping with E820 reserved regions if that has been disabled by default by +further patches in this patch-set. + +Both options taint the kernel because they are intended for debugging and +workaround purposes until a quirk can set them automatically. + +[bhelgaas: commit log, add printk] +Link: https://bugzilla.redhat.com/show_bug.cgi?id=1868899 Lenovo IdeaPad 3 +Link: https://lore.kernel.org/r/20220519152150.6135-2-hdegoede@redhat.com +Signed-off-by: Hans de Goede +Signed-off-by: Bjorn Helgaas +Acked-by: Rafael J. Wysocki +Cc: Benoit Grégoire +Cc: Hui Wang +Acked-by: Lee, Chun-Yi +--- + Documentation/admin-guide/kernel-parameters.txt | 9 +++++++++ + arch/x86/include/asm/pci_x86.h | 2 ++ + arch/x86/pci/acpi.c | 18 ++++++++++++++++-- + arch/x86/pci/common.c | 8 ++++++++ + 4 files changed, 35 insertions(+), 2 deletions(-) + +--- a/Documentation/admin-guide/kernel-parameters.txt ++++ b/Documentation/admin-guide/kernel-parameters.txt +@@ -3932,6 +3932,15 @@ + please report a bug. + nocrs [X86] Ignore PCI host bridge windows from ACPI. + If you need to use this, please report a bug. ++ use_e820 [X86] Use E820 reservations to exclude parts of ++ PCI host bridge windows. This is a workaround ++ for BIOS defects in host bridge _CRS methods. ++ If you need to use this, please report a bug to ++ . ++ no_e820 [X86] Ignore E820 reservations for PCI host ++ bridge windows. This is the default on modern ++ hardware. If you need to use this, please report ++ a bug to . + routeirq Do IRQ routing for all PCI devices. + This is normally done in pci_enable_device(), + so this option is a temporary workaround +--- a/arch/x86/include/asm/pci_x86.h ++++ b/arch/x86/include/asm/pci_x86.h +@@ -39,6 +39,8 @@ do { \ + #define PCI_ROOT_NO_CRS 0x100000 + #define PCI_NOASSIGN_BARS 0x200000 + #define PCI_BIG_ROOT_WINDOW 0x400000 ++#define PCI_USE_E820 0x800000 ++#define PCI_NO_E820 0x1000000 + + extern unsigned int pci_probe; + extern unsigned long pirq_table_addr; +--- a/arch/x86/pci/acpi.c ++++ b/arch/x86/pci/acpi.c +@@ -20,6 +20,7 @@ struct pci_root_info { + #endif + }; + ++static bool pci_use_e820 = true; + static bool pci_use_crs = true; + static bool pci_ignore_seg; + +@@ -161,6 +162,17 @@ void __init pci_acpi_crs_quirks(void) + "if necessary, use \"pci=%s\" and report a bug\n", + pci_use_crs ? "Using" : "Ignoring", + pci_use_crs ? "nocrs" : "use_crs"); ++ ++ /* "pci=use_e820"/"pci=no_e820" on the kernel cmdline takes precedence */ ++ if (pci_probe & PCI_NO_E820) ++ pci_use_e820 = false; ++ else if (pci_probe & PCI_USE_E820) ++ pci_use_e820 = true; ++ ++ printk(KERN_INFO "PCI: %s E820 reservations for host bridge windows\n", ++ pci_use_e820 ? "Using" : "Ignoring"); ++ if (pci_probe & (PCI_NO_E820 | PCI_USE_E820)) ++ printk(KERN_INFO "PCI: Please notify linux-pci@vger.kernel.org so future kernels can this automatically\n"); + } + + #ifdef CONFIG_PCI_MMCONFIG +@@ -301,8 +313,10 @@ static int pci_acpi_root_prepare_resourc + + status = acpi_pci_probe_root_resources(ci); + +- resource_list_for_each_entry(entry, &ci->resources) +- remove_e820_regions(&device->dev, entry->res); ++ if (pci_use_e820) { ++ resource_list_for_each_entry(entry, &ci->resources) ++ remove_e820_regions(&device->dev, entry->res); ++ } + + if (pci_use_crs) { + resource_list_for_each_entry_safe(entry, tmp, &ci->resources) +--- a/arch/x86/pci/common.c ++++ b/arch/x86/pci/common.c +@@ -595,6 +595,14 @@ char *__init pcibios_setup(char *str) + } else if (!strcmp(str, "nocrs")) { + pci_probe |= PCI_ROOT_NO_CRS; + return NULL; ++ } else if (!strcmp(str, "use_e820")) { ++ pci_probe |= PCI_USE_E820; ++ add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); ++ return NULL; ++ } else if (!strcmp(str, "no_e820")) { ++ pci_probe |= PCI_NO_E820; ++ add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); ++ return NULL; + #ifdef CONFIG_PHYS_ADDR_T_64BIT + } else if (!strcmp(str, "big_root_window")) { + pci_probe |= PCI_BIG_ROOT_WINDOW; diff --git a/patches.suse/x86-PCI-Clip-only-host-bridge-windows-for-E820-regio.patch b/patches.suse/x86-PCI-Clip-only-host-bridge-windows-for-E820-regio.patch new file mode 100644 index 0000000..ee085c3 --- /dev/null +++ b/patches.suse/x86-PCI-Clip-only-host-bridge-windows-for-E820-regio.patch @@ -0,0 +1,134 @@ +From: Bjorn Helgaas +Date: Thu, 3 Mar 2022 16:00:39 -0600 +Subject: x86/PCI: Clip only host bridge windows for E820 regions +Patch-mainline: v5.19-rc1 +Git-commit: 4c5e242d3e937bb9f9c226d06888d9189826879d +References: jsc#PED-1408 + +ACPI firmware advertises PCI host bridge resources via PNP0A03 _CRS +methods. Some BIOSes include non-window address space in _CRS, and if we +allocate that non-window space for PCI devices, they don't work. + +4dc2287c1805 ("x86: avoid E820 regions when allocating address space") +works around this issue by clipping out any regions mentioned in the E820 +table in the allocate_resource() path, but the implementation has a couple +issues: + + - The clipping is done for *all* allocations, not just those for PCI + address space, and + + - The clipping is done at each allocation instead of being done once when + setting up the host bridge windows. + +Rework the implementation so we only clip PCI host bridge windows, and we +do it once when setting them up. + +Example output changes: + + BIOS-e820: [mem 0x00000000b0000000-0x00000000c00fffff] reserved + + acpi PNP0A08:00: clipped [mem 0xc0000000-0xfebfffff window] to [mem 0xc0100000-0xfebfffff window] for e820 entry [mem 0xb0000000-0xc00fffff] + - pci_bus 0000:00: root bus resource [mem 0xc0000000-0xfebfffff window] + + pci_bus 0000:00: root bus resource [mem 0xc0100000-0xfebfffff window] + +Link: https://lore.kernel.org/r/20220304035110.988712-3-helgaas@kernel.org +Signed-off-by: Bjorn Helgaas +Reviewed-by: Hans de Goede +Reviewed-by: Mika Westerberg +Acked-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + arch/x86/include/asm/e820/api.h | 5 +++++ + arch/x86/kernel/resource.c | 14 +++++++------- + arch/x86/pci/acpi.c | 5 +++++ + 3 files changed, 17 insertions(+), 7 deletions(-) + +--- a/arch/x86/include/asm/e820/api.h ++++ b/arch/x86/include/asm/e820/api.h +@@ -4,6 +4,9 @@ + + #include + ++struct device; ++struct resource; ++ + extern struct e820_table *e820_table; + extern struct e820_table *e820_table_kexec; + extern struct e820_table *e820_table_firmware; +@@ -43,6 +46,8 @@ extern void e820__register_nosave_region + + extern int e820__get_entry_type(u64 start, u64 end); + ++extern void remove_e820_regions(struct device *dev, struct resource *avail); ++ + /* + * Returns true iff the specified range [start,end) is completely contained inside + * the ISA region. +--- a/arch/x86/kernel/resource.c ++++ b/arch/x86/kernel/resource.c +@@ -1,6 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0 ++#include + #include +-#include + #include + + static void resource_clip(struct resource *res, resource_size_t start, +@@ -24,13 +24,16 @@ static void resource_clip(struct resourc + res->start = end + 1; + } + +-static void remove_e820_regions(struct resource *avail) ++void remove_e820_regions(struct device *dev, struct resource *avail) + { + int i; + struct e820_entry *entry; + u64 e820_start, e820_end; + struct resource orig = *avail; + ++ if (!(avail->flags & IORESOURCE_MEM)) ++ return; ++ + for (i = 0; i < e820_table->nr_entries; i++) { + entry = &e820_table->entries[i]; + e820_start = entry->addr; +@@ -38,7 +41,7 @@ static void remove_e820_regions(struct r + + resource_clip(avail, e820_start, e820_end); + if (orig.start != avail->start || orig.end != avail->end) { +- pr_info("clipped %pR to %pR for e820 entry [mem %#010Lx-%#010Lx]\n", ++ dev_info(dev, "clipped %pR to %pR for e820 entry [mem %#010Lx-%#010Lx]\n", + &orig, avail, e820_start, e820_end); + orig = *avail; + } +@@ -52,9 +55,6 @@ void arch_remove_reservations(struct res + * the low 1MB unconditionally, as this area is needed for some ISA + * cards requiring a memory range, e.g. the i82365 PCMCIA controller. + */ +- if (avail->flags & IORESOURCE_MEM) { ++ if (avail->flags & IORESOURCE_MEM) + resource_clip(avail, BIOS_ROM_BASE, BIOS_ROM_END); +- +- remove_e820_regions(avail); +- } + } +--- a/arch/x86/pci/acpi.c ++++ b/arch/x86/pci/acpi.c +@@ -8,6 +8,7 @@ + #include + #include + #include ++#include + + struct pci_root_info { + struct acpi_pci_root_info common; +@@ -299,6 +300,10 @@ static int pci_acpi_root_prepare_resourc + int status; + + status = acpi_pci_probe_root_resources(ci); ++ ++ resource_list_for_each_entry(entry, &ci->resources) ++ remove_e820_regions(&device->dev, entry->res); ++ + if (pci_use_crs) { + resource_list_for_each_entry_safe(entry, tmp, &ci->resources) + if (resource_is_pcicfg_ioport(entry->res)) diff --git a/patches.suse/x86-PCI-Disable-E820-reserved-region-clipping-starti.patch b/patches.suse/x86-PCI-Disable-E820-reserved-region-clipping-starti.patch new file mode 100644 index 0000000..7ad4f59 --- /dev/null +++ b/patches.suse/x86-PCI-Disable-E820-reserved-region-clipping-starti.patch @@ -0,0 +1,135 @@ +From: Hans de Goede +Date: Thu, 19 May 2022 17:21:50 +0200 +Subject: x86/PCI: Disable E820 reserved region clipping starting in 2023 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Patch-mainline: v5.19-rc1 +Git-commit: 0ae084d5a6744b1318407d8e20fb88ac0fd85d47 +References: jsc#PED-1408 + +Some firmware includes unusable space (host bridge registers, hidden PCI +device BARs, etc) in PCI host bridge _CRS. As far as we know, there's +nothing in the ACPI, UEFI, or PCI Firmware spec that requires the OS to +remove E820 reserved regions from _CRS, so this seems like a firmware +defect. + +As a workaround, 4dc2287c1805 ("x86: avoid E820 regions when allocating +address space") has clipped out the unusable space in the past. This is +required for machines like the following: + + - Dell Precision T3500 (the original motivator for 4dc2287c1805); see + https://bugzilla.kernel.org/show_bug.cgi?id=16228 + + - Asus C523NA (Coral) Chromebook; see + https://lore.kernel.org/all/4e9fca2f-0af1-3684-6c97-4c35befd5019@redhat.com/ + + - Lenovo ThinkPad X1 Gen 2; see: + https://bugzilla.redhat.com/show_bug.cgi?id=2029207 + +But other firmware supplies E820 reserved regions that cover entire _CRS +windows, and clipping throws away the entire window, leaving none for +hot-added or uninitialized devices. This clipping breaks a whole range of +Lenovo IdeaPads, Yogas, Yoga Slims, and notebooks, as well as Acer Spin 5 +and Clevo X170KM-G Barebone machines. + +E820 reserved entries that cover a memory-mapped PCI host bridge, including +its registers and memory/IO windows, are probably *not* a firmware defect. +Per ACPI v5.4, sec 15.2, the E820 memory map may include: + + Address ranges defined for baseboard memory-mapped I/O devices, such as + APICs, are returned as reserved. + +Disable the E820 clipping by default for all post-2022 machines. We +already have quirks to disable clipping for pre-2023 machines, and we'll +likely need quirks to *enable* clipping for post-2022 machines that +incorrectly include unusable space in _CRS, including Chromebooks and +Lenovo ThinkPads. + +Here's the rationale for doing this. If we do nothing, and continue +clipping by default: + + - Future systems like the Lenovo IdeaPads, Yogas, etc, Acer Spin, and + Clevo Barebones will require new quirks to disable clipping. + + - The problem here is E820 entries that cover entire _CRS windows that + should not be clipped out. + + - I think these E820 entries are legal per spec, and it would be hard to + get BIOS vendors to change them. + + - We will discover new systems that need clipping disabled piecemeal as + they are released. + + - Future systems like Lenovo X1 Carbon and the Chromebooks (probably + anything using coreboot) will just work, even though their _CRS is + incorrect, so we will not notice new ones that rely on the clipping. + + - BIOS updates will not require new quirks unless they change the DMI + model string. + +If we add the date check in this commit that disables clipping, e.g., "no +clipping when date >= 2023": + + - Future systems like Lenovo *IIL*, Acer Spin, and Clevo Barebones will + just work without new quirks. + + - Future systems like Lenovo X1 Carbon and the Chromebooks will require + new quirks to *enable* clipping. + + - The problem here is that _CRS contains regions that are not usable by + PCI devices, and we rely on the E820 kludge to clip them out. + + - I think this use of E820 is clearly a firmware bug, so we have a + fighting chance of getting it changed eventually. + + - BIOS updates after the cutoff date *will* require quirks, but only for + systems like Lenovo X1 Carbon and Chromebooks that we already think + have broken firmware. + +It seems to me like it's better to add quirks for firmware that we think is +broken than for firmware that seems unusual but correct. + +[bhelgaas: comment and commit log] +Link: https://lore.kernel.org/linux-pci/20220518220754.GA7911@bhelgaas/ +Link: https://lore.kernel.org/r/20220519152150.6135-4-hdegoede@redhat.com +Signed-off-by: Hans de Goede +Signed-off-by: Bjorn Helgaas +Acked-by: Rafael J. Wysocki +Cc: Benoit Grégoire +Cc: Hui Wang +Acked-by: Lee, Chun-Yi +--- + arch/x86/pci/acpi.c | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +--- a/arch/x86/pci/acpi.c ++++ b/arch/x86/pci/acpi.c +@@ -200,6 +200,27 @@ void __init pci_acpi_crs_quirks(void) + if (year >= 0 && year < 2008 && iomem_resource.end <= 0xffffffff) + pci_use_crs = false; + ++ /* ++ * Some firmware includes unusable space (host bridge registers, ++ * hidden PCI device BARs, etc) in PCI host bridge _CRS. This is a ++ * firmware defect, and 4dc2287c1805 ("x86: avoid E820 regions when ++ * allocating address space") has clipped out the unusable space in ++ * the past. ++ * ++ * But other firmware supplies E820 reserved regions that cover ++ * entire _CRS windows, so clipping throws away the entire window, ++ * leaving none for hot-added or uninitialized devices. These E820 ++ * entries are probably *not* a firmware defect, so disable the ++ * clipping by default for post-2022 machines. ++ * ++ * We already have quirks to disable clipping for pre-2023 ++ * machines, and we'll likely need quirks to *enable* clipping for ++ * post-2022 machines that incorrectly include unusable space in ++ * _CRS. ++ */ ++ if (year >= 2023) ++ pci_use_e820 = false; ++ + dmi_check_system(pci_crs_quirks); + + /* diff --git a/patches.suse/x86-PCI-Disable-E820-reserved-region-clipping-via-qu.patch b/patches.suse/x86-PCI-Disable-E820-reserved-region-clipping-via-qu.patch new file mode 100644 index 0000000..984ba85 --- /dev/null +++ b/patches.suse/x86-PCI-Disable-E820-reserved-region-clipping-via-qu.patch @@ -0,0 +1,154 @@ +From: Hans de Goede +Date: Thu, 19 May 2022 17:21:49 +0200 +Subject: x86/PCI: Disable E820 reserved region clipping via quirks +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Patch-mainline: v5.19-rc1 +Git-commit: d341838d776abadb3ac48abdd2f1f40df5a4fc10 +References: jsc#PED-1408 + +To avoid unusable space that some firmware includes in PCI host bridge +_CRS, Linux currently excludes E820 reserved regions from _CRS windows; see +4dc2287c1805 ("x86: avoid E820 regions when allocating address space"). + +However, some systems supply E820 reserved regions that cover the entire +memory window from _CRS, so clipping them out leaves no space for hot-added +or uninitialized PCI devices. + +For example, from a Lenovo IdeaPad 3 15IIL 81WE: + + BIOS-e820: [mem 0x4bc50000-0xcfffffff] reserved + pci_bus 0000:00: root bus resource [mem 0x65400000-0xbfffffff window] + pci 0000:00:15.0: BAR 0: [mem 0x00000000-0x00000fff 64bit] + pci 0000:00:15.0: BAR 0: no space for [mem size 0x00001000 64bit] + +Add quirks to disable the E820 clipping for machines known to do this. + +A single DMI_PRODUCT_VERSION "IIL" quirk matches all the below: + + Lenovo IdeaPad 3 14IIL05 + Lenovo IdeaPad 3 15IIL05 + Lenovo IdeaPad 3 17IIL05 + Lenovo IdeaPad 5 14IIL05 + Lenovo IdeaPad 5 15IIL05 + Lenovo IdeaPad Slim 7 14IIL05 + Lenovo IdeaPad Slim 7 15IIL05 + Lenovo IdeaPad S145-15IIL + Lenovo IdeaPad S340-14IIL + Lenovo IdeaPad S340-15IIL + Lenovo IdeaPad C340-15IIL + Lenovo BS145-15IIL + Lenovo V14-IIL + Lenovo V15-IIL + Lenovo V17-IIL + Lenovo Yoga C940-14IIL + Lenovo Yoga S740-14IIL + Lenovo Yoga Slim 7 14IIL05 + Lenovo Yoga Slim 7 15IIL05 + +in addition to the following that don't actually need it because they have +no E820 reserved regions that overlap _CRS windows: + + Lenovo IdeaPad Flex 5 14IIL05 + Lenovo IdeaPad Flex 5 15IIL05 + Lenovo ThinkBook 14-IIL + Lenovo ThinkBook 15-IIL + Lenovo Yoga S940-14IIL + +Other quirks match these: + + Acer Spin 5 (SP513-54N) + + Clevo X170KM-G Barebone + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=206459 Lenovo Yoga C940-14IIL +Link: https://bugzilla.kernel.org/show_bug.cgi?id=214259 Clevo X170KM Barebone +Link: https://bugzilla.redhat.com/show_bug.cgi?id=1868899 Lenovo IdeaPad 3 15IIL05 +Link: https://bugzilla.redhat.com/show_bug.cgi?id=1871793 Lenovo IdeaPad 5 14IIL05 +Link: https://bugs.launchpad.net/bugs/1878279 Lenovo IdeaPad 5 14IIL05 +Link: https://bugs.launchpad.net/bugs/1880172 Lenovo IdeaPad 3 14IIL05 +Link: https://bugs.launchpad.net/bugs/1884232 Acer Spin SP513-54N +Link: https://bugs.launchpad.net/bugs/1921649 Lenovo IdeaPad S145 +Link: https://bugs.launchpad.net/bugs/1931715 Lenovo IdeaPad S145 +Link: https://bugs.launchpad.net/bugs/1932069 Lenovo BS145-15IIL +Link: https://lore.kernel.org/r/20220519152150.6135-3-hdegoede@redhat.com +Signed-off-by: Hans de Goede +Signed-off-by: Bjorn Helgaas +Acked-by: Rafael J. Wysocki +Cc: Benoit Grégoire +Cc: Hui Wang +Acked-by: Lee, Chun-Yi +--- + arch/x86/pci/acpi.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 53 insertions(+) + +--- a/arch/x86/pci/acpi.c ++++ b/arch/x86/pci/acpi.c +@@ -43,6 +43,14 @@ static int __init set_ignore_seg(const s + return 0; + } + ++static int __init set_no_e820(const struct dmi_system_id *id) ++{ ++ printk(KERN_INFO "PCI: %s detected: not clipping E820 regions from _CRS\n", ++ id->ident); ++ pci_use_e820 = false; ++ return 0; ++} ++ + static const struct dmi_system_id pci_crs_quirks[] __initconst = { + /* http://bugzilla.kernel.org/show_bug.cgi?id=14183 */ + { +@@ -137,6 +145,51 @@ static const struct dmi_system_id pci_cr + DMI_MATCH(DMI_PRODUCT_NAME, "HP xw9300 Workstation"), + }, + }, ++ ++ /* ++ * Many Lenovo models with "IIL" in their DMI_PRODUCT_VERSION have ++ * an E820 reserved region that covers the entire 32-bit host ++ * bridge memory window from _CRS. Using the E820 region to clip ++ * _CRS means no space is available for hot-added or uninitialized ++ * PCI devices. This typically breaks I2C controllers for touchpads ++ * and hot-added Thunderbolt devices. See the commit log for ++ * models known to require this quirk and related bug reports. ++ */ ++ { ++ .callback = set_no_e820, ++ .ident = "Lenovo *IIL* product version", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "IIL"), ++ }, ++ }, ++ ++ /* ++ * The Acer Spin 5 (SP513-54N) has the same E820 reservation covering ++ * the entire _CRS 32-bit window issue as the Lenovo *IIL* models. ++ * See https://bugs.launchpad.net/bugs/1884232 ++ */ ++ { ++ .callback = set_no_e820, ++ .ident = "Acer Spin 5 (SP513-54N)", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Spin SP513-54N"), ++ }, ++ }, ++ ++ /* ++ * Clevo X170KM-G barebones have the same E820 reservation covering ++ * the entire _CRS 32-bit window issue as the Lenovo *IIL* models. ++ * See https://bugzilla.kernel.org/show_bug.cgi?id=214259 ++ */ ++ { ++ .callback = set_no_e820, ++ .ident = "Clevo X170KM-G Barebone", ++ .matches = { ++ DMI_MATCH(DMI_BOARD_NAME, "X170KM-G"), ++ }, ++ }, + {} + }; + diff --git a/patches.suse/x86-PCI-Eliminate-remove_e820_regions-common-subexpr.patch b/patches.suse/x86-PCI-Eliminate-remove_e820_regions-common-subexpr.patch new file mode 100644 index 0000000..a45fa3b --- /dev/null +++ b/patches.suse/x86-PCI-Eliminate-remove_e820_regions-common-subexpr.patch @@ -0,0 +1,39 @@ +From: Bjorn Helgaas +Date: Thu, 3 Mar 2022 18:04:43 -0600 +Subject: x86/PCI: Eliminate remove_e820_regions() common subexpressions +Patch-mainline: v5.19-rc1 +Git-commit: 93d256cd3c1e93c4093e8015b371e832de4c4146 +References: jsc#PED-1408 + +Add local variables to reduce repetition later. No functional change +intended. + +Link: https://lore.kernel.org/r/20220304035110.988712-2-helgaas@kernel.org +Signed-off-by: Bjorn Helgaas +Reviewed-by: Hans de Goede +Reviewed-by: Mika Westerberg +Acked-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + arch/x86/kernel/resource.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/arch/x86/kernel/resource.c ++++ b/arch/x86/kernel/resource.c +@@ -27,12 +27,14 @@ static void remove_e820_regions(struct r + { + int i; + struct e820_entry *entry; ++ u64 e820_start, e820_end; + + for (i = 0; i < e820_table->nr_entries; i++) { + entry = &e820_table->entries[i]; ++ e820_start = entry->addr; ++ e820_end = entry->addr + entry->size - 1; + +- resource_clip(avail, entry->addr, +- entry->addr + entry->size - 1); ++ resource_clip(avail, e820_start, e820_end); + } + } + diff --git a/patches.suse/x86-PCI-Revert-x86-PCI-Clip-only-host-bridge-windows.patch b/patches.suse/x86-PCI-Revert-x86-PCI-Clip-only-host-bridge-windows.patch new file mode 100644 index 0000000..738d2d8 --- /dev/null +++ b/patches.suse/x86-PCI-Revert-x86-PCI-Clip-only-host-bridge-windows.patch @@ -0,0 +1,192 @@ +From: Hans de Goede +Date: Sun, 12 Jun 2022 16:43:25 +0200 +Subject: x86/PCI: Revert "x86/PCI: Clip only host bridge windows for E820 + regions" +Patch-mainline: v5.19-rc3 +Git-commit: a2b36ffbf5b6ec301e61249c8b09e610bc80772f +References: jsc#PED-1408 + +This reverts commit 4c5e242d3e93. + +Prior to 4c5e242d3e93 ("x86/PCI: Clip only host bridge windows for E820 +regions"), E820 regions did not affect PCI host bridge windows. We only +looked at E820 regions and avoided them when allocating new MMIO space. +If firmware PCI bridge window and BAR assignments used E820 regions, we +left them alone. + +After 4c5e242d3e93, we removed E820 regions from the PCI host bridge +windows before looking at BARs, so firmware assignments in E820 regions +looked like errors, and we moved things around to fit in the space left +(if any) after removing the E820 regions. This unnecessary BAR +reassignment broke several machines. + +Guilherme reported that Steam Deck fails to boot after 4c5e242d3e93. We +clipped the window that contained most 32-bit BARs: + + BIOS-e820: [mem 0x00000000a0000000-0x00000000a00fffff] reserved + acpi PNP0A08:00: clipped [mem 0x80000000-0xf7ffffff window] to [mem 0xa0100000-0xf7ffffff window] for e820 entry [mem 0xa0000000-0xa00fffff] + +which forced us to reassign all those BARs, for example, this NVMe BAR: + + pci 0000:00:01.2: PCI bridge to [bus 01] + pci 0000:00:01.2: bridge window [mem 0x80600000-0x806fffff] + pci 0000:01:00.0: BAR 0: [mem 0x80600000-0x80603fff 64bit] + pci 0000:00:01.2: can't claim window [mem 0x80600000-0x806fffff]: no compatible bridge window + pci 0000:01:00.0: can't claim BAR 0 [mem 0x80600000-0x80603fff 64bit]: no compatible bridge window + + pci 0000:00:01.2: bridge window: assigned [mem 0xa0100000-0xa01fffff] + pci 0000:01:00.0: BAR 0: assigned [mem 0xa0100000-0xa0103fff 64bit] + +All the reassignments were successful, so the devices should have been +functional at the new addresses, but some were not. + +Andy reported a similar failure on an Intel MID platform. Benjamin +reported a similar failure on a VMWare Fusion VM. + +Note: this is not a clean revert; this revert keeps the later change to +make the clipping dependent on a new pci_use_e820 bool, moving the checking +of this bool to arch_remove_reservations(). + +[bhelgaas: commit log, add more reporters and testers] +BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=216109 +Reported-by: Guilherme G. Piccoli +Reported-by: Andy Shevchenko +Reported-by: Benjamin Coddington +Reported-by: Jongman Heo +Fixes: 4c5e242d3e93 ("x86/PCI: Clip only host bridge windows for E820 regions") +Link: https://lore.kernel.org/r/20220612144325.85366-1-hdegoede@redhat.com +Tested-by: Guilherme G. Piccoli +Tested-by: Andy Shevchenko +Tested-by: Benjamin Coddington +Signed-off-by: Hans de Goede +Signed-off-by: Bjorn Helgaas +Acked-by: Lee, Chun-Yi +--- + arch/x86/include/asm/e820/api.h | 5 ----- + arch/x86/include/asm/pci_x86.h | 8 ++++++++ + arch/x86/kernel/resource.c | 14 +++++++++----- + arch/x86/pci/acpi.c | 8 +------- + 4 files changed, 18 insertions(+), 17 deletions(-) + +--- a/arch/x86/include/asm/e820/api.h ++++ b/arch/x86/include/asm/e820/api.h +@@ -4,9 +4,6 @@ + + #include + +-struct device; +-struct resource; +- + extern struct e820_table *e820_table; + extern struct e820_table *e820_table_kexec; + extern struct e820_table *e820_table_firmware; +@@ -46,8 +43,6 @@ extern void e820__register_nosave_region + + extern int e820__get_entry_type(u64 start, u64 end); + +-extern void remove_e820_regions(struct device *dev, struct resource *avail); +- + /* + * Returns true iff the specified range [start,end) is completely contained inside + * the ISA region. +--- a/arch/x86/include/asm/pci_x86.h ++++ b/arch/x86/include/asm/pci_x86.h +@@ -66,6 +66,8 @@ void pcibios_scan_specific_bus(int busn) + + /* pci-irq.c */ + ++struct pci_dev; ++ + struct irq_info { + u8 bus, devfn; /* Bus, device and function */ + struct { +@@ -234,3 +236,9 @@ static inline void mmio_config_writel(vo + # define x86_default_pci_init_irq NULL + # define x86_default_pci_fixup_irqs NULL + #endif ++ ++#if defined(CONFIG_PCI) && defined(CONFIG_ACPI) ++extern bool pci_use_e820; ++#else ++#define pci_use_e820 false ++#endif +--- a/arch/x86/kernel/resource.c ++++ b/arch/x86/kernel/resource.c +@@ -1,7 +1,8 @@ + // SPDX-License-Identifier: GPL-2.0 +-#include + #include ++#include + #include ++#include + + static void resource_clip(struct resource *res, resource_size_t start, + resource_size_t end) +@@ -24,14 +25,14 @@ static void resource_clip(struct resourc + res->start = end + 1; + } + +-void remove_e820_regions(struct device *dev, struct resource *avail) ++static void remove_e820_regions(struct resource *avail) + { + int i; + struct e820_entry *entry; + u64 e820_start, e820_end; + struct resource orig = *avail; + +- if (!(avail->flags & IORESOURCE_MEM)) ++ if (!pci_use_e820) + return; + + for (i = 0; i < e820_table->nr_entries; i++) { +@@ -41,7 +42,7 @@ void remove_e820_regions(struct device * + + resource_clip(avail, e820_start, e820_end); + if (orig.start != avail->start || orig.end != avail->end) { +- dev_info(dev, "clipped %pR to %pR for e820 entry [mem %#010Lx-%#010Lx]\n", ++ pr_info("clipped %pR to %pR for e820 entry [mem %#010Lx-%#010Lx]\n", + &orig, avail, e820_start, e820_end); + orig = *avail; + } +@@ -55,6 +56,9 @@ void arch_remove_reservations(struct res + * the low 1MB unconditionally, as this area is needed for some ISA + * cards requiring a memory range, e.g. the i82365 PCMCIA controller. + */ +- if (avail->flags & IORESOURCE_MEM) ++ if (avail->flags & IORESOURCE_MEM) { + resource_clip(avail, BIOS_ROM_BASE, BIOS_ROM_END); ++ ++ remove_e820_regions(avail); ++ } + } +--- a/arch/x86/pci/acpi.c ++++ b/arch/x86/pci/acpi.c +@@ -8,7 +8,6 @@ + #include + #include + #include +-#include + + struct pci_root_info { + struct acpi_pci_root_info common; +@@ -20,7 +19,7 @@ struct pci_root_info { + #endif + }; + +-static bool pci_use_e820 = true; ++bool pci_use_e820 = true; + static bool pci_use_crs = true; + static bool pci_ignore_seg; + +@@ -387,11 +386,6 @@ static int pci_acpi_root_prepare_resourc + + status = acpi_pci_probe_root_resources(ci); + +- if (pci_use_e820) { +- resource_list_for_each_entry(entry, &ci->resources) +- remove_e820_regions(&device->dev, entry->res); +- } +- + if (pci_use_crs) { + resource_list_for_each_entry_safe(entry, tmp, &ci->resources) + if (resource_is_pcicfg_ioport(entry->res)) diff --git a/patches.suse/x86-boot-Add-Confidential-Computing-type-to-setup_data b/patches.suse/x86-boot-Add-Confidential-Computing-type-to-setup_data new file mode 100644 index 0000000..c1ac30d --- /dev/null +++ b/patches.suse/x86-boot-Add-Confidential-Computing-type-to-setup_data @@ -0,0 +1,90 @@ +From: Brijesh Singh +Date: Mon, 7 Mar 2022 15:33:39 -0600 +Subject: x86/boot: Add Confidential Computing type to setup_data +Git-commit: 5ea98e01ab524cbc53dad8aebd27b434ebe5d074 +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +While launching encrypted guests, the hypervisor may need to provide +some additional information during the guest boot. When booting under an +EFI-based BIOS, the EFI configuration table contains an entry for the +confidential computing blob that contains the required information. + +To support booting encrypted guests on non-EFI VMs, the hypervisor +needs to pass this additional information to the guest kernel using a +different method. + +For this purpose, introduce SETUP_CC_BLOB type in setup_data to hold +the physical address of the confidential computing blob location. The +boot loader or hypervisor may choose to use this method instead of an +EFI configuration table. The CC blob location scanning should give +preference to a setup_data blob over an EFI configuration table. + +In AMD SEV-SNP, the CC blob contains the address of the secrets and +CPUID pages. The secrets page includes information such as a VM to PSP +communication key and the CPUID page contains PSP-filtered CPUID values. +Define the AMD SEV confidential computing blob structure. + +While at it, define the EFI GUID for the confidential computing blob. + + [ bp: Massage commit message, mark struct __packed. ] + +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Acked-by: Ard Biesheuvel +Link: https://lore.kernel.org/r/20220307213356.2797205-30-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/include/asm/sev.h | 18 ++++++++++++++++++ + arch/x86/include/uapi/asm/bootparam.h | 1 + + include/linux/efi.h | 1 + + 3 files changed, 20 insertions(+) + +--- a/arch/x86/include/asm/sev.h ++++ b/arch/x86/include/asm/sev.h +@@ -42,6 +42,24 @@ struct es_em_ctxt { + struct es_fault_info fi; + }; + ++/* ++ * AMD SEV Confidential computing blob structure. The structure is ++ * defined in OVMF UEFI firmware header: ++ * https://github.com/tianocore/edk2/blob/master/OvmfPkg/Include/Guid/ConfidentialComputingSevSnpBlob.h ++ */ ++#define CC_BLOB_SEV_HDR_MAGIC 0x45444d41 ++struct cc_blob_sev_info { ++ u32 magic; ++ u16 version; ++ u16 reserved; ++ u64 secrets_phys; ++ u32 secrets_len; ++ u32 rsvd1; ++ u64 cpuid_phys; ++ u32 cpuid_len; ++ u32 rsvd2; ++} __packed; ++ + void do_vc_no_ghcb(struct pt_regs *regs, unsigned long exit_code); + + static inline u64 lower_bits(u64 val, unsigned int bits) +--- a/arch/x86/include/uapi/asm/bootparam.h ++++ b/arch/x86/include/uapi/asm/bootparam.h +@@ -10,6 +10,7 @@ + #define SETUP_EFI 4 + #define SETUP_APPLE_PROPERTIES 5 + #define SETUP_JAILHOUSE 6 ++#define SETUP_CC_BLOB 7 + + #define SETUP_INDIRECT (1<<31) + +--- a/include/linux/efi.h ++++ b/include/linux/efi.h +@@ -346,6 +346,7 @@ void efi_native_runtime_setup(void); + #define EFI_CERT_SHA256_GUID EFI_GUID(0xc1c41626, 0x504c, 0x4092, 0xac, 0xa9, 0x41, 0xf9, 0x36, 0x93, 0x43, 0x28) + #define EFI_CERT_X509_GUID EFI_GUID(0xa5c059a1, 0x94e4, 0x4aa7, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72) + #define EFI_CERT_X509_SHA256_GUID EFI_GUID(0x3bd2a492, 0x96c0, 0x4079, 0xb4, 0x20, 0xfc, 0xf9, 0x8e, 0xf1, 0x03, 0xed) ++#define EFI_CC_BLOB_GUID EFI_GUID(0x067b1f5f, 0xcf26, 0x44c5, 0x85, 0x54, 0x93, 0xd7, 0x77, 0x91, 0x2d, 0x42) + + /* + * This GUID is used to pass to the kernel proper the struct screen_info diff --git a/patches.suse/x86-boot-Add-a-pointer-to-Confidential-Computing-blob-in-bootpar b/patches.suse/x86-boot-Add-a-pointer-to-Confidential-Computing-blob-in-bootpar new file mode 100644 index 0000000..5599756 --- /dev/null +++ b/patches.suse/x86-boot-Add-a-pointer-to-Confidential-Computing-blob-in-bootpar @@ -0,0 +1,90 @@ +From: Michael Roth +Date: Thu, 24 Feb 2022 10:56:13 -0600 +Subject: x86/boot: Add a pointer to Confidential Computing blob in bootparams +Git-commit: 8c9c509baf660f1062bc758c26008b7f9bbc39f3 +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +The previously defined Confidential Computing blob is provided to the +kernel via a setup_data structure or EFI config table entry. Currently, +these are both checked for by boot/compressed kernel to access the CPUID +table address within it for use with SEV-SNP CPUID enforcement. + +To also enable that enforcement for the run-time kernel, similar +access to the CPUID table is needed early on while it's still using +the identity-mapped page table set up by boot/compressed, where global +pointers need to be accessed via fixup_pointer(). + +This isn't much of an issue for accessing setup_data, and the EFI config +table helper code currently used in boot/compressed *could* be used in +this case as well since they both rely on identity-mapping. However, it +has some reliance on EFI helpers/string constants that would need to be +accessed via fixup_pointer(), and fixing it up while making it shareable +between boot/compressed and run-time kernel is fragile and introduces a +good bit of ugliness. + +Instead, add a boot_params->cc_blob_address pointer that the +boot/compressed kernel can initialize so that the run-time kernel can +access the CC blob from there instead of re-scanning the EFI config +table. + +Also document these in Documentation/x86/zero-page.rst. While there, +add missing documentation for the acpi_rsdp_addr field, which serves a +similar purpose in providing the run-time kernel a pointer to the ACPI +RSDP table so that it does not need to [re-]scan the EFI configuration +table. + + [ bp: Fix typos, massage commit message. ] + +Signed-off-by: Michael Roth +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220307213356.2797205-34-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + Documentation/x86/zero-page.rst | 2 ++ + arch/x86/include/asm/bootparam_utils.h | 1 + + arch/x86/include/uapi/asm/bootparam.h | 3 ++- + 3 files changed, 5 insertions(+), 1 deletion(-) + +--- a/Documentation/x86/zero-page.rst ++++ b/Documentation/x86/zero-page.rst +@@ -19,6 +19,7 @@ Offset/Size Proto Name Meaning + 058/008 ALL tboot_addr Physical address of tboot shared page + 060/010 ALL ist_info Intel SpeedStep (IST) BIOS support information + (struct ist_info) ++070/008 ALL acpi_rsdp_addr Physical address of ACPI RSDP table + 080/010 ALL hd0_info hd0 disk parameter, OBSOLETE!! + 090/010 ALL hd1_info hd1 disk parameter, OBSOLETE!! + 0A0/010 ALL sys_desc_table System description table (struct sys_desc_table), +@@ -27,6 +28,7 @@ Offset/Size Proto Name Meaning + 0C0/004 ALL ext_ramdisk_image ramdisk_image high 32bits + 0C4/004 ALL ext_ramdisk_size ramdisk_size high 32bits + 0C8/004 ALL ext_cmd_line_ptr cmd_line_ptr high 32bits ++13C/004 ALL cc_blob_address Physical address of Confidential Computing blob + 140/080 ALL edid_info Video mode setup (struct edid_info) + 1C0/020 ALL efi_info EFI 32 information (struct efi_info) + 1E0/004 ALL alt_mem_k Alternative mem check, in KB +--- a/arch/x86/include/asm/bootparam_utils.h ++++ b/arch/x86/include/asm/bootparam_utils.h +@@ -74,6 +74,7 @@ static void sanitize_boot_params(struct + BOOT_PARAM_PRESERVE(hdr), + BOOT_PARAM_PRESERVE(e820_table), + BOOT_PARAM_PRESERVE(eddbuf), ++ BOOT_PARAM_PRESERVE(cc_blob_address), + }; + + memset(&scratch, 0, sizeof(scratch)); +--- a/arch/x86/include/uapi/asm/bootparam.h ++++ b/arch/x86/include/uapi/asm/bootparam.h +@@ -188,7 +188,8 @@ struct boot_params { + __u32 ext_ramdisk_image; /* 0x0c0 */ + __u32 ext_ramdisk_size; /* 0x0c4 */ + __u32 ext_cmd_line_ptr; /* 0x0c8 */ +- __u8 _pad4[116]; /* 0x0cc */ ++ __u8 _pad4[112]; /* 0x0cc */ ++ __u32 cc_blob_address; /* 0x13c */ + struct edid_info edid_info; /* 0x140 */ + struct efi_info efi_info; /* 0x1c0 */ + __u32 alt_mem_k; /* 0x1e0 */ diff --git a/patches.suse/x86-boot-Introduce-helpers-for-MSR-reads-writes b/patches.suse/x86-boot-Introduce-helpers-for-MSR-reads-writes new file mode 100644 index 0000000..fbc5364 --- /dev/null +++ b/patches.suse/x86-boot-Introduce-helpers-for-MSR-reads-writes @@ -0,0 +1,100 @@ +From: Michael Roth +Date: Wed, 9 Feb 2022 12:09:59 -0600 +Subject: x86/boot: Introduce helpers for MSR reads/writes +Git-commit: 176db622573f028f85221873ea4577e096785315 +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +The current set of helpers used throughout the run-time kernel have +dependencies on code/facilities outside of the boot kernel, so there +are a number of call-sites throughout the boot kernel where inline +assembly is used instead. More will be added with subsequent patches +that add support for SEV-SNP, so take the opportunity to provide a basic +set of helpers that can be used by the boot kernel to reduce reliance on +inline assembly. + +Use boot_* prefix so that it's clear these are helpers specific to the +boot kernel to avoid any confusion with the various other MSR read/write +helpers. + + [ bp: Disambiguate parameter names and trim comment. ] + +Suggested-by: Borislav Petkov +Signed-off-by: Michael Roth +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220307213356.2797205-6-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/boot/msr.h | 26 ++++++++++++++++++++++++++ + arch/x86/include/asm/msr.h | 11 +---------- + arch/x86/include/asm/shared/msr.h | 15 +++++++++++++++ + 3 files changed, 42 insertions(+), 10 deletions(-) + +--- /dev/null ++++ b/arch/x86/boot/msr.h +@@ -0,0 +1,26 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * Helpers/definitions related to MSR access. ++ */ ++ ++#ifndef BOOT_MSR_H ++#define BOOT_MSR_H ++ ++#include ++ ++/* ++ * The kernel proper already defines rdmsr()/wrmsr(), but they are not for the ++ * boot kernel since they rely on tracepoint/exception handling infrastructure ++ * that's not available here. ++ */ ++static inline void boot_rdmsr(unsigned int reg, struct msr *m) ++{ ++ asm volatile("rdmsr" : "=a" (m->l), "=d" (m->h) : "c" (reg)); ++} ++ ++static inline void boot_wrmsr(unsigned int reg, const struct msr *m) ++{ ++ asm volatile("wrmsr" : : "c" (reg), "a"(m->l), "d" (m->h) : "memory"); ++} ++ ++#endif /* BOOT_MSR_H */ +--- a/arch/x86/include/asm/msr.h ++++ b/arch/x86/include/asm/msr.h +@@ -10,16 +10,7 @@ + #include + #include + #include +- +-struct msr { +- union { +- struct { +- u32 l; +- u32 h; +- }; +- u64 q; +- }; +-}; ++#include + + struct msr_info { + u32 msr_no; +--- /dev/null ++++ b/arch/x86/include/asm/shared/msr.h +@@ -0,0 +1,15 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++#ifndef _ASM_X86_SHARED_MSR_H ++#define _ASM_X86_SHARED_MSR_H ++ ++struct msr { ++ union { ++ struct { ++ u32 l; ++ u32 h; ++ }; ++ u64 q; ++ }; ++}; ++ ++#endif /* _ASM_X86_SHARED_MSR_H */ diff --git a/patches.suse/x86-boot-Put-globals-that-are-accessed-early-into-the-.data-sect b/patches.suse/x86-boot-Put-globals-that-are-accessed-early-into-the-.data-sect new file mode 100644 index 0000000..ebb2eaf --- /dev/null +++ b/patches.suse/x86-boot-Put-globals-that-are-accessed-early-into-the-.data-sect @@ -0,0 +1,58 @@ +From: Michael Roth +Date: Wed, 20 Apr 2022 10:26:13 -0500 +Subject: x86/boot: Put globals that are accessed early into the .data section +Git-commit: 6044d159b5d826259a7397d42fa3ad0bfc4dbd13 +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +The helpers in arch/x86/boot/compressed/efi.c might be used during +early boot to access the EFI system/config tables, and in some cases +these EFI helpers might attempt to print debug/error messages, before +console_init() has been called. + +__putstr() checks some variables to avoid printing anything before +the console has been initialized, but this isn't enough since those +variables live in .bss, which may not have been cleared yet. This can +lead to a triple-fault occurring, primarily when booting in legacy/CSM +mode (where EFI helpers will attempt to print some debug messages). + +Fix this by declaring these globals in .data section instead so there +is no dependency on .bss being cleared before accessing them. + +Fixes: c01fce9cef849 ("x86/compressed: Add SEV-SNP feature detection/setup") +Reported-by: Borislav Petkov +Suggested-by: Thomas Lendacky +Signed-off-by: Michael Roth +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220420152613.145077-1-michael.roth@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/boot/compressed/early_serial_console.c | 3 ++- + arch/x86/boot/compressed/misc.c | 5 ++++- + 2 files changed, 6 insertions(+), 2 deletions(-) + +--- a/arch/x86/boot/compressed/early_serial_console.c ++++ b/arch/x86/boot/compressed/early_serial_console.c +@@ -1,5 +1,6 @@ + #include "misc.h" + +-int early_serial_base; ++/* This might be accessed before .bss is cleared, so use .data instead. */ ++int early_serial_base __section(".data"); + + #include "../early_serial_console.c" +--- a/arch/x86/boot/compressed/misc.c ++++ b/arch/x86/boot/compressed/misc.c +@@ -49,7 +49,10 @@ memptr free_mem_end_ptr; + + static char *vidmem; + static int vidport; +-static int lines, cols; ++ ++/* These might be accessed before .bss is cleared, so use .data instead. */ ++static int lines __section(".data"); ++static int cols __section(".data"); + + #ifdef CONFIG_KERNEL_GZIP + #include "../../../../lib/decompress_inflate.c" diff --git a/patches.suse/x86-boot-Use-MSR-read-write-helpers-instead-of-inline-assembly b/patches.suse/x86-boot-Use-MSR-read-write-helpers-instead-of-inline-assembly new file mode 100644 index 0000000..05e4de2 --- /dev/null +++ b/patches.suse/x86-boot-Use-MSR-read-write-helpers-instead-of-inline-assembly @@ -0,0 +1,127 @@ +From: Michael Roth +Date: Wed, 9 Feb 2022 12:10:00 -0600 +Subject: x86/boot: Use MSR read/write helpers instead of inline assembly +Git-commit: 950d00558a920227b5703d1fcc4751cfe03853cd +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +Update all C code to use the new boot_rdmsr()/boot_wrmsr() helpers +instead of relying on inline assembly. + +Suggested-by: Borislav Petkov +Signed-off-by: Michael Roth +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220307213356.2797205-7-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/boot/compressed/sev.c | 17 +++++++---------- + arch/x86/boot/cpucheck.c | 30 +++++++++++++++--------------- + 2 files changed, 22 insertions(+), 25 deletions(-) + +--- a/arch/x86/boot/compressed/sev.c ++++ b/arch/x86/boot/compressed/sev.c +@@ -22,6 +22,7 @@ + #include + + #include "error.h" ++#include "../msr.h" + + struct ghcb boot_ghcb_page __aligned(PAGE_SIZE); + struct ghcb *boot_ghcb; +@@ -56,23 +57,19 @@ static unsigned long insn_get_seg_base(s + + static inline u64 sev_es_rd_ghcb_msr(void) + { +- unsigned long low, high; ++ struct msr m; + +- asm volatile("rdmsr" : "=a" (low), "=d" (high) : +- "c" (MSR_AMD64_SEV_ES_GHCB)); ++ boot_rdmsr(MSR_AMD64_SEV_ES_GHCB, &m); + +- return ((high << 32) | low); ++ return m.q; + } + + static inline void sev_es_wr_ghcb_msr(u64 val) + { +- u32 low, high; ++ struct msr m; + +- low = val & 0xffffffffUL; +- high = val >> 32; +- +- asm volatile("wrmsr" : : "c" (MSR_AMD64_SEV_ES_GHCB), +- "a"(low), "d" (high) : "memory"); ++ m.q = val; ++ boot_wrmsr(MSR_AMD64_SEV_ES_GHCB, &m); + } + + static enum es_result vc_decode_insn(struct es_em_ctxt *ctxt) +--- a/arch/x86/boot/cpucheck.c ++++ b/arch/x86/boot/cpucheck.c +@@ -27,6 +27,7 @@ + #include + #include + #include "string.h" ++#include "msr.h" + + static u32 err_flags[NCAPINTS]; + +@@ -130,12 +131,11 @@ int check_cpu(int *cpu_level_ptr, int *r + /* If this is an AMD and we're only missing SSE+SSE2, try to + turn them on */ + +- u32 ecx = MSR_K7_HWCR; +- u32 eax, edx; ++ struct msr m; + +- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx)); +- eax &= ~(1 << 15); +- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx)); ++ boot_rdmsr(MSR_K7_HWCR, &m); ++ m.l &= ~(1 << 15); ++ boot_wrmsr(MSR_K7_HWCR, &m); + + get_cpuflags(); /* Make sure it really did something */ + err = check_cpuflags(); +@@ -145,28 +145,28 @@ int check_cpu(int *cpu_level_ptr, int *r + /* If this is a VIA C3, we might have to enable CX8 + explicitly */ + +- u32 ecx = MSR_VIA_FCR; +- u32 eax, edx; ++ struct msr m; + +- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx)); +- eax |= (1<<1)|(1<<7); +- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx)); ++ boot_rdmsr(MSR_VIA_FCR, &m); ++ m.l |= (1 << 1) | (1 << 7); ++ boot_wrmsr(MSR_VIA_FCR, &m); + + set_bit(X86_FEATURE_CX8, cpu.flags); + err = check_cpuflags(); + } else if (err == 0x01 && is_transmeta()) { + /* Transmeta might have masked feature bits in word 0 */ + +- u32 ecx = 0x80860004; +- u32 eax, edx; ++ struct msr m, m_tmp; + u32 level = 1; + +- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx)); +- asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx)); ++ boot_rdmsr(0x80860004, &m); ++ m_tmp = m; ++ m_tmp.l = ~0; ++ boot_wrmsr(0x80860004, &m_tmp); + asm("cpuid" + : "+a" (level), "=d" (cpu.flags[0]) + : : "ecx", "ebx"); +- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx)); ++ boot_wrmsr(0x80860004, &m); + + err = check_cpuflags(); + } else if (err == 0x01 && diff --git a/patches.suse/x86-compressed-64-Add-identity-mapping-for-Confidential-Computin b/patches.suse/x86-compressed-64-Add-identity-mapping-for-Confidential-Computin new file mode 100644 index 0000000..c07db2f --- /dev/null +++ b/patches.suse/x86-compressed-64-Add-identity-mapping-for-Confidential-Computin @@ -0,0 +1,86 @@ +From: Michael Roth +Date: Thu, 24 Feb 2022 10:56:17 -0600 +Subject: x86/compressed/64: Add identity mapping for Confidential Computing + blob +Git-commit: 76f61e1e89b32f3e5d639f1b57413a919066da06 +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +The run-time kernel will need to access the Confidential Computing blob +very early during boot to access the CPUID table it points to. At that +stage, it will be relying on the identity-mapped page table set up by +the boot/compressed kernel, so make sure the blob and the CPUID table it +points to are mapped in advance. + + [ bp: Massage. ] + +Signed-off-by: Michael Roth +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220307213356.2797205-38-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/boot/compressed/ident_map_64.c | 3 ++- + arch/x86/boot/compressed/misc.h | 2 ++ + arch/x86/boot/compressed/sev.c | 21 +++++++++++++++++++++ + 3 files changed, 25 insertions(+), 1 deletion(-) + +--- a/arch/x86/boot/compressed/ident_map_64.c ++++ b/arch/x86/boot/compressed/ident_map_64.c +@@ -163,8 +163,9 @@ void initialize_identity_maps(void *rmod + cmdline = get_cmd_line_ptr(); + kernel_add_identity_map(cmdline, cmdline + COMMAND_LINE_SIZE); + ++ sev_prep_identity_maps(top_level_pgt); ++ + /* Load the new page-table. */ +- sev_verify_cbit(top_level_pgt); + write_cr3(top_level_pgt); + } + +--- a/arch/x86/boot/compressed/misc.h ++++ b/arch/x86/boot/compressed/misc.h +@@ -123,6 +123,7 @@ void sev_es_shutdown_ghcb(void); + extern bool sev_es_check_ghcb_fault(unsigned long address); + void snp_set_page_private(unsigned long paddr); + void snp_set_page_shared(unsigned long paddr); ++void sev_prep_identity_maps(unsigned long top_level_pgt); + #else + static inline void sev_enable(struct boot_params *bp) { } + static inline void sev_es_shutdown_ghcb(void) { } +@@ -132,6 +133,7 @@ static inline bool sev_es_check_ghcb_fau + } + static inline void snp_set_page_private(unsigned long paddr) { } + static inline void snp_set_page_shared(unsigned long paddr) { } ++static inline void sev_prep_identity_maps(unsigned long top_level_pgt) { } + #endif + + /* acpi.c */ +--- a/arch/x86/boot/compressed/sev.c ++++ b/arch/x86/boot/compressed/sev.c +@@ -478,3 +478,24 @@ bool snp_init(struct boot_params *bp) + + return true; + } ++ ++void sev_prep_identity_maps(unsigned long top_level_pgt) ++{ ++ /* ++ * The Confidential Computing blob is used very early in uncompressed ++ * kernel to find the in-memory CPUID table to handle CPUID ++ * instructions. Make sure an identity-mapping exists so it can be ++ * accessed after switchover. ++ */ ++ if (sev_snp_enabled()) { ++ unsigned long cc_info_pa = boot_params->cc_blob_address; ++ struct cc_blob_sev_info *cc_info; ++ ++ kernel_add_identity_map(cc_info_pa, cc_info_pa + sizeof(*cc_info)); ++ ++ cc_info = (struct cc_blob_sev_info *)cc_info_pa; ++ kernel_add_identity_map(cc_info->cpuid_phys, cc_info->cpuid_phys + cc_info->cpuid_len); ++ } ++ ++ sev_verify_cbit(top_level_pgt); ++} diff --git a/patches.suse/x86-compressed-64-Add-support-for-SEV-SNP-CPUID-table-in-VC-hand b/patches.suse/x86-compressed-64-Add-support-for-SEV-SNP-CPUID-table-in-VC-hand new file mode 100644 index 0000000..5ca000c --- /dev/null +++ b/patches.suse/x86-compressed-64-Add-support-for-SEV-SNP-CPUID-table-in-VC-hand @@ -0,0 +1,417 @@ +From: Michael Roth +Date: Thu, 24 Feb 2022 10:56:12 -0600 +Subject: x86/compressed/64: Add support for SEV-SNP CPUID table in #VC + handlers +Git-commit: ee0bfa08a345370df28c07288e886abcbaac481f +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +CPUID instructions generate a #VC exception for SEV-ES/SEV-SNP guests, +for which early handlers are currently set up to handle. In the case +of SEV-SNP, guests can use a configurable location in guest memory +that has been pre-populated with a firmware-validated CPUID table to +look up the relevant CPUID values rather than requesting them from +hypervisor via a VMGEXIT. Add the various hooks in the #VC handlers to +allow CPUID instructions to be handled via the table. The code to +actually configure/enable the table will be added in a subsequent +commit. + +Signed-off-by: Michael Roth +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220307213356.2797205-33-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/include/asm/sev-common.h | 2 + arch/x86/kernel/sev-shared.c | 324 ++++++++++++++++++++++++++++++++++++++ + 2 files changed, 326 insertions(+) + +--- a/arch/x86/include/asm/sev-common.h ++++ b/arch/x86/include/asm/sev-common.h +@@ -152,6 +152,8 @@ struct snp_psc_desc { + #define GHCB_TERM_PSC 1 /* Page State Change failure */ + #define GHCB_TERM_PVALIDATE 2 /* Pvalidate failure */ + #define GHCB_TERM_NOT_VMPL0 3 /* SNP guest is not running at VMPL-0 */ ++#define GHCB_TERM_CPUID 4 /* CPUID-validation failure */ ++#define GHCB_TERM_CPUID_HV 5 /* CPUID failure during hypervisor fallback */ + + #define GHCB_RESP_CODE(v) ((v) & GHCB_MSR_INFO_MASK) + +--- a/arch/x86/kernel/sev-shared.c ++++ b/arch/x86/kernel/sev-shared.c +@@ -25,6 +25,36 @@ struct cpuid_leaf { + }; + + /* ++ * Individual entries of the SNP CPUID table, as defined by the SNP ++ * Firmware ABI, Revision 0.9, Section 7.1, Table 14. ++ */ ++struct snp_cpuid_fn { ++ u32 eax_in; ++ u32 ecx_in; ++ u64 xcr0_in; ++ u64 xss_in; ++ u32 eax; ++ u32 ebx; ++ u32 ecx; ++ u32 edx; ++ u64 __reserved; ++} __packed; ++ ++/* ++ * SNP CPUID table, as defined by the SNP Firmware ABI, Revision 0.9, ++ * Section 8.14.2.6. Also noted there is the SNP firmware-enforced limit ++ * of 64 entries per CPUID table. ++ */ ++#define SNP_CPUID_COUNT_MAX 64 ++ ++struct snp_cpuid_table { ++ u32 count; ++ u32 __reserved1; ++ u64 __reserved2; ++ struct snp_cpuid_fn fn[SNP_CPUID_COUNT_MAX]; ++} __packed; ++ ++/* + * Since feature negotiation related variables are set early in the boot + * process they must reside in the .data section so as not to be zeroed + * out when the .bss section is later cleared. +@@ -33,6 +63,19 @@ struct cpuid_leaf { + */ + static u16 ghcb_version __ro_after_init; + ++/* Copy of the SNP firmware's CPUID page. */ ++static struct snp_cpuid_table cpuid_table_copy __ro_after_init; ++ ++/* ++ * These will be initialized based on CPUID table so that non-present ++ * all-zero leaves (for sparse tables) can be differentiated from ++ * invalid/out-of-range leaves. This is needed since all-zero leaves ++ * still need to be post-processed. ++ */ ++static u32 cpuid_std_range_max __ro_after_init; ++static u32 cpuid_hyp_range_max __ro_after_init; ++static u32 cpuid_ext_range_max __ro_after_init; ++ + static bool __init sev_es_check_cpu_features(void) + { + if (!has_cpuflag(X86_FEATURE_RDRAND)) { +@@ -243,6 +286,252 @@ static int sev_cpuid_hv(struct cpuid_lea + } + + /* ++ * This may be called early while still running on the initial identity ++ * mapping. Use RIP-relative addressing to obtain the correct address ++ * while running with the initial identity mapping as well as the ++ * switch-over to kernel virtual addresses later. ++ */ ++static const struct snp_cpuid_table *snp_cpuid_get_table(void) ++{ ++ void *ptr; ++ ++ asm ("lea cpuid_table_copy(%%rip), %0" ++ : "=r" (ptr) ++ : "p" (&cpuid_table_copy)); ++ ++ return ptr; ++} ++ ++/* ++ * The SNP Firmware ABI, Revision 0.9, Section 7.1, details the use of ++ * XCR0_IN and XSS_IN to encode multiple versions of 0xD subfunctions 0 ++ * and 1 based on the corresponding features enabled by a particular ++ * combination of XCR0 and XSS registers so that a guest can look up the ++ * version corresponding to the features currently enabled in its XCR0/XSS ++ * registers. The only values that differ between these versions/table ++ * entries is the enabled XSAVE area size advertised via EBX. ++ * ++ * While hypervisors may choose to make use of this support, it is more ++ * robust/secure for a guest to simply find the entry corresponding to the ++ * base/legacy XSAVE area size (XCR0=1 or XCR0=3), and then calculate the ++ * XSAVE area size using subfunctions 2 through 64, as documented in APM ++ * Volume 3, Rev 3.31, Appendix E.3.8, which is what is done here. ++ * ++ * Since base/legacy XSAVE area size is documented as 0x240, use that value ++ * directly rather than relying on the base size in the CPUID table. ++ * ++ * Return: XSAVE area size on success, 0 otherwise. ++ */ ++static u32 snp_cpuid_calc_xsave_size(u64 xfeatures_en, bool compacted) ++{ ++ const struct snp_cpuid_table *cpuid_table = snp_cpuid_get_table(); ++ u64 xfeatures_found = 0; ++ u32 xsave_size = 0x240; ++ int i; ++ ++ for (i = 0; i < cpuid_table->count; i++) { ++ const struct snp_cpuid_fn *e = &cpuid_table->fn[i]; ++ ++ if (!(e->eax_in == 0xD && e->ecx_in > 1 && e->ecx_in < 64)) ++ continue; ++ if (!(xfeatures_en & (BIT_ULL(e->ecx_in)))) ++ continue; ++ if (xfeatures_found & (BIT_ULL(e->ecx_in))) ++ continue; ++ ++ xfeatures_found |= (BIT_ULL(e->ecx_in)); ++ ++ if (compacted) ++ xsave_size += e->eax; ++ else ++ xsave_size = max(xsave_size, e->eax + e->ebx); ++ } ++ ++ /* ++ * Either the guest set unsupported XCR0/XSS bits, or the corresponding ++ * entries in the CPUID table were not present. This is not a valid ++ * state to be in. ++ */ ++ if (xfeatures_found != (xfeatures_en & GENMASK_ULL(63, 2))) ++ return 0; ++ ++ return xsave_size; ++} ++ ++static bool ++snp_cpuid_get_validated_func(struct cpuid_leaf *leaf) ++{ ++ const struct snp_cpuid_table *cpuid_table = snp_cpuid_get_table(); ++ int i; ++ ++ for (i = 0; i < cpuid_table->count; i++) { ++ const struct snp_cpuid_fn *e = &cpuid_table->fn[i]; ++ ++ if (e->eax_in != leaf->fn) ++ continue; ++ ++ if (cpuid_function_is_indexed(leaf->fn) && e->ecx_in != leaf->subfn) ++ continue; ++ ++ /* ++ * For 0xD subfunctions 0 and 1, only use the entry corresponding ++ * to the base/legacy XSAVE area size (XCR0=1 or XCR0=3, XSS=0). ++ * See the comments above snp_cpuid_calc_xsave_size() for more ++ * details. ++ */ ++ if (e->eax_in == 0xD && (e->ecx_in == 0 || e->ecx_in == 1)) ++ if (!(e->xcr0_in == 1 || e->xcr0_in == 3) || e->xss_in) ++ continue; ++ ++ leaf->eax = e->eax; ++ leaf->ebx = e->ebx; ++ leaf->ecx = e->ecx; ++ leaf->edx = e->edx; ++ ++ return true; ++ } ++ ++ return false; ++} ++ ++static void snp_cpuid_hv(struct cpuid_leaf *leaf) ++{ ++ if (sev_cpuid_hv(leaf)) ++ sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_CPUID_HV); ++} ++ ++static int snp_cpuid_postprocess(struct cpuid_leaf *leaf) ++{ ++ struct cpuid_leaf leaf_hv = *leaf; ++ ++ switch (leaf->fn) { ++ case 0x1: ++ snp_cpuid_hv(&leaf_hv); ++ ++ /* initial APIC ID */ ++ leaf->ebx = (leaf_hv.ebx & GENMASK(31, 24)) | (leaf->ebx & GENMASK(23, 0)); ++ /* APIC enabled bit */ ++ leaf->edx = (leaf_hv.edx & BIT(9)) | (leaf->edx & ~BIT(9)); ++ ++ /* OSXSAVE enabled bit */ ++ if (native_read_cr4() & X86_CR4_OSXSAVE) ++ leaf->ecx |= BIT(27); ++ break; ++ case 0x7: ++ /* OSPKE enabled bit */ ++ leaf->ecx &= ~BIT(4); ++ if (native_read_cr4() & X86_CR4_PKE) ++ leaf->ecx |= BIT(4); ++ break; ++ case 0xB: ++ leaf_hv.subfn = 0; ++ snp_cpuid_hv(&leaf_hv); ++ ++ /* extended APIC ID */ ++ leaf->edx = leaf_hv.edx; ++ break; ++ case 0xD: { ++ bool compacted = false; ++ u64 xcr0 = 1, xss = 0; ++ u32 xsave_size; ++ ++ if (leaf->subfn != 0 && leaf->subfn != 1) ++ return 0; ++ ++ if (native_read_cr4() & X86_CR4_OSXSAVE) ++ xcr0 = xgetbv(XCR_XFEATURE_ENABLED_MASK); ++ if (leaf->subfn == 1) { ++ /* Get XSS value if XSAVES is enabled. */ ++ if (leaf->eax & BIT(3)) { ++ unsigned long lo, hi; ++ ++ asm volatile("rdmsr" : "=a" (lo), "=d" (hi) ++ : "c" (MSR_IA32_XSS)); ++ xss = (hi << 32) | lo; ++ } ++ ++ /* ++ * The PPR and APM aren't clear on what size should be ++ * encoded in 0xD:0x1:EBX when compaction is not enabled ++ * by either XSAVEC (feature bit 1) or XSAVES (feature ++ * bit 3) since SNP-capable hardware has these feature ++ * bits fixed as 1. KVM sets it to 0 in this case, but ++ * to avoid this becoming an issue it's safer to simply ++ * treat this as unsupported for SNP guests. ++ */ ++ if (!(leaf->eax & (BIT(1) | BIT(3)))) ++ return -EINVAL; ++ ++ compacted = true; ++ } ++ ++ xsave_size = snp_cpuid_calc_xsave_size(xcr0 | xss, compacted); ++ if (!xsave_size) ++ return -EINVAL; ++ ++ leaf->ebx = xsave_size; ++ } ++ break; ++ case 0x8000001E: ++ snp_cpuid_hv(&leaf_hv); ++ ++ /* extended APIC ID */ ++ leaf->eax = leaf_hv.eax; ++ /* compute ID */ ++ leaf->ebx = (leaf->ebx & GENMASK(31, 8)) | (leaf_hv.ebx & GENMASK(7, 0)); ++ /* node ID */ ++ leaf->ecx = (leaf->ecx & GENMASK(31, 8)) | (leaf_hv.ecx & GENMASK(7, 0)); ++ break; ++ default: ++ /* No fix-ups needed, use values as-is. */ ++ break; ++ } ++ ++ return 0; ++} ++ ++/* ++ * Returns -EOPNOTSUPP if feature not enabled. Any other non-zero return value ++ * should be treated as fatal by caller. ++ */ ++static int snp_cpuid(struct cpuid_leaf *leaf) ++{ ++ const struct snp_cpuid_table *cpuid_table = snp_cpuid_get_table(); ++ ++ if (!cpuid_table->count) ++ return -EOPNOTSUPP; ++ ++ if (!snp_cpuid_get_validated_func(leaf)) { ++ /* ++ * Some hypervisors will avoid keeping track of CPUID entries ++ * where all values are zero, since they can be handled the ++ * same as out-of-range values (all-zero). This is useful here ++ * as well as it allows virtually all guest configurations to ++ * work using a single SNP CPUID table. ++ * ++ * To allow for this, there is a need to distinguish between ++ * out-of-range entries and in-range zero entries, since the ++ * CPUID table entries are only a template that may need to be ++ * augmented with additional values for things like ++ * CPU-specific information during post-processing. So if it's ++ * not in the table, set the values to zero. Then, if they are ++ * within a valid CPUID range, proceed with post-processing ++ * using zeros as the initial values. Otherwise, skip ++ * post-processing and just return zeros immediately. ++ */ ++ leaf->eax = leaf->ebx = leaf->ecx = leaf->edx = 0; ++ ++ /* Skip post-processing for out-of-range zero leafs. */ ++ if (!(leaf->fn <= cpuid_std_range_max || ++ (leaf->fn >= 0x40000000 && leaf->fn <= cpuid_hyp_range_max) || ++ (leaf->fn >= 0x80000000 && leaf->fn <= cpuid_ext_range_max))) ++ return 0; ++ } ++ ++ return snp_cpuid_postprocess(leaf); ++} ++ ++/* + * Boot VC Handler - This is the first VC handler during boot, there is no GHCB + * page yet, so it only supports the MSR based communication with the + * hypervisor and only the CPUID exit-code. +@@ -252,6 +541,7 @@ void __init do_vc_no_ghcb(struct pt_regs + unsigned int subfn = lower_bits(regs->cx, 32); + unsigned int fn = lower_bits(regs->ax, 32); + struct cpuid_leaf leaf; ++ int ret; + + /* Only CPUID is supported via MSR protocol */ + if (exit_code != SVM_EXIT_CPUID) +@@ -259,9 +549,18 @@ void __init do_vc_no_ghcb(struct pt_regs + + leaf.fn = fn; + leaf.subfn = subfn; ++ ++ ret = snp_cpuid(&leaf); ++ if (!ret) ++ goto cpuid_done; ++ ++ if (ret != -EOPNOTSUPP) ++ goto fail; ++ + if (sev_cpuid_hv(&leaf)) + goto fail; + ++cpuid_done: + regs->ax = leaf.eax; + regs->bx = leaf.ebx; + regs->cx = leaf.ecx; +@@ -556,12 +855,37 @@ static enum es_result vc_handle_ioio(str + return ret; + } + ++static int vc_handle_cpuid_snp(struct pt_regs *regs) ++{ ++ struct cpuid_leaf leaf; ++ int ret; ++ ++ leaf.fn = regs->ax; ++ leaf.subfn = regs->cx; ++ ret = snp_cpuid(&leaf); ++ if (!ret) { ++ regs->ax = leaf.eax; ++ regs->bx = leaf.ebx; ++ regs->cx = leaf.ecx; ++ regs->dx = leaf.edx; ++ } ++ ++ return ret; ++} ++ + static enum es_result vc_handle_cpuid(struct ghcb *ghcb, + struct es_em_ctxt *ctxt) + { + struct pt_regs *regs = ctxt->regs; + u32 cr4 = native_read_cr4(); + enum es_result ret; ++ int snp_cpuid_ret; ++ ++ snp_cpuid_ret = vc_handle_cpuid_snp(regs); ++ if (!snp_cpuid_ret) ++ return ES_OK; ++ if (snp_cpuid_ret != -EOPNOTSUPP) ++ return ES_VMM_ERROR; + + ghcb_set_rax(ghcb, regs->ax); + ghcb_set_rcx(ghcb, regs->cx); diff --git a/patches.suse/x86-compressed-64-Detect-setup-SEV-SME-features-earlier-during-b b/patches.suse/x86-compressed-64-Detect-setup-SEV-SME-features-earlier-during-b new file mode 100644 index 0000000..305e791 --- /dev/null +++ b/patches.suse/x86-compressed-64-Detect-setup-SEV-SME-features-earlier-during-b @@ -0,0 +1,210 @@ +From: Michael Roth +Date: Wed, 9 Feb 2022 12:10:01 -0600 +Subject: x86/compressed/64: Detect/setup SEV/SME features earlier during boot +Git-commit: ec1c66af3a30d45c2420da0974c01d3515dba26e +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +With upcoming SEV-SNP support, SEV-related features need to be +initialized earlier during boot, at the same point the initial #VC +handler is set up, so that the SEV-SNP CPUID table can be utilized +during the initial feature checks. Also, SEV-SNP feature detection +will rely on EFI helper functions to scan the EFI config table for the +Confidential Computing blob, and so would need to be implemented at +least partially in C. + +Currently set_sev_encryption_mask() is used to initialize the +sev_status and sme_me_mask globals that advertise what SEV/SME features +are available in a guest. Rename it to sev_enable() to better reflect +that (SME is only enabled in the case of SEV guests in the +boot/compressed kernel), and move it to just after the stage1 #VC +handler is set up so that it can be used to initialize SEV-SNP as well +in future patches. + +While at it, re-implement it as C code so that all SEV feature +detection can be better consolidated with upcoming SEV-SNP feature +detection, which will also be in C. + +The 32-bit entry path remains unchanged, as it never relied on the +set_sev_encryption_mask() initialization to begin with. + + [ bp: Massage commit message. ] + +Signed-off-by: Michael Roth +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220307213356.2797205-8-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/boot/compressed/head_64.S | 37 +++++++++++++++++++-------------- + arch/x86/boot/compressed/mem_encrypt.S | 36 -------------------------------- + arch/x86/boot/compressed/misc.h | 4 +-- + arch/x86/boot/compressed/sev.c | 36 ++++++++++++++++++++++++++++++++ + 4 files changed, 60 insertions(+), 53 deletions(-) + +--- a/arch/x86/boot/compressed/head_64.S ++++ b/arch/x86/boot/compressed/head_64.S +@@ -189,11 +189,11 @@ SYM_FUNC_START(startup_32) + subl $32, %eax /* Encryption bit is always above bit 31 */ + bts %eax, %edx /* Set encryption mask for page tables */ + /* +- * Mark SEV as active in sev_status so that startup32_check_sev_cbit() +- * will do a check. The sev_status memory will be fully initialized +- * with the contents of MSR_AMD_SEV_STATUS later in +- * set_sev_encryption_mask(). For now it is sufficient to know that SEV +- * is active. ++ * Set MSR_AMD64_SEV_ENABLED_BIT in sev_status so that ++ * startup32_check_sev_cbit() will do a check. sev_enable() will ++ * initialize sev_status with all the bits reported by ++ * MSR_AMD_SEV_STATUS later, but only MSR_AMD64_SEV_ENABLED_BIT ++ * needs to be set for now. + */ + movl $1, rva(sev_status)(%ebp) + 1: +@@ -447,6 +447,23 @@ SYM_CODE_START(startup_64) + call load_stage1_idt + popq %rsi + ++#ifdef CONFIG_AMD_MEM_ENCRYPT ++ /* ++ * Now that the stage1 interrupt handlers are set up, #VC exceptions from ++ * CPUID instructions can be properly handled for SEV-ES guests. ++ * ++ * For SEV-SNP, the CPUID table also needs to be set up in advance of any ++ * CPUID instructions being issued, so go ahead and do that now via ++ * sev_enable(), which will also handle the rest of the SEV-related ++ * detection/setup to ensure that has been done in advance of any dependent ++ * code. ++ */ ++ pushq %rsi ++ movq %rsi, %rdi /* real mode address */ ++ call sev_enable ++ popq %rsi ++#endif ++ + /* + * paging_prepare() sets up the trampoline and checks if we need to + * enable 5-level paging. +@@ -559,17 +576,7 @@ SYM_FUNC_START_LOCAL_NOALIGN(.Lrelocated + shrq $3, %rcx + rep stosq + +-/* +- * If running as an SEV guest, the encryption mask is required in the +- * page-table setup code below. When the guest also has SEV-ES enabled +- * set_sev_encryption_mask() will cause #VC exceptions, but the stage2 +- * handler can't map its GHCB because the page-table is not set up yet. +- * So set up the encryption mask here while still on the stage1 #VC +- * handler. Then load stage2 IDT and switch to the kernel's own +- * page-table. +- */ + pushq %rsi +- call set_sev_encryption_mask + call load_stage2_idt + + /* Pass boot_params to initialize_identity_maps() */ +--- a/arch/x86/boot/compressed/mem_encrypt.S ++++ b/arch/x86/boot/compressed/mem_encrypt.S +@@ -187,42 +187,6 @@ SYM_CODE_END(startup32_vc_handler) + .code64 + + #include "../../kernel/sev_verify_cbit.S" +-SYM_FUNC_START(set_sev_encryption_mask) +-#ifdef CONFIG_AMD_MEM_ENCRYPT +- push %rbp +- push %rdx +- +- movq %rsp, %rbp /* Save current stack pointer */ +- +- call get_sev_encryption_bit /* Get the encryption bit position */ +- testl %eax, %eax +- jz .Lno_sev_mask +- +- bts %rax, sme_me_mask(%rip) /* Create the encryption mask */ +- +- /* +- * Read MSR_AMD64_SEV again and store it to sev_status. Can't do this in +- * get_sev_encryption_bit() because this function is 32-bit code and +- * shared between 64-bit and 32-bit boot path. +- */ +- movl $MSR_AMD64_SEV, %ecx /* Read the SEV MSR */ +- rdmsr +- +- /* Store MSR value in sev_status */ +- shlq $32, %rdx +- orq %rdx, %rax +- movq %rax, sev_status(%rip) +- +-.Lno_sev_mask: +- movq %rbp, %rsp /* Restore original stack pointer */ +- +- pop %rdx +- pop %rbp +-#endif +- +- xor %rax, %rax +- RET +-SYM_FUNC_END(set_sev_encryption_mask) + + .data + +--- a/arch/x86/boot/compressed/misc.h ++++ b/arch/x86/boot/compressed/misc.h +@@ -116,12 +116,12 @@ static inline void console_init(void) + { } + #endif + +-void set_sev_encryption_mask(void); +- + #ifdef CONFIG_AMD_MEM_ENCRYPT ++void sev_enable(struct boot_params *bp); + void sev_es_shutdown_ghcb(void); + extern bool sev_es_check_ghcb_fault(unsigned long address); + #else ++static inline void sev_enable(struct boot_params *bp) { } + static inline void sev_es_shutdown_ghcb(void) { } + static inline bool sev_es_check_ghcb_fault(unsigned long address) + { +--- a/arch/x86/boot/compressed/sev.c ++++ b/arch/x86/boot/compressed/sev.c +@@ -201,3 +201,39 @@ finish: + else if (result != ES_RETRY) + sev_es_terminate(GHCB_SEV_ES_GEN_REQ); + } ++ ++void sev_enable(struct boot_params *bp) ++{ ++ unsigned int eax, ebx, ecx, edx; ++ struct msr m; ++ ++ /* Check for the SME/SEV support leaf */ ++ eax = 0x80000000; ++ ecx = 0; ++ native_cpuid(&eax, &ebx, &ecx, &edx); ++ if (eax < 0x8000001f) ++ return; ++ ++ /* ++ * Check for the SME/SEV feature: ++ * CPUID Fn8000_001F[EAX] ++ * - Bit 0 - Secure Memory Encryption support ++ * - Bit 1 - Secure Encrypted Virtualization support ++ * CPUID Fn8000_001F[EBX] ++ * - Bits 5:0 - Pagetable bit position used to indicate encryption ++ */ ++ eax = 0x8000001f; ++ ecx = 0; ++ native_cpuid(&eax, &ebx, &ecx, &edx); ++ /* Check whether SEV is supported */ ++ if (!(eax & BIT(1))) ++ return; ++ ++ /* Set the SME mask if this is an SEV guest. */ ++ boot_rdmsr(MSR_AMD64_SEV, &m); ++ sev_status = m.q; ++ if (!(sev_status & MSR_AMD64_SEV_ENABLED)) ++ return; ++ ++ sme_me_mask = BIT_ULL(ebx & 0x3f); ++} diff --git a/patches.suse/x86-compressed-Add-SEV-SNP-feature-detection-setup b/patches.suse/x86-compressed-Add-SEV-SNP-feature-detection-setup new file mode 100644 index 0000000..5b4ba2e --- /dev/null +++ b/patches.suse/x86-compressed-Add-SEV-SNP-feature-detection-setup @@ -0,0 +1,184 @@ +From: Michael Roth +Date: Thu, 24 Feb 2022 10:56:14 -0600 +Subject: x86/compressed: Add SEV-SNP feature detection/setup +Git-commit: c01fce9cef8491974f7f007f90281f1608400768 +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +Initial/preliminary detection of SEV-SNP is done via the Confidential +Computing blob. Check for it prior to the normal SEV/SME feature +initialization, and add some sanity checks to confirm it agrees with +SEV-SNP CPUID/MSR bits. + +Signed-off-by: Michael Roth +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220307213356.2797205-35-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/boot/compressed/sev.c | 112 ++++++++++++++++++++++++++++++++++++++++- + arch/x86/include/asm/sev.h | 3 + + 2 files changed, 114 insertions(+), 1 deletion(-) + +--- a/arch/x86/boot/compressed/sev.c ++++ b/arch/x86/boot/compressed/sev.c +@@ -274,6 +274,13 @@ void sev_enable(struct boot_params *bp) + { + unsigned int eax, ebx, ecx, edx; + struct msr m; ++ bool snp; ++ ++ /* ++ * Setup/preliminary detection of SNP. This will be sanity-checked ++ * against CPUID/MSR values later. ++ */ ++ snp = snp_init(bp); + + /* Check for the SME/SEV support leaf */ + eax = 0x80000000; +@@ -294,8 +301,11 @@ void sev_enable(struct boot_params *bp) + ecx = 0; + native_cpuid(&eax, &ebx, &ecx, &edx); + /* Check whether SEV is supported */ +- if (!(eax & BIT(1))) ++ if (!(eax & BIT(1))) { ++ if (snp) ++ error("SEV-SNP support indicated by CC blob, but not CPUID."); + return; ++ } + + /* Set the SME mask if this is an SEV guest. */ + boot_rdmsr(MSR_AMD64_SEV, &m); +@@ -320,5 +330,105 @@ void sev_enable(struct boot_params *bp) + enforce_vmpl0(); + } + ++ if (snp && !(sev_status & MSR_AMD64_SEV_SNP_ENABLED)) ++ error("SEV-SNP supported indicated by CC blob, but not SEV status MSR."); ++ + sme_me_mask = BIT_ULL(ebx & 0x3f); + } ++ ++/* Search for Confidential Computing blob in the EFI config table. */ ++static struct cc_blob_sev_info *find_cc_blob_efi(struct boot_params *bp) ++{ ++ unsigned long cfg_table_pa; ++ unsigned int cfg_table_len; ++ int ret; ++ ++ ret = efi_get_conf_table(bp, &cfg_table_pa, &cfg_table_len); ++ if (ret) ++ return NULL; ++ ++ return (struct cc_blob_sev_info *)efi_find_vendor_table(bp, cfg_table_pa, ++ cfg_table_len, ++ EFI_CC_BLOB_GUID); ++} ++ ++struct cc_setup_data { ++ struct setup_data header; ++ u32 cc_blob_address; ++}; ++ ++/* ++ * Search for a Confidential Computing blob passed in as a setup_data entry ++ * via the Linux Boot Protocol. ++ */ ++static struct cc_blob_sev_info *find_cc_blob_setup_data(struct boot_params *bp) ++{ ++ struct cc_setup_data *sd = NULL; ++ struct setup_data *hdr; ++ ++ hdr = (struct setup_data *)bp->hdr.setup_data; ++ ++ while (hdr) { ++ if (hdr->type == SETUP_CC_BLOB) { ++ sd = (struct cc_setup_data *)hdr; ++ return (struct cc_blob_sev_info *)(unsigned long)sd->cc_blob_address; ++ } ++ hdr = (struct setup_data *)hdr->next; ++ } ++ ++ return NULL; ++} ++ ++/* ++ * Initial set up of SNP relies on information provided by the ++ * Confidential Computing blob, which can be passed to the boot kernel ++ * by firmware/bootloader in the following ways: ++ * ++ * - via an entry in the EFI config table ++ * - via a setup_data structure, as defined by the Linux Boot Protocol ++ * ++ * Scan for the blob in that order. ++ */ ++static struct cc_blob_sev_info *find_cc_blob(struct boot_params *bp) ++{ ++ struct cc_blob_sev_info *cc_info; ++ ++ cc_info = find_cc_blob_efi(bp); ++ if (cc_info) ++ goto found_cc_info; ++ ++ cc_info = find_cc_blob_setup_data(bp); ++ if (!cc_info) ++ return NULL; ++ ++found_cc_info: ++ if (cc_info->magic != CC_BLOB_SEV_HDR_MAGIC) ++ sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED); ++ ++ return cc_info; ++} ++ ++/* ++ * Indicate SNP based on presence of SNP-specific CC blob. Subsequent checks ++ * will verify the SNP CPUID/MSR bits. ++ */ ++bool snp_init(struct boot_params *bp) ++{ ++ struct cc_blob_sev_info *cc_info; ++ ++ if (!bp) ++ return false; ++ ++ cc_info = find_cc_blob(bp); ++ if (!cc_info) ++ return false; ++ ++ /* ++ * Pass run-time kernel a pointer to CC info via boot_params so EFI ++ * config table doesn't need to be searched again during early startup ++ * phase. ++ */ ++ bp->cc_blob_address = (u32)(unsigned long)cc_info; ++ ++ return true; ++} +--- a/arch/x86/include/asm/sev.h ++++ b/arch/x86/include/asm/sev.h +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + + #define GHCB_PROTOCOL_MIN 1ULL + #define GHCB_PROTOCOL_MAX 2ULL +@@ -151,6 +152,7 @@ void __init snp_prep_memory(unsigned lon + void snp_set_memory_shared(unsigned long vaddr, unsigned int npages); + void snp_set_memory_private(unsigned long vaddr, unsigned int npages); + void snp_set_wakeup_secondary_cpu(void); ++bool snp_init(struct boot_params *bp); + #else + static inline void sev_es_ist_enter(struct pt_regs *regs) { } + static inline void sev_es_ist_exit(void) { } +@@ -168,6 +170,7 @@ static inline void __init snp_prep_memor + static inline void snp_set_memory_shared(unsigned long vaddr, unsigned int npages) { } + static inline void snp_set_memory_private(unsigned long vaddr, unsigned int npages) { } + static inline void snp_set_wakeup_secondary_cpu(void) { } ++static inline bool snp_init(struct boot_params *bp) { return false; } + #endif + + #endif diff --git a/patches.suse/x86-compressed-Add-helper-for-validating-pages-in-the-decompress b/patches.suse/x86-compressed-Add-helper-for-validating-pages-in-the-decompress new file mode 100644 index 0000000..4e999e5 --- /dev/null +++ b/patches.suse/x86-compressed-Add-helper-for-validating-pages-in-the-decompress @@ -0,0 +1,198 @@ +From: Brijesh Singh +Date: Wed, 9 Feb 2022 12:10:09 -0600 +Subject: x86/compressed: Add helper for validating pages in the decompression + stage +Git-commit: 4f9c403e44e5e88feb27d5e617d1adc9cc7ef684 +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +Many of the integrity guarantees of SEV-SNP are enforced through the +Reverse Map Table (RMP). Each RMP entry contains the GPA at which a +particular page of DRAM should be mapped. The VMs can request the +hypervisor to add pages in the RMP table via the Page State Change +VMGEXIT defined in the GHCB specification. + +Inside each RMP entry is a Validated flag; this flag is automatically +cleared to 0 by the CPU hardware when a new RMP entry is created for a +guest. Each VM page can be either validated or invalidated, as indicated +by the Validated flag in the RMP entry. Memory access to a private page +that is not validated generates a #VC. A VM must use the PVALIDATE +instruction to validate a private page before using it. + +To maintain the security guarantee of SEV-SNP guests, when transitioning +pages from private to shared, the guest must invalidate the pages before +asking the hypervisor to change the page state to shared in the RMP table. + +After the pages are mapped private in the page table, the guest must +issue a page state change VMGEXIT to mark the pages private in the RMP +table and validate them. + +Upon boot, BIOS should have validated the entire system memory. +During the kernel decompression stage, early_setup_ghcb() uses +set_page_decrypted() to make the GHCB page shared (i.e. clear encryption +attribute). And while exiting from the decompression, it calls +set_page_encrypted() to make the page private. + +Add snp_set_page_{private,shared}() helpers that are used by +set_page_{decrypted,encrypted}() to change the page state in the RMP +table. + + [ bp: Massage commit message and comments. ] + +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220307213356.2797205-16-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/boot/compressed/ident_map_64.c | 18 +++++++++++- + arch/x86/boot/compressed/misc.h | 4 ++ + arch/x86/boot/compressed/sev.c | 46 ++++++++++++++++++++++++++++++++ + arch/x86/include/asm/sev-common.h | 26 ++++++++++++++++++ + 4 files changed, 93 insertions(+), 1 deletion(-) + +--- a/arch/x86/boot/compressed/ident_map_64.c ++++ b/arch/x86/boot/compressed/ident_map_64.c +@@ -275,15 +275,31 @@ static int set_clr_page_flags(struct x86 + * Changing encryption attributes of a page requires to flush it from + * the caches. + */ +- if ((set | clr) & _PAGE_ENC) ++ if ((set | clr) & _PAGE_ENC) { + clflush_page(address); + ++ /* ++ * If the encryption attribute is being cleared, change the page state ++ * to shared in the RMP table. ++ */ ++ if (clr) ++ snp_set_page_shared(__pa(address & PAGE_MASK)); ++ } ++ + /* Update PTE */ + pte = *ptep; + pte = pte_set_flags(pte, set); + pte = pte_clear_flags(pte, clr); + set_pte(ptep, pte); + ++ /* ++ * If the encryption attribute is being set, then change the page state to ++ * private in the RMP entry. The page state change must be done after the PTE ++ * is updated. ++ */ ++ if (set & _PAGE_ENC) ++ snp_set_page_private(__pa(address & PAGE_MASK)); ++ + /* Flush TLB after changing encryption attribute */ + write_cr3(top_level_pgt); + +--- a/arch/x86/boot/compressed/misc.h ++++ b/arch/x86/boot/compressed/misc.h +@@ -120,6 +120,8 @@ static inline void console_init(void) + void sev_enable(struct boot_params *bp); + void sev_es_shutdown_ghcb(void); + extern bool sev_es_check_ghcb_fault(unsigned long address); ++void snp_set_page_private(unsigned long paddr); ++void snp_set_page_shared(unsigned long paddr); + #else + static inline void sev_enable(struct boot_params *bp) { } + static inline void sev_es_shutdown_ghcb(void) { } +@@ -127,6 +129,8 @@ static inline bool sev_es_check_ghcb_fau + { + return false; + } ++static inline void snp_set_page_private(unsigned long paddr) { } ++static inline void snp_set_page_shared(unsigned long paddr) { } + #endif + + /* acpi.c */ +--- a/arch/x86/boot/compressed/sev.c ++++ b/arch/x86/boot/compressed/sev.c +@@ -116,6 +116,52 @@ static enum es_result vc_read_mem(struct + /* Include code for early handlers */ + #include "../../kernel/sev-shared.c" + ++static inline bool sev_snp_enabled(void) ++{ ++ return sev_status & MSR_AMD64_SEV_SNP_ENABLED; ++} ++ ++static void __page_state_change(unsigned long paddr, enum psc_op op) ++{ ++ u64 val; ++ ++ if (!sev_snp_enabled()) ++ return; ++ ++ /* ++ * If private -> shared then invalidate the page before requesting the ++ * state change in the RMP table. ++ */ ++ if (op == SNP_PAGE_STATE_SHARED && pvalidate(paddr, RMP_PG_SIZE_4K, 0)) ++ sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PVALIDATE); ++ ++ /* Issue VMGEXIT to change the page state in RMP table. */ ++ sev_es_wr_ghcb_msr(GHCB_MSR_PSC_REQ_GFN(paddr >> PAGE_SHIFT, op)); ++ VMGEXIT(); ++ ++ /* Read the response of the VMGEXIT. */ ++ val = sev_es_rd_ghcb_msr(); ++ if ((GHCB_RESP_CODE(val) != GHCB_MSR_PSC_RESP) || GHCB_MSR_PSC_RESP_VAL(val)) ++ sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PSC); ++ ++ /* ++ * Now that page state is changed in the RMP table, validate it so that it is ++ * consistent with the RMP entry. ++ */ ++ if (op == SNP_PAGE_STATE_PRIVATE && pvalidate(paddr, RMP_PG_SIZE_4K, 1)) ++ sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PVALIDATE); ++} ++ ++void snp_set_page_private(unsigned long paddr) ++{ ++ __page_state_change(paddr, SNP_PAGE_STATE_PRIVATE); ++} ++ ++void snp_set_page_shared(unsigned long paddr) ++{ ++ __page_state_change(paddr, SNP_PAGE_STATE_SHARED); ++} ++ + static bool early_setup_ghcb(void) + { + if (set_page_decrypted((unsigned long)&boot_ghcb_page)) +--- a/arch/x86/include/asm/sev-common.h ++++ b/arch/x86/include/asm/sev-common.h +@@ -57,6 +57,32 @@ + #define GHCB_MSR_AP_RESET_HOLD_REQ 0x006 + #define GHCB_MSR_AP_RESET_HOLD_RESP 0x007 + ++/* ++ * SNP Page State Change Operation ++ * ++ * GHCBData[55:52] - Page operation: ++ * 0x0001 Page assignment, Private ++ * 0x0002 Page assignment, Shared ++ */ ++enum psc_op { ++ SNP_PAGE_STATE_PRIVATE = 1, ++ SNP_PAGE_STATE_SHARED, ++}; ++ ++#define GHCB_MSR_PSC_REQ 0x014 ++#define GHCB_MSR_PSC_REQ_GFN(gfn, op) \ ++ /* GHCBData[55:52] */ \ ++ (((u64)((op) & 0xf) << 52) | \ ++ /* GHCBData[51:12] */ \ ++ ((u64)((gfn) & GENMASK_ULL(39, 0)) << 12) | \ ++ /* GHCBData[11:0] */ \ ++ GHCB_MSR_PSC_REQ) ++ ++#define GHCB_MSR_PSC_RESP 0x015 ++#define GHCB_MSR_PSC_RESP_VAL(val) \ ++ /* GHCBData[63:32] */ \ ++ (((u64)(val) & GENMASK_ULL(63, 32)) >> 32) ++ + /* GHCB Hypervisor Feature Request/Response */ + #define GHCB_MSR_HV_FT_REQ 0x080 + #define GHCB_MSR_HV_FT_RESP 0x081 diff --git a/patches.suse/x86-compressed-Export-and-rename-add_identity_map b/patches.suse/x86-compressed-Export-and-rename-add_identity_map new file mode 100644 index 0000000..88553f4 --- /dev/null +++ b/patches.suse/x86-compressed-Export-and-rename-add_identity_map @@ -0,0 +1,88 @@ +From: Michael Roth +Date: Thu, 24 Feb 2022 10:56:16 -0600 +Subject: x86/compressed: Export and rename add_identity_map() +Git-commit: a9ee679b1f8c3803490ed2eeffb688aaee56583f +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +SEV-specific code will need to add some additional mappings, but doing +this within ident_map_64.c requires some SEV-specific helpers to be +exported and some SEV-specific struct definitions to be pulled into +ident_map_64.c. Instead, export add_identity_map() so SEV-specific (and +other subsystem-specific) code can be better contained outside of +ident_map_64.c. + +While at it, rename the function to kernel_add_identity_map(), similar +to the kernel_ident_mapping_init() function it relies upon. + +No functional changes. + +Suggested-by: Borislav Petkov +Signed-off-by: Michael Roth +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220307213356.2797205-37-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/boot/compressed/ident_map_64.c | 18 +++++++++--------- + arch/x86/boot/compressed/misc.h | 1 + + 2 files changed, 10 insertions(+), 9 deletions(-) + +--- a/arch/x86/boot/compressed/ident_map_64.c ++++ b/arch/x86/boot/compressed/ident_map_64.c +@@ -90,7 +90,7 @@ static struct x86_mapping_info mapping_i + /* + * Adds the specified range to the identity mappings. + */ +-static void add_identity_map(unsigned long start, unsigned long end) ++void kernel_add_identity_map(unsigned long start, unsigned long end) + { + int ret; + +@@ -157,11 +157,11 @@ void initialize_identity_maps(void *rmod + * explicitly here in case the compressed kernel does not touch them, + * or does not touch all the pages covering them. + */ +- add_identity_map((unsigned long)_head, (unsigned long)_end); ++ kernel_add_identity_map((unsigned long)_head, (unsigned long)_end); + boot_params = rmode; +- add_identity_map((unsigned long)boot_params, (unsigned long)(boot_params + 1)); ++ kernel_add_identity_map((unsigned long)boot_params, (unsigned long)(boot_params + 1)); + cmdline = get_cmd_line_ptr(); +- add_identity_map(cmdline, cmdline + COMMAND_LINE_SIZE); ++ kernel_add_identity_map(cmdline, cmdline + COMMAND_LINE_SIZE); + + /* Load the new page-table. */ + sev_verify_cbit(top_level_pgt); +@@ -246,10 +246,10 @@ static int set_clr_page_flags(struct x86 + * It should already exist, but keep things generic. + * + * To map the page just read from it and fault it in if there is no +- * mapping yet. add_identity_map() can't be called here because that +- * would unconditionally map the address on PMD level, destroying any +- * PTE-level mappings that might already exist. Use assembly here so +- * the access won't be optimized away. ++ * mapping yet. kernel_add_identity_map() can't be called here because ++ * that would unconditionally map the address on PMD level, destroying ++ * any PTE-level mappings that might already exist. Use assembly here ++ * so the access won't be optimized away. + */ + asm volatile("mov %[address], %%r9" + :: [address] "g" (*(unsigned long *)address) +@@ -363,5 +363,5 @@ void do_boot_page_fault(struct pt_regs * + * Error code is sane - now identity map the 2M region around + * the faulting address. + */ +- add_identity_map(address, end); ++ kernel_add_identity_map(address, end); + } +--- a/arch/x86/boot/compressed/misc.h ++++ b/arch/x86/boot/compressed/misc.h +@@ -152,6 +152,7 @@ static inline int count_immovable_mem_re + #ifdef CONFIG_X86_5LEVEL + extern unsigned int __pgtable_l5_enabled, pgdir_shift, ptrs_per_p4d; + #endif ++extern void kernel_add_identity_map(unsigned long start, unsigned long end); + + /* Used by PAGE_KERN* macros: */ + extern pteval_t __default_kernel_pte_mask; diff --git a/patches.suse/x86-compressed-Register-GHCB-memory-when-SEV-SNP-is-active b/patches.suse/x86-compressed-Register-GHCB-memory-when-SEV-SNP-is-active new file mode 100644 index 0000000..61caad3 --- /dev/null +++ b/patches.suse/x86-compressed-Register-GHCB-memory-when-SEV-SNP-is-active @@ -0,0 +1,88 @@ +From: Brijesh Singh +Date: Wed, 9 Feb 2022 12:10:10 -0600 +Subject: x86/compressed: Register GHCB memory when SEV-SNP is active +Git-commit: 87294bdb7b4b73555b0fba45da1cdecdc6a0d5a8 +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +The SEV-SNP guest is required by the GHCB spec to register the GHCB's +Guest Physical Address (GPA). This is because the hypervisor may prefer +that a guest use a consistent and/or specific GPA for the GHCB associated +with a vCPU. For more information, see the GHCB specification section +"GHCB GPA Registration". + +If hypervisor can not work with the guest provided GPA then terminate the +guest boot. + +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Reviewed-by: Venu Busireddy +Link: https://lore.kernel.org/r/20220307213356.2797205-17-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/boot/compressed/sev.c | 4 ++++ + arch/x86/include/asm/sev-common.h | 13 +++++++++++++ + arch/x86/kernel/sev-shared.c | 16 ++++++++++++++++ + 3 files changed, 33 insertions(+) + +--- a/arch/x86/boot/compressed/sev.c ++++ b/arch/x86/boot/compressed/sev.c +@@ -175,6 +175,10 @@ static bool early_setup_ghcb(void) + /* Initialize lookup tables for the instruction decoder */ + inat_init_tables(); + ++ /* SNP guest requires the GHCB GPA must be registered */ ++ if (sev_snp_enabled()) ++ snp_register_ghcb_early(__pa(&boot_ghcb_page)); ++ + return true; + } + +--- a/arch/x86/include/asm/sev-common.h ++++ b/arch/x86/include/asm/sev-common.h +@@ -57,6 +57,19 @@ + #define GHCB_MSR_AP_RESET_HOLD_REQ 0x006 + #define GHCB_MSR_AP_RESET_HOLD_RESP 0x007 + ++/* GHCB GPA Register */ ++#define GHCB_MSR_REG_GPA_REQ 0x012 ++#define GHCB_MSR_REG_GPA_REQ_VAL(v) \ ++ /* GHCBData[63:12] */ \ ++ (((u64)((v) & GENMASK_ULL(51, 0)) << 12) | \ ++ /* GHCBData[11:0] */ \ ++ GHCB_MSR_REG_GPA_REQ) ++ ++#define GHCB_MSR_REG_GPA_RESP 0x013 ++#define GHCB_MSR_REG_GPA_RESP_VAL(v) \ ++ /* GHCBData[63:12] */ \ ++ (((u64)(v) & GENMASK_ULL(63, 12)) >> 12) ++ + /* + * SNP Page State Change Operation + * +--- a/arch/x86/kernel/sev-shared.c ++++ b/arch/x86/kernel/sev-shared.c +@@ -68,6 +68,22 @@ static u64 get_hv_features(void) + return GHCB_MSR_HV_FT_RESP_VAL(val); + } + ++static void __maybe_unused snp_register_ghcb_early(unsigned long paddr) ++{ ++ unsigned long pfn = paddr >> PAGE_SHIFT; ++ u64 val; ++ ++ sev_es_wr_ghcb_msr(GHCB_MSR_REG_GPA_REQ_VAL(pfn)); ++ VMGEXIT(); ++ ++ val = sev_es_rd_ghcb_msr(); ++ ++ /* If the response GPA is not ours then abort the guest */ ++ if ((GHCB_RESP_CODE(val) != GHCB_MSR_REG_GPA_RESP) || ++ (GHCB_MSR_REG_GPA_RESP_VAL(val) != pfn)) ++ sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_REGISTER); ++} ++ + static bool sev_es_negotiate_protocol(void) + { + u64 val; diff --git a/patches.suse/x86-compressed-Use-firmware-validated-CPUID-leaves-for-SEV-SNP-g b/patches.suse/x86-compressed-Use-firmware-validated-CPUID-leaves-for-SEV-SNP-g new file mode 100644 index 0000000..3e6b499 --- /dev/null +++ b/patches.suse/x86-compressed-Use-firmware-validated-CPUID-leaves-for-SEV-SNP-g @@ -0,0 +1,92 @@ +From: Michael Roth +Date: Thu, 24 Feb 2022 10:56:15 -0600 +Subject: x86/compressed: Use firmware-validated CPUID leaves for SEV-SNP + guests +Git-commit: 5f211f4fc49622473667e6983bb57beab755f6f6 +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +SEV-SNP guests will be provided the location of special 'secrets' +'CPUID' pages via the Confidential Computing blob. This blob is +provided to the boot kernel either through an EFI config table entry, +or via a setup_data structure as defined by the Linux Boot Protocol. + +Locate the Confidential Computing from these sources and, if found, +use the provided CPUID page/table address to create a copy that the +boot kernel will use when servicing CPUID instructions via a #VC CPUID +handler. + + [ bp: s/cpuid/CPUID/ ] + +Signed-off-by: Michael Roth +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220307213356.2797205-36-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/boot/compressed/sev.c | 46 +++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 46 insertions(+) + +--- a/arch/x86/boot/compressed/sev.c ++++ b/arch/x86/boot/compressed/sev.c +@@ -409,6 +409,43 @@ found_cc_info: + } + + /* ++ * Initialize the kernel's copy of the SNP CPUID table, and set up the ++ * pointer that will be used to access it. ++ * ++ * Maintaining a direct mapping of the SNP CPUID table used by firmware would ++ * be possible as an alternative, but the approach is brittle since the ++ * mapping needs to be updated in sync with all the changes to virtual memory ++ * layout and related mapping facilities throughout the boot process. ++ */ ++static void setup_cpuid_table(const struct cc_blob_sev_info *cc_info) ++{ ++ const struct snp_cpuid_table *cpuid_table_fw, *cpuid_table; ++ int i; ++ ++ if (!cc_info || !cc_info->cpuid_phys || cc_info->cpuid_len < PAGE_SIZE) ++ sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_CPUID); ++ ++ cpuid_table_fw = (const struct snp_cpuid_table *)cc_info->cpuid_phys; ++ if (!cpuid_table_fw->count || cpuid_table_fw->count > SNP_CPUID_COUNT_MAX) ++ sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_CPUID); ++ ++ cpuid_table = snp_cpuid_get_table(); ++ memcpy((void *)cpuid_table, cpuid_table_fw, sizeof(*cpuid_table)); ++ ++ /* Initialize CPUID ranges for range-checking. */ ++ for (i = 0; i < cpuid_table->count; i++) { ++ const struct snp_cpuid_fn *fn = &cpuid_table->fn[i]; ++ ++ if (fn->eax_in == 0x0) ++ cpuid_std_range_max = fn->eax; ++ else if (fn->eax_in == 0x40000000) ++ cpuid_hyp_range_max = fn->eax; ++ else if (fn->eax_in == 0x80000000) ++ cpuid_ext_range_max = fn->eax; ++ } ++} ++ ++/* + * Indicate SNP based on presence of SNP-specific CC blob. Subsequent checks + * will verify the SNP CPUID/MSR bits. + */ +@@ -424,6 +461,15 @@ bool snp_init(struct boot_params *bp) + return false; + + /* ++ * If a SNP-specific Confidential Computing blob is present, then ++ * firmware/bootloader have indicated SNP support. Verifying this ++ * involves CPUID checks which will be more reliable if the SNP ++ * CPUID table is used. See comments over snp_setup_cpuid_table() for ++ * more details. ++ */ ++ setup_cpuid_table(cc_info); ++ ++ /* + * Pass run-time kernel a pointer to CC info via boot_params so EFI + * config table doesn't need to be searched again during early startup + * phase. diff --git a/patches.suse/x86-compressed-acpi-Move-EFI-config-table-lookup-to-helper b/patches.suse/x86-compressed-acpi-Move-EFI-config-table-lookup-to-helper new file mode 100644 index 0000000..b5021ec --- /dev/null +++ b/patches.suse/x86-compressed-acpi-Move-EFI-config-table-lookup-to-helper @@ -0,0 +1,144 @@ +From: Michael Roth +Date: Thu, 24 Feb 2022 10:56:06 -0600 +Subject: x86/compressed/acpi: Move EFI config table lookup to helper +Git-commit: 61c14ceda8405f37545a0983d6b9bc45c6236793 +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +Future patches for SEV-SNP-validated CPUID will also require early +parsing of the EFI configuration. Incrementally move the related code +into a set of helpers that can be re-used for that purpose. + + [ bp: Remove superfluous zeroing of a stack variable. ] + +Signed-off-by: Michael Roth +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220307213356.2797205-27-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/boot/compressed/acpi.c | 25 +++++++---------------- + arch/x86/boot/compressed/efi.c | 43 ++++++++++++++++++++++++++++++++++++++++ + arch/x86/boot/compressed/misc.h | 9 ++++++++ + 3 files changed, 60 insertions(+), 17 deletions(-) + +--- a/arch/x86/boot/compressed/acpi.c ++++ b/arch/x86/boot/compressed/acpi.c +@@ -118,10 +118,13 @@ static acpi_physical_address kexec_get_r + static acpi_physical_address efi_get_rsdp_addr(void) + { + #ifdef CONFIG_EFI +- unsigned long systab_pa, config_tables; ++ unsigned long cfg_tbl_pa = 0; ++ unsigned int cfg_tbl_len; ++ unsigned long systab_pa; + unsigned int nr_tables; + enum efi_type et; + bool efi_64; ++ int ret; + + et = efi_get_type(boot_params); + if (et == EFI_TYPE_64) +@@ -135,23 +138,11 @@ static acpi_physical_address efi_get_rsd + if (!systab_pa) + error("EFI support advertised, but unable to locate system table."); + +- /* Handle EFI bitness properly */ +- if (efi_64) { +- efi_system_table_64_t *stbl = (efi_system_table_64_t *)systab_pa; ++ ret = efi_get_conf_table(boot_params, &cfg_tbl_pa, &cfg_tbl_len); ++ if (ret || !cfg_tbl_pa) ++ error("EFI config table not found."); + +- config_tables = stbl->tables; +- nr_tables = stbl->nr_tables; +- } else { +- efi_system_table_32_t *stbl = (efi_system_table_32_t *)systab_pa; +- +- config_tables = stbl->tables; +- nr_tables = stbl->nr_tables; +- } +- +- if (!config_tables) +- error("EFI config tables not found."); +- +- return __efi_get_rsdp_addr(config_tables, nr_tables, efi_64); ++ return __efi_get_rsdp_addr(cfg_tbl_pa, cfg_tbl_len, efi_64); + #else + return 0; + #endif +--- a/arch/x86/boot/compressed/efi.c ++++ b/arch/x86/boot/compressed/efi.c +@@ -77,3 +77,46 @@ unsigned long efi_get_system_table(struc + + return sys_tbl_pa; + } ++ ++/** ++ * efi_get_conf_table - Given a pointer to boot_params, locate and return the physical ++ * address of EFI configuration table. ++ * ++ * @bp: pointer to boot_params ++ * @cfg_tbl_pa: location to store physical address of config table ++ * @cfg_tbl_len: location to store number of config table entries ++ * ++ * Return: 0 on success. On error, return params are left unchanged. ++ */ ++int efi_get_conf_table(struct boot_params *bp, unsigned long *cfg_tbl_pa, ++ unsigned int *cfg_tbl_len) ++{ ++ unsigned long sys_tbl_pa; ++ enum efi_type et; ++ int ret; ++ ++ if (!cfg_tbl_pa || !cfg_tbl_len) ++ return -EINVAL; ++ ++ sys_tbl_pa = efi_get_system_table(bp); ++ if (!sys_tbl_pa) ++ return -EINVAL; ++ ++ /* Handle EFI bitness properly */ ++ et = efi_get_type(bp); ++ if (et == EFI_TYPE_64) { ++ efi_system_table_64_t *stbl = (efi_system_table_64_t *)sys_tbl_pa; ++ ++ *cfg_tbl_pa = stbl->tables; ++ *cfg_tbl_len = stbl->nr_tables; ++ } else if (et == EFI_TYPE_32) { ++ efi_system_table_32_t *stbl = (efi_system_table_32_t *)sys_tbl_pa; ++ ++ *cfg_tbl_pa = stbl->tables; ++ *cfg_tbl_len = stbl->nr_tables; ++ } else { ++ return -EINVAL; ++ } ++ ++ return 0; ++} +--- a/arch/x86/boot/compressed/misc.h ++++ b/arch/x86/boot/compressed/misc.h +@@ -182,6 +182,8 @@ enum efi_type { + /* helpers for early EFI config table access */ + enum efi_type efi_get_type(struct boot_params *bp); + unsigned long efi_get_system_table(struct boot_params *bp); ++int efi_get_conf_table(struct boot_params *bp, unsigned long *cfg_tbl_pa, ++ unsigned int *cfg_tbl_len); + #else + static inline enum efi_type efi_get_type(struct boot_params *bp) + { +@@ -192,6 +194,13 @@ static inline unsigned long efi_get_syst + { + return 0; + } ++ ++static inline int efi_get_conf_table(struct boot_params *bp, ++ unsigned long *cfg_tbl_pa, ++ unsigned int *cfg_tbl_len) ++{ ++ return -ENOENT; ++} + #endif /* CONFIG_EFI */ + + #endif /* BOOT_COMPRESSED_MISC_H */ diff --git a/patches.suse/x86-compressed-acpi-Move-EFI-detection-to-helper b/patches.suse/x86-compressed-acpi-Move-EFI-detection-to-helper new file mode 100644 index 0000000..3f0a275 --- /dev/null +++ b/patches.suse/x86-compressed-acpi-Move-EFI-detection-to-helper @@ -0,0 +1,176 @@ +From: Michael Roth +Date: Wed, 9 Feb 2022 12:10:18 -0600 +Subject: x86/compressed/acpi: Move EFI detection to helper +Git-commit: 7c4146e8885512719a50b641e9277a1712e052ff +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +Future patches for SEV-SNP-validated CPUID will also require early +parsing of the EFI configuration. Incrementally move the related code +into a set of helpers that can be re-used for that purpose. + +First, carve out the functionality which determines the EFI environment +type the machine is booting on. + + [ bp: Massage commit message. ] + +Signed-off-by: Michael Roth +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220307213356.2797205-25-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/boot/compressed/Makefile | 1 + arch/x86/boot/compressed/acpi.c | 28 +++++++-------------- + arch/x86/boot/compressed/efi.c | 50 ++++++++++++++++++++++++++++++++++++++ + arch/x86/boot/compressed/misc.h | 16 ++++++++++++ + 4 files changed, 77 insertions(+), 18 deletions(-) + +--- a/arch/x86/boot/compressed/Makefile ++++ b/arch/x86/boot/compressed/Makefile +@@ -100,6 +100,7 @@ endif + vmlinux-objs-$(CONFIG_ACPI) += $(obj)/acpi.o + + vmlinux-objs-$(CONFIG_EFI_MIXED) += $(obj)/efi_thunk_$(BITS).o ++vmlinux-objs-$(CONFIG_EFI) += $(obj)/efi.o + efi-obj-$(CONFIG_EFI_STUB) = $(objtree)/drivers/firmware/efi/libstub/lib.a + + $(obj)/vmlinux: $(vmlinux-objs-y) $(efi-obj-y) FORCE +--- a/arch/x86/boot/compressed/acpi.c ++++ b/arch/x86/boot/compressed/acpi.c +@@ -87,7 +87,7 @@ static acpi_physical_address kexec_get_r + efi_system_table_64_t *systab; + struct efi_setup_data *esd; + struct efi_info *ei; +- char *sig; ++ enum efi_type et; + + esd = (struct efi_setup_data *)get_kexec_setup_data_addr(); + if (!esd) +@@ -98,10 +98,9 @@ static acpi_physical_address kexec_get_r + return 0; + } + +- ei = &boot_params->efi_info; +- sig = (char *)&ei->efi_loader_signature; +- if (strncmp(sig, EFI64_LOADER_SIGNATURE, 4)) { +- debug_putstr("Wrong kexec EFI loader signature.\n"); ++ et = efi_get_type(boot_params); ++ if (et != EFI_TYPE_64) { ++ debug_putstr("Unexpected kexec EFI environment (expected 64-bit EFI).\n"); + return 0; + } + +@@ -122,29 +121,22 @@ static acpi_physical_address efi_get_rsd + unsigned long systab, config_tables; + unsigned int nr_tables; + struct efi_info *ei; ++ enum efi_type et; + bool efi_64; +- char *sig; +- +- ei = &boot_params->efi_info; +- sig = (char *)&ei->efi_loader_signature; + +- if (!strncmp(sig, EFI64_LOADER_SIGNATURE, 4)) { ++ et = efi_get_type(boot_params); ++ if (et == EFI_TYPE_64) + efi_64 = true; +- } else if (!strncmp(sig, EFI32_LOADER_SIGNATURE, 4)) { ++ else if (et == EFI_TYPE_32) + efi_64 = false; +- } else { +- debug_putstr("Wrong EFI loader signature.\n"); ++ else + return 0; +- } + + /* Get systab from boot params. */ ++ ei = &boot_params->efi_info; + #ifdef CONFIG_X86_64 + systab = ei->efi_systab | ((__u64)ei->efi_systab_hi << 32); + #else +- if (ei->efi_systab_hi || ei->efi_memmap_hi) { +- debug_putstr("Error getting RSDP address: EFI system table located above 4GB.\n"); +- return 0; +- } + systab = ei->efi_systab; + #endif + if (!systab) +--- /dev/null ++++ b/arch/x86/boot/compressed/efi.c +@@ -0,0 +1,50 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Helpers for early access to EFI configuration table. ++ * ++ * Originally derived from arch/x86/boot/compressed/acpi.c ++ */ ++ ++#include "misc.h" ++#include ++#include ++ ++/** ++ * efi_get_type - Given a pointer to boot_params, determine the type of EFI environment. ++ * ++ * @bp: pointer to boot_params ++ * ++ * Return: EFI_TYPE_{32,64} for valid EFI environments, EFI_TYPE_NONE otherwise. ++ */ ++enum efi_type efi_get_type(struct boot_params *bp) ++{ ++ struct efi_info *ei; ++ enum efi_type et; ++ const char *sig; ++ ++ ei = &bp->efi_info; ++ sig = (char *)&ei->efi_loader_signature; ++ ++ if (!strncmp(sig, EFI64_LOADER_SIGNATURE, 4)) { ++ et = EFI_TYPE_64; ++ } else if (!strncmp(sig, EFI32_LOADER_SIGNATURE, 4)) { ++ et = EFI_TYPE_32; ++ } else { ++ debug_putstr("No EFI environment detected.\n"); ++ et = EFI_TYPE_NONE; ++ } ++ ++#ifndef CONFIG_X86_64 ++ /* ++ * Existing callers like acpi.c treat this case as an indicator to ++ * fall-through to non-EFI, rather than an error, so maintain that ++ * functionality here as well. ++ */ ++ if (ei->efi_systab_hi || ei->efi_memmap_hi) { ++ debug_putstr("EFI system table is located above 4GB and cannot be accessed.\n"); ++ et = EFI_TYPE_NONE; ++ } ++#endif ++ ++ return et; ++} +--- a/arch/x86/boot/compressed/misc.h ++++ b/arch/x86/boot/compressed/misc.h +@@ -172,4 +172,20 @@ void boot_stage2_vc(void); + + unsigned long sev_verify_cbit(unsigned long cr3); + ++enum efi_type { ++ EFI_TYPE_64, ++ EFI_TYPE_32, ++ EFI_TYPE_NONE, ++}; ++ ++#ifdef CONFIG_EFI ++/* helpers for early EFI config table access */ ++enum efi_type efi_get_type(struct boot_params *bp); ++#else ++static inline enum efi_type efi_get_type(struct boot_params *bp) ++{ ++ return EFI_TYPE_NONE; ++} ++#endif /* CONFIG_EFI */ ++ + #endif /* BOOT_COMPRESSED_MISC_H */ diff --git a/patches.suse/x86-compressed-acpi-Move-EFI-kexec-handling-into-common-code b/patches.suse/x86-compressed-acpi-Move-EFI-kexec-handling-into-common-code new file mode 100644 index 0000000..616468a --- /dev/null +++ b/patches.suse/x86-compressed-acpi-Move-EFI-kexec-handling-into-common-code @@ -0,0 +1,168 @@ +From: Michael Roth +Date: Thu, 24 Feb 2022 10:56:08 -0600 +Subject: x86/compressed/acpi: Move EFI kexec handling into common code +Git-commit: 824f37783189a48db914488fb41eba36ec57ebb7 +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +Future patches for SEV-SNP-validated CPUID will also require early +parsing of the EFI configuration. Incrementally move the related code +into a set of helpers that can be re-used for that purpose. + +In this instance, the current acpi.c kexec handling is mainly used to +get the alternative EFI config table address provided by kexec via a +setup_data entry of type SETUP_EFI. If not present, the code then falls +back to normal EFI config table address provided by EFI system table. +This would need to be done by all call-sites attempting to access the +EFI config table, so just have efi_get_conf_table() handle that +automatically. + +Signed-off-by: Michael Roth +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220307213356.2797205-29-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/boot/compressed/acpi.c | 59 ---------------------------------------- + arch/x86/boot/compressed/efi.c | 46 ++++++++++++++++++++++++++++++- + 2 files changed, 45 insertions(+), 60 deletions(-) + +--- a/arch/x86/boot/compressed/acpi.c ++++ b/arch/x86/boot/compressed/acpi.c +@@ -47,57 +47,6 @@ __efi_get_rsdp_addr(unsigned long cfg_tb + return 0; + } + +-/* EFI/kexec support is 64-bit only. */ +-#ifdef CONFIG_X86_64 +-static struct efi_setup_data *get_kexec_setup_data_addr(void) +-{ +- struct setup_data *data; +- u64 pa_data; +- +- pa_data = boot_params->hdr.setup_data; +- while (pa_data) { +- data = (struct setup_data *)pa_data; +- if (data->type == SETUP_EFI) +- return (struct efi_setup_data *)(pa_data + sizeof(struct setup_data)); +- +- pa_data = data->next; +- } +- return NULL; +-} +- +-static acpi_physical_address kexec_get_rsdp_addr(void) +-{ +- efi_system_table_64_t *systab; +- struct efi_setup_data *esd; +- struct efi_info *ei; +- enum efi_type et; +- +- esd = (struct efi_setup_data *)get_kexec_setup_data_addr(); +- if (!esd) +- return 0; +- +- if (!esd->tables) { +- debug_putstr("Wrong kexec SETUP_EFI data.\n"); +- return 0; +- } +- +- et = efi_get_type(boot_params); +- if (et != EFI_TYPE_64) { +- debug_putstr("Unexpected kexec EFI environment (expected 64-bit EFI).\n"); +- return 0; +- } +- +- /* Get systab from boot params. */ +- systab = (efi_system_table_64_t *)efi_get_system_table(boot_params); +- if (!systab) +- error("EFI system table not found in kexec boot_params."); +- +- return __efi_get_rsdp_addr((unsigned long)esd->tables, systab->nr_tables); +-} +-#else +-static acpi_physical_address kexec_get_rsdp_addr(void) { return 0; } +-#endif /* CONFIG_X86_64 */ +- + static acpi_physical_address efi_get_rsdp_addr(void) + { + #ifdef CONFIG_EFI +@@ -210,14 +159,6 @@ acpi_physical_address get_rsdp_addr(void + + pa = boot_params->acpi_rsdp_addr; + +- /* +- * Try to get EFI data from setup_data. This can happen when we're a +- * kexec'ed kernel and kexec(1) has passed all the required EFI info to +- * us. +- */ +- if (!pa) +- pa = kexec_get_rsdp_addr(); +- + if (!pa) + pa = efi_get_rsdp_addr(); + +--- a/arch/x86/boot/compressed/efi.c ++++ b/arch/x86/boot/compressed/efi.c +@@ -78,6 +78,46 @@ unsigned long efi_get_system_table(struc + return sys_tbl_pa; + } + ++/* ++ * EFI config table address changes to virtual address after boot, which may ++ * not be accessible for the kexec'd kernel. To address this, kexec provides ++ * the initial physical address via a struct setup_data entry, which is ++ * checked for here, along with some sanity checks. ++ */ ++static struct efi_setup_data *get_kexec_setup_data(struct boot_params *bp, ++ enum efi_type et) ++{ ++#ifdef CONFIG_X86_64 ++ struct efi_setup_data *esd = NULL; ++ struct setup_data *data; ++ u64 pa_data; ++ ++ pa_data = bp->hdr.setup_data; ++ while (pa_data) { ++ data = (struct setup_data *)pa_data; ++ if (data->type == SETUP_EFI) { ++ esd = (struct efi_setup_data *)(pa_data + sizeof(struct setup_data)); ++ break; ++ } ++ ++ pa_data = data->next; ++ } ++ ++ /* ++ * Original ACPI code falls back to attempting normal EFI boot in these ++ * cases, so maintain existing behavior by indicating non-kexec ++ * environment to the caller, but print them for debugging. ++ */ ++ if (esd && !esd->tables) { ++ debug_putstr("kexec EFI environment missing valid configuration table.\n"); ++ return NULL; ++ } ++ ++ return esd; ++#endif ++ return NULL; ++} ++ + /** + * efi_get_conf_table - Given a pointer to boot_params, locate and return the physical + * address of EFI configuration table. +@@ -106,8 +146,12 @@ int efi_get_conf_table(struct boot_param + et = efi_get_type(bp); + if (et == EFI_TYPE_64) { + efi_system_table_64_t *stbl = (efi_system_table_64_t *)sys_tbl_pa; ++ struct efi_setup_data *esd; ++ ++ /* kexec provides an alternative EFI conf table, check for it. */ ++ esd = get_kexec_setup_data(bp, et); + +- *cfg_tbl_pa = stbl->tables; ++ *cfg_tbl_pa = esd ? esd->tables : stbl->tables; + *cfg_tbl_len = stbl->nr_tables; + } else if (et == EFI_TYPE_32) { + efi_system_table_32_t *stbl = (efi_system_table_32_t *)sys_tbl_pa; diff --git a/patches.suse/x86-compressed-acpi-Move-EFI-system-table-lookup-to-helper b/patches.suse/x86-compressed-acpi-Move-EFI-system-table-lookup-to-helper new file mode 100644 index 0000000..21b56e0 --- /dev/null +++ b/patches.suse/x86-compressed-acpi-Move-EFI-system-table-lookup-to-helper @@ -0,0 +1,130 @@ +From: Michael Roth +Date: Thu, 24 Feb 2022 10:56:05 -0600 +Subject: x86/compressed/acpi: Move EFI system table lookup to helper +Git-commit: 58f3e6b71f42f99ab5d0ab26ddf6e7ee5631f5db +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +Future patches for SEV-SNP-validated CPUID will also require early +parsing of the EFI configuration. Incrementally move the related +code into a set of helpers that can be re-used for that purpose. + +Signed-off-by: Michael Roth +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220307213356.2797205-26-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/boot/compressed/acpi.c | 21 +++++++-------------- + arch/x86/boot/compressed/efi.c | 29 +++++++++++++++++++++++++++++ + arch/x86/boot/compressed/misc.h | 6 ++++++ + 3 files changed, 42 insertions(+), 14 deletions(-) + +--- a/arch/x86/boot/compressed/acpi.c ++++ b/arch/x86/boot/compressed/acpi.c +@@ -105,7 +105,7 @@ static acpi_physical_address kexec_get_r + } + + /* Get systab from boot params. */ +- systab = (efi_system_table_64_t *) (ei->efi_systab | ((__u64)ei->efi_systab_hi << 32)); ++ systab = (efi_system_table_64_t *)efi_get_system_table(boot_params); + if (!systab) + error("EFI system table not found in kexec boot_params."); + +@@ -118,9 +118,8 @@ static acpi_physical_address kexec_get_r + static acpi_physical_address efi_get_rsdp_addr(void) + { + #ifdef CONFIG_EFI +- unsigned long systab, config_tables; ++ unsigned long systab_pa, config_tables; + unsigned int nr_tables; +- struct efi_info *ei; + enum efi_type et; + bool efi_64; + +@@ -132,24 +131,18 @@ static acpi_physical_address efi_get_rsd + else + return 0; + +- /* Get systab from boot params. */ +- ei = &boot_params->efi_info; +-#ifdef CONFIG_X86_64 +- systab = ei->efi_systab | ((__u64)ei->efi_systab_hi << 32); +-#else +- systab = ei->efi_systab; +-#endif +- if (!systab) +- error("EFI system table not found."); ++ systab_pa = efi_get_system_table(boot_params); ++ if (!systab_pa) ++ error("EFI support advertised, but unable to locate system table."); + + /* Handle EFI bitness properly */ + if (efi_64) { +- efi_system_table_64_t *stbl = (efi_system_table_64_t *)systab; ++ efi_system_table_64_t *stbl = (efi_system_table_64_t *)systab_pa; + + config_tables = stbl->tables; + nr_tables = stbl->nr_tables; + } else { +- efi_system_table_32_t *stbl = (efi_system_table_32_t *)systab; ++ efi_system_table_32_t *stbl = (efi_system_table_32_t *)systab_pa; + + config_tables = stbl->tables; + nr_tables = stbl->nr_tables; +--- a/arch/x86/boot/compressed/efi.c ++++ b/arch/x86/boot/compressed/efi.c +@@ -48,3 +48,32 @@ enum efi_type efi_get_type(struct boot_p + + return et; + } ++ ++/** ++ * efi_get_system_table - Given a pointer to boot_params, retrieve the physical address ++ * of the EFI system table. ++ * ++ * @bp: pointer to boot_params ++ * ++ * Return: EFI system table address on success. On error, return 0. ++ */ ++unsigned long efi_get_system_table(struct boot_params *bp) ++{ ++ unsigned long sys_tbl_pa; ++ struct efi_info *ei; ++ enum efi_type et; ++ ++ /* Get systab from boot params. */ ++ ei = &bp->efi_info; ++#ifdef CONFIG_X86_64 ++ sys_tbl_pa = ei->efi_systab | ((__u64)ei->efi_systab_hi << 32); ++#else ++ sys_tbl_pa = ei->efi_systab; ++#endif ++ if (!sys_tbl_pa) { ++ debug_putstr("EFI system table not found."); ++ return 0; ++ } ++ ++ return sys_tbl_pa; ++} +--- a/arch/x86/boot/compressed/misc.h ++++ b/arch/x86/boot/compressed/misc.h +@@ -181,11 +181,17 @@ enum efi_type { + #ifdef CONFIG_EFI + /* helpers for early EFI config table access */ + enum efi_type efi_get_type(struct boot_params *bp); ++unsigned long efi_get_system_table(struct boot_params *bp); + #else + static inline enum efi_type efi_get_type(struct boot_params *bp) + { + return EFI_TYPE_NONE; + } ++ ++static inline unsigned long efi_get_system_table(struct boot_params *bp) ++{ ++ return 0; ++} + #endif /* CONFIG_EFI */ + + #endif /* BOOT_COMPRESSED_MISC_H */ diff --git a/patches.suse/x86-compressed-acpi-Move-EFI-vendor-table-lookup-to-helper b/patches.suse/x86-compressed-acpi-Move-EFI-vendor-table-lookup-to-helper new file mode 100644 index 0000000..c2db653 --- /dev/null +++ b/patches.suse/x86-compressed-acpi-Move-EFI-vendor-table-lookup-to-helper @@ -0,0 +1,243 @@ +From: Michael Roth +Date: Thu, 24 Feb 2022 10:56:07 -0600 +Subject: x86/compressed/acpi: Move EFI vendor table lookup to helper +Git-commit: dee602dd5d1489b5aa4651c561dfbe90eaee1589 +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +Future patches for SEV-SNP-validated CPUID will also require early +parsing of the EFI configuration. Incrementally move the related code +into a set of helpers that can be re-used for that purpose. + + [ bp: Unbreak unnecessarily broken lines. ] + +Signed-off-by: Michael Roth +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220307213356.2797205-28-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/boot/compressed/acpi.c | 68 +++++++++++++------------------------- + arch/x86/boot/compressed/efi.c | 70 ++++++++++++++++++++++++++++++++++++++++ + arch/x86/boot/compressed/misc.h | 13 +++++++ + 3 files changed, 106 insertions(+), 45 deletions(-) + +--- a/arch/x86/boot/compressed/acpi.c ++++ b/arch/x86/boot/compressed/acpi.c +@@ -20,48 +20,31 @@ + */ + struct mem_vector immovable_mem[MAX_NUMNODES*2]; + +-/* +- * Search EFI system tables for RSDP. If both ACPI_20_TABLE_GUID and +- * ACPI_TABLE_GUID are found, take the former, which has more features. +- */ + static acpi_physical_address +-__efi_get_rsdp_addr(unsigned long config_tables, unsigned int nr_tables, +- bool efi_64) ++__efi_get_rsdp_addr(unsigned long cfg_tbl_pa, unsigned int cfg_tbl_len) + { +- acpi_physical_address rsdp_addr = 0; +- + #ifdef CONFIG_EFI +- int i; ++ unsigned long rsdp_addr; ++ int ret; + +- /* Get EFI tables from systab. */ +- for (i = 0; i < nr_tables; i++) { +- acpi_physical_address table; +- efi_guid_t guid; +- +- if (efi_64) { +- efi_config_table_64_t *tbl = (efi_config_table_64_t *)config_tables + i; +- +- guid = tbl->guid; +- table = tbl->table; +- +- if (!IS_ENABLED(CONFIG_X86_64) && table >> 32) { +- debug_putstr("Error getting RSDP address: EFI config table located above 4GB.\n"); +- return 0; +- } +- } else { +- efi_config_table_32_t *tbl = (efi_config_table_32_t *)config_tables + i; +- +- guid = tbl->guid; +- table = tbl->table; +- } +- +- if (!(efi_guidcmp(guid, ACPI_TABLE_GUID))) +- rsdp_addr = table; +- else if (!(efi_guidcmp(guid, ACPI_20_TABLE_GUID))) +- return table; +- } ++ /* ++ * Search EFI system tables for RSDP. Preferred is ACPI_20_TABLE_GUID to ++ * ACPI_TABLE_GUID because it has more features. ++ */ ++ rsdp_addr = efi_find_vendor_table(boot_params, cfg_tbl_pa, cfg_tbl_len, ++ ACPI_20_TABLE_GUID); ++ if (rsdp_addr) ++ return (acpi_physical_address)rsdp_addr; ++ ++ /* No ACPI_20_TABLE_GUID found, fallback to ACPI_TABLE_GUID. */ ++ rsdp_addr = efi_find_vendor_table(boot_params, cfg_tbl_pa, cfg_tbl_len, ++ ACPI_TABLE_GUID); ++ if (rsdp_addr) ++ return (acpi_physical_address)rsdp_addr; ++ ++ debug_putstr("Error getting RSDP address.\n"); + #endif +- return rsdp_addr; ++ return 0; + } + + /* EFI/kexec support is 64-bit only. */ +@@ -109,7 +92,7 @@ static acpi_physical_address kexec_get_r + if (!systab) + error("EFI system table not found in kexec boot_params."); + +- return __efi_get_rsdp_addr((unsigned long)esd->tables, systab->nr_tables, true); ++ return __efi_get_rsdp_addr((unsigned long)esd->tables, systab->nr_tables); + } + #else + static acpi_physical_address kexec_get_rsdp_addr(void) { return 0; } +@@ -123,15 +106,10 @@ static acpi_physical_address efi_get_rsd + unsigned long systab_pa; + unsigned int nr_tables; + enum efi_type et; +- bool efi_64; + int ret; + + et = efi_get_type(boot_params); +- if (et == EFI_TYPE_64) +- efi_64 = true; +- else if (et == EFI_TYPE_32) +- efi_64 = false; +- else ++ if (et == EFI_TYPE_NONE) + return 0; + + systab_pa = efi_get_system_table(boot_params); +@@ -142,7 +120,7 @@ static acpi_physical_address efi_get_rsd + if (ret || !cfg_tbl_pa) + error("EFI config table not found."); + +- return __efi_get_rsdp_addr(cfg_tbl_pa, cfg_tbl_len, efi_64); ++ return __efi_get_rsdp_addr(cfg_tbl_pa, cfg_tbl_len); + #else + return 0; + #endif +--- a/arch/x86/boot/compressed/efi.c ++++ b/arch/x86/boot/compressed/efi.c +@@ -120,3 +120,73 @@ int efi_get_conf_table(struct boot_param + + return 0; + } ++ ++/* Get vendor table address/guid from EFI config table at the given index */ ++static int get_vendor_table(void *cfg_tbl, unsigned int idx, ++ unsigned long *vendor_tbl_pa, ++ efi_guid_t *vendor_tbl_guid, ++ enum efi_type et) ++{ ++ if (et == EFI_TYPE_64) { ++ efi_config_table_64_t *tbl_entry = (efi_config_table_64_t *)cfg_tbl + idx; ++ ++ if (!IS_ENABLED(CONFIG_X86_64) && tbl_entry->table >> 32) { ++ debug_putstr("Error: EFI config table entry located above 4GB.\n"); ++ return -EINVAL; ++ } ++ ++ *vendor_tbl_pa = tbl_entry->table; ++ *vendor_tbl_guid = tbl_entry->guid; ++ ++ } else if (et == EFI_TYPE_32) { ++ efi_config_table_32_t *tbl_entry = (efi_config_table_32_t *)cfg_tbl + idx; ++ ++ *vendor_tbl_pa = tbl_entry->table; ++ *vendor_tbl_guid = tbl_entry->guid; ++ } else { ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++/** ++ * efi_find_vendor_table - Given EFI config table, search it for the physical ++ * address of the vendor table associated with GUID. ++ * ++ * @bp: pointer to boot_params ++ * @cfg_tbl_pa: pointer to EFI configuration table ++ * @cfg_tbl_len: number of entries in EFI configuration table ++ * @guid: GUID of vendor table ++ * ++ * Return: vendor table address on success. On error, return 0. ++ */ ++unsigned long efi_find_vendor_table(struct boot_params *bp, ++ unsigned long cfg_tbl_pa, ++ unsigned int cfg_tbl_len, ++ efi_guid_t guid) ++{ ++ enum efi_type et; ++ unsigned int i; ++ ++ et = efi_get_type(bp); ++ if (et == EFI_TYPE_NONE) ++ return 0; ++ ++ for (i = 0; i < cfg_tbl_len; i++) { ++ unsigned long vendor_tbl_pa; ++ efi_guid_t vendor_tbl_guid; ++ int ret; ++ ++ ret = get_vendor_table((void *)cfg_tbl_pa, i, ++ &vendor_tbl_pa, ++ &vendor_tbl_guid, et); ++ if (ret) ++ return 0; ++ ++ if (!efi_guidcmp(guid, vendor_tbl_guid)) ++ return vendor_tbl_pa; ++ } ++ ++ return 0; ++} +--- a/arch/x86/boot/compressed/misc.h ++++ b/arch/x86/boot/compressed/misc.h +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -184,6 +185,10 @@ enum efi_type efi_get_type(struct boot_p + unsigned long efi_get_system_table(struct boot_params *bp); + int efi_get_conf_table(struct boot_params *bp, unsigned long *cfg_tbl_pa, + unsigned int *cfg_tbl_len); ++unsigned long efi_find_vendor_table(struct boot_params *bp, ++ unsigned long cfg_tbl_pa, ++ unsigned int cfg_tbl_len, ++ efi_guid_t guid); + #else + static inline enum efi_type efi_get_type(struct boot_params *bp) + { +@@ -201,6 +206,14 @@ static inline int efi_get_conf_table(str + { + return -ENOENT; + } ++ ++static inline unsigned long efi_find_vendor_table(struct boot_params *bp, ++ unsigned long cfg_tbl_pa, ++ unsigned int cfg_tbl_len, ++ efi_guid_t guid) ++{ ++ return 0; ++} + #endif /* CONFIG_EFI */ + + #endif /* BOOT_COMPRESSED_MISC_H */ diff --git a/patches.suse/x86-cpu-Add-CPU-model-numbers-for-Meteor-Lake.patch b/patches.suse/x86-cpu-Add-CPU-model-numbers-for-Meteor-Lake.patch new file mode 100644 index 0000000..e9f244a --- /dev/null +++ b/patches.suse/x86-cpu-Add-CPU-model-numbers-for-Meteor-Lake.patch @@ -0,0 +1,29 @@ +From: Tony Luck +Date: Wed, 24 Aug 2022 10:57:18 -0700 +Subject: x86/cpu: Add CPU model numbers for Meteor Lake +Git-commit: 5515d21c6817bc27b0b13c61edf22b09b58bc647 +Patch-mainline: 6.0 +References: jsc#PED-637 + +Add model numbers for client and mobile parts. + +Signed-off-by: Tony Luck +Signed-off-by: Dave Hansen +Link: https://lkml.kernel.org/r/20220824175718.232384-1-tony.luck@intel.com +Signed-off-by: Jiri Slaby (SUSE) +--- + arch/x86/include/asm/intel-family.h | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/arch/x86/include/asm/intel-family.h ++++ b/arch/x86/include/asm/intel-family.h +@@ -115,6 +115,9 @@ + #define INTEL_FAM6_RAPTORLAKE_P 0xBA + #define INTEL_FAM6_RAPTORLAKE_S 0xBF + ++#define INTEL_FAM6_METEORLAKE 0xAC ++#define INTEL_FAM6_METEORLAKE_L 0xAA ++ + /* "Small Core" Processors (Atom) */ + + #define INTEL_FAM6_ATOM_BONNELL 0x1C /* Diamondville, Pineview */ diff --git a/patches.suse/x86-cpu-Add-new-Raptor-Lake-CPU-model-number.patch b/patches.suse/x86-cpu-Add-new-Raptor-Lake-CPU-model-number.patch new file mode 100644 index 0000000..d7138ba --- /dev/null +++ b/patches.suse/x86-cpu-Add-new-Raptor-Lake-CPU-model-number.patch @@ -0,0 +1,49 @@ +From: Tony Luck +Date: Tue, 23 Aug 2022 10:48:19 -0700 +Subject: x86/cpu: Add new Raptor Lake CPU model number +Git-commit: ea902bcc1943f7539200ec464de3f54335588774 +Patch-mainline: 6.0-rc3 +References: jsc#PED-716 + +Note1: Model 0xB7 already claimed the "no suffix" #define for a regular +client part, so add (yet another) suffix "S" to distinguish this new +part from the earlier one. + +Note2: the RAPTORLAKE* and ALDERLAKE* processors are very similar from a +software enabling point of view. There are no known features that have +model-specific enabling and also differ between the two. In other words, +every single place that list *one* or more RAPTORLAKE* or ALDERLAKE* +processors should list all of them. + +Note3: This is being merged before there is an in-tree user. Merging +this provides an "anchor" so that the different folks can update their +subsystems (like perf) in parallel to use this define and test it. + +[ dhansen: add a note about why this has no in-tree users yet ] + +Signed-off-by: Tony Luck +Signed-off-by: Dave Hansen +Link: https://lkml.kernel.org/r/20220823174819.223941-1-tony.luck@intel.com +Signed-off-by: Jiri Slaby (SUSE) +--- + arch/x86/include/asm/intel-family.h | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/arch/x86/include/asm/intel-family.h ++++ b/arch/x86/include/asm/intel-family.h +@@ -27,6 +27,7 @@ + * _X - regular server parts + * _D - micro server parts + * _N,_P - other mobile parts ++ * _S - other client parts + * + * Historical OPTDIFFs: + * +@@ -112,6 +113,7 @@ + + #define INTEL_FAM6_RAPTORLAKE 0xB7 + #define INTEL_FAM6_RAPTORLAKE_P 0xBA ++#define INTEL_FAM6_RAPTORLAKE_S 0xBF + + /* "Small Core" Processors (Atom) */ + diff --git a/patches.suse/x86-cpu-amd-Enumerate-BTC_NO.patch b/patches.suse/x86-cpu-amd-Enumerate-BTC_NO.patch index a8dd008..ac89eb1 100644 --- a/patches.suse/x86-cpu-amd-Enumerate-BTC_NO.patch +++ b/patches.suse/x86-cpu-amd-Enumerate-BTC_NO.patch @@ -24,10 +24,10 @@ Signed-off-by: Borislav Petkov --- a/arch/x86/include/asm/cpufeatures.h +++ b/arch/x86/include/asm/cpufeatures.h -@@ -321,6 +321,7 @@ - #define X86_FEATURE_AMD_SSBD (13*32+24) /* "" Speculative Store Bypass Disable */ +@@ -322,6 +322,7 @@ #define X86_FEATURE_VIRT_SSBD (13*32+25) /* Virtualized Speculative Store Bypass Disable */ #define X86_FEATURE_AMD_SSB_NO (13*32+26) /* "" Speculative Store Bypass is fixed in hardware. */ + #define X86_FEATURE_CPPC (13*32+27) /* Collaborative Processor Performance Control */ +#define X86_FEATURE_BTC_NO (13*32+29) /* "" Not vulnerable to Branch Type Confusion */ /* Thermal and Power Management Leaf, CPUID level 0x00000006 (EAX), word 14 */ diff --git a/patches.suse/x86-cpufeatures-Add-AMD-Collaborative-Processor-Perf.patch b/patches.suse/x86-cpufeatures-Add-AMD-Collaborative-Processor-Perf.patch new file mode 100644 index 0000000..b6e9bd5 --- /dev/null +++ b/patches.suse/x86-cpufeatures-Add-AMD-Collaborative-Processor-Perf.patch @@ -0,0 +1,35 @@ +From: Huang Rui +Date: Fri, 24 Dec 2021 09:04:55 +0800 +Subject: x86/cpufeatures: Add AMD Collaborative Processor Performance Control + feature flag +Patch-mainline: v5.17-rc1 +Git-commit: d341db8f48ea43314f489921962c7f8f4ec27239 +References: jsc#PED-1408 + +Add Collaborative Processor Performance Control feature flag for AMD +processors. + +This feature flag will be used on the following AMD P-State driver. The +AMD P-State driver has two approaches to implement the frequency control +behavior. That depends on the CPU hardware implementation. One is "Full +MSR Support" and another is "Shared Memory Support". The feature flag +indicates the current processors with "Full MSR Support". + +Acked-by: Borislav Petkov +Signed-off-by: Huang Rui +Signed-off-by: Rafael J. Wysocki +Acked-by: Lee, Chun-Yi +--- + arch/x86/include/asm/cpufeatures.h | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/x86/include/asm/cpufeatures.h ++++ b/arch/x86/include/asm/cpufeatures.h +@@ -315,6 +315,7 @@ + #define X86_FEATURE_AMD_SSBD (13*32+24) /* "" Speculative Store Bypass Disable */ + #define X86_FEATURE_VIRT_SSBD (13*32+25) /* Virtualized Speculative Store Bypass Disable */ + #define X86_FEATURE_AMD_SSB_NO (13*32+26) /* "" Speculative Store Bypass is fixed in hardware. */ ++#define X86_FEATURE_CPPC (13*32+27) /* Collaborative Processor Performance Control */ + + /* Thermal and Power Management Leaf, CPUID level 0x00000006 (EAX), word 14 */ + #define X86_FEATURE_DTHERM (14*32+ 0) /* Digital Thermal Sensor */ diff --git a/patches.suse/x86-ftrace-Use-alternative-RET-encoding.patch b/patches.suse/x86-ftrace-Use-alternative-RET-encoding.patch deleted file mode 100644 index 2b13a93..0000000 --- a/patches.suse/x86-ftrace-Use-alternative-RET-encoding.patch +++ /dev/null @@ -1,37 +0,0 @@ -From: Peter Zijlstra -Date: Tue, 14 Jun 2022 23:15:40 +0200 -Subject: x86/ftrace: Use alternative RET encoding -Git-commit: 1f001e9da6bbf482311e45e48f53c2bd2179e59c -Patch-mainline: v5.19-rc7 -References: bsc#1199657 CVE-2022-29900 CVE-2022-29901 - -Use the return thunk in ftrace trampolines, if needed. - -Signed-off-by: Peter Zijlstra (Intel) -Signed-off-by: Borislav Petkov -Reviewed-by: Josh Poimboeuf -Signed-off-by: Borislav Petkov ---- - arch/x86/kernel/ftrace.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - ---- a/arch/x86/kernel/ftrace.c -+++ b/arch/x86/kernel/ftrace.c -@@ -308,7 +308,7 @@ union ftrace_op_code_union { - } __attribute__((packed)); - }; - --#define RET_SIZE 1 + IS_ENABLED(CONFIG_SLS) -+#define RET_SIZE (IS_ENABLED(CONFIG_RETPOLINE) ? 5 : 1 + IS_ENABLED(CONFIG_SLS)) - - static unsigned long - create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size) -@@ -364,6 +364,8 @@ create_trampoline(struct ftrace_ops *ops - goto fail; - - ip = trampoline + size; -+ if (cpu_feature_enabled(X86_FEATURE_RETHUNK)) -+ __text_gen_insn(ip, JMP32_INSN_OPCODE, ip, &__x86_return_thunk, JMP32_INSN_SIZE); - - /* The trampoline ends with ret(q) */ - retq = (unsigned long)ftrace_stub; diff --git a/patches.suse/x86-ftrace-use-alternative-ret-encoding.patch b/patches.suse/x86-ftrace-use-alternative-ret-encoding.patch new file mode 100644 index 0000000..d480c1a --- /dev/null +++ b/patches.suse/x86-ftrace-use-alternative-ret-encoding.patch @@ -0,0 +1,43 @@ +From: Peter Zijlstra +Date: Tue, 14 Jun 2022 23:15:40 +0200 +Subject: x86/ftrace: Use alternative RET encoding +Git-commit: 1f001e9da6bbf482311e45e48f53c2bd2179e59c +Patch-mainline: v5.19-rc7 +References: bsc#1203969, bsc#1199657 CVE-2022-29900 CVE-2022-29901 + +Use the return thunk in ftrace trampolines, if needed. + +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Borislav Petkov +Reviewed-by: Josh Poimboeuf +Signed-off-by: Borislav Petkov +--- + arch/x86/kernel/ftrace.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c +index 5b4efc927d80..24b9fa89aa27 100644 +--- a/arch/x86/kernel/ftrace.c ++++ b/arch/x86/kernel/ftrace.c +@@ -301,7 +301,7 @@ union ftrace_op_code_union { + } __attribute__((packed)); + }; + +-#define RET_SIZE 1 + IS_ENABLED(CONFIG_SLS) ++#define RET_SIZE (IS_ENABLED(CONFIG_RETPOLINE) ? 5 : 1 + IS_ENABLED(CONFIG_SLS)) + + static unsigned long + create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size) +@@ -357,7 +357,10 @@ create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size) + goto fail; + + ip = trampoline + size; +- memcpy(ip, retq, RET_SIZE); ++ if (cpu_feature_enabled(X86_FEATURE_RETHUNK)) ++ __text_gen_insn(ip, JMP32_INSN_OPCODE, ip, &__x86_return_thunk, JMP32_INSN_SIZE); ++ else ++ memcpy(ip, retq, sizeof(retq)); + + /* No need to test direct calls on created trampolines */ + if (ops->flags & FTRACE_OPS_FL_SAVE_REGS) { + diff --git a/patches.suse/x86-head-64-Re-enable-stack-protection b/patches.suse/x86-head-64-Re-enable-stack-protection new file mode 100644 index 0000000..7f3de3b --- /dev/null +++ b/patches.suse/x86-head-64-Re-enable-stack-protection @@ -0,0 +1,151 @@ +From: Michael Roth +Date: Wed, 9 Feb 2022 12:10:17 -0600 +Subject: x86/head/64: Re-enable stack protection +Git-commit: 469693d8f62299709e8ba56d8fb3da9ea990213c +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +Due to + + 103a4908ad4d ("x86/head/64: Disable stack protection for head$(BITS).o") + +kernel/head{32,64}.c are compiled with -fno-stack-protector to allow +a call to set_bringup_idt_handler(), which would otherwise have stack +protection enabled with CONFIG_STACKPROTECTOR_STRONG. + +While sufficient for that case, there may still be issues with calls to +any external functions that were compiled with stack protection enabled +that in-turn make stack-protected calls, or if the exception handlers +set up by set_bringup_idt_handler() make calls to stack-protected +functions. + +Subsequent patches for SEV-SNP CPUID validation support will introduce +both such cases. Attempting to disable stack protection for everything +in scope to address that is prohibitive since much of the code, like the +SEV-ES #VC handler, is shared code that remains in use after boot and +could benefit from having stack protection enabled. Attempting to inline +calls is brittle and can quickly balloon out to library/helper code +where that's not really an option. + +Instead, re-enable stack protection for head32.c/head64.c, and make the +appropriate changes to ensure the segment used for the stack canary is +initialized in advance of any stack-protected C calls. + +For head64.c: + +- The BSP will enter from startup_64() and call into C code + (startup_64_setup_env()) shortly after setting up the stack, which + may result in calls to stack-protected code. Set up %gs early to allow + for this safely. +- APs will enter from secondary_startup_64*(), and %gs will be set up + soon after. There is one call to C code prior to %gs being setup + (__startup_secondary_64()), but it is only to fetch 'sme_me_mask' + global, so just load 'sme_me_mask' directly instead, and remove the + now-unused __startup_secondary_64() function. + +For head32.c: + +- BSPs/APs will set %fs to __BOOT_DS prior to any C calls. In recent + kernels, the compiler is configured to access the stack canary at + %fs:__stack_chk_guard [1], which overlaps with the initial per-cpu + '__stack_chk_guard' variable in the initial/"master" .data..percpu + area. This is sufficient to allow access to the canary for use + during initial startup, so no changes are needed there. + +[1] 3fb0fdb3bbe7 ("x86/stackprotector/32: Make the canary into a regular percpu variable") + + [ bp: Massage commit message. ] + +Suggested-by: Joerg Roedel #for 64-bit %gs set up +Signed-off-by: Michael Roth +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220307213356.2797205-24-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/include/asm/setup.h | 1 - + arch/x86/kernel/Makefile | 2 -- + arch/x86/kernel/head64.c | 9 --------- + arch/x86/kernel/head_64.S | 24 +++++++++++++++++++++--- + 4 files changed, 21 insertions(+), 15 deletions(-) + +--- a/arch/x86/include/asm/setup.h ++++ b/arch/x86/include/asm/setup.h +@@ -49,7 +49,6 @@ extern unsigned long saved_video_mode; + extern void reserve_standard_io_resources(void); + extern void i386_reserve_resources(void); + extern unsigned long __startup_64(unsigned long physaddr, struct boot_params *bp); +-extern unsigned long __startup_secondary_64(void); + extern void startup_64_setup_env(unsigned long physbase); + extern void early_setup_idt(void); + extern void __init do_early_exception(struct pt_regs *regs, int trapnr); +--- a/arch/x86/kernel/Makefile ++++ b/arch/x86/kernel/Makefile +@@ -46,8 +46,6 @@ endif + # non-deterministic coverage. + KCOV_INSTRUMENT := n + +-CFLAGS_head$(BITS).o += -fno-stack-protector +- + CFLAGS_irq.o := -I $(srctree)/$(src)/../include/asm/trace + + obj-y := process_$(BITS).o signal.o +--- a/arch/x86/kernel/head64.c ++++ b/arch/x86/kernel/head64.c +@@ -318,15 +318,6 @@ unsigned long __head __startup_64(unsign + return sme_postprocess_startup(bp, pmd); + } + +-unsigned long __startup_secondary_64(void) +-{ +- /* +- * Return the SME encryption mask (if SME is active) to be used as a +- * modifier for the initial pgdir entry programmed into CR3. +- */ +- return sme_get_me_mask(); +-} +- + /* Wipe all early page tables except for the kernel symbol map */ + static void __init reset_early_page_tables(void) + { +--- a/arch/x86/kernel/head_64.S ++++ b/arch/x86/kernel/head_64.S +@@ -65,6 +65,22 @@ SYM_CODE_START_NOALIGN(startup_64) + leaq (__end_init_task - FRAME_SIZE)(%rip), %rsp + + leaq _text(%rip), %rdi ++ ++ /* ++ * initial_gs points to initial fixed_percpu_data struct with storage for ++ * the stack protector canary. Global pointer fixups are needed at this ++ * stage, so apply them as is done in fixup_pointer(), and initialize %gs ++ * such that the canary can be accessed at %gs:40 for subsequent C calls. ++ */ ++ movl $MSR_GS_BASE, %ecx ++ movq initial_gs(%rip), %rax ++ movq $_text, %rdx ++ subq %rdx, %rax ++ addq %rdi, %rax ++ movq %rax, %rdx ++ shrq $32, %rdx ++ wrmsr ++ + pushq %rsi + call startup_64_setup_env + popq %rsi +@@ -145,9 +161,11 @@ SYM_INNER_LABEL(secondary_startup_64_no_ + * Retrieve the modifier (SME encryption mask if SME is active) to be + * added to the initial pgdir entry that will be programmed into CR3. + */ +- pushq %rsi +- call __startup_secondary_64 +- popq %rsi ++#ifdef CONFIG_AMD_MEM_ENCRYPT ++ movq sme_me_mask, %rax ++#else ++ xorq %rax, %rax ++#endif + + /* Form the CR3 value being sure to include the CR3 modifier */ + addq $(init_top_pgt - __START_KERNEL_map), %rax diff --git a/patches.suse/x86-ibt-ftrace-make-function-graph-play-nice.patch b/patches.suse/x86-ibt-ftrace-make-function-graph-play-nice.patch new file mode 100644 index 0000000..ecc8528 --- /dev/null +++ b/patches.suse/x86-ibt-ftrace-make-function-graph-play-nice.patch @@ -0,0 +1,56 @@ +From: Peter Zijlstra +Date: Tue, 8 Mar 2022 16:30:31 +0100 +Subject: x86/ibt,ftrace: Make function-graph play nice +Git-commit: e52fc2cf3f662828cc0d51c4b73bed73ad275fce +Patch-mainline: v5.18-rc1 +References: bsc#1203969 + +Return trampoline must not use indirect branch to return; while this +preserves the RSB, it is fundamentally incompatible with IBT. Instead +use a retpoline like ROP gadget that defeats IBT while not unbalancing +the RSB. + +And since ftrace_stub is no longer a plain RET, don't use it to copy +from. Since RET is a trivial instruction, poke it directly. + +Signed-off-by: Peter Zijlstra (Intel) +Acked-by: Josh Poimboeuf +Link: https://lore.kernel.org/r/20220308154318.347296408@infradead.org + [ bp: Do not backport the ftrace_64.S bits for now as we don't have IBT. ] +Acked-by: Borislav Petkov +--- + arch/x86/kernel/ftrace.c | 9 ++------- + 2 files changed, 19 insertions(+), 11 deletions(-) + +diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c +index 7cc540e6de0c..1e31c7d21597 100644 +--- a/arch/x86/kernel/ftrace.c ++++ b/arch/x86/kernel/ftrace.c +@@ -316,12 +316,12 @@ create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size) + unsigned long offset; + unsigned long npages; + unsigned long size; +- unsigned long retq; + unsigned long *ptr; + void *trampoline; + void *ip; + /* 48 8b 15 is movq (%rip), %rdx */ + unsigned const char op_ref[] = { 0x48, 0x8b, 0x15 }; ++ unsigned const char retq[] = { RET_INSN_OPCODE, INT3_INSN_OPCODE }; + union ftrace_op_code_union op_ptr; + int ret; + +@@ -359,12 +359,7 @@ create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size) + goto fail; + + ip = trampoline + size; +- +- /* The trampoline ends with ret(q) */ +- retq = (unsigned long)ftrace_stub; +- ret = copy_from_kernel_nofault(ip, (void *)retq, RET_SIZE); +- if (WARN_ON(ret < 0)) +- goto fail; ++ memcpy(ip, retq, RET_SIZE); + + /* No need to test direct calls on created trampolines */ + if (ops->flags & FTRACE_OPS_FL_SAVE_REGS) { diff --git a/patches.suse/x86-kernel-Mark-the-.bss.decrypted-section-as-shared-in-the-RMP- b/patches.suse/x86-kernel-Mark-the-.bss.decrypted-section-as-shared-in-the-RMP- new file mode 100644 index 0000000..6888299 --- /dev/null +++ b/patches.suse/x86-kernel-Mark-the-.bss.decrypted-section-as-shared-in-the-RMP- @@ -0,0 +1,48 @@ +From: Brijesh Singh +Date: Wed, 9 Feb 2022 12:10:13 -0600 +Subject: x86/kernel: Mark the .bss..decrypted section as shared in the RMP + table +Git-commit: efac0eedfab515e523cde5cb7a62289eb2ee58f8 +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +The encryption attribute for the .bss..decrypted section is cleared in the +initial page table build. This is because the section contains the data +that need to be shared between the guest and the hypervisor. + +When SEV-SNP is active, just clearing the encryption attribute in the +page table is not enough. The page state needs to be updated in the RMP +table. + +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220307213356.2797205-20-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/kernel/head64.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/arch/x86/kernel/head64.c ++++ b/arch/x86/kernel/head64.c +@@ -143,7 +143,20 @@ static unsigned long sme_postprocess_sta + if (sme_get_me_mask()) { + vaddr = (unsigned long)__start_bss_decrypted; + vaddr_end = (unsigned long)__end_bss_decrypted; ++ + for (; vaddr < vaddr_end; vaddr += PMD_SIZE) { ++ /* ++ * On SNP, transition the page to shared in the RMP table so that ++ * it is consistent with the page table attribute change. ++ * ++ * __start_bss_decrypted has a virtual address in the high range ++ * mapping (kernel .text). PVALIDATE, by way of ++ * early_snp_set_memory_shared(), requires a valid virtual ++ * address but the kernel is currently running off of the identity ++ * mapping so use __pa() to get a *currently* valid virtual address. ++ */ ++ early_snp_set_memory_shared(__pa(vaddr), __pa(vaddr), PTRS_PER_PMD); ++ + i = pmd_index(vaddr); + pmd[i] -= sme_get_me_mask(); + } diff --git a/patches.suse/x86-kernel-Validate-ROM-memory-before-accessing-when-SEV-SNP-is- b/patches.suse/x86-kernel-Validate-ROM-memory-before-accessing-when-SEV-SNP-is- new file mode 100644 index 0000000..631b698 --- /dev/null +++ b/patches.suse/x86-kernel-Validate-ROM-memory-before-accessing-when-SEV-SNP-is- @@ -0,0 +1,61 @@ +From: Brijesh Singh +Date: Wed, 9 Feb 2022 12:10:14 -0600 +Subject: x86/kernel: Validate ROM memory before accessing when SEV-SNP is + active +Git-commit: 9704c07bf9f7682a83aec4e66f2d9154dbd8577f +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +probe_roms() accesses the memory range (0xc0000 - 0x10000) to probe +various ROMs. The memory range is not part of the E820 system RAM range. +The memory range is mapped as private (i.e encrypted) in the page table. + +When SEV-SNP is active, all the private memory must be validated before +accessing. The ROM range was not part of E820 map, so the guest BIOS +did not validate it. An access to invalidated memory will cause a +exception yet, so validate the ROM memory regions before it is accessed. + + [ bp: Massage commit message. ] + +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220307213356.2797205-21-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/kernel/probe_roms.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +--- a/arch/x86/kernel/probe_roms.c ++++ b/arch/x86/kernel/probe_roms.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + + static struct resource system_rom_resource = { + .name = "System ROM", +@@ -197,11 +198,21 @@ static int __init romchecksum(const unsi + + void __init probe_roms(void) + { +- const unsigned char *rom; + unsigned long start, length, upper; ++ const unsigned char *rom; + unsigned char c; + int i; + ++ /* ++ * The ROM memory range is not part of the e820 table and is therefore not ++ * pre-validated by BIOS. The kernel page table maps the ROM region as encrypted ++ * memory, and SNP requires encrypted memory to be validated before access. ++ * Do that here. ++ */ ++ snp_prep_memory(video_rom_resource.start, ++ ((system_rom_resource.end + 1) - video_rom_resource.start), ++ SNP_PAGE_STATE_PRIVATE); ++ + /* video rom */ + upper = adapter_rom_resources[0].start; + for (start = video_rom_resource.start; start < upper; start += 2048) { diff --git a/patches.suse/x86-kexec-fix-memory-leak-of-elf-header-buffer.patch b/patches.suse/x86-kexec-fix-memory-leak-of-elf-header-buffer.patch new file mode 100644 index 0000000..e67f5c1 --- /dev/null +++ b/patches.suse/x86-kexec-fix-memory-leak-of-elf-header-buffer.patch @@ -0,0 +1,85 @@ +From b3e34a47f98974d0844444c5121aaff123004e57 Mon Sep 17 00:00:00 2001 +From: Baoquan He +Date: Wed, 23 Feb 2022 19:32:24 +0800 +Subject: [PATCH] x86/kexec: fix memory leak of elf header buffer + +References: bsc#1196444 +Patch-mainline: v5.19-rc1 +Git-commit: b3e34a47f98974d0844444c5121aaff123004e57 + +This is reported by kmemleak detector: + +unreferenced object 0xffffc900002a9000 (size 4096): + comm "kexec", pid 14950, jiffies 4295110793 (age 373.951s) + hex dump (first 32 bytes): + 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 .ELF............ + 04 00 3e 00 01 00 00 00 00 00 00 00 00 00 00 00 ..>............. + backtrace: + [<0000000016a8ef9f>] __vmalloc_node_range+0x101/0x170 + [<000000002b66b6c0>] __vmalloc_node+0xb4/0x160 + [<00000000ad40107d>] crash_prepare_elf64_headers+0x8e/0xcd0 + [<0000000019afff23>] crash_load_segments+0x260/0x470 + [<0000000019ebe95c>] bzImage64_load+0x814/0xad0 + [<0000000093e16b05>] arch_kexec_kernel_image_load+0x1be/0x2a0 + [<000000009ef2fc88>] kimage_file_alloc_init+0x2ec/0x5a0 + [<0000000038f5a97a>] __do_sys_kexec_file_load+0x28d/0x530 + [<0000000087c19992>] do_syscall_64+0x3b/0x90 + [<0000000066e063a4>] entry_SYSCALL_64_after_hwframe+0x44/0xae + +In crash_prepare_elf64_headers(), a buffer is allocated via vmalloc() to +store elf headers. While it's not freed back to system correctly when +kdump kernel is reloaded or unloaded. Then memory leak is caused. Fix it +by introducing x86 specific function arch_kimage_file_post_load_cleanup(), +and freeing the buffer there. + +And also remove the incorrect elf header buffer freeing code. Before +calling arch specific kexec_file loading function, the image instance has +been initialized. So 'image->elf_headers' must be NULL. It doesn't make +sense to free the elf header buffer in the place. + +Three different people have reported three bugs about the memory leak on +x86_64 inside Redhat. + +Link: https://lkml.kernel.org/r/20220223113225.63106-2-bhe@redhat.com +Signed-off-by: Baoquan He +Acked-by: Dave Young +Cc: +Signed-off-by: Andrew Morton +Acked-by: Michal Suchanek +--- + arch/x86/kernel/machine_kexec_64.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c +index 566bb8e17149..0611fd83858e 100644 +--- a/arch/x86/kernel/machine_kexec_64.c ++++ b/arch/x86/kernel/machine_kexec_64.c +@@ -376,9 +376,6 @@ void machine_kexec(struct kimage *image) + #ifdef CONFIG_KEXEC_FILE + void *arch_kexec_kernel_image_load(struct kimage *image) + { +- vfree(image->elf_headers); +- image->elf_headers = NULL; +- + if (!image->fops || !image->fops->load) + return ERR_PTR(-ENOEXEC); + +@@ -514,6 +511,15 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi, + (int)ELF64_R_TYPE(rel[i].r_info), value); + return -ENOEXEC; + } ++ ++int arch_kimage_file_post_load_cleanup(struct kimage *image) ++{ ++ vfree(image->elf_headers); ++ image->elf_headers = NULL; ++ image->elf_headers_sz = 0; ++ ++ return kexec_image_post_load_cleanup_default(image); ++} + #endif /* CONFIG_KEXEC_FILE */ + + static int +-- +2.35.3 + diff --git a/patches.suse/x86-mce-Retrieve-poison-range-from-hardware.patch b/patches.suse/x86-mce-Retrieve-poison-range-from-hardware.patch new file mode 100644 index 0000000..146731d --- /dev/null +++ b/patches.suse/x86-mce-Retrieve-poison-range-from-hardware.patch @@ -0,0 +1,66 @@ +From: Jane Chu +Date: Fri, 26 Aug 2022 17:38:51 -0600 +Subject: x86/mce: Retrieve poison range from hardware +Patch-mainline: Queued in subsystem maintainer repository +Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git +Git-commit: f9781bb18ed828e7b83b7bac4a4ad7cd497ee7d7 +References: jsc#PED-1408 + +When memory poison consumption machine checks fire, MCE notifier +handlers like nfit_handle_mce() record the impacted physical address +range which is reported by the hardware in the MCi_MISC MSR. The error +information includes data about blast radius, i.e. how many cachelines +did the hardware determine are impacted. A recent change + + 7917f9cdb503 ("acpi/nfit: rely on mce->misc to determine poison granularity") + +updated nfit_handle_mce() to stop hard coding the blast radius value of +1 cacheline, and instead rely on the blast radius reported in 'struct +mce' which can be up to 4K (64 cachelines). + +It turns out that apei_mce_report_mem_error() had a similar problem in +that it hard coded a blast radius of 4K rather than reading the blast +radius from the error information. Fix apei_mce_report_mem_error() to +convey the proper poison granularity. + +Signed-off-by: Jane Chu +Signed-off-by: Borislav Petkov +Reviewed-by: Dan Williams +Reviewed-by: Ingo Molnar +Link: https://lore.kernel.org/r/7ed50fd8-521e-cade-77b1-738b8bfb8502@oracle.com +Link: https://lore.kernel.org/r/20220826233851.1319100-1-jane.chu@oracle.com +Acked-by: Lee, Chun-Yi +--- + arch/x86/kernel/cpu/mce/apei.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +--- a/arch/x86/kernel/cpu/mce/apei.c ++++ b/arch/x86/kernel/cpu/mce/apei.c +@@ -29,15 +29,26 @@ + void apei_mce_report_mem_error(int severity, struct cper_sec_mem_err *mem_err) + { + struct mce m; ++ int lsb; + + if (!(mem_err->validation_bits & CPER_MEM_VALID_PA)) + return; + ++ /* ++ * Even if the ->validation_bits are set for address mask, ++ * to be extra safe, check and reject an error radius '0', ++ * and fall back to the default page size. ++ */ ++ if (mem_err->validation_bits & CPER_MEM_VALID_PA_MASK) ++ lsb = find_first_bit((void *)&mem_err->physical_addr_mask, PAGE_SHIFT); ++ else ++ lsb = PAGE_SHIFT; ++ + mce_setup(&m); + m.bank = -1; + /* Fake a memory read error with unknown channel */ + m.status = MCI_STATUS_VAL | MCI_STATUS_EN | MCI_STATUS_ADDRV | MCI_STATUS_MISCV | 0x9f; +- m.misc = (MCI_MISC_ADDR_PHYS << 6) | PAGE_SHIFT; ++ m.misc = (MCI_MISC_ADDR_PHYS << 6) | lsb; + + if (severity >= GHES_SEV_RECOVERABLE) + m.status |= MCI_STATUS_UC; diff --git a/patches.suse/x86-mm-Extend-cc_attr-to-include-AMD-SEV-SNP b/patches.suse/x86-mm-Extend-cc_attr-to-include-AMD-SEV-SNP new file mode 100644 index 0000000..b08e42e --- /dev/null +++ b/patches.suse/x86-mm-Extend-cc_attr-to-include-AMD-SEV-SNP @@ -0,0 +1,77 @@ +From: Brijesh Singh +Date: Thu, 24 Feb 2022 10:55:49 -0600 +Subject: x86/mm: Extend cc_attr to include AMD SEV-SNP +Git-commit: f742b90e61bb53b27771f64bdae05db03a6ab1f2 +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +The CC_ATTR_GUEST_SEV_SNP can be used by the guest to query whether the +SNP (Secure Nested Paging) feature is active. + +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220307213356.2797205-10-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/coco/core.c | 3 +++ + arch/x86/include/asm/msr-index.h | 2 ++ + arch/x86/mm/mem_encrypt.c | 4 ++++ + include/linux/cc_platform.h | 8 ++++++++ + 4 files changed, 17 insertions(+) + +--- a/arch/x86/coco/core.c ++++ b/arch/x86/coco/core.c +@@ -57,6 +57,9 @@ static bool amd_cc_platform_has(enum cc_ + return (sev_status & MSR_AMD64_SEV_ENABLED) && + !(sev_status & MSR_AMD64_SEV_ES_ENABLED); + ++ case CC_ATTR_GUEST_SEV_SNP: ++ return sev_status & MSR_AMD64_SEV_SNP_ENABLED; ++ + default: + return false; + } +--- a/arch/x86/include/asm/msr-index.h ++++ b/arch/x86/include/asm/msr-index.h +@@ -482,8 +482,10 @@ + #define MSR_AMD64_SEV 0xc0010131 + #define MSR_AMD64_SEV_ENABLED_BIT 0 + #define MSR_AMD64_SEV_ES_ENABLED_BIT 1 ++#define MSR_AMD64_SEV_SNP_ENABLED_BIT 2 + #define MSR_AMD64_SEV_ENABLED BIT_ULL(MSR_AMD64_SEV_ENABLED_BIT) + #define MSR_AMD64_SEV_ES_ENABLED BIT_ULL(MSR_AMD64_SEV_ES_ENABLED_BIT) ++#define MSR_AMD64_SEV_SNP_ENABLED BIT_ULL(MSR_AMD64_SEV_SNP_ENABLED_BIT) + + #define MSR_AMD64_VIRT_SPEC_CTRL 0xc001011f + +--- a/arch/x86/mm/mem_encrypt.c ++++ b/arch/x86/mm/mem_encrypt.c +@@ -62,6 +62,10 @@ static void print_mem_encrypt_feature_in + if (cc_platform_has(CC_ATTR_GUEST_STATE_ENCRYPT)) + pr_cont(" SEV-ES"); + ++ /* Secure Nested Paging */ ++ if (cc_platform_has(CC_ATTR_GUEST_SEV_SNP)) ++ pr_cont(" SEV-SNP"); ++ + pr_cont("\n"); + } + +--- a/include/linux/cc_platform.h ++++ b/include/linux/cc_platform.h +@@ -72,6 +72,14 @@ enum cc_attr { + * Examples include TDX guest & SEV. + */ + CC_ATTR_GUEST_UNROLL_STRING_IO, ++ ++ /** ++ * @CC_ATTR_SEV_SNP: Guest SNP is active. ++ * ++ * The platform/OS is running as a guest/virtual machine and actively ++ * using AMD SEV-SNP features. ++ */ ++ CC_ATTR_GUEST_SEV_SNP, + }; + + #ifdef CONFIG_ARCH_HAS_CC_PLATFORM diff --git a/patches.suse/x86-mm-Validate-memory-when-changing-the-C-bit b/patches.suse/x86-mm-Validate-memory-when-changing-the-C-bit new file mode 100644 index 0000000..7ccb728 --- /dev/null +++ b/patches.suse/x86-mm-Validate-memory-when-changing-the-C-bit @@ -0,0 +1,297 @@ +From: Brijesh Singh +Date: Thu, 24 Feb 2022 10:56:01 -0600 +Subject: x86/mm: Validate memory when changing the C-bit +Git-commit: dc3f3d2474b80eaee8be89f4c5eb344f10648f42 +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +Add the needed functionality to change pages state from shared +to private and vice-versa using the Page State Change VMGEXIT as +documented in the GHCB spec. + +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220307213356.2797205-22-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/include/asm/sev-common.h | 22 ++++ + arch/x86/include/asm/sev.h | 4 + arch/x86/include/uapi/asm/svm.h | 2 + arch/x86/kernel/sev.c | 168 ++++++++++++++++++++++++++++++++++++++ + arch/x86/mm/mem_encrypt_amd.c | 13 ++ + 5 files changed, 209 insertions(+) + +--- a/arch/x86/include/asm/sev-common.h ++++ b/arch/x86/include/asm/sev-common.h +@@ -105,6 +105,28 @@ enum psc_op { + + #define GHCB_HV_FT_SNP BIT_ULL(0) + ++/* SNP Page State Change NAE event */ ++#define VMGEXIT_PSC_MAX_ENTRY 253 ++ ++struct psc_hdr { ++ u16 cur_entry; ++ u16 end_entry; ++ u32 reserved; ++} __packed; ++ ++struct psc_entry { ++ u64 cur_page : 12, ++ gfn : 40, ++ operation : 4, ++ pagesize : 1, ++ reserved : 7; ++} __packed; ++ ++struct snp_psc_desc { ++ struct psc_hdr hdr; ++ struct psc_entry entries[VMGEXIT_PSC_MAX_ENTRY]; ++} __packed; ++ + #define GHCB_MSR_TERM_REQ 0x100 + #define GHCB_MSR_TERM_REASON_SET_POS 12 + #define GHCB_MSR_TERM_REASON_SET_MASK 0xf +--- a/arch/x86/include/asm/sev.h ++++ b/arch/x86/include/asm/sev.h +@@ -128,6 +128,8 @@ void __init early_snp_set_memory_private + void __init early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr, + unsigned int npages); + void __init snp_prep_memory(unsigned long paddr, unsigned int sz, enum psc_op op); ++void snp_set_memory_shared(unsigned long vaddr, unsigned int npages); ++void snp_set_memory_private(unsigned long vaddr, unsigned int npages); + #else + static inline void sev_es_ist_enter(struct pt_regs *regs) { } + static inline void sev_es_ist_exit(void) { } +@@ -142,6 +144,8 @@ early_snp_set_memory_private(unsigned lo + static inline void __init + early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr, unsigned int npages) { } + static inline void __init snp_prep_memory(unsigned long paddr, unsigned int sz, enum psc_op op) { } ++static inline void snp_set_memory_shared(unsigned long vaddr, unsigned int npages) { } ++static inline void snp_set_memory_private(unsigned long vaddr, unsigned int npages) { } + #endif + + #endif +--- a/arch/x86/include/uapi/asm/svm.h ++++ b/arch/x86/include/uapi/asm/svm.h +@@ -108,6 +108,7 @@ + #define SVM_VMGEXIT_AP_JUMP_TABLE 0x80000005 + #define SVM_VMGEXIT_SET_AP_JUMP_TABLE 0 + #define SVM_VMGEXIT_GET_AP_JUMP_TABLE 1 ++#define SVM_VMGEXIT_PSC 0x80000010 + #define SVM_VMGEXIT_HV_FEATURES 0x8000fffd + #define SVM_VMGEXIT_UNSUPPORTED_EVENT 0x8000ffff + +@@ -219,6 +220,7 @@ + { SVM_VMGEXIT_NMI_COMPLETE, "vmgexit_nmi_complete" }, \ + { SVM_VMGEXIT_AP_HLT_LOOP, "vmgexit_ap_hlt_loop" }, \ + { SVM_VMGEXIT_AP_JUMP_TABLE, "vmgexit_ap_jump_table" }, \ ++ { SVM_VMGEXIT_PSC, "vmgexit_page_state_change" }, \ + { SVM_VMGEXIT_HV_FEATURES, "vmgexit_hypervisor_feature" }, \ + { SVM_EXIT_ERR, "invalid_guest_state" } + +--- a/arch/x86/kernel/sev.c ++++ b/arch/x86/kernel/sev.c +@@ -655,6 +655,174 @@ void __init snp_prep_memory(unsigned lon + WARN(1, "invalid memory op %d\n", op); + } + ++static int vmgexit_psc(struct snp_psc_desc *desc) ++{ ++ int cur_entry, end_entry, ret = 0; ++ struct snp_psc_desc *data; ++ struct ghcb_state state; ++ struct es_em_ctxt ctxt; ++ unsigned long flags; ++ struct ghcb *ghcb; ++ ++ /* ++ * __sev_get_ghcb() needs to run with IRQs disabled because it is using ++ * a per-CPU GHCB. ++ */ ++ local_irq_save(flags); ++ ++ ghcb = __sev_get_ghcb(&state); ++ if (!ghcb) { ++ ret = 1; ++ goto out_unlock; ++ } ++ ++ /* Copy the input desc into GHCB shared buffer */ ++ data = (struct snp_psc_desc *)ghcb->shared_buffer; ++ memcpy(ghcb->shared_buffer, desc, min_t(int, GHCB_SHARED_BUF_SIZE, sizeof(*desc))); ++ ++ /* ++ * As per the GHCB specification, the hypervisor can resume the guest ++ * before processing all the entries. Check whether all the entries ++ * are processed. If not, then keep retrying. Note, the hypervisor ++ * will update the data memory directly to indicate the status, so ++ * reference the data->hdr everywhere. ++ * ++ * The strategy here is to wait for the hypervisor to change the page ++ * state in the RMP table before guest accesses the memory pages. If the ++ * page state change was not successful, then later memory access will ++ * result in a crash. ++ */ ++ cur_entry = data->hdr.cur_entry; ++ end_entry = data->hdr.end_entry; ++ ++ while (data->hdr.cur_entry <= data->hdr.end_entry) { ++ ghcb_set_sw_scratch(ghcb, (u64)__pa(data)); ++ ++ /* This will advance the shared buffer data points to. */ ++ ret = sev_es_ghcb_hv_call(ghcb, true, &ctxt, SVM_VMGEXIT_PSC, 0, 0); ++ ++ /* ++ * Page State Change VMGEXIT can pass error code through ++ * exit_info_2. ++ */ ++ if (WARN(ret || ghcb->save.sw_exit_info_2, ++ "SNP: PSC failed ret=%d exit_info_2=%llx\n", ++ ret, ghcb->save.sw_exit_info_2)) { ++ ret = 1; ++ goto out; ++ } ++ ++ /* Verify that reserved bit is not set */ ++ if (WARN(data->hdr.reserved, "Reserved bit is set in the PSC header\n")) { ++ ret = 1; ++ goto out; ++ } ++ ++ /* ++ * Sanity check that entry processing is not going backwards. ++ * This will happen only if hypervisor is tricking us. ++ */ ++ if (WARN(data->hdr.end_entry > end_entry || cur_entry > data->hdr.cur_entry, ++"SNP: PSC processing going backward, end_entry %d (got %d) cur_entry %d (got %d)\n", ++ end_entry, data->hdr.end_entry, cur_entry, data->hdr.cur_entry)) { ++ ret = 1; ++ goto out; ++ } ++ } ++ ++out: ++ __sev_put_ghcb(&state); ++ ++out_unlock: ++ local_irq_restore(flags); ++ ++ return ret; ++} ++ ++static void __set_pages_state(struct snp_psc_desc *data, unsigned long vaddr, ++ unsigned long vaddr_end, int op) ++{ ++ struct psc_hdr *hdr; ++ struct psc_entry *e; ++ unsigned long pfn; ++ int i; ++ ++ hdr = &data->hdr; ++ e = data->entries; ++ ++ memset(data, 0, sizeof(*data)); ++ i = 0; ++ ++ while (vaddr < vaddr_end) { ++ if (is_vmalloc_addr((void *)vaddr)) ++ pfn = vmalloc_to_pfn((void *)vaddr); ++ else ++ pfn = __pa(vaddr) >> PAGE_SHIFT; ++ ++ e->gfn = pfn; ++ e->operation = op; ++ hdr->end_entry = i; ++ ++ /* ++ * Current SNP implementation doesn't keep track of the RMP page ++ * size so use 4K for simplicity. ++ */ ++ e->pagesize = RMP_PG_SIZE_4K; ++ ++ vaddr = vaddr + PAGE_SIZE; ++ e++; ++ i++; ++ } ++ ++ if (vmgexit_psc(data)) ++ sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PSC); ++} ++ ++static void set_pages_state(unsigned long vaddr, unsigned int npages, int op) ++{ ++ unsigned long vaddr_end, next_vaddr; ++ struct snp_psc_desc *desc; ++ ++ desc = kmalloc(sizeof(*desc), GFP_KERNEL_ACCOUNT); ++ if (!desc) ++ panic("SNP: failed to allocate memory for PSC descriptor\n"); ++ ++ vaddr = vaddr & PAGE_MASK; ++ vaddr_end = vaddr + (npages << PAGE_SHIFT); ++ ++ while (vaddr < vaddr_end) { ++ /* Calculate the last vaddr that fits in one struct snp_psc_desc. */ ++ next_vaddr = min_t(unsigned long, vaddr_end, ++ (VMGEXIT_PSC_MAX_ENTRY * PAGE_SIZE) + vaddr); ++ ++ __set_pages_state(desc, vaddr, next_vaddr, op); ++ ++ vaddr = next_vaddr; ++ } ++ ++ kfree(desc); ++} ++ ++void snp_set_memory_shared(unsigned long vaddr, unsigned int npages) ++{ ++ if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP)) ++ return; ++ ++ pvalidate_pages(vaddr, npages, false); ++ ++ set_pages_state(vaddr, npages, SNP_PAGE_STATE_SHARED); ++} ++ ++void snp_set_memory_private(unsigned long vaddr, unsigned int npages) ++{ ++ if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP)) ++ return; ++ ++ set_pages_state(vaddr, npages, SNP_PAGE_STATE_PRIVATE); ++ ++ pvalidate_pages(vaddr, npages, true); ++} ++ + int sev_es_setup_ap_jump_table(struct real_mode_header *rmh) + { + u16 startup_cs, startup_ip; +--- a/arch/x86/mm/mem_encrypt_amd.c ++++ b/arch/x86/mm/mem_encrypt_amd.c +@@ -316,11 +316,24 @@ static void enc_dec_hypercall(unsigned l + + static void amd_enc_status_change_prepare(unsigned long vaddr, int npages, bool enc) + { ++ /* ++ * To maintain the security guarantees of SEV-SNP guests, make sure ++ * to invalidate the memory before encryption attribute is cleared. ++ */ ++ if (cc_platform_has(CC_ATTR_GUEST_SEV_SNP) && !enc) ++ snp_set_memory_shared(vaddr, npages); + } + + /* Return true unconditionally: return value doesn't matter for the SEV side */ + static bool amd_enc_status_change_finish(unsigned long vaddr, int npages, bool enc) + { ++ /* ++ * After memory is mapped encrypted in the page table, validate it ++ * so that it is consistent with the page table updates. ++ */ ++ if (cc_platform_has(CC_ATTR_GUEST_SEV_SNP) && enc) ++ snp_set_memory_private(vaddr, npages); ++ + if (!cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT)) + enc_dec_hypercall(vaddr, npages, enc); + diff --git a/patches.suse/x86-sev-Add-SEV-SNP-feature-detection-setup b/patches.suse/x86-sev-Add-SEV-SNP-feature-detection-setup new file mode 100644 index 0000000..d9f3a3c --- /dev/null +++ b/patches.suse/x86-sev-Add-SEV-SNP-feature-detection-setup @@ -0,0 +1,216 @@ +From: Michael Roth +Date: Thu, 24 Feb 2022 10:56:18 -0600 +Subject: x86/sev: Add SEV-SNP feature detection/setup +Git-commit: b190a043c49af4587f5e157053f909192820522a +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +Initial/preliminary detection of SEV-SNP is done via the Confidential +Computing blob. Check for it prior to the normal SEV/SME feature +initialization, and add some sanity checks to confirm it agrees with +SEV-SNP CPUID/MSR bits. + +Signed-off-by: Michael Roth +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220307213356.2797205-39-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/boot/compressed/sev.c | 27 --------------- + arch/x86/include/asm/sev.h | 2 + + arch/x86/kernel/sev-shared.c | 27 +++++++++++++++ + arch/x86/kernel/sev.c | 64 +++++++++++++++++++++++++++++++++++++ + arch/x86/mm/mem_encrypt_identity.c | 8 ++++ + 5 files changed, 101 insertions(+), 27 deletions(-) + +--- a/arch/x86/boot/compressed/sev.c ++++ b/arch/x86/boot/compressed/sev.c +@@ -352,33 +352,6 @@ static struct cc_blob_sev_info *find_cc_ + EFI_CC_BLOB_GUID); + } + +-struct cc_setup_data { +- struct setup_data header; +- u32 cc_blob_address; +-}; +- +-/* +- * Search for a Confidential Computing blob passed in as a setup_data entry +- * via the Linux Boot Protocol. +- */ +-static struct cc_blob_sev_info *find_cc_blob_setup_data(struct boot_params *bp) +-{ +- struct cc_setup_data *sd = NULL; +- struct setup_data *hdr; +- +- hdr = (struct setup_data *)bp->hdr.setup_data; +- +- while (hdr) { +- if (hdr->type == SETUP_CC_BLOB) { +- sd = (struct cc_setup_data *)hdr; +- return (struct cc_blob_sev_info *)(unsigned long)sd->cc_blob_address; +- } +- hdr = (struct setup_data *)hdr->next; +- } +- +- return NULL; +-} +- + /* + * Initial set up of SNP relies on information provided by the + * Confidential Computing blob, which can be passed to the boot kernel +--- a/arch/x86/include/asm/sev.h ++++ b/arch/x86/include/asm/sev.h +@@ -153,6 +153,7 @@ void snp_set_memory_shared(unsigned long + void snp_set_memory_private(unsigned long vaddr, unsigned int npages); + void snp_set_wakeup_secondary_cpu(void); + bool snp_init(struct boot_params *bp); ++void snp_abort(void); + #else + static inline void sev_es_ist_enter(struct pt_regs *regs) { } + static inline void sev_es_ist_exit(void) { } +@@ -171,6 +172,7 @@ static inline void snp_set_memory_shared + static inline void snp_set_memory_private(unsigned long vaddr, unsigned int npages) { } + static inline void snp_set_wakeup_secondary_cpu(void) { } + static inline bool snp_init(struct boot_params *bp) { return false; } ++static inline void snp_abort(void) { } + #endif + + #endif +--- a/arch/x86/kernel/sev-shared.c ++++ b/arch/x86/kernel/sev-shared.c +@@ -937,3 +937,30 @@ static enum es_result vc_handle_rdtsc(st + + return ES_OK; + } ++ ++struct cc_setup_data { ++ struct setup_data header; ++ u32 cc_blob_address; ++}; ++ ++/* ++ * Search for a Confidential Computing blob passed in as a setup_data entry ++ * via the Linux Boot Protocol. ++ */ ++static struct cc_blob_sev_info *find_cc_blob_setup_data(struct boot_params *bp) ++{ ++ struct cc_setup_data *sd = NULL; ++ struct setup_data *hdr; ++ ++ hdr = (struct setup_data *)bp->hdr.setup_data; ++ ++ while (hdr) { ++ if (hdr->type == SETUP_CC_BLOB) { ++ sd = (struct cc_setup_data *)hdr; ++ return (struct cc_blob_sev_info *)(unsigned long)sd->cc_blob_address; ++ } ++ hdr = (struct setup_data *)hdr->next; ++ } ++ ++ return NULL; ++} +--- a/arch/x86/kernel/sev.c ++++ b/arch/x86/kernel/sev.c +@@ -2064,3 +2064,67 @@ fail: + while (true) + halt(); + } ++ ++/* ++ * Initial set up of SNP relies on information provided by the ++ * Confidential Computing blob, which can be passed to the kernel ++ * in the following ways, depending on how it is booted: ++ * ++ * - when booted via the boot/decompress kernel: ++ * - via boot_params ++ * ++ * - when booted directly by firmware/bootloader (e.g. CONFIG_PVH): ++ * - via a setup_data entry, as defined by the Linux Boot Protocol ++ * ++ * Scan for the blob in that order. ++ */ ++static __init struct cc_blob_sev_info *find_cc_blob(struct boot_params *bp) ++{ ++ struct cc_blob_sev_info *cc_info; ++ ++ /* Boot kernel would have passed the CC blob via boot_params. */ ++ if (bp->cc_blob_address) { ++ cc_info = (struct cc_blob_sev_info *)(unsigned long)bp->cc_blob_address; ++ goto found_cc_info; ++ } ++ ++ /* ++ * If kernel was booted directly, without the use of the ++ * boot/decompression kernel, the CC blob may have been passed via ++ * setup_data instead. ++ */ ++ cc_info = find_cc_blob_setup_data(bp); ++ if (!cc_info) ++ return NULL; ++ ++found_cc_info: ++ if (cc_info->magic != CC_BLOB_SEV_HDR_MAGIC) ++ snp_abort(); ++ ++ return cc_info; ++} ++ ++bool __init snp_init(struct boot_params *bp) ++{ ++ struct cc_blob_sev_info *cc_info; ++ ++ if (!bp) ++ return false; ++ ++ cc_info = find_cc_blob(bp); ++ if (!cc_info) ++ return false; ++ ++ /* ++ * The CC blob will be used later to access the secrets page. Cache ++ * it here like the boot kernel does. ++ */ ++ bp->cc_blob_address = (u32)(unsigned long)cc_info; ++ ++ return true; ++} ++ ++void __init snp_abort(void) ++{ ++ sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED); ++} +--- a/arch/x86/mm/mem_encrypt_identity.c ++++ b/arch/x86/mm/mem_encrypt_identity.c +@@ -45,6 +45,7 @@ + #include + #include + #include ++#include + + #include "mm_internal.h" + +@@ -509,8 +510,11 @@ void __init sme_enable(struct boot_param + bool active_by_default; + unsigned long me_mask; + char buffer[16]; ++ bool snp; + u64 msr; + ++ snp = snp_init(bp); ++ + /* Check for the SME/SEV support leaf */ + eax = 0x80000000; + ecx = 0; +@@ -542,6 +546,10 @@ void __init sme_enable(struct boot_param + sev_status = __rdmsr(MSR_AMD64_SEV); + feature_mask = (sev_status & MSR_AMD64_SEV_ENABLED) ? AMD_SEV_BIT : AMD_SME_BIT; + ++ /* The SEV-SNP CC blob should never be present unless SEV-SNP is enabled. */ ++ if (snp && !(sev_status & MSR_AMD64_SEV_SNP_ENABLED)) ++ snp_abort(); ++ + /* Check if memory encryption is enabled */ + if (feature_mask == AMD_SME_BIT) { + /* diff --git a/patches.suse/x86-sev-Add-a-helper-for-the-PVALIDATE-instruction b/patches.suse/x86-sev-Add-a-helper-for-the-PVALIDATE-instruction new file mode 100644 index 0000000..8f944be --- /dev/null +++ b/patches.suse/x86-sev-Add-a-helper-for-the-PVALIDATE-instruction @@ -0,0 +1,71 @@ +From: Brijesh Singh +Date: Wed, 9 Feb 2022 12:10:07 -0600 +Subject: x86/sev: Add a helper for the PVALIDATE instruction +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Git-commit: 0bd6f1e526070271dbe0f626b123b4f6b01dc79c +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +An SNP-active guest uses the PVALIDATE instruction to validate or +rescind the validation of a guest page’s RMP entry. Upon completion, a +return code is stored in EAX and rFLAGS bits are set based on the return +code. If the instruction completed successfully, the carry flag (CF) +indicates if the content of the RMP were changed or not. + +See AMD APM Volume 3 for additional details. + +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Reviewed-by: Venu Busireddy +Link: https://lore.kernel.org/r/20220307213356.2797205-14-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/include/asm/sev.h | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +--- a/arch/x86/include/asm/sev.h ++++ b/arch/x86/include/asm/sev.h +@@ -60,6 +60,9 @@ extern void vc_no_ghcb(void); + extern void vc_boot_ghcb(void); + extern bool handle_vc_boot_ghcb(struct pt_regs *regs); + ++/* Software defined (when rFlags.CF = 1) */ ++#define PVALIDATE_FAIL_NOUPDATE 255 ++ + #ifdef CONFIG_AMD_MEM_ENCRYPT + extern struct static_key_false sev_es_enable_key; + extern void __sev_es_ist_enter(struct pt_regs *regs); +@@ -87,12 +90,30 @@ extern enum es_result sev_es_ghcb_hv_cal + struct es_em_ctxt *ctxt, + u64 exit_code, u64 exit_info_1, + u64 exit_info_2); ++static inline int pvalidate(unsigned long vaddr, bool rmp_psize, bool validate) ++{ ++ bool no_rmpupdate; ++ int rc; ++ ++ /* "pvalidate" mnemonic support in binutils 2.36 and newer */ ++ asm volatile(".byte 0xF2, 0x0F, 0x01, 0xFF\n\t" ++ CC_SET(c) ++ : CC_OUT(c) (no_rmpupdate), "=a"(rc) ++ : "a"(vaddr), "c"(rmp_psize), "d"(validate) ++ : "memory", "cc"); ++ ++ if (no_rmpupdate) ++ return PVALIDATE_FAIL_NOUPDATE; ++ ++ return rc; ++} + #else + static inline void sev_es_ist_enter(struct pt_regs *regs) { } + static inline void sev_es_ist_exit(void) { } + static inline int sev_es_setup_ap_jump_table(struct real_mode_header *rmh) { return 0; } + static inline void sev_es_nmi_complete(void) { } + static inline int sev_es_efi_map_ghcbs(pgd_t *pgd) { return 0; } ++static inline int pvalidate(unsigned long vaddr, bool rmp_psize, bool validate) { return 0; } + #endif + + #endif diff --git a/patches.suse/x86-sev-Add-a-sev-cmdline-option b/patches.suse/x86-sev-Add-a-sev-cmdline-option new file mode 100644 index 0000000..cd970e7 --- /dev/null +++ b/patches.suse/x86-sev-Add-a-sev-cmdline-option @@ -0,0 +1,126 @@ +From: Michael Roth +Date: Mon, 7 Mar 2022 15:33:50 -0600 +Subject: x86/sev: Add a sev= cmdline option +Git-commit: ba37a1438aeb540cc48722d629f4b2e7e4398466 +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +For debugging purposes it is very useful to have a way to see the full +contents of the SNP CPUID table provided to a guest. Add an sev=debug +kernel command-line option to do so. + +Also introduce some infrastructure so that additional options can be +specified via sev=option1[,option2] over time in a consistent manner. + + [ bp: Massage, simplify string parsing. ] + +Suggested-by: Borislav Petkov +Signed-off-by: Michael Roth +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220307213356.2797205-41-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + Documentation/admin-guide/kernel-parameters.txt | 2 + + Documentation/x86/x86_64/boot-options.rst | 14 +++++++ + arch/x86/kernel/sev.c | 44 ++++++++++++++++++++++++ + 3 files changed, 60 insertions(+) + +--- a/Documentation/admin-guide/kernel-parameters.txt ++++ b/Documentation/admin-guide/kernel-parameters.txt +@@ -5108,6 +5108,8 @@ + + serialnumber [BUGS=X86-32] + ++ sev=option[,option...] [X86-64] See Documentation/x86/x86_64/boot-options.rst ++ + shapers= [NET] + Maximal number of shapers. + +--- a/Documentation/x86/x86_64/boot-options.rst ++++ b/Documentation/x86/x86_64/boot-options.rst +@@ -308,3 +308,17 @@ Miscellaneous + Do not use GB pages for kernel direct mappings. + gbpages + Use GB pages for kernel direct mappings. ++ ++ ++AMD SEV (Secure Encrypted Virtualization) ++========================================= ++Options relating to AMD SEV, specified via the following format: ++ ++:: ++ ++ sev=option1[,option2] ++ ++The available options are: ++ ++ debug ++ Enable debug messages. +--- a/arch/x86/kernel/sev.c ++++ b/arch/x86/kernel/sev.c +@@ -112,6 +112,13 @@ DEFINE_STATIC_KEY_FALSE(sev_es_enable_ke + + static DEFINE_PER_CPU(struct sev_es_save_area *, sev_vmsa); + ++struct sev_config { ++ __u64 debug : 1, ++ __reserved : 63; ++}; ++ ++static struct sev_config sev_cfg __read_mostly; ++ + static __always_inline bool on_vc_stack(struct pt_regs *regs) + { + unsigned long sp = regs->sp; +@@ -2132,6 +2139,23 @@ void __init snp_abort(void) + sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED); + } + ++static void dump_cpuid_table(void) ++{ ++ const struct snp_cpuid_table *cpuid_table = snp_cpuid_get_table(); ++ int i = 0; ++ ++ pr_info("count=%d reserved=0x%x reserved2=0x%llx\n", ++ cpuid_table->count, cpuid_table->__reserved1, cpuid_table->__reserved2); ++ ++ for (i = 0; i < SNP_CPUID_COUNT_MAX; i++) { ++ const struct snp_cpuid_fn *fn = &cpuid_table->fn[i]; ++ ++ pr_info("index=%3d fn=0x%08x subfn=0x%08x: eax=0x%08x ebx=0x%08x ecx=0x%08x edx=0x%08x xcr0_in=0x%016llx xss_in=0x%016llx reserved=0x%016llx\n", ++ i, fn->eax_in, fn->ecx_in, fn->eax, fn->ebx, fn->ecx, ++ fn->edx, fn->xcr0_in, fn->xss_in, fn->__reserved); ++ } ++} ++ + /* + * It is useful from an auditing/testing perspective to provide an easy way + * for the guest owner to know that the CPUID table has been initialized as +@@ -2149,6 +2173,26 @@ static int __init report_cpuid_table(voi + pr_info("Using SNP CPUID table, %d entries present.\n", + cpuid_table->count); + ++ if (sev_cfg.debug) ++ dump_cpuid_table(); ++ + return 0; + } + arch_initcall(report_cpuid_table); ++ ++static int __init init_sev_config(char *str) ++{ ++ char *s; ++ ++ while ((s = strsep(&str, ","))) { ++ if (!strcmp(s, "debug")) { ++ sev_cfg.debug = true; ++ continue; ++ } ++ ++ pr_info("SEV command-line option '%s' was not recognized\n", s); ++ } ++ ++ return 1; ++} ++__setup("sev=", init_sev_config); diff --git a/patches.suse/x86-sev-Add-helper-for-validating-pages-in-early-enc-attribute-c b/patches.suse/x86-sev-Add-helper-for-validating-pages-in-early-enc-attribute-c new file mode 100644 index 0000000..aaf1920 --- /dev/null +++ b/patches.suse/x86-sev-Add-helper-for-validating-pages-in-early-enc-attribute-c @@ -0,0 +1,278 @@ +From: Brijesh Singh +Date: Wed, 9 Feb 2022 12:10:12 -0600 +Subject: x86/sev: Add helper for validating pages in early enc attribute + changes +Git-commit: 5e5ccff60a2977142d39b987a8b90e422d9fc634 +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +early_set_memory_{encrypted,decrypted}() are used for changing the page +state from decrypted (shared) to encrypted (private) and vice versa. + +When SEV-SNP is active, the page state transition needs to go through +additional steps. + +If the page is transitioned from shared to private, then perform the +following after the encryption attribute is set in the page table: + +1. Issue the page state change VMGEXIT to add the page as a private + in the RMP table. +2. Validate the page after its successfully added in the RMP table. + +To maintain the security guarantees, if the page is transitioned from +private to shared, then perform the following before clearing the +encryption attribute from the page table. + +1. Invalidate the page. +2. Issue the page state change VMGEXIT to make the page shared in the + RMP table. + +early_set_memory_{encrypted,decrypted}() can be called before the GHCB +is setup so use the SNP page state MSR protocol VMGEXIT defined in the +GHCB specification to request the page state change in the RMP table. + +While at it, add a helper snp_prep_memory() which will be used in +probe_roms(), in a later patch. + + [ bp: Massage commit message. ] + +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Reviewed-by: Venu Busireddy +Link: https://lore.kernel.org/r/20220307213356.2797205-19-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/include/asm/sev.h | 10 ++++ + arch/x86/kernel/sev.c | 99 ++++++++++++++++++++++++++++++++++++++++++ + arch/x86/mm/mem_encrypt_amd.c | 58 ++++++++++++++++++++++-- + 3 files changed, 163 insertions(+), 4 deletions(-) + +--- a/arch/x86/include/asm/sev.h ++++ b/arch/x86/include/asm/sev.h +@@ -123,6 +123,11 @@ static inline int pvalidate(unsigned lon + return rc; + } + void setup_ghcb(void); ++void __init early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr, ++ unsigned int npages); ++void __init early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr, ++ unsigned int npages); ++void __init snp_prep_memory(unsigned long paddr, unsigned int sz, enum psc_op op); + #else + static inline void sev_es_ist_enter(struct pt_regs *regs) { } + static inline void sev_es_ist_exit(void) { } +@@ -132,6 +137,11 @@ static inline int sev_es_efi_map_ghcbs(p + static inline int pvalidate(unsigned long vaddr, bool rmp_psize, bool validate) { return 0; } + static inline int rmpadjust(unsigned long vaddr, bool rmp_psize, unsigned long attrs) { return 0; } + static inline void setup_ghcb(void) { } ++static inline void __init ++early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr, unsigned int npages) { } ++static inline void __init ++early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr, unsigned int npages) { } ++static inline void __init snp_prep_memory(unsigned long paddr, unsigned int sz, enum psc_op op) { } + #endif + + #endif +--- a/arch/x86/kernel/sev.c ++++ b/arch/x86/kernel/sev.c +@@ -556,6 +556,105 @@ static u64 get_jump_table_addr(void) + return ret; + } + ++static void pvalidate_pages(unsigned long vaddr, unsigned int npages, bool validate) ++{ ++ unsigned long vaddr_end; ++ int rc; ++ ++ vaddr = vaddr & PAGE_MASK; ++ vaddr_end = vaddr + (npages << PAGE_SHIFT); ++ ++ while (vaddr < vaddr_end) { ++ rc = pvalidate(vaddr, RMP_PG_SIZE_4K, validate); ++ if (WARN(rc, "Failed to validate address 0x%lx ret %d", vaddr, rc)) ++ sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PVALIDATE); ++ ++ vaddr = vaddr + PAGE_SIZE; ++ } ++} ++ ++static void __init early_set_pages_state(unsigned long paddr, unsigned int npages, enum psc_op op) ++{ ++ unsigned long paddr_end; ++ u64 val; ++ ++ paddr = paddr & PAGE_MASK; ++ paddr_end = paddr + (npages << PAGE_SHIFT); ++ ++ while (paddr < paddr_end) { ++ /* ++ * Use the MSR protocol because this function can be called before ++ * the GHCB is established. ++ */ ++ sev_es_wr_ghcb_msr(GHCB_MSR_PSC_REQ_GFN(paddr >> PAGE_SHIFT, op)); ++ VMGEXIT(); ++ ++ val = sev_es_rd_ghcb_msr(); ++ ++ if (WARN(GHCB_RESP_CODE(val) != GHCB_MSR_PSC_RESP, ++ "Wrong PSC response code: 0x%x\n", ++ (unsigned int)GHCB_RESP_CODE(val))) ++ goto e_term; ++ ++ if (WARN(GHCB_MSR_PSC_RESP_VAL(val), ++ "Failed to change page state to '%s' paddr 0x%lx error 0x%llx\n", ++ op == SNP_PAGE_STATE_PRIVATE ? "private" : "shared", ++ paddr, GHCB_MSR_PSC_RESP_VAL(val))) ++ goto e_term; ++ ++ paddr = paddr + PAGE_SIZE; ++ } ++ ++ return; ++ ++e_term: ++ sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PSC); ++} ++ ++void __init early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr, ++ unsigned int npages) ++{ ++ if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP)) ++ return; ++ ++ /* ++ * Ask the hypervisor to mark the memory pages as private in the RMP ++ * table. ++ */ ++ early_set_pages_state(paddr, npages, SNP_PAGE_STATE_PRIVATE); ++ ++ /* Validate the memory pages after they've been added in the RMP table. */ ++ pvalidate_pages(vaddr, npages, true); ++} ++ ++void __init early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr, ++ unsigned int npages) ++{ ++ if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP)) ++ return; ++ ++ /* Invalidate the memory pages before they are marked shared in the RMP table. */ ++ pvalidate_pages(vaddr, npages, false); ++ ++ /* Ask hypervisor to mark the memory pages shared in the RMP table. */ ++ early_set_pages_state(paddr, npages, SNP_PAGE_STATE_SHARED); ++} ++ ++void __init snp_prep_memory(unsigned long paddr, unsigned int sz, enum psc_op op) ++{ ++ unsigned long vaddr, npages; ++ ++ vaddr = (unsigned long)__va(paddr); ++ npages = PAGE_ALIGN(sz) >> PAGE_SHIFT; ++ ++ if (op == SNP_PAGE_STATE_PRIVATE) ++ early_snp_set_memory_private(vaddr, paddr, npages); ++ else if (op == SNP_PAGE_STATE_SHARED) ++ early_snp_set_memory_shared(vaddr, paddr, npages); ++ else ++ WARN(1, "invalid memory op %d\n", op); ++} ++ + int sev_es_setup_ap_jump_table(struct real_mode_header *rmh) + { + u16 startup_cs, startup_ip; +--- a/arch/x86/mm/mem_encrypt_amd.c ++++ b/arch/x86/mm/mem_encrypt_amd.c +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + + #include "mm_internal.h" + +@@ -48,6 +49,36 @@ EXPORT_SYMBOL(sme_me_mask); + static char sme_early_buffer[PAGE_SIZE] __initdata __aligned(PAGE_SIZE); + + /* ++ * SNP-specific routine which needs to additionally change the page state from ++ * private to shared before copying the data from the source to destination and ++ * restore after the copy. ++ */ ++static inline void __init snp_memcpy(void *dst, void *src, size_t sz, ++ unsigned long paddr, bool decrypt) ++{ ++ unsigned long npages = PAGE_ALIGN(sz) >> PAGE_SHIFT; ++ ++ if (decrypt) { ++ /* ++ * @paddr needs to be accessed decrypted, mark the page shared in ++ * the RMP table before copying it. ++ */ ++ early_snp_set_memory_shared((unsigned long)__va(paddr), paddr, npages); ++ ++ memcpy(dst, src, sz); ++ ++ /* Restore the page state after the memcpy. */ ++ early_snp_set_memory_private((unsigned long)__va(paddr), paddr, npages); ++ } else { ++ /* ++ * @paddr need to be accessed encrypted, no need for the page state ++ * change. ++ */ ++ memcpy(dst, src, sz); ++ } ++} ++ ++/* + * This routine does not change the underlying encryption setting of the + * page(s) that map this memory. It assumes that eventually the memory is + * meant to be accessed as either encrypted or decrypted but the contents +@@ -95,8 +126,13 @@ static void __init __sme_early_enc_dec(r + * Use a temporary buffer, of cache-line multiple size, to + * avoid data corruption as documented in the APM. + */ +- memcpy(sme_early_buffer, src, len); +- memcpy(dst, sme_early_buffer, len); ++ if (cc_platform_has(CC_ATTR_GUEST_SEV_SNP)) { ++ snp_memcpy(sme_early_buffer, src, len, paddr, enc); ++ snp_memcpy(dst, sme_early_buffer, len, paddr, !enc); ++ } else { ++ memcpy(sme_early_buffer, src, len); ++ memcpy(dst, sme_early_buffer, len); ++ } + + early_memunmap(dst, len); + early_memunmap(src, len); +@@ -322,14 +358,28 @@ static void __init __set_clr_pte_enc(pte + clflush_cache_range(__va(pa), size); + + /* Encrypt/decrypt the contents in-place */ +- if (enc) ++ if (enc) { + sme_early_encrypt(pa, size); +- else ++ } else { + sme_early_decrypt(pa, size); + ++ /* ++ * ON SNP, the page state in the RMP table must happen ++ * before the page table updates. ++ */ ++ early_snp_set_memory_shared((unsigned long)__va(pa), pa, 1); ++ } ++ + /* Change the page encryption mask. */ + new_pte = pfn_pte(pfn, new_prot); + set_pte_atomic(kpte, new_pte); ++ ++ /* ++ * If page is set encrypted in the page table, then update the RMP table to ++ * add this page as private. ++ */ ++ if (enc) ++ early_snp_set_memory_private((unsigned long)__va(pa), pa, 1); + } + + static int __init early_set_memory_enc_dec(unsigned long vaddr, diff --git a/patches.suse/x86-sev-Add-missing-__init-annotations-to-SEV-init-routines b/patches.suse/x86-sev-Add-missing-__init-annotations-to-SEV-init-routines new file mode 100644 index 0000000..97c1b30 --- /dev/null +++ b/patches.suse/x86-sev-Add-missing-__init-annotations-to-SEV-init-routines @@ -0,0 +1,80 @@ +From: Michael Roth +Date: Fri, 22 Apr 2022 08:56:23 -0500 +Subject: x86/sev: Add missing __init annotations to SEV init routines +Git-commit: 75d359ec4141b013727022a663762931f69e6510 +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924 jsc#SLE-24814 + +Currently, get_secrets_page() is only reachable from the following call +chain: + + __init snp_init_platform_device(): + get_secrets_page() + +so mark it as __init as well. This is also needed since it calls +early_memremap(), which is also an __init routine. + +Similarly, get_jump_table_addr() is only reachable from the following +call chain: + + __init setup_real_mode(): + sme_sev_setup_real_mode(): + sev_es_setup_ap_jump_table(): + get_jump_table_addr() + +so mark get_jump_table_addr() and everything up that call chain as +__init as well. This is also needed since future patches will add a +call to get_secrets_page(), which needs to be __init due to the reasons +stated above. + +Suggested-by: Borislav Petkov +Signed-off-by: Michael Roth +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220422135624.114172-2-michael.roth@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/kernel/sev.c | 6 +++--- + arch/x86/realmode/init.c | 2 +- + 2 files changed, 4 insertions(+), 4 deletions(-) + +--- a/arch/x86/kernel/sev.c ++++ b/arch/x86/kernel/sev.c +@@ -558,7 +558,7 @@ void noinstr __sev_es_nmi_complete(void) + __sev_put_ghcb(&state); + } + +-static u64 get_jump_table_addr(void) ++static u64 __init get_jump_table_addr(void) + { + struct ghcb_state state; + unsigned long flags; +@@ -1077,7 +1077,7 @@ void snp_set_wakeup_secondary_cpu(void) + apic->wakeup_secondary_cpu = wakeup_cpu_via_vmgexit; + } + +-int sev_es_setup_ap_jump_table(struct real_mode_header *rmh) ++int __init sev_es_setup_ap_jump_table(struct real_mode_header *rmh) + { + u16 startup_cs, startup_ip; + phys_addr_t jump_table_pa; +@@ -2262,7 +2262,7 @@ static struct platform_device guest_req_ + .id = -1, + }; + +-static u64 get_secrets_page(void) ++static u64 __init get_secrets_page(void) + { + u64 pa_data = boot_params.cc_blob_address; + struct cc_blob_sev_info info; +--- a/arch/x86/realmode/init.c ++++ b/arch/x86/realmode/init.c +@@ -41,7 +41,7 @@ void __init reserve_real_mode(void) + memblock_reserve(0, SZ_1M); + } + +-static void sme_sev_setup_real_mode(struct trampoline_header *th) ++static void __init sme_sev_setup_real_mode(struct trampoline_header *th) + { + #ifdef CONFIG_AMD_MEM_ENCRYPT + if (cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT)) diff --git a/patches.suse/x86-sev-Check-SEV-SNP-features-support b/patches.suse/x86-sev-Check-SEV-SNP-features-support new file mode 100644 index 0000000..c104527 --- /dev/null +++ b/patches.suse/x86-sev-Check-SEV-SNP-features-support @@ -0,0 +1,224 @@ +From: Brijesh Singh +Date: Wed, 9 Feb 2022 12:10:06 -0600 +Subject: x86/sev: Check SEV-SNP features support +Git-commit: cbd3d4f7c4e5a93edae68e5142a269368fde77d6 +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +Version 2 of the GHCB specification added the advertisement of features +that are supported by the hypervisor. If the hypervisor supports SEV-SNP +then it must set the SEV-SNP features bit to indicate that the base +functionality is supported. + +Check that feature bit while establishing the GHCB; if failed, terminate +the guest. + +Version 2 of the GHCB specification adds several new Non-Automatic Exits +(NAEs), most of them are optional except the hypervisor feature. Now +that the hypervisor feature NAE is implemented, bump the GHCB maximum +supported protocol version. + +While at it, move the GHCB protocol negotiation check from the #VC +exception handler to sev_enable() so that all feature detection happens +before the first #VC exception. + +While at it, document why the GHCB page cannot be setup from +load_stage2_idt(). + + [ bp: Massage commit message. ] + +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220307213356.2797205-13-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/boot/compressed/idt_64.c | 18 +++++++++++++++++- + arch/x86/boot/compressed/sev.c | 20 +++++++++++++++----- + arch/x86/include/asm/sev-common.h | 6 ++++++ + arch/x86/include/asm/sev.h | 2 +- + arch/x86/include/uapi/asm/svm.h | 2 ++ + arch/x86/kernel/sev-shared.c | 20 ++++++++++++++++++++ + arch/x86/kernel/sev.c | 14 ++++++++++++++ + 7 files changed, 75 insertions(+), 7 deletions(-) + +--- a/arch/x86/boot/compressed/idt_64.c ++++ b/arch/x86/boot/compressed/idt_64.c +@@ -39,7 +39,23 @@ void load_stage1_idt(void) + load_boot_idt(&boot_idt_desc); + } + +-/* Setup IDT after kernel jumping to .Lrelocated */ ++/* ++ * Setup IDT after kernel jumping to .Lrelocated. ++ * ++ * initialize_identity_maps() needs a #PF handler to be setup ++ * in order to be able to fault-in identity mapping ranges; see ++ * do_boot_page_fault(). ++ * ++ * This #PF handler setup needs to happen in load_stage2_idt() where the ++ * IDT is loaded and there the #VC IDT entry gets setup too. ++ * ++ * In order to be able to handle #VCs, one needs a GHCB which ++ * gets setup with an already set up pagetable, which is done in ++ * initialize_identity_maps(). And there's the catch 22: the boot #VC ++ * handler do_boot_stage2_vc() needs to call early_setup_ghcb() itself ++ * (and, especially set_page_decrypted()) because the SEV-ES setup code ++ * cannot initialize a GHCB as there's no #PF handler yet... ++ */ + void load_stage2_idt(void) + { + boot_idt_desc.address = (unsigned long)boot_idt; +--- a/arch/x86/boot/compressed/sev.c ++++ b/arch/x86/boot/compressed/sev.c +@@ -116,11 +116,8 @@ static enum es_result vc_read_mem(struct + /* Include code for early handlers */ + #include "../../kernel/sev-shared.c" + +-static bool early_setup_sev_es(void) ++static bool early_setup_ghcb(void) + { +- if (!sev_es_negotiate_protocol()) +- sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SEV_ES_PROT_UNSUPPORTED); +- + if (set_page_decrypted((unsigned long)&boot_ghcb_page)) + return false; + +@@ -171,7 +168,7 @@ void do_boot_stage2_vc(struct pt_regs *r + struct es_em_ctxt ctxt; + enum es_result result; + +- if (!boot_ghcb && !early_setup_sev_es()) ++ if (!boot_ghcb && !early_setup_ghcb()) + sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SEV_ES_GEN_REQ); + + vc_ghcb_invalidate(boot_ghcb); +@@ -235,5 +232,18 @@ void sev_enable(struct boot_params *bp) + if (!(sev_status & MSR_AMD64_SEV_ENABLED)) + return; + ++ /* Negotiate the GHCB protocol version. */ ++ if (sev_status & MSR_AMD64_SEV_ES_ENABLED) { ++ if (!sev_es_negotiate_protocol()) ++ sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SEV_ES_PROT_UNSUPPORTED); ++ } ++ ++ /* ++ * SNP is supported in v2 of the GHCB spec which mandates support for HV ++ * features. ++ */ ++ if (sev_status & MSR_AMD64_SEV_SNP_ENABLED && !(get_hv_features() & GHCB_HV_FT_SNP)) ++ sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED); ++ + sme_me_mask = BIT_ULL(ebx & 0x3f); + } +--- a/arch/x86/include/asm/sev-common.h ++++ b/arch/x86/include/asm/sev-common.h +@@ -60,6 +60,11 @@ + /* GHCB Hypervisor Feature Request/Response */ + #define GHCB_MSR_HV_FT_REQ 0x080 + #define GHCB_MSR_HV_FT_RESP 0x081 ++#define GHCB_MSR_HV_FT_RESP_VAL(v) \ ++ /* GHCBData[63:12] */ \ ++ (((u64)(v) & GENMASK_ULL(63, 12)) >> 12) ++ ++#define GHCB_HV_FT_SNP BIT_ULL(0) + + #define GHCB_MSR_TERM_REQ 0x100 + #define GHCB_MSR_TERM_REASON_SET_POS 12 +@@ -77,6 +82,7 @@ + #define SEV_TERM_SET_GEN 0 + #define GHCB_SEV_ES_GEN_REQ 0 + #define GHCB_SEV_ES_PROT_UNSUPPORTED 1 ++#define GHCB_SNP_UNSUPPORTED 2 + + /* Linux-specific reason codes (used with reason set 1) */ + #define SEV_TERM_SET_LINUX 1 +--- a/arch/x86/include/asm/sev.h ++++ b/arch/x86/include/asm/sev.h +@@ -13,7 +13,7 @@ + #include + + #define GHCB_PROTOCOL_MIN 1ULL +-#define GHCB_PROTOCOL_MAX 1ULL ++#define GHCB_PROTOCOL_MAX 2ULL + #define GHCB_DEFAULT_USAGE 0ULL + + #define VMGEXIT() { asm volatile("rep; vmmcall\n\r"); } +--- a/arch/x86/include/uapi/asm/svm.h ++++ b/arch/x86/include/uapi/asm/svm.h +@@ -108,6 +108,7 @@ + #define SVM_VMGEXIT_AP_JUMP_TABLE 0x80000005 + #define SVM_VMGEXIT_SET_AP_JUMP_TABLE 0 + #define SVM_VMGEXIT_GET_AP_JUMP_TABLE 1 ++#define SVM_VMGEXIT_HV_FEATURES 0x8000fffd + #define SVM_VMGEXIT_UNSUPPORTED_EVENT 0x8000ffff + + /* Exit code reserved for hypervisor/software use */ +@@ -218,6 +219,7 @@ + { SVM_VMGEXIT_NMI_COMPLETE, "vmgexit_nmi_complete" }, \ + { SVM_VMGEXIT_AP_HLT_LOOP, "vmgexit_ap_hlt_loop" }, \ + { SVM_VMGEXIT_AP_JUMP_TABLE, "vmgexit_ap_jump_table" }, \ ++ { SVM_VMGEXIT_HV_FEATURES, "vmgexit_hypervisor_feature" }, \ + { SVM_EXIT_ERR, "invalid_guest_state" } + + +--- a/arch/x86/kernel/sev-shared.c ++++ b/arch/x86/kernel/sev-shared.c +@@ -48,6 +48,26 @@ static void __noreturn sev_es_terminate( + asm volatile("hlt\n" : : : "memory"); + } + ++/* ++ * The hypervisor features are available from GHCB version 2 onward. ++ */ ++static u64 get_hv_features(void) ++{ ++ u64 val; ++ ++ if (ghcb_version < 2) ++ return 0; ++ ++ sev_es_wr_ghcb_msr(GHCB_MSR_HV_FT_REQ); ++ VMGEXIT(); ++ ++ val = sev_es_rd_ghcb_msr(); ++ if (GHCB_RESP_CODE(val) != GHCB_MSR_HV_FT_RESP) ++ return 0; ++ ++ return GHCB_MSR_HV_FT_RESP_VAL(val); ++} ++ + static bool sev_es_negotiate_protocol(void) + { + u64 val; +--- a/arch/x86/kernel/sev.c ++++ b/arch/x86/kernel/sev.c +@@ -43,6 +43,9 @@ static struct ghcb boot_ghcb_page __bss_ + */ + static struct ghcb __initdata *boot_ghcb; + ++/* Bitmap of SEV features supported by the hypervisor */ ++static u64 sev_hv_features __ro_after_init; ++ + /* #VC handler runtime per-CPU data */ + struct sev_es_runtime_data { + struct ghcb ghcb_page; +@@ -766,6 +769,17 @@ void __init sev_es_init_vc_handling(void + if (!sev_es_check_cpu_features()) + panic("SEV-ES CPU Features missing"); + ++ /* ++ * SNP is supported in v2 of the GHCB spec which mandates support for HV ++ * features. ++ */ ++ if (cc_platform_has(CC_ATTR_GUEST_SEV_SNP)) { ++ sev_hv_features = get_hv_features(); ++ ++ if (!(sev_hv_features & GHCB_HV_FT_SNP)) ++ sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED); ++ } ++ + /* Enable SEV-ES special handling */ + static_branch_enable(&sev_es_enable_key); + diff --git a/patches.suse/x86-sev-Check-the-VMPL-level b/patches.suse/x86-sev-Check-the-VMPL-level new file mode 100644 index 0000000..e0c3340 --- /dev/null +++ b/patches.suse/x86-sev-Check-the-VMPL-level @@ -0,0 +1,129 @@ +From: Brijesh Singh +Date: Wed, 9 Feb 2022 12:10:08 -0600 +Subject: x86/sev: Check the VMPL level +Git-commit: 81cc3df9a90e7817494421ecc48ede6bd5e8132b +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +The Virtual Machine Privilege Level (VMPL) feature in the SEV-SNP +architecture allows a guest VM to divide its address space into four +levels. The level can be used to provide hardware isolated abstraction +layers within a VM. VMPL0 is the highest privilege level, and VMPL3 is +the least privilege level. Certain operations must be done by the VMPL0 +software, such as: + +* Validate or invalidate memory range (PVALIDATE instruction) +* Allocate VMSA page (RMPADJUST instruction when VMSA=1) + +The initial SNP support requires that the guest kernel is running at +VMPL0. Add such a check to verify the guest is running at level 0 before +continuing the boot. There is no easy method to query the current VMPL +level, so use the RMPADJUST instruction to determine whether the guest +is running at the VMPL0. + + [ bp: Massage commit message. ] + +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220307213356.2797205-15-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/boot/compressed/sev.c | 28 ++++++++++++++++++++++++++-- + arch/x86/include/asm/sev-common.h | 1 + + arch/x86/include/asm/sev.h | 16 ++++++++++++++++ + 3 files changed, 43 insertions(+), 2 deletions(-) + +--- a/arch/x86/boot/compressed/sev.c ++++ b/arch/x86/boot/compressed/sev.c +@@ -199,6 +199,26 @@ finish: + sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SEV_ES_GEN_REQ); + } + ++static void enforce_vmpl0(void) ++{ ++ u64 attrs; ++ int err; ++ ++ /* ++ * RMPADJUST modifies RMP permissions of a lesser-privileged (numerically ++ * higher) privilege level. Here, clear the VMPL1 permission mask of the ++ * GHCB page. If the guest is not running at VMPL0, this will fail. ++ * ++ * If the guest is running at VMPL0, it will succeed. Even if that operation ++ * modifies permission bits, it is still ok to do so currently because Linux ++ * SNP guests are supported only on VMPL0 so VMPL1 or higher permission masks ++ * changing is a don't-care. ++ */ ++ attrs = 1; ++ if (rmpadjust((unsigned long)&boot_ghcb_page, RMP_PG_SIZE_4K, attrs)) ++ sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_NOT_VMPL0); ++} ++ + void sev_enable(struct boot_params *bp) + { + unsigned int eax, ebx, ecx, edx; +@@ -242,8 +262,12 @@ void sev_enable(struct boot_params *bp) + * SNP is supported in v2 of the GHCB spec which mandates support for HV + * features. + */ +- if (sev_status & MSR_AMD64_SEV_SNP_ENABLED && !(get_hv_features() & GHCB_HV_FT_SNP)) +- sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED); ++ if (sev_status & MSR_AMD64_SEV_SNP_ENABLED) { ++ if (!(get_hv_features() & GHCB_HV_FT_SNP)) ++ sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED); ++ ++ enforce_vmpl0(); ++ } + + sme_me_mask = BIT_ULL(ebx & 0x3f); + } +--- a/arch/x86/include/asm/sev-common.h ++++ b/arch/x86/include/asm/sev-common.h +@@ -89,6 +89,7 @@ + #define GHCB_TERM_REGISTER 0 /* GHCB GPA registration failure */ + #define GHCB_TERM_PSC 1 /* Page State Change failure */ + #define GHCB_TERM_PVALIDATE 2 /* Pvalidate failure */ ++#define GHCB_TERM_NOT_VMPL0 3 /* SNP guest is not running at VMPL-0 */ + + #define GHCB_RESP_CODE(v) ((v) & GHCB_MSR_INFO_MASK) + +--- a/arch/x86/include/asm/sev.h ++++ b/arch/x86/include/asm/sev.h +@@ -63,6 +63,9 @@ extern bool handle_vc_boot_ghcb(struct p + /* Software defined (when rFlags.CF = 1) */ + #define PVALIDATE_FAIL_NOUPDATE 255 + ++/* RMP page size */ ++#define RMP_PG_SIZE_4K 0 ++ + #ifdef CONFIG_AMD_MEM_ENCRYPT + extern struct static_key_false sev_es_enable_key; + extern void __sev_es_ist_enter(struct pt_regs *regs); +@@ -90,6 +93,18 @@ extern enum es_result sev_es_ghcb_hv_cal + struct es_em_ctxt *ctxt, + u64 exit_code, u64 exit_info_1, + u64 exit_info_2); ++static inline int rmpadjust(unsigned long vaddr, bool rmp_psize, unsigned long attrs) ++{ ++ int rc; ++ ++ /* "rmpadjust" mnemonic support in binutils 2.36 and newer */ ++ asm volatile(".byte 0xF3,0x0F,0x01,0xFE\n\t" ++ : "=a"(rc) ++ : "a"(vaddr), "c"(rmp_psize), "d"(attrs) ++ : "memory", "cc"); ++ ++ return rc; ++} + static inline int pvalidate(unsigned long vaddr, bool rmp_psize, bool validate) + { + bool no_rmpupdate; +@@ -114,6 +129,7 @@ static inline int sev_es_setup_ap_jump_t + static inline void sev_es_nmi_complete(void) { } + static inline int sev_es_efi_map_ghcbs(pgd_t *pgd) { return 0; } + static inline int pvalidate(unsigned long vaddr, bool rmp_psize, bool validate) { return 0; } ++static inline int rmpadjust(unsigned long vaddr, bool rmp_psize, unsigned long attrs) { return 0; } + #endif + + #endif diff --git a/patches.suse/x86-sev-Detect-setup-SEV-SME-features-earlier-in-boot b/patches.suse/x86-sev-Detect-setup-SEV-SME-features-earlier-in-boot new file mode 100644 index 0000000..455bf7f --- /dev/null +++ b/patches.suse/x86-sev-Detect-setup-SEV-SME-features-earlier-in-boot @@ -0,0 +1,58 @@ +From: Michael Roth +Date: Wed, 9 Feb 2022 12:10:02 -0600 +Subject: x86/sev: Detect/setup SEV/SME features earlier in boot +Git-commit: bcce829083339bf862d66df602cbb111943da8fb +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +sme_enable() handles feature detection for both SEV and SME. Future +patches will also use it for SEV-SNP feature detection/setup, which +will need to be done immediately after the first #VC handler is set up. +Move it now in preparation. + +Signed-off-by: Michael Roth +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Reviewed-by: Venu Busireddy +Link: https://lore.kernel.org/r/20220307213356.2797205-9-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/kernel/head64.c | 3 --- + arch/x86/kernel/head_64.S | 13 +++++++++++++ + 2 files changed, 13 insertions(+), 3 deletions(-) + +--- a/arch/x86/kernel/head64.c ++++ b/arch/x86/kernel/head64.c +@@ -192,9 +192,6 @@ unsigned long __head __startup_64(unsign + if (load_delta & ~PMD_PAGE_MASK) + for (;;); + +- /* Activate Secure Memory Encryption (SME) if supported and enabled */ +- sme_enable(bp); +- + /* Include the SME encryption mask in the fixup value */ + load_delta += sme_get_me_mask(); + +--- a/arch/x86/kernel/head_64.S ++++ b/arch/x86/kernel/head_64.S +@@ -69,6 +69,19 @@ SYM_CODE_START_NOALIGN(startup_64) + call startup_64_setup_env + popq %rsi + ++#ifdef CONFIG_AMD_MEM_ENCRYPT ++ /* ++ * Activate SEV/SME memory encryption if supported/enabled. This needs to ++ * be done now, since this also includes setup of the SEV-SNP CPUID table, ++ * which needs to be done before any CPUID instructions are executed in ++ * subsequent code. ++ */ ++ movq %rsi, %rdi ++ pushq %rsi ++ call sme_enable ++ popq %rsi ++#endif ++ + /* Now switch to __KERNEL_CS so IRET works reliably */ + pushq $__KERNEL_CS + leaq .Lon_kernel_cs(%rip), %rax diff --git a/patches.suse/x86-sev-Get-the-AP-jump-table-address-from-secrets-page b/patches.suse/x86-sev-Get-the-AP-jump-table-address-from-secrets-page new file mode 100644 index 0000000..97ea3a1 --- /dev/null +++ b/patches.suse/x86-sev-Get-the-AP-jump-table-address-from-secrets-page @@ -0,0 +1,221 @@ +From: Brijesh Singh +Date: Fri, 22 Apr 2022 08:56:24 -0500 +Subject: x86/sev: Get the AP jump table address from secrets page +Git-commit: c2106a231c2ba36ff9af50cdf2867b9a5f8150a6 +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +The GHCB specification section 2.7 states that when SEV-SNP is enabled, +a guest should not rely on the hypervisor to provide the address of the +AP jump table. Instead, if a guest BIOS wants to provide an AP jump +table, it should record the address in the SNP secrets page so the guest +operating system can obtain it directly from there. + +Fix this on the guest kernel side by having SNP guests use the AP jump +table address published in the secrets page rather than issuing a GHCB +request to get it. + + [ mroth: + - Improve error handling when ioremap()/memremap() return NULL + - Don't mix function calls with declarations + - Add missing __init + - Tweak commit message ] + +Fixes: 0afb6b660a6b ("x86/sev: Use SEV-SNP AP creation to start secondary CPUs") +Signed-off-by: Brijesh Singh +Signed-off-by: Michael Roth +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220422135624.114172-3-michael.roth@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/include/asm/sev.h | 35 +++++++++++++++ + arch/x86/kernel/sev.c | 76 +++++++++++++++++++++++----------- + drivers/virt/coco/sevguest/sevguest.h | 35 --------------- + 3 files changed, 87 insertions(+), 59 deletions(-) + +--- a/arch/x86/include/asm/sev.h ++++ b/arch/x86/include/asm/sev.h +@@ -99,6 +99,41 @@ struct snp_guest_platform_data { + u64 secrets_gpa; + }; + ++/* ++ * The secrets page contains 96-bytes of reserved field that can be used by ++ * the guest OS. The guest OS uses the area to save the message sequence ++ * number for each VMPCK. ++ * ++ * See the GHCB spec section Secret page layout for the format for this area. ++ */ ++struct secrets_os_area { ++ u32 msg_seqno_0; ++ u32 msg_seqno_1; ++ u32 msg_seqno_2; ++ u32 msg_seqno_3; ++ u64 ap_jump_table_pa; ++ u8 rsvd[40]; ++ u8 guest_usage[32]; ++} __packed; ++ ++#define VMPCK_KEY_LEN 32 ++ ++/* See the SNP spec version 0.9 for secrets page format */ ++struct snp_secrets_page_layout { ++ u32 version; ++ u32 imien : 1, ++ rsvd1 : 31; ++ u32 fms; ++ u32 rsvd2; ++ u8 gosvw[16]; ++ u8 vmpck0[VMPCK_KEY_LEN]; ++ u8 vmpck1[VMPCK_KEY_LEN]; ++ u8 vmpck2[VMPCK_KEY_LEN]; ++ u8 vmpck3[VMPCK_KEY_LEN]; ++ struct secrets_os_area os_area; ++ u8 rsvd3[3840]; ++} __packed; ++ + #ifdef CONFIG_AMD_MEM_ENCRYPT + extern struct static_key_false sev_es_enable_key; + extern void __sev_es_ist_enter(struct pt_regs *regs); +--- a/arch/x86/kernel/sev.c ++++ b/arch/x86/kernel/sev.c +@@ -558,6 +558,55 @@ void noinstr __sev_es_nmi_complete(void) + __sev_put_ghcb(&state); + } + ++static u64 __init get_secrets_page(void) ++{ ++ u64 pa_data = boot_params.cc_blob_address; ++ struct cc_blob_sev_info info; ++ void *map; ++ ++ /* ++ * The CC blob contains the address of the secrets page, check if the ++ * blob is present. ++ */ ++ if (!pa_data) ++ return 0; ++ ++ map = early_memremap(pa_data, sizeof(info)); ++ if (!map) { ++ pr_err("Unable to locate SNP secrets page: failed to map the Confidential Computing blob.\n"); ++ return 0; ++ } ++ memcpy(&info, map, sizeof(info)); ++ early_memunmap(map, sizeof(info)); ++ ++ /* smoke-test the secrets page passed */ ++ if (!info.secrets_phys || info.secrets_len != PAGE_SIZE) ++ return 0; ++ ++ return info.secrets_phys; ++} ++ ++static u64 __init get_snp_jump_table_addr(void) ++{ ++ struct snp_secrets_page_layout *layout; ++ u64 pa, addr; ++ ++ pa = get_secrets_page(); ++ if (!pa) ++ return 0; ++ ++ layout = (__force void *)ioremap_encrypted(pa, PAGE_SIZE); ++ if (!layout) { ++ pr_err("Unable to locate AP jump table address: failed to map the SNP secrets page.\n"); ++ return 0; ++ } ++ ++ addr = layout->os_area.ap_jump_table_pa; ++ iounmap(layout); ++ ++ return addr; ++} ++ + static u64 __init get_jump_table_addr(void) + { + struct ghcb_state state; +@@ -565,6 +614,9 @@ static u64 __init get_jump_table_addr(vo + struct ghcb *ghcb; + u64 ret = 0; + ++ if (cc_platform_has(CC_ATTR_GUEST_SEV_SNP)) ++ return get_snp_jump_table_addr(); ++ + local_irq_save(flags); + + ghcb = __sev_get_ghcb(&state); +@@ -2262,30 +2314,6 @@ static struct platform_device guest_req_ + .id = -1, + }; + +-static u64 __init get_secrets_page(void) +-{ +- u64 pa_data = boot_params.cc_blob_address; +- struct cc_blob_sev_info info; +- void *map; +- +- /* +- * The CC blob contains the address of the secrets page, check if the +- * blob is present. +- */ +- if (!pa_data) +- return 0; +- +- map = early_memremap(pa_data, sizeof(info)); +- memcpy(&info, map, sizeof(info)); +- early_memunmap(map, sizeof(info)); +- +- /* smoke-test the secrets page passed */ +- if (!info.secrets_phys || info.secrets_len != PAGE_SIZE) +- return 0; +- +- return info.secrets_phys; +-} +- + static int __init snp_init_platform_device(void) + { + struct snp_guest_platform_data data; +--- a/drivers/virt/coco/sevguest/sevguest.h ++++ b/drivers/virt/coco/sevguest/sevguest.h +@@ -60,39 +60,4 @@ struct snp_guest_msg { + u8 payload[4000]; + } __packed; + +-/* +- * The secrets page contains 96-bytes of reserved field that can be used by +- * the guest OS. The guest OS uses the area to save the message sequence +- * number for each VMPCK. +- * +- * See the GHCB spec section Secret page layout for the format for this area. +- */ +-struct secrets_os_area { +- u32 msg_seqno_0; +- u32 msg_seqno_1; +- u32 msg_seqno_2; +- u32 msg_seqno_3; +- u64 ap_jump_table_pa; +- u8 rsvd[40]; +- u8 guest_usage[32]; +-} __packed; +- +-#define VMPCK_KEY_LEN 32 +- +-/* See the SNP spec version 0.9 for secrets page format */ +-struct snp_secrets_page_layout { +- u32 version; +- u32 imien : 1, +- rsvd1 : 31; +- u32 fms; +- u32 rsvd2; +- u8 gosvw[16]; +- u8 vmpck0[VMPCK_KEY_LEN]; +- u8 vmpck1[VMPCK_KEY_LEN]; +- u8 vmpck2[VMPCK_KEY_LEN]; +- u8 vmpck3[VMPCK_KEY_LEN]; +- struct secrets_os_area os_area; +- u8 rsvd3[3840]; +-} __packed; +- + #endif /* __VIRT_SEVGUEST_H__ */ diff --git a/patches.suse/x86-sev-Move-MSR-based-VMGEXITs-for-CPUID-to-helper b/patches.suse/x86-sev-Move-MSR-based-VMGEXITs-for-CPUID-to-helper new file mode 100644 index 0000000..36d1131 --- /dev/null +++ b/patches.suse/x86-sev-Move-MSR-based-VMGEXITs-for-CPUID-to-helper @@ -0,0 +1,161 @@ +From: Michael Roth +Date: Thu, 24 Feb 2022 10:56:11 -0600 +Subject: x86/sev: Move MSR-based VMGEXITs for CPUID to helper +Git-commit: 801baa693c1f6d7327475c39100c456db340cd3e +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +This code will also be used later for SEV-SNP-validated CPUID code in +some cases, so move it to a common helper. + +While here, also add a check to terminate in cases where the CPUID +function/subfunction is indexed and the subfunction is non-zero, since +the GHCB MSR protocol does not support non-zero subfunctions. + +Suggested-by: Sean Christopherson +Signed-off-by: Michael Roth +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220307213356.2797205-32-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/boot/compressed/sev.c | 1 + arch/x86/kernel/sev-shared.c | 83 ++++++++++++++++++++++++++++------------- + arch/x86/kernel/sev.c | 1 + 3 files changed, 59 insertions(+), 26 deletions(-) + +--- a/arch/x86/boot/compressed/sev.c ++++ b/arch/x86/boot/compressed/sev.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + + #include "error.h" + #include "../msr.h" +--- a/arch/x86/kernel/sev-shared.c ++++ b/arch/x86/kernel/sev-shared.c +@@ -14,6 +14,16 @@ + #define has_cpuflag(f) boot_cpu_has(f) + #endif + ++/* I/O parameters for CPUID-related helpers */ ++struct cpuid_leaf { ++ u32 fn; ++ u32 subfn; ++ u32 eax; ++ u32 ebx; ++ u32 ecx; ++ u32 edx; ++}; ++ + /* + * Since feature negotiation related variables are set early in the boot + * process they must reside in the .data section so as not to be zeroed +@@ -194,6 +204,44 @@ enum es_result sev_es_ghcb_hv_call(struc + return verify_exception_info(ghcb, ctxt); + } + ++static int __sev_cpuid_hv(u32 fn, int reg_idx, u32 *reg) ++{ ++ u64 val; ++ ++ sev_es_wr_ghcb_msr(GHCB_CPUID_REQ(fn, reg_idx)); ++ VMGEXIT(); ++ val = sev_es_rd_ghcb_msr(); ++ if (GHCB_RESP_CODE(val) != GHCB_MSR_CPUID_RESP) ++ return -EIO; ++ ++ *reg = (val >> 32); ++ ++ return 0; ++} ++ ++static int sev_cpuid_hv(struct cpuid_leaf *leaf) ++{ ++ int ret; ++ ++ /* ++ * MSR protocol does not support fetching non-zero subfunctions, but is ++ * sufficient to handle current early-boot cases. Should that change, ++ * make sure to report an error rather than ignoring the index and ++ * grabbing random values. If this issue arises in the future, handling ++ * can be added here to use GHCB-page protocol for cases that occur late ++ * enough in boot that GHCB page is available. ++ */ ++ if (cpuid_function_is_indexed(leaf->fn) && leaf->subfn) ++ return -EINVAL; ++ ++ ret = __sev_cpuid_hv(leaf->fn, GHCB_CPUID_REQ_EAX, &leaf->eax); ++ ret = ret ? : __sev_cpuid_hv(leaf->fn, GHCB_CPUID_REQ_EBX, &leaf->ebx); ++ ret = ret ? : __sev_cpuid_hv(leaf->fn, GHCB_CPUID_REQ_ECX, &leaf->ecx); ++ ret = ret ? : __sev_cpuid_hv(leaf->fn, GHCB_CPUID_REQ_EDX, &leaf->edx); ++ ++ return ret; ++} ++ + /* + * Boot VC Handler - This is the first VC handler during boot, there is no GHCB + * page yet, so it only supports the MSR based communication with the +@@ -201,40 +249,23 @@ enum es_result sev_es_ghcb_hv_call(struc + */ + void __init do_vc_no_ghcb(struct pt_regs *regs, unsigned long exit_code) + { ++ unsigned int subfn = lower_bits(regs->cx, 32); + unsigned int fn = lower_bits(regs->ax, 32); +- unsigned long val; ++ struct cpuid_leaf leaf; + + /* Only CPUID is supported via MSR protocol */ + if (exit_code != SVM_EXIT_CPUID) + goto fail; + +- sev_es_wr_ghcb_msr(GHCB_CPUID_REQ(fn, GHCB_CPUID_REQ_EAX)); +- VMGEXIT(); +- val = sev_es_rd_ghcb_msr(); +- if (GHCB_RESP_CODE(val) != GHCB_MSR_CPUID_RESP) +- goto fail; +- regs->ax = val >> 32; +- +- sev_es_wr_ghcb_msr(GHCB_CPUID_REQ(fn, GHCB_CPUID_REQ_EBX)); +- VMGEXIT(); +- val = sev_es_rd_ghcb_msr(); +- if (GHCB_RESP_CODE(val) != GHCB_MSR_CPUID_RESP) +- goto fail; +- regs->bx = val >> 32; +- +- sev_es_wr_ghcb_msr(GHCB_CPUID_REQ(fn, GHCB_CPUID_REQ_ECX)); +- VMGEXIT(); +- val = sev_es_rd_ghcb_msr(); +- if (GHCB_RESP_CODE(val) != GHCB_MSR_CPUID_RESP) ++ leaf.fn = fn; ++ leaf.subfn = subfn; ++ if (sev_cpuid_hv(&leaf)) + goto fail; +- regs->cx = val >> 32; + +- sev_es_wr_ghcb_msr(GHCB_CPUID_REQ(fn, GHCB_CPUID_REQ_EDX)); +- VMGEXIT(); +- val = sev_es_rd_ghcb_msr(); +- if (GHCB_RESP_CODE(val) != GHCB_MSR_CPUID_RESP) +- goto fail; +- regs->dx = val >> 32; ++ regs->ax = leaf.eax; ++ regs->bx = leaf.ebx; ++ regs->cx = leaf.ecx; ++ regs->dx = leaf.edx; + + /* + * This is a VC handler and the #VC is only raised when SEV-ES is +--- a/arch/x86/kernel/sev.c ++++ b/arch/x86/kernel/sev.c +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + + #define DR7_RESET_VALUE 0x400 + diff --git a/patches.suse/x86-sev-Provide-support-for-SNP-guest-request-NAEs b/patches.suse/x86-sev-Provide-support-for-SNP-guest-request-NAEs new file mode 100644 index 0000000..a95def9 --- /dev/null +++ b/patches.suse/x86-sev-Provide-support-for-SNP-guest-request-NAEs @@ -0,0 +1,160 @@ +From: Brijesh Singh +Date: Mon, 7 Mar 2022 15:33:51 -0600 +Subject: x86/sev: Provide support for SNP guest request NAEs +Git-commit: d5af44dde5461d125d1602ac913ab5c6bdf09b8b +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +Version 2 of GHCB specification provides SNP_GUEST_REQUEST and +SNP_EXT_GUEST_REQUEST NAE that can be used by the SNP guest to +communicate with the PSP. + +While at it, add a snp_issue_guest_request() helper that will be used by +driver or other subsystem to issue the request to PSP. + +See SEV-SNP firmware and GHCB spec for more details. + +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220307213356.2797205-42-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/include/asm/sev-common.h | 3 ++ + arch/x86/include/asm/sev.h | 14 +++++++++ + arch/x86/include/uapi/asm/svm.h | 4 ++ + arch/x86/kernel/sev.c | 57 ++++++++++++++++++++++++++++++++++++++ + 4 files changed, 78 insertions(+) + +--- a/arch/x86/include/asm/sev-common.h ++++ b/arch/x86/include/asm/sev-common.h +@@ -128,6 +128,9 @@ struct snp_psc_desc { + struct psc_entry entries[VMGEXIT_PSC_MAX_ENTRY]; + } __packed; + ++/* Guest message request error code */ ++#define SNP_GUEST_REQ_INVALID_LEN BIT_ULL(32) ++ + #define GHCB_MSR_TERM_REQ 0x100 + #define GHCB_MSR_TERM_REASON_SET_POS 12 + #define GHCB_MSR_TERM_REASON_SET_MASK 0xf +--- a/arch/x86/include/asm/sev.h ++++ b/arch/x86/include/asm/sev.h +@@ -87,6 +87,14 @@ extern bool handle_vc_boot_ghcb(struct p + + #define RMPADJUST_VMSA_PAGE_BIT BIT(16) + ++/* SNP Guest message request */ ++struct snp_req_data { ++ unsigned long req_gpa; ++ unsigned long resp_gpa; ++ unsigned long data_gpa; ++ unsigned int data_npages; ++}; ++ + #ifdef CONFIG_AMD_MEM_ENCRYPT + extern struct static_key_false sev_es_enable_key; + extern void __sev_es_ist_enter(struct pt_regs *regs); +@@ -154,6 +162,7 @@ void snp_set_memory_private(unsigned lon + void snp_set_wakeup_secondary_cpu(void); + bool snp_init(struct boot_params *bp); + void snp_abort(void); ++int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, unsigned long *fw_err); + #else + static inline void sev_es_ist_enter(struct pt_regs *regs) { } + static inline void sev_es_ist_exit(void) { } +@@ -173,6 +182,11 @@ static inline void snp_set_memory_privat + static inline void snp_set_wakeup_secondary_cpu(void) { } + static inline bool snp_init(struct boot_params *bp) { return false; } + static inline void snp_abort(void) { } ++static inline int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, ++ unsigned long *fw_err) ++{ ++ return -ENOTTY; ++} + #endif + + #endif +--- a/arch/x86/include/uapi/asm/svm.h ++++ b/arch/x86/include/uapi/asm/svm.h +@@ -109,6 +109,8 @@ + #define SVM_VMGEXIT_SET_AP_JUMP_TABLE 0 + #define SVM_VMGEXIT_GET_AP_JUMP_TABLE 1 + #define SVM_VMGEXIT_PSC 0x80000010 ++#define SVM_VMGEXIT_GUEST_REQUEST 0x80000011 ++#define SVM_VMGEXIT_EXT_GUEST_REQUEST 0x80000012 + #define SVM_VMGEXIT_AP_CREATION 0x80000013 + #define SVM_VMGEXIT_AP_CREATE_ON_INIT 0 + #define SVM_VMGEXIT_AP_CREATE 1 +@@ -225,6 +227,8 @@ + { SVM_VMGEXIT_AP_HLT_LOOP, "vmgexit_ap_hlt_loop" }, \ + { SVM_VMGEXIT_AP_JUMP_TABLE, "vmgexit_ap_jump_table" }, \ + { SVM_VMGEXIT_PSC, "vmgexit_page_state_change" }, \ ++ { SVM_VMGEXIT_GUEST_REQUEST, "vmgexit_guest_request" }, \ ++ { SVM_VMGEXIT_EXT_GUEST_REQUEST, "vmgexit_ext_guest_request" }, \ + { SVM_VMGEXIT_AP_CREATION, "vmgexit_ap_creation" }, \ + { SVM_VMGEXIT_HV_FEATURES, "vmgexit_hypervisor_feature" }, \ + { SVM_EXIT_ERR, "invalid_guest_state" } +--- a/arch/x86/kernel/sev.c ++++ b/arch/x86/kernel/sev.c +@@ -2196,3 +2196,60 @@ static int __init init_sev_config(char * + return 1; + } + __setup("sev=", init_sev_config); ++ ++int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, unsigned long *fw_err) ++{ ++ struct ghcb_state state; ++ struct es_em_ctxt ctxt; ++ unsigned long flags; ++ struct ghcb *ghcb; ++ int ret; ++ ++ if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP)) ++ return -ENODEV; ++ ++ if (!fw_err) ++ return -EINVAL; ++ ++ /* ++ * __sev_get_ghcb() needs to run with IRQs disabled because it is using ++ * a per-CPU GHCB. ++ */ ++ local_irq_save(flags); ++ ++ ghcb = __sev_get_ghcb(&state); ++ if (!ghcb) { ++ ret = -EIO; ++ goto e_restore_irq; ++ } ++ ++ vc_ghcb_invalidate(ghcb); ++ ++ if (exit_code == SVM_VMGEXIT_EXT_GUEST_REQUEST) { ++ ghcb_set_rax(ghcb, input->data_gpa); ++ ghcb_set_rbx(ghcb, input->data_npages); ++ } ++ ++ ret = sev_es_ghcb_hv_call(ghcb, true, &ctxt, exit_code, input->req_gpa, input->resp_gpa); ++ if (ret) ++ goto e_put; ++ ++ if (ghcb->save.sw_exit_info_2) { ++ /* Number of expected pages are returned in RBX */ ++ if (exit_code == SVM_VMGEXIT_EXT_GUEST_REQUEST && ++ ghcb->save.sw_exit_info_2 == SNP_GUEST_REQ_INVALID_LEN) ++ input->data_npages = ghcb_get_rbx(ghcb); ++ ++ *fw_err = ghcb->save.sw_exit_info_2; ++ ++ ret = -EIO; ++ } ++ ++e_put: ++ __sev_put_ghcb(&state); ++e_restore_irq: ++ local_irq_restore(flags); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(snp_issue_guest_request); diff --git a/patches.suse/x86-sev-Register-GHCB-memory-when-SEV-SNP-is-active b/patches.suse/x86-sev-Register-GHCB-memory-when-SEV-SNP-is-active new file mode 100644 index 0000000..1d61fdf --- /dev/null +++ b/patches.suse/x86-sev-Register-GHCB-memory-when-SEV-SNP-is-active @@ -0,0 +1,170 @@ +From: Brijesh Singh +Date: Wed, 9 Feb 2022 12:10:11 -0600 +Subject: x86/sev: Register GHCB memory when SEV-SNP is active +Git-commit: 95d33bfaa3e169cfec1926e0d0f0c6b0ea75d763 +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +The SEV-SNP guest is required by the GHCB spec to register the GHCB's +Guest Physical Address (GPA). This is because the hypervisor may prefer +that a guest uses a consistent and/or specific GPA for the GHCB associated +with a vCPU. For more information, see the GHCB specification section +"GHCB GPA Registration". + + [ bp: Cleanup comments. ] + +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220307213356.2797205-18-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/include/asm/sev.h | 2 + + arch/x86/kernel/cpu/common.c | 4 +++ + arch/x86/kernel/head64.c | 4 ++- + arch/x86/kernel/sev-shared.c | 2 - + arch/x86/kernel/sev.c | 46 +++++++++++++++++++++++++++++++------------ + 5 files changed, 44 insertions(+), 14 deletions(-) + +--- a/arch/x86/include/asm/sev.h ++++ b/arch/x86/include/asm/sev.h +@@ -122,6 +122,7 @@ static inline int pvalidate(unsigned lon + + return rc; + } ++void setup_ghcb(void); + #else + static inline void sev_es_ist_enter(struct pt_regs *regs) { } + static inline void sev_es_ist_exit(void) { } +@@ -130,6 +131,7 @@ static inline void sev_es_nmi_complete(v + static inline int sev_es_efi_map_ghcbs(pgd_t *pgd) { return 0; } + static inline int pvalidate(unsigned long vaddr, bool rmp_psize, bool validate) { return 0; } + static inline int rmpadjust(unsigned long vaddr, bool rmp_psize, unsigned long attrs) { return 0; } ++static inline void setup_ghcb(void) { } + #endif + + #endif +--- a/arch/x86/kernel/cpu/common.c ++++ b/arch/x86/kernel/cpu/common.c +@@ -59,6 +59,7 @@ + #include + #include + #include ++#include + + #include "cpu.h" + +@@ -1975,6 +1976,9 @@ void cpu_init_exception_handling(void) + + load_TR_desc(); + ++ /* GHCB needs to be setup to handle #VC. */ ++ setup_ghcb(); ++ + /* Finally load the IDT */ + load_current_idt(); + } +--- a/arch/x86/kernel/head64.c ++++ b/arch/x86/kernel/head64.c +@@ -583,8 +583,10 @@ static void startup_64_load_idt(unsigned + void early_setup_idt(void) + { + /* VMM Communication Exception */ +- if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT)) ++ if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT)) { ++ setup_ghcb(); + set_bringup_idt_handler(bringup_idt_table, X86_TRAP_VC, vc_boot_ghcb); ++ } + + bringup_idt_descr.address = (unsigned long)bringup_idt_table; + native_load_idt(&bringup_idt_descr); +--- a/arch/x86/kernel/sev-shared.c ++++ b/arch/x86/kernel/sev-shared.c +@@ -68,7 +68,7 @@ static u64 get_hv_features(void) + return GHCB_MSR_HV_FT_RESP_VAL(val); + } + +-static void __maybe_unused snp_register_ghcb_early(unsigned long paddr) ++static void snp_register_ghcb_early(unsigned long paddr) + { + unsigned long pfn = paddr >> PAGE_SHIFT; + u64 val; +--- a/arch/x86/kernel/sev.c ++++ b/arch/x86/kernel/sev.c +@@ -41,7 +41,7 @@ static struct ghcb boot_ghcb_page __bss_ + * Needs to be in the .data section because we need it NULL before bss is + * cleared + */ +-static struct ghcb __initdata *boot_ghcb; ++static struct ghcb *boot_ghcb __section(".data"); + + /* Bitmap of SEV features supported by the hypervisor */ + static u64 sev_hv_features __ro_after_init; +@@ -647,15 +647,39 @@ static enum es_result vc_handle_msr(stru + return ret; + } + +-/* +- * This function runs on the first #VC exception after the kernel +- * switched to virtual addresses. +- */ +-static bool __init sev_es_setup_ghcb(void) ++static void snp_register_per_cpu_ghcb(void) + { ++ struct sev_es_runtime_data *data; ++ struct ghcb *ghcb; ++ ++ data = this_cpu_read(runtime_data); ++ ghcb = &data->ghcb_page; ++ ++ snp_register_ghcb_early(__pa(ghcb)); ++} ++ ++void setup_ghcb(void) ++{ ++ if (!cc_platform_has(CC_ATTR_GUEST_STATE_ENCRYPT)) ++ return; ++ + /* First make sure the hypervisor talks a supported protocol. */ + if (!sev_es_negotiate_protocol()) +- return false; ++ sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SEV_ES_GEN_REQ); ++ ++ /* ++ * Check whether the runtime #VC exception handler is active. It uses ++ * the per-CPU GHCB page which is set up by sev_es_init_vc_handling(). ++ * ++ * If SNP is active, register the per-CPU GHCB page so that the runtime ++ * exception handler can use it. ++ */ ++ if (initial_vc_handler == (unsigned long)kernel_exc_vmm_communication) { ++ if (cc_platform_has(CC_ATTR_GUEST_SEV_SNP)) ++ snp_register_per_cpu_ghcb(); ++ ++ return; ++ } + + /* + * Clear the boot_ghcb. The first exception comes in before the bss +@@ -666,7 +690,9 @@ static bool __init sev_es_setup_ghcb(voi + /* Alright - Make the boot-ghcb public */ + boot_ghcb = &boot_ghcb_page; + +- return true; ++ /* SNP guest requires that GHCB GPA must be registered. */ ++ if (cc_platform_has(CC_ATTR_GUEST_SEV_SNP)) ++ snp_register_ghcb_early(__pa(&boot_ghcb_page)); + } + + #ifdef CONFIG_HOTPLUG_CPU +@@ -1487,10 +1513,6 @@ bool __init handle_vc_boot_ghcb(struct p + struct es_em_ctxt ctxt; + enum es_result result; + +- /* Do initial setup or terminate the guest */ +- if (unlikely(boot_ghcb == NULL && !sev_es_setup_ghcb())) +- sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SEV_ES_GEN_REQ); +- + vc_ghcb_invalidate(boot_ghcb); + + result = vc_init_em_ctxt(&ctxt, regs, exit_code); diff --git a/patches.suse/x86-sev-Register-SEV-SNP-guest-request-platform-device b/patches.suse/x86-sev-Register-SEV-SNP-guest-request-platform-device new file mode 100644 index 0000000..81044ed --- /dev/null +++ b/patches.suse/x86-sev-Register-SEV-SNP-guest-request-platform-device @@ -0,0 +1,121 @@ +From: Brijesh Singh +Date: Thu, 24 Feb 2022 10:56:21 -0600 +Subject: x86/sev: Register SEV-SNP guest request platform device +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Git-commit: 3a45b3753849c4a12cca2dd176c0192cd2a63e62 +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +Version 2 of the GHCB specification provides a Non Automatic Exit (NAE) +event type that can be used by the SEV-SNP guest to communicate with the +PSP without risk from a malicious hypervisor who wishes to read, alter, +drop or replay the messages sent. + +SNP_LAUNCH_UPDATE can insert two special pages into the guest’s memory: +the secrets page and the CPUID page. The PSP firmware populates the +contents of the secrets page. The secrets page contains encryption keys +used by the guest to interact with the firmware. Because the secrets +page is encrypted with the guest’s memory encryption key, the hypervisor +cannot read the keys. See SEV-SNP firmware spec for further details on +the secrets page format. + +Create a platform device that the SEV-SNP guest driver can bind to get +the platform resources such as encryption key and message id to use to +communicate with the PSP. The SEV-SNP guest driver provides a userspace +interface to get the attestation report, key derivation, extended +attestation report etc. + +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220307213356.2797205-43-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/include/asm/sev.h | 4 +++ + arch/x86/kernel/sev.c | 56 +++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 60 insertions(+) + +--- a/arch/x86/include/asm/sev.h ++++ b/arch/x86/include/asm/sev.h +@@ -95,6 +95,10 @@ struct snp_req_data { + unsigned int data_npages; + }; + ++struct snp_guest_platform_data { ++ u64 secrets_gpa; ++}; ++ + #ifdef CONFIG_AMD_MEM_ENCRYPT + extern struct static_key_false sev_es_enable_key; + extern void __sev_es_ist_enter(struct pt_regs *regs); +--- a/arch/x86/kernel/sev.c ++++ b/arch/x86/kernel/sev.c +@@ -19,6 +19,9 @@ + #include + #include + #include ++#include ++#include ++#include + + #include + #include +@@ -2253,3 +2256,56 @@ e_restore_irq: + return ret; + } + EXPORT_SYMBOL_GPL(snp_issue_guest_request); ++ ++static struct platform_device guest_req_device = { ++ .name = "snp-guest", ++ .id = -1, ++}; ++ ++static u64 get_secrets_page(void) ++{ ++ u64 pa_data = boot_params.cc_blob_address; ++ struct cc_blob_sev_info info; ++ void *map; ++ ++ /* ++ * The CC blob contains the address of the secrets page, check if the ++ * blob is present. ++ */ ++ if (!pa_data) ++ return 0; ++ ++ map = early_memremap(pa_data, sizeof(info)); ++ memcpy(&info, map, sizeof(info)); ++ early_memunmap(map, sizeof(info)); ++ ++ /* smoke-test the secrets page passed */ ++ if (!info.secrets_phys || info.secrets_len != PAGE_SIZE) ++ return 0; ++ ++ return info.secrets_phys; ++} ++ ++static int __init snp_init_platform_device(void) ++{ ++ struct snp_guest_platform_data data; ++ u64 gpa; ++ ++ if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP)) ++ return -ENODEV; ++ ++ gpa = get_secrets_page(); ++ if (!gpa) ++ return -ENODEV; ++ ++ data.secrets_gpa = gpa; ++ if (platform_device_add_data(&guest_req_device, &data, sizeof(data))) ++ return -ENODEV; ++ ++ if (platform_device_register(&guest_req_device)) ++ return -ENODEV; ++ ++ pr_info("SNP guest platform device initialized.\n"); ++ return 0; ++} ++device_initcall(snp_init_platform_device); diff --git a/patches.suse/x86-sev-Use-SEV-SNP-AP-creation-to-start-secondary-CPUs b/patches.suse/x86-sev-Use-SEV-SNP-AP-creation-to-start-secondary-CPUs new file mode 100644 index 0000000..196faff --- /dev/null +++ b/patches.suse/x86-sev-Use-SEV-SNP-AP-creation-to-start-secondary-CPUs @@ -0,0 +1,401 @@ +From: Tom Lendacky +Date: Mon, 7 Mar 2022 15:33:32 -0600 +Subject: x86/sev: Use SEV-SNP AP creation to start secondary CPUs +Git-commit: 0afb6b660a6b58cb336d1175ed687bf9525849a4 +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +To provide a more secure way to start APs under SEV-SNP, use the SEV-SNP +AP Creation NAE event. This allows for guest control over the AP register +state rather than trusting the hypervisor with the SEV-ES Jump Table +address. + +During native_smp_prepare_cpus(), invoke an SEV-SNP function that, if +SEV-SNP is active, will set/override apic->wakeup_secondary_cpu. This +will allow the SEV-SNP AP Creation NAE event method to be used to boot +the APs. As a result of installing the override when SEV-SNP is active, +this method of starting the APs becomes the required method. The override +function will fail to start the AP if the hypervisor does not have +support for AP creation. + + [ bp: Work in forgotten review comments. ] + +Signed-off-by: Tom Lendacky +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220307213356.2797205-23-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/include/asm/sev-common.h | 1 + + arch/x86/include/asm/sev.h | 4 + + arch/x86/include/uapi/asm/svm.h | 5 + + arch/x86/kernel/sev.c | 242 ++++++++++++++++++++++++++++++ + arch/x86/kernel/smpboot.c | 3 + + 5 files changed, 255 insertions(+) + +diff --git a/arch/x86/include/asm/sev-common.h b/arch/x86/include/asm/sev-common.h +index 1aa72b5c2490..e9b6815b3b3d 100644 +--- a/arch/x86/include/asm/sev-common.h ++++ b/arch/x86/include/asm/sev-common.h +@@ -104,6 +104,7 @@ enum psc_op { + (((u64)(v) & GENMASK_ULL(63, 12)) >> 12) + + #define GHCB_HV_FT_SNP BIT_ULL(0) ++#define GHCB_HV_FT_SNP_AP_CREATION BIT_ULL(1) + + /* SNP Page State Change NAE event */ + #define VMGEXIT_PSC_MAX_ENTRY 253 +diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h +index feeb93e6ec97..a3203b2caaca 100644 +--- a/arch/x86/include/asm/sev.h ++++ b/arch/x86/include/asm/sev.h +@@ -66,6 +66,8 @@ extern bool handle_vc_boot_ghcb(struct pt_regs *regs); + /* RMP page size */ + #define RMP_PG_SIZE_4K 0 + ++#define RMPADJUST_VMSA_PAGE_BIT BIT(16) ++ + #ifdef CONFIG_AMD_MEM_ENCRYPT + extern struct static_key_false sev_es_enable_key; + extern void __sev_es_ist_enter(struct pt_regs *regs); +@@ -130,6 +132,7 @@ void __init early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr + void __init snp_prep_memory(unsigned long paddr, unsigned int sz, enum psc_op op); + void snp_set_memory_shared(unsigned long vaddr, unsigned int npages); + void snp_set_memory_private(unsigned long vaddr, unsigned int npages); ++void snp_set_wakeup_secondary_cpu(void); + #else + static inline void sev_es_ist_enter(struct pt_regs *regs) { } + static inline void sev_es_ist_exit(void) { } +@@ -146,6 +149,7 @@ early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr, unsigned i + static inline void __init snp_prep_memory(unsigned long paddr, unsigned int sz, enum psc_op op) { } + static inline void snp_set_memory_shared(unsigned long vaddr, unsigned int npages) { } + static inline void snp_set_memory_private(unsigned long vaddr, unsigned int npages) { } ++static inline void snp_set_wakeup_secondary_cpu(void) { } + #endif + + #endif +diff --git a/arch/x86/include/uapi/asm/svm.h b/arch/x86/include/uapi/asm/svm.h +index 64404b47b773..cfea5e875088 100644 +--- a/arch/x86/include/uapi/asm/svm.h ++++ b/arch/x86/include/uapi/asm/svm.h +@@ -109,6 +109,10 @@ + #define SVM_VMGEXIT_SET_AP_JUMP_TABLE 0 + #define SVM_VMGEXIT_GET_AP_JUMP_TABLE 1 + #define SVM_VMGEXIT_PSC 0x80000010 ++#define SVM_VMGEXIT_AP_CREATION 0x80000013 ++#define SVM_VMGEXIT_AP_CREATE_ON_INIT 0 ++#define SVM_VMGEXIT_AP_CREATE 1 ++#define SVM_VMGEXIT_AP_DESTROY 2 + #define SVM_VMGEXIT_HV_FEATURES 0x8000fffd + #define SVM_VMGEXIT_UNSUPPORTED_EVENT 0x8000ffff + +@@ -221,6 +225,7 @@ + { SVM_VMGEXIT_AP_HLT_LOOP, "vmgexit_ap_hlt_loop" }, \ + { SVM_VMGEXIT_AP_JUMP_TABLE, "vmgexit_ap_jump_table" }, \ + { SVM_VMGEXIT_PSC, "vmgexit_page_state_change" }, \ ++ { SVM_VMGEXIT_AP_CREATION, "vmgexit_ap_creation" }, \ + { SVM_VMGEXIT_HV_FEATURES, "vmgexit_hypervisor_feature" }, \ + { SVM_EXIT_ERR, "invalid_guest_state" } + +diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c +index bf4b57835694..d7915ae7729d 100644 +--- a/arch/x86/kernel/sev.c ++++ b/arch/x86/kernel/sev.c +@@ -18,6 +18,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -31,9 +32,26 @@ + #include + #include + #include ++#include + + #define DR7_RESET_VALUE 0x400 + ++/* AP INIT values as documented in the APM2 section "Processor Initialization State" */ ++#define AP_INIT_CS_LIMIT 0xffff ++#define AP_INIT_DS_LIMIT 0xffff ++#define AP_INIT_LDTR_LIMIT 0xffff ++#define AP_INIT_GDTR_LIMIT 0xffff ++#define AP_INIT_IDTR_LIMIT 0xffff ++#define AP_INIT_TR_LIMIT 0xffff ++#define AP_INIT_RFLAGS_DEFAULT 0x2 ++#define AP_INIT_DR6_DEFAULT 0xffff0ff0 ++#define AP_INIT_GPAT_DEFAULT 0x0007040600070406ULL ++#define AP_INIT_XCR0_DEFAULT 0x1 ++#define AP_INIT_X87_FTW_DEFAULT 0x5555 ++#define AP_INIT_X87_FCW_DEFAULT 0x0040 ++#define AP_INIT_CR0_DEFAULT 0x60000010 ++#define AP_INIT_MXCSR_DEFAULT 0x1f80 ++ + /* For early boot hypervisor communication in SEV-ES enabled guests */ + static struct ghcb boot_ghcb_page __bss_decrypted __aligned(PAGE_SIZE); + +@@ -90,6 +108,8 @@ struct ghcb_state { + static DEFINE_PER_CPU(struct sev_es_runtime_data*, runtime_data); + DEFINE_STATIC_KEY_FALSE(sev_es_enable_key); + ++static DEFINE_PER_CPU(struct sev_es_save_area *, sev_vmsa); ++ + static __always_inline bool on_vc_stack(struct pt_regs *regs) + { + unsigned long sp = regs->sp; +@@ -823,6 +843,228 @@ void snp_set_memory_private(unsigned long vaddr, unsigned int npages) + pvalidate_pages(vaddr, npages, true); + } + ++static int snp_set_vmsa(void *va, bool vmsa) ++{ ++ u64 attrs; ++ ++ /* ++ * Running at VMPL0 allows the kernel to change the VMSA bit for a page ++ * using the RMPADJUST instruction. However, for the instruction to ++ * succeed it must target the permissions of a lesser privileged ++ * (higher numbered) VMPL level, so use VMPL1 (refer to the RMPADJUST ++ * instruction in the AMD64 APM Volume 3). ++ */ ++ attrs = 1; ++ if (vmsa) ++ attrs |= RMPADJUST_VMSA_PAGE_BIT; ++ ++ return rmpadjust((unsigned long)va, RMP_PG_SIZE_4K, attrs); ++} ++ ++#define __ATTR_BASE (SVM_SELECTOR_P_MASK | SVM_SELECTOR_S_MASK) ++#define INIT_CS_ATTRIBS (__ATTR_BASE | SVM_SELECTOR_READ_MASK | SVM_SELECTOR_CODE_MASK) ++#define INIT_DS_ATTRIBS (__ATTR_BASE | SVM_SELECTOR_WRITE_MASK) ++ ++#define INIT_LDTR_ATTRIBS (SVM_SELECTOR_P_MASK | 2) ++#define INIT_TR_ATTRIBS (SVM_SELECTOR_P_MASK | 3) ++ ++static void *snp_alloc_vmsa_page(void) ++{ ++ struct page *p; ++ ++ /* ++ * Allocate VMSA page to work around the SNP erratum where the CPU will ++ * incorrectly signal an RMP violation #PF if a large page (2MB or 1GB) ++ * collides with the RMP entry of VMSA page. The recommended workaround ++ * is to not use a large page. ++ * ++ * Allocate an 8k page which is also 8k-aligned. ++ */ ++ p = alloc_pages(GFP_KERNEL_ACCOUNT | __GFP_ZERO, 1); ++ if (!p) ++ return NULL; ++ ++ split_page(p, 1); ++ ++ /* Free the first 4k. This page may be 2M/1G aligned and cannot be used. */ ++ __free_page(p); ++ ++ return page_address(p + 1); ++} ++ ++static void snp_cleanup_vmsa(struct sev_es_save_area *vmsa) ++{ ++ int err; ++ ++ err = snp_set_vmsa(vmsa, false); ++ if (err) ++ pr_err("clear VMSA page failed (%u), leaking page\n", err); ++ else ++ free_page((unsigned long)vmsa); ++} ++ ++static int wakeup_cpu_via_vmgexit(int apic_id, unsigned long start_ip) ++{ ++ struct sev_es_save_area *cur_vmsa, *vmsa; ++ struct ghcb_state state; ++ unsigned long flags; ++ struct ghcb *ghcb; ++ u8 sipi_vector; ++ int cpu, ret; ++ u64 cr4; ++ ++ /* ++ * The hypervisor SNP feature support check has happened earlier, just check ++ * the AP_CREATION one here. ++ */ ++ if (!(sev_hv_features & GHCB_HV_FT_SNP_AP_CREATION)) ++ return -EOPNOTSUPP; ++ ++ /* ++ * Verify the desired start IP against the known trampoline start IP ++ * to catch any future new trampolines that may be introduced that ++ * would require a new protected guest entry point. ++ */ ++ if (WARN_ONCE(start_ip != real_mode_header->trampoline_start, ++ "Unsupported SNP start_ip: %lx\n", start_ip)) ++ return -EINVAL; ++ ++ /* Override start_ip with known protected guest start IP */ ++ start_ip = real_mode_header->sev_es_trampoline_start; ++ ++ /* Find the logical CPU for the APIC ID */ ++ for_each_present_cpu(cpu) { ++ if (arch_match_cpu_phys_id(cpu, apic_id)) ++ break; ++ } ++ if (cpu >= nr_cpu_ids) ++ return -EINVAL; ++ ++ cur_vmsa = per_cpu(sev_vmsa, cpu); ++ ++ /* ++ * A new VMSA is created each time because there is no guarantee that ++ * the current VMSA is the kernels or that the vCPU is not running. If ++ * an attempt was done to use the current VMSA with a running vCPU, a ++ * #VMEXIT of that vCPU would wipe out all of the settings being done ++ * here. ++ */ ++ vmsa = (struct sev_es_save_area *)snp_alloc_vmsa_page(); ++ if (!vmsa) ++ return -ENOMEM; ++ ++ /* CR4 should maintain the MCE value */ ++ cr4 = native_read_cr4() & X86_CR4_MCE; ++ ++ /* Set the CS value based on the start_ip converted to a SIPI vector */ ++ sipi_vector = (start_ip >> 12); ++ vmsa->cs.base = sipi_vector << 12; ++ vmsa->cs.limit = AP_INIT_CS_LIMIT; ++ vmsa->cs.attrib = INIT_CS_ATTRIBS; ++ vmsa->cs.selector = sipi_vector << 8; ++ ++ /* Set the RIP value based on start_ip */ ++ vmsa->rip = start_ip & 0xfff; ++ ++ /* Set AP INIT defaults as documented in the APM */ ++ vmsa->ds.limit = AP_INIT_DS_LIMIT; ++ vmsa->ds.attrib = INIT_DS_ATTRIBS; ++ vmsa->es = vmsa->ds; ++ vmsa->fs = vmsa->ds; ++ vmsa->gs = vmsa->ds; ++ vmsa->ss = vmsa->ds; ++ ++ vmsa->gdtr.limit = AP_INIT_GDTR_LIMIT; ++ vmsa->ldtr.limit = AP_INIT_LDTR_LIMIT; ++ vmsa->ldtr.attrib = INIT_LDTR_ATTRIBS; ++ vmsa->idtr.limit = AP_INIT_IDTR_LIMIT; ++ vmsa->tr.limit = AP_INIT_TR_LIMIT; ++ vmsa->tr.attrib = INIT_TR_ATTRIBS; ++ ++ vmsa->cr4 = cr4; ++ vmsa->cr0 = AP_INIT_CR0_DEFAULT; ++ vmsa->dr7 = DR7_RESET_VALUE; ++ vmsa->dr6 = AP_INIT_DR6_DEFAULT; ++ vmsa->rflags = AP_INIT_RFLAGS_DEFAULT; ++ vmsa->g_pat = AP_INIT_GPAT_DEFAULT; ++ vmsa->xcr0 = AP_INIT_XCR0_DEFAULT; ++ vmsa->mxcsr = AP_INIT_MXCSR_DEFAULT; ++ vmsa->x87_ftw = AP_INIT_X87_FTW_DEFAULT; ++ vmsa->x87_fcw = AP_INIT_X87_FCW_DEFAULT; ++ ++ /* SVME must be set. */ ++ vmsa->efer = EFER_SVME; ++ ++ /* ++ * Set the SNP-specific fields for this VMSA: ++ * VMPL level ++ * SEV_FEATURES (matches the SEV STATUS MSR right shifted 2 bits) ++ */ ++ vmsa->vmpl = 0; ++ vmsa->sev_features = sev_status >> 2; ++ ++ /* Switch the page over to a VMSA page now that it is initialized */ ++ ret = snp_set_vmsa(vmsa, true); ++ if (ret) { ++ pr_err("set VMSA page failed (%u)\n", ret); ++ free_page((unsigned long)vmsa); ++ ++ return -EINVAL; ++ } ++ ++ /* Issue VMGEXIT AP Creation NAE event */ ++ local_irq_save(flags); ++ ++ ghcb = __sev_get_ghcb(&state); ++ ++ vc_ghcb_invalidate(ghcb); ++ ghcb_set_rax(ghcb, vmsa->sev_features); ++ ghcb_set_sw_exit_code(ghcb, SVM_VMGEXIT_AP_CREATION); ++ ghcb_set_sw_exit_info_1(ghcb, ((u64)apic_id << 32) | SVM_VMGEXIT_AP_CREATE); ++ ghcb_set_sw_exit_info_2(ghcb, __pa(vmsa)); ++ ++ sev_es_wr_ghcb_msr(__pa(ghcb)); ++ VMGEXIT(); ++ ++ if (!ghcb_sw_exit_info_1_is_valid(ghcb) || ++ lower_32_bits(ghcb->save.sw_exit_info_1)) { ++ pr_err("SNP AP Creation error\n"); ++ ret = -EINVAL; ++ } ++ ++ __sev_put_ghcb(&state); ++ ++ local_irq_restore(flags); ++ ++ /* Perform cleanup if there was an error */ ++ if (ret) { ++ snp_cleanup_vmsa(vmsa); ++ vmsa = NULL; ++ } ++ ++ /* Free up any previous VMSA page */ ++ if (cur_vmsa) ++ snp_cleanup_vmsa(cur_vmsa); ++ ++ /* Record the current VMSA page */ ++ per_cpu(sev_vmsa, cpu) = vmsa; ++ ++ return ret; ++} ++ ++void snp_set_wakeup_secondary_cpu(void) ++{ ++ if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP)) ++ return; ++ ++ /* ++ * Always set this override if SNP is enabled. This makes it the ++ * required method to start APs under SNP. If the hypervisor does ++ * not support AP creation, then no APs will be started. ++ */ ++ apic->wakeup_secondary_cpu = wakeup_cpu_via_vmgexit; ++} ++ + int sev_es_setup_ap_jump_table(struct real_mode_header *rmh) + { + u16 startup_cs, startup_ip; +diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c +index 2ef14772dc04..85d7b1c5eb70 100644 +--- a/arch/x86/kernel/smpboot.c ++++ b/arch/x86/kernel/smpboot.c +@@ -82,6 +82,7 @@ + #include + #include + #include ++#include + + /* representing HT siblings of each logical CPU */ + DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_sibling_map); +@@ -1430,6 +1431,8 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus) + smp_quirk_init_udelay(); + + speculative_store_bypass_ht_init(); ++ ++ snp_set_wakeup_secondary_cpu(); + } + + void arch_thaw_secondary_cpus_begin(void) +-- +2.35.3 + diff --git a/patches.suse/x86-sev-Use-firmware-validated-CPUID-for-SEV-SNP-guests b/patches.suse/x86-sev-Use-firmware-validated-CPUID-for-SEV-SNP-guests new file mode 100644 index 0000000..5bc35fb --- /dev/null +++ b/patches.suse/x86-sev-Use-firmware-validated-CPUID-for-SEV-SNP-guests @@ -0,0 +1,163 @@ +From: Michael Roth +Date: Mon, 7 Mar 2022 15:33:49 -0600 +Subject: x86/sev: Use firmware-validated CPUID for SEV-SNP guests +Git-commit: 30612045e69d088f1effd748048ebb0e282984ec +Patch-mainline: v5.19-rc1 +References: jsc#SLE-19924, jsc#SLE-24814 + +SEV-SNP guests will be provided the location of special 'secrets' and +'CPUID' pages via the Confidential Computing blob. This blob is +provided to the run-time kernel either through a boot_params field that +was initialized by the boot/compressed kernel, or via a setup_data +structure as defined by the Linux Boot Protocol. + +Locate the Confidential Computing blob from these sources and, if found, +use the provided CPUID page/table address to create a copy that the +run-time kernel will use when servicing CPUID instructions via a #VC +handler. + +Signed-off-by: Michael Roth +Signed-off-by: Brijesh Singh +Signed-off-by: Borislav Petkov +Link: https://lore.kernel.org/r/20220307213356.2797205-40-brijesh.singh@amd.com + +Acked-by: Joerg Roedel +--- + arch/x86/boot/compressed/sev.c | 37 ------------------------------------- + arch/x86/kernel/sev-shared.c | 37 +++++++++++++++++++++++++++++++++++++ + arch/x86/kernel/sev.c | 24 ++++++++++++++++++++++++ + 3 files changed, 61 insertions(+), 37 deletions(-) + +--- a/arch/x86/boot/compressed/sev.c ++++ b/arch/x86/boot/compressed/sev.c +@@ -382,43 +382,6 @@ found_cc_info: + } + + /* +- * Initialize the kernel's copy of the SNP CPUID table, and set up the +- * pointer that will be used to access it. +- * +- * Maintaining a direct mapping of the SNP CPUID table used by firmware would +- * be possible as an alternative, but the approach is brittle since the +- * mapping needs to be updated in sync with all the changes to virtual memory +- * layout and related mapping facilities throughout the boot process. +- */ +-static void setup_cpuid_table(const struct cc_blob_sev_info *cc_info) +-{ +- const struct snp_cpuid_table *cpuid_table_fw, *cpuid_table; +- int i; +- +- if (!cc_info || !cc_info->cpuid_phys || cc_info->cpuid_len < PAGE_SIZE) +- sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_CPUID); +- +- cpuid_table_fw = (const struct snp_cpuid_table *)cc_info->cpuid_phys; +- if (!cpuid_table_fw->count || cpuid_table_fw->count > SNP_CPUID_COUNT_MAX) +- sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_CPUID); +- +- cpuid_table = snp_cpuid_get_table(); +- memcpy((void *)cpuid_table, cpuid_table_fw, sizeof(*cpuid_table)); +- +- /* Initialize CPUID ranges for range-checking. */ +- for (i = 0; i < cpuid_table->count; i++) { +- const struct snp_cpuid_fn *fn = &cpuid_table->fn[i]; +- +- if (fn->eax_in == 0x0) +- cpuid_std_range_max = fn->eax; +- else if (fn->eax_in == 0x40000000) +- cpuid_hyp_range_max = fn->eax; +- else if (fn->eax_in == 0x80000000) +- cpuid_ext_range_max = fn->eax; +- } +-} +- +-/* + * Indicate SNP based on presence of SNP-specific CC blob. Subsequent checks + * will verify the SNP CPUID/MSR bits. + */ +--- a/arch/x86/kernel/sev-shared.c ++++ b/arch/x86/kernel/sev-shared.c +@@ -964,3 +964,40 @@ static struct cc_blob_sev_info *find_cc_ + + return NULL; + } ++ ++/* ++ * Initialize the kernel's copy of the SNP CPUID table, and set up the ++ * pointer that will be used to access it. ++ * ++ * Maintaining a direct mapping of the SNP CPUID table used by firmware would ++ * be possible as an alternative, but the approach is brittle since the ++ * mapping needs to be updated in sync with all the changes to virtual memory ++ * layout and related mapping facilities throughout the boot process. ++ */ ++static void __init setup_cpuid_table(const struct cc_blob_sev_info *cc_info) ++{ ++ const struct snp_cpuid_table *cpuid_table_fw, *cpuid_table; ++ int i; ++ ++ if (!cc_info || !cc_info->cpuid_phys || cc_info->cpuid_len < PAGE_SIZE) ++ sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_CPUID); ++ ++ cpuid_table_fw = (const struct snp_cpuid_table *)cc_info->cpuid_phys; ++ if (!cpuid_table_fw->count || cpuid_table_fw->count > SNP_CPUID_COUNT_MAX) ++ sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_CPUID); ++ ++ cpuid_table = snp_cpuid_get_table(); ++ memcpy((void *)cpuid_table, cpuid_table_fw, sizeof(*cpuid_table)); ++ ++ /* Initialize CPUID ranges for range-checking. */ ++ for (i = 0; i < cpuid_table->count; i++) { ++ const struct snp_cpuid_fn *fn = &cpuid_table->fn[i]; ++ ++ if (fn->eax_in == 0x0) ++ cpuid_std_range_max = fn->eax; ++ else if (fn->eax_in == 0x40000000) ++ cpuid_hyp_range_max = fn->eax; ++ else if (fn->eax_in == 0x80000000) ++ cpuid_ext_range_max = fn->eax; ++ } ++} +--- a/arch/x86/kernel/sev.c ++++ b/arch/x86/kernel/sev.c +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + + #define DR7_RESET_VALUE 0x400 + +@@ -2115,6 +2116,8 @@ bool __init snp_init(struct boot_params + if (!cc_info) + return false; + ++ setup_cpuid_table(cc_info); ++ + /* + * The CC blob will be used later to access the secrets page. Cache + * it here like the boot kernel does. +@@ -2128,3 +2131,24 @@ void __init snp_abort(void) + { + sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED); + } ++ ++/* ++ * It is useful from an auditing/testing perspective to provide an easy way ++ * for the guest owner to know that the CPUID table has been initialized as ++ * expected, but that initialization happens too early in boot to print any ++ * sort of indicator, and there's not really any other good place to do it, ++ * so do it here. ++ */ ++static int __init report_cpuid_table(void) ++{ ++ const struct snp_cpuid_table *cpuid_table = snp_cpuid_get_table(); ++ ++ if (!cpuid_table->count) ++ return 0; ++ ++ pr_info("Using SNP CPUID table, %d entries present.\n", ++ cpuid_table->count); ++ ++ return 0; ++} ++arch_initcall(report_cpuid_table); diff --git a/patches.suse/x86-sev-define-the-linux-specific-guest-termination-reasons.patch b/patches.suse/x86-sev-define-the-linux-specific-guest-termination-reasons.patch index 186d545..3cd65e3 100644 --- a/patches.suse/x86-sev-define-the-linux-specific-guest-termination-reasons.patch +++ b/patches.suse/x86-sev-define-the-linux-specific-guest-termination-reasons.patch @@ -31,7 +31,7 @@ Link: https://lore.kernel.org/r/20220307213356.2797205-11-brijesh.singh@amd.com --- a/arch/x86/boot/compressed/sev.c +++ b/arch/x86/boot/compressed/sev.c -@@ -122,7 +122,7 @@ static enum es_result vc_read_mem(struct +@@ -119,7 +119,7 @@ static enum es_result vc_read_mem(struct static bool early_setup_sev_es(void) { if (!sev_es_negotiate_protocol()) @@ -40,7 +40,7 @@ Link: https://lore.kernel.org/r/20220307213356.2797205-11-brijesh.singh@amd.com if (set_page_decrypted((unsigned long)&boot_ghcb_page)) return false; -@@ -175,7 +175,7 @@ void do_boot_stage2_vc(struct pt_regs *r +@@ -172,7 +172,7 @@ void do_boot_stage2_vc(struct pt_regs *r enum es_result result; if (!boot_ghcb && !early_setup_sev_es()) @@ -49,13 +49,15 @@ Link: https://lore.kernel.org/r/20220307213356.2797205-11-brijesh.singh@amd.com vc_ghcb_invalidate(boot_ghcb); result = vc_init_em_ctxt(&ctxt, regs, exit_code); -@@ -202,5 +202,5 @@ finish: +@@ -199,7 +199,7 @@ finish: if (result == ES_OK) vc_finish_insn(&ctxt); else if (result != ES_RETRY) - sev_es_terminate(GHCB_SEV_ES_GEN_REQ); + sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SEV_ES_GEN_REQ); } + + void sev_enable(struct boot_params *bp) --- a/arch/x86/include/asm/sev-common.h +++ b/arch/x86/include/asm/sev-common.h @@ -73,9 +73,17 @@ @@ -76,26 +78,6 @@ Link: https://lore.kernel.org/r/20220307213356.2797205-11-brijesh.singh@amd.com #define GHCB_RESP_CODE(v) ((v) & GHCB_MSR_INFO_MASK) /* ---- a/arch/x86/kernel/sev.c -+++ b/arch/x86/kernel/sev.c -@@ -1427,7 +1427,7 @@ DEFINE_IDTENTRY_VC_KERNEL(exc_vmm_commun - show_regs(regs); - - /* Ask hypervisor to sev_es_terminate */ -- sev_es_terminate(GHCB_SEV_ES_GEN_REQ); -+ sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SEV_ES_GEN_REQ); - - /* If that fails and we get here - just panic */ - panic("Returned from Terminate-Request to Hypervisor\n"); -@@ -1475,7 +1475,7 @@ bool __init handle_vc_boot_ghcb(struct p - - /* Do initial setup or terminate the guest */ - if (unlikely(boot_ghcb == NULL && !sev_es_setup_ghcb())) -- sev_es_terminate(GHCB_SEV_ES_GEN_REQ); -+ sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SEV_ES_GEN_REQ); - - vc_ghcb_invalidate(boot_ghcb); - --- a/arch/x86/kernel/sev-shared.c +++ b/arch/x86/kernel/sev-shared.c @@ -24,15 +24,12 @@ static bool __init sev_es_check_cpu_feat @@ -126,3 +108,23 @@ Link: https://lore.kernel.org/r/20220307213356.2797205-11-brijesh.singh@amd.com } static enum es_result vc_insn_string_read(struct es_em_ctxt *ctxt, +--- a/arch/x86/kernel/sev.c ++++ b/arch/x86/kernel/sev.c +@@ -1427,7 +1427,7 @@ DEFINE_IDTENTRY_VC_KERNEL(exc_vmm_commun + show_regs(regs); + + /* Ask hypervisor to sev_es_terminate */ +- sev_es_terminate(GHCB_SEV_ES_GEN_REQ); ++ sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SEV_ES_GEN_REQ); + + /* If that fails and we get here - just panic */ + panic("Returned from Terminate-Request to Hypervisor\n"); +@@ -1475,7 +1475,7 @@ bool __init handle_vc_boot_ghcb(struct p + + /* Do initial setup or terminate the guest */ + if (unlikely(boot_ghcb == NULL && !sev_es_setup_ghcb())) +- sev_es_terminate(GHCB_SEV_ES_GEN_REQ); ++ sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SEV_ES_GEN_REQ); + + vc_ghcb_invalidate(boot_ghcb); + diff --git a/patches.suse/x86-xen-Remove-undefined-behavior-in-setup_features.patch b/patches.suse/x86-xen-Remove-undefined-behavior-in-setup_features.patch new file mode 100644 index 0000000..a2a971f --- /dev/null +++ b/patches.suse/x86-xen-Remove-undefined-behavior-in-setup_features.patch @@ -0,0 +1,33 @@ +Patch-mainline: v5.19-rc4 +Git-commit: ecb6237fa397b7b810d798ad19322eca466dbab1 +References: git-fixes +From: Julien Grall +Date: Fri, 17 Jun 2022 11:30:37 +0100 +Subject: [PATCH] x86/xen: Remove undefined behavior in setup_features() + +1 << 31 is undefined. So switch to 1U << 31. + +Fixes: 5ead97c84fa7 ("xen: Core Xen implementation") +Signed-off-by: Julien Grall +Reviewed-by: Juergen Gross +Link: https://lore.kernel.org/r/20220617103037.57828-1-julien@xen.org +Signed-off-by: Juergen Gross +--- + drivers/xen/features.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/xen/features.c b/drivers/xen/features.c +index 7b591443833c..87f1828d40d5 100644 +--- a/drivers/xen/features.c ++++ b/drivers/xen/features.c +@@ -42,6 +42,6 @@ void xen_setup_features(void) + if (HYPERVISOR_xen_version(XENVER_get_features, &fi) < 0) + break; + for (j = 0; j < 32; j++) +- xen_features[i * 32 + j] = !!(fi.submap & 1< +Date: Wed, 31 Aug 2022 16:58:22 +0000 +Subject: [PATCH] xen-blkback: Advertise feature-persistent as user requested +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The advertisement of the persistent grants feature (writing +'feature-persistent' to xenbus) should mean not the decision for using +the feature but only the availability of the feature. However, commit +aac8a70db24b ("xen-blkback: add a parameter for disabling of persistent +grants") made a field of blkback, which was a place for saving only the +negotiation result, to be used for yet another purpose: caching of the +'feature_persistent' parameter value. As a result, the advertisement, +which should follow only the parameter value, becomes inconsistent. + +This commit fixes the misuse of the semantic by making blkback saves the +parameter value in a separate place and advertises the support based on +only the saved value. + +Fixes: aac8a70db24b ("xen-blkback: add a parameter for disabling of persistent grants") +Cc: # 5.10.x +Suggested-by: Juergen Gross +Signed-off-by: SeongJae Park +Tested-by: Marek Marczykowski-Górecki +Reviewed-by: Juergen Gross +Link: https://lore.kernel.org/r/20220831165824.94815-2-sj@kernel.org +Signed-off-by: Juergen Gross +--- + drivers/block/xen-blkback/common.h | 3 +++ + drivers/block/xen-blkback/xenbus.c | 6 ++++-- + 2 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h +index bda5c815e441..a28473470e66 100644 +--- a/drivers/block/xen-blkback/common.h ++++ b/drivers/block/xen-blkback/common.h +@@ -226,6 +226,9 @@ struct xen_vbd { + sector_t size; + unsigned int flush_support:1; + unsigned int discard_secure:1; ++ /* Connect-time cached feature_persistent parameter value */ ++ unsigned int feature_gnt_persistent_parm:1; ++ /* Persistent grants feature negotiation result */ + unsigned int feature_gnt_persistent:1; + unsigned int overflow_max_grants:1; + }; +diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c +index ee7ad2fb432d..c0227dfa4688 100644 +--- a/drivers/block/xen-blkback/xenbus.c ++++ b/drivers/block/xen-blkback/xenbus.c +@@ -907,7 +907,7 @@ static void connect(struct backend_info *be) + xen_blkbk_barrier(xbt, be, be->blkif->vbd.flush_support); + + err = xenbus_printf(xbt, dev->nodename, "feature-persistent", "%u", +- be->blkif->vbd.feature_gnt_persistent); ++ be->blkif->vbd.feature_gnt_persistent_parm); + if (err) { + xenbus_dev_fatal(dev, err, "writing %s/feature-persistent", + dev->nodename); +@@ -1085,7 +1085,9 @@ static int connect_ring(struct backend_info *be) + return -ENOSYS; + } + +- blkif->vbd.feature_gnt_persistent = feature_persistent && ++ blkif->vbd.feature_gnt_persistent_parm = feature_persistent; ++ blkif->vbd.feature_gnt_persistent = ++ blkif->vbd.feature_gnt_persistent_parm && + xenbus_read_unsigned(dev->otherend, "feature-persistent", 0); + + blkif->vbd.overflow_max_grants = 0; +-- +2.35.3 + diff --git a/patches.suse/xen-blkback-Apply-feature_persistent-parameter-when-.patch b/patches.suse/xen-blkback-Apply-feature_persistent-parameter-when-.patch new file mode 100644 index 0000000..49277bc --- /dev/null +++ b/patches.suse/xen-blkback-Apply-feature_persistent-parameter-when-.patch @@ -0,0 +1,82 @@ +Patch-mainline: v6.0-rc1 +Git-commit: e94c6101e151b019b8babc518ac2a6ada644a5a1 +References: git-fixes +From: Maximilian Heyne +Date: Fri, 15 Jul 2022 22:51:07 +0000 +Subject: [PATCH] xen-blkback: Apply 'feature_persistent' parameter when + connect + +In some use cases[1], the backend is created while the frontend doesn't +support the persistent grants feature, but later the frontend can be +changed to support the feature and reconnect. In the past, 'blkback' +enabled the persistent grants feature since it unconditionally checked +if frontend supports the persistent grants feature for every connect +('connect_ring()') and decided whether it should use persistent grans or +not. + +However, commit aac8a70db24b ("xen-blkback: add a parameter for +disabling of persistent grants") has mistakenly changed the behavior. +It made the frontend feature support check to not be repeated once it +shown the 'feature_persistent' as 'false', or the frontend doesn't +support persistent grants. + +This commit changes the behavior of the parameter to make effect for +every connect, so that the previous workflow can work again as expected. + +[1] https://lore.kernel.org/xen-devel/CAJwUmVB6H3iTs-C+U=v-pwJB7-_ZRHPxHzKRJZ22xEPW7z8a=g@mail.gmail.com/ + +Reported-by: Andrii Chepurnyi +Fixes: aac8a70db24b ("xen-blkback: add a parameter for disabling of persistent grants") +Cc: # 5.10.x +Signed-off-by: Maximilian Heyne +Signed-off-by: SeongJae Park +Reviewed-by: Maximilian Heyne +Reviewed-by: Juergen Gross +Link: https://lore.kernel.org/r/20220715225108.193398-3-sj@kernel.org +Signed-off-by: Juergen Gross +--- + Documentation/ABI/testing/sysfs-driver-xen-blkback | 2 +- + drivers/block/xen-blkback/xenbus.c | 9 +++------ + 2 files changed, 4 insertions(+), 7 deletions(-) + +diff --git a/Documentation/ABI/testing/sysfs-driver-xen-blkback b/Documentation/ABI/testing/sysfs-driver-xen-blkback +index 7faf719af165..fac0f429a869 100644 +--- a/Documentation/ABI/testing/sysfs-driver-xen-blkback ++++ b/Documentation/ABI/testing/sysfs-driver-xen-blkback +@@ -42,5 +42,5 @@ KernelVersion: 5.10 + Contact: SeongJae Park + Description: + Whether to enable the persistent grants feature or not. Note +- that this option only takes effect on newly created backends. ++ that this option only takes effect on newly connected backends. + The default is Y (enable). +diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c +index 16c6785d260c..ee7ad2fb432d 100644 +--- a/drivers/block/xen-blkback/xenbus.c ++++ b/drivers/block/xen-blkback/xenbus.c +@@ -186,8 +186,6 @@ static struct xen_blkif *xen_blkif_alloc(domid_t domid) + __module_get(THIS_MODULE); + INIT_WORK(&blkif->free_work, xen_blkif_deferred_free); + +- blkif->vbd.feature_gnt_persistent = feature_persistent; +- + return blkif; + } + +@@ -1086,10 +1084,9 @@ static int connect_ring(struct backend_info *be) + xenbus_dev_fatal(dev, err, "unknown fe protocol %s", protocol); + return -ENOSYS; + } +- if (blkif->vbd.feature_gnt_persistent) +- blkif->vbd.feature_gnt_persistent = +- xenbus_read_unsigned(dev->otherend, +- "feature-persistent", 0); ++ ++ blkif->vbd.feature_gnt_persistent = feature_persistent && ++ xenbus_read_unsigned(dev->otherend, "feature-persistent", 0); + + blkif->vbd.overflow_max_grants = 0; + +-- +2.35.3 + diff --git a/patches.suse/xen-blkback-fix-persistent-grants-negotiation.patch b/patches.suse/xen-blkback-fix-persistent-grants-negotiation.patch new file mode 100644 index 0000000..24d2e49 --- /dev/null +++ b/patches.suse/xen-blkback-fix-persistent-grants-negotiation.patch @@ -0,0 +1,92 @@ +Patch-mainline: v6.0-rc1 +Git-commit: fc9be616bb8f3ed9cf560308f86904f5c06be205 +References: git-fixes +From: SeongJae Park +Date: Fri, 15 Jul 2022 22:51:06 +0000 +Subject: [PATCH] xen-blkback: fix persistent grants negotiation + +Persistent grants feature can be used only when both backend and the +frontend supports the feature. The feature was always supported by +'blkback', but commit aac8a70db24b ("xen-blkback: add a parameter for +disabling of persistent grants") has introduced a parameter for +disabling it runtime. + +To avoid the parameter be updated while being used by 'blkback', the +commit caches the parameter into 'vbd->feature_gnt_persistent' in +'xen_vbd_create()', and then check if the guest also supports the +feature and finally updates the field in 'connect_ring()'. + +However, 'connect_ring()' could be called before 'xen_vbd_create()', so +later execution of 'xen_vbd_create()' can wrongly overwrite 'true' to +'vbd->feature_gnt_persistent'. As a result, 'blkback' could try to use +'persistent grants' feature even if the guest doesn't support the +feature. + +This commit fixes the issue by moving the parameter value caching to +'xen_blkif_alloc()', which allocates the 'blkif'. Because the struct +embeds 'vbd' object, which will be used by 'connect_ring()' later, this +should be called before 'connect_ring()' and therefore this should be +the right and safe place to do the caching. + +Fixes: aac8a70db24b ("xen-blkback: add a parameter for disabling of persistent grants") +Cc: # 5.10.x +Signed-off-by: Maximilian Heyne +Signed-off-by: SeongJae Park +Reviewed-by: Maximilian Heyne +Reviewed-by: Juergen Gross +Link: https://lore.kernel.org/r/20220715225108.193398-2-sj@kernel.org +Signed-off-by: Juergen Gross +--- + drivers/block/xen-blkback/xenbus.c | 15 +++++++-------- + 1 file changed, 7 insertions(+), 8 deletions(-) + +diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c +index 97de13b14175..16c6785d260c 100644 +--- a/drivers/block/xen-blkback/xenbus.c ++++ b/drivers/block/xen-blkback/xenbus.c +@@ -157,6 +157,11 @@ static int xen_blkif_alloc_rings(struct xen_blkif *blkif) + return 0; + } + ++/* Enable the persistent grants feature. */ ++static bool feature_persistent = true; ++module_param(feature_persistent, bool, 0644); ++MODULE_PARM_DESC(feature_persistent, "Enables the persistent grants feature"); ++ + static struct xen_blkif *xen_blkif_alloc(domid_t domid) + { + struct xen_blkif *blkif; +@@ -181,6 +186,8 @@ static struct xen_blkif *xen_blkif_alloc(domid_t domid) + __module_get(THIS_MODULE); + INIT_WORK(&blkif->free_work, xen_blkif_deferred_free); + ++ blkif->vbd.feature_gnt_persistent = feature_persistent; ++ + return blkif; + } + +@@ -472,12 +479,6 @@ static void xen_vbd_free(struct xen_vbd *vbd) + vbd->bdev = NULL; + } + +-/* Enable the persistent grants feature. */ +-static bool feature_persistent = true; +-module_param(feature_persistent, bool, 0644); +-MODULE_PARM_DESC(feature_persistent, +- "Enables the persistent grants feature"); +- + static int xen_vbd_create(struct xen_blkif *blkif, blkif_vdev_t handle, + unsigned major, unsigned minor, int readonly, + int cdrom) +@@ -520,8 +521,6 @@ static int xen_vbd_create(struct xen_blkif *blkif, blkif_vdev_t handle, + if (q && blk_queue_secure_erase(q)) + vbd->discard_secure = true; + +- vbd->feature_gnt_persistent = feature_persistent; +- + pr_debug("Successful creation of handle=%04x (dom=%u)\n", + handle, blkif->domid); + return 0; +-- +2.35.3 + diff --git a/patches.suse/xen-blkfront-Advertise-feature-persistent-as-user-re.patch b/patches.suse/xen-blkfront-Advertise-feature-persistent-as-user-re.patch new file mode 100644 index 0000000..285f270 --- /dev/null +++ b/patches.suse/xen-blkfront-Advertise-feature-persistent-as-user-re.patch @@ -0,0 +1,71 @@ +Patch-mainline: v6.0-rc4 +Git-commit: 9f5e0fe5d05f7e8de7f39b2b10089834eb0ff787 +References: git-fixes +From: SeongJae Park +Date: Wed, 31 Aug 2022 16:58:23 +0000 +Subject: [PATCH] xen-blkfront: Advertise feature-persistent as user requested +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The advertisement of the persistent grants feature (writing +'feature-persistent' to xenbus) should mean not the decision for using +the feature but only the availability of the feature. However, commit +74a852479c68 ("xen-blkfront: add a parameter for disabling of persistent +grants") made a field of blkfront, which was a place for saving only the +negotiation result, to be used for yet another purpose: caching of the +'feature_persistent' parameter value. As a result, the advertisement, +which should follow only the parameter value, becomes inconsistent. + +This commit fixes the misuse of the semantic by making blkfront saves +the parameter value in a separate place and advertises the support based +on only the saved value. + +Fixes: 74a852479c68 ("xen-blkfront: add a parameter for disabling of persistent grants") +Cc: # 5.10.x +Suggested-by: Juergen Gross +Signed-off-by: SeongJae Park +Tested-by: Marek Marczykowski-Górecki +Reviewed-by: Juergen Gross +Link: https://lore.kernel.org/r/20220831165824.94815-3-sj@kernel.org +Signed-off-by: Juergen Gross +--- + drivers/block/xen-blkfront.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c +index 4e763701b372..276b2ee2a155 100644 +--- a/drivers/block/xen-blkfront.c ++++ b/drivers/block/xen-blkfront.c +@@ -213,6 +213,9 @@ struct blkfront_info + unsigned int feature_fua:1; + unsigned int feature_discard:1; + unsigned int feature_secdiscard:1; ++ /* Connect-time cached feature_persistent parameter */ ++ unsigned int feature_persistent_parm:1; ++ /* Persistent grants feature negotiation result */ + unsigned int feature_persistent:1; + unsigned int bounce:1; + unsigned int discard_granularity; +@@ -1848,7 +1851,7 @@ static int talk_to_blkback(struct xenbus_device *dev, + goto abort_transaction; + } + err = xenbus_printf(xbt, dev->nodename, "feature-persistent", "%u", +- info->feature_persistent); ++ info->feature_persistent_parm); + if (err) + dev_warn(&dev->dev, + "writing persistent grants feature to xenbus"); +@@ -2281,7 +2284,8 @@ static void blkfront_gather_backend_features(struct blkfront_info *info) + if (xenbus_read_unsigned(info->xbdev->otherend, "feature-discard", 0)) + blkfront_setup_discard(info); + +- if (feature_persistent) ++ info->feature_persistent_parm = feature_persistent; ++ if (info->feature_persistent_parm) + info->feature_persistent = + !!xenbus_read_unsigned(info->xbdev->otherend, + "feature-persistent", 0); +-- +2.35.3 + diff --git a/patches.suse/xen-blkfront-Apply-feature_persistent-parameter-when.patch b/patches.suse/xen-blkfront-Apply-feature_persistent-parameter-when.patch new file mode 100644 index 0000000..989c74c --- /dev/null +++ b/patches.suse/xen-blkfront-Apply-feature_persistent-parameter-when.patch @@ -0,0 +1,78 @@ +Patch-mainline: v6.0-rc1 +Git-commit: 402c43ea6b34a1b371ffeed9adf907402569eaf5 +References: git-fixes +From: SeongJae Park +Date: Fri, 15 Jul 2022 22:51:08 +0000 +Subject: [PATCH] xen-blkfront: Apply 'feature_persistent' parameter when + connect + +In some use cases[1], the backend is created while the frontend doesn't +support the persistent grants feature, but later the frontend can be +changed to support the feature and reconnect. In the past, 'blkback' +enabled the persistent grants feature since it unconditionally checked +if frontend supports the persistent grants feature for every connect +('connect_ring()') and decided whether it should use persistent grans or +not. + +However, commit aac8a70db24b ("xen-blkback: add a parameter for +disabling of persistent grants") has mistakenly changed the behavior. +It made the frontend feature support check to not be repeated once it +shown the 'feature_persistent' as 'false', or the frontend doesn't +support persistent grants. + +Similar behavioral change has made on 'blkfront' by commit 74a852479c68 +("xen-blkfront: add a parameter for disabling of persistent grants"). +This commit changes the behavior of the parameter to make effect for +every connect, so that the previous behavior of 'blkfront' can be +restored. + +[1] https://lore.kernel.org/xen-devel/CAJwUmVB6H3iTs-C+U=v-pwJB7-_ZRHPxHzKRJZ22xEPW7z8a=g@mail.gmail.com/ + +Fixes: 74a852479c68 ("xen-blkfront: add a parameter for disabling of persistent grants") +Cc: # 5.10.x +Signed-off-by: SeongJae Park +Reviewed-by: Maximilian Heyne +Reviewed-by: Juergen Gross +Link: https://lore.kernel.org/r/20220715225108.193398-4-sj@kernel.org +Signed-off-by: Juergen Gross +--- + Documentation/ABI/testing/sysfs-driver-xen-blkfront | 2 +- + drivers/block/xen-blkfront.c | 4 +--- + 2 files changed, 2 insertions(+), 4 deletions(-) + +diff --git a/Documentation/ABI/testing/sysfs-driver-xen-blkfront b/Documentation/ABI/testing/sysfs-driver-xen-blkfront +index 7f646c58832e..4d36c5a10546 100644 +--- a/Documentation/ABI/testing/sysfs-driver-xen-blkfront ++++ b/Documentation/ABI/testing/sysfs-driver-xen-blkfront +@@ -15,5 +15,5 @@ KernelVersion: 5.10 + Contact: SeongJae Park + Description: + Whether to enable the persistent grants feature or not. Note +- that this option only takes effect on newly created frontends. ++ that this option only takes effect on newly connected frontends. + The default is Y (enable). +diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c +index 3646c0cae672..4e763701b372 100644 +--- a/drivers/block/xen-blkfront.c ++++ b/drivers/block/xen-blkfront.c +@@ -1988,8 +1988,6 @@ static int blkfront_probe(struct xenbus_device *dev, + info->vdevice = vdevice; + info->connected = BLKIF_STATE_DISCONNECTED; + +- info->feature_persistent = feature_persistent; +- + /* Front end dir is a number, which is used as the id. */ + info->handle = simple_strtoul(strrchr(dev->nodename, '/')+1, NULL, 0); + dev_set_drvdata(&dev->dev, info); +@@ -2283,7 +2281,7 @@ static void blkfront_gather_backend_features(struct blkfront_info *info) + if (xenbus_read_unsigned(info->xbdev->otherend, "feature-discard", 0)) + blkfront_setup_discard(info); + +- if (info->feature_persistent) ++ if (feature_persistent) + info->feature_persistent = + !!xenbus_read_unsigned(info->xbdev->otherend, + "feature-persistent", 0); +-- +2.35.3 + diff --git a/patches.suse/xen-blkfront-Cache-feature_persistent-value-before-a.patch b/patches.suse/xen-blkfront-Cache-feature_persistent-value-before-a.patch new file mode 100644 index 0000000..9b7bba9 --- /dev/null +++ b/patches.suse/xen-blkfront-Cache-feature_persistent-value-before-a.patch @@ -0,0 +1,90 @@ +Patch-mainline: v6.0-rc4 +Git-commit: fe8f65b018effbf473f53af3538d0c1878b8b329 +References: git-fixes +From: SeongJae Park +Date: Wed, 31 Aug 2022 16:58:24 +0000 +Subject: [PATCH] xen-blkfront: Cache feature_persistent value before + advertisement +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Xen blkfront advertises its support of the persistent grants feature +when it first setting up and when resuming in 'talk_to_blkback()'. +Then, blkback reads the advertised value when it connects with blkfront +and decides if it will use the persistent grants feature or not, and +advertises its decision to blkfront. Blkfront reads the blkback's +decision and it also makes the decision for the use of the feature. + +Commit 402c43ea6b34 ("xen-blkfront: Apply 'feature_persistent' parameter +when connect"), however, made the blkfront's read of the parameter for +disabling the advertisement, namely 'feature_persistent', to be done +when it negotiate, not when advertise. Therefore blkfront advertises +without reading the parameter. As the field for caching the parameter +value is zero-initialized, it always advertises as the feature is +disabled, so that the persistent grants feature becomes always disabled. + +This commit fixes the issue by making the blkfront does parmeter caching +just before the advertisement. + +Fixes: 402c43ea6b34 ("xen-blkfront: Apply 'feature_persistent' parameter when connect") +Cc: # 5.10.x +Reported-by: Marek Marczykowski-Górecki +Signed-off-by: SeongJae Park +Tested-by: Marek Marczykowski-Górecki +Reviewed-by: Juergen Gross +Link: https://lore.kernel.org/r/20220831165824.94815-4-sj@kernel.org +Signed-off-by: Juergen Gross +--- + drivers/block/xen-blkfront.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c +index 276b2ee2a155..1f85750f981e 100644 +--- a/drivers/block/xen-blkfront.c ++++ b/drivers/block/xen-blkfront.c +@@ -1759,6 +1759,12 @@ static int write_per_ring_nodes(struct xenbus_transaction xbt, + return err; + } + ++/* Enable the persistent grants feature. */ ++static bool feature_persistent = true; ++module_param(feature_persistent, bool, 0644); ++MODULE_PARM_DESC(feature_persistent, ++ "Enables the persistent grants feature"); ++ + /* Common code used when first setting up, and when resuming. */ + static int talk_to_blkback(struct xenbus_device *dev, + struct blkfront_info *info) +@@ -1850,6 +1856,7 @@ static int talk_to_blkback(struct xenbus_device *dev, + message = "writing protocol"; + goto abort_transaction; + } ++ info->feature_persistent_parm = feature_persistent; + err = xenbus_printf(xbt, dev->nodename, "feature-persistent", "%u", + info->feature_persistent_parm); + if (err) +@@ -1919,12 +1926,6 @@ static int negotiate_mq(struct blkfront_info *info) + return 0; + } + +-/* Enable the persistent grants feature. */ +-static bool feature_persistent = true; +-module_param(feature_persistent, bool, 0644); +-MODULE_PARM_DESC(feature_persistent, +- "Enables the persistent grants feature"); +- + /* + * Entry point to this code when a new device is created. Allocate the basic + * structures and the ring buffer for communication with the backend, and +@@ -2284,7 +2285,6 @@ static void blkfront_gather_backend_features(struct blkfront_info *info) + if (xenbus_read_unsigned(info->xbdev->otherend, "feature-discard", 0)) + blkfront_setup_discard(info); + +- info->feature_persistent_parm = feature_persistent; + if (info->feature_persistent_parm) + info->feature_persistent = + !!xenbus_read_unsigned(info->xbdev->otherend, +-- +2.35.3 + diff --git a/patches.suse/xen-blkfront-Handle-NULL-gendisk.patch b/patches.suse/xen-blkfront-Handle-NULL-gendisk.patch new file mode 100644 index 0000000..fb75936 --- /dev/null +++ b/patches.suse/xen-blkfront-Handle-NULL-gendisk.patch @@ -0,0 +1,140 @@ +Patch-mainline: v5.19-rc4 +Git-commit: f9710c357e5bbf64d7ce45ba0bc75a52222491c1 +References: git-fixes +From: Jason Andryuk +Date: Wed, 1 Jun 2022 15:53:41 -0400 +Subject: [PATCH] xen-blkfront: Handle NULL gendisk +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When a VBD is not fully created and then closed, the kernel can have a +NULL pointer dereference: + +The reproducer is trivial: + +[user@dom0 ~]$ sudo xl block-attach work backend=sys-usb vdev=xvdi target=/dev/sdz +[user@dom0 ~]$ xl block-list work +Vdev BE handle state evt-ch ring-ref BE-path +51712 0 241 4 -1 -1 /local/domain/0/backend/vbd/241/51712 +51728 0 241 4 -1 -1 /local/domain/0/backend/vbd/241/51728 +51744 0 241 4 -1 -1 /local/domain/0/backend/vbd/241/51744 +51760 0 241 4 -1 -1 /local/domain/0/backend/vbd/241/51760 +51840 3 241 3 -1 -1 /local/domain/3/backend/vbd/241/51840 + ^ note state, the /dev/sdz doesn't exist in the backend + +[user@dom0 ~]$ sudo xl block-detach work xvdi +[user@dom0 ~]$ xl block-list work +Vdev BE handle state evt-ch ring-ref BE-path +work is an invalid domain identifier + +And its console has: + +BUG: kernel NULL pointer dereference, address: 0000000000000050 +PGD 80000000edebb067 P4D 80000000edebb067 PUD edec2067 PMD 0 +Oops: 0000 [#1] PREEMPT SMP PTI +CPU: 1 PID: 52 Comm: xenwatch Not tainted 5.16.18-2.43.fc32.qubes.x86_64 #1 +RIP: 0010:blk_mq_stop_hw_queues+0x5/0x40 +Code: 00 48 83 e0 fd 83 c3 01 48 89 85 a8 00 00 00 41 39 5c 24 50 77 c0 5b 5d 41 5c 41 5d c3 c3 0f 1f 80 00 00 00 00 0f 1f 44 00 00 <8b> 47 50 85 c0 74 32 41 54 49 89 fc 55 53 31 db 49 8b 44 24 48 48 +RSP: 0018:ffffc90000bcfe98 EFLAGS: 00010293 +RAX: ffffffffc0008370 RBX: 0000000000000005 RCX: 0000000000000000 +RDX: 0000000000000000 RSI: 0000000000000005 RDI: 0000000000000000 +RBP: ffff88800775f000 R08: 0000000000000001 R09: ffff888006e620b8 +R10: ffff888006e620b0 R11: f000000000000000 R12: ffff8880bff39000 +R13: ffff8880bff39000 R14: 0000000000000000 R15: ffff88800604be00 +FS: 0000000000000000(0000) GS:ffff8880f3300000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 0000000000000050 CR3: 00000000e932e002 CR4: 00000000003706e0 +Call Trace: + + blkback_changed+0x95/0x137 [xen_blkfront] + ? read_reply+0x160/0x160 + xenwatch_thread+0xc0/0x1a0 + ? do_wait_intr_irq+0xa0/0xa0 + kthread+0x16b/0x190 + ? set_kthread_struct+0x40/0x40 + ret_from_fork+0x22/0x30 + +Modules linked in: snd_seq_dummy snd_hrtimer snd_seq snd_seq_device snd_timer snd soundcore ipt_REJECT nf_reject_ipv4 xt_state xt_conntrack nft_counter nft_chain_nat xt_MASQUERADE nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 nft_compat nf_tables nfnetlink intel_rapl_msr intel_rapl_common crct10dif_pclmul crc32_pclmul crc32c_intel ghash_clmulni_intel xen_netfront pcspkr xen_scsiback target_core_mod xen_netback xen_privcmd xen_gntdev xen_gntalloc xen_blkback xen_evtchn ipmi_devintf ipmi_msghandler fuse bpf_preload ip_tables overlay xen_blkfront +CR2: 0000000000000050 +---[ end trace 7bc9597fd06ae89d ]--- +RIP: 0010:blk_mq_stop_hw_queues+0x5/0x40 +Code: 00 48 83 e0 fd 83 c3 01 48 89 85 a8 00 00 00 41 39 5c 24 50 77 c0 5b 5d 41 5c 41 5d c3 c3 0f 1f 80 00 00 00 00 0f 1f 44 00 00 <8b> 47 50 85 c0 74 32 41 54 49 89 fc 55 53 31 db 49 8b 44 24 48 48 +RSP: 0018:ffffc90000bcfe98 EFLAGS: 00010293 +RAX: ffffffffc0008370 RBX: 0000000000000005 RCX: 0000000000000000 +RDX: 0000000000000000 RSI: 0000000000000005 RDI: 0000000000000000 +RBP: ffff88800775f000 R08: 0000000000000001 R09: ffff888006e620b8 +R10: ffff888006e620b0 R11: f000000000000000 R12: ffff8880bff39000 +R13: ffff8880bff39000 R14: 0000000000000000 R15: ffff88800604be00 +FS: 0000000000000000(0000) GS:ffff8880f3300000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 0000000000000050 CR3: 00000000e932e002 CR4: 00000000003706e0 +Kernel panic - not syncing: Fatal exception +Kernel Offset: disabled + +info->rq and info->gd are only set in blkfront_connect(), which is +called for state 4 (XenbusStateConnected). Guard against using NULL +variables in blkfront_closing() to avoid the issue. + +The rest of blkfront_closing looks okay. If info->nr_rings is 0, then +for_each_rinfo won't do anything. + +blkfront_remove also needs to check for non-NULL pointers before +cleaning up the gendisk and request queue. + +Fixes: 05d69d950d9d "xen-blkfront: sanitize the removal state machine" +Reported-by: Marek Marczykowski-Górecki +Signed-off-by: Jason Andryuk +Reviewed-by: Juergen Gross +Link: https://lore.kernel.org/r/20220601195341.28581-1-jandryuk@gmail.com +Signed-off-by: Juergen Gross +--- + drivers/block/xen-blkfront.c | 19 ++++++++++++------- + 1 file changed, 12 insertions(+), 7 deletions(-) + +diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c +index a88ce4426400..33f04ef78984 100644 +--- a/drivers/block/xen-blkfront.c ++++ b/drivers/block/xen-blkfront.c +@@ -2114,9 +2114,11 @@ static void blkfront_closing(struct blkfront_info *info) + return; + + /* No more blkif_request(). */ +- blk_mq_stop_hw_queues(info->rq); +- blk_set_queue_dying(info->rq); +- set_capacity(info->gd, 0); ++ if (info->rq && info->gd) { ++ blk_mq_stop_hw_queues(info->rq); ++ blk_set_queue_dying(info->rq); ++ set_capacity(info->gd, 0); ++ } + + for_each_rinfo(info, rinfo, i) { + /* No more gnttab callback work. */ +@@ -2457,16 +2459,19 @@ static int blkfront_remove(struct xenbus_device *xbdev) + + dev_dbg(&xbdev->dev, "%s removed", xbdev->nodename); + +- del_gendisk(info->gd); ++ if (info->gd) ++ del_gendisk(info->gd); + + mutex_lock(&blkfront_mutex); + list_del(&info->info_list); + mutex_unlock(&blkfront_mutex); + + blkif_free(info, 0); +- xlbd_release_minors(info->gd->first_minor, info->gd->minors); +- blk_cleanup_disk(info->gd); +- blk_mq_free_tag_set(&info->tag_set); ++ if (info->gd) { ++ xlbd_release_minors(info->gd->first_minor, info->gd->minors); ++ blk_cleanup_disk(info->gd); ++ blk_mq_free_tag_set(&info->tag_set); ++ } + + kfree(info); + return 0; +-- +2.35.3 + diff --git a/patches.suse/xen-blkfront-force-data-bouncing-when-backend-is-unt.patch b/patches.suse/xen-blkfront-force-data-bouncing-when-backend-is-unt.patch index 144be33..0229e5e 100644 --- a/patches.suse/xen-blkfront-force-data-bouncing-when-backend-is-unt.patch +++ b/patches.suse/xen-blkfront-force-data-bouncing-when-backend-is-unt.patch @@ -23,14 +23,12 @@ This is CVE-2022-33742, part of XSA-403. Signed-off-by: Roger Pau Monné Reviewed-by: Juergen Gross --- - drivers/block/xen-blkfront.c | 49 +++++++++++++++++++++++++----------- + drivers/block/xen-blkfront.c | 49 +++++++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 15 deletions(-) -diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c -index 4b3bef6ace68..3646c0cae672 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c -@@ -152,6 +152,10 @@ static unsigned int xen_blkif_max_ring_order; +@@ -151,6 +151,10 @@ static unsigned int xen_blkif_max_ring_o module_param_named(max_ring_page_order, xen_blkif_max_ring_order, int, 0444); MODULE_PARM_DESC(max_ring_page_order, "Maximum order of pages to be used for the shared ring"); @@ -41,7 +39,7 @@ index 4b3bef6ace68..3646c0cae672 100644 #define BLK_RING_SIZE(info) \ __CONST_RING_SIZE(blkif, XEN_PAGE_SIZE * (info)->nr_ring_pages) -@@ -210,6 +214,7 @@ struct blkfront_info +@@ -208,6 +212,7 @@ struct blkfront_info unsigned int feature_discard:1; unsigned int feature_secdiscard:1; unsigned int feature_persistent:1; @@ -49,7 +47,7 @@ index 4b3bef6ace68..3646c0cae672 100644 unsigned int discard_granularity; unsigned int discard_alignment; /* Number of 4KB segments handled */ -@@ -310,7 +315,7 @@ static int fill_grant_buffer(struct blkfront_ring_info *rinfo, int num) +@@ -310,7 +315,7 @@ static int fill_grant_buffer(struct blkf if (!gnt_list_entry) goto out_of_memory; @@ -58,7 +56,7 @@ index 4b3bef6ace68..3646c0cae672 100644 granted_page = alloc_page(GFP_NOIO | __GFP_ZERO); if (!granted_page) { kfree(gnt_list_entry); -@@ -330,7 +335,7 @@ static int fill_grant_buffer(struct blkfront_ring_info *rinfo, int num) +@@ -330,7 +335,7 @@ out_of_memory: list_for_each_entry_safe(gnt_list_entry, n, &rinfo->grants, node) { list_del(&gnt_list_entry->node); @@ -67,7 +65,7 @@ index 4b3bef6ace68..3646c0cae672 100644 __free_page(gnt_list_entry->page); kfree(gnt_list_entry); i--; -@@ -376,7 +381,7 @@ static struct grant *get_grant(grant_ref_t *gref_head, +@@ -376,7 +381,7 @@ static struct grant *get_grant(grant_ref /* Assign a gref to this page */ gnt_list_entry->gref = gnttab_claim_grant_reference(gref_head); BUG_ON(gnt_list_entry->gref == -ENOSPC); @@ -76,7 +74,7 @@ index 4b3bef6ace68..3646c0cae672 100644 grant_foreign_access(gnt_list_entry, info); else { /* Grant access to the GFN passed by the caller */ -@@ -400,7 +405,7 @@ static struct grant *get_indirect_grant(grant_ref_t *gref_head, +@@ -400,7 +405,7 @@ static struct grant *get_indirect_grant( /* Assign a gref to this page */ gnt_list_entry->gref = gnttab_claim_grant_reference(gref_head); BUG_ON(gnt_list_entry->gref == -ENOSPC); @@ -85,7 +83,7 @@ index 4b3bef6ace68..3646c0cae672 100644 struct page *indirect_page; /* Fetch a pre-allocated page to use for indirect grefs */ -@@ -703,7 +708,7 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri +@@ -702,7 +707,7 @@ static int blkif_queue_rw_req(struct req .grant_idx = 0, .segments = NULL, .rinfo = rinfo, @@ -94,7 +92,7 @@ index 4b3bef6ace68..3646c0cae672 100644 }; /* -@@ -981,11 +986,12 @@ static void xlvbd_flush(struct blkfront_info *info) +@@ -980,11 +985,12 @@ static void xlvbd_flush(struct blkfront_ { blk_queue_write_cache(info->rq, info->feature_flush ? true : false, info->feature_fua ? true : false); @@ -109,7 +107,7 @@ index 4b3bef6ace68..3646c0cae672 100644 } static int xen_translate_vdev(int vdevice, int *minor, unsigned int *offset) -@@ -1207,7 +1213,7 @@ static void blkif_free_ring(struct blkfront_ring_info *rinfo) +@@ -1212,7 +1218,7 @@ static void blkif_free_ring(struct blkfr if (!list_empty(&rinfo->indirect_pages)) { struct page *indirect_page, *n; @@ -118,8 +116,8 @@ index 4b3bef6ace68..3646c0cae672 100644 list_for_each_entry_safe(indirect_page, n, &rinfo->indirect_pages, lru) { list_del(&indirect_page->lru); __free_page(indirect_page); -@@ -1224,7 +1230,7 @@ static void blkif_free_ring(struct blkfront_ring_info *rinfo) - 0, 0UL); +@@ -1229,7 +1235,7 @@ static void blkif_free_ring(struct blkfr + 0UL); rinfo->persistent_gnts_c--; } - if (info->feature_persistent) @@ -127,16 +125,16 @@ index 4b3bef6ace68..3646c0cae672 100644 __free_page(persistent_gnt->page); kfree(persistent_gnt); } -@@ -1245,7 +1251,7 @@ static void blkif_free_ring(struct blkfront_ring_info *rinfo) +@@ -1250,7 +1256,7 @@ static void blkif_free_ring(struct blkfr for (j = 0; j < segs; j++) { persistent_gnt = rinfo->shadow[i].grants_used[j]; - gnttab_end_foreign_access(persistent_gnt->gref, 0, 0UL); + gnttab_end_foreign_access(persistent_gnt->gref, 0UL); - if (info->feature_persistent) + if (info->bounce) __free_page(persistent_gnt->page); kfree(persistent_gnt); } -@@ -1428,7 +1434,7 @@ static int blkif_completion(unsigned long *id, +@@ -1440,7 +1446,7 @@ static int blkif_completion(unsigned lon data.s = s; num_sg = s->num_sg; @@ -145,7 +143,7 @@ index 4b3bef6ace68..3646c0cae672 100644 for_each_sg(s->sg, sg, num_sg, i) { BUG_ON(sg->offset + sg->length > PAGE_SIZE); -@@ -1487,7 +1493,7 @@ static int blkif_completion(unsigned long *id, +@@ -1499,7 +1505,7 @@ static int blkif_completion(unsigned lon * Add the used indirect page back to the list of * available pages for indirect grefs. */ @@ -154,7 +152,7 @@ index 4b3bef6ace68..3646c0cae672 100644 indirect_page = s->indirect_grants[i]->page; list_add(&indirect_page->lru, &rinfo->indirect_pages); } -@@ -1764,6 +1770,10 @@ static int talk_to_blkback(struct xenbus_device *dev, +@@ -1790,6 +1796,10 @@ static int talk_to_blkback(struct xenbus if (!info) return -ENODEV; @@ -165,7 +163,7 @@ index 4b3bef6ace68..3646c0cae672 100644 max_page_order = xenbus_read_unsigned(info->xbdev->otherend, "max-ring-page-order", 0); ring_page_order = min(xen_blkif_max_ring_order, max_page_order); -@@ -2173,10 +2183,10 @@ static int blkfront_setup_indirect(struct blkfront_ring_info *rinfo) +@@ -2197,10 +2207,10 @@ static int blkfront_setup_indirect(struc if (err) goto out_of_memory; @@ -179,7 +177,7 @@ index 4b3bef6ace68..3646c0cae672 100644 * used for mapping indirect grefs */ int num = INDIRECT_GREFS(grants) * BLK_RING_SIZE(info); -@@ -2277,6 +2287,8 @@ static void blkfront_gather_backend_features(struct blkfront_info *info) +@@ -2301,6 +2311,8 @@ static void blkfront_gather_backend_feat info->feature_persistent = !!xenbus_read_unsigned(info->xbdev->otherend, "feature-persistent", 0); @@ -188,7 +186,7 @@ index 4b3bef6ace68..3646c0cae672 100644 indirect_segments = xenbus_read_unsigned(info->xbdev->otherend, "feature-max-indirect-segments", 0); -@@ -2548,6 +2560,13 @@ static void blkfront_delay_work(struct work_struct *work) +@@ -2561,6 +2573,13 @@ static void blkfront_delay_work(struct w struct blkfront_info *info; bool need_schedule_work = false; @@ -202,6 +200,3 @@ index 4b3bef6ace68..3646c0cae672 100644 mutex_lock(&blkfront_mutex); list_for_each_entry(info, &info_list, info_list) { --- -2.35.3 - diff --git a/patches.suse/xen-gntdev-Avoid-blocking-in-unmap_grant_pages.patch b/patches.suse/xen-gntdev-Avoid-blocking-in-unmap_grant_pages.patch new file mode 100644 index 0000000..dfcdfb2 --- /dev/null +++ b/patches.suse/xen-gntdev-Avoid-blocking-in-unmap_grant_pages.patch @@ -0,0 +1,366 @@ +Patch-mainline: v5.19-rc4 +Git-commit: dbe97cff7dd9f0f75c524afdd55ad46be3d15295 +References: git-fixes +From: Demi Marie Obenour +Date: Tue, 21 Jun 2022 22:27:26 -0400 +Subject: [PATCH] xen/gntdev: Avoid blocking in unmap_grant_pages() + +unmap_grant_pages() currently waits for the pages to no longer be used. +In https://github.com/QubesOS/qubes-issues/issues/7481, this lead to a +deadlock against i915: i915 was waiting for gntdev's MMU notifier to +finish, while gntdev was waiting for i915 to free its pages. I also +believe this is responsible for various deadlocks I have experienced in +the past. + +Avoid these problems by making unmap_grant_pages async. This requires +making it return void, as any errors will not be available when the +function returns. Fortunately, the only use of the return value is a +WARN_ON(), which can be replaced by a WARN_ON when the error is +detected. Additionally, a failed call will not prevent further calls +from being made, but this is harmless. + +Because unmap_grant_pages is now async, the grant handle will be sent to +INVALID_GRANT_HANDLE too late to prevent multiple unmaps of the same +handle. Instead, a separate bool array is allocated for this purpose. +This wastes memory, but stuffing this information in padding bytes is +too fragile. Furthermore, it is necessary to grab a reference to the +map before making the asynchronous call, and release the reference when +the call returns. + +It is also necessary to guard against reentrancy in gntdev_map_put(), +and to handle the case where userspace tries to map a mapping whose +contents have not all been freed yet. + +Fixes: 745282256c75 ("xen/gntdev: safely unmap grants in case they are still in use") +Cc: stable@vger.kernel.org +Signed-off-by: Demi Marie Obenour +Reviewed-by: Juergen Gross +Link: https://lore.kernel.org/r/20220622022726.2538-1-demi@invisiblethingslab.com +Signed-off-by: Juergen Gross +--- + drivers/xen/gntdev-common.h | 7 ++ + drivers/xen/gntdev.c | 157 ++++++++++++++++++++++++------------ + 2 files changed, 113 insertions(+), 51 deletions(-) + +diff --git a/drivers/xen/gntdev-common.h b/drivers/xen/gntdev-common.h +index 20d7d059dadb..40ef379c28ab 100644 +--- a/drivers/xen/gntdev-common.h ++++ b/drivers/xen/gntdev-common.h +@@ -16,6 +16,7 @@ + #include + #include + #include ++#include + + struct gntdev_dmabuf_priv; + +@@ -56,6 +57,7 @@ struct gntdev_grant_map { + struct gnttab_unmap_grant_ref *unmap_ops; + struct gnttab_map_grant_ref *kmap_ops; + struct gnttab_unmap_grant_ref *kunmap_ops; ++ bool *being_removed; + struct page **pages; + unsigned long pages_vm_start; + +@@ -73,6 +75,11 @@ struct gntdev_grant_map { + /* Needed to avoid allocation in gnttab_dma_free_pages(). */ + xen_pfn_t *frames; + #endif ++ ++ /* Number of live grants */ ++ atomic_t live_grants; ++ /* Needed to avoid allocation in __unmap_grant_pages */ ++ struct gntab_unmap_queue_data unmap_data; + }; + + struct gntdev_grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count, +diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c +index 59ffea800079..4b56c39f766d 100644 +--- a/drivers/xen/gntdev.c ++++ b/drivers/xen/gntdev.c +@@ -35,6 +35,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -60,10 +61,11 @@ module_param(limit, uint, 0644); + MODULE_PARM_DESC(limit, + "Maximum number of grants that may be mapped by one mapping request"); + ++/* True in PV mode, false otherwise */ + static int use_ptemod; + +-static int unmap_grant_pages(struct gntdev_grant_map *map, +- int offset, int pages); ++static void unmap_grant_pages(struct gntdev_grant_map *map, ++ int offset, int pages); + + static struct miscdevice gntdev_miscdev; + +@@ -120,6 +122,7 @@ static void gntdev_free_map(struct gntdev_grant_map *map) + kvfree(map->unmap_ops); + kvfree(map->kmap_ops); + kvfree(map->kunmap_ops); ++ kvfree(map->being_removed); + kfree(map); + } + +@@ -140,10 +143,13 @@ struct gntdev_grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count, + add->unmap_ops = kvmalloc_array(count, sizeof(add->unmap_ops[0]), + GFP_KERNEL); + add->pages = kvcalloc(count, sizeof(add->pages[0]), GFP_KERNEL); ++ add->being_removed = ++ kvcalloc(count, sizeof(add->being_removed[0]), GFP_KERNEL); + if (NULL == add->grants || + NULL == add->map_ops || + NULL == add->unmap_ops || +- NULL == add->pages) ++ NULL == add->pages || ++ NULL == add->being_removed) + goto err; + if (use_ptemod) { + add->kmap_ops = kvmalloc_array(count, sizeof(add->kmap_ops[0]), +@@ -250,9 +256,36 @@ void gntdev_put_map(struct gntdev_priv *priv, struct gntdev_grant_map *map) + if (!refcount_dec_and_test(&map->users)) + return; + +- if (map->pages && !use_ptemod) ++ if (map->pages && !use_ptemod) { ++ /* ++ * Increment the reference count. This ensures that the ++ * subsequent call to unmap_grant_pages() will not wind up ++ * re-entering itself. It *can* wind up calling ++ * gntdev_put_map() recursively, but such calls will be with a ++ * reference count greater than 1, so they will return before ++ * this code is reached. The recursion depth is thus limited to ++ * 1. Do NOT use refcount_inc() here, as it will detect that ++ * the reference count is zero and WARN(). ++ */ ++ refcount_set(&map->users, 1); ++ ++ /* ++ * Unmap the grants. This may or may not be asynchronous, so it ++ * is possible that the reference count is 1 on return, but it ++ * could also be greater than 1. ++ */ + unmap_grant_pages(map, 0, map->count); + ++ /* Check if the memory now needs to be freed */ ++ if (!refcount_dec_and_test(&map->users)) ++ return; ++ ++ /* ++ * All pages have been returned to the hypervisor, so free the ++ * map. ++ */ ++ } ++ + if (map->notify.flags & UNMAP_NOTIFY_SEND_EVENT) { + notify_remote_via_evtchn(map->notify.event); + evtchn_put(map->notify.event); +@@ -283,6 +316,7 @@ static int find_grant_ptes(pte_t *pte, unsigned long addr, void *data) + + int gntdev_map_grant_pages(struct gntdev_grant_map *map) + { ++ size_t alloced = 0; + int i, err = 0; + + if (!use_ptemod) { +@@ -331,97 +365,116 @@ int gntdev_map_grant_pages(struct gntdev_grant_map *map) + map->count); + + for (i = 0; i < map->count; i++) { +- if (map->map_ops[i].status == GNTST_okay) ++ if (map->map_ops[i].status == GNTST_okay) { + map->unmap_ops[i].handle = map->map_ops[i].handle; +- else if (!err) ++ if (!use_ptemod) ++ alloced++; ++ } else if (!err) + err = -EINVAL; + + if (map->flags & GNTMAP_device_map) + map->unmap_ops[i].dev_bus_addr = map->map_ops[i].dev_bus_addr; + + if (use_ptemod) { +- if (map->kmap_ops[i].status == GNTST_okay) ++ if (map->kmap_ops[i].status == GNTST_okay) { ++ if (map->map_ops[i].status == GNTST_okay) ++ alloced++; + map->kunmap_ops[i].handle = map->kmap_ops[i].handle; +- else if (!err) ++ } else if (!err) + err = -EINVAL; + } + } ++ atomic_add(alloced, &map->live_grants); + return err; + } + +-static int __unmap_grant_pages(struct gntdev_grant_map *map, int offset, +- int pages) ++static void __unmap_grant_pages_done(int result, ++ struct gntab_unmap_queue_data *data) + { +- int i, err = 0; +- struct gntab_unmap_queue_data unmap_data; +- +- if (map->notify.flags & UNMAP_NOTIFY_CLEAR_BYTE) { +- int pgno = (map->notify.addr >> PAGE_SHIFT); +- if (pgno >= offset && pgno < offset + pages) { +- /* No need for kmap, pages are in lowmem */ +- uint8_t *tmp = pfn_to_kaddr(page_to_pfn(map->pages[pgno])); +- tmp[map->notify.addr & (PAGE_SIZE-1)] = 0; +- map->notify.flags &= ~UNMAP_NOTIFY_CLEAR_BYTE; +- } +- } +- +- unmap_data.unmap_ops = map->unmap_ops + offset; +- unmap_data.kunmap_ops = use_ptemod ? map->kunmap_ops + offset : NULL; +- unmap_data.pages = map->pages + offset; +- unmap_data.count = pages; +- +- err = gnttab_unmap_refs_sync(&unmap_data); +- if (err) +- return err; ++ unsigned int i; ++ struct gntdev_grant_map *map = data->data; ++ unsigned int offset = data->unmap_ops - map->unmap_ops; + +- for (i = 0; i < pages; i++) { +- if (map->unmap_ops[offset+i].status) +- err = -EINVAL; ++ for (i = 0; i < data->count; i++) { ++ WARN_ON(map->unmap_ops[offset+i].status); + pr_debug("unmap handle=%d st=%d\n", + map->unmap_ops[offset+i].handle, + map->unmap_ops[offset+i].status); + map->unmap_ops[offset+i].handle = INVALID_GRANT_HANDLE; + if (use_ptemod) { +- if (map->kunmap_ops[offset+i].status) +- err = -EINVAL; ++ WARN_ON(map->kunmap_ops[offset+i].status); + pr_debug("kunmap handle=%u st=%d\n", + map->kunmap_ops[offset+i].handle, + map->kunmap_ops[offset+i].status); + map->kunmap_ops[offset+i].handle = INVALID_GRANT_HANDLE; + } + } +- return err; ++ /* ++ * Decrease the live-grant counter. This must happen after the loop to ++ * prevent premature reuse of the grants by gnttab_mmap(). ++ */ ++ atomic_sub(data->count, &map->live_grants); ++ ++ /* Release reference taken by __unmap_grant_pages */ ++ gntdev_put_map(NULL, map); ++} ++ ++static void __unmap_grant_pages(struct gntdev_grant_map *map, int offset, ++ int pages) ++{ ++ if (map->notify.flags & UNMAP_NOTIFY_CLEAR_BYTE) { ++ int pgno = (map->notify.addr >> PAGE_SHIFT); ++ ++ if (pgno >= offset && pgno < offset + pages) { ++ /* No need for kmap, pages are in lowmem */ ++ uint8_t *tmp = pfn_to_kaddr(page_to_pfn(map->pages[pgno])); ++ ++ tmp[map->notify.addr & (PAGE_SIZE-1)] = 0; ++ map->notify.flags &= ~UNMAP_NOTIFY_CLEAR_BYTE; ++ } ++ } ++ ++ map->unmap_data.unmap_ops = map->unmap_ops + offset; ++ map->unmap_data.kunmap_ops = use_ptemod ? map->kunmap_ops + offset : NULL; ++ map->unmap_data.pages = map->pages + offset; ++ map->unmap_data.count = pages; ++ map->unmap_data.done = __unmap_grant_pages_done; ++ map->unmap_data.data = map; ++ refcount_inc(&map->users); /* to keep map alive during async call below */ ++ ++ gnttab_unmap_refs_async(&map->unmap_data); + } + +-static int unmap_grant_pages(struct gntdev_grant_map *map, int offset, +- int pages) ++static void unmap_grant_pages(struct gntdev_grant_map *map, int offset, ++ int pages) + { +- int range, err = 0; ++ int range; ++ ++ if (atomic_read(&map->live_grants) == 0) ++ return; /* Nothing to do */ + + pr_debug("unmap %d+%d [%d+%d]\n", map->index, map->count, offset, pages); + + /* It is possible the requested range will have a "hole" where we + * already unmapped some of the grants. Only unmap valid ranges. + */ +- while (pages && !err) { +- while (pages && +- map->unmap_ops[offset].handle == INVALID_GRANT_HANDLE) { ++ while (pages) { ++ while (pages && map->being_removed[offset]) { + offset++; + pages--; + } + range = 0; + while (range < pages) { +- if (map->unmap_ops[offset + range].handle == +- INVALID_GRANT_HANDLE) ++ if (map->being_removed[offset + range]) + break; ++ map->being_removed[offset + range] = true; + range++; + } +- err = __unmap_grant_pages(map, offset, range); ++ if (range) ++ __unmap_grant_pages(map, offset, range); + offset += range; + pages -= range; + } +- +- return err; + } + + /* ------------------------------------------------------------------ */ +@@ -473,7 +526,6 @@ static bool gntdev_invalidate(struct mmu_interval_notifier *mn, + struct gntdev_grant_map *map = + container_of(mn, struct gntdev_grant_map, notifier); + unsigned long mstart, mend; +- int err; + + if (!mmu_notifier_range_blockable(range)) + return false; +@@ -494,10 +546,9 @@ static bool gntdev_invalidate(struct mmu_interval_notifier *mn, + map->index, map->count, + map->vma->vm_start, map->vma->vm_end, + range->start, range->end, mstart, mend); +- err = unmap_grant_pages(map, ++ unmap_grant_pages(map, + (mstart - map->vma->vm_start) >> PAGE_SHIFT, + (mend - mstart) >> PAGE_SHIFT); +- WARN_ON(err); + + return true; + } +@@ -985,6 +1036,10 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma) + goto unlock_out; + if (use_ptemod && map->vma) + goto unlock_out; ++ if (atomic_read(&map->live_grants)) { ++ err = -EAGAIN; ++ goto unlock_out; ++ } + refcount_inc(&map->users); + + vma->vm_ops = &gntdev_vmops; +-- +2.35.3 + diff --git a/patches.suse/xen-gntdev-Ignore-failure-to-unmap-INVALID_GRANT_HAN.patch b/patches.suse/xen-gntdev-Ignore-failure-to-unmap-INVALID_GRANT_HAN.patch new file mode 100644 index 0000000..1c022e9 --- /dev/null +++ b/patches.suse/xen-gntdev-Ignore-failure-to-unmap-INVALID_GRANT_HAN.patch @@ -0,0 +1,55 @@ +Patch-mainline: v5.19-rc7 +Git-commit: 166d3863231667c4f64dee72b77d1102cdfad11f +References: git-fixes +From: Demi Marie Obenour +Date: Sun, 10 Jul 2022 19:05:22 -0400 +Subject: [PATCH] xen/gntdev: Ignore failure to unmap INVALID_GRANT_HANDLE + +The error paths of gntdev_mmap() can call unmap_grant_pages() even +though not all of the pages have been successfully mapped. This will +trigger the WARN_ON()s in __unmap_grant_pages_done(). The number of +warnings can be very large; I have observed thousands of lines of +warnings in the systemd journal. + +Avoid this problem by only warning on unmapping failure if the handle +being unmapped is not INVALID_GRANT_HANDLE. The handle field of any +page that was not successfully mapped will be INVALID_GRANT_HANDLE, so +this catches all cases where unmapping can legitimately fail. + +Fixes: dbe97cff7dd9 ("xen/gntdev: Avoid blocking in unmap_grant_pages()") +Cc: stable@vger.kernel.org +Suggested-by: Juergen Gross +Signed-off-by: Demi Marie Obenour +Reviewed-by: Oleksandr Tyshchenko +Reviewed-by: Juergen Gross +Link: https://lore.kernel.org/r/20220710230522.1563-1-demi@invisiblethingslab.com +Signed-off-by: Juergen Gross +--- + drivers/xen/gntdev.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c +index 4b56c39f766d..84b143eef395 100644 +--- a/drivers/xen/gntdev.c ++++ b/drivers/xen/gntdev.c +@@ -396,13 +396,15 @@ static void __unmap_grant_pages_done(int result, + unsigned int offset = data->unmap_ops - map->unmap_ops; + + for (i = 0; i < data->count; i++) { +- WARN_ON(map->unmap_ops[offset+i].status); ++ WARN_ON(map->unmap_ops[offset + i].status != GNTST_okay && ++ map->unmap_ops[offset + i].handle != INVALID_GRANT_HANDLE); + pr_debug("unmap handle=%d st=%d\n", + map->unmap_ops[offset+i].handle, + map->unmap_ops[offset+i].status); + map->unmap_ops[offset+i].handle = INVALID_GRANT_HANDLE; + if (use_ptemod) { +- WARN_ON(map->kunmap_ops[offset+i].status); ++ WARN_ON(map->kunmap_ops[offset + i].status != GNTST_okay && ++ map->kunmap_ops[offset + i].handle != INVALID_GRANT_HANDLE); + pr_debug("kunmap handle=%u st=%d\n", + map->kunmap_ops[offset+i].handle, + map->kunmap_ops[offset+i].status); +-- +2.35.3 + diff --git a/patches.suse/xen-grant-table-remove-readonly-parameter-from-funct.patch b/patches.suse/xen-grant-table-remove-readonly-parameter-from-funct.patch new file mode 100644 index 0000000..a908623 --- /dev/null +++ b/patches.suse/xen-grant-table-remove-readonly-parameter-from-funct.patch @@ -0,0 +1,469 @@ +From c94b731da21f10086a9e52d63c21c730e3f6c939 Mon Sep 17 00:00:00 2001 +From: Juergen Gross +Date: Fri, 11 Mar 2022 11:34:29 +0100 +Subject: [PATCH] xen/grant-table: remove readonly parameter from functions +Git-commit: c94b731da21f10086a9e52d63c21c730e3f6c939 +References: jsc#PED-531 +Patch-mainline: v5.18-rc1 + +The gnttab_end_foreign_access() family of functions is taking a +"readonly" parameter, which isn't used. Remove it from the function +parameters. + +Signed-off-by: Juergen Gross +Link: https://lore.kernel.org/r/20220311103429.12845-3-jgross@suse.com +Reviewed-by: Jan Beulich +Acked-by: Christian Schoenebeck +Signed-off-by: Boris Ostrovsky +Signed-off-by: Oliver Neukum +--- + drivers/block/xen-blkfront.c | 8 ++--- + drivers/char/tpm/xen-tpmfront.c | 2 - + drivers/gpu/drm/xen/xen_drm_front_evtchnl.c | 2 - + drivers/input/misc/xen-kbdfront.c | 4 +- + drivers/net/xen-netfront.c | 13 ++++----- + drivers/pci/xen-pcifront.c | 2 - + drivers/scsi/xen-scsifront.c | 4 +- + drivers/usb/host/xen-hcd.c | 4 +- + drivers/xen/gntalloc.c | 2 - + drivers/xen/gntdev-dmabuf.c | 2 - + drivers/xen/grant-table.c | 38 +++++++++++----------------- + drivers/xen/pvcalls-front.c | 6 ++-- + drivers/xen/xen-front-pgdir-shbuf.c | 3 -- + include/xen/grant_table.h | 5 +-- + net/9p/trans_xen.c | 8 ++--- + sound/xen/xen_snd_front_evtchnl.c | 2 - + 16 files changed, 48 insertions(+), 57 deletions(-) + +--- a/drivers/block/xen-blkfront.c ++++ b/drivers/block/xen-blkfront.c +@@ -1226,7 +1226,7 @@ static void blkif_free_ring(struct blkfr + list_del(&persistent_gnt->node); + if (persistent_gnt->gref != GRANT_INVALID_REF) { + gnttab_end_foreign_access(persistent_gnt->gref, +- 0, 0UL); ++ 0UL); + rinfo->persistent_gnts_c--; + } + if (info->feature_persistent) +@@ -1249,7 +1249,7 @@ static void blkif_free_ring(struct blkfr + rinfo->shadow[i].req.u.rw.nr_segments; + for (j = 0; j < segs; j++) { + persistent_gnt = rinfo->shadow[i].grants_used[j]; +- gnttab_end_foreign_access(persistent_gnt->gref, 0, 0UL); ++ gnttab_end_foreign_access(persistent_gnt->gref, 0UL); + if (info->feature_persistent) + __free_page(persistent_gnt->page); + kfree(persistent_gnt); +@@ -1264,7 +1264,7 @@ static void blkif_free_ring(struct blkfr + + for (j = 0; j < INDIRECT_GREFS(segs); j++) { + persistent_gnt = rinfo->shadow[i].indirect_grants[j]; +- gnttab_end_foreign_access(persistent_gnt->gref, 0, 0UL); ++ gnttab_end_foreign_access(persistent_gnt->gref, 0UL); + __free_page(persistent_gnt->page); + kfree(persistent_gnt); + } +@@ -1287,7 +1287,7 @@ free_shadow: + /* Free resources associated with old device channel. */ + for (i = 0; i < info->nr_ring_pages; i++) { + if (rinfo->ring_ref[i] != GRANT_INVALID_REF) { +- gnttab_end_foreign_access(rinfo->ring_ref[i], 0, 0); ++ gnttab_end_foreign_access(rinfo->ring_ref[i], 0); + rinfo->ring_ref[i] = GRANT_INVALID_REF; + } + } +--- a/drivers/char/tpm/xen-tpmfront.c ++++ b/drivers/char/tpm/xen-tpmfront.c +@@ -332,7 +332,7 @@ static void ring_free(struct tpm_private + return; + + if (priv->ring_ref) +- gnttab_end_foreign_access(priv->ring_ref, 0, ++ gnttab_end_foreign_access(priv->ring_ref, + (unsigned long)priv->shr); + else + free_page((unsigned long)priv->shr); +--- a/drivers/gpu/drm/xen/xen_drm_front_evtchnl.c ++++ b/drivers/gpu/drm/xen/xen_drm_front_evtchnl.c +@@ -148,7 +148,7 @@ static void evtchnl_free(struct xen_drm_ + + /* end access and free the page */ + if (evtchnl->gref != GRANT_INVALID_REF) +- gnttab_end_foreign_access(evtchnl->gref, 0, page); ++ gnttab_end_foreign_access(evtchnl->gref, page); + + memset(evtchnl, 0, sizeof(*evtchnl)); + } +--- a/drivers/input/misc/xen-kbdfront.c ++++ b/drivers/input/misc/xen-kbdfront.c +@@ -481,7 +481,7 @@ static int xenkbd_connect_backend(struct + error_evtchan: + xenbus_free_evtchn(dev, evtchn); + error_grant: +- gnttab_end_foreign_access(info->gref, 0, 0UL); ++ gnttab_end_foreign_access(info->gref, 0UL); + info->gref = -1; + return ret; + } +@@ -492,7 +492,7 @@ static void xenkbd_disconnect_backend(st + unbind_from_irqhandler(info->irq, info); + info->irq = -1; + if (info->gref >= 0) +- gnttab_end_foreign_access(info->gref, 0, 0UL); ++ gnttab_end_foreign_access(info->gref, 0UL); + info->gref = -1; + } + +--- a/drivers/net/xen-netfront.c ++++ b/drivers/net/xen-netfront.c +@@ -425,7 +425,7 @@ static bool xennet_tx_buf_gc(struct netf + skb = queue->tx_skbs[id]; + queue->tx_skbs[id] = NULL; + if (unlikely(!gnttab_end_foreign_access_ref( +- queue->grant_tx_ref[id], GNTMAP_readonly))) { ++ queue->grant_tx_ref[id]))) { + dev_alert(dev, + "Grant still in use by backend domain\n"); + goto err; +@@ -1007,7 +1007,7 @@ static int xennet_get_responses(struct n + goto next; + } + +- if (!gnttab_end_foreign_access_ref(ref, 0)) { ++ if (!gnttab_end_foreign_access_ref(ref)) { + dev_alert(dev, + "Grant still in use by backend domain\n"); + queue->info->broken = true; +@@ -1366,7 +1366,6 @@ static void xennet_release_tx_bufs(struc + queue->tx_skbs[i] = NULL; + get_page(queue->grant_tx_page[i]); + gnttab_end_foreign_access(queue->grant_tx_ref[i], +- GNTMAP_readonly, + (unsigned long)page_address(queue->grant_tx_page[i])); + queue->grant_tx_page[i] = NULL; + queue->grant_tx_ref[i] = GRANT_INVALID_REF; +@@ -1399,7 +1398,7 @@ static void xennet_release_rx_bufs(struc + * foreign access is ended (which may be deferred). + */ + get_page(page); +- gnttab_end_foreign_access(ref, 0, ++ gnttab_end_foreign_access(ref, + (unsigned long)page_address(page)); + queue->grant_rx_ref[id] = GRANT_INVALID_REF; + +@@ -1740,7 +1739,7 @@ static void xennet_end_access(int ref, v + { + /* This frees the page as a side-effect */ + if (ref != GRANT_INVALID_REF) +- gnttab_end_foreign_access(ref, 0, (unsigned long)page); ++ gnttab_end_foreign_access(ref, (unsigned long)page); + } + + static void xennet_disconnect_backend(struct netfront_info *info) +@@ -1957,14 +1956,14 @@ static int setup_netfront(struct xenbus_ + */ + fail: + if (queue->rx_ring_ref != GRANT_INVALID_REF) { +- gnttab_end_foreign_access(queue->rx_ring_ref, 0, ++ gnttab_end_foreign_access(queue->rx_ring_ref, + (unsigned long)rxs); + queue->rx_ring_ref = GRANT_INVALID_REF; + } else { + free_page((unsigned long)rxs); + } + if (queue->tx_ring_ref != GRANT_INVALID_REF) { +- gnttab_end_foreign_access(queue->tx_ring_ref, 0, ++ gnttab_end_foreign_access(queue->tx_ring_ref, + (unsigned long)txs); + queue->tx_ring_ref = GRANT_INVALID_REF; + } else { +--- a/drivers/pci/xen-pcifront.c ++++ b/drivers/pci/xen-pcifront.c +@@ -767,7 +767,7 @@ static void free_pdev(struct pcifront_de + xenbus_free_evtchn(pdev->xdev, pdev->evtchn); + + if (pdev->gnt_ref != INVALID_GRANT_REF) +- gnttab_end_foreign_access(pdev->gnt_ref, 0 /* r/w page */, ++ gnttab_end_foreign_access(pdev->gnt_ref, + (unsigned long)pdev->sh_info); + else + free_page((unsigned long)pdev->sh_info); +--- a/drivers/scsi/xen-scsifront.c ++++ b/drivers/scsi/xen-scsifront.c +@@ -757,7 +757,7 @@ static int scsifront_alloc_ring(struct v + free_irq: + unbind_from_irqhandler(info->irq, info); + free_gnttab: +- gnttab_end_foreign_access(info->ring_ref, 0, ++ gnttab_end_foreign_access(info->ring_ref, + (unsigned long)info->ring.sring); + + return err; +@@ -766,7 +766,7 @@ free_gnttab: + static void scsifront_free_ring(struct vscsifrnt_info *info) + { + unbind_from_irqhandler(info->irq, info); +- gnttab_end_foreign_access(info->ring_ref, 0, ++ gnttab_end_foreign_access(info->ring_ref, + (unsigned long)info->ring.sring); + } + +--- a/drivers/usb/host/xen-hcd.c ++++ b/drivers/usb/host/xen-hcd.c +@@ -1073,14 +1073,14 @@ static void xenhcd_destroy_rings(struct + info->irq = 0; + + if (info->urb_ring_ref != GRANT_INVALID_REF) { +- gnttab_end_foreign_access(info->urb_ring_ref, 0, ++ gnttab_end_foreign_access(info->urb_ring_ref, + (unsigned long)info->urb_ring.sring); + info->urb_ring_ref = GRANT_INVALID_REF; + } + info->urb_ring.sring = NULL; + + if (info->conn_ring_ref != GRANT_INVALID_REF) { +- gnttab_end_foreign_access(info->conn_ring_ref, 0, ++ gnttab_end_foreign_access(info->conn_ring_ref, + (unsigned long)info->conn_ring.sring); + info->conn_ring_ref = GRANT_INVALID_REF; + } +--- a/drivers/xen/gntalloc.c ++++ b/drivers/xen/gntalloc.c +@@ -192,7 +192,7 @@ static void __del_gref(struct gntalloc_g + if (gref->gref_id) { + if (gref->page) { + addr = (unsigned long)page_to_virt(gref->page); +- gnttab_end_foreign_access(gref->gref_id, 0, addr); ++ gnttab_end_foreign_access(gref->gref_id, addr); + } else + gnttab_free_grant_reference(gref->gref_id); + } +--- a/drivers/xen/gntdev-dmabuf.c ++++ b/drivers/xen/gntdev-dmabuf.c +@@ -530,7 +530,7 @@ static void dmabuf_imp_end_foreign_acces + + for (i = 0; i < count; i++) + if (refs[i] != GRANT_INVALID_REF) +- gnttab_end_foreign_access(refs[i], 0, 0UL); ++ gnttab_end_foreign_access(refs[i], 0UL); + } + + static void dmabuf_imp_free_storage(struct gntdev_dmabuf *gntdev_dmabuf) +--- a/drivers/xen/grant-table.c ++++ b/drivers/xen/grant-table.c +@@ -118,13 +118,12 @@ struct gnttab_ops { + unsigned long frame, unsigned flags); + /* + * Stop granting a grant entry to domain for accessing. Ref parameter is +- * reference of a grant entry whose grant access will be stopped, +- * readonly is not in use in this function. If the grant entry is +- * currently mapped for reading or writing, just return failure(==0) +- * directly and don't tear down the grant access. Otherwise, stop grant +- * access for this entry and return success(==1). ++ * reference of a grant entry whose grant access will be stopped. ++ * If the grant entry is currently mapped for reading or writing, just ++ * return failure(==0) directly and don't tear down the grant access. ++ * Otherwise, stop grant access for this entry and return success(==1). + */ +- int (*end_foreign_access_ref)(grant_ref_t ref, int readonly); ++ int (*end_foreign_access_ref)(grant_ref_t ref); + /* + * Stop granting a grant entry to domain for transfer. Ref parameter is + * reference of a grant entry whose grant transfer will be stopped. If +@@ -304,7 +303,7 @@ int gnttab_query_foreign_access(grant_re + } + EXPORT_SYMBOL_GPL(gnttab_query_foreign_access); + +-static int gnttab_end_foreign_access_ref_v1(grant_ref_t ref, int readonly) ++static int gnttab_end_foreign_access_ref_v1(grant_ref_t ref) + { + u16 flags, nflags; + u16 *pflags; +@@ -320,7 +319,7 @@ static int gnttab_end_foreign_access_ref + return 1; + } + +-static int gnttab_end_foreign_access_ref_v2(grant_ref_t ref, int readonly) ++static int gnttab_end_foreign_access_ref_v2(grant_ref_t ref) + { + gnttab_shared.v2[ref].hdr.flags = 0; + mb(); /* Concurrent access by hypervisor. */ +@@ -343,14 +342,14 @@ static int gnttab_end_foreign_access_ref + return 1; + } + +-static inline int _gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly) ++static inline int _gnttab_end_foreign_access_ref(grant_ref_t ref) + { +- return gnttab_interface->end_foreign_access_ref(ref, readonly); ++ return gnttab_interface->end_foreign_access_ref(ref); + } + +-int gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly) ++int gnttab_end_foreign_access_ref(grant_ref_t ref) + { +- if (_gnttab_end_foreign_access_ref(ref, readonly)) ++ if (_gnttab_end_foreign_access_ref(ref)) + return 1; + pr_warn("WARNING: g.e. %#x still in use!\n", ref); + return 0; +@@ -370,7 +369,6 @@ static unsigned long gnttab_read_frame_v + struct deferred_entry { + struct list_head list; + grant_ref_t ref; +- bool ro; + uint16_t warn_delay; + struct page *page; + }; +@@ -394,7 +392,7 @@ static void gnttab_handle_deferred(struc + break; + list_del(&entry->list); + spin_unlock_irqrestore(&gnttab_list_lock, flags); +- if (_gnttab_end_foreign_access_ref(entry->ref, entry->ro)) { ++ if (_gnttab_end_foreign_access_ref(entry->ref)) { + put_free_entry(entry->ref); + pr_debug("freeing g.e. %#x (pfn %#lx)\n", + entry->ref, page_to_pfn(entry->page)); +@@ -420,8 +418,7 @@ static void gnttab_handle_deferred(struc + spin_unlock_irqrestore(&gnttab_list_lock, flags); + } + +-static void gnttab_add_deferred(grant_ref_t ref, bool readonly, +- struct page *page) ++static void gnttab_add_deferred(grant_ref_t ref, struct page *page) + { + struct deferred_entry *entry; + gfp_t gfp = (in_atomic() || irqs_disabled()) ? GFP_ATOMIC : GFP_KERNEL; +@@ -439,7 +436,6 @@ static void gnttab_add_deferred(grant_re + unsigned long flags; + + entry->ref = ref; +- entry->ro = readonly; + entry->page = page; + entry->warn_delay = 60; + spin_lock_irqsave(&gnttab_list_lock, flags); +@@ -457,7 +453,7 @@ static void gnttab_add_deferred(grant_re + + int gnttab_try_end_foreign_access(grant_ref_t ref) + { +- int ret = _gnttab_end_foreign_access_ref(ref, 0); ++ int ret = _gnttab_end_foreign_access_ref(ref); + + if (ret) + put_free_entry(ref); +@@ -466,15 +462,13 @@ int gnttab_try_end_foreign_access(grant_ + } + EXPORT_SYMBOL_GPL(gnttab_try_end_foreign_access); + +-void gnttab_end_foreign_access(grant_ref_t ref, int readonly, +- unsigned long page) ++void gnttab_end_foreign_access(grant_ref_t ref, unsigned long page) + { + if (gnttab_try_end_foreign_access(ref)) { + if (page != 0) + put_page(virt_to_page(page)); + } else +- gnttab_add_deferred(ref, readonly, +- page ? virt_to_page(page) : NULL); ++ gnttab_add_deferred(ref, page ? virt_to_page(page) : NULL); + } + EXPORT_SYMBOL_GPL(gnttab_end_foreign_access); + +--- a/drivers/xen/pvcalls-front.c ++++ b/drivers/xen/pvcalls-front.c +@@ -238,8 +238,8 @@ static void pvcalls_front_free_map(struc + spin_unlock(&bedata->socket_lock); + + for (i = 0; i < (1 << PVCALLS_RING_ORDER); i++) +- gnttab_end_foreign_access(map->active.ring->ref[i], 0, 0); +- gnttab_end_foreign_access(map->active.ref, 0, 0); ++ gnttab_end_foreign_access(map->active.ring->ref[i], 0); ++ gnttab_end_foreign_access(map->active.ref, 0); + free_page((unsigned long)map->active.ring); + + kfree(map); +@@ -1117,7 +1117,7 @@ static int pvcalls_front_remove(struct x + } + } + if (bedata->ref != -1) +- gnttab_end_foreign_access(bedata->ref, 0, 0); ++ gnttab_end_foreign_access(bedata->ref, 0); + kfree(bedata->ring.sring); + kfree(bedata); + xenbus_switch_state(dev, XenbusStateClosed); +--- a/drivers/xen/xen-front-pgdir-shbuf.c ++++ b/drivers/xen/xen-front-pgdir-shbuf.c +@@ -143,8 +143,7 @@ void xen_front_pgdir_shbuf_free(struct x + + for (i = 0; i < buf->num_grefs; i++) + if (buf->grefs[i] != GRANT_INVALID_REF) +- gnttab_end_foreign_access(buf->grefs[i], +- 0, 0UL); ++ gnttab_end_foreign_access(buf->grefs[i], 0UL); + } + kfree(buf->grefs); + kfree(buf->directory); +--- a/include/xen/grant_table.h ++++ b/include/xen/grant_table.h +@@ -97,7 +97,7 @@ int gnttab_grant_foreign_access(domid_t + * longer in use. Return 1 if the grant entry was freed, 0 if it is still in + * use. + */ +-int gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly); ++int gnttab_end_foreign_access_ref(grant_ref_t ref); + + /* + * Eventually end access through the given grant reference, and once that +@@ -114,8 +114,7 @@ int gnttab_end_foreign_access_ref(grant_ + * gnttab_end_foreign_access() are done via alloc_pages_exact() (and freeing + * via free_pages_exact()) in order to avoid high order pages. + */ +-void gnttab_end_foreign_access(grant_ref_t ref, int readonly, +- unsigned long page); ++void gnttab_end_foreign_access(grant_ref_t ref, unsigned long page); + + /* + * End access through the given grant reference, iff the grant entry is +--- a/net/9p/trans_xen.c ++++ b/net/9p/trans_xen.c +@@ -302,13 +302,13 @@ static void xen_9pfs_front_free(struct x + grant_ref_t ref; + + ref = priv->rings[i].intf->ref[j]; +- gnttab_end_foreign_access(ref, 0, 0); ++ gnttab_end_foreign_access(ref, 0); + } + free_pages_exact(priv->rings[i].data.in, + 1UL << (priv->rings[i].intf->ring_order + + XEN_PAGE_SHIFT)); + } +- gnttab_end_foreign_access(priv->rings[i].ref, 0, 0); ++ gnttab_end_foreign_access(priv->rings[i].ref, 0); + free_page((unsigned long)priv->rings[i].intf); + } + kfree(priv->rings); +@@ -376,10 +376,10 @@ static int xen_9pfs_front_alloc_dataring + out: + if (bytes) { + for (i--; i >= 0; i--) +- gnttab_end_foreign_access(ring->intf->ref[i], 0, 0); ++ gnttab_end_foreign_access(ring->intf->ref[i], 0); + free_pages_exact(bytes, 1UL << (order + XEN_PAGE_SHIFT)); + } +- gnttab_end_foreign_access(ring->ref, 0, 0); ++ gnttab_end_foreign_access(ring->ref, 0); + free_page((unsigned long)ring->intf); + return ret; + } +--- a/sound/xen/xen_snd_front_evtchnl.c ++++ b/sound/xen/xen_snd_front_evtchnl.c +@@ -168,7 +168,7 @@ static void evtchnl_free(struct xen_snd_ + + /* End access and free the page. */ + if (channel->gref != GRANT_INVALID_REF) +- gnttab_end_foreign_access(channel->gref, 0, page); ++ gnttab_end_foreign_access(channel->gref, page); + else + free_page(page); + diff --git a/patches.suse/xen-grants-prevent-integer-overflow-in-gnttab_dma_al.patch b/patches.suse/xen-grants-prevent-integer-overflow-in-gnttab_dma_al.patch new file mode 100644 index 0000000..ff0e0c8 --- /dev/null +++ b/patches.suse/xen-grants-prevent-integer-overflow-in-gnttab_dma_al.patch @@ -0,0 +1,38 @@ +Patch-mainline: v6.0-rc4 +Git-commit: e9ea0b30ada008f4e65933f449db6894832cb242 +References: git-fixes +From: Dan Carpenter +Date: Thu, 1 Sep 2022 18:35:20 +0300 +Subject: [PATCH] xen/grants: prevent integer overflow in + gnttab_dma_alloc_pages() + +The change from kcalloc() to kvmalloc() means that arg->nr_pages +might now be large enough that the "args->nr_pages << PAGE_SHIFT" can +result in an integer overflow. + +Fixes: b3f7931f5c61 ("xen/gntdev: switch from kcalloc() to kvcalloc()") +Signed-off-by: Dan Carpenter +Reviewed-by: Juergen Gross +Link: https://lore.kernel.org/r/YxDROJqu/RPvR0bi@kili +Signed-off-by: Juergen Gross +--- + drivers/xen/grant-table.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c +index 738029de3c67..e1ec725c2819 100644 +--- a/drivers/xen/grant-table.c ++++ b/drivers/xen/grant-table.c +@@ -1047,6 +1047,9 @@ int gnttab_dma_alloc_pages(struct gnttab_dma_alloc_args *args) + size_t size; + int i, ret; + ++ if (args->nr_pages < 0 || args->nr_pages > (INT_MAX >> PAGE_SHIFT)) ++ return -ENOMEM; ++ + size = args->nr_pages << PAGE_SHIFT; + if (args->coherent) + args->vaddr = dma_alloc_coherent(args->dev, size, +-- +2.35.3 + diff --git a/patches.suse/xen-netback-only-remove-hotplug-status-when-the-vif-.patch b/patches.suse/xen-netback-only-remove-hotplug-status-when-the-vif-.patch new file mode 100644 index 0000000..d002c93 --- /dev/null +++ b/patches.suse/xen-netback-only-remove-hotplug-status-when-the-vif-.patch @@ -0,0 +1,48 @@ +Patch-mainline: v6.0-rc5 +Git-commit: c55f34b6aec2a8cb47eadaffea773e83bf85de91 +References: git-fixes +From: Paul Durrant +Date: Thu, 1 Sep 2022 12:55:54 +0100 +Subject: [PATCH] xen-netback: only remove 'hotplug-status' when the vif is + actually destroyed + +Removing 'hotplug-status' in backend_disconnected() means that it will be +removed even in the case that the frontend unilaterally disconnects (which +it is free to do at any time). The consequence of this is that, when the +frontend attempts to re-connect, the backend gets stuck in 'InitWait' +rather than moving straight to 'Connected' (which it can do because the +hotplug script has already run). +Instead, the 'hotplug-status' mode should be removed in netback_remove() +i.e. when the vif really is going away. + +Fixes: 0f4558ae9187 ("Revert "xen-netback: remove 'hotplug-status' once it has served its purpose"") +Signed-off-by: Paul Durrant +Signed-off-by: David S. Miller +Signed-off-by: Juergen Gross +--- + drivers/net/xen-netback/xenbus.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c +index 990360d75cb6..e85b3c5d4acc 100644 +--- a/drivers/net/xen-netback/xenbus.c ++++ b/drivers/net/xen-netback/xenbus.c +@@ -256,7 +256,6 @@ static void backend_disconnect(struct backend_info *be) + unsigned int queue_index; + + xen_unregister_watchers(vif); +- xenbus_rm(XBT_NIL, be->dev->nodename, "hotplug-status"); + #ifdef CONFIG_DEBUG_FS + xenvif_debugfs_delif(vif); + #endif /* CONFIG_DEBUG_FS */ +@@ -984,6 +983,7 @@ static int netback_remove(struct xenbus_device *dev) + struct backend_info *be = dev_get_drvdata(&dev->dev); + + unregister_hotplug_status_watch(be); ++ xenbus_rm(XBT_NIL, dev->nodename, "hotplug-status"); + if (be->vif) { + kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE); + backend_disconnect(be); +-- +2.35.3 + diff --git a/patches.suse/xen-update-ring.h.patch b/patches.suse/xen-update-ring.h.patch new file mode 100644 index 0000000..77047a3 --- /dev/null +++ b/patches.suse/xen-update-ring.h.patch @@ -0,0 +1,100 @@ +From 6fac592cca60dca0b2a524c303c83e958c2003bb Mon Sep 17 00:00:00 2001 +From: Juergen Gross +Date: Thu, 28 Apr 2022 09:59:01 +0200 +Subject: [PATCH] xen: update ring.h +Git-commit: 6fac592cca60dca0b2a524c303c83e958c2003bb +References: jsc#PED-531 +Patch-mainline: v5.19-rc1 + +Update include/xen/interface/io/ring.h to its newest version. + +Switch the two improper use cases of RING_HAS_UNCONSUMED_RESPONSES() to +XEN_RING_NR_UNCONSUMED_RESPONSES() in order to avoid the nasty +XEN_RING_HAS_UNCONSUMED_IS_BOOL #define. + +Signed-off-by: Juergen Gross +Reviewed-by: Boris Ostrovsky +Signed-off-by: Juergen Gross +Signed-off-by: Oliver Neukum +--- + drivers/net/xen-netfront.c | 4 ++-- + include/xen/interface/io/ring.h | 19 ++++++++++++++----- + 2 files changed, 16 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c +index af3d3de7d9fa..966bee2a6902 100644 +--- a/drivers/net/xen-netfront.c ++++ b/drivers/net/xen-netfront.c +@@ -866,7 +866,7 @@ static void xennet_set_rx_rsp_cons(struct netfront_queue *queue, RING_IDX val) + + spin_lock_irqsave(&queue->rx_cons_lock, flags); + queue->rx.rsp_cons = val; +- queue->rx_rsp_unconsumed = RING_HAS_UNCONSUMED_RESPONSES(&queue->rx); ++ queue->rx_rsp_unconsumed = XEN_RING_NR_UNCONSUMED_RESPONSES(&queue->rx); + spin_unlock_irqrestore(&queue->rx_cons_lock, flags); + } + +@@ -1498,7 +1498,7 @@ static bool xennet_handle_rx(struct netfront_queue *queue, unsigned int *eoi) + return false; + + spin_lock_irqsave(&queue->rx_cons_lock, flags); +- work_queued = RING_HAS_UNCONSUMED_RESPONSES(&queue->rx); ++ work_queued = XEN_RING_NR_UNCONSUMED_RESPONSES(&queue->rx); + if (work_queued > queue->rx_rsp_unconsumed) { + queue->rx_rsp_unconsumed = work_queued; + *eoi = 0; +diff --git a/include/xen/interface/io/ring.h b/include/xen/interface/io/ring.h +index 2470ec45ebb2..ba4c4274b714 100644 +--- a/include/xen/interface/io/ring.h ++++ b/include/xen/interface/io/ring.h +@@ -72,9 +72,8 @@ typedef unsigned int RING_IDX; + * of the shared memory area (PAGE_SIZE, for instance). To initialise + * the front half: + * +- * mytag_front_ring_t front_ring; +- * SHARED_RING_INIT((mytag_sring_t *)shared_page); +- * FRONT_RING_INIT(&front_ring, (mytag_sring_t *)shared_page, PAGE_SIZE); ++ * mytag_front_ring_t ring; ++ * XEN_FRONT_RING_INIT(&ring, (mytag_sring_t *)shared_page, PAGE_SIZE); + * + * Initializing the back follows similarly (note that only the front + * initializes the shared ring): +@@ -146,6 +145,11 @@ struct __name##_back_ring { \ + + #define FRONT_RING_INIT(_r, _s, __size) FRONT_RING_ATTACH(_r, _s, 0, __size) + ++#define XEN_FRONT_RING_INIT(r, s, size) do { \ ++ SHARED_RING_INIT(s); \ ++ FRONT_RING_INIT(r, s, size); \ ++} while (0) ++ + #define BACK_RING_ATTACH(_r, _s, _i, __size) do { \ + (_r)->rsp_prod_pvt = (_i); \ + (_r)->req_cons = (_i); \ +@@ -170,16 +174,21 @@ struct __name##_back_ring { \ + (RING_FREE_REQUESTS(_r) == 0) + + /* Test if there are outstanding messages to be processed on a ring. */ +-#define RING_HAS_UNCONSUMED_RESPONSES(_r) \ ++#define XEN_RING_NR_UNCONSUMED_RESPONSES(_r) \ + ((_r)->sring->rsp_prod - (_r)->rsp_cons) + +-#define RING_HAS_UNCONSUMED_REQUESTS(_r) ({ \ ++#define XEN_RING_NR_UNCONSUMED_REQUESTS(_r) ({ \ + unsigned int req = (_r)->sring->req_prod - (_r)->req_cons; \ + unsigned int rsp = RING_SIZE(_r) - \ + ((_r)->req_cons - (_r)->rsp_prod_pvt); \ + req < rsp ? req : rsp; \ + }) + ++#define RING_HAS_UNCONSUMED_RESPONSES(_r) \ ++ (!!XEN_RING_NR_UNCONSUMED_RESPONSES(_r)) ++#define RING_HAS_UNCONSUMED_REQUESTS(_r) \ ++ (!!XEN_RING_NR_UNCONSUMED_REQUESTS(_r)) ++ + /* Direct access to individual ring elements, by index. */ + #define RING_GET_REQUEST(_r, _idx) \ + (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].req)) +-- +2.35.3 + diff --git a/patches.suse/xen-usb-don-t-use-arbitrary_virt_to_machine.patch b/patches.suse/xen-usb-don-t-use-arbitrary_virt_to_machine.patch new file mode 100644 index 0000000..9d02291 --- /dev/null +++ b/patches.suse/xen-usb-don-t-use-arbitrary_virt_to_machine.patch @@ -0,0 +1,50 @@ +From cee03ca3cb44c867b45f9d32601c1d532f66fe7a Mon Sep 17 00:00:00 2001 +From: Juergen Gross +Date: Fri, 11 Mar 2022 11:35:00 +0100 +Subject: [PATCH] xen/usb: don't use arbitrary_virt_to_machine() +Git-commit: cee03ca3cb44c867b45f9d32601c1d532f66fe7a +References: jsc#PED-531 +Patch-mainline: v5.18-rc1 + +arbitrary_virt_to_machine() is meant to be used in PV guests only. +Replace its usage with virt_to_gfn(). + +Signed-off-by: Juergen Gross +Link: https://lore.kernel.org/r/20220311103500.12885-1-jgross@suse.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/usb/host/xen-hcd.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/usb/host/xen-hcd.c b/drivers/usb/host/xen-hcd.c +index be09fd9bac58..36f7c8a0b500 100644 +--- a/drivers/usb/host/xen-hcd.c ++++ b/drivers/usb/host/xen-hcd.c +@@ -589,14 +589,12 @@ static void xenhcd_gnttab_map(struct xenhcd_info *info, void *addr, int length, + int nr_pages, int flags) + { + grant_ref_t ref; +- unsigned long buffer_mfn; + unsigned int offset; + unsigned int len = length; + unsigned int bytes; + int i; + + for (i = 0; i < nr_pages; i++) { +- buffer_mfn = PFN_DOWN(arbitrary_virt_to_machine(addr).maddr); + offset = offset_in_page(addr); + + bytes = PAGE_SIZE - offset; +@@ -605,7 +603,7 @@ static void xenhcd_gnttab_map(struct xenhcd_info *info, void *addr, int length, + + ref = gnttab_claim_grant_reference(gref_head); + gnttab_grant_foreign_access_ref(ref, info->xbdev->otherend_id, +- buffer_mfn, flags); ++ virt_to_gfn(addr), flags); + seg[i].gref = ref; + seg[i].offset = (__u16)offset; + seg[i].length = (__u16)bytes; +-- +2.35.3 + diff --git a/patches.suse/xen-usb-harden-xen_hcd-against-malicious-backends.patch b/patches.suse/xen-usb-harden-xen_hcd-against-malicious-backends.patch new file mode 100644 index 0000000..1df0d58 --- /dev/null +++ b/patches.suse/xen-usb-harden-xen_hcd-against-malicious-backends.patch @@ -0,0 +1,169 @@ +From aff477cb8f94613f501d386d10f20019e294bc35 Mon Sep 17 00:00:00 2001 +From: Juergen Gross +Date: Fri, 11 Mar 2022 11:35:09 +0100 +Subject: [PATCH] xen/usb: harden xen_hcd against malicious backends +Git-commit: aff477cb8f94613f501d386d10f20019e294bc35 +References: jsc#PED-531 +Patch-mainline: v5.18-rc1 + +Make sure a malicious backend can't cause any harm other than wrong +I/O data. + +Missing are verification of the request id in a response, sanitizing +the reported actual I/O length, and protection against interrupt storms +from the backend. + +Signed-off-by: Juergen Gross +Link: https://lore.kernel.org/r/20220311103509.12908-1-jgross@suse.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/usb/host/xen-hcd.c | 57 ++++++++++++++++++++++++++++---------- + 1 file changed, 43 insertions(+), 14 deletions(-) + +diff --git a/drivers/usb/host/xen-hcd.c b/drivers/usb/host/xen-hcd.c +index 47ec092bd8e3..210f91bf661c 100644 +--- a/drivers/usb/host/xen-hcd.c ++++ b/drivers/usb/host/xen-hcd.c +@@ -51,6 +51,7 @@ struct vdevice_status { + struct usb_shadow { + struct xenusb_urb_request req; + struct urb *urb; ++ bool in_flight; + }; + + struct xenhcd_info { +@@ -720,6 +721,12 @@ static void xenhcd_gnttab_done(struct xenhcd_info *info, unsigned int id) + int nr_segs = 0; + int i; + ++ if (!shadow->in_flight) { ++ xenhcd_set_error(info, "Illegal request id"); ++ return; ++ } ++ shadow->in_flight = false; ++ + nr_segs = shadow->req.nr_buffer_segs; + + if (xenusb_pipeisoc(shadow->req.pipe)) +@@ -803,6 +810,7 @@ static int xenhcd_do_request(struct xenhcd_info *info, struct urb_priv *urbp) + + info->urb_ring.req_prod_pvt++; + info->shadow[id].urb = urb; ++ info->shadow[id].in_flight = true; + + RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&info->urb_ring, notify); + if (notify) +@@ -931,10 +939,27 @@ static int xenhcd_unlink_urb(struct xenhcd_info *info, struct urb_priv *urbp) + return ret; + } + +-static int xenhcd_urb_request_done(struct xenhcd_info *info) ++static void xenhcd_res_to_urb(struct xenhcd_info *info, ++ struct xenusb_urb_response *res, struct urb *urb) ++{ ++ if (unlikely(!urb)) ++ return; ++ ++ if (res->actual_length > urb->transfer_buffer_length) ++ urb->actual_length = urb->transfer_buffer_length; ++ else if (res->actual_length < 0) ++ urb->actual_length = 0; ++ else ++ urb->actual_length = res->actual_length; ++ urb->error_count = res->error_count; ++ urb->start_frame = res->start_frame; ++ xenhcd_giveback_urb(info, urb, res->status); ++} ++ ++static int xenhcd_urb_request_done(struct xenhcd_info *info, ++ unsigned int *eoiflag) + { + struct xenusb_urb_response res; +- struct urb *urb; + RING_IDX i, rp; + __u16 id; + int more_to_do = 0; +@@ -961,16 +986,12 @@ static int xenhcd_urb_request_done(struct xenhcd_info *info) + xenhcd_gnttab_done(info, id); + if (info->error) + goto err; +- urb = info->shadow[id].urb; +- if (likely(urb)) { +- urb->actual_length = res.actual_length; +- urb->error_count = res.error_count; +- urb->start_frame = res.start_frame; +- xenhcd_giveback_urb(info, urb, res.status); +- } ++ xenhcd_res_to_urb(info, &res, info->shadow[id].urb); + } + + xenhcd_add_id_to_freelist(info, id); ++ ++ *eoiflag = 0; + } + info->urb_ring.rsp_cons = i; + +@@ -988,7 +1009,7 @@ static int xenhcd_urb_request_done(struct xenhcd_info *info) + return 0; + } + +-static int xenhcd_conn_notify(struct xenhcd_info *info) ++static int xenhcd_conn_notify(struct xenhcd_info *info, unsigned int *eoiflag) + { + struct xenusb_conn_response res; + struct xenusb_conn_request *req; +@@ -1033,6 +1054,8 @@ static int xenhcd_conn_notify(struct xenhcd_info *info) + info->conn_ring.req_prod_pvt); + req->id = id; + info->conn_ring.req_prod_pvt++; ++ ++ *eoiflag = 0; + } + + if (rc != info->conn_ring.req_prod_pvt) +@@ -1055,14 +1078,19 @@ static int xenhcd_conn_notify(struct xenhcd_info *info) + static irqreturn_t xenhcd_int(int irq, void *dev_id) + { + struct xenhcd_info *info = (struct xenhcd_info *)dev_id; ++ unsigned int eoiflag = XEN_EOI_FLAG_SPURIOUS; + +- if (unlikely(info->error)) ++ if (unlikely(info->error)) { ++ xen_irq_lateeoi(irq, XEN_EOI_FLAG_SPURIOUS); + return IRQ_HANDLED; ++ } + +- while (xenhcd_urb_request_done(info) | xenhcd_conn_notify(info)) ++ while (xenhcd_urb_request_done(info, &eoiflag) | ++ xenhcd_conn_notify(info, &eoiflag)) + /* Yield point for this unbounded loop. */ + cond_resched(); + ++ xen_irq_lateeoi(irq, eoiflag); + return IRQ_HANDLED; + } + +@@ -1139,9 +1167,9 @@ static int xenhcd_setup_rings(struct xenbus_device *dev, + goto fail; + } + +- err = bind_evtchn_to_irq(info->evtchn); ++ err = bind_evtchn_to_irq_lateeoi(info->evtchn); + if (err <= 0) { +- xenbus_dev_fatal(dev, err, "bind_evtchn_to_irq"); ++ xenbus_dev_fatal(dev, err, "bind_evtchn_to_irq_lateeoi"); + goto fail; + } + +@@ -1494,6 +1522,7 @@ static struct usb_hcd *xenhcd_create_hcd(struct xenbus_device *dev) + for (i = 0; i < XENUSB_URB_RING_SIZE; i++) { + info->shadow[i].req.id = i + 1; + info->shadow[i].urb = NULL; ++ info->shadow[i].in_flight = false; + } + info->shadow[XENUSB_URB_RING_SIZE - 1].req.id = 0x0fff; + +-- +2.35.3 + diff --git a/patches.suse/xen-usb-switch-xen-hcd-to-use-INVALID_GRANT_REF.patch b/patches.suse/xen-usb-switch-xen-hcd-to-use-INVALID_GRANT_REF.patch new file mode 100644 index 0000000..fbcc2a7 --- /dev/null +++ b/patches.suse/xen-usb-switch-xen-hcd-to-use-INVALID_GRANT_REF.patch @@ -0,0 +1,68 @@ +From edd81e7caa77a2772bb9ddb8562e2d45aeed2cc1 Mon Sep 17 00:00:00 2001 +From: Juergen Gross +Date: Thu, 28 Apr 2022 09:01:02 +0200 +Subject: [PATCH] xen/usb: switch xen-hcd to use INVALID_GRANT_REF +Git-commit: edd81e7caa77a2772bb9ddb8562e2d45aeed2cc1 +References: jsc#PED-531 +Patch-mainline: v5.19-rc1 + +Instead of using a private macro for an invalid grant reference use +the common one. + +Signed-off-by: Juergen Gross +Acked-by: Greg Kroah-Hartman +Signed-off-by: Juergen Gross +Signed-off-by: Oliver Neukum +--- + drivers/usb/host/xen-hcd.c | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +diff --git a/drivers/usb/host/xen-hcd.c b/drivers/usb/host/xen-hcd.c +index 3e487baf8422..9cbc7c2dab02 100644 +--- a/drivers/usb/host/xen-hcd.c ++++ b/drivers/usb/host/xen-hcd.c +@@ -87,8 +87,6 @@ struct xenhcd_info { + bool error; + }; + +-#define GRANT_INVALID_REF 0 +- + #define XENHCD_RING_JIFFIES (HZ/200) + #define XENHCD_SCAN_JIFFIES 1 + +@@ -1100,17 +1098,17 @@ static void xenhcd_destroy_rings(struct xenhcd_info *info) + unbind_from_irqhandler(info->irq, info); + info->irq = 0; + +- if (info->urb_ring_ref != GRANT_INVALID_REF) { ++ if (info->urb_ring_ref != INVALID_GRANT_REF) { + gnttab_end_foreign_access(info->urb_ring_ref, + (unsigned long)info->urb_ring.sring); +- info->urb_ring_ref = GRANT_INVALID_REF; ++ info->urb_ring_ref = INVALID_GRANT_REF; + } + info->urb_ring.sring = NULL; + +- if (info->conn_ring_ref != GRANT_INVALID_REF) { ++ if (info->conn_ring_ref != INVALID_GRANT_REF) { + gnttab_end_foreign_access(info->conn_ring_ref, + (unsigned long)info->conn_ring.sring); +- info->conn_ring_ref = GRANT_INVALID_REF; ++ info->conn_ring_ref = INVALID_GRANT_REF; + } + info->conn_ring.sring = NULL; + } +@@ -1123,8 +1121,8 @@ static int xenhcd_setup_rings(struct xenbus_device *dev, + grant_ref_t gref; + int err; + +- info->urb_ring_ref = GRANT_INVALID_REF; +- info->conn_ring_ref = GRANT_INVALID_REF; ++ info->urb_ring_ref = INVALID_GRANT_REF; ++ info->conn_ring_ref = INVALID_GRANT_REF; + + urb_sring = (struct xenusb_urb_sring *)get_zeroed_page( + GFP_NOIO | __GFP_HIGH); +-- +2.35.3 + diff --git a/patches.suse/xen-usbfront-use-xenbus_setup_ring-and-xenbus_teardo.patch b/patches.suse/xen-usbfront-use-xenbus_setup_ring-and-xenbus_teardo.patch new file mode 100644 index 0000000..8fd27a3 --- /dev/null +++ b/patches.suse/xen-usbfront-use-xenbus_setup_ring-and-xenbus_teardo.patch @@ -0,0 +1,109 @@ +From 2b3daf083aa8297c737c8cd8f896596d509ead35 Mon Sep 17 00:00:00 2001 +From: Juergen Gross +Date: Thu, 28 Apr 2022 09:01:05 +0200 +Subject: [PATCH] xen/usbfront: use xenbus_setup_ring() and + xenbus_teardown_ring() +Git-commit: 2b3daf083aa8297c737c8cd8f896596d509ead35 +References: jsc#PED-531 +Patch-mainline: v5.19-rc1 + +Simplify xen-hcd's ring creation and removal via xenbus_setup_ring() +and xenbus_teardown_ring(). + +Signed-off-by: Juergen Gross +Acked-by: Greg Kroah-Hartman +Signed-off-by: Juergen Gross +Signed-off-by: Oliver Neukum +--- + drivers/usb/host/xen-hcd.c | 61 ++++++++++---------------------------- + 1 file changed, 15 insertions(+), 46 deletions(-) + +diff --git a/drivers/usb/host/xen-hcd.c b/drivers/usb/host/xen-hcd.c +index 9cbc7c2dab02..de1b09158318 100644 +--- a/drivers/usb/host/xen-hcd.c ++++ b/drivers/usb/host/xen-hcd.c +@@ -1098,19 +1098,10 @@ static void xenhcd_destroy_rings(struct xenhcd_info *info) + unbind_from_irqhandler(info->irq, info); + info->irq = 0; + +- if (info->urb_ring_ref != INVALID_GRANT_REF) { +- gnttab_end_foreign_access(info->urb_ring_ref, +- (unsigned long)info->urb_ring.sring); +- info->urb_ring_ref = INVALID_GRANT_REF; +- } +- info->urb_ring.sring = NULL; +- +- if (info->conn_ring_ref != INVALID_GRANT_REF) { +- gnttab_end_foreign_access(info->conn_ring_ref, +- (unsigned long)info->conn_ring.sring); +- info->conn_ring_ref = INVALID_GRANT_REF; +- } +- info->conn_ring.sring = NULL; ++ xenbus_teardown_ring((void **)&info->urb_ring.sring, 1, ++ &info->urb_ring_ref); ++ xenbus_teardown_ring((void **)&info->conn_ring.sring, 1, ++ &info->conn_ring_ref); + } + + static int xenhcd_setup_rings(struct xenbus_device *dev, +@@ -1118,46 +1109,24 @@ static int xenhcd_setup_rings(struct xenbus_device *dev, + { + struct xenusb_urb_sring *urb_sring; + struct xenusb_conn_sring *conn_sring; +- grant_ref_t gref; + int err; + +- info->urb_ring_ref = INVALID_GRANT_REF; + info->conn_ring_ref = INVALID_GRANT_REF; +- +- urb_sring = (struct xenusb_urb_sring *)get_zeroed_page( +- GFP_NOIO | __GFP_HIGH); +- if (!urb_sring) { +- xenbus_dev_fatal(dev, -ENOMEM, "allocating urb ring"); +- return -ENOMEM; +- } +- SHARED_RING_INIT(urb_sring); +- FRONT_RING_INIT(&info->urb_ring, urb_sring, PAGE_SIZE); +- +- err = xenbus_grant_ring(dev, urb_sring, 1, &gref); +- if (err < 0) { +- free_page((unsigned long)urb_sring); +- info->urb_ring.sring = NULL; +- goto fail; +- } +- info->urb_ring_ref = gref; +- +- conn_sring = (struct xenusb_conn_sring *)get_zeroed_page( +- GFP_NOIO | __GFP_HIGH); +- if (!conn_sring) { +- xenbus_dev_fatal(dev, -ENOMEM, "allocating conn ring"); +- err = -ENOMEM; +- goto fail; ++ err = xenbus_setup_ring(dev, GFP_NOIO | __GFP_HIGH, ++ (void **)&urb_sring, 1, &info->urb_ring_ref); ++ if (err) { ++ xenbus_dev_fatal(dev, err, "allocating urb ring"); ++ return err; + } +- SHARED_RING_INIT(conn_sring); +- FRONT_RING_INIT(&info->conn_ring, conn_sring, PAGE_SIZE); ++ XEN_FRONT_RING_INIT(&info->urb_ring, urb_sring, PAGE_SIZE); + +- err = xenbus_grant_ring(dev, conn_sring, 1, &gref); +- if (err < 0) { +- free_page((unsigned long)conn_sring); +- info->conn_ring.sring = NULL; ++ err = xenbus_setup_ring(dev, GFP_NOIO | __GFP_HIGH, ++ (void **)&conn_sring, 1, &info->conn_ring_ref); ++ if (err) { ++ xenbus_dev_fatal(dev, err, "allocating conn ring"); + goto fail; + } +- info->conn_ring_ref = gref; ++ XEN_FRONT_RING_INIT(&info->conn_ring, conn_sring, PAGE_SIZE); + + err = xenbus_alloc_evtchn(dev, &info->evtchn); + if (err) { +-- +2.35.3 + diff --git a/patches.suse/xen-xenbus-add-xenbus_setup_ring-service-function.patch b/patches.suse/xen-xenbus-add-xenbus_setup_ring-service-function.patch new file mode 100644 index 0000000..19e942b --- /dev/null +++ b/patches.suse/xen-xenbus-add-xenbus_setup_ring-service-function.patch @@ -0,0 +1,130 @@ +From 7050096d07755c53f71e486af18475050cc4e04b Mon Sep 17 00:00:00 2001 +From: Juergen Gross +Date: Thu, 28 Apr 2022 09:01:03 +0200 +Subject: [PATCH] xen/xenbus: add xenbus_setup_ring() service function +Git-commit: 7050096d07755c53f71e486af18475050cc4e04b +References: jsc#PED-531 +Patch-mainline: v5.19-rc1 + +Most PV device frontends share very similar code for setting up shared +ring buffers: + +- allocate page(s) +- init the ring admin data +- give the backend access to the ring via grants + +Tearing down the ring requires similar actions in all frontends again: + +- remove grants +- free the page(s) + +Provide service functions xenbus_setup_ring() and xenbus_teardown_ring() +for that purpose. + +Signed-off-by: Juergen Gross +Reviewed-by: Boris Ostrovsky +Signed-off-by: Juergen Gross +Signed-off-by: Oliver Neukum +--- + drivers/xen/xenbus/xenbus_client.c | 69 ++++++++++++++++++++++++++++++ + include/xen/xenbus.h | 4 ++ + 2 files changed, 73 insertions(+) + +diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c +index df6890681231..1a2e0d94ccd1 100644 +--- a/drivers/xen/xenbus/xenbus_client.c ++++ b/drivers/xen/xenbus/xenbus_client.c +@@ -407,6 +407,75 @@ int xenbus_grant_ring(struct xenbus_device *dev, void *vaddr, + } + EXPORT_SYMBOL_GPL(xenbus_grant_ring); + ++/* ++ * xenbus_setup_ring ++ * @dev: xenbus device ++ * @vaddr: pointer to starting virtual address of the ring ++ * @nr_pages: number of pages to be granted ++ * @grefs: grant reference array to be filled in ++ * ++ * Allocate physically contiguous pages for a shared ring buffer and grant it ++ * to the peer of the given device. The ring buffer is initially filled with ++ * zeroes. The virtual address of the ring is stored at @vaddr and the ++ * grant references are stored in the @grefs array. In case of error @vaddr ++ * will be set to NULL and @grefs will be filled with INVALID_GRANT_REF. ++ */ ++int xenbus_setup_ring(struct xenbus_device *dev, gfp_t gfp, void **vaddr, ++ unsigned int nr_pages, grant_ref_t *grefs) ++{ ++ unsigned long ring_size = nr_pages * XEN_PAGE_SIZE; ++ unsigned int i; ++ int ret; ++ ++ *vaddr = alloc_pages_exact(ring_size, gfp | __GFP_ZERO); ++ if (!*vaddr) { ++ ret = -ENOMEM; ++ goto err; ++ } ++ ++ ret = xenbus_grant_ring(dev, *vaddr, nr_pages, grefs); ++ if (ret) ++ goto err; ++ ++ return 0; ++ ++ err: ++ if (*vaddr) ++ free_pages_exact(*vaddr, ring_size); ++ for (i = 0; i < nr_pages; i++) ++ grefs[i] = INVALID_GRANT_REF; ++ *vaddr = NULL; ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(xenbus_setup_ring); ++ ++/* ++ * xenbus_teardown_ring ++ * @vaddr: starting virtual address of the ring ++ * @nr_pages: number of pages ++ * @grefs: grant reference array ++ * ++ * Remove grants for the shared ring buffer and free the associated memory. ++ * On return the grant reference array is filled with INVALID_GRANT_REF. ++ */ ++void xenbus_teardown_ring(void **vaddr, unsigned int nr_pages, ++ grant_ref_t *grefs) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < nr_pages; i++) { ++ if (grefs[i] != INVALID_GRANT_REF) { ++ gnttab_end_foreign_access(grefs[i], 0); ++ grefs[i] = INVALID_GRANT_REF; ++ } ++ } ++ ++ if (*vaddr) ++ free_pages_exact(*vaddr, nr_pages * XEN_PAGE_SIZE); ++ *vaddr = NULL; ++} ++EXPORT_SYMBOL_GPL(xenbus_teardown_ring); + + /** + * Allocate an event channel for the given xenbus_device, assigning the newly +diff --git a/include/xen/xenbus.h b/include/xen/xenbus.h +index b13eb86395e0..b533b4adc835 100644 +--- a/include/xen/xenbus.h ++++ b/include/xen/xenbus.h +@@ -226,6 +226,10 @@ int xenbus_watch_pathfmt(struct xenbus_device *dev, struct xenbus_watch *watch, + int xenbus_switch_state(struct xenbus_device *dev, enum xenbus_state new_state); + int xenbus_grant_ring(struct xenbus_device *dev, void *vaddr, + unsigned int nr_pages, grant_ref_t *grefs); ++int xenbus_setup_ring(struct xenbus_device *dev, gfp_t gfp, void **vaddr, ++ unsigned int nr_pages, grant_ref_t *grefs); ++void xenbus_teardown_ring(void **vaddr, unsigned int nr_pages, ++ grant_ref_t *grefs); + int xenbus_map_ring_valloc(struct xenbus_device *dev, grant_ref_t *gnt_refs, + unsigned int nr_grefs, void **vaddr); + +-- +2.35.3 + diff --git a/patches.suse/xhci-Don-t-show-warning-for-reinit-on-known-broken-s.patch b/patches.suse/xhci-Don-t-show-warning-for-reinit-on-known-broken-s.patch new file mode 100644 index 0000000..c26abba --- /dev/null +++ b/patches.suse/xhci-Don-t-show-warning-for-reinit-on-known-broken-s.patch @@ -0,0 +1,48 @@ +From 484d6f7aa3283d082c87654b7fe7a7f725423dfb Mon Sep 17 00:00:00 2001 +From: Mario Limonciello +Date: Wed, 21 Sep 2022 15:34:47 +0300 +Subject: [PATCH] xhci: Don't show warning for reinit on known broken suspend +Git-commit: 484d6f7aa3283d082c87654b7fe7a7f725423dfb +Patch-mainline: v6.1-rc1 +References: git-fixes + +commit 8b328f8002bc ("xhci: re-initialize the HC during resume if HCE was +set") introduced a new warning message when the host controller error +was set and re-initializing. + +This is expected behavior on some designs which already set +`xhci->broken_suspend` so the new warning is alarming to some users. + +Modify the code to only show the warning if this was a surprising behavior +to the XHCI driver. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=216470 +Fixes: 8b328f8002bc ("xhci: re-initialize the HC during resume if HCE was set") +Reported-by: Artem S. Tashkinov +Signed-off-by: Mario Limonciello +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20220921123450.671459-4-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/usb/host/xhci.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index e8837c5d6f5c..9f6b55281f44 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -1183,7 +1183,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) + /* re-initialize the HC on Restore Error, or Host Controller Error */ + if (temp & (STS_SRE | STS_HCE)) { + reinit_xhc = true; +- xhci_warn(xhci, "xHC error in resume, USBSTS 0x%x, Reinit\n", temp); ++ if (!xhci->broken_suspend) ++ xhci_warn(xhci, "xHC error in resume, USBSTS 0x%x, Reinit\n", temp); + } + + if (reinit_xhc) { +-- +2.35.3 + diff --git a/patches.suse/xhci-dbc-Fix-memory-leak-in-xhci_alloc_dbc.patch b/patches.suse/xhci-dbc-Fix-memory-leak-in-xhci_alloc_dbc.patch new file mode 100644 index 0000000..f1cff2b --- /dev/null +++ b/patches.suse/xhci-dbc-Fix-memory-leak-in-xhci_alloc_dbc.patch @@ -0,0 +1,39 @@ +From d591b32e519603524a35b172156db71df9116902 Mon Sep 17 00:00:00 2001 +From: Rafael Mendonca +Date: Wed, 21 Sep 2022 15:34:46 +0300 +Subject: [PATCH] xhci: dbc: Fix memory leak in xhci_alloc_dbc() +Git-commit: d591b32e519603524a35b172156db71df9116902 +Patch-mainline: v6.1-rc1 +References: git-fixes + +If DbC is already in use, then the allocated memory for the xhci_dbc struct +doesn't get freed before returning NULL, which leads to a memleak. + +Fixes: 534675942e90 ("xhci: dbc: refactor xhci_dbc_init()") +Cc: stable@vger.kernel.org +Signed-off-by: Rafael Mendonca +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20220921123450.671459-3-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/usb/host/xhci-dbgcap.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/usb/host/xhci-dbgcap.c b/drivers/usb/host/xhci-dbgcap.c +index e61155fa6379..f1367b53b260 100644 +--- a/drivers/usb/host/xhci-dbgcap.c ++++ b/drivers/usb/host/xhci-dbgcap.c +@@ -988,7 +988,7 @@ xhci_alloc_dbc(struct device *dev, void __iomem *base, const struct dbc_driver * + dbc->driver = driver; + + if (readl(&dbc->regs->control) & DBC_CTRL_DBC_ENABLE) +- return NULL; ++ goto err; + + INIT_DELAYED_WORK(&dbc->event_work, xhci_dbc_handle_events); + spin_lock_init(&dbc->lock); +-- +2.35.3 + diff --git a/patches.suse/xhci-remove-unused-command-member-from-struct-xhci_h.patch b/patches.suse/xhci-remove-unused-command-member-from-struct-xhci_h.patch new file mode 100644 index 0000000..2e24700 --- /dev/null +++ b/patches.suse/xhci-remove-unused-command-member-from-struct-xhci_h.patch @@ -0,0 +1,32 @@ +From 1a855a83592ed968d95ea28f15755c22f8336fba Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Wed, 21 Sep 2022 15:34:49 +0300 +Subject: [PATCH] xhci: remove unused command member from struct xhci_hcd + struct +Git-commit: 1a855a83592ed968d95ea28f15755c22f8336fba +References: jsc#PED-531 +Patch-mainline: v6.1-rc1 + +The u32 command was added to struct xhci_hcd over 10 years ago in +commit 9777e3ce907d ("USB: xHCI: bus power management implementation") + +It wasn't even used back then, so remove it. + +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20220921123450.671459-6-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/usb/host/xhci.h | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1827,7 +1827,6 @@ struct xhci_hcd { + /* Host controller watchdog timer structures */ + unsigned int xhc_state; + +- u32 command; + struct s3_save s3; + /* Host controller is dying - not responding to commands. "I'm not dead yet!" + * diff --git a/patches.suse/xhci-remove-unused-lpm_failed_dev-member-from-struct.patch b/patches.suse/xhci-remove-unused-lpm_failed_dev-member-from-struct.patch new file mode 100644 index 0000000..fe9439b --- /dev/null +++ b/patches.suse/xhci-remove-unused-lpm_failed_dev-member-from-struct.patch @@ -0,0 +1,43 @@ +From d2e672a67fd24d842874216911ea2d1cdb54173e Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Wed, 21 Sep 2022 15:34:50 +0300 +Subject: [PATCH] xhci: remove unused lpm_failed_dev member from struct + xhci_hcd +Git-commit: d2e672a67fd24d842874216911ea2d1cdb54173e +References: jsc#PED-531 +Patch-mainline: v6.1-rc1 + +xhci used to test if link power management (LPM) capable USB2 devices +really could enter and exit L1 state link state. +Failed devices were added to a lpm_failed_dev list. + +This feature was removed 9 years ago in +commit de68bab4fa96 ("usb: Don't enable USB 2.0 Link PM by default.") +but lpm_failed_dev member was still left. + +Remove it now. + +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20220921123450.671459-7-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/usb/host/xhci.h | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h +index e1091bce942f..c0964fe8ac12 100644 +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1807,8 +1807,6 @@ struct xhci_hcd { + struct xhci_erst erst; + /* Scratchpad */ + struct xhci_scratchpad *scratchpad; +- /* Store LPM test failed devices' information */ +- struct list_head lpm_failed_devs; + + /* slot enabling and address device helpers */ + /* these are not thread safe so use mutex */ +-- +2.35.3 + diff --git a/rpm/check-for-config-changes b/rpm/check-for-config-changes index fb31586..624f10c 100755 --- a/rpm/check-for-config-changes +++ b/rpm/check-for-config-changes @@ -5,7 +5,7 @@ # # please keep them sorted alphabetically declare -a IGNORED_CONFIGS_RE=( - 'AS_HAS_[A-Z_]*' + 'AS_HAS_[A-Z0-9_]*' 'AS_VERSION' 'CC_CAN_[A-Z_]*' 'CC_HAS_[A-Z_]*' diff --git a/scripts/check-kernel-commit b/scripts/check-kernel-commit new file mode 100755 index 0000000..45a0a6e --- /dev/null +++ b/scripts/check-kernel-commit @@ -0,0 +1,173 @@ +#!/bin/bash + +usage() +{ + echo "Check whether a given list of commit is available in" + echo "a given list of branches." + echo + echo "Usage: ${0##*/} [branches.conf] term..." + echo + echo "Parametes:" + echo " branches.conf: file with the list of branches to be checked" + echo " term: hash of the commit|CVE|bsc to be found" +} + +fetch_branches() +{ + local CACHED_BRANCHES="/tmp/$USER-branches.conf" + local URL="https://kerncvs.suse.de/branches.conf" + local EXPIRE=7 + branches=$CACHED_BRANCHES + if [[ $(find "$CACHED_BRANCHES" -mtime -$EXPIRE -print 2>/dev/null) \ + && -s "$CACHED_BRANCHES" ]]; then + echo "Using cached $CACHED_BRANCHES" >&2 + return + fi + curl "$URL" -o "$CACHED_BRANCHES" +} + +if [ $# -lt 1 ] ; then + usage + exit 1 +fi + +branches=$1 +if [ ! -f "$branches" ] ; then + echo "Branches file not specified, trying to fetch it..." >&2 + if ! fetch_branches ; then + "Error: Can't find the file with the list of branches: $branches nor fetch it" + exit 1 + fi +else + shift; +fi + +KBC_CHECK_TERMS="$*" + +term2regex() +{ + shopt -q nocasematch + local t=$1 + case $t in + # CVEs first + 2[0-9][0-9][0-9]-*) + t=cve-$t + ;& + cve-*) + echo "^References:.*$t" + ;; + # looks like a hash, look for commits + [a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]*) + echo "^Git-commit:.*$t" + ;; + # treat rest as a generic reference + *) + echo "^References:.*$t" + ;; + esac +} + +check_branch() +{ + verbose=0 + if [ "$1" = "-v" ] ; then + verbose=1 + shift + fi + + branch="$1" + found="" + missing="" + + for term in $KBC_CHECK_TERMS ; do + git grep -qi "$(term2regex $term)" "remotes/origin/$branch" -- 'patches.*' 2>/dev/null + if [ $? -eq 0 ] ; then + found="$found $term" + else + missing="$missing $term" + fi + done + + # found + if [ -z "$missing" ] ; then + return 0 + fi + + # missing + if [ -z "$found" ] ; then + return 2 + fi + + # partly + if [ $verbose -ne 0 ] ; then + echo " missing hash:" + for hash in $missing ; do + echo " $term" + done + echo + fi + return 1 +} + +check_parents() +{ + last_branch="" + for branch in "$@" ; do + check_branch $branch + case $? in + 0) + echo " (found in $branch)" + return + ;; + 1) + echo " (partly in $branch)" + return + ;; + *) + ;; + esac + last_branch="$branch" + done + + # not found anywhere + echo " (not even in $last_branch)" +} + +grep -w build "$branches" | grep -v -E "^(master|vanilla|linux-next|cve)" | \ +while read line ; do + line=${line%%\#*} + branch=${line%%:*} + + # empty line or comment + if [ -z "$branch" ] ; then + continue + fi + + # always check also the _EMBARGO branch as a possible parent + parents="${branch}_EMBARGO" + set dummy ${line#$branch:} + while [ $# -gt 0 ] ; do + shift + [[ "$1" =~ "merge:" ]] || continue + tmp="${1//*merge:-/}" + parents="$parents ${tmp//*merge:/}" + done + + printf "%-23s" "$branch" + check_branch "$branch" + + case $? in + 0) + echo "" + ;; + 1) + echo -n " " + check_parents $parents + # print missing commits + check_branch -v "$branch" + ;; + *) + echo -n "" + check_parents "${branch}_EMBARGO" $parents + esac +done diff --git a/scripts/git_sort/git_sort.py b/scripts/git_sort/git_sort.py index d4881c7..fb07dcf 100755 --- a/scripts/git_sort/git_sort.py +++ b/scripts/git_sort/git_sort.py @@ -213,8 +213,8 @@ remotes = ( Head(RepoURL("gregkh/tty.git"), "tty-next"), Head(RepoURL("gregkh/usb.git"), "usb-next"), Head(RepoURL("jj/linux-apparmor.git"), "apparmor-next"), - Head(RepoURL("pablo/nf.git")), - Head(RepoURL("pablo/nf-next.git")), + Head(RepoURL("netfilter/nf.git")), + Head(RepoURL("netfilter/nf-next.git")), Head(RepoURL("horms/ipvs.git")), Head(RepoURL("horms/ipvs-next.git")), Head(RepoURL("klassert/ipsec.git")), diff --git a/scripts/git_sort/lib.py b/scripts/git_sort/lib.py index c656116..59d08bf 100644 --- a/scripts/git_sort/lib.py +++ b/scripts/git_sort/lib.py @@ -277,6 +277,12 @@ class InputEntry(object): raise exc.KSError("Multiple Patch-mainline tags found. Patch \"%s\" is " "tagged improperly." % (name,)) + if not mainline_tags: + raise exc.KSError( + "There is a problem with patch \"%s\". " + "The Patch-mainline tag is missing." % ( + name,)) + if not commit_tags: self.dest_head = git_sort.oot mainline = mainline_tags[0] diff --git a/scripts/git_sort/tests/test_series_insert.py b/scripts/git_sort/tests/test_series_insert.py index 9be2e1e..43d52d3 100755 --- a/scripts/git_sort/tests/test_series_insert.py +++ b/scripts/git_sort/tests/test_series_insert.py @@ -53,11 +53,19 @@ class TestSeriesInsert(unittest.TestCase): # setup stub kernel-source content self.ks_dir = tempfile.mkdtemp(prefix="gs_ks") patch_dir = os.path.join(self.ks_dir, "patches.suse") + self.si_path = os.path.join(lib.libdir(), "series_insert.py") os.mkdir(patch_dir) os.chdir(patch_dir) for commit in commits: tests.support.format_patch(self.repo.get(commit), mainline="v3.45-rc6") + series = os.path.join(self.ks_dir, "series.conf"); + content = tests.support.format_series(( + (None, + ("patches.suse/mainline-%d.patch" % (i,) for i in (0, 2,))), + )) + with open(series, mode="w") as f: + f.write(content) def tearDown(self): shutil.rmtree(os.environ["XDG_CACHE_HOME"]) @@ -66,18 +74,11 @@ class TestSeriesInsert(unittest.TestCase): def test_simple(self): - si_path = os.path.join(lib.libdir(), "series_insert.py") os.chdir(self.ks_dir) series = "series.conf" - series1 = tests.support.format_series(( - (None, - ("patches.suse/mainline-%d.patch" % (i,) for i in (0, 2,))), - )) - with open(series, mode="w") as f: - f.write(series1) - subprocess.check_call([si_path, "patches.suse/mainline-1.patch"]) + subprocess.check_call([self.si_path, "patches.suse/mainline-1.patch"]) with open(series) as f: content = f.read() self.assertEqual(content, @@ -86,6 +87,9 @@ class TestSeriesInsert(unittest.TestCase): ("patches.suse/mainline-%d.patch" % (i,) for i in range(3))), ))) + def test_invalid(self): + os.chdir(self.ks_dir) + content = [] with open("patches.suse/mainline-1.patch") as f: for line in f: @@ -95,11 +99,8 @@ class TestSeriesInsert(unittest.TestCase): with open("patches.suse/mainline-1.patch", mode="w+") as f: f.writelines(content) - with open(series, mode="w") as f: - f.write(series1) - try: - subprocess.check_output([si_path, "patches.suse/mainline-1.patch"], + subprocess.check_output([self.si_path, "patches.suse/mainline-1.patch"], stderr=subprocess.STDOUT) except subprocess.CalledProcessError as err: self.assertEqual(err.returncode, 1) @@ -110,7 +111,28 @@ class TestSeriesInsert(unittest.TestCase): else: self.assertTrue(False) - os.unlink(series) + def test_noheader(self): + os.chdir(self.ks_dir) + + content = [] + with open("patches.suse/mainline-1.patch") as f: + for line in f: + if not line.startswith("Git-commit: ") and not line.startswith("Patch-mainline: "): + content.append(line) + with open("patches.suse/mainline-1.patch", mode="w+") as f: + f.writelines(content) + + try: + subprocess.check_output([self.si_path, "patches.suse/mainline-1.patch"], + stderr=subprocess.STDOUT) + except subprocess.CalledProcessError as err: + self.assertEqual(err.returncode, 1) + self.assertEqual( + err.output.decode(), + 'Error: There is a problem with patch "patches.suse/mainline-1.patch". ' + 'The Patch-mainline tag is missing.\n') + else: + self.assertTrue(False) if __name__ == '__main__': diff --git a/scripts/python/suse_git/header.py b/scripts/python/suse_git/header.py index 43d4406..f3fcd04 100755 --- a/scripts/python/suse_git/header.py +++ b/scripts/python/suse_git/header.py @@ -59,6 +59,11 @@ tag_map = { 'match' : 'Submitted,?\s+.+', 'excludes' : [ 'Git-commit', 'Git-repo' ], }, { + # Catch a frequent misuse of 'Not yet'. + 'match' : 'Not yet,\s+submitted', + 'error' : "Please use 'Submitted'", + 'excludes' : [ 'Git-commit', 'Git-repo' ], + }, { # Should be used rarely. Description should provide # reason for the patch not being accepted upstream. 'name' : 'Not yet', diff --git a/scripts/python/tests/test_header.py b/scripts/python/tests/test_header.py index 5051b39..21daceb 100755 --- a/scripts/python/tests/test_header.py +++ b/scripts/python/tests/test_header.py @@ -715,3 +715,18 @@ References: FATE#123456 Acked-by: developer@suse.com """ self.header = header.Checker(text, False, "patches.kabi/FATE123456_fix_kabi.patch") + + def test_patch_mainline_invalid2(self): + text = """ +From: developer@site.com +Subject: some patch +Patch-mainline: Not yet, submitted 2022-08-23 +References: bsc#12345 +Acked-by: developer@suse.com +""" + with self.assertRaises(header.HeaderException) as cm: + self.header = header.Checker(text) + + e = cm.exception + self.assertEqual(1, e.errors(header.FormatError)) + self.assertEqual(1, e.errors()) diff --git a/scripts/wd-functions.sh b/scripts/wd-functions.sh index 3111d40..d645a42 100644 --- a/scripts/wd-functions.sh +++ b/scripts/wd-functions.sh @@ -34,7 +34,7 @@ get_branch_name() if $using_git; then # FIXME: guess a branch name when a non-branch revision is checked # out - local res=$(sed -ne 's|^ref: refs/heads/||p' "$scripts_dir"/../.git/HEAD 2>/dev/null) + local res=$(sed -ne 's|^ref: refs/heads/||p' "$(git rev-parse --git-dir)"/HEAD 2>/dev/null) echo "$res" fi } diff --git a/series.conf b/series.conf index cc1675f..55f66a7 100644 --- a/series.conf +++ b/series.conf @@ -147,6 +147,10 @@ patches.suse/s390-qdio-cancel-the-ESTABLISH-ccw-after-timeout.patch patches.suse/s390-qdio-improve-roll-back-after-error-on-ESTABLISH-ccw patches.suse/s390-qdio-propagate-error-when-cancelling-a-ccw-fails + patches.suse/s390-qdio-remove-remaining-tasklet-timer-code + patches.suse/s390-qdio-remove-unneeded-siga-sync-for-Output-Queue + patches.suse/s390-qdio-clarify-reporting-of-errors-to-the-drivers + patches.suse/s390-qdio-remove-unused-macros patches.suse/s390-report-more-CPU-capabilities patches.suse/s390-disassembler-add-instructions patches.suse/s390-make-PCI-mio-support-a-machine-flag.patch @@ -154,6 +158,13 @@ patches.suse/s390-replace-deprecated-CPU-hotplug-functions.patch patches.suse/s390-sclp-replace-deprecated-CPU-hotplug-functions.patch patches.suse/s390-cio-add-dev_busid-sysfs-entry-for-each-subchann.patch + patches.suse/s390-qdio-use-absolute-data-address-in-ESTABLISH-ccw + patches.suse/s390-qdio-remove-unused-sync-after-IRQ-infrastructure + patches.suse/s390-qdio-clean-up-SIGA-capability-tracking + patches.suse/s390-qdio-fine-tune-the-queue-sync + patches.suse/s390-qdio-use-dev_info-in-qdio_print_subchannel_info + patches.suse/s390-qdio-consolidate-QIB-code + patches.suse/s390-qdio-remove-unused-support-for-SLIB-parameters patches.suse/s390-zcrypt-fix-wrong-offset-index-for-APKA-master-k.patch patches.suse/s390-pci-cleanup-resources-only-if-necessary.patch patches.suse/s390-kasan-fix-large-PMD-pages-address-alignment-che.patch @@ -513,6 +524,7 @@ patches.suse/PM-sleep-s2idle-Replace-deprecated-CPU-hotplug-functions.patch patches.suse/opp-Don-t-print-an-error-if-required-opps-is-missing.patch patches.suse/powercap-intel_rapl-Replace-deprecated-CPU-hotplug-functions.patch + patches.suse/powercap-Add-Power-Limit4-support-for-Alder-Lake-SoC.patch patches.suse/ACPICA-iASL-Add-support-for-the-AEST-table-data-comp-e692fa13.patch patches.suse/ACPICA-Fix-an-if-statement-add-parens-5ecce804.patch patches.suse/ACPICA-Macros-should-not-use-a-trailing-semicolon-78df71b3.patch @@ -637,6 +649,8 @@ patches.suse/i40e-improve-locking-of-mac_filter_hash.patch patches.suse/iavf-do-not-override-the-adapter-state-in-the-watchd.patch patches.suse/iavf-fix-locking-of-critical-sections.patch + patches.suse/s390-qeth-clean-up-QETH_PROT_-naming + patches.suse/s390-qeth-clean-up-device_type-management patches.suse/net-dsa-build-tag_8021q.c-as-part-of-DSA-core.patch patches.suse/net-phy-add-API-to-read-802.3-c45-IDs.patch patches.suse/net-phy-add-Maxlinear-GPY115-21x-24x-driver.patch @@ -766,6 +780,7 @@ patches.suse/octeontx2-af-cn10k-DWRR-MTU-configuration.patch patches.suse/octeontx2-pf-cn10k-Config-DWRR-weight-based-on-MTU.patch patches.suse/cxgb4-make-the-array-match_all_mac-static-makes-obje.patch + patches.suse/qlcnic-make-the-array-random_data-static-const-makes-object-smaller.patch patches.suse/net-mlx4-make-the-array-states-static-const-makes-ob.patch patches.suse/net-mlx5e-Use-a-new-initializer-to-build-uniform-ind.patch patches.suse/net-mlx5e-Introduce-mlx5e_channels-API-to-get-RQNs.patch @@ -890,6 +905,7 @@ patches.suse/devlink-Clear-whole-devlink_flash_notify-struct.patch patches.suse/net-hns3-remove-always-exist-devlink-pointer-check.patch patches.suse/samples-pktgen-add-missing-IPv6-option-to-pktgen-scr.patch + patches.suse/s390-net-replace-in_irq-with-in_hardirq patches.suse/net-stmmac-fix-INTR-TBU-status-affecting-irq-count-s.patch patches.suse/ethtool-add-two-link-extended-substates-of-bad-signa.patch patches.suse/net-hns3-add-header-file-hns3_ethtoo.h.patch @@ -1032,6 +1048,7 @@ patches.suse/rtw88-wow-fix-size-access-error-of-probe-request.patch patches.suse/vmxnet3-switch-from-pci_-to-dma_-API.patch patches.suse/net-mellanox-switch-from-pci_-to-dma_-API.patch + patches.suse/qlcnic-switch-from-pci_-to-dma_-API.patch patches.suse/cxgb4-improve-printing-NIC-information.patch patches.suse/ethtool-add-two-coalesce-attributes-for-CQE-mode.patch patches.suse/ethtool-extend-coalesce-setting-uAPI-with-CQE-mode.patch @@ -1397,6 +1414,7 @@ patches.suse/usb-host-ohci-tmio-add-IRQ-check.patch patches.suse/usb-phy-tahvo-add-IRQ-check.patch patches.suse/usb-dwc3-Decouple-USB-2.0-L1-L2-events.patch + patches.suse/usb-host-remove-dead-EHCI-support-for-on-chip-PMC-MS.patch patches.suse/usb-gadget-mv_u3d-request_irq-after-initializing-UDC.patch patches.suse/USB-EHCI-Add-register-array-bounds-to-HCS-ports.patch patches.suse/USB-EHCI-Add-alias-for-Broadcom-INSNREG.patch @@ -1530,6 +1548,7 @@ patches.suse/ASoC-ti-delete-some-dead-code-in-omap_abe_probe.patch patches.suse/ASoC-atmel-ATMEL-drivers-don-t-need-HAS_DMA.patch patches.suse/ASoC-codecs-wcd938x-fix-returnvar.cocci-warnings.patch + patches.suse/ASoC-wm_adsp-Remove-pointless-string-comparison.patch patches.suse/ASoC-tlv320aic32x4-Fix-TAS2505-TAS2521-channel-count.patch patches.suse/ASoC-amd-fix-spelling-mistakes.patch patches.suse/ASoC-Intel-soc-acpi-add-support-for-SoundWire-of-TGL.patch @@ -2335,6 +2354,7 @@ patches.suse/asus-wmi-Add-panel-overdrive-functionality.patch patches.suse/asus-wmi-Add-dgpu-disable-method.patch patches.suse/asus-wmi-Add-egpu-enable-method.patch + patches.suse/i2c-acpi-Add-an-i2c_acpi_client_count-helper-functio.patch patches.suse/platform-x86-intel_pmc_core-Prevent-possibile-overfl.patch patches.suse/platform-x86-intel_pmt_telemetry-Ignore-zero-sized-e.patch patches.suse/asus-wmi-Add-support-for-platform_profile.patch @@ -2508,6 +2528,7 @@ patches.suse/scsi-smartpqi-Update-version-to-2.1.10-020.patch patches.suse/scsi-core-Add-scsi_prot_ref_tag-helper.patch patches.suse/scsi-qla2xxx-Use-the-proper-SCSI-midlayer-interfaces.patch + patches.suse/scsi-zfcp-Use-the-proper-SCSI-midlayer-interfaces-for-PI patches.suse/scsi-core-Introduce-scsi_get_sector.patch patches.suse/scsi-iser-Use-scsi_get_sector-instead-of-scsi_get_lb.patch patches.suse/scsi-lpfc-Add-PCI-ID-support-for-LPe37000-LPe38000-s.patch @@ -2553,6 +2574,7 @@ patches.suse/scsi-core-Introduce-the-scsi_cmd_to_rq-function.patch patches.suse/scsi-RDMA-iser-Use-scsi_cmd_to_rq-instead-of-scsi_cm.patch patches.suse/scsi-RDMA-srp-Use-scsi_cmd_to_rq-instead-of-scsi_cmn.patch + patches.suse/scsi-zfcp-Use-scsi_cmd_to_rq-instead-of-scsi_cmnd.request patches.suse/scsi-aacraid-Use-scsi_cmd_to_rq-instead-of-scsi_cmnd.request.patch patches.suse/scsi-bnx2i-Use-scsi_cmd_to_rq-instead-of-scsi_cmnd.request.patch patches.suse/scsi-csiostor-Use-scsi_cmd_to_rq-instead-of-scsi_cmnd.request.patch @@ -2824,6 +2846,7 @@ patches.suse/powerpc-pseries-Fix-build-error-when-NUMA-n.patch patches.suse/powerpc-config-Fix-IPV6-warning-in-mpc855_ads.patch patches.suse/powerpc-config-Renable-MTD_PHYSMAP_OF.patch + patches.suse/powerpc-kvm-Remove-obsolete-and-unneeded-select.patch patches.suse/powerpc-perf-hv-gpci-Fix-counter-value-parsing.patch patches.suse/powerpc-perf-Use-stack-siar-instead-of-mfspr.patch patches.suse/powerpc-perf-Drop-the-case-of-returning-0-as-instruc.patch @@ -3273,6 +3296,7 @@ patches.suse/s390-entry-make-oklabel-within-CHKSTG-macro-local.patch patches.suse/s390-unwind-use-current_frame_address-to-unwind-current-task.patch patches.suse/s390-topology-fix-topology-information-when-calling-.patch + patches.suse/scsi-zfcp-fix-kernel-doc-comments patches.suse/tracing-Add-migrate-disabled-counter-to-tracing-outp.patch patches.suse/tracing-osnoise-Fix-missed-cpus_read_unlock-in-start_per_cpu_kthreads.patch patches.suse/tools-bootconfig-Fix-tracing_on-option-checking-in-f.patch @@ -3443,6 +3467,7 @@ patches.suse/ice-Correctly-deal-with-PFs-that-do-not-support-RDMA.patch patches.suse/r6040-Restore-MDIO-clock-frequency-after-MAC-reset.patch patches.suse/qed-Handle-management-FW-error.patch + patches.suse/qlcnic-Remove-redundant-initialization-of-variable-ret.patch patches.suse/net-stmmac-allow-CSR-clock-of-300MHz.patch patches.suse/net-dsa-qca8k-fix-kernel-panic-with-legacy-mdio-mapp.patch patches.suse/selftest-net-fix-typo-in-altname-test.patch @@ -5038,6 +5063,7 @@ patches.suse/x86-sev-replace-occurrences-of-sev_es_active-with-cc_platform_has patches.suse/treewide-replace-the-use-of-mem_encrypt_active-with-cc_platform_has patches.suse/x86-cpu-Fix-migration-safety-with-X86_BUG_NULL_SEL.patch + patches.suse/x86-Kconfig-Fix-an-unused-variable-error-in-dell-smm.patch patches.suse/x86-insn-Use-get_unaligned-instead-of-memcpy.patch patches.suse/x86-sev-carve-out-hv-call-s-return-value-verification patches.suse/x86-sme-use-define-use_early_pgtable_l5-in-mem_encrypt_identity-c.patch @@ -5231,6 +5257,9 @@ patches.suse/mlxsw-reg-Add-Port-Module-To-local-DataBase-Register.patch patches.suse/mlxsw-spectrum-Use-PMTDB-register-to-obtain-split-in.patch patches.suse/mlxsw-reg-Remove-PMTM-register.patch + patches.suse/s390-ctcm-remove-incorrect-kernel-doc-indicators + patches.suse/s390-lcs-remove-incorrect-kernel-doc-indicators + patches.suse/s390-netiucv-remove-incorrect-kernel-doc-indicators patches.suse/net-smc-add-support-for-user-defined-EIDs patches.suse/net-smc-keep-static-copy-of-system-EID patches.suse/net-smc-add-generic-netlink-support-for-system-EID @@ -5396,6 +5425,7 @@ patches.suse/qed-Update-the-TCP-active-termination-2-MSL-timer-TI.patch patches.suse/qed-fix-ll2-establishment-during-load-of-RDMA-driver.patch patches.suse/ethernet-ehea-add-missing-cast.patch + patches.suse/net-bgmac-support-MDIO-described-in-DT.patch patches.suse/net-mlx5e-Specify-SQ-stats-struct-for-mlx5e_open_txq.patch patches.suse/net-mlx5e-Add-TX-max-rate-support-for-MQPRIO-channel.patch patches.suse/net-mlx5e-TC-Refactor-sample-offload-error-flow.patch @@ -5548,6 +5578,7 @@ patches.suse/ip-use-dev_addr_set-in-tunnels.patch patches.suse/net-remove-single-byte-netdev-dev_addr-writes.patch patches.suse/marvell-octeontx2-build-error-unknown-type-name-u64.patch + patches.suse/net-delete-redundant-function-declaration.patch patches.suse/ice-Refactor-ice_aqc_link_topo_addr.patch patches.suse/ice-Implement-functions-for-reading-and-setting-GPIO.patch patches.suse/ice-Add-support-for-SMA-control-multiplexer.patch @@ -5697,6 +5728,7 @@ patches.suse/ice-Add-infrastructure-for-mqprio-support-via-ndo_se.patch patches.suse/ice-enable-ndo_setup_tc-support-for-mqprio_qdisc.patch patches.suse/ice-Add-tc-flower-filter-support-for-channel.patch + patches.suse/net-dsa-introduce-helpers-for-iterating-through-port.patch patches.suse/net-stats-Read-the-statistics-in-___gnet_stats_copy_.patch patches.suse/ice-Nuild-fix.patch patches.suse/mlx5-fix-build-after-merge.patch @@ -5707,12 +5739,17 @@ patches.suse/fddi-defxx-defza-use-dev_addr_set.patch patches.suse/fddi-skfp-constify-and-use-dev_addr_set.patch patches.suse/net-fjes-constify-and-use-eth_hw_addr_set.patch + patches.suse/net-s390-constify-and-use-eth_hw_addr_set patches.suse/net-plip-use-eth_hw_addr_set.patch patches.suse/net-sb1000-rionet-use-eth_hw_addr_set.patch + patches.suse/mac80211-move-CRC-into-struct-ieee802_11_elems.patch + patches.suse/mac80211-mlme-find-auth-challenge-directly.patch + patches.suse/mac80211-always-allocate-struct-ieee802_11_elems.patch patches.suse/cfg80211-always-free-wiphy-specific-regdomain.patch patches.suse/wireless-mac80211_hwsim-use-eth_hw_addr_set.patch patches.suse/mac80211-use-eth_hw_addr_set.patch patches.suse/cfg80211-prepare-for-const-netdev-dev_addr.patch + patches.suse/mac80211-fix-memory-leaks-with-element-parsing.patch patches.suse/b43legacy-fix-a-lower-bounds-test.patch patches.suse/b43-fix-a-lower-bounds-test.patch patches.suse/rtw89-add-Realtek-802.11ax-driver.patch @@ -5798,6 +5835,15 @@ patches.suse/can-bittiming-can_fixup_bittiming-change-type-of-tse.patch patches.suse/net-dsa-avoid-refcount-warnings-when-port_-fdb-mdb-_.patch patches.suse/net-mscc-ocelot-serialize-access-to-the-MAC-table.patch + patches.suse/s390-qeth-improve-trace-entries-for-MAC-address-un-registration + patches.suse/s390-qeth-remove-.do_ioctl-callback-from-driver-discipline + patches.suse/s390-qeth-move-qdio-s-QAOB-cache-into-qeth + patches.suse/s390-qeth-clarify-remaining-dev_kfree_skb_any-users + patches.suse/s390-qeth-don-t-keep-track-of-Input-Queue-count + patches.suse/s390-qeth-fix-various-format-strings + patches.suse/s390-qeth-add-__printf-format-attribute-to-qeth_dbf_longtext + patches.suse/s390-qeth-fix-kernel-doc-comments + patches.suse/s390-qeth-update-kerneldoc-for-qeth_add_hw_header patches.suse/net-hns3-add-debugfs-support-for-interrupt-coalesce.patch patches.suse/net-hns3-modify-mac-statistics-update-process-for-co.patch patches.suse/net-hns3-device-specifications-add-number-of-mac-sta.patch @@ -6219,6 +6265,7 @@ patches.suse/drm-i915-bios-use-ddc-pin-directly-from-child-data.patch patches.suse/drm-i915-bios-get-rid-of-vbt-ddi_port_info.patch patches.suse/drm-i915-s-ddi_translations-trans.patch + patches.suse/0002-drm-i915-hdmi-convert-intel_hdmi_to_dev-to-intel_hdm.patch patches.suse/dma-buf-WARN-on-dmabuf-release-with-pending-attachme.patch patches.suse/drm-panel-orientation-quirks-Update-the-Lenovo-Ideap.patch patches.suse/drm-panel-orientation-quirks-Add-quirk-for-KD-Kurio-.patch @@ -6360,10 +6407,18 @@ patches.suse/ALSA-oxfw-fix-functional-regression-for-Mackie-Onyx-.patch patches.suse/ALSA-usb-audio-Add-registration-quirk-for-JBL-Quantu-763d92ed5dec.patch patches.suse/ALSA-usb-audio-Line6-HX-Stomp-XL-USB_ID-for-48k-fixe.patch + patches.suse/ASoC-cs42l42-Don-t-reconfigure-the-PLL-while-it-is-r.patch patches.suse/ASoC-cs42l42-Always-configure-both-ASP-TX-channels.patch patches.suse/ASoC-cs42l42-Correct-some-register-default-values.patch patches.suse/ASoC-cs42l42-Don-t-set-defaults-for-volatile-registe.patch patches.suse/ASoC-cs42l42-Defer-probe-if-request_threaded_irq-ret.patch + patches.suse/ASoC-cs42l42-Don-t-claim-to-support-192k.patch + patches.suse/ASoC-cs42l42-Use-PLL-for-SCLK-12.288MHz.patch + patches.suse/ASoC-cs42l42-Allow-time-for-HP-ADC-to-power-up-after.patch + patches.suse/ASoC-cs42l42-Set-correct-SRC-MCLK.patch + patches.suse/ASoC-cs42l42-Mark-OSC_SWITCH_STATUS-register-volatil.patch + patches.suse/ASoC-cs42l42-Fix-WARN-in-remove-if-running-without-a.patch + patches.suse/ASoC-cs42l42-Always-enable-TS_PLUG-and-TS_UNPLUG-int.patch patches.suse/ASoC-rockchip-Use-generic-dmaengine-code.patch patches.suse/ASoC-meson-t9015-Add-missing-AVDD-supply-property.patch patches.suse/ASoC-mediatek-mt8195-Remove-unsued-irqs_lock.patch @@ -6372,6 +6427,18 @@ patches.suse/ASoC-Add-json-schema-documentation-for-sound-name-pr.patch patches.suse/ASoC-Use-schema-reference-for-sound-name-prefix.patch patches.suse/ASoC-Remove-name-prefix.txt.patch + patches.suse/ASoC-cs35l41-CS35L41-Boosted-Smart-Amplifier.patch + patches.suse/ASoC-cs35l41-Add-bindings-for-CS35L41.patch + patches.suse/ASoC-cs35l41-Fix-use-of-an-uninitialised-variable.patch + patches.suse/ASoC-cs35l41-Use-regmap_read_poll_timeout-to-wait-fo.patch + patches.suse/ASoC-cs35l41-Combine-adjacent-register-writes.patch + patches.suse/ASoC-cs35l41-Don-t-overwrite-returned-error-code.patch + patches.suse/ASoC-cs35l41-Fixup-the-error-messages.patch + patches.suse/ASoC-cs35l41-Fix-a-bunch-of-trivial-code-formating-s.patch + patches.suse/ASoC-cs42l42-Minor-fix-all-errors-reported-by-checkp.patch + patches.suse/misc-cs35l41-Remove-unused-pdn-variable.patch + patches.suse/ASoC-cs35l41-Binding-fixes.patch + patches.suse/ASoC-cs42l42-Implement-Manual-Type-detection-as-fall.patch patches.suse/ASoC-soc-pcm-Don-t-reconnect-an-already-active-BE.patch patches.suse/ASoC-simple-card-utils-Increase-maximum-DAI-links-li.patch patches.suse/ASoC-audio-graph-Fixup-CPU-endpoint-hw_params-in-a-B.patch @@ -6384,6 +6451,24 @@ patches.suse/ASoC-tegra-Add-Tegra210-based-Mixer-driver.patch patches.suse/ASoC-Fix-warning-related-to-sound-name-prefix-bindin.patch patches.suse/ASoC-wcd9335-Use-correct-version-to-initialize-Class.patch + patches.suse/ASoC-cs42l42-Use-two-thresholds-and-increased-wait-t.patch + patches.suse/ASoC-wm_adsp-Remove-use-of-snd_ctl_elem_type_t.patch + patches.suse/ASoC-wm_adsp-Move-check-for-control-existence.patch + patches.suse/ASoC-wm_adsp-Switch-to-using-wm_coeff_read_ctrl-for-.patch + patches.suse/ASoC-wm_adsp-Cancel-ongoing-work-when-removing-contr.patch + patches.suse/ASoC-wm_adsp-Rename-generic-DSP-support.patch + patches.suse/ASoC-wm_adsp-Introduce-cs_dsp-logging-macros.patch + patches.suse/ASoC-wm_adsp-Separate-some-ASoC-and-generic-function.patch + patches.suse/ASoC-wm_adsp-Split-DSP-power-operations-into-helper-.patch + patches.suse/ASoC-wm_adsp-Move-sys_config_size-to-wm_adsp.patch + patches.suse/ASoC-wm_adsp-Separate-generic-cs_dsp_coeff_ctl-handl.patch + patches.suse/ASoC-wm_adsp-Move-check-of-dsp-running-to-better-pla.patch + patches.suse/ASoC-wm_adsp-Pass-firmware-names-as-parameters-when-.patch + patches.suse/ASoC-wm_adsp-move-firmware-loading-to-client.patch + patches.suse/ASoC-wm_adsp-Split-out-struct-cs_dsp-from-struct-wm_.patch + patches.suse/ASoC-wm_adsp-Separate-wm_adsp-specifics-in-cs_dsp_cl.patch + patches.suse/firmware-cs_dsp-add-driver-to-support-firmware-loadi.patch + patches.suse/ASoC-wm_adsp-remove-a-repeated-including.patch patches.suse/ASoC-rt5682-move-clk-related-code-to-rt5682_i2c_prob.patch patches.suse/ASoC-fsl_spdif-implement-bypass-mode-from-in-to-out.patch patches.suse/ASoC-es8316-Use-IRQF_NO_AUTOEN-when-requesting-the-I.patch @@ -6395,9 +6480,14 @@ patches.suse/ASoC-SOF-topology-do-not-power-down-primary-core-dur.patch patches.suse/ASoC-soc-pcm-restore-mixer-functionality.patch patches.suse/ASoC-rt5682-fix-a-little-pop-while-playback.patch + patches.suse/ASoC-cs42l42-Remove-unused-runtime_suspend-runtime_r.patch patches.suse/ASoC-tegra-Restore-AC97-support.patch patches.suse/ASoC-tegra-Set-default-card-name-for-Trimslice.patch + patches.suse/ASoC-cs35l41-Make-cs35l41_remove-return-void.patch + patches.suse/ASoC-cs42l42-Prevent-NULL-pointer-deref-in-interrupt.patch patches.suse/ASoC-topology-Fix-stub-for-snd_soc_tplg_component_re.patch + patches.suse/ASoC-cs42l42-Reset-and-power-down-on-remove-and-fail.patch + patches.suse/ASoC-cs42l42-free_irq-before-powering-down-on-probe-.patch patches.suse/ASoC-dt-bindings-cs42l42-Correct-description-of-ts-i.patch patches.suse/ASoC-cs42l42-Correct-configuring-of-switch-inversion.patch patches.suse/ASoC-rsnd-Fix-an-error-handling-path-in-rsnd_node_co.patch @@ -6607,6 +6697,7 @@ patches.suse/soc-qcom-llcc-Disable-MMUHWT-retention.patch patches.suse/soc-qcom-aoss-Expose-send-for-generic-usecase.patch patches.suse/Revert-soc-imx-gpcv2-move-reset-assert-after-request.patch + patches.suse/soc-sunxi_sram-Make-use-of-the-helper-function-devm_.patch patches.suse/tee-add-sec_world_id-to-struct-tee_shm.patch patches.suse/optee-simplify-optee_release.patch patches.suse/optee-refactor-driver-with-internal-callbacks.patch @@ -6646,6 +6737,7 @@ patches.suse/usb-typec-tipd-Add-an-additional-overflow-check.patch patches.suse/usb-typec-tipd-Remove-WARN_ON-in-tps6598x_block_read.patch patches.suse/usb-core-hcd-fix-messages-in-usb_hcd_request_irqs.patch + patches.suse/usb-dwc3-gadget-Avoid-starting-DWC3-gadget-during-UD.patch patches.suse/usb-typec-tcpci-Fix-spelling-mistake-resolbed-resolv.patch patches.suse/usb-typec-ucsi-Always-cancel-the-command-if-PPM-repo.patch patches.suse/usb-typec-ucsi-Don-t-stop-alt-mode-registration-on-b.patch @@ -6659,6 +6751,7 @@ patches.suse/usb-typec-tipd-Add-support-for-Apple-CD321X.patch patches.suse/usb-typec-tipd-Switch-CD321X-power-state-to-S0.patch patches.suse/usb-typec-tipd-Remove-FIXME-about-testing-with-I2C_F.patch + patches.suse/usb-ehci-Fix-a-function-name-in-comments.patch patches.suse/usb-phy-tegra-Support-OTG-mode-programming.patch patches.suse/usb-xhci-mtk-use-xhci_dbg-to-print-log.patch patches.suse/usb-gadget-uvc-fix-multiple-opens.patch @@ -6708,6 +6801,7 @@ patches.suse/staging-rtl8192u-fix-control-message-timeouts.patch patches.suse/staging-r8712u-fix-control-message-timeout.patch patches.suse/pvpanic-Fix-typos-in-the-comments.patch + patches.suse/habanalabs-select-CRC32.patch patches.suse/binder-don-t-detect-sender-target-during-buffer-clea.patch patches.suse/char-xillybus-fix-msg_ep-UAF-in-xillyusb_probe.patch patches.suse/dt-bindings-iio-accel-Add-DT-binding-doc-for-ADXL355.patch @@ -7072,6 +7166,7 @@ patches.suse/i2c-mediatek-fixing-the-incorrect-register-offset.patch patches.suse/i2c-tegra-Ensure-that-device-is-suspended-before-dri.patch patches.suse/i2c-xlr-Fix-a-resource-leak-in-the-error-handling-pa.patch + patches.suse/i2c-i801-Add-support-for-Intel-Ice-Lake-PCH-N.patch patches.suse/cxl-pci-Fix-NULL-vs-ERR_PTR-confusion.patch patches.suse/gpio-tegra186-Force-one-interrupt-per-bank.patch patches.suse/gpio-tegra186-Support-multiple-interrupts-per-bank.patch @@ -7186,6 +7281,8 @@ patches.suse/NFS-Fix-deadlocks-in-nfs_scan_commit_list.patch patches.suse/NFS-Fix-up-commit-deadlocks.patch patches.suse/NFS-Fix-an-Oops-in-pnfs_mark_request_commit.patch + patches.suse/NFSv4-Fixes-for-nfs4_inode_return_delegation.patch + patches.suse/NFS-Fix-WARN_ON-due-to-unionization-of-nfs_inode.nre.patch patches.suse/Fix-user-namespace-leak.patch patches.suse/NFSv4-Fix-a-regression-in-nfs_set_open_stateid_locke.patch patches.suse/SUNRPC-Check-if-the-xprt-is-connected-before-handlin.patch @@ -7433,6 +7530,7 @@ patches.suse/0001-KVM-SEV-Fix-typo-in-and-tweak-name-of-cmd_allowed_fr.patch patches.suse/selftests-KVM-Add-x86_64-sev_migrate_tests-to-.gitig.patch patches.suse/KVM-x86-Assume-a-64-bit-hypercall-for-guests-with-pr.patch + patches.suse/0001-parisc-sticon-fix-reverse-colors.patch patches.suse/fs-handle-circular-mappings-correctly.patch patches.suse/udf-Fix-crash-after-seekdir.patch patches.suse/btrfs-fix-memory-ordering-between-normal-and-ordered-work-functions.patch @@ -7565,10 +7663,12 @@ patches.suse/media-cec-copy-sequence-field-for-the-reply.patch patches.suse/ALSA-hda-realtek-Add-quirk-for-ASRock-NUC-Box-1100.patch patches.suse/ALSA-hda-realtek-Fix-LED-on-HP-ProBook-435-G7.patch + patches.suse/ASoC-cs35l41-Change-monitor-widgets-to-siggens.patch patches.suse/ASoC-SOF-Intel-hda-fix-hotplug-when-only-codec-is-su.patch patches.suse/ASoC-DAPM-Cover-regression-by-kctl-change-notificati.patch patches.suse/ASoC-rt5682-Avoid-the-unexpected-IRQ-event-during-go.patch patches.suse/ASoC-rt5682-Re-detect-the-combo-jack-after-resuming.patch + patches.suse/ASoC-wm_adsp-wm_adsp_control_add-error-uninitialized.patch patches.suse/ASoC-qdsp6-q6routing-Conditionally-reset-FrontEnd-Mi.patch patches.suse/ASoC-qdsp6-q6asm-fix-q6asm_dai_prepare-error-handlin.patch patches.suse/ASoC-topology-Add-missing-rwsem-around-snd_ctl_remov.patch @@ -7606,6 +7706,8 @@ patches.suse/nvme-fabrics-ignore-invalid-fast_io_fail_tmo-values.patch patches.suse/drm-amd-display-Fix-DPIA-outbox-timeout-after-GPU-re.patch patches.suse/drm-amd-display-Set-plane-update-flags-for-all-plane.patch + patches.suse/0005-drm-amdgpu-gfx10-add-wraparound-gpu-counter-check-fo.patch + patches.suse/0001-drm-amdgpu-gfx9-switch-to-golden-tsc-registers-for-r.patch patches.suse/drm-amdgpu-IH-process-reset-count-when-restart.patch patches.suse/drm-nouveau-recognise-GA106.patch patches.suse/drm-nouveau-acr-fix-a-couple-NULL-vs-IS_ERR-checks.patch @@ -7666,6 +7768,7 @@ patches.suse/r8169-fix-incorrect-mac-address-assignment.patch patches.suse/net-chelsio-cxgb4vf-Fix-an-error-code-in-cxgb4vf_pci.patch patches.suse/net-usb-Correct-PHY-handling-of-smsc95xx.patch + patches.suse/net-ipa-kill-ipa_cmd_pipeline_clear.patch patches.suse/net-marvell-mvpp2-increase-MTU-limit-when-XDP-enable.patch patches.suse/tools-sync-uapi-linux-if_link.h-header.patch patches.suse/lan743x-fix-deadlock-in-lan743x_phy_link_status_chan.patch @@ -7727,6 +7830,7 @@ patches.suse/KVM-nVMX-Abide-to-KVM_REQ_TLB_FLUSH_GUEST-request-on.patch patches.suse/KVM-nVMX-Emulate-guest-TLB-flush-on-nested-VM-Enter-.patch patches.suse/KVM-selftests-Make-sure-kvm_create_max_vcpus-test-wo.patch + patches.suse/KVM-X86-Fix-when-shadow_root_level-5-guest-root_leve.patch patches.suse/KVM-X86-Use-vcpu-arch.walk_mmu-for-kvm_mmu_invlpg.patch patches.suse/KVM-x86-mmu-Use-yield-safe-TDP-MMU-root-iter-in-MMU-.patch patches.suse/KVM-x86-mmu-Remove-spurious-TLB-flushes-in-TDP-MMU-z.patch @@ -7759,6 +7863,7 @@ patches.suse/ASoC-tegra-Fix-kcontrol-put-callback-in-ADX.patch patches.suse/ASoC-tegra-Fix-kcontrol-put-callback-in-Mixer.patch patches.suse/ASoC-rk817-Add-module-alias-for-rk817-codec.patch + patches.suse/ASoC-cs35l41-Set-the-max-SPI-speed-for-the-whole-dev.patch patches.suse/ALSA-hda-cs8409-Set-PMSG_ON-earlier-inside-cs8409-dr.patch patches.suse/ALSA-hda-Add-Intel-DG2-PCI-ID-and-HDMI-codec-vid.patch patches.suse/ALSA-hda-hdmi-fix-HDA-codec-entry-table-order-for-AD.patch @@ -7860,6 +7965,7 @@ patches.suse/arm64-ftrace-add-missing-BTIs.patch patches.suse/s390-pci-move-pseudo-MMIO-to-prevent-MIO-overlap patches.suse/scsi-lpfc-Fix-non-recovery-of-remote-ports-following.patch + patches.suse/scsi-ufs-ufs-pci-Add-support-for-Intel-ADL.patch patches.suse/loop-Use-pr_warn_once-for-loop_control_remove-warnin.patch patches.suse/cifs-fix-missed-refcounting-of-ipc-tcon.patch patches.suse/cifs-wait-for-tcon-resource_id-before-getting-fscache-super.patch @@ -8363,7 +8469,9 @@ patches.suse/drm-amd-display-Added-power-down-for-DCN10.patch patches.suse/drm-amd-display-Send-s0i2_rdy-in-stream_count-0-opti.patch patches.suse/drm-amd-display-Set-optimize_pwr_state-for-DCN31.patch + patches.suse/0002-drm-amd-display-Changed-pipe-split-policy-to-allow-f.patch patches.suse/drm-amdgpu-fix-dropped-backing-store-handling-in-amd.patch + patches.suse/0003-drm-nouveau-wait-for-the-exclusive-fence-after-the-s.patch patches.suse/scsi-lpfc-Terminate-string-in-lpfc_debugfs_nvmeio_trc_write patches.suse/scsi-vmw_pvscsi-Set-residual-data-length-conditionally patches.suse/userfaultfd-selftests-fix-hugetlb-area-allocations.patch @@ -8392,6 +8500,7 @@ patches.suse/ieee802154-atusb-fix-uninit-value-in-atusb_set_exten.patch patches.suse/Revert-net-usb-r8152-Add-MAC-passthrough-support-for.patch patches.suse/tracing-Fix-check-for-trace_percpu_buffer-validity-in-get_trace_buf.patch + patches.suse/tracing-Tag-trace_percpu_buffer-as-a-percpu-pointer.patch patches.suse/RDMA-rxe-Prevent-double-freeing-rxe_map_set.patch patches.suse/Revert-RDMA-mlx5-Fix-releasing-unallocated-memory-in.patch patches.suse/RDMA-uverbs-Check-for-null-return-of-kmalloc_array.patch @@ -8464,6 +8573,15 @@ patches.suse/arm64-cpufeature-add-HWCAP-for-FEAT_AFP.patch patches.suse/arm64-add-ID_AA64ISAR2_EL1-sys-register.patch patches.suse/arm64-cpufeature-add-HWCAP-for-FEAT_RPRES.patch + patches.suse/s390-qdio-remove-QDIO_SBAL_SIZE-macro + patches.suse/s390-qdio-improve-handling-of-CIWs + patches.suse/s390-qdio-avoid-allocating-the-qdio_irq-with-GFP_DMA + patches.suse/s390-qdio-clean-up-access-to-queue-in-qdio_handle_activate_check + patches.suse/s390-qdio-clarify-handler-logic-for-qdio_handle_activate_check + patches.suse/s390-qdio-split-qdio_inspect_queue + patches.suse/s390-qdio-split-do_QDIO + patches.suse/s390-qdio-remove-unneeded-sanity-check-in-qdio_do_sqbs + patches.suse/s390-qdio-clarify-logical-vs-absolute-in-QIB-s-kerneldoc patches.suse/s390-mm-fix-2KB-pgtable-release-race.patch patches.suse/x86-sev-shorten-ghcb-terminate-macro-names patches.suse/x86-sev-get-rid-of-excessive-use-of-defines @@ -8514,6 +8632,7 @@ patches.suse/drm-lima-fix-warning-when-CONFIG_DEBUG_SG-y-CONFIG_D.patch patches.suse/drm-ttm-Put-BO-in-its-memory-manager-s-lru-list.patch patches.suse/drm-bridge-dw-hdmi-handle-ELD-when-DRM_BRIDGE_ATTACH.patch + patches.suse/drm-bridge-display-connector-implement-bus-fmts-call.patch patches.suse/drm-meson-split-out-encoder-from-meson_dw_hdmi.patch patches.suse/drm-nouveau-pmu-gm200-avoid-touching-PMU-outside-of-.patch patches.suse/drm-nouveau-pmu-gm200-use-alternate-falcon-reset-seq.patch @@ -8560,6 +8679,7 @@ patches.suse/drm-msm-dp-displayPort-driver-need-algorithm-rationa.patch patches.suse/drm-msm-dp-dp_link_parse_sink_count-return-immediate.patch patches.suse/drm-msm-dpu-fix-safe-status-debugfs-file.patch + patches.suse/drm-amdgpu-Separate-vf2pf-work-item-init-from-virt-d.patch patches.suse/drm-amdgpu-fixup-bad-vram-size-on-gmc-v8.patch patches.suse/amdgpu-pm-Make-sysfs-pm-attributes-as-read-only-for-.patch patches.suse/drm-amd-display-Fix-the-uninitialized-variable-in-en.patch @@ -8694,6 +8814,10 @@ patches.suse/amd-ni65-use-eth_hw_addr_set.patch patches.suse/amd-a2065-ariadne-use-eth_hw_addr_set.patch patches.suse/smc9194-use-eth_hw_addr_set.patch + patches.suse/s390-qeth-allocate-RX-queue-at-probe-time + patches.suse/s390-ctcm-fix-format-string + patches.suse/s390-ctcm-add-__printf-format-attribute-to-ctcm_dbf_longtext + patches.suse/s390-lcs-add-braces-around-empty-function-body patches.suse/cxgb4-Use-struct_group-for-memcpy-region.patch patches.suse/bnx2x-Use-struct_group-for-memcpy-region.patch patches.suse/bnx2x-constify-static-inline-stub-for-dev_addr.patch @@ -8785,6 +8909,11 @@ patches.suse/rsi-Fix-out-of-bounds-read-in-rsi_read_pkt.patch patches.suse/libertas_tf-Use-struct_group-for-memcpy-region.patch patches.suse/msft-hv-2488-hv_sock-Extract-hvs_send_data-helper-that-takes-only.patch + patches.suse/s390-qeth-split-up-L2-netdev_ops + patches.suse/s390-qeth-don-t-offer-.ndo_bridge_-ops-for-OSA-devices + patches.suse/s390-qeth-fine-tune-.ndo_select_queue + patches.suse/s390-qeth-remove-check-for-packing-mode-in-qeth_check_outbound_queue + patches.suse/net-huawei-hinic-Use-devm_kcalloc-instead-of-devm_kz.patch patches.suse/net-phy-prefer-1000baseT-over-1000baseKX.patch patches.suse/xfrm-add-net-device-refcount-tracker-to-struct-xfrm_.patch patches.suse/bpf-Adjust-BTF-log-size-limit.patch @@ -9154,6 +9283,7 @@ patches.suse/bnxt_en-use-firmware-provided-max-timeout-for-messag.patch patches.suse/bnxt_en-improve-firmware-timeout-messaging.patch patches.suse/net-mlx5e-Fix-build-error-in-fec_set_block_stats.patch + patches.suse/qlcnic-Simplify-DMA-setting.patch patches.suse/bna-Simplify-DMA-setting.patch patches.suse/vmxnet3-Remove-useless-DMA-32-fallback-configuration.patch patches.suse/be2net-Remove-useless-DMA-32-fallback-configuration.patch @@ -9247,11 +9377,13 @@ patches.suse/ACPI-thermal-drop-an-always-true-check.patch patches.suse/ACPI-battery-Add-the-ThinkPad-Not-Charging-quirk.patch patches.suse/cpufreq-intel_pstate-Update-EPP-for-AlderLake-mobile.patch + patches.suse/x86-cpufeatures-Add-AMD-Collaborative-Processor-Perf.patch patches.suse/ACPI-CPPC-Implement-support-for-SystemIO-registers.patch patches.suse/ACPI-CPPC-Check-present-CPUs-for-determining-_CPC-is.patch patches.suse/ACPI-CPPC-Add-CPPC-enable-register-function.patch patches.suse/PM-runtime-Add-safety-net-to-supplier-device-release.patch patches.suse/PM-hibernate-Allow-ACPI-hardware-signature-to-be-hon.patch + patches.suse/powercap-intel_rapl-support-new-layout-of-Psys-PowerLimit-Register-on-SPR.patch patches.suse/thermal-drivers-imx-Implement-runtime-PM-support.patch patches.suse/thermal-drivers-imx8mm-Enable-ADC-when-enabling-moni.patch patches.suse/thermal-drivers-int340x-Fix-RFIM-mailbox-write-comma.patch @@ -9540,6 +9672,7 @@ patches.suse/iommu-io-pgtable-arm-fix-table-descriptor-paddr-formatting patches.suse/iommu-iova-fix-race-between-fq-timeout-and-teardown patches.suse/perf-Protect-perf_guest_cbs-with-RCU.patch + patches.suse/KVM-x86-Register-perf-callbacks-after-calling-vendor.patch patches.suse/KVM-x86-Register-Processor-Trace-interrupt-hook-iff-.patch patches.suse/x86-use-mindirect-branch-cs-prefix-for-retpoline-builds.patch patches.suse/x86-lib-atomic64_386_32-rename-things.patch @@ -9682,9 +9815,31 @@ patches.suse/ALSA-hda-cs8409-Increase-delay-during-jack-detection.patch patches.suse/ALSA-hda-cs8409-Fix-Jack-detection-after-resume.patch patches.suse/ASoC-Intel-sof_sdw-fix-jack-detection-on-HP-Spectre-.patch + patches.suse/ASoC-dt-bindings-cs42l42-Convert-binding-to-yaml.patch + patches.suse/ASoC-cs35l41-DSP-Support.patch + patches.suse/ASoC-cs42l42-Add-control-for-audio-slow-start-switch.patch + patches.suse/firmware-cs_dsp-tidy-includes-in-cs_dsp.c-and-cs_dsp.patch + patches.suse/ASoC-wm_adsp-Remove-the-wmfw_add_ctl-helper-function.patch + patches.suse/firmware-cs_dsp-Add-lockdep-asserts-to-interface-fun.patch + patches.suse/firmware-cs_dsp-Add-version-checks-on-coefficient-lo.patch + patches.suse/firmware-cs_dsp-Add-pre_run-callback.patch + patches.suse/firmware-cs_dsp-Print-messages-from-bin-files.patch + patches.suse/firmware-cs_dsp-Add-support-for-rev-2-coefficient-fi.patch + patches.suse/firmware-cs_dsp-Perform-NULL-check-in-cs_dsp_coeff_w.patch + patches.suse/firmware-cs_dsp-Clarify-some-kernel-doc-comments.patch + patches.suse/firmware-cs_dsp-Add-offset-to-cs_dsp-read-write.patch + patches.suse/firmware-cs_dsp-Allow-creation-of-event-controls.patch + patches.suse/ASoC-cs42l42-Remove-redundant-writes-to-DETECT_MODE.patch + patches.suse/ASoC-cs42l42-Remove-redundant-writes-to-RS_PLUG-RS_U.patch + patches.suse/ASoC-cs42l42-Simplify-reporting-of-jack-unplug.patch + patches.suse/ASoC-cs42l42-Remove-redundant-pll_divout-member.patch + patches.suse/ASoC-cs42l42-Report-initial-jack-state.patch patches.suse/ASoC-uniphier-drop-selecting-non-existing-SND_SOC_UN.patch patches.suse/ASoC-codecs-wcd938x-add-SND_SOC_WCD938_SDW-to-codec-.patch patches.suse/ASoC-imx-hdmi-add-put_device-after-of_find_device_by.patch + patches.suse/ASoC-cs35l41-Fix-link-problem.patch + patches.suse/firmware-cs_dsp-Move-lockdep-asserts-to-avoid-potent.patch + patches.suse/ASoC-cs35l41-Fix-undefined-reference-to-core-functio.patch patches.suse/ASoC-rt5663-Handle-device_property_read_u32_array-er.patch patches.suse/dmaengine-pxa-mmp-stop-referencing-config-slave_id.patch patches.suse/ASoC-Intel-catpt-Test-dmaengine_submit-result-before.patch @@ -9695,15 +9850,35 @@ patches.suse/ASoC-mediatek-mt8183-fix-device_node-leak.patch patches.suse/ASoC-mediatek-use-of_device_get_match_data.patch patches.suse/ASoC-samsung-idma-Check-of-ioremap-return-value.patch + patches.suse/ASoC-cs35l41-Convert-tables-to-shared-source-code.patch + patches.suse/ASoC-cs35l41-Move-cs35l41_otp_unpack-to-shared-code.patch + patches.suse/ASoC-cs35l41-Move-power-initializations-to-reg_seque.patch + patches.suse/ASoC-cs35l41-Create-shared-function-for-errata-patch.patch + patches.suse/ASoC-cs35l41-Create-shared-function-for-setting-chan.patch + patches.suse/ASoC-cs35l41-Create-shared-function-for-boost-config.patch patches.suse/ASoC-fsl_mqs-fix-MODULE_ALIAS.patch patches.suse/ALSA-hda-realtek-Add-quirk-for-Legion-Y9000X-2020.patch patches.suse/ALSA-hda-realtek-Re-order-quirk-entries-for-Lenovo.patch + patches.suse/ALSA-hda-cs35l41-Add-support-for-CS35L41-in-HDA-syst.patch + patches.suse/ALSA-hda-realtek-Add-support-for-Legion-7-16ACHg6-la.patch + patches.suse/ALSA-hda-realtek-Add-CS35L41-support-for-Thinkpad-la.patch patches.suse/ALSA-hda-ALC287-Add-Lenovo-IdeaPad-Slim-9i-14ITL5-sp.patch patches.suse/ALSA-seq-virmidi-Add-a-drain-operation.patch + patches.suse/ALSA-hda-Fix-dependency-on-ASoC-cs35l41-codec.patch + patches.suse/ALSA-hda-Fix-dependencies-of-CS35L41-on-SPI-I2C-buse.patch + patches.suse/ASoC-cs35l41-Add-cs35l51-53-IDs.patch + patches.suse/ASoC-cs35l41-Remove-incorrect-comment.patch + patches.suse/ASoC-cs35l41-Correct-DSP-power-down.patch + patches.suse/ASoC-cs35l41-Correct-handling-of-some-registers-in-t.patch + patches.suse/firmware-cs_dsp-Clear-core-reset-for-cache.patch + patches.suse/ASoC-wm_adsp-Add-support-for-toggle-preloaders.patch patches.suse/ASoC-fsl_asrc-refine-the-check-of-available-clock-di.patch patches.suse/ASoC-imx-card-Need-special-setting-for-ak4497-on-i.M.patch patches.suse/ASoC-imx-card-Fix-mclk-calculation-issue-for-akcodec.patch patches.suse/ASoC-imx-card-improve-the-sound-quality-for-low-rate.patch + patches.suse/ASoC-cs35l41-Update-handling-of-test-key-registers.patch + patches.suse/ASoC-cs35l41-Add-support-for-hibernate-memory-retent.patch + patches.suse/ALSA-hda-cs35l41-fix-double-free-on-error-in-probe.patch patches.suse/powerpc-powernv-Remove-POWER9-PVR-version-check-for-.patch patches.suse/powerpc-xive-Introduce-an-helper-to-print-out-interr.patch patches.suse/powerpc-xive-Introduce-xive_core_debugfs_create.patch @@ -9750,6 +9925,7 @@ patches.suse/mei-hbm-fix-client-dma-reply-status.patch patches.suse/i2c-tegra-Add-the-ACPI-support.patch patches.suse/i2c-i801-Don-t-silently-correct-invalid-transfer-siz.patch + patches.suse/i2c-i801-Improve-handling-of-chip-specific-feature-d.patch patches.suse/i2c-mpc-Correct-I2C-reset-procedure.patch patches.suse/i2c-tegra-use-i2c_timings-for-bus-clock-freq.patch patches.suse/i2c-designware-pci-Fix-to-change-data-types-of-hcnt-.patch @@ -9886,6 +10062,7 @@ patches.suse/cifs-Fix-smb311_update_preauth_hash-kernel-doc-comment.patch patches.suse/cifs-move-superblock-magic-defitions-to-magic-h.patch patches.suse/cifs-fix-FILE_BOTH_DIRECTORY_INFO-definition.patch + patches.suse/tools-headers-cpufeatures-Sync-with-the-kernel-sourc.patch patches.suse/ACPI-scan-Change-acpi_scan_init-return-value-type-to.patch patches.suse/ACPI-scan-Simplify-initialization-of-power-and-sleep.patch patches.suse/ACPI-scan-Rename-label-in-acpi_scan_init.patch @@ -10002,6 +10179,7 @@ patches.suse/clk-si5341-Fix-clock-HW-provider-cleanup.patch patches.suse/drm-i915-display-ehl-Update-voltage-swing-table.patch patches.suse/drm-amdgpu-don-t-do-resets-on-APUs-which-don-t-suppo.patch + patches.suse/drm-amd-amdgpu-fixing-read-wrong-pf2vf-data-in-SRIOV.patch patches.suse/drm-radeon-fix-error-handling-in-radeon_driver_open_.patch patches.suse/rtc-cmos-take-rtc_lock-while-reading-from-CMOS.patch patches.suse/rtc-ftrtc010-Use-platform_get_irq-to-get-the-interru.patch @@ -10009,6 +10187,13 @@ patches.suse/ALSA-hda-realtek-fix-speakers-and-micmute-on-HP-855-.patch patches.suse/ALSA-usb-audio-add-mapping-for-MSI-MPG-X570S-Carbon-.patch patches.suse/ALSA-core-Fix-SSID-quirk-lookup-for-subvendor-0.patch + patches.suse/ALSA-hda-cs35l41-Avoid-overwriting-register-patch.patch + patches.suse/ALSA-hda-cs35l41-Add-calls-to-newly-added-test-key-f.patch + patches.suse/ALSA-hda-cs35l41-Move-cs35l41-calls-to-its-own-symbo.patch + patches.suse/ALSA-hda-cs35l41-Add-missing-default-cases.patch + patches.suse/ALSA-hda-cs35l41-Make-use-of-the-helper-function-dev.patch + patches.suse/ALSA-hda-cs35l41-Tidyup-code.patch + patches.suse/ALSA-hda-cs35l41-Make-cs35l41_hda_remove-return-void.patch patches.suse/ALSA-core-Simplify-snd_power_ref_and_wait-with-the-s.patch patches.suse/ALSA-hda-cs8409-Add-new-Warlock-SKUs-to-patch_cs8409.patch patches.suse/blk-mq-fix-tag_get-wait-task-can-t-be-awakened.patch @@ -10135,6 +10320,7 @@ patches.suse/drm-msm-a6xx-Add-missing-suspend_count-increment.patch patches.suse/drm-msm-dsi-invalid-parameter-check-in-msm_dsi_phy_e.patch patches.suse/drm-etnaviv-relax-submit-size-limits.patch + patches.suse/drm-amd-display-Correct-MPC-split-policy-for-DCN301.patch patches.suse/drm-amd-display-dc-calcs-dce_calcs-Fix-a-memleak-in-.patch patches.suse/drm-amd-display-Fix-FP-start-end-for-dcn30_internal_.patch patches.suse/hwmon-lm90-Reduce-maximum-conversion-rate-for-G781.patch @@ -10170,6 +10356,7 @@ patches.suse/ucount-Make-get_ucount-a-safe-get_user-replacement.patch patches.suse/tracing-histogram-Fix-a-potential-memory-leak-for-kstrdup.patch patches.suse/tracing-Fix-smatch-warning-for-null-glob-in-event_hist_trigger_parse.patch + patches.suse/tracing-Fix-smatch-warning-for-do-while-check-in-eve.patch patches.suse/tracing-Propagate-is_signed-to-expression.patch patches.suse/tracing-Don-t-inc-err_log-entry-count-if-entry-allocation-fails.patch patches.suse/PM-wakeup-simplify-the-output-logic-of-pm_show_wakel.patch @@ -10304,6 +10491,7 @@ patches.suse/drm-nouveau-fix-off-by-one-in-BIOS-boundary-checking.patch patches.suse/dma-buf-heaps-Fix-potential-spectre-v1-gadget.patch patches.suse/0001-Revert-fbcon-Disable-accelerated-scrolling.patch + patches.suse/0002-fbcon-Add-option-to-enable-legacy-hardware-accelerat.patch patches.suse/drm-i915-overlay-Prevent-divide-by-zero-bugs-in-scal.patch patches.suse/drm-i915-adlp-Fix-TypeC-PHY-ready-status-readout.patch patches.suse/ALSA-hda-Fix-UAF-of-leds-class-devs-at-unbinding.patch @@ -10384,6 +10572,7 @@ patches.suse/NFSD-Fix-ia_size-underflow.patch patches.suse/NFSD-Fix-NFSv3-SETATTR-CREATE-s-handling-of-large-fi.patch patches.suse/NFSD-Clamp-WRITE-offsets.patch + patches.suse/NFSD-Fix-offset-type-in-I-O-trace-points.patch patches.suse/tipc-improve-size-validations-for-received-domain-re.patch patches.suse/selftests-fixup-build-warnings-in-pidfd-clone3-tests.patch patches.suse/net-sparx5-Fix-get_stat64-crash-in-tcpdump.patch @@ -10595,6 +10784,7 @@ patches.suse/ASoC-rt5668-do-not-block-workqueue-if-card-is-unboun.patch patches.suse/ASoC-rt5682-do-not-block-workqueue-if-card-is-unboun.patch patches.suse/ASoC-qcom-Actually-clear-DMA-interrupt-register-for-.patch + patches.suse/ASoC-wm_adsp-Correct-control-read-size-when-parsing-.patch patches.suse/ALSA-hda-Set-max-DMA-segment-size.patch patches.suse/ASoC-SOF-hda-Set-max-DMA-segment-size.patch patches.suse/ASoC-intel-skylake-Set-max-DMA-segment-size.patch @@ -10610,6 +10800,7 @@ patches.suse/ACPI-tables-Quiet-ACPI-table-not-found-warning.patch patches.suse/ACPI-processor-idle-fix-lockup-regression-on-32-bit-.patch patches.suse/NFS-Remove-an-incorrect-revalidation-in-nfs4_update_.patch + patches.suse/NFS-LOOKUP_DIRECTORY-is-also-ok-with-symlinks.patch patches.suse/NFS-Do-not-report-writeback-errors-in-nfs_getattr.patch patches.suse/ucounts-Enforce-RLIMIT_NPROC-not-RLIMIT_NPROC-1.patch patches.suse/ucounts-Base-set_cred_ucounts-changes-on-the-real-us.patch @@ -11141,6 +11332,7 @@ patches.suse/PM-domains-Fix-sleep-in-atomic-bug-caused-by-genpd_d.patch patches.suse/thermal-int340x-Check-for-NULL-after-calling-kmemdup.patch patches.suse/thermal-int340x-Increase-bitmap-size.patch + patches.suse/thermal-int340x-Update-OS-policy-capability-handshak.patch patches.suse/random-remove-useless-header-comment.patch patches.suse/hwrng-cavium-HW_RANDOM_CAVIUM-should-depend-on-ARCH_.patch patches.suse/crypto-sun8i-ss-really-disable-hash-on-A80.patch @@ -11200,8 +11392,12 @@ patches.suse/hwmon-pmbus-Add-Vin-unit-off-handling.patch patches.suse/regulator-qcom_smd-fix-for_each_child.cocci-warnings.patch patches.suse/regulator-rpi-panel-Handle-I2C-errors-timing-to-the-.patch + patches.suse/spi-Create-helper-API-to-lookup-ACPI-info-for-spi-de.patch + patches.suse/spi-Support-selection-of-the-index-of-the-ACPI-Spi-R.patch + patches.suse/spi-Add-API-to-count-spi-acpi-resources.patch patches.suse/spi-tegra114-Add-missing-IRQ-check-in-tegra_spi_prob.patch patches.suse/spi-tegra210-quad-Fix-missin-IRQ-check-in-tegra_qspi.patch + patches.suse/spi-pxa2xx-Add-support-for-Intel-Raptor-Lake-PCH-S.patch patches.suse/spi-rockchip-Stop-spi-slave-dma-receiver-when-cs-ina.patch patches.suse/spi-rockchip-Preset-cs-high-and-clk-polarity-in-setu.patch patches.suse/spi-pxa2xx-pci-Balance-reference-count-for-PCI-DMA-d.patch @@ -11377,6 +11573,9 @@ patches.suse/ASoC-codecs-wcd934x-fix-kcontrol-max-values.patch patches.suse/ASoC-codecs-wcd934x-fix-return-value-of-wcd934x_rx_h.patch patches.suse/ASoC-SOF-Intel-Fix-NULL-ptr-dereference-when-ENOMEM.patch + patches.suse/ASoC-cs35l41-Fix-GPIO2-configuration.patch + patches.suse/ASoC-cs35l41-Fix-max-number-of-TX-channels.patch + patches.suse/ASoC-cs35l41-Fix-DSP-mbox-start-command-and-global-e.patch patches.suse/ALSA-hda-realtek-Fix-headset-mic-problem-for-a-HP-ma.patch patches.suse/ALSA-usb-audio-Add-mute-TLV-for-playback-volumes-on-.patch patches.suse/ALSA-hda-realtek-Add-quirk-for-ASUS-GA402.patch @@ -11384,16 +11583,29 @@ patches.suse/ALSA-oss-Fix-PCM-OSS-buffer-allocation-overflow.patch patches.suse/ALSA-hda-Fix-driver-index-handling-at-re-binding.patch patches.suse/ALSA-hda-Add-PCI-and-HDMI-IDs-for-Intel-Raptor-Lake.patch + patches.suse/platform-x86-i2c-multi-instantiate-Rename-it-for-a-g.patch + patches.suse/platform-x86-serial-multi-instantiate-Reorganize-I2C.patch + patches.suse/platform-x86-serial-multi-instantiate-Add-SPI-suppor.patch + patches.suse/ALSA-hda-realtek-Add-support-for-HP-Laptops.patch + patches.suse/ACPI-scan-Create-platform-device-for-CS35L41.patch + patches.suse/ALSA-hda-tegra-Add-Tegra234-hda-driver-support.patch + patches.suse/ALSA-hda-tegra-Update-scratch-reg.-communication.patch patches.suse/ALSA-spi-Add-check-for-clk_enable.patch patches.suse/ALSA-hda-Add-AlderLake-PS-variant-PCI-ID.patch patches.suse/ALSA-hda-realtek-fix-right-sounds-and-mute-micmute-L.patch + patches.suse/ALSA-hda-realtek-Fix-LED-on-Zbook-Studio-G9.patch patches.suse/ASoC-codecs-Check-for-error-pointer-after-calling-de.patch patches.suse/ASoC-topology-Allow-TLV-control-to-be-either-read-or.patch patches.suse/ASoC-topology-Optimize-soc_tplg_dapm_graph_elems_loa.patch patches.suse/ASoC-xilinx-xlnx_formatter_pcm-Handle-sysclk-setting.patch patches.suse/ASoC-simple-card-utils-Set-sysclk-on-all-components.patch patches.suse/ASoC-SOF-Intel-match-sdw-version-on-link_slaves_foun.patch + patches.suse/ASoC-cs42l42-Report-full-jack-status-when-plug-is-de.patch + patches.suse/ASoC-cs42l42-Change-jack_detect_mutex-to-a-lock-of-a.patch + patches.suse/ASoC-cs42l42-Handle-system-suspend.patch patches.suse/ASoC-madera-Add-dependencies-on-MFD.patch + patches.suse/ASoC-wm_adsp-Make-compressed-buffers-optional.patch + patches.suse/ASoC-wm_adsp-Add-trace-caps-to-speaker-protection-FW.patch patches.suse/ASoC-soc-core-skip-zero-num_dai-component-in-searchi.patch patches.suse/ASoC-rt5663-check-the-return-value-of-devm_kzalloc-i.patch patches.suse/ASoC-amd-vg-fix-for-pm-resume-callback-sequence.patch @@ -11404,7 +11616,10 @@ patches.suse/ASoC-soc-compress-prevent-the-potentially-use-of-nul.patch patches.suse/ASoC-atmel-Add-missing-of_node_put-in-at91sam9g20ek_.patch patches.suse/ASoC-wm8350-Handle-error-for-wm8350_register_irq.patch + patches.suse/ASoC-cs35l41-Remove-unnecessary-param.patch patches.suse/ASoC-fsi-Add-check-for-clk_enable.patch + patches.suse/ASoC-wm_adsp-Expand-firmware-loading-search-options.patch + patches.suse/ASoC-cs42l42-Add-warnings-about-DETECT_MODE-and-PLL_.patch patches.suse/ASoC-Intel-sof_sdw-fix-quirks-for-2022-HP-Spectre-x3.patch patches.suse/ASoC-SOF-Intel-pci-tgl-add-RPL-S-support.patch patches.suse/ASoC-atmel-Fix-error-handling-in-snd_proto_probe.patch @@ -11484,8 +11699,10 @@ patches.suse/TOMOYO-fix-__setup-handlers-return-values.patch patches.suse/KVM-x86-mmu-Move-invalid-check-out-of-kvm_tdp_mmu_ge.patch patches.suse/KVM-x86-mmu-Zap-_all_-roots-when-unmapping-gfn-range.patch + patches.suse/KVM-x86-hyper-v-Drop-redundant-ex-parameter-from-kvm-ipi.patch patches.suse/KVM-x86-hyper-v-Drop-redundant-ex-parameter-from-kvm.patch patches.suse/KVM-x86-hyper-v-Fix-the-maximum-number-of-sparse-ban.patch + patches.suse/KVM-x86-hyper-v-HVCALL_SEND_IPI_EX-is-an-XMM-fast-hy.patch patches.suse/KVM-x86-Fix-emulation-in-writing-cr8.patch patches.suse/KVM-x86-emulator-Defer-not-present-segment-check-in-.patch patches.suse/mm-vmalloc-introduce-array-allocation-functions @@ -11536,6 +11753,7 @@ patches.suse/bnxt_en-Add-driver-support-to-use-Real-Time-Counter-.patch patches.suse/bnxt_en-Implement-.adjtime-for-PTP-RTC-mode.patch patches.suse/bnxt_en-Handle-async-event-when-the-PHC-is-updated-i.patch + patches.suse/net-phy-at803x-move-page-selection-fix-to-config_ini.patch patches.suse/dt-bindings-net-xgmac_mdio-Remove-unsupported-bus-fr.patch patches.suse/ixgbe-Remove-useless-DMA-32-fallback-configuration.patch patches.suse/ixgbevf-Remove-useless-DMA-32-fallback-configuration.patch @@ -11689,11 +11907,13 @@ patches.suse/net-mlx5e-TC-Make-post_act-parse-CT-and-sample-actio.patch patches.suse/net-mlx5e-TC-Allow-sample-action-with-CT.patch patches.suse/selftests-mptcp-add-csum-mib-check-for-mptcp_connect.patch + patches.suse/s390-qeth-Remove-redundant-flush_workqueue-calls patches.suse/net-ibmvnic-Cleanup-workaround-doing-an-EOI-after-pa.patch patches.suse/ionic-catch-transition-back-to-RUNNING-with-fw_gener.patch patches.suse/i40e-remove-dead-stores-on-XSK-hotpath.patch patches.suse/octeontx2-pf-cn10k-add-support-for-new-ptp-timestamp.patch patches.suse/octeontx2-af-cn10k-add-workaround-for-ptp-errata.patch + patches.suse/s390-net-sort-out-physical-vs-virtual-pointers-usage patches.suse/ixgbevf-clean-up-some-inconsistent-indenting.patch patches.suse/ixgbe-Remove-non-inclusive-language.patch patches.suse/nfp-refactor-policer-config-to-support-ingress-egres.patch @@ -11703,6 +11923,7 @@ patches.suse/nfp-add-support-to-offload-police-action-from-flower.patch patches.suse/net-flow_offload-add-tc-police-action-parameters.patch patches.suse/flow_offload-reject-offload-for-all-drivers-with-inv.patch + patches.suse/net-qlcnic-use-time_is_before_jiffies-instead-of-open-coding-it.patch patches.suse/mlx5-remove-unused-static-inlines.patch patches.suse/net-mlx5-Add-ability-to-insert-to-specific-flow-grou.patch patches.suse/net-mlx5-E-Switch-reserve-and-use-same-uplink-metada.patch @@ -11981,6 +12202,7 @@ patches.suse/mt76-mt7921-fix-mt7921_queues_acq-implementation.patch patches.suse/mt76-fix-monitor-mode-crash-with-sdio-driver.patch patches.suse/rfkill-make-new-event-layout-opt-in.patch + patches.suse/qlcnic-remove-redundant-assignment-to-variable-index.patch patches.suse/Bluetooth-btusb-Add-missing-Chicony-device-for-Realt.patch patches.suse/Bluetooth-Fix-use-after-free-in-hci_send_acl.patch patches.suse/Bluetooth-call-hci_le_conn_failed-with-hdev-lock-in-.patch @@ -12004,6 +12226,7 @@ patches.suse/net-mlx5e-Statify-function-mlx5_cmd_trigger_completi.patch patches.suse/net-mlx5e-HTB-remove-unused-function-declaration.patch patches.suse/qed-remove-unnecessary-memset-in-qed_init_fw_funcs.patch + patches.suse/s390-ctcm-fix-typo-length-to-short-length-too-short patches.suse/bnxt-use-the-devlink-instance-lock-to-protect-sriov.patch patches.suse/devlink-add-explicitly-locked-flavor-of-the-rate-nod.patch patches.suse/netdevsim-replace-port_list_lock-with-devlink-instan.patch @@ -12063,6 +12286,7 @@ patches.suse/drm-amd-pm-return-ENOTSUPP-if-there-is-no-get_dpm_ul.patch patches.suse/drm-amdkfd-Don-t-take-process-mutex-for-svm-ioctls.patch patches.suse/drm-amdgpu-Fix-recursive-locking-warning.patch + patches.suse/drm-amdgpu-display-change-pipe-policy-for-DCN-2.0.patch patches.suse/drm-amd-pm-enable-pm-sysfs-write-for-one-VF-mode.patch patches.suse/drm-amd-display-Add-affected-crtcs-to-atomic-state-f.patch patches.suse/0011-drm-amdgpu-fix-amdgpu_ras_block_late_init-error-hand.patch @@ -12186,6 +12410,7 @@ patches.suse/scsi-libiscsi-Add-iscsi_cls_conn-to-sysfs-after-initialization.patch patches.suse/scsi-libiscsi-Teardown-iscsi_cls_conn-gracefully.patch patches.suse/scsi-qla2xxx-Fix-incorrect-reporting-of-task-managem.patch + patches.suse/scsi-qla2xxx-Fix-disk-failure-to-rediscover.patch patches.suse/scsi-qla2xxx-Fix-loss-of-NVMe-namespaces-after-drive.patch patches.suse/scsi-qla2xxx-Fix-missed-DMA-unmap-for-NVMe-ls-reques.patch patches.suse/scsi-qla2xxx-Fix-crash-during-module-load-unload-tes.patch @@ -12315,8 +12540,10 @@ patches.suse/mtd-rawnand-pl353-Set-the-nand-chip-node-as-the-flas.patch patches.suse/mtd-rawnand-atmel-fix-refcount-issue-in-atmel_nand_c.patch patches.suse/mfd-mc13xxx-Add-check-for-mc13xxx_irq_request.patch + patches.suse/mfd-intel-lpss-Add-Intel-Raptor-Lake-PCH-S-PCI-IDs.patch patches.suse/mfd-exynos-lpass-Drop-unneeded-syscon.h-include.patch patches.suse/mfd-asic3-Add-missing-iounmap-on-error-asic3_mfd_pro.patch + patches.suse/drm-i915-Reject-unsupported-TMDS-rates-on-ICL.patch patches.suse/drm-i915-Treat-SAGV-block-time-0-as-SAGV-disabled.patch patches.suse/drm-i915-Fix-PSF-GV-point-mask-when-SAGV-is-not-poss.patch patches.suse/drm-edid-check-basic-audio-support-on-CEA-extension-.patch @@ -12336,6 +12563,7 @@ patches.suse/i2c-piix4-Add-EFCH-MMIO-support-to-SMBus-base-addres.patch patches.suse/i2c-piix4-Add-EFCH-MMIO-support-for-SMBus-port-selec.patch patches.suse/i2c-piix4-Enable-EFCH-MMIO-for-Family-17h.patch + patches.suse/i2c-i801-Add-support-for-Intel-Raptor-Lake-PCH-S.patch patches.suse/i2c-smbus-Check-for-parent-device-before-dereference.patch patches.suse/i2c-tegra-Add-SMBus-block-read-function.patch patches.suse/i2c-xiic-Make-bus-names-unique.patch @@ -12365,22 +12593,36 @@ patches.suse/usb-dwc3-pci-Set-the-swnode-from-inside-dwc3_pci_qui.patch patches.suse/xhci-omit-mem-read-just-after-allocation-of-trb.patch patches.suse/USB-core-Update-kerneldoc-for-usb_get_dev-and-usb_ge.patch + patches.suse/usb-Drop-commas-after-SoC-match-table-sentinels.patch patches.suse/usb-typec-tipd-Forward-plug-orientation-to-typec-sub.patch patches.suse/xhci-make-xhci_handshake-timeout-for-xhci_reset-adju.patch patches.suse/xhci-fix-garbage-USBSTS-being-logged-in-some-cases.patch patches.suse/xhci-fix-uninitialized-string-returned-by-xhci_decod.patch patches.suse/xhci-fix-runtime-PM-imbalance-in-USB2-resume.patch + patches.suse/usb-host-xhci-use-ffs-in-xhci_mem_init.patch + patches.suse/usb-host-xhci-fix-a-comment-typo-in-xhci_mem_init.patch patches.suse/USB-serial-simple-add-Nokia-phone-driver.patch patches.suse/USB-serial-pl2303-add-IBM-device-IDs.patch patches.suse/USB-serial-pl2303-fix-GS-type-detection.patch + patches.suse/thunderbolt-Remove-useless-DMA-32-fallback-configura.patch + patches.suse/thunderbolt-Disable-LTTPR-on-Intel-Titan-Ridge.patch + patches.suse/thunderbolt-Add-missing-device-ID-to-tb_switch_is_al.patch + patches.suse/thunderbolt-Add-internal-xHCI-connect-flows-for-Thun.patch + patches.suse/thunderbolt-Replace-acpi_bus_get_device.patch + patches.suse/thunderbolt-Retry-DROM-reads-for-more-failure-scenar.patch + patches.suse/thunderbolt-Do-not-resume-routers-if-UID-is-not-set.patch + patches.suse/thunderbolt-Do-not-make-DROM-read-success-compulsory.patch + patches.suse/thunderbolt-Clarify-register-definitions-for-tb_cap_.patch patches.suse/dt-bindings-usb-hcd-correct-usb-device-path.patch patches.suse/usb-dwc3-gadget-Give-some-time-to-schedule-isoc.patch patches.suse/usb-dwc3-omap-fix-unbalanced-disables-for-smps10_out.patch patches.suse/USB-storage-ums-realtek-fix-error-code-in-rts51x_rea.patch patches.suse/usb-common-usb-conn-gpio-Make-VBUS-supply-completely.patch + patches.suse/xen-usb-don-t-use-arbitrary_virt_to_machine.patch patches.suse/usb-dwc3-gadget-ep_queue-simplify-isoc-start-conditi.patch patches.suse/usb-dwc3-gadget-move-cmd_endtransfer-to-extra-functi.patch patches.suse/usb-dwc3-gadget-Wait-for-ep0-xfers-to-complete-durin.patch + patches.suse/xen-usb-harden-xen_hcd-against-malicious-backends.patch patches.suse/usb-usbip-eliminate-anonymous-module_init-module_exi.patch patches.suse/usb-gadget-eliminate-anonymous-module_init-module_ex.patch patches.suse/USB-usb-storage-Fix-use-of-bitfields-for-hardware-da.patch @@ -12388,6 +12630,7 @@ patches.suse/tracing-Have-trace-event-string-test-handle-zero-length-strings.patch patches.suse/x86-ibt-paravirt-use-text_gen_insn-for-paravirt_patch.patch patches.suse/x86-ibt-xen-sprinkle-the-endbr.patch + patches.suse/x86-ibt-ftrace-make-function-graph-play-nice.patch patches.suse/mailbox-tegra-hsp-Flush-whole-channel.patch patches.suse/mailbox-imx-fix-wakeup-failure-from-freeze-mode.patch patches.suse/mailbox-imx-fix-crash-in-resume-on-i.mx8ulp.patch @@ -12399,6 +12642,8 @@ patches.suse/pinctrl-nuvoton-npcm7xx-Rename-DS-macro-to-DSTR.patch patches.suse/pinctrl-renesas-r8a77470-Reduce-size-for-narrow-VIN1.patch patches.suse/pinctrl-renesas-checker-Fix-miscalculation-of-number.patch + patches.suse/pinctrl-alderlake-Add-Raptor-Lake-S-ACPI-ID.patch + patches.suse/pinctrl-alderlake-Add-Intel-Alder-Lake-N-pin-control.patch patches.suse/pinctrl-mediatek-Fix-missing-of_node_put-in-mtk_pctr.patch patches.suse/pinctrl-pinconf-generic-Print-arguments-for-bias-pul.patch patches.suse/pinctrl-mediatek-paris-Fix-PIN_CONFIG_BIAS_-readback.patch @@ -12419,6 +12664,8 @@ patches.suse/VMCI-dma-dg-allocate-send-and-receive-buffers-for-DM.patch patches.suse/VMCI-dma-dg-add-support-for-DMA-datagrams-sends.patch patches.suse/VMCI-dma-dg-add-support-for-DMA-datagrams-receive.patch + patches.suse/nvmem-core-Check-input-parameter-for-NULL-in-nvmem_u.patch + patches.suse/thunderbolt-Drop-duplicate-NULL-checks-around-nvmem_.patch patches.suse/mmc-rtsx-Let-MMC-core-handle-runtime-PM.patch patches.suse/w1-w1_therm-fixes-w1_seq-for-ds28ea00-sensors.patch patches.suse/VMCI-Fix-the-description-of-vmci_check_host_caps.patch @@ -12473,6 +12720,7 @@ patches.suse/serial-samsung_tty-do-not-unlock-port-lock-for-uart_.patch patches.suse/serial-sc16is7xx-Clear-RS485-bits-in-the-shutdown.patch patches.suse/serial-8250-fix-XOFF-XON-sending-when-DMA-is-used.patch + patches.suse/xen-grant-table-remove-readonly-parameter-from-funct.patch patches.suse/xen-fix-is_xen_pmu.patch patches.suse/livepatch-Don-t-block-removal-of-patches-that-are-safe-to-unload.patch patches.suse/net-stmmac-dwmac-qcom-ethqos-Enable-RGMII-functional.patch @@ -12488,6 +12736,7 @@ patches.suse/net-phy-broadcom-Fix-brcm_fet_config_init.patch patches.suse/selftests-test_vxlan_under_vrf-Fix-broken-test-case.patch patches.suse/net-hns3-clean-residual-vf-config-after-disable-srio.patch + patches.suse/net-hns3-add-netdev-reset-check-for-hns3_set_tunable.patch patches.suse/net-hns3-add-NULL-pointer-check-for-hns3_set-get_rin.patch patches.suse/net-hns3-fix-phy-can-not-link-up-when-autoneg-off-an.patch patches.suse/net-sparx5-depends-on-PTP_1588_CLOCK_OPTIONAL.patch @@ -12502,6 +12751,7 @@ patches.suse/cpufreq-qcom-cpufreq-nvmem-fix-reading-of-PVS-Valid-.patch patches.suse/fs-fd-tables-have-to-be-multiples-of-BITS_PER_LONG.patch patches.suse/jfs-fix-divide-error-in-dbNextAG.patch + patches.suse/jfs-prevent-NULL-deref-in-diFree.patch patches.suse/NFS-NFSv2-v3-clients-should-never-be-setting-NFS_CAP.patch patches.suse/NFS-Use-of-mapping_set_error-results-in-spurious-err.patch patches.suse/NFS-Return-valid-errors-from-nfs2-3_decode_dirent.patch @@ -12511,6 +12761,7 @@ patches.suse/SUNRPC-remove-scheduling-boost-for-SWAPPER-tasks.patch patches.suse/SUNRPC-improve-swap-handling-scheduling-and-PF_MEMAL.patch patches.suse/0001-SUNRPC-change-locking-for-xs_swap_enable-disable.patch + patches.suse/SUNRPC-Don-t-call-connect-more-than-once-on-a-TCP-so.patch patches.suse/SUNRPC-avoid-race-between-mod_timer-and-del_timer_sy.patch patches.suse/SUNRPC-don-t-resend-a-task-on-an-offlined-transport.patch patches.suse/NFSv4.1-don-t-retry-BIND_CONN_TO_SESSION-on-session-.patch @@ -12618,8 +12869,15 @@ patches.suse/Input-stmfts-fix-reference-leak-in-stmfts_input_open.patch patches.suse/Input-synaptics-enable-InterTouch-on-ThinkPad-T14-P1.patch patches.suse/Revert-Input-clear-BTN_RIGHT-MIDDLE-on-buttonpads.patch + patches.suse/ALSA-hda-realtek-Add-mute-and-micmut-LED-support-for.patch patches.suse/ALSA-hda-realtek-Enable-headset-mic-on-Lenovo-P360.patch patches.suse/ALSA-cs4236-fix-an-incorrect-NULL-check-on-list-iter.patch + patches.suse/ALSA-hda-cs8409-Fix-Warlock-to-use-mono-mic-configur.patch + patches.suse/ALSA-hda-cs8409-Re-order-quirk-table-into-ascending-.patch + patches.suse/ALSA-hda-cs8409-Fix-Full-Scale-Volume-setting-for-al.patch + patches.suse/ALSA-hda-cs8409-Support-new-Warlock-MLK-Variants.patch + patches.suse/ALSA-hda-cs8409-Disable-HSBIAS_SENSE_EN-for-Cyborg.patch + patches.suse/ALSA-hda-cs8409-Add-new-Dolphin-HW-variants.patch patches.suse/ALSA-hda-realtek-Fix-audio-regression-on-Mi-Notebook.patch patches.suse/ALSA-hda-Avoid-unsol-event-during-RPM-suspending.patch patches.suse/ASoC-mediatek-mt6358-add-missing-EXPORT_SYMBOLs.patch @@ -12692,7 +12950,10 @@ patches.suse/ice-Clear-default-forwarding-VSI-during-VSI-release.patch patches.suse/ice-Fix-MAC-address-setting.patch patches.suse/ice-Fix-broken-IFF_ALLMULTI-handling.patch + patches.suse/net-ipv4-fix-route-with-nexthop-object-delete-warnin.patch + patches.suse/selftests-net-add-delete-nexthop-route-warning-test.patch patches.suse/net-stmmac-Fix-unset-max_speed-difference-between-DT.patch + patches.suse/selftests-net-fix-nexthop-warning-cleanup-double-ip-.patch patches.suse/qed-fix-ethtool-register-dump.patch patches.suse/bnxt_en-Synchronize-tx-when-xdp-redirects-happen-on-.patch patches.suse/bnxt_en-reserve-space-inside-receive-page-for-skb_sh.patch @@ -12738,6 +12999,7 @@ patches.suse/amd-display-set-backlight-only-if-required.patch patches.suse/drm-amdkfd-Create-file-descriptor-after-client-is-ad.patch patches.suse/drm-amdgpu-don-t-use-BACO-for-reset-in-S3.patch + patches.suse/drm-amdgpu-display-change-pipe-policy-for-DCN-2.1.patch patches.suse/drm-amdgpu-smu10-fix-SoC-fclk-units-in-auto-mode.patch patches.suse/drm-nouveau-pmu-Add-missing-callbacks-for-Tegra-devi.patch patches.suse/iommu-omap-Fix-regression-in-probe-for-NULL-pointer-dereference @@ -12780,6 +13042,7 @@ patches.suse/scsi-lpfc-fix-locking-for-lpfc_sli_iocbq_lookup.patch patches.suse/scsi-virtio-scsi-Eliminate-anonymous-module_init-module_exit patches.suse/scsi-zorro7xx-Fix-a-resource-leak-in-zorro7xx_remove_one + patches.suse/scsi-ufs-ufs-pci-Add-support-for-Intel-MTL.patch patches.suse/tools-testing-nvdimm-Fix-security_init-symbol-collis.patch patches.suse/sched-core-Fix-forceidle-balancing.patch patches.suse/sched-Teach-the-forced-newidle-balancer-about-CPU-af.patch @@ -12792,6 +13055,7 @@ patches.suse/powerpc-numa-Handle-partially-initialized-numa-nodes.patch patches.suse/platform-x86-samsung-laptop-Fix-an-unsigned-comparis.patch patches.suse/media-rockchip-rga-do-proper-error-checking-in-probe.patch + patches.suse/KVM-avoid-NULL-pointer-dereference-in-kvm_dirty_ring.patch patches.suse/nfsd-Fix-a-write-performance-regression.patch patches.suse/SUNRPC-Fix-NFSD-s-request-deferral-on-RDMA-transport.patch patches.suse/SUNRPC-Fix-the-svc_deferred_event-trace-class.patch @@ -12828,6 +13092,7 @@ patches.suse/nl80211-correctly-check-NL80211_ATTR_REG_ALPHA2-size.patch patches.suse/cfg80211-hold-bss_lock-while-updating-nontrans_list.patch patches.suse/nfc-nci-add-flush_workqueue-to-prevent-uaf.patch + patches.suse/net-dsa-felix-fix-tagging-protocol-changes-with-mult.patch patches.suse/net-bcmgenet-Revert-Use-stronger-register-read-write.patch patches.suse/cifs-Check-the-IOCB_DIRECT-flag-not-O_DIRECT.patch patches.suse/cifs-release-cached-dentries-only-if-mount-is-complete.patch @@ -12844,6 +13109,7 @@ patches.suse/drm-amdgpu-Ensure-HDA-function-is-suspended-before-A.patch patches.suse/drm-amdgpu-Enable-gfxoff-quirk-on-MacBook-Pro.patch patches.suse/testing-selftests-mqueue-Fix-mq_perf_tests-to-free-t.patch + patches.suse/nvme-don-t-print-verbose-errors-for-internal-passthr.patch patches.suse/0008-dm-mpath-only-use-ktime_get_ns-in-historical-selecto.patch patches.suse/mm-page_alloc-fix-build_zonerefs_node.patch patches.suse/dma-direct-avoid-redundant-memory-sync-for-swiotlb.patch @@ -12910,11 +13176,15 @@ patches.suse/ASoC-topology-Correct-error-handling-in-soc_tplg_dap.patch patches.suse/ASoC-soc-dapm-fix-two-incorrect-uses-of-list-iterato.patch patches.suse/ASoC-rt5682-fix-an-incorrect-NULL-check-on-list-iter.patch + patches.suse/ASoC-cs35l41-Add-one-more-variable-in-the-debug-log.patch + patches.suse/ASoC-cs35l41-Fix-a-shift-out-of-bounds-warning-found.patch patches.suse/ASoC-rk817-Use-devm_clk_get-in-rk817_platform_probe.patch patches.suse/ASoC-msm8916-wcd-digital-Check-failure-for-devm_snd_.patch patches.suse/ASoC-codecs-wcd934x-do-not-switch-off-SIDO-Buck-when.patch patches.suse/ASoC-Intel-soc-acpi-correct-device-endpoints-for-max.patch + patches.suse/firmware-cs_dsp-Fix-overrun-of-unterminated-control-.patch patches.suse/ALSA-usb-audio-Clear-MIDI-port-active-flag-after-dra.patch + patches.suse/ALSA-hda-realtek-Enable-mute-micmute-LEDs-and-limit-.patch patches.suse/ALSA-hda-intel-dsp-config-Add-RaptorLake-PCI-IDs.patch patches.suse/ALSA-hda-realtek-Add-quirk-for-Clevo-NP70PNP.patch patches.suse/cifs-Use-kzalloc-instead-of-kmalloc-memset.patch @@ -12949,6 +13219,8 @@ patches.suse/powerpc-perf-Fix-power10-event-alternatives.patch patches.suse/sched-pelt-Fix-attach_entity_load_avg-corner-case.patch patches.suse/0002-video-fbdev-udlfb-properly-check-endpoint-type.patch + patches.suse/video-fbdev-i740fb-Error-out-if-pixclock-equals-zero.patch + patches.suse/pinctrl-alderlake-Fix-register-offsets-for-ADL-N-var.patch patches.suse/pinctrl-mediatek-moore-Fix-build-error.patch patches.suse/pinctrl-stm32-Do-not-call-stm32_gpio_get-for-edge-tr.patch patches.suse/pinctrl-samsung-fix-missing-GPIOLIB-on-ARM64-Exynos-.patch @@ -12973,6 +13245,7 @@ patches.suse/cpufreq-fix-memory-leak-in-sun50i_cpufreq_nvmem_prob.patch patches.suse/thermal-int340x-Fix-attr.show-callback-prototype.patch patches.suse/wireguard-device-check-for-metadata_dst-with-skb_val.patch + patches.suse/net-ethernet-stmmac-fix-write-to-sgmii_adapter_base.patch patches.suse/net-hns3-clear-inited-state-and-stop-client-after-fa.patch patches.suse/net-hns3-align-the-debugfs-output-to-the-left.patch patches.suse/net-hns3-modify-the-return-code-of-hclge_get_ring_ch.patch @@ -13032,6 +13305,7 @@ patches.suse/usb-xhci-tegra-Fix-PM-usage-reference-leak-of-tegra_.patch patches.suse/usb-typec-ucsi-Fix-reuse-of-completion-structure.patch patches.suse/usb-typec-ucsi-Fix-role-swapping.patch + patches.suse/USB-Fix-ehci-infinite-suspend-resume-loop-issue-in-z.patch patches.suse/usb-misc-fix-improper-handling-of-refcount-in-uss720.patch patches.suse/xhci-Enable-runtime-PM-on-second-Alderlake-controlle.patch patches.suse/usb-mtu3-fix-USB-3.0-dual-role-switch-from-device-to.patch @@ -13104,6 +13378,7 @@ patches.suse/net-ethernet-mediatek-add-missing-of_node_put-in-mtk.patch patches.suse/net-mdio-Fix-ENOMEM-return-value-in-BCM6368-mux-bus-.patch patches.suse/hinic-fix-bug-of-wq-out-of-bound-access.patch + patches.suse/net-dsa-ksz9477-port-mirror-sniffing-limited-to-one-.patch patches.suse/net-dsa-mt7530-add-missing-of_node_put-in-mt7530_set.patch patches.suse/net-stmmac-dwmac-sun8i-add-missing-of_node_put-in-su.patch patches.suse/net-cpsw-add-missing-of_node_put-in-cpsw_probe_dt.patch @@ -13157,6 +13432,7 @@ patches.suse/kvm-x86-cpuid-Only-provide-CPUID-leaf-0xA-if-host-ha.patch patches.suse/SUNRPC-release-the-transport-of-a-relocated-task-wit.patch patches.suse/NFSv4-Don-t-invalidate-inode-attributes-on-delegatio.patch + patches.suse/SUNRPC-Don-t-leak-sockets-in-xs_local_connect.patch patches.suse/SUNRPC-Ensure-gss-proxy-connects-on-setup.patch patches.suse/Revert-SUNRPC-attempt-AF_LOCAL-connect-on-setup.patch patches.suse/s390-dasd-fix-data-corruption-for-ESE-devices @@ -13168,6 +13444,8 @@ patches.suse/gpio-visconti-Fix-fwnode-of-GPIO-IRQ.patch patches.suse/gpio-pca953x-fix-irq_stat-not-updated-when-irq-is-di.patch patches.suse/floppy-use-a-statically-allocated-error-counter.patch + patches.suse/ALSA-hda-realtek-Fix-mute-led-issue-on-thinkpad-with.patch + patches.suse/ALSA-hda-realtek-Enable-mute-micmute-LEDs-support-fo.patch patches.suse/firewire-fix-potential-uaf-in-outbound_phy_packet_ca.patch patches.suse/firewire-remove-check-of-list-iterator-against-head-.patch patches.suse/firewire-core-extend-card-lock-in-fw_core_handle_bus.patch @@ -13184,6 +13462,7 @@ patches.suse/ASoC-dmaengine-Restore-NULL-prepare_slave_config-cal.patch patches.suse/ASoC-ops-Validate-input-values-in-snd_soc_put_volsw_.patch patches.suse/ASoC-SOF-Fix-NULL-pointer-exception-in-sof_pci_probe.patch + patches.suse/mm-Fix-PASID-use-after-free-issue.patch patches.suse/genirq-Synchronize-interrupt-thread-startup.patch patches.suse/timekeeping-Mark-NMI-safe-time-accessors-as-notrace.patch patches.suse/powerpc-pseries-vas-Use-QoS-credits-from-the-userspa.patch @@ -13266,6 +13545,7 @@ patches.suse/fsl_lpuart-Don-t-enable-interrupts-too-early.patch patches.suse/slimbus-qcom-Fix-IRQ-check-in-qcom_slim_probe.patch patches.suse/firmware_loader-use-kernel-credentials-when-reading-.patch + patches.suse/thermal-int340x-Mode-setting-with-new-OS-handshake.patch patches.suse/Revert-PCI-aardvark-Rewrite-IRQ-code-to-chained-IRQ-.patch patches.suse/ALSA-usb-audio-Don-t-get-sample-rate-for-MCT-Trigger.patch patches.suse/ALSA-hda-fix-unused-Realtek-function-when-PM-is-not-.patch @@ -13358,8 +13638,58 @@ patches.suse/irqchip-aspeed-scu-ic-Fix-irq_of_parse_and_map-retur.patch patches.suse/irqchip-armada-370-xp-Do-not-touch-Performance-Count.patch patches.suse/irqchip-gic-v3-Ensure-pseudo-NMIs-have-an-ISB-betwee.patch + patches.suse/edac-dmc520-don-t-print-an-error-for-each-unconfigured-interrupt-line.patch + patches.suse/KVM-SVM-Define-sev_features-and-VMPL-field-in-the-VMSA + patches.suse/KVM-SVM-Create-a-separate-mapping-for-the-SEV-ES-save-area + patches.suse/KVM-SVM-Create-a-separate-mapping-for-the-GHCB-save-area + patches.suse/KVM-SVM-Update-the-SEV-ES-save-area-mapping + patches.suse/x86-boot-Introduce-helpers-for-MSR-reads-writes + patches.suse/x86-boot-Use-MSR-read-write-helpers-instead-of-inline-assembly + patches.suse/x86-compressed-64-Detect-setup-SEV-SME-features-earlier-during-b + patches.suse/x86-sev-Detect-setup-SEV-SME-features-earlier-in-boot + patches.suse/x86-mm-Extend-cc_attr-to-include-AMD-SEV-SNP patches.suse/x86-sev-define-the-linux-specific-guest-termination-reasons.patch patches.suse/x86-sev-save-the-negotiated-ghcb-version.patch + patches.suse/x86-sev-Check-SEV-SNP-features-support + patches.suse/x86-sev-Add-a-helper-for-the-PVALIDATE-instruction + patches.suse/x86-sev-Check-the-VMPL-level + patches.suse/x86-compressed-Add-helper-for-validating-pages-in-the-decompress + patches.suse/x86-compressed-Register-GHCB-memory-when-SEV-SNP-is-active + patches.suse/x86-sev-Register-GHCB-memory-when-SEV-SNP-is-active + patches.suse/x86-sev-Add-helper-for-validating-pages-in-early-enc-attribute-c + patches.suse/x86-kernel-Mark-the-.bss.decrypted-section-as-shared-in-the-RMP- + patches.suse/x86-kernel-Validate-ROM-memory-before-accessing-when-SEV-SNP-is- + patches.suse/x86-mm-Validate-memory-when-changing-the-C-bit + patches.suse/x86-sev-Use-SEV-SNP-AP-creation-to-start-secondary-CPUs + patches.suse/x86-head-64-Re-enable-stack-protection + patches.suse/x86-compressed-acpi-Move-EFI-detection-to-helper + patches.suse/x86-compressed-acpi-Move-EFI-system-table-lookup-to-helper + patches.suse/x86-compressed-acpi-Move-EFI-config-table-lookup-to-helper + patches.suse/x86-compressed-acpi-Move-EFI-vendor-table-lookup-to-helper + patches.suse/x86-compressed-acpi-Move-EFI-kexec-handling-into-common-code + patches.suse/x86-boot-Add-Confidential-Computing-type-to-setup_data + patches.suse/KVM-x86-Move-lookup-of-indexed-CPUID-leafs-to-helper + patches.suse/x86-sev-Move-MSR-based-VMGEXITs-for-CPUID-to-helper + patches.suse/x86-compressed-64-Add-support-for-SEV-SNP-CPUID-table-in-VC-hand + patches.suse/x86-boot-Add-a-pointer-to-Confidential-Computing-blob-in-bootpar + patches.suse/x86-compressed-Add-SEV-SNP-feature-detection-setup + patches.suse/x86-compressed-Use-firmware-validated-CPUID-leaves-for-SEV-SNP-g + patches.suse/x86-compressed-Export-and-rename-add_identity_map + patches.suse/x86-compressed-64-Add-identity-mapping-for-Confidential-Computin + patches.suse/x86-sev-Add-SEV-SNP-feature-detection-setup + patches.suse/x86-sev-Use-firmware-validated-CPUID-for-SEV-SNP-guests + patches.suse/x86-sev-Add-a-sev-cmdline-option + patches.suse/x86-sev-Provide-support-for-SNP-guest-request-NAEs + patches.suse/x86-sev-Register-SEV-SNP-guest-request-platform-device + patches.suse/virt-Add-SEV-SNP-guest-driver + patches.suse/virt-sevguest-Add-support-to-derive-key + patches.suse/virt-sevguest-Add-support-to-get-extended-report + patches.suse/virt-sevguest-Add-documentation-for-SEV-SNP-CPUID-Enforcement + patches.suse/virt-sevguest-Fix-return-value-check-in-alloc_shared_pages + patches.suse/virt-sevguest-Fix-bool-function-returning-negative-value + patches.suse/x86-boot-Put-globals-that-are-accessed-early-into-the-.data-sect + patches.suse/x86-sev-Add-missing-__init-annotations-to-SEV-init-routines + patches.suse/x86-sev-Get-the-AP-jump-table-address-from-secrets-page patches.suse/ACPICA-Avoid-cache-flush-inside-virtual-machines.patch patches.suse/x86-mm-simplify-reserve_brk.patch patches.suse/x86-entry-remove-skip_r11rcx.patch @@ -13367,6 +13697,10 @@ patches.suse/x86-platform-uv-update-tsc-sync-state-for-uv5.patch patches.suse/x86-platform-uv-log-gap-hole-end-size.patch patches.suse/platform-x86-intel-hid-fix-_DSM-function-index-handl.patch + patches.suse/xen-usb-switch-xen-hcd-to-use-INVALID_GRANT_REF.patch + patches.suse/xen-update-ring.h.patch + patches.suse/xen-xenbus-add-xenbus_setup_ring-service-function.patch + patches.suse/xen-usbfront-use-xenbus_setup_ring-and-xenbus_teardo.patch patches.suse/irqchip-irq-xtensa-mx-fix-initial-IRQ-affinity.patch patches.suse/tty-goldfish-Introduce-gf_ioread32-gf_iowrite32.patch patches.suse/s390-stp-clock_delta-should-be-signed @@ -13378,6 +13712,7 @@ patches.suse/kselftest-arm64-bti-force-static-linking.patch patches.suse/arm64-compat-Do-not-treat-syscall-number-as-ESR_ELx-.patch patches.suse/scripts-faddr2line-Fix-overlapping-text-section-fail.patch + patches.suse/ACPI-Add-perf-low-power-callback.patch patches.suse/perf-amd-ibs-cascade-pmu-init-functions-return-value.patch patches.suse/perf-amd-ibs-use-is_visible-callback-for-dynamic-attributes.patch patches.suse/perf-amd-ibs-add-support-for-l3-miss-filtering.patch @@ -13448,29 +13783,86 @@ patches.suse/HID-bigben-fix-slab-out-of-bounds-Write-in-bigben_pr.patch patches.suse/HID-amd_sfh-Modify-the-bus-name.patch patches.suse/HID-amd_sfh-Modify-the-hid-name.patch + patches.suse/ACPI-utils-include-UUID-in-_DSM-evaluation-warning.patch + patches.suse/ACPICA-Add-support-for-the-Windows-11-_OSI-string.patch + patches.suse/ACPICA-Add-the-subtable-CFMWS-to-the-CEDT-table.patch + patches.suse/ACPICA-iASL-NHLT-Treat-Terminator-as-specific_config.patch + patches.suse/ACPICA-iASL-NHLT-Fix-parsing-undocumented-bytes-at-t.patch + patches.suse/ACPICA-iASL-NHLT-Rename-linux-specific-strucures-to-.patch + patches.suse/ACPICA-Add-new-ACPI-6.4-semantics-to-the-Load-operat.patch + patches.suse/ACPICA-Add-new-ACPI-6.4-semantics-for-LoadTable-oper.patch + patches.suse/ACPICA-Clean-up-double-word-in-comment.patch + patches.suse/ACPICA-Update-copyright-notices-to-the-year-2022.patch + patches.suse/ACPICA-Removed-some-tabs-and-comments.patch + patches.suse/ACPICA-Headers-Replace-zero-length-array-with-flexib.patch + patches.suse/ACPICA-executer-exsystem-Add-units-to-time-variable-.patch + patches.suse/ACPICA-Add-support-for-ARM-Performance-Monitoring-Un.patch + patches.suse/ACPICA-executer-exsystem-Inform-users-about-ACPI-spe.patch + patches.suse/ACPICA-executer-exsystem-Warn-about-sleeps-greater-t.patch + patches.suse/ACPICA-iASL-MADT-Add-OEM-defined-subtable.patch + patches.suse/ACPICA-executer-exsystem-Fix-some-typo-mistakes.patch + patches.suse/ACPICA-IORT-Updates-for-revision-E.d.patch + patches.suse/ACPICA-exsystem.c-Use-ACPI_FORMAT_UINT64-for-64-bit-.patch + patches.suse/ACPICA-Update-version-to-20220331.patch + patches.suse/Revert-ACPICA-executer-exsystem-Warn-about-sleeps-gr.patch + patches.suse/ACPI-PM-Convert-debug-message-in-acpi_device_get_pow.patch + patches.suse/ACPI-PM-Change-pr_fmt-in-device_pm.c.patch + patches.suse/ACPI-PM-Unify-debug-messages-in-acpi_device_set_powe.patch + patches.suse/ACPI-PM-Always-print-final-debug-message-in-acpi_dev.patch patches.suse/ACPI-PM-Block-ASUS-B1400CEAE-from-suspend-to-idle-by.patch + patches.suse/ACPI-bus-Introduce-acpi_dev_for_each_child.patch + patches.suse/ACPI-PM-Introduce-acpi_dev_power_up_children_with_ad.patch + patches.suse/PCI-ACPI-PM-Power-up-devices-in-D3cold-before-scanni.patch + patches.suse/ACPI-bus-Avoid-non-ACPI-device-objects-in-walks-over.patch patches.suse/ACPI-sysfs-Fix-BERT-error-region-memory-mapping.patch + patches.suse/ACPI-SPCR-Add-support-for-NVIDIA-16550-compatible-po.patch + patches.suse/ACPI-BGRT-use-static-for-BGRT_SHOW-kobj_attribute-de.patch patches.suse/ACPI-AGDI-Fix-missing-prototype-warning-for-acpi_agd.patch + patches.suse/ACPI-APEI-Fix-missing-ERST-record-id.patch + patches.suse/ACPI-APEI-EINJ-Refuse-to-inject-into-the-zero-page.patch + patches.suse/ACPI-DPTF-Correct-description-of-INT3407-INT3532-att.patch + patches.suse/ACPI-DPTF-Add-support-for-high-frequency-impedance-n.patch + patches.suse/x86-ACPI-Make-mp_config_acpi_gsi-a-void-function.patch patches.suse/PM-devfreq-rk3399_dmc-Disable-edev-on-remove.patch + patches.suse/x86-ACPI-Preserve-ACPI-table-override-during-hiberna.patch + patches.suse/powercap-intel_rapl-add-support-for-RaptorLake.patch + patches.suse/powercap-RAPL-Add-Power-Limit4-support-for-RaptorLake.patch + patches.suse/powercap-intel_rapl-add-support-for-ALDERLAKE_N.patch + patches.suse/ACPI-CPPC-Check-_OSC-for-flexible-address-space.patch + patches.suse/ACPI-bus-Set-CPPC-_OSC-bits-for-all-and-when-CPPC_LI.patch patches.suse/ACPI-CPPC-Assume-no-transition-latency-if-no-PCCT.patch + patches.suse/cpufreq-CPPC-Enable-fast_switch.patch patches.suse/PM-domains-Fix-initialization-of-genpd-s-next_wakeup.patch patches.suse/thermal-drivers-bcm2711-Don-t-clamp-temperature-at-z.patch patches.suse/thermal-drivers-broadcom-Fix-potential-NULL-derefere.patch patches.suse/thermal-core-Fix-memory-leak-in-__thermal_cooling_de.patch patches.suse/thermal-drivers-imx_sc_thermal-Fix-refcount-leak-in-.patch patches.suse/thermal-devfreq_cooling-use-local-ops-instead-of-glo.patch + patches.suse/device-property-Convert-device_-dma_supported-get_dm.patch + patches.suse/ACPI-property-Move-acpi_fwnode_device_get_match_data.patch + patches.suse/device-property-Add-irq_get-to-fwnode-operation.patch patches.suse/ACPI-property-Release-subnode-properties-with-data-n.patch patches.suse/media-i2c-max9286-fix-kernel-oops-when-removing-modu.patch patches.suse/media-media-entity.h-Fix-documentation-for-media_cre.patch patches.suse/media-venus-hfi-avoid-null-dereference-in-deinit.patch + patches.suse/media-imx-jpeg-Add-pm-sleep-support-for-imx-jpeg.patch + patches.suse/media-coda-Fix-reported-H264-profile.patch + patches.suse/media-coda-Add-more-H264-levels-for-CODA960.patch patches.suse/media-pci-cx23885-Fix-the-error-handling-in-cx23885_.patch patches.suse/media-cx25821-Fix-the-warning-when-removing-the-modu.patch patches.suse/media-hantro-Empty-encoder-capture-buffers-by-defaul.patch patches.suse/media-uvcvideo-Fix-missing-check-to-determine-if-ele.patch + patches.suse/media-aspeed-Fix-an-error-handling-path-in-aspeed_vi.patch + patches.suse/media-exynos4-is-Fix-PM-disable-depth-imbalance-in-f.patch + patches.suse/media-st-delta-Fix-PM-disable-depth-imbalance-in-del.patch patches.suse/media-atmel-atmel-isc-Fix-PM-disable-depth-imbalance.patch + patches.suse/media-imx-jpeg-Fix-potential-array-out-of-bounds-in-.patch patches.suse/media-i2c-rdacm2x-properly-set-subdev-entity-functio.patch + patches.suse/media-exynos4-is-Change-clk_disable-to-clk_disable_u.patch + patches.suse/media-imx-jpeg-Refactor-function-mxc_jpeg_parse.patch patches.suse/media-rga-fix-possible-memory-leak-in-rga_probe.patch patches.suse/media-pvrusb2-fix-array-index-out-of-bounds-in-pvr2_.patch + patches.suse/media-vsp1-Fix-offset-calculation-for-plane-cropping.patch patches.suse/media-atmel-atmel-sama5d2-isc-fix-wrong-mask-in-YUYV.patch patches.suse/media-hantro-HEVC-Fix-tile-info-buffer-value-computa.patch patches.suse/media-hantro-HEVC-unconditionnaly-set-pps_-cb-cr-_qp.patch @@ -13580,6 +13972,7 @@ patches.suse/ixgbe-xsk-Get-rid-of-redundant-fallthrough.patch patches.suse/i40e-xsk-Get-rid-of-redundant-fallthrough.patch patches.suse/eth-benet-remove-a-copy-of-the-NAPI_POLL_WEIGHT-defi.patch + patches.suse/qeth-remove-a-copy-of-the-NAPI_POLL_WEIGHT-define patches.suse/sfc-add-EF100-VF-support-via-a-write-to-sriov_numvfs.patch patches.suse/qede-Reduce-verbosity-of-ptp-tx-timestamp.patch patches.suse/net-ieee802154-ca8210-Fix-lifs-sifs-periods.patch @@ -13634,6 +14027,7 @@ patches.suse/net-mlx5-Allow-future-addition-of-IPsec-object-modif.patch patches.suse/sfc-Disable-Siena-support.patch patches.suse/sfc-Copy-a-subset-of-mcdi_pcol.h-to-siena.patch + patches.suse/net-switch-to-netif_napi_add_tx.patch patches.suse/ice-use-min_t-to-make-code-cleaner-in-ice_gnss.patch patches.suse/ice-introduce-common-helper-for-retrieving-VSI-by-vs.patch patches.suse/ice-return-ENOSPC-when-exceeding-ICE_MAX_CHAIN_WORDS.patch @@ -13649,6 +14043,7 @@ patches.suse/net-make-drivers-set-the-TSO-limit-not-the-GSO-limit.patch patches.suse/ixgbe-Fix-module_param-allow_unsupported_sfp-type.patch patches.suse/igb-Convert-kmap-to-kmap_local_page.patch + patches.suse/rtnetlink-add-extack-support-in-fdb-del-handlers.patch patches.suse/ice-link-representors-to-PCI-device.patch patches.suse/Revert-ice-Hide-bus-info-in-ethtool-for-PRs-in-switc.patch patches.suse/sfc-Move-Siena-specific-files.patch @@ -13723,6 +14118,8 @@ patches.suse/net-mlx5-Lag-refactor-lag-state-machine.patch patches.suse/net-mlx5-Remove-unused-argument.patch patches.suse/net-mlx5-Support-multiport-eswitch-mode.patch + patches.suse/net-stmmac-remove-unused-get_addr-callback.patch + patches.suse/eth-sun-cassini-remove-dead-code.patch patches.suse/sfc-siena-Have-a-unique-wrapper-ifndef-for-efx-chann.patch patches.suse/net-mlx5-fix-multiple-definitions-of-mlx5_lag_mpesw_.patch patches.suse/cfg80211-declare-MODULE_FIRMWARE-for-regulatory.db.patch @@ -13737,6 +14134,7 @@ patches.suse/iwlwifi-fw-init-SAR-GEO-table-only-if-data-is-presen.patch patches.suse/iwlwifi-mvm-fix-assert-1F04-upon-reconfig.patch patches.suse/can-mcp251xfd-silence-clang-s-Wunaligned-access-warn.patch + patches.suse/net-wwan-iosm-remove-pointless-null-check.patch patches.suse/sfc-siena-Remove-duplicate-check-on-segments.patch patches.suse/eth-bnxt-make-ulp_id-unsigned-to-make-GCC-12-happy.patch patches.suse/net-mlx5-fix-typo-in-comment.patch @@ -13748,8 +14146,12 @@ patches.suse/Bluetooth-hci_qca-Use-del_timer_sync-before-freeing.patch patches.suse/Bluetooth-use-hdev-lock-in-activate_scan-for-hci_is_.patch patches.suse/Bluetooth-use-hdev-lock-for-accept_list-and-reject_l.patch + patches.suse/net-macb-Fix-PTP-one-step-sync-support.patch patches.suse/Documentation-add-description-for-net.core.gro_norma.patch patches.suse/NFC-hci-fix-sleep-in-atomic-context-bugs-in-nfc_hci_.patch + patches.suse/net-stmmac-fix-out-of-bounds-access-in-a-selftest.patch + patches.suse/hinic-Avoid-some-over-memory-allocation.patch + patches.suse/net-dsa-restrict-SMSC_LAN9303_I2C-kconfig.patch patches.suse/net-smc-postpone-sk_refcnt-increment-in-connect patches.suse/drm-i915-Fix-Wstringop-overflow-warning-in-call-to-i.patch patches.suse/dt-bindings-soc-qcom-smd-rpm-Fix-missing-MSM8936-com.patch @@ -13826,13 +14228,47 @@ patches.suse/drm-i915-Fix-CFI-violation-with-show_dynamic_id.patch patches.suse/drm-i915-dsi-fix-VBT-send-packet-port-selection-for-.patch patches.suse/ALSA-jack-Access-input_dev-under-mutex.patch + patches.suse/ALSA-cs35l41-Unify-hardware-configuration.patch + patches.suse/ALSA-cs35l41-Check-hw_config-before-using-it.patch + patches.suse/ALSA-cs35l41-Move-cs35l41_gpio_config-to-shared-lib.patch + patches.suse/ALSA-hda-cs35l41-Fix-I2S-params-comments.patch + patches.suse/ALSA-hda-cs35l41-Always-configure-the-DAI.patch + patches.suse/ALSA-hda-cs35l41-Add-Boost-type-flag.patch + patches.suse/ALSA-hda-cs35l41-Put-the-device-into-safe-mode-for-e.patch + patches.suse/ALSA-hda-cs35l41-Mute-the-device-before-shutdown.patch + patches.suse/ALSA-cs35l41-Enable-Internal-Boost-in-shared-lib.patch + patches.suse/ALSA-hda-cs35l41-Move-boost-config-to-initialization.patch + patches.suse/ALSA-hda-cs35l41-Remove-cs35l41_hda_reg_sequence-str.patch + patches.suse/ALSA-hda-cs35l41-Reorganize-log-for-playback-actions.patch + patches.suse/ALSA-hda-cs35l41-Handle-all-external-boost-setups-th.patch + patches.suse/ALSA-hda-cs35l41-Move-external-boost-handling-to-lib.patch + patches.suse/ASoC-cs35l41-Document-CS35l41-External-Boost.patch + patches.suse/ASoC-cs35l41-Support-external-boost.patch patches.suse/ALSA-usb-audio-Add-quirk-bits-for-enabling-disabling.patch patches.suse/ALSA-usb-audio-Move-generic-implicit-fb-quirk-entrie.patch patches.suse/ALSA-pcm-Check-for-null-pointer-of-pointer-substream.patch patches.suse/ALSA-hda-conexant-add-a-new-hda-codec-SN6140.patch + patches.suse/ASoC-cs42l42-Move-CS42L42-register-descriptions-to-g.patch + patches.suse/ALSA-hda-cs8409-Use-general-cs42l42-include-in-cs840.patch + patches.suse/ALSA-hda-cs8409-Support-manual-mode-detection-for-CS.patch + patches.suse/ALSA-hda-cs8409-Support-new-Odin-Variants.patch + patches.suse/ALSA-hda-cs8409-Add-Speaker-Playback-Switch-for-Cybo.patch + patches.suse/ALSA-hda-cs8409-Add-Speaker-Playback-Switch-for-Warl.patch + patches.suse/ALSA-hda-cs35l41-Fix-error-in-spi-cs35l41-hda-driver.patch + patches.suse/ALSA-hda-cs35l41-Set-Speaker-Position-for-CLSA0100-L.patch + patches.suse/ALSA-hda-cs35l41-Remove-Set-Channel-Map-api-from-bin.patch + patches.suse/ALSA-hda-cs35l41-Add-Support-for-Interrupts.patch + patches.suse/ALSA-hda-cs35l41-Enable-GPIO2-Interrupt-for-CLSA0100.patch + patches.suse/ASoC-cs35l41-Move-cs35l41_set_cspl_mbox_cmd-to-share.patch + patches.suse/ASoC-cs35l41-Move-cs35l41-fs-errata-into-shared-code.patch + patches.suse/ASoC-cs35l41-Move-cs_dsp-config-struct-into-shared-c.patch + patches.suse/ALSA-hda-cs35l41-Add-Amp-Name-based-on-channel-and-i.patch + patches.suse/ASoC-wm_adsp-Compressed-stream-DSP-memory-structs-sh.patch patches.suse/ALSA-usb-audio-Workaround-for-clock-setup-on-TEAC-de.patch patches.suse/ALSA-usb-audio-Add-missing-ep_idx-in-fixed-EP-quirks.patch patches.suse/ALSA-ctxfi-Add-SB046x-PCI-ID.patch + patches.suse/ASoC-cs35l41-Add-one-more-variable-in-the-debug-log-0f91bc71fe1f.patch + patches.suse/ASoC-cs35l41-Fix-an-out-of-bounds-access-in-otp_pack.patch patches.suse/ASoC-mediatek-Fix-error-handling-in-mt8173_max98090_.patch patches.suse/ASoC-mediatek-Fix-missing-of_node_put-in-mt2701_wm89.patch patches.suse/ASoC-rsnd-care-default-case-on-rsnd_ssiu_busif_err_s.patch @@ -13845,6 +14281,7 @@ patches.suse/ASoC-rt5514-Fix-event-generation-for-DSP-Voice-Wake-.patch patches.suse/ASoC-atmel-pdmic-Remove-endianness-flag-on-pdmic-com.patch patches.suse/ASoC-atmel-classd-Remove-endianness-flag-on-class-d-.patch + patches.suse/ASoC-cs35l41-Add-endianness-flag-in-snd_soc_componen.patch patches.suse/ASoC-tscs454-Add-endianness-flag-in-snd_soc_componen.patch patches.suse/ASoC-rt711-Add-endianness-flag-in-snd_soc_component_.patch patches.suse/ASoC-rt711-sdca-Add-endianness-flag-in-snd_soc_compo.patch @@ -13955,6 +14392,7 @@ patches.suse/arm64-dts-qcom-sdm845-xiaomi-beryllium-fix-typo-in-p.patch patches.suse/arm64-dts-qcom-qrb5165-rb5-Fix-can-clock-node-name.patch patches.suse/ARM-dts-ci4x10-Adapt-to-changes-in-imx6qdl.dtsi-rega.patch + patches.suse/ARM-dts-imx-align-SPI-NOR-node-name-with-dtschema.patch patches.suse/ARM-dts-imx6dl-colibri-Fix-I2C-pinmuxing.patch patches.suse/arm64-dts-imx8mm-beacon-Enable-RTS-CTS-on-UART3.patch patches.suse/arm64-dts-imx8mn-beacon-Enable-RTS-CTS-on-UART3.patch @@ -13986,6 +14424,7 @@ patches.suse/KVM-LAPIC-Drop-pending-LAPIC-timer-injection-when-ca.patch patches.suse/platform-chrome-cros_ec-fix-error-handling-in-cros_e.patch patches.suse/platform-chrome-Re-introduce-cros_ec_cmd_xfer-and-us.patch + patches.suse/NFSD-Clean-up-the-show_nf_flags-macro.patch patches.suse/nfsd-Fix-null-ptr-deref-in-nfsd_fill_super.patch patches.suse/nfsd-destroy-percpu-stats-counters-after-reply-cache.patch patches.suse/NFSD-Fix-possible-sleep-during-nfsd4_release_lockown.patch @@ -14022,6 +14461,12 @@ patches.suse/PCI-AER-Clear-MULTI_ERR_COR-UNCOR_RCV-bits.patch patches.suse/PCI-ACPI-Allow-D3-only-if-Root-Port-can-signal-and-w.patch patches.suse/PCI-PM-Power-up-all-devices-during-runtime-resume.patch + patches.suse/x86-PCI-Eliminate-remove_e820_regions-common-subexpr.patch + patches.suse/x86-Log-resource-clipping-for-E820-regions.patch + patches.suse/x86-PCI-Clip-only-host-bridge-windows-for-E820-regio.patch + patches.suse/x86-PCI-Add-kernel-cmdline-options-to-use-ignore-E82.patch + patches.suse/x86-PCI-Disable-E820-reserved-region-clipping-via-qu.patch + patches.suse/x86-PCI-Disable-E820-reserved-region-clipping-starti.patch patches.suse/PCI-cadence-Fix-find_first_zero_bit-limit.patch patches.suse/PCI-dwc-Fix-setting-error-return-on-MSI-DMA-mapping-.patch patches.suse/PCI-imx6-Fix-PERST-start-up-sequence.patch @@ -14041,6 +14486,7 @@ patches.suse/mfd-davinci_voicecodec-Fix-possible-null-ptr-deref-d.patch patches.suse/testing-nvdimm-iomap-make-__nfit_test_ioremap-a-macr.patch patches.suse/testing-nvdimm-asm-mce.h-is-not-needed-in-nfit.c.patch + patches.suse/acpi-nfit-rely-on-mce-misc-to-determine-poison-granu.patch patches.suse/SMB3-EBADF-EIO-errors-in-rename-open-caused-by-race-condition-in-sm.patch patches.suse/cifs-fix-signed-integer-overflow-when-fl_end-is-OFFSET_MAX.patch patches.suse/cifs-don-t-call-cifs_dfs_query_info_nonascii_quirk-if-nodfs-was-s.patch @@ -14077,6 +14523,10 @@ patches.suse/crypto-qat-remove-dma_free_coherent-for-RSA.patch patches.suse/crypto-qat-remove-dma_free_coherent-for-DH.patch patches.suse/hwrng-omap3-rom-fix-using-wrong-clk_disable-in-omap_.patch + patches.suse/PCI-ACPI-add-a-helper-for-retrieving-_OSC-Control-DW.patch + patches.suse/PCI-ACPI-Prefer-CXL-_OSC-instead-of-PCIe-_OSC-for-CX.patch + patches.suse/PCI-ACPI-negotiate-CXL-_OSC.patch + patches.suse/ACPI-NFIT-Drop-nfit_device_lock.patch patches.suse/pinctrl-mediatek-mt8195-enable-driver-on-mtk-platfor.patch patches.suse/pinctrl-mvebu-Fix-irq_of_parse_and_map-return-value.patch patches.suse/pinctrl-tegra-tegra194-drop-unused-pin-groups.patch @@ -14115,6 +14565,13 @@ patches.suse/dmaengine-idxd-add-missing-callback-function-to-supp.patch patches.suse/dmaengine-stm32-mdma-remove-GISR1-register.patch patches.suse/dmaengine-stm32-mdma-fix-chan-initialization-in-stm3.patch + patches.suse/ACPI-DPTF-Support-Meteor-Lake.patch + patches.suse/ACPI-glue-Rearrange-find_child_checks.patch + patches.suse/ACPI-processor-idle-Expose-max_cstate-nocst-bm_check.patch + patches.suse/ACPI-CPPC-fix-typo-in-comment.patch + patches.suse/ACPI-battery-Make-not-charging-the-default-on-no-cha.patch + patches.suse/ACPI-video-improve-PM-notifer-callback.patch + patches.suse/ACPI-clean-up-white-space-in-a-few-places-for-consis.patch patches.suse/cpufreq-mediatek-Use-module_init-and-add-module_exit.patch patches.suse/cpufreq-mediatek-Unregister-platform-device-on-exit.patch patches.suse/video-fbdev-clcdfb-Fix-refcount-leak-in-clcdfb_of_vr.patch @@ -14170,7 +14627,9 @@ patches.suse/netfilter-nf_tables-disallow-non-stateful-expression.patch patches.suse/net-ethernet-mtk_eth_soc-out-of-bounds-read-in-mtk_h.patch patches.suse/net-ethernet-ti-am65-cpsw-nuss-Fix-some-refcount-lea.patch + patches.suse/net-dsa-mv88e6xxx-Fix-refcount-leak-in-mv88e6xxx_mdi.patch patches.suse/net-smc-fixes-for-converting-from-struct-smc_cdc_tx_pend-to-struct-smc_wr_tx_pend_priv + patches.suse/net-enetc-Use-pci_release_region-to-release-some-res.patch patches.suse/sfc-fix-considering-that-all-channels-have-TX-queues.patch patches.suse/sfc-fix-wrong-tx-channel-offset-with-efx_separate_tx.patch patches.suse/netfilter-nf_tables-sanitize-nft_set_desc_concat_par.patch @@ -14257,6 +14716,7 @@ patches.suse/tty-Fix-a-possible-resource-leak-in-icom_probe.patch patches.suse/tty-serial-owl-Fix-missing-clk_disable_unprepare-in-.patch patches.suse/tty-n_tty-Restore-EOF-push-handling-behavior.patch + patches.suse/serial-atmel-remove-redundant-assignment-in-rs485_co.patch patches.suse/serial-8250_aspeed_vuart-Fix-potential-NULL-derefere.patch patches.suse/tty-serial-fsl_lpuart-fix-potential-bug-when-using-b.patch patches.suse/tty-n_gsm-clean-up-dead-code-in-gsm_queue.patch @@ -14298,6 +14758,8 @@ patches.suse/usb-dwc2-gadget-don-t-reset-gadget-s-driver-bus.patch patches.suse/usb-ehci-omap-drop-unused-ehci_read-function.patch patches.suse/usb-dwc3-gadget-Prevent-repeat-pullup.patch + patches.suse/usb-dwc3-gadget-Refactor-pullup.patch + patches.suse/usb-dwc3-gadget-Don-t-modify-GEVNTCOUNT-in-pullup.patch patches.suse/usb-core-hcd-Add-support-for-deferring-roothub-regis.patch patches.suse/xhci-Set-HCD-flag-to-defer-primary-roothub-registrat.patch patches.suse/xhci-factor-out-parts-of-xhci_gen_setup.patch @@ -14308,7 +14770,10 @@ patches.suse/xhci-use-generic-command-timer-for-stop-endpoint-com.patch patches.suse/xhci-prevent-U2-link-power-state-if-Intel-tier-polic.patch patches.suse/xhci-Allow-host-runtime-PM-as-default-for-Intel-Alde.patch + patches.suse/thunderbolt-Replace-usage-of-found-with-dedicated-li.patch + patches.suse/thunderbolt-Use-decimal-number-with-port-numbers.patch patches.suse/thunderbolt-Use-different-lane-for-second-DisplayPor.patch + patches.suse/thunderbolt-Fix-buffer-allocation-of-devices-with-no.patch patches.suse/xhci-Don-t-defer-primary-roothub-registration-if-the.patch patches.suse/usb-isp1760-Fix-out-of-bounds-array-access.patch patches.suse/usb-dwc3-gadget-Move-null-pinter-check-to-proper-pla.patch @@ -14355,6 +14820,8 @@ patches.suse/regulator-mt6315-regulator-fix-invalid-allowed-mode.patch patches.suse/gpio-pca953x-use-the-correct-register-address-to-do-.patch patches.suse/gpio-adp5588-Remove-support-for-platform-setup-and-t.patch + patches.suse/0006-parisc-stifb-Implement-fb_is_primary_device.patch + patches.suse/0007-parisc-stifb-Keep-track-of-hardware-path-of-graphics.patch patches.suse/net-mellanox-fix-open-coded-for_each_set_bit.patch patches.suse/qed-rework-qed_rdma_bmap_free.patch patches.suse/octeontx2-pf-replace-bitmap_weight-with-bitmap_empty.patch @@ -14382,15 +14849,20 @@ patches.suse/clocksource-drivers-sp804-Avoid-error-on-multiple-in.patch patches.suse/clocksource-drivers-oxnas-rps-Fix-irq_of_parse_and_m.patch patches.suse/x86-sgx-set-active-memcg-prior-to-shmem-allocation.patch + patches.suse/x86-kexec-fix-memory-leak-of-elf-header-buffer.patch patches.suse/dma-debug-make-things-less-spammy-under-memory-press.patch patches.suse/mmc-block-Fix-CQE-recovery-reset-success.patch patches.suse/Input-bcm5974-set-missing-URB_NO_TRANSFER_DMA_MAP-ur.patch patches.suse/Input-soc_button_array-also-add-Lenovo-Yoga-Tablet2-.patch patches.suse/KEYS-trusted-tpm2-Fix-migratable-logic.patch + patches.suse/KVM-SVM-fix-tsc-scaling-cache-logic.patch patches.suse/0001-KVM-x86-do-not-report-a-vCPU-as-preempted-outside-in.patch patches.suse/drm-imx-fix-compiler-warning-with-gcc-12.patch patches.suse/mellanox-mlx5-avoid-uninitialized-variable-warning-w.patch patches.suse/net-phy-dp83867-retrigger-SGMII-AN-when-link-change.patch + patches.suse/net-ethernet-bgmac-Fix-refcount-leak-in-bcma_mdio_mi.patch + patches.suse/stmmac-intel-Fix-an-error-handling-path-in-intel_eth.patch + patches.suse/net-dsa-lantiq_gswip-Fix-refcount-leak-in-gswip_gphy.patch patches.suse/net-mlx4_en-Fix-wrong-return-value-on-ioctl-EEPROM-q.patch patches.suse/net-mdio-unexport-__init-annotated-mdio_bus_init.patch patches.suse/net-xfrm-unexport-__init-annotated-xfrm4_protocol_in.patch @@ -14401,6 +14873,8 @@ patches.suse/nfc-nfcmrvl-Fix-memory-leak-in-nfcmrvl_play_deferred.patch patches.suse/net-ethernet-mtk_eth_soc-fix-misuse-of-mem-alloc-int.patch patches.suse/net-openvswitch-fix-misuse-of-the-cached-connection-.patch + patches.suse/net-altera-Fix-refcount-leak-in-altera_tse_mdio_crea.patch + patches.suse/net-dsa-mv88e6xxx-use-BMSR_ANEGCOMPLETE-bit-for-fill.patch patches.suse/ixgbe-fix-bcast-packets-Rx-on-VF-after-promisc-remov.patch patches.suse/ixgbe-fix-unexpected-VLAN-Rx-in-promisc-mode-on-VF.patch patches.suse/powerpc-Don-t-select-HAVE_IRQ_EXIT_ON_IRQ_STACK.patch @@ -14483,7 +14957,11 @@ patches.suse/Documentation-add-description-for-net.sctp.reconf_en.patch patches.suse/Documentation-add-description-for-net.sctp.intl_enab.patch patches.suse/Documentation-add-description-for-net.sctp.ecn_enabl.patch + patches.suse/net-hns3-set-port-base-vlan-tbl_sta-to-false-before-.patch + patches.suse/net-hns3-don-t-push-link-state-to-VF-if-unalive.patch patches.suse/octeontx2-vf-Add-support-for-adaptive-interrupt-coal.patch + patches.suse/mlxsw-spectrum_cnt-Reorder-counter-pools.patch + patches.suse/net-bgmac-Fix-an-erroneous-kfree-in-bgmac_remove.patch patches.suse/ice-Fix-PTP-TX-timestamp-offset-calculation.patch patches.suse/ice-Sync-VLAN-filtering-features-for-DVM.patch patches.suse/ice-Fix-queue-config-fail-handling.patch @@ -14512,6 +14990,7 @@ patches.suse/arm64-ftrace-fix-branch-range-checks.patch patches.suse/arm64-ftrace-consistently-handle-PLTs.patch patches.suse/arm64-mm-Don-t-invalidate-FROM_DEVICE-buffers-at-start-of-DMA-transfer.patch + patches.suse/x86-PCI-Revert-x86-PCI-Clip-only-host-bridge-windows.patch patches.suse/pNFS-Don-t-keep-retrying-if-the-server-replied-NFS4E.patch patches.suse/pNFS-Avoid-a-live-lock-condition-in-pnfs_update_layo.patch patches.suse/ext4-fix-super-block-checksum-incorrect-after-mount.patch @@ -14556,6 +15035,7 @@ patches.suse/mmc-mediatek-wait-dma-stop-bit-reset-to-0.patch patches.suse/phy-aquantia-Fix-AN-when-higher-speeds-than-1G-are-n.patch patches.suse/igb-fix-a-use-after-free-issue-in-igb_clean_tx_ring.patch + patches.suse/bonding-ARP-monitor-spams-NETDEV_NOTIFY_PEERS-notifi.patch patches.suse/0001-ethtool-Fix-get-module-eeprom-fallback.patch patches.suse/net-phy-smsc-Disable-Energy-Detect-Power-Down-in-int.patch patches.suse/selftests-netfilter-correct-PKTGEN_SCRIPT_PATHS-in-n.patch @@ -14577,6 +15057,9 @@ patches.suse/drm-msm-mdp4-Fix-refcount-leak-in-mdp4_modeset_init_.patch patches.suse/drm-msm-dp-check-core_initialized-before-disable-int.patch patches.suse/drm-msm-dp-force-link-training-for-display-resolutio.patch + patches.suse/xen-blkfront-Handle-NULL-gendisk.patch + patches.suse/x86-xen-Remove-undefined-behavior-in-setup_features.patch + patches.suse/xen-gntdev-Avoid-blocking-in-unmap_grant_pages.patch patches.suse/s390-crash-make-copy_oldmem_page-return-number-of-bytes-copied patches.suse/s390-cpumf-Handle-events-cycles-and-instructions-identical patches.suse/regmap-irq-Fix-a-bug-in-regmap_irq_enable-for-type_i.patch @@ -14585,6 +15068,7 @@ patches.suse/usb-gadget-Fix-non-unique-driver-names-in-raw-gadget.patch patches.suse/dt-bindings-usb-ohci-Increase-the-number-of-PHYs.patch patches.suse/dt-bindings-usb-ehci-Increase-the-number-of-PHYs.patch + patches.suse/usb-typec-wcove-Drop-wrong-dependency-to-INTEL_SOC_P.patch patches.suse/USB-serial-option-add-Telit-LE910Cx-0x1250-compositi.patch patches.suse/USB-serial-pl2303-add-support-for-more-HXN-G-types.patch patches.suse/USB-serial-option-add-Quectel-EM05-G-modem.patch @@ -14618,6 +15102,8 @@ patches.suse/powerpc-Enable-execve-syscall-exit-tracepoint.patch patches.suse/powerpc-rtas-Allow-ibm-platform-dump-RTAS-call-with-.patch patches.suse/powerpc-powernv-wire-up-rng-during-setup_arch.patch + patches.suse/0008-parisc-stifb-Fix-fb_is_primary_device-only-available.patch + patches.suse/video-fbdev-pxa3xx-gcu-Fix-integer-overflow-in-pxa3x.patch patches.suse/ARM-dts-imx7-Move-hsic_phy-power-domain-to-HSIC-PHY-.patch patches.suse/ARM-dts-imx6qdl-correct-PU-regulator-ramp-delay.patch patches.suse/ARM-Fix-refcount-leak-in-axxia_boot_secondary.patch @@ -14645,11 +15131,16 @@ patches.suse/platform-x86-hp-wmi-Ignore-Sanitization-Mode-event.patch patches.suse/RDMA-qedr-Fix-reporting-QP-timeout-attribute.patch patches.suse/linux-dim-Fix-divide-by-0-in-RDMA-DIM.patch + patches.suse/net-dsa-hirschmann-Add-missing-of_node_get-in-hellcr.patch + patches.suse/net-dsa-bcm_sf2-force-pause-link-settings.patch patches.suse/selftests-net-pass-ipv6_args-to-udpgso_bench-s-IPv6-.patch + patches.suse/net-dp83822-disable-false-carrier-interrupt.patch + patches.suse/net-dp83822-disable-rx-error-interrupt.patch patches.suse/tunnels-do-not-assume-mac-header-is-set-in-skb_tunne.patch patches.suse/epic100-fix-use-after-free-on-rmmod.patch patches.suse/net-asix-fix-can-t-send-until-first-packet-is-send-i.patch patches.suse/net-usb-asix-do-not-force-pause-frames-support.patch + patches.suse/net-bonding-fix-possible-NULL-deref-in-rlb-code.patch patches.suse/selftests-mptcp-more-stable-diag-tests.patch patches.suse/net-ipv6-unexport-__init-annotated-seg6_hmac_net_ini.patch patches.suse/nfc-nfcmrvl-Fix-irq_of_parse_and_map-return-value.patch @@ -14658,6 +15149,7 @@ patches.suse/usbnet-fix-memory-allocation-in-helpers.patch patches.suse/net-phy-Don-t-trigger-state-machine-while-in-suspend.patch patches.suse/net-phy-ax88772a-fix-lost-pause-advertisement-config.patch + patches.suse/net-bonding-fix-use-after-free-after-802.3ad-slave-u.patch patches.suse/net-usb-ax88179_178a-Fix-packet-receiving.patch patches.suse/net-rose-fix-UAF-bugs-caused-by-timer-handler.patch patches.suse/drm-i915-gem-add-missing-else.patch @@ -14665,11 +15157,13 @@ patches.suse/drm-amdgpu-To-flush-tlb-for-MMHUB-of-RAVEN-series.patch patches.suse/Revert-drm-amdgpu-display-set-vblank_disable_immedia.patch patches.suse/dm-raid-fix-KASAN-warning-in-raid5_add_disks.patch + patches.suse/s390-qdio-Fix-spelling-mistake patches.suse/hwmon-occ-Prevent-power-cap-command-overwriting-poll.patch patches.suse/hwmon-ibmaem-don-t-call-platform_device_del-if-platf.patch patches.suse/PM-devfreq-exynos-ppmu-Fix-refcount-leak-in-of_get_d.patch patches.suse/drivers-cpufreq-Add-missing-of_node_put-in-qoriq-cpu.patch patches.suse/cpufreq-pmac32-cpufreq-Fix-refcount-leak-bug.patch + patches.suse/NFSD-restore-EINVAL-error-translation-in-nfsd_commit.patch patches.suse/SUNRPC-Fix-READ_PLUS-crasher.patch patches.suse/xfs-use-invalidate_lock-to-check-the-state-of-mmap_l.patch patches.suse/xfs-prevent-a-UAF-when-log-IO-errors-race-with-unmou.patch @@ -14717,8 +15211,10 @@ patches.suse/ASoC-wcd938x-Fix-event-generation-for-some-controls.patch patches.suse/ASoC-Intel-bytcr_wm5102-Fix-GPIO-related-probe-order.patch patches.suse/ASoC-wm5110-Fix-DRE-control.patch + patches.suse/ASoC-cs35l41-Correct-some-control-names.patch patches.suse/ASoC-rt711-sdca-fix-kernel-NULL-pointer-dereference-.patch patches.suse/ASoC-dapm-Initialise-kcontrol-data-for-mux-demux-con.patch + patches.suse/ASoC-cs35l41-Add-ASP-TX3-4-source-to-register-patch.patch patches.suse/ASoC-cs47l15-Fix-event-generation-for-low-power-mux-.patch patches.suse/ASoC-madera-Fix-event-generation-for-OUT1-demux.patch patches.suse/ASoC-madera-Fix-event-generation-for-rate-controls.patch @@ -14737,6 +15233,8 @@ patches.suse/can-m_can-m_can_chip_config-actually-enable-internal.patch patches.suse/can-mcp251xfd-mcp251xfd_regmap_crc_read-improve-work.patch patches.suse/can-mcp251xfd-mcp251xfd_regmap_crc_read-update-worka.patch + patches.suse/can-mcp251xfd-mcp251xfd_register_get_dev_id-use-corr.patch + patches.suse/can-mcp251xfd-mcp251xfd_register_get_dev_id-fix-endi.patch patches.suse/selftests-forwarding-fix-flood_unicast_test-when-h2-.patch patches.suse/selftests-forwarding-fix-learning_test-when-h1-suppo.patch patches.suse/selftests-forwarding-fix-error-message-in-learning_t.patch @@ -14752,6 +15250,7 @@ patches.suse/iommu-vt-d-Fix-RID2PASID-setup-teardown-failure patches.suse/memregion-Fix-memregion_free-fallback-definition.patch patches.suse/ACPI-CPPC-Only-probe-for-_CPC-if-CPPC-v2-is-acked.patch + patches.suse/ACPI-CPPC-Don-t-require-_OSC-if-X86_FEATURE_CPPC-is-.patch patches.suse/powerpc-powernv-delay-rng-platform-device-creation-u.patch patches.suse/i2c-piix4-Fix-a-memory-leak-in-the-EFCH-MMIO-support.patch patches.suse/i2c-cadence-Unregister-the-clk-notifier-in-error-pat.patch @@ -14777,7 +15276,7 @@ patches.suse/x86-Undo-return-thunk-damage.patch patches.suse/x86-objtool-Create-.return_sites.patch patches.suse/x86-static_call-Use-alternative-RET-encoding.patch - patches.suse/x86-ftrace-Use-alternative-RET-encoding.patch + patches.suse/x86-ftrace-use-alternative-ret-encoding.patch patches.suse/x86-bpf-Use-alternative-RET-encoding.patch patches.suse/x86-kvm-Fix-SETcc-emulation-for-return-thunks.patch patches.suse/x86-vsyscall_emu-64-Don-t-use-RET-in-vsyscall-emulation.patch @@ -14848,6 +15347,7 @@ patches.suse/ima-force-signature-verification-when-CONFIG_KEXEC_S.patch patches.suse/ima-Fix-potential-memory-leak-in-ima_init_crypto.patch patches.suse/net-stmmac-dwc-qos-Disable-split-header-for-Tegra194.patch + patches.suse/net-ethernet-ti-am65-cpsw-Fix-devlink-port-register-.patch patches.suse/net-mlx5-TC-allow-offload-from-uplink-to-other-PF-s-.patch patches.suse/net-mlx5-Lag-decouple-FDB-selection-and-shared-FDB.patch patches.suse/net-mlx5e-kTLS-Fix-build-time-constant-test-in-TX.patch @@ -14873,6 +15373,8 @@ patches.suse/sysctl-Fix-data-races-in-proc_dointvec_ms_jiffies.patch patches.suse/raw-Fix-a-data-race-around-sysctl_raw_l3mdev_accept.patch patches.suse/tcp-Fix-data-races-around-sysctl_tcp_ecn.patch + patches.suse/net-ftgmac100-Hold-reference-returned-by-of_get_chil.patch + patches.suse/net-stmmac-fix-leaks-in-probe.patch patches.suse/wifi-mac80211_hwsim-set-virtio-device-ready-in-probe.patch patches.suse/wifi-mac80211-fix-queue-selection-for-mesh-OCB-inter.patch patches.suse/sfc-fix-use-after-free-when-disabling-sriov.patch @@ -14886,6 +15388,7 @@ patches.suse/drm-i915-gt-Serialize-TLB-invalidates-with-GT-resets.patch patches.suse/drm-amd-display-Ignore-First-MST-Sideband-Message-Re.patch patches.suse/drm-amd-display-Only-use-depth-36-bpp-linebuffers-on.patch + patches.suse/xen-gntdev-Ignore-failure-to-unmap-INVALID_GRANT_HAN.patch patches.suse/ACPI-video-Fix-acpi_video_handles_brightness_key_pre.patch patches.suse/arm64-dts-rockchip-Assign-RK3399-VDU-clock-rate.patch patches.suse/reset-Fix-devm-bulk-optional-exclusive-control-gette.patch @@ -14898,6 +15401,7 @@ patches.suse/spi-amd-Limit-max-transfer-and-message-size.patch patches.suse/kvm-emulate-do-not-adjust-size-of-fastop-and-setcc-subroutines.patch patches.suse/efi-x86-use-naked-RET-on-mixed-mode-call-wrapper.patch + patches.suse/ACPI-CPPC-Fix-enabling-CPPC-on-AMD-systems-with-shar.patch patches.suse/tty-serial-samsung_tty-set-dma-burst_size-to-1.patch patches.suse/serial-pl011-UPSTAT_AUTORTS-requires-.throttle-unthr.patch patches.suse/serial-stm32-Clear-prev-values-before-setting-RTS-de.patch @@ -14918,9 +15422,14 @@ patches.suse/watchqueue-make-sure-to-serialize-wqueue-defunct-pro.patch patches.suse/watch-queue-remove-spurious-double-semicolon.patch patches.suse/mm-Force-TLB-flush-for-PFNMAP-mappings-before-unlink_file_vma.patch + patches.suse/ip-Fix-data-races-around-sysctl_ip_fwd_update_priori.patch + patches.suse/net-stmmac-fix-pm-runtime-issue-in-stmmac_dvr_remove.patch + patches.suse/net-stmmac-fix-unbalanced-ptp-clock-issue-in-suspend.patch + patches.suse/net-dsa-microchip-ksz_common-Fix-refcount-leak-bug.patch patches.suse/e1000e-Enable-GPT-clock-before-sending-message-to-CS.patch patches.suse/Revert-e1000e-Fix-possible-HW-unit-hang-after-an-s0i.patch patches.suse/igc-Reinstate-IGC_REMOVED-logic-and-implement-it-pro.patch + patches.suse/net-stmmac-fix-dma-queue-left-shift-overflow-issue.patch patches.suse/docs-net-dsa-update-probing-documentation.patch patches.suse/docs-net-dsa-document-the-shutdown-behavior.patch patches.suse/docs-net-dsa-rename-tag_protocol-to-get_tag_protocol.patch @@ -14934,7 +15443,10 @@ patches.suse/docs-net-dsa-re-explain-what-port_fdb_dump-actually-.patch patches.suse/i40e-Fix-erroneous-adapter-reinitialization-during-r.patch patches.suse/ixgbe-Add-locking-to-prevent-panic-when-setting-srio.patch + patches.suse/net-stmmac-remove-redunctant-disable-xPCS-EEE-call.patch patches.suse/0001-be2net-Fix-buffer-overflow-in-be_get_module_eeprom.patch + patches.suse/net-dsa-sja1105-silent-spi_device_id-warnings.patch + patches.suse/net-dsa-vitesse-vsc73xx-silent-spi_device_id-warning.patch patches.suse/r8152-fix-a-WOL-issue.patch patches.suse/Documentation-fix-udp_wmem_min-in-ip-sysctl.rst.patch patches.suse/iavf-Fix-VLAN_V2-addition-rejection.patch @@ -14942,7 +15454,9 @@ patches.suse/iavf-Fix-handling-of-dummy-receive-descriptors.patch patches.suse/iavf-Fix-missing-state-logs.patch patches.suse/xfrm-xfrm_policy-fix-a-possible-double-xfrm_pols_put.patch + patches.suse/ipv4-Fix-data-races-around-sysctl_fib_multipath_hash.patch patches.suse/tcp-Fix-data-races-around-sysctl-knobs-related-to-SY.patch + patches.suse/mlxsw-spectrum_router-Fix-IPv4-nexthop-gateway-indic.patch patches.suse/mtd-rawnand-gpmi-Set-WAIT_FOR_READY-timeout-based-on.patch patches.suse/drm-amdgpu-Remove-one-duplicated-ef-removal.patch patches.suse/drm-ttm-fix-locking-in-vmap-vunmap-TTM-GEM-helpers.patch @@ -14953,6 +15467,7 @@ patches.suse/gpio-gpio-xilinx-Fix-integer-overflow.patch patches.suse/i2c-mlxcpld-Fix-register-setting-for-400KHz-frequenc.patch patches.suse/i2c-cadence-Change-large-transfer-count-reset-logic-.patch + patches.suse/ACPI-CPPC-Don-t-require-flexible-address-space-if-X8.patch patches.suse/spi-bcm2835-bcm2835_spi_handle_err-fix-NULL-pointer-.patch patches.suse/spi-spi-rspi-Fix-PIO-fallback-on-RZ-platforms.patch patches.suse/lkdtm-disable-return-thunks-in-rodata-c.patch @@ -14960,13 +15475,17 @@ patches.suse/asm-generic-remove-a-broken-and-needless-ifdef-condi.patch patches.suse/watch_queue-Fix-missing-rcu-annotation.patch patches.suse/watch_queue-Fix-missing-locking-in-add_watch_to_obje.patch + patches.suse/net-pcs-xpcs-propagate-xpcs_read-error-to-xpcs_get_s.patch + patches.suse/net-sungem_phy-Add-of_node_put-for-reference-returne.patch patches.suse/Documentation-fix-sctp_wmem-in-ip-sysctl.rst.patch + patches.suse/s390-qeth-Fix-typo-the-the-in-comment patches.suse/macsec-fix-NULL-deref-in-macsec_add_rxsa.patch patches.suse/macsec-fix-error-message-in-macsec_add_rxsa-and-_txs.patch patches.suse/macsec-limit-replay-window-size-with-XPN.patch patches.suse/macsec-always-read-MACSEC_SA_ATTR_PN-as-a-u64.patch patches.suse/net-macsec-fix-potential-resource-leak-in-macsec_add.patch patches.suse/i40e-Fix-interface-init-with-MSI-interrupts-no-MSI-X.patch + patches.suse/octeontx2-pf-cn10k-Fix-egress-ratelimit-configuratio.patch patches.suse/Bluetooth-L2CAP-Fix-use-after-free-caused-by-l2cap_c.patch patches.suse/netfilter-nf_queue-do-not-allow-packet-truncation-be.patch patches.suse/virtio-net-fix-the-race-between-refill-work-and-clos.patch @@ -15061,8 +15580,11 @@ patches.suse/regulator-of-Fix-refcount-leak-bug-in-of_get_regulat.patch patches.suse/spi-spi-altera-dfl-Fix-an-error-handling-path.patch patches.suse/spi-synquacer-Add-missing-clk_disable_unprepare.patch + patches.suse/spi-pxa2xx-Add-support-for-Intel-Meteor-Lake-P.patch patches.suse/spi-dt-bindings-cadence-add-missing-required.patch patches.suse/spi-dt-bindings-zynqmp-qspi-add-missing-required.patch + patches.suse/spi-Return-deferred-probe-error-when-controller-isn-.patch + patches.suse/spi-propagate-error-code-to-the-caller-of-acpi_spi_d.patch patches.suse/spi-Fix-simplification-of-devm_spi_register_controll.patch patches.suse/spi-tegra20-slink-fix-UAF-in-tegra_slink_remove.patch patches.suse/pwm-lpc18xx-Fix-period-handling.patch @@ -15082,6 +15604,8 @@ patches.suse/ACPI-video-Shortening-quirk-list-by-identifying-Clev.patch patches.suse/Documentation-ACPI-EINJ-Fix-obsolete-example.patch patches.suse/PM-hibernate-defer-device-probing-when-resuming-from.patch + patches.suse/powercap-intel_rapl-Add-support-for-RAPTORLAKE_P.patch + patches.suse/powercap-RAPL-Add-Power-Limit4-support-for-Alder-Lake-N-and-Raptor-Lake-P.patch patches.suse/PM-domains-Ensure-genpd_debugfs_dir-exists-before-re.patch patches.suse/Documentation-PM-Drop-pme_interrupt-reference.patch patches.suse/thermal-tools-tmon-Include-pthread-and-time-headers-.patch @@ -15089,6 +15613,12 @@ patches.suse/selftests-seccomp-Fix-compile-warning-when-CC-clang.patch patches.suse/selinux-fix-memleak-in-security_read_state_kernel.patch patches.suse/selinux-Add-boundary-check-in-put_entry.patch + patches.suse/kexec_file-drop-weak-attribute-from-functions.patch + patches.suse/kexec-drop-weak-attribute-from-functions.patch + patches.suse/kexec-clean-up-arch_kexec_kernel_verify_sig.patch + patches.suse/kexec-KEYS-make-the-code-in-bzImage64_verify_sig-gen.patch + patches.suse/arm64-kexec_file-use-more-system-keyrings-to-verify-.patch + patches.suse/kexec-KEYS-s390-Make-use-of-built-in-and-secondary-k.patch patches.suse/crypto-ccp-Use-kzalloc-for-sev-ioctl-interfaces-to-p.patch patches.suse/crypto-sun8i-ss-fix-error-codes-in-allocate_flows.patch patches.suse/crypto-sun8i-ss-fix-infinite-loop-in-sun8i_ss_setup_.patch @@ -15126,6 +15656,7 @@ patches.suse/igb-Remove-duplicate-defines.patch patches.suse/ixgbe-Fix-typos-in-comments.patch patches.suse/drivers-net-ethernet-intel-fix-typos-in-comments.patch + patches.suse/ethernet-Remove-vf-rate-limit-check-for-drivers.patch patches.suse/net-mlx5-Introduce-header-modify-pattern-ICM-propert.patch patches.suse/net-mlx5-Manage-ICM-of-type-modify-header-pattern.patch patches.suse/RDMA-mlx5-Support-handling-of-modify-header-pattern-.patch @@ -15136,6 +15667,8 @@ patches.suse/net-mlx5-Remove-not-used-MLX5_CAP_BITS_RW_MASK.patch patches.suse/net-mlx5-Add-bits-and-fields-to-support-enhanced-CQE.patch patches.suse/i40e-add-xdp-frags-support-to-ndo_xdp_xmit.patch + patches.suse/msft-hv-2623-net-mana-Add-the-Linux-MANA-PF-driver.patch + patches.suse/msft-hv-2624-net-mana-Add-support-of-XDP_REDIRECT-action.patch patches.suse/mlxsw-Keep-track-of-number-of-allocated-RIFs.patch patches.suse/mlxsw-Add-a-resource-describing-number-of-RIFs.patch patches.suse/sfc-Fix-typo-in-comment.patch @@ -15185,6 +15718,7 @@ patches.suse/ice-Remove-unnecessary-NULL-check-before-dev_put.patch patches.suse/cxgb4-Fix-typo-in-string.patch patches.suse/qlogic-qed-fix-repeated-words-in-comments.patch + patches.suse/net-add-skb_-inner_-tcp_all_headers-helpers.patch patches.suse/net-mlx5-Delete-ipsec_fs-header-file-as-not-used.patch patches.suse/net-mlx5-delete-dead-code-in-mlx5_esw_unlock.patch patches.suse/net-mlx5-E-switch-Introduce-flag-to-indicate-if-vpor.patch @@ -15313,6 +15847,7 @@ patches.suse/i40e-Refactor-tc-mqprio-checks.patch patches.suse/iavf-Check-for-duplicate-TC-flower-filter-before-par.patch patches.suse/wifi-mac80211_hwsim-use-32-bit-skb-cookie.patch + patches.suse/wifi-mac80211-refactor-elements-parsing-with-paramet.patch patches.suse/wifi-mac80211-limit-A-MSDU-subframes-for-client-too.patch patches.suse/mt76-mt76x02u-fix-possible-memory-leak-in-__mt76x02u.patch patches.suse/mt76-mt7615-do-not-update-pm-stats-in-case-of-error.patch @@ -15409,15 +15944,20 @@ patches.suse/i2c-npcm-Capitalize-the-one-line-comment.patch patches.suse/i2c-mxs-Silence-a-clang-warning.patch patches.suse/i2c-Fix-a-potential-use-after-free.patch + patches.suse/i2c-i801-Add-support-for-Intel-Meteor-Lake-P.patch patches.suse/i2c-cadence-Support-PEC-for-SMBus-block-read.patch patches.suse/i2c-mux-gpmux-Add-of_node_put-when-breaking-out-of-l.patch patches.suse/media-atmel-atmel-sama7g5-isc-fix-warning-in-configs.patch patches.suse/media-tw686x-Register-the-irq-at-the-end-of-probe.patch + patches.suse/media-imx-jpeg-Correct-some-definition-according-spe.patch + patches.suse/media-imx-jpeg-Leave-a-blank-space-before-the-config.patch patches.suse/media-pvrusb2-fix-memory-leak-in-pvr_probe.patch + patches.suse/media-imx-jpeg-Disable-slot-interrupt-when-frame-don.patch patches.suse/media-hdpvr-fix-error-value-returns-in-hdpvr_read.patch patches.suse/media-v4l2-mem2mem-prevent-pollerr-when-last_buffer_.patch patches.suse/media-driver-nxp-imx-jpeg-fix-a-unexpected-return-va.patch patches.suse/media-tw686x-Fix-memory-leak-in-tw686x_video_init.patch + patches.suse/media-platform-mtk-mdp-Fix-mdp_ipi_comm-structure-al.patch patches.suse/media-PATCH-pci-atomisp_cmd-fix-three-missing-checks.patch patches.suse/media-cedrus-h265-Fix-flag-name.patch patches.suse/media-cedrus-hevc-Add-check-for-invalid-timestamp.patch @@ -15429,6 +15969,7 @@ patches.suse/virtio-gpu-fix-a-missing-check-to-avoid-NULL-derefer.patch patches.suse/udmabuf-Set-the-DMA-mask-for-the-udmabuf-device-v2.patch patches.suse/drm-adv7511-override-i2c-address-of-cec-before-acces.patch + patches.suse/0009-fbcon-Fix-accelerated-fbdev-scrolling-while-logo-is-.patch patches.suse/fbcon-Fix-boundary-checks-for-fbcon-vc-n1-n2-paramet.patch patches.suse/drm-bridge-adv7511-Add-check-for-mipi_dsi_driver_reg.patch patches.suse/drm-mcde-Fix-refcount-leak-in-mcde_dsi_bind.patch @@ -15454,6 +15995,7 @@ patches.suse/drm-rockchip-vop-Don-t-crash-for-invalid-duplicate_s.patch patches.suse/drm-rockchip-Fix-an-error-handling-path-rockchip_dp_.patch patches.suse/drm-bridge-sii8620-fix-possible-off-by-one.patch + patches.suse/drm-tegra-vic-Fix-build-warning-when-CONFIG_PM-n.patch patches.suse/drm-mediatek-Modify-dsi-funcs-to-atomic-operations.patch patches.suse/drm-mediatek-Separate-poweron-poweroff-from-enable-d.patch patches.suse/drm-mediatek-Keep-dsi-as-LP00-before-dcs-cmds-transf.patch @@ -15579,6 +16121,7 @@ patches.suse/usb-dwc2-gadget-remove-D-pull-up-while-no-vbus-with-.patch patches.suse/usb-core-sysfs-convert-sysfs-snprintf-to-sysfs_emit.patch patches.suse/dt-bindings-usb-mtk-xhci-Allow-wakeup-interrupt-name.patch + patches.suse/thunderbolt-Add-support-for-Intel-Raptor-Lake.patch patches.suse/usb-host-xhci-use-snprintf-in-xhci_decode_trb.patch patches.suse/gadgetfs-ep_io-wait-until-IRQ-finishes.patch patches.suse/usb-dwc3-gadget-refactor-dwc3_repare_one_trb.patch @@ -15590,6 +16133,7 @@ patches.suse/USB-serial-fix-tty-port-initialized-comments.patch patches.suse/USB-HCD-Fix-URB-giveback-issue-in-tasklet-function.patch patches.suse/usb-core-fix-repeated-words-in-comments.patch + patches.suse/usb-renesas-xhci-Do-not-print-any-log-while-fw-verif.patch patches.suse/usb-cdns3-change-place-of-priv_ep-assignment-in-cdns.patch patches.suse/usb-typec-ucsi-Acknowledge-the-GET_ERROR_STATUS-comm.patch patches.suse/usb-cdns3-Don-t-use-priv_dev-uninitialized-in-cdns3_.patch @@ -15603,6 +16147,7 @@ patches.suse/KVM-nVMX-Snapshot-pre-VM-Enter-DEBUGCTL-for-nested_r.patch patches.suse/KVM-x86-Mark-TSS-busy-during-LTR-emulation-_after_-a.patch patches.suse/KVM-x86-Set-error-code-to-segment-selector-on-LLDT-L.patch + patches.suse/KVM-s390-pv-don-t-present-the-ecall-interrupt-twice patches.suse/KVM-nVMX-Inject-UD-if-VMXON-is-attempted-with-incomp.patch patches.suse/KVM-nVMX-Let-userspace-set-nVMX-MSR-to-any-_host_-su.patch patches.suse/KVM-nVMX-Set-UMIP-bit-CR4_FIXED1-MSR-when-emulating-.patch @@ -15623,7 +16168,6 @@ patches.suse/pinctrl-intel-Check-against-matching-data-instead-of.patch patches.suse/gpio-gpiolib-of-Fix-refcount-bugs-in-of_mm_gpiochip_.patch patches.suse/clk-mediatek-reset-Fix-written-reset-bit-offset.patch - patches.suse/clk-ti-Stop-using-legacy-clkctrl-names-for-omap4-and.patch patches.suse/clk-renesas-r9a06g032-Fix-UART-clkgrp-bitsel.patch patches.suse/clk-qcom-camcc-sm8250-Fix-halt-on-boot-by-reducing-d.patch patches.suse/clk-qcom-clk-krait-unlock-spin-after-mux-completion.patch @@ -15676,6 +16220,7 @@ patches.suse/memstick-ms_block-Fix-some-incorrect-memory-allocati.patch patches.suse/memstick-ms_block-Fix-a-memory-leak.patch patches.suse/mmc-tmio-avoid-glitches-when-resetting.patch + patches.suse/mmc-core-Replace-with-already-defined-values-for-rea.patch patches.suse/mmc-sdhci-of-at91-fix-set_uhs_signaling-rewriting-of.patch patches.suse/mmc-block-Add-single-read-for-4k-sector-cards.patch patches.suse/mmc-cavium-octeon-Add-of_node_put-when-breaking-out-.patch @@ -15731,7 +16276,10 @@ patches.suse/scsi-lpfc-Remove-Menlo-Hornet-related-code.patch patches.suse/scsi-lpfc-Update-lpfc-version-to-14.2.0.5.patch patches.suse/scsi-lpfc-Copyright-updates-for-14.2.0.5-patches.patch + patches.suse/scsi-smartpqi-Shorten-drive-visibility-after-removal.patch patches.suse/scsi-smartpqi-Fix-DMA-direction-for-RAID-requests.patch + patches.suse/scsi-smartpqi-Add-module-param-to-disable-managed-ints.patch + patches.suse/scsi-Revert-scsi-qla2xxx-Fix-disk-failure-to-rediscover.patch patches.suse/scsi-qla2xxx-Fix-incorrect-display-of-max-frame-size.patch patches.suse/scsi-qla2xxx-Zero-undefined-mailbox-IN-registers.patch patches.suse/scsi-qla2xxx-Fix-response-queue-handler-reading-stal.patch @@ -15765,6 +16313,7 @@ patches.suse/RDMA-mlx5-Store-in-the-cache-mkeys-instead-of-mrs.patch patches.suse/RDMA-mlx5-Rename-the-mkey-cache-variables-and-functi.patch patches.suse/RDMA-mlx5-Add-missing-check-for-return-value-in-get-.patch + patches.suse/md-unlock-mddev-before-reap-sync_thread-in-action_st.patch patches.suse/0001-crypto-add-crypto_has_shash.patch patches.suse/0002-crypto-add-crypto_has_kpp.patch patches.suse/0003-lib-base64-RFC4648-compliant-base64-encoding.patch @@ -15776,6 +16325,7 @@ patches.suse/0009-nvmet-Implement-basic-In-Band-Authentication.patch patches.suse/0010-nvmet-auth-Diffie-Hellman-key-exchange-support.patch patches.suse/0011-nvmet-auth-expire-authentication-sessions.patch + patches.suse/md-raid10-fix-KASAN-warning.patch patches.suse/jbd2-fix-outstanding-credits-assert-in-jbd2_journal_.patch patches.suse/ext4-recover-csum-seed-of-tmp_inode-after-migrating-.patch patches.suse/ext4-check-if-directory-block-is-within-i_size.patch @@ -15813,35 +16363,72 @@ patches.suse/tpm-eventlog-Fix-section-mismatch-for-DEBUG_SECTION_.patch patches.suse/ALSA-usb-audio-Support-jack-detection-on-Dell-dock.patch patches.suse/ALSA-usb-audio-Turn-off-manual-mode-on-Dell-dock.patch + patches.suse/ALSA-hda-cs8409-change-cs8409_fixups-v.pins-initiali.patch patches.suse/ALSA-usb-audio-Add-endianness-annotations.patch + patches.suse/ALSA-hda-cs35l41-Fix-comments-wrt-serial-multi-insta.patch + patches.suse/ALSA-hda-cs35l41-Improve-dev_err_probe-messaging.patch + patches.suse/ALSA-hda-cs35l41-Don-t-dereference-fwnode-handle.patch + patches.suse/ALSA-hda-cs35l41-Allow-compilation-test-on-non-ACPI-.patch + patches.suse/ALSA-hda-cs35l41-Drop-wrong-use-of-ACPI_PTR.patch + patches.suse/ALSA-hda-cs35l41-Consolidate-selections-under-SND_HD.patch + patches.suse/ALSA-hda-hda_cs_dsp_ctl-Add-Library-to-support-CS_DS.patch + patches.suse/ALSA-hda-hda_cs_dsp_ctl-Add-apis-to-write-the-contro.patch + patches.suse/ALSA-hda-cs35l41-Save-codec-object-inside-component-.patch + patches.suse/ALSA-hda-cs35l41-Add-initial-DSP-support-and-firmwar.patch + patches.suse/ALSA-hda-cs35l41-Save-Subsystem-ID-inside-CS35L41-Dr.patch + patches.suse/ALSA-hda-cs35l41-Support-reading-subsystem-id-from-A.patch + patches.suse/ALSA-hda-cs35l41-Support-multiple-load-paths-for-fir.patch + patches.suse/ALSA-hda-cs35l41-Support-Speaker-ID-for-laptops.patch patches.suse/ALSA-bcd2000-Fix-a-UAF-bug-on-the-error-path-of-prob.patch patches.suse/ASoC-cros_ec_codec-Fix-refcount-leak-in-cros_ec_code.patch patches.suse/ASoC-samsung-Fix-error-handling-in-aries_audio_probe.patch patches.suse/ASoC-imx-audmux-Silence-a-clang-warning.patch patches.suse/ASoC-mt6797-mt6351-Fix-refcount-leak-in-mt6797_mt635.patch patches.suse/ASoC-codecs-da7210-add-check-for-i2c_add_driver.patch + patches.suse/ASoC-cs35l41-Move-cs35l41-exit-hibernate-function-in.patch + patches.suse/ASoC-cs35l41-Add-common-cs35l41-enter-hibernate-func.patch + patches.suse/ASoC-cs35l41-Do-not-print-error-when-waking-from-hib.patch patches.suse/ASoC-codecs-msm8916-wcd-digital-move-gains-from-SX_T.patch patches.suse/ASoC-codecs-wcd9335-move-gains-from-SX_TLV-to-S8_TLV.patch + patches.suse/ASoC-wm_adsp-Fix-event-for-preloader.patch + patches.suse/ASoC-cs35l41-Add-support-for-CLSA3541-ACPI-device-ID.patch patches.suse/ASoC-samsung-h1940_uda1380-include-proepr-GPIO-consu.patch patches.suse/ASoC-samsung-change-gpiod_speaker_power-and-rx1950_a.patch patches.suse/ASoC-samsung-change-neo1973_audio-from-a-global-to-s.patch + patches.suse/ASoC-wm_adsp-Minor-clean-and-redundant-code-removal.patch patches.suse/ASoC-qcom-Fix-missing-of_node_put-in-asoc_qcom_lpass.patch patches.suse/ASoC-imx-card-Fix-DSD-PDM-mclk-frequency.patch patches.suse/ASoC-mt6359-Fix-refcount-leak-bug.patch patches.suse/ASoC-rsnd-care-default-case-on-rsnd_ssiu_busif_err_i.patch + patches.suse/ALSA-hda-cs35l41-Support-Hibernation-during-Suspend.patch + patches.suse/ALSA-hda-cs35l41-Read-Speaker-Calibration-data-from-.patch + patches.suse/ALSA-hda-hda_cs_dsp_ctl-Add-fw-id-strings.patch + patches.suse/ALSA-hda-cs35l41-Add-defaulted-values-into-dsp-bypas.patch + patches.suse/ALSA-hda-cs35l41-Support-Firmware-switching-and-relo.patch + patches.suse/ALSA-hda-cs35l41-Add-module-parameter-to-control-fir.patch + patches.suse/Revert-ALSA-hda-cs35l41-Allow-compilation-test-on-no.patch patches.suse/ALSA-usb-audio-Add-quirk-for-Behringer-UMC202HD.patch + patches.suse/ALSA-hda-realtek-Enable-speaker-and-mute-LEDs-for-HP.patch + patches.suse/ALSA-hda-cs35l41-Use-the-CS35L41-HDA-internal-define.patch + patches.suse/ALSA-hda-cs35l41-Support-CLSA0101.patch + patches.suse/ACPI-scan-Add-CLSA0101-Laptop-Support.patch patches.suse/ALSA-core-Add-async-signal-helpers.patch patches.suse/ALSA-timer-Use-deferred-fasync-helper.patch patches.suse/ALSA-control-Use-deferred-fasync-helper.patch patches.suse/ALSA-hda-realtek-Add-quirk-for-Lenovo-Yoga9-14IAP7.patch patches.suse/ALSA-hda-realtek-Add-quirk-for-Clevo-NV45PZ.patch + patches.suse/ACPI-utils-Add-api-to-read-_SUB-from-ACPI.patch + patches.suse/ASoC-cs35l41-Read-System-Name-from-ACPI-_SUB-to-iden.patch patches.suse/ASoC-qcom-q6dsp-Fix-an-off-by-one-in-q6adm_alloc_cop.patch patches.suse/ASoC-audio-graph-card-Add-of_node_put-in-fail-path.patch patches.suse/ASoC-fsl_asrc-force-cast-the-asrc_format-type.patch patches.suse/ASoC-fsl-asoc-card-force-cast-the-asrc_format-type.patch patches.suse/ASoC-fsl_easrc-use-snd_pcm_format_t-type-for-sample_.patch patches.suse/ASoC-imx-card-use-snd_pcm_format_t-type-for-asrc_for.patch + patches.suse/firmware-cs_dsp-Add-pre_stop-callback.patch + patches.suse/firmware-cs_dsp-Add-memory-chunk-helpers.patch patches.suse/ASoC-mchp-spdifrx-disable-end-of-block-interrupt-on-.patch + patches.suse/ASoC-mchp-spdiftx-remove-references-to-mchp_i2s_caps.patch patches.suse/ALSA-hda-realtek-Add-quirk-for-HP-Spectre-x360-15-eb.patch patches.suse/mfd-t7l66xb-Drop-platform-disable-callback.patch patches.suse/mfd-max77620-Fix-refcount-leak-in-max77620_initialis.patch @@ -15855,6 +16442,7 @@ patches.suse/iommu-vt-d-Remove-global-g_iommus-array.patch patches.suse/iommu-vt-d-Make-DMAR_UNITS_SUPPORTED-default-1024.patch patches.suse/iommu-amd-Simplify-and-Consolidate-Virtual-APIC-AVIC-Enablement + patches.suse/selftests-powerpc-Skip-energy_scale_info-test-on-old.patch patches.suse/powerpc-perf-Optimize-clearing-the-pending-PMI-and-r.patch patches.suse/powerpc-pseries-hvcall.h-add-H_WATCHDOG-opcode-H_NOO.patch patches.suse/powerpc-pseries-add-FW_FEATURE_WATCHDOG-flag.patch @@ -15896,6 +16484,7 @@ patches.suse/exfat-Drop-superfluous-new-line-for-error-messages.patch patches.suse/fuse-limit-nsec.patch patches.suse/fuse-ioctl-translate-ENOSYS.patch + patches.suse/fuse-Remove-the-control-interface-for-virtio-fs.patch patches.suse/serial-8250_dw-Store-LSR-into-lsr_saved_flags-in-dw8.patch patches.suse/tty-serial-Fix-refcount-leak-bug-in-ucc_uart.c.patch patches.suse/tty-n_gsm-fix-user-open-not-possible-at-responder-un.patch @@ -15924,6 +16513,7 @@ patches.suse/watchdog-armada_37xx_wdt-check-the-return-value-of-d.patch patches.suse/rpmsg-char-Add-mutex-protection-for-rpmsg_eptdev_ope.patch patches.suse/rpmsg-mtk_rpmsg-Fix-circular-locking-dependency.patch + patches.suse/rpmsg-qcom-glink-replace-strncpy-with-strscpy_pad.patch patches.suse/rpmsg-qcom_smd-Fix-refcount-leak-in-qcom_smd_parse_e.patch patches.suse/remoteproc-k3-r5-Fix-refcount-leak-in-k3_r5_cluster_.patch patches.suse/remoteproc-imx_rproc-Fix-refcount-leak-in-imx_rproc_.patch @@ -15937,6 +16527,9 @@ patches.suse/fs-add-mode_strip_sgid-helper.patch patches.suse/fs-Add-missing-umask-strip-in-vfs_tmpfile.patch patches.suse/fs-move-S_ISGID-stripping-into-the-vfs_-helpers.patch + patches.suse/nfsd-eliminate-the-NFSD_FILE_BREAK_-flags.patch + patches.suse/SUNRPC-Fix-xdr_encode_bool.patch + patches.suse/lockd-detect-and-reject-lock-arguments-that-overflow.patch patches.suse/Revert-scripts-mod-modpost.c-permit-.cranges-secton-.patch patches.suse/kbuild-dummy-tools-avoid-tmpdir-leak-in-dummy-gcc.patch patches.suse/apparmor-fix-absroot-causing-audited-secids-to-begin.patch @@ -15952,6 +16545,14 @@ patches.suse/pinctrl-amd-Don-t-save-restore-interrupt-status-and-.patch patches.suse/pinctrl-sunxi-Add-I-O-bias-setting-for-H6-R-PIO.patch patches.suse/pinctrl-qcom-sm8250-Fix-PDC-map.patch + patches.suse/Revert-pNFS-nfs3_set_ds_client-should-set-NFS_CS_NOP.patch + patches.suse/pNFS-flexfiles-Report-RDMA-connection-errors-to-the-.patch + patches.suse/NFSv4.1-Don-t-decrease-the-value-of-seq_nr_highest_s.patch + patches.suse/NFSv4.1-Handle-NFS4ERR_DELAY-replies-to-OP_SEQUENCE-.patch + patches.suse/sunrpc-fix-expiry-of-auth-creds.patch + patches.suse/NFSv4-Fix-races-in-the-legacy-idmapper-upcall.patch + patches.suse/NFSv4.1-RECLAIM_COMPLETE-must-handle-EACCES.patch + patches.suse/SUNRPC-Reinitialise-the-backchannel-request-buffers-.patch patches.suse/Makefile-link-with-z-noexecstack-no-warn-rwx-segment.patch patches.suse/x86-link-vdso-and-boot-with-z-noexecstack-no-warn-rw.patch patches.suse/Input-exc3000-fix-return-value-check-of-wait_for_com.patch @@ -15960,6 +16561,7 @@ patches.suse/Input-i8042-add-TUXEDO-devices-to-i8042-quirk-tables.patch patches.suse/Input-i8042-add-additional-TUXEDO-devices-to-i8042-q.patch patches.suse/KVM-x86-revalidate-steal-time-cache-if-MSR-value-cha.patch + patches.suse/KVM-x86-do-not-report-preemption-if-the-steal-time-c.patch patches.suse/KVM-X86-avoid-uninitialized-fault.async_page_fault-f.patch patches.suse/ceph-use-correct-index-when-encoding-client-supported-features.patch patches.suse/ceph-don-t-leak-snap_rwsem-in-handle_cap_grant.patch @@ -15985,6 +16587,7 @@ patches.suse/vsock-Fix-memory-leak-in-vsock_connect.patch patches.suse/vsock-Set-socket-state-back-to-SS_UNCONNECTED-in-vso.patch patches.suse/devlink-Fix-use-after-free-after-a-failed-reload.patch + patches.suse/selftests-forwarding-Fix-failing-tests-with-old-libn.patch patches.suse/net_sched-cls_route-remove-from-list-when-handle-is-.patch patches.suse/drm-shmem-helper-Add-missing-vunmap-on-error.patch patches.suse/drm-gem-Properly-annotate-WW-context-on-drm_gem_lock.patch @@ -16009,9 +16612,13 @@ patches.suse/NTB-ntb_tool-uninitialized-heap-data-in-tool_fn_writ.patch patches.suse/docs-i2c-i2c-sysfs-fix-hyperlinks.patch patches.suse/posix-cpu-timers-Cleanup-CPU-timers-before-freeing-t.patch + patches.suse/xen-blkback-fix-persistent-grants-negotiation.patch + patches.suse/xen-blkback-Apply-feature_persistent-parameter-when-.patch + patches.suse/xen-blkfront-Apply-feature_persistent-parameter-when.patch patches.suse/xen-xenbus-fix-return-type-in-xenbus_file_read.patch patches.suse/regulator-pca9450-Remove-restrictions-for-regulator-.patch patches.suse/spi-meson-spicc-add-local-pow2-clock-ops-to-preserve.patch + patches.suse/net-sunrpc-fix-potential-memory-leaks-in-rpc_sysfs_x.patch patches.suse/bnx2x-Fix-comment-typo.patch patches.suse/ice-Fix-VSI-rebuild-WARN_ON-check-for-VF.patch patches.suse/ice-Fix-call-trace-with-null-VSI-during-VF-reset.patch @@ -16043,12 +16650,17 @@ patches.suse/drm-amdgpu-Increase-tlb-flush-timeout-for-sriov.patch patches.suse/drm-amd-display-avoid-doing-vm_init-multiple-time.patch patches.suse/drm-amdgpu-remove-useless-condition-in-amdgpu_job_st.patch + patches.suse/ALSA-hda-realtek-Add-quirks-for-ASUS-Zenbooks-using-.patch patches.suse/ASoC-SOF-debug-Fix-potential-buffer-overflow-by-snpr.patch patches.suse/ASoC-tas2770-Set-correct-FSYNC-polarity.patch patches.suse/ASoC-tas2770-Allow-mono-streams.patch patches.suse/ASoC-tas2770-Drop-conflicting-set_bias_level-power-s.patch patches.suse/ASoC-tas2770-Fix-handling-of-mute-unmute.patch patches.suse/ASoC-codec-tlv320aic32x4-fix-mono-playback-via-I2S.patch + patches.suse/ALSA-hda-cs35l41-Clarify-support-for-CSC3551-without.patch + patches.suse/ALSA-hda-realtek-Add-quirk-for-Lenovo-Yoga7-14IAL7.patch + patches.suse/platform-x86-serial-multi-instantiate-Add-CLSA0101-L.patch + patches.suse/ALSA-hda-cs8409-Support-new-Dolphin-Variants.patch patches.suse/ALSA-info-Fix-llseek-return-value-when-using-callbac.patch patches.suse/ALSA-hda-realtek-Add-quirk-for-Clevo-NS50PU-NS70PU.patch patches.suse/mmc-pxamci-Fix-an-error-handling-path-in-pxamci_prob.patch @@ -16063,7 +16675,13 @@ patches.suse/ftrace-Fix-NULL-pointer-dereference-in-is_ftrace_trampoline-when-ftrace-is-dead.patch patches.suse/tracing-probes-Have-kprobes-and-uprobes-use-COMM-too.patch patches.suse/tracing-Have-filter-accept-common_cpu-to-be-consistent.patch + patches.suse/NFS-Fix-another-fsync-issue-after-a-server-reboot.patch + patches.suse/NFSv4.2-fix-problems-with-__nfs42_ssc_open.patch + patches.suse/SUNRPC-RPC-level-errors-should-set-task-tk_rpc_statu.patch patches.suse/audit-fix-potential-double-free-on-error-path-from-f.patch + patches.suse/cgroup-Fix-threadgroup_rwsem-cpus_read_lock-deadlock.patch + patches.suse/cgroup-Fix-race-condition-at-rebind_subsystems.patch + patches.suse/cgroup-Add-missing-cpus_read_lock-to-cgroup_attach_task_all.patch patches.suse/rose-check-NULL-rose_loopback_neigh-loopback.patch patches.suse/r8152-fix-the-units-of-some-registers-for-RTL8156A.patch patches.suse/r8152-fix-the-RX-FIFO-settings-when-suspending.patch @@ -16093,20 +16711,31 @@ patches.suse/netfilter-nf_tables-disallow-binding-to-already-boun.patch patches.suse/ixgbe-stop-resetting-SYSTIME-in-ixgbe_ptp_start_cycl.patch patches.suse/i40e-Fix-incorrect-address-type-for-IPv6-flow-rules.patch + patches.suse/scsi-qla2xxx-Disable-ATIO-interrupt-coalesce-for-qua.patch patches.suse/loop-Check-for-overflow-while-configuring-loop.patch + patches.suse/md-call-__md_stop_writes-in-md_stop.patch + patches.suse/drm-gem-Fix-GEM-handle-release-errors.patch patches.suse/nouveau-explicitly-wait-on-the-fence-in-nouveau_bo_m.patch + patches.suse/drm-amdgpu-Move-psp_xgmi_terminate-call-from-amdgpu_.patch + patches.suse/drm-amdgpu-Check-num_gfx_rings-for-gfx-v9_0-rb-setup.patch + patches.suse/drm-radeon-add-a-force-flush-to-delay-work-when-rade.patch + patches.suse/drm-amdgpu-mmVM_L2_CNTL3-register-not-initialized-co.patch patches.suse/arm64-Fix-match_list-for-erratum-1286807-on-Arm-Cort.patch patches.suse/arm64-fix-rodata-full.patch patches.suse/fbdev-fb_pm2fb-Avoid-potential-divide-by-zero-error.patch + patches.suse/fbdev-chipsfb-Add-missing-pci_disable_device-in-chip.patch patches.suse/fbdev-fbcon-Properly-revert-changes-when-vc_resize-f.patch patches.suse/xen-privcmd-fix-error-exit-of-privcmd_ioctl_dm_op.patch patches.suse/s390-fix-double-free-of-GS-and-RI-CBs-on-fork-failure patches.suse/s390-mm-do-not-trigger-write-fault-when-vma-does-not-allow-VM_WRITE patches.suse/ACPI-processor-Remove-freq-Qos-request-for-all-CPUs.patch + patches.suse/x86-cpu-Add-new-Raptor-Lake-CPU-model-number.patch patches.suse/btrfs-fix-space-cache-corruption-and-potential-doubl.patch patches.suse/asm-generic-sections-refactor-memory_intersects.patch patches.suse/HID-steam-Prevent-NULL-pointer-dereference-in-steam_.patch patches.suse/HID-asus-ROG-NKey-Ignore-portion-of-0x5a-report.patch + patches.suse/HID-ishtp-hid-clientHID-ishtp-hid-client-Fix-comment.patch + patches.suse/hid-intel-ish-hid-ishtp-Fix-ishtp-client-sending-dis.patch patches.suse/HID-thrustmaster-Add-sparco-wheel-and-fix-array-leng.patch patches.suse/HID-AMD_SFH-Add-a-DMI-quirk-entry-for-Chromebooks.patch patches.suse/HID-add-Lenovo-Yoga-C630-battery-quirk.patch @@ -16123,9 +16752,12 @@ patches.suse/Bluetooth-L2CAP-Fix-build-errors-in-some-archs.patch patches.suse/tg3-Disable-tg3-device-on-system-reboot-to-avoid-tri.patch patches.suse/ieee802154-adf7242-defer-destroy_workqueue-call.patch + patches.suse/ieee802154-cc2520-add-rc-code-in-cc2520_tx.patch patches.suse/ethernet-rocker-fix-sleep-in-atomic-context-bug-in-n.patch patches.suse/kcm-fix-strp_init-order-and-cleanup.patch patches.suse/platform-x86-pmc_atom-Fix-SLP_TYPx-bitfield-mask.patch + patches.suse/platform-surface-aggregator_registry-Add-support-for-84b8e403435c.patch + patches.suse/platform-x86-acer-wmi-Acer-Aspire-One-AOD270-Packard.patch patches.suse/musb-fix-USB_MUSB_TUSB6010-dependency.patch patches.suse/usb-typec-tcpm-Return-ENOTSUPP-for-power-supply-prop.patch patches.suse/usb-storage-Add-ignore-residue-quirk-for-NXP-PN7462A.patch @@ -16138,12 +16770,16 @@ patches.suse/usb-gadget-f_uac2-fix-superspeed-transfer.patch patches.suse/USB-cdc-acm-Add-Icom-PMR-F3400-support-0c26-0020.patch patches.suse/thunderbolt-Use-the-actual-buffer-in-tb_async_error.patch + patches.suse/usb-add-quirks-for-Lenovo-OneLink-Dock.patch + patches.suse/usb-dwc3-disable-USB-core-PHY-management.patch patches.suse/usb-gadget-udc-xilinx-replace-memcpy-with-memcpy_toi.patch patches.suse/usb-dwc2-fix-wrong-order-of-phy_power_on-and-phy_ini.patch + patches.suse/USB-core-Prevent-nested-device-reset-calls.patch patches.suse/media-mceusb-Use-new-usb_control_msg_-routines.patch patches.suse/usb-gadget-mass_storage-Fix-cdrom-data-transfers-on-.patch patches.suse/usb-cdns3-fix-incorrect-handling-TRB_SMM-flag-for-IS.patch patches.suse/usb-cdns3-fix-issue-with-rearming-ISO-OUT-endpoint.patch + patches.suse/Revert-usb-add-quirks-for-Lenovo-OneLink-Dock.patch patches.suse/USB-serial-option-add-support-for-OPPO-R11-diag-port.patch patches.suse/USB-serial-option-add-Quectel-EM060K-modem.patch patches.suse/USB-serial-ftdi_sio-add-Omron-CS1W-CIF31-device-id.patch @@ -16151,6 +16787,7 @@ patches.suse/USB-serial-cp210x-add-Decagon-UCA-device-id.patch patches.suse/USB-serial-ch341-fix-lost-character-on-LCR-updates.patch patches.suse/USB-serial-ch341-fix-disabled-rx-timer-on-older-devi.patch + patches.suse/usb-storage-Add-ASUS-0x0b05-0x1932-to-IGNORE_UAS.patch patches.suse/Revert-usb-gadget-udc-xilinx-replace-memcpy-with-mem.patch patches.suse/iio-adc-mcp3911-make-use-of-the-sign-bit.patch patches.suse/iio-adc-mcp3911-use-correct-formula-for-AD-conversio.patch @@ -16161,10 +16798,12 @@ patches.suse/driver-core-Don-t-probe-devices-after-bus_type.match.patch patches.suse/drm-i915-reg-Fix-spelling-mistake-Unsupport-Unsuppor.patch patches.suse/drm-i915-display-avoid-warnings-when-registering-dua.patch + patches.suse/drm-amd-amdgpu-skip-ucode-loading-if-ucode_size-0.patch patches.suse/drm-msm-dsi-fix-the-inconsistent-indenting.patch patches.suse/drm-msm-dp-delete-DP_RECOVERED_CLOCK_OUT_EN-to-fix-t.patch patches.suse/drm-msm-dsi-Fix-number-of-regulators-for-msm8996_dsi.patch patches.suse/drm-msm-dsi-Fix-number-of-regulators-for-SDM660.patch + patches.suse/drm-msm-rd-Fix-FIFO-full-deadlock.patch patches.suse/drm-i915-fix-null-pointer-dereference.patch patches.suse/drm-i915-glk-ECS-Liva-Q2-needs-GLK-HDMI-port-timing-.patch patches.suse/drm-i915-Skip-wm-ddb-readout-for-disabled-pipes.patch @@ -16181,17 +16820,28 @@ patches.suse/vt-Clear-selection-before-changing-the-font.patch patches.suse/serial-fsl_lpuart-RS485-RTS-polariy-is-inverse.patch patches.suse/tty-serial-lpuart-disable-flow-control-while-waiting.patch + patches.suse/tty-serial-atmel-Preserve-previous-USART-mode-if-RS4.patch patches.suse/tty-n_gsm-add-sanity-check-for-gsm-receive-in-gsm_re.patch patches.suse/tty-n_gsm-initialize-more-members-at-gsm_alloc_mux.patch patches.suse/tty-n_gsm-replace-kicktimer-with-delayed_work.patch patches.suse/tty-n_gsm-avoid-call-of-sleeping-functions-from-atom.patch + patches.suse/Input-goodix-add-support-for-GT1158.patch patches.suse/Input-rk805-pwrkey-fix-module-autoloading.patch + patches.suse/Input-goodix-add-compatible-string-for-GT1158.patch patches.suse/Input-iforce-wake-up-after-clearing-IFORCE_XMIT_RUNN.patch + patches.suse/Input-iforce-add-support-for-Boeder-Force-Feedback-W.patch patches.suse/s390-hugetlb-fix-prepare_hugepage_range-check-for-2-GB-hugepages + patches.suse/xen-blkback-Advertise-feature-persistent-as-user-req.patch + patches.suse/xen-blkfront-Advertise-feature-persistent-as-user-re.patch + patches.suse/xen-blkfront-Cache-feature_persistent-value-before-a.patch + patches.suse/xen-grants-prevent-integer-overflow-in-gnttab_dma_al.patch + patches.suse/gpio-mockup-remove-gpio-debugfs-when-remove-device.patch patches.suse/gpio-pca953x-Add-mutex_lock-for-regcache-sync-in-PM.patch + patches.suse/KVM-VMX-Heed-the-msr-argument-in-msr_write_intercept.patch patches.suse/powerpc-papr_scm-Fix-nvdimm-event-mappings.patch patches.suse/powerpc-papr_scm-Ensure-rc-is-always-initialized-in-.patch patches.suse/ARM-dts-imx6qdl-kontron-samx6i-remove-duplicated-nod.patch + patches.suse/ARM-dts-imx6qdl-kontron-samx6i-fix-spi-flash-compati.patch patches.suse/soc-imx-gpcv2-Assert-reset-before-ungating-clock.patch patches.suse/soc-brcmstb-pm-arm-Fix-refcount-leak-and-__iomem-lea.patch patches.suse/soc-fsl-select-FSL_GUTS-driver-for-DPIO.patch @@ -16199,9 +16849,15 @@ patches.suse/ARM-dts-at91-sama5d2_icp-specify-proper-regulator-ou.patch patches.suse/ARM-dts-at91-sama5d27_wlsom1-don-t-keep-ldo2-enabled.patch patches.suse/ARM-dts-at91-sama5d2_icp-don-t-keep-vdd_other-enable.patch + patches.suse/efi-libstub-Disable-struct-randomization.patch + patches.suse/efi-capsule-loader-Fix-use-after-free-in-efi_capsule.patch patches.suse/netfilter-nf_conntrack_irc-Fix-forged-IP-logic.patch + patches.suse/xen-netback-only-remove-hotplug-status-when-the-vif-.patch patches.suse/wifi-iwlegacy-4965-corrected-fix-for-potential-off-b.patch + patches.suse/wifi-mac80211_hwsim-check-length-for-virtio-packets.patch + patches.suse/net-usb-qmi_wwan-add-Quectel-RM520N.patch patches.suse/regulator-core-Clean-up-on-enable-failure.patch + patches.suse/regulator-pfuze100-Fix-the-global-out-of-bounds-acce.patch patches.suse/tracing-hold-caller_addr-to-hardirq_-enable-disable-_ip.patch patches.suse/ALSA-usb-audio-Inform-the-delayed-registration-more-.patch patches.suse/ALSA-usb-audio-Register-card-again-for-iface-over-de.patch @@ -16213,8 +16869,17 @@ patches.suse/ALSA-hda-tegra-Align-BDL-entry-to-4KB-boundary.patch patches.suse/ALSA-usb-audio-Fix-an-out-of-bounds-bug-in-__snd_usb.patch patches.suse/ALSA-emu10k1-Fix-out-of-bounds-access-in-snd_emu10k1.patch + patches.suse/ASoC-cs42l42-Only-report-button-state-if-there-was-a.patch patches.suse/ASoC-qcom-sm8250-add-missing-module-owner.patch + patches.suse/ASoC-mchp-spdiftx-Fix-clang-Wbitfield-constant-conve.patch + patches.suse/ASoC-nau8824-Fix-semaphore-unbalance-at-error-paths.patch + patches.suse/vfio-type1-Unpin-zero-pages.patch + patches.suse/drm-panfrost-devfreq-set-opp-to-the-recommended-one-.patch + patches.suse/drm-i915-Implement-WaEdpLinkRateDataReload.patch patches.suse/nvme-tcp-fix-uaf-when-detecting-digest-errors.patch + patches.suse/scsi-lpfc-Return-DID_TRANSPORT_DISRUPTED-instead-of-.patch + patches.suse/scsi-lpfc-Add-missing-destroy_workqueue-in-error-pat.patch + patches.suse/scsi-mpt3sas-Fix-use-after-free-warning.patch patches.suse/hwmon-tps23861-fix-byte-order-in-resistance-register.patch patches.suse/dt-bindings-hwmon-mr75203-fix-intel-vm-map-property-.patch patches.suse/hwmon-mr75203-fix-VM-sensor-allocation-when-intel-vm.patch @@ -16223,10 +16888,305 @@ patches.suse/hwmon-mr75203-fix-multi-channel-voltage-reading.patch patches.suse/hwmon-mr75203-enable-polling-for-all-VM-channels.patch patches.suse/s390-boot-fix-absolute-zero-lowcore-corruption-on-boot + patches.suse/s390-smp-enforce-lowcore-protection-on-CPU-restart patches.suse/docs-i2c-i2c-topology-fix-incorrect-heading.patch patches.suse/kbuild-disable-header-exports-for-UML-in-a-straightf.patch - - # mkp/scsi queue + patches.suse/NFSv4-Turn-off-open-by-filehandle-and-NFS-re-export-.patch + patches.suse/NFSv4.2-Update-mode-bits-after-ALLOCATE-and-DEALLOCA.patch + patches.suse/Revert-SUNRPC-Remove-unreachable-error-condition.patch + patches.suse/of-fdt-fix-off-by-one-error-in-unflatten_dt_nodes.patch + patches.suse/of-device-Fix-up-of_dma_configure_id-stub.patch + patches.suse/drm-amd-pm-disable-BACO-entry-exit-completely-on-sev.patch + patches.suse/drm-amdgpu-use-dirty-framebuffer-helper.patch + patches.suse/drm-amd-display-Limit-user-regamma-to-a-valid-value.patch + patches.suse/drm-amd-display-Reduce-number-of-arguments-of-dml31-.patch + patches.suse/drm-amd-display-Reduce-number-of-arguments-of-dml31--21485d3da659.patch + patches.suse/drm-amd-display-Mark-dml30-s-UseMinimumDCFCLK-as-noi.patch + patches.suse/drm-amdgpu-move-nbio-ih_doorbell_range-into-ih-code-.patch + patches.suse/drm-amdgpu-move-nbio-sdma_doorbell_range-into-sdma-c.patch + patches.suse/drm-amdgpu-make-sure-to-init-common-IP-before-gmc.patch + patches.suse/drm-meson-Correct-OSD1-global-alpha-value.patch + patches.suse/drm-meson-Fix-OSD1-RGB-to-YCbCr-coefficient.patch + patches.suse/drm-gma500-Fix-BUG-sleeping-function-called-from-inv.patch + patches.suse/drm-rockchip-Fix-return-type-of-cdn_dp_connector_mod.patch + patches.suse/pinctrl-qcom-sc8180x-Fix-gpio_wakeirq_map.patch + patches.suse/pinctrl-qcom-sc8180x-Fix-wrong-pin-numbers.patch + patches.suse/pinctrl-sunxi-Fix-name-for-A100-R_PIO.patch + patches.suse/gpio-mpc8xxx-Fix-support-for-IRQ_TYPE_LEVEL_LOW-flow.patch + patches.suse/ALSA-hda-Fix-hang-at-HD-audio-codec-unbinding-due-to.patch + patches.suse/ALSA-hda-add-Intel-5-Series-3400-PCI-DID.patch + patches.suse/ALSA-hda-tegra-set-depop-delay-for-tegra.patch + patches.suse/ALSA-hda-realtek-Add-quirk-for-Huawei-WRT-WX9.patch + patches.suse/ALSA-hda-Fix-Nvidia-dp-infoframe.patch + patches.suse/ALSA-hda-realtek-Enable-4-speaker-output-Dell-Precis.patch + patches.suse/ALSA-hda-realtek-Enable-4-speaker-output-Dell-Precis-1885ff13d4c4.patch + patches.suse/ALSA-hda-realtek-Re-arrange-quirk-table-entries.patch + patches.suse/ALSA-hda-realtek-Add-pincfg-for-ASUS-G513-HP-jack.patch + patches.suse/ALSA-hda-realtek-Add-pincfg-for-ASUS-G533Z-HP-jack.patch + patches.suse/ALSA-hda-realtek-Add-quirk-for-ASUS-GA503R-laptop.patch + patches.suse/ALSA-hda-hdmi-Fix-the-converter-reuse-for-the-silent.patch + patches.suse/ALSA-hda-realtek-Add-a-quirk-for-HP-OMEN-16-8902-mut.patch + patches.suse/ALSA-core-Fix-double-free-at-snd_card_new.patch + patches.suse/Revert-ALSA-usb-audio-Split-endpoint-setups-for-hw_p.patch + patches.suse/dmaengine-xilinx_dma-Fix-devm_platform_ioremap_resou.patch + patches.suse/dmaengine-xilinx_dma-cleanup-for-fetching-xlnx-num-f.patch + patches.suse/dmaengine-xilinx_dma-Report-error-in-case-of-dma_set.patch + patches.suse/dmaengine-ti-k3-udma-private-Fix-refcount-leak-bug-i.patch + patches.suse/gpio-mockup-fix-NULL-pointer-dereference-when-removi.patch + patches.suse/gpiolib-cdev-Set-lineevent_state-irq-after-IRQ-regis.patch + patches.suse/net-phy-aquantia-wait-for-the-suspend-resume-operati.patch + patches.suse/net-ieee802154-fix-uninit-value-bug-in-dgram_sendmsg.patch + patches.suse/msft-hv-2644-net-mana-Add-rmb-after-checking-owner-bits.patch + patches.suse/batman-adv-Fix-hang-up-with-small-MTU-hard-interface.patch + patches.suse/wifi-mt76-fix-reading-current-per-tid-starting-seque.patch + patches.suse/gve-Fix-GFP-flags-when-allocing-pages-8ccac4edc8da.patch + patches.suse/can-gs_usb-gs_can_open-fix-race-dev-can.state-condit.patch + patches.suse/selftests-forwarding-add-shebang-for-sch_red.sh.patch + patches.suse/firmware-arm_scmi-Improve-checks-in-the-info_get-ope.patch + patches.suse/firmware-arm_scmi-Harden-accesses-to-the-sensor-doma.patch + patches.suse/firmware-arm_scmi-Harden-accesses-to-the-reset-domai.patch + patches.suse/firmware-arm_scmi-Fix-the-asynchronous-reset-request.patch + patches.suse/firmware-arm_scmi-Add-SCMI-PM-driver-remove-routine.patch + patches.suse/ARM-dts-fix-Moxa-SDIO-compatible-remove-sdhci-misnom.patch + patches.suse/arm64-dts-rockchip-Pull-up-wlan-wake-on-Gru-Bob.patch + patches.suse/arm64-dts-rockchip-Fix-typo-in-lisense-text-for-PX30.patch + patches.suse/arm64-dts-rockchip-Set-RK3399-Gru-PCLK_EDP-to-24-MHz.patch + patches.suse/arm64-dts-rockchip-Remove-enable-active-low-from-rk3.patch + patches.suse/scsi-qla2xxx-Fix-memory-leak-in-__qlt_24xx_handle_ab.patch + patches.suse/drm-amd-display-Fix-double-cursor-on-non-video-RGB-M.patch + patches.suse/drm-amd-display-Assume-an-LTTPR-is-always-present-on.patch + patches.suse/drm-amd-display-update-gamut-remap-if-plane-has-chan.patch + patches.suse/drm-amd-display-skip-audio-setup-when-audio-stream-i.patch + patches.suse/drm-amdgpu-don-t-register-a-dirty-callback-for-non-a.patch + patches.suse/drm-mediatek-dsi-Add-atomic-destroy-duplicate-_state.patch + patches.suse/drm-mediatek-dsi-Move-mtk_dsi_stop-call-back-to-mtk_.patch + patches.suse/drm-panel-simple-Fix-innolux_g121i1_l01-bus_format.patch + patches.suse/KVM-x86-Inject-UD-on-emulated-XSETBV-if-XSAVES-isn-t.patch + patches.suse/USB-core-Fix-RST-error-in-hub.c.patch + patches.suse/usb-dwc3-core-leave-default-DMA-if-the-controller-do.patch + patches.suse/thunderbolt-Add-support-for-Intel-Maple-Ridge-single.patch + patches.suse/media-flexcop-usb-fix-endpoint-type-check.patch + patches.suse/USB-serial-option-add-Quectel-BG95-0x0203-compositio.patch + patches.suse/USB-serial-option-add-Quectel-RM520N.patch + patches.suse/arm64-topology-fix-possible-overflow-in-amu_fie_setu.patch + patches.suse/workqueue-don-t-skip-lockdep-work-dependency-in-canc.patch + patches.suse/cgroup-cgroup_get_from_id-must-check-the-looked-up-kn-is-a-directory.patch + patches.suse/serial-Create-uart_xmit_advance.patch + patches.suse/serial-tegra-Use-uart_xmit_advance-fixes-icount.tx-a.patch + patches.suse/serial-tegra-tcu-Use-uart_xmit_advance-fixes-icount..patch + patches.suse/serial-fsl_lpuart-Reset-prior-to-registration.patch + patches.suse/Makefile.debug-re-enable-debug-info-for-.S-files.patch + patches.suse/i2c-imx-If-pm_runtime_get_sync-returned-1-device-acc.patch + patches.suse/i2c-mlxbf-incorrect-base-address-passed-during-io-wr.patch + patches.suse/i2c-mlxbf-prevent-stack-overflow-in-mlxbf_i2c_smbus_.patch + patches.suse/i2c-mlxbf-Fix-frequency-calculation.patch + patches.suse/x86-cpu-Add-CPU-model-numbers-for-Meteor-Lake.patch + patches.suse/ASoC-imx-card-Fix-refcount-issue-with-of_node_put.patch + patches.suse/ASoC-tas2770-Reinit-regcache-on-reset.patch + patches.suse/ARM-dts-am33xx-Fix-MMCHS0-dma-properties.patch + patches.suse/soc-sunxi-sram-Actually-claim-SRAM-regions.patch + patches.suse/soc-sunxi-sram-Prevent-the-driver-from-being-unbound.patch + patches.suse/soc-sunxi-sram-Fix-probe-function-ordering-issues.patch + patches.suse/soc-sunxi-sram-Fix-debugfs-info-for-A64-SRAM-C.patch + patches.suse/ARM-dts-integrator-Tag-PCI-host-with-device_type.patch + patches.suse/arm64-dts-qcom-sm8350-fix-UFS-PHY-serdes-size.patch + patches.suse/reset-imx7-Fix-the-iMX8MP-PCIe-PHY-PERST-support.patch + patches.suse/mmc-moxart-fix-4-bit-bus-width-and-remove-8-bit-bus-.patch + patches.suse/mmc-core-Terminate-infinite-loop-in-SD-UHS-voltage-s.patch + patches.suse/Revert-firmware-arm_scmi-Add-clock-management-to-the.patch + patches.suse/mmc-hsq-Fix-data-stomping-during-mmc-recovery.patch + patches.suse/libata-add-ATA_HORKAGE_NOLPM-for-Pioneer-BDR-207M-an.patch + patches.suse/Input-melfas_mip4-fix-return-value-check-in-mip4_pro.patch + patches.suse/Input-iqs62x-keys-drop-unused-device-node-references.patch + patches.suse/Input-snvs_pwrkey-fix-SNVS_HPVIDR1-register-address.patch + patches.suse/usbnet-Fix-memory-leak-in-usbnet_disconnect.patch + patches.suse/net-phy-Don-t-WARN-for-PHY_UP-state-in-mdio_bus_phy_.patch + patches.suse/selftests-Fix-the-if-conditions-of-in-test_extra_fil.patch + patches.suse/net-usb-qmi_wwan-Add-new-usb-id-for-Dell-branded-EM7.patch + patches.suse/wifi-mac80211-fix-regression-with-non-QoS-drivers.patch + patches.suse/drm-bridge-lt8912b-add-vsync-hsync.patch + patches.suse/drm-bridge-lt8912b-set-hdmi-or-dvi-mode.patch + patches.suse/drm-bridge-lt8912b-fix-corrupted-image-output.patch + patches.suse/Revert-drm-bridge-analogix-dp-add-panel-prepare-unpr.patch + patches.suse/drm-i915-gt-Restrict-forced-preemption-to-the-active.patch + patches.suse/gpio-mvebu-Fix-check-for-pwm-support-on-non-A8K-plat.patch + patches.suse/clk-ingenic-tcu-Properly-enable-registers-before-acc.patch + patches.suse/clk-imx-imx6sx-remove-the-SET_RATE_PARENT-flag-for-Q.patch + patches.suse/clk-iproc-Do-not-rely-on-node-name-for-correct-PLL-s.patch + patches.suse/media-v4l2-compat-ioctl32.c-zero-buffer-passed-to-v4.patch + patches.suse/media-dvb_vb2-fix-possible-out-of-bound-access.patch + patches.suse/media-rkvdec-Disable-H.264-error-detection.patch + patches.suse/thunderbolt-Explicitly-reset-plug-events-delay-back-.patch + patches.suse/usb-typec-ucsi-Remove-incorrect-warning.patch + patches.suse/uas-add-no-uas-quirk-for-Hiksemi-usb_disk.patch + patches.suse/usb-storage-Add-Hiksemi-USB3-FW-to-IGNORE_UAS.patch + patches.suse/uas-ignore-UAS-for-Thinkplus-chips.patch + patches.suse/docs-update-mediator-information-in-CoC-docs.patch + patches.suse/efi-Correct-Macmini-DMI-match-in-uefi-cert-quirk.patch + patches.suse/x86-mce-Retrieve-poison-range-from-hardware.patch + patches.suse/wifi-rtlwifi-8192de-correct-checking-of-IQK-reload.patch + patches.suse/wifi-mac80211-allow-bw-change-during-channel-switch-.patch + patches.suse/net-thunderbolt-Enable-DMA-paths-only-after-rings-ar.patch + patches.suse/net-ethernet-move-from-strlcpy-with-unused-retval-to-strscpy.patch + patches.suse/wifi-ath10k-add-peer-map-clean-up-for-peer-delete-in.patch + patches.suse/wifi-rtl8xxxu-tighten-bounds-checking-in-rtl8xxxu_re.patch + patches.suse/wifi-rtw88-add-missing-destroy_workqueue-on-error-pa.patch + patches.suse/can-rx-offload-can_rx_offload_init_queue-fix-typo.patch + patches.suse/wifi-rtl8xxxu-Fix-skb-misuse-in-TX-queue-selection.patch + patches.suse/wifi-rtl8xxxu-gen2-Fix-mistake-in-path-B-IQ-calibrat.patch + patches.suse/wifi-rtl8xxxu-Remove-copy-paste-leftover-in-gen2_upd.patch + patches.suse/mwifiex-fix-sleep-in-atomic-context-bugs-caused-by-d.patch + patches.suse/wifi-mt76-sdio-fix-transmitting-packet-hangs.patch + patches.suse/wifi-mt76-mt7615-add-mt7615_mutex_acquire-release-in.patch + patches.suse/wifi-mt76-mt7915-do-not-check-state-before-configuri.patch + patches.suse/wifi-ath11k-fix-number-of-VHT-beamformee-spatial-str.patch + patches.suse/wifi-rtl8xxxu-Fix-AIFS-written-to-REG_EDCA_-_PARAM.patch + patches.suse/wifi-rtl8xxxu-Improve-rtl8xxxu_queue_select.patch + patches.suse/Bluetooth-btusb-mediatek-fix-WMT-failure-during-runt.patch + patches.suse/Bluetooth-hci_-ldisc-serdev-check-percpu_init_rwsem-.patch + patches.suse/Bluetooth-hci_core-Fix-not-handling-link-timeouts-pr.patch + patches.suse/vhost-vsock-Use-kvmalloc-kvfree-for-larger-packets.patch + patches.suse/eth-alx-take-rtnl_lock-on-resume.patch + patches.suse/mISDN-fix-use-after-free-bugs-in-l1oip-timer-handler.patch + patches.suse/net-wwan-iosm-Call-mutex_init-before-locking-it.patch + patches.suse/i2c-mlxbf-support-lock-mechanism.patch + patches.suse/hwmon-gsc-hwmon-Call-of_node_get-before-of_find_xxx-.patch + patches.suse/hwmon-pmbus-mp2888-Fix-sensors-readouts-for-MPS-Mult.patch + patches.suse/regulator-qcom_rpm-Fix-circular-deferral-regression.patch + patches.suse/spi-mt7621-Fix-an-error-message-in-mt7621_spi_probe.patch + patches.suse/spi-qup-add-missing-clk_disable_unprepare-on-error-i.patch + patches.suse/spi-qup-add-missing-clk_disable_unprepare-on-error-i-494a22765ce4.patch + patches.suse/spi-meson-spicc-do-not-rely-on-busy-flag-in-pow2-clk.patch + patches.suse/spi-dw-Fix-PM-disable-depth-imbalance-in-dw_spi_bt1_.patch + patches.suse/spi-omap100k-Fix-PM-disable-depth-imbalance-in-omap1.patch + patches.suse/spi-s3c64xx-Fix-large-transfers-with-DMA.patch + patches.suse/mmc-au1xmmc-Fix-an-error-handling-path-in-au1xmmc_pr.patch + patches.suse/mmc-wmt-sdmmc-Fix-an-error-handling-path-in-wmt_mci_.patch + patches.suse/platform-chrome-cros_ec_proto-Update-version-on-GET_.patch + patches.suse/platform-chrome-fix-double-free-in-chromeos_laptop_p.patch + patches.suse/platform-chrome-fix-memory-corruption-in-ioctl.patch + patches.suse/platform-chrome-cros_ec_typec-Correct-alt-mode-index.patch + patches.suse/platform-x86-asus-wmi-Document-the-dgpu_disable-sysf.patch + patches.suse/platform-x86-asus-wmi-Document-the-egpu_enable-sysfs.patch + patches.suse/platform-x86-asus-wmi-Document-the-panel_od-sysfs-at.patch + patches.suse/platform-x86-msi-laptop-Fix-old-ec-check-for-backlig.patch + patches.suse/platform-x86-msi-laptop-Fix-resource-cleanup.patch + patches.suse/drm-bridge-adv7511-fix-CEC-power-down-control-regist.patch + patches.suse/drm-nouveau-fix-a-use-after-free-in-nouveau_gem_prim.patch + patches.suse/drm-bridge-Avoid-uninitialized-variable-warning.patch + patches.suse/drm-mipi-dsi-Detach-devices-when-removing-the-host.patch + patches.suse/drm-virtio-Unlock-reservations-on-virtio_gpu_object_.patch + patches.suse/drm-bridge-parade-ps8640-Fix-regulator-supply-order.patch + patches.suse/drm-udl-Replace-semaphore-with-a-simple-wait-queue.patch + patches.suse/drm-udl-Sync-pending-URBs-at-suspend-disconnect.patch + patches.suse/drm-udl-Kill-pending-URBs-at-suspend-and-disconnect.patch + patches.suse/drm-udl-Replace-BUG_ON-with-WARN_ON.patch + patches.suse/drm-pl111-Add-of_node_put-when-breaking-out-of-for_e.patch + patches.suse/drm-msm-Make-.remove-and-.shutdown-HW-shutdown-consi.patch + patches.suse/drm-fix-drm_mipi_dbi-build-errors.patch + patches.suse/drm-bridge-megachips-Fix-a-null-pointer-dereference-.patch + patches.suse/drm-scheduler-quieten-kernel-doc-warnings.patch + patches.suse/drm-amdgpu-add-missing-pci_disable_device-in-amdgpu_.patch + patches.suse/dt-bindings-display-msm-dpu-sc7180-add-missing-DPU-o.patch + patches.suse/dt-bindings-display-msm-dpu-sdm845-add-missing-DPU-o.patch + patches.suse/drm-msm-dpu-index-dpu_kms-hw_vbif-using-vbif_idx.patch + patches.suse/drm-msm-dpu-Fix-comment-typo.patch + patches.suse/drm-msm-dp-Silence-inconsistent-indent-warning.patch + patches.suse/drm-msm-dp-correct-1.62G-link-rate-at-dp_catalog_ctr.patch + patches.suse/drm-omap-dss-Fix-refcount-leak-bugs.patch + patches.suse/drm-udl-Restore-display-mode-on-resume.patch + patches.suse/drm-udl-Add-reset_resume.patch + patches.suse/drm-udl-Enable-damage-clipping.patch + patches.suse/Revert-drm-udl-Kill-pending-URBs-at-suspend-and-disc.patch + patches.suse/drm-udl-Suppress-error-print-for-EPROTO-at-URB-compl.patch + patches.suse/drm-udl-Increase-the-default-URB-list-size-to-20.patch + patches.suse/drm-udl-Drop-unneeded-alignment.patch + patches.suse/drm-udl-Fix-potential-URB-leaks.patch + patches.suse/drm-udl-Fix-inconsistent-urbs.count-value-during-udl.patch + patches.suse/drm-udl-Don-t-re-initialize-stuff-at-retrying-the-UR.patch + patches.suse/drm-udl-Sync-pending-URBs-at-the-end-of-suspend.patch + patches.suse/ASoC-wcd9335-fix-order-of-Slimbus-unprepare-disable.patch + patches.suse/ASoC-wcd934x-fix-order-of-Slimbus-unprepare-disable.patch + patches.suse/ALSA-asihpi-Remove-useless-code-in-hpi_meter_get_pea.patch + patches.suse/ALSA-hda-hdmi-change-type-for-the-assigned-variable.patch + patches.suse/ALSA-hda-hdmi-Fix-the-converter-allocation-for-the-s.patch + patches.suse/ALSA-dmaengine-increment-buffer-pointer-atomically.patch + patches.suse/ALSA-hda-realtek-Add-quirk-for-HP-Zbook-Firefly-14-G.patch + patches.suse/ALSA-hda-realtek-More-robust-component-matching-for-.patch + patches.suse/ALSA-usb-audio-Fix-NULL-dererence-at-error-path.patch + patches.suse/ALSA-usb-audio-Fix-potential-memory-leaks.patch + patches.suse/ALSA-hda-hdmi-Don-t-skip-notification-handling-durin.patch + patches.suse/ALSA-hda-Fix-position-reporting-on-Poulsbo.patch + patches.suse/ASoC-mt6359-fix-tests-for-platform_get_irq-failure.patch + patches.suse/ASoC-fsl_sai-Remove-unnecessary-FIFO-reset-in-ISR.patch + patches.suse/ASoC-tas2764-Allow-mono-streams.patch + patches.suse/ASoC-tas2764-Drop-conflicting-set_bias_level-power-s.patch + patches.suse/ASoC-tas2764-Fix-mute-unmute.patch + patches.suse/ASoC-rsnd-Add-check-for-rsnd_mod_power_on.patch + patches.suse/ASoC-wm_adsp-Handle-optional-legacy-support.patch + patches.suse/ASoC-eureka-tlv320-Hold-reference-returned-from-of_f.patch + patches.suse/ASoC-da7219-Fix-an-error-handling-path-in-da7219_reg.patch + patches.suse/ASoC-codecs-tx-macro-fix-kcontrol-put.patch + patches.suse/ASoC-wm8997-Fix-PM-disable-depth-imbalance-in-wm8997.patch + patches.suse/ASoC-wm5110-Fix-PM-disable-depth-imbalance-in-wm5110.patch + patches.suse/ASoC-wm5102-Fix-PM-disable-depth-imbalance-in-wm5102.patch + patches.suse/ASoC-mt6660-Fix-PM-disable-depth-imbalance-in-mt6660.patch + patches.suse/ARM-defconfig-clean-up-multi_v4t-and-multi_v5-config.patch + patches.suse/ARM-defconfig-drop-CONFIG_SERIAL_OMAP-references.patch + patches.suse/ARM-defconfig-drop-CONFIG_PTP_1588_CLOCK-y.patch + patches.suse/ARM-defconfig-drop-CONFIG_USB_FSL_USB2.patch + patches.suse/memory-pl353-smc-Fix-refcount-leak-bug-in-pl353_smc_.patch + patches.suse/memory-of-Fix-refcount-leak-bug-in-of_get_ddr_timing.patch + patches.suse/memory-of-Fix-refcount-leak-bug-in-of_lpddr3_get_ddr.patch + patches.suse/soc-qcom-smsm-Fix-refcount-leak-bugs-in-qcom_smsm_pr.patch + patches.suse/soc-qcom-smem_state-Add-refcounting-for-the-state-of.patch + patches.suse/ARM-dts-imx6qdl-kontron-samx6i-hook-up-DDC-i2c-bus.patch + patches.suse/arm64-dts-ti-k3-j7200-fix-main-pinmux-range.patch + patches.suse/arm64-dts-qcom-sc7280-Cleanup-the-lpasscc-node.patch + patches.suse/ARM-dts-turris-omnia-Fix-mpp26-pin-name-and-comment.patch + patches.suse/ARM-dts-kirkwood-lsxl-fix-serial-line.patch + patches.suse/ARM-dts-kirkwood-lsxl-remove-first-ethernet-port.patch + patches.suse/ARM-dts-armada-38x-Add-gpio-ranges-for-pin-muxing.patch + patches.suse/ARM-dts-turris-omnia-Add-label-for-wan-port.patch + patches.suse/ARM-dts-exynos-correct-s5k6a3-reset-polarity-on-Mida.patch + patches.suse/ARM-dts-exynos-fix-polarity-of-VBUS-GPIO-of-Origen.patch + patches.suse/ARM-Drop-CMDLINE_-dependency-on-ATAGS.patch + patches.suse/arm64-ftrace-fix-module-PLTs-with-mcount.patch + patches.suse/fs-fix-UAF-GPF-bug-in-nilfs_mdt_destroy.patch + patches.suse/sbitmap-fix-possible-io-hung-due-to-lost-wakeup.patch + patches.suse/sbitmap-Avoid-leaving-waitqueue-in-invalid-state-in-.patch + patches.suse/nvme-restrict-management-ioctls-to-admin.patch + patches.suse/nvme-ensure-subsystem-reset-is-single-threaded.patch + patches.suse/ata-fix-ata_id_sense_reporting_enabled-and-ata_id_ha.patch + patches.suse/ata-fix-ata_id_has_devslp.patch + patches.suse/ata-fix-ata_id_has_ncq_autosense.patch + patches.suse/ata-fix-ata_id_has_dipm.patch + patches.suse/media-cedrus-Set-the-platform-driver-data-earlier.patch + patches.suse/media-cedrus-Fix-endless-loop-in-cedrus_h265_skip_bi.patch + patches.suse/media-meson-vdec-add-missing-clk_disable_unprepare-o.patch + patches.suse/media-uvcvideo-Fix-memory-leak-in-uvc_gpio_parse.patch + patches.suse/media-uvcvideo-Use-entity-get_cur-in-uvc_ctrl_set.patch + patches.suse/media-xilinx-vipp-Fix-refcount-leak-in-xvip_graph_dm.patch + patches.suse/hid-hid-logitech-hidpp-avoid-unnecessary-assignments.patch + patches.suse/HID-multitouch-Add-memory-barriers.patch + patches.suse/mfd-intel_soc_pmic-Fix-an-error-handling-path-in-int.patch + patches.suse/mfd-fsl-imx25-Fix-an-error-handling-path-in-mx25_tsa.patch + patches.suse/mfd-lp8788-Fix-an-error-handling-path-in-lp8788_prob.patch + patches.suse/mfd-lp8788-Fix-an-error-handling-path-in-lp8788_irq_.patch + patches.suse/mfd-fsl-imx25-Fix-check-for-platform_get_irq-errors.patch + patches.suse/mfd-sm501-Add-check-for-platform_driver_register.patch + patches.suse/HSI-omap_ssi-Fix-refcount-leak-in-ssi_probe.patch + patches.suse/HSI-omap_ssi_port-Fix-dma_map_sg-error-check.patch + patches.suse/remoteproc-imx_rproc-Simplify-some-error-message.patch + patches.suse/mtd-devices-docg3-check-the-return-value-of-devm_ior.patch + patches.suse/dt-bindings-mtd-intel-lgm-nand-Fix-compatible-string.patch + patches.suse/dt-bindings-mtd-intel-lgm-nand-Fix-maximum-chip-sele.patch + patches.suse/mtd-rawnand-intel-Read-the-chip-select-line-from-the.patch + patches.suse/mtd-rawnand-intel-Remove-undocumented-compatible-str.patch + patches.suse/mtd-rawnand-intel-Don-t-re-define-NAND_DATA_IFACE_CH.patch + patches.suse/mtd-rawnand-fsl_elbc-Fix-none-ECC-mode.patch + patches.suse/mtd-rawnand-meson-fix-bit-map-use-in-meson_nfc_ecc_c.patch + patches.suse/mtd-rawnand-atmel-Unmap-streaming-DMA-mappings.patch patches.suse/scsi-lpfc-Fix-unsolicited-FLOGI-receive-handling-dur.patch patches.suse/scsi-lpfc-Fix-null-ndlp-ptr-dereference-in-abnormal-.patch patches.suse/scsi-lpfc-Rework-MIB-Rx-Monitor-debug-info-logic.patch @@ -16234,6 +17194,196 @@ patches.suse/scsi-lpfc-Remove-SANDiags-related-code.patch patches.suse/scsi-lpfc-Update-lpfc-version-to-14.2.0.6.patch patches.suse/scsi-lpfc-Copyright-updates-for-14.2.0.6-patches.patch + patches.suse/scsi-qla2xxx-remove-unused-del_sess_list-field.patch + patches.suse/scsi-qla2xxx-remove-unused-qlt_tmr_work.patch + patches.suse/scsi-qla2xxx-always-wait-for-qlt_sess_work_fn-from.patch + patches.suse/scsi-qla2xxx-avoid-flush_scheduled_work-usage.patch + patches.suse/scsi-qla2xxx-log-message-skipping-scsi_scan_host-as.patch + patches.suse/scsi-qla2xxx-revert-scsi-qla2xxx-fix-response-queue-handler.patch + patches.suse/scsi-qla2xxx-fix-response-queue-handler-reading-stale-packets.patch + patches.suse/scsi-qla2xxx-add-debugfs-create-delete-helpers.patch + patches.suse/scsi-qla2xxx-add-nvme-parameters-support-in-auxiliary-image-status.patch + patches.suse/scsi-qla2xxx-enhance-driver-tracing-with-separate-tunable-and-more.patch + patches.suse/scsi-qla2xxx-define-static-symbols.patch + patches.suse/scsi-qla2xxx-update-version-to-10.02.07.900-k.patch + patches.suse/scsi-lpfc-remove-the-unneeded-result-variable.patch + patches.suse/scsi-lpfc-remove-unneeded-result-variable.patch + patches.suse/scsi-qla2xxx-drop-did_target_failure-use.patch + patches.suse/scsi-qla2xxx-fix-spelling-mistake-definiton-definition.patch + patches.suse/scsi-qla2xxx-remove-unused-declarations-for-qla2xxx.patch + patches.suse/scsi-lpfc-fix-prli_fc4_req-checks-in-prli-handling.patch + patches.suse/scsi-lpfc-fix-flogi-acc-with-wrong-sid-in-pt2pt-topology.patch + patches.suse/scsi-lpfc-fix-mbuf-pool-resource-detected-as-busy-at-driver-unload.patch + patches.suse/scsi-lpfc-add-missing-free-iocb-and-nlp-kref-put-for-early-return.patch + patches.suse/scsi-lpfc-fix-multiple-nvme-remoteport-registration-calls-for-the.patch + patches.suse/scsi-lpfc-move-scsi_host_template-outside-dynamically.patch + patches.suse/scsi-lpfc-update-congestion-mode-logging-for-emulex-san-manager.patch + patches.suse/scsi-lpfc-rename-mp-bmp-dma-buffers-to-rq-rsp-in-lpfc_fdmi_cmd.patch + patches.suse/scsi-lpfc-rework-lpfc_fdmi_cmd-routine-for-cleanup-and.patch + patches.suse/scsi-lpfc-rework-fdmi-attribute-registration-for-unintential.patch + patches.suse/scsi-lpfc-add-reporting-capability-for-link-degrade-signaling.patch + patches.suse/scsi-lpfc-fix-various-issues-reported-by-tools.patch + patches.suse/scsi-lpfc-update-lpfc-version-to-14.2.0.7.patch + patches.suse/scsi-stex-Properly-zero-out-the-passthrough-command-structure.patch + patches.suse/dmaengine-hisilicon-Disable-channels-when-unregister.patch + patches.suse/dmaengine-hisilicon-Fix-CQ-head-update.patch + patches.suse/dmaengine-hisilicon-Add-multi-thread-support-for-a-D.patch + patches.suse/dmaengine-mxs-use-platform_driver_register.patch + patches.suse/dmaengine-ioat-stop-mod_timer-from-resurrecting-dele.patch + patches.suse/dt-bindings-phy-qcom-qmp-fix-bogus-clock-cells-prope.patch + patches.suse/dt-bindings-phy-qcom-qmp-usb3-dp-fix-bogus-clock-cel.patch + patches.suse/phy-amlogic-phy-meson-axg-mipi-pcie-analog-Hold-refe.patch + patches.suse/phy-qualcomm-call-clk_disable_unprepare-in-the-error.patch + patches.suse/tty-xilinx_uartps-Fix-the-ignore_status.patch + patches.suse/drivers-serial-jsm-fix-some-leaks-in-probe.patch + patches.suse/tty-serial-fsl_lpuart-disable-dma-rx-tx-use-flags-in.patch + patches.suse/serial-8250-Fix-restoring-termios-speed-after-suspen.patch + patches.suse/usb-common-debug-Check-non-standard-control-requests.patch + patches.suse/usb-hcd-Fix-dma_map_sg-error-check.patch + patches.suse/usb-host-Initiate-urb-ep-with-udev-ep0.patch + patches.suse/USB-hcd-pci-Drop-the-unused-id-parameter-from-usb_hc.patch + patches.suse/USB-xhci-make-xhci_get_endpoint_address-static.patch + patches.suse/USB-serial-ftdi_sio-fix-300-bps-rate-for-SIO.patch + patches.suse/USB-serial-console-move-mutex_unlock-before-usb_seri.patch + patches.suse/xhci-dbc-Fix-memory-leak-in-xhci_alloc_dbc.patch + patches.suse/xhci-Don-t-show-warning-for-reinit-on-known-broken-s.patch + patches.suse/xhci-remove-unused-command-member-from-struct-xhci_h.patch + patches.suse/xhci-remove-unused-lpm_failed_dev-member-from-struct.patch + patches.suse/usb-gadget-function-fix-dangling-pnp_string-in-f_pri.patch + patches.suse/usb-mon-make-mmapped-memory-read-only.patch + patches.suse/USB-add-RESET_RESUME-quirk-for-NVIDIA-Jetson-devices.patch + patches.suse/Revert-usb-storage-Add-quirk-for-Samsung-Fit-flash.patch + patches.suse/usb-mtu3-fix-failed-runtime-suspend-in-host-only-mod.patch + patches.suse/USB-serial-qcserial-add-new-usb-id-for-Dell-branded-.patch + patches.suse/misc-ocxl-fix-possible-refcount-leak-in-afu_ioctl.patch + patches.suse/virt-vbox-convert-to-use-dev_groups.patch + patches.suse/misc-pci_endpoint_test-Aggregate-params-checking-for.patch + patches.suse/misc-pci_endpoint_test-Fix-pci_endpoint_test_-copy-w.patch + patches.suse/fpga-prevent-integer-overflow-in-dfl_feature_ioctl_s.patch + patches.suse/iio-adc-at91-sama5d2_adc-fix-AT91_SAMA5D2_MR_TRACKTI.patch + patches.suse/iio-adc-at91-sama5d2_adc-check-return-status-for-pre.patch + patches.suse/iio-adc-at91-sama5d2_adc-lock-around-oversampling-an.patch + patches.suse/iio-adc-at91-sama5d2_adc-disable-prepare-buffer-on-s.patch + patches.suse/iio-inkern-only-release-the-device-node-when-done-wi.patch + patches.suse/iio-inkern-fix-return-value-in-devm_of_iio_channel_g.patch + patches.suse/iio-ABI-Fix-wrong-format-of-differential-capacitance.patch + patches.suse/iio-magnetometer-yas530-Change-data-type-of-hard_off.patch + patches.suse/slimbus-qcom-ngd-use-correct-error-in-message-of-pdr.patch + patches.suse/slimbus-qcom-ngd-cleanup-in-probe-error-path.patch + patches.suse/firmware-google-Test-spinlock-on-panic-path-to-avoid.patch + patches.suse/iio-dac-ad5593r-Fix-i2c-read-protocol-requirements.patch + patches.suse/iio-ltc2497-Fix-reading-conversion-results.patch + patches.suse/iio-adc-ad7923-fix-channel-readings-for-some-variant.patch + patches.suse/spmi-pmic-arb-do-not-ack-and-clear-peripheral-interr.patch + patches.suse/spmi-pmic-arb-correct-duplicate-APID-to-PPID-mapping.patch + patches.suse/staging-vt6655-fix-some-erroneous-memory-clean-up-lo.patch + patches.suse/clk-meson-Hold-reference-returned-by-of_get_parent.patch + patches.suse/clk-oxnas-Hold-reference-returned-by-of_get_parent.patch + patches.suse/clk-qoriq-Hold-reference-returned-by-of_get_parent.patch + patches.suse/clk-berlin-Add-of_node_put-for-of_get_parent.patch + patches.suse/clk-sprd-Hold-reference-returned-by-of_get_parent.patch + patches.suse/clk-tegra-Fix-refcount-leak-in-tegra210_clock_init.patch + patches.suse/clk-tegra-Fix-refcount-leak-in-tegra114_clock_init.patch + patches.suse/clk-tegra20-Fix-refcount-leak-in-tegra20_clock_init.patch + patches.suse/clk-ti-dra7-atl-Fix-reference-leak-in-of_dra7_atl_cl.patch + patches.suse/clk-mediatek-mt8183-mfgcfg-Propagate-rate-changes-to.patch + patches.suse/clk-ast2600-BCLK-comes-from-EPLL.patch + patches.suse/clk-qcom-gcc-msm8916-use-ARRAY_SIZE-instead-of-speci.patch + patches.suse/clk-qcom-apss-ipq6018-mark-apcs_alias0_core_clk-as-c.patch + patches.suse/clk-imx-scu-fix-memleak-on-platform_device_add-fails.patch + patches.suse/clk-vc5-Fix-5P49V6901-outputs-disabling-when-enablin.patch + patches.suse/clk-baikal-t1-Fix-invalid-xGMAC-PTP-clock-divider.patch + patches.suse/clk-baikal-t1-Add-shared-xGMAC-ref-ptp-clocks-intern.patch + patches.suse/clk-baikal-t1-Add-SATA-internal-ref-clock-buffer.patch + patches.suse/clk-bcm2835-Round-UART-input-clock-up.patch + patches.suse/clk-bcm2835-fix-bcm2835_clock_rate_from_divisor-decl.patch + patches.suse/clk-bcm-rpi-Add-support-for-VEC-clock.patch + patches.suse/mailbox-mpfs-fix-handling-of-the-reg-property.patch + patches.suse/mailbox-mpfs-account-for-mbox-offsets-while-sending.patch + patches.suse/mailbox-bcm-ferxrm-mailbox-Fix-error-check-for-dma_m.patch + patches.suse/efi-libstub-drop-pointless-get_memory_map-call.patch + patches.suse/KVM-VMX-Inject-PF-on-ENCLS-as-emulated-PF.patch + patches.suse/powerpc-pci_dn-Add-missing-of_node_put.patch + patches.suse/powerpc-powernv-add-missing-of_node_put-in-opal_expo.patch + patches.suse/Revert-powerpc-rtas-Implement-reentrant-rtas-call.patch + patches.suse/powerpc-64-Remove-unused-SYS_CALL_TABLE-symbol.patch + patches.suse/powerpc-mm-64s-Drop-pgd_huge.patch + patches.suse/powerpc-kprobes-Fix-null-pointer-reference-in-arch_p.patch + patches.suse/powerpc-pseries-vas-Pass-hw_cpu_id-to-node-associati.patch + patches.suse/crypto-sahara-don-t-sleep-when-in-softirq.patch + patches.suse/crypto-hisilicon-zip-fix-mismatch-in-get-set-sgl_sge.patch + patches.suse/crypto-qat-fix-default-value-of-WDT-timer.patch + patches.suse/crypto-akcipher-default-implementation-for-setting-a.patch + patches.suse/crypto-ccp-Release-dma-channels-before-dmaengine-unr.patch + patches.suse/crypto-inside-secure-Change-swab-to-swab32.patch + patches.suse/Revert-crypto-qat-reduce-size-of-mapped-region.patch + patches.suse/crypto-inside-secure-Replace-generic-aes-with-libaes.patch + patches.suse/crypto-marvell-octeontx-prevent-integer-overflows.patch + patches.suse/crypto-cavium-prevent-integer-overflow-loading-firmw.patch + patches.suse/selftest-tpm2-Add-Client.__del__-to-close-dev-tpm-ha.patch + patches.suse/dt-bindings-crypto-ti-sa2ul-drop-dma-coherent-proper.patch + patches.suse/lib-sg_pool-change-module_init-sg_pool_init-to-subsy.patch + patches.suse/ACPI-APEI-do-not-add-task_work-to-kernel-thread-to-a.patch + patches.suse/Input-xpad-add-supported-devices-as-contributed-on-g.patch + patches.suse/Input-xpad-fix-wireless-360-controller-breaking-afte.patch + patches.suse/Input-synaptics-rmi4-fix-firmware-update-operations-.patch + patches.suse/Input-i8042-fix-refount-leak-on-sparc.patch + patches.suse/pinctrl-armada-37xx-Add-missing-GPIO-only-pins.patch + patches.suse/pinctrl-armada-37xx-Fix-definitions-for-MPP-pins-20-.patch + patches.suse/pinctrl-armada-37xx-Checks-for-errors-in-gpio_reques.patch + patches.suse/pinctrl-microchip-sgpio-Correct-the-fwnode_irq_get-r.patch + patches.suse/i2c-designware-Fix-handling-of-real-but-unexpected-d.patch + patches.suse/PCI-ASPM-Ignore-L1-PM-Substates-if-device-lacks-capa.patch + patches.suse/PCI-ASPM-Correct-LTR_L1.2_THRESHOLD-computation.patch + patches.suse/PCI-Fix-used_buses-calculation-in-pci_scan_child_bus.patch + patches.suse/PCI-Sanitise-firmware-BAR-assignments-behind-a-PCI-P.patch + patches.suse/dt-bindings-PCI-microchip-pcie-host-fix-missing-cloc.patch + patches.suse/dt-bindings-PCI-microchip-pcie-host-fix-missing-dma-.patch + patches.suse/PCI-mediatek-gen3-Change-driver-name-to-mtk-pcie-gen.patch + patches.suse/irqchip-ls-extirq-Fix-invalid-wait-context-by-avoidi.patch + patches.suse/drm-i915-gvt-fix-a-memory-leak-in-intel_gvt_init_vgp.patch + patches.suse/watchdog-hpwdt-Include-nmi.h-only-if-CONFIG_HPWDT_NM.patch + patches.suse/watchdog-ftwdt010_wdt-fix-test-for-platform_get_irq-.patch + patches.suse/watchdog-armada_37xx_wdt-Fix-.set_timeout-callback.patch + patches.suse/net-ieee802154-return-EINVAL-for-unknown-addr-type.patch + patches.suse/mISDN-hfcpci-Fix-use-after-free-bug-in-hfcpci_softir.patch + patches.suse/macvlan-enforce-a-consistent-minimal-mtu.patch + patches.suse/can-kvaser_usb-Fix-use-of-uninitialized-completion.patch + patches.suse/can-kvaser_usb_leaf-Fix-TX-queue-out-of-sync-after-r.patch + patches.suse/can-kvaser_usb_leaf-Fix-CAN-state-after-restart.patch + patches.suse/wifi-mac80211-do-not-drop-packets-smaller-than-the-L.patch + patches.suse/wifi-mac80211-fix-probe-req-HE-capabilities-access.patch + patches.suse/wifi-mac80211-fix-decap-offload-for-stations-on-AP_V.patch + patches.suse/wifi-cfg80211-fix-ieee80211_data_to_8023_exthdr-hand.patch + patches.suse/wifi-iwlwifi-mvm-fix-double-list_add-at-iwl_mvm_mac_-95b0f66649bb.patch + patches.suse/selftests-netfilter-Fix-nft_fib.sh-for-all.rp_filter.patch + patches.suse/openvswitch-add-nf_ct_is_confirmed-check-before-assi.patch + patches.suse/wifi-cfg80211-fix-u8-overflow-in-cfg80211_update_not.patch + patches.suse/wifi-cfg80211-mac80211-reject-bad-MBSSID-elements.patch + patches.suse/wifi-mac80211-fix-MBSSID-parsing-use-after-free.patch + patches.suse/wifi-cfg80211-ensure-length-byte-is-present-before-a.patch + patches.suse/wifi-cfg80211-fix-BSS-refcounting-bugs.patch + patches.suse/wifi-cfg80211-avoid-nontransmitted-BSS-list-corrupti.patch + patches.suse/wifi-mac80211_hwsim-avoid-mac80211-warning-on-bad-ra.patch + patches.suse/wifi-mac80211-fix-crash-in-beacon-protection-for-P2P.patch + patches.suse/wifi-cfg80211-update-hidden-BSSes-to-avoid-WARN_ON.patch + patches.suse/mmc-sdhci-sprd-Fix-minimum-clock-limit.patch + patches.suse/drm-i915-ehl-Update-MOCS-table-for-EHL.patch + patches.suse/Revert-drm-amdgpu-use-dirty-framebuffer-helper.patch + patches.suse/drm-amd-pm-smu7_hwmgr-fix-potential-off-by-one-overf.patch + patches.suse/arm64-mte-Avoid-setting-PG_mte_tagged-if-no-tags-cle.patch + patches.suse/ALSA-hda-realtek-remove-ALC289_FIXUP_DUAL_SPK-for-De.patch + patches.suse/ALSA-hda-realtek-Correct-pin-configs-for-ASUS-G533Z.patch + patches.suse/ALSA-hda-realtek-Add-quirk-for-ASUS-GV601R-laptop.patch + patches.suse/ALSA-hda-realtek-Add-Intel-Reference-SSID-to-support.patch + patches.suse/ALSA-rawmidi-Drop-register_mutex-in-snd_rawmidi_free.patch + patches.suse/ALSA-oss-Fix-potential-deadlock-at-unregistration.patch + patches.suse/rtc-stmp3xxx-Add-failure-handling-for-stmp3xxx_wdt_r.patch + patches.suse/ACPI-HMAT-Release-platform-device-in-case-of-platfor.patch + patches.suse/clk-at91-fix-the-build-with-binutils-2.27.patch + + # netdev/net + patches.suse/ipv4-Handle-attempt-to-delete-multipath-route-when-f.patch ######################################################## # end of sorted patches @@ -16264,21 +17414,6 @@ patches.suse/static_call-Fix-tools_headers.patch patches.suse/sched-preempt-Tell-about-PREEMPT_DYNAMIC-on-kernel-h.patch patches.suse/nvme-consider-also-host_iface-when-checking-ip-options.patch - patches.suse/drm-udl-Replace-semaphore-with-a-simple-wait-queue.patch - patches.suse/drm-udl-Sync-pending-URBs-at-suspend-disconnect.patch - patches.suse/drm-udl-Kill-pending-URBs-at-suspend-and-disconnect.patch - patches.suse/drm-udl-Replace-BUG_ON-with-WARN_ON.patch - patches.suse/drm-udl-Restore-display-mode-on-resume.patch - patches.suse/drm-udl-Add-reset_resume.patch - patches.suse/drm-udl-Enable-damage-clipping.patch - patches.suse/Revert-drm-udl-Kill-pending-URBs-at-suspend-and-disc.patch - patches.suse/drm-udl-Suppress-error-print-for-EPROTO-at-URB-compl.patch - patches.suse/drm-udl-Increase-the-default-URB-list-size-to-20.patch - patches.suse/drm-udl-Drop-unneeded-alignment.patch - patches.suse/drm-udl-Fix-potential-URB-leaks.patch - patches.suse/drm-udl-Fix-inconsistent-urbs.count-value-during-udl.patch - patches.suse/drm-udl-Don-t-re-initialize-stuff-at-retrying-the-UR.patch - patches.suse/drm-udl-Sync-pending-URBs-at-the-end-of-suspend.patch patches.suse/netfilter-nf_conntrack_irc-Tighten-matching-on-DCC-m.patch patches.suse/nvmet-expose-max-queues-to-configfs.patch @@ -16289,6 +17424,18 @@ patches.suse/ice-Allow-operation-with-reduced-device-MSI-X.patch patches.suse/ppc64-kdump-Limit-kdump-base-to-512MB.patch + patches.suse/media-dvb-core-Fix-UAF-due-to-refcount-races-at-rele.patch + + patches.suse/scsi-core-Add-BLIST_NO_ASK_VPD_SIZE-for-some-VDASD.patch + patches.suse/fbdev-smscufx-Fix-use-after-free-in-ufx_ops_open.patch + patches.suse/char-pcmcia-synclink_cs-Fix-use-after-free-in-mgslpc.patch + patches.suse/misc-sgi-gru-fix-use-after-free-error-in-gru_set_con.patch + + patches.suse/ALSA-hda-hda_cs_dsp_ctl-Minor-clean-and-redundant-co.patch + patches.suse/ALSA-hda-hda_cs_dsp_ctl-Ensure-pwr_lock-is-held-befo.patch + patches.suse/ALSA-hda-cs_dsp_ctl-Fix-mutex-inversion-when-creatin.patch + patches.suse/ALSA-hda-cs35l41-Remove-suspend-resume-hda-hooks.patch + patches.suse/ALSA-hda-cs35l41-Support-System-Suspend.patch ######################################################## # kbuild/module infrastructure fixes @@ -16346,6 +17493,7 @@ patches.suse/x86-apic-force-bigsmp-apic-on-IBM-EXA3-4.patch # s390x + patches.suse/s390-qeth-remove-OSN-deprecation-notice.patch +ptesarik +sp4_needs_review patches.suse/s390-sles15sp2-kdump-fix-out-of-memory-with-PCI.patch # ppc64 @@ -16550,6 +17698,7 @@ patches.suse/thermal-Add-a-sanity-check-for-invalid-state-at-stat.patch # Bug 1201308 - Partner-L3: HP Z2 G8 Workstation: supportconfig reboots on systool command patches.suse/thermal-int340x_thermal-handle-data_vault-when-the-v.patch + patches.suse/ACPI-processor-idle-Practically-limit-Dummy-wait-wor.patch ######################################################## # DRM / Graphics @@ -16604,7 +17753,6 @@ patches.suse/nvme-auth-align-to-pre-upstream-FFDHE-implementation.patch patches.suse/qla2xxx-add-module_version-back-to-driver.patch - patches.suse/lpfc-decouple-port_template-and-vport_template.patch patches.suse/lpfc-reintroduce-old-irq-probe-logic.patch patches.suse/rdma-addr-create-addr_wq-with-wq_mem_reclaim-flag.patch patches.suse/rdma-core-create-ib_cm-with-wq_mem_reclaim-flag.patch diff --git a/supported.conf b/supported.conf index 787aa0d..79aa283 100644 --- a/supported.conf +++ b/supported.conf @@ -729,6 +729,7 @@ - drivers/firmware/arm_scmi/scmi_pm_domain drivers/firmware/arm_scpi - drivers/firmware/broadcom/tee_bnxt_fw + drivers/firmware/cirrus/cs_dsp drivers/firmware/dmi-sysfs # fate#320109 +base drivers/firmware/edd drivers/firmware/efi/capsule-loader # fate#319346 @@ -3462,7 +3463,6 @@ drivers/platform/x86/hp-wmi drivers/platform/x86/hp_accel # HP 3D DriveGuard (FATE #306448) - drivers/platform/x86/huawei-wmi - drivers/platform/x86/i2c-multi-instantiate # some type C controllers need this - drivers/platform/x86/ibm_rtl - drivers/platform/x86/ideapad-laptop - drivers/platform/x86/intel-hid @@ -3514,6 +3514,7 @@ - drivers/platform/x86/peaq-wmi - drivers/platform/x86/samsung-laptop - drivers/platform/x86/samsung-q10 + drivers/platform/x86/serial-multi-instantiate drivers/platform/x86/sony-laptop - drivers/platform/x86/system76_acpi -!optional drivers/platform/x86/think-lmi @@ -4030,7 +4031,7 @@ drivers/spi/spi-orion # fate#319899 fate#320700 -!optional drivers/spi/spi-pl022 -!optional drivers/spi/spi-pxa2xx-pci --!optional drivers/spi/spi-pxa2xx-platform + drivers/spi/spi-pxa2xx-platform - drivers/spi/spi-qcom-qspi -!optional drivers/spi/spi-qup -!optional drivers/spi/spi-rockchip @@ -4681,6 +4682,7 @@ -!optional drivers/virt/acrn/acrn drivers/virt/nitro_enclaves/nitro_enclaves - drivers/virt/vboxguest/vboxguest ++base drivers/virt/coco/sevguest/sevguest +base drivers/virtio/virtio +base drivers/virtio/virtio_balloon drivers/virtio/virtio_dma_buf