Merge tag 'u-boot-stm32-20230113' of https://source.denx.de/u-boot/custodians/u-boot-stm

Add driver to manage onboard hub supplies
Add calibration support for stm32-adc
Linux kernel v6.1 DT synchronization for stm32mp151.dtsi
stm32mp157a-dk1-scmi-u-boot.dtsi update
Add support of OP-TEE and STM32MP13x in bsec driver
ECDSA various fixes for stm32mp
diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml
index 02cd8e4..49fc34f 100644
--- a/.azure-pipelines.yml
+++ b/.azure-pipelines.yml
@@ -2,7 +2,7 @@
   windows_vm: windows-2019
   ubuntu_vm: ubuntu-22.04
   macos_vm: macOS-12
-  ci_runner_image: trini/u-boot-gitlab-ci-runner:jammy-20221101-22Nov2022
+  ci_runner_image: trini/u-boot-gitlab-ci-runner:jammy-20221130-11Jan2023
   # Add '-u 0' options for Azure pipelines, otherwise we get "permission
   # denied" error when it tries to "useradd -m -u 1001 vsts_azpcontainer",
   # since our $(ci_runner_image) user is not root.
@@ -76,8 +76,8 @@
     steps:
       - script: cppcheck -j$(nproc) --force --quiet --inline-suppr .
 
-  - job: htmldocs
-    displayName: 'Build HTML documentation'
+  - job: docs
+    displayName: 'Build documentation'
     pool:
       vmImage: $(ubuntu_vm)
     container:
@@ -89,6 +89,7 @@
           . /tmp/venvhtml/bin/activate
           pip install -r doc/sphinx/requirements.txt
           make htmldocs
+          make infodocs
 
   - job: todo
     displayName: 'Search for TODO within source tree'
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index afd8394..398fa2b 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -2,7 +2,7 @@
 
 # Grab our configured image.  The source for this is found
 # in the u-boot tree at tools/docker/Dockerfile
-image: trini/u-boot-gitlab-ci-runner:jammy-20221101-22Nov2022
+image: trini/u-boot-gitlab-ci-runner:jammy-20221130-11Jan2023
 
 # We run some tests in different order, to catch some failures quicker.
 stages:
@@ -149,14 +149,15 @@
     # search for HACK within source tree and ignore HACKKIT board
     - grep -r HACK . | grep -v HACKKIT
 
-# build HTML documentation
-htmldocs:
+# build documentation
+docs:
   stage: testsuites
   script:
     - virtualenv -p /usr/bin/python3 /tmp/venvhtml
     - . /tmp/venvhtml/bin/activate
     - pip install -r doc/sphinx/requirements.txt
     - make htmldocs
+    - make infodocs
 
 # some statistics about the code base
 sloccount:
diff --git a/MAINTAINERS b/MAINTAINERS
index 237f394..b2de50c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1198,6 +1198,7 @@
 S:	Maintained
 F:	doc/api/nvmem.rst
 F:	drivers/misc/nvmem.c
+F:	drivers/reboot-mode/reboot-mode-nvmem.c
 F:	include/nvmem.h
 
 NXP C45 TJA11XX PHY DRIVER
diff --git a/arch/Kconfig b/arch/Kconfig
index 5f2b72f..8fb87b7 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -384,9 +384,11 @@
 	bool "U-Boot is loaded in to RAM by a pre-loader"
 	depends on M68K || NIOS2
 
-config SKIP_LOWLEVEL_INIT
-	bool "Skip the calls to certain low level initialization functions"
+menu "Skipping low level initialization functions"
 	depends on ARM || MIPS || RISCV
+
+config SKIP_LOWLEVEL_INIT
+	bool "Skip calls to certain low level initialization functions"
 	help
 	  If enabled, then certain low level initializations (like setting up
 	  the memory controller) are omitted and/or U-Boot does not relocate
@@ -396,8 +398,8 @@
 	  debugger which performs these initializations itself.
 
 config SPL_SKIP_LOWLEVEL_INIT
-	bool "Skip the calls to certain low level initialization functions"
-	depends on SPL && (ARM || MIPS || RISCV)
+	bool "Skip calls to certain low level initialization functions in SPL"
+	depends on SPL
 	help
 	  If enabled, then certain low level initializations (like setting up
 	  the memory controller) are omitted and/or U-Boot does not relocate
@@ -407,7 +409,7 @@
 	  debugger which performs these initializations itself.
 
 config TPL_SKIP_LOWLEVEL_INIT
-	bool "Skip the calls to certain low level initialization functions"
+	bool "Skip calls to certain low level initialization functions in TPL"
 	depends on SPL && ARM
 	help
 	  If enabled, then certain low level initializations (like setting up
@@ -418,7 +420,7 @@
 	  debugger which performs these initializations itself.
 
 config SKIP_LOWLEVEL_INIT_ONLY
-	bool "Skip the call to lowlevel_init during early boot ONLY"
+	bool "Skip call to lowlevel_init during early boot ONLY"
 	depends on ARM
 	help
 	  This allows just the call to lowlevel_init() to be skipped. The
@@ -426,7 +428,7 @@
 	  performed.
 
 config SPL_SKIP_LOWLEVEL_INIT_ONLY
-	bool "Skip the call to lowlevel_init during early boot ONLY"
+	bool "Skip call to lowlevel_init during early SPL boot ONLY"
 	depends on SPL && ARM
 	help
 	  This allows just the call to lowlevel_init() to be skipped. The
@@ -434,13 +436,15 @@
 	  performed.
 
 config TPL_SKIP_LOWLEVEL_INIT_ONLY
-	bool "Skip the call to lowlevel_init during early boot ONLY"
+	bool "Skip call to lowlevel_init during early TPL boot ONLY"
 	depends on TPL && ARM
 	help
 	  This allows just the call to lowlevel_init() to be skipped. The
 	  normal CP15 init (such as enabling the instruction cache) is still
 	  performed.
 
+endmenu
+
 config SYS_HAS_NONCACHED_MEMORY
 	bool "Enable reserving a non-cached memory area for drivers"
 	depends on (ARM || MIPS) && (RTL8169 || MEDIATEK_ETH)
diff --git a/arch/Kconfig.nxp b/arch/Kconfig.nxp
index ad61dab..f492b04 100644
--- a/arch/Kconfig.nxp
+++ b/arch/Kconfig.nxp
@@ -1,3 +1,5 @@
+menu "Functionality shared between NXP SoCs"
+
 config FSL_TRUST_ARCH_v1
 	bool
 
@@ -142,8 +144,6 @@
 
 endmenu
 
-comment "Other functionality shared between NXP SoCs"
-
 config DEEP_SLEEP
 	bool "Enable SoC deep sleep feature"
 	depends on ARCH_T1024 || ARCH_T1040 || ARCH_T1042 || ARCH_LS1021A
@@ -271,3 +271,5 @@
 
 config SYS_DPAA_FMAN
 	bool
+
+endmenu
diff --git a/arch/arm/lib/elf_aarch64_efi.lds b/arch/arm/lib/elf_aarch64_efi.lds
index 3e3da47..5dd9809 100644
--- a/arch/arm/lib/elf_aarch64_efi.lds
+++ b/arch/arm/lib/elf_aarch64_efi.lds
@@ -28,6 +28,10 @@
 		*(.dynamic);
 		. = ALIGN(512);
 	}
+	.rela.dyn : { *(.rela.dyn) }
+	.rela.plt : { *(.rela.plt) }
+	.rela.got : { *(.rela.got) }
+	.rela.data : { *(.rela.data) *(.rela.data*) }
 	_etext = .;
 	_text_size = . - _text;
 	. = ALIGN(4096);
@@ -57,10 +61,6 @@
 		_edata = .;
 	} :data
 	_data_size = _edata - _data;
-	.rela.dyn : { *(.rela.dyn) }
-	.rela.plt : { *(.rela.plt) }
-	.rela.got : { *(.rela.got) }
-	.rela.data : { *(.rela.data) *(.rela.data*) }
 
 	. = ALIGN(4096);
 	.dynsym   : { *(.dynsym) }
diff --git a/arch/arm/mach-imx/mx6/soc.c b/arch/arm/mach-imx/mx6/soc.c
index 08f47cf..c2875e7 100644
--- a/arch/arm/mach-imx/mx6/soc.c
+++ b/arch/arm/mach-imx/mx6/soc.c
@@ -746,6 +746,16 @@
 		if (ret)
 			printf("Failed to initialize caam_jr: %d\n", ret);
 	}
+
+	if (IS_ENABLED(CONFIG_FSL_DCP_RNG)) {
+		struct udevice *dev;
+		int ret;
+
+		ret = uclass_get_device_by_driver(UCLASS_RNG, DM_DRIVER_GET(dcp_rng), &dev);
+		if (ret)
+			printf("Failed to initialize dcp rng: %d\n", ret);
+	}
+
 	setup_serial_number();
 	return 0;
 }
diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c
index d5e1f8e..a2adb79 100644
--- a/arch/arm/mach-k3/common.c
+++ b/arch/arm/mach-k3/common.c
@@ -181,7 +181,7 @@
 	if (!*loadaddr)
 		return 0;
 
