Merge git://git.denx.de/u-boot-dm
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index b0f0ca8..06d0e8c 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -27,6 +27,10 @@
 		testfdt3 = "/b-test";
 		testfdt5 = "/some-bus/c-test@5";
 		testfdt8 = "/a-test";
+		fdt_dummy0 = "/translation-test@8000/dev@0,0";
+		fdt_dummy1 = "/translation-test@8000/dev@1,100";
+		fdt_dummy2 = "/translation-test@8000/dev@2,200";
+		fdt_dummy3 = "/translation-test@8000/noxlatebus@3,300/dev@42";
 		usb0 = &usb_0;
 		usb1 = &usb_1;
 		usb2 = &usb_2;
@@ -487,6 +491,50 @@
 			reg = <9 1>;
 		};
 	};
+
+	translation-test@8000 {
+		compatible = "simple-bus";
+		reg = <0x8000 0x4000>;
+
+		#address-cells = <0x2>;
+		#size-cells = <0x1>;
+
+		ranges = <0 0x0 0x8000 0x1000
+			  1 0x100 0x9000 0x1000
+			  2 0x200 0xA000 0x1000
+			  3 0x300 0xB000 0x1000
+			 >;
+
+		dev@0,0 {
+			compatible = "denx,u-boot-fdt-dummy";
+			reg = <0 0x0 0x1000>;
+		};
+
+		dev@1,100 {
+			compatible = "denx,u-boot-fdt-dummy";
+			reg = <1 0x100 0x1000>;
+
+		};
+
+		dev@2,200 {
+			compatible = "denx,u-boot-fdt-dummy";
+			reg = <2 0x200 0x1000>;
+		};
+
+
+		noxlatebus@3,300 {
+			compatible = "simple-bus";
+			reg = <3 0x300 0x1000>;
+
+			#address-cells = <0x1>;
+			#size-cells = <0x0>;
+
+			dev@42 {
+				compatible = "denx,u-boot-fdt-dummy";
+				reg = <0x42>;
+			};
+		};
+	};
 };
 
 #include "sandbox_pmic.dtsi"
