aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2009-11-23 20:54:23 -0500
committerGrant Likely <grant.likely@secretlab.ca>2009-11-23 20:54:23 -0500
commitc8cb7a59842c0b512b44f6f818cdb0b5a3ddc89e (patch)
tree74d7b5c8dac3d5167b0394b5967bad52681dc28e
parente169cfbef46d62e042614ffafa8880eed1d894bb (diff)
of/flattree: merge of_scan_flat_dt
Merge common code between PowerPC and Microblaze Signed-off-by: Grant Likely <grant.likely@secretlab.ca> Reviewed-by: Wolfram Sang <w.sang@pengutronix.de> Tested-by: Michal Simek <monstr@monstr.eu>
-rw-r--r--arch/microblaze/kernel/prom.c61
-rw-r--r--arch/powerpc/kernel/prom.c61
-rw-r--r--drivers/of/fdt.c64
3 files changed, 64 insertions, 122 deletions
diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
index 06d620ab4168..0db8ee64ffe6 100644
--- a/arch/microblaze/kernel/prom.c
+++ b/arch/microblaze/kernel/prom.c
@@ -50,67 +50,6 @@ typedef u32 cell_t;
50/* export that to outside world */ 50/* export that to outside world */
51struct device_node *of_chosen; 51struct device_node *of_chosen;
52 52
53/**
54 * This function is used to scan the flattened device-tree, it is
55 * used to extract the memory informations at boot before we can
56 * unflatten the tree
57 */
58int __init of_scan_flat_dt(int (*it)(unsigned long node,
59 const char *uname, int depth,
60 void *data),
61 void *data)
62{
63 unsigned long p = ((unsigned long)initial_boot_params) +
64 initial_boot_params->off_dt_struct;
65 int rc = 0;
66 int depth = -1;
67
68 do {
69 u32 tag = *((u32 *)p);
70 char *pathp;
71
72 p += 4;
73 if (tag == OF_DT_END_NODE) {
74 depth--;
75 continue;
76 }
77 if (tag == OF_DT_NOP)
78 continue;
79 if (tag == OF_DT_END)
80 break;
81 if (tag == OF_DT_PROP) {
82 u32 sz = *((u32 *)p);
83 p += 8;
84 if (initial_boot_params->version < 0x10)
85 p = _ALIGN(p, sz >= 8 ? 8 : 4);
86 p += sz;
87 p = _ALIGN(p, 4);
88 continue;
89 }
90 if (tag != OF_DT_BEGIN_NODE) {
91 printk(KERN_WARNING "Invalid tag %x scanning flattened"
92 " device tree !\n", tag);
93 return -EINVAL;
94 }
95 depth++;
96 pathp = (char *)p;
97 p = _ALIGN(p + strlen(pathp) + 1, 4);
98 if ((*pathp) == '/') {
99 char *lp, *np;
100 for (lp = NULL, np = pathp; *np; np++)
101 if ((*np) == '/')
102 lp = np+1;
103 if (lp != NULL)
104 pathp = lp;
105 }
106 rc = it(p, pathp, depth, data);
107 if (rc != 0)
108 break;
109 } while (1);
110
111 return rc;
112}
113
114unsigned long __init of_get_flat_dt_root(void) 53unsigned long __init of_get_flat_dt_root(void)
115{ 54{
116 unsigned long p = ((unsigned long)initial_boot_params) + 55 unsigned long p = ((unsigned long)initial_boot_params) +
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index fccf7e49bb28..14a07b9e00d1 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -80,67 +80,6 @@ extern rwlock_t devtree_lock; /* temporary while merging */
80/* export that to outside world */ 80/* export that to outside world */
81struct device_node *of_chosen; 81struct device_node *of_chosen;
82 82
83/**
84 * This function is used to scan the flattened device-tree, it is
85 * used to extract the memory informations at boot before we can
86 * unflatten the tree
87 */
88int __init of_scan_flat_dt(int (*it)(unsigned long node,
89 const char *uname, int depth,
90 void *data),
91 void *data)
92{
93 unsigned long p = ((unsigned long)initial_boot_params) +
94 initial_boot_params->off_dt_struct;
95 int rc = 0;
96 int depth = -1;
97
98 do {
99 u32 tag = *((u32 *)p);
100 char *pathp;
101
102 p += 4;
103 if (tag == OF_DT_END_NODE) {
104 depth --;
105 continue;
106 }
107 if (tag == OF_DT_NOP)
108 continue;
109 if (tag == OF_DT_END)
110 break;
111 if (tag == OF_DT_PROP) {
112 u32 sz = *((u32 *)p);
113 p += 8;
114 if (initial_boot_params->version < 0x10)
115 p = _ALIGN(p, sz >= 8 ? 8 : 4);
116 p += sz;
117 p = _ALIGN(p, 4);
118 continue;
119 }
120 if (tag != OF_DT_BEGIN_NODE) {
121 printk(KERN_WARNING "Invalid tag %x scanning flattened"
122 " device tree !\n", tag);
123 return -EINVAL;
124 }
125 depth++;
126 pathp = (char *)p;
127 p = _ALIGN(p + strlen(pathp) + 1, 4);
128 if ((*pathp) == '/') {
129 char *lp, *np;
130 for (lp = NULL, np = pathp; *np; np++)
131 if ((*np) == '/')
132 lp = np+1;
133 if (lp != NULL)
134 pathp = lp;
135 }
136 rc = it(p, pathp, depth, data);
137 if (rc != 0)
138 break;
139 } while(1);
140
141 return rc;
142}
143
144unsigned long __init of_get_flat_dt_root(void) 83unsigned long __init of_get_flat_dt_root(void)
145{ 84{
146 unsigned long p = ((unsigned long)initial_boot_params) + 85 unsigned long p = ((unsigned long)initial_boot_params) +
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}