-	if (!uclass_get_device(UCLASS_FS_FIRMWARE_LOADER, 0, &fsdev)) {
+	if (!get_fs_loader(&fsdev)) {
 		size = request_firmware_into_buf(fsdev, name, (void *)*loadaddr,
 						 0, 0);
 	}
diff --git a/arch/arm/mach-omap2/boot-common.c b/arch/arm/mach-omap2/boot-common.c
index d104f23..9a342a1 100644
--- a/arch/arm/mach-omap2/boot-common.c
+++ b/arch/arm/mach-omap2/boot-common.c
@@ -214,7 +214,7 @@
 	if (!*loadaddr)
 		return 0;
 
-	if (!uclass_get_device(UCLASS_FS_FIRMWARE_LOADER, 0, &fsdev)) {
+	if (!get_fs_loader(&fsdev)) {
 		size = request_firmware_into_buf(fsdev, name_fw,
 						 (void *)*loadaddr, 0, 0);
 	}
diff --git a/arch/arm/mach-socfpga/qts-filter-a10.sh b/arch/arm/mach-socfpga/qts-filter-a10.sh
index 57d77e8..ab16522 100755
--- a/arch/arm/mach-socfpga/qts-filter-a10.sh
+++ b/arch/arm/mach-socfpga/qts-filter-a10.sh
@@ -10,7 +10,7 @@
 
 #filter out only what we need from a10 hps.xml
 grep_a10_hps_config() {
-	egrep "clk_hz|i_clk_mgr|i_io48_pin_mux|AXI_SLAVE|AXI_MASTER"
+	grep -E "clk_hz|i_clk_mgr|i_io48_pin_mux|AXI_SLAVE|AXI_MASTER"
 }
 
 #
@@ -35,35 +35,35 @@
 
 	echo "/* Clocks */"
 	fix_newlines_in_macros \
-		${hps_xml} | egrep "clk_hz" |
+		${hps_xml} | grep "clk_hz" |
 			awk -F"'" '{ gsub("\\.","_",$2) ; \
 				print "#define" " " toupper($2) " " $4}' |
 			sed 's/\.[0-9]//' |
 			sed 's/I_CLK_MGR_//' |
 			sort
 	fix_newlines_in_macros \
-		${hps_xml} | egrep "i_clk_mgr_mainpll" |
+		${hps_xml} | grep "i_clk_mgr_mainpll" |
 			awk -F"'" '{ gsub("\\.","_",$2) ; \
 				print "#define" " " toupper($2) " " $4}' |
 			sed 's/\.[0-9]//' |
 			sed 's/I_CLK_MGR_//' |
 			sort
 	fix_newlines_in_macros \
-		${hps_xml} | egrep "i_clk_mgr_perpll" |
+		${hps_xml} | grep "i_clk_mgr_perpll" |
 			awk -F"'" '{ gsub("\\.","_",$2) ; \
 				print "#define" " " toupper($2) " " $4}' |
 			sed 's/\.[0-9]//' |
 			sed 's/I_CLK_MGR_//' |
 			sort
 	fix_newlines_in_macros \
-		${hps_xml} | egrep "i_clk_mgr_clkmgr" |
+		${hps_xml} | grep "i_clk_mgr_clkmgr" |
 			awk -F"'" '{ gsub("\\.","_",$2) ; \
 				print "#define" " " toupper($2) " " $4}' |
 			sed 's/\.[0-9]//' |
 			sed 's/I_CLK_MGR_//' |
 			sort
 	fix_newlines_in_macros \
-		${hps_xml} | egrep "i_clk_mgr_alteragrp" |
+		${hps_xml} | grep "i_clk_mgr_alteragrp" |
 			awk -F"'" '{ gsub("\\.","_",$2) ; \
 				print "#define" " " toupper($2) " " $4}' |
 			sed 's/\.[0-9]//' |
@@ -77,7 +77,7 @@
 	echo
 	echo "/* Pin Mux Configuration */"
 	fix_newlines_in_macros \
-		${hps_xml} | egrep "i_io48_pin_mux" |
+		${hps_xml} | grep "i_io48_pin_mux" |
 			awk -F"'" '{ gsub("\\.","_",$2) ; \
 				print "#define" " " toupper($2) " " $4}' |
 			sed 's/I_IO48_PIN_MUX_//' |
@@ -90,7 +90,7 @@
 	echo
 	echo "/* Bridge Configuration */"
 	fix_newlines_in_macros \
-		${hps_xml} | egrep "AXI_SLAVE|AXI_MASTER" |
+		${hps_xml} | grep -E "AXI_SLAVE|AXI_MASTER" |
 			awk -F"'" '{ gsub("\\.","_",$2) ; \
 				print "#define" " " toupper($2) " " $4}' |
 			sed 's/true/1/' |
diff --git a/arch/arm/mach-socfpga/qts-filter.sh b/arch/arm/mach-socfpga/qts-filter.sh
index 6416252..1610c89 100755
--- a/arch/arm/mach-socfpga/qts-filter.sh
+++ b/arch/arm/mach-socfpga/qts-filter.sh
@@ -128,7 +128,7 @@
 # Filter out only the macros which are actually used by the code
 #
 grep_sdram_config() {
-	egrep "#define (CFG_HPS_SDR_CTRLCFG_CTRLCFG_MEMTYPE|CFG_HPS_SDR_CTRLCFG_CTRLCFG_MEMBL|CFG_HPS_SDR_CTRLCFG_CTRLCFG_ADDRORDER|CFG_HPS_SDR_CTRLCFG_CTRLCFG_ECCEN|CFG_HPS_SDR_CTRLCFG_CTRLCFG_ECCCORREN|CFG_HPS_SDR_CTRLCFG_CTRLCFG_REORDEREN|CFG_HPS_SDR_CTRLCFG_CTRLCFG_STARVELIMIT|CFG_HPS_SDR_CTRLCFG_CTRLCFG_DQSTRKEN|CFG_HPS_SDR_CTRLCFG_CTRLCFG_NODMPINS|CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TCWL|CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_AL|CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TCL|CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TRRD|CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TFAW|CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TRFC|CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TREFI|CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TRCD|CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TRP|CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TWR|CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TWTR|CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRTP|CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRAS|CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRC|CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TMRD|CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TCCD|CFG_HPS_SDR_CTRLCFG_DRAMTIMING4_SELFRFSHEXIT|CFG_HPS_SDR_CTRLCFG_DRAMTIMING4_PWRDOWNEXIT|CFG_HPS_SDR_CTRLCFG_LOWPWRTIMING_AUTOPDCYCLES|CFG_HPS_SDR_CTRLCFG_LOWPWRTIMING_CLKDISABLECYCLES|CFG_HPS_SDR_CTRLCFG_DRAMODT_READ|CFG_HPS_SDR_CTRLCFG_DRAMODT_WRITE|CFG_HPS_SDR_CTRLCFG_DRAMADDRW_COLBITS|CFG_HPS_SDR_CTRLCFG_DRAMADDRW_ROWBITS|CFG_HPS_SDR_CTRLCFG_DRAMADDRW_BANKBITS|CFG_HPS_SDR_CTRLCFG_DRAMADDRW_CSBITS|CFG_HPS_SDR_CTRLCFG_DRAMIFWIDTH_IFWIDTH|CFG_HPS_SDR_CTRLCFG_DRAMDEVWIDTH_DEVWIDTH|CFG_HPS_SDR_CTRLCFG_DRAMINTR_INTREN|CFG_HPS_SDR_CTRLCFG_LOWPWREQ_SELFRFSHMASK|CFG_HPS_SDR_CTRLCFG_STATICCFG_MEMBL|CFG_HPS_SDR_CTRLCFG_STATICCFG_USEECCASDATA|CFG_HPS_SDR_CTRLCFG_CTRLWIDTH_CTRLWIDTH|CFG_HPS_SDR_CTRLCFG_CPORTWIDTH_CPORTWIDTH|CFG_HPS_SDR_CTRLCFG_CPORTWMAP_CPORTWMAP|CFG_HPS_SDR_CTRLCFG_CPORTRMAP_CPORTRMAP|CFG_HPS_SDR_CTRLCFG_RFIFOCMAP_RFIFOCMAP|CFG_HPS_SDR_CTRLCFG_WFIFOCMAP_WFIFOCMAP|CFG_HPS_SDR_CTRLCFG_CPORTRDWR_CPORTRDWR|CFG_HPS_SDR_CTRLCFG_PORTCFG_AUTOPCHEN|CFG_HPS_SDR_CTRLCFG_FPGAPORTRST|CFG_HPS_SDR_CTRLCFG_FIFOCFG_SYNCMODE|CFG_HPS_SDR_CTRLCFG_FIFOCFG_INCSYNC|CFG_HPS_SDR_CTRLCFG_MPPRIORITY_USERPRIORITY|CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_0_STATICWEIGHT_31_0|CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_1_STATICWEIGHT_49_32|CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_1_SUMOFWEIGHT_13_0|CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_2_SUMOFWEIGHT_45_14|CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_3_SUMOFWEIGHT_63_46|CFG_HPS_SDR_CTRLCFG_PHYCTRL_PHYCTRL_0|CFG_HPS_SDR_CTRLCFG_MPPACING_0_THRESHOLD1_31_0|CFG_HPS_SDR_CTRLCFG_MPPACING_1_THRESHOLD1_59_32|CFG_HPS_SDR_CTRLCFG_MPPACING_1_THRESHOLD2_3_0|CFG_HPS_SDR_CTRLCFG_MPPACING_2_THRESHOLD2_35_4|CFG_HPS_SDR_CTRLCFG_MPPACING_3_THRESHOLD2_59_36|CFG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_0_THRESHOLDRSTCYCLES_31_0|CFG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_1_THRESHOLDRSTCYCLES_63_32|CFG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_2_THRESHOLDRSTCYCLES_79_64|RW_MGR_ACTIVATE_0_AND_1|RW_MGR_ACTIVATE_0_AND_1_WAIT1|RW_MGR_ACTIVATE_0_AND_1_WAIT2|RW_MGR_ACTIVATE_1|RW_MGR_CLEAR_DQS_ENABLE|RW_MGR_EMR_OCD_ENABLE|RW_MGR_EMR|RW_MGR_EMR2|RW_MGR_EMR3|RW_MGR_GUARANTEED_READ|RW_MGR_GUARANTEED_READ_CONT|RW_MGR_GUARANTEED_WRITE|RW_MGR_GUARANTEED_WRITE_WAIT0|RW_MGR_GUARANTEED_WRITE_WAIT1|RW_MGR_GUARANTEED_WRITE_WAIT2|RW_MGR_GUARANTEED_WRITE_WAIT3|RW_MGR_IDLE|RW_MGR_IDLE_LOOP1|RW_MGR_IDLE_LOOP2|RW_MGR_INIT_RESET_0_CKE_0|RW_MGR_INIT_RESET_1_CKE_0|RW_MGR_INIT_CKE_0|RW_MGR_LFSR_WR_RD_BANK_0|RW_MGR_LFSR_WR_RD_BANK_0_DATA|RW_MGR_LFSR_WR_RD_BANK_0_DQS|RW_MGR_LFSR_WR_RD_BANK_0_NOP|RW_MGR_LFSR_WR_RD_BANK_0_WAIT|RW_MGR_LFSR_WR_RD_BANK_0_WL_1|RW_MGR_LFSR_WR_RD_DM_BANK_0|RW_MGR_LFSR_WR_RD_DM_BANK_0_DATA|RW_MGR_LFSR_WR_RD_DM_BANK_0_DQS|RW_MGR_LFSR_WR_RD_DM_BANK_0_NOP|RW_MGR_LFSR_WR_RD_DM_BANK_0_WAIT|RW_MGR_LFSR_WR_RD_DM_BANK_0_WL_1|RW_MGR_MR_CALIB|RW_MGR_MR_USER|RW_MGR_MR_DLL_RESET|RW_MGR_MRS0_DLL_RESET|RW_MGR_MRS0_DLL_RESET_MIRR|RW_MGR_MRS0_USER|RW_MGR_MRS0_USER_MIRR|RW_MGR_MRS1|RW_MGR_MRS1_MIRR|RW_MGR_MRS2|RW_MGR_MRS2_MIRR|RW_MGR_MRS3|RW_MGR_MRS3_MIRR|RW_MGR_NOP|RW_MGR_PRECHARGE_ALL|RW_MGR_READ_B2B|RW_MGR_READ_B2B_WAIT1|RW_MGR_READ_B2B_WAIT2|RW_MGR_REFRESH|RW_MGR_REFRESH_ALL|RW_MGR_RETURN|RW_MGR_SGLE_READ|RW_MGR_ZQCL|RW_MGR_TRUE_MEM_DATA_MASK_WIDTH|RW_MGR_MEM_ADDRESS_MIRRORING|RW_MGR_MEM_DATA_MASK_WIDTH|RW_MGR_MEM_DATA_WIDTH|RW_MGR_MEM_DQ_PER_READ_DQS|RW_MGR_MEM_DQ_PER_WRITE_DQS|RW_MGR_MEM_IF_READ_DQS_WIDTH|RW_MGR_MEM_IF_WRITE_DQS_WIDTH|RW_MGR_MEM_NUMBER_OF_CS_PER_DIMM|RW_MGR_MEM_NUMBER_OF_RANKS|RW_MGR_MEM_VIRTUAL_GROUPS_PER_READ_DQS|RW_MGR_MEM_VIRTUAL_GROUPS_PER_WRITE_DQS|IO_DELAY_PER_DCHAIN_TAP|IO_DELAY_PER_DQS_EN_DCHAIN_TAP|IO_DELAY_PER_OPA_TAP|IO_DLL_CHAIN_LENGTH|IO_DQDQS_OUT_PHASE_MAX|IO_DQS_EN_DELAY_MAX|IO_DQS_EN_DELAY_OFFSET|IO_DQS_EN_PHASE_MAX|IO_DQS_IN_DELAY_MAX|IO_DQS_IN_RESERVE|IO_DQS_OUT_RESERVE|IO_IO_IN_DELAY_MAX|IO_IO_OUT1_DELAY_MAX|IO_IO_OUT2_DELAY_MAX|IO_SHIFT_DQS_EN_WHEN_SHIFT_DQS|AFI_RATE_RATIO|AFI_CLK_FREQ|CALIB_LFIFO_OFFSET|CALIB_VFIFO_OFFSET|ENABLE_SUPER_QUICK_CALIBRATION|MAX_LATENCY_COUNT_WIDTH|READ_VALID_FIFO_SIZE|REG_FILE_INIT_SEQ_SIGNATURE|TINIT_CNTR0_VAL|TINIT_CNTR1_VAL|TINIT_CNTR2_VAL|TRESET_CNTR0_VAL|TRESET_CNTR1_VAL|TRESET_CNTR2_VAL|CFG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR|CFG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR_BC|CFG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR_DIFF_CHIP)[[:space:]]"
+	grep -E "#define (CFG_HPS_SDR_CTRLCFG_CTRLCFG_MEMTYPE|CFG_HPS_SDR_CTRLCFG_CTRLCFG_MEMBL|CFG_HPS_SDR_CTRLCFG_CTRLCFG_ADDRORDER|CFG_HPS_SDR_CTRLCFG_CTRLCFG_ECCEN|CFG_HPS_SDR_CTRLCFG_CTRLCFG_ECCCORREN|CFG_HPS_SDR_CTRLCFG_CTRLCFG_REORDEREN|CFG_HPS_SDR_CTRLCFG_CTRLCFG_STARVELIMIT|CFG_HPS_SDR_CTRLCFG_CTRLCFG_DQSTRKEN|CFG_HPS_SDR_CTRLCFG_CTRLCFG_NODMPINS|CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TCWL|CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_AL|CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TCL|CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TRRD|CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TFAW|CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TRFC|CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TREFI|CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TRCD|CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TRP|CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TWR|CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TWTR|CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRTP|CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRAS|CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRC|CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TMRD|CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TCCD|CFG_HPS_SDR_CTRLCFG_DRAMTIMING4_SELFRFSHEXIT|CFG_HPS_SDR_CTRLCFG_DRAMTIMING4_PWRDOWNEXIT|CFG_HPS_SDR_CTRLCFG_LOWPWRTIMING_AUTOPDCYCLES|CFG_HPS_SDR_CTRLCFG_LOWPWRTIMING_CLKDISABLECYCLES|CFG_HPS_SDR_CTRLCFG_DRAMODT_READ|CFG_HPS_SDR_CTRLCFG_DRAMODT_WRITE|CFG_HPS_SDR_CTRLCFG_DRAMADDRW_COLBITS|CFG_HPS_SDR_CTRLCFG_DRAMADDRW_ROWBITS|CFG_HPS_SDR_CTRLCFG_DRAMADDRW_BANKBITS|CFG_HPS_SDR_CTRLCFG_DRAMADDRW_CSBITS|CFG_HPS_SDR_CTRLCFG_DRAMIFWIDTH_IFWIDTH|CFG_HPS_SDR_CTRLCFG_DRAMDEVWIDTH_DEVWIDTH|CFG_HPS_SDR_CTRLCFG_DRAMINTR_INTREN|CFG_HPS_SDR_CTRLCFG_LOWPWREQ_SELFRFSHMASK|CFG_HPS_SDR_CTRLCFG_STATICCFG_MEMBL|CFG_HPS_SDR_CTRLCFG_STATICCFG_USEECCASDATA|CFG_HPS_SDR_CTRLCFG_CTRLWIDTH_CTRLWIDTH|CFG_HPS_SDR_CTRLCFG_CPORTWIDTH_CPORTWIDTH|CFG_HPS_SDR_CTRLCFG_CPORTWMAP_CPORTWMAP|CFG_HPS_SDR_CTRLCFG_CPORTRMAP_CPORTRMAP|CFG_HPS_SDR_CTRLCFG_RFIFOCMAP_RFIFOCMAP|CFG_HPS_SDR_CTRLCFG_WFIFOCMAP_WFIFOCMAP|CFG_HPS_SDR_CTRLCFG_CPORTRDWR_CPORTRDWR|CFG_HPS_SDR_CTRLCFG_PORTCFG_AUTOPCHEN|CFG_HPS_SDR_CTRLCFG_FPGAPORTRST|CFG_HPS_SDR_CTRLCFG_FIFOCFG_SYNCMODE|CFG_HPS_SDR_CTRLCFG_FIFOCFG_INCSYNC|CFG_HPS_SDR_CTRLCFG_MPPRIORITY_USERPRIORITY|CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_0_STATICWEIGHT_31_0|CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_1_STATICWEIGHT_49_32|CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_1_SUMOFWEIGHT_13_0|CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_2_SUMOFWEIGHT_45_14|CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_3_SUMOFWEIGHT_63_46|CFG_HPS_SDR_CTRLCFG_PHYCTRL_PHYCTRL_0|CFG_HPS_SDR_CTRLCFG_MPPACING_0_THRESHOLD1_31_0|CFG_HPS_SDR_CTRLCFG_MPPACING_1_THRESHOLD1_59_32|CFG_HPS_SDR_CTRLCFG_MPPACING_1_THRESHOLD2_3_0|CFG_HPS_SDR_CTRLCFG_MPPACING_2_THRESHOLD2_35_4|CFG_HPS_SDR_CTRLCFG_MPPACING_3_THRESHOLD2_59_36|CFG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_0_THRESHOLDRSTCYCLES_31_0|CFG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_1_THRESHOLDRSTCYCLES_63_32|CFG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_2_THRESHOLDRSTCYCLES_79_64|RW_MGR_ACTIVATE_0_AND_1|RW_MGR_ACTIVATE_0_AND_1_WAIT1|RW_MGR_ACTIVATE_0_AND_1_WAIT2|RW_MGR_ACTIVATE_1|RW_MGR_CLEAR_DQS_ENABLE|RW_MGR_EMR_OCD_ENABLE|RW_MGR_EMR|RW_MGR_EMR2|RW_MGR_EMR3|RW_MGR_GUARANTEED_READ|RW_MGR_GUARANTEED_READ_CONT|RW_MGR_GUARANTEED_WRITE|RW_MGR_GUARANTEED_WRITE_WAIT0|RW_MGR_GUARANTEED_WRITE_WAIT1|RW_MGR_GUARANTEED_WRITE_WAIT2|RW_MGR_GUARANTEED_WRITE_WAIT3|RW_MGR_IDLE|RW_MGR_IDLE_LOOP1|RW_MGR_IDLE_LOOP2|RW_MGR_INIT_RESET_0_CKE_0|RW_MGR_INIT_RESET_1_CKE_0|RW_MGR_INIT_CKE_0|RW_MGR_LFSR_WR_RD_BANK_0|RW_MGR_LFSR_WR_RD_BANK_0_DATA|RW_MGR_LFSR_WR_RD_BANK_0_DQS|RW_MGR_LFSR_WR_RD_BANK_0_NOP|RW_MGR_LFSR_WR_RD_BANK_0_WAIT|RW_MGR_LFSR_WR_RD_BANK_0_WL_1|RW_MGR_LFSR_WR_RD_DM_BANK_0|RW_MGR_LFSR_WR_RD_DM_BANK_0_DATA|RW_MGR_LFSR_WR_RD_DM_BANK_0_DQS|RW_MGR_LFSR_WR_RD_DM_BANK_0_NOP|RW_MGR_LFSR_WR_RD_DM_BANK_0_WAIT|RW_MGR_LFSR_WR_RD_DM_BANK_0_WL_1|RW_MGR_MR_CALIB|RW_MGR_MR_USER|RW_MGR_MR_DLL_RESET|RW_MGR_MRS0_DLL_RESET|RW_MGR_MRS0_DLL_RESET_MIRR|RW_MGR_MRS0_USER|RW_MGR_MRS0_USER_MIRR|RW_MGR_MRS1|RW_MGR_MRS1_MIRR|RW_MGR_MRS2|RW_MGR_MRS2_MIRR|RW_MGR_MRS3|RW_MGR_MRS3_MIRR|RW_MGR_NOP|RW_MGR_PRECHARGE_ALL|RW_MGR_READ_B2B|RW_MGR_READ_B2B_WAIT1|RW_MGR_READ_B2B_WAIT2|RW_MGR_REFRESH|RW_MGR_REFRESH_ALL|RW_MGR_RETURN|RW_MGR_SGLE_READ|RW_MGR_ZQCL|RW_MGR_TRUE_MEM_DATA_MASK_WIDTH|RW_MGR_MEM_ADDRESS_MIRRORING|RW_MGR_MEM_DATA_MASK_WIDTH|RW_MGR_MEM_DATA_WIDTH|RW_MGR_MEM_DQ_PER_READ_DQS|RW_MGR_MEM_DQ_PER_WRITE_DQS|RW_MGR_MEM_IF_READ_DQS_WIDTH|RW_MGR_MEM_IF_WRITE_DQS_WIDTH|RW_MGR_MEM_NUMBER_OF_CS_PER_DIMM|RW_MGR_MEM_NUMBER_OF_RANKS|RW_MGR_MEM_VIRTUAL_GROUPS_PER_READ_DQS|RW_MGR_MEM_VIRTUAL_GROUPS_PER_WRITE_DQS|IO_DELAY_PER_DCHAIN_TAP|IO_DELAY_PER_DQS_EN_DCHAIN_TAP|IO_DELAY_PER_OPA_TAP|IO_DLL_CHAIN_LENGTH|IO_DQDQS_OUT_PHASE_MAX|IO_DQS_EN_DELAY_MAX|IO_DQS_EN_DELAY_OFFSET|IO_DQS_EN_PHASE_MAX|IO_DQS_IN_DELAY_MAX|IO_DQS_IN_RESERVE|IO_DQS_OUT_RESERVE|IO_IO_IN_DELAY_MAX|IO_IO_OUT1_DELAY_MAX|IO_IO_OUT2_DELAY_MAX|IO_SHIFT_DQS_EN_WHEN_SHIFT_DQS|AFI_RATE_RATIO|AFI_CLK_FREQ|CALIB_LFIFO_OFFSET|CALIB_VFIFO_OFFSET|ENABLE_SUPER_QUICK_CALIBRATION|MAX_LATENCY_COUNT_WIDTH|READ_VALID_FIFO_SIZE|REG_FILE_INIT_SEQ_SIGNATURE|TINIT_CNTR0_VAL|TINIT_CNTR1_VAL|TINIT_CNTR2_VAL|TRESET_CNTR0_VAL|TRESET_CNTR1_VAL|TRESET_CNTR2_VAL|CFG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR|CFG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR_BC|CFG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR_DIFF_CHIP)[[:space:]]"
 }
 
 #
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 199a553..b2aefae 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -2539,6 +2539,7 @@
 config MTDIDS_DEFAULT
 	string "Default MTD IDs"
 	depends on MTD || SPI_FLASH
+	depends on !SYS_MTDPARTS_RUNTIME
 	help
 	  Defines a default MTD IDs list for use with MTD partitions in the
 	  Linux MTD command line partitions format.
@@ -2546,6 +2547,7 @@
 config MTDPARTS_DEFAULT
 	string "Default MTD partition scheme"
 	depends on MTD || SPI_FLASH
+	depends on !SYS_MTDPARTS_RUNTIME
 	help
 	  Defines a default MTD partitioning scheme in the Linux MTD command
 	  line partitions format
diff --git a/cmd/exit.c b/cmd/exit.c
index 2c71326..7bf241e 100644
--- a/cmd/exit.c
+++ b/cmd/exit.c
@@ -10,10 +10,13 @@
 static int do_exit(struct cmd_tbl *cmdtp, int flag, int argc,
 		   char *const argv[])
 {
-	if (argc > 1)
-		return dectoul(argv[1], NULL);
+	int r;
 
-	return 0;
+	r = 0;
+	if (argc > 1)
+		r = simple_strtoul(argv[1], NULL, 10);
+
+	return -r - 2;
 }
 
 U_BOOT_CMD(
diff --git a/cmd/fastboot.c b/cmd/fastboot.c
index b498e4b..b94dbd5 100644
--- a/cmd/fastboot.c
+++ b/cmd/fastboot.c
@@ -19,8 +19,14 @@
 static int do_fastboot_udp(int argc, char *const argv[],
 			   uintptr_t buf_addr, size_t buf_size)
 {
-#if CONFIG_IS_ENABLED(UDP_FUNCTION_FASTBOOT)
-	int err = net_loop(FASTBOOT);
+	int err;
+
+	if (!CONFIG_IS_ENABLED(UDP_FUNCTION_FASTBOOT)) {
+		pr_err("Fastboot UDP not enabled\n");
+		return CMD_RET_FAILURE;
+	}
+
+	err = net_loop(FASTBOOT);
 
 	if (err < 0) {
 		printf("fastboot udp error: %d\n", err);
@@ -28,21 +34,21 @@
 	}
 
 	return CMD_RET_SUCCESS;
-#else
-	pr_err("Fastboot UDP not enabled\n");
-	return CMD_RET_FAILURE;
-#endif
 }
 
 static int do_fastboot_usb(int argc, char *const argv[],
 			   uintptr_t buf_addr, size_t buf_size)
 {
-#if CONFIG_IS_ENABLED(USB_FUNCTION_FASTBOOT)
 	int controller_index;
 	char *usb_controller;
 	char *endp;
 	int ret;
 
+	if (!CONFIG_IS_ENABLED(USB_FUNCTION_FASTBOOT)) {
+		pr_err("Fastboot USB not enabled\n");
+		return CMD_RET_FAILURE;
+	}
+
 	if (argc < 2)
 		return CMD_RET_USAGE;
 
@@ -88,10 +94,6 @@
 	g_dnl_clear_detach();
 
 	return ret;
-#else
-	pr_err("Fastboot USB not enabled\n");
-	return CMD_RET_FAILURE;
-#endif
 }
 
 static int do_fastboot(struct cmd_tbl *cmdtp, int flag, int argc,
@@ -148,17 +150,12 @@
 	return do_fastboot_usb(argc, argv, buf_addr, buf_size);
 }
 
-#ifdef CONFIG_SYS_LONGHELP
-static char fastboot_help_text[] =
+U_BOOT_CMD(
+	fastboot, CONFIG_SYS_MAXARGS, 1, do_fastboot,
+	"run as a fastboot usb or udp device",
 	"[-l addr] [-s size] usb <controller> | udp\n"
 	"\taddr - address of buffer used during data transfers ("
 	__stringify(CONFIG_FASTBOOT_BUF_ADDR) ")\n"
 	"\tsize - size of buffer used during data transfers ("
 	__stringify(CONFIG_FASTBOOT_BUF_SIZE) ")"
-	;
-#endif
-
-U_BOOT_CMD(
-	fastboot, CONFIG_SYS_MAXARGS, 1, do_fastboot,
-	"run as a fastboot usb or udp device", fastboot_help_text
 );
diff --git a/cmd/mvebu/comphy_rx_training.c b/cmd/mvebu/comphy_rx_training.c
index 25a9e15..4ee8f54 100644
--- a/cmd/mvebu/comphy_rx_training.c
+++ b/cmd/mvebu/comphy_rx_training.c
@@ -22,7 +22,7 @@
 
 	if (argc != 3) {
 		printf("missing arguments\n");
-		return -1;
+		return CMD_RET_USAGE;
 	}
 
 	cp_index = hextoul(argv[1], NULL);
diff --git a/cmd/spi.c b/cmd/spi.c
index 454ebe3..f30018f 100644
--- a/cmd/spi.c
+++ b/cmd/spi.c
@@ -112,6 +112,9 @@
 
 	if ((flag & CMD_FLAG_REPEAT) == 0)
 	{
+		if (argc < 2)
+			return CMD_RET_USAGE;
+
 		if (argc >= 2) {
 			mode = CONFIG_DEFAULT_SPI_MODE;
 			bus = dectoul(argv[1], &cp);
diff --git a/common/Kconfig b/common/Kconfig
index 8c71d3c..73e3fe3 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -164,6 +164,16 @@
 	  (e.g. NAND). This option makes the value of the 'silent'
 	  environment variable take effect at relocation.
 
+config SILENT_CONSOLE_UNTIL_ENV
+	bool "Keep console silent until environment is loaded"
+	depends on SILENT_CONSOLE
+	help
+	  This option makes sure U-Boot will never use the console unless the
+	  environment from flash does not contain the 'silent' variable.  If
+	  set, the console is kept silent until after the environment was
+	  loaded.  Use this in combination with PRE_CONSOLE_BUFFER to print out
+	  earlier messages after loading the environment when allowed.
+
 config PRE_CONSOLE_BUFFER
 	bool "Buffer characters before the console is available"
 	help
diff --git a/common/autoboot.c b/common/autoboot.c
index ea44fdf..848c33b 100644
--- a/common/autoboot.c
+++ b/common/autoboot.c
@@ -422,7 +422,7 @@
 	return abort;
 }
 
-static void process_fdt_options(const void *blob)
+static void process_fdt_options(void)
 {
 #ifdef CONFIG_TEXT_BASE
 	ulong addr;
@@ -474,7 +474,7 @@
 		s = env_get("bootcmd");
 
 	if (IS_ENABLED(CONFIG_OF_CONTROL))
-		process_fdt_options(gd->fdt_blob);
+		process_fdt_options();
 	stored_bootdelay = bootdelay;
 
 	return s;
diff --git a/common/board_r.c b/common/board_r.c
index 42060ee..3618aca 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -756,9 +756,6 @@
 	initr_status_led,
 #endif
 	/* PPC has a udelay(20) here dating from 2002. Why? */
-#if defined(CONFIG_GPIO_HOG)
-	gpio_hog_probe_all,
-#endif
 #ifdef CONFIG_BOARD_LATE_INIT
 	board_late_init,
 #endif
diff --git a/common/cli.c b/common/cli.c
index a47d6a3..ba45dad 100644
--- a/common/cli.c
+++ b/common/cli.c
@@ -146,7 +146,7 @@
 #if defined(CONFIG_CMD_RUN)
 int do_run(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
 {
-	int i;
+	int i, ret;
 
 	if (argc < 2)
 		return CMD_RET_USAGE;
@@ -160,8 +160,9 @@
 			return 1;
 		}
 
-		if (run_command(arg, flag | CMD_FLAG_ENV) != 0)
-			return 1;
+		ret = run_command(arg, flag | CMD_FLAG_ENV);
+		if (ret)
+			return ret;
 	}
 	return 0;
 }
diff --git a/common/cli_hush.c b/common/cli_hush.c
index a80b847..1ad7a50 100644
--- a/common/cli_hush.c
+++ b/common/cli_hush.c
@@ -1901,7 +1901,7 @@
 			last_return_code = -rcode - 2;
 			return -2;	/* exit */
 		}
-		last_return_code=(rcode == 0) ? 0 : 1;
+		last_return_code = rcode;
 #endif
 #ifndef __U_BOOT__
 		pi->num_progs = save_num_progs; /* restore number of programs */
@@ -3211,7 +3211,15 @@
 					printf("exit not allowed from main input shell.\n");
 					continue;
 				}
-				break;
+				/*
+				 * DANGER
+				 * Return code -2 is special in this context,
+				 * it indicates exit from inner pipe instead
+				 * of return code itself, the return code is
+				 * stored in 'last_return_code' variable!
+				 * DANGER
+				 */
+				return -2;
 			}
 			if (code == -1)
 			    flag_repeat = 0;
@@ -3248,9 +3256,9 @@
 #endif	/* __U_BOOT__ */
 {
 	struct in_str input;
+	int rcode;
 #ifdef __U_BOOT__
 	char *p = NULL;
-	int rcode;
 	if (!s)
 		return 1;
 	if (!*s)
@@ -3262,11 +3270,12 @@
 		setup_string_in_str(&input, p);
 		rcode = parse_stream_outer(&input, flag);
 		free(p);
-		return rcode;
+		return rcode == -2 ? last_return_code : rcode;
 	} else {
 #endif
 	setup_string_in_str(&input, s);
-	return parse_stream_outer(&input, flag);
+	rcode = parse_stream_outer(&input, flag);
+	return rcode == -2 ? last_return_code : rcode;
 #ifdef __U_BOOT__
 	}
 #endif
@@ -3286,7 +3295,7 @@
 	setup_file_in_str(&input);
 #endif
 	rcode = parse_stream_outer(&input, FLAG_PARSE_SEMICOLON);
-	return rcode;
+	return rcode == -2 ? last_return_code : rcode;
 }
 
 #ifdef __U_BOOT__
diff --git a/common/console.c b/common/console.c
index 10ab361..e4301a4 100644
--- a/common/console.c
+++ b/common/console.c
@@ -970,6 +970,11 @@
 	if (!IS_ENABLED(CONFIG_SILENT_CONSOLE))
 		return false;
 
+	if (IS_ENABLED(CONFIG_SILENT_CONSOLE_UNTIL_ENV) && !(gd->flags & GD_FLG_ENV_READY)) {
+		gd->flags |= GD_FLG_SILENT;
+		return false;
+	}
+
 	if (env_get("silent")) {
 		gd->flags |= GD_FLG_SILENT;
 		return false;
diff --git a/common/spl/spl.c b/common/spl/spl.c
index 4668367..a630e79 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -786,9 +786,6 @@
 		}
 	}
 
