On 11/3/21 03:02, Marek Behún wrote:
From: Marek Behún <[email protected]>

Add functions
   fdt_node_offset_by_pathf(),
   fdt_create_phandle_by_pathf(),
   fdt_set_status_by_pathf()
to get node offset, get/create node phandle and set status for node
given by path/alias formatted with sprintf.

Add functions
   fdt_create_phandle_by_compatible(),
   fdt_set_status_by_compatible()
to get/create node phandle and set status for first node given by
compatible.

Signed-off-by: Marek Behún <[email protected]>

My only concern here, that this might blow up the code size. But as
these new functions are unused by current boards, this should not be
the case. So

Reviewed-by: Stefan Roese <[email protected]>

Thanks,
Stefan

---
  common/fdt_support.c  | 119 ++++++++++++++++++++++++++++++++++++++++++
  include/fdt_support.h |  30 +++++++++++
  2 files changed, 149 insertions(+)

diff --git a/common/fdt_support.c b/common/fdt_support.c
index df111f708c..c2e16727e1 100644
--- a/common/fdt_support.c
+++ b/common/fdt_support.c
@@ -1463,6 +1463,37 @@ int fdt_node_offset_by_compat_reg(void *blob, const char 
*compat,
        return -FDT_ERR_NOTFOUND;
  }
