linux/drivers/of/fdt.c
<<
>>
Prefs
   1/*
   2 * Functions for working with the Flattened Device Tree data format
   3 *
   4 * Copyright 2009 Benjamin Herrenschmidt, IBM Corp
   5 * benh@kernel.crashing.org
   6 *
   7 * This program is free software; you can redistribute it and/or
   8 * modify it under the terms of the GNU General Public License
   9 * version 2 as published by the Free Software Foundation.
  10 */
  11
  12#include <linux/kernel.h>
  13#include <linux/initrd.h>
  14#include <linux/module.h>
  15#include <linux/of.h>
  16#include <linux/of_fdt.h>
  17#include <linux/string.h>
  18#include <linux/errno.h>
  19#include <linux/slab.h>
  20
  21#include <asm/setup.h>  /* for COMMAND_LINE_SIZE */
  22#ifdef CONFIG_PPC
  23#include <asm/machdep.h>
  24#endif /* CONFIG_PPC */
  25
  26#include <asm/page.h>
  27
  28char *of_fdt_get_string(struct boot_param_header *blob, u32 offset)
  29{
  30        return ((char *)blob) +
  31                be32_to_cpu(blob->off_dt_strings) + offset;
  32}
  33
  34/**
  35 * of_fdt_get_property - Given a node in the given flat blob, return
  36 * the property ptr
  37 */
  38void *of_fdt_get_property(struct boot_param_header *blob,
  39                       unsigned long node, const char *name,
  40                       unsigned long *size)
  41{
  42        unsigned long p = node;
  43
  44        do {
  45                u32 tag = be32_to_cpup((__be32 *)p);
  46                u32 sz, noff;
  47                const char *nstr;
  48
  49                p += 4;
  50                if (tag == OF_DT_NOP)
  51                        continue;
  52                if (tag != OF_DT_PROP)
  53                        return NULL;
  54
  55                sz = be32_to_cpup((__be32 *)p);
  56                noff = be32_to_cpup((__be32 *)(p + 4));
  57                p += 8;
  58                if (be32_to_cpu(blob->version) < 0x10)
  59                        p = ALIGN(p, sz >= 8 ? 8 : 4);
  60
  61                nstr = of_fdt_get_string(blob, noff);
  62                if (nstr == NULL) {
  63                        pr_warning("Can't find property index name !\n");
  64                        return NULL;
  65                }
  66                if (strcmp(name, nstr) == 0) {
  67                        if (size)
  68                                *size = sz;
  69                        return (void *)p;
  70                }
  71                p += sz;
  72                p = ALIGN(p, 4);
  73        } while (1);
  74}
  75
  76/**
  77 * of_fdt_is_compatible - Return true if given node from the given blob has
  78 * compat in its compatible list
  79 * @blob: A device tree blob
  80 * @node: node to test
  81 * @compat: compatible string to compare with compatible list.
  82 *
  83 * On match, returns a non-zero value with smaller values returned for more
  84 * specific compatible values.
  85 */
  86int of_fdt_is_compatible(struct boot_param_header *blob,
  87                      unsigned long node, const char *compat)
  88{
  89        const char *cp;
  90        unsigned long cplen, l, score = 0;
  91
  92        cp = of_fdt_get_property(blob, node, "compatible", &cplen);
  93        if (cp == NULL)
  94                return 0;
  95        while (cplen > 0) {
  96                score++;
  97                if (of_compat_cmp(cp, compat, strlen(compat)) == 0)
  98                        return score;
  99                l = strlen(cp) + 1;
 100                cp += l;
 101                cplen -= l;
 102        }
 103
 104        return 0;
 105}
 106
 107/**
 108 * of_fdt_match - Return true if node matches a list of compatible values
 109 */
 110int of_fdt_match(struct boot_param_header *blob, unsigned long node,
 111                 const char *const *compat)
 112{
 113        unsigned int tmp, score = 0;
 114
 115        if (!compat)
 116                return 0;
 117
 118        while (*compat) {
 119                tmp = of_fdt_is_compatible(blob, node, *compat);
 120                if (tmp && (score == 0 || (tmp < score)))
 121                        score = tmp;
 122                compat++;
 123        }
 124
 125        return score;
 126}
 127
 128static void *unflatten_dt_alloc(unsigned long *mem, unsigned long size,
 129                                       unsigned long align)
 130{
 131        void *res;
 132
 133        *mem = ALIGN(*mem, align);
 134        res = (void *)*mem;
 135        *mem += size;
 136
 137        return res;
 138}
 139
 140/**
 141 * unflatten_dt_node - Alloc and populate a device_node from the flat tree
 142 * @blob: The parent device tree blob
 143 * @mem: Memory chunk to use for allocating device nodes and properties
 144 * @p: pointer to node in flat tree
 145 * @dad: Parent struct device_node
 146 * @allnextpp: pointer to ->allnext from last allocated device_node
 147 * @fpsize: Size of the node path up at the current depth.
 148 */
 149static unsigned long unflatten_dt_node(struct boot_param_header *blob,
 150                                unsigned long mem,
 151                                unsigned long *p,
 152                                struct device_node *dad,
 153                                struct device_node ***allnextpp,
 154                                unsigned long fpsize)
 155{
 156        struct device_node *np;
 157        struct property *pp, **prev_pp = NULL;
 158        char *pathp;
 159        u32 tag;
 160        unsigned int l, allocl;
 161        int has_name = 0;
 162        int new_format = 0;
 163
 164        tag = be32_to_cpup((__be32 *)(*p));
 165        if (tag != OF_DT_BEGIN_NODE) {
 166                pr_err("Weird tag at start of node: %x\n", tag);
 167                return mem;
 168        }
 169        *p += 4;
 170        pathp = (char *)*p;
 171        l = allocl = strlen(pathp) + 1;
 172        *p = ALIGN(*p + l, 4);
 173
 174        /* version 0x10 has a more compact unit name here instead of the full
 175         * path. we accumulate the full path size using "fpsize", we'll rebuild
 176         * it later. We detect this because the first character of the name is
 177         * not '/'.
 178         */
 179        if ((*pathp) != '/') {
 180                new_format = 1;
 181                if (fpsize == 0) {
 182                        /* root node: special case. fpsize accounts for path
 183                         * plus terminating zero. root node only has '/', so
 184                         * fpsize should be 2, but we want to avoid the first
 185                         * level nodes to have two '/' so we use fpsize 1 here
 186                         */
 187                        fpsize = 1;
 188                        allocl = 2;
 189                        l = 1;
 190                        *pathp = '\0';
 191                } else {
 192                        /* account for '/' and path size minus terminal 0
 193                         * already in 'l'
 194                         */
 195                        fpsize += l;
 196                        allocl = fpsize;
 197                }
 198        }
 199
 200        np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl,
 201                                __alignof__(struct device_node));
 202        if (allnextpp) {
 203                char *fn;
 204                memset(np, 0, sizeof(*np));
 205                np->full_name = fn = ((char *)np) + sizeof(*np);
 206                if (new_format) {
 207                        /* rebuild full path for new format */
 208                        if (dad && dad->parent) {
 209                                strcpy(fn, dad->full_name);
 210#ifdef DEBUG
 211                                if ((strlen(fn) + l + 1) != allocl) {
 212                                        pr_debug("%s: p: %d, l: %d, a: %d\n",
 213                                                pathp, (int)strlen(fn),
 214                                                l, allocl);
 215                                }
 216#endif
 217                                fn += strlen(fn);
 218                        }
 219                        *(fn++) = '/';
 220                }
 221                memcpy(fn, pathp, l);
 222
 223                prev_pp = &np->properties;
 224                **allnextpp = np;
 225                *allnextpp = &np->allnext;
 226                if (dad != NULL) {
 227                        np->parent = dad;
 228                        /* we temporarily use the next field as `last_child'*/
 229                        if (dad->next == NULL)
 230                                dad->child = np;
 231                        else
 232                                dad->next->sibling = np;
 233                        dad->next = np;
 234                }
 235                kref_init(&np->kref);
 236        }
 237        /* process properties */
 238        while (1) {
 239                u32 sz, noff;
 240                char *pname;
 241
 242                tag = be32_to_cpup((__be32 *)(*p));
 243                if (tag == OF_DT_NOP) {
 244                        *p += 4;
 245                        continue;
 246                }
 247                if (tag != OF_DT_PROP)
 248                        break;
 249                *p += 4;
 250                sz = be32_to_cpup((__be32 *)(*p));
 251                noff = be32_to_cpup((__be32 *)((*p) + 4));
 252                *p += 8;
 253                if (be32_to_cpu(blob->version) < 0x10)
 254                        *p = ALIGN(*p, sz >= 8 ? 8 : 4);
 255
 256                pname = of_fdt_get_string(blob, noff);
 257                if (pname == NULL) {
 258                        pr_info("Can't find property name in list !\n");
 259                        break;
 260                }
 261                if (strcmp(pname, "name") == 0)
 262                        has_name = 1;
 263                l = strlen(pname) + 1;
 264                pp = unflatten_dt_alloc(&mem, sizeof(struct property),
 265                                        __alignof__(struct property));
 266                if (allnextpp) {
 267                        /* We accept flattened tree phandles either in
 268                         * ePAPR-style "phandle" properties, or the
 269                         * legacy "linux,phandle" properties.  If both
 270                         * appear and have different values, things
 271                         * will get weird.  Don't do that. */
 272                        if ((strcmp(pname, "phandle") == 0) ||
 273                            (strcmp(pname, "linux,phandle") == 0)) {
 274                                if (np->phandle == 0)
 275                                        np->phandle = be32_to_cpup((__be32*)*p);
 276                        }
 277                        /* And we process the "ibm,phandle" property
 278                         * used in pSeries dynamic device tree
 279                         * stuff */
 280                        if (strcmp(pname, "ibm,phandle") == 0)
 281                                np->phandle = be32_to_cpup((__be32 *)*p);
 282                        pp->name = pname;
 283                        pp->length = sz;
 284                        pp->value = (void *)*p;
 285                        *prev_pp = pp;
 286                        prev_pp = &pp->next;
 287                }
 288                *p = ALIGN((*p) + sz, 4);
 289        }
 290        /* with version 0x10 we may not have the name property, recreate
 291         * it here from the unit name if absent
 292         */
 293        if (!has_name) {
 294                char *p1 = pathp, *ps = pathp, *pa = NULL;
 295                int sz;
 296
 297                while (*p1) {
 298                        if ((*p1) == '@')
 299                                pa = p1;
 300                        if ((*p1) == '/')
 301                                ps = p1 + 1;
 302                        p1++;
 303                }
 304                if (pa < ps)
 305                        pa = p1;
 306                sz = (pa - ps) + 1;
 307                pp = unflatten_dt_alloc(&mem, sizeof(struct property) + sz,
 308                                        __alignof__(struct property));
 309                if (allnextpp) {
 310                        pp->name = "name";
 311                        pp->length = sz;
 312                        pp->value = pp + 1;
 313                        *prev_pp = pp;
 314                        prev_pp = &pp->next;
 315                        memcpy(pp->value, ps, sz - 1);
 316                        ((char *)pp->value)[sz - 1] = 0;
 317                        pr_debug("fixed up name for %s -> %s\n", pathp,
 318                                (char *)pp->value);
 319                }
 320        }
 321        if (allnextpp) {
 322                *prev_pp = NULL;
 323                np->name = of_get_property(np, "name", NULL);
 324                np->type = of_get_property(np, "device_type", NULL);
 325
 326                if (!np->name)
 327                        np->name = "<NULL>";
 328                if (!np->type)
 329                        np->type = "<NULL>";
 330        }
 331        while (tag == OF_DT_BEGIN_NODE || tag == OF_DT_NOP) {
 332                if (tag == OF_DT_NOP)
 333                        *p += 4;
 334                else
 335                        mem = unflatten_dt_node(blob, mem, p, np, allnextpp,
 336                                                fpsize);
 337                tag = be32_to_cpup((__be32 *)(*p));
 338        }
 339        if (tag != OF_DT_END_NODE) {
 340                pr_err("Weird tag at end of node: %x\n", tag);
 341                return mem;
 342        }
 343        *p += 4;
 344        return mem;
 345}
 346
 347/**
 348 * __unflatten_device_tree - create tree of device_nodes from flat blob
 349 *
 350 * unflattens a device-tree, creating the
 351 * tree of struct device_node. It also fills the "name" and "type"
 352 * pointers of the nodes so the normal device-tree walking functions
 353 * can be used.
 354 * @blob: The blob to expand
 355 * @mynodes: The device_node tree created by the call
 356 * @dt_alloc: An allocator that provides a virtual address to memory
 357 * for the resulting tree
 358 */
 359static void __unflatten_device_tree(struct boot_param_header *blob,
 360                             struct device_node **mynodes,
 361                             void * (*dt_alloc)(u64 size, u64 align))
 362{
 363        unsigned long start, mem, size;
 364        struct device_node **allnextp = mynodes;
 365
 366        pr_debug(" -> unflatten_device_tree()\n");
 367
 368        if (!blob) {
 369                pr_debug("No device tree pointer\n");
 370                return;
 371        }
 372
 373        pr_debug("Unflattening device tree:\n");
 374        pr_debug("magic: %08x\n", be32_to_cpu(blob->magic));
 375        pr_debug("size: %08x\n", be32_to_cpu(blob->totalsize));
 376        pr_debug("version: %08x\n", be32_to_cpu(blob->version));
 377
 378        if (be32_to_cpu(blob->magic) != OF_DT_HEADER) {
 379                pr_err("Invalid device tree blob header\n");
 380                return;
 381        }
 382
 383        /* First pass, scan for size */
 384        start = ((unsigned long)blob) +
 385                be32_to_cpu(blob->off_dt_struct);
 386        size = unflatten_dt_node(blob, 0, &start, NULL, NULL, 0);
 387        size = (size | 3) + 1;
 388
 389        pr_debug("  size is %lx, allocating...\n", size);
 390
 391        /* Allocate memory for the expanded device tree */
 392        mem = (unsigned long)
 393                dt_alloc(size + 4, __alignof__(struct device_node));
 394
 395        memset((void *)mem, 0, size);
 396
 397        ((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef);
 398
 399        pr_debug("  unflattening %lx...\n", mem);
 400
 401        /* Second pass, do actual unflattening */
 402        start = ((unsigned long)blob) +
 403                be32_to_cpu(blob->off_dt_struct);
 404        unflatten_dt_node(blob, mem, &start, NULL, &allnextp, 0);
 405        if (be32_to_cpup((__be32 *)start) != OF_DT_END)
 406                pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start));
 407        if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef)
 408                pr_warning("End of tree marker overwritten: %08x\n",
 409                           be32_to_cpu(((__be32 *)mem)[size / 4]));
 410        *allnextp = NULL;
 411
 412        pr_debug(" <- unflatten_device_tree()\n");
 413}
 414
 415static void *kernel_tree_alloc(u64 size, u64 align)
 416{
 417        return kzalloc(size, GFP_KERNEL);
 418}
 419
 420/**
 421 * of_fdt_unflatten_tree - create tree of device_nodes from flat blob
 422 *
 423 * unflattens the device-tree passed by the firmware, creating the
 424 * tree of struct device_node. It also fills the "name" and "type"
 425 * pointers of the nodes so the normal device-tree walking functions
 426 * can be used.
 427 */
 428void of_fdt_unflatten_tree(unsigned long *blob,
 429                        struct device_node **mynodes)
 430{
 431        struct boot_param_header *device_tree =
 432                (struct boot_param_header *)blob;
 433        __unflatten_device_tree(device_tree, mynodes, &kernel_tree_alloc);
 434}
 435EXPORT_SYMBOL_GPL(of_fdt_unflatten_tree);
 436
 437/* Everything below here references initial_boot_params directly. */
 438int __initdata dt_root_addr_cells;
 439int __initdata dt_root_size_cells;
 440
 441struct boot_param_header *initial_boot_params;
 442
 443#ifdef CONFIG_OF_EARLY_FLATTREE
 444
 445/**
 446 * of_scan_flat_dt - scan flattened tree blob and call callback on each.
 447 * @it: callback function
 448 * @data: context data pointer
 449 *
 450 * This function is used to scan the flattened device-tree, it is
 451 * used to extract the memory information at boot before we can
 452 * unflatten the tree
 453 */
 454int __init of_scan_flat_dt(int (*it)(unsigned long node,
 455                                     const char *uname, int depth,
 456                                     void *data),
 457                           void *data)
 458{
 459        unsigned long p = ((unsigned long)initial_boot_params) +
 460                be32_to_cpu(initial_boot_params->off_dt_struct);
 461        int rc = 0;
 462        int depth = -1;
 463
 464        do {
 465                u32 tag = be32_to_cpup((__be32 *)p);
 466                const char *pathp;
 467
 468                p += 4;
 469                if (tag == OF_DT_END_NODE) {
 470                        depth--;
 471                        continue;
 472                }
 473                if (tag == OF_DT_NOP)
 474                        continue;
 475                if (tag == OF_DT_END)
 476                        break;
 477                if (tag == OF_DT_PROP) {
 478                        u32 sz = be32_to_cpup((__be32 *)p);
 479                        p += 8;
 480                        if (be32_to_cpu(initial_boot_params->version) < 0x10)
 481                                p = ALIGN(p, sz >= 8 ? 8 : 4);
 482                        p += sz;
 483                        p = ALIGN(p, 4);
 484                        continue;
 485                }
 486                if (tag != OF_DT_BEGIN_NODE) {
 487                        pr_err("Invalid tag %x in flat device tree!\n", tag);
 488                        return -EINVAL;
 489                }
 490                depth++;
 491                pathp = (char *)p;
 492                p = ALIGN(p + strlen(pathp) + 1, 4);
 493                if (*pathp == '/')
 494                        pathp = kbasename(pathp);
 495                rc = it(p, pathp, depth, data);
 496                if (rc != 0)
 497                        break;
 498        } while (1);
 499
 500        return rc;
 501}
 502
 503/**
 504 * of_get_flat_dt_root - find the root node in the flat blob
 505 */
 506unsigned long __init of_get_flat_dt_root(void)
 507{
 508        unsigned long p = ((unsigned long)initial_boot_params) +
 509                be32_to_cpu(initial_boot_params->off_dt_struct);
 510
 511        while (be32_to_cpup((__be32 *)p) == OF_DT_NOP)
 512                p += 4;
 513        BUG_ON(be32_to_cpup((__be32 *)p) != OF_DT_BEGIN_NODE);
 514        p += 4;
 515        return ALIGN(p + strlen((char *)p) + 1, 4);
 516}
 517
 518/**
 519 * of_get_flat_dt_prop - Given a node in the flat blob, return the property ptr
 520 *
 521 * This function can be used within scan_flattened_dt callback to get
 522 * access to properties
 523 */
 524void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
 525                                 unsigned long *size)
 526{
 527        return of_fdt_get_property(initial_boot_params, node, name, size);
 528}
 529
 530/**
 531 * of_flat_dt_is_compatible - Return true if given node has compat in compatible list
 532 * @node: node to test
 533 * @compat: compatible string to compare with compatible list.
 534 */
 535int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
 536{
 537        return of_fdt_is_compatible(initial_boot_params, node, compat);
 538}
 539
 540/**
 541 * of_flat_dt_match - Return true if node matches a list of compatible values
 542 */
 543int __init of_flat_dt_match(unsigned long node, const char *const *compat)
 544{
 545        return of_fdt_match(initial_boot_params, node, compat);
 546}
 547
 548#ifdef CONFIG_BLK_DEV_INITRD
 549/**
 550 * early_init_dt_check_for_initrd - Decode initrd location from flat tree
 551 * @node: reference to node containing initrd location ('chosen')
 552 */
 553void __init early_init_dt_check_for_initrd(unsigned long node)
 554{
 555        unsigned long start, end, len;
 556        __be32 *prop;
 557
 558        pr_debug("Looking for initrd properties... ");
 559
 560        prop = of_get_flat_dt_prop(node, "linux,initrd-start", &len);
 561        if (!prop)
 562                return;
 563        start = of_read_ulong(prop, len/4);
 564
 565        prop = of_get_flat_dt_prop(node, "linux,initrd-end", &len);
 566        if (!prop)
 567                return;
 568        end = of_read_ulong(prop, len/4);
 569
 570        early_init_dt_setup_initrd_arch(start, end);
 571        pr_debug("initrd_start=0x%lx  initrd_end=0x%lx\n", start, end);
 572}
 573#else
 574inline void early_init_dt_check_for_initrd(unsigned long node)
 575{
 576}
 577#endif /* CONFIG_BLK_DEV_INITRD */
 578
 579/**
 580 * early_init_dt_scan_root - fetch the top level address and size cells
 581 */
 582int __init early_init_dt_scan_root(unsigned long node, const char *uname,
 583                                   int depth, void *data)
 584{
 585        __be32 *prop;
 586
 587        if (depth != 0)
 588                return 0;
 589
 590        dt_root_size_cells = OF_ROOT_NODE_SIZE_CELLS_DEFAULT;
 591        dt_root_addr_cells = OF_ROOT_NODE_ADDR_CELLS_DEFAULT;
 592
 593        prop = of_get_flat_dt_prop(node, "#size-cells", NULL);
 594        if (prop)
 595                dt_root_size_cells = be32_to_cpup(prop);
 596        pr_debug("dt_root_size_cells = %x\n", dt_root_size_cells);
 597
 598        prop = of_get_flat_dt_prop(node, "#address-cells", NULL);
 599        if (prop)
 600                dt_root_addr_cells = be32_to_cpup(prop);
 601        pr_debug("dt_root_addr_cells = %x\n", dt_root_addr_cells);
 602
 603        /* break now */
 604        return 1;
 605}
 606
 607u64 __init dt_mem_next_cell(int s, __be32 **cellp)
 608{
 609        __be32 *p = *cellp;
 610
 611        *cellp = p + s;
 612        return of_read_number(p, s);
 613}
 614
 615/**
 616 * early_init_dt_scan_memory - Look for an parse memory nodes
 617 */
 618int __init early_init_dt_scan_memory(unsigned long node, const char *uname,
 619                                     int depth, void *data)
 620{
 621        char *type = of_get_flat_dt_prop(node, "device_type", NULL);
 622        __be32 *reg, *endp;
 623        unsigned long l;
 624
 625        /* We are scanning "memory" nodes only */
 626        if (type == NULL) {
 627                /*
 628                 * The longtrail doesn't have a device_type on the
 629                 * /memory node, so look for the node called /memory@0.
 630                 */
 631                if (depth != 1 || strcmp(uname, "memory@0") != 0)
 632                        return 0;
 633        } else if (strcmp(type, "memory") != 0)
 634                return 0;
 635
 636        reg = of_get_flat_dt_prop(node, "linux,usable-memory", &l);
 637        if (reg == NULL)
 638                reg = of_get_flat_dt_prop(node, "reg", &l);
 639        if (reg == NULL)
 640                return 0;
 641
 642        endp = reg + (l / sizeof(__be32));
 643
 644        pr_debug("memory scan node %s, reg size %ld, data: %x %x %x %x,\n",
 645            uname, l, reg[0], reg[1], reg[2], reg[3]);
 646
 647        while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
 648                u64 base, size;
 649
 650                base = dt_mem_next_cell(dt_root_addr_cells, &reg);
 651                size = dt_mem_next_cell(dt_root_size_cells, &reg);
 652
 653                if (size == 0)
 654                        continue;
 655                pr_debug(" - %llx ,  %llx\n", (unsigned long long)base,
 656                    (unsigned long long)size);
 657
 658                early_init_dt_add_memory_arch(base, size);
 659        }
 660
 661        return 0;
 662}
 663
 664int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
 665                                     int depth, void *data)
 666{
 667        unsigned long l;
 668        char *p;
 669
 670        pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
 671
 672        if (depth != 1 || !data ||
 673            (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0))
 674                return 0;
 675
 676        early_init_dt_check_for_initrd(node);
 677
 678        /* Retrieve command line */
 679        p = of_get_flat_dt_prop(node, "bootargs", &l);
 680        if (p != NULL && l > 0)
 681                strlcpy(data, p, min((int)l, COMMAND_LINE_SIZE));
 682
 683        /*
 684         * CONFIG_CMDLINE is meant to be a default in case nothing else
 685         * managed to set the command line, unless CONFIG_CMDLINE_FORCE
 686         * is set in which case we override whatever was found earlier.
 687         */
 688#ifdef CONFIG_CMDLINE
 689#ifndef CONFIG_CMDLINE_FORCE
 690        if (!((char *)data)[0])
 691#endif
 692                strlcpy(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
 693#endif /* CONFIG_CMDLINE */
 694
 695        pr_debug("Command line is: %s\n", (char*)data);
 696
 697        /* break now */
 698        return 1;
 699}
 700
 701/**
 702 * unflatten_device_tree - create tree of device_nodes from flat blob
 703 *
 704 * unflattens the device-tree passed by the firmware, creating the
 705 * tree of struct device_node. It also fills the "name" and "type"
 706 * pointers of the nodes so the normal device-tree walking functions
 707 * can be used.
 708 */
 709void __init unflatten_device_tree(void)
 710{
 711        __unflatten_device_tree(initial_boot_params, &of_allnodes,
 712                                early_init_dt_alloc_memory_arch);
 713
 714        /* Get pointer to "/chosen" and "/aliases" nodes for use everywhere */
 715        of_alias_scan(early_init_dt_alloc_memory_arch);
 716}
 717
 718#endif /* CONFIG_OF_EARLY_FLATTREE */
 719