-	if (CONFIG_IS_ENABLED(GPIO_HOG))
-		gpio_hog_probe_all();
-
 #if CONFIG_IS_ENABLED(BOARD_INIT)
 	spl_board_init();
 #endif
diff --git a/common/spl/spl_ram.c b/common/spl/spl_ram.c
index 5753bd2..8139a20 100644
--- a/common/spl/spl_ram.c
+++ b/common/spl/spl_ram.c
@@ -38,12 +38,13 @@
 			      struct spl_boot_device *bootdev)
 {
 	struct legacy_img_hdr *header;
+	int ret;
 
 	header = (struct legacy_img_hdr *)CONFIG_SPL_LOAD_FIT_ADDRESS;
 
 	if (CONFIG_IS_ENABLED(IMAGE_PRE_LOAD)) {
 		unsigned long addr = (unsigned long)header;
-		int ret = image_pre_load(addr);
+		ret = image_pre_load(addr);
 
 		if (ret)
 			return ret;
@@ -64,7 +65,7 @@
 		debug("Found FIT\n");
 		load.bl_len = 1;
 		load.read = spl_ram_load_read;
-		spl_load_simple_fit(spl_image, &load, 0, header);
+		ret = spl_load_simple_fit(spl_image, &load, 0, header);
 	} else {
 		ulong u_boot_pos = spl_get_image_pos();
 
@@ -85,10 +86,10 @@
 		}
 		header = (struct legacy_img_hdr *)map_sysmem(u_boot_pos, 0);
 
-		spl_parse_image_header(spl_image, bootdev, header);
+		ret = spl_parse_image_header(spl_image, bootdev, header);
 	}
 
-	return 0;
+	return ret;
 }
 #if CONFIG_IS_ENABLED(RAM_DEVICE)
 SPL_LOAD_IMAGE_METHOD("RAM", 0, BOOT_DEVICE_RAM, spl_ram_load_image);
diff --git a/configs/mx6ull_14x14_evk_defconfig b/configs/mx6ull_14x14_evk_defconfig
index 65db621..881bc27 100644
--- a/configs/mx6ull_14x14_evk_defconfig
+++ b/configs/mx6ull_14x14_evk_defconfig
@@ -65,3 +65,7 @@
 CONFIG_FSL_QSPI=y
 CONFIG_SOFT_SPI=y
 CONFIG_IMX_THERMAL=y
+CONFIG_ARCH_MISC_INIT=y
+CONFIG_DM_RNG=y
+CONFIG_CMD_RNG=y
+CONFIG_FSL_DCP_RNG=y
diff --git a/configs/mx6ull_14x14_evk_plugin_defconfig b/configs/mx6ull_14x14_evk_plugin_defconfig
index 55ddd7e..5e67662 100644
--- a/configs/mx6ull_14x14_evk_plugin_defconfig
+++ b/configs/mx6ull_14x14_evk_plugin_defconfig
@@ -64,3 +64,7 @@
 CONFIG_FSL_QSPI=y
 CONFIG_SOFT_SPI=y
 CONFIG_IMX_THERMAL=y
+CONFIG_ARCH_MISC_INIT=y
+CONFIG_DM_RNG=y
+CONFIG_CMD_RNG=y
+CONFIG_FSL_DCP_RNG=y
diff --git a/doc/README.gpio b/doc/README.gpio
index 548ff37..d253f65 100644
--- a/doc/README.gpio
+++ b/doc/README.gpio
@@ -2,10 +2,8 @@
 GPIO hog (CONFIG_GPIO_HOG)
 --------
 
-All the GPIO hog are initialized in gpio_hog_probe_all() function called in
-board_r.c just before board_late_init() but you can also acces directly to
-the gpio with gpio_hog_lookup_name().
-
+All the GPIO hog are initialized using DM_FLAG_PROBE_AFTER_BIND DM flag
+after bind().
 
 Example, for the device tree:
 
diff --git a/doc/android/fastboot.rst b/doc/android/fastboot.rst
index 7611f07..1ad8a89 100644
--- a/doc/android/fastboot.rst
+++ b/doc/android/fastboot.rst
@@ -28,6 +28,7 @@
 - ``oem partconf`` - this executes ``mmc partconf %x <arg> 0`` to configure eMMC
   with <arg> = boot_ack boot_partition
 - ``oem bootbus``  - this executes ``mmc bootbus %x %s`` to configure eMMC
+- ``oem run`` - this executes an arbitrary U-Boot command
 
 Support for both eMMC and NAND devices is included.
 
@@ -227,6 +228,23 @@
 
    Starting kernel ...
 
+Running Shell Commands
+^^^^^^^^^^^^^^^^^^^^^^
+
+Normally, arbitrary U-Boot command execution is not enabled. This is so
+fastboot can be used to update systems using verified boot. However, such
+functionality can be useful for production or when verified boot is not in use.
+Enable ``CONFIG_FASTBOOT_OEM_RUN`` to use this functionality. This will enable
+``oem run`` command, which can be used with the fastboot client. For example,
+to print "Hello at 115200 baud" (or whatever ``CONFIG_BAUDRATE`` is), run::
+
+    $ fastboot oem run:'echo Hello at $baudrate baud'
+
+You can run any command you would normally run on the U-Boot command line,
+including multiple commands (using e.g. ``;`` or ``&&``) and control structures
+(``if``, ``while``, etc.). The exit code of ``fastboot`` will reflect the exit
+code of the command you ran.
+
 References
 ----------
 
diff --git a/doc/board/intel/edison.rst b/doc/board/intel/edison.rst
index 5a65673..782d75a 100644
--- a/doc/board/intel/edison.rst
+++ b/doc/board/intel/edison.rst
@@ -90,7 +90,7 @@
 
 .. code-block:: none
 
-  lsusb | egrep "8087|8086"
+  lsusb | grep -E "8087|8086"
   Bus 001 Device 004: ID 8086:e005 Intel Corp.
 
 If you see a device with the same ID as above, the board is waiting for your
diff --git a/doc/usage/cmd/exit.rst b/doc/usage/cmd/exit.rst
index 769223c..3edb128 100644
--- a/doc/usage/cmd/exit.rst
+++ b/doc/usage/cmd/exit.rst
@@ -37,4 +37,6 @@
 Return value
 ------------
 
-$? is always set to 0 (true).
+$? is default set to 0 (true). In case zero or positive integer parameter
+is passed to the command, the return value is the parameter value. In case
+negative integer parameter is passed to the command, the return value is 0.
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index a063b22..3fe53d6 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -135,6 +135,7 @@
 
 config SATA_SIL
 	bool "Enable Silicon Image SIL3131 / SIL3132 / SIL3124 SATA driver support"
+	depends on PCI
 	select AHCI
 	select LIBATA
 	help
