aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of/fdt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/of/fdt.c')
-rw-r--r--drivers/of/fdt.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 9faa9a5cbdf0..dd9057cb7aa7 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -19,3 +19,67 @@ char *find_flat_dt_string(u32 offset)
19 return ((char *)initial_boot_params) + 19 return ((char *)initial_boot_params) +
20 initial_boot_params->off_dt_strings + offset; 20 initial_boot_params->off_dt_strings + offset;
21} 21}
22
23/**
24 * of_scan_flat_dt - scan flattened tree blob and call callback on each.
25 * @it: callback function
26 * @data: context data pointer
27 *
28 * This function is used to scan the flattened device-tree, it is
29 * used to extract the memory information at boot before we can
30 * unflatten the tree
31 */
32int __init of_scan_flat_dt(int (*it)(unsigned long node,
33 const char *uname, int depth,
34 void *data),
35 void *data)
36{
37 unsigned long p = ((unsigned long)initial_boot_params) +
38 initial_boot_params->off_dt_struct;
39 int rc = 0;
40 int depth = -1;
41
42 do {
43 u32 tag = *((u32 *)p);
44 char *pathp;
45
46 p += 4;
47 if (tag == OF_DT_END_NODE) {
48 depth--;
49 continue;
50 }
51 if (tag == OF_DT_NOP)
52 continue;
53 if (tag == OF_DT_END)
54 break;
55 if (tag == OF_DT_PROP) {
56 u32 sz = *((u32 *)p);
57 p += 8;
58 if (initial_boot_params->version < 0x10)
59 p = _ALIGN(p, sz >= 8 ? 8 : 4);
60 p += sz;
61 p = _ALIGN(p, 4);
62 continue;
63 }
64 if (tag != OF_DT_BEGIN_NODE) {
65 pr_err("Invalid tag %x in flat device tree!\n", tag);
66 return -EINVAL;
67 }
68 depth++;
69 pathp = (char *)p;
70 p = _ALIGN(p + strlen(pathp) + 1, 4);
71 if ((*pathp) == '/') {
72 char *lp, *np;
73 for (lp = NULL, np = pathp; *np; np++)
74 if ((*np) == '/')
75 lp = np+1;
76 if (lp != NULL)
77 pathp = lp;
78 }
79 rc = it(p, pathp, depth, data);
80 if (rc != 0)
81 break;
82 } while (1);
83
84 return rc;
85}