fdt.c 18 KB

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