diff --git a/drivers/core/root.c b/drivers/core/root.c
index f24ddfa..c4fb485 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -363,20 +363,22 @@
 
 static int dm_probe_devices(struct udevice *dev, bool pre_reloc_only)
 {
-	u32 mask = DM_FLAG_PROBE_AFTER_BIND;
-	u32 flags = dev_get_flags(dev);
+	ofnode node = dev_ofnode(dev);
 	struct udevice *child;
 	int ret;
 
-	if (pre_reloc_only)
-		mask |= DM_FLAG_PRE_RELOC;
+	if (pre_reloc_only &&
+	    (!ofnode_valid(node) || !ofnode_pre_reloc(node)) &&
+	    !(dev->driver->flags & DM_FLAG_PRE_RELOC))
+		goto probe_children;
 
-	if ((flags & mask) == mask) {
+	if (dev_get_flags(dev) & DM_FLAG_PROBE_AFTER_BIND) {
 		ret = device_probe(dev);
 		if (ret)
 			return ret;
 	}
 
+probe_children:
 	list_for_each_entry(child, &dev->child_head, sibling_node)
 		dm_probe_devices(child, pre_reloc_only);
 
diff --git a/drivers/crypto/fsl/Kconfig b/drivers/crypto/fsl/Kconfig
index b04c701..91a51cc 100644
--- a/drivers/crypto/fsl/Kconfig
+++ b/drivers/crypto/fsl/Kconfig
@@ -73,3 +73,13 @@
 	  reseeded from the TRNG every time random data is generated.
 
 endif
+
+config FSL_DCP_RNG
+	bool "Enable Random Number Generator support"
+	depends on DM_RNG
+	default n
+	help
+	  Enable support for the hardware based random number generator
+	  module of the DCP. It uses the True Random Number Generator (TRNG)
+	  and a Pseudo-Random Number Generator (PRNG) to achieve a true
+	  randomness and cryptographic strength.
diff --git a/drivers/crypto/fsl/Makefile b/drivers/crypto/fsl/Makefile
index f9c3cce..7a2543e 100644
--- a/drivers/crypto/fsl/Makefile
+++ b/drivers/crypto/fsl/Makefile
@@ -7,4 +7,5 @@
 obj-$(CONFIG_CMD_BLOB)$(CONFIG_IMX_CAAM_DEK_ENCAP) += fsl_blob.o
 obj-$(CONFIG_RSA_FREESCALE_EXP) += fsl_rsa.o
 obj-$(CONFIG_FSL_CAAM_RNG) += rng.o
+obj-$(CONFIG_FSL_DCP_RNG) += dcp_rng.o
 obj-$(CONFIG_FSL_MFGPROT) += fsl_mfgprot.o
diff --git a/drivers/crypto/fsl/dcp_rng.c b/drivers/crypto/fsl/dcp_rng.c
new file mode 100644
index 0000000..3170696
--- /dev/null
+++ b/drivers/crypto/fsl/dcp_rng.c
@@ -0,0 +1,182 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * RNG driver for Freescale RNGC
+ *
+ * Copyright 2022 NXP
+ *
+ * Based on RNGC driver in drivers/char/hw_random/imx-rngc.c in Linux
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <dm.h>
+#include <rng.h>
+#include <asm/cache.h>
+#include <asm/io.h>
+#include <dm/root.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+
+#define DCP_RNG_MAX_FIFO_STORE_SIZE	4
+#define RNGC_VER_ID			0x0
+#define RNGC_COMMAND			0x4
+#define RNGC_CONTROL			0x8
+#define RNGC_STATUS			0xC
+#define RNGC_ERROR			0x10
+#define RNGC_FIFO			0x14
+
+/* the fields in the ver id register */
+#define RNGC_TYPE_SHIFT			28
+
+/* the rng_type field */
+#define RNGC_TYPE_RNGB			0x1
+#define RNGC_TYPE_RNGC			0x2
+
+#define RNGC_CMD_CLR_ERR		0x20
+#define RNGC_CMD_SEED			0x2
+
+#define RNGC_CTRL_AUTO_SEED		0x10
+
+#define RNGC_STATUS_ERROR		0x10000
+#define RNGC_STATUS_FIFO_LEVEL_MASK	0xf00
+#define RNGC_STATUS_FIFO_LEVEL_SHIFT	8
+#define RNGC_STATUS_SEED_DONE		0x20
+#define RNGC_STATUS_ST_DONE		0x10
+
+#define RNGC_ERROR_STATUS_STAT_ERR	0x8
+
+#define RNGC_TIMEOUT			3000000U /* 3 sec */
+
+struct imx_rngc_priv {
+	unsigned long base;
+};
+
+static int rngc_read(struct udevice *dev, void *data, size_t len)
+{
+	struct imx_rngc_priv *priv = dev_get_priv(dev);
+	u8 buffer[DCP_RNG_MAX_FIFO_STORE_SIZE];
+	u32 status, level;
+	size_t size;
+
+	while (len) {
+		status = readl(priv->base + RNGC_STATUS);
+
+		/* is there some error while reading this random number? */
+		if (status & RNGC_STATUS_ERROR)
+			break;
+		/* how many random numbers are in FIFO? [0-16] */
+		level = (status & RNGC_STATUS_FIFO_LEVEL_MASK) >>
+			RNGC_STATUS_FIFO_LEVEL_SHIFT;
+
+		if (level) {
+			/* retrieve a random number from FIFO */
+			*(u32 *)buffer = readl(priv->base + RNGC_FIFO);
+			size = min(len, sizeof(u32));
+			memcpy(data, buffer, size);
+			data += size;
+			len -= size;
+		}
+	}
+
+	return len ? -EIO : 0;
+}
+
+static int rngc_init(struct imx_rngc_priv *priv)
+{
+	u32 cmd, ctrl, status, err_reg = 0;
+	unsigned long long timeval = 0;
+	unsigned long long timeout = RNGC_TIMEOUT;
+
+	/* clear error */
+	cmd = readl(priv->base + RNGC_COMMAND);
+	writel(cmd | RNGC_CMD_CLR_ERR, priv->base + RNGC_COMMAND);
+
+	/* create seed, repeat while there is some statistical error */
+	do {
+		/* seed creation */
+		cmd = readl(priv->base + RNGC_COMMAND);
+		writel(cmd | RNGC_CMD_SEED, priv->base + RNGC_COMMAND);
+
+		udelay(1);
+		timeval += 1;
+
+		status = readl(priv->base + RNGC_STATUS);
+		err_reg = readl(priv->base + RNGC_ERROR);
+
+		if (status & (RNGC_STATUS_SEED_DONE | RNGC_STATUS_ST_DONE))
+			break;
+
+		if (timeval > timeout) {
+			debug("rngc timed out\n");
+			return -ETIMEDOUT;
+		}
+	} while (err_reg == RNGC_ERROR_STATUS_STAT_ERR);
+
+	if (err_reg)
+		return -EIO;
+
+	/*
+	 * enable automatic seeding, the rngc creates a new seed automatically
+	 * after serving 2^20 random 160-bit words
+	 */
+	ctrl = readl(priv->base + RNGC_CONTROL);
+	ctrl |= RNGC_CTRL_AUTO_SEED;
+	writel(ctrl, priv->base + RNGC_CONTROL);
+	return 0;
+}
+
+static int rngc_probe(struct udevice *dev)
+{
+	struct imx_rngc_priv *priv = dev_get_priv(dev);
+	fdt_addr_t addr;
+	u32 ver_id;
+	u8  rng_type;
+	int ret;
+
+	addr = dev_read_addr(dev);
+	if (addr == FDT_ADDR_T_NONE) {
+		ret = -EINVAL;
+		goto err;
+	}
+
+	priv->base = addr;
+	ver_id = readl(priv->base + RNGC_VER_ID);
+	rng_type = ver_id >> RNGC_TYPE_SHIFT;
+	/*
+	 * This driver supports only RNGC and RNGB. (There's a different
+	 * driver for RNGA.)
+	 */
+	if (rng_type != RNGC_TYPE_RNGC && rng_type != RNGC_TYPE_RNGB) {
+		ret = -ENODEV;
+		goto err;
+	}
+
+	ret = rngc_init(priv);
+	if (ret)
+		goto err;
+
+	return 0;
+
+err:
+	printf("%s error = %d\n", __func__, ret);
+	return ret;
+}
+
+static const struct dm_rng_ops rngc_ops = {
+	.read = rngc_read,
+};
+
+static const struct udevice_id rngc_dt_ids[] = {
+	{ .compatible = "fsl,imx25-rngb" },
+	{ }
+};
+
+U_BOOT_DRIVER(dcp_rng) = {
+	.name = "dcp_rng",
+	.id = UCLASS_RNG,
+	.of_match = rngc_dt_ids,
+	.ops = &rngc_ops,
+	.probe = rngc_probe,
+	.priv_auto  = sizeof(struct imx_rngc_priv),
+	.flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
diff --git a/drivers/fastboot/Kconfig b/drivers/fastboot/Kconfig
index b97c67b..eefa347 100644
--- a/drivers/fastboot/Kconfig
+++ b/drivers/fastboot/Kconfig
@@ -80,12 +80,13 @@
 	  this to enable the "fastboot flash" command.
 
 config FASTBOOT_UUU_SUPPORT
-	bool "Enable FASTBOOT i.MX UUU special command"
+	bool "Enable UUU support"
 	help
-	  The fastboot protocol includes "UCmd" and "ACmd" command.
-	  Be aware that you provide full access to any U-Boot command,
-	  including working with memory and may open a huge backdoor,
-	  when enabling this option.
+	  This extends the fastboot protocol with the "UCmd" and "ACmd"
+	  commands, which are used by NXP's "universal update utility" (UUU).
+	  These commands allow running any shell command. Do not enable this
+	  feature if you are using verified boot, as it will allow an attacker
+	  to bypass any restrictions you have in place.
 
 choice
 	prompt "Flash provider for FASTBOOT"
@@ -218,6 +219,14 @@
 	  Add support for the "oem bootbus" command from a client. This set
 	  the mmc boot configuration for the selecting eMMC device.
 
+config FASTBOOT_OEM_RUN
+	bool "Enable the 'oem run' command"
+	help
+	  This extends the fastboot protocol with an "oem run" command. This
+	  command allows running arbitrary U-Boot shell commands. Do not enable
+	  this feature if you are using verified boot, as it will allow an
+	  attacker to bypass any restrictions you have in place.
+
 endif # FASTBOOT
 
 endmenu
diff --git a/drivers/fastboot/fb_command.c b/drivers/fastboot/fb_command.c
index bdfdf26..67a9479 100644
--- a/drivers/fastboot/fb_command.c
+++ b/drivers/fastboot/fb_command.c
@@ -31,27 +31,16 @@
 static void okay(char *, char *);
 static void getvar(char *, char *);
 static void download(char *, char *);
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
 static void flash(char *, char *);
 static void erase(char *, char *);
-#endif
 static void reboot_bootloader(char *, char *);
 static void reboot_fastbootd(char *, char *);
 static void reboot_recovery(char *, char *);
-#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
 static void oem_format(char *, char *);
-#endif
-#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_PARTCONF)
 static void oem_partconf(char *, char *);
-#endif
-#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_BOOTBUS)
 static void oem_bootbus(char *, char *);
-#endif
-
-#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
 static void run_ucmd(char *, char *);
 static void run_acmd(char *, char *);
-#endif
 
 static const struct {
 	const char *command;
@@ -65,16 +54,14 @@
 		.command = "download",
 		.dispatch = download
 	},
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
 	[FASTBOOT_COMMAND_FLASH] =  {
 		.command = "flash",
-		.dispatch = flash
+		.dispatch = CONFIG_IS_ENABLED(FASTBOOT_FLASH, (flash), (NULL))
 	},
 	[FASTBOOT_COMMAND_ERASE] =  {
 		.command = "erase",
-		.dispatch = erase
+		.dispatch = CONFIG_IS_ENABLED(FASTBOOT_FLASH, (erase), (NULL))
 	},
-#endif
 	[FASTBOOT_COMMAND_BOOT] =  {
 		.command = "boot",
 		.dispatch = okay
@@ -103,34 +90,30 @@
 		.command = "set_active",
 		.dispatch = okay
 	},
-#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
 	[FASTBOOT_COMMAND_OEM_FORMAT] = {
 		.command = "oem format",
-		.dispatch = oem_format,
+		.dispatch = CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT, (oem_format), (NULL))
 	},
-#endif
-#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_PARTCONF)
 	[FASTBOOT_COMMAND_OEM_PARTCONF] = {
 		.command = "oem partconf",
-		.dispatch = oem_partconf,
+		.dispatch = CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_PARTCONF, (oem_partconf), (NULL))
 	},
-#endif
-#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_BOOTBUS)
 	[FASTBOOT_COMMAND_OEM_BOOTBUS] = {
 		.command = "oem bootbus",
-		.dispatch = oem_bootbus,
+		.dispatch = CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_BOOTBUS, (oem_bootbus), (NULL))
 	},
-#endif
-#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
+	[FASTBOOT_COMMAND_OEM_RUN] = {
+		.command = "oem run",
+		.dispatch = CONFIG_IS_ENABLED(FASTBOOT_OEM_RUN, (run_ucmd), (NULL))
+	},
 	[FASTBOOT_COMMAND_UCMD] = {
 		.command = "UCmd",
-		.dispatch = run_ucmd,
+		.dispatch = CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT, (run_ucmd), (NULL))
 	},
 	[FASTBOOT_COMMAND_ACMD] = {
 		.command = "ACmd",
-		.dispatch = run_acmd,
+		.dispatch = CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT, (run_acmd), (NULL))
 	},
-#endif
 };
 
 /**
@@ -156,7 +139,9 @@
 							response);
 				return i;
 			} else {
-				break;
+				pr_err("command %s not supported.\n", cmd_string);
+				fastboot_fail("Unsupported command", response);
+				return -1;
 			}
 		}
 	}
@@ -299,7 +284,6 @@
 	fastboot_bytes_received = 0;
 }
 
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
 /**
  * flash() - write the downloaded image to the indicated partition.
  *
@@ -309,16 +293,15 @@
  * Writes the previously downloaded image to the partition indicated by
  * cmd_parameter. Writes to response.
  */
-static void flash(char *cmd_parameter, char *response)
+static void __maybe_unused flash(char *cmd_parameter, char *response)
 {
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
-	fastboot_mmc_flash_write(cmd_parameter, fastboot_buf_addr, image_size,
-				 response);
-#endif
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
-	fastboot_nand_flash_write(cmd_parameter, fastboot_buf_addr, image_size,
-				  response);
-#endif
+	if (CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC))
+		fastboot_mmc_flash_write(cmd_parameter, fastboot_buf_addr,
+					 image_size, response);
+
+	if (CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND))
+		fastboot_nand_flash_write(cmd_parameter, fastboot_buf_addr,
+					  image_size, response);
 }
 
 /**
@@ -330,25 +313,22 @@
  * Erases the partition indicated by cmd_parameter (clear to 0x00s). Writes
  * to response.
  */
-static void erase(char *cmd_parameter, char *response)
+static void __maybe_unused erase(char *cmd_parameter, char *response)
 {
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
-	fastboot_mmc_erase(cmd_parameter, response);
-#endif
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
-	fastboot_nand_erase(cmd_parameter, response);
-#endif
-}
-#endif
+	if (CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC))
+		fastboot_mmc_erase(cmd_parameter, response);
 
-#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
+	if (CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND))
+		fastboot_nand_erase(cmd_parameter, response);
+}
+
 /**
  * run_ucmd() - Execute the UCmd command
  *
  * @cmd_parameter: Pointer to command parameter
  * @response: Pointer to fastboot response buffer
  */
