fdt_support: Add some useful functions

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 <marek.behun@nic.cz>
Reviewed-by: Stefan Roese <sr@denx.de>
This commit is contained in:
Marek Behún 2021-11-26 14:57:10 +01:00 committed by Stefan Roese
parent c92ccba771
commit 9ab0c2f837
2 changed files with 149 additions and 0 deletions

View File

@ -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)
{

View File

@ -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)
{