[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