-static void run_ucmd(char *cmd_parameter, char *response)
+static void __maybe_unused run_ucmd(char *cmd_parameter, char *response)
 {
 	if (!cmd_parameter) {
 		pr_err("missing slot suffix\n");
@@ -375,7 +355,7 @@
  * @cmd_parameter: Pointer to command parameter
  * @response: Pointer to fastboot response buffer
  */
-static void run_acmd(char *cmd_parameter, char *response)
+static void __maybe_unused run_acmd(char *cmd_parameter, char *response)
 {
 	if (!cmd_parameter) {
 		pr_err("missing slot suffix\n");
@@ -392,7 +372,6 @@
 	strcpy(g_a_cmd_buff, cmd_parameter);
 	fastboot_okay(NULL, response);
 }
-#endif
 
 /**
  * reboot_bootloader() - Sets reboot bootloader flag.
@@ -436,40 +415,40 @@
 		fastboot_okay(NULL, response);
 }
 
-#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
 /**
  * oem_format() - Execute the OEM format command
  *
  * @cmd_parameter: Pointer to command parameter
  * @response: Pointer to fastboot response buffer
  */
-static void oem_format(char *cmd_parameter, char *response)
+static void __maybe_unused oem_format(char *cmd_parameter, char *response)
 {
 	char cmdbuf[32];
+	const int mmc_dev = config_opt_enabled(CONFIG_FASTBOOT_FLASH_MMC,
+					       CONFIG_FASTBOOT_FLASH_MMC_DEV, -1);
 
 	if (!env_get("partitions")) {
 		fastboot_fail("partitions not set", response);
 	} else {
-		sprintf(cmdbuf, "gpt write mmc %x $partitions",
-			CONFIG_FASTBOOT_FLASH_MMC_DEV);
+		sprintf(cmdbuf, "gpt write mmc %x $partitions", mmc_dev);
 		if (run_command(cmdbuf, 0))
 			fastboot_fail("", response);
 		else
 			fastboot_okay(NULL, response);
 	}
 }
-#endif
 
-#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_PARTCONF)
 /**
  * oem_partconf() - Execute the OEM partconf command
  *
  * @cmd_parameter: Pointer to command parameter
  * @response: Pointer to fastboot response buffer
  */
-static void oem_partconf(char *cmd_parameter, char *response)
+static void __maybe_unused oem_partconf(char *cmd_parameter, char *response)
 {
 	char cmdbuf[32];
+	const int mmc_dev = config_opt_enabled(CONFIG_FASTBOOT_FLASH_MMC,
+					       CONFIG_FASTBOOT_FLASH_MMC_DEV, -1);
 
 	if (!cmd_parameter) {
 		fastboot_fail("Expected command parameter", response);
@@ -477,26 +456,25 @@
 	}
 
 	/* execute 'mmc partconfg' command with cmd_parameter arguments*/
-	snprintf(cmdbuf, sizeof(cmdbuf), "mmc partconf %x %s 0",
-		 CONFIG_FASTBOOT_FLASH_MMC_DEV, cmd_parameter);
+	snprintf(cmdbuf, sizeof(cmdbuf), "mmc partconf %x %s 0", mmc_dev, cmd_parameter);
 	printf("Execute: %s\n", cmdbuf);
 	if (run_command(cmdbuf, 0))
 		fastboot_fail("Cannot set oem partconf", response);
 	else
 		fastboot_okay(NULL, response);
 }
-#endif
 
-#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_BOOTBUS)
 /**
  * oem_bootbus() - Execute the OEM bootbus command
  *
  * @cmd_parameter: Pointer to command parameter
  * @response: Pointer to fastboot response buffer
  */
-static void oem_bootbus(char *cmd_parameter, char *response)
+static void __maybe_unused oem_bootbus(char *cmd_parameter, char *response)
 {
 	char cmdbuf[32];
+	const int mmc_dev = config_opt_enabled(CONFIG_FASTBOOT_FLASH_MMC,
+					       CONFIG_FASTBOOT_FLASH_MMC_DEV, -1);
 
 	if (!cmd_parameter) {
 		fastboot_fail("Expected command parameter", response);
@@ -504,12 +482,10 @@
 	}
 
 	/* execute 'mmc bootbus' command with cmd_parameter arguments*/
-	snprintf(cmdbuf, sizeof(cmdbuf), "mmc bootbus %x %s",
-		 CONFIG_FASTBOOT_FLASH_MMC_DEV, cmd_parameter);
+	snprintf(cmdbuf, sizeof(cmdbuf), "mmc bootbus %x %s", mmc_dev, cmd_parameter);
 	printf("Execute: %s\n", cmdbuf);
 	if (run_command(cmdbuf, 0))
 		fastboot_fail("Cannot set oem bootbus", response);
 	else
 		fastboot_okay(NULL, response);
 }
-#endif
diff --git a/drivers/fastboot/fb_common.c b/drivers/fastboot/fb_common.c
index ef399d0..7563650 100644
--- a/drivers/fastboot/fb_common.c
+++ b/drivers/fastboot/fb_common.c
@@ -91,20 +91,21 @@
  */
 int __weak fastboot_set_reboot_flag(enum fastboot_reboot_reason reason)
 {
-#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
 	static const char * const boot_cmds[] = {
 		[FASTBOOT_REBOOT_REASON_BOOTLOADER] = "bootonce-bootloader",
 		[FASTBOOT_REBOOT_REASON_FASTBOOTD] = "boot-fastboot",
 		[FASTBOOT_REBOOT_REASON_RECOVERY] = "boot-recovery"
 	};
+	const int mmc_dev = config_opt_enabled(CONFIG_FASTBOOT_FLASH_MMC,
+					       CONFIG_FASTBOOT_FLASH_MMC_DEV, -1);
+
+	if (!CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC))
+		return -EINVAL;
 
 	if (reason >= FASTBOOT_REBOOT_REASONS_COUNT)
 		return -EINVAL;
 
-	return bcb_write_reboot_reason(CONFIG_FASTBOOT_FLASH_MMC_DEV, "misc", boot_cmds[reason]);
-#else
-    return -EINVAL;
-#endif
+	return bcb_write_reboot_reason(mmc_dev, "misc", boot_cmds[reason]);
 }
 
 /**
diff --git a/drivers/fastboot/fb_getvar.c b/drivers/fastboot/fb_getvar.c
index 018989d..2fbd285 100644
--- a/drivers/fastboot/fb_getvar.c
+++ b/drivers/fastboot/fb_getvar.c
@@ -21,15 +21,9 @@
 static void getvar_product(char *var_parameter, char *response);
 static void getvar_platform(char *var_parameter, char *response);
 static void getvar_current_slot(char *var_parameter, char *response);
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
 static void getvar_has_slot(char *var_parameter, char *response);
-#endif
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
 static void getvar_partition_type(char *part_name, char *response);
-#endif
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
 static void getvar_partition_size(char *part_name, char *response);
-#endif
 static void getvar_is_userspace(char *var_parameter, char *response);
 
 static const struct {
@@ -84,7 +78,6 @@
 	}
 };
 
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
 /**
  * Get partition number and size for any storage type.
  *
@@ -102,28 +95,26 @@
 				size_t *size)
 {
 	int r;
-# if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
 	struct blk_desc *dev_desc;
-	struct disk_partition part_info;
-
-	r = fastboot_mmc_get_part_info(part_name, &dev_desc, &part_info,
-				       response);
-	if (r >= 0 && size)
-		*size = part_info.size * part_info.blksz;
-# elif CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
+	struct disk_partition disk_part;
 	struct part_info *part_info;
 
-	r = fastboot_nand_get_part_info(part_name, &part_info, response);
-	if (r >= 0 && size)
-		*size = part_info->size;
-# else
-	fastboot_fail("this storage is not supported in bootloader", response);
-	r = -ENODEV;
-# endif
+	if (CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)) {
+		r = fastboot_mmc_get_part_info(part_name, &dev_desc, &disk_part,
+					       response);
+		if (r >= 0 && size)
+			*size = disk_part.size * disk_part.blksz;
+	} else if (CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)) {
+		r = fastboot_nand_get_part_info(part_name, &part_info, response);
+		if (r >= 0 && size)
+			*size = part_info->size;
+	} else {
+		fastboot_fail("this storage is not supported in bootloader", response);
+		r = -ENODEV;
+	}
 
 	return r;
 }
-#endif
 
 static void getvar_version(char *var_parameter, char *response)
 {
@@ -181,8 +172,7 @@
 	fastboot_okay("a", response);
 }
 
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
-static void getvar_has_slot(char *part_name, char *response)
+static void __maybe_unused getvar_has_slot(char *part_name, char *response)
 {
 	char part_name_wslot[PART_NAME_LEN];
 	size_t len;
@@ -213,10 +203,8 @@
 fail:
 	fastboot_fail("invalid partition name", response);
 }
-#endif
 
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
-static void getvar_partition_type(char *part_name, char *response)
+static void __maybe_unused getvar_partition_type(char *part_name, char *response)
 {
 	int r;
 	struct blk_desc *dev_desc;
@@ -232,10 +220,8 @@
 			fastboot_okay(fs_get_type_name(), response);
 	}
 }
-#endif
 
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
-static void getvar_partition_size(char *part_name, char *response)
+static void __maybe_unused getvar_partition_size(char *part_name, char *response)
 {
 	int r;
 	size_t size;
@@ -244,7 +230,6 @@
 	if (r >= 0)
 		fastboot_response("OKAY", response, "0x%016zx", size);
 }
-#endif
 
 static void getvar_is_userspace(char *var_parameter, char *response)
 {
diff --git a/drivers/fpga/socfpga_arria10.c b/drivers/fpga/socfpga_arria10.c
index 3b785e6..96b1950 100644
--- a/drivers/fpga/socfpga_arria10.c
+++ b/drivers/fpga/socfpga_arria10.c
@@ -777,42 +777,20 @@
 {
 	struct fpga_loadfs_info fpga_loadfs;
 	struct udevice *dev;
-	int status, ret, size;
+	int status, ret;
 	u32 buffer = (uintptr_t)buf;
 	size_t buffer_sizebytes = bsize;
 	size_t buffer_sizebytes_ori = bsize;
 	size_t total_sizeof_image = 0;
 	ofnode node;
-	const fdt32_t *phandle_p;
-	u32 phandle;
 
 	node = get_fpga_mgr_ofnode(ofnode_null());
-
-	if (ofnode_valid(node)) {
-		phandle_p = ofnode_get_property(node, "firmware-loader", &size);
-		if (!phandle_p) {
-			node = ofnode_path("/chosen");
-			if (!ofnode_valid(node)) {
-				debug("FPGA: /chosen node was not found.\n");
-				return -ENOENT;
-			}
-
-			phandle_p = ofnode_get_property(node, "firmware-loader",
-						       &size);
-			if (!phandle_p) {
-				debug("FPGA: firmware-loader property was not");
-				debug(" found.\n");
-				return -ENOENT;
-			}
-		}
-	} else {
+	if (!ofnode_valid(node)) {
 		debug("FPGA: FPGA manager node was not found.\n");
 		return -ENOENT;
 	}
 
-	phandle = fdt32_to_cpu(*phandle_p);
-	ret = uclass_get_device_by_phandle_id(UCLASS_FS_FIRMWARE_LOADER,
-					     phandle, &dev);
+	ret = get_fs_loader(&dev);
 	if (ret)
 		return ret;
 
diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index 3a6ef3b..dbebf3a 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -311,34 +311,11 @@
 	return 0;
 }
 
-int gpio_hog_probe_all(void)
-{
-	struct udevice *dev;
-	int ret;
-	int retval = 0;
-
-	for (uclass_first_device(UCLASS_NOP, &dev);
-	     dev;
-	     uclass_find_next_device(&dev)) {
-		if (dev->driver == DM_DRIVER_GET(gpio_hog)) {
-			ret = device_probe(dev);
-			if (ret) {
-				printf("Failed to probe device %s err: %d\n",
-				       dev->name, ret);
-				retval = ret;
-			}
-		}
-	}
-
-	return retval;
-}
-
 int gpio_hog_lookup_name(const char *name, struct gpio_desc **desc)
 {
 	struct udevice *dev;
 
 	*desc = NULL;
-	gpio_hog_probe_all();
 	if (!uclass_get_device_by_name(UCLASS_NOP, name, &dev)) {
 		struct gpio_hog_priv *priv = dev_get_priv(dev);
 
@@ -1505,9 +1482,17 @@
 								 &child);
 				if (ret)
 					return ret;
+
+				/*
+				 * Make sure gpio-hogs are probed after bind
+				 * since hogs can be essential to the hardware
+				 * system.
+				 */
+				dev_or_flags(child, DM_FLAG_PROBE_AFTER_BIND);
 			}
 		}
 	}
+
 	return 0;
 }
 
diff --git a/drivers/misc/fs_loader.c b/drivers/misc/fs_loader.c
index 5b4d036..ccf5c7a 100644
--- a/drivers/misc/fs_loader.c
+++ b/drivers/misc/fs_loader.c
@@ -15,6 +15,8 @@
 #include <fs_loader.h>
 #include <log.h>
 #include <asm/global_data.h>
+#include <dm/device-internal.h>
+#include <dm/root.h>
 #include <linux/string.h>
 #include <mapmem.h>
 #include <malloc.h>
@@ -297,6 +299,31 @@
 	.priv_auto	= sizeof(struct firmware),
 };
 
