Merge branch 'master' of git://git.denx.de/u-boot-socfpga
diff --git a/Kconfig b/Kconfig
index 8f9ea97..81b4226 100644
--- a/Kconfig
+++ b/Kconfig
@@ -308,6 +308,8 @@
 
 endmenu		# Boot images
 
+source "api/Kconfig"
+
 source "common/Kconfig"
 
 source "cmd/Kconfig"
@@ -325,3 +327,5 @@
 source "lib/Kconfig"
 
 source "test/Kconfig"
+
+source "scripts/Kconfig"
diff --git a/Makefile b/Makefile
index d3222a0..0b1e8a6 100644
--- a/Makefile
+++ b/Makefile
@@ -482,6 +482,13 @@
 # Build targets only - this includes vmlinux, arch specific targets, clean
 # targets and others. In general all targets except *config targets.
 
+# Additional helpers built in scripts/
+# Carefully list dependencies so we do not try to build scripts twice
+# in parallel
+PHONY += scripts
+scripts: scripts_basic include/config/auto.conf
+	$(Q)$(MAKE) $(build)=$(@)
+
 ifeq ($(dot-config),1)
 # Read in config
 -include include/config/auto.conf
@@ -829,6 +836,10 @@
 
 cfg: u-boot.cfg
 
+quiet_cmd_cfgcheck = CFGCHK  $2
+cmd_cfgcheck = $(srctree)/scripts/check-config.sh $2 \
+		$(srctree)/scripts/config_whitelist.txt $(srctree)
+
 all:		$(ALL-y)
 ifeq ($(CONFIG_DM_I2C_COMPAT)$(CONFIG_SANDBOX),y)
 	@echo "===================== WARNING ======================"
@@ -840,8 +851,7 @@
 	@# Check that this build does not use CONFIG options that we do not
 	@# know about unless they are in Kconfig. All the existing CONFIG
 	@# options are whitelisted, so new ones should not be added.
-	$(srctree)/scripts/check-config.sh u-boot.cfg \
-		$(srctree)/scripts/config_whitelist.txt ${srctree} 1>&2
+	$(call cmd,cfgcheck,u-boot.cfg)
 
 PHONY += dtbs
 dtbs: dts/dt.dtb
@@ -883,7 +893,7 @@
 	$(call if_changed,objcopy)
 
 OBJCOPYFLAGS_u-boot-nodtb.bin := -O binary \
-		$(if $(CONFIG_X86_RESET_VECTOR),-R .start16 -R .resetvec)
+		$(if $(CONFIG_X86_16BIT_INIT),-R .start16 -R .resetvec)
 
 binary_size_check: u-boot-nodtb.bin FORCE
 	@file_size=$(shell wc -c u-boot-nodtb.bin | awk '{print $$1}') ; \
@@ -1077,8 +1087,9 @@
 cmd_ldr = $(LD) $(LDFLAGS_$(@F)) \
 	       $(filter-out FORCE,$^) -o $@
 
-u-boot.rom: u-boot-x86-16bit.bin u-boot.bin FORCE \
-		$(if $(CONFIG_HAVE_REFCODE),refcode.bin)
+u-boot.rom: u-boot-x86-16bit.bin u-boot.bin \
+		$(if $(CONFIG_SPL_X86_16BIT_INIT),spl/u-boot-spl.bin) \
+		$(if $(CONFIG_HAVE_REFCODE),refcode.bin) FORCE
 	$(call if_changed,binman)
 
 OBJCOPYFLAGS_u-boot-x86-16bit.bin := -O binary -j .start16 -j .resetvec
@@ -1417,7 +1428,7 @@
 	       $(foreach d, spl tpl, $(patsubst %,$d/%, \
 			$(filter-out include, $(shell ls -1 $d 2>/dev/null))))
 
-CLEAN_FILES += include/bmp_logo.h include/bmp_logo_data.h include/license.h \
+CLEAN_FILES += include/bmp_logo.h include/bmp_logo_data.h \
 	       boot* u-boot* MLO* SPL System.map
 
 # Directories & files removed with 'make mrproper'
@@ -1538,11 +1549,6 @@
 	$(Q)$(MAKE) $(build)=scripts build_docproc
 	$(Q)$(MAKE) $(build)=doc/DocBook $@
 
-# Dummies...
-PHONY += prepare scripts
-prepare: ;
-scripts: ;
-
 endif #ifeq ($(config-targets),1)
 endif #ifeq ($(mixed-targets),1)
 
diff --git a/README b/README
index ecb1710..a3d3ecc 100644
--- a/README
+++ b/README
@@ -1771,12 +1771,6 @@
 		can be displayed via the splashscreen support or the
 		bmp command.
 
-- Do compressing for memory range:
-		CONFIG_CMD_ZIP
-
-		If this option is set, it would use zlib deflate method
-		to compress the specified memory at its best effort.
-
 - Compression support:
 		CONFIG_GZIP
 
diff --git a/api/Kconfig b/api/Kconfig
new file mode 100644
index 0000000..16731d3
--- /dev/null
+++ b/api/Kconfig
@@ -0,0 +1,9 @@
+menu "API"
+
+config API
+	bool "Enable U-Boot API"
+	default n
+	help
+	  This option enables the U-Boot API. See api/README for more information.
+
+endmenu
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 397a0ae..2d75f64 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -320,10 +320,10 @@
 
 dtb-$(CONFIG_MX7) += imx7-colibri.dtb
 
-dtb-$(CONFIG_SOC_KEYSTONE) += k2hk-evm.dtb \
-	k2l-evm.dtb \
-	k2e-evm.dtb \
-	k2g-evm.dtb
+dtb-$(CONFIG_SOC_KEYSTONE) += keystone-k2hk-evm.dtb \
+	keystone-k2l-evm.dtb \
+	keystone-k2e-evm.dtb \
+	keystone-k2g-evm.dtb
 
 dtb-$(CONFIG_TARGET_SAMA5D2_XPLAINED) += \
 	at91-sama5d2_xplained.dtb
diff --git a/arch/arm/dts/k2e-clocks.dtsi b/arch/arm/dts/keystone-k2e-clocks.dtsi
similarity index 100%
rename from arch/arm/dts/k2e-clocks.dtsi
rename to arch/arm/dts/keystone-k2e-clocks.dtsi
diff --git a/arch/arm/dts/k2e-evm.dts b/arch/arm/dts/keystone-k2e-evm.dts
similarity index 98%
rename from arch/arm/dts/k2e-evm.dts
rename to arch/arm/dts/keystone-k2e-evm.dts
index e2c3fb4..3be8b53 100644
--- a/arch/arm/dts/k2e-evm.dts
+++ b/arch/arm/dts/keystone-k2e-evm.dts
@@ -10,7 +10,7 @@
 /dts-v1/;
 
 #include "keystone.dtsi"
-#include "k2e.dtsi"
+#include "keystone-k2e.dtsi"
 
 / {
 	compatible =  "ti,k2e-evm","ti,keystone";
diff --git a/arch/arm/dts/k2e-netcp.dtsi b/arch/arm/dts/keystone-k2e-netcp.dtsi
similarity index 100%
rename from arch/arm/dts/k2e-netcp.dtsi
rename to arch/arm/dts/keystone-k2e-netcp.dtsi
diff --git a/arch/arm/dts/k2e.dtsi b/arch/arm/dts/keystone-k2e.dtsi
similarity index 97%
rename from arch/arm/dts/k2e.dtsi
rename to arch/arm/dts/keystone-k2e.dtsi
index 675fb8e..b5d9061 100644
--- a/arch/arm/dts/k2e.dtsi
+++ b/arch/arm/dts/keystone-k2e.dtsi
@@ -41,7 +41,7 @@
 	};
 
 	soc {
-		/include/ "k2e-clocks.dtsi"
+		/include/ "keystone-k2e-clocks.dtsi"
 
 		usb: usb@2680000 {
 			interrupts = <GIC_SPI 152 IRQ_TYPE_EDGE_RISING>;
@@ -142,6 +142,6 @@
 			clock-names = "fck";
 			bus_freq	= <2500000>;
 		};
-		/include/ "k2e-netcp.dtsi"
+		/include/ "keystone-k2e-netcp.dtsi"
 	};
 };
diff --git a/arch/arm/dts/k2g-evm.dts b/arch/arm/dts/keystone-k2g-evm.dts
similarity index 95%
rename from arch/arm/dts/k2g-evm.dts
rename to arch/arm/dts/keystone-k2g-evm.dts
index 61d0d55..696a0d7 100644
--- a/arch/arm/dts/k2g-evm.dts
+++ b/arch/arm/dts/keystone-k2g-evm.dts
@@ -1,7 +1,7 @@
 /*
  * Copyright 2014 Texas Instruments, Inc.
  *
- * Keystone 2 Galileo EVM device tree
+ * Device Tree Source for K2G EVM
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -9,11 +9,11 @@
  */
 /dts-v1/;
 
-#include "k2g.dtsi"
+#include "keystone-k2g.dtsi"
 
 / {
 	compatible =  "ti,k2g-evm","ti,keystone";
-	model = "Texas Instruments Keystone 2 Galileo EVM";
+	model = "Texas Instruments K2G General Purpose EVM";
 
 	chosen {
 		stdout-path = &uart0;
diff --git a/arch/arm/dts/k2g-netcp.dtsi b/arch/arm/dts/keystone-k2g-netcp.dtsi
similarity index 98%
rename from arch/arm/dts/k2g-netcp.dtsi
rename to arch/arm/dts/keystone-k2g-netcp.dtsi
index 6f0ff86..a9b26c3 100644
--- a/arch/arm/dts/k2g-netcp.dtsi
+++ b/arch/arm/dts/keystone-k2g-netcp.dtsi
@@ -1,5 +1,5 @@
 /*
- * Device Tree Source for Keystone 2 Galileo Netcp driver
+ * Device Tree Source for K2G Netcp driver
  *
  * Copyright 2015 Texas Instruments, Inc.
  *
diff --git a/arch/arm/dts/k2g.dtsi b/arch/arm/dts/keystone-k2g.dtsi
similarity index 97%
rename from arch/arm/dts/k2g.dtsi
rename to arch/arm/dts/keystone-k2g.dtsi
index add03b7..2193f9f 100644
--- a/arch/arm/dts/k2g.dtsi
+++ b/arch/arm/dts/keystone-k2g.dtsi
@@ -1,7 +1,7 @@
 /*
  * Copyright 2014 Texas Instruments, Inc.
  *
- * Keystone 2 Galileo soc device tree
+ * Device Tree Source for K2G SOC
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -12,7 +12,7 @@
 #include "skeleton.dtsi"
 
 / {
-	model = "Texas Instruments Keystone 2 SoC";
+	model = "Texas Instruments K2G SoC";
 	#address-cells = <1>;
 	#size-cells = <1>;
 	interrupt-parent = <&gic>;
@@ -98,7 +98,7 @@
 			status = "disabled";
 		};
 
-		#include "k2g-netcp.dtsi"
+		#include "keystone-k2g-netcp.dtsi"
 
 		pmmc: pmmc@2900000 {
 			compatible = "ti,power-processor";
diff --git a/arch/arm/dts/k2hk-clocks.dtsi b/arch/arm/dts/keystone-k2hk-clocks.dtsi
similarity index 100%
rename from arch/arm/dts/k2hk-clocks.dtsi
rename to arch/arm/dts/keystone-k2hk-clocks.dtsi
diff --git a/arch/arm/dts/k2hk-evm.dts b/arch/arm/dts/keystone-k2hk-evm.dts
similarity index 98%
rename from arch/arm/dts/k2hk-evm.dts
rename to arch/arm/dts/keystone-k2hk-evm.dts
index c5cad2c..76a675f 100644
--- a/arch/arm/dts/k2hk-evm.dts
+++ b/arch/arm/dts/keystone-k2hk-evm.dts
@@ -10,7 +10,7 @@
 /dts-v1/;
 
 #include "keystone.dtsi"
-#include "k2hk.dtsi"
+#include "keystone-k2hk.dtsi"
 
 / {
 	compatible =  "ti,k2hk-evm","ti,keystone";
diff --git a/arch/arm/dts/k2hk-netcp.dtsi b/arch/arm/dts/keystone-k2hk-netcp.dtsi
similarity index 100%
rename from arch/arm/dts/k2hk-netcp.dtsi
rename to arch/arm/dts/keystone-k2hk-netcp.dtsi
diff --git a/arch/arm/dts/k2hk.dtsi b/arch/arm/dts/keystone-k2hk.dtsi
similarity index 96%
rename from arch/arm/dts/k2hk.dtsi
rename to arch/arm/dts/keystone-k2hk.dtsi
index d0810a5..fc78696 100644
--- a/arch/arm/dts/k2hk.dtsi
+++ b/arch/arm/dts/keystone-k2hk.dtsi
@@ -41,7 +41,7 @@
 	};
 
 	soc {
-		/include/ "k2hk-clocks.dtsi"
+		/include/ "keystone-k2hk-clocks.dtsi"
 
 		dspgpio0: keystone_dsp_gpio@02620240 {
 			compatible = "ti,keystone-dsp-gpio";
@@ -109,6 +109,6 @@
 			clock-names = "fck";
 			bus_freq	= <2500000>;
 		};
-		/include/ "k2hk-netcp.dtsi"
+		/include/ "keystone-k2hk-netcp.dtsi"
 	};
 };
diff --git a/arch/arm/dts/k2l-clocks.dtsi b/arch/arm/dts/keystone-k2l-clocks.dtsi
similarity index 100%
rename from arch/arm/dts/k2l-clocks.dtsi
rename to arch/arm/dts/keystone-k2l-clocks.dtsi
diff --git a/arch/arm/dts/k2l-evm.dts b/arch/arm/dts/keystone-k2l-evm.dts
similarity index 98%
rename from arch/arm/dts/k2l-evm.dts
rename to arch/arm/dts/keystone-k2l-evm.dts
index da0661b..b5c5617 100644
--- a/arch/arm/dts/k2l-evm.dts
+++ b/arch/arm/dts/keystone-k2l-evm.dts
@@ -10,7 +10,7 @@
 /dts-v1/;
 
 #include "keystone.dtsi"
-#include "k2l.dtsi"
+#include "keystone-k2l.dtsi"
 
 / {
 	compatible =  "ti,k2l-evm","ti,keystone";
diff --git a/arch/arm/dts/k2l-netcp.dtsi b/arch/arm/dts/keystone-k2l-netcp.dtsi
similarity index 100%
rename from arch/arm/dts/k2l-netcp.dtsi
rename to arch/arm/dts/keystone-k2l-netcp.dtsi
diff --git a/arch/arm/dts/k2l.dtsi b/arch/arm/dts/keystone-k2l.dtsi
similarity index 96%
rename from arch/arm/dts/k2l.dtsi
rename to arch/arm/dts/keystone-k2l.dtsi
index 49fd414..d681cab 100644
--- a/arch/arm/dts/k2l.dtsi
+++ b/arch/arm/dts/keystone-k2l.dtsi
@@ -29,7 +29,7 @@
 	};
 
 	soc {
-		/include/ "k2l-clocks.dtsi"
+		/include/ "keystone-k2l-clocks.dtsi"
 
 		uart2: serial@02348400 {
 			compatible = "ns16550a";
@@ -89,7 +89,7 @@
 			clock-names = "fck";
 			bus_freq	= <2500000>;
 		};
-		/include/ "k2l-netcp.dtsi"
+		/include/ "keystone-k2l-netcp.dtsi"
 	};
 };
 
diff --git a/arch/arm/lib/crt0_64.S b/arch/arm/lib/crt0_64.S
index 91b19e0..19c6a98 100644
--- a/arch/arm/lib/crt0_64.S
+++ b/arch/arm/lib/crt0_64.S
@@ -117,10 +117,8 @@
  */
 	ldr	x0, =__bss_start		/* this is auto-relocated! */
 	ldr	x1, =__bss_end			/* this is auto-relocated! */
-	mov	x2, #0
 clear_loop:
-	str	x2, [x0]
-	add	x0, x0, #8
+	str	xzr, [x0], #8
 	cmp	x0, x1
 	b.lo	clear_loop
 
diff --git a/arch/arm/lib/relocate_64.S b/arch/arm/lib/relocate_64.S
index 242e56e..c760053 100644
--- a/arch/arm/lib/relocate_64.S
+++ b/arch/arm/lib/relocate_64.S
@@ -68,7 +68,7 @@
 	b	0f
 1:	mrs	x0, sctlr_el1
 0:	tbz	w0, #2, 5f	/* skip flushing cache if disabled */
-	tbz	w0, #12, 4f	/* invalide i-cache is enabled */
+	tbz	w0, #12, 4f	/* skip invalidating i-cache if disabled */
 	ic	iallu		/* i-cache invalidate all */
 	isb	sy
 4:	ldp	x0, x1, [sp, #16]
diff --git a/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c b/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c
index ace1028..cb6e03f 100644
--- a/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c
+++ b/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c
@@ -392,7 +392,7 @@
 	priv->regs = regmap_get_range(map, 0);
 	priv->phy = regmap_get_range(map, 1);
 
-	priv->clock_rate = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+	priv->clock_rate = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 					  "clock-frequency", 0);
 
 	if (!priv->clock_rate) {
diff --git a/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c b/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c
index be3d713..89fd8e6 100644
--- a/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c
+++ b/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c
@@ -1016,7 +1016,7 @@
 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
 	struct rk3288_sdram_params *params = dev_get_platdata(dev);
 	const void *blob = gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	int ret;
 
 	/* Rk3288 supports dual-channel, set default channel num to 2 */
diff --git a/arch/arm/mach-uniphier/Kconfig b/arch/arm/mach-uniphier/Kconfig
index cd9ba6b..5739325 100644
--- a/arch/arm/mach-uniphier/Kconfig
+++ b/arch/arm/mach-uniphier/Kconfig
@@ -13,6 +13,7 @@
 config ARCH_UNIPHIER_64BIT
 	bool
 	select ARM64
+	select CMD_UNZIP
 	select SPL_SEPARATE_BSS if SPL
 	select ARMV8_MULTIENTRY if SPL
 	select ARMV8_SPIN_TABLE if SPL
diff --git a/arch/nios2/cpu/cpu.c b/arch/nios2/cpu/cpu.c
index 4f0f8fc..c1caa65 100644
--- a/arch/nios2/cpu/cpu.c
+++ b/arch/nios2/cpu/cpu.c
@@ -103,7 +103,7 @@
 static int altera_nios2_probe(struct udevice *dev)
 {
 	const void *blob = gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 
 	gd->cpu_clk = fdtdec_get_int(blob, node,
 		"clock-frequency", 0);
diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts
index e6d336f..2061464 100644
--- a/arch/sandbox/dts/sandbox.dts
+++ b/arch/sandbox/dts/sandbox.dts
@@ -203,6 +203,11 @@
 		stringarray = "one";
 	};
 
+	spl-test4 {
+		u-boot,dm-pre-reloc;
+		compatible = "sandbox,spl-test.2";
+	};
+
 	square {
 		compatible = "demo-shape";
 		colour = "blue";
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 0884af2..5f9597b 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -5,6 +5,52 @@
 	default "x86"
 
 choice
+	prompt "Run U-Boot in 32/64-bit mode"
+	default X86_RUN_32BIT
+	help
+	  U-Boot can be built as a 32-bit binary which runs in 32-bit mode
+	  even on 64-bit machines. In this case SPL is not used, and U-Boot
+	  runs directly from the reset vector (via 16-bit start-up).
+
+	  Alternatively it can be run as a 64-bit binary, thus requiring a
+	  64-bit machine. In this case SPL runs in 32-bit mode (via 16-bit
+	  start-up) then jumps to U-Boot in 64-bit mode.
+
+	  For now, 32-bit mode is recommended, as 64-bit is still
+	  experimental and is missing a lot of features.
+
+config X86_RUN_32BIT
+	bool "32-bit"
+	help
+	  Build U-Boot as a 32-bit binary with no SPL. This is the currently
+	  supported normal setup. U-Boot will stay in 32-bit mode even on
+	  64-bit machines. When booting a 64-bit kernel, U-Boot will switch
+	  to 64-bit just before starting the kernel. Only the bottom 4GB of
+	  memory can be accessed through normal means, although
+	  arch_phys_memset() can be used for basic access to other memory.
+
+config X86_RUN_64BIT
+	bool "64-bit"
+	select X86_64
+	select SUPPORT_SPL
+	select SPL
+	select SPL_SEPARATE_BSS
+	help
+	  Build U-Boot as a 64-bit binary with a 32-bit SPL. This is
+	  experimental and many features are missing. U-Boot SPL starts up,
+	  runs through the 16-bit and 32-bit init, then switches to 64-bit
+	  mode and jumps to U-Boot proper.
+
+endchoice
+
+config X86_64
+	bool
+
+config SPL_X86_64
+	bool
+	depends on SPL
+
+choice
 	prompt "Mainboard vendor"
 	default VENDOR_EMULATION
 
@@ -89,6 +135,46 @@
 	bool
 	default n
 
+# The following options control where the 16-bit and 32-bit init lies
+# If SPL is enabled then it normally holds this init code, and U-Boot proper
+# is normally a 64-bit build.
+#
+# The 16-bit init refers to the reset vector and the small amount of code to
+# get the processor into 32-bit mode. It may be in SPL or in U-Boot proper,
+# or missing altogether if U-Boot is started from EFI or coreboot.
+#
+# The 32-bit init refers to processor init, running binary blobs including
+# FSP, setting up interrupts and anything else that needs to be done in
+# 32-bit code. It is normally in the same place as 16-bit init if that is
+# enabled (i.e. they are both in SPL, or both in U-Boot proper).
+config X86_16BIT_INIT
+	bool
+	depends on X86_RESET_VECTOR
+	default y if X86_RESET_VECTOR && !SPL
+	help
+	  This is enabled when 16-bit init is in U-Boot proper
+
+config SPL_X86_16BIT_INIT
+	bool
+	depends on X86_RESET_VECTOR
+	default y if X86_RESET_VECTOR && SPL
+	help
+	  This is enabled when 16-bit init is in SPL
+
+config X86_32BIT_INIT
+	bool
+	depends on X86_RESET_VECTOR
+	default y if X86_RESET_VECTOR && !SPL
+	help
+	  This is enabled when 32-bit init is in U-Boot proper
+
+config SPL_X86_32BIT_INIT
+	bool
+	depends on X86_RESET_VECTOR
+	default y if X86_RESET_VECTOR && SPL
+	help
+	  This is enabled when 32-bit init is in SPL
+
 config RESET_SEG_START
 	hex
 	depends on X86_RESET_VECTOR
@@ -109,6 +195,14 @@
 	depends on X86_RESET_VECTOR
 	default 0xfffff800
 
+config X86_LOAD_FROM_32_BIT
+	bool "Boot from a 32-bit program"
+	help
+	  Define this to boot U-Boot from a 32-bit program which sets
+	  the GDT differently. This can be used to boot directly from
+	  any stage of coreboot, for example, bypassing the normal
+	  payload-loading feature.
+
 config BOARD_ROMSIZE_KB_512
 	bool
 config BOARD_ROMSIZE_KB_1024
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index d104a49..4be1c35 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -3,12 +3,15 @@
 #
 
 ifeq ($(CONFIG_EFI_APP),)
+ifdef CONFIG_$(SPL_)X86_64
+head-y := arch/x86/cpu/start64.o
+else
 head-y := arch/x86/cpu/start.o
 endif
-ifeq ($(CONFIG_SPL_BUILD),y)
-head-y += arch/x86/cpu/start16.o
-head-y += arch/x86/cpu/resetvec.o
 endif
 
+head-$(CONFIG_$(SPL_)X86_16BIT_INIT) += arch/x86/cpu/start16.o
+head-$(CONFIG_$(SPL_)X86_16BIT_INIT) += arch/x86/cpu/resetvec.o
+
 libs-y += arch/x86/cpu/
 libs-y += arch/x86/lib/
diff --git a/arch/x86/config.mk b/arch/x86/config.mk
index 1697dca..74b87ce 100644
--- a/arch/x86/config.mk
+++ b/arch/x86/config.mk
@@ -15,11 +15,25 @@
 
 PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_X86)
 PLATFORM_CPPFLAGS += -fno-dwarf2-cfi-asm
+
+ifdef CONFIG_SPL_BUILD
+IS_32BIT := y
+else
+ifndef CONFIG_X86_64
+IS_32BIT := y
+endif
+endif
+
+ifeq ($(IS_32BIT),y)
 PLATFORM_CPPFLAGS += -march=i386 -m32
+else
+PLATFORM_CPPFLAGS += $(if $(CONFIG_SPL_BUILD),,-fpic) -fno-common
+endif
 
 PLATFORM_RELFLAGS += -ffunction-sections -fvisibility=hidden
 
-PLATFORM_LDFLAGS += -Bsymbolic -Bsymbolic-functions -m elf_i386
+PLATFORM_LDFLAGS += -Bsymbolic -Bsymbolic-functions
+PLATFORM_LDFLAGS += -m $(if $(IS_32BIT),elf_i386,elf_x86_64)
 
 LDFLAGS_FINAL += --wrap=__divdi3 --wrap=__udivdi3
 LDFLAGS_FINAL += --wrap=__moddi3 --wrap=__umoddi3
@@ -31,7 +45,9 @@
 OBJCOPYFLAGS_EFI := -j .text -j .sdata -j .data -j .dynamic -j .dynsym \
 	-j .rel -j .rela -j .reloc
 
+ifeq ($(IS_32BIT),y)
 CFLAGS_NON_EFI := -mregparm=3
+endif
 CFLAGS_EFI := -fpic -fshort-wchar
 
 ifeq ($(CONFIG_EFI_STUB_64BIT),)
@@ -62,8 +78,18 @@
 
 PLATFORM_CPPFLAGS += $(CFLAGS_NON_EFI)
 PLATFORM_LDFLAGS += --emit-relocs
-LDFLAGS_FINAL += --gc-sections -pie
+LDFLAGS_FINAL += --gc-sections $(if $(CONFIG_SPL_BUILD),,-pie)
+
+endif
 
+ifdef CONFIG_X86_64
+ifndef CONFIG_SPL_BUILD
+PLATFORM_CPPFLAGS += -D__x86_64__
+else
+PLATFORM_CPPFLAGS += -D__I386__
+endif
+else
+PLATFORM_CPPFLAGS += -D__I386__
 endif
 
 ifneq ($(CONFIG_EFI_STUB)$(CONFIG_CMD_BOOTEFI_HELLO_COMPILE),)
diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile
index f5b8c9e..92a9023 100644
--- a/arch/x86/cpu/Makefile
+++ b/arch/x86/cpu/Makefile
@@ -8,15 +8,22 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
+ifeq ($(CONFIG_$(SPL_)X86_64),y)
+extra-y	= start64.o
+else
 extra-y	= start.o
-obj-$(CONFIG_X86_RESET_VECTOR) += resetvec.o start16.o
-obj-y	+= interrupts.o cpu.o cpu_x86.o call64.o setjmp.o
+endif
+extra-$(CONFIG_$(SPL_)X86_16BIT_INIT) += resetvec.o start16.o
 
+obj-y	+= cpu.o cpu_x86.o
+
+ifndef CONFIG_$(SPL_)X86_64
 AFLAGS_REMOVE_call32.o := -mregparm=3 \
 	$(if $(CONFIG_EFI_STUB_64BIT),-march=i386 -m32)
 AFLAGS_call32.o := -fpic -fshort-wchar
 
 extra-y += call32.o
+endif
 
 obj-y += intel_common/
 obj-$(CONFIG_INTEL_BAYTRAIL) += baytrail/
@@ -27,9 +34,20 @@
 obj-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += ivybridge/
 obj-$(CONFIG_INTEL_QUARK) += quark/
 obj-$(CONFIG_INTEL_QUEENSBAY) += queensbay/
-obj-y += irq.o lapic.o ioapic.o
+obj-y += lapic.o ioapic.o
+obj-y += irq.o
+ifndef CONFIG_$(SPL_)X86_64
 obj-$(CONFIG_SMP) += mp_init.o
+endif
 obj-y += mtrr.o
 obj-$(CONFIG_PCI) += pci.o
+ifndef CONFIG_$(SPL_)X86_64
 obj-$(CONFIG_SMP) += sipi_vector.o
+endif
 obj-y += turbo.o
+
+ifeq ($(CONFIG_$(SPL_)X86_64),y)
+obj-y += x86_64/
+else
+obj-y += i386/
+endif
diff --git a/arch/x86/cpu/broadwell/cpu.c b/arch/x86/cpu/broadwell/cpu.c
index 6977e86..1b71d56 100644
--- a/arch/x86/cpu/broadwell/cpu.c
+++ b/arch/x86/cpu/broadwell/cpu.c
@@ -256,8 +256,8 @@
 	/* Set the slow ramp rate */
 	msr.hi &= ~(0x3 << (53 - 32));
 	/* Configure the C-state exit ramp rate */
-	ramp = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "intel,slow-ramp",
-			      -1);
+	ramp = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
+			      "intel,slow-ramp", -1);
 	if (ramp != -1) {
 		/* Configured slow ramp rate */
 		msr.hi |= ((ramp & 0x3) << (53 - 32));
@@ -271,8 +271,8 @@
 	}
 	/* Set MIN_VID (31:24) to allow CPU to have full control */
 	msr.lo &= ~0xff000000;
-	min_vid = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "intel,min-vid",
-				 0);
+	min_vid = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
+				 "intel,min-vid", 0);
 	msr.lo |= (min_vid & 0xff) << 24;
 	msr_write(MSR_VR_MISC_CONFIG, msr);
 
@@ -562,7 +562,7 @@
 	int tcc_offset;
 	msr_t msr;
 
-	tcc_offset = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+	tcc_offset = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 				    "intel,tcc-offset", 0);
 
 	/* Set TCC activaiton offset if supported */
diff --git a/arch/x86/cpu/broadwell/pch.c b/arch/x86/cpu/broadwell/pch.c
index 317f57d..16eac3d 100644
--- a/arch/x86/cpu/broadwell/pch.c
+++ b/arch/x86/cpu/broadwell/pch.c
@@ -190,14 +190,14 @@
 	debug("Set power %s after power failure.\n", state);
 
 	/* GPE setup based on device tree configuration */
-	ret = fdtdec_get_int_array(gd->fdt_blob, dev->of_offset,
+	ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev),
 				   "intel,gpe0-en", enable, ARRAY_SIZE(enable));
 	if (ret)
 		return -EINVAL;
 	enable_all_gpe(enable[0], enable[1], enable[2], enable[3]);
 
 	/* SMI setup based on device tree configuration */
-	enable_alt_smi(dev, fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+	enable_alt_smi(dev, fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 					   "intel,alt-gp-smi-enable", 0));
 
 	return 0;
diff --git a/arch/x86/cpu/broadwell/pinctrl_broadwell.c b/arch/x86/cpu/broadwell/pinctrl_broadwell.c
index 2a3fced..881413f 100644
--- a/arch/x86/cpu/broadwell/pinctrl_broadwell.c
+++ b/arch/x86/cpu/broadwell/pinctrl_broadwell.c
@@ -51,7 +51,7 @@
 	int node;
 
 	debug("%s: starting\n", __func__);
-	for (node = fdt_first_subnode(blob, dev->of_offset);
+	for (node = fdt_first_subnode(blob, dev_of_offset(dev));
 	     node > 0;
 	     node = fdt_next_subnode(blob, node)) {
 		int phandle = fdt_get_phandle(blob, node);
@@ -115,7 +115,7 @@
 	int count = 0;
 	int node;
 
-	for (node = fdt_first_subnode(blob, dev->of_offset);
+	for (node = fdt_first_subnode(blob, dev_of_offset(dev));
 	     node > 0;
 	     node = fdt_next_subnode(blob, node)) {
 		int len, i;
diff --git a/arch/x86/cpu/broadwell/sata.c b/arch/x86/cpu/broadwell/sata.c
index 2e47082..10461d9 100644
--- a/arch/x86/cpu/broadwell/sata.c
+++ b/arch/x86/cpu/broadwell/sata.c
@@ -235,7 +235,7 @@
 {
 	struct sata_platdata *plat = dev_get_platdata(dev);
 	const void *blob = gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 
 	plat->port_map = fdtdec_get_int(blob, node, "intel,sata-port-map", 0);
 	plat->port0_gen3_tx = fdtdec_get_int(blob, node,
diff --git a/arch/x86/cpu/config.mk b/arch/x86/cpu/config.mk
index 1263221..b519f43 100644
--- a/arch/x86/cpu/config.mk
+++ b/arch/x86/cpu/config.mk
@@ -7,11 +7,15 @@
 
 CROSS_COMPILE ?= i386-linux-
 
-PLATFORM_CPPFLAGS += -D__I386__
-
 # DO NOT MODIFY THE FOLLOWING UNLESS YOU REALLY KNOW WHAT YOU ARE DOING!
 LDPPFLAGS += -DRESET_SEG_START=$(CONFIG_RESET_SEG_START)
 LDPPFLAGS += -DRESET_SEG_SIZE=$(CONFIG_RESET_SEG_SIZE)
 LDPPFLAGS += -DRESET_VEC_LOC=$(CONFIG_RESET_VEC_LOC)
 LDPPFLAGS += -DSTART_16=$(CONFIG_SYS_X86_START16)
 LDPPFLAGS += -DRESET_BASE="CONFIG_SYS_TEXT_BASE + (CONFIG_SYS_MONITOR_LEN - RESET_SEG_SIZE)"
+
+ifdef CONFIG_X86_64
+ifndef CONFIG_SPL_BUILD
+LDSCRIPT = $(srctree)/arch/x86/cpu/u-boot-64.lds
+endif
+endif
diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c
index 7c1d6de..8fa6953 100644
--- a/arch/x86/cpu/cpu.c
+++ b/arch/x86/cpu/cpu.c
@@ -43,55 +43,6 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/*
- * Constructor for a conventional segment GDT (or LDT) entry
- * This is a macro so it can be used in initialisers
- */
-#define GDT_ENTRY(flags, base, limit)			\
-	((((base)  & 0xff000000ULL) << (56-24)) |	\
-	 (((flags) & 0x0000f0ffULL) << 40) |		\
-	 (((limit) & 0x000f0000ULL) << (48-16)) |	\
-	 (((base)  & 0x00ffffffULL) << 16) |		\
-	 (((limit) & 0x0000ffffULL)))
-
-struct gdt_ptr {
-	u16 len;
-	u32 ptr;
-} __packed;
-
-struct cpu_device_id {
-	unsigned vendor;
-	unsigned device;
-};
-
-struct cpuinfo_x86 {
-	uint8_t x86;            /* CPU family */
-	uint8_t x86_vendor;     /* CPU vendor */
-	uint8_t x86_model;
-	uint8_t x86_mask;
-};
-
-/*
- * List of cpu vendor strings along with their normalized
- * id values.
- */
-static const struct {
-	int vendor;
-	const char *name;
-} x86_vendors[] = {
-	{ X86_VENDOR_INTEL,     "GenuineIntel", },
-	{ X86_VENDOR_CYRIX,     "CyrixInstead", },
-	{ X86_VENDOR_AMD,       "AuthenticAMD", },
-	{ X86_VENDOR_UMC,       "UMC UMC UMC ", },
-	{ X86_VENDOR_NEXGEN,    "NexGenDriven", },
-	{ X86_VENDOR_CENTAUR,   "CentaurHauls", },
-	{ X86_VENDOR_RISE,      "RiseRiseRise", },
-	{ X86_VENDOR_TRANSMETA, "GenuineTMx86", },
-	{ X86_VENDOR_TRANSMETA, "TransmetaCPU", },
-	{ X86_VENDOR_NSC,       "Geode by NSC", },
-	{ X86_VENDOR_SIS,       "SiS SiS SiS ", },
-};
-
 static const char *const x86_vendor_name[] = {
 	[X86_VENDOR_INTEL]     = "Intel",
 	[X86_VENDOR_CYRIX]     = "Cyrix",
@@ -105,100 +56,6 @@
 	[X86_VENDOR_SIS]       = "SiS",
 };
 
-static void load_ds(u32 segment)
-{
-	asm volatile("movl %0, %%ds" : : "r" (segment * X86_GDT_ENTRY_SIZE));
-}
-
-static void load_es(u32 segment)
-{
-	asm volatile("movl %0, %%es" : : "r" (segment * X86_GDT_ENTRY_SIZE));
-}
-
-static void load_fs(u32 segment)
-{
-	asm volatile("movl %0, %%fs" : : "r" (segment * X86_GDT_ENTRY_SIZE));
-}
-
-static void load_gs(u32 segment)
-{
-	asm volatile("movl %0, %%gs" : : "r" (segment * X86_GDT_ENTRY_SIZE));
-}
-
-static void load_ss(u32 segment)
-{
-	asm volatile("movl %0, %%ss" : : "r" (segment * X86_GDT_ENTRY_SIZE));
-}
-
-static void load_gdt(const u64 *boot_gdt, u16 num_entries)
-{
-	struct gdt_ptr gdt;
-
-	gdt.len = (num_entries * X86_GDT_ENTRY_SIZE) - 1;
-	gdt.ptr = (ulong)boot_gdt;
-
-	asm volatile("lgdtl %0\n" : : "m" (gdt));
-}
-
-void arch_setup_gd(gd_t *new_gd)
-{
-	u64 *gdt_addr;
-
-	gdt_addr = new_gd->arch.gdt;
-
-	/*
-	 * CS: code, read/execute, 4 GB, base 0
-	 *
-	 * Some OS (like VxWorks) requires GDT entry 1 to be the 32-bit CS
-	 */
-	gdt_addr[X86_GDT_ENTRY_UNUSED] = GDT_ENTRY(0xc09b, 0, 0xfffff);
-	gdt_addr[X86_GDT_ENTRY_32BIT_CS] = GDT_ENTRY(0xc09b, 0, 0xfffff);
-
-	/* DS: data, read/write, 4 GB, base 0 */
-	gdt_addr[X86_GDT_ENTRY_32BIT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff);
-
-	/* FS: data, read/write, 4 GB, base (Global Data Pointer) */
-	new_gd->arch.gd_addr = new_gd;
-	gdt_addr[X86_GDT_ENTRY_32BIT_FS] = GDT_ENTRY(0xc093,
-		     (ulong)&new_gd->arch.gd_addr, 0xfffff);
-
-	/* 16-bit CS: code, read/execute, 64 kB, base 0 */
-	gdt_addr[X86_GDT_ENTRY_16BIT_CS] = GDT_ENTRY(0x009b, 0, 0x0ffff);
-
-	/* 16-bit DS: data, read/write, 64 kB, base 0 */
-	gdt_addr[X86_GDT_ENTRY_16BIT_DS] = GDT_ENTRY(0x0093, 0, 0x0ffff);
-
-	gdt_addr[X86_GDT_ENTRY_16BIT_FLAT_CS] = GDT_ENTRY(0x809b, 0, 0xfffff);
-	gdt_addr[X86_GDT_ENTRY_16BIT_FLAT_DS] = GDT_ENTRY(0x8093, 0, 0xfffff);
-
-	load_gdt(gdt_addr, X86_GDT_NUM_ENTRIES);
-	load_ds(X86_GDT_ENTRY_32BIT_DS);
-	load_es(X86_GDT_ENTRY_32BIT_DS);
-	load_gs(X86_GDT_ENTRY_32BIT_DS);
-	load_ss(X86_GDT_ENTRY_32BIT_DS);
-	load_fs(X86_GDT_ENTRY_32BIT_FS);
-}
-
-#ifdef CONFIG_HAVE_FSP
-/*
- * Setup FSP execution environment GDT
- *
- * Per Intel FSP external architecture specification, before calling any FSP
- * APIs, we need make sure the system is in flat 32-bit mode and both the code
- * and data selectors should have full 4GB access range. Here we reuse the one
- * we used in arch/x86/cpu/start16.S, and reload the segement registers.
- */
-void setup_fsp_gdt(void)
-{
-	load_gdt((const u64 *)(gdt_rom + CONFIG_RESET_SEG_START), 4);
-	load_ds(X86_GDT_ENTRY_32BIT_DS);
-	load_ss(X86_GDT_ENTRY_32BIT_DS);
-	load_es(X86_GDT_ENTRY_32BIT_DS);
-	load_fs(X86_GDT_ENTRY_32BIT_DS);
-	load_gs(X86_GDT_ENTRY_32BIT_DS);
-}
-#endif
-
 int __weak x86_cleanup_before_linux(void)
 {
 #ifdef CONFIG_BOOTSTAGE_STASH
@@ -209,241 +66,6 @@
 	return 0;
 }
 
-/*
- * Cyrix CPUs without cpuid or with cpuid not yet enabled can be detected
- * by the fact that they preserve the flags across the division of 5/2.
- * PII and PPro exhibit this behavior too, but they have cpuid available.
- */
-
-/*
- * Perform the Cyrix 5/2 test. A Cyrix won't change
- * the flags, while other 486 chips will.
- */
-static inline int test_cyrix_52div(void)
-{
-	unsigned int test;
-
-	__asm__ __volatile__(
-	     "sahf\n\t"		/* clear flags (%eax = 0x0005) */
-	     "div %b2\n\t"	/* divide 5 by 2 */
-	     "lahf"		/* store flags into %ah */
-	     : "=a" (test)
-	     : "0" (5), "q" (2)
-	     : "cc");
-
-	/* AH is 0x02 on Cyrix after the divide.. */
-	return (unsigned char) (test >> 8) == 0x02;
-}
-
-/*
- *	Detect a NexGen CPU running without BIOS hypercode new enough
- *	to have CPUID. (Thanks to Herbert Oppmann)
- */
-
-static int deep_magic_nexgen_probe(void)
-{
-	int ret;
-
-	__asm__ __volatile__ (
-		"	movw	$0x5555, %%ax\n"
-		"	xorw	%%dx,%%dx\n"
-		"	movw	$2, %%cx\n"
-		"	divw	%%cx\n"
-		"	movl	$0, %%eax\n"
-		"	jnz	1f\n"
-		"	movl	$1, %%eax\n"
-		"1:\n"
-		: "=a" (ret) : : "cx", "dx");
-	return  ret;
-}
-
-static bool has_cpuid(void)
-{
-	return flag_is_changeable_p(X86_EFLAGS_ID);
-}
-
-static bool has_mtrr(void)
-{
-	return cpuid_edx(0x00000001) & (1 << 12) ? true : false;
-}
-
-static int build_vendor_name(char *vendor_name)
-{
-	struct cpuid_result result;
-	result = cpuid(0x00000000);
-	unsigned int *name_as_ints = (unsigned int *)vendor_name;
-
-	name_as_ints[0] = result.ebx;
-	name_as_ints[1] = result.edx;
-	name_as_ints[2] = result.ecx;
-
-	return result.eax;
-}
-
-static void identify_cpu(struct cpu_device_id *cpu)
-{
-	char vendor_name[16];
-	int i;
-
-	vendor_name[0] = '\0'; /* Unset */
-	cpu->device = 0; /* fix gcc 4.4.4 warning */
-
-	/* Find the id and vendor_name */
-	if (!has_cpuid()) {
-		/* Its a 486 if we can modify the AC flag */
-		if (flag_is_changeable_p(X86_EFLAGS_AC))
-			cpu->device = 0x00000400; /* 486 */
-		else
-			cpu->device = 0x00000300; /* 386 */
-		if ((cpu->device == 0x00000400) && test_cyrix_52div()) {
-			memcpy(vendor_name, "CyrixInstead", 13);
-			/* If we ever care we can enable cpuid here */
-		}
-		/* Detect NexGen with old hypercode */
-		else if (deep_magic_nexgen_probe())
-			memcpy(vendor_name, "NexGenDriven", 13);
-	}
-	if (has_cpuid()) {
-		int  cpuid_level;
-
-		cpuid_level = build_vendor_name(vendor_name);
-		vendor_name[12] = '\0';
-
-		/* Intel-defined flags: level 0x00000001 */
-		if (cpuid_level >= 0x00000001) {
-			cpu->device = cpuid_eax(0x00000001);
-		} else {
-			/* Have CPUID level 0 only unheard of */
-			cpu->device = 0x00000400;
-		}
-	}
-	cpu->vendor = X86_VENDOR_UNKNOWN;
-	for (i = 0; i < ARRAY_SIZE(x86_vendors); i++) {
-		if (memcmp(vendor_name, x86_vendors[i].name, 12) == 0) {
-			cpu->vendor = x86_vendors[i].vendor;
-			break;
-		}
-	}
-}
-
-static inline void get_fms(struct cpuinfo_x86 *c, uint32_t tfms)
-{
-	c->x86 = (tfms >> 8) & 0xf;
-	c->x86_model = (tfms >> 4) & 0xf;
-	c->x86_mask = tfms & 0xf;
-	if (c->x86 == 0xf)
-		c->x86 += (tfms >> 20) & 0xff;
-	if (c->x86 >= 0x6)
-		c->x86_model += ((tfms >> 16) & 0xF) << 4;
-}
-
-u32 cpu_get_family_model(void)
-{
-	return gd->arch.x86_device & 0x0fff0ff0;
-}
-
-u32 cpu_get_stepping(void)
-{
-	return gd->arch.x86_mask;
-}
-
-int x86_cpu_init_f(void)
-{
-	const u32 em_rst = ~X86_CR0_EM;
-	const u32 mp_ne_set = X86_CR0_MP | X86_CR0_NE;
-
-	if (ll_boot_init()) {
-		/* initialize FPU, reset EM, set MP and NE */
-		asm ("fninit\n" \
-		"movl %%cr0, %%eax\n" \
-		"andl %0, %%eax\n" \
-		"orl  %1, %%eax\n" \
-		"movl %%eax, %%cr0\n" \
-		: : "i" (em_rst), "i" (mp_ne_set) : "eax");
-	}
-
-	/* identify CPU via cpuid and store the decoded info into gd->arch */
-	if (has_cpuid()) {
-		struct cpu_device_id cpu;
-		struct cpuinfo_x86 c;
-
-		identify_cpu(&cpu);
-		get_fms(&c, cpu.device);
-		gd->arch.x86 = c.x86;
-		gd->arch.x86_vendor = cpu.vendor;
-		gd->arch.x86_model = c.x86_model;
-		gd->arch.x86_mask = c.x86_mask;
-		gd->arch.x86_device = cpu.device;
-
-		gd->arch.has_mtrr = has_mtrr();
-	}
-	/* Don't allow PCI region 3 to use memory in the 2-4GB memory hole */
-	gd->pci_ram_top = 0x80000000U;
-
-	/* Configure fixed range MTRRs for some legacy regions */
-	if (gd->arch.has_mtrr) {
-		u64 mtrr_cap;
-
-		mtrr_cap = native_read_msr(MTRR_CAP_MSR);
-		if (mtrr_cap & MTRR_CAP_FIX) {
-			/* Mark the VGA RAM area as uncacheable */
-			native_write_msr(MTRR_FIX_16K_A0000_MSR,
-					 MTRR_FIX_TYPE(MTRR_TYPE_UNCACHEABLE),
-					 MTRR_FIX_TYPE(MTRR_TYPE_UNCACHEABLE));
-
-			/*
-			 * Mark the PCI ROM area as cacheable to improve ROM
-			 * execution performance.
-			 */
-			native_write_msr(MTRR_FIX_4K_C0000_MSR,
-					 MTRR_FIX_TYPE(MTRR_TYPE_WRBACK),
-					 MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
-			native_write_msr(MTRR_FIX_4K_C8000_MSR,
-					 MTRR_FIX_TYPE(MTRR_TYPE_WRBACK),
-					 MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
-			native_write_msr(MTRR_FIX_4K_D0000_MSR,
-					 MTRR_FIX_TYPE(MTRR_TYPE_WRBACK),
-					 MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
-			native_write_msr(MTRR_FIX_4K_D8000_MSR,
-					 MTRR_FIX_TYPE(MTRR_TYPE_WRBACK),
-					 MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
-
-			/* Enable the fixed range MTRRs */
-			msr_setbits_64(MTRR_DEF_TYPE_MSR, MTRR_DEF_TYPE_FIX_EN);
-		}
-	}
-
-#ifdef CONFIG_I8254_TIMER
-	/* Set up the i8254 timer if required */
-	i8254_init();
-#endif
-
-	return 0;
-}
-
-void x86_enable_caches(void)
-{
-	unsigned long cr0;
-
-	cr0 = read_cr0();
-	cr0 &= ~(X86_CR0_NW | X86_CR0_CD);
-	write_cr0(cr0);
-	wbinvd();
-}
-void enable_caches(void) __attribute__((weak, alias("x86_enable_caches")));
-
-void x86_disable_caches(void)
-{
-	unsigned long cr0;
-
-	cr0 = read_cr0();
-	cr0 |= X86_CR0_NW | X86_CR0_CD;
-	wbinvd();
-	write_cr0(cr0);
-	wbinvd();
-}
-void disable_caches(void) __attribute__((weak, alias("x86_disable_caches")));
-
 int x86_init_cache(void)
 {
 	enable_caches();
@@ -483,11 +105,6 @@
 	outb(FULL_RST | SYS_RST | RST_CPU, IO_PORT_RESET);
 }
 
-int dcache_status(void)
-{
-	return !(read_cr0() & X86_CR0_CD);
-}
-
 /* Define these functions to allow ehch-hcd to function */
 void flush_dcache_range(unsigned long start, unsigned long stop)
 {
@@ -520,57 +137,6 @@
 	return 1;
 }
 
-void cpu_enable_paging_pae(ulong cr3)
-{
-	__asm__ __volatile__(
-		/* Load the page table address */
-		"movl	%0, %%cr3\n"
-		/* Enable pae */
-		"movl	%%cr4, %%eax\n"
-		"orl	$0x00000020, %%eax\n"
-		"movl	%%eax, %%cr4\n"
-		/* Enable paging */
-		"movl	%%cr0, %%eax\n"
-		"orl	$0x80000000, %%eax\n"
-		"movl	%%eax, %%cr0\n"
-		:
-		: "r" (cr3)
-		: "eax");
-}
-
-void cpu_disable_paging_pae(void)
-{
-	/* Turn off paging */
-	__asm__ __volatile__ (
-		/* Disable paging */
-		"movl	%%cr0, %%eax\n"
-		"andl	$0x7fffffff, %%eax\n"
-		"movl	%%eax, %%cr0\n"
-		/* Disable pae */
-		"movl	%%cr4, %%eax\n"
-		"andl	$0xffffffdf, %%eax\n"
-		"movl	%%eax, %%cr4\n"
-		:
-		:
-		: "eax");
-}
-
-static bool can_detect_long_mode(void)
-{
-	return cpuid_eax(0x80000000) > 0x80000000UL;
-}
-
-static bool has_long_mode(void)
-{
-	return cpuid_edx(0x80000001) & (1 << 29) ? true : false;
-}
-
-int cpu_has_64bit(void)
-{
-	return has_cpuid() && can_detect_long_mode() &&
-		has_long_mode();
-}
-
 const char *cpu_vendor_name(int vendor)
 {
 	const char *name;
@@ -616,46 +182,6 @@
 	return 0;
 }
 
-#define PAGETABLE_SIZE		(6 * 4096)
-
-/**
- * build_pagetable() - build a flat 4GiB page table structure for 64-bti mode
- *
- * @pgtable: Pointer to a 24iKB block of memory
- */
-static void build_pagetable(uint32_t *pgtable)
-{
-	uint i;
-
-	memset(pgtable, '\0', PAGETABLE_SIZE);
-
-	/* Level 4 needs a single entry */
-	pgtable[0] = (ulong)&pgtable[1024] + 7;
-
-	/* Level 3 has one 64-bit entry for each GiB of memory */
-	for (i = 0; i < 4; i++)
-		pgtable[1024 + i * 2] = (ulong)&pgtable[2048] + 0x1000 * i + 7;
-
-	/* Level 2 has 2048 64-bit entries, each repesenting 2MiB */
-	for (i = 0; i < 2048; i++)
-		pgtable[2048 + i * 2] = 0x183 + (i << 21UL);
-}
-
-int cpu_jump_to_64bit(ulong setup_base, ulong target)
-{
-	uint32_t *pgtable;
-
-	pgtable = memalign(4096, PAGETABLE_SIZE);
-	if (!pgtable)
-		return -ENOMEM;
-
-	build_pagetable(pgtable);
-	cpu_call64((ulong)pgtable, setup_base, target);
-	free(pgtable);
-
-	return -EFAULT;
-}
-
 void show_boot_progress(int val)
 {
 	outb(val, POST_PORT);
@@ -680,36 +206,6 @@
 }
 #endif
 
-#ifdef CONFIG_SMP
-static int enable_smis(struct udevice *cpu, void *unused)
-{
-	return 0;
-}
-
-static struct mp_flight_record mp_steps[] = {
-	MP_FR_BLOCK_APS(mp_init_cpu, NULL, mp_init_cpu, NULL),
-	/* Wait for APs to finish initialization before proceeding */
-	MP_FR_BLOCK_APS(NULL, NULL, enable_smis, NULL),
-};
-
-static int x86_mp_init(void)
-{
-	struct mp_params mp_params;
-
-	mp_params.parallel_microcode_load = 0,
-	mp_params.flight_plan = &mp_steps[0];
-	mp_params.num_records = ARRAY_SIZE(mp_steps);
-	mp_params.microcode_pointer = 0;
-
-	if (mp_init(&mp_params)) {
-		printf("Warning: MP init failure\n");
-		return -EIO;
-	}
-
-	return 0;
-}
-#endif
-
 static int x86_init_cpus(void)
 {
 #ifdef CONFIG_SMP
diff --git a/arch/x86/cpu/cpu_x86.c b/arch/x86/cpu/cpu_x86.c
index 157f3de..8be14b5 100644
--- a/arch/x86/cpu/cpu_x86.c
+++ b/arch/x86/cpu/cpu_x86.c
@@ -17,7 +17,7 @@
 	struct cpu_platdata *plat = dev_get_parent_platdata(dev);
 	struct cpuid_result res;
 
-	plat->cpu_id = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+	plat->cpu_id = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 				      "intel,apic-id", -1);
 	plat->family = gd->arch.x86;
 	res = cpuid(1);
diff --git a/arch/x86/cpu/i386/Makefile b/arch/x86/cpu/i386/Makefile
new file mode 100644
index 0000000..0c47252
--- /dev/null
+++ b/arch/x86/cpu/i386/Makefile
@@ -0,0 +1,9 @@
+#
+# (C) Copyright 2016 Google, Inc
+# Written by Simon Glass <sjg@chromium.org>
+#
+
+obj-y += call64.o
+obj-y += cpu.o
+obj-y += interrupt.o
+obj-y += setjmp.o
diff --git a/arch/x86/cpu/call64.S b/arch/x86/cpu/i386/call64.S
similarity index 98%
rename from arch/x86/cpu/call64.S
rename to arch/x86/cpu/i386/call64.S
index 08dc473..970c461 100644
--- a/arch/x86/cpu/call64.S
+++ b/arch/x86/cpu/i386/call64.S
@@ -81,6 +81,9 @@
 	jmp	*%eax			/* Jump to the 64-bit target */
 
 	.data
+	.align	16
+	.globl	gdt64
+gdt64:
 gdt:
 	.word	gdt_end - gdt - 1
 	.long	gdt			/* Fixed up by code above */
diff --git a/arch/x86/cpu/i386/cpu.c b/arch/x86/cpu/i386/cpu.c
new file mode 100644
index 0000000..aabdc94
--- /dev/null
+++ b/arch/x86/cpu/i386/cpu.c
@@ -0,0 +1,598 @@
+/*
+ * (C) Copyright 2008-2011
+ * Graeme Russ, <graeme.russ@gmail.com>
+ *
+ * (C) Copyright 2002
+ * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * Part of this file is adapted from coreboot
+ * src/arch/x86/lib/cpu.c
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <asm/control_regs.h>
+#include <asm/cpu.h>
+#include <asm/mp.h>
+#include <asm/msr.h>
+#include <asm/mtrr.h>
+#include <asm/processor-flags.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * Constructor for a conventional segment GDT (or LDT) entry
+ * This is a macro so it can be used in initialisers
+ */
+#define GDT_ENTRY(flags, base, limit)			\
+	((((base)  & 0xff000000ULL) << (56-24)) |	\
+	 (((flags) & 0x0000f0ffULL) << 40) |		\
+	 (((limit) & 0x000f0000ULL) << (48-16)) |	\
+	 (((base)  & 0x00ffffffULL) << 16) |		\
+	 (((limit) & 0x0000ffffULL)))
+
+struct gdt_ptr {
+	u16 len;
+	u32 ptr;
+} __packed;
+
+struct cpu_device_id {
+	unsigned vendor;
+	unsigned device;
+};
+
+struct cpuinfo_x86 {
+	uint8_t x86;            /* CPU family */
+	uint8_t x86_vendor;     /* CPU vendor */
+	uint8_t x86_model;
+	uint8_t x86_mask;
+};
+
+/*
+ * List of cpu vendor strings along with their normalized
+ * id values.
+ */
+static const struct {
+	int vendor;
+	const char *name;
+} x86_vendors[] = {
+	{ X86_VENDOR_INTEL,     "GenuineIntel", },
+	{ X86_VENDOR_CYRIX,     "CyrixInstead", },
+	{ X86_VENDOR_AMD,       "AuthenticAMD", },
+	{ X86_VENDOR_UMC,       "UMC UMC UMC ", },
+	{ X86_VENDOR_NEXGEN,    "NexGenDriven", },
+	{ X86_VENDOR_CENTAUR,   "CentaurHauls", },
+	{ X86_VENDOR_RISE,      "RiseRiseRise", },
+	{ X86_VENDOR_TRANSMETA, "GenuineTMx86", },
+	{ X86_VENDOR_TRANSMETA, "TransmetaCPU", },
+	{ X86_VENDOR_NSC,       "Geode by NSC", },
+	{ X86_VENDOR_SIS,       "SiS SiS SiS ", },
+};
+
+static void load_ds(u32 segment)
+{
+	asm volatile("movl %0, %%ds" : : "r" (segment * X86_GDT_ENTRY_SIZE));
+}
+
+static void load_es(u32 segment)
+{
+	asm volatile("movl %0, %%es" : : "r" (segment * X86_GDT_ENTRY_SIZE));
+}
+
+static void load_fs(u32 segment)
+{
+	asm volatile("movl %0, %%fs" : : "r" (segment * X86_GDT_ENTRY_SIZE));
+}
+
+static void load_gs(u32 segment)
+{
+	asm volatile("movl %0, %%gs" : : "r" (segment * X86_GDT_ENTRY_SIZE));
+}
+
+static void load_ss(u32 segment)
+{
+	asm volatile("movl %0, %%ss" : : "r" (segment * X86_GDT_ENTRY_SIZE));
+}
+
+static void load_gdt(const u64 *boot_gdt, u16 num_entries)
+{
+	struct gdt_ptr gdt;
+
+	gdt.len = (num_entries * X86_GDT_ENTRY_SIZE) - 1;
+	gdt.ptr = (ulong)boot_gdt;
+
+	asm volatile("lgdtl %0\n" : : "m" (gdt));
+}
+
+void arch_setup_gd(gd_t *new_gd)
+{
+	u64 *gdt_addr;
+
+	gdt_addr = new_gd->arch.gdt;
+
+	/*
+	 * CS: code, read/execute, 4 GB, base 0
+	 *
+	 * Some OS (like VxWorks) requires GDT entry 1 to be the 32-bit CS
+	 */
+	gdt_addr[X86_GDT_ENTRY_UNUSED] = GDT_ENTRY(0xc09b, 0, 0xfffff);
+	gdt_addr[X86_GDT_ENTRY_32BIT_CS] = GDT_ENTRY(0xc09b, 0, 0xfffff);
+
+	/* DS: data, read/write, 4 GB, base 0 */
+	gdt_addr[X86_GDT_ENTRY_32BIT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff);
+
+	/* FS: data, read/write, 4 GB, base (Global Data Pointer) */
+	new_gd->arch.gd_addr = new_gd;
+	gdt_addr[X86_GDT_ENTRY_32BIT_FS] = GDT_ENTRY(0xc093,
+		     (ulong)&new_gd->arch.gd_addr, 0xfffff);
+
+	/* 16-bit CS: code, read/execute, 64 kB, base 0 */
+	gdt_addr[X86_GDT_ENTRY_16BIT_CS] = GDT_ENTRY(0x009b, 0, 0x0ffff);
+
+	/* 16-bit DS: data, read/write, 64 kB, base 0 */
+	gdt_addr[X86_GDT_ENTRY_16BIT_DS] = GDT_ENTRY(0x0093, 0, 0x0ffff);
+
+	gdt_addr[X86_GDT_ENTRY_16BIT_FLAT_CS] = GDT_ENTRY(0x809b, 0, 0xfffff);
+	gdt_addr[X86_GDT_ENTRY_16BIT_FLAT_DS] = GDT_ENTRY(0x8093, 0, 0xfffff);
+
+	load_gdt(gdt_addr, X86_GDT_NUM_ENTRIES);
+	load_ds(X86_GDT_ENTRY_32BIT_DS);
+	load_es(X86_GDT_ENTRY_32BIT_DS);
+	load_gs(X86_GDT_ENTRY_32BIT_DS);
+	load_ss(X86_GDT_ENTRY_32BIT_DS);
+	load_fs(X86_GDT_ENTRY_32BIT_FS);
+}
+
+#ifdef CONFIG_HAVE_FSP
+/*
+ * Setup FSP execution environment GDT
+ *
+ * Per Intel FSP external architecture specification, before calling any FSP
+ * APIs, we need make sure the system is in flat 32-bit mode and both the code
+ * and data selectors should have full 4GB access range. Here we reuse the one
+ * we used in arch/x86/cpu/start16.S, and reload the segement registers.
+ */
+void setup_fsp_gdt(void)
+{
+	load_gdt((const u64 *)(gdt_rom + CONFIG_RESET_SEG_START), 4);
+	load_ds(X86_GDT_ENTRY_32BIT_DS);
+	load_ss(X86_GDT_ENTRY_32BIT_DS);
+	load_es(X86_GDT_ENTRY_32BIT_DS);
+	load_fs(X86_GDT_ENTRY_32BIT_DS);
+	load_gs(X86_GDT_ENTRY_32BIT_DS);
+}
+#endif
+
+/*
+ * Cyrix CPUs without cpuid or with cpuid not yet enabled can be detected
+ * by the fact that they preserve the flags across the division of 5/2.
+ * PII and PPro exhibit this behavior too, but they have cpuid available.
+ */
+
+/*
+ * Perform the Cyrix 5/2 test. A Cyrix won't change
+ * the flags, while other 486 chips will.
+ */
+static inline int test_cyrix_52div(void)
+{
+	unsigned int test;
+
+	__asm__ __volatile__(
+	     "sahf\n\t"		/* clear flags (%eax = 0x0005) */
+	     "div %b2\n\t"	/* divide 5 by 2 */
+	     "lahf"		/* store flags into %ah */
+	     : "=a" (test)
+	     : "0" (5), "q" (2)
+	     : "cc");
+
+	/* AH is 0x02 on Cyrix after the divide.. */
+	return (unsigned char) (test >> 8) == 0x02;
+}
+
+/*
+ *	Detect a NexGen CPU running without BIOS hypercode new enough
+ *	to have CPUID. (Thanks to Herbert Oppmann)
+ */
+static int deep_magic_nexgen_probe(void)
+{
+	int ret;
+
+	__asm__ __volatile__ (
+		"	movw	$0x5555, %%ax\n"
+		"	xorw	%%dx,%%dx\n"
+		"	movw	$2, %%cx\n"
+		"	divw	%%cx\n"
+		"	movl	$0, %%eax\n"
+		"	jnz	1f\n"
+		"	movl	$1, %%eax\n"
+		"1:\n"
+		: "=a" (ret) : : "cx", "dx");
+	return  ret;
+}
+
+static bool has_cpuid(void)
+{
+	return flag_is_changeable_p(X86_EFLAGS_ID);
+}
+
+static bool has_mtrr(void)
+{
+	return cpuid_edx(0x00000001) & (1 << 12) ? true : false;
+}
+
+static int build_vendor_name(char *vendor_name)
+{
+	struct cpuid_result result;
+	result = cpuid(0x00000000);
+	unsigned int *name_as_ints = (unsigned int *)vendor_name;
+
+	name_as_ints[0] = result.ebx;
+	name_as_ints[1] = result.edx;
+	name_as_ints[2] = result.ecx;
+
+	return result.eax;
+}
+
+static void identify_cpu(struct cpu_device_id *cpu)
+{
+	char vendor_name[16];
+	int i;
+
+	vendor_name[0] = '\0'; /* Unset */
+	cpu->device = 0; /* fix gcc 4.4.4 warning */
+
+	/* Find the id and vendor_name */
+	if (!has_cpuid()) {
+		/* Its a 486 if we can modify the AC flag */
+		if (flag_is_changeable_p(X86_EFLAGS_AC))
+			cpu->device = 0x00000400; /* 486 */
+		else
+			cpu->device = 0x00000300; /* 386 */
+		if ((cpu->device == 0x00000400) && test_cyrix_52div()) {
+			memcpy(vendor_name, "CyrixInstead", 13);
+			/* If we ever care we can enable cpuid here */
+		}
+		/* Detect NexGen with old hypercode */
+		else if (deep_magic_nexgen_probe())
+			memcpy(vendor_name, "NexGenDriven", 13);
+	}
+	if (has_cpuid()) {
+		int  cpuid_level;
+
+		cpuid_level = build_vendor_name(vendor_name);
+		vendor_name[12] = '\0';
+
+		/* Intel-defined flags: level 0x00000001 */
+		if (cpuid_level >= 0x00000001) {
+			cpu->device = cpuid_eax(0x00000001);
+		} else {
+			/* Have CPUID level 0 only unheard of */
+			cpu->device = 0x00000400;
+		}
+	}
+	cpu->vendor = X86_VENDOR_UNKNOWN;
+	for (i = 0; i < ARRAY_SIZE(x86_vendors); i++) {
+		if (memcmp(vendor_name, x86_vendors[i].name, 12) == 0) {
+			cpu->vendor = x86_vendors[i].vendor;
+			break;
+		}
+	}
+}
+
+static inline void get_fms(struct cpuinfo_x86 *c, uint32_t tfms)
+{
+	c->x86 = (tfms >> 8) & 0xf;
+	c->x86_model = (tfms >> 4) & 0xf;
+	c->x86_mask = tfms & 0xf;
+	if (c->x86 == 0xf)
+		c->x86 += (tfms >> 20) & 0xff;
+	if (c->x86 >= 0x6)
+		c->x86_model += ((tfms >> 16) & 0xF) << 4;
+}
+
+u32 cpu_get_family_model(void)
+{
+	return gd->arch.x86_device & 0x0fff0ff0;
+}
+
+u32 cpu_get_stepping(void)
+{
+	return gd->arch.x86_mask;
+}
+
+int x86_cpu_init_f(void)
+{
+	const u32 em_rst = ~X86_CR0_EM;
+	const u32 mp_ne_set = X86_CR0_MP | X86_CR0_NE;
+
+	if (ll_boot_init()) {
+		/* initialize FPU, reset EM, set MP and NE */
+		asm ("fninit\n" \
+		"movl %%cr0, %%eax\n" \
+		"andl %0, %%eax\n" \
+		"orl  %1, %%eax\n" \
+		"movl %%eax, %%cr0\n" \
+		: : "i" (em_rst), "i" (mp_ne_set) : "eax");
+	}
+
+	/* identify CPU via cpuid and store the decoded info into gd->arch */
+	if (has_cpuid()) {
+		struct cpu_device_id cpu;
+		struct cpuinfo_x86 c;
+
+		identify_cpu(&cpu);
+		get_fms(&c, cpu.device);
+		gd->arch.x86 = c.x86;
+		gd->arch.x86_vendor = cpu.vendor;
+		gd->arch.x86_model = c.x86_model;
+		gd->arch.x86_mask = c.x86_mask;
+		gd->arch.x86_device = cpu.device;
+
+		gd->arch.has_mtrr = has_mtrr();
+	}
+	/* Don't allow PCI region 3 to use memory in the 2-4GB memory hole */
+	gd->pci_ram_top = 0x80000000U;
+
+	/* Configure fixed range MTRRs for some legacy regions */
+	if (gd->arch.has_mtrr) {
+		u64 mtrr_cap;
+
+		mtrr_cap = native_read_msr(MTRR_CAP_MSR);
+		if (mtrr_cap & MTRR_CAP_FIX) {
+			/* Mark the VGA RAM area as uncacheable */
+			native_write_msr(MTRR_FIX_16K_A0000_MSR,
+					 MTRR_FIX_TYPE(MTRR_TYPE_UNCACHEABLE),
+					 MTRR_FIX_TYPE(MTRR_TYPE_UNCACHEABLE));
+
+			/*
+			 * Mark the PCI ROM area as cacheable to improve ROM
+			 * execution performance.
+			 */
+			native_write_msr(MTRR_FIX_4K_C0000_MSR,
+					 MTRR_FIX_TYPE(MTRR_TYPE_WRBACK),
+					 MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
+			native_write_msr(MTRR_FIX_4K_C8000_MSR,
+					 MTRR_FIX_TYPE(MTRR_TYPE_WRBACK),
+					 MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
+			native_write_msr(MTRR_FIX_4K_D0000_MSR,
+					 MTRR_FIX_TYPE(MTRR_TYPE_WRBACK),
+					 MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
+			native_write_msr(MTRR_FIX_4K_D8000_MSR,
+					 MTRR_FIX_TYPE(MTRR_TYPE_WRBACK),
+					 MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
+
+			/* Enable the fixed range MTRRs */
+			msr_setbits_64(MTRR_DEF_TYPE_MSR, MTRR_DEF_TYPE_FIX_EN);
+		}
+	}
+
+#ifdef CONFIG_I8254_TIMER
+	/* Set up the i8254 timer if required */
+	i8254_init();
+#endif
+
+	return 0;
+}
+
+void x86_enable_caches(void)
+{
+	unsigned long cr0;
+
+	cr0 = read_cr0();
+	cr0 &= ~(X86_CR0_NW | X86_CR0_CD);
+	write_cr0(cr0);
+	wbinvd();
+}
+void enable_caches(void) __attribute__((weak, alias("x86_enable_caches")));
+
+void x86_disable_caches(void)
+{
+	unsigned long cr0;
+
+	cr0 = read_cr0();
+	cr0 |= X86_CR0_NW | X86_CR0_CD;
+	wbinvd();
+	write_cr0(cr0);
+	wbinvd();
+}
+void disable_caches(void) __attribute__((weak, alias("x86_disable_caches")));
+
+int dcache_status(void)
+{
+	return !(read_cr0() & X86_CR0_CD);
+}
+
+void cpu_enable_paging_pae(ulong cr3)
+{
+	__asm__ __volatile__(
+		/* Load the page table address */
+		"movl	%0, %%cr3\n"
+		/* Enable pae */
+		"movl	%%cr4, %%eax\n"
+		"orl	$0x00000020, %%eax\n"
+		"movl	%%eax, %%cr4\n"
+		/* Enable paging */
+		"movl	%%cr0, %%eax\n"
+		"orl	$0x80000000, %%eax\n"
+		"movl	%%eax, %%cr0\n"
+		:
+		: "r" (cr3)
+		: "eax");
+}
+
+void cpu_disable_paging_pae(void)
+{
+	/* Turn off paging */
+	__asm__ __volatile__ (
+		/* Disable paging */
+		"movl	%%cr0, %%eax\n"
+		"andl	$0x7fffffff, %%eax\n"
+		"movl	%%eax, %%cr0\n"
+		/* Disable pae */
+		"movl	%%cr4, %%eax\n"
+		"andl	$0xffffffdf, %%eax\n"
+		"movl	%%eax, %%cr4\n"
+		:
+		:
+		: "eax");
+}
+
+static bool can_detect_long_mode(void)
+{
+	return cpuid_eax(0x80000000) > 0x80000000UL;
+}
+
+static bool has_long_mode(void)
+{
+	return cpuid_edx(0x80000001) & (1 << 29) ? true : false;
+}
+
+int cpu_has_64bit(void)
+{
+	return has_cpuid() && can_detect_long_mode() &&
+		has_long_mode();
+}
+
+#define PAGETABLE_SIZE		(6 * 4096)
+
+/**
+ * build_pagetable() - build a flat 4GiB page table structure for 64-bti mode
+ *
+ * @pgtable: Pointer to a 24iKB block of memory
+ */
+static void build_pagetable(uint32_t *pgtable)
+{
+	uint i;
+
+	memset(pgtable, '\0', PAGETABLE_SIZE);
+
+	/* Level 4 needs a single entry */
+	pgtable[0] = (ulong)&pgtable[1024] + 7;
+
+	/* Level 3 has one 64-bit entry for each GiB of memory */
+	for (i = 0; i < 4; i++)
+		pgtable[1024 + i * 2] = (ulong)&pgtable[2048] + 0x1000 * i + 7;
+
+	/* Level 2 has 2048 64-bit entries, each repesenting 2MiB */
+	for (i = 0; i < 2048; i++)
+		pgtable[2048 + i * 2] = 0x183 + (i << 21UL);
+}
+
+int cpu_jump_to_64bit(ulong setup_base, ulong target)
+{
+	uint32_t *pgtable;
+
+	pgtable = memalign(4096, PAGETABLE_SIZE);
+	if (!pgtable)
+		return -ENOMEM;
+
+	build_pagetable(pgtable);
+	cpu_call64((ulong)pgtable, setup_base, target);
+	free(pgtable);
+
+	return -EFAULT;
+}
+
+/*
+ * Jump from SPL to U-Boot
+ *
+ * This function is work-in-progress with many issues to resolve.
+ *
+ * It works by setting up several regions:
+ *   ptr      - a place to put the code that jumps into 64-bit mode
+ *   gdt      - a place to put the global descriptor table
+ *   pgtable  - a place to put the page tables
+ *
+ * The cpu_call64() code is copied from ROM and then manually patched so that
+ * it has the correct GDT address in RAM. U-Boot is copied from ROM into
+ * its pre-relocation address. Then we jump to the cpu_call64() code in RAM,
+ * which changes to 64-bit mode and starts U-Boot.
+ */
+int cpu_jump_to_64bit_uboot(ulong target)
+{
+	typedef void (*func_t)(ulong pgtable, ulong setup_base, ulong target);
+	uint32_t *pgtable;
+	func_t func;
+
+	/* TODO(sjg@chromium.org): Find a better place for this */
+	pgtable = (uint32_t *)0x1000000;
+	if (!pgtable)
+		return -ENOMEM;
+
+	build_pagetable(pgtable);
+
+	/* TODO(sjg@chromium.org): Find a better place for this */
+	char *ptr = (char *)0x3000000;
+	char *gdt = (char *)0x3100000;
+
+	extern char gdt64[];
+
+	memcpy(ptr, cpu_call64, 0x1000);
+	memcpy(gdt, gdt64, 0x100);
+
+	/*
+	 * TODO(sjg@chromium.org): This manually inserts the pointers into
+	 * the code. Tidy this up to avoid this.
+	 */
+	func = (func_t)ptr;
+	ulong ofs = (ulong)cpu_call64 - (ulong)ptr;
+	*(ulong *)(ptr + 7) = (ulong)gdt;
+	*(ulong *)(ptr + 0xc) = (ulong)gdt + 2;
+	*(ulong *)(ptr + 0x13) = (ulong)gdt;
+	*(ulong *)(ptr + 0x117 - 0xd4) -= ofs;
+
+	/*
+	 * Copy U-Boot from ROM
+	 * TODO(sjg@chromium.org): Figure out a way to get the text base
+	 * correctly here, and in the device-tree binman definition.
+	 *
+	 * Also consider using FIT so we get the correct image length and
+	 * parameters.
+	 */
+	memcpy((char *)target, (char *)0xfff00000, 0x100000);
+
+	/* Jump to U-Boot */
+	func((ulong)pgtable, 0, (ulong)target);
+
+	return -EFAULT;
+}
+
+#ifdef CONFIG_SMP
+static int enable_smis(struct udevice *cpu, void *unused)
+{
+	return 0;
+}
+
+static struct mp_flight_record mp_steps[] = {
+	MP_FR_BLOCK_APS(mp_init_cpu, NULL, mp_init_cpu, NULL),
+	/* Wait for APs to finish initialization before proceeding */
+	MP_FR_BLOCK_APS(NULL, NULL, enable_smis, NULL),
+};
+
+int x86_mp_init(void)
+{
+	struct mp_params mp_params;
+
+	mp_params.parallel_microcode_load = 0,
+	mp_params.flight_plan = &mp_steps[0];
+	mp_params.num_records = ARRAY_SIZE(mp_steps);
+	mp_params.microcode_pointer = 0;
+
+	if (mp_init(&mp_params)) {
+		printf("Warning: MP init failure\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+#endif
diff --git a/arch/x86/cpu/interrupts.c b/arch/x86/cpu/i386/interrupt.c
similarity index 98%
rename from arch/x86/cpu/interrupts.c
rename to arch/x86/cpu/i386/interrupt.c
index 5f6cdd3..a058303 100644
--- a/arch/x86/cpu/interrupts.c
+++ b/arch/x86/cpu/i386/interrupt.c
@@ -13,16 +13,12 @@
 
 #include <common.h>
 #include <dm.h>
-#include <asm/cache.h>
 #include <asm/control_regs.h>
 #include <asm/i8259.h>
 #include <asm/interrupt.h>
 #include <asm/io.h>
 #include <asm/lapic.h>
-#include <asm/msr.h>
 #include <asm/processor-flags.h>
-#include <asm/processor.h>
-#include <asm/u-boot-x86.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -238,7 +234,7 @@
 {
 	long flags;
 
-#ifdef CONFIG_X86_64
+#if CONFIG_IS_ENABLED(X86_64)
 	asm volatile ("pushfq ; popq %0 ; cli\n" : "=g" (flags) : );
 #else
 	asm volatile ("pushfl ; popl %0 ; cli\n" : "=g" (flags) : );
diff --git a/arch/x86/cpu/setjmp.S b/arch/x86/cpu/i386/setjmp.S
similarity index 100%
rename from arch/x86/cpu/setjmp.S
rename to arch/x86/cpu/i386/setjmp.S
diff --git a/arch/x86/cpu/intel_common/Makefile b/arch/x86/cpu/intel_common/Makefile
index 804c539..1145e78 100644
--- a/arch/x86/cpu/intel_common/Makefile
+++ b/arch/x86/cpu/intel_common/Makefile
@@ -4,13 +4,15 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
-obj-$(CONFIG_HAVE_MRC) += car.o
+ifdef CONFIG_HAVE_MRC
+obj-$(CONFIG_$(SPL_)X86_32BIT_INIT) += car.o
+obj-$(CONFIG_$(SPL_)X86_32BIT_INIT) += me_status.o
+obj-$(CONFIG_$(SPL_)X86_32BIT_INIT) += report_platform.o
+obj-$(CONFIG_$(SPL_)X86_32BIT_INIT) += mrc.o
+endif
 obj-y += cpu.o
 obj-y += lpc.o
-obj-$(CONFIG_HAVE_MRC) += me_status.o
 ifndef CONFIG_TARGET_EFI
 obj-y += microcode.o
 endif
 obj-y += pch.o
-obj-$(CONFIG_HAVE_MRC) += report_platform.o
-obj-$(CONFIG_HAVE_MRC) += mrc.o
diff --git a/arch/x86/cpu/intel_common/lpc.c b/arch/x86/cpu/intel_common/lpc.c
index 03cb45b..696b630 100644
--- a/arch/x86/cpu/intel_common/lpc.c
+++ b/arch/x86/cpu/intel_common/lpc.c
@@ -50,7 +50,7 @@
 	int count;
 	int i;
 
-	count = fdtdec_get_int_array_count(gd->fdt_blob, dev->of_offset,
+	count = fdtdec_get_int_array_count(gd->fdt_blob, dev_of_offset(dev),
 			"intel,gen-dec", (u32 *)values,
 			sizeof(values) / sizeof(u32));
 	if (count < 0)
diff --git a/arch/x86/cpu/intel_common/mrc.c b/arch/x86/cpu/intel_common/mrc.c
index 01b6e86..f1a249a 100644
--- a/arch/x86/cpu/intel_common/mrc.c
+++ b/arch/x86/cpu/intel_common/mrc.c
@@ -149,7 +149,7 @@
 	spd_index = dm_gpio_get_values_as_int(desc, ret);
 	debug("spd index %d\n", spd_index);
 
-	node = fdt_first_subnode(blob, dev->of_offset);
+	node = fdt_first_subnode(blob, dev_of_offset(dev));
 	if (node < 0)
 		return -EINVAL;
 	for (spd_node = fdt_first_subnode(blob, node);
diff --git a/arch/x86/cpu/irq.c b/arch/x86/cpu/irq.c
index 9364410..f5654eb 100644
--- a/arch/x86/cpu/irq.c
+++ b/arch/x86/cpu/irq.c
@@ -17,8 +17,6 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-static struct irq_routing_table *pirq_routing_table;
-
 bool pirq_check_irq_routed(struct udevice *dev, int link, u8 irq)
 {
 	struct irq_router *priv = dev_get_priv(dev);
@@ -28,7 +26,7 @@
 	if (priv->config == PIRQ_VIA_PCI)
 		dm_pci_read_config8(dev->parent, LINK_N2V(link, base), &pirq);
 	else
-		pirq = readb(priv->ibase + LINK_N2V(link, base));
+		pirq = readb((uintptr_t)priv->ibase + LINK_N2V(link, base));
 
 	pirq &= 0xf;
 
@@ -58,7 +56,7 @@
 	if (priv->config == PIRQ_VIA_PCI)
 		dm_pci_write_config8(dev->parent, LINK_N2V(link, base), irq);
 	else
-		writeb(irq, priv->ibase + LINK_N2V(link, base));
+		writeb(irq, (uintptr_t)priv->ibase + LINK_N2V(link, base));
 }
 
 static struct irq_info *check_dup_entry(struct irq_info *slot_base,
@@ -98,7 +96,7 @@
 	int i;
 	int ret;
 
-	node = dev->of_offset;
+	node = dev_of_offset(dev);
 
 	/* extract the bdf from fdt_pci_addr */
 	priv->bdf = dm_pci_get_bdf(dev->parent);
@@ -219,7 +217,7 @@
 	/* Fix up the table checksum */
 	rt->checksum = table_compute_checksum(rt, rt->size);
 
-	pirq_routing_table = rt;
+	gd->arch.pirq_routing_table = rt;
 
 	return 0;
 }
@@ -236,7 +234,7 @@
 		if (priv->config == PIRQ_VIA_PCI)
 			dm_pci_write_config32(dev->parent, priv->actl_addr, 0);
 		else
-			writel(0, priv->ibase + priv->actl_addr);
+			writel(0, (uintptr_t)priv->ibase + priv->actl_addr);
 	}
 }
 
@@ -250,8 +248,8 @@
 		return ret;
 	}
 	/* Route PIRQ */
-	pirq_route_irqs(dev, pirq_routing_table->slots,
-			get_irq_slot_count(pirq_routing_table));
+	pirq_route_irqs(dev, gd->arch.pirq_routing_table->slots,
+			get_irq_slot_count(gd->arch.pirq_routing_table));
 
 	if (IS_ENABLED(CONFIG_GENERATE_ACPI_TABLE))
 		irq_enable_sci(dev);
@@ -264,12 +262,12 @@
 	return irq_router_common_init(dev);
 }
 
-u32 write_pirq_routing_table(u32 addr)
+ulong write_pirq_routing_table(ulong addr)
 {
-	if (!pirq_routing_table)
+	if (!gd->arch.pirq_routing_table)
 		return addr;
 
-	return copy_pirq_routing_table(addr, pirq_routing_table);
+	return copy_pirq_routing_table(addr, gd->arch.pirq_routing_table);
 }
 
 static const struct udevice_id irq_router_ids[] = {
diff --git a/arch/x86/cpu/ivybridge/Makefile b/arch/x86/cpu/ivybridge/Makefile
index 498e71a..25fbd59 100644
--- a/arch/x86/cpu/ivybridge/Makefile
+++ b/arch/x86/cpu/ivybridge/Makefile
@@ -7,12 +7,17 @@
 ifdef CONFIG_HAVE_FSP
 obj-y += fsp_configs.o ivybridge.o
 else
-obj-y += cpu.o
+obj-$(CONFIG_$(SPL_)X86_32BIT_INIT) += cpu.o
 obj-y += early_me.o
 obj-y += lpc.o
 obj-y += model_206ax.o
 obj-y += northbridge.o
+ifndef CONFIG_SPL_BUILD
 obj-y += sata.o
-obj-y += sdram.o
+endif
+obj-$(CONFIG_$(SPL_)X86_32BIT_INIT) += sdram.o
+ifndef CONFIG_$(SPL_)X86_32BIT_INIT
+obj-y += sdram_nop.o
+endif
 endif
 obj-y += bd82x6x.o
diff --git a/arch/x86/cpu/ivybridge/bd82x6x.c b/arch/x86/cpu/ivybridge/bd82x6x.c
index e63ea6b..e3eff69 100644
--- a/arch/x86/cpu/ivybridge/bd82x6x.c
+++ b/arch/x86/cpu/ivybridge/bd82x6x.c
@@ -19,6 +19,8 @@
 #include <asm/arch/pch.h>
 #include <asm/arch/sandybridge.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 #define GPIO_BASE	0x48
 #define BIOS_CTRL	0xdc
 
diff --git a/arch/x86/cpu/ivybridge/cpu.c b/arch/x86/cpu/ivybridge/cpu.c
index 85e361a..c4aca08 100644
--- a/arch/x86/cpu/ivybridge/cpu.c
+++ b/arch/x86/cpu/ivybridge/cpu.c
@@ -169,8 +169,10 @@
 
 	/* Enable SPD ROMs and DDR-III DRAM */
 	ret = uclass_first_device_err(UCLASS_I2C, &dev);
-	if (ret)
+	if (ret) {
+		debug("%s: Failed to get I2C (ret=%d)\n", __func__, ret);
 		return ret;
+	}
 
 	/* Prepare USB controller early in S3 resume */
 	if (boot_mode == PEI_BOOT_RESUME) {
diff --git a/arch/x86/cpu/ivybridge/lpc.c b/arch/x86/cpu/ivybridge/lpc.c
index 4af89b3..4e254b3 100644
--- a/arch/x86/cpu/ivybridge/lpc.c
+++ b/arch/x86/cpu/ivybridge/lpc.c
@@ -20,6 +20,8 @@
 #include <asm/pci.h>
 #include <asm/arch/pch.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 #define NMI_OFF				0
 
 #define ENABLE_ACPI_MODE_IN_COREBOOT	0
@@ -84,7 +86,7 @@
 {
 	uint8_t route[8], *ptr;
 
-	if (fdtdec_get_byte_array(gd->fdt_blob, pch->of_offset,
+	if (fdtdec_get_byte_array(gd->fdt_blob, dev_of_offset(pch),
 				  "intel,pirq-routing", route, sizeof(route)))
 		return -EINVAL;
 	ptr = route;
@@ -111,7 +113,7 @@
 	u32 reg;
 	int gpi;
 
-	if (fdtdec_get_byte_array(gd->fdt_blob, pch->of_offset,
+	if (fdtdec_get_byte_array(gd->fdt_blob, dev_of_offset(pch),
 				  "intel,gpi-routing", route, sizeof(route)))
 		return -EINVAL;
 
@@ -126,7 +128,7 @@
 static int pch_power_options(struct udevice *pch)
 {
 	const void *blob = gd->fdt_blob;
-	int node = pch->of_offset;
+	int node = dev_of_offset(pch);
 	u8 reg8;
 	u16 reg16, pmbase;
 	u32 reg32;
diff --git a/arch/x86/cpu/ivybridge/model_206ax.c b/arch/x86/cpu/ivybridge/model_206ax.c
index 09b5342..81dedee 100644
--- a/arch/x86/cpu/ivybridge/model_206ax.c
+++ b/arch/x86/cpu/ivybridge/model_206ax.c
@@ -22,6 +22,8 @@
 #include <asm/turbo.h>
 #include <asm/arch/model_206ax.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 static void enable_vmx(void)
 {
 	struct cpuid_result regs;
@@ -286,8 +288,8 @@
 	int tcc_offset;
 	msr_t msr;
 
-	tcc_offset = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "tcc-offset",
-				    0);
+	tcc_offset = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
+				    "tcc-offset", 0);
 
 	/* Set TCC activaiton offset if supported */
 	msr = msr_read(MSR_PLATFORM_INFO);
diff --git a/arch/x86/cpu/ivybridge/northbridge.c b/arch/x86/cpu/ivybridge/northbridge.c
index 491f289..94f31c4 100644
--- a/arch/x86/cpu/ivybridge/northbridge.c
+++ b/arch/x86/cpu/ivybridge/northbridge.c
@@ -19,6 +19,8 @@
 #include <asm/arch/model_206ax.h>
 #include <asm/arch/sandybridge.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 int bridge_silicon_revision(struct udevice *dev)
 {
 	struct cpuid_result result;
diff --git a/arch/x86/cpu/ivybridge/sata.c b/arch/x86/cpu/ivybridge/sata.c
index 87ff872..0f5e190 100644
--- a/arch/x86/cpu/ivybridge/sata.c
+++ b/arch/x86/cpu/ivybridge/sata.c
@@ -39,7 +39,7 @@
 {
 	unsigned int port_map, speed_support, port_tx;
 	const void *blob = gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	const char *mode;
 	u32 reg32;
 	u16 reg16;
@@ -53,7 +53,7 @@
 
 	mode = fdt_getprop(blob, node, "intel,sata-mode", NULL);
 	if (!mode || !strcmp(mode, "ahci")) {
-		u32 abar;
+		ulong abar;
 
 		debug("SATA: Controller in AHCI mode\n");
 
@@ -72,7 +72,7 @@
 
 		/* Initialize AHCI memory-mapped space */
 		abar = dm_pci_read_bar32(dev, 5);
-		debug("ABAR: %08X\n", abar);
+		debug("ABAR: %08lx\n", abar);
 		/* CAP (HBA Capabilities) : enable power management */
 		reg32 = readl(abar + 0x00);
 		reg32 |= 0x0c006000;  /* set PSC+SSC+SALP+SSS */
@@ -190,7 +190,7 @@
 static void bd82x6x_sata_enable(struct udevice *dev)
 {
 	const void *blob = gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	unsigned port_map;
 	const char *mode;
 	u16 map = 0;
diff --git a/arch/x86/cpu/ivybridge/sdram.c b/arch/x86/cpu/ivybridge/sdram.c
index e0b06b5..201368c 100644
--- a/arch/x86/cpu/ivybridge/sdram.c
+++ b/arch/x86/cpu/ivybridge/sdram.c
@@ -207,8 +207,10 @@
 	int ret;
 
 	ret = mrc_locate_spd(dev, sizeof(peid->spd_data[0]), &data);
-	if (ret)
+	if (ret) {
+		debug("%s: Could not locate SPD (ret=%d)\n", __func__, ret);
 		return ret;
+	}
 
 	memcpy(peid->spd_data[0], data, sizeof(peid->spd_data[0]));
 
@@ -460,18 +462,27 @@
 
 	/* We need the pinctrl set up early */
 	ret = syscon_get_by_driver_data(X86_SYSCON_PINCONF, &dev);
-	if (ret)
+	if (ret) {
+		debug("%s: Could not get pinconf (ret=%d)\n", __func__, ret);
 		return ret;
+	}
 
 	ret = uclass_first_device_err(UCLASS_NORTHBRIDGE, &dev);
-	if (ret)
+	if (ret) {
+		debug("%s: Could not get northbridge (ret=%d)\n", __func__,
+		      ret);
 		return ret;
+	}
 	ret = syscon_get_by_driver_data(X86_SYSCON_ME, &me_dev);
-	if (ret)
+	if (ret) {
+		debug("%s: Could not get ME (ret=%d)\n", __func__, ret);
 		return ret;
+	}
 	ret = copy_spd(dev, pei_data);
-	if (ret)
+	if (ret) {
+		debug("%s: Could not get SPD (ret=%d)\n", __func__, ret);
 		return ret;
+	}
 	pei_data->boot_mode = gd->arch.pei_boot_mode;
 	debug("Boot mode %d\n", gd->arch.pei_boot_mode);
 	debug("mrc_input %p\n", pei_data->mrc_input);
@@ -498,19 +509,27 @@
 
 	/* Wait for ME to be ready */
 	ret = intel_early_me_init(me_dev);
-	if (ret)
+	if (ret) {
+		debug("%s: Could not init ME (ret=%d)\n", __func__, ret);
 		return ret;
+	}
 	ret = intel_early_me_uma_size(me_dev);
-	if (ret < 0)
+	if (ret < 0) {
+		debug("%s: Could not get UMA size (ret=%d)\n", __func__, ret);
 		return ret;
+	}
 
 	ret = mrc_common_init(dev, pei_data, false);
-	if (ret)
+	if (ret) {
+		debug("%s: mrc_common_init() failed (ret=%d)\n", __func__, ret);
 		return ret;
+	}
 
 	ret = sdram_find(dev);
-	if (ret)
+	if (ret) {
+		debug("%s: sdram_find() failed (ret=%d)\n", __func__, ret);
 		return ret;
+	}
 	gd->ram_size = gd->arch.meminfo.total_32bit_memory;
 
 	debug("MRC output data length %#x at %p\n", pei_data->mrc_output_len,
diff --git a/arch/x86/cpu/ivybridge/sdram_nop.c b/arch/x86/cpu/ivybridge/sdram_nop.c
new file mode 100644
index 0000000..bd1189e
--- /dev/null
+++ b/arch/x86/cpu/ivybridge/sdram_nop.c
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#include <common.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+	gd->ram_size = 1ULL << 31;
+	gd->bd->bi_dram[0].start = 0;
+	gd->bd->bi_dram[0].size = gd->ram_size;
+
+	return 0;
+}
diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index 2b6b3bd..988073c 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -568,7 +568,8 @@
 	 * seq num in the uclass_resolve_seq() during device_probe(). To avoid
 	 * this, set req_seq to the reg number in the device tree in advance.
 	 */
-	cpu->req_seq = fdtdec_get_int(gd->fdt_blob, cpu->of_offset, "reg", -1);
+	cpu->req_seq = fdtdec_get_int(gd->fdt_blob, dev_of_offset(cpu), "reg",
+				      -1);
 	plat->ucode_version = microcode_read_rev();
 	plat->device_id = gd->arch.x86_device;
 
diff --git a/arch/x86/cpu/qemu/e820.c b/arch/x86/cpu/qemu/e820.c
index 63853e4..c1c9b89 100644
--- a/arch/x86/cpu/qemu/e820.c
+++ b/arch/x86/cpu/qemu/e820.c
@@ -7,6 +7,8 @@
 #include <common.h>
 #include <asm/e820.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 unsigned install_e820_map(unsigned max_entries, struct e820entry *entries)
 {
 	entries[0].addr = 0;
diff --git a/arch/x86/cpu/qemu/qemu.c b/arch/x86/cpu/qemu/qemu.c
index c3092f2..7153eb2 100644
--- a/arch/x86/cpu/qemu/qemu.c
+++ b/arch/x86/cpu/qemu/qemu.c
@@ -47,7 +47,7 @@
 static void qemu_x86_fwcfg_read_entry_dma(struct fw_cfg_dma_access *dma)
 {
 	/* the DMA address register is big endian */
-	outl(cpu_to_be32((uint32_t)dma), FW_DMA_PORT_HIGH);
+	outl(cpu_to_be32((uintptr_t)dma), FW_DMA_PORT_HIGH);
 
 	while (be32_to_cpu(dma->control) & ~FW_CFG_DMA_ERROR)
 		__asm__ __volatile__ ("pause");
@@ -137,14 +137,17 @@
 #endif
 }
 
+#if !CONFIG_IS_ENABLED(SPL_X86_32BIT_INIT)
 int arch_cpu_init(void)
 {
 	post_code(POST_CPU_INIT);
 
 	return x86_cpu_init_f();
 }
+#endif
 
-#ifndef CONFIG_EFI_STUB
+#if !CONFIG_IS_ENABLED(EFI_STUB) && \
+	!CONFIG_IS_ENABLED(SPL_X86_32BIT_INIT)
 int print_cpuinfo(void)
 {
 	post_code(POST_CPU_INFO);
diff --git a/arch/x86/cpu/start.S b/arch/x86/cpu/start.S
index a5cba1c..8de55a0 100644
--- a/arch/x86/cpu/start.S
+++ b/arch/x86/cpu/start.S
@@ -18,14 +18,6 @@
 #include <generated/generic-asm-offsets.h>
 #include <generated/asm-offsets.h>
 
-/*
- * Define this to boot U-Boot from a 32-bit program which sets the GDT
- * differently. This can be used to boot directly from any stage of coreboot,
- * for example, bypassing the normal payload-loading feature.
- * This is only useful for development.
- */
-#undef LOAD_FROM_32_BIT
-
 .section .text
 .code32
 .globl _start
@@ -76,7 +68,7 @@
 	/* Save table pointer */
 	movl	%ecx, %esi
 
-#ifdef LOAD_FROM_32_BIT
+#ifdef CONFIG_X86_LOAD_FROM_32_BIT
 	lgdt	gdt_ptr2
 #endif
 
@@ -233,7 +225,7 @@
 	/* entry addr */
 	.long	CONFIG_SYS_TEXT_BASE
 
-#ifdef LOAD_FROM_32_BIT
+#ifdef CONFIG_X86_LOAD_FROM_32_BIT
 	/*
 	 * The following Global Descriptor Table is just enough to get us into
 	 * 'Flat Protected Mode' - It will be discarded as soon as the final
diff --git a/arch/x86/cpu/start64.S b/arch/x86/cpu/start64.S
new file mode 100644
index 0000000..651f16a
--- /dev/null
+++ b/arch/x86/cpu/start64.S
@@ -0,0 +1,28 @@
+/*
+ * 64-bit x86 Startup Code
+ *
+ * (C) Copyright 216 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <config.h>
+
+.section .text
+.code64
+.globl _start
+.type _start, @function
+_start:
+	/* Set up memory using the existing stack */
+	mov	%rsp, %rdi
+	call	board_init_f_alloc_reserve
+	mov	%rax, %rsp
+
+	call	board_init_f_init_reserve
+
+	call	board_init_f
+	call	board_init_f_r
+
+	/* Should not return here */
+	jmp	.
diff --git a/arch/x86/cpu/turbo.c b/arch/x86/cpu/turbo.c
index 254d0de..bbd255e 100644
--- a/arch/x86/cpu/turbo.c
+++ b/arch/x86/cpu/turbo.c
@@ -12,6 +12,8 @@
 #include <asm/processor.h>
 #include <asm/turbo.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 #if CONFIG_CPU_INTEL_TURBO_NOT_PACKAGE_SCOPED
 static inline int get_global_turbo_state(void)
 {
@@ -22,16 +24,14 @@
 {
 }
 #else
-static int g_turbo_state = TURBO_UNKNOWN;
-
 static inline int get_global_turbo_state(void)
 {
-	return g_turbo_state;
+	return gd->arch.turbo_state;
 }
 
 static inline void set_global_turbo_state(int state)
 {
-	g_turbo_state = state;
+	gd->arch.turbo_state = state;
 }
 #endif
 
diff --git a/arch/x86/cpu/u-boot-64.lds b/arch/x86/cpu/u-boot-64.lds
new file mode 100644
index 0000000..718790c
--- /dev/null
+++ b/arch/x86/cpu/u-boot-64.lds
@@ -0,0 +1,76 @@
+/*
+ * (C) Copyright 2002
+ * Daniel Engström, Omicron Ceti AB, daniel@omicron.se.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <config.h>
+OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
+OUTPUT_ARCH(i386:x86-64)
+ENTRY(_start)
+
+SECTIONS
+{
+#ifndef CONFIG_CMDLINE
+	/DISCARD/ : { *(.u_boot_list_2_cmd_*) }
+#endif
+
+	. = CONFIG_SYS_TEXT_BASE;	/* Location of bootcode in flash */
+	__text_start = .;
+	.text  : { *(.text*); }
+
+	. = ALIGN(4);
+
+	. = ALIGN(4);
+	.u_boot_list : {
+		KEEP(*(SORT(.u_boot_list*)));
+	}
+
+	. = ALIGN(4);
+	.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
+
+	. = ALIGN(4);
+	.data : { *(.data*) }
+
+	. = ALIGN(4);
+	.hash : { *(.hash*) }
+
+	. = ALIGN(4);
+	.got : { *(.got*) }
+
+	. = ALIGN(4);
+	__data_end = .;
+	__init_end = .;
+
+	. = ALIGN(4);
+	.dynsym : { *(.dynsym*) }
+
+	. = ALIGN(4);
+	__rel_dyn_start = .;
+	.rela.dyn : {
+		*(.rela*)
+	}
+	__rel_dyn_end = .;
+	. = ALIGN(4);
+
+	.dynamic : { *(.dynamic) }
+
+	. = ALIGN(4);
+	_end = .;
+
+	.bss __rel_dyn_start (OVERLAY) : {
+		__bss_start = .;
+		*(.bss)
+		*(COM*)
+		. = ALIGN(4);
+		__bss_end = .;
+	}
+
+	/DISCARD/ : { *(.dynsym) }
+	/DISCARD/ : { *(.dynstr*) }
+	/DISCARD/ : { *(.dynamic*) }
+	/DISCARD/ : { *(.plt*) }
+	/DISCARD/ : { *(.interp*) }
+	/DISCARD/ : { *(.gnu*) }
+}
diff --git a/arch/x86/cpu/u-boot-spl.lds b/arch/x86/cpu/u-boot-spl.lds
new file mode 100644
index 0000000..8a38d58
--- /dev/null
+++ b/arch/x86/cpu/u-boot-spl.lds
@@ -0,0 +1,74 @@
+/*
+ * (C) Copyright 2002
+ * Daniel Engström, Omicron Ceti AB, daniel@omicron.se.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <config.h>
+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
+OUTPUT_ARCH(i386)
+ENTRY(_start)
+
+SECTIONS
+{
+#ifndef CONFIG_CMDLINE
+	/DISCARD/ : { *(.u_boot_list_2_cmd_*) }
+#endif
+
+	. = CONFIG_SPL_TEXT_BASE;	/* Location of bootcode in flash */
+	__text_start = .;
+	.text  : { *(.text*); }
+
+	. = ALIGN(4);
+
+	. = ALIGN(4);
+	.u_boot_list : {
+		KEEP(*(SORT(.u_boot_list*)));
+	}
+
+	. = ALIGN(4);
+	.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
+
+	. = ALIGN(4);
+	.data : { *(.data*) }
+
+	. = ALIGN(4);
+	__data_end = .;
+	__init_end = .;
+
+        _image_binary_end = .;
+
+	. = 0x120000;
+	.bss (OVERLAY) : {
+		__bss_start = .;
+		*(.bss*)
+		*(COM*)
+		. = ALIGN(4);
+		__bss_end = .;
+	}
+	__bss_size = __bss_end - __bss_start;
+
+	/DISCARD/ : { *(.dynstr*) }
+	/DISCARD/ : { *(.dynamic*) }
+	/DISCARD/ : { *(.plt*) }
+	/DISCARD/ : { *(.interp*) }
+	/DISCARD/ : { *(.gnu*) }
+
+#ifdef CONFIG_SPL_X86_16BIT_INIT
+	/*
+	 * The following expressions place the 16-bit Real-Mode code and
+	 * Reset Vector at the end of the Flash ROM
+	 */
+	. = START_16 - RESET_SEG_START;
+	.start16 : AT (START_16) {
+		KEEP(*(.start16));
+	}
+
+	. = RESET_VEC_LOC - RESET_SEG_START;
+	.resetvec : AT (RESET_VEC_LOC) {
+		KEEP(*(.resetvec));
+	}
+#endif
+
+}
diff --git a/arch/x86/cpu/u-boot.lds b/arch/x86/cpu/u-boot.lds
index cca536b..186718d 100644
--- a/arch/x86/cpu/u-boot.lds
+++ b/arch/x86/cpu/u-boot.lds
@@ -103,7 +103,7 @@
 	/DISCARD/ : { *(.interp*) }
 	/DISCARD/ : { *(.gnu*) }
 
-#ifdef CONFIG_X86_RESET_VECTOR
+#ifdef CONFIG_X86_16BIT_INIT
 	/*
 	 * The following expressions place the 16-bit Real-Mode code and
 	 * Reset Vector at the end of the Flash ROM
diff --git a/arch/x86/cpu/x86_64/Makefile b/arch/x86/cpu/x86_64/Makefile
new file mode 100644
index 0000000..400f0ff
--- /dev/null
+++ b/arch/x86/cpu/x86_64/Makefile
@@ -0,0 +1,6 @@
+#
+# (C) Copyright 2016 Google, Inc
+# Written by Simon Glass <sjg@chromium.org>
+#
+
+obj-y += cpu.o interrupts.o setjmp.o
diff --git a/arch/x86/cpu/x86_64/cpu.c b/arch/x86/cpu/x86_64/cpu.c
new file mode 100644
index 0000000..db171f7
--- /dev/null
+++ b/arch/x86/cpu/x86_64/cpu.c
@@ -0,0 +1,73 @@
+/*
+ * (C) Copyright 2016 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <debug_uart.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Global declaration of gd */
+struct global_data *global_data_ptr;
+
+void arch_setup_gd(gd_t *new_gd)
+{
+	global_data_ptr = new_gd;
+
+	/*
+	 * TODO(sjg@chromium.org): For some reason U-Boot does not boot
+	 * without this line. It fails to start up U-Boot proper and instead
+	 * restarts SPL. Need to figure out why:
+	 *
+	 * U-Boot SPL 2017.01
+	 *
+	 * U-Boot SPL 2017.01
+	 * CPU:   Intel(R) Core(TM) i5-3427U CPU @ 1.80GHz
+	 * Trying to boot from SPIJumping to 64-bit U-Boot: Note many
+	 * features are missing
+	 *
+	 * U-Boot SPL 2017.01
+	 */
+#ifdef CONFIG_DEBUG_UART
+	printch(' ');
+#endif
+}
+
+int cpu_has_64bit(void)
+{
+	return true;
+}
+
+void enable_caches(void)
+{
+	/* Not implemented */
+}
+
+void disable_caches(void)
+{
+	/* Not implemented */
+}
+
+int dcache_status(void)
+{
+	return true;
+}
+
+int x86_mp_init(void)
+{
+	/* Not implemented */
+	return 0;
+}
+
+int misc_init_r(void)
+{
+	return 0;
+}
+
+int print_cpuinfo(void)
+{
+	return 0;
+}
diff --git a/arch/x86/cpu/x86_64/interrupts.c b/arch/x86/cpu/x86_64/interrupts.c
new file mode 100644
index 0000000..3e06173
--- /dev/null
+++ b/arch/x86/cpu/x86_64/interrupts.c
@@ -0,0 +1,29 @@
+/*
+ * (C) Copyright 2016 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/processor-flags.h>
+
+void enable_interrupts(void)
+{
+	asm("sti\n");
+}
+
+int disable_interrupts(void)
+{
+	long flags;
+
+	asm volatile ("pushfq ; popq %0 ; cli\n" : "=g" (flags) : );
+
+	return flags & X86_EFLAGS_IF;
+}
+
+int interrupt_init(void)
+{
+	/* Nothing to do - this was already done in SPL */
+	return 0;
+}
diff --git a/arch/x86/cpu/x86_64/setjmp.c b/arch/x86/cpu/x86_64/setjmp.c
new file mode 100644
index 0000000..25f8d28
--- /dev/null
+++ b/arch/x86/cpu/x86_64/setjmp.c
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/setjmp.h>
+
+int setjmp(struct jmp_buf_data *jmp_buf)
+{
+	printf("WARNING: setjmp() is not supported\n");
+
+	return 0;
+}
+
+void longjmp(struct jmp_buf_data *jmp_buf, int val)
+{
+	printf("WARNING: longjmp() is not supported\n");
+}
diff --git a/arch/x86/dts/chromebook_link.dts b/arch/x86/dts/chromebook_link.dts
index b932340..fab919a 100644
--- a/arch/x86/dts/chromebook_link.dts
+++ b/arch/x86/dts/chromebook_link.dts
@@ -26,12 +26,14 @@
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
+		u-boot,dm-pre-reloc;
 
 		cpu@0 {
 			device_type = "cpu";
 			compatible = "intel,core-gen3";
 			reg = <0>;
 			intel,apic-id = <0>;
+			u-boot,dm-pre-reloc;
 		};
 
 		cpu@1 {
@@ -39,6 +41,7 @@
 			compatible = "intel,core-gen3";
 			reg = <1>;
 			intel,apic-id = <1>;
+			u-boot,dm-pre-reloc;
 		};
 
 		cpu@2 {
@@ -46,6 +49,7 @@
 			compatible = "intel,core-gen3";
 			reg = <2>;
 			intel,apic-id = <2>;
+			u-boot,dm-pre-reloc;
 		};
 
 		cpu@3 {
@@ -53,6 +57,7 @@
 			compatible = "intel,core-gen3";
 			reg = <3>;
 			intel,apic-id = <3>;
+			u-boot,dm-pre-reloc;
 		};
 
 	};
@@ -229,14 +234,16 @@
 
 		northbridge@0,0 {
 			reg = <0x00000000 0 0 0 0>;
+			u-boot,dm-pre-reloc;
 			compatible = "intel,bd82x6x-northbridge";
 			board-id-gpios = <&gpio_b 9 0>, <&gpio_b 10 0>,
 					<&gpio_b 11 0>, <&gpio_a 10 0>;
-			u-boot,dm-pre-reloc;
 			spd {
+				u-boot,dm-pre-reloc;
 				#address-cells = <1>;
 				#size-cells = <0>;
 				elpida_4Gb_1600_x16 {
+					u-boot,dm-pre-reloc;
 					reg = <0>;
 					data = [92 10 0b 03 04 19 02 02
 						03 52 01 08 0a 00 fe 00
@@ -272,6 +279,7 @@
 						00 00 00 00 00 00 00 00];
 				};
 				samsung_4Gb_1600_1.35v_x16 {
+					u-boot,dm-pre-reloc;
 					reg = <1>;
 					data = [92 11 0b 03 04 19 02 02
 						03 11 01 08 0a 00 fe 00
@@ -391,9 +399,11 @@
 				#address-cells = <1>;
 				#size-cells = <0>;
 				compatible = "intel,ich9-spi";
+				u-boot,dm-pre-reloc;
 				spi-flash@0 {
 					#size-cells = <1>;
 					#address-cells = <1>;
+					u-boot,dm-pre-reloc;
 					reg = <0>;
 					compatible = "winbond,w25q64",
 							"spi-flash";
@@ -401,6 +411,7 @@
 					rw-mrc-cache {
 						label = "rw-mrc-cache";
 						reg = <0x003e0000 0x00010000>;
+						u-boot,dm-pre-reloc;
 					};
 				};
 			};
@@ -478,7 +489,9 @@
 	};
 
 	microcode {
+		u-boot,dm-pre-reloc;
 		update@0 {
+			u-boot,dm-pre-reloc;
 #include "microcode/m12306a9_0000001b.dtsi"
 		};
 	};
diff --git a/arch/x86/dts/emulation-u-boot.dtsi b/arch/x86/dts/emulation-u-boot.dtsi
index 56d34af..7714ed0 100644
--- a/arch/x86/dts/emulation-u-boot.dtsi
+++ b/arch/x86/dts/emulation-u-boot.dtsi
@@ -10,9 +10,15 @@
 #ifdef CONFIG_ROM_SIZE
 / {
 	binman {
+#ifdef CONFIG_SPL
+		u-boot-spl-with-ucode-ptr {
+			optional-ucode;
+		};
+#else
 		u-boot-with-ucode-ptr {
 			optional-ucode;
 		};
+#endif
 	};
 };
 #endif
diff --git a/arch/x86/dts/qemu-x86_i440fx.dts b/arch/x86/dts/qemu-x86_i440fx.dts
index 9c3f2a0..afea14e 100644
--- a/arch/x86/dts/qemu-x86_i440fx.dts
+++ b/arch/x86/dts/qemu-x86_i440fx.dts
@@ -29,10 +29,12 @@
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
+		u-boot,dm-pre-reloc;
 
 		cpu@0 {
 			device_type = "cpu";
 			compatible = "cpu-qemu";
+			u-boot,dm-pre-reloc;
 			reg = <0>;
 			intel,apic-id = <0>;
 		};
@@ -54,9 +56,11 @@
 		pch@1,0 {
 			reg = <0x00000800 0 0 0 0>;
 			compatible = "intel,pch7";
+			u-boot,dm-pre-reloc;
 
 			irq-router {
 				compatible = "intel,irq-router";
+				u-boot,dm-pre-reloc;
 				intel,pirq-config = "pci";
 				intel,pirq-link = <0x60 4>;
 				intel,pirq-mask = <0x0e40>;
diff --git a/arch/x86/dts/qemu-x86_q35.dts b/arch/x86/dts/qemu-x86_q35.dts
index 0d462a9..bc398dd 100644
--- a/arch/x86/dts/qemu-x86_q35.dts
+++ b/arch/x86/dts/qemu-x86_q35.dts
@@ -40,10 +40,12 @@
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
+		u-boot,dm-pre-reloc;
 
 		cpu@0 {
 			device_type = "cpu";
 			compatible = "cpu-qemu";
+			u-boot,dm-pre-reloc;
 			reg = <0>;
 			intel,apic-id = <0>;
 		};
@@ -65,9 +67,11 @@
 		pch@1f,0 {
 			reg = <0x0000f800 0 0 0 0>;
 			compatible = "intel,pch9";
+			u-boot,dm-pre-reloc;
 
 			irq-router {
 				compatible = "intel,irq-router";
+				u-boot,dm-pre-reloc;
 				intel,pirq-config = "pci";
 				intel,actl-8bit;
 				intel,actl-addr = <0x44>;
diff --git a/arch/x86/dts/serial.dtsi b/arch/x86/dts/serial.dtsi
index 54c3faf..22f7b54 100644
--- a/arch/x86/dts/serial.dtsi
+++ b/arch/x86/dts/serial.dtsi
@@ -1,5 +1,6 @@
 / {
 	serial: serial {
+		u-boot,dm-pre-reloc;
 		compatible = "ns16550";
 		reg = <0x3f8 8>;
 		reg-shift = <0>;
diff --git a/arch/x86/dts/u-boot.dtsi b/arch/x86/dts/u-boot.dtsi
index 31f0b1a..69c1c1d 100644
--- a/arch/x86/dts/u-boot.dtsi
+++ b/arch/x86/dts/u-boot.dtsi
@@ -21,9 +21,22 @@
 		intel-me {
 		};
 #endif
+#ifdef CONFIG_SPL
+		u-boot-spl-with-ucode-ptr {
+			pos = <CONFIG_SPL_TEXT_BASE>;
+		};
+
+		u-boot-dtb-with-ucode2 {
+			type = "u-boot-dtb-with-ucode";
+		};
+		u-boot {
+			pos = <0xfff00000>;
+		};
+#else
 		u-boot-with-ucode-ptr {
 			pos = <CONFIG_SYS_TEXT_BASE>;
 		};
+#endif
 		u-boot-dtb-with-ucode {
 		};
 		u-boot-ucode {
@@ -57,9 +70,15 @@
 			pos = <CONFIG_X86_REFCODE_ADDR>;
 		};
 #endif
+#ifdef CONFIG_SPL
+		x86-start16-spl {
+			pos = <CONFIG_SYS_X86_START16>;
+		};
+#else
 		x86-start16 {
 			pos = <CONFIG_SYS_X86_START16>;
 		};
+#endif
 	};
 };
 #endif
diff --git a/arch/x86/include/asm/acpi_table.h b/arch/x86/include/asm/acpi_table.h
index caff4d8..bbd80a1 100644
--- a/arch/x86/include/asm/acpi_table.h
+++ b/arch/x86/include/asm/acpi_table.h
@@ -316,4 +316,4 @@
 			       u8 cpu, u16 flags, u8 lint);
 u32 acpi_fill_madt(u32 current);
 void acpi_create_gnvs(struct acpi_global_nvs *gnvs);
-u32 write_acpi_tables(u32 start);
+ulong write_acpi_tables(ulong start);
diff --git a/arch/x86/include/asm/bootparam.h b/arch/x86/include/asm/bootparam.h
index a373a79..48b138c 100644
--- a/arch/x86/include/asm/bootparam.h
+++ b/arch/x86/include/asm/bootparam.h
@@ -117,7 +117,8 @@
 	X86_SUBARCH_PC = 0,
 	X86_SUBARCH_LGUEST,
 	X86_SUBARCH_XEN,
-	X86_SUBARCH_MRST,
+	X86_SUBARCH_INTEL_MID,
+	X86_SUBARCH_CE4100,
 	X86_NR_SUBARCHS,
 };
 #endif /* _ASM_X86_BOOTPARAM_H */
diff --git a/arch/x86/include/asm/byteorder.h b/arch/x86/include/asm/byteorder.h
index 7dfeb8b..a2d1fd8 100644
--- a/arch/x86/include/asm/byteorder.h
+++ b/arch/x86/include/asm/byteorder.h
@@ -8,24 +8,25 @@
 
 static __inline__ __u32 ___arch__swab32(__u32 x)
 {
-#ifdef CONFIG_X86_BSWAP
 	__asm__("bswap %0" : "=r" (x) : "0" (x));
-#else
-	__asm__("xchgb %b0,%h0\n\t"	/* swap lower bytes	*/
-		"rorl $16,%0\n\t"	/* swap words		*/
-		"xchgb %b0,%h0"		/* swap higher bytes	*/
-		:"=q" (x)
-		: "0" (x));
-#endif
+
 	return x;
 }
 
+#define _constant_swab16(x) ((__u16)(				\
+	(((__u16)(x) & (__u16)0x00ffU) << 8) |			\
+	(((__u16)(x) & (__u16)0xff00U) >> 8)))
+
 static __inline__ __u16 ___arch__swab16(__u16 x)
 {
+#if CONFIG_IS_ENABLED(X86_64)
+	return _constant_swab16(x);
+#else
 	__asm__("xchgb %b0,%h0"		/* swap bytes		*/ \
 		: "=q" (x) \
 		:  "0" (x)); \
 		return x;
+#endif
 }
 
 #define __arch__swab32(x) ___arch__swab32(x)
diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h
index 540024a..c651f2f 100644
--- a/arch/x86/include/asm/cpu.h
+++ b/arch/x86/include/asm/cpu.h
@@ -159,6 +159,8 @@
 	return edx;
 }
 
+#if !CONFIG_IS_ENABLED(X86_64)
+
 /* Standard macro to see if a specific flag is changeable */
 static inline int flag_is_changeable_p(uint32_t flag)
 {
@@ -179,6 +181,7 @@
 		: "ir" (flag));
 	return ((f1^f2) & flag) != 0;
 }
+#endif
 
 static inline void mfence(void)
 {
@@ -261,6 +264,15 @@
 int cpu_jump_to_64bit(ulong setup_base, ulong target);
 
 /**
+ * cpu_jump_to_64bit_uboot() - special function to jump from SPL to U-Boot
+ *
+ * This handles calling from 32-bit SPL to 64-bit U-Boot.
+ *
+ * @target:	Address of U-Boot in RAM
+ */
+int cpu_jump_to_64bit_uboot(ulong target);
+
+/**
  * cpu_get_family_model() - Get the family and model for the CPU
  *
  * @return the CPU ID masked with 0x0fff0ff0
diff --git a/arch/x86/include/asm/fsp/fsp_hob.h b/arch/x86/include/asm/fsp/fsp_hob.h
index 3fb3546..7c22bcd 100644
--- a/arch/x86/include/asm/fsp/fsp_hob.h
+++ b/arch/x86/include/asm/fsp/fsp_hob.h
@@ -139,7 +139,7 @@
  */
 static inline const struct hob_header *get_next_hob(const struct hob_header *hdr)
 {
-	return (const struct hob_header *)((u32)hdr + hdr->len);
+	return (const struct hob_header *)((uintptr_t)hdr + hdr->len);
 }
 
 /**
@@ -172,7 +172,7 @@
  */
 static inline void *get_guid_hob_data(const struct hob_header *hdr)
 {
-	return (void *)((u32)hdr + sizeof(struct hob_guid));
+	return (void *)((uintptr_t)hdr + sizeof(struct hob_guid));
 }
 
 /**
diff --git a/arch/x86/include/asm/global_data.h b/arch/x86/include/asm/global_data.h
index 7434f77..4570bc7 100644
--- a/arch/x86/include/asm/global_data.h
+++ b/arch/x86/include/asm/global_data.h
@@ -93,6 +93,8 @@
 	char *mrc_output;
 	unsigned int mrc_output_len;
 	ulong table;			/* Table pointer from previous loader */
+	int turbo_state;		/* Current turbo state */
+	struct irq_routing_table *pirq_routing_table;
 #ifdef CONFIG_SEABIOS
 	u32 high_table_ptr;
 	u32 high_table_limit;
@@ -104,8 +106,9 @@
 #include <asm-generic/global_data.h>
 
 #ifndef __ASSEMBLY__
-# ifdef CONFIG_EFI_APP
+# if defined(CONFIG_EFI_APP) || CONFIG_IS_ENABLED(X86_64)
 
+/* TODO(sjg@chromium.org): Consider using a fixed register for gd on x86_64 */
 #define gd global_data_ptr
 
 #define DECLARE_GLOBAL_DATA_PTR   extern struct global_data *global_data_ptr
@@ -114,7 +117,11 @@
 {
 	gd_t *gd_ptr;
 
+#if CONFIG_IS_ENABLED(X86_64)
+	asm volatile("fs mov 0, %0\n" : "=r" (gd_ptr));
+#else
 	asm volatile("fs movl 0, %0\n" : "=r" (gd_ptr));
+#endif
 
 	return gd_ptr;
 }
diff --git a/arch/x86/include/asm/mp.h b/arch/x86/include/asm/mp.h
index 2e6c312..83b99dc 100644
--- a/arch/x86/include/asm/mp.h
+++ b/arch/x86/include/asm/mp.h
@@ -90,4 +90,7 @@
 /* Probes the CPU device */
 int mp_init_cpu(struct udevice *cpu, void *unused);
 
+/* Set up additional CPUs */
+int x86_mp_init(void);
+
 #endif /* _X86_MP_H_ */
diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
index ad8eba9..30dbdca 100644
--- a/arch/x86/include/asm/mpspec.h
+++ b/arch/x86/include/asm/mpspec.h
@@ -224,9 +224,9 @@
  * @mc:		configuration table header address
  * @return:	configuration table end address
  */
-static inline u32 mp_next_mpc_entry(struct mp_config_table *mc)
+static inline ulong mp_next_mpc_entry(struct mp_config_table *mc)
 {
-	return (u32)mc + mc->mpc_length;
+	return (ulong)mc + mc->mpc_length;
 }
 
 /**
@@ -254,9 +254,9 @@
  * @mc:		configuration table header address
  * @return:	configuration table end address
  */
-static inline u32 mp_next_mpe_entry(struct mp_config_table *mc)
+static inline ulong mp_next_mpe_entry(struct mp_config_table *mc)
 {
-	return (u32)mc + mc->mpc_length + mc->mpe_length;
+	return (ulong)mc + mc->mpc_length + mc->mpe_length;
 }
 
 /**
@@ -456,6 +456,6 @@
  * @addr:	start address to write MP table
  * @return:	end address of MP table
  */
-u32 write_mp_table(u32 addr);
+ulong write_mp_table(ulong addr);
 
 #endif /* __ASM_MPSPEC_H */
diff --git a/arch/x86/include/asm/posix_types.h b/arch/x86/include/asm/posix_types.h
index 5529f32..717f6cb 100644
--- a/arch/x86/include/asm/posix_types.h
+++ b/arch/x86/include/asm/posix_types.h
@@ -16,8 +16,13 @@
 typedef unsigned short	__kernel_ipc_pid_t;
 typedef unsigned short	__kernel_uid_t;
 typedef unsigned short	__kernel_gid_t;
+#if CONFIG_IS_ENABLED(X86_64)
+typedef unsigned long	__kernel_size_t;
+typedef long		__kernel_ssize_t;
+#else
 typedef unsigned int	__kernel_size_t;
 typedef int		__kernel_ssize_t;
+#endif
 typedef int		__kernel_ptrdiff_t;
 typedef long		__kernel_time_t;
 typedef long		__kernel_suseconds_t;
diff --git a/arch/x86/include/asm/sfi.h b/arch/x86/include/asm/sfi.h
index d1f0f0c..d6c44c9 100644
--- a/arch/x86/include/asm/sfi.h
+++ b/arch/x86/include/asm/sfi.h
@@ -132,6 +132,6 @@
  * @base:	Address to write table to
  * @return address to use for the next table
  */
-u32 write_sfi_table(u32 base);
+ulong write_sfi_table(ulong base);
 
 #endif /*_LINUX_SFI_H */
diff --git a/arch/x86/include/asm/spl.h b/arch/x86/include/asm/spl.h
new file mode 100644
index 0000000..d48a3fc
--- /dev/null
+++ b/arch/x86/include/asm/spl.h
@@ -0,0 +1,8 @@
+/*
+ * Copyright (C) 2017 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * This file is required for SPL to build, but is empty.
+ */
diff --git a/arch/x86/include/asm/tables.h b/arch/x86/include/asm/tables.h
index 81f98f2..d1b2388 100644
--- a/arch/x86/include/asm/tables.h
+++ b/arch/x86/include/asm/tables.h
@@ -65,6 +65,6 @@
  * @start:	start address to write PIRQ routing table
  * @return:	end address of PIRQ routing table
  */
-u32 write_pirq_routing_table(u32 start);
+ulong write_pirq_routing_table(ulong start);
 
 #endif /* _X86_TABLES_H_ */
diff --git a/arch/x86/include/asm/types.h b/arch/x86/include/asm/types.h
index 880dcb4..a47e581 100644
--- a/arch/x86/include/asm/types.h
+++ b/arch/x86/include/asm/types.h
@@ -44,7 +44,12 @@
 typedef __UINT64_TYPE__ u64;
 #endif
 
+#if CONFIG_IS_ENABLED(X86_64)
+#define BITS_PER_LONG 64
+#else
 #define BITS_PER_LONG 32
+#endif
+
 /* Dma addresses are 32-bits wide.  */
 
 typedef u32 dma_addr_t;
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index 723288f..1c2c085 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -5,10 +5,14 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
+ifndef CONFIG_X86_64
 obj-y += bios.o
 obj-y += bios_asm.o
 obj-y += bios_interrupts.o
+endif
+ifndef CONFIG_SPL_BUILD
 obj-$(CONFIG_CMD_BOOTM) += bootm.o
+endif
 obj-y	+= cmd_boot.o
 obj-$(CONFIG_SEABIOS) += coreboot_table.o
 obj-$(CONFIG_EFI) += efi/
@@ -35,8 +39,11 @@
 obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi_table.o
 endif
 obj-y	+= tables.o
+ifndef CONFIG_SPL_BUILD
 obj-$(CONFIG_CMD_ZBOOT)	+= zimage.o
+endif
 obj-$(CONFIG_HAVE_FSP) += fsp/
+obj-$(CONFIG_SPL_BUILD) += spl.o
 
 extra-$(CONFIG_USE_PRIVATE_LIBGCC) += lib.a
 
@@ -45,7 +52,9 @@
 $(obj)/lib.a: $(NORMAL_LIBGCC) FORCE
 	$(call if_changed,objcopy)
 
+ifeq ($(CONFIG_$(SPL_)X86_64),)
 obj-$(CONFIG_EFI_APP) += crt0_ia32_efi.o reloc_ia32_efi.o
+endif
 
 ifneq ($(CONFIG_EFI_STUB),)
 
@@ -65,5 +74,7 @@
 endif
 
 ifneq ($(CONFIG_EFI_STUB)$(CONFIG_CMD_BOOTEFI_HELLO_COMPILE),)
+ifeq ($(CONFIG_$(SPL_)X86_64),)
 extra-y += $(EFI_CRT0) $(EFI_RELOC)
 endif
+endif
diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c
index 7001e8b..355456d 100644
--- a/arch/x86/lib/acpi_table.c
+++ b/arch/x86/lib/acpi_table.c
@@ -327,7 +327,7 @@
  * QEMU's version of write_acpi_tables is defined in
  * arch/x86/cpu/qemu/acpi_table.c
  */
-u32 write_acpi_tables(u32 start)
+ulong write_acpi_tables(ulong start)
 {
 	u32 current;
 	struct acpi_rsdp *rsdp;
@@ -345,7 +345,7 @@
 	/* Align ACPI tables to 16 byte */
 	current = ALIGN(current, 16);
 
-	debug("ACPI: Writing ACPI tables at %x\n", start);
+	debug("ACPI: Writing ACPI tables at %lx\n", start);
 
 	/* We need at least an RSDP and an RSDT Table */
 	rsdp = (struct acpi_rsdp *)current;
diff --git a/arch/x86/lib/bios.c b/arch/x86/lib/bios.c
index 9324bdb..66d7629 100644
--- a/arch/x86/lib/bios.c
+++ b/arch/x86/lib/bios.c
@@ -157,7 +157,7 @@
 	 for (i = 0; i < 256; i++) {
 		idts[i].cs = 0;
 		idts[i].offset = 0x1000 + (i * __idt_handler_size);
-		write_idt_stub((void *)((u32)idts[i].offset), i);
+		write_idt_stub((void *)((ulong)idts[i].offset), i);
 	}
 
 	/*
@@ -227,7 +227,7 @@
 	mode_info->video_mode = (1 << 14) | vesa_mode;
 	vbe_get_mode_info(mode_info);
 
-	framebuffer = (unsigned char *)mode_info->vesa.phys_base_ptr;
+	framebuffer = (unsigned char *)(ulong)mode_info->vesa.phys_base_ptr;
 	debug("VBE: resolution:  %dx%d@%d\n",
 	      le16_to_cpu(mode_info->vesa.x_resolution),
 	      le16_to_cpu(mode_info->vesa.y_resolution),
diff --git a/arch/x86/lib/bootm.c b/arch/x86/lib/bootm.c
index e5e63f6..3c3d9e1 100644
--- a/arch/x86/lib/bootm.c
+++ b/arch/x86/lib/bootm.c
@@ -155,7 +155,14 @@
 			puts("Cannot boot 64-bit kernel on 32-bit machine\n");
 			return -EFAULT;
 		}
+		/* At present 64-bit U-Boot does not support booting a
+		 * kernel.
+		 * TODO(sjg@chromium.org): Support booting both 32-bit and
+		 * 64-bit kernels from 64-bit U-Boot.
+		 */
+#if !CONFIG_IS_ENABLED(X86_64)
 		return cpu_jump_to_64bit(setup_base, load_address);
+#endif
 	} else {
 		/*
 		* Set %ebx, %ebp, and %edi to 0, %esi to point to the
diff --git a/arch/x86/lib/init_helpers.c b/arch/x86/lib/init_helpers.c
index 2a186fc..420393b 100644
--- a/arch/x86/lib/init_helpers.c
+++ b/arch/x86/lib/init_helpers.c
@@ -19,7 +19,7 @@
 
 int init_cache_f_r(void)
 {
-#if defined(CONFIG_X86_RESET_VECTOR) & !defined(CONFIG_HAVE_FSP)
+#if CONFIG_IS_ENABLED(X86_32BIT_INIT) && !defined(CONFIG_HAVE_FSP)
 	int ret;
 
 	ret = mtrr_commit(false);
diff --git a/arch/x86/lib/interrupts.c b/arch/x86/lib/interrupts.c
index dd08402..d3ae6d9 100644
--- a/arch/x86/lib/interrupts.c
+++ b/arch/x86/lib/interrupts.c
@@ -33,6 +33,8 @@
 #include <common.h>
 #include <asm/interrupt.h>
 
+#if !CONFIG_IS_ENABLED(X86_64)
+
 struct irq_action {
 	interrupt_handler_t *handler;
 	void *arg;
@@ -118,10 +120,12 @@
 		}
 	}
 }
+#endif
 
 #if defined(CONFIG_CMD_IRQ)
 int do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
+#if !CONFIG_IS_ENABLED(X86_64)
 	int irq;
 
 	printf("Spurious IRQ: %u, last unknown IRQ: %d\n",
@@ -139,6 +143,7 @@
 					irq_handlers[irq].count);
 		}
 	}
+#endif
 
 	return 0;
 }
diff --git a/arch/x86/lib/mpspec.c b/arch/x86/lib/mpspec.c
index 6ab43f1..a6e493d 100644
--- a/arch/x86/lib/mpspec.c
+++ b/arch/x86/lib/mpspec.c
@@ -25,10 +25,10 @@
 
 struct mp_config_table *mp_write_floating_table(struct mp_floating_table *mf)
 {
-	u32 mc;
+	ulong mc;
 
 	memcpy(mf->mpf_signature, MPF_SIGNATURE, 4);
-	mf->mpf_physptr = (u32)mf + sizeof(struct mp_floating_table);
+	mf->mpf_physptr = (ulong)mf + sizeof(struct mp_floating_table);
 	mf->mpf_length = 1;
 	mf->mpf_spec = MPSPEC_V14;
 	mf->mpf_checksum = 0;
@@ -41,7 +41,7 @@
 	mf->mpf_feature5 = 0;
 	mf->mpf_checksum = table_compute_checksum(mf, mf->mpf_length * 16);
 
-	mc = (u32)mf + sizeof(struct mp_floating_table);
+	mc = (ulong)mf + sizeof(struct mp_floating_table);
 	return (struct mp_config_table *)mc;
 }
 
@@ -219,14 +219,14 @@
 
 u32 mptable_finalize(struct mp_config_table *mc)
 {
-	u32 end;
+	ulong end;
 
 	mc->mpe_checksum = table_compute_checksum((void *)mp_next_mpc_entry(mc),
 						  mc->mpe_length);
 	mc->mpc_checksum = table_compute_checksum(mc, mc->mpc_length);
 	end = mp_next_mpe_entry(mc);
 
-	debug("Write the MP table at: %x - %x\n", (u32)mc, end);
+	debug("Write the MP table at: %lx - %lx\n", (ulong)mc, end);
 
 	return end;
 }
@@ -304,7 +304,8 @@
 	}
 
 	/* Get I/O interrupt information from device tree */
-	cell = fdt_getprop(blob, dev->of_offset, "intel,pirq-routing", &len);
+	cell = fdt_getprop(blob, dev_of_offset(dev), "intel,pirq-routing",
+			   &len);
 	if (!cell)
 		return -ENOENT;
 
@@ -365,13 +366,13 @@
 			 bus_isa, 0, MP_APIC_ALL, 1);
 }
 
-u32 write_mp_table(u32 addr)
+ulong write_mp_table(ulong addr)
 {
 	struct mp_config_table *mc;
 	int ioapic_id, ioapic_ver;
 	int bus_isa = 0xff;
 	int ret;
-	u32 end;
+	ulong end;
 
 	/* 16 byte align the table address */
 	addr = ALIGN(addr, 16);
diff --git a/arch/x86/lib/pinctrl_ich6.c b/arch/x86/lib/pinctrl_ich6.c
index 3f94cdf..406852d 100644
--- a/arch/x86/lib/pinctrl_ich6.c
+++ b/arch/x86/lib/pinctrl_ich6.c
@@ -104,7 +104,7 @@
 
 	/* if iobase is present, let's configure the pad */
 	if (iobase != -1) {
-		int iobase_addr;
+		ulong iobase_addr;
 
 		/*
 		 * The offset for the same pin for the IOBASE and GPIOBASE are
@@ -187,7 +187,7 @@
 		return -EINVAL;
 	}
 
-	for (pin_node = fdt_first_subnode(gd->fdt_blob, dev->of_offset);
+	for (pin_node = fdt_first_subnode(gd->fdt_blob, dev_of_offset(dev));
 	     pin_node > 0;
 	     pin_node = fdt_next_subnode(gd->fdt_blob, pin_node)) {
 		/* Configure the pin */
diff --git a/arch/x86/lib/pirq_routing.c b/arch/x86/lib/pirq_routing.c
index a93d355..5df3cab 100644
--- a/arch/x86/lib/pirq_routing.c
+++ b/arch/x86/lib/pirq_routing.c
@@ -11,9 +11,8 @@
 #include <asm/pci.h>
 #include <asm/pirq_routing.h>
 
-static bool irq_already_routed[16];
-
-static u8 pirq_get_next_free_irq(struct udevice *dev, u8 *pirq, u16 bitmap)
+static u8 pirq_get_next_free_irq(struct udevice *dev, u8 *pirq, u16 bitmap,
+				 bool irq_already_routed[])
 {
 	int i, link;
 	u8 irq = 0;
@@ -55,9 +54,11 @@
 {
 	unsigned char irq_slot[MAX_INTX_ENTRIES];
 	unsigned char pirq[CONFIG_MAX_PIRQ_LINKS];
+	bool irq_already_routed[16];
 	int i, intx;
 
 	memset(pirq, 0, CONFIG_MAX_PIRQ_LINKS);
+	memset(irq_already_routed, '\0', sizeof(irq_already_routed));
 
 	/* Set PCI IRQs */
 	for (i = 0; i < num; i++) {
@@ -83,7 +84,8 @@
 
 			/* yet not routed */
 			if (!pirq[link]) {
-				irq = pirq_get_next_free_irq(dev, pirq, bitmap);
+				irq = pirq_get_next_free_irq(dev, pirq, bitmap,
+						irq_already_routed);
 				pirq[link] = irq;
 			} else {
 				irq = pirq[link];
@@ -114,14 +116,14 @@
 	addr = ALIGN(addr, 16);
 
 	debug("Copying Interrupt Routing Table to 0x%x\n", addr);
-	memcpy((void *)addr, rt, rt->size);
+	memcpy((void *)(uintptr_t)addr, rt, rt->size);
 
 	/*
 	 * We do the sanity check here against the copied table after memcpy,
 	 * as something might go wrong after the memcpy, which is normally
 	 * due to the F segment decode is not turned on to systeam RAM.
 	 */
-	rom_rt = (struct irq_routing_table *)addr;
+	rom_rt = (struct irq_routing_table *)(uintptr_t)addr;
 	if (rom_rt->signature != PIRQ_SIGNATURE ||
 	    rom_rt->version != PIRQ_VERSION || rom_rt->size % 16) {
 		printf("Interrupt Routing Table not valid\n");
diff --git a/arch/x86/lib/relocate.c b/arch/x86/lib/relocate.c
index 0d683bf..1da5210 100644
--- a/arch/x86/lib/relocate.c
+++ b/arch/x86/lib/relocate.c
@@ -26,7 +26,7 @@
 
 int copy_uboot_to_ram(void)
 {
-	size_t len = (size_t)&__data_end - (size_t)&__text_start;
+	size_t len = (uintptr_t)&__data_end - (uintptr_t)&__text_start;
 
 	if (gd->flags & GD_FLG_SKIP_RELOC)
 		return 0;
@@ -38,7 +38,7 @@
 int clear_bss(void)
 {
 	ulong dst_addr = (ulong)&__bss_start + gd->reloc_off;
-	size_t len = (size_t)&__bss_end - (size_t)&__bss_start;
+	size_t len = (uintptr_t)&__bss_end - (uintptr_t)&__bss_start;
 
 	if (gd->flags & GD_FLG_SKIP_RELOC)
 		return 0;
@@ -47,38 +47,58 @@
 	return 0;
 }
 
-/*
- * This function has more error checking than you might expect. Please see
- * the commit message for more informaiton.
- */
-int do_elf_reloc_fixups(void)
+#if CONFIG_IS_ENABLED(X86_64)
+static void do_elf_reloc_fixups64(unsigned int text_base, uintptr_t size,
+				  Elf64_Rela *re_src, Elf64_Rela *re_end)
 {
-	Elf32_Rel *re_src = (Elf32_Rel *)(&__rel_dyn_start);
-	Elf32_Rel *re_end = (Elf32_Rel *)(&__rel_dyn_end);
+	Elf64_Addr *offset_ptr_rom, *last_offset = NULL;
+	Elf64_Addr *offset_ptr_ram;
 
-	Elf32_Addr *offset_ptr_rom, *last_offset = NULL;
-	Elf32_Addr *offset_ptr_ram;
-	unsigned int text_base = 0;
+	do {
+		/* Get the location from the relocation entry */
+		offset_ptr_rom = (Elf64_Addr *)(uintptr_t)re_src->r_offset;
 
-	/* The size of the region of u-boot that runs out of RAM. */
-	uintptr_t size = (uintptr_t)&__bss_end - (uintptr_t)&__text_start;
+		/* Check that the location of the relocation is in .text */
+		if (offset_ptr_rom >= (Elf64_Addr *)(uintptr_t)text_base &&
+		    offset_ptr_rom > last_offset) {
+			/* Switch to the in-RAM version */
+			offset_ptr_ram = (Elf64_Addr *)((ulong)offset_ptr_rom +
+							gd->reloc_off);
 
-	if (gd->flags & GD_FLG_SKIP_RELOC)
-		return 0;
-	if (re_src == re_end)
-		panic("No relocation data");
+			/* Check that the target points into .text */
+			if (*offset_ptr_ram >= text_base &&
+			    *offset_ptr_ram <= text_base + size) {
+				*offset_ptr_ram = gd->reloc_off +
+							re_src->r_addend;
+			} else {
+				debug("   %p: %lx: rom reloc %lx, ram %p, value %lx, limit %"
+				      PRIXPTR "\n",
+				      re_src, (ulong)re_src->r_info,
+				      (ulong)re_src->r_offset, offset_ptr_ram,
+				      (ulong)*offset_ptr_ram, text_base + size);
+			}
+		} else {
+			debug("   %p: %lx: rom reloc %lx, last %p\n", re_src,
+			      (ulong)re_src->r_info, (ulong)re_src->r_offset,
+			      last_offset);
+		}
+		last_offset = offset_ptr_rom;
 
-#ifdef CONFIG_SYS_TEXT_BASE
-	text_base = CONFIG_SYS_TEXT_BASE;
+	} while (++re_src < re_end);
+}
 #else
-	panic("No CONFIG_SYS_TEXT_BASE");
-#endif
+static void do_elf_reloc_fixups32(unsigned int text_base, uintptr_t size,
+				  Elf32_Rel *re_src, Elf32_Rel *re_end)
+{
+	Elf32_Addr *offset_ptr_rom, *last_offset = NULL;
+	Elf32_Addr *offset_ptr_ram;
+
 	do {
 		/* Get the location from the relocation entry */
-		offset_ptr_rom = (Elf32_Addr *)re_src->r_offset;
+		offset_ptr_rom = (Elf32_Addr *)(uintptr_t)re_src->r_offset;
 
 		/* Check that the location of the relocation is in .text */
-		if (offset_ptr_rom >= (Elf32_Addr *)text_base &&
+		if (offset_ptr_rom >= (Elf32_Addr *)(uintptr_t)text_base &&
 		    offset_ptr_rom > last_offset) {
 
 			/* Switch to the in-RAM version */
@@ -103,6 +123,38 @@
 		last_offset = offset_ptr_rom;
 
 	} while (++re_src < re_end);
+}
+#endif
+
+/*
+ * This function has more error checking than you might expect. Please see
+ * this commit message for more information:
+ *    62f7970a x86: Add error checking to x86 relocation code
+ */
+int do_elf_reloc_fixups(void)
+{
+	void *re_src = (void *)(&__rel_dyn_start);
+	void *re_end = (void *)(&__rel_dyn_end);
+	uint text_base;
+
+	/* The size of the region of u-boot that runs out of RAM. */
+	uintptr_t size = (uintptr_t)&__bss_end - (uintptr_t)&__text_start;
+
+	if (gd->flags & GD_FLG_SKIP_RELOC)
+		return 0;
+	if (re_src == re_end)
+		panic("No relocation data");
+
+#ifdef CONFIG_SYS_TEXT_BASE
+	text_base = CONFIG_SYS_TEXT_BASE;
+#else
+	panic("No CONFIG_SYS_TEXT_BASE");
+#endif
+#if CONFIG_IS_ENABLED(X86_64)
+	do_elf_reloc_fixups64(text_base, size, re_src, re_end);
+#else
+	do_elf_reloc_fixups32(text_base, size, re_src, re_end);
+#endif
 
 	return 0;
 }
diff --git a/arch/x86/lib/sfi.c b/arch/x86/lib/sfi.c
index 3d36580..507e037 100644
--- a/arch/x86/lib/sfi.c
+++ b/arch/x86/lib/sfi.c
@@ -38,14 +38,14 @@
 	tab->table[tab->count] = tab->entry_start;
 	tab->entry_start += sizeof(struct sfi_table_header);
 
-	return (void *)tab->entry_start;
+	return (void *)(uintptr_t)tab->entry_start;
 }
 
 static void finish_table(struct table_info *tab, const char *sig, void *entry)
 {
 	struct sfi_table_header *hdr;
 
-	hdr = (struct sfi_table_header *)(tab->base + tab->ptr);
+	hdr = (struct sfi_table_header *)(uintptr_t)(tab->base + tab->ptr);
 	strcpy(hdr->sig, sig);
 	hdr->len = sizeof(*hdr) + ((ulong)entry - tab->entry_start);
 	hdr->rev = 1;
@@ -131,7 +131,7 @@
 	return 0;
 }
 
-u32 write_sfi_table(u32 base)
+ulong write_sfi_table(ulong base)
 {
 	struct table_info table;
 
diff --git a/arch/x86/lib/spl.c b/arch/x86/lib/spl.c
new file mode 100644
index 0000000..ed2d40b
--- /dev/null
+++ b/arch/x86/lib/spl.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0
+ */
+
+#include <common.h>
+#include <debug_uart.h>
+#include <spl.h>
+#include <asm/cpu.h>
+#include <asm/init_helpers.h>
+#include <asm/mtrr.h>
+#include <asm/processor.h>
+#include <asm-generic/sections.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+__weak int arch_cpu_init_dm(void)
+{
+	return 0;
+}
+
+static int x86_spl_init(void)
+{
+	/*
+	 * TODO(sjg@chromium.org): We use this area of RAM for the stack
+	 * and global_data in SPL. Once U-Boot starts up and releocates it
+	 * is not needed. We could make this a CONFIG option or perhaps
+	 * place it immediately below CONFIG_SYS_TEXT_BASE.
+	 */
+	char *ptr = (char *)0x110000;
+	int ret;
+
+	debug("%s starting\n", __func__);
+	ret = spl_init();
+	if (ret) {
+		debug("%s: spl_init() failed\n", __func__);
+		return ret;
+	}
+	preloader_console_init();
+
+	ret = arch_cpu_init();
+	if (ret) {
+		debug("%s: arch_cpu_init() failed\n", __func__);
+		return ret;
+	}
+	ret = arch_cpu_init_dm();
+	if (ret) {
+		debug("%s: arch_cpu_init_dm() failed\n", __func__);
+		return ret;
+	}
+	ret = print_cpuinfo();
+	if (ret) {
+		debug("%s: print_cpuinfo() failed\n", __func__);
+		return ret;
+	}
+	ret = dram_init();
+	if (ret) {
+		debug("%s: dram_init() failed\n", __func__);
+		return ret;
+	}
+	memset(&__bss_start, 0, (ulong)&__bss_end - (ulong)&__bss_start);
+
+	/* TODO(sjg@chromium.org): Consider calling cpu_init_r() here */
+	ret = interrupt_init();
+	if (ret) {
+		debug("%s: interrupt_init() failed\n", __func__);
+		return ret;
+	}
+
+	/*
+	 * The stack grows down from ptr. Put the global data at ptr. This
+	 * will only be used for SPL. Once SPL loads U-Boot proper it will
+	 * set up its own stack.
+	 */
+	gd->new_gd = (struct global_data *)ptr;
+	memcpy(gd->new_gd, gd, sizeof(*gd));
+	arch_setup_gd(gd->new_gd);
+	gd->start_addr_sp = (ulong)ptr;
+
+	/* Cache the SPI flash. Otherwise copying the code to RAM takes ages */
+	ret = mtrr_add_request(MTRR_TYPE_WRBACK,
+			       (1ULL << 32) - CONFIG_XIP_ROM_SIZE,
+			       CONFIG_XIP_ROM_SIZE);
+	if (ret) {
+		debug("%s: SPI cache setup failed\n", __func__);
+		return ret;
+	}
+
+	return 0;
+}
+
+void board_init_f(ulong flags)
+{
+	int ret;
+
+	ret = x86_spl_init();
+	if (ret) {
+		debug("Error %d\n", ret);
+		hang();
+	}
+
+	/* Uninit CAR and jump to board_init_f_r() */
+	board_init_f_r_trampoline(gd->start_addr_sp);
+}
+
+void board_init_f_r(void)
+{
+	init_cache_f_r();
+	gd->flags &= ~GD_FLG_SERIAL_READY;
+	debug("cache status %d\n", dcache_status());
+	board_init_r(gd, 0);
+}
+
+u32 spl_boot_device(void)
+{
+	return BOOT_DEVICE_BOARD;
+}
+
+int spl_start_uboot(void)
+{
+	return 0;
+}
+
+void spl_board_announce_boot_device(void)
+{
+	printf("SPI flash");
+}
+
+static int spl_board_load_image(struct spl_image_info *spl_image,
+				struct spl_boot_device *bootdev)
+{
+	spl_image->size = CONFIG_SYS_MONITOR_LEN;
+	spl_image->entry_point = CONFIG_SYS_TEXT_BASE;
+	spl_image->load_addr = CONFIG_SYS_TEXT_BASE;
+	spl_image->os = IH_OS_U_BOOT;
+	spl_image->name = "U-Boot";
+
+	debug("Loading to %lx\n", spl_image->load_addr);
+
+	return 0;
+}
+SPL_LOAD_IMAGE_METHOD("SPI", 0, BOOT_DEVICE_BOARD, spl_board_load_image);
+
+int spl_spi_load_image(void)
+{
+	return -EPERM;
+}
+
+void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
+{
+	int ret;
+
+	printf("Jumping to 64-bit U-Boot: Note many features are missing\n");
+	ret = cpu_jump_to_64bit_uboot(spl_image->entry_point);
+	debug("ret=%d\n", ret);
+	while (1)
+		;
+}
diff --git a/arch/x86/lib/tables.c b/arch/x86/lib/tables.c
index 5966e58..4f5fe74 100644
--- a/arch/x86/lib/tables.c
+++ b/arch/x86/lib/tables.c
@@ -12,20 +12,13 @@
 #include <asm/acpi_table.h>
 #include <asm/coreboot_tables.h>
 
-#ifdef CONFIG_GENERATE_SMBIOS_TABLE
-static u32 write_smbios_table_wrapper(u32 addr)
-{
-	return write_smbios_table(addr);
-}
-#endif
-
 /**
  * Function prototype to write a specific configuration table
  *
  * @addr:	start address to write the table
  * @return:	end address of the table
  */
-typedef u32 (*table_write)(u32 addr);
+typedef ulong (*table_write)(ulong addr);
 
 static table_write table_write_funcs[] = {
 #ifdef CONFIG_GENERATE_PIRQ_TABLE
@@ -41,7 +34,7 @@
 	write_acpi_tables,
 #endif
 #ifdef CONFIG_GENERATE_SMBIOS_TABLE
-	write_smbios_table_wrapper,
+	write_smbios_table,
 #endif
 };
 
diff --git a/arch/x86/lib/zimage.c b/arch/x86/lib/zimage.c
index 1b33c77..b6b0f2b 100644
--- a/arch/x86/lib/zimage.c
+++ b/arch/x86/lib/zimage.c
@@ -165,7 +165,7 @@
 		 * A very old kernel MUST have its real-mode code
 		 * loaded at 0x90000
 		 */
-		if ((u32)setup_base != 0x90000) {
+		if ((ulong)setup_base != 0x90000) {
 			/* Copy the real-mode kernel */
 			memmove((void *)0x90000, setup_base, setup_size);
 
diff --git a/board/emulation/Kconfig b/board/emulation/Kconfig
index 36809fd..6d55dca 100644
--- a/board/emulation/Kconfig
+++ b/board/emulation/Kconfig
@@ -18,6 +18,13 @@
 	  supported by U-Boot. They are via QEMU '-M pc', an i440FX/PIIX
 	  chipset platform and '-M q35', a Q35/ICH9 chipset platform.
 
+config TARGET_QEMU_X86_64
+	bool "QEMU x86 64-bit"
+	help
+	  This is the QEMU emulated x86 64-bit board. With this config
+	  U-Boot is built as a 64-bit binary. This allows testing while
+	  this feature is being completed.
+
 endchoice
 
 source "board/emulation/qemu-x86/Kconfig"
diff --git a/board/emulation/qemu-x86/Kconfig b/board/emulation/qemu-x86/Kconfig
index c9181fc..a593f8c 100644
--- a/board/emulation/qemu-x86/Kconfig
+++ b/board/emulation/qemu-x86/Kconfig
@@ -1,4 +1,4 @@
-if TARGET_QEMU_X86
+if TARGET_QEMU_X86 || TARGET_QEMU_X86_64
 
 config SYS_BOARD
 	default "qemu-x86"
@@ -13,8 +13,8 @@
 	default "qemu-x86"
 
 config SYS_TEXT_BASE
-	default 0xfff00000 if !EFI_STUB
-	default 0x01110000 if EFI_STUB
+	default 0xfff00000 if !EFI_STUB && !SUPPORT_SPL
+	default 0x01110000 if EFI_STUB || SUPPORT_SPL
 
 config BOARD_SPECIFIC_OPTIONS # dummy
 	def_bool y
diff --git a/board/emulation/qemu-x86/MAINTAINERS b/board/emulation/qemu-x86/MAINTAINERS
index 54dc2c5..4cf8ac9 100644
--- a/board/emulation/qemu-x86/MAINTAINERS
+++ b/board/emulation/qemu-x86/MAINTAINERS
@@ -6,3 +6,10 @@
 F:	configs/qemu-x86_defconfig
 F:	configs/qemu-x86_efi_payload32_defconfig
 F:	configs/qemu-x86_efi_payload64_defconfig
+
+QEMU X86 64-bit BOARD
+M:	Bin Meng <bmeng.cn@gmail.com>
+S:	Maintained
+F:	board/emulation/qemu-x86/
+F:	include/configs/qemu-x86.h
+F:	configs/qemu-x86_64_defconfig
diff --git a/board/google/Kconfig b/board/google/Kconfig
index 7ba73a2..e56c026 100644
--- a/board/google/Kconfig
+++ b/board/google/Kconfig
@@ -22,6 +22,13 @@
 	  and it provides a 2560x1700 high resolution touch-enabled LCD
 	  display.
 
+config TARGET_CHROMEBOOK_LINK64
+	bool "Chromebook link 64-bit"
+	help
+	  This is the Chromebook Pixel released in 2013. With this config
+	  U-Boot is built as a 64-bit binary. This allows testing while this
+	  feature is being completed.
+
 config TARGET_CHROMEBOX_PANTHER
 	bool "Chromebox panther (not available)"
 	select n
diff --git a/board/google/chromebook_link/Kconfig b/board/google/chromebook_link/Kconfig
index fa12f33..8999b58 100644
--- a/board/google/chromebook_link/Kconfig
+++ b/board/google/chromebook_link/Kconfig
@@ -1,4 +1,4 @@
-if TARGET_CHROMEBOOK_LINK
+if TARGET_CHROMEBOOK_LINK || TARGET_CHROMEBOOK_LINK64
 
 config SYS_BOARD
 	default "chromebook_link"
@@ -13,7 +13,8 @@
 	default "chromebook_link"
 
 config SYS_TEXT_BASE
-	default 0xfff00000
+	default 0xfff00000 if !SUPPORT_SPL
+	default 0x10000000 if SUPPORT_SPL
 
 config BOARD_SPECIFIC_OPTIONS # dummy
 	def_bool y
diff --git a/board/google/chromebook_link/MAINTAINERS b/board/google/chromebook_link/MAINTAINERS
index bc253a2..e7aef53 100644
--- a/board/google/chromebook_link/MAINTAINERS
+++ b/board/google/chromebook_link/MAINTAINERS
@@ -4,3 +4,10 @@
 F:	board/google/chromebook_link/
 F:	include/configs/chromebook_link.h
 F:	configs/chromebook_link_defconfig
+
+CHROMEBOOK LINK 64-bit BOARD
+M:	Simon Glass <sjg@chromium.org>
+S:	Maintained
+F:	board/google/chromebook_link/
+F:	include/configs/chromebook_link.h
+F:	configs/chromebook_link64_defconfig
diff --git a/board/phytec/pcm052/pcm052.c b/board/phytec/pcm052/pcm052.c
index e75ff4f..54a4e4f 100644
--- a/board/phytec/pcm052/pcm052.c
+++ b/board/phytec/pcm052/pcm052.c
@@ -258,8 +258,7 @@
 		.wldqsen           = 25,
 	};
 
-	ddrmc_ctrl_init_ddr3(&pcm052_ddr_timings, pcm052_cr_settings,
-			     pcm052_phy_settings, 1, 2);
+    const int row_diff = 2;
 
 #elif defined(CONFIG_TARGET_BK4R1)
 
@@ -314,8 +313,7 @@
 		.wldqsen           = 25,
 	};
 
-	ddrmc_ctrl_init_ddr3(&pcm052_ddr_timings, pcm052_cr_settings,
-			     pcm052_phy_settings, 1, 1);
+    const int row_diff = 1;
 
 #else /* Unknown PCM052 variant */
 
@@ -325,6 +323,9 @@
 
 	imx_iomux_v3_setup_multiple_pads(pcm052_pads, ARRAY_SIZE(pcm052_pads));
 
+	ddrmc_ctrl_init_ddr3(&pcm052_ddr_timings, pcm052_cr_settings,
+			     pcm052_phy_settings, 1, row_diff);
+
 	gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE);
 
 	return 0;
diff --git a/board/qualcomm/dragonboard410c/dragonboard410c.c b/board/qualcomm/dragonboard410c/dragonboard410c.c
index 1fa5664..818ae04 100644
--- a/board/qualcomm/dragonboard410c/dragonboard410c.c
+++ b/board/qualcomm/dragonboard410c/dragonboard410c.c
@@ -44,7 +44,8 @@
 
 	/* Try to request gpios needed to start usb host on dragonboard */
 	if (!dm_gpio_is_valid(&hub_reset)) {
-		node = fdt_subnode_offset(gd->fdt_blob, pmic_gpio->of_offset,
+		node = fdt_subnode_offset(gd->fdt_blob,
+					  dev_of_offset(pmic_gpio),
 					  "usb_hub_reset_pm");
 		if (node < 0) {
 			printf("Failed to find usb_hub_reset_pm dt node.\n");
@@ -59,7 +60,8 @@
 	}
 
 	if (!dm_gpio_is_valid(&usb_sel)) {
-		node = fdt_subnode_offset(gd->fdt_blob, pmic_gpio->of_offset,
+		node = fdt_subnode_offset(gd->fdt_blob,
+					  dev_of_offset(pmic_gpio),
 					  "usb_sw_sel_pm");
 		if (node < 0) {
 			printf("Failed to find usb_sw_sel_pm dt node.\n");
@@ -110,7 +112,8 @@
 		return 0;
 	}
 
-	node = fdt_subnode_offset(gd->fdt_blob, pon->of_offset, "key_vol_down");
+	node = fdt_subnode_offset(gd->fdt_blob, dev_of_offset(pon),
+				  "key_vol_down");
 	if (node < 0) {
 		printf("Failed to find key_vol_down node. Check device tree\n");
 		return 0;
diff --git a/cmd/.gitignore b/cmd/.gitignore
new file mode 100644
index 0000000..bab889f
--- /dev/null
+++ b/cmd/.gitignore
@@ -0,0 +1,6 @@
+config_data.gz
+config_data_gz.h
+config_data_size.h
+license_data.gz
+license_data_gz.h
+license_data_size.h
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 4a0d489..ef53156 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -126,6 +126,18 @@
 	help
 	  Print board info
 
+config CMD_CONFIG
+	bool "config"
+	select BUILD_BIN2C
+	default SANDBOX
+	help
+	  Print ".config" contents.
+
+	  If this option is enabled, the ".config" file contents are embedded
+	  in the U-Boot image and can be printed on the console by the "config"
+	  command.  This provides information of which options are enabled on
+	  the running U-Boot.
+
 config CMD_CONSOLE
 	bool "coninfo"
 	default y
@@ -142,6 +154,7 @@
 
 config CMD_LICENSE
 	bool "license"
+	select BUILD_BIN2C
 	help
 	  Print GPL license text
 
@@ -346,6 +359,16 @@
 	help
 	  Display memory information.
 
+config CMD_UNZIP
+	bool "unzip"
+	help
+	  Uncompress a zip-compressed memory region.
+
+config CMD_ZIP
+	bool "zip"
+	help
+	  Compress a memory region with zlib deflate method.
+
 endmenu
 
 menu "Device access commands"
diff --git a/cmd/Makefile b/cmd/Makefile
index 566fed9..f13bb8c 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -31,6 +31,7 @@
 obj-$(CONFIG_CMD_CACHE) += cache.o
 obj-$(CONFIG_CMD_CBFS) += cbfs.o
 obj-$(CONFIG_CMD_CLK) += clk.o
+obj-$(CONFIG_CMD_CONFIG) += config.o
 obj-$(CONFIG_CMD_CONSOLE) += console.o
 obj-$(CONFIG_CMD_CPLBINFO) += cplbinfo.o
 obj-$(CONFIG_CMD_CPU) += cpu.o
@@ -165,3 +166,39 @@
 obj-y += nvedit.o
 
 obj-$(CONFIG_ARCH_MVEBU) += mvebu/
+
+filechk_data_gz = (echo "static const char data_gz[] ="; cat $< | scripts/bin2c; echo ";")
+
+filechk_data_size = \
+	(echo "static const size_t data_size = "; \
+	cat $< | wc -c; echo ";")
+
+# "config" command
+$(obj)/config.o: $(obj)/config_data_gz.h $(obj)/config_data_size.h
+
+targets += config_data.gz
+$(obj)/config_data.gz: $(KCONFIG_CONFIG) FORCE
+	$(call if_changed,gzip)
+
+targets += config_data_gz.h
+$(obj)/config_data_gz.h: $(obj)/config_data.gz FORCE
+	$(call filechk,data_gz)
+
+targets += config_data_size.h
+$(obj)/config_data_size.h: $(KCONFIG_CONFIG) FORCE
+	$(call filechk,data_size)
+
+# "license" command
+$(obj)/license.o: $(obj)/license_data_gz.h $(obj)/license_data_size.h
+
+targets += license_data.gz
+$(obj)/license_data.gz: $(srctree)/Licenses/gpl-2.0.txt FORCE
+	$(call if_changed,gzip)
+
+targets += license_data_gz.h
+$(obj)/license_data_gz.h: $(obj)/license_data.gz FORCE
+	$(call filechk,data_gz)
+
+targets += license_data_size.h
+$(obj)/license_data_size.h: $(srctree)/Licenses/gpl-2.0.txt FORCE
+	$(call filechk,data_size)
diff --git a/cmd/bootm.c b/cmd/bootm.c
index a7e181d..953a57d 100644
--- a/cmd/bootm.c
+++ b/cmd/bootm.c
@@ -390,7 +390,7 @@
 		return -ENOMEM;
 	}
 
-	ret = nand_read_skip_bad(mtd, off, &len, imgdata);
+	ret = nand_read_skip_bad(mtd, off, &len, NULL, mtd->size, imgdata);
 	if (ret < 0 && ret != -EUCLEAN) {
 		free(imgdata);
 		return ret;
@@ -430,7 +430,7 @@
 		return -ENOMEM;
 	}
 
-	ret = nand_read_skip_bad(mtd, off, &len, imgdata);
+	ret = nand_read_skip_bad(mtd, off, &len, NULL, mtd->size, imgdata);
 	if (ret < 0 && ret != -EUCLEAN) {
 		free(imgdata);
 		return ret;
diff --git a/cmd/config.c b/cmd/config.c
new file mode 100644
index 0000000..0c7f4e0
--- /dev/null
+++ b/cmd/config.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2017 Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include <malloc.h>
+
+#include "config_data_gz.h"
+#include "config_data_size.h"
+
+static int do_config(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	char *dst;
+	unsigned long len = data_size;
+	int ret = CMD_RET_SUCCESS;
+
+	dst = malloc(data_size + 1);
+	if (!dst)
+		return CMD_RET_FAILURE;
+
+	ret = gunzip(dst, data_size, (unsigned char *)data_gz, &len);
+	if (ret) {
+		printf("failed to uncompress .config data\n");
+		ret = CMD_RET_FAILURE;
+		goto free;
+	}
+
+	dst[data_size] = 0;
+	puts(dst);
+
+free:
+	free(dst);
+
+	return ret;
+}
+
+U_BOOT_CMD(
+	config, 1, 1, do_config,
+	"print .config",
+	""
+);
diff --git a/cmd/license.c b/cmd/license.c
index 5ee57f8..29fc8aa 100644
--- a/cmd/license.c
+++ b/cmd/license.c
@@ -6,31 +6,36 @@
  */
 
 #include <common.h>
-
-/* Licenses/gpl-2.0.txt is currently 18092 bytes in size */
-#define LICENSE_MAX	20480
-
 #include <command.h>
 #include <malloc.h>
-#include <license.h>
 
-int do_license(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+#include "license_data_gz.h"
+#include "license_data_size.h"
+
+static int do_license(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-	char *dst = malloc(LICENSE_MAX);
-	unsigned long len = LICENSE_MAX;
+	char *dst;
+	unsigned long len = data_size;
+	int ret = CMD_RET_SUCCESS;
 
+	dst = malloc(data_size + 1);
 	if (!dst)
-		return -1;
+		return CMD_RET_FAILURE;
 
-	if (gunzip(dst, LICENSE_MAX, license_gzip, &len) != 0) {
+	ret = gunzip(dst, data_size, (unsigned char *)data_gz, &len);
+	if (ret) {
 		printf("Error uncompressing license text\n");
-		free(dst);
-		return -1;
+		ret = CMD_RET_FAILURE;
+		goto free;
 	}
+
+	dst[data_size] = 0;
 	puts(dst);
+
+free:
 	free(dst);
 
-	return 0;
+	return ret;
 }
 
 U_BOOT_CMD(
diff --git a/common/board_f.c b/common/board_f.c
index 99c0b5a..ae6cd85 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -768,7 +768,8 @@
 }
 
 /* ARM calls relocate_code from its crt0.S */
-#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX)
+#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) && \
+		!CONFIG_IS_ENABLED(X86_64)
 
 static int jump_to_copy(void)
 {
@@ -845,7 +846,7 @@
 	return 0;
 }
 
-static init_fnc_t init_sequence_f[] = {
+static const init_fnc_t init_sequence_f[] = {
 #ifdef CONFIG_SANDBOX
 	setup_ram_buf,
 #endif
@@ -1032,13 +1033,14 @@
 	setup_reloc,
 #if defined(CONFIG_X86) || defined(CONFIG_ARC)
 	copy_uboot_to_ram,
-	clear_bss,
 	do_elf_reloc_fixups,
+	clear_bss,
 #endif
 #if defined(CONFIG_XTENSA)
 	clear_bss,
 #endif
-#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX)
+#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) && \
+		!CONFIG_IS_ENABLED(X86_64)
 	jump_to_copy,
 #endif
 	NULL,
@@ -1072,7 +1074,7 @@
 		hang();
 
 #if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) && \
-		!defined(CONFIG_EFI_APP)
+		!defined(CONFIG_EFI_APP) && !CONFIG_IS_ENABLED(X86_64)
 	/* NOTREACHED - jump_to_copy() does not return */
 	hang();
 #endif
@@ -1096,8 +1098,10 @@
  * NOTE: At present only x86 uses this route, but it is intended that
  * all archs will move to this when generic relocation is implemented.
  */
-static init_fnc_t init_sequence_f_r[] = {
+static const init_fnc_t init_sequence_f_r[] = {
+#if !CONFIG_IS_ENABLED(X86_64)
 	init_cache_f_r,
+#endif
 
 	NULL,
 };
diff --git a/common/board_r.c b/common/board_r.c
index 48fa4ee..8077280 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -737,7 +737,7 @@
  *
  * TODO: perhaps reset the watchdog in the initcall function after each call?
  */
-init_fnc_t init_sequence_r[] = {
+static init_fnc_t init_sequence_r[] = {
 	initr_trace,
 	initr_reloc,
 	/* TODO: could x86/PPC have this also perhaps? */
@@ -947,6 +947,16 @@
 
 void board_init_r(gd_t *new_gd, ulong dest_addr)
 {
+	/*
+	 * Set up the new global data pointer. So far only x86 does this
+	 * here.
+	 * TODO(sjg@chromium.org): Consider doing this for all archs, or
+	 * dropping the new_gd parameter.
+	 */
+#if CONFIG_IS_ENABLED(X86_64)
+	arch_setup_gd(new_gd);
+#endif
+
 #ifdef CONFIG_NEEDS_MANUAL_RELOC
 	int i;
 #endif
diff --git a/common/console.c b/common/console.c
index e1d8476..1232808 100644
--- a/common/console.c
+++ b/common/console.c
@@ -41,14 +41,14 @@
 	case env_op_create:
 	case env_op_overwrite:
 
-#ifdef CONFIG_CONSOLE_MUX
+#if CONFIG_IS_ENABLED(CONSOLE_MUX)
 		if (iomux_doenv(console, value))
 			return 1;
 #else
 		/* Try assigning specified device */
 		if (console_assign(console, value) < 0)
 			return 1;
-#endif /* CONFIG_CONSOLE_MUX */
+#endif
 		return 0;
 
 	case env_op_delete:
@@ -85,7 +85,7 @@
 U_BOOT_ENV_CALLBACK(silent, on_silent);
 #endif
 
-#ifdef CONFIG_SYS_CONSOLE_IS_IN_ENV
+#if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)
 /*
  * if overwrite_console returns 1, the stdin, stderr and stdout
  * are switched to the serial port, else the settings in the
@@ -98,7 +98,7 @@
 #define OVERWRITE_CONSOLE 0
 #endif /* CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE */
 
-#endif /* CONFIG_SYS_CONSOLE_IS_IN_ENV */
+#endif /* CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) */
 
 static int console_setfile(int file, struct stdio_dev * dev)
 {
@@ -145,7 +145,7 @@
 	return error;
 }
 
-#if defined(CONFIG_CONSOLE_MUX)
+#if CONFIG_IS_ENABLED(CONSOLE_MUX)
 /** Console I/O multiplexing *******************************************/
 
 static struct stdio_dev *tstcdev;
@@ -265,7 +265,7 @@
 {
 	console_setfile(file, dev);
 }
-#endif /* defined(CONFIG_CONSOLE_MUX) */
+#endif /* CONIFIG_IS_ENABLED(CONSOLE_MUX) */
 
 /** U-Boot INITIAL CONSOLE-NOT COMPATIBLE FUNCTIONS *************************/
 
@@ -290,7 +290,7 @@
 int fgetc(int file)
 {
 	if (file < MAX_FILES) {
-#if defined(CONFIG_CONSOLE_MUX)
+#if CONFIG_IS_ENABLED(CONSOLE_MUX)
 		/*
 		 * Effectively poll for input wherever it may be available.
 		 */
@@ -736,7 +736,7 @@
 	}
 }
 
-#ifdef CONFIG_SYS_CONSOLE_IS_IN_ENV
+#if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)
 /* Called after the relocation - use desired console functions */
 int console_init_r(void)
 {
@@ -745,7 +745,7 @@
 #ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE
 	int i;
 #endif /* CONFIG_SYS_CONSOLE_ENV_OVERWRITE */
-#ifdef CONFIG_CONSOLE_MUX
+#if CONFIG_IS_ENABLED(CONSOLE_MUX)
 	int iomux_err = 0;
 #endif
 
@@ -766,7 +766,7 @@
 		inputdev  = search_device(DEV_FLAGS_INPUT,  stdinname);
 		outputdev = search_device(DEV_FLAGS_OUTPUT, stdoutname);
 		errdev    = search_device(DEV_FLAGS_OUTPUT, stderrname);
-#ifdef CONFIG_CONSOLE_MUX
+#if CONFIG_IS_ENABLED(CONSOLE_MUX)
 		iomux_err = iomux_doenv(stdin, stdinname);
 		iomux_err += iomux_doenv(stdout, stdoutname);
 		iomux_err += iomux_doenv(stderr, stderrname);
@@ -799,7 +799,7 @@
 		console_doenv(stdin, inputdev);
 	}
 
-#ifdef CONFIG_CONSOLE_MUX
+#if CONFIG_IS_ENABLED(CONSOLE_MUX)
 done:
 #endif
 
@@ -829,7 +829,7 @@
 	return 0;
 }
 
-#else /* CONFIG_SYS_CONSOLE_IS_IN_ENV */
+#else /* !CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) */
 
 /* Called after the relocation - use desired console functions */
 int console_init_r(void)
@@ -873,7 +873,7 @@
 	if (outputdev != NULL) {
 		console_setfile(stdout, outputdev);
 		console_setfile(stderr, outputdev);
-#ifdef CONFIG_CONSOLE_MUX
+#if CONFIG_IS_ENABLED(CONSOLE_MUX)
 		console_devices[stdout][0] = outputdev;
 		console_devices[stderr][0] = outputdev;
 #endif
@@ -882,7 +882,7 @@
 	/* Initializes input console */
 	if (inputdev != NULL) {
 		console_setfile(stdin, inputdev);
-#ifdef CONFIG_CONSOLE_MUX
+#if CONFIG_IS_ENABLED(CONSOLE_MUX)
 		console_devices[stdin][0] = inputdev;
 #endif
 	}
@@ -907,4 +907,4 @@
 	return 0;
 }
 
-#endif /* CONFIG_SYS_CONSOLE_IS_IN_ENV */
+#endif /* CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) */
diff --git a/common/env_sf.c b/common/env_sf.c
index c53200f..27b4d12 100644
--- a/common/env_sf.c
+++ b/common/env_sf.c
@@ -19,16 +19,16 @@
 #include <dm/device-internal.h>
 
 #ifndef CONFIG_ENV_SPI_BUS
-# define CONFIG_ENV_SPI_BUS	0
+# define CONFIG_ENV_SPI_BUS	CONFIG_SF_DEFAULT_BUS
 #endif
 #ifndef CONFIG_ENV_SPI_CS
-# define CONFIG_ENV_SPI_CS	0
+# define CONFIG_ENV_SPI_CS	CONFIG_SF_DEFAULT_CS
 #endif
 #ifndef CONFIG_ENV_SPI_MAX_HZ
-# define CONFIG_ENV_SPI_MAX_HZ	1000000
+# define CONFIG_ENV_SPI_MAX_HZ	CONFIG_SF_DEFAULT_SPEED
 #endif
 #ifndef CONFIG_ENV_SPI_MODE
-# define CONFIG_ENV_SPI_MODE	SPI_MODE_3
+# define CONFIG_ENV_SPI_MODE	CONFIG_SF_DEFAULT_MODE
 #endif
 
 #ifdef CONFIG_ENV_OFFSET_REDUND
diff --git a/common/fdt_support.c b/common/fdt_support.c
index c9f7019..a57a575 100644
--- a/common/fdt_support.c
+++ b/common/fdt_support.c
@@ -903,14 +903,9 @@
 {
 	struct node_info *ni = node_info;
 	struct mtd_device *dev;
-	char *parts;
 	int i, idx;
 	int noff;
 
-	parts = getenv("mtdparts");
-	if (!parts)
-		return;
-
 	if (mtdparts_init() != 0)
 		return;
 
diff --git a/common/iomux.c b/common/iomux.c
index 3d8d00b..0e4e680 100644
--- a/common/iomux.c
+++ b/common/iomux.c
@@ -10,7 +10,7 @@
 #include <serial.h>
 #include <malloc.h>
 
-#ifdef CONFIG_CONSOLE_MUX
+#if CONFIG_IS_ENABLED(CONSOLE_MUX)
 void iomux_printdevs(const int console)
 {
 	int i;
@@ -145,4 +145,4 @@
 	free(cons_set);
 	return 0;
 }
-#endif /* CONFIG_CONSOLE_MUX */
+#endif /* CONSOLE_MUX */
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index b2ba492..cf714c2 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -149,6 +149,16 @@
 	  SHA256 variant is supported: SHA512 and others are not currently
 	  supported in U-Boot.
 
+config SPL_CPU_SUPPORT
+	bool "Support CPU drivers"
+	depends on SPL
+	help
+	  Enable this to support CPU drivers in SPL. These drivers can set
+	  up CPUs and provide information about them such as the model and
+	  name. This can be useful in SPL since setting up the CPUs earlier
+	  may improve boot performance. Enable this option to build the
+	  drivers in drivers/cpu as part of an SPL build.
+
 config SPL_CRYPTO_SUPPORT
 	bool "Support crypto drivers"
 	depends on SPL
@@ -425,6 +435,24 @@
 
 endif # SPL_OS_BOOT
 
+config SPL_PCI_SUPPORT
+	bool "Support PCI drivers"
+	depends on SPL
+	help
+	  Enable support for PCI in SPL. For platforms that need PCI to boot,
+	  or must perform some init using PCI in SPL, this provides the
+	  necessary driver support. This enables the drivers in drivers/pci
+	  as part of an SPL build.
+
+config SPL_PCH_SUPPORT
+	bool "Support PCH drivers"
+	depends on SPL
+	help
+	  Enable support for PCH (Platform Controller Hub) devices in SPL.
+	  These are used to set up GPIOs and the SPI peripheral early in
+	  boot. This enables the drivers in drivers/pch as part of an SPL
+	  build.
+
 config SPL_POST_MEM_SUPPORT
 	bool "Support POST drivers"
 	depends on SPL
@@ -465,6 +493,16 @@
 	  be already in memory when SPL takes over, e.g. loaded by the boot
 	  ROM.
 
+config SPL_RTC_SUPPORT
+	bool "Support RTC drivers"
+	depends on SPL
+	help
+	  Enable RTC (Real-time Clock) support in SPL. This includes support
+	  for reading and setting the time. Some RTC devices also have some
+	  non-volatile (battery-backed) memory which is accessible if
+	  needed. This enables the drivers in drivers/rtc as part of an SPL
+	  build.
+
 config SPL_SATA_SUPPORT
 	bool "Support loading from SATA"
 	depends on SPL
@@ -508,6 +546,15 @@
 	  enable SPI drivers that are needed for other purposes also, such
 	  as a SPI PMIC.
 
+config SPL_TIMER_SUPPORT
+	bool "Support timer drivers"
+	depends on SPL
+	help
+	  Enable support for timer drivers in SPL. These can be used to get
+	  a timer value when in SPL, or perhaps for implementing a delay
+	  function. This enables the drivers in drivers/timer as part of an
+	  SPL build.
+
 config SPL_USB_HOST_SUPPORT
 	bool "Support USB host drivers"
 	depends on SPL
diff --git a/common/spl/spl_spi.c b/common/spl/spl_spi.c
index cd1d6b2..925a1b1 100644
--- a/common/spl/spl_spi.c
+++ b/common/spl/spl_spi.c
@@ -96,8 +96,11 @@
 		/* Load u-boot, mkimage header is 64 bytes. */
 		err = spi_flash_read(flash, CONFIG_SYS_SPI_U_BOOT_OFFS, 0x40,
 				     (void *)header);
-		if (err)
+		if (err) {
+			debug("%s: Failed to read from SPI flash (err=%d)\n",
+			      __func__, err);
 			return err;
+		}
 
 		if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
 			image_get_magic(header) == FDT_MAGIC) {
diff --git a/common/usb_kbd.c b/common/usb_kbd.c
index 5f9a64a..d2d29cc 100644
--- a/common/usb_kbd.c
+++ b/common/usb_kbd.c
@@ -516,7 +516,7 @@
 		return error;
 
 	stdinname = getenv("stdin");
-#ifdef CONFIG_CONSOLE_MUX
+#if CONFIG_IS_ENABLED(CONSOLE_MUX)
 	error = iomux_doenv(stdin, stdinname);
 	if (error)
 		return error;
@@ -581,7 +581,7 @@
 		data = usb_kbd_dev->privptr;
 		if (stdio_deregister_dev(dev, force) != 0)
 			return 1;
-#ifdef CONFIG_CONSOLE_MUX
+#if CONFIG_IS_ENABLED(CONSOLE_MUX)
 		if (iomux_doenv(stdin, getenv("stdin")) != 0)
 			return 1;
 #endif
@@ -626,7 +626,7 @@
 		ret = -EPERM;
 		goto err;
 	}
-#ifdef CONFIG_CONSOLE_MUX
+#if CONFIG_IS_ENABLED(CONSOLE_MUX)
 	if (iomux_doenv(stdin, getenv("stdin"))) {
 		ret = -ENOLINK;
 		goto err;
diff --git a/configs/PMC440_defconfig b/configs/PMC440_defconfig
index 0bcc586..7380ba7 100644
--- a/configs/PMC440_defconfig
+++ b/configs/PMC440_defconfig
@@ -24,3 +24,4 @@
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
 CONFIG_OF_LIBFDT=y
+CONFIG_API=y
diff --git a/configs/brxre1_defconfig b/configs/brxre1_defconfig
index 0b7b082..dfa8712 100644
--- a/configs/brxre1_defconfig
+++ b/configs/brxre1_defconfig
@@ -31,6 +31,7 @@
 # CONFIG_CMD_XIMG is not set
 # CONFIG_CMD_EDITENV is not set
 # CONFIG_CMD_CRC32 is not set
+CONFIG_CMD_UNZIP=y
 # CONFIG_CMD_LOADB is not set
 # CONFIG_CMD_LOADS is not set
 # CONFIG_CMD_FLASH is not set
diff --git a/configs/chromebook_link64_defconfig b/configs/chromebook_link64_defconfig
new file mode 100644
index 0000000..c1d8e73
--- /dev/null
+++ b/configs/chromebook_link64_defconfig
@@ -0,0 +1,89 @@
+CONFIG_X86=y
+CONFIG_SPL_GPIO_SUPPORT=y
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_SPL_I2C_SUPPORT=y
+CONFIG_SPL_SERIAL_SUPPORT=y
+CONFIG_SPL_SPI_FLASH_SUPPORT=y
+CONFIG_SPL_SPI_SUPPORT=y
+CONFIG_X86_RUN_64BIT=y
+CONFIG_VENDOR_GOOGLE=y
+CONFIG_DEFAULT_DEVICE_TREE="chromebook_link"
+CONFIG_TARGET_CHROMEBOOK_LINK64=y
+CONFIG_ENABLE_MRC_CACHE=y
+CONFIG_HAVE_MRC=y
+CONFIG_SMP=y
+CONFIG_HAVE_VGA_BIOS=y
+CONFIG_FIT=y
+CONFIG_SPL_LOAD_FIT=y
+CONFIG_BOOTSTAGE=y
+CONFIG_BOOTSTAGE_REPORT=y
+CONFIG_SYS_CONSOLE_INFO_QUIET=y
+CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+CONFIG_SPL_CPU_SUPPORT=y
+CONFIG_SPL_NET_SUPPORT=y
+CONFIG_SPL_PCI_SUPPORT=y
+CONFIG_SPL_PCH_SUPPORT=y
+CONFIG_SPL_RTC_SUPPORT=y
+CONFIG_SPL_TIMER_SUPPORT=y
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_CPU=y
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_GPIO=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_DHCP=y
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_PING=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_BOOTSTAGE=y
+CONFIG_CMD_TPM=y
+CONFIG_CMD_TPM_TEST=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_SPL_OF_CONTROL=y
+CONFIG_SPL_DM=y
+CONFIG_REGMAP=y
+CONFIG_SPL_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_SPL_SYSCON=y
+CONFIG_CPU=y
+CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_INTEL=y
+CONFIG_CROS_EC=y
+CONFIG_CROS_EC_LPC=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_DM_PCI=y
+CONFIG_DM_RTC=y
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_BASE=0x3f8
+CONFIG_DEBUG_UART_CLOCK=1843200
+CONFIG_DEBUG_UART_BOARD_INIT=y
+CONFIG_SYS_NS16550=y
+CONFIG_ICH_SPI=y
+CONFIG_TIMER=y
+CONFIG_TPM_TIS_LPC=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_STORAGE=y
+CONFIG_DM_VIDEO=y
+CONFIG_USB_KEYBOARD=y
+CONFIG_VIDEO_VESA=y
+CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
+CONFIG_FRAMEBUFFER_VESA_MODE_11A=y
+CONFIG_VIDEO_IVYBRIDGE_IGD=y
+CONFIG_CONSOLE_SCROLL_LINES=5
+CONFIG_USE_PRIVATE_LIBGCC=y
+CONFIG_TPM=y
+# CONFIG_CMD_BOOTEFI_HELLO_COMPILE is not set
diff --git a/configs/chromebook_link_defconfig b/configs/chromebook_link_defconfig
index 1a79ab8..86852ad 100644
--- a/configs/chromebook_link_defconfig
+++ b/configs/chromebook_link_defconfig
@@ -1,5 +1,5 @@
 CONFIG_X86=y
-CONFIG_SYS_MALLOC_F_LEN=0x1800
+CONFIG_SYS_MALLOC_F_LEN=0x2000
 CONFIG_VENDOR_GOOGLE=y
 CONFIG_DEFAULT_DEVICE_TREE="chromebook_link"
 CONFIG_TARGET_CHROMEBOOK_LINK=y
@@ -61,8 +61,8 @@
 CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_USB_STORAGE=y
-CONFIG_USB_KEYBOARD=y
 CONFIG_DM_VIDEO=y
+CONFIG_USB_KEYBOARD=y
 CONFIG_VIDEO_VESA=y
 CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
 CONFIG_FRAMEBUFFER_VESA_MODE_11A=y
diff --git a/configs/dragonboard410c_defconfig b/configs/dragonboard410c_defconfig
index 8f206e2..e94f7b3 100644
--- a/configs/dragonboard410c_defconfig
+++ b/configs/dragonboard410c_defconfig
@@ -9,6 +9,7 @@
 # CONFIG_CMD_IMI is not set
 # CONFIG_CMD_IMLS is not set
 CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_UNZIP=y
 CONFIG_CMD_GPT=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_USB=y
diff --git a/configs/ethernut5_defconfig b/configs/ethernut5_defconfig
index c831aab..4d1b4b0 100644
--- a/configs/ethernut5_defconfig
+++ b/configs/ethernut5_defconfig
@@ -8,6 +8,7 @@
 CONFIG_SYS_PROMPT="U-Boot> "
 # CONFIG_CMD_BDI is not set
 CONFIG_CMD_ASKENV=y
+CONFIG_CMD_UNZIP=y
 # CONFIG_CMD_LOADS is not set
 CONFIG_CMD_MMC=y
 CONFIG_CMD_SF=y
diff --git a/configs/hikey_defconfig b/configs/hikey_defconfig
index 8dd330a..b112be2 100644
--- a/configs/hikey_defconfig
+++ b/configs/hikey_defconfig
@@ -7,6 +7,7 @@
 # CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_BOARD_EARLY_INIT_F=y
 # CONFIG_CMD_IMLS is not set
+CONFIG_CMD_UNZIP=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_USB=y
 CONFIG_CMD_GPIO=y
diff --git a/configs/icnova-a20-swac_defconfig b/configs/icnova-a20-swac_defconfig
index 567eb9b..5ef0e47 100644
--- a/configs/icnova-a20-swac_defconfig
+++ b/configs/icnova-a20-swac_defconfig
@@ -13,9 +13,10 @@
 CONFIG_VIDEO_LCD_PANEL_LVDS=y
 CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-icnova-swac"
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
-CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,CMD_BMP,CMD_UNZIP"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,CMD_BMP"
 CONFIG_SPL=y
 # CONFIG_CMD_IMLS is not set
+CONFIG_CMD_UNZIP=y
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_FPGA is not set
 # CONFIG_SPL_DOS_PARTITION is not set
diff --git a/configs/k2e_evm_defconfig b/configs/k2e_evm_defconfig
index 8f0d3fa..a42a485 100644
--- a/configs/k2e_evm_defconfig
+++ b/configs/k2e_evm_defconfig
@@ -8,7 +8,7 @@
 CONFIG_SPL_SERIAL_SUPPORT=y
 CONFIG_SPL_SPI_FLASH_SUPPORT=y
 CONFIG_SPL_SPI_SUPPORT=y
-CONFIG_DEFAULT_DEVICE_TREE="k2e-evm"
+CONFIG_DEFAULT_DEVICE_TREE="keystone-k2e-evm"
 CONFIG_OF_BOARD_SETUP=y
 CONFIG_SYS_CONSOLE_INFO_QUIET=y
 CONFIG_VERSION_VARIABLE=y
diff --git a/configs/k2g_evm_defconfig b/configs/k2g_evm_defconfig
index 17a5e67..f3ee01a 100644
--- a/configs/k2g_evm_defconfig
+++ b/configs/k2g_evm_defconfig
@@ -8,7 +8,7 @@
 CONFIG_SPL_SERIAL_SUPPORT=y
 CONFIG_SPL_SPI_FLASH_SUPPORT=y
 CONFIG_SPL_SPI_SUPPORT=y
-CONFIG_DEFAULT_DEVICE_TREE="k2g-evm"
+CONFIG_DEFAULT_DEVICE_TREE="keystone-k2g-evm"
 CONFIG_OF_BOARD_SETUP=y
 CONFIG_SYS_CONSOLE_INFO_QUIET=y
 CONFIG_VERSION_VARIABLE=y
diff --git a/configs/k2hk_evm_defconfig b/configs/k2hk_evm_defconfig
index 6791d56..d924796 100644
--- a/configs/k2hk_evm_defconfig
+++ b/configs/k2hk_evm_defconfig
@@ -8,7 +8,7 @@
 CONFIG_SPL_SERIAL_SUPPORT=y
 CONFIG_SPL_SPI_FLASH_SUPPORT=y
 CONFIG_SPL_SPI_SUPPORT=y
-CONFIG_DEFAULT_DEVICE_TREE="k2hk-evm"
+CONFIG_DEFAULT_DEVICE_TREE="keystone-k2hk-evm"
 CONFIG_OF_BOARD_SETUP=y
 CONFIG_SYS_CONSOLE_INFO_QUIET=y
 CONFIG_VERSION_VARIABLE=y
diff --git a/configs/k2l_evm_defconfig b/configs/k2l_evm_defconfig
index 4a70e1a..c817585 100644
--- a/configs/k2l_evm_defconfig
+++ b/configs/k2l_evm_defconfig
@@ -8,7 +8,7 @@
 CONFIG_SPL_SERIAL_SUPPORT=y
 CONFIG_SPL_SPI_FLASH_SUPPORT=y
 CONFIG_SPL_SPI_SUPPORT=y
-CONFIG_DEFAULT_DEVICE_TREE="k2l-evm"
+CONFIG_DEFAULT_DEVICE_TREE="keystone-k2l-evm"
 CONFIG_OF_BOARD_SETUP=y
 CONFIG_SYS_CONSOLE_INFO_QUIET=y
 CONFIG_VERSION_VARIABLE=y
diff --git a/configs/lsxhl_defconfig b/configs/lsxhl_defconfig
index 75bd46d..4d974f1 100644
--- a/configs/lsxhl_defconfig
+++ b/configs/lsxhl_defconfig
@@ -23,3 +23,4 @@
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
 CONFIG_OF_LIBFDT=y
+CONFIG_API=y
diff --git a/configs/qemu-x86_64_defconfig b/configs/qemu-x86_64_defconfig
new file mode 100644
index 0000000..484e2e9
--- /dev/null
+++ b/configs/qemu-x86_64_defconfig
@@ -0,0 +1,80 @@
+CONFIG_X86=y
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_SYS_MALLOC_F_LEN=0x1000
+CONFIG_MAX_CPUS=2
+CONFIG_SPL_SERIAL_SUPPORT=y
+CONFIG_SPL_ENV_SUPPORT=y
+CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
+CONFIG_SPL_SPI_FLASH_SUPPORT=y
+CONFIG_SPL_SPI_SUPPORT=y
+CONFIG_X86_RUN_64BIT=y
+CONFIG_DEFAULT_DEVICE_TREE="qemu-x86_i440fx"
+CONFIG_TARGET_QEMU_X86_64=y
+CONFIG_SMP=y
+CONFIG_GENERATE_PIRQ_TABLE=y
+CONFIG_GENERATE_MP_TABLE=y
+CONFIG_GENERATE_ACPI_TABLE=y
+CONFIG_FIT=y
+CONFIG_SPL_LOAD_FIT=y
+CONFIG_BOOTSTAGE=y
+CONFIG_BOOTSTAGE_REPORT=y
+CONFIG_SYS_CONSOLE_INFO_QUIET=y
+CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+CONFIG_SPL_CPU_SUPPORT=y
+CONFIG_SPL_NET_SUPPORT=y
+CONFIG_SPL_PCI_SUPPORT=y
+CONFIG_SPL_PCH_SUPPORT=y
+CONFIG_SPL_RTC_SUPPORT=y
+CONFIG_SPL_TIMER_SUPPORT=y
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_CPU=y
+# CONFIG_CMD_BOOTEFI_HELLO_COMPILE is not set
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_USB=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_DHCP=y
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_PING=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_QFW=y
+CONFIG_CMD_BOOTSTAGE=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_SPL_OF_CONTROL=y
+CONFIG_SPL_DM=y
+CONFIG_REGMAP=y
+CONFIG_SPL_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_SPL_SYSCON=y
+CONFIG_CPU=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_DM_ETH=y
+CONFIG_E1000=y
+CONFIG_DM_PCI=y
+CONFIG_DM_RTC=y
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_BASE=0x3f8
+CONFIG_DEBUG_UART_CLOCK=1843200
+CONFIG_SYS_NS16550=y
+CONFIG_TIMER=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_KEYBOARD=y
+CONFIG_DM_VIDEO=y
+CONFIG_VIDEO_VESA=y
+CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
+CONFIG_FRAMEBUFFER_VESA_MODE_111=y
+CONFIG_CONSOLE_SCROLL_LINES=5
+CONFIG_USE_PRIVATE_LIBGCC=y
diff --git a/configs/vexpress_aemv8a_dram_defconfig b/configs/vexpress_aemv8a_dram_defconfig
index c899be0..db492af 100644
--- a/configs/vexpress_aemv8a_dram_defconfig
+++ b/configs/vexpress_aemv8a_dram_defconfig
@@ -14,6 +14,7 @@
 # CONFIG_CMD_EDITENV is not set
 # CONFIG_CMD_ENV_EXISTS is not set
 CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_UNZIP=y
 # CONFIG_CMD_LOADS is not set
 CONFIG_CMD_ARMFLASH=y
 # CONFIG_CMD_FPGA is not set
diff --git a/configs/vexpress_aemv8a_juno_defconfig b/configs/vexpress_aemv8a_juno_defconfig
index 2267362..537301c 100644
--- a/configs/vexpress_aemv8a_juno_defconfig
+++ b/configs/vexpress_aemv8a_juno_defconfig
@@ -14,6 +14,7 @@
 # CONFIG_CMD_EDITENV is not set
 # CONFIG_CMD_ENV_EXISTS is not set
 CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_UNZIP=y
 # CONFIG_CMD_LOADS is not set
 CONFIG_CMD_ARMFLASH=y
 # CONFIG_CMD_FPGA is not set
diff --git a/configs/vexpress_aemv8a_semi_defconfig b/configs/vexpress_aemv8a_semi_defconfig
index 02740a4..2720a71 100644
--- a/configs/vexpress_aemv8a_semi_defconfig
+++ b/configs/vexpress_aemv8a_semi_defconfig
@@ -14,6 +14,7 @@
 # CONFIG_CMD_EDITENV is not set
 # CONFIG_CMD_ENV_EXISTS is not set
 CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_UNZIP=y
 # CONFIG_CMD_LOADS is not set
 CONFIG_CMD_ARMFLASH=y
 # CONFIG_CMD_FPGA is not set
diff --git a/configs/xilinx_zynqmp_ep_defconfig b/configs/xilinx_zynqmp_ep_defconfig
index 49c0786..6b568b4 100644
--- a/configs/xilinx_zynqmp_ep_defconfig
+++ b/configs/xilinx_zynqmp_ep_defconfig
@@ -21,6 +21,7 @@
 # CONFIG_CMD_XIMG is not set
 # CONFIG_CMD_EDITENV is not set
 # CONFIG_CMD_ENV_EXISTS is not set
+CONFIG_CMD_UNZIP=y
 # CONFIG_CMD_LOADB is not set
 # CONFIG_CMD_LOADS is not set
 CONFIG_CMD_GPT=y
diff --git a/configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig b/configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig
index a3585d0..4d7bcf3 100644
--- a/configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig
+++ b/configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig
@@ -19,6 +19,7 @@
 CONFIG_SYS_PROMPT="ZynqMP> "
 # CONFIG_CMD_IMLS is not set
 CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_UNZIP=y
 # CONFIG_CMD_FLASH is not set
 CONFIG_CMD_GPT=y
 CONFIG_CMD_MMC=y
diff --git a/configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig b/configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig
index 3693d9b..822b25d 100644
--- a/configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig
+++ b/configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig
@@ -21,6 +21,7 @@
 CONFIG_SYS_PROMPT="ZynqMP> "
 # CONFIG_CMD_IMLS is not set
 CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_UNZIP=y
 # CONFIG_CMD_FLASH is not set
 CONFIG_CMD_GPT=y
 CONFIG_CMD_NAND=y
diff --git a/configs/xilinx_zynqmp_zc1751_xm018_dc4_defconfig b/configs/xilinx_zynqmp_zc1751_xm018_dc4_defconfig
index a4c73f8..89813df 100644
--- a/configs/xilinx_zynqmp_zc1751_xm018_dc4_defconfig
+++ b/configs/xilinx_zynqmp_zc1751_xm018_dc4_defconfig
@@ -16,6 +16,7 @@
 CONFIG_SYS_PROMPT="ZynqMP> "
 # CONFIG_CMD_IMLS is not set
 CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_UNZIP=y
 # CONFIG_CMD_FLASH is not set
 CONFIG_CMD_MMC=y
 CONFIG_CMD_I2C=y
diff --git a/configs/xilinx_zynqmp_zc1751_xm019_dc5_defconfig b/configs/xilinx_zynqmp_zc1751_xm019_dc5_defconfig
index f981b21..b8fe33e 100644
--- a/configs/xilinx_zynqmp_zc1751_xm019_dc5_defconfig
+++ b/configs/xilinx_zynqmp_zc1751_xm019_dc5_defconfig
@@ -17,6 +17,7 @@
 CONFIG_SYS_PROMPT="ZynqMP> "
 # CONFIG_CMD_IMLS is not set
 CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_UNZIP=y
 # CONFIG_CMD_FLASH is not set
 CONFIG_CMD_MMC=y
 CONFIG_CMD_I2C=y
diff --git a/configs/xilinx_zynqmp_zcu102_defconfig b/configs/xilinx_zynqmp_zcu102_defconfig
index 7b65fe0..b13bf5b 100644
--- a/configs/xilinx_zynqmp_zcu102_defconfig
+++ b/configs/xilinx_zynqmp_zcu102_defconfig
@@ -19,6 +19,7 @@
 CONFIG_SYS_PROMPT="ZynqMP> "
 # CONFIG_CMD_IMLS is not set
 CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_UNZIP=y
 # CONFIG_CMD_FLASH is not set
 CONFIG_CMD_GPT=y
 CONFIG_CMD_MMC=y
diff --git a/configs/xilinx_zynqmp_zcu102_revB_defconfig b/configs/xilinx_zynqmp_zcu102_revB_defconfig
index 4bed589..2489d89 100644
--- a/configs/xilinx_zynqmp_zcu102_revB_defconfig
+++ b/configs/xilinx_zynqmp_zcu102_revB_defconfig
@@ -19,6 +19,7 @@
 CONFIG_SYS_PROMPT="ZynqMP> "
 # CONFIG_CMD_IMLS is not set
 CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_UNZIP=y
 # CONFIG_CMD_FLASH is not set
 CONFIG_CMD_GPT=y
 CONFIG_CMD_MMC=y
diff --git a/disk/part_efi.c b/disk/part_efi.c
index b5928e5..893cbbd 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -324,6 +324,13 @@
 		printf("%s: calloc failed!\n", __func__);
 		return -1;
 	}
+
+	/* Read MBR to backup boot code if it exists */
+	if (blk_dread(dev_desc, 0, 1, p_mbr) != 1) {
+		error("** Can't read from device %d **\n", dev_desc->devnum);
+		return -1;
+	}
+
 	/* Append signature */
 	p_mbr->signature = MSDOS_MBR_SIGNATURE;
 	p_mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT;
diff --git a/doc/driver-model/README.txt b/doc/driver-model/README.txt
index 1b5ccec..fea324e 100644
--- a/doc/driver-model/README.txt
+++ b/doc/driver-model/README.txt
@@ -684,7 +684,7 @@
 
    g. If the driver provides an ofdata_to_platdata() method, then this is
    called to convert the device tree data into platform data. This should
-   do various calls like fdtdec_get_int(gd->fdt_blob, dev->of_offset, ...)
+   do various calls like fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), ...)
    to access the node and store the resulting information into dev->platdata.
    After this point, the device works the same way whether it was bound
    using a device tree node or U_BOOT_DEVICE() structure. In either case,
diff --git a/doc/driver-model/of-plat.txt b/doc/driver-model/of-plat.txt
index 86e5e25..0063bfe 100644
--- a/doc/driver-model/of-plat.txt
+++ b/doc/driver-model/of-plat.txt
@@ -205,7 +205,7 @@
             /* Decode the device tree data */
             struct mmc_platdata *plat = dev_get_platdata(dev);
             const void *blob = gd->fdt_blob;
-            int node = dev->of_offset;
+            int node = dev_of_offset(dev);
 
             plat->fifo_depth = fdtdec_get_int(blob, node, "fifo-depth", 0);
     #endif
diff --git a/doc/driver-model/spi-howto.txt b/doc/driver-model/spi-howto.txt
index ee4abf4..1955ffe 100644
--- a/doc/driver-model/spi-howto.txt
+++ b/doc/driver-model/spi-howto.txt
@@ -223,7 +223,7 @@
 {
 	struct exynos_spi_platdata *plat = bus->platdata;
 	const void *blob = gd->fdt_blob;
-	int node = bus->of_offset;
+	int node = dev_of_offset(bus);
 
 	plat->regs = (struct exynos_spi *)fdtdec_get_addr(blob, node, "reg");
 	plat->periph_id = pinmux_decode_periph_id(blob, node);
diff --git a/drivers/Makefile b/drivers/Makefile
index c19fa14..34c55bf 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -10,6 +10,7 @@
 
 ifdef CONFIG_SPL_BUILD
 
+obj-$(CONFIG_SPL_CPU_SUPPORT) += cpu/
 obj-$(CONFIG_SPL_CRYPTO_SUPPORT) += crypto/
 obj-$(CONFIG_SPL_I2C_SUPPORT) += i2c/
 obj-$(CONFIG_SPL_GPIO_SUPPORT) += gpio/
@@ -32,6 +33,10 @@
 obj-$(CONFIG_SPL_ETH_SUPPORT) += net/
 obj-$(CONFIG_SPL_ETH_SUPPORT) += net/phy/
 obj-$(CONFIG_SPL_USBETH_SUPPORT) += net/phy/
+obj-$(CONFIG_SPL_PCI_SUPPORT) += pci/
+obj-$(CONFIG_SPL_PCH_SUPPORT) += pch/
+obj-$(CONFIG_SPL_RTC_SUPPORT) += rtc/
+obj-$(CONFIG_SPL_TIMER_SUPPORT) += timer/
 obj-$(CONFIG_SPL_MUSB_NEW_SUPPORT) += usb/musb-new/
 obj-$(CONFIG_SPL_USB_GADGET_SUPPORT) += usb/gadget/
 obj-$(CONFIG_SPL_USB_GADGET_SUPPORT) += usb/gadget/udc/
diff --git a/drivers/adc/adc-uclass.c b/drivers/adc/adc-uclass.c
index 9233fcd..3e28a56 100644
--- a/drivers/adc/adc-uclass.c
+++ b/drivers/adc/adc-uclass.c
@@ -345,7 +345,7 @@
 static int adc_vdd_platdata_set(struct udevice *dev)
 {
 	struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
-	int ret, offset = dev->of_offset;
+	int ret, offset = dev_of_offset(dev);
 	const void *fdt = gd->fdt_blob;
 	char *prop;
 
@@ -366,7 +366,7 @@
 static int adc_vss_platdata_set(struct udevice *dev)
 {
 	struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
-	int ret, offset = dev->of_offset;
+	int ret, offset = dev_of_offset(dev);
 	const void *fdt = gd->fdt_blob;
 	char *prop;
 
diff --git a/drivers/clk/aspeed/clk_ast2500.c b/drivers/clk/aspeed/clk_ast2500.c
index af369cc..26a5e58 100644
--- a/drivers/clk/aspeed/clk_ast2500.c
+++ b/drivers/clk/aspeed/clk_ast2500.c
@@ -35,7 +35,7 @@
 	const ulong post_div = (mpll_reg >> SCU_MPLL_POST_SHIFT)
 			& SCU_MPLL_POST_MASK;
 
-	return (clkin * ((num + 1) / (denum + 1))) / post_div;
+	return (clkin * ((num + 1) / (denum + 1))) / (post_div + 1);
 }
 
 /*
@@ -50,7 +50,7 @@
 	const ulong post_div = (hpll_reg >> SCU_HPLL_POST_SHIFT)
 			& SCU_HPLL_POST_MASK;
 
-	return (clkin * ((num + 1) / (denum + 1))) / post_div;
+	return (clkin * ((num + 1) / (denum + 1))) / (post_div + 1);
 }
 
 static ulong ast2500_get_clkin(struct ast2500_scu *scu)
diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c
index d36f64f..ac27d3e 100644
--- a/drivers/clk/at91/clk-generated.c
+++ b/drivers/clk/at91/clk-generated.c
@@ -154,9 +154,8 @@
 	u32 num_parents;
 
 	num_parents = fdtdec_get_int_array_count(gd->fdt_blob,
-						 dev_get_parent(dev)->of_offset,
-						 "clocks", cells,
-						 GENERATED_SOURCE_MAX);
+			dev_of_offset(dev_get_parent(dev)), "clocks", cells,
+			GENERATED_SOURCE_MAX);
 
 	if (!num_parents)
 		return -1;
diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
index 76ba91a..c73156a 100644
--- a/drivers/clk/at91/pmc.c
+++ b/drivers/clk/at91/pmc.c
@@ -47,7 +47,7 @@
 int at91_clk_sub_device_bind(struct udevice *dev, const char *drv_name)
 {
 	const void *fdt = gd->fdt_blob;
-	int offset = dev->of_offset;
+	int offset = dev_of_offset(dev);
 	bool pre_reloc_only = !(gd->flags & GD_FLG_RELOC);
 	const char *name;
 	int ret;
@@ -90,7 +90,8 @@
 		return -EINVAL;
 	}
 
-	periph = fdtdec_get_uint(gd->fdt_blob, clk->dev->of_offset, "reg", -1);
+	periph = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(clk->dev), "reg",
+				 -1);
 	if (periph < 0)
 		return -EINVAL;
 
diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index 153ceba..6fcfd69 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -65,7 +65,7 @@
 	debug("%s(dev=%p, index=%d, clk=%p)\n", __func__, dev, index, clk);
 
 	assert(clk);
-	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset,
+	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
 					     "clocks", "#clock-cells", 0, index,
 					     &args);
 	if (ret) {
@@ -104,7 +104,7 @@
 
 	debug("%s(dev=%p, name=%s, clk=%p)\n", __func__, dev, name, clk);
 
-	index = fdt_stringlist_search(gd->fdt_blob, dev->of_offset,
+	index = fdt_stringlist_search(gd->fdt_blob, dev_of_offset(dev),
 				      "clock-names", name);
 	if (index < 0) {
 		debug("fdt_stringlist_search() failed: %d\n", index);
diff --git a/drivers/clk/clk_fixed_rate.c b/drivers/clk/clk_fixed_rate.c
index 9c4d2b3..3911bf6 100644
--- a/drivers/clk/clk_fixed_rate.c
+++ b/drivers/clk/clk_fixed_rate.c
@@ -32,7 +32,7 @@
 {
 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
 	to_clk_fixed_rate(dev)->fixed_rate =
-				fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+				fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 					       "clock-frequency", 0);
 #endif
 
diff --git a/drivers/clk/clk_pic32.c b/drivers/clk/clk_pic32.c
index 70ec354..f6eef31 100644
--- a/drivers/clk/clk_pic32.c
+++ b/drivers/clk/clk_pic32.c
@@ -330,7 +330,7 @@
 	for (i = REF1CLK; i <= REF5CLK; i++) {
 		snprintf(propname, sizeof(propname),
 			 "microchip,refo%d-frequency", i - REF1CLK + 1);
-		rate = fdtdec_get_int(blob, dev->of_offset, propname, 0);
+		rate = fdtdec_get_int(blob, dev_of_offset(dev), propname, 0);
 		if (rate)
 			pic32_set_refclk(priv, i, pll_hz, rate, ROCLK_SRC_SPLL);
 	}
@@ -393,7 +393,8 @@
 	fdt_addr_t addr;
 	fdt_size_t size;
 
-	addr = fdtdec_get_addr_size(gd->fdt_blob, dev->of_offset, "reg", &size);
+	addr = fdtdec_get_addr_size(gd->fdt_blob, dev_of_offset(dev), "reg",
+				    &size);
 	if (addr == FDT_ADDR_T_NONE)
 		return -EINVAL;
 
diff --git a/drivers/core/device.c b/drivers/core/device.c
index ed553d7..70fcfc2 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -355,7 +355,7 @@
 			goto fail;
 	}
 
-	if (drv->ofdata_to_platdata && dev->of_offset >= 0) {
+	if (drv->ofdata_to_platdata && dev_of_offset(dev) >= 0) {
 		ret = drv->ofdata_to_platdata(dev);
 		if (ret)
 			goto fail;
@@ -524,7 +524,7 @@
 	*devp = NULL;
 
 	list_for_each_entry(dev, &parent->child_head, sibling_node) {
-		if (dev->of_offset == of_offset) {
+		if (dev_of_offset(dev) == of_offset) {
 			*devp = dev;
 			return 0;
 		}
@@ -549,7 +549,7 @@
 {
 	struct udevice *dev, *found;
 
-	if (parent->of_offset == of_offset)
+	if (dev_of_offset(parent) == of_offset)
 		return parent;
 
 	list_for_each_entry(dev, &parent->child_head, sibling_node) {
@@ -637,19 +637,21 @@
 		int len = 0;
 		int na, ns;
 
-		na = fdt_address_cells(gd->fdt_blob, dev->parent->of_offset);
+		na = fdt_address_cells(gd->fdt_blob,
+				       dev_of_offset(dev->parent));
 		if (na < 1) {
 			debug("bad #address-cells\n");
 			return FDT_ADDR_T_NONE;
 		}
 
-		ns = fdt_size_cells(gd->fdt_blob, dev->parent->of_offset);
+		ns = fdt_size_cells(gd->fdt_blob, dev_of_offset(dev->parent));
 		if (ns < 0) {
 			debug("bad #size-cells\n");
 			return FDT_ADDR_T_NONE;
 		}
 
-		reg = fdt_getprop(gd->fdt_blob, dev->of_offset, "reg", &len);
+		reg = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "reg",
+				  &len);
 		if (!reg || (len <= (index * sizeof(fdt32_t) * (na + ns)))) {
 			debug("Req index out of range\n");
 			return FDT_ADDR_T_NONE;
@@ -662,16 +664,15 @@
 		 * bus setups.
 		 */
 		addr = fdt_translate_address((void *)gd->fdt_blob,
-					     dev->of_offset, reg);
+					     dev_of_offset(dev), reg);
 	} else {
 		/*
 		 * Use the "simple" translate function for less complex
 		 * bus setups.
 		 */
 		addr = fdtdec_get_addr_size_auto_parent(gd->fdt_blob,
-							dev->parent->of_offset,
-							dev->of_offset, "reg",
-							index, NULL, false);
+				dev_of_offset(dev->parent), dev_of_offset(dev),
+				"reg", index, NULL, false);
 		if (CONFIG_IS_ENABLED(SIMPLE_BUS) && addr != FDT_ADDR_T_NONE) {
 			if (device_get_uclass_id(dev->parent) ==
 			    UCLASS_SIMPLE_BUS)
@@ -702,7 +703,7 @@
 	 * next call to the exisiting dev_get_xxx function which handles
 	 * all config options.
 	 */
-	fdtdec_get_addr_size_auto_noparent(gd->fdt_blob, dev->of_offset,
+	fdtdec_get_addr_size_auto_noparent(gd->fdt_blob, dev_of_offset(dev),
 					   "reg", index, size, false);
 
 	/*
@@ -720,7 +721,7 @@
 #if CONFIG_IS_ENABLED(OF_CONTROL)
 	int index;
 
-	index = fdt_stringlist_search(gd->fdt_blob, dev->of_offset,
+	index = fdt_stringlist_search(gd->fdt_blob, dev_of_offset(dev),
 				      "reg-names", name);
 	if (index < 0)
 		return index;
@@ -799,7 +800,7 @@
 {
 	const void *fdt = gd->fdt_blob;
 
-	return !fdt_node_check_compatible(fdt, dev->of_offset, compat);
+	return !fdt_node_check_compatible(fdt, dev_of_offset(dev), compat);
 }
 
 bool of_machine_is_compatible(const char *compat)
diff --git a/drivers/core/regmap.c b/drivers/core/regmap.c
index c68bcba..833cd78 100644
--- a/drivers/core/regmap.c
+++ b/drivers/core/regmap.c
@@ -71,12 +71,12 @@
 	int parent;
 	int len;
 
-	parent = dev->parent->of_offset;
+	parent = dev_of_offset(dev->parent);
 	addr_len = fdt_address_cells(blob, parent);
 	size_len = fdt_size_cells(blob, parent);
 	both_len = addr_len + size_len;
 
-	cell = fdt_getprop(blob, dev->of_offset, "reg", &len);
+	cell = fdt_getprop(blob, dev_of_offset(dev), "reg", &len);
 	len /= sizeof(*cell);
 	count = len / both_len;
 	if (!cell || !count)
diff --git a/drivers/core/root.c b/drivers/core/root.c
index 9edfc1e..175fd3f 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -227,10 +227,10 @@
 
 int dm_scan_fdt_dev(struct udevice *dev)
 {
-	if (dev->of_offset == -1)
+	if (dev_of_offset(dev) == -1)
 		return 0;
 
-	return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset,
+	return dm_scan_fdt_node(dev, gd->fdt_blob, dev_of_offset(dev),
 				gd->flags & GD_FLG_RELOC ? false : true);
 }
 
diff --git a/drivers/core/simple-bus.c b/drivers/core/simple-bus.c
index 5c955da..a300217 100644
--- a/drivers/core/simple-bus.c
+++ b/drivers/core/simple-bus.c
@@ -27,10 +27,13 @@
 
 static int simple_bus_post_bind(struct udevice *dev)
 {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+	return 0;
+#else
 	u32 cell[3];
 	int ret;
 
-	ret = fdtdec_get_int_array(gd->fdt_blob, dev->of_offset, "ranges",
+	ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev), "ranges",
 				   cell, ARRAY_SIZE(cell));
 	if (!ret) {
 		struct simple_bus_plat *plat = dev_get_uclass_platdata(dev);
@@ -41,6 +44,7 @@
 	}
 
 	return dm_scan_fdt_dev(dev);
+#endif
 }
 
 UCLASS_DRIVER(simple_bus) = {
diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index 60610e5..7de3706 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -278,7 +278,7 @@
 		return ret;
 
 	list_for_each_entry(dev, &uc->dev_head, uclass_node) {
-		if (dev->of_offset == node) {
+		if (dev_of_offset(dev) == node) {
 			*devp = dev;
 			return 0;
 		}
@@ -299,7 +299,7 @@
 	int ret;
 
 	*devp = NULL;
-	find_phandle = fdtdec_get_int(gd->fdt_blob, parent->of_offset, name,
+	find_phandle = fdtdec_get_int(gd->fdt_blob, dev_of_offset(parent), name,
 				      -1);
 	if (find_phandle <= 0)
 		return -ENOENT;
@@ -308,7 +308,9 @@
 		return ret;
 
 	list_for_each_entry(dev, &uc->dev_head, uclass_node) {
-		uint phandle = fdt_get_phandle(gd->fdt_blob, dev->of_offset);
+		uint phandle;
+
+		phandle = fdt_get_phandle(gd->fdt_blob, dev_of_offset(dev));
 
 		if (phandle == find_phandle) {
 			*devp = dev;
diff --git a/drivers/demo/demo-shape.c b/drivers/demo/demo-shape.c
index d908736..7e71f3b 100644
--- a/drivers/demo/demo-shape.c
+++ b/drivers/demo/demo-shape.c
@@ -151,7 +151,7 @@
 		return ret;
 
 	/* Parse the data that only we need */
-	pdata->default_char = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+	pdata->default_char = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 					     "character", '@');
 
 	return 0;
diff --git a/drivers/demo/demo-uclass.c b/drivers/demo/demo-uclass.c
index 725f068..3341572 100644
--- a/drivers/demo/demo-uclass.c
+++ b/drivers/demo/demo-uclass.c
@@ -66,7 +66,7 @@
 int demo_parse_dt(struct udevice *dev)
 {
 	struct dm_demo_pdata *pdata = dev_get_platdata(dev);
-	int dn = dev->of_offset;
+	int dn = dev_of_offset(dev);
 
 	pdata->sides = fdtdec_get_int(gd->fdt_blob, dn, "sides", 0);
 	pdata->colour = fdt_getprop(gd->fdt_blob, dn, "colour", NULL);
diff --git a/drivers/gpio/74x164_gpio.c b/drivers/gpio/74x164_gpio.c
index 9ac10a7..750eedf 100644
--- a/drivers/gpio/74x164_gpio.c
+++ b/drivers/gpio/74x164_gpio.c
@@ -130,7 +130,7 @@
 	char *str, name[32];
 	int ret;
 	const void *fdt = gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 
 	snprintf(name, sizeof(name), "%s_", dev->name);
 	str = strdup(name);
diff --git a/drivers/gpio/altera_pio.c b/drivers/gpio/altera_pio.c
index 6f42bf8..92849c5 100644
--- a/drivers/gpio/altera_pio.c
+++ b/drivers/gpio/altera_pio.c
@@ -92,9 +92,9 @@
 	plat->regs = map_physmem(dev_get_addr(dev),
 				 sizeof(struct altera_pio_regs),
 				 MAP_NOCACHE);
-	plat->gpio_count = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+	plat->gpio_count = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 		"altr,gpio-bank-width", 32);
-	plat->bank_name = fdt_getprop(gd->fdt_blob, dev->of_offset,
+	plat->bank_name = fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
 		"gpio-bank-name", NULL);
 
 	return 0;
diff --git a/drivers/gpio/atmel_pio4.c b/drivers/gpio/atmel_pio4.c
index cb90b02..81c3047 100644
--- a/drivers/gpio/atmel_pio4.c
+++ b/drivers/gpio/atmel_pio4.c
@@ -276,7 +276,7 @@
 
 static int atmel_pio4_bind(struct udevice *dev)
 {
-	return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
+	return dm_scan_fdt_node(dev, gd->fdt_blob, dev_of_offset(dev), false);
 }
 
 static int atmel_pio4_probe(struct udevice *dev)
@@ -308,7 +308,8 @@
 	pioctrl_data = (struct atmel_pioctrl_data *)dev_get_driver_data(dev);
 	nbanks = pioctrl_data->nbanks;
 
-	uc_priv->bank_name = fdt_get_name(gd->fdt_blob, dev->of_offset, NULL);
+	uc_priv->bank_name = fdt_get_name(gd->fdt_blob, dev_of_offset(dev),
+					  NULL);
 	uc_priv->gpio_count = nbanks * ATMEL_PIO_NPINS_PER_BANK;
 
 	return 0;
diff --git a/drivers/gpio/db8500_gpio.c b/drivers/gpio/db8500_gpio.c
index db32db6..eefb56d 100644
--- a/drivers/gpio/db8500_gpio.c
+++ b/drivers/gpio/db8500_gpio.c
@@ -174,7 +174,7 @@
 
 /**
  * config_pin - configure a pin's mux attributes
- * @cfg: pin confguration
+ * @cfg: pin configuration
  *
  * Configures a pin's mode (alternate function or GPIO), its pull up status,
  * and its sleep mode based on the specified configuration.  The @cfg is
diff --git a/drivers/gpio/dwapb_gpio.c b/drivers/gpio/dwapb_gpio.c
index 85e0a86..7d1904c 100644
--- a/drivers/gpio/dwapb_gpio.c
+++ b/drivers/gpio/dwapb_gpio.c
@@ -112,13 +112,13 @@
 	if (plat)
 		return 0;
 
-	base = fdtdec_get_addr(blob, dev->of_offset, "reg");
+	base = fdtdec_get_addr(blob, dev_of_offset(dev), "reg");
 	if (base == FDT_ADDR_T_NONE) {
 		debug("Can't get the GPIO register base address\n");
 		return -ENXIO;
 	}
 
-	for (node = fdt_first_subnode(blob, dev->of_offset);
+	for (node = fdt_first_subnode(blob, dev_of_offset(dev));
 	     node > 0;
 	     node = fdt_next_subnode(blob, node)) {
 		if (!fdtdec_get_bool(blob, node, "gpio-controller"))
@@ -142,7 +142,7 @@
 		if (ret)
 			goto err;
 
-		subdev->of_offset = node;
+		dev_set_of_offset(subdev, node);
 		bank++;
 	}
 
diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index 4559739..9ab9df4 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -707,7 +707,7 @@
 	 * calls in gpio_request_by_name(), but we can do this until
 	 * gpio_request_by_name_nodev() can be dropped.
 	 */
-	return gpio_request_by_name_nodev(gd->fdt_blob, dev->of_offset,
+	return gpio_request_by_name_nodev(gd->fdt_blob, dev_of_offset(dev),
 					  list_name, index, desc, flags);
 }
 
@@ -746,7 +746,7 @@
 	 * calls in gpio_request_by_name(), but we can do this until
 	 * gpio_request_list_by_name_nodev() can be dropped.
 	 */
-	return gpio_request_list_by_name_nodev(gd->fdt_blob, dev->of_offset,
+	return gpio_request_list_by_name_nodev(gd->fdt_blob, dev_of_offset(dev),
 					       list_name, desc, max_count,
 					       flags);
 }
@@ -755,7 +755,7 @@
 {
 	int ret;
 
-	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset,
+	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
 					     list_name, "#gpio-cells", 0, -1,
 					     NULL);
 	if (ret) {
diff --git a/drivers/gpio/intel_broadwell_gpio.c b/drivers/gpio/intel_broadwell_gpio.c
index 81ce446..790577a 100644
--- a/drivers/gpio/intel_broadwell_gpio.c
+++ b/drivers/gpio/intel_broadwell_gpio.c
@@ -149,14 +149,14 @@
 	if (ret)
 		return ret;
 
-	bank = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "reg", -1);
+	bank = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "reg", -1);
 	if (bank == -1) {
 		debug("%s: Invalid bank number %d\n", __func__, bank);
 		return -EINVAL;
 	}
 	plat->bank = bank;
 	plat->base_addr = gpiobase;
-	plat->bank_name = fdt_getprop(gd->fdt_blob, dev->of_offset,
+	plat->bank_name = fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
 				      "bank-name", NULL);
 
 	return 0;
diff --git a/drivers/gpio/intel_ich6_gpio.c b/drivers/gpio/intel_ich6_gpio.c
index fd6181f..8b78226 100644
--- a/drivers/gpio/intel_ich6_gpio.c
+++ b/drivers/gpio/intel_ich6_gpio.c
@@ -94,14 +94,14 @@
 	if (ret)
 		return ret;
 
-	offset = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "reg", -1);
+	offset = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "reg", -1);
 	if (offset == -1) {
 		debug("%s: Invalid register offset %d\n", __func__, offset);
 		return -EINVAL;
 	}
 	plat->offset = offset;
 	plat->base_addr = gpiobase + offset;
-	plat->bank_name = fdt_getprop(gd->fdt_blob, dev->of_offset,
+	plat->bank_name = fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
 				      "bank-name", NULL);
 
 	return 0;
diff --git a/drivers/gpio/lpc32xx_gpio.c b/drivers/gpio/lpc32xx_gpio.c
index 9674ee7..1bf945a 100644
--- a/drivers/gpio/lpc32xx_gpio.c
+++ b/drivers/gpio/lpc32xx_gpio.c
@@ -297,7 +297,7 @@
 	struct lpc32xx_gpio_priv *gpio_priv = dev_get_priv(dev);
 	struct gpio_dev_priv *uc_priv = dev->uclass_priv;
 
-	if (dev->of_offset == -1) {
+	if (dev_of_offset(dev) == -1) {
 		/* Tell the uclass how many GPIOs we have */
 		uc_priv->gpio_count = LPC32XX_GPIOS;
 	}
diff --git a/drivers/gpio/mpc85xx_gpio.c b/drivers/gpio/mpc85xx_gpio.c
index 168c696..cfeb6e7 100644
--- a/drivers/gpio/mpc85xx_gpio.c
+++ b/drivers/gpio/mpc85xx_gpio.c
@@ -169,13 +169,13 @@
 	fdt_addr_t addr;
 	fdt_size_t size;
 
-	addr = fdtdec_get_addr_size_auto_noparent(gd->fdt_blob, dev->of_offset,
-						  "reg", 0, &size, false);
+	addr = fdtdec_get_addr_size_auto_noparent(gd->fdt_blob,
+			dev_of_offset(dev), "reg", 0, &size, false);
 
 	plat->addr = addr;
 	plat->size = size;
-	plat->ngpios = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
-						  "ngpios", 32);
+	plat->ngpios = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
+				      "ngpios", 32);
 
 	return 0;
 }
diff --git a/drivers/gpio/msm_gpio.c b/drivers/gpio/msm_gpio.c
index 0302979..01ce1d6 100644
--- a/drivers/gpio/msm_gpio.c
+++ b/drivers/gpio/msm_gpio.c
@@ -106,9 +106,9 @@
 {
 	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 
-	uc_priv->gpio_count = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+	uc_priv->gpio_count = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 					     "gpio-count", 0);
-	uc_priv->bank_name = fdt_getprop(gd->fdt_blob, dev->of_offset,
+	uc_priv->bank_name = fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
 					 "gpio-bank-name", NULL);
 	if (uc_priv->bank_name == NULL)
 		uc_priv->bank_name = "soc";
diff --git a/drivers/gpio/omap_gpio.c b/drivers/gpio/omap_gpio.c
index f906b97..5338552 100644
--- a/drivers/gpio/omap_gpio.c
+++ b/drivers/gpio/omap_gpio.c
@@ -320,7 +320,7 @@
 		return -ENOMEM;
 
 	plat->base = base_addr;
-	plat->port_name = fdt_get_name(gd->fdt_blob, dev->of_offset, NULL);
+	plat->port_name = fdt_get_name(gd->fdt_blob, dev_of_offset(dev), NULL);
 	dev->platdata = plat;
 
 	return 0;
diff --git a/drivers/gpio/pca953x_gpio.c b/drivers/gpio/pca953x_gpio.c
index 0410add..b81f0fa 100644
--- a/drivers/gpio/pca953x_gpio.c
+++ b/drivers/gpio/pca953x_gpio.c
@@ -265,7 +265,7 @@
 		return -ENODEV;
 	}
 
-	addr = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "reg", 0);
+	addr = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "reg", 0);
 	if (addr == 0)
 		return -ENODEV;
 
diff --git a/drivers/gpio/pcf8575_gpio.c b/drivers/gpio/pcf8575_gpio.c
index 2bda0ff..2cbb9e6 100644
--- a/drivers/gpio/pcf8575_gpio.c
+++ b/drivers/gpio/pcf8575_gpio.c
@@ -131,15 +131,15 @@
 
 	int n_latch;
 
-	uc_priv->gpio_count = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+	uc_priv->gpio_count = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 					     "gpio-count", 16);
-	uc_priv->bank_name = fdt_getprop(gd->fdt_blob, dev->of_offset,
+	uc_priv->bank_name = fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
 					 "gpio-bank-name", NULL);
 	if (!uc_priv->bank_name)
 		uc_priv->bank_name = fdt_get_name(gd->fdt_blob,
-						  dev->of_offset, NULL);
+						  dev_of_offset(dev), NULL);
 
-	n_latch = fdtdec_get_uint(gd->fdt_blob, dev->of_offset,
+	n_latch = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
 				  "lines-initial-states", 0);
 	plat->out = ~n_latch;
 
diff --git a/drivers/gpio/pic32_gpio.c b/drivers/gpio/pic32_gpio.c
index 7a037f3..e838ad4 100644
--- a/drivers/gpio/pic32_gpio.c
+++ b/drivers/gpio/pic32_gpio.c
@@ -133,7 +133,8 @@
 	char *end;
 	int bank;
 
-	addr = fdtdec_get_addr_size(gd->fdt_blob, dev->of_offset, "reg", &size);
+	addr = fdtdec_get_addr_size(gd->fdt_blob, dev_of_offset(dev), "reg",
+				    &size);
 	if (addr == FDT_ADDR_T_NONE)
 		return -EINVAL;
 
diff --git a/drivers/gpio/pm8916_gpio.c b/drivers/gpio/pm8916_gpio.c
index 0b61975..e38cee8 100644
--- a/drivers/gpio/pm8916_gpio.c
+++ b/drivers/gpio/pm8916_gpio.c
@@ -193,9 +193,9 @@
 {
 	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 
-	uc_priv->gpio_count = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+	uc_priv->gpio_count = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 					     "gpio-count", 0);
-	uc_priv->bank_name = fdt_getprop(gd->fdt_blob, dev->of_offset,
+	uc_priv->bank_name = fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
 					 "gpio-bank-name", NULL);
 	if (uc_priv->bank_name == NULL)
 		uc_priv->bank_name = "pm8916";
diff --git a/drivers/gpio/s5p_gpio.c b/drivers/gpio/s5p_gpio.c
index 377fed4..042996e 100644
--- a/drivers/gpio/s5p_gpio.c
+++ b/drivers/gpio/s5p_gpio.c
@@ -317,7 +317,7 @@
 		return 0;
 
 	base = (struct s5p_gpio_bank *)dev_get_addr(parent);
-	for (node = fdt_first_subnode(blob, parent->of_offset), bank = base;
+	for (node = fdt_first_subnode(blob, dev_of_offset(parent)), bank = base;
 	     node > 0;
 	     node = fdt_next_subnode(blob, node), bank++) {
 		struct exynos_gpio_platdata *plat;
@@ -337,7 +337,7 @@
 		if (ret)
 			return ret;
 
-		dev->of_offset = node;
+		dev_set_of_offset(dev, node);
 
 		reg = dev_get_addr(dev);
 		if (reg != FDT_ADDR_T_NONE)
diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c
index f6435a0..ae6d930 100644
--- a/drivers/gpio/sandbox.c
+++ b/drivers/gpio/sandbox.c
@@ -197,9 +197,9 @@
 {
 	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 
-	uc_priv->gpio_count = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+	uc_priv->gpio_count = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 					     "num-gpios", 0);
-	uc_priv->bank_name = fdt_getprop(gd->fdt_blob, dev->of_offset,
+	uc_priv->bank_name = fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
 					 "gpio-bank-name", NULL);
 
 	return 0;
@@ -209,7 +209,7 @@
 {
 	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 
-	if (dev->of_offset == -1) {
+	if (dev_of_offset(dev) == -1) {
 		/* Tell the uclass how many GPIOs we have */
 		uc_priv->gpio_count = CONFIG_SANDBOX_GPIO_COUNT;
 	}
diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c
index e8accaa..8d2bb18 100644
--- a/drivers/gpio/sunxi_gpio.c
+++ b/drivers/gpio/sunxi_gpio.c
@@ -312,7 +312,7 @@
 					plat->bank_name, plat, -1, &dev);
 		if (ret)
 			return ret;
-		dev->of_offset = parent->of_offset;
+		dev_set_of_offset(dev, dev_of_offset(parent));
 	}
 
 	return 0;
diff --git a/drivers/gpio/tegra186_gpio.c b/drivers/gpio/tegra186_gpio.c
index 1c68151..b0c22e5 100644
--- a/drivers/gpio/tegra186_gpio.c
+++ b/drivers/gpio/tegra186_gpio.c
@@ -197,7 +197,7 @@
 				  -1, &dev);
 		if (ret)
 			return ret;
-		dev->of_offset = parent->of_offset;
+		dev_set_of_offset(dev, dev_of_offset(parent));
 	}
 
 	return 0;
diff --git a/drivers/gpio/tegra_gpio.c b/drivers/gpio/tegra_gpio.c
index 5a03115..b01968a 100644
--- a/drivers/gpio/tegra_gpio.c
+++ b/drivers/gpio/tegra_gpio.c
@@ -337,7 +337,8 @@
 	 * This driver does not make use of interrupts, other than to figure
 	 * out the number of GPIO banks
 	 */
-	if (!fdt_getprop(gd->fdt_blob, parent->of_offset, "interrupts", &len))
+	if (!fdt_getprop(gd->fdt_blob, dev_of_offset(parent), "interrupts",
+			 &len))
 		return -EINVAL;
 	bank_count = len / 3 / sizeof(u32);
 	ctlr = (struct gpio_ctlr *)dev_get_addr(parent);
@@ -363,7 +364,7 @@
 					  plat->port_name, plat, -1, &dev);
 			if (ret)
 				return ret;
-			dev->of_offset = parent->of_offset;
+			dev_set_of_offset(dev, dev_of_offset(parent));
 		}
 	}
 
diff --git a/drivers/gpio/vybrid_gpio.c b/drivers/gpio/vybrid_gpio.c
index a30ba5d..458104e 100644
--- a/drivers/gpio/vybrid_gpio.c
+++ b/drivers/gpio/vybrid_gpio.c
@@ -129,7 +129,7 @@
 
 	plat->base = base_addr;
 	plat->chip = dev->req_seq;
-	plat->port_name = fdt_get_name(gd->fdt_blob, dev->of_offset, NULL);
+	plat->port_name = fdt_get_name(gd->fdt_blob, dev_of_offset(dev), NULL);
 	dev->platdata = plat;
 
 	return 0;
diff --git a/drivers/i2c/at91_i2c.c b/drivers/i2c/at91_i2c.c
index 4bc54ee..5a63669 100644
--- a/drivers/i2c/at91_i2c.c
+++ b/drivers/i2c/at91_i2c.c
@@ -242,7 +242,7 @@
 {
 	const void *blob = gd->fdt_blob;
 	struct at91_i2c_bus *bus = dev_get_priv(dev);
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 
 	bus->regs = (struct at91_i2c_regs *)dev_get_addr(dev);
 	bus->pdata = (struct at91_i2c_pdata *)dev_get_driver_data(dev);
diff --git a/drivers/i2c/cros_ec_tunnel.c b/drivers/i2c/cros_ec_tunnel.c
index 9cf8e7d..86fa684 100644
--- a/drivers/i2c/cros_ec_tunnel.c
+++ b/drivers/i2c/cros_ec_tunnel.c
@@ -34,7 +34,7 @@
 {
 	struct cros_ec_i2c_bus *i2c_bus = dev_get_priv(dev);
 	const void *blob = gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 
 	i2c_bus->remote_bus = fdtdec_get_uint(blob, node, "google,remote-bus",
 					      0);
diff --git a/drivers/i2c/exynos_hs_i2c.c b/drivers/i2c/exynos_hs_i2c.c
index 9521aeb..2dd75fd 100644
--- a/drivers/i2c/exynos_hs_i2c.c
+++ b/drivers/i2c/exynos_hs_i2c.c
@@ -522,7 +522,7 @@
 	struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);
 	int node;
 
-	node = dev->of_offset;
+	node = dev_of_offset(dev);
 
 	i2c_bus->hsregs = (struct exynos5_hsi2c *)dev_get_addr(dev);
 
diff --git a/drivers/i2c/fsl_i2c.c b/drivers/i2c/fsl_i2c.c
index c3f826d..e9fbf82 100644
--- a/drivers/i2c/fsl_i2c.c
+++ b/drivers/i2c/fsl_i2c.c
@@ -585,21 +585,21 @@
 	struct fsl_i2c_dev *dev = dev_get_priv(bus);
 	fdt_addr_t addr;
 	fdt_size_t size;
+	int node = dev_of_offset(bus);
 
-	addr = fdtdec_get_addr_size_auto_noparent(gd->fdt_blob, bus->of_offset,
-						  "reg", 0, &size, false);
+	addr = fdtdec_get_addr_size_auto_noparent(gd->fdt_blob, node, "reg", 0,
+						  &size, false);
 
 	dev->base = map_sysmem(CONFIG_SYS_IMMR + addr, size);
 
 	if (!dev->base)
 		return -ENOMEM;
 
-	dev->index = fdtdec_get_int(gd->fdt_blob, bus->of_offset,
-				    "cell-index", -1);
-	dev->slaveadd = fdtdec_get_int(gd->fdt_blob, bus->of_offset,
+	dev->index = fdtdec_get_int(gd->fdt_blob, node, "cell-index", -1);
+	dev->slaveadd = fdtdec_get_int(gd->fdt_blob, node,
 				       "u-boot,i2c-slave-addr", 0x7f);
-	dev->speed = fdtdec_get_int(gd->fdt_blob, bus->of_offset,
-				    "clock-frequency", 400000);
+	dev->speed = fdtdec_get_int(gd->fdt_blob, node, "clock-frequency",
+				    400000);
 
 	dev->i2c_clk = dev->index ? gd->arch.i2c2_clk : gd->arch.i2c1_clk;
 
diff --git a/drivers/i2c/i2c-gpio.c b/drivers/i2c/i2c-gpio.c
index a8b83c5..aeeb304 100644
--- a/drivers/i2c/i2c-gpio.c
+++ b/drivers/i2c/i2c-gpio.c
@@ -309,7 +309,7 @@
 {
 	struct i2c_gpio_bus *bus = dev_get_priv(dev);
 	const void *blob = gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	int ret;
 
 	ret = gpio_request_list_by_name(dev, "gpios", bus->gpios,
diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c
index dbd3789..f3184c7 100644
--- a/drivers/i2c/i2c-uclass.c
+++ b/drivers/i2c/i2c-uclass.c
@@ -489,7 +489,7 @@
 #if CONFIG_IS_ENABLED(OF_CONTROL)
 	struct dm_i2c_bus *i2c = dev_get_uclass_priv(dev);
 
-	i2c->speed_hz = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+	i2c->speed_hz = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 				     "clock-frequency", 100000);
 
 	return dm_i2c_set_bus_speed(dev, i2c->speed_hz);
@@ -503,10 +503,11 @@
 #if CONFIG_IS_ENABLED(OF_CONTROL)
 	struct dm_i2c_chip *plat = dev_get_parent_platdata(dev);
 
-	if (dev->of_offset == -1)
+	if (dev_of_offset(dev) == -1)
 		return 0;
 
-	return i2c_chip_ofdata_to_platdata(gd->fdt_blob, dev->of_offset, plat);
+	return i2c_chip_ofdata_to_platdata(gd->fdt_blob, dev_of_offset(dev),
+					   plat);
 #else
 	return 0;
 #endif
diff --git a/drivers/i2c/muxes/i2c-arb-gpio-challenge.c b/drivers/i2c/muxes/i2c-arb-gpio-challenge.c
index 3f072c7..66ce7ec 100644
--- a/drivers/i2c/muxes/i2c-arb-gpio-challenge.c
+++ b/drivers/i2c/muxes/i2c-arb-gpio-challenge.c
@@ -89,7 +89,7 @@
 {
 	struct i2c_arbitrator_priv *priv = dev_get_priv(dev);
 	const void *blob = gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	int ret;
 
 	debug("%s: %s\n", __func__, dev->name);
diff --git a/drivers/i2c/muxes/i2c-mux-uclass.c b/drivers/i2c/muxes/i2c-mux-uclass.c
index db086ef..d243b8e 100644
--- a/drivers/i2c/muxes/i2c-mux-uclass.c
+++ b/drivers/i2c/muxes/i2c-mux-uclass.c
@@ -40,7 +40,7 @@
 	struct i2c_mux_bus *plat = dev_get_parent_platdata(dev);
 	int channel;
 
-	channel = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "reg", -1);
+	channel = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "reg", -1);
 	if (channel < 0)
 		return -EINVAL;
 	plat->channel = channel;
@@ -60,7 +60,7 @@
 	 * There is no compatible string in the sub-nodes, so we must manually
 	 * bind these
 	 */
-	for (offset = fdt_first_subnode(blob, mux->of_offset);
+	for (offset = fdt_first_subnode(blob, dev_of_offset(mux));
 	     offset > 0;
 	     offset = fdt_next_subnode(blob, offset)) {
 		struct udevice *dev;
diff --git a/drivers/i2c/muxes/pca954x.c b/drivers/i2c/muxes/pca954x.c
index 7e0d2da..1a67618 100644
--- a/drivers/i2c/muxes/pca954x.c
+++ b/drivers/i2c/muxes/pca954x.c
@@ -51,7 +51,7 @@
 {
 	struct pca954x_priv *priv = dev_get_priv(dev);
 
-	priv->addr = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "reg", 0);
+	priv->addr = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "reg", 0);
 	if (!priv->addr) {
 		debug("MUX not found\n");
 		return -ENODEV;
diff --git a/drivers/i2c/mvtwsi.c b/drivers/i2c/mvtwsi.c
index cea3da0..648a96e 100644
--- a/drivers/i2c/mvtwsi.c
+++ b/drivers/i2c/mvtwsi.c
@@ -775,11 +775,11 @@
 	if (!dev->base)
 		return -ENOMEM;
 
-	dev->index = fdtdec_get_int(gd->fdt_blob, bus->of_offset,
+	dev->index = fdtdec_get_int(gd->fdt_blob, dev_of_offset(bus),
 				    "cell-index", -1);
-	dev->slaveadd = fdtdec_get_int(gd->fdt_blob, bus->of_offset,
+	dev->slaveadd = fdtdec_get_int(gd->fdt_blob, dev_of_offset(bus),
 				       "u-boot,i2c-slave-addr", 0x0);
-	dev->speed = fdtdec_get_int(gd->fdt_blob, bus->of_offset,
+	dev->speed = fdtdec_get_int(gd->fdt_blob, dev_of_offset(bus),
 				    "clock-frequency", 100000);
 	return 0;
 }
diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index 94d9027..eb789f5 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -750,7 +750,7 @@
 {
 	struct mxc_i2c_bus *i2c_bus = dev_get_priv(bus);
 	const void *fdt = gd->fdt_blob;
-	int node = bus->of_offset;
+	int node = dev_of_offset(bus);
 	fdt_addr_t addr;
 	int ret, ret2;
 
diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c
index 363cd04..3c69dbf 100644
--- a/drivers/i2c/s3c24x0_i2c.c
+++ b/drivers/i2c/s3c24x0_i2c.c
@@ -312,7 +312,7 @@
 	struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);
 	int node;
 
-	node = dev->of_offset;
+	node = dev_of_offset(dev);
 
 	i2c_bus->regs = (struct s3c24x0_i2c *)dev_get_addr(dev);
 
diff --git a/drivers/i2c/tegra186_bpmp_i2c.c b/drivers/i2c/tegra186_bpmp_i2c.c
index 513c414..931c6de 100644
--- a/drivers/i2c/tegra186_bpmp_i2c.c
+++ b/drivers/i2c/tegra186_bpmp_i2c.c
@@ -90,7 +90,7 @@
 {
 	struct tegra186_bpmp_i2c *priv = dev_get_priv(dev);
 
-	priv->bpmp_bus_id = fdtdec_get_uint(gd->fdt_blob, dev->of_offset,
+	priv->bpmp_bus_id = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
 					    "nvidia,bpmp-bus-id", U32_MAX);
 	if (priv->bpmp_bus_id == U32_MAX) {
 		debug("%s: could not parse nvidia,bpmp-bus-id\n", __func__);
diff --git a/drivers/input/cros_ec_keyb.c b/drivers/input/cros_ec_keyb.c
index 9bc4555..00381dc 100644
--- a/drivers/input/cros_ec_keyb.c
+++ b/drivers/input/cros_ec_keyb.c
@@ -189,7 +189,7 @@
 	struct stdio_dev *sdev = &uc_priv->sdev;
 	struct input_config *input = &uc_priv->input;
 	const void *blob = gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	int ret;
 
 	if (cros_ec_keyb_decode_fdt(blob, node, priv))
diff --git a/drivers/input/i8042.c b/drivers/input/i8042.c
index 03d4840..0fd25b1 100644
--- a/drivers/input/i8042.c
+++ b/drivers/input/i8042.c
@@ -315,7 +315,7 @@
 	struct input_config *input = &uc_priv->input;
 	int ret;
 
-	if (fdtdec_get_bool(gd->fdt_blob, dev->of_offset,
+	if (fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
 			    "intel,duplicate-por"))
 		priv->quirks |= QUIRK_DUP_POR;
 
diff --git a/drivers/input/tegra-kbc.c b/drivers/input/tegra-kbc.c
index c77f610..d36f1a1 100644
--- a/drivers/input/tegra-kbc.c
+++ b/drivers/input/tegra-kbc.c
@@ -290,7 +290,7 @@
 	struct keyboard_priv *uc_priv = dev_get_uclass_priv(dev);
 	struct stdio_dev *sdev = &uc_priv->sdev;
 	struct input_config *input = &uc_priv->input;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	int ret;
 
 	priv->kbc = (struct kbc_tegra *)dev_get_addr(dev);
diff --git a/drivers/led/led_gpio.c b/drivers/led/led_gpio.c
index cb6e996..5b11990 100644
--- a/drivers/led/led_gpio.c
+++ b/drivers/led/led_gpio.c
@@ -62,7 +62,7 @@
 	int node;
 	int ret;
 
-	for (node = fdt_first_subnode(blob, parent->of_offset);
+	for (node = fdt_first_subnode(blob, dev_of_offset(parent));
 	     node > 0;
 	     node = fdt_next_subnode(blob, node)) {
 		struct led_uclass_plat *uc_plat;
diff --git a/drivers/mailbox/mailbox-uclass.c b/drivers/mailbox/mailbox-uclass.c
index a7fcde5..38448de 100644
--- a/drivers/mailbox/mailbox-uclass.c
+++ b/drivers/mailbox/mailbox-uclass.c
@@ -41,7 +41,7 @@
 
 	debug("%s(dev=%p, index=%d, chan=%p)\n", __func__, dev, index, chan);
 
-	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset,
+	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
 					     "mboxes", "#mbox-cells", 0,
 					     index, &args);
 	if (ret) {
@@ -85,7 +85,7 @@
 
 	debug("%s(dev=%p, name=%s, chan=%p)\n", __func__, dev, name, chan);
 
-	index = fdt_stringlist_search(gd->fdt_blob, dev->of_offset,
+	index = fdt_stringlist_search(gd->fdt_blob, dev_of_offset(dev),
 				      "mbox-names", name);
 	if (index < 0) {
 		debug("fdt_stringlist_search() failed: %d\n", index);
diff --git a/drivers/misc/cros_ec.c b/drivers/misc/cros_ec.c
index 759bb46..3d449b2 100644
--- a/drivers/misc/cros_ec.c
+++ b/drivers/misc/cros_ec.c
@@ -998,7 +998,7 @@
 {
 	struct cros_ec_dev *cdev = dev_get_uclass_priv(dev);
 	const void *blob = gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	char id[MSG_BYTES];
 
 	cdev->dev = dev;
diff --git a/drivers/misc/cros_ec_i2c.c b/drivers/misc/cros_ec_i2c.c
index 3de18b2..6e09340 100644
--- a/drivers/misc/cros_ec_i2c.c
+++ b/drivers/misc/cros_ec_i2c.c
@@ -24,11 +24,96 @@
 #define debug_trace(fmt, b...)
 #endif
 
+/**
+ * Request format for protocol v3
+ * byte 0	0xda (EC_COMMAND_PROTOCOL_3)
+ * byte 1-8	struct ec_host_request
+ * byte 10-	response data
+ */
+struct ec_host_request_i2c {
+	/* Always 0xda to backward compatible with v2 struct */
+	uint8_t  command_protocol;
+	struct ec_host_request ec_request;
+} __packed;
+
+/*
+ * Response format for protocol v3
+ * byte 0	result code
+ * byte 1	packet_length
+ * byte 2-9	struct ec_host_response
+ * byte 10-	response data
+ */
+struct ec_host_response_i2c {
+	uint8_t result;
+	uint8_t packet_length;
+	struct ec_host_response ec_response;
+} __packed;
+
+static int cros_ec_i2c_packet(struct udevice *udev, int out_bytes, int in_bytes)
+{
+	struct cros_ec_dev *dev = dev_get_uclass_priv(udev);
+	struct dm_i2c_chip *chip = dev_get_parent_platdata(udev);
+	struct ec_host_request_i2c *ec_request_i2c =
+		(struct ec_host_request_i2c *)dev->dout;
+	struct ec_host_response_i2c *ec_response_i2c =
+		(struct ec_host_response_i2c *)dev->din;
+	struct i2c_msg i2c_msg[2];
+	int ret;
+
+	i2c_msg[0].addr = chip->chip_addr;
+	i2c_msg[0].flags = 0;
+	i2c_msg[1].addr = chip->chip_addr;
+	i2c_msg[1].flags = I2C_M_RD;
+
+	/* one extra byte, to indicate v3 */
+	i2c_msg[0].len = out_bytes + 1;
+	i2c_msg[0].buf = dev->dout;
+
+	/* stitch on EC_COMMAND_PROTOCOL_3 */
+	memmove(&ec_request_i2c->ec_request, dev->dout, out_bytes);
+	ec_request_i2c->command_protocol = EC_COMMAND_PROTOCOL_3;
+
+	/* two extra bytes for v3 */
+	i2c_msg[1].len = in_bytes + 2;
+	i2c_msg[1].buf = dev->din;
+
+	ret = dm_i2c_xfer(udev, &i2c_msg[0], 2);
+	if (ret) {
+		printf("%s: Could not execute transfer: %d\n", __func__, ret);
+		return ret;
+	}
+
+	/* When we send a v3 request to v2 ec, ec won't recognize the 0xda
+	 * (EC_COMMAND_PROTOCOL_3) and will return with status
+	 * EC_RES_INVALID_COMMAND with zero data length
+	 *
+	 * In case of invalid command for v3 protocol the data length
+	 * will be at least sizeof(struct ec_host_response)
+	 */
+	if (ec_response_i2c->result == EC_RES_INVALID_COMMAND &&
+	    ec_response_i2c->packet_length == 0)
+		return -EPROTONOSUPPORT;
+
+	if (ec_response_i2c->packet_length < sizeof(struct ec_host_response)) {
+		printf("%s: response of %u bytes too short; not a full hdr\n",
+		       __func__, ec_response_i2c->packet_length);
+		return -EBADMSG;
+	}
+
+
+	/* drop result and packet_len */
+	memmove(dev->din, &ec_response_i2c->ec_response, in_bytes);
+
+	return in_bytes;
+}
+
 static int cros_ec_i2c_command(struct udevice *udev, uint8_t cmd,
 			       int cmd_version, const uint8_t *dout,
 			       int dout_len, uint8_t **dinp, int din_len)
 {
 	struct cros_ec_dev *dev = dev_get_uclass_priv(udev);
+	struct dm_i2c_chip *chip = dev_get_parent_platdata(udev);
+	struct i2c_msg i2c_msg[2];
 	/* version8, cmd8, arglen8, out8[dout_len], csum8 */
 	int out_bytes = dout_len + 4;
 	/* response8, arglen8, in8[din_len], checksum8 */
@@ -53,6 +138,11 @@
 	assert(dout_len >= 0);
 	assert(dinp);
 
+	i2c_msg[0].addr = chip->chip_addr;
+	i2c_msg[0].len = out_bytes;
+	i2c_msg[0].buf = dev->dout;
+	i2c_msg[0].flags = 0;
+
 	/*
 	 * Copy command and data into output buffer so we can do a single I2C
 	 * burst transaction.
@@ -85,24 +175,21 @@
 	*ptr++ = (uint8_t)
 		cros_ec_calc_checksum(dev->dout, dout_len + 3);
 
+	i2c_msg[1].addr = chip->chip_addr;
+	i2c_msg[1].len = in_bytes;
+	i2c_msg[1].buf = in_ptr;
+	i2c_msg[1].flags = I2C_M_RD;
+
 	/* Send output data */
 	cros_ec_dump_data("out", -1, dev->dout, out_bytes);
-	ret = dm_i2c_write(udev, 0, dev->dout, out_bytes);
+
+	ret = dm_i2c_xfer(udev, &i2c_msg[0], 2);
 	if (ret) {
-		debug("%s: Cannot complete I2C write to %s\n", __func__,
+		debug("%s: Could not execute transfer to %s\n", __func__,
 		      udev->name);
 		ret = -1;
 	}
 
-	if (!ret) {
-		ret = dm_i2c_read(udev, 0, in_ptr, in_bytes);
-		if (ret) {
-			debug("%s: Cannot complete I2C read from %s\n",
-			      __func__, udev->name);
-			ret = -1;
-		}
-	}
-
 	if (*in_ptr != EC_RES_SUCCESS) {
 		debug("%s: Received bad result code %d\n", __func__, *in_ptr);
 		return -(int)*in_ptr;
@@ -136,6 +223,7 @@
 
 static struct dm_cros_ec_ops cros_ec_ops = {
 	.command = cros_ec_i2c_command,
+	.packet = cros_ec_i2c_packet,
 };
 
 static const struct udevice_id cros_ec_ids[] = {
diff --git a/drivers/misc/cros_ec_sandbox.c b/drivers/misc/cros_ec_sandbox.c
index c4fbca0..848c67b 100644
--- a/drivers/misc/cros_ec_sandbox.c
+++ b/drivers/misc/cros_ec_sandbox.c
@@ -522,7 +522,7 @@
 	int err;
 
 	memcpy(ec, &s_state, sizeof(*ec));
-	err = cros_ec_decode_ec_flash(blob, dev->of_offset, &ec->ec_config);
+	err = cros_ec_decode_ec_flash(blob, dev_of_offset(dev), &ec->ec_config);
 	if (err)
 		return err;
 
@@ -531,7 +531,7 @@
 	     keyb_dev;
 	     device_find_next_child(&keyb_dev)) {
 		if (device_get_uclass_id(keyb_dev) == UCLASS_KEYBOARD) {
-			node = keyb_dev->of_offset;
+			node = dev_of_offset(keyb_dev);
 			break;
 		}
 	}
diff --git a/drivers/misc/i2c_eeprom_emul.c b/drivers/misc/i2c_eeprom_emul.c
index 4410d03..02de8d7 100644
--- a/drivers/misc/i2c_eeprom_emul.c
+++ b/drivers/misc/i2c_eeprom_emul.c
@@ -115,9 +115,9 @@
 {
 	struct sandbox_i2c_flash_plat_data *plat = dev_get_platdata(dev);
 
-	plat->size = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+	plat->size = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 				    "sandbox,size", 32);
-	plat->filename = fdt_getprop(gd->fdt_blob, dev->of_offset,
+	plat->filename = fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
 				     "sandbox,filename", NULL);
 	if (!plat->filename) {
 		debug("%s: No filename for device '%s'\n", __func__,
diff --git a/drivers/misc/qfw.c b/drivers/misc/qfw.c
index d43d1d3..a8af9e0 100644
--- a/drivers/misc/qfw.c
+++ b/drivers/misc/qfw.c
@@ -32,7 +32,7 @@
  *          be ignored.
  * @return: 0 on success, or negative value on failure
  */
-static int bios_linker_allocate(struct bios_linker_entry *entry, u32 *addr)
+static int bios_linker_allocate(struct bios_linker_entry *entry, ulong *addr)
 {
 	uint32_t size, align;
 	struct fw_file *file;
@@ -147,7 +147,7 @@
 }
 
 /* This function loads and patches ACPI tables provided by QEMU */
-u32 write_acpi_tables(u32 addr)
+ulong write_acpi_tables(ulong addr)
 {
 	int i, ret = 0;
 	struct fw_file *file;
diff --git a/drivers/misc/tegra186_bpmp.c b/drivers/misc/tegra186_bpmp.c
index f4ddbea3..bd8b960 100644
--- a/drivers/misc/tegra186_bpmp.c
+++ b/drivers/misc/tegra186_bpmp.c
@@ -112,19 +112,19 @@
 	debug("%s(dev=%p)\n", __func__, dev);
 
 	ret = device_bind_driver_to_node(dev, "tegra186_clk", "tegra186_clk",
-					 dev->of_offset, &child);
+					 dev_of_offset(dev), &child);
 	if (ret)
 		return ret;
 
 	ret = device_bind_driver_to_node(dev, "tegra186_reset",
-					 "tegra186_reset", dev->of_offset,
+					 "tegra186_reset", dev_of_offset(dev),
 					 &child);
 	if (ret)
 		return ret;
 
 	ret = device_bind_driver_to_node(dev, "tegra186_power_domain",
 					 "tegra186_power_domain",
-					 dev->of_offset, &child);
+					 dev_of_offset(dev), &child);
 	if (ret)
 		return ret;
 
@@ -141,7 +141,7 @@
 	struct fdtdec_phandle_args args;
 	fdt_addr_t reg;
 
-	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset,
+	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
 					      "shmem", NULL, 0, index, &args);
 	if (ret < 0) {
 		error("fdtdec_parse_phandle_with_args() failed: %d\n", ret);
diff --git a/drivers/misc/tegra_car.c b/drivers/misc/tegra_car.c
index 0eb0096..5db3c37 100644
--- a/drivers/misc/tegra_car.c
+++ b/drivers/misc/tegra_car.c
@@ -22,12 +22,12 @@
 	debug("%s(dev=%p)\n", __func__, dev);
 
 	ret = device_bind_driver_to_node(dev, "tegra_car_clk", "tegra_car_clk",
-					 dev->of_offset, &child);
+					 dev_of_offset(dev), &child);
 	if (ret)
 		return ret;
 
 	ret = device_bind_driver_to_node(dev, "tegra_car_reset",
-					 "tegra_car_reset", dev->of_offset,
+					 "tegra_car_reset", dev_of_offset(dev),
 					 &child);
 	if (ret)
 		return ret;
diff --git a/drivers/mmc/atmel_sdhci.c b/drivers/mmc/atmel_sdhci.c
index 62cb242..8522557 100644
--- a/drivers/mmc/atmel_sdhci.c
+++ b/drivers/mmc/atmel_sdhci.c
@@ -75,7 +75,7 @@
 	host->ioaddr = (void *)dev_get_addr(dev);
 
 	host->quirks = 0;
-	host->bus_width	= fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+	host->bus_width	= fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 					 "bus-width", 4);
 
 	caps = sdhci_readl(host, SDHCI_CAPABILITIES);
diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c
index c440399..40f7892 100644
--- a/drivers/mmc/exynos_dw_mmc.c
+++ b/drivers/mmc/exynos_dw_mmc.c
@@ -264,7 +264,7 @@
 	struct dwmci_host *host = &priv->host;
 	int err;
 
-	err = exynos_dwmci_get_config(gd->fdt_blob, dev->of_offset, host);
+	err = exynos_dwmci_get_config(gd->fdt_blob, dev_of_offset(dev), host);
 	if (err)
 		return err;
 	err = do_dwmci_init(host);
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index 73473c5..adeb5df 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -954,7 +954,7 @@
 	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
 	struct fsl_esdhc_priv *priv = dev_get_priv(dev);
 	const void *fdt = gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	fdt_addr_t addr;
 	unsigned int val;
 	int ret;
diff --git a/drivers/mmc/msm_sdhci.c b/drivers/mmc/msm_sdhci.c
index 1db683d..7a7e67f 100644
--- a/drivers/mmc/msm_sdhci.c
+++ b/drivers/mmc/msm_sdhci.c
@@ -50,16 +50,16 @@
 
 static int msm_sdc_clk_init(struct udevice *dev)
 {
-	uint clk_rate = fdtdec_get_uint(gd->fdt_blob, dev->of_offset,
-					"clock-frequency", 400000);
+	int node = dev_of_offset(dev);
+	uint clk_rate = fdtdec_get_uint(gd->fdt_blob, node, "clock-frequency",
+					400000);
 	uint clkd[2]; /* clk_id and clk_no */
 	int clk_offset;
 	struct udevice *clk_dev;
 	struct clk clk;
 	int ret;
 
-	ret = fdtdec_get_int_array(gd->fdt_blob, dev->of_offset, "clock", clkd,
-				   2);
+	ret = fdtdec_get_int_array(gd->fdt_blob, node, "clock", clkd, 2);
 	if (ret)
 		return ret;
 
@@ -168,17 +168,14 @@
 	struct udevice *parent = dev->parent;
 	struct msm_sdhc *priv = dev_get_priv(dev);
 	struct sdhci_host *host = &priv->host;
+	int node = dev_of_offset(dev);
 
 	host->name = strdup(dev->name);
 	host->ioaddr = (void *)dev_get_addr(dev);
-	host->bus_width = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
-					 "bus-width", 4);
-	host->index = fdtdec_get_uint(gd->fdt_blob, dev->of_offset, "index", 0);
+	host->bus_width = fdtdec_get_int(gd->fdt_blob, node, "bus-width", 4);
+	host->index = fdtdec_get_uint(gd->fdt_blob, node, "index", 0);
 	priv->base = (void *)fdtdec_get_addr_size_auto_parent(gd->fdt_blob,
-							      parent->of_offset,
-							      dev->of_offset,
-							      "reg", 1, NULL,
-							      false);
+			dev_of_offset(parent), node, "reg", 1, NULL, false);
 	if (priv->base == (void *)FDT_ADDR_T_NONE ||
 	    host->ioaddr == (void *)FDT_ADDR_T_NONE)
 		return -EINVAL;
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index b326846..5bb628d 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -728,7 +728,7 @@
 {
 	struct omap_hsmmc_data *priv = dev_get_priv(dev);
 	const void *fdt = gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	struct mmc_config *cfg;
 	int val;
 
diff --git a/drivers/mmc/pic32_sdhci.c b/drivers/mmc/pic32_sdhci.c
index 1e14fa1..9d8a392 100644
--- a/drivers/mmc/pic32_sdhci.c
+++ b/drivers/mmc/pic32_sdhci.c
@@ -38,18 +38,18 @@
 	fdt_size_t size;
 	int ret;
 
-	addr = fdtdec_get_addr_size(fdt, dev->of_offset, "reg", &size);
+	addr = fdtdec_get_addr_size(fdt, dev_of_offset(dev), "reg", &size);
 	if (addr == FDT_ADDR_T_NONE)
 		return -EINVAL;
 
 	host->ioaddr	= ioremap(addr, size);
 	host->name	= dev->name;
 	host->quirks	= SDHCI_QUIRK_NO_HISPD_BIT;
-	host->bus_width	= fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+	host->bus_width	= fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 					"bus-width", 4);
 	host->ops = &pic32_sdhci_ops;
 
-	ret = fdtdec_get_int_array(gd->fdt_blob, dev->of_offset,
+	ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev),
 				   "clock-freq-min-max", f_min_max, 2);
 	if (ret) {
 		printf("sdhci: clock-freq-min-max not found\n");
diff --git a/drivers/mmc/rockchip_dw_mmc.c b/drivers/mmc/rockchip_dw_mmc.c
index 47db678..c36eda0 100644
--- a/drivers/mmc/rockchip_dw_mmc.c
+++ b/drivers/mmc/rockchip_dw_mmc.c
@@ -59,24 +59,24 @@
 
 	host->name = dev->name;
 	host->ioaddr = (void *)dev_get_addr(dev);
-	host->buswidth = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+	host->buswidth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 					"bus-width", 4);
 	host->get_mmc_clk = rockchip_dwmmc_get_mmc_clk;
 	host->priv = dev;
 
 	/* use non-removeable as sdcard and emmc as judgement */
-	if (fdtdec_get_bool(gd->fdt_blob, dev->of_offset, "non-removable"))
+	if (fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev), "non-removable"))
 		host->dev_index = 0;
 	else
 		host->dev_index = 1;
 
-	priv->fifo_depth = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+	priv->fifo_depth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 				    "fifo-depth", 0);
 	if (priv->fifo_depth < 0)
 		return -EINVAL;
-	priv->fifo_mode = fdtdec_get_bool(gd->fdt_blob, dev->of_offset,
+	priv->fifo_mode = fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
 					  "fifo-mode");
-	if (fdtdec_get_int_array(gd->fdt_blob, dev->of_offset,
+	if (fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev),
 				 "clock-freq-min-max", priv->minmax, 2))
 		return -EINVAL;
 #endif
diff --git a/drivers/mmc/rockchip_sdhci.c b/drivers/mmc/rockchip_sdhci.c
index 1358864..bd91f91 100644
--- a/drivers/mmc/rockchip_sdhci.c
+++ b/drivers/mmc/rockchip_sdhci.c
@@ -38,7 +38,7 @@
 	struct clk clk;
 
 
-	max_frequency = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+	max_frequency = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 			"max-frequency", 0);
 	ret = clk_get_by_index(dev, 0, &clk);
 	if (!ret) {
diff --git a/drivers/mmc/s5p_sdhci.c b/drivers/mmc/s5p_sdhci.c
index 28327d5..640ea02 100644
--- a/drivers/mmc/s5p_sdhci.c
+++ b/drivers/mmc/s5p_sdhci.c
@@ -247,7 +247,7 @@
 	struct sdhci_host *host = dev_get_priv(dev);
 	int ret;
 
-	ret = sdhci_get_config(gd->fdt_blob, dev->of_offset, host);
+	ret = sdhci_get_config(gd->fdt_blob, dev_of_offset(dev), host);
 	if (ret)
 		return ret;
 
diff --git a/drivers/mmc/socfpga_dw_mmc.c b/drivers/mmc/socfpga_dw_mmc.c
index 0a22e58..d0c3c51 100644
--- a/drivers/mmc/socfpga_dw_mmc.c
+++ b/drivers/mmc/socfpga_dw_mmc.c
@@ -70,7 +70,7 @@
 		return -EINVAL;
 	}
 
-	fifo_depth = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+	fifo_depth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 				    "fifo-depth", 0);
 	if (fifo_depth < 0) {
 		printf("DWMMC: Can't get FIFO depth\n");
@@ -79,7 +79,7 @@
 
 	host->name = dev->name;
 	host->ioaddr = (void *)dev_get_addr(dev);
-	host->buswidth = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+	host->buswidth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 					"bus-width", 4);
 	host->clksel = socfpga_dwmci_clksel;
 
@@ -92,9 +92,9 @@
 	host->bus_hz = clk;
 	host->fifoth_val = MSIZE(0x2) |
 		RX_WMARK(fifo_depth / 2 - 1) | TX_WMARK(fifo_depth / 2);
-	priv->drvsel = fdtdec_get_uint(gd->fdt_blob, dev->of_offset,
+	priv->drvsel = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
 				       "drvsel", 3);
-	priv->smplsel = fdtdec_get_uint(gd->fdt_blob, dev->of_offset,
+	priv->smplsel = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
 					"smplsel", 0);
 	host->priv = priv;
 
diff --git a/drivers/mmc/tegra_mmc.c b/drivers/mmc/tegra_mmc.c
index 0211dc7..0df74ef 100644
--- a/drivers/mmc/tegra_mmc.c
+++ b/drivers/mmc/tegra_mmc.c
@@ -578,8 +578,8 @@
 	priv->cfg.name = "Tegra SD/MMC";
 	priv->cfg.ops = &tegra_mmc_ops;
 
-	bus_width = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "bus-width",
-				   1);
+	bus_width = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
+				   "bus-width", 1);
 
 	priv->cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
 	priv->cfg.host_caps = 0;
diff --git a/drivers/mmc/uniphier-sd.c b/drivers/mmc/uniphier-sd.c
index 4af7fdb..7f20ef1 100644
--- a/drivers/mmc/uniphier-sd.c
+++ b/drivers/mmc/uniphier-sd.c
@@ -705,7 +705,8 @@
 	plat->cfg.name = dev->name;
 	plat->cfg.host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS;
 
-	switch (fdtdec_get_int(gd->fdt_blob, dev->of_offset, "bus-width", 1)) {
+	switch (fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "bus-width",
+			       1)) {
 	case 8:
 		plat->cfg.host_caps |= MMC_MODE_8BIT;
 		break;
@@ -719,7 +720,7 @@
 		return -EINVAL;
 	}
 
-	if (fdt_get_property(gd->fdt_blob, dev->of_offset, "non-removable",
+	if (fdt_get_property(gd->fdt_blob, dev_of_offset(dev), "non-removable",
 			     NULL))
 		priv->caps |= UNIPHIER_SD_CAP_NONREMOVABLE;
 
diff --git a/drivers/mmc/xenon_sdhci.c b/drivers/mmc/xenon_sdhci.c
index 828da11..f678110 100644
--- a/drivers/mmc/xenon_sdhci.c
+++ b/drivers/mmc/xenon_sdhci.c
@@ -405,7 +405,8 @@
 		armada_3700_soc_pad_voltage_set(host);
 
 	host->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_DDR_52MHz;
-	switch (fdtdec_get_int(gd->fdt_blob, dev->of_offset, "bus-width", 1)) {
+	switch (fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "bus-width",
+		1)) {
 	case 8:
 		host->host_caps |= MMC_MODE_8BIT;
 		break;
@@ -455,7 +456,7 @@
 	if (of_device_is_compatible(dev, "marvell,armada-3700-sdhci"))
 		priv->pad_ctrl_reg = (void *)dev_get_addr_index(dev, 1);
 
-	name = fdt_getprop(gd->fdt_blob, dev->of_offset, "marvell,pad-type",
+	name = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "marvell,pad-type",
 			   NULL);
 	if (name) {
 		if (0 == strncmp(name, "sd", 2)) {
diff --git a/drivers/mtd/altera_qspi.c b/drivers/mtd/altera_qspi.c
index a9148a7..e04964b 100644
--- a/drivers/mtd/altera_qspi.c
+++ b/drivers/mtd/altera_qspi.c
@@ -349,7 +349,7 @@
 {
 	struct altera_qspi_platdata *pdata = dev_get_platdata(dev);
 	void *blob = (void *)gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	const char *list, *end;
 	const fdt32_t *cell;
 	void *base;
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index e036b88..d440f5c 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -2441,7 +2441,7 @@
 static int cfi_flash_probe(struct udevice *dev)
 {
 	void *blob = (void *)gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	const fdt32_t *cell;
 	phys_addr_t addr;
 	int parent, addrc, sizec;
diff --git a/drivers/mtd/pic32_flash.c b/drivers/mtd/pic32_flash.c
index 9166fcd..8ed7874 100644
--- a/drivers/mtd/pic32_flash.c
+++ b/drivers/mtd/pic32_flash.c
@@ -371,7 +371,7 @@
 static int pic32_flash_probe(struct udevice *dev)
 {
 	void *blob = (void *)gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	const char *list, *end;
 	const fdt32_t *cell;
 	unsigned long addr, size;
diff --git a/drivers/mtd/spi/sandbox.c b/drivers/mtd/spi/sandbox.c
index 4944059..36a50fe 100644
--- a/drivers/mtd/spi/sandbox.c
+++ b/drivers/mtd/spi/sandbox.c
@@ -516,7 +516,7 @@
 {
 	struct sandbox_spi_flash_plat_data *pdata = dev_get_platdata(dev);
 	const void *blob = gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 
 	pdata->filename = fdt_getprop(blob, node, "sandbox,filename", NULL);
 	pdata->device_name = fdt_getprop(blob, node, "compatible", NULL);
@@ -641,7 +641,7 @@
 		debug("%s: busnum=%u, cs=%u: binding SPI flash emulation: ",
 		      __func__, busnum, cs);
 		ret = sandbox_sf_bind_emul(state, busnum, cs, bus,
-					   slave->of_offset, slave->name);
+					   dev_of_offset(slave), slave->name);
 		if (ret) {
 			debug("failed (err=%d)\n", ret);
 			return ret;
diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index 2e378dc..ab7910b 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -919,7 +919,7 @@
 #ifdef CONFIG_DM_SPI_FLASH
 	fdt_addr_t addr;
 	fdt_size_t size;
-	int node = flash->dev->of_offset;
+	int node = dev_of_offset(flash->dev);
 
 	addr = fdtdec_get_addr_size(blob, node, "memory-map", &size);
 	if (addr == FDT_ADDR_T_NONE) {
diff --git a/drivers/net/ag7xxx.c b/drivers/net/ag7xxx.c
index 346f138..f8782bc 100644
--- a/drivers/net/ag7xxx.c
+++ b/drivers/net/ag7xxx.c
@@ -857,7 +857,7 @@
 {
 	int offset;
 
-	offset = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset, "phy");
+	offset = fdtdec_lookup_phandle(gd->fdt_blob, dev_of_offset(dev), "phy");
 	if (offset <= 0) {
 		debug("%s: PHY OF node not found (ret=%i)\n", __func__, offset);
 		return -EINVAL;
diff --git a/drivers/net/altera_tse.c b/drivers/net/altera_tse.c
index 92a1b64..d4d17dd 100644
--- a/drivers/net/altera_tse.c
+++ b/drivers/net/altera_tse.c
@@ -576,7 +576,7 @@
 	struct eth_pdata *pdata = dev_get_platdata(dev);
 	struct altera_tse_priv *priv = dev_get_priv(dev);
 	void *blob = (void *)gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	const char *list, *end;
 	const fdt32_t *cell;
 	void *base, *desc_mem = NULL;
@@ -676,7 +676,8 @@
 	const char *phy_mode;
 
 	pdata->phy_interface = -1;
-	phy_mode = fdt_getprop(gd->fdt_blob, dev->of_offset, "phy-mode", NULL);
+	phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode",
+			       NULL);
 	if (phy_mode)
 		pdata->phy_interface = phy_get_interface_by_name(phy_mode);
 	if (pdata->phy_interface == -1) {
diff --git a/drivers/net/cpsw-common.c b/drivers/net/cpsw-common.c
index e828e85..55f56d9 100644
--- a/drivers/net/cpsw-common.c
+++ b/drivers/net/cpsw-common.c
@@ -20,7 +20,7 @@
 				       int slave, u8 *mac_addr)
 {
 	void *fdt = (void *)gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	u32 macid_lsb;
 	u32 macid_msb;
 	fdt32_t gmii = 0;
@@ -60,7 +60,7 @@
 				    u8 *mac_addr)
 {
 	void *fdt = (void *)gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	u32 macid_lo;
 	u32 macid_hi;
 	fdt32_t gmii = 0;
@@ -110,7 +110,7 @@
 	if (of_device_is_compatible(dev, "ti,dm816-emac"))
 		return cpsw_am33xx_cm_get_macid(dev, 0x30, slave, mac_addr);
 
-	if (of_machine_is_compatible("ti,am4372"))
+	if (of_machine_is_compatible("ti,am43"))
 		return cpsw_am33xx_cm_get_macid(dev, 0x630, slave, mac_addr);
 
 	if (of_machine_is_compatible("ti,dra7"))
diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c
index cbce683..5fbab9e 100644
--- a/drivers/net/cpsw.c
+++ b/drivers/net/cpsw.c
@@ -981,7 +981,7 @@
 
 #ifdef CONFIG_DM_ETH
 	if (slave->data->phy_of_handle)
-		phydev->dev->of_offset = slave->data->phy_of_handle;
+		dev_set_of_offset(phydev->dev, slave->data->phy_of_handle);
 #endif
 
 	priv->phydev = phydev;
@@ -1286,7 +1286,7 @@
 	const char *phy_mode;
 	const char *phy_sel_compat = NULL;
 	const void *fdt = gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	int subnode;
 	int slave_index = 0;
 	int active_slave;
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index e207bc6..eee4e09 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -728,7 +728,8 @@
 
 	pdata->iobase = dev_get_addr(dev);
 	pdata->phy_interface = -1;
-	phy_mode = fdt_getprop(gd->fdt_blob, dev->of_offset, "phy-mode", NULL);
+	phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode",
+			       NULL);
 	if (phy_mode)
 		pdata->phy_interface = phy_get_interface_by_name(phy_mode);
 	if (pdata->phy_interface == -1) {
@@ -737,19 +738,19 @@
 	}
 
 	pdata->max_speed = 0;
-	cell = fdt_getprop(gd->fdt_blob, dev->of_offset, "max-speed", NULL);
+	cell = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "max-speed", NULL);
 	if (cell)
 		pdata->max_speed = fdt32_to_cpu(*cell);
 
 #ifdef CONFIG_DM_GPIO
-	if (fdtdec_get_bool(gd->fdt_blob, dev->of_offset,
+	if (fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
 			    "snps,reset-active-low"))
 		reset_flags |= GPIOD_ACTIVE_LOW;
 
 	ret = gpio_request_by_name(dev, "snps,reset-gpio", 0,
 		&priv->reset_gpio, reset_flags);
 	if (ret == 0) {
-		ret = fdtdec_get_int_array(gd->fdt_blob, dev->of_offset,
+		ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev),
 			"snps,reset-delays-us", dw_pdata->reset_delays, 3);
 	} else if (ret == -ENOENT) {
 		ret = 0;
diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c
index 3304fddc..5f34c8f 100644
--- a/drivers/net/fec_mxc.c
+++ b/drivers/net/fec_mxc.c
@@ -1277,7 +1277,8 @@
 	priv->eth = (struct ethernet_regs *)pdata->iobase;
 
 	pdata->phy_interface = -1;
-	phy_mode = fdt_getprop(gd->fdt_blob, dev->of_offset, "phy-mode", NULL);
+	phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode",
+			       NULL);
 	if (phy_mode)
 		pdata->phy_interface = phy_get_interface_by_name(phy_mode);
 	if (pdata->phy_interface == -1) {
diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c
index 5f833fa..e9b202a 100644
--- a/drivers/net/gmac_rockchip.c
+++ b/drivers/net/gmac_rockchip.c
@@ -36,9 +36,9 @@
 {
 	struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
 
-	pdata->tx_delay = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+	pdata->tx_delay = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 					 "tx-delay", 0x30);
-	pdata->rx_delay = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+	pdata->rx_delay = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 					 "rx-delay", 0x10);
 
 	return designware_eth_ofdata_to_platdata(dev);
diff --git a/drivers/net/keystone_net.c b/drivers/net/keystone_net.c
index a5120e0..1b781f4 100644
--- a/drivers/net/keystone_net.c
+++ b/drivers/net/keystone_net.c
@@ -1099,7 +1099,7 @@
 	struct ks2_eth_priv *priv = dev_get_priv(dev);
 	struct eth_pdata *pdata = dev_get_platdata(dev);
 	const void *fdt = gd->fdt_blob;
-	int slave = dev->of_offset;
+	int slave = dev_of_offset(dev);
 	int interfaces;
 	int gbe;
 	int netcp_devices;
@@ -1126,13 +1126,13 @@
 	int netcp_devices;
 	int gbe;
 
-	netcp_devices = fdt_subnode_offset(fdt, dev->of_offset,
+	netcp_devices = fdt_subnode_offset(fdt, dev_of_offset(dev),
 					   "netcp-devices");
 	gbe = fdt_subnode_offset(fdt, netcp_devices, "gbe");
 
 	ks2_eth_bind_slaves(dev, gbe, &gbe_0);
 
-	ks2_eth_parse_slave_interface(dev->of_offset, gbe_0, priv, pdata);
+	ks2_eth_parse_slave_interface(dev_of_offset(dev), gbe_0, priv, pdata);
 
 	pdata->iobase = dev_get_addr(dev);
 
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 01527f7..452fc3e 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -999,7 +999,8 @@
 #ifdef CONFIG_DM_ETH
 	const char *phy_mode;
 
-	phy_mode = fdt_getprop(gd->fdt_blob, dev->of_offset, "phy-mode", NULL);
+	phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode",
+			       NULL);
 	if (phy_mode)
 		macb->phy_interface = phy_get_interface_by_name(phy_mode);
 	if (macb->phy_interface == -1) {
diff --git a/drivers/net/mvneta.c b/drivers/net/mvneta.c
index 00f378f..674075f 100644
--- a/drivers/net/mvneta.c
+++ b/drivers/net/mvneta.c
@@ -1611,7 +1611,7 @@
 	struct eth_pdata *pdata = dev_get_platdata(dev);
 	struct mvneta_port *pp = dev_get_priv(dev);
 	void *blob = (void *)gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	struct mii_dev *bus;
 	unsigned long addr;
 	void *bd_space;
@@ -1691,7 +1691,8 @@
 
 	/* Get phy-mode / phy_interface from DT */
 	pdata->phy_interface = -1;
-	phy_mode = fdt_getprop(gd->fdt_blob, dev->of_offset, "phy-mode", NULL);
+	phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode",
+			       NULL);
 	if (phy_mode)
 		pdata->phy_interface = phy_get_interface_by_name(phy_mode);
 	if (pdata->phy_interface == -1) {
diff --git a/drivers/net/mvpp2.c b/drivers/net/mvpp2.c
index 405776a..88e88b9 100644
--- a/drivers/net/mvpp2.c
+++ b/drivers/net/mvpp2.c
@@ -4047,7 +4047,7 @@
 		return err;
 	}
 
-	return mvpp2_port_probe(dev, port, dev->of_offset, priv,
+	return mvpp2_port_probe(dev, port, dev_of_offset(dev), priv,
 				&buffer_loc.first_rxq);
 }
 
@@ -4138,7 +4138,7 @@
 static int mvpp2_base_bind(struct udevice *parent)
 {
 	const void *blob = gd->fdt_blob;
-	int node = parent->of_offset;
+	int node = dev_of_offset(parent);
 	struct uclass_driver *drv;
 	struct udevice *dev;
 	struct eth_pdata *plat;
@@ -4169,7 +4169,7 @@
 
 		/* Create child device UCLASS_ETH and bind it */
 		device_bind(parent, &mvpp2_driver, name, plat, subnode, &dev);
-		dev->of_offset = subnode;
+		dev_set_of_offset(dev, subnode);
 	}
 
 	return 0;
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 7163fa2..0e4a4eb 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -244,7 +244,7 @@
 		return -EOPNOTSUPP;
 
 	for (i = 0; i < ofcfg->grpsz; i++) {
-		val[i] = fdtdec_get_uint(gd->fdt_blob, dev->of_offset,
+		val[i] = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
 					 ofcfg->grp[i].name, -1);
 		offset = ofcfg->grp[i].off;
 		if (val[i] == -1) {
diff --git a/drivers/net/phy/ti.c b/drivers/net/phy/ti.c
index c55dd97..d1ce406 100644
--- a/drivers/net/phy/ti.c
+++ b/drivers/net/phy/ti.c
@@ -167,13 +167,13 @@
 	struct dp83867_private *dp83867 = phydev->priv;
 	struct udevice *dev = phydev->dev;
 
-	dp83867->rx_id_delay = fdtdec_get_uint(gd->fdt_blob, dev->of_offset,
+	dp83867->rx_id_delay = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
 				 "ti,rx-internal-delay", -1);
 
-	dp83867->tx_id_delay = fdtdec_get_uint(gd->fdt_blob, dev->of_offset,
+	dp83867->tx_id_delay = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
 				 "ti,tx-internal-delay", -1);
 
-	dp83867->fifo_depth = fdtdec_get_uint(gd->fdt_blob, dev->of_offset,
+	dp83867->fifo_depth = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
 				 "ti,fifo-depth", -1);
 
 	return 0;
diff --git a/drivers/net/phy/xilinx_phy.c b/drivers/net/phy/xilinx_phy.c
index 920bfcb..3f80f04 100644
--- a/drivers/net/phy/xilinx_phy.c
+++ b/drivers/net/phy/xilinx_phy.c
@@ -104,7 +104,7 @@
 	u32 phytype;
 
 	debug("%s\n", __func__);
-	phytype = fdtdec_get_int(gd->fdt_blob, phydev->dev->of_offset,
+	phytype = fdtdec_get_int(gd->fdt_blob, dev_of_offset(phydev->dev),
 				 "phy-type", -1);
 	if (phytype == XAE_PHY_TYPE_1000BASE_X)
 		phydev->flags |= XAE_PHY_TYPE_1000BASE_X;
diff --git a/drivers/net/pic32_eth.c b/drivers/net/pic32_eth.c
index 167af8b..385aad5 100644
--- a/drivers/net/pic32_eth.c
+++ b/drivers/net/pic32_eth.c
@@ -535,7 +535,8 @@
 	int offset = 0;
 	int phy_addr = -1;
 
-	addr = fdtdec_get_addr_size(gd->fdt_blob, dev->of_offset, "reg", &size);
+	addr = fdtdec_get_addr_size(gd->fdt_blob, dev_of_offset(dev), "reg",
+				    &size);
 	if (addr == FDT_ADDR_T_NONE)
 		return -EINVAL;
 
@@ -544,7 +545,8 @@
 
 	/* get phy mode */
 	pdata->phy_interface = -1;
-	phy_mode = fdt_getprop(gd->fdt_blob, dev->of_offset, "phy-mode", NULL);
+	phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode",
+			       NULL);
 	if (phy_mode)
 		pdata->phy_interface = phy_get_interface_by_name(phy_mode);
 	if (pdata->phy_interface == -1) {
@@ -553,13 +555,13 @@
 	}
 
 	/* get phy addr */
-	offset = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset,
+	offset = fdtdec_lookup_phandle(gd->fdt_blob, dev_of_offset(dev),
 				       "phy-handle");
 	if (offset > 0)
 		phy_addr = fdtdec_get_int(gd->fdt_blob, offset, "reg", -1);
 
 	/* phy reset gpio */
-	gpio_request_by_name_nodev(gd->fdt_blob, dev->of_offset,
+	gpio_request_by_name_nodev(gd->fdt_blob, dev_of_offset(dev),
 				   "reset-gpios", 0,
 				   &priv->rst_gpio, GPIOD_IS_OUT);
 
diff --git a/drivers/net/sandbox-raw.c b/drivers/net/sandbox-raw.c
index 5912427..9742c2c 100644
--- a/drivers/net/sandbox-raw.c
+++ b/drivers/net/sandbox-raw.c
@@ -26,7 +26,7 @@
 
 	debug("eth_sandbox_raw: Start\n");
 
-	interface = fdt_getprop(gd->fdt_blob, dev->of_offset,
+	interface = fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
 					    "host-raw-interface", NULL);
 	if (interface == NULL)
 		return -EINVAL;
diff --git a/drivers/net/sandbox.c b/drivers/net/sandbox.c
index d538d37..79d0ae6 100644
--- a/drivers/net/sandbox.c
+++ b/drivers/net/sandbox.c
@@ -60,8 +60,9 @@
 
 	debug("eth_sandbox: Start\n");
 
-	fdtdec_get_byte_array(gd->fdt_blob, dev->of_offset, "fake-host-hwaddr",
-			      priv->fake_host_hwaddr, ARP_HLEN);
+	fdtdec_get_byte_array(gd->fdt_blob, dev_of_offset(dev),
+			      "fake-host-hwaddr", priv->fake_host_hwaddr,
+			      ARP_HLEN);
 	priv->recv_packet_buffer = net_rx_packets[0];
 	return 0;
 }
diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c
index abd9cc8..b87210b 100644
--- a/drivers/net/sun8i_emac.c
+++ b/drivers/net/sun8i_emac.c
@@ -442,7 +442,7 @@
 	const char *pin_name;
 	int drive, pull, i;
 
-	offset = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset,
+	offset = fdtdec_lookup_phandle(gd->fdt_blob, dev_of_offset(dev),
 				       "pinctrl-0");
 	if (offset < 0) {
 		printf("WARNING: emac: cannot find pinctrl-0 node\n");
@@ -716,6 +716,7 @@
 	struct eth_pdata *pdata = dev_get_platdata(dev);
 	struct emac_eth_dev *priv = dev_get_priv(dev);
 	const char *phy_mode;
+	int node = dev_of_offset(dev);
 	int offset = 0;
 
 	pdata->iobase = dev_get_addr_name(dev, "emac");
@@ -725,13 +726,13 @@
 	priv->phyaddr = -1;
 	priv->use_internal_phy = false;
 
-	offset = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset,
+	offset = fdtdec_lookup_phandle(gd->fdt_blob, node,
 				       "phy");
 	if (offset > 0)
 		priv->phyaddr = fdtdec_get_int(gd->fdt_blob, offset, "reg",
 					       -1);
 
-	phy_mode = fdt_getprop(gd->fdt_blob, dev->of_offset, "phy-mode", NULL);
+	phy_mode = fdt_getprop(gd->fdt_blob, node, "phy-mode", NULL);
 
 	if (phy_mode)
 		pdata->phy_interface = phy_get_interface_by_name(phy_mode);
@@ -751,7 +752,7 @@
 	}
 
 	if (priv->variant == H3_EMAC) {
-		if (fdt_getprop(gd->fdt_blob, dev->of_offset,
+		if (fdt_getprop(gd->fdt_blob, node,
 				"allwinner,use-internal-phy", NULL))
 			priv->use_internal_phy = true;
 	}
diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c
index 7df4c63..f2ce4e2 100644
--- a/drivers/net/tsec.c
+++ b/drivers/net/tsec.c
@@ -783,7 +783,7 @@
 	pdata->iobase = (phys_addr_t)dev_get_addr(dev);
 	priv->regs = (struct tsec *)pdata->iobase;
 
-	offset = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset,
+	offset = fdtdec_lookup_phandle(gd->fdt_blob, dev_of_offset(dev),
 				       "phy-handle");
 	if (offset > 0) {
 		reg = fdtdec_get_int(gd->fdt_blob, offset, "reg", 0);
@@ -802,7 +802,7 @@
 		return -ENOENT;
 	}
 
-	offset = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset,
+	offset = fdtdec_lookup_phandle(gd->fdt_blob, dev_of_offset(dev),
 				       "tbi-handle");
 	if (offset > 0) {
 		reg = fdtdec_get_int(gd->fdt_blob, offset, "reg",
@@ -812,7 +812,7 @@
 		priv->tbiaddr = CONFIG_SYS_TBIPA_VALUE;
 	}
 
-	phy_mode = fdt_getprop(gd->fdt_blob, dev->of_offset,
+	phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
 			       "phy-connection-type", NULL);
 	if (phy_mode)
 		pdata->phy_interface = phy_get_interface_by_name(phy_mode);
diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c
index 51c7426..a6f24b3 100644
--- a/drivers/net/xilinx_axi_emac.c
+++ b/drivers/net/xilinx_axi_emac.c
@@ -682,13 +682,14 @@
 {
 	struct eth_pdata *pdata = dev_get_platdata(dev);
 	struct axidma_priv *priv = dev_get_priv(dev);
+	int node = dev_of_offset(dev);
 	int offset = 0;
 	const char *phy_mode;
 
 	pdata->iobase = (phys_addr_t)dev_get_addr(dev);
 	priv->iobase = (struct axi_regs *)pdata->iobase;
 
-	offset = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset,
+	offset = fdtdec_lookup_phandle(gd->fdt_blob, node,
 				       "axistream-connected");
 	if (offset <= 0) {
 		printf("%s: axistream is not found\n", __func__);
@@ -705,12 +706,11 @@
 
 	priv->phyaddr = -1;
 
-	offset = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset,
-				       "phy-handle");
+	offset = fdtdec_lookup_phandle(gd->fdt_blob, node, "phy-handle");
 	if (offset > 0)
 		priv->phyaddr = fdtdec_get_int(gd->fdt_blob, offset, "reg", -1);
 
-	phy_mode = fdt_getprop(gd->fdt_blob, dev->of_offset, "phy-mode", NULL);
+	phy_mode = fdt_getprop(gd->fdt_blob, node, "phy-mode", NULL);
 	if (phy_mode)
 		pdata->phy_interface = phy_get_interface_by_name(phy_mode);
 	if (pdata->phy_interface == -1) {
diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c
index ea93cf9..7d4e14f 100644
--- a/drivers/net/xilinx_emaclite.c
+++ b/drivers/net/xilinx_emaclite.c
@@ -604,15 +604,15 @@
 
 	emaclite->phyaddr = -1;
 
-	offset = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset,
+	offset = fdtdec_lookup_phandle(gd->fdt_blob, dev_of_offset(dev),
 				      "phy-handle");
 	if (offset > 0)
 		emaclite->phyaddr = fdtdec_get_int(gd->fdt_blob, offset,
 						   "reg", -1);
 
-	emaclite->txpp = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+	emaclite->txpp = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 					"xlnx,tx-ping-pong", 0);
-	emaclite->rxpp = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+	emaclite->rxpp = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 					"xlnx,rx-ping-pong", 0);
 
 	printf("EMACLITE: %lx, phyaddr %d, %d/%d\n", (ulong)emaclite->regs,
diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c
index 6dd87cf..86dd03f 100644
--- a/drivers/net/zynq_gem.c
+++ b/drivers/net/zynq_gem.c
@@ -345,7 +345,7 @@
 	priv->phydev->advertising = priv->phydev->supported;
 
 	if (priv->phy_of_handle > 0)
-		priv->phydev->dev->of_offset = priv->phy_of_handle;
+		dev_set_of_offset(priv->phydev->dev, priv->phy_of_handle);
 
 	return phy_config(priv->phydev);
 }
@@ -684,6 +684,7 @@
 {
 	struct eth_pdata *pdata = dev_get_platdata(dev);
 	struct zynq_gem_priv *priv = dev_get_priv(dev);
+	int node = dev_of_offset(dev);
 	const char *phy_mode;
 
 	pdata->iobase = (phys_addr_t)dev_get_addr(dev);
@@ -692,13 +693,13 @@
 	priv->emio = 0;
 	priv->phyaddr = -1;
 
-	priv->phy_of_handle = fdtdec_lookup_phandle(gd->fdt_blob,
-					dev->of_offset, "phy-handle");
+	priv->phy_of_handle = fdtdec_lookup_phandle(gd->fdt_blob, node,
+						    "phy-handle");
 	if (priv->phy_of_handle > 0)
 		priv->phyaddr = fdtdec_get_int(gd->fdt_blob,
 					priv->phy_of_handle, "reg", -1);
 
-	phy_mode = fdt_getprop(gd->fdt_blob, dev->of_offset, "phy-mode", NULL);
+	phy_mode = fdt_getprop(gd->fdt_blob, node, "phy-mode", NULL);
 	if (phy_mode)
 		pdata->phy_interface = phy_get_interface_by_name(phy_mode);
 	if (pdata->phy_interface == -1) {
@@ -707,7 +708,7 @@
 	}
 	priv->interface = pdata->phy_interface;
 
-	priv->emio = fdtdec_get_bool(gd->fdt_blob, dev->of_offset, "xlnx,emio");
+	priv->emio = fdtdec_get_bool(gd->fdt_blob, node, "xlnx,emio");
 
 	printf("ZYNQ GEM: %lx, phyaddr %x, interface %s\n", (ulong)priv->iobase,
 	       priv->phyaddr, phy_string_for_interface(priv->interface));
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index 3b00e6a..a1408f5 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -839,8 +839,9 @@
 	/* For bridges, use the top-level PCI controller */
 	if (!device_is_on_pci_bus(bus)) {
 		hose->ctlr = bus;
-		ret = decode_regions(hose, gd->fdt_blob, bus->parent->of_offset,
-				bus->of_offset);
+		ret = decode_regions(hose, gd->fdt_blob,
+				     dev_of_offset(bus->parent),
+				     dev_of_offset(bus));
 		if (ret) {
 			debug("%s: Cannot decode regions\n", __func__);
 			return ret;
@@ -903,7 +904,7 @@
 	struct fdt_pci_addr addr;
 	int ret;
 
-	if (dev->of_offset == -1)
+	if (dev_of_offset(dev) == -1)
 		return 0;
 
 	/*
@@ -911,7 +912,7 @@
 	 * just check the address.
 	 */
 	pplat = dev_get_parent_platdata(dev);
-	ret = fdtdec_get_pci_addr(gd->fdt_blob, dev->of_offset,
+	ret = fdtdec_get_pci_addr(gd->fdt_blob, dev_of_offset(dev),
 				  FDT_PCI_SPACE_CONFIG, "reg", &addr);
 
 	if (ret) {
diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c
index cd083f7..57204c4 100644
--- a/drivers/pci/pci_rom.c
+++ b/drivers/pci/pci_rom.c
@@ -334,7 +334,7 @@
 			goto err;
 #endif
 	} else {
-#ifdef CONFIG_X86
+#if defined(CONFIG_X86) && CONFIG_IS_ENABLED(X86_32BIT_INIT)
 		bios_set_interrupt_handler(0x15, int15_handler);
 
 		bios_run_on_x86(dev, (unsigned long)ram, vesa_mode,
diff --git a/drivers/pci/pci_tegra.c b/drivers/pci/pci_tegra.c
index 430270e..7d9c63b 100644
--- a/drivers/pci/pci_tegra.c
+++ b/drivers/pci/pci_tegra.c
@@ -1099,7 +1099,7 @@
 
 	INIT_LIST_HEAD(&pcie->ports);
 
-	if (tegra_pcie_parse_dt(gd->fdt_blob, dev->of_offset, id, pcie))
+	if (tegra_pcie_parse_dt(gd->fdt_blob, dev_of_offset(dev), id, pcie))
 		return -EINVAL;
 
 	return 0;
diff --git a/drivers/pci/pcie_layerscape.c b/drivers/pci/pcie_layerscape.c
index 90b9fe2..b6806cf 100644
--- a/drivers/pci/pcie_layerscape.c
+++ b/drivers/pci/pcie_layerscape.c
@@ -438,7 +438,7 @@
 {
 	struct ls_pcie *pcie = dev_get_priv(dev);
 	const void *fdt = gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	u8 header_type;
 	u16 link_sta;
 	bool ep_mode;
diff --git a/drivers/pci/pcie_xilinx.c b/drivers/pci/pcie_xilinx.c
index 5216001..08e2e93 100644
--- a/drivers/pci/pcie_xilinx.c
+++ b/drivers/pci/pcie_xilinx.c
@@ -186,7 +186,7 @@
 	DECLARE_GLOBAL_DATA_PTR;
 	int err;
 
-	err = fdt_get_resource(gd->fdt_blob, dev->of_offset, "reg",
+	err = fdt_get_resource(gd->fdt_blob, dev_of_offset(dev), "reg",
 			       0, &reg_res);
 	if (err < 0) {
 		error("\"reg\" resource not found\n");
diff --git a/drivers/phy/marvell/comphy_core.c b/drivers/phy/marvell/comphy_core.c
index bc2508b..caa1928 100644
--- a/drivers/phy/marvell/comphy_core.c
+++ b/drivers/phy/marvell/comphy_core.c
@@ -107,7 +107,7 @@
 static int comphy_probe(struct udevice *dev)
 {
 	const void *blob = gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	struct chip_serdes_phy_config *chip_cfg = dev_get_priv(dev);
 	struct comphy_map comphy_map_data[MAX_LANE_OPTIONS];
 	int subnode;
diff --git a/drivers/pinctrl/ath79/pinctrl_ar933x.c b/drivers/pinctrl/ath79/pinctrl_ar933x.c
index e3f64b6..fccc7c4 100644
--- a/drivers/pinctrl/ath79/pinctrl_ar933x.c
+++ b/drivers/pinctrl/ath79/pinctrl_ar933x.c
@@ -75,7 +75,7 @@
 	u32 cell[2];
 	int ret;
 
-	ret = fdtdec_get_int_array(gd->fdt_blob, periph->of_offset,
+	ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(periph),
 				   "interrupts", cell, ARRAY_SIZE(cell));
 	if (ret < 0)
 		return -EINVAL;
diff --git a/drivers/pinctrl/ath79/pinctrl_qca953x.c b/drivers/pinctrl/ath79/pinctrl_qca953x.c
index d02597e..a7f8c70 100644
--- a/drivers/pinctrl/ath79/pinctrl_qca953x.c
+++ b/drivers/pinctrl/ath79/pinctrl_qca953x.c
@@ -95,7 +95,7 @@
 	u32 cell[2];
 	int ret;
 
-	ret = fdtdec_get_int_array(gd->fdt_blob, periph->of_offset,
+	ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(periph),
 				   "interrupts", cell, ARRAY_SIZE(cell));
 	if (ret < 0)
 		return -EINVAL;
diff --git a/drivers/pinctrl/exynos/pinctrl-exynos.c b/drivers/pinctrl/exynos/pinctrl-exynos.c
index dd0a16e..5b9a592 100644
--- a/drivers/pinctrl/exynos/pinctrl-exynos.c
+++ b/drivers/pinctrl/exynos/pinctrl-exynos.c
@@ -70,7 +70,7 @@
 int exynos_pinctrl_set_state(struct udevice *dev, struct udevice *config)
 {
 	const void *fdt = gd->fdt_blob;
-	int node = config->of_offset;
+	int node = dev_of_offset(config);
 	unsigned int count, idx, pin_num;
 	unsigned int pinfunc, pinpud, pindrv;
 	unsigned long reg, value;
diff --git a/drivers/pinctrl/meson/pinctrl-meson.c b/drivers/pinctrl/meson/pinctrl-meson.c
index 30f7cfc..b5486b8 100644
--- a/drivers/pinctrl/meson/pinctrl-meson.c
+++ b/drivers/pinctrl/meson/pinctrl-meson.c
@@ -142,19 +142,19 @@
 	int node, gpio = -1, len;
 	int na, ns;
 
-	na = fdt_address_cells(gd->fdt_blob, dev->parent->of_offset);
+	na = fdt_address_cells(gd->fdt_blob, dev_of_offset(dev->parent));
 	if (na < 1) {
 		debug("bad #address-cells\n");
 		return -EINVAL;
 	}
 
-	ns = fdt_size_cells(gd->fdt_blob, dev->parent->of_offset);
+	ns = fdt_size_cells(gd->fdt_blob, dev_of_offset(dev->parent));
 	if (ns < 1) {
 		debug("bad #size-cells\n");
 		return -EINVAL;
 	}
 
-	fdt_for_each_subnode(node, gd->fdt_blob, dev->of_offset) {
+	fdt_for_each_subnode(node, gd->fdt_blob, dev_of_offset(dev)) {
 		if (fdt_getprop(gd->fdt_blob, node, "gpio-controller", &len)) {
 			gpio = node;
 			break;
diff --git a/drivers/pinctrl/mvebu/pinctrl-mvebu.c b/drivers/pinctrl/mvebu/pinctrl-mvebu.c
index b077639..80f0dfa 100644
--- a/drivers/pinctrl/mvebu/pinctrl-mvebu.c
+++ b/drivers/pinctrl/mvebu/pinctrl-mvebu.c
@@ -28,7 +28,7 @@
 int mvebu_pinctrl_set_state(struct udevice *dev, struct udevice *config)
 {
 	const void *blob = gd->fdt_blob;
-	int node = config->of_offset;
+	int node = dev_of_offset(config);
 	struct mvebu_pinctrl_priv *priv;
 	u32 pin_arr[MVEBU_MAX_PINS_PER_BANK];
 	u32 function;
@@ -82,7 +82,7 @@
 				       struct udevice *config)
 {
 	const void *blob = gd->fdt_blob;
-	int node = config->of_offset;
+	int node = dev_of_offset(config);
 	struct mvebu_pinctrl_priv *priv;
 	u32 func_arr[MVEBU_MAX_PINS_PER_BANK];
 	int pin, err;
@@ -128,7 +128,7 @@
 int mvebu_pinctl_probe(struct udevice *dev)
 {
 	const void *blob = gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	struct mvebu_pinctrl_priv *priv;
 
 	priv = dev_get_priv(dev);
diff --git a/drivers/pinctrl/nxp/pinctrl-imx.c b/drivers/pinctrl/nxp/pinctrl-imx.c
index 949d0f3..e130faf 100644
--- a/drivers/pinctrl/nxp/pinctrl-imx.c
+++ b/drivers/pinctrl/nxp/pinctrl-imx.c
@@ -19,7 +19,7 @@
 {
 	struct imx_pinctrl_priv *priv = dev_get_priv(dev);
 	struct imx_pinctrl_soc_info *info = priv->info;
-	int node = config->of_offset;
+	int node = dev_of_offset(config);
 	const struct fdt_property *prop;
 	u32 *pin_data;
 	int npins, size, pin_size;
@@ -176,7 +176,7 @@
 		      struct imx_pinctrl_soc_info *info)
 {
 	struct imx_pinctrl_priv *priv = dev_get_priv(dev);
-	int node = dev->of_offset, ret;
+	int node = dev_of_offset(dev), ret;
 	struct fdtdec_phandle_args arg;
 	fdt_addr_t addr;
 	fdt_size_t size;
@@ -189,7 +189,8 @@
 	priv->dev = dev;
 	priv->info = info;
 
-	addr = fdtdec_get_addr_size(gd->fdt_blob, dev->of_offset, "reg", &size);
+	addr = fdtdec_get_addr_size(gd->fdt_blob, dev_of_offset(dev), "reg",
+				    &size);
 
 	if (addr == FDT_ADDR_T_NONE)
 		return -EINVAL;
diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c
index 6d4aadc..5c6bff5 100644
--- a/drivers/pinctrl/pinctrl-at91-pio4.c
+++ b/drivers/pinctrl/pinctrl-at91-pio4.c
@@ -109,7 +109,7 @@
 {
 	struct atmel_pio4_port *bank_base;
 	const void *blob = gd->fdt_blob;
-	int node = config->of_offset;
+	int node = dev_of_offset(config);
 	u32 offset, func, bank, line;
 	u32 cells[MAX_PINMUX_ENTRIES];
 	u32 i, conf;
diff --git a/drivers/pinctrl/pinctrl-generic.c b/drivers/pinctrl/pinctrl-generic.c
index 3629322..0272496 100644
--- a/drivers/pinctrl/pinctrl-generic.c
+++ b/drivers/pinctrl/pinctrl-generic.c
@@ -245,7 +245,7 @@
 					 bool is_group, unsigned selector)
 {
 	const void *fdt = gd->fdt_blob;
-	int node_offset = config->of_offset;
+	int node_offset = dev_of_offset(config);
 	const char *propname;
 	const void *value;
 	int prop_offset, len, func_selector, param, ret;
@@ -300,7 +300,7 @@
 					     struct udevice *config)
 {
 	const void *fdt = gd->fdt_blob;
-	int node = config->of_offset;
+	int node = dev_of_offset(config);
 	const char *subnode_target_type = "pins";
 	bool is_group = false;
 	const char *name;
diff --git a/drivers/pinctrl/pinctrl-uclass.c b/drivers/pinctrl/pinctrl-uclass.c
index 02ab9b4..49afe91 100644
--- a/drivers/pinctrl/pinctrl-uclass.c
+++ b/drivers/pinctrl/pinctrl-uclass.c
@@ -64,7 +64,7 @@
 static int pinctrl_select_state_full(struct udevice *dev, const char *statename)
 {
 	const void *fdt = gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	char propname[32]; /* long enough */
 	const fdt32_t *list;
 	uint32_t phandle;
@@ -122,7 +122,7 @@
 static int pinconfig_post_bind(struct udevice *dev)
 {
 	const void *fdt = gd->fdt_blob;
-	int offset = dev->of_offset;
+	int offset = dev_of_offset(dev);
 	bool pre_reloc_only = !(gd->flags & GD_FLG_RELOC);
 	const char *name;
 	int ret;
diff --git a/drivers/pinctrl/pinctrl_pic32.c b/drivers/pinctrl/pinctrl_pic32.c
index 9acac29..59466ee 100644
--- a/drivers/pinctrl/pinctrl_pic32.c
+++ b/drivers/pinctrl/pinctrl_pic32.c
@@ -253,7 +253,7 @@
 	int ret;
 	u32 cell[2];
 
-	ret = fdtdec_get_int_array(gd->fdt_blob, periph->of_offset,
+	ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(periph),
 				   "interrupts", cell, ARRAY_SIZE(cell));
 	if (ret < 0)
 		return -EINVAL;
@@ -310,7 +310,7 @@
 	struct pic32_pinctrl_priv *priv = dev_get_priv(dev);
 	struct fdt_resource res;
 	void *fdt = (void *)gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	int ret;
 
 	ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3036.c b/drivers/pinctrl/rockchip/pinctrl_rk3036.c
index 6aea856..8d42584 100644
--- a/drivers/pinctrl/rockchip/pinctrl_rk3036.c
+++ b/drivers/pinctrl/rockchip/pinctrl_rk3036.c
@@ -205,7 +205,7 @@
 	u32 cell[3];
 	int ret;
 
-	ret = fdtdec_get_int_array(gd->fdt_blob, periph->of_offset,
+	ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(periph),
 				   "interrupts", cell, ARRAY_SIZE(cell));
 	if (ret < 0)
 		return -EINVAL;
diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3288.c b/drivers/pinctrl/rockchip/pinctrl_rk3288.c
index 0322264..cb13d30 100644
--- a/drivers/pinctrl/rockchip/pinctrl_rk3288.c
+++ b/drivers/pinctrl/rockchip/pinctrl_rk3288.c
@@ -479,7 +479,7 @@
 	u32 cell[3];
 	int ret;
 
-	ret = fdtdec_get_int_array(gd->fdt_blob, periph->of_offset,
+	ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(periph),
 				   "interrupts", cell, ARRAY_SIZE(cell));
 	if (ret < 0)
 		return -EINVAL;
@@ -644,7 +644,7 @@
 	u32 cell[60], *ptr;
 
 	debug("%s: %s %s\n", __func__, dev->name, config->name);
-	ret = fdtdec_get_int_array_count(blob, config->of_offset,
+	ret = fdtdec_get_int_array_count(blob, dev_of_offset(config),
 					 "rockchip,pins", cell,
 					 ARRAY_SIZE(cell));
 	if (ret < 0) {
diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3399.c b/drivers/pinctrl/rockchip/pinctrl_rk3399.c
index 17ea165..da30154 100644
--- a/drivers/pinctrl/rockchip/pinctrl_rk3399.c
+++ b/drivers/pinctrl/rockchip/pinctrl_rk3399.c
@@ -362,7 +362,7 @@
 	u32 cell[3];
 	int ret;
 
-	ret = fdtdec_get_int_array(gd->fdt_blob, periph->of_offset,
+	ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(periph),
 				   "interrupts", cell, ARRAY_SIZE(cell));
 	if (ret < 0)
 		return -EINVAL;
diff --git a/drivers/power/domain/power-domain-uclass.c b/drivers/power/domain/power-domain-uclass.c
index 1bb6262..3dabbe4 100644
--- a/drivers/power/domain/power-domain-uclass.c
+++ b/drivers/power/domain/power-domain-uclass.c
@@ -41,7 +41,7 @@
 
 	debug("%s(dev=%p, power_domain=%p)\n", __func__, dev, power_domain);
 
-	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset,
+	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
 					     "power-domains",
 					     "#power-domain-cells", 0, 0,
 					     &args);
diff --git a/drivers/power/pmic/act8846.c b/drivers/power/pmic/act8846.c
index e8164bf..15da12e 100644
--- a/drivers/power/pmic/act8846.c
+++ b/drivers/power/pmic/act8846.c
@@ -52,7 +52,7 @@
 	int regulators_node;
 	int children;
 
-	regulators_node = fdt_subnode_offset(blob, dev->of_offset,
+	regulators_node = fdt_subnode_offset(blob, dev_of_offset(dev),
 					     "regulators");
 	if (regulators_node <= 0) {
 		debug("%s: %s regulators subnode not found!", __func__,
diff --git a/drivers/power/pmic/i2c_pmic_emul.c b/drivers/power/pmic/i2c_pmic_emul.c
index aeab5c9..4f92e3d 100644
--- a/drivers/power/pmic/i2c_pmic_emul.c
+++ b/drivers/power/pmic/i2c_pmic_emul.c
@@ -108,9 +108,9 @@
 
 	debug("%s:%d Setting PMIC default registers\n", __func__, __LINE__);
 
-	reg_defaults = fdtdec_locate_byte_array(gd->fdt_blob, emul->of_offset,
-						"reg-defaults",
-						SANDBOX_PMIC_REG_COUNT);
+	reg_defaults = fdtdec_locate_byte_array(gd->fdt_blob,
+			dev_of_offset(emul), "reg-defaults",
+			SANDBOX_PMIC_REG_COUNT);
 
 	if (!reg_defaults) {
 		error("Property \"reg-defaults\" not found for device: %s!",
diff --git a/drivers/power/pmic/lp873x.c b/drivers/power/pmic/lp873x.c
index 307f96b..d8f30df 100644
--- a/drivers/power/pmic/lp873x.c
+++ b/drivers/power/pmic/lp873x.c
@@ -49,7 +49,7 @@
 	int regulators_node;
 	const void *blob = gd->fdt_blob;
 	int children;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 
 	regulators_node = fdt_subnode_offset(blob, node, "regulators");
 
diff --git a/drivers/power/pmic/max77686.c b/drivers/power/pmic/max77686.c
index dc5a54a..8295fab 100644
--- a/drivers/power/pmic/max77686.c
+++ b/drivers/power/pmic/max77686.c
@@ -54,7 +54,7 @@
 	const void *blob = gd->fdt_blob;
 	int children;
 
-	regulators_node = fdt_subnode_offset(blob, dev->of_offset,
+	regulators_node = fdt_subnode_offset(blob, dev_of_offset(dev),
 					     "voltage-regulators");
 	if (regulators_node <= 0) {
 		debug("%s: %s regulators subnode not found!", __func__,
diff --git a/drivers/power/pmic/palmas.c b/drivers/power/pmic/palmas.c
index 0ab425e..f5a2307 100644
--- a/drivers/power/pmic/palmas.c
+++ b/drivers/power/pmic/palmas.c
@@ -49,7 +49,7 @@
 	int pmic_node = -1, regulators_node;
 	const void *blob = gd->fdt_blob;
 	int children;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	int subnode, len;
 
 	fdt_for_each_subnode(subnode, blob, node) {
diff --git a/drivers/power/pmic/pfuze100.c b/drivers/power/pmic/pfuze100.c
index 3beb48e..90a43f2 100644
--- a/drivers/power/pmic/pfuze100.c
+++ b/drivers/power/pmic/pfuze100.c
@@ -56,7 +56,7 @@
 	int regulators_node;
 	const void *blob = gd->fdt_blob;
 
-	regulators_node = fdt_subnode_offset(blob, dev->of_offset,
+	regulators_node = fdt_subnode_offset(blob, dev_of_offset(dev),
 					     "regulators");
 	if (regulators_node <= 0) {
 		debug("%s: %s regulators subnode not found!", __func__,
diff --git a/drivers/power/pmic/pmic-uclass.c b/drivers/power/pmic/pmic-uclass.c
index 7211026..0f7fa51 100644
--- a/drivers/power/pmic/pmic-uclass.c
+++ b/drivers/power/pmic/pmic-uclass.c
@@ -33,7 +33,7 @@
 	int ret;
 
 	debug("%s for '%s' at node offset: %d\n", __func__, pmic->name,
-	      pmic->of_offset);
+	      dev_of_offset(pmic));
 
 	for (node = fdt_first_subnode(blob, offset);
 	     node > 0;
diff --git a/drivers/power/pmic/rk808.c b/drivers/power/pmic/rk808.c
index 770f471..3f5f316 100644
--- a/drivers/power/pmic/rk808.c
+++ b/drivers/power/pmic/rk808.c
@@ -61,7 +61,7 @@
 	int regulators_node;
 	int children;
 
-	regulators_node = fdt_subnode_offset(blob, dev->of_offset,
+	regulators_node = fdt_subnode_offset(blob, dev_of_offset(dev),
 					     "regulators");
 	if (regulators_node <= 0) {
 		debug("%s: %s regulators subnode not found!", __func__,
diff --git a/drivers/power/pmic/s5m8767.c b/drivers/power/pmic/s5m8767.c
index 075fe7e..25d673b 100644
--- a/drivers/power/pmic/s5m8767.c
+++ b/drivers/power/pmic/s5m8767.c
@@ -58,7 +58,7 @@
 	const void *blob = gd->fdt_blob;
 	int children;
 
-	node = fdt_subnode_offset(blob, dev->of_offset, "regulators");
+	node = fdt_subnode_offset(blob, dev_of_offset(dev), "regulators");
 	if (node <= 0) {
 		debug("%s: %s regulators subnode not found!", __func__,
 		      dev->name);
diff --git a/drivers/power/pmic/sandbox.c b/drivers/power/pmic/sandbox.c
index 3e56acd..b4e412e 100644
--- a/drivers/power/pmic/sandbox.c
+++ b/drivers/power/pmic/sandbox.c
@@ -51,7 +51,7 @@
 
 static int sandbox_pmic_bind(struct udevice *dev)
 {
-	if (!pmic_bind_children(dev, dev->of_offset, pmic_children_info))
+	if (!pmic_bind_children(dev, dev_of_offset(dev), pmic_children_info))
 		error("%s:%d PMIC: %s - no child found!", __func__, __LINE__,
 							  dev->name);
 
diff --git a/drivers/power/pmic/tps65090.c b/drivers/power/pmic/tps65090.c
index 4797f32..b30a7f0 100644
--- a/drivers/power/pmic/tps65090.c
+++ b/drivers/power/pmic/tps65090.c
@@ -56,7 +56,7 @@
 	const void *blob = gd->fdt_blob;
 	int children;
 
-	regulators_node = fdt_subnode_offset(blob, dev->of_offset,
+	regulators_node = fdt_subnode_offset(blob, dev_of_offset(dev),
 					     "regulators");
 	if (regulators_node <= 0) {
 		debug("%s: %s regulators subnode not found!", __func__,
diff --git a/drivers/power/regulator/fixed.c b/drivers/power/regulator/fixed.c
index 3d2d908..cd52137 100644
--- a/drivers/power/regulator/fixed.c
+++ b/drivers/power/regulator/fixed.c
@@ -28,7 +28,7 @@
 	struct fixed_regulator_platdata *dev_pdata;
 	struct gpio_desc *gpio;
 	const void *blob = gd->fdt_blob;
-	int node = dev->of_offset, flags = GPIOD_IS_OUT;
+	int node = dev_of_offset(dev), flags = GPIOD_IS_OUT;
 	int ret;
 
 	dev_pdata = dev_get_platdata(dev);
@@ -54,7 +54,7 @@
 
 	/* Get optional ramp up delay */
 	dev_pdata->startup_delay_us = fdtdec_get_uint(gd->fdt_blob,
-						      dev->of_offset,
+						      dev_of_offset(dev),
 						      "startup-delay-us", 0);
 
 	return 0;
diff --git a/drivers/power/regulator/gpio-regulator.c b/drivers/power/regulator/gpio-regulator.c
index 0a60a9c..42391c6 100644
--- a/drivers/power/regulator/gpio-regulator.c
+++ b/drivers/power/regulator/gpio-regulator.c
@@ -30,7 +30,7 @@
 	struct gpio_regulator_platdata *dev_pdata;
 	struct gpio_desc *gpio;
 	const void *blob = gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	int ret, count, i, j;
 	u32 states_array[8];
 
diff --git a/drivers/power/regulator/palmas_regulator.c b/drivers/power/regulator/palmas_regulator.c
index cce7cd2..399f7a5 100644
--- a/drivers/power/regulator/palmas_regulator.c
+++ b/drivers/power/regulator/palmas_regulator.c
@@ -356,7 +356,7 @@
 		case 8:
 		case 9:
 		case 10:
-			idx = dev->driver_data - 4;
+			idx = dev->driver_data - 3;
 			uc_pdata->ctrl_reg = palmas_smps_ctrl[type][idx];
 			uc_pdata->volt_reg = palmas_smps_volt[type][idx];
 			break;
diff --git a/drivers/power/regulator/pwm_regulator.c b/drivers/power/regulator/pwm_regulator.c
index b0a4c5d..4875238 100644
--- a/drivers/power/regulator/pwm_regulator.c
+++ b/drivers/power/regulator/pwm_regulator.c
@@ -88,7 +88,7 @@
 	struct pwm_regulator_info *priv = dev_get_priv(dev);
 	struct fdtdec_phandle_args args;
 	const void *blob = gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	int ret;
 
 	ret = fdtdec_parse_phandle_with_args(blob, node, "pwms", "#pwm-cells",
diff --git a/drivers/power/regulator/regulator-uclass.c b/drivers/power/regulator/regulator-uclass.c
index 52a1070..2e0b5ed 100644
--- a/drivers/power/regulator/regulator-uclass.c
+++ b/drivers/power/regulator/regulator-uclass.c
@@ -278,7 +278,7 @@
 static int regulator_post_bind(struct udevice *dev)
 {
 	struct dm_regulator_uclass_platdata *uc_pdata;
-	int offset = dev->of_offset;
+	int offset = dev_of_offset(dev);
 	const void *blob = gd->fdt_blob;
 	const char *property = "regulator-name";
 
@@ -308,7 +308,7 @@
 static int regulator_pre_probe(struct udevice *dev)
 {
 	struct dm_regulator_uclass_platdata *uc_pdata;
-	int offset = dev->of_offset;
+	int offset = dev_of_offset(dev);
 
 	uc_pdata = dev_get_uclass_platdata(dev);
 	if (!uc_pdata)
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index af39347..b037130 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -10,10 +10,9 @@
 
 #ccflags-y += -DDEBUG
 
-obj-$(CONFIG_DM_PWM) += pwm-uclass.o
-obj-$(CONFIG_PWM_ROCKCHIP) += rk_pwm.o
-obj-$(CONFIG_PWM_IMX) += pwm-imx.o pwm-imx-util.o
-ifdef CONFIG_DM_PWM
-obj-$(CONFIG_PWM_TEGRA) += tegra_pwm.o
-obj-$(CONFIG_PWM_EXYNOS) += exynos_pwm.o
-endif
+obj-$(CONFIG_DM_PWM)		+= pwm-uclass.o
+
+obj-$(CONFIG_PWM_EXYNOS)	+= exynos_pwm.o
+obj-$(CONFIG_PWM_IMX)		+= pwm-imx.o pwm-imx-util.o
+obj-$(CONFIG_PWM_ROCKCHIP)	+= rk_pwm.o
+obj-$(CONFIG_PWM_TEGRA)		+= tegra_pwm.o
diff --git a/drivers/remoteproc/rproc-uclass.c b/drivers/remoteproc/rproc-uclass.c
index 200cf61..b6e67f2 100644
--- a/drivers/remoteproc/rproc-uclass.c
+++ b/drivers/remoteproc/rproc-uclass.c
@@ -116,7 +116,7 @@
 
 	if (!dev->platdata) {
 #if CONFIG_IS_ENABLED(OF_CONTROL)
-		int node = dev->of_offset;
+		int node = dev_of_offset(dev);
 		const void *blob = gd->fdt_blob;
 		bool tmp;
 		if (!blob) {
diff --git a/drivers/remoteproc/ti_power_proc.c b/drivers/remoteproc/ti_power_proc.c
index 76ac3be..bb7a145 100644
--- a/drivers/remoteproc/ti_power_proc.c
+++ b/drivers/remoteproc/ti_power_proc.c
@@ -33,7 +33,7 @@
 static int ti_of_to_priv(struct udevice *dev,
 			 struct ti_powerproc_privdata *priv)
 {
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	const void *blob = gd->fdt_blob;
 	int tmp;
 
diff --git a/drivers/reset/reset-uclass.c b/drivers/reset/reset-uclass.c
index d3744ef..e92b24f 100644
--- a/drivers/reset/reset-uclass.c
+++ b/drivers/reset/reset-uclass.c
@@ -43,7 +43,7 @@
 	debug("%s(dev=%p, index=%d, reset_ctl=%p)\n", __func__, dev, index,
 	      reset_ctl);
 
-	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset,
+	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
 					     "resets", "#reset-cells", 0,
 					     index, &args);
 	if (ret) {
@@ -88,7 +88,7 @@
 	debug("%s(dev=%p, name=%s, reset_ctl=%p)\n", __func__, dev, name,
 	      reset_ctl);
 
-	index = fdt_stringlist_search(gd->fdt_blob, dev->of_offset,
+	index = fdt_stringlist_search(gd->fdt_blob, dev_of_offset(dev),
 				      "reset-names", name);
 	if (index < 0) {
 		debug("fdt_stringlist_search() failed: %d\n", index);
diff --git a/drivers/serial/altera_uart.c b/drivers/serial/altera_uart.c
index eff9c59..8344940 100644
--- a/drivers/serial/altera_uart.c
+++ b/drivers/serial/altera_uart.c
@@ -92,7 +92,7 @@
 	plat->regs = map_physmem(dev_get_addr(dev),
 				 sizeof(struct altera_uart_regs),
 				 MAP_NOCACHE);
-	plat->uartclk = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+	plat->uartclk = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 		"clock-frequency", 0);
 
 	return 0;
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index 2df4a1f..1f819d4 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -383,13 +383,13 @@
 		int ret;
 
 		/* we prefer to use a memory-mapped register */
-		ret = fdtdec_get_pci_addr(gd->fdt_blob, dev->of_offset,
+		ret = fdtdec_get_pci_addr(gd->fdt_blob, dev_of_offset(dev),
 					  FDT_PCI_SPACE_MEM32, "reg",
 					  &pci_addr);
 		if (ret) {
 			/* try if there is any i/o-mapped register */
 			ret = fdtdec_get_pci_addr(gd->fdt_blob,
-						  dev->of_offset,
+						  dev_of_offset(dev),
 						  FDT_PCI_SPACE_IO,
 						  "reg", &pci_addr);
 			if (ret)
@@ -413,9 +413,9 @@
 	plat->base = (unsigned long)map_physmem(addr, 0, MAP_NOCACHE);
 #endif
 
-	plat->reg_offset = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+	plat->reg_offset = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 				     "reg-offset", 0);
-	plat->reg_shift = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+	plat->reg_shift = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 					 "reg-shift", 0);
 
 	err = clk_get_by_index(dev, 0, &clk);
@@ -429,7 +429,7 @@
 	}
 
 	if (!plat->clock)
-		plat->clock = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+		plat->clock = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 					     "clock-frequency",
 					     CONFIG_SYS_NS16550_CLK);
 	if (!plat->clock) {
diff --git a/drivers/serial/sandbox.c b/drivers/serial/sandbox.c
index bcc3465..858e340 100644
--- a/drivers/serial/sandbox.c
+++ b/drivers/serial/sandbox.c
@@ -152,7 +152,7 @@
 	int i;
 
 	plat->colour = -1;
-	colour = fdt_getprop(gd->fdt_blob, dev->of_offset,
+	colour = fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
 			     "sandbox,text-colour", NULL);
 	if (colour) {
 		for (i = 0; i < ARRAY_SIZE(ansi_colour); i++) {
diff --git a/drivers/serial/serial_arc.c b/drivers/serial/serial_arc.c
index 326a536..fc91977 100644
--- a/drivers/serial/serial_arc.c
+++ b/drivers/serial/serial_arc.c
@@ -115,7 +115,7 @@
 	DECLARE_GLOBAL_DATA_PTR;
 
 	plat->reg = (struct arc_serial_regs *)dev_get_addr(dev);
-	plat->uartclk = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+	plat->uartclk = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 				       "clock-frequency", 0);
 
 	return 0;
diff --git a/drivers/serial/serial_bcm283x_mu.c b/drivers/serial/serial_bcm283x_mu.c
index 3884f74..e7ed899 100644
--- a/drivers/serial/serial_bcm283x_mu.c
+++ b/drivers/serial/serial_bcm283x_mu.c
@@ -164,8 +164,9 @@
 		return -EINVAL;
 
 	plat->base = addr;
-	plat->clock = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "clock", 1);
-	plat->skip_init = fdtdec_get_bool(gd->fdt_blob, dev->of_offset,
+	plat->clock = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "clock",
+				     1);
+	plat->skip_init = fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
 	                                  "skip-init");
 	plat->disabled = false;
 	return 0;
diff --git a/drivers/serial/serial_msm.c b/drivers/serial/serial_msm.c
index a7cab13..63b3006 100644
--- a/drivers/serial/serial_msm.c
+++ b/drivers/serial/serial_msm.c
@@ -146,7 +146,7 @@
 
 static int msm_uart_clk_init(struct udevice *dev)
 {
-	uint clk_rate = fdtdec_get_uint(gd->fdt_blob, dev->of_offset,
+	uint clk_rate = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
 					"clock-frequency", 115200);
 	uint clkd[2]; /* clk_id and clk_no */
 	int clk_offset;
@@ -154,8 +154,8 @@
 	struct clk clk;
 	int ret;
 
-	ret = fdtdec_get_int_array(gd->fdt_blob, dev->of_offset, "clock", clkd,
-				   2);
+	ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev), "clock",
+				   clkd, 2);
 	if (ret)
 		return ret;
 
diff --git a/drivers/serial/serial_mxc.c b/drivers/serial/serial_mxc.c
index 4fd2b1d..1cfcbf2 100644
--- a/drivers/serial/serial_mxc.c
+++ b/drivers/serial/serial_mxc.c
@@ -359,7 +359,7 @@
 
 	plat->reg = (struct mxc_uart *)addr;
 
-	plat->use_dte = fdtdec_get_bool(gd->fdt_blob, dev->of_offset,
+	plat->use_dte = fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
 					"fsl,dte-mode");
 	return 0;
 }
diff --git a/drivers/serial/serial_pic32.c b/drivers/serial/serial_pic32.c
index c2141f0..b0e01aa 100644
--- a/drivers/serial/serial_pic32.c
+++ b/drivers/serial/serial_pic32.c
@@ -141,7 +141,8 @@
 	int ret;
 
 	/* get address */
-	addr = fdtdec_get_addr_size(gd->fdt_blob, dev->of_offset, "reg", &size);
+	addr = fdtdec_get_addr_size(gd->fdt_blob, dev_of_offset(dev), "reg",
+				    &size);
 	if (addr == FDT_ADDR_T_NONE)
 		return -EINVAL;
 
diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c
index a8d3d67..a49134a 100644
--- a/drivers/serial/serial_pl01x.c
+++ b/drivers/serial/serial_pl01x.c
@@ -354,9 +354,10 @@
 		return -EINVAL;
 
 	plat->base = addr;
-	plat->clock = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "clock", 1);
+	plat->clock = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "clock",
+				     1);
 	plat->type = dev_get_driver_data(dev);
-	plat->skip_init = fdtdec_get_bool(gd->fdt_blob, dev->of_offset,
+	plat->skip_init = fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
 	                                  "skip-init");
 	return 0;
 }
diff --git a/drivers/serial/serial_s5p.c b/drivers/serial/serial_s5p.c
index 6225479..96842de 100644
--- a/drivers/serial/serial_s5p.c
+++ b/drivers/serial/serial_s5p.c
@@ -187,7 +187,7 @@
 		return -EINVAL;
 
 	plat->reg = (struct s5p_uart *)addr;
-	plat->port_id = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+	plat->port_id = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 					"id", dev->seq);
 	return 0;
 }
diff --git a/drivers/serial/serial_sh.c b/drivers/serial/serial_sh.c
index ef7cf0f..51f7fbc 100644
--- a/drivers/serial/serial_sh.c
+++ b/drivers/serial/serial_sh.c
@@ -216,12 +216,13 @@
 	struct sh_serial_platdata *plat = dev_get_platdata(dev);
 	fdt_addr_t addr;
 
-	addr = fdtdec_get_addr(gd->fdt_blob, dev->of_offset, "reg");
+	addr = fdtdec_get_addr(gd->fdt_blob, dev_of_offset(dev), "reg");
 	if (addr == FDT_ADDR_T_NONE)
 		return -EINVAL;
 
 	plat->base = addr;
-	plat->clk = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "clock", 1);
+	plat->clk = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "clock",
+				   1);
 	plat->type = dev_get_driver_data(dev);
 	return 0;
 }
diff --git a/drivers/serial/serial_uniphier.c b/drivers/serial/serial_uniphier.c
index 4ea5304..0e25cba 100644
--- a/drivers/serial/serial_uniphier.c
+++ b/drivers/serial/serial_uniphier.c
@@ -105,7 +105,7 @@
 
 	priv->membase = port;
 
-	priv->uartclk = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+	priv->uartclk = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 				       "clock-frequency", 0);
 
 	tmp = readl(&port->lcr_mcr);
diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c
index f16f90d..9a6e41f 100644
--- a/drivers/spi/cadence_qspi.c
+++ b/drivers/spi/cadence_qspi.c
@@ -282,7 +282,7 @@
 {
 	struct cadence_spi_platdata *plat = bus->platdata;
 	const void *blob = gd->fdt_blob;
-	int node = bus->of_offset;
+	int node = dev_of_offset(bus);
 	int subnode;
 	u32 data[4];
 	int ret;
diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c
index 20aa99a..65d37b0 100644
--- a/drivers/spi/davinci_spi.c
+++ b/drivers/spi/davinci_spi.c
@@ -540,7 +540,7 @@
 {
 	struct davinci_spi_slave *ds = dev_get_priv(bus);
 	const void *blob = gd->fdt_blob;
-	int node = bus->of_offset;
+	int node = dev_of_offset(bus);
 
 	ds->regs = dev_map_physmem(bus, sizeof(struct davinci_spi_regs));
 	if (!ds->regs) {
diff --git a/drivers/spi/designware_spi.c b/drivers/spi/designware_spi.c
index 24a6e98..9d5e29c 100644
--- a/drivers/spi/designware_spi.c
+++ b/drivers/spi/designware_spi.c
@@ -132,7 +132,7 @@
 {
 	struct dw_spi_platdata *plat = bus->platdata;
 	const void *blob = gd->fdt_blob;
-	int node = bus->of_offset;
+	int node = dev_of_offset(bus);
 
 	plat->regs = (struct dw_spi *)dev_get_addr(bus);
 
diff --git a/drivers/spi/exynos_spi.c b/drivers/spi/exynos_spi.c
index 44948c3..aa0784c 100644
--- a/drivers/spi/exynos_spi.c
+++ b/drivers/spi/exynos_spi.c
@@ -253,7 +253,7 @@
 {
 	struct exynos_spi_platdata *plat = bus->platdata;
 	const void *blob = gd->fdt_blob;
-	int node = bus->of_offset;
+	int node = dev_of_offset(bus);
 
 	plat->regs = (struct exynos_spi *)dev_get_addr(bus);
 	plat->periph_id = pinmux_decode_periph_id(blob, node);
diff --git a/drivers/spi/fsl_dspi.c b/drivers/spi/fsl_dspi.c
index f213587..e09985e 100644
--- a/drivers/spi/fsl_dspi.c
+++ b/drivers/spi/fsl_dspi.c
@@ -646,7 +646,7 @@
 	fdt_addr_t addr;
 	struct fsl_dspi_platdata *plat = bus->platdata;
 	const void *blob = gd->fdt_blob;
-	int node = bus->of_offset;
+	int node = dev_of_offset(bus);
 
 	if (fdtdec_get_bool(blob, node, "big-endian"))
 		plat->flags |= DSPI_FLAG_REGMAP_ENDIAN_BIG;
diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c
index 4d378c2..b2a0583 100644
--- a/drivers/spi/fsl_qspi.c
+++ b/drivers/spi/fsl_qspi.c
@@ -1078,7 +1078,7 @@
 	struct fdt_resource res_regs, res_mem;
 	struct fsl_qspi_platdata *plat = bus->platdata;
 	const void *blob = gd->fdt_blob;
-	int node = bus->of_offset;
+	int node = dev_of_offset(bus);
 	int ret, flash_num = 0, subnode;
 
 	if (fdtdec_get_bool(blob, node, "big-endian"))
diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c
index caf0103..893fe33 100644
--- a/drivers/spi/ich.c
+++ b/drivers/spi/ich.c
@@ -658,14 +658,14 @@
 static int ich_spi_ofdata_to_platdata(struct udevice *dev)
 {
 	struct ich_spi_platdata *plat = dev_get_platdata(dev);
+	int node = dev_of_offset(dev);
 	int ret;
 
-	ret = fdt_node_check_compatible(gd->fdt_blob, dev->of_offset,
-					"intel,ich7-spi");
+	ret = fdt_node_check_compatible(gd->fdt_blob, node, "intel,ich7-spi");
 	if (ret == 0) {
 		plat->ich_version = ICHV_7;
 	} else {
-		ret = fdt_node_check_compatible(gd->fdt_blob, dev->of_offset,
+		ret = fdt_node_check_compatible(gd->fdt_blob, node,
 						"intel,ich9-spi");
 		if (ret == 0)
 			plat->ich_version = ICHV_9;
diff --git a/drivers/spi/mvebu_a3700_spi.c b/drivers/spi/mvebu_a3700_spi.c
index 7c58c36..ee847e4 100644
--- a/drivers/spi/mvebu_a3700_spi.c
+++ b/drivers/spi/mvebu_a3700_spi.c
@@ -261,9 +261,9 @@
 	 * it should be used to read the input clock and the DT property
 	 * can be removed.
 	 */
-	plat->clock = fdtdec_get_int(gd->fdt_blob, bus->of_offset,
+	plat->clock = fdtdec_get_int(gd->fdt_blob, dev_of_offset(bus),
 				     "clock-frequency", 160000);
-	plat->frequency = fdtdec_get_int(gd->fdt_blob, bus->of_offset,
+	plat->frequency = fdtdec_get_int(gd->fdt_blob, dev_of_offset(bus),
 					 "spi-max-frequency", 40000);
 
 	return 0;
diff --git a/drivers/spi/omap3_spi.c b/drivers/spi/omap3_spi.c
index 60e9d6e..8a89450 100644
--- a/drivers/spi/omap3_spi.c
+++ b/drivers/spi/omap3_spi.c
@@ -627,7 +627,7 @@
 {
 	struct omap3_spi_priv *priv = dev_get_priv(dev);
 	const void *blob = gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 
 	struct omap2_mcspi_platform_config* data =
 		(struct omap2_mcspi_platform_config*)dev_get_driver_data(dev);
diff --git a/drivers/spi/pic32_spi.c b/drivers/spi/pic32_spi.c
index 25ca1f3..78d78bc 100644
--- a/drivers/spi/pic32_spi.c
+++ b/drivers/spi/pic32_spi.c
@@ -377,13 +377,14 @@
 {
 	struct pic32_spi_priv *priv = dev_get_priv(bus);
 	struct dm_spi_bus *dm_spi = dev_get_uclass_priv(bus);
+	int node = dev_of_offset(bus);
 	struct udevice *clkdev;
 	fdt_addr_t addr;
 	fdt_size_t size;
 	int ret;
 
 	debug("%s: %d, bus: %i\n", __func__, __LINE__, bus->seq);
-	addr = fdtdec_get_addr_size(gd->fdt_blob, bus->of_offset, "reg", &size);
+	addr = fdtdec_get_addr_size(gd->fdt_blob, node, "reg", &size);
 	if (addr == FDT_ADDR_T_NONE)
 		return -EINVAL;
 
@@ -391,8 +392,8 @@
 	if (!priv->regs)
 		return -EINVAL;
 
-	dm_spi->max_hz = fdtdec_get_int(gd->fdt_blob, bus->of_offset,
-					"spi-max-frequency", 250000000);
+	dm_spi->max_hz = fdtdec_get_int(gd->fdt_blob, node, "spi-max-frequency",
+					250000000);
 	/* get clock rate */
 	ret = clk_get_by_index(bus, 0, &clkdev);
 	if (ret < 0) {
@@ -413,8 +414,7 @@
 	 * of the ongoing transfer. To avoid this sort of error we will drive
 	 * /CS manually by toggling cs-gpio pins.
 	 */
-	ret = gpio_request_by_name_nodev(gd->fdt_blob, bus->of_offset,
-					 "cs-gpios", 0,
+	ret = gpio_request_by_name_nodev(gd->fdt_blob, node, "cs-gpios", 0,
 					 &priv->cs_gpio, GPIOD_IS_OUT);
 	if (ret) {
 		printf("pic32-spi: error, cs-gpios not found\n");
diff --git a/drivers/spi/rk_spi.c b/drivers/spi/rk_spi.c
index 15cf0bd..3e44f17 100644
--- a/drivers/spi/rk_spi.c
+++ b/drivers/spi/rk_spi.c
@@ -164,7 +164,7 @@
 	struct rockchip_spi_platdata *plat = dev_get_platdata(bus);
 	struct rockchip_spi_priv *priv = dev_get_priv(bus);
 	const void *blob = gd->fdt_blob;
-	int node = bus->of_offset;
+	int node = dev_of_offset(bus);
 	int ret;
 
 	plat->base = dev_get_addr(bus);
diff --git a/drivers/spi/soft_spi.c b/drivers/spi/soft_spi.c
index d23dc81..1690cd7 100644
--- a/drivers/spi/soft_spi.c
+++ b/drivers/spi/soft_spi.c
@@ -202,7 +202,7 @@
 {
 	struct soft_spi_platdata *plat = dev->platdata;
 	const void *blob = gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 
 	plat->spi_delay_us = fdtdec_get_int(blob, node, "spi-delay-us", 0);
 
diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c
index 1ab5b75..ac17da0 100644
--- a/drivers/spi/spi-uclass.c
+++ b/drivers/spi/spi-uclass.c
@@ -113,10 +113,11 @@
 {
 	struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev);
 
-	if (dev->of_offset == -1)
+	if (dev_of_offset(dev) == -1)
 		return 0;
 
-	return spi_slave_ofdata_to_platdata(gd->fdt_blob, dev->of_offset, plat);
+	return spi_slave_ofdata_to_platdata(gd->fdt_blob, dev_of_offset(dev),
+					    plat);
 }
 #endif
 
@@ -125,7 +126,7 @@
 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
 	struct dm_spi_bus *spi = dev_get_uclass_priv(bus);
 
-	spi->max_hz = fdtdec_get_int(gd->fdt_blob, bus->of_offset,
+	spi->max_hz = fdtdec_get_int(gd->fdt_blob, dev_of_offset(bus),
 				     "spi-max-frequency", 0);
 #endif
 #if defined(CONFIG_NEEDS_MANUAL_RELOC)
diff --git a/drivers/spi/stm32_qspi.c b/drivers/spi/stm32_qspi.c
index 123a1f3..05358eb 100644
--- a/drivers/spi/stm32_qspi.c
+++ b/drivers/spi/stm32_qspi.c
@@ -411,7 +411,7 @@
 	struct fdt_resource res_regs, res_mem;
 	struct stm32_qspi_platdata *plat = bus->platdata;
 	const void *blob = gd->fdt_blob;
-	int node = bus->of_offset;
+	int node = dev_of_offset(bus);
 	int ret;
 
 	ret = fdt_get_named_resource(blob, node, "reg", "reg-names",
diff --git a/drivers/spi/tegra114_spi.c b/drivers/spi/tegra114_spi.c
index 509afba..897409c 100644
--- a/drivers/spi/tegra114_spi.c
+++ b/drivers/spi/tegra114_spi.c
@@ -101,7 +101,7 @@
 {
 	struct tegra_spi_platdata *plat = bus->platdata;
 	const void *blob = gd->fdt_blob;
-	int node = bus->of_offset;
+	int node = dev_of_offset(bus);
 
 	plat->base = dev_get_addr(bus);
 	plat->periph_id = clock_decode_periph_id(blob, node);
diff --git a/drivers/spi/tegra20_sflash.c b/drivers/spi/tegra20_sflash.c
index ce3a2d3..ecbf4c1 100644
--- a/drivers/spi/tegra20_sflash.c
+++ b/drivers/spi/tegra20_sflash.c
@@ -88,7 +88,7 @@
 {
 	struct tegra_spi_platdata *plat = bus->platdata;
 	const void *blob = gd->fdt_blob;
-	int node = bus->of_offset;
+	int node = dev_of_offset(bus);
 
 	plat->base = dev_get_addr(bus);
 	plat->periph_id = clock_decode_periph_id(blob, node);
diff --git a/drivers/spi/tegra20_slink.c b/drivers/spi/tegra20_slink.c
index e1da23b..1d99a1e 100644
--- a/drivers/spi/tegra20_slink.c
+++ b/drivers/spi/tegra20_slink.c
@@ -94,7 +94,7 @@
 {
 	struct tegra_spi_platdata *plat = bus->platdata;
 	const void *blob = gd->fdt_blob;
-	int node = bus->of_offset;
+	int node = dev_of_offset(bus);
 
 	plat->base = dev_get_addr(bus);
 	plat->periph_id = clock_decode_periph_id(blob, node);
diff --git a/drivers/spi/tegra210_qspi.c b/drivers/spi/tegra210_qspi.c
index 026cff0..1e094cb 100644
--- a/drivers/spi/tegra210_qspi.c
+++ b/drivers/spi/tegra210_qspi.c
@@ -97,7 +97,7 @@
 {
 	struct tegra_spi_platdata *plat = bus->platdata;
 	const void *blob = gd->fdt_blob;
-	int node = bus->of_offset;
+	int node = dev_of_offset(bus);
 
 	plat->base = dev_get_addr(bus);
 	plat->periph_id = clock_decode_periph_id(blob, node);
diff --git a/drivers/spi/ti_qspi.c b/drivers/spi/ti_qspi.c
index 6f9f983..79955d7 100644
--- a/drivers/spi/ti_qspi.c
+++ b/drivers/spi/ti_qspi.c
@@ -553,7 +553,7 @@
 {
 	struct ti_qspi_priv *priv = dev_get_priv(bus);
 	const void *blob = gd->fdt_blob;
-	int node = bus->of_offset;
+	int node = dev_of_offset(bus);
 	fdt_addr_t addr;
 	void *mmap;
 
diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c
index b98663c..255e02f 100644
--- a/drivers/spi/zynq_qspi.c
+++ b/drivers/spi/zynq_qspi.c
@@ -101,7 +101,7 @@
 {
 	struct zynq_qspi_platdata *plat = bus->platdata;
 	const void *blob = gd->fdt_blob;
-	int node = bus->of_offset;
+	int node = dev_of_offset(bus);
 
 	plat->regs = (struct zynq_qspi_regs *)fdtdec_get_addr(blob,
 							      node, "reg");
diff --git a/drivers/spi/zynq_spi.c b/drivers/spi/zynq_spi.c
index 15ca271..5a9b1f0 100644
--- a/drivers/spi/zynq_spi.c
+++ b/drivers/spi/zynq_spi.c
@@ -71,7 +71,7 @@
 {
 	struct zynq_spi_platdata *plat = bus->platdata;
 	const void *blob = gd->fdt_blob;
-	int node = bus->of_offset;
+	int node = dev_of_offset(bus);
 
 	plat->regs = (struct zynq_spi_regs *)dev_get_addr(bus);
 
diff --git a/drivers/spmi/spmi-msm.c b/drivers/spmi/spmi-msm.c
index 48bc157..605683f 100644
--- a/drivers/spmi/spmi-msm.c
+++ b/drivers/spmi/spmi-msm.c
@@ -147,18 +147,14 @@
 {
 	struct udevice *parent = dev->parent;
 	struct msm_spmi_priv *priv = dev_get_priv(dev);
+	int node = dev_of_offset(dev);
 	int i;
 
 	priv->arb_chnl = dev_get_addr(dev);
 	priv->spmi_core = fdtdec_get_addr_size_auto_parent(gd->fdt_blob,
-							   parent->of_offset,
-							   dev->of_offset,
-							   "reg", 1, NULL,
-							   false);
+			dev_of_offset(parent), node, "reg", 1, NULL, false);
 	priv->spmi_obs = fdtdec_get_addr_size_auto_parent(gd->fdt_blob,
-							  parent->of_offset,
-							  dev->of_offset, "reg",
-							  2, NULL, false);
+			dev_of_offset(parent), node, "reg", 2, NULL, false);
 	if (priv->arb_chnl == FDT_ADDR_T_NONE ||
 	    priv->spmi_core == FDT_ADDR_T_NONE ||
 	    priv->spmi_obs == FDT_ADDR_T_NONE)
diff --git a/drivers/sysreset/sysreset_sandbox.c b/drivers/sysreset/sysreset_sandbox.c
index 7ae7f38..0c4e2e1 100644
--- a/drivers/sysreset/sysreset_sandbox.c
+++ b/drivers/sysreset/sysreset_sandbox.c
@@ -41,7 +41,7 @@
 	 * (see the U_BOOT_DEVICE() declaration below) should not do anything.
 	 * If we are that device, return an error.
 	 */
-	if (state->fdt_fname && dev->of_offset == -1)
+	if (state->fdt_fname && dev_of_offset(dev) == -1)
 		return -ENODEV;
 
 	switch (type) {
diff --git a/drivers/timer/timer-uclass.c b/drivers/timer/timer-uclass.c
index 5c63e6b..1caf3cd 100644
--- a/drivers/timer/timer-uclass.c
+++ b/drivers/timer/timer-uclass.c
@@ -55,7 +55,7 @@
 		uc_priv->clock_rate = ret;
 	} else
 		uc_priv->clock_rate = fdtdec_get_int(gd->fdt_blob,
-				dev->of_offset,	"clock-frequency", 0);
+				dev_of_offset(dev),	"clock-frequency", 0);
 
 	return 0;
 }
diff --git a/drivers/usb/emul/sandbox_flash.c b/drivers/usb/emul/sandbox_flash.c
index 0965ad0..9abb323 100644
--- a/drivers/usb/emul/sandbox_flash.c
+++ b/drivers/usb/emul/sandbox_flash.c
@@ -373,8 +373,8 @@
 	struct sandbox_flash_plat *plat = dev_get_platdata(dev);
 	const void *blob = gd->fdt_blob;
 
-	plat->pathname = fdt_getprop(blob, dev->of_offset, "sandbox,filepath",
-				     NULL);
+	plat->pathname = fdt_getprop(blob, dev_of_offset(dev),
+				     "sandbox,filepath", NULL);
 
 	return 0;
 }
diff --git a/drivers/usb/emul/sandbox_hub.c b/drivers/usb/emul/sandbox_hub.c
index 624fbde..c3a8e73 100644
--- a/drivers/usb/emul/sandbox_hub.c
+++ b/drivers/usb/emul/sandbox_hub.c
@@ -277,7 +277,8 @@
 {
 	struct sandbox_hub_platdata *plat = dev_get_parent_platdata(dev);
 
-	plat->port = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "reg", -1);
+	plat->port = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "reg",
+				    -1);
 
 	return 0;
 }
diff --git a/drivers/usb/host/dwc2.c b/drivers/usb/host/dwc2.c
index d08879d..d253b94 100644
--- a/drivers/usb/host/dwc2.c
+++ b/drivers/usb/host/dwc2.c
@@ -1199,8 +1199,8 @@
 		return -EINVAL;
 	priv->regs = (struct dwc2_core_regs *)addr;
 
-	prop = fdt_getprop(gd->fdt_blob, dev->of_offset, "disable-over-current",
-			   NULL);
+	prop = fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
+			   "disable-over-current", NULL);
 	if (prop)
 		priv->oc_disable = true;
 
diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c
index 53281d7..981543e 100644
--- a/drivers/usb/host/ehci-exynos.c
+++ b/drivers/usb/host/ehci-exynos.c
@@ -59,7 +59,7 @@
 	}
 
 	depth = 0;
-	node = fdtdec_next_compatible_subnode(blob, dev->of_offset,
+	node = fdtdec_next_compatible_subnode(blob, dev_of_offset(dev),
 				COMPAT_SAMSUNG_EXYNOS_USB_PHY, &depth);
 	if (node <= 0) {
 		debug("XHCI: Can't get device node for usb3-phy controller\n");
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index 9c32921..7ad50fc 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -61,7 +61,7 @@
 	struct ehci_fsl_priv *priv = dev_get_priv(dev);
 	const void *prop;
 
-	prop = fdt_getprop(gd->fdt_blob, dev->of_offset, "phy_type",
+	prop = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy_type",
 			   NULL);
 	if (prop) {
 		priv->phy_type = (char *)prop;
diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c
index 7b309b7..55ac162 100644
--- a/drivers/usb/host/ehci-mx6.c
+++ b/drivers/usb/host/ehci-mx6.c
@@ -437,7 +437,7 @@
 	void *__iomem addr = (void *__iomem)dev_get_addr(dev);
 	void *__iomem phy_ctrl, *__iomem phy_status;
 	const void *blob = gd->fdt_blob;
-	int offset = dev->of_offset, phy_off;
+	int offset = dev_of_offset(dev), phy_off;
 	u32 val;
 
 	/*
@@ -484,7 +484,7 @@
 	struct usb_platdata *plat = dev_get_platdata(dev);
 	const char *mode;
 
-	mode = fdt_getprop(gd->fdt_blob, dev->of_offset, "dr_mode", NULL);
+	mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "dr_mode", NULL);
 	if (mode) {
 		if (strcmp(mode, "peripheral") == 0)
 			plat->init_type = USB_INIT_DEVICE;
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index e3620da..beb3b02 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -696,7 +696,7 @@
 static int fdt_decode_usb(struct udevice *dev, struct fdt_usb *config)
 {
 	const void *blob = gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	const char *phy, *mode;
 
 	config->reg = (struct usb_ctlr *)dev_get_addr(dev);
diff --git a/drivers/usb/host/ehci-vf.c b/drivers/usb/host/ehci-vf.c
index f389bff..84241cd 100644
--- a/drivers/usb/host/ehci-vf.c
+++ b/drivers/usb/host/ehci-vf.c
@@ -218,7 +218,7 @@
 {
 	struct ehci_vf_priv_data *priv = dev_get_priv(dev);
 	const void *dt_blob = gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	const char *mode;
 
 	priv->portnr = dev->seq;
diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c
index be114fc..5cf1e9a 100644
--- a/drivers/usb/host/usb-uclass.c
+++ b/drivers/usb/host/usb-uclass.c
@@ -686,16 +686,17 @@
 	const void *blob = gd->fdt_blob;
 	int val;
 
-	if (dev->of_offset == -1)
+	if (dev_of_offset(dev) == -1)
 		return 0;
 
 	/* We only support matching a few things */
-	val = fdtdec_get_int(blob, dev->of_offset, "usb,device-class", -1);
+	val = fdtdec_get_int(blob, dev_of_offset(dev), "usb,device-class", -1);
 	if (val != -1) {
 		plat->id.match_flags |= USB_DEVICE_ID_MATCH_DEV_CLASS;
 		plat->id.bDeviceClass = val;
 	}
-	val = fdtdec_get_int(blob, dev->of_offset, "usb,interface-class", -1);
+	val = fdtdec_get_int(blob, dev_of_offset(dev), "usb,interface-class",
+			     -1);
 	if (val != -1) {
 		plat->id.match_flags |= USB_DEVICE_ID_MATCH_INT_CLASS;
 		plat->id.bInterfaceClass = val;
diff --git a/drivers/usb/host/xhci-exynos5.c b/drivers/usb/host/xhci-exynos5.c
index 82fcd84..b3f48b3 100644
--- a/drivers/usb/host/xhci-exynos5.c
+++ b/drivers/usb/host/xhci-exynos5.c
@@ -68,7 +68,7 @@
 	}
 
 	depth = 0;
-	node = fdtdec_next_compatible_subnode(blob, dev->of_offset,
+	node = fdtdec_next_compatible_subnode(blob, dev_of_offset(dev),
 				COMPAT_SAMSUNG_EXYNOS5_USB3_PHY, &depth);
 	if (node <= 0) {
 		debug("XHCI: Can't get device node for usb3-phy controller\n");
diff --git a/drivers/usb/host/xhci-rockchip.c b/drivers/usb/host/xhci-rockchip.c
index 8cbcb8f..f559830 100644
--- a/drivers/usb/host/xhci-rockchip.c
+++ b/drivers/usb/host/xhci-rockchip.c
@@ -90,11 +90,11 @@
 	/* Set dwc3 usb2 phy config */
 	reg = readl(&dwc3_reg->g_usb2phycfg[0]);
 
-	if (fdtdec_get_bool(blob, dev->of_offset,
+	if (fdtdec_get_bool(blob, dev_of_offset(dev),
 			    "snps,dis-enblslpm-quirk"))
 		reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
 
-	utmi_bits = fdtdec_get_int(blob, dev->of_offset,
+	utmi_bits = fdtdec_get_int(blob, dev_of_offset(dev),
 				   "snps,phyif-utmi-bits", -1);
 	if (utmi_bits == 16) {
 		reg |= DWC3_GUSB2PHYCFG_PHYIF;
@@ -106,11 +106,11 @@
 		reg |= DWC3_GUSB2PHYCFG_USBTRDTIM_8BIT;
 	}
 
-	if (fdtdec_get_bool(blob, dev->of_offset,
+	if (fdtdec_get_bool(blob, dev_of_offset(dev),
 			    "snps,dis-u2-freeclk-exists-quirk"))
 		reg &= ~DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS;
 
-	if (fdtdec_get_bool(blob, dev->of_offset,
+	if (fdtdec_get_bool(blob, dev_of_offset(dev),
 			    "snps,dis-u2-susphy-quirk"))
 		reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
 
diff --git a/drivers/usb/musb-new/pic32.c b/drivers/usb/musb-new/pic32.c
index c888c64..ed6da19 100644
--- a/drivers/usb/musb-new/pic32.c
+++ b/drivers/usb/musb-new/pic32.c
@@ -219,7 +219,7 @@
 	struct musb_host_data *mdata = &pdata->mdata;
 	struct fdt_resource mc, glue;
 	void *fdt = (void *)gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	void __iomem *mregs;
 	int ret;
 
diff --git a/drivers/usb/musb-new/ti-musb.c b/drivers/usb/musb-new/ti-musb.c
index 1c15aa2..852f07f 100644
--- a/drivers/usb/musb-new/ti-musb.c
+++ b/drivers/usb/musb-new/ti-musb.c
@@ -83,7 +83,7 @@
 {
 	struct ti_musb_platdata *platdata = dev_get_platdata(dev);
 	const void *fdt = gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	int phys;
 	int ctrl_mod;
 	int usb_index;
@@ -178,7 +178,7 @@
 {
 	struct ti_musb_platdata *platdata = dev_get_platdata(dev);
 	const void *fdt = gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	int ret;
 
 	ret = ti_musb_ofdata_to_platdata(dev);
@@ -209,7 +209,7 @@
 	int node;
 	int ret;
 
-	for (node = fdt_first_subnode(fdt, parent->of_offset); node > 0;
+	for (node = fdt_first_subnode(fdt, dev_of_offset(parent)); node > 0;
 	     node = fdt_next_subnode(fdt, node)) {
 		struct udevice *dev;
 		const char *name = fdt_get_name(fdt, node, NULL);
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index 39cd7ca..ed2bd30 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -276,7 +276,7 @@
 	struct display_timing *timing = &priv->timing;
 	const void *blob = gd->fdt_blob;
 
-	if (fdtdec_decode_display_timing(blob, dev->of_offset,
+	if (fdtdec_decode_display_timing(blob, dev_of_offset(dev),
 					 plat->timing_index, timing)) {
 		debug("%s: Failed to decode display timing\n", __func__);
 		return -EINVAL;
diff --git a/drivers/video/bridge/ps862x.c b/drivers/video/bridge/ps862x.c
index 80f63e3..46aacca 100644
--- a/drivers/video/bridge/ps862x.c
+++ b/drivers/video/bridge/ps862x.c
@@ -86,7 +86,8 @@
 	if (ret)
 		return ret;
 
-	params = fdt_getprop(gd->fdt_blob, dev->of_offset, "parade,regs", &len);
+	params = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "parade,regs",
+			     &len);
 	if (!params || len % 3) {
 		debug("%s: missing/invalid params=%p, len=%x\n", __func__,
 		      params, len);
diff --git a/drivers/video/broadwell_igd.c b/drivers/video/broadwell_igd.c
index beef770..4612d04 100644
--- a/drivers/video/broadwell_igd.c
+++ b/drivers/video/broadwell_igd.c
@@ -705,7 +705,7 @@
 {
 	struct broadwell_igd_plat *plat = dev_get_platdata(dev);
 	struct broadwell_igd_priv *priv = dev_get_priv(dev);
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	const void *blob = gd->fdt_blob;
 
 	if (fdtdec_get_int_array(blob, node, "intel,dp-hotplug",
diff --git a/drivers/video/exynos/exynos_dp.c b/drivers/video/exynos/exynos_dp.c
index fc39f2c..c5039e7 100644
--- a/drivers/video/exynos/exynos_dp.c
+++ b/drivers/video/exynos/exynos_dp.c
@@ -880,7 +880,7 @@
 {
 	struct exynos_dp_priv *priv = dev_get_priv(dev);
 	const void *blob = gd->fdt_blob;
-	unsigned int node = dev->of_offset;
+	unsigned int node = dev_of_offset(dev);
 	fdt_addr_t addr;
 
 	addr = dev_get_addr(dev);
diff --git a/drivers/video/exynos/exynos_fb.c b/drivers/video/exynos/exynos_fb.c
index 5483d66..46320e7 100644
--- a/drivers/video/exynos/exynos_fb.c
+++ b/drivers/video/exynos/exynos_fb.c
@@ -383,7 +383,7 @@
 	unsigned int offset;
 	unsigned int node;
 
-	node = dev->of_offset;
+	node = dev_of_offset(dev);
 	if (fdtdec_get_bool(gd->fdt_blob, node, "samsung,disable-sysmmu"))
 		exynos_fimd_disable_sysmmu();
 
@@ -482,7 +482,7 @@
 int exynos_fb_ofdata_to_platdata(struct udevice *dev)
 {
 	struct exynos_fb_priv *priv = dev_get_priv(dev);
-	unsigned int node = dev->of_offset;
+	unsigned int node = dev_of_offset(dev);
 	const void *blob = gd->fdt_blob;
 	fdt_addr_t addr;
 
diff --git a/drivers/video/ivybridge_igd.c b/drivers/video/ivybridge_igd.c
index 94db3dd..d8af2e1 100644
--- a/drivers/video/ivybridge_igd.c
+++ b/drivers/video/ivybridge_igd.c
@@ -18,6 +18,8 @@
 #include <asm/arch/pch.h>
 #include <asm/arch/sandybridge.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 struct gt_powermeter {
 	u16 reg;
 	u32 value;
@@ -515,7 +517,7 @@
 static int gma_pm_init_post_vbios(struct udevice *dev, int rev, void *gtt_bar)
 {
 	const void *blob = gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	u32 reg32, cycle_delay;
 
 	debug("GT Power Management Init (post VBIOS)\n");
@@ -800,7 +802,7 @@
 	mtrr_add_request(MTRR_TYPE_WRCOMB, base, 256 << 20);
 	mtrr_commit(true);
 
-	gtt_bar = (void *)dm_pci_read_bar32(dev, 0);
+	gtt_bar = (void *)(ulong)dm_pci_read_bar32(dev, 0);
 	debug("GT bar %p\n", gtt_bar);
 	ret = gma_pm_init_pre_vbios(gtt_bar, rev);
 	if (ret)
@@ -822,7 +824,7 @@
 		return ret;
 
 	/* Post VBIOS init */
-	gtt_bar = (void *)dm_pci_read_bar32(dev, 0);
+	gtt_bar = (void *)(ulong)dm_pci_read_bar32(dev, 0);
 	ret = gma_pm_init_post_vbios(dev, rev, gtt_bar);
 	if (ret)
 		return ret;
diff --git a/drivers/video/pwm_backlight.c b/drivers/video/pwm_backlight.c
index de6277f..3697f49 100644
--- a/drivers/video/pwm_backlight.c
+++ b/drivers/video/pwm_backlight.c
@@ -61,7 +61,7 @@
 	struct pwm_backlight_priv *priv = dev_get_priv(dev);
 	struct fdtdec_phandle_args args;
 	const void *blob = gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	int index, ret, count, len;
 	const u32 *cell;
 
diff --git a/drivers/video/rockchip/rk_lvds.c b/drivers/video/rockchip/rk_lvds.c
index fcbb4d6..ee43255 100644
--- a/drivers/video/rockchip/rk_lvds.c
+++ b/drivers/video/rockchip/rk_lvds.c
@@ -162,7 +162,7 @@
 int rk_lvds_read_timing(struct udevice *dev, struct display_timing *timing)
 {
 	if (fdtdec_decode_display_timing
-	    (gd->fdt_blob, dev->of_offset, 0, timing)) {
+	    (gd->fdt_blob, dev_of_offset(dev), 0, timing)) {
 		debug("%s: Failed to decode display timing\n", __func__);
 		return -EINVAL;
 	}
@@ -174,7 +174,7 @@
 {
 	struct rk_lvds_priv *priv = dev_get_priv(dev);
 	const void *blob = gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	int ret;
 	priv->regs = (void *)dev_get_addr(dev);
 	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
diff --git a/drivers/video/rockchip/rk_vop.c b/drivers/video/rockchip/rk_vop.c
index eab5486..aeecb58 100644
--- a/drivers/video/rockchip/rk_vop.c
+++ b/drivers/video/rockchip/rk_vop.c
@@ -321,7 +321,7 @@
 	 * clock so it is currently not possible to use more than one display
 	 * device simultaneously.
 	 */
-	port = fdt_subnode_offset(blob, dev->of_offset, "port");
+	port = fdt_subnode_offset(blob, dev_of_offset(dev), "port");
 	if (port < 0)
 		return -EINVAL;
 	for (node = fdt_first_subnode(blob, port);
diff --git a/drivers/video/sandbox_sdl.c b/drivers/video/sandbox_sdl.c
index dc5a220..18afe2f 100644
--- a/drivers/video/sandbox_sdl.c
+++ b/drivers/video/sandbox_sdl.c
@@ -46,7 +46,7 @@
 	struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
 	struct sandbox_sdl_plat *plat = dev_get_platdata(dev);
 	const void *blob = gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	int ret = 0;
 
 	plat->xres = fdtdec_get_int(blob, node, "xres", LCD_MAX_WIDTH);
diff --git a/drivers/video/tegra.c b/drivers/video/tegra.c
index 92214d6..0ba3f2c 100644
--- a/drivers/video/tegra.c
+++ b/drivers/video/tegra.c
@@ -338,7 +338,7 @@
 	struct tegra_lcd_priv *priv = dev_get_priv(dev);
 	const void *blob = gd->fdt_blob;
 	struct display_timing *timing;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	int panel_node;
 	int rgb;
 	int ret;
@@ -392,7 +392,7 @@
 {
 	struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
 	const void *blob = gd->fdt_blob;
-	int node = dev->of_offset;
+	int node = dev_of_offset(dev);
 	int rgb;
 
 	rgb = fdt_subnode_offset(blob, node, "rgb");
diff --git a/drivers/video/tegra124/display.c b/drivers/video/tegra124/display.c
index 28db96c..bbbca13b 100644
--- a/drivers/video/tegra124/display.c
+++ b/drivers/video/tegra124/display.c
@@ -363,9 +363,9 @@
 		return ret;
 	}
 
-	dc_ctlr = (struct dc_ctlr *)fdtdec_get_addr(blob, dev->of_offset,
+	dc_ctlr = (struct dc_ctlr *)fdtdec_get_addr(blob, dev_of_offset(dev),
 						    "reg");
-	if (fdtdec_decode_display_timing(blob, dev->of_offset, 0, timing)) {
+	if (fdtdec_decode_display_timing(blob, dev_of_offset(dev), 0, timing)) {
 		debug("%s: Failed to decode display timing\n", __func__);
 		return -EINVAL;
 	}
diff --git a/drivers/video/tegra124/sor.c b/drivers/video/tegra124/sor.c
index e5cea51..5e4140f 100644
--- a/drivers/video/tegra124/sor.c
+++ b/drivers/video/tegra124/sor.c
@@ -757,7 +757,7 @@
 
 	/* Use the first display controller */
 	debug("%s\n", __func__);
-	node = dc_dev->of_offset;
+	node = dev_of_offset(dc_dev);
 	disp_ctrl = (struct dc_ctlr *)fdtdec_get_addr(blob, node, "reg");
 
 	tegra_dc_sor_enable_dc(disp_ctrl);
@@ -973,7 +973,7 @@
 
 	debug("%s\n", __func__);
 	/* Use the first display controller */
-	node = dc_dev->of_offset;
+	node = dev_of_offset(dc_dev);
 	disp_ctrl = (struct dc_ctlr *)fdtdec_get_addr(blob, node, "reg");
 
 	/* Sleep mode */
@@ -1045,7 +1045,7 @@
 	int node;
 	int ret;
 
-	priv->base = (void *)fdtdec_get_addr(blob, dev->of_offset, "reg");
+	priv->base = (void *)fdtdec_get_addr(blob, dev_of_offset(dev), "reg");
 
 	node = fdtdec_next_compatible(blob, 0, COMPAT_NVIDIA_TEGRA124_PMC);
 	if (node < 0) {
diff --git a/include/.gitignore b/include/.gitignore
index 75be527..8e41a95 100644
--- a/include/.gitignore
+++ b/include/.gitignore
@@ -2,4 +2,3 @@
 /bmp_logo.h
 /bmp_logo_data.h
 /config.h
-/license.h
diff --git a/include/config_cmd_all.h b/include/config_cmd_all.h
index a0d4e94..a8befe3 100644
--- a/include/config_cmd_all.h
+++ b/include/config_cmd_all.h
@@ -49,7 +49,6 @@
 #define CONFIG_CMD_TERMINAL	/* built-in Serial Terminal	*/
 #define CONFIG_CMD_UBIFS	/* UBIFS Support		*/
 #define CONFIG_CMD_UNIVERSE	/* Tundra Universe Support	*/
-#define CONFIG_CMD_UNZIP	/* unzip from memory to memory	*/
 #define CONFIG_CMD_ZFS		/* ZFS Support			*/
 
 #endif	/* _CONFIG_CMD_ALL_H */
diff --git a/include/configs/PMC440.h b/include/configs/PMC440.h
index 5ea82f8..59ba79e 100644
--- a/include/configs/PMC440.h
+++ b/include/configs/PMC440.h
@@ -385,6 +385,4 @@
 #define CONFIG_KGDB_BAUDRATE	230400	/* speed to run kgdb serial port */
 #endif
 
-#define CONFIG_API		1
-
 #endif /* __CONFIG_H */
diff --git a/include/configs/am3517_crane.h b/include/configs/am3517_crane.h
index 5d56860..f1b82df 100644
--- a/include/configs/am3517_crane.h
+++ b/include/configs/am3517_crane.h
@@ -88,8 +88,6 @@
 
 #ifdef CONFIG_USB_MUSB_HCD
 
-#define CONGIG_CMD_STORAGE
-
 #ifdef CONFIG_USB_KEYBOARD
 #define CONFIG_SYS_USB_EVENT_POLL
 #define CONFIG_PREBOOT "usb start"
diff --git a/include/configs/am3517_evm.h b/include/configs/am3517_evm.h
index 13de819..1062e20 100644
--- a/include/configs/am3517_evm.h
+++ b/include/configs/am3517_evm.h
@@ -88,8 +88,6 @@
 
 #ifdef CONFIG_USB_MUSB_HOST
 
-#define CONGIG_CMD_STORAGE
-
 #ifdef CONFIG_USB_KEYBOARD
 #define CONFIG_SYS_USB_EVENT_POLL
 #define CONFIG_PREBOOT "usb start"
diff --git a/include/configs/brxre1.h b/include/configs/brxre1.h
index 02094b5..82ee7c6 100644
--- a/include/configs/brxre1.h
+++ b/include/configs/brxre1.h
@@ -22,7 +22,6 @@
 
 #define CONFIG_VIDEO_BMP_GZIP
 #define CONFIG_SYS_VIDEO_LOGO_MAX_SIZE	(1366*767*4)
-#define CONFIG_CMD_UNZIP
 #define CONFIG_CMD_BMP
 #define CONFIG_BMP_24BMP
 #define CONFIG_BMP_32BPP
diff --git a/include/configs/chromebook_link.h b/include/configs/chromebook_link.h
index f2d798a..b116a27 100644
--- a/include/configs/chromebook_link.h
+++ b/include/configs/chromebook_link.h
@@ -19,4 +19,13 @@
 #define CONFIG_ENV_SECT_SIZE		0x1000
 #define CONFIG_ENV_OFFSET		0x003f8000
 
+#define CONFIG_SPL_FRAMEWORK
+
+#define CONFIG_SPL_TEXT_BASE		0xfffd0000
+
+#define BOOT_DEVICE_SPI			10
+
+#define CONFIG_SPL_BOARD_LOAD_IMAGE
+#define BOOT_DEVICE_BOARD		11
+
 #endif	/* __CONFIG_H */
diff --git a/include/configs/dragonboard410c.h b/include/configs/dragonboard410c.h
index da1c589..9b7f43f 100644
--- a/include/configs/dragonboard410c.h
+++ b/include/configs/dragonboard410c.h
@@ -57,7 +57,6 @@
 /*#define CONFIG_SUPPORT_EMMC_BOOT */
 #define CONFIG_CMD_REGINFO	/* Register dump		*/
 #define CONFIG_CMD_TFTP
-#define CONFIG_CMD_UNZIP
 
 /* Partition table support */
 #define HAVE_BLOCK_DEVICE /* Needed for partition commands */
diff --git a/include/configs/ethernut5.h b/include/configs/ethernut5.h
index a3c40d6..55d65ef 100644
--- a/include/configs/ethernut5.h
+++ b/include/configs/ethernut5.h
@@ -95,7 +95,6 @@
 #define CONFIG_CMD_REISER
 #define CONFIG_CMD_SAVES
 #define CONFIG_CMD_UBIFS
-#define CONFIG_CMD_UNZIP
 #endif
 
 /* NAND flash */
diff --git a/include/configs/hikey.h b/include/configs/hikey.h
index 9ec8140..899d62d 100644
--- a/include/configs/hikey.h
+++ b/include/configs/hikey.h
@@ -74,7 +74,6 @@
 #define CONFIG_FS_EXT4
 
 /* Command line configuration */
-#define CONFIG_CMD_UNZIP
 #define CONFIG_CMD_ENV
 
 #define CONFIG_MTD_PARTITIONS
diff --git a/include/configs/lsxl.h b/include/configs/lsxl.h
index 7ec82cd..ad1adce 100644
--- a/include/configs/lsxl.h
+++ b/include/configs/lsxl.h
@@ -38,11 +38,6 @@
 #define CONFIG_SYS_NO_FLASH
 
 /*
- * Enable u-boot API for standalone programs.
- */
-#define CONFIG_API
-
-/*
  * Commands configuration
  */
 #define CONFIG_CMD_ENV
diff --git a/include/configs/omap3_evm.h b/include/configs/omap3_evm.h
index 8846aa6..8ed5602 100644
--- a/include/configs/omap3_evm.h
+++ b/include/configs/omap3_evm.h
@@ -217,8 +217,6 @@
 
 #ifdef CONFIG_USB_MUSB_HCD
 
-#define CONGIG_CMD_STORAGE
-
 #ifdef CONFIG_USB_KEYBOARD
 #define CONFIG_SYS_USB_EVENT_POLL
 #define CONFIG_PREBOOT			"usb start"
diff --git a/include/configs/qemu-x86.h b/include/configs/qemu-x86.h
index affe712..687befd 100644
--- a/include/configs/qemu-x86.h
+++ b/include/configs/qemu-x86.h
@@ -53,4 +53,13 @@
 #undef CONFIG_ENV_IS_IN_SPI_FLASH
 #define CONFIG_ENV_IS_NOWHERE
 
+#define CONFIG_SPL_FRAMEWORK
+
+#define CONFIG_SPL_TEXT_BASE		0xfffd0000
+
+#define BOOT_DEVICE_SPI			10
+
+#define CONFIG_SPL_BOARD_LOAD_IMAGE
+#define BOOT_DEVICE_BOARD		11
+
 #endif	/* __CONFIG_H */
diff --git a/include/configs/tao3530.h b/include/configs/tao3530.h
index dafb05f..32a4b27 100644
--- a/include/configs/tao3530.h
+++ b/include/configs/tao3530.h
@@ -263,7 +263,6 @@
 
 #define CONFIG_USB_ETHER
 #define CONFIG_USB_ETHER_RNDIS
-#define CONGIG_CMD_STORAGE
 
 /* Defines for SPL */
 #define CONFIG_SPL_FRAMEWORK
diff --git a/include/configs/ti_armv7_keystone2.h b/include/configs/ti_armv7_keystone2.h
index d120c69..5d4ef58 100644
--- a/include/configs/ti_armv7_keystone2.h
+++ b/include/configs/ti_armv7_keystone2.h
@@ -47,11 +47,11 @@
 #define CONFIG_SYS_SPL_MALLOC_START	(CONFIG_SPL_BSS_START_ADDR + \
 					CONFIG_SPL_BSS_MAX_SIZE)
 #define CONFIG_SYS_SPL_MALLOC_SIZE	(32 * 1024)
-#define CONFIG_SPL_STACK_SIZE		(8 * 1024)
+#define KEYSTONE_SPL_STACK_SIZE		(8 * 1024)
 #define CONFIG_SPL_STACK		(CONFIG_SYS_SPL_MALLOC_START + \
 					CONFIG_SYS_SPL_MALLOC_SIZE + \
 					SPL_MALLOC_F_SIZE + \
-					CONFIG_SPL_STACK_SIZE - 4)
+					KEYSTONE_SPL_STACK_SIZE - 4)
 #define CONFIG_SPL_SPI_LOAD
 #define CONFIG_SYS_SPI_U_BOOT_OFFS	CONFIG_SPL_PAD_TO
 
diff --git a/include/configs/uniphier.h b/include/configs/uniphier.h
index 22962392e..b453d8f 100644
--- a/include/configs/uniphier.h
+++ b/include/configs/uniphier.h
@@ -15,10 +15,6 @@
 
 #define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS  10
 
-#ifdef CONFIG_ARM64
-#define CONFIG_CMD_UNZIP
-#endif
-
 /*-----------------------------------------------------------------------
  * MMU and Cache Setting
  *----------------------------------------------------------------------*/
diff --git a/include/configs/vexpress_aemv8a.h b/include/configs/vexpress_aemv8a.h
index 3a4bfe8..35ac60a 100644
--- a/include/configs/vexpress_aemv8a.h
+++ b/include/configs/vexpress_aemv8a.h
@@ -126,7 +126,6 @@
 #endif
 
 /*#define CONFIG_MENU_SHOW*/
-#define CONFIG_CMD_UNZIP
 #define CONFIG_CMD_ENV
 
 /* BOOTP options */
diff --git a/include/configs/xilinx_zynqmp.h b/include/configs/xilinx_zynqmp.h
index 4759373..73830b2 100644
--- a/include/configs/xilinx_zynqmp.h
+++ b/include/configs/xilinx_zynqmp.h
@@ -207,8 +207,6 @@
 
 #define CONFIG_SYS_BOOTM_LEN	(60 * 1024 * 1024)
 
-#define CONFIG_CMD_UNZIP
-
 #define CONFIG_BOARD_EARLY_INIT_R
 #define CONFIG_CLOCKS
 
diff --git a/include/dm/device.h b/include/dm/device.h
index 9948bd4..4e95fb7 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -121,6 +121,16 @@
 /* Returns non-zero if the device is active (probed and not removed) */
 #define device_active(dev)	((dev)->flags & DM_FLAG_ACTIVATED)
 
+static inline int dev_of_offset(const struct udevice *dev)
+{
+	return dev->of_offset;
+}
+
+static inline void dev_set_of_offset(struct udevice *dev, int of_offset)
+{
+	dev->of_offset = of_offset;
+}
+
 /**
  * struct udevice_id - Lists the compatible strings supported by a driver
  * @compatible: Compatible string
diff --git a/include/smbios.h b/include/smbios.h
index d582d4f..c24d00e 100644
--- a/include/smbios.h
+++ b/include/smbios.h
@@ -225,7 +225,7 @@
  * @handle:	the structure's handle, a unique 16-bit number
  * @return:	size of the structure
  */
-typedef int (*smbios_write_type)(uintptr_t *addr, int handle);
+typedef int (*smbios_write_type)(ulong *addr, int handle);
 
 /**
  * write_smbios_table() - Write SMBIOS table
@@ -235,6 +235,6 @@
  * @addr:	start address to write SMBIOS table
  * @return:	end address of SMBIOS table
  */
-uintptr_t write_smbios_table(uintptr_t addr);
+ulong write_smbios_table(ulong addr);
 
 #endif /* _SMBIOS_H_ */
diff --git a/lib/smbios.c b/lib/smbios.c
index ce1974d..22ca247 100644
--- a/lib/smbios.c
+++ b/lib/smbios.c
@@ -73,7 +73,7 @@
 	return len + 1;
 }
 
-static int smbios_write_type0(uintptr_t *current, int handle)
+static int smbios_write_type0(ulong *current, int handle)
 {
 	struct smbios_type0 *t = (struct smbios_type0 *)*current;
 	int len = sizeof(struct smbios_type0);
@@ -108,7 +108,7 @@
 	return len;
 }
 
-static int smbios_write_type1(uintptr_t *current, int handle)
+static int smbios_write_type1(ulong *current, int handle)
 {
 	struct smbios_type1 *t = (struct smbios_type1 *)*current;
 	int len = sizeof(struct smbios_type1);
@@ -129,7 +129,7 @@
 	return len;
 }
 
-static int smbios_write_type2(uintptr_t *current, int handle)
+static int smbios_write_type2(ulong *current, int handle)
 {
 	struct smbios_type2 *t = (struct smbios_type2 *)*current;
 	int len = sizeof(struct smbios_type2);
@@ -147,7 +147,7 @@
 	return len;
 }
 
-static int smbios_write_type3(uintptr_t *current, int handle)
+static int smbios_write_type3(ulong *current, int handle)
 {
 	struct smbios_type3 *t = (struct smbios_type3 *)*current;
 	int len = sizeof(struct smbios_type3);
@@ -199,7 +199,7 @@
 	t->processor_version = smbios_add_string(t->eos, name);
 }
 
-static int smbios_write_type4(uintptr_t *current, int handle)
+static int smbios_write_type4(ulong *current, int handle)
 {
 	struct smbios_type4 *t = (struct smbios_type4 *)*current;
 	int len = sizeof(struct smbios_type4);
@@ -221,7 +221,7 @@
 	return len;
 }
 
-static int smbios_write_type32(uintptr_t *current, int handle)
+static int smbios_write_type32(ulong *current, int handle)
 {
 	struct smbios_type32 *t = (struct smbios_type32 *)*current;
 	int len = sizeof(struct smbios_type32);
@@ -234,7 +234,7 @@
 	return len;
 }
 
-static int smbios_write_type127(uintptr_t *current, int handle)
+static int smbios_write_type127(ulong *current, int handle)
 {
 	struct smbios_type127 *t = (struct smbios_type127 *)*current;
 	int len = sizeof(struct smbios_type127);
@@ -257,10 +257,10 @@
 	smbios_write_type127
 };
 
-uintptr_t write_smbios_table(uintptr_t addr)
+ulong write_smbios_table(ulong addr)
 {
 	struct smbios_entry *se;
-	u32 tables;
+	ulong tables;
 	int len = 0;
 	int max_struct_size = 0;
 	int handle = 0;
@@ -271,7 +271,7 @@
 	/* 16 byte align the table address */
 	addr = ALIGN(addr, 16);
 
-	se = (struct smbios_entry *)addr;
+	se = (struct smbios_entry *)(uintptr_t)addr;
 	memset(se, 0, sizeof(struct smbios_entry));
 
 	addr += sizeof(struct smbios_entry);
@@ -280,7 +280,7 @@
 
 	/* populate minimum required tables */
 	for (i = 0; i < ARRAY_SIZE(smbios_write_funcs); i++) {
-		int tmp = smbios_write_funcs[i](&addr, handle++);
+		int tmp = smbios_write_funcs[i]((ulong *)&addr, handle++);
 		max_struct_size = max(max_struct_size, tmp);
 		len += tmp;
 	}
diff --git a/scripts/.gitignore b/scripts/.gitignore
index 82bc06e..17b903b 100644
--- a/scripts/.gitignore
+++ b/scripts/.gitignore
@@ -1,4 +1,5 @@
 #
 # Generated files
 #
+bin2c
 docproc
diff --git a/scripts/Kconfig b/scripts/Kconfig
new file mode 100644
index 0000000..2a2c18e
--- /dev/null
+++ b/scripts/Kconfig
@@ -0,0 +1,2 @@
+config BUILD_BIN2C
+	bool
diff --git a/scripts/Makefile b/scripts/Makefile
index 2f081f7..3e10c16 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -7,6 +7,10 @@
 # SPDX-License-Identifier:	GPL-2.0
 #
 
+hostprogs-$(CONFIG_BUILD_BIN2C)		+= bin2c
+
+always		:= $(hostprogs-y)
+
 # The following hostprogs-y programs are only build on demand
 hostprogs-y += docproc
 
diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
index c962bbc..b52f996 100644
--- a/scripts/Makefile.spl
+++ b/scripts/Makefile.spl
@@ -35,6 +35,12 @@
 SPL_BIN := u-boot-spl
 endif
 
+ifdef CONFIG_SPL_BUILD
+SPL_ := SPL_
+else
+SPL_ :=
+endif
+
 include $(srctree)/config.mk
 include $(srctree)/arch/$(ARCH)/Makefile
 
@@ -173,6 +179,8 @@
 ALL-y	+= boot.bin
 endif
 
+ALL-$(CONFIG_SPL_X86_16BIT_INIT) += $(obj)/u-boot-x86-16bit-spl.bin
+
 ALL-$(CONFIG_ARCH_ZYNQ)		+= $(obj)/boot.bin
 ALL-$(CONFIG_ARCH_ZYNQMP)	+= $(obj)/boot.bin
 
@@ -185,7 +193,8 @@
       cmd_copy = cp $< $@
 
 ifeq ($(CONFIG_SPL_OF_CONTROL)$(CONFIG_OF_SEPARATE)$(CONFIG_SPL_OF_PLATDATA),yy)
-$(obj)/$(SPL_BIN)-dtb.bin: $(obj)/$(SPL_BIN)-nodtb.bin $(obj)/$(SPL_BIN)-pad.bin \
+$(obj)/$(SPL_BIN)-dtb.bin: $(obj)/$(SPL_BIN)-nodtb.bin \
+		$(if $(CONFIG_SPL_SEPARATE_BSS),,$(obj)/$(SPL_BIN)-pad.bin) \
 		$(obj)/$(SPL_BIN).dtb FORCE
 	$(call if_changed,cat)
 
@@ -256,11 +265,16 @@
 quiet_cmd_objcopy = OBJCOPY $@
 cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@
 
-OBJCOPYFLAGS_$(SPL_BIN)-nodtb.bin = $(SPL_OBJCFLAGS) -O binary
+OBJCOPYFLAGS_$(SPL_BIN)-nodtb.bin = $(SPL_OBJCFLAGS) -O binary \
+		$(if $(CONFIG_SPL_X86_16BIT_INIT),-R .start16 -R .resetvec)
 
 $(obj)/$(SPL_BIN)-nodtb.bin: $(obj)/$(SPL_BIN) FORCE
 	$(call if_changed,objcopy)
 
+OBJCOPYFLAGS_u-boot-x86-16bit-spl.bin := -O binary -j .start16 -j .resetvec
+$(obj)/u-boot-x86-16bit-spl.bin: $(obj)/u-boot-spl FORCE
+	$(call if_changed,objcopy)
+
 LDFLAGS_$(SPL_BIN) += -T u-boot-spl.lds $(LDFLAGS_FINAL)
 ifneq ($(CONFIG_SPL_TEXT_BASE),)
 LDFLAGS_$(SPL_BIN) += -Ttext $(CONFIG_SPL_TEXT_BASE)
diff --git a/scripts/bin2c.c b/scripts/bin2c.c
new file mode 100644
index 0000000..c3d7eef
--- /dev/null
+++ b/scripts/bin2c.c
@@ -0,0 +1,36 @@
+/*
+ * Unloved program to convert a binary on stdin to a C include on stdout
+ *
+ * Jan 1999 Matt Mackall <mpm@selenic.com>
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ */
+
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+	int ch, total = 0;
+
+	if (argc > 1)
+		printf("const char %s[] %s=\n",
+			argv[1], argc > 2 ? argv[2] : "");
+
+	do {
+		printf("\t\"");
+		while ((ch = getchar()) != EOF) {
+			total++;
+			printf("\\x%02x", ch);
+			if (total % 16 == 0)
+				break;
+		}
+		printf("\"\n");
+	} while (ch != EOF);
+
+	if (argc > 1)
+		printf("\t;\n\n#include <linux/types.h>\n\nconst size_t %s_size = %d;\n",
+		       argv[1], total);
+
+	return 0;
+}
diff --git a/scripts/check-config.sh b/scripts/check-config.sh
index 6618dfb..97e52dc 100755
--- a/scripts/check-config.sh
+++ b/scripts/check-config.sh
@@ -37,12 +37,12 @@
 	-e 's/^menuconfig \([A-Za-z0-9_]*\).*$/CONFIG_\1/p' |sort |uniq > ${ok}
 comm -23 ${suspects} ${ok} >${new_adhoc}
 if [ -s ${new_adhoc} ]; then
-	echo "Error: You must add new CONFIG options using Kconfig"
-	echo "The following new ad-hoc CONFIG options were detected:"
-	cat ${new_adhoc}
-	echo
-	echo "Please add these via Kconfig instead. Find a suitable Kconfig"
-	echo "file and add a 'config' or 'menuconfig' option."
+	echo >&2 "Error: You must add new CONFIG options using Kconfig"
+	echo >&2 "The following new ad-hoc CONFIG options were detected:"
+	cat >&2 ${new_adhoc}
+	echo >&2
+	echo >&2 "Please add these via Kconfig instead. Find a suitable Kconfig"
+	echo >&2 "file and add a 'config' or 'menuconfig' option."
 	# Don't delete the temporary files in case they are useful
 	exit 1
 else
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 84f5756..3afc870 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -7,9 +7,12 @@
 
 use strict;
 use POSIX;
+use File::Basename;
+use Cwd 'abs_path';
 
 my $P = $0;
 $P =~ s@.*/@@g;
+my $D = dirname(abs_path($P));
 
 my $V = '0.32';
 
@@ -42,6 +45,9 @@
 my $max_line_length = 80;
 my $ignore_perl_version = 0;
 my $minimum_perl_version = 5.10.0;
+my $spelling_file = "$D/spelling.txt";
+my $codespell = 0;
+my $codespellfile = "/usr/share/codespell/dictionary.txt";
 
 sub help {
 	my ($exitcode) = @_;
@@ -82,6 +88,9 @@
                              file.  It's your fault if there's no backup or git
   --ignore-perl-version      override checking of perl version.  expect
                              runtime errors.
+  --codespell                Use the codespell dictionary for spelling/typos
+                             (default:/usr/local/share/codespell/dictionary.txt)
+  --codespellfile            Use this codespell dictionary
   -h, --help, --version      display this help and exit
 
 When FILE is - read standard input.
@@ -139,6 +148,8 @@
 	'ignore-perl-version!' => \$ignore_perl_version,
 	'debug=s'	=> \%debug,
 	'test-only=s'	=> \$tst_only,
+	'codespell!'    => \$codespell,
+	'codespellfile=s' => \$codespellfile,
 	'h|help'	=> \$help,
 	'version'	=> \$help
 ) or help(1);
@@ -387,6 +398,56 @@
 )};
 # memory.h: ARM has a custom one
 
+# Load common spelling mistakes and build regular expression list.
+my $misspellings;
+my %spelling_fix;
+
+if (open(my $spelling, '<', $spelling_file)) {
+	while (<$spelling>) {
+		my $line = $_;
+
+		$line =~ s/\s*\n?$//g;
+		$line =~ s/^\s*//g;
+
+		next if ($line =~ m/^\s*#/);
+		next if ($line =~ m/^\s*$/);
+
+		my ($suspect, $fix) = split(/\|\|/, $line);
+
+		$spelling_fix{$suspect} = $fix;
+	}
+	close($spelling);
+} else {
+	warn "No typos will be found - file '$spelling_file': $!\n";
+}
+
+if ($codespell) {
+	if (open(my $spelling, '<', $codespellfile)) {
+		while (<$spelling>) {
+			my $line = $_;
+
+			$line =~ s/\s*\n?$//g;
+			$line =~ s/^\s*//g;
+
+			next if ($line =~ m/^\s*#/);
+			next if ($line =~ m/^\s*$/);
+			next if ($line =~ m/, disabled/i);
+
+			$line =~ s/,.*$//;
+
+			my ($suspect, $fix) = split(/->/, $line);
+
+			$spelling_fix{$suspect} = $fix;
+		}
+		close($spelling);
+	} else {
+		warn "No codespell typos will be found - file '$codespellfile': $!\n";
+	}
+}
+
+$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix;
+
+
 sub build_types {
 	my $mods = "(?x:  \n" . join("|\n  ", @modifierList) . "\n)";
 	my $all = "(?x:  \n" . join("|\n  ", @typeList) . "\n)";
@@ -528,6 +589,8 @@
 my @lines = ();
 my @fixed = ();
 my $vname;
+my $fixlinenr = -1;
+
 for my $filename (@ARGV) {
 	my $FILE;
 	if ($file) {
@@ -1950,6 +2013,24 @@
 			    "8-bit UTF-8 used in possible commit log\n" . $herecurr);
 		}
 
+# Check for various typo / spelling mistakes
+		if (defined($misspellings) &&
+		    ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) {
+			while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:\b|$|[^a-z@])/gi) {
+				my $typo = $1;
+				my $typo_fix = $spelling_fix{lc($typo)};
+				$typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/);
+				$typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/);
+				my $msg_type = \&WARN;
+				$msg_type = \&CHK if ($file);
+				if (&{$msg_type}("TYPO_SPELLING",
+						 "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) &&
+				    $fix) {
+					$fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/;
+				}
+			}
+		}
+
 # ignore non-hunk lines and lines being removed
 		next if (!$hunk_line || $line =~ /^-/);
 
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index d21589b..826d031 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -102,7 +102,6 @@
 CONFIG_APER_0_BASE
 CONFIG_APER_1_BASE
 CONFIG_APER_SIZE
-CONFIG_API
 CONFIG_APUS_FAST_EXCEPT
 CONFIG_AP_SH4A_4A
 CONFIG_ARCH_ADPAG101P
diff --git a/test/dm/spi.c b/test/dm/spi.c
index 5733096..f52cb73 100644
--- a/test/dm/spi.c
+++ b/test/dm/spi.c
@@ -35,7 +35,7 @@
 	 */
 	ut_asserteq(0, uclass_get_device_by_seq(UCLASS_SPI, busnum, &bus));
 	ut_assertok(spi_cs_info(bus, cs, &info));
-	of_offset = info.dev->of_offset;
+	of_offset = dev_of_offset(info.dev);
 	device_remove(info.dev);
 	device_unbind(info.dev);
 
diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c
index 49a36cb..3048a7b 100644
--- a/test/dm/test-fdt.c
+++ b/test/dm/test-fdt.c
@@ -37,9 +37,9 @@
 {
 	struct dm_test_pdata *pdata = dev_get_platdata(dev);
 
-	pdata->ping_add = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+	pdata->ping_add = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 					"ping-add", -1);
-	pdata->base = fdtdec_get_addr(gd->fdt_blob, dev->of_offset,
+	pdata->base = fdtdec_get_addr(gd->fdt_blob, dev_of_offset(dev),
 				      "ping-expect");
 
 	return 0;
@@ -121,10 +121,10 @@
 		 * want to test the code that sets that up
 		 * (testfdt_drv_probe()).
 		 */
-		base = fdtdec_get_addr(gd->fdt_blob, dev->of_offset,
+		base = fdtdec_get_addr(gd->fdt_blob, dev_of_offset(dev),
 				       "ping-expect");
 		debug("dev=%d, base=%d: %s\n", i, base,
-		      fdt_get_name(gd->fdt_blob, dev->of_offset, NULL));
+		      fdt_get_name(gd->fdt_blob, dev_of_offset(dev), NULL));
 
 		ut_assert(!dm_check_operations(uts, dev, base,
 					       dev_get_priv(dev)));
diff --git a/tools/Makefile b/tools/Makefile
index f5ac631..cbccd4a 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -32,7 +32,6 @@
 
 hostprogs-$(CONFIG_SPL_GENERATE_ATMEL_PMECC_HEADER) += atmel_pmecc_params
 
-hostprogs-$(CONFIG_CMD_LICENSE) += bin2header
 hostprogs-$(CONFIG_LCD_LOGO) += bmp_logo
 hostprogs-$(CONFIG_VIDEO_LOGO) += bmp_logo
 HOSTCFLAGS_bmp_logo.o := -pedantic
@@ -233,10 +232,6 @@
 
 endif # !LOGO_BMP
 
-# Generated gziped GPL-2.0 license text
-LICENSE_H = $(objtree)/include/license.h
-LICENSE-$(CONFIG_CMD_LICENSE) += $(LICENSE_H)
-
 #
 # Use native tools and options
 # Define __KERNEL_STRICT_NAMES to prevent typedef overlaps
@@ -251,7 +246,7 @@
 		-D__KERNEL_STRICT_NAMES \
 		-D_GNU_SOURCE
 
-__build:	$(LOGO-y) $(LICENSE-y)
+__build:	$(LOGO-y)
 
 $(LOGO_H):	$(obj)/bmp_logo $(LOGO_BMP)
 	$(obj)/bmp_logo --gen-info $(LOGO_BMP) > $@
@@ -259,10 +254,6 @@
 $(LOGO_DATA_H):	$(obj)/bmp_logo $(LOGO_BMP)
 	$(obj)/bmp_logo --gen-data $(LOGO_BMP) > $@
 
-$(LICENSE_H): $(obj)/bin2header $(srctree)/Licenses/gpl-2.0.txt
-	cat $(srctree)/Licenses/gpl-2.0.txt | gzip -9 -c | \
-		$(obj)/bin2header license_gzip > $(LICENSE_H)
-
 # Let clean descend into subdirs
 subdir- += env
 
diff --git a/tools/bin2header.c b/tools/bin2header.c
deleted file mode 100644
index 6c2c23f..0000000
--- a/tools/bin2header.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/* bin2header.c - program to convert binary file into a C structure
- * definition to be included in a header file.
- *
- * (C) Copyright 2008 by Harald Welte <laforge@openmoko.org>
- *
- * SPDX-License-Identifier:	GPL-2.0+
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-
-int main(int argc, char **argv)
-{
-	if (argc < 2) {
-		fprintf(stderr, "%s needs one argument: the structure name\n",
-			argv[0]);
-		exit(1);
-	}
-
-	printf("/* bin2header output - automatically generated */\n");
-	printf("unsigned char %s[] = {\n", argv[1]);
-
-	while (1) {
-		int i, nread;
-		unsigned char buf[10];
-		nread = read(0, buf, sizeof(buf));
-		if (nread <= 0)
-			break;
-
-		printf("\t");
-		for (i = 0; i < nread - 1; i++)
-			printf("0x%02x, ", buf[i]);
-
-		printf("0x%02x,\n", buf[nread-1]);
-	}
-
-	printf("};\n");
-
-	exit(0);
-}
diff --git a/tools/binman/etype/u_boot_spl_with_ucode_ptr.py b/tools/binman/etype/u_boot_spl_with_ucode_ptr.py
index 764c282..1c6706d 100644
--- a/tools/binman/etype/u_boot_spl_with_ucode_ptr.py
+++ b/tools/binman/etype/u_boot_spl_with_ucode_ptr.py
@@ -21,7 +21,7 @@
     process.
     """
     def __init__(self, image, etype, node):
-        Entry_blob.__init__(self, image, etype, node)
+        Entry_u_boot_with_ucode_ptr.__init__(self, image, etype, node)
         self.elf_fname = 'spl/u-boot-spl'
 
     def GetDefaultFilename(self):
diff --git a/tools/binman/etype/u_boot_ucode.py b/tools/binman/etype/u_boot_ucode.py
index 8fe27ac..8e51e99 100644
--- a/tools/binman/etype/u_boot_ucode.py
+++ b/tools/binman/etype/u_boot_ucode.py
@@ -62,6 +62,12 @@
             self.data = ''
             return True
 
+        # Handle microcode in SPL image as well
+        ucode_dest_entry = self.image.FindEntryType('u-boot-spl-with-ucode-ptr')
+        if ucode_dest_entry and not ucode_dest_entry.target_pos:
+            self.data = ''
+            return True
+
         # Get the microcode from the device tree entry
         fdt_entry = self.image.FindEntryType('u-boot-dtb-with-ucode')
         if not fdt_entry or not fdt_entry.ucode_data:
diff --git a/tools/buildman/README b/tools/buildman/README
index ccea13f..f665276 100644
--- a/tools/buildman/README
+++ b/tools/buildman/README
@@ -141,7 +141,7 @@
 with 'ball'.
 
 It is convenient to use the -n option to see what will be built based on
-the subset given.
+the subset given. Use -v as well to get an actual list of boards.
 
 Buildman does not store intermediate object files. It optionally copies
 the binary output into a directory when a build is successful. Size
diff --git a/tools/buildman/board.py b/tools/buildman/board.py
index ae0e0b8..f842d3a 100644
--- a/tools/buildman/board.py
+++ b/tools/buildman/board.py
@@ -249,15 +249,15 @@
             exclude: List of boards to exclude, regardless of 'args'
 
         Returns:
-            Dictionary which holds the number of boards which were selected
+            Dictionary which holds the list of boards which were selected
             due to each argument, arranged by argument.
         """
         result = {}
         terms = self._BuildTerms(args)
 
-        result['all'] = 0
+        result['all'] = []
         for term in terms:
-            result[str(term)] = 0
+            result[str(term)] = []
 
         exclude_list = []
         for expr in exclude:
@@ -285,7 +285,7 @@
             if build_it:
                 board.build_it = True
                 if matching_term:
-                    result[matching_term] += 1
-                result['all'] += 1
+                    result[matching_term].append(board.target)
+                result['all'].append(board.target)
 
         return result
diff --git a/tools/buildman/control.py b/tools/buildman/control.py
index 545c2cb..73b1a14 100644
--- a/tools/buildman/control.py
+++ b/tools/buildman/control.py
@@ -48,9 +48,9 @@
     Args:
         series: Series object
         why_selected: Dictionary where each key is a buildman argument
-                provided by the user, and the value is the boards brought
-                in by that argument. For example, 'arm' might bring in
-                400 boards, so in this case the key would be 'arm' and
+                provided by the user, and the value is the list of boards
+                brought in by that argument. For example, 'arm' might bring
+                in 400 boards, so in this case the key would be 'arm' and
                 the value would be a list of board names.
         boards_selected: Dict of selected boards, key is target name,
                 value is Board object
@@ -75,9 +75,11 @@
     print
     for arg in why_selected:
         if arg != 'all':
-            print arg, ': %d boards' % why_selected[arg]
+            print arg, ': %d boards' % len(why_selected[arg])
+            if options.verbose:
+                print '   %s' % ' '.join(why_selected[arg])
     print ('Total boards to build for each commit: %d\n' %
-            why_selected['all'])
+            len(why_selected['all']))
 
 def DoBuildman(options, args, toolchains=None, make_func=None, boards=None,
                clean_dir=False):
@@ -221,9 +223,10 @@
                     options.git_dir, count, series=None, allow_overwrite=True)
     else:
         series = None
-        options.verbose = True
-        if not options.summary:
-            options.show_errors = True
+        if not options.dry_run:
+            options.verbose = True
+            if not options.summary:
+                options.show_errors = True
 
     # By default we have one thread per CPU. But if there are not enough jobs
     # we can have fewer threads and use a high '-j' value for make.
diff --git a/tools/dtoc/dtoc.py b/tools/dtoc/dtoc.py
index 11050b6..6df7b0d 100755
--- a/tools/dtoc/dtoc.py
+++ b/tools/dtoc/dtoc.py
@@ -54,6 +54,7 @@
     str = name.replace('@', '_at_')
     str = str.replace('-', '_')
     str = str.replace(',', '_')
+    str = str.replace('.', '_')
     str = str.replace('/', '__')
     return str
 
diff --git a/tools/patman/checkpatch.py b/tools/patman/checkpatch.py
index be78fc5..2915d97 100644
--- a/tools/patman/checkpatch.py
+++ b/tools/patman/checkpatch.py
@@ -138,7 +138,7 @@
         msg_type = col.Color(col.RED, msg_type)
     elif msg_type == 'check':
         msg_type = col.Color(col.MAGENTA, msg_type)
-    return '%s: %s,%d: %s' % (msg_type, fname, line, msg)
+    return '%s:%d: %s: %s\n' % (fname, line, msg_type, msg)
 
 def CheckPatches(verbose, args):
     '''Run the checkpatch.pl script on each patch'''
@@ -157,7 +157,8 @@
                     result.checks):
                 print("Internal error: some problems lost")
             for item in result.problems:
-                print(GetWarningMsg(col, item.get('type', '<unknown>'),
+                sys.stderr.write(
+                    GetWarningMsg(col, item.get('type', '<unknown>'),
                         item.get('file', '<unknown>'),
                         item.get('line', 0), item.get('msg', 'message')))
             print
diff --git a/tools/patman/series.py b/tools/patman/series.py
index 38a452e..c1b8652 100644
--- a/tools/patman/series.py
+++ b/tools/patman/series.py
@@ -235,7 +235,8 @@
 
         if cover_fname:
             cover_cc = gitutil.BuildEmailList(self.get('cover_cc', ''))
-            print(cover_fname, ', '.join(set(cover_cc + all_ccs)), file=fd)
+            cc_list = ', '.join([x.decode('utf-8') for x in set(cover_cc + all_ccs)])
+            print(cover_fname, cc_list.encode('utf-8'), file=fd)
 
         fd.close()
         return fname