property.c 40 KB

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