+static struct device_plat default_plat = { 0 };
+
+int get_fs_loader(struct udevice **dev)
+{
+	int ret;
+	ofnode node = ofnode_get_chosen_node("firmware-loader");
+
+	if (ofnode_valid(node))
+		return uclass_get_device_by_ofnode(UCLASS_FS_FIRMWARE_LOADER,
+						   node, dev);
+
+	/* Try the first device if none was chosen */
+	ret = uclass_first_device_err(UCLASS_FS_FIRMWARE_LOADER, dev);
+	if (ret != -ENODEV)
+		return ret;
+
+	/* Just create a new device */
+	ret = device_bind(dm_root(), DM_DRIVER_GET(fs_loader), "default-loader",
+			  &default_plat, ofnode_null(), dev);
+	if (ret)
+		return ret;
+
+	return device_probe(*dev);
+}
+
 UCLASS_DRIVER(fs_loader) = {
 	.id		= UCLASS_FS_FIRMWARE_LOADER,
 	.name		= "fs-loader",
diff --git a/drivers/net/fm/fm.c b/drivers/net/fm/fm.c
index 055dd61..e1fba24 100644
--- a/drivers/net/fm/fm.c
+++ b/drivers/net/fm/fm.c
@@ -5,9 +5,11 @@
  */
 #include <common.h>
 #include <env.h>
+#include <fs_loader.h>
 #include <image.h>
 #include <malloc.h>
 #include <asm/io.h>
+#include <dm/device_compat.h>
 #include <linux/errno.h>
 #include <u-boot/crc.h>
 #include <dm.h>
@@ -353,7 +355,7 @@
 
 /* Init common part of FM, index is fm num# like fm as above */
 #ifdef CONFIG_TFABOOT
-int fm_init_common(int index, struct ccsr_fman *reg)
+int fm_init_common(int index, struct ccsr_fman *reg, const char *firmware_name)
 {
 	int rc;
 	void *addr = NULL;
@@ -448,10 +450,32 @@
 	return fm_init_bmi(index, &reg->fm_bmi_common);
 }
 #else
-int fm_init_common(int index, struct ccsr_fman *reg)
+int fm_init_common(int index, struct ccsr_fman *reg, const char *firmware_name)
 {
 	int rc;
-#if defined(CONFIG_SYS_QE_FMAN_FW_IN_NOR)
+#if defined(CONFIG_SYS_QE_FMAN_FW_IN_FS)
+	struct udevice *fs_loader;
+	void *addr = malloc(CONFIG_SYS_QE_FMAN_FW_LENGTH);
+
+	if (!addr)
+		return -ENOMEM;
+
+	rc = get_fs_loader(&fs_loader);
+	if (rc) {
+		debug("could not get fs loader: %d\n", rc);
+		return rc;
+	}
+
+	if (!firmware_name)
+		firmware_name = "fman.itb";
+
+	rc = request_firmware_into_buf(fs_loader, firmware_name, addr,
+				       CONFIG_SYS_QE_FMAN_FW_LENGTH, 0);
+	if (rc < 0) {
+		debug("could not request %s: %d\n", firmware_name, rc);
+		return rc;
+	}
+#elif defined(CONFIG_SYS_QE_FMAN_FW_IN_NOR)
 	void *addr = (void *)CONFIG_SYS_FMAN_FW_ADDR;
 #elif defined(CONFIG_SYS_QE_FMAN_FW_IN_NAND)
 	size_t fw_length = CONFIG_SYS_QE_FMAN_FW_LENGTH;
@@ -561,6 +585,8 @@
 
 static int fman_probe(struct udevice *dev)
 {
+	const char *firmware_name = NULL;
+	int ret;
 	struct fman_priv *priv = dev_get_priv(dev);
 
 	priv->reg = (struct ccsr_fman *)(uintptr_t)dev_read_addr(dev);
@@ -570,7 +596,13 @@
 		return -EINVAL;
 	}
 
-	return fm_init_common(priv->fman_id, priv->reg);
+	ret = dev_read_string_index(dev, "firmware-name", 0, &firmware_name);
+	if (ret && ret != -EINVAL) {
+		dev_dbg(dev, "Could not read firmware-name\n");
+		return ret;
+	}
+
+	return fm_init_common(priv->fman_id, priv->reg, firmware_name);
 }
 
 static int fman_remove(struct udevice *dev)
diff --git a/drivers/net/fm/fm.h b/drivers/net/fm/fm.h
index ba858cc..a2d5b03 100644
--- a/drivers/net/fm/fm.h
+++ b/drivers/net/fm/fm.h
@@ -106,7 +106,7 @@
 
 void *fm_muram_alloc(int fm_idx, size_t size, ulong align);
 void *fm_muram_base(int fm_idx);
-int fm_init_common(int index, struct ccsr_fman *reg);
+int fm_init_common(int index, struct ccsr_fman *reg, const char *firmware_name);
 int fm_eth_initialize(struct ccsr_fman *reg, struct fm_eth_info *info);
 phy_interface_t fman_port_enet_if(enum fm_port port);
 void fman_disable_port(enum fm_port port);
diff --git a/drivers/qe/Kconfig b/drivers/qe/Kconfig
index c44a81f..89a75c1 100644
--- a/drivers/qe/Kconfig
+++ b/drivers/qe/Kconfig
@@ -27,6 +27,10 @@
 	depends on FMAN_ENET || QE
 	default SYS_QE_FMAN_FW_IN_ROM
 
+config SYS_QE_FMAN_FW_IN_FS
+	depends on FS_LOADER && FMAN_ENET
+	bool "Filesystem"
+
 config SYS_QE_FMAN_FW_IN_NOR
 	bool "NOR flash"
 
diff --git a/drivers/reboot-mode/Kconfig b/drivers/reboot-mode/Kconfig
index 63ea18c..d57baac 100644
--- a/drivers/reboot-mode/Kconfig
+++ b/drivers/reboot-mode/Kconfig
@@ -30,4 +30,11 @@
 		a device in a specific mode by using a register(s) that can be controlled
 		outside U-Boot (e.g. Kernel).
 
+config REBOOT_MODE_NVMEM
+	bool "Use NVMEM reboot mode"
+	depends on DM_REBOOT_MODE && NVMEM
+	help
+	  Use any kind of non-volatile memory (EEPROM, RTC, etc) to control the
+	  reboot mode.
+
 endmenu
diff --git a/drivers/reboot-mode/Makefile b/drivers/reboot-mode/Makefile
index 2c13780..48c8ab7 100644
--- a/drivers/reboot-mode/Makefile
+++ b/drivers/reboot-mode/Makefile
@@ -7,3 +7,4 @@
 obj-$(CONFIG_DM_REBOOT_MODE) += reboot-mode-uclass.o
 obj-$(CONFIG_DM_REBOOT_MODE_GPIO) += reboot-mode-gpio.o
 obj-$(CONFIG_DM_REBOOT_MODE_RTC) += reboot-mode-rtc.o
+obj-$(CONFIG_REBOOT_MODE_NVMEM) += reboot-mode-nvmem.o
diff --git a/drivers/reboot-mode/reboot-mode-nvmem.c b/drivers/reboot-mode/reboot-mode-nvmem.c
new file mode 100644
index 0000000..da41ca4
--- /dev/null
+++ b/drivers/reboot-mode/reboot-mode-nvmem.c
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2022 Sean Anderson <sean.anderson@seco.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <nvmem.h>
+#include <reboot-mode/reboot-mode.h>
+
+/**
+ * struct nvmem_reboot_mode_priv - Private data for the nvmem reboot mode device
+ * @cell: The nvmem cell to store the mode in
+ */
+struct nvmem_reboot_mode_priv {
+	struct nvmem_cell cell;
+};
+
+static int reboot_mode_get(struct udevice *dev, u32 *mode)
+{
+	struct nvmem_reboot_mode_priv *priv = dev_get_priv(dev);
+
+	return nvmem_cell_read(&priv->cell, mode, sizeof(*mode));
+}
+
+static int reboot_mode_set(struct udevice *dev, u32 mode)
+{
+	struct nvmem_reboot_mode_priv *priv = dev_get_priv(dev);
+
+	return nvmem_cell_write(&priv->cell, &mode, sizeof(mode));
+}
+
+static const struct reboot_mode_ops nvmem_reboot_mode_ops = {
+	.get = reboot_mode_get,
+	.set = reboot_mode_set,
+};
+
+static int reboot_mode_probe(struct udevice *dev)
+{
+	struct nvmem_reboot_mode_priv *priv = dev_get_priv(dev);
+
+	return nvmem_cell_get_by_name(dev, "reboot-mode", &priv->cell);
+}
+
+static const struct udevice_id nvmem_reboot_mode_ids[] = {
+	{ .compatible = "nvmem-reboot-mode" },
+	{ }
+};
+
+U_BOOT_DRIVER(nvmem_reboot_mode) = {
+	.name = "nvmem-reboot-mode",
+	.id = UCLASS_REBOOT_MODE,
+	.of_match = nvmem_reboot_mode_ids,
+	.probe = reboot_mode_probe,
+	.priv_auto = sizeof(struct nvmem_reboot_mode_priv),
+	.ops = &nvmem_reboot_mode_ops,
+};
diff --git a/drivers/rtc/abx80x.c b/drivers/rtc/abx80x.c
index 528b06c..823aff0 100644
--- a/drivers/rtc/abx80x.c
+++ b/drivers/rtc/abx80x.c
@@ -17,6 +17,7 @@
 #include <i2c.h>
 #include <rtc.h>
 #include <log.h>
+#include <linux/bitfield.h>
 
 #define ABX8XX_REG_HTH		0x00
 #define ABX8XX_REG_SC		0x01
@@ -88,6 +89,16 @@
 #define ABX8XX_TRICKLE_STANDARD_DIODE	0x8
 #define ABX8XX_TRICKLE_SCHOTTKY_DIODE	0x4
 
+#define ABX8XX_REG_EXTRAM	0x3f
+#define ABX8XX_EXTRAM_XADS	GENMASK(1, 0)
+
+#define ABX8XX_SRAM_BASE	0x40
+#define ABX8XX_SRAM_WIN_SIZE	0x40U
+#define ABX8XX_RAM_SIZE		256
+
+#define RAM_ADDR_LOWER		GENMASK(5, 0)
+#define RAM_ADDR_UPPER		GENMASK(7, 6)
+
 static u8 trickle_resistors[] = {0, 3, 6, 11};
 
 enum abx80x_chip {AB0801, AB0803, AB0804, AB0805,
@@ -112,29 +123,52 @@
 	[ABX80X] = {.pn = 0}
 };
 
-static int abx80x_rtc_read8(struct udevice *dev, unsigned int reg)
+static int abx80x_rtc_xfer(struct udevice *dev, unsigned int offset,
+			   u8 *val, unsigned int bytes, bool write)
 {
-	int ret = 0;
-	u8 buf;
+	int ret;
 
-	if (reg > 0xff)
+	if (offset + bytes > ABX8XX_RAM_SIZE)
 		return -EINVAL;
 
-	ret = dm_i2c_read(dev, reg, &buf, sizeof(buf));
-	if (ret < 0)
-		return ret;
+	while (bytes) {
+		u8 extram, reg, len, lower, upper;
 
-	return buf;
+		lower = FIELD_GET(RAM_ADDR_LOWER, offset);
+		upper = FIELD_GET(RAM_ADDR_UPPER, offset);
+		extram = FIELD_PREP(ABX8XX_EXTRAM_XADS, upper);
+		reg = ABX8XX_SRAM_BASE + lower;
+		len = min(lower + bytes, ABX8XX_SRAM_WIN_SIZE) - lower;
+
+		ret = dm_i2c_reg_write(dev, ABX8XX_REG_EXTRAM, extram);
+		if (ret)
+			return ret;
+
+		if (write)
+			ret = dm_i2c_write(dev, reg, val, len);
+		else
+			ret = dm_i2c_read(dev, reg, val, len);
+		if (ret)
+			return ret;
+
+		offset += len;
+		val += len;
+		bytes -= len;
+	}
+
+	return 0;
 }
 
-static int abx80x_rtc_write8(struct udevice *dev, unsigned int reg, int val)
+static int abx80x_rtc_read(struct udevice *dev, unsigned int offset, u8 *val,
+			   unsigned int bytes)
 {
-	u8 buf = (u8)val;
+	return abx80x_rtc_xfer(dev, offset, val, bytes, false);
+}
 
-	if (reg > 0xff)
-		return -EINVAL;
-
-	return dm_i2c_write(dev, reg, &buf, sizeof(buf));
+static int abx80x_rtc_write(struct udevice *dev, unsigned int offset,
+			    const u8 *val, unsigned int bytes)
+{
+	return abx80x_rtc_xfer(dev, offset, (u8 *)val, bytes, true);
 }
 
 static int abx80x_is_rc_mode(struct udevice *dev)
@@ -334,9 +368,9 @@
 static const struct rtc_ops abx80x_rtc_ops = {
 	.get	= abx80x_rtc_read_time,
 	.set	= abx80x_rtc_set_time,
-	.reset  = abx80x_rtc_reset,
-	.read8  = abx80x_rtc_read8,
-	.write8 = abx80x_rtc_write8
+	.reset	= abx80x_rtc_reset,
+	.read	= abx80x_rtc_read,
+	.write	= abx80x_rtc_write,
 };
 
 static int abx80x_dt_trickle_cfg(struct udevice *dev)
diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
index b21031d..a813a84 100644
--- a/drivers/tee/optee/core.c
+++ b/drivers/tee/optee/core.c
@@ -92,7 +92,8 @@
 		if (!service)
 			continue;
 
-		ret = device_bind_driver(dev, service->driver_name, service->driver_name, NULL);
+		ret = device_bind_driver_to_node(dev, service->driver_name, service->driver_name,
+						 dev_ofnode(dev), NULL);
 		if (ret) {
 			dev_warn(dev, "%s was not bound: %d, ignored\n", service->driver_name, ret);
 			continue;
@@ -846,7 +847,8 @@
 		 * Discovery of TAs on the TEE bus is not supported in U-Boot:
 		 * only bind the drivers associated to the supported OP-TEE TA
 		 */
-		ret = device_bind_driver(dev, "optee-rng", "optee-rng", NULL);
+		ret = device_bind_driver_to_node(dev, "optee-rng", "optee-rng",
+						 dev_ofnode(dev), NULL);
 		if (ret)
 			dev_warn(dev, "ftpm_tee failed to bind: %d\n", ret);
 	}
diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
index 07b1681..c6e7f42 100644
--- a/drivers/usb/gadget/f_fastboot.c
+++ b/drivers/usb/gadget/f_fastboot.c
@@ -495,7 +495,6 @@
 	do_exit_on_complete(ep, req);
 }
 
