Merge remote-tracking branch 'github/pr/94' into github-ci
diff --git a/Documentation/dt-object-internal.txt b/Documentation/dt-object-internal.txt
index 51d68ab..c7357e6 100644
--- a/Documentation/dt-object-internal.txt
+++ b/Documentation/dt-object-internal.txt
@@ -35,7 +35,7 @@
 should result in different Device Tree configuration.
 
 We cannot boot with this static tree because due to the configuration of the
-foo platform there exist multiple conficting peripherals DT fragments.
+foo platform there exist multiple conflicting peripherals DT fragments.
 
 So for the bar peripheral we would have this:
 
diff --git a/checks.c b/checks.c
index 16bc7f6..8ed7a60 100644
--- a/checks.c
+++ b/checks.c
@@ -1767,6 +1767,11 @@
 		      get_property(child, "remote-endpoint")))
 			continue;
 
+                /* The root node cannot be a port */
+		if (!node->parent) {
+			FAIL(c, dti, node, "root node contains endpoint node '%s', potentially misplaced remote-endpoint property", child->name);
+			continue;
+		}
 		node->bus = &graph_port_bus;
 
 		/* The parent of 'port' nodes can be either 'ports' or a device */
diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c
index 9f6c551..c4c520c 100644
--- a/libfdt/fdt_ro.c
+++ b/libfdt/fdt_ro.c
@@ -522,16 +522,22 @@
 	return fdt32_ld_(php);
 }
 
+static const void *fdt_path_getprop_namelen(const void *fdt, const char *path,
+					    const char *propname, int propnamelen,
+					    int *lenp)
+{
+	int offset = fdt_path_offset(fdt, path);
+
+	if (offset < 0)
+		return NULL;
+
+	return fdt_getprop_namelen(fdt, offset, propname, propnamelen, lenp);
+}
+
 const char *fdt_get_alias_namelen(const void *fdt,
 				  const char *name, int namelen)
 {
-	int aliasoffset;
-
-	aliasoffset = fdt_path_offset(fdt, "/aliases");
-	if (aliasoffset < 0)
-		return NULL;
-
-	return fdt_getprop_namelen(fdt, aliasoffset, name, namelen, NULL);
+	return fdt_path_getprop_namelen(fdt, "/aliases", name, namelen, NULL);
 }
 
 const char *fdt_get_alias(const void *fdt, const char *name)
@@ -539,6 +545,17 @@
 	return fdt_get_alias_namelen(fdt, name, strlen(name));
 }
 
+const char *fdt_get_symbol_namelen(const void *fdt,
+				   const char *name, int namelen)
+{
+	return fdt_path_getprop_namelen(fdt, "/__symbols__", name, namelen, NULL);
+}
+
+const char *fdt_get_symbol(const void *fdt, const char *name)
+{
+	return fdt_get_symbol_namelen(fdt, name, strlen(name));
+}
+
 int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
 {
 	int pdepth = 0, p = 0;
diff --git a/libfdt/libfdt.h b/libfdt/libfdt.h
index d0a2ed2..34c4d55 100644
--- a/libfdt/libfdt.h
+++ b/libfdt/libfdt.h
@@ -524,10 +524,35 @@
  * level matching the given component, differentiated only by unit
  * address).
  *
+ * If the path is not absolute (i.e. does not begin with '/'), the
+ * first component is treated as an alias.  That is, the property by
+ * that name is looked up in the /aliases node, and the value of that
+ * property used in place of that first component.
+ *
+ * For example, for this small fragment
+ *
+ * / {
+ *     aliases {
+ *         i2c2 = &foo; // RHS compiles to "/soc@0/i2c@30a40000/eeprom@52"
+ *     };
+ *     soc@0 {
+ *         foo: i2c@30a40000 {
+ *             bar: eeprom@52 {
+ *             };
+ *         };
+ *     };
+ * };
+ *
+ * these would be equivalent:
+ *
+ *   /soc@0/i2c@30a40000/eeprom@52
+ *   i2c2/eeprom@52
+ *
  * returns:
  *	structure block offset of the node with the requested path (>=0), on
  *		success
- *	-FDT_ERR_BADPATH, given path does not begin with '/' or is invalid
+ *	-FDT_ERR_BADPATH, given path does not begin with '/' and the first
+ *		component is not a valid alias
  *	-FDT_ERR_NOTFOUND, if the requested node does not exist
  *      -FDT_ERR_BADMAGIC,
  *	-FDT_ERR_BADVERSION,
