[U-Boot-Users] [RFC][PATCH] fdt fixup

Kumar Gala galak at kernel.crashing.org
Thu Nov 1 23:17:10 CET 2007


This code adds a generic fixup mechanism that allows us to get ride of
needing explicit paths to device nodes.

diff --git a/common/fdt_support.c b/common/fdt_support.c
index 7a81469..2c1e8ac 100644
--- a/common/fdt_support.c
+++ b/common/fdt_support.c
@@ -363,4 +363,125 @@ int fdt_bd_t(void *fdt)
 }
 #endif /* ifdef CONFIG_OF_HAS_BD_T */

+/*
+ * "Setter" functions used to add/modify FDT entries.
+ */
+#ifdef CONFIG_HAS_ETH0
+static int fdt_set_eth0(void *blob, int nodeoffset, const char *name, bd_t *bd)
+{
+	/* Fix it up if it exists, don't create it if it doesn't exist */
+	if (fdt_get_property(blob, nodeoffset, name, 0)) {
+		return fdt_setprop(blob, nodeoffset, name, bd->bi_enetaddr, 6);
+	}
+	return 0;
+}
+#endif
+#ifdef CONFIG_HAS_ETH1
+/* second onboard ethernet port */
+static int fdt_set_eth1(void *blob, int nodeoffset, const char *name, bd_t *bd)
+{
+	/* Fix it up if it exists, don't create it if it doesn't exist */
+	if (fdt_get_property(blob, nodeoffset, name, 0)) {
+		return fdt_setprop(blob, nodeoffset, name, bd->bi_enet1addr, 6);
+	}
+	return 0;
+}
+#endif
+#ifdef CONFIG_HAS_ETH2
+/* third onboard ethernet port */
+static int fdt_set_eth2(void *blob, int nodeoffset, const char *name, bd_t *bd)
+{
+	/* Fix it up if it exists, don't create it if it doesn't exist */
+	if (fdt_get_property(blob, nodeoffset, name, 0)) {
+		return fdt_setprop(blob, nodeoffset, name, bd->bi_enet2addr, 6);
+	}
+	return 0;
+}
+#endif
+#ifdef CONFIG_HAS_ETH3
+/* fourth onboard ethernet port */
+static int fdt_set_eth3(void *blob, int nodeoffset, const char *name, bd_t *bd)
+{
+	/* Fix it up if it exists, don't create it if it doesn't exist */
+	if (fdt_get_property(blob, nodeoffset, name, 0)) {
+		return fdt_setprop(blob, nodeoffset, name, bd->bi_enet3addr, 6);
+	}
+	return 0;
+}
+#endif
+
+static int fdt_set_busfreq(void *blob, int nodeoffset, const char *name, bd_t *bd)
+{
+	u32 tmp;
+	/* Create or update the property */
+	tmp = cpu_to_be32(bd->bi_busfreq);
+	return fdt_setprop(blob, nodeoffset, name, &tmp, sizeof(tmp));
+}
+
+static int fdt_set_tbfreq(void *blob, int nodeoffset, const char *name, bd_t *bd)
+{
+	u32 tmp;
+	/* Create or update the property */
+	tmp = cpu_to_be32(bd->bi_busfreq / 8);
+	return fdt_setprop(blob, nodeoffset, name, &tmp, sizeof(tmp));
+}
+
+static int fdt_set_stdout_path(void *blob, int nodeoffset, const char *name, bd_t *bd)
+{
+	char buf[256];
+	int err, off;
+
+	off = fdt_path_offset(blob, "/chosen");
+	if (off < 0)
+		return off;
+
+	err = fdt_get_path(blob, nodeoffset, &buf, 256);
+	if (err < 0)
+		return err;
+
+	err = fdt_setprop(blob, off, "linux,stdout-path", buf, err + 1);
+
+	return err;
+}
+
+/*
+ * Fixups to the fdt.
+ */
+
+void fdt_fixups(struct fdt_fixup *tbl, int num, void *blob, bd_t *bd)
+{
+	int j, err, off;
+
+	for (j = 0; j < num; j++) {
+		off = -1;
+		do {
+			if (tbl[j].compat)
+				off = fdt_node_offset_by_prop_and_compat(blob,
+					off, tbl[j].compat, "device_type",
+					tbl[j].type, strlen(tbl[j].type) + 1);
+			else
+				off = fdt_node_offset_by_prop_value(blob, off,
+					"device_type",
+					tbl[j].type, strlen(tbl[j].type) + 1);
+
+			if (off >= 0) {
+				if (tbl[j].name) {
+					int len;
+					const char *name;
+
+					name = fdt_get_name(blob, off, &len);
+					if (strncmp(name, tbl[j].name, len) != 0)
+						continue;
+				}
+
+				err = tbl[j].set_fn(blob, off, tbl[j].prop, bd);
+				if (err < 0)
+					debug("Problem setting %s = %s: %s\n",
+					      tbl[j].node, tbl[j].prop,
+					      fdt_strerror(err));
+			}
+		} while (off >= 0);
+	}
+}
+
 #endif /* CONFIG_OF_LIBFDT */
diff --git a/include/fdt_support.h b/include/fdt_support.h
index 60fa423..f66e562 100644
--- a/include/fdt_support.h
+++ b/include/fdt_support.h
@@ -28,7 +28,18 @@

 #include <fdt.h>

+typedef int (*set_fn_t)(void *blob, int nodeoffset, const char *name, bd_t *bd);
+
+struct fdt_fixup {
+	const char *type;
+	const char *compat;
+	const char *prop;
+	const char *name;
+	set_fn_t set_fn;
+};
+
 int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end, int force);
+void fdt_fixups(struct fdt_fixup *tbl, int num, void *blob, bd_t *bd);

 #ifdef CONFIG_OF_HAS_UBOOT_ENV
 int fdt_env(void *fdt);




More information about the U-Boot mailing list