-#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
 static void do_acmd_complete(struct usb_ep *ep, struct usb_request *req)
 {
 	/* When usb dequeue complete will be called
@@ -505,7 +504,6 @@
 	if (req->status == 0)
 		fastboot_acmd_complete();
 }
-#endif
 
 static void rx_handler_command(struct usb_ep *ep, struct usb_request *req)
 {
@@ -546,11 +544,10 @@
 			fastboot_func->in_req->complete = compl_do_reset;
 			g_dnl_trigger_detach();
 			break;
-#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
 		case FASTBOOT_COMMAND_ACMD:
-			fastboot_func->in_req->complete = do_acmd_complete;
+			if (CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT))
+				fastboot_func->in_req->complete = do_acmd_complete;
 			break;
-#endif
 		}
 	}
 
diff --git a/env/env.c b/env/env.c
index 69848fb..06078c7 100644
--- a/env/env.c
+++ b/env/env.c
@@ -311,11 +311,15 @@
 	if (drv) {
 		int ret;
 
-		if (!drv->erase)
+		if (!drv->erase) {
+			printf("not possible\n");
 			return -ENODEV;
+		}
 
-		if (!env_has_inited(drv->location))
+		if (!env_has_inited(drv->location)) {
+			printf("not initialized\n");
 			return -ENODEV;
+		}
 
 		printf("Erasing Environment on %s... ", drv->name);
 		ret = drv->erase();
diff --git a/env/ubi.c b/env/ubi.c
index eb21c4f..445d34f 100644
--- a/env/ubi.c
+++ b/env/ubi.c
@@ -28,6 +28,12 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#if CONFIG_SYS_REDUNDAND_ENVIRONMENT
+#define ENV_UBI_VOLUME_REDUND CONFIG_ENV_UBI_VOLUME_REDUND
+#else
+#define ENV_UBI_VOLUME_REDUND "invalid"
+#endif
+
 #ifdef CONFIG_CMD_SAVEENV
 #ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
 static int env_ubi_save(void)
@@ -177,9 +183,43 @@
 }
 #endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */
 
+static int env_ubi_erase(void)
+{
+	ALLOC_CACHE_ALIGN_BUFFER(char, env_buf, CONFIG_ENV_SIZE);
+	int ret = 0;
+
+	if (ubi_part(CONFIG_ENV_UBI_PART, UBI_VID_OFFSET)) {
+		printf("\n** Cannot find mtd partition \"%s\"\n",
+		       CONFIG_ENV_UBI_PART);
+		return 1;
+	}
+
+	memset(env_buf, 0x0, CONFIG_ENV_SIZE);
+
+	if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME,
+			     (void *)env_buf, CONFIG_ENV_SIZE)) {
+		printf("\n** Unable to erase env to %s:%s **\n",
+		       CONFIG_ENV_UBI_PART,
+		       CONFIG_ENV_UBI_VOLUME);
+		ret = 1;
+	}
+	if (IS_ENABLED(CONFIG_SYS_REDUNDAND_ENVIRONMENT)) {
+		if (ubi_volume_write(ENV_UBI_VOLUME_REDUND,
+				     (void *)env_buf, CONFIG_ENV_SIZE)) {
+			printf("\n** Unable to erase env to %s:%s **\n",
+			       CONFIG_ENV_UBI_PART,
+			       ENV_UBI_VOLUME_REDUND);
+			ret = 1;
+		}
+	}
+
+	return ret;
+}
+
 U_BOOT_ENV_LOCATION(ubi) = {
 	.location	= ENVL_UBI,
 	ENV_NAME("UBI")
 	.load		= env_ubi_load,
 	.save		= env_save_ptr(env_ubi_save),
+	.erase		= ENV_ERASE_PTR(env_ubi_erase),
 };
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 3f0d9f1..7eaa7e9 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -541,34 +541,39 @@
 int read_extent_data(struct btrfs_fs_info *fs_info, char *data, u64 logical,
 		     u64 *len, int mirror)
 {
-	u64 offset = 0;
+	u64 orig_len = *len;
+	u64 cur = logical;
 	struct btrfs_multi_bio *multi = NULL;
 	struct btrfs_device *device;
 	int ret = 0;
-	u64 max_len = *len;
 
-	ret = btrfs_map_block(fs_info, READ, logical, len, &multi, mirror,
-			      NULL);
-	if (ret) {
-		fprintf(stderr, "Couldn't map the block %llu\n",
-				logical + offset);
-		goto err;
-	}
-	device = multi->stripes[0].dev;
+	while (cur < logical + orig_len) {
+		u64 cur_len = logical + orig_len - cur;
 
-	if (*len > max_len)
-		*len = max_len;
-	if (!device->desc || !device->part) {
-		ret = -EIO;
-		goto err;
-	}
-
-	ret = __btrfs_devread(device->desc, device->part, data, *len,
-			      multi->stripes[0].physical);
-	if (ret != *len)
-		ret = -EIO;
-	else
+		ret = btrfs_map_block(fs_info, READ, cur, &cur_len, &multi,
+				      mirror, NULL);
+		if (ret) {
+			error("Couldn't map the block %llu", cur);
+			goto err;
+		}
+		device = multi->stripes[0].dev;
+		if (!device->desc || !device->part) {
+			error("devid %llu is missing", device->devid);
+			ret = -EIO;
+			goto err;
+		}
+		ret = __btrfs_devread(device->desc, device->part,
+				data + (cur - logical), cur_len,
+				multi->stripes[0].physical);
+		if (ret != cur_len) {
+			error("read failed on devid %llu physical %llu",
+			      device->devid, multi->stripes[0].physical);
+			ret = -EIO;
+			goto err;
+		}
+		cur += cur_len;
 		ret = 0;
+	}
 err:
 	kfree(multi);
 	return ret;
diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c
index 4226621..1430e67 100644
--- a/fs/squashfs/sqfs.c
+++ b/fs/squashfs/sqfs.c
@@ -100,7 +100,7 @@
 static int sqfs_frag_lookup(u32 inode_fragment_index,
 			    struct squashfs_fragment_block_entry *e)
 {
-	u64 start, n_blks, src_len, table_offset, start_block;
+	u64 start, end, exp_tbl, n_blks, src_len, table_offset, start_block;
 	unsigned char *metadata_buffer, *metadata, *table;
 	struct squashfs_fragment_block_entry *entries;
 	struct squashfs_super_block *sblk = ctxt.sblk;
@@ -115,11 +115,17 @@
 	if (inode_fragment_index >= get_unaligned_le32(&sblk->fragments))
 		return -EINVAL;
 
-	start = get_unaligned_le64(&sblk->fragment_table_start) /
-		ctxt.cur_dev->blksz;
+	start = get_unaligned_le64(&sblk->fragment_table_start);
+	end = get_unaligned_le64(&sblk->id_table_start);
+	exp_tbl = get_unaligned_le64(&sblk->export_table_start);
+
+	if (exp_tbl > start && exp_tbl < end)
+		end = exp_tbl;
+
 	n_blks = sqfs_calc_n_blks(sblk->fragment_table_start,
-				  sblk->export_table_start,
-				  &table_offset);
+				  cpu_to_le64(end), &table_offset);
+
+	start /= ctxt.cur_dev->blksz;
 
 	/* Allocate a proper sized buffer to store the fragment index table */
 	table = malloc_cache_aligned(n_blks * ctxt.cur_dev->blksz);
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index 0fcf709..dd0bdf2 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -462,14 +462,6 @@
 int gpio_hog_lookup_name(const char *name, struct gpio_desc **desc);
 
 /**
- * gpio_hog_probe_all() - probe all gpio devices with
- * gpio-hog subnodes.
- *
- * @return:	Returns return value from device_probe()
- */
-int gpio_hog_probe_all(void);
-
-/**
  * gpio_lookup_name - Look up a GPIO name and return its details
  *
  * This is used to convert a named GPIO into a device, offset and GPIO
diff --git a/include/charset.h b/include/charset.h
index 6e79d71..44034c7 100644
--- a/include/charset.h
+++ b/include/charset.h
@@ -178,7 +178,6 @@
  *
  * @s1:		first string to compare
  * @s2:		second string to compare
- * @n:		maximum number of u16 to compare
  * Return:	0  if the first n u16 are the same in s1 and s2
  *		< 0 if the first different u16 in s1 is less than the
  *		corresponding u16 in s2
diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h
index c3a2414..9d2a225 100644
--- a/include/config_distro_bootcmd.h
+++ b/include/config_distro_bootcmd.h
@@ -521,6 +521,9 @@
 			"if fstype ${devtype} "                           \
 					"${devnum}:${distro_bootpart} "   \
 					"bootfstype; then "               \
+				"part uuid ${devtype} "                   \
+					"${devnum}:${distro_bootpart} "   \
+					"distro_bootpart_uuid ; "         \
 				"run scan_dev_for_boot; "                 \
 			"fi; "                                            \
 		"done; "                                                  \
diff --git a/include/fastboot.h b/include/fastboot.h
index 57daaf1..07f4c8f 100644
--- a/include/fastboot.h
+++ b/include/fastboot.h
@@ -24,10 +24,8 @@
 enum {
 	FASTBOOT_COMMAND_GETVAR = 0,
 	FASTBOOT_COMMAND_DOWNLOAD,
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
 	FASTBOOT_COMMAND_FLASH,
 	FASTBOOT_COMMAND_ERASE,
-#endif
 	FASTBOOT_COMMAND_BOOT,
 	FASTBOOT_COMMAND_CONTINUE,
 	FASTBOOT_COMMAND_REBOOT,
@@ -35,20 +33,12 @@
 	FASTBOOT_COMMAND_REBOOT_FASTBOOTD,
 	FASTBOOT_COMMAND_REBOOT_RECOVERY,
 	FASTBOOT_COMMAND_SET_ACTIVE,
-#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
 	FASTBOOT_COMMAND_OEM_FORMAT,
-#endif
-#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_PARTCONF)
 	FASTBOOT_COMMAND_OEM_PARTCONF,
-#endif
-#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_BOOTBUS)
 	FASTBOOT_COMMAND_OEM_BOOTBUS,
-#endif
-#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
+	FASTBOOT_COMMAND_OEM_RUN,
 	FASTBOOT_COMMAND_ACMD,
 	FASTBOOT_COMMAND_UCMD,
-#endif
-
 	FASTBOOT_COMMAND_COUNT
 };
 
@@ -173,7 +163,5 @@
  */
 void fastboot_data_complete(char *response);
 
-#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
 void fastboot_acmd_complete(void);
-#endif
 #endif /* _FASTBOOT_H_ */
diff --git a/include/fs_loader.h b/include/fs_loader.h
index 8de7cb1..5eb5b7a 100644
--- a/include/fs_loader.h
+++ b/include/fs_loader.h
@@ -52,4 +52,16 @@
 int request_firmware_into_buf(struct udevice *dev,
 			      const char *name,
 			      void *buf, size_t size, u32 offset);
+
+/**
+ * get_fs_loader() - Get the chosen filesystem loader
+ * @dev: Where to store the device
+ *
+ * This gets a filesystem loader device based on the value of
+ * /chosen/firmware-loader. If no such property exists, it returns a
+ * firmware loader which is configured by environmental variables.
+ *
+ * Return: 0 on success, negative value on error
+ */
+int get_fs_loader(struct udevice **dev);
 #endif
diff --git a/include/test/suites.h b/include/test/suites.h
index a01000e..9ce49cb 100644
--- a/include/test/suites.h
+++ b/include/test/suites.h
@@ -38,6 +38,7 @@
 		      char *const argv[]);
 int do_ut_dm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_env(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
+int do_ut_exit(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_font(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_lib(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
index 7ea0334..d170a86 100644
--- a/lib/efi_loader/efi_disk.c
+++ b/lib/efi_loader/efi_disk.c
@@ -13,6 +13,7 @@
 #include <dm/device-internal.h>
 #include <dm/tag.h>
 #include <event.h>
+#include <efi_driver.h>
 #include <efi_loader.h>
 #include <fs.h>
 #include <log.h>
@@ -386,6 +387,7 @@
  * @part_info:		partition info
  * @part:		partition
  * @disk:		pointer to receive the created handle
+ * @agent_handle:	handle of the EFI block driver
  * Return:		disk object
  */
 static efi_status_t efi_disk_add_dev(
@@ -395,7 +397,8 @@
 				int dev_index,
 				struct disk_partition *part_info,
 				unsigned int part,
-				struct efi_disk_obj **disk)
+				struct efi_disk_obj **disk,
+				efi_handle_t agent_handle)
 {
 	struct efi_disk_obj *diskobj;
 	struct efi_object *handle;
@@ -529,17 +532,18 @@
 	return ret;
 }
 
-/*
- * Create a handle for a whole raw disk
+/**
+ * efi_disk_create_raw() - create a handle for a whole raw disk
  *
- * @dev		uclass device (UCLASS_BLK)
+ * @dev:		udevice (UCLASS_BLK)
+ * @agent_handle:	handle of the EFI block driver
  *
  * Create an efi_disk object which is associated with @dev.
  * The type of @dev must be UCLASS_BLK.
  *
- * @return	0 on success, -1 otherwise
+ * Return:		0 on success, -1 otherwise
  */
-static int efi_disk_create_raw(struct udevice *dev)
+static int efi_disk_create_raw(struct udevice *dev, efi_handle_t agent_handle)
 {
 	struct efi_disk_obj *disk;
 	struct blk_desc *desc;
@@ -550,7 +554,7 @@
 	diskid = desc->devnum;
 
 	ret = efi_disk_add_dev(NULL, NULL, desc,
-			       diskid, NULL, 0, &disk);
+			       diskid, NULL, 0, &disk, agent_handle);
 	if (ret != EFI_SUCCESS) {
 		if (ret == EFI_NOT_READY)
 			log_notice("Disk %s not ready\n", dev->name);
@@ -569,17 +573,18 @@
 	return 0;
 }
 
-/*
- * Create a handle for a disk partition
+/**
+ * efi_disk_create_part() - create a handle for a disk partition
  *
- * @dev		uclass device (UCLASS_PARTITION)
+ * @dev:		udevice (UCLASS_PARTITION)
+ * @agent_handle:	handle of the EFI block driver
  *
  * Create an efi_disk object which is associated with @dev.
  * The type of @dev must be UCLASS_PARTITION.
  *
- * @return	0 on success, -1 otherwise
+ * Return:		0 on success, -1 otherwise
  */
-static int efi_disk_create_part(struct udevice *dev)
+static int efi_disk_create_part(struct udevice *dev, efi_handle_t agent_handle)
 {
 	efi_handle_t parent;
 	struct blk_desc *desc;
@@ -608,7 +613,7 @@
 	dp_parent = (struct efi_device_path *)handler->protocol_interface;
 
 	ret = efi_disk_add_dev(parent, dp_parent, desc, diskid,
-			       info, part, &disk);
+			       info, part, &disk, agent_handle);
 	if (ret != EFI_SUCCESS) {
 		log_err("Adding partition for %s failed\n", dev->name);
 		return -1;
@@ -623,17 +628,18 @@
 	return 0;
 }
 
-/*
- * Create efi_disk objects for a block device
+/**
+ * efi_disk_probe() - create efi_disk objects for a block device
  *
- * @dev		uclass device (UCLASS_BLK)
+ * @ctx:	event context - driver binding protocol
+ * @event:	EV_PM_POST_PROBE event
  *
  * Create efi_disk objects for partitions as well as a raw disk
  * which is associated with @dev.
  * The type of @dev must be UCLASS_BLK.
  * This function is expected to be called at EV_PM_POST_PROBE.
  *
- * @return	0 on success, -1 otherwise
+ * Return:	0 on success, -1 otherwise
  */
 int efi_disk_probe(void *ctx, struct event *event)
 {
@@ -641,28 +647,30 @@
 	enum uclass_id id;
 	struct blk_desc *desc;
 	struct udevice *child;
+	struct efi_driver_binding_extended_protocol *db_prot = ctx;
+	efi_handle_t agent_handle = db_prot->bp.driver_binding_handle;
 	int ret;
 
 	dev = event->data.dm.dev;
 	id = device_get_uclass_id(dev);
 
-	/* TODO: We won't support partitions in a partition */
+	/* We won't support partitions in a partition */
 	if (id != UCLASS_BLK)
 		return 0;
 
 	/*
-	 * avoid creating duplicated objects now that efi_driver
+	 * Avoid creating duplicated objects now that efi_driver
 	 * has already created an efi_disk at this moment.
 	 */
 	desc = dev_get_uclass_plat(dev);
 	if (desc->uclass_id != UCLASS_EFI_LOADER) {
-		ret = efi_disk_create_raw(dev);
+		ret = efi_disk_create_raw(dev, agent_handle);
 		if (ret)
 			return -1;
 	}
 
 	device_foreach_child(child, dev) {
-		ret = efi_disk_create_part(child);
+		ret = efi_disk_create_part(child, agent_handle);
 		if (ret)
 			return -1;
 	}
diff --git a/lib/efi_loader/efi_hii.c b/lib/efi_loader/efi_hii.c
index 27db3be..3b54ecb1 100644
--- a/lib/efi_loader/efi_hii.c
+++ b/lib/efi_loader/efi_hii.c
@@ -758,6 +758,9 @@
 {
 	EFI_ENTRY("%p, %pUs", this, key_guid);
 
+	if (!key_guid)
+		return EFI_EXIT(EFI_INVALID_PARAMETER);
+
 	return EFI_EXIT(EFI_NOT_FOUND);
 }
 
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
index 32254d2..b7bee98 100644
--- a/lib/efi_loader/efi_memory.c
+++ b/lib/efi_loader/efi_memory.c
@@ -78,12 +78,19 @@
 	return ret;
 }
 
-/*
+/**
+ * efi_mem_cmp() - comparator function for sorting memory map
+ *
  * Sorts the memory list from highest address to lowest address
  *
  * When allocating memory we should always start from the highest
  * address chunk, so sort the memory list such that the first list
  * iterator gets the highest address and goes lower from there.
+ *
+ * @priv:	unused
+ * @a:		first memory area
+ * @b:		second memory area
+ * Return:	1 if @a is before @b, -1 if @b is before @a, 0 if equal
  */
 static int efi_mem_cmp(void *priv, struct list_head *a, struct list_head *b)
 {
@@ -98,11 +105,22 @@
 		return -1;
 }
 
+/**
+ * desc_get_end() - get end address of memory area
+ *
+ * @desc:	memory descriptor
+ * Return:	end address + 1
+ */
 static uint64_t desc_get_end(struct efi_mem_desc *desc)
 {
 	return desc->physical_start + (desc->num_pages << EFI_PAGE_SHIFT);
 }
 
+/**
+ * efi_mem_sort() - sort memory map
+ *
+ * Sort the memory map and then try to merge adjacent memory areas.
+ */
 static void efi_mem_sort(void)
 {
 	struct list_head *lhandle;
@@ -148,12 +166,13 @@
 	}
 }
 
-/** efi_mem_carve_out - unmap memory region
+/**
+ * efi_mem_carve_out() - unmap memory region
  *
  * @map:		memory map
  * @carve_desc:		memory region to unmap
  * @overlap_only_ram:	the carved out region may only overlap RAM
- * Return Value:	the number of overlapping pages which have been
+ * Return:		the number of overlapping pages which have been
  *			removed from the map,
  *			EFI_CARVE_NO_OVERLAP, if the regions don't overlap,
  *			EFI_CARVE_OVERLAPS_NONRAM, if the carve and map overlap,
@@ -403,6 +422,13 @@
 	return EFI_NOT_FOUND;
 }
 
+/**
+ * efi_find_free_memory() - find free memory pages
+ *
+ * @len:	size of memory area needed
+ * @max_addr:	highest address to allocate
+ * Return:	pointer to free memory area or 0
+ */
 static uint64_t efi_find_free_memory(uint64_t len, uint64_t max_addr)
 {
 	struct list_head *lhandle;
@@ -445,13 +471,13 @@
 	return 0;
 }
 
-/*
- * Allocate memory pages.
+/**
+ * efi_allocate_pages - allocate memory pages
  *
- * @type		type of allocation to be performed
- * @memory_type		usage type of the allocated memory
- * @pages		number of pages to be allocated
- * @memory		allocated memory
+ * @type:		type of allocation to be performed
+ * @memory_type:	usage type of the allocated memory
+ * @pages:		number of pages to be allocated
+ * @memory:		allocated memory
  * Return:		status code
  */
 efi_status_t efi_allocate_pages(enum efi_allocate_type type,
@@ -507,6 +533,13 @@
 	return EFI_SUCCESS;
 }
 
+/**
+ * efi_alloc() - allocate memory pages
+ *
+ * @len:		size of the memory to be allocated
+ * @memory_type:	usage type of the allocated memory
+ * Return:		pointer to the allocated memory area or NULL
+ */
 void *efi_alloc(uint64_t len, int memory_type)
 {
 	uint64_t ret = 0;
@@ -552,7 +585,7 @@
 }
 
 /**
- * efi_alloc_aligned_pages - allocate
+ * efi_alloc_aligned_pages() - allocate aligned memory pages
  *
  * @len:		len in bytes
  * @memory_type:	usage type of the allocated memory
@@ -673,15 +706,15 @@
 	return ret;
 }
 
-/*
- * Get map describing memory usage.
+/**
+ * efi_get_memory_map() - get map describing memory usage.
  *
- * @memory_map_size	on entry the size, in bytes, of the memory map buffer,
+ * @memory_map_size:	on entry the size, in bytes, of the memory map buffer,
  *			on exit the size of the copied memory map
- * @memory_map		buffer to which the memory map is written
- * @map_key		key for the memory map
- * @descriptor_size	size of an individual memory descriptor
- * @descriptor_version	version number of the memory descriptor structure
+ * @memory_map:		buffer to which the memory map is written
+ * @map_key:		key for the memory map
+ * @descriptor_size:	size of an individual memory descriptor
+ * @descriptor_version:	version number of the memory descriptor structure
  * Return:		status code
  */
 efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size,
@@ -741,8 +774,8 @@
  *
  * The caller is responsible for calling FreePool() if the call succeeds.
  *
- * @memory_map		buffer to which the memory map is written
- * @map_size		size of the memory map
+ * @map_size:		size of the memory map
+ * @memory_map:		buffer to which the memory map is written
  * Return:		status code
  */
 efi_status_t efi_get_memory_map_alloc(efi_uintn_t *map_size,
@@ -818,6 +851,11 @@
 	return EFI_SUCCESS;
 }
 
+/**
+ * efi_add_known_memory() - add memory banks to map
+ *
+ * This function may be overridden for specific architectures.
+ */
 __weak void efi_add_known_memory(void)
 {
 	u64 ram_top = board_get_usable_ram_top(0) & ~EFI_PAGE_MASK;
@@ -844,7 +882,11 @@
 	}
 }
 
-/* Add memory regions for U-Boot's memory and for the runtime services code */
+/**
+ * add_u_boot_and_runtime() - add U-Boot code to memory map
+ *
+ * Add memory regions for U-Boot's memory and for the runtime services code.
+ */
 static void add_u_boot_and_runtime(void)
 {
 	unsigned long runtime_start, runtime_end, runtime_pages;
diff --git a/lib/efi_loader/efi_riscv.c b/lib/efi_loader/efi_riscv.c
index bccfefd..0641727 100644
--- a/lib/efi_loader/efi_riscv.c
+++ b/lib/efi_loader/efi_riscv.c
@@ -31,7 +31,7 @@
 	EFI_ENTRY("%p, %p",  this, boot_hartid);
 
 	if (this != &riscv_efi_boot_prot || !boot_hartid)
-		return EFI_INVALID_PARAMETER;
+		return EFI_EXIT(EFI_INVALID_PARAMETER);
 
 	*boot_hartid = gd->arch.boot_hart;
 
diff --git a/lib/efi_selftest/efi_selftest_hii.c b/lib/efi_selftest/efi_selftest_hii.c
index eaf3b09..f4b5588 100644
--- a/lib/efi_selftest/efi_selftest_hii.c
+++ b/lib/efi_selftest/efi_selftest_hii.c
@@ -564,7 +564,19 @@
  */
 static int test_hii_database_set_keyboard_layout(void)
 {
+	efi_status_t ret;
+
 	PRINT_TESTNAME;
+
+	/* Invalid key guid. */
+	ret = hii_database_protocol->set_keyboard_layout(
+			hii_database_protocol, NULL);
+	if (ret != EFI_INVALID_PARAMETER) {
+		efi_st_error("set_keyboard_layout returned %u not invalid\n",
+			     (unsigned int)ret);
+		return EFI_ST_FAILURE;
+	}
+
 	/* set_keyboard_layout() not implemented yet */
 	return EFI_ST_SUCCESS;
 }
diff --git a/lib/rsa/rsa-sign.c b/lib/rsa/rsa-sign.c
index b2a2119..d20bdb5 100644
--- a/lib/rsa/rsa-sign.c
+++ b/lib/rsa/rsa-sign.c
@@ -608,7 +608,7 @@
 	BIGNUM *modulus, *r_squared;
 	uint64_t exponent;
 	uint32_t n0_inv;
-	int parent, node;
+	int parent, node = -FDT_ERR_NOTFOUND;
 	char name[100];
 	int ret;
 	int bits;
diff --git a/lib/time.c b/lib/time.c
index 8235026..0c95d12 100644
--- a/lib/time.c
+++ b/lib/time.c
@@ -63,7 +63,7 @@
 }
 
 #else
-extern unsigned long __weak timer_read_counter(void);
+extern unsigned long timer_read_counter(void);
 #endif
 
 #if CONFIG_IS_ENABLED(TIMER)
diff --git a/net/fastboot.c b/net/fastboot.c
index 139233b..96bdf54 100644
--- a/net/fastboot.c
+++ b/net/fastboot.c
@@ -42,7 +42,6 @@
 
 static void boot_downloaded_image(void);
 
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
 /**
  * fastboot_udp_send_info() - Send an INFO packet during long commands.
  *
@@ -104,7 +103,6 @@
 		fastboot_udp_send_info(msg);
 	}
 }
-#endif
 
 /**
  * fastboot_send() - Sends a packet in response to received fastboot packet
@@ -309,9 +307,9 @@
 
 	fastboot_our_port = CONFIG_UDP_FUNCTION_FASTBOOT_PORT;
 
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
-	fastboot_set_progress_callback(fastboot_timed_send_info);
-#endif
+	if (CONFIG_IS_ENABLED(FASTBOOT_FLASH))
+		fastboot_set_progress_callback(fastboot_timed_send_info);
+
 	net_set_udp_handler(fastboot_handler);
 
 	/* zero out server ether in case the server ip has changed */
diff --git a/scripts/coccicheck b/scripts/coccicheck
index dccaea3..00b22e6 100755
--- a/scripts/coccicheck
+++ b/scripts/coccicheck
@@ -54,7 +54,7 @@
 # inspected there.
 #
 # --profile will not output if --very-quiet is used, so avoid it.
-echo $SPFLAGS | egrep -e "--profile|--show-trying" 2>&1 > /dev/null
+echo $SPFLAGS | grep -Ee "--profile|--show-trying" 2>&1 > /dev/null
 if [ $? -eq 0 ]; then
 	FLAGS="--quiet"
 fi
diff --git a/test/cmd/Makefile b/test/cmd/Makefile
index bc961df..09e410e 100644
--- a/test/cmd/Makefile
+++ b/test/cmd/Makefile
@@ -8,7 +8,7 @@
 ifdef CONFIG_CONSOLE_RECORD
 obj-$(CONFIG_CMD_PAUSE) += test_pause.o
 endif
-obj-y += mem.o
+obj-y += exit.o mem.o
 obj-$(CONFIG_CMD_ADDRMAP) += addrmap.o
 obj-$(CONFIG_CMD_FDT) += fdt.o
 obj-$(CONFIG_CONSOLE_TRUETYPE) += font.o
diff --git a/test/cmd/exit.c b/test/cmd/exit.c
new file mode 100644
index 0000000..ca34abe
--- /dev/null
+++ b/test/cmd/exit.c
@@ -0,0 +1,135 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Tests for exit command
+ *
+ * Copyright 2022 Marek Vasut <marex@denx.de>
+ */
+
+#include <common.h>
+#include <console.h>
+#include <mapmem.h>
+#include <asm/global_data.h>
+#include <test/suites.h>
+#include <test/ut.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Declare a new exit test */
+#define EXIT_TEST(_name, _flags)	UNIT_TEST(_name, _flags, exit_test)
+
+/* Test 'exit addr' getting/setting address */
+static int cmd_exit_test(struct unit_test_state *uts)
+{
+	int i;
+
+	/*
+	 * Test 'exit' with parameter -3, -2, -1, 0, 1, 2, 3 . Use all those
+	 * parameters to cover also the special return value -2 that is used
+	 * in HUSH to detect exit command.
+	 *
+	 * Always test whether 'exit' command:
+	 * - exits out of the 'run' command
+	 * - return value is propagated out of the 'run' command
+	 * - return value can be tested on outside of 'run' command
+	 * - return value can be printed outside of 'run' command
+	 */
+	for (i = -3; i <= 3; i++) {
+		ut_assertok(console_record_reset_enable());
+		ut_assertok(run_commandf("setenv foo 'echo bar ; exit %d ; echo baz' ; run foo ; echo $?", i));
+		ut_assert_nextline("bar");
+		ut_assert_nextline("%d", i > 0 ? i : 0);
+		ut_assertok(ut_check_console_end(uts));
+
+		ut_assertok(console_record_reset_enable());
+		ut_assertok(run_commandf("setenv foo 'echo bar ; exit %d ; echo baz' ; run foo && echo quux ; echo $?", i));
+		ut_assert_nextline("bar");
+		if (i <= 0)
+			ut_assert_nextline("quux");
+		ut_assert_nextline("%d", i > 0 ? i : 0);
+		ut_assertok(ut_check_console_end(uts));
+
+		ut_assertok(console_record_reset_enable());
+		ut_assertok(run_commandf("setenv foo 'echo bar ; exit %d ; echo baz' ; run foo || echo quux ; echo $?", i));
+		ut_assert_nextline("bar");
+		if (i > 0)
+			ut_assert_nextline("quux");
+		/* Either 'exit' returns 0, or 'echo quux' returns 0 */
+		ut_assert_nextline("0");
+		ut_assertok(ut_check_console_end(uts));
+	}
+
+	/* Validate that 'exit' behaves the same way as 'exit 0' */
+	ut_assertok(console_record_reset_enable());
+	ut_assertok(run_commandf("setenv foo 'echo bar ; exit ; echo baz' ; run foo ; echo $?", i));
+	ut_assert_nextline("bar");
+	ut_assert_nextline("0");
+	ut_assertok(ut_check_console_end(uts));
+
+	ut_assertok(console_record_reset_enable());
+	ut_assertok(run_commandf("setenv foo 'echo bar ; exit ; echo baz' ; run foo && echo quux ; echo $?", i));
+	ut_assert_nextline("bar");
+	ut_assert_nextline("quux");
+	ut_assert_nextline("0");
+	ut_assertok(ut_check_console_end(uts));
+
+	ut_assertok(console_record_reset_enable());
+	ut_assertok(run_commandf("setenv foo 'echo bar ; exit ; echo baz' ; run foo || echo quux ; echo $?", i));
+	ut_assert_nextline("bar");
+	/* Either 'exit' returns 0, or 'echo quux' returns 0 */
+	ut_assert_nextline("0");
+	ut_assertok(ut_check_console_end(uts));
+
+	/* Validate that return value still propagates from 'run' command */
+	ut_assertok(console_record_reset_enable());
+	ut_assertok(run_commandf("setenv foo 'echo bar ; true' ; run foo ; echo $?", i));
+	ut_assert_nextline("bar");
+	ut_assert_nextline("0");
+	ut_assertok(ut_check_console_end(uts));
+
+	ut_assertok(console_record_reset_enable());
+	ut_assertok(run_commandf("setenv foo 'echo bar ; true' ; run foo && echo quux ; echo $?", i));
+	ut_assert_nextline("bar");
+	ut_assert_nextline("quux");
+	ut_assert_nextline("0");
+	ut_assertok(ut_check_console_end(uts));
+
+	ut_assertok(console_record_reset_enable());
+	ut_assertok(run_commandf("setenv foo 'echo bar ; true' ; run foo || echo quux ; echo $?", i));
+	ut_assert_nextline("bar");
+	/* The 'true' returns 0 */
+	ut_assert_nextline("0");
+	ut_assertok(ut_check_console_end(uts));
+
+	ut_assertok(console_record_reset_enable());
+	ut_assertok(run_commandf("setenv foo 'echo bar ; false' ; run foo ; echo $?", i));
+	ut_assert_nextline("bar");
+	ut_assert_nextline("1");
+	ut_assertok(ut_check_console_end(uts));
+
+	ut_assertok(console_record_reset_enable());
+	ut_assertok(run_commandf("setenv foo 'echo bar ; false' ; run foo && echo quux ; echo $?", i));
+	ut_assert_nextline("bar");
+	ut_assert_nextline("1");
+	ut_assertok(ut_check_console_end(uts));
+
+	ut_assertok(console_record_reset_enable());
+	ut_assertok(run_commandf("setenv foo 'echo bar ; false' ; run foo || echo quux ; echo $?", i));
+	ut_assert_nextline("bar");
+	ut_assert_nextline("quux");
+	/* The 'echo quux' returns 0 */
+	ut_assert_nextline("0");
+	ut_assertok(ut_check_console_end(uts));
+
+	return 0;
+}
+
+EXIT_TEST(cmd_exit_test, UT_TESTF_CONSOLE_REC);
+
+int do_ut_exit(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+	struct unit_test *tests = UNIT_TEST_SUITE_START(exit_test);
+	const int n_ents = UNIT_TEST_SUITE_COUNT(exit_test);
+
+	return cmd_ut_category("cmd_exit", "exit_test_", tests, n_ents,
+			       argc, argv);
+}
diff --git a/test/cmd_ut.c b/test/cmd_ut.c
index 2736582..067bd08 100644
--- a/test/cmd_ut.c
+++ b/test/cmd_ut.c
@@ -65,6 +65,7 @@
 #if defined(CONFIG_UT_ENV)
 	U_BOOT_CMD_MKENT(env, CONFIG_SYS_MAXARGS, 1, do_ut_env, "", ""),
 #endif
+	U_BOOT_CMD_MKENT(exit, CONFIG_SYS_MAXARGS, 1, do_ut_exit, "", ""),
 #ifdef CONFIG_CMD_FDT
 	U_BOOT_CMD_MKENT(fdt, CONFIG_SYS_MAXARGS, 1, do_ut_fdt, "", ""),
 #endif
diff --git a/test/compression.c b/test/compression.c
index 82e29c9..ba98d21 100644
--- a/test/compression.c
+++ b/test/compression.c
@@ -321,42 +321,48 @@
 	/* Compress works as expected. */
 	printf("\torig_size:%lu\n", buf->orig_size);
 	memset(buf->compressed_buf, 'A', TEST_BUFFER_SIZE);
-	errcheck(compress(uts, buf->orig_buf, buf->orig_size,
+	ut_assertok(compress(uts, buf->orig_buf, buf->orig_size,
 			  buf->compressed_buf, buf->compressed_size,
-			  &buf->compressed_size) == 0);
+			  &buf->compressed_size));
 	printf("\tcompressed_size:%lu\n", buf->compressed_size);
-	errcheck(buf->compressed_size > 0);
-	errcheck(buf->compressed_size < buf->orig_size);
-	errcheck(((char *)buf->compressed_buf)[buf->compressed_size - 1] !=
-			'A');
-	errcheck(((char *)buf->compressed_buf)[buf->compressed_size] == 'A');
+	ut_assert(buf->compressed_size > 0);
+	ut_assert(buf->compressed_size < buf->orig_size);
+	ut_assert(((char *)buf->compressed_buf)[buf->compressed_size - 1]
+			!= 'A');
+	ut_asserteq(((char *)buf->compressed_buf)[buf->compressed_size], 'A');
 
 	/* Uncompresses with space remaining. */
-	errcheck(uncompress(uts, buf->compressed_buf, buf->compressed_size,
+	ut_assertok(uncompress(uts, buf->compressed_buf, buf->compressed_size,
 			    buf->uncompressed_buf, buf->uncompressed_size,
-			    &buf->uncompressed_size) == 0);
+			    &buf->uncompressed_size));
 	printf("\tuncompressed_size:%lu\n", buf->uncompressed_size);
-	errcheck(buf->uncompressed_size == buf->orig_size);
-	errcheck(memcmp(buf->orig_buf, buf->uncompressed_buf,
-			buf->orig_size) == 0);
+	ut_asserteq(buf->uncompressed_size, buf->orig_size);
+	ut_asserteq_mem(buf->orig_buf, buf->uncompressed_buf, buf->orig_size);
 
 	/* Uncompresses with exactly the right size output buffer. */
 	memset(buf->uncompressed_buf, 'A', TEST_BUFFER_SIZE);
-	errcheck(uncompress(uts, buf->compressed_buf, buf->compressed_size,
+	ut_assertok(uncompress(uts, buf->compressed_buf, buf->compressed_size,
 			    buf->uncompressed_buf, buf->orig_size,
-			    &buf->uncompressed_size) == 0);
-	errcheck(buf->uncompressed_size == buf->orig_size);
-	errcheck(memcmp(buf->orig_buf, buf->uncompressed_buf,
-			buf->orig_size) == 0);
-	errcheck(((char *)buf->uncompressed_buf)[buf->orig_size] == 'A');
+			    &buf->uncompressed_size));
+	ut_asserteq(buf->uncompressed_size, buf->orig_size);
+	ut_asserteq_mem(buf->orig_buf, buf->uncompressed_buf, buf->orig_size);
+	ut_asserteq(((char *)buf->uncompressed_buf)[buf->orig_size], 'A');
+
+	/* Uncompresses with trailing garbage in input buffer. */
+	memset(buf->uncompressed_buf, 'A', TEST_BUFFER_SIZE);
+	ut_assertok(uncompress(uts, buf->compressed_buf, buf->compressed_size + 4,
+			    buf->uncompressed_buf, buf->uncompressed_size,
+			    &buf->uncompressed_size));
+	ut_asserteq(buf->uncompressed_size, buf->orig_size);
+	ut_asserteq_mem(buf->orig_buf, buf->uncompressed_buf, buf->orig_size);
 
 	/* Make sure compression does not over-run. */
 	memset(buf->compare_buf, 'A', TEST_BUFFER_SIZE);
 	ret = compress(uts, buf->orig_buf, buf->orig_size,
 		       buf->compare_buf, buf->compressed_size - 1,
 		       NULL);
-	errcheck(((char *)buf->compare_buf)[buf->compressed_size] == 'A');
-	errcheck(ret != 0);
+	ut_asserteq(((char *)buf->compare_buf)[buf->compressed_size], 'A');
+	ut_assert(ret != 0);
 	printf("\tcompress does not overrun\n");
 
 	/* Make sure decompression does not over-run. */
@@ -364,15 +370,12 @@
 	ret = uncompress(uts, buf->compressed_buf, buf->compressed_size,
 			 buf->compare_buf, buf->uncompressed_size - 1,
 			 NULL);
-	errcheck(((char *)buf->compare_buf)[buf->uncompressed_size - 1] == 'A');
-	errcheck(ret != 0);
+	ut_asserteq(((char *)buf->compare_buf)[buf->uncompressed_size - 1], 'A');
+	ut_assert(ret != 0);
 	printf("\tuncompress does not overrun\n");
 
 	/* Got here, everything is fine. */
-	ret = 0;
-
-out:
-	return ret;
+	return 0;
 }
 
 static int run_test(struct unit_test_state *uts, char *name,
diff --git a/test/fs/fs-test.sh b/test/fs/fs-test.sh
index b877481..dec2634 100755
--- a/test/fs/fs-test.sh
+++ b/test/fs/fs-test.sh
@@ -462,22 +462,22 @@
 	FAIL=0
 
 	# Check if the ls is showing correct results for 2.5 gb file
-	grep -A7 "Test Case 1 " "$1" | egrep -iq "2621440000 *$4"
+	grep -A7 "Test Case 1 " "$1" | grep -Eiq "2621440000 *$4"
 	pass_fail "TC1: ls of $4"
 
 	# Check if the ls is showing correct results for 1 mb file
-	grep -A7 "Test Case 1 " "$1" | egrep -iq "1048576 *$3"
+	grep -A7 "Test Case 1 " "$1" | grep -Eiq "1048576 *$3"
 	pass_fail "TC1: ls of $3"
 
 	# Check size command on 1MB.file
-	egrep -A3 "Test Case 2a " "$1" | grep -q "filesize=100000"
+	grep -A3 "Test Case 2a " "$1" | grep -q "filesize=100000"
 	pass_fail "TC2: size of $3"
 	# Check size command on 1MB.file via a path using '..'
-	egrep -A3 "Test Case 2b " "$1" | grep -q "filesize=100000"
+	grep -A3 "Test Case 2b " "$1" | grep -q "filesize=100000"
 	pass_fail "TC2: size of $3 via a path using '..'"
 
 	# Check size command on 2.5GB.file
-	egrep -A3 "Test Case 3 " "$1" | grep -q "filesize=9c400000"
+	grep -A3 "Test Case 3 " "$1" | grep -q "filesize=9c400000"
 	pass_fail "TC3: size of $4"
 
 	# Check read full mb of 1MB.file
diff --git a/test/py/tests/test_env.py b/test/py/tests/test_env.py
index 6d08565..00bcccd 100644
--- a/test/py/tests/test_env.py
+++ b/test/py/tests/test_env.py
@@ -8,6 +8,7 @@
 
 import os
 import os.path
+import re
 from subprocess import call, CalledProcessError
 import tempfile
 
@@ -173,6 +174,29 @@
     response = state_test_env.u_boot_console.run_command('printenv %s' % var)
     assert response == ('%s=%s' % (var, value))
 
+@pytest.mark.boardspec('sandbox')
+def test_env_initial_env_file(u_boot_console):
+    """Test that the u-boot-initial-env make target works"""
+    cons = u_boot_console
+    builddir = 'O=' + cons.config.build_dir
+    envfile = cons.config.build_dir + '/u-boot-initial-env'
+
+    # remove if already exists from an older run
+    try:
+        os.remove(envfile)
+    except:
+        pass
+
+    u_boot_utils.run_and_log(cons, ['make', builddir, 'u-boot-initial-env'])
+
+    assert os.path.exists(envfile)
+
+    # assume that every environment has a board variable, e.g. board=sandbox
+    with open(envfile, 'r') as file:
+        env = file.read()
+    regex = re.compile('board=.+\\n')
+    assert re.search(regex, env)
+
 def test_env_echo_exists(state_test_env):
     """Test echoing a variable that exists."""
 
diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile
index 2408788..202a814 100644
--- a/tools/docker/Dockerfile
+++ b/tools/docker/Dockerfile
@@ -2,7 +2,7 @@
 # This Dockerfile is used to build an image containing basic stuff to be used
 # to build U-Boot and run our test suites.
 
-FROM ubuntu:jammy-20221101
+FROM ubuntu:jammy-20221130
 MAINTAINER Tom Rini <trini@konsulko.com>
 LABEL Description=" This image is for building U-Boot inside a container"
 
@@ -64,6 +64,7 @@
 	iasl \
 	imagemagick \
 	iputils-ping \
+	libc6-i386 \
 	libconfuse-dev \
 	libgit2-dev \
 	libjson-glib-dev \
@@ -109,6 +110,7 @@
 	srecord \
 	sudo \
 	swig \
+	texinfo \
 	util-linux \
 	uuid-dev \
 	virtualenv \