Merge patch series "omap configuration cleanups"

Paul Kocialkowski <paulk@sys-base.io> says:

Here is a bunch of configuration cleanups for OMAP boards, mostly
unifying and moving common configuration from board-specific defconfigs
to Kconfig definitions.

There's also a cleanup of the sniper (LG Optimus Black) defconfig,
prior to migrating it to DM/DT in a future follow-up series.
diff --git a/MAINTAINERS b/MAINTAINERS
index a6e47e8..ddcb712 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -945,6 +945,7 @@
 T:	git https://source.denx.de/u-boot/custodians/u-boot-dfu.git
 F:	boot/bootmeth_android.c
 F:	boot/bootmeth_android.h
+F:	doc/develop/bootstd/android.rst
 
 BTRFS
 M:	Marek Behún <kabel@kernel.org>
@@ -996,6 +997,13 @@
 F:	doc/arch/m68k.rst
 F:	drivers/watchdog/mcf_wdt.c
 
+CPU
+M:	Simon Glass <sjg@chromium.org>
+M:	Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
+S:	Maintained
+F:	cmd/cpu.c
+F:	doc/usage/cpu.rst
+
 CYCLIC
 M:	Stefan Roese <sr@denx.de>
 S:	Maintained
diff --git a/Makefile b/Makefile
index 750ce61..2861b4d 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@
 VERSION = 2024
 PATCHLEVEL = 10
 SUBLEVEL =
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc2
 NAME =
 
 # *DOCUMENTATION*
@@ -1048,7 +1048,7 @@
 CHECKFLAGS += --arch=$(ARCH)
 
 # insure the checker run with the right endianness
-CHECKFLAGS += $(if $(CONFIG_CPU_BIG_ENDIAN),-mbig-endian,-mlittle-endian)
+CHECKFLAGS += $(if $(CONFIG_SYS_BIG_ENDIAN),-mbig-endian,-mlittle-endian)
 
 # the checker needs the correct machine size
 CHECKFLAGS += $(if $(CONFIG_64BIT),-m64,-m32)
@@ -1388,9 +1388,12 @@
 		-a rockchip-tpl-path=$(ROCKCHIP_TPL) \
 		-a spl-bss-pad=$(if $(CONFIG_SPL_SEPARATE_BSS),,1) \
 		-a tpl-bss-pad=$(if $(CONFIG_TPL_SEPARATE_BSS),,1) \
+		-a vpl-bss-pad=$(if $(CONFIG_VPL_SEPARATE_BSS),,1) \
 		-a spl-dtb=$(CONFIG_SPL_OF_REAL) \
 		-a tpl-dtb=$(CONFIG_TPL_OF_REAL) \
+		-a vpl-dtb=$(CONFIG_VPL_OF_REAL) \
 		-a pre-load-key-path=${PRE_LOAD_KEY_PATH} \
+		-a of-spl-remove-props=$(CONFIG_OF_SPL_REMOVE_PROPS) \
 		$(BINMAN_$(@F))
 
 OBJCOPYFLAGS_u-boot.ldr.hex := -I binary -O ihex
diff --git a/arch/Kconfig b/arch/Kconfig
index abd406d..8f1f466 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -8,6 +8,13 @@
 config HAVE_ARCH_IOREMAP
 	bool
 
+config SUPPORT_BIG_ENDIAN
+	bool
+
+config SUPPORT_LITTLE_ENDIAN
+	bool
+	default y if !SUPPORT_BIG_ENDIAN
+
 config SYS_CACHE_SHIFT_4
 	bool
 
@@ -59,6 +66,8 @@
 	select SUPPORT_OF_CONTROL
 	select SYS_CACHE_SHIFT_7
 	select TIMER
+	select SUPPORT_BIG_ENDIAN
+	select SUPPORT_LITTLE_ENDIAN
 	select SYS_BIG_ENDIAN if CPU_BIG_ENDIAN
 	select SYS_LITTLE_ENDIAN if !CPU_BIG_ENDIAN
 
@@ -68,6 +77,7 @@
 	select CREATE_ARCH_SYMLINK
 	select HAVE_PRIVATE_LIBGCC if !ARM64
 	select SUPPORT_ACPI
+	select SUPPORT_LITTLE_ENDIAN
 	select SUPPORT_OF_CONTROL
 
 config M68K
@@ -77,10 +87,13 @@
 	select SYS_BOOT_GET_CMDLINE
 	select SYS_BOOT_GET_KBD
 	select SYS_CACHE_SHIFT_4
+	select SUPPORT_BIG_ENDIAN
 	select SUPPORT_OF_CONTROL
 
 config MICROBLAZE
 	bool "MicroBlaze architecture"
+	select SUPPORT_BIG_ENDIAN
+	select SUPPORT_LITTLE_ENDIAN
 	select SUPPORT_OF_CONTROL
 	imply CMD_TIMER
 	imply SPL_REGMAP if SPL
@@ -101,12 +114,14 @@
 	select DM
 	select DM_EVENT
 	select OF_CONTROL
+	select SUPPORT_LITTLE_ENDIAN
 	select SUPPORT_OF_CONTROL
 	imply CMD_DM
 
 config PPC
 	bool "PowerPC architecture"
 	select HAVE_PRIVATE_LIBGCC
+	select SUPPORT_BIG_ENDIAN
 	select SUPPORT_OF_CONTROL
 	select SYS_BOOT_GET_CMDLINE
 	select SYS_BOOT_GET_KBD
@@ -115,6 +130,7 @@
 	bool "RISC-V architecture"
 	select CREATE_ARCH_SYMLINK
 	select SUPPORT_ACPI
+	select SUPPORT_LITTLE_ENDIAN
 	select SUPPORT_OF_CONTROL
 	select OF_CONTROL
 	select DM
@@ -160,6 +176,8 @@
 	select PCI_ENDPOINT
 	select SPI
 	select SUPPORT_OF_CONTROL
+	select SUPPORT_BIG_ENDIAN
+	select SUPPORT_LITTLE_ENDIAN
 	select SYSRESET_CMD_POWEROFF if CMD_POWEROFF
 	select SYS_CACHE_SHIFT_4
 	select IRQ
@@ -224,6 +242,7 @@
 
 config SH
 	bool "SuperH architecture"
+	select SUPPORT_LITTLE_ENDIAN
 	select HAVE_PRIVATE_LIBGCC
 	select SUPPORT_OF_CONTROL
 
@@ -231,6 +250,7 @@
 	bool "x86 architecture"
 	select SUPPORT_SPL
 	select SUPPORT_TPL
+	select SUPPORT_LITTLE_ENDIAN
 	select CREATE_ARCH_SYMLINK
 	select DM
 	select HAVE_ARCH_IOMAP
@@ -312,6 +332,7 @@
 config XTENSA
 	bool "Xtensa architecture"
 	select CREATE_ARCH_SYMLINK
+	select SUPPORT_LITTLE_ENDIAN
 	select SUPPORT_OF_CONTROL
 
 endchoice
@@ -515,24 +536,21 @@
 
 source "board/keymile/Kconfig"
 
-if MIPS || MICROBLAZE
-
 choice
 	prompt "Endianness selection"
+	default SYS_BIG_ENDIAN if MIPS || MICROBLAZE
+	default SYS_LITTLE_ENDIAN
 	help
-	  Some MIPS boards can be configured for either little or big endian
+	  Some boards can be configured for either little or big endian
 	  byte order. These modes require different U-Boot images. In general there
 	  is one preferred byteorder for a particular system but some systems are
 	  just as commonly used in the one or the other endianness.
 
 config SYS_BIG_ENDIAN
 	bool "Big endian"
-	depends on (SUPPORTS_BIG_ENDIAN && MIPS) || MICROBLAZE
+	depends on SUPPORT_BIG_ENDIAN
 
 config SYS_LITTLE_ENDIAN
 	bool "Little endian"
-	depends on (SUPPORTS_LITTLE_ENDIAN && MIPS) || MICROBLAZE
-
+	depends on SUPPORT_LITTLE_ENDIAN
 endchoice
-
-endif
diff --git a/arch/arc/include/asm/arc-bcr.h b/arch/arc/include/asm/arc-bcr.h
index a6c972b..d4de9b8 100644
--- a/arch/arc/include/asm/arc-bcr.h
+++ b/arch/arc/include/asm/arc-bcr.h
@@ -15,7 +15,7 @@
 
 union bcr_di_cache {
 	struct {
-#ifdef CONFIG_CPU_BIG_ENDIAN
+#ifdef CONFIG_SYS_BIG_ENDIAN
 		unsigned int pad:12, line_len:4, sz:4, config:4, ver:8;
 #else
 		unsigned int ver:8, config:4, sz:4, line_len:4, pad:12;
@@ -26,7 +26,7 @@
 
 union bcr_slc_cfg {
 	struct {
-#ifdef CONFIG_CPU_BIG_ENDIAN
+#ifdef CONFIG_SYS_BIG_ENDIAN
 		unsigned int pad:24, way:2, lsz:2, sz:4;
 #else
 		unsigned int sz:4, lsz:2, way:2, pad:24;
@@ -37,7 +37,7 @@
 
 union bcr_generic {
 	struct {
-#ifdef CONFIG_CPU_BIG_ENDIAN
+#ifdef CONFIG_SYS_BIG_ENDIAN
 		unsigned int pad:24, ver:8;
 #else
 		unsigned int ver:8, pad:24;
@@ -48,7 +48,7 @@
 
 union bcr_clust_cfg {
 	struct {
-#ifdef CONFIG_CPU_BIG_ENDIAN
+#ifdef CONFIG_SYS_BIG_ENDIAN
 		unsigned int pad:7, c:1, num_entries:8, num_cores:8, ver:8;
 #else
 		unsigned int ver:8, num_cores:8, num_entries:8, c:1, pad:7;
@@ -59,7 +59,7 @@
 
 union bcr_mmu_4 {
 	struct {
-#ifdef CONFIG_CPU_BIG_ENDIAN
+#ifdef CONFIG_SYS_BIG_ENDIAN
 	unsigned int ver:8, sasid:1, sz1:4, sz0:4, res:2, pae:1,
 		     n_ways:2, n_entry:2, n_super:2, u_itlb:3, u_dtlb:3;
 #else
diff --git a/arch/arm/cpu/armv8/linux-kernel-image-header-vars.h b/arch/arm/cpu/armv8/linux-kernel-image-header-vars.h
index b6394ae..c6af825 100644
--- a/arch/arm/cpu/armv8/linux-kernel-image-header-vars.h
+++ b/arch/arm/cpu/armv8/linux-kernel-image-header-vars.h
@@ -31,7 +31,7 @@
  * when PIE is in effect. So we need to split them up in 32-bit high and low
  * words.
  */
-#ifdef CONFIG_CPU_BIG_ENDIAN
+#ifdef CONFIG_SYS_BIG_ENDIAN
 #define DATA_LE32(data)				\
 	((((data) & 0x000000ff) << 24) |	\
 	 (((data) & 0x0000ff00) << 8)  |	\
@@ -55,7 +55,7 @@
 #endif
 #define __MEM_USAGE		(__CODE_DATA_SIZE + __MAX_EXTRA_RAM_USAGE)
 
-#ifdef CONFIG_CPU_BIG_ENDIAN
+#ifdef CONFIG_SYS_BIG_ENDIAN
 #define __HEAD_FLAG_BE		1
 #else
 #define __HEAD_FLAG_BE		0
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 3ae4110..82d37ad 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -883,7 +883,6 @@
 	imx7-cm.dtb \
 	imx7d-colibri-emmc-eval-v3.dtb \
 	imx7d-colibri-eval-v3.dtb \
-	imx7s-warp.dtb \
 	imx7d-meerkat96.dtb \
 	imx7d-pico-pi.dtb \
 	imx7d-pico-hobbit.dtb \
diff --git a/arch/arm/dts/imx7s-warp.dts b/arch/arm/dts/imx7s-warp.dts
deleted file mode 100644
index e8734d2..0000000
--- a/arch/arm/dts/imx7s-warp.dts
+++ /dev/null
@@ -1,500 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-/*
- * Copyright (C) 2016 NXP Semiconductors.
- * Author: Fabio Estevam <fabio.estevam@nxp.com>
- */
-
-/dts-v1/;
-
-#include <dt-bindings/input/input.h>
-#include "imx7s.dtsi"
-
-/ {
-	model = "Element14 Warp i.MX7 Board";
-	compatible = "element14,imx7s-warp", "fsl,imx7s";
-
-	memory@80000000 {
-		device_type = "memory";
-		reg = <0x80000000 0x20000000>;
-	};
-
-	gpio-keys {
-		compatible = "gpio-keys";
-		pinctrl-0 = <&pinctrl_gpio>;
-		autorepeat;
-
-		back {
-			label = "Back";
-			gpios = <&gpio7 1 GPIO_ACTIVE_HIGH>;
-			linux,code = <KEY_BACK>;
-			wakeup-source;
-		};
-	};
-
-	reg_brcm: regulator-brcm {
-		compatible = "regulator-fixed";
-		enable-active-high;
-		gpio = <&gpio5 10 GPIO_ACTIVE_HIGH>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_brcm_reg>;
-		regulator-name = "brcm_reg";
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		startup-delay-us = <200000>;
-	};
-
-	reg_bt: regulator-bt {
-		compatible = "regulator-fixed";
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_bt_reg>;
-		enable-active-high;
-		gpio = <&gpio5 17 GPIO_ACTIVE_HIGH>;
-		regulator-name = "bt_reg";
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		regulator-always-on;
-	};
-
-	reg_peri_3p15v: regulator-peri-3p15v {
-		compatible = "regulator-fixed";
-		regulator-name = "peri_3p15v_reg";
-		regulator-min-microvolt = <3150000>;
-		regulator-max-microvolt = <3150000>;
-		regulator-always-on;
-	};
-
-	sound {
-		compatible = "simple-audio-card";
-		simple-audio-card,name = "imx7-sgtl5000";
-		simple-audio-card,format = "i2s";
-		simple-audio-card,bitclock-master = <&dailink_master>;
-		simple-audio-card,frame-master = <&dailink_master>;
-		simple-audio-card,cpu {
-			sound-dai = <&sai1>;
-		};
-
-		dailink_master: simple-audio-card,codec {
-			sound-dai = <&codec>;
-			clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>;
-		};
-	};
-};
-
-&clks {
-	assigned-clocks = <&clks IMX7D_PLL_AUDIO_POST_DIV>;
-	assigned-clock-rates = <884736000>;
-};
-
-&csi {
-	status = "okay";
-};
-
-&i2c1 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_i2c1>;
-	status = "okay";
-
-	pmic: pfuze3000@8 {
-		compatible = "fsl,pfuze3000";
-		reg = <0x08>;
-
-		regulators {
-			sw1a_reg: sw1a {
-				regulator-min-microvolt = <700000>;
-				regulator-max-microvolt = <1475000>;
-				regulator-boot-on;
-				regulator-always-on;
-				regulator-ramp-delay = <6250>;
-			};
-
-			/* use sw1c_reg to align with pfuze100/pfuze200 */
-			sw1c_reg: sw1b {
-				regulator-min-microvolt = <700000>;
-				regulator-max-microvolt = <1475000>;
-				regulator-boot-on;
-				regulator-always-on;
-				regulator-ramp-delay = <6250>;
-			};
-
-			sw2_reg: sw2 {
-				regulator-min-microvolt = <1500000>;
-				regulator-max-microvolt = <1850000>;
-				regulator-boot-on;
-				regulator-always-on;
-			};
-
-			sw3a_reg: sw3 {
-				regulator-min-microvolt = <900000>;
-				regulator-max-microvolt = <1650000>;
-				regulator-boot-on;
-				regulator-always-on;
-			};
-
-			swbst_reg: swbst {
-				regulator-min-microvolt = <5000000>;
-				regulator-max-microvolt = <5150000>;
-				regulator-boot-on;
-				regulator-always-on;
-			};
-
-			snvs_reg: vsnvs {
-				regulator-min-microvolt = <1000000>;
-				regulator-max-microvolt = <3000000>;
-				regulator-boot-on;
-				regulator-always-on;
-			};
-
-			vref_reg: vrefddr {
-				regulator-boot-on;
-				regulator-always-on;
-			};
-
-			vgen1_reg: vldo1 {
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <3300000>;
-				regulator-always-on;
-			};
-
-			vgen2_reg: vldo2 {
-				regulator-min-microvolt = <800000>;
-				regulator-max-microvolt = <1550000>;
-			};
-
-			vgen3_reg: vccsd {
-				regulator-min-microvolt = <2850000>;
-				regulator-max-microvolt = <3300000>;
-				regulator-always-on;
-			};
-
-			vgen4_reg: v33 {
-				regulator-min-microvolt = <2850000>;
-				regulator-max-microvolt = <3300000>;
-				regulator-always-on;
-			};
-
-			vgen5_reg: vldo3 {
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <3300000>;
-				regulator-always-on;
-			};
-
-			vgen6_reg: vldo4 {
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <3300000>;
-				regulator-always-on;
-			};
-		};
-	};
-};
-
-&i2c2 {
-	clock-frequency = <100000>;
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_i2c2>;
-	status = "okay";
-
-	ov2680: camera@36 {
-		compatible = "ovti,ov2680";
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_ov2680>;
-		reg = <0x36>;
-		clocks = <&osc>;
-		clock-names = "xvclk";
-		reset-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
-		DOVDD-supply = <&sw2_reg>;
-		DVDD-supply = <&sw2_reg>;
-		AVDD-supply = <&reg_peri_3p15v>;
-
-		port {
-			ov2680_to_mipi: endpoint {
-				remote-endpoint = <&mipi_from_sensor>;
-				clock-lanes = <0>;
-				data-lanes = <1>;
-			};
-		};
-	};
-};
-
-&i2c3 {
-	clock-frequency = <100000>;
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_i2c3>;
-	status = "okay";
-};
-
-&i2c4 {
-	clock-frequency = <100000>;
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_i2c4>;
-	status = "okay";
-
-	codec: sgtl5000@a {
-		#sound-dai-cells = <0>;
-		reg = <0x0a>;
-		compatible = "fsl,sgtl5000";
-		clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_sai1_mclk>;
-		VDDA-supply = <&vgen4_reg>;
-		VDDIO-supply = <&vgen4_reg>;
-		VDDD-supply = <&vgen2_reg>;
-	};
-
-	mpl3115@60 {
-		compatible = "fsl,mpl3115";
-		reg = <0x60>;
-	};
-};
-
-&mipi_csi {
-	clock-frequency = <166000000>;
-	status = "okay";
-
-	ports {
-		port@0 {
-			reg = <0>;
-
-			mipi_from_sensor: endpoint {
-				remote-endpoint = <&ov2680_to_mipi>;
-				data-lanes = <1>;
-			};
-		};
-	};
-};
-
-&sai1 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_sai1>;
-	assigned-clocks = <&clks IMX7D_SAI1_ROOT_SRC>,
-			  <&clks IMX7D_SAI1_ROOT_CLK>;
-	assigned-clock-parents = <&clks IMX7D_PLL_AUDIO_POST_DIV>;
-	assigned-clock-rates = <0>, <36864000>;
-	status = "okay";
-};
-
-&uart1 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_uart1>;
-	assigned-clocks = <&clks IMX7D_UART1_ROOT_SRC>;
-	assigned-clock-parents = <&clks IMX7D_PLL_SYS_MAIN_240M_CLK>;
-	status = "okay";
-};
-
-&uart3  {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_uart3>;
-	assigned-clocks = <&clks IMX7D_UART3_ROOT_SRC>;
-	assigned-clock-parents = <&clks IMX7D_PLL_SYS_MAIN_240M_CLK>;
-	uart-has-rtscts;
-	status = "okay";
-};
-
-&uart6 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_uart6>;
-	assigned-clocks = <&clks IMX7D_UART6_ROOT_SRC>;
-	assigned-clock-parents = <&clks IMX7D_PLL_SYS_MAIN_240M_CLK>;
-	fsl,dte-mode;
-	status = "okay";
-};
-
-&usbotg1 {
-	dr_mode = "peripheral";
-	status = "okay";
-};
-
-&usdhc1 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_usdhc1>;
-	bus-width = <4>;
-	keep-power-in-suspend;
-	no-1-8-v;
-	non-removable;
-	vmmc-supply = <&reg_brcm>;
-	status = "okay";
-};
-
-&usdhc3 {
-	pinctrl-names = "default", "state_100mhz", "state_200mhz";
-	pinctrl-0 = <&pinctrl_usdhc3>;
-	pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
-	pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
-	assigned-clocks = <&clks IMX7D_USDHC3_ROOT_CLK>;
-	assigned-clock-rates = <400000000>;
-	bus-width = <8>;
-	no-1-8-v;
-	fsl,tuning-step = <2>;
-	non-removable;
-	status = "okay";
-};
-
-&video_mux {
-	status = "okay";
-};
-
-&wdog1 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_wdog>;
-	fsl,ext-reset-output;
-	status = "okay";
-};
-
-&iomuxc {
-	pinctrl_brcm_reg: brcmreggrp {
-		fsl,pins = <
-			MX7D_PAD_SD2_WP__GPIO5_IO10	0x14 /* WL_REG_ON */
-		>;
-	};
-
-	pinctrl_bt_reg: btreggrp {
-		fsl,pins = <
-			MX7D_PAD_SD2_DATA3__GPIO5_IO17	0x14 /* BT_REG_ON */
-		>;
-	};
-
-	pinctrl_gpio: gpiogrp {
-		fsl,pins = <
-			MX7D_PAD_ENET1_RGMII_RD1__GPIO7_IO1	0x14
-		>;
-	};
-
-	pinctrl_i2c1: i2c1grp {
-		fsl,pins = <
-			MX7D_PAD_I2C1_SDA__I2C1_SDA		0x4000007f
-			MX7D_PAD_I2C1_SCL__I2C1_SCL		0x4000007f
-		>;
-	};
-
-	pinctrl_i2c2: i2c2grp {
-		fsl,pins = <
-			MX7D_PAD_I2C2_SDA__I2C2_SDA	0x4000007f
-			MX7D_PAD_I2C2_SCL__I2C2_SCL	0x4000007f
-		>;
-	};
-
-	pinctrl_i2c3: i2c3grp {
-		fsl,pins = <
-			MX7D_PAD_I2C3_SDA__I2C3_SDA	0x4000007f
-			MX7D_PAD_I2C3_SCL__I2C3_SCL	0x4000007f
-		>;
-	};
-
-	pinctrl_i2c4: i2c4grp {
-		fsl,pins = <
-			MX7D_PAD_I2C4_SCL__I2C4_SCL	0x4000007f
-			MX7D_PAD_I2C4_SDA__I2C4_SDA	0x4000007f
-		>;
-	};
-
-	pinctrl_ov2680: ov2660grp {
-		fsl,pins = <
-			MX7D_PAD_LPSR_GPIO1_IO03__GPIO1_IO3	0x14
-		>;
-	};
-
-	pinctrl_sai1: sai1grp {
-		fsl,pins = <
-			MX7D_PAD_SAI1_RX_DATA__SAI1_RX_DATA0	0x1f
-			MX7D_PAD_SAI1_TX_BCLK__SAI1_TX_BCLK	0x1f
-			MX7D_PAD_SAI1_TX_SYNC__SAI1_TX_SYNC	0x1f
-			MX7D_PAD_SAI1_TX_DATA__SAI1_TX_DATA0	0x30
-		>;
-	};
-
-	pinctrl_sai1_mclk: sai1mclkgrp {
-		fsl,pins = <
-			MX7D_PAD_SAI1_MCLK__SAI1_MCLK           0x1f
-		>;
-	};
-
-	pinctrl_uart1: uart1grp {
-		fsl,pins = <
-			MX7D_PAD_UART1_TX_DATA__UART1_DCE_TX	0x79
-			MX7D_PAD_UART1_RX_DATA__UART1_DCE_RX	0x79
-		>;
-	};
-
-	pinctrl_uart3: uart3grp {
-		fsl,pins = <
-			MX7D_PAD_UART3_TX_DATA__UART3_DCE_TX	0x79
-			MX7D_PAD_UART3_RX_DATA__UART3_DCE_RX	0x79
-			MX7D_PAD_UART3_CTS_B__UART3_DCE_CTS	0x79
-			MX7D_PAD_UART3_RTS_B__UART3_DCE_RTS	0x79
-		>;
-	};
-
-	pinctrl_uart6: uart6grp {
-		fsl,pins = <
-			MX7D_PAD_ECSPI1_MOSI__UART6_DTE_RX	0x79
-			MX7D_PAD_ECSPI1_SCLK__UART6_DTE_TX	0x79
-		>;
-	};
-
-	pinctrl_usdhc1: usdhc1grp {
-		fsl,pins = <
-			MX7D_PAD_SD1_CMD__SD1_CMD	0x59
-			MX7D_PAD_SD1_CLK__SD1_CLK	0x19
-			MX7D_PAD_SD1_DATA0__SD1_DATA0	0x59
-			MX7D_PAD_SD1_DATA1__SD1_DATA1	0x59
-			MX7D_PAD_SD1_DATA2__SD1_DATA2	0x59
-			MX7D_PAD_SD1_DATA3__SD1_DATA3	0x59
-			MX7D_PAD_SD2_RESET_B__GPIO5_IO11 0x14 /* WL_HOST_WAKE */
-		>;
-	};
-
-	pinctrl_usdhc3: usdhc3grp {
-		fsl,pins = <
-			MX7D_PAD_SD3_CMD__SD3_CMD		0x59
-			MX7D_PAD_SD3_CLK__SD3_CLK		0x19
-			MX7D_PAD_SD3_DATA0__SD3_DATA0		0x59
-			MX7D_PAD_SD3_DATA1__SD3_DATA1		0x59
-			MX7D_PAD_SD3_DATA2__SD3_DATA2		0x59
-			MX7D_PAD_SD3_DATA3__SD3_DATA3		0x59
-			MX7D_PAD_SD3_DATA4__SD3_DATA4		0x59
-			MX7D_PAD_SD3_DATA5__SD3_DATA5		0x59
-			MX7D_PAD_SD3_DATA6__SD3_DATA6		0x59
-			MX7D_PAD_SD3_DATA7__SD3_DATA7		0x59
-			MX7D_PAD_SD3_RESET_B__SD3_RESET_B	0x19
-		>;
-	};
-
-	pinctrl_usdhc3_100mhz: usdhc3grp_100mhz {
-		fsl,pins = <
-			MX7D_PAD_SD3_CMD__SD3_CMD		0x5a
-			MX7D_PAD_SD3_CLK__SD3_CLK		0x1a
-			MX7D_PAD_SD3_DATA0__SD3_DATA0		0x5a
-			MX7D_PAD_SD3_DATA1__SD3_DATA1		0x5a
-			MX7D_PAD_SD3_DATA2__SD3_DATA2		0x5a
-			MX7D_PAD_SD3_DATA3__SD3_DATA3		0x5a
-			MX7D_PAD_SD3_DATA4__SD3_DATA4		0x5a
-			MX7D_PAD_SD3_DATA5__SD3_DATA5		0x5a
-			MX7D_PAD_SD3_DATA6__SD3_DATA6		0x5a
-			MX7D_PAD_SD3_DATA7__SD3_DATA7		0x5a
-			MX7D_PAD_SD3_RESET_B__SD3_RESET_B	0x1a
-		>;
-	};
-
-	pinctrl_usdhc3_200mhz: usdhc3grp_200mhz {
-		fsl,pins = <
-			MX7D_PAD_SD3_CMD__SD3_CMD		0x5b
-			MX7D_PAD_SD3_CLK__SD3_CLK		0x1b
-			MX7D_PAD_SD3_DATA0__SD3_DATA0		0x5b
-			MX7D_PAD_SD3_DATA1__SD3_DATA1		0x5b
-			MX7D_PAD_SD3_DATA2__SD3_DATA2		0x5b
-			MX7D_PAD_SD3_DATA3__SD3_DATA3		0x5b
-			MX7D_PAD_SD3_DATA4__SD3_DATA4		0x5b
-			MX7D_PAD_SD3_DATA5__SD3_DATA5		0x5b
-			MX7D_PAD_SD3_DATA6__SD3_DATA6		0x5b
-			MX7D_PAD_SD3_DATA7__SD3_DATA7		0x5b
-			MX7D_PAD_SD3_RESET_B__SD3_RESET_B	0x1b
-		>;
-	};
-};
-
-&iomuxc_lpsr {
-	pinctrl_wdog: wdoggrp {
-		fsl,pins = <
-			MX7D_PAD_LPSR_GPIO1_IO00__WDOG1_WDOG_B	0x74
-		>;
-	};
-};
diff --git a/arch/arm/mach-imx/mx7/Kconfig b/arch/arm/mach-imx/mx7/Kconfig
index 3c0208e..2e68557 100644
--- a/arch/arm/mach-imx/mx7/Kconfig
+++ b/arch/arm/mach-imx/mx7/Kconfig
@@ -87,6 +87,7 @@
 	select DM_THERMAL
 	select MX7D
 	imply CMD_DM
+	imply OF_UPSTREAM
 
 config TARGET_COLIBRI_IMX7
 	bool "Support Colibri iMX7S/iMX7D modules"
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index eb7f3ad..38577af 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -28,14 +28,14 @@
 	select OF_ISA_BUS
 	select PCI_MAP_SYSTEM_MEMORY
 	select ROM_EXCEPTION_VECTORS
-	select SUPPORTS_BIG_ENDIAN
 	select SUPPORTS_CPU_MIPS32_R1
 	select SUPPORTS_CPU_MIPS32_R2
 	select SUPPORTS_CPU_MIPS32_R6
 	select SUPPORTS_CPU_MIPS64_R1
 	select SUPPORTS_CPU_MIPS64_R2
 	select SUPPORTS_CPU_MIPS64_R6
-	select SUPPORTS_LITTLE_ENDIAN
+	select SUPPORT_BIG_ENDIAN
+	select SUPPORT_LITTLE_ENDIAN
 	select SWAP_IO_SPACE
 	imply CMD_DM
 
@@ -86,7 +86,7 @@
 	select ROM_EXCEPTION_VECTORS
 	select SUPPORTS_CPU_MIPS32_R1
 	select SUPPORTS_CPU_MIPS32_R2
-	select SUPPORTS_LITTLE_ENDIAN
+	select SUPPORT_LITTLE_ENDIAN
 	select SUPPORT_SPL
 
 config ARCH_JZ47XX
@@ -112,7 +112,7 @@
 	select MIPS_TUNE_OCTEON3
 	select MTD
 	select ROM_EXCEPTION_VECTORS
-	select SUPPORTS_BIG_ENDIAN
+	select SUPPORT_BIG_ENDIAN
 	select SUPPORTS_CPU_MIPS64_OCTEON
 	select PHYS_64BIT
 	select OF_CONTROL
@@ -138,14 +138,14 @@
 	select OF_BOARD_SETUP
 	select OF_CONTROL
 	select ROM_EXCEPTION_VECTORS
-	select SUPPORTS_BIG_ENDIAN
 	select SUPPORTS_CPU_MIPS32_R1
 	select SUPPORTS_CPU_MIPS32_R2
 	select SUPPORTS_CPU_MIPS32_R6
 	select SUPPORTS_CPU_MIPS64_R1
 	select SUPPORTS_CPU_MIPS64_R2
 	select SUPPORTS_CPU_MIPS64_R6
-	select SUPPORTS_LITTLE_ENDIAN
+	select SUPPORT_BIG_ENDIAN
+	select SUPPORT_LITTLE_ENDIAN
 	imply CMD_DM
 
 config TARGET_XILFPGA
@@ -159,7 +159,7 @@
 	select ROM_EXCEPTION_VECTORS
 	select SUPPORTS_CPU_MIPS32_R1
 	select SUPPORTS_CPU_MIPS32_R2
-	select SUPPORTS_LITTLE_ENDIAN
+	select SUPPORT_LITTLE_ENDIAN
 	imply CMD_DM
 	help
 	  This supports IMGTEC MIPSfpga platform
@@ -413,12 +413,6 @@
 
 endmenu
 
-config SUPPORTS_BIG_ENDIAN
-	bool
-
-config SUPPORTS_LITTLE_ENDIAN
-	bool
-
 config SUPPORTS_CPU_MIPS32_R1
 	bool
 
diff --git a/arch/mips/mach-ath79/Kconfig b/arch/mips/mach-ath79/Kconfig
index cd85d1b..2fa6285 100644
--- a/arch/mips/mach-ath79/Kconfig
+++ b/arch/mips/mach-ath79/Kconfig
@@ -8,7 +8,7 @@
 	bool
 	select MIPS_TUNE_24KC
 	select ROM_EXCEPTION_VECTORS
-	select SUPPORTS_BIG_ENDIAN
+	select SUPPORT_BIG_ENDIAN
 	select SUPPORTS_CPU_MIPS32_R1
 	select SUPPORTS_CPU_MIPS32_R2
 	help
@@ -17,7 +17,7 @@
 config SOC_AR934X
 	bool
 	select MIPS_TUNE_74KC
-	select SUPPORTS_BIG_ENDIAN
+	select SUPPORT_BIG_ENDIAN
 	select SUPPORTS_CPU_MIPS32_R1
 	select SUPPORTS_CPU_MIPS32_R2
 	select USB_EHCI_IS_TDI if USB_EHCI_HCD
@@ -28,7 +28,7 @@
 	bool
 	select MIPS_TUNE_24KC
 	select ROM_EXCEPTION_VECTORS
-	select SUPPORTS_BIG_ENDIAN
+	select SUPPORT_BIG_ENDIAN
 	select SUPPORTS_CPU_MIPS32_R1
 	select SUPPORTS_CPU_MIPS32_R2
 	help
@@ -37,7 +37,7 @@
 config SOC_QCA956X
 	bool
 	select MIPS_TUNE_74KC
-	select SUPPORTS_BIG_ENDIAN
+	select SUPPORT_BIG_ENDIAN
 	select SUPPORTS_CPU_MIPS32_R1
 	select SUPPORTS_CPU_MIPS32_R2
 	help
diff --git a/arch/mips/mach-bmips/Kconfig b/arch/mips/mach-bmips/Kconfig
index eb9ea34..b140552 100644
--- a/arch/mips/mach-bmips/Kconfig
+++ b/arch/mips/mach-bmips/Kconfig
@@ -23,7 +23,7 @@
 	bool "BMIPS BCM3380 family"
 	select SYS_CACHE_SHIFT_4
 	select MIPS_TUNE_4KC
-	select SUPPORTS_BIG_ENDIAN
+	select SUPPORT_BIG_ENDIAN
 	select SUPPORTS_CPU_MIPS32_R1
 	select SYSRESET_WATCHDOG
 	help
@@ -33,7 +33,7 @@
 	bool "BMIPS BCM6318 family"
 	select SYS_CACHE_SHIFT_4
 	select MIPS_TUNE_4KC
-	select SUPPORTS_BIG_ENDIAN
+	select SUPPORT_BIG_ENDIAN
 	select SUPPORTS_CPU_MIPS32_R1
 	select SYSRESET_SYSCON
 	help
@@ -43,7 +43,7 @@
 	bool "BMIPS BCM6328 family"
 	select SYS_CACHE_SHIFT_4
 	select MIPS_TUNE_4KC
-	select SUPPORTS_BIG_ENDIAN
+	select SUPPORT_BIG_ENDIAN
 	select SUPPORTS_CPU_MIPS32_R1
 	select SYSRESET_SYSCON
 	help
@@ -53,7 +53,7 @@
 	bool "BMIPS BCM6338 family"
 	select SYS_CACHE_SHIFT_4
 	select MIPS_TUNE_4KC
-	select SUPPORTS_BIG_ENDIAN
+	select SUPPORT_BIG_ENDIAN
 	select SUPPORTS_CPU_MIPS32_R1
 	select SYSRESET_SYSCON
 	help
@@ -63,7 +63,7 @@
 	bool "BMIPS BCM6348 family"
 	select SYS_CACHE_SHIFT_4
 	select MIPS_TUNE_4KC
-	select SUPPORTS_BIG_ENDIAN
+	select SUPPORT_BIG_ENDIAN
 	select SUPPORTS_CPU_MIPS32_R1
 	select SYSRESET_WATCHDOG
 	help
@@ -73,7 +73,7 @@
 	bool "BMIPS BCM6358 family"
 	select SYS_CACHE_SHIFT_4
 	select MIPS_TUNE_4KC
-	select SUPPORTS_BIG_ENDIAN
+	select SUPPORT_BIG_ENDIAN
 	select SUPPORTS_CPU_MIPS32_R1
 	select SYSRESET_SYSCON
 	help
@@ -83,7 +83,7 @@
 	bool "BMIPS BCM6368 family"
 	select SYS_CACHE_SHIFT_4
 	select MIPS_TUNE_4KC
-	select SUPPORTS_BIG_ENDIAN
+	select SUPPORT_BIG_ENDIAN
 	select SUPPORTS_CPU_MIPS32_R1
 	select SYSRESET_SYSCON
 	help
@@ -93,7 +93,7 @@
 	bool "BMIPS BCM6362 family"
 	select SYS_CACHE_SHIFT_4
 	select MIPS_TUNE_4KC
-	select SUPPORTS_BIG_ENDIAN
+	select SUPPORT_BIG_ENDIAN
 	select SUPPORTS_CPU_MIPS32_R1
 	select SYSRESET_SYSCON
 	help
@@ -103,7 +103,7 @@
 	bool "BMIPS BCM63268 family"
 	select SYS_CACHE_SHIFT_4
 	select MIPS_TUNE_4KC
-	select SUPPORTS_BIG_ENDIAN
+	select SUPPORT_BIG_ENDIAN
 	select SUPPORTS_CPU_MIPS32_R1
 	select SYSRESET_SYSCON
 	help
@@ -114,7 +114,7 @@
 	bool "BMIPS BCM6838 family"
 	select SYS_CACHE_SHIFT_4
 	select MIPS_TUNE_4KC
-	select SUPPORTS_BIG_ENDIAN
+	select SUPPORT_BIG_ENDIAN
 	select SUPPORTS_CPU_MIPS32_R1
 	select SYSRESET_SYSCON
 	help
diff --git a/arch/mips/mach-jz47xx/Kconfig b/arch/mips/mach-jz47xx/Kconfig
index dcaac01..858173e 100644
--- a/arch/mips/mach-jz47xx/Kconfig
+++ b/arch/mips/mach-jz47xx/Kconfig
@@ -6,7 +6,7 @@
 
 config SOC_JZ4780
 	bool
-	select SUPPORTS_LITTLE_ENDIAN
+	select SUPPORT_LITTLE_ENDIAN
 	select SUPPORTS_CPU_MIPS32_R1
 	select SUPPORTS_CPU_MIPS32_R2
 	help
diff --git a/arch/mips/mach-mscc/Kconfig b/arch/mips/mach-mscc/Kconfig
index affc472..367d524 100644
--- a/arch/mips/mach-mscc/Kconfig
+++ b/arch/mips/mach-mscc/Kconfig
@@ -6,10 +6,10 @@
 config SOC_VCOREIII
 	select MIPS_TUNE_24KC
 	select ROM_EXCEPTION_VECTORS
-	select SUPPORTS_BIG_ENDIAN
+	select SUPPORT_BIG_ENDIAN
 	select SUPPORTS_CPU_MIPS32_R1
 	select SUPPORTS_CPU_MIPS32_R2
-	select SUPPORTS_LITTLE_ENDIAN
+	select SUPPORT_LITTLE_ENDIAN
 	bool
 
 config SYS_SOC
diff --git a/arch/mips/mach-pic32/Kconfig b/arch/mips/mach-pic32/Kconfig
index 2afa972..52d2eec 100644
--- a/arch/mips/mach-pic32/Kconfig
+++ b/arch/mips/mach-pic32/Kconfig
@@ -13,7 +13,7 @@
 	select ROM_EXCEPTION_VECTORS
 	select SUPPORTS_CPU_MIPS32_R1
 	select SUPPORTS_CPU_MIPS32_R2
-	select SUPPORTS_LITTLE_ENDIAN
+	select SUPPORT_LITTLE_ENDIAN
 	select SYS_MIPS_CACHE_INIT_RAM_LOAD
 	help
 	  This supports Microchip PIC32MZ[DA] family of microcontrollers.
diff --git a/boot/bootm.c b/boot/bootm.c
index 376d63a..480f8e6 100644
--- a/boot/bootm.c
+++ b/boot/bootm.c
@@ -740,18 +740,6 @@
 	eth_halt();
 #endif
 
-#if defined(CONFIG_CMD_USB)
-	/*
-	 * turn off USB to prevent the host controller from writing to the
-	 * SDRAM while Linux is booting. This could happen (at least for OHCI
-	 * controller), because the HCCA (Host Controller Communication Area)
-	 * lies within the SDRAM and the host controller writes continously to
-	 * this area (as busmaster!). The HccaFrameNumber is for example
-	 * updated every 1 ms within the HCCA structure in SDRAM! For more
-	 * details see the OpenHCI specification.
-	 */
-	usb_stop();
-#endif
 	return iflag;
 }
 
diff --git a/cmd/cpu.c b/cmd/cpu.c
index 9e32306..2755250 100644
--- a/cmd/cpu.c
+++ b/cmd/cpu.c
@@ -3,6 +3,7 @@
  * Copyright (c) 2015 Google, Inc
  * Written by Simon Glass <sjg@chromium.org>
  * Copyright (c) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ * Copyright 2024 NXP
  */
 
 #include <command.h>
@@ -18,6 +19,19 @@
 	"Device ID",
 };
 
+static struct udevice *cpu_find_device(unsigned long cpu_id)
+{
+	struct udevice *dev;
+
+	for (uclass_first_device(UCLASS_CPU, &dev); dev;
+	     uclass_next_device(&dev)) {
+		if (cpu_id == dev_seq(dev))
+			return dev;
+	}
+
+	return NULL;
+}
+
 static int print_cpu_list(bool detail)
 {
 	struct udevice *dev;
@@ -82,10 +96,36 @@
 	return 0;
 }
 
+static int do_cpu_release(struct cmd_tbl *cmdtp, int flag, int argc,
+			  char *const argv[])
+{
+	struct udevice *dev;
+	unsigned long cpu_id;
+	unsigned long long boot_addr;
+
+	if (argc != 3)
+		return CMD_RET_USAGE;
+
+	cpu_id = dectoul(argv[1], NULL);
+	dev = cpu_find_device(cpu_id);
+	if (!dev)
+		return CMD_RET_FAILURE;
+
+	boot_addr = simple_strtoull(argv[2], NULL, 16);
+
+	if (cpu_release_core(dev, boot_addr))
+		return CMD_RET_FAILURE;
+
+	return 0;
+}
+
 U_BOOT_LONGHELP(cpu,
 	"list	- list available CPUs\n"
-	"cpu detail	- show CPU detail");
+	"cpu detail	- show CPU detail\n"
+	"cpu release <core ID> <addr>	- Release CPU <core ID> at <addr>\n"
+	"            <core ID>: the sequence number in list subcommand outputs");
 
 U_BOOT_CMD_WITH_SUBCMDS(cpu, "display information about CPUs", cpu_help_text,
 	U_BOOT_SUBCMD_MKENT(list, 1, 1, do_cpu_list),
-	U_BOOT_SUBCMD_MKENT(detail, 1, 0, do_cpu_detail));
+	U_BOOT_SUBCMD_MKENT(detail, 1, 0, do_cpu_detail),
+	U_BOOT_SUBCMD_MKENT(release, 3, 0, do_cpu_release));
diff --git a/cmd/led.c b/cmd/led.c
index 4256b34..2f786f3 100644
--- a/cmd/led.c
+++ b/cmd/led.c
@@ -15,9 +15,7 @@
 	[LEDST_OFF]	= "off",
 	[LEDST_ON]	= "on",
 	[LEDST_TOGGLE]	= "toggle",
-#ifdef CONFIG_LED_BLINK
 	[LEDST_BLINK]	= "blink",
-#endif
 };
 
 enum led_state_t get_led_cmd(char *var)
@@ -75,9 +73,7 @@
 	enum led_state_t cmd;
 	const char *led_label;
 	struct udevice *dev;
-#ifdef CONFIG_LED_BLINK
 	int freq_ms = 0;
-#endif
 	int ret;
 
 	/* Validate arguments */
@@ -88,13 +84,11 @@
 		return list_leds();
 
 	cmd = argc > 2 ? get_led_cmd(argv[2]) : LEDST_COUNT;
-#ifdef CONFIG_LED_BLINK
 	if (cmd == LEDST_BLINK) {
 		if (argc < 4)
 			return CMD_RET_USAGE;
 		freq_ms = dectoul(argv[3], NULL);
 	}
-#endif
 	ret = led_get_by_label(led_label, &dev);
 	if (ret) {
 		printf("LED '%s' not found (err=%d)\n", led_label, ret);
@@ -106,13 +100,11 @@
 	case LEDST_TOGGLE:
 		ret = led_set_state(dev, cmd);
 		break;
-#ifdef CONFIG_LED_BLINK
 	case LEDST_BLINK:
 		ret = led_set_period(dev, freq_ms);
 		if (!ret)
 			ret = led_set_state(dev, LEDST_BLINK);
 		break;
-#endif
 	case LEDST_COUNT:
 		printf("LED '%s': ", led_label);
 		ret = show_led_state(dev);
diff --git a/common/Kconfig b/common/Kconfig
index 4bb9f08..83c81ed 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -626,8 +626,17 @@
 
 if CYCLIC
 
+config SPL_CYCLIC
+	bool "General-purpose cyclic execution mechanism (SPL)"
+	help
+	  This enables a general-purpose cyclic execution infrastructure in SPL,
+	  to allow "small" (run-time wise) functions to be executed at
+	  a specified frequency. Things like LED blinking or watchdog
+	  triggering are examples for such tasks.
+
 config CYCLIC_MAX_CPU_TIME_US
 	int "Sets the max allowed time for a cyclic function in us"
+	default 100000 if SANDBOX  # sandbox video is quite slow
 	default 5000
 	help
 	  The max allowed time for a cyclic function in us. If a functions
diff --git a/common/Makefile b/common/Makefile
index e983547..d871113c 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -79,7 +79,7 @@
 obj-y += dlmalloc.o
 obj-$(CONFIG_$(SPL_TPL_)SYS_MALLOC_F) += malloc_simple.o
 
-obj-$(CONFIG_CYCLIC) += cyclic.o
+obj-$(CONFIG_$(SPL_TPL_)CYCLIC) += cyclic.o
 obj-$(CONFIG_$(SPL_TPL_)EVENT) += event.o
 
 obj-$(CONFIG_$(SPL_TPL_)HASH) += hash.o
diff --git a/configs/M5208EVBE_defconfig b/configs/M5208EVBE_defconfig
index ed14662..c6c2ad7 100644
--- a/configs/M5208EVBE_defconfig
+++ b/configs/M5208EVBE_defconfig
@@ -5,6 +5,7 @@
 CONFIG_ENV_SECT_SIZE=0x2000
 CONFIG_DEFAULT_DEVICE_TREE="M5208EVBE"
 CONFIG_SYS_MONITOR_LEN=262144
+CONFIG_WATCHDOG_TIMEOUT_MSECS=5000
 CONFIG_SYS_LOAD_ADDR=0x40010000
 CONFIG_ENV_ADDR=0x2000
 CONFIG_TARGET_M5208EVBE=y
@@ -50,6 +51,5 @@
 CONFIG_MCFFEC=y
 CONFIG_MII=y
 CONFIG_MCFUART=y
-CONFIG_WATCHDOG_TIMEOUT_MSECS=5000
 CONFIG_WDT=y
 CONFIG_WDT_MCF=y
diff --git a/configs/M5235EVB_Flash32_defconfig b/configs/M5235EVB_Flash32_defconfig
index 45e0460..9b19185 100644
--- a/configs/M5235EVB_Flash32_defconfig
+++ b/configs/M5235EVB_Flash32_defconfig
@@ -5,6 +5,7 @@
 CONFIG_ENV_SECT_SIZE=0x2000
 CONFIG_DEFAULT_DEVICE_TREE="M5235EVB_Flash32"
 CONFIG_SYS_MONITOR_LEN=262144
+CONFIG_WATCHDOG_TIMEOUT_MSECS=5000
 CONFIG_SYS_LOAD_ADDR=0x20000
 CONFIG_ENV_ADDR=0xFFE04000
 CONFIG_TARGET_M5235EVB=y
@@ -58,4 +59,3 @@
 CONFIG_MCFFEC=y
 CONFIG_MII=y
 CONFIG_MCFUART=y
-CONFIG_WATCHDOG_TIMEOUT_MSECS=5000
diff --git a/configs/M5235EVB_defconfig b/configs/M5235EVB_defconfig
index 719a435..fac3071 100644
--- a/configs/M5235EVB_defconfig
+++ b/configs/M5235EVB_defconfig
@@ -5,6 +5,7 @@
 CONFIG_ENV_SECT_SIZE=0x2000
 CONFIG_DEFAULT_DEVICE_TREE="M5235EVB"
 CONFIG_SYS_MONITOR_LEN=262144
+CONFIG_WATCHDOG_TIMEOUT_MSECS=5000
 CONFIG_SYS_LOAD_ADDR=0x20000
 CONFIG_ENV_ADDR=0xFFE04000
 CONFIG_TARGET_M5235EVB=y
@@ -57,4 +58,3 @@
 CONFIG_MCFFEC=y
 CONFIG_MII=y
 CONFIG_MCFUART=y
-CONFIG_WATCHDOG_TIMEOUT_MSECS=5000
diff --git a/configs/M5272C3_defconfig b/configs/M5272C3_defconfig
index ccb756e..b6f8d18 100644
--- a/configs/M5272C3_defconfig
+++ b/configs/M5272C3_defconfig
@@ -5,6 +5,7 @@
 CONFIG_ENV_SECT_SIZE=0x2000
 CONFIG_DEFAULT_DEVICE_TREE="M5272C3"
 CONFIG_SYS_MONITOR_LEN=131072
+CONFIG_WATCHDOG_TIMEOUT_MSECS=10000
 CONFIG_SYS_LOAD_ADDR=0x20000
 CONFIG_ENV_ADDR=0xFFE04000
 CONFIG_TARGET_M5272C3=y
@@ -72,4 +73,3 @@
 CONFIG_MCFFEC=y
 CONFIG_MII=y
 CONFIG_MCFUART=y
-CONFIG_WATCHDOG_TIMEOUT_MSECS=10000
diff --git a/configs/M53017EVB_defconfig b/configs/M53017EVB_defconfig
index f0a7b1c..46df7c2 100644
--- a/configs/M53017EVB_defconfig
+++ b/configs/M53017EVB_defconfig
@@ -5,6 +5,7 @@
 CONFIG_ENV_SECT_SIZE=0x8000
 CONFIG_DEFAULT_DEVICE_TREE="M53017EVB"
 CONFIG_SYS_MONITOR_LEN=262144
+CONFIG_WATCHDOG_TIMEOUT_MSECS=5000
 CONFIG_SYS_LOAD_ADDR=0x40010000
 CONFIG_ENV_ADDR=0x40000
 CONFIG_TARGET_M53017EVB=y
@@ -57,4 +58,3 @@
 CONFIG_MCFRTC=y
 CONFIG_SYS_MCFRTC_BASE=0xFC0A8000
 CONFIG_MCFUART=y
-CONFIG_WATCHDOG_TIMEOUT_MSECS=5000
diff --git a/configs/M5329AFEE_defconfig b/configs/M5329AFEE_defconfig
index bbb5a23..3e5da1f 100644
--- a/configs/M5329AFEE_defconfig
+++ b/configs/M5329AFEE_defconfig
@@ -5,6 +5,7 @@
 CONFIG_ENV_SECT_SIZE=0x2000
 CONFIG_DEFAULT_DEVICE_TREE="M5329AFEE"
 CONFIG_SYS_MONITOR_LEN=262144
+CONFIG_WATCHDOG_TIMEOUT_MSECS=5000
 CONFIG_SYS_LOAD_ADDR=0x40010000
 CONFIG_ENV_ADDR=0x4000
 CONFIG_TARGET_M5329EVB=y
@@ -54,4 +55,3 @@
 CONFIG_MCFRTC=y
 CONFIG_SYS_MCFRTC_BASE=0xFC0A8000
 CONFIG_MCFUART=y
-CONFIG_WATCHDOG_TIMEOUT_MSECS=5000
diff --git a/configs/M5329BFEE_defconfig b/configs/M5329BFEE_defconfig
index ff8522b..ab7b8e6 100644
--- a/configs/M5329BFEE_defconfig
+++ b/configs/M5329BFEE_defconfig
@@ -5,6 +5,7 @@
 CONFIG_ENV_SECT_SIZE=0x2000
 CONFIG_DEFAULT_DEVICE_TREE="M5329BFEE"
 CONFIG_SYS_MONITOR_LEN=262144
+CONFIG_WATCHDOG_TIMEOUT_MSECS=5000
 CONFIG_SYS_LOAD_ADDR=0x40010000
 CONFIG_ENV_ADDR=0x4000
 CONFIG_TARGET_M5329EVB=y
@@ -56,4 +57,3 @@
 CONFIG_MCFRTC=y
 CONFIG_SYS_MCFRTC_BASE=0xFC0A8000
 CONFIG_MCFUART=y
-CONFIG_WATCHDOG_TIMEOUT_MSECS=5000
diff --git a/configs/M5373EVB_defconfig b/configs/M5373EVB_defconfig
index 981542f..1df1682 100644
--- a/configs/M5373EVB_defconfig
+++ b/configs/M5373EVB_defconfig
@@ -5,6 +5,7 @@
 CONFIG_ENV_SECT_SIZE=0x2000
 CONFIG_DEFAULT_DEVICE_TREE="M5373EVB"
 CONFIG_SYS_MONITOR_LEN=262144
+CONFIG_WATCHDOG_TIMEOUT_MSECS=3360
 CONFIG_SYS_LOAD_ADDR=0x40010000
 CONFIG_ENV_ADDR=0x4000
 CONFIG_TARGET_M5373EVB=y
@@ -56,4 +57,3 @@
 CONFIG_MCFRTC=y
 CONFIG_SYS_MCFRTC_BASE=0xFC0A8000
 CONFIG_MCFUART=y
-CONFIG_WATCHDOG_TIMEOUT_MSECS=3360
diff --git a/configs/am62ax_evm_a53_defconfig b/configs/am62ax_evm_a53_defconfig
index 2a71b06..4a351cd 100644
--- a/configs/am62ax_evm_a53_defconfig
+++ b/configs/am62ax_evm_a53_defconfig
@@ -37,6 +37,7 @@
 CONFIG_SPL_POWER_DOMAIN=y
 CONFIG_SPL_YMODEM_SUPPORT=y
 CONFIG_CMD_MMC=y
+CONFIG_CMD_REMOTEPROC=y
 CONFIG_OF_CONTROL=y
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_OF_UPSTREAM=y
@@ -73,8 +74,8 @@
 CONFIG_TI_SCI_POWER_DOMAIN=y
 CONFIG_K3_SYSTEM_CONTROLLER=y
 CONFIG_REMOTEPROC_TI_K3_ARM64=y
-CONFIG_REMOTEPROC_TI_K3_R5F=y
 CONFIG_REMOTEPROC_TI_K3_DSP=y
+CONFIG_REMOTEPROC_TI_K3_R5F=y
 CONFIG_RESET_TI_SCI=y
 CONFIG_DM_SERIAL=y
 CONFIG_SOC_DEVICE=y
@@ -84,4 +85,3 @@
 CONFIG_SPL_SYSRESET=y
 CONFIG_SYSRESET_TI_SCI=y
 CONFIG_FS_FAT_MAX_CLUSTSIZE=16384
-CONFIG_CMD_REMOTEPROC=y
diff --git a/configs/bitmain_antminer_s9_defconfig b/configs/bitmain_antminer_s9_defconfig
index 4bade84..afe8de8 100644
--- a/configs/bitmain_antminer_s9_defconfig
+++ b/configs/bitmain_antminer_s9_defconfig
@@ -99,4 +99,3 @@
 CONFIG_SYS_TIMER_COUNTS_DOWN=y
 CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y
 CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y
-CONFIG_TOOLS_MKEFICAPSULE=y
diff --git a/configs/chromebook_coral_defconfig b/configs/chromebook_coral_defconfig
index 9fcac5a..b3ebc04 100644
--- a/configs/chromebook_coral_defconfig
+++ b/configs/chromebook_coral_defconfig
@@ -9,7 +9,6 @@
 CONFIG_SPL_TEXT_BASE=0xfef10000
 CONFIG_TPL_TEXT_BASE=0xffff8000
 CONFIG_SPL_SYS_MALLOC_F_LEN=0xf000
-CONFIG_BOOTSTAGE_STASH_ADDR=0xfef00000
 CONFIG_DEBUG_UART_BASE=0xde000000
 CONFIG_DEBUG_UART_CLOCK=1843200
 CONFIG_DEBUG_UART_BOARD_INIT=y
@@ -32,6 +31,7 @@
 CONFIG_BOOTSTAGE_REPORT=y
 CONFIG_SPL_BOOTSTAGE_RECORD_COUNT=10
 CONFIG_BOOTSTAGE_STASH=y
+CONFIG_BOOTSTAGE_STASH_ADDR=0xfef00000
 CONFIG_USE_BOOTARGS=y
 CONFIG_BOOTARGS_SUBST=y
 CONFIG_BOOTCOMMAND="tpm init; tpm startup TPM2_SU_CLEAR; bootflow scan -lb"
diff --git a/configs/corstone1000_defconfig b/configs/corstone1000_defconfig
index ab4e0fe..26e157d 100644
--- a/configs/corstone1000_defconfig
+++ b/configs/corstone1000_defconfig
@@ -66,6 +66,5 @@
 CONFIG_FFA_SHARED_MM_BUF_OFFSET=0
 CONFIG_FFA_SHARED_MM_BUF_ADDR=0x02000000
 CONFIG_EFI_CAPSULE_ON_DISK=y
-CONFIG_EFI_IGNORE_OSINDICATIONS=y
 CONFIG_FWU_MULTI_BANK_UPDATE=y
 CONFIG_FWU_MDATA_V1=y
diff --git a/configs/dh_imx6_defconfig b/configs/dh_imx6_defconfig
index 41804a0..27dab9e 100644
--- a/configs/dh_imx6_defconfig
+++ b/configs/dh_imx6_defconfig
@@ -23,6 +23,7 @@
 CONFIG_SPL_SERIAL=y
 CONFIG_BOOTCOUNT_BOOTLIMIT=3
 CONFIG_SYS_BOOTCOUNT_ADDR=0x020CC068
+CONFIG_WATCHDOG_TIMEOUT_MSECS=60000
 CONFIG_SPL=y
 CONFIG_SYS_BOOTCOUNT_SINGLEWORD=y
 CONFIG_ENV_OFFSET_REDUND=0x110000
@@ -127,6 +128,5 @@
 CONFIG_SDP_LOADADDR=0x17ffffc0
 CONFIG_USB_GADGET_DOWNLOAD=y
 CONFIG_SPL_USB_SDP_SUPPORT=y
-CONFIG_WATCHDOG_TIMEOUT_MSECS=60000
 CONFIG_IMX_WATCHDOG=y
 CONFIG_BZIP2=y
diff --git a/configs/display5_defconfig b/configs/display5_defconfig
index 7707b32..1d3336b 100644
--- a/configs/display5_defconfig
+++ b/configs/display5_defconfig
@@ -25,6 +25,7 @@
 CONFIG_BOOTCOUNT_BOOTLIMIT=3
 CONFIG_SYS_BOOTCOUNT_ADDR=0x020CC068
 CONFIG_SPL_SYS_MALLOC_F_LEN=0x400
+CONFIG_WATCHDOG_TIMEOUT_MSECS=15000
 CONFIG_SPL=y
 CONFIG_SYS_BOOTCOUNT_SINGLEWORD=y
 CONFIG_ENV_OFFSET_REDUND=0x130000
@@ -127,5 +128,4 @@
 CONFIG_MXC_SPI=y
 CONFIG_SYSRESET=y
 CONFIG_SYSRESET_WATCHDOG=y
-CONFIG_WATCHDOG_TIMEOUT_MSECS=15000
 CONFIG_IMX_WATCHDOG=y
diff --git a/configs/display5_factory_defconfig b/configs/display5_factory_defconfig
index 58f4751..7c681f0 100644
--- a/configs/display5_factory_defconfig
+++ b/configs/display5_factory_defconfig
@@ -23,6 +23,7 @@
 CONFIG_SPL_MMC=y
 CONFIG_SPL_SERIAL=y
 CONFIG_SPL_SYS_MALLOC_F_LEN=0x400
+CONFIG_WATCHDOG_TIMEOUT_MSECS=15000
 CONFIG_SPL=y
 CONFIG_ENV_OFFSET_REDUND=0x130000
 CONFIG_SPL_SPI_FLASH_SUPPORT=y
@@ -134,6 +135,5 @@
 CONFIG_CI_UDC=y
 CONFIG_USB_GADGET_DOWNLOAD=y
 CONFIG_SPL_USB_SDP_SUPPORT=y
-CONFIG_WATCHDOG_TIMEOUT_MSECS=15000
 CONFIG_IMX_WATCHDOG=y
 CONFIG_PANIC_HANG=y
diff --git a/configs/evb-px30_defconfig b/configs/evb-px30_defconfig
index 488a259..972f418 100644
--- a/configs/evb-px30_defconfig
+++ b/configs/evb-px30_defconfig
@@ -29,8 +29,8 @@
 # CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
 CONFIG_SPL_ATF=y
 # CONFIG_TPL_FRAMEWORK is not set
-# CONFIG_TPL_SYS_MALLOC_SIMPLE is not set
 # CONFIG_TPL_BANNER_PRINT is not set
+# CONFIG_TPL_SYS_MALLOC_SIMPLE is not set
 # CONFIG_CMD_BOOTD is not set
 # CONFIG_CMD_ELF is not set
 # CONFIG_CMD_IMI is not set
diff --git a/configs/firefly-px30_defconfig b/configs/firefly-px30_defconfig
index 3fe1dc3..a1ce922 100644
--- a/configs/firefly-px30_defconfig
+++ b/configs/firefly-px30_defconfig
@@ -30,8 +30,8 @@
 # CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
 CONFIG_SPL_ATF=y
 # CONFIG_TPL_FRAMEWORK is not set
-# CONFIG_TPL_SYS_MALLOC_SIMPLE is not set
 # CONFIG_TPL_BANNER_PRINT is not set
+# CONFIG_TPL_SYS_MALLOC_SIMPLE is not set
 # CONFIG_CMD_BOOTD is not set
 # CONFIG_CMD_ELF is not set
 # CONFIG_CMD_IMI is not set
diff --git a/configs/ge_b1x5v2_defconfig b/configs/ge_b1x5v2_defconfig
index 20384bc..403a5a5 100644
--- a/configs/ge_b1x5v2_defconfig
+++ b/configs/ge_b1x5v2_defconfig
@@ -19,6 +19,7 @@
 CONFIG_SPL_TEXT_BASE=0x00908000
 CONFIG_SPL_SERIAL=y
 CONFIG_BOOTCOUNT_BOOTLIMIT=10
+CONFIG_WATCHDOG_TIMEOUT_MSECS=30000
 CONFIG_SPL=y
 CONFIG_DEBUG_UART_BASE=0x21ec000
 CONFIG_DEBUG_UART_CLOCK=24000000
@@ -134,6 +135,5 @@
 CONFIG_VIDEO=y
 CONFIG_VIDEO_IPUV3=y
 CONFIG_IMX_VIDEO_SKIP=y
-CONFIG_WATCHDOG_TIMEOUT_MSECS=30000
 CONFIG_IMX_WATCHDOG=y
 CONFIG_BCH=y
diff --git a/configs/ge_bx50v3_defconfig b/configs/ge_bx50v3_defconfig
index 2a42938..ce5dfb4 100644
--- a/configs/ge_bx50v3_defconfig
+++ b/configs/ge_bx50v3_defconfig
@@ -11,6 +11,7 @@
 CONFIG_DM_GPIO=y
 CONFIG_DEFAULT_DEVICE_TREE="imx6q-bx50v3"
 CONFIG_BOOTCOUNT_BOOTLIMIT=10
+CONFIG_WATCHDOG_TIMEOUT_MSECS=8000
 CONFIG_PCI=y
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
 CONFIG_FIT=y
@@ -97,7 +98,6 @@
 CONFIG_VIDEO_IPUV3=y
 CONFIG_IMX_VIDEO_SKIP=y
 CONFIG_IMX_HDMI=y
-CONFIG_WATCHDOG_TIMEOUT_MSECS=8000
 CONFIG_IMX_WATCHDOG=y
 CONFIG_BCH=y
 # CONFIG_EFI_LOADER is not set
diff --git a/configs/gwventana_emmc_defconfig b/configs/gwventana_emmc_defconfig
index ad99474..213a5e5 100644
--- a/configs/gwventana_emmc_defconfig
+++ b/configs/gwventana_emmc_defconfig
@@ -22,6 +22,7 @@
 CONFIG_SPL_DRIVERS_MISC=y
 CONFIG_SPL_STACK_R_ADDR=0x18000000
 CONFIG_SPL_STACK_R=y
+CONFIG_WATCHDOG_TIMEOUT_MSECS=60000
 CONFIG_SPL=y
 CONFIG_ENV_OFFSET_REDUND=0xD1400
 CONFIG_CMD_HDMIDETECT=y
@@ -174,5 +175,4 @@
 CONFIG_SPLASH_SCREEN=y
 CONFIG_SPLASH_SCREEN_ALIGN=y
 CONFIG_HIDE_LOGO_VERSION=y
-CONFIG_WATCHDOG_TIMEOUT_MSECS=60000
 CONFIG_IMX_WATCHDOG=y
diff --git a/configs/gwventana_nand_defconfig b/configs/gwventana_nand_defconfig
index 96c64c8..2306cd6 100644
--- a/configs/gwventana_nand_defconfig
+++ b/configs/gwventana_nand_defconfig
@@ -22,6 +22,7 @@
 CONFIG_SPL_DRIVERS_MISC=y
 CONFIG_SPL_STACK_R_ADDR=0x18000000
 CONFIG_SPL_STACK_R=y
+CONFIG_WATCHDOG_TIMEOUT_MSECS=60000
 CONFIG_SPL=y
 CONFIG_ENV_OFFSET_REDUND=0x1080000
 CONFIG_CMD_HDMIDETECT=y
@@ -181,5 +182,4 @@
 CONFIG_SPLASH_SCREEN=y
 CONFIG_SPLASH_SCREEN_ALIGN=y
 CONFIG_HIDE_LOGO_VERSION=y
-CONFIG_WATCHDOG_TIMEOUT_MSECS=60000
 CONFIG_IMX_WATCHDOG=y
diff --git a/configs/imx6q_bosch_acc_defconfig b/configs/imx6q_bosch_acc_defconfig
index 73ae4ac..dce1b64 100644
--- a/configs/imx6q_bosch_acc_defconfig
+++ b/configs/imx6q_bosch_acc_defconfig
@@ -18,6 +18,7 @@
 CONFIG_SPL_MMC=y
 CONFIG_SPL_SERIAL=y
 CONFIG_BOOTCOUNT_BOOTLIMIT=8
+CONFIG_WATCHDOG_TIMEOUT_MSECS=60000
 CONFIG_SPL_SIZE_LIMIT=69632
 CONFIG_SPL=y
 CONFIG_ENV_OFFSET_REDUND=0x1ff000
@@ -94,7 +95,6 @@
 CONFIG_DM_PMIC_PFUZE100=y
 CONFIG_DM_SERIAL=y
 CONFIG_MXC_UART=y
-CONFIG_WATCHDOG_TIMEOUT_MSECS=60000
 CONFIG_IMX_WATCHDOG=y
 CONFIG_WDT=y
 CONFIG_EXT4_WRITE=y
diff --git a/configs/imx8mm-phygate-tauri-l_defconfig b/configs/imx8mm-phygate-tauri-l_defconfig
index 41765f1..16ba7d4 100644
--- a/configs/imx8mm-phygate-tauri-l_defconfig
+++ b/configs/imx8mm-phygate-tauri-l_defconfig
@@ -46,6 +46,7 @@
 CONFIG_SYS_PROMPT="u-boot=> "
 # CONFIG_CMD_EXPORTENV is not set
 # CONFIG_CMD_IMPORTENV is not set
+CONFIG_CMD_ERASEENV=y
 # CONFIG_CMD_CRC32 is not set
 CONFIG_CMD_EEPROM=y
 CONFIG_SYS_I2C_EEPROM_ADDR_LEN=2
diff --git a/configs/imx8mm_evk_defconfig b/configs/imx8mm_evk_defconfig
index ff33d15..788770b 100644
--- a/configs/imx8mm_evk_defconfig
+++ b/configs/imx8mm_evk_defconfig
@@ -41,6 +41,7 @@
 CONFIG_SPL_POWER=y
 CONFIG_SPL_WATCHDOG=y
 CONFIG_SYS_PROMPT="u-boot=> "
+CONFIG_CMD_CPU=y
 # CONFIG_CMD_EXPORTENV is not set
 # CONFIG_CMD_IMPORTENV is not set
 # CONFIG_CMD_CRC32 is not set
@@ -68,6 +69,8 @@
 CONFIG_CLK_COMPOSITE_CCF=y
 CONFIG_SPL_CLK_IMX8MM=y
 CONFIG_CLK_IMX8MM=y
+CONFIG_CPU=y
+CONFIG_CPU_IMX=y
 CONFIG_MXC_GPIO=y
 CONFIG_DM_I2C=y
 CONFIG_SUPPORT_EMMC_BOOT=y
diff --git a/configs/imx8mn_evk_defconfig b/configs/imx8mn_evk_defconfig
index 2402e9e..679ca71 100644
--- a/configs/imx8mn_evk_defconfig
+++ b/configs/imx8mn_evk_defconfig
@@ -50,6 +50,7 @@
 CONFIG_SPL_POWER=y
 CONFIG_SPL_WATCHDOG=y
 CONFIG_SYS_PROMPT="u-boot=> "
+CONFIG_CMD_CPU=y
 # CONFIG_CMD_EXPORTENV is not set
 # CONFIG_CMD_IMPORTENV is not set
 CONFIG_CMD_ERASEENV=y
@@ -71,6 +72,8 @@
 CONFIG_SPL_DM=y
 CONFIG_SPL_CLK_IMX8MN=y
 CONFIG_CLK_IMX8MN=y
+CONFIG_CPU=y
+CONFIG_CPU_IMX=y
 CONFIG_MXC_GPIO=y
 CONFIG_DM_I2C=y
 CONFIG_SUPPORT_EMMC_BOOT=y
diff --git a/configs/imx8mp_evk_defconfig b/configs/imx8mp_evk_defconfig
index f5ba022..a2c0796 100644
--- a/configs/imx8mp_evk_defconfig
+++ b/configs/imx8mp_evk_defconfig
@@ -47,6 +47,7 @@
 CONFIG_SPL_POWER=y
 CONFIG_SPL_WATCHDOG=y
 CONFIG_SYS_PROMPT="u-boot=> "
+CONFIG_CMD_CPU=y
 # CONFIG_CMD_EXPORTENV is not set
 # CONFIG_CMD_IMPORTENV is not set
 # CONFIG_CMD_CRC32 is not set
@@ -74,6 +75,8 @@
 CONFIG_SPL_DM=y
 CONFIG_CLK_COMPOSITE_CCF=y
 CONFIG_CLK_IMX8MP=y
+CONFIG_CPU=y
+CONFIG_CPU_IMX=y
 CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0x42800000
 CONFIG_FASTBOOT_BUF_SIZE=0x20000000
diff --git a/configs/imx93_11x11_evk_defconfig b/configs/imx93_11x11_evk_defconfig
index 2246715..6f083e0 100644
--- a/configs/imx93_11x11_evk_defconfig
+++ b/configs/imx93_11x11_evk_defconfig
@@ -48,6 +48,7 @@
 CONFIG_SPL_POWER=y
 CONFIG_SPL_WATCHDOG=y
 CONFIG_SYS_PROMPT="u-boot=> "
+CONFIG_CMD_CPU=y
 CONFIG_CMD_ERASEENV=y
 # CONFIG_CMD_CRC32 is not set
 CONFIG_CMD_MEMTEST=y
diff --git a/configs/iot2050_defconfig b/configs/iot2050_defconfig
index e0c2b14..8654bf2 100644
--- a/configs/iot2050_defconfig
+++ b/configs/iot2050_defconfig
@@ -27,6 +27,7 @@
 CONFIG_SPL_BSS_START_ADDR=0x80a00000
 CONFIG_SPL_BSS_MAX_SIZE=0x80000
 CONFIG_SPL_STACK_R=y
+CONFIG_WATCHDOG_TIMEOUT_MSECS=0
 CONFIG_ENV_OFFSET_REDUND=0x6a0000
 CONFIG_SPL_SPI_FLASH_SUPPORT=y
 CONFIG_SPL_SPI=y
@@ -147,7 +148,6 @@
 CONFIG_USB_KEYBOARD=y
 # CONFIG_WATCHDOG is not set
 # CONFIG_WATCHDOG_AUTOSTART is not set
-CONFIG_WATCHDOG_TIMEOUT_MSECS=0
 CONFIG_WDT=y
 CONFIG_WDT_K3_RTI=y
 CONFIG_WDT_K3_RTI_LOAD_FW=y
diff --git a/configs/j7200_evm_a72_defconfig b/configs/j7200_evm_a72_defconfig
index 4db5654..fcfa926 100644
--- a/configs/j7200_evm_a72_defconfig
+++ b/configs/j7200_evm_a72_defconfig
@@ -85,6 +85,7 @@
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_OF_CONTROL=y
 CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_UPSTREAM=y
 CONFIG_SPL_MULTI_DTB_FIT=y
 CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y
 CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
@@ -96,7 +97,6 @@
 CONFIG_SPL_REGMAP=y
 CONFIG_SPL_SYSCON=y
 CONFIG_SPL_OF_TRANSLATE=y
-CONFIG_OF_UPSTREAM=y
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
 CONFIG_CLK_CCF=y
diff --git a/configs/j721e_evm_r5_defconfig b/configs/j721e_evm_r5_defconfig
index ffaf21d..f1c9bbd 100644
--- a/configs/j721e_evm_r5_defconfig
+++ b/configs/j721e_evm_r5_defconfig
@@ -82,7 +82,6 @@
 CONFIG_OF_CONTROL=y
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_SPL_MULTI_DTB_FIT=y
-CONFIG_SPL_OF_LIST="k3-j721e-r5-common-proc-board"
 CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y
 CONFIG_ENV_OVERWRITE=y
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
diff --git a/configs/j721s2_evm_a72_defconfig b/configs/j721s2_evm_a72_defconfig
index 5c3b52ba..5800e4b 100644
--- a/configs/j721s2_evm_a72_defconfig
+++ b/configs/j721s2_evm_a72_defconfig
@@ -34,9 +34,8 @@
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
 CONFIG_SPL_LOAD_FIT=y
 CONFIG_SPL_LOAD_FIT_ADDRESS=0x81000000
-CONFIG_OF_SYSTEM_SETUP=y
 CONFIG_BOOTSTD_FULL=y
-CONFIG_BOOTSTD_DEFAULTS=y
+CONFIG_OF_SYSTEM_SETUP=y
 CONFIG_BOOTCOMMAND="run envboot; bootflow scan -lb"
 CONFIG_LOGLEVEL=7
 CONFIG_SPL_MAX_SIZE=0xc0000
@@ -85,9 +84,8 @@
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_OF_CONTROL=y
 CONFIG_SPL_OF_CONTROL=y
-CONFIG_OF_LIST="ti/k3-j721s2-common-proc-board"
-CONFIG_SPL_MULTI_DTB_FIT=y
 CONFIG_OF_UPSTREAM=y
+CONFIG_SPL_MULTI_DTB_FIT=y
 CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y
 CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
diff --git a/configs/j721s2_evm_r5_defconfig b/configs/j721s2_evm_r5_defconfig
index 6404b1c..d0af664 100644
--- a/configs/j721s2_evm_r5_defconfig
+++ b/configs/j721s2_evm_r5_defconfig
@@ -83,7 +83,6 @@
 CONFIG_OF_CONTROL=y
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_SPL_MULTI_DTB_FIT=y
-CONFIG_SPL_OF_LIST="k3-j721s2-r5-common-proc-board"
 CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y
 CONFIG_ENV_OVERWRITE=y
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
diff --git a/configs/j722s_evm_r5_defconfig b/configs/j722s_evm_r5_defconfig
index d7b99cb..8ba3916 100644
--- a/configs/j722s_evm_r5_defconfig
+++ b/configs/j722s_evm_r5_defconfig
@@ -23,7 +23,6 @@
 CONFIG_SPL_BSS_START_ADDR=0x43c7b000
 CONFIG_SPL_BSS_MAX_SIZE=0x3000
 CONFIG_SPL_STACK_R=y
-CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x200000
 CONFIG_SPL_SIZE_LIMIT=0x3C000
 CONFIG_SPL_SIZE_LIMIT_PROVIDE_STACK=0x5000
 CONFIG_SPL_FS_FAT=y
diff --git a/configs/kontron-sl-mx8mm_defconfig b/configs/kontron-sl-mx8mm_defconfig
index f257028..1b7d22b 100644
--- a/configs/kontron-sl-mx8mm_defconfig
+++ b/configs/kontron-sl-mx8mm_defconfig
@@ -148,5 +148,4 @@
 CONFIG_EFI_SET_TIME=y
 CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y
 CONFIG_EFI_CAPSULE_ON_DISK=y
-CONFIG_EFI_IGNORE_OSINDICATIONS=y
 CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y
diff --git a/configs/kp_imx6q_tpc_defconfig b/configs/kp_imx6q_tpc_defconfig
index cc57ab0..fceda3f 100644
--- a/configs/kp_imx6q_tpc_defconfig
+++ b/configs/kp_imx6q_tpc_defconfig
@@ -16,6 +16,7 @@
 CONFIG_SYS_MONITOR_LEN=409600
 CONFIG_SPL_MMC=y
 CONFIG_SPL_SERIAL=y
+CONFIG_WATCHDOG_TIMEOUT_MSECS=60000
 CONFIG_SPL=y
 CONFIG_ENV_OFFSET_REDUND=0x102000
 CONFIG_SPL_PAYLOAD="u-boot.img"
@@ -83,5 +84,4 @@
 # CONFIG_SPL_DM_USB is not set
 CONFIG_USB_HOST_ETHER=y
 CONFIG_USB_ETHER_ASIX=y
-CONFIG_WATCHDOG_TIMEOUT_MSECS=60000
 CONFIG_IMX_WATCHDOG=y
diff --git a/configs/m53menlo_defconfig b/configs/m53menlo_defconfig
index db3a5b9..65a9875 100644
--- a/configs/m53menlo_defconfig
+++ b/configs/m53menlo_defconfig
@@ -18,11 +18,11 @@
 CONFIG_BOOTCOUNT_BOOTLIMIT=3
 CONFIG_SYS_BOOTCOUNT_ADDR=0x53FA401C
 CONFIG_SPL_STACK=0x70004000
+CONFIG_WATCHDOG_TIMEOUT_MSECS=8000
 CONFIG_SPL=y
 CONFIG_SYS_BOOTCOUNT_SINGLEWORD=y
 CONFIG_ENV_OFFSET_REDUND=0x180000
 CONFIG_SYS_LOAD_ADDR=0x70800000
-CONFIG_CMD_BMODE=y
 CONFIG_FIT=y
 CONFIG_BOOTDELAY=1
 CONFIG_OF_BOARD_SETUP=y
@@ -132,5 +132,4 @@
 CONFIG_VIDEO_BMP_GZIP=y
 CONFIG_VIDEO_LOGO_MAX_SIZE=0x200000
 CONFIG_BMP_16BPP=y
-CONFIG_WATCHDOG_TIMEOUT_MSECS=8000
 CONFIG_IMX_WATCHDOG=y
diff --git a/configs/mt7629_rfb_defconfig b/configs/mt7629_rfb_defconfig
index bccbbcc..8e9306a 100644
--- a/configs/mt7629_rfb_defconfig
+++ b/configs/mt7629_rfb_defconfig
@@ -60,9 +60,7 @@
 CONFIG_USE_SERVERIP=y
 CONFIG_SERVERIP="192.168.1.2"
 CONFIG_SPL_DM_SEQ_ALIAS=y
-CONFIG_REGMAP=y
 CONFIG_SPL_REGMAP=y
-CONFIG_SYSCON=y
 CONFIG_SPL_SYSCON=y
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
diff --git a/configs/mt8512_bm1_emmc_defconfig b/configs/mt8512_bm1_emmc_defconfig
index 2a285a5..c7ac0df 100644
--- a/configs/mt8512_bm1_emmc_defconfig
+++ b/configs/mt8512_bm1_emmc_defconfig
@@ -25,8 +25,6 @@
 # CONFIG_DOS_PARTITION is not set
 CONFIG_EFI_PARTITION=y
 CONFIG_ENV_OVERWRITE=y
-CONFIG_REGMAP=y
-CONFIG_SYSCON=y
 CONFIG_CLK=y
 CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0x56000000
diff --git a/configs/mvebu_espressobin_ultra-88f3720_defconfig b/configs/mvebu_espressobin_ultra-88f3720_defconfig
index c6ffaaa..974b6df 100644
--- a/configs/mvebu_espressobin_ultra-88f3720_defconfig
+++ b/configs/mvebu_espressobin_ultra-88f3720_defconfig
@@ -11,7 +11,6 @@
 CONFIG_ENV_OFFSET=0x3F0000
 CONFIG_ENV_SECT_SIZE=0x10000
 CONFIG_DM_GPIO=y
-CONFIG_OF_UPSTREAM=y
 CONFIG_DEFAULT_DEVICE_TREE="marvell/armada-3720-espressobin-ultra"
 CONFIG_SYS_LOAD_ADDR=0x6000000
 CONFIG_PCI=y
@@ -46,6 +45,7 @@
 CONFIG_CMD_SQUASHFS=y
 CONFIG_CMD_FS_UUID=y
 CONFIG_MAC_PARTITION=y
+CONFIG_OF_UPSTREAM=y
 CONFIG_ENV_OVERWRITE=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
@@ -64,7 +64,6 @@
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
 CONFIG_MMC_SDHCI_XENON=y
-CONFIG_MTD=y
 CONFIG_DM_MTD=y
 CONFIG_SPI_FLASH_GIGADEVICE=y
 CONFIG_SPI_FLASH_ISSI=y
@@ -75,8 +74,8 @@
 CONFIG_SPI_FLASH_MTD=y
 CONFIG_PHY_MARVELL=y
 CONFIG_PHY_FIXED=y
-CONFIG_PHY_GIGE=y
 CONFIG_DM_DSA=y
+CONFIG_PHY_GIGE=y
 CONFIG_MV88E6XXX=y
 CONFIG_MVNETA=y
 CONFIG_MVMDIO=y
@@ -87,6 +86,8 @@
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_ARMADA_37XX=y
 CONFIG_DM_REGULATOR_GPIO=y
+CONFIG_DM_RTC=y
+CONFIG_RTC_PCF8563=y
 CONFIG_DEFAULT_ENV_IS_RW=y
 CONFIG_MVEBU_A3700_UART=y
 CONFIG_MVEBU_A3700_SPI=y
@@ -97,10 +98,3 @@
 CONFIG_WDT=y
 CONFIG_WDT_ARMADA_37XX=y
 CONFIG_SHA1=y
-CONFIG_DM_RTC=y
-CONFIG_RTC_PCF8563=y
-# CONFIG_DEBUG_UART=y
-# CONFIG_DEBUG_UART_BASE=0xd0012000
-# CONFIG_DEBUG_UART_CLOCK=25804800
-# CONFIG_DEBUG_UART_SHIFT=2
-# CONFIG_DEBUG_UART_ANNOUNCE=y
diff --git a/configs/mx53ppd_defconfig b/configs/mx53ppd_defconfig
index 659de71..463cfc6 100644
--- a/configs/mx53ppd_defconfig
+++ b/configs/mx53ppd_defconfig
@@ -9,6 +9,7 @@
 CONFIG_DM_GPIO=y
 CONFIG_DEFAULT_DEVICE_TREE="imx53-ppd"
 CONFIG_BOOTCOUNT_BOOTLIMIT=10
+CONFIG_WATCHDOG_TIMEOUT_MSECS=8000
 CONFIG_SYS_LOAD_ADDR=0x72000000
 CONFIG_FIT=y
 CONFIG_SUPPORT_RAW_INITRD=y
@@ -81,6 +82,5 @@
 CONFIG_SYS_WHITE_ON_BLACK=y
 CONFIG_VIDEO_IPUV3=y
 CONFIG_IMX_VIDEO_SKIP=y
-CONFIG_WATCHDOG_TIMEOUT_MSECS=8000
 CONFIG_IMX_WATCHDOG=y
 CONFIG_BCH=y
diff --git a/configs/nyan-big_defconfig b/configs/nyan-big_defconfig
index 78fb758..efcc8f7 100644
--- a/configs/nyan-big_defconfig
+++ b/configs/nyan-big_defconfig
@@ -10,7 +10,6 @@
 CONFIG_DEFAULT_DEVICE_TREE="tegra124-nyan-big"
 CONFIG_SPL_TEXT_BASE=0x80108000
 CONFIG_SPL_STACK=0x800ffffc
-CONFIG_BOOTSTAGE_STASH_ADDR=0x83000000
 CONFIG_TEGRA124=y
 CONFIG_TARGET_NYAN_BIG=y
 CONFIG_TEGRA_GPU=y
@@ -20,6 +19,7 @@
 CONFIG_BOOTSTAGE=y
 CONFIG_SPL_BOOTSTAGE=y
 CONFIG_BOOTSTAGE_STASH=y
+CONFIG_BOOTSTAGE_STASH_ADDR=0x83000000
 CONFIG_OF_SYSTEM_SETUP=y
 CONFIG_SYS_PBSIZE=2087
 CONFIG_SYS_STDIO_DEREGISTER=y
diff --git a/configs/odroid-go2_defconfig b/configs/odroid-go2_defconfig
index a9af415..b38676a 100644
--- a/configs/odroid-go2_defconfig
+++ b/configs/odroid-go2_defconfig
@@ -36,8 +36,8 @@
 CONFIG_SPL_POWER=y
 CONFIG_SPL_ATF=y
 # CONFIG_TPL_FRAMEWORK is not set
-# CONFIG_TPL_SYS_MALLOC_SIMPLE is not set
 # CONFIG_TPL_BANNER_PRINT is not set
+# CONFIG_TPL_SYS_MALLOC_SIMPLE is not set
 # CONFIG_CMD_BOOTD is not set
 # CONFIG_CMD_ELF is not set
 # CONFIG_CMD_IMI is not set
diff --git a/configs/phycore-imx8mm_defconfig b/configs/phycore-imx8mm_defconfig
index f9fd725..6748e6f 100644
--- a/configs/phycore-imx8mm_defconfig
+++ b/configs/phycore-imx8mm_defconfig
@@ -12,6 +12,7 @@
 CONFIG_DEFAULT_DEVICE_TREE="freescale/imx8mm-phyboard-polis-rdk"
 CONFIG_SPL_TEXT_BASE=0x7E1000
 CONFIG_TARGET_PHYCORE_IMX8MM=y
+CONFIG_DM_RESET=y
 CONFIG_SYS_MONITOR_LEN=524288
 CONFIG_SPL_MMC=y
 CONFIG_SPL_SERIAL=y
@@ -23,6 +24,7 @@
 CONFIG_SPL=y
 CONFIG_ENV_OFFSET_REDUND=0x3E0000
 CONFIG_SYS_LOAD_ADDR=0x40480000
+CONFIG_PCI=y
 CONFIG_FIT=y
 CONFIG_FIT_EXTERNAL_OFFSET=0x3000
 CONFIG_SPL_LOAD_FIT=y
@@ -48,6 +50,7 @@
 CONFIG_SYS_PROMPT="u-boot=> "
 # CONFIG_CMD_EXPORTENV is not set
 # CONFIG_CMD_IMPORTENV is not set
+CONFIG_CMD_ERASEENV=y
 # CONFIG_CMD_CRC32 is not set
 CONFIG_CMD_EEPROM=y
 CONFIG_SYS_I2C_EEPROM_ADDR_LEN=2
@@ -59,6 +62,7 @@
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
+CONFIG_CMD_PCI=y
 CONFIG_CMD_SF_TEST=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
@@ -110,10 +114,15 @@
 CONFIG_PHY_GIGE=y
 CONFIG_FEC_MXC=y
 CONFIG_MII=y
+CONFIG_NVME_PCI=y
+CONFIG_PCIE_DW_IMX=y
+CONFIG_PHY=y
+CONFIG_PHY_IMX8M_PCIE=y
 CONFIG_PINCTRL=y
 CONFIG_SPL_PINCTRL=y
 CONFIG_PINCTRL_IMX8M=y
-CONFIG_DM_REGULATOR=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_IMX8M_POWER_DOMAIN=y
 CONFIG_DM_REGULATOR_FIXED=y
 CONFIG_DM_REGULATOR_GPIO=y
 CONFIG_DM_SERIAL=y
diff --git a/configs/phycore-imx8mp_defconfig b/configs/phycore-imx8mp_defconfig
index da7fe61..63f8a80 100644
--- a/configs/phycore-imx8mp_defconfig
+++ b/configs/phycore-imx8mp_defconfig
@@ -52,6 +52,7 @@
 CONFIG_SPL_WATCHDOG=y
 CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="u-boot=> "
+CONFIG_CMD_ERASEENV=y
 # CONFIG_CMD_CRC32 is not set
 CONFIG_CMD_EEPROM=y
 CONFIG_SYS_I2C_EEPROM_ADDR_LEN=2
diff --git a/configs/phycore_am62x_r5_defconfig b/configs/phycore_am62x_r5_defconfig
index c1664c4..b7d0273 100644
--- a/configs/phycore_am62x_r5_defconfig
+++ b/configs/phycore_am62x_r5_defconfig
@@ -90,6 +90,7 @@
 CONFIG_TI_SCI_PROTOCOL=y
 CONFIG_DA8XX_GPIO=y
 CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_OMAP24XX=y
 CONFIG_DM_MAILBOX=y
 CONFIG_K3_SEC_PROXY=y
 CONFIG_SPL_MISC=y
@@ -130,4 +131,3 @@
 CONFIG_OMAP_TIMER=y
 CONFIG_LIB_RATIONAL=y
 CONFIG_SPL_LIB_RATIONAL=y
-CONFIG_SYS_I2C_OMAP24XX=y
diff --git a/configs/px30-core-ctouch2-of10-px30_defconfig b/configs/px30-core-ctouch2-of10-px30_defconfig
index fdcbd8a..3d44c01 100644
--- a/configs/px30-core-ctouch2-of10-px30_defconfig
+++ b/configs/px30-core-ctouch2-of10-px30_defconfig
@@ -30,8 +30,8 @@
 # CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
 CONFIG_SPL_ATF=y
 # CONFIG_TPL_FRAMEWORK is not set
-# CONFIG_TPL_SYS_MALLOC_SIMPLE is not set
 # CONFIG_TPL_BANNER_PRINT is not set
+# CONFIG_TPL_SYS_MALLOC_SIMPLE is not set
 # CONFIG_CMD_BOOTD is not set
 # CONFIG_CMD_ELF is not set
 # CONFIG_CMD_IMI is not set
diff --git a/configs/px30-core-ctouch2-px30_defconfig b/configs/px30-core-ctouch2-px30_defconfig
index 343fd0b..7a65598 100644
--- a/configs/px30-core-ctouch2-px30_defconfig
+++ b/configs/px30-core-ctouch2-px30_defconfig
@@ -30,8 +30,8 @@
 # CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
 CONFIG_SPL_ATF=y
 # CONFIG_TPL_FRAMEWORK is not set
-# CONFIG_TPL_SYS_MALLOC_SIMPLE is not set
 # CONFIG_TPL_BANNER_PRINT is not set
+# CONFIG_TPL_SYS_MALLOC_SIMPLE is not set
 # CONFIG_CMD_BOOTD is not set
 # CONFIG_CMD_ELF is not set
 # CONFIG_CMD_IMI is not set
diff --git a/configs/px30-core-edimm2.2-px30_defconfig b/configs/px30-core-edimm2.2-px30_defconfig
index aa0bff4..0c80f40 100644
--- a/configs/px30-core-edimm2.2-px30_defconfig
+++ b/configs/px30-core-edimm2.2-px30_defconfig
@@ -30,8 +30,8 @@
 # CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
 CONFIG_SPL_ATF=y
 # CONFIG_TPL_FRAMEWORK is not set
-# CONFIG_TPL_SYS_MALLOC_SIMPLE is not set
 # CONFIG_TPL_BANNER_PRINT is not set
+# CONFIG_TPL_SYS_MALLOC_SIMPLE is not set
 # CONFIG_CMD_BOOTD is not set
 # CONFIG_CMD_ELF is not set
 # CONFIG_CMD_IMI is not set
diff --git a/configs/qcom_defconfig b/configs/qcom_defconfig
index 419e969..8852e83 100644
--- a/configs/qcom_defconfig
+++ b/configs/qcom_defconfig
@@ -36,9 +36,9 @@
 CONFIG_CMD_REGULATOR=y
 CONFIG_CMD_LOG=y
 CONFIG_OF_LIVE=y
-CONFIG_BUTTON_QCOM_PMIC=y
 CONFIG_USE_DEFAULT_ENV_FILE=y
 CONFIG_DEFAULT_ENV_FILE="board/qualcomm/default.env"
+CONFIG_BUTTON_QCOM_PMIC=y
 CONFIG_CLK=y
 CONFIG_CLK_QCOM_APQ8016=y
 CONFIG_CLK_QCOM_APQ8096=y
diff --git a/configs/sheep-rk3368_defconfig b/configs/sheep-rk3368_defconfig
index a591b27..00a7f79 100644
--- a/configs/sheep-rk3368_defconfig
+++ b/configs/sheep-rk3368_defconfig
@@ -8,7 +8,6 @@
 CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x300000
 CONFIG_DEFAULT_DEVICE_TREE="rk3368-sheep"
 CONFIG_ROCKCHIP_RK3368=y
-CONFIG_TARGET_SHEEP=y
 CONFIG_DEBUG_UART_BASE=0xFF1b0000
 CONFIG_DEBUG_UART_CLOCK=24000000
 CONFIG_SYS_LOAD_ADDR=0x800800
diff --git a/configs/socfpga_secu1_defconfig b/configs/socfpga_secu1_defconfig
index 5f68a71..b8d9c84 100644
--- a/configs/socfpga_secu1_defconfig
+++ b/configs/socfpga_secu1_defconfig
@@ -15,6 +15,7 @@
 # CONFIG_SPL_MMC is not set
 CONFIG_SPL_DRIVERS_MISC=y
 CONFIG_SPL_STACK=0x0
+CONFIG_WATCHDOG_TIMEOUT_MSECS=60000
 CONFIG_TARGET_SOCFPGA_ARRIA5_SECU1=y
 CONFIG_ENV_OFFSET_REDUND=0x120000
 # CONFIG_SPL_LIBDISK_SUPPORT is not set
@@ -106,7 +107,6 @@
 CONFIG_SPI=y
 CONFIG_SPI_MEM=y
 CONFIG_DESIGNWARE_SPI=y
-CONFIG_WATCHDOG_TIMEOUT_MSECS=60000
 CONFIG_DESIGNWARE_WATCHDOG=y
 CONFIG_WDT=y
 CONFIG_SYS_TIMER_COUNTS_DOWN=y
diff --git a/configs/synquacer_developerbox_defconfig b/configs/synquacer_developerbox_defconfig
index 7e1aeac..a7b3d19 100644
--- a/configs/synquacer_developerbox_defconfig
+++ b/configs/synquacer_developerbox_defconfig
@@ -14,7 +14,6 @@
 CONFIG_AHCI=y
 CONFIG_FIT=y
 CONFIG_SYS_BOOTM_LEN=0x800000
-CONFIG_BOOTSTAGE_STASH_SIZE=4096
 CONFIG_HUSH_PARSER=y
 CONFIG_SYS_MAXARGS=128
 CONFIG_CMD_FWU_METADATA=y
@@ -93,7 +92,6 @@
 CONFIG_EFI_SET_TIME=y
 CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y
 CONFIG_EFI_CAPSULE_ON_DISK=y
-CONFIG_EFI_IGNORE_OSINDICATIONS=y
 CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y
 CONFIG_FWU_MULTI_BANK_UPDATE=y
 CONFIG_FWU_MDATA_V2=y
diff --git a/configs/verdin-am62_a53_defconfig b/configs/verdin-am62_a53_defconfig
index 464d0bb..25f5f5e 100644
--- a/configs/verdin-am62_a53_defconfig
+++ b/configs/verdin-am62_a53_defconfig
@@ -74,7 +74,6 @@
 CONFIG_CMD_BCB=y
 CONFIG_CMD_CLK=y
 CONFIG_CMD_DFU=y
-CONFIG_CMD_DM=y
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
diff --git a/configs/warp7_bl33_defconfig b/configs/warp7_bl33_defconfig
index 51e5200..6b68681 100644
--- a/configs/warp7_bl33_defconfig
+++ b/configs/warp7_bl33_defconfig
@@ -4,7 +4,7 @@
 CONFIG_ENV_SIZE=0x2000
 CONFIG_ENV_OFFSET=0x80000
 CONFIG_DM_GPIO=y
-CONFIG_DEFAULT_DEVICE_TREE="imx7s-warp"
+CONFIG_DEFAULT_DEVICE_TREE="nxp/imx/imx7s-warp"
 CONFIG_TARGET_WARP7=y
 CONFIG_OF_LIBFDT_OVERLAY=y
 CONFIG_ARMV7_BOOT_SEC_DEFAULT=y
diff --git a/configs/warp7_defconfig b/configs/warp7_defconfig
index 48042b7..679b6e8 100644
--- a/configs/warp7_defconfig
+++ b/configs/warp7_defconfig
@@ -5,7 +5,7 @@
 CONFIG_ENV_SIZE=0x2000
 CONFIG_ENV_OFFSET=0xC0000
 CONFIG_DM_GPIO=y
-CONFIG_DEFAULT_DEVICE_TREE="imx7s-warp"
+CONFIG_DEFAULT_DEVICE_TREE="nxp/imx/imx7s-warp"
 CONFIG_TARGET_WARP7=y
 CONFIG_ARMV7_BOOT_SEC_DEFAULT=y
 # CONFIG_ARMV7_VIRT is not set
diff --git a/configs/work_92105_defconfig b/configs/work_92105_defconfig
index 1de6188..4b73e15 100644
--- a/configs/work_92105_defconfig
+++ b/configs/work_92105_defconfig
@@ -12,7 +12,6 @@
 CONFIG_NR_DRAM_BANKS=2
 CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
 CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x8007ff20
-CONFIG_TARGET_WORK_92105=y
 CONFIG_CMD_HD44760=y
 CONFIG_CMD_MAX6957=y
 CONFIG_ENV_SIZE=0x20000
diff --git a/configs/xilinx_zynq_virt_defconfig b/configs/xilinx_zynq_virt_defconfig
index 9be904f..b2a1f14 100644
--- a/configs/xilinx_zynq_virt_defconfig
+++ b/configs/xilinx_zynq_virt_defconfig
@@ -155,4 +155,3 @@
 CONFIG_SPL_GZIP=y
 CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y
 CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y
-CONFIG_TOOLS_MKEFICAPSULE=y
diff --git a/doc/develop/bootstd/android.rst b/doc/develop/bootstd/android.rst
new file mode 100644
index 0000000..41701d5
--- /dev/null
+++ b/doc/develop/bootstd/android.rst
@@ -0,0 +1,39 @@
+.. SPDX-License-Identifier: GPL-2.0+:
+
+Android Bootmeth
+================
+
+Android provides a mechanism for booting its Operating System from eMMC storage,
+described on `source.android.com <https://source.android.com/docs/core/architecture/bootloader>`_.
+
+Android has strong requirements about partitioning layout which are described
+`here <https://source.android.com/docs/core/architecture/partitions>`_.
+Because multiple partitions are required, this bootmeth only operates on whole mmc
+devices which have a valid partition table.
+
+When invoked on a bootdev, this bootmeth searches for the ``misc`` partition in order
+to read the *boot mode*, which can be one of following:
+
+Normal
+  Boot the regular Android Operating System.
+
+Recovery
+  Boot a slimmed down Recovery Operating System. Can be used
+  to factory reset the device or to apply system updates.
+
+Bootloader
+  Stay in U-Boot and wait for fastboot commands from the host.
+
+After the *boot mode* has been determined, this bootmeth will read the *slot suffix*
+from the ``misc`` partition. For details about slots, see
+`the AOSP documentation <https://source.android.com/docs/core/ota/ab#slots>`_.
+
+When both the *boot mode* and the *slot suffix* are known, the bootflow is created.
+
+When the bootflow is booted, the bootmeth reads the kernel, the boot arguments and
+the vendor ramdisk.
+It then boots the kernel using bootm. The relevant devicetree blob is extracted
+from the ``boot`` partition based on the ``adtb_idx`` environment variable.
+
+The compatible string "u-boot,android" is used for the driver. It is present
+if `CONFIG_BOOTMETH_ANDROID` is enabled.
diff --git a/doc/develop/bootstd/index.rst b/doc/develop/bootstd/index.rst
index 9d35b56..4c4e26c 100644
--- a/doc/develop/bootstd/index.rst
+++ b/doc/develop/bootstd/index.rst
@@ -10,6 +10,7 @@
    extlinux
    pxelinux
    qfw
+   android
    cros
    script
    sandbox
diff --git a/doc/develop/bootstd/overview.rst b/doc/develop/bootstd/overview.rst
index ff3cc48..c6f0038 100644
--- a/doc/develop/bootstd/overview.rst
+++ b/doc/develop/bootstd/overview.rst
@@ -429,7 +429,7 @@
 
 Bootmeth drivers are provided for booting from various media:
 
-   - Android bootflow (boot image v4)
+   - :doc:`Android <android>` bootflow (boot image v4)
    - :doc:`ChromiumOS <cros>` ChromiumOS boot from a disk
    - EFI boot using bootefi from disk
    - EFI boot using boot manager
diff --git a/doc/develop/devicetree/control.rst b/doc/develop/devicetree/control.rst
index ca4fb0b..211f7e4 100644
--- a/doc/develop/devicetree/control.rst
+++ b/doc/develop/devicetree/control.rst
@@ -96,12 +96,12 @@
 the next branch opens (refer: :doc:`../release_cycle`) with the latest mainline
 Linux kernel release. To sync the `dts/upstream/` subtree, run::
 
-    ./dts/update-dts-subtree.sh pull <devicetree-rebasing-release-tag>
+    ./tools/update-subtree.sh pull dts <devicetree-rebasing-release-tag>
 
 If required it is also possible to cherry-pick fixes from the
 devicetree-rebasing repository prior to next sync, usage::
 
-    ./dts/update-dts-subtree.sh pick <devicetree-rebasing-commit-id>
+    ./tools/update-subtree.sh pick dts <devicetree-rebasing-commit-id>
 
 
 Configuration
@@ -116,8 +116,8 @@
 newly added board support then one option is that you can add the corresponding
 devicetree source file as `arch/<arch>/dts/<name>.dts`. To select that add `#
 CONFIG_OF_UPSTREAM is not set` and set `DEFAULT_DEVICE_TREE=<name>` when
-prompted by Kconfig. Another option is that you can use use the "pick" option of
-`dts/update-dts-subtree.sh` mentioned above to bring in the commits that you
+prompted by Kconfig. Another option is that you can use the "pick" option of
+`tools/update-subtree.sh` mentioned above to bring in the commits that you
 need.
 
 This should include your CPU or SoC's devicetree file. On top of that any U-Boot
diff --git a/doc/develop/qconfig.rst b/doc/develop/qconfig.rst
index 8efb1eb..123779e 100644
--- a/doc/develop/qconfig.rst
+++ b/doc/develop/qconfig.rst
@@ -85,6 +85,20 @@
     3 matches
     pg_wcom_seli8_defconfig highbank_defconfig pg_wcom_expu1_defconfig
 
+It is also possible to search for particular values. For example, this finds all
+boards with an empty string for `CONFIG_DEFAULT_FDT_FILE`::
+
+    ./tools/qconfig.py -f DEFAULT_FDT_FILE=\"\"
+    1092 matches
+    ...
+
+This finds boards which have a value for SYS_MAXARGS other than 64::
+
+    ./tools/qconfig.py -f ~SYS_MAXARGS=64
+    cfg CONFIG_SYS_MAXARGS
+    281 matches
+    ...
+
 
 Finding implied CONFIGs
 -----------------------
diff --git a/doc/develop/release_cycle.rst b/doc/develop/release_cycle.rst
index e3c13b9..776af60 100644
--- a/doc/develop/release_cycle.rst
+++ b/doc/develop/release_cycle.rst
@@ -55,7 +55,7 @@
 
 * The Merge Window for the next release (v2024.10) is **closed**.
 
-* The next branch is now **closed**.
+* The next branch is now **open**.
 
 * Release "v2024.10" is scheduled for 07 October 2024.
 
@@ -69,7 +69,7 @@
 
 * U-Boot v2024.10-rc1 was released on Mon 22 July 2024.
 
-.. * U-Boot v2024.10-rc2 was released on Mon 05 August 2024.
+* U-Boot v2024.10-rc2 was released on Mon 05 August 2024.
 
 .. * U-Boot v2024.10-rc3 was released on Mon 19 August 2024.
 
diff --git a/doc/develop/spl.rst b/doc/develop/spl.rst
index 0a3e572..4bb48e6 100644
--- a/doc/develop/spl.rst
+++ b/doc/develop/spl.rst
@@ -121,6 +121,8 @@
 also find the previous and next phase and get the phase name.
 
 
+.. _fdtgrep_filter:
+
 Device tree
 -----------
 The U-Boot device tree is filtered by the fdtgrep tools during the build
diff --git a/doc/mkeficapsule.1 b/doc/mkeficapsule.1
index c4c2057..c3d0f21 100644
--- a/doc/mkeficapsule.1
+++ b/doc/mkeficapsule.1
@@ -88,6 +88,10 @@
 Capsule OEM flag, value between 0x0000 to 0xffff
 
 .TP
+.BR -V ", " --version
+Print version information and exit.
+
+.TP
 .BR -h ", " --help
 Print a help message
 
diff --git a/doc/usage/cmd/cpu.rst b/doc/usage/cmd/cpu.rst
new file mode 100644
index 0000000..8b0b7d5
--- /dev/null
+++ b/doc/usage/cmd/cpu.rst
@@ -0,0 +1,101 @@
+.. SPDX-License-Identifier: GPL-2.0+
+.. Copyright 2024 NXP
+
+.. index::
+   single: cpu (command)
+
+cpu command
+===========
+
+Synopsis
+--------
+
+::
+
+    cpu list
+    cpu detail
+    cpu release <core ID> <addr>
+
+Description
+-----------
+
+The *cpu* command prints information about the CPUs, and release a CPU core
+to a given address to run applications.
+
+
+cpu list
+~~~~~~~~
+
+The 'list' subcommand lists and prints brief information of all the CPU cores,
+the CPU information is provided by vendors' CPU driver.
+
+cpu detail
+~~~~~~~~~~
+
+The 'detail' subcommand prints more details about the CPU cores, including
+CPU ID, core frequency and feature list.
+
+cpu release
+~~~~~~~~~~~
+
+The 'release' subcommand is used to release a CPU core to run a baremetal or
+RTOS applications.
+The parameter <core ID> is the sequence number of the CPU core to release.
+The parameter <addr> is the address to run of the specified core after release.
+
+
+Examples
+--------
+
+cpu list
+~~~~~~~~
+
+This example lists all the CPU cores On i.MX8M Plus EVK:
+::
+
+    u-boot=> cpu list
+      0: cpu@0      NXP i.MX8MP Rev1.1 A53 at 1200 MHz at 31C
+      1: cpu@1      NXP i.MX8MP Rev1.1 A53 at 1200 MHz at 30C
+      2: cpu@2      NXP i.MX8MP Rev1.1 A53 at 1200 MHz at 31C
+      3: cpu@3      NXP i.MX8MP Rev1.1 A53 at 1200 MHz at 31C
+
+cpu detail
+~~~~~~~~~~
+
+This example prints the details of the CPU cores On i.MX8M Plus EVK:
+::
+
+    u-boot=> cpu detail
+      0: cpu@0      NXP i.MX8MP Rev1.1 A53 at 1200 MHz at 31C
+            ID = 0, freq = 1.2 GHz: L1 cache, MMU
+      1: cpu@1      NXP i.MX8MP Rev1.1 A53 at 1200 MHz at 30C
+            ID = 0, freq = 1.2 GHz: L1 cache, MMU
+      2: cpu@2      NXP i.MX8MP Rev1.1 A53 at 1200 MHz at 31C
+            ID = 0, freq = 1.2 GHz: L1 cache, MMU
+      3: cpu@3      NXP i.MX8MP Rev1.1 A53 at 1200 MHz at 31C
+            ID = 0, freq = 1.2 GHz: L1 cache, MMU
+
+cpu release
+~~~~~~~~~~~
+
+This example shows release the LAST CPU core to run a RTOS application, on
+i.MX8M Plus EVK:
+::
+
+     u-boot=> load mmc 1:2 c0000000 /hello_world.bin
+     66008 bytes read in 5 ms (12.6 MiB/s)
+     u-boot=> dcache flush; icache flush
+     u-boot=> cpu release 3 c0000000
+     Released CPU core (mpidr: 0x3) to address 0xc0000000
+
+
+Configuration
+-------------
+
+The cpu command is available if CONFIG_CMD_CPU=y.
+
+Return code
+-----------
+
+The return value $? is set to 0 (true) if the command is successful,
+1 (false) otherwise.
diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index 49b354e..1f6518b 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -50,6 +50,7 @@
    cmd/coninfo
    cmd/conitrace
    cmd/cp
+   cmd/cpu
    cmd/cyclic
    cmd/dm
    cmd/ebtupdate
diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index c48a62b..16169da 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -178,7 +178,7 @@
 bulk_get_err:
 	err = clk_release_all(bulk->clks, bulk->count);
 	if (err)
-		debug("%s: could release all clocks for %p\n",
+		debug("%s: could not release all clocks for %p\n",
 		      __func__, dev);
 
 	return ret;
@@ -609,7 +609,7 @@
 	struct clk *clkp = NULL;
 	int ret;
 
-	debug("%s(clk=%p)\n", __func__, clk);
+	debug("%s(clk=%p name=%s)\n", __func__, clk, clk->dev->name);
 	if (!clk_valid(clk))
 		return 0;
 	ops = clk_dev_ops(clk->dev);
@@ -670,7 +670,7 @@
 	struct clk *clkp = NULL;
 	int ret;
 
-	debug("%s(clk=%p)\n", __func__, clk);
+	debug("%s(clk=%p name=%s)\n", __func__, clk, clk->dev->name);
 	if (!clk_valid(clk))
 		return 0;
 	ops = clk_dev_ops(clk->dev);
diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c
index e538f04..a91c676 100644
--- a/drivers/clk/imx/clk-imx8mm.c
+++ b/drivers/clk/imx/clk-imx8mm.c
@@ -21,6 +21,8 @@
 static const char * const sys_pll2_bypass_sels[] = {"sys_pll2", "sys_pll2_ref_sel", };
 static const char * const sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", };
 
+static const char * const imx8mm_arm_core_sels[] = {"arm_a53_src", "arm_pll_out", };
+
 static const char * const imx8mm_a53_sels[] = {"clock-osc-24m", "arm_pll_out", "sys_pll2_500m",
 					       "sys_pll2_1000m", "sys_pll1_800m", "sys_pll1_400m",
 					       "audio_pll1_out", "sys_pll3_out", };
@@ -417,6 +419,12 @@
 	       imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0));
 #endif
 
+	clk_dm(IMX8MM_CLK_ARM,
+	       imx_clk_mux2_flags("arm_core", base + 0x9880, 24, 1,
+				  imx8mm_arm_core_sels,
+				  ARRAY_SIZE(imx8mm_arm_core_sels),
+				  CLK_IS_CRITICAL));
+
 	return 0;
 }
 
diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c
index 8911e34..125215e 100644
--- a/drivers/clk/imx/clk-imx8mn.c
+++ b/drivers/clk/imx/clk-imx8mn.c
@@ -23,6 +23,8 @@
 static const char * const sys_pll2_bypass_sels[] = {"sys_pll2", "sys_pll2_ref_sel", };
 static const char * const sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", };
 
+static const char * const imx8mn_arm_core_sels[] = {"arm_a53_src", "arm_pll_out", };
+
 static const char * const imx8mn_a53_sels[] = {"clock-osc-24m", "arm_pll_out", "sys_pll2_500m",
 					       "sys_pll2_1000m", "sys_pll1_800m", "sys_pll1_400m",
 					       "audio_pll1_out", "sys_pll3_out", };
@@ -403,6 +405,12 @@
 	       imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0));
 #endif
 
+	clk_dm(IMX8MN_CLK_ARM,
+	       imx_clk_mux2_flags("arm_core", base + 0x9880, 24, 1,
+				  imx8mn_arm_core_sels,
+				  ARRAY_SIZE(imx8mn_arm_core_sels),
+				  CLK_IS_CRITICAL));
+
 	return 0;
 }
 
diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c
index 6b18483..34d91cd 100644
--- a/drivers/clk/imx/clk-imx8mp.c
+++ b/drivers/clk/imx/clk-imx8mp.c
@@ -21,6 +21,8 @@
 static const char * const sys_pll2_bypass_sels[] = {"sys_pll2", "sys_pll2_ref_sel", };
 static const char * const sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", };
 
+static const char * const imx8mp_arm_core_sels[] = {"arm_a53_src", "arm_pll_out", };
+
 static const char * const imx8mp_a53_sels[] = {"clock-osc-24m", "arm_pll_out", "sys_pll2_500m",
 					       "sys_pll2_1000m", "sys_pll1_800m", "sys_pll1_400m",
 					       "audio_pll1_out", "sys_pll3_out", };
@@ -354,6 +356,12 @@
 
 	clk_dm(IMX8MP_CLK_USDHC3_ROOT, imx_clk_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0));
 
+	clk_dm(IMX8MP_CLK_ARM,
+	       imx_clk_mux2_flags("arm_core", base + 0x9880, 24, 1,
+				  imx8mp_arm_core_sels,
+				  ARRAY_SIZE(imx8mp_arm_core_sels),
+				  CLK_IS_CRITICAL));
+
 	return 0;
 }
 
diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index d2c45be..66683ae 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -35,6 +35,68 @@
 
 /* shared functions */
 
+static int mtk_clk_get_id(struct clk *clk)
+{
+	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+	int id = clk->id;
+
+	/* Remap the clk ID to the one expected by driver */
+	if (priv->tree->id_offs_map)
+		id = priv->tree->id_offs_map[id];
+
+	return id;
+}
+
+static int mtk_gate_enable(void __iomem *base, const struct mtk_gate *gate)
+{
+	u32 bit = BIT(gate->shift);
+
+	switch (gate->flags & CLK_GATE_MASK) {
+	case CLK_GATE_SETCLR:
+		writel(bit, base + gate->regs->clr_ofs);
+		break;
+	case CLK_GATE_SETCLR_INV:
+		writel(bit, base + gate->regs->set_ofs);
+		break;
+	case CLK_GATE_NO_SETCLR:
+		clrsetbits_le32(base + gate->regs->sta_ofs, bit, 0);
+		break;
+	case CLK_GATE_NO_SETCLR_INV:
+		clrsetbits_le32(base + gate->regs->sta_ofs, bit, bit);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int mtk_gate_disable(void __iomem *base, const struct mtk_gate *gate)
+{
+	u32 bit = BIT(gate->shift);
+
+	switch (gate->flags & CLK_GATE_MASK) {
+	case CLK_GATE_SETCLR:
+		writel(bit, base + gate->regs->set_ofs);
+		break;
+	case CLK_GATE_SETCLR_INV:
+		writel(bit, base + gate->regs->clr_ofs);
+		break;
+	case CLK_GATE_NO_SETCLR:
+		clrsetbits_le32(base + gate->regs->sta_ofs, bit, bit);
+		break;
+	case CLK_GATE_NO_SETCLR_INV:
+		clrsetbits_le32(base + gate->regs->sta_ofs, bit, 0);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 /*
  * In case the rate change propagation to parent clocks is undesirable,
  * this function is recursively called to find the parent to calculate
@@ -54,13 +116,27 @@
 }
 
 static int mtk_clk_mux_set_parent(void __iomem *base, u32 parent,
+				  u32 parent_type,
 				  const struct mtk_composite *mux)
 {
 	u32 val, index = 0;
 
-	while (mux->parent[index] != parent)
-		if (++index == mux->num_parents)
-			return -EINVAL;
+	if (mux->flags & CLK_PARENT_MIXED) {
+		/*
+		 * Assume parent_type in clk_tree to be always set with
+		 * CLK_PARENT_MIXED implementation. If it's not, assume
+		 * not parent clk ID clash is possible.
+		 */
+		while (mux->parent_flags[index].id != parent ||
+		       (parent_type && (mux->parent_flags[index].flags & CLK_PARENT_MASK) !=
+			parent_type))
+			if (++index == mux->num_parents)
+				return -EINVAL;
+	} else {
+		while (mux->parent[index] != parent)
+			if (++index == mux->num_parents)
+				return -EINVAL;
+	}
 
 	if (mux->flags & CLK_MUX_SETCLR_UPD) {
 		val = (mux->mux_mask << mux->mux_shift);
@@ -117,12 +193,14 @@
  * for the integer part and the remaining bits (if present) for the
  * fractional part. Also they have a 3 bit power-of-two post divider.
  */
-static void mtk_pll_set_rate_regs(struct clk *clk, u32 pcw, int postdiv)
+static void mtk_pll_set_rate_regs(struct mtk_clk_priv *priv, u32 id,
+				  u32 pcw, int postdiv)
 {
-	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
-	const struct mtk_pll_data *pll = &priv->tree->plls[clk->id];
+	const struct mtk_pll_data *pll;
 	u32 val, chg;
 
+	pll = &priv->tree->plls[id];
+
 	/* set postdiv */
 	val = readl(priv->base + pll->pd_reg);
 	val &= ~(POSTDIV_MASK << pll->pd_shift);
@@ -153,21 +231,24 @@
 
 /**
  * mtk_pll_calc_values - calculate good values for a given input frequency.
- * @clk:	The clk
+ * @priv:	The mtk priv struct
+ * @id:		The clk id
  * @pcw:	The pcw value (output)
  * @postdiv:	The post divider (output)
  * @freq:	The desired target frequency
  */
-static void mtk_pll_calc_values(struct clk *clk, u32 *pcw, u32 *postdiv,
-				u32 freq)
+static void mtk_pll_calc_values(struct mtk_clk_priv *priv, u32 id,
+				u32 *pcw, u32 *postdiv, u32 freq)
 {
-	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
-	const struct mtk_pll_data *pll = &priv->tree->plls[clk->id];
-	unsigned long fmin = pll->fmin ? pll->fmin : 1000 * MHZ;
+	const struct mtk_pll_data *pll;
+	unsigned long fmin;
 	u64 _pcw;
 	int ibits;
 	u32 val;
 
+	pll = &priv->tree->plls[id];
+	fmin = pll->fmin ? pll->fmin : 1000 * MHZ;
+
 	if (freq > pll->fmax)
 		freq = pll->fmax;
 
@@ -187,11 +268,16 @@
 
 static ulong mtk_apmixedsys_set_rate(struct clk *clk, ulong rate)
 {
+	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+	int id = mtk_clk_get_id(clk);
 	u32 pcw = 0;
 	u32 postdiv;
 
-	mtk_pll_calc_values(clk, &pcw, &postdiv, rate);
-	mtk_pll_set_rate_regs(clk, pcw, postdiv);
+	if (priv->tree->gates && id >= priv->tree->gates_offs)
+		return -EINVAL;
+
+	mtk_pll_calc_values(priv, id, &pcw, &postdiv, rate);
+	mtk_pll_set_rate_regs(priv, id, pcw, postdiv);
 
 	return 0;
 }
@@ -199,10 +285,20 @@
 static ulong mtk_apmixedsys_get_rate(struct clk *clk)
 {
 	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
-	const struct mtk_pll_data *pll = &priv->tree->plls[clk->id];
+	const struct mtk_pll_data *pll;
+	int id = mtk_clk_get_id(clk);
+	const struct mtk_gate *gate;
 	u32 postdiv;
 	u32 pcw;
 
+	/* GATE handling */
+	if (priv->tree->gates && id >= priv->tree->gates_offs) {
+		gate = &priv->tree->gates[id - priv->tree->gates_offs];
+		return mtk_clk_find_parent_rate(clk, gate->parent, NULL);
+	}
+
+	pll = &priv->tree->plls[id];
+
 	postdiv = (readl(priv->base + pll->pd_reg) >> pll->pd_shift) &
 		   POSTDIV_MASK;
 	postdiv = 1 << postdiv;
@@ -217,9 +313,19 @@
 static int mtk_apmixedsys_enable(struct clk *clk)
 {
 	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
-	const struct mtk_pll_data *pll = &priv->tree->plls[clk->id];
+	const struct mtk_pll_data *pll;
+	int id = mtk_clk_get_id(clk);
+	const struct mtk_gate *gate;
 	u32 r;
 
+	/* GATE handling */
+	if (priv->tree->gates && id >= priv->tree->gates_offs) {
+		gate = &priv->tree->gates[id - priv->tree->gates_offs];
+		return mtk_gate_enable(priv->base, gate);
+	}
+
+	pll = &priv->tree->plls[id];
+
 	r = readl(priv->base + pll->pwr_reg) | CON0_PWR_ON;
 	writel(r, priv->base + pll->pwr_reg);
 	udelay(1);
@@ -246,9 +352,19 @@
 static int mtk_apmixedsys_disable(struct clk *clk)
 {
 	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
-	const struct mtk_pll_data *pll = &priv->tree->plls[clk->id];
+	const struct mtk_pll_data *pll;
+	int id = mtk_clk_get_id(clk);
+	const struct mtk_gate *gate;
 	u32 r;
 
+	/* GATE handling */
+	if (priv->tree->gates && id >= priv->tree->gates_offs) {
+		gate = &priv->tree->gates[id - priv->tree->gates_offs];
+		return mtk_gate_disable(priv->base, gate);
+	}
+
+	pll = &priv->tree->plls[id];
+
 	if (pll->flags & HAVE_RST_BAR) {
 		r = readl(priv->base + pll->reg + REG_CON0);
 		r &= ~pll->rst_bar_mask;
@@ -324,6 +440,19 @@
 	return mtk_factor_recalc_rate(fdiv, rate);
 }
 
+static ulong mtk_topckgen_find_parent_rate(struct mtk_clk_priv *priv, struct clk *clk,
+					   const int parent, u16 flags)
+{
+	switch (flags & CLK_PARENT_MASK) {
+	case CLK_PARENT_XTAL:
+		return priv->tree->xtal_rate;
+	case CLK_PARENT_APMIXED:
+		return mtk_clk_find_parent_rate(clk, parent, priv->parent);
+	default:
+		return mtk_clk_find_parent_rate(clk, parent, NULL);
+	}
+}
+
 static ulong mtk_topckgen_get_mux_rate(struct clk *clk, u32 off)
 {
 	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
@@ -334,22 +463,40 @@
 	index &= mux->mux_mask << mux->mux_shift;
 	index = index >> mux->mux_shift;
 
-	if (mux->parent[index] > 0 ||
-	    (mux->parent[index] == CLK_XTAL &&
-	     priv->tree->flags & CLK_BYPASS_XTAL)) {
-		switch (mux->flags & CLK_PARENT_MASK) {
-		case CLK_PARENT_APMIXED:
-			return mtk_clk_find_parent_rate(clk, mux->parent[index],
-							priv->parent);
-			break;
-		default:
-			return mtk_clk_find_parent_rate(clk, mux->parent[index],
-							NULL);
-			break;
-		}
+	/*
+	 * Parents can be either from APMIXED or TOPCKGEN,
+	 * inspect the mtk_parent struct to check the source
+	 */
+	if (mux->flags & CLK_PARENT_MIXED) {
+		const struct mtk_parent *parent = &mux->parent_flags[index];
+
+		return mtk_topckgen_find_parent_rate(priv, clk, parent->id,
+						     parent->flags);
 	}
 
-	return priv->tree->xtal_rate;
+	if (mux->parent[index] == CLK_XTAL &&
+	    !(priv->tree->flags & CLK_BYPASS_XTAL))
+		return priv->tree->xtal_rate;
+
+	return mtk_topckgen_find_parent_rate(priv, clk, mux->parent[index],
+					     mux->flags);
+}
+
+static ulong mtk_find_parent_rate(struct mtk_clk_priv *priv, struct clk *clk,
+				  const int parent, u16 flags)
+{
+	switch (flags & CLK_PARENT_MASK) {
+	case CLK_PARENT_XTAL:
+		return priv->tree->xtal_rate;
+	/* Assume the second level parent is always APMIXED */
+	case CLK_PARENT_APMIXED:
+		priv = dev_get_priv(priv->parent);
+		fallthrough;
+	case CLK_PARENT_TOPCKGEN:
+		return mtk_clk_find_parent_rate(clk, parent, priv->parent);
+	default:
+		return mtk_clk_find_parent_rate(clk, parent, NULL);
+	}
 }
 
 static ulong mtk_infrasys_get_mux_rate(struct clk *clk, u32 off)
@@ -362,51 +509,69 @@
 	index &= mux->mux_mask << mux->mux_shift;
 	index = index >> mux->mux_shift;
 
-	if (mux->parent[index] > 0 ||
-	    (mux->parent[index] == CLK_XTAL &&
-	     priv->tree->flags & CLK_BYPASS_XTAL)) {
-		switch (mux->flags & CLK_PARENT_MASK) {
-		case CLK_PARENT_TOPCKGEN:
-			return mtk_clk_find_parent_rate(clk, mux->parent[index],
-							priv->parent);
-			break;
-		default:
-			return mtk_clk_find_parent_rate(clk, mux->parent[index],
-							NULL);
-			break;
-		}
+	/*
+	 * Parents can be either from TOPCKGEN or INFRACFG,
+	 * inspect the mtk_parent struct to check the source
+	 */
+	if (mux->flags & CLK_PARENT_MIXED) {
+		const struct mtk_parent *parent = &mux->parent_flags[index];
+
+		return mtk_find_parent_rate(priv, clk, parent->id, parent->flags);
 	}
-	return 0;
+
+	if (mux->parent[index] == CLK_XTAL &&
+	    !(priv->tree->flags & CLK_BYPASS_XTAL))
+		return priv->tree->xtal_rate;
+
+	return mtk_find_parent_rate(priv, clk, mux->parent[index], mux->flags);
 }
 
 static ulong mtk_topckgen_get_rate(struct clk *clk)
 {
 	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+	int id = mtk_clk_get_id(clk);
 
-	if (clk->id < priv->tree->fdivs_offs)
-		return priv->tree->fclks[clk->id].rate;
-	else if (clk->id < priv->tree->muxes_offs)
-		return mtk_topckgen_get_factor_rate(clk, clk->id -
+	if (id < priv->tree->fdivs_offs)
+		return priv->tree->fclks[id].rate;
+	else if (id < priv->tree->muxes_offs)
+		return mtk_topckgen_get_factor_rate(clk, id -
 						    priv->tree->fdivs_offs);
 	else
-		return mtk_topckgen_get_mux_rate(clk, clk->id -
+		return mtk_topckgen_get_mux_rate(clk, id -
 						 priv->tree->muxes_offs);
 }
 
 static ulong mtk_infrasys_get_rate(struct clk *clk)
 {
 	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
-
+	int id = mtk_clk_get_id(clk);
 	ulong rate;
 
-	if (clk->id < priv->tree->fdivs_offs) {
-		rate = priv->tree->fclks[clk->id].rate;
-	} else if (clk->id < priv->tree->muxes_offs) {
-		rate = mtk_infrasys_get_factor_rate(clk, clk->id -
+	if (id < priv->tree->fdivs_offs) {
+		rate = priv->tree->fclks[id].rate;
+	} else if (id < priv->tree->muxes_offs) {
+		rate = mtk_infrasys_get_factor_rate(clk, id -
 						    priv->tree->fdivs_offs);
-	} else {
-		rate = mtk_infrasys_get_mux_rate(clk, clk->id -
+	/* No gates defined or ID is a MUX */
+	} else if (!priv->tree->gates || id < priv->tree->gates_offs) {
+		rate = mtk_infrasys_get_mux_rate(clk, id -
 						 priv->tree->muxes_offs);
+	/* Only valid with muxes + gates implementation */
+	} else {
+		struct udevice *parent = NULL;
+		const struct mtk_gate *gate;
+
+		gate = &priv->tree->gates[id - priv->tree->gates_offs];
+		if (gate->flags & CLK_PARENT_TOPCKGEN)
+			parent = priv->parent;
+		/*
+		 * Assume xtal_rate to be declared if some gates have
+		 * XTAL as parent
+		 */
+		else if (gate->flags & CLK_PARENT_XTAL)
+			return priv->tree->xtal_rate;
+
+		rate = mtk_clk_find_parent_rate(clk, gate->parent, parent);
 	}
 
 	return rate;
@@ -416,12 +581,13 @@
 {
 	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
 	const struct mtk_composite *mux;
+	int id = mtk_clk_get_id(clk);
 	u32 val;
 
-	if (clk->id < priv->tree->muxes_offs)
+	if (id < priv->tree->muxes_offs)
 		return 0;
 
-	mux = &priv->tree->muxes[clk->id - priv->tree->muxes_offs];
+	mux = &priv->tree->muxes[id - priv->tree->muxes_offs];
 	if (mux->gate_shift < 0)
 		return 0;
 
@@ -449,12 +615,13 @@
 {
 	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
 	const struct mtk_composite *mux;
+	int id = mtk_clk_get_id(clk);
 	u32 val;
 
-	if (clk->id < priv->tree->muxes_offs)
+	if (id < priv->tree->muxes_offs)
 		return 0;
 
-	mux = &priv->tree->muxes[clk->id - priv->tree->muxes_offs];
+	mux = &priv->tree->muxes[id - priv->tree->muxes_offs];
 	if (mux->gate_shift < 0)
 		return 0;
 
@@ -473,13 +640,20 @@
 
 static int mtk_common_clk_set_parent(struct clk *clk, struct clk *parent)
 {
+	struct mtk_clk_priv *parent_priv = dev_get_priv(parent->dev);
 	struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+	int id = mtk_clk_get_id(clk);
+	u32 parent_type;
 
-	if (clk->id < priv->tree->muxes_offs)
+	if (id < priv->tree->muxes_offs)
 		return 0;
 
-	return mtk_clk_mux_set_parent(priv->base, parent->id,
-			&priv->tree->muxes[clk->id - priv->tree->muxes_offs]);
+	if (!parent_priv)
+		return 0;
+
+	parent_type = parent_priv->tree->flags & CLK_PARENT_MASK;
+	return mtk_clk_mux_set_parent(priv->base, parent->id, parent_type,
+			&priv->tree->muxes[id - priv->tree->muxes_offs]);
 }
 
 /* CG functions */
@@ -487,63 +661,88 @@
 static int mtk_clk_gate_enable(struct clk *clk)
 {
 	struct mtk_cg_priv *priv = dev_get_priv(clk->dev);
-	const struct mtk_gate *gate = &priv->gates[clk->id];
-	u32 bit = BIT(gate->shift);
+	int id = mtk_clk_get_id(clk);
+	const struct mtk_gate *gate;
 
-	switch (gate->flags & CLK_GATE_MASK) {
-	case CLK_GATE_SETCLR:
-		writel(bit, priv->base + gate->regs->clr_ofs);
-		break;
-	case CLK_GATE_SETCLR_INV:
-		writel(bit, priv->base + gate->regs->set_ofs);
-		break;
-	case CLK_GATE_NO_SETCLR:
-		clrsetbits_le32(priv->base + gate->regs->sta_ofs, bit, 0);
-		break;
-	case CLK_GATE_NO_SETCLR_INV:
-		clrsetbits_le32(priv->base + gate->regs->sta_ofs, bit, bit);
-		break;
-
-	default:
+	if (id < priv->tree->gates_offs)
 		return -EINVAL;
-	}
 
-	return 0;
+	gate = &priv->gates[id - priv->tree->gates_offs];
+	return mtk_gate_enable(priv->base, gate);
+}
+
+static int mtk_clk_infrasys_enable(struct clk *clk)
+{
+	struct mtk_cg_priv *priv = dev_get_priv(clk->dev);
+	int id = mtk_clk_get_id(clk);
+	const struct mtk_gate *gate;
+
+	/* MUX handling */
+	if (!priv->tree->gates || id < priv->tree->gates_offs)
+		return mtk_clk_mux_enable(clk);
+
+	gate = &priv->tree->gates[id - priv->tree->gates_offs];
+	return mtk_gate_enable(priv->base, gate);
 }
 
 static int mtk_clk_gate_disable(struct clk *clk)
 {
 	struct mtk_cg_priv *priv = dev_get_priv(clk->dev);
-	const struct mtk_gate *gate = &priv->gates[clk->id];
-	u32 bit = BIT(gate->shift);
+	int id = mtk_clk_get_id(clk);
+	const struct mtk_gate *gate;
 
-	switch (gate->flags & CLK_GATE_MASK) {
-	case CLK_GATE_SETCLR:
-		writel(bit, priv->base + gate->regs->set_ofs);
-		break;
-	case CLK_GATE_SETCLR_INV:
-		writel(bit, priv->base + gate->regs->clr_ofs);
-		break;
-	case CLK_GATE_NO_SETCLR:
-		clrsetbits_le32(priv->base + gate->regs->sta_ofs, bit, bit);
-		break;
-	case CLK_GATE_NO_SETCLR_INV:
-		clrsetbits_le32(priv->base + gate->regs->sta_ofs, bit, 0);
-		break;
-
-	default:
+	if (id < priv->tree->gates_offs)
 		return -EINVAL;
-	}
 
-	return 0;
+	gate = &priv->gates[id - priv->tree->gates_offs];
+	return mtk_gate_disable(priv->base, gate);
+}
+
+static int mtk_clk_infrasys_disable(struct clk *clk)
+{
+	struct mtk_cg_priv *priv = dev_get_priv(clk->dev);
+	int id = mtk_clk_get_id(clk);
+	const struct mtk_gate *gate;
+
+	/* MUX handling */
+	if (!priv->tree->gates || id < priv->tree->gates_offs)
+		return mtk_clk_mux_disable(clk);
+
+	gate = &priv->tree->gates[id - priv->tree->gates_offs];
+	return mtk_gate_disable(priv->base, gate);
 }
 
 static ulong mtk_clk_gate_get_rate(struct clk *clk)
 {
 	struct mtk_cg_priv *priv = dev_get_priv(clk->dev);
-	const struct mtk_gate *gate = &priv->gates[clk->id];
+	struct udevice *parent = priv->parent;
+	int id = mtk_clk_get_id(clk);
+	const struct mtk_gate *gate;
 
-	return mtk_clk_find_parent_rate(clk, gate->parent, priv->parent);
+	if (id < priv->tree->gates_offs)
+		return -EINVAL;
+
+	gate = &priv->gates[id - priv->tree->gates_offs];
+	/*
+	 * With requesting a TOPCKGEN parent, make sure the dev parent
+	 * is actually topckgen. This might not be the case for an
+	 * infracfg-ao implementation where:
+	 * parent = infracfg
+	 * parent->parent = topckgen
+	 */
+	if (gate->flags & CLK_PARENT_TOPCKGEN &&
+	    parent->driver != DM_DRIVER_GET(mtk_clk_topckgen)) {
+		priv = dev_get_priv(parent);
+		parent = priv->parent;
+	/*
+	 * Assume xtal_rate to be declared if some gates have
+	 * XTAL as parent
+	 */
+	} else if (gate->flags & CLK_PARENT_XTAL) {
+		return priv->tree->xtal_rate;
+	}
+
+	return mtk_clk_find_parent_rate(clk, gate->parent, parent);
 }
 
 const struct clk_ops mtk_clk_apmixedsys_ops = {
@@ -561,8 +760,8 @@
 };
 
 const struct clk_ops mtk_clk_infrasys_ops = {
-	.enable = mtk_clk_mux_enable,
-	.disable = mtk_clk_mux_disable,
+	.enable = mtk_clk_infrasys_enable,
+	.disable = mtk_clk_infrasys_disable,
 	.get_rate = mtk_infrasys_get_rate,
 	.set_parent = mtk_common_clk_set_parent,
 };
@@ -573,8 +772,9 @@
 	.get_rate = mtk_clk_gate_get_rate,
 };
 
-int mtk_common_clk_init(struct udevice *dev,
-			const struct mtk_clk_tree *tree)
+static int mtk_common_clk_init_drv(struct udevice *dev,
+				   const struct mtk_clk_tree *tree,
+				   const struct driver *drv)
 {
 	struct mtk_clk_priv *priv = dev_get_priv(dev);
 	struct udevice *parent;
@@ -586,8 +786,7 @@
 
 	ret = uclass_get_device_by_phandle(UCLASS_CLK, dev, "clock-parent", &parent);
 	if (ret || !parent) {
-		ret = uclass_get_device_by_driver(UCLASS_CLK,
-				DM_DRIVER_GET(mtk_clk_apmixedsys), &parent);
+		ret = uclass_get_device_by_driver(UCLASS_CLK, drv, &parent);
 		if (ret || !parent)
 			return -ENOENT;
 	}
@@ -598,6 +797,20 @@
 	return 0;
 }
 
+int mtk_common_clk_init(struct udevice *dev,
+			const struct mtk_clk_tree *tree)
+{
+	return mtk_common_clk_init_drv(dev, tree,
+				       DM_DRIVER_GET(mtk_clk_apmixedsys));
+}
+
+int mtk_common_clk_infrasys_init(struct udevice *dev,
+				 const struct mtk_clk_tree *tree)
+{
+	return mtk_common_clk_init_drv(dev, tree,
+				       DM_DRIVER_GET(mtk_clk_topckgen));
+}
+
 int mtk_common_clk_gate_init(struct udevice *dev,
 			     const struct mtk_clk_tree *tree,
 			     const struct mtk_gate *gates)
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index 48ce164..c1d9901 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -13,7 +13,11 @@
 
 /* flags in struct mtk_clk_tree */
 
-/* clk id == 0 doesn't mean it's xtal clk */
+/* clk id == 0 doesn't mean it's xtal clk
+ * This doesn't apply when CLK_PARENT_MIXED is defined.
+ * With CLK_PARENT_MIXED declare CLK_PARENT_XTAL for the
+ * relevant parent.
+ */
 #define CLK_BYPASS_XTAL			BIT(0)
 
 #define HAVE_RST_BAR			BIT(0)
@@ -30,7 +34,17 @@
 #define CLK_PARENT_TOPCKGEN		BIT(5)
 #define CLK_PARENT_INFRASYS		BIT(6)
 #define CLK_PARENT_XTAL			BIT(7)
-#define CLK_PARENT_MASK			GENMASK(7, 4)
+/*
+ * For CLK_PARENT_MIXED to correctly work, is required to
+ * define in clk_tree flags the clk type using the alias.
+ */
+#define CLK_PARENT_MIXED		BIT(8)
+#define CLK_PARENT_MASK			GENMASK(8, 4)
+
+/* alias to reference clk type */
+#define CLK_APMIXED			CLK_PARENT_APMIXED
+#define CLK_TOPCKGEN			CLK_PARENT_TOPCKGEN
+#define CLK_INFRASYS			CLK_PARENT_INFRASYS
 
 #define ETHSYS_HIFSYS_RST_CTRL_OFS	0x34
 
@@ -98,10 +112,30 @@
 	}
 
 /**
+ * struct mtk_parent -  clock parent with flags. Needed for MUX that
+ *			parent with mixed infracfg and topckgen.
+ *
+ * @id:			index of parent clocks
+ * @flags:		hardware-specific flags (parent location,
+ *			infracfg, topckgen, APMIXED, xtal ...)
+ */
+struct mtk_parent {
+	const int id;
+	u16 flags;
+};
+
+#define PARENT(_id, _flags) {				\
+		.id = _id,				\
+		.flags = _flags,			\
+	}
+
+/**
  * struct mtk_composite - aggregate clock of mux, divider and gate clocks
  *
  * @id:			index of clocks
  * @parent:		index of parnet clocks
+ * @parent:		index of parnet clocks
+ * @parent_flags:	table of parent clocks with flags
  * @mux_reg:		hardware-specific mux register
  * @gate_reg:		hardware-specific gate register
  * @mux_mask:		mask to the mux bit field
@@ -112,7 +146,10 @@
  */
 struct mtk_composite {
 	const int id;
-	const int *parent;
+	union {
+		const int *parent;
+		const struct mtk_parent *parent_flags;
+	};
 	u32 mux_reg;
 	u32 mux_set_reg;
 	u32 mux_clr_reg;
@@ -142,7 +179,20 @@
 #define MUX_GATE(_id, _parents, _reg, _shift, _width, _gate)		\
 	MUX_GATE_FLAGS(_id, _parents, _reg, _shift, _width, _gate, 0)
 
-#define MUX(_id, _parents, _reg, _shift, _width) {			\
+#define MUX_MIXED_FLAGS(_id, _parents, _reg, _shift, _width, _flags) {	\
+		.id = _id,						\
+		.mux_reg = _reg,					\
+		.mux_shift = _shift,					\
+		.mux_mask = BIT(_width) - 1,				\
+		.gate_shift = -1,					\
+		.parent_flags = _parents,				\
+		.num_parents = ARRAY_SIZE(_parents),			\
+		.flags = CLK_PARENT_MIXED | (_flags),			\
+	}
+#define MUX_MIXED(_id, _parents, _reg, _shift, _width)			\
+	MUX_MIXED_FLAGS(_id, _parents, _reg, _shift, _width, 0)
+
+#define MUX_FLAGS(_id, _parents, _reg, _shift, _width, _flags) {	\
 		.id = _id,						\
 		.mux_reg = _reg,					\
 		.mux_shift = _shift,					\
@@ -150,8 +200,10 @@
 		.gate_shift = -1,					\
 		.parent = _parents,					\
 		.num_parents = ARRAY_SIZE(_parents),			\
-		.flags = 0,						\
+		.flags = _flags,					\
 	}
+#define MUX(_id, _parents, _reg, _shift, _width)			\
+	MUX_FLAGS(_id, _parents, _reg, _shift, _width, 0)
 
 #define MUX_CLR_SET_UPD_FLAGS(_id, _parents, _mux_ofs, _mux_set_ofs,\
 			_mux_clr_ofs, _shift, _width, _gate,		\
@@ -198,12 +250,22 @@
 struct mtk_clk_tree {
 	unsigned long xtal_rate;
 	unsigned long xtal2_rate;
+	/*
+	 * Clock ID offset are remapped with an auxiliary table.
+	 * Enable this by defining .id_offs_map.
+	 * This is needed for upstream linux kernel <soc>-clk.h that
+	 * have mixed clk ID and doesn't have clear distinction between
+	 * ID for factor, mux and gates.
+	 */
+	const int *id_offs_map; /* optional, table clk.h to driver ID */
 	const int fdivs_offs;
 	const int muxes_offs;
+	const int gates_offs;
 	const struct mtk_pll_data *plls;
 	const struct mtk_fixed_clk *fclks;
 	const struct mtk_fixed_factor *fdivs;
 	const struct mtk_composite *muxes;
+	const struct mtk_gate *gates;
 	u32 flags;
 };
 
@@ -227,6 +289,8 @@
 
 int mtk_common_clk_init(struct udevice *dev,
 			const struct mtk_clk_tree *tree);
+int mtk_common_clk_infrasys_init(struct udevice *dev,
+				 const struct mtk_clk_tree *tree);
 int mtk_common_clk_gate_init(struct udevice *dev,
 			     const struct mtk_clk_tree *tree,
 			     const struct mtk_gate *gates);
diff --git a/drivers/core/util.c b/drivers/core/util.c
index 108a3bc..fa89348 100644
--- a/drivers/core/util.c
+++ b/drivers/core/util.c
@@ -3,23 +3,13 @@
  * Copyright (c) 2013 Google, Inc
  */
 
+#include <vsprintf.h>
 #include <dm/device.h>
 #include <dm/ofnode.h>
 #include <dm/read.h>
 #include <dm/util.h>
 #include <linux/libfdt.h>
-#include <vsprintf.h>
-
-int list_count_items(struct list_head *head)
-{
-	struct list_head *node;
-	int count = 0;
-
-	list_for_each(node, head)
-		count++;
-
-	return count;
-}
+#include <linux/list.h>
 
 #if CONFIG_IS_ENABLED(OF_REAL)
 int pci_get_devfn(struct udevice *dev)
diff --git a/drivers/cpu/cpu-uclass.c b/drivers/cpu/cpu-uclass.c
index 16f8f2e..2c8e46c 100644
--- a/drivers/cpu/cpu-uclass.c
+++ b/drivers/cpu/cpu-uclass.c
@@ -104,6 +104,16 @@
 	return ops->get_vendor(dev, buf, size);
 }
 
+int cpu_release_core(const struct udevice *dev, phys_addr_t addr)
+{
+	struct cpu_ops *ops = cpu_get_ops(dev);
+
+	if (!ops->release_core)
+		return -ENOSYS;
+
+	return ops->release_core(dev, addr);
+}
+
 U_BOOT_DRIVER(cpu_bus) = {
 	.name	= "cpu_bus",
 	.id	= UCLASS_SIMPLE_BUS,
diff --git a/drivers/cpu/cpu_sandbox.c b/drivers/cpu/cpu_sandbox.c
index e65e1bd..b152795 100644
--- a/drivers/cpu/cpu_sandbox.c
+++ b/drivers/cpu/cpu_sandbox.c
@@ -44,6 +44,11 @@
 	cpu_current = name;
 }
 
+static int cpu_sandbox_release_core(const struct udevice *dev, phys_addr_t addr)
+{
+	return 0;
+}
+
 static int cpu_sandbox_is_current(struct udevice *dev)
 {
 	if (!strcmp(dev->name, cpu_current))
@@ -58,6 +63,7 @@
 	.get_count = cpu_sandbox_get_count,
 	.get_vendor = cpu_sandbox_get_vendor,
 	.is_current = cpu_sandbox_is_current,
+	.release_core = cpu_sandbox_release_core,
 };
 
 static int cpu_sandbox_bind(struct udevice *dev)
diff --git a/drivers/cpu/imx8_cpu.c b/drivers/cpu/imx8_cpu.c
index 4781a56..60deca9 100644
--- a/drivers/cpu/imx8_cpu.c
+++ b/drivers/cpu/imx8_cpu.c
@@ -1,12 +1,13 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * Copyright 2019 NXP
+ * Copyright 2019, 2024 NXP
  */
 
 #include <cpu.h>
 #include <dm.h>
 #include <thermal.h>
 #include <asm/global_data.h>
+#include <asm/ptrace.h>
 #include <asm/system.h>
 #include <firmware/imx/sci/sci.h>
 #include <asm/arch/sys_proto.h>
@@ -15,6 +16,7 @@
 #include <imx_thermal.h>
 #include <linux/bitops.h>
 #include <linux/clk-provider.h>
+#include <linux/psci.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -31,6 +33,12 @@
 static const char *get_imx_type_str(u32 imxtype)
 {
 	switch (imxtype) {
+	case MXC_CPU_IMX8MM:
+		return "8MM";
+	case MXC_CPU_IMX8MN:
+		return "8MN";
+	case MXC_CPU_IMX8MP:
+		return "8MP";
 	case MXC_CPU_IMX8QXP:
 	case MXC_CPU_IMX8QXP_A0:
 		return "8QXP";
@@ -184,8 +192,6 @@
 			ret = snprintf(buf, size, " - invalid sensor data");
 	}
 
-	snprintf(buf + ret, size - ret, "\n");
-
 	return 0;
 }
 
@@ -193,7 +199,7 @@
 {
 	struct cpu_imx_plat *plat = dev_get_plat(dev);
 
-	info->cpu_freq = plat->freq_mhz * 1000;
+	info->cpu_freq = plat->freq_mhz * 1000000;
 	info->features = BIT(CPU_FEAT_L1_CACHE) | BIT(CPU_FEAT_MMU);
 	return 0;
 }
@@ -236,12 +242,34 @@
 	return 0;
 }
 
+static int cpu_imx_release_core(const struct udevice *dev, phys_addr_t addr)
+{
+	struct cpu_imx_plat *plat = dev_get_plat(dev);
+	struct pt_regs regs;
+
+	regs.regs[0] = PSCI_0_2_FN64_CPU_ON;
+	regs.regs[1] = plat->mpidr;
+	regs.regs[2] = addr;
+	regs.regs[3] = 0;
+
+	smc_call(&regs);
+	if (regs.regs[0]) {
+		printf("Failed to release CPU core (mpidr: 0x%x)\n", plat->mpidr);
+		return -1;
+	}
+
+	printf("Released CPU core (mpidr: 0x%x) to address 0x%llx\n", plat->mpidr, addr);
+
+	return 0;
+}
+
 static const struct cpu_ops cpu_imx_ops = {
 	.get_desc	= cpu_imx_get_desc,
 	.get_info	= cpu_imx_get_info,
 	.get_count	= cpu_imx_get_count,
 	.get_vendor	= cpu_imx_get_vendor,
 	.is_current	= cpu_imx_is_current,
+	.release_core	= cpu_imx_release_core,
 };
 
 static const struct udevice_id cpu_imx_ids[] = {
@@ -287,7 +315,7 @@
 	cpurev = get_cpu_rev();
 	plat->cpurev = cpurev;
 	plat->rev = get_imx_rev_str(cpurev & 0xFFF);
-	plat->type = get_imx_type_str((cpurev & 0xFF000) >> 12);
+	plat->type = get_imx_type_str((cpurev & 0x1FF000) >> 12);
 	plat->freq_mhz = imx_get_cpu_rate(dev) / 1000000;
 	plat->mpidr = dev_read_addr(dev);
 	if (plat->mpidr == FDT_ADDR_T_NONE) {
diff --git a/drivers/led/Kconfig b/drivers/led/Kconfig
index 9837960..bee74b2 100644
--- a/drivers/led/Kconfig
+++ b/drivers/led/Kconfig
@@ -65,7 +65,7 @@
 	  Linux compatible ofdata.
 
 config LED_BLINK
-	bool "Support LED blinking"
+	bool "Support hardware LED blinking"
 	depends on LED
 	help
 	  Some drivers can support automatic blinking of LEDs with a given
@@ -73,6 +73,20 @@
 	  This option enables support for this which adds slightly to the
 	  code size.
 
+config LED_SW_BLINK
+	bool "Support software LED blinking"
+	depends on LED
+	select CYCLIC
+	help
+	  Turns on led blinking implemented in the software, useful when
+	  the hardware doesn't support led blinking. Half of the period
+	  led will be ON and the rest time it will be OFF. Standard
+	  led commands can be used to configure blinking. Does nothing
+	  if driver supports hardware blinking.
+	  WARNING: Blinking may be inaccurate during execution of time
+	  consuming commands (ex. flash reading). Also it completely
+	  stops during OS booting.
+
 config SPL_LED
 	bool "Enable LED support in SPL"
 	depends on SPL_DM
diff --git a/drivers/led/Makefile b/drivers/led/Makefile
index 2bcb858..e27aa48 100644
--- a/drivers/led/Makefile
+++ b/drivers/led/Makefile
@@ -4,6 +4,7 @@
 # Written by Simon Glass <sjg@chromium.org>
 
 obj-y += led-uclass.o
+obj-$(CONFIG_LED_SW_BLINK) += led_sw_blink.o
 obj-$(CONFIG_LED_BCM6328) += led_bcm6328.o
 obj-$(CONFIG_LED_BCM6358) += led_bcm6358.o
 obj-$(CONFIG_LED_BCM6753) += led_bcm6753.o
diff --git a/drivers/led/led-uclass.c b/drivers/led/led-uclass.c
index f37bf6a..199d68b 100644
--- a/drivers/led/led-uclass.c
+++ b/drivers/led/led-uclass.c
@@ -58,6 +58,10 @@
 	if (!ops->set_state)
 		return -ENOSYS;
 
+	if (IS_ENABLED(CONFIG_LED_SW_BLINK) &&
+	    led_sw_on_state_change(dev, state))
+		return 0;
+
 	return ops->set_state(dev, state);
 }
 
@@ -68,21 +72,28 @@
 	if (!ops->get_state)
 		return -ENOSYS;
 
+	if (IS_ENABLED(CONFIG_LED_SW_BLINK) &&
+	    led_sw_is_blinking(dev))
+		return LEDST_BLINK;
+
 	return ops->get_state(dev);
 }
 
-#ifdef CONFIG_LED_BLINK
 int led_set_period(struct udevice *dev, int period_ms)
 {
+#ifdef CONFIG_LED_BLINK
 	struct led_ops *ops = led_get_ops(dev);
 
-	if (!ops->set_period)
-		return -ENOSYS;
-
-	return ops->set_period(dev, period_ms);
-}
+	if (ops->set_period)
+		return ops->set_period(dev, period_ms);
 #endif
 
+	if (IS_ENABLED(CONFIG_LED_SW_BLINK))
+		return led_sw_set_period(dev, period_ms);
+
+	return -ENOSYS;
+}
+
 static int led_post_bind(struct udevice *dev)
 {
 	struct led_uc_plat *uc_plat = dev_get_uclass_plat(dev);
@@ -107,6 +118,14 @@
 	else
 		return 0;
 
+	if (IS_ENABLED(CONFIG_LED_BLINK)) {
+		const char *trigger;
+
+		trigger = dev_read_string(dev, "linux,default-trigger");
+		if (trigger && !strncmp(trigger, "pattern", 7))
+			uc_plat->default_state = LEDST_BLINK;
+	}
+
 	/*
 	 * In case the LED has default-state DT property, trigger
 	 * probe() to configure its default state during startup.
@@ -119,12 +138,24 @@
 static int led_post_probe(struct udevice *dev)
 {
 	struct led_uc_plat *uc_plat = dev_get_uclass_plat(dev);
+	int default_period_ms = 1000;
+	int ret = 0;
 
-	if (uc_plat->default_state == LEDST_ON ||
-	    uc_plat->default_state == LEDST_OFF)
-		led_set_state(dev, uc_plat->default_state);
+	switch (uc_plat->default_state) {
+	case LEDST_ON:
+	case LEDST_OFF:
+		ret = led_set_state(dev, uc_plat->default_state);
+		break;
+	case LEDST_BLINK:
+		ret = led_set_period(dev, default_period_ms);
+		if (!ret)
+			ret = led_set_state(dev, uc_plat->default_state);
+		break;
+	default:
+		break;
+	}
 
-	return 0;
+	return ret;
 }
 
 UCLASS_DRIVER(led) = {
diff --git a/drivers/led/led_sw_blink.c b/drivers/led/led_sw_blink.c
new file mode 100644
index 0000000..9e36edb
--- /dev/null
+++ b/drivers/led/led_sw_blink.c
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Software blinking helpers
+ * Copyright (C) 2024 IOPSYS Software Solutions AB
+ * Author: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+ */
+
+#include <dm.h>
+#include <led.h>
+#include <time.h>
+#include <stdlib.h>
+
+#define CYCLIC_NAME_PREFIX	"led_sw_blink_"
+
+static void led_sw_blink(struct cyclic_info *c)
+{
+	struct led_sw_blink *sw_blink;
+	struct udevice *dev;
+	struct led_ops *ops;
+
+	sw_blink = container_of(c, struct led_sw_blink, cyclic);
+	dev = sw_blink->dev;
+	ops = led_get_ops(dev);
+
+	switch (sw_blink->state) {
+	case LED_SW_BLINK_ST_OFF:
+		sw_blink->state = LED_SW_BLINK_ST_ON;
+		ops->set_state(dev, LEDST_ON);
+		break;
+	case LED_SW_BLINK_ST_ON:
+		sw_blink->state = LED_SW_BLINK_ST_OFF;
+		ops->set_state(dev, LEDST_OFF);
+		break;
+	case LED_SW_BLINK_ST_NOT_READY:
+		/*
+		 * led_set_period has been called, but
+		 * led_set_state(LDST_BLINK) has not yet,
+		 * so doing nothing
+		 */
+		break;
+	default:
+		break;
+	}
+}
+
+int led_sw_set_period(struct udevice *dev, int period_ms)
+{
+	struct led_uc_plat *uc_plat = dev_get_uclass_plat(dev);
+	struct led_sw_blink *sw_blink = uc_plat->sw_blink;
+	struct led_ops *ops = led_get_ops(dev);
+	int half_period_us;
+
+	half_period_us = period_ms * 1000 / 2;
+
+	if (!sw_blink) {
+		int len = sizeof(struct led_sw_blink) +
+			  strlen(CYCLIC_NAME_PREFIX) +
+			  strlen(uc_plat->label) + 1;
+
+		sw_blink = calloc(1, len);
+		if (!sw_blink)
+			return -ENOMEM;
+
+		sw_blink->dev = dev;
+		sw_blink->state = LED_SW_BLINK_ST_DISABLED;
+		strcpy((char *)sw_blink->cyclic_name, CYCLIC_NAME_PREFIX);
+		strcat((char *)sw_blink->cyclic_name, uc_plat->label);
+
+		uc_plat->sw_blink = sw_blink;
+	}
+
+	if (sw_blink->state == LED_SW_BLINK_ST_DISABLED) {
+		cyclic_register(&sw_blink->cyclic, led_sw_blink,
+				half_period_us, sw_blink->cyclic_name);
+	} else {
+		sw_blink->cyclic.delay_us = half_period_us;
+		sw_blink->cyclic.start_time_us = timer_get_us();
+	}
+
+	sw_blink->state = LED_SW_BLINK_ST_NOT_READY;
+	ops->set_state(dev, LEDST_OFF);
+
+	return 0;
+}
+
+bool led_sw_is_blinking(struct udevice *dev)
+{
+	struct led_uc_plat *uc_plat = dev_get_uclass_plat(dev);
+	struct led_sw_blink *sw_blink = uc_plat->sw_blink;
+
+	if (!sw_blink)
+		return false;
+
+	return sw_blink->state > LED_SW_BLINK_ST_NOT_READY;
+}
+
+bool led_sw_on_state_change(struct udevice *dev, enum led_state_t state)
+{
+	struct led_uc_plat *uc_plat = dev_get_uclass_plat(dev);
+	struct led_sw_blink *sw_blink = uc_plat->sw_blink;
+
+	if (!sw_blink || sw_blink->state == LED_SW_BLINK_ST_DISABLED)
+		return false;
+
+	if (state == LEDST_BLINK) {
+		/* start blinking on next led_sw_blink() call */
+		sw_blink->state = LED_SW_BLINK_ST_OFF;
+		return true;
+	}
+
+	/* stop blinking */
+	uc_plat->sw_blink = NULL;
+	cyclic_unregister(&sw_blink->cyclic);
+	free(sw_blink);
+
+	return false;
+}
diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index b7bf7cc..b1af3f7 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -1698,7 +1698,7 @@
 	desc->cmd_irq = (dma_cmd << 24) |
 		(end ? (0x03 << 8) : 0) | /* IRQ | STOP */
 		(!!begin) | ((!!end) << 1); /* head, tail */
-#ifdef CONFIG_CPU_BIG_ENDIAN
+#ifdef CONFIG_SYS_BIG_ENDIAN
 	desc->cmd_irq |= 0x01 << 12;
 #endif
 	desc->dram_addr = lower_32_bits(buf);
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
index 67ac86f..43f0ec7 100644
--- a/drivers/net/dwc_eth_qos.c
+++ b/drivers/net/dwc_eth_qos.c
@@ -50,6 +50,7 @@
 #include <asm/arch/clock.h>
 #include <asm/mach-imx/sys_proto.h>
 #endif
+#include <linux/bitfield.h>
 #include <linux/delay.h>
 #include <linux/printk.h>
 
@@ -146,6 +147,25 @@
 				 1000000, true);
 }
 
+/* Bitmask common for mdio_read and mdio_write */
+#define EQOS_MDIO_BITFIELD(pa, rda, cr) \
+	FIELD_PREP(EQOS_MAC_MDIO_ADDRESS_PA_MASK, pa)   | \
+	FIELD_PREP(EQOS_MAC_MDIO_ADDRESS_RDA_MASK, rda) | \
+	FIELD_PREP(EQOS_MAC_MDIO_ADDRESS_CR_MASK, cr)   | \
+	EQOS_MAC_MDIO_ADDRESS_GB
+
+static u32 eqos_mdio_bitfield(struct eqos_priv *eqos, int addr, int devad, int reg)
+{
+	int cr = eqos->config->config_mac_mdio;
+	bool c22 = devad == MDIO_DEVAD_NONE ? true : false;
+
+	if (c22)
+		return EQOS_MDIO_BITFIELD(addr, reg, cr);
+	else
+		return EQOS_MDIO_BITFIELD(addr, devad, cr) |
+		       EQOS_MAC_MDIO_ADDRESS_C45E;
+}
+
 static int eqos_mdio_read(struct mii_dev *bus, int mdio_addr, int mdio_devad,
 			  int mdio_reg)
 {
@@ -163,15 +183,17 @@
 	}
 
 	val = readl(&eqos->mac_regs->mdio_address);
-	val &= EQOS_MAC_MDIO_ADDRESS_SKAP |
-		EQOS_MAC_MDIO_ADDRESS_C45E;
-	val |= (mdio_addr << EQOS_MAC_MDIO_ADDRESS_PA_SHIFT) |
-		(mdio_reg << EQOS_MAC_MDIO_ADDRESS_RDA_SHIFT) |
-		(eqos->config->config_mac_mdio <<
-		 EQOS_MAC_MDIO_ADDRESS_CR_SHIFT) |
-		(EQOS_MAC_MDIO_ADDRESS_GOC_READ <<
-		 EQOS_MAC_MDIO_ADDRESS_GOC_SHIFT) |
-		EQOS_MAC_MDIO_ADDRESS_GB;
+	val &= EQOS_MAC_MDIO_ADDRESS_SKAP;
+
+	val |= eqos_mdio_bitfield(eqos, mdio_addr, mdio_devad, mdio_reg) |
+	       FIELD_PREP(EQOS_MAC_MDIO_ADDRESS_GOC_MASK,
+			  EQOS_MAC_MDIO_ADDRESS_GOC_READ);
+
+	if (val & EQOS_MAC_MDIO_ADDRESS_C45E) {
+		writel(FIELD_PREP(EQOS_MAC_MDIO_DATA_RA_MASK, mdio_reg),
+		       &eqos->mac_regs->mdio_data);
+	}
+
 	writel(val, &eqos->mac_regs->mdio_address);
 
 	udelay(eqos->config->mdio_wait);
@@ -194,7 +216,8 @@
 			   int mdio_reg, u16 mdio_val)
 {
 	struct eqos_priv *eqos = bus->priv;
-	u32 val;
+	u32 v_addr;
+	u32 v_data;
 	int ret;
 
 	debug("%s(dev=%p, addr=%x, reg=%d, val=%x):\n", __func__, eqos->dev,
@@ -206,20 +229,19 @@
 		return ret;
 	}
 
-	writel(mdio_val, &eqos->mac_regs->mdio_data);
+	v_addr = readl(&eqos->mac_regs->mdio_address);
+	v_addr &= EQOS_MAC_MDIO_ADDRESS_SKAP;
 
-	val = readl(&eqos->mac_regs->mdio_address);
-	val &= EQOS_MAC_MDIO_ADDRESS_SKAP |
-		EQOS_MAC_MDIO_ADDRESS_C45E;
-	val |= (mdio_addr << EQOS_MAC_MDIO_ADDRESS_PA_SHIFT) |
-		(mdio_reg << EQOS_MAC_MDIO_ADDRESS_RDA_SHIFT) |
-		(eqos->config->config_mac_mdio <<
-		 EQOS_MAC_MDIO_ADDRESS_CR_SHIFT) |
-		(EQOS_MAC_MDIO_ADDRESS_GOC_WRITE <<
-		 EQOS_MAC_MDIO_ADDRESS_GOC_SHIFT) |
-		EQOS_MAC_MDIO_ADDRESS_GB;
-	writel(val, &eqos->mac_regs->mdio_address);
+	v_addr |= eqos_mdio_bitfield(eqos, mdio_addr, mdio_devad, mdio_reg) |
+	       FIELD_PREP(EQOS_MAC_MDIO_ADDRESS_GOC_MASK,
+			  EQOS_MAC_MDIO_ADDRESS_GOC_WRITE);
 
+	v_data = mdio_val;
+	if (v_addr & EQOS_MAC_MDIO_ADDRESS_C45E)
+		v_data |= FIELD_PREP(EQOS_MAC_MDIO_DATA_RA_MASK, mdio_reg);
+
+	writel(v_data, &eqos->mac_regs->mdio_data);
+	writel(v_addr, &eqos->mac_regs->mdio_address);
 	udelay(eqos->config->mdio_wait);
 
 	ret = eqos_mdio_wait_idle(eqos);
diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h
index 8b3d0d4..a06390a 100644
--- a/drivers/net/dwc_eth_qos.h
+++ b/drivers/net/dwc_eth_qos.h
@@ -79,19 +79,20 @@
 #define EQOS_MAC_HW_FEATURE3_ASP_SHIFT			28
 #define EQOS_MAC_HW_FEATURE3_ASP_MASK			0x3
 
-#define EQOS_MAC_MDIO_ADDRESS_PA_SHIFT			21
-#define EQOS_MAC_MDIO_ADDRESS_RDA_SHIFT			16
-#define EQOS_MAC_MDIO_ADDRESS_CR_SHIFT			8
+#define EQOS_MAC_MDIO_ADDRESS_PA_MASK			GENMASK(25, 21)
+#define EQOS_MAC_MDIO_ADDRESS_RDA_MASK			GENMASK(20, 16)
+#define EQOS_MAC_MDIO_ADDRESS_CR_MASK			GENMASK(11, 8)
 #define EQOS_MAC_MDIO_ADDRESS_CR_100_150		1
 #define EQOS_MAC_MDIO_ADDRESS_CR_20_35			2
 #define EQOS_MAC_MDIO_ADDRESS_CR_250_300		5
 #define EQOS_MAC_MDIO_ADDRESS_SKAP			BIT(4)
-#define EQOS_MAC_MDIO_ADDRESS_GOC_SHIFT			2
+#define EQOS_MAC_MDIO_ADDRESS_GOC_MASK			GENMASK(3, 2)
 #define EQOS_MAC_MDIO_ADDRESS_GOC_READ			3
 #define EQOS_MAC_MDIO_ADDRESS_GOC_WRITE			1
 #define EQOS_MAC_MDIO_ADDRESS_C45E			BIT(1)
 #define EQOS_MAC_MDIO_ADDRESS_GB			BIT(0)
 
+#define EQOS_MAC_MDIO_DATA_RA_MASK			GENMASK(31, 16)
 #define EQOS_MAC_MDIO_DATA_GD_MASK			0xffff
 
 #define EQOS_MTL_REGS_BASE 0xd00
diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c
index ef9a182..45270e2 100644
--- a/drivers/ram/rockchip/sdram_rk3399.c
+++ b/drivers/ram/rockchip/sdram_rk3399.c
@@ -13,6 +13,7 @@
 #include <log.h>
 #include <ram.h>
 #include <regmap.h>
+#include <spl.h>
 #include <syscon.h>
 #include <asm/arch-rockchip/clock.h>
 #include <asm/arch-rockchip/cru.h>
@@ -63,8 +64,6 @@
 };
 
 struct dram_info {
-#if defined(CONFIG_TPL_BUILD) || \
-	(!defined(CONFIG_TPL) && defined(CONFIG_SPL_BUILD))
 	u32 pwrup_srefresh_exit[2];
 	struct chan_info chan[2];
 	struct clk ddr_clk;
@@ -75,7 +74,6 @@
 	struct rk3399_pmusgrf_regs *pmusgrf;
 	struct rk3399_ddr_cic_regs *cic;
 	const struct sdram_rk3399_ops *ops;
-#endif
 	struct ram_info info;
 	struct rk3399_pmugrf_regs *pmugrf;
 };
@@ -92,9 +90,6 @@
 					struct rk3399_sdram_params *params);
 };
 
-#if defined(CONFIG_TPL_BUILD) || \
-	(!defined(CONFIG_TPL) && defined(CONFIG_SPL_BUILD))
-
 struct rockchip_dmc_plat {
 #if CONFIG_IS_ENABLED(OF_PLATDATA)
 	struct dtd_rockchip_rk3399_dmc dtplat;
@@ -191,6 +186,19 @@
 	},
 };
 
+/**
+ * phase_sdram_init() - Check if this is the phase where SDRAM init happens
+ *
+ * Returns: true to do SDRAM init in this phase, false to not
+ */
+static bool phase_sdram_init(void)
+{
+	return spl_phase() == PHASE_TPL ||
+		(!IS_ENABLED(CONFIG_TPL) &&
+		 !IS_ENABLED(CONFIG_ROCKCHIP_EXTERNAL_TPL) &&
+		 !spl_in_proper());
+}
+
 static struct io_setting *
 lpddr4_get_io_settings(const struct rk3399_sdram_params *params, u32 mr5)
 {
@@ -3021,12 +3029,13 @@
 
 static int rk3399_dmc_of_to_plat(struct udevice *dev)
 {
-	struct rockchip_dmc_plat *plat = dev_get_plat(dev);
+	struct rockchip_dmc_plat *plat;
 	int ret;
 
-	if (!CONFIG_IS_ENABLED(OF_REAL))
+	if (!CONFIG_IS_ENABLED(OF_REAL) || !phase_sdram_init())
 		return 0;
 
+	plat = dev_get_plat(dev);
 	ret = dev_read_u32_array(dev, "rockchip,sdram-params",
 				 (u32 *)&plat->sdram_params,
 				 sizeof(plat->sdram_params) / sizeof(u32));
@@ -3093,7 +3102,6 @@
 	priv->cic = syscon_get_first_range(ROCKCHIP_SYSCON_CIC);
 	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
 	priv->pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU);
-	priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF);
 	priv->pmusgrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUSGRF);
 	priv->pmucru = rockchip_get_pmucru();
 	priv->cru = rockchip_get_cru();
@@ -3138,23 +3146,26 @@
 
 	return 0;
 }
-#endif
 
 static int rk3399_dmc_probe(struct udevice *dev)
 {
-#if defined(CONFIG_TPL_BUILD) || \
-	(!defined(CONFIG_TPL) && defined(CONFIG_SPL_BUILD))
-	if (rk3399_dmc_init(dev))
-		return 0;
-#else
 	struct dram_info *priv = dev_get_priv(dev);
 
 	priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF);
 	debug("%s: pmugrf = %p\n", __func__, priv->pmugrf);
-	priv->info.base = CFG_SYS_SDRAM_BASE;
-	priv->info.size =
-		rockchip_sdram_size((phys_addr_t)&priv->pmugrf->os_reg2);
-#endif
+	if (phase_sdram_init() && rk3399_dmc_init(dev))
+		return 0;
+
+	/*
+	 * There is no point in checking the SDRAM size in TPL as it is not
+	 * used, so avoid the code size increment.
+	 */
+	if (!IS_ENABLED(CONFIG_TPL_BUILD)) {
+		priv->info.base = CFG_SYS_SDRAM_BASE;
+		priv->info.size = rockchip_sdram_size(
+			(phys_addr_t)&priv->pmugrf->os_reg2);
+	}
+
 	return 0;
 }
 
@@ -3181,10 +3192,7 @@
 	.id = UCLASS_RAM,
 	.of_match = rk3399_dmc_ids,
 	.ops = &rk3399_dmc_ops,
-#if defined(CONFIG_TPL_BUILD) || \
-	(!defined(CONFIG_TPL) && defined(CONFIG_SPL_BUILD))
 	.of_to_plat = rk3399_dmc_of_to_plat,
-#endif
 	.probe = rk3399_dmc_probe,
 	.priv_auto	= sizeof(struct dram_info),
 #if defined(CONFIG_TPL_BUILD) || \
diff --git a/drivers/serial/sandbox.c b/drivers/serial/sandbox.c
index ec0068e..77a1558 100644
--- a/drivers/serial/sandbox.c
+++ b/drivers/serial/sandbox.c
@@ -138,8 +138,6 @@
 		return 0;
 
 	os_usleep(100);
-	if (IS_ENABLED(CONFIG_VIDEO) && !IS_ENABLED(CONFIG_SPL_BUILD))
-		video_sync_all();
 	avail = membuff_putraw(&priv->buf, 100, false, &data);
 	if (!avail)
 		return 1;	/* buffer full */
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 7808ae7..6e79694 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -7,6 +7,7 @@
 config VIDEO
 	bool "Enable driver model support for LCD/video"
 	depends on DM
+	imply CYCLIC
 	help
 	  This enables driver model for LCD and video devices. These support
 	  a bitmap display of various sizes and depths which can be drawn on
@@ -14,6 +15,11 @@
 	  option compiles in the video uclass and routes all LCD/video access
 	  through this.
 
+	  If CYCLIC is enabled (which it is by default), the cyclic subsystem
+	  is used to flush pending output to the display periodically, rather
+	  than this happening with every chunk of output. This allows for more
+	  efficient operation and faster display output.
+
 if VIDEO
 
 config VIDEO_FONT_4X6
@@ -232,6 +238,35 @@
 	  loads takes over the screen.  This, for example, can be used to
 	  keep splash image on screen until grub graphical boot menu starts.
 
+config VIDEO_SYNC_MS
+	int "Video-sync period in milliseconds for foreground processing"
+	default 300 if SANDBOX
+	default 100
+	help
+	  This sets the requested, maximum time before a video sync will take
+	  place, in milliseconds. Note that the time between video syncs
+	  may be longer than this, since syncs only happen when the video system
+	  is used, e.g. by outputting a character to the console.
+
+	  It may also be shorter, since the video uclass will automatically
+	  force a sync in certain situations.
+
+	  Many video-output systems require a sync operation before any output
+	  is visible. This may flush the CPU cache or perhaps copy the
+	  display contents to a hardware framebuffer. Without this, change to
+	  the video may never be displayed.
+
+config VIDEO_SYNC_CYCLIC_MS
+	int "Video-sync period in milliseconds for cyclic processing"
+	depends on CYCLIC
+	default 100 if SANDBOX
+	default 10
+	help
+	  This sets the frequency of cyclic video syncs. The cyclic system is
+	  used to ensure that when U-Boot is idle, it syncs the video. This
+	  improves the responsiveness of the command line to new characters
+	  being entered.
+
 config PANEL
 	bool "Enable panel uclass support"
 	default y
diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c
index ff1382f..a5aa8dd 100644
--- a/drivers/video/video-uclass.c
+++ b/drivers/video/video-uclass.c
@@ -8,6 +8,7 @@
 #include <bloblist.h>
 #include <console.h>
 #include <cpu_func.h>
+#include <cyclic.h>
 #include <dm.h>
 #include <log.h>
 #include <malloc.h>
@@ -52,6 +53,8 @@
  */
 DECLARE_GLOBAL_DATA_PTR;
 
+struct cyclic_info;
+
 /**
  * struct video_uc_priv - Information for the video uclass
  *
@@ -60,9 +63,12 @@
  *	available address to use for a device's framebuffer. It starts at
  *	gd->video_top and works downwards, running out of space when it hits
  *	gd->video_bottom.
+ * @cyc: handle for cyclic-execution function, or NULL if none
  */
 struct video_uc_priv {
 	ulong video_ptr;
+	bool cyc_active;
+	struct cyclic_info cyc;
 };
 
 /** struct vid_rgb - Describes a video colour */
@@ -349,6 +355,7 @@
 /* Flush video activity to the caches */
 int video_sync(struct udevice *vid, bool force)
 {
+	struct video_priv *priv = dev_get_uclass_priv(vid);
 	struct video_ops *ops = video_get_ops(vid);
 	int ret;
 
@@ -358,28 +365,26 @@
 			return ret;
 	}
 
+	if (CONFIG_IS_ENABLED(CYCLIC) && !force &&
+	    get_timer(priv->last_sync) < CONFIG_VIDEO_SYNC_MS)
+		return 0;
+
 	/*
 	 * flush_dcache_range() is declared in common.h but it seems that some
 	 * architectures do not actually implement it. Is there a way to find
 	 * out whether it exists? For now, ARM is safe.
 	 */
 #if defined(CONFIG_ARM) && !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
-	struct video_priv *priv = dev_get_uclass_priv(vid);
-
 	if (priv->flush_dcache) {
 		flush_dcache_range((ulong)priv->fb,
 				   ALIGN((ulong)priv->fb + priv->fb_size,
 					 CONFIG_SYS_CACHELINE_SIZE));
 	}
 #elif defined(CONFIG_VIDEO_SANDBOX_SDL)
-	struct video_priv *priv = dev_get_uclass_priv(vid);
-	static ulong last_sync;
-
-	if (force || get_timer(last_sync) > 100) {
-		sandbox_sdl_sync(priv->fb);
-		last_sync = get_timer(0);
-	}
+	sandbox_sdl_sync(priv->fb);
 #endif
+	priv->last_sync = get_timer(0);
+
 	return 0;
 }
 
@@ -528,10 +533,16 @@
 	return vc_priv->y_charsize;
 }
 
+static void video_idle(struct cyclic_info *cyc)
+{
+	video_sync_all();
+}
+
 /* Set up the display ready for use */
 static int video_post_probe(struct udevice *dev)
 {
 	struct video_uc_plat *plat = dev_get_uclass_plat(dev);
+	struct video_uc_priv *uc_priv = uclass_get_priv(dev->uclass);
 	struct video_priv *priv = dev_get_uclass_priv(dev);
 	char name[30], drv[15], *str;
 	const char *drv_name = drv;
@@ -622,6 +633,16 @@
 		}
 	}
 
+	/* register cyclic as soon as the first video device is probed */
+	if (CONFIG_IS_ENABLED(CYCLIC) && (gd->flags && GD_FLG_RELOC) &&
+	    !uc_priv->cyc_active) {
+		uint ms = CONFIG_IF_ENABLED_INT(CYCLIC, VIDEO_SYNC_CYCLIC_MS);
+
+		cyclic_register(&uc_priv->cyc, video_idle, ms * 1000,
+				"video_init");
+		uc_priv->cyc_active = true;
+	}
+
 	return 0;
 };
 
@@ -661,6 +682,18 @@
 	return 0;
 }
 
+__maybe_unused static int video_destroy(struct uclass *uc)
+{
+	struct video_uc_priv *uc_priv = uclass_get_priv(uc);
+
+	if (uc_priv->cyc_active) {
+		cyclic_unregister(&uc_priv->cyc);
+		uc_priv->cyc_active = false;
+	}
+
+	return 0;
+}
+
 UCLASS_DRIVER(video) = {
 	.id		= UCLASS_VIDEO,
 	.name		= "video",
@@ -670,4 +703,5 @@
 	.priv_auto	= sizeof(struct video_uc_priv),
 	.per_device_auto	= sizeof(struct video_priv),
 	.per_device_plat_auto	= sizeof(struct video_uc_plat),
+	CONFIG_IS_ENABLED(CYCLIC, (.destroy = video_destroy, ))
 };
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 8318fd7..0c3e991 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -4,6 +4,7 @@
 	bool "Enable U-Boot watchdog reset"
 	depends on !HW_WATCHDOG
 	select CYCLIC
+	imply SPL_CYCLIC if SPL
 	help
 	  This option enables U-Boot watchdog support where U-Boot is using
 	  watchdog_reset function to service watchdog device in U-Boot. Enable
@@ -408,6 +409,7 @@
 config SPL_WDT
 	bool "Enable driver model for watchdog timer drivers in SPL"
 	depends on SPL_DM
+	select SPL_CYCLIC if CYCLIC
 	help
 	  Enable driver model for watchdog timer in SPL.
 	  This is similar to CONFIG_WDT in U-Boot.
diff --git a/dts/update-dts-subtree.sh b/dts/update-dts-subtree.sh
deleted file mode 100755
index a57b78a..0000000
--- a/dts/update-dts-subtree.sh
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0+
-#
-# Copyright 2024 Linaro Ltd.
-#
-# Usage: from the top level U-Boot source tree, run:
-# $ ./dts/update-dts-subtree.sh pull <release-tag>
-# $ ./dts/update-dts-subtree.sh pick <commit-id>
-#
-# The script will pull changes from devicetree-rebasing repo into U-Boot
-# as a subtree located as <U-Boot>/dts/upstream sub-directory. It will
-# automatically create a squash/merge commit listing the commits imported.
-
-set -e
-
-merge_commit_msg=$(cat << EOF
-Subtree merge tag '$2' of devicetree-rebasing repo [1] into dts/upstream
-
-[1] https://git.kernel.org/pub/scm/linux/kernel/git/devicetree/devicetree-rebasing.git/
-EOF
-)
-
-remote_add_and_fetch() {
-    if ! git remote get-url devicetree-rebasing 2>/dev/null
-    then
-        echo "Warning: Script automatically adds new git remote via:"
-        echo "    git remote add devicetree-rebasing \\"
-        echo "        https://git.kernel.org/pub/scm/linux/kernel/git/devicetree/devicetree-rebasing.git"
-        git remote add devicetree-rebasing \
-            https://git.kernel.org/pub/scm/linux/kernel/git/devicetree/devicetree-rebasing.git
-    fi
-    git fetch devicetree-rebasing master
-}
-
-if [ "$1" = "pull" ]
-then
-    remote_add_and_fetch
-    git subtree pull --prefix dts/upstream devicetree-rebasing \
-        "$2" --squash -m "${merge_commit_msg}"
-elif [ "$1" = "pick" ]
-then
-    remote_add_and_fetch
-    git cherry-pick -x --strategy=subtree -Xsubtree=dts/upstream/ "$2"
-else
-    echo "usage: $0 <op> <ref>"
-    echo "  <op>     pull or pick"
-    echo "  <ref>    release tag [pull] or commit id [pick]"
-fi
diff --git a/env/mmc.c b/env/mmc.c
index 776df07..0338aa6 100644
--- a/env/mmc.c
+++ b/env/mmc.c
@@ -110,8 +110,9 @@
 	int hwpart = 0;
 	int err;
 
-	if (IS_ENABLED(CONFIG_SYS_MMC_ENV_PART))
-		hwpart = mmc_get_env_part(mmc);
+#if defined(CONFIG_SYS_MMC_ENV_PART)
+	hwpart = mmc_get_env_part(mmc);
+#endif
 
 #if defined(CONFIG_ENV_MMC_PARTITION)
 	str = CONFIG_ENV_MMC_PARTITION;
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index aa336d6..27aa75e 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -481,7 +481,7 @@
 	 */
 	struct event_state event_state;
 #endif
-#ifdef CONFIG_CYCLIC
+#if CONFIG_IS_ENABLED(CYCLIC)
 	/**
 	 * @cyclic_list: list of registered cyclic functions
 	 */
diff --git a/include/asm-generic/int-ll64.h b/include/asm-generic/int-ll64.h
index 7451718..aa57202 100644
--- a/include/asm-generic/int-ll64.h
+++ b/include/asm-generic/int-ll64.h
@@ -43,5 +43,4 @@
 
 #endif /* __ASSEMBLY__ */
 
-
 #endif /* _ASM_GENERIC_INT_LL64_H */
diff --git a/include/ata.h b/include/ata.h
index a7bcee6..57be0e8 100644
--- a/include/ata.h
+++ b/include/ata.h
@@ -73,7 +73,6 @@
 #define ATAPI_CMD_START_STOP 0x1B
 #define ATAPI_CMD_READ_12 0xA8
 
-
 #define ATA_GET_ERR()	inb(ATA_STATUS)
 #define ATA_GET_STAT()	inb(ATA_STATUS)
 #define ATA_OK_STAT(stat,good,bad)	(((stat)&((good)|(bad)))==(good))
@@ -189,7 +188,6 @@
 	unsigned short	words164_255[92];/* reserved words 164-255 */
 } hd_driveid_t;
 
-
 /*
  * PIO Mode Configuration
  *
diff --git a/include/blkmap.h b/include/blkmap.h
index 30dc84a..d530954 100644
--- a/include/blkmap.h
+++ b/include/blkmap.h
@@ -65,7 +65,6 @@
 int blkmap_map_pmem(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
 		    phys_addr_t paddr);
 
-
 /**
  * blkmap_from_label() - Find blkmap from label
  *
diff --git a/include/bzlib.h b/include/bzlib.h
index 19314f8..e3cf6f9 100644
--- a/include/bzlib.h
+++ b/include/bzlib.h
@@ -62,7 +62,6 @@
   For more information on these sources, see the manual.
 --*/
 
-
 #ifndef _BZLIB_H
 #define _BZLIB_H
 
@@ -117,7 +116,6 @@
    }
    bz_stream;
 
-
 #ifndef BZ_IMPORT
 #define BZ_EXPORT
 #endif
@@ -141,7 +139,6 @@
 #   define BZ_EXTERN extern
 #endif
 
-
 /*-- Core (low-level) library functions --*/
 
 BZ_EXTERN int BZ_API(BZ2_bzCompressInit) (
@@ -174,7 +171,6 @@
       bz_stream *strm
    );
 
-
 /*-- High(er) level library functions --*/
 
 #ifndef BZ_NO_STDIO
@@ -247,7 +243,6 @@
    );
 #endif
 
-
 /*-- Utility functions --*/
 
 BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) (
@@ -269,7 +264,6 @@
       int           verbosity
    );
 
-
 /*--
    Code contributed by Yoshioka Tsuneo
    (QWF00133@niftyserve.or.jp/tsuneo-y@is.aist-nara.ac.jp),
diff --git a/include/clk.h b/include/clk.h
index af23e4f..045e923 100644
--- a/include/clk.h
+++ b/include/clk.h
@@ -444,7 +444,7 @@
 struct clk *clk_get_parent(struct clk *clk);
 
 /**
- * clk_get_parent_rate() - Get parent of current clock rate.
+ * clk_get_parent_rate() - Get rate of current clock's parent.
  * @clk:	A clock struct that was previously successfully requested by
  *		clk_request/get_by_*().
  *
diff --git a/include/cpu.h b/include/cpu.h
index 2077ff3..0018910 100644
--- a/include/cpu.h
+++ b/include/cpu.h
@@ -102,6 +102,15 @@
 	 *         if not.
 	 */
 	int (*is_current)(struct udevice *dev);
+
+	/**
+	 * release_core() - Relase a CPU core to the given address to run application
+	 *
+	 * @dev:	Device to check (UCLASS_CPU)
+	 * @addr:	Address to relese the CPU core
+	 * @return 0 if OK, -ve on error
+	 */
+	int (*release_core)(const struct udevice *dev, phys_addr_t addr);
 };
 
 #define cpu_get_ops(dev)        ((struct cpu_ops *)(dev)->driver->ops)
@@ -164,4 +173,10 @@
  */
 struct udevice *cpu_get_current_dev(void);
 
+/**
+ * cpu_release_core() - Relase a CPU core to the given address to run application
+ *
+ * @return 0 if OK, -ve on error
+ */
+int cpu_release_core(const struct udevice *dev, phys_addr_t addr);
 #endif
diff --git a/include/cyclic.h b/include/cyclic.h
index 2c3d383..cd95b69 100644
--- a/include/cyclic.h
+++ b/include/cyclic.h
@@ -46,7 +46,8 @@
 /** Function type for cyclic functions */
 typedef void (*cyclic_func_t)(struct cyclic_info *c);
 
-#if defined(CONFIG_CYCLIC)
+#if CONFIG_IS_ENABLED(CYCLIC)
+
 /**
  * cyclic_register - Register a new cyclic function
  *
@@ -123,6 +124,6 @@
 {
 	return 0;
 }
-#endif
+#endif /* CYCLIC */
 
 #endif
diff --git a/include/dfu.h b/include/dfu.h
index fa1918c..6c5431b 100644
--- a/include/dfu.h
+++ b/include/dfu.h
@@ -99,7 +99,6 @@
 	int dev_num;
 };
 
-
 #if defined(CONFIG_DFU_NAME_MAX_SIZE)
 #define DFU_NAME_SIZE			CONFIG_DFU_NAME_MAX_SIZE
 #else
diff --git a/include/dm/of_addr.h b/include/dm/of_addr.h
index e7f3a28..5fb5a48 100644
--- a/include/dm/of_addr.h
+++ b/include/dm/of_addr.h
@@ -44,7 +44,6 @@
  */
 u64 of_translate_dma_address(const struct device_node *np, const __be32 *in_addr);
 
-
 /**
  * of_get_dma_range() - get dma-ranges for a specific DT node
  *
diff --git a/include/dm/util.h b/include/dm/util.h
index 95c3527..ec518c5 100644
--- a/include/dm/util.h
+++ b/include/dm/util.h
@@ -17,14 +17,6 @@
 struct list_head;
 
 /**
- * list_count_items() - Count number of items in a list
- *
- * @param head:		Head of list
- * Return: number of items, or 0 if empty
- */
-int list_count_items(struct list_head *head);
-
-/**
  * Dump out a tree of all devices starting @uclass
  *
  * @dev_name: udevice name
diff --git a/include/dt-bindings/clock/mt8516-clk.h b/include/dt-bindings/clock/mt8516-clk.h
index 745b87f..d6f9a45 100644
--- a/include/dt-bindings/clock/mt8516-clk.h
+++ b/include/dt-bindings/clock/mt8516-clk.h
@@ -8,7 +8,6 @@
 #ifndef _DT_BINDINGS_CLK_MT8516_H
 #define _DT_BINDINGS_CLK_MT8516_H
 
-
 /* APMIXEDSYS */
 
 #define CLK_APMIXED_ARMPLL	0
diff --git a/include/dt-bindings/clock/qcom,gcc-msm8996.h b/include/dt-bindings/clock/qcom,gcc-msm8996.h
index ddfd6fd..de5c36c 100644
--- a/include/dt-bindings/clock/qcom,gcc-msm8996.h
+++ b/include/dt-bindings/clock/qcom,gcc-msm8996.h
@@ -347,7 +347,6 @@
 #define GCC_USB3PHY_PHY_BCR					104
 #define GCC_MSS_RESTART						105
 
-
 /* Indexes for GDSCs */
 #define AGGRE0_NOC_GDSC			0
 #define HLOS1_VOTE_AGGRE0_NOC_GDSC	1
diff --git a/include/dt-bindings/clock/qcom,rpmh.h b/include/dt-bindings/clock/qcom,rpmh.h
index 0a7d1be..bf5b59b 100644
--- a/include/dt-bindings/clock/qcom,rpmh.h
+++ b/include/dt-bindings/clock/qcom,rpmh.h
@@ -1,7 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /* Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved. */
 
-
 #ifndef _DT_BINDINGS_CLK_MSM_RPMH_H
 #define _DT_BINDINGS_CLK_MSM_RPMH_H
 
diff --git a/include/dt-bindings/clock/tegra210-car.h b/include/dt-bindings/clock/tegra210-car.h
index bd3530e..eddac16 100644
--- a/include/dt-bindings/clock/tegra210-car.h
+++ b/include/dt-bindings/clock/tegra210-car.h
@@ -248,7 +248,6 @@
 #define TEGRA210_CLK_SOR_SAFE 222
 #define TEGRA210_CLK_PLL_P_OUT_CPU 223
 
-
 #define TEGRA210_CLK_UARTB 224
 #define TEGRA210_CLK_VFIR 225
 #define TEGRA210_CLK_SPDIF_IN 226
diff --git a/include/dt-bindings/dma/at91.h b/include/dt-bindings/dma/at91.h
index ab6cbba..0e7814b 100644
--- a/include/dt-bindings/dma/at91.h
+++ b/include/dt-bindings/dma/at91.h
@@ -26,7 +26,6 @@
 #define AT91_DMA_CFG_FIFOCFG_ALAP	(0x1 << AT91_DMA_CFG_FIFOCFG_OFFSET)	/* largest defined AHB burst */
 #define AT91_DMA_CFG_FIFOCFG_ASAP	(0x2 << AT91_DMA_CFG_FIFOCFG_OFFSET)	/* single AHB access */
 
-
 /* ---------- XDMAC ---------- */
 #define AT91_XDMAC_DT_MEM_IF_MASK	(0x1)
 #define AT91_XDMAC_DT_MEM_IF_OFFSET	(13)
diff --git a/include/dt-bindings/mfd/stm32f7-rcc.h b/include/dt-bindings/mfd/stm32f7-rcc.h
index a4e4f92..1aa267e 100644
--- a/include/dt-bindings/mfd/stm32f7-rcc.h
+++ b/include/dt-bindings/mfd/stm32f7-rcc.h
@@ -34,7 +34,6 @@
 #define STM32F7_AHB1_RESET(bit) (STM32F7_RCC_AHB1_##bit + (0x10 * 8))
 #define STM32F7_AHB1_CLOCK(bit) (STM32F7_RCC_AHB1_##bit)
 
-
 /* AHB2 */
 #define STM32F7_RCC_AHB2_DCMI		0
 #define STM32F7_RCC_AHB2_CRYP		4
diff --git a/include/dw_hdmi.h b/include/dw_hdmi.h
index f4d66ed..b735182 100644
--- a/include/dw_hdmi.h
+++ b/include/dw_hdmi.h
@@ -309,7 +309,6 @@
 	HDMI_FC_INVIDCONF_IN_I_P_INTERLACED = 0x1,
 	HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE = 0x0,
 
-
 	/* fc_aviconf0-fc_aviconf3 field values */
 	HDMI_FC_AVICONF0_PIX_FMT_MASK = 0x03,
 	HDMI_FC_AVICONF0_PIX_FMT_RGB = 0x00,
diff --git a/include/ec_commands.h b/include/ec_commands.h
index 36f4a02..23597d2 100644
--- a/include/ec_commands.h
+++ b/include/ec_commands.h
@@ -345,7 +345,6 @@
 /* Current version of ACPI memory address space */
 #define EC_ACPI_MEM_VERSION_CURRENT 2
 
-
 /*
  * This header file is used in coreboot both in C and ACPI code.  The ACPI code
  * is pre-processed to handle constants but the ASL compiler is unable to
@@ -984,7 +983,6 @@
 	uint32_t flags;
 };
 
-
 /*****************************************************************************/
 /* Get/Set miscellaneous values */
 
@@ -1300,7 +1298,6 @@
 	uint32_t size;     /* Size to erase in bytes */
 };
 
-
 #define EC_VER_FLASH_WRITE 1
 /* v1 add async erase:
  * subcommands can returns:
@@ -1451,7 +1448,6 @@
 	uint8_t block[EC_VBNV_BLOCK_SIZE_V2];
 };
 
-
 /* Get SPI flash information */
 #define EC_CMD_FLASH_SPI_INFO 0x0018
 
@@ -1469,7 +1465,6 @@
 	uint8_t sr1, sr2;
 };
 
-
 /* Select flash during flash operations */
 #define EC_CMD_FLASH_SELECT 0x0019
 
@@ -1801,7 +1796,6 @@
 		struct lightbar_params_v0 get_params_v0;
 		struct lightbar_params_v1 get_params_v1;
 
-
 		struct lightbar_params_v2_timing get_params_v2_timing;
 		struct lightbar_params_v2_tap get_params_v2_tap;
 		struct lightbar_params_v2_oscillation get_params_v2_osc;
@@ -2667,7 +2661,6 @@
 	uint16_t value;
 };
 
-
 /* The version 1 structs are visible. */
 enum ec_temp_thresholds {
 	EC_TEMP_THRESH_WARN = 0,
@@ -2765,7 +2758,6 @@
 	float val[0];
 };
 
-
 /* Read raw TMP006 data */
 #define EC_CMD_TMP006_GET_RAW 0x0055
 
@@ -3082,7 +3074,6 @@
 /*****************************************************************************/
 /* Host event commands */
 
-
 /* Obsolete. New implementation should use EC_CMD_PROGRAM_HOST_EVENT instead */
 /*
  * Host event mask params and response structures, shared by all of the host
@@ -3619,7 +3610,6 @@
 	};
 };
 
-
 /*
  * Set maximum battery charging current.
  */
@@ -4207,7 +4197,6 @@
 	uint8_t payload[0]; /* optional additional data payload: 0..16 bytes */
 };
 
-
 /* The timestamp is the microsecond counter shifted to get about a ms. */
 #define PD_LOG_TIMESTAMP_SHIFT 10 /* 1 LSB = 1024us */
 
@@ -4322,7 +4311,6 @@
 	uint8_t port; /* port#, or 0 for events unrelated to a given port */
 };
 
-
 /* Control USB-PD chip */
 #define EC_CMD_PD_CONTROL 0x0119
 
diff --git a/include/efi_api.h b/include/efi_api.h
index ab40b1b..f07d074 100644
--- a/include/efi_api.h
+++ b/include/efi_api.h
@@ -2017,7 +2017,6 @@
 	struct win_certificate_uefi_guid auth_info;
 } __attribute__((__packed__));
 
-
 /**
  * struct efi_signature_data - A format of signature
  *
diff --git a/include/efi_loader.h b/include/efi_loader.h
index f2e5063..f84852e 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -153,7 +153,6 @@
 	EFI_GUID(0xb2ac5fc9, 0x92b7, 0x4acd, \
 		 0xae, 0xac, 0x11, 0xe8, 0x18, 0xc3, 0x13, 0x0c)
 
-
 /* Use internal device tree when starting UEFI application */
 #define EFI_FDT_USE_INTERNAL NULL
 
diff --git a/include/env_internal.h b/include/env_internal.h
index cbd1ef3..0a267e3 100644
--- a/include/env_internal.h
+++ b/include/env_internal.h
@@ -15,7 +15,6 @@
 #ifndef _ENV_INTERNAL_H_
 #define _ENV_INTERNAL_H_
 
-
 /**************************************************************************
  *
  * The "environment" is stored as a list of '\0' terminated
diff --git a/include/exports.h b/include/exports.h
index 6f8c9cf..23cc3a6 100644
--- a/include/exports.h
+++ b/include/exports.h
@@ -70,7 +70,6 @@
 #undef EXPORT_FUNC
 };
 
-
 #define XF_VERSION	9
 
 #if defined(CONFIG_X86)
diff --git a/include/firmware/imx/sci/rpc.h b/include/firmware/imx/sci/rpc.h
index 85af6f3..28adec2 100644
--- a/include/firmware/imx/sci/rpc.h
+++ b/include/firmware/imx/sci/rpc.h
@@ -44,7 +44,6 @@
 #define SC_RPC_SVC_SECO         9U
 #define SC_RPC_SVC_ABORT        10U
 
-
 /* Types */
 
 struct sc_rpc_msg_s {
diff --git a/include/flash.h b/include/flash.h
index 0f73697..60babe8 100644
--- a/include/flash.h
+++ b/include/flash.h
@@ -256,7 +256,6 @@
 #define AMD_ID_GL128N_2	0x22212221	/* 2nd ID word for S29GL128N */
 #define AMD_ID_GL128N_3	0x22012201	/* 3rd ID word for S29GL128N */
 
-
 #define AMD_ID_LV320B_2 0x221A221A	/* 2d ID word for AM29LV320MB at 0x38 */
 #define AMD_ID_LV320B_3 0x22002200	/* 3d ID word for AM29LV320MB at 0x3c */
 
@@ -476,7 +475,6 @@
 
 #define FLASH_UNKNOWN	0xFFFF		/* unknown flash type			*/
 
-
 /* manufacturer offsets
  */
 #define FLASH_MAN_AMD	0x00000000	/* AMD					*/
diff --git a/include/fsl-mc/fsl_dprc.h b/include/fsl-mc/fsl_dprc.h
index fb95ac5..22240d8 100644
--- a/include/fsl-mc/fsl_dprc.h
+++ b/include/fsl-mc/fsl_dprc.h
@@ -149,7 +149,6 @@
  */
 #define DPRC_CFG_OPT_TOPOLOGY_CHANGES_ALLOWED	0x00000008
 
-
 /* AIOP - Indicates that container belongs to AIOP. */
 #define DPRC_CFG_OPT_AIOP			0x00000020
 
diff --git a/include/fsl-mc/fsl_mc_cmd.h b/include/fsl-mc/fsl_mc_cmd.h
index c239595..3acc427 100644
--- a/include/fsl-mc/fsl_mc_cmd.h
+++ b/include/fsl-mc/fsl_mc_cmd.h
@@ -68,7 +68,6 @@
 /* Command completion flag */
 #define MC_CMD_FLAG_INTR_DIS	0x01000000
 
-
 #define MC_CMD_HDR_CMDID_O	48	/* Command ID field offset */
 #define MC_CMD_HDR_CMDID_S	16	/* Command ID field size */
 #define MC_CMD_HDR_STATUS_O	16	/* Status field offset */
diff --git a/include/fsl-mc/fsl_qbman_portal.h b/include/fsl-mc/fsl_qbman_portal.h
index ee0e4aa..11905f4 100644
--- a/include/fsl-mc/fsl_qbman_portal.h
+++ b/include/fsl-mc/fsl_qbman_portal.h
@@ -23,7 +23,6 @@
  * dependencies we just pre/re-declare it here opaquely. */
 struct ldpaa_dq;
 
-
 /* ------------------- */
 /* Pull-mode dequeuing */
 /* ------------------- */
@@ -110,7 +109,6 @@
 	uint32_t dont_manipulate_directly[8];
 };
 
-
 /* Clear the contents of a descriptor to default/starting state. */
 void qbman_eq_desc_clear(struct qbman_eq_desc *);
 /* Exactly one of the following descriptor "actions" should be set. (Calling
diff --git a/include/fsl_ddr_sdram.h b/include/fsl_ddr_sdram.h
index c43f780..182f583 100644
--- a/include/fsl_ddr_sdram.h
+++ b/include/fsl_ddr_sdram.h
@@ -197,7 +197,6 @@
 /* DEBUG_29 register */
 #define DDR_TX_BD_DIS	(1 << 10) /* Transmit Bit Deskew Disable */
 
-
 #if (defined(CONFIG_SYS_FSL_DDR_VER) && \
 	(CONFIG_SYS_FSL_DDR_VER >= FSL_DDR_VER_4_7))
 #ifdef CONFIG_SYS_FSL_DDR3L
@@ -473,7 +472,6 @@
 extern void ddr_enable_ecc(unsigned int dram_size);
 #endif
 
-
 typedef struct fixed_ddr_parm{
 	int min_freq;
 	int max_freq;
diff --git a/include/fsl_dtsec.h b/include/fsl_dtsec.h
index ccd6572..d93f50e 100644
--- a/include/fsl_dtsec.h
+++ b/include/fsl_dtsec.h
@@ -97,7 +97,6 @@
 	u32	res9[80];
 };
 
-
 /* TBI register addresses */
 #define TBI_CR			0x00
 #define TBI_SR			0x01
diff --git a/include/fsl_errata.h b/include/fsl_errata.h
index 9f07072..c15f9a0 100644
--- a/include/fsl_errata.h
+++ b/include/fsl_errata.h
@@ -14,7 +14,6 @@
 #include <asm/arch/soc.h>
 #endif
 
-
 #ifdef CONFIG_SYS_FSL_ERRATUM_A006379
 static inline bool has_erratum_a006379(void)
 {
@@ -62,7 +61,6 @@
 	u32 svr = get_svr();
 	u32 soc = SVR_SOC_VER(svr);
 
-
 	switch (soc) {
 #ifdef CONFIG_ARCH_LS1021A
 	case SOC_VER_LS1020:
diff --git a/include/fsl_ifc.h b/include/fsl_ifc.h
index 4991d93..3ac2268 100644
--- a/include/fsl_ifc.h
+++ b/include/fsl_ifc.h
@@ -33,7 +33,6 @@
 #error Neither CONFIG_SYS_FSL_IFC_LE nor CONFIG_SYS_FSL_IFC_BE is defined
 #endif
 
-
 /*
  * CSPR - Chip Select Property Register
  */
@@ -790,7 +789,6 @@
  */
 #define IFC_GPCM_STAT_BSY		0x80000000  /* GPCM is busy */
 
-
 #ifndef __ASSEMBLY__
 #include <asm/io.h>
 
diff --git a/include/fsl_mmdc.h b/include/fsl_mmdc.h
index 05fb41f..f706cfe 100644
--- a/include/fsl_mmdc.h
+++ b/include/fsl_mmdc.h
@@ -12,7 +12,6 @@
 /* PHY Pre-defined Compare and CA delay-line Configuration (MPPDCMPR2) */
 #define MPPDCMPR2_MPR_COMPARE_EN	(1 << 0)
 
-
 /* MMDC PHY Read DQS gating control register 0 (MPDGCTRL0) */
 #define AUTO_RD_DQS_GATING_CALIBRATION_EN	(1 << 28)
 
diff --git a/include/fsl_validate.h b/include/fsl_validate.h
index 66a5883..4b69de8 100644
--- a/include/fsl_validate.h
+++ b/include/fsl_validate.h
@@ -161,7 +161,6 @@
 
 #endif /* CONFIG_ESBC_HDR_LS */
 
-
 #if defined(CONFIG_FSL_ISBC_KEY_EXT)
 struct ie_key_table {
 	u32 key_len;
diff --git a/include/gt64120.h b/include/gt64120.h
index b58afe3..b8d3f03 100644
--- a/include/gt64120.h
+++ b/include/gt64120.h
@@ -221,7 +221,6 @@
 #define GT_PCI0_HICMASK_OFS	0xca4
 #define GT_PCI1_SERR1MASK_OFS	0xca8
 
-
 /*
  * I2O Support Registers
  */
@@ -283,7 +282,6 @@
 #define GT_CPU_WR_DXDXDXDX	0
 #define GT_CPU_WR_DDDD		1
 
-
 #define GT_PCI_DCRM_SHF		21
 #define GT_PCI_LD_SHF		0
 #define GT_PCI_LD_MSK		(MSK(15) << GT_PCI_LD_SHF)
@@ -292,7 +290,6 @@
 #define GT_PCI_REMAP_SHF	0
 #define GT_PCI_REMAP_MSK	(MSK(11) << GT_PCI_REMAP_SHF)
 
-
 #define GT_CFGADDR_CFGEN_SHF	31
 #define GT_CFGADDR_CFGEN_MSK	(MSK(1) << GT_CFGADDR_CFGEN_SHF)
 #define GT_CFGADDR_CFGEN_BIT	GT_CFGADDR_CFGEN_MSK
@@ -309,7 +306,6 @@
 #define GT_CFGADDR_REGNUM_SHF	2
 #define GT_CFGADDR_REGNUM_MSK	(MSK(6) << GT_CFGADDR_REGNUM_SHF)
 
-
 #define GT_SDRAM_BM_ORDER_SHF	2
 #define GT_SDRAM_BM_ORDER_MSK	(MSK(1) << GT_SDRAM_BM_ORDER_SHF)
 #define GT_SDRAM_BM_ORDER_BIT	GT_SDRAM_BM_ORDER_MSK
@@ -318,7 +314,6 @@
 
 #define GT_SDRAM_BM_RSVD_ALL1	0xffb
 
-
 #define GT_SDRAM_ADDRDECODE_ADDR_SHF	0
 #define GT_SDRAM_ADDRDECODE_ADDR_MSK	(MSK(3) << GT_SDRAM_ADDRDECODE_ADDR_SHF)
 #define GT_SDRAM_ADDRDECODE_ADDR_0	0
@@ -330,7 +325,6 @@
 #define GT_SDRAM_ADDRDECODE_ADDR_6	6
 #define GT_SDRAM_ADDRDECODE_ADDR_7	7
 
-
 #define GT_SDRAM_B0_CASLAT_SHF		0
 #define GT_SDRAM_B0_CASLAT_MSK		(MSK(2) << GT_SDRAM_B0__SHF)
 #define GT_SDRAM_B0_CASLAT_2		1
@@ -396,7 +390,6 @@
 #define GT_SDRAM_B0_BLEN_8		0
 #define GT_SDRAM_B0_BLEN_4		1
 
-
 #define GT_SDRAM_CFG_REFINT_SHF		0
 #define GT_SDRAM_CFG_REFINT_MSK		(MSK(14) << GT_SDRAM_CFG_REFINT_SHF)
 
@@ -443,7 +436,6 @@
 #define GT_TC_CONTROL_SELTC0_MSK	(MSK(1) << GT_TC_CONTROL_SELTC0_SHF)
 #define GT_TC_CONTROL_SELTC0_BIT	GT_TC_CONTROL_SELTC0_MSK
 
-
 #define GT_PCI0_BARE_SWSCS3BOOTDIS_SHF	0
 #define GT_PCI0_BARE_SWSCS3BOOTDIS_MSK	\
 	(MSK(1) << GT_PCI0_BARE_SWSCS3BOOTDIS_SHF)
@@ -481,7 +473,6 @@
 #define GT_PCI0_BARE_SCS10DIS_MSK	(MSK(1) << GT_PCI0_BARE_SCS10DIS_SHF)
 #define GT_PCI0_BARE_SCS10DIS_BIT	GT_PCI0_BARE_SCS10DIS_MSK
 
-
 #define GT_INTRCAUSE_MASABORT0_SHF	18
 #define GT_INTRCAUSE_MASABORT0_MSK	(MSK(1) << GT_INTRCAUSE_MASABORT0_SHF)
 #define GT_INTRCAUSE_MASABORT0_BIT	GT_INTRCAUSE_MASABORT0_MSK
@@ -490,7 +481,6 @@
 #define GT_INTRCAUSE_TARABORT0_MSK	(MSK(1) << GT_INTRCAUSE_TARABORT0_SHF)
 #define GT_INTRCAUSE_TARABORT0_BIT	GT_INTRCAUSE_TARABORT0_MSK
 
-
 #define GT_PCI0_CMD_MBYTESWAP_SHF	0
 #define GT_PCI0_CMD_MBYTESWAP_MSK	(MSK(1) << GT_PCI0_CMD_MBYTESWAP_SHF)
 #define GT_PCI0_CMD_MBYTESWAP_BIT	GT_PCI0_CMD_MBYTESWAP_MSK
diff --git a/include/jffs2/jffs2.h b/include/jffs2/jffs2.h
index 651f94c..e986508 100644
--- a/include/jffs2/jffs2.h
+++ b/include/jffs2/jffs2.h
@@ -109,7 +109,6 @@
 #define JFFS2_INO_FLAG_USERCOMPR  2	/* User has requested a specific
 					   compression type */
 
-
 struct jffs2_unknown_node
 {
 	/* All start like this */
@@ -212,7 +211,6 @@
 # define DT_WHT         DT_WHT
   };
 
-
 u32 jffs2_1pass_ls(struct part_info *part,const char *fname);
 u32 jffs2_1pass_load(char *dest, struct part_info *part,const char *fname);
 u32 jffs2_1pass_info(struct part_info *part);
diff --git a/include/key_matrix.h b/include/key_matrix.h
index 17f5d12..fffe2dd 100644
--- a/include/key_matrix.h
+++ b/include/key_matrix.h
@@ -8,7 +8,6 @@
 #ifndef _KEY_MATRIX_H
 #define _KEY_MATRIX_H
 
-
 /* Information about a matrix keyboard */
 struct key_matrix {
 	/* Dimensions of the keyboard matrix, in rows and columns */
diff --git a/include/led.h b/include/led.h
index a635316..99f93c5 100644
--- a/include/led.h
+++ b/include/led.h
@@ -7,19 +7,34 @@
 #ifndef __LED_H
 #define __LED_H
 
+#include <stdbool.h>
+#include <cyclic.h>
+
 struct udevice;
 
 enum led_state_t {
 	LEDST_OFF = 0,
 	LEDST_ON = 1,
 	LEDST_TOGGLE,
-#ifdef CONFIG_LED_BLINK
 	LEDST_BLINK,
-#endif
 
 	LEDST_COUNT,
 };
 
+enum led_sw_blink_state_t {
+	LED_SW_BLINK_ST_DISABLED,
+	LED_SW_BLINK_ST_NOT_READY,
+	LED_SW_BLINK_ST_OFF,
+	LED_SW_BLINK_ST_ON,
+};
+
+struct led_sw_blink {
+	enum led_sw_blink_state_t state;
+	struct udevice *dev;
+	struct cyclic_info cyclic;
+	const char cyclic_name[0];
+};
+
 /**
  * struct led_uc_plat - Platform data the uclass stores about each device
  *
@@ -29,6 +44,9 @@
 struct led_uc_plat {
 	const char *label;
 	enum led_state_t default_state;
+#ifdef CONFIG_LED_SW_BLINK
+	struct led_sw_blink *sw_blink;
+#endif
 };
 
 /**
@@ -118,4 +136,9 @@
  */
 int led_bind_generic(struct udevice *parent, const char *driver_name);
 
+/* Internal functions for software blinking. Do not use them in your code */
+int led_sw_set_period(struct udevice *dev, int period_ms);
+bool led_sw_is_blinking(struct udevice *dev);
+bool led_sw_on_state_change(struct udevice *dev, enum led_state_t state);
+
 #endif
diff --git a/include/linux/asn1.h b/include/linux/asn1.h
index a4d0bdd..ca20833 100644
--- a/include/linux/asn1.h
+++ b/include/linux/asn1.h
@@ -17,7 +17,6 @@
 };
 #define ASN1_CLASS_BITS	0xc0
 
-
 enum asn1_method {
 	ASN1_PRIM	= 0,	/* Primitive */
 	ASN1_CONS	= 1	/* Constructed */
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index d2e5ca0..f826d7f 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -108,7 +108,6 @@
 	return r;
 }
 
-
 /*
  * hweightN: returns the hamming weight (i.e. the number
  * of bits set) of a N-bit word
diff --git a/include/linux/byteorder/swab.h b/include/linux/byteorder/swab.h
index 5efc252..2b41fba 100644
--- a/include/linux/byteorder/swab.h
+++ b/include/linux/byteorder/swab.h
@@ -76,7 +76,6 @@
 #  define __arch__swab64s(x) do { *(x) = __swab64p((x)); } while (0)
 #endif
 
-
 /*
  * Allow constant folding
  */
@@ -99,7 +98,6 @@
 #  define __swab64(x) __fswab64(x)
 #endif /* OPTIMIZE */
 
-
 static __inline__ __attribute__((const)) __u16 __fswab16(__u16 x)
 {
 	return __arch__swab16(x);
diff --git a/include/linux/edd.h b/include/linux/edd.h
index 992ce7c..904e3d2 100644
--- a/include/linux/edd.h
+++ b/include/linux/edd.h
@@ -35,7 +35,6 @@
 #define EDDMAGIC1 0x55AA
 #define EDDMAGIC2 0xAA55
 
-
 #define READ_SECTORS 0x02         /* int13 AH=0x02 is READ_SECTORS command */
 #define EDD_MBR_SIG_OFFSET 0x1B8  /* offset of signature in the MBR */
 #define EDD_MBR_SIG_BUF    0x290  /* addr in boot params */
diff --git a/include/linux/err.h b/include/linux/err.h
index 5ede824..7a0b212 100644
--- a/include/linux/err.h
+++ b/include/linux/err.h
@@ -6,7 +6,6 @@
 
 #include <linux/errno.h>
 
-
 /*
  * Kernel pointers have redundant information, so we can use a
  * scheme where we can return either an error code or a dentry
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index aa7d2fd..1b0736c 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -376,7 +376,6 @@
 	__u8    proto;
 };
 
-
 /**
  * struct ethtool_rxfh_indir - command to get or set RX flow hash indirection
  * @cmd: Specific command number - %ETHTOOL_GRXFHINDIR or %ETHTOOL_SRXFHINDIR
diff --git a/include/linux/fb.h b/include/linux/fb.h
index c820a4f..5fbc30c 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -160,7 +160,6 @@
 #define VESA_HSYNC_SUSPEND	2
 #define VESA_POWERDOWN		3
 
-
 enum {
 	/* screen: unblanked, hsync: on,  vsync: on */
 	FB_BLANK_UNBLANK       = VESA_NO_BLANKING,
@@ -583,7 +582,6 @@
 #define FB_MODE_IS_FIRST	16
 #define FB_MODE_IS_FROM_VAR	32
 
-
 /* drivers/video/fbcmap.c */
 
 extern int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp);
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 5cd6c9d..939465f 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -255,7 +255,6 @@
  */
 #define clamp_val(val, lo, hi) clamp_t(typeof(val), val, lo, hi)
 
-
 /*
  * swap - swap value of @a and @b
  */
diff --git a/include/linux/list.h b/include/linux/list.h
index 6910721..0f9d939 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -547,6 +547,21 @@
 	     &pos->member != (head);					\
 	     pos = n, n = list_entry(n->member.prev, typeof(*n), member))
 
+/**
+ * list_count_nodes - count nodes in the list
+ * @head:	the head for your list.
+ */
+static inline size_t list_count_nodes(struct list_head *head)
+{
+	struct list_head *pos;
+	size_t count = 0;
+
+	list_for_each(pos, head)
+		count++;
+
+	return count;
+}
+
 /*
  * Double linked lists with a single pointer list head.
  * Mostly useful for hash tables where the two pointer list head is
diff --git a/include/linux/mtd/flashchip.h b/include/linux/mtd/flashchip.h
index 265e89f..00278da 100644
--- a/include/linux/mtd/flashchip.h
+++ b/include/linux/mtd/flashchip.h
@@ -51,7 +51,6 @@
 	FL_UNKNOWN
 } flstate_t;
 
-
 /* NOTE: confusingly, this can be used to refer to more than one chip at a time,
    if they're interleaved.  This can even refer to individual partitions on
    the same physical chip when present. */
@@ -98,5 +97,4 @@
 	struct flchip *erasing;
 };
 
-
 #endif /* __MTD_FLASHCHIP_H__ */
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index ee18a63..983a55c 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -522,7 +522,6 @@
 extern struct mtd_info *get_mtd_device_nm(const char *name);
 extern void put_mtd_device(struct mtd_info *mtd);
 
-
 #ifndef __UBOOT__
 struct mtd_notifier {
 	void (*add)(struct mtd_info *mtd);
@@ -530,7 +529,6 @@
 	struct list_head list;
 };
 
-
 extern void register_mtd_user (struct mtd_notifier *new);
 extern int unregister_mtd_user (struct mtd_notifier *old);
 #endif
diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h
index 0f5a233..1959a69 100644
--- a/include/linux/mtd/partitions.h
+++ b/include/linux/mtd/partitions.h
@@ -11,7 +11,6 @@
 
 #include <linux/types.h>
 
-
 /*
  * Partition definition structure:
  *
@@ -49,7 +48,6 @@
 #define MTDPART_OFS_APPEND	(-1)
 #define MTDPART_SIZ_FULL	(0)
 
-
 struct mtd_info;
 struct device_node;
 
@@ -64,7 +62,6 @@
 	struct device_node *of_node;
 };
 
-
 /*
  * Functions dealing with the various ways of partitioning the space
  */
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index 4abaf47..537c624 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -177,7 +177,6 @@
 /* Bit mask for flags passed to do_nand_read_ecc */
 #define NAND_GET_DEVICE		0x80
 
-
 /*
  * Option constants for bizarre disfunctionality and real
  * features.
@@ -931,7 +930,6 @@
 	int (*setup_data_interface)(struct mtd_info *mtd, int chipnr,
 				    const struct nand_data_interface *conf);
 
-
 	int chip_delay;
 	unsigned int options;
 	unsigned int bbt_options;
diff --git a/include/linux/rbtree.h b/include/linux/rbtree.h
index 1d2b176..3809c3f 100644
--- a/include/linux/rbtree.h
+++ b/include/linux/rbtree.h
@@ -32,7 +32,6 @@
 	struct rb_node *rb_node;
 };
 
-
 #define rb_parent(r)   ((struct rb_node *)((r)->__rb_parent_color & ~3))
 
 #define RB_ROOT	(struct rb_root) { NULL, }
@@ -46,11 +45,9 @@
 #define RB_CLEAR_NODE(node)  \
 	((node)->__rb_parent_color = (unsigned long)(node))
 
-
 extern void rb_insert_color(struct rb_node *, struct rb_root *);
 extern void rb_erase(struct rb_node *, struct rb_root *);
 
-
 /* Find logical next and previous nodes in a tree */
 extern struct rb_node *rb_next(const struct rb_node *);
 extern struct rb_node *rb_prev(const struct rb_node *);
diff --git a/include/linux/rbtree_augmented.h b/include/linux/rbtree_augmented.h
index da04156..605888d 100644
--- a/include/linux/rbtree_augmented.h
+++ b/include/linux/rbtree_augmented.h
@@ -70,7 +70,6 @@
 	rbname ## _propagate, rbname ## _copy, rbname ## _rotate	\
 };
 
-
 #define	RB_RED		0
 #define	RB_BLACK	1
 
diff --git a/include/linux/serial_reg.h b/include/linux/serial_reg.h
index 0613717..99d0aeb 100644
--- a/include/linux/serial_reg.h
+++ b/include/linux/serial_reg.h
@@ -287,7 +287,6 @@
 #define UART_ACR_ICRRD	0x40	/* ICR Read enable */
 #define UART_ACR_ASREN	0x80	/* Additional status enable */
 
-
 /*
  * These definitions are for the RSA-DV II/S card, from
  *
diff --git a/include/linux/string.h b/include/linux/string.h
index df1c1c5..27b2beb 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -14,7 +14,6 @@
 extern char * strsep(char **,const char *);
 extern __kernel_size_t strspn(const char *,const char *);
 
-
 /*
  * Include machine specific inline routines
  */
diff --git a/include/linux/time.h b/include/linux/time.h
index 14a144d..0de44cf 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -34,7 +34,6 @@
 
 #define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
 
-
 /* Used by other time functions.  */
 struct tm {
     int tm_sec;                   /* Seconds.     [0-60] (1 leap second) */
diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h
index a8fa5d7..c8c553b 100644
--- a/include/linux/usb/ch9.h
+++ b/include/linux/usb/ch9.h
@@ -248,7 +248,6 @@
 	__u8  bDescriptorType;
 } __attribute__ ((packed));
 
-
 /*-------------------------------------------------------------------------*/
 
 /* USB_DT_DEVICE: Device descriptor */
@@ -272,7 +271,6 @@
 
 #define USB_DT_DEVICE_SIZE		18
 
-
 /*
  * Device and/or Interface Class codes
  * as found in bDeviceClass or bInterfaceClass
@@ -703,7 +701,6 @@
 	__u8  bRESERVED;
 } __attribute__ ((packed));
 
-
 /*-------------------------------------------------------------------------*/
 
 /* USB_DT_OTG (from OTG 1.0a supplement) */
@@ -745,7 +742,6 @@
 	__u8  iFunction;
 } __attribute__ ((packed));
 
-
 /*-------------------------------------------------------------------------*/
 
 /* USB_DT_SECURITY:  group of wireless security descriptors, including
@@ -789,7 +785,6 @@
 	__u8  bAuthKeyIndex;
 } __attribute__((packed));
 
-
 /*-------------------------------------------------------------------------*/
 
 /* USB_DT_BOS:  group of device-level capabilities */
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index cf21616..c7927df 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -446,7 +446,6 @@
 		ep->ops->fifo_flush(ep);
 }
 
-
 /*-------------------------------------------------------------------------*/
 
 struct usb_dcd_config_params {
@@ -567,7 +566,6 @@
 #define gadget_for_each_ep(tmp, gadget) \
 	list_for_each_entry(tmp, &(gadget)->ep_list, ep_list)
 
-
 /**
  * gadget_is_dualspeed - return true iff the hardware handles high speed
  * @g: controller that might support both high and full speeds
@@ -769,7 +767,6 @@
 	return gadget->ops->pullup(gadget, 0);
 }
 
-
 /*-------------------------------------------------------------------------*/
 
 /**
@@ -856,7 +853,6 @@
 	void			(*reset)(struct usb_gadget *);
 };
 
-
 /*-------------------------------------------------------------------------*/
 
 /* driver modules register and unregister, as usual.
diff --git a/include/linux/usb/musb.h b/include/linux/usb/musb.h
index a31ce67..2083cbe 100644
--- a/include/linux/usb/musb.h
+++ b/include/linux/usb/musb.h
@@ -128,7 +128,6 @@
 	const void	*platform_ops;
 };
 
-
 /* TUSB 6010 support */
 
 #define	TUSB6010_OSCCLK_60	16667	/* psec/clk @ 60.0 MHz */
diff --git a/include/linux/zstd_errors.h b/include/linux/zstd_errors.h
index 58b6dd4..edba6e1 100644
--- a/include/linux/zstd_errors.h
+++ b/include/linux/zstd_errors.h
@@ -11,11 +11,9 @@
 #ifndef ZSTD_ERRORS_H_398273423
 #define ZSTD_ERRORS_H_398273423
 
-
 /*===== dependency =====*/
 #include <linux/types.h>   /* size_t */
 
-
 /* =====   ZSTDERRORLIB_API : control library symbols visibility   ===== */
 #define ZSTDERRORLIB_VISIBILITY 
 #define ZSTDERRORLIB_API ZSTDERRORLIB_VISIBILITY
@@ -72,6 +70,4 @@
 ZSTDERRORLIB_API ZSTD_ErrorCode ZSTD_getErrorCode(size_t functionResult);
 ZSTDERRORLIB_API const char* ZSTD_getErrorString(ZSTD_ErrorCode code);   /*< Same as ZSTD_getErrorName, but using a `ZSTD_ErrorCode` enum argument */
 
-
-
 #endif /* ZSTD_ERRORS_H_398273423 */
diff --git a/include/linux/zstd_lib.h b/include/linux/zstd_lib.h
index 25f5907..a4d559c 100644
--- a/include/linux/zstd_lib.h
+++ b/include/linux/zstd_lib.h
@@ -14,7 +14,6 @@
 /* ======   Dependency   ======*/
 #include <linux/types.h>   /* size_t */
 
-
 /* =====   ZSTDLIB_API : control library symbols visibility   ===== */
 #ifndef ZSTDLIB_VISIBLE
 #  if (__GNUC__ >= 4) && !defined(__MINGW32__)
@@ -27,7 +26,6 @@
 #endif
 #define ZSTDLIB_API ZSTDLIB_VISIBLE
 
-
 /* *****************************************************************************
   Introduction
 
@@ -100,7 +98,6 @@
 #define ZSTD_BLOCKSIZELOG_MAX  17
 #define ZSTD_BLOCKSIZE_MAX     (1<<ZSTD_BLOCKSIZELOG_MAX)
 
-
 /* *************************************
 *  Simple API
 ***************************************/
@@ -165,7 +162,6 @@
  *        or an error code if input is invalid */
 ZSTDLIB_API size_t ZSTD_findFrameCompressedSize(const void* src, size_t srcSize);
 
-
 /*======  Helper functions  ======*/
 #define ZSTD_COMPRESSBOUND(srcSize)   ((srcSize) + ((srcSize)>>8) + (((srcSize) < (128<<10)) ? (((128<<10) - (srcSize)) >> 11) /* margin, from 64 to 0 */ : 0))  /* this formula ensures that bound(A) + bound(B) <= bound(A+B) as long as A and B >= 128 KB */
 ZSTDLIB_API size_t      ZSTD_compressBound(size_t srcSize); /*!< maximum compressed size in worst case single-pass scenario */
@@ -175,7 +171,6 @@
 ZSTDLIB_API int         ZSTD_maxCLevel(void);               /*!< maximum compression level available */
 ZSTDLIB_API int         ZSTD_defaultCLevel(void);           /*!< default compression level, specified by ZSTD_CLEVEL_DEFAULT, requires v1.5.0+ */
 
-
 /* *************************************
 *  Explicit context
 ***************************************/
@@ -225,7 +220,6 @@
                                        void* dst, size_t dstCapacity,
                                  const void* src, size_t srcSize);
 
-
 /* *******************************************
 *  Advanced compression API (Requires v1.4.0+)
 **********************************************/
@@ -243,7 +237,6 @@
  *   In the future, we expect to remove from experimental API entry points which are redundant with this API.
  */
 
-
 /* Compression strategies, listed from fastest to strongest */
 typedef enum { ZSTD_fast=1,
                ZSTD_dfast=2,
@@ -513,7 +506,6 @@
                                    void* dst, size_t dstCapacity,
                              const void* src, size_t srcSize);
 
-
 /* *********************************************
 *  Advanced decompression API (Requires v1.4.0+)
 ************************************************/
@@ -578,7 +570,6 @@
  */
 ZSTDLIB_API size_t ZSTD_DCtx_reset(ZSTD_DCtx* dctx, ZSTD_ResetDirective reset);
 
-
 /* **************************
 *  Streaming
 ****************************/
@@ -595,8 +586,6 @@
   size_t pos;         /*< position where writing stopped. Will be updated. Necessarily 0 <= pos <= size */
 } ZSTD_outBuffer;
 
-
-
 /*-***********************************************************************
 *  Streaming compression - HowTo
 *
@@ -705,7 +694,6 @@
                                          ZSTD_inBuffer* input,
                                          ZSTD_EndDirective endOp);
 
-
 /* These buffer sizes are softly recommended.
  * They are not required : ZSTD_compressStream*() happily accepts any buffer size, for both input and output.
  * Respecting the recommended size just makes it a bit easier for ZSTD_compressStream*(),
@@ -722,7 +710,6 @@
 ZSTDLIB_API size_t ZSTD_CStreamInSize(void);    /*< recommended size for input buffer */
 ZSTDLIB_API size_t ZSTD_CStreamOutSize(void);   /*< recommended size for output buffer. Guarantee to successfully flush at least one complete compressed block. */
 
-
 /* *****************************************************************************
  * This following is a legacy streaming API, available since v1.0+ .
  * It can be replaced by ZSTD_CCtx_reset() and ZSTD_compressStream2().
@@ -751,7 +738,6 @@
 /*! Equivalent to ZSTD_compressStream2(zcs, output, &emptyInput, ZSTD_e_end). */
 ZSTDLIB_API size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
 
-
 /*-***************************************************************************
 *  Streaming decompression - HowTo
 *
@@ -799,7 +785,6 @@
 ZSTDLIB_API size_t ZSTD_DStreamInSize(void);    /*!< recommended size for input buffer */
 ZSTDLIB_API size_t ZSTD_DStreamOutSize(void);   /*!< recommended size for output buffer. Guarantee to successfully flush at least one complete block in all circumstances. */
 
-
 /* ************************
 *  Simple dictionary API
 ***************************/
@@ -827,7 +812,6 @@
                                        const void* src, size_t srcSize,
                                        const void* dict,size_t dictSize);
 
-
 /* *********************************
  *  Bulk processing dictionary API
  **********************************/
@@ -863,7 +847,6 @@
                                       const void* src, size_t srcSize,
                                       const ZSTD_CDict* cdict);
 
-
 typedef struct ZSTD_DDict_s ZSTD_DDict;
 
 /*! ZSTD_createDDict() :
@@ -884,7 +867,6 @@
                                         const void* src, size_t srcSize,
                                         const ZSTD_DDict* ddict);
 
-
 /* ******************************
  *  Dictionary helper functions
  *******************************/
@@ -919,7 +901,6 @@
  *  When identifying the exact failure cause, it's possible to use ZSTD_getFrameHeader(), which will provide a more precise error code. */
 ZSTDLIB_API unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize);
 
-
 /* *****************************************************************************
  * Advanced dictionary and prefix API (Requires v1.4.0+)
  *
@@ -929,7 +910,6 @@
  * ZSTD_reset_session_and_parameters. Prefixes are single-use.
  ******************************************************************************/
 
-
 /*! ZSTD_CCtx_loadDictionary() : Requires v1.4.0+
  *  Create an internal CDict from `dict` buffer.
  *  Decompression will have to use same dictionary.
@@ -1052,7 +1032,6 @@
 
 #endif  /* ZSTD_H_235446 */
 
-
 /* **************************************************************************************
  *   ADVANCED AND EXPERIMENTAL FUNCTIONS
  ****************************************************************************************
@@ -1123,7 +1102,6 @@
 #define ZSTD_STRATEGY_MIN        ZSTD_fast
 #define ZSTD_STRATEGY_MAX        ZSTD_btultra2
 
-
 #define ZSTD_OVERLAPLOG_MIN       0
 #define ZSTD_OVERLAPLOG_MAX       9
 
@@ -1133,7 +1111,6 @@
                                            * This limit can be overridden using ZSTD_DCtx_setParameter(,ZSTD_d_windowLogMax,).
                                            * The limit does not apply for one-pass decoders (such as ZSTD_decompress()), since no additional memory is allocated */
 
-
 /* LDM parameter bounds */
 #define ZSTD_LDM_HASHLOG_MIN      ZSTD_HASHLOG_MIN
 #define ZSTD_LDM_HASHLOG_MAX      ZSTD_HASHLOG_MAX
@@ -1149,7 +1126,6 @@
 #define ZSTD_TARGETCBLOCKSIZE_MAX   ZSTD_BLOCKSIZE_MAX
 #define ZSTD_SRCSIZEHINT_MIN        0
 
-
 /* ---  Advanced types  --- */
 
 typedef struct ZSTD_CCtx_params_s ZSTD_CCtx_params;
@@ -1417,7 +1393,6 @@
                                   const ZSTD_Sequence* inSeqs, size_t inSeqsSize,
                                   const void* src, size_t srcSize);
 
-
 /*! ZSTD_writeSkippableFrame() :
  * Generates a zstd skippable frame containing data given by src, and writes it to dst buffer.
  *
@@ -1453,8 +1428,6 @@
  */
 ZSTDLIB_API unsigned ZSTD_isSkippableFrame(const void* buffer, size_t size);
 
-
-
 /* *************************************
 *  Memory management
 ***************************************/
@@ -1555,7 +1528,6 @@
                                         ZSTD_dictLoadMethod_e dictLoadMethod,
                                         ZSTD_dictContentType_e dictContentType);
 
-
 /*! Custom memory allocation :
  *  These prototypes make it possible to pass your own allocation/free functions.
  *  ZSTD_customMem is provided at creation time, using ZSTD_create*_advanced() variants listed below.
@@ -1594,7 +1566,6 @@
 ZSTDLIB_STATIC_API void ZSTD_freeThreadPool (ZSTD_threadPool* pool);  /* accept NULL pointer */
 ZSTDLIB_STATIC_API size_t ZSTD_CCtx_refThreadPool(ZSTD_CCtx* cctx, ZSTD_threadPool* pool);
 
-
 /*
  * This API is temporary and is expected to change or disappear in the future!
  */
@@ -1611,7 +1582,6 @@
     ZSTD_dictContentType_e dictContentType,
     ZSTD_customMem customMem);
 
-
 /* *************************************
 *  Advanced compression functions
 ***************************************/
@@ -1669,7 +1639,6 @@
                                         const ZSTD_CDict* cdict,
                                               ZSTD_frameParameters fParams);
 
-
 /*! ZSTD_CCtx_loadDictionary_byReference() :
  *  Same as ZSTD_CCtx_loadDictionary(), but dictionary content is referenced, instead of being copied into CCtx.
  *  It saves some memory, but also requires that `dict` outlives its usage within `cctx` */
@@ -1933,7 +1902,6 @@
  */
 ZSTDLIB_STATIC_API size_t ZSTD_CCtx_getParameter(const ZSTD_CCtx* cctx, ZSTD_cParameter param, int* value);
 
-
 /*! ZSTD_CCtx_params :
  *  Quick howto :
  *  - ZSTD_createCCtxParams() : Create a ZSTD_CCtx_params structure
@@ -2010,7 +1978,6 @@
                       const void* src, size_t srcSize, size_t* srcPos,
                             ZSTD_EndDirective endOp);
 
-
 /* *************************************
 *  Advanced decompression functions
 ***************************************/
@@ -2135,7 +2102,6 @@
  */
 #define ZSTD_d_refMultipleDDicts ZSTD_d_experimentalParam4
 
-
 /*! ZSTD_DCtx_setFormat() :
  *  This function is REDUNDANT. Prefer ZSTD_DCtx_setParameter().
  *  Instruct the decoder context about what kind of data to decode next.
@@ -2156,7 +2122,6 @@
                             void* dst, size_t dstCapacity, size_t* dstPos,
                       const void* src, size_t srcSize, size_t* srcPos);
 
-
 /* ******************************************************************
 *  Advanced streaming functions
 *  Warning : most of these functions are now redundant with the Advanced API.
@@ -2274,7 +2239,6 @@
 ZSTD_DEPRECATED("use ZSTD_CCtx_reset, see zstd.h for detailed instructions")
 size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize);
 
-
 typedef struct {
     unsigned long long ingested;   /* nb input bytes read and buffered */
     unsigned long long consumed;   /* nb input bytes actually compressed */
@@ -2307,7 +2271,6 @@
  */
 ZSTDLIB_STATIC_API size_t ZSTD_toFlushNow(ZSTD_CCtx* cctx);
 
-
 /*=====   Advanced Streaming decompression functions  =====*/
 
 /*!
@@ -2342,7 +2305,6 @@
  */
 ZSTDLIB_STATIC_API size_t ZSTD_resetDStream(ZSTD_DStream* zds);
 
-
 /* *******************************************************************
 *  Buffer-less and synchronous inner streaming functions
 *
@@ -2504,9 +2466,6 @@
 typedef enum { ZSTDnit_frameHeader, ZSTDnit_blockHeader, ZSTDnit_block, ZSTDnit_lastBlock, ZSTDnit_checksum, ZSTDnit_skippableFrame } ZSTD_nextInputType_e;
 ZSTDLIB_STATIC_API ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx);
 
-
-
-
 /* ============================ */
 /*       Block level API       */
 /* ============================ */
@@ -2544,6 +2503,5 @@
 ZSTDLIB_STATIC_API size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
 ZSTDLIB_STATIC_API size_t ZSTD_insertBlock    (ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize);  /*< insert uncompressed block into `dctx` history. Useful for multi-blocks decompression. */
 
-
 #endif   /* ZSTD_H_ZSTD_STATIC_LINKING_ONLY */
 
diff --git a/include/malloc.h b/include/malloc.h
index 161ccbd..07d3e90 100644
--- a/include/malloc.h
+++ b/include/malloc.h
@@ -213,7 +213,6 @@
      quickly avoid procedure declaration conflicts and linker symbol
      conflicts with existing memory allocation routines.
 
-
 */
 
 
@@ -256,12 +255,10 @@
 #include <stdio.h>	/* needed for malloc_stats */
 #endif
 
-
 /*
   Compile-time options
 */
 
-
 /*
     Debugging:
 
@@ -306,10 +303,8 @@
   returns a unique pointer for malloc(0), so does realloc(p, 0).
 */
 
-
 /*   #define REALLOC_ZERO_BYTES_FREES */
 
-
 /*
   WIN32 causes an emulation of sbrk to be compiled in
   mmap-based options are not currently supported in WIN32.
@@ -335,7 +330,6 @@
 #include <windows.h>
 #endif
 
-
 /*
   HAVE_MEMCPY should be defined if you are not otherwise using
   ANSI STD C, but still have memcpy and memset in your C library
@@ -460,7 +454,6 @@
 
 #endif
 
-
 /*
   Define HAVE_MMAP to optionally make malloc() use mmap() to
   allocate very large blocks.  These will be returned to the
@@ -563,7 +556,6 @@
 #  endif
 #endif
 
-
 /*
 
   This version of malloc supports the standard SVID/XPG mallinfo
@@ -626,7 +618,6 @@
 #define M_MMAP_THRESHOLD    -3
 #define M_MMAP_MAX          -4
 
-
 #ifndef DEFAULT_TRIM_THRESHOLD
 #define DEFAULT_TRIM_THRESHOLD (128 * 1024)
 #endif
@@ -677,10 +668,8 @@
       It must be greater than page size to have any useful effect.  To
       disable trimming completely, you can set to (unsigned long)(-1);
 
-
 */
 
-
 #ifndef DEFAULT_TOP_PAD
 #define DEFAULT_TOP_PAD        (0)
 #endif
@@ -713,7 +702,6 @@
 
 */
 
-
 #ifndef DEFAULT_MMAP_THRESHOLD
 #define DEFAULT_MMAP_THRESHOLD (128 * 1024)
 #endif
@@ -753,10 +741,8 @@
       All together, these considerations should lead you to use mmap
       only for relatively large requests.
 
-
 */
 
-
 #ifndef DEFAULT_MMAP_MAX
 #ifdef HAVE_MMAP
 #define DEFAULT_MMAP_MAX       (64)
@@ -784,7 +770,6 @@
       in mallopt will fail.
 */
 
-
 /*
     USE_DL_PREFIX will prefix all public routines with the string 'dl'.
       Useful to quickly avoid procedure declaration conflicts and linker
@@ -815,7 +800,6 @@
 
 */
 
-
 #ifdef INTERNAL_LINUX_C_LIB
 
 #if __STD_C
diff --git a/include/mc13892.h b/include/mc13892.h
index 8e8b63e..d9ef53b 100644
--- a/include/mc13892.h
+++ b/include/mc13892.h
@@ -6,7 +6,6 @@
  * (C) Copyright 2009 Freescale Semiconductor, Inc.
  */
 
-
 #ifndef __MC13892_H__
 #define __MC13892_H__
 
diff --git a/include/micrel.h b/include/micrel.h
index a2593c5..6294bff 100644
--- a/include/micrel.h
+++ b/include/micrel.h
@@ -32,7 +32,6 @@
 #define PHY_ID_KSZ9031				0x00221620
 #define PHY_ID_KSZ9131				0x00221640
 
-
 /* Registers */
 #define MMD_ACCESS_CONTROL	0xd
 #define MMD_ACCESS_REG_DATA	0xe
diff --git a/include/mmc.h b/include/mmc.h
index 7f19003..155a8e9 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -73,7 +73,6 @@
 #define MMC_MODE_1BIT		BIT(28)
 #define MMC_MODE_SPI		BIT(27)
 
-
 #define SD_DATA_4BIT	0x00040000
 
 #define IS_SD(x)	((x)->version & SD_VERSION_SD)
@@ -113,7 +112,6 @@
 #define MMC_CMD62_ARG1			0xefac62ec
 #define MMC_CMD62_ARG2			0xcbaea7
 
-
 #define SD_CMD_SEND_RELATIVE_ADDR	3
 #define SD_CMD_SWITCH_FUNC		6
 #define SD_CMD_SEND_IF_COND		8
diff --git a/include/mpc8xx.h b/include/mpc8xx.h
index 0e0e0cb..53e0be3 100644
--- a/include/mpc8xx.h
+++ b/include/mpc8xx.h
@@ -13,7 +13,6 @@
 #ifndef __MPCXX_H__
 #define __MPCXX_H__
 
-
 /*-----------------------------------------------------------------------
  * Exception offsets (PowerPC standard)
  */
@@ -200,7 +199,6 @@
 #define SCCR_DFALCD10	0x00000002	/* Division by 5			*/
 #define SCCR_DFALCD11	0x00000003	/* Division by 7 (maximum)		*/
 
-
 /*-----------------------------------------------------------------------
  * BR - Memory Controler: Base Register					16-9
  */
@@ -253,7 +251,6 @@
 #define OR_TRLX		0x00000004	/* Timing Relaxed			*/
 #define OR_EHTR		0x00000002	/* Extended Hold Time on Read		*/
 
-
 /*-----------------------------------------------------------------------
  * MPTPR - Memory Periodic Timer Prescaler Register			16-17
  */
@@ -464,7 +461,6 @@
 #define TGCR_STP1	0x0002		/* Stop timer	1		*/
 #define TGCR_RST1	0x0001		/* Reset timer	1		*/
 
-
 /*-----------------------------------------------------------------------
  * Timer Mode Register							18-9
  */
@@ -485,7 +481,6 @@
 #define TMR_ICLK_TIN_PIN	0x0006	/* TINx pin				*/
 #define TMR_GE			0x0001	/* Gate Enable				*/
 
-
 /*-----------------------------------------------------------------------
  * I2C Controller Registers
  */
diff --git a/include/mtd/ubi-user.h b/include/mtd/ubi-user.h
index 8d472cc..cc95fa2 100644
--- a/include/mtd/ubi-user.h
+++ b/include/mtd/ubi-user.h
@@ -421,7 +421,6 @@
 	__s8  padding[3];
 } __packed;
 
-
 /**
  * struct ubi_set_vol_prop_req - a data structure used to set an UBI volume
  *                               property.
diff --git a/include/mv88e6352.h b/include/mv88e6352.h
index 152a077..4de9dbd 100644
--- a/include/mv88e6352.h
+++ b/include/mv88e6352.h
@@ -7,7 +7,6 @@
 #ifndef __MV886352_H
 #define __MV886352_H
 
-
 /* PHY registers */
 #define PHY(itf)	(itf)
 
diff --git a/include/nand.h b/include/nand.h
index cdba738..3a0ef6a 100644
--- a/include/nand.h
+++ b/include/nand.h
@@ -58,7 +58,6 @@
 	return mtd_erase(info, &instr);
 }
 
-
 /*****************************************************************************
  * declarations from nand_util.c
  ****************************************************************************/
diff --git a/include/net.h b/include/net.h
index ac511ea..bb2ae20 100644
--- a/include/net.h
+++ b/include/net.h
@@ -225,7 +225,6 @@
 int eth_env_set_enetaddr_by_index(const char *base_name, int index,
 				 uchar *enetaddr);
 
-
 /*
  * Initialize USB ethernet device with CONFIG_DM_ETH
  * Returns:
diff --git a/include/net/sntp.h b/include/net/sntp.h
index 30b44d1..5dd9aa3 100644
--- a/include/net/sntp.h
+++ b/include/net/sntp.h
@@ -9,7 +9,6 @@
 #define NTP_SERVICE_PORT	123
 #define SNTP_PACKET_LEN		48
 
-
 /* Leap Indicator */
 #define NTP_LI_NOLEAP		0x0
 #define NTP_LI_61SECS		0x1
diff --git a/include/part.h b/include/part.h
index 32ee404..b187ec4 100644
--- a/include/part.h
+++ b/include/part.h
@@ -609,7 +609,6 @@
 			  struct disk_partition *partitions, int parts,
 			  gpt_header *gpt_head, gpt_entry **gpt_pte);
 
-
 /**
  * get_disk_guid() - Read the GUID string from a device's GPT
  *
diff --git a/include/pci.h b/include/pci.h
index ea3b739..5fea815 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -272,7 +272,6 @@
 #define  PCI_X_CMD_MAX_SPLIT    0x0030  /* Max Outstanding Split Transactions */
 #define  PCI_X_CMD_VERSION(x)   (((x) >> 12) & 3) /* Version */
 
-
 /* Slot Identification */
 
 #define PCI_SID_ESR		2	/* Expansion Slot Register */
diff --git a/include/pci_gt64120.h b/include/pci_gt64120.h
index c9fb9fa..f06e86b 100644
--- a/include/pci_gt64120.h
+++ b/include/pci_gt64120.h
@@ -12,5 +12,4 @@
 		     unsigned long io_bus, unsigned long io_phys,
 		     unsigned long io_size);
 
-
 #endif /* _PCI_GT64120_H */
diff --git a/include/pci_ids.h b/include/pci_ids.h
index 6f09544..191d277 100644
--- a/include/pci_ids.h
+++ b/include/pci_ids.h
@@ -1535,7 +1535,6 @@
 #define PCI_VENDOR_ID_ZIATECH		0x1138
 #define PCI_DEVICE_ID_ZIATECH_5550_HC	0x5550
 
-
 #define PCI_VENDOR_ID_SYSKONNECT	0x1148
 #define PCI_DEVICE_ID_SYSKONNECT_TR	0x4200
 #define PCI_DEVICE_ID_SYSKONNECT_GE	0x4300
diff --git a/include/power/max17042_fg.h b/include/power/max17042_fg.h
index ec8377d..e417012 100644
--- a/include/power/max17042_fg.h
+++ b/include/power/max17042_fg.h
@@ -43,7 +43,6 @@
 #define RCOMP0			0x0060
 #define TempCo			0x1015
 
-
 #define MAX17042_POR (1 << 1)
 
 #define MODEL_UNLOCK1		0x0059
diff --git a/include/power/tps65910.h b/include/power/tps65910.h
index ccc759a..645eabc 100644
--- a/include/power/tps65910.h
+++ b/include/power/tps65910.h
@@ -51,7 +51,6 @@
 #define TPS65910_REG_ST_OFF_1				(0x2)
 #define TPS65910_REG_ST_ON_LOW_POW			(0x3)
 
-
 /* VDD2 & VDD1 voltage selection register. (VDD2_OP_REG & VDD1_OP_REG) */
 #define TPS65910_OP_REG_SEL				(0x7F)
 
diff --git a/include/scsi.h b/include/scsi.h
index cf756aa..b18ae37 100644
--- a/include/scsi.h
+++ b/include/scsi.h
@@ -95,7 +95,6 @@
 #define	M_X_WIDE_REQ	(0x03)
 #define	M_X_PPR_REQ	(0x04)
 
-
 /*
 **	Status
 */
@@ -131,7 +130,6 @@
 #define SENSE_VOLUME_OVERFLOW	0xD
 #define SENSE_MISCOMPARE			0xE
 
-
 #define SCSI_CHANGE_DEF	0x40		/* Change Definition (Optional) */
 #define SCSI_COMPARE		0x39		/* Compare (O) */
 #define SCSI_COPY			0x18		/* Copy (O) */
diff --git a/include/smbios.h b/include/smbios.h
index a4fda9d..00119d7 100644
--- a/include/smbios.h
+++ b/include/smbios.h
@@ -105,6 +105,7 @@
 	u8 bios_minor_release;
 	u8 ec_major_release;
 	u8 ec_minor_release;
+	u16 extended_bios_rom_size;
 	char eos[SMBIOS_STRUCT_EOS_BYTES];
 };
 
diff --git a/include/spd.h b/include/spd.h
index 2bcf46d..8b24a1e 100644
--- a/include/spd.h
+++ b/include/spd.h
@@ -77,7 +77,6 @@
 	unsigned char intel_cas;   /* 129 Intel spec: CAS# Latency support */
 } spd_eeprom_t;
 
-
 /*
  * Byte 2 Fundamental Memory Types.
  */
diff --git a/include/spl.h b/include/spl.h
index 5dfdf77..1eebea3 100644
--- a/include/spl.h
+++ b/include/spl.h
@@ -436,7 +436,6 @@
 			struct spl_load_info *load, ulong offset,
 			struct legacy_img_hdr *hdr);
 
-
 /**
  * spl_load_imx_container() - Loads a imx container image from a device.
  * @spl_image:	Image description to set up
diff --git a/include/tegra-kbc.h b/include/tegra-kbc.h
index 1208b75..316e6b1 100644
--- a/include/tegra-kbc.h
+++ b/include/tegra-kbc.h
@@ -7,7 +7,6 @@
 #ifndef __include_tegra_kbc_h__
 #define __include_tegra_kbc_h__
 
-
 #define KEY_IS_MODIFIER(key) ((key) >= KEY_FIRST_MODIFIER)
 
 struct kbc_tegra {
diff --git a/include/u-boot/sha512.h b/include/u-boot/sha512.h
index 90bd96a..83c2119 100644
--- a/include/u-boot/sha512.h
+++ b/include/u-boot/sha512.h
@@ -36,5 +36,4 @@
 void sha384_csum_wd(const unsigned char *input, unsigned int ilen,
 		unsigned char *output, unsigned int chunk_sz);
 
-
 #endif /* _SHA512_H */
diff --git a/include/u-boot/zlib.h b/include/u-boot/zlib.h
index ee19f46..dac5654 100644
--- a/include/u-boot/zlib.h
+++ b/include/u-boot/zlib.h
@@ -36,7 +36,6 @@
   Jean-loup Gailly        Mark Adler
   jloup@gzip.org          madler@alumni.caltech.edu
 
-
   The data format used by the zlib library is described by RFCs (Request for
   Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
   (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
@@ -547,7 +546,6 @@
 ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
 			z_streamp source));
 
-
 ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
 			int stream_size));
 ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
diff --git a/include/usb.h b/include/usb.h
index 3aafdc8..fcbe214 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -274,7 +274,6 @@
 int usb_stop(void); /* stop the USB Controller */
 int usb_detect_change(void); /* detect if a USB device has been (un)plugged */
 
-
 int usb_set_protocol(struct usb_device *dev, int ifnum, int protocol);
 int usb_set_idle(struct usb_device *dev, int ifnum, int duration,
 			int report_id);
@@ -600,7 +599,6 @@
 	} u;
 } __attribute__ ((packed));
 
-
 struct usb_hub_device {
 	struct usb_device *pusb_dev;
 	struct usb_hub_descriptor desc;
diff --git a/include/usb/ci_udc.h b/include/usb/ci_udc.h
index 06adb2b..9f15dba 100644
--- a/include/usb/ci_udc.h
+++ b/include/usb/ci_udc.h
@@ -4,7 +4,6 @@
  * Lei Wen <leiwen@marvell.com>
  */
 
-
 #ifndef __CI_UDC_H__
 #define __CI_UDC_H__
 
diff --git a/include/usb/ulpi.h b/include/usb/ulpi.h
index 126623c..10e3122 100644
--- a/include/usb/ulpi.h
+++ b/include/usb/ulpi.h
@@ -116,7 +116,6 @@
  */
 int ulpi_reset(struct ulpi_viewport *ulpi_vp);
 
-
 /* ULPI access methods below must be implemented for each ULPI viewport. */
 
 /*
@@ -314,5 +313,4 @@
 #define ULPI_CARKIT_PLS_CTRL_SPKRLEFT_BIASEN	(1 << 2)
 #define ULPI_CARKIT_PLS_CTRL_SPKRRIGHT_BIASEN	(1 << 3)
 
-
 #endif /* __USB_ULPI_H__ */
diff --git a/include/usb/xhci.h b/include/usb/xhci.h
index 04d16a2..5fcdae1 100644
--- a/include/usb/xhci.h
+++ b/include/usb/xhci.h
@@ -682,7 +682,6 @@
 	__le32	rsvd2[6];
 };
 
-
 /**
  * struct xhci_device_context_array
  * @dev_context_ptr	array of 64-bit DMA addresses for device contexts
@@ -699,7 +698,6 @@
  * might not be able to handle the maximum number of devices possible.
  */
 
-
 struct xhci_transfer_event {
 	/* 64-bit buffer address, or immediate data */
 	__le64	buffer;
@@ -835,7 +833,6 @@
 #define TRB_TO_STREAM_ID(p)		((((p) & (0xffff << 16)) >> 16))
 #define STREAM_ID_FOR_TRB(p)		((((p)) & 0xffff) << 16)
 
-
 /* Port Status Change Event TRB fields */
 /* Port ID - bits 31:24 */
 #define GET_PORT_ID(p)			(((p) & (0xff << 24)) >> 24)
@@ -1134,7 +1131,6 @@
 					struct xhci_hcor **ret_hcor);
 void xhci_hcd_stop(int index);
 
-
 /*************************************************************
 	EXTENDED CAPABILITY DEFINITIONS
 *************************************************************/
diff --git a/include/usb_defs.h b/include/usb_defs.h
index ec00161..28757c8 100644
--- a/include/usb_defs.h
+++ b/include/usb_defs.h
@@ -30,7 +30,6 @@
 #define USB_PROT_HID_KEYBOARD   1
 #define USB_PROT_HID_MOUSE      2
 
-
 /* Sub STORAGE Classes */
 #define US_SC_RBC              1		/* Typically, flash devices */
 #define US_SC_8020             2		/* CD-ROM */
@@ -190,7 +189,6 @@
 #define USB_TEST_MODE_PACKET        0x04
 #define USB_TEST_MODE_FORCE_ENABLE  0x05
 
-
 /*
  * "pipe" definitions, use unsigned so we can compare reliably, since this
  * value is shifted up to bits 30/31.
@@ -225,7 +223,6 @@
 #define USB_ST_BIT_ERR          0x40	/* Bitstuff error */
 #define USB_ST_NOT_PROC         0x80000000L	/* Not yet processed */
 
-
 /*************************************************************************
  * Hub defines
  */
diff --git a/include/usbdescriptors.h b/include/usbdescriptors.h
index 641b4a3..db1d6ef 100644
--- a/include/usbdescriptors.h
+++ b/include/usbdescriptors.h
@@ -58,7 +58,6 @@
  *
  */
 
-
 #ifndef __USBDESCRIPTORS_H__
 #define __USBDESCRIPTORS_H__
 
@@ -111,7 +110,6 @@
 /* c.f. CDC 4.7 Table 19 */
 #define DATA_INTERFACE_PROTOCOL_NONE	0x00	/* No class protcol required */
 
-
 /* c.f. CDC 5.2.3 Table 24 */
 #define CS_INTERFACE		0x24
 #define CS_ENDPOINT			0x25
@@ -168,7 +166,6 @@
 #define BULK		0x02
 #define INTERRUPT	0x03
 
-
 /* configuration modifiers
  */
 #define BMATTRIBUTE_RESERVED		0x80
@@ -239,7 +236,6 @@
 	u8 bDescriptorSubtype;
 } __attribute__ ((packed));
 
-
 /*
  * communications class descriptor structures
  *
@@ -319,7 +315,6 @@
 	u16 wCountryCode0[0];
 } __attribute__ ((packed));
 
-
 struct usb_class_telephone_operational_descriptor {
 	u8 bFunctionLength;
 	u8 bDescriptorType;
@@ -327,7 +322,6 @@
 	u8 bmCapabilities;
 } __attribute__ ((packed));
 
-
 struct usb_class_usb_terminal_descriptor {
 	u8 bFunctionLength;
 	u8 bDescriptorType;
@@ -405,7 +399,6 @@
 	u16 wMaxVC;
 } __attribute__ ((packed));
 
-
 struct usb_class_mdlm_descriptor {
 	u8 bFunctionLength;
 	u8 bDescriptorType;
diff --git a/include/usbdevice.h b/include/usbdevice.h
index e59f558..d173c1c 100644
--- a/include/usbdevice.h
+++ b/include/usbdevice.h
@@ -19,10 +19,8 @@
 
 #include "usbdescriptors.h"
 
-
 #define MAX_URBS_QUEUED 5
 
-
 #if 1
 #define usberr(fmt,args...) serial_printf("ERROR: %s(), %d: "fmt"\n",__FUNCTION__,__LINE__,##args)
 #else
@@ -269,14 +267,12 @@
 #define USB_REQ_SET_IDLE		0x0A
 #define USB_REQ_SET_PROTOCOL		0x0B
 
-
 /*
  * USB Spec Release number
  */
 
 #define USB_BCD_VERSION			0x0110
 
-
 /*
  * Device Requests	(c.f Table 9-2)
  */
@@ -328,7 +324,6 @@
 #define USB_DEVICE_REMOTE_WAKEUP	0x01
 #define USB_TEST_MODE			0x02
 
-
 /* USB Requests
  *
  */
@@ -341,7 +336,6 @@
 	u16 wLength;
 } __attribute__ ((packed));
 
-
 /* USB Status
  *
  */
@@ -425,7 +419,6 @@
 
 } usb_device_event_t;
 
-
 typedef struct urb_link {
 	struct urb_link *next;
 	struct urb_link *prev;
@@ -519,7 +512,6 @@
 	struct usb_interface_instance *interface_instance_array;
 };
 
-
 /* USB Device Instance
  *
  * For each physical bus interface we create a logical device structure. This
diff --git a/include/valgrind/memcheck.h b/include/valgrind/memcheck.h
index 501cb14..4e5127a 100644
--- a/include/valgrind/memcheck.h
+++ b/include/valgrind/memcheck.h
@@ -9,7 +9,6 @@
 #ifndef __MEMCHECK_H
 #define __MEMCHECK_H
 
-
 /* This file is for inclusion into client (your!) code.
 
    You can use these macros to manipulate and query memory permissions
@@ -53,8 +52,6 @@
          = VG_USERREQ_TOOL_BASE('M','C') + 256
    } Vg_MemCheckClientRequest;
 
-
-
 /* Client-code macros to manipulate the state of memory. */
 
 /* Mark memory at _qzz_addr as unaddressable for _qzz_len bytes. */
@@ -102,7 +99,6 @@
                             VG_USERREQ__DISCARD,                 \
                             0, (_qzz_blkindex), 0, 0, 0)
 
-
 /* Client-code macros to check the state of memory. */
 
 /* Check that memory at _qzz_addr is addressable for _qzz_len bytes.
@@ -133,7 +129,6 @@
       (volatile unsigned char *)&(__lvalue),                     \
                       (unsigned long)(sizeof (__lvalue)))
 
-
 /* Do a full memory leak check (like --leak-check=full) mid-execution. */
 #define VALGRIND_DO_LEAK_CHECK                                   \
     VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DO_LEAK_CHECK,   \
@@ -202,7 +197,6 @@
     suppressed = _qzz_suppressed;                                        \
    }
 
-
 /* Get the validity data for addresses [zza..zza+zznbytes-1] and copy it
    into the provided zzvbits array.  Return values:
       0   if not running on valgrind
diff --git a/include/valgrind/valgrind.h b/include/valgrind/valgrind.h
index 5d4fa5f..6114c4a 100644
--- a/include/valgrind/valgrind.h
+++ b/include/valgrind/valgrind.h
@@ -24,7 +24,6 @@
 #ifndef __VALGRIND_H
 #define __VALGRIND_H
 
-
 /* ------------------------------------------------------------------ */
 /* VERSION NUMBER OF VALGRIND                                         */
 /* ------------------------------------------------------------------ */
@@ -42,7 +41,6 @@
 #define __VALGRIND_MAJOR__    3
 #define __VALGRIND_MINOR__    16
 
-
 #include <stdarg.h>
 
 /* Nb: this file might be included in a file compiled with -ansi.  So
@@ -77,7 +75,6 @@
 #undef PLAT_x86_solaris
 #undef PLAT_amd64_solaris
 
-
 #if defined(__APPLE__) && defined(__i386__)
 #  define PLAT_x86_darwin 1
 #elif defined(__APPLE__) && defined(__x86_64__)
@@ -126,7 +123,6 @@
 #  endif
 #endif
 
-
 /* ------------------------------------------------------------------ */
 /* ARCHITECTURE SPECIFICS for SPECIAL INSTRUCTIONS.  There is nothing */
 /* in here of use to end-users -- skip to the next section.           */
@@ -928,7 +924,6 @@
                     );                                           \
  } while (0)
 
-
 #endif /* PLAT_mips32_linux */
 
 /* ------------------------- mips64-linux ---------------- */
@@ -1073,7 +1068,6 @@
 
 #endif /* CONFIG_VALGRIND */
 
-
 /* ------------------------------------------------------------------ */
 /* PLATFORM SPECIFICS for FUNCTION WRAPPING.  This is all very        */
 /* ugly.  It's the least-worst tradeoff I can think of.               */
@@ -5168,7 +5162,6 @@
       lval = (__typeof__(lval)) _res;                            \
    } while (0)
 
-
 #endif /* PLAT_s390x_linux */
 
 /* ------------------------- mips32-linux ----------------------- */
@@ -6197,7 +6190,6 @@
       lval = (__typeof__(lval)) (long)_res;                       \
    } while (0)
 
-
 #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
    do {                                                           \
       volatile OrigFn        _orig = (orig);                      \
@@ -6657,7 +6649,6 @@
 #  define __extension__ /* */
 #endif
 
-
 /* Returns the number of Valgrinds this code is running under.  That
    is, 0 if running natively, 1 if running under Valgrind, 2 if
    running under Valgrind which is running under another Valgrind,
@@ -6667,7 +6658,6 @@
                                     VG_USERREQ__RUNNING_ON_VALGRIND,  \
                                     0, 0, 0, 0, 0)                    \
 
-
 /* Discard translation of code in the range [_qzz_addr .. _qzz_addr +
    _qzz_len - 1].  Useful if you are debugging a JITter or some such,
    since it provides a way to make sure valgrind will retranslate the
@@ -6680,7 +6670,6 @@
    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__INNER_THREADS,           \
                                    _qzz_addr, 0, 0, 0, 0)
 
-
 /* These requests are for getting Valgrind itself to print something.
    Possibly with a backtrace.  This is a really ugly hack.  The return value
    is the number of characters printed, excluding the "**<pid>** " part at the
@@ -6766,7 +6755,6 @@
 #endif /* CONFIG_VALGRIND */
 }
 
-
 /* These requests allow control to move from the simulated CPU to the
    real CPU, calling an arbitrary function.
    
@@ -6815,7 +6803,6 @@
                                     _qyy_arg1, _qyy_arg2,               \
                                     _qyy_arg3, 0)
 
-
 /* Counts the number of errors that have been recorded by a tool.  Nb:
    the tool must record the errors with VG_(maybe_record_error)() or
    VG_(unique_error)() for them to be counted. */
@@ -7079,7 +7066,6 @@
    VALGRIND_DO_CLIENT_REQUEST_EXPR(0, VG_USERREQ__GDB_MONITOR_COMMAND, \
                                    command, 0, 0, 0, 0)
 
-
 /* Change the value of a dynamic command line option.
    Note that unknown or not dynamically changeable options
    will cause a warning message to be output.  */
@@ -7087,7 +7073,6 @@
    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CLO_CHANGE, \
                                    option, 0, 0, 0, 0)
 
-
 #undef PLAT_x86_darwin
 #undef PLAT_amd64_darwin
 #undef PLAT_x86_win32
diff --git a/include/video.h b/include/video.h
index 4d8df9b..4013a94 100644
--- a/include/video.h
+++ b/include/video.h
@@ -97,6 +97,7 @@
  *		the LCD is updated
  * @fg_col_idx:	Foreground color code (bit 3 = bold, bit 0-2 = color)
  * @bg_col_idx:	Background color code (bit 3 = bold, bit 0-2 = color)
+ * @last_sync:	Monotonic time of last video sync
  */
 struct video_priv {
 	/* Things set up by the driver: */
@@ -121,6 +122,7 @@
 	bool flush_dcache;
 	u8 fg_col_idx;
 	u8 bg_col_idx;
+	ulong last_sync;
 };
 
 /**
diff --git a/include/xyzModem.h b/include/xyzModem.h
index a8911b6..0de8788 100644
--- a/include/xyzModem.h
+++ b/include/xyzModem.h
@@ -44,7 +44,6 @@
 #define xyzModem_close 1
 #define xyzModem_abort 2
 
-
 #define CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT
 #define CYGACC_CALL_IF_SET_CONSOLE_COMM(x)
 
@@ -60,8 +59,6 @@
     int   chan;
 } connection_info_t;
 
-
-
 int   xyzModem_stream_open(connection_info_t *info, int *err);
 void  xyzModem_stream_close(int *err);
 void  xyzModem_stream_terminate(bool method, int (*getc)(void));
diff --git a/include/zfs/spa.h b/include/zfs/spa.h
index cd2ddf5..df01d49 100644
--- a/include/zfs/spa.h
+++ b/include/zfs/spa.h
@@ -10,7 +10,6 @@
 #ifndef ZFS_SPA_HEADER
 #define	ZFS_SPA_HEADER 1
 
-
 /*
  * General-purpose 32-bit and 64-bit bitfield encodings.
  */
diff --git a/include/zfs/zfs.h b/include/zfs/zfs.h
index 72d8745..8415437 100644
--- a/include/zfs/zfs.h
+++ b/include/zfs/zfs.h
@@ -10,7 +10,6 @@
 #ifndef	GRUB_ZFS_HEADER
 #define	GRUB_ZFS_HEADER 1
 
-
 /*
  * On-disk version number.
  */
diff --git a/include/zfs/zfs_acl.h b/include/zfs/zfs_acl.h
index d6cc408..038c68f 100644
--- a/include/zfs/zfs_acl.h
+++ b/include/zfs/zfs_acl.h
@@ -38,5 +38,4 @@
 	uint8_t	z_ace_data[ZFS_ACE_SPACE]; /* space for embedded ACEs */
 } zfs_znode_acl_t;
 
-
 #endif	/* _SYS_FS_ZFS_ACL_H */
diff --git a/include/zfs_common.h b/include/zfs_common.h
index cb83e59..8b93d68 100644
--- a/include/zfs_common.h
+++ b/include/zfs_common.h
@@ -27,14 +27,12 @@
 #define SECTOR_SIZE			0x200
 #define SECTOR_BITS			9
 
-
 typedef enum zfs_endian {
 	UNKNOWN_ENDIAN = -2,
 	LITTLE_ENDIAN = -1,
 	BIG_ENDIAN = 0
 } zfs_endian_t;
 
-
 /* Endian macros. */
 #define zfs_to_cpu16(x, a) (((a) == BIG_ENDIAN) ? be16_to_cpu(x) \
 								: le16_to_cpu(x))
@@ -51,7 +49,6 @@
 #define cpu_to_zfs64(x, a) (((a) == BIG_ENDIAN) ? cpu_to_be64(x) \
 								: cpu_to_le64(x))
 
-
 enum zfs_errors {
 	ZFS_ERR_NONE = 0,
 	ZFS_ERR_NOT_IMPLEMENTED_YET = -1,
@@ -89,9 +86,6 @@
 	time_t mtime2;
 };
 
-
-
-
 struct zfs_filesystem *zfsget_fs(void);
 int zfs_open(zfs_file_t, const char *filename);
 uint64_t zfs_read(zfs_file_t, char *buf, uint64_t len);
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index 38e64af..1179c31 100644
--- a/lib/efi_loader/Kconfig
+++ b/lib/efi_loader/Kconfig
@@ -220,6 +220,7 @@
 config EFI_IGNORE_OSINDICATIONS
 	bool "Ignore OsIndications for CapsuleUpdate on-disk"
 	depends on EFI_CAPSULE_ON_DISK
+	default y if !EFI_RT_VOLATILE_STORE
 	help
 	  There are boards where U-Boot does not support SetVariable at runtime.
 	  Select this option if you want to use the capsule-on-disk feature
@@ -486,6 +487,7 @@
 
 config EFI_EBBR_2_1_CONFORMANCE
 	bool "Add the EBBRv2.1 conformance entry to the ECPT table"
+	depends on BOOTMETH_EFI_BOOTMGR
 	depends on EFI_ECPT
 	depends on EFI_LOADER_HII
 	depends on EFI_RISCV_BOOT_PROTOCOL || !RISCV
diff --git a/lib/efi_loader/efi_fdt.c b/lib/efi_loader/efi_fdt.c
index 4ccf205..c5ecade 100644
--- a/lib/efi_loader/efi_fdt.c
+++ b/lib/efi_loader/efi_fdt.c
@@ -43,6 +43,9 @@
 	case 2:
 		prefix = "/dtb/current";
 		break;
+	case 3:
+		prefix = "/dtbs";
+		break;
 	default:
 		return log_msg_ret("pref", -EINVAL);
 	}
diff --git a/lib/efi_loader/efi_helper.c b/lib/efi_loader/efi_helper.c
index 348612c..65d2116 100644
--- a/lib/efi_loader/efi_helper.c
+++ b/lib/efi_loader/efi_helper.c
@@ -133,7 +133,7 @@
 
 		*dp = efi_dp_concat(tmp_dp, fdt_dp, *dp_size);
 		efi_free_pool(tmp_dp);
-		if (!dp)
+		if (!*dp)
 			return EFI_OUT_OF_RESOURCES;
 		*dp_size += efi_dp_size(fdt_dp) + sizeof(END);
 	}
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
index 12cf23f..c6f1dd0 100644
--- a/lib/efi_loader/efi_memory.c
+++ b/lib/efi_loader/efi_memory.c
@@ -127,7 +127,7 @@
  */
 static void efi_mem_sort(void)
 {
-	struct list_head *lhandle;
+	struct efi_mem_list *lmem;
 	struct efi_mem_list *prevmem = NULL;
 	bool merge_again = true;
 
@@ -136,19 +136,18 @@
 	/* Now merge entries that can be merged */
 	while (merge_again) {
 		merge_again = false;
-		list_for_each(lhandle, &efi_mem) {
-			struct efi_mem_list *lmem;
-			struct efi_mem_desc *prev = &prevmem->desc;
+		list_for_each_entry(lmem, &efi_mem, link) {
+			struct efi_mem_desc *prev;
 			struct efi_mem_desc *cur;
 			uint64_t pages;
 
-			lmem = list_entry(lhandle, struct efi_mem_list, link);
 			if (!prevmem) {
 				prevmem = lmem;
 				continue;
 			}
 
 			cur = &lmem->desc;
+			prev = &prevmem->desc;
 
 			if ((desc_get_end(cur) == prev->physical_start) &&
 			    (prev->type == cur->type) &&
@@ -268,7 +267,7 @@
 					  int memory_type,
 					  bool overlap_only_ram)
 {
-	struct list_head *lhandle;
+	struct efi_mem_list *lmem;
 	struct efi_mem_list *newlist;
 	bool carve_again;
 	uint64_t carved_pages = 0;
@@ -308,11 +307,9 @@
 	/* Add our new map */
 	do {
 		carve_again = false;
-		list_for_each(lhandle, &efi_mem) {
-			struct efi_mem_list *lmem;
+		list_for_each_entry(lmem, &efi_mem, link) {
 			s64 r;
 
-			lmem = list_entry(lhandle, struct efi_mem_list, link);
 			r = efi_mem_carve_out(lmem, &newlist->desc,
 					      overlap_only_ram);
 			switch (r) {
@@ -444,7 +441,7 @@
  */
 static uint64_t efi_find_free_memory(uint64_t len, uint64_t max_addr)
 {
-	struct list_head *lhandle;
+	struct efi_mem_list *lmem;
 
 	/*
 	 * Prealign input max address, so we simplify our matching
@@ -452,9 +449,7 @@
 	 */
 	max_addr &= ~EFI_PAGE_MASK;
 
-	list_for_each(lhandle, &efi_mem) {
-		struct efi_mem_list *lmem = list_entry(lhandle,
-			struct efi_mem_list, link);
+	list_for_each_entry(lmem, &efi_mem, link) {
 		struct efi_mem_desc *desc = &lmem->desc;
 		uint64_t desc_len = desc->num_pages << EFI_PAGE_SHIFT;
 		uint64_t desc_end = desc->physical_start + desc_len;
@@ -742,9 +737,9 @@
 				efi_uintn_t *descriptor_size,
 				uint32_t *descriptor_version)
 {
+	size_t map_entries;
 	efi_uintn_t map_size = 0;
-	int map_entries = 0;
-	struct list_head *lhandle;
+	struct efi_mem_list *lmem;
 	efi_uintn_t provided_map_size;
 
 	if (!memory_map_size)
@@ -752,8 +747,7 @@
 
 	provided_map_size = *memory_map_size;
 
-	list_for_each(lhandle, &efi_mem)
-		map_entries++;
+	map_entries = list_count_nodes(&efi_mem);
 
 	map_size = map_entries * sizeof(struct efi_mem_desc);
 
@@ -774,10 +768,7 @@
 	/* Copy list into array */
 	/* Return the list in ascending order */
 	memory_map = &memory_map[map_entries - 1];
-	list_for_each(lhandle, &efi_mem) {
-		struct efi_mem_list *lmem;
-
-		lmem = list_entry(lhandle, struct efi_mem_list, link);
+	list_for_each_entry(lmem, &efi_mem, link) {
 		*memory_map = lmem->desc;
 		memory_map--;
 	}
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 5b3b26d..6865f78 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -1668,8 +1668,16 @@
 {
 	int ret = -ENOENT;
 
-	/* If allowing a bloblist, check that first */
-	if (CONFIG_IS_ENABLED(BLOBLIST)) {
+	/*
+	 * If allowing a bloblist, check that first. There was discussion about
+	 * adding an OF_BLOBLIST Kconfig, but this was rejected.
+	 *
+	 * The necessary test is whether the previous phase passed a bloblist,
+	 * not whether this phase creates one.
+	 */
+	if (CONFIG_IS_ENABLED(BLOBLIST) &&
+	    (spl_prev_phase() != PHASE_TPL ||
+	     !IS_ENABLED(CONFIG_TPL_BLOBLIST))) {
 		ret = bloblist_maybe_init();
 		if (!ret) {
 			gd->fdt_blob = bloblist_find(BLOBLISTT_CONTROL_FDT, 0);
diff --git a/lib/smbios.c b/lib/smbios.c
index 4126466..7c24ea1 100644
--- a/lib/smbios.c
+++ b/lib/smbios.c
@@ -22,6 +22,7 @@
 #include <cpu.h>
 #include <dm/uclass-internal.h>
 #endif
+#include <linux/sizes.h>
 
 /* Safeguard for checking that U_BOOT_VERSION_NUM macros are compatible with U_BOOT_DMI */
 #if U_BOOT_VERSION_NUM < 2000 || U_BOOT_VERSION_NUM > 2099 || \
@@ -348,7 +349,13 @@
 #endif
 	t->bios_release_date = smbios_add_prop(ctx, NULL, U_BOOT_DMI_DATE);
 #ifdef CONFIG_ROM_SIZE
-	t->bios_rom_size = (CONFIG_ROM_SIZE / 65536) - 1;
+	if (CONFIG_ROM_SIZE < SZ_16M) {
+		t->bios_rom_size = (CONFIG_ROM_SIZE / 65536) - 1;
+	} else {
+		/* CONFIG_ROM_SIZE < 8 GiB */
+		t->bios_rom_size = 0xff;
+		t->extended_bios_rom_size = CONFIG_ROM_SIZE >> 20;
+	}
 #endif
 	t->bios_characteristics = BIOS_CHARACTERISTICS_PCI_SUPPORTED |
 				  BIOS_CHARACTERISTICS_SELECTABLE_BOOT |
diff --git a/net/eth_internal.h b/net/eth_internal.h
index 0b829a8..cb302c1 100644
--- a/net/eth_internal.h
+++ b/net/eth_internal.h
@@ -11,22 +11,6 @@
 /* Do init that is common to driver model and legacy networking */
 void eth_common_init(void);
 
-/**
- * eth_env_set_enetaddr_by_index() - set the MAC address environment variable
- *
- * This sets up an environment variable with the given MAC address (@enetaddr).
- * The environment variable to be set is defined by <@base_name><@index>addr.
- * If @index is 0 it is omitted. For common Ethernet this means ethaddr,
- * eth1addr, etc.
- *
- * @base_name:	Base name for variable, typically "eth"
- * @index:	Index of interface being updated (>=0)
- * @enetaddr:	Pointer to MAC address to put into the variable
- * Return: 0 if OK, other value on error
- */
-int eth_env_set_enetaddr_by_index(const char *base_name, int index,
-				 uchar *enetaddr);
-
 int eth_mac_skip(int index);
 void eth_current_changed(void);
 void eth_set_dev(struct udevice *dev);
diff --git a/net/tftp.c b/net/tftp.c
index 65c39d7..2e07318 100644
--- a/net/tftp.c
+++ b/net/tftp.c
@@ -493,8 +493,15 @@
 				tftp_prev_block = tftp_cur_block;
 				tftp_cur_block = (unsigned short)(block + 1);
 				update_block_number();
-				if (ack_ok)
+				if (ack_ok) {
+					if (block == 0 &&
+					    tftp_state == STATE_SEND_WRQ){
+						/* connection's first ACK */
+						tftp_state = STATE_DATA;
+						tftp_remote_port = src;
+					}
 					tftp_send(); /* Send next data block */
+				}
 			}
 		}
 #endif
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 97dd4a6..99cc295 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -224,7 +224,7 @@
 		    $(srctree)/scripts/recordmcount.h
 else
 sub_cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \
-	"$(if $(CONFIG_CPU_BIG_ENDIAN),big,little)" \
+	"$(if $(CONFIG_SYS_BIG_ENDIAN),big,little)" \
 	"$(if $(CONFIG_64BIT),64,32)" \
 	"$(OBJDUMP)" "$(OBJCOPY)" "$(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS)" \
 	"$(LD) $(KBUILD_LDFLAGS)" "$(NM)" "$(RM)" "$(MV)" \
diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c
index 5ced0f6..3d40bd7 100644
--- a/scripts/basic/fixdep.c
+++ b/scripts/basic/fixdep.c
@@ -421,6 +421,8 @@
 		strcpy(tmp_buf, "SPL_");
 	else if (!strncmp(target, "tpl/", 4))
 		strcpy(tmp_buf, "TPL_");
+	else if (!strncmp(target, "vpl/", 4))
+		strcpy(tmp_buf, "VPL_");
 	/* end U-Boot hack */
 
 	xprintf("cmd_%s := %s\n\n", target, cmdline);
diff --git a/test/dm/bus.c b/test/dm/bus.c
index a338c7f..95326f2 100644
--- a/test/dm/bus.c
+++ b/test/dm/bus.c
@@ -14,6 +14,7 @@
 #include <dm/test.h>
 #include <dm/uclass-internal.h>
 #include <dm/util.h>
+#include <linux/list.h>
 #include <test/test.h>
 #include <test/ut.h>
 
@@ -27,14 +28,14 @@
 	struct uclass *uc;
 
 	ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc));
-	ut_asserteq(num_devices, list_count_items(&uc->dev_head));
+	ut_asserteq(num_devices, list_count_nodes(&uc->dev_head));
 
 	/* Probe the bus, which should yield 3 more devices */
 	ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
 	num_devices += 3;
 
 	ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc));
-	ut_asserteq(num_devices, list_count_items(&uc->dev_head));
+	ut_asserteq(num_devices, list_count_nodes(&uc->dev_head));
 
 	ut_assert(!dm_check_devices(uts, num_devices));
 
diff --git a/test/dm/core.c b/test/dm/core.c
index dbad1b3..5bc5e8e 100644
--- a/test/dm/core.c
+++ b/test/dm/core.c
@@ -16,6 +16,7 @@
 #include <dm/util.h>
 #include <dm/test.h>
 #include <dm/uclass-internal.h>
+#include <linux/list.h>
 #include <test/test.h>
 #include <test/ut.h>
 
@@ -123,15 +124,15 @@
 	 * device with no children.
 	 */
 	ut_assert(uts->root);
-	ut_asserteq(1, list_count_items(gd->uclass_root));
-	ut_asserteq(0, list_count_items(&gd->dm_root->child_head));
+	ut_asserteq(1, list_count_nodes(gd->uclass_root));
+	ut_asserteq(0, list_count_nodes(&gd->dm_root->child_head));
 	ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_POST_BIND]);
 
 	ut_assertok(dm_scan_plat(false));
 
 	/* We should have our test class now at least, plus more children */
-	ut_assert(1 < list_count_items(gd->uclass_root));
-	ut_assert(0 < list_count_items(&gd->dm_root->child_head));
+	ut_assert(1 < list_count_nodes(gd->uclass_root));
+	ut_assert(0 < list_count_nodes(&gd->dm_root->child_head));
 
 	/* Our 3 dm_test_infox children should be bound to the test uclass */
 	ut_asserteq(3, dm_testdrv_op_count[DM_TEST_OP_POST_BIND]);
diff --git a/test/dm/cpu.c b/test/dm/cpu.c
index acba810..8af2531 100644
--- a/test/dm/cpu.c
+++ b/test/dm/cpu.c
@@ -43,6 +43,8 @@
 	ut_assertok(cpu_get_vendor(dev, text, sizeof(text)));
 	ut_assertok(strcmp(text, "Languid Example Garbage Inc."));
 
+	ut_assertok(cpu_release_core(dev, 0));
+
 	return 0;
 }
 
diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c
index 18c89ee..31effff 100644
--- a/test/dm/test-fdt.c
+++ b/test/dm/test-fdt.c
@@ -19,6 +19,7 @@
 #include <dm/util.h>
 #include <dm/of_access.h>
 #include <linux/ioport.h>
+#include <linux/list.h>
 #include <test/test.h>
 #include <test/ut.h>
 
@@ -162,7 +163,7 @@
 	ut_assert(!ret);
 
 	/* These are num_devices compatible root-level device tree nodes */
-	ut_asserteq(num_devices, list_count_items(&uc->dev_head));
+	ut_asserteq(num_devices, list_count_nodes(&uc->dev_head));
 
 	/* Each should have platform data but no private data */
 	for (i = 0; i < num_devices; i++) {
@@ -217,7 +218,7 @@
 	 * one with "bootph-all" property (a-test node), and the other
 	 * one whose driver marked with DM_FLAG_PRE_RELOC flag (h-test node).
 	 */
-	ut_asserteq(2, list_count_items(&uc->dev_head));
+	ut_asserteq(2, list_count_nodes(&uc->dev_head));
 
 	return 0;
 }
diff --git a/tools/binman/binman.rst b/tools/binman/binman.rst
index 872e974..0cafc36 100644
--- a/tools/binman/binman.rst
+++ b/tools/binman/binman.rst
@@ -1211,7 +1211,7 @@
 
         spi-image {
             filename = "image-spi.bin";
-            insert-template = <&fit>;
+            insert-template = <&common_part>;
 
             /* things specific to SPI follow */
             footer {
@@ -1224,7 +1224,7 @@
 
         mmc-image {
             filename = "image-mmc.bin";
-            insert-template = <&fit>;
+            insert-template = <&common_part>;
 
             /* things specific to MMC follow */
             footer {
diff --git a/tools/binman/bintools.rst b/tools/binman/bintools.rst
index 1336f4d..cd05ad8 100644
--- a/tools/binman/bintools.rst
+++ b/tools/binman/bintools.rst
@@ -10,6 +10,15 @@
 
 
 
+Bintool: bootgen: Generate bootable fsbl image for zynq/zynqmp
+--------------------------------------------------------------
+
+This bintools supports running Xilinx "bootgen" in order
+to generate a bootable, authenticated image form an SPL.
+
+
+
+
 Bintool: bzip2: Compression/decompression using the bzip2 algorithm
 -------------------------------------------------------------------
 
@@ -37,6 +46,33 @@
 
 
 
+Bintool: cst: Image generation for U-Boot
+-----------------------------------------
+
+This bintool supports running `cst` with some basic parameters as
+needed by binman.
+
+
+
+Bintool: fdt_add_pubkey: Add public key to control dtb (spl or u-boot proper)
+-----------------------------------------------------------------------------
+
+This bintool supports running `fdt_add_pubkey`.
+
+Normally mkimage adds signature information to the control dtb. However
+binman images are built independent from each other. Thus it is required
+to add the public key separately from mkimage.
+
+
+
+Bintool: fdtgrep: Handles the 'fdtgrep' tool
+--------------------------------------------
+
+This bintool supports running `fdtgrep` with parameters suitable for
+producing SPL devicetrees from the main one.
+
+
+
 Bintool: fiptool: Image generation for ARM Trusted Firmware
 -----------------------------------------------------------
 
@@ -143,11 +179,20 @@
 
 
 
+Bintool: mkeficapsule: Handles the 'mkeficapsule' tool
+------------------------------------------------------
+
+This bintool is used for generating the EFI capsules. The
+capsule generation parameters can either be specified through
+commandline, or through a config file.
+
+
+
 Bintool: mkimage: Image generation for U-Boot
 ---------------------------------------------
 
 This bintool supports running `mkimage` with some basic parameters as
-neeed by binman.
+needed by binman.
 
 Normally binman uses the mkimage built by U-Boot. But when run outside the
 U-Boot build system, binman can use the version installed in your system.
@@ -194,25 +239,3 @@
 
 
 
-Bintool: fdt_add_pubkey: Add public key to device tree
-------------------------------------------------------
-
-This bintool supports running `fdt_add_pubkey` in order to add a public
-key coming from a certificate to a device-tree.
-
-Normally signing is done using `mkimage` in context of `binman sign`. However,
-in this process the public key is not added to the stage before u-boot proper.
-Using `fdt_add_pubkey` the key can be injected to the SPL independent of
-`mkimage`
-
-
-
-Bintool: bootgen: Sign ZynqMP FSBL image
-----------------------------------------
-
-This bintool supports running `bootgen` in order to sign a SPL for ZynqMP
-devices.
-
-The bintool automatically creates an appropriate input image file (.bif) for
-bootgen based on the passed arguments. The output is a bootable,
-authenticated `boot.bin` file.
diff --git a/tools/binman/btool/fdt_add_pubkey.py b/tools/binman/btool/fdt_add_pubkey.py
index a507742..75a9716 100644
--- a/tools/binman/btool/fdt_add_pubkey.py
+++ b/tools/binman/btool/fdt_add_pubkey.py
@@ -32,6 +32,10 @@
                 verified for the image / configuration to be considered valid.
             algo (str): Cryptographic algorithm. Optional parameter,
                 default value: sha1,rsa2048
+
+        Returns:
+            CommandResult: Resulting output from the bintool, or None if the
+                tool is not present
         """
         args = []
         if algo:
diff --git a/tools/binman/btool/fdtgrep.py b/tools/binman/btool/fdtgrep.py
new file mode 100644
index 0000000..da1f8c7
--- /dev/null
+++ b/tools/binman/btool/fdtgrep.py
@@ -0,0 +1,137 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright 2022 Google LLC
+#
+"""Bintool implementation for fdtgrep
+
+fdtgrepprovides a way to grep devicetree-binary files to extract or remove
+certain elements.
+
+Usage: fdtgrep - extract portions from device tree
+
+Usage:
+	fdtgrep <options> <dt file>|-
+
+Output formats are:
+	dts - device tree soure text
+	dtb - device tree blob (sets -Hmt automatically)
+	bin - device tree fragment (may not be a valid .dtb)
+
+Options: -[haAc:b:C:defg:G:HIlLmn:N:o:O:p:P:rRsStTvhV]
+  -a, --show-address                 Display address
+  -A, --colour                       Show all nodes/tags, colour those that match
+  -b, --include-node-with-prop <arg> Include contains containing property
+  -c, --include-compat <arg>         Compatible nodes to include in grep
+  -C, --exclude-compat <arg>         Compatible nodes to exclude in grep
+  -d, --diff                         Diff: Mark matching nodes with +, others with -
+  -e, --enter-node                   Enter direct subnode names of matching nodes
+  -f, --show-offset                  Display offset
+  -g, --include-match <arg>          Node/property/compatible string to include in grep
+  -G, --exclude-match <arg>          Node/property/compatible string to exclude in grep
+  -H, --show-header                  Output a header
+  -I, --show-version                 Put "/dts-v1/;" on first line of dts output
+  -l, --list-regions                 Output a region list
+  -L, --list-strings                 List strings in string table
+  -m, --include-mem                  Include mem_rsvmap section in binary output
+  -n, --include-node <arg>           Node to include in grep
+  -N, --exclude-node <arg>           Node to exclude in grep
+  -p, --include-prop <arg>           Property to include in grep
+  -P, --exclude-prop <arg>           Property to exclude in grep
+  -r, --remove-strings               Remove unused strings from string table
+  -R, --include-root                 Include root node and all properties
+  -s, --show-subnodes                Show all subnodes matching nodes
+  -S, --skip-supernodes              Don't include supernodes of matching nodes
+  -t, --show-stringtab               Include string table in binary output
+  -T, --show-aliases                 Include matching aliases in output
+  -o, --out <arg>                    -o <output file>
+  -O, --out-format <arg>             -O <output format>
+  -v, --invert-match                 Invert the sense of matching (select non-matching lines)
+  -h, --help                         Print this help and exit
+  -V, --version                      Print version and exit
+"""
+
+import tempfile
+
+from u_boot_pylib import tools
+from binman import bintool
+
+class Bintoolfdtgrep(bintool.Bintool):
+    """Handles the 'fdtgrep' tool
+
+    This bintool supports running `fdtgrep` with parameters suitable for
+    producing SPL devicetrees from the main one.
+    """
+    def __init__(self, name):
+        super().__init__(name, 'Grep devicetree files')
+
+    def create_for_phase(self, infile, phase, outfile, remove_props):
+        """Create the FDT for a particular phase
+
+        Args:
+            infile (str): Input filename containing the full FDT contents (with
+                all nodes and properties)
+            phase (str): Phase to generate for ('tpl', 'vpl', 'spl')
+            outfile (str): Output filename to write the grepped FDT contents to
+                (with only neceesary nodes and properties)
+
+        Returns:
+            CommandResult: Resulting output from the bintool, or None if the
+                tool is not present
+        """
+        if phase == 'tpl':
+            tag = 'bootph-pre-sram'
+        elif phase == 'vpl':
+            tag = 'bootph-verify'
+        elif phase == 'spl':
+            tag = 'bootph-pre-ram'
+        else:
+            raise ValueError(f"Invalid U-Boot phase '{phase}': Use tpl/vpl/spl")
+
+        # These args mirror those in cmd_fdtgrep in scripts/Makefile.lib
+        # First do the first stage
+        with tempfile.NamedTemporaryFile(prefix='fdtgrep.tmp',
+                                         dir=tools.get_output_dir()) as tmp:
+            args = [
+                infile,
+                '-o', tmp.name,
+                '-b', 'bootph-all',
+                '-b', tag,
+                '-u',
+                '-RT',
+                '-n', '/chosen',
+                 '-n', '/config',
+                 '-O', 'dtb',
+                ]
+            self.run_cmd(*args)
+            args = [
+                    tmp.name,
+                    '-o', outfile,
+                    '-r',
+                     '-O', 'dtb',
+                    '-P', 'bootph-all',
+                    '-P', 'bootph-pre-ram',
+                    '-P', 'bootph-pre-sram',
+                    '-P', 'bootph-verify',
+                    ]
+            for prop_name in remove_props:
+                args += ['-P', prop_name]
+            return self.run_cmd(*args)
+
+    def fetch(self, method):
+        """Fetch handler for fdtgrep
+
+        This installs fdtgrep using the apt utility, which assumes that it is
+        packaged in u-boot tools, which it is not.
+
+        Args:
+            method (FETCH_...): Method to use
+
+        Returns:
+            True if the file was fetched and now installed, None if a method
+            other than FETCH_BIN was requested
+
+        Raises:
+            Valuerror: Fetching could not be completed
+        """
+        if method != bintool.FETCH_BIN:
+            return None
+        return self.apt_install('u-boot-tools')
diff --git a/tools/binman/btool/mkeficapsule.py b/tools/binman/btool/mkeficapsule.py
index ef1da63..f7e5a88 100644
--- a/tools/binman/btool/mkeficapsule.py
+++ b/tools/binman/btool/mkeficapsule.py
@@ -33,7 +33,8 @@
     commandline, or through a config file.
     """
     def __init__(self, name):
-        super().__init__(name, 'mkeficapsule tool for generating capsules')
+        super().__init__(name, 'mkeficapsule tool for generating capsules',
+                         r'mkeficapsule version (.*)')
 
     def generate_capsule(self, image_index, image_guid, hardware_instance,
                          payload, output_fname, priv_key, pub_key,
diff --git a/tools/binman/control.py b/tools/binman/control.py
index 2f00279..542c2b4 100644
--- a/tools/binman/control.py
+++ b/tools/binman/control.py
@@ -617,6 +617,50 @@
         dtb_item.Flush()
     return images
 
+def CheckForProblems(image):
+    """Check for problems with image generation
+
+    Shows warning about missing, faked or optional external blobs, as well as
+    missing bintools.
+
+    Args:
+        image (Image): Image to process
+
+    Returns:
+        bool: True if there are any problems which result in a non-functional
+            image
+    """
+    missing_list = []
+    image.CheckMissing(missing_list)
+    if missing_list:
+        tout.error("Image '%s' is missing external blobs and is non-functional: %s\n" %
+                   (image.name, ' '.join([e.name for e in missing_list])))
+        _ShowHelpForMissingBlobs(tout.ERROR, missing_list)
+
+    faked_list = []
+    image.CheckFakedBlobs(faked_list)
+    if faked_list:
+        tout.warning(
+            "Image '%s' has faked external blobs and is non-functional: %s\n" %
+            (image.name, ' '.join([os.path.basename(e.GetDefaultFilename())
+                                   for e in faked_list])))
+
+    optional_list = []
+    image.CheckOptional(optional_list)
+    if optional_list:
+        tout.warning(
+            "Image '%s' is missing optional external blobs but is still functional: %s\n" %
+            (image.name, ' '.join([e.name for e in optional_list])))
+        _ShowHelpForMissingBlobs(tout.WARNING, optional_list)
+
+    missing_bintool_list = []
+    image.check_missing_bintools(missing_bintool_list)
+    if missing_bintool_list:
+        tout.warning(
+            "Image '%s' has missing bintools and is non-functional: %s\n" %
+            (image.name, ' '.join([os.path.basename(bintool.name)
+                                   for bintool in missing_bintool_list])))
+    return any([missing_list, faked_list, missing_bintool_list])
 
 def ProcessImage(image, update_fdt, write_map, get_contents=True,
                  allow_resize=True, allow_missing=False,
@@ -689,38 +733,11 @@
     if write_map:
         image.WriteMap()
 
-    missing_list = []
-    image.CheckMissing(missing_list)
-    if missing_list:
-        tout.error("Image '%s' is missing external blobs and is non-functional: %s\n" %
-                   (image.name, ' '.join([e.name for e in missing_list])))
-        _ShowHelpForMissingBlobs(tout.ERROR, missing_list)
+    has_problems = CheckForProblems(image)
 
-    faked_list = []
-    image.CheckFakedBlobs(faked_list)
-    if faked_list:
-        tout.warning(
-            "Image '%s' has faked external blobs and is non-functional: %s\n" %
-            (image.name, ' '.join([os.path.basename(e.GetDefaultFilename())
-                                   for e in faked_list])))
+    image.WriteAlternates()
 
-    optional_list = []
-    image.CheckOptional(optional_list)
-    if optional_list:
-        tout.warning(
-            "Image '%s' is missing optional external blobs but is still functional: %s\n" %
-            (image.name, ' '.join([e.name for e in optional_list])))
-        _ShowHelpForMissingBlobs(tout.WARNING, optional_list)
-
-    missing_bintool_list = []
-    image.check_missing_bintools(missing_bintool_list)
-    if missing_bintool_list:
-        tout.warning(
-            "Image '%s' has missing bintools and is non-functional: %s\n" %
-            (image.name, ' '.join([os.path.basename(bintool.name)
-                                   for bintool in missing_bintool_list])))
-    return any([missing_list, faked_list, missing_bintool_list])
-
+    return has_problems
 
 def Binman(args):
     """The main control code for binman
diff --git a/tools/binman/elf.py b/tools/binman/elf.py
index 2ecc95f..a469405 100644
--- a/tools/binman/elf.py
+++ b/tools/binman/elf.py
@@ -275,7 +275,7 @@
         return 0
     base = syms.get(base_sym)
     if not base and not is_elf:
-        tout.debug('LookupAndWriteSymbols: no base')
+        tout.debug(f'LookupAndWriteSymbols: no base: elf_fname={elf_fname}, base_sym={base_sym}, is_elf={is_elf}')
         return 0
     base_addr = 0 if is_elf else base.address
     count = 0
diff --git a/tools/binman/entries.rst b/tools/binman/entries.rst
index bdda1ef..1248270 100644
--- a/tools/binman/entries.rst
+++ b/tools/binman/entries.rst
@@ -11,6 +11,48 @@
 
 
 
+.. _etype_alternates_fdt:
+
+Entry: alternates-fdt: Entry that generates alternative sections for each devicetree provided
+---------------------------------------------------------------------------------------------
+
+When creating an image designed to boot on multiple models, each model
+requires its own devicetree. This entry deals with selecting the correct
+devicetree from a directory containing them. Each one is read in turn, then
+used to produce section contents which are written to a file. This results
+in a number of images, one for each model.
+
+For example this produces images for each .dtb file in the 'dtb' directory::
+
+    alternates-fdt {
+        fdt-list-dir = "dtb";
+        filename-pattern = "NAME.bin";
+        fdt-phase = "tpl";
+
+        section {
+            u-boot-tpl {
+            };
+        };
+    };
+
+Each output file is named based on its input file, so an input file of
+`model1.dtb` results in an output file of `model1.bin` (i.e. the `NAME` in
+the `filename-pattern` property is replaced with the .dtb basename).
+
+Note that this entry type still produces contents for the 'main' image, in
+that case using the normal dtb provided to Binman, e.g. `u-boot-tpl.dtb`.
+But that image is unlikely to be useful, since it relates to whatever dtb
+happened to be the default when U-Boot builds
+(i.e. `CONFIG_DEFAULT_DEVICE_TREE`). However, Binman ensures that the size
+of each of the alternates is the same as the 'default' one, so they can in
+principle be 'slotted in' to the appropriate place in the main image.
+
+The optional `fdt-phase` property indicates the phase to build. In this
+case, it etype runs fdtgrep to obtain the devicetree subset for that phase,
+respecting the `bootph-xxx` tags in the devicetree.
+
+
+
 .. _etype_atf_bl31:
 
 Entry: atf-bl31: ARM Trusted Firmware (ATF) BL31 blob
@@ -815,6 +857,13 @@
 
             fit,fdt-list-val = "dtb1", "dtb2";
 
+    fit,fdt-list-dir
+        As an alternative to fit,fdt-list the list of device tree files
+        can be provided as a directory. Each .dtb file in the directory is
+        processed, , e.g.::
+
+            fit,fdt-list-dir = "arch/arm/dts
+
 Substitutions
 ~~~~~~~~~~~~~
 
@@ -890,6 +939,7 @@
             firmware = "atf";
             loadables = "uboot";
             fdt = "fdt-SEQ";
+            fit,compatible;    // optional
         };
     };
 
@@ -899,6 +949,39 @@
 Note that if no devicetree files are provided (with '-a of-list' as above)
 then no nodes will be generated.
 
+The 'fit,compatible' property (if present) is replaced with the compatible
+string from the root node of the devicetree, so that things work correctly
+with FIT's configuration-matching algortihm.
+
+Dealing with phases
+~~~~~~~~~~~~~~~~~~~
+
+FIT can be used to load firmware. In this case it may be necessary to run
+the devicetree for each model through fdtgrep to remove unwanted properties.
+The 'fit,fdt-phase' property can be provided to indicate the phase for which
+the devicetree is intended.
+
+For example this indicates that the FDT should be processed for VPL::
+
+    images {
+        @fdt-SEQ {
+            description = "fdt-NAME";
+            type = "flat_dt";
+            compression = "none";
+            fit,fdt-phase = "vpl";
+        };
+    };
+
+Using this mechanism, it is possible to generate a FIT which can provide VPL
+images for multiple models, with TPL selecting the correct model to use. The
+same approach can of course be used for SPL images.
+
+Note that the `of-spl-remove-props` entryarg can be used to indicate
+additional properties to remove. It is often used to remove properties like
+`clock-names` and `pinctrl-names` which are not needed in SPL builds.
+
+See :ref:`fdtgrep_filter` for more information.
+
 Generating nodes from an ELF file (split-elf)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -2290,8 +2373,6 @@
 
 SPL can access binman symbols at runtime. See :ref:`binman_fdt`.
 
-in the binman README for more information.
-
 The ELF file 'spl/u-boot-spl' must also be available for this to work, since
 binman uses that to look up symbols to write into the SPL binary.
 
@@ -2480,8 +2561,6 @@
 
 TPL can access binman symbols at runtime. See :ref:`binman_fdt`.
 
-in the binman README for more information.
-
 The ELF file 'tpl/u-boot-tpl' must also be available for this to work, since
 binman uses that to look up symbols to write into the TPL binary.
 
@@ -2571,6 +2650,9 @@
 The ELF file 'vpl/u-boot-vpl' must also be available for this to work, since
 binman uses that to look up symbols to write into the VPL binary.
 
+Note that this entry is automatically replaced with u-boot-vpl-expanded
+unless --no-expanded is used or the node has a 'no-expanded' property.
+
 
 
 .. _etype_u_boot_vpl_bss_pad:
@@ -2659,8 +2741,8 @@
 
 This is the U-Boot VPL binary, It does not include a device tree blob at
 the end of it so may not be able to work without it, assuming VPL needs
-a device tree to operate on your platform. You can add a u_boot_vpl_dtb
-entry after this one, or use a u_boot_vpl entry instead, which normally
+a device tree to operate on your platform. You can add a u-boot-vpl-dtb
+entry after this one, or use a u-boot-vpl entry instead, which normally
 expands to a section containing u-boot-vpl-dtb, u-boot-vpl-bss-pad and
 u-boot-vpl-dtb
 
diff --git a/tools/binman/entry.py b/tools/binman/entry.py
index 219d5dc..6d2f378 100644
--- a/tools/binman/entry.py
+++ b/tools/binman/entry.py
@@ -1199,6 +1199,9 @@
             self.uncomp_size = len(indata)
             if self.comp_bintool.is_present():
                 data = self.comp_bintool.compress(indata)
+                uniq = self.GetUniqueName()
+                fname = tools.get_output_filename(f'comp.{uniq}')
+                tools.write_file(fname, data)
             else:
                 self.record_missing_bintool(self.comp_bintool)
                 data = tools.get_bytes(0, 1024)
@@ -1383,3 +1386,17 @@
 
     def UpdateSignatures(self, privatekey_fname, algo, input_fname):
         self.Raise('Updating signatures is not supported with this entry type')
+
+    def FdtContents(self, fdt_etype):
+        """Get the contents of an FDT for a particular phase
+
+        Args:
+            fdt_etype (str): Filename of the phase of the FDT to return, e.g.
+                'u-boot-tpl-dtb'
+
+        Returns:
+            tuple:
+                fname (str): Filename of .dtb
+                bytes: Contents of FDT (possibly run through fdtgrep)
+        """
+        return self.section.FdtContents(fdt_etype)
diff --git a/tools/binman/etype/alternates_fdt.py b/tools/binman/etype/alternates_fdt.py
new file mode 100644
index 0000000..808f535
--- /dev/null
+++ b/tools/binman/etype/alternates_fdt.py
@@ -0,0 +1,132 @@
+# SPDX-License-Identifier:      GPL-2.0+
+# Copyright 2024 Google LLC
+# Written by Simon Glass <sjg@chromium.org>
+
+"""Entry-type module for producing multiple alternate sections"""
+
+import glob
+import os
+
+from binman.entry import EntryArg
+from binman.etype.section import Entry_section
+from dtoc import fdt_util
+from u_boot_pylib import tools
+
+class Entry_alternates_fdt(Entry_section):
+    """Entry that generates alternative sections for each devicetree provided
+
+    When creating an image designed to boot on multiple models, each model
+    requires its own devicetree. This entry deals with selecting the correct
+    devicetree from a directory containing them. Each one is read in turn, then
+    used to produce section contents which are written to a file. This results
+    in a number of images, one for each model.
+
+    For example this produces images for each .dtb file in the 'dtb' directory::
+
+        alternates-fdt {
+            fdt-list-dir = "dtb";
+            filename-pattern = "NAME.bin";
+            fdt-phase = "tpl";
+
+            section {
+                u-boot-tpl {
+                };
+            };
+        };
+
+    Each output file is named based on its input file, so an input file of
+    `model1.dtb` results in an output file of `model1.bin` (i.e. the `NAME` in
+    the `filename-pattern` property is replaced with the .dtb basename).
+
+    Note that this entry type still produces contents for the 'main' image, in
+    that case using the normal dtb provided to Binman, e.g. `u-boot-tpl.dtb`.
+    But that image is unlikely to be useful, since it relates to whatever dtb
+    happened to be the default when U-Boot builds
+    (i.e. `CONFIG_DEFAULT_DEVICE_TREE`). However, Binman ensures that the size
+    of each of the alternates is the same as the 'default' one, so they can in
+    principle be 'slotted in' to the appropriate place in the main image.
+
+    The optional `fdt-phase` property indicates the phase to build. In this
+    case, it etype runs fdtgrep to obtain the devicetree subset for that phase,
+    respecting the `bootph-xxx` tags in the devicetree.
+    """
+    def __init__(self, section, etype, node):
+        super().__init__(section, etype, node)
+        self.fdt_list_dir = None
+        self.filename_pattern = None
+        self.required_props = ['fdt-list-dir']
+        self._cur_fdt = None
+        self._fdt_phase = None
+        self.fdtgrep = None
+        self._fdt_dir = None
+        self._fdts = None
+        self._fname_pattern = None
+        self._remove_props = None
+        self.alternates = None
+
+    def ReadNode(self):
+        """Read properties from the node"""
+        super().ReadNode()
+        self._fdt_dir = fdt_util.GetString(self._node, 'fdt-list-dir')
+        fname = tools.get_input_filename(self._fdt_dir)
+        fdts = glob.glob('*.dtb', root_dir=fname)
+        self._fdts = [os.path.splitext(f)[0] for f in fdts]
+
+        self._fdt_phase = fdt_util.GetString(self._node, 'fdt-phase')
+
+        # This is used by Image.WriteAlternates()
+        self.alternates = self._fdts
+
+        self._fname_pattern = fdt_util.GetString(self._node, 'filename-pattern')
+
+        self._remove_props = []
+        props, = self.GetEntryArgsOrProps(
+            [EntryArg('of-spl-remove-props', str)], required=False)
+        if props:
+            self._remove_props = props.split()
+
+    def FdtContents(self, fdt_etype):
+        # If there is no current FDT, just use the normal one
+        if not self._cur_fdt:
+            return self.section.FdtContents(fdt_etype)
+
+        # Find the file to use
+        fname = os.path.join(self._fdt_dir, f'{self._cur_fdt}.dtb')
+        infile = tools.get_input_filename(fname)
+
+        # Run fdtgrep if needed, to remove unwanted nodes and properties
+        if self._fdt_phase:
+            uniq = self.GetUniqueName()
+            outfile = tools.get_output_filename(
+                f'{uniq}.{self._cur_fdt}-{self._fdt_phase}.dtb')
+            self.fdtgrep.create_for_phase(infile, self._fdt_phase, outfile,
+                                          self._remove_props)
+            return outfile, tools.read_file(outfile)
+        return fname, tools.read_file(infile)
+
+    def ProcessWithFdt(self, alt):
+        """Produce the contents of this entry, using a particular FDT blob
+
+        Args:
+            alt (str): Name of the alternate
+
+        Returns:
+            tuple:
+                str: Filename to use for the alternate's .bin file
+                bytes: Contents of this entry's section, using the selected FDT
+        """
+        pattern = self._fname_pattern or 'NAME.bin'
+        fname = pattern.replace('NAME', alt)
+
+        data = b''
+        try:
+            self._cur_fdt = alt
+            self.ProcessContents()
+            data = self.GetPaddedData()
+        finally:
+            self._cur_fdt = None
+        return fname, data
+
+    def AddBintools(self, btools):
+        super().AddBintools(btools)
+        self.fdtgrep = self.AddBintool(btools, 'fdtgrep')
diff --git a/tools/binman/etype/blob_dtb.py b/tools/binman/etype/blob_dtb.py
index d543de9..b234323 100644
--- a/tools/binman/etype/blob_dtb.py
+++ b/tools/binman/etype/blob_dtb.py
@@ -41,12 +41,12 @@
     def ObtainContents(self, fake_size=0):
         """Get the device-tree from the list held by the 'state' module"""
         self._filename = self.GetDefaultFilename()
-        self._pathname, _ = state.GetFdtContents(self.GetFdtEtype())
+        self._pathname, _ = self.FdtContents(self.GetFdtEtype())
         return super().ReadBlobContents()
 
     def ProcessContents(self):
         """Re-read the DTB contents so that we get any calculated properties"""
-        _, indata = state.GetFdtContents(self.GetFdtEtype())
+        _, indata = self.FdtContents(self.GetFdtEtype())
 
         if self.compress == 'zstd' and self.prepend != 'length':
             self.Raise('The zstd compression requires a length header')
@@ -57,7 +57,9 @@
     def GetFdtEtype(self):
         """Get the entry type of this device tree
 
-        This can be 'u-boot-dtb', 'u-boot-spl-dtb' or 'u-boot-tpl-dtb'
+        This can be 'u-boot-dtb', 'u-boot-spl-dtb', 'u-boot-tpl-dtb' or
+        'u-boot-vpl-dtb'
+
         Returns:
             Entry type if any, e.g. 'u-boot-dtb'
         """
diff --git a/tools/binman/etype/efi_capsule.py b/tools/binman/etype/efi_capsule.py
index 751f654..5941545 100644
--- a/tools/binman/etype/efi_capsule.py
+++ b/tools/binman/etype/efi_capsule.py
@@ -148,8 +148,11 @@
                                                  self.fw_version,
                                                  self.oem_flags)
         if ret is not None:
-            os.remove(payload)
             return tools.read_file(capsule_fname)
+        else:
+            # Bintool is missing; just use the input data as the output
+            self.record_missing_bintool(self.mkeficapsule)
+            return data
 
     def AddBintools(self, btools):
         self.mkeficapsule = self.AddBintool(btools, 'mkeficapsule')
diff --git a/tools/binman/etype/fit.py b/tools/binman/etype/fit.py
index 2c14b15..ee44e5a 100644
--- a/tools/binman/etype/fit.py
+++ b/tools/binman/etype/fit.py
@@ -5,7 +5,9 @@
 
 """Entry-type module for producing a FIT"""
 
+import glob
 import libfdt
+import os
 
 from binman.entry import Entry, EntryArg
 from binman.etype.section import Entry_section
@@ -87,6 +89,13 @@
 
                 fit,fdt-list-val = "dtb1", "dtb2";
 
+        fit,fdt-list-dir
+            As an alternative to fit,fdt-list the list of device tree files
+            can be provided as a directory. Each .dtb file in the directory is
+            processed, , e.g.::
+
+                fit,fdt-list-dir = "arch/arm/dts
+
     Substitutions
     ~~~~~~~~~~~~~
 
@@ -162,6 +171,7 @@
                 firmware = "atf";
                 loadables = "uboot";
                 fdt = "fdt-SEQ";
+                fit,compatible;    // optional
             };
         };
 
@@ -171,6 +181,40 @@
     Note that if no devicetree files are provided (with '-a of-list' as above)
     then no nodes will be generated.
 
+    The 'fit,compatible' property (if present) is replaced with the compatible
+    string from the root node of the devicetree, so that things work correctly
+    with FIT's configuration-matching algortihm.
+
+    Dealing with phases
+    ~~~~~~~~~~~~~~~~~~~
+
+    FIT can be used to load firmware. In this case it may be necessary to run
+    the devicetree for each model through fdtgrep to remove unwanted properties.
+    The 'fit,fdt-phase' property can be provided to indicate the phase for which
+    the devicetree is intended.
+
+    For example this indicates that the FDT should be processed for VPL::
+
+        images {
+            @fdt-SEQ {
+                description = "fdt-NAME";
+                type = "flat_dt";
+                compression = "none";
+                fit,fdt-phase = "vpl";
+            };
+        };
+
+    Using this mechanism, it is possible to generate a FIT which can provide VPL
+    images for multiple models, with TPL selecting the correct model to use. The
+    same approach can of course be used for SPL images.
+
+    Note that the `of-spl-remove-props` entryarg can be used to indicate
+    additional properties to remove. It is often used to remove properties like
+    `clock-names` and `pinctrl-names` which are not needed in SPL builds. This
+    value is automatically passed to binman by the U-Boot build.
+
+    See :ref:`fdtgrep_filter` for more information.
+
     Generating nodes from an ELF file (split-elf)
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -352,9 +396,16 @@
         self._fit = None
         self._fit_props = {}
         self._fdts = None
+        self._fdt_dir = None
         self.mkimage = None
+        self.fdtgrep = None
         self._priv_entries = {}
         self._loadables = []
+        self._remove_props = []
+        props, = self.GetEntryArgsOrProps(
+            [EntryArg('of-spl-remove-props', str)], required=False)
+        if props:
+            self._remove_props = props.split()
 
     def ReadNode(self):
         super().ReadNode()
@@ -368,7 +419,14 @@
             if fdts is not None:
                 self._fdts = fdts.split()
         else:
-            self._fdts = fdt_util.GetStringList(self._node, 'fit,fdt-list-val')
+            self._fdt_dir = fdt_util.GetString(self._node, 'fit,fdt-list-dir')
+            if self._fdt_dir:
+                indir = tools.get_input_filename(self._fdt_dir)
+                fdts = glob.glob('*.dtb', root_dir=indir)
+                self._fdts = [os.path.splitext(f)[0] for f in sorted(fdts)]
+            else:
+                self._fdts = fdt_util.GetStringList(self._node,
+                                                    'fit,fdt-list-val')
 
         self._fit_default_dt = self.GetEntryArgsOrProps([EntryArg('default-dt',
                                                                   str)])[0]
@@ -483,6 +541,19 @@
         rel_path = node.path[len(self._node.path) + 1:]
         self.Raise(f"subnode '{rel_path}': {msg}")
 
+    def _run_fdtgrep(self, infile, phase, outfile):
+        """Run fdtgrep to create the dtb for a phase
+
+        Args:
+            infile (str): Input filename containing the full FDT contents (with
+                all nodes and properties)
+            phase (str): Phase to generate for ('tpl', 'vpl', 'spl')
+            outfile (str): Output filename to write the grepped FDT contents to
+                (with only neceesary nodes and properties)
+        """
+        return self.fdtgrep.create_for_phase(infile, phase, outfile,
+                                             self._remove_props)
+
     def _build_input(self):
         """Finish the FIT by adding the 'data' properties to it
 
@@ -584,6 +655,7 @@
                 for seq, fdt_fname in enumerate(self._fdts):
                     node_name = node.name[1:].replace('SEQ', str(seq + 1))
                     fname = tools.get_input_filename(fdt_fname + '.dtb')
+                    fdt_phase = None
                     with fsw.add_node(node_name):
                         for pname, prop in node.props.items():
                             if pname == 'fit,firmware':
@@ -594,6 +666,15 @@
                                 fsw.property('loadables', val.encode('utf-8'))
                             elif pname == 'fit,operation':
                                 pass
+                            elif pname == 'fit,compatible':
+                                fdt_phase = fdt_util.GetString(node, pname)
+                                data = tools.read_file(fname)
+                                fdt = Fdt.FromData(data)
+                                fdt.Scan()
+                                prop = fdt.GetRoot().props['compatible']
+                                fsw.property('compatible', prop.bytes)
+                            elif pname == 'fit,fdt-phase':
+                                fdt_phase = fdt_util.GetString(node, pname)
                             elif pname.startswith('fit,'):
                                 self._raise_subnode(
                                     node, f"Unknown directive '{pname}'")
@@ -606,7 +687,14 @@
 
                         # Add data for 'images' nodes (but not 'config')
                         if depth == 1 and in_images:
-                            fsw.property('data', tools.read_file(fname))
+                            if fdt_phase:
+                                phase_fname = tools.get_output_filename(
+                                    f'{fdt_fname}-{fdt_phase}.dtb')
+                                self._run_fdtgrep(fname, fdt_phase, phase_fname)
+                                data = tools.read_file(phase_fname)
+                            else:
+                                data = tools.read_file(fname)
+                            fsw.property('data', data)
 
                         for subnode in node.subnodes:
                             with fsw.add_node(subnode.name):
@@ -834,6 +922,7 @@
     def AddBintools(self, btools):
         super().AddBintools(btools)
         self.mkimage = self.AddBintool(btools, 'mkimage')
+        self.fdtgrep = self.AddBintool(btools, 'fdtgrep')
 
     def CheckMissing(self, missing_list):
         # We must use our private entry list for this since generator nodes
diff --git a/tools/binman/etype/u_boot_spl_nodtb.py b/tools/binman/etype/u_boot_spl_nodtb.py
index e7ec329..0e172ae 100644
--- a/tools/binman/etype/u_boot_spl_nodtb.py
+++ b/tools/binman/etype/u_boot_spl_nodtb.py
@@ -23,8 +23,6 @@
 
     SPL can access binman symbols at runtime. See :ref:`binman_fdt`.
 
-    in the binman README for more information.
-
     The ELF file 'spl/u-boot-spl' must also be available for this to work, since
     binman uses that to look up symbols to write into the SPL binary.
     """
diff --git a/tools/binman/etype/u_boot_tpl_nodtb.py b/tools/binman/etype/u_boot_tpl_nodtb.py
index 9bb2b5d..e0c8a55 100644
--- a/tools/binman/etype/u_boot_tpl_nodtb.py
+++ b/tools/binman/etype/u_boot_tpl_nodtb.py
@@ -23,8 +23,6 @@
 
     TPL can access binman symbols at runtime. See :ref:`binman_fdt`.
 
-    in the binman README for more information.
-
     The ELF file 'tpl/u-boot-tpl' must also be available for this to work, since
     binman uses that to look up symbols to write into the TPL binary.
     """
diff --git a/tools/binman/etype/u_boot_vpl.py b/tools/binman/etype/u_boot_vpl.py
index 31d7e83..0797831 100644
--- a/tools/binman/etype/u_boot_vpl.py
+++ b/tools/binman/etype/u_boot_vpl.py
@@ -27,6 +27,9 @@
 
     The ELF file 'vpl/u-boot-vpl' must also be available for this to work, since
     binman uses that to look up symbols to write into the VPL binary.
+
+    Note that this entry is automatically replaced with u-boot-vpl-expanded
+    unless --no-expanded is used or the node has a 'no-expanded' property.
     """
     def __init__(self, section, etype, node):
         super().__init__(section, etype, node, auto_write_symbols=True)
diff --git a/tools/binman/etype/u_boot_vpl_nodtb.py b/tools/binman/etype/u_boot_vpl_nodtb.py
index 64c2767..765cf53 100644
--- a/tools/binman/etype/u_boot_vpl_nodtb.py
+++ b/tools/binman/etype/u_boot_vpl_nodtb.py
@@ -16,8 +16,8 @@
 
     This is the U-Boot VPL binary, It does not include a device tree blob at
     the end of it so may not be able to work without it, assuming VPL needs
-    a device tree to operate on your platform. You can add a u_boot_vpl_dtb
-    entry after this one, or use a u_boot_vpl entry instead, which normally
+    a device tree to operate on your platform. You can add a u-boot-vpl-dtb
+    entry after this one, or use a u-boot-vpl entry instead, which normally
     expands to a section containing u-boot-vpl-dtb, u-boot-vpl-bss-pad and
     u-boot-vpl-dtb
 
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index e4da040..93f3d22 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -7,6 +7,7 @@
 #    python -m unittest func_test.TestFunctional.testHelp
 
 import collections
+import glob
 import gzip
 import hashlib
 from optparse import OptionParser
@@ -546,7 +547,7 @@
             dtb_data = self._SetupDtb(fname)
 
             # For testing purposes, make a copy of the DT for SPL and TPL. Add
-            # a node indicating which it is, so aid verification.
+            # a node indicating which it is, to aid verification.
             for name in ['spl', 'tpl', 'vpl']:
                 dtb_fname = '%s/u-boot-%s.dtb' % (name, name)
                 outfile = os.path.join(self._indir, dtb_fname)
@@ -4180,8 +4181,8 @@
         data = self._DoReadFile('172_scp.dts')
         self.assertEqual(SCP_DATA, data[:len(SCP_DATA)])
 
-    def testFitFdt(self):
-        """Test an image with an FIT with multiple FDT images"""
+    def CheckFitFdt(self, dts='170_fit_fdt.dts', use_fdt_list=True):
+        """Check an image with an FIT with multiple FDT images"""
         def _CheckFdt(seq, expected_data):
             """Check the FDT nodes
 
@@ -4220,11 +4221,12 @@
             self.assertEqual('fdt-%d' % seq, fnode.props['fdt'].value)
 
         entry_args = {
-            'of-list': 'test-fdt1 test-fdt2',
             'default-dt': 'test-fdt2',
         }
+        if use_fdt_list:
+            entry_args['of-list'] = 'test-fdt1 test-fdt2'
         data = self._DoReadFileDtb(
-            '170_fit_fdt.dts',
+            dts,
             entry_args=entry_args,
             extra_indirs=[os.path.join(self._indir, TEST_FDT_SUBDIR)])[0]
         self.assertEqual(U_BOOT_NODTB_DATA, data[-len(U_BOOT_NODTB_DATA):])
@@ -4243,6 +4245,10 @@
         _CheckConfig(1, TEST_FDT1_DATA)
         _CheckConfig(2, TEST_FDT2_DATA)
 
+    def testFitFdt(self):
+        """Test an image with an FIT with multiple FDT images"""
+        self.CheckFitFdt()
+
     def testFitFdtMissingList(self):
         """Test handling of a missing 'of-list' entry arg"""
         with self.assertRaises(ValueError) as e:
@@ -7175,27 +7181,24 @@
 
 
     def testSplPubkeyDtb(self):
-         """Test u_boot_spl_pubkey_dtb etype"""
-         data = tools.read_file(self.TestFile("key.pem"))
-         self._MakeInputFile("key.crt", data)
-         self._DoReadFileRealDtb('306_spl_pubkey_dtb.dts')
-         image = control.images['image']
-         entries = image.GetEntries()
-         dtb_entry = entries['u-boot-spl-pubkey-dtb']
-         dtb_data = dtb_entry.GetData()
-         dtb = fdt.Fdt.FromData(dtb_data)
-         dtb.Scan()
+        """Test u_boot_spl_pubkey_dtb etype"""
+        data = tools.read_file(self.TestFile("key.pem"))
+        self._MakeInputFile("key.crt", data)
+        self._DoReadFileRealDtb('306_spl_pubkey_dtb.dts')
+        image = control.images['image']
+        entries = image.GetEntries()
+        dtb_entry = entries['u-boot-spl-pubkey-dtb']
+        dtb_data = dtb_entry.GetData()
+        dtb = fdt.Fdt.FromData(dtb_data)
+        dtb.Scan()
 
-         signature_node = dtb.GetNode('/signature')
-         self.assertIsNotNone(signature_node)
-         key_node = signature_node.FindNode("key-key")
-         self.assertIsNotNone(key_node)
-         self.assertEqual(fdt_util.GetString(key_node, "required"),
-                          "conf")
-         self.assertEqual(fdt_util.GetString(key_node, "algo"),
-                          "sha384,rsa4096")
-         self.assertEqual(fdt_util.GetString(key_node, "key-name-hint"),
-                          "key")
+        signature_node = dtb.GetNode('/signature')
+        self.assertIsNotNone(signature_node)
+        key_node = signature_node.FindNode("key-key")
+        self.assertIsNotNone(key_node)
+        self.assertEqual(fdt_util.GetString(key_node, "required"), "conf")
+        self.assertEqual(fdt_util.GetString(key_node, "algo"), "sha384,rsa4096")
+        self.assertEqual(fdt_util.GetString(key_node, "key-name-hint"), "key")
 
     def testXilinxBootgenSigning(self):
         """Test xilinx-bootgen etype"""
@@ -7487,6 +7490,206 @@
             err,
             "Image '.*' is missing external blobs and is non-functional: .*")
 
+    def SetupAlternateDts(self):
+        """Compile the .dts test files for alternative-fdt
+
+        Returns:
+            tuple:
+                str: Test directory created
+                list of str: '.bin' files which we expect Binman to create
+        """
+        testdir = TestFunctional._MakeInputDir('dtb')
+        dtb_list = []
+        for fname in glob.glob(f'{self.TestFile("alt_dts")}/*.dts'):
+            tmp_fname = fdt_util.EnsureCompiled(fname, testdir)
+            base = os.path.splitext(os.path.basename(fname))[0]
+            dtb_list.append(base + '.bin')
+            shutil.move(tmp_fname, os.path.join(testdir, base + '.dtb'))
+
+        return testdir, dtb_list
+
+    def CheckAlternates(self, dts, phase, xpl_data):
+        """Run the test for the alterative-fdt etype
+
+        Args:
+            dts (str): Devicetree file to process
+            phase (str): Phase to process ('spl', 'tpl' or 'vpl')
+            xpl_data (bytes): Expected data for the phase's binary
+
+        Returns:
+            dict of .dtb files produced
+                key: str filename
+                value: Fdt object
+        """
+        dtb_list = self.SetupAlternateDts()[1]
+
+        entry_args = {
+            f'{phase}-dtb': '1',
+            f'{phase}-bss-pad': 'y',
+            'of-spl-remove-props': 'prop-to-remove another-prop-to-get-rid-of',
+        }
+        data = self._DoReadFileDtb(dts, use_real_dtb=True, update_dtb=True,
+                                   use_expanded=True, entry_args=entry_args)[0]
+        self.assertEqual(xpl_data, data[:len(xpl_data)])
+        rest = data[len(xpl_data):]
+        pad_len = 10
+        self.assertEqual(tools.get_bytes(0, pad_len), rest[:pad_len])
+
+        # Check the dtb is using the test file
+        dtb_data = rest[pad_len:]
+        dtb = fdt.Fdt.FromData(dtb_data)
+        dtb.Scan()
+        fdt_size = dtb.GetFdtObj().totalsize()
+        self.assertEqual('model-not-set',
+                         fdt_util.GetString(dtb.GetRoot(), 'compatible'))
+
+        pad_len = 10
+
+        # Check the other output files
+        dtbs = {}
+        for fname in dtb_list:
+            pathname = tools.get_output_filename(fname)
+            self.assertTrue(os.path.exists(pathname))
+
+            data = tools.read_file(pathname)
+            self.assertEqual(xpl_data, data[:len(xpl_data)])
+            rest = data[len(xpl_data):]
+
+            self.assertEqual(tools.get_bytes(0, pad_len), rest[:pad_len])
+            rest = rest[pad_len:]
+
+            dtb = fdt.Fdt.FromData(rest)
+            dtb.Scan()
+            dtbs[fname] = dtb
+
+            expected = 'one' if '1' in fname else 'two'
+            self.assertEqual(f'u-boot,model-{expected}',
+                             fdt_util.GetString(dtb.GetRoot(), 'compatible'))
+
+            # Make sure the FDT is the same size as the 'main' one
+            rest = rest[fdt_size:]
+
+            self.assertEqual(b'', rest)
+        return dtbs
+
+    def testAlternatesFdt(self):
+        """Test handling of alternates-fdt etype"""
+        self._SetupTplElf()
+        dtbs = self.CheckAlternates('328_alternates_fdt.dts', 'tpl',
+                                    U_BOOT_TPL_NODTB_DATA)
+        for dtb in dtbs.values():
+            # Check for the node with the tag
+            node = dtb.GetNode('/node')
+            self.assertIsNotNone(node)
+            self.assertEqual(5, len(node.props.keys()))
+
+            # Make sure the other node is still there
+            self.assertIsNotNone(dtb.GetNode('/node/other-node'))
+
+    def testAlternatesFdtgrep(self):
+        """Test handling of alternates-fdt etype using fdtgrep"""
+        self._SetupTplElf()
+        dtbs = self.CheckAlternates('329_alternates_fdtgrep.dts', 'tpl',
+                                    U_BOOT_TPL_NODTB_DATA)
+        for dtb in dtbs.values():
+            # Check for the node with the tag
+            node = dtb.GetNode('/node')
+            self.assertIsNotNone(node)
+            self.assertEqual({'some-prop', 'not-a-prop-to-remove'},
+                             node.props.keys())
+
+            # Make sure the other node is gone
+            self.assertIsNone(dtb.GetNode('/node/other-node'))
+
+    def testAlternatesFdtgrepVpl(self):
+        """Test handling of alternates-fdt etype using fdtgrep with vpl"""
+        self._SetupVplElf()
+        dtbs = self.CheckAlternates('330_alternates_vpl.dts', 'vpl',
+                                    U_BOOT_VPL_NODTB_DATA)
+
+    def testAlternatesFdtgrepSpl(self):
+        """Test handling of alternates-fdt etype using fdtgrep with spl"""
+        self._SetupSplElf()
+        dtbs = self.CheckAlternates('331_alternates_spl.dts', 'spl',
+                                    U_BOOT_SPL_NODTB_DATA)
+
+    def testAlternatesFdtgrepInval(self):
+        """Test alternates-fdt etype using fdtgrep with invalid phase"""
+        self._SetupSplElf()
+        with self.assertRaises(ValueError) as e:
+            dtbs = self.CheckAlternates('332_alternates_inval.dts', 'spl',
+                                        U_BOOT_SPL_NODTB_DATA)
+        self.assertIn("Invalid U-Boot phase 'bad-phase': Use tpl/vpl/spl",
+                      str(e.exception))
+
+    def testFitFdtListDir(self):
+        """Test an image with an FIT with FDT images using fit,fdt-list-dir"""
+        self.CheckFitFdt('333_fit_fdt_dir.dts', False)
+
+    def testFitFdtCompat(self):
+        """Test an image with an FIT with compatible in the config nodes"""
+        entry_args = {
+            'of-list': 'model1 model2',
+            'default-dt': 'model2',
+            }
+        testdir, dtb_list = self.SetupAlternateDts()
+        data = self._DoReadFileDtb(
+            '334_fit_fdt_compat.dts', use_real_dtb=True, update_dtb=True,
+            entry_args=entry_args, extra_indirs=[testdir])[0]
+
+        fit_data = data[len(U_BOOT_DATA):-len(U_BOOT_NODTB_DATA)]
+
+        fit = fdt.Fdt.FromData(fit_data)
+        fit.Scan()
+
+        cnode = fit.GetNode('/configurations')
+        self.assertIn('default', cnode.props)
+        self.assertEqual('config-2', cnode.props['default'].value)
+
+        for seq in range(1, 2):
+            name = f'config-{seq}'
+            fnode = fit.GetNode('/configurations/%s' % name)
+            self.assertIsNotNone(fnode)
+            self.assertIn('compatible', fnode.props.keys())
+            expected = 'one' if seq == 1 else 'two'
+            self.assertEqual(f'u-boot,model-{expected}',
+                             fnode.props['compatible'].value)
+
+    def testFitFdtPhase(self):
+        """Test an image with an FIT with fdt-phase in the fdt nodes"""
+        phase = 'tpl'
+        entry_args = {
+            f'{phase}-dtb': '1',
+            f'{phase}-bss-pad': 'y',
+            'of-spl-remove-props': 'prop-to-remove another-prop-to-get-rid-of',
+            'of-list': 'model1 model2',
+            'default-dt': 'model2',
+            }
+        testdir, dtb_list = self.SetupAlternateDts()
+        data = self._DoReadFileDtb(
+            '335_fit_fdt_phase.dts', use_real_dtb=True, update_dtb=True,
+            entry_args=entry_args, extra_indirs=[testdir])[0]
+        fit_data = data[len(U_BOOT_DATA):-len(U_BOOT_NODTB_DATA)]
+        fit = fdt.Fdt.FromData(fit_data)
+        fit.Scan()
+
+        # Check that each FDT has only the expected properties for the phase
+        for seq in range(1, 2):
+            fnode = fit.GetNode(f'/images/fdt-{seq}')
+            self.assertIsNotNone(fnode)
+            dtb = fdt.Fdt.FromData(fnode.props['data'].bytes)
+            dtb.Scan()
+
+            # Make sure that the 'bootph-pre-sram' tag in /node protects it from
+            # removal
+            node = dtb.GetNode('/node')
+            self.assertIsNotNone(node)
+            self.assertEqual({'some-prop', 'not-a-prop-to-remove'},
+                             node.props.keys())
+
+            # Make sure the other node is gone
+            self.assertIsNone(dtb.GetNode('/node/other-node'))
+
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/tools/binman/image.py b/tools/binman/image.py
index e77b5d0..702c905 100644
--- a/tools/binman/image.py
+++ b/tools/binman/image.py
@@ -21,6 +21,9 @@
 from u_boot_pylib import tools
 from u_boot_pylib import tout
 
+# This is imported if needed
+state = None
+
 class Image(section.Entry_section):
     """A Image, representing an output from binman
 
@@ -75,6 +78,10 @@
     def __init__(self, name, node, copy_to_orig=True, test=False,
                  ignore_missing=False, use_expanded=False, missing_etype=False,
                  generate=True):
+        # Put this here to allow entry-docs and help to work without libfdt
+        global state
+        from binman import state
+
         super().__init__(None, 'section', node, test=test)
         self.copy_to_orig = copy_to_orig
         self.name = name
@@ -186,6 +193,19 @@
                 os.remove(sname)
             os.symlink(fname, sname)
 
+    def WriteAlternates(self):
+        """Write out alternative devicetree blobs, each in its own file"""
+        alt_entry = self.FindEntryType('alternates-fdt')
+        if not alt_entry:
+            return
+
+        for alt in alt_entry.alternates:
+            fname, data = alt_entry.ProcessWithFdt(alt)
+            pathname = tools.get_output_filename(fname)
+            tout.info(f"Writing alternate '{alt}' to '{pathname}'")
+            tools.write_file(pathname, data)
+            tout.info("Wrote %#x bytes" % len(data))
+
     def WriteMap(self):
         """Write a map of the image to a .map file
 
@@ -418,3 +438,7 @@
         super().AddBintools(bintools)
         self.bintools = bintools
         return bintools
+
+    def FdtContents(self, fdt_etype):
+        """This base-class implementation simply calls the state function"""
+        return state.GetFdtContents(fdt_etype)
diff --git a/tools/binman/main.py b/tools/binman/main.py
index 92d2431..dc817dd 100755
--- a/tools/binman/main.py
+++ b/tools/binman/main.py
@@ -122,6 +122,8 @@
             ret_code = RunTests(args.debug, args.verbosity, args.processes,
                                 args.test_preserve_dirs, args.tests,
                                 args.toolpath)
+            if args.debug and not test_util.use_concurrent:
+                print('Tests can run in parallel: pip install concurrencytest')
 
     elif args.cmd == 'bintool-docs':
         control.write_bintool_docs(bintool.Bintool.get_tool_list())
diff --git a/tools/binman/test/328_alternates_fdt.dts b/tools/binman/test/328_alternates_fdt.dts
new file mode 100644
index 0000000..c913c8e
--- /dev/null
+++ b/tools/binman/test/328_alternates_fdt.dts
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright 2024 Google LLC
+// Written by Simon Glass <sjg@chromium.org>
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	compatible = "model-not-set";
+
+	binman {
+		alternates-fdt {
+			fdt-list-dir = "dtb";
+			filename-pattern = "NAME.bin";
+
+			section {
+				u-boot-tpl {
+				};
+			};
+		};
+
+		blob {
+			filename = "blobfile";
+		};
+	};
+};
diff --git a/tools/binman/test/329_alternates_fdtgrep.dts b/tools/binman/test/329_alternates_fdtgrep.dts
new file mode 100644
index 0000000..4169528
--- /dev/null
+++ b/tools/binman/test/329_alternates_fdtgrep.dts
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright 2024 Google LLC
+// Written by Simon Glass <sjg@chromium.org>
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	compatible = "model-not-set";
+
+	binman {
+		alternates-fdt {
+			fdt-list-dir = "dtb";
+			filename-pattern = "NAME.bin";
+			fdt-phase = "tpl";
+
+			section {
+				u-boot-tpl {
+				};
+			};
+		};
+
+		blob {
+			filename = "blobfile";
+		};
+	};
+};
diff --git a/tools/binman/test/330_alternates_vpl.dts b/tools/binman/test/330_alternates_vpl.dts
new file mode 100644
index 0000000..5b57069
--- /dev/null
+++ b/tools/binman/test/330_alternates_vpl.dts
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright 2024 Google LLC
+// Written by Simon Glass <sjg@chromium.org>
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	compatible = "model-not-set";
+
+	binman {
+		alternates-fdt {
+			fdt-list-dir = "dtb";
+			filename-pattern = "NAME.bin";
+			fdt-phase = "vpl";
+
+			section {
+				u-boot-vpl {
+				};
+			};
+		};
+
+		blob {
+			filename = "blobfile";
+		};
+	};
+};
diff --git a/tools/binman/test/331_alternates_spl.dts b/tools/binman/test/331_alternates_spl.dts
new file mode 100644
index 0000000..882fefc
--- /dev/null
+++ b/tools/binman/test/331_alternates_spl.dts
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright 2024 Google LLC
+// Written by Simon Glass <sjg@chromium.org>
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	compatible = "model-not-set";
+
+	binman {
+		alternates-fdt {
+			fdt-list-dir = "dtb";
+			filename-pattern = "NAME.bin";
+			fdt-phase = "spl";
+
+			section {
+				u-boot-spl {
+				};
+			};
+		};
+
+		blob {
+			filename = "blobfile";
+		};
+	};
+};
diff --git a/tools/binman/test/332_alternates_inval.dts b/tools/binman/test/332_alternates_inval.dts
new file mode 100644
index 0000000..8c145dd
--- /dev/null
+++ b/tools/binman/test/332_alternates_inval.dts
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright 2024 Google LLC
+// Written by Simon Glass <sjg@chromium.org>
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	compatible = "model-not-set";
+
+	binman {
+		alternates-fdt {
+			fdt-list-dir = "dtb";
+			filename-pattern = "NAME.bin";
+			fdt-phase = "bad-phase";
+
+			section {
+				u-boot-spl {
+				};
+			};
+		};
+
+		blob {
+			filename = "blobfile";
+		};
+	};
+};
diff --git a/tools/binman/test/333_fit_fdt_dir.dts b/tools/binman/test/333_fit_fdt_dir.dts
new file mode 100644
index 0000000..aa77845
--- /dev/null
+++ b/tools/binman/test/333_fit_fdt_dir.dts
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		u-boot {
+		};
+		fit {
+			description = "test-desc";
+			#address-cells = <1>;
+			fit,fdt-list-dir = "fdts";
+
+			images {
+				kernel {
+					description = "Vanilla Linux kernel";
+					type = "kernel";
+					arch = "ppc";
+					os = "linux";
+					compression = "gzip";
+					load = <00000000>;
+					entry = <00000000>;
+					hash-1 {
+						algo = "crc32";
+					};
+					hash-2 {
+						algo = "sha1";
+					};
+					u-boot {
+					};
+				};
+				@fdt-SEQ {
+					description = "fdt-NAME.dtb";
+					type = "flat_dt";
+					compression = "none";
+					hash {
+						algo = "sha256";
+					};
+				};
+			};
+
+			configurations {
+				default = "@config-DEFAULT-SEQ";
+				@config-SEQ {
+					description = "conf-NAME.dtb";
+					firmware = "uboot";
+					loadables = "atf";
+					fdt = "fdt-SEQ";
+				};
+			};
+		};
+		u-boot-nodtb {
+		};
+	};
+};
diff --git a/tools/binman/test/334_fit_fdt_compat.dts b/tools/binman/test/334_fit_fdt_compat.dts
new file mode 100644
index 0000000..3bf45c7
--- /dev/null
+++ b/tools/binman/test/334_fit_fdt_compat.dts
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		u-boot {
+		};
+		fit {
+			description = "test-desc";
+			#address-cells = <1>;
+			fit,fdt-list = "of-list";
+
+			images {
+				kernel {
+					description = "Vanilla Linux kernel";
+					type = "kernel";
+					arch = "ppc";
+					os = "linux";
+					compression = "gzip";
+					load = <00000000>;
+					entry = <00000000>;
+					hash-1 {
+						algo = "crc32";
+					};
+					hash-2 {
+						algo = "sha1";
+					};
+					u-boot {
+					};
+				};
+				@fdt-SEQ {
+					description = "fdt-NAME.dtb";
+					type = "flat_dt";
+					compression = "none";
+					hash {
+						algo = "sha256";
+					};
+				};
+			};
+
+			configurations {
+				default = "@config-DEFAULT-SEQ";
+				@config-SEQ {
+					description = "conf-NAME.dtb";
+					firmware = "uboot";
+					loadables = "atf";
+					fdt = "fdt-SEQ";
+					fit,firmware = "vpl";
+					fit,compatible;
+				};
+			};
+		};
+		u-boot-nodtb {
+		};
+	};
+};
diff --git a/tools/binman/test/335_fit_fdt_phase.dts b/tools/binman/test/335_fit_fdt_phase.dts
new file mode 100644
index 0000000..f8d0740
--- /dev/null
+++ b/tools/binman/test/335_fit_fdt_phase.dts
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		u-boot {
+		};
+		fit {
+			description = "test-desc";
+			#address-cells = <1>;
+			fit,fdt-list = "of-list";
+
+			images {
+				kernel {
+					description = "Vanilla Linux kernel";
+					type = "kernel";
+					arch = "ppc";
+					os = "linux";
+					compression = "gzip";
+					load = <00000000>;
+					entry = <00000000>;
+					hash-1 {
+						algo = "crc32";
+					};
+					hash-2 {
+						algo = "sha1";
+					};
+					u-boot {
+					};
+				};
+				@fdt-SEQ {
+					description = "fdt-NAME.dtb";
+					type = "flat_dt";
+					compression = "none";
+					fit,fdt-phase = "tpl";
+					hash {
+						algo = "sha256";
+					};
+				};
+			};
+
+			configurations {
+				default = "@config-DEFAULT-SEQ";
+				@config-SEQ {
+					description = "conf-NAME.dtb";
+					firmware = "uboot";
+					loadables = "atf";
+					fdt = "fdt-SEQ";
+					fit,firmware = "tpl";
+					fit,compatible;
+				};
+			};
+		};
+		u-boot-nodtb {
+		};
+	};
+};
diff --git a/tools/binman/test/alt_dts/model1.dts b/tools/binman/test/alt_dts/model1.dts
new file mode 100644
index 0000000..01e95e8
--- /dev/null
+++ b/tools/binman/test/alt_dts/model1.dts
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright 2024 Google LLC
+// Written by Simon Glass <sjg@chromium.org>
+
+/dts-v1/;
+
+/ {
+	model = "Model One";
+	compatible = "u-boot,model-one";
+
+	/* this node remains due to bootph-pre-sram tag */
+	node {
+		some-prop;
+		prop-to-remove;
+		another-prop-to-get-rid-of;
+		not-a-prop-to-remove;
+		bootph-pre-sram;
+
+		/* this node get removed by fdtgrep */
+		other-node {
+			another-prop;
+		};
+	};
+};
diff --git a/tools/binman/test/alt_dts/model2.dts b/tools/binman/test/alt_dts/model2.dts
new file mode 100644
index 0000000..7829c51
--- /dev/null
+++ b/tools/binman/test/alt_dts/model2.dts
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright 2024 Google LLC
+// Written by Simon Glass <sjg@chromium.org>
+
+/dts-v1/;
+
+/ {
+	model = "Model Two";
+	compatible = "u-boot,model-two";
+
+	/* this node remains due to bootph-pre-sram tag */
+	node {
+		some-prop;
+		prop-to-remove;
+		another-prop-to-get-rid-of;
+		not-a-prop-to-remove;
+		bootph-pre-sram;
+
+		/* this node get removed by fdtgrep */
+		other-node {
+			another-prop;
+		};
+	};
+};
diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c
index 6a261ff..f28008a 100644
--- a/tools/mkeficapsule.c
+++ b/tools/mkeficapsule.c
@@ -21,6 +21,8 @@
 #include <gnutls/pkcs7.h>
 #include <gnutls/abstract.h>
 
+#include <version.h>
+
 #include "eficapsule.h"
 
 static const char *tool_name = "mkeficapsule";
@@ -28,7 +30,7 @@
 efi_guid_t efi_guid_fm_capsule = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID;
 efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID;
 
-static const char *opts_short = "g:i:I:v:p:c:m:o:dhARD";
+static const char *opts_short = "g:i:I:v:p:c:m:o:dhARDV";
 
 enum {
 	CAPSULE_NORMAL_BLOB = 0,
@@ -70,6 +72,7 @@
 		"\t-R, --fw-revert  firmware revert capsule, takes no GUID, no image blob\n"
 		"\t-o, --capoemflag Capsule OEM Flag, an integer between 0x0000 and 0xffff\n"
 		"\t-D, --dump-capsule          dump the contents of the capsule headers\n"
+		"\t-V, --version               show version number\n"
 		"\t-h, --help                  print a help message\n",
 		tool_name);
 }
@@ -969,9 +972,12 @@
 		case 'D':
 			capsule_dump = true;
 			break;
+		case 'V':
+			printf("mkeficapsule version %s\n", PLAIN_VERSION);
+			exit(EXIT_SUCCESS);
 		default:
 			print_usage();
-			exit(EXIT_SUCCESS);
+			exit(EXIT_FAILURE);
 		}
 	}
 
diff --git a/tools/qconfig.py b/tools/qconfig.py
index 4088079..7b868c7 100755
--- a/tools/qconfig.py
+++ b/tools/qconfig.py
@@ -1079,7 +1079,7 @@
             for linenum in sorted(linenums, reverse=True):
                 add_imply_rule(config[CONFIG_LEN:], fname, linenum)
 
-def defconfig_matches(configs, re_match):
+def defconfig_matches(configs, re_match, re_val):
     """Check if any CONFIG option matches a regex
 
     The match must be complete, i.e. from the start to end of the CONFIG option.
@@ -1089,16 +1089,18 @@
             key: CONFIG option
             value: Value of option
         re_match (re.Pattern): Match to check
+        re_val (re.Pattern): Regular expression to check against value (or None)
 
     Returns:
         bool: True if any CONFIG matches the regex
     """
-    for cfg in configs:
+    for cfg, val in configs.items():
         if re_match.fullmatch(cfg):
-            return True
+            if not re_val or re_val.fullmatch(val):
+                return True
     return False
 
-def do_find_config(config_list):
+def do_find_config(config_list, list_format):
     """Find boards with a given combination of CONFIGs
 
     Args:
@@ -1106,6 +1108,8 @@
             consisting of a config option, with or without a CONFIG_ prefix. If
             an option is preceded by a tilde (~) then it must be false,
             otherwise it must be true)
+        list_format (bool): True to write in 'list' format, one board name per
+            line
 
     Returns:
         int: exit code (0 for success)
@@ -1123,6 +1127,11 @@
         if cfg[0] == '~':
             want = False
             cfg = cfg[1:]
+        val = None
+        re_val = None
+        if '=' in cfg:
+            cfg, val = cfg.split('=', maxsplit=1)
+            re_val = re.compile(val)
 
         # Search everything that is still in the running. If it has a config
         # that we want, or doesn't have one that we don't, add it into the
@@ -1131,11 +1140,13 @@
         out = set()
         re_match = re.compile(cfg)
         for defc in in_list:
-            has_cfg = defconfig_matches(config_db[defc], re_match)
+            has_cfg = defconfig_matches(config_db[defc], re_match, re_val)
             if has_cfg == want:
                 out.add(defc)
-    print(f'{len(out)} matches')
-    print(' '.join(item.split('_defconfig')[0] for item in out))
+    if not list_format:
+        print(f'{len(out)} matches')
+    sep = '\n' if list_format else ' '
+    print(sep.join(item.split('_defconfig')[0] for item in sorted(list(out))))
     return 0
 
 
@@ -1528,6 +1539,8 @@
                       help='Find boards with a given config combination')
     parser.add_argument('-i', '--imply', action='store_true', default=False,
                       help='find options which imply others')
+    parser.add_argument('-l', '--list', action='store_true', default=False,
+                      help='Show a sorted list of board names, one per line')
     parser.add_argument('-I', '--imply-flags', type=str, default='',
                       help="control the -i option ('help' for help")
     parser.add_argument('-j', '--jobs', type=int, default=cpu_count,
@@ -1681,7 +1694,7 @@
             sys.exit(1)
         return 0
     if args.find:
-        return do_find_config(args.configs)
+        return do_find_config(args.configs, args.list)
 
     config_db, progress = move_config(args)
 
diff --git a/tools/update-subtree.sh b/tools/update-subtree.sh
new file mode 100755
index 0000000..536b331
--- /dev/null
+++ b/tools/update-subtree.sh
@@ -0,0 +1,85 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (c) 2024 Linaro Limited
+#
+# Usage: from the top level U-Boot source tree, run:
+# $ ./tools/update-subtree.sh pull <subtree-name> <release-tag>
+# Or:
+# $ ./tools/update-subtree.sh pick <subtree-name> <commit-id>
+#
+# The script will pull changes from subtree repo into U-Boot.
+# It will automatically create a squash/merge commit listing the commits
+# imported.
+
+set -e
+
+print_usage() {
+    echo "usage: $0 <op> <subtree-name> <ref>"
+    echo "  <op>           pull or pick"
+    echo "  <subtree-name> mbedtls or dts or lwip"
+    echo "  <ref>          release tag [pull] or commit id [pick]"
+}
+
+if [ $# -ne 3 ]; then
+    print_usage
+    exit 1
+fi
+
+op=$1
+subtree_name=$2
+ref=$3
+
+set_params() {
+    case "$subtree_name" in
+        mbedtls)
+            path=lib/mbedtls/external/mbedtls
+            repo_url=https://github.com/Mbed-TLS/mbedtls.git
+            remote_name="mbedtls_upstream"
+            ;;
+        dts)
+            path=dts/upstream
+            repo_url=https://git.kernel.org/pub/scm/linux/kernel/git/devicetree/devicetree-rebasing.git
+            remote_name="devicetree-rebasing"
+            ;;
+        lwip)
+            path=lib/lwip/lwip
+            repo_url=https://git.savannah.gnu.org/git/lwip.git
+            remote_name="lwip_upstream"
+            ;;
+        *)
+            echo "Invalid subtree name: $subtree_name"
+            print_usage
+            exit 1
+    esac
+}
+
+set_params
+
+merge_commit_msg=$(cat << EOF
+Subtree merge tag '$ref' of $subtree_name repo [1] into $path
+
+[1] $repo_url
+EOF
+)
+
+remote_add_and_fetch() {
+    if [ -z "$(git remote get-url $remote_name 2>/dev/null)" ]; then
+        echo "Warning: Script automatically adds new git remote via:"
+        echo "    git remote add $remote_name \\"
+        echo "        $repo_url"
+        git remote add $remote_name $repo_url
+    fi
+    git fetch $remote_name master
+}
+
+if [ "$op" = "pull" ]; then
+    remote_add_and_fetch
+    git subtree pull --prefix $path $remote_name "$ref" --squash -m "$merge_commit_msg"
+elif [ "$op" = "pick" ]; then
+    remote_add_and_fetch
+    git cherry-pick -x --strategy=subtree -Xsubtree=$path/ "$ref"
+else
+    print_usage
+    exit 1
+fi