Skip to content

Commit a4ebca6

Browse files
committed
lk2nd: util: lkfdt: Add more uint32_t/phandle helpers used in qebspil
These are not used in lk2nd yet, but might come useful in the future.
1 parent 7cba95c commit a4ebca6

File tree

2 files changed

+89
-5
lines changed

2 files changed

+89
-5
lines changed

lk2nd/include/lk2nd/util/lkfdt.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,30 @@ bool lkfdt_node_is_available(const void *fdt, int node) __PURE;
4848
*/
4949
int lkfdt_get_reg(const void *fdt, int parent, int node, uint32_t *addr, uint32_t *size) __PURE;
5050

51+
/**
52+
* lkfdt_getprop_u32() - Read 32-bit number (e.g. phandle) from property.
53+
* @fdt: Device tree blob
54+
* @node: Device tree node offset
55+
* @prop: Name of property that contains the uint32_t value
56+
* @val: Output variable that is filled with the decoded uint32_t value
57+
*
58+
* Return: 0 if successful, <0 libfdt error
59+
*/
60+
int lkfdt_getprop_u32(const void *fdt, int node, const char *prop, uint32_t *val) __PURE;
61+
62+
/**
63+
* lkfdt_u32list_get() - Read one specific 32-bit number from a list.
64+
* @fdt: Device tree blob
65+
* @node: Device tree node offset
66+
* @prop: Name of property that contains the uint32_t list
67+
* @idx: Index of uint32_t to return from the list (must be >= 0)
68+
* @val: Output variable that is filled with the uint32_t value
69+
*
70+
* Return: 0 if successful, <0 libfdt error (e.g. -FDT_ERR_NOTFOUND)
71+
*/
72+
int lkfdt_u32list_get(const void *fdt, int node, const char *prop,
73+
int idx, uint32_t *val) __PURE;
74+
5175
/**
5276
* lkfdt_lookup_phandle() - Read phandle from property and search for the node.
5377
* @fdt: Device tree blob
@@ -60,6 +84,21 @@ int lkfdt_get_reg(const void *fdt, int parent, int node, uint32_t *addr, uint32_
6084
*/
6185
int lkfdt_lookup_phandle(const void *fdt, int node, const char *prop) __PURE;
6286

87+
/**
88+
* lkfdt_subnode_offset_by_phandle() - Return subnode that matches a phandle.
89+
* @fdt: Device tree blob
90+
* @parent: Device tree node offset of parent
91+
* @phandle: The phandle to search for
92+
*
93+
* Iterate over all subnodes of the "parent" and look for the node that has
94+
* the specified "phandle".
95+
*
96+
* Return:
97+
* * >= 0 - The offset of the subnode that matches the phandle, if successful
98+
* * < 0 - libfdt error (<0), otherwise
99+
*/
100+
int lkfdt_subnode_offset_by_phandle(const void *fdt, int parent, uint32_t phandle) __PURE;
101+
63102
/**
64103
* lkfdt_stringlist_get_all() - Obtain array of strings for a given prop
65104
* @fdt: Device tree blob

lk2nd/util/lkfdt.c

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,18 +66,63 @@ int lkfdt_get_reg(const void *fdt, int parent, int node,
6666
return 0;
6767
}
6868

69-
int lkfdt_lookup_phandle(const void *fdt, int node, const char *prop)
69+
int lkfdt_getprop_u32(const void *fdt, int node, const char *prop, uint32_t *val)
7070
{
71-
const fdt32_t *phandle;
71+
const fdt32_t *fval;
7272
int len;
7373

74-
phandle = fdt_getprop(fdt, node, prop, &len);
74+
fval = fdt_getprop(fdt, node, prop, &len);
7575
if (len < 0)
7676
return len;
77-
if (len != sizeof(*phandle))
77+
if (len != sizeof(*fval))
7878
return -FDT_ERR_BADVALUE;
7979

80-
return fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*phandle));
80+
*val = fdt32_to_cpu(*fval);
81+
return 0;
82+
}
83+
84+
int lkfdt_u32list_get(const void *fdt, int node, const char *prop,
85+
int idx, uint32_t *val)
86+
{
87+
const fdt32_t *fvals;
88+
int len;
89+
90+
if (idx < 0 || idx >= (INT_MAX / (int)sizeof(*fvals)))
91+
return -FDT_ERR_BADOFFSET;
92+
93+
fvals = fdt_getprop(fdt, node, prop, &len);
94+
if (len < 0)
95+
return len;
96+
if (len % sizeof(*fvals))
97+
return -FDT_ERR_BADVALUE;
98+
if (len < ((idx + 1) * (int)sizeof(*fvals)))
99+
return -FDT_ERR_NOTFOUND;
100+
101+
*val = fdt32_to_cpu(fvals[idx]);
102+
return 0;
103+
}
104+
105+
int lkfdt_lookup_phandle(const void *fdt, int node, const char *prop)
106+
{
107+
uint32_t phandle;
108+
int ret;
109+
110+
ret = lkfdt_getprop_u32(fdt, node, prop, &phandle);
111+
if (ret < 0)
112+
return ret;
113+
114+
return fdt_node_offset_by_phandle(fdt, phandle);
115+
}
116+
117+
int lkfdt_subnode_offset_by_phandle(const void *fdt, int parent, uint32_t phandle)
118+
{
119+
int node;
120+
121+
fdt_for_each_subnode(node, fdt, parent) {
122+
if (fdt_get_phandle(fdt, node) == phandle)
123+
return node;
124+
}
125+
return node;
81126
}
82127

83128
/**

0 commit comments

Comments
 (0)