diff --git a/cmd/cbfs.c b/cmd/cbfs.c
index 799ba01..736f8c4 100644
--- a/cmd/cbfs.c
+++ b/cmd/cbfs.c
@@ -22,7 +22,7 @@
 		return 0;
 	}
 	if (argc == 2) {
-		end_of_rom = (int)simple_strtoul(argv[1], &ep, 16);
+		end_of_rom = simple_strtoul(argv[1], &ep, 16);
 		if (*ep) {
 			puts("\n** Invalid end of ROM **\n");
 			return 1;
diff --git a/common/image-fdt.c b/common/image-fdt.c
index 25103ba..3dc02a1 100644
--- a/common/image-fdt.c
+++ b/common/image-fdt.c
@@ -21,6 +21,9 @@
 #define CONFIG_SYS_FDT_PAD 0x3000
 #endif
 
+/* adding a ramdisk needs 0x44 bytes in version 2008.10 */
+#define FDT_RAMDISK_OVERHEAD	0x80
+
 DECLARE_GLOBAL_DATA_PTR;
 
 static void fdt_error(const char *msg)
diff --git a/drivers/core/fdtaddr.c b/drivers/core/fdtaddr.c
index 3847dd8..9a3b4c3 100644
--- a/drivers/core/fdtaddr.c
+++ b/drivers/core/fdtaddr.c
@@ -49,12 +49,17 @@
 
 		reg += index * (na + ns);
 
-		/*
-		 * Use the full-fledged translate function for complex
-		 * bus setups.
-		 */
-		addr = fdt_translate_address((void *)gd->fdt_blob,
-					     dev_of_offset(dev), reg);
+		if (ns) {
+			/*
+			 * Use the full-fledged translate function for complex
+			 * bus setups.
+			 */
+			addr = fdt_translate_address((void *)gd->fdt_blob,
+						     dev_of_offset(dev), reg);
+		} else {
+			/* Non translatable if #size-cells == 0 */
+			addr = fdt_read_number(reg, na);
+		}
 	} else {
 		/*
 		 * Use the "simple" translate function for less complex
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c
index 4e45326..5909a25 100644
--- a/drivers/core/ofnode.c
+++ b/drivers/core/ofnode.c
@@ -227,13 +227,16 @@
 		uint flags;
 		u64 size;
 		int na;
+		int ns;
 
 		prop_val = of_get_address(ofnode_to_np(node), index, &size,
 					  &flags);
 		if (!prop_val)
 			return FDT_ADDR_T_NONE;
 
-		if (IS_ENABLED(CONFIG_OF_TRANSLATE)) {
+		ns = of_n_size_cells(ofnode_to_np(node));
+
+		if (IS_ENABLED(CONFIG_OF_TRANSLATE) && ns > 0) {
 			return of_translate_address(ofnode_to_np(node), prop_val);
 		} else {
 			na = of_n_addr_cells(ofnode_to_np(node));
diff --git a/drivers/core/root.c b/drivers/core/root.c
index 3a426ab..9000ed5 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -333,7 +333,8 @@
 
 int dm_extended_scan_fdt(const void *blob, bool pre_reloc_only)
 {
-	int node, ret;
+	int ret;
+	ofnode node;
 
 	ret = dm_scan_fdt(gd->fdt_blob, pre_reloc_only);
 	if (ret) {
@@ -342,13 +343,18 @@
 	}
 
 	/* bind fixed-clock */
-	node = ofnode_to_offset(ofnode_path("/clocks"));
+	node = ofnode_path("/clocks");
 	/* if no DT "clocks" node, no need to go further */
-	if (node < 0)
+	if (!ofnode_valid(node))
 		return ret;
 
-	ret = dm_scan_fdt_node(gd->dm_root, gd->fdt_blob, node,
-			       pre_reloc_only);
+#if CONFIG_IS_ENABLED(OF_LIVE)
+	if (of_live_active())
+		ret = dm_scan_fdt_live(gd->dm_root, node.np, pre_reloc_only);
+	else
+#endif
+		ret = dm_scan_fdt_node(gd->dm_root, gd->fdt_blob, node.of_offset,
+				       pre_reloc_only);
 	if (ret)
 		debug("dm_scan_fdt_node() failed: %d\n", ret);
 
diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index 1aedaa0..628e2e1 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -457,6 +457,32 @@
 }
 
 #if CONFIG_IS_ENABLED(OF_CONTROL)
+int uclass_get_device_by_phandle_id(enum uclass_id id, uint phandle_id,
+				    struct udevice **devp)
+{
+	struct udevice *dev;
+	struct uclass *uc;
+	int ret;
+
+	*devp = NULL;
+	ret = uclass_get(id, &uc);
+	if (ret)
+		return ret;
+
+	list_for_each_entry(dev, &uc->dev_head, uclass_node) {
+		uint phandle;
+
+		phandle = dev_read_phandle(dev);
+
+		if (phandle == phandle_id) {
+			*devp = dev;
+			return uclass_get_device_tail(dev, ret, devp);
+		}
+	}
+
+	return -ENODEV;
+}
+
 int uclass_get_device_by_phandle(enum uclass_id id, struct udevice *parent,
 				 const char *name, struct udevice **devp)
 {
diff --git a/drivers/pinctrl/pinctrl-uclass.c b/drivers/pinctrl/pinctrl-uclass.c
index 6a73a06..a0a326a 100644
--- a/drivers/pinctrl/pinctrl-uclass.c
+++ b/drivers/pinctrl/pinctrl-uclass.c
@@ -12,6 +12,7 @@
 #include <dm/lists.h>
 #include <dm/pinctrl.h>
 #include <dm/util.h>
+#include <dm/of_access.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -63,16 +64,13 @@
  */
 static int pinctrl_select_state_full(struct udevice *dev, const char *statename)
 {
-	const void *fdt = gd->fdt_blob;
-	int node = dev_of_offset(dev);
 	char propname[32]; /* long enough */
 	const fdt32_t *list;
 	uint32_t phandle;
-	int config_node;
 	struct udevice *config;
 	int state, size, i, ret;
 
-	state = fdt_stringlist_search(fdt, node, "pinctrl-names", statename);
+	state = dev_read_stringlist_search(dev, "pinctrl-names", statename);
 	if (state < 0) {
 		char *end;
 		/*
@@ -85,22 +83,15 @@
 	}
 
 	snprintf(propname, sizeof(propname), "pinctrl-%d", state);
-	list = fdt_getprop(fdt, node, propname, &size);
+	list = dev_read_prop(dev, propname, &size);
 	if (!list)
 		return -EINVAL;
 
 	size /= sizeof(*list);
 	for (i = 0; i < size; i++) {
 		phandle = fdt32_to_cpu(*list++);
-
-		config_node = fdt_node_offset_by_phandle(fdt, phandle);
-		if (config_node < 0) {
-			dev_err(dev, "prop %s index %d invalid phandle\n",
-				propname, i);
-			return -EINVAL;
-		}
-		ret = uclass_get_device_by_of_offset(UCLASS_PINCONFIG,
-						     config_node, &config);
+		ret = uclass_get_device_by_phandle_id(UCLASS_PINCONFIG, phandle,
+						      &config);
 		if (ret)
 			return ret;
 
diff --git a/fs/cbfs/cbfs.c b/fs/cbfs/cbfs.c
index 6e1107d..46da8f1 100644
--- a/fs/cbfs/cbfs.c
+++ b/fs/cbfs/cbfs.c
@@ -168,9 +168,9 @@
 				 struct cbfs_header *header)
 {
 	struct cbfs_header *header_in_rom;
+	int32_t offset = *(u32 *)(end_of_rom - 3);
 
-	header_in_rom = (struct cbfs_header *)(uintptr_t)
-			*(u32 *)(end_of_rom - 3);
+	header_in_rom = (struct cbfs_header *)(end_of_rom + offset + 1);
 	swap_header(header, header_in_rom);
 
 	if (header->magic != good_magic || header->offset >
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index 07fabc3..d28fb3e 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -19,6 +19,7 @@
 	UCLASS_TEST_FDT,
 	UCLASS_TEST_BUS,
 	UCLASS_TEST_PROBE,
+	UCLASS_TEST_DUMMY,
 	UCLASS_SPI_EMUL,	/* sandbox SPI device emulator */
 	UCLASS_I2C_EMUL,	/* sandbox I2C device emulator */
 	UCLASS_PCI_EMUL,	/* sandbox PCI device emulator */
diff --git a/include/dm/uclass.h b/include/dm/uclass.h
index 3a01abc..a5bf3eb 100644
--- a/include/dm/uclass.h
+++ b/include/dm/uclass.h
@@ -211,6 +211,22 @@
 				struct udevice **devp);
 
 /**
+ * uclass_get_device_by_phandle_id() - Get a uclass device by phandle id
+ *
+ * This searches the devices in the uclass for one with the given phandle id.
+ *
+ * The device is probed to activate it ready for use.
+ *
+ * @id: uclass ID to look up
+ * @phandle_id: the phandle id to look up
+ * @devp: Returns pointer to device (there is only one for each node)
+ * @return 0 if OK, -ENODEV if there is no device match the phandle, other
+ *	-ve on error
+ */
+int uclass_get_device_by_phandle_id(enum uclass_id id, uint phandle_id,
+				    struct udevice **devp);
+
+/**
  * uclass_get_device_by_phandle() - Get a uclass device by phandle
  *
  * This searches the devices in the uclass for one with the given phandle.
diff --git a/include/image.h b/include/image.h
index 621abf6..a6f82ae 100644
--- a/include/image.h
+++ b/include/image.h
@@ -21,6 +21,7 @@
 
 /* Define this to avoid #ifdefs later on */
 struct lmb;
+struct fdt_region;
 
 #ifdef USE_HOSTCC
 #include <sys/types.h>
diff --git a/include/linux/libfdt.h b/include/linux/libfdt.h
index 9e6eead..eeb2344 100644
--- a/include/linux/libfdt.h
+++ b/include/linux/libfdt.h
@@ -309,7 +309,4 @@
 
 extern struct fdt_header *working_fdt;  /* Pointer to the working fdt */
 
-/* adding a ramdisk needs 0x44 bytes in version 2008.10 */
-#define FDT_RAMDISK_OVERHEAD	0x80
-
 #endif /* _INCLUDE_LIBFDT_H_ */
diff --git a/lib/libfdt/fdt_region.c b/lib/libfdt/fdt_region.c
index 70914a4..054c4b3 100644
--- a/lib/libfdt/fdt_region.c
+++ b/lib/libfdt/fdt_region.c
@@ -14,8 +14,6 @@
 #include "fdt_host.h"
 #endif
 
-#include "libfdt_internal.h"
-
 #define FDT_MAX_DEPTH	32
 
 static int str_in_list(const char *str, char * const list[], int count)
diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c
index 920ccbf..0d11bfd 100644
--- a/test/dm/test-fdt.c
+++ b/test/dm/test-fdt.c
@@ -419,3 +419,46 @@
 	return 0;
 }
 DM_TEST(dm_test_first_next_ok_device, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+static const struct udevice_id fdt_dummy_ids[] = {
+	{ .compatible = "denx,u-boot-fdt-dummy", },
+	{ }
+};
+
+UCLASS_DRIVER(fdt_dummy) = {
+	.name		= "fdt_dummy",
+	.id		= UCLASS_TEST_DUMMY,
+	.flags		= DM_UC_FLAG_SEQ_ALIAS,
+};
+
+U_BOOT_DRIVER(fdt_dummy_drv) = {
+	.name	= "fdt_dummy_drv",
+	.of_match	= fdt_dummy_ids,
+	.id	= UCLASS_TEST_DUMMY,
+};
+
+static int dm_test_fdt_translation(struct unit_test_state *uts)
+{
+	struct udevice *dev;
+
+	/* Some simple translations */
+	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, true, &dev));
+	ut_asserteq_str("dev@0,0", dev->name);
+	ut_asserteq(0x8000, dev_read_addr(dev));
+
+	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 1, true, &dev));
+	ut_asserteq_str("dev@1,100", dev->name);
+	ut_asserteq(0x9000, dev_read_addr(dev));
+
+	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 2, true, &dev));
+	ut_asserteq_str("dev@2,200", dev->name);
+	ut_asserteq(0xA000, dev_read_addr(dev));
+
+	/* No translation for busses with #size-cells == 0 */
+	ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 3, true, &dev));
+	ut_asserteq_str("dev@42", dev->name);
+	ut_asserteq(0x42, dev_read_addr(dev));
+
+	return 0;
+}
+DM_TEST(dm_test_fdt_translation, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);