of/flattree: merge find_flat_dt_string and initial_boot_params
[firefly-linux-kernel-4.4.55.git] / arch / microblaze / kernel / prom.c
1 /*
2  * Procedures for creating, accessing and interpreting the device tree.
3  *
4  * Paul Mackerras       August 1996.
5  * Copyright (C) 1996-2005 Paul Mackerras.
6  *
7  *  Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
8  *    {engebret|bergner}@us.ibm.com
9  *
10  *      This program is free software; you can redistribute it and/or
11  *      modify it under the terms of the GNU General Public License
12  *      as published by the Free Software Foundation; either version
13  *      2 of the License, or (at your option) any later version.
14  */
15
16 #include <stdarg.h>
17 #include <linux/kernel.h>
18 #include <linux/string.h>
19 #include <linux/init.h>
20 #include <linux/threads.h>
21 #include <linux/spinlock.h>
22 #include <linux/types.h>
23 #include <linux/pci.h>
24 #include <linux/stringify.h>
25 #include <linux/delay.h>
26 #include <linux/initrd.h>
27 #include <linux/bitops.h>
28 #include <linux/module.h>
29 #include <linux/kexec.h>
30 #include <linux/debugfs.h>
31 #include <linux/irq.h>
32 #include <linux/lmb.h>
33
34 #include <asm/prom.h>
35 #include <asm/page.h>
36 #include <asm/processor.h>
37 #include <asm/irq.h>
38 #include <linux/io.h>
39 #include <asm/system.h>
40 #include <asm/mmu.h>
41 #include <asm/pgtable.h>
42 #include <asm/sections.h>
43 #include <asm/pci-bridge.h>
44
45 static int __initdata dt_root_addr_cells;
46 static int __initdata dt_root_size_cells;
47
48 typedef u32 cell_t;
49
50 /* export that to outside world */
51 struct device_node *of_chosen;
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  */
58 int __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
114 unsigned long __init of_get_flat_dt_root(void)
115 {
116         unsigned long p = ((unsigned long)initial_boot_params) +
117                 initial_boot_params->off_dt_struct;
118
119         while (*((u32 *)p) == OF_DT_NOP)
120                 p += 4;
121         BUG_ON(*((u32 *)p) != OF_DT_BEGIN_NODE);
122         p += 4;
123         return _ALIGN(p + strlen((char *)p) + 1, 4);
124 }
125
126 /**
127  * This function can be used within scan_flattened_dt callback to get
128  * access to properties
129  */
130 void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
131                                 unsigned long *size)
132 {
133         unsigned long p = node;
134
135         do {
136                 u32 tag = *((u32 *)p);
137                 u32 sz, noff;
138                 const char *nstr;
139
140                 p += 4;
141                 if (tag == OF_DT_NOP)
142                         continue;
143                 if (tag != OF_DT_PROP)
144                         return NULL;
145
146                 sz = *((u32 *)p);
147                 noff = *((u32 *)(p + 4));
148                 p += 8;
149                 if (initial_boot_params->version < 0x10)
150                         p = _ALIGN(p, sz >= 8 ? 8 : 4);
151
152                 nstr = find_flat_dt_string(noff);
153                 if (nstr == NULL) {
154                         printk(KERN_WARNING "Can't find property index"
155                                 " name !\n");
156                         return NULL;
157                 }
158                 if (strcmp(name, nstr) == 0) {
159                         if (size)
160                                 *size = sz;
161                         return (void *)p;
162                 }
163                 p += sz;
164                 p = _ALIGN(p, 4);
165         } while (1);
166 }
167
168 int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
169 {
170         const char *cp;
171         unsigned long cplen, l;
172
173         cp = of_get_flat_dt_prop(node, "compatible", &cplen);
174         if (cp == NULL)
175                 return 0;
176         while (cplen > 0) {
177                 if (strncasecmp(cp, compat, strlen(compat)) == 0)
178                         return 1;
179                 l = strlen(cp) + 1;
180                 cp += l;
181                 cplen -= l;
182         }
183
184         return 0;
185 }
186
187 static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
188                                         unsigned long align)
189 {
190         void *res;
191
192         *mem = _ALIGN(*mem, align);
193         res = (void *)*mem;
194         *mem += size;
195
196         return res;
197 }
198
199 static unsigned long __init unflatten_dt_node(unsigned long mem,
200                                         unsigned long *p,
201                                         struct device_node *dad,
202                                         struct device_node ***allnextpp,
203                                         unsigned long fpsize)
204 {
205         struct device_node *np;
206         struct property *pp, **prev_pp = NULL;
207         char *pathp;
208         u32 tag;
209         unsigned int l, allocl;
210         int has_name = 0;
211         int new_format = 0;
212
213         tag = *((u32 *)(*p));
214         if (tag != OF_DT_BEGIN_NODE) {
215                 printk("Weird tag at start of node: %x\n", tag);
216                 return mem;
217         }
218         *p += 4;
219         pathp = (char *)*p;
220         l = allocl = strlen(pathp) + 1;
221         *p = _ALIGN(*p + l, 4);
222
223         /* version 0x10 has a more compact unit name here instead of the full
224          * path. we accumulate the full path size using "fpsize", we'll rebuild
225          * it later. We detect this because the first character of the name is
226          * not '/'.
227          */
228         if ((*pathp) != '/') {
229                 new_format = 1;
230                 if (fpsize == 0) {
231                         /* root node: special case. fpsize accounts for path
232                          * plus terminating zero. root node only has '/', so
233                          * fpsize should be 2, but we want to avoid the first
234                          * level nodes to have two '/' so we use fpsize 1 here
235                          */
236                         fpsize = 1;
237                         allocl = 2;
238                 } else {
239                         /* account for '/' and path size minus terminal 0
240                          * already in 'l'
241                          */
242                         fpsize += l;
243                         allocl = fpsize;
244                 }
245         }
246
247         np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl,
248                                 __alignof__(struct device_node));
249         if (allnextpp) {
250                 memset(np, 0, sizeof(*np));
251                 np->full_name = ((char *)np) + sizeof(struct device_node);
252                 if (new_format) {
253                         char *p2 = np->full_name;
254                         /* rebuild full path for new format */
255                         if (dad && dad->parent) {
256                                 strcpy(p2, dad->full_name);
257 #ifdef DEBUG
258                                 if ((strlen(p2) + l + 1) != allocl) {
259                                         pr_debug("%s: p: %d, l: %d, a: %d\n",
260                                                 pathp, (int)strlen(p2),
261                                                 l, allocl);
262                                 }
263 #endif
264                                 p2 += strlen(p2);
265                         }
266                         *(p2++) = '/';
267                         memcpy(p2, pathp, l);
268                 } else
269                         memcpy(np->full_name, pathp, l);
270                 prev_pp = &np->properties;
271                 **allnextpp = np;
272                 *allnextpp = &np->allnext;
273                 if (dad != NULL) {
274                         np->parent = dad;
275                         /* we temporarily use the next field as `last_child'*/
276                         if (dad->next == NULL)
277                                 dad->child = np;
278                         else
279                                 dad->next->sibling = np;
280                         dad->next = np;
281                 }
282                 kref_init(&np->kref);
283         }
284         while (1) {
285                 u32 sz, noff;
286                 char *pname;
287
288                 tag = *((u32 *)(*p));
289                 if (tag == OF_DT_NOP) {
290                         *p += 4;
291                         continue;
292                 }
293                 if (tag != OF_DT_PROP)
294                         break;
295                 *p += 4;
296                 sz = *((u32 *)(*p));
297                 noff = *((u32 *)((*p) + 4));
298                 *p += 8;
299                 if (initial_boot_params->version < 0x10)
300                         *p = _ALIGN(*p, sz >= 8 ? 8 : 4);
301
302                 pname = find_flat_dt_string(noff);
303                 if (pname == NULL) {
304                         printk(KERN_INFO
305                                 "Can't find property name in list !\n");
306                         break;
307                 }
308                 if (strcmp(pname, "name") == 0)
309                         has_name = 1;
310                 l = strlen(pname) + 1;
311                 pp = unflatten_dt_alloc(&mem, sizeof(struct property),
312                                         __alignof__(struct property));
313                 if (allnextpp) {
314                         if (strcmp(pname, "linux,phandle") == 0) {
315                                 np->node = *((u32 *)*p);
316                                 if (np->linux_phandle == 0)
317                                         np->linux_phandle = np->node;
318                         }
319                         if (strcmp(pname, "ibm,phandle") == 0)
320                                 np->linux_phandle = *((u32 *)*p);
321                         pp->name = pname;
322                         pp->length = sz;
323                         pp->value = (void *)*p;
324                         *prev_pp = pp;
325                         prev_pp = &pp->next;
326                 }
327                 *p = _ALIGN((*p) + sz, 4);
328         }
329         /* with version 0x10 we may not have the name property, recreate
330          * it here from the unit name if absent
331          */
332         if (!has_name) {
333                 char *p1 = pathp, *ps = pathp, *pa = NULL;
334                 int sz;
335
336                 while (*p1) {
337                         if ((*p1) == '@')
338                                 pa = p1;
339                         if ((*p1) == '/')
340                                 ps = p1 + 1;
341                         p1++;
342                 }
343                 if (pa < ps)
344                         pa = p1;
345                 sz = (pa - ps) + 1;
346                 pp = unflatten_dt_alloc(&mem, sizeof(struct property) + sz,
347                                         __alignof__(struct property));
348                 if (allnextpp) {
349                         pp->name = "name";
350                         pp->length = sz;
351                         pp->value = pp + 1;
352                         *prev_pp = pp;
353                         prev_pp = &pp->next;
354                         memcpy(pp->value, ps, sz - 1);
355                         ((char *)pp->value)[sz - 1] = 0;
356                         pr_debug("fixed up name for %s -> %s\n", pathp,
357                                 (char *)pp->value);
358                 }
359         }
360         if (allnextpp) {
361                 *prev_pp = NULL;
362                 np->name = of_get_property(np, "name", NULL);
363                 np->type = of_get_property(np, "device_type", NULL);
364
365                 if (!np->name)
366                         np->name = "<NULL>";
367                 if (!np->type)
368                         np->type = "<NULL>";
369         }
370         while (tag == OF_DT_BEGIN_NODE) {
371                 mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
372                 tag = *((u32 *)(*p));
373         }
374         if (tag != OF_DT_END_NODE) {
375                 printk(KERN_INFO "Weird tag at end of node: %x\n", tag);
376                 return mem;
377         }
378         *p += 4;
379         return mem;
380 }
381
382 /**
383  * unflattens the device-tree passed by the firmware, creating the
384  * tree of struct device_node. It also fills the "name" and "type"
385  * pointers of the nodes so the normal device-tree walking functions
386  * can be used (this used to be done by finish_device_tree)
387  */
388 void __init unflatten_device_tree(void)
389 {
390         unsigned long start, mem, size;
391         struct device_node **allnextp = &allnodes;
392
393         pr_debug(" -> unflatten_device_tree()\n");
394
395         /* First pass, scan for size */
396         start = ((unsigned long)initial_boot_params) +
397                 initial_boot_params->off_dt_struct;
398         size = unflatten_dt_node(0, &start, NULL, NULL, 0);
399         size = (size | 3) + 1;
400
401         pr_debug("  size is %lx, allocating...\n", size);
402
403         /* Allocate memory for the expanded device tree */
404         mem = lmb_alloc(size + 4, __alignof__(struct device_node));
405         mem = (unsigned long) __va(mem);
406
407         ((u32 *)mem)[size / 4] = 0xdeadbeef;
408
409         pr_debug("  unflattening %lx...\n", mem);
410
411         /* Second pass, do actual unflattening */
412         start = ((unsigned long)initial_boot_params) +
413                 initial_boot_params->off_dt_struct;
414         unflatten_dt_node(mem, &start, NULL, &allnextp, 0);
415         if (*((u32 *)start) != OF_DT_END)
416                 printk(KERN_WARNING "Weird tag at end of tree: %08x\n",
417                         *((u32 *)start));
418         if (((u32 *)mem)[size / 4] != 0xdeadbeef)
419                 printk(KERN_WARNING "End of tree marker overwritten: %08x\n",
420                         ((u32 *)mem)[size / 4]);
421         *allnextp = NULL;
422
423         /* Get pointer to OF "/chosen" node for use everywhere */
424         of_chosen = of_find_node_by_path("/chosen");
425         if (of_chosen == NULL)
426                 of_chosen = of_find_node_by_path("/chosen@0");
427
428         pr_debug(" <- unflatten_device_tree()\n");
429 }
430
431 #define early_init_dt_scan_drconf_memory(node) 0
432
433 static int __init early_init_dt_scan_cpus(unsigned long node,
434                                           const char *uname, int depth,
435                                           void *data)
436 {
437         static int logical_cpuid;
438         char *type = of_get_flat_dt_prop(node, "device_type", NULL);
439         const u32 *intserv;
440         int i, nthreads;
441         int found = 0;
442
443         /* We are scanning "cpu" nodes only */
444         if (type == NULL || strcmp(type, "cpu") != 0)
445                 return 0;
446
447         /* Get physical cpuid */
448         intserv = of_get_flat_dt_prop(node, "reg", NULL);
449         nthreads = 1;
450
451         /*
452          * Now see if any of these threads match our boot cpu.
453          * NOTE: This must match the parsing done in smp_setup_cpu_maps.
454          */
455         for (i = 0; i < nthreads; i++) {
456                 /*
457                  * version 2 of the kexec param format adds the phys cpuid of
458                  * booted proc.
459                  */
460                 if (initial_boot_params && initial_boot_params->version >= 2) {
461                         if (intserv[i] ==
462                                         initial_boot_params->boot_cpuid_phys) {
463                                 found = 1;
464                                 break;
465                         }
466                 } else {
467                         /*
468                          * Check if it's the boot-cpu, set it's hw index now,
469                          * unfortunately this format did not support booting
470                          * off secondary threads.
471                          */
472                         if (of_get_flat_dt_prop(node,
473                                         "linux,boot-cpu", NULL) != NULL) {
474                                 found = 1;
475                                 break;
476                         }
477                 }
478
479 #ifdef CONFIG_SMP
480                 /* logical cpu id is always 0 on UP kernels */
481                 logical_cpuid++;
482 #endif
483         }
484
485         if (found) {
486                 pr_debug("boot cpu: logical %d physical %d\n", logical_cpuid,
487                         intserv[i]);
488                 boot_cpuid = logical_cpuid;
489         }
490
491         return 0;
492 }
493
494 #ifdef CONFIG_BLK_DEV_INITRD
495 static void __init early_init_dt_check_for_initrd(unsigned long node)
496 {
497         unsigned long l;
498         u32 *prop;
499
500         pr_debug("Looking for initrd properties... ");
501
502         prop = of_get_flat_dt_prop(node, "linux,initrd-start", &l);
503         if (prop) {
504                 initrd_start = (unsigned long)
505                                         __va((u32)of_read_ulong(prop, l/4));
506
507                 prop = of_get_flat_dt_prop(node, "linux,initrd-end", &l);
508                 if (prop) {
509                         initrd_end = (unsigned long)
510                                         __va((u32)of_read_ulong(prop, 1/4));
511                         initrd_below_start_ok = 1;
512                 } else {
513                         initrd_start = 0;
514                 }
515         }
516
517         pr_debug("initrd_start=0x%lx  initrd_end=0x%lx\n",
518                                         initrd_start, initrd_end);
519 }
520 #else
521 static inline void early_init_dt_check_for_initrd(unsigned long node)
522 {
523 }
524 #endif /* CONFIG_BLK_DEV_INITRD */
525
526 static int __init early_init_dt_scan_chosen(unsigned long node,
527                                 const char *uname, int depth, void *data)
528 {
529         unsigned long l;
530         char *p;
531
532         pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
533
534         if (depth != 1 ||
535                 (strcmp(uname, "chosen") != 0 &&
536                                 strcmp(uname, "chosen@0") != 0))
537                 return 0;
538
539 #ifdef CONFIG_KEXEC
540         lprop = (u64 *)of_get_flat_dt_prop(node,
541                                 "linux,crashkernel-base", NULL);
542         if (lprop)
543                 crashk_res.start = *lprop;
544
545         lprop = (u64 *)of_get_flat_dt_prop(node,
546                                 "linux,crashkernel-size", NULL);
547         if (lprop)
548                 crashk_res.end = crashk_res.start + *lprop - 1;
549 #endif
550
551         early_init_dt_check_for_initrd(node);
552
553         /* Retreive command line */
554         p = of_get_flat_dt_prop(node, "bootargs", &l);
555         if (p != NULL && l > 0)
556                 strlcpy(cmd_line, p, min((int)l, COMMAND_LINE_SIZE));
557
558 #ifdef CONFIG_CMDLINE
559 #ifndef CONFIG_CMDLINE_FORCE
560         if (p == NULL || l == 0 || (l == 1 && (*p) == 0))
561 #endif
562                 strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
563 #endif /* CONFIG_CMDLINE */
564
565         pr_debug("Command line is: %s\n", cmd_line);
566
567         /* break now */
568         return 1;
569 }
570
571 static int __init early_init_dt_scan_root(unsigned long node,
572                                 const char *uname, int depth, void *data)
573 {
574         u32 *prop;
575
576         if (depth != 0)
577                 return 0;
578
579         prop = of_get_flat_dt_prop(node, "#size-cells", NULL);
580         dt_root_size_cells = (prop == NULL) ? 1 : *prop;
581         pr_debug("dt_root_size_cells = %x\n", dt_root_size_cells);
582
583         prop = of_get_flat_dt_prop(node, "#address-cells", NULL);
584         dt_root_addr_cells = (prop == NULL) ? 2 : *prop;
585         pr_debug("dt_root_addr_cells = %x\n", dt_root_addr_cells);
586
587         /* break now */
588         return 1;
589 }
590
591 static u64 __init dt_mem_next_cell(int s, cell_t **cellp)
592 {
593         cell_t *p = *cellp;
594
595         *cellp = p + s;
596         return of_read_number(p, s);
597 }
598
599 static int __init early_init_dt_scan_memory(unsigned long node,
600                                 const char *uname, int depth, void *data)
601 {
602         char *type = of_get_flat_dt_prop(node, "device_type", NULL);
603         cell_t *reg, *endp;
604         unsigned long l;
605
606         /* Look for the ibm,dynamic-reconfiguration-memory node */
607 /*      if (depth == 1 &&
608                 strcmp(uname, "ibm,dynamic-reconfiguration-memory") == 0)
609                 return early_init_dt_scan_drconf_memory(node);
610 */
611         /* We are scanning "memory" nodes only */
612         if (type == NULL) {
613                 /*
614                  * The longtrail doesn't have a device_type on the
615                  * /memory node, so look for the node called /memory@0.
616                  */
617                 if (depth != 1 || strcmp(uname, "memory@0") != 0)
618                         return 0;
619         } else if (strcmp(type, "memory") != 0)
620                 return 0;
621
622         reg = (cell_t *)of_get_flat_dt_prop(node, "linux,usable-memory", &l);
623         if (reg == NULL)
624                 reg = (cell_t *)of_get_flat_dt_prop(node, "reg", &l);
625         if (reg == NULL)
626                 return 0;
627
628         endp = reg + (l / sizeof(cell_t));
629
630         pr_debug("memory scan node %s, reg size %ld, data: %x %x %x %x,\n",
631                 uname, l, reg[0], reg[1], reg[2], reg[3]);
632
633         while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
634                 u64 base, size;
635
636                 base = dt_mem_next_cell(dt_root_addr_cells, &reg);
637                 size = dt_mem_next_cell(dt_root_size_cells, &reg);
638
639                 if (size == 0)
640                         continue;
641                 pr_debug(" - %llx ,  %llx\n", (unsigned long long)base,
642                         (unsigned long long)size);
643
644                 lmb_add(base, size);
645         }
646         return 0;
647 }
648
649 #ifdef CONFIG_PHYP_DUMP
650 /**
651  * phyp_dump_calculate_reserve_size() - reserve variable boot area 5% or arg
652  *
653  * Function to find the largest size we need to reserve
654  * during early boot process.
655  *
656  * It either looks for boot param and returns that OR
657  * returns larger of 256 or 5% rounded down to multiples of 256MB.
658  *
659  */
660 static inline unsigned long phyp_dump_calculate_reserve_size(void)
661 {
662         unsigned long tmp;
663
664         if (phyp_dump_info->reserve_bootvar)
665                 return phyp_dump_info->reserve_bootvar;
666
667         /* divide by 20 to get 5% of value */
668         tmp = lmb_end_of_DRAM();
669         do_div(tmp, 20);
670
671         /* round it down in multiples of 256 */
672         tmp = tmp & ~0x0FFFFFFFUL;
673
674         return (tmp > PHYP_DUMP_RMR_END ? tmp : PHYP_DUMP_RMR_END);
675 }
676
677 /**
678  * phyp_dump_reserve_mem() - reserve all not-yet-dumped mmemory
679  *
680  * This routine may reserve memory regions in the kernel only
681  * if the system is supported and a dump was taken in last
682  * boot instance or if the hardware is supported and the
683  * scratch area needs to be setup. In other instances it returns
684  * without reserving anything. The memory in case of dump being
685  * active is freed when the dump is collected (by userland tools).
686  */
687 static void __init phyp_dump_reserve_mem(void)
688 {
689         unsigned long base, size;
690         unsigned long variable_reserve_size;
691
692         if (!phyp_dump_info->phyp_dump_configured) {
693                 printk(KERN_ERR "Phyp-dump not supported on this hardware\n");
694                 return;
695         }
696
697         if (!phyp_dump_info->phyp_dump_at_boot) {
698                 printk(KERN_INFO "Phyp-dump disabled at boot time\n");
699                 return;
700         }
701
702         variable_reserve_size = phyp_dump_calculate_reserve_size();
703
704         if (phyp_dump_info->phyp_dump_is_active) {
705                 /* Reserve *everything* above RMR.Area freed by userland tools*/
706                 base = variable_reserve_size;
707                 size = lmb_end_of_DRAM() - base;
708
709                 /* XXX crashed_ram_end is wrong, since it may be beyond
710                  * the memory_limit, it will need to be adjusted. */
711                 lmb_reserve(base, size);
712
713                 phyp_dump_info->init_reserve_start = base;
714                 phyp_dump_info->init_reserve_size = size;
715         } else {
716                 size = phyp_dump_info->cpu_state_size +
717                         phyp_dump_info->hpte_region_size +
718                         variable_reserve_size;
719                 base = lmb_end_of_DRAM() - size;
720                 lmb_reserve(base, size);
721                 phyp_dump_info->init_reserve_start = base;
722                 phyp_dump_info->init_reserve_size = size;
723         }
724 }
725 #else
726 static inline void __init phyp_dump_reserve_mem(void) {}
727 #endif /* CONFIG_PHYP_DUMP  && CONFIG_PPC_RTAS */
728
729 #ifdef CONFIG_EARLY_PRINTK
730 /* MS this is Microblaze specifig function */
731 static int __init early_init_dt_scan_serial(unsigned long node,
732                                 const char *uname, int depth, void *data)
733 {
734         unsigned long l;
735         char *p;
736         int *addr;
737
738         pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
739
740 /* find all serial nodes */
741         if (strncmp(uname, "serial", 6) != 0)
742                 return 0;
743
744         early_init_dt_check_for_initrd(node);
745
746 /* find compatible node with uartlite */
747         p = of_get_flat_dt_prop(node, "compatible", &l);
748         if ((strncmp(p, "xlnx,xps-uartlite", 17) != 0) &&
749                         (strncmp(p, "xlnx,opb-uartlite", 17) != 0))
750                 return 0;
751
752         addr = of_get_flat_dt_prop(node, "reg", &l);
753         return *addr; /* return address */
754 }
755
756 /* this function is looking for early uartlite console - Microblaze specific */
757 int __init early_uartlite_console(void)
758 {
759         return of_scan_flat_dt(early_init_dt_scan_serial, NULL);
760 }
761 #endif
762
763 void __init early_init_devtree(void *params)
764 {
765         pr_debug(" -> early_init_devtree(%p)\n", params);
766
767         /* Setup flat device-tree pointer */
768         initial_boot_params = params;
769
770 #ifdef CONFIG_PHYP_DUMP
771         /* scan tree to see if dump occured during last boot */
772         of_scan_flat_dt(early_init_dt_scan_phyp_dump, NULL);
773 #endif
774
775         /* Retrieve various informations from the /chosen node of the
776          * device-tree, including the platform type, initrd location and
777          * size, TCE reserve, and more ...
778          */
779         of_scan_flat_dt(early_init_dt_scan_chosen, NULL);
780
781         /* Scan memory nodes and rebuild LMBs */
782         lmb_init();
783         of_scan_flat_dt(early_init_dt_scan_root, NULL);
784         of_scan_flat_dt(early_init_dt_scan_memory, NULL);
785
786         /* Save command line for /proc/cmdline and then parse parameters */
787         strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE);
788         parse_early_param();
789
790         lmb_analyze();
791
792         pr_debug("Phys. mem: %lx\n", (unsigned long) lmb_phys_mem_size());
793
794         pr_debug("Scanning CPUs ...\n");
795
796         /* Retreive CPU related informations from the flat tree
797          * (altivec support, boot CPU ID, ...)
798          */
799         of_scan_flat_dt(early_init_dt_scan_cpus, NULL);
800
801         pr_debug(" <- early_init_devtree()\n");
802 }
803
804 /**
805  * Indicates whether the root node has a given value in its
806  * compatible property.
807  */
808 int machine_is_compatible(const char *compat)
809 {
810         struct device_node *root;
811         int rc = 0;
812
813         root = of_find_node_by_path("/");
814         if (root) {
815                 rc = of_device_is_compatible(root, compat);
816                 of_node_put(root);
817         }
818         return rc;
819 }
820 EXPORT_SYMBOL(machine_is_compatible);
821
822 /*******
823  *
824  * New implementation of the OF "find" APIs, return a refcounted
825  * object, call of_node_put() when done.  The device tree and list
826  * are protected by a rw_lock.
827  *
828  * Note that property management will need some locking as well,
829  * this isn't dealt with yet.
830  *
831  *******/
832
833 /**
834  *      of_find_node_by_phandle - Find a node given a phandle
835  *      @handle:        phandle of the node to find
836  *
837  *      Returns a node pointer with refcount incremented, use
838  *      of_node_put() on it when done.
839  */
840 struct device_node *of_find_node_by_phandle(phandle handle)
841 {
842         struct device_node *np;
843
844         read_lock(&devtree_lock);
845         for (np = allnodes; np != NULL; np = np->allnext)
846                 if (np->linux_phandle == handle)
847                         break;
848         of_node_get(np);
849         read_unlock(&devtree_lock);
850         return np;
851 }
852 EXPORT_SYMBOL(of_find_node_by_phandle);
853
854 /**
855  *      of_node_get - Increment refcount of a node
856  *      @node:  Node to inc refcount, NULL is supported to
857  *              simplify writing of callers
858  *
859  *      Returns node.
860  */
861 struct device_node *of_node_get(struct device_node *node)
862 {
863         if (node)
864                 kref_get(&node->kref);
865         return node;
866 }
867 EXPORT_SYMBOL(of_node_get);
868
869 static inline struct device_node *kref_to_device_node(struct kref *kref)
870 {
871         return container_of(kref, struct device_node, kref);
872 }
873
874 /**
875  *      of_node_release - release a dynamically allocated node
876  *      @kref:  kref element of the node to be released
877  *
878  *      In of_node_put() this function is passed to kref_put()
879  *      as the destructor.
880  */
881 static void of_node_release(struct kref *kref)
882 {
883         struct device_node *node = kref_to_device_node(kref);
884         struct property *prop = node->properties;
885
886         /* We should never be releasing nodes that haven't been detached. */
887         if (!of_node_check_flag(node, OF_DETACHED)) {
888                 printk(KERN_INFO "WARNING: Bad of_node_put() on %s\n",
889                         node->full_name);
890                 dump_stack();
891                 kref_init(&node->kref);
892                 return;
893         }
894
895         if (!of_node_check_flag(node, OF_DYNAMIC))
896                 return;
897
898         while (prop) {
899                 struct property *next = prop->next;
900                 kfree(prop->name);
901                 kfree(prop->value);
902                 kfree(prop);
903                 prop = next;
904
905                 if (!prop) {
906                         prop = node->deadprops;
907                         node->deadprops = NULL;
908                 }
909         }
910         kfree(node->full_name);
911         kfree(node->data);
912         kfree(node);
913 }
914
915 /**
916  *      of_node_put - Decrement refcount of a node
917  *      @node:  Node to dec refcount, NULL is supported to
918  *              simplify writing of callers
919  *
920  */
921 void of_node_put(struct device_node *node)
922 {
923         if (node)
924                 kref_put(&node->kref, of_node_release);
925 }
926 EXPORT_SYMBOL(of_node_put);
927
928 /*
929  * Plug a device node into the tree and global list.
930  */
931 void of_attach_node(struct device_node *np)
932 {
933         unsigned long flags;
934
935         write_lock_irqsave(&devtree_lock, flags);
936         np->sibling = np->parent->child;
937         np->allnext = allnodes;
938         np->parent->child = np;
939         allnodes = np;
940         write_unlock_irqrestore(&devtree_lock, flags);
941 }
942
943 /*
944  * "Unplug" a node from the device tree.  The caller must hold
945  * a reference to the node.  The memory associated with the node
946  * is not freed until its refcount goes to zero.
947  */
948 void of_detach_node(struct device_node *np)
949 {
950         struct device_node *parent;
951         unsigned long flags;
952
953         write_lock_irqsave(&devtree_lock, flags);
954
955         parent = np->parent;
956         if (!parent)
957                 goto out_unlock;
958
959         if (allnodes == np)
960                 allnodes = np->allnext;
961         else {
962                 struct device_node *prev;
963                 for (prev = allnodes;
964                      prev->allnext != np;
965                      prev = prev->allnext)
966                         ;
967                 prev->allnext = np->allnext;
968         }
969
970         if (parent->child == np)
971                 parent->child = np->sibling;
972         else {
973                 struct device_node *prevsib;
974                 for (prevsib = np->parent->child;
975                      prevsib->sibling != np;
976                      prevsib = prevsib->sibling)
977                         ;
978                 prevsib->sibling = np->sibling;
979         }
980
981         of_node_set_flag(np, OF_DETACHED);
982
983 out_unlock:
984         write_unlock_irqrestore(&devtree_lock, flags);
985 }
986
987 /*
988  * Add a property to a node
989  */
990 int prom_add_property(struct device_node *np, struct property *prop)
991 {
992         struct property **next;
993         unsigned long flags;
994
995         prop->next = NULL;
996         write_lock_irqsave(&devtree_lock, flags);
997         next = &np->properties;
998         while (*next) {
999                 if (strcmp(prop->name, (*next)->name) == 0) {
1000                         /* duplicate ! don't insert it */
1001                         write_unlock_irqrestore(&devtree_lock, flags);
1002                         return -1;
1003                 }
1004                 next = &(*next)->next;
1005         }
1006         *next = prop;
1007         write_unlock_irqrestore(&devtree_lock, flags);
1008
1009 #ifdef CONFIG_PROC_DEVICETREE
1010         /* try to add to proc as well if it was initialized */
1011         if (np->pde)
1012                 proc_device_tree_add_prop(np->pde, prop);
1013 #endif /* CONFIG_PROC_DEVICETREE */
1014
1015         return 0;
1016 }
1017
1018 /*
1019  * Remove a property from a node.  Note that we don't actually
1020  * remove it, since we have given out who-knows-how-many pointers
1021  * to the data using get-property.  Instead we just move the property
1022  * to the "dead properties" list, so it won't be found any more.
1023  */
1024 int prom_remove_property(struct device_node *np, struct property *prop)
1025 {
1026         struct property **next;
1027         unsigned long flags;
1028         int found = 0;
1029
1030         write_lock_irqsave(&devtree_lock, flags);
1031         next = &np->properties;
1032         while (*next) {
1033                 if (*next == prop) {
1034                         /* found the node */
1035                         *next = prop->next;
1036                         prop->next = np->deadprops;
1037                         np->deadprops = prop;
1038                         found = 1;
1039                         break;
1040                 }
1041                 next = &(*next)->next;
1042         }
1043         write_unlock_irqrestore(&devtree_lock, flags);
1044
1045         if (!found)
1046                 return -ENODEV;
1047
1048 #ifdef CONFIG_PROC_DEVICETREE
1049         /* try to remove the proc node as well */
1050         if (np->pde)
1051                 proc_device_tree_remove_prop(np->pde, prop);
1052 #endif /* CONFIG_PROC_DEVICETREE */
1053
1054         return 0;
1055 }
1056
1057 /*
1058  * Update a property in a node.  Note that we don't actually
1059  * remove it, since we have given out who-knows-how-many pointers
1060  * to the data using get-property.  Instead we just move the property
1061  * to the "dead properties" list, and add the new property to the
1062  * property list
1063  */
1064 int prom_update_property(struct device_node *np,
1065                          struct property *newprop,
1066                          struct property *oldprop)
1067 {
1068         struct property **next;
1069         unsigned long flags;
1070         int found = 0;
1071
1072         write_lock_irqsave(&devtree_lock, flags);
1073         next = &np->properties;
1074         while (*next) {
1075                 if (*next == oldprop) {
1076                         /* found the node */
1077                         newprop->next = oldprop->next;
1078                         *next = newprop;
1079                         oldprop->next = np->deadprops;
1080                         np->deadprops = oldprop;
1081                         found = 1;
1082                         break;
1083                 }
1084                 next = &(*next)->next;
1085         }
1086         write_unlock_irqrestore(&devtree_lock, flags);
1087
1088         if (!found)
1089                 return -ENODEV;
1090
1091 #ifdef CONFIG_PROC_DEVICETREE
1092         /* try to add to proc as well if it was initialized */
1093         if (np->pde)
1094                 proc_device_tree_update_prop(np->pde, newprop, oldprop);
1095 #endif /* CONFIG_PROC_DEVICETREE */
1096
1097         return 0;
1098 }
1099
1100 #if defined(CONFIG_DEBUG_FS) && defined(DEBUG)
1101 static struct debugfs_blob_wrapper flat_dt_blob;
1102
1103 static int __init export_flat_device_tree(void)
1104 {
1105         struct dentry *d;
1106
1107         flat_dt_blob.data = initial_boot_params;
1108         flat_dt_blob.size = initial_boot_params->totalsize;
1109
1110         d = debugfs_create_blob("flat-device-tree", S_IFREG | S_IRUSR,
1111                                 of_debugfs_root, &flat_dt_blob);
1112         if (!d)
1113                 return 1;
1114
1115         return 0;
1116 }
1117 device_initcall(export_flat_device_tree);
1118 #endif