property.c 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341
  1. /*
  2. * property.c - Unified device property interface.
  3. *
  4. * Copyright (C) 2014, Intel Corporation
  5. * Authors: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  6. * Mika Westerberg <mika.westerberg@linux.intel.com>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License version 2 as
  10. * published by the Free Software Foundation.
  11. */
  12. #include <linux/acpi.h>
  13. #include <linux/export.h>
  14. #include <linux/kernel.h>
  15. #include <linux/of.h>
  16. #include <linux/of_address.h>
  17. #include <linux/of_graph.h>
  18. #include <linux/property.h>
  19. #include <linux/etherdevice.h>
  20. #include <linux/phy.h>
  21. struct property_set {
  22. struct fwnode_handle fwnode;
  23. const struct property_entry *properties;
  24. };
  25. static inline bool is_pset_node(struct fwnode_handle *fwnode)
  26. {
  27. return !IS_ERR_OR_NULL(fwnode) && fwnode->type == FWNODE_PDATA;
  28. }
  29. static inline struct property_set *to_pset_node(struct fwnode_handle *fwnode)
  30. {
  31. return is_pset_node(fwnode) ?
  32. container_of(fwnode, struct property_set, fwnode) : NULL;
  33. }
  34. static const struct property_entry *pset_prop_get(struct property_set *pset,
  35. const char *name)
  36. {
  37. const struct property_entry *prop;
  38. if (!pset || !pset->properties)
  39. return NULL;
  40. for (prop = pset->properties; prop->name; prop++)
  41. if (!strcmp(name, prop->name))
  42. return prop;
  43. return NULL;
  44. }
  45. static const void *pset_prop_find(struct property_set *pset,
  46. const char *propname, size_t length)
  47. {
  48. const struct property_entry *prop;
  49. const void *pointer;
  50. prop = pset_prop_get(pset, propname);
  51. if (!prop)
  52. return ERR_PTR(-EINVAL);
  53. if (prop->is_array)
  54. pointer = prop->pointer.raw_data;
  55. else
  56. pointer = &prop->value.raw_data;
  57. if (!pointer)
  58. return ERR_PTR(-ENODATA);
  59. if (length > prop->length)
  60. return ERR_PTR(-EOVERFLOW);
  61. return pointer;
  62. }
  63. static int pset_prop_read_u8_array(struct property_set *pset,
  64. const char *propname,
  65. u8 *values, size_t nval)
  66. {
  67. const void *pointer;
  68. size_t length = nval * sizeof(*values);
  69. pointer = pset_prop_find(pset, propname, length);
  70. if (IS_ERR(pointer))
  71. return PTR_ERR(pointer);
  72. memcpy(values, pointer, length);
  73. return 0;
  74. }
  75. static int pset_prop_read_u16_array(struct property_set *pset,
  76. const char *propname,
  77. u16 *values, size_t nval)
  78. {
  79. const void *pointer;
  80. size_t length = nval * sizeof(*values);
  81. pointer = pset_prop_find(pset, propname, length);
  82. if (IS_ERR(pointer))
  83. return PTR_ERR(pointer);
  84. memcpy(values, pointer, length);
  85. return 0;
  86. }
  87. static int pset_prop_read_u32_array(struct property_set *pset,
  88. const char *propname,
  89. u32 *values, size_t nval)
  90. {
  91. const void *pointer;
  92. size_t length = nval * sizeof(*values);
  93. pointer = pset_prop_find(pset, propname, length);
  94. if (IS_ERR(pointer))
  95. return PTR_ERR(pointer);
  96. memcpy(values, pointer, length);
  97. return 0;
  98. }
  99. static int pset_prop_read_u64_array(struct property_set *pset,
  100. const char *propname,
  101. u64 *values, size_t nval)
  102. {
  103. const void *pointer;
  104. size_t length = nval * sizeof(*values);
  105. pointer = pset_prop_find(pset, propname, length);
  106. if (IS_ERR(pointer))
  107. return PTR_ERR(pointer);
  108. memcpy(values, pointer, length);
  109. return 0;
  110. }
  111. static int pset_prop_count_elems_of_size(struct property_set *pset,
  112. const char *propname, size_t length)
  113. {
  114. const struct property_entry *prop;
  115. prop = pset_prop_get(pset, propname);
  116. if (!prop)
  117. return -EINVAL;
  118. return prop->length / length;
  119. }
  120. static int pset_prop_read_string_array(struct property_set *pset,
  121. const char *propname,
  122. const char **strings, size_t nval)
  123. {
  124. const struct property_entry *prop;
  125. const void *pointer;
  126. size_t array_len, length;
  127. /* Find out the array length. */
  128. prop = pset_prop_get(pset, propname);
  129. if (!prop)
  130. return -EINVAL;
  131. if (!prop->is_array)
  132. /* The array length for a non-array string property is 1. */
  133. array_len = 1;
  134. else
  135. /* Find the length of an array. */
  136. array_len = pset_prop_count_elems_of_size(pset, propname,
  137. sizeof(const char *));
  138. /* Return how many there are if strings is NULL. */
  139. if (!strings)
  140. return array_len;
  141. array_len = min(nval, array_len);
  142. length = array_len * sizeof(*strings);
  143. pointer = pset_prop_find(pset, propname, length);
  144. if (IS_ERR(pointer))
  145. return PTR_ERR(pointer);
  146. memcpy(strings, pointer, length);
  147. return array_len;
  148. }
  149. struct fwnode_handle *dev_fwnode(struct device *dev)
  150. {
  151. return IS_ENABLED(CONFIG_OF) && dev->of_node ?
  152. &dev->of_node->fwnode : dev->fwnode;
  153. }
  154. EXPORT_SYMBOL_GPL(dev_fwnode);
  155. /**
  156. * device_property_present - check if a property of a device is present
  157. * @dev: Device whose property is being checked
  158. * @propname: Name of the property
  159. *
  160. * Check if property @propname is present in the device firmware description.
  161. */
  162. bool device_property_present(struct device *dev, const char *propname)
  163. {
  164. return fwnode_property_present(dev_fwnode(dev), propname);
  165. }
  166. EXPORT_SYMBOL_GPL(device_property_present);
  167. static bool __fwnode_property_present(struct fwnode_handle *fwnode,
  168. const char *propname)
  169. {
  170. if (is_of_node(fwnode))
  171. return of_property_read_bool(to_of_node(fwnode), propname);
  172. else if (is_acpi_node(fwnode))
  173. return !acpi_node_prop_get(fwnode, propname, NULL);
  174. else if (is_pset_node(fwnode))
  175. return !!pset_prop_get(to_pset_node(fwnode), propname);
  176. return false;
  177. }
  178. /**
  179. * fwnode_property_present - check if a property of a firmware node is present
  180. * @fwnode: Firmware node whose property to check
  181. * @propname: Name of the property
  182. */
  183. bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname)
  184. {
  185. bool ret;
  186. ret = __fwnode_property_present(fwnode, propname);
  187. if (ret == false && !IS_ERR_OR_NULL(fwnode) &&
  188. !IS_ERR_OR_NULL(fwnode->secondary))
  189. ret = __fwnode_property_present(fwnode->secondary, propname);
  190. return ret;
  191. }
  192. EXPORT_SYMBOL_GPL(fwnode_property_present);
  193. /**
  194. * device_property_read_u8_array - return a u8 array property of a device
  195. * @dev: Device to get the property of
  196. * @propname: Name of the property
  197. * @val: The values are stored here or %NULL to return the number of values
  198. * @nval: Size of the @val array
  199. *
  200. * Function reads an array of u8 properties with @propname from the device
  201. * firmware description and stores them to @val if found.
  202. *
  203. * Return: number of values if @val was %NULL,
  204. * %0 if the property was found (success),
  205. * %-EINVAL if given arguments are not valid,
  206. * %-ENODATA if the property does not have a value,
  207. * %-EPROTO if the property is not an array of numbers,
  208. * %-EOVERFLOW if the size of the property is not as expected.
  209. * %-ENXIO if no suitable firmware interface is present.
  210. */
  211. int device_property_read_u8_array(struct device *dev, const char *propname,
  212. u8 *val, size_t nval)
  213. {
  214. return fwnode_property_read_u8_array(dev_fwnode(dev), propname, val, nval);
  215. }
  216. EXPORT_SYMBOL_GPL(device_property_read_u8_array);
  217. /**
  218. * device_property_read_u16_array - return a u16 array property of a device
  219. * @dev: Device to get the property of
  220. * @propname: Name of the property
  221. * @val: The values are stored here or %NULL to return the number of values
  222. * @nval: Size of the @val array
  223. *
  224. * Function reads an array of u16 properties with @propname from the device
  225. * firmware description and stores them to @val if found.
  226. *
  227. * Return: number of values if @val was %NULL,
  228. * %0 if the property was found (success),
  229. * %-EINVAL if given arguments are not valid,
  230. * %-ENODATA if the property does not have a value,
  231. * %-EPROTO if the property is not an array of numbers,
  232. * %-EOVERFLOW if the size of the property is not as expected.
  233. * %-ENXIO if no suitable firmware interface is present.
  234. */
  235. int device_property_read_u16_array(struct device *dev, const char *propname,
  236. u16 *val, size_t nval)
  237. {
  238. return fwnode_property_read_u16_array(dev_fwnode(dev), propname, val, nval);
  239. }
  240. EXPORT_SYMBOL_GPL(device_property_read_u16_array);
  241. /**
  242. * device_property_read_u32_array - return a u32 array property of a device
  243. * @dev: Device to get the property of
  244. * @propname: Name of the property
  245. * @val: The values are stored here or %NULL to return the number of values
  246. * @nval: Size of the @val array
  247. *
  248. * Function reads an array of u32 properties with @propname from the device
  249. * firmware description and stores them to @val if found.
  250. *
  251. * Return: number of values if @val was %NULL,
  252. * %0 if the property was found (success),
  253. * %-EINVAL if given arguments are not valid,
  254. * %-ENODATA if the property does not have a value,
  255. * %-EPROTO if the property is not an array of numbers,
  256. * %-EOVERFLOW if the size of the property is not as expected.
  257. * %-ENXIO if no suitable firmware interface is present.
  258. */
  259. int device_property_read_u32_array(struct device *dev, const char *propname,
  260. u32 *val, size_t nval)
  261. {
  262. return fwnode_property_read_u32_array(dev_fwnode(dev), propname, val, nval);
  263. }
  264. EXPORT_SYMBOL_GPL(device_property_read_u32_array);
  265. /**
  266. * device_property_read_u64_array - return a u64 array property of a device
  267. * @dev: Device to get the property of
  268. * @propname: Name of the property
  269. * @val: The values are stored here or %NULL to return the number of values
  270. * @nval: Size of the @val array
  271. *
  272. * Function reads an array of u64 properties with @propname from the device
  273. * firmware description and stores them to @val if found.
  274. *
  275. * Return: number of values if @val was %NULL,
  276. * %0 if the property was found (success),
  277. * %-EINVAL if given arguments are not valid,
  278. * %-ENODATA if the property does not have a value,
  279. * %-EPROTO if the property is not an array of numbers,
  280. * %-EOVERFLOW if the size of the property is not as expected.
  281. * %-ENXIO if no suitable firmware interface is present.
  282. */
  283. int device_property_read_u64_array(struct device *dev, const char *propname,
  284. u64 *val, size_t nval)
  285. {
  286. return fwnode_property_read_u64_array(dev_fwnode(dev), propname, val, nval);
  287. }
  288. EXPORT_SYMBOL_GPL(device_property_read_u64_array);
  289. /**
  290. * device_property_read_string_array - return a string array property of device
  291. * @dev: Device to get the property of
  292. * @propname: Name of the property
  293. * @val: The values are stored here or %NULL to return the number of values
  294. * @nval: Size of the @val array
  295. *
  296. * Function reads an array of string properties with @propname from the device
  297. * firmware description and stores them to @val if found.
  298. *
  299. * Return: number of values read on success if @val is non-NULL,
  300. * number of values available on success if @val is NULL,
  301. * %-EINVAL if given arguments are not valid,
  302. * %-ENODATA if the property does not have a value,
  303. * %-EPROTO or %-EILSEQ if the property is not an array of strings,
  304. * %-EOVERFLOW if the size of the property is not as expected.
  305. * %-ENXIO if no suitable firmware interface is present.
  306. */
  307. int device_property_read_string_array(struct device *dev, const char *propname,
  308. const char **val, size_t nval)
  309. {
  310. return fwnode_property_read_string_array(dev_fwnode(dev), propname, val, nval);
  311. }
  312. EXPORT_SYMBOL_GPL(device_property_read_string_array);
  313. /**
  314. * device_property_read_string - return a string property of a device
  315. * @dev: Device to get the property of
  316. * @propname: Name of the property
  317. * @val: The value is stored here
  318. *
  319. * Function reads property @propname from the device firmware description and
  320. * stores the value into @val if found. The value is checked to be a string.
  321. *
  322. * Return: %0 if the property was found (success),
  323. * %-EINVAL if given arguments are not valid,
  324. * %-ENODATA if the property does not have a value,
  325. * %-EPROTO or %-EILSEQ if the property type is not a string.
  326. * %-ENXIO if no suitable firmware interface is present.
  327. */
  328. int device_property_read_string(struct device *dev, const char *propname,
  329. const char **val)
  330. {
  331. return fwnode_property_read_string(dev_fwnode(dev), propname, val);
  332. }
  333. EXPORT_SYMBOL_GPL(device_property_read_string);
  334. /**
  335. * device_property_match_string - find a string in an array and return index
  336. * @dev: Device to get the property of
  337. * @propname: Name of the property holding the array
  338. * @string: String to look for
  339. *
  340. * Find a given string in a string array and if it is found return the
  341. * index back.
  342. *
  343. * Return: %0 if the property was found (success),
  344. * %-EINVAL if given arguments are not valid,
  345. * %-ENODATA if the property does not have a value,
  346. * %-EPROTO if the property is not an array of strings,
  347. * %-ENXIO if no suitable firmware interface is present.
  348. */
  349. int device_property_match_string(struct device *dev, const char *propname,
  350. const char *string)
  351. {
  352. return fwnode_property_match_string(dev_fwnode(dev), propname, string);
  353. }
  354. EXPORT_SYMBOL_GPL(device_property_match_string);
  355. #define OF_DEV_PROP_READ_ARRAY(node, propname, type, val, nval) \
  356. (val) ? of_property_read_##type##_array((node), (propname), (val), (nval)) \
  357. : of_property_count_elems_of_size((node), (propname), sizeof(type))
  358. #define PSET_PROP_READ_ARRAY(node, propname, type, val, nval) \
  359. (val) ? pset_prop_read_##type##_array((node), (propname), (val), (nval)) \
  360. : pset_prop_count_elems_of_size((node), (propname), sizeof(type))
  361. #define FWNODE_PROP_READ(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \
  362. ({ \
  363. int _ret_; \
  364. if (is_of_node(_fwnode_)) \
  365. _ret_ = OF_DEV_PROP_READ_ARRAY(to_of_node(_fwnode_), _propname_, \
  366. _type_, _val_, _nval_); \
  367. else if (is_acpi_node(_fwnode_)) \
  368. _ret_ = acpi_node_prop_read(_fwnode_, _propname_, _proptype_, \
  369. _val_, _nval_); \
  370. else if (is_pset_node(_fwnode_)) \
  371. _ret_ = PSET_PROP_READ_ARRAY(to_pset_node(_fwnode_), _propname_, \
  372. _type_, _val_, _nval_); \
  373. else \
  374. _ret_ = -ENXIO; \
  375. _ret_; \
  376. })
  377. #define FWNODE_PROP_READ_ARRAY(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \
  378. ({ \
  379. int _ret_; \
  380. _ret_ = FWNODE_PROP_READ(_fwnode_, _propname_, _type_, _proptype_, \
  381. _val_, _nval_); \
  382. if (_ret_ == -EINVAL && !IS_ERR_OR_NULL(_fwnode_) && \
  383. !IS_ERR_OR_NULL(_fwnode_->secondary)) \
  384. _ret_ = FWNODE_PROP_READ(_fwnode_->secondary, _propname_, _type_, \
  385. _proptype_, _val_, _nval_); \
  386. _ret_; \
  387. })
  388. /**
  389. * fwnode_property_read_u8_array - return a u8 array property of firmware node
  390. * @fwnode: Firmware node to get the property of
  391. * @propname: Name of the property
  392. * @val: The values are stored here or %NULL to return the number of values
  393. * @nval: Size of the @val array
  394. *
  395. * Read an array of u8 properties with @propname from @fwnode and stores them to
  396. * @val if found.
  397. *
  398. * Return: number of values if @val was %NULL,
  399. * %0 if the property was found (success),
  400. * %-EINVAL if given arguments are not valid,
  401. * %-ENODATA if the property does not have a value,
  402. * %-EPROTO if the property is not an array of numbers,
  403. * %-EOVERFLOW if the size of the property is not as expected,
  404. * %-ENXIO if no suitable firmware interface is present.
  405. */
  406. int fwnode_property_read_u8_array(struct fwnode_handle *fwnode,
  407. const char *propname, u8 *val, size_t nval)
  408. {
  409. return FWNODE_PROP_READ_ARRAY(fwnode, propname, u8, DEV_PROP_U8,
  410. val, nval);
  411. }
  412. EXPORT_SYMBOL_GPL(fwnode_property_read_u8_array);
  413. /**
  414. * fwnode_property_read_u16_array - return a u16 array property of firmware node
  415. * @fwnode: Firmware node to get the property of
  416. * @propname: Name of the property
  417. * @val: The values are stored here or %NULL to return the number of values
  418. * @nval: Size of the @val array
  419. *
  420. * Read an array of u16 properties with @propname from @fwnode and store them to
  421. * @val if found.
  422. *
  423. * Return: number of values if @val was %NULL,
  424. * %0 if the property was found (success),
  425. * %-EINVAL if given arguments are not valid,
  426. * %-ENODATA if the property does not have a value,
  427. * %-EPROTO if the property is not an array of numbers,
  428. * %-EOVERFLOW if the size of the property is not as expected,
  429. * %-ENXIO if no suitable firmware interface is present.
  430. */
  431. int fwnode_property_read_u16_array(struct fwnode_handle *fwnode,
  432. const char *propname, u16 *val, size_t nval)
  433. {
  434. return FWNODE_PROP_READ_ARRAY(fwnode, propname, u16, DEV_PROP_U16,
  435. val, nval);
  436. }
  437. EXPORT_SYMBOL_GPL(fwnode_property_read_u16_array);
  438. /**
  439. * fwnode_property_read_u32_array - return a u32 array property of firmware node
  440. * @fwnode: Firmware node to get the property of
  441. * @propname: Name of the property
  442. * @val: The values are stored here or %NULL to return the number of values
  443. * @nval: Size of the @val array
  444. *
  445. * Read an array of u32 properties with @propname from @fwnode store them to
  446. * @val if found.
  447. *
  448. * Return: number of values if @val was %NULL,
  449. * %0 if the property was found (success),
  450. * %-EINVAL if given arguments are not valid,
  451. * %-ENODATA if the property does not have a value,
  452. * %-EPROTO if the property is not an array of numbers,
  453. * %-EOVERFLOW if the size of the property is not as expected,
  454. * %-ENXIO if no suitable firmware interface is present.
  455. */
  456. int fwnode_property_read_u32_array(struct fwnode_handle *fwnode,
  457. const char *propname, u32 *val, size_t nval)
  458. {
  459. return FWNODE_PROP_READ_ARRAY(fwnode, propname, u32, DEV_PROP_U32,
  460. val, nval);
  461. }
  462. EXPORT_SYMBOL_GPL(fwnode_property_read_u32_array);
  463. /**
  464. * fwnode_property_read_u64_array - return a u64 array property firmware node
  465. * @fwnode: Firmware node to get the property of
  466. * @propname: Name of the property
  467. * @val: The values are stored here or %NULL to return the number of values
  468. * @nval: Size of the @val array
  469. *
  470. * Read an array of u64 properties with @propname from @fwnode and store them to
  471. * @val if found.
  472. *
  473. * Return: number of values if @val was %NULL,
  474. * %0 if the property was found (success),
  475. * %-EINVAL if given arguments are not valid,
  476. * %-ENODATA if the property does not have a value,
  477. * %-EPROTO if the property is not an array of numbers,
  478. * %-EOVERFLOW if the size of the property is not as expected,
  479. * %-ENXIO if no suitable firmware interface is present.
  480. */
  481. int fwnode_property_read_u64_array(struct fwnode_handle *fwnode,
  482. const char *propname, u64 *val, size_t nval)
  483. {
  484. return FWNODE_PROP_READ_ARRAY(fwnode, propname, u64, DEV_PROP_U64,
  485. val, nval);
  486. }
  487. EXPORT_SYMBOL_GPL(fwnode_property_read_u64_array);
  488. static int __fwnode_property_read_string_array(struct fwnode_handle *fwnode,
  489. const char *propname,
  490. const char **val, size_t nval)
  491. {
  492. if (is_of_node(fwnode))
  493. return val ?
  494. of_property_read_string_array(to_of_node(fwnode),
  495. propname, val, nval) :
  496. of_property_count_strings(to_of_node(fwnode), propname);
  497. else if (is_acpi_node(fwnode))
  498. return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
  499. val, nval);
  500. else if (is_pset_node(fwnode))
  501. return pset_prop_read_string_array(to_pset_node(fwnode),
  502. propname, val, nval);
  503. return -ENXIO;
  504. }
  505. /**
  506. * fwnode_property_read_string_array - return string array property of a node
  507. * @fwnode: Firmware node to get the property of
  508. * @propname: Name of the property
  509. * @val: The values are stored here or %NULL to return the number of values
  510. * @nval: Size of the @val array
  511. *
  512. * Read an string list property @propname from the given firmware node and store
  513. * them to @val if found.
  514. *
  515. * Return: number of values read on success if @val is non-NULL,
  516. * number of values available on success if @val is NULL,
  517. * %-EINVAL if given arguments are not valid,
  518. * %-ENODATA if the property does not have a value,
  519. * %-EPROTO or %-EILSEQ if the property is not an array of strings,
  520. * %-EOVERFLOW if the size of the property is not as expected,
  521. * %-ENXIO if no suitable firmware interface is present.
  522. */
  523. int fwnode_property_read_string_array(struct fwnode_handle *fwnode,
  524. const char *propname, const char **val,
  525. size_t nval)
  526. {
  527. int ret;
  528. ret = __fwnode_property_read_string_array(fwnode, propname, val, nval);
  529. if (ret == -EINVAL && !IS_ERR_OR_NULL(fwnode) &&
  530. !IS_ERR_OR_NULL(fwnode->secondary))
  531. ret = __fwnode_property_read_string_array(fwnode->secondary,
  532. propname, val, nval);
  533. return ret;
  534. }
  535. EXPORT_SYMBOL_GPL(fwnode_property_read_string_array);
  536. /**
  537. * fwnode_property_read_string - return a string property of a firmware node
  538. * @fwnode: Firmware node to get the property of
  539. * @propname: Name of the property
  540. * @val: The value is stored here
  541. *
  542. * Read property @propname from the given firmware node and store the value into
  543. * @val if found. The value is checked to be a string.
  544. *
  545. * Return: %0 if the property was found (success),
  546. * %-EINVAL if given arguments are not valid,
  547. * %-ENODATA if the property does not have a value,
  548. * %-EPROTO or %-EILSEQ if the property is not a string,
  549. * %-ENXIO if no suitable firmware interface is present.
  550. */
  551. int fwnode_property_read_string(struct fwnode_handle *fwnode,
  552. const char *propname, const char **val)
  553. {
  554. int ret = fwnode_property_read_string_array(fwnode, propname, val, 1);
  555. return ret < 0 ? ret : 0;
  556. }
  557. EXPORT_SYMBOL_GPL(fwnode_property_read_string);
  558. /**
  559. * fwnode_property_match_string - find a string in an array and return index
  560. * @fwnode: Firmware node to get the property of
  561. * @propname: Name of the property holding the array
  562. * @string: String to look for
  563. *
  564. * Find a given string in a string array and if it is found return the
  565. * index back.
  566. *
  567. * Return: %0 if the property was found (success),
  568. * %-EINVAL if given arguments are not valid,
  569. * %-ENODATA if the property does not have a value,
  570. * %-EPROTO if the property is not an array of strings,
  571. * %-ENXIO if no suitable firmware interface is present.
  572. */
  573. int fwnode_property_match_string(struct fwnode_handle *fwnode,
  574. const char *propname, const char *string)
  575. {
  576. const char **values;
  577. int nval, ret;
  578. nval = fwnode_property_read_string_array(fwnode, propname, NULL, 0);
  579. if (nval < 0)
  580. return nval;
  581. if (nval == 0)
  582. return -ENODATA;
  583. values = kcalloc(nval, sizeof(*values), GFP_KERNEL);
  584. if (!values)
  585. return -ENOMEM;
  586. ret = fwnode_property_read_string_array(fwnode, propname, values, nval);
  587. if (ret < 0)
  588. goto out;
  589. ret = match_string(values, nval, string);
  590. if (ret < 0)
  591. ret = -ENODATA;
  592. out:
  593. kfree(values);
  594. return ret;
  595. }
  596. EXPORT_SYMBOL_GPL(fwnode_property_match_string);
  597. static int property_copy_string_array(struct property_entry *dst,
  598. const struct property_entry *src)
  599. {
  600. char **d;
  601. size_t nval = src->length / sizeof(*d);
  602. int i;
  603. d = kcalloc(nval, sizeof(*d), GFP_KERNEL);
  604. if (!d)
  605. return -ENOMEM;
  606. for (i = 0; i < nval; i++) {
  607. d[i] = kstrdup(src->pointer.str[i], GFP_KERNEL);
  608. if (!d[i] && src->pointer.str[i]) {
  609. while (--i >= 0)
  610. kfree(d[i]);
  611. kfree(d);
  612. return -ENOMEM;
  613. }
  614. }
  615. dst->pointer.raw_data = d;
  616. return 0;
  617. }
  618. static int property_entry_copy_data(struct property_entry *dst,
  619. const struct property_entry *src)
  620. {
  621. int error;
  622. dst->name = kstrdup(src->name, GFP_KERNEL);
  623. if (!dst->name)
  624. return -ENOMEM;
  625. if (src->is_array) {
  626. if (!src->length) {
  627. error = -ENODATA;
  628. goto out_free_name;
  629. }
  630. if (src->is_string) {
  631. error = property_copy_string_array(dst, src);
  632. if (error)
  633. goto out_free_name;
  634. } else {
  635. dst->pointer.raw_data = kmemdup(src->pointer.raw_data,
  636. src->length, GFP_KERNEL);
  637. if (!dst->pointer.raw_data) {
  638. error = -ENOMEM;
  639. goto out_free_name;
  640. }
  641. }
  642. } else if (src->is_string) {
  643. dst->value.str = kstrdup(src->value.str, GFP_KERNEL);
  644. if (!dst->value.str && src->value.str) {
  645. error = -ENOMEM;
  646. goto out_free_name;
  647. }
  648. } else {
  649. dst->value.raw_data = src->value.raw_data;
  650. }
  651. dst->length = src->length;
  652. dst->is_array = src->is_array;
  653. dst->is_string = src->is_string;
  654. return 0;
  655. out_free_name:
  656. kfree(dst->name);
  657. return error;
  658. }
  659. static void property_entry_free_data(const struct property_entry *p)
  660. {
  661. size_t i, nval;
  662. if (p->is_array) {
  663. if (p->is_string && p->pointer.str) {
  664. nval = p->length / sizeof(const char *);
  665. for (i = 0; i < nval; i++)
  666. kfree(p->pointer.str[i]);
  667. }
  668. kfree(p->pointer.raw_data);
  669. } else if (p->is_string) {
  670. kfree(p->value.str);
  671. }
  672. kfree(p->name);
  673. }
  674. /**
  675. * property_entries_dup - duplicate array of properties
  676. * @properties: array of properties to copy
  677. *
  678. * This function creates a deep copy of the given NULL-terminated array
  679. * of property entries.
  680. */
  681. struct property_entry *
  682. property_entries_dup(const struct property_entry *properties)
  683. {
  684. struct property_entry *p;
  685. int i, n = 0;
  686. while (properties[n].name)
  687. n++;
  688. p = kcalloc(n + 1, sizeof(*p), GFP_KERNEL);
  689. if (!p)
  690. return ERR_PTR(-ENOMEM);
  691. for (i = 0; i < n; i++) {
  692. int ret = property_entry_copy_data(&p[i], &properties[i]);
  693. if (ret) {
  694. while (--i >= 0)
  695. property_entry_free_data(&p[i]);
  696. kfree(p);
  697. return ERR_PTR(ret);
  698. }
  699. }
  700. return p;
  701. }
  702. EXPORT_SYMBOL_GPL(property_entries_dup);
  703. /**
  704. * property_entries_free - free previously allocated array of properties
  705. * @properties: array of properties to destroy
  706. *
  707. * This function frees given NULL-terminated array of property entries,
  708. * along with their data.
  709. */
  710. void property_entries_free(const struct property_entry *properties)
  711. {
  712. const struct property_entry *p;
  713. for (p = properties; p->name; p++)
  714. property_entry_free_data(p);
  715. kfree(properties);
  716. }
  717. EXPORT_SYMBOL_GPL(property_entries_free);
  718. /**
  719. * pset_free_set - releases memory allocated for copied property set
  720. * @pset: Property set to release
  721. *
  722. * Function takes previously copied property set and releases all the
  723. * memory allocated to it.
  724. */
  725. static void pset_free_set(struct property_set *pset)
  726. {
  727. if (!pset)
  728. return;
  729. property_entries_free(pset->properties);
  730. kfree(pset);
  731. }
  732. /**
  733. * pset_copy_set - copies property set
  734. * @pset: Property set to copy
  735. *
  736. * This function takes a deep copy of the given property set and returns
  737. * pointer to the copy. Call device_free_property_set() to free resources
  738. * allocated in this function.
  739. *
  740. * Return: Pointer to the new property set or error pointer.
  741. */
  742. static struct property_set *pset_copy_set(const struct property_set *pset)
  743. {
  744. struct property_entry *properties;
  745. struct property_set *p;
  746. p = kzalloc(sizeof(*p), GFP_KERNEL);
  747. if (!p)
  748. return ERR_PTR(-ENOMEM);
  749. properties = property_entries_dup(pset->properties);
  750. if (IS_ERR(properties)) {
  751. kfree(p);
  752. return ERR_CAST(properties);
  753. }
  754. p->properties = properties;
  755. return p;
  756. }
  757. /**
  758. * device_remove_properties - Remove properties from a device object.
  759. * @dev: Device whose properties to remove.
  760. *
  761. * The function removes properties previously associated to the device
  762. * secondary firmware node with device_add_properties(). Memory allocated
  763. * to the properties will also be released.
  764. */
  765. void device_remove_properties(struct device *dev)
  766. {
  767. struct fwnode_handle *fwnode;
  768. fwnode = dev_fwnode(dev);
  769. if (!fwnode)
  770. return;
  771. /*
  772. * Pick either primary or secondary node depending which one holds
  773. * the pset. If there is no real firmware node (ACPI/DT) primary
  774. * will hold the pset.
  775. */
  776. if (is_pset_node(fwnode)) {
  777. set_primary_fwnode(dev, NULL);
  778. pset_free_set(to_pset_node(fwnode));
  779. } else {
  780. fwnode = fwnode->secondary;
  781. if (!IS_ERR(fwnode) && is_pset_node(fwnode)) {
  782. set_secondary_fwnode(dev, NULL);
  783. pset_free_set(to_pset_node(fwnode));
  784. }
  785. }
  786. }
  787. EXPORT_SYMBOL_GPL(device_remove_properties);
  788. /**
  789. * device_add_properties - Add a collection of properties to a device object.
  790. * @dev: Device to add properties to.
  791. * @properties: Collection of properties to add.
  792. *
  793. * Associate a collection of device properties represented by @properties with
  794. * @dev as its secondary firmware node. The function takes a copy of
  795. * @properties.
  796. */
  797. int device_add_properties(struct device *dev,
  798. const struct property_entry *properties)
  799. {
  800. struct property_set *p, pset;
  801. if (!properties)
  802. return -EINVAL;
  803. pset.properties = properties;
  804. p = pset_copy_set(&pset);
  805. if (IS_ERR(p))
  806. return PTR_ERR(p);
  807. p->fwnode.type = FWNODE_PDATA;
  808. set_secondary_fwnode(dev, &p->fwnode);
  809. return 0;
  810. }
  811. EXPORT_SYMBOL_GPL(device_add_properties);
  812. /**
  813. * fwnode_get_next_parent - Iterate to the node's parent
  814. * @fwnode: Firmware whose parent is retrieved
  815. *
  816. * This is like fwnode_get_parent() except that it drops the refcount
  817. * on the passed node, making it suitable for iterating through a
  818. * node's parents.
  819. *
  820. * Returns a node pointer with refcount incremented, use
  821. * fwnode_handle_node() on it when done.
  822. */
  823. struct fwnode_handle *fwnode_get_next_parent(struct fwnode_handle *fwnode)
  824. {
  825. struct fwnode_handle *parent = fwnode_get_parent(fwnode);
  826. fwnode_handle_put(fwnode);
  827. return parent;
  828. }
  829. EXPORT_SYMBOL_GPL(fwnode_get_next_parent);
  830. /**
  831. * fwnode_get_parent - Return parent firwmare node
  832. * @fwnode: Firmware whose parent is retrieved
  833. *
  834. * Return parent firmware node of the given node if possible or %NULL if no
  835. * parent was available.
  836. */
  837. struct fwnode_handle *fwnode_get_parent(struct fwnode_handle *fwnode)
  838. {
  839. struct fwnode_handle *parent = NULL;
  840. if (is_of_node(fwnode)) {
  841. struct device_node *node;
  842. node = of_get_parent(to_of_node(fwnode));
  843. if (node)
  844. parent = &node->fwnode;
  845. } else if (is_acpi_node(fwnode)) {
  846. parent = acpi_node_get_parent(fwnode);
  847. }
  848. return parent;
  849. }
  850. EXPORT_SYMBOL_GPL(fwnode_get_parent);
  851. /**
  852. * fwnode_get_next_child_node - Return the next child node handle for a node
  853. * @fwnode: Firmware node to find the next child node for.
  854. * @child: Handle to one of the node's child nodes or a %NULL handle.
  855. */
  856. struct fwnode_handle *fwnode_get_next_child_node(struct fwnode_handle *fwnode,
  857. struct fwnode_handle *child)
  858. {
  859. if (is_of_node(fwnode)) {
  860. struct device_node *node;
  861. node = of_get_next_available_child(to_of_node(fwnode),
  862. to_of_node(child));
  863. if (node)
  864. return &node->fwnode;
  865. } else if (is_acpi_node(fwnode)) {
  866. return acpi_get_next_subnode(fwnode, child);
  867. }
  868. return NULL;
  869. }
  870. EXPORT_SYMBOL_GPL(fwnode_get_next_child_node);
  871. /**
  872. * device_get_next_child_node - Return the next child node handle for a device
  873. * @dev: Device to find the next child node for.
  874. * @child: Handle to one of the device's child nodes or a null handle.
  875. */
  876. struct fwnode_handle *device_get_next_child_node(struct device *dev,
  877. struct fwnode_handle *child)
  878. {
  879. struct acpi_device *adev = ACPI_COMPANION(dev);
  880. struct fwnode_handle *fwnode = NULL;
  881. if (dev->of_node)
  882. fwnode = &dev->of_node->fwnode;
  883. else if (adev)
  884. fwnode = acpi_fwnode_handle(adev);
  885. return fwnode_get_next_child_node(fwnode, child);
  886. }
  887. EXPORT_SYMBOL_GPL(device_get_next_child_node);
  888. /**
  889. * fwnode_get_named_child_node - Return first matching named child node handle
  890. * @fwnode: Firmware node to find the named child node for.
  891. * @childname: String to match child node name against.
  892. */
  893. struct fwnode_handle *fwnode_get_named_child_node(struct fwnode_handle *fwnode,
  894. const char *childname)
  895. {
  896. struct fwnode_handle *child;
  897. /*
  898. * Find first matching named child node of this fwnode.
  899. * For ACPI this will be a data only sub-node.
  900. */
  901. fwnode_for_each_child_node(fwnode, child) {
  902. if (is_of_node(child)) {
  903. if (!of_node_cmp(to_of_node(child)->name, childname))
  904. return child;
  905. } else if (is_acpi_data_node(child)) {
  906. if (acpi_data_node_match(child, childname))
  907. return child;
  908. }
  909. }
  910. return NULL;
  911. }
  912. EXPORT_SYMBOL_GPL(fwnode_get_named_child_node);
  913. /**
  914. * device_get_named_child_node - Return first matching named child node handle
  915. * @dev: Device to find the named child node for.
  916. * @childname: String to match child node name against.
  917. */
  918. struct fwnode_handle *device_get_named_child_node(struct device *dev,
  919. const char *childname)
  920. {
  921. return fwnode_get_named_child_node(dev_fwnode(dev), childname);
  922. }
  923. EXPORT_SYMBOL_GPL(device_get_named_child_node);
  924. /**
  925. * fwnode_handle_get - Obtain a reference to a device node
  926. * @fwnode: Pointer to the device node to obtain the reference to.
  927. */
  928. void fwnode_handle_get(struct fwnode_handle *fwnode)
  929. {
  930. if (is_of_node(fwnode))
  931. of_node_get(to_of_node(fwnode));
  932. }
  933. EXPORT_SYMBOL_GPL(fwnode_handle_get);
  934. /**
  935. * fwnode_handle_put - Drop reference to a device node
  936. * @fwnode: Pointer to the device node to drop the reference to.
  937. *
  938. * This has to be used when terminating device_for_each_child_node() iteration
  939. * with break or return to prevent stale device node references from being left
  940. * behind.
  941. */
  942. void fwnode_handle_put(struct fwnode_handle *fwnode)
  943. {
  944. if (is_of_node(fwnode))
  945. of_node_put(to_of_node(fwnode));
  946. }
  947. EXPORT_SYMBOL_GPL(fwnode_handle_put);
  948. /**
  949. * device_get_child_node_count - return the number of child nodes for device
  950. * @dev: Device to cound the child nodes for
  951. */
  952. unsigned int device_get_child_node_count(struct device *dev)
  953. {
  954. struct fwnode_handle *child;
  955. unsigned int count = 0;
  956. device_for_each_child_node(dev, child)
  957. count++;
  958. return count;
  959. }
  960. EXPORT_SYMBOL_GPL(device_get_child_node_count);
  961. bool device_dma_supported(struct device *dev)
  962. {
  963. /* For DT, this is always supported.
  964. * For ACPI, this depends on CCA, which
  965. * is determined by the acpi_dma_supported().
  966. */
  967. if (IS_ENABLED(CONFIG_OF) && dev->of_node)
  968. return true;
  969. return acpi_dma_supported(ACPI_COMPANION(dev));
  970. }
  971. EXPORT_SYMBOL_GPL(device_dma_supported);
  972. enum dev_dma_attr device_get_dma_attr(struct device *dev)
  973. {
  974. enum dev_dma_attr attr = DEV_DMA_NOT_SUPPORTED;
  975. if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
  976. if (of_dma_is_coherent(dev->of_node))
  977. attr = DEV_DMA_COHERENT;
  978. else
  979. attr = DEV_DMA_NON_COHERENT;
  980. } else
  981. attr = acpi_get_dma_attr(ACPI_COMPANION(dev));
  982. return attr;
  983. }
  984. EXPORT_SYMBOL_GPL(device_get_dma_attr);
  985. /**
  986. * device_get_phy_mode - Get phy mode for given device
  987. * @dev: Pointer to the given device
  988. *
  989. * The function gets phy interface string from property 'phy-mode' or
  990. * 'phy-connection-type', and return its index in phy_modes table, or errno in
  991. * error case.
  992. */
  993. int device_get_phy_mode(struct device *dev)
  994. {
  995. const char *pm;
  996. int err, i;
  997. err = device_property_read_string(dev, "phy-mode", &pm);
  998. if (err < 0)
  999. err = device_property_read_string(dev,
  1000. "phy-connection-type", &pm);
  1001. if (err < 0)
  1002. return err;
  1003. for (i = 0; i < PHY_INTERFACE_MODE_MAX; i++)
  1004. if (!strcasecmp(pm, phy_modes(i)))
  1005. return i;
  1006. return -ENODEV;
  1007. }
  1008. EXPORT_SYMBOL_GPL(device_get_phy_mode);
  1009. static void *device_get_mac_addr(struct device *dev,
  1010. const char *name, char *addr,
  1011. int alen)
  1012. {
  1013. int ret = device_property_read_u8_array(dev, name, addr, alen);
  1014. if (ret == 0 && alen == ETH_ALEN && is_valid_ether_addr(addr))
  1015. return addr;
  1016. return NULL;
  1017. }
  1018. /**
  1019. * device_get_mac_address - Get the MAC for a given device
  1020. * @dev: Pointer to the device
  1021. * @addr: Address of buffer to store the MAC in
  1022. * @alen: Length of the buffer pointed to by addr, should be ETH_ALEN
  1023. *
  1024. * Search the firmware node for the best MAC address to use. 'mac-address' is
  1025. * checked first, because that is supposed to contain to "most recent" MAC
  1026. * address. If that isn't set, then 'local-mac-address' is checked next,
  1027. * because that is the default address. If that isn't set, then the obsolete
  1028. * 'address' is checked, just in case we're using an old device tree.
  1029. *
  1030. * Note that the 'address' property is supposed to contain a virtual address of
  1031. * the register set, but some DTS files have redefined that property to be the
  1032. * MAC address.
  1033. *
  1034. * All-zero MAC addresses are rejected, because those could be properties that
  1035. * exist in the firmware tables, but were not updated by the firmware. For
  1036. * example, the DTS could define 'mac-address' and 'local-mac-address', with
  1037. * zero MAC addresses. Some older U-Boots only initialized 'local-mac-address'.
  1038. * In this case, the real MAC is in 'local-mac-address', and 'mac-address'
  1039. * exists but is all zeros.
  1040. */
  1041. void *device_get_mac_address(struct device *dev, char *addr, int alen)
  1042. {
  1043. char *res;
  1044. res = device_get_mac_addr(dev, "mac-address", addr, alen);
  1045. if (res)
  1046. return res;
  1047. res = device_get_mac_addr(dev, "local-mac-address", addr, alen);
  1048. if (res)
  1049. return res;
  1050. return device_get_mac_addr(dev, "address", addr, alen);
  1051. }
  1052. EXPORT_SYMBOL(device_get_mac_address);
  1053. /**
  1054. * device_graph_get_next_endpoint - Get next endpoint firmware node
  1055. * @fwnode: Pointer to the parent firmware node
  1056. * @prev: Previous endpoint node or %NULL to get the first
  1057. *
  1058. * Returns an endpoint firmware node pointer or %NULL if no more endpoints
  1059. * are available.
  1060. */
  1061. struct fwnode_handle *
  1062. fwnode_graph_get_next_endpoint(struct fwnode_handle *fwnode,
  1063. struct fwnode_handle *prev)
  1064. {
  1065. struct fwnode_handle *endpoint = NULL;
  1066. if (is_of_node(fwnode)) {
  1067. struct device_node *node;
  1068. node = of_graph_get_next_endpoint(to_of_node(fwnode),
  1069. to_of_node(prev));
  1070. if (node)
  1071. endpoint = &node->fwnode;
  1072. } else if (is_acpi_node(fwnode)) {
  1073. endpoint = acpi_graph_get_next_endpoint(fwnode, prev);
  1074. if (IS_ERR(endpoint))
  1075. endpoint = NULL;
  1076. }
  1077. return endpoint;
  1078. }
  1079. EXPORT_SYMBOL_GPL(fwnode_graph_get_next_endpoint);
  1080. /**
  1081. * fwnode_graph_get_remote_port_parent - Return fwnode of a remote device
  1082. * @fwnode: Endpoint firmware node pointing to the remote endpoint
  1083. *
  1084. * Extracts firmware node of a remote device the @fwnode points to.
  1085. */
  1086. struct fwnode_handle *
  1087. fwnode_graph_get_remote_port_parent(struct fwnode_handle *fwnode)
  1088. {
  1089. struct fwnode_handle *parent = NULL;
  1090. if (is_of_node(fwnode)) {
  1091. struct device_node *node;
  1092. node = of_graph_get_remote_port_parent(to_of_node(fwnode));
  1093. if (node)
  1094. parent = &node->fwnode;
  1095. } else if (is_acpi_node(fwnode)) {
  1096. int ret;
  1097. ret = acpi_graph_get_remote_endpoint(fwnode, &parent, NULL,
  1098. NULL);
  1099. if (ret)
  1100. return NULL;
  1101. }
  1102. return parent;
  1103. }
  1104. EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_port_parent);
  1105. /**
  1106. * fwnode_graph_get_remote_port - Return fwnode of a remote port
  1107. * @fwnode: Endpoint firmware node pointing to the remote endpoint
  1108. *
  1109. * Extracts firmware node of a remote port the @fwnode points to.
  1110. */
  1111. struct fwnode_handle *fwnode_graph_get_remote_port(struct fwnode_handle *fwnode)
  1112. {
  1113. struct fwnode_handle *port = NULL;
  1114. if (is_of_node(fwnode)) {
  1115. struct device_node *node;
  1116. node = of_graph_get_remote_port(to_of_node(fwnode));
  1117. if (node)
  1118. port = &node->fwnode;
  1119. } else if (is_acpi_node(fwnode)) {
  1120. int ret;
  1121. ret = acpi_graph_get_remote_endpoint(fwnode, NULL, &port, NULL);
  1122. if (ret)
  1123. return NULL;
  1124. }
  1125. return port;
  1126. }
  1127. EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_port);
  1128. /**
  1129. * fwnode_graph_get_remote_endpoint - Return fwnode of a remote endpoint
  1130. * @fwnode: Endpoint firmware node pointing to the remote endpoint
  1131. *
  1132. * Extracts firmware node of a remote endpoint the @fwnode points to.
  1133. */
  1134. struct fwnode_handle *
  1135. fwnode_graph_get_remote_endpoint(struct fwnode_handle *fwnode)
  1136. {
  1137. struct fwnode_handle *endpoint = NULL;
  1138. if (is_of_node(fwnode)) {
  1139. struct device_node *node;
  1140. node = of_parse_phandle(to_of_node(fwnode), "remote-endpoint",
  1141. 0);
  1142. if (node)
  1143. endpoint = &node->fwnode;
  1144. } else if (is_acpi_node(fwnode)) {
  1145. int ret;
  1146. ret = acpi_graph_get_remote_endpoint(fwnode, NULL, NULL,
  1147. &endpoint);
  1148. if (ret)
  1149. return NULL;
  1150. }
  1151. return endpoint;
  1152. }
  1153. EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_endpoint);
  1154. /**
  1155. * fwnode_graph_parse_endpoint - parse common endpoint node properties
  1156. * @fwnode: pointer to endpoint fwnode_handle
  1157. * @endpoint: pointer to the fwnode endpoint data structure
  1158. *
  1159. * Parse @fwnode representing a graph endpoint node and store the
  1160. * information in @endpoint. The caller must hold a reference to
  1161. * @fwnode.
  1162. */
  1163. int fwnode_graph_parse_endpoint(struct fwnode_handle *fwnode,
  1164. struct fwnode_endpoint *endpoint)
  1165. {
  1166. struct fwnode_handle *port_fwnode = fwnode_get_parent(fwnode);
  1167. memset(endpoint, 0, sizeof(*endpoint));
  1168. endpoint->local_fwnode = fwnode;
  1169. if (is_acpi_node(port_fwnode)) {
  1170. fwnode_property_read_u32(port_fwnode, "port", &endpoint->port);
  1171. fwnode_property_read_u32(fwnode, "endpoint", &endpoint->id);
  1172. } else {
  1173. fwnode_property_read_u32(port_fwnode, "reg", &endpoint->port);
  1174. fwnode_property_read_u32(fwnode, "reg", &endpoint->id);
  1175. }
  1176. fwnode_handle_put(port_fwnode);
  1177. return 0;
  1178. }
  1179. EXPORT_SYMBOL(fwnode_graph_parse_endpoint);