of_access.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735
  1. /*
  2. * Originally from Linux v4.9
  3. * Paul Mackerras August 1996.
  4. * Copyright (C) 1996-2005 Paul Mackerras.
  5. *
  6. * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
  7. * {engebret|bergner}@us.ibm.com
  8. *
  9. * Adapted for sparc and sparc64 by David S. Miller davem@davemloft.net
  10. *
  11. * Reconsolidated from arch/x/kernel/prom.c by Stephen Rothwell and
  12. * Grant Likely.
  13. *
  14. * Modified for U-Boot
  15. * Copyright (c) 2017 Google, Inc
  16. *
  17. * This file follows drivers/of/base.c with functions in the same order as the
  18. * Linux version.
  19. *
  20. * SPDX-License-Identifier: GPL-2.0+
  21. */
  22. #include <common.h>
  23. #include <libfdt.h>
  24. #include <dm/of_access.h>
  25. #include <linux/ctype.h>
  26. #include <linux/err.h>
  27. #include <linux/ioport.h>
  28. DECLARE_GLOBAL_DATA_PTR;
  29. /* list of struct alias_prop aliases */
  30. LIST_HEAD(aliases_lookup);
  31. /* "/aliaes" node */
  32. static struct device_node *of_aliases;
  33. /* "/chosen" node */
  34. static struct device_node *of_chosen;
  35. /* node pointed to by the stdout-path alias */
  36. static struct device_node *of_stdout;
  37. /* pointer to options given after the alias (separated by :) or NULL if none */
  38. static const char *of_stdout_options;
  39. /**
  40. * struct alias_prop - Alias property in 'aliases' node
  41. *
  42. * The structure represents one alias property of 'aliases' node as
  43. * an entry in aliases_lookup list.
  44. *
  45. * @link: List node to link the structure in aliases_lookup list
  46. * @alias: Alias property name
  47. * @np: Pointer to device_node that the alias stands for
  48. * @id: Index value from end of alias name
  49. * @stem: Alias string without the index
  50. */
  51. struct alias_prop {
  52. struct list_head link;
  53. const char *alias;
  54. struct device_node *np;
  55. int id;
  56. char stem[0];
  57. };
  58. int of_n_addr_cells(const struct device_node *np)
  59. {
  60. const __be32 *ip;
  61. do {
  62. if (np->parent)
  63. np = np->parent;
  64. ip = of_get_property(np, "#address-cells", NULL);
  65. if (ip)
  66. return be32_to_cpup(ip);
  67. } while (np->parent);
  68. /* No #address-cells property for the root node */
  69. return OF_ROOT_NODE_ADDR_CELLS_DEFAULT;
  70. }
  71. int of_n_size_cells(const struct device_node *np)
  72. {
  73. const __be32 *ip;
  74. do {
  75. if (np->parent)
  76. np = np->parent;
  77. ip = of_get_property(np, "#size-cells", NULL);
  78. if (ip)
  79. return be32_to_cpup(ip);
  80. } while (np->parent);
  81. /* No #size-cells property for the root node */
  82. return OF_ROOT_NODE_SIZE_CELLS_DEFAULT;
  83. }
  84. struct property *of_find_property(const struct device_node *np,
  85. const char *name, int *lenp)
  86. {
  87. struct property *pp;
  88. if (!np)
  89. return NULL;
  90. for (pp = np->properties; pp; pp = pp->next) {
  91. if (strcmp(pp->name, name) == 0) {
  92. if (lenp)
  93. *lenp = pp->length;
  94. break;
  95. }
  96. }
  97. if (!pp && lenp)
  98. *lenp = -FDT_ERR_NOTFOUND;
  99. return pp;
  100. }
  101. struct device_node *of_find_all_nodes(struct device_node *prev)
  102. {
  103. struct device_node *np;
  104. if (!prev) {
  105. np = gd->of_root;
  106. } else if (prev->child) {
  107. np = prev->child;
  108. } else {
  109. /*
  110. * Walk back up looking for a sibling, or the end of the
  111. * structure
  112. */
  113. np = prev;
  114. while (np->parent && !np->sibling)
  115. np = np->parent;
  116. np = np->sibling; /* Might be null at the end of the tree */
  117. }
  118. return np;
  119. }
  120. const void *of_get_property(const struct device_node *np, const char *name,
  121. int *lenp)
  122. {
  123. struct property *pp = of_find_property(np, name, lenp);
  124. return pp ? pp->value : NULL;
  125. }
  126. static const char *of_prop_next_string(struct property *prop, const char *cur)
  127. {
  128. const void *curv = cur;
  129. if (!prop)
  130. return NULL;
  131. if (!cur)
  132. return prop->value;
  133. curv += strlen(cur) + 1;
  134. if (curv >= prop->value + prop->length)
  135. return NULL;
  136. return curv;
  137. }
  138. int of_device_is_compatible(const struct device_node *device,
  139. const char *compat, const char *type,
  140. const char *name)
  141. {
  142. struct property *prop;
  143. const char *cp;
  144. int index = 0, score = 0;
  145. /* Compatible match has highest priority */
  146. if (compat && compat[0]) {
  147. prop = of_find_property(device, "compatible", NULL);
  148. for (cp = of_prop_next_string(prop, NULL); cp;
  149. cp = of_prop_next_string(prop, cp), index++) {
  150. if (of_compat_cmp(cp, compat, strlen(compat)) == 0) {
  151. score = INT_MAX/2 - (index << 2);
  152. break;
  153. }
  154. }
  155. if (!score)
  156. return 0;
  157. }
  158. /* Matching type is better than matching name */
  159. if (type && type[0]) {
  160. if (!device->type || of_node_cmp(type, device->type))
  161. return 0;
  162. score += 2;
  163. }
  164. /* Matching name is a bit better than not */
  165. if (name && name[0]) {
  166. if (!device->name || of_node_cmp(name, device->name))
  167. return 0;
  168. score++;
  169. }
  170. return score;
  171. }
  172. bool of_device_is_available(const struct device_node *device)
  173. {
  174. const char *status;
  175. int statlen;
  176. if (!device)
  177. return false;
  178. status = of_get_property(device, "status", &statlen);
  179. if (status == NULL)
  180. return true;
  181. if (statlen > 0) {
  182. if (!strcmp(status, "okay"))
  183. return true;
  184. }
  185. return false;
  186. }
  187. struct device_node *of_get_parent(const struct device_node *node)
  188. {
  189. const struct device_node *np;
  190. if (!node)
  191. return NULL;
  192. np = of_node_get(node->parent);
  193. return (struct device_node *)np;
  194. }
  195. static struct device_node *__of_get_next_child(const struct device_node *node,
  196. struct device_node *prev)
  197. {
  198. struct device_node *next;
  199. if (!node)
  200. return NULL;
  201. next = prev ? prev->sibling : node->child;
  202. for (; next; next = next->sibling)
  203. if (of_node_get(next))
  204. break;
  205. of_node_put(prev);
  206. return next;
  207. }
  208. #define __for_each_child_of_node(parent, child) \
  209. for (child = __of_get_next_child(parent, NULL); child != NULL; \
  210. child = __of_get_next_child(parent, child))
  211. static struct device_node *__of_find_node_by_path(struct device_node *parent,
  212. const char *path)
  213. {
  214. struct device_node *child;
  215. int len;
  216. len = strcspn(path, "/:");
  217. if (!len)
  218. return NULL;
  219. __for_each_child_of_node(parent, child) {
  220. const char *name = strrchr(child->full_name, '/');
  221. name++;
  222. if (strncmp(path, name, len) == 0 && (strlen(name) == len))
  223. return child;
  224. }
  225. return NULL;
  226. }
  227. #define for_each_property_of_node(dn, pp) \
  228. for (pp = dn->properties; pp != NULL; pp = pp->next)
  229. struct device_node *of_find_node_opts_by_path(const char *path,
  230. const char **opts)
  231. {
  232. struct device_node *np = NULL;
  233. struct property *pp;
  234. const char *separator = strchr(path, ':');
  235. if (opts)
  236. *opts = separator ? separator + 1 : NULL;
  237. if (strcmp(path, "/") == 0)
  238. return of_node_get(gd->of_root);
  239. /* The path could begin with an alias */
  240. if (*path != '/') {
  241. int len;
  242. const char *p = separator;
  243. if (!p)
  244. p = strchrnul(path, '/');
  245. len = p - path;
  246. /* of_aliases must not be NULL */
  247. if (!of_aliases)
  248. return NULL;
  249. for_each_property_of_node(of_aliases, pp) {
  250. if (strlen(pp->name) == len && !strncmp(pp->name, path,
  251. len)) {
  252. np = of_find_node_by_path(pp->value);
  253. break;
  254. }
  255. }
  256. if (!np)
  257. return NULL;
  258. path = p;
  259. }
  260. /* Step down the tree matching path components */
  261. if (!np)
  262. np = of_node_get(gd->of_root);
  263. while (np && *path == '/') {
  264. struct device_node *tmp = np;
  265. path++; /* Increment past '/' delimiter */
  266. np = __of_find_node_by_path(np, path);
  267. of_node_put(tmp);
  268. path = strchrnul(path, '/');
  269. if (separator && separator < path)
  270. break;
  271. }
  272. return np;
  273. }
  274. struct device_node *of_find_compatible_node(struct device_node *from,
  275. const char *type, const char *compatible)
  276. {
  277. struct device_node *np;
  278. for_each_of_allnodes_from(from, np)
  279. if (of_device_is_compatible(np, compatible, type, NULL) &&
  280. of_node_get(np))
  281. break;
  282. of_node_put(from);
  283. return np;
  284. }
  285. struct device_node *of_find_node_by_phandle(phandle handle)
  286. {
  287. struct device_node *np;
  288. if (!handle)
  289. return NULL;
  290. for_each_of_allnodes(np)
  291. if (np->phandle == handle)
  292. break;
  293. (void)of_node_get(np);
  294. return np;
  295. }
  296. /**
  297. * of_find_property_value_of_size() - find property of given size
  298. *
  299. * Search for a property in a device node and validate the requested size.
  300. *
  301. * @np: device node from which the property value is to be read.
  302. * @propname: name of the property to be searched.
  303. * @len: requested length of property value
  304. *
  305. * @return the property value on success, -EINVAL if the property does not
  306. * exist, -ENODATA if property does not have a value, and -EOVERFLOW if the
  307. * property data isn't large enough.
  308. */
  309. static void *of_find_property_value_of_size(const struct device_node *np,
  310. const char *propname, u32 len)
  311. {
  312. struct property *prop = of_find_property(np, propname, NULL);
  313. if (!prop)
  314. return ERR_PTR(-EINVAL);
  315. if (!prop->value)
  316. return ERR_PTR(-ENODATA);
  317. if (len > prop->length)
  318. return ERR_PTR(-EOVERFLOW);
  319. return prop->value;
  320. }
  321. int of_read_u32(const struct device_node *np, const char *propname, u32 *outp)
  322. {
  323. const __be32 *val;
  324. debug("%s: %s: ", __func__, propname);
  325. if (!np)
  326. return -EINVAL;
  327. val = of_find_property_value_of_size(np, propname, sizeof(*outp));
  328. if (IS_ERR(val)) {
  329. debug("(not found)\n");
  330. return PTR_ERR(val);
  331. }
  332. *outp = be32_to_cpup(val);
  333. debug("%#x (%d)\n", *outp, *outp);
  334. return 0;
  335. }
  336. int of_read_u32_array(const struct device_node *np, const char *propname,
  337. u32 *out_values, size_t sz)
  338. {
  339. const __be32 *val;
  340. debug("%s: %s: ", __func__, propname);
  341. val = of_find_property_value_of_size(np, propname,
  342. sz * sizeof(*out_values));
  343. if (IS_ERR(val))
  344. return PTR_ERR(val);
  345. debug("size %zd\n", sz);
  346. while (sz--)
  347. *out_values++ = be32_to_cpup(val++);
  348. return 0;
  349. }
  350. int of_property_match_string(const struct device_node *np, const char *propname,
  351. const char *string)
  352. {
  353. const struct property *prop = of_find_property(np, propname, NULL);
  354. size_t l;
  355. int i;
  356. const char *p, *end;
  357. if (!prop)
  358. return -EINVAL;
  359. if (!prop->value)
  360. return -ENODATA;
  361. p = prop->value;
  362. end = p + prop->length;
  363. for (i = 0; p < end; i++, p += l) {
  364. l = strnlen(p, end - p) + 1;
  365. if (p + l > end)
  366. return -EILSEQ;
  367. debug("comparing %s with %s\n", string, p);
  368. if (strcmp(string, p) == 0)
  369. return i; /* Found it; return index */
  370. }
  371. return -ENODATA;
  372. }
  373. /**
  374. * of_property_read_string_helper() - Utility helper for parsing string properties
  375. * @np: device node from which the property value is to be read.
  376. * @propname: name of the property to be searched.
  377. * @out_strs: output array of string pointers.
  378. * @sz: number of array elements to read.
  379. * @skip: Number of strings to skip over at beginning of list.
  380. *
  381. * Don't call this function directly. It is a utility helper for the
  382. * of_property_read_string*() family of functions.
  383. */
  384. int of_property_read_string_helper(const struct device_node *np,
  385. const char *propname, const char **out_strs,
  386. size_t sz, int skip)
  387. {
  388. const struct property *prop = of_find_property(np, propname, NULL);
  389. int l = 0, i = 0;
  390. const char *p, *end;
  391. if (!prop)
  392. return -EINVAL;
  393. if (!prop->value)
  394. return -ENODATA;
  395. p = prop->value;
  396. end = p + prop->length;
  397. for (i = 0; p < end && (!out_strs || i < skip + sz); i++, p += l) {
  398. l = strnlen(p, end - p) + 1;
  399. if (p + l > end)
  400. return -EILSEQ;
  401. if (out_strs && i >= skip)
  402. *out_strs++ = p;
  403. }
  404. i -= skip;
  405. return i <= 0 ? -ENODATA : i;
  406. }
  407. static int __of_parse_phandle_with_args(const struct device_node *np,
  408. const char *list_name,
  409. const char *cells_name,
  410. int cell_count, int index,
  411. struct of_phandle_args *out_args)
  412. {
  413. const __be32 *list, *list_end;
  414. int rc = 0, cur_index = 0;
  415. uint32_t count = 0;
  416. struct device_node *node = NULL;
  417. phandle phandle;
  418. int size;
  419. /* Retrieve the phandle list property */
  420. list = of_get_property(np, list_name, &size);
  421. if (!list)
  422. return -ENOENT;
  423. list_end = list + size / sizeof(*list);
  424. /* Loop over the phandles until all the requested entry is found */
  425. while (list < list_end) {
  426. rc = -EINVAL;
  427. count = 0;
  428. /*
  429. * If phandle is 0, then it is an empty entry with no
  430. * arguments. Skip forward to the next entry.
  431. */
  432. phandle = be32_to_cpup(list++);
  433. if (phandle) {
  434. /*
  435. * Find the provider node and parse the #*-cells
  436. * property to determine the argument length.
  437. *
  438. * This is not needed if the cell count is hard-coded
  439. * (i.e. cells_name not set, but cell_count is set),
  440. * except when we're going to return the found node
  441. * below.
  442. */
  443. if (cells_name || cur_index == index) {
  444. node = of_find_node_by_phandle(phandle);
  445. if (!node) {
  446. debug("%s: could not find phandle\n",
  447. np->full_name);
  448. goto err;
  449. }
  450. }
  451. if (cells_name) {
  452. if (of_read_u32(node, cells_name, &count)) {
  453. debug("%s: could not get %s for %s\n",
  454. np->full_name, cells_name,
  455. node->full_name);
  456. goto err;
  457. }
  458. } else {
  459. count = cell_count;
  460. }
  461. /*
  462. * Make sure that the arguments actually fit in the
  463. * remaining property data length
  464. */
  465. if (list + count > list_end) {
  466. debug("%s: arguments longer than property\n",
  467. np->full_name);
  468. goto err;
  469. }
  470. }
  471. /*
  472. * All of the error cases above bail out of the loop, so at
  473. * this point, the parsing is successful. If the requested
  474. * index matches, then fill the out_args structure and return,
  475. * or return -ENOENT for an empty entry.
  476. */
  477. rc = -ENOENT;
  478. if (cur_index == index) {
  479. if (!phandle)
  480. goto err;
  481. if (out_args) {
  482. int i;
  483. if (WARN_ON(count > OF_MAX_PHANDLE_ARGS))
  484. count = OF_MAX_PHANDLE_ARGS;
  485. out_args->np = node;
  486. out_args->args_count = count;
  487. for (i = 0; i < count; i++)
  488. out_args->args[i] =
  489. be32_to_cpup(list++);
  490. } else {
  491. of_node_put(node);
  492. }
  493. /* Found it! return success */
  494. return 0;
  495. }
  496. of_node_put(node);
  497. node = NULL;
  498. list += count;
  499. cur_index++;
  500. }
  501. /*
  502. * Unlock node before returning result; will be one of:
  503. * -ENOENT : index is for empty phandle
  504. * -EINVAL : parsing error on data
  505. * [1..n] : Number of phandle (count mode; when index = -1)
  506. */
  507. rc = index < 0 ? cur_index : -ENOENT;
  508. err:
  509. if (node)
  510. of_node_put(node);
  511. return rc;
  512. }
  513. struct device_node *of_parse_phandle(const struct device_node *np,
  514. const char *phandle_name, int index)
  515. {
  516. struct of_phandle_args args;
  517. if (index < 0)
  518. return NULL;
  519. if (__of_parse_phandle_with_args(np, phandle_name, NULL, 0, index,
  520. &args))
  521. return NULL;
  522. return args.np;
  523. }
  524. int of_parse_phandle_with_args(const struct device_node *np,
  525. const char *list_name, const char *cells_name,
  526. int index, struct of_phandle_args *out_args)
  527. {
  528. if (index < 0)
  529. return -EINVAL;
  530. return __of_parse_phandle_with_args(np, list_name, cells_name, 0,
  531. index, out_args);
  532. }
  533. static void of_alias_add(struct alias_prop *ap, struct device_node *np,
  534. int id, const char *stem, int stem_len)
  535. {
  536. ap->np = np;
  537. ap->id = id;
  538. strncpy(ap->stem, stem, stem_len);
  539. ap->stem[stem_len] = 0;
  540. list_add_tail(&ap->link, &aliases_lookup);
  541. debug("adding DT alias:%s: stem=%s id=%i node=%s\n",
  542. ap->alias, ap->stem, ap->id, of_node_full_name(np));
  543. }
  544. int of_alias_scan(void)
  545. {
  546. struct property *pp;
  547. of_aliases = of_find_node_by_path("/aliases");
  548. of_chosen = of_find_node_by_path("/chosen");
  549. if (of_chosen == NULL)
  550. of_chosen = of_find_node_by_path("/chosen@0");
  551. if (of_chosen) {
  552. const char *name;
  553. name = of_get_property(of_chosen, "stdout-path", NULL);
  554. if (name)
  555. of_stdout = of_find_node_opts_by_path(name,
  556. &of_stdout_options);
  557. }
  558. if (!of_aliases)
  559. return 0;
  560. for_each_property_of_node(of_aliases, pp) {
  561. const char *start = pp->name;
  562. const char *end = start + strlen(start);
  563. struct device_node *np;
  564. struct alias_prop *ap;
  565. ulong id;
  566. int len;
  567. /* Skip those we do not want to proceed */
  568. if (!strcmp(pp->name, "name") ||
  569. !strcmp(pp->name, "phandle") ||
  570. !strcmp(pp->name, "linux,phandle"))
  571. continue;
  572. np = of_find_node_by_path(pp->value);
  573. if (!np)
  574. continue;
  575. /*
  576. * walk the alias backwards to extract the id and work out
  577. * the 'stem' string
  578. */
  579. while (isdigit(*(end-1)) && end > start)
  580. end--;
  581. len = end - start;
  582. if (strict_strtoul(end, 10, &id) < 0)
  583. continue;
  584. /* Allocate an alias_prop with enough space for the stem */
  585. ap = malloc(sizeof(*ap) + len + 1);
  586. if (!ap)
  587. return -ENOMEM;
  588. memset(ap, 0, sizeof(*ap) + len + 1);
  589. ap->alias = start;
  590. of_alias_add(ap, np, id, start, len);
  591. }
  592. return 0;
  593. }
  594. int of_alias_get_id(const struct device_node *np, const char *stem)
  595. {
  596. struct alias_prop *app;
  597. int id = -ENODEV;
  598. mutex_lock(&of_mutex);
  599. list_for_each_entry(app, &aliases_lookup, link) {
  600. if (strcmp(app->stem, stem) != 0)
  601. continue;
  602. if (np == app->np) {
  603. id = app->id;
  604. break;
  605. }
  606. }
  607. mutex_unlock(&of_mutex);
  608. return id;
  609. }
  610. struct device_node *of_get_stdout(void)
  611. {
  612. return of_stdout;
  613. }