Merge branch 'master' of git://git.denx.de/u-boot-sunxi
diff --git a/.gitignore b/.gitignore
index f1b8015..9110eda 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,6 +13,7 @@
 *.su
 *.mod.c
 *.i
+*.lex.c
 *.lst
 *.order
 *.elf
@@ -20,6 +21,7 @@
 *.bin
 *.patch
 *.cfgtmp
+*.tab.[ch]
 
 # host programs on Cygwin
 *.exe
@@ -46,7 +48,6 @@
 #
 # Generated files
 #
-/LOG
 /spl/
 /tpl/
 /defconfig
diff --git a/.travis.yml b/.travis.yml
index 937f028..7e90bc9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -87,9 +87,9 @@
     fi
   - if [[ "${TOOLCHAIN}" == "powerpc" ]]; then ./tools/buildman/buildman --fetch-arch powerpc; fi
   - if [[ "${TOOLCHAIN}" == "riscv" ]]; then
-        wget https://github.com/PkmX/riscv-prebuilt-toolchains/releases/download/20180111/riscv32-unknown-elf-toolchain.tar.gz &&
-        tar -C /tmp -xf riscv32-unknown-elf-toolchain.tar.gz &&
-        echo -e "\n[toolchain-prefix]\nriscv = /tmp/riscv32-unknown-elf/bin/riscv32-unknown-elf-" >> ~/.buildman;
+        wget https://github.com/andestech/prebuilt/releases/download/20180530/riscv64-unknown-linux-gnu.tar.gz &&
+        tar -C /tmp -xf riscv64-unknown-linux-gnu.tar.gz &&
+        echo -e "\n[toolchain-prefix]\nriscv = /tmp/riscv64-unknown-linux-gnu/bin/riscv64-unknown-linux-gnu-" >> ~/.buildman;
     fi
   - if [[ "${QEMU_TARGET}" != "" ]]; then
        git clone git://git.qemu.org/qemu.git /tmp/qemu;
diff --git a/MAINTAINERS b/MAINTAINERS
index 5670917..642c448 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -60,6 +60,7 @@
 L:	uboot-snps-arc@synopsys.com
 T:	git git://git.denx.de/u-boot-arc.git
 F:	arch/arc/
+F:	board/synopsys/
 
 ARC HSDK CGU CLOCK
 M:	Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
@@ -135,6 +136,7 @@
 T:	git git://git.denx.de/u-boot-marvell.git
 F:	arch/arm/mach-kirkwood/
 F:	arch/arm/mach-mvebu/
+F:	drivers/ata/ahci_mvebu.c
 
 ARM MARVELL PXA
 M:	Marek Vasut <marex@denx.de>
@@ -204,6 +206,7 @@
 S:	Maintained
 F:	arch/arm/mach-stm32mp
 F:	drivers/clk/clk_stm32mp1.c
+F:	drivers/misc/stm32mp_fuse.c
 F:	drivers/ram/stm32mp1/
 
 ARM STM STV0991
@@ -339,6 +342,7 @@
 M:	Alexander Graf <agraf@suse.de>
 S:	Maintained
 T:	git git://github.com/agraf/u-boot.git
+F:	doc/DocBook/efi.tmpl
 F:	doc/README.uefi
 F:	doc/README.iscsi
 F:	include/efi*
diff --git a/Makefile b/Makefile
index d08fb6a..4592564 100644
--- a/Makefile
+++ b/Makefile
@@ -353,9 +353,13 @@
 STRIP		= $(CROSS_COMPILE)strip
 OBJCOPY		= $(CROSS_COMPILE)objcopy
 OBJDUMP		= $(CROSS_COMPILE)objdump
+LEX		= flex
+YACC		= bison
 AWK		= awk
 PERL		= perl
 PYTHON		?= python
+PYTHON2		= python2
+PYTHON3		= python3
 DTC		?= $(objtree)/scripts/dtc/dtc
 CHECK		= sparse
 
@@ -378,7 +382,7 @@
 export ARCH CPU BOARD VENDOR SOC CPUDIR BOARDDIR
 export CONFIG_SHELL HOSTCC HOSTCFLAGS HOSTLDFLAGS CROSS_COMPILE AS LD CC
 export CPP AR NM LDR STRIP OBJCOPY OBJDUMP
-export MAKE AWK PERL PYTHON
+export MAKE LEX YACC AWK PERL PYTHON PYTHON2 PYTHON3
 export HOSTCXX HOSTCXXFLAGS CHECK CHECKFLAGS DTC DTC_FLAGS
 
 export KBUILD_CPPFLAGS NOSTDINC_FLAGS UBOOTINCLUDE OBJCOPYFLAGS LDFLAGS
@@ -514,7 +518,7 @@
 # if auto.conf.cmd is missing then we are probably in a cleaned tree so
 # we execute the config step to be sure to catch updated Kconfig files
 include/config/%.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd
-	$(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig
+	$(Q)$(MAKE) -f $(srctree)/Makefile syncconfig
 	@# If the following part fails, include/config/auto.conf should be
 	@# deleted so "make silentoldconfig" will be re-run on the next build.
 	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.autoconf || \
@@ -1617,10 +1621,12 @@
 		\( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
 		-o -name '*.ko.*' -o -name '*.su' -o -name '*.cfgtmp' \
 		-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
+		-o -name '*.lex.c' -o -name '*.tab.[ch]' \
 		-o -name '*.symtypes' -o -name 'modules.order' \
 		-o -name modules.builtin -o -name '.tmp_*.o.*' \
 		-o -name 'dsdt.aml' -o -name 'dsdt.asl.tmp' -o -name 'dsdt.c' \
-		-o -name '*.gcno' \) -type f -print | xargs rm -f
+		-o -name '*.efi' -o -name '*.gcno' -o -name '*.so' \) \
+		-type f -print | xargs rm -f
 
 # mrproper - Delete all generated files, including .config
 #
diff --git a/README b/README
index df1d5d6..fb331f9 100644
--- a/README
+++ b/README
@@ -331,11 +331,6 @@
 
 - Board Type:	Define exactly one, e.g. CONFIG_MPC8540ADS.
 
-- Marvell Family Member
-		CONFIG_SYS_MVFS		- define it if you want to enable
-					  multiple fs option at one time
-					  for marvell soc family
-
 - 85xx CPU Options:
 		CONFIG_SYS_PPC64
 
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index aee15d5..6f139d5 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -150,6 +150,10 @@
 config TARGET_AXS103
 	bool "Support Synopsys Designware SDP board AXS103"
 
+config TARGET_EMDK
+	bool "Synopsys EM Development kit"
+	select CPU_ARCEM6
+
 config TARGET_HSDK
 	bool "Support Synpsys HS DevelopmentKit board"
 
@@ -158,6 +162,7 @@
 source "board/abilis/tb100/Kconfig"
 source "board/synopsys/Kconfig"
 source "board/synopsys/axs10x/Kconfig"
+source "board/synopsys/emdk/Kconfig"
 source "board/synopsys/hsdk/Kconfig"
 
 endmenu
diff --git a/arch/arc/cpu/u-boot.lds b/arch/arc/cpu/u-boot.lds
index 73c642e..e12145c 100644
--- a/arch/arc/cpu/u-boot.lds
+++ b/arch/arc/cpu/u-boot.lds
@@ -5,13 +5,22 @@
 
 #include <config.h>
 
-OUTPUT_FORMAT("elf32-littlearc", "elf32-littlearc", "elf32-littlearc")
+OUTPUT_FORMAT("elf32-littlearc", "elf32-bigarc", "elf32-littlearc")
 OUTPUT_ARCH(arc)
 ENTRY(_start)
 SECTIONS
 {
 	. = CONFIG_SYS_TEXT_BASE;
 	__image_copy_start = .;
+	. = ALIGN(1024);
+	__ivt_start = .;
+	.ivt :
+	{
+		KEEP(*(.ivt))
+	}
+	__ivt_end = .;
+
+	. = ALIGN(1024);
 	__text_start = .;
 	.text :	{
 		arch/arc/lib/start.o (.text*)
@@ -19,14 +28,6 @@
 	}
 	__text_end = .;
 
-	. = ALIGN(1024);
-	__ivt_start = .;
-	.ivt :
-	{
-		*(.ivt)
-	}
-	__ivt_end = .;
-
 	. = ALIGN(4);
 	.rodata : {
 		*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
diff --git a/arch/arc/dts/Makefile b/arch/arc/dts/Makefile
index 6eccec9..491a4f4 100644
--- a/arch/arc/dts/Makefile
+++ b/arch/arc/dts/Makefile
@@ -4,6 +4,7 @@
 dtb-$(CONFIG_TARGET_AXS103) +=  axs103.dtb
 dtb-$(CONFIG_TARGET_NSIM) +=  nsim.dtb
 dtb-$(CONFIG_TARGET_TB100) +=  abilis_tb100.dtb
+dtb-$(CONFIG_TARGET_EMDK) +=  emdk.dtb
 dtb-$(CONFIG_TARGET_HSDK) +=  hsdk.dtb
 
 targets += $(dtb-y)
diff --git a/arch/arc/dts/emdk.dts b/arch/arc/dts/emdk.dts
new file mode 100644
index 0000000..5e853e3
--- /dev/null
+++ b/arch/arc/dts/emdk.dts
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Synopsys, Inc. All rights reserved.
+ */
+/dts-v1/;
+
+#include "skeleton.dtsi"
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	aliases {
+		console = &uart0;
+	};
+
+	cpu_card {
+		core_clk: core_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <40000000>;
+			u-boot,dm-pre-reloc;
+		};
+	};
+
+	uart0: serial0@f0004000 {
+		compatible = "snps,dw-apb-uart";
+		clock-frequency = <100000000>;
+		reg = <0xf0004000 0x1000>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+	};
+};
diff --git a/arch/arc/lib/cache.c b/arch/arc/lib/cache.c
index 6f52877..8c1cb6e 100644
--- a/arch/arc/lib/cache.c
+++ b/arch/arc/lib/cache.c
@@ -432,9 +432,16 @@
 	int dc_line_sz = 0, ic_line_sz = 0;
 	union bcr_di_cache ibcr, dbcr;
 
+	/*
+	 * We don't care much about I$ line length really as there're
+	 * no per-line ops on I$ instead we only do full invalidation of it
+	 * on occasion of relocation and right before jumping to the OS.
+	 * Still we check insane config with zero-encoded line length in
+	 * presense of version field in I$ BCR. Just in case.
+	 */
 	ibcr.word = read_aux_reg(ARC_BCR_IC_BUILD);
 	if (ibcr.fields.ver) {
-		gd->arch.l1_line_sz = ic_line_sz = 8 << ibcr.fields.line_len;
+		ic_line_sz = 8 << ibcr.fields.line_len;
 		if (!ic_line_sz)
 			panic("Instruction exists but line length is 0\n");
 	}
@@ -445,9 +452,6 @@
 		if (!dc_line_sz)
 			panic("Data cache exists but line length is 0\n");
 	}
-
-	if (ic_line_sz && dc_line_sz && (ic_line_sz != dc_line_sz))
-		panic("Instruction and data cache line lengths differ\n");
 }
 
 void cache_init(void)
diff --git a/arch/arc/lib/relocate.c b/arch/arc/lib/relocate.c
index a3b7428..4ffba84 100644
--- a/arch/arc/lib/relocate.c
+++ b/arch/arc/lib/relocate.c
@@ -8,7 +8,9 @@
 #include <asm-generic/sections.h>
 
 extern ulong __image_copy_start;
+extern ulong __ivt_start;
 extern ulong __ivt_end;
+extern ulong __text_end;
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -48,7 +50,7 @@
 	debug("Section .rela.dyn is located at %08x-%08x\n",
 	      (unsigned int)re_src, (unsigned int)re_end);
 
-	Elf32_Addr *offset_ptr_rom, *last_offset = NULL;
+	Elf32_Addr *offset_ptr_rom;
 	Elf32_Addr *offset_ptr_ram;
 
 	do {
@@ -57,15 +59,28 @@
 
 		/* Check that the location of the relocation is in .text */
 		if (offset_ptr_rom >= (Elf32_Addr *)&__image_copy_start &&
-		    offset_ptr_rom > last_offset) {
-			unsigned int val;
+		    offset_ptr_rom < (Elf32_Addr *)&__image_copy_end) {
+			unsigned int val, do_swap = 0;
 			/* Switch to the in-RAM version */
 			offset_ptr_ram = (Elf32_Addr *)((ulong)offset_ptr_rom +
 							gd->reloc_off);
 
-			debug("Patching value @ %08x (relocated to %08x)\n",
+#ifdef __LITTLE_ENDIAN__
+			/* If location in ".text" section swap value */
+			if (((u32)offset_ptr_rom >= (u32)&__text_start &&
+			     (u32)offset_ptr_rom <= (u32)&__text_end)
+#if defined(__ARC700__) || defined(__ARC600__)
+			    || ((u32)offset_ptr_rom >= (u32)&__ivt_start &&
+				(u32)offset_ptr_rom <= (u32)&__ivt_end)
+#endif
+			   )
+				do_swap = 1;
+#endif
+
+			debug("Patching value @ %08x (relocated to %08x)%s\n",
 			      (unsigned int)offset_ptr_rom,
-			      (unsigned int)offset_ptr_ram);
+			      (unsigned int)offset_ptr_ram,
+			      do_swap ? ", middle-endian encoded" : "");
 
 			/*
 			 * Use "memcpy" because target location might be
@@ -75,28 +90,45 @@
 			 */
 			memcpy(&val, offset_ptr_ram, sizeof(int));
 
-#ifdef __LITTLE_ENDIAN__
-			/* If location in ".text" section swap value */
-			if ((unsigned int)offset_ptr_rom <
-			    (unsigned int)&__ivt_end)
+			if (do_swap)
 				val = (val << 16) | (val >> 16);
-#endif
 
 			/* Check that the target points into executable */
-			if (val >= (unsigned int)&__image_copy_start && val <=
-			    (unsigned int)&__image_copy_end) {
-				val += gd->reloc_off;
-#ifdef __LITTLE_ENDIAN__
-				/* If location in ".text" section swap value */
-				if ((unsigned int)offset_ptr_rom <
-				    (unsigned int)&__ivt_end)
-					val = (val << 16) | (val >> 16);
-#endif
-				memcpy(offset_ptr_ram, &val, sizeof(int));
+			if (val < (unsigned int)&__image_copy_start ||
+			    val > (unsigned int)&__image_copy_end) {
+				/* TODO: Use panic() instead of debug()
+				 *
+				 * For some reason GCC might generate
+				 * fake relocation even for LD/SC of constant
+				 * inderectly. See an example below:
+				 * ----------------------->8--------------------
+				 * static int setup_mon_len(void)
+				 * {
+				 *         gd->mon_len = (ulong)&__bss_end - CONFIG_SYS_MONITOR_BASE;
+				 *         return 0;
+				 * }
+				 * ----------------------->8--------------------
+				 *
+				 * And that's what we get in the binary:
+				 * ----------------------->8--------------------
+				 * 10005cb4 <setup_mon_len>:
+				 * 10005cb4:       193c 3f80 0003 2f80     st      0x32f80,[r25,60]
+				 *                         10005cb8: R_ARC_RELATIVE        *ABS*-0x10000000
+				 * 10005cbc:       7fe0                    j_s.d   [blink]
+				 * 10005cbe:       700c                    mov_s   r0,0
+				 * ----------------------->8--------------------
+				 */
+				debug("Relocation target %08x points outside of image\n",
+				      val);
 			}
-		}
-		last_offset = offset_ptr_rom;
 
+			val += gd->reloc_off;
+
+			if (do_swap)
+				val = (val << 16) | (val >> 16);
+
+			memcpy(offset_ptr_ram, &val, sizeof(int));
+		}
 	} while (++re_src < re_end);
 
 	return 0;
diff --git a/arch/arc/lib/reset.c b/arch/arc/lib/reset.c
index 40fb0f1..02e08df 100644
--- a/arch/arc/lib/reset.c
+++ b/arch/arc/lib/reset.c
@@ -6,13 +6,17 @@
 #include <command.h>
 #include <common.h>
 
+__weak void reset_cpu(ulong addr)
+{
+	/* Stop debug session here */
+	__builtin_arc_brk();
+}
+
 int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 {
-	printf("Put your restart handler here\n");
+	printf("Resetting the board...\n");
 
-#ifdef DEBUG
-	/* Stop debug session here */
-	__asm__("brk");
-#endif
+	reset_cpu(0);
+
 	return 0;
 }
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0d1802b..dde422b 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1225,6 +1225,7 @@
 	select DM_SERIAL
 	select OF_CONTROL
 	select OF_LIBFDT
+	select MISC
 	select PINCTRL
 	select REGMAP
 	select SUPPORT_SPL
@@ -1257,9 +1258,7 @@
 	select DM_REGULATOR
 	select ENABLE_ARM_SOC_BOOT0_HOOK
 	select SPI
-	imply CMD_FASTBOOT
 	imply DISTRO_DEFAULTS
-	imply FASTBOOT
 	imply FAT_WRITE
 	imply USB_FUNCTION_FASTBOOT
 	imply SPL_SYSRESET
diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile
index 2605664..4f4647c 100644
--- a/arch/arm/cpu/armv7/Makefile
+++ b/arch/arm/cpu/armv7/Makefile
@@ -12,6 +12,10 @@
 
 obj-$(CONFIG_SYS_ARM_MPU) += mpu_v7r.o
 
+ifneq ($(CONFIG_SPL_BUILD),y)
+obj-$(CONFIG_EFI_LOADER) += sctlr.o
+endif
+
 ifneq ($(CONFIG_SKIP_LOWLEVEL_INIT),y)
 obj-y	+= lowlevel_init.o
 endif
diff --git a/arch/arm/cpu/armv7/sctlr.S b/arch/arm/cpu/armv7/sctlr.S
new file mode 100644
index 0000000..bd56e41
--- /dev/null
+++ b/arch/arm/cpu/armv7/sctlr.S
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier:     GPL-2.0+ */
+/*
+ *  Routines to access the system control register
+ *
+ *  Copyright (c) 2018 Heinrich Schuchardt
+ */
+
+#include <linux/linkage.h>
+
+/*
+ * void allow_unaligned(void) - allow unaligned access
+ *
+ * This routine clears the aligned flag in the system control register.
+ * After calling this routine unaligned access does no longer lead to a
+ * data abort but is handled by the CPU.
+ */
+ENTRY(allow_unaligned)
+	mrc	p15, 0, r0, c1, c0, 0	@ load system control register
+	bic	r0, r0, #2		@ clear aligned flag
+	mcr	p15, 0, r0, c1, c0, 0	@ write system control register
+	bx	lr			@ return
+ENDPROC(allow_unaligned)
diff --git a/arch/arm/cpu/armv8/zynqmp/clk.c b/arch/arm/cpu/armv8/zynqmp/clk.c
index 13e1977..0593b63 100644
--- a/arch/arm/cpu/armv8/zynqmp/clk.c
+++ b/arch/arm/cpu/armv8/zynqmp/clk.c
@@ -16,10 +16,6 @@
 	u32 ver = zynqmp_get_silicon_version();
 
 	switch (ver) {
-	case ZYNQMP_CSU_VERSION_VELOCE:
-		return 10000;
-	case ZYNQMP_CSU_VERSION_EP108:
-		return 4000000;
 	case ZYNQMP_CSU_VERSION_QEMU:
 		return 50000000;
 	}
@@ -40,11 +36,7 @@
 {
 	gd->cpu_clk = get_tbclk();
 
-	/* Support Veloce to show at least 1MHz via bdi */
-	if (gd->cpu_clk > 1000000)
-		gd->bd->bi_arm_freq = gd->cpu_clk / 1000000;
-	else
-		gd->bd->bi_arm_freq = 1;
+	gd->bd->bi_arm_freq = gd->cpu_clk / 1000000;
 
 	gd->bd->bi_dsp_freq = 0;
 
diff --git a/arch/arm/cpu/armv8/zynqmp/cpu.c b/arch/arm/cpu/armv8/zynqmp/cpu.c
index 2748d65..e122be5 100644
--- a/arch/arm/cpu/armv8/zynqmp/cpu.c
+++ b/arch/arm/cpu/armv8/zynqmp/cpu.c
@@ -135,12 +135,8 @@
 	gd->cpu_clk = get_tbclk();
 
 	switch (gd->cpu_clk) {
-	case 0 ... 1000000:
-		return ZYNQMP_CSU_VERSION_VELOCE;
 	case 50000000:
 		return ZYNQMP_CSU_VERSION_QEMU;
-	case 4000000:
-		return ZYNQMP_CSU_VERSION_EP108;
 	}
 
 	return ZYNQMP_CSU_VERSION_SILICON;
@@ -177,8 +173,8 @@
 
 #define ZYNQMP_SIP_SVC_GET_API_VERSION		0xC2000001
 
-#define ZYNQMP_PM_VERSION_MAJOR		0
-#define ZYNQMP_PM_VERSION_MINOR		3
+#define ZYNQMP_PM_VERSION_MAJOR		1
+#define ZYNQMP_PM_VERSION_MINOR		0
 #define ZYNQMP_PM_VERSION_MAJOR_SHIFT	16
 #define ZYNQMP_PM_VERSION_MINOR_MASK	0xFFFF
 
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 3efa3b9..790571b 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -130,6 +130,7 @@
 	zynq-cc108.dtb \
 	zynq-cse-qspi-single.dtb \
 	zynq-microzed.dtb \
+	zynq-minized.dtb \
 	zynq-picozed.dtb \
 	zynq-syzygy-hub.dtb \
 	zynq-topic-miami.dtb \
@@ -440,6 +441,7 @@
 	r8a7796-salvator-x.dtb \
 	r8a77965-salvator-x.dtb \
 	r8a77970-eagle.dtb \
+	r8a77990-ebisu.dtb \
 	r8a77995-draak.dtb
 
 dtb-$(CONFIG_SOC_KEYSTONE) += keystone-k2hk-evm.dtb \
diff --git a/arch/arm/dts/armada-8040-db.dts b/arch/arm/dts/armada-8040-db.dts
index fa58995..65b30bb 100644
--- a/arch/arm/dts/armada-8040-db.dts
+++ b/arch/arm/dts/armada-8040-db.dts
@@ -81,6 +81,13 @@
 		     1 3 0 0 0 0 0 0 0 3 >;
 };
 
+&ap_sdhci0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ap_emmc_pins>;
+	bus-width = <8>;
+	status = "okay";
+};
+
 &cpm_pinctl {
 	/* MPP Bus:
 	 *	[0-31]	= 0xff: Keep default CP0_shared_pins
@@ -182,6 +189,13 @@
 	status = "okay";
 };
 
+&cpm_sdhci0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&cpm_sdhci_pins>;
+	bus-width = <4>;
+	status = "okay";
+};
+
 &cps_pinctl {
 	/* MPP Bus:
 	 *	[0-11]	RGMII0
diff --git a/arch/arm/dts/armada-8040-mcbin.dts b/arch/arm/dts/armada-8040-mcbin.dts
index f912596..08f1d7d 100644
--- a/arch/arm/dts/armada-8040-mcbin.dts
+++ b/arch/arm/dts/armada-8040-mcbin.dts
@@ -154,6 +154,14 @@
 	status = "okay";
 };
 
+/* uSD slot */
+&cpm_sdhci0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&cpm_sdhci_pins>;
+	bus-width = <4>;
+	status = "okay";
+};
+
 &cpm_comphy {
 	/*
 	 * CP0 Serdes Configuration:
diff --git a/arch/arm/dts/armada-ap806.dtsi b/arch/arm/dts/armada-ap806.dtsi
index e0d3016..ebdee51 100644
--- a/arch/arm/dts/armada-ap806.dtsi
+++ b/arch/arm/dts/armada-ap806.dtsi
@@ -141,7 +141,7 @@
 			};
 
 			ap_pinctl: ap-pinctl@6F4000 {
-				compatible = "marvell,armada-ap806-pinctrl";
+				compatible = "marvell,ap806-pinctrl";
 				bank-name ="apn-806";
 				reg = <0x6F4000 0x10>;
 				pin-count = <20>;
diff --git a/arch/arm/dts/armada-cp110-master.dtsi b/arch/arm/dts/armada-cp110-master.dtsi
index 8c336f2..551d00d 100644
--- a/arch/arm/dts/armada-cp110-master.dtsi
+++ b/arch/arm/dts/armada-cp110-master.dtsi
@@ -120,8 +120,8 @@
 
 			cpm_pinctl: cpm-pinctl@440000 {
 				compatible = "marvell,mvebu-pinctrl",
-					     "marvell,a70x0-pinctrl",
-					     "marvell,a80x0-cp0-pinctrl";
+					     "marvell,armada-7k-pinctrl",
+					     "marvell,armada-8k-cpm-pinctrl";
 				bank-name ="cp0-110";
 				reg = <0x440000 0x20>;
 				pin-count = <63>;
diff --git a/arch/arm/dts/armada-cp110-slave.dtsi b/arch/arm/dts/armada-cp110-slave.dtsi
index 0cdb3d3..2ea9004 100644
--- a/arch/arm/dts/armada-cp110-slave.dtsi
+++ b/arch/arm/dts/armada-cp110-slave.dtsi
@@ -120,7 +120,7 @@
 
 			cps_pinctl: cps-pinctl@440000 {
 				compatible = "marvell,mvebu-pinctrl",
-					     "marvell,a80x0-cp1-pinctrl";
+					     "marvell,armada-8k-cps-pinctrl";
 				bank-name ="cp1-110";
 				reg = <0x440000 0x20>;
 				pin-count = <63>;
diff --git a/arch/arm/dts/bitmain-antminer-s9.dts b/arch/arm/dts/bitmain-antminer-s9.dts
new file mode 100644
index 0000000..7362ad4
--- /dev/null
+++ b/arch/arm/dts/bitmain-antminer-s9.dts
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Bitmain Antminer S9 board DTS
+ *
+ * Copyright (C) 2018 Michal Simek
+ * Copyright (C) 2018 VanguardiaSur
+ */
+/dts-v1/;
+#include "zynq-7000.dtsi"
+
+/ {
+	model = "Bitmain Antminer S9 Board";
+	compatible = "bitmain,antminer-s9", "xlnx,zynq-7000";
+
+	aliases {
+		ethernet0 = &gem0;
+		serial0 = &uart1;
+		mmc0 = &sdhci0;
+		gpio0 = &gpio0;
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x40000000>;
+	};
+
+	reserved-memory {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		bootcount@efffff0 {
+			reg = <0xefffff0 0x10>;
+			no-map;
+		};
+
+		fpga_space@f000000 {
+			reg = <0xf000000 0x1000000>;
+			no-map;
+		};
+	};
+
+	chosen {
+		bootargs = "earlycon";
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+&clkc {
+	ps-clk-frequency = <33333333>;
+};
+
+&gem0 {
+	status = "okay";
+	phy-mode = "rgmii-id";
+	phy-handle = <&ethernet_phy>;
+
+	/* 0362/5e62 */
+	ethernet_phy: ethernet-phy@1 {
+		reg = <1>;
+	};
+};
+
+&sdhci0 {
+	u-boot,dm-pre-reloc;
+	status = "okay";
+	disable-wp;
+};
+
+&uart1 {
+	u-boot,dm-pre-reloc;
+	status = "okay";
+};
+
+&watchdog0 {
+	reset-on-timeout;
+	timeout-sec = <200>;
+};
diff --git a/arch/arm/dts/dragonboard410c.dts b/arch/arm/dts/dragonboard410c.dts
index d9d5831..182a865 100644
--- a/arch/arm/dts/dragonboard410c.dts
+++ b/arch/arm/dts/dragonboard410c.dts
@@ -8,6 +8,7 @@
 /dts-v1/;
 
 #include "skeleton64.dtsi"
+#include <dt-bindings/pinctrl/pinctrl-snapdragon.h>
 
 / {
 	model = "Qualcomm Technologies, Inc. Dragonboard 410c";
@@ -38,6 +39,17 @@
 		ranges = <0x0 0x0 0x0 0xffffffff>;
 		compatible = "simple-bus";
 
+		pinctrl: qcom,tlmm@1000000 {
+			compatible = "qcom,tlmm-apq8016";
+			reg = <0x1000000 0x400000>;
+
+			blsp1_uart: uart {
+				function = "blsp1_uart";
+				pins = "GPIO_4", "GPIO_5";
+				drive-strength = <DRIVE_STRENGTH_8MA>;
+				bias-disable;
+			};
+		};
 		clkc: qcom,gcc@1800000 {
 			compatible = "qcom,gcc-apq8016";
 			reg = <0x1800000 0x80000>;
@@ -49,6 +61,8 @@
 			compatible = "qcom,msm-uartdm-v1.4";
 			reg = <0x78b0000 0x200>;
 			clock = <&clkc 4>;
+			pinctrl-names = "uart";
+			pinctrl-0 = <&blsp1_uart>;
 		};
 
 		soc_gpios: pinctrl@1000000 {
diff --git a/arch/arm/dts/dragonboard820c-uboot.dtsi b/arch/arm/dts/dragonboard820c-uboot.dtsi
index 88312b3..97394cc 100644
--- a/arch/arm/dts/dragonboard820c-uboot.dtsi
+++ b/arch/arm/dts/dragonboard820c-uboot.dtsi
@@ -5,6 +5,20 @@
  * (C) Copyright 2017 Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
  */
 
+/ {
+	soc {
+		u-boot,dm-pre-reloc;
+
+		clock-controller@300000 {
+			u-boot,dm-pre-reloc;
+		};
+
+		serial@75b0000 {
+			u-boot,dm-pre-reloc;
+			};
+		};
+};
+
 &pm8994_pon {
 	key_vol_down {
 		gpios = <&pm8994_pon 1 0>;
diff --git a/arch/arm/dts/dragonboard820c.dts b/arch/arm/dts/dragonboard820c.dts
index 7bfae1c..7457d7b 100644
--- a/arch/arm/dts/dragonboard820c.dts
+++ b/arch/arm/dts/dragonboard820c.dts
@@ -50,6 +50,7 @@
 		blsp2_uart1: serial@75b0000 {
 			compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
 			reg = <0x75b0000 0x1000>;
+			clock = <&gcc 4>;
 		};
 
 		sdhc2: sdhci@74a4900 {
diff --git a/arch/arm/dts/kirkwood-d2net.dts b/arch/arm/dts/kirkwood-d2net.dts
new file mode 100644
index 0000000..bd3b266
--- /dev/null
+++ b/arch/arm/dts/kirkwood-d2net.dts
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree file for d2 Network v2
+ *
+ * Copyright (C) 2014 Simon Guinot <simon.guinot@sequanux.org>
+ *
+*/
+
+/dts-v1/;
+
+#include <dt-bindings/leds/leds-ns2.h>
+#include "kirkwood-netxbig.dtsi"
+
+/ {
+	model = "LaCie d2 Network v2";
+	compatible = "lacie,d2net_v2", "lacie,netxbig", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x10000000>;
+	};
+
+	ns2-leds {
+		compatible = "lacie,ns2-leds";
+
+		blue-sata {
+			label = "d2net_v2:blue:sata";
+			slow-gpio = <&gpio0 29 GPIO_ACTIVE_HIGH>;
+			cmd-gpio = <&gpio0 30 GPIO_ACTIVE_HIGH>;
+			modes-map = <NS_V2_LED_OFF  1 0
+				     NS_V2_LED_ON   0 1
+				     NS_V2_LED_ON   1 1
+				     NS_V2_LED_SATA 0 0>;
+		};
+	};
+
+	gpio-leds {
+		compatible = "gpio-leds";
+
+		red-fail {
+			label = "d2net_v2:red:fail";
+			gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
diff --git a/arch/arm/dts/kirkwood-dreamplug.dts b/arch/arm/dts/kirkwood-dreamplug.dts
new file mode 100644
index 0000000..a647a65
--- /dev/null
+++ b/arch/arm/dts/kirkwood-dreamplug.dts
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+
+/ {
+	model = "Globalscale Technologies Dreamplug";
+	compatible = "globalscale,dreamplug-003-ds2001", "globalscale,dreamplug", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x20000000>;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200n8 earlyprintk";
+		stdout-path = &uart0;
+	};
+
+	ocp@f1000000 {
+		pinctrl: pin-controller@10000 {
+			pmx_led_bluetooth: pmx-led-bluetooth {
+				marvell,pins = "mpp47";
+				marvell,function = "gpio";
+			};
+			pmx_led_wifi: pmx-led-wifi {
+				marvell,pins = "mpp48";
+				marvell,function = "gpio";
+			};
+			pmx_led_wifi_ap: pmx-led-wifi-ap {
+				marvell,pins = "mpp49";
+				marvell,function = "gpio";
+			};
+		};
+		serial@12000 {
+			status = "ok";
+		};
+
+		spi@10600 {
+			status = "okay";
+
+			m25p40@0 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+				compatible = "mxicy,mx25l1606e", "jedec,spi-nor", "spi-flash";
+				reg = <0>;
+				spi-max-frequency = <50000000>;
+				mode = <0>;
+
+				partition@0 {
+					reg = <0x0 0x80000>;
+					label = "u-boot";
+				};
+
+				partition@100000 {
+					reg = <0x100000 0x10000>;
+					label = "u-boot env";
+				};
+
+				partition@180000 {
+					reg = <0x180000 0x10000>;
+					label = "dtb";
+				};
+			};
+		};
+
+		sata@80000 {
+			status = "okay";
+			nr-ports = <1>;
+		};
+
+		mvsdio@90000 {
+			pinctrl-0 = <&pmx_sdio>;
+			pinctrl-names = "default";
+			status = "okay";
+			/* No CD or WP GPIOs */
+			broken-cd;
+		};
+	};
+
+	gpio-leds {
+		compatible = "gpio-leds";
+		pinctrl-0 = <&pmx_led_bluetooth &pmx_led_wifi
+			     &pmx_led_wifi_ap >;
+		pinctrl-names = "default";
+
+		bluetooth {
+			label = "dreamplug:blue:bluetooth";
+			gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+		};
+		wifi {
+			label = "dreamplug:green:wifi";
+			gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
+		};
+		wifi-ap {
+			label = "dreamplug:green:wifi_ap";
+			gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&mdio {
+	status = "okay";
+
+	ethphy0: ethernet-phy@0 {
+		reg = <0>;
+	};
+
+	ethphy1: ethernet-phy@1 {
+		reg = <1>;
+	};
+};
+
+&eth0 {
+	status = "okay";
+	ethernet0-port@0 {
+		phy-handle = <&ethphy0>;
+	};
+};
+
+&eth1 {
+	status = "okay";
+	ethernet1-port@0 {
+		phy-handle = <&ethphy1>;
+	};
+};
diff --git a/arch/arm/dts/kirkwood-ds109.dts b/arch/arm/dts/kirkwood-ds109.dts
new file mode 100644
index 0000000..29982e7
--- /dev/null
+++ b/arch/arm/dts/kirkwood-ds109.dts
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+#include "kirkwood-synology.dtsi"
+
+/ {
+	model = "Synology DS109, DS110, DS110jv20";
+	compatible = "synology,ds109", "synology,ds110jv20",
+		     "synology,ds110", "marvell,kirkwood";
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x8000000>;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200n8";
+		stdout-path = &uart0;
+	};
+
+	gpio-fan-150-32-35 {
+		status = "okay";
+	};
+
+	gpio-leds-hdd-21-1 {
+		status = "okay";
+	};
+};
+
+&rs5c372 {
+	status = "okay";
+};
diff --git a/arch/arm/dts/kirkwood-is2.dts b/arch/arm/dts/kirkwood-is2.dts
new file mode 100644
index 0000000..1bc16a5
--- /dev/null
+++ b/arch/arm/dts/kirkwood-is2.dts
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+
+#include <dt-bindings/leds/leds-ns2.h>
+#include "kirkwood-ns2-common.dtsi"
+
+/ {
+	model = "LaCie Internet Space v2";
+	compatible = "lacie,inetspace_v2", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x8000000>;
+	};
+
+	ocp@f1000000 {
+		sata@80000 {
+			pinctrl-0 = <&pmx_ns2_sata0>;
+			pinctrl-names = "default";
+			status = "okay";
+			nr-ports = <1>;
+		};
+	};
+
+	ns2-leds {
+		compatible = "lacie,ns2-leds";
+
+		blue-sata {
+			label = "ns2:blue:sata";
+			slow-gpio = <&gpio0 29 0>;
+			cmd-gpio = <&gpio0 30 0>;
+			modes-map = <NS_V2_LED_OFF  1 0
+				     NS_V2_LED_ON   0 1
+				     NS_V2_LED_ON   1 1
+				     NS_V2_LED_SATA 0 0>;
+		};
+	};
+};
+
+&ethphy0 { reg = <8>; };
diff --git a/arch/arm/dts/kirkwood-km_common.dtsi b/arch/arm/dts/kirkwood-km_common.dtsi
new file mode 100644
index 0000000..75dc839
--- /dev/null
+++ b/arch/arm/dts/kirkwood-km_common.dtsi
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0
+/ {
+	chosen {
+		bootargs = "console=ttyS0,115200n8 earlyprintk";
+		stdout-path = &uart0;
+	};
+
+	ocp@f1000000 {
+		pinctrl: pin-controller@10000 {
+			pinctrl-0 = < &pmx_i2c_gpio_sda &pmx_i2c_gpio_scl >;
+			pinctrl-names = "default";
+
+			pmx_i2c_gpio_sda: pmx-gpio-sda {
+				marvell,pins = "mpp8";
+				marvell,function = "gpio";
+			};
+			pmx_i2c_gpio_scl: pmx-gpio-scl {
+				marvell,pins = "mpp9";
+				marvell,function = "gpio";
+			};
+		};
+
+		serial@12000 {
+			status = "okay";
+		};
+	};
+
+	i2c {
+		compatible = "i2c-gpio";
+		gpios = < &gpio0 8 GPIO_ACTIVE_HIGH		/* sda */
+			  &gpio0 9 GPIO_ACTIVE_HIGH>;		/* scl */
+		i2c-gpio,delay-us = <2>;	/* ~100 kHz */
+	};
+};
+
+&nand {
+	status = "okay";
+	chip-delay = <25>;
+};
+
+&pciec {
+        status = "okay";
+};
+
+&pcie0 {
+	status = "okay";
+};
diff --git a/arch/arm/dts/kirkwood-km_kirkwood.dts b/arch/arm/dts/kirkwood-km_kirkwood.dts
new file mode 100644
index 0000000..f035eff
--- /dev/null
+++ b/arch/arm/dts/kirkwood-km_kirkwood.dts
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-98dx4122.dtsi"
+#include "kirkwood-km_common.dtsi"
+
+/ {
+	model = "Keymile Kirkwood Reference Design";
+	compatible = "keymile,km_kirkwood", "marvell,kirkwood-98DX4122", "marvell,kirkwood";
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x08000000>;
+	};
+};
+
+&mdio {
+	status = "okay";
+
+	ethphy0: ethernet-phy@0 {
+		reg = <0>;
+	};
+};
+
+&eth0 {
+	status = "okay";
+	ethernet0-port@0 {
+		phy-handle = <&ethphy0>;
+	};
+};
diff --git a/arch/arm/dts/kirkwood-lschlv2.dts b/arch/arm/dts/kirkwood-lschlv2.dts
new file mode 100644
index 0000000..1d737d9
--- /dev/null
+++ b/arch/arm/dts/kirkwood-lschlv2.dts
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+
+#include "kirkwood-lsxl.dtsi"
+
+/ {
+	model = "Buffalo Linkstation LS-CHLv2";
+	compatible = "buffalo,lschlv2", "buffalo,lsxl", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x4000000>;
+	};
+
+	ocp@f1000000 {
+		serial@12000 {
+			status = "okay";
+		};
+	};
+};
diff --git a/arch/arm/dts/kirkwood-lsxhl.dts b/arch/arm/dts/kirkwood-lsxhl.dts
new file mode 100644
index 0000000..a56e0d7
--- /dev/null
+++ b/arch/arm/dts/kirkwood-lsxhl.dts
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+
+#include "kirkwood-lsxl.dtsi"
+
+/ {
+	model = "Buffalo Linkstation LS-XHL";
+	compatible = "buffalo,lsxhl", "buffalo,lsxl", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x10000000>;
+	};
+
+	ocp@f1000000 {
+		serial@12000 {
+			status = "okay";
+		};
+	};
+};
diff --git a/arch/arm/dts/kirkwood-lsxl.dtsi b/arch/arm/dts/kirkwood-lsxl.dtsi
new file mode 100644
index 0000000..92b11c7
--- /dev/null
+++ b/arch/arm/dts/kirkwood-lsxl.dtsi
@@ -0,0 +1,237 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+
+/ {
+	chosen {
+		bootargs = "console=ttyS0,115200n8 earlyprintk";
+		stdout-path = &uart0;
+	};
+
+	ocp@f1000000 {
+		pinctrl: pin-controller@10000 {
+			pmx_power_hdd: pmx-power-hdd {
+				marvell,pins = "mpp10";
+				marvell,function = "gpo";
+			};
+			pmx_usb_vbus: pmx-usb-vbus {
+				marvell,pins = "mpp11";
+				marvell,function = "gpio";
+			};
+			pmx_fan_high: pmx-fan-high {
+				marvell,pins = "mpp18";
+				marvell,function = "gpo";
+			};
+			pmx_fan_low: pmx-fan-low {
+				marvell,pins = "mpp19";
+				marvell,function = "gpo";
+			};
+			pmx_led_function_blue: pmx-led-function-blue {
+				marvell,pins = "mpp36";
+				marvell,function = "gpio";
+			};
+			pmx_led_alarm: pmx-led-alarm {
+				marvell,pins = "mpp37";
+				marvell,function = "gpio";
+			};
+			pmx_led_info: pmx-led-info {
+				marvell,pins = "mpp38";
+				marvell,function = "gpio";
+			};
+			pmx_led_power: pmx-led-power {
+				marvell,pins = "mpp39";
+				marvell,function = "gpio";
+			};
+			pmx_fan_lock: pmx-fan-lock {
+				marvell,pins = "mpp40";
+				marvell,function = "gpio";
+			};
+			pmx_button_function: pmx-button-function {
+				marvell,pins = "mpp41";
+				marvell,function = "gpio";
+			};
+			pmx_power_switch: pmx-power-switch {
+				marvell,pins = "mpp42";
+				marvell,function = "gpio";
+			};
+			pmx_power_auto_switch: pmx-power-auto-switch {
+				marvell,pins = "mpp43";
+				marvell,function = "gpio";
+			};
+			pmx_led_function_red: pmx-led-function_red {
+				marvell,pins = "mpp48";
+				marvell,function = "gpio";
+			};
+
+		};
+		sata@80000 {
+			status = "okay";
+			nr-ports = <1>;
+		};
+
+		spi@10600 {
+			status = "okay";
+
+			m25p40@0 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+				compatible = "m25p40", "jedec,spi-nor", "spi-flash";
+				reg = <0>;
+				spi-max-frequency = <25000000>;
+				mode = <0>;
+
+				partition@0 {
+					reg = <0x0 0x60000>;
+					label = "uboot";
+					read-only;
+				};
+
+				partition@60000 {
+					reg = <0x60000 0x10000>;
+					label = "dtb";
+					read-only;
+				};
+
+				partition@70000 {
+					reg = <0x70000 0x10000>;
+					label = "uboot_env";
+				};
+			};
+		};
+	};
+
+	gpio_keys {
+		compatible = "gpio-keys";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		pinctrl-0 = <&pmx_button_function &pmx_power_switch
+			     &pmx_power_auto_switch>;
+		pinctrl-names = "default";
+
+		option {
+			label = "Function Button";
+			linux,code = <KEY_OPTION>;
+			gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
+		};
+		reserved {
+			label = "Power-on Switch";
+			linux,code = <KEY_RESERVED>;
+			linux,input-type = <5>;
+			gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
+		};
+		power {
+			label = "Power-auto Switch";
+			linux,code = <KEY_ESC>;
+			linux,input-type = <5>;
+			gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	gpio_leds {
+		compatible = "gpio-leds";
+		pinctrl-0 = <&pmx_led_function_red &pmx_led_alarm
+			     &pmx_led_info &pmx_led_power
+			     &pmx_led_function_blue>;
+		pinctrl-names = "default";
+
+		func_blue {
+			label = "lsxl:blue:func";
+			gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
+		};
+
+		alarm {
+			label = "lsxl:red:alarm";
+			gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
+		};
+
+		info {
+			label = "lsxl:amber:info";
+			gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
+		};
+
+		power {
+			label = "lsxl:blue:power";
+			gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
+			default-state = "keep";
+		};
+
+		func_red {
+			label = "lsxl:red:func";
+			gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	gpio_fan {
+		compatible = "gpio-fan";
+		pinctrl-0 = <&pmx_fan_low &pmx_fan_high &pmx_fan_lock>;
+		pinctrl-names = "default";
+		gpios = <&gpio0 19 GPIO_ACTIVE_LOW
+		         &gpio0 18 GPIO_ACTIVE_LOW>;
+		gpio-fan,speed-map = <0    3
+		                      1500 2
+		                      3250 1
+		                      5000 0>;
+		alarm-gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
+	};
+
+	restart_poweroff {
+		compatible = "restart-poweroff";
+	};
+
+	regulators {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		pinctrl-0 = <&pmx_power_hdd &pmx_usb_vbus>;
+		pinctrl-names = "default";
+
+		usb_power: regulator@1 {
+			compatible = "regulator-fixed";
+			reg = <1>;
+			regulator-name = "USB Power";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			gpio = <&gpio0 11 0>;
+		};
+		hdd_power: regulator@2 {
+			compatible = "regulator-fixed";
+			reg = <2>;
+			regulator-name = "HDD Power";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			gpio = <&gpio0 10 0>;
+		};
+	};
+};
+
+&mdio {
+	status = "okay";
+
+	ethphy0: ethernet-phy@0 {
+		reg = <0>;
+	};
+
+	ethphy1: ethernet-phy@8 {
+		reg = <8>;
+	};
+};
+
+&eth0 {
+	status = "okay";
+	ethernet0-port@0 {
+		phy-handle = <&ethphy0>;
+	};
+};
+
+&eth1 {
+	status = "okay";
+	ethernet1-port@0 {
+		phy-handle = <&ethphy1>;
+	};
+};
diff --git a/arch/arm/dts/kirkwood-net2big.dts b/arch/arm/dts/kirkwood-net2big.dts
new file mode 100644
index 0000000..3e3ac28
--- /dev/null
+++ b/arch/arm/dts/kirkwood-net2big.dts
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree file for LaCie 2Big Network v2
+ *
+ * Copyright (C) 2014
+ *
+ * Andrew Lunn <andrew@lunn.ch>
+ *
+ * Based on netxbig_v2-setup.c,
+ * Copyright (C) 2010 Simon Guinot <sguinot@lacie.com>
+ *
+*/
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+#include "kirkwood-netxbig.dtsi"
+
+/ {
+	model = "LaCie 2Big Network v2";
+	compatible = "lacie,net2big_v2", "lacie,netxbig", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x10000000>;
+	};
+
+	fan {
+		compatible = "gpio-fan";
+		alarm-gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&regulators {
+	regulator@2 {
+		compatible = "regulator-fixed";
+		reg = <2>;
+		regulator-name = "hdd1power";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		enable-active-high;
+		regulator-always-on;
+		regulator-boot-on;
+		gpio = <&gpio0 17 GPIO_ACTIVE_HIGH>;
+	};
+
+	clocks {
+	       g762_clk: g762-oscillator {
+			 compatible = "fixed-clock";
+			 #clock-cells = <0>;
+			 clock-frequency = <32768>;
+	       };
+	};
+};
+
+&i2c0 {
+	g762@3e {
+		compatible = "gmt,g762";
+		reg = <0x3e>;
+		clocks = <&g762_clk>;
+	};
+};
diff --git a/arch/arm/dts/kirkwood-netxbig.dtsi b/arch/arm/dts/kirkwood-netxbig.dtsi
new file mode 100644
index 0000000..135ac80
--- /dev/null
+++ b/arch/arm/dts/kirkwood-netxbig.dtsi
@@ -0,0 +1,232 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree common file for LaCie 2Big and 5Big Network v2
+ *
+ * Copyright (C) 2014
+ *
+ * Andrew Lunn <andrew@lunn.ch>
+ *
+ * Based on netxbig_v2-setup.c,
+ * Copyright (C) 2010 Simon Guinot <sguinot@lacie.com>
+ *
+*/
+
+#include <dt-bindings/leds/leds-netxbig.h>
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+
+/ {
+	chosen {
+		bootargs = "console=ttyS0,115200n8";
+		stdout-path = &uart0;
+	};
+
+	ocp@f1000000 {
+		serial@12000 {
+			status = "okay";
+		};
+
+		spi@10600 {
+			status = "okay";
+
+			flash@0 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+				compatible = "mxicy,mx25l4005a", "jedec,spi-nor", "spi-flash";
+				reg = <0>;
+				spi-max-frequency = <20000000>;
+				mode = <0>;
+
+				partition@0 {
+					reg = <0x0 0x80000>;
+					label = "u-boot";
+				};
+			};
+		};
+
+		sata@80000 {
+			status = "okay";
+			nr-ports = <2>;
+		};
+
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		/*
+		 * esc and power represent a three position rocker
+		 * switch. Thus the conventional KEY_POWER does not fit
+		 */
+		exc {
+			label = "Back power switch (on|auto)";
+			linux,code = <KEY_ESC>;
+			linux,input-type = <5>;
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+		power {
+			label = "Back power switch (auto|off)";
+			linux,code = <KEY_1>;
+			linux,input-type = <5>;
+			gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
+		};
+		option {
+			label = "Function button";
+			linux,code = <KEY_OPTION>;
+			gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+		};
+
+	};
+
+	gpio-poweroff {
+		compatible = "gpio-poweroff";
+		gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
+	};
+
+	regulators: regulators {
+		status = "okay";
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		pinctrl-names = "default";
+
+		regulator@1 {
+			compatible = "regulator-fixed";
+			reg = <1>;
+			regulator-name = "hdd0power";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			gpio = <&gpio0 16 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	netxbig_gpio_ext: netxbig-gpio-ext {
+		compatible = "lacie,netxbig-gpio-ext";
+
+		addr-gpios = <&gpio1 15 GPIO_ACTIVE_HIGH
+			      &gpio1 16 GPIO_ACTIVE_HIGH
+			      &gpio1 17 GPIO_ACTIVE_HIGH>;
+		data-gpios = <&gpio1 12 GPIO_ACTIVE_HIGH
+			      &gpio1 13 GPIO_ACTIVE_HIGH
+			      &gpio1 14 GPIO_ACTIVE_HIGH>;
+		enable-gpio = <&gpio0 29 GPIO_ACTIVE_HIGH>;
+	};
+
+	netxbig-leds {
+		compatible = "lacie,netxbig-leds";
+
+		gpio-ext = <&netxbig_gpio_ext>;
+
+		timers = <NETXBIG_LED_TIMER1 500 500
+			  NETXBIG_LED_TIMER2 500 1000>;
+
+		blue-power {
+			label = "netxbig:blue:power";
+			mode-addr = <0>;
+			mode-val = <NETXBIG_LED_OFF 0
+				    NETXBIG_LED_ON 1
+				    NETXBIG_LED_TIMER1 3
+				    NETXBIG_LED_TIMER2 7>;
+			bright-addr = <1>;
+			max-brightness = <7>;
+		};
+		red-power {
+			label = "netxbig:red:power";
+			mode-addr = <0>;
+			mode-val = <NETXBIG_LED_OFF 0
+				    NETXBIG_LED_ON 2
+				    NETXBIG_LED_TIMER1 4>;
+			bright-addr = <1>;
+			max-brightness = <7>;
+		};
+		blue-sata0 {
+			label = "netxbig:blue:sata0";
+			mode-addr = <3>;
+			mode-val = <NETXBIG_LED_OFF 0
+				    NETXBIG_LED_ON 7
+				    NETXBIG_LED_SATA 1
+				    NETXBIG_LED_TIMER1 3>;
+			bright-addr = <2>;
+			max-brightness = <7>;
+		};
+		red-sata0 {
+			label = "netxbig:red:sata0";
+			mode-addr = <3>;
+			mode-val = <NETXBIG_LED_OFF 0
+				    NETXBIG_LED_ON 2
+				    NETXBIG_LED_TIMER1 4>;
+			bright-addr = <2>;
+			max-brightness = <7>;
+		};
+		blue-sata1 {
+			label = "netxbig:blue:sata1";
+			mode-addr = <4>;
+			mode-val = <NETXBIG_LED_OFF 0
+				    NETXBIG_LED_ON 7
+				    NETXBIG_LED_SATA 1
+				    NETXBIG_LED_TIMER1 3>;
+			bright-addr = <2>;
+			max-brightness = <7>;
+		};
+		red-sata1 {
+			label = "netxbig:red:sata1";
+			mode-addr = <4>;
+			mode-val = <NETXBIG_LED_OFF 0
+				    NETXBIG_LED_ON 2
+				    NETXBIG_LED_TIMER1 4>;
+			bright-addr = <2>;
+			max-brightness = <7>;
+		};
+	};
+};
+
+&mdio {
+	status = "okay";
+
+	ethphy0: ethernet-phy@0 {
+		reg = <8>;
+	};
+
+	ethphy1: ethernet-phy@1 {
+		reg = <0>;
+	};
+};
+
+&eth0 {
+	status = "okay";
+	ethernet0-port@0 {
+		phy-handle = <&ethphy0>;
+	};
+};
+
+&pinctrl {
+	pinctrl-names = "default";
+
+	pmx_button_function: pmx-button-function {
+		marvell,pins = "mpp34";
+		marvell,function = "gpio";
+	};
+	pmx_button_power_off: pmx-button-power-off {
+		marvell,pins = "mpp15";
+		marvell,function = "gpio";
+	};
+	pmx_button_power_on: pmx-button-power-on {
+		marvell,pins = "mpp13";
+		marvell,function = "gpio";
+	};
+};
+
+&i2c0 {
+	status = "okay";
+
+	eeprom@50 {
+		compatible = "atmel,24c04";
+		pagesize = <16>;
+		reg = <0x50>;
+	};
+};
diff --git a/arch/arm/dts/kirkwood-ns2-common.dtsi b/arch/arm/dts/kirkwood-ns2-common.dtsi
new file mode 100644
index 0000000..f997bb4
--- /dev/null
+++ b/arch/arm/dts/kirkwood-ns2-common.dtsi
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+
+/ {
+	chosen {
+		bootargs = "console=ttyS0,115200n8";
+		stdout-path = &uart0;
+	};
+
+	ocp@f1000000 {
+		pinctrl: pin-controller@10000 {
+			pmx_ns2_sata0: pmx-ns2-sata0 {
+				marvell,pins = "mpp21";
+				marvell,function = "sata0";
+			};
+			pmx_ns2_sata1: pmx-ns2-sata1 {
+				marvell,pins = "mpp20";
+				marvell,function = "sata1";
+			};
+		};
+
+		serial@12000 {
+			status = "okay";
+		};
+
+		spi@10600 {
+			status = "okay";
+
+			flash@0 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+				compatible = "mxicy,mx25l4005a", "jedec,spi-nor", "spi-flash";
+				reg = <0>;
+				spi-max-frequency = <20000000>;
+				mode = <0>;
+
+				partition@0 {
+					reg = <0x0 0x80000>;
+					label = "u-boot";
+				};
+			};
+		};
+
+		i2c@11000 {
+			status = "okay";
+
+			eeprom@50 {
+				compatible = "atmel,24c04";
+				pagesize = <16>;
+				reg = <0x50>;
+			};
+		};
+	};
+
+	gpio_keys {
+		compatible = "gpio-keys";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		power {
+			label = "Power push button";
+			linux,code = <KEY_POWER>;
+			gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	gpio-leds {
+		compatible = "gpio-leds";
+
+		red-fail {
+			label = "ns2:red:fail";
+			gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	gpio_poweroff {
+		compatible = "gpio-poweroff";
+		gpios = <&gpio0 31 GPIO_ACTIVE_HIGH>;
+	};
+
+};
+
+&mdio {
+	status = "okay";
+
+	ethphy0: ethernet-phy@X {
+                /* overwrite reg property in board file */
+	};
+};
+
+&eth0 {
+	status = "okay";
+	ethernet0-port@0 {
+		phy-handle = <&ethphy0>;
+	};
+};
diff --git a/arch/arm/dts/kirkwood-ns2.dts b/arch/arm/dts/kirkwood-ns2.dts
new file mode 100644
index 0000000..7b67083
--- /dev/null
+++ b/arch/arm/dts/kirkwood-ns2.dts
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+
+#include <dt-bindings/leds/leds-ns2.h>
+#include "kirkwood-ns2-common.dtsi"
+
+/ {
+	model = "LaCie Network Space v2";
+	compatible = "lacie,netspace_v2", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x10000000>;
+	};
+
+	ocp@f1000000 {
+		sata@80000 {
+			pinctrl-0 = <&pmx_ns2_sata0>;
+			pinctrl-names = "default";
+			status = "okay";
+			nr-ports = <1>;
+		};
+	};
+
+	ns2-leds {
+		compatible = "lacie,ns2-leds";
+
+		blue-sata {
+			label = "ns2:blue:sata";
+			slow-gpio = <&gpio0 29 0>;
+			cmd-gpio = <&gpio0 30 0>;
+			modes-map = <NS_V2_LED_OFF  1 0
+				     NS_V2_LED_ON   0 1
+				     NS_V2_LED_ON   1 1
+				     NS_V2_LED_SATA 0 0>;
+		};
+	};
+};
+
+&ethphy0 { reg = <8>; };
diff --git a/arch/arm/dts/kirkwood-ns2lite.dts b/arch/arm/dts/kirkwood-ns2lite.dts
new file mode 100644
index 0000000..b0cb590
--- /dev/null
+++ b/arch/arm/dts/kirkwood-ns2lite.dts
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+
+#include "kirkwood-ns2-common.dtsi"
+
+/ {
+	model = "LaCie Network Space Lite v2";
+	compatible = "lacie,netspace_lite_v2", "marvell,kirkwood-88f6192", "marvell,kirkwood";
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x8000000>;
+	};
+
+	ocp@f1000000 {
+		sata@80000 {
+			pinctrl-0 = <&pmx_ns2_sata0>;
+			pinctrl-names = "default";
+			status = "okay";
+			nr-ports = <1>;
+		};
+	};
+
+	gpio-leds {
+		compatible = "gpio-leds";
+
+		blue-sata {
+			label = "ns2:blue:sata";
+			gpios = <&gpio0 30 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "disk-activity";
+		};
+	};
+};
+
+&ethphy0 { reg = <0>; };
diff --git a/arch/arm/dts/kirkwood-ns2max.dts b/arch/arm/dts/kirkwood-ns2max.dts
new file mode 100644
index 0000000..c0a087e
--- /dev/null
+++ b/arch/arm/dts/kirkwood-ns2max.dts
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+
+#include <dt-bindings/leds/leds-ns2.h>
+#include "kirkwood-ns2-common.dtsi"
+
+/ {
+	model = "LaCie Network Space Max v2";
+	compatible = "lacie,netspace_max_v2", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x10000000>;
+	};
+
+	ocp@f1000000 {
+		sata@80000 {
+			pinctrl-0 = <&pmx_ns2_sata0 &pmx_ns2_sata1>;
+			pinctrl-names = "default";
+			status = "okay";
+			nr-ports = <2>;
+		};
+	};
+
+	gpio_fan {
+		compatible = "gpio-fan";
+		gpios = <&gpio0 22 GPIO_ACTIVE_LOW
+			 &gpio0  7 GPIO_ACTIVE_LOW
+			 &gpio1  1 GPIO_ACTIVE_LOW
+			 &gpio0 23 GPIO_ACTIVE_LOW>;
+		gpio-fan,speed-map =
+			<   0  0
+			 1500 15
+			 1700 14
+			 1800 13
+			 2100 12
+			 3100 11
+			 3300 10
+			 4300  9
+			 5500  8>;
+		alarm-gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
+	};
+
+	ns2-leds {
+		compatible = "lacie,ns2-leds";
+
+		blue-sata {
+			label = "ns2:blue:sata";
+			slow-gpio = <&gpio0 29 0>;
+			cmd-gpio = <&gpio0 30 0>;
+			modes-map = <NS_V2_LED_OFF  1 0
+				     NS_V2_LED_ON   0 1
+				     NS_V2_LED_ON   1 1
+				     NS_V2_LED_SATA 0 0>;
+		};
+	};
+};
+
+&ethphy0 { reg = <8>; };
diff --git a/arch/arm/dts/kirkwood-ns2mini.dts b/arch/arm/dts/kirkwood-ns2mini.dts
new file mode 100644
index 0000000..5b9fa14
--- /dev/null
+++ b/arch/arm/dts/kirkwood-ns2mini.dts
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+
+#include <dt-bindings/leds/leds-ns2.h>
+#include "kirkwood-ns2-common.dtsi"
+
+/ {
+	/* This machine is embedded in the first LaCie CloudBox product. */
+	model = "LaCie Network Space Mini v2";
+	compatible = "lacie,netspace_mini_v2", "marvell,kirkwood-88f6192", "marvell,kirkwood";
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x8000000>;
+	};
+
+	ocp@f1000000 {
+		sata@80000 {
+			pinctrl-0 = <&pmx_ns2_sata0>;
+			pinctrl-names = "default";
+			status = "okay";
+			nr-ports = <1>;
+		};
+	};
+
+	gpio_fan {
+		compatible = "gpio-fan";
+		gpios = <&gpio0 22 GPIO_ACTIVE_LOW
+			 &gpio0  7 GPIO_ACTIVE_LOW
+			 &gpio1  1 GPIO_ACTIVE_LOW
+			 &gpio0 23 GPIO_ACTIVE_LOW>;
+		gpio-fan,speed-map =
+			<   0  0
+			 3000 15
+			 3180 14
+			 4140 13
+			 4570 12
+			 6760 11
+			 7140 10
+			 7980  9
+			 9200  8>;
+		alarm-gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
+	};
+
+	ns2-leds {
+		compatible = "lacie,ns2-leds";
+
+		blue-sata {
+			label = "ns2:blue:sata";
+			slow-gpio = <&gpio0 29 0>;
+			cmd-gpio = <&gpio0 30 0>;
+			modes-map = <NS_V2_LED_OFF  1 0
+				     NS_V2_LED_ON   0 1
+				     NS_V2_LED_ON   1 1
+				     NS_V2_LED_SATA 0 0>;
+		};
+	};
+};
+
+&ethphy0 { reg = <0>; };
diff --git a/arch/arm/dts/kirkwood-synology.dtsi b/arch/arm/dts/kirkwood-synology.dtsi
new file mode 100644
index 0000000..b80d8ee
--- /dev/null
+++ b/arch/arm/dts/kirkwood-synology.dtsi
@@ -0,0 +1,855 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Nodes for Marvell 628x Synology devices
+ *
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ */
+
+/ {
+	ocp@f1000000 {
+		pinctrl: pin-controller@10000 {
+			pmx_alarmled_12: pmx-alarmled-12 {
+				marvell,pins = "mpp12";
+				marvell,function = "gpio";
+			};
+
+			pmx_fanctrl_15: pmx-fanctrl-15 {
+				marvell,pins = "mpp15";
+				marvell,function = "gpio";
+			};
+
+			pmx_fanctrl_16: pmx-fanctrl-16 {
+				marvell,pins = "mpp16";
+				marvell,function = "gpio";
+			};
+
+			pmx_fanctrl_17: pmx-fanctrl-17 {
+				marvell,pins = "mpp17";
+				marvell,function = "gpio";
+			};
+
+			pmx_fanalarm_18: pmx-fanalarm-18 {
+				marvell,pins = "mpp18";
+				marvell,function = "gpo";
+			};
+
+			pmx_hddled_20: pmx-hddled-20 {
+				marvell,pins = "mpp20";
+				marvell,function = "gpio";
+			};
+
+			pmx_hddled_21: pmx-hddled-21 {
+				marvell,pins = "mpp21";
+				marvell,function = "gpio";
+			};
+
+			pmx_hddled_22: pmx-hddled-22 {
+				marvell,pins = "mpp22";
+				marvell,function = "gpio";
+			};
+
+			pmx_hddled_23: pmx-hddled-23 {
+				marvell,pins = "mpp23";
+				marvell,function = "gpio";
+			};
+
+			pmx_hddled_24: pmx-hddled-24 {
+				marvell,pins = "mpp24";
+				marvell,function = "gpio";
+			};
+
+			pmx_hddled_25: pmx-hddled-25 {
+				marvell,pins = "mpp25";
+				marvell,function = "gpio";
+			};
+
+			pmx_hddled_26: pmx-hddled-26 {
+				marvell,pins = "mpp26";
+				marvell,function = "gpio";
+			};
+
+			pmx_hddled_27: pmx-hddled-27 {
+				marvell,pins = "mpp27";
+				marvell,function = "gpio";
+			};
+
+			pmx_hddled_28: pmx-hddled-28 {
+				marvell,pins = "mpp28";
+				marvell,function = "gpio";
+			};
+
+			pmx_hdd1_pwr_29: pmx-hdd1-pwr-29 {
+				marvell,pins = "mpp29";
+				marvell,function = "gpio";
+			};
+
+			pmx_hdd1_pwr_30: pmx-hdd-pwr-30 {
+				marvell,pins = "mpp30";
+				marvell,function = "gpio";
+			};
+
+			pmx_hdd2_pwr_31: pmx-hdd2-pwr-31 {
+				marvell,pins = "mpp31";
+				marvell,function = "gpio";
+			};
+
+			pmx_fanctrl_32: pmx-fanctrl-32 {
+				marvell,pins = "mpp32";
+				marvell,function = "gpio";
+			};
+
+			pmx_fanctrl_33: pmx-fanctrl-33 {
+				marvell,pins = "mpp33";
+				marvell,function = "gpo";
+			};
+
+			pmx_fanctrl_34: pmx-fanctrl-34 {
+				marvell,pins = "mpp34";
+				marvell,function = "gpio";
+			};
+
+			pmx_hdd2_pwr_34: pmx-hdd2-pwr-34 {
+				marvell,pins = "mpp34";
+				marvell,function = "gpio";
+			};
+
+			pmx_fanalarm_35: pmx-fanalarm-35 {
+				marvell,pins = "mpp35";
+				marvell,function = "gpio";
+			};
+
+			pmx_hddled_36: pmx-hddled-36 {
+				marvell,pins = "mpp36";
+				marvell,function = "gpio";
+			};
+
+			pmx_hddled_37: pmx-hddled-37 {
+				marvell,pins = "mpp37";
+				marvell,function = "gpio";
+			};
+
+			pmx_hddled_38: pmx-hddled-38 {
+				marvell,pins = "mpp38";
+				marvell,function = "gpio";
+			};
+
+			pmx_hddled_39: pmx-hddled-39 {
+				marvell,pins = "mpp39";
+				marvell,function = "gpio";
+			};
+
+			pmx_hddled_40: pmx-hddled-40 {
+				marvell,pins = "mpp40";
+				marvell,function = "gpio";
+			};
+
+			pmx_hddled_41: pmx-hddled-41 {
+				marvell,pins = "mpp41";
+				marvell,function = "gpio";
+			};
+
+			pmx_hddled_42: pmx-hddled-42 {
+				marvell,pins = "mpp42";
+				marvell,function = "gpio";
+			};
+
+			pmx_hddled_43: pmx-hddled-43 {
+				marvell,pins = "mpp43";
+				marvell,function = "gpio";
+			};
+
+			pmx_hddled_44: pmx-hddled-44 {
+				marvell,pins = "mpp44";
+				marvell,function = "gpio";
+			};
+
+			pmx_hddled_45: pmx-hddled-45 {
+				marvell,pins = "mpp45";
+				marvell,function = "gpio";
+			};
+
+			pmx_hdd3_pwr_44: pmx-hdd3-pwr-44 {
+				marvell,pins = "mpp44";
+				marvell,function = "gpio";
+			};
+
+			pmx_hdd4_pwr_45: pmx-hdd4-pwr-45 {
+				marvell,pins = "mpp45";
+				marvell,function = "gpio";
+			};
+
+			pmx_fanalarm_44: pmx-fanalarm-44 {
+				marvell,pins = "mpp44";
+				marvell,function = "gpio";
+			};
+
+			pmx_fanalarm_45: pmx-fanalarm-45 {
+				marvell,pins = "mpp45";
+				marvell,function = "gpio";
+			};
+		};
+
+		rtc@10300 {
+			status = "disabled";
+		};
+
+		spi@10600 {
+			status = "okay";
+
+			m25p80@0 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+				compatible = "st,m25p80", "jedec,spi-nor", "spi-flash";
+				reg = <0>;
+				spi-max-frequency = <20000000>;
+				mode = <0>;
+
+				partition@0 {
+					reg = <0x00000000 0x00080000>;
+					label = "RedBoot";
+				};
+
+				partition@80000 {
+					reg = <0x00080000 0x00200000>;
+					label = "zImage";
+				};
+
+				partition@280000 {
+					reg = <0x00280000 0x00140000>;
+					label = "rd.gz";
+				};
+
+				partition@3c0000 {
+					reg = <0x003c0000 0x00010000>;
+					label = "vendor";
+				};
+
+				partition@3d0000 {
+					reg = <0x003d0000 0x00020000>;
+					label = "RedBoot config";
+				};
+
+				partition@3f0000 {
+					reg = <0x003f0000 0x00010000>;
+					label = "FIS directory";
+				};
+			};
+		};
+
+		i2c@11000 {
+			status = "okay";
+			clock-frequency = <400000>;
+
+			rs5c372: rs5c372@32 {
+				status = "disabled";
+				compatible = "ricoh,rs5c372";
+				reg = <0x32>;
+			};
+
+			s35390a: s35390a@30 {
+				status = "disabled";
+				compatible = "sii,s35390a";
+				reg = <0x30>;
+			};
+		};
+
+		serial@12000 {
+			status = "okay";
+		};
+
+		serial@12100 {
+			status = "okay";
+		};
+
+		poweroff@12100 {
+			compatible = "synology,power-off";
+			reg = <0x12100 0x100>;
+			clocks = <&gate_clk 7>;
+		};
+
+		sata@80000 {
+			pinctrl-0 = <&pmx_sata0 &pmx_sata1>;
+			pinctrl-names = "default";
+			status = "okay";
+			nr-ports = <2>;
+		};
+	};
+
+	gpio-fan-150-32-35 {
+		status = "disabled";
+		compatible = "gpio-fan";
+		pinctrl-0 = <&pmx_fanctrl_32 &pmx_fanctrl_33 &pmx_fanctrl_34
+		             &pmx_fanalarm_35>;
+		pinctrl-names = "default";
+		gpios = <&gpio1 0 GPIO_ACTIVE_HIGH
+			 &gpio1 1 GPIO_ACTIVE_HIGH
+			 &gpio1 2 GPIO_ACTIVE_HIGH>;
+		gpio-fan,speed-map = <    0 0
+				       2200 1
+				       2500 2
+				       3000 4
+				       3300 3
+				       3700 5
+				       3800 6
+				       4200 7 >;
+	};
+
+	gpio-fan-150-15-18 {
+		status = "disabled";
+		compatible = "gpio-fan";
+		pinctrl-0 = <&pmx_fanctrl_15 &pmx_fanctrl_16 &pmx_fanctrl_17
+		             &pmx_fanalarm_18>;
+		pinctrl-names = "default";
+		gpios = <&gpio0 15 GPIO_ACTIVE_HIGH
+			 &gpio0 16 GPIO_ACTIVE_HIGH
+			 &gpio0 17 GPIO_ACTIVE_HIGH>;
+		alarm-gpios = <&gpio0 18 GPIO_ACTIVE_HIGH>;
+		gpio-fan,speed-map = <    0 0
+				       2200 1
+				       2500 2
+				       3000 4
+				       3300 3
+				       3700 5
+				       3800 6
+				       4200 7 >;
+	};
+
+	gpio-fan-100-32-35 {
+		status = "disabled";
+		compatible = "gpio-fan";
+		pinctrl-0 = <&pmx_fanctrl_32 &pmx_fanctrl_33 &pmx_fanctrl_34
+		             &pmx_fanalarm_35>;
+		pinctrl-names = "default";
+		gpios = <&gpio1 0 GPIO_ACTIVE_HIGH
+			 &gpio1 1 GPIO_ACTIVE_HIGH
+			 &gpio1 2 GPIO_ACTIVE_HIGH>;
+		alarm-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
+		gpio-fan,speed-map = <    0 0
+				       2500 1
+				       3100 2
+				       3800 3
+				       4600 4
+				       4800 5
+				       4900 6
+				       5000 7 >;
+	};
+
+	gpio-fan-100-15-18 {
+		status = "disabled";
+		compatible = "gpio-fan";
+		pinctrl-0 = <&pmx_fanctrl_15 &pmx_fanctrl_16 &pmx_fanctrl_17
+		             &pmx_fanalarm_18>;
+		pinctrl-names = "default";
+		gpios = <&gpio0 15 GPIO_ACTIVE_HIGH
+			 &gpio0 16 GPIO_ACTIVE_HIGH
+			 &gpio0 17 GPIO_ACTIVE_HIGH>;
+		alarm-gpios = <&gpio0 18 GPIO_ACTIVE_HIGH>;
+		gpio-fan,speed-map = <    0 0
+				       2500 1
+				       3100 2
+				       3800 3
+				       4600 4
+				       4800 5
+				       4900 6
+				       5000 7 >;
+	};
+
+	gpio-fan-100-15-35-1 {
+		status = "disabled";
+		compatible = "gpio-fan";
+		pinctrl-0 = <&pmx_fanctrl_15 &pmx_fanctrl_16 &pmx_fanctrl_17
+		             &pmx_fanalarm_35>;
+		pinctrl-names = "default";
+		gpios = <&gpio0 15 GPIO_ACTIVE_HIGH
+			 &gpio0 16 GPIO_ACTIVE_HIGH
+			 &gpio0 17 GPIO_ACTIVE_HIGH>;
+		alarm-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
+		gpio-fan,speed-map = <    0 0
+				       2500 1
+				       3100 2
+				       3800 3
+				       4600 4
+				       4800 5
+				       4900 6
+				       5000 7 >;
+	};
+
+	gpio-fan-100-15-35-3 {
+		status = "disabled";
+		compatible = "gpio-fan";
+		pinctrl-0 = <&pmx_fanctrl_15 &pmx_fanctrl_16 &pmx_fanctrl_17
+		             &pmx_fanalarm_35 &pmx_fanalarm_44 &pmx_fanalarm_45>;
+		pinctrl-names = "default";
+		gpios = <&gpio0 15 GPIO_ACTIVE_HIGH
+			 &gpio0 16 GPIO_ACTIVE_HIGH
+			 &gpio0 17 GPIO_ACTIVE_HIGH>;
+		alarm-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH
+			       &gpio1 12 GPIO_ACTIVE_HIGH
+			       &gpio1 13 GPIO_ACTIVE_HIGH>;
+		gpio-fan,speed-map = <    0 0
+				       2500 1
+				       3100 2
+				       3800 3
+				       4600 4
+				       4800 5
+				       4900 6
+				       5000 7 >;
+	};
+
+	gpio-leds-alarm-12 {
+		status = "disabled";
+		compatible = "gpio-leds";
+		pinctrl-0 = <&pmx_alarmled_12>;
+		pinctrl-names = "default";
+
+		hdd1-green {
+			label = "synology:alarm";
+			gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	gpio-leds-hdd-20 {
+		status = "disabled";
+		compatible = "gpio-leds";
+		pinctrl-0 = <&pmx_hddled_20 &pmx_hddled_21 &pmx_hddled_22
+			     &pmx_hddled_23 &pmx_hddled_24 &pmx_hddled_25
+			     &pmx_hddled_26 &pmx_hddled_27>;
+		pinctrl-names = "default";
+
+		hdd1-green {
+			label = "synology:green:hdd1";
+			gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
+		};
+
+		hdd1-amber {
+			label = "synology:amber:hdd1";
+			gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
+		};
+
+		hdd2-green {
+			label = "synology:green:hdd2";
+			gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
+		};
+
+		hdd2-amber {
+			label = "synology:amber:hdd2";
+			gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
+		};
+
+		hdd3-green {
+			label = "synology:green:hdd3";
+			gpios = <&gpio0 24 GPIO_ACTIVE_LOW>;
+		};
+
+		hdd3-amber {
+			label = "synology:amber:hdd3";
+			gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
+		};
+
+		hdd4-green {
+			label = "synology:green:hdd4";
+			gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
+		};
+
+		hdd4-amber {
+			label = "synology:amber:hdd4";
+			gpios = <&gpio0 27 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	gpio-leds-hdd-21-1 {
+		status = "disabled";
+		compatible = "gpio-leds";
+		pinctrl-0 = <&pmx_hddled_21 &pmx_hddled_23>;
+		pinctrl-names = "default";
+
+		hdd1-green {
+			label = "synology:green:hdd1";
+			gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
+		};
+
+		hdd1-amber {
+			label = "synology:amber:hdd1";
+			gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	gpio-leds-hdd-21-2 {
+		status = "disabled";
+		compatible = "gpio-leds";
+		pinctrl-0 = <&pmx_hddled_21 &pmx_hddled_23 &pmx_hddled_20 &pmx_hddled_22>;
+		pinctrl-names = "default";
+
+		hdd1-green {
+			label = "synology:green:hdd1";
+			gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
+		};
+
+		hdd1-amber {
+			label = "synology:amber:hdd1";
+			gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
+		};
+
+		hdd2-green {
+			label = "synology:green:hdd2";
+			gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
+		};
+
+		hdd2-amber {
+			label = "synology:amber:hdd2";
+			gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	gpio-leds-hdd-36 {
+		status = "disabled";
+		compatible = "gpio-leds";
+		pinctrl-0 = <&pmx_hddled_36 &pmx_hddled_37 &pmx_hddled_38
+			     &pmx_hddled_39 &pmx_hddled_40 &pmx_hddled_41
+			     &pmx_hddled_42 &pmx_hddled_43 &pmx_hddled_44
+			     &pmx_hddled_45>;
+		pinctrl-names = "default";
+
+		hdd1-green {
+			label = "synology:green:hdd1";
+			gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
+		};
+
+		hdd1-amber {
+			label = "synology:amber:hdd1";
+			gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
+		};
+
+		hdd2-green {
+			label = "synology:green:hdd2";
+			gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
+		};
+
+		hdd2-amber {
+			label = "synology:amber:hdd2";
+			gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
+		};
+
+		hdd3-green {
+			label = "synology:green:hdd3";
+			gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
+		};
+
+		hdd3-amber {
+			label = "synology:amber:hdd3";
+			gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
+		};
+
+		hdd4-green {
+			label = "synology:green:hdd4";
+			gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
+		};
+
+		hdd4-amber {
+			label = "synology:amber:hdd4";
+			gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
+		};
+
+		hdd5-green {
+			label = "synology:green:hdd5";
+			gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
+		};
+
+		hdd5-amber {
+			label = "synology:amber:hdd5";
+			gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	gpio-leds-hdd-38 {
+		status = "disabled";
+		compatible = "gpio-leds";
+		pinctrl-0 = <&pmx_hddled_38 &pmx_hddled_39 &pmx_hddled_36 &pmx_hddled_37>;
+		pinctrl-names = "default";
+
+		hdd1-green {
+			label = "synology:green:hdd1";
+			gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
+		};
+
+		hdd1-amber {
+			label = "synology:amber:hdd1";
+			gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
+		};
+
+		hdd2-green {
+			label = "synology:green:hdd2";
+			gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
+		};
+
+		hdd2-amber {
+			label = "synology:amber:hdd2";
+			gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	regulators-hdd-29 {
+		status = "disabled";
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		pinctrl-0 = <&pmx_hdd1_pwr_29 &pmx_hdd2_pwr_31>;
+		pinctrl-names = "default";
+
+		regulator@1 {
+			compatible = "regulator-fixed";
+			reg = <1>;
+			regulator-name = "hdd1power";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			startup-delay-us = <5000000>;
+			gpio = <&gpio0 29 GPIO_ACTIVE_HIGH>;
+		};
+
+		regulator@2 {
+			compatible = "regulator-fixed";
+			reg = <2>;
+			regulator-name = "hdd2power";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			startup-delay-us = <5000000>;
+			gpio = <&gpio0 31 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	regulators-hdd-30-1 {
+		status = "disabled";
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		pinctrl-0 = <&pmx_hdd1_pwr_30>;
+		pinctrl-names = "default";
+
+		regulator@1 {
+			compatible = "regulator-fixed";
+			reg = <1>;
+			regulator-name = "hdd1power";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			startup-delay-us = <5000000>;
+			gpio = <&gpio0 30 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	regulators-hdd-30-2 {
+		status = "disabled";
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		pinctrl-0 = <&pmx_hdd1_pwr_30 &pmx_hdd2_pwr_34>;
+		pinctrl-names = "default";
+
+		regulator@1 {
+			compatible = "regulator-fixed";
+			reg = <1>;
+			regulator-name = "hdd1power";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			startup-delay-us = <5000000>;
+			gpio = <&gpio0 30 GPIO_ACTIVE_HIGH>;
+		};
+
+		regulator@2 {
+			compatible = "regulator-fixed";
+			reg = <2>;
+			regulator-name = "hdd2power";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			startup-delay-us = <5000000>;
+			gpio = <&gpio1 2 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	regulators-hdd-30-4 {
+		status = "disabled";
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		pinctrl-0 = <&pmx_hdd1_pwr_30 &pmx_hdd2_pwr_34
+			     &pmx_hdd3_pwr_44 &pmx_hdd4_pwr_45>;
+		pinctrl-names = "default";
+
+		regulator@1 {
+			compatible = "regulator-fixed";
+			reg = <1>;
+			regulator-name = "hdd1power";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			startup-delay-us = <5000000>;
+			gpio = <&gpio0 30 GPIO_ACTIVE_HIGH>;
+		};
+
+		regulator@2 {
+			compatible = "regulator-fixed";
+			reg = <2>;
+			regulator-name = "hdd2power";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			startup-delay-us = <5000000>;
+			gpio = <&gpio1 2 GPIO_ACTIVE_HIGH>;
+		};
+
+		regulator@3 {
+			compatible = "regulator-fixed";
+			reg = <3>;
+			regulator-name = "hdd3power";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			startup-delay-us = <5000000>;
+			gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+		};
+
+		regulator@4 {
+			compatible = "regulator-fixed";
+			reg = <4>;
+			regulator-name = "hdd4power";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			startup-delay-us = <5000000>;
+			gpio = <&gpio1 13 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	regulators-hdd-31 {
+		status = "disabled";
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		pinctrl-0 = <&pmx_hdd2_pwr_31>;
+		pinctrl-names = "default";
+
+		regulator@1 {
+			compatible = "regulator-fixed";
+			reg = <1>;
+			regulator-name = "hdd2power";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			startup-delay-us = <5000000>;
+			gpio = <&gpio0 31 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	regulators-hdd-34 {
+		status = "disabled";
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		pinctrl-0 = <&pmx_hdd2_pwr_34 &pmx_hdd3_pwr_44
+			     &pmx_hdd4_pwr_45>;
+		pinctrl-names = "default";
+
+		regulator@2 {
+			compatible = "regulator-fixed";
+			reg = <2>;
+			regulator-name = "hdd2power";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			startup-delay-us = <5000000>;
+			gpio = <&gpio1 2 GPIO_ACTIVE_HIGH>;
+		};
+
+		regulator@3 {
+			compatible = "regulator-fixed";
+			reg = <3>;
+			regulator-name = "hdd3power";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			startup-delay-us = <5000000>;
+			gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+		};
+
+		regulator@4 {
+			compatible = "regulator-fixed";
+			reg = <4>;
+			regulator-name = "hdd4power";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			startup-delay-us = <5000000>;
+			gpio = <&gpio1 13 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&mdio {
+	status = "okay";
+
+	ethphy0: ethernet-phy@0 {
+		device_type = "ethernet-phy";
+		reg = <8>;
+	};
+
+	ethphy1: ethernet-phy@1 {
+		device_type = "ethernet-phy";
+		reg = <9>;
+	};
+};
+
+&eth0 {
+	status = "okay";
+
+	ethernet0-port@0 {
+		phy-handle = <&ethphy0>;
+	};
+};
+
+&eth1 {
+	status = "disabled";
+
+	ethernet1-port@0 {
+		phy-handle = <&ethphy1>;
+	};
+};
+
+&pciec {
+        status = "okay";
+};
+
+&pcie0 {
+	status = "okay";
+};
diff --git a/arch/arm/dts/r8a77990-ebisu-u-boot.dts b/arch/arm/dts/r8a77990-ebisu-u-boot.dts
new file mode 100644
index 0000000..8d4ea88
--- /dev/null
+++ b/arch/arm/dts/r8a77990-ebisu-u-boot.dts
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source extras for U-Boot for the Ebisu board
+ *
+ * Copyright (C) 2018 Marek Vasut <marek.vasut@gmail.com>
+ */
+
+#include "r8a77990-ebisu.dts"
+#include "r8a77990-u-boot.dtsi"
diff --git a/arch/arm/dts/r8a77990-ebisu.dts b/arch/arm/dts/r8a77990-ebisu.dts
new file mode 100644
index 0000000..7a09d05
--- /dev/null
+++ b/arch/arm/dts/r8a77990-ebisu.dts
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Device Tree Source for the ebisu board
+ *
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ */
+
+/dts-v1/;
+#include "r8a77990.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	model = "Renesas Ebisu board based on r8a77990";
+	compatible = "renesas,ebisu", "renesas,r8a77990";
+
+	aliases {
+		serial0 = &scif2;
+		ethernet0 = &avb;
+	};
+
+	chosen {
+		bootargs = "ignore_loglevel";
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory@48000000 {
+		device_type = "memory";
+		/* first 128MB is reserved for secure area. */
+		reg = <0x0 0x48000000 0x0 0x38000000>;
+	};
+};
+
+&avb {
+	pinctrl-0 = <&avb_pins>;
+	pinctrl-names = "default";
+	renesas,no-ether-link;
+	phy-handle = <&phy0>;
+	phy-mode = "rgmii-txid";
+	status = "okay";
+
+	phy0: ethernet-phy@0 {
+		rxc-skew-ps = <1500>;
+		reg = <0>;
+		interrupt-parent = <&gpio2>;
+		interrupts = <21 IRQ_TYPE_LEVEL_LOW>;
+		reset-gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&extal_clk {
+	clock-frequency = <48000000>;
+};
+
+&pfc {
+	avb_pins: avb {
+		mux {
+			groups = "avb_link", "avb_mii";
+			function = "avb";
+		};
+	};
+};
+
+&scif2 {
+	status = "okay";
+};
diff --git a/arch/arm/dts/r8a77990-u-boot.dtsi b/arch/arm/dts/r8a77990-u-boot.dtsi
new file mode 100644
index 0000000..564c258
--- /dev/null
+++ b/arch/arm/dts/r8a77990-u-boot.dtsi
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source extras for U-Boot on RCar R8A77990 SoC
+ *
+ * Copyright (C) 2018 Marek Vasut <marek.vasut@gmail.com>
+ */
+
+#include "r8a779x-u-boot.dtsi"
diff --git a/arch/arm/dts/r8a77990.dtsi b/arch/arm/dts/r8a77990.dtsi
new file mode 100644
index 0000000..be4f519
--- /dev/null
+++ b/arch/arm/dts/r8a77990.dtsi
@@ -0,0 +1,281 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Device Tree Source for the r8a77990 SoC
+ *
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ */
+
+#include <dt-bindings/clock/renesas-cpg-mssr.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	compatible = "renesas,r8a77990";
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		/* 1 core only at this point */
+		a53_0: cpu@0 {
+			compatible = "arm,cortex-a53", "arm,armv8";
+			reg = <0x0>;
+			device_type = "cpu";
+			power-domains = <&sysc 5>;
+			next-level-cache = <&L2_CA53>;
+			enable-method = "psci";
+		};
+
+		L2_CA53: cache-controller-0 {
+			compatible = "cache";
+			power-domains = <&sysc 21>;
+			cache-unified;
+			cache-level = <2>;
+		};
+	};
+
+	extal_clk: extal {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		/* This value must be overridden by the board */
+		clock-frequency = <0>;
+	};
+
+	pmu_a53 {
+		compatible = "arm,cortex-a53-pmu";
+		interrupts-extended = <&gic GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&a53_0>;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0", "arm,psci-0.2";
+		method = "smc";
+	};
+
+	soc: soc {
+		compatible = "simple-bus";
+		interrupt-parent = <&gic>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		gpio0: gpio@e6050000 {
+			compatible = "renesas,gpio-r8a77990",
+				     "renesas,rcar-gen3-gpio";
+			reg = <0 0xe6050000 0 0x50>;
+			interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 0 18>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 912>;
+			power-domains = <&sysc 32>;
+			resets = <&cpg 912>;
+		};
+
+		gpio1: gpio@e6051000 {
+			compatible = "renesas,gpio-r8a77990",
+				     "renesas,rcar-gen3-gpio";
+			reg = <0 0xe6051000 0 0x50>;
+			interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 32 23>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 911>;
+			power-domains = <&sysc 32>;
+			resets = <&cpg 911>;
+		};
+
+		gpio2: gpio@e6052000 {
+			compatible = "renesas,gpio-r8a77990",
+				     "renesas,rcar-gen3-gpio";
+			reg = <0 0xe6052000 0 0x50>;
+			interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 64 26>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 910>;
+			power-domains = <&sysc 32>;
+			resets = <&cpg 910>;
+		};
+
+		gpio3: gpio@e6053000 {
+			compatible = "renesas,gpio-r8a77990",
+				     "renesas,rcar-gen3-gpio";
+			reg = <0 0xe6053000 0 0x50>;
+			interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 96 16>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 909>;
+			power-domains = <&sysc 32>;
+			resets = <&cpg 909>;
+		};
+
+		gpio4: gpio@e6054000 {
+			compatible = "renesas,gpio-r8a77990",
+				     "renesas,rcar-gen3-gpio";
+			reg = <0 0xe6054000 0 0x50>;
+			interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 128 11>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 908>;
+			power-domains = <&sysc 32>;
+			resets = <&cpg 908>;
+		};
+
+		gpio5: gpio@e6055000 {
+			compatible = "renesas,gpio-r8a77990",
+				     "renesas,rcar-gen3-gpio";
+			reg = <0 0xe6055000 0 0x50>;
+			interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 160 20>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 907>;
+			power-domains = <&sysc 32>;
+			resets = <&cpg 907>;
+		};
+
+		gpio6: gpio@e6055400 {
+			compatible = "renesas,gpio-r8a77990",
+				     "renesas,rcar-gen3-gpio";
+			reg = <0 0xe6055400 0 0x50>;
+			interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 192 18>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 906>;
+			power-domains = <&sysc 32>;
+			resets = <&cpg 906>;
+		};
+
+		pfc: pin-controller@e6060000 {
+			compatible = "renesas,pfc-r8a77990";
+			reg = <0 0xe6060000 0 0x508>;
+		};
+
+		cpg: clock-controller@e6150000 {
+			compatible = "renesas,r8a77990-cpg-mssr";
+			reg = <0 0xe6150000 0 0x1000>;
+			clocks = <&extal_clk>;
+			clock-names = "extal";
+			#clock-cells = <2>;
+			#power-domain-cells = <0>;
+			#reset-cells = <1>;
+		};
+
+		rst: reset-controller@e6160000 {
+			compatible = "renesas,r8a77990-rst";
+			reg = <0 0xe6160000 0 0x0200>;
+		};
+
+		sysc: system-controller@e6180000 {
+			compatible = "renesas,r8a77990-sysc";
+			reg = <0 0xe6180000 0 0x0400>;
+			#power-domain-cells = <1>;
+		};
+
+		avb: ethernet@e6800000 {
+			compatible = "renesas,etheravb-r8a77990",
+				     "renesas,etheravb-rcar-gen3";
+			reg = <0 0xe6800000 0 0x800>, <0 0xe6a00000 0 0x10000>;
+			interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12", "ch13", "ch14", "ch15",
+					  "ch16", "ch17", "ch18", "ch19",
+					  "ch20", "ch21", "ch22", "ch23",
+					  "ch24";
+			clocks = <&cpg CPG_MOD 812>;
+			power-domains = <&sysc 32>;
+			resets = <&cpg 812>;
+			phy-mode = "rgmii";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		scif2: serial@e6e88000 {
+			compatible = "renesas,scif-r8a77990",
+				     "renesas,rcar-gen3-scif", "renesas,scif";
+			reg = <0 0xe6e88000 0 64>;
+			interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 310>;
+			clock-names = "fck";
+			power-domains = <&sysc 32>;
+			resets = <&cpg 310>;
+			status = "disabled";
+		};
+
+		gic: interrupt-controller@f1010000 {
+			compatible = "arm,gic-400";
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+			interrupt-controller;
+			reg = <0x0 0xf1010000 0 0x1000>,
+			      <0x0 0xf1020000 0 0x20000>,
+			      <0x0 0xf1040000 0 0x20000>,
+			      <0x0 0xf1060000 0 0x20000>;
+			interrupts = <GIC_PPI 9
+					(GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_HIGH)>;
+			clocks = <&cpg CPG_MOD 408>;
+			clock-names = "clk";
+			power-domains = <&sysc 32>;
+			resets = <&cpg 408>;
+		};
+
+		prr: chipid@fff00044 {
+			compatible = "renesas,prr";
+			reg = <0 0xfff00044 0 4>;
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>;
+	};
+};
diff --git a/arch/arm/dts/stm32f429-disco-u-boot.dtsi b/arch/arm/dts/stm32f429-disco-u-boot.dtsi
index 8a0f642..10e0950 100644
--- a/arch/arm/dts/stm32f429-disco-u-boot.dtsi
+++ b/arch/arm/dts/stm32f429-disco-u-boot.dtsi
@@ -37,6 +37,8 @@
 			clocks = <&rcc 0 STM32F4_AHB3_CLOCK(FMC)>;
 			pinctrl-0 = <&fmc_pins>;
 			pinctrl-names = "default";
+			st,syscfg = <&syscfg>;
+			st,swp_fmc = <1>;
 			u-boot,dm-pre-reloc;
 
 			/*
diff --git a/arch/arm/dts/stm32f746.dtsi b/arch/arm/dts/stm32f746.dtsi
index 8581df9..afa7832 100644
--- a/arch/arm/dts/stm32f746.dtsi
+++ b/arch/arm/dts/stm32f746.dtsi
@@ -88,10 +88,11 @@
 			#address-cells = <1>;
 			#size-cells = <0>;
 			reg = <0xA0001000 0x1000>, <0x90000000 0x10000000>;
-			reg-names = "QuadSPI", "QuadSPI-memory";
+			reg-names = "qspi", "qspi_mm";
 			interrupts = <92>;
 			spi-max-frequency = <108000000>;
 			clocks = <&rcc 0 STM32F7_AHB3_CLOCK(QSPI)>;
+			resets = <&rcc STM32F7_AHB3_RESET(QSPI)>;
 			status = "disabled";
 		};
 		usart1: serial@40011000 {
diff --git a/arch/arm/dts/zynq-minized.dts b/arch/arm/dts/zynq-minized.dts
new file mode 100644
index 0000000..525921e
--- /dev/null
+++ b/arch/arm/dts/zynq-minized.dts
@@ -0,0 +1,106 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * dts file for Avnet MiniZed board
+ *
+ * (C) Copyright 2017 - 2018, Xilinx, Inc.
+ *
+ * Ibai Erkiaga <ibai.erkiaga-elorza@xilinx.com>
+ */
+
+/dts-v1/;
+#include "zynq-7000.dtsi"
+
+/ {
+	model = "Avnet Zynq MiniZed Development Board";
+	compatible = "avnet,minized", "xlnx,zynq-7000";
+
+	aliases {
+		serial0 = &uart1;
+		serial1 = &uart0;
+		spi0 = &qspi;
+		mmc0 = &sdhci0;
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x20000000>;
+	};
+
+	chosen {
+		bootargs = "";
+		stdout-path = "serial0:115200n8";
+	};
+
+	usb_phy0: phy0 {
+		compatible = "usb-nop-xceiv";
+		#phy-cells = <0>;
+	};
+};
+
+&qspi {
+	status = "okay";
+	is-dual = <0>;
+	num-cs = <1>;
+	flash@0 {
+		compatible = "micron,m25p128";
+		reg = <0x0>;
+		spi-tx-bus-width = <4>;
+		spi-rx-bus-width = <4>;
+		spi-max-frequency = <50000000>;
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			partition@0 {
+				label = "boot";
+				reg = <0x0 0xff0000>;
+			};
+
+			partition@270000 {
+				label = "kernel";
+				reg = <0x270000 0xd80000>;
+			};
+
+			partition@ff0000 {
+				label = "bootenv";
+				reg = <0xff0000 0x10000>;
+			};
+
+			partition@1000000 {
+				label = "spare";
+				reg = <0x1000000 0x0>;
+			};
+		};
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&uart1 {
+	u-boot,dm-pre-reloc;
+	status = "okay";
+};
+
+&usb0 {
+	status = "okay";
+	dr_mode = "host";
+	usb-phy = <&usb_phy0>;
+	usb-reset = <&gpio0 7 0>; /* USB_RST_N-MIO7 */
+};
+
+&sdhci1 {
+	status = "okay";
+	non-removable;
+	bus-width = <4>;
+	max-frequency = <12000000>;
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+	mmccard: mmccard@0 {
+		compatible = "mmc-card";
+		reg = <0>;
+		broken-hpi;
+	};
+};
diff --git a/arch/arm/dts/zynqmp-clk-ccf.dtsi b/arch/arm/dts/zynqmp-clk-ccf.dtsi
index b18d8d1..247a35f 100644
--- a/arch/arm/dts/zynqmp-clk-ccf.dtsi
+++ b/arch/arm/dts/zynqmp-clk-ccf.dtsi
@@ -248,6 +248,22 @@
 	clocks = <&clkc 59>, <&clkc 31>;
 };
 
+&ttc0 {
+	clocks = <&clkc 31>;
+};
+
+&ttc1 {
+	clocks = <&clkc 31>;
+};
+
+&ttc2 {
+	clocks = <&clkc 31>;
+};
+
+&ttc3 {
+	clocks = <&clkc 31>;
+};
+
 &uart0 {
 	clocks = <&clkc 56>,  <&clkc 31>;
 };
diff --git a/arch/arm/dts/zynqmp-zcu100-revC.dts b/arch/arm/dts/zynqmp-zcu100-revC.dts
index bcd9c39..c6aaa08 100644
--- a/arch/arm/dts/zynqmp-zcu100-revC.dts
+++ b/arch/arm/dts/zynqmp-zcu100-revC.dts
@@ -252,7 +252,6 @@
 &sdhci0 {
 	status = "okay";
 	no-1-8-v;
-	broken-cd; /* CD has to be enabled by default */
 	disable-wp;
 	xlnx,mio_bank = <0>;
 };
diff --git a/arch/arm/dts/zynqmp-zcu104-revA.dts b/arch/arm/dts/zynqmp-zcu104-revA.dts
index a0e13d8..6a4b701 100644
--- a/arch/arm/dts/zynqmp-zcu104-revA.dts
+++ b/arch/arm/dts/zynqmp-zcu104-revA.dts
@@ -130,9 +130,9 @@
 			#address-cells = <1>;
 			#size-cells = <0>;
 			reg = <4>;
-			tca6416_u97: gpio@21 {
+			tca6416_u97: gpio@20 {
 				compatible = "ti,tca6416";
-				reg = <0x21>;
+				reg = <0x20>;
 				gpio-controller;
 				#gpio-cells = <2>;
 				/*
diff --git a/arch/arm/dts/zynqmp-zcu104-revC.dts b/arch/arm/dts/zynqmp-zcu104-revC.dts
index 6e3cf5a..fe742b8 100644
--- a/arch/arm/dts/zynqmp-zcu104-revC.dts
+++ b/arch/arm/dts/zynqmp-zcu104-revC.dts
@@ -74,9 +74,9 @@
 	status = "okay";
 	clock-frequency = <400000>;
 
-	tca6416_u97: gpio@21 {
+	tca6416_u97: gpio@20 {
 		compatible = "ti,tca6416";
-		reg = <0x21>;
+		reg = <0x20>;
 		gpio-controller;
 		#gpio-cells = <2>;
 		/*
@@ -145,10 +145,15 @@
 			};
 		};
 
-		i2c@4 {
+		i2c@3 {
 			#address-cells = <1>;
 			#size-cells = <0>;
-			reg = <4>;
+			reg = <3>;
+			ina226@40 { /* u183 */
+				compatible = "ti,ina226";
+				reg = <0x40>;
+				shunt-resistor = <5000>;
+			};
 		};
 
 		i2c@5 {
@@ -163,7 +168,7 @@
 			reg = <7>;
 		};
 
-		/* 3, 6 not connected */
+		/* 4, 6 not connected */
 	};
 };
 
diff --git a/arch/arm/dts/zynqmp-zcu111-revA.dts b/arch/arm/dts/zynqmp-zcu111-revA.dts
index 4002d78..aa9055b 100644
--- a/arch/arm/dts/zynqmp-zcu111-revA.dts
+++ b/arch/arm/dts/zynqmp-zcu111-revA.dts
@@ -500,6 +500,7 @@
 &sdhci1 {
 	status = "okay";
 	no-1-8-v;
+	disable-wp;
 	xlnx,mio_bank = <1>;
 };
 
diff --git a/arch/arm/include/asm/arch-zynqmp/hardware.h b/arch/arm/include/asm/arch-zynqmp/hardware.h
index acc6825..8a505ed 100644
--- a/arch/arm/include/asm/arch-zynqmp/hardware.h
+++ b/arch/arm/include/asm/arch-zynqmp/hardware.h
@@ -30,6 +30,14 @@
 #define PS_MODE2	BIT(2)
 #define PS_MODE3	BIT(3)
 
+#define RESET_REASON_DEBUG_SYS	BIT(6)
+#define RESET_REASON_SOFT	BIT(5)
+#define RESET_REASON_SRST	BIT(4)
+#define RESET_REASON_PSONLY	BIT(3)
+#define RESET_REASON_PMU	BIT(2)
+#define RESET_REASON_INTERNAL	BIT(1)
+#define RESET_REASON_EXTERNAL	BIT(0)
+
 struct crlapb_regs {
 	u32 reserved0[36];
 	u32 cpu_r5_ctrl; /* 0x90 */
@@ -37,7 +45,9 @@
 	u32 timestamp_ref_ctrl; /* 0x128 */
 	u32 reserved2[53];
 	u32 boot_mode; /* 0x200 */
-	u32 reserved3[14];
+	u32 reserved3_0[7];
+	u32 reset_reason; /* 0x220 */
+	u32 reserved3_1[6];
 	u32 rst_lpd_top; /* 0x23C */
 	u32 reserved4[4];
 	u32 boot_pin_ctrl; /* 0x250 */
@@ -120,8 +130,6 @@
 /* Board version value */
 #define ZYNQMP_CSU_BASEADDR		0xFFCA0000
 #define ZYNQMP_CSU_VERSION_SILICON	0x0
-#define ZYNQMP_CSU_VERSION_EP108	0x1
-#define ZYNQMP_CSU_VERSION_VELOCE	0x2
 #define ZYNQMP_CSU_VERSION_QEMU		0x3
 
 #define ZYNQMP_CSU_VERSION_EMPTY_SHIFT		20
diff --git a/arch/arm/include/asm/arch-zynqmp/sys_proto.h b/arch/arm/include/asm/arch-zynqmp/sys_proto.h
index 6056bc6..773b930 100644
--- a/arch/arm/include/asm/arch-zynqmp/sys_proto.h
+++ b/arch/arm/include/asm/arch-zynqmp/sys_proto.h
@@ -13,8 +13,14 @@
 #define ZYNQMP_SIP_SVC_PM_SECURE_IMG_LOAD	0xC200002D
 #define KEY_PTR_LEN	32
 
+#define ZYNQMP_FPGA_BIT_AUTH_DDR	1
+#define ZYNQMP_FPGA_BIT_AUTH_OCM	2
+#define ZYNQMP_FPGA_BIT_ENC_USR_KEY	3
+#define ZYNQMP_FPGA_BIT_ENC_DEV_KEY	4
 #define ZYNQMP_FPGA_BIT_NS		5
 
+#define ZYNQMP_FPGA_AUTH_DDR	1
+
 enum {
 	IDCODE,
 	VERSION,
diff --git a/arch/arm/include/asm/u-boot-arm.h b/arch/arm/include/asm/u-boot-arm.h
index 01c3ba8..cc828c4 100644
--- a/arch/arm/include/asm/u-boot-arm.h
+++ b/arch/arm/include/asm/u-boot-arm.h
@@ -37,7 +37,6 @@
 
 /* board/.../... */
 int	board_init(void);
-void	board_quiesce_devices(void);
 
 /* cpu/.../interrupt.c */
 int	arch_interrupt_init	(void);
diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile
index 3b9a811..ade7b87 100644
--- a/arch/arm/mach-mvebu/Makefile
+++ b/arch/arm/mach-mvebu/Makefile
@@ -7,7 +7,6 @@
 obj-$(CONFIG_ARMADA_3700) += armada3700/
 obj-$(CONFIG_ARMADA_8K) += armada8k/
 obj-y += arm64-common.o
-obj-$(CONFIG_AHCI) += sata.o
 
 else # CONFIG_ARM64
 
diff --git a/arch/arm/mach-omap2/boot-common.c b/arch/arm/mach-omap2/boot-common.c
index 0e9fd03..d4a1e2e 100644
--- a/arch/arm/mach-omap2/boot-common.c
+++ b/arch/arm/mach-omap2/boot-common.c
@@ -236,13 +236,3 @@
 	ahci_reset((void __iomem *)DWC_AHSATA_BASE);
 }
 #endif
-
-#if defined(CONFIG_USB_FUNCTION_FASTBOOT) && !defined(CONFIG_ENV_IS_NOWHERE)
-int fb_set_reboot_flag(void)
-{
-	printf("Setting reboot to fastboot flag ...\n");
-	env_set("dofastboot", "1");
-	env_save();
-	return 0;
-}
-#endif
diff --git a/arch/arm/mach-omap2/utils.c b/arch/arm/mach-omap2/utils.c
index dc7b37f..edf5edc 100644
--- a/arch/arm/mach-omap2/utils.c
+++ b/arch/arm/mach-omap2/utils.c
@@ -85,7 +85,7 @@
 	env_set("fastboot.board_rev", board_rev);
 }
 
-#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
+#ifdef CONFIG_FASTBOOT_FLASH_MMC
 static u32 omap_mmc_get_part_size(const char *part)
 {
 	int res;
@@ -128,7 +128,7 @@
 static inline void omap_set_fastboot_userdata_size(void)
 {
 }
-#endif /* CONFIG_FASTBOOT_FLASH_MMC_DEV */
+#endif /* CONFIG_FASTBOOT_FLASH_MMC */
 void omap_set_fastboot_vars(void)
 {
 	omap_set_fastboot_cpu();
diff --git a/arch/arm/mach-rmobile/Kconfig.64 b/arch/arm/mach-rmobile/Kconfig.64
index 6112d79..cb9f569 100644
--- a/arch/arm/mach-rmobile/Kconfig.64
+++ b/arch/arm/mach-rmobile/Kconfig.64
@@ -12,6 +12,9 @@
 config R8A77970
 	bool "Renesas SoC R8A77970"
 
+config R8A77990
+	bool "Renesas SoC R8A77990"
+
 config R8A77995
 	bool "Renesas SoC R8A77995"
 
@@ -31,6 +34,11 @@
 	help
           Support for Renesas R-Car Gen3 Eagle platform
 
+config TARGET_EBISU
+	bool "Ebisu board"
+	help
+          Support for Renesas R-Car Gen3 Ebisu platform
+
 config TARGET_SALVATOR_X
 	bool "Salvator-X board"
 	help
@@ -48,6 +56,7 @@
 
 source "board/renesas/draak/Kconfig"
 source "board/renesas/eagle/Kconfig"
+source "board/renesas/ebisu/Kconfig"
 source "board/renesas/salvator-x/Kconfig"
 source "board/renesas/ulcb/Kconfig"
 
diff --git a/arch/arm/mach-rmobile/cpu_info.c b/arch/arm/mach-rmobile/cpu_info.c
index 4e6a191..e110737 100644
--- a/arch/arm/mach-rmobile/cpu_info.c
+++ b/arch/arm/mach-rmobile/cpu_info.c
@@ -59,6 +59,7 @@
 	{ RMOBILE_CPU_TYPE_R8A7796, "R8A7796" },
 	{ RMOBILE_CPU_TYPE_R8A77965, "R8A77965" },
 	{ RMOBILE_CPU_TYPE_R8A77970, "R8A77970" },
+	{ RMOBILE_CPU_TYPE_R8A77990, "R8A77990" },
 	{ RMOBILE_CPU_TYPE_R8A77995, "R8A77995" },
 	{ 0x0, "CPU" },
 };
diff --git a/arch/arm/mach-rmobile/include/mach/rmobile.h b/arch/arm/mach-rmobile/include/mach/rmobile.h
index 94ea366..c94b3ff 100644
--- a/arch/arm/mach-rmobile/include/mach/rmobile.h
+++ b/arch/arm/mach-rmobile/include/mach/rmobile.h
@@ -35,6 +35,7 @@
 #define RMOBILE_CPU_TYPE_R8A7796	0x52
 #define RMOBILE_CPU_TYPE_R8A77965	0x55
 #define RMOBILE_CPU_TYPE_R8A77970	0x54
+#define RMOBILE_CPU_TYPE_R8A77990	0x57
 #define RMOBILE_CPU_TYPE_R8A77995	0x58
 
 #ifndef __ASSEMBLY__
diff --git a/arch/arm/mach-rockchip/rk3128-board.c b/arch/arm/mach-rockchip/rk3128-board.c
index 48cd8ba..7fd667a 100644
--- a/arch/arm/mach-rockchip/rk3128-board.c
+++ b/arch/arm/mach-rockchip/rk3128-board.c
@@ -111,8 +111,8 @@
 }
 #endif
 
-#if defined(CONFIG_USB_FUNCTION_FASTBOOT)
-int fb_set_reboot_flag(void)
+#if CONFIG_IS_ENABLED(FASTBOOT)
+int fastboot_set_reboot_flag(void)
 {
 	struct rk3128_grf *grf;
 
diff --git a/arch/arm/mach-rockchip/rk322x-board.c b/arch/arm/mach-rockchip/rk322x-board.c
index 99a60c4..7366d45 100644
--- a/arch/arm/mach-rockchip/rk322x-board.c
+++ b/arch/arm/mach-rockchip/rk322x-board.c
@@ -139,8 +139,8 @@
 }
 #endif
 
-#if defined(CONFIG_USB_FUNCTION_FASTBOOT)
-int fb_set_reboot_flag(void)
+#if CONFIG_IS_ENABLED(FASTBOOT)
+int fastboot_set_reboot_flag(void)
 {
 	struct rk322x_grf *grf;
 
diff --git a/arch/arm/mach-snapdragon/Kconfig b/arch/arm/mach-snapdragon/Kconfig
index d55dc1a..bfd99db 100644
--- a/arch/arm/mach-snapdragon/Kconfig
+++ b/arch/arm/mach-snapdragon/Kconfig
@@ -3,6 +3,12 @@
 config SYS_SOC
 	default "snapdragon"
 
+config SYS_MALLOC_F_LEN
+	default 0x2000
+
+config SPL_SYS_MALLOC_F_LEN
+	default 0x2000
+
 choice
 	prompt "Snapdragon board select"
 
diff --git a/arch/arm/mach-snapdragon/Makefile b/arch/arm/mach-snapdragon/Makefile
index 1c23dc5..1d35fea 100644
--- a/arch/arm/mach-snapdragon/Makefile
+++ b/arch/arm/mach-snapdragon/Makefile
@@ -6,4 +6,6 @@
 obj-$(CONFIG_TARGET_DRAGONBOARD820C) += sysmap-apq8096.o
 obj-$(CONFIG_TARGET_DRAGONBOARD410C) += clock-apq8016.o
 obj-$(CONFIG_TARGET_DRAGONBOARD410C) += sysmap-apq8016.o
+obj-$(CONFIG_TARGET_DRAGONBOARD410C) += pinctrl-apq8016.o
+obj-$(CONFIG_TARGET_DRAGONBOARD410C) += pinctrl-snapdragon.o
 obj-y += clock-snapdragon.o
diff --git a/arch/arm/mach-snapdragon/clock-apq8016.c b/arch/arm/mach-snapdragon/clock-apq8016.c
index 9c0cc1c..6e4a0cc 100644
--- a/arch/arm/mach-snapdragon/clock-apq8016.c
+++ b/arch/arm/mach-snapdragon/clock-apq8016.c
@@ -17,7 +17,6 @@
 
 /* GPLL0 clock control registers */
 #define GPLL0_STATUS_ACTIVE BIT(17)
-#define APCS_GPLL_ENA_VOTE_GPLL0 BIT(0)
 
 static const struct bcr_regs sdc_regs[] = {
 	{
@@ -36,11 +35,17 @@
 	}
 };
 
-static struct gpll0_ctrl gpll0_ctrl = {
+static struct pll_vote_clk gpll0_vote_clk = {
 	.status = GPLL0_STATUS,
 	.status_bit = GPLL0_STATUS_ACTIVE,
 	.ena_vote = APCS_GPLL_ENA_VOTE,
-	.vote_bit = APCS_GPLL_ENA_VOTE_GPLL0,
+	.vote_bit = BIT(0),
+};
+
+static struct vote_clk gcc_blsp1_ahb_clk = {
+	.cbcr_reg = BLSP1_AHB_CBCR,
+	.ena_vote = APCS_CLOCK_BRANCH_ENA_VOTE,
+	.vote_bit = BIT(10),
 };
 
 /* SDHCI */
@@ -55,7 +60,7 @@
 	/* 800Mhz/div, gpll0 */
 	clk_rcg_set_rate_mnd(priv->base, &sdc_regs[slot], div, 0, 0,
 			     CFG_CLK_SRC_GPLL0);
-	clk_enable_gpll0(priv->base, &gpll0_ctrl);
+	clk_enable_gpll0(priv->base, &gpll0_vote_clk);
 	clk_enable_cbc(priv->base + SDCC_APPS_CBCR(slot));
 
 	return rate;
@@ -72,12 +77,16 @@
 /* UART: 115200 */
 static int clk_init_uart(struct msm_clk_priv *priv)
 {
-	/* Enable iface clk */
-	clk_enable_cbc(priv->base + BLSP1_AHB_CBCR);
+	/* Enable AHB clock */
+	clk_enable_vote_clk(priv->base, &gcc_blsp1_ahb_clk);
+
 	/* 7372800 uart block clock @ GPLL0 */
 	clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 1, 144, 15625,
 			     CFG_CLK_SRC_GPLL0);
-	clk_enable_gpll0(priv->base, &gpll0_ctrl);
+
+	/* Vote for gpll0 clock */
+	clk_enable_gpll0(priv->base, &gpll0_vote_clk);
+
 	/* Enable core clk */
 	clk_enable_cbc(priv->base + BLSP1_UART2_APPS_CBCR);
 
diff --git a/arch/arm/mach-snapdragon/clock-apq8096.c b/arch/arm/mach-snapdragon/clock-apq8096.c
index 008649a..628c387 100644
--- a/arch/arm/mach-snapdragon/clock-apq8096.c
+++ b/arch/arm/mach-snapdragon/clock-apq8096.c
@@ -27,7 +27,7 @@
 	.D = SDCC2_D,
 };
 
-static const struct gpll0_ctrl gpll0_ctrl = {
+static const struct pll_vote_clk gpll0_vote_clk = {
 	.status = GPLL0_STATUS,
 	.status_bit = GPLL0_STATUS_ACTIVE,
 	.ena_vote = APCS_GPLL_ENA_VOTE,
@@ -41,7 +41,7 @@
 	clk_enable_cbc(priv->base + SDCC2_AHB_CBCR);
 	clk_rcg_set_rate_mnd(priv->base, &sdc_regs, div, 0, 0,
 			     CFG_CLK_SRC_GPLL0);
-	clk_enable_gpll0(priv->base, &gpll0_ctrl);
+	clk_enable_gpll0(priv->base, &gpll0_vote_clk);
 	clk_enable_cbc(priv->base + SDCC2_APPS_CBCR);
 
 	return rate;
diff --git a/arch/arm/mach-snapdragon/clock-snapdragon.c b/arch/arm/mach-snapdragon/clock-snapdragon.c
index f738f57..8552618 100644
--- a/arch/arm/mach-snapdragon/clock-snapdragon.c
+++ b/arch/arm/mach-snapdragon/clock-snapdragon.c
@@ -30,7 +30,7 @@
 		;
 }
 
-void clk_enable_gpll0(phys_addr_t base, const struct gpll0_ctrl *gpll0)
+void clk_enable_gpll0(phys_addr_t base, const struct pll_vote_clk *gpll0)
 {
 	if (readl(base + gpll0->status) & gpll0->status_bit)
 		return; /* clock already enabled */
@@ -41,6 +41,21 @@
 		;
 }
 
+#define BRANCH_ON_VAL (0)
+#define BRANCH_NOC_FSM_ON_VAL BIT(29)
+#define BRANCH_CHECK_MASK GENMASK(31, 28)
+
+void clk_enable_vote_clk(phys_addr_t base, const struct vote_clk *vclk)
+{
+	u32 val;
+
+	setbits_le32(base + vclk->ena_vote, vclk->vote_bit);
+	do {
+		val = readl(base + vclk->cbcr_reg);
+		val &= BRANCH_CHECK_MASK;
+	} while ((val != BRANCH_ON_VAL) && (val != BRANCH_NOC_FSM_ON_VAL));
+}
+
 #define APPS_CMD_RGCR_UPDATE BIT(0)
 
 /* Update clock command via CMD_RGCR */
diff --git a/arch/arm/mach-snapdragon/clock-snapdragon.h b/arch/arm/mach-snapdragon/clock-snapdragon.h
index 2cff4f8..58fab40 100644
--- a/arch/arm/mach-snapdragon/clock-snapdragon.h
+++ b/arch/arm/mach-snapdragon/clock-snapdragon.h
@@ -11,13 +11,18 @@
 #define CFG_CLK_SRC_GPLL0 (1 << 8)
 #define CFG_CLK_SRC_MASK  (7 << 8)
 
-struct gpll0_ctrl {
+struct pll_vote_clk {
 	uintptr_t status;
 	int status_bit;
 	uintptr_t ena_vote;
 	int vote_bit;
 };
 
+struct vote_clk {
+	uintptr_t cbcr_reg;
+	uintptr_t ena_vote;
+	int vote_bit;
+};
 struct bcr_regs {
 	uintptr_t cfg_rcgr;
 	uintptr_t cmd_rcgr;
@@ -30,9 +35,10 @@
 	phys_addr_t base;
 };
 
-void clk_enable_gpll0(phys_addr_t base, const struct gpll0_ctrl *pll0);
+void clk_enable_gpll0(phys_addr_t base, const struct pll_vote_clk *gpll0);
 void clk_bcr_update(phys_addr_t apps_cmd_rgcr);
 void clk_enable_cbc(phys_addr_t cbcr);
+void clk_enable_vote_clk(phys_addr_t base, const struct vote_clk *vclk);
 void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs,
 			  int div, int m, int n, int source);
 
diff --git a/arch/arm/mach-snapdragon/include/mach/sysmap-apq8016.h b/arch/arm/mach-snapdragon/include/mach/sysmap-apq8016.h
index ae78438..520e2e6 100644
--- a/arch/arm/mach-snapdragon/include/mach/sysmap-apq8016.h
+++ b/arch/arm/mach-snapdragon/include/mach/sysmap-apq8016.h
@@ -13,6 +13,7 @@
 /* Clocks: (from CLK_CTL_BASE)  */
 #define GPLL0_STATUS			(0x2101C)
 #define APCS_GPLL_ENA_VOTE		(0x45000)
+#define APCS_CLOCK_BRANCH_ENA_VOTE (0x45004)
 
 #define SDCC_BCR(n)			((n * 0x1000) + 0x41000)
 #define SDCC_CMD_RCGR(n)		((n * 0x1000) + 0x41004)
diff --git a/arch/arm/mach-snapdragon/pinctrl-apq8016.c b/arch/arm/mach-snapdragon/pinctrl-apq8016.c
new file mode 100644
index 0000000..bdb755d
--- /dev/null
+++ b/arch/arm/mach-snapdragon/pinctrl-apq8016.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Qualcomm APQ8016 pinctrl
+ *
+ * (C) Copyright 2018 Ramon Fried <ramon.fried@gmail.com>
+ *
+ */
+
+#include "pinctrl-snapdragon.h"
+#include <common.h>
+
+#define MAX_PIN_NAME_LEN 32
+static char pin_name[MAX_PIN_NAME_LEN];
+static const char * const msm_pinctrl_pins[] = {
+	"SDC1_CLK",
+	"SDC1_CMD",
+	"SDC1_DATA",
+	"SDC2_CLK",
+	"SDC2_CMD",
+	"SDC2_DATA",
+	"QDSD_CLK",
+	"QDSD_CMD",
+	"QDSD_DATA0",
+	"QDSD_DATA1",
+	"QDSD_DATA2",
+	"QDSD_DATA3",
+};
+
+static const struct pinctrl_function msm_pinctrl_functions[] = {
+	{"blsp1_uart", 2},
+};
+
+static const char *apq8016_get_function_name(struct udevice *dev,
+					     unsigned int selector)
+{
+	return msm_pinctrl_functions[selector].name;
+}
+
+static const char *apq8016_get_pin_name(struct udevice *dev,
+					unsigned int selector)
+{
+	if (selector < 130) {
+		snprintf(pin_name, MAX_PIN_NAME_LEN, "GPIO_%u", selector);
+		return pin_name;
+	} else {
+		return msm_pinctrl_pins[selector - 130];
+	}
+}
+
+static unsigned int apq8016_get_function_mux(unsigned int selector)
+{
+	return msm_pinctrl_functions[selector].val;
+}
+
+struct msm_pinctrl_data apq8016_data = {
+	.pin_count = 140,
+	.functions_count = ARRAY_SIZE(msm_pinctrl_functions),
+	.get_function_name = apq8016_get_function_name,
+	.get_function_mux = apq8016_get_function_mux,
+	.get_pin_name = apq8016_get_pin_name,
+};
+
diff --git a/arch/arm/mach-snapdragon/pinctrl-snapdragon.c b/arch/arm/mach-snapdragon/pinctrl-snapdragon.c
new file mode 100644
index 0000000..5365ccd
--- /dev/null
+++ b/arch/arm/mach-snapdragon/pinctrl-snapdragon.c
@@ -0,0 +1,128 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * TLMM driver for Qualcomm APQ8016, APQ8096
+ *
+ * (C) Copyright 2018 Ramon Fried <ramon.fried@gmail.com>
+ *
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <dm/pinctrl.h>
+#include "pinctrl-snapdragon.h"
+
+struct msm_pinctrl_priv {
+	phys_addr_t base;
+	struct msm_pinctrl_data *data;
+};
+
+#define GPIO_CONFIG_OFFSET(x)         ((x) * 0x1000)
+#define TLMM_GPIO_PULL_MASK GENMASK(1, 0)
+#define TLMM_FUNC_SEL_MASK GENMASK(5, 2)
+#define TLMM_DRV_STRENGTH_MASK GENMASK(8, 6)
+#define TLMM_GPIO_ENABLE BIT(9)
+
+static const struct pinconf_param msm_conf_params[] = {
+	{ "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 3 },
+	{ "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
+};
+
+static int msm_get_functions_count(struct udevice *dev)
+{
+	struct msm_pinctrl_priv *priv = dev_get_priv(dev);
+
+	return priv->data->functions_count;
+}
+
+static int msm_get_pins_count(struct udevice *dev)
+{
+	struct msm_pinctrl_priv *priv = dev_get_priv(dev);
+
+	return priv->data->pin_count;
+}
+
+static const char *msm_get_function_name(struct udevice *dev,
+					 unsigned int selector)
+{
+	struct msm_pinctrl_priv *priv = dev_get_priv(dev);
+
+	return priv->data->get_function_name(dev, selector);
+}
+
+static int msm_pinctrl_probe(struct udevice *dev)
+{
+	struct msm_pinctrl_priv *priv = dev_get_priv(dev);
+
+	priv->base = devfdt_get_addr(dev);
+	priv->data = (struct msm_pinctrl_data *)dev->driver_data;
+
+	return priv->base == FDT_ADDR_T_NONE ? -EINVAL : 0;
+}
+
+static const char *msm_get_pin_name(struct udevice *dev, unsigned int selector)
+{
+	struct msm_pinctrl_priv *priv = dev_get_priv(dev);
+
+	return priv->data->get_pin_name(dev, selector);
+}
+
+static int msm_pinmux_set(struct udevice *dev, unsigned int pin_selector,
+			  unsigned int func_selector)
+{
+	struct msm_pinctrl_priv *priv = dev_get_priv(dev);
+
+	clrsetbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector),
+			TLMM_FUNC_SEL_MASK | TLMM_GPIO_ENABLE,
+			priv->data->get_function_mux(func_selector) << 2);
+	return 0;
+}
+
+static int msm_pinconf_set(struct udevice *dev, unsigned int pin_selector,
+			   unsigned int param, unsigned int argument)
+{
+	struct msm_pinctrl_priv *priv = dev_get_priv(dev);
+
+	switch (param) {
+	case PIN_CONFIG_DRIVE_STRENGTH:
+		clrsetbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector),
+				TLMM_DRV_STRENGTH_MASK, argument << 6);
+		break;
+	case PIN_CONFIG_BIAS_DISABLE:
+		clrbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector),
+			     TLMM_GPIO_PULL_MASK);
+		break;
+	default:
+		return 0;
+	}
+
+	return 0;
+}
+
+static struct pinctrl_ops msm_pinctrl_ops = {
+	.get_pins_count = msm_get_pins_count,
+	.get_pin_name = msm_get_pin_name,
+	.set_state = pinctrl_generic_set_state,
+	.pinmux_set = msm_pinmux_set,
+	.pinconf_num_params = ARRAY_SIZE(msm_conf_params),
+	.pinconf_params = msm_conf_params,
+	.pinconf_set = msm_pinconf_set,
+	.get_functions_count = msm_get_functions_count,
+	.get_function_name = msm_get_function_name,
+};
+
+static const struct udevice_id msm_pinctrl_ids[] = {
+	{ .compatible = "qcom,tlmm-msm8916", .data = (ulong)&apq8016_data },
+	{ .compatible = "qcom,tlmm-apq8016", .data = (ulong)&apq8016_data },
+	{ }
+};
+
+U_BOOT_DRIVER(pinctrl_snapdraon) = {
+	.name		= "pinctrl_msm",
+	.id		= UCLASS_PINCTRL,
+	.of_match	= msm_pinctrl_ids,
+	.priv_auto_alloc_size = sizeof(struct msm_pinctrl_priv),
+	.ops		= &msm_pinctrl_ops,
+	.probe		= msm_pinctrl_probe,
+};
diff --git a/arch/arm/mach-snapdragon/pinctrl-snapdragon.h b/arch/arm/mach-snapdragon/pinctrl-snapdragon.h
new file mode 100644
index 0000000..c47d988
--- /dev/null
+++ b/arch/arm/mach-snapdragon/pinctrl-snapdragon.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Qualcomm Pin control
+ *
+ * (C) Copyright 2018 Ramon Fried <ramon.fried@gmail.com>
+ *
+ */
+#ifndef _PINCTRL_SNAPDRAGON_H
+#define _PINCTRL_SNAPDRAGON_H
+
+#include <common.h>
+
+struct msm_pinctrl_data {
+	int pin_count;
+	int functions_count;
+	const char *(*get_function_name)(struct udevice *dev,
+					 unsigned int selector);
+	unsigned int (*get_function_mux)(unsigned int selector);
+	const char *(*get_pin_name)(struct udevice *dev,
+				    unsigned int selector);
+};
+
+struct pinctrl_function {
+	const char *name;
+	int val;
+};
+
+extern struct msm_pinctrl_data apq8016_data;
+
+#endif
diff --git a/arch/arm/mach-stm32mp/Kconfig b/arch/arm/mach-stm32mp/Kconfig
index ccbeb5c..abceede 100644
--- a/arch/arm/mach-stm32mp/Kconfig
+++ b/arch/arm/mach-stm32mp/Kconfig
@@ -54,4 +54,19 @@
 
 source "board/st/stm32mp1/Kconfig"
 
+# currently activated for debug / should be deactivated for real product
+if DEBUG_UART
+
+config DEBUG_UART_BOARD_INIT
+	default y
+
+# debug on UART4 by default
+config DEBUG_UART_BASE
+	default 0x40010000
+
+# clock source is HSI on reset
+config DEBUG_UART_CLOCK
+	default 64000000
+endif
+
 endif
diff --git a/arch/arm/mach-stm32mp/Makefile b/arch/arm/mach-stm32mp/Makefile
index 08ee642..f59ced5 100644
--- a/arch/arm/mach-stm32mp/Makefile
+++ b/arch/arm/mach-stm32mp/Makefile
@@ -1,4 +1,4 @@
-# SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+# SPDX-License-Identifier: GPL-2.0+
 #
 # Copyright (C) 2018, STMicroelectronics - All Rights Reserved
 #
@@ -7,6 +7,10 @@
 obj-y += dram_init.o
 obj-y += syscon.o
 
-obj-$(CONFIG_SPL_BUILD) += spl.o
+ifdef CONFIG_SPL_BUILD
+obj-y += spl.o
+else
+obj-y += bsec.o
+endif
 obj-$(CONFIG_ARMV7_PSCI) += psci.o
 obj-$(CONFIG_$(SPL_)DM_REGULATOR) += pwr_regulator.o
diff --git a/arch/arm/mach-stm32mp/bsec.c b/arch/arm/mach-stm32mp/bsec.c
new file mode 100644
index 0000000..0e152ef
--- /dev/null
+++ b/arch/arm/mach-stm32mp/bsec.c
@@ -0,0 +1,431 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <misc.h>
+#include <asm/io.h>
+#include <linux/iopoll.h>
+
+#define BSEC_OTP_MAX_VALUE		95
+
+#define BSEC_TIMEOUT_US			10000
+
+/* BSEC REGISTER OFFSET (base relative) */
+#define BSEC_OTP_CONF_OFF		0x000
+#define BSEC_OTP_CTRL_OFF		0x004
+#define BSEC_OTP_WRDATA_OFF		0x008
+#define BSEC_OTP_STATUS_OFF		0x00C
+#define BSEC_OTP_LOCK_OFF		0x010
+#define BSEC_DISTURBED_OFF		0x01C
+#define BSEC_ERROR_OFF			0x034
+#define BSEC_SPLOCK_OFF			0x064 /* Program safmem sticky lock */
+#define BSEC_SWLOCK_OFF			0x07C /* write in OTP sticky lock */
+#define BSEC_SRLOCK_OFF			0x094 /* shadowing sticky lock */
+#define BSEC_OTP_DATA_OFF		0x200
+
+/* BSEC_CONFIGURATION Register MASK */
+#define BSEC_CONF_POWER_UP		0x001
+
+/* BSEC_CONTROL Register */
+#define BSEC_READ			0x000
+#define BSEC_WRITE			0x100
+
+/* LOCK Register */
+#define OTP_LOCK_MASK			0x1F
+#define OTP_LOCK_BANK_SHIFT		0x05
+#define OTP_LOCK_BIT_MASK		0x01
+
+/* STATUS Register */
+#define BSEC_MODE_BUSY_MASK		0x08
+#define BSEC_MODE_PROGFAIL_MASK		0x10
+#define BSEC_MODE_PWR_MASK		0x20
+
+/*
+ * OTP Lock services definition
+ * Value must corresponding to the bit number in the register
+ */
+#define BSEC_LOCK_PROGRAM		0x04
+
+/**
+ * bsec_check_error() - Check status of one otp
+ * @base: base address of bsec IP
+ * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
+ * Return: 0 if no error, -EAGAIN or -ENOTSUPP
+ */
+static u32 bsec_check_error(u32 base, u32 otp)
+{
+	u32 bit;
+	u32 bank;
+
+	bit = 1 << (otp & OTP_LOCK_MASK);
+	bank = ((otp >> OTP_LOCK_BANK_SHIFT) & OTP_LOCK_MASK) * sizeof(u32);
+
+	if (readl(base + BSEC_DISTURBED_OFF + bank) & bit)
+		return -EAGAIN;
+	else if (readl(base + BSEC_ERROR_OFF + bank) & bit)
+		return -ENOTSUPP;
+
+	return 0;
+}
+
+/**
+ * bsec_lock() - manage lock for each type SR/SP/SW
+ * @address: address of bsec IP register
+ * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
+ * Return: true if locked else false
+ */
+static bool bsec_read_lock(u32 address, u32 otp)
+{
+	u32 bit;
+	u32 bank;
+
+	bit = 1 << (otp & OTP_LOCK_MASK);
+	bank = ((otp >> OTP_LOCK_BANK_SHIFT) & OTP_LOCK_MASK) * sizeof(u32);
+
+	return !!(readl(address + bank) & bit);
+}
+
+/**
+ * bsec_read_SR_lock() - read SR lock (Shadowing)
+ * @base: base address of bsec IP
+ * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
+ * Return: true if locked else false
+ */
+static bool bsec_read_SR_lock(u32 base, u32 otp)
+{
+	return bsec_read_lock(base + BSEC_SRLOCK_OFF, otp);
+}
+
+/**
+ * bsec_read_SP_lock() - read SP lock (program Lock)
+ * @base: base address of bsec IP
+ * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
+ * Return: true if locked else false
+ */
+static bool bsec_read_SP_lock(u32 base, u32 otp)
+{
+	return bsec_read_lock(base + BSEC_SPLOCK_OFF, otp);
+}
+
+/**
+ * bsec_SW_lock() - manage SW lock (Write in Shadow)
+ * @base: base address of bsec IP
+ * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
+ * Return: true if locked else false
+ */
+static bool bsec_read_SW_lock(u32 base, u32 otp)
+{
+	return bsec_read_lock(base + BSEC_SWLOCK_OFF, otp);
+}
+
+/**
+ * bsec_power_safmem() - Activate or deactivate safmem power
+ * @base: base address of bsec IP
+ * @power: true to power up , false to power down
+ * Return: 0 if succeed
+ */
+static int bsec_power_safmem(u32 base, bool power)
+{
+	u32 val;
+	u32 mask;
+
+	if (power) {
+		setbits_le32(base + BSEC_OTP_CONF_OFF, BSEC_CONF_POWER_UP);
+		mask = BSEC_MODE_PWR_MASK;
+	} else {
+		clrbits_le32(base + BSEC_OTP_CONF_OFF, BSEC_CONF_POWER_UP);
+		mask = 0;
+	}
+
+	/* waiting loop */
+	return readl_poll_timeout(base + BSEC_OTP_STATUS_OFF,
+				  val, (val & BSEC_MODE_PWR_MASK) == mask,
+				  BSEC_TIMEOUT_US);
+}
+
+/**
+ * bsec_shadow_register() - copy safmen otp to bsec data
+ * @base: base address of bsec IP
+ * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
+ * Return: 0 if no error
+ */
+static int bsec_shadow_register(u32 base, u32 otp)
+{
+	u32 val;
+	int ret;
+	bool power_up = false;
+
+	/* check if shadowing of otp is locked */
+	if (bsec_read_SR_lock(base, otp))
+		pr_debug("bsec : OTP %d is locked and refreshed with 0\n", otp);
+
+	/* check if safemem is power up */
+	val = readl(base + BSEC_OTP_STATUS_OFF);
+	if (!(val & BSEC_MODE_PWR_MASK)) {
+		ret = bsec_power_safmem(base, true);
+		if (ret)
+			return ret;
+		power_up = 1;
+	}
+	/* set BSEC_OTP_CTRL_OFF with the otp value*/
+	writel(otp | BSEC_READ, base + BSEC_OTP_CTRL_OFF);
+
+	/* check otp status*/
+	ret = readl_poll_timeout(base + BSEC_OTP_STATUS_OFF,
+				 val, (val & BSEC_MODE_BUSY_MASK) == 0,
+				 BSEC_TIMEOUT_US);
+	if (ret)
+		return ret;
+
+	ret = bsec_check_error(base, otp);
+
+	if (power_up)
+		bsec_power_safmem(base, false);
+
+	return ret;
+}
+
+/**
+ * bsec_read_shadow() - read an otp data value from shadow
+ * @base: base address of bsec IP
+ * @val: read value
+ * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
+ * Return: 0 if no error
+ */
+static int bsec_read_shadow(u32 base, u32 *val, u32 otp)
+{
+	*val = readl(base + BSEC_OTP_DATA_OFF + otp * sizeof(u32));
+
+	return bsec_check_error(base, otp);
+}
+
+/**
+ * bsec_write_shadow() - write value in BSEC data register in shadow
+ * @base: base address of bsec IP
+ * @val: value to write
+ * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
+ * Return: 0 if no error
+ */
+static int bsec_write_shadow(u32 base, u32 val, u32 otp)
+{
+	/* check if programming of otp is locked */
+	if (bsec_read_SW_lock(base, otp))
+		pr_debug("bsec : OTP %d is lock, write will be ignore\n", otp);
+
+	writel(val, base + BSEC_OTP_DATA_OFF + otp * sizeof(u32));
+
+	return bsec_check_error(base, otp);
+}
+
+/**
+ * bsec_program_otp() - program a bit in SAFMEM
+ * @base: base address of bsec IP
+ * @val: value to program
+ * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
+ * after the function the otp data is not refreshed in shadow
+ * Return: 0 if no error
+ */
+static int bsec_program_otp(long base, u32 val, u32 otp)
+{
+	u32 ret;
+	bool power_up = false;
+
+	if (bsec_read_SP_lock(base, otp))
+		pr_debug("bsec : OTP %d locked, prog will be ignore\n", otp);
+
+	if (readl(base + BSEC_OTP_LOCK_OFF) & (1 << BSEC_LOCK_PROGRAM))
+		pr_debug("bsec : Global lock, prog will be ignore\n");
+
+	/* check if safemem is power up */
+	if (!(readl(base + BSEC_OTP_STATUS_OFF) & BSEC_MODE_PWR_MASK)) {
+		ret = bsec_power_safmem(base, true);
+		if (ret)
+			return ret;
+
+		power_up = true;
+	}
+	/* set value in write register*/
+	writel(val, base + BSEC_OTP_WRDATA_OFF);
+
+	/* set BSEC_OTP_CTRL_OFF with the otp value */
+	writel(otp | BSEC_WRITE, base + BSEC_OTP_CTRL_OFF);
+
+	/* check otp status*/
+	ret = readl_poll_timeout(base + BSEC_OTP_STATUS_OFF,
+				 val, (val & BSEC_MODE_BUSY_MASK) == 0,
+				 BSEC_TIMEOUT_US);
+	if (ret)
+		return ret;
+
+	if (val & BSEC_MODE_PROGFAIL_MASK)
+		ret = -EACCES;
+	else
+		ret = bsec_check_error(base, otp);
+
+	if (power_up)
+		bsec_power_safmem(base, false);
+
+	return ret;
+}
+
+/* BSEC MISC driver *******************************************************/
+struct stm32mp_bsec_platdata {
+	u32 base;
+};
+
+static int stm32mp_bsec_read_otp(struct udevice *dev, u32 *val, u32 otp)
+{
+	struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
+	u32 tmp_data = 0;
+	int ret;
+
+	/* read current shadow value */
+	ret = bsec_read_shadow(plat->base, &tmp_data, otp);
+	if (ret)
+		return ret;
+
+	/* copy otp in shadow */
+	ret = bsec_shadow_register(plat->base, otp);
+	if (ret)
+		return ret;
+
+	ret = bsec_read_shadow(plat->base, val, otp);
+	if (ret)
+		return ret;
+
+	/* restore shadow value */
+	ret = bsec_write_shadow(plat->base, tmp_data, otp);
+	return ret;
+}
+
+static int stm32mp_bsec_read_shadow(struct udevice *dev, u32 *val, u32 otp)
+{
+	struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
+
+	return bsec_read_shadow(plat->base, val, otp);
+}
+
+static int stm32mp_bsec_write_otp(struct udevice *dev, u32 val, u32 otp)
+{
+	struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
+
+	return bsec_program_otp(plat->base, val, otp);
+}
+
+static int stm32mp_bsec_write_shadow(struct udevice *dev, u32 val, u32 otp)
+{
+	struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
+
+	return bsec_write_shadow(plat->base, val, otp);
+}
+
+static int stm32mp_bsec_read(struct udevice *dev, int offset,
+			     void *buf, int size)
+{
+	int ret;
+	int i;
+	bool shadow = true;
+	int nb_otp = size / sizeof(u32);
+	int otp;
+
+	if (offset >= STM32_BSEC_OTP_OFFSET) {
+		offset -= STM32_BSEC_OTP_OFFSET;
+		shadow = false;
+	}
+	otp = offset / sizeof(u32);
+
+	if (otp < 0 || (otp + nb_otp - 1) > BSEC_OTP_MAX_VALUE) {
+		dev_err(dev, "wrong value for otp, max value : %i\n",
+			BSEC_OTP_MAX_VALUE);
+		return -EINVAL;
+	}
+
+	for (i = otp; i < (otp + nb_otp); i++) {
+		u32 *addr = &((u32 *)buf)[i - otp];
+
+		if (shadow)
+			ret = stm32mp_bsec_read_shadow(dev, addr, i);
+		else
+			ret = stm32mp_bsec_read_otp(dev, addr, i);
+
+		if (ret)
+			break;
+	}
+	return ret;
+}
+
+static int stm32mp_bsec_write(struct udevice *dev, int offset,
+			      const void *buf, int size)
+{
+	int ret = 0;
+	int i;
+	bool shadow = true;
+	int nb_otp = size / sizeof(u32);
+	int otp;
+
+	if (offset >= STM32_BSEC_OTP_OFFSET) {
+		offset -= STM32_BSEC_OTP_OFFSET;
+		shadow = false;
+	}
+	otp = offset / sizeof(u32);
+
+	if (otp < 0 || (otp + nb_otp - 1) > BSEC_OTP_MAX_VALUE) {
+		dev_err(dev, "wrong value for otp, max value : %d\n",
+			BSEC_OTP_MAX_VALUE);
+		return -EINVAL;
+	}
+
+	for (i = otp; i < otp + nb_otp; i++) {
+		u32 *val = &((u32 *)buf)[i - otp];
+
+		if (shadow)
+			ret = stm32mp_bsec_write_shadow(dev, *val, i);
+		else
+			ret = stm32mp_bsec_write_otp(dev, *val, i);
+		if (ret)
+			break;
+	}
+	return ret;
+}
+
+static const struct misc_ops stm32mp_bsec_ops = {
+	.read = stm32mp_bsec_read,
+	.write = stm32mp_bsec_write,
+};
+
+static int stm32mp_bsec_ofdata_to_platdata(struct udevice *dev)
+{
+	struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
+
+	plat->base = (u32)dev_read_addr_ptr(dev);
+
+	return 0;
+}
+
+static const struct udevice_id stm32mp_bsec_ids[] = {
+	{ .compatible = "st,stm32mp-bsec" },
+	{}
+};
+
+U_BOOT_DRIVER(stm32mp_bsec) = {
+	.name = "stm32mp_bsec",
+	.id = UCLASS_MISC,
+	.of_match = stm32mp_bsec_ids,
+	.ofdata_to_platdata = stm32mp_bsec_ofdata_to_platdata,
+	.platdata_auto_alloc_size = sizeof(struct stm32mp_bsec_platdata),
+	.ops = &stm32mp_bsec_ops,
+	.flags  = DM_FLAG_PRE_RELOC,
+};
+
+/* bsec IP is not present in device tee, manage IP address by platdata */
+static struct stm32mp_bsec_platdata stm32_bsec_platdata = {
+	.base = STM32_BSEC_BASE,
+};
+
+U_BOOT_DEVICE(stm32mp_bsec) = {
+	.name = "stm32mp_bsec",
+	.platdata = &stm32_bsec_platdata,
+};
diff --git a/arch/arm/mach-stm32mp/cpu.c b/arch/arm/mach-stm32mp/cpu.c
index dfcbbd2..0e01f8e 100644
--- a/arch/arm/mach-stm32mp/cpu.c
+++ b/arch/arm/mach-stm32mp/cpu.c
@@ -4,9 +4,13 @@
  */
 #include <common.h>
 #include <clk.h>
+#include <debug_uart.h>
+#include <environment.h>
+#include <misc.h>
 #include <asm/io.h>
 #include <asm/arch/stm32.h>
 #include <asm/arch/sys_proto.h>
+#include <dm/device.h>
 #include <dm/uclass.h>
 
 /* RCC register */
@@ -50,6 +54,10 @@
 #define BOOTROM_INSTANCE_MASK	 GENMASK(31, 16)
 #define BOOTROM_INSTANCE_SHIFT	16
 
+/* BSEC OTP index */
+#define BSEC_OTP_SERIAL	13
+#define BSEC_OTP_MAC	57
+
 #if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)
 static void security_init(void)
 {
@@ -152,6 +160,8 @@
  */
 int arch_cpu_init(void)
 {
+	u32 boot_mode;
+
 	/* early armv7 timer init: needed for polling */
 	timer_init();
 
@@ -160,8 +170,17 @@
 
 	security_init();
 #endif
+
 	/* get bootmode from BootRom context: saved in TAMP register */
-	get_bootmode();
+	boot_mode = get_bootmode();
+
+	if ((boot_mode & TAMP_BOOT_DEVICE_MASK) == BOOT_SERIAL_UART)
+		gd->flags |= GD_FLG_SILENT | GD_FLG_DISABLE_CONSOLE;
+#if defined(CONFIG_DEBUG_UART) && \
+	(!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD))
+	else
+		debug_uart_init();
+#endif
 
 	return 0;
 }
@@ -262,9 +281,83 @@
 	}
 }
 
+/*
+ * If there is no MAC address in the environment, then it will be initialized
+ * (silently) from the value in the OTP.
+ */
+static int setup_mac_address(void)
+{
+#if defined(CONFIG_NET)
+	int ret;
+	int i;
+	u32 otp[2];
+	uchar enetaddr[6];
+	struct udevice *dev;
+
+	/* MAC already in environment */
+	if (eth_env_get_enetaddr("ethaddr", enetaddr))
+		return 0;
+
+	ret = uclass_get_device_by_driver(UCLASS_MISC,
+					  DM_GET_DRIVER(stm32mp_bsec),
+					  &dev);
+	if (ret)
+		return ret;
+
+	ret = misc_read(dev, BSEC_OTP_MAC * 4 + STM32_BSEC_OTP_OFFSET,
+			otp, sizeof(otp));
+	if (ret)
+		return ret;
+
+	for (i = 0; i < 6; i++)
+		enetaddr[i] = ((uint8_t *)&otp)[i];
+
+	if (!is_valid_ethaddr(enetaddr)) {
+		pr_err("invalid MAC address in OTP %pM", enetaddr);
+		return -EINVAL;
+	}
+	pr_debug("OTP MAC address = %pM\n", enetaddr);
+	ret = !eth_env_set_enetaddr("ethaddr", enetaddr);
+	if (!ret)
+		pr_err("Failed to set mac address %pM from OTP: %d\n",
+		       enetaddr, ret);
+#endif
+
+	return 0;
+}
+
+static int setup_serial_number(void)
+{
+	char serial_string[25];
+	u32 otp[3] = {0, 0, 0 };
+	struct udevice *dev;
+	int ret;
+
+	if (env_get("serial#"))
+		return 0;
+
+	ret = uclass_get_device_by_driver(UCLASS_MISC,
+					  DM_GET_DRIVER(stm32mp_bsec),
+					  &dev);
+	if (ret)
+		return ret;
+
+	ret = misc_read(dev, BSEC_OTP_SERIAL * 4 + STM32_BSEC_OTP_OFFSET,
+			otp, sizeof(otp));
+	if (ret)
+		return ret;
+
+	sprintf(serial_string, "%08x%08x%08x", otp[0], otp[1], otp[2]);
+	env_set("serial#", serial_string);
+
+	return 0;
+}
+
 int arch_misc_init(void)
 {
 	setup_boot_mode();
+	setup_mac_address();
+	setup_serial_number();
 
 	return 0;
 }
diff --git a/arch/arm/mach-stm32mp/include/mach/stm32.h b/arch/arm/mach-stm32mp/include/mach/stm32.h
index a814201..5d0bdca 100644
--- a/arch/arm/mach-stm32mp/include/mach/stm32.h
+++ b/arch/arm/mach-stm32mp/include/mach/stm32.h
@@ -13,10 +13,23 @@
 #define STM32_RCC_BASE			0x50000000
 #define STM32_PWR_BASE			0x50001000
 #define STM32_DBGMCU_BASE		0x50081000
+#define STM32_BSEC_BASE			0x5C005000
 #define STM32_TZC_BASE			0x5C006000
 #define STM32_ETZPC_BASE		0x5C007000
 #define STM32_TAMP_BASE			0x5C00A000
 
+#ifdef CONFIG_DEBUG_UART_BASE
+/* hardcoded value can be only used for DEBUG UART */
+#define STM32_USART1_BASE		0x5C000000
+#define STM32_USART2_BASE		0x4000E000
+#define STM32_USART3_BASE		0x4000F000
+#define STM32_UART4_BASE		0x40010000
+#define STM32_UART5_BASE		0x40011000
+#define STM32_USART6_BASE		0x44003000
+#define STM32_UART7_BASE		0x40018000
+#define STM32_UART8_BASE		0x40019000
+#endif
+
 #define STM32_SYSRAM_BASE		0x2FFC0000
 #define STM32_SYSRAM_SIZE		SZ_256K
 
@@ -83,5 +96,9 @@
 #define TAMP_BOOT_DEVICE_MASK		GENMASK(7, 4)
 #define TAMP_BOOT_INSTANCE_MASK		GENMASK(3, 0)
 
+/* offset used for BSEC driver: misc_read and misc_write */
+#define STM32_BSEC_SHADOW_OFFSET	0x0
+#define STM32_BSEC_OTP_OFFSET		0x80000000
+
 #endif /* __ASSEMBLY__*/
 #endif /* _MACH_STM32_H_ */
diff --git a/arch/arm/mach-stm32mp/spl.c b/arch/arm/mach-stm32mp/spl.c
index b56f0c5..790973e 100644
--- a/arch/arm/mach-stm32mp/spl.c
+++ b/arch/arm/mach-stm32mp/spl.c
@@ -14,9 +14,6 @@
 
 	boot_mode = (readl(TAMP_BOOT_CONTEXT) & TAMP_BOOT_MODE_MASK) >>
 		    TAMP_BOOT_MODE_SHIFT;
-	clrsetbits_le32(TAMP_BOOT_CONTEXT,
-			TAMP_BOOT_MODE_MASK,
-			boot_mode << TAMP_BOOT_MODE_SHIFT);
 
 	switch (boot_mode) {
 	case BOOT_FLASH_SD_1:
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index c50be37..20a43d8 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -8,12 +8,12 @@
 	prompt "Target select"
 	optional
 
-config TARGET_NX25_AE250
-	bool "Support nx25-ae250"
+config TARGET_AX25_AE350
+	bool "Support ax25-ae350"
 
 endchoice
 
-source "board/AndesTech/nx25-ae250/Kconfig"
+source "board/AndesTech/ax25-ae350/Kconfig"
 
 choice
 	prompt "CPU selection"
diff --git a/arch/riscv/config.mk b/arch/riscv/config.mk
index a7448e2..219e666 100644
--- a/arch/riscv/config.mk
+++ b/arch/riscv/config.mk
@@ -19,15 +19,20 @@
 
 ifdef CONFIG_32BIT
 PLATFORM_LDFLAGS	+= -m $(32bit-emul)
+EFI_LDS			:= elf_riscv32_efi.lds
 endif
 
 ifdef CONFIG_64BIT
 PLATFORM_LDFLAGS	+= -m $(64bit-emul)
+EFI_LDS			:= elf_riscv64_efi.lds
 endif
 
 CONFIG_STANDALONE_LOAD_ADDR = 0x00000000 \
 			      -T $(srctree)/examples/standalone/riscv.lds
 
 PLATFORM_CPPFLAGS	+= -ffixed-gp -fpic
-PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -gdwarf-2
+PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -gdwarf-2 -ffunction-sections
 LDFLAGS_u-boot += --gc-sections -static -pie
+
+EFI_CRT0		:= crt0_riscv_efi.o
+EFI_RELOC		:= reloc_riscv_efi.o
diff --git a/arch/riscv/cpu/nx25/Makefile b/arch/riscv/cpu/ax25/Makefile
similarity index 100%
rename from arch/riscv/cpu/nx25/Makefile
rename to arch/riscv/cpu/ax25/Makefile
diff --git a/arch/riscv/cpu/nx25/cpu.c b/arch/riscv/cpu/ax25/cpu.c
similarity index 92%
rename from arch/riscv/cpu/nx25/cpu.c
rename to arch/riscv/cpu/ax25/cpu.c
index 091e9ef..ab05b57 100644
--- a/arch/riscv/cpu/nx25/cpu.c
+++ b/arch/riscv/cpu/ax25/cpu.c
@@ -28,5 +28,5 @@
 int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
 	disable_interrupts();
-	panic("nx25-ae250 wdt not support yet.\n");
+	panic("ax25-ae350 wdt not support yet.\n");
 }
diff --git a/arch/riscv/cpu/nx25/start.S b/arch/riscv/cpu/ax25/start.S
similarity index 100%
rename from arch/riscv/cpu/nx25/start.S
rename to arch/riscv/cpu/ax25/start.S
diff --git a/arch/riscv/cpu/nx25/u-boot.lds b/arch/riscv/cpu/ax25/u-boot.lds
similarity index 71%
rename from arch/riscv/cpu/nx25/u-boot.lds
rename to arch/riscv/cpu/ax25/u-boot.lds
index 86ebc9f..1589bab 100644
--- a/arch/riscv/cpu/nx25/u-boot.lds
+++ b/arch/riscv/cpu/ax25/u-boot.lds
@@ -11,7 +11,7 @@
 	. = ALIGN(4);
 	.text :
 	{
-		arch/riscv/cpu/nx25/start.o	(.text)
+		arch/riscv/cpu/ax25/start.o	(.text)
 		*(.text)
 	}
 
@@ -39,6 +39,22 @@
 
     . = ALIGN(4);
 
+	.efi_runtime : {
+                __efi_runtime_start = .;
+		*(efi_runtime_text)
+		*(efi_runtime_data)
+                __efi_runtime_stop = .;
+	}
+
+	.efi_runtime_rel : {
+                __efi_runtime_rel_start = .;
+		*(.relaefi_runtime_text)
+		*(.relaefi_runtime_data)
+                __efi_runtime_rel_stop = .;
+	}
+
+    . = ALIGN(4);
+
     /DISCARD/ : { *(.rela.plt*) }
     .rela.dyn : {
         __rel_dyn_start = .;
diff --git a/arch/riscv/dts/Makefile b/arch/riscv/dts/Makefile
index 7936775..a1b06ff 100644
--- a/arch/riscv/dts/Makefile
+++ b/arch/riscv/dts/Makefile
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0+
 
-dtb-$(CONFIG_TARGET_NX25_AE250) += ae250.dtb
+dtb-$(CONFIG_TARGET_AX25_AE350) += ae350.dtb
 targets += $(dtb-y)
 
 DTC_FLAGS += -R 4 -p 0x1000
diff --git a/arch/riscv/dts/ae250.dts b/arch/riscv/dts/ae250.dts
deleted file mode 100644
index 9a38345..0000000
--- a/arch/riscv/dts/ae250.dts
+++ /dev/null
@@ -1,97 +0,0 @@
-/dts-v1/;
-/ {
-	compatible = "riscv32 nx25";
-	#address-cells = <1>;
-	#size-cells = <1>;
-	interrupt-parent = <&intc>;
-
-	aliases {
-		uart0 = &serial0;
-		ethernet0 = &mac0;
-		spi0 = &spi;
-	} ;
-
-	chosen {
-		bootargs = "console=ttyS0,38400n8 earlyprintk=uart8250-32bit,0xf0300000 debug loglevel=7";
-		stdout-path = "uart0:38400n8";
-		tick-timer = &timer0;
-	};
-
-	memory@0 {
-		device_type = "memory";
-		reg = <0x00000000 0x40000000>;
-	};
-
-	spiclk: virt_100mhz {
-		#clock-cells = <0>;
-		compatible = "fixed-clock";
-		clock-frequency = <100000000>;
-	};
-
-	cpus {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		cpu@0 {
-			compatible = "andestech,n13";
-			reg = <0>;
-			/* FIXME: to fill correct frqeuency */
-			clock-frequency = <60000000>;
-		};
-	};
-
-	intc: interrupt-controller {
-		compatible = "andestech,atnointc010";
-		#interrupt-cells = <1>;
-		interrupt-controller;
-	};
-
-	serial0: serial@f0300000 {
-		compatible = "andestech,uart16550", "ns16550a";
-		reg = <0xf0300000 0x1000>;
-		interrupts = <7 4>;
-		clock-frequency = <19660800>;
-		reg-shift = <2>;
-		reg-offset = <32>;
-		no-loopback-test = <1>;
-	};
-
-	timer0: timer@f0400000 {
-		compatible = "andestech,atcpit100";
-		reg = <0xf0400000 0x1000>;
-		interrupts = <2 4>;
-		clock-frequency = <40000000>;
-	};
-
-	mac0: mac@e0100000 {
-		compatible = "andestech,atmac100";
-		reg = <0xe0100000 0x1000>;
-		interrupts = <25 4>;
-	};
-
-	mmc0: mmc@f0e00000 {
-		compatible = "andestech,atsdc010";
-		max-frequency = <100000000>;
-		fifo-depth = <0x10>;
-		reg = <0xf0e00000 0x1000>;
-		interrupts = <17 4>;
-		cap-sd-highspeed;
-	};
-
-	spi: spi@f0b00000 {
-		compatible = "andestech,atcspi200";
-		reg = <0xf0b00000 0x1000>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		num-cs = <1>;
-		clocks = <&spiclk>;
-		interrupts = <3 4>;
-			flash@0 {
-			compatible = "spi-flash";
-			spi-max-frequency = <50000000>;
-			reg = <0>;
-			spi-cpol;
-			spi-cpha;
-		};
-	};
-
-};
diff --git a/arch/riscv/dts/ae350.dts b/arch/riscv/dts/ae350.dts
new file mode 100644
index 0000000..2927e41
--- /dev/null
+++ b/arch/riscv/dts/ae350.dts
@@ -0,0 +1,149 @@
+/dts-v1/;
+
+/ {
+  #address-cells = <2>;
+  #size-cells = <2>;
+  compatible = "andestech,ax25";
+  model = "andestech,ax25";
+
+	aliases {
+		uart0 = &serial0;
+		spi0 = &spi;
+	} ;
+
+	chosen {
+		bootargs = "console=ttyS0,38400n8 earlyprintk=uart8250-32bit,0xf0300000 debug loglevel=7";
+		stdout-path = "uart0:38400n8";
+  };
+
+  cpus {
+    #address-cells = <1>;
+    #size-cells = <0>;
+    timebase-frequency = <10000000>;
+    CPU0: cpu@0 {
+      device_type = "cpu";
+      reg = <0>;
+      status = "okay";
+      compatible = "riscv";
+      riscv,isa = "rv64imafdc";
+      mmu-type = "riscv,sv39";
+      clock-frequency = <60000000>;
+      CPU0_intc: interrupt-controller {
+        #interrupt-cells = <1>;
+        interrupt-controller;
+        compatible = "riscv,cpu-intc";
+      };
+    };
+	};
+
+	memory@0 {
+		device_type = "memory";
+    reg = <0x0 0x00000000 0x0 0x40000000>;
+	};
+
+  soc {
+    #address-cells = <2>;
+    #size-cells = <2>;
+    compatible = "andestech,riscv-ae350-soc";
+    ranges;
+	};
+
+  plmt0@e6000000 {
+    compatible = "riscv,plmt0";
+    interrupts-extended = <&CPU0_intc 7>;
+    reg = <0x0 0xe6000000 0x0 0x100000>;
+		};
+
+  plic0: interrupt-controller@e4000000 {
+    compatible = "riscv,plic0";
+    #address-cells = <2>;
+    #interrupt-cells = <2>;
+    interrupt-controller;
+    reg = <0x0 0xe4000000 0x0 0x2000000>;
+    riscv,ndev=<31>;
+    interrupts-extended = <&CPU0_intc 11 &CPU0_intc 9>;
+	};
+
+  plic1: interrupt-controller@e6400000 {
+    compatible = "riscv,plic1";
+    #address-cells = <2>;
+    #interrupt-cells = <2>;
+		interrupt-controller;
+    reg = <0x0 0xe6400000 0x0 0x400000>;
+    riscv,ndev=<1>;
+    interrupts-extended = <&CPU0_intc 3>;
+  };
+
+  spiclk: virt_100mhz {
+    #clock-cells = <0>;
+    compatible = "fixed-clock";
+    clock-frequency = <100000000>;
+  };
+
+  timer0: timer@f0400000 {
+    compatible = "andestech,atcpit100";
+    reg = <0x0 0xf0400000 0x0 0x1000>;
+    clock-frequency = <40000000>;
+    interrupts = <3 4>;
+    interrupt-parent = <&plic0>;
+	};
+
+	serial0: serial@f0300000 {
+		compatible = "andestech,uart16550", "ns16550a";
+    reg = <0x0 0xf0300000 0x0 0x1000>;
+    interrupts = <9 4>;
+		clock-frequency = <19660800>;
+		reg-shift = <2>;
+		reg-offset = <32>;
+		no-loopback-test = <1>;
+    interrupt-parent = <&plic0>;
+	};
+
+	mac0: mac@e0100000 {
+		compatible = "andestech,atmac100";
+    reg = <0x0 0xe0100000 0x0 0x1000>;
+    interrupts = <19 4>;
+    interrupt-parent = <&plic0>;
+	};
+
+	mmc0: mmc@f0e00000 {
+    compatible = "andestech,atfsdc010";
+		max-frequency = <100000000>;
+    clock-freq-min-max = <400000 100000000>;
+		fifo-depth = <0x10>;
+    reg = <0x0 0xf0e00000 0x0 0x1000>;
+    interrupts = <18 4>;
+		cap-sd-highspeed;
+    interrupt-parent = <&plic0>;
+	};
+
+  smc0: smc@e0400000 {
+    compatible = "andestech,atfsmc020";
+    reg = <0x0 0xe0400000 0x0 0x1000>;
+  };
+
+  nor@0,0 {
+    compatible = "cfi-flash";
+    reg = <0x0 0x88000000 0x0 0x1000>;
+    bank-width = <2>;
+    device-width = <1>;
+  };
+
+	spi: spi@f0b00000 {
+		compatible = "andestech,atcspi200";
+    reg = <0x0 0xf0b00000 0x0 0x1000>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		num-cs = <1>;
+		clocks = <&spiclk>;
+		interrupts = <3 4>;
+    interrupt-parent = <&plic0>;
+			flash@0 {
+			compatible = "spi-flash";
+			spi-max-frequency = <50000000>;
+			reg = <0>;
+			spi-cpol;
+			spi-cpha;
+		};
+	};
+};
diff --git a/arch/riscv/include/asm/mach-types.h b/arch/riscv/include/asm/mach-types.h
index 93afff7..f219ced 100644
--- a/arch/riscv/include/asm/mach-types.h
+++ b/arch/riscv/include/asm/mach-types.h
@@ -12,18 +12,18 @@
 extern unsigned int __machine_arch_type;
 #endif
 
-#define MACH_TYPE_AE250		1
+#define MACH_TYPE_AE350		1
 
-#ifdef CONFIG_ARCH_AE250
+#ifdef CONFIG_ARCH_AE350
 # ifdef machine_arch_type
 #  undef machine_arch_type
 #  define machine_arch_type __machine_arch_type
 # else
-#  define machine_arch_type MACH_TYPE_AE250
+#  define machine_arch_type MACH_TYPE_AE350
 # endif
-# define machine_is_ae250() (machine_arch_type == MACH_TYPE_AE250)
+# define machine_is_ae350() (machine_arch_type == MACH_TYPE_AE350)
 #else
-# define machine_is_ae250() (1)
+# define machine_is_ae350() (1)
 #endif
 
 #endif /* __ASM_RISCV_MACH_TYPE_H */
diff --git a/arch/riscv/include/asm/setjmp.h b/arch/riscv/include/asm/setjmp.h
new file mode 100644
index 0000000..72383d4
--- /dev/null
+++ b/arch/riscv/include/asm/setjmp.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2018 Alexander Graf <agraf@suse.de>
+ */
+
+#ifndef _SETJMP_H_
+#define _SETJMP_H_	1
+
+/*
+ * This really should be opaque, but the EFI implementation wrongly
+ * assumes that a 'struct jmp_buf_data' is defined.
+ */
+struct jmp_buf_data {
+	/* x2, x8, x9, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, sp */
+	unsigned long s_regs[12];	/* s0 - s11 */
+	unsigned long ra;
+	unsigned long sp;
+};
+
+typedef struct jmp_buf_data jmp_buf[1];
+
+int setjmp(jmp_buf jmp);
+void longjmp(jmp_buf jmp, int ret);
+
+#endif /* _SETJMP_H_ */
diff --git a/arch/riscv/include/asm/u-boot-riscv.h b/arch/riscv/include/asm/u-boot-riscv.h
index c4c068f..49febd5 100644
--- a/arch/riscv/include/asm/u-boot-riscv.h
+++ b/arch/riscv/include/asm/u-boot-riscv.h
@@ -16,5 +16,6 @@
 
 /* board/.../... */
 int board_init(void);
+void board_quiesce_devices(void);
 
 #endif	/* _U_BOOT_RISCV_H_ */
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index 0b671f7..cc562f9 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -10,3 +10,15 @@
 obj-$(CONFIG_CMD_GO) += boot.o
 obj-y	+= cache.o
 obj-y	+= interrupts.o
+obj-y   += setjmp.o
+
+# For building EFI apps
+CFLAGS_$(EFI_CRT0) := $(CFLAGS_EFI)
+CFLAGS_REMOVE_$(EFI_CRT0) := $(CFLAGS_NON_EFI)
+
+CFLAGS_$(EFI_RELOC) := $(CFLAGS_EFI)
+CFLAGS_REMOVE_$(EFI_RELOC) := $(CFLAGS_NON_EFI)
+
+extra-$(CONFIG_CMD_BOOTEFI_HELLO_COMPILE) += $(EFI_CRT0) $(EFI_RELOC)
+extra-$(CONFIG_CMD_BOOTEFI_SELFTEST) += $(EFI_CRT0) $(EFI_RELOC)
+extra-$(CONFIG_EFI) += $(EFI_CRT0) $(EFI_RELOC)
diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c
index 8ede048..2610a57 100644
--- a/arch/riscv/lib/bootm.c
+++ b/arch/riscv/lib/bootm.c
@@ -15,6 +15,10 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+__weak void board_quiesce_devices(void)
+{
+}
+
 int arch_fixup_fdt(void *blob)
 {
 	return 0;
diff --git a/arch/riscv/lib/crt0_riscv_efi.S b/arch/riscv/lib/crt0_riscv_efi.S
new file mode 100644
index 0000000..18f61f5
--- /dev/null
+++ b/arch/riscv/lib/crt0_riscv_efi.S
@@ -0,0 +1,151 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * crt0-efi-riscv.S - PE/COFF header for RISC-V EFI applications
+ *
+ * Copright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
+ * Copright (C) 2018 Alexander Graf <agraf@suse.de>
+ *
+ * This file is inspired by arch/arm/lib/crt0_aarch64_efi.S
+ */
+
+#include <asm-generic/pe.h>
+
+#if __riscv_xlen == 64
+#define SIZE_LONG	8
+#define SAVE_LONG(reg, idx)	sd	reg, (idx*SIZE_LONG)(sp)
+#define LOAD_LONG(reg, idx)	ld	reg, (idx*SIZE_LONG)(sp)
+#define PE_MACHINE	0x5064
+#else
+#define SIZE_LONG	4
+#define SAVE_LONG(reg, idx)	sw	reg, (idx*SIZE_LONG)(sp)
+#define LOAD_LONG(reg, idx)	lw	reg, (idx*SIZE_LONG)(sp)
+#define PE_MACHINE	0x5032
+#endif
+
+
+	.section	.text.head
+
+	/*
+	 * Magic "MZ" signature for PE/COFF
+	 */
+	.globl	ImageBase
+ImageBase:
+	.ascii	"MZ"
+	.skip	58				/* 'MZ' + pad + offset == 64 */
+	.long	pe_header - ImageBase		/* Offset to the PE header */
+pe_header:
+	.ascii	"PE"
+	.short	0
+coff_header:
+	.short	PE_MACHINE			/* RISC-V 64/32-bit */
+	.short	2				/* nr_sections */
+	.long	0				/* TimeDateStamp */
+	.long	0				/* PointerToSymbolTable */
+	.long	1				/* NumberOfSymbols */
+	.short	section_table - optional_header	/* SizeOfOptionalHeader */
+	/*
+	 * Characteristics: IMAGE_FILE_DEBUG_STRIPPED |
+	 * IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_LINE_NUMS_STRIPPED
+	 */
+	.short	0x206
+optional_header:
+	.short	0x20b				/* PE32+ format */
+	.byte	0x02				/* MajorLinkerVersion */
+	.byte	0x14				/* MinorLinkerVersion */
+	.long	_edata - _start			/* SizeOfCode */
+	.long	0				/* SizeOfInitializedData */
+	.long	0				/* SizeOfUninitializedData */
+	.long	_start - ImageBase		/* AddressOfEntryPoint */
+	.long	_start - ImageBase		/* BaseOfCode */
+
+extra_header_fields:
+	.quad	0				/* ImageBase */
+	.long	0x20				/* SectionAlignment */
+	.long	0x8				/* FileAlignment */
+	.short	0				/* MajorOperatingSystemVersion */
+	.short	0				/* MinorOperatingSystemVersion */
+	.short	0				/* MajorImageVersion */
+	.short	0				/* MinorImageVersion */
+	.short	0				/* MajorSubsystemVersion */
+	.short	0				/* MinorSubsystemVersion */
+	.long	0				/* Win32VersionValue */
+
+	.long	_edata - ImageBase		/* SizeOfImage */
+
+	/*
+	 * Everything before the kernel image is considered part of the header
+	 */
+	.long	_start - ImageBase		/* SizeOfHeaders */
+	.long	0				/* CheckSum */
+	.short	IMAGE_SUBSYSTEM_EFI_APPLICATION /* Subsystem */
+	.short	0				/* DllCharacteristics */
+	.quad	0				/* SizeOfStackReserve */
+	.quad	0				/* SizeOfStackCommit */
+	.quad	0				/* SizeOfHeapReserve */
+	.quad	0				/* SizeOfHeapCommit */
+	.long	0				/* LoaderFlags */
+	.long	0x6				/* NumberOfRvaAndSizes */
+
+	.quad	0				/* ExportTable */
+	.quad	0				/* ImportTable */
+	.quad	0				/* ResourceTable */
+	.quad	0				/* ExceptionTable */
+	.quad	0				/* CertificationTable */
+	.quad	0				/* BaseRelocationTable */
+
+	/* Section table */
+section_table:
+
+	/*
+	 * The EFI application loader requires a relocation section
+	 * because EFI applications must be relocatable.  This is a
+	 * dummy section as far as we are concerned.
+	 */
+	.ascii	".reloc"
+	.byte	0
+	.byte	0			/* end of 0 padding of section name */
+	.long	0
+	.long	0
+	.long	0			/* SizeOfRawData */
+	.long	0			/* PointerToRawData */
+	.long	0			/* PointerToRelocations */
+	.long	0			/* PointerToLineNumbers */
+	.short	0			/* NumberOfRelocations */
+	.short	0			/* NumberOfLineNumbers */
+	.long	0x42100040		/* Characteristics (section flags) */
+
+
+	.ascii	".text"
+	.byte	0
+	.byte	0
+	.byte	0			/* end of 0 padding of section name */
+	.long	_edata - _start		/* VirtualSize */
+	.long	_start - ImageBase	/* VirtualAddress */
+	.long	_edata - _start		/* SizeOfRawData */
+	.long	_start - ImageBase	/* PointerToRawData */
+
+	.long	0		/* PointerToRelocations (0 for executables) */
+	.long	0		/* PointerToLineNumbers (0 for executables) */
+	.short	0		/* NumberOfRelocations  (0 for executables) */
+	.short	0		/* NumberOfLineNumbers  (0 for executables) */
+	.long	0xe0500020	/* Characteristics (section flags) */
+
+_start:
+	addi		sp, sp, -(SIZE_LONG * 3)
+	SAVE_LONG(a0, 0)
+	SAVE_LONG(a1, 1)
+	SAVE_LONG(ra, 2)
+
+	lla		a0, ImageBase
+	lla		a1, _DYNAMIC
+	call		_relocate
+	bne		a0, zero, 0f
+
+	LOAD_LONG(a1, 1)
+	LOAD_LONG(a0, 0)
+	call		efi_main
+
+	LOAD_LONG(ra, 2)
+
+0:	addi		sp, sp, (SIZE_LONG * 3)
+	ret
diff --git a/arch/riscv/lib/elf_riscv32_efi.lds b/arch/riscv/lib/elf_riscv32_efi.lds
new file mode 100644
index 0000000..629705f
--- /dev/null
+++ b/arch/riscv/lib/elf_riscv32_efi.lds
@@ -0,0 +1,71 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * U-Boot riscv32 EFI linker script
+ *
+ * SPDX-License-Identifier:	BSD-2-Clause
+ *
+ * Modified from arch/arm/lib/elf_aarch64_efi.lds
+ */
+
+OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv")
+OUTPUT_ARCH(riscv)
+ENTRY(_start)
+SECTIONS
+{
+	.text 0x0 : {
+		_text = .;
+		*(.text.head)
+		*(.text)
+		*(.text.*)
+		*(.gnu.linkonce.t.*)
+		*(.srodata)
+		*(.rodata*)
+		. = ALIGN(16);
+	}
+	_etext = .;
+	_text_size = . - _text;
+	.dynamic  : { *(.dynamic) }
+	.data : {
+		_data = .;
+		*(.sdata)
+		*(.data)
+		*(.data1)
+		*(.data.*)
+		*(.got.plt)
+		*(.got)
+
+		/*
+		 * The EFI loader doesn't seem to like a .bss section, so we
+		 * stick it all into .data:
+		 */
+		. = ALIGN(16);
+		_bss = .;
+		*(.sbss)
+		*(.scommon)
+		*(.dynbss)
+		*(.bss)
+		*(.bss.*)
+		*(COMMON)
+		. = ALIGN(16);
+		_bss_end = .;
+		_edata = .;
+	}
+	.rela.dyn : { *(.rela.dyn) }
+	.rela.plt : { *(.rela.plt) }
+	.rela.got : { *(.rela.got) }
+	.rela.data : { *(.rela.data) *(.rela.data*) }
+	_data_size = . - _etext;
+
+	. = ALIGN(4096);
+	.dynsym   : { *(.dynsym) }
+	. = ALIGN(4096);
+	.dynstr   : { *(.dynstr) }
+	. = ALIGN(4096);
+	.note.gnu.build-id : { *(.note.gnu.build-id) }
+	/DISCARD/ : {
+		*(.rel.reloc)
+		*(.eh_frame)
+		*(.note.GNU-stack)
+	}
+	.comment 0 : { *(.comment) }
+}
diff --git a/arch/riscv/lib/elf_riscv64_efi.lds b/arch/riscv/lib/elf_riscv64_efi.lds
new file mode 100644
index 0000000..aece030
--- /dev/null
+++ b/arch/riscv/lib/elf_riscv64_efi.lds
@@ -0,0 +1,71 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * U-Boot riscv64 EFI linker script
+ *
+ * SPDX-License-Identifier:	BSD-2-Clause
+ *
+ * Modified from arch/arm/lib/elf_aarch64_efi.lds
+ */
+
+OUTPUT_FORMAT("elf64-littleriscv", "elf64-littleriscv", "elf64-littleriscv")
+OUTPUT_ARCH(riscv)
+ENTRY(_start)
+SECTIONS
+{
+	.text 0x0 : {
+		_text = .;
+		*(.text.head)
+		*(.text)
+		*(.text.*)
+		*(.gnu.linkonce.t.*)
+		*(.srodata)
+		*(.rodata*)
+		. = ALIGN(16);
+	}
+	_etext = .;
+	_text_size = . - _text;
+	.dynamic  : { *(.dynamic) }
+	.data : {
+		_data = .;
+		*(.sdata)
+		*(.data)
+		*(.data1)
+		*(.data.*)
+		*(.got.plt)
+		*(.got)
+
+		/*
+		 * The EFI loader doesn't seem to like a .bss section, so we
+		 * stick it all into .data:
+		 */
+		. = ALIGN(16);
+		_bss = .;
+		*(.sbss)
+		*(.scommon)
+		*(.dynbss)
+		*(.bss)
+		*(.bss.*)
+		*(COMMON)
+		. = ALIGN(16);
+		_bss_end = .;
+		_edata = .;
+	}
+	.rela.dyn : { *(.rela.dyn) }
+	.rela.plt : { *(.rela.plt) }
+	.rela.got : { *(.rela.got) }
+	.rela.data : { *(.rela.data) *(.rela.data*) }
+	_data_size = . - _etext;
+
+	. = ALIGN(4096);
+	.dynsym   : { *(.dynsym) }
+	. = ALIGN(4096);
+	.dynstr   : { *(.dynstr) }
+	. = ALIGN(4096);
+	.note.gnu.build-id : { *(.note.gnu.build-id) }
+	/DISCARD/ : {
+		*(.rel.reloc)
+		*(.eh_frame)
+		*(.note.GNU-stack)
+	}
+	.comment 0 : { *(.comment) }
+}
diff --git a/arch/riscv/lib/reloc_riscv_efi.c b/arch/riscv/lib/reloc_riscv_efi.c
new file mode 100644
index 0000000..8b4b2b1
--- /dev/null
+++ b/arch/riscv/lib/reloc_riscv_efi.c
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* reloc_riscv.c - position independent ELF shared object relocator
+   Copyright (C) 2018 Alexander Graf <agraf@suse.de>
+   Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
+   Copyright (C) 1999 Hewlett-Packard Co.
+	Contributed by David Mosberger <davidm@hpl.hp.com>.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials
+      provided with the distribution.
+    * Neither the name of Hewlett-Packard Co. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+    CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+    INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+    MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+    BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+    OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+    TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+    THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+*/
+
+#include <efi.h>
+
+#include <elf.h>
+
+#if __riscv_xlen == 64
+#define Elf_Dyn		Elf64_Dyn
+#define Elf_Rela	Elf64_Rela
+#define ELF_R_TYPE	ELF64_R_TYPE
+#else
+#define Elf_Dyn		Elf32_Dyn
+#define Elf_Rela	Elf32_Rela
+#define ELF_R_TYPE	ELF32_R_TYPE
+#endif
+
+efi_status_t _relocate(long ldbase, Elf_Dyn *dyn, efi_handle_t image,
+		       struct efi_system_table *systab)
+{
+	long relsz = 0, relent = 0;
+	Elf_Rela *rel = 0;
+	unsigned long *addr;
+	int i;
+
+	for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
+		switch (dyn[i].d_tag) {
+		case DT_RELA:
+			rel = (Elf_Rela *)((ulong)dyn[i].d_un.d_ptr + ldbase);
+			break;
+		case DT_RELASZ:
+			relsz = dyn[i].d_un.d_val;
+			break;
+		case DT_RELAENT:
+			relent = dyn[i].d_un.d_val;
+			break;
+		default:
+			break;
+		}
+	}
+
+	if (!rel && relent == 0)
+		return EFI_SUCCESS;
+
+	if (!rel || relent == 0)
+		return EFI_LOAD_ERROR;
+
+	while (relsz > 0) {
+		/* apply the relocs */
+		switch (ELF_R_TYPE(rel->r_info)) {
+		case R_RISCV_RELATIVE:
+			addr = (ulong *)(ldbase + rel->r_offset);
+			*addr = ldbase + rel->r_addend;
+			break;
+		default:
+			/* Panic */
+			while (1) ;
+		}
+		rel = (Elf_Rela *)((char *)rel + relent);
+		relsz -= relent;
+	}
+	return EFI_SUCCESS;
+}
diff --git a/arch/riscv/lib/setjmp.S b/arch/riscv/lib/setjmp.S
new file mode 100644
index 0000000..8f5a6a2
--- /dev/null
+++ b/arch/riscv/lib/setjmp.S
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) 2018 Alexander Graf <agraf@suse.de>
+ */
+
+#include <config.h>
+#include <linux/linkage.h>
+
+#ifdef CONFIG_CPU_RISCV_64
+#define STORE_IDX(reg, idx)	sd reg, (idx*8)(a0)
+#define LOAD_IDX(reg, idx)	ld reg, (idx*8)(a0)
+#else
+#define STORE_IDX(reg, idx)	sw reg, (idx*4)(a0)
+#define LOAD_IDX(reg, idx)	lw reg, (idx*4)(a0)
+#endif
+
+.pushsection .text.setjmp, "ax"
+ENTRY(setjmp)
+	/* Preserve all callee-saved registers and the SP */
+	STORE_IDX(s0, 0)
+	STORE_IDX(s1, 1)
+	STORE_IDX(s2, 2)
+	STORE_IDX(s3, 3)
+	STORE_IDX(s4, 4)
+	STORE_IDX(s5, 5)
+	STORE_IDX(s6, 6)
+	STORE_IDX(s7, 7)
+	STORE_IDX(s8, 8)
+	STORE_IDX(s9, 9)
+	STORE_IDX(s10, 10)
+	STORE_IDX(s11, 11)
+	STORE_IDX(ra, 12)
+	STORE_IDX(sp, 13)
+	li  a0, 0
+	ret
+ENDPROC(setjmp)
+.popsection
+
+.pushsection .text.longjmp, "ax"
+ENTRY(longjmp)
+	LOAD_IDX(s0, 0)
+	LOAD_IDX(s1, 1)
+	LOAD_IDX(s2, 2)
+	LOAD_IDX(s3, 3)
+	LOAD_IDX(s4, 4)
+	LOAD_IDX(s5, 5)
+	LOAD_IDX(s6, 6)
+	LOAD_IDX(s7, 7)
+	LOAD_IDX(s8, 8)
+	LOAD_IDX(s9, 9)
+	LOAD_IDX(s10, 10)
+	LOAD_IDX(s11, 11)
+	LOAD_IDX(ra, 12)
+	LOAD_IDX(sp, 13)
+
+	/* Move the return value in place, but return 1 if passed 0. */
+	beq a1, zero, longjmp_1
+	mv a0, a1
+	ret
+
+	longjmp_1:
+	li a0, 1
+	ret
+ENDPROC(longjmp)
+.popsection
diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c
index d4ad020..cde0b05 100644
--- a/arch/sandbox/cpu/cpu.c
+++ b/arch/sandbox/cpu/cpu.c
@@ -9,6 +9,7 @@
 #include <linux/libfdt.h>
 #include <os.h>
 #include <asm/io.h>
+#include <asm/setjmp.h>
 #include <asm/state.h>
 #include <dm/root.h>
 
@@ -164,3 +165,15 @@
 
 	return (count - base_count) / 1000;
 }
+
+int setjmp(jmp_buf jmp)
+{
+	return os_setjmp((ulong *)jmp, sizeof(*jmp));
+}
+
+void longjmp(jmp_buf jmp, int ret)
+{
+	os_longjmp((ulong *)jmp, ret);
+	while (1)
+		;
+}
diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c
index d76d021..5839932 100644
--- a/arch/sandbox/cpu/os.c
+++ b/arch/sandbox/cpu/os.c
@@ -7,6 +7,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <getopt.h>
+#include <setjmp.h>
 #include <stdio.h>
 #include <stdint.h>
 #include <stdlib.h>
@@ -628,3 +629,25 @@
 	rt->tm_yday = tm->tm_yday;
 	rt->tm_isdst = tm->tm_isdst;
 }
+
+int os_setjmp(ulong *jmp, int size)
+{
+	jmp_buf dummy;
+
+	/*
+	 * We cannot rely on the struct name that jmp_buf uses, so use a
+	 * local variable here
+	 */
+	if (size < sizeof(dummy)) {
+		printf("setjmp: jmpbuf is too small (%d bytes, need %d)\n",
+		       size, sizeof(jmp_buf));
+		return -ENOSPC;
+	}
+
+	return setjmp((struct __jmp_buf_tag *)jmp);
+}
+
+void os_longjmp(ulong *jmp, int ret)
+{
+	longjmp((struct __jmp_buf_tag *)jmp, ret);
+}
diff --git a/arch/sandbox/cpu/u-boot.lds b/arch/sandbox/cpu/u-boot.lds
index f97abdf..3a6cf55 100644
--- a/arch/sandbox/cpu/u-boot.lds
+++ b/arch/sandbox/cpu/u-boot.lds
@@ -18,6 +18,35 @@
 	__u_boot_sandbox_option_end = .;
 
 	__bss_start = .;
+
+		.__efi_runtime_start : {
+		*(.__efi_runtime_start)
+	}
+
+	.efi_runtime : {
+		*(efi_runtime_text)
+		*(efi_runtime_data)
+	}
+
+	.__efi_runtime_stop : {
+		*(.__efi_runtime_stop)
+	}
+
+	.efi_runtime_rel_start :
+	{
+		*(.__efi_runtime_rel_start)
+	}
+
+	.efi_runtime_rel : {
+		*(.relefi_runtime_text)
+		*(.relefi_runtime_data)
+	}
+
+	.efi_runtime_rel_stop :
+	{
+		*(.__efi_runtime_rel_stop)
+	}
+
 }
 
 INSERT BEFORE .data;
diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts
index 86680a6..0ea2452 100644
--- a/arch/sandbox/dts/sandbox.dts
+++ b/arch/sandbox/dts/sandbox.dts
@@ -242,6 +242,10 @@
 		compatible = "google,sandbox-tpm";
 	};
 
+	tpm2 {
+		compatible = "sandbox,tpm2";
+	};
+
 	triangle {
 		compatible = "demo-shape";
 		colour = "cyan";
diff --git a/arch/sandbox/dts/sandbox64.dts b/arch/sandbox/dts/sandbox64.dts
index 8f707b4..48e420e 100644
--- a/arch/sandbox/dts/sandbox64.dts
+++ b/arch/sandbox/dts/sandbox64.dts
@@ -242,6 +242,10 @@
 		compatible = "google,sandbox-tpm";
 	};
 
+	tpm2 {
+		compatible = "sandbox,tpm2";
+	};
+
 	triangle {
 		compatible = "demo-shape";
 		colour = "cyan";
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 5a0f187..5752bf5 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -27,10 +27,10 @@
 		testfdt3 = "/b-test";
 		testfdt5 = "/some-bus/c-test@5";
 		testfdt8 = "/a-test";
-		fdt_dummy0 = "/translation-test@8000/dev@0,0";
-		fdt_dummy1 = "/translation-test@8000/dev@1,100";
-		fdt_dummy2 = "/translation-test@8000/dev@2,200";
-		fdt_dummy3 = "/translation-test@8000/noxlatebus@3,300/dev@42";
+		fdt-dummy0 = "/translation-test@8000/dev@0,0";
+		fdt-dummy1 = "/translation-test@8000/dev@1,100";
+		fdt-dummy2 = "/translation-test@8000/dev@2,200";
+		fdt-dummy3 = "/translation-test@8000/noxlatebus@3,300/dev@42";
 		usb0 = &usb_0;
 		usb1 = &usb_1;
 		usb2 = &usb_2;
@@ -422,6 +422,10 @@
 		clock-frequency = <1000000>;
 	};
 
+	tpm2 {
+		compatible = "sandbox,tpm2";
+	};
+
 	uart0: serial {
 		compatible = "sandbox,serial";
 		u-boot,dm-pre-reloc;
diff --git a/arch/sandbox/include/asm/setjmp.h b/arch/sandbox/include/asm/setjmp.h
new file mode 100644
index 0000000..1fe37c9
--- /dev/null
+++ b/arch/sandbox/include/asm/setjmp.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) 2018 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#ifndef _SETJMP_H_
+#define _SETJMP_H_
+
+struct jmp_buf_data {
+	/*
+	 * We're not sure how long this should be:
+	 *
+	 *   amd64: 200 bytes
+	 *   arm64: 392 bytes
+	 *   armhf: 392 bytes
+	 *
+	 * So allow space for all of those, plus some extra.
+	 * We don't need to worry about 16-byte alignment, since this does not
+	 * run on Windows.
+	 */
+	ulong data[128];
+};
+
+typedef struct jmp_buf_data jmp_buf[1];
+
+int setjmp(jmp_buf jmp);
+__noreturn void longjmp(jmp_buf jmp, int ret);
+
+#endif /* _SETJMP_H_ */
diff --git a/arch/sandbox/lib/Makefile b/arch/sandbox/lib/Makefile
index 52eef2e..b4ff717 100644
--- a/arch/sandbox/lib/Makefile
+++ b/arch/sandbox/lib/Makefile
@@ -5,7 +5,7 @@
 # (C) Copyright 2002-2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 
-obj-y	+= interrupts.o
+obj-y	+= interrupts.o sections.o
 obj-$(CONFIG_PCI)	+= pci_io.o
 obj-$(CONFIG_CMD_BOOTM) += bootm.o
 obj-$(CONFIG_CMD_BOOTZ) += bootm.o
diff --git a/arch/sandbox/lib/sections.c b/arch/sandbox/lib/sections.c
new file mode 100644
index 0000000..697a816
--- /dev/null
+++ b/arch/sandbox/lib/sections.c
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2013 Albert ARIBAUD <albert.u.boot@aribaud.net>
+ *
+ */
+
+char __efi_runtime_start[0] __attribute__((section(".__efi_runtime_start")));
+char __efi_runtime_stop[0] __attribute__((section(".__efi_runtime_stop")));
+char __efi_runtime_rel_start[0]
+		__attribute__((section(".__efi_runtime_rel_start")));
+char __efi_runtime_rel_stop[0]
+		__attribute__((section(".__efi_runtime_rel_stop")));
diff --git a/arch/x86/config.mk b/arch/x86/config.mk
index 97db03d..5f77f98 100644
--- a/arch/x86/config.mk
+++ b/arch/x86/config.mk
@@ -86,9 +86,9 @@
 PLATFORM_CPPFLAGS += -D__I386__
 endif
 
-ifneq ($(CONFIG_EFI_STUB)$(CONFIG_CMD_BOOTEFI_HELLO_COMPILE),)
+ifdef CONFIG_EFI_STUB
 
-ifneq ($(CONFIG_EFI_STUB_64BIT),)
+ifdef CONFIG_EFI_STUB_64BIT
 EFI_LDS := elf_x86_64_efi.lds
 EFI_CRT0 := crt0_x86_64_efi.o
 EFI_RELOC := reloc_x86_64_efi.o
@@ -98,10 +98,22 @@
 EFI_RELOC := reloc_ia32_efi.o
 endif
 
+else
+
+ifdef CONFIG_X86_64
+EFI_LDS := elf_x86_64_efi.lds
+EFI_CRT0 := crt0_x86_64_efi.o
+EFI_RELOC := reloc_x86_64_efi.o
+else
+EFI_LDS := elf_ia32_efi.lds
+EFI_CRT0 := crt0_ia32_efi.o
+EFI_RELOC := reloc_ia32_efi.o
+endif
+
+endif
+
 ifdef CONFIG_X86_64
 EFI_TARGET := --target=efi-app-x86_64
 else
 EFI_TARGET := --target=efi-app-ia32
 endif
-
-endif
diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h
index 9be4584..2340ef8 100644
--- a/arch/x86/include/asm/u-boot-x86.h
+++ b/arch/x86/include/asm/u-boot-x86.h
@@ -84,7 +84,6 @@
 /* board/... */
 void timer_set_tsc_base(uint64_t new_base);
 uint64_t timer_get_tsc(void);
-void board_quiesce_devices(void);
 
 void quick_ram_check(void);
 
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index 51d451f..5a64f6e 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -68,8 +68,18 @@
 
 endif
 
-ifneq ($(CONFIG_EFI_STUB)$(CONFIG_CMD_BOOTEFI_HELLO_COMPILE),)
+ifdef CONFIG_EFI_STUB
+
 ifeq ($(CONFIG_$(SPL_)X86_64),)
 extra-y += $(EFI_CRT0) $(EFI_RELOC)
 endif
+
+else
+
+ifndef CONFIG_SPL_BUILD
+ifneq ($(CONFIG_CMD_BOOTEFI_SELFTEST)$(CONFIG_CMD_BOOTEFI_HELLO_COMPILE),)
+extra-y += $(EFI_CRT0) $(EFI_RELOC)
+endif
+endif
+
 endif
diff --git a/arch/x86/lib/bootm.c b/arch/x86/lib/bootm.c
index 533ba07..54c22fe 100644
--- a/arch/x86/lib/bootm.c
+++ b/arch/x86/lib/bootm.c
@@ -27,10 +27,6 @@
 
 #define COMMAND_LINE_OFFSET 0x9000
 
-__weak void board_quiesce_devices(void)
-{
-}
-
 void bootm_announce_and_cleanup(void)
 {
 	printf("\nStarting kernel ...\n\n");
diff --git a/board/AndesTech/nx25-ae250/Kconfig b/board/AndesTech/ax25-ae350/Kconfig
similarity index 70%
rename from board/AndesTech/nx25-ae250/Kconfig
rename to board/AndesTech/ax25-ae350/Kconfig
index 2fb3234..bb69ea3 100644
--- a/board/AndesTech/nx25-ae250/Kconfig
+++ b/board/AndesTech/ax25-ae350/Kconfig
@@ -1,19 +1,19 @@
-if TARGET_NX25_AE250
+if TARGET_AX25_AE350
 
 config SYS_CPU
-	default "nx25"
+	default "ax25"
 
 config SYS_BOARD
-	default "nx25-ae250"
+	default "ax25-ae350"
 
 config SYS_VENDOR
 	default "AndesTech"
 
 config SYS_SOC
-	default "ae250"
+	default "ae350"
 
 config SYS_CONFIG_NAME
-	default "nx25-ae250"
+	default "ax25-ae350"
 
 config ENV_SIZE
 	default 0x2000 if ENV_IS_IN_SPI_FLASH
diff --git a/board/AndesTech/ax25-ae350/MAINTAINERS b/board/AndesTech/ax25-ae350/MAINTAINERS
new file mode 100644
index 0000000..508c6ac
--- /dev/null
+++ b/board/AndesTech/ax25-ae350/MAINTAINERS
@@ -0,0 +1,6 @@
+AX25-AE350 BOARD
+M:	Rick Chen <rick@andestech.com>
+S:	Maintained
+F:	board/AndesTech/ax25-ae350/
+F:	include/configs/ax25-ae350.h
+F:	configs/ax25-ae350_defconfig
diff --git a/board/AndesTech/nx25-ae250/Makefile b/board/AndesTech/ax25-ae350/Makefile
similarity index 87%
rename from board/AndesTech/nx25-ae250/Makefile
rename to board/AndesTech/ax25-ae350/Makefile
index e30b2d3..0e4ba8d 100644
--- a/board/AndesTech/nx25-ae250/Makefile
+++ b/board/AndesTech/ax25-ae350/Makefile
@@ -3,4 +3,4 @@
 # Copyright (C) 2017 Andes Technology Corporation.
 # Rick Chen, Andes Technology Corporation <rick@andestech.com>
 
-obj-y	:= nx25-ae250.o
+obj-y	:= ax25-ae350.o
diff --git a/board/AndesTech/nx25-ae250/nx25-ae250.c b/board/AndesTech/ax25-ae350/ax25-ae350.c
similarity index 70%
rename from board/AndesTech/nx25-ae250/nx25-ae250.c
rename to board/AndesTech/ax25-ae350/ax25-ae350.c
index 4bb618b..fd5aaa1 100644
--- a/board/AndesTech/nx25-ae250/nx25-ae250.c
+++ b/board/AndesTech/ax25-ae350/ax25-ae350.c
@@ -10,6 +10,8 @@
 #include <netdev.h>
 #endif
 #include <linux/io.h>
+#include <faraday/ftsmc020.h>
+#include <fdtdec.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -19,7 +21,7 @@
 
 int board_init(void)
 {
-	gd->bd->bi_arch_number = MACH_TYPE_AE250;
+	gd->bd->bi_arch_number = MACH_TYPE_AE350;
 	gd->bd->bi_boot_params = PHYS_SDRAM_0 + 0x400;
 
 	return 0;
@@ -72,3 +74,35 @@
 
 	return (void *)CONFIG_SYS_FDT_BASE;
 }
+
+int smc_init(void)
+{
+	int node = -1;
+	const char *compat = "andestech,atfsmc020";
+	void *blob = (void *)gd->fdt_blob;
+	fdt_addr_t addr;
+	struct ftsmc020_bank *regs;
+
+	node = fdt_node_offset_by_compatible(blob, -1, compat);
+	if (node < 0)
+		return -FDT_ERR_NOTFOUND;
+
+	addr = fdtdec_get_addr(blob, node, "reg");
+
+	if (addr == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	regs = (struct ftsmc020_bank *)addr;
+	regs->cr &= ~FTSMC020_BANK_WPROT;
+
+	return 0;
+}
+
+#ifdef CONFIG_BOARD_EARLY_INIT_F
+int board_early_init_f(void)
+{
+	smc_init();
+
+	return 0;
+}
+#endif
diff --git a/board/AndesTech/nx25-ae250/MAINTAINERS b/board/AndesTech/nx25-ae250/MAINTAINERS
deleted file mode 100644
index 1bff127..0000000
--- a/board/AndesTech/nx25-ae250/MAINTAINERS
+++ /dev/null
@@ -1,6 +0,0 @@
-NX25-AE250 BOARD
-M:	Rick Chen <rick@andestech.com>
-S:	Maintained
-F:	board/AndesTech/nx25-ae250/
-F:	include/configs/nx25-ae250.h
-F:	configs/nx25-ae250_defconfig
diff --git a/board/amazon/kc1/kc1.c b/board/amazon/kc1/kc1.c
index d9ca183..031fd11 100644
--- a/board/amazon/kc1/kc1.c
+++ b/board/amazon/kc1/kc1.c
@@ -161,7 +161,7 @@
 	omap_die_id_get_board_serial(serialnr);
 }
 
-int fb_set_reboot_flag(void)
+int fastboot_set_reboot_flag(void)
 {
 	return omap_reboot_mode_store("b");
 }
diff --git a/board/bitmain/antminer_s9/MAINTAINERS b/board/bitmain/antminer_s9/MAINTAINERS
new file mode 100644
index 0000000..302dd48
--- /dev/null
+++ b/board/bitmain/antminer_s9/MAINTAINERS
@@ -0,0 +1,6 @@
+Bitmain Antminer S9
+M:	Michal Simek <monstr@monstr.eu>
+S:	Maintained
+F:	board/bitmain/antminer_s9
+F:	include/configs/bitmain_antminer_s9.h
+F:	configs/bitmain_antminer_s9_defconfig
diff --git a/board/bitmain/antminer_s9/Makefile b/board/bitmain/antminer_s9/Makefile
new file mode 100644
index 0000000..93a1e77
--- /dev/null
+++ b/board/bitmain/antminer_s9/Makefile
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y	:= board.o
+
+# Remove quotes
+hw-platform-y :=$(shell echo $(CONFIG_DEFAULT_DEVICE_TREE))
+
+obj-$(CONFIG_SPL_BUILD) += $(hw-platform-y)/ps7_init_gpl.o
diff --git a/board/bitmain/antminer_s9/bitmain-antminer-s9/ps7_init_gpl.c b/board/bitmain/antminer_s9/bitmain-antminer-s9/ps7_init_gpl.c
new file mode 100644
index 0000000..aee2029
--- /dev/null
+++ b/board/bitmain/antminer_s9/bitmain-antminer-s9/ps7_init_gpl.c
@@ -0,0 +1,280 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2018 Michal Simek
+ */
+
+#include <asm/arch/ps7_init_gpl.h>
+
+static unsigned long ps7_pll_init_data_3_0[] = {
+	EMIT_MASKWRITE(0xf8000008, 0x0000ffff, 0x0000df0d),
+	EMIT_MASKWRITE(0xf8000110, 0x003ffff0, 0x000fa220),
+	EMIT_MASKWRITE(0xf8000100, 0x0007f000, 0x00028000),
+	EMIT_MASKWRITE(0xf8000100, 0x00000010, 0x00000010),
+	EMIT_MASKWRITE(0xf8000100, 0x00000001, 0x00000001),
+	EMIT_MASKWRITE(0xf8000100, 0x00000001, 0x00000000),
+	EMIT_MASKPOLL(0xf800010c, 0x00000001),
+	EMIT_MASKWRITE(0xf8000100, 0x00000010, 0x00000000),
+	EMIT_MASKWRITE(0xf8000120, 0x1f003f30, 0x1f000200),
+	EMIT_MASKWRITE(0xf8000114, 0x003ffff0, 0x0012c220),
+	EMIT_MASKWRITE(0xf8000104, 0x0007f000, 0x00020000),
+	EMIT_MASKWRITE(0xf8000104, 0x00000010, 0x00000010),
+	EMIT_MASKWRITE(0xf8000104, 0x00000001, 0x000000),
+	EMIT_MASKWRITE(0xf8000104, 0x00000001, 0x00000000),
+	EMIT_MASKPOLL(0xf800010c, 0x00000002),
+	EMIT_MASKWRITE(0xf8000104, 0x00000010, 0x00000000),
+	EMIT_MASKWRITE(0xf8000124, 0xfff00003, 0x0c200003),
+	EMIT_MASKWRITE(0xf8000118, 0x003ffff0, 0x001452c0),
+	EMIT_MASKWRITE(0xf8000108, 0x0007f000, 0x0001e000),
+	EMIT_MASKWRITE(0xf8000108, 0x00000010, 0x00000010),
+	EMIT_MASKWRITE(0xf8000108, 0x00000001, 0x00000001),
+	EMIT_MASKWRITE(0xf8000108, 0x00000001, 0x00000000),
+	EMIT_MASKPOLL(0xf800010c, 0x00000004),
+	EMIT_MASKWRITE(0xf8000108, 0x00000010, 0x00000000),
+	EMIT_MASKWRITE(0xf8000004, 0x0000ffff, 0x0000767b),
+	EMIT_EXIT(),
+};
+
+static unsigned long ps7_clock_init_data_3_0[] = {
+	EMIT_MASKWRITE(0xf8000008, 0x0000ffff, 0x0000df0d),
+	EMIT_MASKWRITE(0xf8000128, 0x03f03f01, 0x00302301),
+	EMIT_MASKWRITE(0xf8000138, 0x00000011, 0x00000001),
+	EMIT_MASKWRITE(0xf8000140, 0x03f03f71, 0x00100801),
+	EMIT_MASKWRITE(0xf8000148, 0x00003f31, 0x00000a01),
+	EMIT_MASKWRITE(0xf8000150, 0x00003f33, 0x00002801),
+	EMIT_MASKWRITE(0xf8000154, 0x00003f33, 0x00001402),
+	EMIT_MASKWRITE(0xf8000168, 0x00003f31, 0x00000501),
+	EMIT_MASKWRITE(0xf8000170, 0x03f03f30, 0x00101400),
+	EMIT_MASKWRITE(0xf8000180, 0x03f03f30, 0x00100a00),
+	EMIT_MASKWRITE(0xf8000190, 0x03f03f30, 0x00101e00),
+	EMIT_MASKWRITE(0xf80001a0, 0x03f03f30, 0x00101400),
+	EMIT_MASKWRITE(0xf80001c4, 0x00000001, 0x00000001),
+	EMIT_MASKWRITE(0xf800012c, 0x01ffcccd, 0x016c044d),
+	EMIT_MASKWRITE(0xf8000004, 0x0000ffff, 0x0000767b),
+	EMIT_EXIT(),
+};
+
+static unsigned long ps7_ddr_init_data_3_0[] = {
+	EMIT_MASKWRITE(0xf8006000, 0x0001ffff, 0x00000080),
+	EMIT_MASKWRITE(0xf8006004, 0x0007ffff, 0x00001081),
+	EMIT_MASKWRITE(0xf8006008, 0x03ffffff, 0x03c0780f),
+	EMIT_MASKWRITE(0xf800600c, 0x03ffffff, 0x02001001),
+	EMIT_MASKWRITE(0xf8006010, 0x03ffffff, 0x00014001),
+	EMIT_MASKWRITE(0xf8006014, 0x001fffff, 0x0004281b),
+	EMIT_MASKWRITE(0xf8006018, 0xf7ffffff, 0x44e458d1),
+	EMIT_MASKWRITE(0xf800601c, 0xffffffff, 0xb2023584),
+	EMIT_MASKWRITE(0xf8006020, 0x7fdffffc, 0x2b08b2d0),
+	EMIT_MASKWRITE(0xf8006024, 0x0fffffc3, 0x00000000),
+	EMIT_MASKWRITE(0xf8006028, 0x00003fff, 0x00002007),
+	EMIT_MASKWRITE(0xf800602c, 0xffffffff, 0x00000000),
+	EMIT_MASKWRITE(0xf8006030, 0xffffffff, 0x00040970),
+	EMIT_MASKWRITE(0xf8006034, 0x13ff3fff, 0x000116d4),
+	EMIT_MASKWRITE(0xf8006038, 0x00000003, 0x00000000),
+	EMIT_MASKWRITE(0xf800603c, 0x000fffff, 0x00000777),
+	EMIT_MASKWRITE(0xf8006040, 0xffffffff, 0xfff00000),
+	EMIT_MASKWRITE(0xf8006044, 0x0fffffff, 0x0f666666),
+	EMIT_MASKWRITE(0xf8006048, 0x0003f03f, 0x0003c008),
+	EMIT_MASKWRITE(0xf8006050, 0xff0f8fff, 0x77010800),
+	EMIT_MASKWRITE(0xf8006058, 0x00010000, 0x00000000),
+	EMIT_MASKWRITE(0xf800605c, 0x0000ffff, 0x00005003),
+	EMIT_MASKWRITE(0xf8006060, 0x000017ff, 0x0000003e),
+	EMIT_MASKWRITE(0xf8006064, 0x00021fe0, 0x00020000),
+	EMIT_MASKWRITE(0xf8006068, 0x03ffffff, 0x00284545),
+	EMIT_MASKWRITE(0xf800606c, 0x0000ffff, 0x00001610),
+	EMIT_MASKWRITE(0xf8006078, 0x03ffffff, 0x00466111),
+	EMIT_MASKWRITE(0xf800607c, 0x000fffff, 0x00032222),
+	EMIT_MASKWRITE(0xf80060a4, 0xffffffff, 0x10200802),
+	EMIT_MASKWRITE(0xf80060a8, 0x0fffffff, 0x0690cb73),
+	EMIT_MASKWRITE(0xf80060ac, 0x000001ff, 0x000001fe),
+	EMIT_MASKWRITE(0xf80060b0, 0x1fffffff, 0x1cffffff),
+	EMIT_MASKWRITE(0xf80060b4, 0x00000200, 0x00000200),
+	EMIT_MASKWRITE(0xf80060b8, 0x01ffffff, 0x0020006a),
+	EMIT_MASKWRITE(0xf80060c4, 0x00000003, 0x00000003),
+	EMIT_MASKWRITE(0xf80060c4, 0x00000003, 0x00000000),
+	EMIT_MASKWRITE(0xf80060c8, 0x000000ff, 0x00000000),
+	EMIT_MASKWRITE(0xf80060dc, 0x00000001, 0x00000000),
+	EMIT_MASKWRITE(0xf80060f0, 0x0000ffff, 0x00000000),
+	EMIT_MASKWRITE(0xf80060f4, 0x0000000f, 0x00000008),
+	EMIT_MASKWRITE(0xf8006114, 0x000000ff, 0x00000000),
+	EMIT_MASKWRITE(0xf8006118, 0x7fffffcf, 0x40000001),
+	EMIT_MASKWRITE(0xf800611c, 0x7fffffcf, 0x40000001),
+	EMIT_MASKWRITE(0xf8006120, 0x7fffffcf, 0x40000001),
+	EMIT_MASKWRITE(0xf8006124, 0x7fffffcf, 0x40000001),
+	EMIT_MASKWRITE(0xf800612c, 0x000fffff, 0x0002c000),
+	EMIT_MASKWRITE(0xf8006130, 0x000fffff, 0x0002c400),
+	EMIT_MASKWRITE(0xf8006134, 0x000fffff, 0x0002f003),
+	EMIT_MASKWRITE(0xf8006138, 0x000fffff, 0x0002ec03),
+	EMIT_MASKWRITE(0xf8006140, 0x000fffff, 0x00000035),
+	EMIT_MASKWRITE(0xf8006144, 0x000fffff, 0x00000035),
+	EMIT_MASKWRITE(0xf8006148, 0x000fffff, 0x00000035),
+	EMIT_MASKWRITE(0xf800614c, 0x000fffff, 0x00000035),
+	EMIT_MASKWRITE(0xf8006154, 0x000fffff, 0x00000077),
+	EMIT_MASKWRITE(0xf8006158, 0x000fffff, 0x00000077),
+	EMIT_MASKWRITE(0xf800615c, 0x000fffff, 0x00000083),
+	EMIT_MASKWRITE(0xf8006160, 0x000fffff, 0x00000083),
+	EMIT_MASKWRITE(0xf8006168, 0x001fffff, 0x00000105),
+	EMIT_MASKWRITE(0xf800616c, 0x001fffff, 0x00000106),
+	EMIT_MASKWRITE(0xf8006170, 0x001fffff, 0x00000111),
+	EMIT_MASKWRITE(0xf8006174, 0x001fffff, 0x00000110),
+	EMIT_MASKWRITE(0xf800617c, 0x000fffff, 0x000000b7),
+	EMIT_MASKWRITE(0xf8006180, 0x000fffff, 0x000000b7),
+	EMIT_MASKWRITE(0xf8006184, 0x000fffff, 0x000000c3),
+	EMIT_MASKWRITE(0xf8006188, 0x000fffff, 0x000000c3),
+	EMIT_MASKWRITE(0xf8006190, 0x6ffffefe, 0x00040080),
+	EMIT_MASKWRITE(0xf8006194, 0x000fffff, 0x0001fd01),
+	EMIT_MASKWRITE(0xf8006204, 0xffffffff, 0x00000000),
+	EMIT_MASKWRITE(0xf8006208, 0x000703ff, 0x000003ff),
+	EMIT_MASKWRITE(0xf800620c, 0x000703ff, 0x000003ff),
+	EMIT_MASKWRITE(0xf8006210, 0x000703ff, 0x000003ff),
+	EMIT_MASKWRITE(0xf8006214, 0x000703ff, 0x000003ff),
+	EMIT_MASKWRITE(0xf8006218, 0x000f03ff, 0x000003ff),
+	EMIT_MASKWRITE(0xf800621c, 0x000f03ff, 0x000003ff),
+	EMIT_MASKWRITE(0xf8006220, 0x000f03ff, 0x000003ff),
+	EMIT_MASKWRITE(0xf8006224, 0x000f03ff, 0x000003ff),
+	EMIT_MASKWRITE(0xf80062a8, 0x00000ff5, 0x00000000),
+	EMIT_MASKWRITE(0xf80062ac, 0xffffffff, 0x00000000),
+	EMIT_MASKWRITE(0xf80062b0, 0x003fffff, 0x00005125),
+	EMIT_MASKWRITE(0xf80062b4, 0x0003ffff, 0x000012a8),
+	EMIT_MASKPOLL(0xf8000b74, 0x00002000),
+	EMIT_MASKWRITE(0xf8006000, 0x0001ffff, 0x00000081),
+	EMIT_MASKPOLL(0xf8006054, 0x00000007),
+	EMIT_EXIT(),
+};
+
+static unsigned long ps7_mio_init_data_3_0[] = {
+	EMIT_MASKWRITE(0xf8000008, 0x0000ffff, 0x0000df0d),
+	EMIT_MASKWRITE(0xf8000b40, 0x00000fff, 0x00000600),
+	EMIT_MASKWRITE(0xf8000b44, 0x00000fff, 0x00000600),
+	EMIT_MASKWRITE(0xf8000b48, 0x00000fff, 0x00000672),
+	EMIT_MASKWRITE(0xf8000b4c, 0x00000fff, 0x00000672),
+	EMIT_MASKWRITE(0xf8000b50, 0x00000fff, 0x00000674),
+	EMIT_MASKWRITE(0xf8000b54, 0x00000fff, 0x00000674),
+	EMIT_MASKWRITE(0xf8000b58, 0x00000fff, 0x00000600),
+	EMIT_MASKWRITE(0xf8000b5c, 0xffffffff, 0x0018c068),
+	EMIT_MASKWRITE(0xf8000b60, 0xffffffff, 0x00f98068),
+	EMIT_MASKWRITE(0xf8000b64, 0xffffffff, 0x00f98068),
+	EMIT_MASKWRITE(0xf8000b68, 0xffffffff, 0x00f98068),
+	EMIT_MASKWRITE(0xf8000b6c, 0x00007fff, 0x00000205),
+	EMIT_MASKWRITE(0xf8000b70, 0x00000001, 0x00000001),
+	EMIT_MASKWRITE(0xf8000b70, 0x00000021, 0x00000020),
+	EMIT_MASKWRITE(0xf8000b70, 0x07feffff, 0x00000823),
+	EMIT_MASKWRITE(0xf8000700, 0x00003fff, 0x00000610),
+	EMIT_MASKWRITE(0xf8000704, 0x00003fff, 0x00000600),
+	EMIT_MASKWRITE(0xf8000708, 0x00003fff, 0x00000610),
+	EMIT_MASKWRITE(0xf800070c, 0x00003fff, 0x00000610),
+	EMIT_MASKWRITE(0xf8000710, 0x00003fff, 0x00000610),
+	EMIT_MASKWRITE(0xf8000714, 0x00003fff, 0x00000610),
+	EMIT_MASKWRITE(0xf8000718, 0x00003fff, 0x00000610),
+	EMIT_MASKWRITE(0xf800071c, 0x00003fff, 0x00000610),
+	EMIT_MASKWRITE(0xf8000720, 0x00003fff, 0x00000610),
+	EMIT_MASKWRITE(0xf8000724, 0x00003fff, 0x00000610),
+	EMIT_MASKWRITE(0xf8000728, 0x00003fff, 0x00000610),
+	EMIT_MASKWRITE(0xf800072c, 0x00003fff, 0x00000610),
+	EMIT_MASKWRITE(0xf8000730, 0x00003fff, 0x00000610),
+	EMIT_MASKWRITE(0xf8000734, 0x00003fff, 0x00000610),
+	EMIT_MASKWRITE(0xf8000738, 0x00003fff, 0x00000611),
+	EMIT_MASKWRITE(0xf800073c, 0x00003fff, 0x00000600),
+	EMIT_MASKWRITE(0xf8000740, 0x00003fff, 0x00000202),
+	EMIT_MASKWRITE(0xf8000744, 0x00003fff, 0x00000202),
+	EMIT_MASKWRITE(0xf8000748, 0x00003fff, 0x00000202),
+	EMIT_MASKWRITE(0xf800074c, 0x00003fff, 0x00000202),
+	EMIT_MASKWRITE(0xf8000750, 0x00003fff, 0x00000202),
+	EMIT_MASKWRITE(0xf8000754, 0x00003fff, 0x00000202),
+	EMIT_MASKWRITE(0xf8000758, 0x00003fff, 0x00000203),
+	EMIT_MASKWRITE(0xf800075c, 0x00003fff, 0x00000203),
+	EMIT_MASKWRITE(0xf8000760, 0x00003fff, 0x00000203),
+	EMIT_MASKWRITE(0xf8000764, 0x00003fff, 0x00000203),
+	EMIT_MASKWRITE(0xf8000768, 0x00003fff, 0x00000203),
+	EMIT_MASKWRITE(0xf800076c, 0x00003fff, 0x00000203),
+	EMIT_MASKWRITE(0xf8000770, 0x00003fff, 0x00000200),
+	EMIT_MASKWRITE(0xf8000774, 0x00003fff, 0x00000200),
+	EMIT_MASKWRITE(0xf8000778, 0x00003fff, 0x00000200),
+	EMIT_MASKWRITE(0xf800077c, 0x00003fff, 0x00000200),
+	EMIT_MASKWRITE(0xf8000780, 0x00003fff, 0x00000200),
+	EMIT_MASKWRITE(0xf8000784, 0x00003fff, 0x00000200),
+	EMIT_MASKWRITE(0xf8000788, 0x00003fff, 0x00000200),
+	EMIT_MASKWRITE(0xf800078c, 0x00003fff, 0x00000200),
+	EMIT_MASKWRITE(0xf8000790, 0x00003fff, 0x00000200),
+	EMIT_MASKWRITE(0xf8000794, 0x00003fff, 0x00000200),
+	EMIT_MASKWRITE(0xf8000798, 0x00003fff, 0x00000200),
+	EMIT_MASKWRITE(0xf800079c, 0x00003fff, 0x00000200),
+	EMIT_MASKWRITE(0xf80007a0, 0x00003fff, 0x00000280),
+	EMIT_MASKWRITE(0xf80007a4, 0x00003fff, 0x00000280),
+	EMIT_MASKWRITE(0xf80007a8, 0x00003fff, 0x00000280),
+	EMIT_MASKWRITE(0xf80007ac, 0x00003fff, 0x00000280),
+	EMIT_MASKWRITE(0xf80007b0, 0x00003fff, 0x00000280),
+	EMIT_MASKWRITE(0xf80007b4, 0x00003fff, 0x00000280),
+	EMIT_MASKWRITE(0xf80007b8, 0x00003f01, 0x00000201),
+	EMIT_MASKWRITE(0xf80007bc, 0x00003fff, 0x00000200),
+	EMIT_MASKWRITE(0xf80007c0, 0x00003fff, 0x000002e0),
+	EMIT_MASKWRITE(0xf80007c4, 0x00003fff, 0x000002e1),
+	EMIT_MASKWRITE(0xf80007c8, 0x00003f01, 0x00000201),
+	EMIT_MASKWRITE(0xf80007cc, 0x00003fff, 0x00000200),
+	EMIT_MASKWRITE(0xf80007d0, 0x00003fff, 0x00000280),
+	EMIT_MASKWRITE(0xf80007d4, 0x00003fff, 0x00000280),
+	EMIT_MASKWRITE(0xf8000830, 0x003f003f, 0x002e0032),
+	EMIT_MASKWRITE(0xf8000004, 0x0000ffff, 0x0000767b),
+	EMIT_EXIT(),
+};
+
+static unsigned long ps7_peripherals_init_data_3_0[] = {
+	EMIT_MASKWRITE(0xf8000008, 0x0000ffff, 0x0000df0d),
+	EMIT_MASKWRITE(0xf8000b48, 0x00000180, 0x00000180),
+	EMIT_MASKWRITE(0xf8000b4c, 0x00000180, 0x00000180),
+	EMIT_MASKWRITE(0xf8000b50, 0x00000180, 0x00000180),
+	EMIT_MASKWRITE(0xf8000b54, 0x00000180, 0x00000180),
+	EMIT_MASKWRITE(0xf8000004, 0x0000ffff, 0x0000767b),
+	EMIT_MASKWRITE(0xe0001034, 0x000000ff, 0x00000006),
+	EMIT_MASKWRITE(0xe0001018, 0x0000ffff, 0x0000003e),
+	EMIT_MASKWRITE(0xe0001000, 0x000001ff, 0x00000017),
+	EMIT_MASKWRITE(0xe0001004, 0x000003ff, 0x00000020),
+	EMIT_MASKWRITE(0xe000d000, 0x00080000, 0x00080000),
+	EMIT_MASKWRITE(0xf8007000, 0x20000000, 0x00000000),
+	EMIT_MASKWRITE(0xe000e014, 0x00ffffff, 0x00449144),
+	EMIT_MASKWRITE(0xe000e018, 0x00000003, 0x00000000),
+	EMIT_MASKWRITE(0xe000e010, 0x03e00000, 0x02400000),
+	EMIT_MASKDELAY(0xf8f00200, 0x00000001),
+	EMIT_MASKDELAY(0xf8f00200, 0x00000001),
+	EMIT_MASKDELAY(0xf8f00200, 0x00000001),
+	EMIT_MASKDELAY(0xf8f00200, 0x00000001),
+	EMIT_MASKDELAY(0xf8f00200, 0x00000001),
+	EMIT_MASKDELAY(0xf8f00200, 0x00000001),
+	EMIT_EXIT(),
+};
+
+static unsigned long ps7_post_config_3_0[] = {
+	EMIT_MASKWRITE(0xf8000008, 0x0000ffff, 0x0000df0d),
+	EMIT_MASKWRITE(0xf8000900, 0x0000000f, 0x0000000f),
+	EMIT_MASKWRITE(0xf8000240, 0xffffffff, 0x00000000),
+	EMIT_MASKWRITE(0xf8008000, 0x00000001, 0x00000001),
+	EMIT_MASKWRITE(0xf8008014, 0x00000001, 0x00000001),
+	EMIT_MASKWRITE(0xf8000004, 0x0000ffff, 0x0000767b),
+	EMIT_EXIT(),
+};
+
+int ps7_init(void)
+{
+	int ret;
+
+	ret = ps7_config(ps7_mio_init_data_3_0);
+	if (ret != PS7_INIT_SUCCESS)
+		return ret;
+	ret = ps7_config(ps7_pll_init_data_3_0);
+	if (ret != PS7_INIT_SUCCESS)
+		return ret;
+	ret = ps7_config(ps7_clock_init_data_3_0);
+	if (ret != PS7_INIT_SUCCESS)
+		return ret;
+	ret = ps7_config(ps7_ddr_init_data_3_0);
+	if (ret != PS7_INIT_SUCCESS)
+		return ret;
+	ret = ps7_config(ps7_peripherals_init_data_3_0);
+	if (ret != PS7_INIT_SUCCESS)
+		return ret;
+
+	return PS7_INIT_SUCCESS;
+}
+
+int ps7_post_config(void)
+{
+	return ps7_config(ps7_post_config_3_0);
+}
diff --git a/board/bitmain/antminer_s9/board.c b/board/bitmain/antminer_s9/board.c
new file mode 100644
index 0000000..bb7cef3
--- /dev/null
+++ b/board/bitmain/antminer_s9/board.c
@@ -0,0 +1,2 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "../../xilinx/zynq/board.c"
diff --git a/board/eets/pdu001/Kconfig b/board/eets/pdu001/Kconfig
index f28ba6e..e64ae28 100644
--- a/board/eets/pdu001/Kconfig
+++ b/board/eets/pdu001/Kconfig
@@ -19,7 +19,7 @@
 
 choice
 	prompt "State of Run LED"
-	default PDU001_RUN_LED_RED
+	default RUN_LED_RED
 	help
 	  The PDU001 has a bi-color (red/green) LED labeled 'Run' which
 	  can be used to indicate the operating state of the board. By
diff --git a/board/emulation/qemu-arm/qemu-arm.c b/board/emulation/qemu-arm/qemu-arm.c
index 6ec4200..085cbbe 100644
--- a/board/emulation/qemu-arm/qemu-arm.c
+++ b/board/emulation/qemu-arm/qemu-arm.c
@@ -28,7 +28,7 @@
 		/* RAM */
 		.virt = 0x40000000UL,
 		.phys = 0x40000000UL,
-		.size = 0xc0000000UL,
+		.size = 255UL * SZ_1G,
 		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
 			 PTE_BLOCK_INNER_SHARE
 	}, {
diff --git a/board/gdsys/a38x/controlcenterdc.c b/board/gdsys/a38x/controlcenterdc.c
index 320bc10..824a08f 100644
--- a/board/gdsys/a38x/controlcenterdc.c
+++ b/board/gdsys/a38x/controlcenterdc.c
@@ -7,7 +7,7 @@
 #include <common.h>
 #include <dm.h>
 #include <miiphy.h>
-#include <tpm.h>
+#include <tpm-v1.h>
 #include <asm/io.h>
 #include <asm/arch/cpu.h>
 #include <asm-generic/gpio.h>
diff --git a/board/gdsys/a38x/hre.c b/board/gdsys/a38x/hre.c
index 961316c..34c4df7 100644
--- a/board/gdsys/a38x/hre.c
+++ b/board/gdsys/a38x/hre.c
@@ -9,7 +9,7 @@
 #include <fs.h>
 #include <i2c.h>
 #include <mmc.h>
-#include <tpm.h>
+#include <tpm-v1.h>
 #include <u-boot/sha1.h>
 #include <asm/byteorder.h>
 #include <asm/unaligned.h>
diff --git a/board/gdsys/a38x/keyprogram.c b/board/gdsys/a38x/keyprogram.c
index f6a2747..1fb5306 100644
--- a/board/gdsys/a38x/keyprogram.c
+++ b/board/gdsys/a38x/keyprogram.c
@@ -5,7 +5,7 @@
  */
 
 #include <common.h>
-#include <tpm.h>
+#include <tpm-v1.h>
 #include <malloc.h>
 #include <linux/ctype.h>
 #include <asm/unaligned.h>
diff --git a/board/gdsys/p1022/controlcenterd-id.c b/board/gdsys/p1022/controlcenterd-id.c
index 87edf92..7e082df 100644
--- a/board/gdsys/p1022/controlcenterd-id.c
+++ b/board/gdsys/p1022/controlcenterd-id.c
@@ -15,7 +15,7 @@
 #include <fs.h>
 #include <i2c.h>
 #include <mmc.h>
-#include <tpm.h>
+#include <tpm-v1.h>
 #include <u-boot/sha1.h>
 #include <asm/byteorder.h>
 #include <asm/unaligned.h>
diff --git a/board/lg/sniper/sniper.c b/board/lg/sniper/sniper.c
index 34a7a11..a7de4c2 100644
--- a/board/lg/sniper/sniper.c
+++ b/board/lg/sniper/sniper.c
@@ -173,7 +173,7 @@
 	omap_reboot_mode_store(reboot_mode);
 }
 
-int fb_set_reboot_flag(void)
+int fastboot_set_reboot_flag(void)
 {
 	return omap_reboot_mode_store("b");
 }
diff --git a/board/renesas/ebisu/Kconfig b/board/renesas/ebisu/Kconfig
new file mode 100644
index 0000000..f500a94
--- /dev/null
+++ b/board/renesas/ebisu/Kconfig
@@ -0,0 +1,15 @@
+if TARGET_EBISU
+
+config SYS_SOC
+	default "rmobile"
+
+config SYS_BOARD
+	default "ebisu"
+
+config SYS_VENDOR
+	default "renesas"
+
+config SYS_CONFIG_NAME
+	default "ebisu"
+
+endif
diff --git a/board/renesas/ebisu/MAINTAINERS b/board/renesas/ebisu/MAINTAINERS
new file mode 100644
index 0000000..facad52
--- /dev/null
+++ b/board/renesas/ebisu/MAINTAINERS
@@ -0,0 +1,6 @@
+EBISU BOARD
+M:	Marek Vasut <marek.vasut+renesas@gmail.com>
+S:	Maintained
+F:	board/renesas/ebisu/
+F:	include/configs/ebisu.h
+F:	configs/r8a77990_ebisu_defconfig
diff --git a/board/renesas/ebisu/Makefile b/board/renesas/ebisu/Makefile
new file mode 100644
index 0000000..2741035
--- /dev/null
+++ b/board/renesas/ebisu/Makefile
@@ -0,0 +1,9 @@
+#
+# board/renesas/ebisu/Makefile
+#
+# Copyright (C) 2018 Renesas Electronics Corporation
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y	:= ebisu.o
diff --git a/board/renesas/ebisu/ebisu.c b/board/renesas/ebisu/ebisu.c
new file mode 100644
index 0000000..fdff2a8
--- /dev/null
+++ b/board/renesas/ebisu/ebisu.c
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * board/renesas/ebisu/ebisu.c
+ *     This file is Ebisu board support.
+ *
+ * Copyright (C) 2018 Marek Vasut <marek.vasut+renesas@gmail.com>
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <netdev.h>
+#include <dm.h>
+#include <dm/platform_data/serial_sh.h>
+#include <asm/processor.h>
+#include <asm/mach-types.h>
+#include <asm/io.h>
+#include <linux/errno.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/gpio.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/rmobile.h>
+#include <asm/arch/rcar-mstp.h>
+#include <asm/arch/sh_sdhi.h>
+#include <i2c.h>
+#include <mmc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void s_init(void)
+{
+}
+
+#define TMU0_MSTP125		BIT(25)	/* secure */
+
+int board_early_init_f(void)
+{
+	/* TMU0 */
+	mstp_clrbits_le32(MSTPSR1, SMSTPCR1, TMU0_MSTP125);
+
+	return 0;
+}
+
+int board_init(void)
+{
+	/* adress of boot parameters */
+	gd->bd->bi_boot_params = CONFIG_SYS_TEXT_BASE + 0x50000;
+
+	return 0;
+}
+
+int dram_init(void)
+{
+	if (fdtdec_setup_memory_size() != 0)
+		return -EINVAL;
+
+	return 0;
+}
+
+int dram_init_banksize(void)
+{
+	fdtdec_setup_memory_banksize();
+
+	return 0;
+}
+
+#define RST_BASE	0xE6160000
+#define RST_CA57RESCNT	(RST_BASE + 0x40)
+#define RST_CA53RESCNT	(RST_BASE + 0x44)
+#define RST_RSTOUTCR	(RST_BASE + 0x58)
+#define RST_CA57_CODE	0xA5A5000F
+#define RST_CA53_CODE	0x5A5A000F
+
+void reset_cpu(ulong addr)
+{
+	unsigned long midr, cputype;
+
+	asm volatile("mrs %0, midr_el1" : "=r" (midr));
+	cputype = (midr >> 4) & 0xfff;
+
+	if (cputype == 0xd03)
+		writel(RST_CA53_CODE, RST_CA53RESCNT);
+	else if (cputype == 0xd07)
+		writel(RST_CA57_CODE, RST_CA57RESCNT);
+	else
+		hang();
+}
diff --git a/board/st/stm32mp1/board.c b/board/st/stm32mp1/board.c
index 956768f..5f31ea9 100644
--- a/board/st/stm32mp1/board.c
+++ b/board/st/stm32mp1/board.c
@@ -10,6 +10,33 @@
 #include <power/pmic.h>
 #include <power/stpmu1.h>
 
+#ifdef CONFIG_DEBUG_UART_BOARD_INIT
+void board_debug_uart_init(void)
+{
+#if (CONFIG_DEBUG_UART_BASE == STM32_UART4_BASE)
+
+#define RCC_MP_APB1ENSETR (STM32_RCC_BASE + 0x0A00)
+#define RCC_MP_AHB4ENSETR (STM32_RCC_BASE + 0x0A28)
+
+	/* UART4 clock enable */
+	setbits_le32(RCC_MP_APB1ENSETR, BIT(16));
+
+#define GPIOG_BASE 0x50008000
+	/* GPIOG clock enable */
+	writel(BIT(6), RCC_MP_AHB4ENSETR);
+	/* GPIO configuration for EVAL board
+	 * => Uart4 TX = G11
+	 */
+	writel(0xffbfffff, GPIOG_BASE + 0x00);
+	writel(0x00006000, GPIOG_BASE + 0x24);
+#else
+
+#error("CONFIG_DEBUG_UART_BASE: not supported value")
+
+#endif
+}
+#endif
+
 #ifdef CONFIG_PMIC_STPMU1
 int board_ddr_power_init(void)
 {
diff --git a/board/synopsys/emdk/Kconfig b/board/synopsys/emdk/Kconfig
new file mode 100644
index 0000000..a9b834d
--- /dev/null
+++ b/board/synopsys/emdk/Kconfig
@@ -0,0 +1,12 @@
+if TARGET_EMDK
+
+config SYS_BOARD
+	default "emdk"
+
+config SYS_VENDOR
+	default "synopsys"
+
+config SYS_CONFIG_NAME
+	default "emdk"
+
+endif
diff --git a/board/synopsys/emdk/MAINTAINERS b/board/synopsys/emdk/MAINTAINERS
new file mode 100644
index 0000000..605e338
--- /dev/null
+++ b/board/synopsys/emdk/MAINTAINERS
@@ -0,0 +1,5 @@
+EM DEVELOPMENT KIT BOARD
+M:	Alexey Brodkin <abrodkin@synopsys.com>
+S:	Maintained
+F:	board/synopsys/emdk/
+F:	configs/emdk_defconfig
diff --git a/board/synopsys/emdk/Makefile b/board/synopsys/emdk/Makefile
new file mode 100644
index 0000000..4926c4e
--- /dev/null
+++ b/board/synopsys/emdk/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (C) 2018 Synopsys, Inc. All rights reserved.
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y	+= emdk.o
diff --git a/board/synopsys/emdk/emdk.c b/board/synopsys/emdk/emdk.c
new file mode 100644
index 0000000..bbb946a
--- /dev/null
+++ b/board/synopsys/emdk/emdk.c
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Synopsys, Inc. All rights reserved.
+ */
+
+#include <common.h>
+#include <dwmmc.h>
+#include <malloc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define ARC_PERIPHERAL_BASE	0xF0000000
+#define SDIO_BASE		(ARC_PERIPHERAL_BASE + 0x10000)
+
+int board_mmc_init(bd_t *bis)
+{
+	struct dwmci_host *host = NULL;
+
+	host = malloc(sizeof(struct dwmci_host));
+	if (!host) {
+		printf("dwmci_host malloc fail!\n");
+		return 1;
+	}
+
+	memset(host, 0, sizeof(struct dwmci_host));
+	host->name = "Synopsys Mobile storage";
+	host->ioaddr = (void *)SDIO_BASE;
+	host->buswidth = 4;
+	host->dev_index = 0;
+	host->bus_hz = 50000000;
+
+	add_dwmci(host, host->bus_hz / 2, 400000);
+
+	return 0;
+}
+
+#define CREG_BASE		0xF0001000
+#define CREG_BOOT_OFFSET	0
+#define CREG_BOOT_WP_OFFSET	8
+
+#define CGU_BASE		0xF0000000
+#define CGU_IP_SW_RESET		0x0FF0
+
+void reset_cpu(ulong addr)
+{
+	writel(1, (u32 *)(CGU_BASE + CGU_IP_SW_RESET));
+	while (1)
+		; /* loop forever till reset */
+}
+
+static int do_emdk_rom(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+	u32 creg_boot = readl((u32 *)(CREG_BASE + CREG_BOOT_OFFSET));
+
+	if (!strcmp(argv[1], "unlock"))
+		creg_boot &= ~BIT(CREG_BOOT_WP_OFFSET);
+	else if (!strcmp(argv[1], "lock"))
+		creg_boot |= BIT(CREG_BOOT_WP_OFFSET);
+	else
+		return CMD_RET_USAGE;
+
+	writel(creg_boot, (u32 *)(CREG_BASE + CREG_BOOT_OFFSET));
+
+	return CMD_RET_SUCCESS;
+}
+
+cmd_tbl_t cmd_emdk[] = {
+	U_BOOT_CMD_MKENT(rom, 2, 0, do_emdk_rom, "", ""),
+};
+
+static int do_emdk(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+	cmd_tbl_t *c;
+
+	c = find_cmd_tbl(argv[1], cmd_emdk, ARRAY_SIZE(cmd_emdk));
+
+	/* Strip off leading 'emdk' command */
+	argc--;
+	argv++;
+
+	if (c == NULL || argc > c->maxargs)
+		return CMD_RET_USAGE;
+
+	return c->cmd(cmdtp, flag, argc, argv);
+}
+
+U_BOOT_CMD(
+	emdk, CONFIG_SYS_MAXARGS, 0, do_emdk,
+	"Synopsys EMDK specific commands",
+	"rom unlock - Unlock non-volatile memory for writing\n"
+	"emdk rom lock - Lock non-volatile memory to prevent writing\n"
+);
diff --git a/board/ti/am57xx/board.c b/board/ti/am57xx/board.c
index fd9d207..177a324 100644
--- a/board/ti/am57xx/board.c
+++ b/board/ti/am57xx/board.c
@@ -1178,5 +1178,15 @@
 	secure_tee_install((u32)tee_image);
 }
 
+#if CONFIG_IS_ENABLED(FASTBOOT) && !CONFIG_IS_ENABLED(ENV_IS_NOWHERE)
+int fastboot_set_reboot_flag(void)
+{
+	printf("Setting reboot to fastboot flag ...\n");
+	env_set("dofastboot", "1");
+	env_save();
+	return 0;
+}
+#endif
+
 U_BOOT_FIT_LOADABLE_HANDLER(IH_TYPE_TEE, board_tee_image_process);
 #endif
diff --git a/board/ti/common/Kconfig b/board/ti/common/Kconfig
index c21eb8c..b1956b8 100644
--- a/board/ti/common/Kconfig
+++ b/board/ti/common/Kconfig
@@ -25,7 +25,6 @@
 	imply CMD_EXT2
 	imply CMD_EXT4
 	imply CMD_EXT4_WRITE
-	imply CMD_FASTBOOT if FASTBOOT
 	imply CMD_FAT
 	imply FAT_WRITE if CMD_FAT
 	imply CMD_FS_GENERIC
diff --git a/board/ti/dra7xx/evm.c b/board/ti/dra7xx/evm.c
index 6918f4d..bbe5445 100644
--- a/board/ti/dra7xx/evm.c
+++ b/board/ti/dra7xx/evm.c
@@ -1188,5 +1188,15 @@
 	secure_tee_install((u32)tee_image);
 }
 
+#if CONFIG_IS_ENABLED(FASTBOOT) && !CONFIG_IS_ENABLED(ENV_IS_NOWHERE)
+int fastboot_set_reboot_flag(void)
+{
+	printf("Setting reboot to fastboot flag ...\n");
+	env_set("dofastboot", "1");
+	env_save();
+	return 0;
+}
+#endif
+
 U_BOOT_FIT_LOADABLE_HANDLER(IH_TYPE_TEE, board_tee_image_process);
 #endif
diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c
index e41fec3..080fb59 100644
--- a/board/xilinx/zynqmp/zynqmp.c
+++ b/board/xilinx/zynqmp/zynqmp.c
@@ -15,6 +15,7 @@
 #include <asm/arch/sys_proto.h>
 #include <asm/arch/psu_init_gpl.h>
 #include <asm/io.h>
+#include <dm/device.h>
 #include <dm/uclass.h>
 #include <usb.h>
 #include <dwc3-uboot.h>
@@ -449,10 +450,54 @@
 {
 }
 
+static const struct {
+	u32 bit;
+	const char *name;
+} reset_reasons[] = {
+	{ RESET_REASON_DEBUG_SYS, "DEBUG" },
+	{ RESET_REASON_SOFT, "SOFT" },
+	{ RESET_REASON_SRST, "SRST" },
+	{ RESET_REASON_PSONLY, "PS-ONLY" },
+	{ RESET_REASON_PMU, "PMU" },
+	{ RESET_REASON_INTERNAL, "INTERNAL" },
+	{ RESET_REASON_EXTERNAL, "EXTERNAL" },
+	{}
+};
+
+static u32 reset_reason(void)
+{
+	u32 ret;
+	int i;
+	const char *reason = NULL;
+
+	ret = readl(&crlapb_base->reset_reason);
+
+	puts("Reset reason:\t");
+
+	for (i = 0; i < ARRAY_SIZE(reset_reasons); i++) {
+		if (ret & reset_reasons[i].bit) {
+			reason = reset_reasons[i].name;
+			printf("%s ", reset_reasons[i].name);
+			break;
+		}
+	}
+
+	puts("\n");
+
+	env_set("reset_reason", reason);
+
+	writel(~0, &crlapb_base->reset_reason);
+
+	return ret;
+}
+
 int board_late_init(void)
 {
 	u32 reg = 0;
 	u8 bootmode;
+	struct udevice *dev;
+	int bootseq = -1;
+	int bootseq_len = 0;
 	int env_targets_len = 0;
 	const char *mode;
 	char *new_targets;
@@ -498,7 +543,15 @@
 		break;
 	case SD_MODE:
 		puts("SD_MODE\n");
-		mode = "mmc0";
+		if (uclass_get_device_by_name(UCLASS_MMC,
+					      "sdhci@ff160000", &dev)) {
+			puts("Boot from SD0 but without SD0 enabled!\n");
+			return -1;
+		}
+		debug("mmc0 device found at %p, seq %d\n", dev, dev->seq);
+
+		mode = "mmc";
+		bootseq = dev->seq;
 		env_set("modeboot", "sdboot");
 		break;
 	case SD1_LSHFT_MODE:
@@ -506,12 +559,15 @@
 		/* fall through */
 	case SD_MODE1:
 		puts("SD_MODE1\n");
-#if defined(CONFIG_ZYNQ_SDHCI0) && defined(CONFIG_ZYNQ_SDHCI1)
-		mode = "mmc1";
-		env_set("sdbootdev", "1");
-#else
-		mode = "mmc0";
-#endif
+		if (uclass_get_device_by_name(UCLASS_MMC,
+					      "sdhci@ff170000", &dev)) {
+			puts("Boot from SD1 but without SD1 enabled!\n");
+			return -1;
+		}
+		debug("mmc1 device found at %p, seq %d\n", dev, dev->seq);
+
+		mode = "mmc";
+		bootseq = dev->seq;
 		env_set("modeboot", "sdboot");
 		break;
 	case NAND_MODE:
@@ -525,6 +581,11 @@
 		break;
 	}
 
+	if (bootseq >= 0) {
+		bootseq_len = snprintf(NULL, 0, "%i", bootseq);
+		debug("Bootseq len: %x\n", bootseq_len);
+	}
+
 	/*
 	 * One terminating char + one byte for space between mode
 	 * and default boot_targets
@@ -533,13 +594,20 @@
 	if (env_targets)
 		env_targets_len = strlen(env_targets);
 
-	new_targets = calloc(1, strlen(mode) + env_targets_len + 2);
+	new_targets = calloc(1, strlen(mode) + env_targets_len + 2 +
+			     bootseq_len);
 
-	sprintf(new_targets, "%s %s", mode,
-		env_targets ? env_targets : "");
+	if (bootseq >= 0)
+		sprintf(new_targets, "%s%x %s", mode, bootseq,
+			env_targets ? env_targets : "");
+	else
+		sprintf(new_targets, "%s %s", mode,
+			env_targets ? env_targets : "");
 
 	env_set("boot_targets", new_targets);
 
+	reset_reason();
+
 	return 0;
 }
 
diff --git a/cmd/Kconfig b/cmd/Kconfig
index cffc3af..e283cb9 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -137,8 +137,6 @@
 
 endmenu
 
-source "cmd/fastboot/Kconfig"
-
 config BUILD_BIN2C
 	bool
 
@@ -228,7 +226,7 @@
 
 config CMD_BOOTEFI_HELLO_COMPILE
 	bool "Compile a standard EFI hello world binary for testing"
-	depends on CMD_BOOTEFI && (ARM || X86)
+	depends on CMD_BOOTEFI && (ARM || X86 || RISCV)
 	default y
 	help
 	  This compiles a standard EFI hello world application with U-Boot so
@@ -650,6 +648,18 @@
 	  can be useful to see the state of driver model for debugging or
 	  interest.
 
+config CMD_FASTBOOT
+	bool "fastboot - Android fastboot support"
+	depends on FASTBOOT
+	help
+	  This enables the command "fastboot" which enables the Android
+	  fastboot mode for the platform. Fastboot is a protocol for
+	  downloading images, flashing and device control used on
+	  Android devices. Fastboot requires either the network stack
+	  enabled or support for acting as a USB device.
+
+	  See doc/README.android-fastboot for more information.
+
 config CMD_FDC
 	bool "fdcboot - Boot from floppy device"
 	help
@@ -697,6 +707,13 @@
 	  Supports loading an FPGA device from a bitstream buffer containing
 	  a partial bitstream.
 
+config CMD_FPGA_LOAD_SECURE
+	bool "fpga loads - loads secure bitstreams (Xilinx only)"
+	depends on CMD_FPGA
+	help
+	  Enables the fpga loads command which is used to load secure
+	  (authenticated or encrypted or both) bitstreams on to FPGA.
+
 config CMD_FPGAD
 	bool "fpgad - dump FPGA registers"
 	help
@@ -823,6 +840,14 @@
 	  Enable the commands for reading, writing and programming the
 	  key for the Replay Protection Memory Block partition in eMMC.
 
+config CMD_MMC_SWRITE
+	bool "mmc swrite"
+	depends on CMD_MMC && MMC_WRITE
+	select IMAGE_SPARSE
+	help
+	  Enable support for the "mmc swrite" command to write Android sparse
+	  images to eMMC.
+
 config CMD_NAND
 	bool "nand"
 	default y if NAND_SUNXI
@@ -1491,25 +1516,37 @@
 	help
 	  Add -v option to verify data against a hash.
 
+config CMD_TPM_V1
+	bool
+
+config CMD_TPM_V2
+	bool
+
 config CMD_TPM
 	bool "Enable the 'tpm' command"
-	depends on TPM
+	depends on TPM_V1 || TPM_V2
+	select CMD_TPM_V1 if TPM_V1
+	select CMD_TPM_V2 if TPM_V2
 	help
 	  This provides a means to talk to a TPM from the command line. A wide
 	  range of commands if provided - see 'tpm help' for details. The
 	  command requires a suitable TPM on your board and the correct driver
 	  must be enabled.
 
+if CMD_TPM
+
 config CMD_TPM_TEST
 	bool "Enable the 'tpm test' command"
-	depends on CMD_TPM
+	depends on TPM_V1
 	help
-	  This provides a a series of tests to confirm that the TPM is working
-	  correctly. The tests cover initialisation, non-volatile RAM, extend,
-	  global lock and checking that timing is within expectations. The
-	  tests pass correctly on Infineon TPMs but may need to be adjusted
+	  This provides a a series of tests to confirm that the TPMv1.x is
+	  working correctly. The tests cover initialisation, non-volatile RAM,
+	  extend, global lock and checking that timing is within expectations.
+	  The tests pass correctly on Infineon TPMs but may need to be adjusted
 	  for other devices.
 
+endif
+
 endmenu
 
 menu "Firmware commands"
diff --git a/cmd/Makefile b/cmd/Makefile
index c05dc2b..e0088df 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -120,8 +120,10 @@
 obj-$(CONFIG_CMD_TIME) += time.o
 obj-$(CONFIG_CMD_TRACE) += trace.o
 obj-$(CONFIG_HUSH_PARSER) += test.o
-obj-$(CONFIG_CMD_TPM) += tpm.o
+obj-$(CONFIG_CMD_TPM) += tpm-common.o
+obj-$(CONFIG_CMD_TPM_V1) += tpm-v1.o
 obj-$(CONFIG_CMD_TPM_TEST) += tpm_test.o
+obj-$(CONFIG_CMD_TPM_V2) += tpm-v2.o
 obj-$(CONFIG_CMD_CROS_EC) += cros_ec.o
 obj-$(CONFIG_CMD_TSI148) += tsi148.o
 obj-$(CONFIG_CMD_UBI) += ubi.o
diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 11b84c5..707d159 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -17,6 +17,7 @@
 #include <memalign.h>
 #include <asm/global_data.h>
 #include <asm-generic/sections.h>
+#include <asm-generic/unaligned.h>
 #include <linux/linkage.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -83,6 +84,15 @@
 }
 
 /*
+ * Allow unaligned memory access.
+ *
+ * This routine is overridden by architectures providing this feature.
+ */
+void __weak allow_unaligned(void)
+{
+}
+
+/*
  * Set the load options of an image from an environment variable.
  *
  * @loaded_image_info:	the image
@@ -133,11 +143,13 @@
 
 	/* Safe fdt location is at 128MB */
 	new_fdt_addr = fdt_ram_start + (128 * 1024 * 1024) + fdt_size;
-	if (efi_allocate_pages(1, EFI_RUNTIME_SERVICES_DATA, fdt_pages,
+	if (efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
+			       EFI_RUNTIME_SERVICES_DATA, fdt_pages,
 			       &new_fdt_addr) != EFI_SUCCESS) {
 		/* If we can't put it there, put it somewhere */
 		new_fdt_addr = (ulong)memalign(EFI_PAGE_SIZE, fdt_size);
-		if (efi_allocate_pages(1, EFI_RUNTIME_SERVICES_DATA, fdt_pages,
+		if (efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
+				       EFI_RUNTIME_SERVICES_DATA, fdt_pages,
 				       &new_fdt_addr) != EFI_SUCCESS) {
 			printf("ERROR: Failed to reserve space for FDT\n");
 			return NULL;
@@ -370,6 +382,9 @@
 	efi_status_t r;
 	void *fdt_addr;
 
+	/* Allow unaligned memory access */
+	allow_unaligned();
+
 	/* Initialize EFI drivers */
 	r = efi_init_obj_list();
 	if (r != EFI_SUCCESS) {
@@ -428,8 +443,6 @@
 		 * callback entry
 		 */
 		efi_save_gd();
-		/* Initialize and populate EFI object list */
-		efi_init_obj_list();
 		/* Transfer environment variable efi_selftest as load options */
 		set_load_options(&loaded_image_info, "efi_selftest");
 		/* Execute the test */
diff --git a/cmd/fastboot.c b/cmd/fastboot.c
index a5ec5f4..557257a 100644
--- a/cmd/fastboot.c
+++ b/cmd/fastboot.c
@@ -10,10 +10,32 @@
 #include <command.h>
 #include <console.h>
 #include <g_dnl.h>
+#include <fastboot.h>
+#include <net.h>
 #include <usb.h>
 
-static int do_fastboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+static int do_fastboot_udp(int argc, char *const argv[],
+			   uintptr_t buf_addr, size_t buf_size)
 {
+#if CONFIG_IS_ENABLED(UDP_FUNCTION_FASTBOOT)
+	int err = net_loop(FASTBOOT);
+
+	if (err < 0) {
+		printf("fastboot udp error: %d\n", err);
+		return CMD_RET_FAILURE;
+	}
+
+	return CMD_RET_SUCCESS;
+#else
+	pr_err("Fastboot UDP not enabled\n");
+	return CMD_RET_FAILURE;
+#endif
+}
+
+static int do_fastboot_usb(int argc, char *const argv[],
+			   uintptr_t buf_addr, size_t buf_size)
+{
+#if CONFIG_IS_ENABLED(USB_FUNCTION_FASTBOOT)
 	int controller_index;
 	char *usb_controller;
 	int ret;
@@ -58,11 +80,70 @@
 	board_usb_cleanup(controller_index, USB_INIT_DEVICE);
 
 	return ret;
+#else
+	pr_err("Fastboot USB not enabled\n");
+	return CMD_RET_FAILURE;
+#endif
 }
 
+static int do_fastboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+	uintptr_t buf_addr = (uintptr_t)NULL;
+	size_t buf_size = 0;
+
+	if (argc < 2)
+		return CMD_RET_USAGE;
+
+	while (argc > 1 && **(argv + 1) == '-') {
+		char *arg = *++argv;
+
+		--argc;
+		while (*++arg) {
+			switch (*arg) {
+			case 'l':
+				if (--argc <= 0)
+					return CMD_RET_USAGE;
+				buf_addr = simple_strtoul(*++argv, NULL, 16);
+				goto NXTARG;
+
+			case 's':
+				if (--argc <= 0)
+					return CMD_RET_USAGE;
+				buf_size = simple_strtoul(*++argv, NULL, 16);
+				goto NXTARG;
+
+			default:
+				return CMD_RET_USAGE;
+			}
+		}
+NXTARG:
+		;
+	}
+
+	fastboot_init((void *)buf_addr, buf_size);
+
+	if (!strcmp(argv[1], "udp"))
+		return do_fastboot_udp(argc, argv, buf_addr, buf_size);
+
+	if (!strcmp(argv[1], "usb")) {
+		argv++;
+		argc--;
+	}
+
+	return do_fastboot_usb(argc, argv, buf_addr, buf_size);
+}
+
+#ifdef CONFIG_SYS_LONGHELP
+static char fastboot_help_text[] =
+	"[-l addr] [-s size] usb <controller> | udp\n"
+	"\taddr - address of buffer used during data transfers ("
+	__stringify(CONFIG_FASTBOOT_BUF_ADDR) ")\n"
+	"\tsize - size of buffer used during data transfers ("
+	__stringify(CONFIG_FASTBOOT_BUF_SIZE) ")"
+	;
+#endif
+
 U_BOOT_CMD(
-	fastboot, 2, 1, do_fastboot,
-	"use USB Fastboot protocol",
-	"<USB_controller>\n"
-	"    - run as a fastboot usb device"
+	fastboot, CONFIG_SYS_MAXARGS, 1, do_fastboot,
+	"run as a fastboot usb or udp device", fastboot_help_text
 );
diff --git a/cmd/fpga.c b/cmd/fpga.c
index 14ad4e5..74ae80c 100644
--- a/cmd/fpga.c
+++ b/cmd/fpga.c
@@ -27,6 +27,7 @@
 	FPGA_LOADP,
 	FPGA_LOADBP,
 	FPGA_LOADFS,
+	FPGA_LOADS,
 };
 
 /* ------------------------------------------------------------------------- */
@@ -54,21 +55,55 @@
 	fpga_fs_info fpga_fsinfo;
 	fpga_fsinfo.fstype = FS_TYPE_ANY;
 #endif
+#if defined(CONFIG_CMD_FPGA_LOAD_SECURE)
+	struct fpga_secure_info fpga_sec_info;
+
+	memset(&fpga_sec_info, 0, sizeof(fpga_sec_info));
+#endif
 
 	if (devstr)
 		dev = (int) simple_strtoul(devstr, NULL, 16);
 	if (datastr)
 		fpga_data = (void *)simple_strtoul(datastr, NULL, 16);
 
-	switch (argc) {
+	if (argc > 9 || argc < 2) {
+		debug("%s: Too many or too few args (%d)\n", __func__, argc);
+		return CMD_RET_USAGE;
+	}
+
+	op = (int)fpga_get_op(argv[1]);
+
+	switch (op) {
 #if defined(CONFIG_CMD_FPGA_LOADFS)
-	case 9:
+	case FPGA_LOADFS:
+		if (argc < 9)
+			return CMD_RET_USAGE;
 		fpga_fsinfo.blocksize = (unsigned int)
-					     simple_strtoul(argv[5], NULL, 16);
+					simple_strtoul(argv[5], NULL, 16);
 		fpga_fsinfo.interface = argv[6];
 		fpga_fsinfo.dev_part = argv[7];
 		fpga_fsinfo.filename = argv[8];
+		argc = 5;
+		break;
 #endif
+#if defined(CONFIG_CMD_FPGA_LOAD_SECURE)
+	case FPGA_LOADS:
+		if (argc < 7)
+			return CMD_RET_USAGE;
+		if (argc == 8)
+			fpga_sec_info.userkey_addr = (u8 *)(uintptr_t)
+						     simple_strtoull(argv[7],
+								     NULL, 16);
+		fpga_sec_info.encflag = (u8)simple_strtoul(argv[6], NULL, 16);
+		fpga_sec_info.authflag = (u8)simple_strtoul(argv[5], NULL, 16);
+		argc = 5;
+		break;
+#endif
+	default:
+		break;
+	}
+
+	switch (argc) {
 	case 5:		/* fpga <op> <dev> <data> <datasize> */
 		data_size = simple_strtoul(argv[4], NULL, 16);
 
@@ -117,15 +152,6 @@
 			      __func__, (ulong)fpga_data);
 			dev = FPGA_INVALID_DEVICE;	/* reset device num */
 		}
-
-	case 2:		/* fpga <op> */
-		op = (int)fpga_get_op(argv[1]);
-		break;
-
-	default:
-		debug("%s: Too many or too few args (%d)\n", __func__, argc);
-		op = FPGA_NONE;	/* force usage display */
-		break;
 	}
 
 	if (dev == FPGA_INVALID_DEVICE) {
@@ -143,6 +169,22 @@
 		if (!fpga_fsinfo.interface || !fpga_fsinfo.dev_part ||
 		    !fpga_fsinfo.filename)
 			wrong_parms = 1;
+		break;
+#endif
+#if defined(CONFIG_CMD_FPGA_LOAD_SECURE)
+	case FPGA_LOADS:
+		if (fpga_sec_info.authflag >= FPGA_NO_ENC_OR_NO_AUTH &&
+		    fpga_sec_info.encflag >= FPGA_NO_ENC_OR_NO_AUTH) {
+			puts("ERR: use <fpga load> for NonSecure bitstream\n");
+			wrong_parms = 1;
+		}
+
+		if (fpga_sec_info.encflag == FPGA_ENC_USR_KEY &&
+		    !fpga_sec_info.userkey_addr) {
+			wrong_parms = 1;
+			puts("ERR:User key not provided\n");
+		}
+		break;
 #endif
 	case FPGA_LOAD:
 	case FPGA_LOADP:
@@ -199,6 +241,12 @@
 		break;
 #endif
 
+#if defined(CONFIG_CMD_FPGA_LOAD_SECURE)
+	case FPGA_LOADS:
+		rc = fpga_loads(dev, fpga_data, data_size, &fpga_sec_info);
+		break;
+#endif
+
 #if defined(CONFIG_CMD_FPGA_LOADMK)
 	case FPGA_LOADMK:
 		switch (genimg_get_format(fpga_data)) {
@@ -332,6 +380,10 @@
 #endif
 	else if (!strcmp("dump", opstr))
 		op = FPGA_DUMP;
+#if defined(CONFIG_CMD_FPGA_LOAD_SECURE)
+	else if (!strcmp("loads", opstr))
+		op = FPGA_LOADS;
+#endif
 
 	if (op == FPGA_NONE)
 		printf("Unknown fpga operation \"%s\"\n", opstr);
@@ -339,7 +391,7 @@
 	return op;
 }
 
-#if defined(CONFIG_CMD_FPGA_LOADFS)
+#if defined(CONFIG_CMD_FPGA_LOADFS) || defined(CONFIG_CMD_FPGA_LOAD_SECURE)
 U_BOOT_CMD(fpga, 9, 1, do_fpga,
 #else
 U_BOOT_CMD(fpga, 6, 1, do_fpga,
@@ -374,4 +426,19 @@
 	   "\tsubimage unit name in the form of addr:<subimg_uname>"
 #endif
 #endif
+#if defined(CONFIG_CMD_FPGA_LOAD_SECURE)
+	   "Load encrypted bitstream (Xilinx only)\n"
+	   "  loads [dev] [address] [size] [auth-OCM-0/DDR-1/noauth-2]\n"
+	   "        [enc-devkey(0)/userkey(1)/nenc(2) [Userkey address]\n"
+	   "Loads the secure bistreams(authenticated/encrypted/both\n"
+	   "authenticated and encrypted) of [size] from [address].\n"
+	   "The auth-OCM/DDR flag specifies to perform authentication\n"
+	   "in OCM or in DDR. 0 for OCM, 1 for DDR, 2 for no authentication.\n"
+	   "The enc flag specifies which key to be used for decryption\n"
+	   "0-device key, 1-user key, 2-no encryption.\n"
+	   "The optional Userkey address specifies from which address key\n"
+	   "has to be used for decryption if user key is selected.\n"
+	   "NOTE: the sceure bitstream has to be created using xilinx\n"
+	   "bootgen tool only.\n"
+#endif
 );
diff --git a/cmd/mmc.c b/cmd/mmc.c
index a3357ef..c2ee2d9 100644
--- a/cmd/mmc.c
+++ b/cmd/mmc.c
@@ -308,8 +308,7 @@
 	return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
 }
 
-#if CONFIG_IS_ENABLED(MMC_WRITE)
-#if defined(CONFIG_FASTBOOT_FLASH)
+#if CONFIG_IS_ENABLED(CMD_MMC_SWRITE)
 static lbaint_t mmc_sparse_write(struct sparse_storage *info, lbaint_t blk,
 				 lbaint_t blkcnt, const void *buffer)
 {
@@ -367,13 +366,14 @@
 	sparse.mssg = NULL;
 	sprintf(dest, "0x" LBAF, sparse.start * sparse.blksz);
 
-	if (write_sparse_image(&sparse, dest, addr))
+	if (write_sparse_image(&sparse, dest, addr, NULL))
 		return CMD_RET_FAILURE;
 	else
 		return CMD_RET_SUCCESS;
 }
 #endif
 
+#if CONFIG_IS_ENABLED(MMC_WRITE)
 static int do_mmc_write(cmd_tbl_t *cmdtp, int flag,
 			int argc, char * const argv[])
 {
@@ -868,11 +868,11 @@
 	U_BOOT_CMD_MKENT(read, 4, 1, do_mmc_read, "", ""),
 #if CONFIG_IS_ENABLED(MMC_WRITE)
 	U_BOOT_CMD_MKENT(write, 4, 0, do_mmc_write, "", ""),
-#if defined(CONFIG_FASTBOOT_FLASH)
-	U_BOOT_CMD_MKENT(swrite, 3, 0, do_mmc_sparse_write, "", ""),
-#endif
 	U_BOOT_CMD_MKENT(erase, 3, 0, do_mmc_erase, "", ""),
 #endif
+#if CONFIG_IS_ENABLED(CMD_MMC_SWRITE)
+	U_BOOT_CMD_MKENT(swrite, 3, 0, do_mmc_sparse_write, "", ""),
+#endif
 	U_BOOT_CMD_MKENT(rescan, 1, 1, do_mmc_rescan, "", ""),
 	U_BOOT_CMD_MKENT(part, 1, 1, do_mmc_part, "", ""),
 	U_BOOT_CMD_MKENT(dev, 3, 0, do_mmc_dev, "", ""),
@@ -927,7 +927,7 @@
 	"info - display info of the current MMC device\n"
 	"mmc read addr blk# cnt\n"
 	"mmc write addr blk# cnt\n"
-#if defined(CONFIG_FASTBOOT_FLASH)
+#if CONFIG_IS_ENABLED(CMD_MMC_SWRITE)
 	"mmc swrite addr blk#\n"
 #endif
 	"mmc erase blk# cnt\n"
diff --git a/cmd/tpm-common.c b/cmd/tpm-common.c
new file mode 100644
index 0000000..6cf9fcc
--- /dev/null
+++ b/cmd/tpm-common.c
@@ -0,0 +1,288 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2013 The Chromium OS Authors.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <dm.h>
+#include <asm/unaligned.h>
+#include <linux/string.h>
+#include <tpm-common.h>
+#include "tpm-user-utils.h"
+
+/**
+ * Print a byte string in hexdecimal format, 16-bytes per line.
+ *
+ * @param data		byte string to be printed
+ * @param count		number of bytes to be printed
+ */
+void print_byte_string(u8 *data, size_t count)
+{
+	int i, print_newline = 0;
+
+	for (i = 0; i < count; i++) {
+		printf(" %02x", data[i]);
+		print_newline = (i % 16 == 15);
+		if (print_newline)
+			putc('\n');
+	}
+	/* Avoid duplicated newline at the end */
+	if (!print_newline)
+		putc('\n');
+}
+
+/**
+ * Convert a text string of hexdecimal values into a byte string.
+ *
+ * @param bytes		text string of hexdecimal values with no space
+ *			between them
+ * @param data		output buffer for byte string.  The caller has to make
+ *			sure it is large enough for storing the output.  If
+ *			NULL is passed, a large enough buffer will be allocated,
+ *			and the caller must free it.
+ * @param count_ptr	output variable for the length of byte string
+ * @return pointer to output buffer
+ */
+void *parse_byte_string(char *bytes, u8 *data, size_t *count_ptr)
+{
+	char byte[3];
+	size_t count, length;
+	int i;
+
+	if (!bytes)
+		return NULL;
+	length = strlen(bytes);
+	count = length / 2;
+
+	if (!data)
+		data = malloc(count);
+	if (!data)
+		return NULL;
+
+	byte[2] = '\0';
+	for (i = 0; i < length; i += 2) {
+		byte[0] = bytes[i];
+		byte[1] = bytes[i + 1];
+		data[i / 2] = (u8)simple_strtoul(byte, NULL, 16);
+	}
+
+	if (count_ptr)
+		*count_ptr = count;
+
+	return data;
+}
+
+/**
+ * report_return_code() - Report any error and return failure or success
+ *
+ * @param return_code	TPM command return code
+ * @return value of enum command_ret_t
+ */
+int report_return_code(int return_code)
+{
+	if (return_code) {
+		printf("Error: %d\n", return_code);
+		return CMD_RET_FAILURE;
+	} else {
+		return CMD_RET_SUCCESS;
+	}
+}
+
+/**
+ * Return number of values defined by a type string.
+ *
+ * @param type_str	type string
+ * @return number of values of type string
+ */
+int type_string_get_num_values(const char *type_str)
+{
+	return strlen(type_str);
+}
+
+/**
+ * Return total size of values defined by a type string.
+ *
+ * @param type_str	type string
+ * @return total size of values of type string, or 0 if type string
+ *  contains illegal type character.
+ */
+size_t type_string_get_space_size(const char *type_str)
+{
+	size_t size;
+
+	for (size = 0; *type_str; type_str++) {
+		switch (*type_str) {
+		case 'b':
+			size += 1;
+			break;
+		case 'w':
+			size += 2;
+			break;
+		case 'd':
+			size += 4;
+			break;
+		default:
+			return 0;
+		}
+	}
+
+	return size;
+}
+
+/**
+ * Allocate a buffer large enough to hold values defined by a type
+ * string.  The caller has to free the buffer.
+ *
+ * @param type_str	type string
+ * @param count		pointer for storing size of buffer
+ * @return pointer to buffer or NULL on error
+ */
+void *type_string_alloc(const char *type_str, u32 *count)
+{
+	void *data;
+	size_t size;
+
+	size = type_string_get_space_size(type_str);
+	if (!size)
+		return NULL;
+	data = malloc(size);
+	if (data)
+		*count = size;
+
+	return data;
+}
+
+/**
+ * Pack values defined by a type string into a buffer.  The buffer must have
+ * large enough space.
+ *
+ * @param type_str	type string
+ * @param values	text strings of values to be packed
+ * @param data		output buffer of values
+ * @return 0 on success, non-0 on error
+ */
+int type_string_pack(const char *type_str, char * const values[],
+		     u8 *data)
+{
+	size_t offset;
+	u32 value;
+
+	for (offset = 0; *type_str; type_str++, values++) {
+		value = simple_strtoul(values[0], NULL, 0);
+		switch (*type_str) {
+		case 'b':
+			data[offset] = value;
+			offset += 1;
+			break;
+		case 'w':
+			put_unaligned_be16(value, data + offset);
+			offset += 2;
+			break;
+		case 'd':
+			put_unaligned_be32(value, data + offset);
+			offset += 4;
+			break;
+		default:
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * Read values defined by a type string from a buffer, and write these values
+ * to environment variables.
+ *
+ * @param type_str	type string
+ * @param data		input buffer of values
+ * @param vars		names of environment variables
+ * @return 0 on success, non-0 on error
+ */
+int type_string_write_vars(const char *type_str, u8 *data,
+			   char * const vars[])
+{
+	size_t offset;
+	u32 value;
+
+	for (offset = 0; *type_str; type_str++, vars++) {
+		switch (*type_str) {
+		case 'b':
+			value = data[offset];
+			offset += 1;
+			break;
+		case 'w':
+			value = get_unaligned_be16(data + offset);
+			offset += 2;
+			break;
+		case 'd':
+			value = get_unaligned_be32(data + offset);
+			offset += 4;
+			break;
+		default:
+			return -1;
+		}
+		if (env_set_ulong(*vars, value))
+			return -1;
+	}
+
+	return 0;
+}
+
+int get_tpm(struct udevice **devp)
+{
+	int rc;
+
+	rc = uclass_first_device_err(UCLASS_TPM, devp);
+	if (rc) {
+		printf("Could not find TPM (ret=%d)\n", rc);
+		return CMD_RET_FAILURE;
+	}
+
+	return 0;
+}
+
+int do_tpm_info(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+	struct udevice *dev;
+	char buf[80];
+	int rc;
+
+	rc = get_tpm(&dev);
+	if (rc)
+		return rc;
+	rc = tpm_get_desc(dev, buf, sizeof(buf));
+	if (rc < 0) {
+		printf("Couldn't get TPM info (%d)\n", rc);
+		return CMD_RET_FAILURE;
+	}
+	printf("%s\n", buf);
+
+	return 0;
+}
+
+int do_tpm_init(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	if (argc != 1)
+		return CMD_RET_USAGE;
+
+	return report_return_code(tpm_init());
+}
+
+int do_tpm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	cmd_tbl_t *tpm_commands, *cmd;
+	unsigned int size;
+
+	if (argc < 2)
+		return CMD_RET_USAGE;
+
+	tpm_commands = get_tpm_commands(&size);
+
+	cmd = find_cmd_tbl(argv[1], tpm_commands, size);
+	if (!cmd)
+		return CMD_RET_USAGE;
+
+	return cmd->cmd(cmdtp, flag, argc - 1, argv + 1);
+}
diff --git a/cmd/tpm-user-utils.h b/cmd/tpm-user-utils.h
new file mode 100644
index 0000000..8ce9861
--- /dev/null
+++ b/cmd/tpm-user-utils.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2013 The Chromium OS Authors.
+ * Coypright (c) 2013 Guntermann & Drunck GmbH
+ */
+
+#ifndef __TPM_USER_UTILS_H
+#define __TPM_USER_UTILS_H
+
+void print_byte_string(u8 *data, size_t count);
+void *parse_byte_string(char *bytes, u8 *data, size_t *count_ptr);
+int report_return_code(int return_code);
+int type_string_get_num_values(const char *type_str);
+size_t type_string_get_space_size(const char *type_str);
+void *type_string_alloc(const char *type_str, u32 *count);
+int type_string_pack(const char *type_str, char * const values[], u8 *data);
+int type_string_write_vars(const char *type_str, u8 *data, char * const vars[]);
+int get_tpm(struct udevice **devp);
+
+int do_tpm_init(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]);
+int do_tpm_info(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]);
+int do_tpm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+
+#endif /* __TPM_USER_UTILS_H */
diff --git a/cmd/tpm.c b/cmd/tpm-v1.c
similarity index 64%
rename from cmd/tpm.c
rename to cmd/tpm-v1.c
index c173bcf..0874c4d 100644
--- a/cmd/tpm.c
+++ b/cmd/tpm-v1.c
@@ -4,241 +4,14 @@
  */
 
 #include <common.h>
-#include <command.h>
-#include <dm.h>
 #include <malloc.h>
-#include <tpm.h>
 #include <asm/unaligned.h>
-#include <linux/string.h>
+#include <tpm-common.h>
+#include <tpm-v1.h>
+#include "tpm-user-utils.h"
 
-/* Useful constants */
-enum {
-	DIGEST_LENGTH		= 20,
-	/* max lengths, valid for RSA keys <= 2048 bits */
-	TPM_PUBKEY_MAX_LENGTH	= 288,
-};
-
-/**
- * Print a byte string in hexdecimal format, 16-bytes per line.
- *
- * @param data		byte string to be printed
- * @param count		number of bytes to be printed
- */
-static void print_byte_string(uint8_t *data, size_t count)
-{
-	int i, print_newline = 0;
-
-	for (i = 0; i < count; i++) {
-		printf(" %02x", data[i]);
-		print_newline = (i % 16 == 15);
-		if (print_newline)
-			putc('\n');
-	}
-	/* Avoid duplicated newline at the end */
-	if (!print_newline)
-		putc('\n');
-}
-
-/**
- * Convert a text string of hexdecimal values into a byte string.
- *
- * @param bytes		text string of hexdecimal values with no space
- *			between them
- * @param data		output buffer for byte string.  The caller has to make
- *			sure it is large enough for storing the output.  If
- *			NULL is passed, a large enough buffer will be allocated,
- *			and the caller must free it.
- * @param count_ptr	output variable for the length of byte string
- * @return pointer to output buffer
- */
-static void *parse_byte_string(char *bytes, uint8_t *data, size_t *count_ptr)
-{
-	char byte[3];
-	size_t count, length;
-	int i;
-
-	if (!bytes)
-		return NULL;
-	length = strlen(bytes);
-	count = length / 2;
-
-	if (!data)
-		data = malloc(count);
-	if (!data)
-		return NULL;
-
-	byte[2] = '\0';
-	for (i = 0; i < length; i += 2) {
-		byte[0] = bytes[i];
-		byte[1] = bytes[i + 1];
-		data[i / 2] = (uint8_t)simple_strtoul(byte, NULL, 16);
-	}
-
-	if (count_ptr)
-		*count_ptr = count;
-
-	return data;
-}
-
-/**
- * report_return_code() - Report any error and return failure or success
- *
- * @param return_code	TPM command return code
- * @return value of enum command_ret_t
- */
-static int report_return_code(int return_code)
-{
-	if (return_code) {
-		printf("Error: %d\n", return_code);
-		return CMD_RET_FAILURE;
-	} else {
-		return CMD_RET_SUCCESS;
-	}
-}
-
-/**
- * Return number of values defined by a type string.
- *
- * @param type_str	type string
- * @return number of values of type string
- */
-static int type_string_get_num_values(const char *type_str)
-{
-	return strlen(type_str);
-}
-
-/**
- * Return total size of values defined by a type string.
- *
- * @param type_str	type string
- * @return total size of values of type string, or 0 if type string
- *  contains illegal type character.
- */
-static size_t type_string_get_space_size(const char *type_str)
-{
-	size_t size;
-
-	for (size = 0; *type_str; type_str++) {
-		switch (*type_str) {
-		case 'b':
-			size += 1;
-			break;
-		case 'w':
-			size += 2;
-			break;
-		case 'd':
-			size += 4;
-			break;
-		default:
-			return 0;
-		}
-	}
-
-	return size;
-}
-
-/**
- * Allocate a buffer large enough to hold values defined by a type
- * string.  The caller has to free the buffer.
- *
- * @param type_str	type string
- * @param count		pointer for storing size of buffer
- * @return pointer to buffer or NULL on error
- */
-static void *type_string_alloc(const char *type_str, uint32_t *count)
-{
-	void *data;
-	size_t size;
-
-	size = type_string_get_space_size(type_str);
-	if (!size)
-		return NULL;
-	data = malloc(size);
-	if (data)
-		*count = size;
-
-	return data;
-}
-
-/**
- * Pack values defined by a type string into a buffer.  The buffer must have
- * large enough space.
- *
- * @param type_str	type string
- * @param values	text strings of values to be packed
- * @param data		output buffer of values
- * @return 0 on success, non-0 on error
- */
-static int type_string_pack(const char *type_str, char * const values[],
-		uint8_t *data)
-{
-	size_t offset;
-	uint32_t value;
-
-	for (offset = 0; *type_str; type_str++, values++) {
-		value = simple_strtoul(values[0], NULL, 0);
-		switch (*type_str) {
-		case 'b':
-			data[offset] = value;
-			offset += 1;
-			break;
-		case 'w':
-			put_unaligned_be16(value, data + offset);
-			offset += 2;
-			break;
-		case 'd':
-			put_unaligned_be32(value, data + offset);
-			offset += 4;
-			break;
-		default:
-			return -1;
-		}
-	}
-
-	return 0;
-}
-
-/**
- * Read values defined by a type string from a buffer, and write these values
- * to environment variables.
- *
- * @param type_str	type string
- * @param data		input buffer of values
- * @param vars		names of environment variables
- * @return 0 on success, non-0 on error
- */
-static int type_string_write_vars(const char *type_str, uint8_t *data,
-		char * const vars[])
-{
-	size_t offset;
-	uint32_t value;
-
-	for (offset = 0; *type_str; type_str++, vars++) {
-		switch (*type_str) {
-		case 'b':
-			value = data[offset];
-			offset += 1;
-			break;
-		case 'w':
-			value = get_unaligned_be16(data + offset);
-			offset += 2;
-			break;
-		case 'd':
-			value = get_unaligned_be32(data + offset);
-			offset += 4;
-			break;
-		default:
-			return -1;
-		}
-		if (env_set_ulong(*vars, value))
-			return -1;
-	}
-
-	return 0;
-}
-
-static int do_tpm_startup(cmd_tbl_t *cmdtp, int flag,
-		int argc, char * const argv[])
+static int do_tpm_startup(cmd_tbl_t *cmdtp, int flag, int argc,
+			  char * const argv[])
 {
 	enum tpm_startup_type mode;
 
@@ -258,10 +31,10 @@
 	return report_return_code(tpm_startup(mode));
 }
 
-static int do_tpm_nv_define_space(cmd_tbl_t *cmdtp, int flag,
-		int argc, char * const argv[])
+static int do_tpm_nv_define_space(cmd_tbl_t *cmdtp, int flag, int argc,
+				  char * const argv[])
 {
-	uint32_t index, perm, size;
+	u32 index, perm, size;
 
 	if (argc != 4)
 		return CMD_RET_USAGE;
@@ -272,10 +45,10 @@
 	return report_return_code(tpm_nv_define_space(index, perm, size));
 }
 
-static int do_tpm_nv_read_value(cmd_tbl_t *cmdtp, int flag,
-		int argc, char * const argv[])
+static int do_tpm_nv_read_value(cmd_tbl_t *cmdtp, int flag, int argc,
+				char * const argv[])
 {
-	uint32_t index, count, rc;
+	u32 index, count, rc;
 	void *data;
 
 	if (argc != 4)
@@ -293,10 +66,10 @@
 	return report_return_code(rc);
 }
 
-static int do_tpm_nv_write_value(cmd_tbl_t *cmdtp, int flag,
-		int argc, char * const argv[])
+static int do_tpm_nv_write_value(cmd_tbl_t *cmdtp, int flag, int argc,
+				 char * const argv[])
 {
-	uint32_t index, rc;
+	u32 index, rc;
 	size_t count;
 	void *data;
 
@@ -315,11 +88,11 @@
 	return report_return_code(rc);
 }
 
-static int do_tpm_extend(cmd_tbl_t *cmdtp, int flag,
-		int argc, char * const argv[])
+static int do_tpm_extend(cmd_tbl_t *cmdtp, int flag, int argc,
+			 char * const argv[])
 {
-	uint32_t index, rc;
-	uint8_t in_digest[20], out_digest[20];
+	u32 index, rc;
+	u8 in_digest[20], out_digest[20];
 
 	if (argc != 3)
 		return CMD_RET_USAGE;
@@ -338,10 +111,10 @@
 	return report_return_code(rc);
 }
 
-static int do_tpm_pcr_read(cmd_tbl_t *cmdtp, int flag,
-		int argc, char * const argv[])
+static int do_tpm_pcr_read(cmd_tbl_t *cmdtp, int flag, int argc,
+			   char * const argv[])
 {
-	uint32_t index, count, rc;
+	u32 index, count, rc;
 	void *data;
 
 	if (argc != 4)
@@ -359,22 +132,22 @@
 	return report_return_code(rc);
 }
 
-static int do_tpm_tsc_physical_presence(cmd_tbl_t *cmdtp, int flag,
-		int argc, char * const argv[])
+static int do_tpm_tsc_physical_presence(cmd_tbl_t *cmdtp, int flag, int argc,
+					char * const argv[])
 {
-	uint16_t presence;
+	u16 presence;
 
 	if (argc != 2)
 		return CMD_RET_USAGE;
-	presence = (uint16_t)simple_strtoul(argv[1], NULL, 0);
+	presence = (u16)simple_strtoul(argv[1], NULL, 0);
 
 	return report_return_code(tpm_tsc_physical_presence(presence));
 }
 
-static int do_tpm_read_pubek(cmd_tbl_t *cmdtp, int flag,
-		int argc, char * const argv[])
+static int do_tpm_read_pubek(cmd_tbl_t *cmdtp, int flag, int argc,
+			     char * const argv[])
 {
-	uint32_t count, rc;
+	u32 count, rc;
 	void *data;
 
 	if (argc != 3)
@@ -391,22 +164,22 @@
 	return report_return_code(rc);
 }
 
-static int do_tpm_physical_set_deactivated(cmd_tbl_t *cmdtp, int flag,
-		int argc, char * const argv[])
+static int do_tpm_physical_set_deactivated(cmd_tbl_t *cmdtp, int flag, int argc,
+					   char * const argv[])
 {
-	uint8_t state;
+	u8 state;
 
 	if (argc != 2)
 		return CMD_RET_USAGE;
-	state = (uint8_t)simple_strtoul(argv[1], NULL, 0);
+	state = (u8)simple_strtoul(argv[1], NULL, 0);
 
 	return report_return_code(tpm_physical_set_deactivated(state));
 }
 
-static int do_tpm_get_capability(cmd_tbl_t *cmdtp, int flag,
-		int argc, char * const argv[])
+static int do_tpm_get_capability(cmd_tbl_t *cmdtp, int flag, int argc,
+				 char * const argv[])
 {
-	uint32_t cap_area, sub_cap, rc;
+	u32 cap_area, sub_cap, rc;
 	void *cap;
 	size_t count;
 
@@ -426,63 +199,14 @@
 	return report_return_code(rc);
 }
 
-#define TPM_COMMAND_NO_ARG(cmd)				\
-static int do_##cmd(cmd_tbl_t *cmdtp, int flag,		\
-		int argc, char * const argv[])		\
-{							\
-	if (argc != 1)					\
-		return CMD_RET_USAGE;			\
-	return report_return_code(cmd());		\
-}
-
-TPM_COMMAND_NO_ARG(tpm_init)
-TPM_COMMAND_NO_ARG(tpm_self_test_full)
-TPM_COMMAND_NO_ARG(tpm_continue_self_test)
-TPM_COMMAND_NO_ARG(tpm_force_clear)
-TPM_COMMAND_NO_ARG(tpm_physical_enable)
-TPM_COMMAND_NO_ARG(tpm_physical_disable)
-
-static int get_tpm(struct udevice **devp)
-{
-	int rc;
-
-	rc = uclass_first_device_err(UCLASS_TPM, devp);
-	if (rc) {
-		printf("Could not find TPM (ret=%d)\n", rc);
-		return CMD_RET_FAILURE;
-	}
-
-	return 0;
-}
-
-static int do_tpm_info(cmd_tbl_t *cmdtp, int flag, int argc,
-		       char *const argv[])
-{
-	struct udevice *dev;
-	char buf[80];
-	int rc;
-
-	rc = get_tpm(&dev);
-	if (rc)
-		return rc;
-	rc = tpm_get_desc(dev, buf, sizeof(buf));
-	if (rc < 0) {
-		printf("Couldn't get TPM info (%d)\n", rc);
-		return CMD_RET_FAILURE;
-	}
-	printf("%s\n", buf);
-
-	return 0;
-}
-
-static int do_tpm_raw_transfer(cmd_tbl_t *cmdtp, int flag,
-		int argc, char * const argv[])
+static int do_tpm_raw_transfer(cmd_tbl_t *cmdtp, int flag, int argc,
+			       char * const argv[])
 {
 	struct udevice *dev;
 	void *command;
-	uint8_t response[1024];
+	u8 response[1024];
 	size_t count, response_length = sizeof(response);
-	uint32_t rc;
+	u32 rc;
 
 	command = parse_byte_string(argv[1], NULL, &count);
 	if (!command) {
@@ -504,10 +228,10 @@
 	return report_return_code(rc);
 }
 
-static int do_tpm_nv_define(cmd_tbl_t *cmdtp, int flag,
-		int argc, char * const argv[])
+static int do_tpm_nv_define(cmd_tbl_t *cmdtp, int flag, int argc,
+			    char * const argv[])
 {
-	uint32_t index, perm, size;
+	u32 index, perm, size;
 
 	if (argc != 4)
 		return CMD_RET_USAGE;
@@ -522,10 +246,10 @@
 	return report_return_code(tpm_nv_define_space(index, perm, size));
 }
 
-static int do_tpm_nv_read(cmd_tbl_t *cmdtp, int flag,
-		int argc, char * const argv[])
+static int do_tpm_nv_read(cmd_tbl_t *cmdtp, int flag, int argc,
+			  char * const argv[])
 {
-	uint32_t index, count, err;
+	u32 index, count, err;
 	void *data;
 
 	if (argc < 3)
@@ -551,10 +275,10 @@
 	return report_return_code(err);
 }
 
-static int do_tpm_nv_write(cmd_tbl_t *cmdtp, int flag,
-		int argc, char * const argv[])
+static int do_tpm_nv_write(cmd_tbl_t *cmdtp, int flag, int argc,
+			   char * const argv[])
 {
-	uint32_t index, count, err;
+	u32 index, count, err;
 	void *data;
 
 	if (argc < 3)
@@ -581,10 +305,10 @@
 
 #ifdef CONFIG_TPM_AUTH_SESSIONS
 
-static int do_tpm_oiap(cmd_tbl_t *cmdtp, int flag,
-		int argc, char * const argv[])
+static int do_tpm_oiap(cmd_tbl_t *cmdtp, int flag, int argc,
+		       char * const argv[])
 {
-	uint32_t auth_handle, err;
+	u32 auth_handle, err;
 
 	err = tpm_oiap(&auth_handle);
 
@@ -595,10 +319,10 @@
 static int do_tpm_load_key_by_sha1(cmd_tbl_t *cmdtp, int flag, int argc, char *
 				   const argv[])
 {
-	uint32_t parent_handle = 0;
-	uint32_t key_len, key_handle, err;
-	uint8_t usage_auth[DIGEST_LENGTH];
-	uint8_t parent_hash[DIGEST_LENGTH];
+	u32 parent_handle = 0;
+	u32 key_len, key_handle, err;
+	u8 usage_auth[DIGEST_LENGTH];
+	u8 parent_hash[DIGEST_LENGTH];
 	void *key;
 
 	if (argc < 5)
@@ -630,11 +354,11 @@
 }
 #endif /* CONFIG_TPM_LOAD_KEY_BY_SHA1 */
 
-static int do_tpm_load_key2_oiap(cmd_tbl_t *cmdtp, int flag,
-		int argc, char * const argv[])
+static int do_tpm_load_key2_oiap(cmd_tbl_t *cmdtp, int flag, int argc,
+				 char * const argv[])
 {
-	uint32_t parent_handle, key_len, key_handle, err;
-	uint8_t usage_auth[DIGEST_LENGTH];
+	u32 parent_handle, key_len, key_handle, err;
+	u8 usage_auth[DIGEST_LENGTH];
 	void *key;
 
 	if (argc < 5)
@@ -648,19 +372,19 @@
 	parse_byte_string(argv[4], usage_auth, NULL);
 
 	err = tpm_load_key2_oiap(parent_handle, key, key_len, usage_auth,
-			&key_handle);
+				 &key_handle);
 	if (!err)
 		printf("Key handle is 0x%x\n", key_handle);
 
 	return report_return_code(err);
 }
 
-static int do_tpm_get_pub_key_oiap(cmd_tbl_t *cmdtp, int flag,
-		int argc, char * const argv[])
+static int do_tpm_get_pub_key_oiap(cmd_tbl_t *cmdtp, int flag, int argc,
+				   char * const argv[])
 {
-	uint32_t key_handle, err;
-	uint8_t usage_auth[DIGEST_LENGTH];
-	uint8_t pub_key_buffer[TPM_PUBKEY_MAX_LENGTH];
+	u32 key_handle, err;
+	u8 usage_auth[DIGEST_LENGTH];
+	u8 pub_key_buffer[TPM_PUBKEY_MAX_LENGTH];
 	size_t pub_key_len = sizeof(pub_key_buffer);
 
 	if (argc < 3)
@@ -671,8 +395,8 @@
 		return CMD_RET_FAILURE;
 	parse_byte_string(argv[2], usage_auth, NULL);
 
-	err = tpm_get_pub_key_oiap(key_handle, usage_auth,
-			pub_key_buffer, &pub_key_len);
+	err = tpm_get_pub_key_oiap(key_handle, usage_auth, pub_key_buffer,
+				   &pub_key_len);
 	if (!err) {
 		printf("dump of received pub key structure:\n");
 		print_byte_string(pub_key_buffer, pub_key_len);
@@ -720,9 +444,9 @@
 	}
 
 	if (!strcasecmp(argv[2], "all")) {
-		uint16_t res_count;
-		uint8_t buf[288];
-		uint8_t *ptr;
+		u16 res_count;
+		u8 buf[288];
+		u8 *ptr;
 		int err;
 		uint i;
 
@@ -738,7 +462,7 @@
 		for (i = 0; i < res_count; ++i, ptr += 4)
 			tpm_flush_specific(get_unaligned_be32(ptr), type);
 	} else {
-		uint32_t handle = simple_strtoul(argv[2], NULL, 0);
+		u32 handle = simple_strtoul(argv[2], NULL, 0);
 
 		if (!handle) {
 			printf("Illegal resource handle %s\n", argv[2]);
@@ -756,9 +480,9 @@
 		       char * const argv[])
 {
 	int type = 0;
-	uint16_t res_count;
-	uint8_t buf[288];
-	uint8_t *ptr;
+	u16 res_count;
+	u8 buf[288];
+	u8 *ptr;
 	int err;
 	uint i;
 
@@ -813,51 +537,53 @@
 }
 #endif /* CONFIG_TPM_LIST_RESOURCES */
 
-#define MAKE_TPM_CMD_ENTRY(cmd) \
-	U_BOOT_CMD_MKENT(cmd, 0, 1, do_tpm_ ## cmd, "", "")
+TPM_COMMAND_NO_ARG(tpm_self_test_full)
+TPM_COMMAND_NO_ARG(tpm_continue_self_test)
+TPM_COMMAND_NO_ARG(tpm_force_clear)
+TPM_COMMAND_NO_ARG(tpm_physical_enable)
+TPM_COMMAND_NO_ARG(tpm_physical_disable)
 
-static cmd_tbl_t tpm_commands[] = {
+static cmd_tbl_t tpm1_commands[] = {
 	U_BOOT_CMD_MKENT(info, 0, 1, do_tpm_info, "", ""),
-	U_BOOT_CMD_MKENT(init, 0, 1,
-			do_tpm_init, "", ""),
+	U_BOOT_CMD_MKENT(init, 0, 1, do_tpm_init, "", ""),
 	U_BOOT_CMD_MKENT(startup, 0, 1,
-			do_tpm_startup, "", ""),
+			 do_tpm_startup, "", ""),
 	U_BOOT_CMD_MKENT(self_test_full, 0, 1,
-			do_tpm_self_test_full, "", ""),
+			 do_tpm_self_test_full, "", ""),
 	U_BOOT_CMD_MKENT(continue_self_test, 0, 1,
-			do_tpm_continue_self_test, "", ""),
+			 do_tpm_continue_self_test, "", ""),
 	U_BOOT_CMD_MKENT(force_clear, 0, 1,
-			do_tpm_force_clear, "", ""),
+			 do_tpm_force_clear, "", ""),
 	U_BOOT_CMD_MKENT(physical_enable, 0, 1,
-			do_tpm_physical_enable, "", ""),
+			 do_tpm_physical_enable, "", ""),
 	U_BOOT_CMD_MKENT(physical_disable, 0, 1,
-			do_tpm_physical_disable, "", ""),
+			 do_tpm_physical_disable, "", ""),
 	U_BOOT_CMD_MKENT(nv_define_space, 0, 1,
-			do_tpm_nv_define_space, "", ""),
+			 do_tpm_nv_define_space, "", ""),
 	U_BOOT_CMD_MKENT(nv_read_value, 0, 1,
-			do_tpm_nv_read_value, "", ""),
+			 do_tpm_nv_read_value, "", ""),
 	U_BOOT_CMD_MKENT(nv_write_value, 0, 1,
-			do_tpm_nv_write_value, "", ""),
+			 do_tpm_nv_write_value, "", ""),
 	U_BOOT_CMD_MKENT(extend, 0, 1,
-			do_tpm_extend, "", ""),
+			 do_tpm_extend, "", ""),
 	U_BOOT_CMD_MKENT(pcr_read, 0, 1,
-			do_tpm_pcr_read, "", ""),
+			 do_tpm_pcr_read, "", ""),
 	U_BOOT_CMD_MKENT(tsc_physical_presence, 0, 1,
-			do_tpm_tsc_physical_presence, "", ""),
+			 do_tpm_tsc_physical_presence, "", ""),
 	U_BOOT_CMD_MKENT(read_pubek, 0, 1,
-			do_tpm_read_pubek, "", ""),
+			 do_tpm_read_pubek, "", ""),
 	U_BOOT_CMD_MKENT(physical_set_deactivated, 0, 1,
-			do_tpm_physical_set_deactivated, "", ""),
+			 do_tpm_physical_set_deactivated, "", ""),
 	U_BOOT_CMD_MKENT(get_capability, 0, 1,
-			do_tpm_get_capability, "", ""),
+			 do_tpm_get_capability, "", ""),
 	U_BOOT_CMD_MKENT(raw_transfer, 0, 1,
-			do_tpm_raw_transfer, "", ""),
+			 do_tpm_raw_transfer, "", ""),
 	U_BOOT_CMD_MKENT(nv_define, 0, 1,
-			do_tpm_nv_define, "", ""),
+			 do_tpm_nv_define, "", ""),
 	U_BOOT_CMD_MKENT(nv_read, 0, 1,
-			do_tpm_nv_read, "", ""),
+			 do_tpm_nv_read, "", ""),
 	U_BOOT_CMD_MKENT(nv_write, 0, 1,
-			do_tpm_nv_write, "", ""),
+			 do_tpm_nv_write, "", ""),
 #ifdef CONFIG_TPM_AUTH_SESSIONS
 	U_BOOT_CMD_MKENT(oiap, 0, 1,
 			 do_tpm_oiap, "", ""),
@@ -882,21 +608,15 @@
 #endif /* CONFIG_TPM_LIST_RESOURCES */
 };
 
-static int do_tpm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+cmd_tbl_t *get_tpm_commands(unsigned int *size)
 {
-	cmd_tbl_t *tpm_cmd;
+	*size = ARRAY_SIZE(tpm1_commands);
 
-	if (argc < 2)
-		return CMD_RET_USAGE;
-	tpm_cmd = find_cmd_tbl(argv[1], tpm_commands, ARRAY_SIZE(tpm_commands));
-	if (!tpm_cmd)
-		return CMD_RET_USAGE;
-
-	return tpm_cmd->cmd(cmdtp, flag, argc - 1, argv + 1);
+	return tpm1_commands;
 }
 
 U_BOOT_CMD(tpm, CONFIG_SYS_MAXARGS, 1, do_tpm,
-"Issue a TPM command",
+"Issue a TPMv1.x command",
 "cmd args...\n"
 "    - Issue TPM command <cmd> with arguments <args...>.\n"
 "Admin Startup and State Commands:\n"
diff --git a/cmd/tpm-v2.c b/cmd/tpm-v2.c
new file mode 100644
index 0000000..38add4f
--- /dev/null
+++ b/cmd/tpm-v2.c
@@ -0,0 +1,389 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2018 Bootlin
+ * Author: Miquel Raynal <miquel.raynal@bootlin.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <log.h>
+#include <mapmem.h>
+#include <tpm-common.h>
+#include <tpm-v2.h>
+#include "tpm-user-utils.h"
+
+static int do_tpm2_startup(cmd_tbl_t *cmdtp, int flag, int argc,
+			   char * const argv[])
+{
+	enum tpm2_startup_types mode;
+
+	if (argc != 2)
+		return CMD_RET_USAGE;
+
+	if (!strcasecmp("TPM2_SU_CLEAR", argv[1])) {
+		mode = TPM2_SU_CLEAR;
+	} else if (!strcasecmp("TPM2_SU_STATE", argv[1])) {
+		mode = TPM2_SU_STATE;
+	} else {
+		printf("Couldn't recognize mode string: %s\n", argv[1]);
+		return CMD_RET_FAILURE;
+	}
+
+	return report_return_code(tpm2_startup(mode));
+}
+
+static int do_tpm2_self_test(cmd_tbl_t *cmdtp, int flag, int argc,
+			     char * const argv[])
+{
+	enum tpm2_yes_no full_test;
+
+	if (argc != 2)
+		return CMD_RET_USAGE;
+
+	if (!strcasecmp("full", argv[1])) {
+		full_test = TPMI_YES;
+	} else if (!strcasecmp("continue", argv[1])) {
+		full_test = TPMI_NO;
+	} else {
+		printf("Couldn't recognize test mode: %s\n", argv[1]);
+		return CMD_RET_FAILURE;
+	}
+
+	return report_return_code(tpm2_self_test(full_test));
+}
+
+static int do_tpm2_clear(cmd_tbl_t *cmdtp, int flag, int argc,
+			 char * const argv[])
+{
+	u32 handle = 0;
+	const char *pw = (argc < 3) ? NULL : argv[2];
+	const ssize_t pw_sz = pw ? strlen(pw) : 0;
+
+	if (argc < 2 || argc > 3)
+		return CMD_RET_USAGE;
+
+	if (pw_sz > TPM2_DIGEST_LEN)
+		return -EINVAL;
+
+	if (!strcasecmp("TPM2_RH_LOCKOUT", argv[1]))
+		handle = TPM2_RH_LOCKOUT;
+	else if (!strcasecmp("TPM2_RH_PLATFORM", argv[1]))
+		handle = TPM2_RH_PLATFORM;
+	else
+		return CMD_RET_USAGE;
+
+	return report_return_code(tpm2_clear(handle, pw, pw_sz));
+}
+
+static int do_tpm2_pcr_extend(cmd_tbl_t *cmdtp, int flag, int argc,
+			      char * const argv[])
+{
+	struct udevice *dev;
+	struct tpm_chip_priv *priv;
+	u32 index = simple_strtoul(argv[1], NULL, 0);
+	void *digest = map_sysmem(simple_strtoul(argv[2], NULL, 0), 0);
+	int ret;
+	u32 rc;
+
+	if (argc != 3)
+		return CMD_RET_USAGE;
+
+	ret = uclass_first_device_err(UCLASS_TPM, &dev);
+	if (ret)
+		return ret;
+
+	priv = dev_get_uclass_priv(dev);
+	if (!priv)
+		return -EINVAL;
+
+	if (index >= priv->pcr_count)
+		return -EINVAL;
+
+	rc = tpm2_pcr_extend(index, digest);
+
+	unmap_sysmem(digest);
+
+	return report_return_code(rc);
+}
+
+static int do_tpm_pcr_read(cmd_tbl_t *cmdtp, int flag, int argc,
+			   char * const argv[])
+{
+	struct udevice *dev;
+	struct tpm_chip_priv *priv;
+	u32 index, rc;
+	unsigned int updates;
+	void *data;
+	int ret;
+
+	if (argc != 3)
+		return CMD_RET_USAGE;
+
+	ret = uclass_first_device_err(UCLASS_TPM, &dev);
+	if (ret)
+		return ret;
+
+	priv = dev_get_uclass_priv(dev);
+	if (!priv)
+		return -EINVAL;
+
+	index = simple_strtoul(argv[1], NULL, 0);
+	if (index >= priv->pcr_count)
+		return -EINVAL;
+
+	data = map_sysmem(simple_strtoul(argv[2], NULL, 0), 0);
+
+	rc = tpm2_pcr_read(index, priv->pcr_select_min, data, &updates);
+	if (!rc) {
+		printf("PCR #%u content (%d known updates):\n", index, updates);
+		print_byte_string(data, TPM2_DIGEST_LEN);
+	}
+
+	unmap_sysmem(data);
+
+	return report_return_code(rc);
+}
+
+static int do_tpm_get_capability(cmd_tbl_t *cmdtp, int flag, int argc,
+				 char * const argv[])
+{
+	u32 capability, property, rc;
+	u8 *data;
+	size_t count;
+	int i, j;
+
+	if (argc != 5)
+		return CMD_RET_USAGE;
+
+	capability = simple_strtoul(argv[1], NULL, 0);
+	property = simple_strtoul(argv[2], NULL, 0);
+	data = map_sysmem(simple_strtoul(argv[3], NULL, 0), 0);
+	count = simple_strtoul(argv[4], NULL, 0);
+
+	rc = tpm2_get_capability(capability, property, data, count);
+	if (rc)
+		goto unmap_data;
+
+	printf("Capabilities read from TPM:\n");
+	for (i = 0; i < count; i++) {
+		printf("Property 0x");
+		for (j = 0; j < 4; j++)
+			printf("%02x", data[(i * 8) + j]);
+		printf(": 0x");
+		for (j = 4; j < 8; j++)
+			printf("%02x", data[(i * 8) + j]);
+		printf("\n");
+	}
+
+unmap_data:
+	unmap_sysmem(data);
+
+	return report_return_code(rc);
+}
+
+static int do_tpm_dam_reset(cmd_tbl_t *cmdtp, int flag, int argc,
+			    char *const argv[])
+{
+	const char *pw = (argc < 2) ? NULL : argv[1];
+	const ssize_t pw_sz = pw ? strlen(pw) : 0;
+
+	if (argc > 2)
+		return CMD_RET_USAGE;
+
+	if (pw_sz > TPM2_DIGEST_LEN)
+		return -EINVAL;
+
+	return report_return_code(tpm2_dam_reset(pw, pw_sz));
+}
+
+static int do_tpm_dam_parameters(cmd_tbl_t *cmdtp, int flag, int argc,
+				 char *const argv[])
+{
+	const char *pw = (argc < 5) ? NULL : argv[4];
+	const ssize_t pw_sz = pw ? strlen(pw) : 0;
+	/*
+	 * No Dictionary Attack Mitigation (DAM) means:
+	 * maxtries = 0xFFFFFFFF, recovery_time = 1, lockout_recovery = 0
+	 */
+	unsigned long int max_tries;
+	unsigned long int recovery_time;
+	unsigned long int lockout_recovery;
+
+	if (argc < 4 || argc > 5)
+		return CMD_RET_USAGE;
+
+	if (pw_sz > TPM2_DIGEST_LEN)
+		return -EINVAL;
+
+	if (strict_strtoul(argv[1], 0, &max_tries))
+		return CMD_RET_USAGE;
+
+	if (strict_strtoul(argv[2], 0, &recovery_time))
+		return CMD_RET_USAGE;
+
+	if (strict_strtoul(argv[3], 0, &lockout_recovery))
+		return CMD_RET_USAGE;
+
+	log(LOGC_NONE, LOGL_INFO, "Changing dictionary attack parameters:\n");
+	log(LOGC_NONE, LOGL_INFO, "- maxTries: %lu", max_tries);
+	log(LOGC_NONE, LOGL_INFO, "- recoveryTime: %lu\n", recovery_time);
+	log(LOGC_NONE, LOGL_INFO, "- lockoutRecovery: %lu\n", lockout_recovery);
+
+	return report_return_code(tpm2_dam_parameters(pw, pw_sz, max_tries,
+						      recovery_time,
+						      lockout_recovery));
+}
+
+static int do_tpm_change_auth(cmd_tbl_t *cmdtp, int flag, int argc,
+			      char *const argv[])
+{
+	u32 handle;
+	const char *newpw = argv[2];
+	const char *oldpw = (argc == 3) ? NULL : argv[3];
+	const ssize_t newpw_sz = strlen(newpw);
+	const ssize_t oldpw_sz = oldpw ? strlen(oldpw) : 0;
+
+	if (argc < 3 || argc > 4)
+		return CMD_RET_USAGE;
+
+	if (newpw_sz > TPM2_DIGEST_LEN || oldpw_sz > TPM2_DIGEST_LEN)
+		return -EINVAL;
+
+	if (!strcasecmp("TPM2_RH_LOCKOUT", argv[1]))
+		handle = TPM2_RH_LOCKOUT;
+	else if (!strcasecmp("TPM2_RH_ENDORSEMENT", argv[1]))
+		handle = TPM2_RH_ENDORSEMENT;
+	else if (!strcasecmp("TPM2_RH_OWNER", argv[1]))
+		handle = TPM2_RH_OWNER;
+	else if (!strcasecmp("TPM2_RH_PLATFORM", argv[1]))
+		handle = TPM2_RH_PLATFORM;
+	else
+		return CMD_RET_USAGE;
+
+	return report_return_code(tpm2_change_auth(handle, newpw, newpw_sz,
+						   oldpw, oldpw_sz));
+}
+
+static int do_tpm_pcr_setauthpolicy(cmd_tbl_t *cmdtp, int flag, int argc,
+				    char * const argv[])
+{
+	u32 index = simple_strtoul(argv[1], NULL, 0);
+	char *key = argv[2];
+	const char *pw = (argc < 4) ? NULL : argv[3];
+	const ssize_t pw_sz = pw ? strlen(pw) : 0;
+
+	if (strlen(key) != TPM2_DIGEST_LEN)
+		return -EINVAL;
+
+	if (argc < 3 || argc > 4)
+		return CMD_RET_USAGE;
+
+	return report_return_code(tpm2_pcr_setauthpolicy(pw, pw_sz, index,
+							 key));
+}
+
+static int do_tpm_pcr_setauthvalue(cmd_tbl_t *cmdtp, int flag,
+				   int argc, char * const argv[])
+{
+	u32 index = simple_strtoul(argv[1], NULL, 0);
+	char *key = argv[2];
+	const ssize_t key_sz = strlen(key);
+	const char *pw = (argc < 4) ? NULL : argv[3];
+	const ssize_t pw_sz = pw ? strlen(pw) : 0;
+
+	if (strlen(key) != TPM2_DIGEST_LEN)
+		return -EINVAL;
+
+	if (argc < 3 || argc > 4)
+		return CMD_RET_USAGE;
+
+	return report_return_code(tpm2_pcr_setauthvalue(pw, pw_sz, index,
+							key, key_sz));
+}
+
+static cmd_tbl_t tpm2_commands[] = {
+	U_BOOT_CMD_MKENT(info, 0, 1, do_tpm_info, "", ""),
+	U_BOOT_CMD_MKENT(init, 0, 1, do_tpm_init, "", ""),
+	U_BOOT_CMD_MKENT(startup, 0, 1, do_tpm2_startup, "", ""),
+	U_BOOT_CMD_MKENT(self_test, 0, 1, do_tpm2_self_test, "", ""),
+	U_BOOT_CMD_MKENT(clear, 0, 1, do_tpm2_clear, "", ""),
+	U_BOOT_CMD_MKENT(pcr_extend, 0, 1, do_tpm2_pcr_extend, "", ""),
+	U_BOOT_CMD_MKENT(pcr_read, 0, 1, do_tpm_pcr_read, "", ""),
+	U_BOOT_CMD_MKENT(get_capability, 0, 1, do_tpm_get_capability, "", ""),
+	U_BOOT_CMD_MKENT(dam_reset, 0, 1, do_tpm_dam_reset, "", ""),
+	U_BOOT_CMD_MKENT(dam_parameters, 0, 1, do_tpm_dam_parameters, "", ""),
+	U_BOOT_CMD_MKENT(change_auth, 0, 1, do_tpm_change_auth, "", ""),
+	U_BOOT_CMD_MKENT(pcr_setauthpolicy, 0, 1,
+			 do_tpm_pcr_setauthpolicy, "", ""),
+	U_BOOT_CMD_MKENT(pcr_setauthvalue, 0, 1,
+			 do_tpm_pcr_setauthvalue, "", ""),
+};
+
+cmd_tbl_t *get_tpm_commands(unsigned int *size)
+{
+	*size = ARRAY_SIZE(tpm2_commands);
+
+	return tpm2_commands;
+}
+
+U_BOOT_CMD(tpm, CONFIG_SYS_MAXARGS, 1, do_tpm, "Issue a TPMv2.x command",
+"<command> [<arguments>]\n"
+"\n"
+"info\n"
+"    Show information about the TPM.\n"
+"init\n"
+"    Initialize the software stack. Always the first command to issue.\n"
+"startup <mode>\n"
+"    Issue a TPM2_Startup command.\n"
+"    <mode> is one of:\n"
+"        * TPM2_SU_CLEAR (reset state)\n"
+"        * TPM2_SU_STATE (preserved state)\n"
+"self_test <type>\n"
+"    Test the TPM capabilities.\n"
+"    <type> is one of:\n"
+"        * full (perform all tests)\n"
+"        * continue (only check untested tests)\n"
+"clear <hierarchy>\n"
+"    Issue a TPM2_Clear command.\n"
+"    <hierarchy> is one of:\n"
+"        * TPM2_RH_LOCKOUT\n"
+"        * TPM2_RH_PLATFORM\n"
+"pcr_extend <pcr> <digest_addr>\n"
+"    Extend PCR #<pcr> with digest at <digest_addr>.\n"
+"    <pcr>: index of the PCR\n"
+"    <digest_addr>: address of a 32-byte SHA256 digest\n"
+"pcr_read <pcr> <digest_addr>\n"
+"    Read PCR #<pcr> to memory address <digest_addr>.\n"
+"    <pcr>: index of the PCR\n"
+"    <digest_addr>: address to store the a 32-byte SHA256 digest\n"
+"get_capability <capability> <property> <addr> <count>\n"
+"    Read and display <count> entries indexed by <capability>/<property>.\n"
+"    Values are 4 bytes long and are written at <addr>.\n"
+"    <capability>: capability\n"
+"    <property>: property\n"
+"    <addr>: address to store <count> entries of 4 bytes\n"
+"    <count>: number of entries to retrieve\n"
+"dam_reset [<password>]\n"
+"    If the TPM is not in a LOCKOUT state, reset the internal error counter.\n"
+"    <password>: optional password\n"
+"dam_parameters <max_tries> <recovery_time> <lockout_recovery> [<password>]\n"
+"    If the TPM is not in a LOCKOUT state, set the DAM parameters\n"
+"    <maxTries>: maximum number of failures before lockout,\n"
+"                0 means always locking\n"
+"    <recoveryTime>: time before decrement of the error counter,\n"
+"                    0 means no lockout\n"
+"    <lockoutRecovery>: time of a lockout (before the next try),\n"
+"                       0 means a reboot is needed\n"
+"    <password>: optional password of the LOCKOUT hierarchy\n"
+"change_auth <hierarchy> <new_pw> [<old_pw>]\n"
+"    <hierarchy>: the hierarchy\n"
+"    <new_pw>: new password for <hierarchy>\n"
+"    <old_pw>: optional previous password of <hierarchy>\n"
+"pcr_setauthpolicy|pcr_setauthvalue <pcr> <key> [<password>]\n"
+"    Change the <key> to access PCR #<pcr>.\n"
+"    hierarchy and may be empty.\n"
+"    /!\\WARNING: untested function, use at your own risks !\n"
+"    <pcr>: index of the PCR\n"
+"    <key>: secret to protect the access of PCR #<pcr>\n"
+"    <password>: optional password of the PLATFORM hierarchy\n"
+);
diff --git a/cmd/tpm_test.c b/cmd/tpm_test.c
index 2e7d133..35f3c96 100644
--- a/cmd/tpm_test.c
+++ b/cmd/tpm_test.c
@@ -6,7 +6,7 @@
 #include <common.h>
 #include <command.h>
 #include <environment.h>
-#include <tpm.h>
+#include <tpm-v1.h>
 
 /* Prints error and returns on failure */
 #define TPM_CHECK(tpm_command) do { \
diff --git a/common/Makefile b/common/Makefile
index d0681c7..b3da72e 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -29,7 +29,6 @@
 
 obj-$(CONFIG_CMD_BEDBUG) += bedbug.o
 obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += fdt_support.o
-
 obj-$(CONFIG_MII) += miiphyutil.o
 obj-$(CONFIG_CMD_MII) += miiphyutil.o
 obj-$(CONFIG_PHYLIB) += miiphyutil.o
@@ -109,19 +108,6 @@
 obj-y += memsize.o
 obj-y += stdio.o
 
-ifndef CONFIG_SPL_BUILD
-# This option is not just y/n - it can have a numeric value
-ifdef CONFIG_FASTBOOT_FLASH
-obj-y += image-sparse.o
-ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
-obj-y += fb_mmc.o
-endif
-ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV
-obj-y += fb_nand.o
-endif
-endif
-endif
-
 ifdef CONFIG_CMD_EEPROM_LAYOUT
 obj-y += eeprom/eeprom_field.o eeprom/eeprom_layout.o
 endif
diff --git a/common/bootm.c b/common/bootm.c
index a0ffc1c..e789f68 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -46,6 +46,10 @@
 				   char * const argv[], bootm_headers_t *images,
 				   ulong *os_data, ulong *os_len);
 
+__weak void board_quiesce_devices(void)
+{
+}
+
 #ifdef CONFIG_LMB
 static void boot_start_lmb(bootm_headers_t *images)
 {
diff --git a/common/dlmalloc.c b/common/dlmalloc.c
index b395eefb..edaad29 100644
--- a/common/dlmalloc.c
+++ b/common/dlmalloc.c
@@ -1891,6 +1891,13 @@
 
   if ((long)bytes < 0) return NULL;
 
+#if CONFIG_VAL(SYS_MALLOC_F_LEN)
+	if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) {
+		nb = roundup(bytes, alignment);
+		return malloc_simple(nb);
+	}
+#endif
+
   /* If need less alignment than we give anyway, just relay to malloc */
 
   if (alignment <= MALLOC_ALIGNMENT) return mALLOc(bytes);
diff --git a/common/image-fit.c b/common/image-fit.c
index 8c15ed1..728187a 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -474,7 +474,7 @@
 	fit_image_get_comp(fit, image_noffset, &comp);
 	printf("%s  Compression:  %s\n", p, genimg_get_comp_name(comp));
 
-	ret = fit_image_get_data(fit, image_noffset, &data, &size);
+	ret = fit_image_get_data_and_size(fit, image_noffset, &data, &size);
 
 #ifndef USE_HOSTCC
 	printf("%s  Data Start:   ", p);
@@ -941,6 +941,54 @@
 }
 
 /**
+ * fit_image_get_data_and_size - get data and its size including
+ *				 both embedded and external data
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @data: double pointer to void, will hold data property's data address
+ * @size: pointer to size_t, will hold data property's data size
+ *
+ * fit_image_get_data_and_size() finds data and its size including
+ * both embedded and external data. If the property is found
+ * its data start address and size are returned to the caller.
+ *
+ * returns:
+ *     0, on success
+ *     otherwise, on failure
+ */
+int fit_image_get_data_and_size(const void *fit, int noffset,
+				const void **data, size_t *size)
+{
+	bool external_data = false;
+	int offset;
+	int len;
+	int ret;
+
+	if (!fit_image_get_data_position(fit, noffset, &offset)) {
+		external_data = true;
+	} else if (!fit_image_get_data_offset(fit, noffset, &offset)) {
+		external_data = true;
+		/*
+		 * For FIT with external data, figure out where
+		 * the external images start. This is the base
+		 * for the data-offset properties in each image.
+		 */
+		offset += ((fdt_totalsize(fit) + 3) & ~3);
+	}
+
+	if (external_data) {
+		debug("External Data\n");
+		ret = fit_image_get_data_size(fit, noffset, &len);
+		*data = fit + offset;
+		*size = len;
+	} else {
+		ret = fit_image_get_data(fit, noffset, data, size);
+	}
+
+	return ret;
+}
+
+/**
  * fit_image_hash_get_algo - get hash algorithm name
  * @fit: pointer to the FIT format image header
  * @noffset: hash node offset
@@ -1238,7 +1286,7 @@
 	char		*err_msg = "";
 
 	/* Get image data and data length */
-	if (fit_image_get_data(fit, image_noffset, &data, &size)) {
+	if (fit_image_get_data_and_size(fit, image_noffset, &data, &size)) {
 		err_msg = "Can't get image data/size";
 		printf("error!\n%s for '%s' hash node in '%s' image node\n",
 		       err_msg, fit_get_name(fit, noffset, NULL),
@@ -1876,7 +1924,7 @@
 	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL_OK);
 
 	/* get image data address and length */
-	if (fit_image_get_data(fit, noffset, &buf, &size)) {
+	if (fit_image_get_data_and_size(fit, noffset, &buf, &size)) {
 		printf("Could not find %s subimage data!\n", prop_name);
 		bootstage_error(bootstage_id + BOOTSTAGE_SUB_GET_DATA);
 		return -ENOENT;
diff --git a/configs/A13-OLinuXino_defconfig b/configs/A13-OLinuXino_defconfig
index 8e160d7..b8ec1e5 100644
--- a/configs/A13-OLinuXino_defconfig
+++ b/configs/A13-OLinuXino_defconfig
@@ -22,6 +22,7 @@
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_SPL_PARTITION_UUIDS is not set
 CONFIG_DFU_RAM=y
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_AXP_ALDO3_VOLT=3300
 CONFIG_CONS_INDEX=2
 CONFIG_USB_EHCI_HCD=y
diff --git a/configs/A20-OLinuXino-Lime2-eMMC_defconfig b/configs/A20-OLinuXino-Lime2-eMMC_defconfig
index 9d043e8..5657fc2 100644
--- a/configs/A20-OLinuXino-Lime2-eMMC_defconfig
+++ b/configs/A20-OLinuXino-Lime2-eMMC_defconfig
@@ -20,6 +20,7 @@
 # CONFIG_SPL_PARTITION_UUIDS is not set
 CONFIG_SCSI_AHCI=y
 CONFIG_DFU_RAM=y
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_RGMII=y
 CONFIG_SUN7I_GMAC=y
diff --git a/configs/A20-OLinuXino-Lime2_defconfig b/configs/A20-OLinuXino-Lime2_defconfig
index f2997c6..134d1d3 100644
--- a/configs/A20-OLinuXino-Lime2_defconfig
+++ b/configs/A20-OLinuXino-Lime2_defconfig
@@ -19,6 +19,7 @@
 # CONFIG_SPL_PARTITION_UUIDS is not set
 CONFIG_SCSI_AHCI=y
 CONFIG_DFU_RAM=y
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_RGMII=y
 CONFIG_SUN7I_GMAC=y
diff --git a/configs/A20-Olimex-SOM204-EVB-eMMC_defconfig b/configs/A20-Olimex-SOM204-EVB-eMMC_defconfig
index 847945b..3bb8c4c 100644
--- a/configs/A20-Olimex-SOM204-EVB-eMMC_defconfig
+++ b/configs/A20-Olimex-SOM204-EVB-eMMC_defconfig
@@ -18,6 +18,7 @@
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_SPL_PARTITION_UUIDS is not set
 CONFIG_SCSI_AHCI=y
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_PHY_ADDR=3
 CONFIG_PHY_MICREL=y
 CONFIG_PHY_MICREL_KSZ90X1=y
diff --git a/configs/A20-Olimex-SOM204-EVB_defconfig b/configs/A20-Olimex-SOM204-EVB_defconfig
index e56f2c7..cfb7ffa 100644
--- a/configs/A20-Olimex-SOM204-EVB_defconfig
+++ b/configs/A20-Olimex-SOM204-EVB_defconfig
@@ -17,6 +17,7 @@
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_SPL_PARTITION_UUIDS is not set
 CONFIG_SCSI_AHCI=y
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_PHY_ADDR=3
 CONFIG_PHY_MICREL=y
 CONFIG_PHY_MICREL_KSZ90X1=y
diff --git a/configs/Bananapi_m2m_defconfig b/configs/Bananapi_m2m_defconfig
index 2032a4a..2316437 100644
--- a/configs/Bananapi_m2m_defconfig
+++ b/configs/Bananapi_m2m_defconfig
@@ -13,6 +13,7 @@
 # CONFIG_CMD_FLASH is not set
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_SPL_PARTITION_UUIDS is not set
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_MUSB_GADGET=y
 CONFIG_USB_FUNCTION_MASS_STORAGE=y
diff --git a/configs/Cubietruck_defconfig b/configs/Cubietruck_defconfig
index f0bb4c9..601eb3c 100644
--- a/configs/Cubietruck_defconfig
+++ b/configs/Cubietruck_defconfig
@@ -21,6 +21,7 @@
 # CONFIG_SPL_PARTITION_UUIDS is not set
 CONFIG_SCSI_AHCI=y
 CONFIG_DFU_RAM=y
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_RGMII=y
 CONFIG_SUN7I_GMAC=y
diff --git a/configs/Sinlinx_SinA33_defconfig b/configs/Sinlinx_SinA33_defconfig
index 9e62672..394534b 100644
--- a/configs/Sinlinx_SinA33_defconfig
+++ b/configs/Sinlinx_SinA33_defconfig
@@ -18,6 +18,7 @@
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_SPL_PARTITION_UUIDS is not set
 CONFIG_DFU_RAM=y
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_MUSB_GADGET=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/alt_defconfig b/configs/alt_defconfig
index b0b864c..49f344b 100644
--- a/configs/alt_defconfig
+++ b/configs/alt_defconfig
@@ -46,6 +46,9 @@
 CONFIG_CMD_EXT4=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
+CONFIG_CMD_MTDPARTS=y
+CONFIG_MTDIDS_DEFAULT="nor0=spi0.0"
+CONFIG_MTDPARTS_DEFAULT="mtdparts=spi0.0:256k(u-boot-spl),512k(u-boot-env1),512k(u-boot-env2),768k(u-boot),-(user)"
 CONFIG_OF_CONTROL=y
 CONFIG_OF_EMBED=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
@@ -58,9 +61,11 @@
 CONFIG_DM_MMC=y
 CONFIG_SH_MMCIF=y
 CONFIG_RENESAS_SDHI=y
+CONFIG_MTD=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y
 CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_MTD=y
 CONFIG_PHY_MICREL=y
 CONFIG_DM_ETH=y
 CONFIG_SH_ETHER=y
diff --git a/configs/am335x_boneblack_defconfig b/configs/am335x_boneblack_defconfig
index 5c01b20..31d2fe9 100644
--- a/configs/am335x_boneblack_defconfig
+++ b/configs/am335x_boneblack_defconfig
@@ -16,9 +16,6 @@
 CONFIG_AUTOBOOT_PROMPT="Press SPACE to abort autoboot in %d seconds\n"
 CONFIG_AUTOBOOT_DELAY_STR="d"
 CONFIG_AUTOBOOT_STOP_STR=" "
-CONFIG_FASTBOOT=y
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=1
 CONFIG_CMD_SPL=y
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_SETEXPR is not set
@@ -28,6 +25,10 @@
 CONFIG_DFU_TFTP=y
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=1
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_MMC_OMAP_HS=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
diff --git a/configs/am335x_boneblack_vboot_defconfig b/configs/am335x_boneblack_vboot_defconfig
index abbacdc..baaae36 100644
--- a/configs/am335x_boneblack_vboot_defconfig
+++ b/configs/am335x_boneblack_vboot_defconfig
@@ -19,7 +19,7 @@
 CONFIG_AUTOBOOT_PROMPT="Press SPACE to abort autoboot in %d seconds\n"
 CONFIG_AUTOBOOT_DELAY_STR="d"
 CONFIG_AUTOBOOT_STOP_STR=" "
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_CMD_SPL=y
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_SETEXPR is not set
diff --git a/configs/am335x_evm_defconfig b/configs/am335x_evm_defconfig
index 6732013..cc556d1 100644
--- a/configs/am335x_evm_defconfig
+++ b/configs/am335x_evm_defconfig
@@ -13,7 +13,7 @@
 CONFIG_SPL_MTD_SUPPORT=y
 CONFIG_SPL_MUSB_NEW_SUPPORT=y
 CONFIG_SPL_OS_BOOT=y
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_CMD_SPL=y
 CONFIG_CMD_SPL_NAND_OFS=0x00080000
 # CONFIG_CMD_FLASH is not set
diff --git a/configs/am335x_evm_nor_defconfig b/configs/am335x_evm_nor_defconfig
index bbde07f..41a5c79 100644
--- a/configs/am335x_evm_nor_defconfig
+++ b/configs/am335x_evm_nor_defconfig
@@ -12,7 +12,7 @@
 CONFIG_SPL_MTD_SUPPORT=y
 CONFIG_SPL_MUSB_NEW_SUPPORT=y
 CONFIG_SPL_OS_BOOT=y
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_CMD_SPL=y
 CONFIG_CMD_SPL_NAND_OFS=0x00080000
 CONFIG_CMD_NAND=y
diff --git a/configs/am335x_evm_norboot_defconfig b/configs/am335x_evm_norboot_defconfig
index 3ddcf64..75d0793 100644
--- a/configs/am335x_evm_norboot_defconfig
+++ b/configs/am335x_evm_norboot_defconfig
@@ -12,7 +12,7 @@
 CONFIG_VERSION_VARIABLE=y
 CONFIG_ARCH_MISC_INIT=y
 CONFIG_BOARD_EARLY_INIT_F=y
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_MTDPARTS=y
 CONFIG_MTDIDS_DEFAULT="nor0=physmap-flash.0"
diff --git a/configs/am335x_evm_spiboot_defconfig b/configs/am335x_evm_spiboot_defconfig
index 10eb0fe..b267887 100644
--- a/configs/am335x_evm_spiboot_defconfig
+++ b/configs/am335x_evm_spiboot_defconfig
@@ -15,7 +15,7 @@
 CONFIG_ARCH_MISC_INIT=y
 CONFIG_SPL_MUSB_NEW_SUPPORT=y
 CONFIG_SPL_SPI_LOAD=y
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_MTDPARTS=y
diff --git a/configs/am335x_evm_usbspl_defconfig b/configs/am335x_evm_usbspl_defconfig
index dc9ac21..4401291 100644
--- a/configs/am335x_evm_usbspl_defconfig
+++ b/configs/am335x_evm_usbspl_defconfig
@@ -19,7 +19,7 @@
 CONFIG_SPL_USB_GADGET_SUPPORT=y
 CONFIG_SPL_USB_ETHER=y
 # CONFIG_SPL_YMODEM_SUPPORT is not set
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_CMD_SPL=y
 CONFIG_CMD_SPL_NAND_OFS=0x00080000
 # CONFIG_CMD_FLASH is not set
diff --git a/configs/am57xx_evm_defconfig b/configs/am57xx_evm_defconfig
index 0e99268..2d8e64e 100644
--- a/configs/am57xx_evm_defconfig
+++ b/configs/am57xx_evm_defconfig
@@ -24,12 +24,6 @@
 CONFIG_SPL_DMA_SUPPORT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_SPI_LOAD=y
-CONFIG_FASTBOOT=y
-CONFIG_FASTBOOT_BUF_ADDR=0x82000000
-CONFIG_FASTBOOT_BUF_SIZE=0x2F000000
-CONFIG_FASTBOOT_USB_DEV=1
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=1
 CONFIG_CMD_SPL=y
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_SETEXPR is not set
@@ -45,6 +39,13 @@
 # CONFIG_BLK is not set
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_BUF_ADDR=0x82000000
+CONFIG_FASTBOOT_BUF_SIZE=0x2F000000
+CONFIG_FASTBOOT_USB_DEV=1
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=1
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_I2C=y
 CONFIG_DM_MMC=y
diff --git a/configs/am57xx_hs_evm_defconfig b/configs/am57xx_hs_evm_defconfig
index 165c2a4..3a73fdb 100644
--- a/configs/am57xx_hs_evm_defconfig
+++ b/configs/am57xx_hs_evm_defconfig
@@ -29,12 +29,6 @@
 CONFIG_SPL_SEPARATE_BSS=y
 CONFIG_SPL_DMA_SUPPORT=y
 CONFIG_SPL_SPI_LOAD=y
-CONFIG_FASTBOOT=y
-CONFIG_FASTBOOT_BUF_ADDR=0x82000000
-CONFIG_FASTBOOT_BUF_SIZE=0x2F000000
-CONFIG_FASTBOOT_USB_DEV=1
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=1
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_OF_CONTROL=y
@@ -48,6 +42,13 @@
 # CONFIG_BLK is not set
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_BUF_ADDR=0x82000000
+CONFIG_FASTBOOT_BUF_SIZE=0x2F000000
+CONFIG_FASTBOOT_USB_DEV=1
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=1
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_I2C=y
 CONFIG_DM_MMC=y
diff --git a/configs/nx25-ae250_defconfig b/configs/ax25-ae350_defconfig
similarity index 78%
rename from configs/nx25-ae250_defconfig
rename to configs/ax25-ae350_defconfig
index 4250775..5a69eb5 100644
--- a/configs/nx25-ae250_defconfig
+++ b/configs/ax25-ae350_defconfig
@@ -1,11 +1,13 @@
 CONFIG_RISCV=y
 CONFIG_SYS_TEXT_BASE=0x00000000
-CONFIG_DEFAULT_DEVICE_TREE="ae250"
-CONFIG_TARGET_NX25_AE250=y
+CONFIG_DEFAULT_DEVICE_TREE="ae350"
+CONFIG_TARGET_AX25_AE350=y
 CONFIG_FIT=y
 CONFIG_BOOTDELAY=3
+CONFIG_BOARD_EARLY_INIT_F=y
 # CONFIG_AUTO_COMPLETE is not set
 CONFIG_SYS_PROMPT="RISC-V # "
+CONFIG_CMD_IMLS=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_SF=y
 CONFIG_CMD_SF_TEST=y
@@ -25,6 +27,9 @@
 CONFIG_DM_MMC=y
 CONFIG_FTSDC010=y
 CONFIG_FTSDC010_SDIO=y
+CONFIG_MTD=y
+CONFIG_MTD_NOR_FLASH=y
+CONFIG_CFI_FLASH=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_MACRONIX=y
@@ -38,3 +43,5 @@
 CONFIG_ATCSPI200_SPI=y
 CONFIG_TIMER=y
 CONFIG_ATCPIT100_TIMER=y
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_CPU_RISCV_64=y
diff --git a/configs/bcm23550_w1d_defconfig b/configs/bcm23550_w1d_defconfig
index 9a986ca..de4fa60 100644
--- a/configs/bcm23550_w1d_defconfig
+++ b/configs/bcm23550_w1d_defconfig
@@ -7,7 +7,7 @@
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_HUSH_PARSER=y
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0x80000000
 CONFIG_FASTBOOT_BUF_SIZE=0x1D000000
 CONFIG_FASTBOOT_FLASH=y
diff --git a/configs/bcm28155_ap_defconfig b/configs/bcm28155_ap_defconfig
index d26cde5..4f7a58e 100644
--- a/configs/bcm28155_ap_defconfig
+++ b/configs/bcm28155_ap_defconfig
@@ -8,7 +8,7 @@
 # CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_HUSH_PARSER=y
 # CONFIG_AUTOBOOT is not set
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0x80000000
 CONFIG_FASTBOOT_BUF_SIZE=0x7FF00000
 CONFIG_FASTBOOT_FLASH=y
diff --git a/configs/birdland_bav335a_defconfig b/configs/birdland_bav335a_defconfig
index 51b3e6b..3efd566 100644
--- a/configs/birdland_bav335a_defconfig
+++ b/configs/birdland_bav335a_defconfig
@@ -25,7 +25,7 @@
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_POWER_SUPPORT=y
 CONFIG_SPL_YMODEM_SUPPORT=y
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0x82000000
 CONFIG_CMD_SPL=y
 CONFIG_CMD_ASKENV=y
diff --git a/configs/birdland_bav335b_defconfig b/configs/birdland_bav335b_defconfig
index 29b223a..2f98116 100644
--- a/configs/birdland_bav335b_defconfig
+++ b/configs/birdland_bav335b_defconfig
@@ -25,7 +25,7 @@
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_POWER_SUPPORT=y
 CONFIG_SPL_YMODEM_SUPPORT=y
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0x82000000
 CONFIG_CMD_SPL=y
 CONFIG_CMD_ASKENV=y
diff --git a/configs/bitmain_antminer_s9_defconfig b/configs/bitmain_antminer_s9_defconfig
new file mode 100644
index 0000000..fc52da0
--- /dev/null
+++ b/configs/bitmain_antminer_s9_defconfig
@@ -0,0 +1,66 @@
+CONFIG_ARM=y
+CONFIG_SYS_VENDOR="bitmain"
+CONFIG_SYS_BOARD="antminer_s9"
+CONFIG_SYS_CONFIG_NAME="bitmain_antminer_s9"
+CONFIG_ARCH_ZYNQ=y
+CONFIG_SYS_TEXT_BASE=0x4000000
+CONFIG_SPL=y
+CONFIG_SPL_STACK_R_ADDR=0x200000
+CONFIG_DEFAULT_DEVICE_TREE="bitmain-antminer-s9"
+CONFIG_DEBUG_UART=y
+CONFIG_FIT=y
+CONFIG_FIT_SIGNATURE=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_BOOTDELAY=3
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_SPL_STACK_R=y
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_PROMPT="antminer> "
+CONFIG_CMD_BOOTZ=y
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_DM is not set
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_FPGA_LOADBP=y
+CONFIG_CMD_FPGA_LOADFS=y
+CONFIG_CMD_FPGA_LOADMK=y
+CONFIG_CMD_FPGA_LOADP=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_NAND_LOCK_UNLOCK=y
+CONFIG_CMD_PART=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_DHCP=y
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_PXE=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_EXT2=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_OF_EMBED=y
+CONFIG_ENV_IS_IN_NAND=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_BOOTCOUNT_LIMIT=y
+CONFIG_SYS_BOOTCOUNT_ADDR=0xEFFFFF0
+CONFIG_FPGA_XILINX=y
+CONFIG_FPGA_ZYNQPL=y
+CONFIG_DM_GPIO=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_ZYNQ=y
+CONFIG_NAND=y
+CONFIG_NAND_ZYNQ=y
+CONFIG_NAND_ZYNQ_USE_BOOTLOADER1_TIMINGS=y
+CONFIG_ZYNQ_GEM=y
+CONFIG_DEBUG_UART_ZYNQ=y
+CONFIG_DEBUG_UART_BASE=0xe0001000
+CONFIG_DEBUG_UART_CLOCK=50000000
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_ZYNQ_SERIAL=y
+# CONFIG_WATCHDOG is not set
+CONFIG_WDT=y
+CONFIG_WDT_CDNS=y
+# CONFIG_EFI_LOADER is not set
diff --git a/configs/cgtqmx6eval_defconfig b/configs/cgtqmx6eval_defconfig
index d4204aa..241e958 100644
--- a/configs/cgtqmx6eval_defconfig
+++ b/configs/cgtqmx6eval_defconfig
@@ -24,7 +24,7 @@
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="CGT-QMX6-Quad U-Boot > "
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0x12000000
 CONFIG_CMD_BOOTZ=y
 CONFIG_CMD_DFU=y
diff --git a/configs/chromebit_mickey_defconfig b/configs/chromebit_mickey_defconfig
index d1728ef..72ecdc6 100644
--- a/configs/chromebit_mickey_defconfig
+++ b/configs/chromebit_mickey_defconfig
@@ -16,8 +16,6 @@
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
 CONFIG_SPL_SPI_LOAD=y
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
@@ -44,6 +42,9 @@
 # CONFIG_SPL_SIMPLE_BUS is not set
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_ROCKCHIP_GPIO=y
 CONFIG_I2C_CROS_EC_TUNNEL=y
 CONFIG_SYS_I2C_ROCKCHIP=y
diff --git a/configs/chromebook_jerry_defconfig b/configs/chromebook_jerry_defconfig
index 43d93f4..fb8400d 100644
--- a/configs/chromebook_jerry_defconfig
+++ b/configs/chromebook_jerry_defconfig
@@ -18,8 +18,6 @@
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
 CONFIG_SPL_SPI_LOAD=y
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
@@ -46,6 +44,9 @@
 # CONFIG_SPL_SIMPLE_BUS is not set
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_ROCKCHIP_GPIO=y
 CONFIG_I2C_CROS_EC_TUNNEL=y
 CONFIG_SYS_I2C_ROCKCHIP=y
diff --git a/configs/chromebook_minnie_defconfig b/configs/chromebook_minnie_defconfig
index 706809c..a8776c9 100644
--- a/configs/chromebook_minnie_defconfig
+++ b/configs/chromebook_minnie_defconfig
@@ -17,8 +17,6 @@
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
 CONFIG_SPL_SPI_LOAD=y
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
@@ -45,6 +43,9 @@
 # CONFIG_SPL_SIMPLE_BUS is not set
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_ROCKCHIP_GPIO=y
 CONFIG_I2C_CROS_EC_TUNNEL=y
 CONFIG_SYS_I2C_ROCKCHIP=y
diff --git a/configs/d2net_v2_defconfig b/configs/d2net_v2_defconfig
index 72db1e7..d054c21 100644
--- a/configs/d2net_v2_defconfig
+++ b/configs/d2net_v2_defconfig
@@ -3,6 +3,7 @@
 CONFIG_SYS_TEXT_BASE=0x600000
 CONFIG_TARGET_NET2BIG_V2=y
 CONFIG_IDENT_STRING=" D2 v2"
+CONFIG_DEFAULT_DEVICE_TREE="kirkwood-d2net"
 CONFIG_SYS_EXTRA_OPTIONS="D2NET_V2"
 CONFIG_BOOTDELAY=3
 CONFIG_USE_BOOTARGS=y
@@ -26,6 +27,7 @@
 CONFIG_ISO_PARTITION=y
 CONFIG_EFI_PARTITION=y
 # CONFIG_PARTITION_UUIDS is not set
+CONFIG_OF_CONTROL=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_MVSATA_IDE=y
 # CONFIG_MMC is not set
@@ -39,4 +41,3 @@
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_STORAGE=y
-CONFIG_OF_LIBFDT=y
diff --git a/configs/dra7xx_evm_defconfig b/configs/dra7xx_evm_defconfig
index 9b81b0c..182f9a9 100644
--- a/configs/dra7xx_evm_defconfig
+++ b/configs/dra7xx_evm_defconfig
@@ -25,11 +25,6 @@
 CONFIG_SPL_DMA_SUPPORT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_SPI_LOAD=y
-CONFIG_FASTBOOT=y
-CONFIG_FASTBOOT_BUF_ADDR=0x82000000
-CONFIG_FASTBOOT_BUF_SIZE=0x2F000000
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=1
 CONFIG_CMD_SPL=y
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_SETEXPR is not set
@@ -50,6 +45,12 @@
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
 CONFIG_DFU_SF=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_BUF_ADDR=0x82000000
+CONFIG_FASTBOOT_BUF_SIZE=0x2F000000
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=1
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_DM_GPIO=y
 CONFIG_PCF8575_GPIO=y
 CONFIG_DM_I2C=y
diff --git a/configs/dra7xx_hs_evm_defconfig b/configs/dra7xx_hs_evm_defconfig
index 536946e..8584d41 100644
--- a/configs/dra7xx_hs_evm_defconfig
+++ b/configs/dra7xx_hs_evm_defconfig
@@ -30,11 +30,6 @@
 CONFIG_SPL_SEPARATE_BSS=y
 CONFIG_SPL_DMA_SUPPORT=y
 CONFIG_SPL_SPI_LOAD=y
-CONFIG_FASTBOOT=y
-CONFIG_FASTBOOT_BUF_ADDR=0x82000000
-CONFIG_FASTBOOT_BUF_SIZE=0x2F000000
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=1
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_OF_CONTROL=y
@@ -50,6 +45,12 @@
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
 CONFIG_DFU_SF=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_BUF_ADDR=0x82000000
+CONFIG_FASTBOOT_BUF_SIZE=0x2F000000
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=1
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_DM_GPIO=y
 CONFIG_PCF8575_GPIO=y
 CONFIG_DM_I2C=y
diff --git a/configs/dragonboard410c_defconfig b/configs/dragonboard410c_defconfig
index e6114db..4b3de64 100644
--- a/configs/dragonboard410c_defconfig
+++ b/configs/dragonboard410c_defconfig
@@ -45,3 +45,8 @@
 CONFIG_USB_ETHER_MCS7830=y
 CONFIG_USB_ETHER_SMSC95XX=y
 CONFIG_OF_LIBFDT_OVERLAY=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_FULL=y
+CONFIG_PINCTRL_GENERIC=y
+CONFIG_PINMUX=y
+CONFIG_PINCONF=y
diff --git a/configs/dreamplug_defconfig b/configs/dreamplug_defconfig
index cbd2fb6..8090c9a 100644
--- a/configs/dreamplug_defconfig
+++ b/configs/dreamplug_defconfig
@@ -3,6 +3,7 @@
 CONFIG_SYS_TEXT_BASE=0x600000
 CONFIG_TARGET_DREAMPLUG=y
 CONFIG_IDENT_STRING="\nMarvell-DreamPlug"
+CONFIG_DEFAULT_DEVICE_TREE="kirkwood-dreamplug"
 CONFIG_BOOTDELAY=3
 # CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_HUSH_PARSER=y
@@ -19,6 +20,7 @@
 CONFIG_CMD_EXT4=y
 CONFIG_CMD_FAT=y
 CONFIG_ISO_PARTITION=y
+CONFIG_OF_CONTROL=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_MVSATA_IDE=y
 # CONFIG_MMC is not set
@@ -32,4 +34,3 @@
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_STORAGE=y
-CONFIG_OF_LIBFDT=y
diff --git a/configs/ds109_defconfig b/configs/ds109_defconfig
index 43e92d7..c920743 100644
--- a/configs/ds109_defconfig
+++ b/configs/ds109_defconfig
@@ -2,6 +2,7 @@
 CONFIG_KIRKWOOD=y
 CONFIG_SYS_TEXT_BASE=0x600000
 CONFIG_TARGET_DS109=y
+CONFIG_DEFAULT_DEVICE_TREE="kirkwood-ds109"
 CONFIG_HUSH_PARSER=y
 # CONFIG_CMD_FLASH is not set
 CONFIG_CMD_IDE=y
@@ -14,6 +15,7 @@
 CONFIG_CMD_DATE=y
 CONFIG_CMD_FAT=y
 CONFIG_ISO_PARTITION=y
+CONFIG_OF_CONTROL=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_MVSATA_IDE=y
 # CONFIG_MMC is not set
diff --git a/configs/emdk_defconfig b/configs/emdk_defconfig
new file mode 100644
index 0000000..e3bccd2
--- /dev/null
+++ b/configs/emdk_defconfig
@@ -0,0 +1,31 @@
+CONFIG_ARC=y
+CONFIG_ISA_ARCV2=y
+CONFIG_CPU_ARCEM6=y
+CONFIG_TARGET_EMDK=y
+CONFIG_SYS_TEXT_BASE=0x00000000
+CONFIG_SYS_CLK_FREQ=40000000
+CONFIG_DEFAULT_DEVICE_TREE="emdk"
+# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
+CONFIG_VERSION_VARIABLE=y
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_PROMPT="emdk# "
+# CONFIG_CMD_BOOTD is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_XIMG is not set
+CONFIG_CMD_MMC=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_FAT=y
+CONFIG_OF_CONTROL=y
+CONFIG_OF_EMBED=y
+CONFIG_ENV_IS_IN_FAT=y
+CONFIG_ENV_FAT_INTERFACE="mmc"
+CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
+# CONFIG_NET is not set
+CONFIG_DM=y
+CONFIG_MMC=y
+CONFIG_MMC_DW=y
+CONFIG_DM_SERIAL=y
+CONFIG_SYS_NS16550=y
+CONFIG_FS_FAT_MAX_CLUSTSIZE=4096
+CONFIG_USE_PRIVATE_LIBGCC=y
+CONFIG_PANIC_HANG=y
diff --git a/configs/evb-rk3036_defconfig b/configs/evb-rk3036_defconfig
index 33775e8..b9242e8 100644
--- a/configs/evb-rk3036_defconfig
+++ b/configs/evb-rk3036_defconfig
@@ -15,8 +15,6 @@
 CONFIG_DISPLAY_BOARDINFO_LATE=y
 # CONFIG_SPL_FRAMEWORK is not set
 CONFIG_SPL_STACK_R=y
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
@@ -31,6 +29,9 @@
 CONFIG_REGMAP=y
 CONFIG_SYSCON=y
 CONFIG_CLK=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_ROCKCHIP_GPIO=y
 CONFIG_SYS_I2C_ROCKCHIP=y
 CONFIG_LED=y
diff --git a/configs/evb-rk3128_defconfig b/configs/evb-rk3128_defconfig
index 796d0ec..9c8252e 100644
--- a/configs/evb-rk3128_defconfig
+++ b/configs/evb-rk3128_defconfig
@@ -7,10 +7,6 @@
 CONFIG_FIT=y
 # CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_DISPLAY_BOARDINFO_LATE=y
-CONFIG_FASTBOOT_BUF_ADDR=0x60800800
-CONFIG_FASTBOOT_BUF_SIZE=0x04000000
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_CMD_GPT=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_USB=y
@@ -20,6 +16,11 @@
 CONFIG_REGMAP=y
 CONFIG_SYSCON=y
 CONFIG_CLK=y
+CONFIG_FASTBOOT_BUF_ADDR=0x60800800
+CONFIG_FASTBOOT_BUF_SIZE=0x04000000
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_ROCKCHIP_GPIO=y
 CONFIG_SYS_I2C_ROCKCHIP=y
 CONFIG_MMC_DW=y
diff --git a/configs/evb-rk3229_defconfig b/configs/evb-rk3229_defconfig
index 710b0b4..7298bf1 100644
--- a/configs/evb-rk3229_defconfig
+++ b/configs/evb-rk3229_defconfig
@@ -14,8 +14,6 @@
 CONFIG_DISPLAY_BOARDINFO_LATE=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x200
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_CMD_GPT=y
 CONFIG_CMD_MMC=y
 # CONFIG_CMD_SETEXPR is not set
@@ -30,6 +28,9 @@
 CONFIG_SPL_SYSCON=y
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_ROCKCHIP_GPIO=y
 CONFIG_SYS_I2C_ROCKCHIP=y
 CONFIG_MMC_DW=y
diff --git a/configs/evb-rk3288_defconfig b/configs/evb-rk3288_defconfig
index 7695277..a7beaa6 100644
--- a/configs/evb-rk3288_defconfig
+++ b/configs/evb-rk3288_defconfig
@@ -14,8 +14,6 @@
 CONFIG_DISPLAY_BOARDINFO_LATE=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
@@ -41,6 +39,9 @@
 CONFIG_SPL_SYSCON=y
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_ROCKCHIP_GPIO=y
 CONFIG_SYS_I2C_ROCKCHIP=y
 CONFIG_LED=y
diff --git a/configs/evb-rk3328_defconfig b/configs/evb-rk3328_defconfig
index 78ae24b..59bf9e5 100644
--- a/configs/evb-rk3328_defconfig
+++ b/configs/evb-rk3328_defconfig
@@ -8,9 +8,6 @@
 CONFIG_FIT=y
 # CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_DISPLAY_BOARDINFO_LATE=y
-CONFIG_FASTBOOT_BUF_ADDR=0x800800
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=1
 CONFIG_CMD_BOOTZ=y
 CONFIG_CMD_GPT=y
 CONFIG_CMD_MMC=y
@@ -23,6 +20,10 @@
 CONFIG_REGMAP=y
 CONFIG_SYSCON=y
 CONFIG_CLK=y
+CONFIG_FASTBOOT_BUF_ADDR=0x800800
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=1
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_ROCKCHIP_GPIO=y
 CONFIG_SYS_I2C_ROCKCHIP=y
 CONFIG_MMC_DW=y
diff --git a/configs/fennec-rk3288_defconfig b/configs/fennec-rk3288_defconfig
index efdd583..dbd6be5 100644
--- a/configs/fennec-rk3288_defconfig
+++ b/configs/fennec-rk3288_defconfig
@@ -15,8 +15,6 @@
 CONFIG_DISPLAY_BOARDINFO_LATE=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
@@ -42,6 +40,9 @@
 # CONFIG_SPL_SIMPLE_BUS is not set
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_ROCKCHIP_GPIO=y
 CONFIG_SYS_I2C_ROCKCHIP=y
 CONFIG_MMC_DW=y
diff --git a/configs/firefly-rk3288_defconfig b/configs/firefly-rk3288_defconfig
index b252d27..83b4968 100644
--- a/configs/firefly-rk3288_defconfig
+++ b/configs/firefly-rk3288_defconfig
@@ -14,8 +14,6 @@
 CONFIG_DISPLAY_BOARDINFO_LATE=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
@@ -42,6 +40,9 @@
 # CONFIG_SPL_SIMPLE_BUS is not set
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_ROCKCHIP_GPIO=y
 CONFIG_SYS_I2C_ROCKCHIP=y
 CONFIG_DM_KEYBOARD=y
diff --git a/configs/gose_defconfig b/configs/gose_defconfig
index 8479887..4b8c5a4 100644
--- a/configs/gose_defconfig
+++ b/configs/gose_defconfig
@@ -46,6 +46,9 @@
 CONFIG_CMD_EXT4=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
+CONFIG_CMD_MTDPARTS=y
+CONFIG_MTDIDS_DEFAULT="nor0=spi0.0"
+CONFIG_MTDPARTS_DEFAULT="mtdparts=spi0.0:256k(u-boot-spl),512k(u-boot-env1),512k(u-boot-env2),768k(u-boot),-(user)"
 CONFIG_OF_CONTROL=y
 CONFIG_OF_EMBED=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
@@ -57,9 +60,11 @@
 CONFIG_SYS_I2C_RCAR_IIC=y
 CONFIG_DM_MMC=y
 CONFIG_RENESAS_SDHI=y
+CONFIG_MTD=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y
 CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_MTD=y
 CONFIG_PHY_MICREL=y
 CONFIG_DM_ETH=y
 CONFIG_SH_ETHER=y
diff --git a/configs/imx6dl_mamoj_defconfig b/configs/imx6dl_mamoj_defconfig
index 0001457..40a128b 100644
--- a/configs/imx6dl_mamoj_defconfig
+++ b/configs/imx6dl_mamoj_defconfig
@@ -9,7 +9,7 @@
 CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg"
 CONFIG_BOOTDELAY=3
 CONFIG_HUSH_PARSER=y
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0x12000000
 CONFIG_FASTBOOT_BUF_SIZE=0x10000000
 CONFIG_FASTBOOT_FLASH=y
diff --git a/configs/inetspace_v2_defconfig b/configs/inetspace_v2_defconfig
index 9f8677b..2fb7209 100644
--- a/configs/inetspace_v2_defconfig
+++ b/configs/inetspace_v2_defconfig
@@ -3,6 +3,7 @@
 CONFIG_SYS_TEXT_BASE=0x600000
 CONFIG_TARGET_NETSPACE_V2=y
 CONFIG_IDENT_STRING=" IS v2"
+CONFIG_DEFAULT_DEVICE_TREE="kirkwood-is2"
 CONFIG_SYS_EXTRA_OPTIONS="INETSPACE_V2"
 CONFIG_BOOTDELAY=3
 CONFIG_USE_BOOTARGS=y
@@ -26,6 +27,7 @@
 CONFIG_ISO_PARTITION=y
 CONFIG_EFI_PARTITION=y
 # CONFIG_PARTITION_UUIDS is not set
+CONFIG_OF_CONTROL=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_MVSATA_IDE=y
 # CONFIG_MMC is not set
@@ -39,4 +41,3 @@
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_STORAGE=y
-CONFIG_OF_LIBFDT=y
diff --git a/configs/kc1_defconfig b/configs/kc1_defconfig
index 534d604..ce71e37 100644
--- a/configs/kc1_defconfig
+++ b/configs/kc1_defconfig
@@ -12,7 +12,7 @@
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=2
 CONFIG_SYS_PROMPT="kc1 # "
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0x82000000
 CONFIG_FASTBOOT_BUF_SIZE=0x2000000
 CONFIG_FASTBOOT_FLASH=y
diff --git a/configs/km_kirkwood_128m16_defconfig b/configs/km_kirkwood_128m16_defconfig
index 5d5b485..e41ec89 100644
--- a/configs/km_kirkwood_128m16_defconfig
+++ b/configs/km_kirkwood_128m16_defconfig
@@ -3,6 +3,7 @@
 CONFIG_SYS_TEXT_BASE=0x07d00000
 CONFIG_TARGET_KM_KIRKWOOD=y
 CONFIG_IDENT_STRING="\nKeymile Kirkwood 128M16"
+CONFIG_DEFAULT_DEVICE_TREE="kirkwood-km_kirkwood"
 CONFIG_SYS_EXTRA_OPTIONS="KM_KIRKWOOD_128M16"
 CONFIG_VERSION_VARIABLE=y
 # CONFIG_DISPLAY_BOARDINFO is not set
@@ -25,6 +26,7 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=orion_nand:-(ubi0);"
 CONFIG_CMD_UBI=y
 # CONFIG_CMD_UBIFS is not set
+CONFIG_OF_CONTROL=y
 CONFIG_ENV_IS_IN_EEPROM=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_RAM=y
@@ -37,4 +39,3 @@
 CONFIG_SPI=y
 CONFIG_KIRKWOOD_SPI=y
 CONFIG_BCH=y
-CONFIG_OF_LIBFDT=y
diff --git a/configs/km_kirkwood_defconfig b/configs/km_kirkwood_defconfig
index b07f36b..fcab051 100644
--- a/configs/km_kirkwood_defconfig
+++ b/configs/km_kirkwood_defconfig
@@ -3,6 +3,7 @@
 CONFIG_SYS_TEXT_BASE=0x07d00000
 CONFIG_TARGET_KM_KIRKWOOD=y
 CONFIG_IDENT_STRING="\nKeymile Kirkwood"
+CONFIG_DEFAULT_DEVICE_TREE="kirkwood-km_kirkwood"
 CONFIG_SYS_EXTRA_OPTIONS="KM_KIRKWOOD"
 CONFIG_VERSION_VARIABLE=y
 # CONFIG_DISPLAY_BOARDINFO is not set
@@ -25,6 +26,7 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=orion_nand:-(ubi0);"
 CONFIG_CMD_UBI=y
 # CONFIG_CMD_UBIFS is not set
+CONFIG_OF_CONTROL=y
 CONFIG_ENV_IS_IN_EEPROM=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_RAM=y
@@ -37,4 +39,3 @@
 CONFIG_SPI=y
 CONFIG_KIRKWOOD_SPI=y
 CONFIG_BCH=y
-CONFIG_OF_LIBFDT=y
diff --git a/configs/km_kirkwood_pci_defconfig b/configs/km_kirkwood_pci_defconfig
index 31dcd0c..4fc83a5 100644
--- a/configs/km_kirkwood_pci_defconfig
+++ b/configs/km_kirkwood_pci_defconfig
@@ -3,6 +3,7 @@
 CONFIG_SYS_TEXT_BASE=0x07d00000
 CONFIG_TARGET_KM_KIRKWOOD=y
 CONFIG_IDENT_STRING="\nKeymile Kirkwood PCI"
+CONFIG_DEFAULT_DEVICE_TREE="kirkwood-km_kirkwood"
 CONFIG_SYS_EXTRA_OPTIONS="KM_KIRKWOOD_PCI"
 CONFIG_VERSION_VARIABLE=y
 # CONFIG_DISPLAY_BOARDINFO is not set
@@ -25,6 +26,7 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=orion_nand:-(ubi0);"
 CONFIG_CMD_UBI=y
 # CONFIG_CMD_UBIFS is not set
+CONFIG_OF_CONTROL=y
 CONFIG_ENV_IS_IN_EEPROM=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_RAM=y
@@ -37,4 +39,3 @@
 CONFIG_SPI=y
 CONFIG_KIRKWOOD_SPI=y
 CONFIG_BCH=y
-CONFIG_OF_LIBFDT=y
diff --git a/configs/kmcoge5un_defconfig b/configs/kmcoge5un_defconfig
index 116369a..4b1edb4 100644
--- a/configs/kmcoge5un_defconfig
+++ b/configs/kmcoge5un_defconfig
@@ -3,6 +3,7 @@
 CONFIG_SYS_TEXT_BASE=0x07d00000
 CONFIG_TARGET_KM_KIRKWOOD=y
 CONFIG_IDENT_STRING="\nKeymile COGE5UN"
+CONFIG_DEFAULT_DEVICE_TREE="kirkwood-km_kirkwood"
 CONFIG_SYS_EXTRA_OPTIONS="KM_COGE5UN"
 CONFIG_VERSION_VARIABLE=y
 # CONFIG_DISPLAY_BOARDINFO is not set
@@ -25,6 +26,7 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=orion_nand:-(ubi0);"
 CONFIG_CMD_UBI=y
 # CONFIG_CMD_UBIFS is not set
+CONFIG_OF_CONTROL=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_RAM=y
@@ -37,4 +39,3 @@
 CONFIG_SPI=y
 CONFIG_KIRKWOOD_SPI=y
 CONFIG_BCH=y
-CONFIG_OF_LIBFDT=y
diff --git a/configs/kmnusa_defconfig b/configs/kmnusa_defconfig
index be7421c..90d9a55 100644
--- a/configs/kmnusa_defconfig
+++ b/configs/kmnusa_defconfig
@@ -3,6 +3,7 @@
 CONFIG_SYS_TEXT_BASE=0x07d00000
 CONFIG_TARGET_KM_KIRKWOOD=y
 CONFIG_IDENT_STRING="\nKeymile NUSA"
+CONFIG_DEFAULT_DEVICE_TREE="kirkwood-km_kirkwood"
 CONFIG_SYS_EXTRA_OPTIONS="KM_NUSA"
 CONFIG_VERSION_VARIABLE=y
 # CONFIG_DISPLAY_BOARDINFO is not set
@@ -25,6 +26,7 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=orion_nand:-(ubi0);"
 CONFIG_CMD_UBI=y
 # CONFIG_CMD_UBIFS is not set
+CONFIG_OF_CONTROL=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_RAM=y
@@ -37,4 +39,3 @@
 CONFIG_SPI=y
 CONFIG_KIRKWOOD_SPI=y
 CONFIG_BCH=y
-CONFIG_OF_LIBFDT=y
diff --git a/configs/kmsugp1_defconfig b/configs/kmsugp1_defconfig
index 535e869..132db20 100644
--- a/configs/kmsugp1_defconfig
+++ b/configs/kmsugp1_defconfig
@@ -3,6 +3,7 @@
 CONFIG_SYS_TEXT_BASE=0x07d00000
 CONFIG_TARGET_KM_KIRKWOOD=y
 CONFIG_IDENT_STRING="\nKeymile SUGP1"
+CONFIG_DEFAULT_DEVICE_TREE="kirkwood-km_kirkwood"
 CONFIG_SYS_EXTRA_OPTIONS="KM_SUGP1"
 CONFIG_VERSION_VARIABLE=y
 # CONFIG_DISPLAY_BOARDINFO is not set
@@ -25,6 +26,7 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=orion_nand:-(ubi0);"
 CONFIG_CMD_UBI=y
 # CONFIG_CMD_UBIFS is not set
+CONFIG_OF_CONTROL=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_RAM=y
@@ -37,4 +39,3 @@
 CONFIG_SPI=y
 CONFIG_KIRKWOOD_SPI=y
 CONFIG_BCH=y
-CONFIG_OF_LIBFDT=y
diff --git a/configs/kmsuv31_defconfig b/configs/kmsuv31_defconfig
index 59522e7..7b5b016 100644
--- a/configs/kmsuv31_defconfig
+++ b/configs/kmsuv31_defconfig
@@ -3,6 +3,7 @@
 CONFIG_SYS_TEXT_BASE=0x07d00000
 CONFIG_TARGET_KM_KIRKWOOD=y
 CONFIG_IDENT_STRING="\nKeymile SUV31"
+CONFIG_DEFAULT_DEVICE_TREE="kirkwood-km_kirkwood"
 CONFIG_SYS_EXTRA_OPTIONS="KM_SUV31"
 CONFIG_VERSION_VARIABLE=y
 # CONFIG_DISPLAY_BOARDINFO is not set
@@ -25,6 +26,7 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=orion_nand:-(ubi0);"
 CONFIG_CMD_UBI=y
 # CONFIG_CMD_UBIFS is not set
+CONFIG_OF_CONTROL=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_RAM=y
@@ -37,4 +39,3 @@
 CONFIG_SPI=y
 CONFIG_KIRKWOOD_SPI=y
 CONFIG_BCH=y
-CONFIG_OF_LIBFDT=y
diff --git a/configs/koelsch_defconfig b/configs/koelsch_defconfig
index faca596..39d5805 100644
--- a/configs/koelsch_defconfig
+++ b/configs/koelsch_defconfig
@@ -46,6 +46,9 @@
 CONFIG_CMD_EXT4=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
+CONFIG_CMD_MTDPARTS=y
+CONFIG_MTDIDS_DEFAULT="nor0=spi0.0"
+CONFIG_MTDPARTS_DEFAULT="mtdparts=spi0.0:256k(u-boot-spl),512k(u-boot-env1),512k(u-boot-env2),768k(u-boot),-(user)"
 CONFIG_OF_CONTROL=y
 CONFIG_OF_EMBED=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
@@ -57,9 +60,11 @@
 CONFIG_SYS_I2C_RCAR_IIC=y
 CONFIG_DM_MMC=y
 CONFIG_RENESAS_SDHI=y
+CONFIG_MTD=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y
 CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_MTD=y
 CONFIG_PHY_MICREL=y
 CONFIG_DM_ETH=y
 CONFIG_SH_ETHER=y
diff --git a/configs/kylin-rk3036_defconfig b/configs/kylin-rk3036_defconfig
index ca53005..373764a 100644
--- a/configs/kylin-rk3036_defconfig
+++ b/configs/kylin-rk3036_defconfig
@@ -14,8 +14,6 @@
 CONFIG_DISPLAY_BOARDINFO_LATE=y
 # CONFIG_SPL_FRAMEWORK is not set
 CONFIG_SPL_STACK_R=y
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
@@ -31,6 +29,9 @@
 CONFIG_REGMAP=y
 CONFIG_SYSCON=y
 CONFIG_CLK=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_ROCKCHIP_GPIO=y
 CONFIG_SYS_I2C_ROCKCHIP=y
 CONFIG_LED=y
diff --git a/configs/lager_defconfig b/configs/lager_defconfig
index 70083bc..0eaf33d 100644
--- a/configs/lager_defconfig
+++ b/configs/lager_defconfig
@@ -46,6 +46,9 @@
 CONFIG_CMD_EXT4=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
+CONFIG_CMD_MTDPARTS=y
+CONFIG_MTDIDS_DEFAULT="nor0=spi0.0"
+CONFIG_MTDPARTS_DEFAULT="mtdparts=spi0.0:256k(u-boot-spl),512k(u-boot-env1),512k(u-boot-env2),768k(u-boot),-(user)"
 CONFIG_OF_CONTROL=y
 CONFIG_OF_EMBED=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
@@ -59,9 +62,11 @@
 CONFIG_DM_MMC=y
 CONFIG_SH_MMCIF=y
 CONFIG_RENESAS_SDHI=y
+CONFIG_MTD=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y
 CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_MTD=y
 CONFIG_PHY_MICREL=y
 CONFIG_DM_ETH=y
 CONFIG_SH_ETHER=y
diff --git a/configs/lschlv2_defconfig b/configs/lschlv2_defconfig
index 1ca3d12..23e68a0 100644
--- a/configs/lschlv2_defconfig
+++ b/configs/lschlv2_defconfig
@@ -3,6 +3,7 @@
 CONFIG_SYS_TEXT_BASE=0x600000
 CONFIG_TARGET_LSXL=y
 CONFIG_IDENT_STRING=" LS-CHLv2"
+CONFIG_DEFAULT_DEVICE_TREE="kirkwood-lschlv2"
 CONFIG_SYS_EXTRA_OPTIONS="LSCHLV2"
 CONFIG_BOOTDELAY=3
 CONFIG_USE_BOOTARGS=y
@@ -28,6 +29,7 @@
 CONFIG_ISO_PARTITION=y
 CONFIG_EFI_PARTITION=y
 # CONFIG_PARTITION_UUIDS is not set
+CONFIG_OF_CONTROL=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_MVSATA_IDE=y
@@ -42,4 +44,3 @@
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_STORAGE=y
-CONFIG_OF_LIBFDT=y
diff --git a/configs/lsxhl_defconfig b/configs/lsxhl_defconfig
index c88fe37..b523b68 100644
--- a/configs/lsxhl_defconfig
+++ b/configs/lsxhl_defconfig
@@ -3,6 +3,7 @@
 CONFIG_SYS_TEXT_BASE=0x600000
 CONFIG_TARGET_LSXL=y
 CONFIG_IDENT_STRING=" LS-XHL"
+CONFIG_DEFAULT_DEVICE_TREE="kirkwood-lsxhl"
 CONFIG_DISTRO_DEFAULTS=y
 CONFIG_SYS_EXTRA_OPTIONS="LSXHL"
 CONFIG_API=y
@@ -19,6 +20,7 @@
 CONFIG_CMD_SPI=y
 CONFIG_CMD_USB=y
 # CONFIG_CMD_SETEXPR is not set
+CONFIG_OF_CONTROL=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_MVSATA_IDE=y
@@ -33,4 +35,3 @@
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_STORAGE=y
-CONFIG_OF_LIBFDT=y
diff --git a/configs/mgcoge3un_defconfig b/configs/mgcoge3un_defconfig
index abf9cdc..baee230 100644
--- a/configs/mgcoge3un_defconfig
+++ b/configs/mgcoge3un_defconfig
@@ -3,6 +3,7 @@
 CONFIG_SYS_TEXT_BASE=0x07d00000
 CONFIG_TARGET_KM_KIRKWOOD=y
 CONFIG_IDENT_STRING="\nKeymile COGE3UN"
+CONFIG_DEFAULT_DEVICE_TREE="kirkwood-km_kirkwood"
 CONFIG_SYS_EXTRA_OPTIONS="KM_MGCOGE3UN"
 CONFIG_VERSION_VARIABLE=y
 # CONFIG_DISPLAY_BOARDINFO is not set
@@ -25,6 +26,7 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=orion_nand:-(ubi0);"
 CONFIG_CMD_UBI=y
 # CONFIG_CMD_UBIFS is not set
+CONFIG_OF_CONTROL=y
 CONFIG_ENV_IS_IN_EEPROM=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_BOOTCOUNT_RAM=y
@@ -37,4 +39,3 @@
 CONFIG_SPI=y
 CONFIG_KIRKWOOD_SPI=y
 CONFIG_BCH=y
-CONFIG_OF_LIBFDT=y
diff --git a/configs/miqi-rk3288_defconfig b/configs/miqi-rk3288_defconfig
index f44537c..5bfcb0c 100644
--- a/configs/miqi-rk3288_defconfig
+++ b/configs/miqi-rk3288_defconfig
@@ -14,8 +14,6 @@
 CONFIG_DISPLAY_BOARDINFO_LATE=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
@@ -42,6 +40,9 @@
 # CONFIG_SPL_SIMPLE_BUS is not set
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_ROCKCHIP_GPIO=y
 CONFIG_SYS_I2C_ROCKCHIP=y
 CONFIG_MMC_DW=y
diff --git a/configs/mvebu_db-88f3720_defconfig b/configs/mvebu_db-88f3720_defconfig
index e6f7cb9..4ba287f 100644
--- a/configs/mvebu_db-88f3720_defconfig
+++ b/configs/mvebu_db-88f3720_defconfig
@@ -30,7 +30,7 @@
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_MAC_PARTITION=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
-CONFIG_SCSI_AHCI=y
+CONFIG_AHCI_MVEBU=y
 CONFIG_BLOCK_CACHE=y
 CONFIG_DM_GPIO=y
 # CONFIG_MVEBU_GPIO is not set
diff --git a/configs/mvebu_db_armada8k_defconfig b/configs/mvebu_db_armada8k_defconfig
index 63f2103..b7694ec 100644
--- a/configs/mvebu_db_armada8k_defconfig
+++ b/configs/mvebu_db_armada8k_defconfig
@@ -30,7 +30,7 @@
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_MAC_PARTITION=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
-CONFIG_SCSI_AHCI=y
+CONFIG_AHCI_MVEBU=y
 CONFIG_BLOCK_CACHE=y
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_MVTWSI=y
diff --git a/configs/mvebu_espressobin-88f3720_defconfig b/configs/mvebu_espressobin-88f3720_defconfig
index 5a6d1e6..db11e51 100644
--- a/configs/mvebu_espressobin-88f3720_defconfig
+++ b/configs/mvebu_espressobin-88f3720_defconfig
@@ -30,7 +30,7 @@
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_MAC_PARTITION=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
-CONFIG_SCSI_AHCI=y
+CONFIG_AHCI_MVEBU=y
 CONFIG_BLOCK_CACHE=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_I2C=y
diff --git a/configs/mvebu_mcbin-88f8040_defconfig b/configs/mvebu_mcbin-88f8040_defconfig
index de682d1..545bb4f 100644
--- a/configs/mvebu_mcbin-88f8040_defconfig
+++ b/configs/mvebu_mcbin-88f8040_defconfig
@@ -32,7 +32,7 @@
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_MAC_PARTITION=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
-CONFIG_SCSI_AHCI=y
+CONFIG_AHCI_MVEBU=y
 CONFIG_BLOCK_CACHE=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_I2C=y
diff --git a/configs/mx6qsabrelite_defconfig b/configs/mx6qsabrelite_defconfig
index 966e823..a4740d4 100644
--- a/configs/mx6qsabrelite_defconfig
+++ b/configs/mx6qsabrelite_defconfig
@@ -9,7 +9,7 @@
 # CONFIG_USE_BOOTCOMMAND is not set
 CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE=y
 CONFIG_BOARD_EARLY_INIT_F=y
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0x12000000
 CONFIG_CMD_MEMTEST=y
 CONFIG_SYS_ALT_MEMTEST=y
diff --git a/configs/mx6sabresd_defconfig b/configs/mx6sabresd_defconfig
index ca37d8b..5c8e9de 100644
--- a/configs/mx6sabresd_defconfig
+++ b/configs/mx6sabresd_defconfig
@@ -22,7 +22,7 @@
 CONFIG_SPL_USB_GADGET_SUPPORT=y
 CONFIG_SPL_USB_SDP_SUPPORT=y
 CONFIG_HUSH_PARSER=y
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0x12000000
 CONFIG_FASTBOOT_BUF_SIZE=0x10000000
 CONFIG_FASTBOOT_FLASH=y
diff --git a/configs/net2big_v2_defconfig b/configs/net2big_v2_defconfig
index d486e4c..e721655 100644
--- a/configs/net2big_v2_defconfig
+++ b/configs/net2big_v2_defconfig
@@ -3,6 +3,7 @@
 CONFIG_SYS_TEXT_BASE=0x600000
 CONFIG_TARGET_NET2BIG_V2=y
 CONFIG_IDENT_STRING=" 2Big v2"
+CONFIG_DEFAULT_DEVICE_TREE="kirkwood-net2big"
 CONFIG_SYS_EXTRA_OPTIONS="NET2BIG_V2"
 CONFIG_BOOTDELAY=3
 CONFIG_USE_BOOTARGS=y
@@ -26,6 +27,7 @@
 CONFIG_ISO_PARTITION=y
 CONFIG_EFI_PARTITION=y
 # CONFIG_PARTITION_UUIDS is not set
+CONFIG_OF_CONTROL=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_MVSATA_IDE=y
 # CONFIG_MMC is not set
@@ -39,4 +41,3 @@
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_STORAGE=y
-CONFIG_OF_LIBFDT=y
diff --git a/configs/netspace_lite_v2_defconfig b/configs/netspace_lite_v2_defconfig
index d37146d..c0e3651 100644
--- a/configs/netspace_lite_v2_defconfig
+++ b/configs/netspace_lite_v2_defconfig
@@ -3,6 +3,7 @@
 CONFIG_SYS_TEXT_BASE=0x600000
 CONFIG_TARGET_NETSPACE_V2=y
 CONFIG_IDENT_STRING=" NS v2 Lite"
+CONFIG_DEFAULT_DEVICE_TREE="kirkwood-ns2lite"
 CONFIG_SYS_EXTRA_OPTIONS="NETSPACE_LITE_V2"
 CONFIG_BOOTDELAY=3
 CONFIG_USE_BOOTARGS=y
@@ -26,6 +27,7 @@
 CONFIG_ISO_PARTITION=y
 CONFIG_EFI_PARTITION=y
 # CONFIG_PARTITION_UUIDS is not set
+CONFIG_OF_CONTROL=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_MVSATA_IDE=y
 # CONFIG_MMC is not set
@@ -39,4 +41,3 @@
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_STORAGE=y
-CONFIG_OF_LIBFDT=y
diff --git a/configs/netspace_max_v2_defconfig b/configs/netspace_max_v2_defconfig
index 9b639c0..db75e6d 100644
--- a/configs/netspace_max_v2_defconfig
+++ b/configs/netspace_max_v2_defconfig
@@ -3,6 +3,7 @@
 CONFIG_SYS_TEXT_BASE=0x600000
 CONFIG_TARGET_NETSPACE_V2=y
 CONFIG_IDENT_STRING=" NS Max v2"
+CONFIG_DEFAULT_DEVICE_TREE="kirkwood-ns2max"
 CONFIG_SYS_EXTRA_OPTIONS="NETSPACE_MAX_V2"
 CONFIG_BOOTDELAY=3
 CONFIG_USE_BOOTARGS=y
@@ -26,6 +27,7 @@
 CONFIG_ISO_PARTITION=y
 CONFIG_EFI_PARTITION=y
 # CONFIG_PARTITION_UUIDS is not set
+CONFIG_OF_CONTROL=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_MVSATA_IDE=y
 # CONFIG_MMC is not set
@@ -39,4 +41,3 @@
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_STORAGE=y
-CONFIG_OF_LIBFDT=y
diff --git a/configs/netspace_mini_v2_defconfig b/configs/netspace_mini_v2_defconfig
index ee7554f..fd774c7 100644
--- a/configs/netspace_mini_v2_defconfig
+++ b/configs/netspace_mini_v2_defconfig
@@ -3,6 +3,7 @@
 CONFIG_SYS_TEXT_BASE=0x600000
 CONFIG_TARGET_NETSPACE_V2=y
 CONFIG_IDENT_STRING=" NS v2 Mini"
+CONFIG_DEFAULT_DEVICE_TREE="kirkwood-ns2mini"
 CONFIG_SYS_EXTRA_OPTIONS="NETSPACE_MINI_V2"
 CONFIG_BOOTDELAY=3
 CONFIG_USE_BOOTARGS=y
@@ -24,6 +25,7 @@
 CONFIG_CMD_FAT=y
 CONFIG_EFI_PARTITION=y
 # CONFIG_PARTITION_UUIDS is not set
+CONFIG_OF_CONTROL=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_MVSATA_IDE=y
 # CONFIG_MMC is not set
@@ -34,4 +36,3 @@
 CONFIG_SYS_NS16550=y
 CONFIG_SPI=y
 CONFIG_KIRKWOOD_SPI=y
-CONFIG_OF_LIBFDT=y
diff --git a/configs/netspace_v2_defconfig b/configs/netspace_v2_defconfig
index 6421706..ebdb16b 100644
--- a/configs/netspace_v2_defconfig
+++ b/configs/netspace_v2_defconfig
@@ -3,6 +3,7 @@
 CONFIG_SYS_TEXT_BASE=0x600000
 CONFIG_TARGET_NETSPACE_V2=y
 CONFIG_IDENT_STRING=" NS v2"
+CONFIG_DEFAULT_DEVICE_TREE="kirkwood-ns2"
 CONFIG_SYS_EXTRA_OPTIONS="NETSPACE_V2"
 CONFIG_BOOTDELAY=3
 CONFIG_USE_BOOTARGS=y
@@ -26,6 +27,7 @@
 CONFIG_ISO_PARTITION=y
 CONFIG_EFI_PARTITION=y
 # CONFIG_PARTITION_UUIDS is not set
+CONFIG_OF_CONTROL=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_MVSATA_IDE=y
 # CONFIG_MMC is not set
@@ -39,4 +41,3 @@
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_STORAGE=y
-CONFIG_OF_LIBFDT=y
diff --git a/configs/nitrogen6dl2g_defconfig b/configs/nitrogen6dl2g_defconfig
index 6ef4226..cfb2ed8 100644
--- a/configs/nitrogen6dl2g_defconfig
+++ b/configs/nitrogen6dl2g_defconfig
@@ -9,7 +9,7 @@
 CONFIG_SUPPORT_RAW_INITRD=y
 CONFIG_BOARD_EARLY_INIT_F=y
 CONFIG_HUSH_PARSER=y
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0x12000000
 CONFIG_CMD_BOOTZ=y
 CONFIG_CMD_MEMTEST=y
diff --git a/configs/nitrogen6dl_defconfig b/configs/nitrogen6dl_defconfig
index b9784a2..9cb7ac2 100644
--- a/configs/nitrogen6dl_defconfig
+++ b/configs/nitrogen6dl_defconfig
@@ -9,7 +9,7 @@
 CONFIG_SUPPORT_RAW_INITRD=y
 CONFIG_BOARD_EARLY_INIT_F=y
 CONFIG_HUSH_PARSER=y
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0x12000000
 CONFIG_CMD_BOOTZ=y
 CONFIG_CMD_MEMTEST=y
diff --git a/configs/nitrogen6q2g_defconfig b/configs/nitrogen6q2g_defconfig
index 61688ba..e31521a 100644
--- a/configs/nitrogen6q2g_defconfig
+++ b/configs/nitrogen6q2g_defconfig
@@ -9,7 +9,7 @@
 CONFIG_SUPPORT_RAW_INITRD=y
 CONFIG_BOARD_EARLY_INIT_F=y
 CONFIG_HUSH_PARSER=y
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0x12000000
 CONFIG_CMD_BOOTZ=y
 CONFIG_CMD_MEMTEST=y
diff --git a/configs/nitrogen6q_defconfig b/configs/nitrogen6q_defconfig
index cfee7ba..85c352c 100644
--- a/configs/nitrogen6q_defconfig
+++ b/configs/nitrogen6q_defconfig
@@ -9,7 +9,7 @@
 CONFIG_SUPPORT_RAW_INITRD=y
 CONFIG_BOARD_EARLY_INIT_F=y
 CONFIG_HUSH_PARSER=y
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0x12000000
 CONFIG_CMD_BOOTZ=y
 CONFIG_CMD_MEMTEST=y
diff --git a/configs/nitrogen6s1g_defconfig b/configs/nitrogen6s1g_defconfig
index 0f29a56..1f37320 100644
--- a/configs/nitrogen6s1g_defconfig
+++ b/configs/nitrogen6s1g_defconfig
@@ -9,7 +9,7 @@
 CONFIG_SUPPORT_RAW_INITRD=y
 CONFIG_BOARD_EARLY_INIT_F=y
 CONFIG_HUSH_PARSER=y
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0x12000000
 CONFIG_CMD_BOOTZ=y
 CONFIG_CMD_MEMTEST=y
diff --git a/configs/nitrogen6s_defconfig b/configs/nitrogen6s_defconfig
index 7ad1584..0696f09 100644
--- a/configs/nitrogen6s_defconfig
+++ b/configs/nitrogen6s_defconfig
@@ -9,7 +9,7 @@
 CONFIG_SUPPORT_RAW_INITRD=y
 CONFIG_BOARD_EARLY_INIT_F=y
 CONFIG_HUSH_PARSER=y
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0x12000000
 CONFIG_CMD_BOOTZ=y
 CONFIG_CMD_MEMTEST=y
diff --git a/configs/omap3_beagle_defconfig b/configs/omap3_beagle_defconfig
index 7b81b03..05dc737 100644
--- a/configs/omap3_beagle_defconfig
+++ b/configs/omap3_beagle_defconfig
@@ -13,7 +13,7 @@
 CONFIG_SPL_MTD_SUPPORT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SYS_PROMPT="BeagleBoard # "
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0x82000000
 CONFIG_CMD_SPL=y
 CONFIG_CMD_SPL_NAND_OFS=0x280000
diff --git a/configs/omap3_evm_defconfig b/configs/omap3_evm_defconfig
index 20795c3..52285cc 100644
--- a/configs/omap3_evm_defconfig
+++ b/configs/omap3_evm_defconfig
@@ -12,7 +12,7 @@
 CONFIG_SPL_MTD_SUPPORT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SYS_PROMPT="OMAP3_EVM # "
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0x82000000
 CONFIG_CMD_SPL=y
 CONFIG_CMD_SPL_NAND_OFS=0x280000
diff --git a/configs/omap3_logic_defconfig b/configs/omap3_logic_defconfig
index 5a31e46..953980c 100644
--- a/configs/omap3_logic_defconfig
+++ b/configs/omap3_logic_defconfig
@@ -13,7 +13,7 @@
 CONFIG_SPL_MTD_SUPPORT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SYS_PROMPT="OMAP Logic # "
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0x82000000
 # CONFIG_CMD_IMI is not set
 CONFIG_CMD_SPL=y
diff --git a/configs/parrot_r16_defconfig b/configs/parrot_r16_defconfig
index 991e9b9..553a8d6 100644
--- a/configs/parrot_r16_defconfig
+++ b/configs/parrot_r16_defconfig
@@ -15,6 +15,7 @@
 # CONFIG_CMD_FLASH is not set
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_SPL_PARTITION_UUIDS is not set
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_CONS_INDEX=5
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_MUSB_GADGET=y
diff --git a/configs/phycore-rk3288_defconfig b/configs/phycore-rk3288_defconfig
index d78b6d5..fc3b81c 100644
--- a/configs/phycore-rk3288_defconfig
+++ b/configs/phycore-rk3288_defconfig
@@ -17,8 +17,6 @@
 CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
 CONFIG_SPL_I2C_SUPPORT=y
 CONFIG_SPL_POWER_SUPPORT=y
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
@@ -44,6 +42,9 @@
 # CONFIG_SPL_SIMPLE_BUS is not set
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_ROCKCHIP_GPIO=y
 CONFIG_SYS_I2C_ROCKCHIP=y
 CONFIG_MISC=y
diff --git a/configs/popmetal-rk3288_defconfig b/configs/popmetal-rk3288_defconfig
index 2670b4b..84c0995 100644
--- a/configs/popmetal-rk3288_defconfig
+++ b/configs/popmetal-rk3288_defconfig
@@ -15,8 +15,6 @@
 CONFIG_DISPLAY_BOARDINFO_LATE=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
@@ -42,6 +40,9 @@
 # CONFIG_SPL_SIMPLE_BUS is not set
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_ROCKCHIP_GPIO=y
 CONFIG_SYS_I2C_ROCKCHIP=y
 CONFIG_MMC_DW=y
diff --git a/configs/porter_defconfig b/configs/porter_defconfig
index b04627e..0588387 100644
--- a/configs/porter_defconfig
+++ b/configs/porter_defconfig
@@ -46,6 +46,9 @@
 CONFIG_CMD_EXT4=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
+CONFIG_CMD_MTDPARTS=y
+CONFIG_MTDIDS_DEFAULT="nor0=spi0.0"
+CONFIG_MTDPARTS_DEFAULT="mtdparts=spi0.0:256k(u-boot-spl),512k(u-boot-env1),512k(u-boot-env2),768k(u-boot),-(user)"
 CONFIG_OF_CONTROL=y
 CONFIG_OF_EMBED=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
@@ -57,9 +60,11 @@
 CONFIG_SYS_I2C_RCAR_IIC=y
 CONFIG_DM_MMC=y
 CONFIG_RENESAS_SDHI=y
+CONFIG_MTD=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y
 CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_MTD=y
 CONFIG_PHY_MICREL=y
 CONFIG_DM_ETH=y
 CONFIG_SH_ETHER=y
diff --git a/configs/r8a77990_ebisu_defconfig b/configs/r8a77990_ebisu_defconfig
new file mode 100644
index 0000000..591eafe
--- /dev/null
+++ b/configs/r8a77990_ebisu_defconfig
@@ -0,0 +1,64 @@
+CONFIG_ARM=y
+CONFIG_ARCH_RMOBILE=y
+CONFIG_SYS_TEXT_BASE=0x50000000
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_RCAR_GEN3=y
+CONFIG_R8A77990=y
+CONFIG_TARGET_EBISU=y
+CONFIG_DEFAULT_DEVICE_TREE="r8a77990-ebisu-u-boot"
+CONFIG_SMBIOS_PRODUCT_NAME=""
+CONFIG_FIT=y
+# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
+CONFIG_USE_BOOTARGS=y
+CONFIG_BOOTARGS="console=ttySC0,115200"
+CONFIG_SUPPORT_RAW_INITRD=y
+CONFIG_DEFAULT_FDT_FILE="r8a77990-ebisu.dtb"
+CONFIG_VERSION_VARIABLE=y
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_BOOTZ=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_EXT2=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_OF_CONTROL=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+CONFIG_CLK_RENESAS=y
+CONFIG_DM_GPIO=y
+CONFIG_RCAR_GPIO=y
+CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_RCAR_IIC=y
+CONFIG_DM_MMC=y
+CONFIG_MMC_IO_VOLTAGE=y
+CONFIG_MMC_UHS_SUPPORT=y
+CONFIG_MMC_HS200_SUPPORT=y
+CONFIG_RENESAS_SDHI=y
+CONFIG_PHY_MICREL=y
+CONFIG_PHY_MICREL_KSZ90X1=y
+CONFIG_DM_ETH=y
+CONFIG_RENESAS_RAVB=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL_PFC=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_REGULATOR_GPIO=y
+CONFIG_SCIF_CONSOLE=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_STORAGE=y
+CONFIG_OF_LIBFDT_OVERLAY=y
+CONFIG_SMBIOS_MANUFACTURER=""
diff --git a/configs/rock2_defconfig b/configs/rock2_defconfig
index cd9a821..01d53ac 100644
--- a/configs/rock2_defconfig
+++ b/configs/rock2_defconfig
@@ -14,8 +14,6 @@
 CONFIG_DISPLAY_BOARDINFO_LATE=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
@@ -42,6 +40,9 @@
 # CONFIG_SPL_SIMPLE_BUS is not set
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_ROCKCHIP_GPIO=y
 CONFIG_SYS_I2C_ROCKCHIP=y
 CONFIG_MMC_DW=y
diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig
index 20a2ab3..228820d 100644
--- a/configs/sandbox64_defconfig
+++ b/configs/sandbox64_defconfig
@@ -175,6 +175,7 @@
 CONFIG_TIMER_EARLY=y
 CONFIG_SANDBOX_TIMER=y
 CONFIG_TPM_TIS_SANDBOX=y
+CONFIG_TPM2_TIS_SANDBOX=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_USB_EMUL=y
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 2fc84a1..dc82ca0 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -176,6 +176,7 @@
 CONFIG_TIMER_EARLY=y
 CONFIG_SANDBOX_TIMER=y
 CONFIG_TPM_TIS_SANDBOX=y
+CONFIG_TPM2_TIS_SANDBOX=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_USB_EMUL=y
diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig
index e922c4b..08072e8 100644
--- a/configs/sandbox_flattree_defconfig
+++ b/configs/sandbox_flattree_defconfig
@@ -157,6 +157,7 @@
 CONFIG_TIMER_EARLY=y
 CONFIG_SANDBOX_TIMER=y
 CONFIG_TPM_TIS_SANDBOX=y
+CONFIG_TPM2_TIS_SANDBOX=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_USB_EMUL=y
diff --git a/configs/sandbox_noblk_defconfig b/configs/sandbox_noblk_defconfig
index 8bdd4ed..306945b 100644
--- a/configs/sandbox_noblk_defconfig
+++ b/configs/sandbox_noblk_defconfig
@@ -156,6 +156,7 @@
 CONFIG_TIMER_EARLY=y
 CONFIG_SANDBOX_TIMER=y
 CONFIG_TPM_TIS_SANDBOX=y
+CONFIG_TPM2_TIS_SANDBOX=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_USB_EMUL=y
diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig
index fb6bb4b..3672755 100644
--- a/configs/sandbox_spl_defconfig
+++ b/configs/sandbox_spl_defconfig
@@ -175,6 +175,7 @@
 CONFIG_TIMER_EARLY=y
 CONFIG_SANDBOX_TIMER=y
 CONFIG_TPM_TIS_SANDBOX=y
+CONFIG_TPM2_TIS_SANDBOX=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_USB_EMUL=y
diff --git a/configs/silk_defconfig b/configs/silk_defconfig
index a1c4e5c..9a9301e 100644
--- a/configs/silk_defconfig
+++ b/configs/silk_defconfig
@@ -46,6 +46,9 @@
 CONFIG_CMD_EXT4=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
+CONFIG_CMD_MTDPARTS=y
+CONFIG_MTDIDS_DEFAULT="nor0=spi0.0"
+CONFIG_MTDPARTS_DEFAULT="mtdparts=spi0.0:256k(u-boot-spl),512k(u-boot-env1),512k(u-boot-env2),768k(u-boot),-(user)"
 CONFIG_OF_CONTROL=y
 CONFIG_OF_EMBED=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
@@ -59,9 +62,11 @@
 CONFIG_DM_MMC=y
 CONFIG_SH_MMCIF=y
 CONFIG_RENESAS_SDHI=y
+CONFIG_MTD=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y
 CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_MTD=y
 CONFIG_PHY_MICREL=y
 CONFIG_DM_ETH=y
 CONFIG_SH_ETHER=y
diff --git a/configs/sniper_defconfig b/configs/sniper_defconfig
index ad22a1c..70e485f 100644
--- a/configs/sniper_defconfig
+++ b/configs/sniper_defconfig
@@ -13,7 +13,7 @@
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=2
 # CONFIG_SPL_EXT_SUPPORT is not set
 CONFIG_SYS_PROMPT="sniper # "
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0x82000000
 CONFIG_FASTBOOT_BUF_SIZE=0x2000000
 CONFIG_FASTBOOT_FLASH=y
diff --git a/configs/stih410-b2260_defconfig b/configs/stih410-b2260_defconfig
index 67391bd..ba1ff25 100644
--- a/configs/stih410-b2260_defconfig
+++ b/configs/stih410-b2260_defconfig
@@ -10,11 +10,6 @@
 CONFIG_BOOTARGS="console=ttyAS1,115200 CONSOLE=/dev/ttyAS1 consoleblank=0 root=/dev/mmcblk0p2 rootfstype=ext4 rw rootwait mem=992M@0x40000000 vmalloc=256m"
 # CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_SYS_PROMPT="stih410-b2260 => "
-CONFIG_FASTBOOT=y
-CONFIG_FASTBOOT_BUF_ADDR=0x40000000
-CONFIG_FASTBOOT_BUF_SIZE=0x3DF00000
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_CMD_GPT=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_USB=y
@@ -26,6 +21,12 @@
 CONFIG_REGMAP=y
 CONFIG_SYSCON=y
 CONFIG_CLK=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_BUF_ADDR=0x40000000
+CONFIG_FASTBOOT_BUF_SIZE=0x3DF00000
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_MISC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_STI=y
diff --git a/configs/stm32mp15_basic_defconfig b/configs/stm32mp15_basic_defconfig
index b1c3690..9e43cc9 100644
--- a/configs/stm32mp15_basic_defconfig
+++ b/configs/stm32mp15_basic_defconfig
@@ -18,6 +18,7 @@
 # CONFIG_CMD_EXPORTENV is not set
 # CONFIG_CMD_IMPORTENV is not set
 CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_FUSE=y
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
diff --git a/configs/stout_defconfig b/configs/stout_defconfig
index d940932..1a9e6ce 100644
--- a/configs/stout_defconfig
+++ b/configs/stout_defconfig
@@ -46,6 +46,9 @@
 CONFIG_CMD_EXT4=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
+CONFIG_CMD_MTDPARTS=y
+CONFIG_MTDIDS_DEFAULT="nor0=spi0.0"
+CONFIG_MTDPARTS_DEFAULT="mtdparts=spi0.0:256k(u-boot-spl),512k(u-boot-env1),512k(u-boot-env2),768k(u-boot),-(user)"
 CONFIG_OF_CONTROL=y
 CONFIG_OF_EMBED=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
@@ -57,9 +60,11 @@
 CONFIG_SYS_I2C_RCAR_IIC=y
 CONFIG_DM_MMC=y
 CONFIG_RENESAS_SDHI=y
+CONFIG_MTD=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y
 CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_MTD=y
 CONFIG_PHY_MICREL=y
 CONFIG_DM_ETH=y
 CONFIG_SH_ETHER=y
diff --git a/configs/tbs_a711_defconfig b/configs/tbs_a711_defconfig
index 3e3de4f..5d58f5c 100644
--- a/configs/tbs_a711_defconfig
+++ b/configs/tbs_a711_defconfig
@@ -16,6 +16,7 @@
 # CONFIG_CMD_FLASH is not set
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_AXP_DCDC5_VOLT=1200
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_MUSB_GADGET=y
diff --git a/configs/tinker-rk3288_defconfig b/configs/tinker-rk3288_defconfig
index fb6bfa5..e1c99c3 100644
--- a/configs/tinker-rk3288_defconfig
+++ b/configs/tinker-rk3288_defconfig
@@ -16,8 +16,6 @@
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
 CONFIG_SPL_I2C_SUPPORT=y
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
@@ -43,6 +41,9 @@
 # CONFIG_SPL_SIMPLE_BUS is not set
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_ROCKCHIP_GPIO=y
 CONFIG_SYS_I2C_ROCKCHIP=y
 CONFIG_MISC=y
diff --git a/configs/turris_mox_defconfig b/configs/turris_mox_defconfig
index 7dea715..3eb0479 100644
--- a/configs/turris_mox_defconfig
+++ b/configs/turris_mox_defconfig
@@ -62,6 +62,8 @@
 CONFIG_DEBUG_UART_ANNOUNCE=y
 CONFIG_MVEBU_A3700_UART=y
 CONFIG_MVEBU_A3700_SPI=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_USB_XHCI_HCD=y
diff --git a/configs/xilinx_zynqmp_zc1232_revA_defconfig b/configs/xilinx_zynqmp_zc1232_revA_defconfig
index 70dc870..d5c0838 100644
--- a/configs/xilinx_zynqmp_zc1232_revA_defconfig
+++ b/configs/xilinx_zynqmp_zc1232_revA_defconfig
@@ -2,9 +2,9 @@
 CONFIG_ARCH_ZYNQMP=y
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
-# CONFIG_SPL_LIBDISK_SUPPORT is not set
 CONFIG_SPL=y
 # CONFIG_SPL_FAT_SUPPORT is not set
+# CONFIG_SPL_LIBDISK_SUPPORT is not set
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1232-revA"
 CONFIG_DEBUG_UART=y
 CONFIG_DISTRO_DEFAULTS=y
diff --git a/configs/xilinx_zynqmp_zc1254_revA_defconfig b/configs/xilinx_zynqmp_zc1254_revA_defconfig
index 09de18d..40baccc 100644
--- a/configs/xilinx_zynqmp_zc1254_revA_defconfig
+++ b/configs/xilinx_zynqmp_zc1254_revA_defconfig
@@ -2,9 +2,9 @@
 CONFIG_ARCH_ZYNQMP=y
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
-# CONFIG_SPL_LIBDISK_SUPPORT is not set
 CONFIG_SPL=y
 # CONFIG_SPL_FAT_SUPPORT is not set
+# CONFIG_SPL_LIBDISK_SUPPORT is not set
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1254-revA"
 CONFIG_DEBUG_UART=y
 CONFIG_DISTRO_DEFAULTS=y
diff --git a/configs/xilinx_zynqmp_zc1275_revA_defconfig b/configs/xilinx_zynqmp_zc1275_revA_defconfig
index a7e79f5..542bfe2 100644
--- a/configs/xilinx_zynqmp_zc1275_revA_defconfig
+++ b/configs/xilinx_zynqmp_zc1275_revA_defconfig
@@ -2,9 +2,9 @@
 CONFIG_ARCH_ZYNQMP=y
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
-# CONFIG_SPL_LIBDISK_SUPPORT is not set
 CONFIG_SPL=y
 # CONFIG_SPL_FAT_SUPPORT is not set
+# CONFIG_SPL_LIBDISK_SUPPORT is not set
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1275-revA"
 CONFIG_DEBUG_UART=y
 CONFIG_DISTRO_DEFAULTS=y
diff --git a/configs/xilinx_zynqmp_zc1275_revB_defconfig b/configs/xilinx_zynqmp_zc1275_revB_defconfig
index 823b503..92bb15a 100644
--- a/configs/xilinx_zynqmp_zc1275_revB_defconfig
+++ b/configs/xilinx_zynqmp_zc1275_revB_defconfig
@@ -3,9 +3,9 @@
 CONFIG_ARCH_ZYNQMP=y
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
-# CONFIG_SPL_LIBDISK_SUPPORT is not set
 CONFIG_SPL=y
 # CONFIG_SPL_FAT_SUPPORT is not set
+# CONFIG_SPL_LIBDISK_SUPPORT is not set
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1275-revB"
 CONFIG_DEBUG_UART=y
 CONFIG_DISTRO_DEFAULTS=y
diff --git a/configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig b/configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig
index f5a3334..779270c 100644
--- a/configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig
+++ b/configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig
@@ -19,9 +19,6 @@
 CONFIG_SPL_RAM_DEVICE=y
 CONFIG_SPL_ATF=y
 CONFIG_SYS_PROMPT="ZynqMP> "
-CONFIG_FASTBOOT=y
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_CMD_THOR_DOWNLOAD=y
 CONFIG_CMD_MEMTEST=y
 CONFIG_SYS_ALT_MEMTEST=y
@@ -47,6 +44,10 @@
 CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_CLK_ZYNQMP=y
 CONFIG_DFU_RAM=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_FPGA_XILINX=y
 CONFIG_FPGA_ZYNQMPPL=y
 CONFIG_DM_GPIO=y
@@ -54,6 +55,7 @@
 CONFIG_SYS_I2C_CADENCE=y
 CONFIG_MISC=y
 CONFIG_DM_MMC=y
+CONFIG_MMC_HS200_SUPPORT=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ZYNQ=y
 CONFIG_SPI_FLASH=y
diff --git a/configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig b/configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig
index 7f7ee55..b269696 100644
--- a/configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig
+++ b/configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig
@@ -1,11 +1,10 @@
 CONFIG_ARM=y
-CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_zc1751_xm016_dc2"
 CONFIG_ARCH_ZYNQMP=y
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
-# CONFIG_SPL_LIBDISK_SUPPORT is not set
 CONFIG_SPL=y
 # CONFIG_SPL_FAT_SUPPORT is not set
+# CONFIG_SPL_LIBDISK_SUPPORT is not set
 CONFIG_ZYNQMP_USB=y
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1751-xm016-dc2"
 CONFIG_DEBUG_UART=y
@@ -20,7 +19,7 @@
 CONFIG_SPL_RAM_DEVICE=y
 CONFIG_SPL_ATF=y
 CONFIG_SYS_PROMPT="ZynqMP> "
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_FLASH=y
 CONFIG_CMD_THOR_DOWNLOAD=y
 CONFIG_CMD_MEMTEST=y
diff --git a/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig b/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig
index 4cb3959..11708f7 100644
--- a/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig
+++ b/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig
@@ -19,9 +19,6 @@
 CONFIG_SPL_RAM_DEVICE=y
 CONFIG_SPL_ATF=y
 CONFIG_SYS_PROMPT="ZynqMP> "
-CONFIG_FASTBOOT=y
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_CMD_THOR_DOWNLOAD=y
 CONFIG_CMD_EEPROM=y
 CONFIG_CMD_MEMTEST=y
@@ -31,6 +28,7 @@
 # CONFIG_CMD_FLASH is not set
 CONFIG_CMD_FPGA_LOADBP=y
 CONFIG_CMD_FPGA_LOADP=y
+CONFIG_CMD_FPGA_LOAD_SECURE=y
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
@@ -50,6 +48,10 @@
 CONFIG_SATA_CEVA=y
 CONFIG_CLK_ZYNQMP=y
 CONFIG_DFU_RAM=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_FPGA_XILINX=y
 CONFIG_FPGA_ZYNQMPPL=y
 CONFIG_DM_GPIO=y
diff --git a/configs/xilinx_zynqmp_zcu102_revA_defconfig b/configs/xilinx_zynqmp_zcu102_revA_defconfig
index e989d16..3420ce5 100644
--- a/configs/xilinx_zynqmp_zcu102_revA_defconfig
+++ b/configs/xilinx_zynqmp_zcu102_revA_defconfig
@@ -19,9 +19,6 @@
 CONFIG_SPL_RAM_DEVICE=y
 CONFIG_SPL_ATF=y
 CONFIG_SYS_PROMPT="ZynqMP> "
-CONFIG_FASTBOOT=y
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_CMD_THOR_DOWNLOAD=y
 CONFIG_CMD_EEPROM=y
 CONFIG_CMD_MEMTEST=y
@@ -50,6 +47,10 @@
 CONFIG_SATA_CEVA=y
 CONFIG_CLK_ZYNQMP=y
 CONFIG_DFU_RAM=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_FPGA_XILINX=y
 CONFIG_FPGA_ZYNQMPPL=y
 CONFIG_DM_GPIO=y
diff --git a/configs/xilinx_zynqmp_zcu102_revB_defconfig b/configs/xilinx_zynqmp_zcu102_revB_defconfig
index bd67df9..a9ba4a1 100644
--- a/configs/xilinx_zynqmp_zcu102_revB_defconfig
+++ b/configs/xilinx_zynqmp_zcu102_revB_defconfig
@@ -19,9 +19,6 @@
 CONFIG_SPL_RAM_DEVICE=y
 CONFIG_SPL_ATF=y
 CONFIG_SYS_PROMPT="ZynqMP> "
-CONFIG_FASTBOOT=y
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_CMD_THOR_DOWNLOAD=y
 CONFIG_CMD_EEPROM=y
 CONFIG_CMD_MEMTEST=y
@@ -50,6 +47,10 @@
 CONFIG_SATA_CEVA=y
 CONFIG_CLK_ZYNQMP=y
 CONFIG_DFU_RAM=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_FPGA_XILINX=y
 CONFIG_FPGA_ZYNQMPPL=y
 CONFIG_DM_GPIO=y
diff --git a/configs/xilinx_zynqmp_zcu106_revA_defconfig b/configs/xilinx_zynqmp_zcu106_revA_defconfig
index a5fa33e..32c6f23 100644
--- a/configs/xilinx_zynqmp_zcu106_revA_defconfig
+++ b/configs/xilinx_zynqmp_zcu106_revA_defconfig
@@ -18,9 +18,6 @@
 CONFIG_SPL_RAM_DEVICE=y
 CONFIG_SPL_ATF=y
 CONFIG_SYS_PROMPT="ZynqMP> "
-CONFIG_FASTBOOT=y
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_CMD_THOR_DOWNLOAD=y
 CONFIG_CMD_EEPROM=y
 CONFIG_CMD_MEMTEST=y
@@ -48,6 +45,10 @@
 CONFIG_SATA_CEVA=y
 CONFIG_CLK_ZYNQMP=y
 CONFIG_DFU_RAM=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_FPGA_XILINX=y
 CONFIG_FPGA_ZYNQMPPL=y
 CONFIG_DM_GPIO=y
diff --git a/configs/zynq_minized_defconfig b/configs/zynq_minized_defconfig
new file mode 100644
index 0000000..8cf3215
--- /dev/null
+++ b/configs/zynq_minized_defconfig
@@ -0,0 +1,66 @@
+CONFIG_ARM=y
+CONFIG_ARCH_ZYNQ=y
+CONFIG_SYS_TEXT_BASE=0x4000000
+CONFIG_SPL=y
+CONFIG_SPL_STACK_R_ADDR=0x200000
+CONFIG_DEFAULT_DEVICE_TREE="zynq-minized"
+CONFIG_DEBUG_UART=y
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_FIT=y
+CONFIG_FIT_SIGNATURE=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
+CONFIG_SPL_STACK_R=y
+CONFIG_SPL_OS_BOOT=y
+CONFIG_SYS_PROMPT="Zynq> "
+CONFIG_CMD_THOR_DOWNLOAD=y
+CONFIG_CMD_DFU=y
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_FPGA_LOADBP=y
+CONFIG_CMD_FPGA_LOADFS=y
+CONFIG_CMD_FPGA_LOADMK=y
+CONFIG_CMD_FPGA_LOADP=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_USB=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_TFTPPUT=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_DFU_MMC=y
+CONFIG_DFU_RAM=y
+CONFIG_FPGA_XILINX=y
+CONFIG_FPGA_ZYNQPL=y
+CONFIG_DM_GPIO=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_ZYNQ=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_PHY_MARVELL=y
+CONFIG_PHY_REALTEK=y
+CONFIG_PHY_XILINX=y
+CONFIG_ZYNQ_GEM=y
+CONFIG_DEBUG_UART_ZYNQ=y
+CONFIG_DEBUG_UART_BASE=0xe0001000
+CONFIG_DEBUG_UART_CLOCK=50000000
+CONFIG_ZYNQ_SERIAL=y
+CONFIG_ZYNQ_QSPI=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_ULPI_VIEWPORT=y
+CONFIG_USB_ULPI=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_MANUFACTURER="Xilinx"
+CONFIG_USB_GADGET_VENDOR_NUM=0x03fd
+CONFIG_USB_GADGET_PRODUCT_NUM=0x0300
+CONFIG_CI_UDC=y
+CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_USB_FUNCTION_THOR=y
diff --git a/doc/DocBook/Makefile b/doc/DocBook/Makefile
index 820b1fb..5257613 100644
--- a/doc/DocBook/Makefile
+++ b/doc/DocBook/Makefile
@@ -7,7 +7,7 @@
 # To add a new book the only step required is to add the book to the
 # list of DOCBOOKS.
 
-DOCBOOKS := linker_lists.xml stdio.xml
+DOCBOOKS := efi.xml linker_lists.xml stdio.xml
 
 ###
 # The build process is as follows (targets):
diff --git a/doc/DocBook/efi.tmpl b/doc/DocBook/efi.tmpl
new file mode 100644
index 0000000..5daaae3
--- /dev/null
+++ b/doc/DocBook/efi.tmpl
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+	"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
+
+<book id="UBootEFI">
+ <bookinfo>
+  <title>The U-Boot EFI subsystem</title>
+ </bookinfo>
+
+<toc></toc>
+
+  <chapter id="BootServices">
+     <title>Boot services</title>
+!Ilib/efi_loader/efi_boottime.c
+  </chapter>
+
+</book>
diff --git a/doc/README.NX25 b/doc/README.AX25
similarity index 95%
rename from doc/README.NX25
rename to doc/README.AX25
index 9f054e5..7a607dd 100644
--- a/doc/README.NX25
+++ b/doc/README.AX25
@@ -1,4 +1,4 @@
-NX25 is Andes CPU IP to adopt RISC-V architecture.
+AX25 is Andes CPU IP to adopt RISC-V architecture.
 
 Features
 ========
diff --git a/doc/README.ae250 b/doc/README.ae350
similarity index 92%
rename from doc/README.ae250
rename to doc/README.ae350
index 77c168a..fe75b80 100644
--- a/doc/README.ae250
+++ b/doc/README.ae350
@@ -1,16 +1,16 @@
-Andes Technology SoC AE250
+Andes Technology SoC AE350
 ===========================
 
-AE250 is the mainline SoC produced by Andes Technology using NX25 CPU core
+AE350 is the mainline SoC produced by Andes Technology using AX25 CPU core
 base on RISC-V architecture.
 
-AE250 has integrated both AHB and APB bus and many periphals for application
+AE350 has integrated both AHB and APB bus and many periphals for application
 and product development.
 
-NX25-AE250
+AX25-AE350
 =========
 
-NX25-AE250 is the SoC with AE250 hardcore CPU.
+AX25-AE350 is the SoC with AE350 hardcore CPU.
 
 Configurations
 ==============
@@ -18,14 +18,14 @@
 CONFIG_SKIP_LOWLEVEL_INIT:
 	If you want to boot this system from SPI ROM and bypass e-bios (the
 	other boot loader on ROM). You should undefine CONFIG_SKIP_LOWLEVEL_INIT
-	in "include/configs/nx25-ae250.h".
+	in "include/configs/ax25-ae350.h".
 
 Build and boot steps
 ====================
 
 build:
 1. Prepare the toolchains and make sure the $PATH to toolchains is correct.
-2. Use `make nx25-ae250_defconfig` in u-boot root to build the image.
+2. Use `make ax25-ae350_defconfig` in u-boot root to build the image.
 
 Verification
 ====================
@@ -49,7 +49,7 @@
 5. Burn this u-boot image to spi rom by spi driver
 6. Re-boot u-boot from spi flash with power off and power on.
 
-Messages of U-Boot boot on AE250 board
+Messages of U-Boot boot on AE350 board
 ======================================
 U-Boot 2018.01-rc2-00033-g824f89a (Dec 21 2017 - 16:51:26 +0800)
 
@@ -77,9 +77,9 @@
 
 RISC-V # mmc rescan
 RISC-V # fatls mmc 0:1
-   318907   u-boot-ae250-64.bin
-     1252   hello_world_ae250_32.bin
-   328787   u-boot-ae250-32.bin
+   318907   u-boot-ae350-64.bin
+     1252   hello_world_ae350_32.bin
+   328787   u-boot-ae350-32.bin
 
 3 file(s), 0 dir(s)
 
@@ -98,8 +98,8 @@
 2 write: 40 ticks, 100 KiB/s 0.800 Mbps
 3 read: 20 ticks, 200 KiB/s 1.600 Mbps
 
-RISC-V # fatload mmc 0:1 0x600000 u-boot-ae250-32.bin
-reading u-boot-ae250-32.bin
+RISC-V # fatload mmc 0:1 0x600000 u-boot-ae350-32.bin
+reading u-boot-ae350-32.bin
 328787 bytes read in 324 ms (990.2 KiB/s)
 
 RISC-V # sf erase 0x0 0x51000
@@ -136,7 +136,7 @@
 ===========================================
 1. Build riscv-linux
 2. Build bbl and riscv-linux with --with-payload
-3. Prepare ae250.dtb
+3. Prepare ae350.dtb
 4. Creating OS-kernel images
 	./mkimage -A riscv -O linux -T kernel -C none -a 0x0000 -e 0x0000 -d bbl.bin bootmImage-bbl.bin
 	Image Name:
@@ -146,7 +146,7 @@
 	Load Address: 00000000
 	Entry Point:  00000000
 
-4. Copy bootmImage-bbl.bin and ae250.dtb to qemu sd card image
+4. Copy bootmImage-bbl.bin and ae350.dtb to qemu sd card image
 5. Message of booting riscv-linux from bbl via u-boot on qemu
 
 U-Boot 2018.03-rc4-00031-g2631273 (Mar 13 2018 - 15:02:55 +0800)
@@ -177,7 +177,7 @@
 
 RISC-V # fatload mmc 0:0 0x00600000 bootmImage-bbl.bin
 17901268 bytes read in 4642 ms (3.7 MiB/s)
-RISC-V # fatload mmc 0:0 0x2000000 ae250.dtb
+RISC-V # fatload mmc 0:0 0x2000000 ae350.dtb
 1954 bytes read in 1 ms (1.9 MiB/s)
 RISC-V # setenv bootm_size 0x2000000
 RISC-V # setenv fdt_high 0x1f00000
@@ -272,4 +272,4 @@
 
 TODO
 ==================================================
-Boot bbl and riscv-linux via U-Boot on AE250 board
+Boot bbl and riscv-linux via U-Boot on AE350 board
diff --git a/doc/README.android-fastboot b/doc/README.android-fastboot
index 2c3ee78..431191c 100644
--- a/doc/README.android-fastboot
+++ b/doc/README.android-fastboot
@@ -1,142 +1,214 @@
+================
 Android Fastboot
-~~~~~~~~~~~~~~~~
+================
 
 Overview
 ========
-The protocol that is used over USB is described in
-README.android-fastboot-protocol in same directory.
 
-The current implementation is a minimal support of the erase command,the
-"oem format" command and flash command;it only supports eMMC devices.
+The protocol that is used over USB and UDP is described in the
+``README.android-fastboot-protocol`` file in the same directory.
+
+The current implementation supports the following standard commands:
+
+- ``boot``
+- ``continue``
+- ``download``
+- ``erase`` (if enabled)
+- ``flash`` (if enabled)
+- ``getvar``
+- ``reboot``
+- ``reboot-bootloader``
+- ``set_active`` (only a stub implementation which always succeeds)
+
+The following OEM commands are supported (if enabled):
+
+- oem format - this executes ``gpt write mmc %x $partitions``
+
+Support for both eMMC and NAND devices is included.
 
 Client installation
 ===================
-The counterpart to this gadget is the fastboot client which can
-be found in Android's platform/system/core repository in the fastboot
-folder. It runs on Windows, Linux and even OSX. Linux user are lucky since
-they only need libusb.
-Windows users need to bring some time until they have Android SDK (currently
-http://dl.google.com/android/installer_r12-windows.exe) installed. You
-need to install ADB package which contains the required glue libraries for
-accessing USB. Also you need "Google USB driver package" and "SDK platform
-tools". Once installed the usb driver is placed in your SDK folder under
-extras\google\usb_driver. The android_winusb.inf needs a line like
 
-   %SingleBootLoaderInterface% = USB_Install, USB\VID_0451&PID_D022
+The counterpart to this is the fastboot client which can be found in
+Android's ``platform/system/core`` repository in the fastboot
+folder. It runs on Windows, Linux and OSX. The fastboot client is
+part of the Android SDK Platform-Tools and can be downloaded from:
 
-either in the [Google.NTx86] section for 32bit Windows or [Google.NTamd64]
-for 64bit Windows. VID and PID should match whatever the fastboot is
-advertising.
+https://developer.android.com/studio/releases/platform-tools
 
 Board specific
 ==============
+
+USB configuration
+-----------------
+
 The fastboot gadget relies on the USB download gadget, so the following
 options must be configured:
 
-CONFIG_USB_GADGET_DOWNLOAD
-CONFIG_USB_GADGET_VENDOR_NUM
-CONFIG_USB_GADGET_PRODUCT_NUM
-CONFIG_USB_GADGET_MANUFACTURER
+::
 
-NOTE: The CONFIG_USB_GADGET_VENDOR_NUM must be one of the numbers supported by
-the fastboot client. The list of vendor IDs supported can be found in the
-fastboot client source code (fastboot.c) mentioned above.
+   CONFIG_USB_GADGET_DOWNLOAD
+   CONFIG_USB_GADGET_VENDOR_NUM
+   CONFIG_USB_GADGET_PRODUCT_NUM
+   CONFIG_USB_GADGET_MANUFACTURER
 
-The fastboot function is enabled by defining CONFIG_USB_FUNCTION_FASTBOOT,
-CONFIG_CMD_FASTBOOT and CONFIG_ANDROID_BOOT_IMAGE.
+NOTE: The ``CONFIG_USB_GADGET_VENDOR_NUM`` must be one of the numbers
+supported by the fastboot client. The list of vendor IDs supported can
+be found in the fastboot client source code.
 
-The fastboot protocol requires a large memory buffer for downloads. This
-buffer should be as large as possible for a platform. The location of the
-buffer and size are set with CONFIG_FASTBOOT_BUF_ADDR and
-CONFIG_FASTBOOT_BUF_SIZE.
+General configuration
+---------------------
+
+The fastboot protocol requires a large memory buffer for
+downloads. This buffer should be as large as possible for a
+platform. The location of the buffer and size are set with
+``CONFIG_FASTBOOT_BUF_ADDR`` and ``CONFIG_FASTBOOT_BUF_SIZE``. These
+may be overridden on the fastboot command line using ``-l`` and
+``-s``.
+
+Fastboot environment variables
+==============================
+
+Partition aliases
+-----------------
 
 Fastboot partition aliases can also be defined for devices where GPT
 limitations prevent user-friendly partition names such as "boot", "system"
 and "cache".  Or, where the actual partition name doesn't match a standard
-partition name used commonly with fastboot.  Current implentation checks
-aliases when accessing partitions by name (flash_write and erase functions).
-To define a partition alias add an environment variable similar to:
-fastboot_partition_alias_<alias partition name>=<actual partition name>
-Example: fastboot_partition_alias_boot=LNX
+partition name used commonly with fastboot.
+
+The current implementation checks aliases when accessing partitions by
+name (flash_write and erase functions).  To define a partition alias
+add an environment variable similar to:
+
+``fastboot_partition_alias_<alias partition name>=<actual partition name>``
+
+for example:
+
+``fastboot_partition_alias_boot=LNX``
+
+Variable overrides
+------------------
+
+Variables retrived through ``getvar`` can be overridden by defining
+environment variables of the form ``fastboot.<variable>``. These are
+looked up first so can be used to override values which would
+otherwise be returned. Using this mechanism you can also return types
+for NAND filesystems, as the fully parameterised variable is looked
+up, e.g.
+
+``fastboot.partition-type:boot=jffs2``
+
+Boot command
+------------
+
+When executing the fastboot ``boot`` command, if ``fastboot_bootcmd`` is set then
+that will be executed in place of ``bootm <CONFIG_FASTBOOT_BUF_ADDR>``.
 
 Partition Names
 ===============
-The Fastboot implementation in U-boot allows to write images into disk
-partitions (currently on eMMC). Target partitions are referred on the host
-computer by their names.
+
+The Fastboot implementation in U-Boot allows to write images into disk
+partitions. Target partitions are referred on the host computer by
+their names.
 
 For GPT/EFI the respective partition name is used.
 
 For MBR the partitions are referred by generic names according to the
 following schema:
 
-  <device type> <device index letter> <partition index>
+  <device type><device index letter><partition index>
 
-Example: hda3, sdb1, usbda1
+Example: ``hda3``, ``sdb1``, ``usbda1``
 
 The device type is as follows:
 
-  * IDE, ATAPI and SATA disks: hd
-  * SCSI disks: sd
-  * USB media: usbd
-  * MMC and SD cards: mmcsd
-  * Disk on chip: docd
-  * other: xx
+  * IDE, ATAPI and SATA disks: ``hd``
+  * SCSI disks: ``sd``
+  * USB media: ``usbd``
+  * MMC and SD cards: ``mmcsd``
+  * Disk on chip: ``docd``
+  * other: ``xx``
 
-The device index starts from 'a' and refers to the interface (e.g. USB
+The device index starts from ``a`` and refers to the interface (e.g. USB
 controller, SD/MMC controller) or disk index. The partition index starts
-from 1 and describes the partition number on the particular device.
+from ``1`` and describes the partition number on the particular device.
 
 Writing Partition Table
 =======================
+
 Fastboot also allows to write the partition table to the media. This can be
 done by writing the respective partition table image to a special target
 "gpt" or "mbr". These names can be customized by defining the following
 configuration options:
 
-CONFIG_FASTBOOT_GPT_NAME
-CONFIG_FASTBOOT_MBR_NAME
+::
+
+   CONFIG_FASTBOOT_GPT_NAME
+   CONFIG_FASTBOOT_MBR_NAME
 
 In Action
 =========
-Enter into fastboot by executing the fastboot command in u-boot and you
-should see:
-|GADGET DRIVER: usb_dnl_fastboot
+
+Enter into fastboot by executing the fastboot command in U-Boot for either USB:
+
+::
+
+   => fastboot usb 0
+
+or UDP:
+
+::
+
+   => fastboot udp
+   link up on port 0, speed 100, full duplex
+   Using ethernet@4a100000 device
+   Listening for fastboot command on 192.168.0.102
 
 On the client side you can fetch the bootloader version for instance:
-|>fastboot getvar bootloader-version
-|bootloader-version: U-Boot 2014.04-00005-gd24cabc
-|finished. total time: 0.000s
+
+::
+
+   $ fastboot getvar bootloader-version
+   bootloader-version: U-Boot 2014.04-00005-gd24cabc
+   finished. total time: 0.000s
 
 or initiate a reboot:
-|>fastboot reboot
+
+::
+
+   $ fastboot reboot
 
 and once the client comes back, the board should reset.
 
 You can also specify a kernel image to boot. You have to either specify
-the an image in Android format _or_ pass a binary kernel and let the
+the an image in Android format *or* pass a binary kernel and let the
 fastboot client wrap the Android suite around it. On OMAP for instance you
 take zImage kernel and pass it to the fastboot client:
 
-|>fastboot -b 0x80000000 -c "console=ttyO2 earlyprintk root=/dev/ram0
-|	mem=128M" boot zImage
-|creating boot image...
-|creating boot image - 1847296 bytes
-|downloading 'boot.img'...
-|OKAY [  2.766s]
-|booting...
-|OKAY [ -0.000s]
-|finished. total time: 2.766s
+::
 
-and on the gadget side you should see:
-|Starting download of 1847296 bytes
-|........................................................
-|downloading of 1847296 bytes finished
-|Booting kernel..
-|## Booting Android Image at 0x81000000 ...
-|Kernel load addr 0x80008000 size 1801 KiB
-|Kernel command line: console=ttyO2 earlyprintk root=/dev/ram0 mem=128M
-|   Loading Kernel Image ... OK
-|OK
-|
-|Starting kernel ...
+   $ fastboot -b 0x80000000 -c "console=ttyO2 earlyprintk root=/dev/ram0 mem=128M" boot zImage
+   creating boot image...
+   creating boot image - 1847296 bytes
+   downloading 'boot.img'...
+   OKAY [  2.766s]
+   booting...
+   OKAY [ -0.000s]
+   finished. total time: 2.766s
+
+and on the U-Boot side you should see:
+
+::
+
+   Starting download of 1847296 bytes
+   ........................................................
+   downloading of 1847296 bytes finished
+   Booting kernel..
+   ## Booting Android Image at 0x81000000 ...
+   Kernel load addr 0x80008000 size 1801 KiB
+   Kernel command line: console=ttyO2 earlyprintk root=/dev/ram0 mem=128M
+      Loading Kernel Image ... OK
+   OK
+
+   Starting kernel ...
diff --git a/doc/README.qemu-arm b/doc/README.qemu-arm
index 6f6f07d..2601656 100644
--- a/doc/README.qemu-arm
+++ b/doc/README.qemu-arm
@@ -39,13 +39,12 @@
 The minimal QEMU command line to get U-Boot up and running is:
 
 - For ARM:
-    qemu-system-arm -machine virt,highmem=off -bios u-boot.bin
+    qemu-system-arm -machine virt -bios u-boot.bin
 
 - For AArch64:
-    qemu-system-aarch64 -machine virt,highmem=off -cpu cortex-a57 -bios u-boot.bin
+    qemu-system-aarch64 -machine virt -cpu cortex-a57 -bios u-boot.bin
 
-The 'highmem=off' parameter to the 'virt' machine is required for PCI to work
-in U-Boot. Also, for some odd reason qemu-system-aarch64 needs to be explicitly
+Note that for some odd reason qemu-system-aarch64 needs to be explicitly
 told to use a 64-bit CPU or it will boot in 32-bit mode.
 
 Additional peripherals that have been tested to work in both U-Boot and Linux
diff --git a/doc/README.uefi b/doc/README.uefi
index 196e999..d4031ef 100644
--- a/doc/README.uefi
+++ b/doc/README.uefi
@@ -299,13 +299,18 @@
     CONFIG_BLK=y
     CONFIG_PARTITIONS=y
 
-## TODOs as of U-Boot 2018.03
+## TODOs as of U-Boot 2018.07
 
 * unimplemented or incompletely implemented boot services
   * Exit - call unload function, unload applications only
-  * ReinstallProtocolInterface
+  * ProtocolRegisterNotify
   * UnloadImage
 
+* unimplemented or incompletely implemented runtime services
+  * SetVariable() ignores attribute EFI_VARIABLE_APPEND_WRITE
+  * GetNextVariableName is not implemented
+  * QueryVariableInfo is not implemented
+
 * unimplemented events
   * EVT_RUNTIME
   * EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE
diff --git a/doc/device-tree-bindings/pinctrl/marvell,mvebu-pinctrl.txt b/doc/device-tree-bindings/pinctrl/marvell,mvebu-pinctrl.txt
index 5f86c0a..1fc1bc6 100644
--- a/doc/device-tree-bindings/pinctrl/marvell,mvebu-pinctrl.txt
+++ b/doc/device-tree-bindings/pinctrl/marvell,mvebu-pinctrl.txt
@@ -6,10 +6,10 @@
 
 Required properties for the pinctrl driver:
 - compatible:	"marvell,mvebu-pinctrl",
-		"marvell,armada-ap806-pinctrl",
-		"marvell,a70x0-pinctrl",
-		"marvell,a80x0-cp0-pinctrl",
-		"marvell,a80x0-cp1-pinctrl"
+		"marvell,ap806-pinctrl",
+		"marvell,armada-7k-pinctrl",
+		"marvell,armada-8k-cpm-pinctrl",
+		"marvell,armada-8k-cps-pinctrl"
 - bank-name:	A string defining the pinc controller bank name
 - reg: 		A pair of values defining the pin controller base address
 		and the address space
@@ -31,7 +31,7 @@
 		config-space {
 			pinctl: pinctl@6F4000 {
 				compatible = "marvell,mvebu-pinctrl",
-					     "marvell,armada-ap806-pinctrl";
+					     "marvell,ap806-pinctrl";
 				bank-name ="apn-806";
 				reg = <0x6F4000 0x10>;
 				pin-count = <20>;
@@ -52,8 +52,8 @@
 		config-space {
 			cpm_pinctl: pinctl@44000 {
 				compatible = "marvell,mvebu-pinctrl",
-					     "marvell,a70x0-pinctrl",
-					     "marvell,a80x0-cp0-pinctrl";
+					     "marvell,armada-7k-pinctrl",
+					     "marvell,armada-8k-cpm-pinctrl";
 				bank-name ="cp0-110";
 				reg = <0x440000 0x20>;
 				pin-count = <63>;
@@ -89,7 +89,7 @@
 		config-space {
 			cps_pinctl: pinctl@44000 {
 				compatible = "marvell,mvebu-pinctrl",
-					     "marvell,a80x0-cp1-pinctrl";
+					     "marvell,armada-8k-cps-pinctrl";
 				bank-name ="cp1-110";
 				reg = <0x440000 0x20>;
 				pin-count = <63>;
diff --git a/doc/device-tree-bindings/tpm2/sandbox.txt b/doc/device-tree-bindings/tpm2/sandbox.txt
new file mode 100644
index 0000000..3d0f727
--- /dev/null
+++ b/doc/device-tree-bindings/tpm2/sandbox.txt
@@ -0,0 +1,11 @@
+Sandbox TPMv2.0 bindings
+------------------------
+
+Required properties:
+- compatible		: Should be "sandbox,tpm2"
+
+Example:
+
+	tpm {
+ 		compatible = "sandbox,tpm2";
+	};
diff --git a/doc/device-tree-bindings/tpm2/tis-tpm2-spi.txt b/doc/device-tree-bindings/tpm2/tis-tpm2-spi.txt
new file mode 100644
index 0000000..b48a151
--- /dev/null
+++ b/doc/device-tree-bindings/tpm2/tis-tpm2-spi.txt
@@ -0,0 +1,18 @@
+ST33TPHF20 SPI TPMv2.0 bindings
+-------------------------------
+
+Required properties:
+- compatible		: Should be "tis,tpm2-spi"
+- reg			: SPI Chip select
+
+Optional properties:
+- gpio-reset		: Reset GPIO (if not connected to the SoC reset line)
+- spi-max-frequency	: See spi-bus.txt
+
+Example:
+
+	tpm@1 {
+		compatible = "tis,tpm2-spi";
+		reg = <1>;
+		spi-max-frequency = <10000000>;
+	};
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 9af8835..9e21b28 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -28,6 +28,8 @@
 
 source "drivers/dma/Kconfig"
 
+source "drivers/fastboot/Kconfig"
+
 source "drivers/firmware/Kconfig"
 
 source "drivers/fpga/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 85e4e0c..a213ea9 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -71,6 +71,7 @@
 obj-$(CONFIG_BOOTCOUNT_LIMIT) += bootcount/
 obj-$(CONFIG_CPU) += cpu/
 obj-y += crypto/
+obj-$(CONFIG_FASTBOOT) += fastboot/
 obj-y += firmware/
 obj-$(CONFIG_FPGA) += fpga/
 obj-y += misc/
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 86ec628..49a056e 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -99,4 +99,15 @@
 	help
 	  Enable this driver to support the SIL3114 SATA controllers.
 
+config AHCI_MVEBU
+	bool "Marvell EBU AHCI SATA support"
+	depends on ARCH_MVEBU
+	depends on AHCI
+	select SCSI_AHCI
+	select DM_SCSI
+	help
+	  This option enables support for the Marvell EBU SoC's
+	  onboard AHCI SATA.
+
+	  If unsure, say N.
 endmenu
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index 02f02c8..10bed53 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -17,3 +17,4 @@
 obj-$(CONFIG_SATA_SIL3114) += sata_sil3114.o
 obj-$(CONFIG_SATA_SIL) += sata_sil.o
 obj-$(CONFIG_SANDBOX) += sata_sandbox.o
+obj-$(CONFIG_AHCI_MVEBU) += ahci_mvebu.o
diff --git a/arch/arm/mach-mvebu/sata.c b/drivers/ata/ahci_mvebu.c
similarity index 71%
rename from arch/arm/mach-mvebu/sata.c
rename to drivers/ata/ahci_mvebu.c
index 3ae8dae..6e3f17e 100644
--- a/arch/arm/mach-mvebu/sata.c
+++ b/drivers/ata/ahci_mvebu.c
@@ -16,13 +16,19 @@
 	return 0;
 }
 
-#ifdef CONFIG_ARMADA_8K
-/* CP110 has different AHCI port addresses */
-void __iomem *ahci_port_base(void __iomem *base, u32 port)
+static int mvebu_ahci_bind(struct udevice *dev)
 {
-	return base + 0x10000 + (port * 0x10000);
+	struct udevice *scsi_dev;
+	int ret;
+
+	ret = ahci_bind_scsi(dev, &scsi_dev);
+	if (ret) {
+		debug("%s: Failed to bind (err=%d\n)", __func__, ret);
+		return ret;
+	}
+
+	return 0;
 }
-#endif
 
 static int mvebu_ahci_probe(struct udevice *dev)
 {
@@ -32,7 +38,7 @@
 	 */
 	board_ahci_enable();
 
-	ahci_init(devfdt_get_addr_ptr(dev));
+	ahci_probe_scsi(dev, (ulong)devfdt_get_addr_ptr(dev));
 
 	return 0;
 }
@@ -47,5 +53,6 @@
 	.name		= "ahci_mvebu",
 	.id		= UCLASS_AHCI,
 	.of_match	= mvebu_ahci_ids,
+	.bind		= mvebu_ahci_bind,
 	.probe		= mvebu_ahci_probe,
 };
diff --git a/drivers/clk/clk_bcm6345.c b/drivers/clk/clk_bcm6345.c
index 91c86a9..f01ec9a 100644
--- a/drivers/clk/clk_bcm6345.c
+++ b/drivers/clk/clk_bcm6345.c
@@ -55,15 +55,11 @@
 static int bcm63xx_clk_probe(struct udevice *dev)
 {
 	struct bcm6345_clk_priv *priv = dev_get_priv(dev);
-	fdt_addr_t addr;
-	fdt_size_t size;
 
-	addr = devfdt_get_addr_size_index(dev, 0, &size);
-	if (addr == FDT_ADDR_T_NONE)
+	priv->regs = dev_remap_addr(dev);
+	if (!priv->regs)
 		return -EINVAL;
 
-	priv->regs = ioremap(addr, size);
-
 	return 0;
 }
 
diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig
index b5a6bcc..578e6a8 100644
--- a/drivers/clk/renesas/Kconfig
+++ b/drivers/clk/renesas/Kconfig
@@ -74,6 +74,13 @@
 	help
 	  Enable this to support the clocks on Renesas R8A77970 SoC.
 
+config CLK_R8A77990
+	bool "Renesas R8A77990 clock driver"
+	def_bool y if R8A77990
+	depends on CLK_RCAR_GEN3
+	help
+	  Enable this to support the clocks on Renesas R8A77990 SoC.
+
 config CLK_R8A77995
 	bool "Renesas R8A77995 clock driver"
 	def_bool y if R8A77995
diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile
index a65d89f..22a817a 100644
--- a/drivers/clk/renesas/Makefile
+++ b/drivers/clk/renesas/Makefile
@@ -9,4 +9,5 @@
 obj-$(CONFIG_CLK_R8A7795) += r8a7795-cpg-mssr.o
 obj-$(CONFIG_CLK_R8A7796) += r8a7796-cpg-mssr.o
 obj-$(CONFIG_CLK_R8A77970) += r8a77970-cpg-mssr.o
+obj-$(CONFIG_CLK_R8A77990) += r8a77990-cpg-mssr.o
 obj-$(CONFIG_CLK_R8A77995) += r8a77995-cpg-mssr.o
diff --git a/drivers/clk/renesas/clk-rcar-gen3.c b/drivers/clk/renesas/clk-rcar-gen3.c
index 3a95647..99698b1 100644
--- a/drivers/clk/renesas/clk-rcar-gen3.c
+++ b/drivers/clk/renesas/clk-rcar-gen3.c
@@ -85,6 +85,28 @@
 	CPG_SD_DIV_TABLE_DATA(1,        0,        4,          0,       32),
 };
 
+static int gen3_clk_get_parent(struct gen3_clk_priv *priv, struct clk *clk,
+			       struct cpg_mssr_info *info, struct clk *parent)
+{
+	const struct cpg_core_clk *core;
+	int ret;
+
+	if (!renesas_clk_is_mod(clk)) {
+		ret = renesas_clk_get_core(clk, info, &core);
+		if (ret)
+			return ret;
+
+		if (core->type == CLK_TYPE_GEN3_PE) {
+			parent->dev = clk->dev;
+			parent->id = core->parent >> (priv->sscg ? 16 : 0);
+			parent->id &= 0xffff;
+			return 0;
+		}
+	}
+
+	return renesas_clk_get_parent(clk, info, parent);
+}
+
 static int gen3_clk_setup_sdif_div(struct clk *clk)
 {
 	struct gen3_clk_priv *priv = dev_get_priv(clk->dev);
@@ -93,7 +115,7 @@
 	struct clk parent;
 	int ret;
 
-	ret = renesas_clk_get_parent(clk, info, &parent);
+	ret = gen3_clk_get_parent(priv, clk, info, &parent);
 	if (ret) {
 		printf("%s[%i] parent fail, ret=%i\n", __func__, __LINE__, ret);
 		return ret;
@@ -134,7 +156,7 @@
 	return renesas_clk_endisable(clk, priv->base, false);
 }
 
-static ulong gen3_clk_get_rate(struct clk *clk)
+static u64 gen3_clk_get_rate64(struct clk *clk)
 {
 	struct gen3_clk_priv *priv = dev_get_priv(clk->dev);
 	struct cpg_mssr_info *info = priv->info;
@@ -142,20 +164,21 @@
 	const struct cpg_core_clk *core;
 	const struct rcar_gen3_cpg_pll_config *pll_config =
 					priv->cpg_pll_config;
-	u32 value, mult, prediv, postdiv, rate = 0;
+	u32 value, mult, div, prediv, postdiv;
+	u64 rate = 0;
 	int i, ret;
 
 	debug("%s[%i] Clock: id=%lu\n", __func__, __LINE__, clk->id);
 
-	ret = renesas_clk_get_parent(clk, info, &parent);
+	ret = gen3_clk_get_parent(priv, clk, info, &parent);
 	if (ret) {
 		printf("%s[%i] parent fail, ret=%i\n", __func__, __LINE__, ret);
 		return ret;
 	}
 
 	if (renesas_clk_is_mod(clk)) {
-		rate = gen3_clk_get_rate(&parent);
-		debug("%s[%i] MOD clk: parent=%lu => rate=%u\n",
+		rate = gen3_clk_get_rate64(&parent);
+		debug("%s[%i] MOD clk: parent=%lu => rate=%llu\n",
 		      __func__, __LINE__, parent.id, rate);
 		return rate;
 	}
@@ -168,14 +191,14 @@
 	case CLK_TYPE_IN:
 		if (core->id == info->clk_extal_id) {
 			rate = clk_get_rate(&priv->clk_extal);
-			debug("%s[%i] EXTAL clk: rate=%u\n",
+			debug("%s[%i] EXTAL clk: rate=%llu\n",
 			      __func__, __LINE__, rate);
 			return rate;
 		}
 
 		if (core->id == info->clk_extalr_id) {
 			rate = clk_get_rate(&priv->clk_extalr);
-			debug("%s[%i] EXTALR clk: rate=%u\n",
+			debug("%s[%i] EXTALR clk: rate=%llu\n",
 			      __func__, __LINE__, rate);
 			return rate;
 		}
@@ -183,8 +206,8 @@
 		return -EINVAL;
 
 	case CLK_TYPE_GEN3_MAIN:
-		rate = gen3_clk_get_rate(&parent) / pll_config->extal_div;
-		debug("%s[%i] MAIN clk: parent=%i extal_div=%i => rate=%u\n",
+		rate = gen3_clk_get_rate64(&parent) / pll_config->extal_div;
+		debug("%s[%i] MAIN clk: parent=%i extal_div=%i => rate=%llu\n",
 		      __func__, __LINE__,
 		      core->parent, pll_config->extal_div, rate);
 		return rate;
@@ -192,49 +215,61 @@
 	case CLK_TYPE_GEN3_PLL0:
 		value = readl(priv->base + CPG_PLL0CR);
 		mult = (((value >> 24) & 0x7f) + 1) * 2;
-		rate = gen3_clk_get_rate(&parent) * mult;
-		debug("%s[%i] PLL0 clk: parent=%i mult=%u => rate=%u\n",
+		rate = gen3_clk_get_rate64(&parent) * mult;
+		debug("%s[%i] PLL0 clk: parent=%i mult=%u => rate=%llu\n",
 		      __func__, __LINE__, core->parent, mult, rate);
 		return rate;
 
 	case CLK_TYPE_GEN3_PLL1:
-		rate = gen3_clk_get_rate(&parent) * pll_config->pll1_mult;
-		debug("%s[%i] PLL1 clk: parent=%i mul=%i => rate=%u\n",
+		rate = gen3_clk_get_rate64(&parent) * pll_config->pll1_mult;
+		rate /= pll_config->pll1_div;
+		debug("%s[%i] PLL1 clk: parent=%i mul=%i div=%i => rate=%llu\n",
 		      __func__, __LINE__,
-		      core->parent, pll_config->pll1_mult, rate);
+		      core->parent, pll_config->pll1_mult,
+		      pll_config->pll1_div, rate);
 		return rate;
 
 	case CLK_TYPE_GEN3_PLL2:
 		value = readl(priv->base + CPG_PLL2CR);
 		mult = (((value >> 24) & 0x7f) + 1) * 2;
-		rate = gen3_clk_get_rate(&parent) * mult;
-		debug("%s[%i] PLL2 clk: parent=%i mult=%u => rate=%u\n",
+		rate = gen3_clk_get_rate64(&parent) * mult;
+		debug("%s[%i] PLL2 clk: parent=%i mult=%u => rate=%llu\n",
 		      __func__, __LINE__, core->parent, mult, rate);
 		return rate;
 
 	case CLK_TYPE_GEN3_PLL3:
-		rate = gen3_clk_get_rate(&parent) * pll_config->pll3_mult;
-		debug("%s[%i] PLL3 clk: parent=%i mul=%i => rate=%u\n",
+		rate = gen3_clk_get_rate64(&parent) * pll_config->pll3_mult;
+		rate /= pll_config->pll3_div;
+		debug("%s[%i] PLL3 clk: parent=%i mul=%i div=%i => rate=%llu\n",
 		      __func__, __LINE__,
-		      core->parent, pll_config->pll3_mult, rate);
+		      core->parent, pll_config->pll3_mult,
+		      pll_config->pll3_div, rate);
 		return rate;
 
 	case CLK_TYPE_GEN3_PLL4:
 		value = readl(priv->base + CPG_PLL4CR);
 		mult = (((value >> 24) & 0x7f) + 1) * 2;
-		rate = gen3_clk_get_rate(&parent) * mult;
-		debug("%s[%i] PLL4 clk: parent=%i mult=%u => rate=%u\n",
+		rate = gen3_clk_get_rate64(&parent) * mult;
+		debug("%s[%i] PLL4 clk: parent=%i mult=%u => rate=%llu\n",
 		      __func__, __LINE__, core->parent, mult, rate);
 		return rate;
 
 	case CLK_TYPE_FF:
-	case CLK_TYPE_GEN3_PE:		/* FIXME */
-		rate = (gen3_clk_get_rate(&parent) * core->mult) / core->div;
-		debug("%s[%i] FIXED clk: parent=%i div=%i mul=%i => rate=%u\n",
+		rate = (gen3_clk_get_rate64(&parent) * core->mult) / core->div;
+		debug("%s[%i] FIXED clk: parent=%i mul=%i div=%i => rate=%llu\n",
 		      __func__, __LINE__,
 		      core->parent, core->mult, core->div, rate);
 		return rate;
 
+	case CLK_TYPE_GEN3_PE:
+		div = (core->div >> (priv->sscg ? 16 : 0)) & 0xffff;
+		rate = gen3_clk_get_rate64(&parent) / div;
+		debug("%s[%i] PE clk: parent=%i div=%u => rate=%llu\n",
+		      __func__, __LINE__,
+		      (core->parent >> (priv->sscg ? 16 : 0)) & 0xffff,
+		      div, rate);
+		return rate;
+
 	case CLK_TYPE_GEN3_SD:		/* FIXME */
 		value = readl(priv->base + core->offset);
 		value &= CPG_SD_STP_MASK | CPG_SD_FC_MASK;
@@ -243,9 +278,9 @@
 			if (cpg_sd_div_table[i].val != value)
 				continue;
 
-			rate = gen3_clk_get_rate(&parent) /
+			rate = gen3_clk_get_rate64(&parent) /
 			       cpg_sd_div_table[i].div;
-			debug("%s[%i] SD clk: parent=%i div=%i => rate=%u\n",
+			debug("%s[%i] SD clk: parent=%i div=%i => rate=%llu\n",
 			      __func__, __LINE__,
 			      core->parent, cpg_sd_div_table[i].div, rate);
 
@@ -255,7 +290,7 @@
 		return -EINVAL;
 
 	case CLK_TYPE_GEN3_RPC:
-		rate = gen3_clk_get_rate(&parent);
+		rate = gen3_clk_get_rate64(&parent);
 
 		value = readl(priv->base + core->offset);
 
@@ -272,7 +307,7 @@
 			  CPG_RPC_POSTDIV_MASK;
 		rate /= postdiv + 1;
 
-		debug("%s[%i] RPC clk: parent=%i prediv=%i postdiv=%i => rate=%u\n",
+		debug("%s[%i] RPC clk: parent=%i prediv=%i postdiv=%i => rate=%llu\n",
 		      __func__, __LINE__,
 		      core->parent, prediv, postdiv, rate);
 
@@ -285,11 +320,16 @@
 	return -ENOENT;
 }
 
+static ulong gen3_clk_get_rate(struct clk *clk)
+{
+	return gen3_clk_get_rate64(clk);
+}
+
 static ulong gen3_clk_set_rate(struct clk *clk, ulong rate)
 {
 	/* Force correct SD-IF divider configuration if applicable */
 	gen3_clk_setup_sdif_div(clk);
-	return gen3_clk_get_rate(clk);
+	return gen3_clk_get_rate64(clk);
 }
 
 static int gen3_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
@@ -341,6 +381,8 @@
 	if (!priv->cpg_pll_config->extal_div)
 		return -EINVAL;
 
+	priv->sscg = !(cpg_mode & BIT(12));
+
 	ret = clk_get_by_name(dev, "extal", &priv->clk_extal);
 	if (ret < 0)
 		return ret;
diff --git a/drivers/clk/renesas/r8a77990-cpg-mssr.c b/drivers/clk/renesas/r8a77990-cpg-mssr.c
new file mode 100644
index 0000000..b3614a1
--- /dev/null
+++ b/drivers/clk/renesas/r8a77990-cpg-mssr.c
@@ -0,0 +1,302 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Renesas R8A77990 CPG MSSR driver
+ *
+ * Copyright (C) 2017-2018 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * Based on the following driver from Linux kernel:
+ * r8a7796 Clock Pulse Generator / Module Standby and Software Reset
+ *
+ * Copyright (C) 2016 Glider bvba
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+
+#include <dt-bindings/clock/r8a77990-cpg-mssr.h>
+
+#include "renesas-cpg-mssr.h"
+#include "rcar-gen3-cpg.h"
+
+enum clk_ids {
+	/* Core Clock Outputs exported to DT */
+	LAST_DT_CORE_CLK = R8A77990_CLK_CPEX,
+
+	/* External Input Clocks */
+	CLK_EXTAL,
+
+	/* Internal Core Clocks */
+	CLK_MAIN,
+	CLK_PLL0,
+	CLK_PLL1,
+	CLK_PLL3,
+	CLK_PLL0D4,
+	CLK_PLL0D6,
+	CLK_PLL0D8,
+	CLK_PLL0D20,
+	CLK_PLL0D24,
+	CLK_PLL1D2,
+	CLK_PE,
+	CLK_S0,
+	CLK_S1,
+	CLK_S2,
+	CLK_S3,
+	CLK_SDSRC,
+
+	/* Module Clocks */
+	MOD_CLK_BASE
+};
+
+static const struct cpg_core_clk r8a77990_core_clks[] = {
+	/* External Clock Inputs */
+	DEF_INPUT("extal",     CLK_EXTAL),
+
+	/* Internal Core Clocks */
+	DEF_BASE(".main",      CLK_MAIN, CLK_TYPE_GEN3_MAIN,       CLK_EXTAL),
+	DEF_BASE(".pll1",      CLK_PLL1, CLK_TYPE_GEN3_PLL1,       CLK_MAIN),
+	DEF_BASE(".pll3",      CLK_PLL3, CLK_TYPE_GEN3_PLL3,       CLK_MAIN),
+
+	DEF_FIXED(".pll0",     CLK_PLL0,           CLK_MAIN,	   1, 100),
+	DEF_FIXED(".pll0d4",   CLK_PLL0D4,         CLK_PLL0,       4, 1),
+	DEF_FIXED(".pll0d6",   CLK_PLL0D6,         CLK_PLL0,       6, 1),
+	DEF_FIXED(".pll0d8",   CLK_PLL0D8,         CLK_PLL0,       8, 1),
+	DEF_FIXED(".pll0d20",  CLK_PLL0D20,        CLK_PLL0,      20, 1),
+	DEF_FIXED(".pll0d24",  CLK_PLL0D24,        CLK_PLL0,      24, 1),
+	DEF_FIXED(".pll1d2",   CLK_PLL1D2,         CLK_PLL1,       2, 1),
+	DEF_FIXED(".pe",       CLK_PE,             CLK_PLL0D20,    1, 1),
+	DEF_FIXED(".s0",       CLK_S0,             CLK_PLL1,       2, 1),
+	DEF_FIXED(".s1",       CLK_S1,             CLK_PLL1,       3, 1),
+	DEF_FIXED(".s2",       CLK_S2,             CLK_PLL1,       4, 1),
+	DEF_FIXED(".s3",       CLK_S3,             CLK_PLL1,       6, 1),
+	DEF_FIXED(".sdsrc",    CLK_SDSRC,          CLK_PLL1,       2, 1),
+
+	/* Core Clock Outputs */
+	DEF_FIXED("za2",       R8A77990_CLK_ZA2,   CLK_PLL0D24,    1, 1),
+	DEF_FIXED("za8",       R8A77990_CLK_ZA8,   CLK_PLL0D8,     1, 1),
+	DEF_FIXED("ztr",       R8A77990_CLK_ZTR,   CLK_PLL1,       6, 1),
+	DEF_FIXED("zt",        R8A77990_CLK_ZT,    CLK_PLL1,       4, 1),
+	DEF_FIXED("zx",        R8A77990_CLK_ZX,    CLK_PLL1,       3, 1),
+	DEF_FIXED("s0d1",      R8A77990_CLK_S0D1,  CLK_S0,         1, 1),
+	DEF_FIXED("s0d3",      R8A77990_CLK_S0D3,  CLK_S0,         3, 1),
+	DEF_FIXED("s0d6",      R8A77990_CLK_S0D6,  CLK_S0,         6, 1),
+	DEF_FIXED("s0d12",     R8A77990_CLK_S0D12, CLK_S0,        12, 1),
+	DEF_FIXED("s0d24",     R8A77990_CLK_S0D24, CLK_S0,        24, 1),
+	DEF_FIXED("s1d1",      R8A77990_CLK_S1D1,  CLK_S1,         1, 1),
+	DEF_FIXED("s1d2",      R8A77990_CLK_S1D2,  CLK_S1,         2, 1),
+	DEF_FIXED("s1d4",      R8A77990_CLK_S1D4,  CLK_S1,         4, 1),
+	DEF_FIXED("s2d1",      R8A77990_CLK_S2D1,  CLK_S2,         1, 1),
+	DEF_FIXED("s2d2",      R8A77990_CLK_S2D2,  CLK_S2,         2, 1),
+	DEF_FIXED("s2d4",      R8A77990_CLK_S2D4,  CLK_S2,         4, 1),
+	DEF_FIXED("s3d1",      R8A77990_CLK_S3D1,  CLK_S3,         1, 1),
+	DEF_FIXED("s3d2",      R8A77990_CLK_S3D2,  CLK_S3,         2, 1),
+	DEF_FIXED("s3d4",      R8A77990_CLK_S3D4,  CLK_S3,         4, 1),
+
+	DEF_GEN3_SD("sd0",     R8A77990_CLK_SD0,   CLK_SDSRC,	  0x0074),
+	DEF_GEN3_SD("sd1",     R8A77990_CLK_SD1,   CLK_SDSRC,	  0x0078),
+	DEF_GEN3_SD("sd3",     R8A77990_CLK_SD3,   CLK_SDSRC,	  0x026c),
+
+	DEF_FIXED("cl",        R8A77990_CLK_CL,    CLK_PLL1,      48, 1),
+	DEF_FIXED("cp",        R8A77990_CLK_CP,    CLK_EXTAL,      2, 1),
+	DEF_FIXED("cpex",      R8A77990_CLK_CPEX,  CLK_EXTAL,      4, 1),
+	DEF_FIXED("osc",       R8A77990_CLK_OSC,   CLK_EXTAL,    384, 1),
+	DEF_FIXED("r",         R8A77990_CLK_R,     CLK_EXTAL,   1536, 1),
+
+	DEF_GEN3_PE("s0d6c",   R8A77990_CLK_S0D6C, CLK_S0, 6, CLK_PE, 6),
+	DEF_GEN3_PE("s3d1c",   R8A77990_CLK_S3D1C, CLK_S3, 1, CLK_PE, 1),
+	DEF_GEN3_PE("s3d2c",   R8A77990_CLK_S3D2C, CLK_S3, 2, CLK_PE, 2),
+	DEF_GEN3_PE("s3d4c",   R8A77990_CLK_S3D4C, CLK_S3, 4, CLK_PE, 4),
+
+	DEF_DIV6P1("canfd",    R8A77990_CLK_CANFD, CLK_PLL0D6, 0x244),
+	DEF_DIV6P1("csi0",     R8A77990_CLK_CSI0,  CLK_PLL1D2, 0x00c),
+	DEF_DIV6P1("mso",      R8A77990_CLK_MSO,   CLK_PLL1D2, 0x014),
+};
+
+static const struct mssr_mod_clk r8a77990_mod_clks[] = {
+	DEF_MOD("scif5",		 202,	R8A77990_CLK_S3D4C),
+	DEF_MOD("scif4",		 203,	R8A77990_CLK_S3D4C),
+	DEF_MOD("scif3",		 204,	R8A77990_CLK_S3D4C),
+	DEF_MOD("scif1",		 206,	R8A77990_CLK_S3D4C),
+	DEF_MOD("scif0",		 207,	R8A77990_CLK_S3D4C),
+	DEF_MOD("msiof3",		 208,	R8A77990_CLK_MSO),
+	DEF_MOD("msiof2",		 209,	R8A77990_CLK_MSO),
+	DEF_MOD("msiof1",		 210,	R8A77990_CLK_MSO),
+	DEF_MOD("msiof0",		 211,	R8A77990_CLK_MSO),
+	DEF_MOD("sys-dmac2",		 217,	R8A77990_CLK_S3D1),
+	DEF_MOD("sys-dmac1",		 218,	R8A77990_CLK_S3D1),
+	DEF_MOD("sys-dmac0",		 219,	R8A77990_CLK_S3D1),
+
+	DEF_MOD("cmt3",			 300,	R8A77990_CLK_R),
+	DEF_MOD("cmt2",			 301,	R8A77990_CLK_R),
+	DEF_MOD("cmt1",			 302,	R8A77990_CLK_R),
+	DEF_MOD("cmt0",			 303,	R8A77990_CLK_R),
+	DEF_MOD("scif2",		 310,	R8A77990_CLK_S3D4C),
+	DEF_MOD("sdif3",		 311,	R8A77990_CLK_SD3),
+	DEF_MOD("sdif1",		 313,	R8A77990_CLK_SD1),
+	DEF_MOD("sdif0",		 314,	R8A77990_CLK_SD0),
+	DEF_MOD("pcie0",		 319,	R8A77990_CLK_S3D1),
+	DEF_MOD("usb3-if0",		 328,	R8A77990_CLK_S3D1),
+	DEF_MOD("usb-dmac0",		 330,	R8A77990_CLK_S3D1),
+	DEF_MOD("usb-dmac1",		 331,	R8A77990_CLK_S3D1),
+
+	DEF_MOD("rwdt",			 402,	R8A77990_CLK_R),
+	DEF_MOD("intc-ex",		 407,	R8A77990_CLK_CP),
+	DEF_MOD("intc-ap",		 408,	R8A77990_CLK_S0D3),
+
+	DEF_MOD("audmac0",		 502,	R8A77990_CLK_S3D4),
+	DEF_MOD("drif7",		 508,	R8A77990_CLK_S3D2),
+	DEF_MOD("drif6",		 509,	R8A77990_CLK_S3D2),
+	DEF_MOD("drif5",		 510,	R8A77990_CLK_S3D2),
+	DEF_MOD("drif4",		 511,	R8A77990_CLK_S3D2),
+	DEF_MOD("drif3",		 512,	R8A77990_CLK_S3D2),
+	DEF_MOD("drif2",		 513,	R8A77990_CLK_S3D2),
+	DEF_MOD("drif1",		 514,	R8A77990_CLK_S3D2),
+	DEF_MOD("drif0",		 515,	R8A77990_CLK_S3D2),
+	DEF_MOD("hscif4",		 516,	R8A77990_CLK_S3D1C),
+	DEF_MOD("hscif3",		 517,	R8A77990_CLK_S3D1C),
+	DEF_MOD("hscif2",		 518,	R8A77990_CLK_S3D1C),
+	DEF_MOD("hscif1",		 519,	R8A77990_CLK_S3D1C),
+	DEF_MOD("hscif0",		 520,	R8A77990_CLK_S3D1C),
+	DEF_MOD("thermal",		 522,	R8A77990_CLK_CP),
+	DEF_MOD("pwm",			 523,	R8A77990_CLK_S3D4C),
+
+	DEF_MOD("fcpvd1",		 602,	R8A77990_CLK_S1D2),
+	DEF_MOD("fcpvd0",		 603,	R8A77990_CLK_S1D2),
+	DEF_MOD("fcpvb0",		 607,	R8A77990_CLK_S0D1),
+	DEF_MOD("fcpvi0",		 611,	R8A77990_CLK_S0D1),
+	DEF_MOD("fcpf0",		 615,	R8A77990_CLK_S0D1),
+	DEF_MOD("fcpcs",		 619,	R8A77990_CLK_S0D1),
+	DEF_MOD("vspd1",		 622,	R8A77990_CLK_S1D2),
+	DEF_MOD("vspd0",		 623,	R8A77990_CLK_S1D2),
+	DEF_MOD("vspb",			 626,	R8A77990_CLK_S0D1),
+	DEF_MOD("vspi0",		 631,	R8A77990_CLK_S0D1),
+
+	DEF_MOD("ehci0",		 703,	R8A77990_CLK_S3D4),
+	DEF_MOD("hsusb",		 704,	R8A77990_CLK_S3D4),
+	DEF_MOD("csi40",		 716,	R8A77990_CLK_CSI0),
+	DEF_MOD("du1",			 723,	R8A77990_CLK_S2D1),
+	DEF_MOD("du0",			 724,	R8A77990_CLK_S2D1),
+	DEF_MOD("lvds",			 727,	R8A77990_CLK_S2D1),
+
+	DEF_MOD("vin7",			 804,	R8A77990_CLK_S1D2),
+	DEF_MOD("vin6",			 805,	R8A77990_CLK_S1D2),
+	DEF_MOD("vin5",			 806,	R8A77990_CLK_S1D2),
+	DEF_MOD("vin4",			 807,	R8A77990_CLK_S1D2),
+	DEF_MOD("etheravb",		 812,	R8A77990_CLK_S3D2),
+
+	DEF_MOD("gpio6",		 906,	R8A77990_CLK_S3D4),
+	DEF_MOD("gpio5",		 907,	R8A77990_CLK_S3D4),
+	DEF_MOD("gpio4",		 908,	R8A77990_CLK_S3D4),
+	DEF_MOD("gpio3",		 909,	R8A77990_CLK_S3D4),
+	DEF_MOD("gpio2",		 910,	R8A77990_CLK_S3D4),
+	DEF_MOD("gpio1",		 911,	R8A77990_CLK_S3D4),
+	DEF_MOD("gpio0",		 912,	R8A77990_CLK_S3D4),
+	DEF_MOD("can-fd",		 914,	R8A77990_CLK_S3D2),
+	DEF_MOD("can-if1",		 915,	R8A77990_CLK_S3D4),
+	DEF_MOD("can-if0",		 916,	R8A77990_CLK_S3D4),
+	DEF_MOD("i2c6",			 918,	R8A77990_CLK_S3D2),
+	DEF_MOD("i2c5",			 919,	R8A77990_CLK_S3D2),
+	DEF_MOD("i2c-dvfs",		 926,	R8A77990_CLK_CP),
+	DEF_MOD("i2c4",			 927,	R8A77990_CLK_S3D2),
+	DEF_MOD("i2c3",			 928,	R8A77990_CLK_S3D2),
+	DEF_MOD("i2c2",			 929,	R8A77990_CLK_S3D2),
+	DEF_MOD("i2c1",			 930,	R8A77990_CLK_S3D2),
+	DEF_MOD("i2c0",			 931,	R8A77990_CLK_S3D2),
+
+	DEF_MOD("ssi-all",		1005,	R8A77990_CLK_S3D4),
+	DEF_MOD("ssi9",			1006,	MOD_CLK_ID(1005)),
+	DEF_MOD("ssi8",			1007,	MOD_CLK_ID(1005)),
+	DEF_MOD("ssi7",			1008,	MOD_CLK_ID(1005)),
+	DEF_MOD("ssi6",			1009,	MOD_CLK_ID(1005)),
+	DEF_MOD("ssi5",			1010,	MOD_CLK_ID(1005)),
+	DEF_MOD("ssi4",			1011,	MOD_CLK_ID(1005)),
+	DEF_MOD("ssi3",			1012,	MOD_CLK_ID(1005)),
+	DEF_MOD("ssi2",			1013,	MOD_CLK_ID(1005)),
+	DEF_MOD("ssi1",			1014,	MOD_CLK_ID(1005)),
+	DEF_MOD("ssi0",			1015,	MOD_CLK_ID(1005)),
+	DEF_MOD("scu-all",		1017,	R8A77990_CLK_S3D4),
+	DEF_MOD("scu-dvc1",		1018,	MOD_CLK_ID(1017)),
+	DEF_MOD("scu-dvc0",		1019,	MOD_CLK_ID(1017)),
+	DEF_MOD("scu-ctu1-mix1",	1020,	MOD_CLK_ID(1017)),
+	DEF_MOD("scu-ctu0-mix0",	1021,	MOD_CLK_ID(1017)),
+	DEF_MOD("scu-src9",		1022,	MOD_CLK_ID(1017)),
+	DEF_MOD("scu-src8",		1023,	MOD_CLK_ID(1017)),
+	DEF_MOD("scu-src7",		1024,	MOD_CLK_ID(1017)),
+	DEF_MOD("scu-src6",		1025,	MOD_CLK_ID(1017)),
+	DEF_MOD("scu-src5",		1026,	MOD_CLK_ID(1017)),
+	DEF_MOD("scu-src4",		1027,	MOD_CLK_ID(1017)),
+	DEF_MOD("scu-src3",		1028,	MOD_CLK_ID(1017)),
+	DEF_MOD("scu-src2",		1029,	MOD_CLK_ID(1017)),
+	DEF_MOD("scu-src1",		1030,	MOD_CLK_ID(1017)),
+	DEF_MOD("scu-src0",		1031,	MOD_CLK_ID(1017)),
+};
+
+/*
+ * CPG Clock Data
+ */
+
+/*
+ * MD19		EXTAL (MHz)	PLL0		PLL1		PLL3
+ *--------------------------------------------------------------------
+ * 0		48 x 1		x100/4		x100/3		x100/3
+ * 1		48 x 1		x100/4		x100/3		 x58/3
+ */
+#define CPG_PLL_CONFIG_INDEX(md)	(((md) & BIT(19)) >> 19)
+
+static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[2] = {
+	/* EXTAL div	PLL1 mult/div	PLL3 mult/div */
+	{ 1,		100,	3,	100,	3,	},
+	{ 1,		100,	3,	 58,	3,	},
+};
+
+static const struct mstp_stop_table r8a77990_mstp_table[] = {
+	{ 0x00200000, 0x0, 0x00200000, 0 },
+	{ 0xFFFFFFFF, 0x0, 0xFFFFFFFF, 0 },
+	{ 0x340E2FDC, 0x2040, 0x340E2FDC, 0 },
+	{ 0xFFFFFFDF, 0x400, 0xFFFFFFDF, 0 },
+	{ 0x80000184, 0x180, 0x80000184, 0 },
+	{ 0xC3FFFFFF, 0x0, 0xC3FFFFFF, 0 },
+	{ 0xFFFFFFFF, 0x0, 0xFFFFFFFF, 0 },
+	{ 0xFFFFFFFF, 0x0, 0xFFFFFFFF, 0 },
+	{ 0x01F1FFF7, 0x0, 0x01F1FFF7, 0 },
+	{ 0xFFFFFFFE, 0x0, 0xFFFFFFFE, 0 },
+	{ 0xFFFEFFE0, 0x0, 0xFFFEFFE0, 0 },
+	{ 0x000000B7, 0x0, 0x000000B7, 0 },
+};
+
+static const void *r8a77990_get_pll_config(const u32 cpg_mode)
+{
+	return &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
+}
+
+static const struct cpg_mssr_info r8a77990_cpg_mssr_info = {
+	.core_clk		= r8a77990_core_clks,
+	.core_clk_size		= ARRAY_SIZE(r8a77990_core_clks),
+	.mod_clk		= r8a77990_mod_clks,
+	.mod_clk_size		= ARRAY_SIZE(r8a77990_mod_clks),
+	.mstp_table		= r8a77990_mstp_table,
+	.mstp_table_size	= ARRAY_SIZE(r8a77990_mstp_table),
+	.reset_node		= "renesas,r8a77990-rst",
+	.mod_clk_base		= MOD_CLK_BASE,
+	.clk_extal_id		= CLK_EXTAL,
+	.clk_extalr_id		= ~0,
+	.get_pll_config		= r8a77990_get_pll_config,
+};
+
+static const struct udevice_id r8a77990_clk_ids[] = {
+	{
+		.compatible	= "renesas,r8a77990-cpg-mssr",
+		.data		= (ulong)&r8a77990_cpg_mssr_info
+	},
+	{ }
+};
+
+U_BOOT_DRIVER(clk_r8a77990) = {
+	.name		= "clk_r8a77990",
+	.id		= UCLASS_CLK,
+	.of_match	= r8a77990_clk_ids,
+	.priv_auto_alloc_size = sizeof(struct gen3_clk_priv),
+	.ops		= &gen3_clk_ops,
+	.probe		= gen3_clk_probe,
+	.remove		= gen3_clk_remove,
+};
diff --git a/drivers/clk/renesas/rcar-gen3-cpg.h b/drivers/clk/renesas/rcar-gen3-cpg.h
index 2f410df..58e71f3 100644
--- a/drivers/clk/renesas/rcar-gen3-cpg.h
+++ b/drivers/clk/renesas/rcar-gen3-cpg.h
@@ -31,8 +31,9 @@
 	DEF_BASE(_name, _id, CLK_TYPE_GEN3_RPC, _parent, .offset = _offset)
 #define DEF_GEN3_PE(_name, _id, _parent_sscg, _div_sscg, _parent_clean, \
 		    _div_clean) \
-	DEF_BASE(_name, _id, CLK_TYPE_FF,			\
-		 (_parent_clean), .div = (_div_clean), 1)
+	DEF_BASE(_name, _id, CLK_TYPE_GEN3_PE,			\
+		 (_parent_sscg) << 16 | (_parent_clean),	\
+		 .div = (_div_sscg) << 16 | (_div_clean))
 
 struct rcar_gen3_cpg_pll_config {
 	u8 extal_div;
@@ -49,6 +50,7 @@
 	struct cpg_mssr_info	*info;
 	struct clk		clk_extal;
 	struct clk		clk_extalr;
+	bool			sscg;
 	const struct rcar_gen3_cpg_pll_config *cpg_pll_config;
 };
 
diff --git a/drivers/core/fdtaddr.c b/drivers/core/fdtaddr.c
index 528cf47..f8cdbd6 100644
--- a/drivers/core/fdtaddr.c
+++ b/drivers/core/fdtaddr.c
@@ -136,6 +136,21 @@
 	return (void *)(uintptr_t)devfdt_get_addr_index(dev, 0);
 }
 
+void *devfdt_remap_addr_index(struct udevice *dev, int index)
+{
+	fdt_addr_t addr = devfdt_get_addr(dev);
+
+	if (addr == FDT_ADDR_T_NONE)
+		return NULL;
+
+	return map_physmem(addr, 0, MAP_NOCACHE);
+}
+
+void *devfdt_remap_addr(struct udevice *dev)
+{
+	return devfdt_remap_addr_index(dev, 0);
+}
+
 void *devfdt_map_physmem(struct udevice *dev, unsigned long size)
 {
 	fdt_addr_t addr = devfdt_get_addr(dev);
diff --git a/drivers/core/read.c b/drivers/core/read.c
index 0322cbf..96766c7 100644
--- a/drivers/core/read.c
+++ b/drivers/core/read.c
@@ -4,6 +4,8 @@
  * Written by Simon Glass <sjg@chromium.org>
  */
 
+#include <asm/types.h>
+#include <asm/io.h>
 #include <common.h>
 #include <dm.h>
 #include <mapmem.h>
@@ -57,6 +59,16 @@
 		return devfdt_get_addr_index(dev, index);
 }
 
+void *dev_remap_addr_index(struct udevice *dev, int index)
+{
+	fdt_addr_t addr = dev_read_addr_index(dev, index);
+
+	if (addr == FDT_ADDR_T_NONE)
+		return NULL;
+
+	return map_physmem(addr, 0, MAP_NOCACHE);
+}
+
 fdt_addr_t dev_read_addr(struct udevice *dev)
 {
 	return dev_read_addr_index(dev, 0);
@@ -69,6 +81,11 @@
 	return (addr == FDT_ADDR_T_NONE) ? NULL : map_sysmem(addr, 0);
 }
 
+void *dev_remap_addr(struct udevice *dev)
+{
+	return dev_remap_addr_index(dev, 0);
+}
+
 fdt_addr_t dev_read_addr_size(struct udevice *dev, const char *property,
 			      fdt_size_t *sizep)
 {
diff --git a/drivers/cpu/bmips_cpu.c b/drivers/cpu/bmips_cpu.c
index 7ed4bc7..f5bacd2 100644
--- a/drivers/cpu/bmips_cpu.c
+++ b/drivers/cpu/bmips_cpu.c
@@ -13,8 +13,6 @@
 #include <errno.h>
 #include <asm/io.h>
 
-DECLARE_GLOBAL_DATA_PTR;
-
 #define REV_CHIPID_SHIFT		16
 #define REV_CHIPID_MASK			(0xffff << REV_CHIPID_SHIFT)
 #define REV_LONG_CHIPID_SHIFT		12
@@ -397,8 +395,7 @@
 {
 	struct cpu_platdata *plat = dev_get_parent_platdata(dev);
 
-	plat->cpu_id = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
-		"reg", -1);
+	plat->cpu_id = dev_read_u32_default(dev, "reg", -1);
 	plat->device_id = read_c0_prid();
 
 	return 0;
@@ -409,14 +406,11 @@
 	struct bmips_cpu_priv *priv = dev_get_priv(dev);
 	const struct bmips_cpu_hw *hw =
 		(const struct bmips_cpu_hw *)dev_get_driver_data(dev);
-	fdt_addr_t addr;
-	fdt_size_t size;
 
-	addr = devfdt_get_addr_size_index(dev_get_parent(dev), 0, &size);
-	if (addr == FDT_ADDR_T_NONE)
+	priv->regs = dev_remap_addr(dev);
+	if (!priv->regs)
 		return -EINVAL;
 
-	priv->regs = ioremap(addr, size);
 	priv->hw = hw;
 
 	return 0;
diff --git a/cmd/fastboot/Kconfig b/drivers/fastboot/Kconfig
similarity index 78%
rename from cmd/fastboot/Kconfig
rename to drivers/fastboot/Kconfig
index 0d2c2f1..bc25ea1 100644
--- a/cmd/fastboot/Kconfig
+++ b/drivers/fastboot/Kconfig
@@ -1,32 +1,27 @@
-comment "FASTBOOT"
+menu "Fastboot support"
 
-menuconfig FASTBOOT
-	bool "Fastboot support"
-	depends on USB_GADGET
-	default y if ARCH_SUNXI && USB_MUSB_GADGET
-
-if FASTBOOT
+config FASTBOOT
+	bool
+	imply ANDROID_BOOT_IMAGE
+	imply CMD_FASTBOOT
 
 config USB_FUNCTION_FASTBOOT
 	bool "Enable USB fastboot gadget"
-	default y
+	depends on USB_GADGET
+	default y if ARCH_SUNXI && USB_MUSB_GADGET
+	select FASTBOOT
 	select USB_GADGET_DOWNLOAD
-	imply ANDROID_BOOT_IMAGE
-	imply CMD_FASTBOOT
 	help
 	  This enables the USB part of the fastboot gadget.
 
-config CMD_FASTBOOT
-	bool "Enable FASTBOOT command"
+config UDP_FUNCTION_FASTBOOT
+	depends on NET
+	select FASTBOOT
+	bool "Enable fastboot protocol over UDP"
 	help
-	  This enables the command "fastboot" which enables the Android
-	  fastboot mode for the platform's USB device. Fastboot is a USB
-	  protocol for downloading images, flashing and device control
-	  used on Android devices.
+	  This enables the fastboot protocol over UDP.
 
-	  See doc/README.android-fastboot for more information.
-
-if USB_FUNCTION_FASTBOOT
+if FASTBOOT
 
 config FASTBOOT_BUF_ADDR
 	hex "Define FASTBOOT buffer address"
@@ -58,6 +53,7 @@
 
 config FASTBOOT_USB_DEV
 	int "USB controller number"
+	depends on USB_FUNCTION_FASTBOOT
 	default 0
 	help
 	  Some boards have USB OTG controller other than 0. Define this
@@ -67,6 +63,8 @@
 config FASTBOOT_FLASH
 	bool "Enable FASTBOOT FLASH command"
 	default y if ARCH_SUNXI
+	depends on MMC || (NAND && CMD_MTDPARTS)
+	select IMAGE_SPARSE
 	help
 	  The fastboot protocol includes a "flash" command for writing
 	  the downloaded image to a non-volatile storage device. Define
@@ -82,7 +80,7 @@
 
 config FASTBOOT_FLASH_NAND
 	bool "FASTBOOT on NAND"
-	depends on NAND
+	depends on NAND && CMD_MTDPARTS
 
 endchoice
 
@@ -96,19 +94,16 @@
 	  regarding the non-volatile storage device. Define this to
 	  the eMMC device that fastboot should use to store the image.
 
-config FASTBOOT_FLASH_NAND_DEV
-	int "Define FASTBOOT NAND FLASH default device"
+config FASTBOOT_FLASH_NAND_TRIMFFS
+	bool "Skip empty pages when flashing NAND"
 	depends on FASTBOOT_FLASH_NAND
-	depends on CMD_MTDPARTS
-	default 0 if ARCH_SUNXI && NAND_SUNXI
 	help
-	  The fastboot "flash" command requires additional information
-	  regarding the non-volatile storage device. Define this to
-	  the NAND device that fastboot should use to store the image.
+	  When flashing NAND enable the DROP_FFS flag to drop trailing all-0xff
+	  pages.
 
 config FASTBOOT_GPT_NAME
 	string "Target name for updating GPT"
-	depends on FASTBOOT_FLASH
+	depends on FASTBOOT_FLASH_MMC && EFI_PARTITION
 	default "gpt"
 	help
 	  The fastboot "flash" command supports writing the downloaded
@@ -121,7 +116,7 @@
 
 config FASTBOOT_MBR_NAME
 	string "Target name for updating MBR"
-	depends on FASTBOOT_FLASH
+	depends on FASTBOOT_FLASH_MMC && DOS_PARTITION
 	default "mbr"
 	help
 	  The fastboot "flash" command allows to write the downloaded image
@@ -129,6 +124,14 @@
 	  specified on the "fastboot flash" command line matches the value
 	  defined here. The default target name for updating MBR is "mbr".
 
-endif # USB_FUNCTION_FASTBOOT
+config FASTBOOT_CMD_OEM_FORMAT
+	bool "Enable the 'oem format' command"
+	depends on FASTBOOT_FLASH_MMC && CMD_GPT
+	help
+	  Add support for the "oem format" command from a client. This
+	  relies on the env variable partitions to contain the list of
+	  partitions as required by the gpt command.
 
 endif # FASTBOOT
+
+endmenu
diff --git a/drivers/fastboot/Makefile b/drivers/fastboot/Makefile
new file mode 100644
index 0000000..a242156
--- /dev/null
+++ b/drivers/fastboot/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier:      GPL-2.0+
+
+obj-y += fb_common.o
+obj-y += fb_getvar.o
+obj-y += fb_command.o
+obj-$(CONFIG_FASTBOOT_FLASH_MMC) += fb_mmc.o
+obj-$(CONFIG_FASTBOOT_FLASH_NAND) += fb_nand.o
diff --git a/drivers/fastboot/fb_command.c b/drivers/fastboot/fb_command.c
new file mode 100644
index 0000000..200f991
--- /dev/null
+++ b/drivers/fastboot/fb_command.c
@@ -0,0 +1,335 @@
+// SPDX-License-Identifier: BSD-2-Clause
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ */
+
+#include <common.h>
+#include <fastboot.h>
+#include <fastboot-internal.h>
+#include <fb_mmc.h>
+#include <fb_nand.h>
+#include <part.h>
+#include <stdlib.h>
+
+/**
+ * image_size - final fastboot image size
+ */
+static u32 image_size;
+
+/**
+ * fastboot_bytes_received - number of bytes received in the current download
+ */
+static u32 fastboot_bytes_received;
+
+/**
+ * fastboot_bytes_expected - number of bytes expected in the current download
+ */
+static u32 fastboot_bytes_expected;
+
+static void okay(char *, char *);
+static void getvar(char *, char *);
+static void download(char *, char *);
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
+static void flash(char *, char *);
+static void erase(char *, char *);
+#endif
+static void reboot_bootloader(char *, char *);
+#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
+static void oem_format(char *, char *);
+#endif
+
+static const struct {
+	const char *command;
+	void (*dispatch)(char *cmd_parameter, char *response);
+} commands[FASTBOOT_COMMAND_COUNT] = {
+	[FASTBOOT_COMMAND_GETVAR] = {
+		.command = "getvar",
+		.dispatch = getvar
+	},
+	[FASTBOOT_COMMAND_DOWNLOAD] = {
+		.command = "download",
+		.dispatch = download
+	},
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
+	[FASTBOOT_COMMAND_FLASH] =  {
+		.command = "flash",
+		.dispatch = flash
+	},
+	[FASTBOOT_COMMAND_ERASE] =  {
+		.command = "erase",
+		.dispatch = erase
+	},
+#endif
+	[FASTBOOT_COMMAND_BOOT] =  {
+		.command = "boot",
+		.dispatch = okay
+	},
+	[FASTBOOT_COMMAND_CONTINUE] =  {
+		.command = "continue",
+		.dispatch = okay
+	},
+	[FASTBOOT_COMMAND_REBOOT] =  {
+		.command = "reboot",
+		.dispatch = okay
+	},
+	[FASTBOOT_COMMAND_REBOOT_BOOTLOADER] =  {
+		.command = "reboot-bootloader",
+		.dispatch = reboot_bootloader
+	},
+	[FASTBOOT_COMMAND_SET_ACTIVE] =  {
+		.command = "set_active",
+		.dispatch = okay
+	},
+#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
+	[FASTBOOT_COMMAND_OEM_FORMAT] = {
+		.command = "oem format",
+		.dispatch = oem_format,
+	},
+#endif
+};
+
+/**
+ * fastboot_handle_command - Handle fastboot command
+ *
+ * @cmd_string: Pointer to command string
+ * @response: Pointer to fastboot response buffer
+ *
+ * Return: Executed command, or -1 if not recognized
+ */
+int fastboot_handle_command(char *cmd_string, char *response)
+{
+	int i;
+	char *cmd_parameter;
+
+	cmd_parameter = cmd_string;
+	strsep(&cmd_parameter, ":");
+
+	for (i = 0; i < FASTBOOT_COMMAND_COUNT; i++) {
+		if (!strcmp(commands[i].command, cmd_string)) {
+			if (commands[i].dispatch) {
+				commands[i].dispatch(cmd_parameter,
+							response);
+				return i;
+			} else {
+				break;
+			}
+		}
+	}
+
+	pr_err("command %s not recognized.\n", cmd_string);
+	fastboot_fail("unrecognized command", response);
+	return -1;
+}
+
+/**
+ * okay() - Send bare OKAY response
+ *
+ * @cmd_parameter: Pointer to command parameter
+ * @response: Pointer to fastboot response buffer
+ *
+ * Send a bare OKAY fastboot response. This is used where the command is
+ * valid, but all the work is done after the response has been sent (e.g.
+ * boot, reboot etc.)
+ */
+static void okay(char *cmd_parameter, char *response)
+{
+	fastboot_okay(NULL, response);
+}
+
+/**
+ * getvar() - Read a config/version variable
+ *
+ * @cmd_parameter: Pointer to command parameter
+ * @response: Pointer to fastboot response buffer
+ */
+static void getvar(char *cmd_parameter, char *response)
+{
+	fastboot_getvar(cmd_parameter, response);
+}
+
+/**
+ * fastboot_download() - Start a download transfer from the client
+ *
+ * @cmd_parameter: Pointer to command parameter
+ * @response: Pointer to fastboot response buffer
+ */
+static void download(char *cmd_parameter, char *response)
+{
+	char *tmp;
+
+	if (!cmd_parameter) {
+		fastboot_fail("Expected command parameter", response);
+		return;
+	}
+	fastboot_bytes_received = 0;
+	fastboot_bytes_expected = simple_strtoul(cmd_parameter, &tmp, 16);
+	if (fastboot_bytes_expected == 0) {
+		fastboot_fail("Expected nonzero image size", response);
+		return;
+	}
+	/*
+	 * Nothing to download yet. Response is of the form:
+	 * [DATA|FAIL]$cmd_parameter
+	 *
+	 * where cmd_parameter is an 8 digit hexadecimal number
+	 */
+	if (fastboot_bytes_expected > fastboot_buf_size) {
+		fastboot_fail(cmd_parameter, response);
+	} else {
+		printf("Starting download of %d bytes\n",
+		       fastboot_bytes_expected);
+		fastboot_response("DATA", response, "%s", cmd_parameter);
+	}
+}
+
+/**
+ * fastboot_data_remaining() - return bytes remaining in current transfer
+ *
+ * Return: Number of bytes left in the current download
+ */
+u32 fastboot_data_remaining(void)
+{
+	return fastboot_bytes_expected - fastboot_bytes_received;
+}
+
+/**
+ * fastboot_data_download() - Copy image data to fastboot_buf_addr.
+ *
+ * @fastboot_data: Pointer to received fastboot data
+ * @fastboot_data_len: Length of received fastboot data
+ * @response: Pointer to fastboot response buffer
+ *
+ * Copies image data from fastboot_data to fastboot_buf_addr. Writes to
+ * response. fastboot_bytes_received is updated to indicate the number
+ * of bytes that have been transferred.
+ *
+ * On completion sets image_size and ${filesize} to the total size of the
+ * downloaded image.
+ */
+void fastboot_data_download(const void *fastboot_data,
+			    unsigned int fastboot_data_len,
+			    char *response)
+{
+#define BYTES_PER_DOT	0x20000
+	u32 pre_dot_num, now_dot_num;
+
+	if (fastboot_data_len == 0 ||
+	    (fastboot_bytes_received + fastboot_data_len) >
+	    fastboot_bytes_expected) {
+		fastboot_fail("Received invalid data length",
+			      response);
+		return;
+	}
+	/* Download data to fastboot_buf_addr */
+	memcpy(fastboot_buf_addr + fastboot_bytes_received,
+	       fastboot_data, fastboot_data_len);
+
+	pre_dot_num = fastboot_bytes_received / BYTES_PER_DOT;
+	fastboot_bytes_received += fastboot_data_len;
+	now_dot_num = fastboot_bytes_received / BYTES_PER_DOT;
+
+	if (pre_dot_num != now_dot_num) {
+		putc('.');
+		if (!(now_dot_num % 74))
+			putc('\n');
+	}
+	*response = '\0';
+}
+
+/**
+ * fastboot_data_complete() - Mark current transfer complete
+ *
+ * @response: Pointer to fastboot response buffer
+ *
+ * Set image_size and ${filesize} to the total size of the downloaded image.
+ */
+void fastboot_data_complete(char *response)
+{
+	/* Download complete. Respond with "OKAY" */
+	fastboot_okay(NULL, response);
+	printf("\ndownloading of %d bytes finished\n", fastboot_bytes_received);
+	image_size = fastboot_bytes_received;
+	env_set_hex("filesize", image_size);
+	fastboot_bytes_expected = 0;
+	fastboot_bytes_received = 0;
+}
+
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
+/**
+ * flash() - write the downloaded image to the indicated partition.
+ *
+ * @cmd_parameter: Pointer to partition name
+ * @response: Pointer to fastboot response buffer
+ *
+ * Writes the previously downloaded image to the partition indicated by
+ * cmd_parameter. Writes to response.
+ */
+static void flash(char *cmd_parameter, char *response)
+{
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
+	fastboot_mmc_flash_write(cmd_parameter, fastboot_buf_addr, image_size,
+				 response);
+#endif
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
+	fastboot_nand_flash_write(cmd_parameter, fastboot_buf_addr, image_size,
+				  response);
+#endif
+}
+
+/**
+ * erase() - erase the indicated partition.
+ *
+ * @cmd_parameter: Pointer to partition name
+ * @response: Pointer to fastboot response buffer
+ *
+ * Erases the partition indicated by cmd_parameter (clear to 0x00s). Writes
+ * to response.
+ */
+static void erase(char *cmd_parameter, char *response)
+{
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
+	fastboot_mmc_erase(cmd_parameter, response);
+#endif
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
+	fastboot_nand_erase(cmd_parameter, response);
+#endif
+}
+#endif
+
+/**
+ * reboot_bootloader() - Sets reboot bootloader flag.
+ *
+ * @cmd_parameter: Pointer to command parameter
+ * @response: Pointer to fastboot response buffer
+ */
+static void reboot_bootloader(char *cmd_parameter, char *response)
+{
+	if (fastboot_set_reboot_flag())
+		fastboot_fail("Cannot set reboot flag", response);
+	else
+		fastboot_okay(NULL, response);
+}
+
+#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
+/**
+ * oem_format() - Execute the OEM format command
+ *
+ * @cmd_parameter: Pointer to command parameter
+ * @response: Pointer to fastboot response buffer
+ */
+static void oem_format(char *cmd_parameter, char *response)
+{
+	char cmdbuf[32];
+
+	if (!env_get("partitions")) {
+		fastboot_fail("partitions not set", response);
+	} else {
+		sprintf(cmdbuf, "gpt write mmc %x $partitions",
+			CONFIG_FASTBOOT_FLASH_MMC_DEV);
+		if (run_command(cmdbuf, 0))
+			fastboot_fail("", response);
+		else
+			fastboot_okay(NULL, response);
+	}
+}
+#endif
diff --git a/drivers/fastboot/fb_common.c b/drivers/fastboot/fb_common.c
new file mode 100644
index 0000000..c6e06aa
--- /dev/null
+++ b/drivers/fastboot/fb_common.c
@@ -0,0 +1,169 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2008 - 2009
+ * Windriver, <www.windriver.com>
+ * Tom Rix <Tom.Rix@windriver.com>
+ *
+ * Copyright 2011 Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ *
+ * Copyright 2014 Linaro, Ltd.
+ * Rob Herring <robh@kernel.org>
+ */
+
+#include <common.h>
+#include <fastboot.h>
+#include <net/fastboot.h>
+
+/**
+ * fastboot_buf_addr - base address of the fastboot download buffer
+ */
+void *fastboot_buf_addr;
+
+/**
+ * fastboot_buf_size - size of the fastboot download buffer
+ */
+u32 fastboot_buf_size;
+
+/**
+ * fastboot_progress_callback - callback executed during long operations
+ */
+void (*fastboot_progress_callback)(const char *msg);
+
+/**
+ * fastboot_response() - Writes a response of the form "$tag$reason".
+ *
+ * @tag: The first part of the response
+ * @response: Pointer to fastboot response buffer
+ * @format: printf style format string
+ */
+void fastboot_response(const char *tag, char *response,
+		       const char *format, ...)
+{
+	va_list args;
+
+	strlcpy(response, tag, FASTBOOT_RESPONSE_LEN);
+	if (format) {
+		va_start(args, format);
+		vsnprintf(response + strlen(response),
+			  FASTBOOT_RESPONSE_LEN - strlen(response) - 1,
+			  format, args);
+		va_end(args);
+	}
+}
+
+/**
+ * fastboot_fail() - Write a FAIL response of the form "FAIL$reason".
+ *
+ * @reason: Pointer to returned reason string
+ * @response: Pointer to fastboot response buffer
+ */
+void fastboot_fail(const char *reason, char *response)
+{
+	fastboot_response("FAIL", response, "%s", reason);
+}
+
+/**
+ * fastboot_okay() - Write an OKAY response of the form "OKAY$reason".
+ *
+ * @reason: Pointer to returned reason string, or NULL to send a bare "OKAY"
+ * @response: Pointer to fastboot response buffer
+ */
+void fastboot_okay(const char *reason, char *response)
+{
+	if (reason)
+		fastboot_response("OKAY", response, "%s", reason);
+	else
+		fastboot_response("OKAY", response, NULL);
+}
+
+/**
+ * fastboot_set_reboot_flag() - Set flag to indicate reboot-bootloader
+ *
+ * Set flag which indicates that we should reboot into the bootloader
+ * following the reboot that fastboot executes after this function.
+ *
+ * This function should be overridden in your board file with one
+ * which sets whatever flag your board specific Android bootloader flow
+ * requires in order to re-enter the bootloader.
+ */
+int __weak fastboot_set_reboot_flag(void)
+{
+	return -ENOSYS;
+}
+
+/**
+ * fastboot_get_progress_callback() - Return progress callback
+ *
+ * Return: Pointer to function called during long operations
+ */
+void (*fastboot_get_progress_callback(void))(const char *)
+{
+	return fastboot_progress_callback;
+}
+
+/**
+ * fastboot_boot() - Execute fastboot boot command
+ *
+ * If ${fastboot_bootcmd} is set, run that command to execute the boot
+ * process, if that returns, then exit the fastboot server and return
+ * control to the caller.
+ *
+ * Otherwise execute "bootm <fastboot_buf_addr>", if that fails, reset
+ * the board.
+ */
+void fastboot_boot(void)
+{
+	char *s;
+
+	s = env_get("fastboot_bootcmd");
+	if (s) {
+		run_command(s, CMD_FLAG_ENV);
+	} else {
+		static char boot_addr_start[12];
+		static char *const bootm_args[] = {
+			"bootm", boot_addr_start, NULL
+		};
+
+		snprintf(boot_addr_start, sizeof(boot_addr_start) - 1,
+			 "0x%p", fastboot_buf_addr);
+		printf("Booting kernel at %s...\n\n\n", boot_addr_start);
+
+		do_bootm(NULL, 0, 2, bootm_args);
+
+		/*
+		 * This only happens if image is somehow faulty so we start
+		 * over. We deliberately leave this policy to the invocation
+		 * of fastbootcmd if that's what's being run
+		 */
+		do_reset(NULL, 0, 0, NULL);
+	}
+}
+
+/**
+ * fastboot_set_progress_callback() - set progress callback
+ *
+ * @progress: Pointer to progress callback
+ *
+ * Set a callback which is invoked periodically during long running operations
+ * (flash and erase). This can be used (for example) by the UDP transport to
+ * send INFO responses to keep the client alive whilst those commands are
+ * executing.
+ */
+void fastboot_set_progress_callback(void (*progress)(const char *msg))
+{
+	fastboot_progress_callback = progress;
+}
+
+/*
+ * fastboot_init() - initialise new fastboot protocol session
+ *
+ * @buf_addr: Pointer to download buffer, or NULL for default
+ * @buf_size: Size of download buffer, or zero for default
+ */
+void fastboot_init(void *buf_addr, u32 buf_size)
+{
+	fastboot_buf_addr = buf_addr ? buf_addr :
+				       (void *)CONFIG_FASTBOOT_BUF_ADDR;
+	fastboot_buf_size = buf_size ? buf_size : CONFIG_FASTBOOT_BUF_SIZE;
+	fastboot_set_progress_callback(NULL);
+}
diff --git a/drivers/fastboot/fb_getvar.c b/drivers/fastboot/fb_getvar.c
new file mode 100644
index 0000000..4d264c9
--- /dev/null
+++ b/drivers/fastboot/fb_getvar.c
@@ -0,0 +1,230 @@
+// SPDX-License-Identifier: BSD-2-Clause
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ */
+
+#include <common.h>
+#include <fastboot.h>
+#include <fastboot-internal.h>
+#include <fb_mmc.h>
+#include <fb_nand.h>
+#include <fs.h>
+#include <version.h>
+
+static void getvar_version(char *var_parameter, char *response);
+static void getvar_bootloader_version(char *var_parameter, char *response);
+static void getvar_downloadsize(char *var_parameter, char *response);
+static void getvar_serialno(char *var_parameter, char *response);
+static void getvar_version_baseband(char *var_parameter, char *response);
+static void getvar_product(char *var_parameter, char *response);
+static void getvar_current_slot(char *var_parameter, char *response);
+static void getvar_slot_suffixes(char *var_parameter, char *response);
+static void getvar_has_slot(char *var_parameter, char *response);
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
+static void getvar_partition_type(char *part_name, char *response);
+#endif
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
+static void getvar_partition_size(char *part_name, char *response);
+#endif
+
+static const struct {
+	const char *variable;
+	void (*dispatch)(char *var_parameter, char *response);
+} getvar_dispatch[] = {
+	{
+		.variable = "version",
+		.dispatch = getvar_version
+	}, {
+		.variable = "bootloader-version",
+		.dispatch = getvar_bootloader_version
+	}, {
+		.variable = "version-bootloader",
+		.dispatch = getvar_bootloader_version
+	}, {
+		.variable = "downloadsize",
+		.dispatch = getvar_downloadsize
+	}, {
+		.variable = "max-download-size",
+		.dispatch = getvar_downloadsize
+	}, {
+		.variable = "serialno",
+		.dispatch = getvar_serialno
+	}, {
+		.variable = "version-baseband",
+		.dispatch = getvar_version_baseband
+	}, {
+		.variable = "product",
+		.dispatch = getvar_product
+	}, {
+		.variable = "current-slot",
+		.dispatch = getvar_current_slot
+	}, {
+		.variable = "slot-suffixes",
+		.dispatch = getvar_slot_suffixes
+	}, {
+		.variable = "has_slot",
+		.dispatch = getvar_has_slot
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
+	}, {
+		.variable = "partition-type",
+		.dispatch = getvar_partition_type
+#endif
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
+	}, {
+		.variable = "partition-size",
+		.dispatch = getvar_partition_size
+#endif
+	}
+};
+
+static void getvar_version(char *var_parameter, char *response)
+{
+	fastboot_okay(FASTBOOT_VERSION, response);
+}
+
+static void getvar_bootloader_version(char *var_parameter, char *response)
+{
+	fastboot_okay(U_BOOT_VERSION, response);
+}
+
+static void getvar_downloadsize(char *var_parameter, char *response)
+{
+	fastboot_response("OKAY", response, "0x%08x", fastboot_buf_size);
+}
+
+static void getvar_serialno(char *var_parameter, char *response)
+{
+	const char *tmp = env_get("serial#");
+
+	if (tmp)
+		fastboot_okay(tmp, response);
+	else
+		fastboot_fail("Value not set", response);
+}
+
+static void getvar_version_baseband(char *var_parameter, char *response)
+{
+	fastboot_okay("N/A", response);
+}
+
+static void getvar_product(char *var_parameter, char *response)
+{
+	const char *board = env_get("board");
+
+	if (board)
+		fastboot_okay(board, response);
+	else
+		fastboot_fail("Board not set", response);
+}
+
+static void getvar_current_slot(char *var_parameter, char *response)
+{
+	/* A/B not implemented, for now always return _a */
+	fastboot_okay("_a", response);
+}
+
+static void getvar_slot_suffixes(char *var_parameter, char *response)
+{
+	fastboot_okay("_a,_b", response);
+}
+
+static void getvar_has_slot(char *part_name, char *response)
+{
+	if (part_name && (!strcmp(part_name, "boot") ||
+			  !strcmp(part_name, "system")))
+		fastboot_okay("yes", response);
+	else
+		fastboot_okay("no", response);
+}
+
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
+static void getvar_partition_type(char *part_name, char *response)
+{
+	int r;
+	struct blk_desc *dev_desc;
+	disk_partition_t part_info;
+
+	r = fastboot_mmc_get_part_info(part_name, &dev_desc, &part_info,
+				       response);
+	if (r >= 0) {
+		r = fs_set_blk_dev_with_part(dev_desc, r);
+		if (r < 0)
+			fastboot_fail("failed to set partition", response);
+		else
+			fastboot_okay(fs_get_type_name(), response);
+	}
+}
+#endif
+
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
+static void getvar_partition_size(char *part_name, char *response)
+{
+	int r;
+	size_t size;
+
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
+	struct blk_desc *dev_desc;
+	disk_partition_t part_info;
+
+	r = fastboot_mmc_get_part_info(part_name, &dev_desc, &part_info,
+				       response);
+	if (r >= 0)
+		size = part_info.size;
+#endif
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
+	struct part_info *part_info;
+
+	r = fastboot_nand_get_part_info(part_name, &part_info, response);
+	if (r >= 0)
+		size = part_info->size;
+#endif
+	if (r >= 0)
+		fastboot_response("OKAY", response, "0x%016zx", size);
+}
+#endif
+
+/**
+ * fastboot_getvar() - Writes variable indicated by cmd_parameter to response.
+ *
+ * @cmd_parameter: Pointer to command parameter
+ * @response: Pointer to fastboot response buffer
+ *
+ * Look up cmd_parameter first as an environment variable of the form
+ * fastboot.<cmd_parameter>, if that exists return use its value to set
+ * response.
+ *
+ * Otherwise lookup the name of variable and execute the appropriate
+ * function to return the requested value.
+ */
+void fastboot_getvar(char *cmd_parameter, char *response)
+{
+	if (!cmd_parameter) {
+		fastboot_fail("missing var", response);
+	} else {
+#define FASTBOOT_ENV_PREFIX	"fastboot."
+		int i;
+		char *var_parameter = cmd_parameter;
+		char envstr[FASTBOOT_RESPONSE_LEN];
+		const char *s;
+
+		snprintf(envstr, sizeof(envstr) - 1,
+			 FASTBOOT_ENV_PREFIX "%s", cmd_parameter);
+		s = env_get(envstr);
+		if (s) {
+			fastboot_response("OKAY", response, "%s", s);
+			return;
+		}
+
+		strsep(&var_parameter, ":");
+		for (i = 0; i < ARRAY_SIZE(getvar_dispatch); ++i) {
+			if (!strcmp(getvar_dispatch[i].variable,
+				    cmd_parameter)) {
+				getvar_dispatch[i].dispatch(var_parameter,
+							    response);
+				return;
+			}
+		}
+		pr_warn("WARNING: unknown variable: %s\n", cmd_parameter);
+		fastboot_fail("Variable not implemented", response);
+	}
+}
diff --git a/common/fb_mmc.c b/drivers/fastboot/fb_mmc.c
similarity index 62%
rename from common/fb_mmc.c
rename to drivers/fastboot/fb_mmc.c
index 46f0073..4c1c7fd 100644
--- a/common/fb_mmc.c
+++ b/drivers/fastboot/fb_mmc.c
@@ -7,6 +7,7 @@
 #include <common.h>
 #include <blk.h>
 #include <fastboot.h>
+#include <fastboot-internal.h>
 #include <fb_mmc.h>
 #include <image-sparse.h>
 #include <part.h>
@@ -15,18 +16,7 @@
 #include <linux/compat.h>
 #include <android_image.h>
 
-/*
- * FIXME: Ensure we always set these names via Kconfig once xxx_PARTITION is
- * migrated
- */
-#ifndef CONFIG_FASTBOOT_GPT_NAME
-#define CONFIG_FASTBOOT_GPT_NAME "gpt"
-#endif
-
-
-#ifndef CONFIG_FASTBOOT_MBR_NAME
-#define CONFIG_FASTBOOT_MBR_NAME "mbr"
-#endif
+#define FASTBOOT_MAX_BLK_WRITE 16384
 
 #define BOOT_PARTITION_NAME "boot"
 
@@ -56,13 +46,48 @@
 	return ret;
 }
 
+/**
+ * fb_mmc_blk_write() - Write/erase MMC in chunks of FASTBOOT_MAX_BLK_WRITE
+ *
+ * @block_dev: Pointer to block device
+ * @start: First block to write/erase
+ * @blkcnt: Count of blocks
+ * @buffer: Pointer to data buffer for write or NULL for erase
+ */
+static lbaint_t fb_mmc_blk_write(struct blk_desc *block_dev, lbaint_t start,
+				 lbaint_t blkcnt, const void *buffer)
+{
+	lbaint_t blk = start;
+	lbaint_t blks_written;
+	lbaint_t cur_blkcnt;
+	lbaint_t blks = 0;
+	int i;
+
+	for (i = 0; i < blkcnt; i += FASTBOOT_MAX_BLK_WRITE) {
+		cur_blkcnt = min((int)blkcnt - i, FASTBOOT_MAX_BLK_WRITE);
+		if (buffer) {
+			if (fastboot_progress_callback)
+				fastboot_progress_callback("writing");
+			blks_written = blk_dwrite(block_dev, blk, cur_blkcnt,
+						  buffer + (i * block_dev->blksz));
+		} else {
+			if (fastboot_progress_callback)
+				fastboot_progress_callback("erasing");
+			blks_written = blk_derase(block_dev, blk, cur_blkcnt);
+		}
+		blk += blks_written;
+		blks += blks_written;
+	}
+	return blks;
+}
+
 static lbaint_t fb_mmc_sparse_write(struct sparse_storage *info,
 		lbaint_t blk, lbaint_t blkcnt, const void *buffer)
 {
 	struct fb_mmc_sparse *sparse = info->priv;
 	struct blk_desc *dev_desc = sparse->dev_desc;
 
-	return blk_dwrite(dev_desc, blk, blkcnt, buffer);
+	return fb_mmc_blk_write(dev_desc, blk, blkcnt, buffer);
 }
 
 static lbaint_t fb_mmc_sparse_reserve(struct sparse_storage *info,
@@ -73,7 +98,7 @@
 
 static void write_raw_image(struct blk_desc *dev_desc, disk_partition_t *info,
 		const char *part_name, void *buffer,
-		unsigned int download_bytes)
+		u32 download_bytes, char *response)
 {
 	lbaint_t blkcnt;
 	lbaint_t blks;
@@ -84,22 +109,23 @@
 
 	if (blkcnt > info->size) {
 		pr_err("too large for partition: '%s'\n", part_name);
-		fastboot_fail("too large for partition");
+		fastboot_fail("too large for partition", response);
 		return;
 	}
 
 	puts("Flashing Raw Image\n");
 
-	blks = blk_dwrite(dev_desc, info->start, blkcnt, buffer);
+	blks = fb_mmc_blk_write(dev_desc, info->start, blkcnt, buffer);
+
 	if (blks != blkcnt) {
 		pr_err("failed writing to device %d\n", dev_desc->devnum);
-		fastboot_fail("failed writing to device");
+		fastboot_fail("failed writing to device", response);
 		return;
 	}
 
 	printf("........ wrote " LBAFU " bytes to '%s'\n", blkcnt * info->blksz,
 	       part_name);
-	fastboot_okay("");
+	fastboot_okay(NULL, response);
 }
 
 #ifdef CONFIG_ANDROID_BOOT_IMAGE
@@ -114,7 +140,8 @@
  */
 static lbaint_t fb_mmc_get_boot_header(struct blk_desc *dev_desc,
 				       disk_partition_t *info,
-				       struct andr_img_hdr *hdr)
+				       struct andr_img_hdr *hdr,
+				       char *response)
 {
 	ulong sector_size;		/* boot partition sector size */
 	lbaint_t hdr_sectors;		/* boot image header sectors count */
@@ -124,24 +151,25 @@
 	sector_size = info->blksz;
 	hdr_sectors = DIV_ROUND_UP(sizeof(struct andr_img_hdr), sector_size);
 	if (hdr_sectors == 0) {
-		pr_err("invalid number of boot sectors: 0");
-		fastboot_fail("invalid number of boot sectors: 0");
+		pr_err("invalid number of boot sectors: 0\n");
+		fastboot_fail("invalid number of boot sectors: 0", response);
 		return 0;
 	}
 
 	/* Read the boot image header */
 	res = blk_dread(dev_desc, info->start, hdr_sectors, (void *)hdr);
 	if (res != hdr_sectors) {
-		pr_err("cannot read header from boot partition");
-		fastboot_fail("cannot read header from boot partition");
+		pr_err("cannot read header from boot partition\n");
+		fastboot_fail("cannot read header from boot partition",
+			      response);
 		return 0;
 	}
 
 	/* Check boot header magic string */
 	res = android_image_check_header(hdr);
 	if (res != 0) {
-		pr_err("bad boot image magic");
-		fastboot_fail("boot partition not initialized");
+		pr_err("bad boot image magic\n");
+		fastboot_fail("boot partition not initialized", response);
 		return 0;
 	}
 
@@ -159,7 +187,8 @@
  */
 static int fb_mmc_update_zimage(struct blk_desc *dev_desc,
 				void *download_buffer,
-				unsigned int download_bytes)
+				u32 download_bytes,
+				char *response)
 {
 	uintptr_t hdr_addr;			/* boot image header address */
 	struct andr_img_hdr *hdr;		/* boot image header */
@@ -178,8 +207,8 @@
 	/* Get boot partition info */
 	res = part_get_info_by_name(dev_desc, BOOT_PARTITION_NAME, &info);
 	if (res < 0) {
-		pr_err("cannot find boot partition");
-		fastboot_fail("cannot find boot partition");
+		pr_err("cannot find boot partition\n");
+		fastboot_fail("cannot find boot partition", response);
 		return -1;
 	}
 
@@ -188,17 +217,18 @@
 	hdr = (struct andr_img_hdr *)hdr_addr;
 
 	/* Read boot image header */
-	hdr_sectors = fb_mmc_get_boot_header(dev_desc, &info, hdr);
+	hdr_sectors = fb_mmc_get_boot_header(dev_desc, &info, hdr, response);
 	if (hdr_sectors == 0) {
-		pr_err("unable to read boot image header");
-		fastboot_fail("unable to read boot image header");
+		pr_err("unable to read boot image header\n");
+		fastboot_fail("unable to read boot image header", response);
 		return -1;
 	}
 
 	/* Check if boot image has second stage in it (we don't support it) */
 	if (hdr->second_size > 0) {
-		pr_err("moving second stage is not supported yet");
-		fastboot_fail("moving second stage is not supported yet");
+		pr_err("moving second stage is not supported yet\n");
+		fastboot_fail("moving second stage is not supported yet",
+			      response);
 		return -1;
 	}
 
@@ -215,8 +245,9 @@
 	res = blk_dread(dev_desc, ramdisk_sector_start, ramdisk_sectors,
 			ramdisk_buffer);
 	if (res != ramdisk_sectors) {
-		pr_err("cannot read ramdisk from boot partition");
-		fastboot_fail("cannot read ramdisk from boot partition");
+		pr_err("cannot read ramdisk from boot partition\n");
+		fastboot_fail("cannot read ramdisk from boot partition",
+			      response);
 		return -1;
 	}
 
@@ -224,8 +255,8 @@
 	hdr->kernel_size = download_bytes;
 	res = blk_dwrite(dev_desc, info.start, hdr_sectors, (void *)hdr);
 	if (res == 0) {
-		pr_err("cannot writeback boot image header");
-		fastboot_fail("cannot write back boot image header");
+		pr_err("cannot writeback boot image header\n");
+		fastboot_fail("cannot write back boot image header", response);
 		return -1;
 	}
 
@@ -236,8 +267,8 @@
 	res = blk_dwrite(dev_desc, kernel_sector_start, kernel_sectors,
 			 download_buffer);
 	if (res == 0) {
-		pr_err("cannot write new kernel");
-		fastboot_fail("cannot write new kernel");
+		pr_err("cannot write new kernel\n");
+		fastboot_fail("cannot write new kernel", response);
 		return -1;
 	}
 
@@ -248,19 +279,59 @@
 	res = blk_dwrite(dev_desc, ramdisk_sector_start, ramdisk_sectors,
 			 ramdisk_buffer);
 	if (res == 0) {
-		pr_err("cannot write back original ramdisk");
-		fastboot_fail("cannot write back original ramdisk");
+		pr_err("cannot write back original ramdisk\n");
+		fastboot_fail("cannot write back original ramdisk", response);
 		return -1;
 	}
 
 	puts("........ zImage was updated in boot partition\n");
-	fastboot_okay("");
+	fastboot_okay(NULL, response);
 	return 0;
 }
 #endif
 
-void fb_mmc_flash_write(const char *cmd, void *download_buffer,
-			unsigned int download_bytes)
+/**
+ * fastboot_mmc_get_part_info() - Lookup eMMC partion by name
+ *
+ * @part_name: Named partition to lookup
+ * @dev_desc: Pointer to returned blk_desc pointer
+ * @part_info: Pointer to returned disk_partition_t
+ * @response: Pointer to fastboot response buffer
+ */
+int fastboot_mmc_get_part_info(char *part_name, struct blk_desc **dev_desc,
+			       disk_partition_t *part_info, char *response)
+{
+	int r;
+
+	*dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
+	if (!*dev_desc) {
+		fastboot_fail("block device not found", response);
+		return -ENOENT;
+	}
+	if (!part_name) {
+		fastboot_fail("partition not found", response);
+		return -ENOENT;
+	}
+
+	r = part_get_info_by_name_or_alias(*dev_desc, part_name, part_info);
+	if (r < 0) {
+		fastboot_fail("partition not found", response);
+		return r;
+	}
+
+	return r;
+}
+
+/**
+ * fastboot_mmc_flash_write() - Write image to eMMC for fastboot
+ *
+ * @cmd: Named partition to write image to
+ * @download_buffer: Pointer to image data
+ * @download_bytes: Size of image data
+ * @response: Pointer to fastboot response buffer
+ */
+void fastboot_mmc_flash_write(const char *cmd, void *download_buffer,
+			      u32 download_bytes, char *response)
 {
 	struct blk_desc *dev_desc;
 	disk_partition_t info;
@@ -268,7 +339,7 @@
 	dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
 	if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
 		pr_err("invalid mmc device\n");
-		fastboot_fail("invalid mmc device");
+		fastboot_fail("invalid mmc device", response);
 		return;
 	}
 
@@ -279,16 +350,17 @@
 		if (is_valid_gpt_buf(dev_desc, download_buffer)) {
 			printf("%s: invalid GPT - refusing to write to flash\n",
 			       __func__);
-			fastboot_fail("invalid GPT partition");
+			fastboot_fail("invalid GPT partition", response);
 			return;
 		}
 		if (write_mbr_and_gpt_partitions(dev_desc, download_buffer)) {
 			printf("%s: writing GPT partitions failed\n", __func__);
-			fastboot_fail("writing GPT partitions failed");
+			fastboot_fail("writing GPT partitions failed",
+				      response);
 			return;
 		}
 		printf("........ success\n");
-		fastboot_okay("");
+		fastboot_okay(NULL, response);
 		return;
 	}
 #endif
@@ -299,30 +371,32 @@
 		if (is_valid_dos_buf(download_buffer)) {
 			printf("%s: invalid MBR - refusing to write to flash\n",
 			       __func__);
-			fastboot_fail("invalid MBR partition");
+			fastboot_fail("invalid MBR partition", response);
 			return;
 		}
 		if (write_mbr_partition(dev_desc, download_buffer)) {
 			printf("%s: writing MBR partition failed\n", __func__);
-			fastboot_fail("writing MBR partition failed");
+			fastboot_fail("writing MBR partition failed",
+				      response);
 			return;
 		}
 		printf("........ success\n");
-		fastboot_okay("");
+		fastboot_okay(NULL, response);
 		return;
 	}
 #endif
 
 #ifdef CONFIG_ANDROID_BOOT_IMAGE
 	if (strncasecmp(cmd, "zimage", 6) == 0) {
-		fb_mmc_update_zimage(dev_desc, download_buffer, download_bytes);
+		fb_mmc_update_zimage(dev_desc, download_buffer,
+				     download_bytes, response);
 		return;
 	}
 #endif
 
 	if (part_get_info_by_name_or_alias(dev_desc, cmd, &info) < 0) {
 		pr_err("cannot find partition: '%s'\n", cmd);
-		fastboot_fail("cannot find partition");
+		fastboot_fail("cannot find partition", response);
 		return;
 	}
 
@@ -344,16 +418,23 @@
 		       sparse.start);
 
 		sparse.priv = &sparse_priv;
-		err = write_sparse_image(&sparse, cmd, download_buffer);
+		err = write_sparse_image(&sparse, cmd, download_buffer,
+					 response);
 		if (!err)
-			fastboot_okay("");
+			fastboot_okay(NULL, response);
 	} else {
 		write_raw_image(dev_desc, &info, cmd, download_buffer,
-				download_bytes);
+				download_bytes, response);
 	}
 }
 
-void fb_mmc_erase(const char *cmd)
+/**
+ * fastboot_mmc_flash_erase() - Erase eMMC for fastboot
+ *
+ * @cmd: Named partition to erase
+ * @response: Pointer to fastboot response buffer
+ */
+void fastboot_mmc_erase(const char *cmd, char *response)
 {
 	int ret;
 	struct blk_desc *dev_desc;
@@ -362,22 +443,22 @@
 	struct mmc *mmc = find_mmc_device(CONFIG_FASTBOOT_FLASH_MMC_DEV);
 
 	if (mmc == NULL) {
-		pr_err("invalid mmc device");
-		fastboot_fail("invalid mmc device");
+		pr_err("invalid mmc device\n");
+		fastboot_fail("invalid mmc device", response);
 		return;
 	}
 
 	dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
 	if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
-		pr_err("invalid mmc device");
-		fastboot_fail("invalid mmc device");
+		pr_err("invalid mmc device\n");
+		fastboot_fail("invalid mmc device", response);
 		return;
 	}
 
 	ret = part_get_info_by_name_or_alias(dev_desc, cmd, &info);
 	if (ret < 0) {
-		pr_err("cannot find partition: '%s'", cmd);
-		fastboot_fail("cannot find partition");
+		pr_err("cannot find partition: '%s'\n", cmd);
+		fastboot_fail("cannot find partition", response);
 		return;
 	}
 
@@ -393,14 +474,15 @@
 	printf("Erasing blocks " LBAFU " to " LBAFU " due to alignment\n",
 	       blks_start, blks_start + blks_size);
 
-	blks = blk_derase(dev_desc, blks_start, blks_size);
+	blks = fb_mmc_blk_write(dev_desc, blks_start, blks_size, NULL);
+
 	if (blks != blks_size) {
-		pr_err("failed erasing from device %d", dev_desc->devnum);
-		fastboot_fail("failed erasing from device");
+		pr_err("failed erasing from device %d\n", dev_desc->devnum);
+		fastboot_fail("failed erasing from device", response);
 		return;
 	}
 
 	printf("........ erased " LBAFU " bytes from '%s'\n",
 	       blks_size * info.blksz, cmd);
-	fastboot_okay("");
+	fastboot_okay(NULL, response);
 }
diff --git a/common/fb_nand.c b/drivers/fastboot/fb_nand.c
similarity index 71%
rename from common/fb_nand.c
rename to drivers/fastboot/fb_nand.c
index c07655e..526bc12 100644
--- a/common/fb_nand.c
+++ b/drivers/fastboot/fb_nand.c
@@ -31,7 +31,8 @@
 
 static int fb_nand_lookup(const char *partname,
 			  struct mtd_info **mtd,
-			  struct part_info **part)
+			  struct part_info **part,
+			  char *response)
 {
 	struct mtd_device *dev;
 	int ret;
@@ -40,21 +41,21 @@
 	ret = mtdparts_init();
 	if (ret) {
 		pr_err("Cannot initialize MTD partitions\n");
-		fastboot_fail("cannot init mtdparts");
+		fastboot_fail("cannot init mtdparts", response);
 		return ret;
 	}
 
 	ret = find_dev_and_part(partname, &dev, &pnum, part);
 	if (ret) {
 		pr_err("cannot find partition: '%s'", partname);
-		fastboot_fail("cannot find partition");
+		fastboot_fail("cannot find partition", response);
 		return ret;
 	}
 
 	if (dev->id->type != MTD_DEV_TYPE_NAND) {
 		pr_err("partition '%s' is not stored on a NAND device",
 		      partname);
-		fastboot_fail("not a NAND device");
+		fastboot_fail("not a NAND device", response);
 		return -EINVAL;
 	}
 
@@ -87,8 +88,8 @@
 }
 
 static int _fb_nand_write(struct mtd_info *mtd, struct part_info *part,
-			  void *buffer, unsigned int offset,
-			  unsigned int length, size_t *written)
+			  void *buffer, u32 offset,
+			  size_t length, size_t *written)
 {
 	int flags = WITH_WR_VERIFY;
 
@@ -144,17 +145,40 @@
 	return blkcnt + bad_blocks;
 }
 
-void fb_nand_flash_write(const char *cmd, void *download_buffer,
-			 unsigned int download_bytes)
+/**
+ * fastboot_nand_get_part_info() - Lookup NAND partion by name
+ *
+ * @part_name: Named device to lookup
+ * @part_info: Pointer to returned part_info pointer
+ * @response: Pointer to fastboot response buffer
+ */
+int fastboot_nand_get_part_info(char *part_name, struct part_info **part_info,
+				char *response)
+{
+	struct mtd_info *mtd = NULL;
+
+	return fb_nand_lookup(part_name, &mtd, part_info, response);
+}
+
+/**
+ * fastboot_nand_flash_write() - Write image to NAND for fastboot
+ *
+ * @cmd: Named device to write image to
+ * @download_buffer: Pointer to image data
+ * @download_bytes: Size of image data
+ * @response: Pointer to fastboot response buffer
+ */
+void fastboot_nand_flash_write(const char *cmd, void *download_buffer,
+			       u32 download_bytes, char *response)
 {
 	struct part_info *part;
 	struct mtd_info *mtd = NULL;
 	int ret;
 
-	ret = fb_nand_lookup(cmd, &mtd, &part);
+	ret = fb_nand_lookup(cmd, &mtd, &part, response);
 	if (ret) {
 		pr_err("invalid NAND device");
-		fastboot_fail("invalid NAND device");
+		fastboot_fail("invalid NAND device", response);
 		return;
 	}
 
@@ -180,9 +204,10 @@
 		       sparse.start);
 
 		sparse.priv = &sparse_priv;
-		ret = write_sparse_image(&sparse, cmd, download_buffer);
+		ret = write_sparse_image(&sparse, cmd, download_buffer,
+					 response);
 		if (!ret)
-			fastboot_okay("");
+			fastboot_okay(NULL, response);
 	} else {
 		printf("Flashing raw image at offset 0x%llx\n",
 		       part->offset);
@@ -195,23 +220,29 @@
 	}
 
 	if (ret) {
-		fastboot_fail("error writing the image");
+		fastboot_fail("error writing the image", response);
 		return;
 	}
 
-	fastboot_okay("");
+	fastboot_okay(NULL, response);
 }
 
-void fb_nand_erase(const char *cmd)
+/**
+ * fastboot_nand_flash_erase() - Erase NAND for fastboot
+ *
+ * @cmd: Named device to erase
+ * @response: Pointer to fastboot response buffer
+ */
+void fastboot_nand_erase(const char *cmd, char *response)
 {
 	struct part_info *part;
 	struct mtd_info *mtd = NULL;
 	int ret;
 
-	ret = fb_nand_lookup(cmd, &mtd, &part);
+	ret = fb_nand_lookup(cmd, &mtd, &part, response);
 	if (ret) {
 		pr_err("invalid NAND device");
-		fastboot_fail("invalid NAND device");
+		fastboot_fail("invalid NAND device", response);
 		return;
 	}
 
@@ -222,9 +253,9 @@
 	ret = _fb_nand_erase(mtd, part);
 	if (ret) {
 		pr_err("failed erasing from device %s", mtd->name);
-		fastboot_fail("failed erasing from device");
+		fastboot_fail("failed erasing from device", response);
 		return;
 	}
 
-	fastboot_okay("");
+	fastboot_okay(NULL, response);
 }
diff --git a/drivers/fpga/fpga.c b/drivers/fpga/fpga.c
index 55bdf9e..7e8bd7e 100644
--- a/drivers/fpga/fpga.c
+++ b/drivers/fpga/fpga.c
@@ -217,6 +217,35 @@
 }
 #endif
 
+#if defined(CONFIG_CMD_FPGA_LOAD_SECURE)
+int fpga_loads(int devnum, const void *buf, size_t size,
+	       struct fpga_secure_info *fpga_sec_info)
+{
+	int ret_val = FPGA_FAIL;
+
+	const fpga_desc *desc = fpga_validate(devnum, buf, size,
+					      (char *)__func__);
+
+	if (desc) {
+		switch (desc->devtype) {
+		case fpga_xilinx:
+#if defined(CONFIG_FPGA_XILINX)
+			ret_val = xilinx_loads(desc->devdesc, buf, size,
+					       fpga_sec_info);
+#else
+			fpga_no_sup((char *)__func__, "Xilinx devices");
+#endif
+			break;
+		default:
+			printf("%s: Invalid or unsupported device type %d\n",
+			       __func__, desc->devtype);
+		}
+	}
+
+	return ret_val;
+}
+#endif
+
 /*
  * Generic multiplexing code
  */
diff --git a/drivers/fpga/xilinx.c b/drivers/fpga/xilinx.c
index 724304a..f513550 100644
--- a/drivers/fpga/xilinx.c
+++ b/drivers/fpga/xilinx.c
@@ -171,6 +171,24 @@
 }
 #endif
 
+#if defined(CONFIG_CMD_FPGA_LOAD_SECURE)
+int xilinx_loads(xilinx_desc *desc, const void *buf, size_t bsize,
+		 struct fpga_secure_info *fpga_sec_info)
+{
+	if (!xilinx_validate(desc, (char *)__func__)) {
+		printf("%s: Invalid device descriptor\n", __func__);
+		return FPGA_FAIL;
+	}
+
+	if (!desc->operations || !desc->operations->loads) {
+		printf("%s: Missing loads operation\n", __func__);
+		return FPGA_FAIL;
+	}
+
+	return desc->operations->loads(desc, buf, bsize, fpga_sec_info);
+}
+#endif
+
 int xilinx_dump(xilinx_desc *desc, const void *buf, size_t bsize)
 {
 	if (!xilinx_validate (desc, (char *)__FUNCTION__)) {
diff --git a/drivers/fpga/zynqmppl.c b/drivers/fpga/zynqmppl.c
index b57623b..03ffa8c 100644
--- a/drivers/fpga/zynqmppl.c
+++ b/drivers/fpga/zynqmppl.c
@@ -223,6 +223,51 @@
 	return ret;
 }
 
+#if defined(CONFIG_CMD_FPGA_LOAD_SECURE) && !defined(CONFIG_SPL_BUILD)
+static int zynqmp_loads(xilinx_desc *desc, const void *buf, size_t bsize,
+			struct fpga_secure_info *fpga_sec_info)
+{
+	int ret;
+	u32 buf_lo, buf_hi;
+	u32 ret_payload[PAYLOAD_ARG_CNT];
+	u8 flag = 0;
+
+	flush_dcache_range((ulong)buf, (ulong)buf +
+			   ALIGN(bsize, CONFIG_SYS_CACHELINE_SIZE));
+
+	if (!fpga_sec_info->encflag)
+		flag |= BIT(ZYNQMP_FPGA_BIT_ENC_DEV_KEY);
+
+	if (fpga_sec_info->userkey_addr &&
+	    fpga_sec_info->encflag == FPGA_ENC_USR_KEY) {
+		flush_dcache_range((ulong)fpga_sec_info->userkey_addr,
+				   (ulong)fpga_sec_info->userkey_addr +
+				   ALIGN(KEY_PTR_LEN,
+					 CONFIG_SYS_CACHELINE_SIZE));
+		flag |= BIT(ZYNQMP_FPGA_BIT_ENC_USR_KEY);
+	}
+
+	if (!fpga_sec_info->authflag)
+		flag |= BIT(ZYNQMP_FPGA_BIT_AUTH_OCM);
+
+	if (fpga_sec_info->authflag == ZYNQMP_FPGA_AUTH_DDR)
+		flag |= BIT(ZYNQMP_FPGA_BIT_AUTH_DDR);
+
+	buf_lo = lower_32_bits((ulong)buf);
+	buf_hi = upper_32_bits((ulong)buf);
+
+	ret = invoke_smc(ZYNQMP_SIP_SVC_PM_FPGA_LOAD, buf_lo, buf_hi,
+			 (u32)(uintptr_t)fpga_sec_info->userkey_addr,
+			 flag, ret_payload);
+	if (ret)
+		puts("PL FPGA LOAD fail\n");
+	else
+		puts("Bitstream successfully loaded\n");
+
+	return ret;
+}
+#endif
+
 static int zynqmp_pcap_info(xilinx_desc *desc)
 {
 	int ret;
@@ -238,5 +283,8 @@
 
 struct xilinx_fpga_op zynqmp_op = {
 	.load = zynqmp_load,
+#if defined CONFIG_CMD_FPGA_LOAD_SECURE
+	.loads = zynqmp_loads,
+#endif
 	.info = zynqmp_pcap_info,
 };
diff --git a/drivers/gpio/bcm6345_gpio.c b/drivers/gpio/bcm6345_gpio.c
index 1a507fc..d1f6cfa 100644
--- a/drivers/gpio/bcm6345_gpio.c
+++ b/drivers/gpio/bcm6345_gpio.c
@@ -13,8 +13,6 @@
 #include <asm/gpio.h>
 #include <asm/io.h>
 
-DECLARE_GLOBAL_DATA_PTR;
-
 struct bcm6345_gpio_priv {
 	void __iomem *reg_dirout;
 	void __iomem *reg_data;
@@ -90,22 +88,16 @@
 {
 	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 	struct bcm6345_gpio_priv *priv = dev_get_priv(dev);
-	fdt_addr_t data_addr, dirout_addr;
-	fdt_size_t data_size, dirout_size;
 
-	dirout_addr = devfdt_get_addr_size_index(dev, 0, &dirout_size);
-	if (dirout_addr == FDT_ADDR_T_NONE)
+	priv->reg_dirout = dev_remap_addr_index(dev, 0);
+	if (!priv->reg_dirout)
 		return -EINVAL;
 
-	data_addr = devfdt_get_addr_size_index(dev, 1, &data_size);
-	if (data_addr == FDT_ADDR_T_NONE)
+	priv->reg_data = dev_remap_addr_index(dev, 1);
+	if (!priv->reg_data)
 		return -EINVAL;
 
-	priv->reg_data = ioremap(data_addr, data_size);
-	priv->reg_dirout = ioremap(dirout_addr, dirout_size);
-
-	uc_priv->gpio_count = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
-					      "ngpios", 32);
+	uc_priv->gpio_count = dev_read_u32_default(dev, "ngpios", 32);
 	uc_priv->bank_name = dev->name;
 
 	return 0;
diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c
index b46621f..6fd1270 100644
--- a/drivers/gpio/gpio-rcar.c
+++ b/drivers/gpio/gpio-rcar.c
@@ -175,6 +175,7 @@
 	{ .compatible = "renesas,gpio-r8a7796" },
 	{ .compatible = "renesas,gpio-r8a77965" },
 	{ .compatible = "renesas,gpio-r8a77970" },
+	{ .compatible = "renesas,gpio-r8a77990" },
 	{ .compatible = "renesas,gpio-r8a77995" },
 	{ .compatible = "renesas,rcar-gen2-gpio" },
 	{ .compatible = "renesas,rcar-gen3-gpio" },
diff --git a/drivers/led/led_bcm6328.c b/drivers/led/led_bcm6328.c
index a1bf44c..a29e5a0 100644
--- a/drivers/led/led_bcm6328.c
+++ b/drivers/led/led_bcm6328.c
@@ -37,8 +37,6 @@
 #define LED_MODE_OFF			3
 #define LED_MODE_MASK			0x3
 
-DECLARE_GLOBAL_DATA_PTR;
-
 struct bcm6328_led_priv {
 	void __iomem *regs;
 	void __iomem *mode;
@@ -149,34 +147,25 @@
 static int bcm6328_led_probe(struct udevice *dev)
 {
 	struct led_uc_plat *uc_plat = dev_get_uclass_platdata(dev);
-	fdt_addr_t addr;
-	fdt_size_t size;
 
 	/* Top-level LED node */
 	if (!uc_plat->label) {
 		void __iomem *regs;
 		u32 set_bits = 0;
 
-		addr = devfdt_get_addr_size_index(dev, 0, &size);
-		if (addr == FDT_ADDR_T_NONE)
+		regs = dev_remap_addr(dev);
+		if (!regs)
 			return -EINVAL;
 
-		regs = ioremap(addr, size);
-
-		if (fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
-				    "brcm,serial-leds"))
+		if (dev_read_bool(dev, "brcm,serial-leds"))
 			set_bits |= LED_INIT_SLEDEN_MASK;
-		if (fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
-				    "brcm,serial-mux"))
+		if (dev_read_bool(dev, "brcm,serial-mux"))
 			set_bits |= LED_INIT_SLEDMUX_MASK;
-		if (fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
-				    "brcm,serial-clk-low"))
+		if (dev_read_bool(dev, "brcm,serial-clk-low"))
 			set_bits |= LED_INIT_SLEDCLKNPOL_MASK;
-		if (!fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
-				     "brcm,serial-dat-low"))
+		if (!dev_read_bool(dev, "brcm,serial-dat-low"))
 			set_bits |= LED_INIT_SLEDDATANPOL_MASK;
-		if (!fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
-				     "brcm,serial-shift-inv"))
+		if (!dev_read_bool(dev, "brcm,serial-shift-inv"))
 			set_bits |= LED_INIT_SLEDSHIFTDIR_MASK;
 
 		clrsetbits_be32(regs + LED_INIT_REG, ~0, set_bits);
@@ -184,17 +173,14 @@
 		struct bcm6328_led_priv *priv = dev_get_priv(dev);
 		unsigned int pin;
 
-		addr = devfdt_get_addr_size_index(dev_get_parent(dev), 0,
-						  &size);
-		if (addr == FDT_ADDR_T_NONE)
+		priv->regs = dev_remap_addr(dev);
+		if (!priv->regs)
 			return -EINVAL;
 
-		pin = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev), "reg",
-				      LEDS_MAX);
+		pin = dev_read_u32_default(dev, "reg", LEDS_MAX);
 		if (pin >= LEDS_MAX)
 			return -EINVAL;
 
-		priv->regs = ioremap(addr, size);
 		if (pin < 8) {
 			/* LEDs 0-7 (bits 47:32) */
 			priv->mode = priv->regs + LED_MODE_REG_HI;
@@ -205,8 +191,7 @@
 			priv->shift = ((pin - 8) << 1);
 		}
 
-		if (fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
-				    "active-low"))
+		if (dev_read_bool(dev, "active-low"))
 			priv->active_low = true;
 	}
 
@@ -215,27 +200,24 @@
 
 static int bcm6328_led_bind(struct udevice *parent)
 {
-	const void *blob = gd->fdt_blob;
-	int node;
+	ofnode node;
 
-	for (node = fdt_first_subnode(blob, dev_of_offset(parent));
-	     node > 0;
-	     node = fdt_next_subnode(blob, node)) {
+	dev_for_each_subnode(node, parent) {
 		struct led_uc_plat *uc_plat;
 		struct udevice *dev;
 		const char *label;
 		int ret;
 
-		label = fdt_getprop(blob, node, "label", NULL);
+		label = ofnode_read_string(node, "label");
 		if (!label) {
 			debug("%s: node %s has no label\n", __func__,
-			      fdt_get_name(blob, node, NULL));
+			      ofnode_get_name(node));
 			return -EINVAL;
 		}
 
 		ret = device_bind_driver_to_node(parent, "bcm6328-led",
-						 fdt_get_name(blob, node, NULL),
-						 offset_to_ofnode(node), &dev);
+						 ofnode_get_name(node),
+						 node, &dev);
 		if (ret)
 			return ret;
 
diff --git a/drivers/led/led_bcm6358.c b/drivers/led/led_bcm6358.c
index 4b1c24b..01b86b7 100644
--- a/drivers/led/led_bcm6358.c
+++ b/drivers/led/led_bcm6358.c
@@ -31,8 +31,6 @@
 #define LED_CTRL_BUSY_SHIFT	3
 #define LED_CTRL_BUSY_MASK	(1 << LED_CTRL_BUSY_SHIFT)
 
-DECLARE_GLOBAL_DATA_PTR;
-
 struct bcm6358_led_priv {
 	void __iomem *regs;
 	uint8_t pin;
@@ -114,8 +112,6 @@
 static int bcm6358_led_probe(struct udevice *dev)
 {
 	struct led_uc_plat *uc_plat = dev_get_uclass_platdata(dev);
-	fdt_addr_t addr;
-	fdt_size_t size;
 
 	/* Top-level LED node */
 	if (!uc_plat->label) {
@@ -123,17 +119,14 @@
 		unsigned int clk_div;
 		u32 set_bits = 0;
 
-		addr = devfdt_get_addr_size_index(dev, 0, &size);
-		if (addr == FDT_ADDR_T_NONE)
+		regs = dev_remap_addr(dev);
+		if (!regs)
 			return -EINVAL;
 
-		regs = ioremap(addr, size);
-
-		if (fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
-				    "brcm,clk-dat-low"))
+		if (dev_read_bool(dev, "brcm,clk-dat-low"))
 			set_bits |= LED_CTRL_POL_MASK;
-		clk_div = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
-					  "brcm,clk-div", LED_CTRL_CLK_1);
+		clk_div = dev_read_u32_default(dev, "brcm,clk-div",
+					       LED_CTRL_CLK_1);
 		switch (clk_div) {
 		case 8:
 			set_bits |= LED_CTRL_CLK_8;
@@ -157,21 +150,17 @@
 		struct bcm6358_led_priv *priv = dev_get_priv(dev);
 		unsigned int pin;
 
-		addr = devfdt_get_addr_size_index(dev_get_parent(dev), 0,
-						  &size);
-		if (addr == FDT_ADDR_T_NONE)
+		priv->regs = dev_remap_addr(dev);
+		if (!priv->regs)
 			return -EINVAL;
 
-		pin = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev), "reg",
-				      LEDS_MAX);
+		pin = dev_read_u32_default(dev, "reg", LEDS_MAX);
 		if (pin >= LEDS_MAX)
 			return -EINVAL;
 
-		priv->regs = ioremap(addr, size);
 		priv->pin = pin;
 
-		if (fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
-				    "active-low"))
+		if (dev_read_bool(dev, "active-low"))
 			priv->active_low = true;
 	}
 
@@ -180,27 +169,24 @@
 
 static int bcm6358_led_bind(struct udevice *parent)
 {
-	const void *blob = gd->fdt_blob;
-	int node;
+	ofnode node;
 
-	for (node = fdt_first_subnode(blob, dev_of_offset(parent));
-	     node > 0;
-	     node = fdt_next_subnode(blob, node)) {
+	dev_for_each_subnode(node, parent) {
 		struct led_uc_plat *uc_plat;
 		struct udevice *dev;
 		const char *label;
 		int ret;
 
-		label = fdt_getprop(blob, node, "label", NULL);
+		label = ofnode_read_string(node, "label");
 		if (!label) {
 			debug("%s: node %s has no label\n", __func__,
-			      fdt_get_name(blob, node, NULL));
+			      ofnode_get_name(node));
 			return -EINVAL;
 		}
 
 		ret = device_bind_driver_to_node(parent, "bcm6358-led",
-						 fdt_get_name(blob, node, NULL),
-						 offset_to_ofnode(node), &dev);
+						 ofnode_get_name(node),
+						 node, &dev);
 		if (ret)
 			return ret;
 
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index be900cf..17b3a80 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -158,6 +158,15 @@
 	help
 	  The I2C address of the PCA9551 LED controller.
 
+config STM32MP_FUSE
+	bool "Enable STM32MP fuse wrapper providing the fuse API"
+	depends on ARCH_STM32MP && MISC
+	default y if CMD_FUSE
+	help
+	  If you say Y here, you will get support for the fuse API (OTP)
+	  for STM32MP architecture.
+	  This API is needed for CMD_FUSE.
+
 config STM32_RCC
 	bool "Enable RCC driver for the STM32 SoC's family"
 	depends on STM32 && MISC
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index e362609..4ce9d21 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -51,5 +51,6 @@
 obj-$(CONFIG_QFW) += qfw.o
 obj-$(CONFIG_ROCKCHIP_EFUSE) += rockchip-efuse.o
 obj-$(CONFIG_STM32_RCC) += stm32_rcc.o
+obj-$(CONFIG_STM32MP_FUSE) += stm32mp_fuse.o
 obj-$(CONFIG_SYS_DPAA_QBMAN) += fsl_portals.o
 obj-$(CONFIG_GDSYS_RXAUI_CTRL) += gdsys_rxaui_ctrl.o
diff --git a/drivers/misc/stm32mp_fuse.c b/drivers/misc/stm32mp_fuse.c
new file mode 100644
index 0000000..2d66135
--- /dev/null
+++ b/drivers/misc/stm32mp_fuse.c
@@ -0,0 +1,116 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ */
+
+#include <common.h>
+#include <command.h>
+#include <misc.h>
+#include <errno.h>
+#include <dm/device.h>
+#include <dm/uclass.h>
+
+#define STM32MP_OTP_BANK	0
+
+/*
+ * The 'fuse' command API
+ */
+int fuse_read(u32 bank, u32 word, u32 *val)
+{
+	int ret = 0;
+	struct udevice *dev;
+
+	switch (bank) {
+	case STM32MP_OTP_BANK:
+		ret = uclass_get_device_by_driver(UCLASS_MISC,
+						  DM_GET_DRIVER(stm32mp_bsec),
+						  &dev);
+		if (ret)
+			return ret;
+		ret = misc_read(dev, word * 4 + STM32_BSEC_SHADOW_OFFSET,
+				val, 4);
+		break;
+
+	default:
+		printf("stm32mp %s: wrong value for bank %i\n", __func__, bank);
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+int fuse_prog(u32 bank, u32 word, u32 val)
+{
+	struct udevice *dev;
+	int ret;
+
+	switch (bank) {
+	case STM32MP_OTP_BANK:
+		ret = uclass_get_device_by_driver(UCLASS_MISC,
+						  DM_GET_DRIVER(stm32mp_bsec),
+						  &dev);
+		if (ret)
+			return ret;
+		ret = misc_write(dev, word * 4 + STM32_BSEC_OTP_OFFSET,
+				 &val, 4);
+		break;
+
+	default:
+		printf("stm32mp %s: wrong value for bank %i\n", __func__, bank);
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+int fuse_sense(u32 bank, u32 word, u32 *val)
+{
+	struct udevice *dev;
+	int ret;
+
+	switch (bank) {
+	case STM32MP_OTP_BANK:
+		ret = uclass_get_device_by_driver(UCLASS_MISC,
+						  DM_GET_DRIVER(stm32mp_bsec),
+						  &dev);
+		if (ret)
+			return ret;
+		ret = misc_read(dev, word * 4 + STM32_BSEC_OTP_OFFSET, val, 4);
+		break;
+
+	default:
+		printf("stm32mp %s: wrong value for bank %i\n", __func__, bank);
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+int fuse_override(u32 bank, u32 word, u32 val)
+{
+	struct udevice *dev;
+	int ret;
+
+	switch (bank) {
+	case STM32MP_OTP_BANK:
+		ret = uclass_get_device_by_driver(UCLASS_MISC,
+						  DM_GET_DRIVER(stm32mp_bsec),
+						  &dev);
+		if (ret)
+			return ret;
+		ret = misc_write(dev, word * 4 + STM32_BSEC_SHADOW_OFFSET,
+				 &val, 4);
+		break;
+
+	default:
+		printf("stm32mp %s: wrong value for bank %i\n",
+		       __func__, bank);
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
diff --git a/drivers/mmc/ftsdc010_mci.c b/drivers/mmc/ftsdc010_mci.c
index 00209e3..9c15eb3 100644
--- a/drivers/mmc/ftsdc010_mci.c
+++ b/drivers/mmc/ftsdc010_mci.c
@@ -463,7 +463,7 @@
 }
 
 static const struct udevice_id ftsdc010_mmc_ids[] = {
-	{ .compatible = "andestech,atsdc010" },
+	{ .compatible = "andestech,atfsdc010" },
 	{ }
 };
 
diff --git a/drivers/mmc/renesas-sdhi.c b/drivers/mmc/renesas-sdhi.c
index 6257789..ecdb088 100644
--- a/drivers/mmc/renesas-sdhi.c
+++ b/drivers/mmc/renesas-sdhi.c
@@ -323,6 +323,7 @@
 	{ .compatible = "renesas,sdhi-r8a7796", .data = RENESAS_GEN3_QUIRKS },
 	{ .compatible = "renesas,sdhi-r8a77965", .data = RENESAS_GEN3_QUIRKS },
 	{ .compatible = "renesas,sdhi-r8a77970", .data = RENESAS_GEN3_QUIRKS },
+	{ .compatible = "renesas,sdhi-r8a77990", .data = RENESAS_GEN3_QUIRKS },
 	{ .compatible = "renesas,sdhi-r8a77995", .data = RENESAS_GEN3_QUIRKS },
 	{ /* sentinel */ }
 };
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 400f87e..40e28ab 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -161,7 +161,8 @@
 	/* We shouldn't wait for data inihibit for stop commands, even
 	   though they might use busy signaling */
 	if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION ||
-	    cmd->cmdidx ==  MMC_CMD_SEND_TUNING_BLOCK)
+	    cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK ||
+	    cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK_HS200)
 		mask &= ~SDHCI_DATA_INHIBIT;
 
 	while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
@@ -183,7 +184,8 @@
 	sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_INT_STATUS);
 
 	mask = SDHCI_INT_RESPONSE;
-	if (cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK)
+	if (cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK ||
+	    cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK_HS200)
 		mask = SDHCI_INT_DATA_AVAIL;
 
 	if (!(cmd->resp_type & MMC_RSP_PRESENT))
@@ -201,7 +203,8 @@
 		flags |= SDHCI_CMD_CRC;
 	if (cmd->resp_type & MMC_RSP_OPCODE)
 		flags |= SDHCI_CMD_INDEX;
-	if (data || cmd->cmdidx ==  MMC_CMD_SEND_TUNING_BLOCK)
+	if (data || cmd->cmdidx ==  MMC_CMD_SEND_TUNING_BLOCK ||
+	    cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK_HS200)
 		flags |= SDHCI_CMD_DATA;
 
 	/* Set Transfer mode regarding to data flag */
diff --git a/drivers/mmc/stm32_sdmmc2.c b/drivers/mmc/stm32_sdmmc2.c
index 11cc438..e8292c4 100644
--- a/drivers/mmc/stm32_sdmmc2.c
+++ b/drivers/mmc/stm32_sdmmc2.c
@@ -235,8 +235,8 @@
 static void stm32_sdmmc2_start_cmd(struct stm32_sdmmc2_priv *priv,
 				   struct mmc_cmd *cmd, u32 cmd_param)
 {
-	if (readl(priv->base + SDMMC_ARG) & SDMMC_CMD_CPSMEN)
-		writel(0, priv->base + SDMMC_ARG);
+	if (readl(priv->base + SDMMC_CMD) & SDMMC_CMD_CPSMEN)
+		writel(0, priv->base + SDMMC_CMD);
 
 	cmd_param |= cmd->cmdidx | SDMMC_CMD_CPSMEN;
 	if (cmd->resp_type & MMC_RSP_PRESENT) {
diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c
index f99731f..5b6d525 100644
--- a/drivers/mmc/zynq_sdhci.c
+++ b/drivers/mmc/zynq_sdhci.c
@@ -32,12 +32,21 @@
 };
 
 #if defined(CONFIG_ARCH_ZYNQMP)
+#define MMC_HS200_BUS_SPEED	5
+
 static const u8 mode2timing[] = {
-	     [UHS_SDR12] = UHS_SDR12_BUS_SPEED,
-	     [UHS_SDR25] = UHS_SDR25_BUS_SPEED,
-	     [UHS_SDR50] = UHS_SDR50_BUS_SPEED,
-	     [UHS_SDR104] = UHS_SDR104_BUS_SPEED,
-	     [UHS_DDR50] = UHS_DDR50_BUS_SPEED,
+	[MMC_LEGACY] = UHS_SDR12_BUS_SPEED,
+	[SD_LEGACY] = UHS_SDR12_BUS_SPEED,
+	[MMC_HS] = HIGH_SPEED_BUS_SPEED,
+	[SD_HS] = HIGH_SPEED_BUS_SPEED,
+	[MMC_HS_52] = HIGH_SPEED_BUS_SPEED,
+	[MMC_DDR_52] = HIGH_SPEED_BUS_SPEED,
+	[UHS_SDR12] = UHS_SDR12_BUS_SPEED,
+	[UHS_SDR25] = UHS_SDR25_BUS_SPEED,
+	[UHS_SDR50] = UHS_SDR50_BUS_SPEED,
+	[UHS_DDR50] = UHS_DDR50_BUS_SPEED,
+	[UHS_SDR104] = UHS_SDR104_BUS_SPEED,
+	[MMC_HS_200] = MMC_HS200_BUS_SPEED,
 };
 
 #define SDHCI_HOST_CTRL2	0x3E
@@ -160,9 +169,6 @@
 	struct mmc *mmc = (struct mmc *)host->mmc;
 	u8 uhsmode;
 
-	if (!IS_SD(mmc))
-		return;
-
 	uhsmode = mode2timing[mmc->selected_mode];
 
 	if (uhsmode >= UHS_SDR25_BUS_SPEED)
@@ -175,6 +181,9 @@
 	struct mmc *mmc = (struct mmc *)host->mmc;
 	u32 reg;
 
+	if (!IS_SD(mmc))
+		return;
+
 	if (mmc->signal_voltage == MMC_SIGNAL_VOLTAGE_180) {
 		reg = sdhci_readw(host, SDHCI_HOST_CTRL2);
 		reg |= SDHCI_18V_SIGNAL;
@@ -283,25 +292,21 @@
 		return -1;
 
 	priv->host->name = dev->name;
-	priv->host->ioaddr = (void *)devfdt_get_addr(dev);
-
-	priv->deviceid = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
-					"xlnx,device_id", -1);
-	priv->bank = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
-				    "xlnx,mio_bank", -1);
-	if (fdt_get_property(gd->fdt_blob, dev_of_offset(dev),
-			     "no-1-8-v", NULL))
-		priv->no_1p8 = 1;
-	else
-		priv->no_1p8 = 0;
 
 #if defined(CONFIG_DM_MMC) && defined(CONFIG_ARCH_ZYNQMP)
 	priv->host->ops = &arasan_ops;
 #endif
 
-	plat->f_max = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
-				"max-frequency", CONFIG_ZYNQ_SDHCI_MAX_FREQ);
+	priv->host->ioaddr = (void *)dev_read_addr(dev);
+	if (IS_ERR(priv->host->ioaddr))
+		return PTR_ERR(priv->host->ioaddr);
 
+	priv->deviceid = dev_read_u32_default(dev, "xlnx,device_id", -1);
+	priv->bank = dev_read_u32_default(dev, "xlnx,mio_bank", -1);
+	priv->no_1p8 = dev_read_bool(dev, "no-1-8-v");
+
+	plat->f_max = dev_read_u32_default(dev, "max-frequency",
+					   CONFIG_ZYNQ_SDHCI_MAX_FREQ);
 	return 0;
 }
 
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index eb593c9..9cec065 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -12,7 +12,6 @@
 obj-$(CONFIG_ALTERA_QSPI) += altera_qspi.o
 obj-$(CONFIG_FLASH_CFI_DRIVER) += cfi_flash.o
 obj-$(CONFIG_FLASH_CFI_MTD) += cfi_mtd.o
-obj-$(CONFIG_FTSMC020) += ftsmc020.o
 obj-$(CONFIG_FLASH_CFI_LEGACY) += jedec_flash.o
 obj-$(CONFIG_MW_EEPROM) += mw_eeprom.o
 obj-$(CONFIG_FLASH_PIC32) += pic32_flash.o
diff --git a/drivers/mtd/ftsmc020.c b/drivers/mtd/ftsmc020.c
deleted file mode 100644
index 41cdd0e..0000000
--- a/drivers/mtd/ftsmc020.c
+++ /dev/null
@@ -1,37 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * (C) Copyright 2009 Faraday Technology
- * Po-Yu Chuang <ratbert@faraday-tech.com>
- */
-
-#include <config.h>
-#include <common.h>
-#include <asm/io.h>
-#include <faraday/ftsmc020.h>
-
-struct ftsmc020_config {
-	unsigned int	config;
-	unsigned int	timing;
-};
-
-static void ftsmc020_setup_bank(unsigned int bank, struct ftsmc020_config *cfg)
-{
-	struct ftsmc020 *smc = (struct ftsmc020 *)CONFIG_FTSMC020_BASE;
-
-	if (bank > 3) {
-		printf("bank # %u invalid\n", bank);
-		return;
-	}
-
-	writel(cfg->config, &smc->bank[bank].cr);
-	writel(cfg->timing, &smc->bank[bank].tpr);
-}
-
-void ftsmc020_init(void)
-{
-	struct ftsmc020_config config[] = CONFIG_SYS_FTSMC020_CONFIGS;
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(config); i++)
-		ftsmc020_setup_bank(i, &config[i]);
-}
diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index 2911729..0ed2317 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -1202,14 +1202,15 @@
 	flash->shift = (flash->dual_flash & SF_DUAL_PARALLEL_FLASH) ? 1 : 0;
 	flash->page_size = info->page_size;
 	/*
-	 * The Spansion S25FL032P and S25FL064P have 256b pages, yet use the
-	 * 0x4d00 Extended JEDEC code. The rest of the Spansion flashes with
-	 * the 0x4d00 Extended JEDEC code have 512b pages. All of the others
-	 * have 256b pages.
+	 * The Spansion S25FS512S, S25FL032P and S25FL064P have 256b pages,
+	 * yet use the 0x4d00 Extended JEDEC code. The rest of the Spansion
+	 * flashes with the 0x4d00 Extended JEDEC code have 512b pages.
+	 * All of the others have 256b pages.
 	 */
 	if (JEDEC_EXT(info) == 0x4d00) {
 		if ((JEDEC_ID(info) != 0x0215) &&
-		    (JEDEC_ID(info) != 0x0216))
+		    (JEDEC_ID(info) != 0x0216) &&
+		    (JEDEC_ID(info) != 0x0220))
 			flash->page_size = 512;
 	}
 	flash->page_size <<= flash->shift;
diff --git a/drivers/mtd/spi/spi_flash_ids.c b/drivers/mtd/spi/spi_flash_ids.c
index 41879d6..5d146e3 100644
--- a/drivers/mtd/spi/spi_flash_ids.c
+++ b/drivers/mtd/spi/spi_flash_ids.c
@@ -71,6 +71,9 @@
 	{"is25lp064",	   INFO(0x9d6017, 0x0, 64 * 1024,   128, 0) },
 	{"is25lp128",	   INFO(0x9d6018, 0x0, 64 * 1024,   256, 0) },
 	{"is25lp256",	   INFO(0x9d6019, 0x0, 64 * 1024,   512, 0) },
+	{"is25wp032",	   INFO(0x9d7016, 0x0, 64 * 1024,    64, RD_FULL | SECT_4K) },
+	{"is25wp064",	   INFO(0x9d7017, 0x0, 64 * 1024,   128, RD_FULL | SECT_4K) },
+	{"is25wp128",	   INFO(0x9d7018, 0x0, 64 * 1024,   256, RD_FULL | SECT_4K) },
 #endif
 #ifdef CONFIG_SPI_FLASH_MACRONIX	/* MACRONIX */
 	{"mx25l2006e",	   INFO(0xc22012, 0x0, 64 * 1024,     4, 0) },
@@ -85,6 +88,7 @@
 	{"mx25u6435f",	   INFO(0xc22537, 0x0, 64 * 1024,   128, RD_FULL | WR_QPP) },
 	{"mx25l12855e",	   INFO(0xc22618, 0x0, 64 * 1024,   256, RD_FULL | WR_QPP) },
 	{"mx25u1635e",     INFO(0xc22535, 0x0, 64 * 1024,  32, SECT_4K) },
+	{"mx25u25635f",    INFO(0xc22539, 0x0, 64 * 1024,   512, RD_FULL | WR_QPP) },
 	{"mx66u51235f",    INFO(0xc2253a, 0x0, 64 * 1024,  1024, RD_FULL | WR_QPP) },
 	{"mx66l1g45g",     INFO(0xc2201b, 0x0, 64 * 1024,  2048, RD_FULL | WR_QPP) },
 #endif
@@ -174,6 +178,7 @@
 	{"w25q32dw",	   INFO(0xef6016, 0x0,	64 * 1024,    64, RD_FULL | WR_QPP | SECT_4K) },
 	{"w25q64dw",	   INFO(0xef6017, 0x0,	64 * 1024,   128, RD_FULL | WR_QPP | SECT_4K) },
 	{"w25q128fw",	   INFO(0xef6018, 0x0,	64 * 1024,   256, RD_FULL | WR_QPP | SECT_4K) },
+	{"w25q256fw",	   INFO(0xef6019, 0x0,	64 * 1024,   512, RD_FULL | WR_QPP | SECT_4K) },
 #endif
 	{},	/* Empty entry to terminate the list */
 	/*
@@ -188,5 +193,6 @@
 	 * (w25q32dw, w25q32fv_qpi)
 	 * (w25q64dw, w25q64fv_qpi)
 	 * (w25q128fw, w25q128fv_qpi)
+	 * (w25q256fw, w25q256fv_qpi)
 	 */
 };
diff --git a/drivers/mtd/ubi/fastmap-wl.c b/drivers/mtd/ubi/fastmap-wl.c
index 675e487..4cb1377 100644
--- a/drivers/mtd/ubi/fastmap-wl.c
+++ b/drivers/mtd/ubi/fastmap-wl.c
@@ -170,6 +170,30 @@
 }
 
 /**
+ * produce_free_peb - produce a free physical eraseblock.
+ * @ubi: UBI device description object
+ *
+ * This function tries to make a free PEB by means of synchronous execution of
+ * pending works. This may be needed if, for example the background thread is
+ * disabled. Returns zero in case of success and a negative error code in case
+ * of failure.
+ */
+static int produce_free_peb(struct ubi_device *ubi)
+{
+	int err;
+
+	while (!ubi->free.rb_node && ubi->works_count) {
+		dbg_wl("do one work synchronously");
+		err = do_work(ubi);
+
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
+/**
  * ubi_wl_get_peb - get a physical eraseblock.
  * @ubi: UBI device description object
  *
@@ -211,6 +235,11 @@
 		}
 		retried = 1;
 		up_read(&ubi->fm_eba_sem);
+		ret = produce_free_peb(ubi);
+		if (ret < 0) {
+			down_read(&ubi->fm_eba_sem);
+			goto out;
+		}
 		goto again;
 	}
 
diff --git a/drivers/net/ftmac100.c b/drivers/net/ftmac100.c
index 6c84748..c08889c 100644
--- a/drivers/net/ftmac100.c
+++ b/drivers/net/ftmac100.c
@@ -104,18 +104,18 @@
 
 	for (i = 0; i < PKTBUFSRX; i++) {
 		/* RXBUF_BADR */
-		rxdes[i].rxdes2 = (unsigned int)net_rx_packets[i];
+		rxdes[i].rxdes2 = (unsigned int)(unsigned long)net_rx_packets[i];
 		rxdes[i].rxdes1 |= FTMAC100_RXDES1_RXBUF_SIZE (PKTSIZE_ALIGN);
 		rxdes[i].rxdes0 = FTMAC100_RXDES0_RXDMA_OWN;
 	}
 
 	/* transmit ring */
 
-	writel ((unsigned int)txdes, &ftmac100->txr_badr);
+	writel ((unsigned long)txdes, &ftmac100->txr_badr);
 
 	/* receive ring */
 
-	writel ((unsigned int)rxdes, &ftmac100->rxr_badr);
+	writel ((unsigned long)rxdes, &ftmac100->rxr_badr);
 
 	/* poll receive descriptor automatically */
 
@@ -192,14 +192,14 @@
 		return -1;
 	}
 
-	debug ("%s(%x, %x)\n", __func__, (int)packet, length);
+	debug ("%s(%lx, %x)\n", __func__, (unsigned long)packet, length);
 
 	length = (length < ETH_ZLEN) ? ETH_ZLEN : length;
 
 	/* initiate a transmit sequence */
 
-	flush_dcache_range((u32)packet,(u32)packet+length);
-	curr_des->txdes2 = (unsigned int)packet;	/* TXBUF_BADR */
+	flush_dcache_range((unsigned long)packet,(unsigned long)packet+length);
+	curr_des->txdes2 = (unsigned int)(unsigned long)packet;	/* TXBUF_BADR */
 
 	curr_des->txdes1 &= FTMAC100_TXDES1_EDOTR;
 	curr_des->txdes1 |= FTMAC100_TXDES1_FTS |
@@ -343,7 +343,7 @@
 	int len;
 	len = __ftmac100_recv(priv);
 	if (len)
-		*packetp = (void *)curr_des->rxdes2;
+		*packetp = (uchar *)(unsigned long)curr_des->rxdes2;
 
 	return len ? len : -EAGAIN;
 }
diff --git a/drivers/net/ravb.c b/drivers/net/ravb.c
index 3392e58..999894f 100644
--- a/drivers/net/ravb.c
+++ b/drivers/net/ravb.c
@@ -659,6 +659,7 @@
 	{ .compatible = "renesas,etheravb-r8a7796" },
 	{ .compatible = "renesas,etheravb-r8a77965" },
 	{ .compatible = "renesas,etheravb-r8a77970" },
+	{ .compatible = "renesas,etheravb-r8a77990" },
 	{ .compatible = "renesas,etheravb-r8a77995" },
 	{ .compatible = "renesas,etheravb-rcar-gen3" },
 	{ }
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index 49be1eb..1cd1e40 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -860,6 +860,13 @@
 		} else {
 			continue;
 		}
+
+		if (!IS_ENABLED(CONFIG_SYS_PCI_64BIT) &&
+		    type == PCI_REGION_MEM && upper_32_bits(pci_addr)) {
+			debug(" - beyond the 32-bit boundary, ignoring\n");
+			continue;
+		}
+
 		pos = -1;
 		for (i = 0; i < hose->region_count; i++) {
 			if (hose->regions[i].flags == type)
diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c
index d1feb50..d7237f6 100644
--- a/drivers/pci/pci_auto.c
+++ b/drivers/pci/pci_auto.c
@@ -98,7 +98,8 @@
 		}
 
 		if (!enum_only && pciauto_region_allocate(bar_res, bar_size,
-							  &bar_value) == 0) {
+							  &bar_value,
+							  found_mem64) == 0) {
 			/* Write it out and update our limit */
 			dm_pci_write_config32(dev, bar, (u32)bar_value);
 
@@ -140,7 +141,8 @@
 				debug("PCI Autoconfig: ROM, size=%#x, ",
 				      (unsigned int)bar_size);
 				if (pciauto_region_allocate(mem, bar_size,
-							    &bar_value) == 0) {
+							    &bar_value,
+							    false) == 0) {
 					dm_pci_write_config32(dev, rom_addr,
 							      bar_value);
 				}
diff --git a/drivers/pci/pci_auto_common.c b/drivers/pci/pci_auto_common.c
index 1d202ae..1837873 100644
--- a/drivers/pci/pci_auto_common.c
+++ b/drivers/pci/pci_auto_common.c
@@ -32,12 +32,12 @@
 }
 
 int pciauto_region_allocate(struct pci_region *res, pci_size_t size,
-	pci_addr_t *bar)
+	pci_addr_t *bar, bool supports_64bit)
 {
 	pci_addr_t addr;
 
 	if (!res) {
-		debug("No resource");
+		debug("No resource\n");
 		goto error;
 	}
 
@@ -48,9 +48,14 @@
 		goto error;
 	}
 
+	if (upper_32_bits(addr) && !supports_64bit) {
+		debug("Cannot assign 64-bit address to 32-bit-only resource\n");
+		goto error;
+	}
+
 	res->bus_lower = addr + size;
 
-	debug("address=0x%llx bus_lower=0x%llx", (unsigned long long)addr,
+	debug("address=0x%llx bus_lower=0x%llx\n", (unsigned long long)addr,
 	      (unsigned long long)res->bus_lower);
 
 	*bar = addr;
diff --git a/drivers/pci/pci_auto_old.c b/drivers/pci/pci_auto_old.c
index bc119fb..e705a30 100644
--- a/drivers/pci/pci_auto_old.c
+++ b/drivers/pci/pci_auto_old.c
@@ -108,7 +108,8 @@
 		}
 
 #ifndef CONFIG_PCI_ENUM_ONLY
-		if (pciauto_region_allocate(bar_res, bar_size, &bar_value) == 0) {
+		if (pciauto_region_allocate(bar_res, bar_size,
+					    &bar_value, found_mem64) == 0) {
 			/* Write it out and update our limit */
 			pci_hose_write_config_dword(hose, dev, bar, (u32)bar_value);
 
@@ -150,7 +151,7 @@
 			debug("PCI Autoconfig: ROM, size=%#x, ",
 			      (unsigned int)bar_size);
 			if (pciauto_region_allocate(mem, bar_size,
-						    &bar_value) == 0) {
+						    &bar_value, false) == 0) {
 				pci_hose_write_config_dword(hose, dev, rom_addr,
 							    bar_value);
 			}
diff --git a/drivers/phy/bcm6318-usbh-phy.c b/drivers/phy/bcm6318-usbh-phy.c
index f5bcf18..de055a3 100644
--- a/drivers/phy/bcm6318-usbh-phy.c
+++ b/drivers/phy/bcm6318-usbh-phy.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
  *
  * Derived from linux/arch/mips/bcm63xx/usb-common.c:
  *	Copyright 2008 Maxime Bizon <mbizon@freebox.fr>
@@ -79,16 +79,12 @@
 	struct power_domain pwr_dom;
 	struct reset_ctl rst_ctl;
 	struct clk clk;
-	fdt_addr_t addr;
-	fdt_size_t size;
 	int ret;
 
-	addr = devfdt_get_addr_size_index(dev, 0, &size);
-	if (addr == FDT_ADDR_T_NONE)
+	priv->regs = dev_remap_addr(dev);
+	if (!priv->regs)
 		return -EINVAL;
 
-	priv->regs = ioremap(addr, size);
-
 	/* enable usbh clock */
 	ret = clk_get_by_name(dev, "usbh", &clk);
 	if (ret < 0)
diff --git a/drivers/phy/bcm6348-usbh-phy.c b/drivers/phy/bcm6348-usbh-phy.c
index f305738..e7761e3 100644
--- a/drivers/phy/bcm6348-usbh-phy.c
+++ b/drivers/phy/bcm6348-usbh-phy.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
  *
  * Derived from linux/arch/mips/bcm63xx/usb-common.c:
  *	Copyright 2008 Maxime Bizon <mbizon@freebox.fr>
@@ -44,16 +44,12 @@
 	struct bcm6348_usbh_priv *priv = dev_get_priv(dev);
 	struct reset_ctl rst_ctl;
 	struct clk clk;
-	fdt_addr_t addr;
-	fdt_size_t size;
 	int ret;
 
-	addr = devfdt_get_addr_size_index(dev, 0, &size);
-	if (addr == FDT_ADDR_T_NONE)
+	priv->regs = dev_remap_addr(dev);
+	if (!priv->regs)
 		return -EINVAL;
 
-	priv->regs = ioremap(addr, size);
-
 	/* enable usbh clock */
 	ret = clk_get_by_name(dev, "usbh", &clk);
 	if (ret < 0)
diff --git a/drivers/phy/bcm6358-usbh-phy.c b/drivers/phy/bcm6358-usbh-phy.c
index 9eb641a..189a1c1 100644
--- a/drivers/phy/bcm6358-usbh-phy.c
+++ b/drivers/phy/bcm6358-usbh-phy.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
  *
  * Derived from linux/arch/mips/bcm63xx/usb-common.c:
  *	Copyright 2008 Maxime Bizon <mbizon@freebox.fr>
@@ -57,16 +57,12 @@
 {
 	struct bcm6358_usbh_priv *priv = dev_get_priv(dev);
 	struct reset_ctl rst_ctl;
-	fdt_addr_t addr;
-	fdt_size_t size;
 	int ret;
 
-	addr = devfdt_get_addr_size_index(dev, 0, &size);
-	if (addr == FDT_ADDR_T_NONE)
+	priv->regs = dev_remap_addr(dev);
+	if (!priv->regs)
 		return -EINVAL;
 
-	priv->regs = ioremap(addr, size);
-
 	/* perform reset */
 	ret = reset_get_by_index(dev, 0, &rst_ctl);
 	if (ret < 0)
diff --git a/drivers/phy/bcm6368-usbh-phy.c b/drivers/phy/bcm6368-usbh-phy.c
index 02197ed..99da97a 100644
--- a/drivers/phy/bcm6368-usbh-phy.c
+++ b/drivers/phy/bcm6368-usbh-phy.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
  *
  * Derived from linux/arch/mips/bcm63xx/usb-common.c:
  *	Copyright 2008 Maxime Bizon <mbizon@freebox.fr>
@@ -116,15 +116,12 @@
 #endif
 	struct reset_ctl rst_ctl;
 	struct clk clk;
-	fdt_addr_t addr;
-	fdt_size_t size;
 	int ret;
 
-	addr = devfdt_get_addr_size_index(dev, 0, &size);
-	if (addr == FDT_ADDR_T_NONE)
+	priv->regs = dev_remap_addr(dev);
+	if (!priv->regs)
 		return -EINVAL;
 
-	priv->regs = ioremap(addr, size);
 	priv->hw = hw;
 
 	/* enable usbh clock */
diff --git a/drivers/pinctrl/mvebu/pinctrl-mvebu.c b/drivers/pinctrl/mvebu/pinctrl-mvebu.c
index d4f2970..0b9c9e1 100644
--- a/drivers/pinctrl/mvebu/pinctrl-mvebu.c
+++ b/drivers/pinctrl/mvebu/pinctrl-mvebu.c
@@ -16,8 +16,48 @@
 #include <asm/arch-armada8k/soc-info.h>
 #include "pinctrl-mvebu.h"
 
+#define AP_EMMC_PHY_CTRL_REG		0x100
+#define CP_EMMC_PHY_CTRL_REG		0x424
+#define EMMC_PHY_CTRL_SDPHY_EN		BIT(0)
+
+#define AP806_EMMC_CLK_PIN_ID		0
+#define AP806_EMMC_CLK_FUNC		0x1
+#define CP110_EMMC_CLK_PIN_ID		56
+#define CP110_EMMC_CLK_FUNC		0xe
+
 DECLARE_GLOBAL_DATA_PTR;
 
+/* mvebu_pinctl_emmc_set_mux: configure sd/mmc PHY mux
+ * To enable SDIO/eMMC in Armada-APN806/CP110, need to configure PHY mux.
+ * eMMC/SD PHY register responsible for muxing between MPPs and SD/eMMC
+ * controller:
+ * - Bit0 enabled SDIO/eMMC PHY is used as a MPP muxltiplexer,
+ * - Bit0 disabled SDIO/eMMC PHY is connected to SDIO/eMMC controller
+ * If pin function is set to eMMC/SD, then configure the eMMC/SD PHY
+ * muxltiplexer register to be on SDIO/eMMC controller
+ */
+void mvebu_pinctl_emmc_set_mux(struct udevice *dev, u32 pin, u32 func)
+{
+	const void *blob = gd->fdt_blob;
+	int node = dev_of_offset(dev);
+	struct mvebu_pinctrl_priv *priv = dev_get_priv(dev);
+
+	if (!fdt_node_check_compatible(blob, node, "marvell,ap806-pinctrl")) {
+		if ((pin == AP806_EMMC_CLK_PIN_ID) &&
+		    (func == AP806_EMMC_CLK_FUNC)) {
+			clrbits_le32(priv->base_reg + AP_EMMC_PHY_CTRL_REG,
+				     EMMC_PHY_CTRL_SDPHY_EN);
+		}
+	} else if (!fdt_node_check_compatible(blob, node,
+					"marvell,armada-8k-cpm-pinctrl")) {
+		if ((pin == CP110_EMMC_CLK_PIN_ID) &&
+		    (func == CP110_EMMC_CLK_FUNC)) {
+			clrbits_le32(priv->base_reg + CP_EMMC_PHY_CTRL_REG,
+				     EMMC_PHY_CTRL_SDPHY_EN);
+		}
+	}
+}
+
 /*
  * mvebu_pinctrl_set_state: configure pin functions.
  * @dev: the pinctrl device to be configured.
@@ -47,9 +87,16 @@
 
 	function = fdtdec_get_int(blob, node, "marvell,function", 0xff);
 
+	/*
+	 * Check if setup of PHY mux is needed for this pins group.
+	 * Only the first pin id in array is tested, all the rest use the same
+	 * pin function.
+	 */
+	mvebu_pinctl_emmc_set_mux(dev, pin_arr[0], function);
+
 	for (i = 0; i < pin_count; i++) {
-	int reg_offset;
-	int field_offset;
+		int reg_offset;
+		int field_offset;
 		int pin = pin_arr[i];
 
 		if (function > priv->max_func) {
@@ -96,6 +143,14 @@
 		return -EINVAL;
 	}
 
+	/* Check if setup of PHY mux is needed for this pins group. */
+	if (priv->pin_cnt < CP110_EMMC_CLK_PIN_ID)
+		mvebu_pinctl_emmc_set_mux(dev, AP806_EMMC_CLK_PIN_ID,
+					  func_arr[AP806_EMMC_CLK_PIN_ID]);
+	else
+		mvebu_pinctl_emmc_set_mux(dev, CP110_EMMC_CLK_PIN_ID,
+					  func_arr[CP110_EMMC_CLK_PIN_ID]);
+
 	for (pin = 0; pin < priv->pin_cnt; pin++) {
 		int reg_offset;
 		int field_offset;
@@ -161,10 +216,10 @@
 
 static const struct udevice_id mvebu_pinctrl_ids[] = {
 	{ .compatible = "marvell,mvebu-pinctrl" },
-	{ .compatible = "marvell,armada-ap806-pinctrl" },
-	{ .compatible = "marvell,a70x0-pinctrl" },
-	{ .compatible = "marvell,a80x0-cp0-pinctrl" },
-	{ .compatible = "marvell,a80x0-cp1-pinctrl" },
+	{ .compatible = "marvell,ap806-pinctrl" },
+	{ .compatible = "marvell,armada-7k-pinctrl" },
+	{ .compatible = "marvell,armada-8k-cpm-pinctrl" },
+	{ .compatible = "marvell,armada-8k-cps-pinctrl" },
 	{ }
 };
 
diff --git a/drivers/pinctrl/renesas/Kconfig b/drivers/pinctrl/renesas/Kconfig
index 5e6d854..1baab90 100644
--- a/drivers/pinctrl/renesas/Kconfig
+++ b/drivers/pinctrl/renesas/Kconfig
@@ -94,6 +94,17 @@
 	  the GPIO definitions and pin control functions for each available
 	  multiplex function.
 
+config PINCTRL_PFC_R8A77990
+	bool "Renesas RCar Gen3 R8A77990 pin control driver"
+	def_bool y if R8A77990
+	depends on PINCTRL_PFC
+	help
+	  Support pin multiplexing control on Renesas RCar Gen3 R8A77990 SoCs.
+
+	  The driver is controlled by a device tree node which contains both
+	  the GPIO definitions and pin control functions for each available
+	  multiplex function.
+
 config PINCTRL_PFC_R8A77995
 	bool "Renesas RCar Gen3 R8A77995 pin control driver"
 	def_bool y if R8A77995
diff --git a/drivers/pinctrl/renesas/Makefile b/drivers/pinctrl/renesas/Makefile
index 29b9912..62bc40b 100644
--- a/drivers/pinctrl/renesas/Makefile
+++ b/drivers/pinctrl/renesas/Makefile
@@ -7,4 +7,5 @@
 obj-$(CONFIG_PINCTRL_PFC_R8A7795) += pfc-r8a7795.o
 obj-$(CONFIG_PINCTRL_PFC_R8A7796) += pfc-r8a7796.o
 obj-$(CONFIG_PINCTRL_PFC_R8A77970) += pfc-r8a77970.o
+obj-$(CONFIG_PINCTRL_PFC_R8A77990) += pfc-r8a77990.o
 obj-$(CONFIG_PINCTRL_PFC_R8A77995) += pfc-r8a77995.o
diff --git a/drivers/pinctrl/renesas/pfc-r8a77990.c b/drivers/pinctrl/renesas/pfc-r8a77990.c
new file mode 100644
index 0000000..f66b159
--- /dev/null
+++ b/drivers/pinctrl/renesas/pfc-r8a77990.c
@@ -0,0 +1,1731 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * R8A77990 processor support - PFC hardware block.
+ *
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ *
+ * This file is based on the drivers/pinctrl/sh-pfc/pfc-r8a7796.c
+ *
+ * R-Car Gen3 processor support - PFC hardware block.
+ *
+ * Copyright (C) 2015  Renesas Electronics Corporation
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <dm/pinctrl.h>
+#include <linux/kernel.h>
+
+#include "sh_pfc.h"
+
+#define CPU_ALL_PORT(fn, sfx)	\
+	PORT_GP_18(0, fn, sfx),	\
+	PORT_GP_23(1, fn, sfx),	\
+	PORT_GP_26(2, fn, sfx),	\
+	PORT_GP_16(3, fn, sfx),	\
+	PORT_GP_11(4, fn, sfx),	\
+	PORT_GP_20(5, fn, sfx),	\
+	PORT_GP_18(6, fn, sfx)
+
+/*
+ * F_() : just information
+ * FM() : macro for FN_xxx / xxx_MARK
+ */
+
+/* GPSR0 */
+#define GPSR0_17	F_(SDA4,		IP7_27_24)
+#define GPSR0_16	F_(SCL4,		IP7_23_20)
+#define GPSR0_15	F_(D15,			IP7_19_16)
+#define GPSR0_14	F_(D14,			IP7_15_12)
+#define GPSR0_13	F_(D13,			IP7_11_8)
+#define GPSR0_12	F_(D12,			IP7_7_4)
+#define GPSR0_11	F_(D11,			IP7_3_0)
+#define GPSR0_10	F_(D10,			IP6_31_28)
+#define GPSR0_9		F_(D9,			IP6_27_24)
+#define GPSR0_8		F_(D8,			IP6_23_20)
+#define GPSR0_7		F_(D7,			IP6_19_16)
+#define GPSR0_6		F_(D6,			IP6_15_12)
+#define GPSR0_5		F_(D5,			IP6_11_8)
+#define GPSR0_4		F_(D4,			IP6_7_4)
+#define GPSR0_3		F_(D3,			IP6_3_0)
+#define GPSR0_2		F_(D2,			IP5_31_28)
+#define GPSR0_1		F_(D1,			IP5_27_24)
+#define GPSR0_0		F_(D0,			IP5_23_20)
+
+/* GPSR1 */
+#define GPSR1_22	F_(WE0_N,		IP5_19_16)
+#define GPSR1_21	F_(CS0_N,		IP5_15_12)
+#define GPSR1_20	FM(CLKOUT)
+#define GPSR1_19	F_(A19,			IP5_11_8)
+#define GPSR1_18	F_(A18,			IP5_7_4)
+#define GPSR1_17	F_(A17,			IP5_3_0)
+#define GPSR1_16	F_(A16,			IP4_31_28)
+#define GPSR1_15	F_(A15,			IP4_27_24)
+#define GPSR1_14	F_(A14,			IP4_23_20)
+#define GPSR1_13	F_(A13,			IP4_19_16)
+#define GPSR1_12	F_(A12,			IP4_15_12)
+#define GPSR1_11	F_(A11,			IP4_11_8)
+#define GPSR1_10	F_(A10,			IP4_7_4)
+#define GPSR1_9		F_(A9,			IP4_3_0)
+#define GPSR1_8		F_(A8,			IP3_31_28)
+#define GPSR1_7		F_(A7,			IP3_27_24)
+#define GPSR1_6		F_(A6,			IP3_23_20)
+#define GPSR1_5		F_(A5,			IP3_19_16)
+#define GPSR1_4		F_(A4,			IP3_15_12)
+#define GPSR1_3		F_(A3,			IP3_11_8)
+#define GPSR1_2		F_(A2,			IP3_7_4)
+#define GPSR1_1		F_(A1,			IP3_3_0)
+#define GPSR1_0		F_(A0,			IP2_31_28)
+
+/* GPSR2 */
+#define GPSR2_25	F_(EX_WAIT0,		IP2_27_24)
+#define GPSR2_24	F_(RD_WR_N,		IP2_23_20)
+#define GPSR2_23	F_(RD_N,		IP2_19_16)
+#define GPSR2_22	F_(BS_N,		IP2_15_12)
+#define GPSR2_21	FM(AVB_PHY_INT)
+#define GPSR2_20	F_(AVB_TXCREFCLK,	IP2_3_0)
+#define GPSR2_19	FM(AVB_RD3)
+#define GPSR2_18	F_(AVB_RD2,		IP1_31_28)
+#define GPSR2_17	F_(AVB_RD1,		IP1_27_24)
+#define GPSR2_16	F_(AVB_RD0,		IP1_23_20)
+#define GPSR2_15	FM(AVB_RXC)
+#define GPSR2_14	FM(AVB_RX_CTL)
+#define GPSR2_13	F_(RPC_RESET_N,		IP1_19_16)
+#define GPSR2_12	F_(RPC_INT_N,		IP1_15_12)
+#define GPSR2_11	F_(QSPI1_SSL,		IP1_11_8)
+#define GPSR2_10	F_(QSPI1_IO3,		IP1_7_4)
+#define GPSR2_9		F_(QSPI1_IO2,		IP1_3_0)
+#define GPSR2_8		F_(QSPI1_MISO_IO1,	IP0_31_28)
+#define GPSR2_7		F_(QSPI1_MOSI_IO0,	IP0_27_24)
+#define GPSR2_6		F_(QSPI1_SPCLK,		IP0_23_20)
+#define GPSR2_5		FM(QSPI0_SSL)
+#define GPSR2_4		F_(QSPI0_IO3,		IP0_19_16)
+#define GPSR2_3		F_(QSPI0_IO2,		IP0_15_12)
+#define GPSR2_2		F_(QSPI0_MISO_IO1,	IP0_11_8)
+#define GPSR2_1		F_(QSPI0_MOSI_IO0,	IP0_7_4)
+#define GPSR2_0		F_(QSPI0_SPCLK,		IP0_3_0)
+
+/* GPSR3 */
+#define GPSR3_15	F_(SD1_WP,		IP11_7_4)
+#define GPSR3_14	F_(SD1_CD,		IP11_3_0)
+#define GPSR3_13	F_(SD0_WP,		IP10_31_28)
+#define GPSR3_12	F_(SD0_CD,		IP10_27_24)
+#define GPSR3_11	F_(SD1_DAT3,		IP9_11_8)
+#define GPSR3_10	F_(SD1_DAT2,		IP9_7_4)
+#define GPSR3_9		F_(SD1_DAT1,		IP9_3_0)
+#define GPSR3_8		F_(SD1_DAT0,		IP8_31_28)
+#define GPSR3_7		F_(SD1_CMD,		IP8_27_24)
+#define GPSR3_6		F_(SD1_CLK,		IP8_23_20)
+#define GPSR3_5		F_(SD0_DAT3,		IP8_19_16)
+#define GPSR3_4		F_(SD0_DAT2,		IP8_15_12)
+#define GPSR3_3		F_(SD0_DAT1,		IP8_11_8)
+#define GPSR3_2		F_(SD0_DAT0,		IP8_7_4)
+#define GPSR3_1		F_(SD0_CMD,		IP8_3_0)
+#define GPSR3_0		F_(SD0_CLK,		IP7_31_28)
+
+/* GPSR4 */
+#define GPSR4_10	F_(SD3_DS,		IP10_23_20)
+#define GPSR4_9		F_(SD3_DAT7,		IP10_19_16)
+#define GPSR4_8		F_(SD3_DAT6,		IP10_15_12)
+#define GPSR4_7		F_(SD3_DAT5,		IP10_11_8)
+#define GPSR4_6		F_(SD3_DAT4,		IP10_7_4)
+#define GPSR4_5		F_(SD3_DAT3,		IP10_3_0)
+#define GPSR4_4		F_(SD3_DAT2,		IP9_31_28)
+#define GPSR4_3		F_(SD3_DAT1,		IP9_27_24)
+#define GPSR4_2		F_(SD3_DAT0,		IP9_23_20)
+#define GPSR4_1		F_(SD3_CMD,		IP9_19_16)
+#define GPSR4_0		F_(SD3_CLK,		IP9_15_12)
+
+/* GPSR5 */
+#define GPSR5_19	F_(MLB_DAT,		IP13_23_20)
+#define GPSR5_18	F_(MLB_SIG,		IP13_19_16)
+#define GPSR5_17	F_(MLB_CLK,		IP13_15_12)
+#define GPSR5_16	F_(SSI_SDATA9,		IP13_11_8)
+#define GPSR5_15	F_(MSIOF0_SS2,		IP13_7_4)
+#define GPSR5_14	F_(MSIOF0_SS1,		IP13_3_0)
+#define GPSR5_13	F_(MSIOF0_SYNC,		IP12_31_28)
+#define GPSR5_12	F_(MSIOF0_TXD,		IP12_27_24)
+#define GPSR5_11	F_(MSIOF0_RXD,		IP12_23_20)
+#define GPSR5_10	F_(MSIOF0_SCK,		IP12_19_16)
+#define GPSR5_9		F_(RX2_A,		IP12_15_12)
+#define GPSR5_8		F_(TX2_A,		IP12_11_8)
+#define GPSR5_7		F_(SCK2_A,		IP12_7_4)
+#define GPSR5_6		F_(TX1,			IP12_3_0)
+#define GPSR5_5		F_(RX1,			IP11_31_28)
+#define GPSR5_4		F_(RTS0_N_TANS_A,	IP11_23_20)
+#define GPSR5_3		F_(CTS0_N_A,		IP11_19_16)
+#define GPSR5_2		F_(TX0_A,		IP11_15_12)
+#define GPSR5_1		F_(RX0_A,		IP11_11_8)
+#define GPSR5_0		F_(SCK0_A,		IP11_27_24)
+
+/* GPSR6 */
+#define GPSR6_17	F_(USB30_PWEN,		IP15_27_24)
+#define GPSR6_16	F_(SSI_SDATA6,		IP15_19_16)
+#define GPSR6_15	F_(SSI_WS6,		IP15_15_12)
+#define GPSR6_14	F_(SSI_SCK6,		IP15_11_8)
+#define GPSR6_13	F_(SSI_SDATA5,		IP15_7_4)
+#define GPSR6_12	F_(SSI_WS5,		IP15_3_0)
+#define GPSR6_11	F_(SSI_SCK5,		IP14_31_28)
+#define GPSR6_10	F_(SSI_SDATA4,		IP14_27_24)
+#define GPSR6_9		F_(USB30_OVC,		IP15_31_28)
+#define GPSR6_8		F_(AUDIO_CLKA,		IP15_23_20)
+#define GPSR6_7		F_(SSI_SDATA3,		IP14_23_20)
+#define GPSR6_6		F_(SSI_WS349,		IP14_19_16)
+#define GPSR6_5		F_(SSI_SCK349,		IP14_15_12)
+#define GPSR6_4		F_(SSI_SDATA2,		IP14_11_8)
+#define GPSR6_3		F_(SSI_SDATA1,		IP14_7_4)
+#define GPSR6_2		F_(SSI_SDATA0,		IP14_3_0)
+#define GPSR6_1		F_(SSI_WS01239,		IP13_31_28)
+#define GPSR6_0		F_(SSI_SCK01239,	IP13_27_24)
+
+/* IPSRx */		/* 0 */			/* 1 */			/* 2 */			/* 3 */			/* 4 */			/* 5 */		/* 6 */		/* 7 */		/* 8 */		/* 9 - F */
+#define IP0_3_0		FM(QSPI0_SPCLK)		FM(HSCK4_A)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP0_7_4		FM(QSPI0_MOSI_IO0)	FM(HCTS4_N_A)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP0_11_8	FM(QSPI0_MISO_IO1)	FM(HRTS4_N_A)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP0_15_12	FM(QSPI0_IO2)		FM(HTX4_A)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP0_19_16	FM(QSPI0_IO3)		FM(HRX4_A)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP0_23_20	FM(QSPI1_SPCLK)		FM(RIF2_CLK_A)		FM(HSCK4_B)		FM(VI4_DATA0_A)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP0_27_24	FM(QSPI1_MOSI_IO0)	FM(RIF2_SYNC_A)		FM(HTX4_B)		FM(VI4_DATA1_A)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP0_31_28	FM(QSPI1_MISO_IO1)	FM(RIF2_D0_A)		FM(HRX4_B)		FM(VI4_DATA2_A)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP1_3_0		FM(QSPI1_IO2)		FM(RIF2_D1_A)		FM(HTX3_C)		FM(VI4_DATA3_A)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP1_7_4		FM(QSPI1_IO3)		FM(RIF3_CLK_A)		FM(HRX3_C)		FM(VI4_DATA4_A)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP1_11_8	FM(QSPI1_SSL)		FM(RIF3_SYNC_A)		FM(HSCK3_C)		FM(VI4_DATA5_A)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP1_15_12	FM(RPC_INT_N)		FM(RIF3_D0_A)		FM(HCTS3_N_C)		FM(VI4_DATA6_A)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP1_19_16	FM(RPC_RESET_N)		FM(RIF3_D1_A)		FM(HRTS3_N_C)		FM(VI4_DATA7_A)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP1_23_20	FM(AVB_RD0)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP1_27_24	FM(AVB_RD1)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP1_31_28	FM(AVB_RD2)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP2_3_0		FM(AVB_TXCREFCLK)	F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP2_7_4		FM(AVB_MDIO)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP2_11_8	FM(AVB_MDC)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP2_15_12	FM(BS_N)		FM(PWM0_A)		FM(AVB_MAGIC)		FM(VI4_CLK)		F_(0, 0)		FM(TX3_C)	F_(0, 0)	FM(VI5_CLK_B)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP2_19_16	FM(RD_N)		FM(PWM1_A)		FM(AVB_LINK)		FM(VI4_FIELD)		F_(0, 0)		FM(RX3_C)	FM(FSCLKST2_N_A) FM(VI5_DATA0_B) F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP2_23_20	FM(RD_WR_N)		FM(SCL7_A)		FM(AVB_AVTP_MATCH_A)	FM(VI4_VSYNC_N)		FM(TX5_B)		FM(SCK3_C)	FM(PWM5_A)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP2_27_24	FM(EX_WAIT0)		FM(SDA7_A)		FM(AVB_AVTP_CAPTURE_A)	FM(VI4_HSYNC_N)		FM(RX5_B)		FM(PWM6_A)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP2_31_28	FM(A0)			FM(IRQ0)		FM(PWM2_A)		FM(MSIOF3_SS1_B)	FM(VI5_CLK_A)		FM(DU_CDE)	FM(HRX3_D)	FM(IERX)	FM(QSTB_QHE)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP3_3_0		FM(A1)			FM(IRQ1)		FM(PWM3_A)		FM(DU_DOTCLKIN1)	FM(VI5_DATA0_A)		FM(DU_DISP_CDE) FM(SDA6_B)	FM(IETX)	FM(QCPV_QDE)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP3_7_4		FM(A2)			FM(IRQ2)		FM(AVB_AVTP_PPS)	FM(VI4_CLKENB)		FM(VI5_DATA1_A)		FM(DU_DISP)	FM(SCL6_B)	F_(0, 0)	FM(QSTVB_QVE)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP3_11_8	FM(A3)			FM(CTS4_N_A)		FM(PWM4_A)		FM(VI4_DATA12)		F_(0, 0)		FM(DU_DOTCLKOUT0) FM(HTX3_D)	FM(IECLK)	FM(LCDOUT12)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP3_15_12	FM(A4)			FM(RTS4_N_TANS_A)	FM(MSIOF3_SYNC_B)	FM(VI4_DATA8)		FM(PWM2_B)		FM(DU_DG4)	FM(RIF2_CLK_B)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP3_19_16	FM(A5)			FM(SCK4_A)		FM(MSIOF3_SCK_B)	FM(VI4_DATA9)		FM(PWM3_B)		F_(0, 0)	FM(RIF2_SYNC_B)	F_(0, 0)	FM(QPOLA)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP3_23_20	FM(A6)			FM(RX4_A)		FM(MSIOF3_RXD_B)	FM(VI4_DATA10)		F_(0, 0)		F_(0, 0)	FM(RIF2_D0_B)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP3_27_24	FM(A7)			FM(TX4_A)		FM(MSIOF3_TXD_B)	FM(VI4_DATA11)		F_(0, 0)		F_(0, 0)	FM(RIF2_D1_B)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP3_31_28	FM(A8)			FM(SDA6_A)		FM(RX3_B)		FM(HRX4_C)		FM(VI5_HSYNC_N_A)	FM(DU_HSYNC)	FM(VI4_DATA0_B)	F_(0, 0)	FM(QSTH_QHS)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+
+/* IPSRx */		/* 0 */			/* 1 */			/* 2 */			/* 3 */			/* 4 */			/* 5 */		/* 6 */		/* 7 */		/* 8 */		/* 9 - F */
+#define IP4_3_0		FM(A9)			FM(TX5_A)		FM(IRQ3)		FM(VI4_DATA16)		FM(VI5_VSYNC_N_A)	FM(DU_DG7)	F_(0, 0)	F_(0, 0)	FM(LCDOUT15)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP4_7_4		FM(A10)			FM(IRQ4)		FM(MSIOF2_SYNC_B)	FM(VI4_DATA13)		FM(VI5_FIELD_A)		FM(DU_DG5)	FM(FSCLKST2_N_B) F_(0, 0)	FM(LCDOUT13)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP4_11_8	FM(A11)			FM(SCL6_A)		FM(TX3_B)		FM(HTX4_C)		F_(0, 0)		FM(DU_VSYNC)	FM(VI4_DATA1_B)	F_(0, 0)	FM(QSTVA_QVS)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP4_15_12	FM(A12)			FM(RX5_A)		FM(MSIOF2_SS2_B)	FM(VI4_DATA17)		FM(VI5_DATA3_A)		FM(DU_DG6)	F_(0, 0)	F_(0, 0)	FM(LCDOUT14)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP4_19_16	FM(A13)			FM(SCK5_A)		FM(MSIOF2_SCK_B)	FM(VI4_DATA14)		FM(HRX4_D)		FM(DU_DB2)	F_(0, 0)	F_(0, 0)	FM(LCDOUT2)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP4_23_20	FM(A14)			FM(MSIOF1_SS1)		FM(MSIOF2_RXD_B)	FM(VI4_DATA15)		FM(HTX4_D)		FM(DU_DB3)	F_(0, 0)	F_(0, 0)	FM(LCDOUT3)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP4_27_24	FM(A15)			FM(MSIOF1_SS2)		FM(MSIOF2_TXD_B)	FM(VI4_DATA18)		FM(VI5_DATA4_A)		FM(DU_DB4)	F_(0, 0)	F_(0, 0)	FM(LCDOUT4)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP4_31_28	FM(A16)			FM(MSIOF1_SYNC)		FM(MSIOF2_SS1_B)	FM(VI4_DATA19)		FM(VI5_DATA5_A)		FM(DU_DB5)	F_(0, 0)	F_(0, 0)	FM(LCDOUT5)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP5_3_0		FM(A17)			FM(MSIOF1_RXD)		F_(0, 0)		FM(VI4_DATA20)		FM(VI5_DATA6_A)		FM(DU_DB6)	F_(0, 0)	F_(0, 0)	FM(LCDOUT6)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP5_7_4		FM(A18)			FM(MSIOF1_TXD)		F_(0, 0)		FM(VI4_DATA21)		FM(VI5_DATA7_A)		FM(DU_DB0)	F_(0, 0)	FM(HRX4_E)	FM(LCDOUT0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP5_11_8	FM(A19)			FM(MSIOF1_SCK)		F_(0, 0)		FM(VI4_DATA22)		FM(VI5_DATA2_A)		FM(DU_DB1)	F_(0, 0)	FM(HTX4_E)	FM(LCDOUT1)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP5_15_12	FM(CS0_N)		FM(SCL5)		F_(0, 0)		F_(0, 0)		F_(0, 0)		FM(DU_DR0)	FM(VI4_DATA2_B)	F_(0, 0)	FM(LCDOUT16)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP5_19_16	FM(WE0_N)		FM(SDA5)		F_(0, 0)		F_(0, 0)		F_(0, 0)		FM(DU_DR1)	FM(VI4_DATA3_B)	F_(0, 0)	FM(LCDOUT17)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP5_23_20	FM(D0)			FM(MSIOF3_SCK_A)	F_(0, 0)		F_(0, 0)		F_(0, 0)		FM(DU_DR2)	FM(CTS4_N_C)	F_(0, 0)	FM(LCDOUT18)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP5_27_24	FM(D1)			FM(MSIOF3_SYNC_A)	FM(SCK3_A)		FM(VI4_DATA23)		FM(VI5_CLKENB_A)	FM(DU_DB7)	FM(RTS4_N_TANS_C) F_(0, 0)	FM(LCDOUT7)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP5_31_28	FM(D2)			FM(MSIOF3_RXD_A)	FM(RX5_C)		F_(0, 0)		FM(VI5_DATA14_A)	FM(DU_DR3)	FM(RX4_C)	F_(0, 0)	FM(LCDOUT19)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP6_3_0		FM(D3)			FM(MSIOF3_TXD_A)	FM(TX5_C)		F_(0, 0)		FM(VI5_DATA15_A)	FM(DU_DR4)	FM(TX4_C)	F_(0, 0)	FM(LCDOUT20)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP6_7_4		FM(D4)			FM(CANFD1_TX)		FM(HSCK3_B)		FM(CAN1_TX)		FM(RTS3_N_TANS_A)	FM(MSIOF3_SS2_A) F_(0, 0)	FM(VI5_DATA1_B)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP6_11_8	FM(D5)			FM(RX3_A)		FM(HRX3_B)		F_(0, 0)		F_(0, 0)		FM(DU_DR5)	FM(VI4_DATA4_B)	F_(0, 0)	FM(LCDOUT21)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP6_15_12	FM(D6)			FM(TX3_A)		FM(HTX3_B)		F_(0, 0)		F_(0, 0)		FM(DU_DR6)	FM(VI4_DATA5_B)	F_(0, 0)	FM(LCDOUT22)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP6_19_16	FM(D7)			FM(CANFD1_RX)		FM(IRQ5)		FM(CAN1_RX)		FM(CTS3_N_A)		F_(0, 0)	F_(0, 0)	FM(VI5_DATA2_B)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP6_23_20	FM(D8)			FM(MSIOF2_SCK_A)	FM(SCK4_B)		F_(0, 0)		FM(VI5_DATA12_A)	FM(DU_DR7)	FM(RIF3_CLK_B)	FM(HCTS3_N_E)	FM(LCDOUT23)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP6_27_24	FM(D9)			FM(MSIOF2_SYNC_A)	F_(0, 0)		F_(0, 0)		FM(VI5_DATA10_A)	FM(DU_DG0)	FM(RIF3_SYNC_B)	FM(HRX3_E)	FM(LCDOUT8)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP6_31_28	FM(D10)			FM(MSIOF2_RXD_A)	F_(0, 0)		F_(0, 0)		FM(VI5_DATA13_A)	FM(DU_DG1)	FM(RIF3_D0_B)	FM(HTX3_E)	FM(LCDOUT9)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP7_3_0		FM(D11)			FM(MSIOF2_TXD_A)	F_(0, 0)		F_(0, 0)		FM(VI5_DATA11_A)	FM(DU_DG2)	FM(RIF3_D1_B)	FM(HRTS3_N_E)	FM(LCDOUT10)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP7_7_4		FM(D12)			FM(CANFD0_TX)		FM(TX4_B)		FM(CAN0_TX)		FM(VI5_DATA8_A)		F_(0, 0)	F_(0, 0)	FM(VI5_DATA3_B)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP7_11_8	FM(D13)			FM(CANFD0_RX)		FM(RX4_B)		FM(CAN0_RX)		FM(VI5_DATA9_A)		FM(SCL7_B)	F_(0, 0)	FM(VI5_DATA4_B)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP7_15_12	FM(D14)			FM(CAN_CLK)		FM(HRX3_A)		FM(MSIOF2_SS2_A)	F_(0, 0)		FM(SDA7_B)	F_(0, 0)	FM(VI5_DATA5_B)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP7_19_16	FM(D15)			FM(MSIOF2_SS1_A)	FM(HTX3_A)		FM(MSIOF3_SS1_A)	F_(0, 0)		FM(DU_DG3)	F_(0, 0)	F_(0, 0)	FM(LCDOUT11)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP7_23_20	FM(SCL4)		FM(CS1_N_A26)		F_(0, 0)		F_(0, 0)		F_(0, 0)		FM(DU_DOTCLKIN0) FM(VI4_DATA6_B) FM(VI5_DATA6_B) FM(QCLK)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP7_27_24	FM(SDA4)		FM(WE1_N)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	FM(VI4_DATA7_B)	FM(VI5_DATA7_B)	FM(QPOLB)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP7_31_28	FM(SD0_CLK)		FM(NFDATA8)		FM(SCL1_C)		FM(HSCK1_B)		FM(SDA2_E)		FM(FMCLK_B)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+
+/* IPSRx */		/* 0 */			/* 1 */			/* 2 */			/* 3 */			/* 4 */			/* 5 */		/* 6 */		/* 7 */		/* 8 */		/* 9 - F */
+#define IP8_3_0		FM(SD0_CMD)		FM(NFDATA9)		F_(0, 0)		FM(HRX1_B)		F_(0, 0)		FM(SPEEDIN_B)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP8_7_4		FM(SD0_DAT0)		FM(NFDATA10)		F_(0, 0)		FM(HTX1_B)		F_(0, 0)		FM(REMOCON_B)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP8_11_8	FM(SD0_DAT1)		FM(NFDATA11)		FM(SDA2_C)		FM(HCTS1_N_B)		F_(0, 0)		FM(FMIN_B)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP8_15_12	FM(SD0_DAT2)		FM(NFDATA12)		FM(SCL2_C)		FM(HRTS1_N_B)		F_(0, 0)		FM(BPFCLK_B)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP8_19_16	FM(SD0_DAT3)		FM(NFDATA13)		FM(SDA1_C)		FM(SCL2_E)		FM(SPEEDIN_C)		FM(REMOCON_C)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP8_23_20	FM(SD1_CLK)		FM(NFDATA14_B)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP8_27_24	FM(SD1_CMD)		FM(NFDATA15_B)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP8_31_28	FM(SD1_DAT0)		FM(NFWP_N_B)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP9_3_0		FM(SD1_DAT1)		FM(NFCE_N_B)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP9_7_4		FM(SD1_DAT2)		FM(NFALE_B)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP9_11_8	FM(SD1_DAT3)		FM(NFRB_N_B)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP9_15_12	FM(SD3_CLK)		FM(NFWE_N)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP9_19_16	FM(SD3_CMD)		FM(NFRE_N)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP9_23_20	FM(SD3_DAT0)		FM(NFDATA0)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP9_27_24	FM(SD3_DAT1)		FM(NFDATA1)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP9_31_28	FM(SD3_DAT2)		FM(NFDATA2)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP10_3_0	FM(SD3_DAT3)		FM(NFDATA3)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP10_7_4	FM(SD3_DAT4)		FM(NFDATA4)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP10_11_8	FM(SD3_DAT5)		FM(NFDATA5)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP10_15_12	FM(SD3_DAT6)		FM(NFDATA6)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP10_19_16	FM(SD3_DAT7)		FM(NFDATA7)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP10_23_20	FM(SD3_DS)		FM(NFCLE)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP10_27_24	FM(SD0_CD)		FM(NFALE_A)		FM(SD3_CD)		FM(RIF0_CLK_B)		FM(SCL2_B)		FM(TCLK1_A)	FM(SSI_SCK2_B)	FM(TS_SCK0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP10_31_28	FM(SD0_WP)		FM(NFRB_N_A)		FM(SD3_WP)		FM(RIF0_D0_B)		FM(SDA2_B)		FM(TCLK2_A)	FM(SSI_WS2_B)	FM(TS_SDAT0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP11_3_0	FM(SD1_CD)		FM(NFCE_N_A)		FM(SSI_SCK1)		FM(RIF0_D1_B)		F_(0, 0)		F_(0, 0)	F_(0, 0)	FM(TS_SDEN0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP11_7_4	FM(SD1_WP)		FM(NFWP_N_A)		FM(SSI_WS1)		FM(RIF0_SYNC_B)		F_(0, 0)		F_(0, 0)	F_(0, 0)	FM(TS_SPSYNC0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP11_11_8	FM(RX0_A)		FM(HRX1_A)		FM(SSI_SCK2_A)		FM(RIF1_SYNC)		F_(0, 0)		F_(0, 0)	F_(0, 0)	FM(TS_SCK1)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP11_15_12	FM(TX0_A)		FM(HTX1_A)		FM(SSI_WS2_A)		FM(RIF1_D0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	FM(TS_SDAT1)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP11_19_16	FM(CTS0_N_A)		FM(NFDATA14_A)		FM(AUDIO_CLKOUT_A)	FM(RIF1_D1)		FM(SCIF_CLK_A)		FM(FMCLK_A)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP11_23_20	FM(RTS0_N_TANS_A)	FM(NFDATA15_A)		FM(AUDIO_CLKOUT1_A)	FM(RIF1_CLK)		FM(SCL2_A)		FM(FMIN_A)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP11_27_24	FM(SCK0_A)		FM(HSCK1_A)		FM(USB3HS0_ID)		FM(RTS1_N_TANS)		FM(SDA2_A)		FM(FMCLK_C)	F_(0, 0)	F_(0, 0)	FM(USB1_ID)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP11_31_28	FM(RX1)			FM(HRX2_B)		FM(SSI_SCK9_B)		FM(AUDIO_CLKOUT1_B)	F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+
+/* IPSRx */		/* 0 */			/* 1 */			/* 2 */			/* 3 */			/* 4 */			/* 5 */		/* 6 */		/* 7 */		/* 8 */		/* 9 - F */
+#define IP12_3_0	FM(TX1)			FM(HTX2_B)		FM(SSI_WS9_B)		FM(AUDIO_CLKOUT3_B)	F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP12_7_4	FM(SCK2_A)		FM(HSCK0_A)		FM(AUDIO_CLKB_A)	FM(CTS1_N)		FM(RIF0_CLK_A)		FM(REMOCON_A)	FM(SCIF_CLK_B)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP12_11_8	FM(TX2_A)		FM(HRX0_A)		FM(AUDIO_CLKOUT2_A)	F_(0, 0)		FM(SCL1_A)		F_(0, 0)	FM(FSO_CFE_0_N_A) FM(TS_SDEN1)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP12_15_12	FM(RX2_A)		FM(HTX0_A)		FM(AUDIO_CLKOUT3_A)	F_(0, 0)		FM(SDA1_A)		F_(0, 0)	FM(FSO_CFE_1_N_A) FM(TS_SPSYNC1) F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP12_19_16	FM(MSIOF0_SCK)		F_(0, 0)		FM(SSI_SCK78)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP12_23_20	FM(MSIOF0_RXD)		F_(0, 0)		FM(SSI_WS78)		F_(0, 0)		F_(0, 0)		FM(TX2_B)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP12_27_24	FM(MSIOF0_TXD)		F_(0, 0)		FM(SSI_SDATA7)		F_(0, 0)		F_(0, 0)		FM(RX2_B)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP12_31_28	FM(MSIOF0_SYNC)		FM(AUDIO_CLKOUT_B)	FM(SSI_SDATA8)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP13_3_0	FM(MSIOF0_SS1)		FM(HRX2_A)		FM(SSI_SCK4)		FM(HCTS0_N_A)		FM(BPFCLK_C)		FM(SPEEDIN_A)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP13_7_4	FM(MSIOF0_SS2)		FM(HTX2_A)		FM(SSI_WS4)		FM(HRTS0_N_A)		FM(FMIN_C)		FM(BPFCLK_A)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP13_11_8	FM(SSI_SDATA9)		F_(0, 0)		FM(AUDIO_CLKC_A)	FM(SCK1)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP13_15_12	FM(MLB_CLK)		FM(RX0_B)		F_(0, 0)		FM(RIF0_D0_A)		FM(SCL1_B)		FM(TCLK1_B)	F_(0, 0)	F_(0, 0)	FM(SIM0_RST_A)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP13_19_16	FM(MLB_SIG)		FM(SCK0_B)		F_(0, 0)		FM(RIF0_D1_A)		FM(SDA1_B)		FM(TCLK2_B)	F_(0, 0)	F_(0, 0)	FM(SIM0_D_A)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP13_23_20	FM(MLB_DAT)		FM(TX0_B)		F_(0, 0)		FM(RIF0_SYNC_A)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	FM(SIM0_CLK_A)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP13_27_24	FM(SSI_SCK01239)	F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP13_31_28	FM(SSI_WS01239)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP14_3_0	FM(SSI_SDATA0)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP14_7_4	FM(SSI_SDATA1)		FM(AUDIO_CLKC_B)	F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	FM(PWM0_B)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP14_11_8	FM(SSI_SDATA2)		FM(AUDIO_CLKOUT2_B)	FM(SSI_SCK9_A)		F_(0, 0)		F_(0, 0)		F_(0, 0)	FM(PWM1_B)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP14_15_12	FM(SSI_SCK349)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	FM(PWM2_C)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP14_19_16	FM(SSI_WS349)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	FM(PWM3_C)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP14_23_20	FM(SSI_SDATA3)		FM(AUDIO_CLKOUT1_C)	FM(AUDIO_CLKB_B)	F_(0, 0)		F_(0, 0)		F_(0, 0)	FM(PWM4_B)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP14_27_24	FM(SSI_SDATA4)		F_(0, 0)		FM(SSI_WS9_A)		F_(0, 0)		F_(0, 0)		F_(0, 0)	FM(PWM5_B)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP14_31_28	FM(SSI_SCK5)		FM(HRX0_B)		F_(0, 0)		FM(USB0_PWEN_B)		FM(SCL2_D)		F_(0, 0)	FM(PWM6_B)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP15_3_0	FM(SSI_WS5)		FM(HTX0_B)		F_(0, 0)		FM(USB0_OVC_B)		FM(SDA2_D)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP15_7_4	FM(SSI_SDATA5)		FM(HSCK0_B)		FM(AUDIO_CLKB_C)	FM(TPU0TO0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP15_11_8	FM(SSI_SCK6)		FM(HSCK2_A)		FM(AUDIO_CLKC_C)	FM(TPU0TO1)		F_(0, 0)		F_(0, 0)	FM(FSO_CFE_0_N_B) F_(0, 0)	FM(SIM0_RST_B)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP15_15_12	FM(SSI_WS6)		FM(HCTS2_N_A)		FM(AUDIO_CLKOUT2_C)	FM(TPU0TO2)		FM(SDA1_D)		F_(0, 0)	FM(FSO_CFE_1_N_B) F_(0, 0)	FM(SIM0_D_B)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP15_19_16	FM(SSI_SDATA6)		FM(HRTS2_N_A)		FM(AUDIO_CLKOUT3_C)	FM(TPU0TO3)		FM(SCL1_D)		F_(0, 0)	FM(FSO_TOE_N_B)	F_(0, 0)	FM(SIM0_CLK_B)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP15_23_20	FM(AUDIO_CLKA)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP15_27_24	FM(USB30_PWEN)		FM(USB0_PWEN_A)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+#define IP15_31_28	FM(USB30_OVC)		FM(USB0_OVC_A)		F_(0, 0)		F_(0, 0)		F_(0, 0)		F_(0, 0)	FM(FSO_TOE_N_A)	F_(0, 0)	F_(0, 0)	F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
+
+#define PINMUX_GPSR	\
+\
+													 \
+													 \
+													 \
+													 \
+													 \
+													 \
+				GPSR2_25								 \
+				GPSR2_24								 \
+				GPSR2_23								 \
+		GPSR1_22	GPSR2_22								 \
+		GPSR1_21	GPSR2_21								 \
+		GPSR1_20	GPSR2_20								 \
+		GPSR1_19	GPSR2_19					GPSR5_19		 \
+		GPSR1_18	GPSR2_18					GPSR5_18		 \
+GPSR0_17	GPSR1_17	GPSR2_17					GPSR5_17	GPSR6_17 \
+GPSR0_16	GPSR1_16	GPSR2_16					GPSR5_16	GPSR6_16 \
+GPSR0_15	GPSR1_15	GPSR2_15	GPSR3_15			GPSR5_15	GPSR6_15 \
+GPSR0_14	GPSR1_14	GPSR2_14	GPSR3_14			GPSR5_14	GPSR6_14 \
+GPSR0_13	GPSR1_13	GPSR2_13	GPSR3_13			GPSR5_13	GPSR6_13 \
+GPSR0_12	GPSR1_12	GPSR2_12	GPSR3_12			GPSR5_12	GPSR6_12 \
+GPSR0_11	GPSR1_11	GPSR2_11	GPSR3_11			GPSR5_11	GPSR6_11 \
+GPSR0_10	GPSR1_10	GPSR2_10	GPSR3_10	GPSR4_10	GPSR5_10	GPSR6_10 \
+GPSR0_9		GPSR1_9		GPSR2_9		GPSR3_9		GPSR4_9		GPSR5_9		GPSR6_9 \
+GPSR0_8		GPSR1_8		GPSR2_8		GPSR3_8		GPSR4_8		GPSR5_8		GPSR6_8 \
+GPSR0_7		GPSR1_7		GPSR2_7		GPSR3_7		GPSR4_7		GPSR5_7		GPSR6_7 \
+GPSR0_6		GPSR1_6		GPSR2_6		GPSR3_6		GPSR4_6		GPSR5_6		GPSR6_6 \
+GPSR0_5		GPSR1_5		GPSR2_5		GPSR3_5		GPSR4_5		GPSR5_5		GPSR6_5 \
+GPSR0_4		GPSR1_4		GPSR2_4		GPSR3_4		GPSR4_4		GPSR5_4		GPSR6_4 \
+GPSR0_3		GPSR1_3		GPSR2_3		GPSR3_3		GPSR4_3		GPSR5_3		GPSR6_3 \
+GPSR0_2		GPSR1_2		GPSR2_2		GPSR3_2		GPSR4_2		GPSR5_2		GPSR6_2 \
+GPSR0_1		GPSR1_1		GPSR2_1		GPSR3_1		GPSR4_1		GPSR5_1		GPSR6_1 \
+GPSR0_0		GPSR1_0		GPSR2_0		GPSR3_0		GPSR4_0		GPSR5_0		GPSR6_0
+
+#define PINMUX_IPSR				\
+\
+FM(IP0_3_0)	IP0_3_0		FM(IP1_3_0)	IP1_3_0		FM(IP2_3_0)	IP2_3_0		FM(IP3_3_0)	IP3_3_0 \
+FM(IP0_7_4)	IP0_7_4		FM(IP1_7_4)	IP1_7_4		FM(IP2_7_4)	IP2_7_4		FM(IP3_7_4)	IP3_7_4 \
+FM(IP0_11_8)	IP0_11_8	FM(IP1_11_8)	IP1_11_8	FM(IP2_11_8)	IP2_11_8	FM(IP3_11_8)	IP3_11_8 \
+FM(IP0_15_12)	IP0_15_12	FM(IP1_15_12)	IP1_15_12	FM(IP2_15_12)	IP2_15_12	FM(IP3_15_12)	IP3_15_12 \
+FM(IP0_19_16)	IP0_19_16	FM(IP1_19_16)	IP1_19_16	FM(IP2_19_16)	IP2_19_16	FM(IP3_19_16)	IP3_19_16 \
+FM(IP0_23_20)	IP0_23_20	FM(IP1_23_20)	IP1_23_20	FM(IP2_23_20)	IP2_23_20	FM(IP3_23_20)	IP3_23_20 \
+FM(IP0_27_24)	IP0_27_24	FM(IP1_27_24)	IP1_27_24	FM(IP2_27_24)	IP2_27_24	FM(IP3_27_24)	IP3_27_24 \
+FM(IP0_31_28)	IP0_31_28	FM(IP1_31_28)	IP1_31_28	FM(IP2_31_28)	IP2_31_28	FM(IP3_31_28)	IP3_31_28 \
+\
+FM(IP4_3_0)	IP4_3_0		FM(IP5_3_0)	IP5_3_0		FM(IP6_3_0)	IP6_3_0		FM(IP7_3_0)	IP7_3_0 \
+FM(IP4_7_4)	IP4_7_4		FM(IP5_7_4)	IP5_7_4		FM(IP6_7_4)	IP6_7_4		FM(IP7_7_4)	IP7_7_4 \
+FM(IP4_11_8)	IP4_11_8	FM(IP5_11_8)	IP5_11_8	FM(IP6_11_8)	IP6_11_8	FM(IP7_11_8)	IP7_11_8 \
+FM(IP4_15_12)	IP4_15_12	FM(IP5_15_12)	IP5_15_12	FM(IP6_15_12)	IP6_15_12	FM(IP7_15_12)	IP7_15_12 \
+FM(IP4_19_16)	IP4_19_16	FM(IP5_19_16)	IP5_19_16	FM(IP6_19_16)	IP6_19_16	FM(IP7_19_16)	IP7_19_16 \
+FM(IP4_23_20)	IP4_23_20	FM(IP5_23_20)	IP5_23_20	FM(IP6_23_20)	IP6_23_20	FM(IP7_23_20)	IP7_23_20 \
+FM(IP4_27_24)	IP4_27_24	FM(IP5_27_24)	IP5_27_24	FM(IP6_27_24)	IP6_27_24	FM(IP7_27_24)	IP7_27_24 \
+FM(IP4_31_28)	IP4_31_28	FM(IP5_31_28)	IP5_31_28	FM(IP6_31_28)	IP6_31_28	FM(IP7_31_28)	IP7_31_28 \
+\
+FM(IP8_3_0)	IP8_3_0		FM(IP9_3_0)	IP9_3_0		FM(IP10_3_0)	IP10_3_0	FM(IP11_3_0)	IP11_3_0 \
+FM(IP8_7_4)	IP8_7_4		FM(IP9_7_4)	IP9_7_4		FM(IP10_7_4)	IP10_7_4	FM(IP11_7_4)	IP11_7_4 \
+FM(IP8_11_8)	IP8_11_8	FM(IP9_11_8)	IP9_11_8	FM(IP10_11_8)	IP10_11_8	FM(IP11_11_8)	IP11_11_8 \
+FM(IP8_15_12)	IP8_15_12	FM(IP9_15_12)	IP9_15_12	FM(IP10_15_12)	IP10_15_12	FM(IP11_15_12)	IP11_15_12 \
+FM(IP8_19_16)	IP8_19_16	FM(IP9_19_16)	IP9_19_16	FM(IP10_19_16)	IP10_19_16	FM(IP11_19_16)	IP11_19_16 \
+FM(IP8_23_20)	IP8_23_20	FM(IP9_23_20)	IP9_23_20	FM(IP10_23_20)	IP10_23_20	FM(IP11_23_20)	IP11_23_20 \
+FM(IP8_27_24)	IP8_27_24	FM(IP9_27_24)	IP9_27_24	FM(IP10_27_24)	IP10_27_24	FM(IP11_27_24)	IP11_27_24 \
+FM(IP8_31_28)	IP8_31_28	FM(IP9_31_28)	IP9_31_28	FM(IP10_31_28)	IP10_31_28	FM(IP11_31_28)	IP11_31_28 \
+\
+FM(IP12_3_0)	IP12_3_0	FM(IP13_3_0)	IP13_3_0	FM(IP14_3_0)	IP14_3_0	FM(IP15_3_0)	IP15_3_0 \
+FM(IP12_7_4)	IP12_7_4	FM(IP13_7_4)	IP13_7_4	FM(IP14_7_4)	IP14_7_4	FM(IP15_7_4)	IP15_7_4 \
+FM(IP12_11_8)	IP12_11_8	FM(IP13_11_8)	IP13_11_8	FM(IP14_11_8)	IP14_11_8	FM(IP15_11_8)	IP15_11_8 \
+FM(IP12_15_12)	IP12_15_12	FM(IP13_15_12)	IP13_15_12	FM(IP14_15_12)	IP14_15_12	FM(IP15_15_12)	IP15_15_12 \
+FM(IP12_19_16)	IP12_19_16	FM(IP13_19_16)	IP13_19_16	FM(IP14_19_16)	IP14_19_16	FM(IP15_19_16)	IP15_19_16 \
+FM(IP12_23_20)	IP12_23_20	FM(IP13_23_20)	IP13_23_20	FM(IP14_23_20)	IP14_23_20	FM(IP15_23_20)	IP15_23_20 \
+FM(IP12_27_24)	IP12_27_24	FM(IP13_27_24)	IP13_27_24	FM(IP14_27_24)	IP14_27_24	FM(IP15_27_24)	IP15_27_24 \
+FM(IP12_31_28)	IP12_31_28	FM(IP13_31_28)	IP13_31_28	FM(IP14_31_28)	IP14_31_28	FM(IP15_31_28)	IP15_31_28
+
+/* MOD_SEL0 */			/* 0 */				/* 1 */				/* 2 */				/* 3 */			/* 4 */			/* 5 */		/* 6 */		/* 7 */
+#define MOD_SEL0_30_29		FM(SEL_ADGB_0)			FM(SEL_ADGB_1)			FM(SEL_ADGB_2)			F_(0, 0)
+#define MOD_SEL0_28		FM(SEL_DRIF0_0)			FM(SEL_DRIF0_1)
+#define MOD_SEL0_27_26		FM(SEL_FM_0)			FM(SEL_FM_1)			FM(SEL_FM_2)			F_(0, 0)
+#define MOD_SEL0_25		FM(SEL_FSO_0)			FM(SEL_FSO_1)
+#define MOD_SEL0_24		FM(SEL_HSCIF0_0)		FM(SEL_HSCIF0_1)
+#define MOD_SEL0_23		FM(SEL_HSCIF1_0)		FM(SEL_HSCIF1_1)
+#define MOD_SEL0_22		FM(SEL_HSCIF2_0)		FM(SEL_HSCIF2_1)
+#define MOD_SEL0_21_20		FM(SEL_I2C1_0)			FM(SEL_I2C1_1)			FM(SEL_I2C1_2)			FM(SEL_I2C1_3)		FM(SEL_I2C1_4)		F_(0, 0)	F_(0, 0)	F_(0, 0)
+#define MOD_SEL0_19_18_17	FM(SEL_I2C2_0)			FM(SEL_I2C2_1)			FM(SEL_I2C2_2)			FM(SEL_I2C2_3)		FM(SEL_I2C2_4)		F_(0, 0)	F_(0, 0)	F_(0, 0)
+#define MOD_SEL0_16		FM(SEL_NDFC_0)			FM(SEL_NDFC_1)
+#define MOD_SEL0_15		FM(SEL_PWM0_0)			FM(SEL_PWM0_1)
+#define MOD_SEL0_14		FM(SEL_PWM1_0)			FM(SEL_PWM1_1)
+#define MOD_SEL0_13_12		FM(SEL_PWM2_0)			FM(SEL_PWM2_1)			FM(SEL_PWM2_2)			F_(0, 0)
+#define MOD_SEL0_11_10		FM(SEL_PWM3_0)			FM(SEL_PWM3_1)			FM(SEL_PWM3_2)			F_(0, 0)
+#define MOD_SEL0_9		FM(SEL_PWM4_0)			FM(SEL_PWM4_1)
+#define MOD_SEL0_8		FM(SEL_PWM5_0)			FM(SEL_PWM5_1)
+#define MOD_SEL0_7		FM(SEL_PWM6_0)			FM(SEL_PWM6_1)
+#define MOD_SEL0_6_5		FM(SEL_REMOCON_0)		FM(SEL_REMOCON_1)		FM(SEL_REMOCON_2)		F_(0, 0)
+#define MOD_SEL0_4		FM(SEL_SCIF_0)			FM(SEL_SCIF_1)
+#define MOD_SEL0_3		FM(SEL_SCIF0_0)			FM(SEL_SCIF0_1)
+#define MOD_SEL0_2		FM(SEL_SCIF2_0)			FM(SEL_SCIF2_1)
+#define MOD_SEL0_1_0		FM(SEL_SPEED_PULSE_IF_0)	FM(SEL_SPEED_PULSE_IF_1)	FM(SEL_SPEED_PULSE_IF_2)	F_(0, 0)
+
+/* MOD_SEL1 */			/* 0 */				/* 1 */				/* 2 */				/* 3 */			/* 4 */			/* 5 */		/* 6 */		/* 7 */
+#define MOD_SEL1_31		FM(SEL_SIMCARD_0)		FM(SEL_SIMCARD_1)
+#define MOD_SEL1_30		FM(SEL_SSI2_0)			FM(SEL_SSI2_1)
+#define MOD_SEL1_29		FM(SEL_TIMER_TMU_0)		FM(SEL_TIMER_TMU_1)
+#define MOD_SEL1_28		FM(SEL_USB_20_CH0_0)		FM(SEL_USB_20_CH0_1)
+#define MOD_SEL1_26		FM(SEL_DRIF2_0)			FM(SEL_DRIF2_1)
+#define MOD_SEL1_25		FM(SEL_DRIF3_0)			FM(SEL_DRIF3_1)
+#define MOD_SEL1_24_23_22	FM(SEL_HSCIF3_0)		FM(SEL_HSCIF3_1)		FM(SEL_HSCIF3_2)		FM(SEL_HSCIF3_3)	FM(SEL_HSCIF3_4)	F_(0, 0)	F_(0, 0)	F_(0, 0)
+#define MOD_SEL1_21_20_19	FM(SEL_HSCIF4_0)		FM(SEL_HSCIF4_1)		FM(SEL_HSCIF4_2)		FM(SEL_HSCIF4_3)	FM(SEL_HSCIF4_4)	F_(0, 0)	F_(0, 0)	F_(0, 0)
+#define MOD_SEL1_18		FM(SEL_I2C6_0)			FM(SEL_I2C6_1)
+#define MOD_SEL1_17		FM(SEL_I2C7_0)			FM(SEL_I2C7_1)
+#define MOD_SEL1_16		FM(SEL_MSIOF2_0)		FM(SEL_MSIOF2_1)
+#define MOD_SEL1_15		FM(SEL_MSIOF3_0)		FM(SEL_MSIOF3_1)
+#define MOD_SEL1_14_13		FM(SEL_SCIF3_0)			FM(SEL_SCIF3_1)			FM(SEL_SCIF3_2)			F_(0, 0)
+#define MOD_SEL1_12_11		FM(SEL_SCIF4_0)			FM(SEL_SCIF4_1)			FM(SEL_SCIF4_2)			F_(0, 0)
+#define MOD_SEL1_10_9		FM(SEL_SCIF5_0)			FM(SEL_SCIF5_1)			FM(SEL_SCIF5_2)			F_(0, 0)
+#define MOD_SEL1_8		FM(SEL_VIN4_0)			FM(SEL_VIN4_1)
+#define MOD_SEL1_7		FM(SEL_VIN5_0)			FM(SEL_VIN5_1)
+#define MOD_SEL1_6_5		FM(SEL_ADGC_0)			FM(SEL_ADGC_1)			FM(SEL_ADGC_2)			F_(0, 0)
+#define MOD_SEL1_4		FM(SEL_SSI9_0)			FM(SEL_SSI9_1)
+
+#define PINMUX_MOD_SELS	\
+\
+			MOD_SEL1_31 \
+MOD_SEL0_30_29		MOD_SEL1_30 \
+			MOD_SEL1_29 \
+MOD_SEL0_28		MOD_SEL1_28 \
+MOD_SEL0_27_26 \
+			MOD_SEL1_26 \
+MOD_SEL0_25		MOD_SEL1_25 \
+MOD_SEL0_24		MOD_SEL1_24_23_22 \
+MOD_SEL0_23 \
+MOD_SEL0_22 \
+MOD_SEL0_21_20		MOD_SEL1_21_20_19 \
+MOD_SEL0_19_18_17	MOD_SEL1_18 \
+			MOD_SEL1_17 \
+MOD_SEL0_16		MOD_SEL1_16 \
+MOD_SEL0_15		MOD_SEL1_15 \
+MOD_SEL0_14		MOD_SEL1_14_13 \
+MOD_SEL0_13_12 \
+			MOD_SEL1_12_11 \
+MOD_SEL0_11_10 \
+			MOD_SEL1_10_9 \
+MOD_SEL0_9 \
+MOD_SEL0_8		MOD_SEL1_8 \
+MOD_SEL0_7		MOD_SEL1_7 \
+MOD_SEL0_6_5		MOD_SEL1_6_5 \
+MOD_SEL0_4		MOD_SEL1_4 \
+MOD_SEL0_3 \
+MOD_SEL0_2 \
+MOD_SEL0_1_0
+
+enum {
+	PINMUX_RESERVED = 0,
+
+	PINMUX_DATA_BEGIN,
+	GP_ALL(DATA),
+	PINMUX_DATA_END,
+
+#define F_(x, y)
+#define FM(x)	FN_##x,
+	PINMUX_FUNCTION_BEGIN,
+	GP_ALL(FN),
+	PINMUX_GPSR
+	PINMUX_IPSR
+	PINMUX_MOD_SELS
+	PINMUX_FUNCTION_END,
+#undef F_
+#undef FM
+
+#define F_(x, y)
+#define FM(x)	x##_MARK,
+	PINMUX_MARK_BEGIN,
+	PINMUX_GPSR
+	PINMUX_IPSR
+	PINMUX_MOD_SELS
+	PINMUX_MARK_END,
+#undef F_
+#undef FM
+};
+
+static const u16 pinmux_data[] = {
+	PINMUX_DATA_GP_ALL(),
+
+	/* IPSR0 */
+	PINMUX_IPSR_GPSR(IP0_3_0,		QSPI0_SPCLK),
+	PINMUX_IPSR_MSEL(IP0_3_0,		HSCK4_A,	SEL_HSCIF4_0),
+
+	PINMUX_IPSR_GPSR(IP0_7_4,		QSPI0_MOSI_IO0),
+	PINMUX_IPSR_MSEL(IP0_7_4,		HCTS4_N_A,	SEL_HSCIF4_0),
+
+	PINMUX_IPSR_GPSR(IP0_11_8,		QSPI0_MISO_IO1),
+	PINMUX_IPSR_MSEL(IP0_11_8,		HRTS4_N_A,	SEL_HSCIF4_0),
+
+	PINMUX_IPSR_GPSR(IP0_15_12,		QSPI0_IO2),
+	PINMUX_IPSR_GPSR(IP0_15_12,		HTX4_A),
+
+	PINMUX_IPSR_GPSR(IP0_19_16,		QSPI0_IO3),
+	PINMUX_IPSR_MSEL(IP0_19_16,		HRX4_A,		SEL_HSCIF4_0),
+
+	PINMUX_IPSR_GPSR(IP0_23_20,		QSPI1_SPCLK),
+	PINMUX_IPSR_MSEL(IP0_23_20,		RIF2_CLK_A,	SEL_DRIF2_0),
+	PINMUX_IPSR_MSEL(IP0_23_20,		HSCK4_B,	SEL_HSCIF4_1),
+	PINMUX_IPSR_MSEL(IP0_23_20,		VI4_DATA0_A,	SEL_VIN4_0),
+
+	PINMUX_IPSR_GPSR(IP0_27_24,		QSPI1_MOSI_IO0),
+	PINMUX_IPSR_MSEL(IP0_27_24,		RIF2_SYNC_A,	SEL_DRIF2_0),
+	PINMUX_IPSR_GPSR(IP0_27_24,		HTX4_B),
+	PINMUX_IPSR_MSEL(IP0_27_24,		VI4_DATA1_A,	SEL_VIN4_0),
+
+	PINMUX_IPSR_GPSR(IP0_31_28,		QSPI1_MISO_IO1),
+	PINMUX_IPSR_MSEL(IP0_31_28,		RIF2_D0_A,	SEL_DRIF2_0),
+	PINMUX_IPSR_MSEL(IP0_31_28,		HRX4_B,		SEL_HSCIF4_1),
+	PINMUX_IPSR_MSEL(IP0_31_28,		VI4_DATA2_A,	SEL_VIN4_0),
+
+	/* IPSR1 */
+	PINMUX_IPSR_GPSR(IP1_3_0,		QSPI1_IO2),
+	PINMUX_IPSR_MSEL(IP1_3_0,		RIF2_D1_A,	SEL_DRIF2_0),
+	PINMUX_IPSR_GPSR(IP1_3_0,		HTX3_C),
+	PINMUX_IPSR_MSEL(IP1_3_0,		VI4_DATA3_A,	SEL_VIN4_0),
+
+	PINMUX_IPSR_GPSR(IP1_7_4,		QSPI1_IO3),
+	PINMUX_IPSR_MSEL(IP1_7_4,		RIF3_CLK_A,	SEL_DRIF3_0),
+	PINMUX_IPSR_MSEL(IP1_7_4,		HRX3_C,		SEL_HSCIF3_2),
+	PINMUX_IPSR_MSEL(IP1_7_4,		VI4_DATA4_A,	SEL_VIN4_0),
+
+	PINMUX_IPSR_GPSR(IP1_11_8,		QSPI1_SSL),
+	PINMUX_IPSR_MSEL(IP1_11_8,		RIF3_SYNC_A,	SEL_DRIF3_0),
+	PINMUX_IPSR_MSEL(IP1_11_8,		HSCK3_C,	SEL_HSCIF3_2),
+	PINMUX_IPSR_MSEL(IP1_11_8,		VI4_DATA5_A,	SEL_VIN4_0),
+
+	PINMUX_IPSR_GPSR(IP1_15_12,		RPC_INT_N),
+	PINMUX_IPSR_MSEL(IP1_15_12,		RIF3_D0_A,	SEL_DRIF3_0),
+	PINMUX_IPSR_MSEL(IP1_15_12,		HCTS3_N_C,	SEL_HSCIF3_2),
+	PINMUX_IPSR_MSEL(IP1_15_12,		VI4_DATA6_A,	SEL_VIN4_0),
+
+	PINMUX_IPSR_GPSR(IP1_19_16,		RPC_RESET_N),
+	PINMUX_IPSR_MSEL(IP1_19_16,		RIF3_D1_A,	SEL_DRIF3_0),
+	PINMUX_IPSR_MSEL(IP1_19_16,		HRTS3_N_C,	SEL_HSCIF3_2),
+	PINMUX_IPSR_MSEL(IP1_19_16,		VI4_DATA7_A,	SEL_VIN4_0),
+
+	PINMUX_IPSR_GPSR(IP1_23_20,		AVB_RD0),
+
+	PINMUX_IPSR_GPSR(IP1_27_24,		AVB_RD1),
+
+	PINMUX_IPSR_GPSR(IP1_31_28,		AVB_RD2),
+
+	/* IPSR2 */
+	PINMUX_IPSR_GPSR(IP2_3_0,		AVB_TXCREFCLK),
+
+	PINMUX_IPSR_GPSR(IP2_7_4,		AVB_MDIO),
+
+	PINMUX_IPSR_GPSR(IP2_11_8,		AVB_MDC),
+
+	PINMUX_IPSR_GPSR(IP2_15_12,		BS_N),
+	PINMUX_IPSR_MSEL(IP2_15_12,		PWM0_A,		SEL_PWM0_0),
+	PINMUX_IPSR_GPSR(IP2_15_12,		AVB_MAGIC),
+	PINMUX_IPSR_GPSR(IP2_15_12,		VI4_CLK),
+	PINMUX_IPSR_GPSR(IP2_15_12,		TX3_C),
+	PINMUX_IPSR_MSEL(IP2_15_12,		VI5_CLK_B,	SEL_VIN5_1),
+
+	PINMUX_IPSR_GPSR(IP2_19_16,		RD_N),
+	PINMUX_IPSR_MSEL(IP2_19_16,		PWM1_A,		SEL_PWM1_0),
+	PINMUX_IPSR_GPSR(IP2_19_16,		AVB_LINK),
+	PINMUX_IPSR_GPSR(IP2_19_16,		VI4_FIELD),
+	PINMUX_IPSR_MSEL(IP2_19_16,		RX3_C,		SEL_SCIF3_2),
+	PINMUX_IPSR_GPSR(IP2_19_16,		FSCLKST2_N_A),
+	PINMUX_IPSR_MSEL(IP2_19_16,		VI5_DATA0_B,	SEL_VIN5_1),
+
+	PINMUX_IPSR_GPSR(IP2_23_20,		RD_WR_N),
+	PINMUX_IPSR_MSEL(IP2_23_20,		SCL7_A,		SEL_I2C7_0),
+	PINMUX_IPSR_GPSR(IP2_23_20,		AVB_AVTP_MATCH_A),
+	PINMUX_IPSR_GPSR(IP2_23_20,		VI4_VSYNC_N),
+	PINMUX_IPSR_GPSR(IP2_23_20,		TX5_B),
+	PINMUX_IPSR_MSEL(IP2_23_20,		SCK3_C,		SEL_SCIF3_2),
+	PINMUX_IPSR_MSEL(IP2_23_20,		PWM5_A,		SEL_PWM5_0),
+
+	PINMUX_IPSR_GPSR(IP2_27_24,		EX_WAIT0),
+	PINMUX_IPSR_MSEL(IP2_27_24,		SDA7_A,		SEL_I2C7_0),
+	PINMUX_IPSR_GPSR(IP2_27_24,		AVB_AVTP_CAPTURE_A),
+	PINMUX_IPSR_GPSR(IP2_27_24,		VI4_HSYNC_N),
+	PINMUX_IPSR_MSEL(IP2_27_24,		RX5_B,		SEL_SCIF5_1),
+	PINMUX_IPSR_MSEL(IP2_27_24,		PWM6_A,		SEL_PWM6_0),
+
+	PINMUX_IPSR_GPSR(IP2_31_28,		A0),
+	PINMUX_IPSR_GPSR(IP2_31_28,		IRQ0),
+	PINMUX_IPSR_MSEL(IP2_31_28,		PWM2_A,		SEL_PWM2_0),
+	PINMUX_IPSR_MSEL(IP2_31_28,		MSIOF3_SS1_B,	SEL_MSIOF3_1),
+	PINMUX_IPSR_MSEL(IP2_31_28,		VI5_CLK_A,	SEL_VIN5_0),
+	PINMUX_IPSR_GPSR(IP2_31_28,		DU_CDE),
+	PINMUX_IPSR_MSEL(IP2_31_28,		HRX3_D,		SEL_HSCIF3_3),
+	PINMUX_IPSR_GPSR(IP2_31_28,		IERX),
+	PINMUX_IPSR_GPSR(IP2_31_28,		QSTB_QHE),
+
+	/* IPSR3 */
+	PINMUX_IPSR_GPSR(IP3_3_0,		A1),
+	PINMUX_IPSR_GPSR(IP3_3_0,		IRQ1),
+	PINMUX_IPSR_MSEL(IP3_3_0,		PWM3_A,		SEL_PWM3_0),
+	PINMUX_IPSR_GPSR(IP3_3_0,		DU_DOTCLKIN1),
+	PINMUX_IPSR_MSEL(IP3_3_0,		VI5_DATA0_A,	SEL_VIN5_0),
+	PINMUX_IPSR_GPSR(IP3_3_0,		DU_DISP_CDE),
+	PINMUX_IPSR_MSEL(IP3_3_0,		SDA6_B,		SEL_I2C6_1),
+	PINMUX_IPSR_GPSR(IP3_3_0,		IETX),
+	PINMUX_IPSR_GPSR(IP3_3_0,		QCPV_QDE),
+
+	PINMUX_IPSR_GPSR(IP3_7_4,		A2),
+	PINMUX_IPSR_GPSR(IP3_7_4,		IRQ2),
+	PINMUX_IPSR_GPSR(IP3_7_4,		AVB_AVTP_PPS),
+	PINMUX_IPSR_GPSR(IP3_7_4,		VI4_CLKENB),
+	PINMUX_IPSR_MSEL(IP3_7_4,		VI5_DATA1_A,	SEL_VIN5_0),
+	PINMUX_IPSR_GPSR(IP3_7_4,		DU_DISP),
+	PINMUX_IPSR_MSEL(IP3_7_4,		SCL6_B,		SEL_I2C6_1),
+	PINMUX_IPSR_GPSR(IP3_7_4,		QSTVB_QVE),
+
+	PINMUX_IPSR_GPSR(IP3_11_8,		A3),
+	PINMUX_IPSR_MSEL(IP3_11_8,		CTS4_N_A,	SEL_SCIF4_0),
+	PINMUX_IPSR_MSEL(IP3_11_8,		PWM4_A,		SEL_PWM4_0),
+	PINMUX_IPSR_GPSR(IP3_11_8,		VI4_DATA12),
+	PINMUX_IPSR_GPSR(IP3_11_8,		DU_DOTCLKOUT0),
+	PINMUX_IPSR_GPSR(IP3_11_8,		HTX3_D),
+	PINMUX_IPSR_GPSR(IP3_11_8,		IECLK),
+	PINMUX_IPSR_GPSR(IP3_11_8,		LCDOUT12),
+
+	PINMUX_IPSR_GPSR(IP3_15_12,		A4),
+	PINMUX_IPSR_MSEL(IP3_15_12,		RTS4_N_TANS_A,	SEL_SCIF4_0),
+	PINMUX_IPSR_MSEL(IP3_15_12,		MSIOF3_SYNC_B,	SEL_MSIOF3_1),
+	PINMUX_IPSR_GPSR(IP3_15_12,		VI4_DATA8),
+	PINMUX_IPSR_MSEL(IP3_15_12,		PWM2_B,		SEL_PWM2_1),
+	PINMUX_IPSR_GPSR(IP3_15_12,		DU_DG4),
+	PINMUX_IPSR_MSEL(IP3_15_12,		RIF2_CLK_B,	SEL_DRIF2_1),
+
+	PINMUX_IPSR_GPSR(IP3_19_16,		A5),
+	PINMUX_IPSR_MSEL(IP3_19_16,		SCK4_A,		SEL_SCIF4_0),
+	PINMUX_IPSR_MSEL(IP3_19_16,		MSIOF3_SCK_B,	SEL_MSIOF3_1),
+	PINMUX_IPSR_GPSR(IP3_19_16,		VI4_DATA9),
+	PINMUX_IPSR_MSEL(IP3_19_16,		PWM3_B,		SEL_PWM3_1),
+	PINMUX_IPSR_MSEL(IP3_19_16,		RIF2_SYNC_B,	SEL_DRIF2_1),
+	PINMUX_IPSR_GPSR(IP3_19_16,		QPOLA),
+
+	PINMUX_IPSR_GPSR(IP3_23_20,		A6),
+	PINMUX_IPSR_MSEL(IP3_23_20,		RX4_A,		SEL_SCIF4_0),
+	PINMUX_IPSR_MSEL(IP3_23_20,		MSIOF3_RXD_B,	SEL_MSIOF3_1),
+	PINMUX_IPSR_GPSR(IP3_23_20,		VI4_DATA10),
+	PINMUX_IPSR_MSEL(IP3_23_20,		RIF2_D0_B,	SEL_DRIF2_1),
+
+	PINMUX_IPSR_GPSR(IP3_27_24,		A7),
+	PINMUX_IPSR_GPSR(IP3_27_24,		TX4_A),
+	PINMUX_IPSR_GPSR(IP3_27_24,		MSIOF3_TXD_B),
+	PINMUX_IPSR_GPSR(IP3_27_24,		VI4_DATA11),
+	PINMUX_IPSR_MSEL(IP3_27_24,		RIF2_D1_B,	SEL_DRIF2_1),
+
+	PINMUX_IPSR_GPSR(IP3_31_28,		A8),
+	PINMUX_IPSR_MSEL(IP3_31_28,		SDA6_A,		SEL_I2C6_0),
+	PINMUX_IPSR_MSEL(IP3_31_28,		RX3_B,		SEL_SCIF3_1),
+	PINMUX_IPSR_MSEL(IP3_31_28,		HRX4_C,		SEL_HSCIF4_2),
+	PINMUX_IPSR_MSEL(IP3_31_28,		VI5_HSYNC_N_A,	SEL_VIN5_0),
+	PINMUX_IPSR_GPSR(IP3_31_28,		DU_HSYNC),
+	PINMUX_IPSR_MSEL(IP3_31_28,		VI4_DATA0_B,	SEL_VIN4_1),
+	PINMUX_IPSR_GPSR(IP3_31_28,		QSTH_QHS),
+
+	/* IPSR4 */
+	PINMUX_IPSR_GPSR(IP4_3_0,		A9),
+	PINMUX_IPSR_GPSR(IP4_3_0,		TX5_A),
+	PINMUX_IPSR_GPSR(IP4_3_0,		IRQ3),
+	PINMUX_IPSR_GPSR(IP4_3_0,		VI4_DATA16),
+	PINMUX_IPSR_MSEL(IP4_3_0,		VI5_VSYNC_N_A,	SEL_VIN5_0),
+	PINMUX_IPSR_GPSR(IP4_3_0,		DU_DG7),
+	PINMUX_IPSR_GPSR(IP4_3_0,		LCDOUT15),
+
+	PINMUX_IPSR_GPSR(IP4_7_4,		A10),
+	PINMUX_IPSR_GPSR(IP4_7_4,		IRQ4),
+	PINMUX_IPSR_MSEL(IP4_7_4,		MSIOF2_SYNC_B,	SEL_MSIOF2_1),
+	PINMUX_IPSR_GPSR(IP4_7_4,		VI4_DATA13),
+	PINMUX_IPSR_MSEL(IP4_7_4,		VI5_FIELD_A,	SEL_VIN5_0),
+	PINMUX_IPSR_GPSR(IP4_7_4,		DU_DG5),
+	PINMUX_IPSR_GPSR(IP4_7_4,		FSCLKST2_N_B),
+	PINMUX_IPSR_GPSR(IP4_7_4,		LCDOUT13),
+
+	PINMUX_IPSR_GPSR(IP4_11_8,		A11),
+	PINMUX_IPSR_MSEL(IP4_11_8,		SCL6_A,		SEL_I2C6_0),
+	PINMUX_IPSR_GPSR(IP4_11_8,		TX3_B),
+	PINMUX_IPSR_GPSR(IP4_11_8,		HTX4_C),
+	PINMUX_IPSR_GPSR(IP4_11_8,		DU_VSYNC),
+	PINMUX_IPSR_MSEL(IP4_11_8,		VI4_DATA1_B,	SEL_VIN4_1),
+	PINMUX_IPSR_GPSR(IP4_11_8,		QSTVA_QVS),
+
+	PINMUX_IPSR_GPSR(IP4_15_12,		A12),
+	PINMUX_IPSR_MSEL(IP4_15_12,		RX5_A,		SEL_SCIF5_0),
+	PINMUX_IPSR_GPSR(IP4_15_12,		MSIOF2_SS2_B),
+	PINMUX_IPSR_GPSR(IP4_15_12,		VI4_DATA17),
+	PINMUX_IPSR_MSEL(IP4_15_12,		VI5_DATA3_A,	SEL_VIN5_0),
+	PINMUX_IPSR_GPSR(IP4_15_12,		DU_DG6),
+	PINMUX_IPSR_GPSR(IP4_15_12,		LCDOUT14),
+
+	PINMUX_IPSR_GPSR(IP4_19_16,		A13),
+	PINMUX_IPSR_MSEL(IP4_19_16,		SCK5_A,		SEL_SCIF5_0),
+	PINMUX_IPSR_MSEL(IP4_19_16,		MSIOF2_SCK_B,	SEL_MSIOF2_1),
+	PINMUX_IPSR_GPSR(IP4_19_16,		VI4_DATA14),
+	PINMUX_IPSR_MSEL(IP4_19_16,		HRX4_D,		SEL_HSCIF4_3),
+	PINMUX_IPSR_GPSR(IP4_19_16,		DU_DB2),
+	PINMUX_IPSR_GPSR(IP4_19_16,		LCDOUT2),
+
+	PINMUX_IPSR_GPSR(IP4_23_20,		A14),
+	PINMUX_IPSR_GPSR(IP4_23_20,		MSIOF1_SS1),
+	PINMUX_IPSR_MSEL(IP4_23_20,		MSIOF2_RXD_B,	SEL_MSIOF2_1),
+	PINMUX_IPSR_GPSR(IP4_23_20,		VI4_DATA15),
+	PINMUX_IPSR_GPSR(IP4_23_20,		HTX4_D),
+	PINMUX_IPSR_GPSR(IP4_23_20,		DU_DB3),
+	PINMUX_IPSR_GPSR(IP4_23_20,		LCDOUT3),
+
+	PINMUX_IPSR_GPSR(IP4_27_24,		A15),
+	PINMUX_IPSR_GPSR(IP4_27_24,		MSIOF1_SS2),
+	PINMUX_IPSR_GPSR(IP4_27_24,		MSIOF2_TXD_B),
+	PINMUX_IPSR_GPSR(IP4_27_24,		VI4_DATA18),
+	PINMUX_IPSR_MSEL(IP4_27_24,		VI5_DATA4_A,	SEL_VIN5_0),
+	PINMUX_IPSR_GPSR(IP4_27_24,		DU_DB4),
+	PINMUX_IPSR_GPSR(IP4_27_24,		LCDOUT4),
+
+	PINMUX_IPSR_GPSR(IP4_31_28,		A16),
+	PINMUX_IPSR_GPSR(IP4_31_28,		MSIOF1_SYNC),
+	PINMUX_IPSR_GPSR(IP4_31_28,		MSIOF2_SS1_B),
+	PINMUX_IPSR_GPSR(IP4_31_28,		VI4_DATA19),
+	PINMUX_IPSR_MSEL(IP4_31_28,		VI5_DATA5_A,	SEL_VIN5_0),
+	PINMUX_IPSR_GPSR(IP4_31_28,		DU_DB5),
+	PINMUX_IPSR_GPSR(IP4_31_28,		LCDOUT5),
+
+	/* IPSR5 */
+	PINMUX_IPSR_GPSR(IP5_3_0,		A17),
+	PINMUX_IPSR_GPSR(IP5_3_0,		MSIOF1_RXD),
+	PINMUX_IPSR_GPSR(IP5_3_0,		VI4_DATA20),
+	PINMUX_IPSR_MSEL(IP5_3_0,		VI5_DATA6_A,	SEL_VIN5_0),
+	PINMUX_IPSR_GPSR(IP5_3_0,		DU_DB6),
+	PINMUX_IPSR_GPSR(IP5_3_0,		LCDOUT6),
+
+	PINMUX_IPSR_GPSR(IP5_7_4,		A18),
+	PINMUX_IPSR_GPSR(IP5_7_4,		MSIOF1_TXD),
+	PINMUX_IPSR_GPSR(IP5_7_4,		VI4_DATA21),
+	PINMUX_IPSR_MSEL(IP5_7_4,		VI5_DATA7_A,	SEL_VIN5_0),
+	PINMUX_IPSR_GPSR(IP5_7_4,		DU_DB0),
+	PINMUX_IPSR_MSEL(IP5_7_4,		HRX4_E,		SEL_HSCIF4_4),
+	PINMUX_IPSR_GPSR(IP5_7_4,		LCDOUT0),
+
+	PINMUX_IPSR_GPSR(IP5_11_8,		A19),
+	PINMUX_IPSR_GPSR(IP5_11_8,		MSIOF1_SCK),
+	PINMUX_IPSR_GPSR(IP5_11_8,		VI4_DATA22),
+	PINMUX_IPSR_MSEL(IP5_11_8,		VI5_DATA2_A,	SEL_VIN5_0),
+	PINMUX_IPSR_GPSR(IP5_11_8,		DU_DB1),
+	PINMUX_IPSR_GPSR(IP5_11_8,		HTX4_E),
+	PINMUX_IPSR_GPSR(IP5_11_8,		LCDOUT1),
+
+	PINMUX_IPSR_GPSR(IP5_15_12,		CS0_N),
+	PINMUX_IPSR_GPSR(IP5_15_12,		SCL5),
+	PINMUX_IPSR_GPSR(IP5_15_12,		DU_DR0),
+	PINMUX_IPSR_MSEL(IP5_15_12,		VI4_DATA2_B,	SEL_VIN4_1),
+	PINMUX_IPSR_GPSR(IP5_15_12,		LCDOUT16),
+
+	PINMUX_IPSR_GPSR(IP5_19_16,		WE0_N),
+	PINMUX_IPSR_GPSR(IP5_19_16,		SDA5),
+	PINMUX_IPSR_GPSR(IP5_19_16,		DU_DR1),
+	PINMUX_IPSR_MSEL(IP5_19_16,		VI4_DATA3_B,	SEL_VIN4_1),
+	PINMUX_IPSR_GPSR(IP5_19_16,		LCDOUT17),
+
+	PINMUX_IPSR_GPSR(IP5_23_20,		D0),
+	PINMUX_IPSR_MSEL(IP5_23_20,		MSIOF3_SCK_A,	SEL_MSIOF3_0),
+	PINMUX_IPSR_GPSR(IP5_23_20,		DU_DR2),
+	PINMUX_IPSR_MSEL(IP5_23_20,		CTS4_N_C,	SEL_SCIF4_2),
+	PINMUX_IPSR_GPSR(IP5_23_20,		LCDOUT18),
+
+	PINMUX_IPSR_GPSR(IP5_27_24,		D1),
+	PINMUX_IPSR_MSEL(IP5_27_24,		MSIOF3_SYNC_A,	SEL_MSIOF3_0),
+	PINMUX_IPSR_MSEL(IP5_27_24,		SCK3_A,		SEL_SCIF3_0),
+	PINMUX_IPSR_GPSR(IP5_27_24,		VI4_DATA23),
+	PINMUX_IPSR_MSEL(IP5_27_24,		VI5_CLKENB_A,	SEL_VIN5_0),
+	PINMUX_IPSR_GPSR(IP5_27_24,		DU_DB7),
+	PINMUX_IPSR_MSEL(IP5_27_24,		RTS4_N_TANS_C,	SEL_SCIF4_2),
+	PINMUX_IPSR_GPSR(IP5_27_24,		LCDOUT7),
+
+	PINMUX_IPSR_GPSR(IP5_31_28,		D2),
+	PINMUX_IPSR_MSEL(IP5_31_28,		MSIOF3_RXD_A,	SEL_MSIOF3_0),
+	PINMUX_IPSR_MSEL(IP5_31_28,		RX5_C,		SEL_SCIF5_2),
+	PINMUX_IPSR_MSEL(IP5_31_28,		VI5_DATA14_A,	SEL_VIN5_0),
+	PINMUX_IPSR_GPSR(IP5_31_28,		DU_DR3),
+	PINMUX_IPSR_MSEL(IP5_31_28,		RX4_C,		SEL_SCIF4_2),
+	PINMUX_IPSR_GPSR(IP5_31_28,		LCDOUT19),
+
+	/* IPSR6 */
+	PINMUX_IPSR_GPSR(IP6_3_0,		D3),
+	PINMUX_IPSR_GPSR(IP6_3_0,		MSIOF3_TXD_A),
+	PINMUX_IPSR_GPSR(IP6_3_0,		TX5_C),
+	PINMUX_IPSR_MSEL(IP6_3_0,		VI5_DATA15_A,	SEL_VIN5_0),
+	PINMUX_IPSR_GPSR(IP6_3_0,		DU_DR4),
+	PINMUX_IPSR_GPSR(IP6_3_0,		TX4_C),
+	PINMUX_IPSR_GPSR(IP6_3_0,		LCDOUT20),
+
+	PINMUX_IPSR_GPSR(IP6_7_4,		D4),
+	PINMUX_IPSR_GPSR(IP6_7_4,		CANFD1_TX),
+	PINMUX_IPSR_MSEL(IP6_7_4,		HSCK3_B,	SEL_HSCIF3_1),
+	PINMUX_IPSR_GPSR(IP6_7_4,		CAN1_TX),
+	PINMUX_IPSR_MSEL(IP6_7_4,		RTS3_N_TANS_A,	SEL_SCIF3_0),
+	PINMUX_IPSR_GPSR(IP6_7_4,		MSIOF3_SS2_A),
+	PINMUX_IPSR_MSEL(IP6_7_4,		VI5_DATA1_B,	SEL_VIN5_1),
+
+	PINMUX_IPSR_GPSR(IP6_11_8,		D5),
+	PINMUX_IPSR_MSEL(IP6_11_8,		RX3_A,		SEL_SCIF3_0),
+	PINMUX_IPSR_MSEL(IP6_11_8,		HRX3_B,		SEL_HSCIF3_1),
+	PINMUX_IPSR_GPSR(IP6_11_8,		DU_DR5),
+	PINMUX_IPSR_MSEL(IP6_11_8,		VI4_DATA4_B,	SEL_VIN4_1),
+	PINMUX_IPSR_GPSR(IP6_11_8,		LCDOUT21),
+
+	PINMUX_IPSR_GPSR(IP6_15_12,		D6),
+	PINMUX_IPSR_GPSR(IP6_15_12,		TX3_A),
+	PINMUX_IPSR_GPSR(IP6_15_12,		HTX3_B),
+	PINMUX_IPSR_GPSR(IP6_15_12,		DU_DR6),
+	PINMUX_IPSR_MSEL(IP6_15_12,		VI4_DATA5_B,	SEL_VIN4_1),
+	PINMUX_IPSR_GPSR(IP6_15_12,		LCDOUT22),
+
+	PINMUX_IPSR_GPSR(IP6_19_16,		D7),
+	PINMUX_IPSR_GPSR(IP6_19_16,		CANFD1_RX),
+	PINMUX_IPSR_GPSR(IP6_19_16,		IRQ5),
+	PINMUX_IPSR_GPSR(IP6_19_16,		CAN1_RX),
+	PINMUX_IPSR_MSEL(IP6_19_16,		CTS3_N_A,	SEL_SCIF3_0),
+	PINMUX_IPSR_MSEL(IP6_19_16,		VI5_DATA2_B,	SEL_VIN5_1),
+
+	PINMUX_IPSR_GPSR(IP6_23_20,		D8),
+	PINMUX_IPSR_MSEL(IP6_23_20,		MSIOF2_SCK_A,	SEL_MSIOF2_0),
+	PINMUX_IPSR_MSEL(IP6_23_20,		SCK4_B,		SEL_SCIF4_1),
+	PINMUX_IPSR_MSEL(IP6_23_20,		VI5_DATA12_A,	SEL_VIN5_0),
+	PINMUX_IPSR_GPSR(IP6_23_20,		DU_DR7),
+	PINMUX_IPSR_MSEL(IP6_23_20,		RIF3_CLK_B,	SEL_DRIF3_1),
+	PINMUX_IPSR_MSEL(IP6_23_20,		HCTS3_N_E,	SEL_HSCIF3_4),
+	PINMUX_IPSR_GPSR(IP6_23_20,		LCDOUT23),
+
+	PINMUX_IPSR_GPSR(IP6_27_24,		D9),
+	PINMUX_IPSR_MSEL(IP6_27_24,		MSIOF2_SYNC_A,	SEL_MSIOF2_0),
+	PINMUX_IPSR_MSEL(IP6_27_24,		VI5_DATA10_A,	SEL_VIN5_0),
+	PINMUX_IPSR_GPSR(IP6_27_24,		DU_DG0),
+	PINMUX_IPSR_MSEL(IP6_27_24,		RIF3_SYNC_B,	SEL_DRIF3_1),
+	PINMUX_IPSR_MSEL(IP6_27_24,		HRX3_E,		SEL_HSCIF3_4),
+	PINMUX_IPSR_GPSR(IP6_27_24,		LCDOUT8),
+
+	PINMUX_IPSR_GPSR(IP6_31_28,		D10),
+	PINMUX_IPSR_MSEL(IP6_31_28,		MSIOF2_RXD_A,	SEL_MSIOF2_0),
+	PINMUX_IPSR_MSEL(IP6_31_28,		VI5_DATA13_A,	SEL_VIN5_0),
+	PINMUX_IPSR_GPSR(IP6_31_28,		DU_DG1),
+	PINMUX_IPSR_MSEL(IP6_31_28,		RIF3_D0_B,	SEL_DRIF3_1),
+	PINMUX_IPSR_GPSR(IP6_31_28,		HTX3_E),
+	PINMUX_IPSR_GPSR(IP6_31_28,		LCDOUT9),
+
+	/* IPSR7 */
+	PINMUX_IPSR_GPSR(IP7_3_0,		D11),
+	PINMUX_IPSR_GPSR(IP7_3_0,		MSIOF2_TXD_A),
+	PINMUX_IPSR_MSEL(IP7_3_0,		VI5_DATA11_A,	SEL_VIN5_0),
+	PINMUX_IPSR_GPSR(IP7_3_0,		DU_DG2),
+	PINMUX_IPSR_MSEL(IP7_3_0,		RIF3_D1_B,	SEL_DRIF3_1),
+	PINMUX_IPSR_MSEL(IP7_3_0,		HRTS3_N_E,	SEL_HSCIF3_4),
+	PINMUX_IPSR_GPSR(IP7_3_0,		LCDOUT10),
+
+	PINMUX_IPSR_GPSR(IP7_7_4,		D12),
+	PINMUX_IPSR_GPSR(IP7_7_4,		CANFD0_TX),
+	PINMUX_IPSR_GPSR(IP7_7_4,		TX4_B),
+	PINMUX_IPSR_GPSR(IP7_7_4,		CAN0_TX),
+	PINMUX_IPSR_MSEL(IP7_7_4,		VI5_DATA8_A,	SEL_VIN5_0),
+	PINMUX_IPSR_MSEL(IP7_7_4,		VI5_DATA3_B,	SEL_VIN5_1),
+
+	PINMUX_IPSR_GPSR(IP7_11_8,		D13),
+	PINMUX_IPSR_GPSR(IP7_11_8,		CANFD0_RX),
+	PINMUX_IPSR_MSEL(IP7_11_8,		RX4_B,		SEL_SCIF4_1),
+	PINMUX_IPSR_GPSR(IP7_11_8,		CAN0_RX),
+	PINMUX_IPSR_MSEL(IP7_11_8,		VI5_DATA9_A,	SEL_VIN5_0),
+	PINMUX_IPSR_MSEL(IP7_11_8,		SCL7_B,		SEL_I2C7_1),
+	PINMUX_IPSR_MSEL(IP7_11_8,		VI5_DATA4_B,	SEL_VIN5_1),
+
+	PINMUX_IPSR_GPSR(IP7_15_12,		D14),
+	PINMUX_IPSR_GPSR(IP7_15_12,		CAN_CLK),
+	PINMUX_IPSR_MSEL(IP7_15_12,		HRX3_A,		SEL_HSCIF3_0),
+	PINMUX_IPSR_GPSR(IP7_15_12,		MSIOF2_SS2_A),
+	PINMUX_IPSR_MSEL(IP7_15_12,		SDA7_B,		SEL_I2C7_1),
+	PINMUX_IPSR_MSEL(IP7_15_12,		VI5_DATA5_B,	SEL_VIN5_1),
+
+	PINMUX_IPSR_GPSR(IP7_19_16,		D15),
+	PINMUX_IPSR_GPSR(IP7_19_16,		MSIOF2_SS1_A),
+	PINMUX_IPSR_GPSR(IP7_19_16,		HTX3_A),
+	PINMUX_IPSR_GPSR(IP7_19_16,		MSIOF3_SS1_A),
+	PINMUX_IPSR_GPSR(IP7_19_16,		DU_DG3),
+	PINMUX_IPSR_GPSR(IP7_19_16,		LCDOUT11),
+
+	PINMUX_IPSR_GPSR(IP7_23_20,		SCL4),
+	PINMUX_IPSR_GPSR(IP7_23_20,		CS1_N_A26),
+	PINMUX_IPSR_GPSR(IP7_23_20,		DU_DOTCLKIN0),
+	PINMUX_IPSR_MSEL(IP7_23_20,		VI4_DATA6_B,	SEL_VIN4_1),
+	PINMUX_IPSR_MSEL(IP7_23_20,		VI5_DATA6_B,	SEL_VIN5_1),
+	PINMUX_IPSR_GPSR(IP7_23_20,		QCLK),
+
+	PINMUX_IPSR_GPSR(IP7_27_24,		SDA4),
+	PINMUX_IPSR_GPSR(IP7_27_24,		WE1_N),
+	PINMUX_IPSR_MSEL(IP7_27_24,		VI4_DATA7_B,	SEL_VIN4_1),
+	PINMUX_IPSR_MSEL(IP7_27_24,		VI5_DATA7_B,	SEL_VIN5_1),
+	PINMUX_IPSR_GPSR(IP7_27_24,		QPOLB),
+
+	PINMUX_IPSR_GPSR(IP7_31_28,		SD0_CLK),
+	PINMUX_IPSR_GPSR(IP7_31_28,		NFDATA8),
+	PINMUX_IPSR_MSEL(IP7_31_28,		SCL1_C,		SEL_I2C1_2),
+	PINMUX_IPSR_MSEL(IP7_31_28,		HSCK1_B,	SEL_HSCIF1_1),
+	PINMUX_IPSR_MSEL(IP7_31_28,		SDA2_E,		SEL_I2C2_4),
+	PINMUX_IPSR_MSEL(IP7_31_28,		FMCLK_B,	SEL_FM_1),
+
+	/* IPSR8 */
+	PINMUX_IPSR_GPSR(IP8_3_0,		SD0_CMD),
+	PINMUX_IPSR_GPSR(IP8_3_0,		NFDATA9),
+	PINMUX_IPSR_MSEL(IP8_3_0,		HRX1_B,		SEL_HSCIF1_1),
+	PINMUX_IPSR_MSEL(IP8_3_0,		SPEEDIN_B,	SEL_SPEED_PULSE_IF_1),
+
+	PINMUX_IPSR_GPSR(IP8_7_4,		SD0_DAT0),
+	PINMUX_IPSR_GPSR(IP8_7_4,		NFDATA10),
+	PINMUX_IPSR_GPSR(IP8_7_4,		HTX1_B),
+	PINMUX_IPSR_MSEL(IP8_7_4,		REMOCON_B,	SEL_REMOCON_1),
+
+	PINMUX_IPSR_GPSR(IP8_11_8,		SD0_DAT1),
+	PINMUX_IPSR_GPSR(IP8_11_8,		NFDATA11),
+	PINMUX_IPSR_MSEL(IP8_11_8,		SDA2_C,		SEL_I2C2_2),
+	PINMUX_IPSR_MSEL(IP8_11_8,		HCTS1_N_B,	SEL_HSCIF1_1),
+	PINMUX_IPSR_MSEL(IP8_11_8,		FMIN_B,		SEL_FM_1),
+
+	PINMUX_IPSR_GPSR(IP8_15_12,		SD0_DAT2),
+	PINMUX_IPSR_GPSR(IP8_15_12,		NFDATA12),
+	PINMUX_IPSR_MSEL(IP8_15_12,		SCL2_C,		SEL_I2C2_2),
+	PINMUX_IPSR_MSEL(IP8_15_12,		HRTS1_N_B,	SEL_HSCIF1_1),
+	PINMUX_IPSR_GPSR(IP8_15_12,		BPFCLK_B),
+
+	PINMUX_IPSR_GPSR(IP8_19_16,		SD0_DAT3),
+	PINMUX_IPSR_GPSR(IP8_19_16,		NFDATA13),
+	PINMUX_IPSR_MSEL(IP8_19_16,		SDA1_C,		SEL_I2C1_2),
+	PINMUX_IPSR_MSEL(IP8_19_16,		SCL2_E,		SEL_I2C2_4),
+	PINMUX_IPSR_MSEL(IP8_19_16,		SPEEDIN_C,	SEL_SPEED_PULSE_IF_2),
+	PINMUX_IPSR_MSEL(IP8_19_16,		REMOCON_C,	SEL_REMOCON_2),
+
+	PINMUX_IPSR_GPSR(IP8_23_20,		SD1_CLK),
+	PINMUX_IPSR_MSEL(IP8_23_20,		NFDATA14_B,	SEL_NDFC_1),
+
+	PINMUX_IPSR_GPSR(IP8_27_24,		SD1_CMD),
+	PINMUX_IPSR_MSEL(IP8_27_24,		NFDATA15_B,	SEL_NDFC_1),
+
+	PINMUX_IPSR_GPSR(IP8_31_28,		SD1_DAT0),
+	PINMUX_IPSR_MSEL(IP8_31_28,		NFWP_N_B,	SEL_NDFC_1),
+
+	/* IPSR9 */
+	PINMUX_IPSR_GPSR(IP9_3_0,		SD1_DAT1),
+	PINMUX_IPSR_MSEL(IP9_3_0,		NFCE_N_B,	SEL_NDFC_1),
+
+	PINMUX_IPSR_GPSR(IP9_7_4,		SD1_DAT2),
+	PINMUX_IPSR_MSEL(IP9_7_4,		NFALE_B,	SEL_NDFC_1),
+
+	PINMUX_IPSR_GPSR(IP9_11_8,		SD1_DAT3),
+	PINMUX_IPSR_MSEL(IP9_11_8,		NFRB_N_B,	SEL_NDFC_1),
+
+	PINMUX_IPSR_GPSR(IP9_15_12,		SD3_CLK),
+	PINMUX_IPSR_GPSR(IP9_15_12,		NFWE_N),
+
+	PINMUX_IPSR_GPSR(IP9_19_16,		SD3_CMD),
+	PINMUX_IPSR_GPSR(IP9_19_16,		NFRE_N),
+
+	PINMUX_IPSR_GPSR(IP9_23_20,		SD3_DAT0),
+	PINMUX_IPSR_GPSR(IP9_23_20,		NFDATA0),
+
+	PINMUX_IPSR_GPSR(IP9_27_24,		SD3_DAT1),
+	PINMUX_IPSR_GPSR(IP9_27_24,		NFDATA1),
+
+	PINMUX_IPSR_GPSR(IP9_31_28,		SD3_DAT2),
+	PINMUX_IPSR_GPSR(IP9_31_28,		NFDATA2),
+
+	/* IPSR10 */
+	PINMUX_IPSR_GPSR(IP10_3_0,		SD3_DAT3),
+	PINMUX_IPSR_GPSR(IP10_3_0,		NFDATA3),
+
+	PINMUX_IPSR_GPSR(IP10_7_4,		SD3_DAT4),
+	PINMUX_IPSR_GPSR(IP10_7_4,		NFDATA4),
+
+	PINMUX_IPSR_GPSR(IP10_11_8,		SD3_DAT5),
+	PINMUX_IPSR_GPSR(IP10_11_8,		NFDATA5),
+
+	PINMUX_IPSR_GPSR(IP10_15_12,		SD3_DAT6),
+	PINMUX_IPSR_GPSR(IP10_15_12,		NFDATA6),
+
+	PINMUX_IPSR_GPSR(IP10_19_16,		SD3_DAT7),
+	PINMUX_IPSR_GPSR(IP10_19_16,		NFDATA7),
+
+	PINMUX_IPSR_GPSR(IP10_23_20,		SD3_DS),
+	PINMUX_IPSR_GPSR(IP10_23_20,		NFCLE),
+
+	PINMUX_IPSR_GPSR(IP10_27_24,		SD0_CD),
+	PINMUX_IPSR_GPSR(IP10_27_24,		NFALE_A),
+	PINMUX_IPSR_GPSR(IP10_27_24,		SD3_CD),
+	PINMUX_IPSR_MSEL(IP10_27_24,		RIF0_CLK_B,	SEL_DRIF0_1),
+	PINMUX_IPSR_MSEL(IP10_27_24,		SCL2_B,		SEL_I2C2_1),
+	PINMUX_IPSR_MSEL(IP10_27_24,		TCLK1_A,	SEL_TIMER_TMU_0),
+	PINMUX_IPSR_MSEL(IP10_27_24,		SSI_SCK2_B,	SEL_SSI2_1),
+	PINMUX_IPSR_GPSR(IP10_27_24,		TS_SCK0),
+
+	PINMUX_IPSR_GPSR(IP10_31_28,		SD0_WP),
+	PINMUX_IPSR_GPSR(IP10_31_28,		NFRB_N_A),
+	PINMUX_IPSR_GPSR(IP10_31_28,		SD3_WP),
+	PINMUX_IPSR_MSEL(IP10_31_28,		RIF0_D0_B,	SEL_DRIF0_1),
+	PINMUX_IPSR_MSEL(IP10_31_28,		SDA2_B,		SEL_I2C2_1),
+	PINMUX_IPSR_MSEL(IP10_31_28,		TCLK2_A,	SEL_TIMER_TMU_0),
+	PINMUX_IPSR_MSEL(IP10_31_28,		SSI_WS2_B,	SEL_SSI2_1),
+	PINMUX_IPSR_GPSR(IP10_31_28,		TS_SDAT0),
+
+	/* IPSR11 */
+	PINMUX_IPSR_GPSR(IP11_3_0,		SD1_CD),
+	PINMUX_IPSR_MSEL(IP11_3_0,		NFCE_N_A,	SEL_NDFC_0),
+	PINMUX_IPSR_GPSR(IP11_3_0,		SSI_SCK1),
+	PINMUX_IPSR_MSEL(IP11_3_0,		RIF0_D1_B,	SEL_DRIF0_1),
+	PINMUX_IPSR_GPSR(IP11_3_0,		TS_SDEN0),
+
+	PINMUX_IPSR_GPSR(IP11_7_4,		SD1_WP),
+	PINMUX_IPSR_MSEL(IP11_7_4,		NFWP_N_A,	SEL_NDFC_0),
+	PINMUX_IPSR_GPSR(IP11_7_4,		SSI_WS1),
+	PINMUX_IPSR_MSEL(IP11_7_4,		RIF0_SYNC_B,	SEL_DRIF0_1),
+	PINMUX_IPSR_GPSR(IP11_7_4,		TS_SPSYNC0),
+
+	PINMUX_IPSR_MSEL(IP11_11_8,		RX0_A,		SEL_SCIF0_0),
+	PINMUX_IPSR_MSEL(IP11_11_8,		HRX1_A,		SEL_HSCIF1_0),
+	PINMUX_IPSR_MSEL(IP11_11_8,		SSI_SCK2_A,	SEL_SSI2_0),
+	PINMUX_IPSR_GPSR(IP11_11_8,		RIF1_SYNC),
+	PINMUX_IPSR_GPSR(IP11_11_8,		TS_SCK1),
+
+	PINMUX_IPSR_GPSR(IP11_15_12,		TX0_A),
+	PINMUX_IPSR_GPSR(IP11_15_12,		HTX1_A),
+	PINMUX_IPSR_MSEL(IP11_15_12,		SSI_WS2_A,	SEL_SSI2_0),
+	PINMUX_IPSR_GPSR(IP11_15_12,		RIF1_D0),
+	PINMUX_IPSR_GPSR(IP11_15_12,		TS_SDAT1),
+
+	PINMUX_IPSR_MSEL(IP11_19_16,		CTS0_N_A,	SEL_SCIF0_0),
+	PINMUX_IPSR_MSEL(IP11_19_16,		NFDATA14_A,	SEL_NDFC_0),
+	PINMUX_IPSR_GPSR(IP11_19_16,		AUDIO_CLKOUT_A),
+	PINMUX_IPSR_GPSR(IP11_19_16,		RIF1_D1),
+	PINMUX_IPSR_MSEL(IP11_19_16,		SCIF_CLK_A,	SEL_SCIF_0),
+	PINMUX_IPSR_MSEL(IP11_19_16,		FMCLK_A,	SEL_FM_0),
+
+	PINMUX_IPSR_MSEL(IP11_23_20,		RTS0_N_TANS_A,	SEL_SCIF0_0),
+	PINMUX_IPSR_MSEL(IP11_23_20,		NFDATA15_A,	SEL_NDFC_0),
+	PINMUX_IPSR_GPSR(IP11_23_20,		AUDIO_CLKOUT1_A),
+	PINMUX_IPSR_GPSR(IP11_23_20,		RIF1_CLK),
+	PINMUX_IPSR_MSEL(IP11_23_20,		SCL2_A,		SEL_I2C2_0),
+	PINMUX_IPSR_MSEL(IP11_23_20,		FMIN_A,		SEL_FM_0),
+
+	PINMUX_IPSR_MSEL(IP11_27_24,		SCK0_A,		SEL_SCIF0_0),
+	PINMUX_IPSR_MSEL(IP11_27_24,		HSCK1_A,	SEL_HSCIF1_0),
+	PINMUX_IPSR_GPSR(IP11_27_24,		USB3HS0_ID),
+	PINMUX_IPSR_GPSR(IP11_27_24,		RTS1_N_TANS),
+	PINMUX_IPSR_MSEL(IP11_27_24,		SDA2_A,		SEL_I2C2_0),
+	PINMUX_IPSR_MSEL(IP11_27_24,		FMCLK_C,	SEL_FM_2),
+	PINMUX_IPSR_GPSR(IP11_27_24,		USB1_ID),
+
+	PINMUX_IPSR_GPSR(IP11_31_28,		RX1),
+	PINMUX_IPSR_MSEL(IP11_31_28,		HRX2_B,		SEL_HSCIF2_1),
+	PINMUX_IPSR_MSEL(IP11_31_28,		SSI_SCK9_B,	SEL_SSI9_1),
+	PINMUX_IPSR_GPSR(IP11_31_28,		AUDIO_CLKOUT1_B),
+
+	/* IPSR12 */
+	PINMUX_IPSR_GPSR(IP12_3_0,		TX1),
+	PINMUX_IPSR_GPSR(IP12_3_0,		HTX2_B),
+	PINMUX_IPSR_MSEL(IP12_3_0,		SSI_WS9_B,	SEL_SSI9_1),
+	PINMUX_IPSR_GPSR(IP12_3_0,		AUDIO_CLKOUT3_B),
+
+	PINMUX_IPSR_GPSR(IP12_7_4,		SCK2_A),
+	PINMUX_IPSR_MSEL(IP12_7_4,		HSCK0_A,	SEL_HSCIF0_0),
+	PINMUX_IPSR_MSEL(IP12_7_4,		AUDIO_CLKB_A,	SEL_ADGB_0),
+	PINMUX_IPSR_GPSR(IP12_7_4,		CTS1_N),
+	PINMUX_IPSR_MSEL(IP12_7_4,		RIF0_CLK_A,	SEL_DRIF0_0),
+	PINMUX_IPSR_MSEL(IP12_7_4,		REMOCON_A,	SEL_REMOCON_0),
+	PINMUX_IPSR_MSEL(IP12_7_4,		SCIF_CLK_B,	SEL_SCIF_1),
+
+	PINMUX_IPSR_GPSR(IP12_11_8,		TX2_A),
+	PINMUX_IPSR_MSEL(IP12_11_8,		HRX0_A,		SEL_HSCIF0_0),
+	PINMUX_IPSR_GPSR(IP12_11_8,		AUDIO_CLKOUT2_A),
+	PINMUX_IPSR_MSEL(IP12_11_8,		SCL1_A,		SEL_I2C1_0),
+	PINMUX_IPSR_MSEL(IP12_11_8,		FSO_CFE_0_N_A,	SEL_FSO_0),
+	PINMUX_IPSR_GPSR(IP12_11_8,		TS_SDEN1),
+
+	PINMUX_IPSR_GPSR(IP12_15_12,		RX2_A),
+	PINMUX_IPSR_GPSR(IP12_15_12,		HTX0_A),
+	PINMUX_IPSR_GPSR(IP12_15_12,		AUDIO_CLKOUT3_A),
+	PINMUX_IPSR_MSEL(IP12_15_12,		SDA1_A,		SEL_I2C1_0),
+	PINMUX_IPSR_MSEL(IP12_15_12,		FSO_CFE_1_N_A,	SEL_FSO_0),
+	PINMUX_IPSR_GPSR(IP12_15_12,		TS_SPSYNC1),
+
+	PINMUX_IPSR_GPSR(IP12_19_16,		MSIOF0_SCK),
+	PINMUX_IPSR_GPSR(IP12_19_16,		SSI_SCK78),
+
+	PINMUX_IPSR_GPSR(IP12_23_20,		MSIOF0_RXD),
+	PINMUX_IPSR_GPSR(IP12_23_20,		SSI_WS78),
+	PINMUX_IPSR_GPSR(IP12_23_20,		TX2_B),
+
+	PINMUX_IPSR_GPSR(IP12_27_24,		MSIOF0_TXD),
+	PINMUX_IPSR_GPSR(IP12_27_24,		SSI_SDATA7),
+	PINMUX_IPSR_GPSR(IP12_27_24,		RX2_B),
+
+	PINMUX_IPSR_GPSR(IP12_31_28,		MSIOF0_SYNC),
+	PINMUX_IPSR_GPSR(IP12_31_28,		AUDIO_CLKOUT_B),
+	PINMUX_IPSR_GPSR(IP12_31_28,		SSI_SDATA8),
+
+	/* IPSR13 */
+	PINMUX_IPSR_GPSR(IP13_3_0,		MSIOF0_SS1),
+	PINMUX_IPSR_MSEL(IP13_3_0,		HRX2_A,		SEL_HSCIF2_0),
+	PINMUX_IPSR_GPSR(IP13_3_0,		SSI_SCK4),
+	PINMUX_IPSR_MSEL(IP13_3_0,		HCTS0_N_A,	SEL_HSCIF0_0),
+	PINMUX_IPSR_GPSR(IP13_3_0,		BPFCLK_C),
+	PINMUX_IPSR_MSEL(IP13_3_0,		SPEEDIN_A,	SEL_SPEED_PULSE_IF_0),
+
+	PINMUX_IPSR_GPSR(IP13_7_4,		MSIOF0_SS2),
+	PINMUX_IPSR_GPSR(IP13_7_4,		HTX2_A),
+	PINMUX_IPSR_GPSR(IP13_7_4,		SSI_WS4),
+	PINMUX_IPSR_MSEL(IP13_7_4,		HRTS0_N_A,	SEL_HSCIF0_0),
+	PINMUX_IPSR_MSEL(IP13_7_4,		FMIN_C,		SEL_FM_2),
+	PINMUX_IPSR_GPSR(IP13_7_4,		BPFCLK_A),
+
+	PINMUX_IPSR_GPSR(IP13_11_8,		SSI_SDATA9),
+	PINMUX_IPSR_MSEL(IP13_11_8,		AUDIO_CLKC_A,	SEL_ADGC_0),
+	PINMUX_IPSR_GPSR(IP13_11_8,		SCK1),
+
+	PINMUX_IPSR_GPSR(IP13_15_12,		MLB_CLK),
+	PINMUX_IPSR_MSEL(IP13_15_12,		RX0_B,		SEL_SCIF0_1),
+	PINMUX_IPSR_MSEL(IP13_15_12,		RIF0_D0_A,	SEL_DRIF0_0),
+	PINMUX_IPSR_MSEL(IP13_15_12,		SCL1_B,		SEL_I2C1_1),
+	PINMUX_IPSR_MSEL(IP13_15_12,		TCLK1_B,	SEL_TIMER_TMU_1),
+	PINMUX_IPSR_GPSR(IP13_15_12,		SIM0_RST_A),
+
+	PINMUX_IPSR_GPSR(IP13_19_16,		MLB_SIG),
+	PINMUX_IPSR_MSEL(IP13_19_16,		SCK0_B,		SEL_SCIF0_1),
+	PINMUX_IPSR_MSEL(IP13_19_16,		RIF0_D1_A,	SEL_DRIF0_0),
+	PINMUX_IPSR_MSEL(IP13_19_16,		SDA1_B,		SEL_I2C1_1),
+	PINMUX_IPSR_MSEL(IP13_19_16,		TCLK2_B,	SEL_TIMER_TMU_1),
+	PINMUX_IPSR_MSEL(IP13_19_16,		SIM0_D_A,	SEL_SIMCARD_0),
+
+	PINMUX_IPSR_GPSR(IP13_23_20,		MLB_DAT),
+	PINMUX_IPSR_GPSR(IP13_23_20,		TX0_B),
+	PINMUX_IPSR_MSEL(IP13_23_20,		RIF0_SYNC_A,	SEL_DRIF0_0),
+	PINMUX_IPSR_GPSR(IP13_23_20,		SIM0_CLK_A),
+
+	PINMUX_IPSR_GPSR(IP13_27_24,		SSI_SCK01239),
+
+	PINMUX_IPSR_GPSR(IP13_31_28,		SSI_WS01239),
+
+	/* IPSR14 */
+	PINMUX_IPSR_GPSR(IP14_3_0,		SSI_SDATA0),
+
+	PINMUX_IPSR_GPSR(IP14_7_4,		SSI_SDATA1),
+	PINMUX_IPSR_MSEL(IP14_7_4,		AUDIO_CLKC_B,	SEL_ADGC_1),
+	PINMUX_IPSR_MSEL(IP14_7_4,		PWM0_B,		SEL_PWM0_1),
+
+	PINMUX_IPSR_GPSR(IP14_11_8,		SSI_SDATA2),
+	PINMUX_IPSR_GPSR(IP14_11_8,		AUDIO_CLKOUT2_B),
+	PINMUX_IPSR_MSEL(IP14_11_8,		SSI_SCK9_A,	SEL_SSI9_0),
+	PINMUX_IPSR_MSEL(IP14_11_8,		PWM1_B,		SEL_PWM1_1),
+
+	PINMUX_IPSR_GPSR(IP14_15_12,		SSI_SCK349),
+	PINMUX_IPSR_MSEL(IP14_15_12,		PWM2_C,		SEL_PWM2_2),
+
+	PINMUX_IPSR_GPSR(IP14_19_16,		SSI_WS349),
+	PINMUX_IPSR_MSEL(IP14_19_16,		PWM3_C,		SEL_PWM3_2),
+
+	PINMUX_IPSR_GPSR(IP14_23_20,		SSI_SDATA3),
+	PINMUX_IPSR_GPSR(IP14_23_20,		AUDIO_CLKOUT1_C),
+	PINMUX_IPSR_MSEL(IP14_23_20,		AUDIO_CLKB_B,	SEL_ADGB_1),
+	PINMUX_IPSR_MSEL(IP14_23_20,		PWM4_B,		SEL_PWM4_1),
+
+	PINMUX_IPSR_GPSR(IP14_27_24,		SSI_SDATA4),
+	PINMUX_IPSR_MSEL(IP14_27_24,		SSI_WS9_A,	SEL_SSI9_0),
+	PINMUX_IPSR_MSEL(IP14_27_24,		PWM5_B,		SEL_PWM5_1),
+
+	PINMUX_IPSR_GPSR(IP14_31_28,		SSI_SCK5),
+	PINMUX_IPSR_MSEL(IP14_31_28,		HRX0_B,		SEL_HSCIF0_1),
+	PINMUX_IPSR_GPSR(IP14_31_28,		USB0_PWEN_B),
+	PINMUX_IPSR_MSEL(IP14_31_28,		SCL2_D,		SEL_I2C2_3),
+	PINMUX_IPSR_MSEL(IP14_31_28,		PWM6_B,		SEL_PWM6_1),
+
+	/* IPSR15 */
+	PINMUX_IPSR_GPSR(IP15_3_0,		SSI_WS5),
+	PINMUX_IPSR_GPSR(IP15_3_0,		HTX0_B),
+	PINMUX_IPSR_MSEL(IP15_3_0,		USB0_OVC_B,	SEL_USB_20_CH0_1),
+	PINMUX_IPSR_MSEL(IP15_3_0,		SDA2_D,		SEL_I2C2_3),
+
+	PINMUX_IPSR_GPSR(IP15_7_4,		SSI_SDATA5),
+	PINMUX_IPSR_MSEL(IP15_7_4,		HSCK0_B,	SEL_HSCIF0_1),
+	PINMUX_IPSR_MSEL(IP15_7_4,		AUDIO_CLKB_C,	SEL_ADGB_2),
+	PINMUX_IPSR_GPSR(IP15_7_4,		TPU0TO0),
+
+	PINMUX_IPSR_GPSR(IP15_11_8,		SSI_SCK6),
+	PINMUX_IPSR_MSEL(IP15_11_8,		HSCK2_A,	SEL_HSCIF2_0),
+	PINMUX_IPSR_MSEL(IP15_11_8,		AUDIO_CLKC_C,	SEL_ADGC_2),
+	PINMUX_IPSR_GPSR(IP15_11_8,		TPU0TO1),
+	PINMUX_IPSR_MSEL(IP15_11_8,		FSO_CFE_0_N_B,	SEL_FSO_1),
+	PINMUX_IPSR_GPSR(IP15_11_8,		SIM0_RST_B),
+
+	PINMUX_IPSR_GPSR(IP15_15_12,		SSI_WS6),
+	PINMUX_IPSR_MSEL(IP15_15_12,		HCTS2_N_A,	SEL_HSCIF2_0),
+	PINMUX_IPSR_GPSR(IP15_15_12,		AUDIO_CLKOUT2_C),
+	PINMUX_IPSR_GPSR(IP15_15_12,		TPU0TO2),
+	PINMUX_IPSR_MSEL(IP15_15_12,		SDA1_D,		SEL_I2C1_3),
+	PINMUX_IPSR_MSEL(IP15_15_12,		FSO_CFE_1_N_B,	SEL_FSO_1),
+	PINMUX_IPSR_MSEL(IP15_15_12,		SIM0_D_B,	SEL_SIMCARD_1),
+
+	PINMUX_IPSR_GPSR(IP15_19_16,		SSI_SDATA6),
+	PINMUX_IPSR_MSEL(IP15_19_16,		HRTS2_N_A,	SEL_HSCIF2_0),
+	PINMUX_IPSR_GPSR(IP15_19_16,		AUDIO_CLKOUT3_C),
+	PINMUX_IPSR_GPSR(IP15_19_16,		TPU0TO3),
+	PINMUX_IPSR_MSEL(IP15_19_16,		SCL1_D,		SEL_I2C1_3),
+	PINMUX_IPSR_MSEL(IP15_19_16,		FSO_TOE_N_B,	SEL_FSO_1),
+	PINMUX_IPSR_GPSR(IP15_19_16,		SIM0_CLK_B),
+
+	PINMUX_IPSR_GPSR(IP15_23_20,		AUDIO_CLKA),
+
+	PINMUX_IPSR_GPSR(IP15_27_24,		USB30_PWEN),
+	PINMUX_IPSR_GPSR(IP15_27_24,		USB0_PWEN_A),
+
+	PINMUX_IPSR_GPSR(IP15_31_28,		USB30_OVC),
+	PINMUX_IPSR_MSEL(IP15_31_28,		USB0_OVC_A,	SEL_USB_20_CH0_0),
+};
+
+static const struct sh_pfc_pin pinmux_pins[] = {
+	PINMUX_GPIO_GP_ALL(),
+};
+
+static const struct sh_pfc_pin_group pinmux_groups[] = {
+};
+
+static const struct sh_pfc_function pinmux_functions[] = {
+};
+
+static const struct pinmux_cfg_reg pinmux_config_regs[] = {
+#define F_(x, y)	FN_##y
+#define FM(x)		FN_##x
+	{ PINMUX_CFG_REG("GPSR0", 0xe6060100, 32, 1) {
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		GP_0_17_FN,	GPSR0_17,
+		GP_0_16_FN,	GPSR0_16,
+		GP_0_15_FN,	GPSR0_15,
+		GP_0_14_FN,	GPSR0_14,
+		GP_0_13_FN,	GPSR0_13,
+		GP_0_12_FN,	GPSR0_12,
+		GP_0_11_FN,	GPSR0_11,
+		GP_0_10_FN,	GPSR0_10,
+		GP_0_9_FN,	GPSR0_9,
+		GP_0_8_FN,	GPSR0_8,
+		GP_0_7_FN,	GPSR0_7,
+		GP_0_6_FN,	GPSR0_6,
+		GP_0_5_FN,	GPSR0_5,
+		GP_0_4_FN,	GPSR0_4,
+		GP_0_3_FN,	GPSR0_3,
+		GP_0_2_FN,	GPSR0_2,
+		GP_0_1_FN,	GPSR0_1,
+		GP_0_0_FN,	GPSR0_0, }
+	},
+	{ PINMUX_CFG_REG("GPSR1", 0xe6060104, 32, 1) {
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		GP_1_22_FN,	GPSR1_22,
+		GP_1_21_FN,	GPSR1_21,
+		GP_1_20_FN,	GPSR1_20,
+		GP_1_19_FN,	GPSR1_19,
+		GP_1_18_FN,	GPSR1_18,
+		GP_1_17_FN,	GPSR1_17,
+		GP_1_16_FN,	GPSR1_16,
+		GP_1_15_FN,	GPSR1_15,
+		GP_1_14_FN,	GPSR1_14,
+		GP_1_13_FN,	GPSR1_13,
+		GP_1_12_FN,	GPSR1_12,
+		GP_1_11_FN,	GPSR1_11,
+		GP_1_10_FN,	GPSR1_10,
+		GP_1_9_FN,	GPSR1_9,
+		GP_1_8_FN,	GPSR1_8,
+		GP_1_7_FN,	GPSR1_7,
+		GP_1_6_FN,	GPSR1_6,
+		GP_1_5_FN,	GPSR1_5,
+		GP_1_4_FN,	GPSR1_4,
+		GP_1_3_FN,	GPSR1_3,
+		GP_1_2_FN,	GPSR1_2,
+		GP_1_1_FN,	GPSR1_1,
+		GP_1_0_FN,	GPSR1_0, }
+	},
+	{ PINMUX_CFG_REG("GPSR2", 0xe6060108, 32, 1) {
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		GP_2_25_FN,	GPSR2_25,
+		GP_2_24_FN,	GPSR2_24,
+		GP_2_23_FN,	GPSR2_23,
+		GP_2_22_FN,	GPSR2_22,
+		GP_2_21_FN,	GPSR2_21,
+		GP_2_20_FN,	GPSR2_20,
+		GP_2_19_FN,	GPSR2_19,
+		GP_2_18_FN,	GPSR2_18,
+		GP_2_17_FN,	GPSR2_17,
+		GP_2_16_FN,	GPSR2_16,
+		GP_2_15_FN,	GPSR2_15,
+		GP_2_14_FN,	GPSR2_14,
+		GP_2_13_FN,	GPSR2_13,
+		GP_2_12_FN,	GPSR2_12,
+		GP_2_11_FN,	GPSR2_11,
+		GP_2_10_FN,	GPSR2_10,
+		GP_2_9_FN,	GPSR2_9,
+		GP_2_8_FN,	GPSR2_8,
+		GP_2_7_FN,	GPSR2_7,
+		GP_2_6_FN,	GPSR2_6,
+		GP_2_5_FN,	GPSR2_5,
+		GP_2_4_FN,	GPSR2_4,
+		GP_2_3_FN,	GPSR2_3,
+		GP_2_2_FN,	GPSR2_2,
+		GP_2_1_FN,	GPSR2_1,
+		GP_2_0_FN,	GPSR2_0, }
+	},
+	{ PINMUX_CFG_REG("GPSR3", 0xe606010c, 32, 1) {
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		GP_3_15_FN,	GPSR3_15,
+		GP_3_14_FN,	GPSR3_14,
+		GP_3_13_FN,	GPSR3_13,
+		GP_3_12_FN,	GPSR3_12,
+		GP_3_11_FN,	GPSR3_11,
+		GP_3_10_FN,	GPSR3_10,
+		GP_3_9_FN,	GPSR3_9,
+		GP_3_8_FN,	GPSR3_8,
+		GP_3_7_FN,	GPSR3_7,
+		GP_3_6_FN,	GPSR3_6,
+		GP_3_5_FN,	GPSR3_5,
+		GP_3_4_FN,	GPSR3_4,
+		GP_3_3_FN,	GPSR3_3,
+		GP_3_2_FN,	GPSR3_2,
+		GP_3_1_FN,	GPSR3_1,
+		GP_3_0_FN,	GPSR3_0, }
+	},
+	{ PINMUX_CFG_REG("GPSR4", 0xe6060110, 32, 1) {
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		GP_4_10_FN,	GPSR4_10,
+		GP_4_9_FN,	GPSR4_9,
+		GP_4_8_FN,	GPSR4_8,
+		GP_4_7_FN,	GPSR4_7,
+		GP_4_6_FN,	GPSR4_6,
+		GP_4_5_FN,	GPSR4_5,
+		GP_4_4_FN,	GPSR4_4,
+		GP_4_3_FN,	GPSR4_3,
+		GP_4_2_FN,	GPSR4_2,
+		GP_4_1_FN,	GPSR4_1,
+		GP_4_0_FN,	GPSR4_0, }
+	},
+	{ PINMUX_CFG_REG("GPSR5", 0xe6060114, 32, 1) {
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		GP_5_19_FN,	GPSR5_19,
+		GP_5_18_FN,	GPSR5_18,
+		GP_5_17_FN,	GPSR5_17,
+		GP_5_16_FN,	GPSR5_16,
+		GP_5_15_FN,	GPSR5_15,
+		GP_5_14_FN,	GPSR5_14,
+		GP_5_13_FN,	GPSR5_13,
+		GP_5_12_FN,	GPSR5_12,
+		GP_5_11_FN,	GPSR5_11,
+		GP_5_10_FN,	GPSR5_10,
+		GP_5_9_FN,	GPSR5_9,
+		GP_5_8_FN,	GPSR5_8,
+		GP_5_7_FN,	GPSR5_7,
+		GP_5_6_FN,	GPSR5_6,
+		GP_5_5_FN,	GPSR5_5,
+		GP_5_4_FN,	GPSR5_4,
+		GP_5_3_FN,	GPSR5_3,
+		GP_5_2_FN,	GPSR5_2,
+		GP_5_1_FN,	GPSR5_1,
+		GP_5_0_FN,	GPSR5_0, }
+	},
+	{ PINMUX_CFG_REG("GPSR6", 0xe6060118, 32, 1) {
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		GP_6_17_FN,	GPSR6_17,
+		GP_6_16_FN,	GPSR6_16,
+		GP_6_15_FN,	GPSR6_15,
+		GP_6_14_FN,	GPSR6_14,
+		GP_6_13_FN,	GPSR6_13,
+		GP_6_12_FN,	GPSR6_12,
+		GP_6_11_FN,	GPSR6_11,
+		GP_6_10_FN,	GPSR6_10,
+		GP_6_9_FN,	GPSR6_9,
+		GP_6_8_FN,	GPSR6_8,
+		GP_6_7_FN,	GPSR6_7,
+		GP_6_6_FN,	GPSR6_6,
+		GP_6_5_FN,	GPSR6_5,
+		GP_6_4_FN,	GPSR6_4,
+		GP_6_3_FN,	GPSR6_3,
+		GP_6_2_FN,	GPSR6_2,
+		GP_6_1_FN,	GPSR6_1,
+		GP_6_0_FN,	GPSR6_0, }
+	},
+#undef F_
+#undef FM
+
+#define F_(x, y)	x,
+#define FM(x)		FN_##x,
+	{ PINMUX_CFG_REG("IPSR0", 0xe6060200, 32, 4) {
+		IP0_31_28
+		IP0_27_24
+		IP0_23_20
+		IP0_19_16
+		IP0_15_12
+		IP0_11_8
+		IP0_7_4
+		IP0_3_0 }
+	},
+	{ PINMUX_CFG_REG("IPSR1", 0xe6060204, 32, 4) {
+		IP1_31_28
+		IP1_27_24
+		IP1_23_20
+		IP1_19_16
+		IP1_15_12
+		IP1_11_8
+		IP1_7_4
+		IP1_3_0 }
+	},
+	{ PINMUX_CFG_REG("IPSR2", 0xe6060208, 32, 4) {
+		IP2_31_28
+		IP2_27_24
+		IP2_23_20
+		IP2_19_16
+		IP2_15_12
+		IP2_11_8
+		IP2_7_4
+		IP2_3_0 }
+	},
+	{ PINMUX_CFG_REG("IPSR3", 0xe606020c, 32, 4) {
+		IP3_31_28
+		IP3_27_24
+		IP3_23_20
+		IP3_19_16
+		IP3_15_12
+		IP3_11_8
+		IP3_7_4
+		IP3_3_0 }
+	},
+	{ PINMUX_CFG_REG("IPSR4", 0xe6060210, 32, 4) {
+		IP4_31_28
+		IP4_27_24
+		IP4_23_20
+		IP4_19_16
+		IP4_15_12
+		IP4_11_8
+		IP4_7_4
+		IP4_3_0 }
+	},
+	{ PINMUX_CFG_REG("IPSR5", 0xe6060214, 32, 4) {
+		IP5_31_28
+		IP5_27_24
+		IP5_23_20
+		IP5_19_16
+		IP5_15_12
+		IP5_11_8
+		IP5_7_4
+		IP5_3_0 }
+	},
+	{ PINMUX_CFG_REG("IPSR6", 0xe6060218, 32, 4) {
+		IP6_31_28
+		IP6_27_24
+		IP6_23_20
+		IP6_19_16
+		IP6_15_12
+		IP6_11_8
+		IP6_7_4
+		IP6_3_0 }
+	},
+	{ PINMUX_CFG_REG("IPSR7", 0xe606021c, 32, 4) {
+		IP7_31_28
+		IP7_27_24
+		IP7_23_20
+		IP7_19_16
+		IP7_15_12
+		IP7_11_8
+		IP7_7_4
+		IP7_3_0 }
+	},
+	{ PINMUX_CFG_REG("IPSR8", 0xe6060220, 32, 4) {
+		IP8_31_28
+		IP8_27_24
+		IP8_23_20
+		IP8_19_16
+		IP8_15_12
+		IP8_11_8
+		IP8_7_4
+		IP8_3_0 }
+	},
+	{ PINMUX_CFG_REG("IPSR9", 0xe6060224, 32, 4) {
+		IP9_31_28
+		IP9_27_24
+		IP9_23_20
+		IP9_19_16
+		IP9_15_12
+		IP9_11_8
+		IP9_7_4
+		IP9_3_0 }
+	},
+	{ PINMUX_CFG_REG("IPSR10", 0xe6060228, 32, 4) {
+		IP10_31_28
+		IP10_27_24
+		IP10_23_20
+		IP10_19_16
+		IP10_15_12
+		IP10_11_8
+		IP10_7_4
+		IP10_3_0 }
+	},
+	{ PINMUX_CFG_REG("IPSR11", 0xe606022c, 32, 4) {
+		IP11_31_28
+		IP11_27_24
+		IP11_23_20
+		IP11_19_16
+		IP11_15_12
+		IP11_11_8
+		IP11_7_4
+		IP11_3_0 }
+	},
+	{ PINMUX_CFG_REG("IPSR12", 0xe6060230, 32, 4) {
+		IP12_31_28
+		IP12_27_24
+		IP12_23_20
+		IP12_19_16
+		IP12_15_12
+		IP12_11_8
+		IP12_7_4
+		IP12_3_0 }
+	},
+	{ PINMUX_CFG_REG("IPSR13", 0xe6060234, 32, 4) {
+		IP13_31_28
+		IP13_27_24
+		IP13_23_20
+		IP13_19_16
+		IP13_15_12
+		IP13_11_8
+		IP13_7_4
+		IP13_3_0 }
+	},
+	{ PINMUX_CFG_REG("IPSR14", 0xe6060238, 32, 4) {
+		IP14_31_28
+		IP14_27_24
+		IP14_23_20
+		IP14_19_16
+		IP14_15_12
+		IP14_11_8
+		IP14_7_4
+		IP14_3_0 }
+	},
+	{ PINMUX_CFG_REG("IPSR15", 0xe606023c, 32, 4) {
+		IP15_31_28
+		IP15_27_24
+		IP15_23_20
+		IP15_19_16
+		IP15_15_12
+		IP15_11_8
+		IP15_7_4
+		IP15_3_0 }
+	},
+#undef F_
+#undef FM
+
+#define F_(x, y)	x,
+#define FM(x)		FN_##x,
+	{ PINMUX_CFG_REG_VAR("MOD_SEL0", 0xe6060500, 32,
+			     1, 2, 1, 2, 1, 1, 1, 1, 2, 3, 1,
+			     1, 1, 2, 2, 1, 1, 1, 2, 1, 1, 1, 2) {
+		/* RESERVED 31 */
+		0, 0,
+		MOD_SEL0_30_29
+		MOD_SEL0_28
+		MOD_SEL0_27_26
+		MOD_SEL0_25
+		MOD_SEL0_24
+		MOD_SEL0_23
+		MOD_SEL0_22
+		MOD_SEL0_21_20
+		MOD_SEL0_19_18_17
+		MOD_SEL0_16
+		MOD_SEL0_15
+		MOD_SEL0_14
+		MOD_SEL0_13_12
+		MOD_SEL0_11_10
+		MOD_SEL0_9
+		MOD_SEL0_8
+		MOD_SEL0_7
+		MOD_SEL0_6_5
+		MOD_SEL0_4
+		MOD_SEL0_3
+		MOD_SEL0_2
+		MOD_SEL0_1_0 }
+	},
+	{ PINMUX_CFG_REG_VAR("MOD_SEL1", 0xe6060504, 32,
+			     1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1,
+			     1, 2, 2, 2, 1, 1, 2, 1, 4) {
+		MOD_SEL1_31
+		MOD_SEL1_30
+		MOD_SEL1_29
+		MOD_SEL1_28
+		/* RESERVED 27 */
+		0, 0,
+		MOD_SEL1_26
+		MOD_SEL1_25
+		MOD_SEL1_24_23_22
+		MOD_SEL1_21_20_19
+		MOD_SEL1_18
+		MOD_SEL1_17
+		MOD_SEL1_16
+		MOD_SEL1_15
+		MOD_SEL1_14_13
+		MOD_SEL1_12_11
+		MOD_SEL1_10_9
+		MOD_SEL1_8
+		MOD_SEL1_7
+		MOD_SEL1_6_5
+		MOD_SEL1_4
+		/* RESERVED 3, 2, 1, 0  */
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+	},
+	{ },
+};
+
+const struct sh_pfc_soc_info r8a77990_pinmux_info = {
+	.name = "r8a77990_pfc",
+	.unlock_reg = 0xe6060000, /* PMMR */
+
+	.function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
+
+	.pins = pinmux_pins,
+	.nr_pins = ARRAY_SIZE(pinmux_pins),
+	.groups = pinmux_groups,
+	.nr_groups = ARRAY_SIZE(pinmux_groups),
+	.functions = pinmux_functions,
+	.nr_functions = ARRAY_SIZE(pinmux_functions),
+
+	.cfg_regs = pinmux_config_regs,
+
+	.pinmux_data = pinmux_data,
+	.pinmux_data_size = ARRAY_SIZE(pinmux_data),
+};
diff --git a/drivers/pinctrl/renesas/pfc.c b/drivers/pinctrl/renesas/pfc.c
index 66f0ce1..01a027f 100644
--- a/drivers/pinctrl/renesas/pfc.c
+++ b/drivers/pinctrl/renesas/pfc.c
@@ -29,6 +29,7 @@
 	SH_PFC_R8A7795,
 	SH_PFC_R8A7796,
 	SH_PFC_R8A77970,
+	SH_PFC_R8A77990,
 	SH_PFC_R8A77995,
 };
 
@@ -806,6 +807,10 @@
 	if (model == SH_PFC_R8A77970)
 		priv->pfc.info = &r8a77970_pinmux_info;
 #endif
+#ifdef CONFIG_PINCTRL_PFC_R8A77990
+	if (model == SH_PFC_R8A77990)
+		priv->pfc.info = &r8a77990_pinmux_info;
+#endif
 #ifdef CONFIG_PINCTRL_PFC_R8A77995
 	if (model == SH_PFC_R8A77995)
 		priv->pfc.info = &r8a77995_pinmux_info;
@@ -870,6 +875,12 @@
 		.data = SH_PFC_R8A77970,
 	},
 #endif
+#ifdef CONFIG_PINCTRL_PFC_R8A77990
+	{
+		.compatible = "renesas,pfc-r8a77990",
+		.data = SH_PFC_R8A77990,
+	},
+#endif
 #ifdef CONFIG_PINCTRL_PFC_R8A77995
 	{
 		.compatible = "renesas,pfc-r8a77995",
diff --git a/drivers/pinctrl/renesas/sh_pfc.h b/drivers/pinctrl/renesas/sh_pfc.h
index 22b8c95..f406009 100644
--- a/drivers/pinctrl/renesas/sh_pfc.h
+++ b/drivers/pinctrl/renesas/sh_pfc.h
@@ -253,6 +253,7 @@
 extern const struct sh_pfc_soc_info r8a7795_pinmux_info;
 extern const struct sh_pfc_soc_info r8a7796_pinmux_info;
 extern const struct sh_pfc_soc_info r8a77970_pinmux_info;
+extern const struct sh_pfc_soc_info r8a77990_pinmux_info;
 extern const struct sh_pfc_soc_info r8a77995_pinmux_info;
 /* -----------------------------------------------------------------------------
  * Helper macros to create pin and port lists
@@ -368,9 +369,13 @@
 	PORT_GP_CFG_1(bank, 9,  fn, sfx, cfg)
 #define PORT_GP_10(bank, fn, sfx)	PORT_GP_CFG_10(bank, fn, sfx, 0)
 
-#define PORT_GP_CFG_12(bank, fn, sfx, cfg)				\
+#define PORT_GP_CFG_11(bank, fn, sfx, cfg)				\
 	PORT_GP_CFG_10(bank, fn, sfx, cfg),				\
-	PORT_GP_CFG_1(bank, 10, fn, sfx, cfg),				\
+	PORT_GP_CFG_1(bank, 10,  fn, sfx, cfg)
+#define PORT_GP_11(bank, fn, sfx)	PORT_GP_CFG_11(bank, fn, sfx, 0)
+
+#define PORT_GP_CFG_12(bank, fn, sfx, cfg)				\
+	PORT_GP_CFG_11(bank, fn, sfx, cfg),				\
 	PORT_GP_CFG_1(bank, 11, fn, sfx, cfg)
 #define PORT_GP_12(bank, fn, sfx)	PORT_GP_CFG_12(bank, fn, sfx, 0)
 
diff --git a/drivers/power/domain/bcm6328-power-domain.c b/drivers/power/domain/bcm6328-power-domain.c
index f9276e6..a90b2c8 100644
--- a/drivers/power/domain/bcm6328-power-domain.c
+++ b/drivers/power/domain/bcm6328-power-domain.c
@@ -48,15 +48,11 @@
 static int bcm6328_power_domain_probe(struct udevice *dev)
 {
 	struct bcm6328_power_domain *priv = dev_get_priv(dev);
-	fdt_addr_t addr;
-	fdt_size_t size;
 
-	addr = devfdt_get_addr_size_index(dev, 0, &size);
-	if (addr == FDT_ADDR_T_NONE)
+	priv->regs = dev_remap_addr(dev);
+	if (!priv->regs)
 		return -EINVAL;
 
-	priv->regs = ioremap(addr, size);
-
 	return 0;
 }
 
diff --git a/drivers/ram/bmips_ram.c b/drivers/ram/bmips_ram.c
index ad2f0ac..cc37dfa 100644
--- a/drivers/ram/bmips_ram.c
+++ b/drivers/ram/bmips_ram.c
@@ -150,14 +150,11 @@
 	struct bmips_ram_priv *priv = dev_get_priv(dev);
 	const struct bmips_ram_hw *hw =
 		(const struct bmips_ram_hw *)dev_get_driver_data(dev);
-	fdt_addr_t addr;
-	fdt_size_t size;
 
-	addr = devfdt_get_addr_size_index(dev, 0, &size);
-	if (addr == FDT_ADDR_T_NONE)
+	priv->regs = dev_remap_addr(dev);
+	if (!priv->regs)
 		return -EINVAL;
 
-	priv->regs = ioremap(addr, size);
 	priv->hw = hw;
 
 	return 0;
diff --git a/drivers/ram/stm32_sdram.c b/drivers/ram/stm32_sdram.c
index dc39f33..f6cac8e 100644
--- a/drivers/ram/stm32_sdram.c
+++ b/drivers/ram/stm32_sdram.c
@@ -11,6 +11,8 @@
 #include <asm/io.h>
 
 #define MEM_MODE_MASK	GENMASK(2, 0)
+#define SWP_FMC_OFFSET 10
+#define SWP_FMC_MASK	GENMASK(SWP_FMC_OFFSET+1, SWP_FMC_OFFSET)
 #define NOT_FOUND	0xff
 
 struct stm32_fmc_regs {
@@ -256,27 +258,36 @@
 	struct ofnode_phandle_args args;
 	u32 *syscfg_base;
 	u32 mem_remap;
+	u32 swp_fmc;
 	ofnode bank_node;
 	char *bank_name;
 	u8 bank = 0;
 	int ret;
 
-	mem_remap = dev_read_u32_default(dev, "st,mem_remap", NOT_FOUND);
-	if (mem_remap != NOT_FOUND) {
-		ret = dev_read_phandle_with_args(dev, "st,syscfg", NULL, 0, 0,
+	ret = dev_read_phandle_with_args(dev, "st,syscfg", NULL, 0, 0,
 						 &args);
-		if (ret) {
-			debug("%s: can't find syscon device (%d)\n", __func__,
-			      ret);
-			return ret;
-		}
-
+	if (ret) {
+		dev_dbg(dev, "%s: can't find syscon device (%d)\n", __func__, ret);
+	} else {
 		syscfg_base = (u32 *)ofnode_get_addr(args.node);
 
-		/* set memory mapping selection */
-		clrsetbits_le32(syscfg_base, MEM_MODE_MASK, mem_remap);
-	} else {
-		debug("%s: cannot find st,mem_remap property\n", __func__);
+		mem_remap = dev_read_u32_default(dev, "st,mem_remap", NOT_FOUND);
+		if (mem_remap != NOT_FOUND) {
+			/* set memory mapping selection */
+			clrsetbits_le32(syscfg_base, MEM_MODE_MASK, mem_remap);
+		} else {
+			dev_dbg(dev, "%s: cannot find st,mem_remap property\n", __func__);
+		}
+		
+		swp_fmc = dev_read_u32_default(dev, "st,swp_fmc", NOT_FOUND);
+		if (swp_fmc != NOT_FOUND) {
+			/* set fmc swapping selection */
+			clrsetbits_le32(syscfg_base, SWP_FMC_MASK, swp_fmc << SWP_FMC_OFFSET);
+		} else {
+			dev_dbg(dev, "%s: cannot find st,swp_fmc property\n", __func__);
+		}
+
+		dev_dbg(dev, "syscfg %x = %x\n", (u32)syscfg_base, *syscfg_base);
 	}
 
 	dev_for_each_subnode(bank_node, dev) {
diff --git a/drivers/reset/reset-bcm6345.c b/drivers/reset/reset-bcm6345.c
index 62b9563..753c110 100644
--- a/drivers/reset/reset-bcm6345.c
+++ b/drivers/reset/reset-bcm6345.c
@@ -66,15 +66,11 @@
 static int bcm6345_reset_probe(struct udevice *dev)
 {
 	struct bcm6345_reset_priv *priv = dev_get_priv(dev);
-	fdt_addr_t addr;
-	fdt_size_t size;
 
-	addr = devfdt_get_addr_size_index(dev, 0, &size);
-	if (addr == FDT_ADDR_T_NONE)
+	priv->regs = dev_remap_addr(dev);
+	if (!priv->regs)
 		return -EINVAL;
 
-	priv->regs = ioremap(addr, size);
-
 	return 0;
 }
 
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 8777909..2940bd0 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -324,6 +324,15 @@
 	  will need to provide parameters to make this work. The driver will
 	  be available until the real driver model serial is running.
 
+config DEBUG_UART_STM32
+	bool "STMicroelectronics STM32"
+	depends on STM32_SERIAL
+	help
+	  Select this to enable a debug UART using the serial_stm32 driver
+	  You will need to provide parameters to make this work.
+	  The driver will be available until the real driver model
+	  serial is running.
+
 config DEBUG_UART_UNIPHIER
 	bool "UniPhier on-chip UART"
 	depends on ARCH_UNIPHIER
diff --git a/drivers/serial/serial_bcm6345.c b/drivers/serial/serial_bcm6345.c
index 8838c41..ee5d561 100644
--- a/drivers/serial/serial_bcm6345.c
+++ b/drivers/serial/serial_bcm6345.c
@@ -227,17 +227,13 @@
 {
 	struct bcm6345_serial_priv *priv = dev_get_priv(dev);
 	struct clk clk;
-	fdt_addr_t addr;
-	fdt_size_t size;
 	int ret;
 
 	/* get address */
-	addr = devfdt_get_addr_size_index(dev, 0, &size);
-	if (addr == FDT_ADDR_T_NONE)
+	priv->base = dev_remap_addr(dev);
+	if (!priv->base)
 		return -EINVAL;
 
-	priv->base = ioremap(addr, size);
-
 	/* get clock rate */
 	ret = clk_get_by_index(dev, 0, &clk);
 	if (ret < 0)
diff --git a/drivers/serial/serial_msm.c b/drivers/serial/serial_msm.c
index 119e6b9..c462394 100644
--- a/drivers/serial/serial_msm.c
+++ b/drivers/serial/serial_msm.c
@@ -16,6 +16,7 @@
 #include <watchdog.h>
 #include <asm/io.h>
 #include <linux/compiler.h>
+#include <dm/pinctrl.h>
 
 /* Serial registers - this driver works in uartdm mode*/
 
@@ -25,6 +26,9 @@
 #define UARTDM_RXFS             0x50 /* RX channel status register */
 #define UARTDM_RXFS_BUF_SHIFT   0x7  /* Number of bytes in the packing buffer */
 #define UARTDM_RXFS_BUF_MASK    0x7
+#define UARTDM_MR1				 0x00
+#define UARTDM_MR2				 0x04
+#define UARTDM_CSR				 0xA0
 
 #define UARTDM_SR                0xA4 /* Status register */
 #define UARTDM_SR_RX_READY       (1 << 0) /* Word is the receiver FIFO */
@@ -45,6 +49,10 @@
 #define UARTDM_TF               0x100 /* UART Transmit FIFO register */
 #define UARTDM_RF               0x140 /* UART Receive FIFO register */
 
+#define UART_DM_CLK_RX_TX_BIT_RATE 0xCC
+#define MSM_BOOT_UART_DM_8_N_1_MODE 0x34
+#define MSM_BOOT_UART_DM_CMD_RESET_RX 0x10
+#define MSM_BOOT_UART_DM_CMD_RESET_TX 0x20
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -179,19 +187,29 @@
 	return 0;
 }
 
+static void uart_dm_init(struct msm_serial_data *priv)
+{
+	writel(UART_DM_CLK_RX_TX_BIT_RATE, priv->base + UARTDM_CSR);
+	writel(0x0, priv->base + UARTDM_MR1);
+	writel(MSM_BOOT_UART_DM_8_N_1_MODE, priv->base + UARTDM_MR2);
+	writel(MSM_BOOT_UART_DM_CMD_RESET_RX, priv->base + UARTDM_CR);
+	writel(MSM_BOOT_UART_DM_CMD_RESET_TX, priv->base + UARTDM_CR);
+}
 static int msm_serial_probe(struct udevice *dev)
 {
+	int ret;
 	struct msm_serial_data *priv = dev_get_priv(dev);
 
-	msm_uart_clk_init(dev); /* Ignore return value and hope clock was
-				  properly initialized by earlier loaders */
+	/* No need to reinitialize the UART after relocation */
+	if (gd->flags & GD_FLG_RELOC)
+		return 0;
 
-	if (readl(priv->base + UARTDM_SR) & UARTDM_SR_UART_OVERRUN)
-		writel(UARTDM_CR_CMD_RESET_ERR, priv->base + UARTDM_CR);
+	ret = msm_uart_clk_init(dev);
+	if (ret)
+		return ret;
 
-	writel(0, priv->base + UARTDM_IMR);
-	writel(UARTDM_CR_CMD_STALE_EVENT_DISABLE, priv->base + UARTDM_CR);
-	msm_serial_fetch(dev);
+	pinctrl_select_state(dev, "uart");
+	uart_dm_init(priv);
 
 	return 0;
 }
diff --git a/drivers/serial/serial_stm32.c b/drivers/serial/serial_stm32.c
index 6717ffa..f262345 100644
--- a/drivers/serial/serial_stm32.c
+++ b/drivers/serial/serial_stm32.c
@@ -7,19 +7,21 @@
 #include <common.h>
 #include <clk.h>
 #include <dm.h>
-#include <asm/io.h>
 #include <serial.h>
+#include <watchdog.h>
+#include <asm/io.h>
 #include <asm/arch/stm32.h>
 #include "serial_stm32.h"
 
-static int stm32_serial_setbrg(struct udevice *dev, int baudrate)
+static void _stm32_serial_setbrg(fdt_addr_t base,
+				 struct stm32_uart_info *uart_info,
+				 u32 clock_rate,
+				 int baudrate)
 {
-	struct stm32x7_serial_platdata *plat = dev_get_platdata(dev);
-	bool stm32f4 = plat->uart_info->stm32f4;
-	fdt_addr_t base = plat->base;
+	bool stm32f4 = uart_info->stm32f4;
 	u32 int_div, mantissa, fraction, oversampling;
 
-	int_div = DIV_ROUND_CLOSEST(plat->clock_rate, baudrate);
+	int_div = DIV_ROUND_CLOSEST(clock_rate, baudrate);
 
 	if (int_div < 16) {
 		oversampling = 8;
@@ -33,6 +35,53 @@
 	fraction = int_div % oversampling;
 
 	writel(mantissa | fraction, base + BRR_OFFSET(stm32f4));
+}
+
+static int stm32_serial_setbrg(struct udevice *dev, int baudrate)
+{
+	struct stm32x7_serial_platdata *plat = dev_get_platdata(dev);
+
+	_stm32_serial_setbrg(plat->base, plat->uart_info,
+			     plat->clock_rate, baudrate);
+
+	return 0;
+}
+
+static int stm32_serial_setparity(struct udevice *dev, enum serial_par parity)
+{
+	struct stm32x7_serial_platdata *plat = dev_get_platdata(dev);
+	bool stm32f4 = plat->uart_info->stm32f4;
+	u8 uart_enable_bit = plat->uart_info->uart_enable_bit;
+	u32 cr1 = plat->base + CR1_OFFSET(stm32f4);
+	u32 config = 0;
+
+	if (stm32f4)
+		return -EINVAL; /* not supported in driver*/
+
+	clrbits_le32(cr1, USART_CR1_RE | USART_CR1_TE | BIT(uart_enable_bit));
+	/* update usart configuration (uart need to be disable)
+	 * PCE: parity check control
+	 * PS : '0' : Even / '1' : Odd
+	 * M[1:0] = '00' : 8 Data bits
+	 * M[1:0] = '01' : 9 Data bits with parity
+	 */
+	switch (parity) {
+	default:
+	case SERIAL_PAR_NONE:
+		config = 0;
+		break;
+	case SERIAL_PAR_ODD:
+		config = USART_CR1_PCE | USART_CR1_PS | USART_CR1_M0;
+		break;
+	case SERIAL_PAR_EVEN:
+		config = USART_CR1_PCE | USART_CR1_M0;
+		break;
+	}
+	clrsetbits_le32(cr1,
+			USART_CR1_PCE | USART_CR1_PS | USART_CR1_M1 |
+			USART_CR1_M0,
+			config);
+	setbits_le32(cr1, USART_CR1_RE | USART_CR1_TE | BIT(uart_enable_bit));
 
 	return 0;
 }
@@ -44,12 +93,13 @@
 	fdt_addr_t base = plat->base;
 	u32 isr = readl(base + ISR_OFFSET(stm32f4));
 
-	if ((isr & USART_ISR_FLAG_RXNE) == 0)
+	if ((isr & USART_ISR_RXNE) == 0)
 		return -EAGAIN;
 
-	if (isr & USART_ISR_FLAG_ORE) {
+	if (isr & (USART_ISR_PE | USART_ISR_ORE)) {
 		if (!stm32f4)
-			setbits_le32(base + ICR_OFFSET, USART_ICR_OREF);
+			setbits_le32(base + ICR_OFFSET,
+				     USART_ICR_PCECF | USART_ICR_ORECF);
 		else
 			readl(base + RDR_OFFSET(stm32f4));
 		return -EIO;
@@ -58,13 +108,13 @@
 	return readl(base + RDR_OFFSET(stm32f4));
 }
 
-static int stm32_serial_putc(struct udevice *dev, const char c)
+static int _stm32_serial_putc(fdt_addr_t base,
+			      struct stm32_uart_info *uart_info,
+			      const char c)
 {
-	struct stm32x7_serial_platdata *plat = dev_get_platdata(dev);
-	bool stm32f4 = plat->uart_info->stm32f4;
-	fdt_addr_t base = plat->base;
+	bool stm32f4 = uart_info->stm32f4;
 
-	if ((readl(base + ISR_OFFSET(stm32f4)) & USART_ISR_FLAG_TXE) == 0)
+	if ((readl(base + ISR_OFFSET(stm32f4)) & USART_ISR_TXE) == 0)
 		return -EAGAIN;
 
 	writel(c, base + TDR_OFFSET(stm32f4));
@@ -72,6 +122,13 @@
 	return 0;
 }
 
+static int stm32_serial_putc(struct udevice *dev, const char c)
+{
+	struct stm32x7_serial_platdata *plat = dev_get_platdata(dev);
+
+	return _stm32_serial_putc(plat->base, plat->uart_info, c);
+}
+
 static int stm32_serial_pending(struct udevice *dev, bool input)
 {
 	struct stm32x7_serial_platdata *plat = dev_get_platdata(dev);
@@ -80,24 +137,34 @@
 
 	if (input)
 		return readl(base + ISR_OFFSET(stm32f4)) &
-			USART_ISR_FLAG_RXNE ? 1 : 0;
+			USART_ISR_RXNE ? 1 : 0;
 	else
 		return readl(base + ISR_OFFSET(stm32f4)) &
-			USART_ISR_FLAG_TXE ? 0 : 1;
+			USART_ISR_TXE ? 0 : 1;
+}
+
+static void _stm32_serial_init(fdt_addr_t base,
+			       struct stm32_uart_info *uart_info)
+{
+	bool stm32f4 = uart_info->stm32f4;
+	u8 uart_enable_bit = uart_info->uart_enable_bit;
+
+	/* Disable uart-> enable fifo -> enable uart */
+	clrbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_RE | USART_CR1_TE |
+		     BIT(uart_enable_bit));
+	if (uart_info->has_fifo)
+		setbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_FIFOEN);
+	setbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_RE | USART_CR1_TE |
+		     BIT(uart_enable_bit));
 }
 
 static int stm32_serial_probe(struct udevice *dev)
 {
 	struct stm32x7_serial_platdata *plat = dev_get_platdata(dev);
 	struct clk clk;
-	fdt_addr_t base = plat->base;
 	int ret;
-	bool stm32f4;
-	u8 uart_enable_bit;
 
 	plat->uart_info = (struct stm32_uart_info *)dev_get_driver_data(dev);
-	stm32f4 = plat->uart_info->stm32f4;
-	uart_enable_bit = plat->uart_info->uart_enable_bit;
 
 	ret = clk_get_by_index(dev, 0, &clk);
 	if (ret < 0)
@@ -115,13 +182,7 @@
 		return plat->clock_rate;
 	};
 
-	/* Disable uart-> enable fifo-> enable uart */
-	clrbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_RE | USART_CR1_TE |
-		     BIT(uart_enable_bit));
-	if (plat->uart_info->has_fifo)
-		setbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_FIFOEN);
-	setbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_RE | USART_CR1_TE |
-		     BIT(uart_enable_bit));
+	_stm32_serial_init(plat->base, plat->uart_info);
 
 	return 0;
 }
@@ -149,6 +210,7 @@
 	.pending = stm32_serial_pending,
 	.getc = stm32_serial_getc,
 	.setbrg = stm32_serial_setbrg,
+	.setparity = stm32_serial_setparity
 };
 
 U_BOOT_DRIVER(serial_stm32) = {
@@ -161,3 +223,43 @@
 	.probe = stm32_serial_probe,
 	.flags = DM_FLAG_PRE_RELOC,
 };
+
+#ifdef CONFIG_DEBUG_UART_STM32
+#include <debug_uart.h>
+static inline struct stm32_uart_info *_debug_uart_info(void)
+{
+	struct stm32_uart_info *uart_info;
+
+#if defined(CONFIG_STM32F4)
+	uart_info = &stm32f4_info;
+#elif defined(CONFIG_STM32F7)
+	uart_info = &stm32f7_info;
+#else
+	uart_info = &stm32h7_info;
+#endif
+	return uart_info;
+}
+
+static inline void _debug_uart_init(void)
+{
+	fdt_addr_t base = CONFIG_DEBUG_UART_BASE;
+	struct stm32_uart_info *uart_info = _debug_uart_info();
+
+	_stm32_serial_init(base, uart_info);
+	_stm32_serial_setbrg(base, uart_info,
+			     CONFIG_DEBUG_UART_CLOCK,
+			     CONFIG_BAUDRATE);
+	printf("DEBUG done\n");
+}
+
+static inline void _debug_uart_putc(int c)
+{
+	fdt_addr_t base = CONFIG_DEBUG_UART_BASE;
+	struct stm32_uart_info *uart_info = _debug_uart_info();
+
+	while (_stm32_serial_putc(base, uart_info, c) == -EAGAIN)
+		WATCHDOG_RESET();
+}
+
+DEBUG_UART_FUNCS
+#endif
diff --git a/drivers/serial/serial_stm32.h b/drivers/serial/serial_stm32.h
index 8a1a24f..ccafa31 100644
--- a/drivers/serial/serial_stm32.h
+++ b/drivers/serial/serial_stm32.h
@@ -13,6 +13,7 @@
 #define ISR_OFFSET(x)	(x ? 0x00 : 0x1c)
 
 #define ICR_OFFSET	0x20
+
 /*
  * STM32F4 has one Data Register (DR) for received or transmitted
  * data, so map Receive Data Register (RDR) and Transmit Data
@@ -53,19 +54,26 @@
 };
 
 #define USART_CR1_FIFOEN		BIT(29)
+#define USART_CR1_M1			BIT(28)
 #define USART_CR1_OVER8			BIT(15)
+#define USART_CR1_M0			BIT(12)
+#define USART_CR1_PCE			BIT(10)
+#define USART_CR1_PS			BIT(9)
 #define USART_CR1_TE			BIT(3)
 #define USART_CR1_RE			BIT(2)
 
 #define USART_CR3_OVRDIS		BIT(12)
 
-#define USART_ISR_FLAG_ORE		BIT(3)
-#define USART_ISR_FLAG_RXNE		BIT(5)
-#define USART_ISR_FLAG_TXE		BIT(7)
+#define USART_ISR_TXE			BIT(7)
+#define USART_ISR_RXNE			BIT(5)
+#define USART_ISR_ORE			BIT(3)
+#define USART_ISR_PE			BIT(0)
 
 #define USART_BRR_F_MASK		GENMASK(7, 0)
 #define USART_BRR_M_SHIFT		4
 #define USART_BRR_M_MASK		GENMASK(15, 4)
 
-#define USART_ICR_OREF			BIT(3)
+#define USART_ICR_ORECF			BIT(3)
+#define USART_ICR_PCECF			BIT(0)
+
 #endif
diff --git a/drivers/serial/serial_zynq.c b/drivers/serial/serial_zynq.c
index 06f0a48..3650af2 100644
--- a/drivers/serial/serial_zynq.c
+++ b/drivers/serial/serial_zynq.c
@@ -175,7 +175,9 @@
 {
 	struct zynq_uart_priv *priv = dev_get_priv(dev);
 
-	priv->regs = (struct uart_zynq *)devfdt_get_addr(dev);
+	priv->regs = (struct uart_zynq *)dev_read_addr(dev);
+	if (IS_ERR(priv->regs))
+		return PTR_ERR(priv->regs);
 
 	return 0;
 }
diff --git a/drivers/spi/atcspi200_spi.c b/drivers/spi/atcspi200_spi.c
index 2c1d36e..af96c6d 100644
--- a/drivers/spi/atcspi200_spi.c
+++ b/drivers/spi/atcspi200_spi.c
@@ -197,7 +197,7 @@
 		int num_bytes;
 		u8 *cmd_buf = ns->cmd_buf;
 		size_t cmd_len = ns->cmd_len;
-		size_t data_len = bitlen / 8;
+		unsigned long data_len = bitlen / 8;
 		int rf_cnt;
 		int ret = 0;
 
@@ -229,13 +229,15 @@
 			__atcspi200_spi_start(ns);
 			break;
 		}
-		debug("spi_xfer: data_out %08X(%p) data_in %08X(%p) data_len %u\n",
-		      *(uint *)data_out, data_out, *(uint *)data_in, data_in, data_len);
+		if (data_out)
+			debug("spi_xfer: data_out %08X(%p) data_in %08X(%p) data_len %lu\n",
+			      *(uint *)data_out, data_out, *(uint *)data_in,
+			      data_in, data_len);
 		num_chunks = DIV_ROUND_UP(data_len, max_tran_len);
 		din = data_in;
 		dout = data_out;
 		while (num_chunks--) {
-			tran_len = min(data_len, (size_t)max_tran_len);
+			tran_len = min((size_t)data_len, (size_t)max_tran_len);
 			ns->tran_len = tran_len;
 			num_blks = DIV_ROUND_UP(tran_len , CHUNK_SIZE);
 			num_bytes = (tran_len) % CHUNK_SIZE;
diff --git a/drivers/spi/bcm63xx_hsspi.c b/drivers/spi/bcm63xx_hsspi.c
index 262ed62..4f527fa7 100644
--- a/drivers/spi/bcm63xx_hsspi.c
+++ b/drivers/spi/bcm63xx_hsspi.c
@@ -15,8 +15,6 @@
 #include <wait_bit.h>
 #include <asm/io.h>
 
-DECLARE_GLOBAL_DATA_PTR;
-
 #define HSSPI_PP			0
 
 #define SPI_MAX_SYNC_CLOCK		30000000
@@ -337,17 +335,13 @@
 	struct bcm63xx_hsspi_priv *priv = dev_get_priv(dev);
 	struct reset_ctl rst_ctl;
 	struct clk clk;
-	fdt_addr_t addr;
-	fdt_size_t size;
 	int ret;
 
-	addr = devfdt_get_addr_size_index(dev, 0, &size);
-	if (addr == FDT_ADDR_T_NONE)
+	priv->regs = dev_remap_addr(dev);
+	if (!priv->regs)
 		return -EINVAL;
 
-	priv->regs = ioremap(addr, size);
-	priv->num_cs = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
-				       "num-cs", 8);
+	priv->num_cs = dev_read_u32_default(dev, "num-cs", 8);
 
 	/* enable clock */
 	ret = clk_get_by_name(dev, "hsspi", &clk);
diff --git a/drivers/spi/bcm63xx_spi.c b/drivers/spi/bcm63xx_spi.c
index 473f002..4d19e03 100644
--- a/drivers/spi/bcm63xx_spi.c
+++ b/drivers/spi/bcm63xx_spi.c
@@ -15,8 +15,6 @@
 #include <wait_bit.h>
 #include <asm/io.h>
 
-DECLARE_GLOBAL_DATA_PTR;
-
 /* BCM6348 SPI core */
 #define SPI_6348_CLK			0x06
 #define SPI_6348_CMD			0x00
@@ -373,18 +371,14 @@
 		(const unsigned long *)dev_get_driver_data(dev);
 	struct reset_ctl rst_ctl;
 	struct clk clk;
-	fdt_addr_t addr;
-	fdt_size_t size;
 	int ret;
 
-	addr = devfdt_get_addr_size_index(dev, 0, &size);
-	if (addr == FDT_ADDR_T_NONE)
+	priv->base = dev_remap_addr(dev);
+	if (!priv->base)
 		return -EINVAL;
 
 	priv->regs = regs;
-	priv->base = ioremap(addr, size);
-	priv->num_cs = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
-				       "num-cs", 8);
+	priv->num_cs = dev_read_u32_default(dev, "num-cs", 8);
 
 	/* enable clock */
 	ret = clk_get_by_index(dev, 0, &clk);
diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c
index 3684249..197f41f 100644
--- a/drivers/spi/fsl_qspi.c
+++ b/drivers/spi/fsl_qspi.c
@@ -407,7 +407,7 @@
 {
 	struct fsl_qspi_regs *regs = priv->regs;
 	u32 mcr_reg;
-	void *rx_addr = NULL;
+	void *rx_addr;
 
 	mcr_reg = qspi_read32(priv->flags, &regs->mcr);
 
diff --git a/drivers/spi/lpc32xx_ssp.c b/drivers/spi/lpc32xx_ssp.c
index e6c876d..ce12eee 100644
--- a/drivers/spi/lpc32xx_ssp.c
+++ b/drivers/spi/lpc32xx_ssp.c
@@ -129,7 +129,7 @@
 		int status = readl(&lslave->regs->sr);
 		if ((idx_out < bytelen) && (status & SSP_SR_TNF))
 			writel(((u8 *)dout)[idx_out++], &lslave->regs->data);
-		if ((idx_in < bytelen) && (status & status & SSP_SR_RNE))
+		if ((idx_in < bytelen) && (status & SSP_SR_RNE))
 			((u8 *)din)[idx_in++] = readl(&lslave->regs->data);
 		if (get_timer(start_time) >= CONFIG_LPC32XX_SSP_TIMEOUT)
 			return -1;
diff --git a/drivers/spi/stm32_qspi.c b/drivers/spi/stm32_qspi.c
index 7d18012..f6cc353 100644
--- a/drivers/spi/stm32_qspi.c
+++ b/drivers/spi/stm32_qspi.c
@@ -8,16 +8,16 @@
  */
 
 #include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <errno.h>
 #include <malloc.h>
+#include <reset.h>
 #include <spi.h>
 #include <spi_flash.h>
 #include <asm/io.h>
-#include <dm.h>
-#include <errno.h>
 #include <asm/arch/stm32.h>
-#include <clk.h>
-
-DECLARE_GLOBAL_DATA_PTR;
+#include <linux/ioport.h>
 
 struct stm32_qspi_regs {
 	u32 cr;		/* 0x00 */
@@ -155,6 +155,8 @@
 /* default SCK frequency, unit: HZ */
 #define STM32_QSPI_DEFAULT_SCK_FREQ 108000000
 
+#define STM32_MAX_NORCHIP 2
+
 struct stm32_qspi_platdata {
 	u32 base;
 	u32 memory_map;
@@ -206,11 +208,18 @@
 static void _stm32_qspi_set_flash_size(struct stm32_qspi_priv *priv, u32 size)
 {
 	u32 fsize = fls(size) - 1;
+
 	clrsetbits_le32(&priv->regs->dcr,
 			STM32_QSPI_DCR_FSIZE_MASK << STM32_QSPI_DCR_FSIZE_SHIFT,
 			fsize << STM32_QSPI_DCR_FSIZE_SHIFT);
 }
 
+static void _stm32_qspi_set_cs(struct stm32_qspi_priv *priv, unsigned int cs)
+{
+	clrsetbits_le32(&priv->regs->cr, STM32_QSPI_CR_FSEL,
+			cs ? STM32_QSPI_CR_FSEL : 0);
+}
+
 static unsigned int _stm32_qspi_gen_ccr(struct stm32_qspi_priv *priv)
 {
 	unsigned int ccr_reg = 0;
@@ -255,13 +264,15 @@
 }
 
 static void _stm32_qspi_enable_mmap(struct stm32_qspi_priv *priv,
-		struct spi_flash *flash)
+				    struct spi_flash *flash)
 {
+	unsigned int ccr_reg;
+
 	priv->command = flash->read_cmd | CMD_HAS_ADR | CMD_HAS_DATA
 			| CMD_HAS_DUMMY;
 	priv->dummycycles = flash->dummy_byte * 8;
 
-	unsigned int ccr_reg = _stm32_qspi_gen_ccr(priv);
+	ccr_reg = _stm32_qspi_gen_ccr(priv);
 	ccr_reg |= (STM32_QSPI_CCR_MEM_MAP << STM32_QSPI_CCR_FMODE_SHIFT);
 
 	_stm32_qspi_wait_for_not_busy(priv);
@@ -291,10 +302,12 @@
 }
 
 static int _stm32_qspi_xfer(struct stm32_qspi_priv *priv,
-		struct spi_flash *flash, unsigned int bitlen,
-		const u8 *dout, u8 *din, unsigned long flags)
+			    struct spi_flash *flash, unsigned int bitlen,
+			    const u8 *dout, u8 *din, unsigned long flags)
 {
 	unsigned int words = bitlen / 8;
+	u32 ccr_reg;
+	int i;
 
 	if (flags & SPI_XFER_MMAP) {
 		_stm32_qspi_enable_mmap(priv, flash);
@@ -346,7 +359,7 @@
 		}
 
 		if (flags & SPI_XFER_END) {
-			u32 ccr_reg = _stm32_qspi_gen_ccr(priv);
+			ccr_reg = _stm32_qspi_gen_ccr(priv);
 			ccr_reg |= STM32_QSPI_CCR_IND_WRITE
 					<< STM32_QSPI_CCR_FMODE_SHIFT;
 
@@ -365,7 +378,7 @@
 
 				debug("%s: words:%d data:", __func__, words);
 
-				int i = 0;
+				i = 0;
 				while (words > i) {
 					writeb(dout[i], &priv->regs->dr);
 					debug("%02x ", dout[i]);
@@ -379,7 +392,7 @@
 			}
 		}
 	} else if (din) {
-		u32 ccr_reg = _stm32_qspi_gen_ccr(priv);
+		ccr_reg = _stm32_qspi_gen_ccr(priv);
 		ccr_reg |= STM32_QSPI_CCR_IND_READ
 				<< STM32_QSPI_CCR_FMODE_SHIFT;
 
@@ -394,7 +407,7 @@
 
 		debug("%s: data:", __func__);
 
-		int i = 0;
+		i = 0;
 		while (words > i) {
 			din[i] = readb(&priv->regs->dr);
 			debug("%02x ", din[i]);
@@ -408,27 +421,23 @@
 
 static int stm32_qspi_ofdata_to_platdata(struct udevice *bus)
 {
-	struct fdt_resource res_regs, res_mem;
+	struct resource res_regs, res_mem;
 	struct stm32_qspi_platdata *plat = bus->platdata;
-	const void *blob = gd->fdt_blob;
-	int node = dev_of_offset(bus);
 	int ret;
 
-	ret = fdt_get_named_resource(blob, node, "reg", "reg-names",
-				     "QuadSPI", &res_regs);
+	ret = dev_read_resource_byname(bus, "qspi", &res_regs);
 	if (ret) {
 		debug("Error: can't get regs base addresses(ret = %d)!\n", ret);
 		return -ENOMEM;
 	}
-	ret = fdt_get_named_resource(blob, node, "reg", "reg-names",
-				     "QuadSPI-memory", &res_mem);
+	ret = dev_read_resource_byname(bus, "qspi_mm", &res_mem);
 	if (ret) {
 		debug("Error: can't get mmap base address(ret = %d)!\n", ret);
 		return -ENOMEM;
 	}
 
-	plat->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency",
-					STM32_QSPI_DEFAULT_SCK_FREQ);
+	plat->max_hz = dev_read_u32_default(bus, "spi-max-frequency",
+					    STM32_QSPI_DEFAULT_SCK_FREQ);
 
 	plat->base = res_regs.start;
 	plat->memory_map = res_mem.start;
@@ -448,6 +457,9 @@
 	struct stm32_qspi_platdata *plat = dev_get_platdata(bus);
 	struct stm32_qspi_priv *priv = dev_get_priv(bus);
 	struct dm_spi_bus *dm_spi_bus;
+	struct clk clk;
+	struct reset_ctl reset_ctl;
+	int ret;
 
 	dm_spi_bus = bus->uclass_priv;
 
@@ -457,9 +469,6 @@
 
 	priv->max_hz = plat->max_hz;
 
-#ifdef CONFIG_CLK
-	int ret;
-	struct clk clk;
 	ret = clk_get_by_index(bus, 0, &clk);
 	if (ret < 0)
 		return ret;
@@ -477,7 +486,19 @@
 		return priv->clock_rate;
 	}
 
-#endif
+	ret = reset_get_by_index(bus, 0, &reset_ctl);
+	if (ret) {
+		if (ret != -ENOENT) {
+			dev_err(bus, "failed to get reset\n");
+			clk_disable(&clk);
+			return ret;
+		}
+	} else {
+		/* Reset QSPI controller */
+		reset_assert(&reset_ctl);
+		udelay(2);
+		reset_deassert(&reset_ctl);
+	}
 
 	setbits_le32(&priv->regs->cr, STM32_QSPI_CR_SSHIFT);
 
@@ -494,10 +515,17 @@
 	struct stm32_qspi_priv *priv;
 	struct udevice *bus;
 	struct spi_flash *flash;
+	struct dm_spi_slave_platdata *slave_plat;
 
 	bus = dev->parent;
 	priv = dev_get_priv(bus);
 	flash = dev_get_uclass_priv(dev);
+	slave_plat = dev_get_parent_platdata(dev);
+
+	if (slave_plat->cs >= STM32_MAX_NORCHIP)
+		return -ENODEV;
+
+	_stm32_qspi_set_cs(priv, slave_plat->cs);
 
 	_stm32_qspi_set_flash_size(priv, flash->size);
 
@@ -520,7 +548,7 @@
 }
 
 static int stm32_qspi_xfer(struct udevice *dev, unsigned int bitlen,
-		const void *dout, void *din, unsigned long flags)
+			   const void *dout, void *din, unsigned long flags)
 {
 	struct stm32_qspi_priv *priv;
 	struct udevice *bus;
@@ -538,12 +566,13 @@
 {
 	struct stm32_qspi_platdata *plat = bus->platdata;
 	struct stm32_qspi_priv *priv = dev_get_priv(bus);
+	u32 qspi_clk = priv->clock_rate;
+	u32 prescaler = 255;
+	u32 csht;
 
 	if (speed > plat->max_hz)
 		speed = plat->max_hz;
 
-	u32 qspi_clk = priv->clock_rate;
-	u32 prescaler = 255;
 	if (speed > 0) {
 		prescaler = DIV_ROUND_UP(qspi_clk, speed) - 1;
 		if (prescaler > 255)
@@ -552,7 +581,7 @@
 			prescaler = 0;
 	}
 
-	u32 csht = DIV_ROUND_UP((5 * qspi_clk) / (prescaler + 1), 100000000);
+	csht = DIV_ROUND_UP((5 * qspi_clk) / (prescaler + 1), 100000000);
 	csht = (csht - 1) & STM32_QSPI_DCR_CSHT_MASK;
 
 	_stm32_qspi_wait_for_not_busy(priv);
@@ -562,7 +591,6 @@
 			STM32_QSPI_CR_PRESCALER_SHIFT,
 			prescaler << STM32_QSPI_CR_PRESCALER_SHIFT);
 
-
 	clrsetbits_le32(&priv->regs->dcr,
 			STM32_QSPI_DCR_CSHT_MASK << STM32_QSPI_DCR_CSHT_SHIFT,
 			csht << STM32_QSPI_DCR_CSHT_SHIFT);
@@ -632,6 +660,7 @@
 
 static const struct udevice_id stm32_qspi_ids[] = {
 	{ .compatible = "st,stm32-qspi" },
+	{ .compatible = "st,stm32f469-qspi" },
 	{ }
 };
 
diff --git a/drivers/timer/cadence-ttc.c b/drivers/timer/cadence-ttc.c
index 5b91c8a..3541e5c 100644
--- a/drivers/timer/cadence-ttc.c
+++ b/drivers/timer/cadence-ttc.c
@@ -64,8 +64,10 @@
 {
 	struct cadence_ttc_priv *priv = dev_get_priv(dev);
 
-	priv->regs = map_physmem(devfdt_get_addr(dev),
+	priv->regs = map_physmem(dev_read_addr(dev),
 				 sizeof(struct cadence_ttc_regs), MAP_NOCACHE);
+	if (IS_ERR(priv->regs))
+		return PTR_ERR(priv->regs);
 
 	return 0;
 }
diff --git a/drivers/tpm/Kconfig b/drivers/tpm/Kconfig
index 2a64bc4..93264dd 100644
--- a/drivers/tpm/Kconfig
+++ b/drivers/tpm/Kconfig
@@ -4,18 +4,31 @@
 
 menu "TPM support"
 
+comment "Please select only one TPM revision"
+	depends on TPM_V1 && TPM_V2
+
+config TPM_V1
+	bool "TPMv1.x support"
+	depends on TPM
+	default y
+	help
+	  Major TPM versions are not compatible at all, choose either
+	  one or the other. This option enables TPMv1.x drivers/commands.
+
+if TPM_V1 && !TPM_V2
+
 config TPM_TIS_SANDBOX
 	bool "Enable sandbox TPM driver"
-	depends on SANDBOX
+	depends on TPM_V1 && SANDBOX
 	help
-	  This driver emulates a TPM, providing access to base functions
+	  This driver emulates a TPMv1.x, providing access to base functions
 	  such as reading and writing TPM private data. This is enough to
 	  support Chrome OS verified boot. Extend functionality is not
 	  implemented.
 
 config TPM_ATMEL_TWI
 	bool "Enable Atmel TWI TPM device driver"
-	depends on TPM
+	depends on TPM_V1
 	help
 	  This driver supports an Atmel TPM device connected on the I2C bus.
 	  The usual tpm operations and the 'tpm' command can be used to talk
@@ -24,7 +37,7 @@
 
 config TPM_TIS_INFINEON
 	bool "Enable support for Infineon SLB9635/45 TPMs on I2C"
-	depends on TPM && DM_I2C
+	depends on TPM_V1 && DM_I2C
 	help
 	  This driver supports Infineon TPM devices connected on the I2C bus.
 	  The usual tpm operations and the 'tpm' command can be used to talk
@@ -48,7 +61,8 @@
 
 config TPM_TIS_LPC
 	bool "Enable support for Infineon SLB9635/45 TPMs on LPC"
-	depends on TPM && X86
+	depends on TPM_V1 && X86
+	select TPM_DRIVER_SELECTED
 	help
 	  This driver supports Infineon TPM devices connected on the LPC bus.
 	  The usual tpm operations and the 'tpm' command can be used to talk
@@ -57,7 +71,7 @@
 
 config TPM_AUTH_SESSIONS
 	bool "Enable TPM authentication session support"
-	depends on TPM
+	depends on TPM_V1
 	help
 	  Enable support for authorised (AUTH1) commands as specified in the
 	  TCG Main Specification 1.2. OIAP-authorised versions of the commands
@@ -66,7 +80,7 @@
 
 config TPM_ST33ZP24_I2C
 	bool "STMicroelectronics ST33ZP24 I2C TPM"
-	depends on TPM && DM_I2C
+	depends on TPM_V1 && DM_I2C
 	---help---
 	  This driver supports STMicroelectronics TPM devices connected on the I2C bus.
 	  The usual tpm operations and the 'tpm' command can be used to talk
@@ -75,7 +89,7 @@
 
 config TPM_ST33ZP24_SPI
 	bool "STMicroelectronics ST33ZP24 SPI TPM"
-	depends on TPM && DM_SPI
+	depends on TPM_V1 && DM_SPI
 	---help---
 	  This driver supports STMicroelectronics TPM devices connected on the SPI bus.
 	  The usual tpm operations and the 'tpm' command can be used to talk
@@ -84,14 +98,14 @@
 
 config TPM_FLUSH_RESOURCES
 	bool "Enable TPM resource flushing support"
-	depends on TPM
+	depends on TPM_V1
 	help
 	  Enable support to flush specific resources (e.g. keys) from the TPM.
 	  The functionality is available via the 'tpm' command as well.
 
 config TPM_LOAD_KEY_BY_SHA1
 	bool "Enable TPM key loading by SHA1 support"
-	depends on TPM
+	depends on TPM_V1
 	help
 	  Enable support to load keys into the TPM by identifying
 	  their parent via the public key's SHA1 hash.
@@ -99,8 +113,41 @@
 
 config TPM_LIST_RESOURCES
 	bool "Enable TPM resource listing support"
-	depends on TPM
+	depends on TPM_V1
 	help
 	  Enable support to list specific resources (e.g. keys) within the TPM.
 	  The functionality is available via the 'tpm' command as well.
+
+endif # TPM_V1
+
+config TPM_V2
+	bool "TPMv2.x support"
+	depends on TPM
+	help
+	  Major TPM versions are not compatible at all, choose either
+	  one or the other. This option enables TPMv2.x drivers/commands.
+
+if TPM_V2 && !TPM_V1
+
+config TPM2_TIS_SANDBOX
+	bool "Enable sandbox TPMv2.x driver"
+	depends on TPM_V2 && SANDBOX
+	select TPM_DRIVER_SELECTED
+	help
+	  This driver emulates a TPMv2.x, providing access to base functions
+	  such as basic configuration, PCR extension and PCR read. Extended
+	  functionalities are not implemented.
+
+config TPM2_TIS_SPI
+	bool "Enable support for TPMv2.x SPI chips"
+	depends on TPM_V2 && DM_SPI
+	select TPM_DRIVER_SELECTED
+	help
+	  This driver supports TPMv2.x devices connected on the SPI bus.
+	  The usual TPM operations and the 'tpm' command can be used to talk
+	  to the device using the standard TPM Interface Specification (TIS)
+	  protocol.
+
+endif # TPM_V2
+
 endmenu
diff --git a/drivers/tpm/Makefile b/drivers/tpm/Makefile
index e5fc86f..af473ef 100644
--- a/drivers/tpm/Makefile
+++ b/drivers/tpm/Makefile
@@ -9,3 +9,6 @@
 obj-$(CONFIG_TPM_TIS_SANDBOX) += tpm_tis_sandbox.o
 obj-$(CONFIG_TPM_ST33ZP24_I2C) += tpm_tis_st33zp24_i2c.o
 obj-$(CONFIG_TPM_ST33ZP24_SPI) += tpm_tis_st33zp24_spi.o
+
+obj-$(CONFIG_TPM2_TIS_SANDBOX) += tpm2_tis_sandbox.o
+obj-$(CONFIG_TPM2_TIS_SPI) += tpm2_tis_spi.o
diff --git a/drivers/tpm/tpm-uclass.c b/drivers/tpm/tpm-uclass.c
index e715452..412697e 100644
--- a/drivers/tpm/tpm-uclass.c
+++ b/drivers/tpm/tpm-uclass.c
@@ -6,8 +6,12 @@
 
 #include <common.h>
 #include <dm.h>
-#include <tpm.h>
 #include <linux/unaligned/be_byteshift.h>
+#if defined(CONFIG_TPM_V1)
+#include <tpm-v1.h>
+#elif defined(CONFIG_TPM_V2)
+#include <tpm-v2.h>
+#endif
 #include "tpm_internal.h"
 
 int tpm_open(struct udevice *dev)
diff --git a/drivers/tpm/tpm2_tis_sandbox.c b/drivers/tpm/tpm2_tis_sandbox.c
new file mode 100644
index 0000000..3240cc5
--- /dev/null
+++ b/drivers/tpm/tpm2_tis_sandbox.c
@@ -0,0 +1,625 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2018, Bootlin
+ * Author: Miquel Raynal <miquel.raynal@bootlin.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <tpm-v2.h>
+#include <asm/state.h>
+#include <asm/unaligned.h>
+#include <linux/crc8.h>
+
+/* Hierarchies */
+enum tpm2_hierarchy {
+	TPM2_HIERARCHY_LOCKOUT = 0,
+	TPM2_HIERARCHY_ENDORSEMENT,
+	TPM2_HIERARCHY_PLATFORM,
+	TPM2_HIERARCHY_NB,
+};
+
+/* Subset of supported capabilities */
+enum tpm2_capability {
+	TPM_CAP_TPM_PROPERTIES = 0x6,
+};
+
+/* Subset of supported properties */
+#define TPM2_PROPERTIES_OFFSET 0x0000020E
+
+enum tpm2_cap_tpm_property {
+	TPM2_FAIL_COUNTER = 0,
+	TPM2_PROP_MAX_TRIES,
+	TPM2_RECOVERY_TIME,
+	TPM2_LOCKOUT_RECOVERY,
+	TPM2_PROPERTY_NB,
+};
+
+#define SANDBOX_TPM_PCR_NB 1
+
+static const u8 sandbox_extended_once_pcr[] = {
+	0xf5, 0xa5, 0xfd, 0x42, 0xd1, 0x6a, 0x20, 0x30,
+	0x27, 0x98, 0xef, 0x6e, 0xd3, 0x09, 0x97, 0x9b,
+	0x43, 0x00, 0x3d, 0x23, 0x20, 0xd9, 0xf0, 0xe8,
+	0xea, 0x98, 0x31, 0xa9, 0x27, 0x59, 0xfb, 0x4b,
+};
+
+struct sandbox_tpm2 {
+	/* TPM internal states */
+	bool init_done;
+	bool startup_done;
+	bool tests_done;
+	/* TPM password per hierarchy */
+	char pw[TPM2_HIERARCHY_NB][TPM2_DIGEST_LEN + 1];
+	int pw_sz[TPM2_HIERARCHY_NB];
+	/* TPM properties */
+	u32 properties[TPM2_PROPERTY_NB];
+	/* TPM PCRs */
+	u8 pcr[SANDBOX_TPM_PCR_NB][TPM2_DIGEST_LEN];
+	/* TPM PCR extensions */
+	u32 pcr_extensions[SANDBOX_TPM_PCR_NB];
+};
+
+/*
+ * Check the tag validity depending on the command (authentication required or
+ * not). If authentication is required, check it is valid. Update the auth
+ * pointer to point to the next chunk of data to process if needed.
+ */
+static int sandbox_tpm2_check_session(struct udevice *dev, u32 command, u16 tag,
+				      const u8 **auth,
+				      enum tpm2_hierarchy *hierarchy)
+{
+	struct sandbox_tpm2 *tpm = dev_get_priv(dev);
+	u32 handle, auth_sz, session_handle;
+	u16 nonce_sz, pw_sz;
+	const char *pw;
+
+	switch (command) {
+	case TPM2_CC_STARTUP:
+	case TPM2_CC_SELF_TEST:
+	case TPM2_CC_GET_CAPABILITY:
+	case TPM2_CC_PCR_READ:
+		if (tag != TPM2_ST_NO_SESSIONS) {
+			printf("No session required for command 0x%x\n",
+			       command);
+			return TPM2_RC_BAD_TAG;
+		}
+
+		return 0;
+
+	case TPM2_CC_CLEAR:
+	case TPM2_CC_HIERCHANGEAUTH:
+	case TPM2_CC_DAM_RESET:
+	case TPM2_CC_DAM_PARAMETERS:
+	case TPM2_CC_PCR_EXTEND:
+		if (tag != TPM2_ST_SESSIONS) {
+			printf("Session required for command 0x%x\n", command);
+			return TPM2_RC_AUTH_CONTEXT;
+		}
+
+		handle = get_unaligned_be32(*auth);
+		*auth += sizeof(handle);
+
+		/*
+		 * PCR_Extend had a different protection mechanism and does not
+		 * use the same standards as other commands.
+		 */
+		if (command == TPM2_CC_PCR_EXTEND)
+			break;
+
+		switch (handle) {
+		case TPM2_RH_LOCKOUT:
+			*hierarchy = TPM2_HIERARCHY_LOCKOUT;
+			break;
+		case TPM2_RH_ENDORSEMENT:
+			if (command == TPM2_CC_CLEAR) {
+				printf("Endorsement hierarchy unsupported\n");
+				return TPM2_RC_AUTH_MISSING;
+			}
+			*hierarchy = TPM2_HIERARCHY_ENDORSEMENT;
+			break;
+		case TPM2_RH_PLATFORM:
+			*hierarchy = TPM2_HIERARCHY_PLATFORM;
+			break;
+		default:
+			printf("Wrong handle 0x%x\n", handle);
+			return TPM2_RC_VALUE;
+		}
+
+		break;
+
+	default:
+		printf("Command code not recognized: 0x%x\n", command);
+		return TPM2_RC_COMMAND_CODE;
+	}
+
+	auth_sz = get_unaligned_be32(*auth);
+	*auth += sizeof(auth_sz);
+
+	session_handle = get_unaligned_be32(*auth);
+	*auth += sizeof(session_handle);
+	if (session_handle != TPM2_RS_PW) {
+		printf("Wrong session handle 0x%x\n", session_handle);
+		return TPM2_RC_VALUE;
+	}
+
+	nonce_sz = get_unaligned_be16(*auth);
+	*auth += sizeof(nonce_sz);
+	if (nonce_sz) {
+		printf("Nonces not supported in Sandbox, aborting\n");
+		return TPM2_RC_HANDLE;
+	}
+
+	/* Ignore attributes */
+	*auth += sizeof(u8);
+
+	pw_sz = get_unaligned_be16(*auth);
+	*auth += sizeof(pw_sz);
+	if (auth_sz != (9 + nonce_sz + pw_sz)) {
+		printf("Authentication size (%d) do not match %d\n",
+		       auth_sz, 9 + nonce_sz + pw_sz);
+		return TPM2_RC_SIZE;
+	}
+
+	/* No passwork is acceptable */
+	if (!pw_sz && !tpm->pw_sz[*hierarchy])
+		return TPM2_RC_SUCCESS;
+
+	/* Password is too long */
+	if (pw_sz > TPM2_DIGEST_LEN) {
+		printf("Password should not be more than %dB\n",
+		       TPM2_DIGEST_LEN);
+		return TPM2_RC_AUTHSIZE;
+	}
+
+	pw = (const char *)*auth;
+	*auth += pw_sz;
+
+	/* Password is wrong */
+	if (pw_sz != tpm->pw_sz[*hierarchy] ||
+	    strncmp(pw, tpm->pw[*hierarchy], tpm->pw_sz[*hierarchy])) {
+		printf("Authentication failed: wrong password.\n");
+		return TPM2_RC_BAD_AUTH;
+	}
+
+	return TPM2_RC_SUCCESS;
+}
+
+static int sandbox_tpm2_check_readyness(struct udevice *dev, int command)
+{
+	struct sandbox_tpm2 *tpm = dev_get_priv(dev);
+
+	switch (command) {
+	case TPM2_CC_STARTUP:
+		if (!tpm->init_done || tpm->startup_done)
+			return TPM2_RC_INITIALIZE;
+
+		break;
+	case TPM2_CC_GET_CAPABILITY:
+		if (!tpm->init_done || !tpm->startup_done)
+			return TPM2_RC_INITIALIZE;
+
+		break;
+	case TPM2_CC_SELF_TEST:
+		if (!tpm->startup_done)
+			return TPM2_RC_INITIALIZE;
+
+		break;
+	default:
+		if (!tpm->tests_done)
+			return TPM2_RC_NEEDS_TEST;
+
+		break;
+	}
+
+	return 0;
+}
+
+static int sandbox_tpm2_fill_buf(u8 **recv, size_t *recv_len, u16 tag, u32 rc)
+{
+	*recv_len = sizeof(tag) + sizeof(u32) + sizeof(rc);
+
+	/* Write tag */
+	put_unaligned_be16(tag, *recv);
+	*recv += sizeof(tag);
+
+	/* Write length */
+	put_unaligned_be32(*recv_len, *recv);
+	*recv += sizeof(u32);
+
+	/* Write return code */
+	put_unaligned_be32(rc, *recv);
+	*recv += sizeof(rc);
+
+	/* Add trailing \0 */
+	*recv = '\0';
+
+	return 0;
+}
+
+static int sandbox_tpm2_extend(struct udevice *dev, int pcr_index,
+			       const u8 *extension)
+{
+	struct sandbox_tpm2 *tpm = dev_get_priv(dev);
+	int i;
+
+	/* Only simulate the first extensions from all '0' with only '0' */
+	for (i = 0; i < TPM2_DIGEST_LEN; i++)
+		if (tpm->pcr[pcr_index][i] || extension[i])
+			return TPM2_RC_FAILURE;
+
+	memcpy(tpm->pcr[pcr_index], sandbox_extended_once_pcr,
+	       TPM2_DIGEST_LEN);
+	tpm->pcr_extensions[pcr_index]++;
+
+	return 0;
+};
+
+static int sandbox_tpm2_xfer(struct udevice *dev, const u8 *sendbuf,
+			     size_t send_size, u8 *recvbuf,
+			     size_t *recv_len)
+{
+	struct sandbox_tpm2 *tpm = dev_get_priv(dev);
+	enum tpm2_hierarchy hierarchy = 0;
+	const u8 *sent = sendbuf;
+	u8 *recv = recvbuf;
+	u32 length, command, rc = 0;
+	u16 tag, mode, new_pw_sz;
+	u8 yes_no;
+	int i, j;
+
+	/* TPM2_GetProperty */
+	u32 capability, property, property_count;
+
+	/* TPM2_PCR_Read/Extend variables */
+	int pcr_index;
+	u64 pcr_map = 0;
+	u32 selections, pcr_nb;
+	u16 alg;
+	u8 pcr_array_sz;
+
+	tag = get_unaligned_be16(sent);
+	sent += sizeof(tag);
+
+	length = get_unaligned_be32(sent);
+	sent += sizeof(length);
+	if (length != send_size) {
+		printf("TPM2: Unmatching length, received: %ld, expected: %d\n",
+		       send_size, length);
+		rc = TPM2_RC_SIZE;
+		sandbox_tpm2_fill_buf(&recv, recv_len, tag, rc);
+		return 0;
+	}
+
+	command = get_unaligned_be32(sent);
+	sent += sizeof(command);
+	rc = sandbox_tpm2_check_readyness(dev, command);
+	if (rc) {
+		sandbox_tpm2_fill_buf(&recv, recv_len, tag, rc);
+		return 0;
+	}
+
+	rc = sandbox_tpm2_check_session(dev, command, tag, &sent, &hierarchy);
+	if (rc) {
+		sandbox_tpm2_fill_buf(&recv, recv_len, tag, rc);
+		return 0;
+	}
+
+	switch (command) {
+	case TPM2_CC_STARTUP:
+		mode = get_unaligned_be16(sent);
+		sent += sizeof(mode);
+		switch (mode) {
+		case TPM2_SU_CLEAR:
+		case TPM2_SU_STATE:
+			break;
+		default:
+			rc = TPM2_RC_VALUE;
+		}
+
+		tpm->startup_done = true;
+
+		sandbox_tpm2_fill_buf(&recv, recv_len, tag, rc);
+		break;
+
+	case TPM2_CC_SELF_TEST:
+		yes_no = *sent;
+		sent += sizeof(yes_no);
+		switch (yes_no) {
+		case TPMI_YES:
+		case TPMI_NO:
+			break;
+		default:
+			rc = TPM2_RC_VALUE;
+		}
+
+		tpm->tests_done = true;
+
+		sandbox_tpm2_fill_buf(&recv, recv_len, tag, rc);
+		break;
+
+	case TPM2_CC_CLEAR:
+		/* Reset this hierarchy password */
+		tpm->pw_sz[hierarchy] = 0;
+
+		/* Reset all password if thisis the PLATFORM hierarchy */
+		if (hierarchy == TPM2_HIERARCHY_PLATFORM)
+			for (i = 0; i < TPM2_HIERARCHY_NB; i++)
+				tpm->pw_sz[i] = 0;
+
+		/* Reset the properties */
+		for (i = 0; i < TPM2_PROPERTY_NB; i++)
+			tpm->properties[i] = 0;
+
+		/* Reset the PCRs and their number of extensions */
+		for (i = 0; i < SANDBOX_TPM_PCR_NB; i++) {
+			tpm->pcr_extensions[i] = 0;
+			for (j = 0; j < TPM2_DIGEST_LEN; j++)
+				tpm->pcr[i][j] = 0;
+		}
+
+		sandbox_tpm2_fill_buf(&recv, recv_len, tag, rc);
+		break;
+
+	case TPM2_CC_HIERCHANGEAUTH:
+		new_pw_sz = get_unaligned_be16(sent);
+		sent += sizeof(new_pw_sz);
+		if (new_pw_sz > TPM2_DIGEST_LEN) {
+			rc = TPM2_RC_SIZE;
+		} else if (new_pw_sz) {
+			tpm->pw_sz[hierarchy] = new_pw_sz;
+			memcpy(tpm->pw[hierarchy], sent, new_pw_sz);
+			sent += new_pw_sz;
+		}
+
+		sandbox_tpm2_fill_buf(&recv, recv_len, tag, rc);
+		break;
+
+	case TPM2_CC_GET_CAPABILITY:
+		capability = get_unaligned_be32(sent);
+		sent += sizeof(capability);
+		if (capability != TPM_CAP_TPM_PROPERTIES) {
+			printf("Sandbox TPM only support TPM_CAPABILITIES\n");
+			return TPM2_RC_HANDLE;
+		}
+
+		property = get_unaligned_be32(sent);
+		sent += sizeof(property);
+		property -= TPM2_PROPERTIES_OFFSET;
+
+		property_count = get_unaligned_be32(sent);
+		sent += sizeof(property_count);
+		if (!property_count ||
+		    property + property_count > TPM2_PROPERTY_NB) {
+			rc = TPM2_RC_HANDLE;
+			return sandbox_tpm2_fill_buf(&recv, recv_len, tag, rc);
+		}
+
+		/* Write tag */
+		put_unaligned_be16(tag, recv);
+		recv += sizeof(tag);
+
+		/* Ignore length for now */
+		recv += sizeof(u32);
+
+		/* Write return code */
+		put_unaligned_be32(rc, recv);
+		recv += sizeof(rc);
+
+		/* Tell there is more data to read */
+		*recv = TPMI_YES;
+		recv += sizeof(yes_no);
+
+		/* Repeat the capability */
+		put_unaligned_be32(capability, recv);
+		recv += sizeof(capability);
+
+		/* Give the number of properties that follow */
+		put_unaligned_be32(property_count, recv);
+		recv += sizeof(property_count);
+
+		/* Fill with the properties */
+		for (i = 0; i < property_count; i++) {
+			put_unaligned_be32(TPM2_PROPERTIES_OFFSET + property +
+					   i, recv);
+			recv += sizeof(property);
+			put_unaligned_be32(tpm->properties[property + i],
+					   recv);
+			recv += sizeof(property);
+		}
+
+		/* Add trailing \0 */
+		*recv = '\0';
+
+		/* Write response length */
+		*recv_len = recv - recvbuf;
+		put_unaligned_be32(*recv_len, recvbuf + sizeof(tag));
+
+		break;
+
+	case TPM2_CC_DAM_PARAMETERS:
+		tpm->properties[TPM2_PROP_MAX_TRIES] = get_unaligned_be32(sent);
+		sent += sizeof(*tpm->properties);
+		tpm->properties[TPM2_RECOVERY_TIME] = get_unaligned_be32(sent);
+		sent += sizeof(*tpm->properties);
+		tpm->properties[TPM2_LOCKOUT_RECOVERY] = get_unaligned_be32(sent);
+		sent += sizeof(*tpm->properties);
+
+		sandbox_tpm2_fill_buf(&recv, recv_len, tag, rc);
+		break;
+
+	case TPM2_CC_PCR_READ:
+		selections = get_unaligned_be32(sent);
+		sent += sizeof(selections);
+		if (selections != 1) {
+			printf("Sandbox cannot handle more than one PCR\n");
+			rc = TPM2_RC_VALUE;
+			return sandbox_tpm2_fill_buf(&recv, recv_len, tag, rc);
+		}
+
+		alg = get_unaligned_be16(sent);
+		sent += sizeof(alg);
+		if (alg != TPM2_ALG_SHA256) {
+			printf("Sandbox TPM only handle SHA256 algorithm\n");
+			rc = TPM2_RC_VALUE;
+			return sandbox_tpm2_fill_buf(&recv, recv_len, tag, rc);
+		}
+
+		pcr_array_sz = *sent;
+		sent += sizeof(pcr_array_sz);
+		if (!pcr_array_sz || pcr_array_sz > 8) {
+			printf("Sandbox TPM cannot handle so much PCRs\n");
+			rc = TPM2_RC_VALUE;
+			return sandbox_tpm2_fill_buf(&recv, recv_len, tag, rc);
+		}
+
+		for (i = 0; i < pcr_array_sz; i++)
+			pcr_map += (u64)sent[i] << (i * 8);
+
+		if (pcr_map >> SANDBOX_TPM_PCR_NB) {
+			printf("Sandbox TPM handles up to %d PCR(s)\n",
+			       SANDBOX_TPM_PCR_NB);
+			rc = TPM2_RC_VALUE;
+			return sandbox_tpm2_fill_buf(&recv, recv_len, tag, rc);
+		}
+
+		if (pcr_map >> SANDBOX_TPM_PCR_NB) {
+			printf("Wrong PCR map.\n");
+			rc = TPM2_RC_VALUE;
+			return sandbox_tpm2_fill_buf(&recv, recv_len, tag, rc);
+		}
+
+		for (i = 0; i < SANDBOX_TPM_PCR_NB; i++)
+			if (pcr_map & BIT(i))
+				pcr_index = i;
+
+		/* Write tag */
+		put_unaligned_be16(tag, recv);
+		recv += sizeof(tag);
+
+		/* Ignore length for now */
+		recv += sizeof(u32);
+
+		/* Write return code */
+		put_unaligned_be32(rc, recv);
+		recv += sizeof(rc);
+
+		/* Number of extensions */
+		put_unaligned_be32(tpm->pcr_extensions[pcr_index], recv);
+		recv += sizeof(u32);
+
+		/* Copy the PCR */
+		memcpy(recv, tpm->pcr[pcr_index], TPM2_DIGEST_LEN);
+		recv += TPM2_DIGEST_LEN;
+
+		/* Add trailing \0 */
+		*recv = '\0';
+
+		/* Write response length */
+		*recv_len = recv - recvbuf;
+		put_unaligned_be32(*recv_len, recvbuf + sizeof(tag));
+
+		break;
+
+	case TPM2_CC_PCR_EXTEND:
+		/* Get the PCR index */
+		pcr_index = get_unaligned_be32(sendbuf + sizeof(tag) +
+					       sizeof(length) +
+					       sizeof(command));
+		if (pcr_index > SANDBOX_TPM_PCR_NB) {
+			printf("Sandbox TPM handles up to %d PCR(s)\n",
+			       SANDBOX_TPM_PCR_NB);
+			rc = TPM2_RC_VALUE;
+		}
+
+		/* Check the number of hashes */
+		pcr_nb = get_unaligned_be32(sent);
+		sent += sizeof(pcr_nb);
+		if (pcr_nb != 1) {
+			printf("Sandbox cannot handle more than one PCR\n");
+			rc = TPM2_RC_VALUE;
+			return sandbox_tpm2_fill_buf(&recv, recv_len, tag, rc);
+		}
+
+		/* Check the hash algorithm */
+		alg = get_unaligned_be16(sent);
+		sent += sizeof(alg);
+		if (alg != TPM2_ALG_SHA256) {
+			printf("Sandbox TPM only handle SHA256 algorithm\n");
+			rc = TPM2_RC_VALUE;
+			return sandbox_tpm2_fill_buf(&recv, recv_len, tag, rc);
+		}
+
+		/* Extend the PCR */
+		rc = sandbox_tpm2_extend(dev, pcr_index, sent);
+
+		sandbox_tpm2_fill_buf(&recv, recv_len, tag, rc);
+		break;
+
+	default:
+		printf("TPM2 command %02x unknown in Sandbox\n", command);
+		rc = TPM2_RC_COMMAND_CODE;
+		sandbox_tpm2_fill_buf(&recv, recv_len, tag, rc);
+	}
+
+	return 0;
+}
+
+static int sandbox_tpm2_get_desc(struct udevice *dev, char *buf, int size)
+{
+	if (size < 15)
+		return -ENOSPC;
+
+	return snprintf(buf, size, "Sandbox TPM2.x");
+}
+
+static int sandbox_tpm2_open(struct udevice *dev)
+{
+	struct sandbox_tpm2 *tpm = dev_get_priv(dev);
+
+	if (tpm->init_done)
+		return -EIO;
+
+	tpm->init_done = true;
+
+	return 0;
+}
+
+static int sandbox_tpm2_probe(struct udevice *dev)
+{
+	struct sandbox_tpm2 *tpm = dev_get_priv(dev);
+	struct tpm_chip_priv *priv = dev_get_uclass_priv(dev);
+
+	memset(tpm, 0, sizeof(*tpm));
+
+	priv->pcr_count = 32;
+	priv->pcr_select_min = 2;
+
+	return 0;
+}
+
+static int sandbox_tpm2_close(struct udevice *dev)
+{
+	return 0;
+}
+
+static const struct tpm_ops sandbox_tpm2_ops = {
+	.open		= sandbox_tpm2_open,
+	.close		= sandbox_tpm2_close,
+	.get_desc	= sandbox_tpm2_get_desc,
+	.xfer		= sandbox_tpm2_xfer,
+};
+
+static const struct udevice_id sandbox_tpm2_ids[] = {
+	{ .compatible = "sandbox,tpm2" },
+	{ }
+};
+
+U_BOOT_DRIVER(sandbox_tpm2) = {
+	.name   = "sandbox_tpm2",
+	.id     = UCLASS_TPM,
+	.of_match = sandbox_tpm2_ids,
+	.ops    = &sandbox_tpm2_ops,
+	.probe	= sandbox_tpm2_probe,
+	.priv_auto_alloc_size = sizeof(struct sandbox_tpm2),
+};
diff --git a/drivers/tpm/tpm2_tis_spi.c b/drivers/tpm/tpm2_tis_spi.c
new file mode 100644
index 0000000..c5d17a6
--- /dev/null
+++ b/drivers/tpm/tpm2_tis_spi.c
@@ -0,0 +1,679 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Author:
+ * Miquel Raynal <miquel.raynal@bootlin.com>
+ *
+ * Description:
+ * SPI-level driver for TCG/TIS TPM (trusted platform module).
+ * Specifications at www.trustedcomputinggroup.org
+ *
+ * This device driver implements the TPM interface as defined in
+ * the TCG SPI protocol stack version 2.0.
+ *
+ * It is based on the U-Boot driver tpm_tis_infineon_i2c.c.
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <log.h>
+#include <spi.h>
+#include <tpm-v2.h>
+#include <linux/errno.h>
+#include <linux/compiler.h>
+#include <linux/types.h>
+#include <linux/unaligned/be_byteshift.h>
+#include <asm-generic/gpio.h>
+
+#include "tpm_tis.h"
+#include "tpm_internal.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define TPM_ACCESS(l)			(0x0000 | ((l) << 12))
+#define TPM_INT_ENABLE(l)               (0x0008 | ((l) << 12))
+#define TPM_STS(l)			(0x0018 | ((l) << 12))
+#define TPM_DATA_FIFO(l)		(0x0024 | ((l) << 12))
+#define TPM_DID_VID(l)			(0x0F00 | ((l) << 12))
+#define TPM_RID(l)			(0x0F04 | ((l) << 12))
+
+#define MAX_SPI_FRAMESIZE 64
+
+/* Number of wait states to wait for */
+#define TPM_WAIT_STATES 100
+
+/**
+ * struct tpm_tis_chip_data - Non-discoverable TPM information
+ *
+ * @pcr_count:		Number of PCR per bank
+ * @pcr_select_min:	Size in octets of the pcrSelect array
+ */
+struct tpm_tis_chip_data {
+	unsigned int pcr_count;
+	unsigned int pcr_select_min;
+	unsigned int time_before_first_cmd_ms;
+};
+
+/**
+ * tpm_tis_spi_read() - Read from TPM register
+ *
+ * @addr: register address to read from
+ * @buffer: provided by caller
+ * @len: number of bytes to read
+ *
+ * Read len bytes from TPM register and put them into
+ * buffer (little-endian format, i.e. first byte is put into buffer[0]).
+ *
+ * NOTE: TPM is big-endian for multi-byte values. Multi-byte
+ * values have to be swapped.
+ *
+ * @return -EIO on error, 0 on success.
+ */
+static int tpm_tis_spi_xfer(struct udevice *dev, u32 addr, const u8 *out,
+			    u8 *in, u16 len)
+{
+	struct spi_slave *slave = dev_get_parent_priv(dev);
+	int transfer_len, ret;
+	u8 tx_buf[MAX_SPI_FRAMESIZE];
+	u8 rx_buf[MAX_SPI_FRAMESIZE];
+
+	if (in && out) {
+		log(LOGC_NONE, LOGL_ERR, "%s: can't do full duplex\n",
+		    __func__);
+		return -EINVAL;
+	}
+
+	ret = spi_claim_bus(slave);
+	if (ret < 0) {
+		log(LOGC_NONE, LOGL_ERR, "%s: could not claim bus\n", __func__);
+		return ret;
+	}
+
+	while (len) {
+		/* Request */
+		transfer_len = min_t(u16, len, MAX_SPI_FRAMESIZE);
+		tx_buf[0] = (in ? BIT(7) : 0) | (transfer_len - 1);
+		tx_buf[1] = 0xD4;
+		tx_buf[2] = addr >> 8;
+		tx_buf[3] = addr;
+
+		ret = spi_xfer(slave, 4 * 8, tx_buf, rx_buf, SPI_XFER_BEGIN);
+		if (ret < 0) {
+			log(LOGC_NONE, LOGL_ERR,
+			    "%s: spi request transfer failed (err: %d)\n",
+			    __func__, ret);
+			goto release_bus;
+		}
+
+		/* Wait state */
+		if (!(rx_buf[3] & 0x1)) {
+			int i;
+
+			for (i = 0; i < TPM_WAIT_STATES; i++) {
+				ret = spi_xfer(slave, 1 * 8, NULL, rx_buf, 0);
+				if (ret) {
+					log(LOGC_NONE, LOGL_ERR,
+					    "%s: wait state failed: %d\n",
+					    __func__, ret);
+					goto release_bus;
+				}
+
+				if (rx_buf[0] & 0x1)
+					break;
+			}
+
+			if (i == TPM_WAIT_STATES) {
+				log(LOGC_NONE, LOGL_ERR,
+				    "%s: timeout on wait state\n", __func__);
+				ret = -ETIMEDOUT;
+				goto release_bus;
+			}
+		}
+
+		/* Read/Write */
+		if (out) {
+			memcpy(tx_buf, out, transfer_len);
+			out += transfer_len;
+		}
+
+		ret = spi_xfer(slave, transfer_len * 8,
+			       out ? tx_buf : NULL,
+			       in ? rx_buf : NULL,
+			       SPI_XFER_END);
+		if (ret) {
+			log(LOGC_NONE, LOGL_ERR,
+			    "%s: spi read transfer failed (err: %d)\n",
+			    __func__, ret);
+			goto release_bus;
+		}
+
+		if (in) {
+			memcpy(in, rx_buf, transfer_len);
+			in += transfer_len;
+		}
+
+		len -= transfer_len;
+	}
+
+release_bus:
+	/* If an error occurred, release the chip by deasserting the CS */
+	if (ret < 0)
+		spi_xfer(slave, 0, NULL, NULL, SPI_XFER_END);
+
+	spi_release_bus(slave);
+
+	return ret;
+}
+
+static int tpm_tis_spi_read(struct udevice *dev, u16 addr, u8 *in, u16 len)
+{
+	return tpm_tis_spi_xfer(dev, addr, NULL, in, len);
+}
+
+static int tpm_tis_spi_read32(struct udevice *dev, u32 addr, u32 *result)
+{
+	__le32 result_le;
+	int ret;
+
+	ret = tpm_tis_spi_read(dev, addr, (u8 *)&result_le, sizeof(u32));
+	if (!ret)
+		*result = le32_to_cpu(result_le);
+
+	return ret;
+}
+
+static int tpm_tis_spi_write(struct udevice *dev, u16 addr, const u8 *out,
+			     u16 len)
+{
+	return tpm_tis_spi_xfer(dev, addr, out, NULL, len);
+}
+
+static int tpm_tis_spi_check_locality(struct udevice *dev, int loc)
+{
+	const u8 mask = TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID;
+	struct tpm_chip *chip = dev_get_priv(dev);
+	u8 buf;
+	int ret;
+
+	ret = tpm_tis_spi_read(dev, TPM_ACCESS(loc), &buf, 1);
+	if (ret)
+		return ret;
+
+	if ((buf & mask) == mask) {
+		chip->locality = loc;
+		return 0;
+	}
+
+	return -ENOENT;
+}
+
+static void tpm_tis_spi_release_locality(struct udevice *dev, int loc,
+					 bool force)
+{
+	const u8 mask = TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID;
+	u8 buf;
+
+	if (tpm_tis_spi_read(dev, TPM_ACCESS(loc), &buf, 1) < 0)
+		return;
+
+	if (force || (buf & mask) == mask) {
+		buf = TPM_ACCESS_ACTIVE_LOCALITY;
+		tpm_tis_spi_write(dev, TPM_ACCESS(loc), &buf, 1);
+	}
+}
+
+static int tpm_tis_spi_request_locality(struct udevice *dev, int loc)
+{
+	struct tpm_chip *chip = dev_get_priv(dev);
+	unsigned long start, stop;
+	u8 buf = TPM_ACCESS_REQUEST_USE;
+	int ret;
+
+	ret = tpm_tis_spi_check_locality(dev, loc);
+	if (!ret)
+		return 0;
+
+	if (ret != -ENOENT) {
+		log(LOGC_NONE, LOGL_ERR, "%s: Failed to get locality: %d\n",
+		    __func__, ret);
+		return ret;
+	}
+
+	ret = tpm_tis_spi_write(dev, TPM_ACCESS(loc), &buf, 1);
+	if (ret) {
+		log(LOGC_NONE, LOGL_ERR, "%s: Failed to write to TPM: %d\n",
+		    __func__, ret);
+		return ret;
+	}
+
+	start = get_timer(0);
+	stop = chip->timeout_a;
+	do {
+		ret = tpm_tis_spi_check_locality(dev, loc);
+		if (!ret)
+			return 0;
+
+		if (ret != -ENOENT) {
+			log(LOGC_NONE, LOGL_ERR,
+			    "%s: Failed to get locality: %d\n", __func__, ret);
+			return ret;
+		}
+
+		mdelay(TPM_TIMEOUT_MS);
+	} while (get_timer(start) < stop);
+
+	log(LOGC_NONE, LOGL_ERR, "%s: Timeout getting locality: %d\n", __func__,
+	    ret);
+
+	return ret;
+}
+
+static u8 tpm_tis_spi_status(struct udevice *dev, u8 *status)
+{
+	struct tpm_chip *chip = dev_get_priv(dev);
+
+	return tpm_tis_spi_read(dev, TPM_STS(chip->locality), status, 1);
+}
+
+static int tpm_tis_spi_wait_for_stat(struct udevice *dev, u8 mask,
+				     unsigned long timeout, u8 *status)
+{
+	unsigned long start = get_timer(0);
+	unsigned long stop = timeout;
+	int ret;
+
+	do {
+		mdelay(TPM_TIMEOUT_MS);
+		ret = tpm_tis_spi_status(dev, status);
+		if (ret)
+			return ret;
+
+		if ((*status & mask) == mask)
+			return 0;
+	} while (get_timer(start) < stop);
+
+	return -ETIMEDOUT;
+}
+
+static int tpm_tis_spi_get_burstcount(struct udevice *dev)
+{
+	struct tpm_chip *chip = dev_get_priv(dev);
+	unsigned long start, stop;
+	u32 burstcount, ret;
+
+	/* wait for burstcount */
+	start = get_timer(0);
+	stop = chip->timeout_d;
+	do {
+		ret = tpm_tis_spi_read32(dev, TPM_STS(chip->locality),
+					 &burstcount);
+		if (ret)
+			return -EBUSY;
+
+		burstcount = (burstcount >> 8) & 0xFFFF;
+		if (burstcount)
+			return burstcount;
+
+		mdelay(TPM_TIMEOUT_MS);
+	} while (get_timer(start) < stop);
+
+	return -EBUSY;
+}
+
+static int tpm_tis_spi_cancel(struct udevice *dev)
+{
+	struct tpm_chip *chip = dev_get_priv(dev);
+	u8 data = TPM_STS_COMMAND_READY;
+
+	return tpm_tis_spi_write(dev, TPM_STS(chip->locality), &data, 1);
+}
+
+static int tpm_tis_spi_recv_data(struct udevice *dev, u8 *buf, size_t count)
+{
+	struct tpm_chip *chip = dev_get_priv(dev);
+	int size = 0, burstcnt, len, ret;
+	u8 status;
+
+	while (size < count &&
+	       tpm_tis_spi_wait_for_stat(dev,
+					 TPM_STS_DATA_AVAIL | TPM_STS_VALID,
+					 chip->timeout_c, &status) == 0) {
+		burstcnt = tpm_tis_spi_get_burstcount(dev);
+		if (burstcnt < 0)
+			return burstcnt;
+
+		len = min_t(int, burstcnt, count - size);
+		ret = tpm_tis_spi_read(dev, TPM_DATA_FIFO(chip->locality),
+				       buf + size, len);
+		if (ret < 0)
+			return ret;
+
+		size += len;
+	}
+
+	return size;
+}
+
+static int tpm_tis_spi_recv(struct udevice *dev, u8 *buf, size_t count)
+{
+	struct tpm_chip *chip = dev_get_priv(dev);
+	int size, expected;
+
+	if (!chip)
+		return -ENODEV;
+
+	if (count < TPM_HEADER_SIZE) {
+		size = -EIO;
+		goto out;
+	}
+
+	size = tpm_tis_spi_recv_data(dev, buf, TPM_HEADER_SIZE);
+	if (size < TPM_HEADER_SIZE) {
+		log(LOGC_NONE, LOGL_ERR, "TPM error, unable to read header\n");
+		goto out;
+	}
+
+	expected = get_unaligned_be32(buf + 2);
+	if (expected > count) {
+		size = -EIO;
+		goto out;
+	}
+
+	size += tpm_tis_spi_recv_data(dev, &buf[TPM_HEADER_SIZE],
+				   expected - TPM_HEADER_SIZE);
+	if (size < expected) {
+		log(LOGC_NONE, LOGL_ERR,
+		    "TPM error, unable to read remaining bytes of result\n");
+		size = -EIO;
+		goto out;
+	}
+
+out:
+	tpm_tis_spi_cancel(dev);
+	tpm_tis_spi_release_locality(dev, chip->locality, false);
+
+	return size;
+}
+
+static int tpm_tis_spi_send(struct udevice *dev, const u8 *buf, size_t len)
+{
+	struct tpm_chip *chip = dev_get_priv(dev);
+	u32 i, size;
+	u8 status;
+	int burstcnt, ret;
+	u8 data;
+
+	if (!chip)
+		return -ENODEV;
+
+	if (len > TPM_DEV_BUFSIZE)
+		return -E2BIG;  /* Command is too long for our tpm, sorry */
+
+	ret = tpm_tis_spi_request_locality(dev, 0);
+	if (ret < 0)
+		return -EBUSY;
+
+	/*
+	 * Check if the TPM is ready. If not, if not, cancel the pending command
+	 * and poll on the status to be finally ready.
+	 */
+	ret = tpm_tis_spi_status(dev, &status);
+	if (ret)
+		return ret;
+
+	if (!(status & TPM_STS_COMMAND_READY)) {
+		/* Force the transition, usually this will be done at startup */
+		ret = tpm_tis_spi_cancel(dev);
+		if (ret) {
+			log(LOGC_NONE, LOGL_ERR,
+			    "%s: Could not cancel previous operation\n",
+			    __func__);
+			goto out_err;
+		}
+
+		ret = tpm_tis_spi_wait_for_stat(dev, TPM_STS_COMMAND_READY,
+						chip->timeout_b, &status);
+		if (ret < 0 || !(status & TPM_STS_COMMAND_READY)) {
+			log(LOGC_NONE, LOGL_ERR,
+			    "status %d after wait for stat returned %d\n",
+			    status, ret);
+			goto out_err;
+		}
+	}
+
+	for (i = 0; i < len - 1;) {
+		burstcnt = tpm_tis_spi_get_burstcount(dev);
+		if (burstcnt < 0)
+			return burstcnt;
+
+		size = min_t(int, len - i - 1, burstcnt);
+		ret = tpm_tis_spi_write(dev, TPM_DATA_FIFO(chip->locality),
+					buf + i, size);
+		if (ret < 0)
+			goto out_err;
+
+		i += size;
+	}
+
+	ret = tpm_tis_spi_status(dev, &status);
+	if (ret)
+		goto out_err;
+
+	if ((status & TPM_STS_DATA_EXPECT) == 0) {
+		ret = -EIO;
+		goto out_err;
+	}
+
+	ret = tpm_tis_spi_write(dev, TPM_DATA_FIFO(chip->locality),
+				buf + len - 1, 1);
+	if (ret)
+		goto out_err;
+
+	ret = tpm_tis_spi_status(dev, &status);
+	if (ret)
+		goto out_err;
+
+	if ((status & TPM_STS_DATA_EXPECT) != 0) {
+		ret = -EIO;
+		goto out_err;
+	}
+
+	data = TPM_STS_GO;
+	ret = tpm_tis_spi_write(dev, TPM_STS(chip->locality), &data, 1);
+	if (ret)
+		goto out_err;
+
+	return len;
+
+out_err:
+	tpm_tis_spi_cancel(dev);
+	tpm_tis_spi_release_locality(dev, chip->locality, false);
+
+	return ret;
+}
+
+static int tpm_tis_spi_cleanup(struct udevice *dev)
+{
+	struct tpm_chip *chip = dev_get_priv(dev);
+
+	tpm_tis_spi_cancel(dev);
+	/*
+	 * The TPM needs some time to clean up here,
+	 * so we sleep rather than keeping the bus busy
+	 */
+	mdelay(2);
+	tpm_tis_spi_release_locality(dev, chip->locality, false);
+
+	return 0;
+}
+
+static int tpm_tis_spi_open(struct udevice *dev)
+{
+	struct tpm_chip *chip = dev_get_priv(dev);
+
+	if (chip->is_open)
+		return -EBUSY;
+
+	chip->is_open = 1;
+
+	return 0;
+}
+
+static int tpm_tis_spi_close(struct udevice *dev)
+{
+	struct tpm_chip *chip = dev_get_priv(dev);
+
+	if (chip->is_open) {
+		tpm_tis_spi_release_locality(dev, chip->locality, true);
+		chip->is_open = 0;
+	}
+
+	return 0;
+}
+
+static int tpm_tis_get_desc(struct udevice *dev, char *buf, int size)
+{
+	struct tpm_chip *chip = dev_get_priv(dev);
+
+	if (size < 80)
+		return -ENOSPC;
+
+	return snprintf(buf, size,
+			"%s v2.0: VendorID 0x%04x, DeviceID 0x%04x, RevisionID 0x%02x [%s]",
+			dev->name, chip->vend_dev & 0xFFFF,
+			chip->vend_dev >> 16, chip->rid,
+			(chip->is_open ? "open" : "closed"));
+}
+
+static int tpm_tis_wait_init(struct udevice *dev, int loc)
+{
+	struct tpm_chip *chip = dev_get_priv(dev);
+	unsigned long start, stop;
+	u8 status;
+	int ret;
+
+	start = get_timer(0);
+	stop = chip->timeout_b;
+	do {
+		mdelay(TPM_TIMEOUT_MS);
+
+		ret = tpm_tis_spi_read(dev, TPM_ACCESS(loc), &status, 1);
+		if (ret)
+			break;
+
+		if (status & TPM_ACCESS_VALID)
+			return 0;
+	} while (get_timer(start) < stop);
+
+	return -EIO;
+}
+
+static int tpm_tis_spi_probe(struct udevice *dev)
+{
+	struct tpm_tis_chip_data *drv_data = (void *)dev_get_driver_data(dev);
+	struct tpm_chip_priv *priv = dev_get_uclass_priv(dev);
+	struct tpm_chip *chip = dev_get_priv(dev);
+	int ret;
+
+	if (IS_ENABLED(CONFIG_DM_GPIO)) {
+		struct gpio_desc reset_gpio;
+
+		ret = gpio_request_by_name(dev, "gpio-reset", 0,
+					   &reset_gpio, GPIOD_IS_OUT);
+		if (ret) {
+			log(LOGC_NONE, LOGL_NOTICE, "%s: missing reset GPIO\n",
+			    __func__);
+		} else {
+			dm_gpio_set_value(&reset_gpio, 0);
+			mdelay(1);
+			dm_gpio_set_value(&reset_gpio, 1);
+		}
+	}
+
+	/* Ensure a minimum amount of time elapsed since reset of the TPM */
+	mdelay(drv_data->time_before_first_cmd_ms);
+
+	chip->locality = 0;
+	chip->timeout_a = TIS_SHORT_TIMEOUT_MS;
+	chip->timeout_b = TIS_LONG_TIMEOUT_MS;
+	chip->timeout_c = TIS_SHORT_TIMEOUT_MS;
+	chip->timeout_d = TIS_SHORT_TIMEOUT_MS;
+	priv->pcr_count = drv_data->pcr_count;
+	priv->pcr_select_min = drv_data->pcr_select_min;
+
+	ret = tpm_tis_wait_init(dev, chip->locality);
+	if (ret) {
+		log(LOGC_DM, LOGL_ERR, "%s: no device found\n", __func__);
+		return ret;
+	}
+
+	ret = tpm_tis_spi_request_locality(dev, chip->locality);
+	if (ret) {
+		log(LOGC_NONE, LOGL_ERR, "%s: could not request locality %d\n",
+		    __func__, chip->locality);
+		return ret;
+	}
+
+	ret = tpm_tis_spi_read32(dev, TPM_DID_VID(chip->locality),
+				 &chip->vend_dev);
+	if (ret) {
+		log(LOGC_NONE, LOGL_ERR,
+		    "%s: could not retrieve VendorID/DeviceID\n", __func__);
+		return ret;
+	}
+
+	ret = tpm_tis_spi_read(dev, TPM_RID(chip->locality), &chip->rid, 1);
+	if (ret) {
+		log(LOGC_NONE, LOGL_ERR, "%s: could not retrieve RevisionID\n",
+		    __func__);
+		return ret;
+	}
+
+	log(LOGC_NONE, LOGL_ERR,
+	    "SPI TPMv2.0 found (vid:%04x, did:%04x, rid:%02x)\n",
+	    chip->vend_dev & 0xFFFF, chip->vend_dev >> 16, chip->rid);
+
+	return 0;
+}
+
+static int tpm_tis_spi_remove(struct udevice *dev)
+{
+	struct tpm_chip *chip = dev_get_priv(dev);
+
+	tpm_tis_spi_release_locality(dev, chip->locality, true);
+
+	return 0;
+}
+
+static const struct tpm_ops tpm_tis_spi_ops = {
+	.open		= tpm_tis_spi_open,
+	.close		= tpm_tis_spi_close,
+	.get_desc	= tpm_tis_get_desc,
+	.send		= tpm_tis_spi_send,
+	.recv		= tpm_tis_spi_recv,
+	.cleanup	= tpm_tis_spi_cleanup,
+};
+
+static const struct tpm_tis_chip_data tpm_tis_std_chip_data = {
+	.pcr_count = 24,
+	.pcr_select_min = 3,
+	.time_before_first_cmd_ms = 30,
+};
+
+static const struct udevice_id tpm_tis_spi_ids[] = {
+	{
+		.compatible = "tis,tpm2-spi",
+		.data = (ulong)&tpm_tis_std_chip_data,
+	},
+	{ }
+};
+
+U_BOOT_DRIVER(tpm_tis_spi) = {
+	.name   = "tpm_tis_spi",
+	.id     = UCLASS_TPM,
+	.of_match = tpm_tis_spi_ids,
+	.ops    = &tpm_tis_spi_ops,
+	.probe	= tpm_tis_spi_probe,
+	.remove	= tpm_tis_spi_remove,
+	.priv_auto_alloc_size = sizeof(struct tpm_chip),
+};
diff --git a/drivers/tpm/tpm_atmel_twi.c b/drivers/tpm/tpm_atmel_twi.c
index 8547580..2079ea9 100644
--- a/drivers/tpm/tpm_atmel_twi.c
+++ b/drivers/tpm/tpm_atmel_twi.c
@@ -7,7 +7,7 @@
 
 #include <common.h>
 #include <dm.h>
-#include <tpm.h>
+#include <tpm-v1.h>
 #include <i2c.h>
 #include <asm/unaligned.h>
 
diff --git a/drivers/tpm/tpm_tis.h b/drivers/tpm/tpm_tis.h
index a899bc0..947585f 100644
--- a/drivers/tpm/tpm_tis.h
+++ b/drivers/tpm/tpm_tis.h
@@ -40,6 +40,7 @@
 	int is_open;
 	int locality;
 	u32 vend_dev;
+	u8 rid;
 	unsigned long timeout_a, timeout_b, timeout_c, timeout_d;  /* msec */
 	ulong chip_type;
 };
diff --git a/drivers/tpm/tpm_tis_infineon.c b/drivers/tpm/tpm_tis_infineon.c
index 9b2a025..b5fe43e 100644
--- a/drivers/tpm/tpm_tis_infineon.c
+++ b/drivers/tpm/tpm_tis_infineon.c
@@ -23,7 +23,7 @@
 #include <dm.h>
 #include <fdtdec.h>
 #include <i2c.h>
-#include <tpm.h>
+#include <tpm-v1.h>
 #include <linux/errno.h>
 #include <linux/compiler.h>
 #include <linux/types.h>
diff --git a/drivers/tpm/tpm_tis_lpc.c b/drivers/tpm/tpm_tis_lpc.c
index 5729263..7664bb1 100644
--- a/drivers/tpm/tpm_tis_lpc.c
+++ b/drivers/tpm/tpm_tis_lpc.c
@@ -15,7 +15,7 @@
 #include <common.h>
 #include <dm.h>
 #include <mapmem.h>
-#include <tpm.h>
+#include <tpm-v1.h>
 #include <asm/io.h>
 
 #define PREFIX "lpc_tpm: "
diff --git a/drivers/tpm/tpm_tis_sandbox.c b/drivers/tpm/tpm_tis_sandbox.c
index 4415754..8816d55 100644
--- a/drivers/tpm/tpm_tis_sandbox.c
+++ b/drivers/tpm/tpm_tis_sandbox.c
@@ -5,7 +5,7 @@
 
 #include <common.h>
 #include <dm.h>
-#include <tpm.h>
+#include <tpm-v1.h>
 #include <asm/state.h>
 #include <asm/unaligned.h>
 #include <linux/crc8.h>
diff --git a/drivers/tpm/tpm_tis_st33zp24_i2c.c b/drivers/tpm/tpm_tis_st33zp24_i2c.c
index 9cf302c..0d38037 100644
--- a/drivers/tpm/tpm_tis_st33zp24_i2c.c
+++ b/drivers/tpm/tpm_tis_st33zp24_i2c.c
@@ -16,7 +16,7 @@
 #include <dm.h>
 #include <fdtdec.h>
 #include <i2c.h>
-#include <tpm.h>
+#include <tpm-v1.h>
 #include <errno.h>
 #include <linux/types.h>
 #include <asm/unaligned.h>
diff --git a/drivers/tpm/tpm_tis_st33zp24_spi.c b/drivers/tpm/tpm_tis_st33zp24_spi.c
index d5fde11..f6087e7 100644
--- a/drivers/tpm/tpm_tis_st33zp24_spi.c
+++ b/drivers/tpm/tpm_tis_st33zp24_spi.c
@@ -16,7 +16,7 @@
 #include <dm.h>
 #include <fdtdec.h>
 #include <spi.h>
-#include <tpm.h>
+#include <tpm-v1.h>
 #include <errno.h>
 #include <linux/types.h>
 #include <asm/unaligned.h>
diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
index 3acadae..3ad4346 100644
--- a/drivers/usb/gadget/f_fastboot.c
+++ b/drivers/usb/gadget/f_fastboot.c
@@ -18,16 +18,7 @@
 #include <linux/usb/gadget.h>
 #include <linux/usb/composite.h>
 #include <linux/compiler.h>
-#include <version.h>
 #include <g_dnl.h>
-#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
-#include <fb_mmc.h>
-#endif
-#ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV
-#include <fb_nand.h>
-#endif
-
-#define FASTBOOT_VERSION		"0.4"
 
 #define FASTBOOT_INTERFACE_CLASS	0xff
 #define FASTBOOT_INTERFACE_SUB_CLASS	0x42
@@ -58,8 +49,6 @@
 }
 
 static struct f_fastboot *fastboot_func;
-static unsigned int download_size;
-static unsigned int download_bytes;
 
 static struct usb_endpoint_descriptor fs_ep_in = {
 	.bLength            = USB_DT_ENDPOINT_SIZE,
@@ -147,22 +136,6 @@
 };
 
 static void rx_handler_command(struct usb_ep *ep, struct usb_request *req);
-static int strcmp_l1(const char *s1, const char *s2);
-
-
-static char *fb_response_str;
-
-void fastboot_fail(const char *reason)
-{
-	strncpy(fb_response_str, "FAIL\0", 5);
-	strncat(fb_response_str, reason, FASTBOOT_RESPONSE_LEN - 4 - 1);
-}
-
-void fastboot_okay(const char *reason)
-{
-	strncpy(fb_response_str, "OKAY\0", 5);
-	strncat(fb_response_str, reason, FASTBOOT_RESPONSE_LEN - 4 - 1);
-}
 
 static void fastboot_complete(struct usb_ep *ep, struct usb_request *req)
 {
@@ -372,90 +345,9 @@
 	do_reset(NULL, 0, 0, NULL);
 }
 
-int __weak fb_set_reboot_flag(void)
-{
-	return -ENOSYS;
-}
-
-static void cb_reboot(struct usb_ep *ep, struct usb_request *req)
-{
-	char *cmd = req->buf;
-	if (!strcmp_l1("reboot-bootloader", cmd)) {
-		if (fb_set_reboot_flag()) {
-			fastboot_tx_write_str("FAILCannot set reboot flag");
-			return;
-		}
-	}
-	fastboot_func->in_req->complete = compl_do_reset;
-	fastboot_tx_write_str("OKAY");
-}
-
-static int strcmp_l1(const char *s1, const char *s2)
-{
-	if (!s1 || !s2)
-		return -1;
-	return strncmp(s1, s2, strlen(s1));
-}
-
-static void cb_getvar(struct usb_ep *ep, struct usb_request *req)
-{
-	char *cmd = req->buf;
-	char response[FASTBOOT_RESPONSE_LEN];
-	const char *s;
-	size_t chars_left;
-
-	strcpy(response, "OKAY");
-	chars_left = sizeof(response) - strlen(response) - 1;
-
-	strsep(&cmd, ":");
-	if (!cmd) {
-		pr_err("missing variable");
-		fastboot_tx_write_str("FAILmissing var");
-		return;
-	}
-
-	if (!strcmp_l1("version", cmd)) {
-		strncat(response, FASTBOOT_VERSION, chars_left);
-	} else if (!strcmp_l1("bootloader-version", cmd)) {
-		strncat(response, U_BOOT_VERSION, chars_left);
-	} else if (!strcmp_l1("downloadsize", cmd) ||
-		!strcmp_l1("max-download-size", cmd)) {
-		char str_num[12];
-
-		sprintf(str_num, "0x%08x", CONFIG_FASTBOOT_BUF_SIZE);
-		strncat(response, str_num, chars_left);
-	} else if (!strcmp_l1("serialno", cmd)) {
-		s = env_get("serial#");
-		if (s)
-			strncat(response, s, chars_left);
-		else
-			strcpy(response, "FAILValue not set");
-	} else {
-		char *envstr;
-
-		envstr = malloc(strlen("fastboot.") + strlen(cmd) + 1);
-		if (!envstr) {
-			fastboot_tx_write_str("FAILmalloc error");
-			return;
-		}
-
-		sprintf(envstr, "fastboot.%s", cmd);
-		s = env_get(envstr);
-		if (s) {
-			strncat(response, s, chars_left);
-		} else {
-			printf("WARNING: unknown variable: %s\n", cmd);
-			strcpy(response, "FAILVariable not implemented");
-		}
-
-		free(envstr);
-	}
-	fastboot_tx_write_str(response);
-}
-
 static unsigned int rx_bytes_expected(struct usb_ep *ep)
 {
-	int rx_remain = download_size - download_bytes;
+	int rx_remain = fastboot_data_remaining();
 	unsigned int rem;
 	unsigned int maxpacket = ep->maxpacket;
 
@@ -477,14 +369,12 @@
 	return rx_remain;
 }
 
-#define BYTES_PER_DOT	0x20000
 static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request *req)
 {
-	char response[FASTBOOT_RESPONSE_LEN];
-	unsigned int transfer_size = download_size - download_bytes;
+	char response[FASTBOOT_RESPONSE_LEN] = {0};
+	unsigned int transfer_size = fastboot_data_remaining();
 	const unsigned char *buffer = req->buf;
 	unsigned int buffer_size = req->actual;
-	unsigned int pre_dot_num, now_dot_num;
 
 	if (req->status != 0) {
 		printf("Bad status: %d\n", req->status);
@@ -494,33 +384,19 @@
 	if (buffer_size < transfer_size)
 		transfer_size = buffer_size;
 
-	memcpy((void *)CONFIG_FASTBOOT_BUF_ADDR + download_bytes,
-	       buffer, transfer_size);
+	fastboot_data_download(buffer, transfer_size, response);
+	if (response[0]) {
+		fastboot_tx_write_str(response);
+	} else if (!fastboot_data_remaining()) {
+		fastboot_data_complete(response);
 
-	pre_dot_num = download_bytes / BYTES_PER_DOT;
-	download_bytes += transfer_size;
-	now_dot_num = download_bytes / BYTES_PER_DOT;
-
-	if (pre_dot_num != now_dot_num) {
-		putc('.');
-		if (!(now_dot_num % 74))
-			putc('\n');
-	}
-
-	/* Check if transfer is done */
-	if (download_bytes >= download_size) {
 		/*
-		 * Reset global transfer variable, keep download_bytes because
-		 * it will be used in the next possible flashing command
+		 * Reset global transfer variable
 		 */
-		download_size = 0;
 		req->complete = rx_handler_command;
 		req->length = EP_BUFFER_SIZE;
 
-		strcpy(response, "OKAY");
 		fastboot_tx_write_str(response);
-
-		printf("\ndownloading of %d bytes finished\n", download_bytes);
 	} else {
 		req->length = rx_bytes_expected(ep);
 	}
@@ -529,204 +405,55 @@
 	usb_ep_queue(ep, req, 0);
 }
 
-static void cb_download(struct usb_ep *ep, struct usb_request *req)
-{
-	char *cmd = req->buf;
-	char response[FASTBOOT_RESPONSE_LEN];
-
-	strsep(&cmd, ":");
-	download_size = simple_strtoul(cmd, NULL, 16);
-	download_bytes = 0;
-
-	printf("Starting download of %d bytes\n", download_size);
-
-	if (0 == download_size) {
-		strcpy(response, "FAILdata invalid size");
-	} else if (download_size > CONFIG_FASTBOOT_BUF_SIZE) {
-		download_size = 0;
-		strcpy(response, "FAILdata too large");
-	} else {
-		sprintf(response, "DATA%08x", download_size);
-		req->complete = rx_handler_dl_image;
-		req->length = rx_bytes_expected(ep);
-	}
-	fastboot_tx_write_str(response);
-}
-
-static void do_bootm_on_complete(struct usb_ep *ep, struct usb_request *req)
-{
-	char boot_addr_start[12];
-	char *bootm_args[] = { "bootm", boot_addr_start, NULL };
-
-	puts("Booting kernel..\n");
-
-	sprintf(boot_addr_start, "0x%lx", (long)CONFIG_FASTBOOT_BUF_ADDR);
-	do_bootm(NULL, 0, 2, bootm_args);
-
-	/* This only happens if image is somehow faulty so we start over */
-	do_reset(NULL, 0, 0, NULL);
-}
-
-static void cb_boot(struct usb_ep *ep, struct usb_request *req)
-{
-	fastboot_func->in_req->complete = do_bootm_on_complete;
-	fastboot_tx_write_str("OKAY");
-}
-
 static void do_exit_on_complete(struct usb_ep *ep, struct usb_request *req)
 {
 	g_dnl_trigger_detach();
 }
 
-static void cb_continue(struct usb_ep *ep, struct usb_request *req)
+static void do_bootm_on_complete(struct usb_ep *ep, struct usb_request *req)
 {
-	fastboot_func->in_req->complete = do_exit_on_complete;
-	fastboot_tx_write_str("OKAY");
+	fastboot_boot();
+	do_exit_on_complete(ep, req);
 }
 
-#ifdef CONFIG_FASTBOOT_FLASH
-static void cb_flash(struct usb_ep *ep, struct usb_request *req)
-{
-	char *cmd = req->buf;
-	char response[FASTBOOT_RESPONSE_LEN];
-
-	strsep(&cmd, ":");
-	if (!cmd) {
-		pr_err("missing partition name");
-		fastboot_tx_write_str("FAILmissing partition name");
-		return;
-	}
-
-	/* initialize the response buffer */
-	fb_response_str = response;
-
-	fastboot_fail("no flash device defined");
-#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
-	fb_mmc_flash_write(cmd, (void *)CONFIG_FASTBOOT_BUF_ADDR,
-			   download_bytes);
-#endif
-#ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV
-	fb_nand_flash_write(cmd,
-			    (void *)CONFIG_FASTBOOT_BUF_ADDR,
-			    download_bytes);
-#endif
-	fastboot_tx_write_str(response);
-}
-#endif
-
-static void cb_oem(struct usb_ep *ep, struct usb_request *req)
-{
-	char *cmd = req->buf;
-#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
-	if (strncmp("format", cmd + 4, 6) == 0) {
-		char cmdbuf[32];
-                sprintf(cmdbuf, "gpt write mmc %x $partitions",
-			CONFIG_FASTBOOT_FLASH_MMC_DEV);
-                if (run_command(cmdbuf, 0))
-			fastboot_tx_write_str("FAIL");
-                else
-			fastboot_tx_write_str("OKAY");
-	} else
-#endif
-	if (strncmp("unlock", cmd + 4, 8) == 0) {
-		fastboot_tx_write_str("FAILnot implemented");
-	}
-	else {
-		fastboot_tx_write_str("FAILunknown oem command");
-	}
-}
-
-#ifdef CONFIG_FASTBOOT_FLASH
-static void cb_erase(struct usb_ep *ep, struct usb_request *req)
-{
-	char *cmd = req->buf;
-	char response[FASTBOOT_RESPONSE_LEN];
-
-	strsep(&cmd, ":");
-	if (!cmd) {
-		pr_err("missing partition name");
-		fastboot_tx_write_str("FAILmissing partition name");
-		return;
-	}
-
-	/* initialize the response buffer */
-	fb_response_str = response;
-
-	fastboot_fail("no flash device defined");
-#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
-	fb_mmc_erase(cmd);
-#endif
-#ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV
-	fb_nand_erase(cmd);
-#endif
-	fastboot_tx_write_str(response);
-}
-#endif
-
-struct cmd_dispatch_info {
-	char *cmd;
-	void (*cb)(struct usb_ep *ep, struct usb_request *req);
-};
-
-static const struct cmd_dispatch_info cmd_dispatch_info[] = {
-	{
-		.cmd = "reboot",
-		.cb = cb_reboot,
-	}, {
-		.cmd = "getvar:",
-		.cb = cb_getvar,
-	}, {
-		.cmd = "download:",
-		.cb = cb_download,
-	}, {
-		.cmd = "boot",
-		.cb = cb_boot,
-	}, {
-		.cmd = "continue",
-		.cb = cb_continue,
-	},
-#ifdef CONFIG_FASTBOOT_FLASH
-	{
-		.cmd = "flash",
-		.cb = cb_flash,
-	}, {
-		.cmd = "erase",
-		.cb = cb_erase,
-	},
-#endif
-	{
-		.cmd = "oem",
-		.cb = cb_oem,
-	},
-};
-
 static void rx_handler_command(struct usb_ep *ep, struct usb_request *req)
 {
 	char *cmdbuf = req->buf;
-	void (*func_cb)(struct usb_ep *ep, struct usb_request *req) = NULL;
-	int i;
+	char response[FASTBOOT_RESPONSE_LEN] = {0};
+	int cmd = -1;
 
 	if (req->status != 0 || req->length == 0)
 		return;
 
-	for (i = 0; i < ARRAY_SIZE(cmd_dispatch_info); i++) {
-		if (!strcmp_l1(cmd_dispatch_info[i].cmd, cmdbuf)) {
-			func_cb = cmd_dispatch_info[i].cb;
-			break;
-		}
+	if (req->actual < req->length) {
+		cmdbuf[req->actual] = '\0';
+		cmd = fastboot_handle_command(cmdbuf, response);
+	} else {
+		pr_err("buffer overflow");
+		fastboot_fail("buffer overflow", response);
 	}
 
-	if (!func_cb) {
-		pr_err("unknown command: %.*s", req->actual, cmdbuf);
-		fastboot_tx_write_str("FAILunknown command");
-	} else {
-		if (req->actual < req->length) {
-			u8 *buf = (u8 *)req->buf;
-			buf[req->actual] = 0;
-			func_cb(ep, req);
-		} else {
-			pr_err("buffer overflow");
-			fastboot_tx_write_str("FAILbuffer overflow");
+	if (!strncmp("DATA", response, 4)) {
+		req->complete = rx_handler_dl_image;
+		req->length = rx_bytes_expected(ep);
+	}
+
+	fastboot_tx_write_str(response);
+
+	if (!strncmp("OKAY", response, 4)) {
+		switch (cmd) {
+		case FASTBOOT_COMMAND_BOOT:
+			fastboot_func->in_req->complete = do_bootm_on_complete;
+			break;
+
+		case FASTBOOT_COMMAND_CONTINUE:
+			fastboot_func->in_req->complete = do_exit_on_complete;
+			break;
+
+		case FASTBOOT_COMMAND_REBOOT:
+		case FASTBOOT_COMMAND_REBOOT_BOOTLOADER:
+			fastboot_func->in_req->complete = compl_do_reset;
+			break;
 		}
 	}
 
diff --git a/drivers/usb/gadget/f_thor.c b/drivers/usb/gadget/f_thor.c
index c8eda05..1aa6be4 100644
--- a/drivers/usb/gadget/f_thor.c
+++ b/drivers/usb/gadget/f_thor.c
@@ -620,22 +620,6 @@
 	      status, req->actual, req->length);
 }
 
-static struct usb_request *thor_start_ep(struct usb_ep *ep)
-{
-	struct usb_request *req;
-
-	req = alloc_ep_req(ep, THOR_PACKET_SIZE);
-	debug("%s: ep:%p req:%p\n", __func__, ep, req);
-
-	if (!req)
-		return NULL;
-
-	memset(req->buf, 0, req->length);
-	req->complete = thor_rx_tx_complete;
-
-	return req;
-}
-
 static void thor_setup_complete(struct usb_ep *ep, struct usb_request *req)
 {
 	if (req->status || req->actual != req->length)
@@ -752,6 +736,13 @@
 	return 0;
 }
 
+static void free_ep_req(struct usb_ep *ep, struct usb_request *req)
+{
+	if (req->buf)
+		free(req->buf);
+	usb_ep_free_request(ep, req);
+}
+
 static int thor_func_bind(struct usb_configuration *c, struct usb_function *f)
 {
 	struct usb_gadget *gadget = c->cdev->gadget;
@@ -860,21 +851,18 @@
 	return 0;
 
  fail:
+	if (dev->req)
+		free_ep_req(gadget->ep0, dev->req);
 	free(dev);
 	return status;
 }
 
-static void free_ep_req(struct usb_ep *ep, struct usb_request *req)
-{
-	free(req->buf);
-	usb_ep_free_request(ep, req);
-}
-
 static void thor_unbind(struct usb_configuration *c, struct usb_function *f)
 {
 	struct f_thor *f_thor = func_to_thor(f);
 	struct thor_dev *dev = f_thor->dev;
 
+	free_ep_req(dev->gadget->ep0, dev->req);
 	free(dev);
 	memset(thor_func, 0, sizeof(*thor_func));
 	thor_func = NULL;
@@ -895,8 +883,6 @@
 	}
 
 	if (dev->out_ep->driver_data) {
-		free(dev->out_req->buf);
-		dev->out_req->buf = NULL;
 		usb_ep_free_request(dev->out_ep, dev->out_req);
 		usb_ep_disable(dev->out_ep);
 		dev->out_ep->driver_data = NULL;
@@ -924,16 +910,17 @@
 
 	result = usb_ep_enable(ep, d);
 	if (result)
-		goto exit;
+		goto err;
 
 	ep->driver_data = cdev; /* claim */
-	req = thor_start_ep(ep);
+	req = alloc_ep_req(ep, THOR_PACKET_SIZE);
 	if (!req) {
-		usb_ep_disable(ep);
 		result = -EIO;
-		goto exit;
+		goto err_disable_in_ep;
 	}
 
+	memset(req->buf, 0, req->length);
+	req->complete = thor_rx_tx_complete;
 	dev->in_req = req;
 	ep = dev->out_ep;
 	d = ep_desc(gadget, &hs_out_desc, &fs_out_desc);
@@ -941,22 +928,34 @@
 
 	result = usb_ep_enable(ep, d);
 	if (result)
-		goto exit;
+		goto err_free_in_req;
 
 	ep->driver_data = cdev; /* claim */
-	req = thor_start_ep(ep);
+	req = usb_ep_alloc_request(ep, 0);
 	if (!req) {
-		usb_ep_disable(ep);
 		result = -EIO;
-		goto exit;
+		goto err_disable_out_ep;
 	}
 
+	req->complete = thor_rx_tx_complete;
 	dev->out_req = req;
 	/* ACM control EP */
 	ep = dev->int_ep;
 	ep->driver_data = cdev;	/* claim */
 
- exit:
+	return 0;
+
+ err_disable_out_ep:
+	usb_ep_disable(dev->out_ep);
+
+ err_free_in_req:
+	free_ep_req(dev->in_ep, dev->in_req);
+	dev->in_req = NULL;
+
+ err_disable_in_ep:
+	usb_ep_disable(dev->in_ep);
+
+ err:
 	return result;
 }
 
diff --git a/drivers/usb/host/xhci-rcar.c b/drivers/usb/host/xhci-rcar.c
index a837afc..f2e91ef 100644
--- a/drivers/usb/host/xhci-rcar.c
+++ b/drivers/usb/host/xhci-rcar.c
@@ -117,12 +117,15 @@
 
 static int xhci_rcar_deregister(struct udevice *dev)
 {
+	int ret;
 	struct rcar_xhci_platdata *plat = dev_get_platdata(dev);
 
+	ret = xhci_deregister(dev);
+
 	clk_disable(&plat->clk);
 	clk_free(&plat->clk);
 
-	return xhci_deregister(dev);
+	return ret;
 }
 
 static int xhci_rcar_ofdata_to_platdata(struct udevice *dev)
diff --git a/drivers/usb/host/xhci-rockchip.c b/drivers/usb/host/xhci-rockchip.c
index 060a6c4..f19bea3 100644
--- a/drivers/usb/host/xhci-rockchip.c
+++ b/drivers/usb/host/xhci-rockchip.c
@@ -17,7 +17,6 @@
 
 struct rockchip_xhci_platdata {
 	fdt_addr_t hcd_base;
-	fdt_addr_t phy_base;
 	struct udevice *vbus_supply;
 };
 
@@ -35,7 +34,6 @@
 static int xhci_usb_ofdata_to_platdata(struct udevice *dev)
 {
 	struct rockchip_xhci_platdata *plat = dev_get_platdata(dev);
-	struct udevice *child;
 	int ret = 0;
 
 	/*
@@ -47,20 +45,6 @@
 		return -ENXIO;
 	}
 
-	/* Get the base address for usbphy from the device node */
-	for (device_find_first_child(dev, &child); child;
-	     device_find_next_child(&child)) {
-		if (!device_is_compatible(child, "rockchip,rk3399-usb3-phy"))
-			continue;
-		plat->phy_base = devfdt_get_addr(child);
-		break;
-	}
-
-	if (plat->phy_base == FDT_ADDR_T_NONE) {
-		pr_err("Can't get the usbphy register address\n");
-		return -ENXIO;
-	}
-
 	/* Vbus regulator */
 	ret = device_get_supply_regulator(dev, "vbus-supply",
 					  &plat->vbus_supply);
diff --git a/drivers/usb/host/xhci-zynqmp.c b/drivers/usb/host/xhci-zynqmp.c
index 7fe5428..e44e1ae 100644
--- a/drivers/usb/host/xhci-zynqmp.c
+++ b/drivers/usb/host/xhci-zynqmp.c
@@ -13,7 +13,7 @@
 #include <dm.h>
 #include <usb.h>
 #include <linux/errno.h>
-#include <asm/arch-zynqmp/hardware.h>
+#include <asm/arch/hardware.h>
 #include <linux/compat.h>
 #include <linux/usb/dwc3.h>
 #include "xhci.h"
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 3adb002..9ded14c 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -536,7 +536,7 @@
 	/* slot context */
 	xhci_slot_copy(ctrl, in_ctx, out_ctx);
 	slot_ctx = xhci_get_slot_ctx(ctrl, in_ctx);
-	slot_ctx->dev_info &= ~(LAST_CTX_MASK);
+	slot_ctx->dev_info &= ~(cpu_to_le32(LAST_CTX_MASK));
 	slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(max_ep_flag + 1) | 0);
 
 	xhci_endpoint_copy(ctrl, in_ctx, out_ctx, 0);
@@ -1424,7 +1424,7 @@
 
 	ctrl_ctx = xhci_get_input_control_ctx(in_ctx);
 	/* Initialize the input context control */
-	ctrl_ctx->add_flags |= cpu_to_le32(SLOT_FLAG);
+	ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG);
 	ctrl_ctx->drop_flags = 0;
 
 	xhci_inval_cache((uintptr_t)out_ctx->bytes, out_ctx->size);
@@ -1435,8 +1435,15 @@
 
 	/* Update hub related fields */
 	slot_ctx->dev_info |= cpu_to_le32(DEV_HUB);
-	if (hub->tt.multi && udev->speed == USB_SPEED_HIGH)
+	/*
+	 * refer to section 6.2.2: MTT should be 0 for full speed hub,
+	 * but it may be already set to 1 when setup an xHCI virtual
+	 * device, so clear it anyway.
+	 */
+	if (hub->tt.multi)
 		slot_ctx->dev_info |= cpu_to_le32(DEV_MTT);
+	else if (udev->speed == USB_SPEED_FULL)
+		slot_ctx->dev_info &= cpu_to_le32(~DEV_MTT);
 	slot_ctx->dev_info2 |= cpu_to_le32(XHCI_MAX_PORTS(udev->maxchild));
 	/*
 	 * Set TT think time - convert from ns to FS bit times.
@@ -1452,6 +1459,7 @@
 		think_time = (think_time / 666) - 1;
 	if (udev->speed == USB_SPEED_HIGH)
 		slot_ctx->tt_info |= cpu_to_le32(TT_THINK_TIME(think_time));
+	slot_ctx->dev_state = 0;
 
 	return xhci_configure_endpoints(udev, false);
 }
diff --git a/drivers/video/sunxi/sunxi_de2.c b/drivers/video/sunxi/sunxi_de2.c
index a2303db..4ed035d 100644
--- a/drivers/video/sunxi/sunxi_de2.c
+++ b/drivers/video/sunxi/sunxi_de2.c
@@ -9,6 +9,7 @@
 #include <display.h>
 #include <dm.h>
 #include <edid.h>
+#include <efi_loader.h>
 #include <fdtdec.h>
 #include <fdt_support.h>
 #include <video.h>
@@ -221,6 +222,13 @@
 	uc_priv->bpix = l2bpp;
 	debug("fb=%lx, size=%d %d\n", fbbase, uc_priv->xsize, uc_priv->ysize);
 
+#ifdef CONFIG_EFI_LOADER
+	efi_add_memory_map(fbbase,
+			   ALIGN(timing.hactive.typ * timing.vactive.typ *
+			   (1 << l2bpp) / 8, EFI_PAGE_SIZE) >> EFI_PAGE_SHIFT,
+			   EFI_RESERVED_MEMORY_TYPE, false);
+#endif
+
 	return 0;
 }
 
diff --git a/drivers/watchdog/bcm6345_wdt.c b/drivers/watchdog/bcm6345_wdt.c
index 54b02fa..e1bd73d 100644
--- a/drivers/watchdog/bcm6345_wdt.c
+++ b/drivers/watchdog/bcm6345_wdt.c
@@ -85,15 +85,11 @@
 static int bcm6345_wdt_probe(struct udevice *dev)
 {
 	struct bcm6345_wdt_priv *priv = dev_get_priv(dev);
-	fdt_addr_t addr;
-	fdt_size_t size;
 
-	addr = devfdt_get_addr_size_index(dev, 0, &size);
-	if (addr == FDT_ADDR_T_NONE)
+	priv->regs = dev_remap_addr(dev);
+	if (!priv->regs)
 		return -EINVAL;
 
-	priv->regs = ioremap(addr, size);
-
 	bcm6345_wdt_stop(dev);
 
 	return 0;
diff --git a/drivers/watchdog/cdns_wdt.c b/drivers/watchdog/cdns_wdt.c
index 9a07fa1..f7618f8 100644
--- a/drivers/watchdog/cdns_wdt.c
+++ b/drivers/watchdog/cdns_wdt.c
@@ -231,17 +231,16 @@
 
 static int cdns_wdt_ofdata_to_platdata(struct udevice *dev)
 {
-	int node = dev_of_offset(dev);
 	struct cdns_wdt_priv *priv = dev_get_priv(dev);
 
-	priv->regs = devfdt_get_addr_ptr(dev);
+	priv->regs = (struct cdns_regs *)dev_read_addr(dev);
 	if (IS_ERR(priv->regs))
 		return PTR_ERR(priv->regs);
 
-	priv->timeout = fdtdec_get_int(gd->fdt_blob, node, "timeout-sec",
-				       CDNS_WDT_DEFAULT_TIMEOUT);
+	priv->timeout = dev_read_u32_default(dev, "timeout-sec",
+					     CDNS_WDT_DEFAULT_TIMEOUT);
 
-	priv->rst = fdtdec_get_bool(gd->fdt_blob, node, "reset-on-timeout");
+	priv->rst = dev_read_bool(dev, "reset-on-timeout");
 
 	debug("%s: timeout %d, reset %d\n", __func__, priv->timeout, priv->rst);
 
diff --git a/fs/fs.c b/fs/fs.c
index 94cdc37..33808d5 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -265,6 +265,19 @@
 	return info;
 }
 
+/**
+ * fs_get_type_name() - Get type of current filesystem
+ *
+ * Return: Pointer to filesystem name
+ *
+ * Returns a string describing the current filesystem, or the sentinel
+ * "unsupported" for any unrecognised filesystem.
+ */
+const char *fs_get_type_name(void)
+{
+	return fs_get_info(fs_type)->name;
+}
+
 int fs_set_blk_dev(const char *ifname, const char *dev_part_str, int fstype)
 {
 	struct fstype_info *info;
diff --git a/include/asm-generic/unaligned.h b/include/asm-generic/unaligned.h
index fd02550..3d33a5a 100644
--- a/include/asm-generic/unaligned.h
+++ b/include/asm-generic/unaligned.h
@@ -20,4 +20,7 @@
 #error invalid endian
 #endif
 
+/* Allow unaligned memory access */
+void allow_unaligned(void);
+
 #endif
diff --git a/include/bootm.h b/include/bootm.h
index 9e42e17..0501414 100644
--- a/include/bootm.h
+++ b/include/bootm.h
@@ -72,4 +72,12 @@
 		       void *load_buf, void *image_buf, ulong image_len,
 		       uint unc_len, ulong *load_end);
 
+/*
+ * boards should define this to disable devices when EFI exits from boot
+ * services.
+ *
+ * TODO(sjg@chromium.org>): Update this to use driver model's device_remove().
+ */
+void board_quiesce_devices(void);
+
 #endif
diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h
index 8d5feb3..d672e8e 100644
--- a/include/config_distro_bootcmd.h
+++ b/include/config_distro_bootcmd.h
@@ -99,6 +99,10 @@
 #define BOOTEFI_NAME "bootia32.efi"
 #elif defined(CONFIG_X86_RUN_64BIT)
 #define BOOTEFI_NAME "bootx64.efi"
+#elif defined(CONFIG_CPU_RISCV_32)
+#define BOOTEFI_NAME "bootriscv32.efi"
+#elif defined(CONFIG_CPU_RISCV_64)
+#define BOOTEFI_NAME "bootriscv64.efi"
 #endif
 #endif
 
@@ -240,6 +244,7 @@
 
 #if defined(CONFIG_CMD_DHCP)
 #if defined(CONFIG_EFI_LOADER)
+/* http://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xml */
 #if defined(CONFIG_ARM64)
 #define BOOTENV_EFI_PXE_ARCH "0xb"
 #define BOOTENV_EFI_PXE_VCI "PXEClient:Arch:00011:UNDI:003000"
@@ -250,6 +255,12 @@
 /* Always assume we're running 64bit */
 #define BOOTENV_EFI_PXE_ARCH "0x7"
 #define BOOTENV_EFI_PXE_VCI "PXEClient:Arch:00007:UNDI:003000"
+#elif defined(CONFIG_CPU_RISCV_32)
+#define BOOTENV_EFI_PXE_ARCH "0x19"
+#define BOOTENV_EFI_PXE_VCI "PXEClient:Arch:00025:UNDI:003000"
+#elif defined(CONFIG_CPU_RISCV_64)
+#define BOOTENV_EFI_PXE_ARCH "0x1b"
+#define BOOTENV_EFI_PXE_VCI "PXEClient:Arch:00027:UNDI:003000"
 #else
 #error Please specify an EFI client identifier
 #endif
diff --git a/include/configs/nx25-ae250.h b/include/configs/ax25-ae350.h
similarity index 62%
rename from include/configs/nx25-ae250.h
rename to include/configs/ax25-ae350.h
index 930cdbd..b1ca5ac 100644
--- a/include/configs/nx25-ae250.h
+++ b/include/configs/ax25-ae350.h
@@ -79,6 +79,44 @@
 #define CONFIG_SYS_MEMTEST_START	PHYS_SDRAM_0
 #define CONFIG_SYS_MEMTEST_END		(PHYS_SDRAM_0 + PHYS_SDRAM_0_SIZE)
 
+/*
+ * FLASH and environment organization
+ */
+
+/* use CFI framework */
+#define CONFIG_SYS_FLASH_CFI
+#define CONFIG_FLASH_CFI_DRIVER
+
+#define CONFIG_SYS_FLASH_CFI_WIDTH	FLASH_CFI_16BIT
+#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
+#define CONFIG_SYS_CFI_FLASH_STATUS_POLL
+
+/* support JEDEC */
+#ifdef CONFIG_CFI_FLASH
+#define CONFIG_SYS_MAX_FLASH_BANKS_DETECT	1
+#endif/* Do not use CONFIG_FLASH_CFI_LEGACY to detect on board flash */
+#define PHYS_FLASH_1			0x88000000	/* BANK 0 */
+#define CONFIG_SYS_FLASH_BASE		PHYS_FLASH_1
+#define CONFIG_SYS_FLASH_BANKS_LIST	{ PHYS_FLASH_1, }
+#define CONFIG_SYS_MONITOR_BASE		PHYS_FLASH_1
+
+#define CONFIG_SYS_FLASH_ERASE_TOUT	120000	/* TO for Flash Erase (ms) */
+#define CONFIG_SYS_FLASH_WRITE_TOUT	500	/* TO for Flash Write (ms) */
+
+/* max number of memory banks */
+/*
+ * There are 4 banks supported for this Controller,
+ * but we have only 1 bank connected to flash on board
+*/
+#ifndef CONFIG_SYS_MAX_FLASH_BANKS_DETECT
+#define CONFIG_SYS_MAX_FLASH_BANKS	1
+#endif
+#define CONFIG_SYS_FLASH_BANKS_SIZES {0x4000000}
+
+/* max number of sectors on one chip */
+#define CONFIG_FLASH_SECTOR_SIZE	(0x10000*2)
+#define CONFIG_SYS_MAX_FLASH_SECT	512
+
 /* environments */
 #define CONFIG_ENV_SPI_BUS		0
 #define CONFIG_ENV_SPI_CS		0
@@ -104,4 +142,21 @@
 /* Increase max gunzip size */
 #define CONFIG_SYS_BOOTM_LEN	(64 << 20)
 
+/* When we use RAM as ENV */
+#define CONFIG_ENV_SIZE 0x2000
+
+/* Enable distro boot */
+#define BOOT_TARGET_DEVICES(func) \
+	func(MMC, mmc, 0) \
+	func(DHCP, dhcp, na)
+#include <config_distro_bootcmd.h>
+
+#define CONFIG_EXTRA_ENV_SETTINGS	\
+				"kernel_addr_r=0x00080000\0" \
+				"pxefile_addr_r=0x01f00000\0" \
+				"scriptaddr=0x01f00000\0" \
+				"fdt_addr_r=0x02000000\0" \
+				"ramdisk_addr_r=0x02800000\0" \
+				BOOTENV
+
 #endif /* __CONFIG_H */
diff --git a/include/configs/bitmain_antminer_s9.h b/include/configs/bitmain_antminer_s9.h
new file mode 100644
index 0000000..2267502
--- /dev/null
+++ b/include/configs/bitmain_antminer_s9.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * (C) Copyright 2018 Michal Simek <monstr@monstr.eu>
+ */
+
+#ifndef __CONFIG_BITMAIN_ANTMINER_S9_H
+#define __CONFIG_BITMAIN_ANTMINER_S9_H
+
+#define CONFIG_SYS_SDRAM_BASE	0x00000000
+#define CONFIG_SYS_SDRAM_SIZE	0x40000000
+
+#define CONFIG_ENV_SIZE		0x20000
+#define CONFIG_ENV_OFFSET	0x300000
+
+#define CONFIG_BOOTP_SERVERIP
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"autoload=no\0" \
+	"pxefile_addr_r=0x2000000\0" \
+	"scriptaddr=0x3000000\0" \
+	"kernel_addr_r=0x2000000\0" \
+	"fdt_high=0xefff000\0" \
+	"initrd_high=0xefff000\0" \
+	"devnum=0\0" \
+	"wdstop=mw f8005000 ABC000\0" \
+	BOOTENV
+
+#include <configs/zynq-common.h>
+
+#endif /* __CONFIG_BITMAIN_ANTMINER_S9_H */
diff --git a/include/configs/dns325.h b/include/configs/dns325.h
index 5b78785..dec7103 100644
--- a/include/configs/dns325.h
+++ b/include/configs/dns325.h
@@ -27,7 +27,8 @@
 /*
  * Commands configuration
  */
-#define CONFIG_SYS_MVFS
+#define CONFIG_MTD_DEVICE		/* needed for mtdparts commands */
+#define CONFIG_MTD_PARTITIONS
 
 #define CONFIG_NR_DRAM_BANKS		1
 
diff --git a/include/configs/ds414.h b/include/configs/ds414.h
index 5b44454..27308c9 100644
--- a/include/configs/ds414.h
+++ b/include/configs/ds414.h
@@ -61,7 +61,8 @@
 #endif
 
 /* why is this only defined in mv-common.h if CONFIG_DM is undefined? */
-#define CONFIG_SYS_MVFS
+#define CONFIG_MTD_DEVICE		/* needed for mtdparts commands */
+#define CONFIG_MTD_PARTITIONS
 
 /*
  * mv-common.h should be defined after CMD configs since it used them
diff --git a/include/configs/ebisu.h b/include/configs/ebisu.h
new file mode 100644
index 0000000..560fe5c
--- /dev/null
+++ b/include/configs/ebisu.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * include/configs/ebisu.h
+ *     This file is Ebisu board configuration.
+ *
+ * Copyright (C) 2018 Renesas Electronics Corporation
+ */
+
+#ifndef __EBISU_H
+#define __EBISU_H
+
+#undef DEBUG
+
+#include "rcar-gen3-common.h"
+
+/* Ethernet RAVB */
+#define CONFIG_NET_MULTI
+#define CONFIG_BITBANGMII
+#define CONFIG_BITBANGMII_MULTI
+
+/* Board Clock */
+/* XTAL_CLK : 33.33MHz */
+#define CONFIG_SYS_CLK_FREQ	48000000u
+
+/* Generic Timer Definitions (use in assembler source) */
+#define COUNTER_FREQUENCY	0xFE502A	/* 16.66MHz from CPclk */
+
+/* Environment in eMMC, at the end of 2nd "boot sector" */
+#define CONFIG_ENV_OFFSET		(-CONFIG_ENV_SIZE)
+#define CONFIG_SYS_MMC_ENV_DEV		2
+#define CONFIG_SYS_MMC_ENV_PART		2
+
+#endif /* __EBISU_H */
diff --git a/include/configs/emdk.h b/include/configs/emdk.h
new file mode 100644
index 0000000..dca13e2
--- /dev/null
+++ b/include/configs/emdk.h
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2018 Synopsys, Inc. All rights reserved.
+ */
+
+#ifndef _CONFIG_EMDK_H_
+#define _CONFIG_EMDK_H_
+
+#include <linux/sizes.h>
+
+#define CONFIG_SYS_MONITOR_BASE		CONFIG_SYS_TEXT_BASE
+
+#define CONFIG_SYS_SDRAM_BASE		0x10000000
+#define CONFIG_SYS_SDRAM_SIZE		SZ_8M
+
+#define CONFIG_SYS_INIT_SP_ADDR		(CONFIG_SYS_SDRAM_BASE + SZ_1M)
+
+#define CONFIG_SYS_MALLOC_LEN		SZ_64K
+#define CONFIG_SYS_LOAD_ADDR		CONFIG_SYS_SDRAM_BASE
+
+/* Required by DW MMC driver */
+#define CONFIG_BOUNCE_BUFFER
+
+/*
+ * Environment
+ */
+#define CONFIG_ENV_SIZE			SZ_4K
+#define CONFIG_BOOTFILE			"app.bin"
+#define CONFIG_LOADADDR			CONFIG_SYS_LOAD_ADDR
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"upgrade_image=u-boot.bin\0" \
+	"upgrade=emdk rom unlock && " \
+		"fatload mmc 0 ${loadaddr} ${upgrade_image} && " \
+		"cp.b ${loadaddr} 0 ${filesize} && " \
+		"dcache flush && " \
+		"emdk rom lock\0"
+
+#endif /* _CONFIG_EMDK_H_ */
+
diff --git a/include/configs/goflexhome.h b/include/configs/goflexhome.h
index 1d9fe29..8b05e0a 100644
--- a/include/configs/goflexhome.h
+++ b/include/configs/goflexhome.h
@@ -41,7 +41,8 @@
  * Commands configuration
  */
 
-#define CONFIG_SYS_MVFS         /* Picks up Filesystem from mv-common.h */
+#define CONFIG_MTD_DEVICE		/* needed for mtdparts commands */
+#define CONFIG_MTD_PARTITIONS
 
 /*
  * mv-common.h should be defined after CMD configs since it used them
diff --git a/include/configs/guruplug.h b/include/configs/guruplug.h
index d59cddb..9e7ca60 100644
--- a/include/configs/guruplug.h
+++ b/include/configs/guruplug.h
@@ -17,7 +17,9 @@
 /*
  * Standard filesystems
  */
-#define CONFIG_SYS_MVFS
+#define CONFIG_BZIP2
+#define CONFIG_MTD_DEVICE		/* needed for mtdparts commands */
+#define CONFIG_MTD_PARTITIONS
 
 /*
  * mv-plug-common.h should be defined after CMD configs since it used them
diff --git a/include/configs/ib62x0.h b/include/configs/ib62x0.h
index 5f071d0..a764316 100644
--- a/include/configs/ib62x0.h
+++ b/include/configs/ib62x0.h
@@ -26,7 +26,8 @@
 /*
  * Commands configuration
  */
-#define CONFIG_SYS_MVFS
+#define CONFIG_MTD_DEVICE		/* needed for mtdparts commands */
+#define CONFIG_MTD_PARTITIONS
 
 /*
  * mv-common.h should be defined after CMD configs since it used them
diff --git a/include/configs/iconnect.h b/include/configs/iconnect.h
index 66131cc..1fe4618 100644
--- a/include/configs/iconnect.h
+++ b/include/configs/iconnect.h
@@ -28,7 +28,8 @@
 /*
  * Commands configuration
  */
-#define CONFIG_SYS_MVFS
+#define CONFIG_MTD_DEVICE		/* needed for mtdparts commands */
+#define CONFIG_MTD_PARTITIONS
 
 /*
  * mv-common.h should be defined after CMD configs since it used them
diff --git a/include/configs/mv-common.h b/include/configs/mv-common.h
index fa9b5bc..79d61c5 100644
--- a/include/configs/mv-common.h
+++ b/include/configs/mv-common.h
@@ -29,10 +29,6 @@
 #define CONFIG_SYS_SDRAM_BASE	0x00000000
 
 /*
- * CLKs configurations
- */
-
-/*
  * NS16550 Configuration
  */
 #define CONFIG_SYS_NS16550_SERIAL
@@ -101,18 +97,4 @@
 #define CONFIG_SYS_MAX_NAND_DEVICE     1
 #endif
 
-/*
- * Common SPI Flash configuration
- */
-#ifdef CONFIG_CMD_SF
-#endif
-
-/*
- * File system
- */
-#ifdef CONFIG_SYS_MVFS
-#define CONFIG_MTD_DEVICE               /* needed for mtdparts commands */
-#define CONFIG_MTD_PARTITIONS
-#endif
-
 #endif /* _MV_COMMON_H */
diff --git a/include/configs/mv-plug-common.h b/include/configs/mv-plug-common.h
index df686db..81c07a8 100644
--- a/include/configs/mv-plug-common.h
+++ b/include/configs/mv-plug-common.h
@@ -17,21 +17,6 @@
 #define CONFIG_BUILD_TARGET     "u-boot.kwb"
 
 /*
- * Compression configuration
- */
-#ifdef CONFIG_SYS_MVFS
-#define CONFIG_BZIP2
-#endif /* CONFIG_SYS_MVFS */
-
-/*
- * Commands configuration
- */
-
-/*
- * Extra file system
- */
-
-/*
  * mv-common.h should be defined after CMD configs since it used them
  * to enable certain macros
  */
diff --git a/include/configs/nsa310s.h b/include/configs/nsa310s.h
index 4c32052..2f90439 100644
--- a/include/configs/nsa310s.h
+++ b/include/configs/nsa310s.h
@@ -22,7 +22,8 @@
 #define CONFIG_BZIP2
 
 /* commands configuration */
-#define CONFIG_SYS_MVFS
+#define CONFIG_MTD_DEVICE		/* needed for mtdparts commands */
+#define CONFIG_MTD_PARTITIONS
 
 /*
  * mv-common.h should be defined after CMD configs since it used them
diff --git a/include/configs/openrd.h b/include/configs/openrd.h
index dfdad56..aa5425a 100644
--- a/include/configs/openrd.h
+++ b/include/configs/openrd.h
@@ -23,7 +23,8 @@
 /*
  * Commands configuration
  */
-#define CONFIG_SYS_MVFS
+#define CONFIG_MTD_DEVICE		/* needed for mtdparts commands */
+#define CONFIG_MTD_PARTITIONS
 
 /*
  * mv-common.h should be defined after CMD configs since it used them
diff --git a/include/configs/pogo_e02.h b/include/configs/pogo_e02.h
index 0416bae..a654df6 100644
--- a/include/configs/pogo_e02.h
+++ b/include/configs/pogo_e02.h
@@ -27,7 +27,8 @@
 /*
  * Commands configuration
  */
-#define CONFIG_SYS_MVFS
+#define CONFIG_MTD_DEVICE		/* needed for mtdparts commands */
+#define CONFIG_MTD_PARTITIONS
 
 /*
  * mv-common.h should be defined after CMD configs since it used them
diff --git a/include/configs/rcar-gen2-common.h b/include/configs/rcar-gen2-common.h
index eadf559..231c4ec 100644
--- a/include/configs/rcar-gen2-common.h
+++ b/include/configs/rcar-gen2-common.h
@@ -51,4 +51,12 @@
 #define CONFIG_ENV_SIZE		(CONFIG_ENV_SECT_SIZE)
 #define CONFIG_ENV_SIZE_REDUND	(CONFIG_SYS_MONITOR_LEN)
 
+/* SF MTD */
+#if defined(CONFIG_SPI_FLASH_MTD) && !defined(CONFIG_SPL_BUILD)
+#define CONFIG_MTD_DEVICE
+#define CONFIG_MTD_PARTITIONS
+#else
+#undef CONFIG_SPI_FLASH_MTD
+#endif
+
 #endif	/* __RCAR_GEN2_COMMON_H */
diff --git a/include/configs/rpi.h b/include/configs/rpi.h
index 649a425..a97550b 100644
--- a/include/configs/rpi.h
+++ b/include/configs/rpi.h
@@ -90,6 +90,14 @@
 	"stdout=serial,vidconsole\0" \
 	"stderr=serial,vidconsole\0"
 
+#ifdef CONFIG_ARM64
+#define FDT_HIGH "ffffffffffffffff"
+#define INITRD_HIGH "ffffffffffffffff"
+#else
+#define FDT_HIGH "ffffffff"
+#define INITRD_HIGH "ffffffff"
+#endif
+
 /*
  * Memory layout for where various images get loaded by boot scripts:
  *
@@ -132,8 +140,8 @@
  * large initrds before they start colliding with U-Boot.
  */
 #define ENV_MEM_LAYOUT_SETTINGS \
-	"fdt_high=ffffffff\0" \
-	"initrd_high=ffffffff\0" \
+	"fdt_high=" FDT_HIGH "\0" \
+	"initrd_high=" INITRD_HIGH "\0" \
 	"kernel_addr_r=0x00080000\0" \
 	"scriptaddr=0x02400000\0" \
 	"pxefile_addr_r=0x02500000\0" \
diff --git a/include/configs/sheevaplug.h b/include/configs/sheevaplug.h
index 656db45..23dd5ce 100644
--- a/include/configs/sheevaplug.h
+++ b/include/configs/sheevaplug.h
@@ -21,7 +21,9 @@
 /*
  * Standard filesystems
  */
-#define CONFIG_SYS_MVFS
+#define CONFIG_BZIP2
+#define CONFIG_MTD_DEVICE		/* needed for mtdparts commands */
+#define CONFIG_MTD_PARTITIONS
 
 /*
  * mv-plug-common.h should be defined after CMD configs since it used them
diff --git a/include/configs/stm32f429-discovery.h b/include/configs/stm32f429-discovery.h
index 4fd9c23..46eda1d 100644
--- a/include/configs/stm32f429-discovery.h
+++ b/include/configs/stm32f429-discovery.h
@@ -22,10 +22,10 @@
 #define CONFIG_NR_DRAM_BANKS		1
 #define CONFIG_SYS_RAM_CS		1
 #define CONFIG_SYS_RAM_FREQ_DIV		2
-#define CONFIG_SYS_RAM_BASE		0xD0000000
+#define CONFIG_SYS_RAM_BASE		0x90000000
 #define CONFIG_SYS_SDRAM_BASE		CONFIG_SYS_RAM_BASE
-#define CONFIG_SYS_LOAD_ADDR		0xD0400000
-#define CONFIG_LOADADDR			0xD0400000
+#define CONFIG_SYS_LOAD_ADDR		0x90400000
+#define CONFIG_LOADADDR			0x90400000
 
 #define CONFIG_SYS_MAX_FLASH_SECT	12
 #define CONFIG_SYS_MAX_FLASH_BANKS	2
diff --git a/include/configs/xilinx_zynqmp_mini.h b/include/configs/xilinx_zynqmp_mini.h
index 947d308..96ff6c9 100644
--- a/include/configs/xilinx_zynqmp_mini.h
+++ b/include/configs/xilinx_zynqmp_mini.h
@@ -32,7 +32,6 @@
 /* BOOTP options */
 #undef CONFIG_BOOTP_BOOTFILESIZE
 #undef CONFIG_BOOTP_MAY_FAIL
-#undef CONFIG_CMD_UNZIP
 
 #undef CONFIG_NR_DRAM_BANKS
 
diff --git a/include/configs/xilinx_zynqmp_zc1751_xm016_dc2.h b/include/configs/xilinx_zynqmp_zc1751_xm016_dc2.h
deleted file mode 100644
index bfebbb3..0000000
--- a/include/configs/xilinx_zynqmp_zc1751_xm016_dc2.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Configuration for Xilinx ZynqMP zc1751 XM016 DC2
- *
- * (C) Copyright 2015 Xilinx, Inc.
- * Michal Simek <michal.simek@xilinx.com>
- */
-
-#ifndef __CONFIG_ZYNQMP_ZC1751_XM016_DC2_H
-#define __CONFIG_ZYNQMP_ZC1751_XM016_DC2_H
-
-#include <configs/xilinx_zynqmp.h>
-
-#endif /* __CONFIG_ZYNQMP_ZC1751_XM016_DC2_H */
diff --git a/include/dm/fdtaddr.h b/include/dm/fdtaddr.h
index db4c11e..49a6ffd 100644
--- a/include/dm/fdtaddr.h
+++ b/include/dm/fdtaddr.h
@@ -34,6 +34,28 @@
 void *devfdt_get_addr_ptr(struct udevice *dev);
 
 /**
+ * devfdt_remap_addr() - Return pointer to the memory-mapped I/O address
+ *                           of the reg property of a device
+ *
+ * @dev: Pointer to a device
+ *
+ * @return Pointer to addr, or NULL if there is no such property
+ */
+void *devfdt_remap_addr(struct udevice *dev);
+
+/**
+ * devfdt_remap_addr_index() - Return indexed pointer to the memory-mapped
+ *                                 I/O address of the reg property of a device
+ * @index: the 'reg' property can hold a list of <addr, size> pairs
+ *	   and @index is used to select which one is required
+ *
+ * @dev: Pointer to a device
+ *
+ * @return Pointer to addr, or NULL if there is no such property
+ */
+void *devfdt_remap_addr_index(struct udevice *dev, int index);
+
+/**
  * devfdt_map_physmem() - Read device address from reg property of the
  *                     device node and map the address into CPU address
  *                     space.
diff --git a/include/dm/read.h b/include/dm/read.h
index 4a725bc..a27b855 100644
--- a/include/dm/read.h
+++ b/include/dm/read.h
@@ -113,6 +113,18 @@
 fdt_addr_t dev_read_addr_index(struct udevice *dev, int index);
 
 /**
+ * dev_remap_addr_index() - Get the indexed reg property of a device
+ *                               as a memory-mapped I/O pointer
+ *
+ * @dev: Device to read from
+ * @index: the 'reg' property can hold a list of <addr, size> pairs
+ *	   and @index is used to select which one is required
+ *
+ * @return pointer or NULL if not found
+ */
+void *dev_remap_addr_index(struct udevice *dev, int index);
+
+/**
  * dev_read_addr() - Get the reg property of a device
  *
  * @dev: Device to read from
@@ -132,6 +144,16 @@
 void *dev_read_addr_ptr(struct udevice *dev);
 
 /**
+ * dev_remap_addr() - Get the reg property of a device as a
+ *                         memory-mapped I/O pointer
+ *
+ * @dev: Device to read from
+ *
+ * @return pointer or NULL if not found
+ */
+void *dev_remap_addr(struct udevice *dev);
+
+/**
  * dev_read_addr_size() - get address and size from a device property
  *
  * This does no address translation. It simply reads an property that contains
@@ -482,6 +504,16 @@
 	return devfdt_get_addr_ptr(dev);
 }
 
+static inline void *dev_remap_addr(struct udevice *dev)
+{
+	return devfdt_remap_addr(dev);
+}
+
+static inline void *dev_remap_addr_index(struct udevice *dev, int index)
+{
+	return devfdt_remap_addr_index(dev, index);
+}
+
 static inline fdt_addr_t dev_read_addr_size(struct udevice *dev,
 					    const char *propname,
 					    fdt_size_t *sizep)
diff --git a/include/dt-bindings/clock/r8a77990-cpg-mssr.h b/include/dt-bindings/clock/r8a77990-cpg-mssr.h
new file mode 100644
index 0000000..c806fce
--- /dev/null
+++ b/include/dt-bindings/clock/r8a77990-cpg-mssr.h
@@ -0,0 +1,63 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ */
+#ifndef __DT_BINDINGS_CLOCK_R8A77990_CPG_MSSR_H__
+#define __DT_BINDINGS_CLOCK_R8A77990_CPG_MSSR_H__
+
+#include <dt-bindings/clock/renesas-cpg-mssr.h>
+
+/* r8a77990 CPG Core Clocks */
+#define R8A77990_CLK_Z2			0
+#define R8A77990_CLK_ZR			1
+#define R8A77990_CLK_ZG			2
+#define R8A77990_CLK_ZTR		3
+#define R8A77990_CLK_ZT			4
+#define R8A77990_CLK_ZX			5
+#define R8A77990_CLK_S0D1		6
+#define R8A77990_CLK_S0D3		7
+#define R8A77990_CLK_S0D6		8
+#define R8A77990_CLK_S0D12		9
+#define R8A77990_CLK_S0D24		10
+#define R8A77990_CLK_S1D1		11
+#define R8A77990_CLK_S1D2		12
+#define R8A77990_CLK_S1D4		13
+#define R8A77990_CLK_S2D1		14
+#define R8A77990_CLK_S2D2		15
+#define R8A77990_CLK_S2D4		16
+#define R8A77990_CLK_S3D1		17
+#define R8A77990_CLK_S3D2		18
+#define R8A77990_CLK_S3D4		19
+#define R8A77990_CLK_S0D6C		20
+#define R8A77990_CLK_S3D1C		21
+#define R8A77990_CLK_S3D2C		22
+#define R8A77990_CLK_S3D4C		23
+#define R8A77990_CLK_LB			24
+#define R8A77990_CLK_CL			25
+#define R8A77990_CLK_ZB3		26
+#define R8A77990_CLK_ZB3D2		27
+#define R8A77990_CLK_CR			28
+#define R8A77990_CLK_CRD2		29
+#define R8A77990_CLK_SD0H		30
+#define R8A77990_CLK_SD0		31
+#define R8A77990_CLK_SD1H		32
+#define R8A77990_CLK_SD1		33
+#define R8A77990_CLK_SD3H		34
+#define R8A77990_CLK_SD3		35
+#define R8A77990_CLK_RPC		36
+#define R8A77990_CLK_RPCD2		37
+#define R8A77990_CLK_ZA2		38
+#define R8A77990_CLK_ZA8		39
+#define R8A77990_CLK_Z2D		40
+#define R8A77990_CLK_CANFD		41
+#define R8A77990_CLK_MSO		42
+#define R8A77990_CLK_R			43
+#define R8A77990_CLK_OSC		44
+#define R8A77990_CLK_LV0		45
+#define R8A77990_CLK_LV1		46
+#define R8A77990_CLK_CSI0		47
+#define R8A77990_CLK_POST3		48
+#define R8A77990_CLK_CP			49
+#define R8A77990_CLK_CPEX		50
+
+#endif /* __DT_BINDINGS_CLOCK_R8A77990_CPG_MSSR_H__ */
diff --git a/include/dt-bindings/leds/leds-netxbig.h b/include/dt-bindings/leds/leds-netxbig.h
new file mode 100644
index 0000000..92658b0
--- /dev/null
+++ b/include/dt-bindings/leds/leds-netxbig.h
@@ -0,0 +1,18 @@
+/*
+ * This header provides constants for netxbig LED bindings.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef _DT_BINDINGS_LEDS_NETXBIG_H
+#define _DT_BINDINGS_LEDS_NETXBIG_H
+
+#define NETXBIG_LED_OFF		0
+#define NETXBIG_LED_ON		1
+#define NETXBIG_LED_SATA	2
+#define NETXBIG_LED_TIMER1	3
+#define NETXBIG_LED_TIMER2	4
+
+#endif /* _DT_BINDINGS_LEDS_NETXBIG_H */
diff --git a/include/dt-bindings/leds/leds-ns2.h b/include/dt-bindings/leds/leds-ns2.h
new file mode 100644
index 0000000..fd61574
--- /dev/null
+++ b/include/dt-bindings/leds/leds-ns2.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _DT_BINDINGS_LEDS_NS2_H
+#define _DT_BINDINGS_LEDS_NS2_H
+
+#define NS_V2_LED_OFF	0
+#define NS_V2_LED_ON	1
+#define NS_V2_LED_SATA	2
+
+#endif
diff --git a/include/dt-bindings/pinctrl/pinctrl-snapdragon.h b/include/dt-bindings/pinctrl/pinctrl-snapdragon.h
new file mode 100644
index 0000000..615affb
--- /dev/null
+++ b/include/dt-bindings/pinctrl/pinctrl-snapdragon.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * This header provides constants for Qualcomm Snapdragon pinctrl bindings.
+ *
+ * (C) Copyright 2018 Ramon Fried <ramon.fried@gmail.com>
+ *
+ */
+
+#ifndef _DT_BINDINGS_PINCTRL_SNAPDRAGON_H
+#define _DT_BINDINGS_PINCTRL_SNAPDRAGON_H
+
+/* GPIO Drive Strength */
+#define DRIVE_STRENGTH_2MA        0
+#define DRIVE_STRENGTH_4MA        1
+#define DRIVE_STRENGTH_6MA        2
+#define DRIVE_STRENGTH_8MA        3
+#define DRIVE_STRENGTH_10MA       4
+#define DRIVE_STRENGTH_12MA       5
+#define DRIVE_STRENGTH_14MA       6
+#define DRIVE_STRENGTH_16MA       7
+
+#endif
diff --git a/include/dt_table.h b/include/dt_table.h
new file mode 100644
index 0000000..7fb16e9
--- /dev/null
+++ b/include/dt_table.h
@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * This is from the Android Project,
+ * Repository: https://android.googlesource.com/platform/system/libufdt
+ * File: utils/src/dt_table.h
+ * Commit: 2626d8b9e4d8e8c6cc67ceb1dc4e05a47779785c
+ * Copyright (C) 2017 The Android Open Source Project
+ */
+
+#ifndef DT_TABLE_H
+#define DT_TABLE_H
+
+#include <linux/types.h>
+
+#define DT_TABLE_MAGIC			0xd7b7ab1e
+#define DT_TABLE_DEFAULT_PAGE_SIZE	2048
+#define DT_TABLE_DEFAULT_VERSION	0
+
+struct dt_table_header {
+	u32 magic;		/* DT_TABLE_MAGIC */
+	u32 total_size;		/* includes dt_table_header + all dt_table_entry
+				 * and all dtb/dtbo
+				 */
+	u32 header_size;	/* sizeof(dt_table_header) */
+
+	u32 dt_entry_size;	/* sizeof(dt_table_entry) */
+	u32 dt_entry_count;	/* number of dt_table_entry */
+	u32 dt_entries_offset;	/* offset to the first dt_table_entry
+				 * from head of dt_table_header.
+				 * The value will be equal to header_size if
+				 * no padding is appended
+				 */
+	u32 page_size;		/* flash page size we assume */
+	u32 version;            /* DTBO image version, the current version is 0.
+				 * The version will be incremented when the
+				 * dt_table_header struct is updated.
+				 */
+};
+
+struct dt_table_entry {
+	u32 dt_size;
+	u32 dt_offset;		/* offset from head of dt_table_header */
+
+	u32 id;			/* optional, must be zero if unused */
+	u32 rev;		/* optional, must be zero if unused */
+	u32 custom[4];		/* optional, must be zero if unused */
+};
+
+#endif
diff --git a/include/efi_api.h b/include/efi_api.h
index 64c27e4..094be6e 100644
--- a/include/efi_api.h
+++ b/include/efi_api.h
@@ -214,15 +214,15 @@
 			uint32_t descriptor_version,
 			struct efi_mem_desc *virtmap);
 	efi_status_t (*convert_pointer)(unsigned long dbg, void **address);
-	efi_status_t (EFIAPI *get_variable)(s16 *variable_name,
-			efi_guid_t *vendor, u32 *attributes,
-			unsigned long *data_size, void *data);
-	efi_status_t (EFIAPI *get_next_variable)(
-			unsigned long *variable_name_size,
-			s16 *variable_name, efi_guid_t *vendor);
-	efi_status_t (EFIAPI *set_variable)(s16 *variable_name,
-			efi_guid_t *vendor, u32 attributes,
-			unsigned long data_size, void *data);
+	efi_status_t (EFIAPI *get_variable)(u16 *variable_name,
+					    efi_guid_t *vendor, u32 *attributes,
+					    efi_uintn_t *data_size, void *data);
+	efi_status_t (EFIAPI *get_next_variable_name)(
+			efi_uintn_t *variable_name_size,
+			u16 *variable_name, efi_guid_t *vendor);
+	efi_status_t (EFIAPI *set_variable)(u16 *variable_name,
+					    efi_guid_t *vendor, u32 attributes,
+					    efi_uintn_t data_size, void *data);
 	efi_status_t (EFIAPI *get_next_high_mono_count)(
 			uint32_t *high_count);
 	void (EFIAPI *reset_system)(enum efi_reset_type reset_type,
@@ -239,9 +239,9 @@
 			u32 reset_type);
 	efi_status_t (EFIAPI *query_variable_info)(
 			u32 attributes,
-			u64 maximum_variable_storage_size,
-			u64 remaining_variable_storage_size,
-			u64 maximum_variable_size);
+			u64 *maximum_variable_storage_size,
+			u64 *remaining_variable_storage_size,
+			u64 *maximum_variable_size);
 };
 
 /* EFI event group GUID definitions */
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 2868ca2..c66252a 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -75,6 +75,13 @@
 		##__VA_ARGS__); \
 	})
 
+#ifdef CONFIG_SYS_CACHELINE_SIZE
+#define EFI_CACHELINE_SIZE CONFIG_SYS_CACHELINE_SIZE
+#else
+/* Just use the greatest cache flush alignment requirement I'm aware of */
+#define EFI_CACHELINE_SIZE 128
+#endif
+
 extern struct efi_runtime_services efi_runtime_services;
 extern struct efi_system_table systab;
 
@@ -207,6 +214,13 @@
 /* Called by bootefi to make the watchdog available */
 efi_status_t efi_watchdog_register(void);
 /* Called by bootefi to make SMBIOS tables available */
+/**
+ * efi_smbios_register() - write out SMBIOS tables
+ *
+ * Called by bootefi to make SMBIOS tables available
+ *
+ * @return 0 if OK, -ENOMEM if no memory is available for the tables
+ */
 efi_status_t efi_smbios_register(void);
 
 struct efi_simple_file_system_protocol *
@@ -415,15 +429,15 @@
 				 struct efi_system_table *systab);
 #endif
 
-efi_status_t EFIAPI efi_get_variable(s16 *variable_name,
-		efi_guid_t *vendor, u32 *attributes,
-		unsigned long *data_size, void *data);
-efi_status_t EFIAPI efi_get_next_variable(
-		unsigned long *variable_name_size,
-		s16 *variable_name, efi_guid_t *vendor);
-efi_status_t EFIAPI efi_set_variable(s16 *variable_name,
-		efi_guid_t *vendor, u32 attributes,
-		unsigned long data_size, void *data);
+efi_status_t EFIAPI efi_get_variable(u16 *variable_name, efi_guid_t *vendor,
+				     u32 *attributes, efi_uintn_t *data_size,
+				     void *data);
+efi_status_t EFIAPI efi_get_next_variable_name(efi_uintn_t *variable_name_size,
+					       u16 *variable_name,
+					       efi_guid_t *vendor);
+efi_status_t EFIAPI efi_set_variable(u16 *variable_name, efi_guid_t *vendor,
+				     u32 attributes, efi_uintn_t data_size,
+				     void *data);
 
 void *efi_bootmgr_load(struct efi_device_path **device_path,
 		       struct efi_device_path **file_path);
diff --git a/include/fastboot-internal.h b/include/fastboot-internal.h
new file mode 100644
index 0000000..bf2f2b3
--- /dev/null
+++ b/include/fastboot-internal.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef _FASTBOOT_INTERNAL_H_
+#define _FASTBOOT_INTERNAL_H_
+
+/**
+ * fastboot_buf_addr - base address of the fastboot download buffer
+ */
+extern void *fastboot_buf_addr;
+
+/**
+ * fastboot_buf_size - size of the fastboot download buffer
+ */
+extern u32 fastboot_buf_size;
+
+/**
+ * fastboot_progress_callback - callback executed during long operations
+ */
+extern void (*fastboot_progress_callback)(const char *msg);
+
+/**
+ * fastboot_getvar() - Writes variable indicated by cmd_parameter to response.
+ *
+ * @cmd_parameter: Pointer to command parameter
+ * @response: Pointer to fastboot response buffer
+ *
+ * Look up cmd_parameter first as an environment variable of the form
+ * fastboot.<cmd_parameter>, if that exists return use its value to set
+ * response.
+ *
+ * Otherwise lookup the name of variable and execute the appropriate
+ * function to return the requested value.
+ */
+void fastboot_getvar(char *cmd_parameter, char *response);
+
+#endif
diff --git a/include/fastboot.h b/include/fastboot.h
index 009f1a7..1933b1d 100644
--- a/include/fastboot.h
+++ b/include/fastboot.h
@@ -12,10 +12,143 @@
 #ifndef _FASTBOOT_H_
 #define _FASTBOOT_H_
 
+#define FASTBOOT_VERSION	"0.4"
+
 /* The 64 defined bytes plus \0 */
+#define FASTBOOT_COMMAND_LEN	(64 + 1)
 #define FASTBOOT_RESPONSE_LEN	(64 + 1)
 
-void fastboot_fail(const char *reason);
-void fastboot_okay(const char *reason);
+/**
+ * All known commands to fastboot
+ */
+enum {
+	FASTBOOT_COMMAND_GETVAR = 0,
+	FASTBOOT_COMMAND_DOWNLOAD,
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
+	FASTBOOT_COMMAND_FLASH,
+	FASTBOOT_COMMAND_ERASE,
+#endif
+	FASTBOOT_COMMAND_BOOT,
+	FASTBOOT_COMMAND_CONTINUE,
+	FASTBOOT_COMMAND_REBOOT,
+	FASTBOOT_COMMAND_REBOOT_BOOTLOADER,
+	FASTBOOT_COMMAND_SET_ACTIVE,
+#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
+	FASTBOOT_COMMAND_OEM_FORMAT,
+#endif
+
+	FASTBOOT_COMMAND_COUNT
+};
+
+/**
+ * fastboot_response() - Writes a response of the form "$tag$reason".
+ *
+ * @tag: The first part of the response
+ * @response: Pointer to fastboot response buffer
+ * @format: printf style format string
+ */
+void fastboot_response(const char *tag, char *response,
+		       const char *format, ...)
+	__attribute__ ((format (__printf__, 3, 4)));
+
+/**
+ * fastboot_fail() - Write a FAIL response of the form "FAIL$reason".
+ *
+ * @reason: Pointer to returned reason string
+ * @response: Pointer to fastboot response buffer
+ */
+void fastboot_fail(const char *reason, char *response);
+
+/**
+ * fastboot_okay() - Write an OKAY response of the form "OKAY$reason".
+ *
+ * @reason: Pointer to returned reason string, or NULL to send a bare "OKAY"
+ * @response: Pointer to fastboot response buffer
+ */
+void fastboot_okay(const char *reason, char *response);
+
+/**
+ * fastboot_set_reboot_flag() - Set flag to indicate reboot-bootloader
+ *
+ * Set flag which indicates that we should reboot into the bootloader
+ * following the reboot that fastboot executes after this function.
+ *
+ * This function should be overridden in your board file with one
+ * which sets whatever flag your board specific Android bootloader flow
+ * requires in order to re-enter the bootloader.
+ */
+int fastboot_set_reboot_flag(void);
+
+/**
+ * fastboot_set_progress_callback() - set progress callback
+ *
+ * @progress: Pointer to progress callback
+ *
+ * Set a callback which is invoked periodically during long running operations
+ * (flash and erase). This can be used (for example) by the UDP transport to
+ * send INFO responses to keep the client alive whilst those commands are
+ * executing.
+ */
+void fastboot_set_progress_callback(void (*progress)(const char *msg));
+
+/*
+ * fastboot_init() - initialise new fastboot protocol session
+ *
+ * @buf_addr: Pointer to download buffer, or NULL for default
+ * @buf_size: Size of download buffer, or zero for default
+ */
+void fastboot_init(void *buf_addr, u32 buf_size);
+
+/**
+ * fastboot_boot() - Execute fastboot boot command
+ *
+ * If ${fastboot_bootcmd} is set, run that command to execute the boot
+ * process, if that returns, then exit the fastboot server and return
+ * control to the caller.
+ *
+ * Otherwise execute "bootm <fastboot_buf_addr>", if that fails, reset
+ * the board.
+ */
+void fastboot_boot(void);
+
+/**
+ * fastboot_handle_command() - Handle fastboot command
+ *
+ * @cmd_string: Pointer to command string
+ * @response: Pointer to fastboot response buffer
+ *
+ * Return: Executed command, or -1 if not recognized
+ */
+int fastboot_handle_command(char *cmd_string, char *response);
+
+/**
+ * fastboot_data_remaining() - return bytes remaining in current transfer
+ *
+ * Return: Number of bytes left in the current download
+ */
+u32 fastboot_data_remaining(void);
+
+/**
+ * fastboot_data_download() - Copy image data to fastboot_buf_addr.
+ *
+ * @fastboot_data: Pointer to received fastboot data
+ * @fastboot_data_len: Length of received fastboot data
+ * @response: Pointer to fastboot response buffer
+ *
+ * Copies image data from fastboot_data to fastboot_buf_addr. Writes to
+ * response. fastboot_bytes_received is updated to indicate the number
+ * of bytes that have been transferred.
+ */
+void fastboot_data_download(const void *fastboot_data,
+			    unsigned int fastboot_data_len, char *response);
+
+/**
+ * fastboot_data_complete() - Mark current transfer complete
+ *
+ * @response: Pointer to fastboot response buffer
+ *
+ * Set image_size and ${filesize} to the total size of the downloaded image.
+ */
+void fastboot_data_complete(char *response);
 
 #endif /* _FASTBOOT_H_ */
diff --git a/include/fb_mmc.h b/include/fb_mmc.h
index a2d7c48..fd5db9e 100644
--- a/include/fb_mmc.h
+++ b/include/fb_mmc.h
@@ -3,6 +3,35 @@
  * Copyright 2014 Broadcom Corporation.
  */
 
-void fb_mmc_flash_write(const char *cmd, void *download_buffer,
-			unsigned int download_bytes);
-void fb_mmc_erase(const char *cmd);
+#ifndef _FB_MMC_H_
+#define _FB_MMC_H_
+
+/**
+ * fastboot_mmc_get_part_info() - Lookup eMMC partion by name
+ *
+ * @part_name: Named partition to lookup
+ * @dev_desc: Pointer to returned blk_desc pointer
+ * @part_info: Pointer to returned disk_partition_t
+ * @response: Pointer to fastboot response buffer
+ */
+int fastboot_mmc_get_part_info(char *part_name, struct blk_desc **dev_desc,
+			       disk_partition_t *part_info, char *response);
+
+/**
+ * fastboot_mmc_flash_write() - Write image to eMMC for fastboot
+ *
+ * @cmd: Named partition to write image to
+ * @download_buffer: Pointer to image data
+ * @download_bytes: Size of image data
+ * @response: Pointer to fastboot response buffer
+ */
+void fastboot_mmc_flash_write(const char *cmd, void *download_buffer,
+			      u32 download_bytes, char *response);
+/**
+ * fastboot_mmc_flash_erase() - Erase eMMC for fastboot
+ *
+ * @cmd: Named partition to erase
+ * @response: Pointer to fastboot response buffer
+ */
+void fastboot_mmc_erase(const char *cmd, char *response);
+#endif
diff --git a/include/fb_nand.h b/include/fb_nand.h
index 3daae8c..08ab0e2 100644
--- a/include/fb_nand.h
+++ b/include/fb_nand.h
@@ -4,6 +4,37 @@
  * Copyright 2015 Free Electrons.
  */
 
-void fb_nand_flash_write(const char *cmd, void *download_buffer,
-			 unsigned int download_bytes);
-void fb_nand_erase(const char *cmd);
+#ifndef _FB_NAND_H_
+#define _FB_NAND_H_
+
+#include <jffs2/load_kernel.h>
+
+/**
+ * fastboot_nand_get_part_info() - Lookup NAND partion by name
+ *
+ * @part_name: Named device to lookup
+ * @part_info: Pointer to returned part_info pointer
+ * @response: Pointer to fastboot response buffer
+ */
+int fastboot_nand_get_part_info(char *part_name, struct part_info **part_info,
+				char *response);
+
+/**
+ * fastboot_nand_flash_write() - Write image to NAND for fastboot
+ *
+ * @cmd: Named device to write image to
+ * @download_buffer: Pointer to image data
+ * @download_bytes: Size of image data
+ * @response: Pointer to fastboot response buffer
+ */
+void fastboot_nand_flash_write(const char *cmd, void *download_buffer,
+			       u32 download_bytes, char *response);
+
+/**
+ * fastboot_nand_flash_erase() - Erase NAND for fastboot
+ *
+ * @cmd: Named device to erase
+ * @response: Pointer to fastboot response buffer
+ */
+void fastboot_nand_erase(const char *cmd, char *response);
+#endif
diff --git a/include/fpga.h b/include/fpga.h
index f444093..195f0bd 100644
--- a/include/fpga.h
+++ b/include/fpga.h
@@ -20,6 +20,9 @@
 /* device numbers must be non-negative */
 #define FPGA_INVALID_DEVICE	-1
 
+#define FPGA_ENC_USR_KEY	1
+#define FPGA_NO_ENC_OR_NO_AUTH	2
+
 /* root data type defintions */
 typedef enum {			/* typedef fpga_type */
 	fpga_min_type,		/* range check value */
@@ -42,6 +45,12 @@
 	int fstype;
 } fpga_fs_info;
 
+struct fpga_secure_info {
+	u8 *userkey_addr;
+	u8 authflag;
+	u8 encflag;
+};
+
 typedef enum {
 	BIT_FULL = 0,
 	BIT_PARTIAL,
@@ -58,6 +67,8 @@
 	      bitstream_type bstype);
 int fpga_fsload(int devnum, const void *buf, size_t size,
 		fpga_fs_info *fpga_fsinfo);
+int fpga_loads(int devnum, const void *buf, size_t size,
+	       struct fpga_secure_info *fpga_sec_info);
 int fpga_loadbitstream(int devnum, char *fpgadata, size_t size,
 		       bitstream_type bstype);
 int fpga_dump(int devnum, const void *buf, size_t bsize);
diff --git a/include/fs.h b/include/fs.h
index d703ed5..163da10 100644
--- a/include/fs.h
+++ b/include/fs.h
@@ -37,6 +37,16 @@
  */
 int fs_set_blk_dev_with_part(struct blk_desc *desc, int part);
 
+/**
+ * fs_get_type_name() - Get type of current filesystem
+ *
+ * Return: Pointer to filesystem name
+ *
+ * Returns a string describing the current filesystem, or the sentinel
+ * "unsupported" for any unrecognised filesystem.
+ */
+const char *fs_get_type_name(void);
+
 /*
  * Print the list of files on the partition previously set by fs_set_blk_dev(),
  * in directory "dirname".
diff --git a/include/image-sparse.h b/include/image-sparse.h
index f39dc16..234c237 100644
--- a/include/image-sparse.h
+++ b/include/image-sparse.h
@@ -23,7 +23,7 @@
 				 lbaint_t blk,
 				 lbaint_t blkcnt);
 
-	void		(*mssg)(const char *str);
+	void		(*mssg)(const char *str, char *response);
 };
 
 static inline int is_sparse_image(void *buf)
@@ -38,4 +38,4 @@
 }
 
 int write_sparse_image(struct sparse_storage *info, const char *part_name,
-		       void *data);
+		       void *data, char *response);
diff --git a/include/image.h b/include/image.h
index 9522ee4..95d5934 100644
--- a/include/image.h
+++ b/include/image.h
@@ -988,6 +988,8 @@
 int fit_image_get_data_position(const void *fit, int noffset,
 				int *data_position);
 int fit_image_get_data_size(const void *fit, int noffset, int *data_size);
+int fit_image_get_data_and_size(const void *fit, int noffset,
+				const void **data, size_t *size);
 
 int fit_image_hash_get_algo(const void *fit, int noffset, char **algo);
 int fit_image_hash_get_value(const void *fit, int noffset, uint8_t **value,
diff --git a/include/linux/libfdt_env.h b/include/linux/libfdt_env.h
index 0d209a6..e2bf79c 100644
--- a/include/linux/libfdt_env.h
+++ b/include/linux/libfdt_env.h
@@ -6,8 +6,8 @@
  * Using the same guard name as that of scripts/dtc/libfdt/libfdt_env.h
  * prevents it from being included.
  */
-#ifndef _LIBFDT_ENV_H
-#define _LIBFDT_ENV_H
+#ifndef LIBFDT_ENV_H
+#define LIBFDT_ENV_H
 
 #include <linux/string.h>
 
@@ -27,5 +27,5 @@
 
 #define strtoul(cp, endp, base)	simple_strtoul(cp, endp, base)
 
-#endif /* _LIBFDT_ENV_H */
+#endif /* LIBFDT_ENV_H */
 #endif
diff --git a/include/net.h b/include/net.h
index 65f51d7..5760685 100644
--- a/include/net.h
+++ b/include/net.h
@@ -535,7 +535,7 @@
 
 enum proto_t {
 	BOOTP, RARP, ARP, TFTPGET, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP,
-	TFTPSRV, TFTPPUT, LINKLOCAL
+	TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT
 };
 
 extern char	net_boot_file_name[1024];/* Boot File name */
diff --git a/include/net/fastboot.h b/include/net/fastboot.h
new file mode 100644
index 0000000..6860209
--- /dev/null
+++ b/include/net/fastboot.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (C) 2016 The Android Open Source Project
+ */
+
+#ifndef __NET_FASTBOOT_H__
+#define __NET_FASTBOOT_H__
+
+/**********************************************************************/
+/*
+ *	Global functions and variables.
+ */
+
+/**
+ * Wait for incoming fastboot comands.
+ */
+void fastboot_start_server(void);
+
+/**********************************************************************/
+
+#endif /* __NET_FASTBOOT_H__ */
diff --git a/include/os.h b/include/os.h
index 64e89a0..c8e0f52 100644
--- a/include/os.h
+++ b/include/os.h
@@ -330,4 +330,25 @@
  */
 void os_localtime(struct rtc_time *rt);
 
+/**
+ * os_setjmp() - Call setjmp()
+ *
+ * Call the host system's setjmp() function.
+ *
+ * @jmp: Buffer to store current execution state
+ * @size: Size of buffer
+ * @return normal setjmp() value if OK, -ENOSPC if @size is too small
+ */
+int os_setjmp(ulong *jmp, int size);
+
+/**
+ * os_longjmp() - Call longjmp()
+ *
+ * Call the host system's longjmp() function.
+ *
+ * @jmp: Buffer where previous execution state was stored
+ * @ret: Value to pass to longjmp()
+ */
+void os_longjmp(ulong *jmp, int ret);
+
 #endif
diff --git a/include/pci.h b/include/pci.h
index cda6907..8e27cbf 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -680,8 +680,21 @@
 void pciauto_region_init(struct pci_region *res);
 void pciauto_region_align(struct pci_region *res, pci_size_t size);
 void pciauto_config_init(struct pci_controller *hose);
+
+/**
+ * pciauto_region_allocate() - Allocate resources from a PCI resource region
+ *
+ * Allocates @size bytes from the PCI resource @res. If @supports_64bit is
+ * false, the result will be guaranteed to fit in 32 bits.
+ *
+ * @res:		PCI region to allocate from
+ * @size:		Amount of bytes to allocate
+ * @bar:		Returns the PCI bus address of the allocated resource
+ * @supports_64bit:	Whether to allow allocations above the 32-bit boundary
+ * @return 0 if successful, -1 on failure
+ */
 int pciauto_region_allocate(struct pci_region *res, pci_size_t size,
-			    pci_addr_t *bar);
+			    pci_addr_t *bar, bool supports_64bit);
 
 #if !defined(CONFIG_DM_PCI) || defined(CONFIG_DM_PCI_COMPAT)
 extern int pci_hose_read_config_byte_via_dword(struct pci_controller *hose,
diff --git a/include/serial.h b/include/serial.h
index 384df94..b9ef6d9 100644
--- a/include/serial.h
+++ b/include/serial.h
@@ -67,6 +67,12 @@
 
 struct udevice;
 
+enum serial_par {
+	SERIAL_PAR_NONE,
+	SERIAL_PAR_ODD,
+	SERIAL_PAR_EVEN
+};
+
 /**
  * struct struct dm_serial_ops - Driver model serial operations
  *
@@ -143,6 +149,16 @@
 	 */
 	int (*loop)(struct udevice *dev, int on);
 #endif
+	/**
+	 * setparity() - Set up the parity
+	 *
+	 * Set up a new parity for this device.
+	 *
+	 * @dev: Device pointer
+	 * @parity: parity to use
+	 * @return 0 if OK, -ve on error
+	 */
+	int (*setparity)(struct udevice *dev, enum serial_par parity);
 };
 
 /**
diff --git a/include/smbios.h b/include/smbios.h
index 79880ef..97b9ddc 100644
--- a/include/smbios.h
+++ b/include/smbios.h
@@ -231,8 +231,9 @@
  *
  * This writes SMBIOS table at a given address.
  *
- * @addr:	start address to write SMBIOS table
- * @return:	end address of SMBIOS table
+ * @addr:	start address to write SMBIOS table. If this is not
+ *	16-byte-aligned then it will be aligned before the table is written
+ * @return:	end address of SMBIOS table (and start address for next entry)
  */
 ulong write_smbios_table(ulong addr);
 
diff --git a/include/tpm-common.h b/include/tpm-common.h
new file mode 100644
index 0000000..734c2c9
--- /dev/null
+++ b/include/tpm-common.h
@@ -0,0 +1,217 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2013 The Chromium OS Authors.
+ * Coypright (c) 2013 Guntermann & Drunck GmbH
+ */
+
+#ifndef __TPM_COMMON_H
+#define __TPM_COMMON_H
+
+enum tpm_duration {
+	TPM_SHORT = 0,
+	TPM_MEDIUM = 1,
+	TPM_LONG = 2,
+	TPM_UNDEFINED,
+
+	TPM_DURATION_COUNT,
+};
+
+/*
+ * Here is a partial implementation of TPM commands.  Please consult TCG Main
+ * Specification for definitions of TPM commands.
+ */
+
+#define TPM_HEADER_SIZE		10
+
+/* Max buffer size supported by our tpm */
+#define TPM_DEV_BUFSIZE		1260
+
+/**
+ * struct tpm_chip_priv - Information about a TPM, stored by the uclass
+ *
+ * These values must be set up by the device's probe() method before
+ * communcation is attempted. If the device has an xfer() method, this is
+ * not needed. There is no need to set up @buf.
+ *
+ * @duration_ms:	Length of each duration type in milliseconds
+ * @retry_time_ms:	Time to wait before retrying receive
+ * @pcr_count:		Number of PCR per bank
+ * @pcr_select_min:	Minimum size in bytes of the pcrSelect array
+ * @buf:		Buffer used during the exchanges with the chip
+ */
+struct tpm_chip_priv {
+	uint duration_ms[TPM_DURATION_COUNT];
+	uint retry_time_ms;
+#if defined(CONFIG_TPM_V2)
+	uint pcr_count;
+	uint pcr_select_min;
+#endif
+	u8 buf[TPM_DEV_BUFSIZE + sizeof(u8)];  /* Max buffer size + addr */
+};
+
+/**
+ * struct tpm_ops - low-level TPM operations
+ *
+ * These are designed to avoid loops and delays in the driver itself. These
+ * should be handled in the uclass.
+ *
+ * In gneral you should implement everything except xfer(). Where you need
+ * complete control of the transfer, then xfer() can be provided and will
+ * override the other methods.
+ *
+ * This interface is for low-level TPM access. It does not understand the
+ * concept of localities or the various TPM messages. That interface is
+ * defined in the functions later on in this file, but they all translate
+ * to bytes which are sent and received.
+ */
+struct tpm_ops {
+	/**
+	 * open() - Request access to locality 0 for the caller
+	 *
+	 * After all commands have been completed the caller should call
+	 * close().
+	 *
+	 * @dev:	Device to close
+	 * @return 0 ok OK, -ve on error
+	 */
+	int (*open)(struct udevice *dev);
+
+	/**
+	 * close() - Close the current session
+	 *
+	 * Releasing the locked locality. Returns 0 on success, -ve 1 on
+	 * failure (in case lock removal did not succeed).
+	 *
+	 * @dev:	Device to close
+	 * @return 0 ok OK, -ve on error
+	 */
+	int (*close)(struct udevice *dev);
+
+	/**
+	 * get_desc() - Get a text description of the TPM
+	 *
+	 * @dev:	Device to check
+	 * @buf:	Buffer to put the string
+	 * @size:	Maximum size of buffer
+	 * @return length of string, or -ENOSPC it no space
+	 */
+	int (*get_desc)(struct udevice *dev, char *buf, int size);
+
+	/**
+	 * send() - send data to the TPM
+	 *
+	 * @dev:	Device to talk to
+	 * @sendbuf:	Buffer of the data to send
+	 * @send_size:	Size of the data to send
+	 *
+	 * Returns 0 on success or -ve on failure.
+	 */
+	int (*send)(struct udevice *dev, const u8 *sendbuf, size_t send_size);
+
+	/**
+	 * recv() - receive a response from the TPM
+	 *
+	 * @dev:	Device to talk to
+	 * @recvbuf:	Buffer to save the response to
+	 * @max_size:	Maximum number of bytes to receive
+	 *
+	 * Returns number of bytes received on success, -EAGAIN if the TPM
+	 * response is not ready, -EINTR if cancelled, or other -ve value on
+	 * failure.
+	 */
+	int (*recv)(struct udevice *dev, u8 *recvbuf, size_t max_size);
+
+	/**
+	 * cleanup() - clean up after an operation in progress
+	 *
+	 * This is called if receiving times out. The TPM may need to abort
+	 * the current transaction if it did not complete, and make itself
+	 * ready for another.
+	 *
+	 * @dev:	Device to talk to
+	 */
+	int (*cleanup)(struct udevice *dev);
+
+	/**
+	 * xfer() - send data to the TPM and get response
+	 *
+	 * This method is optional. If it exists it is used in preference
+	 * to send(), recv() and cleanup(). It should handle all aspects of
+	 * TPM communication for a single transfer.
+	 *
+	 * @dev:	Device to talk to
+	 * @sendbuf:	Buffer of the data to send
+	 * @send_size:	Size of the data to send
+	 * @recvbuf:	Buffer to save the response to
+	 * @recv_size:	Pointer to the size of the response buffer
+	 *
+	 * Returns 0 on success (and places the number of response bytes at
+	 * recv_size) or -ve on failure.
+	 */
+	int (*xfer)(struct udevice *dev, const u8 *sendbuf, size_t send_size,
+		    u8 *recvbuf, size_t *recv_size);
+};
+
+#define tpm_get_ops(dev)        ((struct tpm_ops *)device_get_ops(dev))
+
+#define MAKE_TPM_CMD_ENTRY(cmd) \
+	U_BOOT_CMD_MKENT(cmd, 0, 1, do_tpm_ ## cmd, "", "")
+
+#define TPM_COMMAND_NO_ARG(cmd)				\
+int do_##cmd(cmd_tbl_t *cmdtp, int flag,		\
+	     int argc, char * const argv[])		\
+{							\
+	if (argc != 1)					\
+		return CMD_RET_USAGE;			\
+	return report_return_code(cmd());		\
+}
+
+/**
+ * tpm_get_desc() - Get a text description of the TPM
+ *
+ * @dev:	Device to check
+ * @buf:	Buffer to put the string
+ * @size:	Maximum size of buffer
+ * @return length of string, or -ENOSPC it no space
+ */
+int tpm_get_desc(struct udevice *dev, char *buf, int size);
+
+/**
+ * tpm_xfer() - send data to the TPM and get response
+ *
+ * This first uses the device's send() method to send the bytes. Then it calls
+ * recv() to get the reply. If recv() returns -EAGAIN then it will delay a
+ * short time and then call recv() again.
+ *
+ * Regardless of whether recv() completes successfully, it will then call
+ * cleanup() to finish the transaction.
+ *
+ * Note that the outgoing data is inspected to determine command type
+ * (ordinal) and a timeout is used for that command type.
+ *
+ * @sendbuf - buffer of the data to send
+ * @send_size size of the data to send
+ * @recvbuf - memory to save the response to
+ * @recv_len - pointer to the size of the response buffer
+ *
+ * Returns 0 on success (and places the number of response bytes at
+ * recv_len) or -ve on failure.
+ */
+int tpm_xfer(struct udevice *dev, const u8 *sendbuf, size_t send_size,
+	     u8 *recvbuf, size_t *recv_size);
+
+/**
+ * Initialize TPM device.  It must be called before any TPM commands.
+ *
+ * @return 0 on success, non-0 on error.
+ */
+int tpm_init(void);
+
+/**
+ * Retrieve the array containing all the commands.
+ *
+ * @return a cmd_tbl_t array.
+ */
+cmd_tbl_t *get_tpm_commands(unsigned int *size);
+
+#endif /* __TPM_COMMON_H */
diff --git a/include/tpm.h b/include/tpm-v1.h
similarity index 60%
rename from include/tpm.h
rename to include/tpm-v1.h
index c631632..6b4941e 100644
--- a/include/tpm.h
+++ b/include/tpm-v1.h
@@ -4,23 +4,22 @@
  * Coypright (c) 2013 Guntermann & Drunck GmbH
  */
 
-#ifndef __TPM_H
-#define __TPM_H
+#ifndef __TPM_V1_H
+#define __TPM_V1_H
 
-/*
- * Here is a partial implementation of TPM commands.  Please consult TCG Main
- * Specification for definitions of TPM commands.
- */
+#include <tpm-common.h>
 
-#define TPM_HEADER_SIZE		10
-
-enum tpm_duration {
-	TPM_SHORT = 0,
-	TPM_MEDIUM = 1,
-	TPM_LONG = 2,
-	TPM_UNDEFINED,
-
-	TPM_DURATION_COUNT,
+/* Useful constants */
+enum {
+	TPM_REQUEST_HEADER_LENGTH	= 10,
+	TPM_RESPONSE_HEADER_LENGTH	= 10,
+	PCR_DIGEST_LENGTH		= 20,
+	DIGEST_LENGTH			= 20,
+	TPM_REQUEST_AUTH_LENGTH		= 45,
+	TPM_RESPONSE_AUTH_LENGTH	= 41,
+	/* some max lengths, valid for RSA keys <= 2048 bits */
+	TPM_KEY12_MAX_LENGTH		= 618,
+	TPM_PUBKEY_MAX_LENGTH		= 288,
 };
 
 enum tpm_startup_type {
@@ -82,13 +81,13 @@
 	TPM_CAP_VERSION_VAL	= 0x0000001A,
 };
 
-#define TPM_NV_PER_GLOBALLOCK		(1U << 15)
-#define TPM_NV_PER_PPREAD		(1U << 16)
-#define TPM_NV_PER_PPWRITE		(1U << 0)
-#define TPM_NV_PER_READ_STCLEAR		(1U << 31)
-#define TPM_NV_PER_WRITE_STCLEAR	(1U << 14)
-#define TPM_NV_PER_WRITEDEFINE		(1U << 13)
-#define TPM_NV_PER_WRITEALL		(1U << 12)
+#define TPM_NV_PER_GLOBALLOCK		BIT(15)
+#define TPM_NV_PER_PPREAD		BIT(16)
+#define TPM_NV_PER_PPWRITE		BIT(0)
+#define TPM_NV_PER_READ_STCLEAR		BIT(31)
+#define TPM_NV_PER_WRITE_STCLEAR	BIT(14)
+#define TPM_NV_PER_WRITEDEFINE		BIT(13)
+#define TPM_NV_PER_WRITEALL		BIT(12)
 
 enum {
 	TPM_PUBEK_SIZE			= 256,
@@ -232,211 +231,27 @@
 	u8	disable_full_da_logic_info;
 } __packed;
 
-/* Max buffer size supported by our tpm */
-#define TPM_DEV_BUFSIZE		1260
-
-/**
- * struct tpm_chip_priv - Information about a TPM, stored by the uclass
- *
- * These values must be set up by the device's probe() method before
- * communcation is attempted. If the device has an xfer() method, this is
- * not needed. There is no need to set up @buf.
- *
- * @duration_ms:	Length of each duration type in milliseconds
- * @retry_time_ms:	Time to wait before retrying receive
- */
-struct tpm_chip_priv {
-	uint duration_ms[TPM_DURATION_COUNT];
-	uint retry_time_ms;
-	u8 buf[TPM_DEV_BUFSIZE + sizeof(u8)];  /* Max buffer size + addr */
-};
-
-/**
- * struct tpm_ops - low-level TPM operations
- *
- * These are designed to avoid loops and delays in the driver itself. These
- * should be handled in the uclass.
- *
- * In gneral you should implement everything except xfer(). Where you need
- * complete control of the transfer, then xfer() can be provided and will
- * override the other methods.
- *
- * This interface is for low-level TPM access. It does not understand the
- * concept of localities or the various TPM messages. That interface is
- * defined in the functions later on in this file, but they all translate
- * to bytes which are sent and received.
- */
-struct tpm_ops {
-	/**
-	 * open() - Request access to locality 0 for the caller
-	 *
-	 * After all commands have been completed the caller should call
-	 * close().
-	 *
-	 * @dev:	Device to close
-	 * @return 0 ok OK, -ve on error
-	 */
-	int (*open)(struct udevice *dev);
-
-	/**
-	 * close() - Close the current session
-	 *
-	 * Releasing the locked locality. Returns 0 on success, -ve 1 on
-	 * failure (in case lock removal did not succeed).
-	 *
-	 * @dev:	Device to close
-	 * @return 0 ok OK, -ve on error
-	 */
-	int (*close)(struct udevice *dev);
-
-	/**
-	 * get_desc() - Get a text description of the TPM
-	 *
-	 * @dev:	Device to check
-	 * @buf:	Buffer to put the string
-	 * @size:	Maximum size of buffer
-	 * @return length of string, or -ENOSPC it no space
-	 */
-	int (*get_desc)(struct udevice *dev, char *buf, int size);
-
-	/**
-	 * send() - send data to the TPM
-	 *
-	 * @dev:	Device to talk to
-	 * @sendbuf:	Buffer of the data to send
-	 * @send_size:	Size of the data to send
-	 *
-	 * Returns 0 on success or -ve on failure.
-	 */
-	int (*send)(struct udevice *dev, const uint8_t *sendbuf,
-		    size_t send_size);
-
-	/**
-	 * recv() - receive a response from the TPM
-	 *
-	 * @dev:	Device to talk to
-	 * @recvbuf:	Buffer to save the response to
-	 * @max_size:	Maximum number of bytes to receive
-	 *
-	 * Returns number of bytes received on success, -EAGAIN if the TPM
-	 * response is not ready, -EINTR if cancelled, or other -ve value on
-	 * failure.
-	 */
-	int (*recv)(struct udevice *dev, uint8_t *recvbuf, size_t max_size);
-
-	/**
-	 * cleanup() - clean up after an operation in progress
-	 *
-	 * This is called if receiving times out. The TPM may need to abort
-	 * the current transaction if it did not complete, and make itself
-	 * ready for another.
-	 *
-	 * @dev:	Device to talk to
-	 */
-	int (*cleanup)(struct udevice *dev);
-
-	/**
-	 * xfer() - send data to the TPM and get response
-	 *
-	 * This method is optional. If it exists it is used in preference
-	 * to send(), recv() and cleanup(). It should handle all aspects of
-	 * TPM communication for a single transfer.
-	 *
-	 * @dev:	Device to talk to
-	 * @sendbuf:	Buffer of the data to send
-	 * @send_size:	Size of the data to send
-	 * @recvbuf:	Buffer to save the response to
-	 * @recv_size:	Pointer to the size of the response buffer
-	 *
-	 * Returns 0 on success (and places the number of response bytes at
-	 * recv_size) or -ve on failure.
-	 */
-	int (*xfer)(struct udevice *dev, const uint8_t *sendbuf,
-		    size_t send_size, uint8_t *recvbuf, size_t *recv_size);
-};
-
-#define tpm_get_ops(dev)        ((struct tpm_ops *)device_get_ops(dev))
-
-/**
- * tpm_open() - Request access to locality 0 for the caller
- *
- * After all commands have been completed the caller is supposed to
- * call tpm_close().
- *
- * Returns 0 on success, -ve on failure.
- */
-int tpm_open(struct udevice *dev);
-
-/**
- * tpm_close() - Close the current session
- *
- * Releasing the locked locality. Returns 0 on success, -ve 1 on
- * failure (in case lock removal did not succeed).
- */
-int tpm_close(struct udevice *dev);
-
-/**
- * tpm_get_desc() - Get a text description of the TPM
- *
- * @dev:	Device to check
- * @buf:	Buffer to put the string
- * @size:	Maximum size of buffer
- * @return length of string, or -ENOSPC it no space
- */
-int tpm_get_desc(struct udevice *dev, char *buf, int size);
-
-/**
- * tpm_xfer() - send data to the TPM and get response
- *
- * This first uses the device's send() method to send the bytes. Then it calls
- * recv() to get the reply. If recv() returns -EAGAIN then it will delay a
- * short time and then call recv() again.
- *
- * Regardless of whether recv() completes successfully, it will then call
- * cleanup() to finish the transaction.
- *
- * Note that the outgoing data is inspected to determine command type
- * (ordinal) and a timeout is used for that command type.
- *
- * @sendbuf - buffer of the data to send
- * @send_size size of the data to send
- * @recvbuf - memory to save the response to
- * @recv_len - pointer to the size of the response buffer
- *
- * Returns 0 on success (and places the number of response bytes at
- * recv_len) or -ve on failure.
- */
-int tpm_xfer(struct udevice *dev, const uint8_t *sendbuf, size_t send_size,
-	     uint8_t *recvbuf, size_t *recv_size);
-
-/**
- * Initialize TPM device.  It must be called before any TPM commands.
- *
- * @return 0 on success, non-0 on error.
- */
-int tpm_init(void);
-
 /**
  * Issue a TPM_Startup command.
  *
  * @param mode		TPM startup mode
  * @return return code of the operation
  */
-uint32_t tpm_startup(enum tpm_startup_type mode);
+u32 tpm_startup(enum tpm_startup_type mode);
 
 /**
  * Issue a TPM_SelfTestFull command.
  *
  * @return return code of the operation
  */
-uint32_t tpm_self_test_full(void);
+u32 tpm_self_test_full(void);
 
 /**
  * Issue a TPM_ContinueSelfTest command.
  *
  * @return return code of the operation
  */
-uint32_t tpm_continue_self_test(void);
+u32 tpm_continue_self_test(void);
 
 /**
  * Issue a TPM_NV_DefineSpace command.  The implementation is limited
@@ -448,7 +263,7 @@
  * @param size		size of the area
  * @return return code of the operation
  */
-uint32_t tpm_nv_define_space(uint32_t index, uint32_t perm, uint32_t size);
+u32 tpm_nv_define_space(u32 index, u32 perm, u32 size);
 
 /**
  * Issue a TPM_NV_ReadValue command.  This implementation is limited
@@ -460,7 +275,7 @@
  * @param count		size of output buffer
  * @return return code of the operation
  */
-uint32_t tpm_nv_read_value(uint32_t index, void *data, uint32_t count);
+u32 tpm_nv_read_value(u32 index, void *data, u32 count);
 
 /**
  * Issue a TPM_NV_WriteValue command.  This implementation is limited
@@ -472,7 +287,7 @@
  * @param length	length of data bytes of input buffer
  * @return return code of the operation
  */
-uint32_t tpm_nv_write_value(uint32_t index, const void *data, uint32_t length);
+u32 tpm_nv_write_value(u32 index, const void *data, u32 length);
 
 /**
  * Issue a TPM_Extend command.
@@ -484,7 +299,7 @@
  *			command
  * @return return code of the operation
  */
-uint32_t tpm_extend(uint32_t index, const void *in_digest, void *out_digest);
+u32 tpm_extend(u32 index, const void *in_digest, void *out_digest);
 
 /**
  * Issue a TPM_PCRRead command.
@@ -494,7 +309,7 @@
  * @param count		size of output buffer
  * @return return code of the operation
  */
-uint32_t tpm_pcr_read(uint32_t index, void *data, size_t count);
+u32 tpm_pcr_read(u32 index, void *data, size_t count);
 
 /**
  * Issue a TSC_PhysicalPresence command.  TPM physical presence flag
@@ -503,37 +318,37 @@
  * @param presence	TPM physical presence flag
  * @return return code of the operation
  */
-uint32_t tpm_tsc_physical_presence(uint16_t presence);
+u32 tpm_tsc_physical_presence(u16 presence);
 
 /**
  * Issue a TPM_ReadPubek command.
  *
  * @param data		output buffer for the public endorsement key
- * @param count		size of ouput buffer
+ * @param count		size of output buffer
  * @return return code of the operation
  */
-uint32_t tpm_read_pubek(void *data, size_t count);
+u32 tpm_read_pubek(void *data, size_t count);
 
 /**
  * Issue a TPM_ForceClear command.
  *
  * @return return code of the operation
  */
-uint32_t tpm_force_clear(void);
+u32 tpm_force_clear(void);
 
 /**
  * Issue a TPM_PhysicalEnable command.
  *
  * @return return code of the operation
  */
-uint32_t tpm_physical_enable(void);
+u32 tpm_physical_enable(void);
 
 /**
  * Issue a TPM_PhysicalDisable command.
  *
  * @return return code of the operation
  */
-uint32_t tpm_physical_disable(void);
+u32 tpm_physical_disable(void);
 
 /**
  * Issue a TPM_PhysicalSetDeactivated command.
@@ -541,7 +356,7 @@
  * @param state		boolean state of the deactivated flag
  * @return return code of the operation
  */
-uint32_t tpm_physical_set_deactivated(uint8_t state);
+u32 tpm_physical_set_deactivated(u8 state);
 
 /**
  * Issue a TPM_GetCapability command.  This implementation is limited
@@ -551,22 +366,21 @@
  * @param sub_cap	further definition of capability, which is
  *			limited to be 4-byte wide
  * @param cap		output buffer for capability information
- * @param count		size of ouput buffer
+ * @param count		size of output buffer
  * @return return code of the operation
  */
-uint32_t tpm_get_capability(uint32_t cap_area, uint32_t sub_cap,
-		void *cap, size_t count);
+u32 tpm_get_capability(u32 cap_area, u32 sub_cap, void *cap, size_t count);
 
 /**
- * Issue a TPM_FlushSpecific command for a AUTH ressource.
+ * Issue a TPM_FlushSpecific command for a AUTH resource.
  *
  * @param auth_handle	handle of the auth session
  * @return return code of the operation
  */
-uint32_t tpm_terminate_auth_session(uint32_t auth_handle);
+u32 tpm_terminate_auth_session(u32 auth_handle);
 
 /**
- * Issue a TPM_OIAP command to setup an object independant authorization
+ * Issue a TPM_OIAP command to setup an object independent authorization
  * session.
  * Information about the session is stored internally.
  * If there was already an OIAP session active it is terminated and a new
@@ -575,14 +389,14 @@
  * @param auth_handle	pointer to the (new) auth handle or NULL.
  * @return return code of the operation
  */
-uint32_t tpm_oiap(uint32_t *auth_handle);
+u32 tpm_oiap(u32 *auth_handle);
 
 /**
  * Ends an active OIAP session.
  *
  * @return return code of the operation
  */
-uint32_t tpm_end_oiap(void);
+u32 tpm_end_oiap(void);
 
 /**
  * Issue a TPM_LoadKey2 (Auth1) command using an OIAP session for authenticating
@@ -595,10 +409,8 @@
  * @param key_handle	pointer to the key handle
  * @return return code of the operation
  */
-uint32_t tpm_load_key2_oiap(uint32_t parent_handle,
-		const void *key, size_t key_length,
-		const void *parent_key_usage_auth,
-		uint32_t *key_handle);
+u32 tpm_load_key2_oiap(u32 parent_handle, const void *key, size_t key_length,
+		       const void *parent_key_usage_auth, u32 *key_handle);
 
 /**
  * Issue a TPM_GetPubKey (Auth1) command using an OIAP session for
@@ -613,8 +425,8 @@
  *			of the stored TPM_PUBKEY structure (iff pubkey != NULL).
  * @return return code of the operation
  */
-uint32_t tpm_get_pub_key_oiap(uint32_t key_handle, const void *usage_auth,
-		void *pubkey, size_t *pubkey_len);
+u32 tpm_get_pub_key_oiap(u32 key_handle, const void *usage_auth, void *pubkey,
+			 size_t *pubkey_len);
 
 /**
  * Get the TPM permanent flags value
@@ -622,7 +434,7 @@
  * @param pflags	Place to put permanent flags
  * @return return code of the operation
  */
-uint32_t tpm_get_permanent_flags(struct tpm_permanent_flags *pflags);
+u32 tpm_get_permanent_flags(struct tpm_permanent_flags *pflags);
 
 /**
  * Get the TPM permissions
@@ -630,7 +442,7 @@
  * @param perm		Returns permissions value
  * @return return code of the operation
  */
-uint32_t tpm_get_permissions(uint32_t index, uint32_t *perm);
+u32 tpm_get_permissions(u32 index, u32 *perm);
 
 /**
  * Flush a resource with a given handle and type from the TPM
@@ -639,7 +451,7 @@
  * @param resource_type                type of the resource
  * @return return code of the operation
  */
-uint32_t tpm_flush_specific(uint32_t key_handle, uint32_t resource_type);
+u32 tpm_flush_specific(u32 key_handle, u32 resource_type);
 
 #ifdef CONFIG_TPM_LOAD_KEY_BY_SHA1
 /**
@@ -650,8 +462,8 @@
  * @param[out] handle	The handle of the key (Non-null iff found)
  * @return 0 if key was found in TPM; != 0 if not.
  */
-uint32_t tpm_find_key_sha1(const uint8_t auth[20], const uint8_t
-			   pubkey_digest[20], uint32_t *handle);
+u32 tpm_find_key_sha1(const u8 auth[20], const u8 pubkey_digest[20],
+		      u32 *handle);
 #endif /* CONFIG_TPM_LOAD_KEY_BY_SHA1 */
 
 /**
@@ -663,6 +475,6 @@
  * @param count		size of output buffer
  * @return return code of the operation
  */
-uint32_t tpm_get_random(void *data, uint32_t count);
+u32 tpm_get_random(void *data, u32 count);
 
-#endif /* __TPM_H */
+#endif /* __TPM_V1_H */
diff --git a/include/tpm-v2.h b/include/tpm-v2.h
new file mode 100644
index 0000000..780e061
--- /dev/null
+++ b/include/tpm-v2.h
@@ -0,0 +1,262 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2018 Bootlin
+ * Author: Miquel Raynal <miquel.raynal@bootlin.com>
+ */
+
+#ifndef __TPM_V2_H
+#define __TPM_V2_H
+
+#include <tpm-common.h>
+
+#define TPM2_DIGEST_LEN		32
+
+/**
+ * TPM2 Structure Tags for command/response buffers.
+ *
+ * @TPM2_ST_NO_SESSIONS: the command does not need an authentication.
+ * @TPM2_ST_SESSIONS: the command needs an authentication.
+ */
+enum tpm2_structures {
+	TPM2_ST_NO_SESSIONS	= 0x8001,
+	TPM2_ST_SESSIONS	= 0x8002,
+};
+
+/**
+ * TPM2 type of boolean.
+ */
+enum tpm2_yes_no {
+	TPMI_YES		= 1,
+	TPMI_NO			= 0,
+};
+
+/**
+ * TPM2 startup values.
+ *
+ * @TPM2_SU_CLEAR: reset the internal state.
+ * @TPM2_SU_STATE: restore saved state (if any).
+ */
+enum tpm2_startup_types {
+	TPM2_SU_CLEAR		= 0x0000,
+	TPM2_SU_STATE		= 0x0001,
+};
+
+/**
+ * TPM2 permanent handles.
+ *
+ * @TPM2_RH_OWNER: refers to the 'owner' hierarchy.
+ * @TPM2_RS_PW: indicates a password.
+ * @TPM2_RH_LOCKOUT: refers to the 'lockout' hierarchy.
+ * @TPM2_RH_ENDORSEMENT: refers to the 'endorsement' hierarchy.
+ * @TPM2_RH_PLATFORM: refers to the 'platform' hierarchy.
+ */
+enum tpm2_handles {
+	TPM2_RH_OWNER		= 0x40000001,
+	TPM2_RS_PW		= 0x40000009,
+	TPM2_RH_LOCKOUT		= 0x4000000A,
+	TPM2_RH_ENDORSEMENT	= 0x4000000B,
+	TPM2_RH_PLATFORM	= 0x4000000C,
+};
+
+/**
+ * TPM2 command codes used at the beginning of a buffer, gives the command.
+ *
+ * @TPM2_CC_STARTUP: TPM2_Startup().
+ * @TPM2_CC_SELF_TEST: TPM2_SelfTest().
+ * @TPM2_CC_CLEAR: TPM2_Clear().
+ * @TPM2_CC_CLEARCONTROL: TPM2_ClearControl().
+ * @TPM2_CC_HIERCHANGEAUTH: TPM2_HierarchyChangeAuth().
+ * @TPM2_CC_PCR_SETAUTHPOL: TPM2_PCR_SetAuthPolicy().
+ * @TPM2_CC_DAM_RESET: TPM2_DictionaryAttackLockReset().
+ * @TPM2_CC_DAM_PARAMETERS: TPM2_DictionaryAttackParameters().
+ * @TPM2_CC_GET_CAPABILITY: TPM2_GetCapibility().
+ * @TPM2_CC_PCR_READ: TPM2_PCR_Read().
+ * @TPM2_CC_PCR_EXTEND: TPM2_PCR_Extend().
+ * @TPM2_CC_PCR_SETAUTHVAL: TPM2_PCR_SetAuthValue().
+ */
+enum tpm2_command_codes {
+	TPM2_CC_STARTUP		= 0x0144,
+	TPM2_CC_SELF_TEST	= 0x0143,
+	TPM2_CC_CLEAR		= 0x0126,
+	TPM2_CC_CLEARCONTROL	= 0x0127,
+	TPM2_CC_HIERCHANGEAUTH	= 0x0129,
+	TPM2_CC_PCR_SETAUTHPOL	= 0x012C,
+	TPM2_CC_DAM_RESET	= 0x0139,
+	TPM2_CC_DAM_PARAMETERS	= 0x013A,
+	TPM2_CC_GET_CAPABILITY	= 0x017A,
+	TPM2_CC_PCR_READ	= 0x017E,
+	TPM2_CC_PCR_EXTEND	= 0x0182,
+	TPM2_CC_PCR_SETAUTHVAL	= 0x0183,
+};
+
+/**
+ * TPM2 return codes.
+ */
+enum tpm2_return_codes {
+	TPM2_RC_SUCCESS		= 0x0000,
+	TPM2_RC_BAD_TAG		= 0x001E,
+	TPM2_RC_FMT1		= 0x0080,
+	TPM2_RC_HASH		= TPM2_RC_FMT1 + 0x0003,
+	TPM2_RC_VALUE		= TPM2_RC_FMT1 + 0x0004,
+	TPM2_RC_SIZE		= TPM2_RC_FMT1 + 0x0015,
+	TPM2_RC_BAD_AUTH	= TPM2_RC_FMT1 + 0x0022,
+	TPM2_RC_HANDLE		= TPM2_RC_FMT1 + 0x000B,
+	TPM2_RC_VER1		= 0x0100,
+	TPM2_RC_INITIALIZE	= TPM2_RC_VER1 + 0x0000,
+	TPM2_RC_FAILURE		= TPM2_RC_VER1 + 0x0001,
+	TPM2_RC_DISABLED	= TPM2_RC_VER1 + 0x0020,
+	TPM2_RC_AUTH_MISSING	= TPM2_RC_VER1 + 0x0025,
+	TPM2_RC_COMMAND_CODE	= TPM2_RC_VER1 + 0x0043,
+	TPM2_RC_AUTHSIZE	= TPM2_RC_VER1 + 0x0044,
+	TPM2_RC_AUTH_CONTEXT	= TPM2_RC_VER1 + 0x0045,
+	TPM2_RC_NEEDS_TEST	= TPM2_RC_VER1 + 0x0053,
+	TPM2_RC_WARN		= 0x0900,
+	TPM2_RC_TESTING		= TPM2_RC_WARN + 0x000A,
+	TPM2_RC_REFERENCE_H0	= TPM2_RC_WARN + 0x0010,
+	TPM2_RC_LOCKOUT		= TPM2_RC_WARN + 0x0021,
+};
+
+/**
+ * TPM2 algorithms.
+ */
+enum tpm2_algorithms {
+	TPM2_ALG_XOR		= 0x0A,
+	TPM2_ALG_SHA256		= 0x0B,
+	TPM2_ALG_SHA384		= 0x0C,
+	TPM2_ALG_SHA512		= 0x0D,
+	TPM2_ALG_NULL		= 0x10,
+};
+
+/**
+ * Issue a TPM2_Startup command.
+ *
+ * @mode	TPM startup mode
+ *
+ * @return code of the operation
+ */
+u32 tpm2_startup(enum tpm2_startup_types mode);
+
+/**
+ * Issue a TPM2_SelfTest command.
+ *
+ * @full_test	Asking to perform all tests or only the untested ones
+ *
+ * @return code of the operation
+ */
+u32 tpm2_self_test(enum tpm2_yes_no full_test);
+
+/**
+ * Issue a TPM2_Clear command.
+ *
+ * @handle	Handle
+ * @pw		Password
+ * @pw_sz	Length of the password
+ *
+ * @return code of the operation
+ */
+u32 tpm2_clear(u32 handle, const char *pw, const ssize_t pw_sz);
+
+/**
+ * Issue a TPM2_PCR_Extend command.
+ *
+ * @index	Index of the PCR
+ * @digest	Value representing the event to be recorded
+ *
+ * @return code of the operation
+ */
+u32 tpm2_pcr_extend(u32 index, const uint8_t *digest);
+
+/**
+ * Issue a TPM2_PCR_Read command.
+ *
+ * @idx		Index of the PCR
+ * @idx_min_sz	Minimum size in bytes of the pcrSelect array
+ * @data	Output buffer for contents of the named PCR
+ * @updates	Optional out parameter: number of updates for this PCR
+ *
+ * @return code of the operation
+ */
+u32 tpm2_pcr_read(u32 idx, unsigned int idx_min_sz, void *data,
+		  unsigned int *updates);
+
+/**
+ * Issue a TPM2_GetCapability command.  This implementation is limited
+ * to query property index that is 4-byte wide.
+ *
+ * @capability	Partition of capabilities
+ * @property	Further definition of capability, limited to be 4 bytes wide
+ * @buf		Output buffer for capability information
+ * @prop_count	Size of output buffer
+ *
+ * @return code of the operation
+ */
+u32 tpm2_get_capability(u32 capability, u32 property, void *buf,
+			size_t prop_count);
+
+/**
+ * Issue a TPM2_DictionaryAttackLockReset command.
+ *
+ * @pw		Password
+ * @pw_sz	Length of the password
+ *
+ * @return code of the operation
+ */
+u32 tpm2_dam_reset(const char *pw, const ssize_t pw_sz);
+
+/**
+ * Issue a TPM2_DictionaryAttackParameters command.
+ *
+ * @pw		Password
+ * @pw_sz	Length of the password
+ * @max_tries	Count of authorizations before lockout
+ * @recovery_time Time before decrementation of the failure count
+ * @lockout_recovery Time to wait after a lockout
+ *
+ * @return code of the operation
+ */
+u32 tpm2_dam_parameters(const char *pw, const ssize_t pw_sz,
+			unsigned int max_tries, unsigned int recovery_time,
+			unsigned int lockout_recovery);
+
+/**
+ * Issue a TPM2_HierarchyChangeAuth command.
+ *
+ * @handle	Handle
+ * @newpw	New password
+ * @newpw_sz	Length of the new password
+ * @oldpw	Old password
+ * @oldpw_sz	Length of the old password
+ *
+ * @return code of the operation
+ */
+int tpm2_change_auth(u32 handle, const char *newpw, const ssize_t newpw_sz,
+		     const char *oldpw, const ssize_t oldpw_sz);
+
+/**
+ * Issue a TPM_PCR_SetAuthPolicy command.
+ *
+ * @pw		Platform password
+ * @pw_sz	Length of the password
+ * @index	Index of the PCR
+ * @digest	New key to access the PCR
+ *
+ * @return code of the operation
+ */
+u32 tpm2_pcr_setauthpolicy(const char *pw, const ssize_t pw_sz, u32 index,
+			   const char *key);
+
+/**
+ * Issue a TPM_PCR_SetAuthValue command.
+ *
+ * @pw		Platform password
+ * @pw_sz	Length of the password
+ * @index	Index of the PCR
+ * @digest	New key to access the PCR
+ * @key_sz	Length of the new key
+ *
+ * @return code of the operation
+ */
+u32 tpm2_pcr_setauthvalue(const char *pw, const ssize_t pw_sz, u32 index,
+			  const char *key, const ssize_t key_sz);
+
+#endif /* __TPM_V2_H */
diff --git a/include/xilinx.h b/include/xilinx.h
index 9429f51..af40bef 100644
--- a/include/xilinx.h
+++ b/include/xilinx.h
@@ -48,6 +48,8 @@
 struct xilinx_fpga_op {
 	int (*load)(xilinx_desc *, const void *, size_t, bitstream_type);
 	int (*loadfs)(xilinx_desc *, const void *, size_t, fpga_fs_info *);
+	int (*loads)(xilinx_desc *desc, const void *buf, size_t bsize,
+		     struct fpga_secure_info *fpga_sec_info);
 	int (*dump)(xilinx_desc *, const void *, size_t);
 	int (*info)(xilinx_desc *);
 };
@@ -60,6 +62,8 @@
 int xilinx_info(xilinx_desc *desc);
 int xilinx_loadfs(xilinx_desc *desc, const void *buf, size_t bsize,
 		  fpga_fs_info *fpga_fsinfo);
+int xilinx_loads(xilinx_desc *desc, const void *buf, size_t bsize,
+		 struct fpga_secure_info *fpga_sec_info);
 
 /* Board specific implementation specific function types
  *********************************************************************/
diff --git a/include/zynqmppl.h b/include/zynqmppl.h
index a0f4e68..5214db9 100644
--- a/include/zynqmppl.h
+++ b/include/zynqmppl.h
@@ -16,6 +16,9 @@
 #define ZYNQMP_FPGA_OP_LOAD			(1 << 1)
 #define ZYNQMP_FPGA_OP_DONE			(1 << 2)
 
+#define ZYNQMP_FPGA_FLAG_AUTHENTICATED		BIT(2)
+#define ZYNQMP_FPGA_FLAG_ENCRYPTED		BIT(3)
+
 #define ZYNQMP_CSU_IDCODE_DEVICE_CODE_SHIFT	15
 #define ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK	(0xf << \
 					ZYNQMP_CSU_IDCODE_DEVICE_CODE_SHIFT)
diff --git a/lib/Kconfig b/lib/Kconfig
index 1590f7a..15c6a52 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -61,6 +61,17 @@
 config TPL_STRTO
 	bool
 
+config IMAGE_SPARSE
+	bool
+
+config IMAGE_SPARSE_FILLBUF_SIZE
+	hex "Android sparse image CHUNK_TYPE_FILL buffer size"
+	default 0x80000
+	depends on IMAGE_SPARSE
+	help
+	  Set the size of the fill buffer used when processing CHUNK_TYPE_FILL
+	  chunks.
+
 config USE_PRIVATE_LIBGCC
 	bool "Use private libgcc"
 	depends on HAVE_PRIVATE_LIBGCC
diff --git a/lib/Makefile b/lib/Makefile
index d531ea5..c0511cb 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -29,6 +29,7 @@
 obj-$(CONFIG_TEST_FDTDEC) += fdtdec_test.o
 obj-$(CONFIG_GZIP_COMPRESSED) += gzip.o
 obj-$(CONFIG_GENERATE_SMBIOS_TABLE) += smbios.o
+obj-$(CONFIG_IMAGE_SPARSE) += image-sparse.o
 obj-y += initcall.o
 obj-$(CONFIG_LMB) += lmb.o
 obj-y += ldiv.o
@@ -39,7 +40,9 @@
 obj-y += qsort.o
 obj-y += rc4.o
 obj-$(CONFIG_SUPPORT_EMMC_RPMB) += sha256.o
-obj-$(CONFIG_TPM) += tpm.o
+obj-$(CONFIG_TPM) += tpm-common.o
+obj-$(CONFIG_TPM_V1) += tpm-v1.o
+obj-$(CONFIG_TPM_V2) += tpm-v2.o
 obj-$(CONFIG_RBTREE)	+= rbtree.o
 obj-$(CONFIG_BITREVERSE) += bitrev.o
 obj-y += list_sort.o
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index d38780b..df58e63 100644
--- a/lib/efi_loader/Kconfig
+++ b/lib/efi_loader/Kconfig
@@ -1,6 +1,6 @@
 config EFI_LOADER
 	bool "Support running EFI Applications in U-Boot"
-	depends on (ARM || X86) && OF_LIBFDT
+	depends on (ARM || X86 || RISCV) && OF_LIBFDT
 	# We do not support bootefi booting ARMv7 in non-secure mode
 	depends on !ARMV7_NONSEC
 	# We need EFI_STUB_64BIT to be set on x86_64 with EFI_STUB
@@ -10,6 +10,7 @@
 	default y
 	select LIB_UUID
 	select HAVE_BLOCK_DEVICE
+	imply CFB_CONSOLE_ANSI
 	help
 	  Select this option if you want to run EFI applications (like grub2)
 	  on top of U-Boot. If this option is enabled, U-Boot will expose EFI
diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c
index 153e173..853358a 100644
--- a/lib/efi_loader/efi_bootmgr.c
+++ b/lib/efi_loader/efi_bootmgr.c
@@ -70,17 +70,17 @@
 
 /* free() the result */
 static void *get_var(u16 *name, const efi_guid_t *vendor,
-		     unsigned long *size)
+		     efi_uintn_t *size)
 {
 	efi_guid_t *v = (efi_guid_t *)vendor;
 	efi_status_t ret;
 	void *buf = NULL;
 
 	*size = 0;
-	EFI_CALL(ret = rs->get_variable((s16 *)name, v, NULL, size, buf));
+	EFI_CALL(ret = rs->get_variable(name, v, NULL, size, buf));
 	if (ret == EFI_BUFFER_TOO_SMALL) {
 		buf = malloc(*size);
-		EFI_CALL(ret = rs->get_variable((s16 *)name, v, NULL, size, buf));
+		EFI_CALL(ret = rs->get_variable(name, v, NULL, size, buf));
 	}
 
 	if (ret != EFI_SUCCESS) {
@@ -104,7 +104,7 @@
 	u16 varname[] = L"Boot0000";
 	u16 hexmap[] = L"0123456789ABCDEF";
 	void *load_option, *image = NULL;
-	unsigned long size;
+	efi_uintn_t size;
 
 	varname[4] = hexmap[(n & 0xf000) >> 12];
 	varname[5] = hexmap[(n & 0x0f00) >> 8];
@@ -147,7 +147,7 @@
 		       struct efi_device_path **file_path)
 {
 	uint16_t *bootorder;
-	unsigned long size;
+	efi_uintn_t size;
 	void *image = NULL;
 	int i, num;
 
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 5715a8b..50d3115 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -10,7 +10,6 @@
 #include <efi_loader.h>
 #include <environment.h>
 #include <malloc.h>
-#include <asm/global_data.h>
 #include <linux/libfdt_env.h>
 #include <u-boot/crc.h>
 #include <bootm.h>
@@ -130,12 +129,15 @@
 #endif
 }
 
-/*
- * Return a string for indenting with two spaces per level. A maximum of ten
- * indent levels is supported. Higher indent levels will be truncated.
+/**
+ * indent_string - returns a string for indenting with two spaces per level
  *
- * @level	indent level
- * @return	indent string
+ * A maximum of ten indent levels is supported. Higher indent levels will be
+ * truncated.
+ *
+ * @level:		indent level
+ * Return Value:	A string for indenting with two spaces per level is
+ *			returned.
  */
 static const char *indent_string(int level)
 {
@@ -161,8 +163,8 @@
 	return indent_string(--nesting_level);
 }
 
-/*
- * Queue an EFI event.
+/**
+ * efi_queue_event - queue an EFI event
  *
  * This function queues the notification function of the event for future
  * execution.
@@ -172,8 +174,8 @@
  *
  * For the SignalEvent service see efi_signal_event_ext.
  *
- * @event	event to signal
- * @check_tpl	check the TPL level
+ * @event:	event to signal
+ * @check_tpl:	check the TPL level
  */
 static void efi_queue_event(struct efi_event *event, bool check_tpl)
 {
@@ -188,8 +190,8 @@
 	event->is_queued = false;
 }
 
-/*
- * Signal an EFI event.
+/**
+ * efi_signal_event - signal an EFI event
  *
  * This function signals an event. If the event belongs to an event group
  * all events of the group are signaled. If they are of type EVT_NOTIFY_SIGNAL
@@ -197,8 +199,8 @@
  *
  * For the SignalEvent service see efi_signal_event_ext.
  *
- * @event	event to signal
- * @check_tpl	check the TPL level
+ * @event:	event to signal
+ * @check_tpl:	check the TPL level
  */
 void efi_signal_event(struct efi_event *event, bool check_tpl)
 {
@@ -232,15 +234,15 @@
 	}
 }
 
-/*
- * Raise the task priority level.
+/**
+ * efi_raise_tpl - raise the task priority level
  *
  * This function implements the RaiseTpl service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @new_tpl	new value of the task priority level
- * @return	old value of the task priority level
+ * @new_tpl:		new value of the task priority level
+ * Return Value:	old value of the task priority level
  */
 static unsigned long EFIAPI efi_raise_tpl(efi_uintn_t new_tpl)
 {
@@ -258,14 +260,14 @@
 	return old_tpl;
 }
 
-/*
- * Lower the task priority level.
+/**
+ * efi_restore_tpl - lower the task priority level
  *
  * This function implements the RestoreTpl service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @old_tpl	value of the task priority level to be restored
+ * @old_tpl:	value of the task priority level to be restored
  */
 static void EFIAPI efi_restore_tpl(efi_uintn_t old_tpl)
 {
@@ -285,18 +287,18 @@
 	EFI_EXIT(EFI_SUCCESS);
 }
 
-/*
- * Allocate memory pages.
+/**
+ * efi_allocate_pages_ext - allocate memory pages
  *
  * This function implements the AllocatePages service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @type		type of allocation to be performed
- * @memory_type		usage type of the allocated memory
- * @pages		number of pages to be allocated
- * @memory		allocated memory
- * @return		status code
+ * @type:		type of allocation to be performed
+ * @memory_type:	usage type of the allocated memory
+ * @pages:		number of pages to be allocated
+ * @memory:		allocated memory
+ * Return Value:	status code
  */
 static efi_status_t EFIAPI efi_allocate_pages_ext(int type, int memory_type,
 						  efi_uintn_t pages,
@@ -309,16 +311,16 @@
 	return EFI_EXIT(r);
 }
 
-/*
- * Free memory pages.
+/**
+ * efi_free_pages_ext - Free memory pages.
  *
  * This function implements the FreePages service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @memory	start of the memory area to be freed
- * @pages	number of pages to be freed
- * @return	status code
+ * @memory:		start of the memory area to be freed
+ * @pages:		number of pages to be freed
+ * Return Value:	status code
  */
 static efi_status_t EFIAPI efi_free_pages_ext(uint64_t memory,
 					      efi_uintn_t pages)
@@ -330,20 +332,20 @@
 	return EFI_EXIT(r);
 }
 
-/*
- * Get map describing memory usage.
+/**
+ * efi_get_memory_map_ext - get map describing memory usage
  *
  * This function implements the GetMemoryMap service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @memory_map_size	on entry the size, in bytes, of the memory map buffer,
+ * @memory_map_size:	on entry the size, in bytes, of the memory map buffer,
  *			on exit the size of the copied memory map
- * @memory_map		buffer to which the memory map is written
- * @map_key		key for the memory map
- * @descriptor_size	size of an individual memory descriptor
- * @descriptor_version	version number of the memory descriptor structure
- * @return		status code
+ * @memory_map:		buffer to which the memory map is written
+ * @map_key:		key for the memory map
+ * @descriptor_size:	size of an individual memory descriptor
+ * @descriptor_version:	version number of the memory descriptor structure
+ * Return Value:	status code
  */
 static efi_status_t EFIAPI efi_get_memory_map_ext(
 					efi_uintn_t *memory_map_size,
@@ -361,17 +363,17 @@
 	return EFI_EXIT(r);
 }
 
-/*
- * Allocate memory from pool.
+/**
+ * efi_allocate_pool_ext - allocate memory from pool
  *
  * This function implements the AllocatePool service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @pool_type	type of the pool from which memory is to be allocated
- * @size	number of bytes to be allocated
- * @buffer	allocated memory
- * @return	status code
+ * @pool_type:		type of the pool from which memory is to be allocated
+ * @size:		number of bytes to be allocated
+ * @buffer:		allocated memory
+ * Return Value:	status code
  */
 static efi_status_t EFIAPI efi_allocate_pool_ext(int pool_type,
 						 efi_uintn_t size,
@@ -384,15 +386,15 @@
 	return EFI_EXIT(r);
 }
 
-/*
- * Free memory from pool.
+/**
+ * efi_free_pool_ext - free memory from pool
  *
  * This function implements the FreePool service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @buffer	start of memory to be freed
- * @return	status code
+ * @buffer:		start of memory to be freed
+ * Return Value:	status code
  */
 static efi_status_t EFIAPI efi_free_pool_ext(void *buffer)
 {
@@ -403,13 +405,13 @@
 	return EFI_EXIT(r);
 }
 
-/*
- * Add a new object to the object list.
+/**
+ * efi_add_handle - add a new object to the object list
  *
  * The protocols list is initialized.
  * The object handle is set.
  *
- * @obj	object to be added
+ * @obj:	object to be added
  */
 void efi_add_handle(struct efi_object *obj)
 {
@@ -420,34 +422,33 @@
 	list_add_tail(&obj->link, &efi_obj_list);
 }
 
-/*
- * Create handle.
+/**
+ * efi_create_handle - create handle
  *
- * @handle	new handle
- * @return	status code
+ * @handle:		new handle
+ * Return Value:	status code
  */
 efi_status_t efi_create_handle(efi_handle_t *handle)
 {
 	struct efi_object *obj;
-	efi_status_t r;
 
-	r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES,
-			      sizeof(struct efi_object),
-			      (void **)&obj);
-	if (r != EFI_SUCCESS)
-		return r;
+	obj = calloc(1, sizeof(struct efi_object));
+	if (!obj)
+		return EFI_OUT_OF_RESOURCES;
+
 	efi_add_handle(obj);
 	*handle = obj->handle;
-	return r;
+
+	return EFI_SUCCESS;
 }
 
-/*
- * Find a protocol on a handle.
+/**
+ * efi_search_protocol - find a protocol on a handle.
  *
- * @handle		handle
- * @protocol_guid	GUID of the protocol
- * @handler		reference to the protocol
- * @return		status code
+ * @handle:		handle
+ * @protocol_guid:	GUID of the protocol
+ * @handler:		reference to the protocol
+ * Return Value:	status code
  */
 efi_status_t efi_search_protocol(const efi_handle_t handle,
 				 const efi_guid_t *protocol_guid,
@@ -474,13 +475,13 @@
 	return EFI_NOT_FOUND;
 }
 
-/*
- * Delete protocol from a handle.
+/**
+ * efi_remove_protocol - delete protocol from a handle
  *
- * @handle			handle from which the protocol shall be deleted
- * @protocol			GUID of the protocol to be deleted
- * @protocol_interface		interface of the protocol implementation
- * @return			status code
+ * @handle:			handle from which the protocol shall be deleted
+ * @protocol:			GUID of the protocol to be deleted
+ * @protocol_interface:		interface of the protocol implementation
+ * Return Value:		status code
  */
 efi_status_t efi_remove_protocol(const efi_handle_t handle,
 				 const efi_guid_t *protocol,
@@ -494,16 +495,18 @@
 		return ret;
 	if (guidcmp(handler->guid, protocol))
 		return EFI_INVALID_PARAMETER;
+	if (handler->protocol_interface != protocol_interface)
+		return EFI_INVALID_PARAMETER;
 	list_del(&handler->link);
 	free(handler);
 	return EFI_SUCCESS;
 }
 
-/*
- * Delete all protocols from a handle.
+/**
+ * efi_remove_all_protocols - delete all protocols from a handle
  *
- * @handle	handle from which the protocols shall be deleted
- * @return	status code
+ * @handle:		handle from which the protocols shall be deleted
+ * Return Value:	status code
  */
 efi_status_t efi_remove_all_protocols(const efi_handle_t handle)
 {
@@ -525,10 +528,10 @@
 	return EFI_SUCCESS;
 }
 
-/*
- * Delete handle.
+/**
+ * efi_delete_handle - delete handle
  *
- * @handle	handle to delete
+ * @obj:	handle to delete
  */
 void efi_delete_handle(struct efi_object *obj)
 {
@@ -539,11 +542,11 @@
 	free(obj);
 }
 
-/*
- * Check if a pointer is a valid event.
+/**
+ * efi_is_event - check if a pointer is a valid event
  *
- * @event		pointer to check
- * @return		status code
+ * @event:		pointer to check
+ * Return Value:	status code
  */
 static efi_status_t efi_is_event(const struct efi_event *event)
 {
@@ -558,20 +561,21 @@
 	return EFI_INVALID_PARAMETER;
 }
 
-/*
- * Create an event.
+/**
+ * efi_create_event - create an event
  *
  * This function is used inside U-Boot code to create an event.
  *
  * For the API function implementing the CreateEvent service see
  * efi_create_event_ext.
  *
- * @type		type of the event to create
- * @notify_tpl		task priority level of the event
- * @notify_function	notification function of the event
- * @notify_context	pointer passed to the notification function
- * @event		created event
- * @return		status code
+ * @type:		type of the event to create
+ * @notify_tpl:		task priority level of the event
+ * @notify_function:	notification function of the event
+ * @notify_context:	pointer passed to the notification function
+ * @group:		event group
+ * @event:		created event
+ * Return Value:	status code
  */
 efi_status_t efi_create_event(uint32_t type, efi_uintn_t notify_tpl,
 			      void (EFIAPI *notify_function) (
@@ -610,20 +614,19 @@
 }
 
 /*
- * Create an event in a group.
+ * efi_create_event_ex - create an event in a group
  *
  * This function implements the CreateEventEx service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
- * TODO: Support event groups
  *
- * @type		type of the event to create
- * @notify_tpl		task priority level of the event
- * @notify_function	notification function of the event
- * @notify_context	pointer passed to the notification function
- * @event		created event
- * @event_group		event group
- * @return		status code
+ * @type:		type of the event to create
+ * @notify_tpl:		task priority level of the event
+ * @notify_function:	notification function of the event
+ * @notify_context:	pointer passed to the notification function
+ * @event:		created event
+ * @event_group:	event group
+ * Return Value:	status code
  */
 efi_status_t EFIAPI efi_create_event_ex(uint32_t type, efi_uintn_t notify_tpl,
 					void (EFIAPI *notify_function) (
@@ -639,19 +642,19 @@
 					 notify_context, event_group, event));
 }
 
-/*
- * Create an event.
+/**
+ * efi_create_event_ext - create an event
  *
  * This function implements the CreateEvent service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @type		type of the event to create
- * @notify_tpl		task priority level of the event
- * @notify_function	notification function of the event
- * @notify_context	pointer passed to the notification function
- * @event		created event
- * @return		status code
+ * @type:		type of the event to create
+ * @notify_tpl:		task priority level of the event
+ * @notify_function:	notification function of the event
+ * @notify_context:	pointer passed to the notification function
+ * @event:		created event
+ * Return Value:	status code
  */
 static efi_status_t EFIAPI efi_create_event_ext(
 			uint32_t type, efi_uintn_t notify_tpl,
@@ -666,7 +669,9 @@
 					 notify_context, NULL, event));
 }
 
-/*
+/**
+ * efi_timer_check - check if a timer event has occurred
+ *
  * Check if a timer event has occurred or a queued notification function should
  * be called.
  *
@@ -699,16 +704,16 @@
 	WATCHDOG_RESET();
 }
 
-/*
- * Set the trigger time for a timer event or stop the event.
+/**
+ * efi_set_timer - set the trigger time for a timer event or stop the event
  *
  * This is the function for internal usage in U-Boot. For the API function
  * implementing the SetTimer service see efi_set_timer_ext.
  *
- * @event		event for which the timer is set
- * @type		type of the timer
- * @trigger_time	trigger period in multiples of 100ns
- * @return		status code
+ * @event:		event for which the timer is set
+ * @type:		type of the timer
+ * @trigger_time:	trigger period in multiples of 100ns
+ * Return Value:		status code
  */
 efi_status_t efi_set_timer(struct efi_event *event, enum efi_timer_delay type,
 			   uint64_t trigger_time)
@@ -740,17 +745,17 @@
 	return EFI_SUCCESS;
 }
 
-/*
- * Set the trigger time for a timer event or stop the event.
+/**
+ * efi_set_timer_ext - Set the trigger time for a timer event or stop the event
  *
  * This function implements the SetTimer service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @event		event for which the timer is set
- * @type		type of the timer
- * @trigger_time	trigger period in multiples of 100ns
- * @return		status code
+ * @event:		event for which the timer is set
+ * @type:		type of the timer
+ * @trigger_time:	trigger period in multiples of 100ns
+ * Return Value:	status code
  */
 static efi_status_t EFIAPI efi_set_timer_ext(struct efi_event *event,
 					     enum efi_timer_delay type,
@@ -760,17 +765,17 @@
 	return EFI_EXIT(efi_set_timer(event, type, trigger_time));
 }
 
-/*
- * Wait for events to be signaled.
+/**
+ * efi_wait_for_event - wait for events to be signaled
  *
  * This function implements the WaitForEvent service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @num_events	number of events to be waited for
- * @events	events to be waited for
- * @index	index of the event that was signaled
- * @return	status code
+ * @num_events:		number of events to be waited for
+ * @event:		events to be waited for
+ * @index:		index of the event that was signaled
+ * Return Value:	status code
  */
 static efi_status_t EFIAPI efi_wait_for_event(efi_uintn_t num_events,
 					      struct efi_event **event,
@@ -817,8 +822,8 @@
 	return EFI_EXIT(EFI_SUCCESS);
 }
 
-/*
- * Signal an EFI event.
+/**
+ * efi_signal_event_ext - signal an EFI event
  *
  * This function implements the SignalEvent service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
@@ -827,8 +832,8 @@
  * This functions sets the signaled state of the event and queues the
  * notification function for execution.
  *
- * @event	event to signal
- * @return	status code
+ * @event:		event to signal
+ * Return Value:	status code
  */
 static efi_status_t EFIAPI efi_signal_event_ext(struct efi_event *event)
 {
@@ -839,15 +844,15 @@
 	return EFI_EXIT(EFI_SUCCESS);
 }
 
-/*
- * Close an EFI event.
+/**
+ * efi_close_event - close an EFI event
  *
  * This function implements the CloseEvent service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @event	event to close
- * @return	status code
+ * @event:		event to close
+ * Return Value:	status code
  */
 static efi_status_t EFIAPI efi_close_event(struct efi_event *event)
 {
@@ -859,8 +864,8 @@
 	return EFI_EXIT(EFI_SUCCESS);
 }
 
-/*
- * Check if an event is signaled.
+/**
+ * efi_check_event - check if an event is signaled
  *
  * This function implements the CheckEvent service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
@@ -869,8 +874,8 @@
  * If an event is not signaled yet, the notification function is queued.
  * The signaled state is cleared.
  *
- * @event	event to check
- * @return	status code
+ * @event:		event to check
+ * Return Value:	status code
  */
 static efi_status_t EFIAPI efi_check_event(struct efi_event *event)
 {
@@ -888,11 +893,11 @@
 	return EFI_EXIT(EFI_NOT_READY);
 }
 
-/*
- * Find the internal EFI object for a handle.
+/**
+ * efi_search_obj - find the internal EFI object for a handle
  *
- * @handle	handle to find
- * @return	EFI object
+ * @handle:		handle to find
+ * Return Value:	EFI object
  */
 struct efi_object *efi_search_obj(const efi_handle_t handle)
 {
@@ -906,11 +911,12 @@
 	return NULL;
 }
 
-/*
- * Create open protocol info entry and add it to a protocol.
+/**
+ * efi_open_protocol_info_entry - create open protocol info entry and add it
+ *				  to a protocol
  *
- * @handler	handler of a protocol
- * @return	open protocol info entry
+ * @handler:		handler of a protocol
+ * Return Value:	open protocol info entry
  */
 static struct efi_open_protocol_info_entry *efi_create_open_info(
 			struct efi_handler *handler)
@@ -926,11 +932,11 @@
 	return &item->info;
 }
 
-/*
- * Remove an open protocol info entry from a protocol.
+/**
+ * efi_delete_open_info - remove an open protocol info entry from a protocol
  *
- * @handler	handler of a protocol
- * @return	status code
+ * @item:		open protocol info entry to delete
+ * Return Value:	status code
  */
 static efi_status_t efi_delete_open_info(
 			struct efi_open_protocol_info_item *item)
@@ -940,13 +946,13 @@
 	return EFI_SUCCESS;
 }
 
-/*
- * Install new protocol on a handle.
+/**
+ * efi_add_protocol - install new protocol on a handle
  *
- * @handle			handle on which the protocol shall be installed
- * @protocol			GUID of the protocol to be installed
- * @protocol_interface		interface of the protocol implementation
- * @return			status code
+ * @handle:			handle on which the protocol shall be installed
+ * @protocol:			GUID of the protocol to be installed
+ * @protocol_interface:		interface of the protocol implementation
+ * Return Value:		status code
  */
 efi_status_t efi_add_protocol(const efi_handle_t handle,
 			      const efi_guid_t *protocol,
@@ -974,19 +980,19 @@
 	return EFI_SUCCESS;
 }
 
-/*
- * Install protocol interface.
+/**
+ * efi_install_protocol_interface - install protocol interface
  *
  * This function implements the InstallProtocolInterface service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @handle			handle on which the protocol shall be installed
- * @protocol			GUID of the protocol to be installed
- * @protocol_interface_type	type of the interface to be installed,
+ * @handle:			handle on which the protocol shall be installed
+ * @protocol:			GUID of the protocol to be installed
+ * @protocol_interface_type:	type of the interface to be installed,
  *				always EFI_NATIVE_INTERFACE
- * @protocol_interface		interface of the protocol implementation
- * @return			status code
+ * @protocol_interface:		interface of the protocol implementation
+ * Return Value:		status code
  */
 static efi_status_t EFIAPI efi_install_protocol_interface(
 			void **handle, const efi_guid_t *protocol,
@@ -1020,38 +1026,16 @@
 	return EFI_EXIT(r);
 }
 
-/*
- * Reinstall protocol interface.
+/**
+ * efi_get_drivers - get all drivers associated to a controller
  *
- * This function implements the ReinstallProtocolInterface service.
- * See the Unified Extensible Firmware Interface (UEFI) specification
- * for details.
- *
- * @handle			handle on which the protocol shall be
- *				reinstalled
- * @protocol			GUID of the protocol to be installed
- * @old_interface		interface to be removed
- * @new_interface		interface to be installed
- * @return			status code
- */
-static efi_status_t EFIAPI efi_reinstall_protocol_interface(
-			efi_handle_t handle, const efi_guid_t *protocol,
-			void *old_interface, void *new_interface)
-{
-	EFI_ENTRY("%p, %pUl, %p, %p", handle, protocol, old_interface,
-		  new_interface);
-	return EFI_EXIT(EFI_ACCESS_DENIED);
-}
-
-/*
- * Get all drivers associated to a controller.
  * The allocated buffer has to be freed with free().
  *
- * @efiobj			handle of the controller
- * @protocol			protocol guid (optional)
- * @number_of_drivers		number of child controllers
- * @driver_handle_buffer	handles of the the drivers
- * @return			status code
+ * @efiobj:			handle of the controller
+ * @protocol:			protocol guid (optional)
+ * @number_of_drivers:		number of child controllers
+ * @driver_handle_buffer:	handles of the the drivers
+ * Return Value:		status code
  */
 static efi_status_t efi_get_drivers(struct efi_object *efiobj,
 				    const efi_guid_t *protocol,
@@ -1107,17 +1091,17 @@
 	return EFI_SUCCESS;
 }
 
-/*
- * Disconnect all drivers from a controller.
+/**
+ * efi_disconnect_all_drivers - disconnect all drivers from a controller
  *
  * This function implements the DisconnectController service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @efiobj		handle of the controller
- * @protocol		protocol guid (optional)
- * @child_handle	handle of the child to destroy
- * @return		status code
+ * @efiobj:		handle of the controller
+ * @protocol:		protocol guid (optional)
+ * @child_handle:	handle of the child to destroy
+ * Return Value:	status code
  */
 static efi_status_t efi_disconnect_all_drivers(
 				struct efi_object *efiobj,
@@ -1146,17 +1130,17 @@
 	return ret;
 }
 
-/*
- * Uninstall protocol interface.
+/**
+ * efi_uninstall_protocol_interface - uninstall protocol interface
  *
  * This function implements the UninstallProtocolInterface service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @handle			handle from which the protocol shall be removed
- * @protocol			GUID of the protocol to be removed
- * @protocol_interface		interface to be removed
- * @return			status code
+ * @handle:			handle from which the protocol shall be removed
+ * @protocol:			GUID of the protocol to be removed
+ * @protocol_interface:		interface to be removed
+ * Return Value:		status code
  */
 static efi_status_t EFIAPI efi_uninstall_protocol_interface(
 				efi_handle_t handle, const efi_guid_t *protocol,
@@ -1203,18 +1187,19 @@
 	return EFI_EXIT(r);
 }
 
-/*
- * Register an event for notification when a protocol is installed.
+/**
+ * efi_register_protocol_notify - register an event for notification when a
+ *				  protocol is installed.
  *
  * This function implements the RegisterProtocolNotify service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @protocol		GUID of the protocol whose installation shall be
+ * @protocol:		GUID of the protocol whose installation shall be
  *			notified
- * @event		event to be signaled upon installation of the protocol
- * @registration	key for retrieving the registration information
- * @return		status code
+ * @event:		event to be signaled upon installation of the protocol
+ * @registration:	key for retrieving the registration information
+ * Return Value:	status code
  */
 static efi_status_t EFIAPI efi_register_protocol_notify(
 						const efi_guid_t *protocol,
@@ -1225,16 +1210,16 @@
 	return EFI_EXIT(EFI_OUT_OF_RESOURCES);
 }
 
-/*
- * Determine if an EFI handle implements a protocol.
+/**
+ * efi_search - determine if an EFI handle implements a protocol
  *
  * See the documentation of the LocateHandle service in the UEFI specification.
  *
- * @search_type		selection criterion
- * @protocol		GUID of the protocol
- * @search_key		registration key
- * @efiobj		handle
- * @return		0 if the handle implements the protocol
+ * @search_type:	selection criterion
+ * @protocol:		GUID of the protocol
+ * @search_key:		registration key
+ * @efiobj:		handle
+ * Return Value:	0 if the handle implements the protocol
  */
 static int efi_search(enum efi_locate_search_type search_type,
 		      const efi_guid_t *protocol, void *search_key,
@@ -1257,18 +1242,18 @@
 	}
 }
 
-/*
- * Locate handles implementing a protocol.
+/**
+ * efi_locate_handle - locate handles implementing a protocol
  *
  * This function is meant for U-Boot internal calls. For the API implementation
  * of the LocateHandle service see efi_locate_handle_ext.
  *
- * @search_type		selection criterion
- * @protocol		GUID of the protocol
- * @search_key		registration key
- * @buffer_size		size of the buffer to receive the handles in bytes
- * @buffer		buffer to receive the relevant handles
- * @return		status code
+ * @search_type:	selection criterion
+ * @protocol:		GUID of the protocol
+ * @search_key:		registration key
+ * @buffer_size:	size of the buffer to receive the handles in bytes
+ * @buffer:		buffer to receive the relevant handles
+ * Return Value:	status code
  */
 static efi_status_t efi_locate_handle(
 			enum efi_locate_search_type search_type,
@@ -1327,19 +1312,19 @@
 	return EFI_SUCCESS;
 }
 
-/*
- * Locate handles implementing a protocol.
+/**
+ * efi_locate_handle_ext - locate handles implementing a protocol.
  *
  * This function implements the LocateHandle service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @search_type		selection criterion
- * @protocol		GUID of the protocol
- * @search_key		registration key
- * @buffer_size		size of the buffer to receive the handles in bytes
- * @buffer		buffer to receive the relevant handles
- * @return		0 if the handle implements the protocol
+ * @search_type:	selection criterion
+ * @protocol:		GUID of the protocol
+ * @search_key:		registration key
+ * @buffer_size:	size of the buffer to receive the handles in bytes
+ * @buffer:		buffer to receive the relevant handles
+ * Return Value:	0 if the handle implements the protocol
  */
 static efi_status_t EFIAPI efi_locate_handle_ext(
 			enum efi_locate_search_type search_type,
@@ -1353,7 +1338,12 @@
 			buffer_size, buffer));
 }
 
-/* Collapses configuration table entries, removing index i */
+/**
+ * efi_remove_configuration_table - collapses configuration table entries,
+ *				    removing index i
+ *
+ * @i:	index of the table entry to be removed
+ */
 static void efi_remove_configuration_table(int i)
 {
 	struct efi_configuration_table *this = &efi_conf_table[i];
@@ -1364,15 +1354,16 @@
 	systab.nr_tables--;
 }
 
-/*
- * Adds, updates, or removes a configuration table.
+/**
+ * efi_install_configuration_table - adds, updates, or removes a configuration
+ *				     table
  *
  * This function is used for internal calls. For the API implementation of the
  * InstallConfigurationTable service see efi_install_configuration_table_ext.
  *
- * @guid		GUID of the installed table
- * @table		table to be installed
- * @return		status code
+ * @guid:		GUID of the installed table
+ * @table:		table to be installed
+ * Return Value:	status code
  */
 efi_status_t efi_install_configuration_table(const efi_guid_t *guid,
 					     void *table)
@@ -1418,16 +1409,17 @@
 	return EFI_SUCCESS;
 }
 
-/*
- * Adds, updates, or removes a configuration table.
+/**
+ * efi_install_configuration_table_ex - Adds, updates, or removes a
+ *					configuration table.
  *
  * This function implements the InstallConfigurationTable service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @guid		GUID of the installed table
- * @table		table to be installed
- * @return		status code
+ * @guid:		GUID of the installed table
+ * @table:		table to be installed
+ * Return Value:	status code
  */
 static efi_status_t EFIAPI efi_install_configuration_table_ext(efi_guid_t *guid,
 							       void *table)
@@ -1436,16 +1428,18 @@
 	return EFI_EXIT(efi_install_configuration_table(guid, table));
 }
 
-/*
- * Initialize a loaded_image_info + loaded_image_info object with correct
+/**
+ * efi_setup_loaded_image - initialize a loaded image
+ *
+ * Initialize a loaded_image_info and loaded_image_info object with correct
  * protocols, boot-device, etc.
  *
- * @info		loaded image info to be passed to the entry point of the
+ * @info:		loaded image info to be passed to the entry point of the
  *			image
- * @obj			internal object associated with the loaded image
- * @device_path		device path of the loaded image
- * @file_path		file path of the loaded image
- * @return		status code
+ * @obj:		internal object associated with the loaded image
+ * @device_path:	device path of the loaded image
+ * @file_path:		file path of the loaded image
+ * Return Value:	status code
  */
 efi_status_t efi_setup_loaded_image(
 			struct efi_loaded_image *info, struct efi_object *obj,
@@ -1499,12 +1493,12 @@
 	return ret;
 }
 
-/*
- * Load an image using a file path.
+/**
+ * efi_load_image_from_path - load an image using a file path
  *
- * @file_path		the path of the image to load
- * @buffer		buffer containing the loaded image
- * @return		status code
+ * @file_path:		the path of the image to load
+ * @buffer:		buffer containing the loaded image
+ * Return Value:	status code
  */
 efi_status_t efi_load_image_from_path(struct efi_device_path *file_path,
 				      void **buffer)
@@ -1548,21 +1542,21 @@
 	return ret;
 }
 
-/*
- * Load an EFI image into memory.
+/**
+ * efi_load_image - load an EFI image into memory
  *
  * This function implements the LoadImage service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @boot_policy		true for request originating from the boot manager
- * @parent_image	the caller's image handle
- * @file_path		the path of the image to load
- * @source_buffer	memory location from which the image is installed
- * @source_size		size of the memory area from which the image is
+ * @boot_policy:	true for request originating from the boot manager
+ * @parent_image:	the caller's image handle
+ * @file_path:		the path of the image to load
+ * @source_buffer:	memory location from which the image is installed
+ * @source_size:	size of the memory area from which the image is
  *			installed
- * @image_handle	handle for the newly installed image
- * @return		status code
+ * @image_handle:	handle for the newly installed image
+ * Return Value:	status code
  */
 static efi_status_t EFIAPI efi_load_image(bool boot_policy,
 					  efi_handle_t parent_image,
@@ -1638,17 +1632,17 @@
 	return EFI_EXIT(ret);
 }
 
-/*
- * Call the entry point of an image.
+/**
+ * efi_start_image - dall the entry point of an image
  *
  * This function implements the StartImage service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @image_handle	handle of the image
- * @exit_data_size	size of the buffer
- * @exit_data		buffer to receive the exit data of the called image
- * @return		status code
+ * @image_handle:	handle of the image
+ * @exit_data_size:	size of the buffer
+ * @exit_data:		buffer to receive the exit data of the called image
+ * Return Value:	status code
  */
 static efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
 					   unsigned long *exit_data_size,
@@ -1704,18 +1698,18 @@
 	return EFI_CALL(systab.boottime->exit(image_handle, ret, 0, NULL));
 }
 
-/*
- * Leave an EFI application or driver.
+/**
+ * efi_exit - leave an EFI application or driver
  *
  * This function implements the Exit service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @image_handle	handle of the application or driver that is exiting
- * @exit_status		status code
- * @exit_data_size	size of the buffer in bytes
- * @exit_data		buffer with data describing an error
- * @return		status code
+ * @image_handle:	handle of the application or driver that is exiting
+ * @exit_status:	status code
+ * @exit_data_size:	size of the buffer in bytes
+ * @exit_data:		buffer with data describing an error
+ * Return Value:	status code
  */
 static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle,
 				    efi_status_t exit_status,
@@ -1753,15 +1747,15 @@
 	panic("EFI application exited");
 }
 
-/*
- * Unload an EFI image.
+/**
+ * efi_unload_image - unload an EFI image
  *
  * This function implements the UnloadImage service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @image_handle	handle of the image to be unloaded
- * @return		status code
+ * @image_handle:	handle of the image to be unloaded
+ * Return Value:	status code
  */
 static efi_status_t EFIAPI efi_unload_image(efi_handle_t image_handle)
 {
@@ -1775,8 +1769,8 @@
 	return EFI_EXIT(EFI_SUCCESS);
 }
 
-/*
- * Fix up caches for EFI payloads if necessary.
+/**
+ * efi_exit_caches - fix up caches for EFI payloads if necessary
  */
 static void efi_exit_caches(void)
 {
@@ -1790,8 +1784,8 @@
 #endif
 }
 
-/*
- * Stop all boot services.
+/**
+ * efi_exit_boot_services - stop all boot services
  *
  * This function implements the ExitBootServices service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
@@ -1801,9 +1795,9 @@
  * For exit boot services events the notification function is called.
  * The boot services are disabled in the system table.
  *
- * @image_handle	handle of the loaded image
- * @map_key		key of the memory map
- * @return		status code
+ * @image_handle:	handle of the loaded image
+ * @map_key:		key of the memory map
+ * Return Value:	status code
  */
 static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle,
 						  unsigned long map_key)
@@ -1865,15 +1859,15 @@
 	return EFI_EXIT(EFI_SUCCESS);
 }
 
-/*
- * Get next value of the counter.
+/**
+ * efi_get_next_monotonic_count - get next value of the counter
  *
  * This function implements the NextMonotonicCount service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @count	returned value of the counter
- * @return	status code
+ * @count:		returned value of the counter
+ * Return Value:	status code
  */
 static efi_status_t EFIAPI efi_get_next_monotonic_count(uint64_t *count)
 {
@@ -1884,15 +1878,15 @@
 	return EFI_EXIT(EFI_SUCCESS);
 }
 
-/*
- * Sleep.
+/**
+ * efi_stall - sleep
  *
  * This function implements the Stall sercive.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @microseconds	period to sleep in microseconds
- * @return		status code
+ * @microseconds:	period to sleep in microseconds
+ * Return Value:	status code
  */
 static efi_status_t EFIAPI efi_stall(unsigned long microseconds)
 {
@@ -1901,18 +1895,18 @@
 	return EFI_EXIT(EFI_SUCCESS);
 }
 
-/*
- * Reset the watchdog timer.
+/**
+ * efi_set_watchdog_timer - reset the watchdog timer
  *
  * This function implements the SetWatchdogTimer service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @timeout		seconds before reset by watchdog
- * @watchdog_code	code to be logged when resetting
- * @data_size		size of buffer in bytes
- * @watchdog_data	buffer with data describing the reset reason
- * @return		status code
+ * @timeout:		seconds before reset by watchdog
+ * @watchdog_code:	code to be logged when resetting
+ * @data_size:		size of buffer in bytes
+ * @watchdog_data:	buffer with data describing the reset reason
+ * Return Value:	status code
  */
 static efi_status_t EFIAPI efi_set_watchdog_timer(unsigned long timeout,
 						  uint64_t watchdog_code,
@@ -1924,18 +1918,18 @@
 	return EFI_EXIT(efi_set_watchdog(timeout));
 }
 
-/*
- * Close a protocol.
+/**
+ * efi_close_protocol - close a protocol
  *
  * This function implements the CloseProtocol service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @handle		handle on which the protocol shall be closed
- * @protocol		GUID of the protocol to close
- * @agent_handle	handle of the driver
- * @controller_handle	handle of the controller
- * @return		status code
+ * @handle:		handle on which the protocol shall be closed
+ * @protocol:		GUID of the protocol to close
+ * @agent_handle:	handle of the driver
+ * @controller_handle:	handle of the controller
+ * Return Value:	status code
  */
 static efi_status_t EFIAPI efi_close_protocol(efi_handle_t handle,
 					      const efi_guid_t *protocol,
@@ -1971,18 +1965,19 @@
 	return EFI_EXIT(r);
 }
 
-/*
- * Provide information about then open status of a protocol on a handle
+/**
+ * efi_open_protocol_information - provide information about then open status
+ *				   of a protocol on a handle
  *
  * This function implements the OpenProtocolInformation service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @handle		handle for which the information shall be retrieved
- * @protocol		GUID of the protocol
- * @entry_buffer	buffer to receive the open protocol information
- * @entry_count		number of entries available in the buffer
- * @return		status code
+ * @handle:		handle for which the information shall be retrieved
+ * @protocol:		GUID of the protocol
+ * @entry_buffer:	buffer to receive the open protocol information
+ * @entry_count:	number of entries available in the buffer
+ * Return Value:	status code
  */
 static efi_status_t EFIAPI efi_open_protocol_information(
 			efi_handle_t handle, const efi_guid_t *protocol,
@@ -2034,17 +2029,17 @@
 	return EFI_EXIT(r);
 }
 
-/*
- * Get protocols installed on a handle.
+/**
+ * efi_protocols_per_handle - get protocols installed on a handle
  *
  * This function implements the ProtocolsPerHandleService.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @handle			handle for which the information is retrieved
- * @protocol_buffer		buffer with protocol GUIDs
- * @protocol_buffer_count	number of entries in the buffer
- * @return			status code
+ * @handle:			handle for which the information is retrieved
+ * @protocol_buffer:		buffer with protocol GUIDs
+ * @protocol_buffer_count:	number of entries in the buffer
+ * Return Value:		status code
  */
 static efi_status_t EFIAPI efi_protocols_per_handle(
 			efi_handle_t handle, efi_guid_t ***protocol_buffer,
@@ -2095,19 +2090,19 @@
 	return EFI_EXIT(EFI_SUCCESS);
 }
 
-/*
- * Locate handles implementing a protocol.
+/**
+ * efi_locate_handle_buffer - locate handles implementing a protocol
  *
  * This function implements the LocateHandleBuffer service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @search_type		selection criterion
- * @protocol		GUID of the protocol
- * @search_key		registration key
- * @no_handles		number of returned handles
- * @buffer		buffer with the returned handles
- * @return		status code
+ * @search_type:	selection criterion
+ * @protocol:		GUID of the protocol
+ * @search_key:		registration key
+ * @no_handles:		number of returned handles
+ * @buffer:		buffer with the returned handles
+ * Return Value:	status code
  */
 static efi_status_t EFIAPI efi_locate_handle_buffer(
 			enum efi_locate_search_type search_type,
@@ -2142,17 +2137,17 @@
 	return EFI_EXIT(r);
 }
 
-/*
- * Find an interface implementing a protocol.
+/**
+ * efi_locate_protocol - find an interface implementing a protocol
  *
  * This function implements the LocateProtocol service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @protocol		GUID of the protocol
- * @registration	registration key passed to the notification function
- * @protocol_interface	interface implementing the protocol
- * @return		status code
+ * @protocol:		GUID of the protocol
+ * @registration:	registration key passed to the notification function
+ * @protocol_interface:	interface implementing the protocol
+ * Return Value:	status code
  */
 static efi_status_t EFIAPI efi_locate_protocol(const efi_guid_t *protocol,
 					       void *registration,
@@ -2183,17 +2178,18 @@
 	return EFI_EXIT(EFI_NOT_FOUND);
 }
 
-/*
- * Get the device path and handle of an device implementing a protocol.
+/**
+ * efi_locate_device_path - Get the device path and handle of an device
+ *			    implementing a protocol
  *
  * This function implements the LocateDevicePath service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @protocol		GUID of the protocol
- * @device_path		device path
- * @device		handle of the device
- * @return		status code
+ * @protocol:		GUID of the protocol
+ * @device_path:	device path
+ * @device:		handle of the device
+ * Return Value:	status code
  */
 static efi_status_t EFIAPI efi_locate_device_path(
 			const efi_guid_t *protocol,
@@ -2259,17 +2255,18 @@
 	return EFI_EXIT(ret);
 }
 
-/*
+/**
  * Install multiple protocol interfaces.
  *
  * This function implements the MultipleProtocolInterfaces service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @handle	handle on which the protocol interfaces shall be installed
- * @...		NULL terminated argument list with pairs of protocol GUIDS and
- *		interfaces
- * @return	status code
+ * @handle:		handle on which the protocol interfaces shall be
+ *			installed
+ * @...:		NULL terminated argument list with pairs of protocol
+ *			GUIDS and interfaces
+ * Return Value:	status code
  */
 static efi_status_t EFIAPI efi_install_multiple_protocol_interfaces(
 			void **handle, ...)
@@ -2316,17 +2313,19 @@
 	return EFI_EXIT(r);
 }
 
-/*
- * Uninstall multiple protocol interfaces.
+/**
+ * efi_uninstall_multiple_protocol_interfaces - uninstall multiple protocol
+ *						interfaces
  *
  * This function implements the UninstallMultipleProtocolInterfaces service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @handle	handle from which the protocol interfaces shall be removed
- * @...		NULL terminated argument list with pairs of protocol GUIDS and
- *		interfaces
- * @return	status code
+ * @handle:		handle from which the protocol interfaces shall be
+ *			removed
+ * @...:		NULL terminated argument list with pairs of protocol
+ *			GUIDS and interfaces
+ * Return Value:	status code
  */
 static efi_status_t EFIAPI efi_uninstall_multiple_protocol_interfaces(
 			void *handle, ...)
@@ -2373,17 +2372,17 @@
 	return EFI_EXIT(r);
 }
 
-/*
- * Calculate cyclic redundancy code.
+/**
+ * efi_calculate_crc32 - calculate cyclic redundancy code
  *
  * This function implements the CalculateCrc32 service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @data	buffer with data
- * @data_size	size of buffer in bytes
- * @crc32_p	cyclic redundancy code
- * @return	status code
+ * @data:		buffer with data
+ * @data_size:		size of buffer in bytes
+ * @crc32_p:		cyclic redundancy code
+ * Return Value:	status code
  */
 static efi_status_t EFIAPI efi_calculate_crc32(void *data,
 					       unsigned long data_size,
@@ -2394,16 +2393,16 @@
 	return EFI_EXIT(EFI_SUCCESS);
 }
 
-/*
- * Copy memory.
+/**
+ * efi_copy_mem - copy memory
  *
  * This function implements the CopyMem service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @destination		destination of the copy operation
- * @source		source of the copy operation
- * @length		number of bytes to copy
+ * @destination:	destination of the copy operation
+ * @source:		source of the copy operation
+ * @length:		number of bytes to copy
  */
 static void EFIAPI efi_copy_mem(void *destination, const void *source,
 				size_t length)
@@ -2413,16 +2412,16 @@
 	EFI_EXIT(EFI_SUCCESS);
 }
 
-/*
- * Fill memory with a byte value.
+/**
+ * efi_set_mem - Fill memory with a byte value.
  *
  * This function implements the SetMem service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @buffer		buffer to fill
- * @size		size of buffer in bytes
- * @value		byte to copy to the buffer
+ * @buffer:		buffer to fill
+ * @size:		size of buffer in bytes
+ * @value:		byte to copy to the buffer
  */
 static void EFIAPI efi_set_mem(void *buffer, size_t size, uint8_t value)
 {
@@ -2431,15 +2430,15 @@
 	EFI_EXIT(EFI_SUCCESS);
 }
 
-/*
- * Open protocol interface on a handle.
+/**
+ * efi_protocol_open - open protocol interface on a handle
  *
- * @handler		handler of a protocol
- * @protocol_interface	interface implementing the protocol
- * @agent_handle	handle of the driver
- * @controller_handle	handle of the controller
- * @attributes		attributes indicating how to open the protocol
- * @return		status code
+ * @handler:		handler of a protocol
+ * @protocol_interface:	interface implementing the protocol
+ * @agent_handle:	handle of the driver
+ * @controller_handle:	handle of the controller
+ * @attributes:		attributes indicating how to open the protocol
+ * Return Value:	status code
  */
 static efi_status_t efi_protocol_open(
 			struct efi_handler *handler,
@@ -2526,20 +2525,20 @@
 	return EFI_SUCCESS;
 }
 
-/*
- * Open protocol interface on a handle.
+/**
+ * efi_open_protocol - open protocol interface on a handle
  *
  * This function implements the OpenProtocol interface.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @handle		handle on which the protocol shall be opened
- * @protocol		GUID of the protocol
- * @protocol_interface	interface implementing the protocol
- * @agent_handle	handle of the driver
- * @controller_handle	handle of the controller
- * @attributes		attributes indicating how to open the protocol
- * @return		status code
+ * @handle:		handle on which the protocol shall be opened
+ * @protocol:		GUID of the protocol
+ * @protocol_interface:	interface implementing the protocol
+ * @agent_handle:	handle of the driver
+ * @controller_handle:	handle of the controller
+ * @attributes:		attributes indicating how to open the protocol
+ * Return Value:	status code
  */
 static efi_status_t EFIAPI efi_open_protocol(
 			void *handle, const efi_guid_t *protocol,
@@ -2593,17 +2592,17 @@
 	return EFI_EXIT(r);
 }
 
-/*
- * Get interface of a protocol on a handle.
+/**
+ * efi_handle_protocol - get interface of a protocol on a handle
  *
  * This function implements the HandleProtocol service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @handle		handle on which the protocol shall be opened
- * @protocol		GUID of the protocol
- * @protocol_interface  interface implementing the protocol
- * @return		status code
+ * @handle:		handle on which the protocol shall be opened
+ * @protocol:		GUID of the protocol
+ * @protocol_interface:	interface implementing the protocol
+ * Return Value:	status code
  */
 static efi_status_t EFIAPI efi_handle_protocol(efi_handle_t handle,
 					       const efi_guid_t *protocol,
@@ -2613,6 +2612,14 @@
 				 NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
 }
 
+/**
+ * efi_bind_controller - bind a single driver to a controller
+ *
+ * @controller_handle:		controller handle
+ * @driver_image_handle:	driver handle
+ * @remain_device_path:		remaining path
+ * Return Value:		status code
+ */
 static efi_status_t efi_bind_controller(
 			efi_handle_t controller_handle,
 			efi_handle_t driver_image_handle,
@@ -2641,6 +2648,14 @@
 	return r;
 }
 
+/**
+ * efi_connect_single_controller - connect a single driver to a controller
+ *
+ * @controller_handle:		controller
+ * @driver_image_handle:	driver
+ * @remain_device_path:		remainting path
+ * Return Value:		status code
+ */
 static efi_status_t efi_connect_single_controller(
 			efi_handle_t controller_handle,
 			efi_handle_t *driver_image_handle,
@@ -2705,8 +2720,8 @@
 	return EFI_SUCCESS;
 }
 
-/*
- * Connect a controller to a driver.
+/**
+ * efi_connect_controller - connect a controller to a driver
  *
  * This function implements the ConnectController service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
@@ -2716,11 +2731,11 @@
  * Afterwards all handles that have openened a protocol of the controller
  * with EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER are connected to drivers.
  *
- * @controller_handle	handle of the controller
- * @driver_image_handle	handle of the driver
- * @remain_device_path	device path of a child controller
- * @recursive		true to connect all child controllers
- * @return		status code
+ * @controller_handle:		handle of the controller
+ * @driver_image_handle:	handle of the driver
+ * @remain_device_path:		device path of a child controller
+ * @recursive:			true to connect all child controllers
+ * Return Value:		status code
  */
 static efi_status_t EFIAPI efi_connect_controller(
 			efi_handle_t controller_handle,
@@ -2773,14 +2788,59 @@
 	return EFI_EXIT(ret);
 }
 
-/*
- * Get all child controllers associated to a driver.
+/**
+ * efi_reinstall_protocol_interface - reinstall protocol interface
+ *
+ * This function implements the ReinstallProtocolInterface service.
+ * See the Unified Extensible Firmware Interface (UEFI) specification
+ * for details.
+ *
+ * The old interface is uninstalled. The new interface is installed.
+ * Drivers are connected.
+ *
+ * @handle:			handle on which the protocol shall be
+ *				reinstalled
+ * @protocol:			GUID of the protocol to be installed
+ * @old_interface:		interface to be removed
+ * @new_interface:		interface to be installed
+ * Return Value:		status code
+ */
+static efi_status_t EFIAPI efi_reinstall_protocol_interface(
+			efi_handle_t handle, const efi_guid_t *protocol,
+			void *old_interface, void *new_interface)
+{
+	efi_status_t ret;
+
+	EFI_ENTRY("%p, %pUl, %p, %p", handle, protocol, old_interface,
+		  new_interface);
+	ret = EFI_CALL(efi_uninstall_protocol_interface(handle, protocol,
+							old_interface));
+	if (ret != EFI_SUCCESS)
+		goto out;
+	ret = EFI_CALL(efi_install_protocol_interface(&handle, protocol,
+						      EFI_NATIVE_INTERFACE,
+						      new_interface));
+	if (ret != EFI_SUCCESS)
+		goto out;
+	/*
+	 * The returned status code has to be ignored.
+	 * Do not create an error if no suitable driver for the handle exists.
+	 */
+	EFI_CALL(efi_connect_controller(handle, NULL, NULL, true));
+out:
+	return EFI_EXIT(ret);
+}
+
+/**
+ * efi_get_child_controllers - get all child controllers associated to a driver
+ *
  * The allocated buffer has to be freed with free().
  *
- * @efiobj			handle of the controller
- * @driver_handle		handle of the driver
- * @number_of_children		number of child controllers
- * @child_handle_buffer		handles of the the child controllers
+ * @efiobj:			handle of the controller
+ * @driver_handle:		handle of the driver
+ * @number_of_children:		number of child controllers
+ * @child_handle_buffer:	handles of the the child controllers
+ * Return Value:		status code
  */
 static efi_status_t efi_get_child_controllers(
 				struct efi_object *efiobj,
@@ -2835,17 +2895,17 @@
 	return EFI_SUCCESS;
 }
 
-/*
- * Disconnect a controller from a driver.
+/**
+ * efi_disconnect_controller - disconnect a controller from a driver
  *
  * This function implements the DisconnectController service.
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * @controller_handle	handle of the controller
- * @driver_image_handle handle of the driver
- * @child_handle	handle of the child to destroy
- * @return		status code
+ * @controller_handle:		handle of the controller
+ * @driver_image_handle:	handle of the driver
+ * @child_handle:		handle of the child to destroy
+ * Return Value:		status code
  */
 static efi_status_t EFIAPI efi_disconnect_controller(
 				efi_handle_t controller_handle,
diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c
index d777db8..ce66c93 100644
--- a/lib/efi_loader/efi_console.c
+++ b/lib/efi_loader/efi_console.c
@@ -12,8 +12,6 @@
 #include <stdio_dev.h>
 #include <video_console.h>
 
-static bool console_size_queried;
-
 #define EFI_COUT_MODE_2 2
 #define EFI_MAX_COUT_MODE 3
 
@@ -62,7 +60,15 @@
 	.cursor_visible = 1,
 };
 
-static int term_read_reply(int *n, int maxnum, char end_char)
+/*
+ * Receive and parse a reply from the terminal.
+ *
+ * @n:		array of return values
+ * @num:	number of return values expected
+ * @end_char:	character indicating end of terminal message
+ * @return:	non-zero indicates error
+ */
+static int term_read_reply(int *n, int num, char end_char)
 {
 	char c;
 	int i = 0;
@@ -79,7 +85,7 @@
 		c = getc();
 		if (c == ';') {
 			i++;
-			if (i >= maxnum)
+			if (i >= num)
 				return -1;
 			n[i] = 0;
 			continue;
@@ -93,6 +99,8 @@
 		n[i] *= 10;
 		n[i] += c - '0';
 	}
+	if (i != num - 1)
+		return -1;
 
 	return 0;
 }
@@ -116,25 +124,36 @@
 
 	unsigned int n16 = utf16_strlen(string);
 	char buf[MAX_UTF8_PER_UTF16 * n16 + 1];
-	char *p;
+	u16 *p;
 
 	*utf16_to_utf8((u8 *)buf, string, n16) = '\0';
 
 	fputs(stdout, buf);
 
-	for (p = buf; *p; p++) {
+	/*
+	 * Update the cursor position.
+	 *
+	 * The UEFI spec provides advance rules for U+0000, U+0008, U+000A,
+	 * and U000D. All other characters, including control characters
+	 * U+0007 (bel) and U+0009 (tab), have to increase the column by one.
+	 */
+	for (p = string; *p; ++p) {
 		switch (*p) {
-		case '\r':   /* carriage-return */
-			con->cursor_column = 0;
+		case '\b':	/* U+0008, backspace */
+			con->cursor_column = max(0, con->cursor_column - 1);
 			break;
-		case '\n':   /* newline */
+		case '\n':	/* U+000A, newline */
 			con->cursor_column = 0;
 			con->cursor_row++;
 			break;
-		case '\t':   /* tab, assume 8 char align */
+		case '\r':	/* U+000D, carriage-return */
+			con->cursor_column = 0;
 			break;
-		case '\b':   /* backspace */
-			con->cursor_column = max(0, con->cursor_column - 1);
+		case 0xd800 ... 0xdbff:
+			/*
+			 * Ignore high surrogates, we do not want to count a
+			 * Unicode character twice.
+			 */
 			break;
 		default:
 			con->cursor_column++;
@@ -194,6 +213,51 @@
 	return 0;
 }
 
+/*
+ * Update the mode table.
+ *
+ * By default the only mode available is 80x25. If the console has at least 50
+ * lines, enable mode 80x50. If we can query the console size and it is neither
+ * 80x25 nor 80x50, set it as an additional mode.
+ */
+static void query_console_size(void)
+{
+	const char *stdout_name = env_get("stdout");
+	int rows = 25, cols = 80;
+
+	if (stdout_name && !strcmp(stdout_name, "vidconsole") &&
+	    IS_ENABLED(CONFIG_DM_VIDEO)) {
+		struct stdio_dev *stdout_dev =
+			stdio_get_by_name("vidconsole");
+		struct udevice *dev = stdout_dev->priv;
+		struct vidconsole_priv *priv =
+			dev_get_uclass_priv(dev);
+		rows = priv->rows;
+		cols = priv->cols;
+	} else if (query_console_serial(&rows, &cols)) {
+		return;
+	}
+
+	/* Test if we can have Mode 1 */
+	if (cols >= 80 && rows >= 50) {
+		efi_cout_modes[1].present = 1;
+		efi_con_mode.max_mode = 2;
+	}
+
+	/*
+	 * Install our mode as mode 2 if it is different
+	 * than mode 0 or 1 and set it as the currently selected mode
+	 */
+	if (!cout_mode_matches(&efi_cout_modes[0], rows, cols) &&
+	    !cout_mode_matches(&efi_cout_modes[1], rows, cols)) {
+		efi_cout_modes[EFI_COUT_MODE_2].columns = cols;
+		efi_cout_modes[EFI_COUT_MODE_2].rows = rows;
+		efi_cout_modes[EFI_COUT_MODE_2].present = 1;
+		efi_con_mode.max_mode = EFI_MAX_COUT_MODE;
+		efi_con_mode.mode = EFI_COUT_MODE_2;
+	}
+}
+
 static efi_status_t EFIAPI efi_cout_query_mode(
 			struct efi_simple_text_output_protocol *this,
 			unsigned long mode_number, unsigned long *columns,
@@ -201,52 +265,12 @@
 {
 	EFI_ENTRY("%p, %ld, %p, %p", this, mode_number, columns, rows);
 
-	if (!console_size_queried) {
-		const char *stdout_name = env_get("stdout");
-		int rows, cols;
-
-		console_size_queried = true;
-
-		if (stdout_name && !strcmp(stdout_name, "vidconsole") &&
-		    IS_ENABLED(CONFIG_DM_VIDEO)) {
-			struct stdio_dev *stdout_dev =
-				stdio_get_by_name("vidconsole");
-			struct udevice *dev = stdout_dev->priv;
-			struct vidconsole_priv *priv =
-				dev_get_uclass_priv(dev);
-			rows = priv->rows;
-			cols = priv->cols;
-		} else if (query_console_serial(&rows, &cols)) {
-			goto out;
-		}
-
-		/* Test if we can have Mode 1 */
-		if (cols >= 80 && rows >= 50) {
-			efi_cout_modes[1].present = 1;
-			efi_con_mode.max_mode = 2;
-		}
-
-		/*
-		 * Install our mode as mode 2 if it is different
-		 * than mode 0 or 1 and set it  as the currently selected mode
-		 */
-		if (!cout_mode_matches(&efi_cout_modes[0], rows, cols) &&
-		    !cout_mode_matches(&efi_cout_modes[1], rows, cols)) {
-			efi_cout_modes[EFI_COUT_MODE_2].columns = cols;
-			efi_cout_modes[EFI_COUT_MODE_2].rows = rows;
-			efi_cout_modes[EFI_COUT_MODE_2].present = 1;
-			efi_con_mode.max_mode = EFI_MAX_COUT_MODE;
-			efi_con_mode.mode = EFI_COUT_MODE_2;
-		}
-	}
-
 	if (mode_number >= efi_con_mode.max_mode)
 		return EFI_EXIT(EFI_UNSUPPORTED);
 
 	if (efi_cout_modes[mode_number].present != 1)
 		return EFI_EXIT(EFI_UNSUPPORTED);
 
-out:
 	if (columns)
 		*columns = efi_cout_modes[mode_number].columns;
 	if (rows)
@@ -554,6 +578,9 @@
 	struct efi_object *efi_console_output_obj;
 	struct efi_object *efi_console_input_obj;
 
+	/* Set up mode information */
+	query_console_size();
+
 	/* Create handles */
 	r = efi_create_handle((efi_handle_t *)&efi_console_output_obj);
 	if (r != EFI_SUCCESS)
diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c
index e832cde..3cffe9e 100644
--- a/lib/efi_loader/efi_image_loader.c
+++ b/lib/efi_loader/efi_image_loader.c
@@ -10,7 +10,6 @@
 #include <common.h>
 #include <efi_loader.h>
 #include <pe.h>
-#include <asm/global_data.h>
 
 const efi_guid_t efi_global_variable_guid = EFI_GLOBAL_VARIABLE_GUID;
 const efi_guid_t efi_guid_device_path = DEVICE_PATH_GUID;
@@ -90,11 +89,16 @@
 }
 
 static efi_status_t efi_loader_relocate(const IMAGE_BASE_RELOCATION *rel,
-			unsigned long rel_size, void *efi_reloc)
+			unsigned long rel_size, void *efi_reloc,
+			unsigned long pref_address)
 {
+	unsigned long delta = (unsigned long)efi_reloc - pref_address;
 	const IMAGE_BASE_RELOCATION *end;
 	int i;
 
+	if (delta == 0)
+		return EFI_SUCCESS;
+
 	end = (const IMAGE_BASE_RELOCATION *)((const char *)rel + rel_size);
 	while (rel < end - 1 && rel->SizeOfBlock) {
 		const uint16_t *relocs = (const uint16_t *)(rel + 1);
@@ -103,7 +107,6 @@
 			uint32_t offset = (uint32_t)(*relocs & 0xfff) +
 					  rel->VirtualAddress;
 			int type = *relocs >> EFI_PAGE_SHIFT;
-			unsigned long delta = (unsigned long)efi_reloc;
 			uint64_t *x64 = efi_reloc + offset;
 			uint32_t *x32 = efi_reloc + offset;
 			uint16_t *x16 = efi_reloc + offset;
@@ -191,6 +194,7 @@
 	unsigned long rel_size;
 	int rel_idx = IMAGE_DIRECTORY_ENTRY_BASERELOC;
 	void *entry;
+	uint64_t image_base;
 	uint64_t image_size;
 	unsigned long virt_size = 0;
 	int supported = 0;
@@ -234,6 +238,7 @@
 	if (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
 		IMAGE_NT_HEADERS64 *nt64 = (void *)nt;
 		IMAGE_OPTIONAL_HEADER64 *opt = &nt64->OptionalHeader;
+		image_base = opt->ImageBase;
 		image_size = opt->SizeOfImage;
 		efi_set_code_and_data_type(loaded_image_info, opt->Subsystem);
 		efi_reloc = efi_alloc(virt_size,
@@ -249,6 +254,7 @@
 		virt_size = ALIGN(virt_size, opt->SectionAlignment);
 	} else if (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
 		IMAGE_OPTIONAL_HEADER32 *opt = &nt->OptionalHeader;
+		image_base = opt->ImageBase;
 		image_size = opt->SizeOfImage;
 		efi_set_code_and_data_type(loaded_image_info, opt->Subsystem);
 		efi_reloc = efi_alloc(virt_size,
@@ -279,7 +285,8 @@
 	}
 
 	/* Run through relocations */
-	if (efi_loader_relocate(rel, rel_size, efi_reloc) != EFI_SUCCESS) {
+	if (efi_loader_relocate(rel, rel_size, efi_reloc,
+				(unsigned long)image_base) != EFI_SUCCESS) {
 		efi_free_pages((uintptr_t) efi_reloc,
 			       (virt_size + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT);
 		return NULL;
@@ -287,7 +294,7 @@
 
 	/* Flush cache */
 	flush_cache((ulong)efi_reloc,
-		    ALIGN(virt_size, CONFIG_SYS_CACHELINE_SIZE));
+		    ALIGN(virt_size, EFI_CACHELINE_SIZE));
 	invalidate_icache_all();
 
 	/* Populate the loaded image interface bits */
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
index 664c651..ec66af9 100644
--- a/lib/efi_loader/efi_memory.c
+++ b/lib/efi_loader/efi_memory.c
@@ -10,7 +10,6 @@
 #include <inttypes.h>
 #include <malloc.h>
 #include <watchdog.h>
-#include <asm/global_data.h>
 #include <linux/list_sort.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -69,23 +68,27 @@
 	list_sort(NULL, &efi_mem, efi_mem_cmp);
 }
 
-/*
- * Unmaps all memory occupied by the carve_desc region from the
- * list entry pointed to by map.
+/** efi_mem_carve_out - unmap memory region
  *
- * Returns EFI_CARVE_NO_OVERLAP if the regions don't overlap.
- * Returns EFI_CARVE_OVERLAPS_NONRAM if the carve and map overlap,
- *    and the map contains anything but free ram.
- *    (only when overlap_only_ram is true)
- * Returns EFI_CARVE_LOOP_AGAIN if the mapping list should be traversed
- *    again, as it has been altered
- * Returns the number of overlapping pages. The pages are removed from
- *     the mapping list.
+ * @map:		memory map
+ * @carve_desc:		memory region to unmap
+ * @overlap_only_ram:	the carved out region may only overlap RAM
+ * Return Value:	the number of overlapping pages which have been
+ *			removed from the map,
+ *			EFI_CARVE_NO_OVERLAP, if the regions don't overlap,
+ *			EFI_CARVE_OVERLAPS_NONRAM, if the carve and map overlap,
+ *			and the map contains anything but free ram
+ *			(only when overlap_only_ram is true),
+ *			EFI_CARVE_LOOP_AGAIN, if the mapping list should be
+ *			traversed again, as it has been altered.
+ *
+ * Unmaps all memory occupied by the carve_desc region from the list entry
+ * pointed to by map.
  *
  * In case of EFI_CARVE_OVERLAPS_NONRAM it is the callers responsibility
- * to readd the already carved out pages to the mapping.
+ * to re-add the already carved out pages to the mapping.
  */
-static int efi_mem_carve_out(struct efi_mem_list *map,
+static s64 efi_mem_carve_out(struct efi_mem_list *map,
 			     struct efi_mem_desc *carve_desc,
 			     bool overlap_only_ram)
 {
@@ -184,7 +187,7 @@
 		carve_again = false;
 		list_for_each(lhandle, &efi_mem) {
 			struct efi_mem_list *lmem;
-			int r;
+			s64 r;
 
 			lmem = list_entry(lhandle, struct efi_mem_list, link);
 			r = efi_mem_carve_out(lmem, &newlist->desc,
@@ -338,7 +341,8 @@
 	uint64_t pages = (len + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT;
 	efi_status_t r;
 
-	r = efi_allocate_pages(0, memory_type, pages, &ret);
+	r = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES, memory_type, pages,
+			       &ret);
 	if (r == EFI_SUCCESS)
 		return (void*)(uintptr_t)ret;
 
@@ -385,7 +389,8 @@
 		return EFI_SUCCESS;
 	}
 
-	r = efi_allocate_pages(0, pool_type, num_pages, &t);
+	r = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES, pool_type, num_pages,
+			       &t);
 
 	if (r == EFI_SUCCESS) {
 		struct efi_pool_allocation *alloc = (void *)(uintptr_t)t;
@@ -516,7 +521,7 @@
 	/* Request a 32bit 64MB bounce buffer region */
 	uint64_t efi_bounce_buffer_addr = 0xffffffff;
 
-	if (efi_allocate_pages(1, EFI_LOADER_DATA,
+	if (efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS, EFI_LOADER_DATA,
 			       (64 * 1024 * 1024) >> EFI_PAGE_SHIFT,
 			       &efi_bounce_buffer_addr) != EFI_SUCCESS)
 		return -1;
diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c
index 52f1301..65f2bcf 100644
--- a/lib/efi_loader/efi_runtime.c
+++ b/lib/efi_loader/efi_runtime.c
@@ -10,7 +10,6 @@
 #include <dm.h>
 #include <efi_loader.h>
 #include <rtc.h>
-#include <asm/global_data.h>
 
 /* For manual relocation support */
 DECLARE_GLOBAL_DATA_PTR;
@@ -29,13 +28,6 @@
 static efi_status_t __efi_runtime EFIAPI efi_device_error(void);
 static efi_status_t __efi_runtime EFIAPI efi_invalid_parameter(void);
 
-#ifdef CONFIG_SYS_CACHELINE_SIZE
-#define EFI_CACHELINE_SIZE CONFIG_SYS_CACHELINE_SIZE
-#else
-/* Just use the greatest cache flush alignment requirement I'm aware of */
-#define EFI_CACHELINE_SIZE 128
-#endif
-
 #if defined(CONFIG_ARM64)
 #define R_RELATIVE	1027
 #define R_MASK		0xffffffffULL
@@ -47,6 +39,25 @@
 #include <asm/elf.h>
 #define R_RELATIVE	R_386_RELATIVE
 #define R_MASK		0xffULL
+#elif defined(CONFIG_RISCV)
+#include <elf.h>
+#define R_RELATIVE	R_RISCV_RELATIVE
+#define R_MASK		0xffULL
+#define IS_RELA		1
+
+struct dyn_sym {
+	ulong foo1;
+	ulong addr;
+	u32 foo2;
+	u32 foo3;
+};
+#ifdef CONFIG_CPU_RISCV_32
+#define R_ABSOLUTE	R_RISCV_32
+#define SYM_INDEX	8
+#else
+#define R_ABSOLUTE	R_RISCV_64
+#define SYM_INDEX	32
+#endif
 #else
 #error Need to add relocation awareness
 #endif
@@ -201,7 +212,7 @@
 		.ptr = &efi_runtime_services.get_variable,
 		.patchto = &efi_device_error,
 	}, {
-		.ptr = &efi_runtime_services.get_next_variable,
+		.ptr = &efi_runtime_services.get_next_variable_name,
 		.patchto = &efi_device_error,
 	}, {
 		.ptr = &efi_runtime_services.set_variable,
@@ -253,15 +264,27 @@
 
 		p = (void*)((ulong)rel->offset - base) + gd->relocaddr;
 
-		if ((rel->info & R_MASK) != R_RELATIVE) {
-			continue;
-		}
+		debug("%s: rel->info=%#lx *p=%#lx rel->offset=%p\n", __func__, rel->info, *p, rel->offset);
 
+		switch (rel->info & R_MASK) {
+		case R_RELATIVE:
 #ifdef IS_RELA
 		newaddr = rel->addend + offset - CONFIG_SYS_TEXT_BASE;
 #else
 		newaddr = *p - lastoff + offset;
 #endif
+			break;
+#ifdef R_ABSOLUTE
+		case R_ABSOLUTE: {
+			ulong symidx = rel->info >> SYM_INDEX;
+			extern struct dyn_sym __dyn_sym_start[];
+			newaddr = __dyn_sym_start[symidx].addr + offset;
+			break;
+		}
+#endif
+		default:
+			continue;
+		}
 
 		/* Check if the relocation is inside bounds */
 		if (map && ((newaddr < map->virtual_start) ||
@@ -421,9 +444,9 @@
 
 efi_status_t __efi_runtime EFIAPI efi_query_variable_info(
 			u32 attributes,
-			u64 maximum_variable_storage_size,
-			u64 remaining_variable_storage_size,
-			u64 maximum_variable_size)
+			u64 *maximum_variable_storage_size,
+			u64 *remaining_variable_storage_size,
+			u64 *maximum_variable_size)
 {
 	return EFI_UNSUPPORTED;
 }
@@ -441,7 +464,7 @@
 	.set_virtual_address_map = &efi_set_virtual_address_map,
 	.convert_pointer = (void *)&efi_invalid_parameter,
 	.get_variable = efi_get_variable,
-	.get_next_variable = efi_get_next_variable,
+	.get_next_variable_name = efi_get_next_variable_name,
 	.set_variable = efi_set_variable,
 	.get_next_high_mono_count = (void *)&efi_device_error,
 	.reset_system = &efi_reset_system_boottime,
diff --git a/lib/efi_loader/efi_smbios.c b/lib/efi_loader/efi_smbios.c
index 482436e..7c3fc8a 100644
--- a/lib/efi_loader/efi_smbios.c
+++ b/lib/efi_loader/efi_smbios.c
@@ -29,7 +29,12 @@
 	if (ret != EFI_SUCCESS)
 		return ret;
 
-	/* Generate SMBIOS tables */
+	/*
+	 * Generate SMBIOS tables - we know that efi_allocate_pages() returns
+	 * a 4k-aligned address, so it is safe to assume that
+	 * write_smbios_table() will write the table at that address.
+	 */
+	assert(!(dmi & 0xf));
 	write_smbios_table(dmi);
 
 	/* And expose them to our EFI payload */
diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c
index 7e0e7f0..90b6372 100644
--- a/lib/efi_loader/efi_variable.c
+++ b/lib/efi_loader/efi_variable.c
@@ -49,7 +49,7 @@
 	(strlen("efi_xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx_") + \
 		(MAX_VAR_NAME * MAX_UTF8_PER_UTF16))
 
-static int hex(unsigned char ch)
+static int hex(int ch)
 {
 	if (ch >= 'a' && ch <= 'f')
 		return ch-'a'+10;
@@ -60,44 +60,32 @@
 	return -1;
 }
 
-static const char *hex2mem(u8 *mem, const char *hexstr, int count)
+static int hex2mem(u8 *mem, const char *hexstr, int size)
 {
-	memset(mem, 0, count/2);
+	int nibble;
+	int i;
 
-	do {
-		int nibble;
-
-		*mem = 0;
-
-		if (!count || !*hexstr)
+	for (i = 0; i < size; i++) {
+		if (*hexstr == '\0')
 			break;
 
 		nibble = hex(*hexstr);
 		if (nibble < 0)
-			break;
+			return -1;
 
 		*mem = nibble;
-		count--;
 		hexstr++;
 
-		if (!count || !*hexstr)
-			break;
-
 		nibble = hex(*hexstr);
 		if (nibble < 0)
-			break;
+			return -1;
 
 		*mem = (*mem << 4) | nibble;
-		count--;
 		hexstr++;
 		mem++;
+	}
 
-	} while (1);
-
-	if (*hexstr)
-		return hexstr;
-
-	return NULL;
+	return i;
 }
 
 static char *mem2hex(char *hexstr, const u8 *mem, int count)
@@ -113,8 +101,8 @@
 	return hexstr;
 }
 
-static efi_status_t efi_to_native(char *native, s16 *variable_name,
-		efi_guid_t *vendor)
+static efi_status_t efi_to_native(char *native, u16 *variable_name,
+				  efi_guid_t *vendor)
 {
 	size_t len;
 
@@ -176,9 +164,9 @@
 }
 
 /* http://wiki.phoenix.com/wiki/index.php/EFI_RUNTIME_SERVICES#GetVariable.28.29 */
-efi_status_t EFIAPI efi_get_variable(s16 *variable_name,
-		efi_guid_t *vendor, u32 *attributes,
-		unsigned long *data_size, void *data)
+efi_status_t EFIAPI efi_get_variable(u16 *variable_name, efi_guid_t *vendor,
+				     u32 *attributes, efi_uintn_t *data_size,
+				     void *data)
 {
 	char native_name[MAX_NATIVE_VAR_NAME + 1];
 	efi_status_t ret;
@@ -209,8 +197,12 @@
 	if ((s = prefix(val, "(blob)"))) {
 		unsigned len = strlen(s);
 
+		/* number of hexadecimal digits must be even */
+		if (len & 1)
+			return EFI_EXIT(EFI_DEVICE_ERROR);
+
 		/* two characters per byte: */
-		len = DIV_ROUND_UP(len, 2);
+		len /= 2;
 		*data_size = len;
 
 		if (in_size < len)
@@ -219,7 +211,7 @@
 		if (!data)
 			return EFI_EXIT(EFI_INVALID_PARAMETER);
 
-		if (hex2mem(data, s, len * 2))
+		if (hex2mem(data, s, len) != len)
 			return EFI_EXIT(EFI_DEVICE_ERROR);
 
 		debug("%s: got value: \"%s\"\n", __func__, s);
@@ -250,9 +242,9 @@
 }
 
 /* http://wiki.phoenix.com/wiki/index.php/EFI_RUNTIME_SERVICES#GetNextVariableName.28.29 */
-efi_status_t EFIAPI efi_get_next_variable(
-		unsigned long *variable_name_size,
-		s16 *variable_name, efi_guid_t *vendor)
+efi_status_t EFIAPI efi_get_next_variable_name(efi_uintn_t *variable_name_size,
+					       u16 *variable_name,
+					       efi_guid_t *vendor)
 {
 	EFI_ENTRY("%p \"%ls\" %pUl", variable_name_size, variable_name, vendor);
 
@@ -260,16 +252,16 @@
 }
 
 /* http://wiki.phoenix.com/wiki/index.php/EFI_RUNTIME_SERVICES#SetVariable.28.29 */
-efi_status_t EFIAPI efi_set_variable(s16 *variable_name,
-		efi_guid_t *vendor, u32 attributes,
-		unsigned long data_size, void *data)
+efi_status_t EFIAPI efi_set_variable(u16 *variable_name, efi_guid_t *vendor,
+				     u32 attributes, efi_uintn_t data_size,
+				     void *data)
 {
 	char native_name[MAX_NATIVE_VAR_NAME + 1];
 	efi_status_t ret = EFI_SUCCESS;
 	char *val, *s;
 	u32 attr;
 
-	EFI_ENTRY("\"%ls\" %pUl %x %lu %p", variable_name, vendor, attributes,
+	EFI_ENTRY("\"%ls\" %pUl %x %zu %p", variable_name, vendor, attributes,
 		  data_size, data);
 
 	if (!variable_name || !vendor)
diff --git a/lib/efi_selftest/Kconfig b/lib/efi_selftest/Kconfig
index 3b5f3a1..59f9f36 100644
--- a/lib/efi_selftest/Kconfig
+++ b/lib/efi_selftest/Kconfig
@@ -1,6 +1,8 @@
 config CMD_BOOTEFI_SELFTEST
 	bool "Allow booting an EFI efi_selftest"
 	depends on CMD_BOOTEFI
+	imply FAT
+	imply FAT_WRITE
 	help
 	  This adds an EFI test application to U-Boot that can be executed
 	  with the 'bootefi selftest' command. It provides extended tests of
diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile
index 80c4302..4fe404d 100644
--- a/lib/efi_selftest/Makefile
+++ b/lib/efi_selftest/Makefile
@@ -28,8 +28,13 @@
 efi_selftest_textoutput.o \
 efi_selftest_tpl.o \
 efi_selftest_util.o \
+efi_selftest_variables.o \
 efi_selftest_watchdog.o
 
+ifeq ($(CONFIG_CMD_BOOTEFI_SELFTEST),y)
+obj-$(CONFIG_CPU_V7) += efi_selftest_unaligned.o
+endif
+
 ifeq ($(CONFIG_BLK)$(CONFIG_PARTITIONS),yy)
 obj-$(CONFIG_CMD_BOOTEFI_SELFTEST) += efi_selftest_block_device.o
 endif
diff --git a/lib/efi_selftest/efi_selftest_controllers.c b/lib/efi_selftest/efi_selftest_controllers.c
index e30c11b..ceefa03 100644
--- a/lib/efi_selftest/efi_selftest_controllers.c
+++ b/lib/efi_selftest/efi_selftest_controllers.c
@@ -6,7 +6,7 @@
  *
  * This unit test checks the following protocol services:
  * ConnectController, DisconnectController,
- * InstallProtocol, UninstallProtocol,
+ * InstallProtocol, ReinstallProtocol, UninstallProtocol,
  * OpenProtocol, CloseProtcol, OpenProtocolInformation
  */
 
@@ -14,6 +14,8 @@
 
 #define NUMBER_OF_CHILD_CONTROLLERS 4
 
+static int interface1 = 1;
+static int interface2 = 2;
 static struct efi_boot_services *boottime;
 const efi_guid_t guid_driver_binding_protocol =
 			EFI_DRIVER_BINDING_PROTOCOL_GUID;
@@ -271,7 +273,7 @@
 	/* Create controller handle */
 	ret = boottime->install_protocol_interface(
 			&handle_controller, &guid_controller,
-			EFI_NATIVE_INTERFACE, NULL);
+			EFI_NATIVE_INTERFACE, &interface1);
 	if (ret != EFI_SUCCESS) {
 		efi_st_error("InstallProtocolInterface failed\n");
 		return EFI_ST_FAILURE;
@@ -299,6 +301,7 @@
  * Disconnect and destroy the remaining child controllers.
  *
  * Connect a controller to a driver.
+ * Reinstall the driver protocol on the controller.
  * Uninstall the driver protocol from the controller.
  */
 static int execute(void)
@@ -361,9 +364,35 @@
 		efi_st_error("Number of children %u != %u\n",
 			     (unsigned int)count, NUMBER_OF_CHILD_CONTROLLERS);
 	}
+	/* Try to uninstall controller protocol using the wrong interface */
+	ret = boottime->uninstall_protocol_interface(handle_controller,
+						     &guid_controller,
+						     &interface2);
+	if (ret == EFI_SUCCESS) {
+		efi_st_error(
+			"Interface not checked when uninstalling protocol\n");
+		return EFI_ST_FAILURE;
+	}
+	/* Reinstall controller protocol */
+	ret = boottime->reinstall_protocol_interface(handle_controller,
+						     &guid_controller,
+						     &interface1,
+						     &interface2);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("Failed to reinstall protocols\n");
+		return EFI_ST_FAILURE;
+	}
+	/* Check number of child controllers */
+	ret = count_child_controllers(handle_controller, &guid_controller,
+				      &count);
+	if (ret != EFI_SUCCESS || count != NUMBER_OF_CHILD_CONTROLLERS) {
+		efi_st_error("Number of children %u != %u\n",
+			     (unsigned int)count, NUMBER_OF_CHILD_CONTROLLERS);
+	}
 	/* Uninstall controller protocol */
 	ret = boottime->uninstall_protocol_interface(handle_controller,
-						     &guid_controller, NULL);
+						     &guid_controller,
+						     &interface2);
 	if (ret != EFI_SUCCESS) {
 		efi_st_error("Failed to uninstall protocols\n");
 		return EFI_ST_FAILURE;
diff --git a/lib/efi_selftest/efi_selftest_manageprotocols.c b/lib/efi_selftest/efi_selftest_manageprotocols.c
index 3e4755c..44b8da3 100644
--- a/lib/efi_selftest/efi_selftest_manageprotocols.c
+++ b/lib/efi_selftest/efi_selftest_manageprotocols.c
@@ -335,7 +335,7 @@
 		return EFI_ST_FAILURE;
 	}
 	ret = boottime->uninstall_protocol_interface(handle1, &guid3,
-						     &interface1);
+						     &interface3);
 	if (ret != EFI_SUCCESS) {
 		efi_st_error("UninstallProtocolInterface failed\n");
 		return EFI_ST_FAILURE;
diff --git a/lib/efi_selftest/efi_selftest_textoutput.c b/lib/efi_selftest/efi_selftest_textoutput.c
index 3533647..a87f65e 100644
--- a/lib/efi_selftest/efi_selftest_textoutput.c
+++ b/lib/efi_selftest/efi_selftest_textoutput.c
@@ -23,6 +23,13 @@
 	size_t background;
 	size_t attrib;
 	efi_status_t ret;
+	s16 col;
+	u16 cr[] = { 0x0d, 0x00 };
+	u16 lf[] = { 0x0a, 0x00 };
+	u16 brahmi[] = { /* 2 Brahmi letters */
+		0xD804, 0xDC05,
+		0xD804, 0xDC22,
+		0};
 
 	/* SetAttribute */
 	efi_st_printf("\nColor palette\n");
@@ -42,6 +49,77 @@
 		efi_st_error("TestString failed for ANSI characters\n");
 		return EFI_ST_FAILURE;
 	}
+	/* OutputString */
+	ret = con_out->output_string(con_out,
+				     L"Testing cursor column update\n");
+	if (ret != EFI_ST_SUCCESS) {
+		efi_st_error("OutputString failed for ANSI characters");
+		return EFI_ST_FAILURE;
+	}
+	col = con_out->mode->cursor_column;
+	ret = con_out->output_string(con_out, lf);
+	if (ret != EFI_ST_SUCCESS) {
+		efi_st_error("OutputString failed for line feed\n");
+		return EFI_ST_FAILURE;
+	}
+	if (con_out->mode->cursor_column != col) {
+		efi_st_error("Cursor column changed by line feed\n");
+		return EFI_ST_FAILURE;
+	}
+	ret = con_out->output_string(con_out, cr);
+	if (ret != EFI_ST_SUCCESS) {
+		efi_st_error("OutputString failed for carriage return\n");
+		return EFI_ST_FAILURE;
+	}
+	if (con_out->mode->cursor_column) {
+		efi_st_error("Cursor column not 0 at beginning of line\n");
+		return EFI_ST_FAILURE;
+	}
+	ret = con_out->output_string(con_out, L"123");
+	if (ret != EFI_ST_SUCCESS) {
+		efi_st_error("OutputString failed for ANSI characters\n");
+		return EFI_ST_FAILURE;
+	}
+	if (con_out->mode->cursor_column != 3) {
+		efi_st_error("Cursor column not incremented properly\n");
+		return EFI_ST_FAILURE;
+	}
+	ret = con_out->output_string(con_out, L"\b");
+	if (ret != EFI_ST_SUCCESS) {
+		efi_st_error("OutputString failed for backspace\n");
+		return EFI_ST_FAILURE;
+	}
+	if (con_out->mode->cursor_column != 2) {
+		efi_st_error("Cursor column not decremented properly\n");
+		return EFI_ST_FAILURE;
+	}
+	ret = con_out->output_string(con_out, L"\b\b");
+	if (ret != EFI_ST_SUCCESS) {
+		efi_st_error("OutputString failed for backspace\n");
+		return EFI_ST_FAILURE;
+	}
+	if (con_out->mode->cursor_column) {
+		efi_st_error("Cursor column not decremented properly\n");
+		return EFI_ST_FAILURE;
+	}
+	ret = con_out->output_string(con_out, L"\b\b");
+	if (ret != EFI_ST_SUCCESS) {
+		efi_st_error("OutputString failed for backspace\n");
+		return EFI_ST_FAILURE;
+	}
+	if (con_out->mode->cursor_column) {
+		efi_st_error("Cursor column decremented past zero\n");
+		return EFI_ST_FAILURE;
+	}
+	ret = con_out->output_string(con_out, brahmi);
+	if (ret != EFI_ST_SUCCESS) {
+		efi_st_todo("Unicode output not fully supported\n");
+	} else if (con_out->mode->cursor_column != 2) {
+		efi_st_printf("Unicode not handled properly\n");
+		return EFI_ST_FAILURE;
+	}
+	efi_st_printf("\n");
+
 	return EFI_ST_SUCCESS;
 }
 
diff --git a/lib/efi_selftest/efi_selftest_unaligned.c b/lib/efi_selftest/efi_selftest_unaligned.c
new file mode 100644
index 0000000..1802948
--- /dev/null
+++ b/lib/efi_selftest/efi_selftest_unaligned.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * efi_selftest_unaligned
+ *
+ * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * Test unaligned memory access on ARMv7.
+ */
+
+#include <efi_selftest.h>
+
+struct aligned_buffer {
+	char a[8] __aligned(8);
+};
+
+/*
+ * Return an u32 at a give address.
+ * If the address is not four byte aligned, an unaligned memory access
+ * occurs.
+ *
+ * @addr:	address to read
+ * @return:	value at the address
+ */
+static inline u32 deref(u32 *addr)
+{
+	int ret;
+
+	asm(
+		"ldr %[out], [%[in]]\n\t"
+		: [out] "=r" (ret)
+		: [in] "r" (addr)
+	);
+	return ret;
+}
+
+/*
+ * Execute unit test.
+ * An unaligned memory access is executed. The result is checked.
+ *
+ * @return:	EFI_ST_SUCCESS for success
+ */
+static int execute(void)
+{
+	struct aligned_buffer buf = {
+		{0, 1, 2, 3, 4, 5, 6, 7},
+		};
+	void *v = &buf;
+	u32 r = 0;
+
+	/* Read an unaligned address */
+	r = deref(v + 1);
+
+	/* UEFI only supports low endian systems */
+	if (r != 0x04030201) {
+		efi_st_error("Unaligned access failed");
+		return EFI_ST_FAILURE;
+	}
+
+	return EFI_ST_SUCCESS;
+}
+
+EFI_UNIT_TEST(unaligned) = {
+	.name = "unaligned memory access",
+	.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
+	.execute = execute,
+};
diff --git a/lib/efi_selftest/efi_selftest_variables.c b/lib/efi_selftest/efi_selftest_variables.c
new file mode 100644
index 0000000..146378f
--- /dev/null
+++ b/lib/efi_selftest/efi_selftest_variables.c
@@ -0,0 +1,196 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * efi_selftest_variables
+ *
+ * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * This unit test checks the following protocol services:
+ * ConnectController, DisconnectController,
+ * InstallProtocol, ReinstallProtocol, UninstallProtocol,
+ * OpenProtocol, CloseProtcol, OpenProtocolInformation
+ */
+
+#include <efi_selftest.h>
+
+#define EFI_ST_MAX_DATA_SIZE 16
+#define EFI_ST_MAX_VARNAME_SIZE 40
+
+static struct efi_boot_services *boottime;
+static struct efi_runtime_services *runtime;
+static efi_guid_t guid_vendor0 =
+	EFI_GUID(0x67029eb5, 0x0af2, 0xf6b1,
+		 0xda, 0x53, 0xfc, 0xb5, 0x66, 0xdd, 0x1c, 0xe6);
+static efi_guid_t guid_vendor1 =
+	EFI_GUID(0xff629290, 0x1fc1, 0xd73f,
+		 0x8f, 0xb1, 0x32, 0xf9, 0x0c, 0xa0, 0x42, 0xea);
+
+/*
+ * Setup unit test.
+ *
+ * @handle	handle of the loaded image
+ * @systable	system table
+ */
+static int setup(const efi_handle_t img_handle,
+		 const struct efi_system_table *systable)
+{
+	boottime = systable->boottime;
+	runtime = systable->runtime;
+
+	return EFI_ST_SUCCESS;
+}
+
+/*
+ * Execute unit test.
+ */
+static int execute(void)
+{
+	efi_status_t ret;
+	efi_uintn_t len;
+	u32 attr;
+	u8 v[16] = {0x5d, 0xd1, 0x5e, 0x51, 0x5a, 0x05, 0xc7, 0x0c,
+		    0x35, 0x4a, 0xae, 0x87, 0xa5, 0xdf, 0x0f, 0x65,};
+	u8 data[EFI_ST_MAX_DATA_SIZE];
+	u16 varname[EFI_ST_MAX_VARNAME_SIZE];
+	int flag;
+	efi_guid_t guid;
+	u64 max_storage, rem_storage, max_size;
+
+	ret = runtime->query_variable_info(EFI_VARIABLE_BOOTSERVICE_ACCESS,
+					   &max_storage, &rem_storage,
+					   &max_size);
+	if (ret != EFI_SUCCESS) {
+		efi_st_todo("QueryVariableInfo failed\n");
+	} else if (!max_storage || !rem_storage || !max_size) {
+		efi_st_error("QueryVariableInfo: wrong info\n");
+		return EFI_ST_FAILURE;
+	}
+	/* Set variable 0 */
+	ret = runtime->set_variable(L"efi_st_var0", &guid_vendor0,
+				    EFI_VARIABLE_BOOTSERVICE_ACCESS,
+				    3, v + 4);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("SetVariable failed\n");
+		return EFI_ST_FAILURE;
+	}
+	data[3] = 0xff;
+	len = 3;
+	ret = runtime->get_variable(L"efi_st_var0", &guid_vendor0,
+				    &attr, &len, data);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("GetVariable failed\n");
+		return EFI_ST_FAILURE;
+	}
+	if (efi_st_memcmp(data, v + 4, 3)) {
+		efi_st_error("GetVariable returned wrong value\n");
+		return EFI_ST_FAILURE;
+	}
+	if (data[3] != 0xff) {
+		efi_st_error("GetVariable wrote past the end of the buffer\n");
+		return EFI_ST_FAILURE;
+	}
+	/* Set variable 1 */
+	ret = runtime->set_variable(L"efi_st_var1", &guid_vendor1,
+				    EFI_VARIABLE_BOOTSERVICE_ACCESS,
+				    8, v);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("SetVariable failed\n");
+		return EFI_ST_FAILURE;
+	}
+	len = EFI_ST_MAX_DATA_SIZE;
+	ret = runtime->get_variable(L"efi_st_var1", &guid_vendor1,
+				    &attr, &len, data);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("GetVariable failed\n");
+		return EFI_ST_FAILURE;
+	}
+	if (len != 8) {
+		efi_st_error("GetVariable returned wrong length %u\n",
+			     (unsigned int)len);
+		return EFI_ST_FAILURE;
+	}
+	if (efi_st_memcmp(data, v, 8)) {
+		efi_st_error("GetVariable returned wrong value\n");
+		return EFI_ST_FAILURE;
+	}
+	/* Append variable 1 */
+	ret = runtime->set_variable(L"efi_st_var1", &guid_vendor1,
+				    EFI_VARIABLE_BOOTSERVICE_ACCESS |
+				    EFI_VARIABLE_APPEND_WRITE,
+				    7, v + 8);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("SetVariable failed\n");
+		return EFI_ST_FAILURE;
+	}
+	len = EFI_ST_MAX_DATA_SIZE;
+	ret = runtime->get_variable(L"efi_st_var1", &guid_vendor1,
+				    &attr, &len, data);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("GetVariable failed\n");
+		return EFI_ST_FAILURE;
+	}
+	if (len != 15)
+		efi_st_todo("GetVariable returned wrong length %u\n",
+			    (unsigned int)len);
+	if (efi_st_memcmp(data, v, len))
+		efi_st_todo("GetVariable returned wrong value\n");
+	/* Enumerate variables */
+	boottime->set_mem(&guid, 16, 0);
+	*varname = 0;
+	flag = 0;
+	for (;;) {
+		len = EFI_ST_MAX_VARNAME_SIZE;
+		ret = runtime->get_next_variable_name(&len, varname, &guid);
+		if (ret == EFI_NOT_FOUND)
+			break;
+		if (ret != EFI_SUCCESS) {
+			efi_st_todo("GetNextVariableName failed\n");
+			break;
+		}
+		if (!efi_st_memcmp(&guid, &guid_vendor0, sizeof(efi_guid_t)) &&
+		    !efi_st_strcmp_16_8(varname, "efi_st_var0"))
+			flag |= 2;
+		if (!efi_st_memcmp(&guid, &guid_vendor1, sizeof(efi_guid_t)) &&
+		    !efi_st_strcmp_16_8(varname, "efi_st_var1"))
+			flag |= 2;
+	}
+	if (flag != 3)
+		efi_st_todo(
+			"GetNextVariableName did not return all variables\n");
+	/* Delete variable 1 */
+	ret = runtime->set_variable(L"efi_st_var1", &guid_vendor1,
+				    0, 0, NULL);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("SetVariable failed\n");
+		return EFI_ST_FAILURE;
+	}
+	len = EFI_ST_MAX_DATA_SIZE;
+	ret = runtime->get_variable(L"efi_st_var1", &guid_vendor1,
+				    &attr, &len, data);
+	if (ret != EFI_NOT_FOUND) {
+		efi_st_error("Variable was not deleted\n");
+		return EFI_ST_FAILURE;
+	}
+	/* Delete variable 0 */
+	ret = runtime->set_variable(L"efi_st_var0", &guid_vendor0,
+				    0, 0, NULL);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("SetVariable failed\n");
+		return EFI_ST_FAILURE;
+	}
+	len = EFI_ST_MAX_DATA_SIZE;
+	ret = runtime->get_variable(L"efi_st_var0", &guid_vendor0,
+				    &attr, &len, data);
+	if (ret != EFI_NOT_FOUND) {
+		efi_st_error("Variable was not deleted\n");
+		return EFI_ST_FAILURE;
+	}
+
+	return EFI_ST_SUCCESS;
+}
+
+EFI_UNIT_TEST(variables) = {
+	.name = "variables",
+	.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
+	.setup = setup,
+	.execute = execute,
+};
diff --git a/common/image-sparse.c b/lib/image-sparse.c
similarity index 88%
rename from common/image-sparse.c
rename to lib/image-sparse.c
index 9223b9a..0360621 100644
--- a/common/image-sparse.c
+++ b/lib/image-sparse.c
@@ -44,14 +44,10 @@
 
 #include <linux/math64.h>
 
-#ifndef CONFIG_FASTBOOT_FLASH_FILLBUF_SIZE
-#define CONFIG_FASTBOOT_FLASH_FILLBUF_SIZE (1024 * 512)
-#endif
-
-static void default_log(const char *ignored) {}
+static void default_log(const char *ignored, char *response) {}
 
 int write_sparse_image(struct sparse_storage *info,
-		       const char *part_name, void *data)
+		       const char *part_name, void *data, char *response)
 {
 	lbaint_t blk;
 	lbaint_t blkcnt;
@@ -69,7 +65,7 @@
 	int i;
 	int j;
 
-	fill_buf_num_blks = CONFIG_FASTBOOT_FLASH_FILLBUF_SIZE / info->blksz;
+	fill_buf_num_blks = CONFIG_IMAGE_SPARSE_FILLBUF_SIZE / info->blksz;
 
 	/* Read and skip over sparse image header */
 	sparse_header = (sparse_header_t *)data;
@@ -104,7 +100,7 @@
 	if (offset) {
 		printf("%s: Sparse image block size issue [%u]\n",
 		       __func__, sparse_header->blk_sz);
-		info->mssg("sparse image block size issue");
+		info->mssg("sparse image block size issue", response);
 		return -1;
 	}
 
@@ -139,7 +135,8 @@
 		case CHUNK_TYPE_RAW:
 			if (chunk_header->total_sz !=
 			    (sparse_header->chunk_hdr_sz + chunk_data_sz)) {
-				info->mssg("Bogus chunk size for chunk type Raw");
+				info->mssg("Bogus chunk size for chunk type Raw",
+					   response);
 				return -1;
 			}
 
@@ -147,7 +144,8 @@
 				printf(
 				    "%s: Request would exceed partition size!\n",
 				    __func__);
-				info->mssg("Request would exceed partition size!");
+				info->mssg("Request would exceed partition size!",
+					   response);
 				return -1;
 			}
 
@@ -157,7 +155,7 @@
 				printf("%s: %s" LBAFU " [" LBAFU "]\n",
 				       __func__, "Write failed, block #",
 				       blk, blks);
-				info->mssg("flash write failure");
+				info->mssg("flash write failure", response);
 				return -1;
 			}
 			blk += blks;
@@ -169,7 +167,7 @@
 		case CHUNK_TYPE_FILL:
 			if (chunk_header->total_sz !=
 			    (sparse_header->chunk_hdr_sz + sizeof(uint32_t))) {
-				info->mssg("Bogus chunk size for chunk type FILL");
+				info->mssg("Bogus chunk size for chunk type FILL", response);
 				return -1;
 			}
 
@@ -179,7 +177,8 @@
 						info->blksz * fill_buf_num_blks,
 						ARCH_DMA_MINALIGN));
 			if (!fill_buf) {
-				info->mssg("Malloc failed for: CHUNK_TYPE_FILL");
+				info->mssg("Malloc failed for: CHUNK_TYPE_FILL",
+					   response);
 				return -1;
 			}
 
@@ -196,7 +195,8 @@
 				printf(
 				    "%s: Request would exceed partition size!\n",
 				    __func__);
-				info->mssg("Request would exceed partition size!");
+				info->mssg("Request would exceed partition size!",
+					   response);
 				return -1;
 			}
 
@@ -211,7 +211,8 @@
 					       __func__,
 					       "Write failed, block #",
 					       blk, j);
-					info->mssg("flash write failure");
+					info->mssg("flash write failure",
+						   response);
 					free(fill_buf);
 					return -1;
 				}
@@ -231,7 +232,8 @@
 		case CHUNK_TYPE_CRC32:
 			if (chunk_header->total_sz !=
 			    sparse_header->chunk_hdr_sz) {
-				info->mssg("Bogus chunk size for chunk type Dont Care");
+				info->mssg("Bogus chunk size for chunk type Dont Care",
+					   response);
 				return -1;
 			}
 			total_blocks += chunk_header->chunk_sz;
@@ -241,7 +243,7 @@
 		default:
 			printf("%s: Unknown chunk type: %x\n", __func__,
 			       chunk_header->chunk_type);
-			info->mssg("Unknown chunk type");
+			info->mssg("Unknown chunk type", response);
 			return -1;
 		}
 	}
@@ -251,7 +253,7 @@
 	printf("........ wrote %u bytes to '%s'\n", bytes_written, part_name);
 
 	if (total_blocks != sparse_header->total_blks) {
-		info->mssg("sparse image write failure");
+		info->mssg("sparse image write failure", response);
 		return -1;
 	}
 
diff --git a/lib/libfdt/fdt_ro.c b/lib/libfdt/fdt_ro.c
index 4b7008d..b6ca4e0 100644
--- a/lib/libfdt/fdt_ro.c
+++ b/lib/libfdt/fdt_ro.c
@@ -76,8 +76,8 @@
 int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
 {
 	FDT_CHECK_HEADER(fdt);
-	*address = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->address);
-	*size = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->size);
+	*address = fdt64_to_cpu(fdt_mem_rsv_(fdt, n)->address);
+	*size = fdt64_to_cpu(fdt_mem_rsv_(fdt, n)->size);
 	return 0;
 }
 
@@ -85,7 +85,7 @@
 {
 	int i = 0;
 
-	while (fdt64_to_cpu(_fdt_mem_rsv(fdt, i)->size) != 0)
+	while (fdt64_to_cpu(fdt_mem_rsv_(fdt, i)->size) != 0)
 		i++;
 	return i;
 }
@@ -211,11 +211,11 @@
 
 const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)
 {
-	const struct fdt_node_header *nh = _fdt_offset_ptr(fdt, nodeoffset);
+	const struct fdt_node_header *nh = fdt_offset_ptr_(fdt, nodeoffset);
 	int err;
 
 	if (((err = fdt_check_header(fdt)) != 0)
-	    || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0))
+	    || ((err = fdt_check_node_offset_(fdt, nodeoffset)) < 0))
 			goto fail;
 
 	if (len)
@@ -233,7 +233,7 @@
 {
 	int offset;
 
-	if ((offset = _fdt_check_node_offset(fdt, nodeoffset)) < 0)
+	if ((offset = fdt_check_node_offset_(fdt, nodeoffset)) < 0)
 		return offset;
 
 	return _nextprop(fdt, offset);
@@ -241,7 +241,7 @@
 
 int fdt_next_property_offset(const void *fdt, int offset)
 {
-	if ((offset = _fdt_check_prop_offset(fdt, offset)) < 0)
+	if ((offset = fdt_check_prop_offset_(fdt, offset)) < 0)
 		return offset;
 
 	return _nextprop(fdt, offset);
@@ -254,13 +254,13 @@
 	int err;
 	const struct fdt_property *prop;
 
-	if ((err = _fdt_check_prop_offset(fdt, offset)) < 0) {
+	if ((err = fdt_check_prop_offset_(fdt, offset)) < 0) {
 		if (lenp)
 			*lenp = err;
 		return NULL;
 	}
 
-	prop = _fdt_offset_ptr(fdt, offset);
+	prop = fdt_offset_ptr_(fdt, offset);
 
 	if (lenp)
 		*lenp = fdt32_to_cpu(prop->len);
diff --git a/lib/tpm-common.c b/lib/tpm-common.c
new file mode 100644
index 0000000..43b5308
--- /dev/null
+++ b/lib/tpm-common.c
@@ -0,0 +1,197 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2013 The Chromium OS Authors.
+ * Coypright (c) 2013 Guntermann & Drunck GmbH
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/unaligned.h>
+#include <tpm-common.h>
+#include "tpm-utils.h"
+
+int pack_byte_string(u8 *str, size_t size, const char *format, ...)
+{
+	va_list args;
+	size_t offset = 0, length = 0;
+	u8 *data = NULL;
+	u32 value = 0;
+
+	va_start(args, format);
+	for (; *format; format++) {
+		switch (*format) {
+		case 'b':
+			offset = va_arg(args, size_t);
+			value = va_arg(args, int);
+			length = 1;
+			break;
+		case 'w':
+			offset = va_arg(args, size_t);
+			value = va_arg(args, int);
+			length = 2;
+			break;
+		case 'd':
+			offset = va_arg(args, size_t);
+			value = va_arg(args, u32);
+			length = 4;
+			break;
+		case 's':
+			offset = va_arg(args, size_t);
+			data = va_arg(args, u8 *);
+			length = va_arg(args, u32);
+			break;
+		default:
+			debug("Couldn't recognize format string\n");
+			va_end(args);
+			return -1;
+		}
+
+		if (offset + length > size) {
+			va_end(args);
+			return -1;
+		}
+
+		switch (*format) {
+		case 'b':
+			str[offset] = value;
+			break;
+		case 'w':
+			put_unaligned_be16(value, str + offset);
+			break;
+		case 'd':
+			put_unaligned_be32(value, str + offset);
+			break;
+		case 's':
+			memcpy(str + offset, data, length);
+			break;
+		}
+	}
+	va_end(args);
+
+	return 0;
+}
+
+int unpack_byte_string(const u8 *str, size_t size, const char *format, ...)
+{
+	va_list args;
+	size_t offset = 0, length = 0;
+	u8 *ptr8 = NULL;
+	u16 *ptr16 = NULL;
+	u32 *ptr32 = NULL;
+
+	va_start(args, format);
+	for (; *format; format++) {
+		switch (*format) {
+		case 'b':
+			offset = va_arg(args, size_t);
+			ptr8 = va_arg(args, u8 *);
+			length = 1;
+			break;
+		case 'w':
+			offset = va_arg(args, size_t);
+			ptr16 = va_arg(args, u16 *);
+			length = 2;
+			break;
+		case 'd':
+			offset = va_arg(args, size_t);
+			ptr32 = va_arg(args, u32 *);
+			length = 4;
+			break;
+		case 's':
+			offset = va_arg(args, size_t);
+			ptr8 = va_arg(args, u8 *);
+			length = va_arg(args, u32);
+			break;
+		default:
+			va_end(args);
+			debug("Couldn't recognize format string\n");
+			return -1;
+		}
+
+		if (offset + length > size) {
+			va_end(args);
+			return -1;
+		}
+
+		switch (*format) {
+		case 'b':
+			*ptr8 = str[offset];
+			break;
+		case 'w':
+			*ptr16 = get_unaligned_be16(str + offset);
+			break;
+		case 'd':
+			*ptr32 = get_unaligned_be32(str + offset);
+			break;
+		case 's':
+			memcpy(ptr8, str + offset, length);
+			break;
+		}
+	}
+	va_end(args);
+
+	return 0;
+}
+
+u32 tpm_command_size(const void *command)
+{
+	const size_t command_size_offset = 2;
+
+	return get_unaligned_be32(command + command_size_offset);
+}
+
+u32 tpm_return_code(const void *response)
+{
+	const size_t return_code_offset = 6;
+
+	return get_unaligned_be32(response + return_code_offset);
+}
+
+u32 tpm_sendrecv_command(const void *command, void *response, size_t *size_ptr)
+{
+	struct udevice *dev;
+	int err, ret;
+	u8 response_buffer[COMMAND_BUFFER_SIZE];
+	size_t response_length;
+	int i;
+
+	if (response) {
+		response_length = *size_ptr;
+	} else {
+		response = response_buffer;
+		response_length = sizeof(response_buffer);
+	}
+
+	ret = uclass_first_device_err(UCLASS_TPM, &dev);
+	if (ret)
+		return ret;
+	err = tpm_xfer(dev, command, tpm_command_size(command),
+		       response, &response_length);
+
+	if (err < 0)
+		return err;
+
+	if (size_ptr)
+		*size_ptr = response_length;
+
+	ret = tpm_return_code(response);
+
+	log(LOGC_NONE, LOGL_DEBUG, "TPM response [ret:%d]: ", ret);
+	for (i = 0; i < response_length; i++)
+		log(LOGC_NONE, LOGL_DEBUG, "%02x ", ((u8 *)response)[i]);
+	log(LOGC_NONE, LOGL_DEBUG, "\n");
+
+	return ret;
+}
+
+int tpm_init(void)
+{
+	struct udevice *dev;
+	int err;
+
+	err = uclass_first_device_err(UCLASS_TPM, &dev);
+	if (err)
+		return err;
+
+	return tpm_open(dev);
+}
diff --git a/lib/tpm-utils.h b/lib/tpm-utils.h
new file mode 100644
index 0000000..a9cb7dc
--- /dev/null
+++ b/lib/tpm-utils.h
@@ -0,0 +1,101 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2013 The Chromium OS Authors.
+ * Coypright (c) 2013 Guntermann & Drunck GmbH
+ */
+
+#ifndef __TPM_UTILS_H
+#define __TPM_UTILS_H
+
+#define COMMAND_BUFFER_SIZE 256
+
+/* Internal error of TPM command library */
+#define TPM_LIB_ERROR ((u32)~0u)
+
+/* To make strings of commands more easily */
+#define __MSB(x) ((x) >> 8)
+#define __LSB(x) ((x) & 0xFF)
+#define tpm_u16(x) __MSB(x), __LSB(x)
+#define tpm_u32(x) tpm_u16((x) >> 16), tpm_u16((x) & 0xFFFF)
+
+/**
+ * tpm_open() - Request access to locality 0 for the caller
+ *
+ * After all commands have been completed the caller is supposed to
+ * call tpm_close().
+ *
+ * Returns 0 on success, -ve on failure.
+ */
+int tpm_open(struct udevice *dev);
+
+/**
+ * tpm_close() - Close the current session
+ *
+ * Releasing the locked locality. Returns 0 on success, -ve 1 on
+ * failure (in case lock removal did not succeed).
+ */
+int tpm_close(struct udevice *dev);
+
+/**
+ * Pack data into a byte string.  The data types are specified in
+ * the format string: 'b' means unsigned byte, 'w' unsigned word,
+ * 'd' unsigned double word, and 's' byte string.  The data are a
+ * series of offsets and values (for type byte string there are also
+ * lengths).  The data values are packed into the byte string
+ * sequentially, and so a latter value could over-write a former
+ * value.
+ *
+ * @param str		output string
+ * @param size		size of output string
+ * @param format	format string
+ * @param ...		data points
+ * @return 0 on success, non-0 on error
+ */
+int pack_byte_string(u8 *str, size_t size, const char *format, ...);
+
+/**
+ * Unpack data from a byte string.  The data types are specified in
+ * the format string: 'b' means unsigned byte, 'w' unsigned word,
+ * 'd' unsigned double word, and 's' byte string.  The data are a
+ * series of offsets and pointers (for type byte string there are also
+ * lengths).
+ *
+ * @param str		output string
+ * @param size		size of output string
+ * @param format	format string
+ * @param ...		data points
+ * @return 0 on success, non-0 on error
+ */
+int unpack_byte_string(const u8 *str, size_t size, const char *format, ...);
+
+/**
+ * Get TPM command size.
+ *
+ * @param command	byte string of TPM command
+ * @return command size of the TPM command
+ */
+u32 tpm_command_size(const void *command);
+
+/**
+ * Get TPM response return code, which is one of TPM_RESULT values.
+ *
+ * @param response	byte string of TPM response
+ * @return return code of the TPM response
+ */
+u32 tpm_return_code(const void *response);
+
+/**
+ * Send a TPM command and return response's return code, and optionally
+ * return response to caller.
+ *
+ * @param command	byte string of TPM command
+ * @param response	output buffer for TPM response, or NULL if the
+ *			caller does not care about it
+ * @param size_ptr	output buffer size (input parameter) and TPM
+ *			response length (output parameter); this parameter
+ *			is a bidirectional
+ * @return return code of the TPM response
+ */
+u32 tpm_sendrecv_command(const void *command, void *response, size_t *size_ptr);
+
+#endif /* __TPM_UTILS_H */
diff --git a/lib/tpm-v1.c b/lib/tpm-v1.c
new file mode 100644
index 0000000..7aecb24
--- /dev/null
+++ b/lib/tpm-v1.c
@@ -0,0 +1,852 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2013 The Chromium OS Authors.
+ * Coypright (c) 2013 Guntermann & Drunck GmbH
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/unaligned.h>
+#include <u-boot/sha1.h>
+#include <tpm-common.h>
+#include <tpm-v1.h>
+#include "tpm-utils.h"
+
+#ifdef CONFIG_TPM_AUTH_SESSIONS
+
+#ifndef CONFIG_SHA1
+#error "TPM_AUTH_SESSIONS require SHA1 to be configured, too"
+#endif /* !CONFIG_SHA1 */
+
+struct session_data {
+	int		valid;
+	u32	handle;
+	u8		nonce_even[DIGEST_LENGTH];
+	u8		nonce_odd[DIGEST_LENGTH];
+};
+
+static struct session_data oiap_session = {0, };
+
+#endif /* CONFIG_TPM_AUTH_SESSIONS */
+
+u32 tpm_startup(enum tpm_startup_type mode)
+{
+	const u8 command[12] = {
+		0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x99, 0x0, 0x0,
+	};
+	const size_t mode_offset = 10;
+	u8 buf[COMMAND_BUFFER_SIZE];
+
+	if (pack_byte_string(buf, sizeof(buf), "sw",
+			     0, command, sizeof(command),
+			     mode_offset, mode))
+		return TPM_LIB_ERROR;
+
+	return tpm_sendrecv_command(buf, NULL, NULL);
+}
+
+u32 tpm_self_test_full(void)
+{
+	const u8 command[10] = {
+		0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x50,
+	};
+	return tpm_sendrecv_command(command, NULL, NULL);
+}
+
+u32 tpm_continue_self_test(void)
+{
+	const u8 command[10] = {
+		0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x53,
+	};
+	return tpm_sendrecv_command(command, NULL, NULL);
+}
+
+u32 tpm_nv_define_space(u32 index, u32 perm, u32 size)
+{
+	const u8 command[101] = {
+		0x0, 0xc1,		/* TPM_TAG */
+		0x0, 0x0, 0x0, 0x65,	/* parameter size */
+		0x0, 0x0, 0x0, 0xcc,	/* TPM_COMMAND_CODE */
+		/* TPM_NV_DATA_PUBLIC->... */
+		0x0, 0x18,		/* ...->TPM_STRUCTURE_TAG */
+		0, 0, 0, 0,		/* ...->TPM_NV_INDEX */
+		/* TPM_NV_DATA_PUBLIC->TPM_PCR_INFO_SHORT */
+		0x0, 0x3,
+		0, 0, 0,
+		0x1f,
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+		/* TPM_NV_DATA_PUBLIC->TPM_PCR_INFO_SHORT */
+		0x0, 0x3,
+		0, 0, 0,
+		0x1f,
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+		/* TPM_NV_ATTRIBUTES->... */
+		0x0, 0x17,		/* ...->TPM_STRUCTURE_TAG */
+		0, 0, 0, 0,		/* ...->attributes */
+		/* End of TPM_NV_ATTRIBUTES */
+		0,			/* bReadSTClear */
+		0,			/* bWriteSTClear */
+		0,			/* bWriteDefine */
+		0, 0, 0, 0,		/* size */
+	};
+	const size_t index_offset = 12;
+	const size_t perm_offset = 70;
+	const size_t size_offset = 77;
+	u8 buf[COMMAND_BUFFER_SIZE];
+
+	if (pack_byte_string(buf, sizeof(buf), "sddd",
+			     0, command, sizeof(command),
+			     index_offset, index,
+			     perm_offset, perm,
+			     size_offset, size))
+		return TPM_LIB_ERROR;
+
+	return tpm_sendrecv_command(buf, NULL, NULL);
+}
+
+u32 tpm_nv_read_value(u32 index, void *data, u32 count)
+{
+	const u8 command[22] = {
+		0x0, 0xc1, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0xcf,
+	};
+	const size_t index_offset = 10;
+	const size_t length_offset = 18;
+	const size_t data_size_offset = 10;
+	const size_t data_offset = 14;
+	u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
+	size_t response_length = sizeof(response);
+	u32 data_size;
+	u32 err;
+
+	if (pack_byte_string(buf, sizeof(buf), "sdd",
+			     0, command, sizeof(command),
+			     index_offset, index,
+			     length_offset, count))
+		return TPM_LIB_ERROR;
+	err = tpm_sendrecv_command(buf, response, &response_length);
+	if (err)
+		return err;
+	if (unpack_byte_string(response, response_length, "d",
+			       data_size_offset, &data_size))
+		return TPM_LIB_ERROR;
+	if (data_size > count)
+		return TPM_LIB_ERROR;
+	if (unpack_byte_string(response, response_length, "s",
+			       data_offset, data, data_size))
+		return TPM_LIB_ERROR;
+
+	return 0;
+}
+
+u32 tpm_nv_write_value(u32 index, const void *data, u32 length)
+{
+	const u8 command[256] = {
+		0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcd,
+	};
+	const size_t command_size_offset = 2;
+	const size_t index_offset = 10;
+	const size_t length_offset = 18;
+	const size_t data_offset = 22;
+	const size_t write_info_size = 12;
+	const u32 total_length =
+		TPM_REQUEST_HEADER_LENGTH + write_info_size + length;
+	u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
+	size_t response_length = sizeof(response);
+	u32 err;
+
+	if (pack_byte_string(buf, sizeof(buf), "sddds",
+			     0, command, sizeof(command),
+			     command_size_offset, total_length,
+			     index_offset, index,
+			     length_offset, length,
+			     data_offset, data, length))
+		return TPM_LIB_ERROR;
+	err = tpm_sendrecv_command(buf, response, &response_length);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+u32 tpm_extend(u32 index, const void *in_digest, void *out_digest)
+{
+	const u8 command[34] = {
+		0x0, 0xc1, 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x14,
+	};
+	const size_t index_offset = 10;
+	const size_t in_digest_offset = 14;
+	const size_t out_digest_offset = 10;
+	u8 buf[COMMAND_BUFFER_SIZE];
+	u8 response[TPM_RESPONSE_HEADER_LENGTH + PCR_DIGEST_LENGTH];
+	size_t response_length = sizeof(response);
+	u32 err;
+
+	if (pack_byte_string(buf, sizeof(buf), "sds",
+			     0, command, sizeof(command),
+			     index_offset, index,
+			     in_digest_offset, in_digest,
+			     PCR_DIGEST_LENGTH))
+		return TPM_LIB_ERROR;
+	err = tpm_sendrecv_command(buf, response, &response_length);
+	if (err)
+		return err;
+
+	if (unpack_byte_string(response, response_length, "s",
+			       out_digest_offset, out_digest,
+			       PCR_DIGEST_LENGTH))
+		return TPM_LIB_ERROR;
+
+	return 0;
+}
+
+u32 tpm_pcr_read(u32 index, void *data, size_t count)
+{
+	const u8 command[14] = {
+		0x0, 0xc1, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x15,
+	};
+	const size_t index_offset = 10;
+	const size_t out_digest_offset = 10;
+	u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
+	size_t response_length = sizeof(response);
+	u32 err;
+
+	if (count < PCR_DIGEST_LENGTH)
+		return TPM_LIB_ERROR;
+
+	if (pack_byte_string(buf, sizeof(buf), "sd",
+			     0, command, sizeof(command),
+			     index_offset, index))
+		return TPM_LIB_ERROR;
+	err = tpm_sendrecv_command(buf, response, &response_length);
+	if (err)
+		return err;
+	if (unpack_byte_string(response, response_length, "s",
+			       out_digest_offset, data, PCR_DIGEST_LENGTH))
+		return TPM_LIB_ERROR;
+
+	return 0;
+}
+
+u32 tpm_tsc_physical_presence(u16 presence)
+{
+	const u8 command[12] = {
+		0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x0, 0x0,
+	};
+	const size_t presence_offset = 10;
+	u8 buf[COMMAND_BUFFER_SIZE];
+
+	if (pack_byte_string(buf, sizeof(buf), "sw",
+			     0, command, sizeof(command),
+			     presence_offset, presence))
+		return TPM_LIB_ERROR;
+
+	return tpm_sendrecv_command(buf, NULL, NULL);
+}
+
+u32 tpm_read_pubek(void *data, size_t count)
+{
+	const u8 command[30] = {
+		0x0, 0xc1, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x7c,
+	};
+	const size_t response_size_offset = 2;
+	const size_t data_offset = 10;
+	const size_t header_and_checksum_size = TPM_RESPONSE_HEADER_LENGTH + 20;
+	u8 response[COMMAND_BUFFER_SIZE + TPM_PUBEK_SIZE];
+	size_t response_length = sizeof(response);
+	u32 data_size;
+	u32 err;
+
+	err = tpm_sendrecv_command(command, response, &response_length);
+	if (err)
+		return err;
+	if (unpack_byte_string(response, response_length, "d",
+			       response_size_offset, &data_size))
+		return TPM_LIB_ERROR;
+	if (data_size < header_and_checksum_size)
+		return TPM_LIB_ERROR;
+	data_size -= header_and_checksum_size;
+	if (data_size > count)
+		return TPM_LIB_ERROR;
+	if (unpack_byte_string(response, response_length, "s",
+			       data_offset, data, data_size))
+		return TPM_LIB_ERROR;
+
+	return 0;
+}
+
+u32 tpm_force_clear(void)
+{
+	const u8 command[10] = {
+		0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x5d,
+	};
+
+	return tpm_sendrecv_command(command, NULL, NULL);
+}
+
+u32 tpm_physical_enable(void)
+{
+	const u8 command[10] = {
+		0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x6f,
+	};
+
+	return tpm_sendrecv_command(command, NULL, NULL);
+}
+
+u32 tpm_physical_disable(void)
+{
+	const u8 command[10] = {
+		0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x70,
+	};
+
+	return tpm_sendrecv_command(command, NULL, NULL);
+}
+
+u32 tpm_physical_set_deactivated(u8 state)
+{
+	const u8 command[11] = {
+		0x0, 0xc1, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x72,
+	};
+	const size_t state_offset = 10;
+	u8 buf[COMMAND_BUFFER_SIZE];
+
+	if (pack_byte_string(buf, sizeof(buf), "sb",
+			     0, command, sizeof(command),
+			     state_offset, state))
+		return TPM_LIB_ERROR;
+
+	return tpm_sendrecv_command(buf, NULL, NULL);
+}
+
+u32 tpm_get_capability(u32 cap_area, u32 sub_cap, void *cap, size_t count)
+{
+	const u8 command[22] = {
+		0x0, 0xc1,		/* TPM_TAG */
+		0x0, 0x0, 0x0, 0x16,	/* parameter size */
+		0x0, 0x0, 0x0, 0x65,	/* TPM_COMMAND_CODE */
+		0x0, 0x0, 0x0, 0x0,	/* TPM_CAPABILITY_AREA */
+		0x0, 0x0, 0x0, 0x4,	/* subcap size */
+		0x0, 0x0, 0x0, 0x0,	/* subcap value */
+	};
+	const size_t cap_area_offset = 10;
+	const size_t sub_cap_offset = 18;
+	const size_t cap_offset = 14;
+	const size_t cap_size_offset = 10;
+	u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
+	size_t response_length = sizeof(response);
+	u32 cap_size;
+	u32 err;
+
+	if (pack_byte_string(buf, sizeof(buf), "sdd",
+			     0, command, sizeof(command),
+			     cap_area_offset, cap_area,
+			     sub_cap_offset, sub_cap))
+		return TPM_LIB_ERROR;
+	err = tpm_sendrecv_command(buf, response, &response_length);
+	if (err)
+		return err;
+	if (unpack_byte_string(response, response_length, "d",
+			       cap_size_offset, &cap_size))
+		return TPM_LIB_ERROR;
+	if (cap_size > response_length || cap_size > count)
+		return TPM_LIB_ERROR;
+	if (unpack_byte_string(response, response_length, "s",
+			       cap_offset, cap, cap_size))
+		return TPM_LIB_ERROR;
+
+	return 0;
+}
+
+u32 tpm_get_permanent_flags(struct tpm_permanent_flags *pflags)
+{
+	const u8 command[22] = {
+		0x0, 0xc1,		/* TPM_TAG */
+		0x0, 0x0, 0x0, 0x16,	/* parameter size */
+		0x0, 0x0, 0x0, 0x65,	/* TPM_COMMAND_CODE */
+		0x0, 0x0, 0x0, 0x4,	/* TPM_CAP_FLAG_PERM */
+		0x0, 0x0, 0x0, 0x4,	/* subcap size */
+		0x0, 0x0, 0x1, 0x8,	/* subcap value */
+	};
+	const size_t data_size_offset = TPM_HEADER_SIZE;
+	const size_t data_offset = TPM_HEADER_SIZE + sizeof(u32);
+	u8 response[COMMAND_BUFFER_SIZE];
+	size_t response_length = sizeof(response);
+	u32 err;
+	u32 data_size;
+
+	err = tpm_sendrecv_command(command, response, &response_length);
+	if (err)
+		return err;
+	if (unpack_byte_string(response, response_length, "d",
+			       data_size_offset, &data_size))
+		return TPM_LIB_ERROR;
+	if (data_size < sizeof(*pflags))
+		return TPM_LIB_ERROR;
+	if (unpack_byte_string(response, response_length, "s",
+			       data_offset, pflags, sizeof(*pflags)))
+		return TPM_LIB_ERROR;
+
+	return 0;
+}
+
+u32 tpm_get_permissions(u32 index, u32 *perm)
+{
+	const u8 command[22] = {
+		0x0, 0xc1,		/* TPM_TAG */
+		0x0, 0x0, 0x0, 0x16,	/* parameter size */
+		0x0, 0x0, 0x0, 0x65,	/* TPM_COMMAND_CODE */
+		0x0, 0x0, 0x0, 0x11,
+		0x0, 0x0, 0x0, 0x4,
+	};
+	const size_t index_offset = 18;
+	const size_t perm_offset = 60;
+	u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
+	size_t response_length = sizeof(response);
+	u32 err;
+
+	if (pack_byte_string(buf, sizeof(buf), "d", 0, command, sizeof(command),
+			     index_offset, index))
+		return TPM_LIB_ERROR;
+	err = tpm_sendrecv_command(buf, response, &response_length);
+	if (err)
+		return err;
+	if (unpack_byte_string(response, response_length, "d",
+			       perm_offset, perm))
+		return TPM_LIB_ERROR;
+
+	return 0;
+}
+
+#ifdef CONFIG_TPM_FLUSH_RESOURCES
+u32 tpm_flush_specific(u32 key_handle, u32 resource_type)
+{
+	const u8 command[18] = {
+		0x00, 0xc1,             /* TPM_TAG */
+		0x00, 0x00, 0x00, 0x12, /* parameter size */
+		0x00, 0x00, 0x00, 0xba, /* TPM_COMMAND_CODE */
+		0x00, 0x00, 0x00, 0x00, /* key handle */
+		0x00, 0x00, 0x00, 0x00, /* resource type */
+	};
+	const size_t key_handle_offset = 10;
+	const size_t resource_type_offset = 14;
+	u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
+	size_t response_length = sizeof(response);
+	u32 err;
+
+	if (pack_byte_string(buf, sizeof(buf), "sdd",
+			     0, command, sizeof(command),
+			     key_handle_offset, key_handle,
+			     resource_type_offset, resource_type))
+		return TPM_LIB_ERROR;
+
+	err = tpm_sendrecv_command(buf, response, &response_length);
+	if (err)
+		return err;
+	return 0;
+}
+#endif /* CONFIG_TPM_FLUSH_RESOURCES */
+
+#ifdef CONFIG_TPM_AUTH_SESSIONS
+
+/**
+ * Fill an authentication block in a request.
+ * This func can create the first as well as the second auth block (for
+ * double authorized commands).
+ *
+ * @param request	pointer to the request (w/ uninitialised auth data)
+ * @param request_len0	length of the request without auth data
+ * @param handles_len	length of the handles area in request
+ * @param auth_session	pointer to the (valid) auth session to be used
+ * @param request_auth	pointer to the auth block of the request to be filled
+ * @param auth		authentication data (HMAC key)
+ */
+static u32 create_request_auth(const void *request, size_t request_len0,
+			       size_t handles_len,
+			       struct session_data *auth_session,
+			       void *request_auth, const void *auth)
+{
+	u8 hmac_data[DIGEST_LENGTH * 3 + 1];
+	sha1_context hash_ctx;
+	const size_t command_code_offset = 6;
+	const size_t auth_nonce_odd_offset = 4;
+	const size_t auth_continue_offset = 24;
+	const size_t auth_auth_offset = 25;
+
+	if (!auth_session || !auth_session->valid)
+		return TPM_LIB_ERROR;
+
+	sha1_starts(&hash_ctx);
+	sha1_update(&hash_ctx, request + command_code_offset, 4);
+	if (request_len0 > TPM_REQUEST_HEADER_LENGTH + handles_len)
+		sha1_update(&hash_ctx,
+			    request + TPM_REQUEST_HEADER_LENGTH + handles_len,
+			    request_len0 - TPM_REQUEST_HEADER_LENGTH
+			    - handles_len);
+	sha1_finish(&hash_ctx, hmac_data);
+
+	sha1_starts(&hash_ctx);
+	sha1_update(&hash_ctx, auth_session->nonce_odd, DIGEST_LENGTH);
+	sha1_update(&hash_ctx, hmac_data, sizeof(hmac_data));
+	sha1_finish(&hash_ctx, auth_session->nonce_odd);
+
+	if (pack_byte_string(request_auth, TPM_REQUEST_AUTH_LENGTH, "dsb",
+			     0, auth_session->handle,
+			     auth_nonce_odd_offset, auth_session->nonce_odd,
+			     DIGEST_LENGTH,
+			     auth_continue_offset, 1))
+		return TPM_LIB_ERROR;
+	if (pack_byte_string(hmac_data, sizeof(hmac_data), "ss",
+			     DIGEST_LENGTH,
+			     auth_session->nonce_even,
+			     DIGEST_LENGTH,
+			     2 * DIGEST_LENGTH,
+			     request_auth + auth_nonce_odd_offset,
+			     DIGEST_LENGTH + 1))
+		return TPM_LIB_ERROR;
+	sha1_hmac(auth, DIGEST_LENGTH, hmac_data, sizeof(hmac_data),
+		  request_auth + auth_auth_offset);
+
+	return TPM_SUCCESS;
+}
+
+/**
+ * Verify an authentication block in a response.
+ * Since this func updates the nonce_even in the session data it has to be
+ * called when receiving a succesfull AUTH response.
+ * This func can verify the first as well as the second auth block (for
+ * double authorized commands).
+ *
+ * @param command_code	command code of the request
+ * @param response	pointer to the request (w/ uninitialised auth data)
+ * @param handles_len	length of the handles area in response
+ * @param auth_session	pointer to the (valid) auth session to be used
+ * @param response_auth	pointer to the auth block of the response to be verified
+ * @param auth		authentication data (HMAC key)
+ */
+static u32 verify_response_auth(u32 command_code, const void *response,
+				size_t response_len0, size_t handles_len,
+				struct session_data *auth_session,
+				const void *response_auth, const void *auth)
+{
+	u8 hmac_data[DIGEST_LENGTH * 3 + 1];
+	u8 computed_auth[DIGEST_LENGTH];
+	sha1_context hash_ctx;
+	const size_t return_code_offset = 6;
+	const size_t auth_continue_offset = 20;
+	const size_t auth_auth_offset = 21;
+	u8 auth_continue;
+
+	if (!auth_session || !auth_session->valid)
+		return TPM_AUTHFAIL;
+	if (pack_byte_string(hmac_data, sizeof(hmac_data), "d",
+			     0, command_code))
+		return TPM_LIB_ERROR;
+	if (response_len0 < TPM_RESPONSE_HEADER_LENGTH)
+		return TPM_LIB_ERROR;
+
+	sha1_starts(&hash_ctx);
+	sha1_update(&hash_ctx, response + return_code_offset, 4);
+	sha1_update(&hash_ctx, hmac_data, 4);
+	if (response_len0 > TPM_RESPONSE_HEADER_LENGTH + handles_len)
+		sha1_update(&hash_ctx,
+			    response + TPM_RESPONSE_HEADER_LENGTH + handles_len,
+			    response_len0 - TPM_RESPONSE_HEADER_LENGTH
+			    - handles_len);
+	sha1_finish(&hash_ctx, hmac_data);
+
+	memcpy(auth_session->nonce_even, response_auth, DIGEST_LENGTH);
+	auth_continue = ((u8 *)response_auth)[auth_continue_offset];
+	if (pack_byte_string(hmac_data, sizeof(hmac_data), "ssb",
+			     DIGEST_LENGTH,
+			     response_auth,
+			     DIGEST_LENGTH,
+			     2 * DIGEST_LENGTH,
+			     auth_session->nonce_odd,
+			     DIGEST_LENGTH,
+			     3 * DIGEST_LENGTH,
+			     auth_continue))
+		return TPM_LIB_ERROR;
+
+	sha1_hmac(auth, DIGEST_LENGTH, hmac_data, sizeof(hmac_data),
+		  computed_auth);
+
+	if (memcmp(computed_auth, response_auth + auth_auth_offset,
+		   DIGEST_LENGTH))
+		return TPM_AUTHFAIL;
+
+	return TPM_SUCCESS;
+}
+
+u32 tpm_terminate_auth_session(u32 auth_handle)
+{
+	const u8 command[18] = {
+		0x00, 0xc1,		/* TPM_TAG */
+		0x00, 0x00, 0x00, 0x00,	/* parameter size */
+		0x00, 0x00, 0x00, 0xba,	/* TPM_COMMAND_CODE */
+		0x00, 0x00, 0x00, 0x00,	/* TPM_HANDLE */
+		0x00, 0x00, 0x00, 0x02,	/* TPM_RESOURCE_TYPE */
+	};
+	const size_t req_handle_offset = TPM_REQUEST_HEADER_LENGTH;
+	u8 request[COMMAND_BUFFER_SIZE];
+
+	if (pack_byte_string(request, sizeof(request), "sd",
+			     0, command, sizeof(command),
+			     req_handle_offset, auth_handle))
+		return TPM_LIB_ERROR;
+	if (oiap_session.valid && oiap_session.handle == auth_handle)
+		oiap_session.valid = 0;
+
+	return tpm_sendrecv_command(request, NULL, NULL);
+}
+
+u32 tpm_end_oiap(void)
+{
+	u32 err = TPM_SUCCESS;
+
+	if (oiap_session.valid)
+		err = tpm_terminate_auth_session(oiap_session.handle);
+	return err;
+}
+
+u32 tpm_oiap(u32 *auth_handle)
+{
+	const u8 command[10] = {
+		0x00, 0xc1,		/* TPM_TAG */
+		0x00, 0x00, 0x00, 0x0a,	/* parameter size */
+		0x00, 0x00, 0x00, 0x0a,	/* TPM_COMMAND_CODE */
+	};
+	const size_t res_auth_handle_offset = TPM_RESPONSE_HEADER_LENGTH;
+	const size_t res_nonce_even_offset = TPM_RESPONSE_HEADER_LENGTH + 4;
+	u8 response[COMMAND_BUFFER_SIZE];
+	size_t response_length = sizeof(response);
+	u32 err;
+
+	if (oiap_session.valid)
+		tpm_terminate_auth_session(oiap_session.handle);
+
+	err = tpm_sendrecv_command(command, response, &response_length);
+	if (err)
+		return err;
+	if (unpack_byte_string(response, response_length, "ds",
+			       res_auth_handle_offset, &oiap_session.handle,
+			       res_nonce_even_offset, &oiap_session.nonce_even,
+			       (u32)DIGEST_LENGTH))
+		return TPM_LIB_ERROR;
+	oiap_session.valid = 1;
+	if (auth_handle)
+		*auth_handle = oiap_session.handle;
+	return 0;
+}
+
+u32 tpm_load_key2_oiap(u32 parent_handle, const void *key, size_t key_length,
+		       const void *parent_key_usage_auth, u32 *key_handle)
+{
+	const u8 command[14] = {
+		0x00, 0xc2,		/* TPM_TAG */
+		0x00, 0x00, 0x00, 0x00,	/* parameter size */
+		0x00, 0x00, 0x00, 0x41,	/* TPM_COMMAND_CODE */
+		0x00, 0x00, 0x00, 0x00,	/* parent handle */
+	};
+	const size_t req_size_offset = 2;
+	const size_t req_parent_handle_offset = TPM_REQUEST_HEADER_LENGTH;
+	const size_t req_key_offset = TPM_REQUEST_HEADER_LENGTH + 4;
+	const size_t res_handle_offset = TPM_RESPONSE_HEADER_LENGTH;
+	u8 request[sizeof(command) + TPM_KEY12_MAX_LENGTH +
+		   TPM_REQUEST_AUTH_LENGTH];
+	u8 response[COMMAND_BUFFER_SIZE];
+	size_t response_length = sizeof(response);
+	u32 err;
+
+	if (!oiap_session.valid) {
+		err = tpm_oiap(NULL);
+		if (err)
+			return err;
+	}
+	if (pack_byte_string(request, sizeof(request), "sdds",
+			     0, command, sizeof(command),
+			     req_size_offset,
+			     sizeof(command) + key_length
+			     + TPM_REQUEST_AUTH_LENGTH,
+			     req_parent_handle_offset, parent_handle,
+			     req_key_offset, key, key_length
+		))
+		return TPM_LIB_ERROR;
+
+	err = create_request_auth(request, sizeof(command) + key_length, 4,
+				  &oiap_session,
+				  request + sizeof(command) + key_length,
+				  parent_key_usage_auth);
+	if (err)
+		return err;
+	err = tpm_sendrecv_command(request, response, &response_length);
+	if (err) {
+		if (err == TPM_AUTHFAIL)
+			oiap_session.valid = 0;
+		return err;
+	}
+
+	err = verify_response_auth(0x00000041, response,
+				   response_length - TPM_RESPONSE_AUTH_LENGTH,
+				   4, &oiap_session,
+				   response + response_length -
+				   TPM_RESPONSE_AUTH_LENGTH,
+				   parent_key_usage_auth);
+	if (err)
+		return err;
+
+	if (key_handle) {
+		if (unpack_byte_string(response, response_length, "d",
+				       res_handle_offset, key_handle))
+			return TPM_LIB_ERROR;
+	}
+
+	return 0;
+}
+
+u32 tpm_get_pub_key_oiap(u32 key_handle, const void *usage_auth, void *pubkey,
+			 size_t *pubkey_len)
+{
+	const u8 command[14] = {
+		0x00, 0xc2,		/* TPM_TAG */
+		0x00, 0x00, 0x00, 0x00,	/* parameter size */
+		0x00, 0x00, 0x00, 0x21,	/* TPM_COMMAND_CODE */
+		0x00, 0x00, 0x00, 0x00,	/* key handle */
+	};
+	const size_t req_size_offset = 2;
+	const size_t req_key_handle_offset = TPM_REQUEST_HEADER_LENGTH;
+	const size_t res_pubkey_offset = TPM_RESPONSE_HEADER_LENGTH;
+	u8 request[sizeof(command) + TPM_REQUEST_AUTH_LENGTH];
+	u8 response[TPM_RESPONSE_HEADER_LENGTH + TPM_PUBKEY_MAX_LENGTH +
+		    TPM_RESPONSE_AUTH_LENGTH];
+	size_t response_length = sizeof(response);
+	u32 err;
+
+	if (!oiap_session.valid) {
+		err = tpm_oiap(NULL);
+		if (err)
+			return err;
+	}
+	if (pack_byte_string(request, sizeof(request), "sdd",
+			     0, command, sizeof(command),
+			     req_size_offset,
+			     (u32)(sizeof(command)
+			     + TPM_REQUEST_AUTH_LENGTH),
+			     req_key_handle_offset, key_handle
+		))
+		return TPM_LIB_ERROR;
+	err = create_request_auth(request, sizeof(command), 4, &oiap_session,
+				  request + sizeof(command), usage_auth);
+	if (err)
+		return err;
+	err = tpm_sendrecv_command(request, response, &response_length);
+	if (err) {
+		if (err == TPM_AUTHFAIL)
+			oiap_session.valid = 0;
+		return err;
+	}
+	err = verify_response_auth(0x00000021, response,
+				   response_length - TPM_RESPONSE_AUTH_LENGTH,
+				   0, &oiap_session,
+				   response + response_length -
+				   TPM_RESPONSE_AUTH_LENGTH,
+				   usage_auth);
+	if (err)
+		return err;
+
+	if (pubkey) {
+		if ((response_length - TPM_RESPONSE_HEADER_LENGTH
+		     - TPM_RESPONSE_AUTH_LENGTH) > *pubkey_len)
+			return TPM_LIB_ERROR;
+		*pubkey_len = response_length - TPM_RESPONSE_HEADER_LENGTH
+			- TPM_RESPONSE_AUTH_LENGTH;
+		memcpy(pubkey, response + res_pubkey_offset,
+		       response_length - TPM_RESPONSE_HEADER_LENGTH
+		       - TPM_RESPONSE_AUTH_LENGTH);
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_TPM_LOAD_KEY_BY_SHA1
+u32 tpm_find_key_sha1(const u8 auth[20], const u8 pubkey_digest[20],
+		      u32 *handle)
+{
+	u16 key_count;
+	u32 key_handles[10];
+	u8 buf[288];
+	u8 *ptr;
+	u32 err;
+	u8 digest[20];
+	size_t buf_len;
+	unsigned int i;
+
+	/* fetch list of already loaded keys in the TPM */
+	err = tpm_get_capability(TPM_CAP_HANDLE, TPM_RT_KEY, buf, sizeof(buf));
+	if (err)
+		return -1;
+	key_count = get_unaligned_be16(buf);
+	ptr = buf + 2;
+	for (i = 0; i < key_count; ++i, ptr += 4)
+		key_handles[i] = get_unaligned_be32(ptr);
+
+	/* now search a(/ the) key which we can access with the given auth */
+	for (i = 0; i < key_count; ++i) {
+		buf_len = sizeof(buf);
+		err = tpm_get_pub_key_oiap(key_handles[i], auth, buf, &buf_len);
+		if (err && err != TPM_AUTHFAIL)
+			return -1;
+		if (err)
+			continue;
+		sha1_csum(buf, buf_len, digest);
+		if (!memcmp(digest, pubkey_digest, 20)) {
+			*handle = key_handles[i];
+			return 0;
+		}
+	}
+	return 1;
+}
+#endif /* CONFIG_TPM_LOAD_KEY_BY_SHA1 */
+
+#endif /* CONFIG_TPM_AUTH_SESSIONS */
+
+u32 tpm_get_random(void *data, u32 count)
+{
+	const u8 command[14] = {
+		0x0, 0xc1,		/* TPM_TAG */
+		0x0, 0x0, 0x0, 0xe,	/* parameter size */
+		0x0, 0x0, 0x0, 0x46,	/* TPM_COMMAND_CODE */
+	};
+	const size_t length_offset = 10;
+	const size_t data_size_offset = 10;
+	const size_t data_offset = 14;
+	u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
+	size_t response_length = sizeof(response);
+	u32 data_size;
+	u8 *out = data;
+
+	while (count > 0) {
+		u32 this_bytes = min((size_t)count,
+				     sizeof(response) - data_offset);
+		u32 err;
+
+		if (pack_byte_string(buf, sizeof(buf), "sd",
+				     0, command, sizeof(command),
+				     length_offset, this_bytes))
+			return TPM_LIB_ERROR;
+		err = tpm_sendrecv_command(buf, response, &response_length);
+		if (err)
+			return err;
+		if (unpack_byte_string(response, response_length, "d",
+				       data_size_offset, &data_size))
+			return TPM_LIB_ERROR;
+		if (data_size > count)
+			return TPM_LIB_ERROR;
+		if (unpack_byte_string(response, response_length, "s",
+				       data_offset, out, data_size))
+			return TPM_LIB_ERROR;
+
+		count -= data_size;
+		out += data_size;
+	}
+
+	return 0;
+}
diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c
new file mode 100644
index 0000000..f1bbca8
--- /dev/null
+++ b/lib/tpm-v2.c
@@ -0,0 +1,419 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2018 Bootlin
+ * Author: Miquel Raynal <miquel.raynal@bootlin.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <tpm-common.h>
+#include <tpm-v2.h>
+#include "tpm-utils.h"
+
+u32 tpm2_startup(enum tpm2_startup_types mode)
+{
+	const u8 command_v2[12] = {
+		tpm_u16(TPM2_ST_NO_SESSIONS),
+		tpm_u32(12),
+		tpm_u32(TPM2_CC_STARTUP),
+		tpm_u16(mode),
+	};
+	int ret;
+
+	/*
+	 * Note TPM2_Startup command will return RC_SUCCESS the first time,
+	 * but will return RC_INITIALIZE otherwise.
+	 */
+	ret = tpm_sendrecv_command(command_v2, NULL, NULL);
+	if (ret && ret != TPM2_RC_INITIALIZE)
+		return ret;
+
+	return 0;
+}
+
+u32 tpm2_self_test(enum tpm2_yes_no full_test)
+{
+	const u8 command_v2[12] = {
+		tpm_u16(TPM2_ST_NO_SESSIONS),
+		tpm_u32(11),
+		tpm_u32(TPM2_CC_SELF_TEST),
+		full_test,
+	};
+
+	return tpm_sendrecv_command(command_v2, NULL, NULL);
+}
+
+u32 tpm2_clear(u32 handle, const char *pw, const ssize_t pw_sz)
+{
+	u8 command_v2[COMMAND_BUFFER_SIZE] = {
+		tpm_u16(TPM2_ST_SESSIONS),	/* TAG */
+		tpm_u32(27 + pw_sz),		/* Length */
+		tpm_u32(TPM2_CC_CLEAR),		/* Command code */
+
+		/* HANDLE */
+		tpm_u32(handle),		/* TPM resource handle */
+
+		/* AUTH_SESSION */
+		tpm_u32(9 + pw_sz),		/* Authorization size */
+		tpm_u32(TPM2_RS_PW),		/* Session handle */
+		tpm_u16(0),			/* Size of <nonce> */
+						/* <nonce> (if any) */
+		0,				/* Attributes: Cont/Excl/Rst */
+		tpm_u16(pw_sz),			/* Size of <hmac/password> */
+		/* STRING(pw)			   <hmac/password> (if any) */
+	};
+	unsigned int offset = 27;
+	int ret;
+
+	/*
+	 * Fill the command structure starting from the first buffer:
+	 *     - the password (if any)
+	 */
+	ret = pack_byte_string(command_v2, sizeof(command_v2), "s",
+			       offset, pw, pw_sz);
+	offset += pw_sz;
+	if (ret)
+		return TPM_LIB_ERROR;
+
+	return tpm_sendrecv_command(command_v2, NULL, NULL);
+}
+
+u32 tpm2_pcr_extend(u32 index, const uint8_t *digest)
+{
+	u8 command_v2[COMMAND_BUFFER_SIZE] = {
+		tpm_u16(TPM2_ST_SESSIONS),	/* TAG */
+		tpm_u32(33 + TPM2_DIGEST_LEN),	/* Length */
+		tpm_u32(TPM2_CC_PCR_EXTEND),	/* Command code */
+
+		/* HANDLE */
+		tpm_u32(index),			/* Handle (PCR Index) */
+
+		/* AUTH_SESSION */
+		tpm_u32(9),			/* Authorization size */
+		tpm_u32(TPM2_RS_PW),		/* Session handle */
+		tpm_u16(0),			/* Size of <nonce> */
+						/* <nonce> (if any) */
+		0,				/* Attributes: Cont/Excl/Rst */
+		tpm_u16(0),			/* Size of <hmac/password> */
+						/* <hmac/password> (if any) */
+		tpm_u32(1),			/* Count (number of hashes) */
+		tpm_u16(TPM2_ALG_SHA256),	/* Algorithm of the hash */
+		/* STRING(digest)		   Digest */
+	};
+	unsigned int offset = 33;
+	int ret;
+
+	/*
+	 * Fill the command structure starting from the first buffer:
+	 *     - the digest
+	 */
+	ret = pack_byte_string(command_v2, sizeof(command_v2), "s",
+			       offset, digest, TPM2_DIGEST_LEN);
+	offset += TPM2_DIGEST_LEN;
+	if (ret)
+		return TPM_LIB_ERROR;
+
+	return tpm_sendrecv_command(command_v2,	NULL, NULL);
+}
+
+u32 tpm2_pcr_read(u32 idx, unsigned int idx_min_sz, void *data,
+		  unsigned int *updates)
+{
+	u8 idx_array_sz = max(idx_min_sz, DIV_ROUND_UP(idx, 8));
+	u8 command_v2[COMMAND_BUFFER_SIZE] = {
+		tpm_u16(TPM2_ST_NO_SESSIONS),	/* TAG */
+		tpm_u32(17 + idx_array_sz),	/* Length */
+		tpm_u32(TPM2_CC_PCR_READ),	/* Command code */
+
+		/* TPML_PCR_SELECTION */
+		tpm_u32(1),			/* Number of selections */
+		tpm_u16(TPM2_ALG_SHA256),	/* Algorithm of the hash */
+		idx_array_sz,			/* Array size for selection */
+		/* bitmap(idx)			   Selected PCR bitmap */
+	};
+	size_t response_len = COMMAND_BUFFER_SIZE;
+	u8 response[COMMAND_BUFFER_SIZE];
+	unsigned int pcr_sel_idx = idx / 8;
+	u8 pcr_sel_bit = BIT(idx % 8);
+	unsigned int counter = 0;
+	int ret;
+
+	if (pack_byte_string(command_v2, COMMAND_BUFFER_SIZE, "b",
+			     17 + pcr_sel_idx, pcr_sel_bit))
+		return TPM_LIB_ERROR;
+
+	ret = tpm_sendrecv_command(command_v2, response, &response_len);
+	if (ret)
+		return ret;
+
+	if (unpack_byte_string(response, response_len, "ds",
+			       10, &counter,
+			       response_len - TPM2_DIGEST_LEN, data,
+			       TPM2_DIGEST_LEN))
+		return TPM_LIB_ERROR;
+
+	if (updates)
+		*updates = counter;
+
+	return 0;
+}
+
+u32 tpm2_get_capability(u32 capability, u32 property, void *buf,
+			size_t prop_count)
+{
+	u8 command_v2[COMMAND_BUFFER_SIZE] = {
+		tpm_u16(TPM2_ST_NO_SESSIONS),		/* TAG */
+		tpm_u32(22),				/* Length */
+		tpm_u32(TPM2_CC_GET_CAPABILITY),	/* Command code */
+
+		tpm_u32(capability),			/* Capability */
+		tpm_u32(property),			/* Property */
+		tpm_u32(prop_count),			/* Property count */
+	};
+	u8 response[COMMAND_BUFFER_SIZE];
+	size_t response_len = COMMAND_BUFFER_SIZE;
+	unsigned int properties_off;
+	int ret;
+
+	ret = tpm_sendrecv_command(command_v2, response, &response_len);
+	if (ret)
+		return ret;
+
+	/*
+	 * In the response buffer, the properties are located after the:
+	 * tag (u16), response size (u32), response code (u32),
+	 * YES/NO flag (u8), TPM_CAP (u32) and TPMU_CAPABILITIES (u32).
+	 */
+	properties_off = sizeof(u16) + sizeof(u32) + sizeof(u32) +
+			 sizeof(u8) + sizeof(u32) + sizeof(u32);
+	memcpy(buf, &response[properties_off], response_len - properties_off);
+
+	return 0;
+}
+
+u32 tpm2_dam_reset(const char *pw, const ssize_t pw_sz)
+{
+	u8 command_v2[COMMAND_BUFFER_SIZE] = {
+		tpm_u16(TPM2_ST_SESSIONS),	/* TAG */
+		tpm_u32(27 + pw_sz),		/* Length */
+		tpm_u32(TPM2_CC_DAM_RESET),	/* Command code */
+
+		/* HANDLE */
+		tpm_u32(TPM2_RH_LOCKOUT),	/* TPM resource handle */
+
+		/* AUTH_SESSION */
+		tpm_u32(9 + pw_sz),		/* Authorization size */
+		tpm_u32(TPM2_RS_PW),		/* Session handle */
+		tpm_u16(0),			/* Size of <nonce> */
+						/* <nonce> (if any) */
+		0,				/* Attributes: Cont/Excl/Rst */
+		tpm_u16(pw_sz),			/* Size of <hmac/password> */
+		/* STRING(pw)			   <hmac/password> (if any) */
+	};
+	unsigned int offset = 27;
+	int ret;
+
+	/*
+	 * Fill the command structure starting from the first buffer:
+	 *     - the password (if any)
+	 */
+	ret = pack_byte_string(command_v2, sizeof(command_v2), "s",
+			       offset, pw, pw_sz);
+	offset += pw_sz;
+	if (ret)
+		return TPM_LIB_ERROR;
+
+	return tpm_sendrecv_command(command_v2, NULL, NULL);
+}
+
+u32 tpm2_dam_parameters(const char *pw, const ssize_t pw_sz,
+			unsigned int max_tries, unsigned int recovery_time,
+			unsigned int lockout_recovery)
+{
+	u8 command_v2[COMMAND_BUFFER_SIZE] = {
+		tpm_u16(TPM2_ST_SESSIONS),	/* TAG */
+		tpm_u32(27 + pw_sz + 12),	/* Length */
+		tpm_u32(TPM2_CC_DAM_PARAMETERS), /* Command code */
+
+		/* HANDLE */
+		tpm_u32(TPM2_RH_LOCKOUT),	/* TPM resource handle */
+
+		/* AUTH_SESSION */
+		tpm_u32(9 + pw_sz),		/* Authorization size */
+		tpm_u32(TPM2_RS_PW),		/* Session handle */
+		tpm_u16(0),			/* Size of <nonce> */
+						/* <nonce> (if any) */
+		0,				/* Attributes: Cont/Excl/Rst */
+		tpm_u16(pw_sz),			/* Size of <hmac/password> */
+		/* STRING(pw)			   <hmac/password> (if any) */
+
+		/* LOCKOUT PARAMETERS */
+		/* tpm_u32(max_tries)		   Max tries (0, always lock) */
+		/* tpm_u32(recovery_time)	   Recovery time (0, no lock) */
+		/* tpm_u32(lockout_recovery)	   Lockout recovery */
+	};
+	unsigned int offset = 27;
+	int ret;
+
+	/*
+	 * Fill the command structure starting from the first buffer:
+	 *     - the password (if any)
+	 *     - max tries
+	 *     - recovery time
+	 *     - lockout recovery
+	 */
+	ret = pack_byte_string(command_v2, sizeof(command_v2), "sddd",
+			       offset, pw, pw_sz,
+			       offset + pw_sz, max_tries,
+			       offset + pw_sz + 4, recovery_time,
+			       offset + pw_sz + 8, lockout_recovery);
+	offset += pw_sz + 12;
+	if (ret)
+		return TPM_LIB_ERROR;
+
+	return tpm_sendrecv_command(command_v2, NULL, NULL);
+}
+
+int tpm2_change_auth(u32 handle, const char *newpw, const ssize_t newpw_sz,
+		     const char *oldpw, const ssize_t oldpw_sz)
+{
+	unsigned int offset = 27;
+	u8 command_v2[COMMAND_BUFFER_SIZE] = {
+		tpm_u16(TPM2_ST_SESSIONS),	/* TAG */
+		tpm_u32(offset + oldpw_sz + 2 + newpw_sz), /* Length */
+		tpm_u32(TPM2_CC_HIERCHANGEAUTH), /* Command code */
+
+		/* HANDLE */
+		tpm_u32(handle),		/* TPM resource handle */
+
+		/* AUTH_SESSION */
+		tpm_u32(9 + oldpw_sz),		/* Authorization size */
+		tpm_u32(TPM2_RS_PW),		/* Session handle */
+		tpm_u16(0),			/* Size of <nonce> */
+						/* <nonce> (if any) */
+		0,				/* Attributes: Cont/Excl/Rst */
+		tpm_u16(oldpw_sz)		/* Size of <hmac/password> */
+		/* STRING(oldpw)		   <hmac/password> (if any) */
+
+		/* TPM2B_AUTH (TPM2B_DIGEST) */
+		/* tpm_u16(newpw_sz)		   Digest size, new pw length */
+		/* STRING(newpw)		   Digest buffer, new pw */
+	};
+	int ret;
+
+	/*
+	 * Fill the command structure starting from the first buffer:
+	 *     - the old password (if any)
+	 *     - size of the new password
+	 *     - new password
+	 */
+	ret = pack_byte_string(command_v2, sizeof(command_v2), "sws",
+			       offset, oldpw, oldpw_sz,
+			       offset + oldpw_sz, newpw_sz,
+			       offset + oldpw_sz + 2, newpw, newpw_sz);
+	offset += oldpw_sz + 2 + newpw_sz;
+	if (ret)
+		return TPM_LIB_ERROR;
+
+	return tpm_sendrecv_command(command_v2, NULL, NULL);
+}
+
+u32 tpm2_pcr_setauthpolicy(const char *pw, const ssize_t pw_sz, u32 index,
+			   const char *key)
+{
+	u8 command_v2[COMMAND_BUFFER_SIZE] = {
+		tpm_u16(TPM2_ST_SESSIONS),	/* TAG */
+		tpm_u32(35 + pw_sz + TPM2_DIGEST_LEN), /* Length */
+		tpm_u32(TPM2_CC_PCR_SETAUTHPOL), /* Command code */
+
+		/* HANDLE */
+		tpm_u32(TPM2_RH_PLATFORM),	/* TPM resource handle */
+
+		/* AUTH_SESSION */
+		tpm_u32(9 + pw_sz),		/* Authorization size */
+		tpm_u32(TPM2_RS_PW),		/* session handle */
+		tpm_u16(0),			/* Size of <nonce> */
+						/* <nonce> (if any) */
+		0,				/* Attributes: Cont/Excl/Rst */
+		tpm_u16(pw_sz)			/* Size of <hmac/password> */
+		/* STRING(pw)			   <hmac/password> (if any) */
+
+		/* TPM2B_AUTH (TPM2B_DIGEST) */
+		/* tpm_u16(TPM2_DIGEST_LEN)	   Digest size length */
+		/* STRING(key)			   Digest buffer (PCR key) */
+
+		/* TPMI_ALG_HASH */
+		/* tpm_u16(TPM2_ALG_SHA256)   Algorithm of the hash */
+
+		/* TPMI_DH_PCR */
+		/* tpm_u32(index),		   PCR Index */
+	};
+	unsigned int offset = 27;
+	int ret;
+
+	/*
+	 * Fill the command structure starting from the first buffer:
+	 *     - the password (if any)
+	 *     - the PCR key length
+	 *     - the PCR key
+	 *     - the hash algorithm
+	 *     - the PCR index
+	 */
+	ret = pack_byte_string(command_v2, sizeof(command_v2), "swswd",
+			       offset, pw, pw_sz,
+			       offset + pw_sz, TPM2_DIGEST_LEN,
+			       offset + pw_sz + 2, key, TPM2_DIGEST_LEN,
+			       offset + pw_sz + 2 + TPM2_DIGEST_LEN,
+			       TPM2_ALG_SHA256,
+			       offset + pw_sz + 4 + TPM2_DIGEST_LEN, index);
+	offset += pw_sz + 2 + TPM2_DIGEST_LEN + 2 + 4;
+	if (ret)
+		return TPM_LIB_ERROR;
+
+	return tpm_sendrecv_command(command_v2, NULL, NULL);
+}
+
+u32 tpm2_pcr_setauthvalue(const char *pw, const ssize_t pw_sz, u32 index,
+			  const char *key, const ssize_t key_sz)
+{
+	u8 command_v2[COMMAND_BUFFER_SIZE] = {
+		tpm_u16(TPM2_ST_SESSIONS),	/* TAG */
+		tpm_u32(33 + pw_sz + TPM2_DIGEST_LEN), /* Length */
+		tpm_u32(TPM2_CC_PCR_SETAUTHVAL), /* Command code */
+
+		/* HANDLE */
+		tpm_u32(index),			/* Handle (PCR Index) */
+
+		/* AUTH_SESSION */
+		tpm_u32(9 + pw_sz),		/* Authorization size */
+		tpm_u32(TPM2_RS_PW),		/* session handle */
+		tpm_u16(0),			/* Size of <nonce> */
+						/* <nonce> (if any) */
+		0,				/* Attributes: Cont/Excl/Rst */
+		tpm_u16(pw_sz),			/* Size of <hmac/password> */
+		/* STRING(pw)			   <hmac/password> (if any) */
+
+		/* TPM2B_DIGEST */
+		/* tpm_u16(key_sz)		   Key length */
+		/* STRING(key)			   Key */
+	};
+	unsigned int offset = 27;
+	int ret;
+
+	/*
+	 * Fill the command structure starting from the first buffer:
+	 *     - the password (if any)
+	 *     - the number of digests, 1 in our case
+	 *     - the algorithm, sha256 in our case
+	 *     - the digest (64 bytes)
+	 */
+	ret = pack_byte_string(command_v2, sizeof(command_v2), "sws",
+			       offset, pw, pw_sz,
+			       offset + pw_sz, key_sz,
+			       offset + pw_sz + 2, key, key_sz);
+	offset += pw_sz + 2 + key_sz;
+	if (ret)
+		return TPM_LIB_ERROR;
+
+	return tpm_sendrecv_command(command_v2, NULL, NULL);
+}
diff --git a/lib/tpm.c b/lib/tpm.c
deleted file mode 100644
index bc9652d..0000000
--- a/lib/tpm.c
+++ /dev/null
@@ -1,1096 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (c) 2013 The Chromium OS Authors.
- * Coypright (c) 2013 Guntermann & Drunck GmbH
- */
-
-#include <common.h>
-#include <dm.h>
-#include <tpm.h>
-#include <asm/unaligned.h>
-#include <u-boot/sha1.h>
-
-/* Internal error of TPM command library */
-#define TPM_LIB_ERROR	((uint32_t)~0u)
-
-/* Useful constants */
-enum {
-	COMMAND_BUFFER_SIZE		= 256,
-	TPM_REQUEST_HEADER_LENGTH	= 10,
-	TPM_RESPONSE_HEADER_LENGTH	= 10,
-	PCR_DIGEST_LENGTH		= 20,
-	DIGEST_LENGTH			= 20,
-	TPM_REQUEST_AUTH_LENGTH		= 45,
-	TPM_RESPONSE_AUTH_LENGTH	= 41,
-	/* some max lengths, valid for RSA keys <= 2048 bits */
-	TPM_KEY12_MAX_LENGTH		= 618,
-	TPM_PUBKEY_MAX_LENGTH		= 288,
-};
-
-#ifdef CONFIG_TPM_AUTH_SESSIONS
-
-#ifndef CONFIG_SHA1
-#error "TPM_AUTH_SESSIONS require SHA1 to be configured, too"
-#endif /* !CONFIG_SHA1 */
-
-struct session_data {
-	int		valid;
-	uint32_t	handle;
-	uint8_t		nonce_even[DIGEST_LENGTH];
-	uint8_t		nonce_odd[DIGEST_LENGTH];
-};
-
-static struct session_data oiap_session = {0, };
-
-#endif /* CONFIG_TPM_AUTH_SESSIONS */
-
-/**
- * Pack data into a byte string.  The data types are specified in
- * the format string: 'b' means unsigned byte, 'w' unsigned word,
- * 'd' unsigned double word, and 's' byte string.  The data are a
- * series of offsets and values (for type byte string there are also
- * lengths).  The data values are packed into the byte string
- * sequentially, and so a latter value could over-write a former
- * value.
- *
- * @param str		output string
- * @param size		size of output string
- * @param format	format string
- * @param ...		data points
- * @return 0 on success, non-0 on error
- */
-int pack_byte_string(uint8_t *str, size_t size, const char *format, ...)
-{
-	va_list args;
-	size_t offset = 0, length = 0;
-	uint8_t *data = NULL;
-	uint32_t value = 0;
-
-	va_start(args, format);
-	for (; *format; format++) {
-		switch (*format) {
-		case 'b':
-			offset = va_arg(args, size_t);
-			value = va_arg(args, int);
-			length = 1;
-			break;
-		case 'w':
-			offset = va_arg(args, size_t);
-			value = va_arg(args, int);
-			length = 2;
-			break;
-		case 'd':
-			offset = va_arg(args, size_t);
-			value = va_arg(args, uint32_t);
-			length = 4;
-			break;
-		case 's':
-			offset = va_arg(args, size_t);
-			data = va_arg(args, uint8_t *);
-			length = va_arg(args, uint32_t);
-			break;
-		default:
-			debug("Couldn't recognize format string\n");
-			va_end(args);
-			return -1;
-		}
-
-		if (offset + length > size) {
-			va_end(args);
-			return -1;
-		}
-
-		switch (*format) {
-		case 'b':
-			str[offset] = value;
-			break;
-		case 'w':
-			put_unaligned_be16(value, str + offset);
-			break;
-		case 'd':
-			put_unaligned_be32(value, str + offset);
-			break;
-		case 's':
-			memcpy(str + offset, data, length);
-			break;
-		}
-	}
-	va_end(args);
-
-	return 0;
-}
-
-/**
- * Unpack data from a byte string.  The data types are specified in
- * the format string: 'b' means unsigned byte, 'w' unsigned word,
- * 'd' unsigned double word, and 's' byte string.  The data are a
- * series of offsets and pointers (for type byte string there are also
- * lengths).
- *
- * @param str		output string
- * @param size		size of output string
- * @param format	format string
- * @param ...		data points
- * @return 0 on success, non-0 on error
- */
-int unpack_byte_string(const uint8_t *str, size_t size, const char *format, ...)
-{
-	va_list args;
-	size_t offset = 0, length = 0;
-	uint8_t *ptr8 = NULL;
-	uint16_t *ptr16 = NULL;
-	uint32_t *ptr32 = NULL;
-
-	va_start(args, format);
-	for (; *format; format++) {
-		switch (*format) {
-		case 'b':
-			offset = va_arg(args, size_t);
-			ptr8 = va_arg(args, uint8_t *);
-			length = 1;
-			break;
-		case 'w':
-			offset = va_arg(args, size_t);
-			ptr16 = va_arg(args, uint16_t *);
-			length = 2;
-			break;
-		case 'd':
-			offset = va_arg(args, size_t);
-			ptr32 = va_arg(args, uint32_t *);
-			length = 4;
-			break;
-		case 's':
-			offset = va_arg(args, size_t);
-			ptr8 = va_arg(args, uint8_t *);
-			length = va_arg(args, uint32_t);
-			break;
-		default:
-			va_end(args);
-			debug("Couldn't recognize format string\n");
-			return -1;
-		}
-
-		if (offset + length > size) {
-			va_end(args);
-			return -1;
-		}
-
-		switch (*format) {
-		case 'b':
-			*ptr8 = str[offset];
-			break;
-		case 'w':
-			*ptr16 = get_unaligned_be16(str + offset);
-			break;
-		case 'd':
-			*ptr32 = get_unaligned_be32(str + offset);
-			break;
-		case 's':
-			memcpy(ptr8, str + offset, length);
-			break;
-		}
-	}
-	va_end(args);
-
-	return 0;
-}
-
-/**
- * Get TPM command size.
- *
- * @param command	byte string of TPM command
- * @return command size of the TPM command
- */
-static uint32_t tpm_command_size(const void *command)
-{
-	const size_t command_size_offset = 2;
-	return get_unaligned_be32(command + command_size_offset);
-}
-
-/**
- * Get TPM response return code, which is one of TPM_RESULT values.
- *
- * @param response	byte string of TPM response
- * @return return code of the TPM response
- */
-static uint32_t tpm_return_code(const void *response)
-{
-	const size_t return_code_offset = 6;
-	return get_unaligned_be32(response + return_code_offset);
-}
-
-/**
- * Send a TPM command and return response's return code, and optionally
- * return response to caller.
- *
- * @param command	byte string of TPM command
- * @param response	output buffer for TPM response, or NULL if the
- *			caller does not care about it
- * @param size_ptr	output buffer size (input parameter) and TPM
- *			response length (output parameter); this parameter
- *			is a bidirectional
- * @return return code of the TPM response
- */
-static uint32_t tpm_sendrecv_command(const void *command,
-		void *response, size_t *size_ptr)
-{
-	struct udevice *dev;
-	int err, ret;
-	uint8_t response_buffer[COMMAND_BUFFER_SIZE];
-	size_t response_length;
-
-	if (response) {
-		response_length = *size_ptr;
-	} else {
-		response = response_buffer;
-		response_length = sizeof(response_buffer);
-	}
-
-	ret = uclass_first_device_err(UCLASS_TPM, &dev);
-	if (ret)
-		return ret;
-	err = tpm_xfer(dev, command, tpm_command_size(command),
-		       response, &response_length);
-
-	if (err < 0)
-		return TPM_LIB_ERROR;
-	if (size_ptr)
-		*size_ptr = response_length;
-
-	return tpm_return_code(response);
-}
-
-int tpm_init(void)
-{
-	int err;
-	struct udevice *dev;
-
-	err = uclass_first_device_err(UCLASS_TPM, &dev);
-	if (err)
-		return err;
-	return tpm_open(dev);
-}
-
-uint32_t tpm_startup(enum tpm_startup_type mode)
-{
-	const uint8_t command[12] = {
-		0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x99, 0x0, 0x0,
-	};
-	const size_t mode_offset = 10;
-	uint8_t buf[COMMAND_BUFFER_SIZE];
-
-	if (pack_byte_string(buf, sizeof(buf), "sw",
-				0, command, sizeof(command),
-				mode_offset, mode))
-		return TPM_LIB_ERROR;
-
-	return tpm_sendrecv_command(buf, NULL, NULL);
-}
-
-uint32_t tpm_self_test_full(void)
-{
-	const uint8_t command[10] = {
-		0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x50,
-	};
-	return tpm_sendrecv_command(command, NULL, NULL);
-}
-
-uint32_t tpm_continue_self_test(void)
-{
-	const uint8_t command[10] = {
-		0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x53,
-	};
-	return tpm_sendrecv_command(command, NULL, NULL);
-}
-
-uint32_t tpm_nv_define_space(uint32_t index, uint32_t perm, uint32_t size)
-{
-	const uint8_t command[101] = {
-		0x0, 0xc1,		/* TPM_TAG */
-		0x0, 0x0, 0x0, 0x65,	/* parameter size */
-		0x0, 0x0, 0x0, 0xcc,	/* TPM_COMMAND_CODE */
-		/* TPM_NV_DATA_PUBLIC->... */
-		0x0, 0x18,		/* ...->TPM_STRUCTURE_TAG */
-		0, 0, 0, 0,		/* ...->TPM_NV_INDEX */
-		/* TPM_NV_DATA_PUBLIC->TPM_PCR_INFO_SHORT */
-		0x0, 0x3,
-		0, 0, 0,
-		0x1f,
-		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-		/* TPM_NV_DATA_PUBLIC->TPM_PCR_INFO_SHORT */
-		0x0, 0x3,
-		0, 0, 0,
-		0x1f,
-		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-		/* TPM_NV_ATTRIBUTES->... */
-		0x0, 0x17,		/* ...->TPM_STRUCTURE_TAG */
-		0, 0, 0, 0,		/* ...->attributes */
-		/* End of TPM_NV_ATTRIBUTES */
-		0,			/* bReadSTClear */
-		0,			/* bWriteSTClear */
-		0,			/* bWriteDefine */
-		0, 0, 0, 0,		/* size */
-	};
-	const size_t index_offset = 12;
-	const size_t perm_offset = 70;
-	const size_t size_offset = 77;
-	uint8_t buf[COMMAND_BUFFER_SIZE];
-
-	if (pack_byte_string(buf, sizeof(buf), "sddd",
-				0, command, sizeof(command),
-				index_offset, index,
-				perm_offset, perm,
-				size_offset, size))
-		return TPM_LIB_ERROR;
-
-	return tpm_sendrecv_command(buf, NULL, NULL);
-}
-
-uint32_t tpm_nv_read_value(uint32_t index, void *data, uint32_t count)
-{
-	const uint8_t command[22] = {
-		0x0, 0xc1, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0xcf,
-	};
-	const size_t index_offset = 10;
-	const size_t length_offset = 18;
-	const size_t data_size_offset = 10;
-	const size_t data_offset = 14;
-	uint8_t buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
-	size_t response_length = sizeof(response);
-	uint32_t data_size;
-	uint32_t err;
-
-	if (pack_byte_string(buf, sizeof(buf), "sdd",
-				0, command, sizeof(command),
-				index_offset, index,
-				length_offset, count))
-		return TPM_LIB_ERROR;
-	err = tpm_sendrecv_command(buf, response, &response_length);
-	if (err)
-		return err;
-	if (unpack_byte_string(response, response_length, "d",
-				data_size_offset, &data_size))
-		return TPM_LIB_ERROR;
-	if (data_size > count)
-		return TPM_LIB_ERROR;
-	if (unpack_byte_string(response, response_length, "s",
-				data_offset, data, data_size))
-		return TPM_LIB_ERROR;
-
-	return 0;
-}
-
-uint32_t tpm_nv_write_value(uint32_t index, const void *data, uint32_t length)
-{
-	const uint8_t command[256] = {
-		0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcd,
-	};
-	const size_t command_size_offset = 2;
-	const size_t index_offset = 10;
-	const size_t length_offset = 18;
-	const size_t data_offset = 22;
-	const size_t write_info_size = 12;
-	const uint32_t total_length =
-		TPM_REQUEST_HEADER_LENGTH + write_info_size + length;
-	uint8_t buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
-	size_t response_length = sizeof(response);
-	uint32_t err;
-
-	if (pack_byte_string(buf, sizeof(buf), "sddds",
-				0, command, sizeof(command),
-				command_size_offset, total_length,
-				index_offset, index,
-				length_offset, length,
-				data_offset, data, length))
-		return TPM_LIB_ERROR;
-	err = tpm_sendrecv_command(buf, response, &response_length);
-	if (err)
-		return err;
-
-	return 0;
-}
-
-uint32_t tpm_extend(uint32_t index, const void *in_digest, void *out_digest)
-{
-	const uint8_t command[34] = {
-		0x0, 0xc1, 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x14,
-	};
-	const size_t index_offset = 10;
-	const size_t in_digest_offset = 14;
-	const size_t out_digest_offset = 10;
-	uint8_t buf[COMMAND_BUFFER_SIZE];
-	uint8_t response[TPM_RESPONSE_HEADER_LENGTH + PCR_DIGEST_LENGTH];
-	size_t response_length = sizeof(response);
-	uint32_t err;
-
-	if (pack_byte_string(buf, sizeof(buf), "sds",
-				0, command, sizeof(command),
-				index_offset, index,
-				in_digest_offset, in_digest,
-				PCR_DIGEST_LENGTH))
-		return TPM_LIB_ERROR;
-	err = tpm_sendrecv_command(buf, response, &response_length);
-	if (err)
-		return err;
-
-	if (unpack_byte_string(response, response_length, "s",
-				out_digest_offset, out_digest,
-				PCR_DIGEST_LENGTH))
-		return TPM_LIB_ERROR;
-
-	return 0;
-}
-
-uint32_t tpm_pcr_read(uint32_t index, void *data, size_t count)
-{
-	const uint8_t command[14] = {
-		0x0, 0xc1, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x15,
-	};
-	const size_t index_offset = 10;
-	const size_t out_digest_offset = 10;
-	uint8_t buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
-	size_t response_length = sizeof(response);
-	uint32_t err;
-
-	if (count < PCR_DIGEST_LENGTH)
-		return TPM_LIB_ERROR;
-
-	if (pack_byte_string(buf, sizeof(buf), "sd",
-				0, command, sizeof(command),
-				index_offset, index))
-		return TPM_LIB_ERROR;
-	err = tpm_sendrecv_command(buf, response, &response_length);
-	if (err)
-		return err;
-	if (unpack_byte_string(response, response_length, "s",
-				out_digest_offset, data, PCR_DIGEST_LENGTH))
-		return TPM_LIB_ERROR;
-
-	return 0;
-}
-
-uint32_t tpm_tsc_physical_presence(uint16_t presence)
-{
-	const uint8_t command[12] = {
-		0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x0, 0x0,
-	};
-	const size_t presence_offset = 10;
-	uint8_t buf[COMMAND_BUFFER_SIZE];
-
-	if (pack_byte_string(buf, sizeof(buf), "sw",
-				0, command, sizeof(command),
-				presence_offset, presence))
-		return TPM_LIB_ERROR;
-
-	return tpm_sendrecv_command(buf, NULL, NULL);
-}
-
-uint32_t tpm_read_pubek(void *data, size_t count)
-{
-	const uint8_t command[30] = {
-		0x0, 0xc1, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x7c,
-	};
-	const size_t response_size_offset = 2;
-	const size_t data_offset = 10;
-	const size_t header_and_checksum_size = TPM_RESPONSE_HEADER_LENGTH + 20;
-	uint8_t response[COMMAND_BUFFER_SIZE + TPM_PUBEK_SIZE];
-	size_t response_length = sizeof(response);
-	uint32_t data_size;
-	uint32_t err;
-
-	err = tpm_sendrecv_command(command, response, &response_length);
-	if (err)
-		return err;
-	if (unpack_byte_string(response, response_length, "d",
-				response_size_offset, &data_size))
-		return TPM_LIB_ERROR;
-	if (data_size < header_and_checksum_size)
-		return TPM_LIB_ERROR;
-	data_size -= header_and_checksum_size;
-	if (data_size > count)
-		return TPM_LIB_ERROR;
-	if (unpack_byte_string(response, response_length, "s",
-				data_offset, data, data_size))
-		return TPM_LIB_ERROR;
-
-	return 0;
-}
-
-uint32_t tpm_force_clear(void)
-{
-	const uint8_t command[10] = {
-		0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x5d,
-	};
-
-	return tpm_sendrecv_command(command, NULL, NULL);
-}
-
-uint32_t tpm_physical_enable(void)
-{
-	const uint8_t command[10] = {
-		0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x6f,
-	};
-
-	return tpm_sendrecv_command(command, NULL, NULL);
-}
-
-uint32_t tpm_physical_disable(void)
-{
-	const uint8_t command[10] = {
-		0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x70,
-	};
-
-	return tpm_sendrecv_command(command, NULL, NULL);
-}
-
-uint32_t tpm_physical_set_deactivated(uint8_t state)
-{
-	const uint8_t command[11] = {
-		0x0, 0xc1, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x72,
-	};
-	const size_t state_offset = 10;
-	uint8_t buf[COMMAND_BUFFER_SIZE];
-
-	if (pack_byte_string(buf, sizeof(buf), "sb",
-				0, command, sizeof(command),
-				state_offset, state))
-		return TPM_LIB_ERROR;
-
-	return tpm_sendrecv_command(buf, NULL, NULL);
-}
-
-uint32_t tpm_get_capability(uint32_t cap_area, uint32_t sub_cap,
-		void *cap, size_t count)
-{
-	const uint8_t command[22] = {
-		0x0, 0xc1,		/* TPM_TAG */
-		0x0, 0x0, 0x0, 0x16,	/* parameter size */
-		0x0, 0x0, 0x0, 0x65,	/* TPM_COMMAND_CODE */
-		0x0, 0x0, 0x0, 0x0,	/* TPM_CAPABILITY_AREA */
-		0x0, 0x0, 0x0, 0x4,	/* subcap size */
-		0x0, 0x0, 0x0, 0x0,	/* subcap value */
-	};
-	const size_t cap_area_offset = 10;
-	const size_t sub_cap_offset = 18;
-	const size_t cap_offset = 14;
-	const size_t cap_size_offset = 10;
-	uint8_t buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
-	size_t response_length = sizeof(response);
-	uint32_t cap_size;
-	uint32_t err;
-
-	if (pack_byte_string(buf, sizeof(buf), "sdd",
-				0, command, sizeof(command),
-				cap_area_offset, cap_area,
-				sub_cap_offset, sub_cap))
-		return TPM_LIB_ERROR;
-	err = tpm_sendrecv_command(buf, response, &response_length);
-	if (err)
-		return err;
-	if (unpack_byte_string(response, response_length, "d",
-				cap_size_offset, &cap_size))
-		return TPM_LIB_ERROR;
-	if (cap_size > response_length || cap_size > count)
-		return TPM_LIB_ERROR;
-	if (unpack_byte_string(response, response_length, "s",
-				cap_offset, cap, cap_size))
-		return TPM_LIB_ERROR;
-
-	return 0;
-}
-
-uint32_t tpm_get_permanent_flags(struct tpm_permanent_flags *pflags)
-{
-	const uint8_t command[22] = {
-		0x0, 0xc1,		/* TPM_TAG */
-		0x0, 0x0, 0x0, 0x16,	/* parameter size */
-		0x0, 0x0, 0x0, 0x65,	/* TPM_COMMAND_CODE */
-		0x0, 0x0, 0x0, 0x4,	/* TPM_CAP_FLAG_PERM */
-		0x0, 0x0, 0x0, 0x4,	/* subcap size */
-		0x0, 0x0, 0x1, 0x8,	/* subcap value */
-	};
-	const size_t data_size_offset = TPM_HEADER_SIZE;
-	const size_t data_offset = TPM_HEADER_SIZE + sizeof (uint32_t);
-	uint8_t response[COMMAND_BUFFER_SIZE];
-	size_t response_length = sizeof(response);
-	uint32_t err;
-	uint32_t data_size;
-
-	err = tpm_sendrecv_command(command, response, &response_length);
-	if (err)
-		return err;
-	if (unpack_byte_string(response, response_length, "d",
-			       data_size_offset, &data_size))
-		return TPM_LIB_ERROR;
-	if (data_size < sizeof(*pflags))
-		return TPM_LIB_ERROR;
-	if (unpack_byte_string(response, response_length, "s",
-			       data_offset, pflags, sizeof(*pflags)))
-		return TPM_LIB_ERROR;
-
-	return 0;
-}
-
-uint32_t tpm_get_permissions(uint32_t index, uint32_t *perm)
-{
-	const uint8_t command[22] = {
-		0x0, 0xc1,		/* TPM_TAG */
-		0x0, 0x0, 0x0, 0x16,	/* parameter size */
-		0x0, 0x0, 0x0, 0x65,	/* TPM_COMMAND_CODE */
-		0x0, 0x0, 0x0, 0x11,
-		0x0, 0x0, 0x0, 0x4,
-	};
-	const size_t index_offset = 18;
-	const size_t perm_offset = 60;
-	uint8_t buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
-	size_t response_length = sizeof(response);
-	uint32_t err;
-
-	if (pack_byte_string(buf, sizeof(buf), "d", 0, command, sizeof(command),
-			     index_offset, index))
-		return TPM_LIB_ERROR;
-	err = tpm_sendrecv_command(buf, response, &response_length);
-	if (err)
-		return err;
-	if (unpack_byte_string(response, response_length, "d",
-			       perm_offset, perm))
-		return TPM_LIB_ERROR;
-
-	return 0;
-}
-
-#ifdef CONFIG_TPM_FLUSH_RESOURCES
-uint32_t tpm_flush_specific(uint32_t key_handle, uint32_t resource_type)
-{
-	const uint8_t command[18] = {
-		0x00, 0xc1,             /* TPM_TAG */
-		0x00, 0x00, 0x00, 0x12, /* parameter size */
-		0x00, 0x00, 0x00, 0xba, /* TPM_COMMAND_CODE */
-		0x00, 0x00, 0x00, 0x00, /* key handle */
-		0x00, 0x00, 0x00, 0x00, /* resource type */
-	};
-	const size_t key_handle_offset = 10;
-	const size_t resource_type_offset = 14;
-	uint8_t buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
-	size_t response_length = sizeof(response);
-	uint32_t err;
-
-	if (pack_byte_string(buf, sizeof(buf), "sdd",
-			     0, command, sizeof(command),
-			     key_handle_offset, key_handle,
-			     resource_type_offset, resource_type))
-		return TPM_LIB_ERROR;
-
-	err = tpm_sendrecv_command(buf, response, &response_length);
-	if (err)
-		return err;
-	return 0;
-}
-#endif /* CONFIG_TPM_FLUSH_RESOURCES */
-
-#ifdef CONFIG_TPM_AUTH_SESSIONS
-
-/**
- * Fill an authentication block in a request.
- * This func can create the first as well as the second auth block (for
- * double authorized commands).
- *
- * @param request	pointer to the request (w/ uninitialised auth data)
- * @param request_len0	length of the request without auth data
- * @param handles_len	length of the handles area in request
- * @param auth_session	pointer to the (valid) auth session to be used
- * @param request_auth	pointer to the auth block of the request to be filled
- * @param auth		authentication data (HMAC key)
- */
-static uint32_t create_request_auth(const void *request, size_t request_len0,
-	size_t handles_len,
-	struct session_data *auth_session,
-	void *request_auth, const void *auth)
-{
-	uint8_t hmac_data[DIGEST_LENGTH * 3 + 1];
-	sha1_context hash_ctx;
-	const size_t command_code_offset = 6;
-	const size_t auth_nonce_odd_offset = 4;
-	const size_t auth_continue_offset = 24;
-	const size_t auth_auth_offset = 25;
-
-	if (!auth_session || !auth_session->valid)
-		return TPM_LIB_ERROR;
-
-	sha1_starts(&hash_ctx);
-	sha1_update(&hash_ctx, request + command_code_offset, 4);
-	if (request_len0 > TPM_REQUEST_HEADER_LENGTH + handles_len)
-		sha1_update(&hash_ctx,
-			    request + TPM_REQUEST_HEADER_LENGTH + handles_len,
-			    request_len0 - TPM_REQUEST_HEADER_LENGTH
-			    - handles_len);
-	sha1_finish(&hash_ctx, hmac_data);
-
-	sha1_starts(&hash_ctx);
-	sha1_update(&hash_ctx, auth_session->nonce_odd, DIGEST_LENGTH);
-	sha1_update(&hash_ctx, hmac_data, sizeof(hmac_data));
-	sha1_finish(&hash_ctx, auth_session->nonce_odd);
-
-	if (pack_byte_string(request_auth, TPM_REQUEST_AUTH_LENGTH, "dsb",
-			     0, auth_session->handle,
-			     auth_nonce_odd_offset, auth_session->nonce_odd,
-			     DIGEST_LENGTH,
-			     auth_continue_offset, 1))
-		return TPM_LIB_ERROR;
-	if (pack_byte_string(hmac_data, sizeof(hmac_data), "ss",
-			     DIGEST_LENGTH,
-			     auth_session->nonce_even,
-			     DIGEST_LENGTH,
-			     2 * DIGEST_LENGTH,
-			     request_auth + auth_nonce_odd_offset,
-			     DIGEST_LENGTH + 1))
-		return TPM_LIB_ERROR;
-	sha1_hmac(auth, DIGEST_LENGTH, hmac_data, sizeof(hmac_data),
-		  request_auth + auth_auth_offset);
-
-	return TPM_SUCCESS;
-}
-
-/**
- * Verify an authentication block in a response.
- * Since this func updates the nonce_even in the session data it has to be
- * called when receiving a succesfull AUTH response.
- * This func can verify the first as well as the second auth block (for
- * double authorized commands).
- *
- * @param command_code	command code of the request
- * @param response	pointer to the request (w/ uninitialised auth data)
- * @param handles_len	length of the handles area in response
- * @param auth_session	pointer to the (valid) auth session to be used
- * @param response_auth	pointer to the auth block of the response to be verified
- * @param auth		authentication data (HMAC key)
- */
-static uint32_t verify_response_auth(uint32_t command_code,
-	const void *response, size_t response_len0,
-	size_t handles_len,
-	struct session_data *auth_session,
-	const void *response_auth, const void *auth)
-{
-	uint8_t hmac_data[DIGEST_LENGTH * 3 + 1];
-	uint8_t computed_auth[DIGEST_LENGTH];
-	sha1_context hash_ctx;
-	const size_t return_code_offset = 6;
-	const size_t auth_continue_offset = 20;
-	const size_t auth_auth_offset = 21;
-	uint8_t auth_continue;
-
-	if (!auth_session || !auth_session->valid)
-		return TPM_AUTHFAIL;
-	if (pack_byte_string(hmac_data, sizeof(hmac_data), "d",
-			     0, command_code))
-		return TPM_LIB_ERROR;
-	if (response_len0 < TPM_RESPONSE_HEADER_LENGTH)
-		return TPM_LIB_ERROR;
-
-	sha1_starts(&hash_ctx);
-	sha1_update(&hash_ctx, response + return_code_offset, 4);
-	sha1_update(&hash_ctx, hmac_data, 4);
-	if (response_len0 > TPM_RESPONSE_HEADER_LENGTH + handles_len)
-		sha1_update(&hash_ctx,
-			    response + TPM_RESPONSE_HEADER_LENGTH + handles_len,
-			    response_len0 - TPM_RESPONSE_HEADER_LENGTH
-			    - handles_len);
-	sha1_finish(&hash_ctx, hmac_data);
-
-	memcpy(auth_session->nonce_even, response_auth, DIGEST_LENGTH);
-	auth_continue = ((uint8_t *)response_auth)[auth_continue_offset];
-	if (pack_byte_string(hmac_data, sizeof(hmac_data), "ssb",
-			     DIGEST_LENGTH,
-			     response_auth,
-			     DIGEST_LENGTH,
-			     2 * DIGEST_LENGTH,
-			     auth_session->nonce_odd,
-			     DIGEST_LENGTH,
-			     3 * DIGEST_LENGTH,
-			     auth_continue))
-		return TPM_LIB_ERROR;
-
-	sha1_hmac(auth, DIGEST_LENGTH, hmac_data, sizeof(hmac_data),
-		  computed_auth);
-
-	if (memcmp(computed_auth, response_auth + auth_auth_offset,
-		   DIGEST_LENGTH))
-		return TPM_AUTHFAIL;
-
-	return TPM_SUCCESS;
-}
-
-
-uint32_t tpm_terminate_auth_session(uint32_t auth_handle)
-{
-	const uint8_t command[18] = {
-		0x00, 0xc1,		/* TPM_TAG */
-		0x00, 0x00, 0x00, 0x00,	/* parameter size */
-		0x00, 0x00, 0x00, 0xba,	/* TPM_COMMAND_CODE */
-		0x00, 0x00, 0x00, 0x00,	/* TPM_HANDLE */
-		0x00, 0x00, 0x00, 0x02,	/* TPM_RESSOURCE_TYPE */
-	};
-	const size_t req_handle_offset = TPM_REQUEST_HEADER_LENGTH;
-	uint8_t request[COMMAND_BUFFER_SIZE];
-
-	if (pack_byte_string(request, sizeof(request), "sd",
-			     0, command, sizeof(command),
-			     req_handle_offset, auth_handle))
-		return TPM_LIB_ERROR;
-	if (oiap_session.valid && oiap_session.handle == auth_handle)
-		oiap_session.valid = 0;
-
-	return tpm_sendrecv_command(request, NULL, NULL);
-}
-
-uint32_t tpm_end_oiap(void)
-{
-	uint32_t err = TPM_SUCCESS;
-	if (oiap_session.valid)
-		err = tpm_terminate_auth_session(oiap_session.handle);
-	return err;
-}
-
-uint32_t tpm_oiap(uint32_t *auth_handle)
-{
-	const uint8_t command[10] = {
-		0x00, 0xc1,		/* TPM_TAG */
-		0x00, 0x00, 0x00, 0x0a,	/* parameter size */
-		0x00, 0x00, 0x00, 0x0a,	/* TPM_COMMAND_CODE */
-	};
-	const size_t res_auth_handle_offset = TPM_RESPONSE_HEADER_LENGTH;
-	const size_t res_nonce_even_offset = TPM_RESPONSE_HEADER_LENGTH + 4;
-	uint8_t response[COMMAND_BUFFER_SIZE];
-	size_t response_length = sizeof(response);
-	uint32_t err;
-
-	if (oiap_session.valid)
-		tpm_terminate_auth_session(oiap_session.handle);
-
-	err = tpm_sendrecv_command(command, response, &response_length);
-	if (err)
-		return err;
-	if (unpack_byte_string(response, response_length, "ds",
-			       res_auth_handle_offset, &oiap_session.handle,
-			       res_nonce_even_offset, &oiap_session.nonce_even,
-			       (uint32_t)DIGEST_LENGTH))
-		return TPM_LIB_ERROR;
-	oiap_session.valid = 1;
-	if (auth_handle)
-		*auth_handle = oiap_session.handle;
-	return 0;
-}
-
-uint32_t tpm_load_key2_oiap(uint32_t parent_handle,
-		const void *key, size_t key_length,
-		const void *parent_key_usage_auth,
-		uint32_t *key_handle)
-{
-	const uint8_t command[14] = {
-		0x00, 0xc2,		/* TPM_TAG */
-		0x00, 0x00, 0x00, 0x00,	/* parameter size */
-		0x00, 0x00, 0x00, 0x41,	/* TPM_COMMAND_CODE */
-		0x00, 0x00, 0x00, 0x00,	/* parent handle */
-	};
-	const size_t req_size_offset = 2;
-	const size_t req_parent_handle_offset = TPM_REQUEST_HEADER_LENGTH;
-	const size_t req_key_offset = TPM_REQUEST_HEADER_LENGTH + 4;
-	const size_t res_handle_offset = TPM_RESPONSE_HEADER_LENGTH;
-	uint8_t request[sizeof(command) + TPM_KEY12_MAX_LENGTH
-			+ TPM_REQUEST_AUTH_LENGTH];
-	uint8_t response[COMMAND_BUFFER_SIZE];
-	size_t response_length = sizeof(response);
-	uint32_t err;
-
-	if (!oiap_session.valid) {
-		err = tpm_oiap(NULL);
-		if (err)
-			return err;
-	}
-	if (pack_byte_string(request, sizeof(request), "sdds",
-			     0, command, sizeof(command),
-			     req_size_offset,
-			     sizeof(command) + key_length
-			     + TPM_REQUEST_AUTH_LENGTH,
-			     req_parent_handle_offset, parent_handle,
-			     req_key_offset, key, key_length
-		))
-		return TPM_LIB_ERROR;
-
-	err = create_request_auth(request, sizeof(command) + key_length, 4,
-				&oiap_session,
-				request + sizeof(command) + key_length,
-				parent_key_usage_auth);
-	if (err)
-		return err;
-	err = tpm_sendrecv_command(request, response, &response_length);
-	if (err) {
-		if (err == TPM_AUTHFAIL)
-			oiap_session.valid = 0;
-		return err;
-	}
-
-	err = verify_response_auth(0x00000041, response,
-			response_length - TPM_RESPONSE_AUTH_LENGTH,
-			4, &oiap_session,
-			response + response_length - TPM_RESPONSE_AUTH_LENGTH,
-			parent_key_usage_auth);
-	if (err)
-		return err;
-
-	if (key_handle) {
-		if (unpack_byte_string(response, response_length, "d",
-				       res_handle_offset, key_handle))
-			return TPM_LIB_ERROR;
-	}
-
-	return 0;
-}
-
-uint32_t tpm_get_pub_key_oiap(uint32_t key_handle, const void *usage_auth,
-			void *pubkey, size_t *pubkey_len)
-{
-	const uint8_t command[14] = {
-		0x00, 0xc2,		/* TPM_TAG */
-		0x00, 0x00, 0x00, 0x00,	/* parameter size */
-		0x00, 0x00, 0x00, 0x21,	/* TPM_COMMAND_CODE */
-		0x00, 0x00, 0x00, 0x00,	/* key handle */
-	};
-	const size_t req_size_offset = 2;
-	const size_t req_key_handle_offset = TPM_REQUEST_HEADER_LENGTH;
-	const size_t res_pubkey_offset = TPM_RESPONSE_HEADER_LENGTH;
-	uint8_t request[sizeof(command) + TPM_REQUEST_AUTH_LENGTH];
-	uint8_t response[TPM_RESPONSE_HEADER_LENGTH + TPM_PUBKEY_MAX_LENGTH
-			+ TPM_RESPONSE_AUTH_LENGTH];
-	size_t response_length = sizeof(response);
-	uint32_t err;
-
-	if (!oiap_session.valid) {
-		err = tpm_oiap(NULL);
-		if (err)
-			return err;
-	}
-	if (pack_byte_string(request, sizeof(request), "sdd",
-			     0, command, sizeof(command),
-			     req_size_offset,
-			     (uint32_t)(sizeof(command)
-			     + TPM_REQUEST_AUTH_LENGTH),
-			     req_key_handle_offset, key_handle
-		))
-		return TPM_LIB_ERROR;
-	err = create_request_auth(request, sizeof(command), 4, &oiap_session,
-			request + sizeof(command), usage_auth);
-	if (err)
-		return err;
-	err = tpm_sendrecv_command(request, response, &response_length);
-	if (err) {
-		if (err == TPM_AUTHFAIL)
-			oiap_session.valid = 0;
-		return err;
-	}
-	err = verify_response_auth(0x00000021, response,
-			response_length - TPM_RESPONSE_AUTH_LENGTH,
-			0, &oiap_session,
-			response + response_length - TPM_RESPONSE_AUTH_LENGTH,
-			usage_auth);
-	if (err)
-		return err;
-
-	if (pubkey) {
-		if ((response_length - TPM_RESPONSE_HEADER_LENGTH
-			- TPM_RESPONSE_AUTH_LENGTH) > *pubkey_len)
-			return TPM_LIB_ERROR;
-		*pubkey_len = response_length - TPM_RESPONSE_HEADER_LENGTH
-			- TPM_RESPONSE_AUTH_LENGTH;
-		memcpy(pubkey, response + res_pubkey_offset,
-		       response_length - TPM_RESPONSE_HEADER_LENGTH
-		       - TPM_RESPONSE_AUTH_LENGTH);
-	}
-
-	return 0;
-}
-
-#ifdef CONFIG_TPM_LOAD_KEY_BY_SHA1
-uint32_t tpm_find_key_sha1(const uint8_t auth[20], const uint8_t
-			   pubkey_digest[20], uint32_t *handle)
-{
-	uint16_t key_count;
-	uint32_t key_handles[10];
-	uint8_t buf[288];
-	uint8_t *ptr;
-	uint32_t err;
-	uint8_t digest[20];
-	size_t buf_len;
-	unsigned int i;
-
-	/* fetch list of already loaded keys in the TPM */
-	err = tpm_get_capability(TPM_CAP_HANDLE, TPM_RT_KEY, buf, sizeof(buf));
-	if (err)
-		return -1;
-	key_count = get_unaligned_be16(buf);
-	ptr = buf + 2;
-	for (i = 0; i < key_count; ++i, ptr += 4)
-		key_handles[i] = get_unaligned_be32(ptr);
-
-	/* now search a(/ the) key which we can access with the given auth */
-	for (i = 0; i < key_count; ++i) {
-		buf_len = sizeof(buf);
-		err = tpm_get_pub_key_oiap(key_handles[i], auth, buf, &buf_len);
-		if (err && err != TPM_AUTHFAIL)
-			return -1;
-		if (err)
-			continue;
-		sha1_csum(buf, buf_len, digest);
-		if (!memcmp(digest, pubkey_digest, 20)) {
-			*handle = key_handles[i];
-			return 0;
-		}
-	}
-	return 1;
-}
-#endif /* CONFIG_TPM_LOAD_KEY_BY_SHA1 */
-
-#endif /* CONFIG_TPM_AUTH_SESSIONS */
-
-uint32_t tpm_get_random(void *data, uint32_t count)
-{
-	const uint8_t command[14] = {
-		0x0, 0xc1,		/* TPM_TAG */
-		0x0, 0x0, 0x0, 0xe,	/* parameter size */
-		0x0, 0x0, 0x0, 0x46,	/* TPM_COMMAND_CODE */
-	};
-	const size_t length_offset = 10;
-	const size_t data_size_offset = 10;
-	const size_t data_offset = 14;
-	uint8_t buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
-	size_t response_length = sizeof(response);
-	uint32_t data_size;
-	uint8_t *out = data;
-
-	while (count > 0) {
-		uint32_t this_bytes = min((size_t)count,
-					  sizeof (response) - data_offset);
-		uint32_t err;
-
-		if (pack_byte_string(buf, sizeof(buf), "sd",
-				     0, command, sizeof(command),
-				     length_offset, this_bytes))
-			return TPM_LIB_ERROR;
-		err = tpm_sendrecv_command(buf, response, &response_length);
-		if (err)
-			return err;
-		if (unpack_byte_string(response, response_length, "d",
-				       data_size_offset, &data_size))
-			return TPM_LIB_ERROR;
-		if (data_size > count)
-			return TPM_LIB_ERROR;
-		if (unpack_byte_string(response, response_length, "s",
-				       data_offset, out, data_size))
-			return TPM_LIB_ERROR;
-
-		count -= data_size;
-		out += data_size;
-	}
-
-	return 0;
-}
diff --git a/net/Makefile b/net/Makefile
index d1e8e01..0746687 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -23,6 +23,7 @@
 obj-$(CONFIG_CMD_RARP) += rarp.o
 obj-$(CONFIG_CMD_SNTP) += sntp.o
 obj-$(CONFIG_CMD_TFTPBOOT) += tftp.o
+obj-$(CONFIG_UDP_FUNCTION_FASTBOOT)  += fastboot.o
 
 # Disable this warning as it is triggered by:
 # sprintf(buf, index ? "foo%d" : "foo", index)
diff --git a/net/fastboot.c b/net/fastboot.c
new file mode 100644
index 0000000..a9f7c07
--- /dev/null
+++ b/net/fastboot.c
@@ -0,0 +1,317 @@
+// SPDX-License-Identifier: BSD-2-Clause
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ */
+
+#include <common.h>
+#include <fastboot.h>
+#include <net.h>
+#include <net/fastboot.h>
+
+/* Fastboot port # defined in spec */
+#define WELL_KNOWN_PORT 5554
+
+enum {
+	FASTBOOT_ERROR = 0,
+	FASTBOOT_QUERY = 1,
+	FASTBOOT_INIT = 2,
+	FASTBOOT_FASTBOOT = 3,
+};
+
+struct __packed fastboot_header {
+	uchar id;
+	uchar flags;
+	unsigned short seq;
+};
+
+#define PACKET_SIZE 1024
+#define DATA_SIZE (PACKET_SIZE - sizeof(struct fastboot_header))
+
+/* Sequence number sent for every packet */
+static unsigned short sequence_number = 1;
+static const unsigned short packet_size = PACKET_SIZE;
+static const unsigned short udp_version = 1;
+
+/* Keep track of last packet for resubmission */
+static uchar last_packet[PACKET_SIZE];
+static unsigned int last_packet_len;
+
+static struct in_addr fastboot_remote_ip;
+/* The UDP port at their end */
+static int fastboot_remote_port;
+/* The UDP port at our end */
+static int fastboot_our_port;
+
+static void boot_downloaded_image(void);
+
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
+/**
+ * fastboot_udp_send_info() - Send an INFO packet during long commands.
+ *
+ * @msg: String describing the reason for waiting
+ */
+static void fastboot_udp_send_info(const char *msg)
+{
+	uchar *packet;
+	uchar *packet_base;
+	int len = 0;
+	char response[FASTBOOT_RESPONSE_LEN] = {0};
+
+	struct fastboot_header response_header = {
+		.id = FASTBOOT_FASTBOOT,
+		.flags = 0,
+		.seq = htons(sequence_number)
+	};
+	++sequence_number;
+	packet = net_tx_packet + net_eth_hdr_size() + IP_UDP_HDR_SIZE;
+	packet_base = packet;
+
+	/* Write headers */
+	memcpy(packet, &response_header, sizeof(response_header));
+	packet += sizeof(response_header);
+	/* Write response */
+	fastboot_response("INFO", response, "%s", msg);
+	memcpy(packet, response, strlen(response));
+	packet += strlen(response);
+
+	len = packet - packet_base;
+
+	/* Save packet for retransmitting */
+	last_packet_len = len;
+	memcpy(last_packet, packet_base, last_packet_len);
+
+	net_send_udp_packet(net_server_ethaddr, fastboot_remote_ip,
+			    fastboot_remote_port, fastboot_our_port, len);
+}
+
+/**
+ * fastboot_timed_send_info() - Send INFO packet every 30 seconds
+ *
+ * @msg: String describing the reason for waiting
+ *
+ * Send an INFO packet during long commands based on timer. An INFO packet
+ * is sent if the time is 30 seconds after start. Else, noop.
+ */
+static void fastboot_timed_send_info(const char *msg)
+{
+	static ulong start;
+
+	/* Initialize timer */
+	if (start == 0)
+		start = get_timer(0);
+	ulong time = get_timer(start);
+	/* Send INFO packet to host every 30 seconds */
+	if (time >= 30000) {
+		start = get_timer(0);
+		fastboot_udp_send_info(msg);
+	}
+}
+#endif
+
+/**
+ * fastboot_send() - Sends a packet in response to received fastboot packet
+ *
+ * @header: Header for response packet
+ * @fastboot_data: Pointer to received fastboot data
+ * @fastboot_data_len: Length of received fastboot data
+ * @retransmit: Nonzero if sending last sent packet
+ */
+static void fastboot_send(struct fastboot_header header, char *fastboot_data,
+			  unsigned int fastboot_data_len, uchar retransmit)
+{
+	uchar *packet;
+	uchar *packet_base;
+	int len = 0;
+	const char *error_msg = "An error occurred.";
+	short tmp;
+	struct fastboot_header response_header = header;
+	static char command[FASTBOOT_COMMAND_LEN];
+	static int cmd = -1;
+	static bool pending_command;
+	char response[FASTBOOT_RESPONSE_LEN] = {0};
+
+	/*
+	 * We will always be sending some sort of packet, so
+	 * cobble together the packet headers now.
+	 */
+	packet = net_tx_packet + net_eth_hdr_size() + IP_UDP_HDR_SIZE;
+	packet_base = packet;
+
+	/* Resend last packet */
+	if (retransmit) {
+		memcpy(packet, last_packet, last_packet_len);
+		net_send_udp_packet(net_server_ethaddr, fastboot_remote_ip,
+				    fastboot_remote_port, fastboot_our_port,
+				    last_packet_len);
+		return;
+	}
+
+	response_header.seq = htons(response_header.seq);
+	memcpy(packet, &response_header, sizeof(response_header));
+	packet += sizeof(response_header);
+
+	switch (header.id) {
+	case FASTBOOT_QUERY:
+		tmp = htons(sequence_number);
+		memcpy(packet, &tmp, sizeof(tmp));
+		packet += sizeof(tmp);
+		break;
+	case FASTBOOT_INIT:
+		tmp = htons(udp_version);
+		memcpy(packet, &tmp, sizeof(tmp));
+		packet += sizeof(tmp);
+		tmp = htons(packet_size);
+		memcpy(packet, &tmp, sizeof(tmp));
+		packet += sizeof(tmp);
+		break;
+	case FASTBOOT_ERROR:
+		memcpy(packet, error_msg, strlen(error_msg));
+		packet += strlen(error_msg);
+		break;
+	case FASTBOOT_FASTBOOT:
+		if (cmd == FASTBOOT_COMMAND_DOWNLOAD) {
+			if (!fastboot_data_len && !fastboot_data_remaining()) {
+				fastboot_data_complete(response);
+			} else {
+				fastboot_data_download(fastboot_data,
+						       fastboot_data_len,
+						       response);
+			}
+		} else if (!pending_command) {
+			strlcpy(command, fastboot_data,
+				min((size_t)fastboot_data_len + 1,
+				    sizeof(command)));
+			pending_command = true;
+		} else {
+			cmd = fastboot_handle_command(command, response);
+			pending_command = false;
+		}
+		/*
+		 * Sent some INFO packets, need to update sequence number in
+		 * header
+		 */
+		if (header.seq != sequence_number) {
+			response_header.seq = htons(sequence_number);
+			memcpy(packet_base, &response_header,
+			       sizeof(response_header));
+		}
+		/* Write response to packet */
+		memcpy(packet, response, strlen(response));
+		packet += strlen(response);
+		break;
+	default:
+		pr_err("ID %d not implemented.\n", header.id);
+		return;
+	}
+
+	len = packet - packet_base;
+
+	/* Save packet for retransmitting */
+	last_packet_len = len;
+	memcpy(last_packet, packet_base, last_packet_len);
+
+	net_send_udp_packet(net_server_ethaddr, fastboot_remote_ip,
+			    fastboot_remote_port, fastboot_our_port, len);
+
+	/* Continue boot process after sending response */
+	if (!strncmp("OKAY", response, 4)) {
+		switch (cmd) {
+		case FASTBOOT_COMMAND_BOOT:
+			boot_downloaded_image();
+			break;
+
+		case FASTBOOT_COMMAND_CONTINUE:
+			net_set_state(NETLOOP_SUCCESS);
+			break;
+
+		case FASTBOOT_COMMAND_REBOOT:
+		case FASTBOOT_COMMAND_REBOOT_BOOTLOADER:
+			do_reset(NULL, 0, 0, NULL);
+			break;
+		}
+	}
+
+	if (!strncmp("OKAY", response, 4) || !strncmp("FAIL", response, 4))
+		cmd = -1;
+}
+
+/**
+ * boot_downloaded_image() - Boots into downloaded image.
+ */
+static void boot_downloaded_image(void)
+{
+	fastboot_boot();
+	net_set_state(NETLOOP_SUCCESS);
+}
+
+/**
+ * fastboot_handler() - Incoming UDP packet handler.
+ *
+ * @packet: Pointer to incoming UDP packet
+ * @dport: Destination UDP port
+ * @sip: Source IP address
+ * @sport: Source UDP port
+ * @len: Packet length
+ */
+static void fastboot_handler(uchar *packet, unsigned int dport,
+			     struct in_addr sip, unsigned int sport,
+			     unsigned int len)
+{
+	struct fastboot_header header;
+	char fastboot_data[DATA_SIZE] = {0};
+	unsigned int fastboot_data_len = 0;
+
+	if (dport != fastboot_our_port)
+		return;
+
+	fastboot_remote_ip = sip;
+	fastboot_remote_port = sport;
+
+	if (len < sizeof(struct fastboot_header) || len > PACKET_SIZE)
+		return;
+	memcpy(&header, packet, sizeof(header));
+	header.flags = 0;
+	header.seq = ntohs(header.seq);
+	packet += sizeof(header);
+	len -= sizeof(header);
+
+	switch (header.id) {
+	case FASTBOOT_QUERY:
+		fastboot_send(header, fastboot_data, 0, 0);
+		break;
+	case FASTBOOT_INIT:
+	case FASTBOOT_FASTBOOT:
+		fastboot_data_len = len;
+		if (len > 0)
+			memcpy(fastboot_data, packet, len);
+		if (header.seq == sequence_number) {
+			fastboot_send(header, fastboot_data,
+				      fastboot_data_len, 0);
+			sequence_number++;
+		} else if (header.seq == sequence_number - 1) {
+			/* Retransmit last sent packet */
+			fastboot_send(header, fastboot_data,
+				      fastboot_data_len, 1);
+		}
+		break;
+	default:
+		pr_err("ID %d not implemented.\n", header.id);
+		header.id = FASTBOOT_ERROR;
+		fastboot_send(header, fastboot_data, 0, 0);
+		break;
+	}
+}
+
+void fastboot_start_server(void)
+{
+	printf("Using %s device\n", eth_get_name());
+	printf("Listening for fastboot command on %pI4\n", &net_ip);
+
+	fastboot_our_port = WELL_KNOWN_PORT;
+
+	fastboot_set_progress_callback(fastboot_timed_send_info);
+	net_set_udp_handler(fastboot_handler);
+
+	/* zero out server ether in case the server ip has changed */
+	memset(net_server_ethaddr, 0, 6);
+}
diff --git a/net/net.c b/net/net.c
index 7f85211..a4932f4 100644
--- a/net/net.c
+++ b/net/net.c
@@ -87,6 +87,7 @@
 #include <environment.h>
 #include <errno.h>
 #include <net.h>
+#include <net/fastboot.h>
 #include <net/tftp.h>
 #if defined(CONFIG_LED_STATUS)
 #include <miiphy.h>
@@ -451,6 +452,11 @@
 			tftp_start_server();
 			break;
 #endif
+#ifdef CONFIG_UDP_FUNCTION_FASTBOOT
+		case FASTBOOT:
+			fastboot_start_server();
+			break;
+#endif
 #if defined(CONFIG_CMD_DHCP)
 		case DHCP:
 			bootp_reset();
@@ -1322,6 +1328,7 @@
 		/* Fall through */
 
 	case NETCONS:
+	case FASTBOOT:
 	case TFTPSRV:
 		if (net_ip.s_addr == 0) {
 			puts("*** ERROR: `ipaddr' not set\n");
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 4a6ed34..482ed0c 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -415,6 +415,17 @@
 targets += $(multi-used-y) $(multi-used-m)
 
 
+# Add intermediate targets:
+# When building objects with specific suffix patterns, add intermediate
+# targets that the final targets are derived from.
+intermediate_targets = $(foreach sfx, $(2), \
+				$(patsubst %$(strip $(1)),%$(sfx), \
+					$(filter %$(strip $(1)), $(targets))))
+# %.lex.o <- %.lex.c <- %.l
+# %.tab.o <- %.tab.[ch] <- %.y
+targets += $(call intermediate_targets, .lex.o, .lex.c) \
+	   $(call intermediate_targets, .tab.o, .tab.c .tab.h)
+
 # Descending
 # ---------------------------------------------------------------------------
 
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index f9809ce..ef7604c 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -209,47 +209,30 @@
 	$(addprefix $(obj)/, $(foreach s, $3, $($(m:%$(strip $2)=%$(s)))))))
 endef
 
-ifdef REGENERATE_PARSERS
-
-# GPERF
-# ---------------------------------------------------------------------------
-quiet_cmd_gperf = GPERF $@
-      cmd_gperf = gperf -t --output-file $@ -a -C -E -g -k 1,3,$$ -p -t $<
-
-.PRECIOUS: $(src)/%.hash.c_shipped
-$(src)/%.hash.c_shipped: $(src)/%.gperf
-	$(call cmd,gperf)
-
 # LEX
 # ---------------------------------------------------------------------------
-LEX_PREFIX = $(if $(LEX_PREFIX_${baseprereq}),$(LEX_PREFIX_${baseprereq}),yy)
-
 quiet_cmd_flex = LEX     $@
-      cmd_flex = flex -o$@ -L -P $(LEX_PREFIX) $<
+      cmd_flex = $(LEX) -o$@ -L $<
 
-.PRECIOUS: $(src)/%.lex.c_shipped
-$(src)/%.lex.c_shipped: $(src)/%.l
-	$(call cmd,flex)
+.PRECIOUS: $(obj)/%.lex.c
+$(obj)/%.lex.c: $(src)/%.l FORCE
+	$(call if_changed,flex)
 
 # YACC
 # ---------------------------------------------------------------------------
-YACC_PREFIX = $(if $(YACC_PREFIX_${baseprereq}),$(YACC_PREFIX_${baseprereq}),yy)
-
 quiet_cmd_bison = YACC    $@
-      cmd_bison = bison -o$@ -t -l -p $(YACC_PREFIX) $<
+      cmd_bison = $(YACC) -o$@ -t -l $<
 
-.PRECIOUS: $(src)/%.tab.c_shipped
-$(src)/%.tab.c_shipped: $(src)/%.y
-	$(call cmd,bison)
+.PRECIOUS: $(obj)/%.tab.c
+$(obj)/%.tab.c: $(src)/%.y FORCE
+	$(call if_changed,bison)
 
 quiet_cmd_bison_h = YACC    $@
-      cmd_bison_h = bison -o/dev/null --defines=$@ -t -l -p $(YACC_PREFIX) $<
+      cmd_bison_h = $(YACC) -o/dev/null --defines=$@ -t -l $<
 
-.PRECIOUS: $(src)/%.tab.h_shipped
-$(src)/%.tab.h_shipped: $(src)/%.y
-	$(call cmd,bison_h)
-
-endif
+.PRECIOUS: $(obj)/%.tab.h
+$(obj)/%.tab.h: $(src)/%.y FORCE
+	$(call if_changed,bison_h)
 
 # Shipped files
 # ===========================================================================
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index c5cb23d..d681937 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -589,8 +589,6 @@
 CONFIG_EXYNOS_SPL
 CONFIG_EXYNOS_TMU
 CONFIG_FACTORYSET
-CONFIG_FASTBOOT_FLASH_FILLBUF_SIZE
-CONFIG_FASTBOOT_FLASH_NAND_TRIMFFS
 CONFIG_FAST_FLASH_BIT
 CONFIG_FB_ADDR
 CONFIG_FB_BACKLIGHT
@@ -1333,7 +1331,6 @@
 CONFIG_MULTI_CS
 CONFIG_MUSB_HOST
 CONFIG_MVEBU_MMC
-CONFIG_MVGBE
 CONFIG_MVGBE_PORTS
 CONFIG_MVMFP_V2
 CONFIG_MVS
@@ -3579,7 +3576,6 @@
 CONFIG_SYS_MSC1_VAL
 CONFIG_SYS_MSC2_VAL
 CONFIG_SYS_MTDPARTS_RUNTIME
-CONFIG_SYS_MVFS
 CONFIG_SYS_MX5_CLK32
 CONFIG_SYS_MX5_HCLK
 CONFIG_SYS_MX6_CLK32
diff --git a/scripts/dtc/.gitignore b/scripts/dtc/.gitignore
index d807c08..689b9be 100644
--- a/scripts/dtc/.gitignore
+++ b/scripts/dtc/.gitignore
@@ -1,4 +1 @@
 /dtc
-/dtc-lexer.lex.c
-/dtc-parser.tab.c
-/dtc-parser.tab.h
diff --git a/scripts/dtc/Makefile b/scripts/dtc/Makefile
index 90ef2db..e999be9 100644
--- a/scripts/dtc/Makefile
+++ b/scripts/dtc/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
 # scripts/dtc makefile
 
 hostprogs-y	:= dtc
@@ -27,8 +28,5 @@
 # dependencies on generated files need to be listed explicitly
 $(obj)/dtc-lexer.lex.o: $(obj)/dtc-parser.tab.h
 
-# generated files need to be cleaned explicitly
-clean-files	:= dtc-lexer.lex.c dtc-parser.tab.c dtc-parser.tab.h
-
 # Added for U-Boot
 subdir-$(CONFIG_PYLIBFDT) += pylibfdt
diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c
index 08a3a29..c07ba4d 100644
--- a/scripts/dtc/checks.c
+++ b/scripts/dtc/checks.c
@@ -53,26 +53,28 @@
 	struct check **prereq;
 };
 
-#define CHECK_ENTRY(_nm, _fn, _d, _w, _e, ...)	       \
-	static struct check *_nm##_prereqs[] = { __VA_ARGS__ }; \
-	static struct check _nm = { \
-		.name = #_nm, \
-		.fn = (_fn), \
-		.data = (_d), \
-		.warn = (_w), \
-		.error = (_e), \
+#define CHECK_ENTRY(nm_, fn_, d_, w_, e_, ...)	       \
+	static struct check *nm_##_prereqs[] = { __VA_ARGS__ }; \
+	static struct check nm_ = { \
+		.name = #nm_, \
+		.fn = (fn_), \
+		.data = (d_), \
+		.warn = (w_), \
+		.error = (e_), \
 		.status = UNCHECKED, \
-		.num_prereqs = ARRAY_SIZE(_nm##_prereqs), \
-		.prereq = _nm##_prereqs, \
+		.num_prereqs = ARRAY_SIZE(nm_##_prereqs), \
+		.prereq = nm_##_prereqs, \
 	};
-#define WARNING(_nm, _fn, _d, ...) \
-	CHECK_ENTRY(_nm, _fn, _d, true, false, __VA_ARGS__)
-#define ERROR(_nm, _fn, _d, ...) \
-	CHECK_ENTRY(_nm, _fn, _d, false, true, __VA_ARGS__)
-#define CHECK(_nm, _fn, _d, ...) \
-	CHECK_ENTRY(_nm, _fn, _d, false, false, __VA_ARGS__)
+#define WARNING(nm_, fn_, d_, ...) \
+	CHECK_ENTRY(nm_, fn_, d_, true, false, __VA_ARGS__)
+#define ERROR(nm_, fn_, d_, ...) \
+	CHECK_ENTRY(nm_, fn_, d_, false, true, __VA_ARGS__)
+#define CHECK(nm_, fn_, d_, ...) \
+	CHECK_ENTRY(nm_, fn_, d_, false, false, __VA_ARGS__)
 
-static inline void  PRINTF(3, 4) check_msg(struct check *c, struct dt_info *dti,
+static inline void  PRINTF(5, 6) check_msg(struct check *c, struct dt_info *dti,
+					   struct node *node,
+					   struct property *prop,
 					   const char *fmt, ...)
 {
 	va_list ap;
@@ -83,19 +85,33 @@
 		fprintf(stderr, "%s: %s (%s): ",
 			strcmp(dti->outname, "-") ? dti->outname : "<stdout>",
 			(c->error) ? "ERROR" : "Warning", c->name);
+		if (node) {
+			fprintf(stderr, "%s", node->fullpath);
+			if (prop)
+				fprintf(stderr, ":%s", prop->name);
+			fputs(": ", stderr);
+		}
 		vfprintf(stderr, fmt, ap);
 		fprintf(stderr, "\n");
 	}
 	va_end(ap);
 }
 
-#define FAIL(c, dti, ...)						\
+#define FAIL(c, dti, node, ...)						\
 	do {								\
 		TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__);	\
 		(c)->status = FAILED;					\
-		check_msg((c), dti, __VA_ARGS__);			\
+		check_msg((c), dti, node, NULL, __VA_ARGS__);		\
 	} while (0)
 
+#define FAIL_PROP(c, dti, node, prop, ...)				\
+	do {								\
+		TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__);	\
+		(c)->status = FAILED;					\
+		check_msg((c), dti, node, prop, __VA_ARGS__);		\
+	} while (0)
+
+
 static void check_nodes_props(struct check *c, struct dt_info *dti, struct node *node)
 {
 	struct node *child;
@@ -126,7 +142,7 @@
 		error = error || run_check(prq, dti);
 		if (prq->status != PASSED) {
 			c->status = PREREQ;
-			check_msg(c, dti, "Failed prerequisite '%s'",
+			check_msg(c, dti, NULL, NULL, "Failed prerequisite '%s'",
 				  c->prereq[i]->name);
 		}
 	}
@@ -156,7 +172,7 @@
 static inline void check_always_fail(struct check *c, struct dt_info *dti,
 				     struct node *node)
 {
-	FAIL(c, dti, "always_fail check");
+	FAIL(c, dti, node, "always_fail check");
 }
 CHECK(always_fail, check_always_fail, NULL);
 
@@ -171,14 +187,42 @@
 		return; /* Not present, assumed ok */
 
 	if (!data_is_one_string(prop->val))
-		FAIL(c, dti, "\"%s\" property in %s is not a string",
-		     propname, node->fullpath);
+		FAIL_PROP(c, dti, node, prop, "property is not a string");
 }
 #define WARNING_IF_NOT_STRING(nm, propname) \
 	WARNING(nm, check_is_string, (propname))
 #define ERROR_IF_NOT_STRING(nm, propname) \
 	ERROR(nm, check_is_string, (propname))
 
+static void check_is_string_list(struct check *c, struct dt_info *dti,
+				 struct node *node)
+{
+	int rem, l;
+	struct property *prop;
+	char *propname = c->data;
+	char *str;
+
+	prop = get_property(node, propname);
+	if (!prop)
+		return; /* Not present, assumed ok */
+
+	str = prop->val.val;
+	rem = prop->val.len;
+	while (rem > 0) {
+		l = strnlen(str, rem);
+		if (l == rem) {
+			FAIL_PROP(c, dti, node, prop, "property is not a string list");
+			break;
+		}
+		rem -= l + 1;
+		str += l + 1;
+	}
+}
+#define WARNING_IF_NOT_STRING_LIST(nm, propname) \
+	WARNING(nm, check_is_string_list, (propname))
+#define ERROR_IF_NOT_STRING_LIST(nm, propname) \
+	ERROR(nm, check_is_string_list, (propname))
+
 static void check_is_cell(struct check *c, struct dt_info *dti,
 			  struct node *node)
 {
@@ -190,8 +234,7 @@
 		return; /* Not present, assumed ok */
 
 	if (prop->val.len != sizeof(cell_t))
-		FAIL(c, dti, "\"%s\" property in %s is not a single cell",
-		     propname, node->fullpath);
+		FAIL_PROP(c, dti, node, prop, "property is not a single cell");
 }
 #define WARNING_IF_NOT_CELL(nm, propname) \
 	WARNING(nm, check_is_cell, (propname))
@@ -212,8 +255,7 @@
 		     child2;
 		     child2 = child2->next_sibling)
 			if (streq(child->name, child2->name))
-				FAIL(c, dti, "Duplicate node name %s",
-				     child->fullpath);
+				FAIL(c, dti, node, "Duplicate node name");
 }
 ERROR(duplicate_node_names, check_duplicate_node_names, NULL);
 
@@ -227,8 +269,7 @@
 			if (prop2->deleted)
 				continue;
 			if (streq(prop->name, prop2->name))
-				FAIL(c, dti, "Duplicate property name %s in %s",
-				     prop->name, node->fullpath);
+				FAIL_PROP(c, dti, node, prop, "Duplicate property name");
 		}
 	}
 }
@@ -246,8 +287,8 @@
 	int n = strspn(node->name, c->data);
 
 	if (n < strlen(node->name))
-		FAIL(c, dti, "Bad character '%c' in node %s",
-		     node->name[n], node->fullpath);
+		FAIL(c, dti, node, "Bad character '%c' in node name",
+		     node->name[n]);
 }
 ERROR(node_name_chars, check_node_name_chars, PROPNODECHARS "@");
 
@@ -257,8 +298,8 @@
 	int n = strspn(node->name, c->data);
 
 	if (n < node->basenamelen)
-		FAIL(c, dti, "Character '%c' not recommended in node %s",
-		     node->name[n], node->fullpath);
+		FAIL(c, dti, node, "Character '%c' not recommended in node name",
+		     node->name[n]);
 }
 CHECK(node_name_chars_strict, check_node_name_chars_strict, PROPNODECHARSSTRICT);
 
@@ -266,8 +307,7 @@
 				   struct node *node)
 {
 	if (strchr(get_unitname(node), '@'))
-		FAIL(c, dti, "Node %s has multiple '@' characters in name",
-		     node->fullpath);
+		FAIL(c, dti, node, "multiple '@' characters in node name");
 }
 ERROR(node_name_format, check_node_name_format, NULL, &node_name_chars);
 
@@ -285,12 +325,10 @@
 
 	if (prop) {
 		if (!unitname[0])
-			FAIL(c, dti, "Node %s has a reg or ranges property, but no unit name",
-			    node->fullpath);
+			FAIL(c, dti, node, "node has a reg or ranges property, but no unit name");
 	} else {
 		if (unitname[0])
-			FAIL(c, dti, "Node %s has a unit name, but no reg property",
-			    node->fullpath);
+			FAIL(c, dti, node, "node has a unit name, but no reg property");
 	}
 }
 WARNING(unit_address_vs_reg, check_unit_address_vs_reg, NULL);
@@ -304,8 +342,8 @@
 		int n = strspn(prop->name, c->data);
 
 		if (n < strlen(prop->name))
-			FAIL(c, dti, "Bad character '%c' in property name \"%s\", node %s",
-			     prop->name[n], prop->name, node->fullpath);
+			FAIL_PROP(c, dti, node, prop, "Bad character '%c' in property name",
+				  prop->name[n]);
 	}
 }
 ERROR(property_name_chars, check_property_name_chars, PROPNODECHARS);
@@ -336,8 +374,8 @@
 			n = strspn(name, c->data);
 		}
 		if (n < strlen(name))
-			FAIL(c, dti, "Character '%c' not recommended in property name \"%s\", node %s",
-			     name[n], prop->name, node->fullpath);
+			FAIL_PROP(c, dti, node, prop, "Character '%c' not recommended in property name",
+				  name[n]);
 	}
 }
 CHECK(property_name_chars_strict, check_property_name_chars_strict, PROPNODECHARSSTRICT);
@@ -370,7 +408,7 @@
 		return;
 
 	if ((othernode != node) || (otherprop != prop) || (othermark != mark))
-		FAIL(c, dti, "Duplicate label '%s' on " DESCLABEL_FMT
+		FAIL(c, dti, node, "Duplicate label '%s' on " DESCLABEL_FMT
 		     " and " DESCLABEL_FMT,
 		     label, DESCLABEL_ARGS(node, prop, mark),
 		     DESCLABEL_ARGS(othernode, otherprop, othermark));
@@ -410,8 +448,8 @@
 		return 0;
 
 	if (prop->val.len != sizeof(cell_t)) {
-		FAIL(c, dti, "%s has bad length (%d) %s property",
-		     node->fullpath, prop->val.len, prop->name);
+		FAIL_PROP(c, dti, node, prop, "bad length (%d) %s property",
+			  prop->val.len, prop->name);
 		return 0;
 	}
 
@@ -422,8 +460,8 @@
 			/* "Set this node's phandle equal to some
 			 * other node's phandle".  That's nonsensical
 			 * by construction. */ {
-			FAIL(c, dti, "%s in %s is a reference to another node",
-			     prop->name, node->fullpath);
+			FAIL(c, dti, node, "%s is a reference to another node",
+			     prop->name);
 		}
 		/* But setting this node's phandle equal to its own
 		 * phandle is allowed - that means allocate a unique
@@ -436,8 +474,8 @@
 	phandle = propval_cell(prop);
 
 	if ((phandle == 0) || (phandle == -1)) {
-		FAIL(c, dti, "%s has bad value (0x%x) in %s property",
-		     node->fullpath, phandle, prop->name);
+		FAIL_PROP(c, dti, node, prop, "bad value (0x%x) in %s property",
+		     phandle, prop->name);
 		return 0;
 	}
 
@@ -463,16 +501,16 @@
 		return;
 
 	if (linux_phandle && phandle && (phandle != linux_phandle))
-		FAIL(c, dti, "%s has mismatching 'phandle' and 'linux,phandle'"
-		     " properties", node->fullpath);
+		FAIL(c, dti, node, "mismatching 'phandle' and 'linux,phandle'"
+		     " properties");
 
 	if (linux_phandle && !phandle)
 		phandle = linux_phandle;
 
 	other = get_node_by_phandle(root, phandle);
 	if (other && (other != node)) {
-		FAIL(c, dti, "%s has duplicated phandle 0x%x (seen before at %s)",
-		     node->fullpath, phandle, other->fullpath);
+		FAIL(c, dti, node, "duplicated phandle 0x%x (seen before at %s)",
+		     phandle, other->fullpath);
 		return;
 	}
 
@@ -496,8 +534,8 @@
 
 	if ((prop->val.len != node->basenamelen+1)
 	    || (memcmp(prop->val.val, node->name, node->basenamelen) != 0)) {
-		FAIL(c, dti, "\"name\" property in %s is incorrect (\"%s\" instead"
-		     " of base node name)", node->fullpath, prop->val.val);
+		FAIL(c, dti, node, "\"name\" property is incorrect (\"%s\" instead"
+		     " of base node name)", prop->val.val);
 	} else {
 		/* The name property is correct, and therefore redundant.
 		 * Delete it */
@@ -531,7 +569,7 @@
 			refnode = get_node_by_ref(dt, m->ref);
 			if (! refnode) {
 				if (!(dti->dtsflags & DTSF_PLUGIN))
-					FAIL(c, dti, "Reference to non-existent node or "
+					FAIL(c, dti, node, "Reference to non-existent node or "
 							"label \"%s\"\n", m->ref);
 				else /* mark the entry as unresolved */
 					*((fdt32_t *)(prop->val.val + m->offset)) =
@@ -563,7 +601,7 @@
 
 			refnode = get_node_by_ref(dt, m->ref);
 			if (!refnode) {
-				FAIL(c, dti, "Reference to non-existent node or label \"%s\"\n",
+				FAIL(c, dti, node, "Reference to non-existent node or label \"%s\"\n",
 				     m->ref);
 				continue;
 			}
@@ -586,6 +624,45 @@
 WARNING_IF_NOT_STRING(device_type_is_string, "device_type");
 WARNING_IF_NOT_STRING(model_is_string, "model");
 WARNING_IF_NOT_STRING(status_is_string, "status");
+WARNING_IF_NOT_STRING(label_is_string, "label");
+
+WARNING_IF_NOT_STRING_LIST(compatible_is_string_list, "compatible");
+
+static void check_names_is_string_list(struct check *c, struct dt_info *dti,
+				       struct node *node)
+{
+	struct property *prop;
+
+	for_each_property(node, prop) {
+		const char *s = strrchr(prop->name, '-');
+		if (!s || !streq(s, "-names"))
+			continue;
+
+		c->data = prop->name;
+		check_is_string_list(c, dti, node);
+	}
+}
+WARNING(names_is_string_list, check_names_is_string_list, NULL);
+
+static void check_alias_paths(struct check *c, struct dt_info *dti,
+				    struct node *node)
+{
+	struct property *prop;
+
+	if (!streq(node->name, "aliases"))
+		return;
+
+	for_each_property(node, prop) {
+		if (!prop->val.val || !get_node_by_path(dti->dt, prop->val.val)) {
+			FAIL_PROP(c, dti, node, prop, "aliases property is not a valid node (%s)",
+				  prop->val.val);
+			continue;
+		}
+		if (strspn(prop->name, LOWERCASE DIGITS "-") != strlen(prop->name))
+			FAIL(c, dti, node, "aliases property name must include only lowercase and '-'");
+	}
+}
+WARNING(alias_paths, check_alias_paths, NULL);
 
 static void fixup_addr_size_cells(struct check *c, struct dt_info *dti,
 				  struct node *node)
@@ -622,21 +699,21 @@
 		return; /* No "reg", that's fine */
 
 	if (!node->parent) {
-		FAIL(c, dti, "Root node has a \"reg\" property");
+		FAIL(c, dti, node, "Root node has a \"reg\" property");
 		return;
 	}
 
 	if (prop->val.len == 0)
-		FAIL(c, dti, "\"reg\" property in %s is empty", node->fullpath);
+		FAIL_PROP(c, dti, node, prop, "property is empty");
 
 	addr_cells = node_addr_cells(node->parent);
 	size_cells = node_size_cells(node->parent);
 	entrylen = (addr_cells + size_cells) * sizeof(cell_t);
 
 	if (!entrylen || (prop->val.len % entrylen) != 0)
-		FAIL(c, dti, "\"reg\" property in %s has invalid length (%d bytes) "
-		     "(#address-cells == %d, #size-cells == %d)",
-		     node->fullpath, prop->val.len, addr_cells, size_cells);
+		FAIL_PROP(c, dti, node, prop, "property has invalid length (%d bytes) "
+			  "(#address-cells == %d, #size-cells == %d)",
+			  prop->val.len, addr_cells, size_cells);
 }
 WARNING(reg_format, check_reg_format, NULL, &addr_size_cells);
 
@@ -651,7 +728,7 @@
 		return;
 
 	if (!node->parent) {
-		FAIL(c, dti, "Root node has a \"ranges\" property");
+		FAIL_PROP(c, dti, node, prop, "Root node has a \"ranges\" property");
 		return;
 	}
 
@@ -663,20 +740,20 @@
 
 	if (prop->val.len == 0) {
 		if (p_addr_cells != c_addr_cells)
-			FAIL(c, dti, "%s has empty \"ranges\" property but its "
-			     "#address-cells (%d) differs from %s (%d)",
-			     node->fullpath, c_addr_cells, node->parent->fullpath,
-			     p_addr_cells);
+			FAIL_PROP(c, dti, node, prop, "empty \"ranges\" property but its "
+				  "#address-cells (%d) differs from %s (%d)",
+				  c_addr_cells, node->parent->fullpath,
+				  p_addr_cells);
 		if (p_size_cells != c_size_cells)
-			FAIL(c, dti, "%s has empty \"ranges\" property but its "
-			     "#size-cells (%d) differs from %s (%d)",
-			     node->fullpath, c_size_cells, node->parent->fullpath,
-			     p_size_cells);
+			FAIL_PROP(c, dti, node, prop, "empty \"ranges\" property but its "
+				  "#size-cells (%d) differs from %s (%d)",
+				  c_size_cells, node->parent->fullpath,
+				  p_size_cells);
 	} else if ((prop->val.len % entrylen) != 0) {
-		FAIL(c, dti, "\"ranges\" property in %s has invalid length (%d bytes) "
-		     "(parent #address-cells == %d, child #address-cells == %d, "
-		     "#size-cells == %d)", node->fullpath, prop->val.len,
-		     p_addr_cells, c_addr_cells, c_size_cells);
+		FAIL_PROP(c, dti, node, prop, "\"ranges\" property has invalid length (%d bytes) "
+			  "(parent #address-cells == %d, child #address-cells == %d, "
+			  "#size-cells == %d)", prop->val.len,
+			  p_addr_cells, c_addr_cells, c_size_cells);
 	}
 }
 WARNING(ranges_format, check_ranges_format, NULL, &addr_size_cells);
@@ -696,41 +773,33 @@
 
 	node->bus = &pci_bus;
 
-	if (!strneq(node->name, "pci", node->basenamelen) &&
-	    !strneq(node->name, "pcie", node->basenamelen))
-		FAIL(c, dti, "Node %s node name is not \"pci\" or \"pcie\"",
-			     node->fullpath);
+	if (!strprefixeq(node->name, node->basenamelen, "pci") &&
+	    !strprefixeq(node->name, node->basenamelen, "pcie"))
+		FAIL(c, dti, node, "node name is not \"pci\" or \"pcie\"");
 
 	prop = get_property(node, "ranges");
 	if (!prop)
-		FAIL(c, dti, "Node %s missing ranges for PCI bridge (or not a bridge)",
-			     node->fullpath);
+		FAIL(c, dti, node, "missing ranges for PCI bridge (or not a bridge)");
 
 	if (node_addr_cells(node) != 3)
-		FAIL(c, dti, "Node %s incorrect #address-cells for PCI bridge",
-			     node->fullpath);
+		FAIL(c, dti, node, "incorrect #address-cells for PCI bridge");
 	if (node_size_cells(node) != 2)
-		FAIL(c, dti, "Node %s incorrect #size-cells for PCI bridge",
-			     node->fullpath);
+		FAIL(c, dti, node, "incorrect #size-cells for PCI bridge");
 
 	prop = get_property(node, "bus-range");
 	if (!prop) {
-		FAIL(c, dti, "Node %s missing bus-range for PCI bridge",
-			     node->fullpath);
+		FAIL(c, dti, node, "missing bus-range for PCI bridge");
 		return;
 	}
 	if (prop->val.len != (sizeof(cell_t) * 2)) {
-		FAIL(c, dti, "Node %s bus-range must be 2 cells",
-			     node->fullpath);
+		FAIL_PROP(c, dti, node, prop, "value must be 2 cells");
 		return;
 	}
 	cells = (cell_t *)prop->val.val;
 	if (fdt32_to_cpu(cells[0]) > fdt32_to_cpu(cells[1]))
-		FAIL(c, dti, "Node %s bus-range 1st cell must be less than or equal to 2nd cell",
-			     node->fullpath);
+		FAIL_PROP(c, dti, node, prop, "1st cell must be less than or equal to 2nd cell");
 	if (fdt32_to_cpu(cells[1]) > 0xff)
-		FAIL(c, dti, "Node %s bus-range maximum bus number must be less than 256",
-			     node->fullpath);
+		FAIL_PROP(c, dti, node, prop, "maximum bus number must be less than 256");
 }
 WARNING(pci_bridge, check_pci_bridge, NULL,
 	&device_type_is_string, &addr_size_cells);
@@ -760,8 +829,8 @@
 		max_bus = fdt32_to_cpu(cells[0]);
 	}
 	if ((bus_num < min_bus) || (bus_num > max_bus))
-		FAIL(c, dti, "Node %s PCI bus number %d out of range, expected (%d - %d)",
-		     node->fullpath, bus_num, min_bus, max_bus);
+		FAIL_PROP(c, dti, node, prop, "PCI bus number %d out of range, expected (%d - %d)",
+			  bus_num, min_bus, max_bus);
 }
 WARNING(pci_device_bus_num, check_pci_device_bus_num, NULL, &reg_format, &pci_bridge);
 
@@ -778,25 +847,22 @@
 
 	prop = get_property(node, "reg");
 	if (!prop) {
-		FAIL(c, dti, "Node %s missing PCI reg property", node->fullpath);
+		FAIL(c, dti, node, "missing PCI reg property");
 		return;
 	}
 
 	cells = (cell_t *)prop->val.val;
 	if (cells[1] || cells[2])
-		FAIL(c, dti, "Node %s PCI reg config space address cells 2 and 3 must be 0",
-			     node->fullpath);
+		FAIL_PROP(c, dti, node, prop, "PCI reg config space address cells 2 and 3 must be 0");
 
 	reg = fdt32_to_cpu(cells[0]);
 	dev = (reg & 0xf800) >> 11;
 	func = (reg & 0x700) >> 8;
 
 	if (reg & 0xff000000)
-		FAIL(c, dti, "Node %s PCI reg address is not configuration space",
-			     node->fullpath);
+		FAIL_PROP(c, dti, node, prop, "PCI reg address is not configuration space");
 	if (reg & 0x000000ff)
-		FAIL(c, dti, "Node %s PCI reg config space address register number must be 0",
-			     node->fullpath);
+		FAIL_PROP(c, dti, node, prop, "PCI reg config space address register number must be 0");
 
 	if (func == 0) {
 		snprintf(unit_addr, sizeof(unit_addr), "%x", dev);
@@ -808,8 +874,8 @@
 	if (streq(unitname, unit_addr))
 		return;
 
-	FAIL(c, dti, "Node %s PCI unit address format error, expected \"%s\"",
-	     node->fullpath, unit_addr);
+	FAIL(c, dti, node, "PCI unit address format error, expected \"%s\"",
+	     unit_addr);
 }
 WARNING(pci_device_reg, check_pci_device_reg, NULL, &reg_format, &pci_bridge);
 
@@ -828,7 +894,7 @@
 
 	for (str = prop->val.val, end = str + prop->val.len; str < end;
 	     str += strnlen(str, end - str) + 1) {
-		if (strneq(str, compat, end - str))
+		if (strprefixeq(str, end - str, compat))
 			return true;
 	}
 	return false;
@@ -865,7 +931,7 @@
 
 	if (!cells) {
 		if (node->parent->parent && !(node->bus == &simple_bus))
-			FAIL(c, dti, "Node %s missing or empty reg/ranges property", node->fullpath);
+			FAIL(c, dti, node, "missing or empty reg/ranges property");
 		return;
 	}
 
@@ -875,8 +941,8 @@
 
 	snprintf(unit_addr, sizeof(unit_addr), "%"PRIx64, reg);
 	if (!streq(unitname, unit_addr))
-		FAIL(c, dti, "Node %s simple-bus unit address format error, expected \"%s\"",
-		     node->fullpath, unit_addr);
+		FAIL(c, dti, node, "simple-bus unit address format error, expected \"%s\"",
+		     unit_addr);
 }
 WARNING(simple_bus_reg, check_simple_bus_reg, NULL, &reg_format, &simple_bus_bridge);
 
@@ -892,14 +958,12 @@
 		return;
 
 	if (!strncmp(unitname, "0x", 2)) {
-		FAIL(c, dti, "Node %s unit name should not have leading \"0x\"",
-		    node->fullpath);
+		FAIL(c, dti, node, "unit name should not have leading \"0x\"");
 		/* skip over 0x for next test */
 		unitname += 2;
 	}
 	if (unitname[0] == '0' && isxdigit(unitname[1]))
-		FAIL(c, dti, "Node %s unit name should not have leading 0s",
-		    node->fullpath);
+		FAIL(c, dti, node, "unit name should not have leading 0s");
 }
 WARNING(unit_address_format, check_unit_address_format, NULL,
 	&node_name_format, &pci_bridge, &simple_bus_bridge);
@@ -922,16 +986,38 @@
 		return;
 
 	if (node->parent->addr_cells == -1)
-		FAIL(c, dti, "Relying on default #address-cells value for %s",
-		     node->fullpath);
+		FAIL(c, dti, node, "Relying on default #address-cells value");
 
 	if (node->parent->size_cells == -1)
-		FAIL(c, dti, "Relying on default #size-cells value for %s",
-		     node->fullpath);
+		FAIL(c, dti, node, "Relying on default #size-cells value");
 }
 WARNING(avoid_default_addr_size, check_avoid_default_addr_size, NULL,
 	&addr_size_cells);
 
+static void check_avoid_unnecessary_addr_size(struct check *c, struct dt_info *dti,
+					      struct node *node)
+{
+	struct property *prop;
+	struct node *child;
+	bool has_reg = false;
+
+	if (!node->parent || node->addr_cells < 0 || node->size_cells < 0)
+		return;
+
+	if (get_property(node, "ranges") || !node->children)
+		return;
+
+	for_each_child(node, child) {
+		prop = get_property(child, "reg");
+		if (prop)
+			has_reg = true;
+	}
+
+	if (!has_reg)
+		FAIL(c, dti, node, "unnecessary #address-cells/#size-cells without \"ranges\" or child \"reg\" property");
+}
+WARNING(avoid_unnecessary_addr_size, check_avoid_unnecessary_addr_size, NULL, &avoid_default_addr_size);
+
 static void check_obsolete_chosen_interrupt_controller(struct check *c,
 						       struct dt_info *dti,
 						       struct node *node)
@@ -950,12 +1036,61 @@
 
 	prop = get_property(chosen, "interrupt-controller");
 	if (prop)
-		FAIL(c, dti, "/chosen has obsolete \"interrupt-controller\" "
-		     "property");
+		FAIL_PROP(c, dti, node, prop,
+			  "/chosen has obsolete \"interrupt-controller\" property");
 }
 WARNING(obsolete_chosen_interrupt_controller,
 	check_obsolete_chosen_interrupt_controller, NULL);
 
+static void check_chosen_node_is_root(struct check *c, struct dt_info *dti,
+				      struct node *node)
+{
+	if (!streq(node->name, "chosen"))
+		return;
+
+	if (node->parent != dti->dt)
+		FAIL(c, dti, node, "chosen node must be at root node");
+}
+WARNING(chosen_node_is_root, check_chosen_node_is_root, NULL);
+
+static void check_chosen_node_bootargs(struct check *c, struct dt_info *dti,
+				       struct node *node)
+{
+	struct property *prop;
+
+	if (!streq(node->name, "chosen"))
+		return;
+
+	prop = get_property(node, "bootargs");
+	if (!prop)
+		return;
+
+	c->data = prop->name;
+	check_is_string(c, dti, node);
+}
+WARNING(chosen_node_bootargs, check_chosen_node_bootargs, NULL);
+
+static void check_chosen_node_stdout_path(struct check *c, struct dt_info *dti,
+					  struct node *node)
+{
+	struct property *prop;
+
+	if (!streq(node->name, "chosen"))
+		return;
+
+	prop = get_property(node, "stdout-path");
+	if (!prop) {
+		prop = get_property(node, "linux,stdout-path");
+		if (!prop)
+			return;
+		FAIL_PROP(c, dti, node, prop, "Use 'stdout-path' instead");
+	}
+
+	c->data = prop->name;
+	check_is_string(c, dti, node);
+}
+WARNING(chosen_node_stdout_path, check_chosen_node_stdout_path, NULL);
+
 struct provider {
 	const char *prop_name;
 	const char *cell_name;
@@ -972,8 +1107,9 @@
 	int cell, cellsize = 0;
 
 	if (prop->val.len % sizeof(cell_t)) {
-		FAIL(c, dti, "property '%s' size (%d) is invalid, expected multiple of %zu in node %s",
-		     prop->name, prop->val.len, sizeof(cell_t), node->fullpath);
+		FAIL_PROP(c, dti, node, prop,
+			  "property size (%d) is invalid, expected multiple of %zu",
+			  prop->val.len, sizeof(cell_t));
 		return;
 	}
 
@@ -988,6 +1124,10 @@
 		 * entries when each index position has a specific definition.
 		 */
 		if (phandle == 0 || phandle == -1) {
+			/* Give up if this is an overlay with external references */
+			if (dti->dtsflags & DTSF_PLUGIN)
+				break;
+
 			cellsize = 0;
 			continue;
 		}
@@ -1000,14 +1140,16 @@
 					break;
 			}
 			if (!m)
-				FAIL(c, dti, "Property '%s', cell %d is not a phandle reference in %s",
-				     prop->name, cell, node->fullpath);
+				FAIL_PROP(c, dti, node, prop,
+					  "cell %d is not a phandle reference",
+					  cell);
 		}
 
 		provider_node = get_node_by_phandle(root, phandle);
 		if (!provider_node) {
-			FAIL(c, dti, "Could not get phandle node for %s:%s(cell %d)",
-			     node->fullpath, prop->name, cell);
+			FAIL_PROP(c, dti, node, prop,
+				  "Could not get phandle node for (cell %d)",
+				  cell);
 			break;
 		}
 
@@ -1017,16 +1159,17 @@
 		} else if (provider->optional) {
 			cellsize = 0;
 		} else {
-			FAIL(c, dti, "Missing property '%s' in node %s or bad phandle (referred from %s:%s[%d])",
+			FAIL(c, dti, node, "Missing property '%s' in node %s or bad phandle (referred from %s[%d])",
 			     provider->cell_name,
 			     provider_node->fullpath,
-			     node->fullpath, prop->name, cell);
+			     prop->name, cell);
 			break;
 		}
 
 		if (prop->val.len < ((cell + cellsize + 1) * sizeof(cell_t))) {
-			FAIL(c, dti, "%s property size (%d) too small for cell size %d in %s",
-			     prop->name, prop->val.len, cellsize, node->fullpath);
+			FAIL_PROP(c, dti, node, prop,
+				  "property size (%d) too small for cell size %d",
+				  prop->val.len, cellsize);
 		}
 	}
 }
@@ -1062,7 +1205,7 @@
 WARNING_PROPERTY_PHANDLE_CELLS(power_domains, "power-domains", "#power-domain-cells");
 WARNING_PROPERTY_PHANDLE_CELLS(pwms, "pwms", "#pwm-cells");
 WARNING_PROPERTY_PHANDLE_CELLS(resets, "resets", "#reset-cells");
-WARNING_PROPERTY_PHANDLE_CELLS(sound_dais, "sound-dais", "#sound-dai-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(sound_dai, "sound-dai", "#sound-dai-cells");
 WARNING_PROPERTY_PHANDLE_CELLS(thermal_sensors, "thermal-sensors", "#thermal-sensor-cells");
 
 static bool prop_is_gpio(struct property *prop)
@@ -1128,8 +1271,8 @@
 		if (!streq(str, "gpio"))
 			continue;
 
-		FAIL(c, dti, "'[*-]gpio' is deprecated, use '[*-]gpios' instead for %s:%s",
-		     node->fullpath, prop->name);
+		FAIL_PROP(c, dti, node, prop,
+			  "'[*-]gpio' is deprecated, use '[*-]gpios' instead");
 	}
 
 }
@@ -1163,9 +1306,8 @@
 		return;
 
 	if (irq_prop->val.len % sizeof(cell_t))
-		FAIL(c, dti, "property '%s' size (%d) is invalid, expected multiple of %zu in node %s",
-		     irq_prop->name, irq_prop->val.len, sizeof(cell_t),
-		     node->fullpath);
+		FAIL_PROP(c, dti, node, irq_prop, "size (%d) is invalid, expected multiple of %zu",
+		     irq_prop->val.len, sizeof(cell_t));
 
 	while (parent && !prop) {
 		if (parent != node && node_is_interrupt_provider(parent)) {
@@ -1176,16 +1318,19 @@
 		prop = get_property(parent, "interrupt-parent");
 		if (prop) {
 			phandle = propval_cell(prop);
+			/* Give up if this is an overlay with external references */
+			if ((phandle == 0 || phandle == -1) &&
+			    (dti->dtsflags & DTSF_PLUGIN))
+					return;
+
 			irq_node = get_node_by_phandle(root, phandle);
 			if (!irq_node) {
-				FAIL(c, dti, "Bad interrupt-parent phandle for %s",
-				     node->fullpath);
+				FAIL_PROP(c, dti, parent, prop, "Bad phandle");
 				return;
 			}
 			if (!node_is_interrupt_provider(irq_node))
-				FAIL(c, dti,
-				     "Missing interrupt-controller or interrupt-map property in %s",
-				     irq_node->fullpath);
+				FAIL(c, dti, irq_node,
+				     "Missing interrupt-controller or interrupt-map property");
 
 			break;
 		}
@@ -1194,23 +1339,21 @@
 	}
 
 	if (!irq_node) {
-		FAIL(c, dti, "Missing interrupt-parent for %s", node->fullpath);
+		FAIL(c, dti, node, "Missing interrupt-parent");
 		return;
 	}
 
 	prop = get_property(irq_node, "#interrupt-cells");
 	if (!prop) {
-		FAIL(c, dti, "Missing #interrupt-cells in interrupt-parent %s",
-		     irq_node->fullpath);
+		FAIL(c, dti, irq_node, "Missing #interrupt-cells in interrupt-parent");
 		return;
 	}
 
 	irq_cells = propval_cell(prop);
 	if (irq_prop->val.len % (irq_cells * sizeof(cell_t))) {
-		FAIL(c, dti,
-		     "interrupts size is (%d), expected multiple of %d in %s",
-		     irq_prop->val.len, (int)(irq_cells * sizeof(cell_t)),
-		     node->fullpath);
+		FAIL_PROP(c, dti, node, prop,
+			  "size is (%d), expected multiple of %d",
+			  irq_prop->val.len, (int)(irq_cells * sizeof(cell_t)));
 	}
 }
 WARNING(interrupts_property, check_interrupts_property, &phandle_references);
@@ -1227,6 +1370,9 @@
 
 	&address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell,
 	&device_type_is_string, &model_is_string, &status_is_string,
+	&label_is_string,
+
+	&compatible_is_string_list, &names_is_string_list,
 
 	&property_name_chars_strict,
 	&node_name_chars_strict,
@@ -1244,7 +1390,9 @@
 	&simple_bus_reg,
 
 	&avoid_default_addr_size,
+	&avoid_unnecessary_addr_size,
 	&obsolete_chosen_interrupt_controller,
+	&chosen_node_is_root, &chosen_node_bootargs, &chosen_node_stdout_path,
 
 	&clocks_property,
 	&cooling_device_property,
@@ -1260,13 +1408,15 @@
 	&power_domains_property,
 	&pwms_property,
 	&resets_property,
-	&sound_dais_property,
+	&sound_dai_property,
 	&thermal_sensors_property,
 
 	&deprecated_gpio_property,
 	&gpios_property,
 	&interrupts_property,
 
+	&alias_paths,
+
 	&always_fail,
 };
 
diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped
deleted file mode 100644
index 011bb96..0000000
--- a/scripts/dtc/dtc-lexer.lex.c_shipped
+++ /dev/null
@@ -1,2259 +0,0 @@
-#line 2 "dtc-lexer.lex.c"
-
-#line 4 "dtc-lexer.lex.c"
-
-#define  YY_INT_ALIGNED short int
-
-/* A lexical scanner generated by flex */
-
-#define FLEX_SCANNER
-#define YY_FLEX_MAJOR_VERSION 2
-#define YY_FLEX_MINOR_VERSION 6
-#define YY_FLEX_SUBMINOR_VERSION 1
-#if YY_FLEX_SUBMINOR_VERSION > 0
-#define FLEX_BETA
-#endif
-
-/* First, we deal with  platform-specific or compiler-specific issues. */
-
-/* begin standard C headers. */
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-
-/* end standard C headers. */
-
-/* flex integer type definitions */
-
-#ifndef FLEXINT_H
-#define FLEXINT_H
-
-/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
-
-#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-
-/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
- * if you want the limit (max/min) macros for int types. 
- */
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS 1
-#endif
-
-#include <inttypes.h>
-typedef int8_t flex_int8_t;
-typedef uint8_t flex_uint8_t;
-typedef int16_t flex_int16_t;
-typedef uint16_t flex_uint16_t;
-typedef int32_t flex_int32_t;
-typedef uint32_t flex_uint32_t;
-#else
-typedef signed char flex_int8_t;
-typedef short int flex_int16_t;
-typedef int flex_int32_t;
-typedef unsigned char flex_uint8_t; 
-typedef unsigned short int flex_uint16_t;
-typedef unsigned int flex_uint32_t;
-
-/* Limits of integral types. */
-#ifndef INT8_MIN
-#define INT8_MIN               (-128)
-#endif
-#ifndef INT16_MIN
-#define INT16_MIN              (-32767-1)
-#endif
-#ifndef INT32_MIN
-#define INT32_MIN              (-2147483647-1)
-#endif
-#ifndef INT8_MAX
-#define INT8_MAX               (127)
-#endif
-#ifndef INT16_MAX
-#define INT16_MAX              (32767)
-#endif
-#ifndef INT32_MAX
-#define INT32_MAX              (2147483647)
-#endif
-#ifndef UINT8_MAX
-#define UINT8_MAX              (255U)
-#endif
-#ifndef UINT16_MAX
-#define UINT16_MAX             (65535U)
-#endif
-#ifndef UINT32_MAX
-#define UINT32_MAX             (4294967295U)
-#endif
-
-#endif /* ! C99 */
-
-#endif /* ! FLEXINT_H */
-
-/* TODO: this is always defined, so inline it */
-#define yyconst const
-
-#if defined(__GNUC__) && __GNUC__ >= 3
-#define yynoreturn __attribute__((__noreturn__))
-#else
-#define yynoreturn
-#endif
-
-/* Returned upon end-of-file. */
-#define YY_NULL 0
-
-/* Promotes a possibly negative, possibly signed char to an unsigned
- * integer for use as an array index.  If the signed char is negative,
- * we want to instead treat it as an 8-bit unsigned char, hence the
- * double cast.
- */
-#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
-
-/* Enter a start condition.  This macro really ought to take a parameter,
- * but we do it the disgusting crufty way forced on us by the ()-less
- * definition of BEGIN.
- */
-#define BEGIN (yy_start) = 1 + 2 *
-
-/* Translate the current start state into a value that can be later handed
- * to BEGIN to return to the state.  The YYSTATE alias is for lex
- * compatibility.
- */
-#define YY_START (((yy_start) - 1) / 2)
-#define YYSTATE YY_START
-
-/* Action number for EOF rule of a given start state. */
-#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
-
-/* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE yyrestart(yyin  )
-
-#define YY_END_OF_BUFFER_CHAR 0
-
-/* Size of default input buffer. */
-#ifndef YY_BUF_SIZE
-#ifdef __ia64__
-/* On IA-64, the buffer size is 16k, not 8k.
- * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
- * Ditto for the __ia64__ case accordingly.
- */
-#define YY_BUF_SIZE 32768
-#else
-#define YY_BUF_SIZE 16384
-#endif /* __ia64__ */
-#endif
-
-/* The state buf must be large enough to hold one state per character in the main buffer.
- */
-#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
-
-#ifndef YY_TYPEDEF_YY_BUFFER_STATE
-#define YY_TYPEDEF_YY_BUFFER_STATE
-typedef struct yy_buffer_state *YY_BUFFER_STATE;
-#endif
-
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef size_t yy_size_t;
-#endif
-
-extern int yyleng;
-
-extern FILE *yyin, *yyout;
-
-#define EOB_ACT_CONTINUE_SCAN 0
-#define EOB_ACT_END_OF_FILE 1
-#define EOB_ACT_LAST_MATCH 2
-
-    #define YY_LESS_LINENO(n)
-    #define YY_LINENO_REWIND_TO(ptr)
-    
-/* Return all but the first "n" matched characters back to the input stream. */
-#define yyless(n) \
-	do \
-		{ \
-		/* Undo effects of setting up yytext. */ \
-        int yyless_macro_arg = (n); \
-        YY_LESS_LINENO(yyless_macro_arg);\
-		*yy_cp = (yy_hold_char); \
-		YY_RESTORE_YY_MORE_OFFSET \
-		(yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
-		YY_DO_BEFORE_ACTION; /* set up yytext again */ \
-		} \
-	while ( 0 )
-
-#define unput(c) yyunput( c, (yytext_ptr)  )
-
-#ifndef YY_STRUCT_YY_BUFFER_STATE
-#define YY_STRUCT_YY_BUFFER_STATE
-struct yy_buffer_state
-	{
-	FILE *yy_input_file;
-
-	char *yy_ch_buf;		/* input buffer */
-	char *yy_buf_pos;		/* current position in input buffer */
-
-	/* Size of input buffer in bytes, not including room for EOB
-	 * characters.
-	 */
-	int yy_buf_size;
-
-	/* Number of characters read into yy_ch_buf, not including EOB
-	 * characters.
-	 */
-	int yy_n_chars;
-
-	/* Whether we "own" the buffer - i.e., we know we created it,
-	 * and can realloc() it to grow it, and should free() it to
-	 * delete it.
-	 */
-	int yy_is_our_buffer;
-
-	/* Whether this is an "interactive" input source; if so, and
-	 * if we're using stdio for input, then we want to use getc()
-	 * instead of fread(), to make sure we stop fetching input after
-	 * each newline.
-	 */
-	int yy_is_interactive;
-
-	/* Whether we're considered to be at the beginning of a line.
-	 * If so, '^' rules will be active on the next match, otherwise
-	 * not.
-	 */
-	int yy_at_bol;
-
-    int yy_bs_lineno; /**< The line count. */
-    int yy_bs_column; /**< The column count. */
-
-	/* Whether to try to fill the input buffer when we reach the
-	 * end of it.
-	 */
-	int yy_fill_buffer;
-
-	int yy_buffer_status;
-
-#define YY_BUFFER_NEW 0
-#define YY_BUFFER_NORMAL 1
-	/* When an EOF's been seen but there's still some text to process
-	 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
-	 * shouldn't try reading from the input source any more.  We might
-	 * still have a bunch of tokens to match, though, because of
-	 * possible backing-up.
-	 *
-	 * When we actually see the EOF, we change the status to "new"
-	 * (via yyrestart()), so that the user can continue scanning by
-	 * just pointing yyin at a new input file.
-	 */
-#define YY_BUFFER_EOF_PENDING 2
-
-	};
-#endif /* !YY_STRUCT_YY_BUFFER_STATE */
-
-/* Stack of input buffers. */
-static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
-static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
-static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */
-
-/* We provide macros for accessing buffer states in case in the
- * future we want to put the buffer states in a more general
- * "scanner state".
- *
- * Returns the top of the stack, or NULL.
- */
-#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
-                          ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
-                          : NULL)
-
-/* Same as previous macro, but useful when we know that the buffer stack is not
- * NULL or when we need an lvalue. For internal use only.
- */
-#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
-
-/* yy_hold_char holds the character lost when yytext is formed. */
-static char yy_hold_char;
-static int yy_n_chars;		/* number of characters read into yy_ch_buf */
-int yyleng;
-
-/* Points to current character in buffer. */
-static char *yy_c_buf_p = NULL;
-static int yy_init = 0;		/* whether we need to initialize */
-static int yy_start = 0;	/* start state number */
-
-/* Flag which is used to allow yywrap()'s to do buffer switches
- * instead of setting up a fresh yyin.  A bit of a hack ...
- */
-static int yy_did_buffer_switch_on_eof;
-
-void yyrestart (FILE *input_file  );
-void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer  );
-YY_BUFFER_STATE yy_create_buffer (FILE *file,int size  );
-void yy_delete_buffer (YY_BUFFER_STATE b  );
-void yy_flush_buffer (YY_BUFFER_STATE b  );
-void yypush_buffer_state (YY_BUFFER_STATE new_buffer  );
-void yypop_buffer_state (void );
-
-static void yyensure_buffer_stack (void );
-static void yy_load_buffer_state (void );
-static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file  );
-
-#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER )
-
-YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size  );
-YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str  );
-YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len  );
-
-void *yyalloc (yy_size_t  );
-void *yyrealloc (void *,yy_size_t  );
-void yyfree (void *  );
-
-#define yy_new_buffer yy_create_buffer
-
-#define yy_set_interactive(is_interactive) \
-	{ \
-	if ( ! YY_CURRENT_BUFFER ){ \
-        yyensure_buffer_stack (); \
-		YY_CURRENT_BUFFER_LVALUE =    \
-            yy_create_buffer(yyin,YY_BUF_SIZE ); \
-	} \
-	YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
-	}
-
-#define yy_set_bol(at_bol) \
-	{ \
-	if ( ! YY_CURRENT_BUFFER ){\
-        yyensure_buffer_stack (); \
-		YY_CURRENT_BUFFER_LVALUE =    \
-            yy_create_buffer(yyin,YY_BUF_SIZE ); \
-	} \
-	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
-	}
-
-#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
-
-/* Begin user sect3 */
-
-#define yywrap() (/*CONSTCOND*/1)
-#define YY_SKIP_YYWRAP
-
-typedef unsigned char YY_CHAR;
-
-FILE *yyin = NULL, *yyout = NULL;
-
-typedef int yy_state_type;
-
-extern int yylineno;
-
-int yylineno = 1;
-
-extern char *yytext;
-#ifdef yytext_ptr
-#undef yytext_ptr
-#endif
-#define yytext_ptr yytext
-
-static yy_state_type yy_get_previous_state (void );
-static yy_state_type yy_try_NUL_trans (yy_state_type current_state  );
-static int yy_get_next_buffer (void );
-static void yynoreturn yy_fatal_error (yyconst char* msg  );
-
-/* Done after the current pattern has been matched and before the
- * corresponding action - sets up yytext.
- */
-#define YY_DO_BEFORE_ACTION \
-	(yytext_ptr) = yy_bp; \
-	yyleng = (int) (yy_cp - yy_bp); \
-	(yy_hold_char) = *yy_cp; \
-	*yy_cp = '\0'; \
-	(yy_c_buf_p) = yy_cp;
-
-#define YY_NUM_RULES 31
-#define YY_END_OF_BUFFER 32
-/* This struct is not used in this scanner,
-   but its presence is necessary. */
-struct yy_trans_info
-	{
-	flex_int32_t yy_verify;
-	flex_int32_t yy_nxt;
-	};
-static yyconst flex_int16_t yy_accept[166] =
-    {   0,
-        0,    0,    0,    0,    0,    0,    0,    0,   32,   30,
-       19,   19,   30,   30,   30,   30,   30,   30,   30,   30,
-       30,   30,   30,   30,   30,   30,   16,   17,   17,   30,
-       17,   11,   11,   19,   27,    0,    3,    0,   28,   13,
-        0,    0,   12,    0,    0,    0,    0,    0,    0,    0,
-        0,   22,   24,   26,   25,   23,    0,   10,   29,    0,
-        0,    0,   15,   15,   17,   17,   17,   11,   11,   11,
-        0,   13,    0,   12,    0,    0,    0,   21,    0,    0,
-        0,    0,    0,    0,    0,    0,    0,   17,   11,   11,
-       11,    0,   14,   20,    0,    0,    0,    0,    0,    0,
-
-        0,    0,    0,    0,   17,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,   17,    7,    0,    0,    0,
-        0,    0,    0,    0,    2,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    4,   18,    0,    0,    5,    2,
-        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    1,    0,    0,    0,    0,    6,    9,    0,
-        0,    0,    0,    8,    0
-    } ;
-
-static yyconst YY_CHAR yy_ec[256] =
-    {   0,
-        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
-        4,    4,    4,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    2,    5,    6,    7,    1,    1,    8,    9,    1,
-        1,   10,   11,   11,   12,   11,   13,   14,   15,   16,
-       16,   16,   16,   16,   16,   16,   16,   17,    1,   18,
-       19,   20,   11,   11,   21,   21,   21,   21,   21,   21,
-       22,   22,   22,   22,   22,   23,   22,   22,   22,   22,
-       22,   22,   22,   22,   24,   22,   22,   25,   22,   22,
-        1,   26,   27,    1,   22,    1,   21,   28,   29,   30,
-
-       31,   21,   32,   22,   33,   22,   22,   34,   35,   36,
-       37,   38,   22,   39,   40,   41,   42,   43,   22,   25,
-       44,   22,   45,   46,   47,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1
-    } ;
-
-static yyconst YY_CHAR yy_meta[48] =
-    {   0,
-        1,    1,    1,    1,    1,    1,    2,    3,    1,    2,
-        2,    2,    4,    5,    5,    5,    6,    1,    1,    1,
-        7,    8,    8,    8,    8,    1,    1,    7,    7,    7,
-        7,    8,    8,    8,    8,    8,    8,    8,    8,    8,
-        8,    8,    8,    8,    3,    1,    4
-    } ;
-
-static yyconst flex_uint16_t yy_base[180] =
-    {   0,
-        0,  393,   35,  392,   66,  391,   38,  107,  397,  401,
-       55,  113,  377,  112,  111,  111,  114,   42,  376,  106,
-      377,  347,  126,  120,    0,  147,  401,    0,  124,    0,
-      137,  158,  170,  163,  401,  153,  401,  389,  401,    0,
-      378,  120,  401,  131,  380,  386,  355,  139,  351,  355,
-      351,  401,  401,  401,  401,  401,  367,  401,  401,  185,
-      350,  346,  401,  364,    0,  185,  347,  189,  356,  355,
-        0,    0,  330,  180,  366,  141,  372,  361,  332,  338,
-      331,  341,  334,  326,  205,  331,  337,  329,  401,  341,
-      167,  316,  401,  349,  348,  320,  328,  346,  180,  318,
-
-      324,  209,  324,  320,  322,  342,  338,  309,  306,  315,
-      305,  315,  312,  192,  342,  341,  401,  293,  306,  282,
-      268,  252,  255,  203,  285,  282,  272,  268,  252,  233,
-      232,  239,  208,  107,  401,  401,  238,  211,  401,  211,
-      212,  208,  228,  203,  215,  207,  233,  222,  212,  211,
-      203,  227,  401,  237,  225,  204,  185,  401,  401,  149,
-      128,   88,   42,  401,  401,  253,  259,  267,  271,  275,
-      281,  288,  292,  300,  308,  312,  318,  326,  334
-    } ;
-
-static yyconst flex_int16_t yy_def[180] =
-    {   0,
-      165,    1,    1,    3,  165,    5,    1,    1,  165,  165,
-      165,  165,  165,  166,  167,  168,  165,  165,  165,  165,
-      169,  165,  165,  165,  170,  169,  165,  171,  172,  171,
-      171,  165,  165,  165,  165,  166,  165,  166,  165,  173,
-      165,  168,  165,  168,  174,  175,  165,  165,  165,  165,
-      165,  165,  165,  165,  165,  165,  169,  165,  165,  165,
-      165,  165,  165,  169,  171,  172,  171,  165,  165,  165,
-      176,  173,  177,  168,  174,  174,  175,  165,  165,  165,
-      165,  165,  165,  165,  165,  165,  165,  171,  165,  165,
-      176,  177,  165,  165,  165,  165,  165,  165,  165,  165,
-
-      165,  165,  165,  165,  171,  165,  165,  165,  165,  165,
-      165,  165,  165,  178,  165,  171,  165,  165,  165,  165,
-      165,  165,  165,  178,  165,  178,  165,  165,  165,  165,
-      165,  165,  165,  165,  165,  165,  165,  165,  165,  165,
-      165,  165,  165,  165,  165,  165,  165,  179,  165,  165,
-      165,  179,  165,  179,  165,  165,  165,  165,  165,  165,
-      165,  165,  165,  165,    0,  165,  165,  165,  165,  165,
-      165,  165,  165,  165,  165,  165,  165,  165,  165
-    } ;
-
-static yyconst flex_uint16_t yy_nxt[449] =
-    {   0,
-       10,   11,   12,   11,   13,   14,   10,   15,   16,   10,
-       10,   10,   17,   10,   10,   10,   10,   18,   19,   20,
-       21,   21,   21,   21,   21,   10,   10,   21,   21,   21,
-       21,   21,   21,   21,   21,   21,   21,   21,   21,   21,
-       21,   21,   21,   21,   10,   22,   10,   24,   25,   25,
-       25,   32,   33,   33,  164,   26,   34,   34,   34,   52,
-       53,   27,   26,   26,   26,   26,   10,   11,   12,   11,
-       13,   14,   28,   15,   16,   28,   28,   28,   24,   28,
-       28,   28,   10,   18,   19,   20,   29,   29,   29,   29,
-       29,   30,   10,   29,   29,   29,   29,   29,   29,   29,
-
-       29,   29,   29,   29,   29,   29,   29,   29,   29,   29,
-       10,   22,   10,   23,   34,   34,   34,   37,   39,   43,
-       32,   33,   33,   45,   55,   56,   46,   60,   43,   45,
-       65,  163,   46,   65,   65,   65,   44,   38,   60,   74,
-       58,   47,  141,   48,  142,   44,   49,   47,   50,   48,
-       76,   51,   62,   94,   50,   41,   44,   51,   37,   61,
-       64,   64,   64,   58,   34,   34,   34,   64,  162,   80,
-       67,   68,   68,   68,   64,   64,   64,   64,   38,   81,
-       69,   70,   71,   68,   68,   68,   60,  161,   43,   69,
-       70,   65,   69,   70,   65,   65,   65,  125,   85,   85,
-
-       85,   58,   68,   68,   68,   44,  102,  110,  125,  133,
-      102,   69,   70,  111,  114,  160,  159,  126,   85,   85,
-       85,  140,  140,  140,  140,  140,  140,  153,  126,  147,
-      147,  147,  153,  148,  147,  147,  147,  158,  148,  165,
-      157,  156,  155,  151,  150,  149,  146,  154,  145,  144,
-      143,  139,  154,   36,   36,   36,   36,   36,   36,   36,
-       36,   40,  138,  137,  136,   40,   40,   42,   42,   42,
-       42,   42,   42,   42,   42,   57,   57,   57,   57,   63,
-      135,   63,   65,  134,  165,   65,  133,   65,   65,   66,
-      132,  131,   66,   66,   66,   66,   72,  130,   72,   72,
-
-       75,   75,   75,   75,   75,   75,   75,   75,   77,   77,
-       77,   77,   77,   77,   77,   77,   91,  129,   91,   92,
-      128,   92,   92,  127,   92,   92,  124,  124,  124,  124,
-      124,  124,  124,  124,  152,  152,  152,  152,  152,  152,
-      152,  152,   60,   60,  123,  122,  121,  120,  119,  118,
-      117,   45,  116,  111,  115,  113,  112,  109,  108,  107,
-       46,  106,   93,   89,  105,  104,  103,  101,  100,   99,
-       98,   97,   96,   95,   78,   76,   93,   90,   89,   88,
-       58,   87,   86,   58,   84,   83,   82,   79,   78,   76,
-       73,  165,   59,   58,   54,   35,  165,   31,   23,   23,
-
-        9,  165,  165,  165,  165,  165,  165,  165,  165,  165,
-      165,  165,  165,  165,  165,  165,  165,  165,  165,  165,
-      165,  165,  165,  165,  165,  165,  165,  165,  165,  165,
-      165,  165,  165,  165,  165,  165,  165,  165,  165,  165,
-      165,  165,  165,  165,  165,  165,  165,  165
-    } ;
-
-static yyconst flex_int16_t yy_chk[449] =
-    {   0,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    3,    3,    3,
-        3,    7,    7,    7,  163,    3,   11,   11,   11,   18,
-       18,    3,    3,    3,    3,    3,    5,    5,    5,    5,
-        5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
-        5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
-        5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
-
-        5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
-        5,    5,    5,    8,   12,   12,   12,   14,   15,   16,
-        8,    8,    8,   17,   20,   20,   17,   23,   42,   24,
-       29,  162,   24,   29,   29,   29,   16,   14,   31,   44,
-       29,   17,  134,   17,  134,   42,   17,   24,   17,   24,
-       76,   17,   24,   76,   24,   15,   44,   24,   36,   23,
-       26,   26,   26,   26,   34,   34,   34,   26,  161,   48,
-       31,   32,   32,   32,   26,   26,   26,   26,   36,   48,
-       32,   32,   32,   33,   33,   33,   60,  160,   74,   91,
-       91,   66,   33,   33,   66,   66,   66,  114,   60,   60,
-
-       60,   66,   68,   68,   68,   74,   85,   99,  124,  133,
-      102,   68,   68,   99,  102,  157,  156,  114,   85,   85,
-       85,  133,  133,  133,  140,  140,  140,  148,  124,  143,
-      143,  143,  152,  143,  147,  147,  147,  155,  147,  154,
-      151,  150,  149,  146,  145,  144,  142,  148,  141,  138,
-      137,  132,  152,  166,  166,  166,  166,  166,  166,  166,
-      166,  167,  131,  130,  129,  167,  167,  168,  168,  168,
-      168,  168,  168,  168,  168,  169,  169,  169,  169,  170,
-      128,  170,  171,  127,  126,  171,  125,  171,  171,  172,
-      123,  122,  172,  172,  172,  172,  173,  121,  173,  173,
-
-      174,  174,  174,  174,  174,  174,  174,  174,  175,  175,
-      175,  175,  175,  175,  175,  175,  176,  120,  176,  177,
-      119,  177,  177,  118,  177,  177,  178,  178,  178,  178,
-      178,  178,  178,  178,  179,  179,  179,  179,  179,  179,
-      179,  179,  116,  115,  113,  112,  111,  110,  109,  108,
-      107,  106,  105,  104,  103,  101,  100,   98,   97,   96,
-       95,   94,   92,   90,   88,   87,   86,   84,   83,   82,
-       81,   80,   79,   78,   77,   75,   73,   70,   69,   67,
-       64,   62,   61,   57,   51,   50,   49,   47,   46,   45,
-       41,   38,   22,   21,   19,   13,    9,    6,    4,    2,
-
-      165,  165,  165,  165,  165,  165,  165,  165,  165,  165,
-      165,  165,  165,  165,  165,  165,  165,  165,  165,  165,
-      165,  165,  165,  165,  165,  165,  165,  165,  165,  165,
-      165,  165,  165,  165,  165,  165,  165,  165,  165,  165,
-      165,  165,  165,  165,  165,  165,  165,  165
-    } ;
-
-static yy_state_type yy_last_accepting_state;
-static char *yy_last_accepting_cpos;
-
-extern int yy_flex_debug;
-int yy_flex_debug = 0;
-
-/* The intent behind this definition is that it'll catch
- * any uses of REJECT which flex missed.
- */
-#define REJECT reject_used_but_not_detected
-#define yymore() yymore_used_but_not_detected
-#define YY_MORE_ADJ 0
-#define YY_RESTORE_YY_MORE_OFFSET
-char *yytext;
-#line 1 "dtc-lexer.l"
-/*
- * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
- *
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
- *                                                                   USA
- */
-#define YY_NO_INPUT 1
-
-
-
-#line 37 "dtc-lexer.l"
-#include "dtc.h"
-#include "srcpos.h"
-#include "dtc-parser.tab.h"
-
-YYLTYPE yylloc;
-extern bool treesource_error;
-
-/* CAUTION: this will stop working if we ever use yyless() or yyunput() */
-#define	YY_USER_ACTION \
-	{ \
-		srcpos_update(&yylloc, yytext, yyleng); \
-	}
-
-/*#define LEXDEBUG	1*/
-
-#ifdef LEXDEBUG
-#define DPRINT(fmt, ...)	fprintf(stderr, fmt, ##__VA_ARGS__)
-#else
-#define DPRINT(fmt, ...)	do { } while (0)
-#endif
-
-static int dts_version = 1;
-
-#define BEGIN_DEFAULT()		DPRINT("<V1>\n"); \
-				BEGIN(V1); \
-
-static void push_input_file(const char *filename);
-static bool pop_input_file(void);
-static void PRINTF(1, 2) lexical_error(const char *fmt, ...);
-
-#line 661 "dtc-lexer.lex.c"
-
-#define INITIAL 0
-#define BYTESTRING 1
-#define PROPNODENAME 2
-#define V1 3
-
-#ifndef YY_NO_UNISTD_H
-/* Special case for "unistd.h", since it is non-ANSI. We include it way
- * down here because we want the user's section 1 to have been scanned first.
- * The user has a chance to override it with an option.
- */
-#include <unistd.h>
-#endif
-
-#ifndef YY_EXTRA_TYPE
-#define YY_EXTRA_TYPE void *
-#endif
-
-static int yy_init_globals (void );
-
-/* Accessor methods to globals.
-   These are made visible to non-reentrant scanners for convenience. */
-
-int yylex_destroy (void );
-
-int yyget_debug (void );
-
-void yyset_debug (int debug_flag  );
-
-YY_EXTRA_TYPE yyget_extra (void );
-
-void yyset_extra (YY_EXTRA_TYPE user_defined  );
-
-FILE *yyget_in (void );
-
-void yyset_in  (FILE * _in_str  );
-
-FILE *yyget_out (void );
-
-void yyset_out  (FILE * _out_str  );
-
-			int yyget_leng (void );
-
-char *yyget_text (void );
-
-int yyget_lineno (void );
-
-void yyset_lineno (int _line_number  );
-
-/* Macros after this point can all be overridden by user definitions in
- * section 1.
- */
-
-#ifndef YY_SKIP_YYWRAP
-#ifdef __cplusplus
-extern "C" int yywrap (void );
-#else
-extern int yywrap (void );
-#endif
-#endif
-
-#ifndef YY_NO_UNPUT
-    
-#endif
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char *,yyconst char *,int );
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * );
-#endif
-
-#ifndef YY_NO_INPUT
-
-#ifdef __cplusplus
-static int yyinput (void );
-#else
-static int input (void );
-#endif
-
-#endif
-
-/* Amount of stuff to slurp up with each read. */
-#ifndef YY_READ_BUF_SIZE
-#ifdef __ia64__
-/* On IA-64, the buffer size is 16k, not 8k */
-#define YY_READ_BUF_SIZE 16384
-#else
-#define YY_READ_BUF_SIZE 8192
-#endif /* __ia64__ */
-#endif
-
-/* Copy whatever the last rule matched to the standard output. */
-#ifndef ECHO
-/* This used to be an fputs(), but since the string might contain NUL's,
- * we now use fwrite().
- */
-#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0)
-#endif
-
-/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
- * is returned in "result".
- */
-#ifndef YY_INPUT
-#define YY_INPUT(buf,result,max_size) \
-	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
-		{ \
-		int c = '*'; \
-		size_t n; \
-		for ( n = 0; n < max_size && \
-			     (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
-			buf[n] = (char) c; \
-		if ( c == '\n' ) \
-			buf[n++] = (char) c; \
-		if ( c == EOF && ferror( yyin ) ) \
-			YY_FATAL_ERROR( "input in flex scanner failed" ); \
-		result = n; \
-		} \
-	else \
-		{ \
-		errno=0; \
-		while ( (result = (int) fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
-			{ \
-			if( errno != EINTR) \
-				{ \
-				YY_FATAL_ERROR( "input in flex scanner failed" ); \
-				break; \
-				} \
-			errno=0; \
-			clearerr(yyin); \
-			} \
-		}\
-\
-
-#endif
-
-/* No semi-colon after return; correct usage is to write "yyterminate();" -
- * we don't want an extra ';' after the "return" because that will cause
- * some compilers to complain about unreachable statements.
- */
-#ifndef yyterminate
-#define yyterminate() return YY_NULL
-#endif
-
-/* Number of entries by which start-condition stack grows. */
-#ifndef YY_START_STACK_INCR
-#define YY_START_STACK_INCR 25
-#endif
-
-/* Report a fatal error. */
-#ifndef YY_FATAL_ERROR
-#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
-#endif
-
-/* end tables serialization structures and prototypes */
-
-/* Default declaration of generated scanner - a define so the user can
- * easily add parameters.
- */
-#ifndef YY_DECL
-#define YY_DECL_IS_OURS 1
-
-extern int yylex (void);
-
-#define YY_DECL int yylex (void)
-#endif /* !YY_DECL */
-
-/* Code executed at the beginning of each rule, after yytext and yyleng
- * have been set up.
- */
-#ifndef YY_USER_ACTION
-#define YY_USER_ACTION
-#endif
-
-/* Code executed at the end of each rule. */
-#ifndef YY_BREAK
-#define YY_BREAK /*LINTED*/break;
-#endif
-
-#define YY_RULE_SETUP \
-	if ( yyleng > 0 ) \
-		YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \
-				(yytext[yyleng - 1] == '\n'); \
-	YY_USER_ACTION
-
-/** The main scanner function which does all the work.
- */
-YY_DECL
-{
-	yy_state_type yy_current_state;
-	char *yy_cp, *yy_bp;
-	int yy_act;
-    
-	if ( !(yy_init) )
-		{
-		(yy_init) = 1;
-
-#ifdef YY_USER_INIT
-		YY_USER_INIT;
-#endif
-
-		if ( ! (yy_start) )
-			(yy_start) = 1;	/* first start state */
-
-		if ( ! yyin )
-			yyin = stdin;
-
-		if ( ! yyout )
-			yyout = stdout;
-
-		if ( ! YY_CURRENT_BUFFER ) {
-			yyensure_buffer_stack ();
-			YY_CURRENT_BUFFER_LVALUE =
-				yy_create_buffer(yyin,YY_BUF_SIZE );
-		}
-
-		yy_load_buffer_state( );
-		}
-
-	{
-#line 69 "dtc-lexer.l"
-
-#line 885 "dtc-lexer.lex.c"
-
-	while ( /*CONSTCOND*/1 )		/* loops until end-of-file is reached */
-		{
-		yy_cp = (yy_c_buf_p);
-
-		/* Support of yytext. */
-		*yy_cp = (yy_hold_char);
-
-		/* yy_bp points to the position in yy_ch_buf of the start of
-		 * the current run.
-		 */
-		yy_bp = yy_cp;
-
-		yy_current_state = (yy_start);
-		yy_current_state += YY_AT_BOL();
-yy_match:
-		do
-			{
-			YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;
-			if ( yy_accept[yy_current_state] )
-				{
-				(yy_last_accepting_state) = yy_current_state;
-				(yy_last_accepting_cpos) = yy_cp;
-				}
-			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
-				{
-				yy_current_state = (int) yy_def[yy_current_state];
-				if ( yy_current_state >= 166 )
-					yy_c = yy_meta[(unsigned int) yy_c];
-				}
-			yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
-			++yy_cp;
-			}
-		while ( yy_current_state != 165 );
-		yy_cp = (yy_last_accepting_cpos);
-		yy_current_state = (yy_last_accepting_state);
-
-yy_find_action:
-		yy_act = yy_accept[yy_current_state];
-
-		YY_DO_BEFORE_ACTION;
-
-do_action:	/* This label is used only to access EOF actions. */
-
-		switch ( yy_act )
-	{ /* beginning of action switch */
-			case 0: /* must back up */
-			/* undo the effects of YY_DO_BEFORE_ACTION */
-			*yy_cp = (yy_hold_char);
-			yy_cp = (yy_last_accepting_cpos);
-			yy_current_state = (yy_last_accepting_state);
-			goto yy_find_action;
-
-case 1:
-/* rule 1 can match eol */
-YY_RULE_SETUP
-#line 70 "dtc-lexer.l"
-{
-			char *name = strchr(yytext, '\"') + 1;
-			yytext[yyleng-1] = '\0';
-			push_input_file(name);
-		}
-	YY_BREAK
-case 2:
-/* rule 2 can match eol */
-YY_RULE_SETUP
-#line 76 "dtc-lexer.l"
-{
-			char *line, *fnstart, *fnend;
-			struct data fn;
-			/* skip text before line # */
-			line = yytext;
-			while (!isdigit((unsigned char)*line))
-				line++;
-
-			/* regexp ensures that first and list "
-			 * in the whole yytext are those at
-			 * beginning and end of the filename string */
-			fnstart = memchr(yytext, '"', yyleng);
-			for (fnend = yytext + yyleng - 1;
-			     *fnend != '"'; fnend--)
-				;
-			assert(fnstart && fnend && (fnend > fnstart));
-
-			fn = data_copy_escape_string(fnstart + 1,
-						     fnend - fnstart - 1);
-
-			/* Don't allow nuls in filenames */
-			if (memchr(fn.val, '\0', fn.len - 1))
-				lexical_error("nul in line number directive");
-
-			/* -1 since #line is the number of the next line */
-			srcpos_set_line(xstrdup(fn.val), atoi(line) - 1);
-			data_free(fn);
-		}
-	YY_BREAK
-case YY_STATE_EOF(INITIAL):
-case YY_STATE_EOF(BYTESTRING):
-case YY_STATE_EOF(PROPNODENAME):
-case YY_STATE_EOF(V1):
-#line 105 "dtc-lexer.l"
-{
-			if (!pop_input_file()) {
-				yyterminate();
-			}
-		}
-	YY_BREAK
-case 3:
-/* rule 3 can match eol */
-YY_RULE_SETUP
-#line 111 "dtc-lexer.l"
-{
-			DPRINT("String: %s\n", yytext);
-			yylval.data = data_copy_escape_string(yytext+1,
-					yyleng-2);
-			return DT_STRING;
-		}
-	YY_BREAK
-case 4:
-YY_RULE_SETUP
-#line 118 "dtc-lexer.l"
-{
-			DPRINT("Keyword: /dts-v1/\n");
-			dts_version = 1;
-			BEGIN_DEFAULT();
-			return DT_V1;
-		}
-	YY_BREAK
-case 5:
-YY_RULE_SETUP
-#line 125 "dtc-lexer.l"
-{
-			DPRINT("Keyword: /plugin/\n");
-			return DT_PLUGIN;
-		}
-	YY_BREAK
-case 6:
-YY_RULE_SETUP
-#line 130 "dtc-lexer.l"
-{
-			DPRINT("Keyword: /memreserve/\n");
-			BEGIN_DEFAULT();
-			return DT_MEMRESERVE;
-		}
-	YY_BREAK
-case 7:
-YY_RULE_SETUP
-#line 136 "dtc-lexer.l"
-{
-			DPRINT("Keyword: /bits/\n");
-			BEGIN_DEFAULT();
-			return DT_BITS;
-		}
-	YY_BREAK
-case 8:
-YY_RULE_SETUP
-#line 142 "dtc-lexer.l"
-{
-			DPRINT("Keyword: /delete-property/\n");
-			DPRINT("<PROPNODENAME>\n");
-			BEGIN(PROPNODENAME);
-			return DT_DEL_PROP;
-		}
-	YY_BREAK
-case 9:
-YY_RULE_SETUP
-#line 149 "dtc-lexer.l"
-{
-			DPRINT("Keyword: /delete-node/\n");
-			DPRINT("<PROPNODENAME>\n");
-			BEGIN(PROPNODENAME);
-			return DT_DEL_NODE;
-		}
-	YY_BREAK
-case 10:
-YY_RULE_SETUP
-#line 156 "dtc-lexer.l"
-{
-			DPRINT("Label: %s\n", yytext);
-			yylval.labelref = xstrdup(yytext);
-			yylval.labelref[yyleng-1] = '\0';
-			return DT_LABEL;
-		}
-	YY_BREAK
-case 11:
-YY_RULE_SETUP
-#line 163 "dtc-lexer.l"
-{
-			char *e;
-			DPRINT("Integer Literal: '%s'\n", yytext);
-
-			errno = 0;
-			yylval.integer = strtoull(yytext, &e, 0);
-
-			if (*e && e[strspn(e, "UL")]) {
-				lexical_error("Bad integer literal '%s'",
-					      yytext);
-			}
-
-			if (errno == ERANGE)
-				lexical_error("Integer literal '%s' out of range",
-					      yytext);
-			else
-				/* ERANGE is the only strtoull error triggerable
-				 *  by strings matching the pattern */
-				assert(errno == 0);
-			return DT_LITERAL;
-		}
-	YY_BREAK
-case 12:
-/* rule 12 can match eol */
-YY_RULE_SETUP
-#line 185 "dtc-lexer.l"
-{
-			struct data d;
-			DPRINT("Character literal: %s\n", yytext);
-
-			d = data_copy_escape_string(yytext+1, yyleng-2);
-			if (d.len == 1) {
-				lexical_error("Empty character literal");
-				yylval.integer = 0;
-			} else {
-				yylval.integer = (unsigned char)d.val[0];
-
-				if (d.len > 2)
-					lexical_error("Character literal has %d"
-						      " characters instead of 1",
-						      d.len - 1);
-			}
-
-			data_free(d);
-			return DT_CHAR_LITERAL;
-		}
-	YY_BREAK
-case 13:
-YY_RULE_SETUP
-#line 206 "dtc-lexer.l"
-{	/* label reference */
-			DPRINT("Ref: %s\n", yytext+1);
-			yylval.labelref = xstrdup(yytext+1);
-			return DT_REF;
-		}
-	YY_BREAK
-case 14:
-YY_RULE_SETUP
-#line 212 "dtc-lexer.l"
-{	/* new-style path reference */
-			yytext[yyleng-1] = '\0';
-			DPRINT("Ref: %s\n", yytext+2);
-			yylval.labelref = xstrdup(yytext+2);
-			return DT_REF;
-		}
-	YY_BREAK
-case 15:
-YY_RULE_SETUP
-#line 219 "dtc-lexer.l"
-{
-			yylval.byte = strtol(yytext, NULL, 16);
-			DPRINT("Byte: %02x\n", (int)yylval.byte);
-			return DT_BYTE;
-		}
-	YY_BREAK
-case 16:
-YY_RULE_SETUP
-#line 225 "dtc-lexer.l"
-{
-			DPRINT("/BYTESTRING\n");
-			BEGIN_DEFAULT();
-			return ']';
-		}
-	YY_BREAK
-case 17:
-YY_RULE_SETUP
-#line 231 "dtc-lexer.l"
-{
-			DPRINT("PropNodeName: %s\n", yytext);
-			yylval.propnodename = xstrdup((yytext[0] == '\\') ?
-							yytext + 1 : yytext);
-			BEGIN_DEFAULT();
-			return DT_PROPNODENAME;
-		}
-	YY_BREAK
-case 18:
-YY_RULE_SETUP
-#line 239 "dtc-lexer.l"
-{
-			DPRINT("Binary Include\n");
-			return DT_INCBIN;
-		}
-	YY_BREAK
-case 19:
-/* rule 19 can match eol */
-YY_RULE_SETUP
-#line 244 "dtc-lexer.l"
-/* eat whitespace */
-	YY_BREAK
-case 20:
-/* rule 20 can match eol */
-YY_RULE_SETUP
-#line 245 "dtc-lexer.l"
-/* eat C-style comments */
-	YY_BREAK
-case 21:
-/* rule 21 can match eol */
-YY_RULE_SETUP
-#line 246 "dtc-lexer.l"
-/* eat C++-style comments */
-	YY_BREAK
-case 22:
-YY_RULE_SETUP
-#line 248 "dtc-lexer.l"
-{ return DT_LSHIFT; };
-	YY_BREAK
-case 23:
-YY_RULE_SETUP
-#line 249 "dtc-lexer.l"
-{ return DT_RSHIFT; };
-	YY_BREAK
-case 24:
-YY_RULE_SETUP
-#line 250 "dtc-lexer.l"
-{ return DT_LE; };
-	YY_BREAK
-case 25:
-YY_RULE_SETUP
-#line 251 "dtc-lexer.l"
-{ return DT_GE; };
-	YY_BREAK
-case 26:
-YY_RULE_SETUP
-#line 252 "dtc-lexer.l"
-{ return DT_EQ; };
-	YY_BREAK
-case 27:
-YY_RULE_SETUP
-#line 253 "dtc-lexer.l"
-{ return DT_NE; };
-	YY_BREAK
-case 28:
-YY_RULE_SETUP
-#line 254 "dtc-lexer.l"
-{ return DT_AND; };
-	YY_BREAK
-case 29:
-YY_RULE_SETUP
-#line 255 "dtc-lexer.l"
-{ return DT_OR; };
-	YY_BREAK
-case 30:
-YY_RULE_SETUP
-#line 257 "dtc-lexer.l"
-{
-			DPRINT("Char: %c (\\x%02x)\n", yytext[0],
-				(unsigned)yytext[0]);
-			if (yytext[0] == '[') {
-				DPRINT("<BYTESTRING>\n");
-				BEGIN(BYTESTRING);
-			}
-			if ((yytext[0] == '{')
-			    || (yytext[0] == ';')) {
-				DPRINT("<PROPNODENAME>\n");
-				BEGIN(PROPNODENAME);
-			}
-			return yytext[0];
-		}
-	YY_BREAK
-case 31:
-YY_RULE_SETUP
-#line 272 "dtc-lexer.l"
-ECHO;
-	YY_BREAK
-#line 1257 "dtc-lexer.lex.c"
-
-	case YY_END_OF_BUFFER:
-		{
-		/* Amount of text matched not including the EOB char. */
-		int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
-
-		/* Undo the effects of YY_DO_BEFORE_ACTION. */
-		*yy_cp = (yy_hold_char);
-		YY_RESTORE_YY_MORE_OFFSET
-
-		if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
-			{
-			/* We're scanning a new file or input source.  It's
-			 * possible that this happened because the user
-			 * just pointed yyin at a new source and called
-			 * yylex().  If so, then we have to assure
-			 * consistency between YY_CURRENT_BUFFER and our
-			 * globals.  Here is the right place to do so, because
-			 * this is the first action (other than possibly a
-			 * back-up) that will match for the new input source.
-			 */
-			(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
-			YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
-			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
-			}
-
-		/* Note that here we test for yy_c_buf_p "<=" to the position
-		 * of the first EOB in the buffer, since yy_c_buf_p will
-		 * already have been incremented past the NUL character
-		 * (since all states make transitions on EOB to the
-		 * end-of-buffer state).  Contrast this with the test
-		 * in input().
-		 */
-		if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
-			{ /* This was really a NUL. */
-			yy_state_type yy_next_state;
-
-			(yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
-
-			yy_current_state = yy_get_previous_state(  );
-
-			/* Okay, we're now positioned to make the NUL
-			 * transition.  We couldn't have
-			 * yy_get_previous_state() go ahead and do it
-			 * for us because it doesn't know how to deal
-			 * with the possibility of jamming (and we don't
-			 * want to build jamming into it because then it
-			 * will run more slowly).
-			 */
-
-			yy_next_state = yy_try_NUL_trans( yy_current_state );
-
-			yy_bp = (yytext_ptr) + YY_MORE_ADJ;
-
-			if ( yy_next_state )
-				{
-				/* Consume the NUL. */
-				yy_cp = ++(yy_c_buf_p);
-				yy_current_state = yy_next_state;
-				goto yy_match;
-				}
-
-			else
-				{
-				yy_cp = (yy_last_accepting_cpos);
-				yy_current_state = (yy_last_accepting_state);
-				goto yy_find_action;
-				}
-			}
-
-		else switch ( yy_get_next_buffer(  ) )
-			{
-			case EOB_ACT_END_OF_FILE:
-				{
-				(yy_did_buffer_switch_on_eof) = 0;
-
-				if ( yywrap( ) )
-					{
-					/* Note: because we've taken care in
-					 * yy_get_next_buffer() to have set up
-					 * yytext, we can now set up
-					 * yy_c_buf_p so that if some total
-					 * hoser (like flex itself) wants to
-					 * call the scanner after we return the
-					 * YY_NULL, it'll still work - another
-					 * YY_NULL will get returned.
-					 */
-					(yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
-
-					yy_act = YY_STATE_EOF(YY_START);
-					goto do_action;
-					}
-
-				else
-					{
-					if ( ! (yy_did_buffer_switch_on_eof) )
-						YY_NEW_FILE;
-					}
-				break;
-				}
-
-			case EOB_ACT_CONTINUE_SCAN:
-				(yy_c_buf_p) =
-					(yytext_ptr) + yy_amount_of_matched_text;
-
-				yy_current_state = yy_get_previous_state(  );
-
-				yy_cp = (yy_c_buf_p);
-				yy_bp = (yytext_ptr) + YY_MORE_ADJ;
-				goto yy_match;
-
-			case EOB_ACT_LAST_MATCH:
-				(yy_c_buf_p) =
-				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
-
-				yy_current_state = yy_get_previous_state(  );
-
-				yy_cp = (yy_c_buf_p);
-				yy_bp = (yytext_ptr) + YY_MORE_ADJ;
-				goto yy_find_action;
-			}
-		break;
-		}
-
-	default:
-		YY_FATAL_ERROR(
-			"fatal flex scanner internal error--no action found" );
-	} /* end of action switch */
-		} /* end of scanning one token */
-	} /* end of user's declarations */
-} /* end of yylex */
-
-/* yy_get_next_buffer - try to read in a new buffer
- *
- * Returns a code representing an action:
- *	EOB_ACT_LAST_MATCH -
- *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
- *	EOB_ACT_END_OF_FILE - end of file
- */
-static int yy_get_next_buffer (void)
-{
-    	char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
-	char *source = (yytext_ptr);
-	int number_to_move, i;
-	int ret_val;
-
-	if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
-		YY_FATAL_ERROR(
-		"fatal flex scanner internal error--end of buffer missed" );
-
-	if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
-		{ /* Don't try to fill the buffer, so this is an EOF. */
-		if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
-			{
-			/* We matched a single character, the EOB, so
-			 * treat this as a final EOF.
-			 */
-			return EOB_ACT_END_OF_FILE;
-			}
-
-		else
-			{
-			/* We matched some text prior to the EOB, first
-			 * process it.
-			 */
-			return EOB_ACT_LAST_MATCH;
-			}
-		}
-
-	/* Try to read more data. */
-
-	/* First move last chars to start of buffer. */
-	number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1);
-
-	for ( i = 0; i < number_to_move; ++i )
-		*(dest++) = *(source++);
-
-	if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
-		/* don't do the read, it's not guaranteed to return an EOF,
-		 * just force an EOF
-		 */
-		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
-
-	else
-		{
-			int num_to_read =
-			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
-
-		while ( num_to_read <= 0 )
-			{ /* Not enough room in the buffer - grow it. */
-
-			/* just a shorter name for the current buffer */
-			YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
-
-			int yy_c_buf_p_offset =
-				(int) ((yy_c_buf_p) - b->yy_ch_buf);
-
-			if ( b->yy_is_our_buffer )
-				{
-				int new_size = b->yy_buf_size * 2;
-
-				if ( new_size <= 0 )
-					b->yy_buf_size += b->yy_buf_size / 8;
-				else
-					b->yy_buf_size *= 2;
-
-				b->yy_ch_buf = (char *)
-					/* Include room in for 2 EOB chars. */
-					yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
-				}
-			else
-				/* Can't grow it, we don't own it. */
-				b->yy_ch_buf = NULL;
-
-			if ( ! b->yy_ch_buf )
-				YY_FATAL_ERROR(
-				"fatal error - scanner input buffer overflow" );
-
-			(yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
-
-			num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
-						number_to_move - 1;
-
-			}
-
-		if ( num_to_read > YY_READ_BUF_SIZE )
-			num_to_read = YY_READ_BUF_SIZE;
-
-		/* Read in more data. */
-		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
-			(yy_n_chars), num_to_read );
-
-		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
-		}
-
-	if ( (yy_n_chars) == 0 )
-		{
-		if ( number_to_move == YY_MORE_ADJ )
-			{
-			ret_val = EOB_ACT_END_OF_FILE;
-			yyrestart(yyin  );
-			}
-
-		else
-			{
-			ret_val = EOB_ACT_LAST_MATCH;
-			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
-				YY_BUFFER_EOF_PENDING;
-			}
-		}
-
-	else
-		ret_val = EOB_ACT_CONTINUE_SCAN;
-
-	if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
-		/* Extend the array by 50%, plus the number we really need. */
-		int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
-		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size  );
-		if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
-			YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
-	}
-
-	(yy_n_chars) += number_to_move;
-	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
-	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
-
-	(yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
-
-	return ret_val;
-}
-
-/* yy_get_previous_state - get the state just before the EOB char was reached */
-
-    static yy_state_type yy_get_previous_state (void)
-{
-	yy_state_type yy_current_state;
-	char *yy_cp;
-    
-	yy_current_state = (yy_start);
-	yy_current_state += YY_AT_BOL();
-
-	for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
-		{
-		YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
-		if ( yy_accept[yy_current_state] )
-			{
-			(yy_last_accepting_state) = yy_current_state;
-			(yy_last_accepting_cpos) = yy_cp;
-			}
-		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
-			{
-			yy_current_state = (int) yy_def[yy_current_state];
-			if ( yy_current_state >= 166 )
-				yy_c = yy_meta[(unsigned int) yy_c];
-			}
-		yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
-		}
-
-	return yy_current_state;
-}
-
-/* yy_try_NUL_trans - try to make a transition on the NUL character
- *
- * synopsis
- *	next_state = yy_try_NUL_trans( current_state );
- */
-    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )
-{
-	int yy_is_jam;
-    	char *yy_cp = (yy_c_buf_p);
-
-	YY_CHAR yy_c = 1;
-	if ( yy_accept[yy_current_state] )
-		{
-		(yy_last_accepting_state) = yy_current_state;
-		(yy_last_accepting_cpos) = yy_cp;
-		}
-	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
-		{
-		yy_current_state = (int) yy_def[yy_current_state];
-		if ( yy_current_state >= 166 )
-			yy_c = yy_meta[(unsigned int) yy_c];
-		}
-	yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
-	yy_is_jam = (yy_current_state == 165);
-
-		return yy_is_jam ? 0 : yy_current_state;
-}
-
-#ifndef YY_NO_UNPUT
-
-#endif
-
-#ifndef YY_NO_INPUT
-#ifdef __cplusplus
-    static int yyinput (void)
-#else
-    static int input  (void)
-#endif
-
-{
-	int c;
-    
-	*(yy_c_buf_p) = (yy_hold_char);
-
-	if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
-		{
-		/* yy_c_buf_p now points to the character we want to return.
-		 * If this occurs *before* the EOB characters, then it's a
-		 * valid NUL; if not, then we've hit the end of the buffer.
-		 */
-		if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
-			/* This was really a NUL. */
-			*(yy_c_buf_p) = '\0';
-
-		else
-			{ /* need more input */
-			int offset = (yy_c_buf_p) - (yytext_ptr);
-			++(yy_c_buf_p);
-
-			switch ( yy_get_next_buffer(  ) )
-				{
-				case EOB_ACT_LAST_MATCH:
-					/* This happens because yy_g_n_b()
-					 * sees that we've accumulated a
-					 * token and flags that we need to
-					 * try matching the token before
-					 * proceeding.  But for input(),
-					 * there's no matching to consider.
-					 * So convert the EOB_ACT_LAST_MATCH
-					 * to EOB_ACT_END_OF_FILE.
-					 */
-
-					/* Reset buffer status. */
-					yyrestart(yyin );
-
-					/*FALLTHROUGH*/
-
-				case EOB_ACT_END_OF_FILE:
-					{
-					if ( yywrap( ) )
-						return 0;
-
-					if ( ! (yy_did_buffer_switch_on_eof) )
-						YY_NEW_FILE;
-#ifdef __cplusplus
-					return yyinput();
-#else
-					return input();
-#endif
-					}
-
-				case EOB_ACT_CONTINUE_SCAN:
-					(yy_c_buf_p) = (yytext_ptr) + offset;
-					break;
-				}
-			}
-		}
-
-	c = *(unsigned char *) (yy_c_buf_p);	/* cast for 8-bit char's */
-	*(yy_c_buf_p) = '\0';	/* preserve yytext */
-	(yy_hold_char) = *++(yy_c_buf_p);
-
-	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n');
-
-	return c;
-}
-#endif	/* ifndef YY_NO_INPUT */
-
-/** Immediately switch to a different input stream.
- * @param input_file A readable stream.
- * 
- * @note This function does not reset the start condition to @c INITIAL .
- */
-    void yyrestart  (FILE * input_file )
-{
-    
-	if ( ! YY_CURRENT_BUFFER ){
-        yyensure_buffer_stack ();
-		YY_CURRENT_BUFFER_LVALUE =
-            yy_create_buffer(yyin,YY_BUF_SIZE );
-	}
-
-	yy_init_buffer(YY_CURRENT_BUFFER,input_file );
-	yy_load_buffer_state( );
-}
-
-/** Switch to a different input buffer.
- * @param new_buffer The new input buffer.
- * 
- */
-    void yy_switch_to_buffer  (YY_BUFFER_STATE  new_buffer )
-{
-    
-	/* TODO. We should be able to replace this entire function body
-	 * with
-	 *		yypop_buffer_state();
-	 *		yypush_buffer_state(new_buffer);
-     */
-	yyensure_buffer_stack ();
-	if ( YY_CURRENT_BUFFER == new_buffer )
-		return;
-
-	if ( YY_CURRENT_BUFFER )
-		{
-		/* Flush out information for old buffer. */
-		*(yy_c_buf_p) = (yy_hold_char);
-		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
-		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
-		}
-
-	YY_CURRENT_BUFFER_LVALUE = new_buffer;
-	yy_load_buffer_state( );
-
-	/* We don't actually know whether we did this switch during
-	 * EOF (yywrap()) processing, but the only time this flag
-	 * is looked at is after yywrap() is called, so it's safe
-	 * to go ahead and always set it.
-	 */
-	(yy_did_buffer_switch_on_eof) = 1;
-}
-
-static void yy_load_buffer_state  (void)
-{
-    	(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
-	(yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
-	yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
-	(yy_hold_char) = *(yy_c_buf_p);
-}
-
-/** Allocate and initialize an input buffer state.
- * @param file A readable stream.
- * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
- * 
- * @return the allocated buffer state.
- */
-    YY_BUFFER_STATE yy_create_buffer  (FILE * file, int  size )
-{
-	YY_BUFFER_STATE b;
-    
-	b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
-	if ( ! b )
-		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
-
-	b->yy_buf_size = (yy_size_t)size;
-
-	/* yy_ch_buf has to be 2 characters longer than the size given because
-	 * we need to put in 2 end-of-buffer characters.
-	 */
-	b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2  );
-	if ( ! b->yy_ch_buf )
-		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
-
-	b->yy_is_our_buffer = 1;
-
-	yy_init_buffer(b,file );
-
-	return b;
-}
-
-/** Destroy the buffer.
- * @param b a buffer created with yy_create_buffer()
- * 
- */
-    void yy_delete_buffer (YY_BUFFER_STATE  b )
-{
-    
-	if ( ! b )
-		return;
-
-	if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
-		YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
-
-	if ( b->yy_is_our_buffer )
-		yyfree((void *) b->yy_ch_buf  );
-
-	yyfree((void *) b  );
-}
-
-/* Initializes or reinitializes a buffer.
- * This function is sometimes called more than once on the same buffer,
- * such as during a yyrestart() or at EOF.
- */
-    static void yy_init_buffer  (YY_BUFFER_STATE  b, FILE * file )
-
-{
-	int oerrno = errno;
-    
-	yy_flush_buffer(b );
-
-	b->yy_input_file = file;
-	b->yy_fill_buffer = 1;
-
-    /* If b is the current buffer, then yy_init_buffer was _probably_
-     * called from yyrestart() or through yy_get_next_buffer.
-     * In that case, we don't want to reset the lineno or column.
-     */
-    if (b != YY_CURRENT_BUFFER){
-        b->yy_bs_lineno = 1;
-        b->yy_bs_column = 0;
-    }
-
-        b->yy_is_interactive = 0;
-    
-	errno = oerrno;
-}
-
-/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
- * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
- * 
- */
-    void yy_flush_buffer (YY_BUFFER_STATE  b )
-{
-    	if ( ! b )
-		return;
-
-	b->yy_n_chars = 0;
-
-	/* We always need two end-of-buffer characters.  The first causes
-	 * a transition to the end-of-buffer state.  The second causes
-	 * a jam in that state.
-	 */
-	b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
-	b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
-
-	b->yy_buf_pos = &b->yy_ch_buf[0];
-
-	b->yy_at_bol = 1;
-	b->yy_buffer_status = YY_BUFFER_NEW;
-
-	if ( b == YY_CURRENT_BUFFER )
-		yy_load_buffer_state( );
-}
-
-/** Pushes the new state onto the stack. The new state becomes
- *  the current state. This function will allocate the stack
- *  if necessary.
- *  @param new_buffer The new state.
- *  
- */
-void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
-{
-    	if (new_buffer == NULL)
-		return;
-
-	yyensure_buffer_stack();
-
-	/* This block is copied from yy_switch_to_buffer. */
-	if ( YY_CURRENT_BUFFER )
-		{
-		/* Flush out information for old buffer. */
-		*(yy_c_buf_p) = (yy_hold_char);
-		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
-		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
-		}
-
-	/* Only push if top exists. Otherwise, replace top. */
-	if (YY_CURRENT_BUFFER)
-		(yy_buffer_stack_top)++;
-	YY_CURRENT_BUFFER_LVALUE = new_buffer;
-
-	/* copied from yy_switch_to_buffer. */
-	yy_load_buffer_state( );
-	(yy_did_buffer_switch_on_eof) = 1;
-}
-
-/** Removes and deletes the top of the stack, if present.
- *  The next element becomes the new top.
- *  
- */
-void yypop_buffer_state (void)
-{
-    	if (!YY_CURRENT_BUFFER)
-		return;
-
-	yy_delete_buffer(YY_CURRENT_BUFFER );
-	YY_CURRENT_BUFFER_LVALUE = NULL;
-	if ((yy_buffer_stack_top) > 0)
-		--(yy_buffer_stack_top);
-
-	if (YY_CURRENT_BUFFER) {
-		yy_load_buffer_state( );
-		(yy_did_buffer_switch_on_eof) = 1;
-	}
-}
-
-/* Allocates the stack if it does not exist.
- *  Guarantees space for at least one push.
- */
-static void yyensure_buffer_stack (void)
-{
-	int num_to_alloc;
-    
-	if (!(yy_buffer_stack)) {
-
-		/* First allocation is just for 2 elements, since we don't know if this
-		 * scanner will even need a stack. We use 2 instead of 1 to avoid an
-		 * immediate realloc on the next call.
-         */
-      num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
-		(yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
-								(num_to_alloc * sizeof(struct yy_buffer_state*)
-								);
-		if ( ! (yy_buffer_stack) )
-			YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
-
-		memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-
-		(yy_buffer_stack_max) = num_to_alloc;
-		(yy_buffer_stack_top) = 0;
-		return;
-	}
-
-	if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
-
-		/* Increase the buffer to prepare for a possible push. */
-		yy_size_t grow_size = 8 /* arbitrary grow size */;
-
-		num_to_alloc = (yy_buffer_stack_max) + grow_size;
-		(yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
-								((yy_buffer_stack),
-								num_to_alloc * sizeof(struct yy_buffer_state*)
-								);
-		if ( ! (yy_buffer_stack) )
-			YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
-
-		/* zero only the new slots.*/
-		memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
-		(yy_buffer_stack_max) = num_to_alloc;
-	}
-}
-
-/** Setup the input buffer state to scan directly from a user-specified character buffer.
- * @param base the character buffer
- * @param size the size in bytes of the character buffer
- * 
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
-{
-	YY_BUFFER_STATE b;
-    
-	if ( size < 2 ||
-	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
-	     base[size-1] != YY_END_OF_BUFFER_CHAR )
-		/* They forgot to leave room for the EOB's. */
-		return NULL;
-
-	b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
-	if ( ! b )
-		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
-
-	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
-	b->yy_buf_pos = b->yy_ch_buf = base;
-	b->yy_is_our_buffer = 0;
-	b->yy_input_file = NULL;
-	b->yy_n_chars = b->yy_buf_size;
-	b->yy_is_interactive = 0;
-	b->yy_at_bol = 1;
-	b->yy_fill_buffer = 0;
-	b->yy_buffer_status = YY_BUFFER_NEW;
-
-	yy_switch_to_buffer(b  );
-
-	return b;
-}
-
-/** Setup the input buffer state to scan a string. The next call to yylex() will
- * scan from a @e copy of @a str.
- * @param yystr a NUL-terminated string to scan
- * 
- * @return the newly allocated buffer state object.
- * @note If you want to scan bytes that may contain NUL values, then use
- *       yy_scan_bytes() instead.
- */
-YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
-{
-    
-	return yy_scan_bytes(yystr,(int) strlen(yystr) );
-}
-
-/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
- * scan from a @e copy of @a bytes.
- * @param yybytes the byte buffer to scan
- * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
- * 
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
-{
-	YY_BUFFER_STATE b;
-	char *buf;
-	yy_size_t n;
-	int i;
-    
-	/* Get memory for full buffer, including space for trailing EOB's. */
-	n = (yy_size_t) (_yybytes_len + 2);
-	buf = (char *) yyalloc(n  );
-	if ( ! buf )
-		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
-
-	for ( i = 0; i < _yybytes_len; ++i )
-		buf[i] = yybytes[i];
-
-	buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
-
-	b = yy_scan_buffer(buf,n );
-	if ( ! b )
-		YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
-
-	/* It's okay to grow etc. this buffer, and we should throw it
-	 * away when we're done.
-	 */
-	b->yy_is_our_buffer = 1;
-
-	return b;
-}
-
-#ifndef YY_EXIT_FAILURE
-#define YY_EXIT_FAILURE 2
-#endif
-
-static void yynoreturn yy_fatal_error (yyconst char* msg )
-{
-			(void) fprintf( stderr, "%s\n", msg );
-	exit( YY_EXIT_FAILURE );
-}
-
-/* Redefine yyless() so it works in section 3 code. */
-
-#undef yyless
-#define yyless(n) \
-	do \
-		{ \
-		/* Undo effects of setting up yytext. */ \
-        int yyless_macro_arg = (n); \
-        YY_LESS_LINENO(yyless_macro_arg);\
-		yytext[yyleng] = (yy_hold_char); \
-		(yy_c_buf_p) = yytext + yyless_macro_arg; \
-		(yy_hold_char) = *(yy_c_buf_p); \
-		*(yy_c_buf_p) = '\0'; \
-		yyleng = yyless_macro_arg; \
-		} \
-	while ( 0 )
-
-/* Accessor  methods (get/set functions) to struct members. */
-
-/** Get the current line number.
- * 
- */
-int yyget_lineno  (void)
-{
-    
-    return yylineno;
-}
-
-/** Get the input stream.
- * 
- */
-FILE *yyget_in  (void)
-{
-        return yyin;
-}
-
-/** Get the output stream.
- * 
- */
-FILE *yyget_out  (void)
-{
-        return yyout;
-}
-
-/** Get the length of the current token.
- * 
- */
-int yyget_leng  (void)
-{
-        return yyleng;
-}
-
-/** Get the current token.
- * 
- */
-
-char *yyget_text  (void)
-{
-        return yytext;
-}
-
-/** Set the current line number.
- * @param _line_number line number
- * 
- */
-void yyset_lineno (int  _line_number )
-{
-    
-    yylineno = _line_number;
-}
-
-/** Set the input stream. This does not discard the current
- * input buffer.
- * @param _in_str A readable stream.
- * 
- * @see yy_switch_to_buffer
- */
-void yyset_in (FILE *  _in_str )
-{
-        yyin = _in_str ;
-}
-
-void yyset_out (FILE *  _out_str )
-{
-        yyout = _out_str ;
-}
-
-int yyget_debug  (void)
-{
-        return yy_flex_debug;
-}
-
-void yyset_debug (int  _bdebug )
-{
-        yy_flex_debug = _bdebug ;
-}
-
-static int yy_init_globals (void)
-{
-        /* Initialization is the same as for the non-reentrant scanner.
-     * This function is called from yylex_destroy(), so don't allocate here.
-     */
-
-    (yy_buffer_stack) = NULL;
-    (yy_buffer_stack_top) = 0;
-    (yy_buffer_stack_max) = 0;
-    (yy_c_buf_p) = NULL;
-    (yy_init) = 0;
-    (yy_start) = 0;
-
-/* Defined in main.c */
-#ifdef YY_STDINIT
-    yyin = stdin;
-    yyout = stdout;
-#else
-    yyin = NULL;
-    yyout = NULL;
-#endif
-
-    /* For future reference: Set errno on error, since we are called by
-     * yylex_init()
-     */
-    return 0;
-}
-
-/* yylex_destroy is for both reentrant and non-reentrant scanners. */
-int yylex_destroy  (void)
-{
-    
-    /* Pop the buffer stack, destroying each element. */
-	while(YY_CURRENT_BUFFER){
-		yy_delete_buffer(YY_CURRENT_BUFFER  );
-		YY_CURRENT_BUFFER_LVALUE = NULL;
-		yypop_buffer_state();
-	}
-
-	/* Destroy the stack itself. */
-	yyfree((yy_buffer_stack) );
-	(yy_buffer_stack) = NULL;
-
-    /* Reset the globals. This is important in a non-reentrant scanner so the next time
-     * yylex() is called, initialization will occur. */
-    yy_init_globals( );
-
-    return 0;
-}
-
-/*
- * Internal utility routines.
- */
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
-{
-		
-	int i;
-	for ( i = 0; i < n; ++i )
-		s1[i] = s2[i];
-}
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * s )
-{
-	int n;
-	for ( n = 0; s[n]; ++n )
-		;
-
-	return n;
-}
-#endif
-
-void *yyalloc (yy_size_t  size )
-{
-			return malloc(size);
-}
-
-void *yyrealloc  (void * ptr, yy_size_t  size )
-{
-		
-	/* The cast to (char *) in the following accommodates both
-	 * implementations that use char* generic pointers, and those
-	 * that use void* generic pointers.  It works with the latter
-	 * because both ANSI C and C++ allow castless assignment from
-	 * any pointer type to void*, and deal with argument conversions
-	 * as though doing an assignment.
-	 */
-	return realloc(ptr, size);
-}
-
-void yyfree (void * ptr )
-{
-			free( (char *) ptr );	/* see yyrealloc() for (char *) cast */
-}
-
-#define YYTABLES_NAME "yytables"
-
-#line 272 "dtc-lexer.l"
-
-
-
-static void push_input_file(const char *filename)
-{
-	assert(filename);
-
-	srcfile_push(filename);
-
-	yyin = current_srcfile->f;
-
-	yypush_buffer_state(yy_create_buffer(yyin,YY_BUF_SIZE));
-}
-
-
-static bool pop_input_file(void)
-{
-	if (srcfile_pop() == 0)
-		return false;
-
-	yypop_buffer_state();
-	yyin = current_srcfile->f;
-
-	return true;
-}
-
-static void lexical_error(const char *fmt, ...)
-{
-	va_list ap;
-
-	va_start(ap, fmt);
-	srcpos_verror(&yylloc, "Lexical error", fmt, ap);
-	va_end(ap);
-
-	treesource_error = true;
-}
-
diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped
deleted file mode 100644
index aea514f..0000000
--- a/scripts/dtc/dtc-parser.tab.c_shipped
+++ /dev/null
@@ -1,2321 +0,0 @@
-/* A Bison parser, made by GNU Bison 3.0.4.  */
-
-/* Bison implementation for Yacc-like parsers in C
-
-   Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
-
-   This program is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
-
-/* As a special exception, you may create a larger work that contains
-   part or all of the Bison parser skeleton and distribute that work
-   under terms of your choice, so long as that work isn't itself a
-   parser generator using the skeleton or a modified version thereof
-   as a parser skeleton.  Alternatively, if you modify or redistribute
-   the parser skeleton itself, you may (at your option) remove this
-   special exception, which will cause the skeleton and the resulting
-   Bison output files to be licensed under the GNU General Public
-   License without this special exception.
-
-   This special exception was added by the Free Software Foundation in
-   version 2.2 of Bison.  */
-
-/* C LALR(1) parser skeleton written by Richard Stallman, by
-   simplifying the original so-called "semantic" parser.  */
-
-/* All symbols defined below should begin with yy or YY, to avoid
-   infringing on user name space.  This should be done even for local
-   variables, as they might otherwise be expanded by user macros.
-   There are some unavoidable exceptions within include files to
-   define necessary library symbols; they are noted "INFRINGES ON
-   USER NAME SPACE" below.  */
-
-/* Identify Bison output.  */
-#define YYBISON 1
-
-/* Bison version.  */
-#define YYBISON_VERSION "3.0.4"
-
-/* Skeleton name.  */
-#define YYSKELETON_NAME "yacc.c"
-
-/* Pure parsers.  */
-#define YYPURE 0
-
-/* Push parsers.  */
-#define YYPUSH 0
-
-/* Pull parsers.  */
-#define YYPULL 1
-
-
-
-
-/* Copy the first part of user declarations.  */
-#line 20 "dtc-parser.y" /* yacc.c:339  */
-
-#include <stdio.h>
-#include <inttypes.h>
-
-#include "dtc.h"
-#include "srcpos.h"
-
-extern int yylex(void);
-extern void yyerror(char const *s);
-#define ERROR(loc, ...) \
-	do { \
-		srcpos_error((loc), "Error", __VA_ARGS__); \
-		treesource_error = true; \
-	} while (0)
-
-extern struct dt_info *parser_output;
-extern bool treesource_error;
-
-#line 85 "dtc-parser.tab.c" /* yacc.c:339  */
-
-# ifndef YY_NULLPTR
-#  if defined __cplusplus && 201103L <= __cplusplus
-#   define YY_NULLPTR nullptr
-#  else
-#   define YY_NULLPTR 0
-#  endif
-# endif
-
-/* Enabling verbose error messages.  */
-#ifdef YYERROR_VERBOSE
-# undef YYERROR_VERBOSE
-# define YYERROR_VERBOSE 1
-#else
-# define YYERROR_VERBOSE 0
-#endif
-
-/* In a future release of Bison, this section will be replaced
-   by #include "dtc-parser.tab.h".  */
-#ifndef YY_YY_DTC_PARSER_TAB_H_INCLUDED
-# define YY_YY_DTC_PARSER_TAB_H_INCLUDED
-/* Debug traces.  */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
-#if YYDEBUG
-extern int yydebug;
-#endif
-
-/* Token type.  */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
-  enum yytokentype
-  {
-    DT_V1 = 258,
-    DT_PLUGIN = 259,
-    DT_MEMRESERVE = 260,
-    DT_LSHIFT = 261,
-    DT_RSHIFT = 262,
-    DT_LE = 263,
-    DT_GE = 264,
-    DT_EQ = 265,
-    DT_NE = 266,
-    DT_AND = 267,
-    DT_OR = 268,
-    DT_BITS = 269,
-    DT_DEL_PROP = 270,
-    DT_DEL_NODE = 271,
-    DT_PROPNODENAME = 272,
-    DT_LITERAL = 273,
-    DT_CHAR_LITERAL = 274,
-    DT_BYTE = 275,
-    DT_STRING = 276,
-    DT_LABEL = 277,
-    DT_REF = 278,
-    DT_INCBIN = 279
-  };
-#endif
-
-/* Value type.  */
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-
-union YYSTYPE
-{
-#line 39 "dtc-parser.y" /* yacc.c:355  */
-
-	char *propnodename;
-	char *labelref;
-	uint8_t byte;
-	struct data data;
-
-	struct {
-		struct data	data;
-		int		bits;
-	} array;
-
-	struct property *prop;
-	struct property *proplist;
-	struct node *node;
-	struct node *nodelist;
-	struct reserve_info *re;
-	uint64_t integer;
-	unsigned int flags;
-
-#line 170 "dtc-parser.tab.c" /* yacc.c:355  */
-};
-
-typedef union YYSTYPE YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
-# define YYSTYPE_IS_DECLARED 1
-#endif
-
-/* Location type.  */
-#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
-typedef struct YYLTYPE YYLTYPE;
-struct YYLTYPE
-{
-  int first_line;
-  int first_column;
-  int last_line;
-  int last_column;
-};
-# define YYLTYPE_IS_DECLARED 1
-# define YYLTYPE_IS_TRIVIAL 1
-#endif
-
-
-extern YYSTYPE yylval;
-extern YYLTYPE yylloc;
-int yyparse (void);
-
-#endif /* !YY_YY_DTC_PARSER_TAB_H_INCLUDED  */
-
-/* Copy the second part of user declarations.  */
-
-#line 201 "dtc-parser.tab.c" /* yacc.c:358  */
-
-#ifdef short
-# undef short
-#endif
-
-#ifdef YYTYPE_UINT8
-typedef YYTYPE_UINT8 yytype_uint8;
-#else
-typedef unsigned char yytype_uint8;
-#endif
-
-#ifdef YYTYPE_INT8
-typedef YYTYPE_INT8 yytype_int8;
-#else
-typedef signed char yytype_int8;
-#endif
-
-#ifdef YYTYPE_UINT16
-typedef YYTYPE_UINT16 yytype_uint16;
-#else
-typedef unsigned short int yytype_uint16;
-#endif
-
-#ifdef YYTYPE_INT16
-typedef YYTYPE_INT16 yytype_int16;
-#else
-typedef short int yytype_int16;
-#endif
-
-#ifndef YYSIZE_T
-# ifdef __SIZE_TYPE__
-#  define YYSIZE_T __SIZE_TYPE__
-# elif defined size_t
-#  define YYSIZE_T size_t
-# elif ! defined YYSIZE_T
-#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
-#  define YYSIZE_T size_t
-# else
-#  define YYSIZE_T unsigned int
-# endif
-#endif
-
-#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
-
-#ifndef YY_
-# if defined YYENABLE_NLS && YYENABLE_NLS
-#  if ENABLE_NLS
-#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
-#   define YY_(Msgid) dgettext ("bison-runtime", Msgid)
-#  endif
-# endif
-# ifndef YY_
-#  define YY_(Msgid) Msgid
-# endif
-#endif
-
-#ifndef YY_ATTRIBUTE
-# if (defined __GNUC__                                               \
-      && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__)))  \
-     || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
-#  define YY_ATTRIBUTE(Spec) __attribute__(Spec)
-# else
-#  define YY_ATTRIBUTE(Spec) /* empty */
-# endif
-#endif
-
-#ifndef YY_ATTRIBUTE_PURE
-# define YY_ATTRIBUTE_PURE   YY_ATTRIBUTE ((__pure__))
-#endif
-
-#ifndef YY_ATTRIBUTE_UNUSED
-# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
-#endif
-
-#if !defined _Noreturn \
-     && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
-# if defined _MSC_VER && 1200 <= _MSC_VER
-#  define _Noreturn __declspec (noreturn)
-# else
-#  define _Noreturn YY_ATTRIBUTE ((__noreturn__))
-# endif
-#endif
-
-/* Suppress unused-variable warnings by "using" E.  */
-#if ! defined lint || defined __GNUC__
-# define YYUSE(E) ((void) (E))
-#else
-# define YYUSE(E) /* empty */
-#endif
-
-#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
-/* Suppress an incorrect diagnostic about yylval being uninitialized.  */
-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
-    _Pragma ("GCC diagnostic push") \
-    _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
-    _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
-# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
-    _Pragma ("GCC diagnostic pop")
-#else
-# define YY_INITIAL_VALUE(Value) Value
-#endif
-#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
-# define YY_IGNORE_MAYBE_UNINITIALIZED_END
-#endif
-#ifndef YY_INITIAL_VALUE
-# define YY_INITIAL_VALUE(Value) /* Nothing. */
-#endif
-
-
-#if ! defined yyoverflow || YYERROR_VERBOSE
-
-/* The parser invokes alloca or malloc; define the necessary symbols.  */
-
-# ifdef YYSTACK_USE_ALLOCA
-#  if YYSTACK_USE_ALLOCA
-#   ifdef __GNUC__
-#    define YYSTACK_ALLOC __builtin_alloca
-#   elif defined __BUILTIN_VA_ARG_INCR
-#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
-#   elif defined _AIX
-#    define YYSTACK_ALLOC __alloca
-#   elif defined _MSC_VER
-#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
-#    define alloca _alloca
-#   else
-#    define YYSTACK_ALLOC alloca
-#    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
-#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-      /* Use EXIT_SUCCESS as a witness for stdlib.h.  */
-#     ifndef EXIT_SUCCESS
-#      define EXIT_SUCCESS 0
-#     endif
-#    endif
-#   endif
-#  endif
-# endif
-
-# ifdef YYSTACK_ALLOC
-   /* Pacify GCC's 'empty if-body' warning.  */
-#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
-#  ifndef YYSTACK_ALLOC_MAXIMUM
-    /* The OS might guarantee only one guard page at the bottom of the stack,
-       and a page size can be as small as 4096 bytes.  So we cannot safely
-       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
-       to allow for a few compiler-allocated temporary stack slots.  */
-#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
-#  endif
-# else
-#  define YYSTACK_ALLOC YYMALLOC
-#  define YYSTACK_FREE YYFREE
-#  ifndef YYSTACK_ALLOC_MAXIMUM
-#   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
-#  endif
-#  if (defined __cplusplus && ! defined EXIT_SUCCESS \
-       && ! ((defined YYMALLOC || defined malloc) \
-             && (defined YYFREE || defined free)))
-#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#   ifndef EXIT_SUCCESS
-#    define EXIT_SUCCESS 0
-#   endif
-#  endif
-#  ifndef YYMALLOC
-#   define YYMALLOC malloc
-#   if ! defined malloc && ! defined EXIT_SUCCESS
-void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
-#   endif
-#  endif
-#  ifndef YYFREE
-#   define YYFREE free
-#   if ! defined free && ! defined EXIT_SUCCESS
-void free (void *); /* INFRINGES ON USER NAME SPACE */
-#   endif
-#  endif
-# endif
-#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
-
-
-#if (! defined yyoverflow \
-     && (! defined __cplusplus \
-         || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
-             && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
-
-/* A type that is properly aligned for any stack member.  */
-union yyalloc
-{
-  yytype_int16 yyss_alloc;
-  YYSTYPE yyvs_alloc;
-  YYLTYPE yyls_alloc;
-};
-
-/* The size of the maximum gap between one aligned stack and the next.  */
-# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
-
-/* The size of an array large to enough to hold all stacks, each with
-   N elements.  */
-# define YYSTACK_BYTES(N) \
-     ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
-      + 2 * YYSTACK_GAP_MAXIMUM)
-
-# define YYCOPY_NEEDED 1
-
-/* Relocate STACK from its old location to the new one.  The
-   local variables YYSIZE and YYSTACKSIZE give the old and new number of
-   elements in the stack, and YYPTR gives the new location of the
-   stack.  Advance YYPTR to a properly aligned location for the next
-   stack.  */
-# define YYSTACK_RELOCATE(Stack_alloc, Stack)                           \
-    do                                                                  \
-      {                                                                 \
-        YYSIZE_T yynewbytes;                                            \
-        YYCOPY (&yyptr->Stack_alloc, Stack, yysize);                    \
-        Stack = &yyptr->Stack_alloc;                                    \
-        yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
-        yyptr += yynewbytes / sizeof (*yyptr);                          \
-      }                                                                 \
-    while (0)
-
-#endif
-
-#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
-/* Copy COUNT objects from SRC to DST.  The source and destination do
-   not overlap.  */
-# ifndef YYCOPY
-#  if defined __GNUC__ && 1 < __GNUC__
-#   define YYCOPY(Dst, Src, Count) \
-      __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
-#  else
-#   define YYCOPY(Dst, Src, Count)              \
-      do                                        \
-        {                                       \
-          YYSIZE_T yyi;                         \
-          for (yyi = 0; yyi < (Count); yyi++)   \
-            (Dst)[yyi] = (Src)[yyi];            \
-        }                                       \
-      while (0)
-#  endif
-# endif
-#endif /* !YYCOPY_NEEDED */
-
-/* YYFINAL -- State number of the termination state.  */
-#define YYFINAL  6
-/* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   138
-
-/* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  48
-/* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  30
-/* YYNRULES -- Number of rules.  */
-#define YYNRULES  85
-/* YYNSTATES -- Number of states.  */
-#define YYNSTATES  149
-
-/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
-   by yylex, with out-of-bounds checking.  */
-#define YYUNDEFTOK  2
-#define YYMAXUTOK   279
-
-#define YYTRANSLATE(YYX)                                                \
-  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
-
-/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
-   as returned by yylex, without out-of-bounds checking.  */
-static const yytype_uint8 yytranslate[] =
-{
-       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,    47,     2,     2,     2,    45,    41,     2,
-      33,    35,    44,    42,    34,    43,     2,    26,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,    38,    25,
-      36,    29,    30,    37,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,    31,     2,    32,    40,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,    27,    39,    28,    46,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
-       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
-      15,    16,    17,    18,    19,    20,    21,    22,    23,    24
-};
-
-#if YYDEBUG
-  /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
-static const yytype_uint16 yyrline[] =
-{
-       0,   109,   109,   117,   121,   128,   129,   139,   142,   149,
-     153,   161,   165,   170,   181,   200,   213,   220,   228,   231,
-     238,   242,   246,   250,   258,   262,   266,   270,   274,   290,
-     300,   308,   311,   315,   322,   338,   343,   362,   376,   383,
-     384,   385,   392,   396,   397,   401,   402,   406,   407,   411,
-     412,   416,   417,   421,   422,   426,   427,   428,   432,   433,
-     434,   435,   436,   440,   441,   442,   446,   447,   448,   452,
-     453,   462,   471,   475,   476,   477,   478,   483,   486,   490,
-     498,   501,   505,   513,   517,   521
-};
-#endif
-
-#if YYDEBUG || YYERROR_VERBOSE || 0
-/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
-   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
-static const char *const yytname[] =
-{
-  "$end", "error", "$undefined", "DT_V1", "DT_PLUGIN", "DT_MEMRESERVE",
-  "DT_LSHIFT", "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND",
-  "DT_OR", "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME",
-  "DT_LITERAL", "DT_CHAR_LITERAL", "DT_BYTE", "DT_STRING", "DT_LABEL",
-  "DT_REF", "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", "'>'", "'['",
-  "']'", "'('", "','", "')'", "'<'", "'?'", "':'", "'|'", "'^'", "'&'",
-  "'+'", "'-'", "'*'", "'%'", "'~'", "'!'", "$accept", "sourcefile",
-  "header", "headers", "memreserves", "memreserve", "devicetree",
-  "nodedef", "proplist", "propdef", "propdata", "propdataprefix",
-  "arrayprefix", "integer_prim", "integer_expr", "integer_trinary",
-  "integer_or", "integer_and", "integer_bitor", "integer_bitxor",
-  "integer_bitand", "integer_eq", "integer_rela", "integer_shift",
-  "integer_add", "integer_mul", "integer_unary", "bytestring", "subnodes",
-  "subnode", YY_NULLPTR
-};
-#endif
-
-# ifdef YYPRINT
-/* YYTOKNUM[NUM] -- (External) token number corresponding to the
-   (internal) symbol number NUM (which must be that of a token).  */
-static const yytype_uint16 yytoknum[] =
-{
-       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
-     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
-     275,   276,   277,   278,   279,    59,    47,   123,   125,    61,
-      62,    91,    93,    40,    44,    41,    60,    63,    58,   124,
-      94,    38,    43,    45,    42,    37,   126,    33
-};
-# endif
-
-#define YYPACT_NINF -44
-
-#define yypact_value_is_default(Yystate) \
-  (!!((Yystate) == (-44)))
-
-#define YYTABLE_NINF -1
-
-#define yytable_value_is_error(Yytable_value) \
-  0
-
-  /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
-     STATE-NUM.  */
-static const yytype_int8 yypact[] =
-{
-      14,    27,    61,    14,     8,    18,   -44,   -44,    37,     8,
-      40,     8,    64,   -44,   -44,   -12,    37,   -44,    50,    52,
-     -44,   -44,   -12,   -12,   -12,   -44,    51,   -44,    -4,    78,
-      53,    54,    55,    17,     2,    30,    38,    -3,   -44,    66,
-     -44,   -44,    70,    72,    50,    50,   -44,   -44,   -44,   -44,
-     -12,   -12,   -12,   -12,   -12,   -12,   -12,   -12,   -12,   -12,
-     -12,   -12,   -12,   -12,   -12,   -12,   -12,   -12,   -12,   -44,
-       3,    73,    50,   -44,   -44,    78,    59,    53,    54,    55,
-      17,     2,     2,    30,    30,    30,    30,    38,    38,    -3,
-      -3,   -44,   -44,   -44,    82,    83,    44,     3,   -44,    74,
-       3,   -44,   -44,   -12,    76,    79,   -44,   -44,   -44,   -44,
-     -44,    80,   -44,   -44,   -44,   -44,   -44,   -10,    36,   -44,
-     -44,   -44,   -44,    85,   -44,   -44,   -44,    75,   -44,   -44,
-      21,    71,    88,    -6,   -44,   -44,   -44,   -44,   -44,    11,
-     -44,   -44,   -44,    37,   -44,    77,    37,    81,   -44
-};
-
-  /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
-     Performed when YYTABLE does not specify something else to do.  Zero
-     means the default is an error.  */
-static const yytype_uint8 yydefact[] =
-{
-       0,     0,     0,     5,     7,     3,     1,     6,     0,     0,
-      16,     7,     0,    39,    40,     0,     0,    10,     0,     2,
-       8,     4,     0,     0,     0,    73,     0,    42,    43,    45,
-      47,    49,    51,    53,    55,    58,    65,    68,    72,     0,
-      18,    11,     0,     0,     0,     0,    74,    75,    76,    41,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     9,
-      80,     0,     0,    14,    12,    46,     0,    48,    50,    52,
-      54,    56,    57,    61,    62,    60,    59,    63,    64,    66,
-      67,    70,    69,    71,     0,     0,     0,     0,    19,     0,
-      80,    15,    13,     0,     0,     0,    21,    31,    83,    23,
-      85,     0,    82,    81,    44,    22,    84,     0,     0,    17,
-      30,    20,    32,     0,    24,    33,    27,     0,    77,    35,
-       0,     0,     0,     0,    38,    37,    25,    36,    34,     0,
-      78,    79,    26,     0,    29,     0,     0,     0,    28
-};
-
-  /* YYPGOTO[NTERM-NUM].  */
-static const yytype_int8 yypgoto[] =
-{
-     -44,   -44,   -44,   103,    99,   104,   -44,   -43,   -44,   -21,
-     -44,   -44,   -44,    -8,    63,     9,   -44,    65,    67,    68,
-      69,    62,    26,     4,    22,    23,   -19,   -44,    20,    28
-};
-
-  /* YYDEFGOTO[NTERM-NUM].  */
-static const yytype_int16 yydefgoto[] =
-{
-      -1,     2,     3,     4,    10,    11,    19,    41,    70,    98,
-     117,   118,   130,    25,    26,    27,    28,    29,    30,    31,
-      32,    33,    34,    35,    36,    37,    38,   133,    99,   100
-};
-
-  /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
-     positive, shift that token.  If negative, reduce the rule whose
-     number is the opposite.  If YYTABLE_NINF, syntax error.  */
-static const yytype_uint8 yytable[] =
-{
-      16,    73,    74,    46,    47,    48,    13,    14,    39,    50,
-      58,    59,   120,     8,   140,   121,   141,     1,    94,    95,
-      96,    15,    12,    66,   122,    97,   142,    56,    57,   102,
-       9,    22,    60,    51,    23,    24,    62,    63,    61,    13,
-      14,    67,    68,   134,   135,   143,   144,    91,    92,    93,
-     123,   136,     5,   108,    15,    13,    14,   124,   125,   126,
-     127,     6,    83,    84,    85,    86,    18,   128,    42,   106,
-      15,    40,   129,   107,    43,    44,   109,    40,    45,   112,
-      64,    65,    81,    82,    87,    88,    49,    89,    90,    21,
-      52,    69,    53,    71,    54,    72,    55,   103,   101,   104,
-     105,   115,   111,   131,   116,   119,     7,   138,   132,   139,
-      20,   146,   114,    17,    76,    75,   148,    80,     0,    77,
-     113,    78,   137,    79,     0,   110,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,   145,     0,     0,   147
-};
-
-static const yytype_int16 yycheck[] =
-{
-       8,    44,    45,    22,    23,    24,    18,    19,    16,    13,
-       8,     9,    22,     5,    20,    25,    22,     3,    15,    16,
-      17,    33,     4,    26,    34,    22,    32,    10,    11,    72,
-      22,    43,    30,    37,    46,    47,     6,     7,    36,    18,
-      19,    44,    45,    22,    23,    34,    35,    66,    67,    68,
-      14,    30,    25,    96,    33,    18,    19,    21,    22,    23,
-      24,     0,    58,    59,    60,    61,    26,    31,    16,    25,
-      33,    27,    36,    29,    22,    23,    97,    27,    26,   100,
-      42,    43,    56,    57,    62,    63,    35,    64,    65,    25,
-      12,    25,    39,    23,    40,    23,    41,    38,    25,    17,
-      17,    25,    28,    18,    25,    25,     3,    36,    33,    21,
-      11,    34,   103,     9,    51,    50,    35,    55,    -1,    52,
-     100,    53,   130,    54,    -1,    97,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,   143,    -1,    -1,   146
-};
-
-  /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
-     symbol of state STATE-NUM.  */
-static const yytype_uint8 yystos[] =
-{
-       0,     3,    49,    50,    51,    25,     0,    51,     5,    22,
-      52,    53,     4,    18,    19,    33,    61,    53,    26,    54,
-      52,    25,    43,    46,    47,    61,    62,    63,    64,    65,
-      66,    67,    68,    69,    70,    71,    72,    73,    74,    61,
-      27,    55,    16,    22,    23,    26,    74,    74,    74,    35,
-      13,    37,    12,    39,    40,    41,    10,    11,     8,     9,
-      30,    36,     6,     7,    42,    43,    26,    44,    45,    25,
-      56,    23,    23,    55,    55,    65,    62,    66,    67,    68,
-      69,    70,    70,    71,    71,    71,    71,    72,    72,    73,
-      73,    74,    74,    74,    15,    16,    17,    22,    57,    76,
-      77,    25,    55,    38,    17,    17,    25,    29,    55,    57,
-      77,    28,    57,    76,    63,    25,    25,    58,    59,    25,
-      22,    25,    34,    14,    21,    22,    23,    24,    31,    36,
-      60,    18,    33,    75,    22,    23,    30,    61,    36,    21,
-      20,    22,    32,    34,    35,    61,    34,    61,    35
-};
-
-  /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
-static const yytype_uint8 yyr1[] =
-{
-       0,    48,    49,    50,    50,    51,    51,    52,    52,    53,
-      53,    54,    54,    54,    54,    54,    54,    55,    56,    56,
-      57,    57,    57,    57,    58,    58,    58,    58,    58,    58,
-      58,    59,    59,    59,    60,    60,    60,    60,    60,    61,
-      61,    61,    62,    63,    63,    64,    64,    65,    65,    66,
-      66,    67,    67,    68,    68,    69,    69,    69,    70,    70,
-      70,    70,    70,    71,    71,    71,    72,    72,    72,    73,
-      73,    73,    73,    74,    74,    74,    74,    75,    75,    75,
-      76,    76,    76,    77,    77,    77
-};
-
-  /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.  */
-static const yytype_uint8 yyr2[] =
-{
-       0,     2,     3,     2,     4,     1,     2,     0,     2,     4,
-       2,     2,     3,     4,     3,     4,     0,     5,     0,     2,
-       4,     2,     3,     2,     2,     3,     4,     2,     9,     5,
-       2,     0,     2,     2,     3,     1,     2,     2,     2,     1,
-       1,     3,     1,     1,     5,     1,     3,     1,     3,     1,
-       3,     1,     3,     1,     3,     1,     3,     3,     1,     3,
-       3,     3,     3,     3,     3,     1,     3,     3,     1,     3,
-       3,     3,     1,     1,     2,     2,     2,     0,     2,     2,
-       0,     2,     2,     2,     3,     2
-};
-
-
-#define yyerrok         (yyerrstatus = 0)
-#define yyclearin       (yychar = YYEMPTY)
-#define YYEMPTY         (-2)
-#define YYEOF           0
-
-#define YYACCEPT        goto yyacceptlab
-#define YYABORT         goto yyabortlab
-#define YYERROR         goto yyerrorlab
-
-
-#define YYRECOVERING()  (!!yyerrstatus)
-
-#define YYBACKUP(Token, Value)                                  \
-do                                                              \
-  if (yychar == YYEMPTY)                                        \
-    {                                                           \
-      yychar = (Token);                                         \
-      yylval = (Value);                                         \
-      YYPOPSTACK (yylen);                                       \
-      yystate = *yyssp;                                         \
-      goto yybackup;                                            \
-    }                                                           \
-  else                                                          \
-    {                                                           \
-      yyerror (YY_("syntax error: cannot back up")); \
-      YYERROR;                                                  \
-    }                                                           \
-while (0)
-
-/* Error token number */
-#define YYTERROR        1
-#define YYERRCODE       256
-
-
-/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
-   If N is 0, then set CURRENT to the empty location which ends
-   the previous symbol: RHS[0] (always defined).  */
-
-#ifndef YYLLOC_DEFAULT
-# define YYLLOC_DEFAULT(Current, Rhs, N)                                \
-    do                                                                  \
-      if (N)                                                            \
-        {                                                               \
-          (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;        \
-          (Current).first_column = YYRHSLOC (Rhs, 1).first_column;      \
-          (Current).last_line    = YYRHSLOC (Rhs, N).last_line;         \
-          (Current).last_column  = YYRHSLOC (Rhs, N).last_column;       \
-        }                                                               \
-      else                                                              \
-        {                                                               \
-          (Current).first_line   = (Current).last_line   =              \
-            YYRHSLOC (Rhs, 0).last_line;                                \
-          (Current).first_column = (Current).last_column =              \
-            YYRHSLOC (Rhs, 0).last_column;                              \
-        }                                                               \
-    while (0)
-#endif
-
-#define YYRHSLOC(Rhs, K) ((Rhs)[K])
-
-
-/* Enable debugging if requested.  */
-#if YYDEBUG
-
-# ifndef YYFPRINTF
-#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
-#  define YYFPRINTF fprintf
-# endif
-
-# define YYDPRINTF(Args)                        \
-do {                                            \
-  if (yydebug)                                  \
-    YYFPRINTF Args;                             \
-} while (0)
-
-
-/* YY_LOCATION_PRINT -- Print the location on the stream.
-   This macro was not mandated originally: define only if we know
-   we won't break user code: when these are the locations we know.  */
-
-#ifndef YY_LOCATION_PRINT
-# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
-
-/* Print *YYLOCP on YYO.  Private, do not rely on its existence. */
-
-YY_ATTRIBUTE_UNUSED
-static unsigned
-yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp)
-{
-  unsigned res = 0;
-  int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0;
-  if (0 <= yylocp->first_line)
-    {
-      res += YYFPRINTF (yyo, "%d", yylocp->first_line);
-      if (0 <= yylocp->first_column)
-        res += YYFPRINTF (yyo, ".%d", yylocp->first_column);
-    }
-  if (0 <= yylocp->last_line)
-    {
-      if (yylocp->first_line < yylocp->last_line)
-        {
-          res += YYFPRINTF (yyo, "-%d", yylocp->last_line);
-          if (0 <= end_col)
-            res += YYFPRINTF (yyo, ".%d", end_col);
-        }
-      else if (0 <= end_col && yylocp->first_column < end_col)
-        res += YYFPRINTF (yyo, "-%d", end_col);
-    }
-  return res;
- }
-
-#  define YY_LOCATION_PRINT(File, Loc)          \
-  yy_location_print_ (File, &(Loc))
-
-# else
-#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-# endif
-#endif
-
-
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location)                    \
-do {                                                                      \
-  if (yydebug)                                                            \
-    {                                                                     \
-      YYFPRINTF (stderr, "%s ", Title);                                   \
-      yy_symbol_print (stderr,                                            \
-                  Type, Value, Location); \
-      YYFPRINTF (stderr, "\n");                                           \
-    }                                                                     \
-} while (0)
-
-
-/*----------------------------------------.
-| Print this symbol's value on YYOUTPUT.  |
-`----------------------------------------*/
-
-static void
-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp)
-{
-  FILE *yyo = yyoutput;
-  YYUSE (yyo);
-  YYUSE (yylocationp);
-  if (!yyvaluep)
-    return;
-# ifdef YYPRINT
-  if (yytype < YYNTOKENS)
-    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
-# endif
-  YYUSE (yytype);
-}
-
-
-/*--------------------------------.
-| Print this symbol on YYOUTPUT.  |
-`--------------------------------*/
-
-static void
-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp)
-{
-  YYFPRINTF (yyoutput, "%s %s (",
-             yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
-
-  YY_LOCATION_PRINT (yyoutput, *yylocationp);
-  YYFPRINTF (yyoutput, ": ");
-  yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp);
-  YYFPRINTF (yyoutput, ")");
-}
-
-/*------------------------------------------------------------------.
-| yy_stack_print -- Print the state stack from its BOTTOM up to its |
-| TOP (included).                                                   |
-`------------------------------------------------------------------*/
-
-static void
-yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
-{
-  YYFPRINTF (stderr, "Stack now");
-  for (; yybottom <= yytop; yybottom++)
-    {
-      int yybot = *yybottom;
-      YYFPRINTF (stderr, " %d", yybot);
-    }
-  YYFPRINTF (stderr, "\n");
-}
-
-# define YY_STACK_PRINT(Bottom, Top)                            \
-do {                                                            \
-  if (yydebug)                                                  \
-    yy_stack_print ((Bottom), (Top));                           \
-} while (0)
-
-
-/*------------------------------------------------.
-| Report that the YYRULE is going to be reduced.  |
-`------------------------------------------------*/
-
-static void
-yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule)
-{
-  unsigned long int yylno = yyrline[yyrule];
-  int yynrhs = yyr2[yyrule];
-  int yyi;
-  YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
-             yyrule - 1, yylno);
-  /* The symbols being reduced.  */
-  for (yyi = 0; yyi < yynrhs; yyi++)
-    {
-      YYFPRINTF (stderr, "   $%d = ", yyi + 1);
-      yy_symbol_print (stderr,
-                       yystos[yyssp[yyi + 1 - yynrhs]],
-                       &(yyvsp[(yyi + 1) - (yynrhs)])
-                       , &(yylsp[(yyi + 1) - (yynrhs)])                       );
-      YYFPRINTF (stderr, "\n");
-    }
-}
-
-# define YY_REDUCE_PRINT(Rule)          \
-do {                                    \
-  if (yydebug)                          \
-    yy_reduce_print (yyssp, yyvsp, yylsp, Rule); \
-} while (0)
-
-/* Nonzero means print parse trace.  It is left uninitialized so that
-   multiple parsers can coexist.  */
-int yydebug;
-#else /* !YYDEBUG */
-# define YYDPRINTF(Args)
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
-# define YY_STACK_PRINT(Bottom, Top)
-# define YY_REDUCE_PRINT(Rule)
-#endif /* !YYDEBUG */
-
-
-/* YYINITDEPTH -- initial size of the parser's stacks.  */
-#ifndef YYINITDEPTH
-# define YYINITDEPTH 200
-#endif
-
-/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
-   if the built-in stack extension method is used).
-
-   Do not make this value too large; the results are undefined if
-   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
-   evaluated with infinite-precision integer arithmetic.  */
-
-#ifndef YYMAXDEPTH
-# define YYMAXDEPTH 10000
-#endif
-
-
-#if YYERROR_VERBOSE
-
-# ifndef yystrlen
-#  if defined __GLIBC__ && defined _STRING_H
-#   define yystrlen strlen
-#  else
-/* Return the length of YYSTR.  */
-static YYSIZE_T
-yystrlen (const char *yystr)
-{
-  YYSIZE_T yylen;
-  for (yylen = 0; yystr[yylen]; yylen++)
-    continue;
-  return yylen;
-}
-#  endif
-# endif
-
-# ifndef yystpcpy
-#  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
-#   define yystpcpy stpcpy
-#  else
-/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
-   YYDEST.  */
-static char *
-yystpcpy (char *yydest, const char *yysrc)
-{
-  char *yyd = yydest;
-  const char *yys = yysrc;
-
-  while ((*yyd++ = *yys++) != '\0')
-    continue;
-
-  return yyd - 1;
-}
-#  endif
-# endif
-
-# ifndef yytnamerr
-/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
-   quotes and backslashes, so that it's suitable for yyerror.  The
-   heuristic is that double-quoting is unnecessary unless the string
-   contains an apostrophe, a comma, or backslash (other than
-   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
-   null, do not copy; instead, return the length of what the result
-   would have been.  */
-static YYSIZE_T
-yytnamerr (char *yyres, const char *yystr)
-{
-  if (*yystr == '"')
-    {
-      YYSIZE_T yyn = 0;
-      char const *yyp = yystr;
-
-      for (;;)
-        switch (*++yyp)
-          {
-          case '\'':
-          case ',':
-            goto do_not_strip_quotes;
-
-          case '\\':
-            if (*++yyp != '\\')
-              goto do_not_strip_quotes;
-            /* Fall through.  */
-          default:
-            if (yyres)
-              yyres[yyn] = *yyp;
-            yyn++;
-            break;
-
-          case '"':
-            if (yyres)
-              yyres[yyn] = '\0';
-            return yyn;
-          }
-    do_not_strip_quotes: ;
-    }
-
-  if (! yyres)
-    return yystrlen (yystr);
-
-  return yystpcpy (yyres, yystr) - yyres;
-}
-# endif
-
-/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
-   about the unexpected token YYTOKEN for the state stack whose top is
-   YYSSP.
-
-   Return 0 if *YYMSG was successfully written.  Return 1 if *YYMSG is
-   not large enough to hold the message.  In that case, also set
-   *YYMSG_ALLOC to the required number of bytes.  Return 2 if the
-   required number of bytes is too large to store.  */
-static int
-yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
-                yytype_int16 *yyssp, int yytoken)
-{
-  YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
-  YYSIZE_T yysize = yysize0;
-  enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
-  /* Internationalized format string. */
-  const char *yyformat = YY_NULLPTR;
-  /* Arguments of yyformat. */
-  char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
-  /* Number of reported tokens (one for the "unexpected", one per
-     "expected"). */
-  int yycount = 0;
-
-  /* There are many possibilities here to consider:
-     - If this state is a consistent state with a default action, then
-       the only way this function was invoked is if the default action
-       is an error action.  In that case, don't check for expected
-       tokens because there are none.
-     - The only way there can be no lookahead present (in yychar) is if
-       this state is a consistent state with a default action.  Thus,
-       detecting the absence of a lookahead is sufficient to determine
-       that there is no unexpected or expected token to report.  In that
-       case, just report a simple "syntax error".
-     - Don't assume there isn't a lookahead just because this state is a
-       consistent state with a default action.  There might have been a
-       previous inconsistent state, consistent state with a non-default
-       action, or user semantic action that manipulated yychar.
-     - Of course, the expected token list depends on states to have
-       correct lookahead information, and it depends on the parser not
-       to perform extra reductions after fetching a lookahead from the
-       scanner and before detecting a syntax error.  Thus, state merging
-       (from LALR or IELR) and default reductions corrupt the expected
-       token list.  However, the list is correct for canonical LR with
-       one exception: it will still contain any token that will not be
-       accepted due to an error action in a later state.
-  */
-  if (yytoken != YYEMPTY)
-    {
-      int yyn = yypact[*yyssp];
-      yyarg[yycount++] = yytname[yytoken];
-      if (!yypact_value_is_default (yyn))
-        {
-          /* Start YYX at -YYN if negative to avoid negative indexes in
-             YYCHECK.  In other words, skip the first -YYN actions for
-             this state because they are default actions.  */
-          int yyxbegin = yyn < 0 ? -yyn : 0;
-          /* Stay within bounds of both yycheck and yytname.  */
-          int yychecklim = YYLAST - yyn + 1;
-          int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
-          int yyx;
-
-          for (yyx = yyxbegin; yyx < yyxend; ++yyx)
-            if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
-                && !yytable_value_is_error (yytable[yyx + yyn]))
-              {
-                if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
-                  {
-                    yycount = 1;
-                    yysize = yysize0;
-                    break;
-                  }
-                yyarg[yycount++] = yytname[yyx];
-                {
-                  YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
-                  if (! (yysize <= yysize1
-                         && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
-                    return 2;
-                  yysize = yysize1;
-                }
-              }
-        }
-    }
-
-  switch (yycount)
-    {
-# define YYCASE_(N, S)                      \
-      case N:                               \
-        yyformat = S;                       \
-      break
-      YYCASE_(0, YY_("syntax error"));
-      YYCASE_(1, YY_("syntax error, unexpected %s"));
-      YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
-      YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
-      YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
-      YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
-# undef YYCASE_
-    }
-
-  {
-    YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
-    if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
-      return 2;
-    yysize = yysize1;
-  }
-
-  if (*yymsg_alloc < yysize)
-    {
-      *yymsg_alloc = 2 * yysize;
-      if (! (yysize <= *yymsg_alloc
-             && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
-        *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
-      return 1;
-    }
-
-  /* Avoid sprintf, as that infringes on the user's name space.
-     Don't have undefined behavior even if the translation
-     produced a string with the wrong number of "%s"s.  */
-  {
-    char *yyp = *yymsg;
-    int yyi = 0;
-    while ((*yyp = *yyformat) != '\0')
-      if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
-        {
-          yyp += yytnamerr (yyp, yyarg[yyi++]);
-          yyformat += 2;
-        }
-      else
-        {
-          yyp++;
-          yyformat++;
-        }
-  }
-  return 0;
-}
-#endif /* YYERROR_VERBOSE */
-
-/*-----------------------------------------------.
-| Release the memory associated to this symbol.  |
-`-----------------------------------------------*/
-
-static void
-yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp)
-{
-  YYUSE (yyvaluep);
-  YYUSE (yylocationp);
-  if (!yymsg)
-    yymsg = "Deleting";
-  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
-
-  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
-  YYUSE (yytype);
-  YY_IGNORE_MAYBE_UNINITIALIZED_END
-}
-
-
-
-
-/* The lookahead symbol.  */
-int yychar;
-
-/* The semantic value of the lookahead symbol.  */
-YYSTYPE yylval;
-/* Location data for the lookahead symbol.  */
-YYLTYPE yylloc
-# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
-  = { 1, 1, 1, 1 }
-# endif
-;
-/* Number of syntax errors so far.  */
-int yynerrs;
-
-
-/*----------.
-| yyparse.  |
-`----------*/
-
-int
-yyparse (void)
-{
-    int yystate;
-    /* Number of tokens to shift before error messages enabled.  */
-    int yyerrstatus;
-
-    /* The stacks and their tools:
-       'yyss': related to states.
-       'yyvs': related to semantic values.
-       'yyls': related to locations.
-
-       Refer to the stacks through separate pointers, to allow yyoverflow
-       to reallocate them elsewhere.  */
-
-    /* The state stack.  */
-    yytype_int16 yyssa[YYINITDEPTH];
-    yytype_int16 *yyss;
-    yytype_int16 *yyssp;
-
-    /* The semantic value stack.  */
-    YYSTYPE yyvsa[YYINITDEPTH];
-    YYSTYPE *yyvs;
-    YYSTYPE *yyvsp;
-
-    /* The location stack.  */
-    YYLTYPE yylsa[YYINITDEPTH];
-    YYLTYPE *yyls;
-    YYLTYPE *yylsp;
-
-    /* The locations where the error started and ended.  */
-    YYLTYPE yyerror_range[3];
-
-    YYSIZE_T yystacksize;
-
-  int yyn;
-  int yyresult;
-  /* Lookahead token as an internal (translated) token number.  */
-  int yytoken = 0;
-  /* The variables used to return semantic value and location from the
-     action routines.  */
-  YYSTYPE yyval;
-  YYLTYPE yyloc;
-
-#if YYERROR_VERBOSE
-  /* Buffer for error messages, and its allocated size.  */
-  char yymsgbuf[128];
-  char *yymsg = yymsgbuf;
-  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
-#endif
-
-#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
-
-  /* The number of symbols on the RHS of the reduced rule.
-     Keep to zero when no symbol should be popped.  */
-  int yylen = 0;
-
-  yyssp = yyss = yyssa;
-  yyvsp = yyvs = yyvsa;
-  yylsp = yyls = yylsa;
-  yystacksize = YYINITDEPTH;
-
-  YYDPRINTF ((stderr, "Starting parse\n"));
-
-  yystate = 0;
-  yyerrstatus = 0;
-  yynerrs = 0;
-  yychar = YYEMPTY; /* Cause a token to be read.  */
-  yylsp[0] = yylloc;
-  goto yysetstate;
-
-/*------------------------------------------------------------.
-| yynewstate -- Push a new state, which is found in yystate.  |
-`------------------------------------------------------------*/
- yynewstate:
-  /* In all cases, when you get here, the value and location stacks
-     have just been pushed.  So pushing a state here evens the stacks.  */
-  yyssp++;
-
- yysetstate:
-  *yyssp = yystate;
-
-  if (yyss + yystacksize - 1 <= yyssp)
-    {
-      /* Get the current used size of the three stacks, in elements.  */
-      YYSIZE_T yysize = yyssp - yyss + 1;
-
-#ifdef yyoverflow
-      {
-        /* Give user a chance to reallocate the stack.  Use copies of
-           these so that the &'s don't force the real ones into
-           memory.  */
-        YYSTYPE *yyvs1 = yyvs;
-        yytype_int16 *yyss1 = yyss;
-        YYLTYPE *yyls1 = yyls;
-
-        /* Each stack pointer address is followed by the size of the
-           data in use in that stack, in bytes.  This used to be a
-           conditional around just the two extra args, but that might
-           be undefined if yyoverflow is a macro.  */
-        yyoverflow (YY_("memory exhausted"),
-                    &yyss1, yysize * sizeof (*yyssp),
-                    &yyvs1, yysize * sizeof (*yyvsp),
-                    &yyls1, yysize * sizeof (*yylsp),
-                    &yystacksize);
-
-        yyls = yyls1;
-        yyss = yyss1;
-        yyvs = yyvs1;
-      }
-#else /* no yyoverflow */
-# ifndef YYSTACK_RELOCATE
-      goto yyexhaustedlab;
-# else
-      /* Extend the stack our own way.  */
-      if (YYMAXDEPTH <= yystacksize)
-        goto yyexhaustedlab;
-      yystacksize *= 2;
-      if (YYMAXDEPTH < yystacksize)
-        yystacksize = YYMAXDEPTH;
-
-      {
-        yytype_int16 *yyss1 = yyss;
-        union yyalloc *yyptr =
-          (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
-        if (! yyptr)
-          goto yyexhaustedlab;
-        YYSTACK_RELOCATE (yyss_alloc, yyss);
-        YYSTACK_RELOCATE (yyvs_alloc, yyvs);
-        YYSTACK_RELOCATE (yyls_alloc, yyls);
-#  undef YYSTACK_RELOCATE
-        if (yyss1 != yyssa)
-          YYSTACK_FREE (yyss1);
-      }
-# endif
-#endif /* no yyoverflow */
-
-      yyssp = yyss + yysize - 1;
-      yyvsp = yyvs + yysize - 1;
-      yylsp = yyls + yysize - 1;
-
-      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
-                  (unsigned long int) yystacksize));
-
-      if (yyss + yystacksize - 1 <= yyssp)
-        YYABORT;
-    }
-
-  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
-
-  if (yystate == YYFINAL)
-    YYACCEPT;
-
-  goto yybackup;
-
-/*-----------.
-| yybackup.  |
-`-----------*/
-yybackup:
-
-  /* Do appropriate processing given the current state.  Read a
-     lookahead token if we need one and don't already have one.  */
-
-  /* First try to decide what to do without reference to lookahead token.  */
-  yyn = yypact[yystate];
-  if (yypact_value_is_default (yyn))
-    goto yydefault;
-
-  /* Not known => get a lookahead token if don't already have one.  */
-
-  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
-  if (yychar == YYEMPTY)
-    {
-      YYDPRINTF ((stderr, "Reading a token: "));
-      yychar = yylex ();
-    }
-
-  if (yychar <= YYEOF)
-    {
-      yychar = yytoken = YYEOF;
-      YYDPRINTF ((stderr, "Now at end of input.\n"));
-    }
-  else
-    {
-      yytoken = YYTRANSLATE (yychar);
-      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
-    }
-
-  /* If the proper action on seeing token YYTOKEN is to reduce or to
-     detect an error, take that action.  */
-  yyn += yytoken;
-  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
-    goto yydefault;
-  yyn = yytable[yyn];
-  if (yyn <= 0)
-    {
-      if (yytable_value_is_error (yyn))
-        goto yyerrlab;
-      yyn = -yyn;
-      goto yyreduce;
-    }
-
-  /* Count tokens shifted since error; after three, turn off error
-     status.  */
-  if (yyerrstatus)
-    yyerrstatus--;
-
-  /* Shift the lookahead token.  */
-  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
-
-  /* Discard the shifted token.  */
-  yychar = YYEMPTY;
-
-  yystate = yyn;
-  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
-  *++yyvsp = yylval;
-  YY_IGNORE_MAYBE_UNINITIALIZED_END
-  *++yylsp = yylloc;
-  goto yynewstate;
-
-
-/*-----------------------------------------------------------.
-| yydefault -- do the default action for the current state.  |
-`-----------------------------------------------------------*/
-yydefault:
-  yyn = yydefact[yystate];
-  if (yyn == 0)
-    goto yyerrlab;
-  goto yyreduce;
-
-
-/*-----------------------------.
-| yyreduce -- Do a reduction.  |
-`-----------------------------*/
-yyreduce:
-  /* yyn is the number of a rule to reduce with.  */
-  yylen = yyr2[yyn];
-
-  /* If YYLEN is nonzero, implement the default value of the action:
-     '$$ = $1'.
-
-     Otherwise, the following line sets YYVAL to garbage.
-     This behavior is undocumented and Bison
-     users should not rely upon it.  Assigning to YYVAL
-     unconditionally makes the parser a bit smaller, and it avoids a
-     GCC warning that YYVAL may be used uninitialized.  */
-  yyval = yyvsp[1-yylen];
-
-  /* Default location.  */
-  YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
-  YY_REDUCE_PRINT (yyn);
-  switch (yyn)
-    {
-        case 2:
-#line 110 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			parser_output = build_dt_info((yyvsp[-2].flags), (yyvsp[-1].re), (yyvsp[0].node),
-			                              guess_boot_cpuid((yyvsp[0].node)));
-		}
-#line 1478 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 3:
-#line 118 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.flags) = DTSF_V1;
-		}
-#line 1486 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 4:
-#line 122 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.flags) = DTSF_V1 | DTSF_PLUGIN;
-		}
-#line 1494 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 6:
-#line 130 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			if ((yyvsp[0].flags) != (yyvsp[-1].flags))
-				ERROR(&(yylsp[0]), "Header flags don't match earlier ones");
-			(yyval.flags) = (yyvsp[-1].flags);
-		}
-#line 1504 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 7:
-#line 139 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.re) = NULL;
-		}
-#line 1512 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 8:
-#line 143 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.re) = chain_reserve_entry((yyvsp[-1].re), (yyvsp[0].re));
-		}
-#line 1520 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 9:
-#line 150 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.re) = build_reserve_entry((yyvsp[-2].integer), (yyvsp[-1].integer));
-		}
-#line 1528 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 10:
-#line 154 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			add_label(&(yyvsp[0].re)->labels, (yyvsp[-1].labelref));
-			(yyval.re) = (yyvsp[0].re);
-		}
-#line 1537 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 11:
-#line 162 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.node) = name_node((yyvsp[0].node), "");
-		}
-#line 1545 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 12:
-#line 166 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.node) = merge_nodes((yyvsp[-2].node), (yyvsp[0].node));
-		}
-#line 1553 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 13:
-#line 171 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref));
-
-			if (target) {
-				add_label(&target->labels, (yyvsp[-2].labelref));
-				merge_nodes(target, (yyvsp[0].node));
-			} else
-				ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref));
-			(yyval.node) = (yyvsp[-3].node);
-		}
-#line 1568 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 14:
-#line 182 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			struct node *target = get_node_by_ref((yyvsp[-2].node), (yyvsp[-1].labelref));
-
-			if (target) {
-				merge_nodes(target, (yyvsp[0].node));
-			} else {
-				/*
-				 * We rely on the rule being always:
-				 *   versioninfo plugindecl memreserves devicetree
-				 * so $-1 is what we want (plugindecl)
-				 */
-				if ((yyvsp[(-1) - (3)].flags) & DTSF_PLUGIN)
-					add_orphan_node((yyvsp[-2].node), (yyvsp[0].node), (yyvsp[-1].labelref));
-				else
-					ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref));
-			}
-			(yyval.node) = (yyvsp[-2].node);
-		}
-#line 1591 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 15:
-#line 201 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref));
-
-			if (target)
-				delete_node(target);
-			else
-				ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref));
-
-
-			(yyval.node) = (yyvsp[-3].node);
-		}
-#line 1607 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 16:
-#line 213 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			/* build empty node */
-			(yyval.node) = name_node(build_node(NULL, NULL), "");
-		}
-#line 1616 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 17:
-#line 221 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist));
-		}
-#line 1624 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 18:
-#line 228 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.proplist) = NULL;
-		}
-#line 1632 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 19:
-#line 232 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist));
-		}
-#line 1640 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 20:
-#line 239 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data));
-		}
-#line 1648 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 21:
-#line 243 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data);
-		}
-#line 1656 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 22:
-#line 247 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.prop) = build_property_delete((yyvsp[-1].propnodename));
-		}
-#line 1664 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 23:
-#line 251 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			add_label(&(yyvsp[0].prop)->labels, (yyvsp[-1].labelref));
-			(yyval.prop) = (yyvsp[0].prop);
-		}
-#line 1673 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 24:
-#line 259 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.data) = data_merge((yyvsp[-1].data), (yyvsp[0].data));
-		}
-#line 1681 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 25:
-#line 263 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.data) = data_merge((yyvsp[-2].data), (yyvsp[-1].array).data);
-		}
-#line 1689 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 26:
-#line 267 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.data) = data_merge((yyvsp[-3].data), (yyvsp[-1].data));
-		}
-#line 1697 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 27:
-#line 271 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.data) = data_add_marker((yyvsp[-1].data), REF_PATH, (yyvsp[0].labelref));
-		}
-#line 1705 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 28:
-#line 275 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			FILE *f = srcfile_relative_open((yyvsp[-5].data).val, NULL);
-			struct data d;
-
-			if ((yyvsp[-3].integer) != 0)
-				if (fseek(f, (yyvsp[-3].integer), SEEK_SET) != 0)
-					die("Couldn't seek to offset %llu in \"%s\": %s",
-					    (unsigned long long)(yyvsp[-3].integer), (yyvsp[-5].data).val,
-					    strerror(errno));
-
-			d = data_copy_file(f, (yyvsp[-1].integer));
-
-			(yyval.data) = data_merge((yyvsp[-8].data), d);
-			fclose(f);
-		}
-#line 1725 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 29:
-#line 291 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			FILE *f = srcfile_relative_open((yyvsp[-1].data).val, NULL);
-			struct data d = empty_data;
-
-			d = data_copy_file(f, -1);
-
-			(yyval.data) = data_merge((yyvsp[-4].data), d);
-			fclose(f);
-		}
-#line 1739 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 30:
-#line 301 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
-		}
-#line 1747 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 31:
-#line 308 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.data) = empty_data;
-		}
-#line 1755 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 32:
-#line 312 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.data) = (yyvsp[-1].data);
-		}
-#line 1763 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 33:
-#line 316 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
-		}
-#line 1771 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 34:
-#line 323 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			unsigned long long bits;
-
-			bits = (yyvsp[-1].integer);
-
-			if ((bits !=  8) && (bits != 16) &&
-			    (bits != 32) && (bits != 64)) {
-				ERROR(&(yylsp[-1]), "Array elements must be"
-				      " 8, 16, 32 or 64-bits");
-				bits = 32;
-			}
-
-			(yyval.array).data = empty_data;
-			(yyval.array).bits = bits;
-		}
-#line 1791 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 35:
-#line 339 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.array).data = empty_data;
-			(yyval.array).bits = 32;
-		}
-#line 1800 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 36:
-#line 344 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			if ((yyvsp[-1].array).bits < 64) {
-				uint64_t mask = (1ULL << (yyvsp[-1].array).bits) - 1;
-				/*
-				 * Bits above mask must either be all zero
-				 * (positive within range of mask) or all one
-				 * (negative and sign-extended). The second
-				 * condition is true if when we set all bits
-				 * within the mask to one (i.e. | in the
-				 * mask), all bits are one.
-				 */
-				if (((yyvsp[0].integer) > mask) && (((yyvsp[0].integer) | mask) != -1ULL))
-					ERROR(&(yylsp[0]), "Value out of range for"
-					      " %d-bit array element", (yyvsp[-1].array).bits);
-			}
-
-			(yyval.array).data = data_append_integer((yyvsp[-1].array).data, (yyvsp[0].integer), (yyvsp[-1].array).bits);
-		}
-#line 1823 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 37:
-#line 363 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			uint64_t val = ~0ULL >> (64 - (yyvsp[-1].array).bits);
-
-			if ((yyvsp[-1].array).bits == 32)
-				(yyvsp[-1].array).data = data_add_marker((yyvsp[-1].array).data,
-							  REF_PHANDLE,
-							  (yyvsp[0].labelref));
-			else
-				ERROR(&(yylsp[0]), "References are only allowed in "
-					    "arrays with 32-bit elements.");
-
-			(yyval.array).data = data_append_integer((yyvsp[-1].array).data, val, (yyvsp[-1].array).bits);
-		}
-#line 1841 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 38:
-#line 377 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.array).data = data_add_marker((yyvsp[-1].array).data, LABEL, (yyvsp[0].labelref));
-		}
-#line 1849 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 41:
-#line 386 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.integer) = (yyvsp[-1].integer);
-		}
-#line 1857 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 44:
-#line 397 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = (yyvsp[-4].integer) ? (yyvsp[-2].integer) : (yyvsp[0].integer); }
-#line 1863 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 46:
-#line 402 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = (yyvsp[-2].integer) || (yyvsp[0].integer); }
-#line 1869 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 48:
-#line 407 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = (yyvsp[-2].integer) && (yyvsp[0].integer); }
-#line 1875 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 50:
-#line 412 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = (yyvsp[-2].integer) | (yyvsp[0].integer); }
-#line 1881 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 52:
-#line 417 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = (yyvsp[-2].integer) ^ (yyvsp[0].integer); }
-#line 1887 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 54:
-#line 422 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = (yyvsp[-2].integer) & (yyvsp[0].integer); }
-#line 1893 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 56:
-#line 427 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = (yyvsp[-2].integer) == (yyvsp[0].integer); }
-#line 1899 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 57:
-#line 428 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = (yyvsp[-2].integer) != (yyvsp[0].integer); }
-#line 1905 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 59:
-#line 433 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = (yyvsp[-2].integer) < (yyvsp[0].integer); }
-#line 1911 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 60:
-#line 434 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = (yyvsp[-2].integer) > (yyvsp[0].integer); }
-#line 1917 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 61:
-#line 435 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = (yyvsp[-2].integer) <= (yyvsp[0].integer); }
-#line 1923 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 62:
-#line 436 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = (yyvsp[-2].integer) >= (yyvsp[0].integer); }
-#line 1929 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 63:
-#line 440 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = (yyvsp[-2].integer) << (yyvsp[0].integer); }
-#line 1935 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 64:
-#line 441 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = (yyvsp[-2].integer) >> (yyvsp[0].integer); }
-#line 1941 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 66:
-#line 446 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); }
-#line 1947 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 67:
-#line 447 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = (yyvsp[-2].integer) - (yyvsp[0].integer); }
-#line 1953 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 69:
-#line 452 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = (yyvsp[-2].integer) * (yyvsp[0].integer); }
-#line 1959 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 70:
-#line 454 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			if ((yyvsp[0].integer) != 0) {
-				(yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer);
-			} else {
-				ERROR(&(yyloc), "Division by zero");
-				(yyval.integer) = 0;
-			}
-		}
-#line 1972 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 71:
-#line 463 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			if ((yyvsp[0].integer) != 0) {
-				(yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer);
-			} else {
-				ERROR(&(yyloc), "Division by zero");
-				(yyval.integer) = 0;
-			}
-		}
-#line 1985 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 74:
-#line 476 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = -(yyvsp[0].integer); }
-#line 1991 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 75:
-#line 477 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = ~(yyvsp[0].integer); }
-#line 1997 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 76:
-#line 478 "dtc-parser.y" /* yacc.c:1646  */
-    { (yyval.integer) = !(yyvsp[0].integer); }
-#line 2003 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 77:
-#line 483 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.data) = empty_data;
-		}
-#line 2011 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 78:
-#line 487 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte));
-		}
-#line 2019 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 79:
-#line 491 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
-		}
-#line 2027 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 80:
-#line 498 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.nodelist) = NULL;
-		}
-#line 2035 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 81:
-#line 502 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist));
-		}
-#line 2043 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 82:
-#line 506 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			ERROR(&(yylsp[0]), "Properties must precede subnodes");
-			YYERROR;
-		}
-#line 2052 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 83:
-#line 514 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename));
-		}
-#line 2060 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 84:
-#line 518 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			(yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename));
-		}
-#line 2068 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-  case 85:
-#line 522 "dtc-parser.y" /* yacc.c:1646  */
-    {
-			add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref));
-			(yyval.node) = (yyvsp[0].node);
-		}
-#line 2077 "dtc-parser.tab.c" /* yacc.c:1646  */
-    break;
-
-
-#line 2081 "dtc-parser.tab.c" /* yacc.c:1646  */
-      default: break;
-    }
-  /* User semantic actions sometimes alter yychar, and that requires
-     that yytoken be updated with the new translation.  We take the
-     approach of translating immediately before every use of yytoken.
-     One alternative is translating here after every semantic action,
-     but that translation would be missed if the semantic action invokes
-     YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
-     if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an
-     incorrect destructor might then be invoked immediately.  In the
-     case of YYERROR or YYBACKUP, subsequent parser actions might lead
-     to an incorrect destructor call or verbose syntax error message
-     before the lookahead is translated.  */
-  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
-
-  YYPOPSTACK (yylen);
-  yylen = 0;
-  YY_STACK_PRINT (yyss, yyssp);
-
-  *++yyvsp = yyval;
-  *++yylsp = yyloc;
-
-  /* Now 'shift' the result of the reduction.  Determine what state
-     that goes to, based on the state we popped back to and the rule
-     number reduced by.  */
-
-  yyn = yyr1[yyn];
-
-  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
-  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
-    yystate = yytable[yystate];
-  else
-    yystate = yydefgoto[yyn - YYNTOKENS];
-
-  goto yynewstate;
-
-
-/*--------------------------------------.
-| yyerrlab -- here on detecting error.  |
-`--------------------------------------*/
-yyerrlab:
-  /* Make sure we have latest lookahead translation.  See comments at
-     user semantic actions for why this is necessary.  */
-  yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
-
-  /* If not already recovering from an error, report this error.  */
-  if (!yyerrstatus)
-    {
-      ++yynerrs;
-#if ! YYERROR_VERBOSE
-      yyerror (YY_("syntax error"));
-#else
-# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
-                                        yyssp, yytoken)
-      {
-        char const *yymsgp = YY_("syntax error");
-        int yysyntax_error_status;
-        yysyntax_error_status = YYSYNTAX_ERROR;
-        if (yysyntax_error_status == 0)
-          yymsgp = yymsg;
-        else if (yysyntax_error_status == 1)
-          {
-            if (yymsg != yymsgbuf)
-              YYSTACK_FREE (yymsg);
-            yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
-            if (!yymsg)
-              {
-                yymsg = yymsgbuf;
-                yymsg_alloc = sizeof yymsgbuf;
-                yysyntax_error_status = 2;
-              }
-            else
-              {
-                yysyntax_error_status = YYSYNTAX_ERROR;
-                yymsgp = yymsg;
-              }
-          }
-        yyerror (yymsgp);
-        if (yysyntax_error_status == 2)
-          goto yyexhaustedlab;
-      }
-# undef YYSYNTAX_ERROR
-#endif
-    }
-
-  yyerror_range[1] = yylloc;
-
-  if (yyerrstatus == 3)
-    {
-      /* If just tried and failed to reuse lookahead token after an
-         error, discard it.  */
-
-      if (yychar <= YYEOF)
-        {
-          /* Return failure if at end of input.  */
-          if (yychar == YYEOF)
-            YYABORT;
-        }
-      else
-        {
-          yydestruct ("Error: discarding",
-                      yytoken, &yylval, &yylloc);
-          yychar = YYEMPTY;
-        }
-    }
-
-  /* Else will try to reuse lookahead token after shifting the error
-     token.  */
-  goto yyerrlab1;
-
-
-/*---------------------------------------------------.
-| yyerrorlab -- error raised explicitly by YYERROR.  |
-`---------------------------------------------------*/
-yyerrorlab:
-
-  /* Pacify compilers like GCC when the user code never invokes
-     YYERROR and the label yyerrorlab therefore never appears in user
-     code.  */
-  if (/*CONSTCOND*/ 0)
-     goto yyerrorlab;
-
-  yyerror_range[1] = yylsp[1-yylen];
-  /* Do not reclaim the symbols of the rule whose action triggered
-     this YYERROR.  */
-  YYPOPSTACK (yylen);
-  yylen = 0;
-  YY_STACK_PRINT (yyss, yyssp);
-  yystate = *yyssp;
-  goto yyerrlab1;
-
-
-/*-------------------------------------------------------------.
-| yyerrlab1 -- common code for both syntax error and YYERROR.  |
-`-------------------------------------------------------------*/
-yyerrlab1:
-  yyerrstatus = 3;      /* Each real token shifted decrements this.  */
-
-  for (;;)
-    {
-      yyn = yypact[yystate];
-      if (!yypact_value_is_default (yyn))
-        {
-          yyn += YYTERROR;
-          if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
-            {
-              yyn = yytable[yyn];
-              if (0 < yyn)
-                break;
-            }
-        }
-
-      /* Pop the current state because it cannot handle the error token.  */
-      if (yyssp == yyss)
-        YYABORT;
-
-      yyerror_range[1] = *yylsp;
-      yydestruct ("Error: popping",
-                  yystos[yystate], yyvsp, yylsp);
-      YYPOPSTACK (1);
-      yystate = *yyssp;
-      YY_STACK_PRINT (yyss, yyssp);
-    }
-
-  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
-  *++yyvsp = yylval;
-  YY_IGNORE_MAYBE_UNINITIALIZED_END
-
-  yyerror_range[2] = yylloc;
-  /* Using YYLLOC is tempting, but would change the location of
-     the lookahead.  YYLOC is available though.  */
-  YYLLOC_DEFAULT (yyloc, yyerror_range, 2);
-  *++yylsp = yyloc;
-
-  /* Shift the error token.  */
-  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
-
-  yystate = yyn;
-  goto yynewstate;
-
-
-/*-------------------------------------.
-| yyacceptlab -- YYACCEPT comes here.  |
-`-------------------------------------*/
-yyacceptlab:
-  yyresult = 0;
-  goto yyreturn;
-
-/*-----------------------------------.
-| yyabortlab -- YYABORT comes here.  |
-`-----------------------------------*/
-yyabortlab:
-  yyresult = 1;
-  goto yyreturn;
-
-#if !defined yyoverflow || YYERROR_VERBOSE
-/*-------------------------------------------------.
-| yyexhaustedlab -- memory exhaustion comes here.  |
-`-------------------------------------------------*/
-yyexhaustedlab:
-  yyerror (YY_("memory exhausted"));
-  yyresult = 2;
-  /* Fall through.  */
-#endif
-
-yyreturn:
-  if (yychar != YYEMPTY)
-    {
-      /* Make sure we have latest lookahead translation.  See comments at
-         user semantic actions for why this is necessary.  */
-      yytoken = YYTRANSLATE (yychar);
-      yydestruct ("Cleanup: discarding lookahead",
-                  yytoken, &yylval, &yylloc);
-    }
-  /* Do not reclaim the symbols of the rule whose action triggered
-     this YYABORT or YYACCEPT.  */
-  YYPOPSTACK (yylen);
-  YY_STACK_PRINT (yyss, yyssp);
-  while (yyssp != yyss)
-    {
-      yydestruct ("Cleanup: popping",
-                  yystos[*yyssp], yyvsp, yylsp);
-      YYPOPSTACK (1);
-    }
-#ifndef yyoverflow
-  if (yyss != yyssa)
-    YYSTACK_FREE (yyss);
-#endif
-#if YYERROR_VERBOSE
-  if (yymsg != yymsgbuf)
-    YYSTACK_FREE (yymsg);
-#endif
-  return yyresult;
-}
-#line 528 "dtc-parser.y" /* yacc.c:1906  */
-
-
-void yyerror(char const *s)
-{
-	ERROR(&yylloc, "%s", s);
-}
diff --git a/scripts/dtc/dtc-parser.tab.h_shipped b/scripts/dtc/dtc-parser.tab.h_shipped
deleted file mode 100644
index 6aa512c..0000000
--- a/scripts/dtc/dtc-parser.tab.h_shipped
+++ /dev/null
@@ -1,125 +0,0 @@
-/* A Bison parser, made by GNU Bison 3.0.4.  */
-
-/* Bison interface for Yacc-like parsers in C
-
-   Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
-
-   This program is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
-
-/* As a special exception, you may create a larger work that contains
-   part or all of the Bison parser skeleton and distribute that work
-   under terms of your choice, so long as that work isn't itself a
-   parser generator using the skeleton or a modified version thereof
-   as a parser skeleton.  Alternatively, if you modify or redistribute
-   the parser skeleton itself, you may (at your option) remove this
-   special exception, which will cause the skeleton and the resulting
-   Bison output files to be licensed under the GNU General Public
-   License without this special exception.
-
-   This special exception was added by the Free Software Foundation in
-   version 2.2 of Bison.  */
-
-#ifndef YY_YY_DTC_PARSER_TAB_H_INCLUDED
-# define YY_YY_DTC_PARSER_TAB_H_INCLUDED
-/* Debug traces.  */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
-#if YYDEBUG
-extern int yydebug;
-#endif
-
-/* Token type.  */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
-  enum yytokentype
-  {
-    DT_V1 = 258,
-    DT_PLUGIN = 259,
-    DT_MEMRESERVE = 260,
-    DT_LSHIFT = 261,
-    DT_RSHIFT = 262,
-    DT_LE = 263,
-    DT_GE = 264,
-    DT_EQ = 265,
-    DT_NE = 266,
-    DT_AND = 267,
-    DT_OR = 268,
-    DT_BITS = 269,
-    DT_DEL_PROP = 270,
-    DT_DEL_NODE = 271,
-    DT_PROPNODENAME = 272,
-    DT_LITERAL = 273,
-    DT_CHAR_LITERAL = 274,
-    DT_BYTE = 275,
-    DT_STRING = 276,
-    DT_LABEL = 277,
-    DT_REF = 278,
-    DT_INCBIN = 279
-  };
-#endif
-
-/* Value type.  */
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-
-union YYSTYPE
-{
-#line 39 "dtc-parser.y" /* yacc.c:1909  */
-
-	char *propnodename;
-	char *labelref;
-	uint8_t byte;
-	struct data data;
-
-	struct {
-		struct data	data;
-		int		bits;
-	} array;
-
-	struct property *prop;
-	struct property *proplist;
-	struct node *node;
-	struct node *nodelist;
-	struct reserve_info *re;
-	uint64_t integer;
-	unsigned int flags;
-
-#line 99 "dtc-parser.tab.h" /* yacc.c:1909  */
-};
-
-typedef union YYSTYPE YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
-# define YYSTYPE_IS_DECLARED 1
-#endif
-
-/* Location type.  */
-#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
-typedef struct YYLTYPE YYLTYPE;
-struct YYLTYPE
-{
-  int first_line;
-  int first_column;
-  int last_line;
-  int last_column;
-};
-# define YYLTYPE_IS_DECLARED 1
-# define YYLTYPE_IS_TRIVIAL 1
-#endif
-
-
-extern YYSTYPE yylval;
-extern YYLTYPE yylloc;
-int yyparse (void);
-
-#endif /* !YY_YY_DTC_PARSER_TAB_H_INCLUDED  */
diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y
index affc81a..44af170 100644
--- a/scripts/dtc/dtc-parser.y
+++ b/scripts/dtc/dtc-parser.y
@@ -166,7 +166,17 @@
 		{
 			$$ = merge_nodes($1, $3);
 		}
-
+	| DT_REF nodedef
+		{
+			/*
+			 * We rely on the rule being always:
+			 *   versioninfo plugindecl memreserves devicetree
+			 * so $-1 is what we want (plugindecl)
+			 */
+			if (!($<flags>-1 & DTSF_PLUGIN))
+				ERROR(&@2, "Label or path %s not found", $1);
+			$$ = add_orphan_node(name_node(build_node(NULL, NULL), ""), $2, $1);
+		}
 	| devicetree DT_LABEL DT_REF nodedef
 		{
 			struct node *target = get_node_by_ref($1, $3);
@@ -209,11 +219,6 @@
 
 			$$ = $1;
 		}
-	| /* empty */
-		{
-			/* build empty node */
-			$$ = name_node(build_node(NULL, NULL), "");
-		}
 	;
 
 nodedef:
diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c
index 5ed873c..c36994e 100644
--- a/scripts/dtc/dtc.c
+++ b/scripts/dtc/dtc.c
@@ -59,8 +59,6 @@
 }
 
 /* Usage related data. */
-#define FDT_VERSION(version)	_FDT_VERSION(version)
-#define _FDT_VERSION(version)	#version
 static const char usage_synopsis[] = "dtc [options] <input file>";
 static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:a:fb:i:H:sW:E:@Ahv";
 static struct option const usage_long_opts[] = {
@@ -98,7 +96,7 @@
 	 "\t\tdts - device tree source text\n"
 	 "\t\tdtb - device tree blob\n"
 	 "\t\tasm - assembler source",
-	"\n\tBlob version to produce, defaults to "FDT_VERSION(DEFAULT_FDT_VERSION)" (for dtb and asm output)",
+	"\n\tBlob version to produce, defaults to "stringify(DEFAULT_FDT_VERSION)" (for dtb and asm output)",
 	"\n\tOutput dependency file",
 	"\n\tMake space for <number> reserve map entries (for dtb and asm output)",
 	"\n\tMake the blob at least <bytes> long (extra space)",
@@ -319,13 +317,14 @@
 		dti->boot_cpuid_phys = cmdline_boot_cpuid;
 
 	fill_fullpaths(dti->dt, "");
-	process_checks(force, dti);
 
 	/* on a plugin, generate by default */
 	if (dti->dtsflags & DTSF_PLUGIN) {
 		generate_fixups = 1;
 	}
 
+	process_checks(force, dti);
+
 	if (auto_label_aliases)
 		generate_label_tree(dti, "aliases", false);
 
diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h
index 35cf926..3b18a42 100644
--- a/scripts/dtc/dtc.h
+++ b/scripts/dtc/dtc.h
@@ -1,5 +1,5 @@
-#ifndef _DTC_H
-#define _DTC_H
+#ifndef DTC_H
+#define DTC_H
 
 /*
  * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
@@ -67,7 +67,8 @@
 
 
 #define streq(a, b)	(strcmp((a), (b)) == 0)
-#define strneq(a, b, n)	(strncmp((a), (b), (n)) == 0)
+#define strstarts(s, prefix)	(strncmp((s), (prefix), strlen(prefix)) == 0)
+#define strprefixeq(a, n, b)	(strlen(b) == (n) && (memcmp(a, b, n) == 0))
 
 #define ALIGN(x, a)	(((x) + (a) - 1) & ~((a) - 1))
 
@@ -203,7 +204,7 @@
 struct node *name_node(struct node *node, char *name);
 struct node *chain_node(struct node *first, struct node *list);
 struct node *merge_nodes(struct node *old_node, struct node *new_node);
-void add_orphan_node(struct node *old_node, struct node *new_node, char *ref);
+struct node *add_orphan_node(struct node *old_node, struct node *new_node, char *ref);
 
 void add_property(struct node *node, struct property *prop);
 void delete_property_by_name(struct node *node, char *name);
@@ -289,4 +290,4 @@
 
 struct dt_info *dt_from_fs(const char *dirname);
 
-#endif /* _DTC_H */
+#endif /* DTC_H */
diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c
index fcf7154..8d268fb 100644
--- a/scripts/dtc/flattree.c
+++ b/scripts/dtc/flattree.c
@@ -731,7 +731,7 @@
 
 	plen = strlen(ppath);
 
-	if (!strneq(ppath, cpath, plen))
+	if (!strstarts(cpath, ppath))
 		die("Path \"%s\" is not valid as a child of \"%s\"\n",
 		    cpath, ppath);
 
diff --git a/scripts/dtc/libfdt/fdt.c b/scripts/dtc/libfdt/fdt.c
index 22286a1..7855a17 100644
--- a/scripts/dtc/libfdt/fdt.c
+++ b/scripts/dtc/libfdt/fdt.c
@@ -88,7 +88,7 @@
 		    || ((offset + len) > fdt_size_dt_struct(fdt)))
 			return NULL;
 
-	return _fdt_offset_ptr(fdt, offset);
+	return fdt_offset_ptr_(fdt, offset);
 }
 
 uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
@@ -123,6 +123,9 @@
 		/* skip-name offset, length and value */
 		offset += sizeof(struct fdt_property) - FDT_TAGSIZE
 			+ fdt32_to_cpu(*lenp);
+		if (fdt_version(fdt) < 0x10 && fdt32_to_cpu(*lenp) >= 8 &&
+		    ((offset - fdt32_to_cpu(*lenp)) % 8) != 0)
+			offset += 4;
 		break;
 
 	case FDT_END:
@@ -141,7 +144,7 @@
 	return tag;
 }
 
-int _fdt_check_node_offset(const void *fdt, int offset)
+int fdt_check_node_offset_(const void *fdt, int offset)
 {
 	if ((offset < 0) || (offset % FDT_TAGSIZE)
 	    || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE))
@@ -150,7 +153,7 @@
 	return offset;
 }
 
-int _fdt_check_prop_offset(const void *fdt, int offset)
+int fdt_check_prop_offset_(const void *fdt, int offset)
 {
 	if ((offset < 0) || (offset % FDT_TAGSIZE)
 	    || (fdt_next_tag(fdt, offset, &offset) != FDT_PROP))
@@ -165,7 +168,7 @@
 	uint32_t tag;
 
 	if (offset >= 0)
-		if ((nextoffset = _fdt_check_node_offset(fdt, offset)) < 0)
+		if ((nextoffset = fdt_check_node_offset_(fdt, offset)) < 0)
 			return nextoffset;
 
 	do {
@@ -227,7 +230,7 @@
 	return offset;
 }
 
-const char *_fdt_find_string(const char *strtab, int tabsize, const char *s)
+const char *fdt_find_string_(const char *strtab, int tabsize, const char *s)
 {
 	int len = strlen(s) + 1;
 	const char *last = strtab + tabsize - len;
diff --git a/scripts/dtc/libfdt/fdt.h b/scripts/dtc/libfdt/fdt.h
index 526aedb..74961f9 100644
--- a/scripts/dtc/libfdt/fdt.h
+++ b/scripts/dtc/libfdt/fdt.h
@@ -1,5 +1,5 @@
-#ifndef _FDT_H
-#define _FDT_H
+#ifndef FDT_H
+#define FDT_H
 /*
  * libfdt - Flat Device Tree manipulation
  * Copyright (C) 2006 David Gibson, IBM Corporation.
@@ -108,4 +108,4 @@
 #define FDT_V16_SIZE	FDT_V3_SIZE
 #define FDT_V17_SIZE	(FDT_V16_SIZE + sizeof(fdt32_t))
 
-#endif /* _FDT_H */
+#endif /* FDT_H */
diff --git a/scripts/dtc/libfdt/fdt_overlay.c b/scripts/dtc/libfdt/fdt_overlay.c
index bd81241..bf75388 100644
--- a/scripts/dtc/libfdt/fdt_overlay.c
+++ b/scripts/dtc/libfdt/fdt_overlay.c
@@ -1,3 +1,54 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2016 Free Electrons
+ * Copyright (C) 2016 NextThing Co.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ *  a) This library is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This library is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *     You should have received a copy of the GNU General Public
+ *     License along with this library; if not, write to the Free
+ *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ *     MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ *  b) Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *     1. Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *     2. Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
 #include "libfdt_env.h"
 
 #include <fdt.h>
diff --git a/scripts/dtc/libfdt/fdt_ro.c b/scripts/dtc/libfdt/fdt_ro.c
index 08de2cc..dfb3236 100644
--- a/scripts/dtc/libfdt/fdt_ro.c
+++ b/scripts/dtc/libfdt/fdt_ro.c
@@ -55,12 +55,13 @@
 
 #include "libfdt_internal.h"
 
-static int _fdt_nodename_eq(const void *fdt, int offset,
+static int fdt_nodename_eq_(const void *fdt, int offset,
 			    const char *s, int len)
 {
-	const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1);
+	int olen;
+	const char *p = fdt_get_name(fdt, offset, &olen);
 
-	if (!p)
+	if (!p || olen < len)
 		/* short match */
 		return 0;
 
@@ -80,7 +81,7 @@
 	return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset;
 }
 
-static int _fdt_string_eq(const void *fdt, int stroffset,
+static int fdt_string_eq_(const void *fdt, int stroffset,
 			  const char *s, int len)
 {
 	const char *p = fdt_string(fdt, stroffset);
@@ -117,8 +118,8 @@
 int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
 {
 	FDT_CHECK_HEADER(fdt);
-	*address = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->address);
-	*size = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->size);
+	*address = fdt64_to_cpu(fdt_mem_rsv_(fdt, n)->address);
+	*size = fdt64_to_cpu(fdt_mem_rsv_(fdt, n)->size);
 	return 0;
 }
 
@@ -126,12 +127,12 @@
 {
 	int i = 0;
 
-	while (fdt64_to_cpu(_fdt_mem_rsv(fdt, i)->size) != 0)
+	while (fdt64_to_cpu(fdt_mem_rsv_(fdt, i)->size) != 0)
 		i++;
 	return i;
 }
 
-static int _nextprop(const void *fdt, int offset)
+static int nextprop_(const void *fdt, int offset)
 {
 	uint32_t tag;
 	int nextoffset;
@@ -166,7 +167,7 @@
 	     (offset >= 0) && (depth >= 0);
 	     offset = fdt_next_node(fdt, offset, &depth))
 		if ((depth == 1)
-		    && _fdt_nodename_eq(fdt, offset, name, namelen))
+		    && fdt_nodename_eq_(fdt, offset, name, namelen))
 			return offset;
 
 	if (depth < 0)
@@ -232,17 +233,35 @@
 
 const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)
 {
-	const struct fdt_node_header *nh = _fdt_offset_ptr(fdt, nodeoffset);
+	const struct fdt_node_header *nh = fdt_offset_ptr_(fdt, nodeoffset);
+	const char *nameptr;
 	int err;
 
 	if (((err = fdt_check_header(fdt)) != 0)
-	    || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0))
+	    || ((err = fdt_check_node_offset_(fdt, nodeoffset)) < 0))
 			goto fail;
 
-	if (len)
-		*len = strlen(nh->name);
+	nameptr = nh->name;
 
-	return nh->name;
+	if (fdt_version(fdt) < 0x10) {
+		/*
+		 * For old FDT versions, match the naming conventions of V16:
+		 * give only the leaf name (after all /). The actual tree
+		 * contents are loosely checked.
+		 */
+		const char *leaf;
+		leaf = strrchr(nameptr, '/');
+		if (leaf == NULL) {
+			err = -FDT_ERR_BADSTRUCTURE;
+			goto fail;
+		}
+		nameptr = leaf+1;
+	}
+
+	if (len)
+		*len = strlen(nameptr);
+
+	return nameptr;
 
  fail:
 	if (len)
@@ -254,34 +273,34 @@
 {
 	int offset;
 
-	if ((offset = _fdt_check_node_offset(fdt, nodeoffset)) < 0)
+	if ((offset = fdt_check_node_offset_(fdt, nodeoffset)) < 0)
 		return offset;
 
-	return _nextprop(fdt, offset);
+	return nextprop_(fdt, offset);
 }
 
 int fdt_next_property_offset(const void *fdt, int offset)
 {
-	if ((offset = _fdt_check_prop_offset(fdt, offset)) < 0)
+	if ((offset = fdt_check_prop_offset_(fdt, offset)) < 0)
 		return offset;
 
-	return _nextprop(fdt, offset);
+	return nextprop_(fdt, offset);
 }
 
-const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
-						      int offset,
-						      int *lenp)
+static const struct fdt_property *fdt_get_property_by_offset_(const void *fdt,
+						              int offset,
+						              int *lenp)
 {
 	int err;
 	const struct fdt_property *prop;
 
-	if ((err = _fdt_check_prop_offset(fdt, offset)) < 0) {
+	if ((err = fdt_check_prop_offset_(fdt, offset)) < 0) {
 		if (lenp)
 			*lenp = err;
 		return NULL;
 	}
 
-	prop = _fdt_offset_ptr(fdt, offset);
+	prop = fdt_offset_ptr_(fdt, offset);
 
 	if (lenp)
 		*lenp = fdt32_to_cpu(prop->len);
@@ -289,23 +308,44 @@
 	return prop;
 }
 
-const struct fdt_property *fdt_get_property_namelen(const void *fdt,
-						    int offset,
-						    const char *name,
-						    int namelen, int *lenp)
+const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
+						      int offset,
+						      int *lenp)
+{
+	/* Prior to version 16, properties may need realignment
+	 * and this API does not work. fdt_getprop_*() will, however. */
+
+	if (fdt_version(fdt) < 0x10) {
+		if (lenp)
+			*lenp = -FDT_ERR_BADVERSION;
+		return NULL;
+	}
+
+	return fdt_get_property_by_offset_(fdt, offset, lenp);
+}
+
+static const struct fdt_property *fdt_get_property_namelen_(const void *fdt,
+						            int offset,
+						            const char *name,
+						            int namelen,
+							    int *lenp,
+							    int *poffset)
 {
 	for (offset = fdt_first_property_offset(fdt, offset);
 	     (offset >= 0);
 	     (offset = fdt_next_property_offset(fdt, offset))) {
 		const struct fdt_property *prop;
 
-		if (!(prop = fdt_get_property_by_offset(fdt, offset, lenp))) {
+		if (!(prop = fdt_get_property_by_offset_(fdt, offset, lenp))) {
 			offset = -FDT_ERR_INTERNAL;
 			break;
 		}
-		if (_fdt_string_eq(fdt, fdt32_to_cpu(prop->nameoff),
-				   name, namelen))
+		if (fdt_string_eq_(fdt, fdt32_to_cpu(prop->nameoff),
+				   name, namelen)) {
+			if (poffset)
+				*poffset = offset;
 			return prop;
+		}
 	}
 
 	if (lenp)
@@ -313,6 +353,25 @@
 	return NULL;
 }
 
+
+const struct fdt_property *fdt_get_property_namelen(const void *fdt,
+						    int offset,
+						    const char *name,
+						    int namelen, int *lenp)
+{
+	/* Prior to version 16, properties may need realignment
+	 * and this API does not work. fdt_getprop_*() will, however. */
+	if (fdt_version(fdt) < 0x10) {
+		if (lenp)
+			*lenp = -FDT_ERR_BADVERSION;
+		return NULL;
+	}
+
+	return fdt_get_property_namelen_(fdt, offset, name, namelen, lenp,
+					 NULL);
+}
+
+
 const struct fdt_property *fdt_get_property(const void *fdt,
 					    int nodeoffset,
 					    const char *name, int *lenp)
@@ -324,12 +383,18 @@
 const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
 				const char *name, int namelen, int *lenp)
 {
+	int poffset;
 	const struct fdt_property *prop;
 
-	prop = fdt_get_property_namelen(fdt, nodeoffset, name, namelen, lenp);
+	prop = fdt_get_property_namelen_(fdt, nodeoffset, name, namelen, lenp,
+					 &poffset);
 	if (!prop)
 		return NULL;
 
+	/* Handle realignment */
+	if (fdt_version(fdt) < 0x10 && (poffset + sizeof(*prop)) % 8 &&
+	    fdt32_to_cpu(prop->len) >= 8)
+		return prop->data + 4;
 	return prop->data;
 }
 
@@ -338,11 +403,16 @@
 {
 	const struct fdt_property *prop;
 
-	prop = fdt_get_property_by_offset(fdt, offset, lenp);
+	prop = fdt_get_property_by_offset_(fdt, offset, lenp);
 	if (!prop)
 		return NULL;
 	if (namep)
 		*namep = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
+
+	/* Handle realignment */
+	if (fdt_version(fdt) < 0x10 && (offset + sizeof(*prop)) % 8 &&
+	    fdt32_to_cpu(prop->len) >= 8)
+		return prop->data + 4;
 	return prop->data;
 }
 
diff --git a/scripts/dtc/libfdt/fdt_rw.c b/scripts/dtc/libfdt/fdt_rw.c
index 5c3a2bb..9b82905 100644
--- a/scripts/dtc/libfdt/fdt_rw.c
+++ b/scripts/dtc/libfdt/fdt_rw.c
@@ -55,8 +55,8 @@
 
 #include "libfdt_internal.h"
 
-static int _fdt_blocks_misordered(const void *fdt,
-			      int mem_rsv_size, int struct_size)
+static int fdt_blocks_misordered_(const void *fdt,
+				  int mem_rsv_size, int struct_size)
 {
 	return (fdt_off_mem_rsvmap(fdt) < FDT_ALIGN(sizeof(struct fdt_header), 8))
 		|| (fdt_off_dt_struct(fdt) <
@@ -67,13 +67,13 @@
 		    (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt)));
 }
 
-static int _fdt_rw_check_header(void *fdt)
+static int fdt_rw_check_header_(void *fdt)
 {
 	FDT_CHECK_HEADER(fdt);
 
 	if (fdt_version(fdt) < 17)
 		return -FDT_ERR_BADVERSION;
-	if (_fdt_blocks_misordered(fdt, sizeof(struct fdt_reserve_entry),
+	if (fdt_blocks_misordered_(fdt, sizeof(struct fdt_reserve_entry),
 				   fdt_size_dt_struct(fdt)))
 		return -FDT_ERR_BADLAYOUT;
 	if (fdt_version(fdt) > 17)
@@ -84,20 +84,20 @@
 
 #define FDT_RW_CHECK_HEADER(fdt) \
 	{ \
-		int __err; \
-		if ((__err = _fdt_rw_check_header(fdt)) != 0) \
-			return __err; \
+		int err_; \
+		if ((err_ = fdt_rw_check_header_(fdt)) != 0) \
+			return err_; \
 	}
 
-static inline int _fdt_data_size(void *fdt)
+static inline int fdt_data_size_(void *fdt)
 {
 	return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
 }
 
-static int _fdt_splice(void *fdt, void *splicepoint, int oldlen, int newlen)
+static int fdt_splice_(void *fdt, void *splicepoint, int oldlen, int newlen)
 {
 	char *p = splicepoint;
-	char *end = (char *)fdt + _fdt_data_size(fdt);
+	char *end = (char *)fdt + fdt_data_size_(fdt);
 
 	if (((p + oldlen) < p) || ((p + oldlen) > end))
 		return -FDT_ERR_BADOFFSET;
@@ -109,12 +109,12 @@
 	return 0;
 }
 
-static int _fdt_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p,
+static int fdt_splice_mem_rsv_(void *fdt, struct fdt_reserve_entry *p,
 			       int oldn, int newn)
 {
 	int delta = (newn - oldn) * sizeof(*p);
 	int err;
-	err = _fdt_splice(fdt, p, oldn * sizeof(*p), newn * sizeof(*p));
+	err = fdt_splice_(fdt, p, oldn * sizeof(*p), newn * sizeof(*p));
 	if (err)
 		return err;
 	fdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + delta);
@@ -122,13 +122,13 @@
 	return 0;
 }
 
-static int _fdt_splice_struct(void *fdt, void *p,
+static int fdt_splice_struct_(void *fdt, void *p,
 			      int oldlen, int newlen)
 {
 	int delta = newlen - oldlen;
 	int err;
 
-	if ((err = _fdt_splice(fdt, p, oldlen, newlen)))
+	if ((err = fdt_splice_(fdt, p, oldlen, newlen)))
 		return err;
 
 	fdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta);
@@ -136,20 +136,20 @@
 	return 0;
 }
 
-static int _fdt_splice_string(void *fdt, int newlen)
+static int fdt_splice_string_(void *fdt, int newlen)
 {
 	void *p = (char *)fdt
 		+ fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
 	int err;
 
-	if ((err = _fdt_splice(fdt, p, 0, newlen)))
+	if ((err = fdt_splice_(fdt, p, 0, newlen)))
 		return err;
 
 	fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen);
 	return 0;
 }
 
-static int _fdt_find_add_string(void *fdt, const char *s)
+static int fdt_find_add_string_(void *fdt, const char *s)
 {
 	char *strtab = (char *)fdt + fdt_off_dt_strings(fdt);
 	const char *p;
@@ -157,13 +157,13 @@
 	int len = strlen(s) + 1;
 	int err;
 
-	p = _fdt_find_string(strtab, fdt_size_dt_strings(fdt), s);
+	p = fdt_find_string_(strtab, fdt_size_dt_strings(fdt), s);
 	if (p)
 		/* found it */
 		return (p - strtab);
 
 	new = strtab + fdt_size_dt_strings(fdt);
-	err = _fdt_splice_string(fdt, len);
+	err = fdt_splice_string_(fdt, len);
 	if (err)
 		return err;
 
@@ -178,8 +178,8 @@
 
 	FDT_RW_CHECK_HEADER(fdt);
 
-	re = _fdt_mem_rsv_w(fdt, fdt_num_mem_rsv(fdt));
-	err = _fdt_splice_mem_rsv(fdt, re, 0, 1);
+	re = fdt_mem_rsv_w_(fdt, fdt_num_mem_rsv(fdt));
+	err = fdt_splice_mem_rsv_(fdt, re, 0, 1);
 	if (err)
 		return err;
 
@@ -190,17 +190,17 @@
 
 int fdt_del_mem_rsv(void *fdt, int n)
 {
-	struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n);
+	struct fdt_reserve_entry *re = fdt_mem_rsv_w_(fdt, n);
 
 	FDT_RW_CHECK_HEADER(fdt);
 
 	if (n >= fdt_num_mem_rsv(fdt))
 		return -FDT_ERR_NOTFOUND;
 
-	return _fdt_splice_mem_rsv(fdt, re, 1, 0);
+	return fdt_splice_mem_rsv_(fdt, re, 1, 0);
 }
 
-static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name,
+static int fdt_resize_property_(void *fdt, int nodeoffset, const char *name,
 				int len, struct fdt_property **prop)
 {
 	int oldlen;
@@ -210,7 +210,7 @@
 	if (!*prop)
 		return oldlen;
 
-	if ((err = _fdt_splice_struct(fdt, (*prop)->data, FDT_TAGALIGN(oldlen),
+	if ((err = fdt_splice_struct_(fdt, (*prop)->data, FDT_TAGALIGN(oldlen),
 				      FDT_TAGALIGN(len))))
 		return err;
 
@@ -218,7 +218,7 @@
 	return 0;
 }
 
-static int _fdt_add_property(void *fdt, int nodeoffset, const char *name,
+static int fdt_add_property_(void *fdt, int nodeoffset, const char *name,
 			     int len, struct fdt_property **prop)
 {
 	int proplen;
@@ -226,17 +226,17 @@
 	int namestroff;
 	int err;
 
-	if ((nextoffset = _fdt_check_node_offset(fdt, nodeoffset)) < 0)
+	if ((nextoffset = fdt_check_node_offset_(fdt, nodeoffset)) < 0)
 		return nextoffset;
 
-	namestroff = _fdt_find_add_string(fdt, name);
+	namestroff = fdt_find_add_string_(fdt, name);
 	if (namestroff < 0)
 		return namestroff;
 
-	*prop = _fdt_offset_ptr_w(fdt, nextoffset);
+	*prop = fdt_offset_ptr_w_(fdt, nextoffset);
 	proplen = sizeof(**prop) + FDT_TAGALIGN(len);
 
-	err = _fdt_splice_struct(fdt, *prop, 0, proplen);
+	err = fdt_splice_struct_(fdt, *prop, 0, proplen);
 	if (err)
 		return err;
 
@@ -260,7 +260,7 @@
 
 	newlen = strlen(name);
 
-	err = _fdt_splice_struct(fdt, namep, FDT_TAGALIGN(oldlen+1),
+	err = fdt_splice_struct_(fdt, namep, FDT_TAGALIGN(oldlen+1),
 				 FDT_TAGALIGN(newlen+1));
 	if (err)
 		return err;
@@ -277,9 +277,9 @@
 
 	FDT_RW_CHECK_HEADER(fdt);
 
-	err = _fdt_resize_property(fdt, nodeoffset, name, len, &prop);
+	err = fdt_resize_property_(fdt, nodeoffset, name, len, &prop);
 	if (err == -FDT_ERR_NOTFOUND)
-		err = _fdt_add_property(fdt, nodeoffset, name, len, &prop);
+		err = fdt_add_property_(fdt, nodeoffset, name, len, &prop);
 	if (err)
 		return err;
 
@@ -313,7 +313,7 @@
 	prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
 	if (prop) {
 		newlen = len + oldlen;
-		err = _fdt_splice_struct(fdt, prop->data,
+		err = fdt_splice_struct_(fdt, prop->data,
 					 FDT_TAGALIGN(oldlen),
 					 FDT_TAGALIGN(newlen));
 		if (err)
@@ -321,7 +321,7 @@
 		prop->len = cpu_to_fdt32(newlen);
 		memcpy(prop->data + oldlen, val, len);
 	} else {
-		err = _fdt_add_property(fdt, nodeoffset, name, len, &prop);
+		err = fdt_add_property_(fdt, nodeoffset, name, len, &prop);
 		if (err)
 			return err;
 		memcpy(prop->data, val, len);
@@ -341,7 +341,7 @@
 		return len;
 
 	proplen = sizeof(*prop) + FDT_TAGALIGN(len);
-	return _fdt_splice_struct(fdt, prop, proplen, 0);
+	return fdt_splice_struct_(fdt, prop, proplen, 0);
 }
 
 int fdt_add_subnode_namelen(void *fdt, int parentoffset,
@@ -369,10 +369,10 @@
 		tag = fdt_next_tag(fdt, offset, &nextoffset);
 	} while ((tag == FDT_PROP) || (tag == FDT_NOP));
 
-	nh = _fdt_offset_ptr_w(fdt, offset);
+	nh = fdt_offset_ptr_w_(fdt, offset);
 	nodelen = sizeof(*nh) + FDT_TAGALIGN(namelen+1) + FDT_TAGSIZE;
 
-	err = _fdt_splice_struct(fdt, nh, 0, nodelen);
+	err = fdt_splice_struct_(fdt, nh, 0, nodelen);
 	if (err)
 		return err;
 
@@ -396,15 +396,15 @@
 
 	FDT_RW_CHECK_HEADER(fdt);
 
-	endoffset = _fdt_node_end_offset(fdt, nodeoffset);
+	endoffset = fdt_node_end_offset_(fdt, nodeoffset);
 	if (endoffset < 0)
 		return endoffset;
 
-	return _fdt_splice_struct(fdt, _fdt_offset_ptr_w(fdt, nodeoffset),
+	return fdt_splice_struct_(fdt, fdt_offset_ptr_w_(fdt, nodeoffset),
 				  endoffset - nodeoffset, 0);
 }
 
-static void _fdt_packblocks(const char *old, char *new,
+static void fdt_packblocks_(const char *old, char *new,
 			    int mem_rsv_size, int struct_size)
 {
 	int mem_rsv_off, struct_off, strings_off;
@@ -450,7 +450,7 @@
 			return struct_size;
 	}
 
-	if (!_fdt_blocks_misordered(fdt, mem_rsv_size, struct_size)) {
+	if (!fdt_blocks_misordered_(fdt, mem_rsv_size, struct_size)) {
 		/* no further work necessary */
 		err = fdt_move(fdt, buf, bufsize);
 		if (err)
@@ -478,7 +478,7 @@
 			return -FDT_ERR_NOSPACE;
 	}
 
-	_fdt_packblocks(fdt, tmp, mem_rsv_size, struct_size);
+	fdt_packblocks_(fdt, tmp, mem_rsv_size, struct_size);
 	memmove(buf, tmp, newsize);
 
 	fdt_set_magic(buf, FDT_MAGIC);
@@ -498,8 +498,8 @@
 
 	mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
 		* sizeof(struct fdt_reserve_entry);
-	_fdt_packblocks(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt));
-	fdt_set_totalsize(fdt, _fdt_data_size(fdt));
+	fdt_packblocks_(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt));
+	fdt_set_totalsize(fdt, fdt_data_size_(fdt));
 
 	return 0;
 }
diff --git a/scripts/dtc/libfdt/fdt_sw.c b/scripts/dtc/libfdt/fdt_sw.c
index 2bd15e7..6d33cc2 100644
--- a/scripts/dtc/libfdt/fdt_sw.c
+++ b/scripts/dtc/libfdt/fdt_sw.c
@@ -55,7 +55,7 @@
 
 #include "libfdt_internal.h"
 
-static int _fdt_sw_check_header(void *fdt)
+static int fdt_sw_check_header_(void *fdt)
 {
 	if (fdt_magic(fdt) != FDT_SW_MAGIC)
 		return -FDT_ERR_BADMAGIC;
@@ -66,11 +66,11 @@
 #define FDT_SW_CHECK_HEADER(fdt) \
 	{ \
 		int err; \
-		if ((err = _fdt_sw_check_header(fdt)) != 0) \
+		if ((err = fdt_sw_check_header_(fdt)) != 0) \
 			return err; \
 	}
 
-static void *_fdt_grab_space(void *fdt, size_t len)
+static void *fdt_grab_space_(void *fdt, size_t len)
 {
 	int offset = fdt_size_dt_struct(fdt);
 	int spaceleft;
@@ -82,7 +82,7 @@
 		return NULL;
 
 	fdt_set_size_dt_struct(fdt, offset + len);
-	return _fdt_offset_ptr_w(fdt, offset);
+	return fdt_offset_ptr_w_(fdt, offset);
 }
 
 int fdt_create(void *buf, int bufsize)
@@ -174,7 +174,7 @@
 
 	FDT_SW_CHECK_HEADER(fdt);
 
-	nh = _fdt_grab_space(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen));
+	nh = fdt_grab_space_(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen));
 	if (! nh)
 		return -FDT_ERR_NOSPACE;
 
@@ -189,7 +189,7 @@
 
 	FDT_SW_CHECK_HEADER(fdt);
 
-	en = _fdt_grab_space(fdt, FDT_TAGSIZE);
+	en = fdt_grab_space_(fdt, FDT_TAGSIZE);
 	if (! en)
 		return -FDT_ERR_NOSPACE;
 
@@ -197,7 +197,7 @@
 	return 0;
 }
 
-static int _fdt_find_add_string(void *fdt, const char *s)
+static int fdt_find_add_string_(void *fdt, const char *s)
 {
 	char *strtab = (char *)fdt + fdt_totalsize(fdt);
 	const char *p;
@@ -205,7 +205,7 @@
 	int len = strlen(s) + 1;
 	int struct_top, offset;
 
-	p = _fdt_find_string(strtab - strtabsize, strtabsize, s);
+	p = fdt_find_string_(strtab - strtabsize, strtabsize, s);
 	if (p)
 		return p - strtab;
 
@@ -227,11 +227,11 @@
 
 	FDT_SW_CHECK_HEADER(fdt);
 
-	nameoff = _fdt_find_add_string(fdt, name);
+	nameoff = fdt_find_add_string_(fdt, name);
 	if (nameoff == 0)
 		return -FDT_ERR_NOSPACE;
 
-	prop = _fdt_grab_space(fdt, sizeof(*prop) + FDT_TAGALIGN(len));
+	prop = fdt_grab_space_(fdt, sizeof(*prop) + FDT_TAGALIGN(len));
 	if (! prop)
 		return -FDT_ERR_NOSPACE;
 
@@ -265,7 +265,7 @@
 	FDT_SW_CHECK_HEADER(fdt);
 
 	/* Add terminator */
-	end = _fdt_grab_space(fdt, sizeof(*end));
+	end = fdt_grab_space_(fdt, sizeof(*end));
 	if (! end)
 		return -FDT_ERR_NOSPACE;
 	*end = cpu_to_fdt32(FDT_END);
@@ -281,7 +281,7 @@
 	while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) {
 		if (tag == FDT_PROP) {
 			struct fdt_property *prop =
-				_fdt_offset_ptr_w(fdt, offset);
+				fdt_offset_ptr_w_(fdt, offset);
 			int nameoff;
 
 			nameoff = fdt32_to_cpu(prop->nameoff);
diff --git a/scripts/dtc/libfdt/fdt_wip.c b/scripts/dtc/libfdt/fdt_wip.c
index 5e85919..534c1cb 100644
--- a/scripts/dtc/libfdt/fdt_wip.c
+++ b/scripts/dtc/libfdt/fdt_wip.c
@@ -93,7 +93,7 @@
 						   val, len);
 }
 
-static void _fdt_nop_region(void *start, int len)
+static void fdt_nop_region_(void *start, int len)
 {
 	fdt32_t *p;
 
@@ -110,12 +110,12 @@
 	if (!prop)
 		return len;
 
-	_fdt_nop_region(prop, len + sizeof(*prop));
+	fdt_nop_region_(prop, len + sizeof(*prop));
 
 	return 0;
 }
 
-int _fdt_node_end_offset(void *fdt, int offset)
+int fdt_node_end_offset_(void *fdt, int offset)
 {
 	int depth = 0;
 
@@ -129,11 +129,11 @@
 {
 	int endoffset;
 
-	endoffset = _fdt_node_end_offset(fdt, nodeoffset);
+	endoffset = fdt_node_end_offset_(fdt, nodeoffset);
 	if (endoffset < 0)
 		return endoffset;
 
-	_fdt_nop_region(fdt_offset_ptr_w(fdt, nodeoffset, 0),
+	fdt_nop_region_(fdt_offset_ptr_w(fdt, nodeoffset, 0),
 			endoffset - nodeoffset);
 	return 0;
 }
diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h
index 7f83023..1e27780 100644
--- a/scripts/dtc/libfdt/libfdt.h
+++ b/scripts/dtc/libfdt/libfdt.h
@@ -1,5 +1,5 @@
-#ifndef _LIBFDT_H
-#define _LIBFDT_H
+#ifndef LIBFDT_H
+#define LIBFDT_H
 /*
  * libfdt - Flat Device Tree manipulation
  * Copyright (C) 2006 David Gibson, IBM Corporation.
@@ -54,7 +54,7 @@
 #include "libfdt_env.h"
 #include "fdt.h"
 
-#define FDT_FIRST_SUPPORTED_VERSION	0x10
+#define FDT_FIRST_SUPPORTED_VERSION	0x02
 #define FDT_LAST_SUPPORTED_VERSION	0x11
 
 /* Error codes: informative error codes */
@@ -225,23 +225,23 @@
 #define fdt_size_dt_strings(fdt)	(fdt_get_header(fdt, size_dt_strings))
 #define fdt_size_dt_struct(fdt)		(fdt_get_header(fdt, size_dt_struct))
 
-#define __fdt_set_hdr(name) \
+#define fdt_set_hdr_(name) \
 	static inline void fdt_set_##name(void *fdt, uint32_t val) \
 	{ \
 		struct fdt_header *fdth = (struct fdt_header *)fdt; \
 		fdth->name = cpu_to_fdt32(val); \
 	}
-__fdt_set_hdr(magic);
-__fdt_set_hdr(totalsize);
-__fdt_set_hdr(off_dt_struct);
-__fdt_set_hdr(off_dt_strings);
-__fdt_set_hdr(off_mem_rsvmap);
-__fdt_set_hdr(version);
-__fdt_set_hdr(last_comp_version);
-__fdt_set_hdr(boot_cpuid_phys);
-__fdt_set_hdr(size_dt_strings);
-__fdt_set_hdr(size_dt_struct);
-#undef __fdt_set_hdr
+fdt_set_hdr_(magic);
+fdt_set_hdr_(totalsize);
+fdt_set_hdr_(off_dt_struct);
+fdt_set_hdr_(off_dt_strings);
+fdt_set_hdr_(off_mem_rsvmap);
+fdt_set_hdr_(version);
+fdt_set_hdr_(last_comp_version);
+fdt_set_hdr_(boot_cpuid_phys);
+fdt_set_hdr_(size_dt_strings);
+fdt_set_hdr_(size_dt_struct);
+#undef fdt_set_hdr_
 
 /**
  * fdt_check_header - sanity check a device tree or possible device tree
@@ -527,6 +527,9 @@
  * offset.  If lenp is non-NULL, the length of the property value is
  * also returned, in the integer pointed to by lenp.
  *
+ * Note that this code only works on device tree versions >= 16. fdt_getprop()
+ * works on all versions.
+ *
  * returns:
  *	pointer to the structure representing the property
  *		if lenp is non-NULL, *lenp contains the length of the property
@@ -1449,7 +1452,7 @@
 		const void *val, int len);
 
 /**
- * fdt_setprop _placeholder - allocate space for a property
+ * fdt_setprop_placeholder - allocate space for a property
  * @fdt: pointer to the device tree blob
  * @nodeoffset: offset of the node whose property to change
  * @name: name of the property to change
@@ -1896,4 +1899,4 @@
 
 const char *fdt_strerror(int errval);
 
-#endif /* _LIBFDT_H */
+#endif /* LIBFDT_H */
diff --git a/scripts/dtc/libfdt/libfdt_env.h b/scripts/dtc/libfdt/libfdt_env.h
index 952056c..bd24746 100644
--- a/scripts/dtc/libfdt/libfdt_env.h
+++ b/scripts/dtc/libfdt/libfdt_env.h
@@ -1,5 +1,5 @@
-#ifndef _LIBFDT_ENV_H
-#define _LIBFDT_ENV_H
+#ifndef LIBFDT_ENV_H
+#define LIBFDT_ENV_H
 /*
  * libfdt - Flat Device Tree manipulation
  * Copyright (C) 2006 David Gibson, IBM Corporation.
@@ -109,4 +109,31 @@
 #undef CPU_TO_FDT16
 #undef EXTRACT_BYTE
 
-#endif /* _LIBFDT_ENV_H */
+#ifdef __APPLE__
+#include <AvailabilityMacros.h>
+
+/* strnlen() is not available on Mac OS < 10.7 */
+# if !defined(MAC_OS_X_VERSION_10_7) || (MAC_OS_X_VERSION_MAX_ALLOWED < \
+                                         MAC_OS_X_VERSION_10_7)
+
+#define strnlen fdt_strnlen
+
+/*
+ * fdt_strnlen: returns the length of a string or max_count - which ever is
+ * smallest.
+ * Input 1 string: the string whose size is to be determined
+ * Input 2 max_count: the maximum value returned by this function
+ * Output: length of the string or max_count (the smallest of the two)
+ */
+static inline size_t fdt_strnlen(const char *string, size_t max_count)
+{
+    const char *p = memchr(string, 0, max_count);
+    return p ? p - string : max_count;
+}
+
+#endif /* !defined(MAC_OS_X_VERSION_10_7) || (MAC_OS_X_VERSION_MAX_ALLOWED <
+          MAC_OS_X_VERSION_10_7) */
+
+#endif /* __APPLE__ */
+
+#endif /* LIBFDT_ENV_H */
diff --git a/scripts/dtc/libfdt/libfdt_internal.h b/scripts/dtc/libfdt/libfdt_internal.h
index 02cfa6f..7681e19 100644
--- a/scripts/dtc/libfdt/libfdt_internal.h
+++ b/scripts/dtc/libfdt/libfdt_internal.h
@@ -1,5 +1,5 @@
-#ifndef _LIBFDT_INTERNAL_H
-#define _LIBFDT_INTERNAL_H
+#ifndef LIBFDT_INTERNAL_H
+#define LIBFDT_INTERNAL_H
 /*
  * libfdt - Flat Device Tree manipulation
  * Copyright (C) 2006 David Gibson, IBM Corporation.
@@ -57,27 +57,27 @@
 
 #define FDT_CHECK_HEADER(fdt) \
 	{ \
-		int __err; \
-		if ((__err = fdt_check_header(fdt)) != 0) \
-			return __err; \
+		int err_; \
+		if ((err_ = fdt_check_header(fdt)) != 0) \
+			return err_; \
 	}
 
-int _fdt_check_node_offset(const void *fdt, int offset);
-int _fdt_check_prop_offset(const void *fdt, int offset);
-const char *_fdt_find_string(const char *strtab, int tabsize, const char *s);
-int _fdt_node_end_offset(void *fdt, int nodeoffset);
+int fdt_check_node_offset_(const void *fdt, int offset);
+int fdt_check_prop_offset_(const void *fdt, int offset);
+const char *fdt_find_string_(const char *strtab, int tabsize, const char *s);
+int fdt_node_end_offset_(void *fdt, int nodeoffset);
 
-static inline const void *_fdt_offset_ptr(const void *fdt, int offset)
+static inline const void *fdt_offset_ptr_(const void *fdt, int offset)
 {
 	return (const char *)fdt + fdt_off_dt_struct(fdt) + offset;
 }
 
-static inline void *_fdt_offset_ptr_w(void *fdt, int offset)
+static inline void *fdt_offset_ptr_w_(void *fdt, int offset)
 {
-	return (void *)(uintptr_t)_fdt_offset_ptr(fdt, offset);
+	return (void *)(uintptr_t)fdt_offset_ptr_(fdt, offset);
 }
 
-static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int n)
+static inline const struct fdt_reserve_entry *fdt_mem_rsv_(const void *fdt, int n)
 {
 	const struct fdt_reserve_entry *rsv_table =
 		(const struct fdt_reserve_entry *)
@@ -85,11 +85,11 @@
 
 	return rsv_table + n;
 }
-static inline struct fdt_reserve_entry *_fdt_mem_rsv_w(void *fdt, int n)
+static inline struct fdt_reserve_entry *fdt_mem_rsv_w_(void *fdt, int n)
 {
-	return (void *)(uintptr_t)_fdt_mem_rsv(fdt, n);
+	return (void *)(uintptr_t)fdt_mem_rsv_(fdt, n);
 }
 
 #define FDT_SW_MAGIC		(~FDT_MAGIC)
 
-#endif /* _LIBFDT_INTERNAL_H */
+#endif /* LIBFDT_INTERNAL_H */
diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c
index 6846ad2..57b7db2 100644
--- a/scripts/dtc/livetree.c
+++ b/scripts/dtc/livetree.c
@@ -216,7 +216,7 @@
 	return old_node;
 }
 
-void add_orphan_node(struct node *dt, struct node *new_node, char *ref)
+struct node * add_orphan_node(struct node *dt, struct node *new_node, char *ref)
 {
 	static unsigned int next_orphan_fragment = 0;
 	struct node *node;
@@ -236,6 +236,7 @@
 	name_node(node, name);
 
 	add_child(dt, node);
+	return dt;
 }
 
 struct node *chain_node(struct node *first, struct node *list)
@@ -507,7 +508,7 @@
 
 	for_each_child(tree, child) {
 		if (p && (strlen(child->name) == p-path) &&
-				strneq(path, child->name, p-path))
+		    strprefixeq(path, p - path, child->name))
 			return get_node_by_path(child, p+1);
 		else if (!p && streq(path, child->name))
 			return child;
@@ -540,7 +541,10 @@
 {
 	struct node *child, *node;
 
-	assert((phandle != 0) && (phandle != -1));
+	if ((phandle == 0) || (phandle == -1)) {
+		assert(generate_fixups);
+		return NULL;
+	}
 
 	if (tree->phandle == phandle) {
 		if (tree->deleted)
diff --git a/scripts/dtc/srcpos.c b/scripts/dtc/srcpos.c
index 9d38459..cb6ed0e 100644
--- a/scripts/dtc/srcpos.c
+++ b/scripts/dtc/srcpos.c
@@ -209,8 +209,6 @@
 	.file = NULL,
 };
 
-#define TAB_SIZE      8
-
 void srcpos_update(struct srcpos *pos, const char *text, int len)
 {
 	int i;
@@ -224,9 +222,6 @@
 		if (text[i] == '\n') {
 			current_srcfile->lineno++;
 			current_srcfile->colno = 1;
-		} else if (text[i] == '\t') {
-			current_srcfile->colno =
-				ALIGN(current_srcfile->colno, TAB_SIZE);
 		} else {
 			current_srcfile->colno++;
 		}
diff --git a/scripts/dtc/srcpos.h b/scripts/dtc/srcpos.h
index 7caca82..9ded12a 100644
--- a/scripts/dtc/srcpos.h
+++ b/scripts/dtc/srcpos.h
@@ -17,8 +17,8 @@
  *                                                                   USA
  */
 
-#ifndef _SRCPOS_H_
-#define _SRCPOS_H_
+#ifndef SRCPOS_H
+#define SRCPOS_H
 
 #include <stdio.h>
 #include <stdbool.h>
@@ -114,4 +114,4 @@
 
 extern void srcpos_set_line(char *f, int l);
 
-#endif /* _SRCPOS_H_ */
+#endif /* SRCPOS_H */
diff --git a/scripts/dtc/update-dtc-source.sh b/scripts/dtc/update-dtc-source.sh
index f3e5c59..1a009fd 100755
--- a/scripts/dtc/update-dtc-source.sh
+++ b/scripts/dtc/update-dtc-source.sh
@@ -1,9 +1,10 @@
 #!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
 # Simple script to update the version of DTC carried by the Linux kernel
 #
 # This script assumes that the dtc and the linux git trees are in the
 # same directory. After building dtc in the dtc directory, it copies the
-# source files and generated source files into the scripts/dtc directory
+# source files and generated source file(s) into the scripts/dtc directory
 # in the kernel and creates a git commit updating them to the new
 # version.
 #
@@ -33,7 +34,6 @@
 DTC_SOURCE="checks.c data.c dtc.c dtc.h flattree.c fstree.c livetree.c srcpos.c \
 		srcpos.h treesource.c util.c util.h version_gen.h Makefile.dtc \
 		dtc-lexer.l dtc-parser.y"
-DTC_GENERATED="dtc-lexer.lex.c dtc-parser.tab.c dtc-parser.tab.h"
 LIBFDT_SOURCE="Makefile.libfdt fdt.c fdt.h fdt_addresses.c fdt_empty_tree.c \
 		fdt_overlay.c fdt_ro.c fdt_rw.c fdt_strerror.c fdt_sw.c \
 		fdt_wip.c libfdt.h libfdt_env.h libfdt_internal.h"
@@ -58,10 +58,6 @@
 	cp ${DTC_UPSTREAM_PATH}/${f} ${f}
 	git add ${f}
 done
-for f in $DTC_GENERATED; do
-	cp ${DTC_UPSTREAM_PATH}/$f ${f}_shipped
-	git add ${f}_shipped
-done
 for f in $LIBFDT_SOURCE; do
        cp ${DTC_UPSTREAM_PATH}/libfdt/${f} libfdt/${f}
        git add libfdt/${f}
diff --git a/scripts/dtc/util.h b/scripts/dtc/util.h
index ad5f411..66fba8e 100644
--- a/scripts/dtc/util.h
+++ b/scripts/dtc/util.h
@@ -1,5 +1,5 @@
-#ifndef _UTIL_H
-#define _UTIL_H
+#ifndef UTIL_H
+#define UTIL_H
 
 #include <stdarg.h>
 #include <stdbool.h>
@@ -35,6 +35,9 @@
 
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
 
+#define stringify(s)	stringify_(s)
+#define stringify_(s)	#s
+
 static inline void NORETURN PRINTF(1, 2) die(const char *str, ...)
 {
 	va_list ap;
@@ -260,4 +263,4 @@
 	case 'V': util_version(); \
 	case '?': usage("unknown option");
 
-#endif /* _UTIL_H */
+#endif /* UTIL_H */
diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h
index d88393c..ad87849 100644
--- a/scripts/dtc/version_gen.h
+++ b/scripts/dtc/version_gen.h
@@ -1 +1 @@
-#define DTC_VERSION "DTC 1.4.5-gb1a60033"
+#define DTC_VERSION "DTC 1.4.6-gaadd0b65"
diff --git a/scripts/kconfig/.gitignore b/scripts/kconfig/.gitignore
index be603c4..2da579e 100644
--- a/scripts/kconfig/.gitignore
+++ b/scripts/kconfig/.gitignore
@@ -1,11 +1,6 @@
 #
 # Generated files
 #
-config*
-*.lex.c
-*.tab.c
-*.tab.h
-zconf.hash.c
 *.moc
 gconf.glade.h
 *.pot
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 2542b38..8b7b349 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -3,7 +3,7 @@
 # Kernel configuration targets
 # These targets are used from top-level makefile
 
-PHONY += xconfig gconfig menuconfig config silentoldconfig update-po-config \
+PHONY += xconfig gconfig menuconfig config syncconfig update-po-config \
 	localmodconfig localyesconfig
 
 # Added for U-Boot
@@ -40,24 +40,24 @@
 nconfig: $(obj)/nconf
 	$< $(silent) $(Kconfig)
 
-silentoldconfig: $(obj)/conf
+# This has become an internal implementation detail and is now deprecated
+# for external use.
+syncconfig: $(obj)/conf
 	$(Q)mkdir -p include/config include/generated
-	$(Q)test -e include/generated/autoksyms.h || \
-	    touch   include/generated/autoksyms.h
 	$< $(silent) --$@ $(Kconfig)
 
-localyesconfig localmodconfig: $(obj)/streamline_config.pl $(obj)/conf
+localyesconfig localmodconfig: $(obj)/conf
 	$(Q)mkdir -p include/config include/generated
-	$(Q)perl $< --$@ $(srctree) $(Kconfig) > .tmp.config
+	$(Q)perl $(srctree)/$(src)/streamline_config.pl --$@ $(srctree) $(Kconfig) > .tmp.config
 	$(Q)if [ -f .config ]; then 					\
 			cmp -s .tmp.config .config ||			\
 			(mv -f .config .config.old.1;			\
 			 mv -f .tmp.config .config;			\
-			 $(obj)/conf $(silent) --silentoldconfig $(Kconfig); \
+			 $< $(silent) --oldconfig $(Kconfig);		\
 			 mv -f .config.old.1 .config.old)		\
 	else								\
 			mv -f .tmp.config .config;			\
-			$(obj)/conf $(silent) --silentoldconfig $(Kconfig); \
+			$< $(silent) --oldconfig $(Kconfig);		\
 	fi
 	$(Q)rm -f .tmp.config
 
@@ -92,12 +92,21 @@
 $(simple-targets): $(obj)/conf
 	$< $(silent) --$@ $(Kconfig)
 
-PHONY += oldnoconfig savedefconfig defconfig
+PHONY += oldnoconfig silentoldconfig savedefconfig defconfig
 
 # oldnoconfig is an alias of olddefconfig, because people already are dependent
 # on its behavior (sets new symbols to their default value but not 'n') with the
 # counter-intuitive name.
 oldnoconfig: olddefconfig
+	@echo "  WARNING: \"oldnoconfig\" target will be removed after Linux 4.19"
+	@echo "            Please use \"olddefconfig\" instead, which is an alias."
+
+# We do not expect manual invokcation of "silentoldcofig" (or "syncconfig").
+silentoldconfig: syncconfig
+	@echo "  WARNING: \"silentoldconfig\" has been renamed to \"syncconfig\""
+	@echo "            and is now an internal implementation detail."
+	@echo "            What you want is probably \"oldconfig\"."
+	@echo "            \"silentoldconfig\" will be removed after Linux 4.19"
 
 savedefconfig: $(obj)/conf
 	$< $(silent) --$@=defconfig $(Kconfig)
@@ -141,6 +150,14 @@
 tinyconfig:
 	$(Q)$(MAKE) -f $(srctree)/Makefile allnoconfig tiny.config
 
+# CHECK: -o cache_dir=<path> working?
+PHONY += testconfig
+testconfig: $(obj)/conf
+	$(PYTHON3) -B -m pytest $(srctree)/$(src)/tests \
+	-o cache_dir=$(abspath $(obj)/tests/.cache) \
+	$(if $(findstring 1,$(KBUILD_VERBOSE)),--capture=no)
+clean-dirs += tests/.cache
+
 # Help text used by make help
 help:
 	@echo  '  config	  - Update current config utilising a line-oriented program'
@@ -152,7 +169,6 @@
 	@echo  '  oldconfig	  - Update current config utilising a provided .config as base'
 	@echo  '  localmodconfig  - Update current config disabling modules not loaded'
 	@echo  '  localyesconfig  - Update current config converting local mods to core'
-	@echo  '  silentoldconfig - Same as oldconfig, but quietly, additionally update deps'
 	@echo  '  defconfig	  - New config with default from ARCH supplied defconfig'
 	@echo  '  savedefconfig   - Save current config as ./defconfig (minimal config)'
 	@echo  '  allnoconfig	  - New config where all options are answered with no'
@@ -161,8 +177,8 @@
 	@echo  '  alldefconfig    - New config with all symbols set to default'
 	@echo  '  randconfig	  - New config with random answer to all options'
 	@echo  '  listnewconfig   - List new options'
-	@echo  '  olddefconfig	  - Same as silentoldconfig but sets new symbols to their'
-	@echo  '                    default value'
+	@echo  '  olddefconfig	  - Same as oldconfig but sets new symbols to their'
+	@echo  '                    default value without prompting'
 #	@echo  '  kvmconfig	  - Enable additional options for kvm guest kernel support'
 #	@echo  '  xenconfig       - Enable additional options for xen dom0 and guest kernel support'
 #	@echo  '  tinyconfig	  - Configure the tiniest possible kernel'
@@ -201,13 +217,14 @@
 
 hostprogs-y := conf nconf mconf kxgettext qconf gconf
 
+targets		+= zconf.lex.c
 clean-files	:= qconf.moc .tmp_qtcheck .tmp_gtkcheck
-clean-files	+= zconf.tab.c zconf.lex.c zconf.hash.c gconf.glade.h
+clean-files	+= gconf.glade.h
 clean-files     += config.pot linux.pot
 
 # Check that we have the required ncurses stuff installed for lxdialog (menuconfig)
 PHONY += $(obj)/dochecklxdialog
-$(addprefix $(obj)/,$(lxdialog)): $(obj)/dochecklxdialog
+$(addprefix $(obj)/, mconf.o $(lxdialog)): $(obj)/dochecklxdialog
 $(obj)/dochecklxdialog:
 	$(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTLOADLIBES_mconf)
 
@@ -215,14 +232,12 @@
 
 # Add environment specific flags
 HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(srctree)/$(src)/check.sh $(HOSTCC) $(HOSTCFLAGS))
+HOST_EXTRACXXFLAGS += $(shell $(CONFIG_SHELL) $(srctree)/$(src)/check.sh $(HOSTCXX) $(HOSTCXXFLAGS))
 
 # generated files seem to need this to find local include files
 HOSTCFLAGS_zconf.lex.o	:= -I$(src)
 HOSTCFLAGS_zconf.tab.o	:= -I$(src)
 
-LEX_PREFIX_zconf	:= zconf
-YACC_PREFIX_zconf	:= zconf
-
 HOSTLOADLIBES_qconf	= $(KC_QT_LIBS)
 HOSTCXXFLAGS_qconf.o	= $(KC_QT_CFLAGS)
 
@@ -291,7 +306,7 @@
 	fi
 endif
 
-$(obj)/zconf.tab.o: $(obj)/zconf.lex.c $(obj)/zconf.hash.c
+$(obj)/zconf.tab.o: $(obj)/zconf.lex.c
 
 $(obj)/qconf.o: $(obj)/qconf.moc
 
diff --git a/scripts/kconfig/check.sh b/scripts/kconfig/check.sh
index 55b79ba..97f0fee 100755
--- a/scripts/kconfig/check.sh
+++ b/scripts/kconfig/check.sh
@@ -1,4 +1,5 @@
 #!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
 # Needed for systems without gettext
 $* -x c -o /dev/null - > /dev/null 2>&1 << EOF
 #include <libintl.h>
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index 866369f..283eeed 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -20,11 +20,10 @@
 
 static void conf(struct menu *menu);
 static void check_conf(struct menu *menu);
-static void xfgets(char *str, int size, FILE *in);
 
 enum input_mode {
 	oldaskconfig,
-	silentoldconfig,
+	syncconfig,
 	oldconfig,
 	allnoconfig,
 	allyesconfig,
@@ -35,11 +34,11 @@
 	savedefconfig,
 	listnewconfig,
 	olddefconfig,
-} input_mode = oldaskconfig;
+};
+static enum input_mode input_mode = oldaskconfig;
 
 static int indent = 1;
 static int tty_stdio;
-static int valid_stdin = 1;
 static int sync_kconfig;
 static int conf_cnt;
 static char line[PATH_MAX];
@@ -72,14 +71,14 @@
 		*p-- = 0;
 }
 
-static void check_stdin(void)
+/* Helper function to facilitate fgets() by Jean Sacren. */
+static void xfgets(char *str, int size, FILE *in)
 {
-	if (!valid_stdin) {
-		printf(_("aborted!\n\n"));
-		printf(_("Console input/output is redirected. "));
-		printf(_("Run 'make oldconfig' to update configuration.\n\n"));
-		exit(1);
-	}
+	if (!fgets(str, size, in))
+		fprintf(stderr, "\nError in reading or end of file.\n");
+
+	if (!tty_stdio)
+		printf("%s", str);
 }
 
 static int conf_askvalue(struct symbol *sym, const char *def)
@@ -101,18 +100,15 @@
 
 	switch (input_mode) {
 	case oldconfig:
-	case silentoldconfig:
+	case syncconfig:
 		if (sym_has_value(sym)) {
 			printf("%s\n", def);
 			return 0;
 		}
-		check_stdin();
 		/* fall through */
 	case oldaskconfig:
 		fflush(stdout);
 		xfgets(line, sizeof(line), stdin);
-		if (!tty_stdio)
-			printf("\n");
 		return 1;
 	default:
 		break;
@@ -192,9 +188,7 @@
 			printf("/m");
 		if (oldval != yes && sym_tristate_within_range(sym, yes))
 			printf("/y");
-		if (menu_has_help(menu))
-			printf("/?");
-		printf("] ");
+		printf("/?] ");
 		if (!conf_askvalue(sym, sym_get_string_value(sym)))
 			return 0;
 		strip(line);
@@ -296,19 +290,15 @@
 			printf("[1]: 1\n");
 			goto conf_childs;
 		}
-		printf("[1-%d", cnt);
-		if (menu_has_help(menu))
-			printf("?");
-		printf("]: ");
+		printf("[1-%d?]: ", cnt);
 		switch (input_mode) {
 		case oldconfig:
-		case silentoldconfig:
+		case syncconfig:
 			if (!is_new) {
 				cnt = def;
 				printf("%d\n", cnt);
 				break;
 			}
-			check_stdin();
 			/* fall through */
 		case oldaskconfig:
 			fflush(stdout);
@@ -368,10 +358,11 @@
 
 		switch (prop->type) {
 		case P_MENU:
-			if ((input_mode == silentoldconfig ||
-			     input_mode == listnewconfig ||
-			     input_mode == olddefconfig) &&
-			    rootEntry != menu) {
+			/*
+			 * Except in oldaskconfig mode, we show only menus that
+			 * contain new symbols.
+			 */
+			if (input_mode != oldaskconfig && rootEntry != menu) {
 				check_conf(menu);
 				return;
 			}
@@ -431,10 +422,20 @@
 		if (sym_is_changable(sym) ||
 		    (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
 			if (input_mode == listnewconfig) {
-				if (sym->name && !sym_is_choice_value(sym)) {
-					printf("%s%s\n", CONFIG_, sym->name);
+				if (sym->name) {
+					const char *str;
+
+					if (sym->type == S_STRING) {
+						str = sym_get_string_value(sym);
+						str = sym_escape_string_value(str);
+						printf("%s%s=%s\n", CONFIG_, sym->name, str);
+						free((void *)str);
+					} else {
+						str = sym_get_string_value(sym);
+						printf("%s%s=%s\n", CONFIG_, sym->name, str);
+					}
 				}
-			} else if (input_mode != olddefconfig) {
+			} else {
 				if (!conf_cnt++)
 					printf(_("*\n* Restart config...\n*\n"));
 				rootEntry = menu_get_parent_menu(menu);
@@ -450,7 +451,7 @@
 static struct option long_opts[] = {
 	{"oldaskconfig",    no_argument,       NULL, oldaskconfig},
 	{"oldconfig",       no_argument,       NULL, oldconfig},
-	{"silentoldconfig", no_argument,       NULL, silentoldconfig},
+	{"syncconfig",      no_argument,       NULL, syncconfig},
 	{"defconfig",       optional_argument, NULL, defconfig},
 	{"savedefconfig",   required_argument, NULL, savedefconfig},
 	{"allnoconfig",     no_argument,       NULL, allnoconfig},
@@ -477,8 +478,9 @@
 	printf("  --listnewconfig         List new options\n");
 	printf("  --oldaskconfig          Start a new configuration using a line-oriented program\n");
 	printf("  --oldconfig             Update a configuration using a provided .config as base\n");
-	printf("  --silentoldconfig       Same as oldconfig, but quietly, additionally update deps\n");
-	printf("  --olddefconfig          Same as silentoldconfig but sets new symbols to their default value\n");
+	printf("  --syncconfig            Similar to oldconfig but generates configuration in\n"
+	       "                          include/{generated/,config/}\n");
+	printf("  --olddefconfig          Same as oldconfig but sets new symbols to their default value\n");
 	printf("  --oldnoconfig           An alias of olddefconfig\n");
 	printf("  --defconfig <file>      New config with default defined in <file>\n");
 	printf("  --savedefconfig <file>  Save the minimal current configuration to <file>\n");
@@ -500,7 +502,7 @@
 	bindtextdomain(PACKAGE, LOCALEDIR);
 	textdomain(PACKAGE);
 
-	tty_stdio = isatty(0) && isatty(1) && isatty(2);
+	tty_stdio = isatty(0) && isatty(1);
 
 	while ((opt = getopt_long(ac, av, "s", long_opts, NULL)) != -1) {
 		if (opt == 's') {
@@ -509,7 +511,7 @@
 		}
 		input_mode = (enum input_mode)opt;
 		switch (opt) {
-		case silentoldconfig:
+		case syncconfig:
 			sync_kconfig = 1;
 			break;
 		case defconfig:
@@ -557,7 +559,7 @@
 		}
 	}
 	if (ac == optind) {
-		printf(_("%s: Kconfig file missing\n"), av[0]);
+		fprintf(stderr, _("%s: Kconfig file missing\n"), av[0]);
 		conf_usage(progname);
 		exit(1);
 	}
@@ -582,14 +584,16 @@
 		if (!defconfig_file)
 			defconfig_file = conf_get_default_confname();
 		if (conf_read(defconfig_file)) {
-			printf(_("***\n"
-				"*** Can't find default configuration \"%s\"!\n"
-				"***\n"), defconfig_file);
+			fprintf(stderr,
+				_("***\n"
+				  "*** Can't find default configuration \"%s\"!\n"
+				  "***\n"),
+				defconfig_file);
 			exit(1);
 		}
 		break;
 	case savedefconfig:
-	case silentoldconfig:
+	case syncconfig:
 	case oldaskconfig:
 	case oldconfig:
 	case listnewconfig:
@@ -642,7 +646,6 @@
 				return 1;
 			}
 		}
-		valid_stdin = tty_stdio;
 	}
 
 	switch (input_mode) {
@@ -670,24 +673,24 @@
 	case oldaskconfig:
 		rootEntry = &rootmenu;
 		conf(&rootmenu);
-		input_mode = silentoldconfig;
+		input_mode = oldconfig;
 		/* fall through */
 	case oldconfig:
 	case listnewconfig:
-	case olddefconfig:
-	case silentoldconfig:
+	case syncconfig:
 		/* Update until a loop caused no more changes */
 		do {
 			conf_cnt = 0;
 			check_conf(&rootmenu);
-		} while (conf_cnt &&
-			 (input_mode != listnewconfig &&
-			  input_mode != olddefconfig));
+		} while (conf_cnt);
+		break;
+	case olddefconfig:
+	default:
 		break;
 	}
 
 	if (sync_kconfig) {
-		/* silentoldconfig is used during the build so we shall update autoconf.
+		/* syncconfig is used during the build so we shall update autoconf.
 		 * All other commands are only used to generate a config.
 		 */
 		if (conf_get_changed() && conf_write(NULL)) {
@@ -712,12 +715,3 @@
 	}
 	return 0;
 }
-
-/*
- * Helper function to facilitate fgets() by Jean Sacren.
- */
-void xfgets(char *str, int size, FILE *in)
-{
-	if (fgets(str, size, in) == NULL)
-		fprintf(stderr, "\nError in reading or end of file.\n");
-}
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 745cb93..e4cbb87 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -28,7 +28,7 @@
 	__attribute__ ((format (printf, 1, 2)));
 
 static const char *conf_filename;
-static int conf_lineno, conf_warnings, conf_unsaved;
+static int conf_lineno, conf_warnings;
 
 const char conf_defname[] = "arch/$ARCH/defconfig";
 
@@ -174,7 +174,7 @@
 	case S_HEX:
 	done:
 		if (sym_string_valid(sym, p)) {
-			sym->def[def].val = strdup(p);
+			sym->def[def].val = xstrdup(p);
 			sym->flags |= def_flags;
 		} else {
 			if (def != S_DEF_AUTO)
@@ -197,7 +197,7 @@
 	if (new_size > *n) {
 		new_size += LINE_GROWTH - 1;
 		new_size *= 2;
-		nline = realloc(*lineptr, new_size);
+		nline = xrealloc(*lineptr, new_size);
 		if (!nline)
 			return -1;
 
@@ -286,7 +286,6 @@
 	conf_filename = name;
 	conf_lineno = 0;
 	conf_warnings = 0;
-	conf_unsaved = 0;
 
 	def_flags = SYMBOL_DEF << def;
 	for_all_symbols(i, sym) {
@@ -405,6 +404,7 @@
 int conf_read(const char *name)
 {
 	struct symbol *sym;
+	int conf_unsaved = 0;
 	int i;
 
 	sym_set_change_count(0);
@@ -1121,7 +1121,7 @@
 bool conf_set_all_new_symbols(enum conf_def_mode mode)
 {
 	struct symbol *sym, *csym;
-	int i, cnt, pby, pty, ptm;	/* pby: probability of boolean  = y
+	int i, cnt, pby, pty, ptm;	/* pby: probability of bool     = y
 					 * pty: probability of tristate = y
 					 * ptm: probability of tristate = m
 					 */
diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c
index cbf4996..e1a39e9 100644
--- a/scripts/kconfig/expr.c
+++ b/scripts/kconfig/expr.c
@@ -94,7 +94,7 @@
 		e->right.expr = expr_copy(org->right.expr);
 		break;
 	default:
-		printf("can't copy type %d\n", e->type);
+		fprintf(stderr, "can't copy type %d\n", e->type);
 		free(e);
 		e = NULL;
 		break;
@@ -113,7 +113,7 @@
 		break;
 	case E_NOT:
 		expr_free(e->left.expr);
-		return;
+		break;
 	case E_EQUAL:
 	case E_GEQ:
 	case E_GTH:
@@ -127,7 +127,7 @@
 		expr_free(e->right.expr);
 		break;
 	default:
-		printf("how to free type %d?\n", e->type);
+		fprintf(stderr, "how to free type %d?\n", e->type);
 		break;
 	}
 	free(e);
@@ -138,8 +138,18 @@
 #define e1 (*ep1)
 #define e2 (*ep2)
 
+/*
+ * expr_eliminate_eq() helper.
+ *
+ * Walks the two expression trees given in 'ep1' and 'ep2'. Any node that does
+ * not have type 'type' (E_OR/E_AND) is considered a leaf, and is compared
+ * against all other leaves. Two equal leaves are both replaced with either 'y'
+ * or 'n' as appropriate for 'type', to be eliminated later.
+ */
 static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2)
 {
+	/* Recurse down to leaves */
+
 	if (e1->type == type) {
 		__expr_eliminate_eq(type, &e1->left.expr, &e2);
 		__expr_eliminate_eq(type, &e1->right.expr, &e2);
@@ -150,12 +160,18 @@
 		__expr_eliminate_eq(type, &e1, &e2->right.expr);
 		return;
 	}
+
+	/* e1 and e2 are leaves. Compare them. */
+
 	if (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
 	    e1->left.sym == e2->left.sym &&
 	    (e1->left.sym == &symbol_yes || e1->left.sym == &symbol_no))
 		return;
 	if (!expr_eq(e1, e2))
 		return;
+
+	/* e1 and e2 are equal leaves. Prepare them for elimination. */
+
 	trans_count++;
 	expr_free(e1); expr_free(e2);
 	switch (type) {
@@ -172,6 +188,35 @@
 	}
 }
 
+/*
+ * Rewrites the expressions 'ep1' and 'ep2' to remove operands common to both.
+ * Example reductions:
+ *
+ *	ep1: A && B           ->  ep1: y
+ *	ep2: A && B && C      ->  ep2: C
+ *
+ *	ep1: A || B           ->  ep1: n
+ *	ep2: A || B || C      ->  ep2: C
+ *
+ *	ep1: A && (B && FOO)  ->  ep1: FOO
+ *	ep2: (BAR && B) && A  ->  ep2: BAR
+ *
+ *	ep1: A && (B || C)    ->  ep1: y
+ *	ep2: (C || B) && A    ->  ep2: y
+ *
+ * Comparisons are done between all operands at the same "level" of && or ||.
+ * For example, in the expression 'e1 && (e2 || e3) && (e4 || e5)', the
+ * following operands will be compared:
+ *
+ *	- 'e1', 'e2 || e3', and 'e4 || e5', against each other
+ *	- e2 against e3
+ *	- e4 against e5
+ *
+ * Parentheses are irrelevant within a single level. 'e1 && (e2 && e3)' and
+ * '(e1 && e2) && e3' are both a single level.
+ *
+ * See __expr_eliminate_eq() as well.
+ */
 void expr_eliminate_eq(struct expr **ep1, struct expr **ep2)
 {
 	if (!e1 || !e2)
@@ -197,6 +242,12 @@
 #undef e1
 #undef e2
 
+/*
+ * Returns true if 'e1' and 'e2' are equal, after minor simplification. Two
+ * &&/|| expressions are considered equal if every operand in one expression
+ * equals some operand in the other (operands do not need to appear in the same
+ * order), recursively.
+ */
 static int expr_eq(struct expr *e1, struct expr *e2)
 {
 	int res, old_count;
@@ -243,6 +294,17 @@
 	return 0;
 }
 
+/*
+ * Recursively performs the following simplifications in-place (as well as the
+ * corresponding simplifications with swapped operands):
+ *
+ *	expr && n  ->  n
+ *	expr && y  ->  expr
+ *	expr || n  ->  expr
+ *	expr || y  ->  y
+ *
+ * Returns the optimized expression.
+ */
 static struct expr *expr_eliminate_yn(struct expr *e)
 {
 	struct expr *tmp;
@@ -516,12 +578,21 @@
 	return NULL;
 }
 
+/*
+ * expr_eliminate_dups() helper.
+ *
+ * Walks the two expression trees given in 'ep1' and 'ep2'. Any node that does
+ * not have type 'type' (E_OR/E_AND) is considered a leaf, and is compared
+ * against all other leaves to look for simplifications.
+ */
 static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2)
 {
 #define e1 (*ep1)
 #define e2 (*ep2)
 	struct expr *tmp;
 
+	/* Recurse down to leaves */
+
 	if (e1->type == type) {
 		expr_eliminate_dups1(type, &e1->left.expr, &e2);
 		expr_eliminate_dups1(type, &e1->right.expr, &e2);
@@ -532,6 +603,9 @@
 		expr_eliminate_dups1(type, &e1, &e2->right.expr);
 		return;
 	}
+
+	/* e1 and e2 are leaves. Compare and process them. */
+
 	if (e1 == e2)
 		return;
 
@@ -568,6 +642,17 @@
 #undef e2
 }
 
+/*
+ * Rewrites 'e' in-place to remove ("join") duplicate and other redundant
+ * operands.
+ *
+ * Example simplifications:
+ *
+ *	A || B || A    ->  A || B
+ *	A && B && A=y  ->  A=y && B
+ *
+ * Returns the deduplicated expression.
+ */
 struct expr *expr_eliminate_dups(struct expr *e)
 {
 	int oldcount;
@@ -584,6 +669,7 @@
 			;
 		}
 		if (!trans_count)
+			/* No simplifications done in this pass. We're done */
 			break;
 		e = expr_eliminate_yn(e);
 	}
@@ -591,6 +677,12 @@
 	return e;
 }
 
+/*
+ * Performs various simplifications involving logical operators and
+ * comparisons.
+ *
+ * Allocates and returns a new expression.
+ */
 struct expr *expr_transform(struct expr *e)
 {
 	struct expr *tmp;
@@ -805,6 +897,20 @@
  	return false;
 }
 
+/*
+ * Inserts explicit comparisons of type 'type' to symbol 'sym' into the
+ * expression 'e'.
+ *
+ * Examples transformations for type == E_UNEQUAL, sym == &symbol_no:
+ *
+ *	A              ->  A!=n
+ *	!A             ->  A=n
+ *	A && B         ->  !(A=n || B=n)
+ *	A || B         ->  !(A=n && B=n)
+ *	A && (B || C)  ->  !(A=n || (B=n && C=n))
+ *
+ * Allocates and returns a new expression.
+ */
 struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym)
 {
 	struct expr *e1, *e2;
@@ -893,7 +999,10 @@
 	switch (type) {
 	case S_BOOLEAN:
 	case S_TRISTATE:
-		return k_string;
+		val->s = !strcmp(str, "n") ? 0 :
+			 !strcmp(str, "m") ? 1 :
+			 !strcmp(str, "y") ? 2 : -1;
+		return k_signed;
 	case S_INT:
 		val->s = strtoll(str, &tail, 10);
 		kind = k_signed;
@@ -1028,49 +1137,9 @@
 	return 0;
 }
 
-static inline struct expr *
-expr_get_leftmost_symbol(const struct expr *e)
-{
-
-	if (e == NULL)
-		return NULL;
-
-	while (e->type != E_SYMBOL)
-		e = e->left.expr;
-
-	return expr_copy(e);
-}
-
-/*
- * Given expression `e1' and `e2', returns the leaf of the longest
- * sub-expression of `e1' not containing 'e2.
- */
-struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2)
-{
-	struct expr *ret;
-
-	switch (e1->type) {
-	case E_OR:
-		return expr_alloc_and(
-		    expr_simplify_unmet_dep(e1->left.expr, e2),
-		    expr_simplify_unmet_dep(e1->right.expr, e2));
-	case E_AND: {
-		struct expr *e;
-		e = expr_alloc_and(expr_copy(e1), expr_copy(e2));
-		e = expr_eliminate_dups(e);
-		ret = (!expr_eq(e, e1)) ? e1 : NULL;
-		expr_free(e);
-		break;
-		}
-	default:
-		ret = e1;
-		break;
-	}
-
-	return expr_get_leftmost_symbol(ret);
-}
-
-void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken)
+void expr_print(struct expr *e,
+		void (*fn)(void *, struct symbol *, const char *),
+		void *data, int prevtoken)
 {
 	if (!e) {
 		fn(data, NULL, "y");
@@ -1204,3 +1273,33 @@
 {
 	expr_print(e, expr_print_gstr_helper, gs, E_NONE);
 }
+
+/*
+ * Transform the top level "||" tokens into newlines and prepend each
+ * line with a minus. This makes expressions much easier to read.
+ * Suitable for reverse dependency expressions.
+ */
+static void expr_print_revdep(struct expr *e,
+			      void (*fn)(void *, struct symbol *, const char *),
+			      void *data, tristate pr_type, const char **title)
+{
+	if (e->type == E_OR) {
+		expr_print_revdep(e->left.expr, fn, data, pr_type, title);
+		expr_print_revdep(e->right.expr, fn, data, pr_type, title);
+	} else if (expr_calc_value(e) == pr_type) {
+		if (*title) {
+			fn(data, NULL, *title);
+			*title = NULL;
+		}
+
+		fn(data, NULL, "  - ");
+		expr_print(e, fn, data, E_NONE);
+		fn(data, NULL, "\n");
+	}
+}
+
+void expr_gstr_print_revdep(struct expr *e, struct gstr *gs,
+			    tristate pr_type, const char *title)
+{
+	expr_print_revdep(e, expr_print_gstr_helper, gs, pr_type, &title);
+}
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index a73f762..94a383b 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -74,17 +74,60 @@
 	S_DEF_COUNT
 };
 
+/*
+ * Represents a configuration symbol.
+ *
+ * Choices are represented as a special kind of symbol and have the
+ * SYMBOL_CHOICE bit set in 'flags'.
+ */
 struct symbol {
+	/* The next symbol in the same bucket in the symbol hash table */
 	struct symbol *next;
+
+	/* The name of the symbol, e.g. "FOO" for 'config FOO' */
 	char *name;
+
+	/* S_BOOLEAN, S_TRISTATE, ... */
 	enum symbol_type type;
+
+	/*
+	 * The calculated value of the symbol. The SYMBOL_VALID bit is set in
+	 * 'flags' when this is up to date. Note that this value might differ
+	 * from the user value set in e.g. a .config file, due to visibility.
+	 */
 	struct symbol_value curr;
+
+	/*
+	 * Values for the symbol provided from outside. def[S_DEF_USER] holds
+	 * the .config value.
+	 */
 	struct symbol_value def[S_DEF_COUNT];
+
+	/*
+	 * An upper bound on the tristate value the user can set for the symbol
+	 * if it is a boolean or tristate. Calculated from prompt dependencies,
+	 * which also inherit dependencies from enclosing menus, choices, and
+	 * ifs. If 'n', the user value will be ignored.
+	 *
+	 * Symbols lacking prompts always have visibility 'n'.
+	 */
 	tristate visible;
+
+	/* SYMBOL_* flags */
 	int flags;
+
+	/* List of properties. See prop_type. */
 	struct property *prop;
+
+	/* Dependencies from enclosing menus, choices, and ifs */
 	struct expr_value dir_dep;
+
+	/* Reverse dependencies through being selected by other symbols */
 	struct expr_value rev_dep;
+
+	/*
+	 * "Weak" reverse dependencies through being implied by other symbols
+	 */
 	struct expr_value implied;
 };
 
@@ -133,7 +176,7 @@
 	P_UNKNOWN,
 	P_PROMPT,   /* prompt "foo prompt" or "BAZ Value" */
 	P_COMMENT,  /* text associated with a comment */
-	P_MENU,     /* prompt associated with a menuconfig option */
+	P_MENU,     /* prompt associated with a menu or menuconfig symbol */
 	P_DEFAULT,  /* default y */
 	P_CHOICE,   /* choice value */
 	P_SELECT,   /* select BAR */
@@ -166,22 +209,67 @@
 	for (st = sym->prop; st; st = st->next) \
 		if (st->text)
 
+/*
+ * Represents a node in the menu tree, as seen in e.g. menuconfig (though used
+ * for all front ends). Each symbol, menu, etc. defined in the Kconfig files
+ * gets a node. A symbol defined in multiple locations gets one node at each
+ * location.
+ */
 struct menu {
+	/* The next menu node at the same level */
 	struct menu *next;
+
+	/* The parent menu node, corresponding to e.g. a menu or choice */
 	struct menu *parent;
+
+	/* The first child menu node, for e.g. menus and choices */
 	struct menu *list;
+
+	/*
+	 * The symbol associated with the menu node. Choices are implemented as
+	 * a special kind of symbol. NULL for menus, comments, and ifs.
+	 */
 	struct symbol *sym;
+
+	/*
+	 * The prompt associated with the node. This holds the prompt for a
+	 * symbol as well as the text for a menu or comment, along with the
+	 * type (P_PROMPT, P_MENU, etc.)
+	 */
 	struct property *prompt;
+
+	/*
+	 * 'visible if' dependencies. If more than one is given, they will be
+	 * ANDed together.
+	 */
 	struct expr *visibility;
+
+	/*
+	 * Ordinary dependencies from e.g. 'depends on' and 'if', ANDed
+	 * together
+	 */
 	struct expr *dep;
+
+	/* MENU_* flags */
 	unsigned int flags;
+
+	/* Any help text associated with the node */
 	char *help;
+
+	/* The location where the menu node appears in the Kconfig files */
 	struct file *file;
 	int lineno;
+
+	/* For use by front ends that need to store auxiliary data */
 	void *data;
 };
 
+/*
+ * Set on a menu node when the corresponding symbol changes state in some way.
+ * Can be checked by front ends.
+ */
 #define MENU_CHANGED		0x0001
+
 #define MENU_ROOT		0x0002
 
 struct jump_key {
@@ -217,11 +305,12 @@
 int expr_contains_symbol(struct expr *dep, struct symbol *sym);
 bool expr_depends_symbol(struct expr *dep, struct symbol *sym);
 struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym);
-struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2);
 
 void expr_fprint(struct expr *e, FILE *out);
 struct gstr; /* forward */
 void expr_gstr_print(struct expr *e, struct gstr *gs);
+void expr_gstr_print_revdep(struct expr *e, struct gstr *gs,
+			    tristate pr_type, const char *title);
 
 static inline int expr_is_yes(struct expr *e)
 {
diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c
index 26d208b..cfddddb 100644
--- a/scripts/kconfig/gconf.c
+++ b/scripts/kconfig/gconf.c
@@ -914,7 +914,7 @@
 			current = menu;
 			display_tree_part();
 			gtk_widget_set_sensitive(back_btn, TRUE);
-		} else if ((col == COL_OPTION)) {
+		} else if (col == COL_OPTION) {
 			toggle_sym_value(menu);
 			gtk_tree_view_expand_row(view, path, TRUE);
 		}
diff --git a/scripts/kconfig/kconf_id.c b/scripts/kconfig/kconf_id.c
new file mode 100644
index 0000000..3ea9c5f
--- /dev/null
+++ b/scripts/kconfig/kconf_id.c
@@ -0,0 +1,53 @@
+
+static struct kconf_id kconf_id_array[] = {
+	{ "mainmenu",		T_MAINMENU,		TF_COMMAND },
+	{ "menu",		T_MENU,			TF_COMMAND },
+	{ "endmenu",		T_ENDMENU,		TF_COMMAND },
+	{ "source",		T_SOURCE,		TF_COMMAND },
+	{ "choice",		T_CHOICE,		TF_COMMAND },
+	{ "endchoice",		T_ENDCHOICE,		TF_COMMAND },
+	{ "comment",		T_COMMENT,		TF_COMMAND },
+	{ "config",		T_CONFIG,		TF_COMMAND },
+	{ "menuconfig",		T_MENUCONFIG,		TF_COMMAND },
+	{ "help",		T_HELP,			TF_COMMAND },
+	{ "---help---",		T_HELP,			TF_COMMAND },
+	{ "if",			T_IF,			TF_COMMAND|TF_PARAM },
+	{ "endif",		T_ENDIF,		TF_COMMAND },
+	{ "depends",		T_DEPENDS,		TF_COMMAND },
+	{ "optional",		T_OPTIONAL,		TF_COMMAND },
+	{ "default",		T_DEFAULT,		TF_COMMAND, S_UNKNOWN },
+	{ "prompt",		T_PROMPT,		TF_COMMAND },
+	{ "tristate",		T_TYPE,			TF_COMMAND, S_TRISTATE },
+	{ "def_tristate",	T_DEFAULT,		TF_COMMAND, S_TRISTATE },
+	{ "bool",		T_TYPE,			TF_COMMAND, S_BOOLEAN },
+	{ "def_bool",		T_DEFAULT,		TF_COMMAND, S_BOOLEAN },
+	{ "int",		T_TYPE,			TF_COMMAND, S_INT },
+	{ "hex",		T_TYPE,			TF_COMMAND, S_HEX },
+	{ "string",		T_TYPE,			TF_COMMAND, S_STRING },
+	{ "select",		T_SELECT,		TF_COMMAND },
+	{ "imply",		T_IMPLY,		TF_COMMAND },
+	{ "range",		T_RANGE,		TF_COMMAND },
+	{ "visible",		T_VISIBLE,		TF_COMMAND },
+	{ "option",		T_OPTION,		TF_COMMAND },
+	{ "on",			T_ON,			TF_PARAM },
+	{ "modules",		T_OPT_MODULES,		TF_OPTION },
+	{ "defconfig_list",	T_OPT_DEFCONFIG_LIST,	TF_OPTION },
+	{ "env",		T_OPT_ENV,		TF_OPTION },
+	{ "allnoconfig_y",	T_OPT_ALLNOCONFIG_Y,	TF_OPTION },
+};
+
+#define KCONF_ID_ARRAY_SIZE (sizeof(kconf_id_array)/sizeof(struct kconf_id))
+
+static const struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len)
+{
+	int i;
+
+	for (i = 0; i < KCONF_ID_ARRAY_SIZE; i++) {
+		struct kconf_id *id = kconf_id_array+i;
+		int l = strlen(id->name);
+
+		if (len == l && !memcmp(str, id->name, len))
+			return id;
+	}
+	return NULL;
+}
diff --git a/scripts/kconfig/kxgettext.c b/scripts/kconfig/kxgettext.c
index 2858738..240880a 100644
--- a/scripts/kconfig/kxgettext.c
+++ b/scripts/kconfig/kxgettext.c
@@ -101,7 +101,7 @@
 	if (self->files == NULL)
 		goto out_fail;
 
-	self->msg = strdup(msg);
+	self->msg = xstrdup(msg);
 	if (self->msg == NULL)
 		goto out_fail_msg;
 
diff --git a/scripts/kconfig/list.h b/scripts/kconfig/list.h
index 2cf23f0..45cb237 100644
--- a/scripts/kconfig/list.h
+++ b/scripts/kconfig/list.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 #ifndef LIST_H
 #define LIST_H
 
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index 91ca126..f4394af 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -62,12 +62,13 @@
 #define T_OPT_ALLNOCONFIG_Y	4
 
 struct kconf_id {
-	int name;
+	const char *name;
 	int token;
 	unsigned int flags;
 	enum symbol_type stype;
 };
 
+extern int yylineno;
 void zconfdump(FILE *out);
 void zconf_starthelp(void);
 FILE *zconf_fopen(const char *name);
@@ -100,7 +101,6 @@
 struct menu *menu_add_menu(void);
 void menu_end_menu(void);
 void menu_add_entry(struct symbol *sym);
-void menu_end_entry(void);
 void menu_add_dep(struct expr *dep);
 void menu_add_visibility(struct expr *dep);
 struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep);
@@ -115,6 +115,8 @@
 int file_write_dep(const char *name);
 void *xmalloc(size_t size);
 void *xcalloc(size_t nmemb, size_t size);
+void *xrealloc(void *p, size_t size);
+char *xstrdup(const char *s);
 
 struct gstr {
 	size_t len;
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
index d539871..9dc8abf 100644
--- a/scripts/kconfig/lkc_proto.h
+++ b/scripts/kconfig/lkc_proto.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 #include <stdarg.h>
 
 /* confdata.c */
@@ -30,7 +31,7 @@
 
 struct symbol * sym_lookup(const char *name, int flags);
 struct symbol * sym_find(const char *name);
-const char * sym_expand_string_value(const char *in);
+char *sym_expand_string_value(const char *in);
 const char * sym_escape_string_value(const char *in);
 struct symbol ** sym_re_search(const char *pattern);
 const char * sym_type_name(enum symbol_type type);
diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh
index 5075ebf..6c0bcd9 100755
--- a/scripts/kconfig/lxdialog/check-lxdialog.sh
+++ b/scripts/kconfig/lxdialog/check-lxdialog.sh
@@ -1,4 +1,5 @@
 #!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
 # Check ncurses compatibility
 
 # What library to link
@@ -54,7 +55,8 @@
 	    echo " *** required header files."                            1>&2
 	    echo " *** 'make menuconfig' requires the ncurses libraries." 1>&2
 	    echo " *** "                                                  1>&2
-	    echo " *** Install ncurses (ncurses-devel) and try again."    1>&2
+	    echo " *** Install ncurses (ncurses-devel or libncurses-dev " 1>&2
+	    echo " *** depending on your distribution) and try again."    1>&2
 	    echo " *** "                                                  1>&2
 	    exit 1
 	fi
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index 315ce2c..c829be8 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -246,7 +246,7 @@
 	"  Selected by: BAR [=n]\n"
 	"-----------------------------------------------------------------\n"
 	"o The line 'Type:' shows the type of the configuration option for\n"
-	"  this symbol (boolean, tristate, string, ...)\n"
+	"  this symbol (bool, tristate, string, ...)\n"
 	"o The line 'Prompt:' shows the text used in the menu structure for\n"
 	"  this symbol\n"
 	"o The 'Defined at' line tells at what file / line number the symbol\n"
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index e935793..5c5c137 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -62,13 +62,8 @@
 		menu_add_symbol(P_SYMBOL, sym, NULL);
 }
 
-void menu_end_entry(void)
-{
-}
-
 struct menu *menu_add_menu(void)
 {
-	menu_end_entry();
 	last_entry_ptr = &current_entry->list;
 	return current_menu = current_entry;
 }
@@ -79,19 +74,23 @@
 	current_menu = current_menu->parent;
 }
 
-static struct expr *menu_check_dep(struct expr *e)
+/*
+ * Rewrites 'm' to 'm' && MODULES, so that it evaluates to 'n' when running
+ * without modules
+ */
+static struct expr *rewrite_m(struct expr *e)
 {
 	if (!e)
 		return e;
 
 	switch (e->type) {
 	case E_NOT:
-		e->left.expr = menu_check_dep(e->left.expr);
+		e->left.expr = rewrite_m(e->left.expr);
 		break;
 	case E_OR:
 	case E_AND:
-		e->left.expr = menu_check_dep(e->left.expr);
-		e->right.expr = menu_check_dep(e->right.expr);
+		e->left.expr = rewrite_m(e->left.expr);
+		e->right.expr = rewrite_m(e->right.expr);
 		break;
 	case E_SYMBOL:
 		/* change 'm' into 'm' && MODULES */
@@ -106,7 +105,7 @@
 
 void menu_add_dep(struct expr *dep)
 {
-	current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep));
+	current_entry->dep = expr_alloc_and(current_entry->dep, dep);
 }
 
 void menu_set_type(int type)
@@ -131,7 +130,7 @@
 
 	prop->menu = current_entry;
 	prop->expr = expr;
-	prop->visible.expr = menu_check_dep(dep);
+	prop->visible.expr = dep;
 
 	if (prompt) {
 		if (isspace(*prompt)) {
@@ -213,6 +212,7 @@
 			sym_defconfig_list = current_entry->sym;
 		else if (sym_defconfig_list != current_entry->sym)
 			zconf_error("trying to redefine defconfig symbol");
+		sym_defconfig_list->flags |= SYMBOL_AUTO;
 		break;
 	case T_OPT_ENV:
 		prop_add_env(arg);
@@ -252,6 +252,16 @@
 					    "'%s': number is invalid",
 					    sym->name);
 			}
+			if (sym_is_choice(sym)) {
+				struct property *choice_prop =
+					sym_get_choice_prop(sym2);
+
+				if (!choice_prop ||
+				    prop_get_symbol(choice_prop) != sym)
+					prop_warn(prop,
+						  "choice default symbol '%s' is not contained in the choice",
+						  sym2->name);
+			}
 			break;
 		case P_SELECT:
 		case P_IMPLY:
@@ -260,13 +270,13 @@
 			if (sym->type != S_BOOLEAN && sym->type != S_TRISTATE)
 				prop_warn(prop,
 				    "config symbol '%s' uses %s, but is "
-				    "not boolean or tristate", sym->name, use);
+				    "not bool or tristate", sym->name, use);
 			else if (sym2->type != S_UNKNOWN &&
 				 sym2->type != S_BOOLEAN &&
 				 sym2->type != S_TRISTATE)
 				prop_warn(prop,
 				    "'%s' has wrong type. '%s' only "
-				    "accept arguments of boolean and "
+				    "accept arguments of bool and "
 				    "tristate type", sym2->name, use);
 			break;
 		case P_RANGE:
@@ -292,6 +302,11 @@
 
 	sym = parent->sym;
 	if (parent->list) {
+		/*
+		 * This menu node has children. We (recursively) process them
+		 * and propagate parent dependencies before moving on.
+		 */
+
 		if (sym && sym_is_choice(sym)) {
 			if (sym->type == S_UNKNOWN) {
 				/* find the first choice value to find out choice type */
@@ -309,30 +324,83 @@
 				if (menu->sym && menu->sym->type == S_UNKNOWN)
 					menu_set_type(sym->type);
 			}
+
+			/*
+			 * Use the choice itself as the parent dependency of
+			 * the contained items. This turns the mode of the
+			 * choice into an upper bound on the visibility of the
+			 * choice value symbols.
+			 */
 			parentdep = expr_alloc_symbol(sym);
 		} else if (parent->prompt)
+			/* Menu node for 'menu' */
 			parentdep = parent->prompt->visible.expr;
 		else
+			/* Menu node for 'if' */
 			parentdep = parent->dep;
 
+		/* For each child menu node... */
 		for (menu = parent->list; menu; menu = menu->next) {
-			basedep = expr_transform(menu->dep);
+			/*
+			 * Propagate parent dependencies to the child menu
+			 * node, also rewriting and simplifying expressions
+			 */
+			basedep = rewrite_m(menu->dep);
+			basedep = expr_transform(basedep);
 			basedep = expr_alloc_and(expr_copy(parentdep), basedep);
 			basedep = expr_eliminate_dups(basedep);
 			menu->dep = basedep;
+
 			if (menu->sym)
+				/*
+				 * Note: For symbols, all prompts are included
+				 * too in the symbol's own property list
+				 */
 				prop = menu->sym->prop;
 			else
+				/*
+				 * For non-symbol menu nodes, we just need to
+				 * handle the prompt
+				 */
 				prop = menu->prompt;
+
+			/* For each property... */
 			for (; prop; prop = prop->next) {
 				if (prop->menu != menu)
+					/*
+					 * Two possibilities:
+					 *
+					 * 1. The property lacks dependencies
+					 *    and so isn't location-specific,
+					 *    e.g. an 'option'
+					 *
+					 * 2. The property belongs to a symbol
+					 *    defined in multiple locations and
+					 *    is from some other location. It
+					 *    will be handled there in that
+					 *    case.
+					 *
+					 * Skip the property.
+					 */
 					continue;
-				dep = expr_transform(prop->visible.expr);
+
+				/*
+				 * Propagate parent dependencies to the
+				 * property's condition, rewriting and
+				 * simplifying expressions at the same time
+				 */
+				dep = rewrite_m(prop->visible.expr);
+				dep = expr_transform(dep);
 				dep = expr_alloc_and(expr_copy(basedep), dep);
 				dep = expr_eliminate_dups(dep);
 				if (menu->sym && menu->sym->type != S_TRISTATE)
 					dep = expr_trans_bool(dep);
 				prop->visible.expr = dep;
+
+				/*
+				 * Handle selects and implies, which modify the
+				 * dependencies of the selected/implied symbol
+				 */
 				if (prop->type == P_SELECT) {
 					struct symbol *es = prop_get_symbol(prop);
 					es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr,
@@ -344,34 +412,81 @@
 				}
 			}
 		}
+
+		if (sym && sym_is_choice(sym))
+			expr_free(parentdep);
+
+		/*
+		 * Recursively process children in the same fashion before
+		 * moving on
+		 */
 		for (menu = parent->list; menu; menu = menu->next)
 			menu_finalize(menu);
 	} else if (sym) {
+		/*
+		 * Automatic submenu creation. If sym is a symbol and A, B, C,
+		 * ... are consecutive items (symbols, menus, ifs, etc.) that
+		 * all depend on sym, then the following menu structure is
+		 * created:
+		 *
+		 *	sym
+		 *	 +-A
+		 *	 +-B
+		 *	 +-C
+		 *	 ...
+		 *
+		 * This also works recursively, giving the following structure
+		 * if A is a symbol and B depends on A:
+		 *
+		 *	sym
+		 *	 +-A
+		 *	 | +-B
+		 *	 +-C
+		 *	 ...
+		 */
+
 		basedep = parent->prompt ? parent->prompt->visible.expr : NULL;
 		basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no);
 		basedep = expr_eliminate_dups(expr_transform(basedep));
+
+		/* Examine consecutive elements after sym */
 		last_menu = NULL;
 		for (menu = parent->next; menu; menu = menu->next) {
 			dep = menu->prompt ? menu->prompt->visible.expr : menu->dep;
 			if (!expr_contains_symbol(dep, sym))
+				/* No dependency, quit */
 				break;
 			if (expr_depends_symbol(dep, sym))
+				/* Absolute dependency, put in submenu */
 				goto next;
+
+			/*
+			 * Also consider it a dependency on sym if our
+			 * dependencies contain sym and are a "superset" of
+			 * sym's dependencies, e.g. '(sym || Q) && R' when sym
+			 * depends on R.
+			 *
+			 * Note that 'R' might be from an enclosing menu or if,
+			 * making this a more common case than it might seem.
+			 */
 			dep = expr_trans_compare(dep, E_UNEQUAL, &symbol_no);
 			dep = expr_eliminate_dups(expr_transform(dep));
 			dep2 = expr_copy(basedep);
 			expr_eliminate_eq(&dep, &dep2);
 			expr_free(dep);
 			if (!expr_is_yes(dep2)) {
+				/* Not superset, quit */
 				expr_free(dep2);
 				break;
 			}
+			/* Superset, put in submenu */
 			expr_free(dep2);
 		next:
 			menu_finalize(menu);
 			menu->parent = parent;
 			last_menu = menu;
 		}
+		expr_free(basedep);
 		if (last_menu) {
 			parent->list = parent->next;
 			parent->next = last_menu->next;
@@ -420,6 +535,35 @@
 			*ep = expr_alloc_one(E_LIST, NULL);
 			(*ep)->right.sym = menu->sym;
 		}
+
+		/*
+		 * This code serves two purposes:
+		 *
+		 * (1) Flattening 'if' blocks, which do not specify a submenu
+		 *     and only add dependencies.
+		 *
+		 *     (Automatic submenu creation might still create a submenu
+		 *     from an 'if' before this code runs.)
+		 *
+		 * (2) "Undoing" any automatic submenus created earlier below
+		 *     promptless symbols.
+		 *
+		 * Before:
+		 *
+		 *	A
+		 *	if ... (or promptless symbol)
+		 *	 +-B
+		 *	 +-C
+		 *	D
+		 *
+		 * After:
+		 *
+		 *	A
+		 *	if ... (or promptless symbol)
+		 *	B
+		 *	C
+		 *	D
+		 */
 		if (menu->list && (!menu->prompt || !menu->prompt->text)) {
 			for (last_menu = menu->list; ; last_menu = last_menu->next) {
 				last_menu->parent = parent;
@@ -444,6 +588,15 @@
 		sym->flags |= SYMBOL_WARNED;
 	}
 
+	/*
+	 * For non-optional choices, add a reverse dependency (corresponding to
+	 * a select) of '<visibility> && m'. This prevents the user from
+	 * setting the choice mode to 'n' when the choice is visible.
+	 *
+	 * This would also work for non-choice symbols, but only non-optional
+	 * choices clear SYMBOL_OPTIONAL as of writing. Choices are implemented
+	 * as a type of symbol.
+	 */
 	if (sym && !sym_is_optional(sym) && parent->prompt) {
 		sym->rev_dep.expr = expr_alloc_or(sym->rev_dep.expr,
 				expr_alloc_and(parent->prompt->visible.expr,
@@ -675,16 +828,16 @@
 
 	get_symbol_props_str(r, sym, P_SELECT, _("  Selects: "));
 	if (sym->rev_dep.expr) {
-		str_append(r, _("  Selected by: "));
-		expr_gstr_print(sym->rev_dep.expr, r);
-		str_append(r, "\n");
+		expr_gstr_print_revdep(sym->rev_dep.expr, r, yes, "  Selected by [y]:\n");
+		expr_gstr_print_revdep(sym->rev_dep.expr, r, mod, "  Selected by [m]:\n");
+		expr_gstr_print_revdep(sym->rev_dep.expr, r, no, "  Selected by [n]:\n");
 	}
 
 	get_symbol_props_str(r, sym, P_IMPLY, _("  Implies: "));
 	if (sym->implied.expr) {
-		str_append(r, _("  Implied by: "));
-		expr_gstr_print(sym->implied.expr, r);
-		str_append(r, "\n");
+		expr_gstr_print_revdep(sym->implied.expr, r, yes, "  Implied by [y]:\n");
+		expr_gstr_print_revdep(sym->implied.expr, r, mod, "  Implied by [m]:\n");
+		expr_gstr_print_revdep(sym->implied.expr, r, no, "  Implied by [n]:\n");
 	}
 
 	str_append(r, "\n\n");
diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c
index a9bc533..0031147 100644
--- a/scripts/kconfig/nconf.c
+++ b/scripts/kconfig/nconf.c
@@ -271,7 +271,7 @@
 static int items_num;
 static int global_exit;
 /* the currently selected button */
-const char *current_instructions = menu_instructions;
+static const char *current_instructions = menu_instructions;
 
 static char *dialog_input_result;
 static int dialog_input_result_len;
@@ -305,7 +305,7 @@
 };
 
 static const int function_keys_num = 9;
-struct function_keys function_keys[] = {
+static struct function_keys function_keys[] = {
 	{
 		.key_str = "F1",
 		.func = "Help",
@@ -508,7 +508,7 @@
 	index = (index + items_num) % items_num;
 	while (true) {
 		char *str = k_menu_items[index].str;
-		if (strcasestr(str, match_str) != 0)
+		if (strcasestr(str, match_str) != NULL)
 			return index;
 		if (flag == FIND_NEXT_MATCH_UP ||
 		    flag == MATCH_TINKER_PATTERN_UP)
@@ -1067,7 +1067,7 @@
 
 static void conf(struct menu *menu)
 {
-	struct menu *submenu = 0;
+	struct menu *submenu = NULL;
 	const char *prompt = menu_get_prompt(menu);
 	struct symbol *sym;
 	int res;
@@ -1234,7 +1234,7 @@
 static void conf_choice(struct menu *menu)
 {
 	const char *prompt = _(menu_get_prompt(menu));
-	struct menu *child = 0;
+	struct menu *child = NULL;
 	struct symbol *active;
 	int selected_index = 0;
 	int last_top_row = 0;
@@ -1456,7 +1456,7 @@
 	}
 }
 
-void setup_windows(void)
+static void setup_windows(void)
 {
 	int lines, columns;
 
diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c
index 4b2f44c..88874ac 100644
--- a/scripts/kconfig/nconf.gui.c
+++ b/scripts/kconfig/nconf.gui.c
@@ -6,6 +6,7 @@
  *
  */
 #include "nconf.h"
+#include "lkc.h"
 
 /* a list of all the different widgets we use */
 attributes_t attributes[ATTR_MAX+1] = {0};
@@ -129,7 +130,7 @@
 	mkattrn(FUNCTION_TEXT, A_REVERSE);
 }
 
-void set_colors()
+void set_colors(void)
 {
 	start_color();
 	use_default_colors();
@@ -192,7 +193,7 @@
 	int lines = 0;
 
 	if (!text)
-		return 0;
+		return NULL;
 
 	for (i = 0; text[i] != '\0' && lines < line_no; i++)
 		if (text[i] == '\n')
@@ -374,7 +375,7 @@
 
 	if (strlen(init)+1 > *result_len) {
 		*result_len = strlen(init)+1;
-		*resultp = result = realloc(result, *result_len);
+		*resultp = result = xrealloc(result, *result_len);
 	}
 
 	/* find the widest line of msg: */
diff --git a/scripts/kconfig/nconf.h b/scripts/kconfig/nconf.h
index 0d52617..9f6f21d 100644
--- a/scripts/kconfig/nconf.h
+++ b/scripts/kconfig/nconf.h
@@ -15,7 +15,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <locale.h>
-#include <curses.h>
+#include <ncurses.h>
 #include <menu.h>
 #include <panel.h>
 #include <form.h>
@@ -24,8 +24,6 @@
 #include <time.h>
 #include <sys/time.h>
 
-#include "ncurses.h"
-
 #define max(a, b) ({\
 		typeof(a) _a = a;\
 		typeof(b) _b = b;\
diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl
index b8c7b29..a2e83ab 100755
--- a/scripts/kconfig/streamline_config.pl
+++ b/scripts/kconfig/streamline_config.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl
 #
 # Copyright 2005-2009 - Steven Rostedt
 # Licensed under the terms of the GNU GPL License version 2
@@ -42,6 +42,7 @@
 #    mv config_strip .config
 #    make oldconfig
 #
+use warnings;
 use strict;
 use Getopt::Long;
 
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index 3c8bd9b..f0b2e3b 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -77,7 +77,7 @@
 {
 	switch (type) {
 	case S_BOOLEAN:
-		return "boolean";
+		return "bool";
 	case S_TRISTATE:
 		return "tristate";
 	case S_INT:
@@ -183,7 +183,7 @@
 		sprintf(str, "%lld", val2);
 	else
 		sprintf(str, "0x%llx", val2);
-	sym->curr.val = strdup(str);
+	sym->curr.val = xstrdup(str);
 }
 
 static void sym_set_changed(struct symbol *sym)
@@ -243,7 +243,7 @@
 	tri = yes;
 	if (sym->dir_dep.expr)
 		tri = expr_calc_value(sym->dir_dep.expr);
-	if (tri == mod)
+	if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
 		tri = yes;
 	if (sym->dir_dep.tri != tri) {
 		sym->dir_dep.tri = tri;
@@ -333,6 +333,27 @@
 	return def_sym;
 }
 
+static void sym_warn_unmet_dep(struct symbol *sym)
+{
+	struct gstr gs = str_new();
+
+	str_printf(&gs,
+		   "\nWARNING: unmet direct dependencies detected for %s\n",
+		   sym->name);
+	str_printf(&gs,
+		   "  Depends on [%c]: ",
+		   sym->dir_dep.tri == mod ? 'm' : 'n');
+	expr_gstr_print(sym->dir_dep.expr, &gs);
+	str_printf(&gs, "\n");
+
+	expr_gstr_print_revdep(sym->rev_dep.expr, &gs, yes,
+			       "  Selected by [y]:\n");
+	expr_gstr_print_revdep(sym->rev_dep.expr, &gs, mod,
+			       "  Selected by [m]:\n");
+
+	fputs(str_get(&gs), stderr);
+}
+
 void sym_calc_value(struct symbol *sym)
 {
 	struct symbol_value newval, oldval;
@@ -371,11 +392,13 @@
 		sym->curr.tri = no;
 		return;
 	}
-	if (!sym_is_choice_value(sym))
-		sym->flags &= ~SYMBOL_WRITE;
+	sym->flags &= ~SYMBOL_WRITE;
 
 	sym_calc_visibility(sym);
 
+	if (sym->visible != no)
+		sym->flags |= SYMBOL_WRITE;
+
 	/* set default if recursively called */
 	sym->curr = newval;
 
@@ -390,7 +413,6 @@
 				/* if the symbol is visible use the user value
 				 * if available, otherwise try the default value
 				 */
-				sym->flags |= SYMBOL_WRITE;
 				if (sym_has_value(sym)) {
 					newval.tri = EXPR_AND(sym->def[S_DEF_USER].tri,
 							      sym->visible);
@@ -402,9 +424,10 @@
 			if (!sym_is_choice(sym)) {
 				prop = sym_get_default_prop(sym);
 				if (prop) {
-					sym->flags |= SYMBOL_WRITE;
 					newval.tri = EXPR_AND(expr_calc_value(prop->expr),
 							      prop->visible.tri);
+					if (newval.tri != no)
+						sym->flags |= SYMBOL_WRITE;
 				}
 				if (sym->implied.tri != no) {
 					sym->flags |= SYMBOL_WRITE;
@@ -412,18 +435,8 @@
 				}
 			}
 		calc_newval:
-			if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) {
-				struct expr *e;
-				e = expr_simplify_unmet_dep(sym->rev_dep.expr,
-				    sym->dir_dep.expr);
-				fprintf(stderr, "warning: (");
-				expr_fprint(e, stderr);
-				fprintf(stderr, ") selects %s which has unmet direct dependencies (",
-					sym->name);
-				expr_fprint(sym->dir_dep.expr, stderr);
-				fprintf(stderr, ")\n");
-				expr_free(e);
-			}
+			if (sym->dir_dep.tri < sym->rev_dep.tri)
+				sym_warn_unmet_dep(sym);
 			newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
 		}
 		if (newval.tri == mod &&
@@ -433,12 +446,9 @@
 	case S_STRING:
 	case S_HEX:
 	case S_INT:
-		if (sym->visible != no) {
-			sym->flags |= SYMBOL_WRITE;
-			if (sym_has_value(sym)) {
-				newval.val = sym->def[S_DEF_USER].val;
-				break;
-			}
+		if (sym->visible != no && sym_has_value(sym)) {
+			newval.val = sym->def[S_DEF_USER].val;
+			break;
 		}
 		prop = sym_get_default_prop(sym);
 		if (prop) {
@@ -851,7 +861,7 @@
 				   : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE))))
 				return symbol;
 		}
-		new_name = strdup(name);
+		new_name = xstrdup(name);
 	} else {
 		new_name = NULL;
 		hash = 0;
@@ -901,12 +911,16 @@
  * name to be expanded shall be prefixed by a '$'. Unknown symbol expands to
  * the empty string.
  */
-const char *sym_expand_string_value(const char *in)
+char *sym_expand_string_value(const char *in)
 {
 	const char *src;
 	char *res;
 	size_t reslen;
 
+	/*
+	 * Note: 'in' might come from a token that's about to be
+	 * freed, so make sure to always allocate a new string
+	 */
 	reslen = strlen(in) + 1;
 	res = xmalloc(reslen);
 	res[0] = '\0';
@@ -934,7 +948,7 @@
 		newlen = strlen(res) + strlen(symval) + strlen(src) + 1;
 		if (newlen > reslen) {
 			reslen = newlen;
-			res = realloc(res, reslen);
+			res = xrealloc(res, reslen);
 		}
 
 		strcat(res, symval);
@@ -1150,8 +1164,7 @@
 		if (stack->sym == last_sym)
 			fprintf(stderr, "%s:%d:error: recursive dependency detected!\n",
 				prop->file->name, prop->lineno);
-			fprintf(stderr, "For a resolution refer to Documentation/kbuild/kconfig-language.txt\n");
-			fprintf(stderr, "subsection \"Kconfig recursive dependency limitations\"\n");
+
 		if (stack->expr) {
 			fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n",
 				prop->file->name, prop->lineno,
@@ -1181,6 +1194,11 @@
 		}
 	}
 
+	fprintf(stderr,
+		"For a resolution refer to Documentation/kbuild/kconfig-language.txt\n"
+		"subsection \"Kconfig recursive dependency limitations\"\n"
+		"\n");
+
 	if (check_top == &cv_stack)
 		dep_stack_remove();
 }
@@ -1215,7 +1233,7 @@
 	default:
 		break;
 	}
-	printf("Oops! How to check %d?\n", e->type);
+	fprintf(stderr, "Oops! How to check %d?\n", e->type);
 	return NULL;
 }
 
diff --git a/scripts/kconfig/tests/auto_submenu/Kconfig b/scripts/kconfig/tests/auto_submenu/Kconfig
new file mode 100644
index 0000000..c17bf2c
--- /dev/null
+++ b/scripts/kconfig/tests/auto_submenu/Kconfig
@@ -0,0 +1,50 @@
+config A
+	bool "A"
+	default y
+
+config A0
+	bool "A0"
+	depends on A
+	default y
+	help
+	  This depends on A, so should be a submenu of A.
+
+config A0_0
+	bool "A1_0"
+	depends on A0
+	help
+	  Submenus are created recursively.
+	  This should be a submenu of A0.
+
+config A1
+	bool "A1"
+	depends on A
+	default y
+	help
+	  This should line up with A0.
+
+choice
+	prompt "choice"
+	depends on A1
+	help
+	  Choice should become a submenu as well.
+
+config A1_0
+	bool "A1_0"
+
+config A1_1
+	bool "A1_1"
+
+endchoice
+
+config B
+	bool "B"
+	help
+	  This is independent of A.
+
+config C
+	bool "C"
+	depends on A
+	help
+	  This depends on A, but not a consecutive item, so can/should not
+	  be a submenu.
diff --git a/scripts/kconfig/tests/auto_submenu/__init__.py b/scripts/kconfig/tests/auto_submenu/__init__.py
new file mode 100644
index 0000000..32e79b8
--- /dev/null
+++ b/scripts/kconfig/tests/auto_submenu/__init__.py
@@ -0,0 +1,12 @@
+"""
+Create submenu for symbols that depend on the preceding one.
+
+If a symbols has dependency on the preceding symbol, the menu entry
+should become the submenu of the preceding one, and displayed with
+deeper indentation.
+"""
+
+
+def test(conf):
+    assert conf.oldaskconfig() == 0
+    assert conf.stdout_contains('expected_stdout')
diff --git a/scripts/kconfig/tests/auto_submenu/expected_stdout b/scripts/kconfig/tests/auto_submenu/expected_stdout
new file mode 100644
index 0000000..bf5236f39
--- /dev/null
+++ b/scripts/kconfig/tests/auto_submenu/expected_stdout
@@ -0,0 +1,10 @@
+A (A) [Y/n/?] (NEW) 
+  A0 (A0) [Y/n/?] (NEW) 
+    A1_0 (A0_0) [N/y/?] (NEW) 
+  A1 (A1) [Y/n/?] (NEW) 
+    choice
+    > 1. A1_0 (A1_0) (NEW)
+      2. A1_1 (A1_1) (NEW)
+    choice[1-2?]: 
+B (B) [N/y/?] (NEW) 
+C (C) [N/y/?] (NEW) 
diff --git a/scripts/kconfig/tests/choice/Kconfig b/scripts/kconfig/tests/choice/Kconfig
new file mode 100644
index 0000000..cc60e9c
--- /dev/null
+++ b/scripts/kconfig/tests/choice/Kconfig
@@ -0,0 +1,54 @@
+config MODULES
+	bool "Enable loadable module support"
+	option modules
+	default y
+
+choice
+	prompt "boolean choice"
+	default BOOL_CHOICE1
+
+config BOOL_CHOICE0
+	bool "choice 0"
+
+config BOOL_CHOICE1
+	bool "choice 1"
+
+endchoice
+
+choice
+	prompt "optional boolean choice"
+	optional
+	default OPT_BOOL_CHOICE1
+
+config OPT_BOOL_CHOICE0
+	bool "choice 0"
+
+config OPT_BOOL_CHOICE1
+	bool "choice 1"
+
+endchoice
+
+choice
+	prompt "tristate choice"
+	default TRI_CHOICE1
+
+config TRI_CHOICE0
+	tristate "choice 0"
+
+config TRI_CHOICE1
+	tristate "choice 1"
+
+endchoice
+
+choice
+	prompt "optional tristate choice"
+	optional
+	default OPT_TRI_CHOICE1
+
+config OPT_TRI_CHOICE0
+	tristate "choice 0"
+
+config OPT_TRI_CHOICE1
+	tristate "choice 1"
+
+endchoice
diff --git a/scripts/kconfig/tests/choice/__init__.py b/scripts/kconfig/tests/choice/__init__.py
new file mode 100644
index 0000000..9edcc52
--- /dev/null
+++ b/scripts/kconfig/tests/choice/__init__.py
@@ -0,0 +1,40 @@
+"""
+Basic choice tests.
+
+The handling of 'choice' is a bit complicated part in Kconfig.
+
+The behavior of 'y' choice is intuitive.  If choice values are tristate,
+the choice can be 'm' where each value can be enabled independently.
+Also, if a choice is marked as 'optional', the whole choice can be
+invisible.
+"""
+
+
+def test_oldask0(conf):
+    assert conf.oldaskconfig() == 0
+    assert conf.stdout_contains('oldask0_expected_stdout')
+
+
+def test_oldask1(conf):
+    assert conf.oldaskconfig('oldask1_config') == 0
+    assert conf.stdout_contains('oldask1_expected_stdout')
+
+
+def test_allyes(conf):
+    assert conf.allyesconfig() == 0
+    assert conf.config_contains('allyes_expected_config')
+
+
+def test_allmod(conf):
+    assert conf.allmodconfig() == 0
+    assert conf.config_contains('allmod_expected_config')
+
+
+def test_allno(conf):
+    assert conf.allnoconfig() == 0
+    assert conf.config_contains('allno_expected_config')
+
+
+def test_alldef(conf):
+    assert conf.alldefconfig() == 0
+    assert conf.config_contains('alldef_expected_config')
diff --git a/scripts/kconfig/tests/choice/alldef_expected_config b/scripts/kconfig/tests/choice/alldef_expected_config
new file mode 100644
index 0000000..7a754bf
--- /dev/null
+++ b/scripts/kconfig/tests/choice/alldef_expected_config
@@ -0,0 +1,5 @@
+CONFIG_MODULES=y
+# CONFIG_BOOL_CHOICE0 is not set
+CONFIG_BOOL_CHOICE1=y
+# CONFIG_TRI_CHOICE0 is not set
+# CONFIG_TRI_CHOICE1 is not set
diff --git a/scripts/kconfig/tests/choice/allmod_expected_config b/scripts/kconfig/tests/choice/allmod_expected_config
new file mode 100644
index 0000000..f1f5dcd
--- /dev/null
+++ b/scripts/kconfig/tests/choice/allmod_expected_config
@@ -0,0 +1,9 @@
+CONFIG_MODULES=y
+# CONFIG_BOOL_CHOICE0 is not set
+CONFIG_BOOL_CHOICE1=y
+# CONFIG_OPT_BOOL_CHOICE0 is not set
+CONFIG_OPT_BOOL_CHOICE1=y
+CONFIG_TRI_CHOICE0=m
+CONFIG_TRI_CHOICE1=m
+CONFIG_OPT_TRI_CHOICE0=m
+CONFIG_OPT_TRI_CHOICE1=m
diff --git a/scripts/kconfig/tests/choice/allno_expected_config b/scripts/kconfig/tests/choice/allno_expected_config
new file mode 100644
index 0000000..b88ee7a
--- /dev/null
+++ b/scripts/kconfig/tests/choice/allno_expected_config
@@ -0,0 +1,5 @@
+# CONFIG_MODULES is not set
+# CONFIG_BOOL_CHOICE0 is not set
+CONFIG_BOOL_CHOICE1=y
+# CONFIG_TRI_CHOICE0 is not set
+CONFIG_TRI_CHOICE1=y
diff --git a/scripts/kconfig/tests/choice/allyes_expected_config b/scripts/kconfig/tests/choice/allyes_expected_config
new file mode 100644
index 0000000..e5a062a
--- /dev/null
+++ b/scripts/kconfig/tests/choice/allyes_expected_config
@@ -0,0 +1,9 @@
+CONFIG_MODULES=y
+# CONFIG_BOOL_CHOICE0 is not set
+CONFIG_BOOL_CHOICE1=y
+# CONFIG_OPT_BOOL_CHOICE0 is not set
+CONFIG_OPT_BOOL_CHOICE1=y
+# CONFIG_TRI_CHOICE0 is not set
+CONFIG_TRI_CHOICE1=y
+# CONFIG_OPT_TRI_CHOICE0 is not set
+CONFIG_OPT_TRI_CHOICE1=y
diff --git a/scripts/kconfig/tests/choice/oldask0_expected_stdout b/scripts/kconfig/tests/choice/oldask0_expected_stdout
new file mode 100644
index 0000000..b251bba
--- /dev/null
+++ b/scripts/kconfig/tests/choice/oldask0_expected_stdout
@@ -0,0 +1,10 @@
+Enable loadable module support (MODULES) [Y/n/?] (NEW) 
+boolean choice
+  1. choice 0 (BOOL_CHOICE0) (NEW)
+> 2. choice 1 (BOOL_CHOICE1) (NEW)
+choice[1-2?]: 
+optional boolean choice [N/y/?] (NEW) 
+tristate choice [M/y/?] (NEW) 
+  choice 0 (TRI_CHOICE0) [N/m/?] (NEW) 
+  choice 1 (TRI_CHOICE1) [N/m/?] (NEW) 
+optional tristate choice [N/m/y/?] (NEW) 
diff --git a/scripts/kconfig/tests/choice/oldask1_config b/scripts/kconfig/tests/choice/oldask1_config
new file mode 100644
index 0000000..b67bfe3
--- /dev/null
+++ b/scripts/kconfig/tests/choice/oldask1_config
@@ -0,0 +1,2 @@
+# CONFIG_MODULES is not set
+CONFIG_OPT_BOOL_CHOICE0=y
diff --git a/scripts/kconfig/tests/choice/oldask1_expected_stdout b/scripts/kconfig/tests/choice/oldask1_expected_stdout
new file mode 100644
index 0000000..c2125e9
--- /dev/null
+++ b/scripts/kconfig/tests/choice/oldask1_expected_stdout
@@ -0,0 +1,15 @@
+Enable loadable module support (MODULES) [N/y/?] 
+boolean choice
+  1. choice 0 (BOOL_CHOICE0) (NEW)
+> 2. choice 1 (BOOL_CHOICE1) (NEW)
+choice[1-2?]: 
+optional boolean choice [Y/n/?] (NEW) 
+optional boolean choice
+> 1. choice 0 (OPT_BOOL_CHOICE0)
+  2. choice 1 (OPT_BOOL_CHOICE1) (NEW)
+choice[1-2?]: 
+tristate choice
+  1. choice 0 (TRI_CHOICE0) (NEW)
+> 2. choice 1 (TRI_CHOICE1) (NEW)
+choice[1-2?]: 
+optional tristate choice [N/y/?] 
diff --git a/scripts/kconfig/tests/choice_value_with_m_dep/Kconfig b/scripts/kconfig/tests/choice_value_with_m_dep/Kconfig
new file mode 100644
index 0000000..11ac25c
--- /dev/null
+++ b/scripts/kconfig/tests/choice_value_with_m_dep/Kconfig
@@ -0,0 +1,19 @@
+config MODULES
+	def_bool y
+	option modules
+
+config DEP
+	tristate
+	default m
+
+choice
+	prompt "Tristate Choice"
+
+config CHOICE0
+	tristate "Choice 0"
+
+config CHOICE1
+	tristate "Choice 1"
+	depends on DEP
+
+endchoice
diff --git a/scripts/kconfig/tests/choice_value_with_m_dep/__init__.py b/scripts/kconfig/tests/choice_value_with_m_dep/__init__.py
new file mode 100644
index 0000000..f8d728c
--- /dev/null
+++ b/scripts/kconfig/tests/choice_value_with_m_dep/__init__.py
@@ -0,0 +1,15 @@
+"""
+Hide tristate choice values with mod dependency in y choice.
+
+If tristate choice values depend on symbols set to 'm', they should be
+hidden when the choice containing them is changed from 'm' to 'y'
+(i.e. exclusive choice).
+
+Related Linux commit: fa64e5f6a35efd5e77d639125d973077ca506074
+"""
+
+
+def test(conf):
+    assert conf.oldaskconfig('config', 'y') == 0
+    assert conf.config_contains('expected_config')
+    assert conf.stdout_contains('expected_stdout')
diff --git a/scripts/kconfig/tests/choice_value_with_m_dep/config b/scripts/kconfig/tests/choice_value_with_m_dep/config
new file mode 100644
index 0000000..3a126b7
--- /dev/null
+++ b/scripts/kconfig/tests/choice_value_with_m_dep/config
@@ -0,0 +1,2 @@
+CONFIG_CHOICE0=m
+CONFIG_CHOICE1=m
diff --git a/scripts/kconfig/tests/choice_value_with_m_dep/expected_config b/scripts/kconfig/tests/choice_value_with_m_dep/expected_config
new file mode 100644
index 0000000..4d07b44
--- /dev/null
+++ b/scripts/kconfig/tests/choice_value_with_m_dep/expected_config
@@ -0,0 +1,3 @@
+CONFIG_MODULES=y
+CONFIG_DEP=m
+CONFIG_CHOICE0=y
diff --git a/scripts/kconfig/tests/choice_value_with_m_dep/expected_stdout b/scripts/kconfig/tests/choice_value_with_m_dep/expected_stdout
new file mode 100644
index 0000000..2b50ab6
--- /dev/null
+++ b/scripts/kconfig/tests/choice_value_with_m_dep/expected_stdout
@@ -0,0 +1,4 @@
+Tristate Choice [M/y/?] y
+Tristate Choice
+> 1. Choice 0 (CHOICE0)
+choice[1]: 1
diff --git a/scripts/kconfig/tests/conftest.py b/scripts/kconfig/tests/conftest.py
new file mode 100644
index 0000000..0345ef6
--- /dev/null
+++ b/scripts/kconfig/tests/conftest.py
@@ -0,0 +1,291 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (C) 2018 Masahiro Yamada <yamada.masahiro@socionext.com>
+#
+
+"""
+Kconfig unit testing framework.
+
+This provides fixture functions commonly used from test files.
+"""
+
+import os
+import pytest
+import shutil
+import subprocess
+import tempfile
+
+CONF_PATH = os.path.abspath(os.path.join('scripts', 'kconfig', 'conf'))
+
+
+class Conf:
+    """Kconfig runner and result checker.
+
+    This class provides methods to run text-based interface of Kconfig
+    (scripts/kconfig/conf) and retrieve the resulted configuration,
+    stdout, and stderr.  It also provides methods to compare those
+    results with expectations.
+    """
+
+    def __init__(self, request):
+        """Create a new Conf instance.
+
+        request: object to introspect the requesting test module
+        """
+        # the directory of the test being run
+        self._test_dir = os.path.dirname(str(request.fspath))
+
+    # runners
+    def _run_conf(self, mode, dot_config=None, out_file='.config',
+                  interactive=False, in_keys=None, extra_env={}):
+        """Run text-based Kconfig executable and save the result.
+
+        mode: input mode option (--oldaskconfig, --defconfig=<file> etc.)
+        dot_config: .config file to use for configuration base
+        out_file: file name to contain the output config data
+        interactive: flag to specify the interactive mode
+        in_keys: key inputs for interactive modes
+        extra_env: additional environments
+        returncode: exit status of the Kconfig executable
+        """
+        command = [CONF_PATH, mode, 'Kconfig']
+
+        # Override 'srctree' environment to make the test as the top directory
+        extra_env['srctree'] = self._test_dir
+
+        # Run Kconfig in a temporary directory.
+        # This directory is automatically removed when done.
+        with tempfile.TemporaryDirectory() as temp_dir:
+
+            # if .config is given, copy it to the working directory
+            if dot_config:
+                shutil.copyfile(os.path.join(self._test_dir, dot_config),
+                                os.path.join(temp_dir, '.config'))
+
+            ps = subprocess.Popen(command,
+                                  stdin=subprocess.PIPE,
+                                  stdout=subprocess.PIPE,
+                                  stderr=subprocess.PIPE,
+                                  cwd=temp_dir,
+                                  env=dict(os.environ, **extra_env))
+
+            # If input key sequence is given, feed it to stdin.
+            if in_keys:
+                ps.stdin.write(in_keys.encode('utf-8'))
+
+            while ps.poll() is None:
+                # For interactive modes such as oldaskconfig, oldconfig,
+                # send 'Enter' key until the program finishes.
+                if interactive:
+                    ps.stdin.write(b'\n')
+
+            self.retcode = ps.returncode
+            self.stdout = ps.stdout.read().decode()
+            self.stderr = ps.stderr.read().decode()
+
+            # Retrieve the resulted config data only when .config is supposed
+            # to exist.  If the command fails, the .config does not exist.
+            # 'listnewconfig' does not produce .config in the first place.
+            if self.retcode == 0 and out_file:
+                with open(os.path.join(temp_dir, out_file)) as f:
+                    self.config = f.read()
+            else:
+                self.config = None
+
+        # Logging:
+        # Pytest captures the following information by default.  In failure
+        # of tests, the captured log will be displayed.  This will be useful to
+        # figure out what has happened.
+
+        print("[command]\n{}\n".format(' '.join(command)))
+
+        print("[retcode]\n{}\n".format(self.retcode))
+
+        print("[stdout]")
+        print(self.stdout)
+
+        print("[stderr]")
+        print(self.stderr)
+
+        if self.config is not None:
+            print("[output for '{}']".format(out_file))
+            print(self.config)
+
+        return self.retcode
+
+    def oldaskconfig(self, dot_config=None, in_keys=None):
+        """Run oldaskconfig.
+
+        dot_config: .config file to use for configuration base (optional)
+        in_key: key inputs (optional)
+        returncode: exit status of the Kconfig executable
+        """
+        return self._run_conf('--oldaskconfig', dot_config=dot_config,
+                              interactive=True, in_keys=in_keys)
+
+    def oldconfig(self, dot_config=None, in_keys=None):
+        """Run oldconfig.
+
+        dot_config: .config file to use for configuration base (optional)
+        in_key: key inputs (optional)
+        returncode: exit status of the Kconfig executable
+        """
+        return self._run_conf('--oldconfig', dot_config=dot_config,
+                              interactive=True, in_keys=in_keys)
+
+    def olddefconfig(self, dot_config=None):
+        """Run olddefconfig.
+
+        dot_config: .config file to use for configuration base (optional)
+        returncode: exit status of the Kconfig executable
+        """
+        return self._run_conf('--olddefconfig', dot_config=dot_config)
+
+    def defconfig(self, defconfig):
+        """Run defconfig.
+
+        defconfig: defconfig file for input
+        returncode: exit status of the Kconfig executable
+        """
+        defconfig_path = os.path.join(self._test_dir, defconfig)
+        return self._run_conf('--defconfig={}'.format(defconfig_path))
+
+    def _allconfig(self, mode, all_config):
+        if all_config:
+            all_config_path = os.path.join(self._test_dir, all_config)
+            extra_env = {'KCONFIG_ALLCONFIG': all_config_path}
+        else:
+            extra_env = {}
+
+        return self._run_conf('--{}config'.format(mode), extra_env=extra_env)
+
+    def allyesconfig(self, all_config=None):
+        """Run allyesconfig.
+
+        all_config: fragment config file for KCONFIG_ALLCONFIG (optional)
+        returncode: exit status of the Kconfig executable
+        """
+        return self._allconfig('allyes', all_config)
+
+    def allmodconfig(self, all_config=None):
+        """Run allmodconfig.
+
+        all_config: fragment config file for KCONFIG_ALLCONFIG (optional)
+        returncode: exit status of the Kconfig executable
+        """
+        return self._allconfig('allmod', all_config)
+
+    def allnoconfig(self, all_config=None):
+        """Run allnoconfig.
+
+        all_config: fragment config file for KCONFIG_ALLCONFIG (optional)
+        returncode: exit status of the Kconfig executable
+        """
+        return self._allconfig('allno', all_config)
+
+    def alldefconfig(self, all_config=None):
+        """Run alldefconfig.
+
+        all_config: fragment config file for KCONFIG_ALLCONFIG (optional)
+        returncode: exit status of the Kconfig executable
+        """
+        return self._allconfig('alldef', all_config)
+
+    def randconfig(self, all_config=None):
+        """Run randconfig.
+
+        all_config: fragment config file for KCONFIG_ALLCONFIG (optional)
+        returncode: exit status of the Kconfig executable
+        """
+        return self._allconfig('rand', all_config)
+
+    def savedefconfig(self, dot_config):
+        """Run savedefconfig.
+
+        dot_config: .config file for input
+        returncode: exit status of the Kconfig executable
+        """
+        return self._run_conf('--savedefconfig', out_file='defconfig')
+
+    def listnewconfig(self, dot_config=None):
+        """Run listnewconfig.
+
+        dot_config: .config file to use for configuration base (optional)
+        returncode: exit status of the Kconfig executable
+        """
+        return self._run_conf('--listnewconfig', dot_config=dot_config,
+                              out_file=None)
+
+    # checkers
+    def _read_and_compare(self, compare, expected):
+        """Compare the result with expectation.
+
+        compare: function to compare the result with expectation
+        expected: file that contains the expected data
+        """
+        with open(os.path.join(self._test_dir, expected)) as f:
+            expected_data = f.read()
+        return compare(self, expected_data)
+
+    def _contains(self, attr, expected):
+        return self._read_and_compare(
+                                    lambda s, e: getattr(s, attr).find(e) >= 0,
+                                    expected)
+
+    def _matches(self, attr, expected):
+        return self._read_and_compare(lambda s, e: getattr(s, attr) == e,
+                                      expected)
+
+    def config_contains(self, expected):
+        """Check if resulted configuration contains expected data.
+
+        expected: file that contains the expected data
+        returncode: True if result contains the expected data, False otherwise
+        """
+        return self._contains('config', expected)
+
+    def config_matches(self, expected):
+        """Check if resulted configuration exactly matches expected data.
+
+        expected: file that contains the expected data
+        returncode: True if result matches the expected data, False otherwise
+        """
+        return self._matches('config', expected)
+
+    def stdout_contains(self, expected):
+        """Check if resulted stdout contains expected data.
+
+        expected: file that contains the expected data
+        returncode: True if result contains the expected data, False otherwise
+        """
+        return self._contains('stdout', expected)
+
+    def stdout_matches(self, expected):
+        """Check if resulted stdout exactly matches expected data.
+
+        expected: file that contains the expected data
+        returncode: True if result matches the expected data, False otherwise
+        """
+        return self._matches('stdout', expected)
+
+    def stderr_contains(self, expected):
+        """Check if resulted stderr contains expected data.
+
+        expected: file that contains the expected data
+        returncode: True if result contains the expected data, False otherwise
+        """
+        return self._contains('stderr', expected)
+
+    def stderr_matches(self, expected):
+        """Check if resulted stderr exactly matches expected data.
+
+        expected: file that contains the expected data
+        returncode: True if result matches the expected data, False otherwise
+        """
+        return self._matches('stderr', expected)
+
+
+@pytest.fixture(scope="module")
+def conf(request):
+    """Create a Conf instance and provide it to test functions."""
+    return Conf(request)
diff --git a/scripts/kconfig/tests/err_recursive_inc/Kconfig b/scripts/kconfig/tests/err_recursive_inc/Kconfig
new file mode 100644
index 0000000..0e4c875
--- /dev/null
+++ b/scripts/kconfig/tests/err_recursive_inc/Kconfig
@@ -0,0 +1 @@
+source "Kconfig.inc1"
diff --git a/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc1 b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc1
new file mode 100644
index 0000000..00e408d
--- /dev/null
+++ b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc1
@@ -0,0 +1,4 @@
+
+
+
+source "Kconfig.inc2"
diff --git a/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc2 b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc2
new file mode 100644
index 0000000..349ea2d
--- /dev/null
+++ b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc2
@@ -0,0 +1,3 @@
+
+
+source "Kconfig.inc3"
diff --git a/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc3 b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc3
new file mode 100644
index 0000000..0e4c875
--- /dev/null
+++ b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc3
@@ -0,0 +1 @@
+source "Kconfig.inc1"
diff --git a/scripts/kconfig/tests/err_recursive_inc/__init__.py b/scripts/kconfig/tests/err_recursive_inc/__init__.py
new file mode 100644
index 0000000..0e4c839
--- /dev/null
+++ b/scripts/kconfig/tests/err_recursive_inc/__init__.py
@@ -0,0 +1,10 @@
+"""
+Detect recursive inclusion error.
+
+If recursive inclusion is detected, it should fail with error messages.
+"""
+
+
+def test(conf):
+    assert conf.oldaskconfig() != 0
+    assert conf.stderr_contains('expected_stderr')
diff --git a/scripts/kconfig/tests/err_recursive_inc/expected_stderr b/scripts/kconfig/tests/err_recursive_inc/expected_stderr
new file mode 100644
index 0000000..6b582ee
--- /dev/null
+++ b/scripts/kconfig/tests/err_recursive_inc/expected_stderr
@@ -0,0 +1,6 @@
+Recursive inclusion detected.
+Inclusion path:
+  current file : Kconfig.inc1
+  included from: Kconfig.inc3:1
+  included from: Kconfig.inc2:3
+  included from: Kconfig.inc1:4
diff --git a/scripts/kconfig/tests/inter_choice/Kconfig b/scripts/kconfig/tests/inter_choice/Kconfig
new file mode 100644
index 0000000..e44449f
--- /dev/null
+++ b/scripts/kconfig/tests/inter_choice/Kconfig
@@ -0,0 +1,23 @@
+config MODULES
+	def_bool y
+	option modules
+
+choice
+	prompt "Choice"
+
+config CHOICE_VAL0
+	tristate "Choice 0"
+
+config CHOIVE_VAL1
+	tristate "Choice 1"
+
+endchoice
+
+choice
+	prompt "Another choice"
+	depends on CHOICE_VAL0
+
+config DUMMY
+	bool "dummy"
+
+endchoice
diff --git a/scripts/kconfig/tests/inter_choice/__init__.py b/scripts/kconfig/tests/inter_choice/__init__.py
new file mode 100644
index 0000000..5c7fc36
--- /dev/null
+++ b/scripts/kconfig/tests/inter_choice/__init__.py
@@ -0,0 +1,14 @@
+"""
+Do not affect user-assigned choice value by another choice.
+
+Handling of state flags for choices is complecated.  In old days,
+the defconfig result of a choice could be affected by another choice
+if those choices interact by 'depends on', 'select', etc.
+
+Related Linux commit: fbe98bb9ed3dae23e320c6b113e35f129538d14a
+"""
+
+
+def test(conf):
+    assert conf.defconfig('defconfig') == 0
+    assert conf.config_contains('expected_config')
diff --git a/scripts/kconfig/tests/inter_choice/defconfig b/scripts/kconfig/tests/inter_choice/defconfig
new file mode 100644
index 0000000..162c414
--- /dev/null
+++ b/scripts/kconfig/tests/inter_choice/defconfig
@@ -0,0 +1 @@
+CONFIG_CHOICE_VAL0=y
diff --git a/scripts/kconfig/tests/inter_choice/expected_config b/scripts/kconfig/tests/inter_choice/expected_config
new file mode 100644
index 0000000..5dceefb
--- /dev/null
+++ b/scripts/kconfig/tests/inter_choice/expected_config
@@ -0,0 +1,4 @@
+CONFIG_MODULES=y
+CONFIG_CHOICE_VAL0=y
+# CONFIG_CHOIVE_VAL1 is not set
+CONFIG_DUMMY=y
diff --git a/scripts/kconfig/tests/new_choice_with_dep/Kconfig b/scripts/kconfig/tests/new_choice_with_dep/Kconfig
new file mode 100644
index 0000000..53ef1b8
--- /dev/null
+++ b/scripts/kconfig/tests/new_choice_with_dep/Kconfig
@@ -0,0 +1,37 @@
+config A
+	bool "A"
+	help
+	  This is a new symbol.
+
+choice
+	prompt "Choice ?"
+	depends on A
+	help
+	  "depends on A" has been newly added.
+
+config CHOICE_B
+	bool "Choice B"
+
+config CHOICE_C
+	bool "Choice C"
+	help
+	  This is a new symbol, so should be asked.
+
+endchoice
+
+choice
+	prompt "Choice2 ?"
+
+config CHOICE_D
+	bool "Choice D"
+
+config CHOICE_E
+	bool "Choice E"
+
+config CHOICE_F
+	bool "Choice F"
+	depends on A
+	help
+	  This is a new symbol, so should be asked.
+
+endchoice
diff --git a/scripts/kconfig/tests/new_choice_with_dep/__init__.py b/scripts/kconfig/tests/new_choice_with_dep/__init__.py
new file mode 100644
index 0000000..f0e0ead
--- /dev/null
+++ b/scripts/kconfig/tests/new_choice_with_dep/__init__.py
@@ -0,0 +1,14 @@
+"""
+Ask new choice values when they become visible.
+
+If new choice values are added with new dependency, and they become
+visible during user configuration, oldconfig should recognize them
+as (NEW), and ask the user for choice.
+
+Related Linux commit: 5d09598d488f081e3be23f885ed65cbbe2d073b5
+"""
+
+
+def test(conf):
+    assert conf.oldconfig('config', 'y') == 0
+    assert conf.stdout_contains('expected_stdout')
diff --git a/scripts/kconfig/tests/new_choice_with_dep/config b/scripts/kconfig/tests/new_choice_with_dep/config
new file mode 100644
index 0000000..47ef95d
--- /dev/null
+++ b/scripts/kconfig/tests/new_choice_with_dep/config
@@ -0,0 +1,3 @@
+CONFIG_CHOICE_B=y
+# CONFIG_CHOICE_D is not set
+CONFIG_CHOICE_E=y
diff --git a/scripts/kconfig/tests/new_choice_with_dep/expected_stdout b/scripts/kconfig/tests/new_choice_with_dep/expected_stdout
new file mode 100644
index 0000000..74dc0bc
--- /dev/null
+++ b/scripts/kconfig/tests/new_choice_with_dep/expected_stdout
@@ -0,0 +1,10 @@
+A (A) [N/y/?] (NEW) y
+  Choice ?
+  > 1. Choice B (CHOICE_B)
+    2. Choice C (CHOICE_C) (NEW)
+  choice[1-2?]: 
+Choice2 ?
+  1. Choice D (CHOICE_D)
+> 2. Choice E (CHOICE_E)
+  3. Choice F (CHOICE_F) (NEW)
+choice[1-3?]: 
diff --git a/scripts/kconfig/tests/no_write_if_dep_unmet/Kconfig b/scripts/kconfig/tests/no_write_if_dep_unmet/Kconfig
new file mode 100644
index 0000000..c00b8fe
--- /dev/null
+++ b/scripts/kconfig/tests/no_write_if_dep_unmet/Kconfig
@@ -0,0 +1,14 @@
+config A
+	bool "A"
+
+choice
+	prompt "Choice ?"
+	depends on A
+
+config CHOICE_B
+	bool "Choice B"
+
+config CHOICE_C
+	bool "Choice C"
+
+endchoice
diff --git a/scripts/kconfig/tests/no_write_if_dep_unmet/__init__.py b/scripts/kconfig/tests/no_write_if_dep_unmet/__init__.py
new file mode 100644
index 0000000..207261b
--- /dev/null
+++ b/scripts/kconfig/tests/no_write_if_dep_unmet/__init__.py
@@ -0,0 +1,19 @@
+"""
+Do not write choice values to .config if the dependency is unmet.
+
+"# CONFIG_... is not set" should not be written into the .config file
+for symbols with unmet dependency.
+
+This was not working correctly for choice values because choice needs
+a bit different symbol computation.
+
+This checks that no unneeded "# COFIG_... is not set" is contained in
+the .config file.
+
+Related Linux commit: cb67ab2cd2b8abd9650292c986c79901e3073a59
+"""
+
+
+def test(conf):
+    assert conf.oldaskconfig('config', 'n') == 0
+    assert conf.config_matches('expected_config')
diff --git a/scripts/kconfig/tests/no_write_if_dep_unmet/config b/scripts/kconfig/tests/no_write_if_dep_unmet/config
new file mode 100644
index 0000000..abd280e
--- /dev/null
+++ b/scripts/kconfig/tests/no_write_if_dep_unmet/config
@@ -0,0 +1 @@
+CONFIG_A=y
diff --git a/scripts/kconfig/tests/no_write_if_dep_unmet/expected_config b/scripts/kconfig/tests/no_write_if_dep_unmet/expected_config
new file mode 100644
index 0000000..0d15e41
--- /dev/null
+++ b/scripts/kconfig/tests/no_write_if_dep_unmet/expected_config
@@ -0,0 +1,5 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# Linux Kernel Configuration
+#
+# CONFIG_A is not set
diff --git a/scripts/kconfig/tests/pytest.ini b/scripts/kconfig/tests/pytest.ini
new file mode 100644
index 0000000..85d7ce8
--- /dev/null
+++ b/scripts/kconfig/tests/pytest.ini
@@ -0,0 +1,7 @@
+[pytest]
+addopts = --verbose
+
+# Pytest requires that test files have unique names, because pytest imports
+# them as top-level modules.  It is silly to prefix or suffix a test file with
+# the directory name that contains it.  Use __init__.py for all test files.
+python_files = __init__.py
diff --git a/scripts/kconfig/tests/rand_nested_choice/Kconfig b/scripts/kconfig/tests/rand_nested_choice/Kconfig
new file mode 100644
index 0000000..c591d51
--- /dev/null
+++ b/scripts/kconfig/tests/rand_nested_choice/Kconfig
@@ -0,0 +1,33 @@
+choice
+	prompt "choice"
+
+config A
+	bool "A"
+
+config B
+	bool "B"
+
+if B
+choice
+	prompt "sub choice"
+
+config C
+	bool "C"
+
+config D
+	bool "D"
+
+if D
+choice
+	prompt "subsub choice"
+
+config E
+	bool "E"
+
+endchoice
+endif # D
+
+endchoice
+endif # B
+
+endchoice
diff --git a/scripts/kconfig/tests/rand_nested_choice/__init__.py b/scripts/kconfig/tests/rand_nested_choice/__init__.py
new file mode 100644
index 0000000..e729a4e
--- /dev/null
+++ b/scripts/kconfig/tests/rand_nested_choice/__init__.py
@@ -0,0 +1,16 @@
+"""
+Set random values recursively in nested choices.
+
+Kconfig can create a choice-in-choice structure by using 'if' statement.
+randconfig should correctly set random choice values.
+
+Related Linux commit: 3b9a19e08960e5cdad5253998637653e592a3c29
+"""
+
+
+def test(conf):
+    for i in range(20):
+        assert conf.randconfig() == 0
+        assert (conf.config_contains('expected_stdout0') or
+                conf.config_contains('expected_stdout1') or
+                conf.config_contains('expected_stdout2'))
diff --git a/scripts/kconfig/tests/rand_nested_choice/expected_stdout0 b/scripts/kconfig/tests/rand_nested_choice/expected_stdout0
new file mode 100644
index 0000000..05450f3
--- /dev/null
+++ b/scripts/kconfig/tests/rand_nested_choice/expected_stdout0
@@ -0,0 +1,2 @@
+CONFIG_A=y
+# CONFIG_B is not set
diff --git a/scripts/kconfig/tests/rand_nested_choice/expected_stdout1 b/scripts/kconfig/tests/rand_nested_choice/expected_stdout1
new file mode 100644
index 0000000..37ab295
--- /dev/null
+++ b/scripts/kconfig/tests/rand_nested_choice/expected_stdout1
@@ -0,0 +1,4 @@
+# CONFIG_A is not set
+CONFIG_B=y
+CONFIG_C=y
+# CONFIG_D is not set
diff --git a/scripts/kconfig/tests/rand_nested_choice/expected_stdout2 b/scripts/kconfig/tests/rand_nested_choice/expected_stdout2
new file mode 100644
index 0000000..849ff47
--- /dev/null
+++ b/scripts/kconfig/tests/rand_nested_choice/expected_stdout2
@@ -0,0 +1,5 @@
+# CONFIG_A is not set
+CONFIG_B=y
+# CONFIG_C is not set
+CONFIG_D=y
+CONFIG_E=y
diff --git a/scripts/kconfig/tests/warn_recursive_dep/Kconfig b/scripts/kconfig/tests/warn_recursive_dep/Kconfig
new file mode 100644
index 0000000..a65bfcb
--- /dev/null
+++ b/scripts/kconfig/tests/warn_recursive_dep/Kconfig
@@ -0,0 +1,62 @@
+# depends on itself
+
+config A
+	bool "A"
+	depends on A
+
+# select itself
+
+config B
+	bool
+	select B
+
+# depends on each other
+
+config C1
+	bool "C1"
+	depends on C2
+
+config C2
+	bool "C2"
+	depends on C1
+
+# depends on and select
+
+config D1
+	bool "D1"
+	depends on D2
+	select D2
+
+config D2
+	bool
+
+# depends on and imply
+# This is not recursive dependency
+
+config E1
+	bool "E1"
+	depends on E2
+	imply E2
+
+config E2
+	bool "E2"
+
+# property
+
+config F1
+	bool "F1"
+	default F2
+
+config F2
+	bool "F2"
+	depends on F1
+
+# menu
+
+menu "menu depending on its content"
+	depends on G
+
+config G
+	bool "G"
+
+endmenu
diff --git a/scripts/kconfig/tests/warn_recursive_dep/__init__.py b/scripts/kconfig/tests/warn_recursive_dep/__init__.py
new file mode 100644
index 0000000..adb2195
--- /dev/null
+++ b/scripts/kconfig/tests/warn_recursive_dep/__init__.py
@@ -0,0 +1,9 @@
+"""
+Warn recursive inclusion.
+
+Recursive dependency should be warned.
+"""
+
+def test(conf):
+    assert conf.oldaskconfig() == 0
+    assert conf.stderr_contains('expected_stderr')
diff --git a/scripts/kconfig/tests/warn_recursive_dep/expected_stderr b/scripts/kconfig/tests/warn_recursive_dep/expected_stderr
new file mode 100644
index 0000000..3de807d
--- /dev/null
+++ b/scripts/kconfig/tests/warn_recursive_dep/expected_stderr
@@ -0,0 +1,30 @@
+Kconfig:9:error: recursive dependency detected!
+Kconfig:9:	symbol B is selected by B
+For a resolution refer to Documentation/kbuild/kconfig-language.txt
+subsection "Kconfig recursive dependency limitations"
+
+Kconfig:3:error: recursive dependency detected!
+Kconfig:3:	symbol A depends on A
+For a resolution refer to Documentation/kbuild/kconfig-language.txt
+subsection "Kconfig recursive dependency limitations"
+
+Kconfig:15:error: recursive dependency detected!
+Kconfig:15:	symbol C1 depends on C2
+Kconfig:19:	symbol C2 depends on C1
+For a resolution refer to Documentation/kbuild/kconfig-language.txt
+subsection "Kconfig recursive dependency limitations"
+
+Kconfig:30:error: recursive dependency detected!
+Kconfig:30:	symbol D2 is selected by D1
+Kconfig:25:	symbol D1 depends on D2
+For a resolution refer to Documentation/kbuild/kconfig-language.txt
+subsection "Kconfig recursive dependency limitations"
+
+Kconfig:59:error: recursive dependency detected!
+Kconfig:59:	symbol G depends on G
+For a resolution refer to Documentation/kbuild/kconfig-language.txt
+subsection "Kconfig recursive dependency limitations"
+
+Kconfig:50:error: recursive dependency detected!
+Kconfig:50:	symbol F2 depends on F1
+Kconfig:48:	symbol F1 default value contains F2
diff --git a/scripts/kconfig/util.c b/scripts/kconfig/util.c
index 0e76042..c6f6e21 100644
--- a/scripts/kconfig/util.c
+++ b/scripts/kconfig/util.c
@@ -14,11 +14,11 @@
 struct file *file_lookup(const char *name)
 {
 	struct file *file;
-	const char *file_name = sym_expand_string_value(name);
+	char *file_name = sym_expand_string_value(name);
 
 	for (file = file_list; file; file = file->next) {
 		if (!strcmp(name, file->name)) {
-			free((void *)file_name);
+			free(file_name);
 			return file;
 		}
 	}
@@ -104,7 +104,7 @@
 	if (s) {
 		l = strlen(gs->s) + strlen(s) + 1;
 		if (l > gs->len) {
-			gs->s   = realloc(gs->s, l);
+			gs->s = xrealloc(gs->s, l);
 			gs->len = l;
 		}
 		strcat(gs->s, s);
@@ -145,3 +145,23 @@
 	fprintf(stderr, "Out of memory.\n");
 	exit(1);
 }
+
+void *xrealloc(void *p, size_t size)
+{
+	p = realloc(p, size);
+	if (p)
+		return p;
+	fprintf(stderr, "Out of memory.\n");
+	exit(1);
+}
+
+char *xstrdup(const char *s)
+{
+	char *p;
+
+	p = strdup(s);
+	if (p)
+		return p;
+	fprintf(stderr, "Out of memory.\n");
+	exit(1);
+}
diff --git a/scripts/kconfig/zconf.gperf b/scripts/kconfig/zconf.gperf
deleted file mode 100644
index ead02ed..0000000
--- a/scripts/kconfig/zconf.gperf
+++ /dev/null
@@ -1,50 +0,0 @@
-%language=ANSI-C
-%define hash-function-name kconf_id_hash
-%define lookup-function-name kconf_id_lookup
-%define string-pool-name kconf_id_strings
-%compare-strncmp
-%enum
-%pic
-%struct-type
-
-struct kconf_id;
-
-static const struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len);
-
-%%
-mainmenu,	T_MAINMENU,	TF_COMMAND
-menu,		T_MENU,		TF_COMMAND
-endmenu,	T_ENDMENU,	TF_COMMAND
-source,		T_SOURCE,	TF_COMMAND
-choice,		T_CHOICE,	TF_COMMAND
-endchoice,	T_ENDCHOICE,	TF_COMMAND
-comment,	T_COMMENT,	TF_COMMAND
-config,		T_CONFIG,	TF_COMMAND
-menuconfig,	T_MENUCONFIG,	TF_COMMAND
-help,		T_HELP,		TF_COMMAND
----help---,	T_HELP,		TF_COMMAND
-if,		T_IF,		TF_COMMAND|TF_PARAM
-endif,		T_ENDIF,	TF_COMMAND
-depends,	T_DEPENDS,	TF_COMMAND
-optional,	T_OPTIONAL,	TF_COMMAND
-default,	T_DEFAULT,	TF_COMMAND, S_UNKNOWN
-prompt,		T_PROMPT,	TF_COMMAND
-tristate,	T_TYPE,		TF_COMMAND, S_TRISTATE
-def_tristate,	T_DEFAULT,	TF_COMMAND, S_TRISTATE
-bool,		T_TYPE,		TF_COMMAND, S_BOOLEAN
-boolean,	T_TYPE,		TF_COMMAND, S_BOOLEAN
-def_bool,	T_DEFAULT,	TF_COMMAND, S_BOOLEAN
-int,		T_TYPE,		TF_COMMAND, S_INT
-hex,		T_TYPE,		TF_COMMAND, S_HEX
-string,		T_TYPE,		TF_COMMAND, S_STRING
-select,		T_SELECT,	TF_COMMAND
-imply,		T_IMPLY,	TF_COMMAND
-range,		T_RANGE,	TF_COMMAND
-visible,	T_VISIBLE,	TF_COMMAND
-option,		T_OPTION,	TF_COMMAND
-on,		T_ON,		TF_PARAM
-modules,	T_OPT_MODULES,	TF_OPTION
-defconfig_list,	T_OPT_DEFCONFIG_LIST,TF_OPTION
-env,		T_OPT_ENV,	TF_OPTION
-allnoconfig_y,	T_OPT_ALLNOCONFIG_Y,TF_OPTION
-%%
diff --git a/scripts/kconfig/zconf.hash.c_shipped b/scripts/kconfig/zconf.hash.c_shipped
deleted file mode 100644
index d51b15d..0000000
--- a/scripts/kconfig/zconf.hash.c_shipped
+++ /dev/null
@@ -1,297 +0,0 @@
-/* ANSI-C code produced by gperf version 3.0.4 */
-/* Command-line: gperf -t --output-file scripts/kconfig/zconf.hash.c_shipped -a -C -E -g -k '1,3,$' -p -t scripts/kconfig/zconf.gperf  */
-
-#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
-      && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
-      && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
-      && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
-      && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
-      && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
-      && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
-      && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
-      && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
-      && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
-      && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
-      && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
-      && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
-      && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
-      && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
-      && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
-      && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
-      && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
-      && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
-      && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
-      && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
-      && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
-      && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
-/* The character set is not based on ISO-646.  */
-#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
-#endif
-
-#line 10 "scripts/kconfig/zconf.gperf"
-struct kconf_id;
-
-static const struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len);
-/* maximum key range = 71, duplicates = 0 */
-
-#ifdef __GNUC__
-__inline
-#else
-#ifdef __cplusplus
-inline
-#endif
-#endif
-static unsigned int
-kconf_id_hash (register const char *str, register unsigned int len)
-{
-  static const unsigned char asso_values[] =
-    {
-      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
-      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
-      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
-      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
-      73, 73, 73, 73, 73,  0, 73, 73, 73, 73,
-      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
-      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
-      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
-      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
-      73, 73, 73, 73, 73, 73, 73, 10, 25, 25,
-       0,  0,  0,  5,  0,  0, 73, 73,  5,  0,
-      10,  5, 45, 73, 20, 20,  0, 15, 15, 73,
-      20,  0, 73, 73, 73, 73, 73, 73, 73, 73,
-      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
-      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
-      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
-      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
-      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
-      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
-      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
-      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
-      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
-      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
-      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
-      73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
-      73, 73, 73, 73, 73, 73
-    };
-  register int hval = len;
-
-  switch (hval)
-    {
-      default:
-        hval += asso_values[(unsigned char)str[2]];
-      /*FALLTHROUGH*/
-      case 2:
-      case 1:
-        hval += asso_values[(unsigned char)str[0]];
-        break;
-    }
-  return hval + asso_values[(unsigned char)str[len - 1]];
-}
-
-struct kconf_id_strings_t
-  {
-    char kconf_id_strings_str2[sizeof("if")];
-    char kconf_id_strings_str3[sizeof("int")];
-    char kconf_id_strings_str5[sizeof("endif")];
-    char kconf_id_strings_str7[sizeof("default")];
-    char kconf_id_strings_str8[sizeof("tristate")];
-    char kconf_id_strings_str9[sizeof("endchoice")];
-    char kconf_id_strings_str10[sizeof("---help---")];
-    char kconf_id_strings_str12[sizeof("def_tristate")];
-    char kconf_id_strings_str13[sizeof("def_bool")];
-    char kconf_id_strings_str14[sizeof("defconfig_list")];
-    char kconf_id_strings_str17[sizeof("on")];
-    char kconf_id_strings_str18[sizeof("optional")];
-    char kconf_id_strings_str21[sizeof("option")];
-    char kconf_id_strings_str22[sizeof("endmenu")];
-    char kconf_id_strings_str23[sizeof("mainmenu")];
-    char kconf_id_strings_str25[sizeof("menuconfig")];
-    char kconf_id_strings_str27[sizeof("modules")];
-    char kconf_id_strings_str28[sizeof("allnoconfig_y")];
-    char kconf_id_strings_str29[sizeof("menu")];
-    char kconf_id_strings_str31[sizeof("select")];
-    char kconf_id_strings_str32[sizeof("comment")];
-    char kconf_id_strings_str33[sizeof("env")];
-    char kconf_id_strings_str35[sizeof("range")];
-    char kconf_id_strings_str36[sizeof("choice")];
-    char kconf_id_strings_str39[sizeof("bool")];
-    char kconf_id_strings_str41[sizeof("source")];
-    char kconf_id_strings_str42[sizeof("visible")];
-    char kconf_id_strings_str43[sizeof("hex")];
-    char kconf_id_strings_str46[sizeof("config")];
-    char kconf_id_strings_str47[sizeof("boolean")];
-    char kconf_id_strings_str50[sizeof("imply")];
-    char kconf_id_strings_str51[sizeof("string")];
-    char kconf_id_strings_str54[sizeof("help")];
-    char kconf_id_strings_str56[sizeof("prompt")];
-    char kconf_id_strings_str72[sizeof("depends")];
-  };
-static const struct kconf_id_strings_t kconf_id_strings_contents =
-  {
-    "if",
-    "int",
-    "endif",
-    "default",
-    "tristate",
-    "endchoice",
-    "---help---",
-    "def_tristate",
-    "def_bool",
-    "defconfig_list",
-    "on",
-    "optional",
-    "option",
-    "endmenu",
-    "mainmenu",
-    "menuconfig",
-    "modules",
-    "allnoconfig_y",
-    "menu",
-    "select",
-    "comment",
-    "env",
-    "range",
-    "choice",
-    "bool",
-    "source",
-    "visible",
-    "hex",
-    "config",
-    "boolean",
-    "imply",
-    "string",
-    "help",
-    "prompt",
-    "depends"
-  };
-#define kconf_id_strings ((const char *) &kconf_id_strings_contents)
-#ifdef __GNUC__
-__inline
-#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
-__attribute__ ((__gnu_inline__))
-#endif
-#endif
-const struct kconf_id *
-kconf_id_lookup (register const char *str, register unsigned int len)
-{
-  enum
-    {
-      TOTAL_KEYWORDS = 35,
-      MIN_WORD_LENGTH = 2,
-      MAX_WORD_LENGTH = 14,
-      MIN_HASH_VALUE = 2,
-      MAX_HASH_VALUE = 72
-    };
-
-  static const struct kconf_id wordlist[] =
-    {
-      {-1}, {-1},
-#line 26 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str2,		T_IF,		TF_COMMAND|TF_PARAM},
-#line 37 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str3,		T_TYPE,		TF_COMMAND, S_INT},
-      {-1},
-#line 27 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str5,		T_ENDIF,	TF_COMMAND},
-      {-1},
-#line 30 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str7,	T_DEFAULT,	TF_COMMAND, S_UNKNOWN},
-#line 32 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str8,	T_TYPE,		TF_COMMAND, S_TRISTATE},
-#line 20 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str9,	T_ENDCHOICE,	TF_COMMAND},
-#line 25 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str10,	T_HELP,		TF_COMMAND},
-      {-1},
-#line 33 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12,	T_DEFAULT,	TF_COMMAND, S_TRISTATE},
-#line 36 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13,	T_DEFAULT,	TF_COMMAND, S_BOOLEAN},
-#line 47 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14,	T_OPT_DEFCONFIG_LIST,TF_OPTION},
-      {-1}, {-1},
-#line 45 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17,		T_ON,		TF_PARAM},
-#line 29 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18,	T_OPTIONAL,	TF_COMMAND},
-      {-1}, {-1},
-#line 44 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21,		T_OPTION,	TF_COMMAND},
-#line 17 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22,	T_ENDMENU,	TF_COMMAND},
-#line 15 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23,	T_MAINMENU,	TF_COMMAND},
-      {-1},
-#line 23 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str25,	T_MENUCONFIG,	TF_COMMAND},
-      {-1},
-#line 46 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27,	T_OPT_MODULES,	TF_OPTION},
-#line 49 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28,	T_OPT_ALLNOCONFIG_Y,TF_OPTION},
-#line 16 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str29,		T_MENU,		TF_COMMAND},
-      {-1},
-#line 40 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31,		T_SELECT,	TF_COMMAND},
-#line 21 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32,	T_COMMENT,	TF_COMMAND},
-#line 48 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33,		T_OPT_ENV,	TF_OPTION},
-      {-1},
-#line 42 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str35,		T_RANGE,	TF_COMMAND},
-#line 19 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str36,		T_CHOICE,	TF_COMMAND},
-      {-1}, {-1},
-#line 34 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str39,		T_TYPE,		TF_COMMAND, S_BOOLEAN},
-      {-1},
-#line 18 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str41,		T_SOURCE,	TF_COMMAND},
-#line 43 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str42,	T_VISIBLE,	TF_COMMAND},
-#line 38 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str43,		T_TYPE,		TF_COMMAND, S_HEX},
-      {-1}, {-1},
-#line 22 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str46,		T_CONFIG,	TF_COMMAND},
-#line 35 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str47,	T_TYPE,		TF_COMMAND, S_BOOLEAN},
-      {-1}, {-1},
-#line 41 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str50,		T_IMPLY,	TF_COMMAND},
-#line 39 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str51,		T_TYPE,		TF_COMMAND, S_STRING},
-      {-1}, {-1},
-#line 24 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str54,		T_HELP,		TF_COMMAND},
-      {-1},
-#line 31 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str56,		T_PROMPT,	TF_COMMAND},
-      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
-      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
-#line 28 "scripts/kconfig/zconf.gperf"
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str72,	T_DEPENDS,	TF_COMMAND}
-    };
-
-  if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
-    {
-      register int key = kconf_id_hash (str, len);
-
-      if (key <= MAX_HASH_VALUE && key >= 0)
-        {
-          register int o = wordlist[key].name;
-          if (o >= 0)
-            {
-              register const char *s = o + kconf_id_strings;
-
-              if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0')
-                return &wordlist[key];
-            }
-        }
-    }
-  return 0;
-}
-#line 50 "scripts/kconfig/zconf.gperf"
-
diff --git a/scripts/kconfig/zconf.l b/scripts/kconfig/zconf.l
index c410d25..045093d 100644
--- a/scripts/kconfig/zconf.l
+++ b/scripts/kconfig/zconf.l
@@ -1,5 +1,5 @@
 %option nostdinit noyywrap never-interactive full ecs
-%option 8bit nodefault perf-report perf-report
+%option 8bit nodefault yylineno
 %option noinput
 %x COMMAND HELP STRING PARAM
 %{
@@ -52,7 +52,7 @@
 	if (new_size > text_asize) {
 		new_size += START_STRSIZE - 1;
 		new_size &= -START_STRSIZE;
-		text = realloc(text, new_size);
+		text = xrealloc(text, new_size);
 		text_asize = new_size;
 	}
 	memcpy(text + text_size, str, size);
@@ -83,7 +83,6 @@
 
 [ \t]*#.*\n	|
 [ \t]*\n	{
-	current_file->lineno++;
 	return T_EOL;
 }
 [ \t]*#.*
@@ -104,19 +103,18 @@
 		const struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
 		BEGIN(PARAM);
 		current_pos.file = current_file;
-		current_pos.lineno = current_file->lineno;
+		current_pos.lineno = yylineno;
 		if (id && id->flags & TF_COMMAND) {
-			zconflval.id = id;
+			yylval.id = id;
 			return id->token;
 		}
 		alloc_string(yytext, yyleng);
-		zconflval.string = text;
+		yylval.string = text;
 		return T_WORD;
 	}
 	.	warn_ignored_character(*yytext);
 	\n	{
 		BEGIN(INITIAL);
-		current_file->lineno++;
 		return T_EOL;
 	}
 }
@@ -138,19 +136,19 @@
 		new_string();
 		BEGIN(STRING);
 	}
-	\n	BEGIN(INITIAL); current_file->lineno++; return T_EOL;
+	\n	BEGIN(INITIAL); return T_EOL;
 	({n}|[/.])+	{
 		const struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
 		if (id && id->flags & TF_PARAM) {
-			zconflval.id = id;
+			yylval.id = id;
 			return id->token;
 		}
 		alloc_string(yytext, yyleng);
-		zconflval.string = text;
+		yylval.string = text;
 		return T_WORD;
 	}
 	#.*	/* comment */
-	\\\n	current_file->lineno++;
+	\\\n	;
 	[[:blank:]]+
 	.	warn_ignored_character(*yytext);
 	<<EOF>> {
@@ -161,7 +159,7 @@
 <STRING>{
 	[^'"\\\n]+/\n	{
 		append_string(yytext, yyleng);
-		zconflval.string = text;
+		yylval.string = text;
 		return T_WORD_QUOTE;
 	}
 	[^'"\\\n]+	{
@@ -169,7 +167,7 @@
 	}
 	\\.?/\n	{
 		append_string(yytext + 1, yyleng - 1);
-		zconflval.string = text;
+		yylval.string = text;
 		return T_WORD_QUOTE;
 	}
 	\\.?	{
@@ -178,14 +176,15 @@
 	\'|\"	{
 		if (str == yytext[0]) {
 			BEGIN(PARAM);
-			zconflval.string = text;
+			yylval.string = text;
 			return T_WORD_QUOTE;
 		} else
 			append_string(yytext, 1);
 	}
 	\n	{
-		printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno());
-		current_file->lineno++;
+		fprintf(stderr,
+			"%s:%d:warning: multi-line strings not supported\n",
+			zconf_curname(), zconf_lineno());
 		BEGIN(INITIAL);
 		return T_EOL;
 	}
@@ -218,12 +217,10 @@
 		}
 	}
 	[ \t]*\n/[^ \t\n] {
-		current_file->lineno++;
 		zconf_endhelp();
 		return T_HELPTEXT;
 	}
 	[ \t]*\n	{
-		current_file->lineno++;
 		append_string("\n", 1);
 	}
 	[^ \t\n].* {
@@ -261,7 +258,7 @@
 
 static void zconf_endhelp(void)
 {
-	zconflval.string = text;
+	yylval.string = text;
 	BEGIN(INITIAL);
 }
 
@@ -294,7 +291,7 @@
 {
 	yyin = zconf_fopen(name);
 	if (!yyin) {
-		printf("can't find file %s\n", name);
+		fprintf(stderr, "can't find file %s\n", name);
 		exit(1);
 	}
 
@@ -302,7 +299,7 @@
 	memset(current_buf, 0, sizeof(*current_buf));
 
 	current_file = file_lookup(name);
-	current_file->lineno = 1;
+	yylineno = 1;
 }
 
 void zconf_nextfile(const char *name)
@@ -315,35 +312,34 @@
 	current_buf->state = YY_CURRENT_BUFFER;
 	yyin = zconf_fopen(file->name);
 	if (!yyin) {
-		printf("%s:%d: can't open file \"%s\"\n",
-		    zconf_curname(), zconf_lineno(), file->name);
+		fprintf(stderr, "%s:%d: can't open file \"%s\"\n",
+			zconf_curname(), zconf_lineno(), file->name);
 		exit(1);
 	}
 	yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
 	buf->parent = current_buf;
 	current_buf = buf;
 
-	for (iter = current_file->parent; iter; iter = iter->parent ) {
-		if (!strcmp(current_file->name,iter->name) ) {
-			printf("%s:%d: recursive inclusion detected. "
-			       "Inclusion path:\n  current file : '%s'\n",
-			       zconf_curname(), zconf_lineno(),
-			       zconf_curname());
-			iter = current_file->parent;
-			while (iter && \
-			       strcmp(iter->name,current_file->name)) {
-				printf("  included from: '%s:%d'\n",
-				       iter->name, iter->lineno-1);
+	current_file->lineno = yylineno;
+	file->parent = current_file;
+
+	for (iter = current_file; iter; iter = iter->parent) {
+		if (!strcmp(iter->name, file->name)) {
+			fprintf(stderr,
+				"Recursive inclusion detected.\n"
+				"Inclusion path:\n"
+				"  current file : %s\n", file->name);
+			iter = file;
+			do {
 				iter = iter->parent;
-			}
-			if (iter)
-				printf("  included from: '%s:%d'\n",
-				       iter->name, iter->lineno+1);
+				fprintf(stderr, "  included from: %s:%d\n",
+					iter->name, iter->lineno - 1);
+			} while (strcmp(iter->name, file->name));
 			exit(1);
 		}
 	}
-	file->lineno = 1;
-	file->parent = current_file;
+
+	yylineno = 1;
 	current_file = file;
 }
 
@@ -352,6 +348,8 @@
 	struct buffer *parent;
 
 	current_file = current_file->parent;
+	if (current_file)
+		yylineno = current_file->lineno;
 
 	parent = current_buf->parent;
 	if (parent) {
diff --git a/scripts/kconfig/zconf.lex.c_shipped b/scripts/kconfig/zconf.lex.c_shipped
deleted file mode 100644
index 37fdf61..0000000
--- a/scripts/kconfig/zconf.lex.c_shipped
+++ /dev/null
@@ -1,2473 +0,0 @@
-
-#line 3 "scripts/kconfig/zconf.lex.c_shipped"
-
-#define  YY_INT_ALIGNED short int
-
-/* A lexical scanner generated by flex */
-
-#define yy_create_buffer zconf_create_buffer
-#define yy_delete_buffer zconf_delete_buffer
-#define yy_flex_debug zconf_flex_debug
-#define yy_init_buffer zconf_init_buffer
-#define yy_flush_buffer zconf_flush_buffer
-#define yy_load_buffer_state zconf_load_buffer_state
-#define yy_switch_to_buffer zconf_switch_to_buffer
-#define yyin zconfin
-#define yyleng zconfleng
-#define yylex zconflex
-#define yylineno zconflineno
-#define yyout zconfout
-#define yyrestart zconfrestart
-#define yytext zconftext
-#define yywrap zconfwrap
-#define yyalloc zconfalloc
-#define yyrealloc zconfrealloc
-#define yyfree zconffree
-
-#define FLEX_SCANNER
-#define YY_FLEX_MAJOR_VERSION 2
-#define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 35
-#if YY_FLEX_SUBMINOR_VERSION > 0
-#define FLEX_BETA
-#endif
-
-/* First, we deal with  platform-specific or compiler-specific issues. */
-
-/* begin standard C headers. */
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-
-/* end standard C headers. */
-
-/* flex integer type definitions */
-
-#ifndef FLEXINT_H
-#define FLEXINT_H
-
-/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
-
-#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-
-/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
- * if you want the limit (max/min) macros for int types. 
- */
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS 1
-#endif
-
-#include <inttypes.h>
-typedef int8_t flex_int8_t;
-typedef uint8_t flex_uint8_t;
-typedef int16_t flex_int16_t;
-typedef uint16_t flex_uint16_t;
-typedef int32_t flex_int32_t;
-typedef uint32_t flex_uint32_t;
-#else
-typedef signed char flex_int8_t;
-typedef short int flex_int16_t;
-typedef int flex_int32_t;
-typedef unsigned char flex_uint8_t; 
-typedef unsigned short int flex_uint16_t;
-typedef unsigned int flex_uint32_t;
-
-/* Limits of integral types. */
-#ifndef INT8_MIN
-#define INT8_MIN               (-128)
-#endif
-#ifndef INT16_MIN
-#define INT16_MIN              (-32767-1)
-#endif
-#ifndef INT32_MIN
-#define INT32_MIN              (-2147483647-1)
-#endif
-#ifndef INT8_MAX
-#define INT8_MAX               (127)
-#endif
-#ifndef INT16_MAX
-#define INT16_MAX              (32767)
-#endif
-#ifndef INT32_MAX
-#define INT32_MAX              (2147483647)
-#endif
-#ifndef UINT8_MAX
-#define UINT8_MAX              (255U)
-#endif
-#ifndef UINT16_MAX
-#define UINT16_MAX             (65535U)
-#endif
-#ifndef UINT32_MAX
-#define UINT32_MAX             (4294967295U)
-#endif
-
-#endif /* ! C99 */
-
-#endif /* ! FLEXINT_H */
-
-#ifdef __cplusplus
-
-/* The "const" storage-class-modifier is valid. */
-#define YY_USE_CONST
-
-#else	/* ! __cplusplus */
-
-/* C99 requires __STDC__ to be defined as 1. */
-#if defined (__STDC__)
-
-#define YY_USE_CONST
-
-#endif	/* defined (__STDC__) */
-#endif	/* ! __cplusplus */
-
-#ifdef YY_USE_CONST
-#define yyconst const
-#else
-#define yyconst
-#endif
-
-/* Returned upon end-of-file. */
-#define YY_NULL 0
-
-/* Promotes a possibly negative, possibly signed char to an unsigned
- * integer for use as an array index.  If the signed char is negative,
- * we want to instead treat it as an 8-bit unsigned char, hence the
- * double cast.
- */
-#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
-
-/* Enter a start condition.  This macro really ought to take a parameter,
- * but we do it the disgusting crufty way forced on us by the ()-less
- * definition of BEGIN.
- */
-#define BEGIN (yy_start) = 1 + 2 *
-
-/* Translate the current start state into a value that can be later handed
- * to BEGIN to return to the state.  The YYSTATE alias is for lex
- * compatibility.
- */
-#define YY_START (((yy_start) - 1) / 2)
-#define YYSTATE YY_START
-
-/* Action number for EOF rule of a given start state. */
-#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
-
-/* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE zconfrestart(zconfin  )
-
-#define YY_END_OF_BUFFER_CHAR 0
-
-/* Size of default input buffer. */
-#ifndef YY_BUF_SIZE
-#ifdef __ia64__
-/* On IA-64, the buffer size is 16k, not 8k.
- * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
- * Ditto for the __ia64__ case accordingly.
- */
-#define YY_BUF_SIZE 32768
-#else
-#define YY_BUF_SIZE 16384
-#endif /* __ia64__ */
-#endif
-
-/* The state buf must be large enough to hold one state per character in the main buffer.
- */
-#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
-
-#ifndef YY_TYPEDEF_YY_BUFFER_STATE
-#define YY_TYPEDEF_YY_BUFFER_STATE
-typedef struct yy_buffer_state *YY_BUFFER_STATE;
-#endif
-
-extern int zconfleng;
-
-extern FILE *zconfin, *zconfout;
-
-#define EOB_ACT_CONTINUE_SCAN 0
-#define EOB_ACT_END_OF_FILE 1
-#define EOB_ACT_LAST_MATCH 2
-
-    #define YY_LESS_LINENO(n)
-    
-/* Return all but the first "n" matched characters back to the input stream. */
-#define yyless(n) \
-	do \
-		{ \
-		/* Undo effects of setting up zconftext. */ \
-        int yyless_macro_arg = (n); \
-        YY_LESS_LINENO(yyless_macro_arg);\
-		*yy_cp = (yy_hold_char); \
-		YY_RESTORE_YY_MORE_OFFSET \
-		(yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
-		YY_DO_BEFORE_ACTION; /* set up zconftext again */ \
-		} \
-	while ( 0 )
-
-#define unput(c) yyunput( c, (yytext_ptr)  )
-
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef size_t yy_size_t;
-#endif
-
-#ifndef YY_STRUCT_YY_BUFFER_STATE
-#define YY_STRUCT_YY_BUFFER_STATE
-struct yy_buffer_state
-	{
-	FILE *yy_input_file;
-
-	char *yy_ch_buf;		/* input buffer */
-	char *yy_buf_pos;		/* current position in input buffer */
-
-	/* Size of input buffer in bytes, not including room for EOB
-	 * characters.
-	 */
-	yy_size_t yy_buf_size;
-
-	/* Number of characters read into yy_ch_buf, not including EOB
-	 * characters.
-	 */
-	int yy_n_chars;
-
-	/* Whether we "own" the buffer - i.e., we know we created it,
-	 * and can realloc() it to grow it, and should free() it to
-	 * delete it.
-	 */
-	int yy_is_our_buffer;
-
-	/* Whether this is an "interactive" input source; if so, and
-	 * if we're using stdio for input, then we want to use getc()
-	 * instead of fread(), to make sure we stop fetching input after
-	 * each newline.
-	 */
-	int yy_is_interactive;
-
-	/* Whether we're considered to be at the beginning of a line.
-	 * If so, '^' rules will be active on the next match, otherwise
-	 * not.
-	 */
-	int yy_at_bol;
-
-    int yy_bs_lineno; /**< The line count. */
-    int yy_bs_column; /**< The column count. */
-    
-	/* Whether to try to fill the input buffer when we reach the
-	 * end of it.
-	 */
-	int yy_fill_buffer;
-
-	int yy_buffer_status;
-
-#define YY_BUFFER_NEW 0
-#define YY_BUFFER_NORMAL 1
-	/* When an EOF's been seen but there's still some text to process
-	 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
-	 * shouldn't try reading from the input source any more.  We might
-	 * still have a bunch of tokens to match, though, because of
-	 * possible backing-up.
-	 *
-	 * When we actually see the EOF, we change the status to "new"
-	 * (via zconfrestart()), so that the user can continue scanning by
-	 * just pointing zconfin at a new input file.
-	 */
-#define YY_BUFFER_EOF_PENDING 2
-
-	};
-#endif /* !YY_STRUCT_YY_BUFFER_STATE */
-
-/* Stack of input buffers. */
-static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
-static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
-static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
-
-/* We provide macros for accessing buffer states in case in the
- * future we want to put the buffer states in a more general
- * "scanner state".
- *
- * Returns the top of the stack, or NULL.
- */
-#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
-                          ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
-                          : NULL)
-
-/* Same as previous macro, but useful when we know that the buffer stack is not
- * NULL or when we need an lvalue. For internal use only.
- */
-#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
-
-/* yy_hold_char holds the character lost when zconftext is formed. */
-static char yy_hold_char;
-static int yy_n_chars;		/* number of characters read into yy_ch_buf */
-int zconfleng;
-
-/* Points to current character in buffer. */
-static char *yy_c_buf_p = (char *) 0;
-static int yy_init = 0;		/* whether we need to initialize */
-static int yy_start = 0;	/* start state number */
-
-/* Flag which is used to allow zconfwrap()'s to do buffer switches
- * instead of setting up a fresh zconfin.  A bit of a hack ...
- */
-static int yy_did_buffer_switch_on_eof;
-
-void zconfrestart (FILE *input_file  );
-void zconf_switch_to_buffer (YY_BUFFER_STATE new_buffer  );
-YY_BUFFER_STATE zconf_create_buffer (FILE *file,int size  );
-void zconf_delete_buffer (YY_BUFFER_STATE b  );
-void zconf_flush_buffer (YY_BUFFER_STATE b  );
-void zconfpush_buffer_state (YY_BUFFER_STATE new_buffer  );
-void zconfpop_buffer_state (void );
-
-static void zconfensure_buffer_stack (void );
-static void zconf_load_buffer_state (void );
-static void zconf_init_buffer (YY_BUFFER_STATE b,FILE *file  );
-
-#define YY_FLUSH_BUFFER zconf_flush_buffer(YY_CURRENT_BUFFER )
-
-YY_BUFFER_STATE zconf_scan_buffer (char *base,yy_size_t size  );
-YY_BUFFER_STATE zconf_scan_string (yyconst char *yy_str  );
-YY_BUFFER_STATE zconf_scan_bytes (yyconst char *bytes,int len  );
-
-void *zconfalloc (yy_size_t  );
-void *zconfrealloc (void *,yy_size_t  );
-void zconffree (void *  );
-
-#define yy_new_buffer zconf_create_buffer
-
-#define yy_set_interactive(is_interactive) \
-	{ \
-	if ( ! YY_CURRENT_BUFFER ){ \
-        zconfensure_buffer_stack (); \
-		YY_CURRENT_BUFFER_LVALUE =    \
-            zconf_create_buffer(zconfin,YY_BUF_SIZE ); \
-	} \
-	YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
-	}
-
-#define yy_set_bol(at_bol) \
-	{ \
-	if ( ! YY_CURRENT_BUFFER ){\
-        zconfensure_buffer_stack (); \
-		YY_CURRENT_BUFFER_LVALUE =    \
-            zconf_create_buffer(zconfin,YY_BUF_SIZE ); \
-	} \
-	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
-	}
-
-#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
-
-/* Begin user sect3 */
-
-#define zconfwrap(n) 1
-#define YY_SKIP_YYWRAP
-
-typedef unsigned char YY_CHAR;
-
-FILE *zconfin = (FILE *) 0, *zconfout = (FILE *) 0;
-
-typedef int yy_state_type;
-
-extern int zconflineno;
-
-int zconflineno = 1;
-
-extern char *zconftext;
-#define yytext_ptr zconftext
-static yyconst flex_int16_t yy_nxt[][18] =
-    {
-    {
-        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,    0,    0
-    },
-
-    {
-       11,   12,   13,   14,   12,   12,   15,   12,   12,   12,
-       12,   12,   12,   12,   12,   12,   12,   12
-    },
-
-    {
-       11,   12,   13,   14,   12,   12,   15,   12,   12,   12,
-       12,   12,   12,   12,   12,   12,   12,   12
-    },
-
-    {
-       11,   16,   16,   17,   16,   16,   16,   16,   16,   16,
-       16,   18,   16,   16,   16,   16,   16,   16
-    },
-
-    {
-       11,   16,   16,   17,   16,   16,   16,   16,   16,   16,
-       16,   18,   16,   16,   16,   16,   16,   16
-
-    },
-
-    {
-       11,   19,   20,   21,   19,   19,   19,   19,   19,   19,
-       19,   19,   19,   19,   19,   19,   19,   19
-    },
-
-    {
-       11,   19,   20,   21,   19,   19,   19,   19,   19,   19,
-       19,   19,   19,   19,   19,   19,   19,   19
-    },
-
-    {
-       11,   22,   22,   23,   22,   24,   22,   22,   24,   22,
-       22,   22,   22,   22,   22,   22,   25,   22
-    },
-
-    {
-       11,   22,   22,   23,   22,   24,   22,   22,   24,   22,
-       22,   22,   22,   22,   22,   22,   25,   22
-    },
-
-    {
-       11,   26,   27,   28,   29,   30,   31,   32,   30,   33,
-       34,   35,   35,   36,   37,   38,   39,   40
-
-    },
-
-    {
-       11,   26,   27,   28,   29,   30,   31,   32,   30,   33,
-       34,   35,   35,   36,   37,   38,   39,   40
-    },
-
-    {
-      -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,
-      -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11
-    },
-
-    {
-       11,  -12,  -12,  -12,  -12,  -12,  -12,  -12,  -12,  -12,
-      -12,  -12,  -12,  -12,  -12,  -12,  -12,  -12
-    },
-
-    {
-       11,  -13,   41,   42,  -13,  -13,   43,  -13,  -13,  -13,
-      -13,  -13,  -13,  -13,  -13,  -13,  -13,  -13
-    },
-
-    {
-       11,  -14,  -14,  -14,  -14,  -14,  -14,  -14,  -14,  -14,
-      -14,  -14,  -14,  -14,  -14,  -14,  -14,  -14
-
-    },
-
-    {
-       11,   44,   44,   45,   44,   44,   44,   44,   44,   44,
-       44,   44,   44,   44,   44,   44,   44,   44
-    },
-
-    {
-       11,  -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16,
-      -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16
-    },
-
-    {
-       11,  -17,  -17,  -17,  -17,  -17,  -17,  -17,  -17,  -17,
-      -17,  -17,  -17,  -17,  -17,  -17,  -17,  -17
-    },
-
-    {
-       11,  -18,  -18,  -18,  -18,  -18,  -18,  -18,  -18,  -18,
-      -18,   46,  -18,  -18,  -18,  -18,  -18,  -18
-    },
-
-    {
-       11,   47,   47,  -19,   47,   47,   47,   47,   47,   47,
-       47,   47,   47,   47,   47,   47,   47,   47
-
-    },
-
-    {
-       11,  -20,   48,   49,  -20,  -20,  -20,  -20,  -20,  -20,
-      -20,  -20,  -20,  -20,  -20,  -20,  -20,  -20
-    },
-
-    {
-       11,   50,  -21,  -21,   50,   50,   50,   50,   50,   50,
-       50,   50,   50,   50,   50,   50,   50,   50
-    },
-
-    {
-       11,   51,   51,   52,   51,  -22,   51,   51,  -22,   51,
-       51,   51,   51,   51,   51,   51,  -22,   51
-    },
-
-    {
-       11,  -23,  -23,  -23,  -23,  -23,  -23,  -23,  -23,  -23,
-      -23,  -23,  -23,  -23,  -23,  -23,  -23,  -23
-    },
-
-    {
-       11,  -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,
-      -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24
-
-    },
-
-    {
-       11,   53,   53,   54,   53,   53,   53,   53,   53,   53,
-       53,   53,   53,   53,   53,   53,   53,   53
-    },
-
-    {
-       11,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,
-      -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26
-    },
-
-    {
-       11,  -27,   55,  -27,  -27,  -27,  -27,  -27,  -27,  -27,
-      -27,  -27,  -27,  -27,  -27,  -27,  -27,  -27
-    },
-
-    {
-       11,  -28,  -28,  -28,  -28,  -28,  -28,  -28,  -28,  -28,
-      -28,  -28,  -28,  -28,  -28,  -28,  -28,  -28
-    },
-
-    {
-       11,  -29,  -29,  -29,  -29,  -29,  -29,  -29,  -29,  -29,
-      -29,  -29,  -29,  -29,   56,  -29,  -29,  -29
-
-    },
-
-    {
-       11,  -30,  -30,  -30,  -30,  -30,  -30,  -30,  -30,  -30,
-      -30,  -30,  -30,  -30,  -30,  -30,  -30,  -30
-    },
-
-    {
-       11,   57,   57,  -31,   57,   57,   57,   57,   57,   57,
-       57,   57,   57,   57,   57,   57,   57,   57
-    },
-
-    {
-       11,  -32,  -32,  -32,  -32,  -32,  -32,   58,  -32,  -32,
-      -32,  -32,  -32,  -32,  -32,  -32,  -32,  -32
-    },
-
-    {
-       11,  -33,  -33,  -33,  -33,  -33,  -33,  -33,  -33,  -33,
-      -33,  -33,  -33,  -33,  -33,  -33,  -33,  -33
-    },
-
-    {
-       11,  -34,  -34,  -34,  -34,  -34,  -34,  -34,  -34,  -34,
-      -34,  -34,  -34,  -34,  -34,  -34,  -34,  -34
-
-    },
-
-    {
-       11,  -35,  -35,  -35,  -35,  -35,  -35,  -35,  -35,  -35,
-      -35,   59,   59,  -35,  -35,  -35,  -35,  -35
-    },
-
-    {
-       11,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,
-      -36,  -36,  -36,  -36,   60,  -36,  -36,  -36
-    },
-
-    {
-       11,  -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,
-      -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37
-    },
-
-    {
-       11,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,
-      -38,  -38,  -38,  -38,   61,  -38,  -38,  -38
-    },
-
-    {
-       11,  -39,  -39,   62,  -39,  -39,  -39,  -39,  -39,  -39,
-      -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39
-
-    },
-
-    {
-       11,  -40,  -40,  -40,  -40,  -40,  -40,  -40,  -40,  -40,
-      -40,  -40,  -40,  -40,  -40,  -40,  -40,   63
-    },
-
-    {
-       11,  -41,   41,   42,  -41,  -41,   43,  -41,  -41,  -41,
-      -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41
-    },
-
-    {
-       11,  -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,
-      -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42
-    },
-
-    {
-       11,   44,   44,   45,   44,   44,   44,   44,   44,   44,
-       44,   44,   44,   44,   44,   44,   44,   44
-    },
-
-    {
-       11,   44,   44,   45,   44,   44,   44,   44,   44,   44,
-       44,   44,   44,   44,   44,   44,   44,   44
-
-    },
-
-    {
-       11,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,
-      -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45
-    },
-
-    {
-       11,  -46,  -46,  -46,  -46,  -46,  -46,  -46,  -46,  -46,
-      -46,   46,  -46,  -46,  -46,  -46,  -46,  -46
-    },
-
-    {
-       11,   47,   47,  -47,   47,   47,   47,   47,   47,   47,
-       47,   47,   47,   47,   47,   47,   47,   47
-    },
-
-    {
-       11,  -48,   48,   49,  -48,  -48,  -48,  -48,  -48,  -48,
-      -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48
-    },
-
-    {
-       11,   50,  -49,  -49,   50,   50,   50,   50,   50,   50,
-       50,   50,   50,   50,   50,   50,   50,   50
-
-    },
-
-    {
-       11,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,
-      -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50
-    },
-
-    {
-       11,   51,   51,   52,   51,  -51,   51,   51,  -51,   51,
-       51,   51,   51,   51,   51,   51,  -51,   51
-    },
-
-    {
-       11,  -52,  -52,  -52,  -52,  -52,  -52,  -52,  -52,  -52,
-      -52,  -52,  -52,  -52,  -52,  -52,  -52,  -52
-    },
-
-    {
-       11,  -53,  -53,   54,  -53,  -53,  -53,  -53,  -53,  -53,
-      -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53
-    },
-
-    {
-       11,  -54,  -54,  -54,  -54,  -54,  -54,  -54,  -54,  -54,
-      -54,  -54,  -54,  -54,  -54,  -54,  -54,  -54
-
-    },
-
-    {
-       11,  -55,   55,  -55,  -55,  -55,  -55,  -55,  -55,  -55,
-      -55,  -55,  -55,  -55,  -55,  -55,  -55,  -55
-    },
-
-    {
-       11,  -56,  -56,  -56,  -56,  -56,  -56,  -56,  -56,  -56,
-      -56,  -56,  -56,  -56,  -56,  -56,  -56,  -56
-    },
-
-    {
-       11,   57,   57,  -57,   57,   57,   57,   57,   57,   57,
-       57,   57,   57,   57,   57,   57,   57,   57
-    },
-
-    {
-       11,  -58,  -58,  -58,  -58,  -58,  -58,  -58,  -58,  -58,
-      -58,  -58,  -58,  -58,  -58,  -58,  -58,  -58
-    },
-
-    {
-       11,  -59,  -59,  -59,  -59,  -59,  -59,  -59,  -59,  -59,
-      -59,   59,   59,  -59,  -59,  -59,  -59,  -59
-
-    },
-
-    {
-       11,  -60,  -60,  -60,  -60,  -60,  -60,  -60,  -60,  -60,
-      -60,  -60,  -60,  -60,  -60,  -60,  -60,  -60
-    },
-
-    {
-       11,  -61,  -61,  -61,  -61,  -61,  -61,  -61,  -61,  -61,
-      -61,  -61,  -61,  -61,  -61,  -61,  -61,  -61
-    },
-
-    {
-       11,  -62,  -62,  -62,  -62,  -62,  -62,  -62,  -62,  -62,
-      -62,  -62,  -62,  -62,  -62,  -62,  -62,  -62
-    },
-
-    {
-       11,  -63,  -63,  -63,  -63,  -63,  -63,  -63,  -63,  -63,
-      -63,  -63,  -63,  -63,  -63,  -63,  -63,  -63
-    },
-
-    } ;
-
-static yy_state_type yy_get_previous_state (void );
-static yy_state_type yy_try_NUL_trans (yy_state_type current_state  );
-static int yy_get_next_buffer (void );
-static void yy_fatal_error (yyconst char msg[]  );
-
-/* Done after the current pattern has been matched and before the
- * corresponding action - sets up zconftext.
- */
-#define YY_DO_BEFORE_ACTION \
-	(yytext_ptr) = yy_bp; \
-	zconfleng = (size_t) (yy_cp - yy_bp); \
-	(yy_hold_char) = *yy_cp; \
-	*yy_cp = '\0'; \
-	(yy_c_buf_p) = yy_cp;
-
-#define YY_NUM_RULES 37
-#define YY_END_OF_BUFFER 38
-/* This struct is not used in this scanner,
-   but its presence is necessary. */
-struct yy_trans_info
-	{
-	flex_int32_t yy_verify;
-	flex_int32_t yy_nxt;
-	};
-static yyconst flex_int16_t yy_accept[64] =
-    {   0,
-        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-       38,    5,    4,    2,    3,    7,    8,    6,   36,   33,
-       35,   28,   32,   31,   30,   26,   25,   21,   13,   20,
-       23,   26,   11,   12,   22,   18,   14,   19,   26,   26,
-        4,    2,    3,    3,    1,    6,   36,   33,   35,   34,
-       28,   27,   30,   29,   25,   15,   23,    9,   22,   16,
-       17,   24,   10
-    } ;
-
-static yyconst flex_int32_t yy_ec[256] =
-    {   0,
-        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    2,    4,    5,    6,    1,    1,    7,    8,    9,
-       10,    1,    1,    1,   11,   12,   12,   11,   11,   11,
-       11,   11,   11,   11,   11,   11,   11,    1,    1,   13,
-       14,   15,    1,    1,   11,   11,   11,   11,   11,   11,
-       11,   11,   11,   11,   11,   11,   11,   11,   11,   11,
-       11,   11,   11,   11,   11,   11,   11,   11,   11,   11,
-        1,   16,    1,    1,   11,    1,   11,   11,   11,   11,
-
-       11,   11,   11,   11,   11,   11,   11,   11,   11,   11,
-       11,   11,   11,   11,   11,   11,   11,   11,   11,   11,
-       11,   11,    1,   17,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1
-    } ;
-
-extern int zconf_flex_debug;
-int zconf_flex_debug = 0;
-
-/* The intent behind this definition is that it'll catch
- * any uses of REJECT which flex missed.
- */
-#define REJECT reject_used_but_not_detected
-#define yymore() yymore_used_but_not_detected
-#define YY_MORE_ADJ 0
-#define YY_RESTORE_YY_MORE_OFFSET
-char *zconftext;
-#define YY_NO_INPUT 1
-
-/*
- * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
- * Released under the terms of the GNU GPL v2.0.
- */
-
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "lkc.h"
-
-#define START_STRSIZE	16
-
-static struct {
-	struct file *file;
-	int lineno;
-} current_pos;
-
-static char *text;
-static int text_size, text_asize;
-
-struct buffer {
-	struct buffer *parent;
-	YY_BUFFER_STATE state;
-};
-
-struct buffer *current_buf;
-
-static int last_ts, first_ts;
-
-static void zconf_endhelp(void);
-static void zconf_endfile(void);
-
-static void new_string(void)
-{
-	text = xmalloc(START_STRSIZE);
-	text_asize = START_STRSIZE;
-	text_size = 0;
-	*text = 0;
-}
-
-static void append_string(const char *str, int size)
-{
-	int new_size = text_size + size + 1;
-	if (new_size > text_asize) {
-		new_size += START_STRSIZE - 1;
-		new_size &= -START_STRSIZE;
-		text = realloc(text, new_size);
-		text_asize = new_size;
-	}
-	memcpy(text + text_size, str, size);
-	text_size += size;
-	text[text_size] = 0;
-}
-
-static void alloc_string(const char *str, int size)
-{
-	text = xmalloc(size + 1);
-	memcpy(text, str, size);
-	text[size] = 0;
-}
-
-static void warn_ignored_character(char chr)
-{
-	fprintf(stderr,
-	        "%s:%d:warning: ignoring unsupported character '%c'\n",
-	        zconf_curname(), zconf_lineno(), chr);
-}
-
-#define INITIAL 0
-#define COMMAND 1
-#define HELP 2
-#define STRING 3
-#define PARAM 4
-
-#ifndef YY_NO_UNISTD_H
-/* Special case for "unistd.h", since it is non-ANSI. We include it way
- * down here because we want the user's section 1 to have been scanned first.
- * The user has a chance to override it with an option.
- */
-#include <unistd.h>
-#endif
-
-#ifndef YY_EXTRA_TYPE
-#define YY_EXTRA_TYPE void *
-#endif
-
-static int yy_init_globals (void );
-
-/* Accessor methods to globals.
-   These are made visible to non-reentrant scanners for convenience. */
-
-int zconflex_destroy (void );
-
-int zconfget_debug (void );
-
-void zconfset_debug (int debug_flag  );
-
-YY_EXTRA_TYPE zconfget_extra (void );
-
-void zconfset_extra (YY_EXTRA_TYPE user_defined  );
-
-FILE *zconfget_in (void );
-
-void zconfset_in  (FILE * in_str  );
-
-FILE *zconfget_out (void );
-
-void zconfset_out  (FILE * out_str  );
-
-int zconfget_leng (void );
-
-char *zconfget_text (void );
-
-int zconfget_lineno (void );
-
-void zconfset_lineno (int line_number  );
-
-/* Macros after this point can all be overridden by user definitions in
- * section 1.
- */
-
-#ifndef YY_SKIP_YYWRAP
-#ifdef __cplusplus
-extern "C" int zconfwrap (void );
-#else
-extern int zconfwrap (void );
-#endif
-#endif
-
-    static void yyunput (int c,char *buf_ptr  );
-    
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char *,yyconst char *,int );
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * );
-#endif
-
-#ifndef YY_NO_INPUT
-
-#ifdef __cplusplus
-static int yyinput (void );
-#else
-static int input (void );
-#endif
-
-#endif
-
-/* Amount of stuff to slurp up with each read. */
-#ifndef YY_READ_BUF_SIZE
-#ifdef __ia64__
-/* On IA-64, the buffer size is 16k, not 8k */
-#define YY_READ_BUF_SIZE 16384
-#else
-#define YY_READ_BUF_SIZE 8192
-#endif /* __ia64__ */
-#endif
-
-/* Copy whatever the last rule matched to the standard output. */
-#ifndef ECHO
-/* This used to be an fputs(), but since the string might contain NUL's,
- * we now use fwrite().
- */
-#define ECHO do { if (fwrite( zconftext, zconfleng, 1, zconfout )) {} } while (0)
-#endif
-
-/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
- * is returned in "result".
- */
-#ifndef YY_INPUT
-#define YY_INPUT(buf,result,max_size) \
-	errno=0; \
-	while ( (result = read( fileno(zconfin), (char *) buf, max_size )) < 0 ) \
-	{ \
-		if( errno != EINTR) \
-		{ \
-			YY_FATAL_ERROR( "input in flex scanner failed" ); \
-			break; \
-		} \
-		errno=0; \
-		clearerr(zconfin); \
-	}\
-\
-
-#endif
-
-/* No semi-colon after return; correct usage is to write "yyterminate();" -
- * we don't want an extra ';' after the "return" because that will cause
- * some compilers to complain about unreachable statements.
- */
-#ifndef yyterminate
-#define yyterminate() return YY_NULL
-#endif
-
-/* Number of entries by which start-condition stack grows. */
-#ifndef YY_START_STACK_INCR
-#define YY_START_STACK_INCR 25
-#endif
-
-/* Report a fatal error. */
-#ifndef YY_FATAL_ERROR
-#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
-#endif
-
-/* end tables serialization structures and prototypes */
-
-/* Default declaration of generated scanner - a define so the user can
- * easily add parameters.
- */
-#ifndef YY_DECL
-#define YY_DECL_IS_OURS 1
-
-extern int zconflex (void);
-
-#define YY_DECL int zconflex (void)
-#endif /* !YY_DECL */
-
-/* Code executed at the beginning of each rule, after zconftext and zconfleng
- * have been set up.
- */
-#ifndef YY_USER_ACTION
-#define YY_USER_ACTION
-#endif
-
-/* Code executed at the end of each rule. */
-#ifndef YY_BREAK
-#define YY_BREAK break;
-#endif
-
-#define YY_RULE_SETUP \
-	YY_USER_ACTION
-
-/** The main scanner function which does all the work.
- */
-YY_DECL
-{
-	register yy_state_type yy_current_state;
-	register char *yy_cp, *yy_bp;
-	register int yy_act;
-    
-	int str = 0;
-	int ts, i;
-
-	if ( !(yy_init) )
-		{
-		(yy_init) = 1;
-
-#ifdef YY_USER_INIT
-		YY_USER_INIT;
-#endif
-
-		if ( ! (yy_start) )
-			(yy_start) = 1;	/* first start state */
-
-		if ( ! zconfin )
-			zconfin = stdin;
-
-		if ( ! zconfout )
-			zconfout = stdout;
-
-		if ( ! YY_CURRENT_BUFFER ) {
-			zconfensure_buffer_stack ();
-			YY_CURRENT_BUFFER_LVALUE =
-				zconf_create_buffer(zconfin,YY_BUF_SIZE );
-		}
-
-		zconf_load_buffer_state( );
-		}
-
-	while ( 1 )		/* loops until end-of-file is reached */
-		{
-		yy_cp = (yy_c_buf_p);
-
-		/* Support of zconftext. */
-		*yy_cp = (yy_hold_char);
-
-		/* yy_bp points to the position in yy_ch_buf of the start of
-		 * the current run.
-		 */
-		yy_bp = yy_cp;
-
-		yy_current_state = (yy_start);
-yy_match:
-		while ( (yy_current_state = yy_nxt[yy_current_state][ yy_ec[YY_SC_TO_UI(*yy_cp)]  ]) > 0 )
-			++yy_cp;
-
-		yy_current_state = -yy_current_state;
-
-yy_find_action:
-		yy_act = yy_accept[yy_current_state];
-
-		YY_DO_BEFORE_ACTION;
-
-do_action:	/* This label is used only to access EOF actions. */
-
-		switch ( yy_act )
-	{ /* beginning of action switch */
-case 1:
-/* rule 1 can match eol */
-case 2:
-/* rule 2 can match eol */
-YY_RULE_SETUP
-{
-	current_file->lineno++;
-	return T_EOL;
-}
-	YY_BREAK
-case 3:
-YY_RULE_SETUP
-
-	YY_BREAK
-case 4:
-YY_RULE_SETUP
-{
-	BEGIN(COMMAND);
-}
-	YY_BREAK
-case 5:
-YY_RULE_SETUP
-{
-	unput(zconftext[0]);
-	BEGIN(COMMAND);
-}
-	YY_BREAK
-
-case 6:
-YY_RULE_SETUP
-{
-		const struct kconf_id *id = kconf_id_lookup(zconftext, zconfleng);
-		BEGIN(PARAM);
-		current_pos.file = current_file;
-		current_pos.lineno = current_file->lineno;
-		if (id && id->flags & TF_COMMAND) {
-			zconflval.id = id;
-			return id->token;
-		}
-		alloc_string(zconftext, zconfleng);
-		zconflval.string = text;
-		return T_WORD;
-	}
-	YY_BREAK
-case 7:
-YY_RULE_SETUP
-warn_ignored_character(*zconftext);
-	YY_BREAK
-case 8:
-/* rule 8 can match eol */
-YY_RULE_SETUP
-{
-		BEGIN(INITIAL);
-		current_file->lineno++;
-		return T_EOL;
-	}
-	YY_BREAK
-
-case 9:
-YY_RULE_SETUP
-return T_AND;
-	YY_BREAK
-case 10:
-YY_RULE_SETUP
-return T_OR;
-	YY_BREAK
-case 11:
-YY_RULE_SETUP
-return T_OPEN_PAREN;
-	YY_BREAK
-case 12:
-YY_RULE_SETUP
-return T_CLOSE_PAREN;
-	YY_BREAK
-case 13:
-YY_RULE_SETUP
-return T_NOT;
-	YY_BREAK
-case 14:
-YY_RULE_SETUP
-return T_EQUAL;
-	YY_BREAK
-case 15:
-YY_RULE_SETUP
-return T_UNEQUAL;
-	YY_BREAK
-case 16:
-YY_RULE_SETUP
-return T_LESS_EQUAL;
-	YY_BREAK
-case 17:
-YY_RULE_SETUP
-return T_GREATER_EQUAL;
-	YY_BREAK
-case 18:
-YY_RULE_SETUP
-return T_LESS;
-	YY_BREAK
-case 19:
-YY_RULE_SETUP
-return T_GREATER;
-	YY_BREAK
-case 20:
-YY_RULE_SETUP
-{
-		str = zconftext[0];
-		new_string();
-		BEGIN(STRING);
-	}
-	YY_BREAK
-case 21:
-/* rule 21 can match eol */
-YY_RULE_SETUP
-BEGIN(INITIAL); current_file->lineno++; return T_EOL;
-	YY_BREAK
-case 22:
-YY_RULE_SETUP
-{
-		const struct kconf_id *id = kconf_id_lookup(zconftext, zconfleng);
-		if (id && id->flags & TF_PARAM) {
-			zconflval.id = id;
-			return id->token;
-		}
-		alloc_string(zconftext, zconfleng);
-		zconflval.string = text;
-		return T_WORD;
-	}
-	YY_BREAK
-case 23:
-YY_RULE_SETUP
-/* comment */
-	YY_BREAK
-case 24:
-/* rule 24 can match eol */
-YY_RULE_SETUP
-current_file->lineno++;
-	YY_BREAK
-case 25:
-YY_RULE_SETUP
-
-	YY_BREAK
-case 26:
-YY_RULE_SETUP
-warn_ignored_character(*zconftext);
-	YY_BREAK
-case YY_STATE_EOF(PARAM):
-{
-		BEGIN(INITIAL);
-	}
-	YY_BREAK
-
-case 27:
-/* rule 27 can match eol */
-*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */
-(yy_c_buf_p) = yy_cp -= 1;
-YY_DO_BEFORE_ACTION; /* set up zconftext again */
-YY_RULE_SETUP
-{
-		append_string(zconftext, zconfleng);
-		zconflval.string = text;
-		return T_WORD_QUOTE;
-	}
-	YY_BREAK
-case 28:
-YY_RULE_SETUP
-{
-		append_string(zconftext, zconfleng);
-	}
-	YY_BREAK
-case 29:
-/* rule 29 can match eol */
-*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */
-(yy_c_buf_p) = yy_cp -= 1;
-YY_DO_BEFORE_ACTION; /* set up zconftext again */
-YY_RULE_SETUP
-{
-		append_string(zconftext + 1, zconfleng - 1);
-		zconflval.string = text;
-		return T_WORD_QUOTE;
-	}
-	YY_BREAK
-case 30:
-YY_RULE_SETUP
-{
-		append_string(zconftext + 1, zconfleng - 1);
-	}
-	YY_BREAK
-case 31:
-YY_RULE_SETUP
-{
-		if (str == zconftext[0]) {
-			BEGIN(PARAM);
-			zconflval.string = text;
-			return T_WORD_QUOTE;
-		} else
-			append_string(zconftext, 1);
-	}
-	YY_BREAK
-case 32:
-/* rule 32 can match eol */
-YY_RULE_SETUP
-{
-		printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno());
-		current_file->lineno++;
-		BEGIN(INITIAL);
-		return T_EOL;
-	}
-	YY_BREAK
-case YY_STATE_EOF(STRING):
-{
-		BEGIN(INITIAL);
-	}
-	YY_BREAK
-
-case 33:
-YY_RULE_SETUP
-{
-		ts = 0;
-		for (i = 0; i < zconfleng; i++) {
-			if (zconftext[i] == '\t')
-				ts = (ts & ~7) + 8;
-			else
-				ts++;
-		}
-		last_ts = ts;
-		if (first_ts) {
-			if (ts < first_ts) {
-				zconf_endhelp();
-				return T_HELPTEXT;
-			}
-			ts -= first_ts;
-			while (ts > 8) {
-				append_string("        ", 8);
-				ts -= 8;
-			}
-			append_string("        ", ts);
-		}
-	}
-	YY_BREAK
-case 34:
-/* rule 34 can match eol */
-*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */
-(yy_c_buf_p) = yy_cp -= 1;
-YY_DO_BEFORE_ACTION; /* set up zconftext again */
-YY_RULE_SETUP
-{
-		current_file->lineno++;
-		zconf_endhelp();
-		return T_HELPTEXT;
-	}
-	YY_BREAK
-case 35:
-/* rule 35 can match eol */
-YY_RULE_SETUP
-{
-		current_file->lineno++;
-		append_string("\n", 1);
-	}
-	YY_BREAK
-case 36:
-YY_RULE_SETUP
-{
-		while (zconfleng) {
-			if ((zconftext[zconfleng-1] != ' ') && (zconftext[zconfleng-1] != '\t'))
-				break;
-			zconfleng--;
-		}
-		append_string(zconftext, zconfleng);
-		if (!first_ts)
-			first_ts = last_ts;
-	}
-	YY_BREAK
-case YY_STATE_EOF(HELP):
-{
-		zconf_endhelp();
-		return T_HELPTEXT;
-	}
-	YY_BREAK
-
-case YY_STATE_EOF(INITIAL):
-case YY_STATE_EOF(COMMAND):
-{
-	if (current_file) {
-		zconf_endfile();
-		return T_EOL;
-	}
-	fclose(zconfin);
-	yyterminate();
-}
-	YY_BREAK
-case 37:
-YY_RULE_SETUP
-YY_FATAL_ERROR( "flex scanner jammed" );
-	YY_BREAK
-
-	case YY_END_OF_BUFFER:
-		{
-		/* Amount of text matched not including the EOB char. */
-		int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
-
-		/* Undo the effects of YY_DO_BEFORE_ACTION. */
-		*yy_cp = (yy_hold_char);
-		YY_RESTORE_YY_MORE_OFFSET
-
-		if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
-			{
-			/* We're scanning a new file or input source.  It's
-			 * possible that this happened because the user
-			 * just pointed zconfin at a new source and called
-			 * zconflex().  If so, then we have to assure
-			 * consistency between YY_CURRENT_BUFFER and our
-			 * globals.  Here is the right place to do so, because
-			 * this is the first action (other than possibly a
-			 * back-up) that will match for the new input source.
-			 */
-			(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
-			YY_CURRENT_BUFFER_LVALUE->yy_input_file = zconfin;
-			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
-			}
-
-		/* Note that here we test for yy_c_buf_p "<=" to the position
-		 * of the first EOB in the buffer, since yy_c_buf_p will
-		 * already have been incremented past the NUL character
-		 * (since all states make transitions on EOB to the
-		 * end-of-buffer state).  Contrast this with the test
-		 * in input().
-		 */
-		if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
-			{ /* This was really a NUL. */
-			yy_state_type yy_next_state;
-
-			(yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
-
-			yy_current_state = yy_get_previous_state(  );
-
-			/* Okay, we're now positioned to make the NUL
-			 * transition.  We couldn't have
-			 * yy_get_previous_state() go ahead and do it
-			 * for us because it doesn't know how to deal
-			 * with the possibility of jamming (and we don't
-			 * want to build jamming into it because then it
-			 * will run more slowly).
-			 */
-
-			yy_next_state = yy_try_NUL_trans( yy_current_state );
-
-			yy_bp = (yytext_ptr) + YY_MORE_ADJ;
-
-			if ( yy_next_state )
-				{
-				/* Consume the NUL. */
-				yy_cp = ++(yy_c_buf_p);
-				yy_current_state = yy_next_state;
-				goto yy_match;
-				}
-
-			else
-				{
-				yy_cp = (yy_c_buf_p);
-				goto yy_find_action;
-				}
-			}
-
-		else switch ( yy_get_next_buffer(  ) )
-			{
-			case EOB_ACT_END_OF_FILE:
-				{
-				(yy_did_buffer_switch_on_eof) = 0;
-
-				if ( zconfwrap( ) )
-					{
-					/* Note: because we've taken care in
-					 * yy_get_next_buffer() to have set up
-					 * zconftext, we can now set up
-					 * yy_c_buf_p so that if some total
-					 * hoser (like flex itself) wants to
-					 * call the scanner after we return the
-					 * YY_NULL, it'll still work - another
-					 * YY_NULL will get returned.
-					 */
-					(yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
-
-					yy_act = YY_STATE_EOF(YY_START);
-					goto do_action;
-					}
-
-				else
-					{
-					if ( ! (yy_did_buffer_switch_on_eof) )
-						YY_NEW_FILE;
-					}
-				break;
-				}
-
-			case EOB_ACT_CONTINUE_SCAN:
-				(yy_c_buf_p) =
-					(yytext_ptr) + yy_amount_of_matched_text;
-
-				yy_current_state = yy_get_previous_state(  );
-
-				yy_cp = (yy_c_buf_p);
-				yy_bp = (yytext_ptr) + YY_MORE_ADJ;
-				goto yy_match;
-
-			case EOB_ACT_LAST_MATCH:
-				(yy_c_buf_p) =
-				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
-
-				yy_current_state = yy_get_previous_state(  );
-
-				yy_cp = (yy_c_buf_p);
-				yy_bp = (yytext_ptr) + YY_MORE_ADJ;
-				goto yy_find_action;
-			}
-		break;
-		}
-
-	default:
-		YY_FATAL_ERROR(
-			"fatal flex scanner internal error--no action found" );
-	} /* end of action switch */
-		} /* end of scanning one token */
-} /* end of zconflex */
-
-/* yy_get_next_buffer - try to read in a new buffer
- *
- * Returns a code representing an action:
- *	EOB_ACT_LAST_MATCH -
- *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
- *	EOB_ACT_END_OF_FILE - end of file
- */
-static int yy_get_next_buffer (void)
-{
-    	register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
-	register char *source = (yytext_ptr);
-	register int number_to_move, i;
-	int ret_val;
-
-	if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
-		YY_FATAL_ERROR(
-		"fatal flex scanner internal error--end of buffer missed" );
-
-	if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
-		{ /* Don't try to fill the buffer, so this is an EOF. */
-		if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
-			{
-			/* We matched a single character, the EOB, so
-			 * treat this as a final EOF.
-			 */
-			return EOB_ACT_END_OF_FILE;
-			}
-
-		else
-			{
-			/* We matched some text prior to the EOB, first
-			 * process it.
-			 */
-			return EOB_ACT_LAST_MATCH;
-			}
-		}
-
-	/* Try to read more data. */
-
-	/* First move last chars to start of buffer. */
-	number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
-
-	for ( i = 0; i < number_to_move; ++i )
-		*(dest++) = *(source++);
-
-	if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
-		/* don't do the read, it's not guaranteed to return an EOF,
-		 * just force an EOF
-		 */
-		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
-
-	else
-		{
-			int num_to_read =
-			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
-
-		while ( num_to_read <= 0 )
-			{ /* Not enough room in the buffer - grow it. */
-
-			/* just a shorter name for the current buffer */
-			YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
-
-			int yy_c_buf_p_offset =
-				(int) ((yy_c_buf_p) - b->yy_ch_buf);
-
-			if ( b->yy_is_our_buffer )
-				{
-				int new_size = b->yy_buf_size * 2;
-
-				if ( new_size <= 0 )
-					b->yy_buf_size += b->yy_buf_size / 8;
-				else
-					b->yy_buf_size *= 2;
-
-				b->yy_ch_buf = (char *)
-					/* Include room in for 2 EOB chars. */
-					zconfrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
-				}
-			else
-				/* Can't grow it, we don't own it. */
-				b->yy_ch_buf = 0;
-
-			if ( ! b->yy_ch_buf )
-				YY_FATAL_ERROR(
-				"fatal error - scanner input buffer overflow" );
-
-			(yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
-
-			num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
-						number_to_move - 1;
-
-			}
-
-		if ( num_to_read > YY_READ_BUF_SIZE )
-			num_to_read = YY_READ_BUF_SIZE;
-
-		/* Read in more data. */
-		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
-			(yy_n_chars), (size_t) num_to_read );
-
-		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
-		}
-
-	if ( (yy_n_chars) == 0 )
-		{
-		if ( number_to_move == YY_MORE_ADJ )
-			{
-			ret_val = EOB_ACT_END_OF_FILE;
-			zconfrestart(zconfin  );
-			}
-
-		else
-			{
-			ret_val = EOB_ACT_LAST_MATCH;
-			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
-				YY_BUFFER_EOF_PENDING;
-			}
-		}
-
-	else
-		ret_val = EOB_ACT_CONTINUE_SCAN;
-
-	if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
-		/* Extend the array by 50%, plus the number we really need. */
-		yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
-		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) zconfrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size  );
-		if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
-			YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
-	}
-
-	(yy_n_chars) += number_to_move;
-	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
-	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
-
-	(yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
-
-	return ret_val;
-}
-
-/* yy_get_previous_state - get the state just before the EOB char was reached */
-
-    static yy_state_type yy_get_previous_state (void)
-{
-	register yy_state_type yy_current_state;
-	register char *yy_cp;
-    
-	yy_current_state = (yy_start);
-
-	for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
-		{
-		yy_current_state = yy_nxt[yy_current_state][(*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1)];
-		}
-
-	return yy_current_state;
-}
-
-/* yy_try_NUL_trans - try to make a transition on the NUL character
- *
- * synopsis
- *	next_state = yy_try_NUL_trans( current_state );
- */
-    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )
-{
-	register int yy_is_jam;
-    
-	yy_current_state = yy_nxt[yy_current_state][1];
-	yy_is_jam = (yy_current_state <= 0);
-
-	return yy_is_jam ? 0 : yy_current_state;
-}
-
-    static void yyunput (int c, register char * yy_bp )
-{
-	register char *yy_cp;
-    
-    yy_cp = (yy_c_buf_p);
-
-	/* undo effects of setting up zconftext */
-	*yy_cp = (yy_hold_char);
-
-	if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
-		{ /* need to shift things up to make room */
-		/* +2 for EOB chars. */
-		register int number_to_move = (yy_n_chars) + 2;
-		register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
-					YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
-		register char *source =
-				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
-
-		while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
-			*--dest = *--source;
-
-		yy_cp += (int) (dest - source);
-		yy_bp += (int) (dest - source);
-		YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
-			(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
-
-		if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
-			YY_FATAL_ERROR( "flex scanner push-back overflow" );
-		}
-
-	*--yy_cp = (char) c;
-
-	(yytext_ptr) = yy_bp;
-	(yy_hold_char) = *yy_cp;
-	(yy_c_buf_p) = yy_cp;
-}
-
-#ifndef YY_NO_INPUT
-#ifdef __cplusplus
-    static int yyinput (void)
-#else
-    static int input  (void)
-#endif
-
-{
-	int c;
-    
-	*(yy_c_buf_p) = (yy_hold_char);
-
-	if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
-		{
-		/* yy_c_buf_p now points to the character we want to return.
-		 * If this occurs *before* the EOB characters, then it's a
-		 * valid NUL; if not, then we've hit the end of the buffer.
-		 */
-		if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
-			/* This was really a NUL. */
-			*(yy_c_buf_p) = '\0';
-
-		else
-			{ /* need more input */
-			int offset = (yy_c_buf_p) - (yytext_ptr);
-			++(yy_c_buf_p);
-
-			switch ( yy_get_next_buffer(  ) )
-				{
-				case EOB_ACT_LAST_MATCH:
-					/* This happens because yy_g_n_b()
-					 * sees that we've accumulated a
-					 * token and flags that we need to
-					 * try matching the token before
-					 * proceeding.  But for input(),
-					 * there's no matching to consider.
-					 * So convert the EOB_ACT_LAST_MATCH
-					 * to EOB_ACT_END_OF_FILE.
-					 */
-
-					/* Reset buffer status. */
-					zconfrestart(zconfin );
-
-					/*FALLTHROUGH*/
-
-				case EOB_ACT_END_OF_FILE:
-					{
-					if ( zconfwrap( ) )
-						return EOF;
-
-					if ( ! (yy_did_buffer_switch_on_eof) )
-						YY_NEW_FILE;
-#ifdef __cplusplus
-					return yyinput();
-#else
-					return input();
-#endif
-					}
-
-				case EOB_ACT_CONTINUE_SCAN:
-					(yy_c_buf_p) = (yytext_ptr) + offset;
-					break;
-				}
-			}
-		}
-
-	c = *(unsigned char *) (yy_c_buf_p);	/* cast for 8-bit char's */
-	*(yy_c_buf_p) = '\0';	/* preserve zconftext */
-	(yy_hold_char) = *++(yy_c_buf_p);
-
-	return c;
-}
-#endif	/* ifndef YY_NO_INPUT */
-
-/** Immediately switch to a different input stream.
- * @param input_file A readable stream.
- * 
- * @note This function does not reset the start condition to @c INITIAL .
- */
-    void zconfrestart  (FILE * input_file )
-{
-    
-	if ( ! YY_CURRENT_BUFFER ){
-        zconfensure_buffer_stack ();
-		YY_CURRENT_BUFFER_LVALUE =
-            zconf_create_buffer(zconfin,YY_BUF_SIZE );
-	}
-
-	zconf_init_buffer(YY_CURRENT_BUFFER,input_file );
-	zconf_load_buffer_state( );
-}
-
-/** Switch to a different input buffer.
- * @param new_buffer The new input buffer.
- * 
- */
-    void zconf_switch_to_buffer  (YY_BUFFER_STATE  new_buffer )
-{
-    
-	/* TODO. We should be able to replace this entire function body
-	 * with
-	 *		zconfpop_buffer_state();
-	 *		zconfpush_buffer_state(new_buffer);
-     */
-	zconfensure_buffer_stack ();
-	if ( YY_CURRENT_BUFFER == new_buffer )
-		return;
-
-	if ( YY_CURRENT_BUFFER )
-		{
-		/* Flush out information for old buffer. */
-		*(yy_c_buf_p) = (yy_hold_char);
-		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
-		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
-		}
-
-	YY_CURRENT_BUFFER_LVALUE = new_buffer;
-	zconf_load_buffer_state( );
-
-	/* We don't actually know whether we did this switch during
-	 * EOF (zconfwrap()) processing, but the only time this flag
-	 * is looked at is after zconfwrap() is called, so it's safe
-	 * to go ahead and always set it.
-	 */
-	(yy_did_buffer_switch_on_eof) = 1;
-}
-
-static void zconf_load_buffer_state  (void)
-{
-    	(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
-	(yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
-	zconfin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
-	(yy_hold_char) = *(yy_c_buf_p);
-}
-
-/** Allocate and initialize an input buffer state.
- * @param file A readable stream.
- * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
- * 
- * @return the allocated buffer state.
- */
-    YY_BUFFER_STATE zconf_create_buffer  (FILE * file, int  size )
-{
-	YY_BUFFER_STATE b;
-    
-	b = (YY_BUFFER_STATE) zconfalloc(sizeof( struct yy_buffer_state )  );
-	if ( ! b )
-		YY_FATAL_ERROR( "out of dynamic memory in zconf_create_buffer()" );
-
-	b->yy_buf_size = size;
-
-	/* yy_ch_buf has to be 2 characters longer than the size given because
-	 * we need to put in 2 end-of-buffer characters.
-	 */
-	b->yy_ch_buf = (char *) zconfalloc(b->yy_buf_size + 2  );
-	if ( ! b->yy_ch_buf )
-		YY_FATAL_ERROR( "out of dynamic memory in zconf_create_buffer()" );
-
-	b->yy_is_our_buffer = 1;
-
-	zconf_init_buffer(b,file );
-
-	return b;
-}
-
-/** Destroy the buffer.
- * @param b a buffer created with zconf_create_buffer()
- * 
- */
-    void zconf_delete_buffer (YY_BUFFER_STATE  b )
-{
-    
-	if ( ! b )
-		return;
-
-	if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
-		YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
-
-	if ( b->yy_is_our_buffer )
-		zconffree((void *) b->yy_ch_buf  );
-
-	zconffree((void *) b  );
-}
-
-/* Initializes or reinitializes a buffer.
- * This function is sometimes called more than once on the same buffer,
- * such as during a zconfrestart() or at EOF.
- */
-    static void zconf_init_buffer  (YY_BUFFER_STATE  b, FILE * file )
-
-{
-	int oerrno = errno;
-    
-	zconf_flush_buffer(b );
-
-	b->yy_input_file = file;
-	b->yy_fill_buffer = 1;
-
-    /* If b is the current buffer, then zconf_init_buffer was _probably_
-     * called from zconfrestart() or through yy_get_next_buffer.
-     * In that case, we don't want to reset the lineno or column.
-     */
-    if (b != YY_CURRENT_BUFFER){
-        b->yy_bs_lineno = 1;
-        b->yy_bs_column = 0;
-    }
-
-        b->yy_is_interactive = 0;
-    
-	errno = oerrno;
-}
-
-/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
- * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
- * 
- */
-    void zconf_flush_buffer (YY_BUFFER_STATE  b )
-{
-    	if ( ! b )
-		return;
-
-	b->yy_n_chars = 0;
-
-	/* We always need two end-of-buffer characters.  The first causes
-	 * a transition to the end-of-buffer state.  The second causes
-	 * a jam in that state.
-	 */
-	b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
-	b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
-
-	b->yy_buf_pos = &b->yy_ch_buf[0];
-
-	b->yy_at_bol = 1;
-	b->yy_buffer_status = YY_BUFFER_NEW;
-
-	if ( b == YY_CURRENT_BUFFER )
-		zconf_load_buffer_state( );
-}
-
-/** Pushes the new state onto the stack. The new state becomes
- *  the current state. This function will allocate the stack
- *  if necessary.
- *  @param new_buffer The new state.
- *  
- */
-void zconfpush_buffer_state (YY_BUFFER_STATE new_buffer )
-{
-    	if (new_buffer == NULL)
-		return;
-
-	zconfensure_buffer_stack();
-
-	/* This block is copied from zconf_switch_to_buffer. */
-	if ( YY_CURRENT_BUFFER )
-		{
-		/* Flush out information for old buffer. */
-		*(yy_c_buf_p) = (yy_hold_char);
-		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
-		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
-		}
-
-	/* Only push if top exists. Otherwise, replace top. */
-	if (YY_CURRENT_BUFFER)
-		(yy_buffer_stack_top)++;
-	YY_CURRENT_BUFFER_LVALUE = new_buffer;
-
-	/* copied from zconf_switch_to_buffer. */
-	zconf_load_buffer_state( );
-	(yy_did_buffer_switch_on_eof) = 1;
-}
-
-/** Removes and deletes the top of the stack, if present.
- *  The next element becomes the new top.
- *  
- */
-void zconfpop_buffer_state (void)
-{
-    	if (!YY_CURRENT_BUFFER)
-		return;
-
-	zconf_delete_buffer(YY_CURRENT_BUFFER );
-	YY_CURRENT_BUFFER_LVALUE = NULL;
-	if ((yy_buffer_stack_top) > 0)
-		--(yy_buffer_stack_top);
-
-	if (YY_CURRENT_BUFFER) {
-		zconf_load_buffer_state( );
-		(yy_did_buffer_switch_on_eof) = 1;
-	}
-}
-
-/* Allocates the stack if it does not exist.
- *  Guarantees space for at least one push.
- */
-static void zconfensure_buffer_stack (void)
-{
-	int num_to_alloc;
-    
-	if (!(yy_buffer_stack)) {
-
-		/* First allocation is just for 2 elements, since we don't know if this
-		 * scanner will even need a stack. We use 2 instead of 1 to avoid an
-		 * immediate realloc on the next call.
-         */
-		num_to_alloc = 1;
-		(yy_buffer_stack) = (struct yy_buffer_state**)zconfalloc
-								(num_to_alloc * sizeof(struct yy_buffer_state*)
-								);
-		if ( ! (yy_buffer_stack) )
-			YY_FATAL_ERROR( "out of dynamic memory in zconfensure_buffer_stack()" );
-								  
-		memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-				
-		(yy_buffer_stack_max) = num_to_alloc;
-		(yy_buffer_stack_top) = 0;
-		return;
-	}
-
-	if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
-
-		/* Increase the buffer to prepare for a possible push. */
-		int grow_size = 8 /* arbitrary grow size */;
-
-		num_to_alloc = (yy_buffer_stack_max) + grow_size;
-		(yy_buffer_stack) = (struct yy_buffer_state**)zconfrealloc
-								((yy_buffer_stack),
-								num_to_alloc * sizeof(struct yy_buffer_state*)
-								);
-		if ( ! (yy_buffer_stack) )
-			YY_FATAL_ERROR( "out of dynamic memory in zconfensure_buffer_stack()" );
-
-		/* zero only the new slots.*/
-		memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
-		(yy_buffer_stack_max) = num_to_alloc;
-	}
-}
-
-/** Setup the input buffer state to scan directly from a user-specified character buffer.
- * @param base the character buffer
- * @param size the size in bytes of the character buffer
- * 
- * @return the newly allocated buffer state object. 
- */
-YY_BUFFER_STATE zconf_scan_buffer  (char * base, yy_size_t  size )
-{
-	YY_BUFFER_STATE b;
-    
-	if ( size < 2 ||
-	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
-	     base[size-1] != YY_END_OF_BUFFER_CHAR )
-		/* They forgot to leave room for the EOB's. */
-		return 0;
-
-	b = (YY_BUFFER_STATE) zconfalloc(sizeof( struct yy_buffer_state )  );
-	if ( ! b )
-		YY_FATAL_ERROR( "out of dynamic memory in zconf_scan_buffer()" );
-
-	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
-	b->yy_buf_pos = b->yy_ch_buf = base;
-	b->yy_is_our_buffer = 0;
-	b->yy_input_file = 0;
-	b->yy_n_chars = b->yy_buf_size;
-	b->yy_is_interactive = 0;
-	b->yy_at_bol = 1;
-	b->yy_fill_buffer = 0;
-	b->yy_buffer_status = YY_BUFFER_NEW;
-
-	zconf_switch_to_buffer(b  );
-
-	return b;
-}
-
-/** Setup the input buffer state to scan a string. The next call to zconflex() will
- * scan from a @e copy of @a str.
- * @param yystr a NUL-terminated string to scan
- * 
- * @return the newly allocated buffer state object.
- * @note If you want to scan bytes that may contain NUL values, then use
- *       zconf_scan_bytes() instead.
- */
-YY_BUFFER_STATE zconf_scan_string (yyconst char * yystr )
-{
-    
-	return zconf_scan_bytes(yystr,strlen(yystr) );
-}
-
-/** Setup the input buffer state to scan the given bytes. The next call to zconflex() will
- * scan from a @e copy of @a bytes.
- * @param yybytes the byte buffer to scan
- * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
- * 
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE zconf_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
-{
-	YY_BUFFER_STATE b;
-	char *buf;
-	yy_size_t n;
-	int i;
-    
-	/* Get memory for full buffer, including space for trailing EOB's. */
-	n = _yybytes_len + 2;
-	buf = (char *) zconfalloc(n  );
-	if ( ! buf )
-		YY_FATAL_ERROR( "out of dynamic memory in zconf_scan_bytes()" );
-
-	for ( i = 0; i < _yybytes_len; ++i )
-		buf[i] = yybytes[i];
-
-	buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
-
-	b = zconf_scan_buffer(buf,n );
-	if ( ! b )
-		YY_FATAL_ERROR( "bad buffer in zconf_scan_bytes()" );
-
-	/* It's okay to grow etc. this buffer, and we should throw it
-	 * away when we're done.
-	 */
-	b->yy_is_our_buffer = 1;
-
-	return b;
-}
-
-#ifndef YY_EXIT_FAILURE
-#define YY_EXIT_FAILURE 2
-#endif
-
-static void yy_fatal_error (yyconst char* msg )
-{
-    	(void) fprintf( stderr, "%s\n", msg );
-	exit( YY_EXIT_FAILURE );
-}
-
-/* Redefine yyless() so it works in section 3 code. */
-
-#undef yyless
-#define yyless(n) \
-	do \
-		{ \
-		/* Undo effects of setting up zconftext. */ \
-        int yyless_macro_arg = (n); \
-        YY_LESS_LINENO(yyless_macro_arg);\
-		zconftext[zconfleng] = (yy_hold_char); \
-		(yy_c_buf_p) = zconftext + yyless_macro_arg; \
-		(yy_hold_char) = *(yy_c_buf_p); \
-		*(yy_c_buf_p) = '\0'; \
-		zconfleng = yyless_macro_arg; \
-		} \
-	while ( 0 )
-
-/* Accessor  methods (get/set functions) to struct members. */
-
-/** Get the current line number.
- * 
- */
-int zconfget_lineno  (void)
-{
-        
-    return zconflineno;
-}
-
-/** Get the input stream.
- * 
- */
-FILE *zconfget_in  (void)
-{
-        return zconfin;
-}
-
-/** Get the output stream.
- * 
- */
-FILE *zconfget_out  (void)
-{
-        return zconfout;
-}
-
-/** Get the length of the current token.
- * 
- */
-int zconfget_leng  (void)
-{
-        return zconfleng;
-}
-
-/** Get the current token.
- * 
- */
-
-char *zconfget_text  (void)
-{
-        return zconftext;
-}
-
-/** Set the current line number.
- * @param line_number
- * 
- */
-void zconfset_lineno (int  line_number )
-{
-    
-    zconflineno = line_number;
-}
-
-/** Set the input stream. This does not discard the current
- * input buffer.
- * @param in_str A readable stream.
- * 
- * @see zconf_switch_to_buffer
- */
-void zconfset_in (FILE *  in_str )
-{
-        zconfin = in_str ;
-}
-
-void zconfset_out (FILE *  out_str )
-{
-        zconfout = out_str ;
-}
-
-int zconfget_debug  (void)
-{
-        return zconf_flex_debug;
-}
-
-void zconfset_debug (int  bdebug )
-{
-        zconf_flex_debug = bdebug ;
-}
-
-static int yy_init_globals (void)
-{
-        /* Initialization is the same as for the non-reentrant scanner.
-     * This function is called from zconflex_destroy(), so don't allocate here.
-     */
-
-    (yy_buffer_stack) = 0;
-    (yy_buffer_stack_top) = 0;
-    (yy_buffer_stack_max) = 0;
-    (yy_c_buf_p) = (char *) 0;
-    (yy_init) = 0;
-    (yy_start) = 0;
-
-/* Defined in main.c */
-#ifdef YY_STDINIT
-    zconfin = stdin;
-    zconfout = stdout;
-#else
-    zconfin = (FILE *) 0;
-    zconfout = (FILE *) 0;
-#endif
-
-    /* For future reference: Set errno on error, since we are called by
-     * zconflex_init()
-     */
-    return 0;
-}
-
-/* zconflex_destroy is for both reentrant and non-reentrant scanners. */
-int zconflex_destroy  (void)
-{
-    
-    /* Pop the buffer stack, destroying each element. */
-	while(YY_CURRENT_BUFFER){
-		zconf_delete_buffer(YY_CURRENT_BUFFER  );
-		YY_CURRENT_BUFFER_LVALUE = NULL;
-		zconfpop_buffer_state();
-	}
-
-	/* Destroy the stack itself. */
-	zconffree((yy_buffer_stack) );
-	(yy_buffer_stack) = NULL;
-
-    /* Reset the globals. This is important in a non-reentrant scanner so the next time
-     * zconflex() is called, initialization will occur. */
-    yy_init_globals( );
-
-    return 0;
-}
-
-/*
- * Internal utility routines.
- */
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
-{
-	register int i;
-	for ( i = 0; i < n; ++i )
-		s1[i] = s2[i];
-}
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * s )
-{
-	register int n;
-	for ( n = 0; s[n]; ++n )
-		;
-
-	return n;
-}
-#endif
-
-void *zconfalloc (yy_size_t  size )
-{
-	return (void *) malloc( size );
-}
-
-void *zconfrealloc  (void * ptr, yy_size_t  size )
-{
-	/* The cast to (char *) in the following accommodates both
-	 * implementations that use char* generic pointers, and those
-	 * that use void* generic pointers.  It works with the latter
-	 * because both ANSI C and C++ allow castless assignment from
-	 * any pointer type to void*, and deal with argument conversions
-	 * as though doing an assignment.
-	 */
-	return (void *) realloc( (char *) ptr, size );
-}
-
-void zconffree (void * ptr )
-{
-	free( (char *) ptr );	/* see zconfrealloc() for (char *) cast */
-}
-
-#define YYTABLES_NAME "yytables"
-
-void zconf_starthelp(void)
-{
-	new_string();
-	last_ts = first_ts = 0;
-	BEGIN(HELP);
-}
-
-static void zconf_endhelp(void)
-{
-	zconflval.string = text;
-	BEGIN(INITIAL);
-}
-
-/*
- * Try to open specified file with following names:
- * ./name
- * $(srctree)/name
- * The latter is used when srctree is separate from objtree
- * when compiling the kernel.
- * Return NULL if file is not found.
- */
-FILE *zconf_fopen(const char *name)
-{
-	char *env, fullname[PATH_MAX+1];
-	FILE *f;
-
-	f = fopen(name, "r");
-	if (!f && name != NULL && name[0] != '/') {
-		env = getenv(SRCTREE);
-		if (env) {
-			sprintf(fullname, "%s/%s", env, name);
-			f = fopen(fullname, "r");
-		}
-	}
-	return f;
-}
-
-void zconf_initscan(const char *name)
-{
-	zconfin = zconf_fopen(name);
-	if (!zconfin) {
-		printf("can't find file %s\n", name);
-		exit(1);
-	}
-
-	current_buf = xmalloc(sizeof(*current_buf));
-	memset(current_buf, 0, sizeof(*current_buf));
-
-	current_file = file_lookup(name);
-	current_file->lineno = 1;
-}
-
-void zconf_nextfile(const char *name)
-{
-	struct file *iter;
-	struct file *file = file_lookup(name);
-	struct buffer *buf = xmalloc(sizeof(*buf));
-	memset(buf, 0, sizeof(*buf));
-
-	current_buf->state = YY_CURRENT_BUFFER;
-	zconfin = zconf_fopen(file->name);
-	if (!zconfin) {
-		printf("%s:%d: can't open file \"%s\"\n",
-		    zconf_curname(), zconf_lineno(), file->name);
-		exit(1);
-	}
-	zconf_switch_to_buffer(zconf_create_buffer(zconfin,YY_BUF_SIZE));
-	buf->parent = current_buf;
-	current_buf = buf;
-
-	for (iter = current_file->parent; iter; iter = iter->parent ) {
-		if (!strcmp(current_file->name,iter->name) ) {
-			printf("%s:%d: recursive inclusion detected. "
-			       "Inclusion path:\n  current file : '%s'\n",
-			       zconf_curname(), zconf_lineno(),
-			       zconf_curname());
-			iter = current_file->parent;
-			while (iter && \
-			       strcmp(iter->name,current_file->name)) {
-				printf("  included from: '%s:%d'\n",
-				       iter->name, iter->lineno-1);
-				iter = iter->parent;
-			}
-			if (iter)
-				printf("  included from: '%s:%d'\n",
-				       iter->name, iter->lineno+1);
-			exit(1);
-		}
-	}
-	file->lineno = 1;
-	file->parent = current_file;
-	current_file = file;
-}
-
-static void zconf_endfile(void)
-{
-	struct buffer *parent;
-
-	current_file = current_file->parent;
-
-	parent = current_buf->parent;
-	if (parent) {
-		fclose(zconfin);
-		zconf_delete_buffer(YY_CURRENT_BUFFER);
-		zconf_switch_to_buffer(parent->state);
-	}
-	free(current_buf);
-	current_buf = parent;
-}
-
-int zconf_lineno(void)
-{
-	return current_pos.lineno;
-}
-
-const char *zconf_curname(void)
-{
-	return current_pos.file ? current_pos.file->name : "<none>";
-}
-
diff --git a/scripts/kconfig/zconf.tab.c_shipped b/scripts/kconfig/zconf.tab.c_shipped
deleted file mode 100644
index 65b7515..0000000
--- a/scripts/kconfig/zconf.tab.c_shipped
+++ /dev/null
@@ -1,2471 +0,0 @@
-/* A Bison parser, made by GNU Bison 3.0.4.  */
-
-/* Bison implementation for Yacc-like parsers in C
-
-   Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
-
-   This program is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
-
-/* As a special exception, you may create a larger work that contains
-   part or all of the Bison parser skeleton and distribute that work
-   under terms of your choice, so long as that work isn't itself a
-   parser generator using the skeleton or a modified version thereof
-   as a parser skeleton.  Alternatively, if you modify or redistribute
-   the parser skeleton itself, you may (at your option) remove this
-   special exception, which will cause the skeleton and the resulting
-   Bison output files to be licensed under the GNU General Public
-   License without this special exception.
-
-   This special exception was added by the Free Software Foundation in
-   version 2.2 of Bison.  */
-
-/* C LALR(1) parser skeleton written by Richard Stallman, by
-   simplifying the original so-called "semantic" parser.  */
-
-/* All symbols defined below should begin with yy or YY, to avoid
-   infringing on user name space.  This should be done even for local
-   variables, as they might otherwise be expanded by user macros.
-   There are some unavoidable exceptions within include files to
-   define necessary library symbols; they are noted "INFRINGES ON
-   USER NAME SPACE" below.  */
-
-/* Identify Bison output.  */
-#define YYBISON 1
-
-/* Bison version.  */
-#define YYBISON_VERSION "3.0.4"
-
-/* Skeleton name.  */
-#define YYSKELETON_NAME "yacc.c"
-
-/* Pure parsers.  */
-#define YYPURE 0
-
-/* Push parsers.  */
-#define YYPUSH 0
-
-/* Pull parsers.  */
-#define YYPULL 1
-
-
-/* Substitute the variable and function names.  */
-#define yyparse         zconfparse
-#define yylex           zconflex
-#define yyerror         zconferror
-#define yydebug         zconfdebug
-#define yynerrs         zconfnerrs
-
-#define yylval          zconflval
-#define yychar          zconfchar
-
-/* Copy the first part of user declarations.  */
-
-
-/*
- * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
- * Released under the terms of the GNU GPL v2.0.
- */
-
-#include <ctype.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdbool.h>
-
-#include "lkc.h"
-
-#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
-
-#define PRINTD		0x0001
-#define DEBUG_PARSE	0x0002
-
-int cdebug = PRINTD;
-
-extern int zconflex(void);
-static void zconfprint(const char *err, ...);
-static void zconf_error(const char *err, ...);
-static void zconferror(const char *err);
-static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtoken);
-
-struct symbol *symbol_hash[SYMBOL_HASHSIZE];
-
-static struct menu *current_menu, *current_entry;
-
-
-
-
-# ifndef YY_NULLPTR
-#  if defined __cplusplus && 201103L <= __cplusplus
-#   define YY_NULLPTR nullptr
-#  else
-#   define YY_NULLPTR 0
-#  endif
-# endif
-
-/* Enabling verbose error messages.  */
-#ifdef YYERROR_VERBOSE
-# undef YYERROR_VERBOSE
-# define YYERROR_VERBOSE 1
-#else
-# define YYERROR_VERBOSE 0
-#endif
-
-
-/* Debug traces.  */
-#ifndef YYDEBUG
-# define YYDEBUG 1
-#endif
-#if YYDEBUG
-extern int zconfdebug;
-#endif
-
-/* Token type.  */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
-  enum yytokentype
-  {
-    T_MAINMENU = 258,
-    T_MENU = 259,
-    T_ENDMENU = 260,
-    T_SOURCE = 261,
-    T_CHOICE = 262,
-    T_ENDCHOICE = 263,
-    T_COMMENT = 264,
-    T_CONFIG = 265,
-    T_MENUCONFIG = 266,
-    T_HELP = 267,
-    T_HELPTEXT = 268,
-    T_IF = 269,
-    T_ENDIF = 270,
-    T_DEPENDS = 271,
-    T_OPTIONAL = 272,
-    T_PROMPT = 273,
-    T_TYPE = 274,
-    T_DEFAULT = 275,
-    T_SELECT = 276,
-    T_IMPLY = 277,
-    T_RANGE = 278,
-    T_VISIBLE = 279,
-    T_OPTION = 280,
-    T_ON = 281,
-    T_WORD = 282,
-    T_WORD_QUOTE = 283,
-    T_UNEQUAL = 284,
-    T_LESS = 285,
-    T_LESS_EQUAL = 286,
-    T_GREATER = 287,
-    T_GREATER_EQUAL = 288,
-    T_CLOSE_PAREN = 289,
-    T_OPEN_PAREN = 290,
-    T_EOL = 291,
-    T_OR = 292,
-    T_AND = 293,
-    T_EQUAL = 294,
-    T_NOT = 295
-  };
-#endif
-
-/* Value type.  */
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-
-union YYSTYPE
-{
-
-
-	char *string;
-	struct file *file;
-	struct symbol *symbol;
-	struct expr *expr;
-	struct menu *menu;
-	const struct kconf_id *id;
-
-
-};
-
-typedef union YYSTYPE YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
-# define YYSTYPE_IS_DECLARED 1
-#endif
-
-
-extern YYSTYPE zconflval;
-
-int zconfparse (void);
-
-
-
-/* Copy the second part of user declarations.  */
-
-
-/* Include zconf.hash.c here so it can see the token constants. */
-#include "zconf.hash.c"
-
-
-
-#ifdef short
-# undef short
-#endif
-
-#ifdef YYTYPE_UINT8
-typedef YYTYPE_UINT8 yytype_uint8;
-#else
-typedef unsigned char yytype_uint8;
-#endif
-
-#ifdef YYTYPE_INT8
-typedef YYTYPE_INT8 yytype_int8;
-#else
-typedef signed char yytype_int8;
-#endif
-
-#ifdef YYTYPE_UINT16
-typedef YYTYPE_UINT16 yytype_uint16;
-#else
-typedef unsigned short int yytype_uint16;
-#endif
-
-#ifdef YYTYPE_INT16
-typedef YYTYPE_INT16 yytype_int16;
-#else
-typedef short int yytype_int16;
-#endif
-
-#ifndef YYSIZE_T
-# ifdef __SIZE_TYPE__
-#  define YYSIZE_T __SIZE_TYPE__
-# elif defined size_t
-#  define YYSIZE_T size_t
-# elif ! defined YYSIZE_T
-#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
-#  define YYSIZE_T size_t
-# else
-#  define YYSIZE_T unsigned int
-# endif
-#endif
-
-#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
-
-#ifndef YY_
-# if defined YYENABLE_NLS && YYENABLE_NLS
-#  if ENABLE_NLS
-#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
-#   define YY_(Msgid) dgettext ("bison-runtime", Msgid)
-#  endif
-# endif
-# ifndef YY_
-#  define YY_(Msgid) Msgid
-# endif
-#endif
-
-#ifndef YY_ATTRIBUTE
-# if (defined __GNUC__                                               \
-      && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__)))  \
-     || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
-#  define YY_ATTRIBUTE(Spec) __attribute__(Spec)
-# else
-#  define YY_ATTRIBUTE(Spec) /* empty */
-# endif
-#endif
-
-#ifndef YY_ATTRIBUTE_PURE
-# define YY_ATTRIBUTE_PURE   YY_ATTRIBUTE ((__pure__))
-#endif
-
-#ifndef YY_ATTRIBUTE_UNUSED
-# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
-#endif
-
-#if !defined _Noreturn \
-     && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
-# if defined _MSC_VER && 1200 <= _MSC_VER
-#  define _Noreturn __declspec (noreturn)
-# else
-#  define _Noreturn YY_ATTRIBUTE ((__noreturn__))
-# endif
-#endif
-
-/* Suppress unused-variable warnings by "using" E.  */
-#if ! defined lint || defined __GNUC__
-# define YYUSE(E) ((void) (E))
-#else
-# define YYUSE(E) /* empty */
-#endif
-
-#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
-/* Suppress an incorrect diagnostic about yylval being uninitialized.  */
-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
-    _Pragma ("GCC diagnostic push") \
-    _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
-    _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
-# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
-    _Pragma ("GCC diagnostic pop")
-#else
-# define YY_INITIAL_VALUE(Value) Value
-#endif
-#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
-# define YY_IGNORE_MAYBE_UNINITIALIZED_END
-#endif
-#ifndef YY_INITIAL_VALUE
-# define YY_INITIAL_VALUE(Value) /* Nothing. */
-#endif
-
-
-#if ! defined yyoverflow || YYERROR_VERBOSE
-
-/* The parser invokes alloca or malloc; define the necessary symbols.  */
-
-# ifdef YYSTACK_USE_ALLOCA
-#  if YYSTACK_USE_ALLOCA
-#   ifdef __GNUC__
-#    define YYSTACK_ALLOC __builtin_alloca
-#   elif defined __BUILTIN_VA_ARG_INCR
-#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
-#   elif defined _AIX
-#    define YYSTACK_ALLOC __alloca
-#   elif defined _MSC_VER
-#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
-#    define alloca _alloca
-#   else
-#    define YYSTACK_ALLOC alloca
-#    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
-#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-      /* Use EXIT_SUCCESS as a witness for stdlib.h.  */
-#     ifndef EXIT_SUCCESS
-#      define EXIT_SUCCESS 0
-#     endif
-#    endif
-#   endif
-#  endif
-# endif
-
-# ifdef YYSTACK_ALLOC
-   /* Pacify GCC's 'empty if-body' warning.  */
-#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
-#  ifndef YYSTACK_ALLOC_MAXIMUM
-    /* The OS might guarantee only one guard page at the bottom of the stack,
-       and a page size can be as small as 4096 bytes.  So we cannot safely
-       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
-       to allow for a few compiler-allocated temporary stack slots.  */
-#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
-#  endif
-# else
-#  define YYSTACK_ALLOC YYMALLOC
-#  define YYSTACK_FREE YYFREE
-#  ifndef YYSTACK_ALLOC_MAXIMUM
-#   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
-#  endif
-#  if (defined __cplusplus && ! defined EXIT_SUCCESS \
-       && ! ((defined YYMALLOC || defined malloc) \
-             && (defined YYFREE || defined free)))
-#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#   ifndef EXIT_SUCCESS
-#    define EXIT_SUCCESS 0
-#   endif
-#  endif
-#  ifndef YYMALLOC
-#   define YYMALLOC malloc
-#   if ! defined malloc && ! defined EXIT_SUCCESS
-void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
-#   endif
-#  endif
-#  ifndef YYFREE
-#   define YYFREE free
-#   if ! defined free && ! defined EXIT_SUCCESS
-void free (void *); /* INFRINGES ON USER NAME SPACE */
-#   endif
-#  endif
-# endif
-#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
-
-
-#if (! defined yyoverflow \
-     && (! defined __cplusplus \
-         || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
-
-/* A type that is properly aligned for any stack member.  */
-union yyalloc
-{
-  yytype_int16 yyss_alloc;
-  YYSTYPE yyvs_alloc;
-};
-
-/* The size of the maximum gap between one aligned stack and the next.  */
-# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
-
-/* The size of an array large to enough to hold all stacks, each with
-   N elements.  */
-# define YYSTACK_BYTES(N) \
-     ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
-      + YYSTACK_GAP_MAXIMUM)
-
-# define YYCOPY_NEEDED 1
-
-/* Relocate STACK from its old location to the new one.  The
-   local variables YYSIZE and YYSTACKSIZE give the old and new number of
-   elements in the stack, and YYPTR gives the new location of the
-   stack.  Advance YYPTR to a properly aligned location for the next
-   stack.  */
-# define YYSTACK_RELOCATE(Stack_alloc, Stack)                           \
-    do                                                                  \
-      {                                                                 \
-        YYSIZE_T yynewbytes;                                            \
-        YYCOPY (&yyptr->Stack_alloc, Stack, yysize);                    \
-        Stack = &yyptr->Stack_alloc;                                    \
-        yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
-        yyptr += yynewbytes / sizeof (*yyptr);                          \
-      }                                                                 \
-    while (0)
-
-#endif
-
-#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
-/* Copy COUNT objects from SRC to DST.  The source and destination do
-   not overlap.  */
-# ifndef YYCOPY
-#  if defined __GNUC__ && 1 < __GNUC__
-#   define YYCOPY(Dst, Src, Count) \
-      __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
-#  else
-#   define YYCOPY(Dst, Src, Count)              \
-      do                                        \
-        {                                       \
-          YYSIZE_T yyi;                         \
-          for (yyi = 0; yyi < (Count); yyi++)   \
-            (Dst)[yyi] = (Src)[yyi];            \
-        }                                       \
-      while (0)
-#  endif
-# endif
-#endif /* !YYCOPY_NEEDED */
-
-/* YYFINAL -- State number of the termination state.  */
-#define YYFINAL  11
-/* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   301
-
-/* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  41
-/* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  50
-/* YYNRULES -- Number of rules.  */
-#define YYNRULES  124
-/* YYNSTATES -- Number of states.  */
-#define YYNSTATES  204
-
-/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
-   by yylex, with out-of-bounds checking.  */
-#define YYUNDEFTOK  2
-#define YYMAXUTOK   295
-
-#define YYTRANSLATE(YYX)                                                \
-  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
-
-/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
-   as returned by yylex, without out-of-bounds checking.  */
-static const yytype_uint8 yytranslate[] =
-{
-       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
-       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
-      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
-      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
-      35,    36,    37,    38,    39,    40
-};
-
-#if YYDEBUG
-  /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
-static const yytype_uint16 yyrline[] =
-{
-       0,   109,   109,   109,   111,   111,   113,   115,   116,   117,
-     118,   119,   120,   124,   128,   128,   128,   128,   128,   128,
-     128,   128,   128,   132,   133,   134,   135,   136,   137,   141,
-     142,   148,   156,   162,   170,   180,   182,   183,   184,   185,
-     186,   187,   190,   198,   204,   214,   220,   226,   232,   235,
-     237,   248,   249,   254,   263,   268,   276,   279,   281,   282,
-     283,   284,   285,   288,   294,   305,   311,   321,   323,   328,
-     336,   344,   347,   349,   350,   351,   356,   363,   370,   375,
-     383,   386,   388,   389,   390,   393,   401,   408,   415,   421,
-     428,   430,   431,   432,   435,   443,   445,   446,   449,   456,
-     458,   463,   464,   467,   468,   469,   473,   474,   477,   478,
-     481,   482,   483,   484,   485,   486,   487,   488,   489,   490,
-     491,   494,   495,   498,   499
-};
-#endif
-
-#if YYDEBUG || YYERROR_VERBOSE || 0
-/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
-   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
-static const char *const yytname[] =
-{
-  "$end", "error", "$undefined", "T_MAINMENU", "T_MENU", "T_ENDMENU",
-  "T_SOURCE", "T_CHOICE", "T_ENDCHOICE", "T_COMMENT", "T_CONFIG",
-  "T_MENUCONFIG", "T_HELP", "T_HELPTEXT", "T_IF", "T_ENDIF", "T_DEPENDS",
-  "T_OPTIONAL", "T_PROMPT", "T_TYPE", "T_DEFAULT", "T_SELECT", "T_IMPLY",
-  "T_RANGE", "T_VISIBLE", "T_OPTION", "T_ON", "T_WORD", "T_WORD_QUOTE",
-  "T_UNEQUAL", "T_LESS", "T_LESS_EQUAL", "T_GREATER", "T_GREATER_EQUAL",
-  "T_CLOSE_PAREN", "T_OPEN_PAREN", "T_EOL", "T_OR", "T_AND", "T_EQUAL",
-  "T_NOT", "$accept", "input", "start", "stmt_list", "option_name",
-  "common_stmt", "option_error", "config_entry_start", "config_stmt",
-  "menuconfig_entry_start", "menuconfig_stmt", "config_option_list",
-  "config_option", "symbol_option", "symbol_option_list",
-  "symbol_option_arg", "choice", "choice_entry", "choice_end",
-  "choice_stmt", "choice_option_list", "choice_option", "choice_block",
-  "if_entry", "if_end", "if_stmt", "if_block", "mainmenu_stmt", "menu",
-  "menu_entry", "menu_end", "menu_stmt", "menu_block", "source_stmt",
-  "comment", "comment_stmt", "help_start", "help", "depends_list",
-  "depends", "visibility_list", "visible", "prompt_stmt_opt", "prompt",
-  "end", "nl", "if_expr", "expr", "symbol", "word_opt", YY_NULLPTR
-};
-#endif
-
-# ifdef YYPRINT
-/* YYTOKNUM[NUM] -- (External) token number corresponding to the
-   (internal) symbol number NUM (which must be that of a token).  */
-static const yytype_uint16 yytoknum[] =
-{
-       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
-     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
-     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
-     285,   286,   287,   288,   289,   290,   291,   292,   293,   294,
-     295
-};
-# endif
-
-#define YYPACT_NINF -92
-
-#define yypact_value_is_default(Yystate) \
-  (!!((Yystate) == (-92)))
-
-#define YYTABLE_NINF -88
-
-#define yytable_value_is_error(Yytable_value) \
-  0
-
-  /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
-     STATE-NUM.  */
-static const yytype_int16 yypact[] =
-{
-      17,    41,   -92,    15,   -92,   150,   -92,    19,   -92,   -92,
-     -13,   -92,    28,    41,    38,    41,    50,    47,    41,    79,
-      82,    44,    76,   -92,   -92,   -92,   -92,   -92,   -92,   -92,
-     -92,   -92,   118,   -92,   129,   -92,   -92,   -92,   -92,   -92,
-     -92,   -92,   -92,   -92,   -92,   -92,   -92,   -92,   -92,   -92,
-     -92,   -92,   184,   -92,   -92,   107,   -92,   111,   -92,   113,
-     -92,   116,   -92,   139,   140,   151,   -92,   -92,    44,    44,
-     142,   256,   -92,   160,   173,    27,   117,    80,    51,   255,
-     -15,   255,   217,   -92,   -92,   -92,   -92,   -92,   -92,    -8,
-     -92,    44,    44,   107,    87,    87,    87,    87,    87,    87,
-     -92,   -92,   174,   176,   187,    41,    41,    44,   188,   189,
-      87,   -92,   213,   -92,   -92,   -92,   -92,   206,   -92,   -92,
-     193,    41,    41,   203,   -92,   -92,   -92,   -92,   -92,   -92,
-     -92,   -92,   -92,   -92,   -92,   -92,   -92,   229,   -92,   241,
-     -92,   -92,   -92,   -92,   -92,   -92,   -92,   -92,   -92,   -92,
-     216,   -92,   -92,   -92,   -92,   -92,   -92,   -92,   -92,   -92,
-      44,   229,   222,   229,    64,   229,   229,    87,    31,   231,
-     -92,   -92,   229,   236,   229,    44,   -92,   145,   242,   -92,
-     -92,   243,   244,   245,   229,   251,   -92,   -92,   247,   -92,
-     257,   125,   -92,   -92,   -92,   -92,   -92,   260,    41,   -92,
-     -92,   -92,   -92,   -92
-};
-
-  /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
-     Performed when YYTABLE does not specify something else to do.  Zero
-     means the default is an error.  */
-static const yytype_uint8 yydefact[] =
-{
-       6,     0,   106,     0,     3,     0,     6,     6,   101,   102,
-       0,     1,     0,     0,     0,     0,   123,     0,     0,     0,
-       0,     0,     0,    14,    19,    15,    16,    21,    17,    18,
-      20,    22,     0,    23,     0,     7,    35,    26,    35,    27,
-      57,    67,     8,    72,    24,    95,    81,     9,    28,    90,
-      25,    10,     0,   107,     2,    76,    13,     0,   103,     0,
-     124,     0,   104,     0,     0,     0,   121,   122,     0,     0,
-       0,   110,   105,     0,     0,     0,     0,     0,     0,     0,
-      90,     0,     0,    77,    85,    53,    86,    31,    33,     0,
-     118,     0,     0,    69,     0,     0,     0,     0,     0,     0,
-      11,    12,     0,     0,     0,     0,    99,     0,     0,     0,
-       0,    49,     0,    41,    40,    36,    37,     0,    39,    38,
-       0,     0,    99,     0,    61,    62,    58,    60,    59,    68,
-      56,    55,    73,    75,    71,    74,    70,   108,    97,     0,
-      96,    82,    84,    80,    83,    79,    92,    93,    91,   117,
-     119,   120,   116,   111,   112,   113,   114,   115,    30,    88,
-       0,   108,     0,   108,   108,   108,   108,     0,     0,     0,
-      89,    65,   108,     0,   108,     0,    98,     0,     0,    42,
-     100,     0,     0,     0,   108,    51,    48,    29,     0,    64,
-       0,   109,    94,    43,    44,    45,    46,     0,     0,    50,
-      63,    66,    47,    52
-};
-
-  /* YYPGOTO[NTERM-NUM].  */
-static const yytype_int16 yypgoto[] =
-{
-     -92,   -92,   285,   291,   -92,    32,   -66,   -92,   -92,   -92,
-     -92,   261,   -92,   -92,   -92,   -92,   -92,   -92,   -92,     1,
-     -92,   -92,   -92,   -92,   -92,   -92,   -92,   -92,   -92,   -92,
-     -92,    24,   -92,   -92,   -92,   -92,   -92,   221,   220,   -64,
-     -92,   -92,   179,    -1,    67,     0,   110,   -67,   -91,   -92
-};
-
-  /* YYDEFGOTO[NTERM-NUM].  */
-static const yytype_int16 yydefgoto[] =
-{
-      -1,     3,     4,     5,    34,    35,   114,    36,    37,    38,
-      39,    75,   115,   116,   168,   199,    40,    41,   130,    42,
-      77,   126,    78,    43,   134,    44,    79,     6,    45,    46,
-     143,    47,    81,    48,    49,    50,   117,   118,    82,   119,
-      80,   140,   162,   163,    51,     7,   176,    70,    71,    61
-};
-
-  /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
-     positive, shift that token.  If negative, reduce the rule whose
-     number is the opposite.  If YYTABLE_NINF, syntax error.  */
-static const yytype_int16 yytable[] =
-{
-      10,    89,    90,   152,   153,   154,   155,   156,   157,   137,
-      55,   125,    57,   128,    59,    11,   147,    63,   148,   167,
-       1,   138,     1,     2,   150,   151,   149,   -32,   102,    91,
-      92,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   103,
-     164,   -32,   -32,   104,   -32,   105,   106,   107,   108,   109,
-     110,   -32,   111,     2,   112,    53,    14,    15,   185,    17,
-      18,    19,    20,   113,    56,    21,    22,   186,     8,     9,
-      93,    66,    67,   147,    58,   148,   184,    60,   175,    68,
-     133,   102,   142,    62,    69,   -54,   -54,    33,   -54,   -54,
-     -54,   -54,   103,   177,   -54,   -54,   104,   120,   121,   122,
-     123,    91,    92,   135,   161,   144,    64,   112,   191,    65,
-     129,   132,    72,   141,    66,    67,   124,   -34,   102,    73,
-     172,   -34,   -34,   -34,   -34,   -34,   -34,   -34,   -34,   103,
-      74,   -34,   -34,   104,   -34,   105,   106,   107,   108,   109,
-     110,   -34,   111,    53,   112,   131,   136,    83,   145,    84,
-      -5,    12,    85,   113,    13,    14,    15,    16,    17,    18,
-      19,    20,    91,    92,    21,    22,    23,    24,    25,    26,
-      27,    28,    29,    30,    31,    86,    87,    32,     2,    91,
-      92,   192,    91,    92,    -4,    12,    33,    88,    13,    14,
-      15,    16,    17,    18,    19,    20,   100,   203,    21,    22,
-      23,    24,    25,    26,    27,    28,    29,    30,    31,   101,
-     158,    32,   159,   160,   169,   165,   166,   -87,   102,   170,
-      33,   -87,   -87,   -87,   -87,   -87,   -87,   -87,   -87,   171,
-     174,   -87,   -87,   104,   -87,   -87,   -87,   -87,   -87,   -87,
-     -87,   -87,   102,   175,   112,   -78,   -78,   -78,   -78,   -78,
-     -78,   -78,   -78,   146,    92,   -78,   -78,   104,   179,    13,
-      14,    15,    16,    17,    18,    19,    20,   187,   112,    21,
-      22,   178,   189,   180,   181,   182,   183,   146,   193,   194,
-     195,   196,   188,   200,   190,    94,    95,    96,    97,    98,
-     198,    33,    54,   201,   197,    99,   202,    52,   127,    76,
-     139,   173
-};
-
-static const yytype_uint8 yycheck[] =
-{
-       1,    68,    69,    94,    95,    96,    97,    98,    99,    24,
-      10,    77,    13,    77,    15,     0,    82,    18,    82,   110,
-       3,    36,     3,    36,    91,    92,    34,     0,     1,    37,
-      38,     4,     5,     6,     7,     8,     9,    10,    11,    12,
-     107,    14,    15,    16,    17,    18,    19,    20,    21,    22,
-      23,    24,    25,    36,    27,    36,     5,     6,    27,     8,
-       9,    10,    11,    36,    36,    14,    15,    36,    27,    28,
-      70,    27,    28,   139,    36,   139,   167,    27,    14,    35,
-      79,     1,    81,    36,    40,     5,     6,    36,     8,     9,
-      10,    11,    12,   160,    14,    15,    16,    17,    18,    19,
-      20,    37,    38,    79,   105,    81,    27,    27,   175,    27,
-      78,    79,    36,    81,    27,    28,    36,     0,     1,     1,
-     121,     4,     5,     6,     7,     8,     9,    10,    11,    12,
-       1,    14,    15,    16,    17,    18,    19,    20,    21,    22,
-      23,    24,    25,    36,    27,    78,    79,    36,    81,    36,
-       0,     1,    36,    36,     4,     5,     6,     7,     8,     9,
-      10,    11,    37,    38,    14,    15,    16,    17,    18,    19,
-      20,    21,    22,    23,    24,    36,    36,    27,    36,    37,
-      38,    36,    37,    38,     0,     1,    36,    36,     4,     5,
-       6,     7,     8,     9,    10,    11,    36,   198,    14,    15,
-      16,    17,    18,    19,    20,    21,    22,    23,    24,    36,
-      36,    27,    36,    26,     1,    27,    27,     0,     1,    13,
-      36,     4,     5,     6,     7,     8,     9,    10,    11,    36,
-      27,    14,    15,    16,    17,    18,    19,    20,    21,    22,
-      23,    24,     1,    14,    27,     4,     5,     6,     7,     8,
-       9,    10,    11,    36,    38,    14,    15,    16,    36,     4,
-       5,     6,     7,     8,     9,    10,    11,    36,    27,    14,
-      15,   161,    36,   163,   164,   165,   166,    36,    36,    36,
-      36,    36,   172,    36,   174,    29,    30,    31,    32,    33,
-      39,    36,     7,    36,   184,    39,    36,     6,    77,    38,
-      80,   122
-};
-
-  /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
-     symbol of state STATE-NUM.  */
-static const yytype_uint8 yystos[] =
-{
-       0,     3,    36,    42,    43,    44,    68,    86,    27,    28,
-      84,     0,     1,     4,     5,     6,     7,     8,     9,    10,
-      11,    14,    15,    16,    17,    18,    19,    20,    21,    22,
-      23,    24,    27,    36,    45,    46,    48,    49,    50,    51,
-      57,    58,    60,    64,    66,    69,    70,    72,    74,    75,
-      76,    85,    44,    36,    43,    86,    36,    84,    36,    84,
-      27,    90,    36,    84,    27,    27,    27,    28,    35,    40,
-      88,    89,    36,     1,     1,    52,    52,    61,    63,    67,
-      81,    73,    79,    36,    36,    36,    36,    36,    36,    88,
-      88,    37,    38,    86,    29,    30,    31,    32,    33,    39,
-      36,    36,     1,    12,    16,    18,    19,    20,    21,    22,
-      23,    25,    27,    36,    47,    53,    54,    77,    78,    80,
-      17,    18,    19,    20,    36,    47,    62,    78,    80,    46,
-      59,    85,    46,    60,    65,    72,    85,    24,    36,    79,
-      82,    46,    60,    71,    72,    85,    36,    47,    80,    34,
-      88,    88,    89,    89,    89,    89,    89,    89,    36,    36,
-      26,    84,    83,    84,    88,    27,    27,    89,    55,     1,
-      13,    36,    84,    83,    27,    14,    87,    88,    87,    36,
-      87,    87,    87,    87,    89,    27,    36,    36,    87,    36,
-      87,    88,    36,    36,    36,    36,    36,    87,    39,    56,
-      36,    36,    36,    84
-};
-
-  /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
-static const yytype_uint8 yyr1[] =
-{
-       0,    41,    42,    42,    43,    43,    44,    44,    44,    44,
-      44,    44,    44,    44,    45,    45,    45,    45,    45,    45,
-      45,    45,    45,    46,    46,    46,    46,    46,    46,    47,
-      47,    48,    49,    50,    51,    52,    52,    52,    52,    52,
-      52,    52,    53,    53,    53,    53,    53,    53,    54,    55,
-      55,    56,    56,    57,    58,    59,    60,    61,    61,    61,
-      61,    61,    61,    62,    62,    62,    62,    63,    63,    64,
-      65,    66,    67,    67,    67,    67,    68,    69,    70,    71,
-      72,    73,    73,    73,    73,    74,    75,    76,    77,    78,
-      79,    79,    79,    79,    80,    81,    81,    81,    82,    83,
-      83,    84,    84,    85,    85,    85,    86,    86,    87,    87,
-      88,    88,    88,    88,    88,    88,    88,    88,    88,    88,
-      88,    89,    89,    90,    90
-};
-
-  /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.  */
-static const yytype_uint8 yyr2[] =
-{
-       0,     2,     2,     1,     2,     1,     0,     2,     2,     2,
-       2,     4,     4,     3,     1,     1,     1,     1,     1,     1,
-       1,     1,     1,     1,     1,     1,     1,     1,     1,     3,
-       2,     3,     2,     3,     2,     0,     2,     2,     2,     2,
-       2,     2,     3,     4,     4,     4,     4,     5,     3,     0,
-       3,     0,     2,     3,     2,     1,     3,     0,     2,     2,
-       2,     2,     2,     4,     3,     2,     4,     0,     2,     3,
-       1,     3,     0,     2,     2,     2,     3,     3,     3,     1,
-       3,     0,     2,     2,     2,     3,     3,     2,     2,     2,
-       0,     2,     2,     2,     4,     0,     2,     2,     2,     0,
-       2,     1,     1,     2,     2,     2,     1,     2,     0,     2,
-       1,     3,     3,     3,     3,     3,     3,     3,     2,     3,
-       3,     1,     1,     0,     1
-};
-
-
-#define yyerrok         (yyerrstatus = 0)
-#define yyclearin       (yychar = YYEMPTY)
-#define YYEMPTY         (-2)
-#define YYEOF           0
-
-#define YYACCEPT        goto yyacceptlab
-#define YYABORT         goto yyabortlab
-#define YYERROR         goto yyerrorlab
-
-
-#define YYRECOVERING()  (!!yyerrstatus)
-
-#define YYBACKUP(Token, Value)                                  \
-do                                                              \
-  if (yychar == YYEMPTY)                                        \
-    {                                                           \
-      yychar = (Token);                                         \
-      yylval = (Value);                                         \
-      YYPOPSTACK (yylen);                                       \
-      yystate = *yyssp;                                         \
-      goto yybackup;                                            \
-    }                                                           \
-  else                                                          \
-    {                                                           \
-      yyerror (YY_("syntax error: cannot back up")); \
-      YYERROR;                                                  \
-    }                                                           \
-while (0)
-
-/* Error token number */
-#define YYTERROR        1
-#define YYERRCODE       256
-
-
-
-/* Enable debugging if requested.  */
-#if YYDEBUG
-
-# ifndef YYFPRINTF
-#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
-#  define YYFPRINTF fprintf
-# endif
-
-# define YYDPRINTF(Args)                        \
-do {                                            \
-  if (yydebug)                                  \
-    YYFPRINTF Args;                             \
-} while (0)
-
-/* This macro is provided for backward compatibility. */
-#ifndef YY_LOCATION_PRINT
-# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-#endif
-
-
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location)                    \
-do {                                                                      \
-  if (yydebug)                                                            \
-    {                                                                     \
-      YYFPRINTF (stderr, "%s ", Title);                                   \
-      yy_symbol_print (stderr,                                            \
-                  Type, Value); \
-      YYFPRINTF (stderr, "\n");                                           \
-    }                                                                     \
-} while (0)
-
-
-/*----------------------------------------.
-| Print this symbol's value on YYOUTPUT.  |
-`----------------------------------------*/
-
-static void
-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
-{
-  FILE *yyo = yyoutput;
-  YYUSE (yyo);
-  if (!yyvaluep)
-    return;
-# ifdef YYPRINT
-  if (yytype < YYNTOKENS)
-    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
-# endif
-  YYUSE (yytype);
-}
-
-
-/*--------------------------------.
-| Print this symbol on YYOUTPUT.  |
-`--------------------------------*/
-
-static void
-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
-{
-  YYFPRINTF (yyoutput, "%s %s (",
-             yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
-
-  yy_symbol_value_print (yyoutput, yytype, yyvaluep);
-  YYFPRINTF (yyoutput, ")");
-}
-
-/*------------------------------------------------------------------.
-| yy_stack_print -- Print the state stack from its BOTTOM up to its |
-| TOP (included).                                                   |
-`------------------------------------------------------------------*/
-
-static void
-yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
-{
-  YYFPRINTF (stderr, "Stack now");
-  for (; yybottom <= yytop; yybottom++)
-    {
-      int yybot = *yybottom;
-      YYFPRINTF (stderr, " %d", yybot);
-    }
-  YYFPRINTF (stderr, "\n");
-}
-
-# define YY_STACK_PRINT(Bottom, Top)                            \
-do {                                                            \
-  if (yydebug)                                                  \
-    yy_stack_print ((Bottom), (Top));                           \
-} while (0)
-
-
-/*------------------------------------------------.
-| Report that the YYRULE is going to be reduced.  |
-`------------------------------------------------*/
-
-static void
-yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule)
-{
-  unsigned long int yylno = yyrline[yyrule];
-  int yynrhs = yyr2[yyrule];
-  int yyi;
-  YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
-             yyrule - 1, yylno);
-  /* The symbols being reduced.  */
-  for (yyi = 0; yyi < yynrhs; yyi++)
-    {
-      YYFPRINTF (stderr, "   $%d = ", yyi + 1);
-      yy_symbol_print (stderr,
-                       yystos[yyssp[yyi + 1 - yynrhs]],
-                       &(yyvsp[(yyi + 1) - (yynrhs)])
-                                              );
-      YYFPRINTF (stderr, "\n");
-    }
-}
-
-# define YY_REDUCE_PRINT(Rule)          \
-do {                                    \
-  if (yydebug)                          \
-    yy_reduce_print (yyssp, yyvsp, Rule); \
-} while (0)
-
-/* Nonzero means print parse trace.  It is left uninitialized so that
-   multiple parsers can coexist.  */
-int yydebug;
-#else /* !YYDEBUG */
-# define YYDPRINTF(Args)
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
-# define YY_STACK_PRINT(Bottom, Top)
-# define YY_REDUCE_PRINT(Rule)
-#endif /* !YYDEBUG */
-
-
-/* YYINITDEPTH -- initial size of the parser's stacks.  */
-#ifndef YYINITDEPTH
-# define YYINITDEPTH 200
-#endif
-
-/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
-   if the built-in stack extension method is used).
-
-   Do not make this value too large; the results are undefined if
-   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
-   evaluated with infinite-precision integer arithmetic.  */
-
-#ifndef YYMAXDEPTH
-# define YYMAXDEPTH 10000
-#endif
-
-
-#if YYERROR_VERBOSE
-
-# ifndef yystrlen
-#  if defined __GLIBC__ && defined _STRING_H
-#   define yystrlen strlen
-#  else
-/* Return the length of YYSTR.  */
-static YYSIZE_T
-yystrlen (const char *yystr)
-{
-  YYSIZE_T yylen;
-  for (yylen = 0; yystr[yylen]; yylen++)
-    continue;
-  return yylen;
-}
-#  endif
-# endif
-
-# ifndef yystpcpy
-#  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
-#   define yystpcpy stpcpy
-#  else
-/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
-   YYDEST.  */
-static char *
-yystpcpy (char *yydest, const char *yysrc)
-{
-  char *yyd = yydest;
-  const char *yys = yysrc;
-
-  while ((*yyd++ = *yys++) != '\0')
-    continue;
-
-  return yyd - 1;
-}
-#  endif
-# endif
-
-# ifndef yytnamerr
-/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
-   quotes and backslashes, so that it's suitable for yyerror.  The
-   heuristic is that double-quoting is unnecessary unless the string
-   contains an apostrophe, a comma, or backslash (other than
-   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
-   null, do not copy; instead, return the length of what the result
-   would have been.  */
-static YYSIZE_T
-yytnamerr (char *yyres, const char *yystr)
-{
-  if (*yystr == '"')
-    {
-      YYSIZE_T yyn = 0;
-      char const *yyp = yystr;
-
-      for (;;)
-        switch (*++yyp)
-          {
-          case '\'':
-          case ',':
-            goto do_not_strip_quotes;
-
-          case '\\':
-            if (*++yyp != '\\')
-              goto do_not_strip_quotes;
-            /* Fall through.  */
-          default:
-            if (yyres)
-              yyres[yyn] = *yyp;
-            yyn++;
-            break;
-
-          case '"':
-            if (yyres)
-              yyres[yyn] = '\0';
-            return yyn;
-          }
-    do_not_strip_quotes: ;
-    }
-
-  if (! yyres)
-    return yystrlen (yystr);
-
-  return yystpcpy (yyres, yystr) - yyres;
-}
-# endif
-
-/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
-   about the unexpected token YYTOKEN for the state stack whose top is
-   YYSSP.
-
-   Return 0 if *YYMSG was successfully written.  Return 1 if *YYMSG is
-   not large enough to hold the message.  In that case, also set
-   *YYMSG_ALLOC to the required number of bytes.  Return 2 if the
-   required number of bytes is too large to store.  */
-static int
-yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
-                yytype_int16 *yyssp, int yytoken)
-{
-  YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
-  YYSIZE_T yysize = yysize0;
-  enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
-  /* Internationalized format string. */
-  const char *yyformat = YY_NULLPTR;
-  /* Arguments of yyformat. */
-  char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
-  /* Number of reported tokens (one for the "unexpected", one per
-     "expected"). */
-  int yycount = 0;
-
-  /* There are many possibilities here to consider:
-     - If this state is a consistent state with a default action, then
-       the only way this function was invoked is if the default action
-       is an error action.  In that case, don't check for expected
-       tokens because there are none.
-     - The only way there can be no lookahead present (in yychar) is if
-       this state is a consistent state with a default action.  Thus,
-       detecting the absence of a lookahead is sufficient to determine
-       that there is no unexpected or expected token to report.  In that
-       case, just report a simple "syntax error".
-     - Don't assume there isn't a lookahead just because this state is a
-       consistent state with a default action.  There might have been a
-       previous inconsistent state, consistent state with a non-default
-       action, or user semantic action that manipulated yychar.
-     - Of course, the expected token list depends on states to have
-       correct lookahead information, and it depends on the parser not
-       to perform extra reductions after fetching a lookahead from the
-       scanner and before detecting a syntax error.  Thus, state merging
-       (from LALR or IELR) and default reductions corrupt the expected
-       token list.  However, the list is correct for canonical LR with
-       one exception: it will still contain any token that will not be
-       accepted due to an error action in a later state.
-  */
-  if (yytoken != YYEMPTY)
-    {
-      int yyn = yypact[*yyssp];
-      yyarg[yycount++] = yytname[yytoken];
-      if (!yypact_value_is_default (yyn))
-        {
-          /* Start YYX at -YYN if negative to avoid negative indexes in
-             YYCHECK.  In other words, skip the first -YYN actions for
-             this state because they are default actions.  */
-          int yyxbegin = yyn < 0 ? -yyn : 0;
-          /* Stay within bounds of both yycheck and yytname.  */
-          int yychecklim = YYLAST - yyn + 1;
-          int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
-          int yyx;
-
-          for (yyx = yyxbegin; yyx < yyxend; ++yyx)
-            if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
-                && !yytable_value_is_error (yytable[yyx + yyn]))
-              {
-                if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
-                  {
-                    yycount = 1;
-                    yysize = yysize0;
-                    break;
-                  }
-                yyarg[yycount++] = yytname[yyx];
-                {
-                  YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
-                  if (! (yysize <= yysize1
-                         && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
-                    return 2;
-                  yysize = yysize1;
-                }
-              }
-        }
-    }
-
-  switch (yycount)
-    {
-# define YYCASE_(N, S)                      \
-      case N:                               \
-        yyformat = S;                       \
-      break
-      YYCASE_(0, YY_("syntax error"));
-      YYCASE_(1, YY_("syntax error, unexpected %s"));
-      YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
-      YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
-      YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
-      YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
-# undef YYCASE_
-    }
-
-  {
-    YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
-    if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
-      return 2;
-    yysize = yysize1;
-  }
-
-  if (*yymsg_alloc < yysize)
-    {
-      *yymsg_alloc = 2 * yysize;
-      if (! (yysize <= *yymsg_alloc
-             && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
-        *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
-      return 1;
-    }
-
-  /* Avoid sprintf, as that infringes on the user's name space.
-     Don't have undefined behavior even if the translation
-     produced a string with the wrong number of "%s"s.  */
-  {
-    char *yyp = *yymsg;
-    int yyi = 0;
-    while ((*yyp = *yyformat) != '\0')
-      if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
-        {
-          yyp += yytnamerr (yyp, yyarg[yyi++]);
-          yyformat += 2;
-        }
-      else
-        {
-          yyp++;
-          yyformat++;
-        }
-  }
-  return 0;
-}
-#endif /* YYERROR_VERBOSE */
-
-/*-----------------------------------------------.
-| Release the memory associated to this symbol.  |
-`-----------------------------------------------*/
-
-static void
-yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
-{
-  YYUSE (yyvaluep);
-  if (!yymsg)
-    yymsg = "Deleting";
-  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
-
-  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
-  switch (yytype)
-    {
-          case 58: /* choice_entry  */
-
-      {
-	fprintf(stderr, "%s:%d: missing end statement for this entry\n",
-		((*yyvaluep).menu)->file->name, ((*yyvaluep).menu)->lineno);
-	if (current_menu == ((*yyvaluep).menu))
-		menu_end_menu();
-}
-
-        break;
-
-    case 64: /* if_entry  */
-
-      {
-	fprintf(stderr, "%s:%d: missing end statement for this entry\n",
-		((*yyvaluep).menu)->file->name, ((*yyvaluep).menu)->lineno);
-	if (current_menu == ((*yyvaluep).menu))
-		menu_end_menu();
-}
-
-        break;
-
-    case 70: /* menu_entry  */
-
-      {
-	fprintf(stderr, "%s:%d: missing end statement for this entry\n",
-		((*yyvaluep).menu)->file->name, ((*yyvaluep).menu)->lineno);
-	if (current_menu == ((*yyvaluep).menu))
-		menu_end_menu();
-}
-
-        break;
-
-
-      default:
-        break;
-    }
-  YY_IGNORE_MAYBE_UNINITIALIZED_END
-}
-
-
-
-
-/* The lookahead symbol.  */
-int yychar;
-
-/* The semantic value of the lookahead symbol.  */
-YYSTYPE yylval;
-/* Number of syntax errors so far.  */
-int yynerrs;
-
-
-/*----------.
-| yyparse.  |
-`----------*/
-
-int
-yyparse (void)
-{
-    int yystate;
-    /* Number of tokens to shift before error messages enabled.  */
-    int yyerrstatus;
-
-    /* The stacks and their tools:
-       'yyss': related to states.
-       'yyvs': related to semantic values.
-
-       Refer to the stacks through separate pointers, to allow yyoverflow
-       to reallocate them elsewhere.  */
-
-    /* The state stack.  */
-    yytype_int16 yyssa[YYINITDEPTH];
-    yytype_int16 *yyss;
-    yytype_int16 *yyssp;
-
-    /* The semantic value stack.  */
-    YYSTYPE yyvsa[YYINITDEPTH];
-    YYSTYPE *yyvs;
-    YYSTYPE *yyvsp;
-
-    YYSIZE_T yystacksize;
-
-  int yyn;
-  int yyresult;
-  /* Lookahead token as an internal (translated) token number.  */
-  int yytoken = 0;
-  /* The variables used to return semantic value and location from the
-     action routines.  */
-  YYSTYPE yyval;
-
-#if YYERROR_VERBOSE
-  /* Buffer for error messages, and its allocated size.  */
-  char yymsgbuf[128];
-  char *yymsg = yymsgbuf;
-  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
-#endif
-
-#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
-
-  /* The number of symbols on the RHS of the reduced rule.
-     Keep to zero when no symbol should be popped.  */
-  int yylen = 0;
-
-  yyssp = yyss = yyssa;
-  yyvsp = yyvs = yyvsa;
-  yystacksize = YYINITDEPTH;
-
-  YYDPRINTF ((stderr, "Starting parse\n"));
-
-  yystate = 0;
-  yyerrstatus = 0;
-  yynerrs = 0;
-  yychar = YYEMPTY; /* Cause a token to be read.  */
-  goto yysetstate;
-
-/*------------------------------------------------------------.
-| yynewstate -- Push a new state, which is found in yystate.  |
-`------------------------------------------------------------*/
- yynewstate:
-  /* In all cases, when you get here, the value and location stacks
-     have just been pushed.  So pushing a state here evens the stacks.  */
-  yyssp++;
-
- yysetstate:
-  *yyssp = yystate;
-
-  if (yyss + yystacksize - 1 <= yyssp)
-    {
-      /* Get the current used size of the three stacks, in elements.  */
-      YYSIZE_T yysize = yyssp - yyss + 1;
-
-#ifdef yyoverflow
-      {
-        /* Give user a chance to reallocate the stack.  Use copies of
-           these so that the &'s don't force the real ones into
-           memory.  */
-        YYSTYPE *yyvs1 = yyvs;
-        yytype_int16 *yyss1 = yyss;
-
-        /* Each stack pointer address is followed by the size of the
-           data in use in that stack, in bytes.  This used to be a
-           conditional around just the two extra args, but that might
-           be undefined if yyoverflow is a macro.  */
-        yyoverflow (YY_("memory exhausted"),
-                    &yyss1, yysize * sizeof (*yyssp),
-                    &yyvs1, yysize * sizeof (*yyvsp),
-                    &yystacksize);
-
-        yyss = yyss1;
-        yyvs = yyvs1;
-      }
-#else /* no yyoverflow */
-# ifndef YYSTACK_RELOCATE
-      goto yyexhaustedlab;
-# else
-      /* Extend the stack our own way.  */
-      if (YYMAXDEPTH <= yystacksize)
-        goto yyexhaustedlab;
-      yystacksize *= 2;
-      if (YYMAXDEPTH < yystacksize)
-        yystacksize = YYMAXDEPTH;
-
-      {
-        yytype_int16 *yyss1 = yyss;
-        union yyalloc *yyptr =
-          (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
-        if (! yyptr)
-          goto yyexhaustedlab;
-        YYSTACK_RELOCATE (yyss_alloc, yyss);
-        YYSTACK_RELOCATE (yyvs_alloc, yyvs);
-#  undef YYSTACK_RELOCATE
-        if (yyss1 != yyssa)
-          YYSTACK_FREE (yyss1);
-      }
-# endif
-#endif /* no yyoverflow */
-
-      yyssp = yyss + yysize - 1;
-      yyvsp = yyvs + yysize - 1;
-
-      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
-                  (unsigned long int) yystacksize));
-
-      if (yyss + yystacksize - 1 <= yyssp)
-        YYABORT;
-    }
-
-  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
-
-  if (yystate == YYFINAL)
-    YYACCEPT;
-
-  goto yybackup;
-
-/*-----------.
-| yybackup.  |
-`-----------*/
-yybackup:
-
-  /* Do appropriate processing given the current state.  Read a
-     lookahead token if we need one and don't already have one.  */
-
-  /* First try to decide what to do without reference to lookahead token.  */
-  yyn = yypact[yystate];
-  if (yypact_value_is_default (yyn))
-    goto yydefault;
-
-  /* Not known => get a lookahead token if don't already have one.  */
-
-  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
-  if (yychar == YYEMPTY)
-    {
-      YYDPRINTF ((stderr, "Reading a token: "));
-      yychar = yylex ();
-    }
-
-  if (yychar <= YYEOF)
-    {
-      yychar = yytoken = YYEOF;
-      YYDPRINTF ((stderr, "Now at end of input.\n"));
-    }
-  else
-    {
-      yytoken = YYTRANSLATE (yychar);
-      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
-    }
-
-  /* If the proper action on seeing token YYTOKEN is to reduce or to
-     detect an error, take that action.  */
-  yyn += yytoken;
-  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
-    goto yydefault;
-  yyn = yytable[yyn];
-  if (yyn <= 0)
-    {
-      if (yytable_value_is_error (yyn))
-        goto yyerrlab;
-      yyn = -yyn;
-      goto yyreduce;
-    }
-
-  /* Count tokens shifted since error; after three, turn off error
-     status.  */
-  if (yyerrstatus)
-    yyerrstatus--;
-
-  /* Shift the lookahead token.  */
-  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
-
-  /* Discard the shifted token.  */
-  yychar = YYEMPTY;
-
-  yystate = yyn;
-  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
-  *++yyvsp = yylval;
-  YY_IGNORE_MAYBE_UNINITIALIZED_END
-
-  goto yynewstate;
-
-
-/*-----------------------------------------------------------.
-| yydefault -- do the default action for the current state.  |
-`-----------------------------------------------------------*/
-yydefault:
-  yyn = yydefact[yystate];
-  if (yyn == 0)
-    goto yyerrlab;
-  goto yyreduce;
-
-
-/*-----------------------------.
-| yyreduce -- Do a reduction.  |
-`-----------------------------*/
-yyreduce:
-  /* yyn is the number of a rule to reduce with.  */
-  yylen = yyr2[yyn];
-
-  /* If YYLEN is nonzero, implement the default value of the action:
-     '$$ = $1'.
-
-     Otherwise, the following line sets YYVAL to garbage.
-     This behavior is undocumented and Bison
-     users should not rely upon it.  Assigning to YYVAL
-     unconditionally makes the parser a bit smaller, and it avoids a
-     GCC warning that YYVAL may be used uninitialized.  */
-  yyval = yyvsp[1-yylen];
-
-
-  YY_REDUCE_PRINT (yyn);
-  switch (yyn)
-    {
-        case 10:
-
-    { zconf_error("unexpected end statement"); }
-
-    break;
-
-  case 11:
-
-    { zconf_error("unknown statement \"%s\"", (yyvsp[-2].string)); }
-
-    break;
-
-  case 12:
-
-    {
-	zconf_error("unexpected option \"%s\"", kconf_id_strings + (yyvsp[-2].id)->name);
-}
-
-    break;
-
-  case 13:
-
-    { zconf_error("invalid statement"); }
-
-    break;
-
-  case 29:
-
-    { zconf_error("unknown option \"%s\"", (yyvsp[-2].string)); }
-
-    break;
-
-  case 30:
-
-    { zconf_error("invalid option"); }
-
-    break;
-
-  case 31:
-
-    {
-	struct symbol *sym = sym_lookup((yyvsp[-1].string), 0);
-	sym->flags |= SYMBOL_OPTIONAL;
-	menu_add_entry(sym);
-	printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string));
-}
-
-    break;
-
-  case 32:
-
-    {
-	menu_end_entry();
-	printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
-}
-
-    break;
-
-  case 33:
-
-    {
-	struct symbol *sym = sym_lookup((yyvsp[-1].string), 0);
-	sym->flags |= SYMBOL_OPTIONAL;
-	menu_add_entry(sym);
-	printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string));
-}
-
-    break;
-
-  case 34:
-
-    {
-	if (current_entry->prompt)
-		current_entry->prompt->type = P_MENU;
-	else
-		zconfprint("warning: menuconfig statement without prompt");
-	menu_end_entry();
-	printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
-}
-
-    break;
-
-  case 42:
-
-    {
-	menu_set_type((yyvsp[-2].id)->stype);
-	printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
-		zconf_curname(), zconf_lineno(),
-		(yyvsp[-2].id)->stype);
-}
-
-    break;
-
-  case 43:
-
-    {
-	menu_add_prompt(P_PROMPT, (yyvsp[-2].string), (yyvsp[-1].expr));
-	printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
-}
-
-    break;
-
-  case 44:
-
-    {
-	menu_add_expr(P_DEFAULT, (yyvsp[-2].expr), (yyvsp[-1].expr));
-	if ((yyvsp[-3].id)->stype != S_UNKNOWN)
-		menu_set_type((yyvsp[-3].id)->stype);
-	printd(DEBUG_PARSE, "%s:%d:default(%u)\n",
-		zconf_curname(), zconf_lineno(),
-		(yyvsp[-3].id)->stype);
-}
-
-    break;
-
-  case 45:
-
-    {
-	menu_add_symbol(P_SELECT, sym_lookup((yyvsp[-2].string), 0), (yyvsp[-1].expr));
-	printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
-}
-
-    break;
-
-  case 46:
-
-    {
-	menu_add_symbol(P_IMPLY, sym_lookup((yyvsp[-2].string), 0), (yyvsp[-1].expr));
-	printd(DEBUG_PARSE, "%s:%d:imply\n", zconf_curname(), zconf_lineno());
-}
-
-    break;
-
-  case 47:
-
-    {
-	menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,(yyvsp[-3].symbol), (yyvsp[-2].symbol)), (yyvsp[-1].expr));
-	printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno());
-}
-
-    break;
-
-  case 50:
-
-    {
-	const struct kconf_id *id = kconf_id_lookup((yyvsp[-1].string), strlen((yyvsp[-1].string)));
-	if (id && id->flags & TF_OPTION)
-		menu_add_option(id->token, (yyvsp[0].string));
-	else
-		zconfprint("warning: ignoring unknown option %s", (yyvsp[-1].string));
-	free((yyvsp[-1].string));
-}
-
-    break;
-
-  case 51:
-
-    { (yyval.string) = NULL; }
-
-    break;
-
-  case 52:
-
-    { (yyval.string) = (yyvsp[0].string); }
-
-    break;
-
-  case 53:
-
-    {
-	struct symbol *sym = sym_lookup((yyvsp[-1].string), SYMBOL_CHOICE);
-	sym->flags |= SYMBOL_AUTO;
-	menu_add_entry(sym);
-	menu_add_expr(P_CHOICE, NULL, NULL);
-	printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
-}
-
-    break;
-
-  case 54:
-
-    {
-	(yyval.menu) = menu_add_menu();
-}
-
-    break;
-
-  case 55:
-
-    {
-	if (zconf_endtoken((yyvsp[0].id), T_CHOICE, T_ENDCHOICE)) {
-		menu_end_menu();
-		printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno());
-	}
-}
-
-    break;
-
-  case 63:
-
-    {
-	menu_add_prompt(P_PROMPT, (yyvsp[-2].string), (yyvsp[-1].expr));
-	printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
-}
-
-    break;
-
-  case 64:
-
-    {
-	if ((yyvsp[-2].id)->stype == S_BOOLEAN || (yyvsp[-2].id)->stype == S_TRISTATE) {
-		menu_set_type((yyvsp[-2].id)->stype);
-		printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
-			zconf_curname(), zconf_lineno(),
-			(yyvsp[-2].id)->stype);
-	} else
-		YYERROR;
-}
-
-    break;
-
-  case 65:
-
-    {
-	current_entry->sym->flags |= SYMBOL_OPTIONAL;
-	printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno());
-}
-
-    break;
-
-  case 66:
-
-    {
-	if ((yyvsp[-3].id)->stype == S_UNKNOWN) {
-		menu_add_symbol(P_DEFAULT, sym_lookup((yyvsp[-2].string), 0), (yyvsp[-1].expr));
-		printd(DEBUG_PARSE, "%s:%d:default\n",
-			zconf_curname(), zconf_lineno());
-	} else
-		YYERROR;
-}
-
-    break;
-
-  case 69:
-
-    {
-	printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
-	menu_add_entry(NULL);
-	menu_add_dep((yyvsp[-1].expr));
-	(yyval.menu) = menu_add_menu();
-}
-
-    break;
-
-  case 70:
-
-    {
-	if (zconf_endtoken((yyvsp[0].id), T_IF, T_ENDIF)) {
-		menu_end_menu();
-		printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno());
-	}
-}
-
-    break;
-
-  case 76:
-
-    {
-	menu_add_prompt(P_MENU, (yyvsp[-1].string), NULL);
-}
-
-    break;
-
-  case 77:
-
-    {
-	menu_add_entry(NULL);
-	menu_add_prompt(P_MENU, (yyvsp[-1].string), NULL);
-	printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
-}
-
-    break;
-
-  case 78:
-
-    {
-	(yyval.menu) = menu_add_menu();
-}
-
-    break;
-
-  case 79:
-
-    {
-	if (zconf_endtoken((yyvsp[0].id), T_MENU, T_ENDMENU)) {
-		menu_end_menu();
-		printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno());
-	}
-}
-
-    break;
-
-  case 85:
-
-    {
-	printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string));
-	zconf_nextfile((yyvsp[-1].string));
-}
-
-    break;
-
-  case 86:
-
-    {
-	menu_add_entry(NULL);
-	menu_add_prompt(P_COMMENT, (yyvsp[-1].string), NULL);
-	printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
-}
-
-    break;
-
-  case 87:
-
-    {
-	menu_end_entry();
-}
-
-    break;
-
-  case 88:
-
-    {
-	printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
-	zconf_starthelp();
-}
-
-    break;
-
-  case 89:
-
-    {
-	current_entry->help = (yyvsp[0].string);
-}
-
-    break;
-
-  case 94:
-
-    {
-	menu_add_dep((yyvsp[-1].expr));
-	printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
-}
-
-    break;
-
-  case 98:
-
-    {
-	menu_add_visibility((yyvsp[0].expr));
-}
-
-    break;
-
-  case 100:
-
-    {
-	menu_add_prompt(P_PROMPT, (yyvsp[-1].string), (yyvsp[0].expr));
-}
-
-    break;
-
-  case 103:
-
-    { (yyval.id) = (yyvsp[-1].id); }
-
-    break;
-
-  case 104:
-
-    { (yyval.id) = (yyvsp[-1].id); }
-
-    break;
-
-  case 105:
-
-    { (yyval.id) = (yyvsp[-1].id); }
-
-    break;
-
-  case 108:
-
-    { (yyval.expr) = NULL; }
-
-    break;
-
-  case 109:
-
-    { (yyval.expr) = (yyvsp[0].expr); }
-
-    break;
-
-  case 110:
-
-    { (yyval.expr) = expr_alloc_symbol((yyvsp[0].symbol)); }
-
-    break;
-
-  case 111:
-
-    { (yyval.expr) = expr_alloc_comp(E_LTH, (yyvsp[-2].symbol), (yyvsp[0].symbol)); }
-
-    break;
-
-  case 112:
-
-    { (yyval.expr) = expr_alloc_comp(E_LEQ, (yyvsp[-2].symbol), (yyvsp[0].symbol)); }
-
-    break;
-
-  case 113:
-
-    { (yyval.expr) = expr_alloc_comp(E_GTH, (yyvsp[-2].symbol), (yyvsp[0].symbol)); }
-
-    break;
-
-  case 114:
-
-    { (yyval.expr) = expr_alloc_comp(E_GEQ, (yyvsp[-2].symbol), (yyvsp[0].symbol)); }
-
-    break;
-
-  case 115:
-
-    { (yyval.expr) = expr_alloc_comp(E_EQUAL, (yyvsp[-2].symbol), (yyvsp[0].symbol)); }
-
-    break;
-
-  case 116:
-
-    { (yyval.expr) = expr_alloc_comp(E_UNEQUAL, (yyvsp[-2].symbol), (yyvsp[0].symbol)); }
-
-    break;
-
-  case 117:
-
-    { (yyval.expr) = (yyvsp[-1].expr); }
-
-    break;
-
-  case 118:
-
-    { (yyval.expr) = expr_alloc_one(E_NOT, (yyvsp[0].expr)); }
-
-    break;
-
-  case 119:
-
-    { (yyval.expr) = expr_alloc_two(E_OR, (yyvsp[-2].expr), (yyvsp[0].expr)); }
-
-    break;
-
-  case 120:
-
-    { (yyval.expr) = expr_alloc_two(E_AND, (yyvsp[-2].expr), (yyvsp[0].expr)); }
-
-    break;
-
-  case 121:
-
-    { (yyval.symbol) = sym_lookup((yyvsp[0].string), 0); free((yyvsp[0].string)); }
-
-    break;
-
-  case 122:
-
-    { (yyval.symbol) = sym_lookup((yyvsp[0].string), SYMBOL_CONST); free((yyvsp[0].string)); }
-
-    break;
-
-  case 123:
-
-    { (yyval.string) = NULL; }
-
-    break;
-
-
-
-      default: break;
-    }
-  /* User semantic actions sometimes alter yychar, and that requires
-     that yytoken be updated with the new translation.  We take the
-     approach of translating immediately before every use of yytoken.
-     One alternative is translating here after every semantic action,
-     but that translation would be missed if the semantic action invokes
-     YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
-     if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an
-     incorrect destructor might then be invoked immediately.  In the
-     case of YYERROR or YYBACKUP, subsequent parser actions might lead
-     to an incorrect destructor call or verbose syntax error message
-     before the lookahead is translated.  */
-  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
-
-  YYPOPSTACK (yylen);
-  yylen = 0;
-  YY_STACK_PRINT (yyss, yyssp);
-
-  *++yyvsp = yyval;
-
-  /* Now 'shift' the result of the reduction.  Determine what state
-     that goes to, based on the state we popped back to and the rule
-     number reduced by.  */
-
-  yyn = yyr1[yyn];
-
-  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
-  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
-    yystate = yytable[yystate];
-  else
-    yystate = yydefgoto[yyn - YYNTOKENS];
-
-  goto yynewstate;
-
-
-/*--------------------------------------.
-| yyerrlab -- here on detecting error.  |
-`--------------------------------------*/
-yyerrlab:
-  /* Make sure we have latest lookahead translation.  See comments at
-     user semantic actions for why this is necessary.  */
-  yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
-
-  /* If not already recovering from an error, report this error.  */
-  if (!yyerrstatus)
-    {
-      ++yynerrs;
-#if ! YYERROR_VERBOSE
-      yyerror (YY_("syntax error"));
-#else
-# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
-                                        yyssp, yytoken)
-      {
-        char const *yymsgp = YY_("syntax error");
-        int yysyntax_error_status;
-        yysyntax_error_status = YYSYNTAX_ERROR;
-        if (yysyntax_error_status == 0)
-          yymsgp = yymsg;
-        else if (yysyntax_error_status == 1)
-          {
-            if (yymsg != yymsgbuf)
-              YYSTACK_FREE (yymsg);
-            yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
-            if (!yymsg)
-              {
-                yymsg = yymsgbuf;
-                yymsg_alloc = sizeof yymsgbuf;
-                yysyntax_error_status = 2;
-              }
-            else
-              {
-                yysyntax_error_status = YYSYNTAX_ERROR;
-                yymsgp = yymsg;
-              }
-          }
-        yyerror (yymsgp);
-        if (yysyntax_error_status == 2)
-          goto yyexhaustedlab;
-      }
-# undef YYSYNTAX_ERROR
-#endif
-    }
-
-
-
-  if (yyerrstatus == 3)
-    {
-      /* If just tried and failed to reuse lookahead token after an
-         error, discard it.  */
-
-      if (yychar <= YYEOF)
-        {
-          /* Return failure if at end of input.  */
-          if (yychar == YYEOF)
-            YYABORT;
-        }
-      else
-        {
-          yydestruct ("Error: discarding",
-                      yytoken, &yylval);
-          yychar = YYEMPTY;
-        }
-    }
-
-  /* Else will try to reuse lookahead token after shifting the error
-     token.  */
-  goto yyerrlab1;
-
-
-/*---------------------------------------------------.
-| yyerrorlab -- error raised explicitly by YYERROR.  |
-`---------------------------------------------------*/
-yyerrorlab:
-
-  /* Pacify compilers like GCC when the user code never invokes
-     YYERROR and the label yyerrorlab therefore never appears in user
-     code.  */
-  if (/*CONSTCOND*/ 0)
-     goto yyerrorlab;
-
-  /* Do not reclaim the symbols of the rule whose action triggered
-     this YYERROR.  */
-  YYPOPSTACK (yylen);
-  yylen = 0;
-  YY_STACK_PRINT (yyss, yyssp);
-  yystate = *yyssp;
-  goto yyerrlab1;
-
-
-/*-------------------------------------------------------------.
-| yyerrlab1 -- common code for both syntax error and YYERROR.  |
-`-------------------------------------------------------------*/
-yyerrlab1:
-  yyerrstatus = 3;      /* Each real token shifted decrements this.  */
-
-  for (;;)
-    {
-      yyn = yypact[yystate];
-      if (!yypact_value_is_default (yyn))
-        {
-          yyn += YYTERROR;
-          if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
-            {
-              yyn = yytable[yyn];
-              if (0 < yyn)
-                break;
-            }
-        }
-
-      /* Pop the current state because it cannot handle the error token.  */
-      if (yyssp == yyss)
-        YYABORT;
-
-
-      yydestruct ("Error: popping",
-                  yystos[yystate], yyvsp);
-      YYPOPSTACK (1);
-      yystate = *yyssp;
-      YY_STACK_PRINT (yyss, yyssp);
-    }
-
-  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
-  *++yyvsp = yylval;
-  YY_IGNORE_MAYBE_UNINITIALIZED_END
-
-
-  /* Shift the error token.  */
-  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
-
-  yystate = yyn;
-  goto yynewstate;
-
-
-/*-------------------------------------.
-| yyacceptlab -- YYACCEPT comes here.  |
-`-------------------------------------*/
-yyacceptlab:
-  yyresult = 0;
-  goto yyreturn;
-
-/*-----------------------------------.
-| yyabortlab -- YYABORT comes here.  |
-`-----------------------------------*/
-yyabortlab:
-  yyresult = 1;
-  goto yyreturn;
-
-#if !defined yyoverflow || YYERROR_VERBOSE
-/*-------------------------------------------------.
-| yyexhaustedlab -- memory exhaustion comes here.  |
-`-------------------------------------------------*/
-yyexhaustedlab:
-  yyerror (YY_("memory exhausted"));
-  yyresult = 2;
-  /* Fall through.  */
-#endif
-
-yyreturn:
-  if (yychar != YYEMPTY)
-    {
-      /* Make sure we have latest lookahead translation.  See comments at
-         user semantic actions for why this is necessary.  */
-      yytoken = YYTRANSLATE (yychar);
-      yydestruct ("Cleanup: discarding lookahead",
-                  yytoken, &yylval);
-    }
-  /* Do not reclaim the symbols of the rule whose action triggered
-     this YYABORT or YYACCEPT.  */
-  YYPOPSTACK (yylen);
-  YY_STACK_PRINT (yyss, yyssp);
-  while (yyssp != yyss)
-    {
-      yydestruct ("Cleanup: popping",
-                  yystos[*yyssp], yyvsp);
-      YYPOPSTACK (1);
-    }
-#ifndef yyoverflow
-  if (yyss != yyssa)
-    YYSTACK_FREE (yyss);
-#endif
-#if YYERROR_VERBOSE
-  if (yymsg != yymsgbuf)
-    YYSTACK_FREE (yymsg);
-#endif
-  return yyresult;
-}
-
-
-
-void conf_parse(const char *name)
-{
-	struct symbol *sym;
-	int i;
-
-	zconf_initscan(name);
-
-	sym_init();
-	_menu_init();
-	rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL);
-
-	if (getenv("ZCONF_DEBUG"))
-		zconfdebug = 1;
-	zconfparse();
-	if (zconfnerrs)
-		exit(1);
-	if (!modules_sym)
-		modules_sym = sym_find( "n" );
-
-	rootmenu.prompt->text = _(rootmenu.prompt->text);
-	rootmenu.prompt->text = sym_expand_string_value(rootmenu.prompt->text);
-
-	menu_finalize(&rootmenu);
-	for_all_symbols(i, sym) {
-		if (sym_check_deps(sym))
-			zconfnerrs++;
-	}
-	if (zconfnerrs)
-		exit(1);
-	sym_set_change_count(1);
-}
-
-static const char *zconf_tokenname(int token)
-{
-	switch (token) {
-	case T_MENU:		return "menu";
-	case T_ENDMENU:		return "endmenu";
-	case T_CHOICE:		return "choice";
-	case T_ENDCHOICE:	return "endchoice";
-	case T_IF:		return "if";
-	case T_ENDIF:		return "endif";
-	case T_DEPENDS:		return "depends";
-	case T_VISIBLE:		return "visible";
-	}
-	return "<token>";
-}
-
-static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtoken)
-{
-	if (id->token != endtoken) {
-		zconf_error("unexpected '%s' within %s block",
-			kconf_id_strings + id->name, zconf_tokenname(starttoken));
-		zconfnerrs++;
-		return false;
-	}
-	if (current_menu->file != current_file) {
-		zconf_error("'%s' in different file than '%s'",
-			kconf_id_strings + id->name, zconf_tokenname(starttoken));
-		fprintf(stderr, "%s:%d: location of the '%s'\n",
-			current_menu->file->name, current_menu->lineno,
-			zconf_tokenname(starttoken));
-		zconfnerrs++;
-		return false;
-	}
-	return true;
-}
-
-static void zconfprint(const char *err, ...)
-{
-	va_list ap;
-
-	fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
-	va_start(ap, err);
-	vfprintf(stderr, err, ap);
-	va_end(ap);
-	fprintf(stderr, "\n");
-}
-
-static void zconf_error(const char *err, ...)
-{
-	va_list ap;
-
-	zconfnerrs++;
-	fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
-	va_start(ap, err);
-	vfprintf(stderr, err, ap);
-	va_end(ap);
-	fprintf(stderr, "\n");
-}
-
-static void zconferror(const char *err)
-{
-	fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
-}
-
-static void print_quoted_string(FILE *out, const char *str)
-{
-	const char *p;
-	int len;
-
-	putc('"', out);
-	while ((p = strchr(str, '"'))) {
-		len = p - str;
-		if (len)
-			fprintf(out, "%.*s", len, str);
-		fputs("\\\"", out);
-		str = p + 1;
-	}
-	fputs(str, out);
-	putc('"', out);
-}
-
-static void print_symbol(FILE *out, struct menu *menu)
-{
-	struct symbol *sym = menu->sym;
-	struct property *prop;
-
-	if (sym_is_choice(sym))
-		fprintf(out, "\nchoice\n");
-	else
-		fprintf(out, "\nconfig %s\n", sym->name);
-	switch (sym->type) {
-	case S_BOOLEAN:
-		fputs("  boolean\n", out);
-		break;
-	case S_TRISTATE:
-		fputs("  tristate\n", out);
-		break;
-	case S_STRING:
-		fputs("  string\n", out);
-		break;
-	case S_INT:
-		fputs("  integer\n", out);
-		break;
-	case S_HEX:
-		fputs("  hex\n", out);
-		break;
-	default:
-		fputs("  ???\n", out);
-		break;
-	}
-	for (prop = sym->prop; prop; prop = prop->next) {
-		if (prop->menu != menu)
-			continue;
-		switch (prop->type) {
-		case P_PROMPT:
-			fputs("  prompt ", out);
-			print_quoted_string(out, prop->text);
-			if (!expr_is_yes(prop->visible.expr)) {
-				fputs(" if ", out);
-				expr_fprint(prop->visible.expr, out);
-			}
-			fputc('\n', out);
-			break;
-		case P_DEFAULT:
-			fputs( "  default ", out);
-			expr_fprint(prop->expr, out);
-			if (!expr_is_yes(prop->visible.expr)) {
-				fputs(" if ", out);
-				expr_fprint(prop->visible.expr, out);
-			}
-			fputc('\n', out);
-			break;
-		case P_CHOICE:
-			fputs("  #choice value\n", out);
-			break;
-		case P_SELECT:
-			fputs( "  select ", out);
-			expr_fprint(prop->expr, out);
-			fputc('\n', out);
-			break;
-		case P_IMPLY:
-			fputs( "  imply ", out);
-			expr_fprint(prop->expr, out);
-			fputc('\n', out);
-			break;
-		case P_RANGE:
-			fputs( "  range ", out);
-			expr_fprint(prop->expr, out);
-			fputc('\n', out);
-			break;
-		case P_MENU:
-			fputs( "  menu ", out);
-			print_quoted_string(out, prop->text);
-			fputc('\n', out);
-			break;
-		default:
-			fprintf(out, "  unknown prop %d!\n", prop->type);
-			break;
-		}
-	}
-	if (menu->help) {
-		int len = strlen(menu->help);
-		while (menu->help[--len] == '\n')
-			menu->help[len] = 0;
-		fprintf(out, "  help\n%s\n", menu->help);
-	}
-}
-
-void zconfdump(FILE *out)
-{
-	struct property *prop;
-	struct symbol *sym;
-	struct menu *menu;
-
-	menu = rootmenu.list;
-	while (menu) {
-		if ((sym = menu->sym))
-			print_symbol(out, menu);
-		else if ((prop = menu->prompt)) {
-			switch (prop->type) {
-			case P_COMMENT:
-				fputs("\ncomment ", out);
-				print_quoted_string(out, prop->text);
-				fputs("\n", out);
-				break;
-			case P_MENU:
-				fputs("\nmenu ", out);
-				print_quoted_string(out, prop->text);
-				fputs("\n", out);
-				break;
-			default:
-				;
-			}
-			if (!expr_is_yes(prop->visible.expr)) {
-				fputs("  depends ", out);
-				expr_fprint(prop->visible.expr, out);
-				fputc('\n', out);
-			}
-		}
-
-		if (menu->list)
-			menu = menu->list;
-		else if (menu->next)
-			menu = menu->next;
-		else while ((menu = menu->parent)) {
-			if (menu->prompt && menu->prompt->type == P_MENU)
-				fputs("\nendmenu\n", out);
-			if (menu->next) {
-				menu = menu->next;
-				break;
-			}
-		}
-	}
-}
-
-#include "zconf.lex.c"
-#include "util.c"
-#include "confdata.c"
-#include "expr.c"
-#include "symbol.c"
-#include "menu.c"
diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y
index 001305f..ad6305b 100644
--- a/scripts/kconfig/zconf.y
+++ b/scripts/kconfig/zconf.y
@@ -20,10 +20,10 @@
 
 int cdebug = PRINTD;
 
-extern int zconflex(void);
+int yylex(void);
+static void yyerror(const char *err);
 static void zconfprint(const char *err, ...);
 static void zconf_error(const char *err, ...);
-static void zconferror(const char *err);
 static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtoken);
 
 struct symbol *symbol_hash[SYMBOL_HASHSIZE];
@@ -85,6 +85,7 @@
 %nonassoc T_NOT
 
 %type <string> prompt
+%type <symbol> nonconst_symbol
 %type <symbol> symbol
 %type <expr> expr
 %type <expr> if_expr
@@ -101,14 +102,34 @@
 } if_entry menu_entry choice_entry
 
 %{
-/* Include zconf.hash.c here so it can see the token constants. */
-#include "zconf.hash.c"
+/* Include kconf_id.c here so it can see the token constants. */
+#include "kconf_id.c"
 %}
 
 %%
 input: nl start | start;
 
-start: mainmenu_stmt stmt_list | stmt_list;
+start: mainmenu_stmt stmt_list | no_mainmenu_stmt stmt_list;
+
+/* mainmenu entry */
+
+mainmenu_stmt: T_MAINMENU prompt nl
+{
+	menu_add_prompt(P_MENU, $2, NULL);
+};
+
+/* Default main menu, if there's no mainmenu entry */
+
+no_mainmenu_stmt: /* empty */
+{
+	/*
+	 * Hack: Keep the main menu title on the heap so we can safely free it
+	 * later regardless of whether it comes from the 'prompt' in
+	 * mainmenu_stmt or here
+	 */
+	menu_add_prompt(P_MENU, xstrdup("Linux Kernel Configuration"), NULL);
+};
+
 
 stmt_list:
 	  /* empty */
@@ -119,7 +140,7 @@
 	| stmt_list T_WORD error T_EOL	{ zconf_error("unknown statement \"%s\"", $2); }
 	| stmt_list option_name error T_EOL
 {
-	zconf_error("unexpected option \"%s\"", kconf_id_strings + $2->name);
+	zconf_error("unexpected option \"%s\"", $2->name);
 }
 	| stmt_list error T_EOL		{ zconf_error("invalid statement"); }
 ;
@@ -145,26 +166,23 @@
 
 /* config/menuconfig entry */
 
-config_entry_start: T_CONFIG T_WORD T_EOL
+config_entry_start: T_CONFIG nonconst_symbol T_EOL
 {
-	struct symbol *sym = sym_lookup($2, 0);
-	sym->flags |= SYMBOL_OPTIONAL;
-	menu_add_entry(sym);
-	printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2);
+	$2->flags |= SYMBOL_OPTIONAL;
+	menu_add_entry($2);
+	printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2->name);
 };
 
 config_stmt: config_entry_start config_option_list
 {
-	menu_end_entry();
 	printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
 };
 
-menuconfig_entry_start: T_MENUCONFIG T_WORD T_EOL
+menuconfig_entry_start: T_MENUCONFIG nonconst_symbol T_EOL
 {
-	struct symbol *sym = sym_lookup($2, 0);
-	sym->flags |= SYMBOL_OPTIONAL;
-	menu_add_entry(sym);
-	printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2);
+	$2->flags |= SYMBOL_OPTIONAL;
+	menu_add_entry($2);
+	printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2->name);
 };
 
 menuconfig_stmt: menuconfig_entry_start config_option_list
@@ -173,7 +191,6 @@
 		current_entry->prompt->type = P_MENU;
 	else
 		zconfprint("warning: menuconfig statement without prompt");
-	menu_end_entry();
 	printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
 };
 
@@ -211,15 +228,15 @@
 		$1->stype);
 };
 
-config_option: T_SELECT T_WORD if_expr T_EOL
+config_option: T_SELECT nonconst_symbol if_expr T_EOL
 {
-	menu_add_symbol(P_SELECT, sym_lookup($2, 0), $3);
+	menu_add_symbol(P_SELECT, $2, $3);
 	printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
 };
 
-config_option: T_IMPLY T_WORD if_expr T_EOL
+config_option: T_IMPLY nonconst_symbol if_expr T_EOL
 {
-	menu_add_symbol(P_IMPLY, sym_lookup($2, 0), $3);
+	menu_add_symbol(P_IMPLY, $2, $3);
 	printd(DEBUG_PARSE, "%s:%d:imply\n", zconf_curname(), zconf_lineno());
 };
 
@@ -237,8 +254,10 @@
 	| symbol_option_list T_WORD symbol_option_arg
 {
 	const struct kconf_id *id = kconf_id_lookup($2, strlen($2));
-	if (id && id->flags & TF_OPTION)
+	if (id && id->flags & TF_OPTION) {
 		menu_add_option(id->token, $3);
+		free($3);
+	}
 	else
 		zconfprint("warning: ignoring unknown option %s", $2);
 	free($2);
@@ -257,6 +276,7 @@
 	sym->flags |= SYMBOL_AUTO;
 	menu_add_entry(sym);
 	menu_add_expr(P_CHOICE, NULL, NULL);
+	free($2);
 	printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
 };
 
@@ -308,10 +328,10 @@
 	printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno());
 };
 
-choice_option: T_DEFAULT T_WORD if_expr T_EOL
+choice_option: T_DEFAULT nonconst_symbol if_expr T_EOL
 {
 	if ($1->stype == S_UNKNOWN) {
-		menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3);
+		menu_add_symbol(P_DEFAULT, $2, $3);
 		printd(DEBUG_PARSE, "%s:%d:default\n",
 			zconf_curname(), zconf_lineno());
 	} else
@@ -351,13 +371,6 @@
 	| if_block choice_stmt
 ;
 
-/* mainmenu entry */
-
-mainmenu_stmt: T_MAINMENU prompt nl
-{
-	menu_add_prompt(P_MENU, $2, NULL);
-};
-
 /* menu entry */
 
 menu: T_MENU prompt T_EOL
@@ -394,6 +407,7 @@
 {
 	printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2);
 	zconf_nextfile($2);
+	free($2);
 };
 
 /* comment entry */
@@ -406,9 +420,7 @@
 };
 
 comment_stmt: comment depends_list
-{
-	menu_end_entry();
-};
+;
 
 /* help option */
 
@@ -420,6 +432,17 @@
 
 help: help_start T_HELPTEXT
 {
+	if (current_entry->help) {
+		free(current_entry->help);
+		zconfprint("warning: '%s' defined with more than one help text -- only the last one will be used",
+			   current_entry->sym->name ?: "<choice>");
+	}
+
+	/* Is the help text empty or all whitespace? */
+	if ($2[strspn($2, " \f\n\r\t\v")] == '\0')
+		zconfprint("warning: '%s' defined with blank help text",
+			   current_entry->sym->name ?: "<choice>");
+
 	current_entry->help = $2;
 };
 
@@ -491,7 +514,10 @@
 	| expr T_AND expr			{ $$ = expr_alloc_two(E_AND, $1, $3); }
 ;
 
-symbol:	  T_WORD	{ $$ = sym_lookup($1, 0); free($1); }
+/* For symbol definitions, selects, etc., where quotes are not accepted */
+nonconst_symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); };
+
+symbol:	  nonconst_symbol
 	| T_WORD_QUOTE	{ $$ = sym_lookup($1, SYMBOL_CONST); free($1); }
 ;
 
@@ -502,6 +528,7 @@
 
 void conf_parse(const char *name)
 {
+	const char *tmp;
 	struct symbol *sym;
 	int i;
 
@@ -509,25 +536,26 @@
 
 	sym_init();
 	_menu_init();
-	rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL);
 
 	if (getenv("ZCONF_DEBUG"))
-		zconfdebug = 1;
-	zconfparse();
-	if (zconfnerrs)
+		yydebug = 1;
+	yyparse();
+	if (yynerrs)
 		exit(1);
 	if (!modules_sym)
 		modules_sym = sym_find( "n" );
 
+	tmp = rootmenu.prompt->text;
 	rootmenu.prompt->text = _(rootmenu.prompt->text);
 	rootmenu.prompt->text = sym_expand_string_value(rootmenu.prompt->text);
+	free((char*)tmp);
 
 	menu_finalize(&rootmenu);
 	for_all_symbols(i, sym) {
 		if (sym_check_deps(sym))
-			zconfnerrs++;
+			yynerrs++;
 	}
-	if (zconfnerrs)
+	if (yynerrs)
 		exit(1);
 	sym_set_change_count(1);
 }
@@ -551,17 +579,17 @@
 {
 	if (id->token != endtoken) {
 		zconf_error("unexpected '%s' within %s block",
-			kconf_id_strings + id->name, zconf_tokenname(starttoken));
-		zconfnerrs++;
+			id->name, zconf_tokenname(starttoken));
+		yynerrs++;
 		return false;
 	}
 	if (current_menu->file != current_file) {
 		zconf_error("'%s' in different file than '%s'",
-			kconf_id_strings + id->name, zconf_tokenname(starttoken));
+			id->name, zconf_tokenname(starttoken));
 		fprintf(stderr, "%s:%d: location of the '%s'\n",
 			current_menu->file->name, current_menu->lineno,
 			zconf_tokenname(starttoken));
-		zconfnerrs++;
+		yynerrs++;
 		return false;
 	}
 	return true;
@@ -582,7 +610,7 @@
 {
 	va_list ap;
 
-	zconfnerrs++;
+	yynerrs++;
 	fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
 	va_start(ap, err);
 	vfprintf(stderr, err, ap);
@@ -590,7 +618,7 @@
 	fprintf(stderr, "\n");
 }
 
-static void zconferror(const char *err)
+static void yyerror(const char *err)
 {
 	fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
 }
@@ -623,7 +651,7 @@
 		fprintf(out, "\nconfig %s\n", sym->name);
 	switch (sym->type) {
 	case S_BOOLEAN:
-		fputs("  boolean\n", out);
+		fputs("  bool\n", out);
 		break;
 	case S_TRISTATE:
 		fputs("  tristate\n", out);
diff --git a/snapshot.commit b/snapshot.commit
deleted file mode 100644
index 8d26309..0000000
--- a/snapshot.commit
+++ /dev/null
@@ -1 +0,0 @@
-$Format:%H  %cD$
diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c
index 8196844..8b72fe4 100644
--- a/test/dm/test-fdt.c
+++ b/test/dm/test-fdt.c
@@ -425,7 +425,7 @@
 };
 
 UCLASS_DRIVER(fdt_dummy) = {
-	.name		= "fdt_dummy",
+	.name		= "fdt-dummy",
 	.id		= UCLASS_TEST_DUMMY,
 	.flags		= DM_UC_FLAG_SEQ_ALIAS,
 };
@@ -461,3 +461,45 @@
 	return 0;
 }
 DM_TEST(dm_test_fdt_translation, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test devfdt_remap_addr_index() */
+static int dm_test_fdt_remap_addr_flat(struct unit_test_state *uts)
+{
+	struct udevice *dev;
+	fdt_addr_t addr;
+	void *paddr;
+
+	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, true, &dev));
+
+	addr = devfdt_get_addr(dev);
+	ut_asserteq(0x8000, addr);
+
+	paddr = map_physmem(addr, 0, MAP_NOCACHE);
+	ut_assertnonnull(paddr);
+	ut_asserteq_ptr(paddr, devfdt_remap_addr(dev));
+
+	return 0;
+}
+DM_TEST(dm_test_fdt_remap_addr_flat,
+	DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT | DM_TESTF_FLAT_TREE);
+
+/* Test dev_remap_addr_index() */
+static int dm_test_fdt_remap_addr_live(struct unit_test_state *uts)
+{
+	struct udevice *dev;
+	fdt_addr_t addr;
+	void *paddr;
+
+	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, true, &dev));
+
+	addr = dev_read_addr(dev);
+	ut_asserteq(0x8000, addr);
+
+	paddr = map_physmem(addr, 0, MAP_NOCACHE);
+	ut_assertnonnull(paddr);
+	ut_asserteq_ptr(paddr, dev_remap_addr(dev));
+
+	return 0;
+}
+DM_TEST(dm_test_fdt_remap_addr_live,
+	DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
diff --git a/test/py/tests/test_log.py b/test/py/tests/test_log.py
index d1c2a36..605275b 100644
--- a/test/py/tests/test_log.py
+++ b/test/py/tests/test_log.py
@@ -12,7 +12,7 @@
 
 LOGL_FIRST, LOGL_WARNING, LOGL_INFO = (0, 4, 6)
 
-@pytest.mark.buildconfigspec('log')
+@pytest.mark.buildconfigspec('cmd_log')
 def test_log(u_boot_console):
     """Test that U-Boot logging works correctly."""
     def check_log_entries(lines, mask, max_level=LOGL_INFO):
@@ -98,7 +98,7 @@
     test8()
     test9()
 
-@pytest.mark.buildconfigspec('log')
+@pytest.mark.buildconfigspec('cmd_log')
 def test_log_format(u_boot_console):
     """Test the 'log format' and 'log rec' commands"""
     def run_with_format(fmt, expected_output):
diff --git a/test/py/tests/test_tpm2.py b/test/py/tests/test_tpm2.py
new file mode 100644
index 0000000..01ffb31
--- /dev/null
+++ b/test/py/tests/test_tpm2.py
@@ -0,0 +1,233 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright (c) 2018, Bootlin
+# Author: Miquel Raynal <miquel.raynal@bootlin.com>
+
+import os.path
+import pytest
+import u_boot_utils
+import re
+import time
+
+"""
+Test the TPMv2.x related commands. You must have a working hardware setup in
+order to do these tests.
+
+Notes:
+* These tests will prove the password mechanism. The TPM chip must be cleared of
+any password.
+* Commands like pcr_setauthpolicy and pcr_resetauthpolicy are not implemented
+here because they would fail the tests in most cases (TPMs do not implement them
+and return an error).
+"""
+
+updates = 0
+
+def force_init(u_boot_console, force=False):
+    """When a test fails, U-Boot is reset. Because TPM stack must be initialized
+    after each reboot, we must ensure these lines are always executed before
+    trying any command or they will fail with no reason. Executing 'tpm init'
+    twice will spawn an error used to detect that the TPM was not reset and no
+    initialization code should be run.
+    """
+    output = u_boot_console.run_command('tpm init')
+    if force or not 'Error' in output:
+        u_boot_console.run_command('echo --- start of init ---')
+        u_boot_console.run_command('tpm startup TPM2_SU_CLEAR')
+        u_boot_console.run_command('tpm self_test full')
+        u_boot_console.run_command('tpm clear TPM2_RH_LOCKOUT')
+        output = u_boot_console.run_command('echo $?')
+        if not output.endswith('0'):
+            u_boot_console.run_command('tpm clear TPM2_RH_PLATFORM')
+        u_boot_console.run_command('echo --- end of init ---')
+
+@pytest.mark.buildconfigspec('cmd_tpm_v2')
+def test_tpm2_init(u_boot_console):
+    """Init the software stack to use TPMv2 commands."""
+
+    u_boot_console.run_command('tpm init')
+    output = u_boot_console.run_command('echo $?')
+    assert output.endswith('0')
+
+@pytest.mark.buildconfigspec('cmd_tpm_v2')
+def test_tpm2_startup(u_boot_console):
+    """Execute a TPM2_Startup command.
+
+    Initiate the TPM internal state machine.
+    """
+
+    u_boot_console.run_command('tpm startup TPM2_SU_CLEAR')
+    output = u_boot_console.run_command('echo $?')
+    assert output.endswith('0')
+
+@pytest.mark.buildconfigspec('cmd_tpm_v2')
+def test_tpm2_self_test_full(u_boot_console):
+    """Execute a TPM2_SelfTest (full) command.
+
+    Ask the TPM to perform all self tests to also enable full capabilities.
+    """
+
+    u_boot_console.run_command('tpm self_test full')
+    output = u_boot_console.run_command('echo $?')
+    assert output.endswith('0')
+
+@pytest.mark.buildconfigspec('cmd_tpm_v2')
+def test_tpm2_continue_self_test(u_boot_console):
+    """Execute a TPM2_SelfTest (continued) command.
+
+    Ask the TPM to finish its self tests (alternative to the full test) in order
+    to enter a fully operational state.
+    """
+
+    u_boot_console.run_command('tpm self_test continue')
+    output = u_boot_console.run_command('echo $?')
+    assert output.endswith('0')
+
+@pytest.mark.buildconfigspec('cmd_tpm_v2')
+def test_tpm2_clear(u_boot_console):
+    """Execute a TPM2_Clear command.
+
+    Ask the TPM to reset entirely its internal state (including internal
+    configuration, passwords, counters and DAM parameters). This is half of the
+    TAKE_OWNERSHIP command from TPMv1.
+
+    Use the LOCKOUT hierarchy for this. The LOCKOUT/PLATFORM hierarchies must
+    not have a password set, otherwise this test will fail. ENDORSEMENT and
+    PLATFORM hierarchies are also available.
+    """
+
+    u_boot_console.run_command('tpm clear TPM2_RH_LOCKOUT')
+    output = u_boot_console.run_command('echo $?')
+    assert output.endswith('0')
+
+    u_boot_console.run_command('tpm clear TPM2_RH_PLATFORM')
+    output = u_boot_console.run_command('echo $?')
+    assert output.endswith('0')
+
+@pytest.mark.buildconfigspec('cmd_tpm_v2')
+def test_tpm2_change_auth(u_boot_console):
+    """Execute a TPM2_HierarchyChangeAuth command.
+
+    Ask the TPM to change the owner, ie. set a new password: 'unicorn'
+
+    Use the LOCKOUT hierarchy for this. ENDORSEMENT and PLATFORM hierarchies are
+    also available.
+    """
+
+    force_init(u_boot_console)
+
+    u_boot_console.run_command('tpm change_auth TPM2_RH_LOCKOUT unicorn')
+    output = u_boot_console.run_command('echo $?')
+    assert output.endswith('0')
+
+    u_boot_console.run_command('tpm clear TPM2_RH_LOCKOUT unicorn')
+    output = u_boot_console.run_command('echo $?')
+    u_boot_console.run_command('tpm clear TPM2_RH_PLATFORM')
+    assert output.endswith('0')
+
+@pytest.mark.buildconfigspec('cmd_tpm_v2')
+def test_tpm2_get_capability(u_boot_console):
+    """Execute a TPM_GetCapability command.
+
+    Display one capability. In our test case, let's display the default DAM
+    lockout counter that should be 0 since the CLEAR:
+    - TPM_CAP_TPM_PROPERTIES = 0x6
+    - TPM_PT_LOCKOUT_COUNTER (1st parameter) = PTR_VAR + 14
+
+    There is no expected default values because it would depend on the chip
+    used. We can still save them in order to check they have changed later.
+    """
+
+    force_init(u_boot_console)
+    ram = u_boot_utils.find_ram_base(u_boot_console)
+
+    read_cap = u_boot_console.run_command('tpm get_capability 0x6 0x20e 0x200 1') #0x%x 1' % ram)
+    output = u_boot_console.run_command('echo $?')
+    assert output.endswith('0')
+    assert 'Property 0x0000020e: 0x00000000' in read_cap
+
+@pytest.mark.buildconfigspec('cmd_tpm_v2')
+def test_tpm2_dam_parameters(u_boot_console):
+    """Execute a TPM2_DictionaryAttackParameters command.
+
+    Change Dictionary Attack Mitigation (DAM) parameters. Ask the TPM to change:
+    - Max number of failed authentication before lockout: 3
+    - Time before the failure counter is automatically decremented: 10 sec
+    - Time after a lockout failure before it can be attempted again: 0 sec
+
+    For an unknown reason, the DAM parameters must be changed before changing
+    the authentication, otherwise the lockout will be engaged after the first
+    failed authentication attempt.
+    """
+
+    force_init(u_boot_console)
+    ram = u_boot_utils.find_ram_base(u_boot_console)
+
+    # Set the DAM parameters to known values
+    u_boot_console.run_command('tpm dam_parameters 3 10 0')
+    output = u_boot_console.run_command('echo $?')
+    assert output.endswith('0')
+
+    # Check the values have been saved
+    read_cap = u_boot_console.run_command('tpm get_capability 0x6 0x20f 0x%x 3' % ram)
+    output = u_boot_console.run_command('echo $?')
+    assert output.endswith('0')
+    assert 'Property 0x0000020f: 0x00000003' in read_cap
+    assert 'Property 0x00000210: 0x0000000a' in read_cap
+    assert 'Property 0x00000211: 0x00000000' in read_cap
+
+@pytest.mark.buildconfigspec('cmd_tpm_v2')
+def test_tpm2_pcr_read(u_boot_console):
+    """Execute a TPM2_PCR_Read command.
+
+    Perform a PCR read of the 0th PCR. Must be zero.
+    """
+
+    force_init(u_boot_console)
+    ram = u_boot_utils.find_ram_base(u_boot_console) + 1024
+
+    read_pcr = u_boot_console.run_command('tpm pcr_read 0 0x%x' % ram)
+    output = u_boot_console.run_command('echo $?')
+    assert output.endswith('0')
+
+    # Save the number of PCR updates
+    str = re.findall(r'\d+ known updates', read_pcr)[0]
+    global updates
+    updates = int(re.findall(r'\d+', str)[0])
+
+    # Check the output value
+    assert 'PCR #0 content' in read_pcr
+    assert '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' in read_pcr
+
+@pytest.mark.buildconfigspec('cmd_tpm_v2')
+def test_tpm2_pcr_extend(u_boot_console):
+    """Execute a TPM2_PCR_Extend command.
+
+    Perform a PCR extension with a known hash in memory (zeroed since the board
+    must have been rebooted).
+
+    No authentication mechanism is used here, not protecting against packet
+    replay, yet.
+    """
+
+    force_init(u_boot_console)
+    ram = u_boot_utils.find_ram_base(u_boot_console) + 1024
+
+    u_boot_console.run_command('tpm pcr_extend 0 0x%x' % ram)
+    output = u_boot_console.run_command('echo $?')
+    assert output.endswith('0')
+
+    read_pcr = u_boot_console.run_command('tpm pcr_read 0 0x%x' % ram)
+    output = u_boot_console.run_command('echo $?')
+    assert output.endswith('0')
+    assert 'f5 a5 fd 42 d1 6a 20 30 27 98 ef 6e d3 09 97 9b' in read_pcr
+    assert '43 00 3d 23 20 d9 f0 e8 ea 98 31 a9 27 59 fb 4b' in read_pcr
+
+    str = re.findall(r'\d+ known updates', read_pcr)[0]
+    new_updates = int(re.findall(r'\d+', str)[0])
+    assert (updates + 1) == new_updates
+
+@pytest.mark.buildconfigspec('cmd_tpm_v2')
+def test_tpm2_cleanup(u_boot_console):
+    """Ensure the TPM is cleared from password or test related configuration."""
+
+    force_init(u_boot_console, True)
diff --git a/tools/libfdt/fdt_rw.c b/tools/libfdt/fdt_rw.c
index e475084..68fc7c8 100644
--- a/tools/libfdt/fdt_rw.c
+++ b/tools/libfdt/fdt_rw.c
@@ -25,7 +25,7 @@
 		new_prop = (struct fdt_property *)(unsigned long)
 			fdt_get_property_by_offset(new, offset, NULL);
 		str = fdt_string(old, fdt32_to_cpu(old_prop->nameoff));
-		ret = _fdt_find_add_string(new, str);
+		ret = fdt_find_add_string_(new, str);
 		if (ret < 0)
 			return ret;
 		new_prop->nameoff = cpu_to_fdt32(ret);
diff --git a/tools/logos/u-boot_logo.bmp b/tools/logos/u-boot_logo.bmp
new file mode 100644
index 0000000..40245dd
--- /dev/null
+++ b/tools/logos/u-boot_logo.bmp
Binary files differ
diff --git a/tools/logos/u-boot_logo.svg b/tools/logos/u-boot_logo.svg
new file mode 100644
index 0000000..e45ef2e
--- /dev/null
+++ b/tools/logos/u-boot_logo.svg
@@ -0,0 +1,248 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- SPDX-License-Identifier: CC-BY-SA-4.0 -->
+
+<!-- Copyright (c) 2018, Heinrich Schuchardt <xypron.glpk@gmx.de> -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="186"
+   height="186"
+   viewBox="0 0 186 186"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.92.3 (2405546, 2018-03-11)"
+   sodipodi:docname="u-boot_logo.svg"
+   inkscape:export-filename="tools/logos/u-boot_logo.png"
+   inkscape:export-xdpi="41.290001"
+   inkscape:export-ydpi="41.290001">
+  <title
+     id="title30">U-Boot Logo</title>
+  <metadata
+     id="metadata31">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title>U-Boot Logo</dc:title>
+        <cc:license
+           rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+        <dc:creator>
+          <cc:Agent>
+            <dc:title>Heinrich Schuchardt &lt;xypron.glpk@gmx.de&gt;</dc:title>
+          </cc:Agent>
+        </dc:creator>
+        <dc:date>May 21st, 2018</dc:date>
+      </cc:Work>
+      <cc:License
+         rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+        <cc:permits
+           rdf:resource="http://creativecommons.org/ns#Reproduction" />
+        <cc:permits
+           rdf:resource="http://creativecommons.org/ns#Distribution" />
+        <cc:requires
+           rdf:resource="http://creativecommons.org/ns#Notice" />
+        <cc:requires
+           rdf:resource="http://creativecommons.org/ns#Attribution" />
+        <cc:permits
+           rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+        <cc:requires
+           rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+      </cc:License>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs29" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1440"
+     inkscape:window-height="871"
+     id="namedview27"
+     showgrid="false"
+     inkscape:zoom="3"
+     inkscape:cx="93"
+     inkscape:cy="93"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="layer1" />
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,0)">
+    <rect
+       style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0"
+       id="rect31"
+       width="186"
+       height="186"
+       x="0"
+       y="0" />
+    <circle
+       style="fill:#004466;fill-opacity:1;stroke-width:0;stroke:none"
+       id="path835"
+       cx="93"
+       cy="93"
+       r="93" />
+    <path
+       inkscape:connector-curvature="0"
+       style="fill:#ffcc88;fill-opacity:1;stroke:none;stroke-width:0;stroke:none"
+       d="m 116,76 a 20,20 0 0 1 -20,-20 20,20 0 0 1 20,-20 v 11 a 9,9 0 0 0 -9,9 9,9 0 0 0 9,9 z"
+       id="path4136-6-6-1-6-3-5" />
+    <path
+       inkscape:connector-curvature="0"
+       style="fill:#ffcc88;fill-opacity:1;stroke:none;stroke-width:0"
+       d="m 116,66 a 10,10 0 0 1 -10,-10 10,10 0 0 1 10,-10 v 1 a 9,9 0 0 0 -9,9 9,9 0 0 0 9,9 z"
+       id="path4136-6-6-1-6-3-5-1-9" />
+    <ellipse
+       style="fill:#dd9955;fill-opacity:1;stroke:none;stroke-width:0"
+       id="path4136-6-6-1-6-3-5-1-2"
+       cx="116"
+       cy="41.5"
+       rx="4"
+       ry="5.5" />
+    <circle
+       style="fill:#dd9955;fill-opacity:1;stroke:none;stroke-width:0"
+       id="path4352"
+       cx="86"
+       cy="66"
+       r="10" />
+    <circle
+       style="fill:#dd9955;fill-opacity:1;stroke:none;stroke-width:0"
+       id="path4352-1"
+       cx="126"
+       cy="66"
+       r="10" />
+    <rect
+       style="fill:#dd9955;fill-opacity:1;stroke:none;stroke-width:0"
+       id="rect4399"
+       width="39"
+       height="20"
+       x="86.5"
+       y="56" />
+    <rect
+       style="fill:#dd9955;fill-opacity:1;stroke:none;stroke-width:0"
+       id="rect4660"
+       width="60"
+       height="9.5"
+       x="76"
+       y="66.5" />
+    <circle
+       style="fill:#dd9955;fill-opacity:1;stroke:none;stroke-width:0"
+       id="path4549-5"
+       cx="36"
+       cy="81"
+       r="15" />
+    <circle
+       style="fill:#dd9955;fill-opacity:1;stroke:none;stroke-width:0"
+       id="path4549-5-5"
+       cx="36"
+       cy="121"
+       r="15" />
+    <ellipse
+       style="fill:#ffcc88;fill-opacity:1;stroke:#000000;stroke-width:0"
+       id="path4136-6-6"
+       cx="15"
+       cy="91"
+       rx="4"
+       ry="10" />
+    <ellipse
+       style="fill:#ffcc88;fill-opacity:1;stroke:#000000;stroke-width:0"
+       id="path4136-6-6-1"
+       cx="15"
+       cy="111"
+       rx="4"
+       ry="10" />
+    <rect
+       style="fill:#dd9955;fill-opacity:1;stroke:#000000;stroke-width:0"
+       id="rect4213"
+       width="65"
+       height="4"
+       x="11"
+       y="99" />
+    <ellipse
+       style="fill:#ffcc88;fill-opacity:1;stroke:#000000;stroke-width:0"
+       id="path4136"
+       cx="100.5"
+       cy="100.5"
+       rx="74.5"
+       ry="34.5" />
+    <ellipse
+       style="fill:#dd9955;fill-opacity:1;stroke:none;stroke-width:0"
+       id="path4416"
+       cx="70"
+       cy="95.5"
+       rx="15"
+       ry="12.5" />
+    <ellipse
+       style="fill:#ffcc88;fill-opacity:1;stroke:none;stroke-width:0"
+       id="path4416-9"
+       cx="70"
+       cy="95.5"
+       rx="14"
+       ry="11.5" />
+    <ellipse
+       style="fill:#dd9955;fill-opacity:1;stroke:none;stroke-width:0"
+       id="path4416-0"
+       cx="70"
+       cy="95.5"
+       rx="11"
+       ry="8.5" />
+    <ellipse
+       style="fill:#dd9955;fill-opacity:1;stroke:none;stroke-width:0"
+       id="path4416-94"
+       cx="110"
+       cy="95.5"
+       rx="15"
+       ry="12.5" />
+    <ellipse
+       style="fill:#ffcc88;fill-opacity:1;stroke:none;stroke-width:0"
+       id="path4416-9-1"
+       cx="110"
+       cy="95.5"
+       rx="14"
+       ry="11.5" />
+    <ellipse
+       style="fill:#dd9955;fill-opacity:1;stroke:none;stroke-width:0"
+       id="path4416-0-1"
+       cx="110"
+       cy="95.5"
+       rx="11"
+       ry="8.5" />
+    <ellipse
+       style="fill:#dd9955;fill-opacity:1;stroke:none;stroke-width:0"
+       id="path4416-94-2"
+       cx="150"
+       cy="95.5"
+       rx="15"
+       ry="12.5" />
+    <ellipse
+       style="fill:#ffcc88;fill-opacity:1;stroke:none;stroke-width:0"
+       id="path4416-9-1-2"
+       cx="150"
+       cy="95.5"
+       rx="14"
+       ry="11.5" />
+    <ellipse
+       style="fill:#dd9955;fill-opacity:1;stroke:none;stroke-width:0"
+       id="path4416-0-1-9"
+       cx="150"
+       cy="95.5"
+       rx="11"
+       ry="8.5" />
+  </g>
+</svg>