@@ -870,6 +895,42 @@
 const char *fdt_get_alias(const void *fdt, const char *name);
 
 /**
+ * fdt_get_symbol_namelen - get symbol based on substring
+ * @fdt: pointer to the device tree blob
+ * @name: name of the symbol to look up
+ * @namelen: number of characters of name to consider
+ *
+ * Identical to fdt_get_symbol(), but only examine the first @namelen
+ * characters of @name for matching the symbol name.
+ *
+ * Return: a pointer to the expansion of the symbol named @name, if it exists,
+ *	   NULL otherwise
+ */
+#ifndef SWIG /* Not available in Python */
+const char *fdt_get_symbol_namelen(const void *fdt,
+				   const char *name, int namelen);
+#endif
+
+/**
+ * fdt_get_symbol - retrieve the path referenced by a given symbol
+ * @fdt: pointer to the device tree blob
+ * @name: name of the symbol to look up
+ *
+ * fdt_get_symbol() retrieves the value of a given symbol.  That is,
+ * the value of the property named @name in the node
+ * /__symbols__. Such a node exists only for a device tree blob that
+ * has been compiled with the -@ dtc option. Each property corresponds
+ * to a label appearing in the device tree source, with the name of
+ * the property being the label and the value being the full path of
+ * the node it is attached to.
+ *
+ * returns:
+ *	a pointer to the expansion of the symbol named 'name', if it exists
+ *	NULL, if the given symbol or the /__symbols__ node does not exist
+ */
+const char *fdt_get_symbol(const void *fdt, const char *name);
+
+/**
  * fdt_get_path - determine the full path of a node
  * @fdt: pointer to the device tree blob
  * @nodeoffset: offset of the node whose path to find
diff --git a/tests/bad-graph-root1.dts b/tests/bad-graph-root1.dts
new file mode 100644
index 0000000..06cf915
--- /dev/null
+++ b/tests/bad-graph-root1.dts
@@ -0,0 +1,7 @@
+/dts-v1/;
+
+/ {
+	foo {
+                remote-endpoint = <0xdeadbeef>;
+	};
+};
diff --git a/tests/bad-graph-root2.dts b/tests/bad-graph-root2.dts
new file mode 100644
index 0000000..026f207
--- /dev/null
+++ b/tests/bad-graph-root2.dts
@@ -0,0 +1,2 @@
+/dts-v1/;
+/ {	endpoint {};  };
diff --git a/tests/bad-graph-root3.dts b/tests/bad-graph-root3.dts
new file mode 100644
index 0000000..7360013
--- /dev/null
+++ b/tests/bad-graph-root3.dts
@@ -0,0 +1,14 @@
+/dts-v1/;
+
+ / {
+	bar: bar {
+		port {
+			bar_con: endpoint {
+				remote-endpoint = <&foo_con>;
+			};
+		};
+	};
+	foo_con: endpoint {
+		remote-endpoint = <&bar_con>;
+	};
+};
diff --git a/tests/bad-graph-root4.dts b/tests/bad-graph-root4.dts
new file mode 100644
index 0000000..5b1a1ea
--- /dev/null
+++ b/tests/bad-graph-root4.dts
@@ -0,0 +1,19 @@
+/dts-v1/;
+
+ / {
+
+	bar: bar {
+		port {
+			bar_con: endpoint {
+				remote-endpoint = <&foo_con>;
+			};
+		};
+	};
+	foo {
+		remote-endpoint = <&bar_con>; // misplaced remote-endpoint property
+		port {
+			foo_con: endpoint {
+			};
+		};
+	};
+};
diff --git a/tests/run_tests.sh b/tests/run_tests.sh
index 57795d7..d7a6d49 100755
--- a/tests/run_tests.sh
+++ b/tests/run_tests.sh
@@ -730,6 +730,10 @@
     check_tests "$SRCDIR/bad-graph.dts" graph_child_address
     check_tests "$SRCDIR/bad-graph.dts" graph_port
     check_tests "$SRCDIR/bad-graph.dts" graph_endpoint
+    check_tests "$SRCDIR/bad-graph-root1.dts" graph_nodes
+    check_tests "$SRCDIR/bad-graph-root2.dts" graph_nodes
+    check_tests "$SRCDIR/bad-graph-root3.dts" graph_nodes
+    check_tests "$SRCDIR/bad-graph-root4.dts" graph_nodes
     run_sh_test "$SRCDIR/dtc-checkfails.sh" deprecated_gpio_property -- -Wdeprecated_gpio_property -I dts -O dtb "$SRCDIR/bad-gpio.dts"
     run_sh_test "$SRCDIR/dtc-checkfails.sh" -n deprecated_gpio_property -- -Wdeprecated_gpio_property -I dts -O dtb "$SRCDIR/good-gpio.dts"
     check_tests "$SRCDIR/bad-interrupt-cells.dts" interrupts_property