aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of/fdt.c
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@linaro.org>2013-08-29 08:30:35 -0400
committerGrant Likely <grant.likely@linaro.org>2013-08-30 06:34:34 -0400
commit4485681939b99d80893e2016ebb9d44e1c414561 (patch)
treeea98248fc30bc75fdf146990828587b369e59342 /drivers/of/fdt.c
parent92d31610aac907c046f0e9c0f888c30415f20936 (diff)
of/fdt: Clean up casting in unflattening path
The flat tree unflatting path is using unsigned longs to carry around virtual address pointers to the device tree and the allocated memory used to unpack it. This is a little insane since every access to them needs to be cast to a pointer type before using it. This patch changes the data type to void* for the 'start' and 'mem' pointers and reworks the unflattening functions to use those values directly which results in slightly simpler code. Signed-off-by: Grant Likely <grant.likely@linaro.org>
Diffstat (limited to 'drivers/of/fdt.c')
-rw-r--r--drivers/of/fdt.c63
1 files changed, 30 insertions, 33 deletions
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 8263d2da3252..4c5ee96bf487 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -126,13 +126,13 @@ int of_fdt_match(struct boot_param_header *blob, unsigned long node,
126 return score; 126 return score;
127} 127}
128 128
129static void *unflatten_dt_alloc(unsigned long *mem, unsigned long size, 129static void *unflatten_dt_alloc(void **mem, unsigned long size,
130 unsigned long align) 130 unsigned long align)
131{ 131{
132 void *res; 132 void *res;
133 133
134 *mem = ALIGN(*mem, align); 134 *mem = PTR_ALIGN(*mem, align);
135 res = (void *)*mem; 135 res = *mem;
136 *mem += size; 136 *mem += size;
137 137
138 return res; 138 return res;
@@ -147,9 +147,9 @@ static void *unflatten_dt_alloc(unsigned long *mem, unsigned long size,
147 * @allnextpp: pointer to ->allnext from last allocated device_node 147 * @allnextpp: pointer to ->allnext from last allocated device_node
148 * @fpsize: Size of the node path up at the current depth. 148 * @fpsize: Size of the node path up at the current depth.
149 */ 149 */
150static unsigned long unflatten_dt_node(struct boot_param_header *blob, 150static void * unflatten_dt_node(struct boot_param_header *blob,
151 unsigned long mem, 151 void *mem,
152 unsigned long *p, 152 void **p,
153 struct device_node *dad, 153 struct device_node *dad,
154 struct device_node ***allnextpp, 154 struct device_node ***allnextpp,
155 unsigned long fpsize) 155 unsigned long fpsize)
@@ -162,15 +162,15 @@ static unsigned long unflatten_dt_node(struct boot_param_header *blob,
162 int has_name = 0; 162 int has_name = 0;
163 int new_format = 0; 163 int new_format = 0;
164 164
165 tag = be32_to_cpup((__be32 *)(*p)); 165 tag = be32_to_cpup(*p);
166 if (tag != OF_DT_BEGIN_NODE) { 166 if (tag != OF_DT_BEGIN_NODE) {
167 pr_err("Weird tag at start of node: %x\n", tag); 167 pr_err("Weird tag at start of node: %x\n", tag);
168 return mem; 168 return mem;
169 } 169 }
170 *p += 4; 170 *p += 4;
171 pathp = (char *)*p; 171 pathp = *p;
172 l = allocl = strlen(pathp) + 1; 172 l = allocl = strlen(pathp) + 1;
173 *p = ALIGN(*p + l, 4); 173 *p = PTR_ALIGN(*p + l, 4);
174 174
175 /* version 0x10 has a more compact unit name here instead of the full 175 /* version 0x10 has a more compact unit name here instead of the full
176 * path. we accumulate the full path size using "fpsize", we'll rebuild 176 * path. we accumulate the full path size using "fpsize", we'll rebuild
@@ -239,7 +239,7 @@ static unsigned long unflatten_dt_node(struct boot_param_header *blob,
239 u32 sz, noff; 239 u32 sz, noff;
240 char *pname; 240 char *pname;
241 241
242 tag = be32_to_cpup((__be32 *)(*p)); 242 tag = be32_to_cpup(*p);
243 if (tag == OF_DT_NOP) { 243 if (tag == OF_DT_NOP) {
244 *p += 4; 244 *p += 4;
245 continue; 245 continue;
@@ -247,11 +247,11 @@ static unsigned long unflatten_dt_node(struct boot_param_header *blob,
247 if (tag != OF_DT_PROP) 247 if (tag != OF_DT_PROP)
248 break; 248 break;
249 *p += 4; 249 *p += 4;
250 sz = be32_to_cpup((__be32 *)(*p)); 250 sz = be32_to_cpup(*p);
251 noff = be32_to_cpup((__be32 *)((*p) + 4)); 251 noff = be32_to_cpup(*p + 4);
252 *p += 8; 252 *p += 8;
253 if (be32_to_cpu(blob->version) < 0x10) 253 if (be32_to_cpu(blob->version) < 0x10)
254 *p = ALIGN(*p, sz >= 8 ? 8 : 4); 254 *p = PTR_ALIGN(*p, sz >= 8 ? 8 : 4);
255 255
256 pname = of_fdt_get_string(blob, noff); 256 pname = of_fdt_get_string(blob, noff);
257 if (pname == NULL) { 257 if (pname == NULL) {
@@ -281,11 +281,11 @@ static unsigned long unflatten_dt_node(struct boot_param_header *blob,
281 np->phandle = be32_to_cpup((__be32 *)*p); 281 np->phandle = be32_to_cpup((__be32 *)*p);
282 pp->name = pname; 282 pp->name = pname;
283 pp->length = sz; 283 pp->length = sz;
284 pp->value = (void *)*p; 284 pp->value = *p;
285 *prev_pp = pp; 285 *prev_pp = pp;
286 prev_pp = &pp->next; 286 prev_pp = &pp->next;
287 } 287 }
288 *p = ALIGN((*p) + sz, 4); 288 *p = PTR_ALIGN((*p) + sz, 4);
289 } 289 }
290 /* with version 0x10 we may not have the name property, recreate 290 /* with version 0x10 we may not have the name property, recreate
291 * it here from the unit name if absent 291 * it here from the unit name if absent
@@ -334,7 +334,7 @@ static unsigned long unflatten_dt_node(struct boot_param_header *blob,
334 else 334 else
335 mem = unflatten_dt_node(blob, mem, p, np, allnextpp, 335 mem = unflatten_dt_node(blob, mem, p, np, allnextpp,
336 fpsize); 336 fpsize);
337 tag = be32_to_cpup((__be32 *)(*p)); 337 tag = be32_to_cpup(*p);
338 } 338 }
339 if (tag != OF_DT_END_NODE) { 339 if (tag != OF_DT_END_NODE) {
340 pr_err("Weird tag at end of node: %x\n", tag); 340 pr_err("Weird tag at end of node: %x\n", tag);
@@ -360,7 +360,8 @@ static void __unflatten_device_tree(struct boot_param_header *blob,
360 struct device_node **mynodes, 360 struct device_node **mynodes,
361 void * (*dt_alloc)(u64 size, u64 align)) 361 void * (*dt_alloc)(u64 size, u64 align))
362{ 362{
363 unsigned long start, mem, size; 363 unsigned long size;
364 void *start, *mem;
364 struct device_node **allnextp = mynodes; 365 struct device_node **allnextp = mynodes;
365 366
366 pr_debug(" -> unflatten_device_tree()\n"); 367 pr_debug(" -> unflatten_device_tree()\n");
@@ -381,32 +382,28 @@ static void __unflatten_device_tree(struct boot_param_header *blob,
381 } 382 }
382 383
383 /* First pass, scan for size */ 384 /* First pass, scan for size */
384 start = ((unsigned long)blob) + 385 start = ((void *)blob) + be32_to_cpu(blob->off_dt_struct);
385 be32_to_cpu(blob->off_dt_struct); 386 size = (unsigned long)unflatten_dt_node(blob, 0, &start, NULL, NULL, 0);
386 size = unflatten_dt_node(blob, 0, &start, NULL, NULL, 0); 387 size = ALIGN(size, 4);
387 size = (size | 3) + 1;
388 388
389 pr_debug(" size is %lx, allocating...\n", size); 389 pr_debug(" size is %lx, allocating...\n", size);
390 390
391 /* Allocate memory for the expanded device tree */ 391 /* Allocate memory for the expanded device tree */
392 mem = (unsigned long) 392 mem = dt_alloc(size + 4, __alignof__(struct device_node));
393 dt_alloc(size + 4, __alignof__(struct device_node)); 393 memset(mem, 0, size);
394 394
395 memset((void *)mem, 0, size); 395 *(__be32 *)(mem + size) = cpu_to_be32(0xdeadbeef);
396 396
397 ((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef); 397 pr_debug(" unflattening %p...\n", mem);
398
399 pr_debug(" unflattening %lx...\n", mem);
400 398
401 /* Second pass, do actual unflattening */ 399 /* Second pass, do actual unflattening */
402 start = ((unsigned long)blob) + 400 start = ((void *)blob) + be32_to_cpu(blob->off_dt_struct);
403 be32_to_cpu(blob->off_dt_struct);
404 unflatten_dt_node(blob, mem, &start, NULL, &allnextp, 0); 401 unflatten_dt_node(blob, mem, &start, NULL, &allnextp, 0);
405 if (be32_to_cpup((__be32 *)start) != OF_DT_END) 402 if (be32_to_cpup(start) != OF_DT_END)
406 pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start)); 403 pr_warning("Weird tag at end of tree: %08x\n", be32_to_cpup(start));
407 if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef) 404 if (be32_to_cpup(mem + size) != 0xdeadbeef)
408 pr_warning("End of tree marker overwritten: %08x\n", 405 pr_warning("End of tree marker overwritten: %08x\n",
409 be32_to_cpu(((__be32 *)mem)[size / 4])); 406 be32_to_cpup(mem + size));
410 *allnextp = NULL; 407 *allnextp = NULL;
411 408
412 pr_debug(" <- unflatten_device_tree()\n"); 409 pr_debug(" <- unflatten_device_tree()\n");