From 75f7e2d10bf2a09616090d02726b15d5eb0a153b Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Tue, 4 Apr 2023 06:43:23 +0200 Subject: [PATCH 01/14] odhcpd: bump to latest git HEAD 40ab806 config: use dedicated link local function to check interface a84bff2 netlink: add support for getting interface linklocal 2ea065f Revert "config: recheck have_link_local on interface reload if already init" 4b38e6b config: fix feature for enabling service only when interface RUNNING Signed-off-by: Christian Marangi --- package/network/services/odhcpd/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package/network/services/odhcpd/Makefile b/package/network/services/odhcpd/Makefile index f2d698b8b0e..c471c7c75d2 100644 --- a/package/network/services/odhcpd/Makefile +++ b/package/network/services/odhcpd/Makefile @@ -12,9 +12,9 @@ PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/odhcpd.git -PKG_MIRROR_HASH:=f95c2edfa6756e2a6522cd9d3e0560bfc1cbc2aed9e0c3763c5f6081b153eb49 -PKG_SOURCE_DATE:=2023-03-24 -PKG_SOURCE_VERSION:=29c934d7ab98ca0b5da0e3757b885a1d3c19a2f4 +PKG_MIRROR_HASH:=c2851b577d1ee632c902eca1864444fa22cad98956bfa852019e6d621c0f8d2a +PKG_SOURCE_DATE:=2023-04-05 +PKG_SOURCE_VERSION:=40ab806bf4c8698ac925d094ce11ce1d57ae2e46 PKG_MAINTAINER:=Hans Dedecker PKG_LICENSE:=GPL-2.0 From 975036f6f9c8b12fbf82854ea006b4951c5be783 Mon Sep 17 00:00:00 2001 From: Eneas U de Queiroz Date: Fri, 10 Mar 2023 17:21:11 -0300 Subject: [PATCH 02/14] openssl: avoid OPENSSL_SMALL_FOOTPRINT, no-asm Building openssl with OPENSSL_SMALL_FOOTPRINT yelds only from 1% to 3% decrease in size, dropping performance from 2% to 91%, depending on the target and algorithm. For example, using AES256-GCM with 1456-bytes operations, X86_64 appears to be the least affected with 2% performance penalty and 1% reduction in size; mips drops performance by 13%, size by 3%; Arm drops 29% in performance, 2% in size. On aarch64, it slows down ghash so much that I consider it broken (-91%). SMALL_FOOTPRINT will reduce AES256-GCM performance by 88%, and size by only 1%. It makes an AES-capable CPU run AES128-GCM at 35% of the speed of Chacha20-Poly1305: Block-size=1456 bytes AES256-GCM AES128-GCM ChaCha20-Poly1305 SMALL_FOOTPRINT 62014.44 65063.23 177090.50 regular 504220.08 565630.28 182706.16 OpenSSL 1.1.1 numbers are about the same, so this should have been noticed a long time ago. This creates an option to use OPENSSL_SMALL_FOOTPRINT, but it is turned off by default unless SMALL_FLASH or LOW_MEMORY_FOOTPRINT is used. Compiling with -O3 instead of -Os, for comparison, will increase size by about 14-15%, with no measureable effect on AES256-GCM performance, and about 2% increase in Chacha20-Poly1305 performance on Aarch64. There are no Arm devices with the small flash feature, so drop the conditional default. The package is built on phase2, so even if we include an Arm device with small flash later, a no-asm library would have to be built from source anyway. Signed-off-by: Eneas U de Queiroz --- package/libs/openssl/Config.in | 18 ++++++++++++++++-- package/libs/openssl/Makefile | 7 +++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/package/libs/openssl/Config.in b/package/libs/openssl/Config.in index 6a668fe4cd3..b948aab7093 100644 --- a/package/libs/openssl/Config.in +++ b/package/libs/openssl/Config.in @@ -12,9 +12,23 @@ config OPENSSL_OPTIMIZE_SPEED The increase in performance and size depends on the target CPU. EC and AES seem to benefit the most. +config OPENSSL_SMALL_FOOTPRINT + bool + depends on !OPENSSL_OPTIMIZE_SPEED + default y if SMALL_FLASH || LOW_MEMORY_FOOTPRINT + prompt "Build with OPENSSL_SMALL_FOOTPRINT (read help)" + help + This turns on -DOPENSSL_SMALL_FOOTPRINT. This will save only + 1-3% of of the ipk size. The performance drop depends on + architecture and algorithm. MIPS drops 13% of performance for + a 3% decrease in ipk size. On Aarch64, for a 1% reduction in + size, ghash and GCM performance decreases 90%, while + Chacha20-Poly1305 is 15% slower. X86_64 drops 1% of its size + for 3% of performance. Other arches have not been tested. + config OPENSSL_WITH_ASM bool - default y if !SMALL_FLASH || !arm + default y prompt "Compile with optimized assembly code" depends on !arc help @@ -46,7 +60,7 @@ config OPENSSL_NO_DEPRECATED config OPENSSL_WITH_ERROR_MESSAGES bool - default y if !SMALL_FLASH && !LOW_MEMORY_FOOTPRINT + default y if !OPENSSL_SMALL_FOOTPRINT || (!SMALL_FLASH && !LOW_MEMORY_FOOTPRINT) prompt "Include error messages" help This option aids debugging, but increases package size and diff --git a/package/libs/openssl/Makefile b/package/libs/openssl/Makefile index 9fe5da9dd34..b076a9c1fa1 100644 --- a/package/libs/openssl/Makefile +++ b/package/libs/openssl/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=openssl PKG_VERSION:=3.0.8 -PKG_RELEASE:=4 +PKG_RELEASE:=5 PKG_BUILD_FLAGS:=no-mips16 gc-sections PKG_BUILD_PARALLEL:=1 @@ -39,6 +39,7 @@ PKG_CONFIG_DEPENDS:= \ CONFIG_OPENSSL_NO_DEPRECATED \ CONFIG_OPENSSL_OPTIMIZE_SPEED \ CONFIG_OPENSSL_PREFER_CHACHA_OVER_GCM \ + CONFIG_OPENSSL_SMALL_FOOTPRINT \ CONFIG_OPENSSL_WITH_ARIA \ CONFIG_OPENSSL_WITH_ASM \ CONFIG_OPENSSL_WITH_ASYNC \ @@ -258,7 +259,9 @@ endif ifeq ($(CONFIG_OPENSSL_OPTIMIZE_SPEED),y) TARGET_CFLAGS := $(filter-out -O%,$(TARGET_CFLAGS)) -O3 -else +endif + +ifeq ($(CONFIG_OPENSSL_SMALL_FOOTPRINT),y) OPENSSL_OPTIONS += -DOPENSSL_SMALL_FOOTPRINT endif From 0b70d55a64c39da4144cc15aa7d6de70a3957ccb Mon Sep 17 00:00:00 2001 From: Eneas U de Queiroz Date: Tue, 14 Mar 2023 18:51:45 -0300 Subject: [PATCH 03/14] openssl: make UCI config aware of built-in engines Engines that are built into the main libcrypto OpenSSL library can't be disabled through UCI. Add a 'builtin' setting to signal that the engine can't be disabled through UCI, and show a message explaining this in case buitin=1 and enabled=0. Signed-off-by: Eneas U de Queiroz --- package/libs/openssl/Makefile | 26 ++++++++++++++++++++++++- package/libs/openssl/files/openssl.init | 25 +++++++++++++++++------- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/package/libs/openssl/Makefile b/package/libs/openssl/Makefile index b076a9c1fa1..66872d54366 100644 --- a/package/libs/openssl/Makefile +++ b/package/libs/openssl/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=openssl PKG_VERSION:=3.0.8 -PKG_RELEASE:=5 +PKG_RELEASE:=6 PKG_BUILD_FLAGS:=no-mips16 gc-sections PKG_BUILD_PARALLEL:=1 @@ -138,6 +138,30 @@ $(call Package/openssl/Default/description) This package installs the OpenSSL configuration file /etc/ssl/openssl.cnf. endef +ifneq ($(CONFIG_OPENSSL_ENGINE_BUILTIN_PADLOCK)$(CONFIG_OPENSSL_ENGINE_BUILTIN_DEVCRYPTO),) +define Package/libopenssl-conf/postinst +#!/bin/sh +OPENSSL_UCI="$${IPKG_INSTROOT}/etc/config/openssl" + +add_engine_config() { + if [ -z "$${IPKG_INSTROOT}" ] && uci -q get "openssl.$$1" >/dev/null; then + [ "$$(uci -q get "openssl.$$1.builtin")" = 1 ] && return + uci set "openssl.$$1.builtin=1" && uci commit openssl + return + fi + { + echo "engine '$$1'" + echo " option enabled '1'" + echo " option builtin '1'" + echo + } >>"$${OPENSSL_UCI}" +} + +$(if $(CONFIG_OPENSSL_ENGINE_BUILTIN_DEVCRYPTO),add_engine_config devcrypto) +$(if $(CONFIG_OPENSSL_ENGINE_BUILTIN_PADLOCK),add_engine_config padlock) +endef +endif + $(eval $(call Package/openssl/add-engine,afalg)) define Package/libopenssl-afalg $(call Package/openssl/Default) diff --git a/package/libs/openssl/files/openssl.init b/package/libs/openssl/files/openssl.init index 21e253e7a56..f895b9878c8 100755 --- a/package/libs/openssl/files/openssl.init +++ b/package/libs/openssl/files/openssl.init @@ -6,15 +6,26 @@ ENGINES_CNF="/var/etc/ssl/engines.cnf" ENGINES_DIR="%ENGINES_DIR%" config_engine() { - local enabled force + local builtin enabled force + + config_get_bool builtin "$1" builtin 0 config_get_bool enabled "$1" enabled 1 config_get_bool force "$1" force 0 - [ "$enabled" = 0 ] && return - if [ "$force" = 0 ] && \ - [ ! -f "${ENGINES_CNF_D}/$1.cnf" ] && \ - [ ! -f "${ENGINES_DIR}/$1.so" ]; then - echo Skipping engine "$1": not installed - return + + if [ "$enabled" = 0 ]; then + [ "$builtin" != 1 ] && return 1 + echo "Engine $1 is built into the libcrypto library and can't be disabled through UCI." && \ + echo "If the engine was not built-in, remove 'config builtin' from /etc/config/openssl." + elif [ "$force" = 1 ]; then + printf "[Forced] " + elif ! grep -q "\\[ *$1 *]" "${ENGINES_CNF_D}"/*; then + echo "$1: Could not find section [$1] in config files." + return 1 + elif [ "$builtin" = 1 ]; then + printf "[Builtin] " + elif [ ! -f "${ENGINES_DIR}/$1.so" ];then + echo "$1: ${ENGINES_DIR}/$1.so not found." + return 1 fi echo Enabling engine "$1" echo "$1=$1" >> "${ENGINES_CNF}" From 0dc5fc8fa53be55c3adc59055e7f6f150a5ab1ad Mon Sep 17 00:00:00 2001 From: Eneas U de Queiroz Date: Fri, 10 Mar 2023 17:53:25 -0300 Subject: [PATCH 04/14] openssl: add legacy provider This adapts the engine build infrastructure to allow building providers, and packages the legacy provider. Providers are the successors of engines, which have been deprecated. The legacy provider supplies OpenSSL implementations of algorithms that have been deemed legacy, including DES, IDEA, MDC2, SEED, and Whirlpool. Even though these algorithms are implemented in a separate package, their removal makes the regular library smaller by 3%, so the build options will remain to allow lean custom builds. Their defaults will change to 'y' if not bulding for a small flash, so that the regular legacy package will contain a complete set of algorithms. The engine build and configuration structure was changed to accomodate providers, and adapt to the new style of openssl.cnf in version 3.0. There is not a clean upgrade path for the /etc/ssl/openssl.cnf file, installed by the openssl-conf package. It is recommended to rename or remove the old config file when flashing an image with the updated openssl-conf package, then apply the changes manually. An old openssl.cnf file will silently work, but new engine or provider packages will not be enabled. Any remaining engine config files under /etc/ssl/engines.cnf.d can be removed. On the build side, the include file used by engine packages was renamed to openssl-module.mk, so the engine packages in other feeds need to adapt. Signed-off-by: Eneas U de Queiroz --- include/openssl-engine.mk | 50 ------------ include/openssl-module.mk | 79 +++++++++++++++++++ package/libs/openssl/Config.in | 26 +++++- package/libs/openssl/Makefile | 35 +++++--- package/libs/openssl/files/afalg.cnf | 2 +- package/libs/openssl/files/devcrypto.cnf | 2 +- package/libs/openssl/files/legacy.cnf | 3 + package/libs/openssl/files/openssl.init | 64 +++++++++++---- package/libs/openssl/files/padlock.cnf | 2 +- .../150-openssl.cnf-add-engines-conf.patch | 34 +++++--- 10 files changed, 202 insertions(+), 95 deletions(-) delete mode 100644 include/openssl-engine.mk create mode 100644 include/openssl-module.mk create mode 100644 package/libs/openssl/files/legacy.cnf diff --git a/include/openssl-engine.mk b/include/openssl-engine.mk deleted file mode 100644 index 891d284f126..00000000000 --- a/include/openssl-engine.mk +++ /dev/null @@ -1,50 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2022-2023 Enéas Ulir de Queiroz - -ENGINES_DIR=engines-3 - -define Package/openssl/engine/Default - SECTION:=libs - CATEGORY:=Libraries - SUBMENU:=SSL - DEPENDS:=libopenssl @OPENSSL_ENGINE +libopenssl-conf -endef - -# 1 = engine name -# 2 - package name, defaults to libopenssl-$(1) -define Package/openssl/add-engine - OSSL_ENG_PKG:=$(if $(2),$(2),libopenssl-$(1)) - Package/$$(OSSL_ENG_PKG)/conffiles:=/etc/ssl/engines.cnf.d/$(1).cnf - - define Package/$$(OSSL_ENG_PKG)/install - $$(INSTALL_DIR) $$(1)/usr/lib/$(ENGINES_DIR) - $$(INSTALL_BIN) $$(PKG_INSTALL_DIR)/usr/lib/$(ENGINES_DIR)/$(1).so \ - $$(1)/usr/lib/$(ENGINES_DIR) - $$(INSTALL_DIR) $$(1)/etc/ssl/engines.cnf.d - $$(INSTALL_DATA) ./files/$(1).cnf $$(1)/etc/ssl/engines.cnf.d/ - endef - - define Package/$$(OSSL_ENG_PKG)/postinst := -#!/bin/sh -OPENSSL_UCI="$$$${IPKG_INSTROOT}/etc/config/openssl" - -[ -z "$$$${IPKG_INSTROOT}" ] && uci -q get openssl.$(1) >/dev/null && exit 0 - -cat << EOF >> "$$$${OPENSSL_UCI}" - -config engine '$(1)' - option enabled '1' -EOF - -[ -n "$$$${IPKG_INSTROOT}" ] || /etc/init.d/openssl reload - endef - - define Package/$$(OSSL_ENG_PKG)/postrm := -#!/bin/sh -[ -n "$$$${IPKG_INSTROOT}" ] && exit 0 -uci delete openssl.$(1) -uci commit openssl -/etc/init.d/openssl reload - endef -endef diff --git a/include/openssl-module.mk b/include/openssl-module.mk new file mode 100644 index 00000000000..7348a10dbc4 --- /dev/null +++ b/include/openssl-module.mk @@ -0,0 +1,79 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2022-2023 Enéas Ulir de Queiroz + +ENGINES_DIR=engines-3 + +define Package/openssl/module/Default + SECTION:=libs + CATEGORY:=Libraries + SUBMENU:=SSL + DEPENDS:=libopenssl +libopenssl-conf +endef + +define Package/openssl/engine/Default + $(Package/openssl/module/Default) + DEPENDS+=@OPENSSL_ENGINE +endef + + +# 1 = moudule type (engine|provider) +# 2 = module name +# 3 = directory to save .so file +# 4 = [ package name, defaults to libopenssl-$(2) ] +define Package/openssl/add-module + $(eval MOD_TYPE:=$(1)) + $(eval MOD_NAME:=$(2)) + $(eval MOD_DIR:=$(3)) + $(eval OSSL_PKG:=$(if $(4),$(4),libopenssl-$(MOD_NAME))) + $(info Package/openssl/add-module 1='$(1)'; 2='$(2)'; 3='$(3)' 4='$(4)') + $(info MOD_TYPE='$(MOD_TYPE)'; MOD_NAME='$(MOD_NAME)'; MOD_DIR='$(MOD_DIR)' OSSL_PKG='$(OSSL_PKG)') + Package/$(OSSL_PKG)/conffiles:=/etc/ssl/modules.cnf.d/$(MOD_NAME).cnf + + define Package/$(OSSL_PKG)/install + $$(INSTALL_DIR) $$(1)/$(MOD_DIR) + $$(INSTALL_BIN) $$(PKG_INSTALL_DIR)/$(MOD_DIR)/$(MOD_NAME).so \ + $$(1)/$(MOD_DIR) + $$(INSTALL_DIR) $$(1)/etc/ssl/modules.cnf.d + $$(INSTALL_DATA) ./files/$(MOD_NAME).cnf $$(1)/etc/ssl/modules.cnf.d/ + endef + + define Package/$(OSSL_PKG)/postinst +#!/bin/sh +OPENSSL_UCI="$$$${IPKG_INSTROOT}/etc/config/openssl" + +[ -z "$$$${IPKG_INSTROOT}" ] \ + && uci -q get openssl.$(MOD_NAME) >/dev/null \ + && exit 0 + +cat << EOF >> "$$$${OPENSSL_UCI}" + +config $(MOD_TYPE) '$(MOD_NAME)' + option enabled '1' +EOF + +[ -n "$$$${IPKG_INSTROOT}" ] || /etc/init.d/openssl reload +exit 0 + endef + + define Package/$(OSSL_PKG)/postrm +#!/bin/sh +[ -n "$$$${IPKG_INSTROOT}" ] && exit 0 +uci -q delete openssl.$(MOD_NAME) && uci commit openssl +/etc/init.d/openssl reload +exit 0 + endef +endef + +# 1 = engine name +# 2 - package name, defaults to libopenssl-$(1) +define Package/openssl/add-engine + $(call Package/openssl/add-module,engine,$(1),/usr/lib/$(ENGINES_DIR),$(2)) +endef + +# 1 = provider name +# 2 = [ package name, defaults to libopenssl-$(1) ] +define Package/openssl/add-provider + $(call Package/openssl/add-module,provider,$(1),/usr/lib/ossl-modules,$(2)) +endef + diff --git a/package/libs/openssl/Config.in b/package/libs/openssl/Config.in index b948aab7093..871080a4cbe 100644 --- a/package/libs/openssl/Config.in +++ b/package/libs/openssl/Config.in @@ -167,16 +167,24 @@ config OPENSSL_WITH_CAMELLIA config OPENSSL_WITH_IDEA bool - prompt "Enable IDEA cipher support" + default y if !SMALL_FLASH + prompt "Enable IDEA cipher support (needs legacy provider)" help IDEA is a block cipher with 128-bit keys. + To use the cipher, one must install the libopenssl-legacy + package, using a main libopenssl package compiled with this + option enabled as well. config OPENSSL_WITH_SEED bool - prompt "Enable SEED cipher support" + default y if !SMALL_FLASH + prompt "Enable SEED cipher support (needs legacy provider)" help SEED is a block cipher with 128-bit keys broadly used in South Korea, but seldom found elsewhere. + To use the cipher, one must install the libopenssl-legacy + package, using a main libopenssl package compiled with this + option enabled as well. config OPENSSL_WITH_SM234 bool @@ -197,11 +205,21 @@ config OPENSSL_WITH_BLAKE2 config OPENSSL_WITH_MDC2 bool - prompt "Enable MDC2 digest support" + default y if !SMALL_FLASH + prompt "Enable MDC2 digest support (needs legacy provider)" + help + To use the digest, one must install the libopenssl-legacy + package, using a main libopenssl package compiled with this + option enabled as well. config OPENSSL_WITH_WHIRLPOOL bool - prompt "Enable Whirlpool digest support" + default y if !SMALL_FLASH + prompt "Enable Whirlpool digest support (needs legacy provider)" + help + To use the digest, one must install the libopenssl-legacy + package, using a main libopenssl package compiled with this + option enabled as well. config OPENSSL_WITH_COMPRESSION bool diff --git a/package/libs/openssl/Makefile b/package/libs/openssl/Makefile index 66872d54366..add3eb7db66 100644 --- a/package/libs/openssl/Makefile +++ b/package/libs/openssl/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=openssl PKG_VERSION:=3.0.8 -PKG_RELEASE:=6 +PKG_RELEASE:=7 PKG_BUILD_FLAGS:=no-mips16 gc-sections PKG_BUILD_PARALLEL:=1 @@ -64,7 +64,7 @@ PKG_CONFIG_DEPENDS:= \ CONFIG_OPENSSL_WITH_WHIRLPOOL include $(INCLUDE_DIR)/package.mk -include $(INCLUDE_DIR)/openssl-engine.mk +include $(INCLUDE_DIR)/openssl-module.mk ifneq ($(CONFIG_CCACHE),) HOSTCC=$(HOSTCC_NOCACHE) @@ -129,8 +129,8 @@ endef define Package/libopenssl-conf/conffiles /etc/ssl/openssl.cnf -$(if $(CONFIG_OPENSSL_ENGINE_BUILTIN_DEVCRYPTO),/etc/ssl/engines.cnf.d/devcrypto.cnf) -$(if $(CONFIG_OPENSSL_ENGINE_BUILTIN_PADLOCK),/etc/ssl/engines.cnf.d/padlock.cnf) +$(if $(CONFIG_OPENSSL_ENGINE_BUILTIN_DEVCRYPTO),/etc/ssl/modules.cnf.d/devcrypto.cnf) +$(if $(CONFIG_OPENSSL_ENGINE_BUILTIN_PADLOCK),/etc/ssl/modules.cnf.d/padlock.cnf) endef define Package/libopenssl-conf/description @@ -162,6 +162,20 @@ $(if $(CONFIG_OPENSSL_ENGINE_BUILTIN_PADLOCK),add_engine_config padlock) endef endif +$(eval $(call Package/openssl/add-provider,legacy)) +define Package/libopenssl-legacy + $(call Package/openssl/Default) + $(call Package/openssl/module/Default) + TITLE:=OpenSSL legacy provider +endef + +define Package/libopenssl-legacy/description +The OpenSSL legacy provider supplies OpenSSL implementations of algorithms that +have been deemed legacy. Such algorithms have commonly fallen out of use, have +been deemed insecure by the cryptography community, or something similar. See +https://www.openssl.org/docs/man3.0/man7/OSSL_PROVIDER-legacy.html +endef + $(eval $(call Package/openssl/add-engine,afalg)) define Package/libopenssl-afalg $(call Package/openssl/Default) @@ -174,7 +188,7 @@ endef define Package/libopenssl-afalg/description This package adds an engine that enables hardware acceleration through the AF_ALG kernel interface. -See https://www.openssl.org/docs/man1.1.1/man5/config.html#Engine-Configuration-Module +See https://www.openssl.org/docs/man3.0/man5/config.html#Engine-Configuration and https://openwrt.org/docs/techref/hardware/cryptographic.hardware.accelerators The engine_id is "afalg" endef @@ -190,7 +204,7 @@ endef define Package/libopenssl-devcrypto/description This package adds an engine that enables hardware acceleration through the /dev/crypto kernel interface. -See https://www.openssl.org/docs/man1.1.1/man5/config.html#Engine-Configuration-Module +See https://www.openssl.org/docs/man3.0/man5/config.html#Engine-Configuration and https://openwrt.org/docs/techref/hardware/cryptographic.hardware.accelerators The engine_id is "devcrypto" endef @@ -206,7 +220,7 @@ endef define Package/libopenssl-padlock/description This package adds an engine that enables VIA Padlock hardware acceleration. -See https://www.openssl.org/docs/man1.1.1/man5/config.html#Engine-Configuration-Module +See https://www.openssl.org/docs/man3.0/man5/config.html#Engine-Configuration and https://openwrt.org/docs/techref/hardware/cryptographic.hardware.accelerators The engine_id is "padlock" endef @@ -403,16 +417,16 @@ define Package/libopenssl/install endef define Package/libopenssl-conf/install - $(INSTALL_DIR) $(1)/etc/ssl/engines.cnf.d $(1)/etc/config $(1)/etc/init.d + $(INSTALL_DIR) $(1)/etc/ssl/modules.cnf.d $(1)/etc/config $(1)/etc/init.d $(CP) $(PKG_INSTALL_DIR)/etc/ssl/openssl.cnf $(1)/etc/ssl/ $(INSTALL_BIN) ./files/openssl.init $(1)/etc/init.d/openssl $(SED) 's!%ENGINES_DIR%!/usr/lib/$(ENGINES_DIR)!' $(1)/etc/init.d/openssl touch $(1)/etc/config/openssl $(if $(CONFIG_OPENSSL_ENGINE_BUILTIN_DEVCRYPTO), - $(CP) ./files/devcrypto.cnf $(1)/etc/ssl/engines.cnf.d/ + $(CP) ./files/devcrypto.cnf $(1)/etc/ssl/modules.cnf.d/ echo -e "config engine 'devcrypto'\n\toption enabled '1'" >> $(1)/etc/config/openssl) $(if $(CONFIG_OPENSSL_ENGINE_BUILTIN_PADLOCK), - $(CP) ./files/padlock.cnf $(1)/etc/ssl/engines.cnf.d/ + $(CP) ./files/padlock.cnf $(1)/etc/ssl/modules.cnf.d/ echo -e "\nconfig engine 'padlock'\n\toption enabled '1'" >> $(1)/etc/config/openssl) endef @@ -425,5 +439,6 @@ $(eval $(call BuildPackage,libopenssl)) $(eval $(call BuildPackage,libopenssl-conf)) $(eval $(call BuildPackage,libopenssl-afalg)) $(eval $(call BuildPackage,libopenssl-devcrypto)) +$(eval $(call BuildPackage,libopenssl-legacy)) $(eval $(call BuildPackage,libopenssl-padlock)) $(eval $(call BuildPackage,openssl-util)) diff --git a/package/libs/openssl/files/afalg.cnf b/package/libs/openssl/files/afalg.cnf index 4f573d757c8..fd206361bf3 100644 --- a/package/libs/openssl/files/afalg.cnf +++ b/package/libs/openssl/files/afalg.cnf @@ -1,3 +1,3 @@ -[afalg] +[afalg_sect] default_algorithms = ALL diff --git a/package/libs/openssl/files/devcrypto.cnf b/package/libs/openssl/files/devcrypto.cnf index 8afd9b1b004..91d0eee17fa 100644 --- a/package/libs/openssl/files/devcrypto.cnf +++ b/package/libs/openssl/files/devcrypto.cnf @@ -1,4 +1,4 @@ -[devcrypto] +[devcrypto_sect] # Leave this alone and configure algorithms with CIPERS/DIGESTS below default_algorithms = ALL diff --git a/package/libs/openssl/files/legacy.cnf b/package/libs/openssl/files/legacy.cnf new file mode 100644 index 00000000000..4c20617444b --- /dev/null +++ b/package/libs/openssl/files/legacy.cnf @@ -0,0 +1,3 @@ +[legacy_sect] +activate = 1 + diff --git a/package/libs/openssl/files/openssl.init b/package/libs/openssl/files/openssl.init index f895b9878c8..1c1e8745ffe 100755 --- a/package/libs/openssl/files/openssl.init +++ b/package/libs/openssl/files/openssl.init @@ -1,11 +1,25 @@ #!/bin/sh /etc/rc.common START=13 -ENGINES_CNF_D="/etc/ssl/engines.cnf.d" -ENGINES_CNF="/var/etc/ssl/engines.cnf" -ENGINES_DIR="%ENGINES_DIR%" +ENGINES_CNF=/var/etc/ssl/engines.cnf +ENGINES_DIR=%ENGINES_DIR% +MODULES_DIR=/usr/lib/ossl-modules +PROVIDERS_CNF=/var/etc/ssl/providers.cnf -config_engine() { +#1: cnf file +write_cnf_header() { + mkdir -p "$(dirname "$1")" && \ + echo "# This file is automatically generated from /etc/config/openssl." >"$1" || { + echo "Error writing to $1." + return 1 + } +} + + +#1: module name +#2: output cnf file +#3: module.so +enable_module() { local builtin enabled force config_get_bool builtin "$1" builtin 0 @@ -13,30 +27,46 @@ config_engine() { config_get_bool force "$1" force 0 if [ "$enabled" = 0 ]; then - [ "$builtin" != 1 ] && return 1 - echo "Engine $1 is built into the libcrypto library and can't be disabled through UCI." && \ + [ "$builtin" = 0 ] && return 1 + echo "Engine $1 is built into the libcrypto library and can't be disabled through UCI." echo "If the engine was not built-in, remove 'config builtin' from /etc/config/openssl." elif [ "$force" = 1 ]; then printf "[Forced] " - elif ! grep -q "\\[ *$1 *]" "${ENGINES_CNF_D}"/*; then + elif ! grep -q "\\[ *$1_sect *]" /etc/ssl/modules.cnf.d/*; then echo "$1: Could not find section [$1] in config files." return 1 elif [ "$builtin" = 1 ]; then printf "[Builtin] " - elif [ ! -f "${ENGINES_DIR}/$1.so" ];then - echo "$1: ${ENGINES_DIR}/$1.so not found." + elif [ ! -f "$3" ];then + echo "Skipping $1: $3 not found." return 1 fi - echo Enabling engine "$1" - echo "$1=$1" >> "${ENGINES_CNF}" + echo "Enabling $1" + echo "$1=$1_sect" >>"$2" +} + +config_engine() { + enable_module "$1" "$ENGINES_CNF" \ + "${ENGINES_DIR}/${1}.so" +} + +config_provider() { + enable_module "$1" "$PROVIDERS_CNF" \ + "${MODULES_DIR}/${1}.so" } start() { - mkdir -p "$(dirname "${ENGINES_CNF}")" || exit 1 - echo Generating engines.cnf - echo "# This file is automatically generated from /etc/config/openssl." \ - > "${ENGINES_CNF}" || \ - { echo Error writing ${ENGINES_CNF} >&2; exit 1; } + local ret=0 + config_load openssl - config_foreach config_engine engine + + echo Generating engines.cnf + write_cnf_header "${ENGINES_CNF}" && \ + config_foreach config_engine engine || ret=$? + + echo Generating providers.cnf + write_cnf_header "${PROVIDERS_CNF}" && \ + config_foreach config_provider provider || ret=$? + + return $ret } diff --git a/package/libs/openssl/files/padlock.cnf b/package/libs/openssl/files/padlock.cnf index ef91079e5d1..f4085d907b4 100644 --- a/package/libs/openssl/files/padlock.cnf +++ b/package/libs/openssl/files/padlock.cnf @@ -1,3 +1,3 @@ -[padlock] +[padlock_sect] default_algorithms = ALL diff --git a/package/libs/openssl/patches/150-openssl.cnf-add-engines-conf.patch b/package/libs/openssl/patches/150-openssl.cnf-add-engines-conf.patch index b1ec0cae711..9fe9cdf590c 100644 --- a/package/libs/openssl/patches/150-openssl.cnf-add-engines-conf.patch +++ b/package/libs/openssl/patches/150-openssl.cnf-add-engines-conf.patch @@ -10,20 +10,32 @@ Signed-off-by: Eneas U de Queiroz --- a/apps/openssl.cnf +++ b/apps/openssl.cnf -@@ -30,6 +30,16 @@ oid_section = new_oids - # (Alternatively, use a configuration file that has only - # X.509v3 extensions in its main [= default] section.) +@@ -52,10 +52,13 @@ tsa_policy3 = 1.2.3.4.5.7 -+openssl_conf=openssl_conf + [openssl_init] + providers = provider_sect ++engines = engines_sect + + # List of providers to load + [provider_sect] + default = default_sect ++.include /var/etc/ssl/providers.cnf + -+[openssl_conf] -+engines=engines + # The fips section name should match the section name inside the + # included fipsmodule.cnf. + # fips = fips_sect +@@ -69,7 +72,13 @@ default = default_sect + # OpenSSL may not work correctly which could lead to significant system + # problems including inability to remotely access the system. + [default_sect] +-# activate = 1 ++activate = 1 + -+[engines] ++[engines_sect] +.include /var/etc/ssl/engines.cnf + -+.include /etc/ssl/engines.cnf.d ++.include /etc/ssl/modules.cnf.d + - [ new_oids ] - # We can add new OIDs in here for use by 'ca', 'req' and 'ts'. - # Add a simple OID like this: + + + #################################################################### From e92b153e99a8019752b08c6ab0f7c17d9f08063e Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Wed, 5 Apr 2023 16:56:54 +0100 Subject: [PATCH 05/14] mediatek: introduce KERNEL_LOADADDR to Device/Default template We need to reset KERNEL_LOADADDR if we use it on a per-device base. Otherwise the previous value will be kept in case a device doesn't define KERNEL_LOADADDR and relies on the default. Move initializing KERNEL_LOADADDR to target/linux/mediatek/image/Makefile, similar to how it's done also on the ramips target. This fixes image size related breakage on devices which rely on the default value of KERNEL_LOADADDR. While at it use 0x48000000 which is more common than the previous default 0x44000000 for the filogic subtarget. Fixed: e7c399bee6 ("filogic: add support for ASUS TUF-AX4200") Signed-off-by: Daniel Golle --- target/linux/mediatek/image/Makefile | 6 ++++++ target/linux/mediatek/image/filogic.mk | 8 +------- target/linux/mediatek/image/mt7622.mk | 6 ------ target/linux/mediatek/image/mt7623.mk | 1 - target/linux/mediatek/image/mt7629.mk | 2 -- 5 files changed, 7 insertions(+), 16 deletions(-) diff --git a/target/linux/mediatek/image/Makefile b/target/linux/mediatek/image/Makefile index 4c17e5845a2..97164428e05 100644 --- a/target/linux/mediatek/image/Makefile +++ b/target/linux/mediatek/image/Makefile @@ -6,6 +6,11 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/image.mk +loadaddr-$(CONFIG_TARGET_mediatek_mt7622) := 0x44000000 +loadaddr-$(CONFIG_TARGET_mediatek_mt7623) := 0x80008000 +loadaddr-$(CONFIG_TARGET_mediatek_mt7629) := 0x40008000 +loadaddr-$(CONFIG_TARGET_mediatek_filogic) := 0x48000000 + # default all platform image(fit) build define Device/Default PROFILES = Default $$(DEVICE_NAME) @@ -14,6 +19,7 @@ define Device/Default fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb KERNEL_INITRAMFS = kernel-bin | lzma | \ fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb with-initrd + KERNEL_LOADADDR = $(loadaddr-y) FILESYSTEMS := squashfs DEVICE_DTS_DIR := $(DTS_DIR) IMAGES := sysupgrade.bin diff --git a/target/linux/mediatek/image/filogic.mk b/target/linux/mediatek/image/filogic.mk index b1b223c55bf..3538ec1b867 100644 --- a/target/linux/mediatek/image/filogic.mk +++ b/target/linux/mediatek/image/filogic.mk @@ -1,7 +1,5 @@ DTS_DIR := $(DTS_DIR)/mediatek -KERNEL_LOADADDR := 0x44000000 - define Image/Prepare # For UBI we want only one extra block rm -f $(KDIR)/ubi_mark @@ -46,7 +44,6 @@ define Device/asus_tuf-ax4200 DEVICE_DTS_LOADADDR := 0x47000000 DEVICE_PACKAGES := kmod-usb3 kmod-mt7986-firmware mt7986-wo-firmware IMAGES := sysupgrade.bin - KERNEL_LOADADDR := 0x48000000 KERNEL := kernel-bin | lzma | \ fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb KERNEL_INITRAMFS := kernel-bin | lzma | \ @@ -65,6 +62,7 @@ define Device/bananapi_bpi-r3 DEVICE_DTS_DIR := ../dts DEVICE_PACKAGES := kmod-hwmon-pwmfan kmod-i2c-gpio kmod-mt7986-firmware kmod-sfp kmod-usb3 e2fsprogs f2fsck mkf2fs mt7986-wo-firmware IMAGES := sysupgrade.itb + KERNEL_LOADADDR := 0x44000000 KERNEL_INITRAMFS_SUFFIX := -recovery.itb ARTIFACTS := \ emmc-preloader.bin emmc-bl31-uboot.fip \ @@ -108,7 +106,6 @@ define Device/mediatek_mt7986a-rfb-nand DEVICE_DTS := mt7986a-rfb-spim-nand DEVICE_DTS_DIR := $(DTS_DIR)/ DEVICE_PACKAGES := kmod-mt7986-firmware mt7986-wo-firmware - KERNEL_LOADADDR := 0x48000000 SUPPORTED_DEVICES := mediatek,mt7986a-rfb-snand UBINIZE_OPTS := -E 5 BLOCKSIZE := 128k @@ -132,7 +129,6 @@ define Device/mediatek_mt7986b-rfb DEVICE_DTS := mt7986b-rfb DEVICE_DTS_DIR := $(DTS_DIR)/ DEVICE_PACKAGES := kmod-mt7986-firmware mt7986-wo-firmware - KERNEL_LOADADDR := 0x48000000 SUPPORTED_DEVICES := mediatek,mt7986b-rfb UBINIZE_OPTS := -E 5 BLOCKSIZE := 128k @@ -151,7 +147,6 @@ define Device/xiaomi_redmi-router-ax6000-stock DEVICE_DTS := mt7986a-xiaomi-redmi-router-ax6000-stock DEVICE_DTS_DIR := ../dts DEVICE_PACKAGES := kmod-leds-ws2812b kmod-mt7986-firmware mt7986-wo-firmware - KERNEL_LOADADDR := 0x48000000 UBINIZE_OPTS := -E 5 BLOCKSIZE := 128k PAGESIZE := 2048 @@ -171,7 +166,6 @@ define Device/xiaomi_redmi-router-ax6000-ubootmod DEVICE_PACKAGES := kmod-leds-ws2812b kmod-mt7986-firmware mt7986-wo-firmware KERNEL_INITRAMFS_SUFFIX := -recovery.itb IMAGES := sysupgrade.itb - KERNEL_LOADADDR := 0x48000000 UBINIZE_OPTS := -E 5 BLOCKSIZE := 128k PAGESIZE := 2048 diff --git a/target/linux/mediatek/image/mt7622.mk b/target/linux/mediatek/image/mt7622.mk index ee71cf87648..12e819ed545 100644 --- a/target/linux/mediatek/image/mt7622.mk +++ b/target/linux/mediatek/image/mt7622.mk @@ -1,11 +1,5 @@ DTS_DIR := $(DTS_DIR)/mediatek -ifdef CONFIG_LINUX_5_4 - KERNEL_LOADADDR := 0x44080000 -else - KERNEL_LOADADDR := 0x44000000 -endif - define Image/Prepare # For UBI we want only one extra block rm -f $(KDIR)/ubi_mark diff --git a/target/linux/mediatek/image/mt7623.mk b/target/linux/mediatek/image/mt7623.mk index 4ef0aabe4da..26befc1c1e5 100644 --- a/target/linux/mediatek/image/mt7623.mk +++ b/target/linux/mediatek/image/mt7623.mk @@ -1,4 +1,3 @@ -KERNEL_LOADADDR := 0x80008000 DEVICE_VARS += UBOOT_TARGET UBOOT_OFFSET UBOOT_IMAGE # The bootrom of MT7623 expects legacy MediaTek headers present in diff --git a/target/linux/mediatek/image/mt7629.mk b/target/linux/mediatek/image/mt7629.mk index 891b65c4e7c..3f5b2e25794 100644 --- a/target/linux/mediatek/image/mt7629.mk +++ b/target/linux/mediatek/image/mt7629.mk @@ -1,5 +1,3 @@ -KERNEL_LOADADDR := 0x40008000 - define Device/mediatek_mt7629-rfb DEVICE_VENDOR := MediaTek DEVICE_MODEL := MT7629 rfb AP From 3b212db232a7c82935c474f081dd72092ea761d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Wed, 5 Apr 2023 23:32:57 +0200 Subject: [PATCH 06/14] kernel: backport of_request_module() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's needed by NVMEM changes queued for 6.4. Signed-off-by: Rafał Miłecki --- ...087-OF-DT-Overlay-configfs-interface.patch | 2 +- ...01-of-Fix-modalias-string-generation.patch | 70 +++++++ ...002-of-Update-of_device_get_modalias.patch | 103 +++++++++++ ...v6.4-0003-of-Rename-of_modalias_node.patch | 173 ++++++++++++++++++ ...0004-of-Move-of_modalias-to-module.c.patch | 160 ++++++++++++++++ ...uest-module-helper-logic-to-module.c.patch | 131 +++++++++++++ ...01-of-Fix-modalias-string-generation.patch | 70 +++++++ ...002-of-Update-of_device_get_modalias.patch | 103 +++++++++++ ...v6.4-0003-of-Rename-of_modalias_node.patch | 173 ++++++++++++++++++ ...0004-of-Move-of_modalias-to-module.c.patch | 160 ++++++++++++++++ ...uest-module-helper-logic-to-module.c.patch | 131 +++++++++++++ 11 files changed, 1275 insertions(+), 1 deletion(-) create mode 100644 target/linux/generic/backport-5.10/828-v6.4-0001-of-Fix-modalias-string-generation.patch create mode 100644 target/linux/generic/backport-5.10/828-v6.4-0002-of-Update-of_device_get_modalias.patch create mode 100644 target/linux/generic/backport-5.10/828-v6.4-0003-of-Rename-of_modalias_node.patch create mode 100644 target/linux/generic/backport-5.10/828-v6.4-0004-of-Move-of_modalias-to-module.c.patch create mode 100644 target/linux/generic/backport-5.10/828-v6.4-0005-of-Move-the-request-module-helper-logic-to-module.c.patch create mode 100644 target/linux/generic/backport-5.15/828-v6.4-0001-of-Fix-modalias-string-generation.patch create mode 100644 target/linux/generic/backport-5.15/828-v6.4-0002-of-Update-of_device_get_modalias.patch create mode 100644 target/linux/generic/backport-5.15/828-v6.4-0003-of-Rename-of_modalias_node.patch create mode 100644 target/linux/generic/backport-5.15/828-v6.4-0004-of-Move-of_modalias-to-module.c.patch create mode 100644 target/linux/generic/backport-5.15/828-v6.4-0005-of-Move-the-request-module-helper-logic-to-module.c.patch diff --git a/target/linux/bcm27xx/patches-5.15/950-0087-OF-DT-Overlay-configfs-interface.patch b/target/linux/bcm27xx/patches-5.15/950-0087-OF-DT-Overlay-configfs-interface.patch index 1cff52fd9e6..bb38a4e68cd 100644 --- a/target/linux/bcm27xx/patches-5.15/950-0087-OF-DT-Overlay-configfs-interface.patch +++ b/target/linux/bcm27xx/patches-5.15/950-0087-OF-DT-Overlay-configfs-interface.patch @@ -106,7 +106,7 @@ configfs: New of_overlay API +++ b/drivers/of/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 - obj-y = base.o device.o platform.o property.o + obj-y = base.o device.o module.o platform.o property.o obj-$(CONFIG_OF_KOBJ) += kobj.o +obj-$(CONFIG_OF_CONFIGFS) += configfs.o obj-$(CONFIG_OF_DYNAMIC) += dynamic.o diff --git a/target/linux/generic/backport-5.10/828-v6.4-0001-of-Fix-modalias-string-generation.patch b/target/linux/generic/backport-5.10/828-v6.4-0001-of-Fix-modalias-string-generation.patch new file mode 100644 index 00000000000..580a897e98f --- /dev/null +++ b/target/linux/generic/backport-5.10/828-v6.4-0001-of-Fix-modalias-string-generation.patch @@ -0,0 +1,70 @@ +From b19a4266c52de78496fe40f0b37580a3b762e67d Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:09 +0100 +Subject: [PATCH] of: Fix modalias string generation + +The helper generating an OF based modalias (of_device_get_modalias()) +works fine, but due to the use of snprintf() internally it needs a +buffer one byte longer than what should be needed just for the entire +string (excluding the '\0'). Most users of this helper are sysfs hooks +providing the modalias string to users. They all provide a PAGE_SIZE +buffer which is way above the number of bytes required to fit the +modalias string and hence do not suffer from this issue. + +There is another user though, of_device_request_module(), which is only +called by drivers/usb/common/ulpi.c. This request module function is +faulty, but maybe because in most cases there is an alternative, ULPI +driver users have not noticed it. + +In this function, of_device_get_modalias() is called twice. The first +time without buffer just to get the number of bytes required by the +modalias string (excluding the null byte), and a second time, after +buffer allocation, to fill the buffer. The allocation asks for an +additional byte, in order to store the trailing '\0'. However, the +buffer *length* provided to of_device_get_modalias() excludes this extra +byte. The internal use of snprintf() with a length that is exactly the +number of bytes to be written has the effect of using the last available +byte to store a '\0', which then smashes the last character of the +modalias string. + +Provide the actual size of the buffer to of_device_get_modalias() to fix +this issue. + +Note: the "str[size - 1] = '\0';" line is not really needed as snprintf +will anyway end the string with a null byte, but there is a possibility +that this function might be called on a struct device_node without +compatible, in this case snprintf() would not be executed. So we keep it +just to avoid possible unbounded strings. + +Cc: Stephen Boyd +Cc: Peter Chen +Fixes: 9c829c097f2f ("of: device: Support loading a module with OF based modalias") +Signed-off-by: Miquel Raynal +Reviewed-by: Rob Herring +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-2-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/of/device.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/of/device.c ++++ b/drivers/of/device.c +@@ -264,12 +264,15 @@ int of_device_request_module(struct devi + if (size < 0) + return size; + +- str = kmalloc(size + 1, GFP_KERNEL); ++ /* Reserve an additional byte for the trailing '\0' */ ++ size++; ++ ++ str = kmalloc(size, GFP_KERNEL); + if (!str) + return -ENOMEM; + + of_device_get_modalias(dev, str, size); +- str[size] = '\0'; ++ str[size - 1] = '\0'; + ret = request_module(str); + kfree(str); + diff --git a/target/linux/generic/backport-5.10/828-v6.4-0002-of-Update-of_device_get_modalias.patch b/target/linux/generic/backport-5.10/828-v6.4-0002-of-Update-of_device_get_modalias.patch new file mode 100644 index 00000000000..eac4ced5ab5 --- /dev/null +++ b/target/linux/generic/backport-5.10/828-v6.4-0002-of-Update-of_device_get_modalias.patch @@ -0,0 +1,103 @@ +From 5c3d15e127ebfc0754cd18def7124633b6d46672 Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:15 +0100 +Subject: [PATCH] of: Update of_device_get_modalias() + +This function only needs a "struct device_node" to work, but for +convenience the author (and only user) of this helper did use a "struct +device" and put it in device.c. + +Let's convert this helper to take a "struct device node" instead. This +change asks for two additional changes: renaming it "of_modalias()" +to fit the current naming, and moving it outside of device.c which will +be done in a follow-up commit. + +Signed-off-by: Miquel Raynal +Reviewed-by: Rob Herring +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-8-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/of/device.c | 29 +++++++++++++++++------------ + 1 file changed, 17 insertions(+), 12 deletions(-) + +--- a/drivers/of/device.c ++++ b/drivers/of/device.c +@@ -215,7 +215,7 @@ const void *of_device_get_match_data(con + } + EXPORT_SYMBOL(of_device_get_match_data); + +-static ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len) ++static ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len) + { + const char *compat; + char *c; +@@ -223,19 +223,16 @@ static ssize_t of_device_get_modalias(st + ssize_t csize; + ssize_t tsize; + +- if ((!dev) || (!dev->of_node) || dev->of_node_reused) +- return -ENODEV; +- + /* Name & Type */ + /* %p eats all alphanum characters, so %c must be used here */ +- csize = snprintf(str, len, "of:N%pOFn%c%s", dev->of_node, 'T', +- of_node_get_device_type(dev->of_node)); ++ csize = snprintf(str, len, "of:N%pOFn%c%s", np, 'T', ++ of_node_get_device_type(np)); + tsize = csize; + len -= csize; + if (str) + str += csize; + +- of_property_for_each_string(dev->of_node, "compatible", p, compat) { ++ of_property_for_each_string(np, "compatible", p, compat) { + csize = strlen(compat) + 1; + tsize += csize; + if (csize > len) +@@ -260,7 +257,10 @@ int of_device_request_module(struct devi + ssize_t size; + int ret; + +- size = of_device_get_modalias(dev, NULL, 0); ++ if (!dev || !dev->of_node) ++ return -ENODEV; ++ ++ size = of_modalias(dev->of_node, NULL, 0); + if (size < 0) + return size; + +@@ -271,7 +271,7 @@ int of_device_request_module(struct devi + if (!str) + return -ENOMEM; + +- of_device_get_modalias(dev, str, size); ++ of_modalias(dev->of_node, str, size); + str[size - 1] = '\0'; + ret = request_module(str); + kfree(str); +@@ -285,7 +285,12 @@ EXPORT_SYMBOL_GPL(of_device_request_modu + */ + ssize_t of_device_modalias(struct device *dev, char *str, ssize_t len) + { +- ssize_t sl = of_device_get_modalias(dev, str, len - 2); ++ ssize_t sl; ++ ++ if (!dev || !dev->of_node || dev->of_node_reused) ++ return -ENODEV; ++ ++ sl = of_modalias(dev->of_node, str, len - 2); + if (sl < 0) + return sl; + if (sl > len - 2) +@@ -348,8 +353,8 @@ int of_device_uevent_modalias(struct dev + if (add_uevent_var(env, "MODALIAS=")) + return -ENOMEM; + +- sl = of_device_get_modalias(dev, &env->buf[env->buflen-1], +- sizeof(env->buf) - env->buflen); ++ sl = of_modalias(dev->of_node, &env->buf[env->buflen-1], ++ sizeof(env->buf) - env->buflen); + if (sl < 0) + return sl; + if (sl >= (sizeof(env->buf) - env->buflen)) diff --git a/target/linux/generic/backport-5.10/828-v6.4-0003-of-Rename-of_modalias_node.patch b/target/linux/generic/backport-5.10/828-v6.4-0003-of-Rename-of_modalias_node.patch new file mode 100644 index 00000000000..7e641211e6a --- /dev/null +++ b/target/linux/generic/backport-5.10/828-v6.4-0003-of-Rename-of_modalias_node.patch @@ -0,0 +1,173 @@ +From 673aa1ed1c9b6710bf24e3f0957d85e2f46c77db Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:16 +0100 +Subject: [PATCH] of: Rename of_modalias_node() + +This helper does not produce a real modalias, but tries to get the +"product" compatible part of the "vendor,product" compatibles only. It +is far from creating a purely useful modalias string and does not seem +to be used like that directly anyway, so let's try to give this helper a +more meaningful name before moving there a real modalias helper (already +existing under of/device.c). + +Also update the various documentations to refer to the strings as +"aliases" rather than "modaliases" which has a real meaning in the Linux +kernel. + +There is no functional change. + +Cc: Rafael J. Wysocki +Cc: Len Brown +Cc: Maarten Lankhorst +Cc: Maxime Ripard +Cc: Thomas Zimmermann +Cc: Sebastian Reichel +Cc: Wolfram Sang +Cc: Mark Brown +Signed-off-by: Miquel Raynal +Reviewed-by: Rob Herring +Acked-by: Mark Brown +Signed-off-by: Srinivas Kandagatla +Acked-by: Sebastian Reichel +Link: https://lore.kernel.org/r/20230404172148.82422-9-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/acpi/bus.c | 7 ++++--- + drivers/gpu/drm/drm_mipi_dsi.c | 2 +- + drivers/hsi/hsi_core.c | 2 +- + drivers/i2c/busses/i2c-powermac.c | 2 +- + drivers/i2c/i2c-core-of.c | 2 +- + drivers/of/base.c | 18 +++++++++++------- + drivers/spi/spi.c | 4 ++-- + include/linux/of.h | 3 ++- + 8 files changed, 23 insertions(+), 17 deletions(-) + +--- a/drivers/acpi/bus.c ++++ b/drivers/acpi/bus.c +@@ -693,9 +693,10 @@ static bool acpi_of_modalias(struct acpi + * @modalias: Pointer to buffer that modalias value will be copied into + * @len: Length of modalias buffer + * +- * This is a counterpart of of_modalias_node() for struct acpi_device objects. +- * If there is a compatible string for @adev, it will be copied to @modalias +- * with the vendor prefix stripped; otherwise, @default_id will be used. ++ * This is a counterpart of of_alias_from_compatible() for struct acpi_device ++ * objects. If there is a compatible string for @adev, it will be copied to ++ * @modalias with the vendor prefix stripped; otherwise, @default_id will be ++ * used. + */ + void acpi_set_modalias(struct acpi_device *adev, const char *default_id, + char *modalias, size_t len) +--- a/drivers/gpu/drm/drm_mipi_dsi.c ++++ b/drivers/gpu/drm/drm_mipi_dsi.c +@@ -160,7 +160,7 @@ of_mipi_dsi_device_add(struct mipi_dsi_h + int ret; + u32 reg; + +- if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) { ++ if (of_alias_from_compatible(node, info.type, sizeof(info.type)) < 0) { + drm_err(host, "modalias failure on %pOF\n", node); + return ERR_PTR(-EINVAL); + } +--- a/drivers/hsi/hsi_core.c ++++ b/drivers/hsi/hsi_core.c +@@ -207,7 +207,7 @@ static void hsi_add_client_from_dt(struc + if (!cl) + return; + +- err = of_modalias_node(client, name, sizeof(name)); ++ err = of_alias_from_compatible(client, name, sizeof(name)); + if (err) + goto err; + +--- a/drivers/i2c/busses/i2c-powermac.c ++++ b/drivers/i2c/busses/i2c-powermac.c +@@ -289,7 +289,7 @@ static bool i2c_powermac_get_type(struct + */ + + /* First try proper modalias */ +- if (of_modalias_node(node, tmp, sizeof(tmp)) >= 0) { ++ if (of_alias_from_compatible(node, tmp, sizeof(tmp)) >= 0) { + snprintf(type, type_size, "MAC,%s", tmp); + return true; + } +--- a/drivers/i2c/i2c-core-of.c ++++ b/drivers/i2c/i2c-core-of.c +@@ -27,7 +27,7 @@ int of_i2c_get_board_info(struct device + + memset(info, 0, sizeof(*info)); + +- if (of_modalias_node(node, info->type, sizeof(info->type)) < 0) { ++ if (of_alias_from_compatible(node, info->type, sizeof(info->type)) < 0) { + dev_err(dev, "of_i2c: modalias failure on %pOF\n", node); + return -EINVAL; + } +--- a/drivers/of/base.c ++++ b/drivers/of/base.c +@@ -1160,19 +1160,23 @@ struct device_node *of_find_matching_nod + EXPORT_SYMBOL(of_find_matching_node_and_match); + + /** +- * of_modalias_node - Lookup appropriate modalias for a device node ++ * of_alias_from_compatible - Lookup appropriate alias for a device node ++ * depending on compatible + * @node: pointer to a device tree node +- * @modalias: Pointer to buffer that modalias value will be copied into +- * @len: Length of modalias value ++ * @alias: Pointer to buffer that alias value will be copied into ++ * @len: Length of alias value + * + * Based on the value of the compatible property, this routine will attempt +- * to choose an appropriate modalias value for a particular device tree node. ++ * to choose an appropriate alias value for a particular device tree node. + * It does this by stripping the manufacturer prefix (as delimited by a ',') + * from the first entry in the compatible list property. + * ++ * Note: The matching on just the "product" side of the compatible is a relic ++ * from I2C and SPI. Please do not add any new user. ++ * + * Return: This routine returns 0 on success, <0 on failure. + */ +-int of_modalias_node(struct device_node *node, char *modalias, int len) ++int of_alias_from_compatible(const struct device_node *node, char *alias, int len) + { + const char *compatible, *p; + int cplen; +@@ -1181,10 +1185,10 @@ int of_modalias_node(struct device_node + if (!compatible || strlen(compatible) > cplen) + return -ENODEV; + p = strchr(compatible, ','); +- strlcpy(modalias, p ? p + 1 : compatible, len); ++ strlcpy(alias, p ? p + 1 : compatible, len); + return 0; + } +-EXPORT_SYMBOL_GPL(of_modalias_node); ++EXPORT_SYMBOL_GPL(of_alias_from_compatible); + + /** + * of_find_node_by_phandle - Find a node given a phandle +--- a/drivers/spi/spi.c ++++ b/drivers/spi/spi.c +@@ -2038,8 +2038,8 @@ of_register_spi_device(struct spi_contro + } + + /* Select device driver */ +- rc = of_modalias_node(nc, spi->modalias, +- sizeof(spi->modalias)); ++ rc = of_alias_from_compatible(nc, spi->modalias, ++ sizeof(spi->modalias)); + if (rc < 0) { + dev_err(&ctlr->dev, "cannot find modalias for %pOF\n", nc); + goto err_out; +--- a/include/linux/of.h ++++ b/include/linux/of.h +@@ -361,7 +361,8 @@ extern int of_n_addr_cells(struct device + extern int of_n_size_cells(struct device_node *np); + extern const struct of_device_id *of_match_node( + const struct of_device_id *matches, const struct device_node *node); +-extern int of_modalias_node(struct device_node *node, char *modalias, int len); ++extern int of_alias_from_compatible(const struct device_node *node, char *alias, ++ int len); + extern void of_print_phandle_args(const char *msg, const struct of_phandle_args *args); + extern int __of_parse_phandle_with_args(const struct device_node *np, + const char *list_name, const char *cells_name, int cell_count, diff --git a/target/linux/generic/backport-5.10/828-v6.4-0004-of-Move-of_modalias-to-module.c.patch b/target/linux/generic/backport-5.10/828-v6.4-0004-of-Move-of_modalias-to-module.c.patch new file mode 100644 index 00000000000..62d1232bcdc --- /dev/null +++ b/target/linux/generic/backport-5.10/828-v6.4-0004-of-Move-of_modalias-to-module.c.patch @@ -0,0 +1,160 @@ +From bd7a7ed774afd1a4174df34227626c95573be517 Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:17 +0100 +Subject: [PATCH] of: Move of_modalias() to module.c + +Create a specific .c file for OF related module handling. +Move of_modalias() inside as a first step. + +The helper is exposed through of.h even though it is only used by core +files because the users from device.c will soon be split into an OF-only +helper in module.c as well as a device-oriented inline helper in +of_device.h. Putting this helper in of_private.h would require to +include of_private.h from of_device.h, which is not acceptable. + +Suggested-by: Rob Herring +Signed-off-by: Miquel Raynal +Reviewed-by: Rob Herring +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-10-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/of/Makefile | 2 +- + drivers/of/device.c | 37 ------------------------------------- + drivers/of/module.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ + include/linux/of.h | 9 +++++++++ + 4 files changed, 54 insertions(+), 38 deletions(-) + create mode 100644 drivers/of/module.c + +--- a/drivers/of/Makefile ++++ b/drivers/of/Makefile +@@ -1,5 +1,5 @@ + # SPDX-License-Identifier: GPL-2.0 +-obj-y = base.o device.o platform.o property.o ++obj-y = base.o device.o module.o platform.o property.o + obj-$(CONFIG_OF_KOBJ) += kobj.o + obj-$(CONFIG_OF_DYNAMIC) += dynamic.o + obj-$(CONFIG_OF_FLATTREE) += fdt.o +--- a/drivers/of/device.c ++++ b/drivers/of/device.c +@@ -1,5 +1,4 @@ + // SPDX-License-Identifier: GPL-2.0 +-#include + #include + #include + #include +@@ -215,42 +214,6 @@ const void *of_device_get_match_data(con + } + EXPORT_SYMBOL(of_device_get_match_data); + +-static ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len) +-{ +- const char *compat; +- char *c; +- struct property *p; +- ssize_t csize; +- ssize_t tsize; +- +- /* Name & Type */ +- /* %p eats all alphanum characters, so %c must be used here */ +- csize = snprintf(str, len, "of:N%pOFn%c%s", np, 'T', +- of_node_get_device_type(np)); +- tsize = csize; +- len -= csize; +- if (str) +- str += csize; +- +- of_property_for_each_string(np, "compatible", p, compat) { +- csize = strlen(compat) + 1; +- tsize += csize; +- if (csize > len) +- continue; +- +- csize = snprintf(str, len, "C%s", compat); +- for (c = str; c; ) { +- c = strchr(c, ' '); +- if (c) +- *c++ = '_'; +- } +- len -= csize; +- str += csize; +- } +- +- return tsize; +-} +- + int of_device_request_module(struct device *dev) + { + char *str; +--- /dev/null ++++ b/drivers/of/module.c +@@ -0,0 +1,44 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Linux kernel module helpers. ++ */ ++ ++#include ++#include ++#include ++ ++ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len) ++{ ++ const char *compat; ++ char *c; ++ struct property *p; ++ ssize_t csize; ++ ssize_t tsize; ++ ++ /* Name & Type */ ++ /* %p eats all alphanum characters, so %c must be used here */ ++ csize = snprintf(str, len, "of:N%pOFn%c%s", np, 'T', ++ of_node_get_device_type(np)); ++ tsize = csize; ++ len -= csize; ++ if (str) ++ str += csize; ++ ++ of_property_for_each_string(np, "compatible", p, compat) { ++ csize = strlen(compat) + 1; ++ tsize += csize; ++ if (csize > len) ++ continue; ++ ++ csize = snprintf(str, len, "C%s", compat); ++ for (c = str; c; ) { ++ c = strchr(c, ' '); ++ if (c) ++ *c++ = '_'; ++ } ++ len -= csize; ++ str += csize; ++ } ++ ++ return tsize; ++} +--- a/include/linux/of.h ++++ b/include/linux/of.h +@@ -373,6 +373,9 @@ extern int of_parse_phandle_with_args_ma + extern int of_count_phandle_with_args(const struct device_node *np, + const char *list_name, const char *cells_name); + ++/* module functions */ ++extern ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len); ++ + /* phandle iterator functions */ + extern int of_phandle_iterator_init(struct of_phandle_iterator *it, + const struct device_node *np, +@@ -878,6 +881,12 @@ static inline int of_count_phandle_with_ + return -ENOSYS; + } + ++static inline ssize_t of_modalias(const struct device_node *np, char *str, ++ ssize_t len) ++{ ++ return -ENODEV; ++} ++ + static inline int of_phandle_iterator_init(struct of_phandle_iterator *it, + const struct device_node *np, + const char *list_name, diff --git a/target/linux/generic/backport-5.10/828-v6.4-0005-of-Move-the-request-module-helper-logic-to-module.c.patch b/target/linux/generic/backport-5.10/828-v6.4-0005-of-Move-the-request-module-helper-logic-to-module.c.patch new file mode 100644 index 00000000000..c176ff8f134 --- /dev/null +++ b/target/linux/generic/backport-5.10/828-v6.4-0005-of-Move-the-request-module-helper-logic-to-module.c.patch @@ -0,0 +1,131 @@ +From e6506f06d5e82765666902ccf9e9162f3e31d518 Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:18 +0100 +Subject: [PATCH] of: Move the request module helper logic to module.c + +Depending on device.c for pure OF handling is considered +backwards. Let's extract the content of of_device_request_module() to +have the real logic under module.c. + +The next step will be to convert users of of_device_request_module() to +use the new helper. + +Signed-off-by: Miquel Raynal +Reviewed-by: Rob Herring +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-11-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/of/device.c | 25 ++----------------------- + drivers/of/module.c | 30 ++++++++++++++++++++++++++++++ + include/linux/of.h | 6 ++++++ + 3 files changed, 38 insertions(+), 23 deletions(-) + +--- a/drivers/of/device.c ++++ b/drivers/of/device.c +@@ -7,7 +7,6 @@ + #include /* for bus_dma_region */ + #include + #include +-#include + #include + #include + #include +@@ -216,30 +215,10 @@ EXPORT_SYMBOL(of_device_get_match_data); + + int of_device_request_module(struct device *dev) + { +- char *str; +- ssize_t size; +- int ret; +- +- if (!dev || !dev->of_node) ++ if (!dev) + return -ENODEV; + +- size = of_modalias(dev->of_node, NULL, 0); +- if (size < 0) +- return size; +- +- /* Reserve an additional byte for the trailing '\0' */ +- size++; +- +- str = kmalloc(size, GFP_KERNEL); +- if (!str) +- return -ENOMEM; +- +- of_modalias(dev->of_node, str, size); +- str[size - 1] = '\0'; +- ret = request_module(str); +- kfree(str); +- +- return ret; ++ return of_request_module(dev->of_node); + } + EXPORT_SYMBOL_GPL(of_device_request_module); + +--- a/drivers/of/module.c ++++ b/drivers/of/module.c +@@ -4,6 +4,7 @@ + */ + + #include ++#include + #include + #include + +@@ -42,3 +43,32 @@ ssize_t of_modalias(const struct device_ + + return tsize; + } ++ ++int of_request_module(const struct device_node *np) ++{ ++ char *str; ++ ssize_t size; ++ int ret; ++ ++ if (!np) ++ return -ENODEV; ++ ++ size = of_modalias(np, NULL, 0); ++ if (size < 0) ++ return size; ++ ++ /* Reserve an additional byte for the trailing '\0' */ ++ size++; ++ ++ str = kmalloc(size, GFP_KERNEL); ++ if (!str) ++ return -ENOMEM; ++ ++ of_modalias(np, str, size); ++ str[size - 1] = '\0'; ++ ret = request_module(str); ++ kfree(str); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(of_request_module); +--- a/include/linux/of.h ++++ b/include/linux/of.h +@@ -375,6 +375,7 @@ extern int of_count_phandle_with_args(co + + /* module functions */ + extern ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len); ++extern int of_request_module(const struct device_node *np); + + /* phandle iterator functions */ + extern int of_phandle_iterator_init(struct of_phandle_iterator *it, +@@ -886,6 +887,11 @@ static inline ssize_t of_modalias(const + { + return -ENODEV; + } ++ ++static inline int of_request_module(const struct device_node *np) ++{ ++ return -ENODEV; ++} + + static inline int of_phandle_iterator_init(struct of_phandle_iterator *it, + const struct device_node *np, diff --git a/target/linux/generic/backport-5.15/828-v6.4-0001-of-Fix-modalias-string-generation.patch b/target/linux/generic/backport-5.15/828-v6.4-0001-of-Fix-modalias-string-generation.patch new file mode 100644 index 00000000000..b5f89289fa9 --- /dev/null +++ b/target/linux/generic/backport-5.15/828-v6.4-0001-of-Fix-modalias-string-generation.patch @@ -0,0 +1,70 @@ +From b19a4266c52de78496fe40f0b37580a3b762e67d Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:09 +0100 +Subject: [PATCH] of: Fix modalias string generation + +The helper generating an OF based modalias (of_device_get_modalias()) +works fine, but due to the use of snprintf() internally it needs a +buffer one byte longer than what should be needed just for the entire +string (excluding the '\0'). Most users of this helper are sysfs hooks +providing the modalias string to users. They all provide a PAGE_SIZE +buffer which is way above the number of bytes required to fit the +modalias string and hence do not suffer from this issue. + +There is another user though, of_device_request_module(), which is only +called by drivers/usb/common/ulpi.c. This request module function is +faulty, but maybe because in most cases there is an alternative, ULPI +driver users have not noticed it. + +In this function, of_device_get_modalias() is called twice. The first +time without buffer just to get the number of bytes required by the +modalias string (excluding the null byte), and a second time, after +buffer allocation, to fill the buffer. The allocation asks for an +additional byte, in order to store the trailing '\0'. However, the +buffer *length* provided to of_device_get_modalias() excludes this extra +byte. The internal use of snprintf() with a length that is exactly the +number of bytes to be written has the effect of using the last available +byte to store a '\0', which then smashes the last character of the +modalias string. + +Provide the actual size of the buffer to of_device_get_modalias() to fix +this issue. + +Note: the "str[size - 1] = '\0';" line is not really needed as snprintf +will anyway end the string with a null byte, but there is a possibility +that this function might be called on a struct device_node without +compatible, in this case snprintf() would not be executed. So we keep it +just to avoid possible unbounded strings. + +Cc: Stephen Boyd +Cc: Peter Chen +Fixes: 9c829c097f2f ("of: device: Support loading a module with OF based modalias") +Signed-off-by: Miquel Raynal +Reviewed-by: Rob Herring +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-2-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/of/device.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/of/device.c ++++ b/drivers/of/device.c +@@ -290,12 +290,15 @@ int of_device_request_module(struct devi + if (size < 0) + return size; + +- str = kmalloc(size + 1, GFP_KERNEL); ++ /* Reserve an additional byte for the trailing '\0' */ ++ size++; ++ ++ str = kmalloc(size, GFP_KERNEL); + if (!str) + return -ENOMEM; + + of_device_get_modalias(dev, str, size); +- str[size] = '\0'; ++ str[size - 1] = '\0'; + ret = request_module(str); + kfree(str); + diff --git a/target/linux/generic/backport-5.15/828-v6.4-0002-of-Update-of_device_get_modalias.patch b/target/linux/generic/backport-5.15/828-v6.4-0002-of-Update-of_device_get_modalias.patch new file mode 100644 index 00000000000..4713cc71b12 --- /dev/null +++ b/target/linux/generic/backport-5.15/828-v6.4-0002-of-Update-of_device_get_modalias.patch @@ -0,0 +1,103 @@ +From 5c3d15e127ebfc0754cd18def7124633b6d46672 Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:15 +0100 +Subject: [PATCH] of: Update of_device_get_modalias() + +This function only needs a "struct device_node" to work, but for +convenience the author (and only user) of this helper did use a "struct +device" and put it in device.c. + +Let's convert this helper to take a "struct device node" instead. This +change asks for two additional changes: renaming it "of_modalias()" +to fit the current naming, and moving it outside of device.c which will +be done in a follow-up commit. + +Signed-off-by: Miquel Raynal +Reviewed-by: Rob Herring +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-8-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/of/device.c | 29 +++++++++++++++++------------ + 1 file changed, 17 insertions(+), 12 deletions(-) + +--- a/drivers/of/device.c ++++ b/drivers/of/device.c +@@ -241,7 +241,7 @@ const void *of_device_get_match_data(con + } + EXPORT_SYMBOL(of_device_get_match_data); + +-static ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len) ++static ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len) + { + const char *compat; + char *c; +@@ -249,19 +249,16 @@ static ssize_t of_device_get_modalias(st + ssize_t csize; + ssize_t tsize; + +- if ((!dev) || (!dev->of_node) || dev->of_node_reused) +- return -ENODEV; +- + /* Name & Type */ + /* %p eats all alphanum characters, so %c must be used here */ +- csize = snprintf(str, len, "of:N%pOFn%c%s", dev->of_node, 'T', +- of_node_get_device_type(dev->of_node)); ++ csize = snprintf(str, len, "of:N%pOFn%c%s", np, 'T', ++ of_node_get_device_type(np)); + tsize = csize; + len -= csize; + if (str) + str += csize; + +- of_property_for_each_string(dev->of_node, "compatible", p, compat) { ++ of_property_for_each_string(np, "compatible", p, compat) { + csize = strlen(compat) + 1; + tsize += csize; + if (csize > len) +@@ -286,7 +283,10 @@ int of_device_request_module(struct devi + ssize_t size; + int ret; + +- size = of_device_get_modalias(dev, NULL, 0); ++ if (!dev || !dev->of_node) ++ return -ENODEV; ++ ++ size = of_modalias(dev->of_node, NULL, 0); + if (size < 0) + return size; + +@@ -297,7 +297,7 @@ int of_device_request_module(struct devi + if (!str) + return -ENOMEM; + +- of_device_get_modalias(dev, str, size); ++ of_modalias(dev->of_node, str, size); + str[size - 1] = '\0'; + ret = request_module(str); + kfree(str); +@@ -314,7 +314,12 @@ EXPORT_SYMBOL_GPL(of_device_request_modu + */ + ssize_t of_device_modalias(struct device *dev, char *str, ssize_t len) + { +- ssize_t sl = of_device_get_modalias(dev, str, len - 2); ++ ssize_t sl; ++ ++ if (!dev || !dev->of_node || dev->of_node_reused) ++ return -ENODEV; ++ ++ sl = of_modalias(dev->of_node, str, len - 2); + if (sl < 0) + return sl; + if (sl > len - 2) +@@ -379,8 +384,8 @@ int of_device_uevent_modalias(struct dev + if (add_uevent_var(env, "MODALIAS=")) + return -ENOMEM; + +- sl = of_device_get_modalias(dev, &env->buf[env->buflen-1], +- sizeof(env->buf) - env->buflen); ++ sl = of_modalias(dev->of_node, &env->buf[env->buflen-1], ++ sizeof(env->buf) - env->buflen); + if (sl < 0) + return sl; + if (sl >= (sizeof(env->buf) - env->buflen)) diff --git a/target/linux/generic/backport-5.15/828-v6.4-0003-of-Rename-of_modalias_node.patch b/target/linux/generic/backport-5.15/828-v6.4-0003-of-Rename-of_modalias_node.patch new file mode 100644 index 00000000000..6c205217018 --- /dev/null +++ b/target/linux/generic/backport-5.15/828-v6.4-0003-of-Rename-of_modalias_node.patch @@ -0,0 +1,173 @@ +From 673aa1ed1c9b6710bf24e3f0957d85e2f46c77db Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:16 +0100 +Subject: [PATCH] of: Rename of_modalias_node() + +This helper does not produce a real modalias, but tries to get the +"product" compatible part of the "vendor,product" compatibles only. It +is far from creating a purely useful modalias string and does not seem +to be used like that directly anyway, so let's try to give this helper a +more meaningful name before moving there a real modalias helper (already +existing under of/device.c). + +Also update the various documentations to refer to the strings as +"aliases" rather than "modaliases" which has a real meaning in the Linux +kernel. + +There is no functional change. + +Cc: Rafael J. Wysocki +Cc: Len Brown +Cc: Maarten Lankhorst +Cc: Maxime Ripard +Cc: Thomas Zimmermann +Cc: Sebastian Reichel +Cc: Wolfram Sang +Cc: Mark Brown +Signed-off-by: Miquel Raynal +Reviewed-by: Rob Herring +Acked-by: Mark Brown +Signed-off-by: Srinivas Kandagatla +Acked-by: Sebastian Reichel +Link: https://lore.kernel.org/r/20230404172148.82422-9-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/acpi/bus.c | 7 ++++--- + drivers/gpu/drm/drm_mipi_dsi.c | 2 +- + drivers/hsi/hsi_core.c | 2 +- + drivers/i2c/busses/i2c-powermac.c | 2 +- + drivers/i2c/i2c-core-of.c | 2 +- + drivers/of/base.c | 18 +++++++++++------- + drivers/spi/spi.c | 4 ++-- + include/linux/of.h | 3 ++- + 8 files changed, 23 insertions(+), 17 deletions(-) + +--- a/drivers/acpi/bus.c ++++ b/drivers/acpi/bus.c +@@ -785,9 +785,10 @@ static bool acpi_of_modalias(struct acpi + * @modalias: Pointer to buffer that modalias value will be copied into + * @len: Length of modalias buffer + * +- * This is a counterpart of of_modalias_node() for struct acpi_device objects. +- * If there is a compatible string for @adev, it will be copied to @modalias +- * with the vendor prefix stripped; otherwise, @default_id will be used. ++ * This is a counterpart of of_alias_from_compatible() for struct acpi_device ++ * objects. If there is a compatible string for @adev, it will be copied to ++ * @modalias with the vendor prefix stripped; otherwise, @default_id will be ++ * used. + */ + void acpi_set_modalias(struct acpi_device *adev, const char *default_id, + char *modalias, size_t len) +--- a/drivers/gpu/drm/drm_mipi_dsi.c ++++ b/drivers/gpu/drm/drm_mipi_dsi.c +@@ -160,7 +160,7 @@ of_mipi_dsi_device_add(struct mipi_dsi_h + int ret; + u32 reg; + +- if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) { ++ if (of_alias_from_compatible(node, info.type, sizeof(info.type)) < 0) { + drm_err(host, "modalias failure on %pOF\n", node); + return ERR_PTR(-EINVAL); + } +--- a/drivers/hsi/hsi_core.c ++++ b/drivers/hsi/hsi_core.c +@@ -207,7 +207,7 @@ static void hsi_add_client_from_dt(struc + if (!cl) + return; + +- err = of_modalias_node(client, name, sizeof(name)); ++ err = of_alias_from_compatible(client, name, sizeof(name)); + if (err) + goto err; + +--- a/drivers/i2c/busses/i2c-powermac.c ++++ b/drivers/i2c/busses/i2c-powermac.c +@@ -284,7 +284,7 @@ static bool i2c_powermac_get_type(struct + */ + + /* First try proper modalias */ +- if (of_modalias_node(node, tmp, sizeof(tmp)) >= 0) { ++ if (of_alias_from_compatible(node, tmp, sizeof(tmp)) >= 0) { + snprintf(type, type_size, "MAC,%s", tmp); + return true; + } +--- a/drivers/i2c/i2c-core-of.c ++++ b/drivers/i2c/i2c-core-of.c +@@ -27,7 +27,7 @@ int of_i2c_get_board_info(struct device + + memset(info, 0, sizeof(*info)); + +- if (of_modalias_node(node, info->type, sizeof(info->type)) < 0) { ++ if (of_alias_from_compatible(node, info->type, sizeof(info->type)) < 0) { + dev_err(dev, "of_i2c: modalias failure on %pOF\n", node); + return -EINVAL; + } +--- a/drivers/of/base.c ++++ b/drivers/of/base.c +@@ -1159,19 +1159,23 @@ struct device_node *of_find_matching_nod + EXPORT_SYMBOL(of_find_matching_node_and_match); + + /** +- * of_modalias_node - Lookup appropriate modalias for a device node ++ * of_alias_from_compatible - Lookup appropriate alias for a device node ++ * depending on compatible + * @node: pointer to a device tree node +- * @modalias: Pointer to buffer that modalias value will be copied into +- * @len: Length of modalias value ++ * @alias: Pointer to buffer that alias value will be copied into ++ * @len: Length of alias value + * + * Based on the value of the compatible property, this routine will attempt +- * to choose an appropriate modalias value for a particular device tree node. ++ * to choose an appropriate alias value for a particular device tree node. + * It does this by stripping the manufacturer prefix (as delimited by a ',') + * from the first entry in the compatible list property. + * ++ * Note: The matching on just the "product" side of the compatible is a relic ++ * from I2C and SPI. Please do not add any new user. ++ * + * Return: This routine returns 0 on success, <0 on failure. + */ +-int of_modalias_node(struct device_node *node, char *modalias, int len) ++int of_alias_from_compatible(const struct device_node *node, char *alias, int len) + { + const char *compatible, *p; + int cplen; +@@ -1180,10 +1184,10 @@ int of_modalias_node(struct device_node + if (!compatible || strlen(compatible) > cplen) + return -ENODEV; + p = strchr(compatible, ','); +- strlcpy(modalias, p ? p + 1 : compatible, len); ++ strlcpy(alias, p ? p + 1 : compatible, len); + return 0; + } +-EXPORT_SYMBOL_GPL(of_modalias_node); ++EXPORT_SYMBOL_GPL(of_alias_from_compatible); + + /** + * of_find_node_by_phandle - Find a node given a phandle +--- a/drivers/spi/spi.c ++++ b/drivers/spi/spi.c +@@ -2128,8 +2128,8 @@ of_register_spi_device(struct spi_contro + } + + /* Select device driver */ +- rc = of_modalias_node(nc, spi->modalias, +- sizeof(spi->modalias)); ++ rc = of_alias_from_compatible(nc, spi->modalias, ++ sizeof(spi->modalias)); + if (rc < 0) { + dev_err(&ctlr->dev, "cannot find modalias for %pOF\n", nc); + goto err_out; +--- a/include/linux/of.h ++++ b/include/linux/of.h +@@ -361,7 +361,8 @@ extern int of_n_addr_cells(struct device + extern int of_n_size_cells(struct device_node *np); + extern const struct of_device_id *of_match_node( + const struct of_device_id *matches, const struct device_node *node); +-extern int of_modalias_node(struct device_node *node, char *modalias, int len); ++extern int of_alias_from_compatible(const struct device_node *node, char *alias, ++ int len); + extern void of_print_phandle_args(const char *msg, const struct of_phandle_args *args); + extern int __of_parse_phandle_with_args(const struct device_node *np, + const char *list_name, const char *cells_name, int cell_count, diff --git a/target/linux/generic/backport-5.15/828-v6.4-0004-of-Move-of_modalias-to-module.c.patch b/target/linux/generic/backport-5.15/828-v6.4-0004-of-Move-of_modalias-to-module.c.patch new file mode 100644 index 00000000000..a70c6f2eec8 --- /dev/null +++ b/target/linux/generic/backport-5.15/828-v6.4-0004-of-Move-of_modalias-to-module.c.patch @@ -0,0 +1,160 @@ +From bd7a7ed774afd1a4174df34227626c95573be517 Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:17 +0100 +Subject: [PATCH] of: Move of_modalias() to module.c + +Create a specific .c file for OF related module handling. +Move of_modalias() inside as a first step. + +The helper is exposed through of.h even though it is only used by core +files because the users from device.c will soon be split into an OF-only +helper in module.c as well as a device-oriented inline helper in +of_device.h. Putting this helper in of_private.h would require to +include of_private.h from of_device.h, which is not acceptable. + +Suggested-by: Rob Herring +Signed-off-by: Miquel Raynal +Reviewed-by: Rob Herring +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-10-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/of/Makefile | 2 +- + drivers/of/device.c | 37 ------------------------------------- + drivers/of/module.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ + include/linux/of.h | 9 +++++++++ + 4 files changed, 54 insertions(+), 38 deletions(-) + create mode 100644 drivers/of/module.c + +--- a/drivers/of/Makefile ++++ b/drivers/of/Makefile +@@ -1,5 +1,5 @@ + # SPDX-License-Identifier: GPL-2.0 +-obj-y = base.o device.o platform.o property.o ++obj-y = base.o device.o module.o platform.o property.o + obj-$(CONFIG_OF_KOBJ) += kobj.o + obj-$(CONFIG_OF_DYNAMIC) += dynamic.o + obj-$(CONFIG_OF_FLATTREE) += fdt.o +--- a/drivers/of/device.c ++++ b/drivers/of/device.c +@@ -1,5 +1,4 @@ + // SPDX-License-Identifier: GPL-2.0 +-#include + #include + #include + #include +@@ -241,42 +240,6 @@ const void *of_device_get_match_data(con + } + EXPORT_SYMBOL(of_device_get_match_data); + +-static ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len) +-{ +- const char *compat; +- char *c; +- struct property *p; +- ssize_t csize; +- ssize_t tsize; +- +- /* Name & Type */ +- /* %p eats all alphanum characters, so %c must be used here */ +- csize = snprintf(str, len, "of:N%pOFn%c%s", np, 'T', +- of_node_get_device_type(np)); +- tsize = csize; +- len -= csize; +- if (str) +- str += csize; +- +- of_property_for_each_string(np, "compatible", p, compat) { +- csize = strlen(compat) + 1; +- tsize += csize; +- if (csize > len) +- continue; +- +- csize = snprintf(str, len, "C%s", compat); +- for (c = str; c; ) { +- c = strchr(c, ' '); +- if (c) +- *c++ = '_'; +- } +- len -= csize; +- str += csize; +- } +- +- return tsize; +-} +- + int of_device_request_module(struct device *dev) + { + char *str; +--- /dev/null ++++ b/drivers/of/module.c +@@ -0,0 +1,44 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Linux kernel module helpers. ++ */ ++ ++#include ++#include ++#include ++ ++ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len) ++{ ++ const char *compat; ++ char *c; ++ struct property *p; ++ ssize_t csize; ++ ssize_t tsize; ++ ++ /* Name & Type */ ++ /* %p eats all alphanum characters, so %c must be used here */ ++ csize = snprintf(str, len, "of:N%pOFn%c%s", np, 'T', ++ of_node_get_device_type(np)); ++ tsize = csize; ++ len -= csize; ++ if (str) ++ str += csize; ++ ++ of_property_for_each_string(np, "compatible", p, compat) { ++ csize = strlen(compat) + 1; ++ tsize += csize; ++ if (csize > len) ++ continue; ++ ++ csize = snprintf(str, len, "C%s", compat); ++ for (c = str; c; ) { ++ c = strchr(c, ' '); ++ if (c) ++ *c++ = '_'; ++ } ++ len -= csize; ++ str += csize; ++ } ++ ++ return tsize; ++} +--- a/include/linux/of.h ++++ b/include/linux/of.h +@@ -373,6 +373,9 @@ extern int of_parse_phandle_with_args_ma + extern int of_count_phandle_with_args(const struct device_node *np, + const char *list_name, const char *cells_name); + ++/* module functions */ ++extern ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len); ++ + /* phandle iterator functions */ + extern int of_phandle_iterator_init(struct of_phandle_iterator *it, + const struct device_node *np, +@@ -885,6 +888,12 @@ static inline int of_count_phandle_with_ + return -ENOSYS; + } + ++static inline ssize_t of_modalias(const struct device_node *np, char *str, ++ ssize_t len) ++{ ++ return -ENODEV; ++} ++ + static inline int of_phandle_iterator_init(struct of_phandle_iterator *it, + const struct device_node *np, + const char *list_name, diff --git a/target/linux/generic/backport-5.15/828-v6.4-0005-of-Move-the-request-module-helper-logic-to-module.c.patch b/target/linux/generic/backport-5.15/828-v6.4-0005-of-Move-the-request-module-helper-logic-to-module.c.patch new file mode 100644 index 00000000000..06bc24ca6e3 --- /dev/null +++ b/target/linux/generic/backport-5.15/828-v6.4-0005-of-Move-the-request-module-helper-logic-to-module.c.patch @@ -0,0 +1,131 @@ +From e6506f06d5e82765666902ccf9e9162f3e31d518 Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:18 +0100 +Subject: [PATCH] of: Move the request module helper logic to module.c + +Depending on device.c for pure OF handling is considered +backwards. Let's extract the content of of_device_request_module() to +have the real logic under module.c. + +The next step will be to convert users of of_device_request_module() to +use the new helper. + +Signed-off-by: Miquel Raynal +Reviewed-by: Rob Herring +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-11-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/of/device.c | 25 ++----------------------- + drivers/of/module.c | 30 ++++++++++++++++++++++++++++++ + include/linux/of.h | 6 ++++++ + 3 files changed, 38 insertions(+), 23 deletions(-) + +--- a/drivers/of/device.c ++++ b/drivers/of/device.c +@@ -8,7 +8,6 @@ + #include /* for bus_dma_region */ + #include + #include +-#include + #include + #include + #include +@@ -242,30 +241,10 @@ EXPORT_SYMBOL(of_device_get_match_data); + + int of_device_request_module(struct device *dev) + { +- char *str; +- ssize_t size; +- int ret; +- +- if (!dev || !dev->of_node) ++ if (!dev) + return -ENODEV; + +- size = of_modalias(dev->of_node, NULL, 0); +- if (size < 0) +- return size; +- +- /* Reserve an additional byte for the trailing '\0' */ +- size++; +- +- str = kmalloc(size, GFP_KERNEL); +- if (!str) +- return -ENOMEM; +- +- of_modalias(dev->of_node, str, size); +- str[size - 1] = '\0'; +- ret = request_module(str); +- kfree(str); +- +- return ret; ++ return of_request_module(dev->of_node); + } + EXPORT_SYMBOL_GPL(of_device_request_module); + +--- a/drivers/of/module.c ++++ b/drivers/of/module.c +@@ -4,6 +4,7 @@ + */ + + #include ++#include + #include + #include + +@@ -42,3 +43,32 @@ ssize_t of_modalias(const struct device_ + + return tsize; + } ++ ++int of_request_module(const struct device_node *np) ++{ ++ char *str; ++ ssize_t size; ++ int ret; ++ ++ if (!np) ++ return -ENODEV; ++ ++ size = of_modalias(np, NULL, 0); ++ if (size < 0) ++ return size; ++ ++ /* Reserve an additional byte for the trailing '\0' */ ++ size++; ++ ++ str = kmalloc(size, GFP_KERNEL); ++ if (!str) ++ return -ENOMEM; ++ ++ of_modalias(np, str, size); ++ str[size - 1] = '\0'; ++ ret = request_module(str); ++ kfree(str); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(of_request_module); +--- a/include/linux/of.h ++++ b/include/linux/of.h +@@ -375,6 +375,7 @@ extern int of_count_phandle_with_args(co + + /* module functions */ + extern ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len); ++extern int of_request_module(const struct device_node *np); + + /* phandle iterator functions */ + extern int of_phandle_iterator_init(struct of_phandle_iterator *it, +@@ -893,6 +894,11 @@ static inline ssize_t of_modalias(const + { + return -ENODEV; + } ++ ++static inline int of_request_module(const struct device_node *np) ++{ ++ return -ENODEV; ++} + + static inline int of_phandle_iterator_init(struct of_phandle_iterator *it, + const struct device_node *np, From b67ba02fc848cee5175cfdefe81e10adf195c435 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 6 Apr 2023 07:26:11 +0200 Subject: [PATCH 07/14] kernel: backport mtd fixes for nvmem MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit They are needed for NVMEM changes pending for v6.4. Signed-off-by: Rafał Miłecki --- ...-unique-name-for-nvmem-device-take-t.patch | 43 +++++++++++++++ ...2-mtd-core-fix-nvmem-error-reporting.patch | 47 ++++++++++++++++ ...re-fix-error-path-for-nvmem-provider.patch | 55 +++++++++++++++++++ ...-mtd_otp_nvmem_add-to-handle-EPROBE_.patch | 47 ++++++++++++++++ ...rans-call-add-disks-after-mtd-device.patch | 10 ++-- 5 files changed, 197 insertions(+), 5 deletions(-) create mode 100644 target/linux/generic/backport-5.15/424-v6.4-0001-mtd-core-provide-unique-name-for-nvmem-device-take-t.patch create mode 100644 target/linux/generic/backport-5.15/424-v6.4-0002-mtd-core-fix-nvmem-error-reporting.patch create mode 100644 target/linux/generic/backport-5.15/424-v6.4-0003-mtd-core-fix-error-path-for-nvmem-provider.patch create mode 100644 target/linux/generic/backport-5.15/424-v6.4-0004-mtd-core-prepare-mtd_otp_nvmem_add-to-handle-EPROBE_.patch diff --git a/target/linux/generic/backport-5.15/424-v6.4-0001-mtd-core-provide-unique-name-for-nvmem-device-take-t.patch b/target/linux/generic/backport-5.15/424-v6.4-0001-mtd-core-provide-unique-name-for-nvmem-device-take-t.patch new file mode 100644 index 00000000000..a453f241e0e --- /dev/null +++ b/target/linux/generic/backport-5.15/424-v6.4-0001-mtd-core-provide-unique-name-for-nvmem-device-take-t.patch @@ -0,0 +1,43 @@ +From 1cd9ceaa5282ff10ea20a7fbadde5a476a1cc99e Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Wed, 8 Mar 2023 09:20:18 +0100 +Subject: [PATCH] mtd: core: provide unique name for nvmem device, take two + +Commit c048b60d39e1 ("mtd: core: provide unique name for nvmem device") +tries to give the nvmem device a unique name, but fails badly if the mtd +device doesn't have a "struct device" associated with it, i.e. if +CONFIG_MTD_PARTITIONED_MASTER is not set. This will result in the name +"(null)-user-otp", which is not unique. It seems the best we can do is +to use the compatible name together with a unique identifier added by +the nvmem subsystem by using NVMEM_DEVID_AUTO. + +Fixes: c048b60d39e1 ("mtd: core: provide unique name for nvmem device") +Cc: stable@vger.kernel.org +Signed-off-by: Michael Walle +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20230308082021.870459-1-michael@walle.cc +--- + drivers/mtd/mtdcore.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/drivers/mtd/mtdcore.c ++++ b/drivers/mtd/mtdcore.c +@@ -895,8 +895,8 @@ static struct nvmem_device *mtd_otp_nvme + + /* OTP nvmem will be registered on the physical device */ + config.dev = mtd->dev.parent; +- config.name = kasprintf(GFP_KERNEL, "%s-%s", dev_name(&mtd->dev), compatible); +- config.id = NVMEM_DEVID_NONE; ++ config.name = compatible; ++ config.id = NVMEM_DEVID_AUTO; + config.owner = THIS_MODULE; + config.type = NVMEM_TYPE_OTP; + config.root_only = true; +@@ -912,7 +912,6 @@ static struct nvmem_device *mtd_otp_nvme + nvmem = NULL; + + of_node_put(np); +- kfree(config.name); + + return nvmem; + } diff --git a/target/linux/generic/backport-5.15/424-v6.4-0002-mtd-core-fix-nvmem-error-reporting.patch b/target/linux/generic/backport-5.15/424-v6.4-0002-mtd-core-fix-nvmem-error-reporting.patch new file mode 100644 index 00000000000..501e9409e22 --- /dev/null +++ b/target/linux/generic/backport-5.15/424-v6.4-0002-mtd-core-fix-nvmem-error-reporting.patch @@ -0,0 +1,47 @@ +From 8bd1d24e6ca3c599dd455b0e1b22f77bab8290eb Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Wed, 8 Mar 2023 09:20:19 +0100 +Subject: [PATCH] mtd: core: fix nvmem error reporting + +The master MTD will only have an associated device if +CONFIG_MTD_PARTITIONED_MASTER is set, thus we cannot use dev_err() on +mtd->dev. Instead use the parent device which is the physical flash +memory. + +Fixes: 4b361cfa8624 ("mtd: core: add OTP nvmem provider support") +Cc: stable@vger.kernel.org +Signed-off-by: Michael Walle +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20230308082021.870459-2-michael@walle.cc +--- + drivers/mtd/mtdcore.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/mtd/mtdcore.c ++++ b/drivers/mtd/mtdcore.c +@@ -946,6 +946,7 @@ static int mtd_nvmem_fact_otp_reg_read(v + + static int mtd_otp_nvmem_add(struct mtd_info *mtd) + { ++ struct device *dev = mtd->dev.parent; + struct nvmem_device *nvmem; + ssize_t size; + int err; +@@ -959,7 +960,7 @@ static int mtd_otp_nvmem_add(struct mtd_ + nvmem = mtd_otp_nvmem_register(mtd, "user-otp", size, + mtd_nvmem_user_otp_reg_read); + if (IS_ERR(nvmem)) { +- dev_err(&mtd->dev, "Failed to register OTP NVMEM device\n"); ++ dev_err(dev, "Failed to register OTP NVMEM device\n"); + return PTR_ERR(nvmem); + } + mtd->otp_user_nvmem = nvmem; +@@ -977,7 +978,7 @@ static int mtd_otp_nvmem_add(struct mtd_ + nvmem = mtd_otp_nvmem_register(mtd, "factory-otp", size, + mtd_nvmem_fact_otp_reg_read); + if (IS_ERR(nvmem)) { +- dev_err(&mtd->dev, "Failed to register OTP NVMEM device\n"); ++ dev_err(dev, "Failed to register OTP NVMEM device\n"); + err = PTR_ERR(nvmem); + goto err; + } diff --git a/target/linux/generic/backport-5.15/424-v6.4-0003-mtd-core-fix-error-path-for-nvmem-provider.patch b/target/linux/generic/backport-5.15/424-v6.4-0003-mtd-core-fix-error-path-for-nvmem-provider.patch new file mode 100644 index 00000000000..099f0d28796 --- /dev/null +++ b/target/linux/generic/backport-5.15/424-v6.4-0003-mtd-core-fix-error-path-for-nvmem-provider.patch @@ -0,0 +1,55 @@ +From e0489f6e221f5ddee6cb3bd51b992b790c5fa4b9 Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Wed, 8 Mar 2023 09:20:20 +0100 +Subject: [PATCH] mtd: core: fix error path for nvmem provider + +If mtd_otp_nvmem_add() fails, the partitions won't be removed +because there is simply no call to del_mtd_partitions(). +Unfortunately, add_mtd_partitions() will print all partitions to +the kernel console. If mtd_otp_nvmem_add() returns -EPROBE_DEFER +this would print the partitions multiple times to the kernel +console. Instead move mtd_otp_nvmem_add() to the beginning of the +function. + +Fixes: 4b361cfa8624 ("mtd: core: add OTP nvmem provider support") +Cc: stable@vger.kernel.org +Signed-off-by: Michael Walle +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20230308082021.870459-3-michael@walle.cc +--- + drivers/mtd/mtdcore.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +--- a/drivers/mtd/mtdcore.c ++++ b/drivers/mtd/mtdcore.c +@@ -1031,10 +1031,14 @@ int mtd_device_parse_register(struct mtd + + mtd_set_dev_defaults(mtd); + ++ ret = mtd_otp_nvmem_add(mtd); ++ if (ret) ++ goto out; ++ + if (IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) { + ret = add_mtd_device(mtd); + if (ret) +- return ret; ++ goto out; + } + + /* Prefer parsed partitions over driver-provided fallback */ +@@ -1069,9 +1073,12 @@ int mtd_device_parse_register(struct mtd + register_reboot_notifier(&mtd->reboot_notifier); + } + +- ret = mtd_otp_nvmem_add(mtd); +- + out: ++ if (ret) { ++ nvmem_unregister(mtd->otp_user_nvmem); ++ nvmem_unregister(mtd->otp_factory_nvmem); ++ } ++ + if (ret && device_is_registered(&mtd->dev)) + del_mtd_device(mtd); + diff --git a/target/linux/generic/backport-5.15/424-v6.4-0004-mtd-core-prepare-mtd_otp_nvmem_add-to-handle-EPROBE_.patch b/target/linux/generic/backport-5.15/424-v6.4-0004-mtd-core-prepare-mtd_otp_nvmem_add-to-handle-EPROBE_.patch new file mode 100644 index 00000000000..2d89a5db126 --- /dev/null +++ b/target/linux/generic/backport-5.15/424-v6.4-0004-mtd-core-prepare-mtd_otp_nvmem_add-to-handle-EPROBE_.patch @@ -0,0 +1,47 @@ +From 281f7a6c1a33fffcde32001bacbb4f672140fbf9 Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Wed, 8 Mar 2023 09:20:21 +0100 +Subject: [PATCH] mtd: core: prepare mtd_otp_nvmem_add() to handle + -EPROBE_DEFER + +NVMEM soon will get the ability for nvmem layouts and these might +not be ready when nvmem_register() is called and thus it might +return -EPROBE_DEFER. Don't print the error message in this case. + +Signed-off-by: Michael Walle +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20230308082021.870459-4-michael@walle.cc +--- + drivers/mtd/mtdcore.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +--- a/drivers/mtd/mtdcore.c ++++ b/drivers/mtd/mtdcore.c +@@ -960,8 +960,8 @@ static int mtd_otp_nvmem_add(struct mtd_ + nvmem = mtd_otp_nvmem_register(mtd, "user-otp", size, + mtd_nvmem_user_otp_reg_read); + if (IS_ERR(nvmem)) { +- dev_err(dev, "Failed to register OTP NVMEM device\n"); +- return PTR_ERR(nvmem); ++ err = PTR_ERR(nvmem); ++ goto err; + } + mtd->otp_user_nvmem = nvmem; + } +@@ -978,7 +978,6 @@ static int mtd_otp_nvmem_add(struct mtd_ + nvmem = mtd_otp_nvmem_register(mtd, "factory-otp", size, + mtd_nvmem_fact_otp_reg_read); + if (IS_ERR(nvmem)) { +- dev_err(dev, "Failed to register OTP NVMEM device\n"); + err = PTR_ERR(nvmem); + goto err; + } +@@ -991,7 +990,7 @@ static int mtd_otp_nvmem_add(struct mtd_ + err: + if (mtd->otp_user_nvmem) + nvmem_unregister(mtd->otp_user_nvmem); +- return err; ++ return dev_err_probe(dev, err, "Failed to register OTP NVMEM device\n"); + } + + /** diff --git a/target/linux/generic/hack-5.15/402-mtd-blktrans-call-add-disks-after-mtd-device.patch b/target/linux/generic/hack-5.15/402-mtd-blktrans-call-add-disks-after-mtd-device.patch index b10b8d99796..32a7fb62664 100644 --- a/target/linux/generic/hack-5.15/402-mtd-blktrans-call-add-disks-after-mtd-device.patch +++ b/target/linux/generic/hack-5.15/402-mtd-blktrans-call-add-disks-after-mtd-device.patch @@ -77,15 +77,15 @@ Signed-off-by: Daniel Golle #include "mtdcore.h" -@@ -1081,6 +1082,8 @@ int mtd_device_parse_register(struct mtd - - ret = mtd_otp_nvmem_add(mtd); +@@ -1082,6 +1083,8 @@ int mtd_device_parse_register(struct mtd + register_reboot_notifier(&mtd->reboot_notifier); + } + register_mtd_blktrans_devs(); + out: - if (ret && device_is_registered(&mtd->dev)) - del_mtd_device(mtd); + if (ret) { + nvmem_unregister(mtd->otp_user_nvmem); --- a/include/linux/mtd/blktrans.h +++ b/include/linux/mtd/blktrans.h @@ -76,6 +76,7 @@ extern int deregister_mtd_blktrans(struc From 323072f3a6fb709d5a20dbd1375816e8c041a85b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 6 Apr 2023 09:15:49 +0200 Subject: [PATCH 08/14] kernel: backport NVMEM patches queued for the v6.4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit They add NVMEM layouts support. It allows handling NVMEM content independently of NVMEM device access. Skip U-Boot env data patch for now as it break our downstream MAC hacks. Signed-off-by: Rafał Miłecki --- ...001-nvmem-xilinx-zynqmp-make-modular.patch | 35 ++ ...2-nvmem-core-introduce-NVMEM-layouts.patch | 387 ++++++++++++++++++ ...ndle-the-absence-of-expected-layouts.patch | 61 +++ ...-core-request-layout-modules-loading.patch | 52 +++ ...em-core-add-per-cell-post-processing.patch | 86 ++++ ...ow-to-modify-a-cell-before-adding-it.patch | 59 +++ ...replace-global-post-processing-with-.patch | 81 ++++ ...m-cell-drop-global-cell_post_process.patch | 68 +++ ...de-own-priv-pointer-in-post-process-.patch | 76 ++++ ...ayouts-sl28vpd-Add-new-layout-driver.patch | 215 ++++++++++ ...youts-onie-tlv-Add-new-layout-driver.patch | 306 ++++++++++++++ ...m-mark-OF-related-data-as-maybe-unus.patch | 32 ++ ...Support-postprocessing-for-GPU-speed.patch | 120 ++++++ ...p-Use-devm_platform_ioremap_resource.patch | 39 ++ ...tp-Use-devm_platform_ioremap_resourc.patch | 39 ++ ...p-Use-devm_platform_get_and_ioremap_.patch | 32 ++ ...rt-specifying-both-cell-raw-data-pos.patch | 115 ++++++ ...cro-to-register-nvmem-layout-drivers.patch | 42 ++ ...28vpd-Use-module_nvmem_layout_driver.patch | 39 ++ ...ie-tlv-Use-module_nvmem_layout_drive.patch | 39 ++ ...uts-onie-tlv-Drop-wrong-module-alias.patch | 24 ++ ...28vpd-set-varaiable-sl28vpd_layout-s.patch | 31 ++ ...001-nvmem-xilinx-zynqmp-make-modular.patch | 35 ++ ...2-nvmem-core-introduce-NVMEM-layouts.patch | 387 ++++++++++++++++++ ...ndle-the-absence-of-expected-layouts.patch | 61 +++ ...-core-request-layout-modules-loading.patch | 52 +++ ...em-core-add-per-cell-post-processing.patch | 86 ++++ ...ow-to-modify-a-cell-before-adding-it.patch | 59 +++ ...replace-global-post-processing-with-.patch | 81 ++++ ...m-cell-drop-global-cell_post_process.patch | 68 +++ ...de-own-priv-pointer-in-post-process-.patch | 76 ++++ ...ayouts-sl28vpd-Add-new-layout-driver.patch | 215 ++++++++++ ...youts-onie-tlv-Add-new-layout-driver.patch | 306 ++++++++++++++ ...m-mark-OF-related-data-as-maybe-unus.patch | 32 ++ ...Support-postprocessing-for-GPU-speed.patch | 120 ++++++ ...p-Use-devm_platform_ioremap_resource.patch | 39 ++ ...tp-Use-devm_platform_ioremap_resourc.patch | 39 ++ ...p-Use-devm_platform_get_and_ioremap_.patch | 32 ++ ...rt-specifying-both-cell-raw-data-pos.patch | 115 ++++++ ...cro-to-register-nvmem-layout-drivers.patch | 42 ++ ...28vpd-Use-module_nvmem_layout_driver.patch | 39 ++ ...ie-tlv-Use-module_nvmem_layout_drive.patch | 39 ++ ...uts-onie-tlv-Drop-wrong-module-alias.patch | 24 ++ ...28vpd-set-varaiable-sl28vpd_layout-s.patch | 31 ++ target/linux/generic/config-5.10 | 2 + target/linux/generic/config-5.15 | 2 + 46 files changed, 3960 insertions(+) create mode 100644 target/linux/generic/backport-5.10/814-v6.4-0001-nvmem-xilinx-zynqmp-make-modular.patch create mode 100644 target/linux/generic/backport-5.10/814-v6.4-0002-nvmem-core-introduce-NVMEM-layouts.patch create mode 100644 target/linux/generic/backport-5.10/814-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch create mode 100644 target/linux/generic/backport-5.10/814-v6.4-0004-nvmem-core-request-layout-modules-loading.patch create mode 100644 target/linux/generic/backport-5.10/814-v6.4-0005-nvmem-core-add-per-cell-post-processing.patch create mode 100644 target/linux/generic/backport-5.10/814-v6.4-0006-nvmem-core-allow-to-modify-a-cell-before-adding-it.patch create mode 100644 target/linux/generic/backport-5.10/814-v6.4-0007-nvmem-imx-ocotp-replace-global-post-processing-with-.patch create mode 100644 target/linux/generic/backport-5.10/814-v6.4-0008-nvmem-cell-drop-global-cell_post_process.patch create mode 100644 target/linux/generic/backport-5.10/814-v6.4-0009-nvmem-core-provide-own-priv-pointer-in-post-process-.patch create mode 100644 target/linux/generic/backport-5.10/814-v6.4-0010-nvmem-layouts-sl28vpd-Add-new-layout-driver.patch create mode 100644 target/linux/generic/backport-5.10/814-v6.4-0011-nvmem-layouts-onie-tlv-Add-new-layout-driver.patch create mode 100644 target/linux/generic/backport-5.10/814-v6.4-0012-nvmem-stm32-romem-mark-OF-related-data-as-maybe-unus.patch create mode 100644 target/linux/generic/backport-5.10/814-v6.4-0013-nvmem-mtk-efuse-Support-postprocessing-for-GPU-speed.patch create mode 100644 target/linux/generic/backport-5.10/814-v6.4-0014-nvmem-bcm-ocotp-Use-devm_platform_ioremap_resource.patch create mode 100644 target/linux/generic/backport-5.10/814-v6.4-0015-nvmem-nintendo-otp-Use-devm_platform_ioremap_resourc.patch create mode 100644 target/linux/generic/backport-5.10/814-v6.4-0016-nvmem-vf610-ocotp-Use-devm_platform_get_and_ioremap_.patch create mode 100644 target/linux/generic/backport-5.10/814-v6.4-0017-nvmem-core-support-specifying-both-cell-raw-data-pos.patch create mode 100644 target/linux/generic/backport-5.10/814-v6.4-0019-nvmem-Add-macro-to-register-nvmem-layout-drivers.patch create mode 100644 target/linux/generic/backport-5.10/814-v6.4-0020-nvmem-layouts-sl28vpd-Use-module_nvmem_layout_driver.patch create mode 100644 target/linux/generic/backport-5.10/814-v6.4-0021-nvmem-layouts-onie-tlv-Use-module_nvmem_layout_drive.patch create mode 100644 target/linux/generic/backport-5.10/814-v6.4-0022-nvmem-layouts-onie-tlv-Drop-wrong-module-alias.patch create mode 100644 target/linux/generic/backport-5.10/814-v6.4-0023-nvmem-layouts-sl28vpd-set-varaiable-sl28vpd_layout-s.patch create mode 100644 target/linux/generic/backport-5.15/811-v6.4-0001-nvmem-xilinx-zynqmp-make-modular.patch create mode 100644 target/linux/generic/backport-5.15/811-v6.4-0002-nvmem-core-introduce-NVMEM-layouts.patch create mode 100644 target/linux/generic/backport-5.15/811-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch create mode 100644 target/linux/generic/backport-5.15/811-v6.4-0004-nvmem-core-request-layout-modules-loading.patch create mode 100644 target/linux/generic/backport-5.15/811-v6.4-0005-nvmem-core-add-per-cell-post-processing.patch create mode 100644 target/linux/generic/backport-5.15/811-v6.4-0006-nvmem-core-allow-to-modify-a-cell-before-adding-it.patch create mode 100644 target/linux/generic/backport-5.15/811-v6.4-0007-nvmem-imx-ocotp-replace-global-post-processing-with-.patch create mode 100644 target/linux/generic/backport-5.15/811-v6.4-0008-nvmem-cell-drop-global-cell_post_process.patch create mode 100644 target/linux/generic/backport-5.15/811-v6.4-0009-nvmem-core-provide-own-priv-pointer-in-post-process-.patch create mode 100644 target/linux/generic/backport-5.15/811-v6.4-0010-nvmem-layouts-sl28vpd-Add-new-layout-driver.patch create mode 100644 target/linux/generic/backport-5.15/811-v6.4-0011-nvmem-layouts-onie-tlv-Add-new-layout-driver.patch create mode 100644 target/linux/generic/backport-5.15/811-v6.4-0012-nvmem-stm32-romem-mark-OF-related-data-as-maybe-unus.patch create mode 100644 target/linux/generic/backport-5.15/811-v6.4-0013-nvmem-mtk-efuse-Support-postprocessing-for-GPU-speed.patch create mode 100644 target/linux/generic/backport-5.15/811-v6.4-0014-nvmem-bcm-ocotp-Use-devm_platform_ioremap_resource.patch create mode 100644 target/linux/generic/backport-5.15/811-v6.4-0015-nvmem-nintendo-otp-Use-devm_platform_ioremap_resourc.patch create mode 100644 target/linux/generic/backport-5.15/811-v6.4-0016-nvmem-vf610-ocotp-Use-devm_platform_get_and_ioremap_.patch create mode 100644 target/linux/generic/backport-5.15/811-v6.4-0017-nvmem-core-support-specifying-both-cell-raw-data-pos.patch create mode 100644 target/linux/generic/backport-5.15/811-v6.4-0019-nvmem-Add-macro-to-register-nvmem-layout-drivers.patch create mode 100644 target/linux/generic/backport-5.15/811-v6.4-0020-nvmem-layouts-sl28vpd-Use-module_nvmem_layout_driver.patch create mode 100644 target/linux/generic/backport-5.15/811-v6.4-0021-nvmem-layouts-onie-tlv-Use-module_nvmem_layout_drive.patch create mode 100644 target/linux/generic/backport-5.15/811-v6.4-0022-nvmem-layouts-onie-tlv-Drop-wrong-module-alias.patch create mode 100644 target/linux/generic/backport-5.15/811-v6.4-0023-nvmem-layouts-sl28vpd-set-varaiable-sl28vpd_layout-s.patch diff --git a/target/linux/generic/backport-5.10/814-v6.4-0001-nvmem-xilinx-zynqmp-make-modular.patch b/target/linux/generic/backport-5.10/814-v6.4-0001-nvmem-xilinx-zynqmp-make-modular.patch new file mode 100644 index 00000000000..8328e87c0af --- /dev/null +++ b/target/linux/generic/backport-5.10/814-v6.4-0001-nvmem-xilinx-zynqmp-make-modular.patch @@ -0,0 +1,35 @@ +From bcd1fe07def0f070eb5f31594620aaee6f81d31a Mon Sep 17 00:00:00 2001 +From: Nick Alcock +Date: Tue, 4 Apr 2023 18:21:11 +0100 +Subject: [PATCH] nvmem: xilinx: zynqmp: make modular + +This driver has a MODULE_LICENSE but is not tristate so cannot be +built as a module, unlike all its peers: make it modular to match. + +Signed-off-by: Nick Alcock +Suggested-by: Michal Simek +Cc: Luis Chamberlain +Cc: linux-modules@vger.kernel.org +Cc: linux-kernel@vger.kernel.org +Cc: Hitomi Hasegawa +Cc: Srinivas Kandagatla +Cc: Michal Simek +Cc: linux-arm-kernel@lists.infradead.org +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-4-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/nvmem/Kconfig ++++ b/drivers/nvmem/Kconfig +@@ -368,7 +368,7 @@ config NVMEM_VF610_OCOTP + be called nvmem-vf610-ocotp. + + config NVMEM_ZYNQMP +- bool "Xilinx ZYNQMP SoC nvmem firmware support" ++ tristate "Xilinx ZYNQMP SoC nvmem firmware support" + depends on ARCH_ZYNQMP + help + This is a driver to access hardware related data like diff --git a/target/linux/generic/backport-5.10/814-v6.4-0002-nvmem-core-introduce-NVMEM-layouts.patch b/target/linux/generic/backport-5.10/814-v6.4-0002-nvmem-core-introduce-NVMEM-layouts.patch new file mode 100644 index 00000000000..8b886aea2e6 --- /dev/null +++ b/target/linux/generic/backport-5.10/814-v6.4-0002-nvmem-core-introduce-NVMEM-layouts.patch @@ -0,0 +1,387 @@ +From 266570f496b90dea8fda893c2cf7c28d63ae2bd9 Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Tue, 4 Apr 2023 18:21:21 +0100 +Subject: [PATCH] nvmem: core: introduce NVMEM layouts + +NVMEM layouts are used to generate NVMEM cells during runtime. Think of +an EEPROM with a well-defined conent. For now, the content can be +described by a device tree or a board file. But this only works if the +offsets and lengths are static and don't change. One could also argue +that putting the layout of the EEPROM in the device tree is the wrong +place. Instead, the device tree should just have a specific compatible +string. + +Right now there are two use cases: + (1) The NVMEM cell needs special processing. E.g. if it only specifies + a base MAC address offset and you need to add an offset, or it + needs to parse a MAC from ASCII format or some proprietary format. + (Post processing of cells is added in a later commit). + (2) u-boot environment parsing. The cells don't have a particular + offset but it needs parsing the content to determine the offsets + and length. + +Co-developed-by: Miquel Raynal +Signed-off-by: Miquel Raynal +Signed-off-by: Michael Walle +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-14-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/driver-api/nvmem.rst | 15 ++++ + drivers/nvmem/Kconfig | 4 + + drivers/nvmem/Makefile | 1 + + drivers/nvmem/core.c | 120 +++++++++++++++++++++++++++++ + drivers/nvmem/layouts/Kconfig | 5 ++ + drivers/nvmem/layouts/Makefile | 4 + + include/linux/nvmem-consumer.h | 7 ++ + include/linux/nvmem-provider.h | 51 ++++++++++++ + 8 files changed, 207 insertions(+) + create mode 100644 drivers/nvmem/layouts/Kconfig + create mode 100644 drivers/nvmem/layouts/Makefile + +--- a/Documentation/driver-api/nvmem.rst ++++ b/Documentation/driver-api/nvmem.rst +@@ -189,3 +189,18 @@ ex:: + ===================== + + See Documentation/devicetree/bindings/nvmem/nvmem.txt ++ ++8. NVMEM layouts ++================ ++ ++NVMEM layouts are yet another mechanism to create cells. With the device ++tree binding it is possible to specify simple cells by using an offset ++and a length. Sometimes, the cells doesn't have a static offset, but ++the content is still well defined, e.g. tag-length-values. In this case, ++the NVMEM device content has to be first parsed and the cells need to ++be added accordingly. Layouts let you read the content of the NVMEM device ++and let you add cells dynamically. ++ ++Another use case for layouts is the post processing of cells. With layouts, ++it is possible to associate a custom post processing hook to a cell. It ++even possible to add this hook to cells not created by the layout itself. +--- a/drivers/nvmem/Kconfig ++++ b/drivers/nvmem/Kconfig +@@ -21,6 +21,10 @@ config NVMEM_SYSFS + This interface is mostly used by userspace applications to + read/write directly into nvmem. + ++# Layouts ++ ++source "drivers/nvmem/layouts/Kconfig" ++ + # Devices + + config NVMEM_APPLE_EFUSES +--- a/drivers/nvmem/Makefile ++++ b/drivers/nvmem/Makefile +@@ -5,6 +5,7 @@ + + obj-$(CONFIG_NVMEM) += nvmem_core.o + nvmem_core-y := core.o ++obj-y += layouts/ + + # Devices + obj-$(CONFIG_NVMEM_APPLE_EFUSES) += nvmem-apple-efuses.o +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -40,6 +40,7 @@ struct nvmem_device { + nvmem_reg_write_t reg_write; + nvmem_cell_post_process_t cell_post_process; + struct gpio_desc *wp_gpio; ++ struct nvmem_layout *layout; + void *priv; + }; + +@@ -74,6 +75,9 @@ static LIST_HEAD(nvmem_lookup_list); + + static BLOCKING_NOTIFIER_HEAD(nvmem_notifier); + ++static DEFINE_SPINLOCK(nvmem_layout_lock); ++static LIST_HEAD(nvmem_layouts); ++ + static int __nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset, + void *val, size_t bytes) + { +@@ -728,6 +732,101 @@ static int nvmem_add_cells_from_of(struc + return 0; + } + ++int __nvmem_layout_register(struct nvmem_layout *layout, struct module *owner) ++{ ++ layout->owner = owner; ++ ++ spin_lock(&nvmem_layout_lock); ++ list_add(&layout->node, &nvmem_layouts); ++ spin_unlock(&nvmem_layout_lock); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(__nvmem_layout_register); ++ ++void nvmem_layout_unregister(struct nvmem_layout *layout) ++{ ++ spin_lock(&nvmem_layout_lock); ++ list_del(&layout->node); ++ spin_unlock(&nvmem_layout_lock); ++} ++EXPORT_SYMBOL_GPL(nvmem_layout_unregister); ++ ++static struct nvmem_layout *nvmem_layout_get(struct nvmem_device *nvmem) ++{ ++ struct device_node *layout_np, *np = nvmem->dev.of_node; ++ struct nvmem_layout *l, *layout = NULL; ++ ++ layout_np = of_get_child_by_name(np, "nvmem-layout"); ++ if (!layout_np) ++ return NULL; ++ ++ spin_lock(&nvmem_layout_lock); ++ ++ list_for_each_entry(l, &nvmem_layouts, node) { ++ if (of_match_node(l->of_match_table, layout_np)) { ++ if (try_module_get(l->owner)) ++ layout = l; ++ ++ break; ++ } ++ } ++ ++ spin_unlock(&nvmem_layout_lock); ++ of_node_put(layout_np); ++ ++ return layout; ++} ++ ++static void nvmem_layout_put(struct nvmem_layout *layout) ++{ ++ if (layout) ++ module_put(layout->owner); ++} ++ ++static int nvmem_add_cells_from_layout(struct nvmem_device *nvmem) ++{ ++ struct nvmem_layout *layout = nvmem->layout; ++ int ret; ++ ++ if (layout && layout->add_cells) { ++ ret = layout->add_cells(&nvmem->dev, nvmem, layout); ++ if (ret) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++#if IS_ENABLED(CONFIG_OF) ++/** ++ * of_nvmem_layout_get_container() - Get OF node to layout container. ++ * ++ * @nvmem: nvmem device. ++ * ++ * Return: a node pointer with refcount incremented or NULL if no ++ * container exists. Use of_node_put() on it when done. ++ */ ++struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem) ++{ ++ return of_get_child_by_name(nvmem->dev.of_node, "nvmem-layout"); ++} ++EXPORT_SYMBOL_GPL(of_nvmem_layout_get_container); ++#endif ++ ++const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem, ++ struct nvmem_layout *layout) ++{ ++ struct device_node __maybe_unused *layout_np; ++ const struct of_device_id *match; ++ ++ layout_np = of_nvmem_layout_get_container(nvmem); ++ match = of_match_node(layout->of_match_table, layout_np); ++ ++ return match ? match->data : NULL; ++} ++EXPORT_SYMBOL_GPL(nvmem_layout_get_match_data); ++ + /** + * nvmem_register() - Register a nvmem device for given nvmem_config. + * Also creates a binary entry in /sys/bus/nvmem/devices/dev-name/nvmem +@@ -834,6 +933,12 @@ struct nvmem_device *nvmem_register(cons + goto err_put_device; + } + ++ /* ++ * If the driver supplied a layout by config->layout, the module ++ * pointer will be NULL and nvmem_layout_put() will be a noop. ++ */ ++ nvmem->layout = config->layout ?: nvmem_layout_get(nvmem); ++ + if (config->cells) { + rval = nvmem_add_cells(nvmem, config->cells, config->ncells); + if (rval) +@@ -854,12 +959,17 @@ struct nvmem_device *nvmem_register(cons + if (rval) + goto err_remove_cells; + ++ rval = nvmem_add_cells_from_layout(nvmem); ++ if (rval) ++ goto err_remove_cells; ++ + blocking_notifier_call_chain(&nvmem_notifier, NVMEM_ADD, nvmem); + + return nvmem; + + err_remove_cells: + nvmem_device_remove_all_cells(nvmem); ++ nvmem_layout_put(nvmem->layout); + if (config->compat) + nvmem_sysfs_remove_compat(nvmem, config); + err_put_device: +@@ -881,6 +991,7 @@ static void nvmem_device_release(struct + device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom); + + nvmem_device_remove_all_cells(nvmem); ++ nvmem_layout_put(nvmem->layout); + device_unregister(&nvmem->dev); + } + +@@ -1246,6 +1357,15 @@ struct nvmem_cell *of_nvmem_cell_get(str + return ERR_PTR(-EINVAL); + } + ++ /* nvmem layouts produce cells within the nvmem-layout container */ ++ if (of_node_name_eq(nvmem_np, "nvmem-layout")) { ++ nvmem_np = of_get_next_parent(nvmem_np); ++ if (!nvmem_np) { ++ of_node_put(cell_np); ++ return ERR_PTR(-EINVAL); ++ } ++ } ++ + nvmem = __nvmem_device_get(nvmem_np, device_match_of_node); + of_node_put(nvmem_np); + if (IS_ERR(nvmem)) { +--- /dev/null ++++ b/drivers/nvmem/layouts/Kconfig +@@ -0,0 +1,5 @@ ++# SPDX-License-Identifier: GPL-2.0 ++ ++menu "Layout Types" ++ ++endmenu +--- /dev/null ++++ b/drivers/nvmem/layouts/Makefile +@@ -0,0 +1,4 @@ ++# SPDX-License-Identifier: GPL-2.0 ++# ++# Makefile for nvmem layouts. ++# +--- a/include/linux/nvmem-consumer.h ++++ b/include/linux/nvmem-consumer.h +@@ -225,6 +225,7 @@ struct nvmem_cell *of_nvmem_cell_get(str + const char *id); + struct nvmem_device *of_nvmem_device_get(struct device_node *np, + const char *name); ++struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem); + #else + static inline struct nvmem_cell *of_nvmem_cell_get(struct device_node *np, + const char *id) +@@ -237,6 +238,12 @@ static inline struct nvmem_device *of_nv + { + return ERR_PTR(-EOPNOTSUPP); + } ++ ++static inline struct device_node * ++of_nvmem_layout_get_container(struct nvmem_device *nvmem) ++{ ++ return ERR_PTR(-EOPNOTSUPP); ++} + #endif /* CONFIG_NVMEM && CONFIG_OF */ + + #endif /* ifndef _LINUX_NVMEM_CONSUMER_H */ +--- a/include/linux/nvmem-provider.h ++++ b/include/linux/nvmem-provider.h +@@ -88,6 +88,7 @@ struct nvmem_cell_info { + * @stride: Minimum read/write access stride. + * @priv: User context passed to read/write callbacks. + * @ignore_wp: Write Protect pin is managed by the provider. ++ * @layout: Fixed layout associated with this nvmem device. + * + * Note: A default "nvmem" name will be assigned to the device if + * no name is specified in its configuration. In such case "" is +@@ -110,6 +111,7 @@ struct nvmem_config { + bool root_only; + struct device_node *of_node; + bool ignore_wp; ++ struct nvmem_layout *layout; + bool no_of_node; + nvmem_reg_read_t reg_read; + nvmem_reg_write_t reg_write; +@@ -142,6 +144,33 @@ struct nvmem_cell_table { + struct list_head node; + }; + ++/** ++ * struct nvmem_layout - NVMEM layout definitions ++ * ++ * @name: Layout name. ++ * @of_match_table: Open firmware match table. ++ * @add_cells: Will be called if a nvmem device is found which ++ * has this layout. The function will add layout ++ * specific cells with nvmem_add_one_cell(). ++ * @owner: Pointer to struct module. ++ * @node: List node. ++ * ++ * A nvmem device can hold a well defined structure which can just be ++ * evaluated during runtime. For example a TLV list, or a list of "name=val" ++ * pairs. A nvmem layout can parse the nvmem device and add appropriate ++ * cells. ++ */ ++struct nvmem_layout { ++ const char *name; ++ const struct of_device_id *of_match_table; ++ int (*add_cells)(struct device *dev, struct nvmem_device *nvmem, ++ struct nvmem_layout *layout); ++ ++ /* private */ ++ struct module *owner; ++ struct list_head node; ++}; ++ + #if IS_ENABLED(CONFIG_NVMEM) + + struct nvmem_device *nvmem_register(const struct nvmem_config *cfg); +@@ -156,6 +185,14 @@ void nvmem_del_cell_table(struct nvmem_c + int nvmem_add_one_cell(struct nvmem_device *nvmem, + const struct nvmem_cell_info *info); + ++int __nvmem_layout_register(struct nvmem_layout *layout, struct module *owner); ++#define nvmem_layout_register(layout) \ ++ __nvmem_layout_register(layout, THIS_MODULE) ++void nvmem_layout_unregister(struct nvmem_layout *layout); ++ ++const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem, ++ struct nvmem_layout *layout); ++ + #else + + static inline struct nvmem_device *nvmem_register(const struct nvmem_config *c) +@@ -179,5 +216,19 @@ static inline int nvmem_add_one_cell(str + return -EOPNOTSUPP; + } + ++static inline int nvmem_layout_register(struct nvmem_layout *layout) ++{ ++ return -EOPNOTSUPP; ++} ++ ++static inline void nvmem_layout_unregister(struct nvmem_layout *layout) {} ++ ++static inline const void * ++nvmem_layout_get_match_data(struct nvmem_device *nvmem, ++ struct nvmem_layout *layout) ++{ ++ return NULL; ++} ++ + #endif /* CONFIG_NVMEM */ + #endif /* ifndef _LINUX_NVMEM_PROVIDER_H */ diff --git a/target/linux/generic/backport-5.10/814-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch b/target/linux/generic/backport-5.10/814-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch new file mode 100644 index 00000000000..6fa7b6382d8 --- /dev/null +++ b/target/linux/generic/backport-5.10/814-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch @@ -0,0 +1,61 @@ +From 6468a6f45148fb5e95c86b4efebf63f9abcd2137 Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:22 +0100 +Subject: [PATCH] nvmem: core: handle the absence of expected layouts + +Make nvmem_layout_get() return -EPROBE_DEFER while the expected layout +is not available. This condition cannot be triggered today as nvmem +layout drivers are initialed as part of an early init call, but soon +these drivers will be converted into modules and be initialized with a +standard priority, so the unavailability of the drivers might become a +reality that must be taken care of. + +Let's anticipate this by telling the caller the layout might not yet be +available. A probe deferral is requested in this case. + +Please note this does not affect any nvmem device not using layouts, +because an early check against the "nvmem-layout" container presence +will return NULL in this case. + +Signed-off-by: Miquel Raynal +Tested-by: Michael Walle +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-15-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -755,7 +755,7 @@ EXPORT_SYMBOL_GPL(nvmem_layout_unregiste + static struct nvmem_layout *nvmem_layout_get(struct nvmem_device *nvmem) + { + struct device_node *layout_np, *np = nvmem->dev.of_node; +- struct nvmem_layout *l, *layout = NULL; ++ struct nvmem_layout *l, *layout = ERR_PTR(-EPROBE_DEFER); + + layout_np = of_get_child_by_name(np, "nvmem-layout"); + if (!layout_np) +@@ -938,6 +938,13 @@ struct nvmem_device *nvmem_register(cons + * pointer will be NULL and nvmem_layout_put() will be a noop. + */ + nvmem->layout = config->layout ?: nvmem_layout_get(nvmem); ++ if (IS_ERR(nvmem->layout)) { ++ rval = PTR_ERR(nvmem->layout); ++ nvmem->layout = NULL; ++ ++ if (rval == -EPROBE_DEFER) ++ goto err_teardown_compat; ++ } + + if (config->cells) { + rval = nvmem_add_cells(nvmem, config->cells, config->ncells); +@@ -970,6 +977,7 @@ struct nvmem_device *nvmem_register(cons + err_remove_cells: + nvmem_device_remove_all_cells(nvmem); + nvmem_layout_put(nvmem->layout); ++err_teardown_compat: + if (config->compat) + nvmem_sysfs_remove_compat(nvmem, config); + err_put_device: diff --git a/target/linux/generic/backport-5.10/814-v6.4-0004-nvmem-core-request-layout-modules-loading.patch b/target/linux/generic/backport-5.10/814-v6.4-0004-nvmem-core-request-layout-modules-loading.patch new file mode 100644 index 00000000000..b9341666f91 --- /dev/null +++ b/target/linux/generic/backport-5.10/814-v6.4-0004-nvmem-core-request-layout-modules-loading.patch @@ -0,0 +1,52 @@ +From b1c37bec1ccfe5ccab72bc0ddc0dfa45c43e2de2 Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:23 +0100 +Subject: [PATCH] nvmem: core: request layout modules loading + +When a storage device like an eeprom or an mtd device probes, it +registers an nvmem device if the nvmem subsystem has been enabled (bool +symbol). During nvmem registration, if the device is using layouts to +expose dynamic nvmem cells, the core will first try to get a reference +over the layout driver callbacks. In practice there is not relationship +that can be described between the storage driver and the nvmem +layout. So there is no way we can enforce both drivers will be built-in +or both will be modules. If the storage device driver is built-in but +the layout is built as a module, instead of badly failing with an +endless probe deferral loop, lets just make a modprobe call in case the +driver was made available in an initramfs with +of_device_node_request_module(), and offer a fully functional system to +the user. + +Signed-off-by: Miquel Raynal +Tested-by: Michael Walle +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-16-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -17,6 +17,7 @@ + #include + #include + #include ++#include + #include + + struct nvmem_device { +@@ -761,6 +762,13 @@ static struct nvmem_layout *nvmem_layout + if (!layout_np) + return NULL; + ++ /* ++ * In case the nvmem device was built-in while the layout was built as a ++ * module, we shall manually request the layout driver loading otherwise ++ * we'll never have any match. ++ */ ++ of_request_module(layout_np); ++ + spin_lock(&nvmem_layout_lock); + + list_for_each_entry(l, &nvmem_layouts, node) { diff --git a/target/linux/generic/backport-5.10/814-v6.4-0005-nvmem-core-add-per-cell-post-processing.patch b/target/linux/generic/backport-5.10/814-v6.4-0005-nvmem-core-add-per-cell-post-processing.patch new file mode 100644 index 00000000000..53628cd4e4f --- /dev/null +++ b/target/linux/generic/backport-5.10/814-v6.4-0005-nvmem-core-add-per-cell-post-processing.patch @@ -0,0 +1,86 @@ +From 345ec382cd4b736c36e01f155d08c913b225b736 Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Tue, 4 Apr 2023 18:21:24 +0100 +Subject: [PATCH] nvmem: core: add per-cell post processing + +Instead of relying on the name the consumer is using for the cell, like +it is done for the nvmem .cell_post_process configuration parameter, +provide a per-cell post processing hook. This can then be populated by +the NVMEM provider (or the NVMEM layout) when adding the cell. + +Signed-off-by: Michael Walle +Signed-off-by: Miquel Raynal +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-17-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 17 +++++++++++++++++ + include/linux/nvmem-provider.h | 3 +++ + 2 files changed, 20 insertions(+) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -54,6 +54,7 @@ struct nvmem_cell_entry { + int bytes; + int bit_offset; + int nbits; ++ nvmem_cell_post_process_t read_post_process; + struct device_node *np; + struct nvmem_device *nvmem; + struct list_head node; +@@ -470,6 +471,7 @@ static int nvmem_cell_info_to_nvmem_cell + cell->offset = info->offset; + cell->bytes = info->bytes; + cell->name = info->name; ++ cell->read_post_process = info->read_post_process; + + cell->bit_offset = info->bit_offset; + cell->nbits = info->nbits; +@@ -1563,6 +1565,13 @@ static int __nvmem_cell_read(struct nvme + if (cell->bit_offset || cell->nbits) + nvmem_shift_read_buffer_in_place(cell, buf); + ++ if (cell->read_post_process) { ++ rc = cell->read_post_process(nvmem->priv, id, index, ++ cell->offset, buf, cell->bytes); ++ if (rc) ++ return rc; ++ } ++ + if (nvmem->cell_post_process) { + rc = nvmem->cell_post_process(nvmem->priv, id, index, + cell->offset, buf, cell->bytes); +@@ -1671,6 +1680,14 @@ static int __nvmem_cell_entry_write(stru + (cell->bit_offset == 0 && len != cell->bytes)) + return -EINVAL; + ++ /* ++ * Any cells which have a read_post_process hook are read-only because ++ * we cannot reverse the operation and it might affect other cells, ++ * too. ++ */ ++ if (cell->read_post_process) ++ return -EINVAL; ++ + if (cell->bit_offset || cell->nbits) { + buf = nvmem_cell_prepare_write_buffer(cell, buf, len); + if (IS_ERR(buf)) +--- a/include/linux/nvmem-provider.h ++++ b/include/linux/nvmem-provider.h +@@ -54,6 +54,8 @@ struct nvmem_keepout { + * @bit_offset: Bit offset if cell is smaller than a byte. + * @nbits: Number of bits. + * @np: Optional device_node pointer. ++ * @read_post_process: Callback for optional post processing of cell data ++ * on reads. + */ + struct nvmem_cell_info { + const char *name; +@@ -62,6 +64,7 @@ struct nvmem_cell_info { + unsigned int bit_offset; + unsigned int nbits; + struct device_node *np; ++ nvmem_cell_post_process_t read_post_process; + }; + + /** diff --git a/target/linux/generic/backport-5.10/814-v6.4-0006-nvmem-core-allow-to-modify-a-cell-before-adding-it.patch b/target/linux/generic/backport-5.10/814-v6.4-0006-nvmem-core-allow-to-modify-a-cell-before-adding-it.patch new file mode 100644 index 00000000000..32990148c80 --- /dev/null +++ b/target/linux/generic/backport-5.10/814-v6.4-0006-nvmem-core-allow-to-modify-a-cell-before-adding-it.patch @@ -0,0 +1,59 @@ +From de12c9691501ccba41a154c223869f82be4c12fd Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Tue, 4 Apr 2023 18:21:25 +0100 +Subject: [PATCH] nvmem: core: allow to modify a cell before adding it + +Provide a way to modify a cell before it will get added. This is useful +to attach a custom post processing hook via a layout. + +Signed-off-by: Michael Walle +Signed-off-by: Miquel Raynal +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-18-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 4 ++++ + include/linux/nvmem-provider.h | 5 +++++ + 2 files changed, 9 insertions(+) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -695,6 +695,7 @@ static int nvmem_validate_keepouts(struc + + static int nvmem_add_cells_from_of(struct nvmem_device *nvmem) + { ++ struct nvmem_layout *layout = nvmem->layout; + struct device *dev = &nvmem->dev; + struct device_node *child; + const __be32 *addr; +@@ -724,6 +725,9 @@ static int nvmem_add_cells_from_of(struc + + info.np = of_node_get(child); + ++ if (layout && layout->fixup_cell_info) ++ layout->fixup_cell_info(nvmem, layout, &info); ++ + ret = nvmem_add_one_cell(nvmem, &info); + kfree(info.name); + if (ret) { +--- a/include/linux/nvmem-provider.h ++++ b/include/linux/nvmem-provider.h +@@ -155,6 +155,8 @@ struct nvmem_cell_table { + * @add_cells: Will be called if a nvmem device is found which + * has this layout. The function will add layout + * specific cells with nvmem_add_one_cell(). ++ * @fixup_cell_info: Will be called before a cell is added. Can be ++ * used to modify the nvmem_cell_info. + * @owner: Pointer to struct module. + * @node: List node. + * +@@ -168,6 +170,9 @@ struct nvmem_layout { + const struct of_device_id *of_match_table; + int (*add_cells)(struct device *dev, struct nvmem_device *nvmem, + struct nvmem_layout *layout); ++ void (*fixup_cell_info)(struct nvmem_device *nvmem, ++ struct nvmem_layout *layout, ++ struct nvmem_cell_info *cell); + + /* private */ + struct module *owner; diff --git a/target/linux/generic/backport-5.10/814-v6.4-0007-nvmem-imx-ocotp-replace-global-post-processing-with-.patch b/target/linux/generic/backport-5.10/814-v6.4-0007-nvmem-imx-ocotp-replace-global-post-processing-with-.patch new file mode 100644 index 00000000000..2a5fa618ea6 --- /dev/null +++ b/target/linux/generic/backport-5.10/814-v6.4-0007-nvmem-imx-ocotp-replace-global-post-processing-with-.patch @@ -0,0 +1,81 @@ +From 6c56a82d7895a213a43182a5d01a21a906a79847 Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Tue, 4 Apr 2023 18:21:26 +0100 +Subject: [PATCH] nvmem: imx-ocotp: replace global post processing with layouts + +In preparation of retiring the global post processing hook change this +driver to use layouts. The layout will be supplied during registration +and will be used to add the post processing hook to all added cells. + +Signed-off-by: Michael Walle +Tested-by: Michael Walle # on kontron-pitx-imx8m +Signed-off-by: Miquel Raynal +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-19-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/imx-ocotp.c | 30 +++++++++++++++++++----------- + 1 file changed, 19 insertions(+), 11 deletions(-) + +--- a/drivers/nvmem/imx-ocotp.c ++++ b/drivers/nvmem/imx-ocotp.c +@@ -225,18 +225,13 @@ read_end: + static int imx_ocotp_cell_pp(void *context, const char *id, int index, + unsigned int offset, void *data, size_t bytes) + { +- struct ocotp_priv *priv = context; ++ u8 *buf = data; ++ int i; + + /* Deal with some post processing of nvmem cell data */ +- if (id && !strcmp(id, "mac-address")) { +- if (priv->params->reverse_mac_address) { +- u8 *buf = data; +- int i; +- +- for (i = 0; i < bytes/2; i++) +- swap(buf[i], buf[bytes - i - 1]); +- } +- } ++ if (id && !strcmp(id, "mac-address")) ++ for (i = 0; i < bytes / 2; i++) ++ swap(buf[i], buf[bytes - i - 1]); + + return 0; + } +@@ -488,7 +483,6 @@ static struct nvmem_config imx_ocotp_nvm + .stride = 1, + .reg_read = imx_ocotp_read, + .reg_write = imx_ocotp_write, +- .cell_post_process = imx_ocotp_cell_pp, + }; + + static const struct ocotp_params imx6q_params = { +@@ -595,6 +589,17 @@ static const struct of_device_id imx_oco + }; + MODULE_DEVICE_TABLE(of, imx_ocotp_dt_ids); + ++static void imx_ocotp_fixup_cell_info(struct nvmem_device *nvmem, ++ struct nvmem_layout *layout, ++ struct nvmem_cell_info *cell) ++{ ++ cell->read_post_process = imx_ocotp_cell_pp; ++} ++ ++struct nvmem_layout imx_ocotp_layout = { ++ .fixup_cell_info = imx_ocotp_fixup_cell_info, ++}; ++ + static int imx_ocotp_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +@@ -619,6 +624,9 @@ static int imx_ocotp_probe(struct platfo + imx_ocotp_nvmem_config.size = 4 * priv->params->nregs; + imx_ocotp_nvmem_config.dev = dev; + imx_ocotp_nvmem_config.priv = priv; ++ if (priv->params->reverse_mac_address) ++ imx_ocotp_nvmem_config.layout = &imx_ocotp_layout; ++ + priv->config = &imx_ocotp_nvmem_config; + + clk_prepare_enable(priv->clk); diff --git a/target/linux/generic/backport-5.10/814-v6.4-0008-nvmem-cell-drop-global-cell_post_process.patch b/target/linux/generic/backport-5.10/814-v6.4-0008-nvmem-cell-drop-global-cell_post_process.patch new file mode 100644 index 00000000000..eac202b8829 --- /dev/null +++ b/target/linux/generic/backport-5.10/814-v6.4-0008-nvmem-cell-drop-global-cell_post_process.patch @@ -0,0 +1,68 @@ +From 011e40a166fdaa65fb9946b7cd91efec85b70dbb Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Tue, 4 Apr 2023 18:21:27 +0100 +Subject: [PATCH] nvmem: cell: drop global cell_post_process + +There are no users anymore for the global cell_post_process callback +anymore. New users should use proper nvmem layouts. + +Signed-off-by: Michael Walle +Signed-off-by: Miquel Raynal +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-20-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 9 --------- + include/linux/nvmem-provider.h | 2 -- + 2 files changed, 11 deletions(-) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -39,7 +39,6 @@ struct nvmem_device { + unsigned int nkeepout; + nvmem_reg_read_t reg_read; + nvmem_reg_write_t reg_write; +- nvmem_cell_post_process_t cell_post_process; + struct gpio_desc *wp_gpio; + struct nvmem_layout *layout; + void *priv; +@@ -903,7 +902,6 @@ struct nvmem_device *nvmem_register(cons + nvmem->type = config->type; + nvmem->reg_read = config->reg_read; + nvmem->reg_write = config->reg_write; +- nvmem->cell_post_process = config->cell_post_process; + nvmem->keepout = config->keepout; + nvmem->nkeepout = config->nkeepout; + if (config->of_node) +@@ -1575,13 +1573,6 @@ static int __nvmem_cell_read(struct nvme + if (rc) + return rc; + } +- +- if (nvmem->cell_post_process) { +- rc = nvmem->cell_post_process(nvmem->priv, id, index, +- cell->offset, buf, cell->bytes); +- if (rc) +- return rc; +- } + + if (len) + *len = cell->bytes; +--- a/include/linux/nvmem-provider.h ++++ b/include/linux/nvmem-provider.h +@@ -85,7 +85,6 @@ struct nvmem_cell_info { + * @no_of_node: Device should not use the parent's of_node even if it's !NULL. + * @reg_read: Callback to read data. + * @reg_write: Callback to write data. +- * @cell_post_process: Callback for vendor specific post processing of cell data + * @size: Device size. + * @word_size: Minimum read/write access granularity. + * @stride: Minimum read/write access stride. +@@ -118,7 +117,6 @@ struct nvmem_config { + bool no_of_node; + nvmem_reg_read_t reg_read; + nvmem_reg_write_t reg_write; +- nvmem_cell_post_process_t cell_post_process; + int size; + int word_size; + int stride; diff --git a/target/linux/generic/backport-5.10/814-v6.4-0009-nvmem-core-provide-own-priv-pointer-in-post-process-.patch b/target/linux/generic/backport-5.10/814-v6.4-0009-nvmem-core-provide-own-priv-pointer-in-post-process-.patch new file mode 100644 index 00000000000..46b30a2ed90 --- /dev/null +++ b/target/linux/generic/backport-5.10/814-v6.4-0009-nvmem-core-provide-own-priv-pointer-in-post-process-.patch @@ -0,0 +1,76 @@ +From 8a134fd9f9323f4c39ec27055b3d3723cfb5c1e9 Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Tue, 4 Apr 2023 18:21:28 +0100 +Subject: [PATCH] nvmem: core: provide own priv pointer in post process + callback + +It doesn't make any more sense to have a opaque pointer set up by the +nvmem device. Usually, the layout isn't associated with a particular +nvmem device. Instead, let the caller who set the post process callback +provide the priv pointer. + +Signed-off-by: Michael Walle +Signed-off-by: Miquel Raynal +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-21-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 4 +++- + include/linux/nvmem-provider.h | 5 ++++- + 2 files changed, 7 insertions(+), 2 deletions(-) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -54,6 +54,7 @@ struct nvmem_cell_entry { + int bit_offset; + int nbits; + nvmem_cell_post_process_t read_post_process; ++ void *priv; + struct device_node *np; + struct nvmem_device *nvmem; + struct list_head node; +@@ -471,6 +472,7 @@ static int nvmem_cell_info_to_nvmem_cell + cell->bytes = info->bytes; + cell->name = info->name; + cell->read_post_process = info->read_post_process; ++ cell->priv = info->priv; + + cell->bit_offset = info->bit_offset; + cell->nbits = info->nbits; +@@ -1568,7 +1570,7 @@ static int __nvmem_cell_read(struct nvme + nvmem_shift_read_buffer_in_place(cell, buf); + + if (cell->read_post_process) { +- rc = cell->read_post_process(nvmem->priv, id, index, ++ rc = cell->read_post_process(cell->priv, id, index, + cell->offset, buf, cell->bytes); + if (rc) + return rc; +--- a/include/linux/nvmem-provider.h ++++ b/include/linux/nvmem-provider.h +@@ -20,7 +20,8 @@ typedef int (*nvmem_reg_write_t)(void *p + void *val, size_t bytes); + /* used for vendor specific post processing of cell data */ + typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, int index, +- unsigned int offset, void *buf, size_t bytes); ++ unsigned int offset, void *buf, ++ size_t bytes); + + enum nvmem_type { + NVMEM_TYPE_UNKNOWN = 0, +@@ -56,6 +57,7 @@ struct nvmem_keepout { + * @np: Optional device_node pointer. + * @read_post_process: Callback for optional post processing of cell data + * on reads. ++ * @priv: Opaque data passed to the read_post_process hook. + */ + struct nvmem_cell_info { + const char *name; +@@ -65,6 +67,7 @@ struct nvmem_cell_info { + unsigned int nbits; + struct device_node *np; + nvmem_cell_post_process_t read_post_process; ++ void *priv; + }; + + /** diff --git a/target/linux/generic/backport-5.10/814-v6.4-0010-nvmem-layouts-sl28vpd-Add-new-layout-driver.patch b/target/linux/generic/backport-5.10/814-v6.4-0010-nvmem-layouts-sl28vpd-Add-new-layout-driver.patch new file mode 100644 index 00000000000..7d97658b60e --- /dev/null +++ b/target/linux/generic/backport-5.10/814-v6.4-0010-nvmem-layouts-sl28vpd-Add-new-layout-driver.patch @@ -0,0 +1,215 @@ +From d9fae023fe86069750092fc1c2f3a73e2fb18512 Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Tue, 4 Apr 2023 18:21:29 +0100 +Subject: [PATCH] nvmem: layouts: sl28vpd: Add new layout driver + +This layout applies to the VPD of the Kontron sl28 boards. The VPD only +contains a base MAC address. Therefore, we have to add an individual +offset to it. This is done by taking the second argument of the nvmem +phandle into account. Also this let us checking the VPD version and the +checksum. + +Signed-off-by: Michael Walle +Signed-off-by: Miquel Raynal +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-22-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/layouts/Kconfig | 9 ++ + drivers/nvmem/layouts/Makefile | 2 + + drivers/nvmem/layouts/sl28vpd.c | 165 ++++++++++++++++++++++++++++++++ + 3 files changed, 176 insertions(+) + create mode 100644 drivers/nvmem/layouts/sl28vpd.c + +--- a/drivers/nvmem/layouts/Kconfig ++++ b/drivers/nvmem/layouts/Kconfig +@@ -2,4 +2,13 @@ + + menu "Layout Types" + ++config NVMEM_LAYOUT_SL28_VPD ++ tristate "Kontron sl28 VPD layout support" ++ select CRC8 ++ help ++ Say Y here if you want to support the VPD layout of the Kontron ++ SMARC-sAL28 boards. ++ ++ If unsure, say N. ++ + endmenu +--- a/drivers/nvmem/layouts/Makefile ++++ b/drivers/nvmem/layouts/Makefile +@@ -2,3 +2,5 @@ + # + # Makefile for nvmem layouts. + # ++ ++obj-$(CONFIG_NVMEM_LAYOUT_SL28_VPD) += sl28vpd.o +--- /dev/null ++++ b/drivers/nvmem/layouts/sl28vpd.c +@@ -0,0 +1,165 @@ ++// SPDX-License-Identifier: GPL-2.0 ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define SL28VPD_MAGIC 'V' ++ ++struct sl28vpd_header { ++ u8 magic; ++ u8 version; ++} __packed; ++ ++struct sl28vpd_v1 { ++ struct sl28vpd_header header; ++ char serial_number[15]; ++ u8 base_mac_address[ETH_ALEN]; ++ u8 crc8; ++} __packed; ++ ++static int sl28vpd_mac_address_pp(void *priv, const char *id, int index, ++ unsigned int offset, void *buf, ++ size_t bytes) ++{ ++ if (bytes != ETH_ALEN) ++ return -EINVAL; ++ ++ if (index < 0) ++ return -EINVAL; ++ ++ if (!is_valid_ether_addr(buf)) ++ return -EINVAL; ++ ++ eth_addr_add(buf, index); ++ ++ return 0; ++} ++ ++static const struct nvmem_cell_info sl28vpd_v1_entries[] = { ++ { ++ .name = "serial-number", ++ .offset = offsetof(struct sl28vpd_v1, serial_number), ++ .bytes = sizeof_field(struct sl28vpd_v1, serial_number), ++ }, ++ { ++ .name = "base-mac-address", ++ .offset = offsetof(struct sl28vpd_v1, base_mac_address), ++ .bytes = sizeof_field(struct sl28vpd_v1, base_mac_address), ++ .read_post_process = sl28vpd_mac_address_pp, ++ }, ++}; ++ ++static int sl28vpd_v1_check_crc(struct device *dev, struct nvmem_device *nvmem) ++{ ++ struct sl28vpd_v1 data_v1; ++ u8 table[CRC8_TABLE_SIZE]; ++ int ret; ++ u8 crc; ++ ++ crc8_populate_msb(table, 0x07); ++ ++ ret = nvmem_device_read(nvmem, 0, sizeof(data_v1), &data_v1); ++ if (ret < 0) ++ return ret; ++ else if (ret != sizeof(data_v1)) ++ return -EIO; ++ ++ crc = crc8(table, (void *)&data_v1, sizeof(data_v1) - 1, 0); ++ ++ if (crc != data_v1.crc8) { ++ dev_err(dev, ++ "Checksum is invalid (got %02x, expected %02x).\n", ++ crc, data_v1.crc8); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int sl28vpd_add_cells(struct device *dev, struct nvmem_device *nvmem, ++ struct nvmem_layout *layout) ++{ ++ const struct nvmem_cell_info *pinfo; ++ struct nvmem_cell_info info = {0}; ++ struct device_node *layout_np; ++ struct sl28vpd_header hdr; ++ int ret, i; ++ ++ /* check header */ ++ ret = nvmem_device_read(nvmem, 0, sizeof(hdr), &hdr); ++ if (ret < 0) ++ return ret; ++ else if (ret != sizeof(hdr)) ++ return -EIO; ++ ++ if (hdr.magic != SL28VPD_MAGIC) { ++ dev_err(dev, "Invalid magic value (%02x)\n", hdr.magic); ++ return -EINVAL; ++ } ++ ++ if (hdr.version != 1) { ++ dev_err(dev, "Version %d is unsupported.\n", hdr.version); ++ return -EINVAL; ++ } ++ ++ ret = sl28vpd_v1_check_crc(dev, nvmem); ++ if (ret) ++ return ret; ++ ++ layout_np = of_nvmem_layout_get_container(nvmem); ++ if (!layout_np) ++ return -ENOENT; ++ ++ for (i = 0; i < ARRAY_SIZE(sl28vpd_v1_entries); i++) { ++ pinfo = &sl28vpd_v1_entries[i]; ++ ++ info.name = pinfo->name; ++ info.offset = pinfo->offset; ++ info.bytes = pinfo->bytes; ++ info.read_post_process = pinfo->read_post_process; ++ info.np = of_get_child_by_name(layout_np, pinfo->name); ++ ++ ret = nvmem_add_one_cell(nvmem, &info); ++ if (ret) { ++ of_node_put(layout_np); ++ return ret; ++ } ++ } ++ ++ of_node_put(layout_np); ++ ++ return 0; ++} ++ ++static const struct of_device_id sl28vpd_of_match_table[] = { ++ { .compatible = "kontron,sl28-vpd" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, sl28vpd_of_match_table); ++ ++struct nvmem_layout sl28vpd_layout = { ++ .name = "sl28-vpd", ++ .of_match_table = sl28vpd_of_match_table, ++ .add_cells = sl28vpd_add_cells, ++}; ++ ++static int __init sl28vpd_init(void) ++{ ++ return nvmem_layout_register(&sl28vpd_layout); ++} ++ ++static void __exit sl28vpd_exit(void) ++{ ++ nvmem_layout_unregister(&sl28vpd_layout); ++} ++ ++module_init(sl28vpd_init); ++module_exit(sl28vpd_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Michael Walle "); ++MODULE_DESCRIPTION("NVMEM layout driver for the VPD of Kontron sl28 boards"); diff --git a/target/linux/generic/backport-5.10/814-v6.4-0011-nvmem-layouts-onie-tlv-Add-new-layout-driver.patch b/target/linux/generic/backport-5.10/814-v6.4-0011-nvmem-layouts-onie-tlv-Add-new-layout-driver.patch new file mode 100644 index 00000000000..ca8b4bc0691 --- /dev/null +++ b/target/linux/generic/backport-5.10/814-v6.4-0011-nvmem-layouts-onie-tlv-Add-new-layout-driver.patch @@ -0,0 +1,306 @@ +From d3c0d12f6474216bf386101e2449cc73e5c5b61d Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:31 +0100 +Subject: [PATCH] nvmem: layouts: onie-tlv: Add new layout driver + +This layout applies on top of any non volatile storage device containing +an ONIE table factory flashed. This table follows the tlv +(type-length-value) organization described in the link below. We cannot +afford using regular parsers because the content of these tables is +manufacturer specific and must be dynamically discovered. + +Link: https://opencomputeproject.github.io/onie/design-spec/hw_requirements.html +Signed-off-by: Miquel Raynal +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-24-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/layouts/Kconfig | 9 ++ + drivers/nvmem/layouts/Makefile | 1 + + drivers/nvmem/layouts/onie-tlv.c | 257 +++++++++++++++++++++++++++++++ + 3 files changed, 267 insertions(+) + create mode 100644 drivers/nvmem/layouts/onie-tlv.c + +--- a/drivers/nvmem/layouts/Kconfig ++++ b/drivers/nvmem/layouts/Kconfig +@@ -11,4 +11,13 @@ config NVMEM_LAYOUT_SL28_VPD + + If unsure, say N. + ++config NVMEM_LAYOUT_ONIE_TLV ++ tristate "ONIE tlv support" ++ select CRC32 ++ help ++ Say Y here if you want to support the Open Compute Project ONIE ++ Type-Length-Value standard table. ++ ++ If unsure, say N. ++ + endmenu +--- a/drivers/nvmem/layouts/Makefile ++++ b/drivers/nvmem/layouts/Makefile +@@ -4,3 +4,4 @@ + # + + obj-$(CONFIG_NVMEM_LAYOUT_SL28_VPD) += sl28vpd.o ++obj-$(CONFIG_NVMEM_LAYOUT_ONIE_TLV) += onie-tlv.o +--- /dev/null ++++ b/drivers/nvmem/layouts/onie-tlv.c +@@ -0,0 +1,257 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * ONIE tlv NVMEM cells provider ++ * ++ * Copyright (C) 2022 Open Compute Group ONIE ++ * Author: Miquel Raynal ++ * Based on the nvmem driver written by: Vadym Kochan ++ * Inspired by the first layout written by: Rafał Miłecki ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define ONIE_TLV_MAX_LEN 2048 ++#define ONIE_TLV_CRC_FIELD_SZ 6 ++#define ONIE_TLV_CRC_SZ 4 ++#define ONIE_TLV_HDR_ID "TlvInfo" ++ ++struct onie_tlv_hdr { ++ u8 id[8]; ++ u8 version; ++ __be16 data_len; ++} __packed; ++ ++struct onie_tlv { ++ u8 type; ++ u8 len; ++} __packed; ++ ++static const char *onie_tlv_cell_name(u8 type) ++{ ++ switch (type) { ++ case 0x21: ++ return "product-name"; ++ case 0x22: ++ return "part-number"; ++ case 0x23: ++ return "serial-number"; ++ case 0x24: ++ return "mac-address"; ++ case 0x25: ++ return "manufacture-date"; ++ case 0x26: ++ return "device-version"; ++ case 0x27: ++ return "label-revision"; ++ case 0x28: ++ return "platform-name"; ++ case 0x29: ++ return "onie-version"; ++ case 0x2A: ++ return "num-macs"; ++ case 0x2B: ++ return "manufacturer"; ++ case 0x2C: ++ return "country-code"; ++ case 0x2D: ++ return "vendor"; ++ case 0x2E: ++ return "diag-version"; ++ case 0x2F: ++ return "service-tag"; ++ case 0xFD: ++ return "vendor-extension"; ++ case 0xFE: ++ return "crc32"; ++ default: ++ break; ++ } ++ ++ return NULL; ++} ++ ++static int onie_tlv_mac_read_cb(void *priv, const char *id, int index, ++ unsigned int offset, void *buf, ++ size_t bytes) ++{ ++ eth_addr_add(buf, index); ++ ++ return 0; ++} ++ ++static nvmem_cell_post_process_t onie_tlv_read_cb(u8 type, u8 *buf) ++{ ++ switch (type) { ++ case 0x24: ++ return &onie_tlv_mac_read_cb; ++ default: ++ break; ++ } ++ ++ return NULL; ++} ++ ++static int onie_tlv_add_cells(struct device *dev, struct nvmem_device *nvmem, ++ size_t data_len, u8 *data) ++{ ++ struct nvmem_cell_info cell = {}; ++ struct device_node *layout; ++ struct onie_tlv tlv; ++ unsigned int hdr_len = sizeof(struct onie_tlv_hdr); ++ unsigned int offset = 0; ++ int ret; ++ ++ layout = of_nvmem_layout_get_container(nvmem); ++ if (!layout) ++ return -ENOENT; ++ ++ while (offset < data_len) { ++ memcpy(&tlv, data + offset, sizeof(tlv)); ++ if (offset + tlv.len >= data_len) { ++ dev_err(dev, "Out of bounds field (0x%x bytes at 0x%x)\n", ++ tlv.len, hdr_len + offset); ++ break; ++ } ++ ++ cell.name = onie_tlv_cell_name(tlv.type); ++ if (!cell.name) ++ continue; ++ ++ cell.offset = hdr_len + offset + sizeof(tlv.type) + sizeof(tlv.len); ++ cell.bytes = tlv.len; ++ cell.np = of_get_child_by_name(layout, cell.name); ++ cell.read_post_process = onie_tlv_read_cb(tlv.type, data + offset + sizeof(tlv)); ++ ++ ret = nvmem_add_one_cell(nvmem, &cell); ++ if (ret) { ++ of_node_put(layout); ++ return ret; ++ } ++ ++ offset += sizeof(tlv) + tlv.len; ++ } ++ ++ of_node_put(layout); ++ ++ return 0; ++} ++ ++static bool onie_tlv_hdr_is_valid(struct device *dev, struct onie_tlv_hdr *hdr) ++{ ++ if (memcmp(hdr->id, ONIE_TLV_HDR_ID, sizeof(hdr->id))) { ++ dev_err(dev, "Invalid header\n"); ++ return false; ++ } ++ ++ if (hdr->version != 0x1) { ++ dev_err(dev, "Invalid version number\n"); ++ return false; ++ } ++ ++ return true; ++} ++ ++static bool onie_tlv_crc_is_valid(struct device *dev, size_t table_len, u8 *table) ++{ ++ struct onie_tlv crc_hdr; ++ u32 read_crc, calc_crc; ++ __be32 crc_be; ++ ++ memcpy(&crc_hdr, table + table_len - ONIE_TLV_CRC_FIELD_SZ, sizeof(crc_hdr)); ++ if (crc_hdr.type != 0xfe || crc_hdr.len != ONIE_TLV_CRC_SZ) { ++ dev_err(dev, "Invalid CRC field\n"); ++ return false; ++ } ++ ++ /* The table contains a JAMCRC, which is XOR'ed compared to the original ++ * CRC32 implementation as known in the Ethernet world. ++ */ ++ memcpy(&crc_be, table + table_len - ONIE_TLV_CRC_SZ, ONIE_TLV_CRC_SZ); ++ read_crc = be32_to_cpu(crc_be); ++ calc_crc = crc32(~0, table, table_len - ONIE_TLV_CRC_SZ) ^ 0xFFFFFFFF; ++ if (read_crc != calc_crc) { ++ dev_err(dev, "Invalid CRC read: 0x%08x, expected: 0x%08x\n", ++ read_crc, calc_crc); ++ return false; ++ } ++ ++ return true; ++} ++ ++static int onie_tlv_parse_table(struct device *dev, struct nvmem_device *nvmem, ++ struct nvmem_layout *layout) ++{ ++ struct onie_tlv_hdr hdr; ++ size_t table_len, data_len, hdr_len; ++ u8 *table, *data; ++ int ret; ++ ++ ret = nvmem_device_read(nvmem, 0, sizeof(hdr), &hdr); ++ if (ret < 0) ++ return ret; ++ ++ if (!onie_tlv_hdr_is_valid(dev, &hdr)) { ++ dev_err(dev, "Invalid ONIE TLV header\n"); ++ return -EINVAL; ++ } ++ ++ hdr_len = sizeof(hdr.id) + sizeof(hdr.version) + sizeof(hdr.data_len); ++ data_len = be16_to_cpu(hdr.data_len); ++ table_len = hdr_len + data_len; ++ if (table_len > ONIE_TLV_MAX_LEN) { ++ dev_err(dev, "Invalid ONIE TLV data length\n"); ++ return -EINVAL; ++ } ++ ++ table = devm_kmalloc(dev, table_len, GFP_KERNEL); ++ if (!table) ++ return -ENOMEM; ++ ++ ret = nvmem_device_read(nvmem, 0, table_len, table); ++ if (ret != table_len) ++ return ret; ++ ++ if (!onie_tlv_crc_is_valid(dev, table_len, table)) ++ return -EINVAL; ++ ++ data = table + hdr_len; ++ ret = onie_tlv_add_cells(dev, nvmem, data_len, data); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static const struct of_device_id onie_tlv_of_match_table[] = { ++ { .compatible = "onie,tlv-layout", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, onie_tlv_of_match_table); ++ ++static struct nvmem_layout onie_tlv_layout = { ++ .name = "ONIE tlv layout", ++ .of_match_table = onie_tlv_of_match_table, ++ .add_cells = onie_tlv_parse_table, ++}; ++ ++static int __init onie_tlv_init(void) ++{ ++ return nvmem_layout_register(&onie_tlv_layout); ++} ++ ++static void __exit onie_tlv_exit(void) ++{ ++ nvmem_layout_unregister(&onie_tlv_layout); ++} ++ ++module_init(onie_tlv_init); ++module_exit(onie_tlv_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Miquel Raynal "); ++MODULE_DESCRIPTION("NVMEM layout driver for Onie TLV table parsing"); ++MODULE_ALIAS("NVMEM layout driver for Onie TLV table parsing"); diff --git a/target/linux/generic/backport-5.10/814-v6.4-0012-nvmem-stm32-romem-mark-OF-related-data-as-maybe-unus.patch b/target/linux/generic/backport-5.10/814-v6.4-0012-nvmem-stm32-romem-mark-OF-related-data-as-maybe-unus.patch new file mode 100644 index 00000000000..94a0911d73c --- /dev/null +++ b/target/linux/generic/backport-5.10/814-v6.4-0012-nvmem-stm32-romem-mark-OF-related-data-as-maybe-unus.patch @@ -0,0 +1,32 @@ +From a4fb434ef96ace5af758ca2c52c3a3f8f3abc87c Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +Date: Tue, 4 Apr 2023 18:21:34 +0100 +Subject: [PATCH] nvmem: stm32-romem: mark OF related data as maybe unused +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The driver can be compile tested with !CONFIG_OF making certain data +unused: + + drivers/nvmem/stm32-romem.c:271:34: error: ‘stm32_romem_of_match’ defined but not used [-Werror=unused-const-variable=] + +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-27-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/stm32-romem.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/nvmem/stm32-romem.c ++++ b/drivers/nvmem/stm32-romem.c +@@ -268,7 +268,7 @@ static const struct stm32_romem_cfg stm3 + .ta = true, + }; + +-static const struct of_device_id stm32_romem_of_match[] = { ++static const struct of_device_id stm32_romem_of_match[] __maybe_unused = { + { .compatible = "st,stm32f4-otp", }, { + .compatible = "st,stm32mp15-bsec", + .data = (void *)&stm32mp15_bsec_cfg, diff --git a/target/linux/generic/backport-5.10/814-v6.4-0013-nvmem-mtk-efuse-Support-postprocessing-for-GPU-speed.patch b/target/linux/generic/backport-5.10/814-v6.4-0013-nvmem-mtk-efuse-Support-postprocessing-for-GPU-speed.patch new file mode 100644 index 00000000000..abda402bddb --- /dev/null +++ b/target/linux/generic/backport-5.10/814-v6.4-0013-nvmem-mtk-efuse-Support-postprocessing-for-GPU-speed.patch @@ -0,0 +1,120 @@ +From de6e05097f7db066afb0ad4c88b730949f7b7749 Mon Sep 17 00:00:00 2001 +From: AngeloGioacchino Del Regno +Date: Tue, 4 Apr 2023 18:21:35 +0100 +Subject: [PATCH] nvmem: mtk-efuse: Support postprocessing for GPU speed + binning data + +On some MediaTek SoCs GPU speed binning data is available for read +in the SoC's eFuse array but it has a format that is incompatible +with what the OPP API expects, as we read a number from 0 to 7 but +opp-supported-hw is expecting a bitmask to enable an OPP entry: +being what we read limited to 0-7, it's straightforward to simply +convert the value to BIT(value) as a post-processing action. + +So, introduce post-processing support and enable it by evaluating +the newly introduced platform data's `uses_post_processing` member, +currently enabled only for MT8186. + +Signed-off-by: AngeloGioacchino Del Regno +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-28-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/mtk-efuse.c | 53 +++++++++++++++++++++++++++++++++++++-- + 1 file changed, 51 insertions(+), 2 deletions(-) + +--- a/drivers/nvmem/mtk-efuse.c ++++ b/drivers/nvmem/mtk-efuse.c +@@ -10,6 +10,11 @@ + #include + #include + #include ++#include ++ ++struct mtk_efuse_pdata { ++ bool uses_post_processing; ++}; + + struct mtk_efuse_priv { + void __iomem *base; +@@ -29,6 +34,37 @@ static int mtk_reg_read(void *context, + return 0; + } + ++static int mtk_efuse_gpu_speedbin_pp(void *context, const char *id, int index, ++ unsigned int offset, void *data, size_t bytes) ++{ ++ u8 *val = data; ++ ++ if (val[0] < 8) ++ val[0] = BIT(val[0]); ++ ++ return 0; ++} ++ ++static void mtk_efuse_fixup_cell_info(struct nvmem_device *nvmem, ++ struct nvmem_layout *layout, ++ struct nvmem_cell_info *cell) ++{ ++ size_t sz = strlen(cell->name); ++ ++ /* ++ * On some SoCs, the GPU speedbin is not read as bitmask but as ++ * a number with range [0-7] (max 3 bits): post process to use ++ * it in OPP tables to describe supported-hw. ++ */ ++ if (cell->nbits <= 3 && ++ strncmp(cell->name, "gpu-speedbin", min(sz, strlen("gpu-speedbin"))) == 0) ++ cell->read_post_process = mtk_efuse_gpu_speedbin_pp; ++} ++ ++static struct nvmem_layout mtk_efuse_layout = { ++ .fixup_cell_info = mtk_efuse_fixup_cell_info, ++}; ++ + static int mtk_efuse_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +@@ -36,6 +72,7 @@ static int mtk_efuse_probe(struct platfo + struct nvmem_device *nvmem; + struct nvmem_config econfig = {}; + struct mtk_efuse_priv *priv; ++ const struct mtk_efuse_pdata *pdata; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) +@@ -45,20 +82,32 @@ static int mtk_efuse_probe(struct platfo + if (IS_ERR(priv->base)) + return PTR_ERR(priv->base); + ++ pdata = device_get_match_data(dev); + econfig.stride = 1; + econfig.word_size = 1; + econfig.reg_read = mtk_reg_read; + econfig.size = resource_size(res); + econfig.priv = priv; + econfig.dev = dev; ++ if (pdata->uses_post_processing) ++ econfig.layout = &mtk_efuse_layout; + nvmem = devm_nvmem_register(dev, &econfig); + + return PTR_ERR_OR_ZERO(nvmem); + } + ++static const struct mtk_efuse_pdata mtk_mt8186_efuse_pdata = { ++ .uses_post_processing = true, ++}; ++ ++static const struct mtk_efuse_pdata mtk_efuse_pdata = { ++ .uses_post_processing = false, ++}; ++ + static const struct of_device_id mtk_efuse_of_match[] = { +- { .compatible = "mediatek,mt8173-efuse",}, +- { .compatible = "mediatek,efuse",}, ++ { .compatible = "mediatek,mt8173-efuse", .data = &mtk_efuse_pdata }, ++ { .compatible = "mediatek,mt8186-efuse", .data = &mtk_mt8186_efuse_pdata }, ++ { .compatible = "mediatek,efuse", .data = &mtk_efuse_pdata }, + {/* sentinel */}, + }; + MODULE_DEVICE_TABLE(of, mtk_efuse_of_match); diff --git a/target/linux/generic/backport-5.10/814-v6.4-0014-nvmem-bcm-ocotp-Use-devm_platform_ioremap_resource.patch b/target/linux/generic/backport-5.10/814-v6.4-0014-nvmem-bcm-ocotp-Use-devm_platform_ioremap_resource.patch new file mode 100644 index 00000000000..a0874f73d15 --- /dev/null +++ b/target/linux/generic/backport-5.10/814-v6.4-0014-nvmem-bcm-ocotp-Use-devm_platform_ioremap_resource.patch @@ -0,0 +1,39 @@ +From 1dc552fa33cf98af3e784dbc0500da93cae3b24a Mon Sep 17 00:00:00 2001 +From: Yang Li +Date: Tue, 4 Apr 2023 18:21:38 +0100 +Subject: [PATCH] nvmem: bcm-ocotp: Use devm_platform_ioremap_resource() + +According to commit 7945f929f1a7 ("drivers: provide +devm_platform_ioremap_resource()"), convert platform_get_resource(), +devm_ioremap_resource() to a single call to use +devm_platform_ioremap_resource(), as this is exactly what this function +does. + +Signed-off-by: Yang Li +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-31-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/bcm-ocotp.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/drivers/nvmem/bcm-ocotp.c ++++ b/drivers/nvmem/bcm-ocotp.c +@@ -254,7 +254,6 @@ MODULE_DEVICE_TABLE(acpi, bcm_otpc_acpi_ + static int bcm_otpc_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +- struct resource *res; + struct otpc_priv *priv; + struct nvmem_device *nvmem; + int err; +@@ -269,8 +268,7 @@ static int bcm_otpc_probe(struct platfor + return -ENODEV; + + /* Get OTP base address register. */ +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- priv->base = devm_ioremap_resource(dev, res); ++ priv->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(priv->base)) { + dev_err(dev, "unable to map I/O memory\n"); + return PTR_ERR(priv->base); diff --git a/target/linux/generic/backport-5.10/814-v6.4-0015-nvmem-nintendo-otp-Use-devm_platform_ioremap_resourc.patch b/target/linux/generic/backport-5.10/814-v6.4-0015-nvmem-nintendo-otp-Use-devm_platform_ioremap_resourc.patch new file mode 100644 index 00000000000..890dacd08db --- /dev/null +++ b/target/linux/generic/backport-5.10/814-v6.4-0015-nvmem-nintendo-otp-Use-devm_platform_ioremap_resourc.patch @@ -0,0 +1,39 @@ +From 649409990d2e93fac657be7c6960c28a2c601d65 Mon Sep 17 00:00:00 2001 +From: Yang Li +Date: Tue, 4 Apr 2023 18:21:39 +0100 +Subject: [PATCH] nvmem: nintendo-otp: Use devm_platform_ioremap_resource() + +According to commit 7945f929f1a7 ("drivers: provide +devm_platform_ioremap_resource()"), convert platform_get_resource(), +devm_ioremap_resource() to a single call to use +devm_platform_ioremap_resource(), as this is exactly what this function +does. + +Signed-off-by: Yang Li +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-32-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/nintendo-otp.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/drivers/nvmem/nintendo-otp.c ++++ b/drivers/nvmem/nintendo-otp.c +@@ -76,7 +76,6 @@ static int nintendo_otp_probe(struct pla + struct device *dev = &pdev->dev; + const struct of_device_id *of_id = + of_match_device(nintendo_otp_of_table, dev); +- struct resource *res; + struct nvmem_device *nvmem; + struct nintendo_otp_priv *priv; + +@@ -92,8 +91,7 @@ static int nintendo_otp_probe(struct pla + if (!priv) + return -ENOMEM; + +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- priv->regs = devm_ioremap_resource(dev, res); ++ priv->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(priv->regs)) + return PTR_ERR(priv->regs); + diff --git a/target/linux/generic/backport-5.10/814-v6.4-0016-nvmem-vf610-ocotp-Use-devm_platform_get_and_ioremap_.patch b/target/linux/generic/backport-5.10/814-v6.4-0016-nvmem-vf610-ocotp-Use-devm_platform_get_and_ioremap_.patch new file mode 100644 index 00000000000..3f5d3c1ad4c --- /dev/null +++ b/target/linux/generic/backport-5.10/814-v6.4-0016-nvmem-vf610-ocotp-Use-devm_platform_get_and_ioremap_.patch @@ -0,0 +1,32 @@ +From c2367aa60d5e34d48582362c6de34b4131d92be7 Mon Sep 17 00:00:00 2001 +From: Yang Li +Date: Tue, 4 Apr 2023 18:21:40 +0100 +Subject: [PATCH] nvmem: vf610-ocotp: Use + devm_platform_get_and_ioremap_resource() + +According to commit 890cc39a8799 ("drivers: provide +devm_platform_get_and_ioremap_resource()"), convert +platform_get_resource(), devm_ioremap_resource() to a single +call to devm_platform_get_and_ioremap_resource(), as this is exactly +what this function does. + +Signed-off-by: Yang Li +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-33-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/vf610-ocotp.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/nvmem/vf610-ocotp.c ++++ b/drivers/nvmem/vf610-ocotp.c +@@ -219,8 +219,7 @@ static int vf610_ocotp_probe(struct plat + if (!ocotp_dev) + return -ENOMEM; + +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- ocotp_dev->base = devm_ioremap_resource(dev, res); ++ ocotp_dev->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); + if (IS_ERR(ocotp_dev->base)) + return PTR_ERR(ocotp_dev->base); + diff --git a/target/linux/generic/backport-5.10/814-v6.4-0017-nvmem-core-support-specifying-both-cell-raw-data-pos.patch b/target/linux/generic/backport-5.10/814-v6.4-0017-nvmem-core-support-specifying-both-cell-raw-data-pos.patch new file mode 100644 index 00000000000..eeb407e9bb6 --- /dev/null +++ b/target/linux/generic/backport-5.10/814-v6.4-0017-nvmem-core-support-specifying-both-cell-raw-data-pos.patch @@ -0,0 +1,115 @@ +From 55d4980ce55b6bb4be66877de4dbec513911b988 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 4 Apr 2023 18:21:42 +0100 +Subject: [PATCH] nvmem: core: support specifying both: cell raw data & post + read lengths +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Callback .read_post_process() is designed to modify raw cell content +before providing it to the consumer. So far we were dealing with +modifications that didn't affect cell size (length). In some cases +however cell content needs to be reformatted and resized. + +It's required e.g. to provide properly formatted MAC address in case +it's stored in a non-binary format (e.g. using ASCII). + +There were few discussions how to optimally handle that. Following +possible solutions were considered: +1. Allow .read_post_process() to realloc (resize) content buffer +2. Allow .read_post_process() to adjust (decrease) just buffer length +3. Register NVMEM cells using post-read sizes + +The preferred solution was the last one. The problem is that simply +adjusting "bytes" in NVMEM providers would result in core code NOT +passing whole raw data to .read_post_process() callbacks. It means +callback functions couldn't do their job without somehow manually +reading original cell content on their own. + +This patch deals with that by registering NVMEM cells with both lengths: +raw content one and post read one. It allows: +1. Core code to read whole raw cell content +2. Callbacks to return content they want + +Signed-off-by: Rafał Miłecki +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-35-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 11 +++++++---- + include/linux/nvmem-provider.h | 2 ++ + 2 files changed, 9 insertions(+), 4 deletions(-) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -50,6 +50,7 @@ struct nvmem_device { + struct nvmem_cell_entry { + const char *name; + int offset; ++ size_t raw_len; + int bytes; + int bit_offset; + int nbits; +@@ -469,6 +470,7 @@ static int nvmem_cell_info_to_nvmem_cell + { + cell->nvmem = nvmem; + cell->offset = info->offset; ++ cell->raw_len = info->raw_len ?: info->bytes; + cell->bytes = info->bytes; + cell->name = info->name; + cell->read_post_process = info->read_post_process; +@@ -1560,7 +1562,7 @@ static int __nvmem_cell_read(struct nvme + { + int rc; + +- rc = nvmem_reg_read(nvmem, cell->offset, buf, cell->bytes); ++ rc = nvmem_reg_read(nvmem, cell->offset, buf, cell->raw_len); + + if (rc) + return rc; +@@ -1571,7 +1573,7 @@ static int __nvmem_cell_read(struct nvme + + if (cell->read_post_process) { + rc = cell->read_post_process(cell->priv, id, index, +- cell->offset, buf, cell->bytes); ++ cell->offset, buf, cell->raw_len); + if (rc) + return rc; + } +@@ -1594,14 +1596,15 @@ static int __nvmem_cell_read(struct nvme + */ + void *nvmem_cell_read(struct nvmem_cell *cell, size_t *len) + { +- struct nvmem_device *nvmem = cell->entry->nvmem; ++ struct nvmem_cell_entry *entry = cell->entry; ++ struct nvmem_device *nvmem = entry->nvmem; + u8 *buf; + int rc; + + if (!nvmem) + return ERR_PTR(-EINVAL); + +- buf = kzalloc(cell->entry->bytes, GFP_KERNEL); ++ buf = kzalloc(max_t(size_t, entry->raw_len, entry->bytes), GFP_KERNEL); + if (!buf) + return ERR_PTR(-ENOMEM); + +--- a/include/linux/nvmem-provider.h ++++ b/include/linux/nvmem-provider.h +@@ -51,6 +51,7 @@ struct nvmem_keepout { + * struct nvmem_cell_info - NVMEM cell description + * @name: Name. + * @offset: Offset within the NVMEM device. ++ * @raw_len: Length of raw data (without post processing). + * @bytes: Length of the cell. + * @bit_offset: Bit offset if cell is smaller than a byte. + * @nbits: Number of bits. +@@ -62,6 +63,7 @@ struct nvmem_keepout { + struct nvmem_cell_info { + const char *name; + unsigned int offset; ++ size_t raw_len; + unsigned int bytes; + unsigned int bit_offset; + unsigned int nbits; diff --git a/target/linux/generic/backport-5.10/814-v6.4-0019-nvmem-Add-macro-to-register-nvmem-layout-drivers.patch b/target/linux/generic/backport-5.10/814-v6.4-0019-nvmem-Add-macro-to-register-nvmem-layout-drivers.patch new file mode 100644 index 00000000000..7c6fe22b5f3 --- /dev/null +++ b/target/linux/generic/backport-5.10/814-v6.4-0019-nvmem-Add-macro-to-register-nvmem-layout-drivers.patch @@ -0,0 +1,42 @@ +From 814c978f02db17f16e6aa2efa2a929372f06da09 Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:44 +0100 +Subject: [PATCH] nvmem: Add macro to register nvmem layout drivers +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Provide a module_nvmem_layout_driver() macro at the end of the +nvmem-provider.h header to reduce the boilerplate when registering nvmem +layout drivers. + +Suggested-by: Srinivas Kandagatla +Signed-off-by: Miquel Raynal +Acked-by: Rafał Miłecki +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-37-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/nvmem-provider.h | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/include/linux/nvmem-provider.h ++++ b/include/linux/nvmem-provider.h +@@ -9,6 +9,7 @@ + #ifndef _LINUX_NVMEM_PROVIDER_H + #define _LINUX_NVMEM_PROVIDER_H + ++#include + #include + #include + #include +@@ -242,4 +243,9 @@ nvmem_layout_get_match_data(struct nvmem + } + + #endif /* CONFIG_NVMEM */ ++ ++#define module_nvmem_layout_driver(__layout_driver) \ ++ module_driver(__layout_driver, nvmem_layout_register, \ ++ nvmem_layout_unregister) ++ + #endif /* ifndef _LINUX_NVMEM_PROVIDER_H */ diff --git a/target/linux/generic/backport-5.10/814-v6.4-0020-nvmem-layouts-sl28vpd-Use-module_nvmem_layout_driver.patch b/target/linux/generic/backport-5.10/814-v6.4-0020-nvmem-layouts-sl28vpd-Use-module_nvmem_layout_driver.patch new file mode 100644 index 00000000000..06646dd68bf --- /dev/null +++ b/target/linux/generic/backport-5.10/814-v6.4-0020-nvmem-layouts-sl28vpd-Use-module_nvmem_layout_driver.patch @@ -0,0 +1,39 @@ +From 0abdf99fe0c86252ba274703425f8d543d7e7f0d Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:45 +0100 +Subject: [PATCH] nvmem: layouts: sl28vpd: Use module_nvmem_layout_driver() + +Stop open-coding the module init/exit functions. Use the +module_nvmem_layout_driver() instead. + +Signed-off-by: Miquel Raynal +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-38-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/layouts/sl28vpd.c | 14 +------------- + 1 file changed, 1 insertion(+), 13 deletions(-) + +--- a/drivers/nvmem/layouts/sl28vpd.c ++++ b/drivers/nvmem/layouts/sl28vpd.c +@@ -146,19 +146,7 @@ struct nvmem_layout sl28vpd_layout = { + .of_match_table = sl28vpd_of_match_table, + .add_cells = sl28vpd_add_cells, + }; +- +-static int __init sl28vpd_init(void) +-{ +- return nvmem_layout_register(&sl28vpd_layout); +-} +- +-static void __exit sl28vpd_exit(void) +-{ +- nvmem_layout_unregister(&sl28vpd_layout); +-} +- +-module_init(sl28vpd_init); +-module_exit(sl28vpd_exit); ++module_nvmem_layout_driver(sl28vpd_layout); + + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("Michael Walle "); diff --git a/target/linux/generic/backport-5.10/814-v6.4-0021-nvmem-layouts-onie-tlv-Use-module_nvmem_layout_drive.patch b/target/linux/generic/backport-5.10/814-v6.4-0021-nvmem-layouts-onie-tlv-Use-module_nvmem_layout_drive.patch new file mode 100644 index 00000000000..826f4378c2f --- /dev/null +++ b/target/linux/generic/backport-5.10/814-v6.4-0021-nvmem-layouts-onie-tlv-Use-module_nvmem_layout_drive.patch @@ -0,0 +1,39 @@ +From d119eb38faab61125aaa4f63c74eef61585cf34c Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:46 +0100 +Subject: [PATCH] nvmem: layouts: onie-tlv: Use module_nvmem_layout_driver() + +Stop open-coding the module init/exit functions. Use the +module_nvmem_layout_driver() instead. + +Signed-off-by: Miquel Raynal +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-39-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/layouts/onie-tlv.c | 14 +------------- + 1 file changed, 1 insertion(+), 13 deletions(-) + +--- a/drivers/nvmem/layouts/onie-tlv.c ++++ b/drivers/nvmem/layouts/onie-tlv.c +@@ -237,19 +237,7 @@ static struct nvmem_layout onie_tlv_layo + .of_match_table = onie_tlv_of_match_table, + .add_cells = onie_tlv_parse_table, + }; +- +-static int __init onie_tlv_init(void) +-{ +- return nvmem_layout_register(&onie_tlv_layout); +-} +- +-static void __exit onie_tlv_exit(void) +-{ +- nvmem_layout_unregister(&onie_tlv_layout); +-} +- +-module_init(onie_tlv_init); +-module_exit(onie_tlv_exit); ++module_nvmem_layout_driver(onie_tlv_layout); + + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("Miquel Raynal "); diff --git a/target/linux/generic/backport-5.10/814-v6.4-0022-nvmem-layouts-onie-tlv-Drop-wrong-module-alias.patch b/target/linux/generic/backport-5.10/814-v6.4-0022-nvmem-layouts-onie-tlv-Drop-wrong-module-alias.patch new file mode 100644 index 00000000000..f20db85ceb6 --- /dev/null +++ b/target/linux/generic/backport-5.10/814-v6.4-0022-nvmem-layouts-onie-tlv-Drop-wrong-module-alias.patch @@ -0,0 +1,24 @@ +From 6b13e4b6a9a45028ac730e550380077df1845912 Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:47 +0100 +Subject: [PATCH] nvmem: layouts: onie-tlv: Drop wrong module alias + +The MODULE_ALIAS macro is misused here as it carries the +description. There is currently no relevant alias to provide so let's +just drop it. + +Signed-off-by: Miquel Raynal +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-40-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/layouts/onie-tlv.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/nvmem/layouts/onie-tlv.c ++++ b/drivers/nvmem/layouts/onie-tlv.c +@@ -242,4 +242,3 @@ module_nvmem_layout_driver(onie_tlv_layo + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("Miquel Raynal "); + MODULE_DESCRIPTION("NVMEM layout driver for Onie TLV table parsing"); +-MODULE_ALIAS("NVMEM layout driver for Onie TLV table parsing"); diff --git a/target/linux/generic/backport-5.10/814-v6.4-0023-nvmem-layouts-sl28vpd-set-varaiable-sl28vpd_layout-s.patch b/target/linux/generic/backport-5.10/814-v6.4-0023-nvmem-layouts-sl28vpd-set-varaiable-sl28vpd_layout-s.patch new file mode 100644 index 00000000000..5cf847b57ae --- /dev/null +++ b/target/linux/generic/backport-5.10/814-v6.4-0023-nvmem-layouts-sl28vpd-set-varaiable-sl28vpd_layout-s.patch @@ -0,0 +1,31 @@ +From a8642cd11635a35a5f1dc31857887900d6610778 Mon Sep 17 00:00:00 2001 +From: Tom Rix +Date: Tue, 4 Apr 2023 18:21:48 +0100 +Subject: [PATCH] nvmem: layouts: sl28vpd: set varaiable sl28vpd_layout + storage-class-specifier to static + +smatch reports +drivers/nvmem/layouts/sl28vpd.c:144:21: warning: symbol + 'sl28vpd_layout' was not declared. Should it be static? + +This variable is only used in one file so it should be static. + +Signed-off-by: Tom Rix +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-41-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/layouts/sl28vpd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/nvmem/layouts/sl28vpd.c ++++ b/drivers/nvmem/layouts/sl28vpd.c +@@ -141,7 +141,7 @@ static const struct of_device_id sl28vpd + }; + MODULE_DEVICE_TABLE(of, sl28vpd_of_match_table); + +-struct nvmem_layout sl28vpd_layout = { ++static struct nvmem_layout sl28vpd_layout = { + .name = "sl28-vpd", + .of_match_table = sl28vpd_of_match_table, + .add_cells = sl28vpd_add_cells, diff --git a/target/linux/generic/backport-5.15/811-v6.4-0001-nvmem-xilinx-zynqmp-make-modular.patch b/target/linux/generic/backport-5.15/811-v6.4-0001-nvmem-xilinx-zynqmp-make-modular.patch new file mode 100644 index 00000000000..8328e87c0af --- /dev/null +++ b/target/linux/generic/backport-5.15/811-v6.4-0001-nvmem-xilinx-zynqmp-make-modular.patch @@ -0,0 +1,35 @@ +From bcd1fe07def0f070eb5f31594620aaee6f81d31a Mon Sep 17 00:00:00 2001 +From: Nick Alcock +Date: Tue, 4 Apr 2023 18:21:11 +0100 +Subject: [PATCH] nvmem: xilinx: zynqmp: make modular + +This driver has a MODULE_LICENSE but is not tristate so cannot be +built as a module, unlike all its peers: make it modular to match. + +Signed-off-by: Nick Alcock +Suggested-by: Michal Simek +Cc: Luis Chamberlain +Cc: linux-modules@vger.kernel.org +Cc: linux-kernel@vger.kernel.org +Cc: Hitomi Hasegawa +Cc: Srinivas Kandagatla +Cc: Michal Simek +Cc: linux-arm-kernel@lists.infradead.org +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-4-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/nvmem/Kconfig ++++ b/drivers/nvmem/Kconfig +@@ -368,7 +368,7 @@ config NVMEM_VF610_OCOTP + be called nvmem-vf610-ocotp. + + config NVMEM_ZYNQMP +- bool "Xilinx ZYNQMP SoC nvmem firmware support" ++ tristate "Xilinx ZYNQMP SoC nvmem firmware support" + depends on ARCH_ZYNQMP + help + This is a driver to access hardware related data like diff --git a/target/linux/generic/backport-5.15/811-v6.4-0002-nvmem-core-introduce-NVMEM-layouts.patch b/target/linux/generic/backport-5.15/811-v6.4-0002-nvmem-core-introduce-NVMEM-layouts.patch new file mode 100644 index 00000000000..23518d21f70 --- /dev/null +++ b/target/linux/generic/backport-5.15/811-v6.4-0002-nvmem-core-introduce-NVMEM-layouts.patch @@ -0,0 +1,387 @@ +From 266570f496b90dea8fda893c2cf7c28d63ae2bd9 Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Tue, 4 Apr 2023 18:21:21 +0100 +Subject: [PATCH] nvmem: core: introduce NVMEM layouts + +NVMEM layouts are used to generate NVMEM cells during runtime. Think of +an EEPROM with a well-defined conent. For now, the content can be +described by a device tree or a board file. But this only works if the +offsets and lengths are static and don't change. One could also argue +that putting the layout of the EEPROM in the device tree is the wrong +place. Instead, the device tree should just have a specific compatible +string. + +Right now there are two use cases: + (1) The NVMEM cell needs special processing. E.g. if it only specifies + a base MAC address offset and you need to add an offset, or it + needs to parse a MAC from ASCII format or some proprietary format. + (Post processing of cells is added in a later commit). + (2) u-boot environment parsing. The cells don't have a particular + offset but it needs parsing the content to determine the offsets + and length. + +Co-developed-by: Miquel Raynal +Signed-off-by: Miquel Raynal +Signed-off-by: Michael Walle +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-14-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/driver-api/nvmem.rst | 15 ++++ + drivers/nvmem/Kconfig | 4 + + drivers/nvmem/Makefile | 1 + + drivers/nvmem/core.c | 120 +++++++++++++++++++++++++++++ + drivers/nvmem/layouts/Kconfig | 5 ++ + drivers/nvmem/layouts/Makefile | 4 + + include/linux/nvmem-consumer.h | 7 ++ + include/linux/nvmem-provider.h | 51 ++++++++++++ + 8 files changed, 207 insertions(+) + create mode 100644 drivers/nvmem/layouts/Kconfig + create mode 100644 drivers/nvmem/layouts/Makefile + +--- a/Documentation/driver-api/nvmem.rst ++++ b/Documentation/driver-api/nvmem.rst +@@ -189,3 +189,18 @@ ex:: + ===================== + + See Documentation/devicetree/bindings/nvmem/nvmem.txt ++ ++8. NVMEM layouts ++================ ++ ++NVMEM layouts are yet another mechanism to create cells. With the device ++tree binding it is possible to specify simple cells by using an offset ++and a length. Sometimes, the cells doesn't have a static offset, but ++the content is still well defined, e.g. tag-length-values. In this case, ++the NVMEM device content has to be first parsed and the cells need to ++be added accordingly. Layouts let you read the content of the NVMEM device ++and let you add cells dynamically. ++ ++Another use case for layouts is the post processing of cells. With layouts, ++it is possible to associate a custom post processing hook to a cell. It ++even possible to add this hook to cells not created by the layout itself. +--- a/drivers/nvmem/Kconfig ++++ b/drivers/nvmem/Kconfig +@@ -21,6 +21,10 @@ config NVMEM_SYSFS + This interface is mostly used by userspace applications to + read/write directly into nvmem. + ++# Layouts ++ ++source "drivers/nvmem/layouts/Kconfig" ++ + # Devices + + config NVMEM_APPLE_EFUSES +--- a/drivers/nvmem/Makefile ++++ b/drivers/nvmem/Makefile +@@ -5,6 +5,7 @@ + + obj-$(CONFIG_NVMEM) += nvmem_core.o + nvmem_core-y := core.o ++obj-y += layouts/ + + # Devices + obj-$(CONFIG_NVMEM_APPLE_EFUSES) += nvmem-apple-efuses.o +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -40,6 +40,7 @@ struct nvmem_device { + nvmem_reg_write_t reg_write; + nvmem_cell_post_process_t cell_post_process; + struct gpio_desc *wp_gpio; ++ struct nvmem_layout *layout; + void *priv; + }; + +@@ -74,6 +75,9 @@ static LIST_HEAD(nvmem_lookup_list); + + static BLOCKING_NOTIFIER_HEAD(nvmem_notifier); + ++static DEFINE_SPINLOCK(nvmem_layout_lock); ++static LIST_HEAD(nvmem_layouts); ++ + static int __nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset, + void *val, size_t bytes) + { +@@ -728,6 +732,101 @@ static int nvmem_add_cells_from_of(struc + return 0; + } + ++int __nvmem_layout_register(struct nvmem_layout *layout, struct module *owner) ++{ ++ layout->owner = owner; ++ ++ spin_lock(&nvmem_layout_lock); ++ list_add(&layout->node, &nvmem_layouts); ++ spin_unlock(&nvmem_layout_lock); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(__nvmem_layout_register); ++ ++void nvmem_layout_unregister(struct nvmem_layout *layout) ++{ ++ spin_lock(&nvmem_layout_lock); ++ list_del(&layout->node); ++ spin_unlock(&nvmem_layout_lock); ++} ++EXPORT_SYMBOL_GPL(nvmem_layout_unregister); ++ ++static struct nvmem_layout *nvmem_layout_get(struct nvmem_device *nvmem) ++{ ++ struct device_node *layout_np, *np = nvmem->dev.of_node; ++ struct nvmem_layout *l, *layout = NULL; ++ ++ layout_np = of_get_child_by_name(np, "nvmem-layout"); ++ if (!layout_np) ++ return NULL; ++ ++ spin_lock(&nvmem_layout_lock); ++ ++ list_for_each_entry(l, &nvmem_layouts, node) { ++ if (of_match_node(l->of_match_table, layout_np)) { ++ if (try_module_get(l->owner)) ++ layout = l; ++ ++ break; ++ } ++ } ++ ++ spin_unlock(&nvmem_layout_lock); ++ of_node_put(layout_np); ++ ++ return layout; ++} ++ ++static void nvmem_layout_put(struct nvmem_layout *layout) ++{ ++ if (layout) ++ module_put(layout->owner); ++} ++ ++static int nvmem_add_cells_from_layout(struct nvmem_device *nvmem) ++{ ++ struct nvmem_layout *layout = nvmem->layout; ++ int ret; ++ ++ if (layout && layout->add_cells) { ++ ret = layout->add_cells(&nvmem->dev, nvmem, layout); ++ if (ret) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++#if IS_ENABLED(CONFIG_OF) ++/** ++ * of_nvmem_layout_get_container() - Get OF node to layout container. ++ * ++ * @nvmem: nvmem device. ++ * ++ * Return: a node pointer with refcount incremented or NULL if no ++ * container exists. Use of_node_put() on it when done. ++ */ ++struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem) ++{ ++ return of_get_child_by_name(nvmem->dev.of_node, "nvmem-layout"); ++} ++EXPORT_SYMBOL_GPL(of_nvmem_layout_get_container); ++#endif ++ ++const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem, ++ struct nvmem_layout *layout) ++{ ++ struct device_node __maybe_unused *layout_np; ++ const struct of_device_id *match; ++ ++ layout_np = of_nvmem_layout_get_container(nvmem); ++ match = of_match_node(layout->of_match_table, layout_np); ++ ++ return match ? match->data : NULL; ++} ++EXPORT_SYMBOL_GPL(nvmem_layout_get_match_data); ++ + /** + * nvmem_register() - Register a nvmem device for given nvmem_config. + * Also creates a binary entry in /sys/bus/nvmem/devices/dev-name/nvmem +@@ -834,6 +933,12 @@ struct nvmem_device *nvmem_register(cons + goto err_put_device; + } + ++ /* ++ * If the driver supplied a layout by config->layout, the module ++ * pointer will be NULL and nvmem_layout_put() will be a noop. ++ */ ++ nvmem->layout = config->layout ?: nvmem_layout_get(nvmem); ++ + if (config->cells) { + rval = nvmem_add_cells(nvmem, config->cells, config->ncells); + if (rval) +@@ -854,12 +959,17 @@ struct nvmem_device *nvmem_register(cons + if (rval) + goto err_remove_cells; + ++ rval = nvmem_add_cells_from_layout(nvmem); ++ if (rval) ++ goto err_remove_cells; ++ + blocking_notifier_call_chain(&nvmem_notifier, NVMEM_ADD, nvmem); + + return nvmem; + + err_remove_cells: + nvmem_device_remove_all_cells(nvmem); ++ nvmem_layout_put(nvmem->layout); + if (config->compat) + nvmem_sysfs_remove_compat(nvmem, config); + err_put_device: +@@ -881,6 +991,7 @@ static void nvmem_device_release(struct + device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom); + + nvmem_device_remove_all_cells(nvmem); ++ nvmem_layout_put(nvmem->layout); + device_unregister(&nvmem->dev); + } + +@@ -1246,6 +1357,15 @@ struct nvmem_cell *of_nvmem_cell_get(str + return ERR_PTR(-EINVAL); + } + ++ /* nvmem layouts produce cells within the nvmem-layout container */ ++ if (of_node_name_eq(nvmem_np, "nvmem-layout")) { ++ nvmem_np = of_get_next_parent(nvmem_np); ++ if (!nvmem_np) { ++ of_node_put(cell_np); ++ return ERR_PTR(-EINVAL); ++ } ++ } ++ + nvmem = __nvmem_device_get(nvmem_np, device_match_of_node); + of_node_put(nvmem_np); + if (IS_ERR(nvmem)) { +--- /dev/null ++++ b/drivers/nvmem/layouts/Kconfig +@@ -0,0 +1,5 @@ ++# SPDX-License-Identifier: GPL-2.0 ++ ++menu "Layout Types" ++ ++endmenu +--- /dev/null ++++ b/drivers/nvmem/layouts/Makefile +@@ -0,0 +1,4 @@ ++# SPDX-License-Identifier: GPL-2.0 ++# ++# Makefile for nvmem layouts. ++# +--- a/include/linux/nvmem-consumer.h ++++ b/include/linux/nvmem-consumer.h +@@ -239,6 +239,7 @@ struct nvmem_cell *of_nvmem_cell_get(str + const char *id); + struct nvmem_device *of_nvmem_device_get(struct device_node *np, + const char *name); ++struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem); + #else + static inline struct nvmem_cell *of_nvmem_cell_get(struct device_node *np, + const char *id) +@@ -251,6 +252,12 @@ static inline struct nvmem_device *of_nv + { + return ERR_PTR(-EOPNOTSUPP); + } ++ ++static inline struct device_node * ++of_nvmem_layout_get_container(struct nvmem_device *nvmem) ++{ ++ return ERR_PTR(-EOPNOTSUPP); ++} + #endif /* CONFIG_NVMEM && CONFIG_OF */ + + #endif /* ifndef _LINUX_NVMEM_CONSUMER_H */ +--- a/include/linux/nvmem-provider.h ++++ b/include/linux/nvmem-provider.h +@@ -88,6 +88,7 @@ struct nvmem_cell_info { + * @stride: Minimum read/write access stride. + * @priv: User context passed to read/write callbacks. + * @ignore_wp: Write Protect pin is managed by the provider. ++ * @layout: Fixed layout associated with this nvmem device. + * + * Note: A default "nvmem" name will be assigned to the device if + * no name is specified in its configuration. In such case "" is +@@ -109,6 +110,7 @@ struct nvmem_config { + bool read_only; + bool root_only; + bool ignore_wp; ++ struct nvmem_layout *layout; + struct device_node *of_node; + bool no_of_node; + nvmem_reg_read_t reg_read; +@@ -142,6 +144,33 @@ struct nvmem_cell_table { + struct list_head node; + }; + ++/** ++ * struct nvmem_layout - NVMEM layout definitions ++ * ++ * @name: Layout name. ++ * @of_match_table: Open firmware match table. ++ * @add_cells: Will be called if a nvmem device is found which ++ * has this layout. The function will add layout ++ * specific cells with nvmem_add_one_cell(). ++ * @owner: Pointer to struct module. ++ * @node: List node. ++ * ++ * A nvmem device can hold a well defined structure which can just be ++ * evaluated during runtime. For example a TLV list, or a list of "name=val" ++ * pairs. A nvmem layout can parse the nvmem device and add appropriate ++ * cells. ++ */ ++struct nvmem_layout { ++ const char *name; ++ const struct of_device_id *of_match_table; ++ int (*add_cells)(struct device *dev, struct nvmem_device *nvmem, ++ struct nvmem_layout *layout); ++ ++ /* private */ ++ struct module *owner; ++ struct list_head node; ++}; ++ + #if IS_ENABLED(CONFIG_NVMEM) + + struct nvmem_device *nvmem_register(const struct nvmem_config *cfg); +@@ -156,6 +185,14 @@ void nvmem_del_cell_table(struct nvmem_c + int nvmem_add_one_cell(struct nvmem_device *nvmem, + const struct nvmem_cell_info *info); + ++int __nvmem_layout_register(struct nvmem_layout *layout, struct module *owner); ++#define nvmem_layout_register(layout) \ ++ __nvmem_layout_register(layout, THIS_MODULE) ++void nvmem_layout_unregister(struct nvmem_layout *layout); ++ ++const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem, ++ struct nvmem_layout *layout); ++ + #else + + static inline struct nvmem_device *nvmem_register(const struct nvmem_config *c) +@@ -179,5 +216,19 @@ static inline int nvmem_add_one_cell(str + return -EOPNOTSUPP; + } + ++static inline int nvmem_layout_register(struct nvmem_layout *layout) ++{ ++ return -EOPNOTSUPP; ++} ++ ++static inline void nvmem_layout_unregister(struct nvmem_layout *layout) {} ++ ++static inline const void * ++nvmem_layout_get_match_data(struct nvmem_device *nvmem, ++ struct nvmem_layout *layout) ++{ ++ return NULL; ++} ++ + #endif /* CONFIG_NVMEM */ + #endif /* ifndef _LINUX_NVMEM_PROVIDER_H */ diff --git a/target/linux/generic/backport-5.15/811-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch b/target/linux/generic/backport-5.15/811-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch new file mode 100644 index 00000000000..6fa7b6382d8 --- /dev/null +++ b/target/linux/generic/backport-5.15/811-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch @@ -0,0 +1,61 @@ +From 6468a6f45148fb5e95c86b4efebf63f9abcd2137 Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:22 +0100 +Subject: [PATCH] nvmem: core: handle the absence of expected layouts + +Make nvmem_layout_get() return -EPROBE_DEFER while the expected layout +is not available. This condition cannot be triggered today as nvmem +layout drivers are initialed as part of an early init call, but soon +these drivers will be converted into modules and be initialized with a +standard priority, so the unavailability of the drivers might become a +reality that must be taken care of. + +Let's anticipate this by telling the caller the layout might not yet be +available. A probe deferral is requested in this case. + +Please note this does not affect any nvmem device not using layouts, +because an early check against the "nvmem-layout" container presence +will return NULL in this case. + +Signed-off-by: Miquel Raynal +Tested-by: Michael Walle +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-15-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -755,7 +755,7 @@ EXPORT_SYMBOL_GPL(nvmem_layout_unregiste + static struct nvmem_layout *nvmem_layout_get(struct nvmem_device *nvmem) + { + struct device_node *layout_np, *np = nvmem->dev.of_node; +- struct nvmem_layout *l, *layout = NULL; ++ struct nvmem_layout *l, *layout = ERR_PTR(-EPROBE_DEFER); + + layout_np = of_get_child_by_name(np, "nvmem-layout"); + if (!layout_np) +@@ -938,6 +938,13 @@ struct nvmem_device *nvmem_register(cons + * pointer will be NULL and nvmem_layout_put() will be a noop. + */ + nvmem->layout = config->layout ?: nvmem_layout_get(nvmem); ++ if (IS_ERR(nvmem->layout)) { ++ rval = PTR_ERR(nvmem->layout); ++ nvmem->layout = NULL; ++ ++ if (rval == -EPROBE_DEFER) ++ goto err_teardown_compat; ++ } + + if (config->cells) { + rval = nvmem_add_cells(nvmem, config->cells, config->ncells); +@@ -970,6 +977,7 @@ struct nvmem_device *nvmem_register(cons + err_remove_cells: + nvmem_device_remove_all_cells(nvmem); + nvmem_layout_put(nvmem->layout); ++err_teardown_compat: + if (config->compat) + nvmem_sysfs_remove_compat(nvmem, config); + err_put_device: diff --git a/target/linux/generic/backport-5.15/811-v6.4-0004-nvmem-core-request-layout-modules-loading.patch b/target/linux/generic/backport-5.15/811-v6.4-0004-nvmem-core-request-layout-modules-loading.patch new file mode 100644 index 00000000000..b9341666f91 --- /dev/null +++ b/target/linux/generic/backport-5.15/811-v6.4-0004-nvmem-core-request-layout-modules-loading.patch @@ -0,0 +1,52 @@ +From b1c37bec1ccfe5ccab72bc0ddc0dfa45c43e2de2 Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:23 +0100 +Subject: [PATCH] nvmem: core: request layout modules loading + +When a storage device like an eeprom or an mtd device probes, it +registers an nvmem device if the nvmem subsystem has been enabled (bool +symbol). During nvmem registration, if the device is using layouts to +expose dynamic nvmem cells, the core will first try to get a reference +over the layout driver callbacks. In practice there is not relationship +that can be described between the storage driver and the nvmem +layout. So there is no way we can enforce both drivers will be built-in +or both will be modules. If the storage device driver is built-in but +the layout is built as a module, instead of badly failing with an +endless probe deferral loop, lets just make a modprobe call in case the +driver was made available in an initramfs with +of_device_node_request_module(), and offer a fully functional system to +the user. + +Signed-off-by: Miquel Raynal +Tested-by: Michael Walle +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-16-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -17,6 +17,7 @@ + #include + #include + #include ++#include + #include + + struct nvmem_device { +@@ -761,6 +762,13 @@ static struct nvmem_layout *nvmem_layout + if (!layout_np) + return NULL; + ++ /* ++ * In case the nvmem device was built-in while the layout was built as a ++ * module, we shall manually request the layout driver loading otherwise ++ * we'll never have any match. ++ */ ++ of_request_module(layout_np); ++ + spin_lock(&nvmem_layout_lock); + + list_for_each_entry(l, &nvmem_layouts, node) { diff --git a/target/linux/generic/backport-5.15/811-v6.4-0005-nvmem-core-add-per-cell-post-processing.patch b/target/linux/generic/backport-5.15/811-v6.4-0005-nvmem-core-add-per-cell-post-processing.patch new file mode 100644 index 00000000000..53628cd4e4f --- /dev/null +++ b/target/linux/generic/backport-5.15/811-v6.4-0005-nvmem-core-add-per-cell-post-processing.patch @@ -0,0 +1,86 @@ +From 345ec382cd4b736c36e01f155d08c913b225b736 Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Tue, 4 Apr 2023 18:21:24 +0100 +Subject: [PATCH] nvmem: core: add per-cell post processing + +Instead of relying on the name the consumer is using for the cell, like +it is done for the nvmem .cell_post_process configuration parameter, +provide a per-cell post processing hook. This can then be populated by +the NVMEM provider (or the NVMEM layout) when adding the cell. + +Signed-off-by: Michael Walle +Signed-off-by: Miquel Raynal +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-17-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 17 +++++++++++++++++ + include/linux/nvmem-provider.h | 3 +++ + 2 files changed, 20 insertions(+) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -54,6 +54,7 @@ struct nvmem_cell_entry { + int bytes; + int bit_offset; + int nbits; ++ nvmem_cell_post_process_t read_post_process; + struct device_node *np; + struct nvmem_device *nvmem; + struct list_head node; +@@ -470,6 +471,7 @@ static int nvmem_cell_info_to_nvmem_cell + cell->offset = info->offset; + cell->bytes = info->bytes; + cell->name = info->name; ++ cell->read_post_process = info->read_post_process; + + cell->bit_offset = info->bit_offset; + cell->nbits = info->nbits; +@@ -1563,6 +1565,13 @@ static int __nvmem_cell_read(struct nvme + if (cell->bit_offset || cell->nbits) + nvmem_shift_read_buffer_in_place(cell, buf); + ++ if (cell->read_post_process) { ++ rc = cell->read_post_process(nvmem->priv, id, index, ++ cell->offset, buf, cell->bytes); ++ if (rc) ++ return rc; ++ } ++ + if (nvmem->cell_post_process) { + rc = nvmem->cell_post_process(nvmem->priv, id, index, + cell->offset, buf, cell->bytes); +@@ -1671,6 +1680,14 @@ static int __nvmem_cell_entry_write(stru + (cell->bit_offset == 0 && len != cell->bytes)) + return -EINVAL; + ++ /* ++ * Any cells which have a read_post_process hook are read-only because ++ * we cannot reverse the operation and it might affect other cells, ++ * too. ++ */ ++ if (cell->read_post_process) ++ return -EINVAL; ++ + if (cell->bit_offset || cell->nbits) { + buf = nvmem_cell_prepare_write_buffer(cell, buf, len); + if (IS_ERR(buf)) +--- a/include/linux/nvmem-provider.h ++++ b/include/linux/nvmem-provider.h +@@ -54,6 +54,8 @@ struct nvmem_keepout { + * @bit_offset: Bit offset if cell is smaller than a byte. + * @nbits: Number of bits. + * @np: Optional device_node pointer. ++ * @read_post_process: Callback for optional post processing of cell data ++ * on reads. + */ + struct nvmem_cell_info { + const char *name; +@@ -62,6 +64,7 @@ struct nvmem_cell_info { + unsigned int bit_offset; + unsigned int nbits; + struct device_node *np; ++ nvmem_cell_post_process_t read_post_process; + }; + + /** diff --git a/target/linux/generic/backport-5.15/811-v6.4-0006-nvmem-core-allow-to-modify-a-cell-before-adding-it.patch b/target/linux/generic/backport-5.15/811-v6.4-0006-nvmem-core-allow-to-modify-a-cell-before-adding-it.patch new file mode 100644 index 00000000000..32990148c80 --- /dev/null +++ b/target/linux/generic/backport-5.15/811-v6.4-0006-nvmem-core-allow-to-modify-a-cell-before-adding-it.patch @@ -0,0 +1,59 @@ +From de12c9691501ccba41a154c223869f82be4c12fd Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Tue, 4 Apr 2023 18:21:25 +0100 +Subject: [PATCH] nvmem: core: allow to modify a cell before adding it + +Provide a way to modify a cell before it will get added. This is useful +to attach a custom post processing hook via a layout. + +Signed-off-by: Michael Walle +Signed-off-by: Miquel Raynal +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-18-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 4 ++++ + include/linux/nvmem-provider.h | 5 +++++ + 2 files changed, 9 insertions(+) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -695,6 +695,7 @@ static int nvmem_validate_keepouts(struc + + static int nvmem_add_cells_from_of(struct nvmem_device *nvmem) + { ++ struct nvmem_layout *layout = nvmem->layout; + struct device *dev = &nvmem->dev; + struct device_node *child; + const __be32 *addr; +@@ -724,6 +725,9 @@ static int nvmem_add_cells_from_of(struc + + info.np = of_node_get(child); + ++ if (layout && layout->fixup_cell_info) ++ layout->fixup_cell_info(nvmem, layout, &info); ++ + ret = nvmem_add_one_cell(nvmem, &info); + kfree(info.name); + if (ret) { +--- a/include/linux/nvmem-provider.h ++++ b/include/linux/nvmem-provider.h +@@ -155,6 +155,8 @@ struct nvmem_cell_table { + * @add_cells: Will be called if a nvmem device is found which + * has this layout. The function will add layout + * specific cells with nvmem_add_one_cell(). ++ * @fixup_cell_info: Will be called before a cell is added. Can be ++ * used to modify the nvmem_cell_info. + * @owner: Pointer to struct module. + * @node: List node. + * +@@ -168,6 +170,9 @@ struct nvmem_layout { + const struct of_device_id *of_match_table; + int (*add_cells)(struct device *dev, struct nvmem_device *nvmem, + struct nvmem_layout *layout); ++ void (*fixup_cell_info)(struct nvmem_device *nvmem, ++ struct nvmem_layout *layout, ++ struct nvmem_cell_info *cell); + + /* private */ + struct module *owner; diff --git a/target/linux/generic/backport-5.15/811-v6.4-0007-nvmem-imx-ocotp-replace-global-post-processing-with-.patch b/target/linux/generic/backport-5.15/811-v6.4-0007-nvmem-imx-ocotp-replace-global-post-processing-with-.patch new file mode 100644 index 00000000000..2a5fa618ea6 --- /dev/null +++ b/target/linux/generic/backport-5.15/811-v6.4-0007-nvmem-imx-ocotp-replace-global-post-processing-with-.patch @@ -0,0 +1,81 @@ +From 6c56a82d7895a213a43182a5d01a21a906a79847 Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Tue, 4 Apr 2023 18:21:26 +0100 +Subject: [PATCH] nvmem: imx-ocotp: replace global post processing with layouts + +In preparation of retiring the global post processing hook change this +driver to use layouts. The layout will be supplied during registration +and will be used to add the post processing hook to all added cells. + +Signed-off-by: Michael Walle +Tested-by: Michael Walle # on kontron-pitx-imx8m +Signed-off-by: Miquel Raynal +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-19-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/imx-ocotp.c | 30 +++++++++++++++++++----------- + 1 file changed, 19 insertions(+), 11 deletions(-) + +--- a/drivers/nvmem/imx-ocotp.c ++++ b/drivers/nvmem/imx-ocotp.c +@@ -225,18 +225,13 @@ read_end: + static int imx_ocotp_cell_pp(void *context, const char *id, int index, + unsigned int offset, void *data, size_t bytes) + { +- struct ocotp_priv *priv = context; ++ u8 *buf = data; ++ int i; + + /* Deal with some post processing of nvmem cell data */ +- if (id && !strcmp(id, "mac-address")) { +- if (priv->params->reverse_mac_address) { +- u8 *buf = data; +- int i; +- +- for (i = 0; i < bytes/2; i++) +- swap(buf[i], buf[bytes - i - 1]); +- } +- } ++ if (id && !strcmp(id, "mac-address")) ++ for (i = 0; i < bytes / 2; i++) ++ swap(buf[i], buf[bytes - i - 1]); + + return 0; + } +@@ -488,7 +483,6 @@ static struct nvmem_config imx_ocotp_nvm + .stride = 1, + .reg_read = imx_ocotp_read, + .reg_write = imx_ocotp_write, +- .cell_post_process = imx_ocotp_cell_pp, + }; + + static const struct ocotp_params imx6q_params = { +@@ -595,6 +589,17 @@ static const struct of_device_id imx_oco + }; + MODULE_DEVICE_TABLE(of, imx_ocotp_dt_ids); + ++static void imx_ocotp_fixup_cell_info(struct nvmem_device *nvmem, ++ struct nvmem_layout *layout, ++ struct nvmem_cell_info *cell) ++{ ++ cell->read_post_process = imx_ocotp_cell_pp; ++} ++ ++struct nvmem_layout imx_ocotp_layout = { ++ .fixup_cell_info = imx_ocotp_fixup_cell_info, ++}; ++ + static int imx_ocotp_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +@@ -619,6 +624,9 @@ static int imx_ocotp_probe(struct platfo + imx_ocotp_nvmem_config.size = 4 * priv->params->nregs; + imx_ocotp_nvmem_config.dev = dev; + imx_ocotp_nvmem_config.priv = priv; ++ if (priv->params->reverse_mac_address) ++ imx_ocotp_nvmem_config.layout = &imx_ocotp_layout; ++ + priv->config = &imx_ocotp_nvmem_config; + + clk_prepare_enable(priv->clk); diff --git a/target/linux/generic/backport-5.15/811-v6.4-0008-nvmem-cell-drop-global-cell_post_process.patch b/target/linux/generic/backport-5.15/811-v6.4-0008-nvmem-cell-drop-global-cell_post_process.patch new file mode 100644 index 00000000000..eac202b8829 --- /dev/null +++ b/target/linux/generic/backport-5.15/811-v6.4-0008-nvmem-cell-drop-global-cell_post_process.patch @@ -0,0 +1,68 @@ +From 011e40a166fdaa65fb9946b7cd91efec85b70dbb Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Tue, 4 Apr 2023 18:21:27 +0100 +Subject: [PATCH] nvmem: cell: drop global cell_post_process + +There are no users anymore for the global cell_post_process callback +anymore. New users should use proper nvmem layouts. + +Signed-off-by: Michael Walle +Signed-off-by: Miquel Raynal +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-20-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 9 --------- + include/linux/nvmem-provider.h | 2 -- + 2 files changed, 11 deletions(-) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -39,7 +39,6 @@ struct nvmem_device { + unsigned int nkeepout; + nvmem_reg_read_t reg_read; + nvmem_reg_write_t reg_write; +- nvmem_cell_post_process_t cell_post_process; + struct gpio_desc *wp_gpio; + struct nvmem_layout *layout; + void *priv; +@@ -903,7 +902,6 @@ struct nvmem_device *nvmem_register(cons + nvmem->type = config->type; + nvmem->reg_read = config->reg_read; + nvmem->reg_write = config->reg_write; +- nvmem->cell_post_process = config->cell_post_process; + nvmem->keepout = config->keepout; + nvmem->nkeepout = config->nkeepout; + if (config->of_node) +@@ -1575,13 +1573,6 @@ static int __nvmem_cell_read(struct nvme + if (rc) + return rc; + } +- +- if (nvmem->cell_post_process) { +- rc = nvmem->cell_post_process(nvmem->priv, id, index, +- cell->offset, buf, cell->bytes); +- if (rc) +- return rc; +- } + + if (len) + *len = cell->bytes; +--- a/include/linux/nvmem-provider.h ++++ b/include/linux/nvmem-provider.h +@@ -85,7 +85,6 @@ struct nvmem_cell_info { + * @no_of_node: Device should not use the parent's of_node even if it's !NULL. + * @reg_read: Callback to read data. + * @reg_write: Callback to write data. +- * @cell_post_process: Callback for vendor specific post processing of cell data + * @size: Device size. + * @word_size: Minimum read/write access granularity. + * @stride: Minimum read/write access stride. +@@ -118,7 +117,6 @@ struct nvmem_config { + bool no_of_node; + nvmem_reg_read_t reg_read; + nvmem_reg_write_t reg_write; +- nvmem_cell_post_process_t cell_post_process; + int size; + int word_size; + int stride; diff --git a/target/linux/generic/backport-5.15/811-v6.4-0009-nvmem-core-provide-own-priv-pointer-in-post-process-.patch b/target/linux/generic/backport-5.15/811-v6.4-0009-nvmem-core-provide-own-priv-pointer-in-post-process-.patch new file mode 100644 index 00000000000..46b30a2ed90 --- /dev/null +++ b/target/linux/generic/backport-5.15/811-v6.4-0009-nvmem-core-provide-own-priv-pointer-in-post-process-.patch @@ -0,0 +1,76 @@ +From 8a134fd9f9323f4c39ec27055b3d3723cfb5c1e9 Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Tue, 4 Apr 2023 18:21:28 +0100 +Subject: [PATCH] nvmem: core: provide own priv pointer in post process + callback + +It doesn't make any more sense to have a opaque pointer set up by the +nvmem device. Usually, the layout isn't associated with a particular +nvmem device. Instead, let the caller who set the post process callback +provide the priv pointer. + +Signed-off-by: Michael Walle +Signed-off-by: Miquel Raynal +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-21-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 4 +++- + include/linux/nvmem-provider.h | 5 ++++- + 2 files changed, 7 insertions(+), 2 deletions(-) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -54,6 +54,7 @@ struct nvmem_cell_entry { + int bit_offset; + int nbits; + nvmem_cell_post_process_t read_post_process; ++ void *priv; + struct device_node *np; + struct nvmem_device *nvmem; + struct list_head node; +@@ -471,6 +472,7 @@ static int nvmem_cell_info_to_nvmem_cell + cell->bytes = info->bytes; + cell->name = info->name; + cell->read_post_process = info->read_post_process; ++ cell->priv = info->priv; + + cell->bit_offset = info->bit_offset; + cell->nbits = info->nbits; +@@ -1568,7 +1570,7 @@ static int __nvmem_cell_read(struct nvme + nvmem_shift_read_buffer_in_place(cell, buf); + + if (cell->read_post_process) { +- rc = cell->read_post_process(nvmem->priv, id, index, ++ rc = cell->read_post_process(cell->priv, id, index, + cell->offset, buf, cell->bytes); + if (rc) + return rc; +--- a/include/linux/nvmem-provider.h ++++ b/include/linux/nvmem-provider.h +@@ -20,7 +20,8 @@ typedef int (*nvmem_reg_write_t)(void *p + void *val, size_t bytes); + /* used for vendor specific post processing of cell data */ + typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, int index, +- unsigned int offset, void *buf, size_t bytes); ++ unsigned int offset, void *buf, ++ size_t bytes); + + enum nvmem_type { + NVMEM_TYPE_UNKNOWN = 0, +@@ -56,6 +57,7 @@ struct nvmem_keepout { + * @np: Optional device_node pointer. + * @read_post_process: Callback for optional post processing of cell data + * on reads. ++ * @priv: Opaque data passed to the read_post_process hook. + */ + struct nvmem_cell_info { + const char *name; +@@ -65,6 +67,7 @@ struct nvmem_cell_info { + unsigned int nbits; + struct device_node *np; + nvmem_cell_post_process_t read_post_process; ++ void *priv; + }; + + /** diff --git a/target/linux/generic/backport-5.15/811-v6.4-0010-nvmem-layouts-sl28vpd-Add-new-layout-driver.patch b/target/linux/generic/backport-5.15/811-v6.4-0010-nvmem-layouts-sl28vpd-Add-new-layout-driver.patch new file mode 100644 index 00000000000..7d97658b60e --- /dev/null +++ b/target/linux/generic/backport-5.15/811-v6.4-0010-nvmem-layouts-sl28vpd-Add-new-layout-driver.patch @@ -0,0 +1,215 @@ +From d9fae023fe86069750092fc1c2f3a73e2fb18512 Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Tue, 4 Apr 2023 18:21:29 +0100 +Subject: [PATCH] nvmem: layouts: sl28vpd: Add new layout driver + +This layout applies to the VPD of the Kontron sl28 boards. The VPD only +contains a base MAC address. Therefore, we have to add an individual +offset to it. This is done by taking the second argument of the nvmem +phandle into account. Also this let us checking the VPD version and the +checksum. + +Signed-off-by: Michael Walle +Signed-off-by: Miquel Raynal +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-22-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/layouts/Kconfig | 9 ++ + drivers/nvmem/layouts/Makefile | 2 + + drivers/nvmem/layouts/sl28vpd.c | 165 ++++++++++++++++++++++++++++++++ + 3 files changed, 176 insertions(+) + create mode 100644 drivers/nvmem/layouts/sl28vpd.c + +--- a/drivers/nvmem/layouts/Kconfig ++++ b/drivers/nvmem/layouts/Kconfig +@@ -2,4 +2,13 @@ + + menu "Layout Types" + ++config NVMEM_LAYOUT_SL28_VPD ++ tristate "Kontron sl28 VPD layout support" ++ select CRC8 ++ help ++ Say Y here if you want to support the VPD layout of the Kontron ++ SMARC-sAL28 boards. ++ ++ If unsure, say N. ++ + endmenu +--- a/drivers/nvmem/layouts/Makefile ++++ b/drivers/nvmem/layouts/Makefile +@@ -2,3 +2,5 @@ + # + # Makefile for nvmem layouts. + # ++ ++obj-$(CONFIG_NVMEM_LAYOUT_SL28_VPD) += sl28vpd.o +--- /dev/null ++++ b/drivers/nvmem/layouts/sl28vpd.c +@@ -0,0 +1,165 @@ ++// SPDX-License-Identifier: GPL-2.0 ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define SL28VPD_MAGIC 'V' ++ ++struct sl28vpd_header { ++ u8 magic; ++ u8 version; ++} __packed; ++ ++struct sl28vpd_v1 { ++ struct sl28vpd_header header; ++ char serial_number[15]; ++ u8 base_mac_address[ETH_ALEN]; ++ u8 crc8; ++} __packed; ++ ++static int sl28vpd_mac_address_pp(void *priv, const char *id, int index, ++ unsigned int offset, void *buf, ++ size_t bytes) ++{ ++ if (bytes != ETH_ALEN) ++ return -EINVAL; ++ ++ if (index < 0) ++ return -EINVAL; ++ ++ if (!is_valid_ether_addr(buf)) ++ return -EINVAL; ++ ++ eth_addr_add(buf, index); ++ ++ return 0; ++} ++ ++static const struct nvmem_cell_info sl28vpd_v1_entries[] = { ++ { ++ .name = "serial-number", ++ .offset = offsetof(struct sl28vpd_v1, serial_number), ++ .bytes = sizeof_field(struct sl28vpd_v1, serial_number), ++ }, ++ { ++ .name = "base-mac-address", ++ .offset = offsetof(struct sl28vpd_v1, base_mac_address), ++ .bytes = sizeof_field(struct sl28vpd_v1, base_mac_address), ++ .read_post_process = sl28vpd_mac_address_pp, ++ }, ++}; ++ ++static int sl28vpd_v1_check_crc(struct device *dev, struct nvmem_device *nvmem) ++{ ++ struct sl28vpd_v1 data_v1; ++ u8 table[CRC8_TABLE_SIZE]; ++ int ret; ++ u8 crc; ++ ++ crc8_populate_msb(table, 0x07); ++ ++ ret = nvmem_device_read(nvmem, 0, sizeof(data_v1), &data_v1); ++ if (ret < 0) ++ return ret; ++ else if (ret != sizeof(data_v1)) ++ return -EIO; ++ ++ crc = crc8(table, (void *)&data_v1, sizeof(data_v1) - 1, 0); ++ ++ if (crc != data_v1.crc8) { ++ dev_err(dev, ++ "Checksum is invalid (got %02x, expected %02x).\n", ++ crc, data_v1.crc8); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int sl28vpd_add_cells(struct device *dev, struct nvmem_device *nvmem, ++ struct nvmem_layout *layout) ++{ ++ const struct nvmem_cell_info *pinfo; ++ struct nvmem_cell_info info = {0}; ++ struct device_node *layout_np; ++ struct sl28vpd_header hdr; ++ int ret, i; ++ ++ /* check header */ ++ ret = nvmem_device_read(nvmem, 0, sizeof(hdr), &hdr); ++ if (ret < 0) ++ return ret; ++ else if (ret != sizeof(hdr)) ++ return -EIO; ++ ++ if (hdr.magic != SL28VPD_MAGIC) { ++ dev_err(dev, "Invalid magic value (%02x)\n", hdr.magic); ++ return -EINVAL; ++ } ++ ++ if (hdr.version != 1) { ++ dev_err(dev, "Version %d is unsupported.\n", hdr.version); ++ return -EINVAL; ++ } ++ ++ ret = sl28vpd_v1_check_crc(dev, nvmem); ++ if (ret) ++ return ret; ++ ++ layout_np = of_nvmem_layout_get_container(nvmem); ++ if (!layout_np) ++ return -ENOENT; ++ ++ for (i = 0; i < ARRAY_SIZE(sl28vpd_v1_entries); i++) { ++ pinfo = &sl28vpd_v1_entries[i]; ++ ++ info.name = pinfo->name; ++ info.offset = pinfo->offset; ++ info.bytes = pinfo->bytes; ++ info.read_post_process = pinfo->read_post_process; ++ info.np = of_get_child_by_name(layout_np, pinfo->name); ++ ++ ret = nvmem_add_one_cell(nvmem, &info); ++ if (ret) { ++ of_node_put(layout_np); ++ return ret; ++ } ++ } ++ ++ of_node_put(layout_np); ++ ++ return 0; ++} ++ ++static const struct of_device_id sl28vpd_of_match_table[] = { ++ { .compatible = "kontron,sl28-vpd" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, sl28vpd_of_match_table); ++ ++struct nvmem_layout sl28vpd_layout = { ++ .name = "sl28-vpd", ++ .of_match_table = sl28vpd_of_match_table, ++ .add_cells = sl28vpd_add_cells, ++}; ++ ++static int __init sl28vpd_init(void) ++{ ++ return nvmem_layout_register(&sl28vpd_layout); ++} ++ ++static void __exit sl28vpd_exit(void) ++{ ++ nvmem_layout_unregister(&sl28vpd_layout); ++} ++ ++module_init(sl28vpd_init); ++module_exit(sl28vpd_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Michael Walle "); ++MODULE_DESCRIPTION("NVMEM layout driver for the VPD of Kontron sl28 boards"); diff --git a/target/linux/generic/backport-5.15/811-v6.4-0011-nvmem-layouts-onie-tlv-Add-new-layout-driver.patch b/target/linux/generic/backport-5.15/811-v6.4-0011-nvmem-layouts-onie-tlv-Add-new-layout-driver.patch new file mode 100644 index 00000000000..ca8b4bc0691 --- /dev/null +++ b/target/linux/generic/backport-5.15/811-v6.4-0011-nvmem-layouts-onie-tlv-Add-new-layout-driver.patch @@ -0,0 +1,306 @@ +From d3c0d12f6474216bf386101e2449cc73e5c5b61d Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:31 +0100 +Subject: [PATCH] nvmem: layouts: onie-tlv: Add new layout driver + +This layout applies on top of any non volatile storage device containing +an ONIE table factory flashed. This table follows the tlv +(type-length-value) organization described in the link below. We cannot +afford using regular parsers because the content of these tables is +manufacturer specific and must be dynamically discovered. + +Link: https://opencomputeproject.github.io/onie/design-spec/hw_requirements.html +Signed-off-by: Miquel Raynal +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-24-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/layouts/Kconfig | 9 ++ + drivers/nvmem/layouts/Makefile | 1 + + drivers/nvmem/layouts/onie-tlv.c | 257 +++++++++++++++++++++++++++++++ + 3 files changed, 267 insertions(+) + create mode 100644 drivers/nvmem/layouts/onie-tlv.c + +--- a/drivers/nvmem/layouts/Kconfig ++++ b/drivers/nvmem/layouts/Kconfig +@@ -11,4 +11,13 @@ config NVMEM_LAYOUT_SL28_VPD + + If unsure, say N. + ++config NVMEM_LAYOUT_ONIE_TLV ++ tristate "ONIE tlv support" ++ select CRC32 ++ help ++ Say Y here if you want to support the Open Compute Project ONIE ++ Type-Length-Value standard table. ++ ++ If unsure, say N. ++ + endmenu +--- a/drivers/nvmem/layouts/Makefile ++++ b/drivers/nvmem/layouts/Makefile +@@ -4,3 +4,4 @@ + # + + obj-$(CONFIG_NVMEM_LAYOUT_SL28_VPD) += sl28vpd.o ++obj-$(CONFIG_NVMEM_LAYOUT_ONIE_TLV) += onie-tlv.o +--- /dev/null ++++ b/drivers/nvmem/layouts/onie-tlv.c +@@ -0,0 +1,257 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * ONIE tlv NVMEM cells provider ++ * ++ * Copyright (C) 2022 Open Compute Group ONIE ++ * Author: Miquel Raynal ++ * Based on the nvmem driver written by: Vadym Kochan ++ * Inspired by the first layout written by: Rafał Miłecki ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define ONIE_TLV_MAX_LEN 2048 ++#define ONIE_TLV_CRC_FIELD_SZ 6 ++#define ONIE_TLV_CRC_SZ 4 ++#define ONIE_TLV_HDR_ID "TlvInfo" ++ ++struct onie_tlv_hdr { ++ u8 id[8]; ++ u8 version; ++ __be16 data_len; ++} __packed; ++ ++struct onie_tlv { ++ u8 type; ++ u8 len; ++} __packed; ++ ++static const char *onie_tlv_cell_name(u8 type) ++{ ++ switch (type) { ++ case 0x21: ++ return "product-name"; ++ case 0x22: ++ return "part-number"; ++ case 0x23: ++ return "serial-number"; ++ case 0x24: ++ return "mac-address"; ++ case 0x25: ++ return "manufacture-date"; ++ case 0x26: ++ return "device-version"; ++ case 0x27: ++ return "label-revision"; ++ case 0x28: ++ return "platform-name"; ++ case 0x29: ++ return "onie-version"; ++ case 0x2A: ++ return "num-macs"; ++ case 0x2B: ++ return "manufacturer"; ++ case 0x2C: ++ return "country-code"; ++ case 0x2D: ++ return "vendor"; ++ case 0x2E: ++ return "diag-version"; ++ case 0x2F: ++ return "service-tag"; ++ case 0xFD: ++ return "vendor-extension"; ++ case 0xFE: ++ return "crc32"; ++ default: ++ break; ++ } ++ ++ return NULL; ++} ++ ++static int onie_tlv_mac_read_cb(void *priv, const char *id, int index, ++ unsigned int offset, void *buf, ++ size_t bytes) ++{ ++ eth_addr_add(buf, index); ++ ++ return 0; ++} ++ ++static nvmem_cell_post_process_t onie_tlv_read_cb(u8 type, u8 *buf) ++{ ++ switch (type) { ++ case 0x24: ++ return &onie_tlv_mac_read_cb; ++ default: ++ break; ++ } ++ ++ return NULL; ++} ++ ++static int onie_tlv_add_cells(struct device *dev, struct nvmem_device *nvmem, ++ size_t data_len, u8 *data) ++{ ++ struct nvmem_cell_info cell = {}; ++ struct device_node *layout; ++ struct onie_tlv tlv; ++ unsigned int hdr_len = sizeof(struct onie_tlv_hdr); ++ unsigned int offset = 0; ++ int ret; ++ ++ layout = of_nvmem_layout_get_container(nvmem); ++ if (!layout) ++ return -ENOENT; ++ ++ while (offset < data_len) { ++ memcpy(&tlv, data + offset, sizeof(tlv)); ++ if (offset + tlv.len >= data_len) { ++ dev_err(dev, "Out of bounds field (0x%x bytes at 0x%x)\n", ++ tlv.len, hdr_len + offset); ++ break; ++ } ++ ++ cell.name = onie_tlv_cell_name(tlv.type); ++ if (!cell.name) ++ continue; ++ ++ cell.offset = hdr_len + offset + sizeof(tlv.type) + sizeof(tlv.len); ++ cell.bytes = tlv.len; ++ cell.np = of_get_child_by_name(layout, cell.name); ++ cell.read_post_process = onie_tlv_read_cb(tlv.type, data + offset + sizeof(tlv)); ++ ++ ret = nvmem_add_one_cell(nvmem, &cell); ++ if (ret) { ++ of_node_put(layout); ++ return ret; ++ } ++ ++ offset += sizeof(tlv) + tlv.len; ++ } ++ ++ of_node_put(layout); ++ ++ return 0; ++} ++ ++static bool onie_tlv_hdr_is_valid(struct device *dev, struct onie_tlv_hdr *hdr) ++{ ++ if (memcmp(hdr->id, ONIE_TLV_HDR_ID, sizeof(hdr->id))) { ++ dev_err(dev, "Invalid header\n"); ++ return false; ++ } ++ ++ if (hdr->version != 0x1) { ++ dev_err(dev, "Invalid version number\n"); ++ return false; ++ } ++ ++ return true; ++} ++ ++static bool onie_tlv_crc_is_valid(struct device *dev, size_t table_len, u8 *table) ++{ ++ struct onie_tlv crc_hdr; ++ u32 read_crc, calc_crc; ++ __be32 crc_be; ++ ++ memcpy(&crc_hdr, table + table_len - ONIE_TLV_CRC_FIELD_SZ, sizeof(crc_hdr)); ++ if (crc_hdr.type != 0xfe || crc_hdr.len != ONIE_TLV_CRC_SZ) { ++ dev_err(dev, "Invalid CRC field\n"); ++ return false; ++ } ++ ++ /* The table contains a JAMCRC, which is XOR'ed compared to the original ++ * CRC32 implementation as known in the Ethernet world. ++ */ ++ memcpy(&crc_be, table + table_len - ONIE_TLV_CRC_SZ, ONIE_TLV_CRC_SZ); ++ read_crc = be32_to_cpu(crc_be); ++ calc_crc = crc32(~0, table, table_len - ONIE_TLV_CRC_SZ) ^ 0xFFFFFFFF; ++ if (read_crc != calc_crc) { ++ dev_err(dev, "Invalid CRC read: 0x%08x, expected: 0x%08x\n", ++ read_crc, calc_crc); ++ return false; ++ } ++ ++ return true; ++} ++ ++static int onie_tlv_parse_table(struct device *dev, struct nvmem_device *nvmem, ++ struct nvmem_layout *layout) ++{ ++ struct onie_tlv_hdr hdr; ++ size_t table_len, data_len, hdr_len; ++ u8 *table, *data; ++ int ret; ++ ++ ret = nvmem_device_read(nvmem, 0, sizeof(hdr), &hdr); ++ if (ret < 0) ++ return ret; ++ ++ if (!onie_tlv_hdr_is_valid(dev, &hdr)) { ++ dev_err(dev, "Invalid ONIE TLV header\n"); ++ return -EINVAL; ++ } ++ ++ hdr_len = sizeof(hdr.id) + sizeof(hdr.version) + sizeof(hdr.data_len); ++ data_len = be16_to_cpu(hdr.data_len); ++ table_len = hdr_len + data_len; ++ if (table_len > ONIE_TLV_MAX_LEN) { ++ dev_err(dev, "Invalid ONIE TLV data length\n"); ++ return -EINVAL; ++ } ++ ++ table = devm_kmalloc(dev, table_len, GFP_KERNEL); ++ if (!table) ++ return -ENOMEM; ++ ++ ret = nvmem_device_read(nvmem, 0, table_len, table); ++ if (ret != table_len) ++ return ret; ++ ++ if (!onie_tlv_crc_is_valid(dev, table_len, table)) ++ return -EINVAL; ++ ++ data = table + hdr_len; ++ ret = onie_tlv_add_cells(dev, nvmem, data_len, data); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static const struct of_device_id onie_tlv_of_match_table[] = { ++ { .compatible = "onie,tlv-layout", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, onie_tlv_of_match_table); ++ ++static struct nvmem_layout onie_tlv_layout = { ++ .name = "ONIE tlv layout", ++ .of_match_table = onie_tlv_of_match_table, ++ .add_cells = onie_tlv_parse_table, ++}; ++ ++static int __init onie_tlv_init(void) ++{ ++ return nvmem_layout_register(&onie_tlv_layout); ++} ++ ++static void __exit onie_tlv_exit(void) ++{ ++ nvmem_layout_unregister(&onie_tlv_layout); ++} ++ ++module_init(onie_tlv_init); ++module_exit(onie_tlv_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Miquel Raynal "); ++MODULE_DESCRIPTION("NVMEM layout driver for Onie TLV table parsing"); ++MODULE_ALIAS("NVMEM layout driver for Onie TLV table parsing"); diff --git a/target/linux/generic/backport-5.15/811-v6.4-0012-nvmem-stm32-romem-mark-OF-related-data-as-maybe-unus.patch b/target/linux/generic/backport-5.15/811-v6.4-0012-nvmem-stm32-romem-mark-OF-related-data-as-maybe-unus.patch new file mode 100644 index 00000000000..94a0911d73c --- /dev/null +++ b/target/linux/generic/backport-5.15/811-v6.4-0012-nvmem-stm32-romem-mark-OF-related-data-as-maybe-unus.patch @@ -0,0 +1,32 @@ +From a4fb434ef96ace5af758ca2c52c3a3f8f3abc87c Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +Date: Tue, 4 Apr 2023 18:21:34 +0100 +Subject: [PATCH] nvmem: stm32-romem: mark OF related data as maybe unused +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The driver can be compile tested with !CONFIG_OF making certain data +unused: + + drivers/nvmem/stm32-romem.c:271:34: error: ‘stm32_romem_of_match’ defined but not used [-Werror=unused-const-variable=] + +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-27-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/stm32-romem.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/nvmem/stm32-romem.c ++++ b/drivers/nvmem/stm32-romem.c +@@ -268,7 +268,7 @@ static const struct stm32_romem_cfg stm3 + .ta = true, + }; + +-static const struct of_device_id stm32_romem_of_match[] = { ++static const struct of_device_id stm32_romem_of_match[] __maybe_unused = { + { .compatible = "st,stm32f4-otp", }, { + .compatible = "st,stm32mp15-bsec", + .data = (void *)&stm32mp15_bsec_cfg, diff --git a/target/linux/generic/backport-5.15/811-v6.4-0013-nvmem-mtk-efuse-Support-postprocessing-for-GPU-speed.patch b/target/linux/generic/backport-5.15/811-v6.4-0013-nvmem-mtk-efuse-Support-postprocessing-for-GPU-speed.patch new file mode 100644 index 00000000000..abda402bddb --- /dev/null +++ b/target/linux/generic/backport-5.15/811-v6.4-0013-nvmem-mtk-efuse-Support-postprocessing-for-GPU-speed.patch @@ -0,0 +1,120 @@ +From de6e05097f7db066afb0ad4c88b730949f7b7749 Mon Sep 17 00:00:00 2001 +From: AngeloGioacchino Del Regno +Date: Tue, 4 Apr 2023 18:21:35 +0100 +Subject: [PATCH] nvmem: mtk-efuse: Support postprocessing for GPU speed + binning data + +On some MediaTek SoCs GPU speed binning data is available for read +in the SoC's eFuse array but it has a format that is incompatible +with what the OPP API expects, as we read a number from 0 to 7 but +opp-supported-hw is expecting a bitmask to enable an OPP entry: +being what we read limited to 0-7, it's straightforward to simply +convert the value to BIT(value) as a post-processing action. + +So, introduce post-processing support and enable it by evaluating +the newly introduced platform data's `uses_post_processing` member, +currently enabled only for MT8186. + +Signed-off-by: AngeloGioacchino Del Regno +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-28-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/mtk-efuse.c | 53 +++++++++++++++++++++++++++++++++++++-- + 1 file changed, 51 insertions(+), 2 deletions(-) + +--- a/drivers/nvmem/mtk-efuse.c ++++ b/drivers/nvmem/mtk-efuse.c +@@ -10,6 +10,11 @@ + #include + #include + #include ++#include ++ ++struct mtk_efuse_pdata { ++ bool uses_post_processing; ++}; + + struct mtk_efuse_priv { + void __iomem *base; +@@ -29,6 +34,37 @@ static int mtk_reg_read(void *context, + return 0; + } + ++static int mtk_efuse_gpu_speedbin_pp(void *context, const char *id, int index, ++ unsigned int offset, void *data, size_t bytes) ++{ ++ u8 *val = data; ++ ++ if (val[0] < 8) ++ val[0] = BIT(val[0]); ++ ++ return 0; ++} ++ ++static void mtk_efuse_fixup_cell_info(struct nvmem_device *nvmem, ++ struct nvmem_layout *layout, ++ struct nvmem_cell_info *cell) ++{ ++ size_t sz = strlen(cell->name); ++ ++ /* ++ * On some SoCs, the GPU speedbin is not read as bitmask but as ++ * a number with range [0-7] (max 3 bits): post process to use ++ * it in OPP tables to describe supported-hw. ++ */ ++ if (cell->nbits <= 3 && ++ strncmp(cell->name, "gpu-speedbin", min(sz, strlen("gpu-speedbin"))) == 0) ++ cell->read_post_process = mtk_efuse_gpu_speedbin_pp; ++} ++ ++static struct nvmem_layout mtk_efuse_layout = { ++ .fixup_cell_info = mtk_efuse_fixup_cell_info, ++}; ++ + static int mtk_efuse_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +@@ -36,6 +72,7 @@ static int mtk_efuse_probe(struct platfo + struct nvmem_device *nvmem; + struct nvmem_config econfig = {}; + struct mtk_efuse_priv *priv; ++ const struct mtk_efuse_pdata *pdata; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) +@@ -45,20 +82,32 @@ static int mtk_efuse_probe(struct platfo + if (IS_ERR(priv->base)) + return PTR_ERR(priv->base); + ++ pdata = device_get_match_data(dev); + econfig.stride = 1; + econfig.word_size = 1; + econfig.reg_read = mtk_reg_read; + econfig.size = resource_size(res); + econfig.priv = priv; + econfig.dev = dev; ++ if (pdata->uses_post_processing) ++ econfig.layout = &mtk_efuse_layout; + nvmem = devm_nvmem_register(dev, &econfig); + + return PTR_ERR_OR_ZERO(nvmem); + } + ++static const struct mtk_efuse_pdata mtk_mt8186_efuse_pdata = { ++ .uses_post_processing = true, ++}; ++ ++static const struct mtk_efuse_pdata mtk_efuse_pdata = { ++ .uses_post_processing = false, ++}; ++ + static const struct of_device_id mtk_efuse_of_match[] = { +- { .compatible = "mediatek,mt8173-efuse",}, +- { .compatible = "mediatek,efuse",}, ++ { .compatible = "mediatek,mt8173-efuse", .data = &mtk_efuse_pdata }, ++ { .compatible = "mediatek,mt8186-efuse", .data = &mtk_mt8186_efuse_pdata }, ++ { .compatible = "mediatek,efuse", .data = &mtk_efuse_pdata }, + {/* sentinel */}, + }; + MODULE_DEVICE_TABLE(of, mtk_efuse_of_match); diff --git a/target/linux/generic/backport-5.15/811-v6.4-0014-nvmem-bcm-ocotp-Use-devm_platform_ioremap_resource.patch b/target/linux/generic/backport-5.15/811-v6.4-0014-nvmem-bcm-ocotp-Use-devm_platform_ioremap_resource.patch new file mode 100644 index 00000000000..a0874f73d15 --- /dev/null +++ b/target/linux/generic/backport-5.15/811-v6.4-0014-nvmem-bcm-ocotp-Use-devm_platform_ioremap_resource.patch @@ -0,0 +1,39 @@ +From 1dc552fa33cf98af3e784dbc0500da93cae3b24a Mon Sep 17 00:00:00 2001 +From: Yang Li +Date: Tue, 4 Apr 2023 18:21:38 +0100 +Subject: [PATCH] nvmem: bcm-ocotp: Use devm_platform_ioremap_resource() + +According to commit 7945f929f1a7 ("drivers: provide +devm_platform_ioremap_resource()"), convert platform_get_resource(), +devm_ioremap_resource() to a single call to use +devm_platform_ioremap_resource(), as this is exactly what this function +does. + +Signed-off-by: Yang Li +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-31-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/bcm-ocotp.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/drivers/nvmem/bcm-ocotp.c ++++ b/drivers/nvmem/bcm-ocotp.c +@@ -254,7 +254,6 @@ MODULE_DEVICE_TABLE(acpi, bcm_otpc_acpi_ + static int bcm_otpc_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +- struct resource *res; + struct otpc_priv *priv; + struct nvmem_device *nvmem; + int err; +@@ -269,8 +268,7 @@ static int bcm_otpc_probe(struct platfor + return -ENODEV; + + /* Get OTP base address register. */ +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- priv->base = devm_ioremap_resource(dev, res); ++ priv->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(priv->base)) { + dev_err(dev, "unable to map I/O memory\n"); + return PTR_ERR(priv->base); diff --git a/target/linux/generic/backport-5.15/811-v6.4-0015-nvmem-nintendo-otp-Use-devm_platform_ioremap_resourc.patch b/target/linux/generic/backport-5.15/811-v6.4-0015-nvmem-nintendo-otp-Use-devm_platform_ioremap_resourc.patch new file mode 100644 index 00000000000..890dacd08db --- /dev/null +++ b/target/linux/generic/backport-5.15/811-v6.4-0015-nvmem-nintendo-otp-Use-devm_platform_ioremap_resourc.patch @@ -0,0 +1,39 @@ +From 649409990d2e93fac657be7c6960c28a2c601d65 Mon Sep 17 00:00:00 2001 +From: Yang Li +Date: Tue, 4 Apr 2023 18:21:39 +0100 +Subject: [PATCH] nvmem: nintendo-otp: Use devm_platform_ioremap_resource() + +According to commit 7945f929f1a7 ("drivers: provide +devm_platform_ioremap_resource()"), convert platform_get_resource(), +devm_ioremap_resource() to a single call to use +devm_platform_ioremap_resource(), as this is exactly what this function +does. + +Signed-off-by: Yang Li +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-32-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/nintendo-otp.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/drivers/nvmem/nintendo-otp.c ++++ b/drivers/nvmem/nintendo-otp.c +@@ -76,7 +76,6 @@ static int nintendo_otp_probe(struct pla + struct device *dev = &pdev->dev; + const struct of_device_id *of_id = + of_match_device(nintendo_otp_of_table, dev); +- struct resource *res; + struct nvmem_device *nvmem; + struct nintendo_otp_priv *priv; + +@@ -92,8 +91,7 @@ static int nintendo_otp_probe(struct pla + if (!priv) + return -ENOMEM; + +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- priv->regs = devm_ioremap_resource(dev, res); ++ priv->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(priv->regs)) + return PTR_ERR(priv->regs); + diff --git a/target/linux/generic/backport-5.15/811-v6.4-0016-nvmem-vf610-ocotp-Use-devm_platform_get_and_ioremap_.patch b/target/linux/generic/backport-5.15/811-v6.4-0016-nvmem-vf610-ocotp-Use-devm_platform_get_and_ioremap_.patch new file mode 100644 index 00000000000..3f5d3c1ad4c --- /dev/null +++ b/target/linux/generic/backport-5.15/811-v6.4-0016-nvmem-vf610-ocotp-Use-devm_platform_get_and_ioremap_.patch @@ -0,0 +1,32 @@ +From c2367aa60d5e34d48582362c6de34b4131d92be7 Mon Sep 17 00:00:00 2001 +From: Yang Li +Date: Tue, 4 Apr 2023 18:21:40 +0100 +Subject: [PATCH] nvmem: vf610-ocotp: Use + devm_platform_get_and_ioremap_resource() + +According to commit 890cc39a8799 ("drivers: provide +devm_platform_get_and_ioremap_resource()"), convert +platform_get_resource(), devm_ioremap_resource() to a single +call to devm_platform_get_and_ioremap_resource(), as this is exactly +what this function does. + +Signed-off-by: Yang Li +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-33-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/vf610-ocotp.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/nvmem/vf610-ocotp.c ++++ b/drivers/nvmem/vf610-ocotp.c +@@ -219,8 +219,7 @@ static int vf610_ocotp_probe(struct plat + if (!ocotp_dev) + return -ENOMEM; + +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- ocotp_dev->base = devm_ioremap_resource(dev, res); ++ ocotp_dev->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); + if (IS_ERR(ocotp_dev->base)) + return PTR_ERR(ocotp_dev->base); + diff --git a/target/linux/generic/backport-5.15/811-v6.4-0017-nvmem-core-support-specifying-both-cell-raw-data-pos.patch b/target/linux/generic/backport-5.15/811-v6.4-0017-nvmem-core-support-specifying-both-cell-raw-data-pos.patch new file mode 100644 index 00000000000..eeb407e9bb6 --- /dev/null +++ b/target/linux/generic/backport-5.15/811-v6.4-0017-nvmem-core-support-specifying-both-cell-raw-data-pos.patch @@ -0,0 +1,115 @@ +From 55d4980ce55b6bb4be66877de4dbec513911b988 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 4 Apr 2023 18:21:42 +0100 +Subject: [PATCH] nvmem: core: support specifying both: cell raw data & post + read lengths +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Callback .read_post_process() is designed to modify raw cell content +before providing it to the consumer. So far we were dealing with +modifications that didn't affect cell size (length). In some cases +however cell content needs to be reformatted and resized. + +It's required e.g. to provide properly formatted MAC address in case +it's stored in a non-binary format (e.g. using ASCII). + +There were few discussions how to optimally handle that. Following +possible solutions were considered: +1. Allow .read_post_process() to realloc (resize) content buffer +2. Allow .read_post_process() to adjust (decrease) just buffer length +3. Register NVMEM cells using post-read sizes + +The preferred solution was the last one. The problem is that simply +adjusting "bytes" in NVMEM providers would result in core code NOT +passing whole raw data to .read_post_process() callbacks. It means +callback functions couldn't do their job without somehow manually +reading original cell content on their own. + +This patch deals with that by registering NVMEM cells with both lengths: +raw content one and post read one. It allows: +1. Core code to read whole raw cell content +2. Callbacks to return content they want + +Signed-off-by: Rafał Miłecki +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-35-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 11 +++++++---- + include/linux/nvmem-provider.h | 2 ++ + 2 files changed, 9 insertions(+), 4 deletions(-) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -50,6 +50,7 @@ struct nvmem_device { + struct nvmem_cell_entry { + const char *name; + int offset; ++ size_t raw_len; + int bytes; + int bit_offset; + int nbits; +@@ -469,6 +470,7 @@ static int nvmem_cell_info_to_nvmem_cell + { + cell->nvmem = nvmem; + cell->offset = info->offset; ++ cell->raw_len = info->raw_len ?: info->bytes; + cell->bytes = info->bytes; + cell->name = info->name; + cell->read_post_process = info->read_post_process; +@@ -1560,7 +1562,7 @@ static int __nvmem_cell_read(struct nvme + { + int rc; + +- rc = nvmem_reg_read(nvmem, cell->offset, buf, cell->bytes); ++ rc = nvmem_reg_read(nvmem, cell->offset, buf, cell->raw_len); + + if (rc) + return rc; +@@ -1571,7 +1573,7 @@ static int __nvmem_cell_read(struct nvme + + if (cell->read_post_process) { + rc = cell->read_post_process(cell->priv, id, index, +- cell->offset, buf, cell->bytes); ++ cell->offset, buf, cell->raw_len); + if (rc) + return rc; + } +@@ -1594,14 +1596,15 @@ static int __nvmem_cell_read(struct nvme + */ + void *nvmem_cell_read(struct nvmem_cell *cell, size_t *len) + { +- struct nvmem_device *nvmem = cell->entry->nvmem; ++ struct nvmem_cell_entry *entry = cell->entry; ++ struct nvmem_device *nvmem = entry->nvmem; + u8 *buf; + int rc; + + if (!nvmem) + return ERR_PTR(-EINVAL); + +- buf = kzalloc(cell->entry->bytes, GFP_KERNEL); ++ buf = kzalloc(max_t(size_t, entry->raw_len, entry->bytes), GFP_KERNEL); + if (!buf) + return ERR_PTR(-ENOMEM); + +--- a/include/linux/nvmem-provider.h ++++ b/include/linux/nvmem-provider.h +@@ -51,6 +51,7 @@ struct nvmem_keepout { + * struct nvmem_cell_info - NVMEM cell description + * @name: Name. + * @offset: Offset within the NVMEM device. ++ * @raw_len: Length of raw data (without post processing). + * @bytes: Length of the cell. + * @bit_offset: Bit offset if cell is smaller than a byte. + * @nbits: Number of bits. +@@ -62,6 +63,7 @@ struct nvmem_keepout { + struct nvmem_cell_info { + const char *name; + unsigned int offset; ++ size_t raw_len; + unsigned int bytes; + unsigned int bit_offset; + unsigned int nbits; diff --git a/target/linux/generic/backport-5.15/811-v6.4-0019-nvmem-Add-macro-to-register-nvmem-layout-drivers.patch b/target/linux/generic/backport-5.15/811-v6.4-0019-nvmem-Add-macro-to-register-nvmem-layout-drivers.patch new file mode 100644 index 00000000000..7c6fe22b5f3 --- /dev/null +++ b/target/linux/generic/backport-5.15/811-v6.4-0019-nvmem-Add-macro-to-register-nvmem-layout-drivers.patch @@ -0,0 +1,42 @@ +From 814c978f02db17f16e6aa2efa2a929372f06da09 Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:44 +0100 +Subject: [PATCH] nvmem: Add macro to register nvmem layout drivers +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Provide a module_nvmem_layout_driver() macro at the end of the +nvmem-provider.h header to reduce the boilerplate when registering nvmem +layout drivers. + +Suggested-by: Srinivas Kandagatla +Signed-off-by: Miquel Raynal +Acked-by: Rafał Miłecki +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-37-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/nvmem-provider.h | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/include/linux/nvmem-provider.h ++++ b/include/linux/nvmem-provider.h +@@ -9,6 +9,7 @@ + #ifndef _LINUX_NVMEM_PROVIDER_H + #define _LINUX_NVMEM_PROVIDER_H + ++#include + #include + #include + #include +@@ -242,4 +243,9 @@ nvmem_layout_get_match_data(struct nvmem + } + + #endif /* CONFIG_NVMEM */ ++ ++#define module_nvmem_layout_driver(__layout_driver) \ ++ module_driver(__layout_driver, nvmem_layout_register, \ ++ nvmem_layout_unregister) ++ + #endif /* ifndef _LINUX_NVMEM_PROVIDER_H */ diff --git a/target/linux/generic/backport-5.15/811-v6.4-0020-nvmem-layouts-sl28vpd-Use-module_nvmem_layout_driver.patch b/target/linux/generic/backport-5.15/811-v6.4-0020-nvmem-layouts-sl28vpd-Use-module_nvmem_layout_driver.patch new file mode 100644 index 00000000000..06646dd68bf --- /dev/null +++ b/target/linux/generic/backport-5.15/811-v6.4-0020-nvmem-layouts-sl28vpd-Use-module_nvmem_layout_driver.patch @@ -0,0 +1,39 @@ +From 0abdf99fe0c86252ba274703425f8d543d7e7f0d Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:45 +0100 +Subject: [PATCH] nvmem: layouts: sl28vpd: Use module_nvmem_layout_driver() + +Stop open-coding the module init/exit functions. Use the +module_nvmem_layout_driver() instead. + +Signed-off-by: Miquel Raynal +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-38-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/layouts/sl28vpd.c | 14 +------------- + 1 file changed, 1 insertion(+), 13 deletions(-) + +--- a/drivers/nvmem/layouts/sl28vpd.c ++++ b/drivers/nvmem/layouts/sl28vpd.c +@@ -146,19 +146,7 @@ struct nvmem_layout sl28vpd_layout = { + .of_match_table = sl28vpd_of_match_table, + .add_cells = sl28vpd_add_cells, + }; +- +-static int __init sl28vpd_init(void) +-{ +- return nvmem_layout_register(&sl28vpd_layout); +-} +- +-static void __exit sl28vpd_exit(void) +-{ +- nvmem_layout_unregister(&sl28vpd_layout); +-} +- +-module_init(sl28vpd_init); +-module_exit(sl28vpd_exit); ++module_nvmem_layout_driver(sl28vpd_layout); + + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("Michael Walle "); diff --git a/target/linux/generic/backport-5.15/811-v6.4-0021-nvmem-layouts-onie-tlv-Use-module_nvmem_layout_drive.patch b/target/linux/generic/backport-5.15/811-v6.4-0021-nvmem-layouts-onie-tlv-Use-module_nvmem_layout_drive.patch new file mode 100644 index 00000000000..826f4378c2f --- /dev/null +++ b/target/linux/generic/backport-5.15/811-v6.4-0021-nvmem-layouts-onie-tlv-Use-module_nvmem_layout_drive.patch @@ -0,0 +1,39 @@ +From d119eb38faab61125aaa4f63c74eef61585cf34c Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:46 +0100 +Subject: [PATCH] nvmem: layouts: onie-tlv: Use module_nvmem_layout_driver() + +Stop open-coding the module init/exit functions. Use the +module_nvmem_layout_driver() instead. + +Signed-off-by: Miquel Raynal +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-39-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/layouts/onie-tlv.c | 14 +------------- + 1 file changed, 1 insertion(+), 13 deletions(-) + +--- a/drivers/nvmem/layouts/onie-tlv.c ++++ b/drivers/nvmem/layouts/onie-tlv.c +@@ -237,19 +237,7 @@ static struct nvmem_layout onie_tlv_layo + .of_match_table = onie_tlv_of_match_table, + .add_cells = onie_tlv_parse_table, + }; +- +-static int __init onie_tlv_init(void) +-{ +- return nvmem_layout_register(&onie_tlv_layout); +-} +- +-static void __exit onie_tlv_exit(void) +-{ +- nvmem_layout_unregister(&onie_tlv_layout); +-} +- +-module_init(onie_tlv_init); +-module_exit(onie_tlv_exit); ++module_nvmem_layout_driver(onie_tlv_layout); + + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("Miquel Raynal "); diff --git a/target/linux/generic/backport-5.15/811-v6.4-0022-nvmem-layouts-onie-tlv-Drop-wrong-module-alias.patch b/target/linux/generic/backport-5.15/811-v6.4-0022-nvmem-layouts-onie-tlv-Drop-wrong-module-alias.patch new file mode 100644 index 00000000000..f20db85ceb6 --- /dev/null +++ b/target/linux/generic/backport-5.15/811-v6.4-0022-nvmem-layouts-onie-tlv-Drop-wrong-module-alias.patch @@ -0,0 +1,24 @@ +From 6b13e4b6a9a45028ac730e550380077df1845912 Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:47 +0100 +Subject: [PATCH] nvmem: layouts: onie-tlv: Drop wrong module alias + +The MODULE_ALIAS macro is misused here as it carries the +description. There is currently no relevant alias to provide so let's +just drop it. + +Signed-off-by: Miquel Raynal +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-40-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/layouts/onie-tlv.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/nvmem/layouts/onie-tlv.c ++++ b/drivers/nvmem/layouts/onie-tlv.c +@@ -242,4 +242,3 @@ module_nvmem_layout_driver(onie_tlv_layo + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("Miquel Raynal "); + MODULE_DESCRIPTION("NVMEM layout driver for Onie TLV table parsing"); +-MODULE_ALIAS("NVMEM layout driver for Onie TLV table parsing"); diff --git a/target/linux/generic/backport-5.15/811-v6.4-0023-nvmem-layouts-sl28vpd-set-varaiable-sl28vpd_layout-s.patch b/target/linux/generic/backport-5.15/811-v6.4-0023-nvmem-layouts-sl28vpd-set-varaiable-sl28vpd_layout-s.patch new file mode 100644 index 00000000000..5cf847b57ae --- /dev/null +++ b/target/linux/generic/backport-5.15/811-v6.4-0023-nvmem-layouts-sl28vpd-set-varaiable-sl28vpd_layout-s.patch @@ -0,0 +1,31 @@ +From a8642cd11635a35a5f1dc31857887900d6610778 Mon Sep 17 00:00:00 2001 +From: Tom Rix +Date: Tue, 4 Apr 2023 18:21:48 +0100 +Subject: [PATCH] nvmem: layouts: sl28vpd: set varaiable sl28vpd_layout + storage-class-specifier to static + +smatch reports +drivers/nvmem/layouts/sl28vpd.c:144:21: warning: symbol + 'sl28vpd_layout' was not declared. Should it be static? + +This variable is only used in one file so it should be static. + +Signed-off-by: Tom Rix +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-41-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/layouts/sl28vpd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/nvmem/layouts/sl28vpd.c ++++ b/drivers/nvmem/layouts/sl28vpd.c +@@ -141,7 +141,7 @@ static const struct of_device_id sl28vpd + }; + MODULE_DEVICE_TABLE(of, sl28vpd_of_match_table); + +-struct nvmem_layout sl28vpd_layout = { ++static struct nvmem_layout sl28vpd_layout = { + .name = "sl28-vpd", + .of_match_table = sl28vpd_of_match_table, + .add_cells = sl28vpd_add_cells, diff --git a/target/linux/generic/config-5.10 b/target/linux/generic/config-5.10 index df93e4d956b..cde0fdb0a04 100644 --- a/target/linux/generic/config-5.10 +++ b/target/linux/generic/config-5.10 @@ -4242,6 +4242,8 @@ CONFIG_NMI_LOG_BUF_SHIFT=13 # CONFIG_NVMEM is not set # CONFIG_NVMEM_BCM_OCOTP is not set # CONFIG_NVMEM_IMX_OCOTP is not set +# CONFIG_NVMEM_LAYOUT_ONIE_TLV is not set +# CONFIG_NVMEM_LAYOUT_SL28_VPD is not set # CONFIG_NVMEM_REBOOT_MODE is not set # CONFIG_NVMEM_RMEM is not set # CONFIG_NVMEM_SYSFS is not set diff --git a/target/linux/generic/config-5.15 b/target/linux/generic/config-5.15 index c9581ba5d4a..a03f65f4d77 100644 --- a/target/linux/generic/config-5.15 +++ b/target/linux/generic/config-5.15 @@ -4442,6 +4442,8 @@ CONFIG_NMI_LOG_BUF_SHIFT=13 # CONFIG_NVMEM is not set # CONFIG_NVMEM_BCM_OCOTP is not set # CONFIG_NVMEM_IMX_OCOTP is not set +# CONFIG_NVMEM_LAYOUT_ONIE_TLV is not set +# CONFIG_NVMEM_LAYOUT_SL28_VPD is not set # CONFIG_NVMEM_REBOOT_MODE is not set # CONFIG_NVMEM_RMEM is not set # CONFIG_NVMEM_SYSFS is not set From 9a62b3977f7c2aa3ff3e25013069dee07c5296d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 6 Apr 2023 12:14:30 +0200 Subject: [PATCH 09/14] kernel: backport NVMEM patch for U-Boot env data "ethaddr" cell MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adjust our local code to avoid breakage. Signed-off-by: Rafał Miłecki --- ...nv-post-process-ethaddr-env-variable.patch | 81 +++++++++++++++++++ ...nv-post-process-ethaddr-env-variable.patch | 81 +++++++++++++++++++ ...env-align-endianness-of-crc32-values.patch | 2 +- ...env-align-endianness-of-crc32-values.patch | 2 +- .../arm64/boot/dts/qcom/ipq8072-wax218.dts | 2 +- .../arm64/boot/dts/qcom/ipq8074-nbg7815.dts | 26 +++--- .../boot/dts/qcom/ipq8074-wxr-5950ax12.dts | 10 +-- 7 files changed, 183 insertions(+), 21 deletions(-) create mode 100644 target/linux/generic/backport-5.10/814-v6.4-0018-nvmem-u-boot-env-post-process-ethaddr-env-variable.patch create mode 100644 target/linux/generic/backport-5.15/811-v6.4-0018-nvmem-u-boot-env-post-process-ethaddr-env-variable.patch diff --git a/target/linux/generic/backport-5.10/814-v6.4-0018-nvmem-u-boot-env-post-process-ethaddr-env-variable.patch b/target/linux/generic/backport-5.10/814-v6.4-0018-nvmem-u-boot-env-post-process-ethaddr-env-variable.patch new file mode 100644 index 00000000000..adde0ffc4b1 --- /dev/null +++ b/target/linux/generic/backport-5.10/814-v6.4-0018-nvmem-u-boot-env-post-process-ethaddr-env-variable.patch @@ -0,0 +1,81 @@ +From c49f1a8af6bcf6d18576bca898f8083ca4b129e1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 4 Apr 2023 18:21:43 +0100 +Subject: [PATCH] nvmem: u-boot-env: post-process "ethaddr" env variable +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +U-Boot environment variables are stored in ASCII format so "ethaddr" +requires parsing into binary to make it work with Ethernet interfaces. + +This includes support for indexes to support #nvmem-cell-cells = <1>. + +Signed-off-by: Rafał Miłecki +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-36-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/Kconfig | 1 + + drivers/nvmem/u-boot-env.c | 26 ++++++++++++++++++++++++++ + 2 files changed, 27 insertions(+) + +--- a/drivers/nvmem/Kconfig ++++ b/drivers/nvmem/Kconfig +@@ -340,6 +340,7 @@ config NVMEM_U_BOOT_ENV + tristate "U-Boot environment variables support" + depends on OF && MTD + select CRC32 ++ select GENERIC_NET_UTILS + help + U-Boot stores its setup as environment variables. This driver adds + support for verifying & exporting such data. It also exposes variables +--- a/drivers/nvmem/u-boot-env.c ++++ b/drivers/nvmem/u-boot-env.c +@@ -4,6 +4,8 @@ + */ + + #include ++#include ++#include + #include + #include + #include +@@ -70,6 +72,25 @@ static int u_boot_env_read(void *context + return 0; + } + ++static int u_boot_env_read_post_process_ethaddr(void *context, const char *id, int index, ++ unsigned int offset, void *buf, size_t bytes) ++{ ++ u8 mac[ETH_ALEN]; ++ ++ if (bytes != 3 * ETH_ALEN - 1) ++ return -EINVAL; ++ ++ if (!mac_pton(buf, mac)) ++ return -EINVAL; ++ ++ if (index) ++ eth_addr_add(mac, index); ++ ++ ether_addr_copy(buf, mac); ++ ++ return 0; ++} ++ + static int u_boot_env_add_cells(struct u_boot_env *priv, uint8_t *buf, + size_t data_offset, size_t data_len) + { +@@ -101,6 +122,11 @@ static int u_boot_env_add_cells(struct u + priv->cells[idx].offset = data_offset + value - data; + priv->cells[idx].bytes = strlen(value); + priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name); ++ if (!strcmp(var, "ethaddr")) { ++ priv->cells[idx].raw_len = strlen(value); ++ priv->cells[idx].bytes = ETH_ALEN; ++ priv->cells[idx].read_post_process = u_boot_env_read_post_process_ethaddr; ++ } + } + + if (WARN_ON(idx != priv->ncells)) diff --git a/target/linux/generic/backport-5.15/811-v6.4-0018-nvmem-u-boot-env-post-process-ethaddr-env-variable.patch b/target/linux/generic/backport-5.15/811-v6.4-0018-nvmem-u-boot-env-post-process-ethaddr-env-variable.patch new file mode 100644 index 00000000000..adde0ffc4b1 --- /dev/null +++ b/target/linux/generic/backport-5.15/811-v6.4-0018-nvmem-u-boot-env-post-process-ethaddr-env-variable.patch @@ -0,0 +1,81 @@ +From c49f1a8af6bcf6d18576bca898f8083ca4b129e1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 4 Apr 2023 18:21:43 +0100 +Subject: [PATCH] nvmem: u-boot-env: post-process "ethaddr" env variable +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +U-Boot environment variables are stored in ASCII format so "ethaddr" +requires parsing into binary to make it work with Ethernet interfaces. + +This includes support for indexes to support #nvmem-cell-cells = <1>. + +Signed-off-by: Rafał Miłecki +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-36-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/Kconfig | 1 + + drivers/nvmem/u-boot-env.c | 26 ++++++++++++++++++++++++++ + 2 files changed, 27 insertions(+) + +--- a/drivers/nvmem/Kconfig ++++ b/drivers/nvmem/Kconfig +@@ -340,6 +340,7 @@ config NVMEM_U_BOOT_ENV + tristate "U-Boot environment variables support" + depends on OF && MTD + select CRC32 ++ select GENERIC_NET_UTILS + help + U-Boot stores its setup as environment variables. This driver adds + support for verifying & exporting such data. It also exposes variables +--- a/drivers/nvmem/u-boot-env.c ++++ b/drivers/nvmem/u-boot-env.c +@@ -4,6 +4,8 @@ + */ + + #include ++#include ++#include + #include + #include + #include +@@ -70,6 +72,25 @@ static int u_boot_env_read(void *context + return 0; + } + ++static int u_boot_env_read_post_process_ethaddr(void *context, const char *id, int index, ++ unsigned int offset, void *buf, size_t bytes) ++{ ++ u8 mac[ETH_ALEN]; ++ ++ if (bytes != 3 * ETH_ALEN - 1) ++ return -EINVAL; ++ ++ if (!mac_pton(buf, mac)) ++ return -EINVAL; ++ ++ if (index) ++ eth_addr_add(mac, index); ++ ++ ether_addr_copy(buf, mac); ++ ++ return 0; ++} ++ + static int u_boot_env_add_cells(struct u_boot_env *priv, uint8_t *buf, + size_t data_offset, size_t data_len) + { +@@ -101,6 +122,11 @@ static int u_boot_env_add_cells(struct u + priv->cells[idx].offset = data_offset + value - data; + priv->cells[idx].bytes = strlen(value); + priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name); ++ if (!strcmp(var, "ethaddr")) { ++ priv->cells[idx].raw_len = strlen(value); ++ priv->cells[idx].bytes = ETH_ALEN; ++ priv->cells[idx].read_post_process = u_boot_env_read_post_process_ethaddr; ++ } + } + + if (WARN_ON(idx != priv->ncells)) diff --git a/target/linux/generic/pending-5.10/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch b/target/linux/generic/pending-5.10/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch index 4010232300c..9b111050eef 100644 --- a/target/linux/generic/pending-5.10/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch +++ b/target/linux/generic/pending-5.10/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch @@ -36,7 +36,7 @@ Signed-off-by: Srinivas Kandagatla --- a/drivers/nvmem/u-boot-env.c +++ b/drivers/nvmem/u-boot-env.c -@@ -156,7 +156,7 @@ static int u_boot_env_parse(struct u_boo +@@ -182,7 +182,7 @@ static int u_boot_env_parse(struct u_boo crc32_data_len = priv->mtd->size - crc32_data_offset; data_len = priv->mtd->size - data_offset; diff --git a/target/linux/generic/pending-5.15/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch b/target/linux/generic/pending-5.15/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch index 4010232300c..9b111050eef 100644 --- a/target/linux/generic/pending-5.15/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch +++ b/target/linux/generic/pending-5.15/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch @@ -36,7 +36,7 @@ Signed-off-by: Srinivas Kandagatla --- a/drivers/nvmem/u-boot-env.c +++ b/drivers/nvmem/u-boot-env.c -@@ -156,7 +156,7 @@ static int u_boot_env_parse(struct u_boo +@@ -182,7 +182,7 @@ static int u_boot_env_parse(struct u_boo crc32_data_len = priv->mtd->size - crc32_data_offset; data_len = priv->mtd->size - data_offset; diff --git a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8072-wax218.dts b/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8072-wax218.dts index 786d461e895..5bfcdcc8ca3 100644 --- a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8072-wax218.dts +++ b/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8072-wax218.dts @@ -142,7 +142,7 @@ phy-handle = <&qca8081_28>; label = "lan"; nvmem-cells = <&macaddr_ubootenv_ethaddr>; - nvmem-cell-names = "mac-address-ascii"; + nvmem-cell-names = "mac-address"; }; &qpic_bam { diff --git a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-nbg7815.dts b/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-nbg7815.dts index 537dd52032d..d113b233ecf 100644 --- a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-nbg7815.dts +++ b/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-nbg7815.dts @@ -220,6 +220,7 @@ reg = <0x600000 0x10000>; macaddr_lan: ethaddr { + #nvmem-cell-cells = <1>; }; }; @@ -349,49 +350,48 @@ status = "okay"; phy-handle = <&qca8075_1>; label = "lan1"; - nvmem-cells = <&macaddr_lan>; - nvmem-cell-names = "mac-address-ascii"; + nvmem-cells = <&macaddr_lan 0>; + nvmem-cell-names = "mac-address"; }; &dp2 { status = "okay"; phy-handle = <&qca8075_2>; label = "lan2"; - nvmem-cells = <&macaddr_lan>; - nvmem-cell-names = "mac-address-ascii"; + nvmem-cells = <&macaddr_lan 0>; + nvmem-cell-names = "mac-address"; }; &dp3 { status = "okay"; phy-handle = <&qca8075_3>; label = "lan3"; - nvmem-cells = <&macaddr_lan>; - nvmem-cell-names = "mac-address-ascii"; + nvmem-cells = <&macaddr_lan 0>; + nvmem-cell-names = "mac-address"; }; &dp4 { status = "okay"; phy-handle = <&qca8075_4>; label = "lan4"; - nvmem-cells = <&macaddr_lan>; - nvmem-cell-names = "mac-address-ascii"; + nvmem-cells = <&macaddr_lan 0>; + nvmem-cell-names = "mac-address"; }; &dp5 { status = "okay"; phy-handle = <&qca8081>; label = "wan"; - nvmem-cells = <&macaddr_lan>; - nvmem-cell-names = "mac-address-ascii"; - mac-address-increment = <1>; + nvmem-cells = <&macaddr_lan 1>; + nvmem-cell-names = "mac-address"; }; &dp6_syn { status = "okay"; phy-handle = <&aqr113c>; label = "10g"; - nvmem-cells = <&macaddr_lan>; - nvmem-cell-names = "mac-address-ascii"; + nvmem-cells = <&macaddr_lan 0>; + nvmem-cell-names = "mac-address"; }; &blsp1_i2c2 { diff --git a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-wxr-5950ax12.dts b/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-wxr-5950ax12.dts index d9b083c4d05..32386dc93e0 100644 --- a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-wxr-5950ax12.dts +++ b/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-wxr-5950ax12.dts @@ -320,7 +320,7 @@ phy-handle = <&qca8075_2>; label = "lan4"; nvmem-cells = <&macaddr_appsblenv_ethaddr>; - nvmem-cell-names = "mac-address-ascii"; + nvmem-cell-names = "mac-address"; }; &dp3 { @@ -328,7 +328,7 @@ phy-handle = <&qca8075_3>; label = "lan3"; nvmem-cells = <&macaddr_appsblenv_ethaddr>; - nvmem-cell-names = "mac-address-ascii"; + nvmem-cell-names = "mac-address"; }; &dp4 { @@ -336,7 +336,7 @@ phy-handle = <&qca8075_4>; label = "lan2"; nvmem-cells = <&macaddr_appsblenv_ethaddr>; - nvmem-cell-names = "mac-address-ascii"; + nvmem-cell-names = "mac-address"; }; &dp5_syn { @@ -344,7 +344,7 @@ phy-handle = <&aqr113c_1>; label = "wan"; nvmem-cells = <&macaddr_appsblenv_ethaddr>; - nvmem-cell-names = "mac-address-ascii"; + nvmem-cell-names = "mac-address"; }; &dp6_syn { @@ -352,7 +352,7 @@ phy-handle = <&aqr113c_2>; label = "lan1"; nvmem-cells = <&macaddr_appsblenv_ethaddr>; - nvmem-cell-names = "mac-address-ascii"; + nvmem-cell-names = "mac-address"; }; &ssphy_0 { From c1f39adaf9692b4c01f226458c4b56d69f074481 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Tue, 4 Apr 2023 21:48:42 +0200 Subject: [PATCH 10/14] ath11k-firmware: update to WLAN.HK.2.9.0.1-01385-QCAHKSWPL_SILICONZ-1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Current WLAN.HK.2.5.0.1 FW is quite old and buggy, but we had to hold off from updating to 2.6.0.1 and 2.7.0.1 as they had compatibility regressions, but now QCA finally released 2.9.0.1 FW which is working on all of the boards. So finally update IPQ8074 and QCN9074 FW to the latest WLAN.HK.2.9.0.1-01385-QCAHKSWPL_SILICONZ-1 firmware. In order to do so, we have to switch to using QCA-s QUIC repo instead of Kalle-s. QCA-s QUIC repo does not have BDF-s so we have to get the QCN9074 BDF from Kalles repo. Tested-by: Mireia Fernández Casals # Xiaomi AX3600 Tested-by: Francisco G Luna #Netgear WAX218 Signed-off-by: Robert Marko --- package/firmware/ath11k-firmware/Makefile | 25 ++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/package/firmware/ath11k-firmware/Makefile b/package/firmware/ath11k-firmware/Makefile index b3163cd1cb0..fc7968a9576 100644 --- a/package/firmware/ath11k-firmware/Makefile +++ b/package/firmware/ath11k-firmware/Makefile @@ -8,13 +8,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=ath11k-firmware -PKG_SOURCE_DATE:=2022-12-14 -PKG_SOURCE_VERSION:=ab1229f94591ec4ffb16410e359b7f618be75a33 -PKG_MIRROR_HASH:=48a2526971e56a3be1c80b72cd82b9932c196b4ab9b7d5dc35117f0548a8fe57 +PKG_SOURCE_DATE:=2023-03-31 +PKG_SOURCE_VERSION:=a039049a9349722fa5c74185452ab04644a0d351 +PKG_MIRROR_HASH:=ed401e3f6e91d70565b3396139193f7e815f410db93700697205ac8ed1b828c5 PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git -PKG_SOURCE_URL:=https://github.com/kvalo/ath11k-firmware.git +PKG_SOURCE_URL:=https://github.com/quic/upstream-wifi-fw.git PKG_LICENSE_FILES:=LICENSE.qca_firmware @@ -46,20 +46,31 @@ define Build/Compile endef +QCN9074_BOARD_REV:=8e140c65f36137714b6d8934e09dcd73cb05c2f6 +QCN9074_BOARD_FILE:=board-2.bin.$(QCN9074_BOARD_REV) + +define Download/qcn9074-board + URL:=https://github.com/kvalo/ath11k-firmware/raw/master/QCN9074/hw1.0/ + URL_FILE:=board-2.bin + FILE:=$(QCN9074_BOARD_FILE) + HASH:=dbf0ca14aa1229eccd48f26f1026901b9718b143bd30b51b8ea67c84ba6207f1 +endef +$(eval $(call Download,qcn9074-board)) + define Package/ath11k-firmware-ipq8074/install $(INSTALL_DIR) $(1)/lib/firmware/IPQ8074 $(INSTALL_DATA) \ - $(PKG_BUILD_DIR)/IPQ8074/hw2.0/2.5.0.1/WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1/* \ + $(PKG_BUILD_DIR)/ath11k-firmware/IPQ8074/hw2.0/testing/2.9.0.1/WLAN.HK.2.9.0.1-01385-QCAHKSWPL_SILICONZ-1/* \ $(1)/lib/firmware/IPQ8074/ endef define Package/ath11k-firmware-qcn9074/install $(INSTALL_DIR) $(1)/lib/firmware/ath11k/QCN9074/hw1.0 $(INSTALL_DATA) \ - $(PKG_BUILD_DIR)/QCN9074/hw1.0/2.5.0.1/WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1/* \ + $(PKG_BUILD_DIR)/ath11k-firmware/QCN9074/hw1.0/testing/2.9.0.1/WLAN.HK.2.9.0.1-01385-QCAHKSWPL_SILICONZ-1/* \ $(1)/lib/firmware/ath11k/QCN9074/hw1.0/ $(INSTALL_BIN) \ - $(PKG_BUILD_DIR)/QCN9074/hw1.0/board-2.bin $(1)/lib/firmware/ath11k/QCN9074/hw1.0/board-2.bin + $(DL_DIR)/$(QCN9074_BOARD_FILE) $(1)/lib/firmware/ath11k/QCN9074/hw1.0/board-2.bin endef $(eval $(call BuildPackage,ath11k-firmware-ipq8074)) From 318848009200c45f1a81eda5c7d4205a83871303 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Tue, 4 Apr 2023 21:49:43 +0200 Subject: [PATCH 11/14] mac80211: ath11k: Fix invalid mgmt rx frame length issue FW 2.9 uses multiple TLV-s for the RX mgmt even which driver currently does not support, so import a pending upstream patch to fix that [1]. [1] https://patchwork.kernel.org/project/linux-wireless/patch/20230320133840.30162-1-quic_nmaran@quicinc.com/ Signed-off-by: Robert Marko --- ...lid-management-rx-frame-length-issue.patch | 202 ++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 package/kernel/mac80211/patches/ath11k/101-Fix-invalid-management-rx-frame-length-issue.patch diff --git a/package/kernel/mac80211/patches/ath11k/101-Fix-invalid-management-rx-frame-length-issue.patch b/package/kernel/mac80211/patches/ath11k/101-Fix-invalid-management-rx-frame-length-issue.patch new file mode 100644 index 00000000000..7b650a53427 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/101-Fix-invalid-management-rx-frame-length-issue.patch @@ -0,0 +1,202 @@ +From patchwork Mon Mar 20 13:38:40 2023 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Nagarajan Maran +X-Patchwork-Id: 13181272 +X-Patchwork-Delegate: kvalo@adurom.com +Return-Path: +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by smtp.lore.kernel.org (Postfix) with ESMTP id 6F899C6FD1D + for ; + Mon, 20 Mar 2023 13:39:52 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S231824AbjCTNjm (ORCPT + ); + Mon, 20 Mar 2023 09:39:42 -0400 +Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44860 "EHLO + lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S231795AbjCTNjT (ORCPT + ); + Mon, 20 Mar 2023 09:39:19 -0400 +Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com + [205.220.180.131]) + by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CD4CC1A66C + for ; + Mon, 20 Mar 2023 06:39:10 -0700 (PDT) +Received: from pps.filterd (m0279872.ppops.net [127.0.0.1]) + by mx0a-0031df01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id + 32KBvFZ2004731; + Mon, 20 Mar 2023 13:39:05 GMT +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; + h=from : to : cc : + subject : date : message-id : mime-version : content-type; s=qcppdkim1; + bh=jMz2u2+gyjJJcj5tuRPYVv0di+sn1S5ni8sqhMu/9Kg=; + b=BNz+KGi99iSZhDkes9KWF52w7CzSYjHOAYXTfBPlCQk7pM1ZZAIsxB8H3zGnapUkas/r + 1FfSr/9GpQ+5F6LsOEhJ4KF4Us8wsGi/jZnw25FoCqH4jPqhHPQzcC4jaVzVtNdjiA/0 + PlEKhMhP6ULKuRkpbM7RDNigSEYSRmhgqbWkVUL69mwPEJi2oHbhQgxFGFO75Rmfk+Gt + 8w4fd4JPJXA1PNOxL3X8nGYxxzxTsUvQi80R1Tm683dJg7fwBKlNOyD/BlmnrBGBeIqv + CMVmf/KTnEUEFt7WWsvQInmEBZG+JH8TvwUAZ9ndRKqA4kCNXqS5+79KGzUuBP80f3yv ow== +Received: from nalasppmta01.qualcomm.com (Global_NAT1.qualcomm.com + [129.46.96.20]) + by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3pen6hrh12-1 + (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 + verify=NOT); + Mon, 20 Mar 2023 13:39:05 +0000 +Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com + [10.47.209.196]) + by NALASPPMTA01.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id + 32KDd4H6010152 + (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 + verify=NOT); + Mon, 20 Mar 2023 13:39:04 GMT +Received: from nmaran-linux.qualcomm.com (10.80.80.8) by + nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server + (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id + 15.2.986.41; Mon, 20 Mar 2023 06:39:02 -0700 +From: Nagarajan Maran +To: +CC: , + Bhagavathi Perumal S , + Nagarajan Maran +Subject: [PATCH] wifi: ath11k: Fix invalid management rx frame length issue +Date: Mon, 20 Mar 2023 19:08:40 +0530 +Message-ID: <20230320133840.30162-1-quic_nmaran@quicinc.com> +X-Mailer: git-send-email 2.17.1 +MIME-Version: 1.0 +X-Originating-IP: [10.80.80.8] +X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To + nalasex01a.na.qualcomm.com (10.47.209.196) +X-QCInternal: smtphost +X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 + signatures=585085 +X-Proofpoint-ORIG-GUID: 8NkXcGNm6eXVpjTaeMT1e0VxZ9FeT59R +X-Proofpoint-GUID: 8NkXcGNm6eXVpjTaeMT1e0VxZ9FeT59R +X-Proofpoint-Virus-Version: vendor=baseguard + engine=ICAP:2.0.254,Aquarius:18.0.942,Hydra:6.0.573,FMLib:17.11.170.22 + definitions=2023-03-20_09,2023-03-20_02,2023-02-09_01 +X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 + mlxlogscore=999 + malwarescore=0 priorityscore=1501 mlxscore=0 bulkscore=0 adultscore=0 + spamscore=0 impostorscore=0 phishscore=0 clxscore=1011 suspectscore=0 + lowpriorityscore=0 classifier=spam adjust=0 reason=mlx scancount=1 + engine=8.12.0-2303150002 definitions=main-2303200115 +Precedence: bulk +List-ID: +X-Mailing-List: linux-wireless@vger.kernel.org + +From: Bhagavathi Perumal S + +The WMI management rx event has multiple arrays of TLVs, however the common +WMI TLV parser won't handle multiple TLV tags of same type. +So the multiple array tags of WMI management rx TLV is parsed incorrectly +and the length calculated becomes wrong when the target sends multiple +array tags. + +Add separate TLV parser to handle multiple arrays for WMI management rx +TLV. This fixes invalid length issue when the target sends multiple array +tags. + +Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 + +Signed-off-by: Bhagavathi Perumal S +Co-developed-by: Nagarajan Maran +Signed-off-by: Nagarajan Maran +--- + drivers/net/wireless/ath/ath11k/wmi.c | 45 +++++++++++++++++++++------ + 1 file changed, 35 insertions(+), 10 deletions(-) + + +base-commit: 3df3715e556027e94246b2cb30986563362a65f4 + +--- a/drivers/net/wireless/ath/ath11k/wmi.c ++++ b/drivers/net/wireless/ath/ath11k/wmi.c +@@ -82,6 +82,12 @@ struct wmi_tlv_fw_stats_parse { + bool chain_rssi_done; + }; + ++struct wmi_tlv_mgmt_rx_parse { ++ const struct wmi_mgmt_rx_hdr *fixed; ++ const u8 *frame_buf; ++ bool frame_buf_done; ++}; ++ + static const struct wmi_tlv_policy wmi_tlv_policies[] = { + [WMI_TAG_ARRAY_BYTE] + = { .min_len = 0 }, +@@ -5633,28 +5639,49 @@ static int ath11k_pull_vdev_stopped_para + return 0; + } + ++static int ath11k_wmi_tlv_mgmt_rx_parse(struct ath11k_base *ab, ++ u16 tag, u16 len, ++ const void *ptr, void *data) ++{ ++ struct wmi_tlv_mgmt_rx_parse *parse = data; ++ ++ switch (tag) { ++ case WMI_TAG_MGMT_RX_HDR: ++ parse->fixed = ptr; ++ break; ++ case WMI_TAG_ARRAY_BYTE: ++ if (!parse->frame_buf_done) { ++ parse->frame_buf = ptr; ++ parse->frame_buf_done = true; ++ } ++ break; ++ } ++ return 0; ++} ++ + static int ath11k_pull_mgmt_rx_params_tlv(struct ath11k_base *ab, + struct sk_buff *skb, + struct mgmt_rx_event_params *hdr) + { +- const void **tb; ++ struct wmi_tlv_mgmt_rx_parse parse = { }; + const struct wmi_mgmt_rx_hdr *ev; + const u8 *frame; + int ret; + +- tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); +- if (IS_ERR(tb)) { +- ret = PTR_ERR(tb); +- ath11k_warn(ab, "failed to parse tlv: %d\n", ret); ++ ret = ath11k_wmi_tlv_iter(ab, skb->data, skb->len, ++ ath11k_wmi_tlv_mgmt_rx_parse, ++ &parse); ++ if (ret) { ++ ath11k_warn(ab, "failed to parse mgmt rx tlv %d\n", ++ ret); + return ret; + } + +- ev = tb[WMI_TAG_MGMT_RX_HDR]; +- frame = tb[WMI_TAG_ARRAY_BYTE]; ++ ev = parse.fixed; ++ frame = parse.frame_buf; + + if (!ev || !frame) { + ath11k_warn(ab, "failed to fetch mgmt rx hdr"); +- kfree(tb); + return -EPROTO; + } + +@@ -5673,7 +5700,6 @@ static int ath11k_pull_mgmt_rx_params_tl + + if (skb->len < (frame - skb->data) + hdr->buf_len) { + ath11k_warn(ab, "invalid length in mgmt rx hdr ev"); +- kfree(tb); + return -EPROTO; + } + +@@ -5685,7 +5711,6 @@ static int ath11k_pull_mgmt_rx_params_tl + + ath11k_ce_byte_swap(skb->data, hdr->buf_len); + +- kfree(tb); + return 0; + } + From aab736aafadede13a7023ba0d11a3bdd0e441da3 Mon Sep 17 00:00:00 2001 From: Nick Hainke Date: Wed, 5 Apr 2023 13:30:14 +0200 Subject: [PATCH 12/14] tools/zstd: update to 1.5.5 Release Notes: https://github.com/facebook/zstd/releases/tag/v1.5.5 Signed-off-by: Nick Hainke --- tools/zstd/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/zstd/Makefile b/tools/zstd/Makefile index ea0f823e11d..4d46a5f9505 100644 --- a/tools/zstd/Makefile +++ b/tools/zstd/Makefile @@ -1,11 +1,11 @@ include $(TOPDIR)/rules.mk PKG_NAME:=zstd -PKG_VERSION:=1.5.4 +PKG_VERSION:=1.5.5 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://github.com/facebook/zstd/releases/download/v$(PKG_VERSION) -PKG_HASH:=0f470992aedad543126d06efab344dc5f3e171893810455787d38347343a4424 +PKG_HASH:=9c4396cc829cfae319a6e2615202e82aad41372073482fce286fac78646d3ee4 PKG_LICENSE:=BSD-3-Clause PKG_LICENSE_FILES:=LICENSE From 036372c769eb9001d548e6b86ad8ebb97f27fa95 Mon Sep 17 00:00:00 2001 From: Raylynn Knight Date: Sun, 2 Apr 2023 04:27:21 -0400 Subject: [PATCH 13/14] realtek: Fix typo for EnGenius EWS2910P Fix mis-typed DEVICE-MODEL in mk file for EnGenius EWS2910P. Signed-off-by: Raylynn Knight [ fix wrong SoB format and improve commit title/description ] Signed-off-by: Christian Marangi --- target/linux/realtek/image/rtl838x.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/linux/realtek/image/rtl838x.mk b/target/linux/realtek/image/rtl838x.mk index 192b88fe541..7c7bc8a0e5e 100644 --- a/target/linux/realtek/image/rtl838x.mk +++ b/target/linux/realtek/image/rtl838x.mk @@ -81,7 +81,7 @@ define Device/engenius_ews2910p SOC := rtl8380 IMAGE_SIZE := 8192k DEVICE_VENDOR := EnGenius - DEVICE_MODEL := EWP2910P + DEVICE_MODEL := EWS2910P UIMAGE_MAGIC := 0x03802910 KERNEL_INITRAMFS := \ kernel-bin | \ From c3cb2d48da781f4e254ef526e1b44ae5a68248d7 Mon Sep 17 00:00:00 2001 From: Eneas U de Queiroz Date: Tue, 4 Apr 2023 15:39:56 -0300 Subject: [PATCH 14/14] openssl: fix CVE-2023-464 and CVE-2023-465 Apply two patches fixing low-severity vulnerabilities related to certificate policies validation: - Excessive Resource Usage Verifying X.509 Policy Constraints (CVE-2023-0464) Severity: Low A security vulnerability has been identified in all supported versions of OpenSSL related to the verification of X.509 certificate chains that include policy constraints. Attackers may be able to exploit this vulnerability by creating a malicious certificate chain that triggers exponential use of computational resources, leading to a denial-of-service (DoS) attack on affected systems. Policy processing is disabled by default but can be enabled by passing the `-policy' argument to the command line utilities or by calling the `X509_VERIFY_PARAM_set1_policies()' function. - Invalid certificate policies in leaf certificates are silently ignored (CVE-2023-0465) Severity: Low Applications that use a non-default option when verifying certificates may be vulnerable to an attack from a malicious CA to circumvent certain checks. Invalid certificate policies in leaf certificates are silently ignored by OpenSSL and other certificate policy checks are skipped for that certificate. A malicious CA could use this to deliberately assert invalid certificate policies in order to circumvent policy checking on the certificate altogether. Policy processing is disabled by default but can be enabled by passing the `-policy' argument to the command line utilities or by calling the `X509_VERIFY_PARAM_set1_policies()' function. Note: OpenSSL also released a fix for low-severity security advisory CVE-2023-466. It is not included here because the fix only changes the documentation, which is not built nor included in any OpenWrt package. Due to the low-severity of these issues, there will be not be an immediate new release of OpenSSL. Signed-off-by: Eneas U de Queiroz --- package/libs/openssl/Makefile | 2 +- ...esource-use-verifying-policy-constra.patch | 207 ++++++++++++++++++ ...AG_INVALID_POLICY-is-checked-even-in.patch | 44 ++++ 3 files changed, 252 insertions(+), 1 deletion(-) create mode 100644 package/libs/openssl/patches/200-x509-excessive-resource-use-verifying-policy-constra.patch create mode 100644 package/libs/openssl/patches/210-Ensure-that-EXFLAG_INVALID_POLICY-is-checked-even-in.patch diff --git a/package/libs/openssl/Makefile b/package/libs/openssl/Makefile index add3eb7db66..2abb348546b 100644 --- a/package/libs/openssl/Makefile +++ b/package/libs/openssl/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=openssl PKG_VERSION:=3.0.8 -PKG_RELEASE:=7 +PKG_RELEASE:=8 PKG_BUILD_FLAGS:=no-mips16 gc-sections PKG_BUILD_PARALLEL:=1 diff --git a/package/libs/openssl/patches/200-x509-excessive-resource-use-verifying-policy-constra.patch b/package/libs/openssl/patches/200-x509-excessive-resource-use-verifying-policy-constra.patch new file mode 100644 index 00000000000..927634c0a74 --- /dev/null +++ b/package/libs/openssl/patches/200-x509-excessive-resource-use-verifying-policy-constra.patch @@ -0,0 +1,207 @@ +From 959c59c7a0164117e7f8366466a32bb1f8d77ff1 Mon Sep 17 00:00:00 2001 +From: Pauli +Date: Wed, 8 Mar 2023 15:28:20 +1100 +Subject: [PATCH] x509: excessive resource use verifying policy constraints + +A security vulnerability has been identified in all supported versions +of OpenSSL related to the verification of X.509 certificate chains +that include policy constraints. Attackers may be able to exploit this +vulnerability by creating a malicious certificate chain that triggers +exponential use of computational resources, leading to a denial-of-service +(DoS) attack on affected systems. + +Fixes CVE-2023-0464 + +Reviewed-by: Tomas Mraz +Reviewed-by: Shane Lontis +(Merged from https://github.com/openssl/openssl/pull/20568) + +--- a/crypto/x509/pcy_local.h ++++ b/crypto/x509/pcy_local.h +@@ -111,6 +111,11 @@ struct X509_POLICY_LEVEL_st { + }; + + struct X509_POLICY_TREE_st { ++ /* The number of nodes in the tree */ ++ size_t node_count; ++ /* The maximum number of nodes in the tree */ ++ size_t node_maximum; ++ + /* This is the tree 'level' data */ + X509_POLICY_LEVEL *levels; + int nlevel; +@@ -157,7 +162,8 @@ X509_POLICY_NODE *ossl_policy_tree_find_ + X509_POLICY_NODE *ossl_policy_level_add_node(X509_POLICY_LEVEL *level, + X509_POLICY_DATA *data, + X509_POLICY_NODE *parent, +- X509_POLICY_TREE *tree); ++ X509_POLICY_TREE *tree, ++ int extra_data); + void ossl_policy_node_free(X509_POLICY_NODE *node); + int ossl_policy_node_match(const X509_POLICY_LEVEL *lvl, + const X509_POLICY_NODE *node, const ASN1_OBJECT *oid); +--- a/crypto/x509/pcy_node.c ++++ b/crypto/x509/pcy_node.c +@@ -59,10 +59,15 @@ X509_POLICY_NODE *ossl_policy_level_find + X509_POLICY_NODE *ossl_policy_level_add_node(X509_POLICY_LEVEL *level, + X509_POLICY_DATA *data, + X509_POLICY_NODE *parent, +- X509_POLICY_TREE *tree) ++ X509_POLICY_TREE *tree, ++ int extra_data) + { + X509_POLICY_NODE *node; + ++ /* Verify that the tree isn't too large. This mitigates CVE-2023-0464 */ ++ if (tree->node_maximum > 0 && tree->node_count >= tree->node_maximum) ++ return NULL; ++ + node = OPENSSL_zalloc(sizeof(*node)); + if (node == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); +@@ -70,7 +75,7 @@ X509_POLICY_NODE *ossl_policy_level_add_ + } + node->data = data; + node->parent = parent; +- if (level) { ++ if (level != NULL) { + if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) { + if (level->anyPolicy) + goto node_error; +@@ -90,7 +95,7 @@ X509_POLICY_NODE *ossl_policy_level_add_ + } + } + +- if (tree) { ++ if (extra_data) { + if (tree->extra_data == NULL) + tree->extra_data = sk_X509_POLICY_DATA_new_null(); + if (tree->extra_data == NULL){ +@@ -103,6 +108,7 @@ X509_POLICY_NODE *ossl_policy_level_add_ + } + } + ++ tree->node_count++; + if (parent) + parent->nchild++; + +--- a/crypto/x509/pcy_tree.c ++++ b/crypto/x509/pcy_tree.c +@@ -14,6 +14,17 @@ + + #include "pcy_local.h" + ++/* ++ * If the maximum number of nodes in the policy tree isn't defined, set it to ++ * a generous default of 1000 nodes. ++ * ++ * Defining this to be zero means unlimited policy tree growth which opens the ++ * door on CVE-2023-0464. ++ */ ++#ifndef OPENSSL_POLICY_TREE_NODES_MAX ++# define OPENSSL_POLICY_TREE_NODES_MAX 1000 ++#endif ++ + static void expected_print(BIO *channel, + X509_POLICY_LEVEL *lev, X509_POLICY_NODE *node, + int indent) +@@ -163,6 +174,9 @@ static int tree_init(X509_POLICY_TREE ** + return X509_PCY_TREE_INTERNAL; + } + ++ /* Limit the growth of the tree to mitigate CVE-2023-0464 */ ++ tree->node_maximum = OPENSSL_POLICY_TREE_NODES_MAX; ++ + /* + * http://tools.ietf.org/html/rfc5280#section-6.1.2, figure 3. + * +@@ -180,7 +194,7 @@ static int tree_init(X509_POLICY_TREE ** + if ((data = ossl_policy_data_new(NULL, + OBJ_nid2obj(NID_any_policy), 0)) == NULL) + goto bad_tree; +- if (ossl_policy_level_add_node(level, data, NULL, tree) == NULL) { ++ if (ossl_policy_level_add_node(level, data, NULL, tree, 1) == NULL) { + ossl_policy_data_free(data); + goto bad_tree; + } +@@ -239,7 +253,8 @@ static int tree_init(X509_POLICY_TREE ** + * Return value: 1 on success, 0 otherwise + */ + static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr, +- X509_POLICY_DATA *data) ++ X509_POLICY_DATA *data, ++ X509_POLICY_TREE *tree) + { + X509_POLICY_LEVEL *last = curr - 1; + int i, matched = 0; +@@ -249,13 +264,13 @@ static int tree_link_matching_nodes(X509 + X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(last->nodes, i); + + if (ossl_policy_node_match(last, node, data->valid_policy)) { +- if (ossl_policy_level_add_node(curr, data, node, NULL) == NULL) ++ if (ossl_policy_level_add_node(curr, data, node, tree, 0) == NULL) + return 0; + matched = 1; + } + } + if (!matched && last->anyPolicy) { +- if (ossl_policy_level_add_node(curr, data, last->anyPolicy, NULL) == NULL) ++ if (ossl_policy_level_add_node(curr, data, last->anyPolicy, tree, 0) == NULL) + return 0; + } + return 1; +@@ -268,7 +283,8 @@ static int tree_link_matching_nodes(X509 + * Return value: 1 on success, 0 otherwise. + */ + static int tree_link_nodes(X509_POLICY_LEVEL *curr, +- const X509_POLICY_CACHE *cache) ++ const X509_POLICY_CACHE *cache, ++ X509_POLICY_TREE *tree) + { + int i; + +@@ -276,7 +292,7 @@ static int tree_link_nodes(X509_POLICY_L + X509_POLICY_DATA *data = sk_X509_POLICY_DATA_value(cache->data, i); + + /* Look for matching nodes in previous level */ +- if (!tree_link_matching_nodes(curr, data)) ++ if (!tree_link_matching_nodes(curr, data, tree)) + return 0; + } + return 1; +@@ -307,7 +323,7 @@ static int tree_add_unmatched(X509_POLIC + /* Curr may not have anyPolicy */ + data->qualifier_set = cache->anyPolicy->qualifier_set; + data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; +- if (ossl_policy_level_add_node(curr, data, node, tree) == NULL) { ++ if (ossl_policy_level_add_node(curr, data, node, tree, 1) == NULL) { + ossl_policy_data_free(data); + return 0; + } +@@ -370,7 +386,7 @@ static int tree_link_any(X509_POLICY_LEV + /* Finally add link to anyPolicy */ + if (last->anyPolicy && + ossl_policy_level_add_node(curr, cache->anyPolicy, +- last->anyPolicy, NULL) == NULL) ++ last->anyPolicy, tree, 0) == NULL) + return 0; + return 1; + } +@@ -553,7 +569,7 @@ static int tree_calculate_user_set(X509_ + extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS + | POLICY_DATA_FLAG_EXTRA_NODE; + node = ossl_policy_level_add_node(NULL, extra, anyPolicy->parent, +- tree); ++ tree, 1); + } + if (!tree->user_policies) { + tree->user_policies = sk_X509_POLICY_NODE_new_null(); +@@ -580,7 +596,7 @@ static int tree_evaluate(X509_POLICY_TRE + + for (i = 1; i < tree->nlevel; i++, curr++) { + cache = ossl_policy_cache_set(curr->cert); +- if (!tree_link_nodes(curr, cache)) ++ if (!tree_link_nodes(curr, cache, tree)) + return X509_PCY_TREE_INTERNAL; + + if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY) diff --git a/package/libs/openssl/patches/210-Ensure-that-EXFLAG_INVALID_POLICY-is-checked-even-in.patch b/package/libs/openssl/patches/210-Ensure-that-EXFLAG_INVALID_POLICY-is-checked-even-in.patch new file mode 100644 index 00000000000..01819c15a8b --- /dev/null +++ b/package/libs/openssl/patches/210-Ensure-that-EXFLAG_INVALID_POLICY-is-checked-even-in.patch @@ -0,0 +1,44 @@ +From 1dd43e0709fece299b15208f36cc7c76209ba0bb Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Tue, 7 Mar 2023 16:52:55 +0000 +Subject: [PATCH] Ensure that EXFLAG_INVALID_POLICY is checked even in leaf + certs + +Even though we check the leaf cert to confirm it is valid, we +later ignored the invalid flag and did not notice that the leaf +cert was bad. + +Fixes: CVE-2023-0465 + +Reviewed-by: Hugo Landau +Reviewed-by: Tomas Mraz +(Merged from https://github.com/openssl/openssl/pull/20587) + +--- a/crypto/x509/x509_vfy.c ++++ b/crypto/x509/x509_vfy.c +@@ -1654,15 +1654,23 @@ static int check_policy(X509_STORE_CTX * + goto memerr; + /* Invalid or inconsistent extensions */ + if (ret == X509_PCY_TREE_INVALID) { +- int i; ++ int i, cbcalled = 0; + + /* Locate certificates with bad extensions and notify callback. */ +- for (i = 1; i < sk_X509_num(ctx->chain); i++) { ++ for (i = 0; i < sk_X509_num(ctx->chain); i++) { + X509 *x = sk_X509_value(ctx->chain, i); + ++ if ((x->ex_flags & EXFLAG_INVALID_POLICY) != 0) ++ cbcalled = 1; + CB_FAIL_IF((x->ex_flags & EXFLAG_INVALID_POLICY) != 0, + ctx, x, i, X509_V_ERR_INVALID_POLICY_EXTENSION); + } ++ if (!cbcalled) { ++ /* Should not be able to get here */ ++ ERR_raise(ERR_LIB_X509, ERR_R_INTERNAL_ERROR); ++ return 0; ++ } ++ /* The callback ignored the error so we return success */ + return 1; + } + if (ret == X509_PCY_TREE_FAILURE) {