+static int vnode_offset_by_pathf(void *blob, const char *fmt, va_list ap)
+{
+       char path[512];
+       int len;
+
+       len = vsnprintf(path, sizeof(path), fmt, ap);
+       if (len < 0 || len + 1 > sizeof(path))
+               return -FDT_ERR_NOSPACE;
+
+       return fdt_path_offset(blob, path);
+}
+
+/**
+ * fdt_node_offset_by_pathf: Find node offset by sprintf formatted path
+ *
+ * @blob: ptr to device tree
+ * @fmt: path format
+ * @ap: vsnprintf arguments
+ */
+int fdt_node_offset_by_pathf(void *blob, const char *fmt, ...)
+{
+       va_list ap;
+       int res;
+
+       va_start(ap, fmt);
+       res = vnode_offset_by_pathf(blob, fmt, ap);
+       va_end(ap);
+
+       return res;
+}
+
  /*
   * fdt_set_phandle: Create a phandle property for the given node
   *
@@ -1536,6 +1567,51 @@ unsigned int fdt_create_phandle(void *fdt, int 
nodeoffset)
        return phandle;
  }
+/**
+ * fdt_create_phandle_by_compatible: Get or create a phandle for first node 
with
+ *                                  given compatible
+ *
+ * @fdt: ptr to device tree
+ * @compat: node's compatible string
+ */
+unsigned int fdt_create_phandle_by_compatible(void *fdt, const char *compat)
+{
+       int offset = fdt_node_offset_by_compatible(fdt, -1, compat);
+
+       if (offset < 0) {
+               printf("Can't find node with compatible \"%s\": %s\n", compat,
+                      fdt_strerror(offset));
+               return 0;
+       }
+
+       return fdt_create_phandle(fdt, offset);
+}
+
+/**
+ * fdt_create_phandle_by_pathf: Get or create a phandle for node given by
+ *                             sprintf-formatted path
+ *
+ * @fdt: ptr to device tree
+ * @fmt, ...: path format string and arguments to pass to sprintf
+ */
+unsigned int fdt_create_phandle_by_pathf(void *fdt, const char *fmt, ...)
+{
+       va_list ap;
+       int offset;
+
+       va_start(ap, fmt);
+       offset = vnode_offset_by_pathf(fdt, fmt, ap);
+       va_end(ap);
+
+       if (offset < 0) {
+               printf("Can't find node by given path: %s\n",
+                      fdt_strerror(offset));
+               return 0;
+       }
+
+       return fdt_create_phandle(fdt, offset);
+}
+
  /*
   * fdt_set_node_status: Set status for the given node
   *
@@ -1584,6 +1660,49 @@ int fdt_set_status_by_alias(void *fdt, const char* alias,
        return fdt_set_node_status(fdt, offset, status);
  }
+/**
+ * fdt_set_status_by_compatible: Set node status for first node with given
+ *                              compatible
+ *
+ * @fdt: ptr to device tree
+ * @compat: node's compatible string
+ * @status: FDT_STATUS_OKAY, FDT_STATUS_DISABLED, FDT_STATUS_FAIL
+ */
+int fdt_set_status_by_compatible(void *fdt, const char *compat,
+                                enum fdt_status status)
+{
+       int offset = fdt_node_offset_by_compatible(fdt, -1, compat);
+
+       if (offset < 0)
+               return offset;
+
+       return fdt_set_node_status(fdt, offset, status);
+}
+
+/**
+ * fdt_set_status_by_pathf: Set node status for node given by sprintf-formatted
+ *                         path
+ *
+ * @fdt: ptr to device tree
+ * @status: FDT_STATUS_OKAY, FDT_STATUS_DISABLED, FDT_STATUS_FAIL
+ * @fmt, ...: path format string and arguments to pass to sprintf
+ */
+int fdt_set_status_by_pathf(void *fdt, enum fdt_status status, const char *fmt,
+                           ...)
+{
+       va_list ap;
+       int offset;
+
+       va_start(ap, fmt);
+       offset = vnode_offset_by_pathf(fdt, fmt, ap);
+       va_end(ap);
+
+       if (offset < 0)
+               return offset;
+
+       return fdt_set_node_status(fdt, offset, status);
+}
+
  #if defined(CONFIG_VIDEO) || defined(CONFIG_LCD)
  int fdt_add_edid(void *blob, const char *compat, unsigned char *edid_buf)
  {
diff --git a/include/fdt_support.h b/include/fdt_support.h
index 850c860bd4..d40586725b 100644
--- a/include/fdt_support.h
+++ b/include/fdt_support.h
@@ -285,8 +285,13 @@ int fdt_get_dma_range(const void *blob, int node_offset, 
phys_addr_t *cpu,
int fdt_node_offset_by_compat_reg(void *blob, const char *compat,
                                        phys_addr_t compat_off);
+int fdt_node_offset_by_pathf(void *blob, const char *fmt, ...)
+       __attribute__ ((format (printf, 2, 3)));
  int fdt_set_phandle(void *fdt, int nodeoffset, uint32_t phandle);
  unsigned int fdt_create_phandle(void *fdt, int nodeoffset);
+unsigned int fdt_create_phandle_by_compatible(void *fdt, const char *compat);
+unsigned int fdt_create_phandle_by_pathf(void *fdt, const char *fmt, ...)
+       __attribute__ ((format (printf, 2, 3)));
  int fdt_add_edid(void *blob, const char *compat, unsigned char *buf);
int fdt_verify_alias_address(void *fdt, int anode, const char *alias,
@@ -329,6 +334,31 @@ static inline int fdt_status_fail_by_alias(void *fdt, 
const char *alias)
        return fdt_set_status_by_alias(fdt, alias, FDT_STATUS_FAIL);
  }
+int fdt_set_status_by_compatible(void *fdt, const char *compat,
+                                enum fdt_status status);
+static inline int fdt_status_okay_by_compatible(void *fdt, const char *compat)
+{
+       return fdt_set_status_by_compatible(fdt, compat, FDT_STATUS_OKAY);
+}
+static inline int fdt_status_disabled_by_compatible(void *fdt,
+                                                   const char *compat)
+{
+       return fdt_set_status_by_compatible(fdt, compat, FDT_STATUS_DISABLED);
+}
+static inline int fdt_status_fail_by_compatible(void *fdt, const char *compat)
+{
+       return fdt_set_status_by_compatible(fdt, compat, FDT_STATUS_FAIL);
+}
+
+int fdt_set_status_by_pathf(void *fdt, enum fdt_status status, const char *fmt,
+                           ...) __attribute__ ((format (printf, 3, 4)));
+#define fdt_status_okay_by_pathf(fdt, fmt, ...) \
+       fdt_set_status_by_pathf((fdt), FDT_STATUS_OKAY, (fmt), ##__VA_ARGS__)
+#define fdt_status_disabled_by_pathf(fdt, fmt, ...) \
+       fdt_set_status_by_pathf((fdt), FDT_STATUS_DISABLED, (fmt), 
##__VA_ARGS__)
+#define fdt_status_fail_by_pathf(fdt, fmt, ...) \
+       fdt_set_status_by_pathf((fdt), FDT_STATUS_FAIL, (fmt), ##__VA_ARGS__)
+
  /* Helper to read a big number; size is in cells (not bytes) */
  static inline u64 fdt_read_number(const fdt32_t *cell, int size)
  {


Viele Grüße,
Stefan Roese

--
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-51 Fax: (+49)-8142-66989-80 Email: [email protected]

Reply via email to