property.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849
  1. /*
  2. * ACPI device specific properties support.
  3. *
  4. * Copyright (C) 2014, Intel Corporation
  5. * All rights reserved.
  6. *
  7. * Authors: Mika Westerberg <mika.westerberg@linux.intel.com>
  8. * Darren Hart <dvhart@linux.intel.com>
  9. * Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License version 2 as
  13. * published by the Free Software Foundation.
  14. */
  15. #include <linux/acpi.h>
  16. #include <linux/device.h>
  17. #include <linux/export.h>
  18. #include "internal.h"
  19. static int acpi_data_get_property_array(struct acpi_device_data *data,
  20. const char *name,
  21. acpi_object_type type,
  22. const union acpi_object **obj);
  23. /* ACPI _DSD device properties UUID: daffd814-6eba-4d8c-8a91-bc9bbf4aa301 */
  24. static const u8 prp_uuid[16] = {
  25. 0x14, 0xd8, 0xff, 0xda, 0xba, 0x6e, 0x8c, 0x4d,
  26. 0x8a, 0x91, 0xbc, 0x9b, 0xbf, 0x4a, 0xa3, 0x01
  27. };
  28. /* ACPI _DSD data subnodes UUID: dbb8e3e6-5886-4ba6-8795-1319f52a966b */
  29. static const u8 ads_uuid[16] = {
  30. 0xe6, 0xe3, 0xb8, 0xdb, 0x86, 0x58, 0xa6, 0x4b,
  31. 0x87, 0x95, 0x13, 0x19, 0xf5, 0x2a, 0x96, 0x6b
  32. };
  33. static bool acpi_enumerate_nondev_subnodes(acpi_handle scope,
  34. const union acpi_object *desc,
  35. struct acpi_device_data *data);
  36. static bool acpi_extract_properties(const union acpi_object *desc,
  37. struct acpi_device_data *data);
  38. static bool acpi_nondev_subnode_ok(acpi_handle scope,
  39. const union acpi_object *link,
  40. struct list_head *list)
  41. {
  42. struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
  43. struct acpi_data_node *dn;
  44. acpi_handle handle;
  45. acpi_status status;
  46. dn = kzalloc(sizeof(*dn), GFP_KERNEL);
  47. if (!dn)
  48. return false;
  49. dn->name = link->package.elements[0].string.pointer;
  50. dn->fwnode.type = FWNODE_ACPI_DATA;
  51. INIT_LIST_HEAD(&dn->data.subnodes);
  52. status = acpi_get_handle(scope, link->package.elements[1].string.pointer,
  53. &handle);
  54. if (ACPI_FAILURE(status))
  55. goto fail;
  56. status = acpi_evaluate_object_typed(handle, NULL, NULL, &buf,
  57. ACPI_TYPE_PACKAGE);
  58. if (ACPI_FAILURE(status))
  59. goto fail;
  60. if (acpi_extract_properties(buf.pointer, &dn->data))
  61. dn->handle = handle;
  62. /*
  63. * The scope for the subnode object lookup is the one of the namespace
  64. * node (device) containing the object that has returned the package.
  65. * That is, it's the scope of that object's parent.
  66. */
  67. status = acpi_get_parent(handle, &scope);
  68. if (ACPI_SUCCESS(status)
  69. && acpi_enumerate_nondev_subnodes(scope, buf.pointer, &dn->data))
  70. dn->handle = handle;
  71. if (dn->handle) {
  72. dn->data.pointer = buf.pointer;
  73. list_add_tail(&dn->sibling, list);
  74. return true;
  75. }
  76. acpi_handle_debug(handle, "Invalid properties/subnodes data, skipping\n");
  77. fail:
  78. ACPI_FREE(buf.pointer);
  79. kfree(dn);
  80. return false;
  81. }
  82. static int acpi_add_nondev_subnodes(acpi_handle scope,
  83. const union acpi_object *links,
  84. struct list_head *list)
  85. {
  86. bool ret = false;
  87. int i;
  88. for (i = 0; i < links->package.count; i++) {
  89. const union acpi_object *link;
  90. link = &links->package.elements[i];
  91. /* Only two elements allowed, both must be strings. */
  92. if (link->package.count == 2
  93. && link->package.elements[0].type == ACPI_TYPE_STRING
  94. && link->package.elements[1].type == ACPI_TYPE_STRING
  95. && acpi_nondev_subnode_ok(scope, link, list))
  96. ret = true;
  97. }
  98. return ret;
  99. }
  100. static bool acpi_enumerate_nondev_subnodes(acpi_handle scope,
  101. const union acpi_object *desc,
  102. struct acpi_device_data *data)
  103. {
  104. int i;
  105. /* Look for the ACPI data subnodes UUID. */
  106. for (i = 0; i < desc->package.count; i += 2) {
  107. const union acpi_object *uuid, *links;
  108. uuid = &desc->package.elements[i];
  109. links = &desc->package.elements[i + 1];
  110. /*
  111. * The first element must be a UUID and the second one must be
  112. * a package.
  113. */
  114. if (uuid->type != ACPI_TYPE_BUFFER || uuid->buffer.length != 16
  115. || links->type != ACPI_TYPE_PACKAGE)
  116. break;
  117. if (memcmp(uuid->buffer.pointer, ads_uuid, sizeof(ads_uuid)))
  118. continue;
  119. return acpi_add_nondev_subnodes(scope, links, &data->subnodes);
  120. }
  121. return false;
  122. }
  123. static bool acpi_property_value_ok(const union acpi_object *value)
  124. {
  125. int j;
  126. /*
  127. * The value must be an integer, a string, a reference, or a package
  128. * whose every element must be an integer, a string, or a reference.
  129. */
  130. switch (value->type) {
  131. case ACPI_TYPE_INTEGER:
  132. case ACPI_TYPE_STRING:
  133. case ACPI_TYPE_LOCAL_REFERENCE:
  134. return true;
  135. case ACPI_TYPE_PACKAGE:
  136. for (j = 0; j < value->package.count; j++)
  137. switch (value->package.elements[j].type) {
  138. case ACPI_TYPE_INTEGER:
  139. case ACPI_TYPE_STRING:
  140. case ACPI_TYPE_LOCAL_REFERENCE:
  141. continue;
  142. default:
  143. return false;
  144. }
  145. return true;
  146. }
  147. return false;
  148. }
  149. static bool acpi_properties_format_valid(const union acpi_object *properties)
  150. {
  151. int i;
  152. for (i = 0; i < properties->package.count; i++) {
  153. const union acpi_object *property;
  154. property = &properties->package.elements[i];
  155. /*
  156. * Only two elements allowed, the first one must be a string and
  157. * the second one has to satisfy certain conditions.
  158. */
  159. if (property->package.count != 2
  160. || property->package.elements[0].type != ACPI_TYPE_STRING
  161. || !acpi_property_value_ok(&property->package.elements[1]))
  162. return false;
  163. }
  164. return true;
  165. }
  166. static void acpi_init_of_compatible(struct acpi_device *adev)
  167. {
  168. const union acpi_object *of_compatible;
  169. int ret;
  170. ret = acpi_data_get_property_array(&adev->data, "compatible",
  171. ACPI_TYPE_STRING, &of_compatible);
  172. if (ret) {
  173. ret = acpi_dev_get_property(adev, "compatible",
  174. ACPI_TYPE_STRING, &of_compatible);
  175. if (ret) {
  176. if (adev->parent
  177. && adev->parent->flags.of_compatible_ok)
  178. goto out;
  179. return;
  180. }
  181. }
  182. adev->data.of_compatible = of_compatible;
  183. out:
  184. adev->flags.of_compatible_ok = 1;
  185. }
  186. static bool acpi_extract_properties(const union acpi_object *desc,
  187. struct acpi_device_data *data)
  188. {
  189. int i;
  190. if (desc->package.count % 2)
  191. return false;
  192. /* Look for the device properties UUID. */
  193. for (i = 0; i < desc->package.count; i += 2) {
  194. const union acpi_object *uuid, *properties;
  195. uuid = &desc->package.elements[i];
  196. properties = &desc->package.elements[i + 1];
  197. /*
  198. * The first element must be a UUID and the second one must be
  199. * a package.
  200. */
  201. if (uuid->type != ACPI_TYPE_BUFFER || uuid->buffer.length != 16
  202. || properties->type != ACPI_TYPE_PACKAGE)
  203. break;
  204. if (memcmp(uuid->buffer.pointer, prp_uuid, sizeof(prp_uuid)))
  205. continue;
  206. /*
  207. * We found the matching UUID. Now validate the format of the
  208. * package immediately following it.
  209. */
  210. if (!acpi_properties_format_valid(properties))
  211. break;
  212. data->properties = properties;
  213. return true;
  214. }
  215. return false;
  216. }
  217. void acpi_init_properties(struct acpi_device *adev)
  218. {
  219. struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
  220. struct acpi_hardware_id *hwid;
  221. acpi_status status;
  222. bool acpi_of = false;
  223. INIT_LIST_HEAD(&adev->data.subnodes);
  224. /*
  225. * Check if ACPI_DT_NAMESPACE_HID is present and inthat case we fill in
  226. * Device Tree compatible properties for this device.
  227. */
  228. list_for_each_entry(hwid, &adev->pnp.ids, list) {
  229. if (!strcmp(hwid->id, ACPI_DT_NAMESPACE_HID)) {
  230. acpi_of = true;
  231. break;
  232. }
  233. }
  234. status = acpi_evaluate_object_typed(adev->handle, "_DSD", NULL, &buf,
  235. ACPI_TYPE_PACKAGE);
  236. if (ACPI_FAILURE(status))
  237. goto out;
  238. if (acpi_extract_properties(buf.pointer, &adev->data)) {
  239. adev->data.pointer = buf.pointer;
  240. if (acpi_of)
  241. acpi_init_of_compatible(adev);
  242. }
  243. if (acpi_enumerate_nondev_subnodes(adev->handle, buf.pointer, &adev->data))
  244. adev->data.pointer = buf.pointer;
  245. if (!adev->data.pointer) {
  246. acpi_handle_debug(adev->handle, "Invalid _DSD data, skipping\n");
  247. ACPI_FREE(buf.pointer);
  248. }
  249. out:
  250. if (acpi_of && !adev->flags.of_compatible_ok)
  251. acpi_handle_info(adev->handle,
  252. ACPI_DT_NAMESPACE_HID " requires 'compatible' property\n");
  253. }
  254. static void acpi_destroy_nondev_subnodes(struct list_head *list)
  255. {
  256. struct acpi_data_node *dn, *next;
  257. if (list_empty(list))
  258. return;
  259. list_for_each_entry_safe_reverse(dn, next, list, sibling) {
  260. acpi_destroy_nondev_subnodes(&dn->data.subnodes);
  261. wait_for_completion(&dn->kobj_done);
  262. list_del(&dn->sibling);
  263. ACPI_FREE((void *)dn->data.pointer);
  264. kfree(dn);
  265. }
  266. }
  267. void acpi_free_properties(struct acpi_device *adev)
  268. {
  269. acpi_destroy_nondev_subnodes(&adev->data.subnodes);
  270. ACPI_FREE((void *)adev->data.pointer);
  271. adev->data.of_compatible = NULL;
  272. adev->data.pointer = NULL;
  273. adev->data.properties = NULL;
  274. }
  275. /**
  276. * acpi_data_get_property - return an ACPI property with given name
  277. * @data: ACPI device deta object to get the property from
  278. * @name: Name of the property
  279. * @type: Expected property type
  280. * @obj: Location to store the property value (if not %NULL)
  281. *
  282. * Look up a property with @name and store a pointer to the resulting ACPI
  283. * object at the location pointed to by @obj if found.
  284. *
  285. * Callers must not attempt to free the returned objects. These objects will be
  286. * freed by the ACPI core automatically during the removal of @data.
  287. *
  288. * Return: %0 if property with @name has been found (success),
  289. * %-EINVAL if the arguments are invalid,
  290. * %-ENODATA if the property doesn't exist,
  291. * %-EPROTO if the property value type doesn't match @type.
  292. */
  293. static int acpi_data_get_property(struct acpi_device_data *data,
  294. const char *name, acpi_object_type type,
  295. const union acpi_object **obj)
  296. {
  297. const union acpi_object *properties;
  298. int i;
  299. if (!data || !name)
  300. return -EINVAL;
  301. if (!data->pointer || !data->properties)
  302. return -ENODATA;
  303. properties = data->properties;
  304. for (i = 0; i < properties->package.count; i++) {
  305. const union acpi_object *propname, *propvalue;
  306. const union acpi_object *property;
  307. property = &properties->package.elements[i];
  308. propname = &property->package.elements[0];
  309. propvalue = &property->package.elements[1];
  310. if (!strcmp(name, propname->string.pointer)) {
  311. if (type != ACPI_TYPE_ANY && propvalue->type != type)
  312. return -EPROTO;
  313. else if (obj)
  314. *obj = propvalue;
  315. return 0;
  316. }
  317. }
  318. return -ENODATA;
  319. }
  320. /**
  321. * acpi_dev_get_property - return an ACPI property with given name.
  322. * @adev: ACPI device to get the property from.
  323. * @name: Name of the property.
  324. * @type: Expected property type.
  325. * @obj: Location to store the property value (if not %NULL).
  326. */
  327. int acpi_dev_get_property(struct acpi_device *adev, const char *name,
  328. acpi_object_type type, const union acpi_object **obj)
  329. {
  330. return adev ? acpi_data_get_property(&adev->data, name, type, obj) : -EINVAL;
  331. }
  332. EXPORT_SYMBOL_GPL(acpi_dev_get_property);
  333. static struct acpi_device_data *acpi_device_data_of_node(struct fwnode_handle *fwnode)
  334. {
  335. if (fwnode->type == FWNODE_ACPI) {
  336. struct acpi_device *adev = to_acpi_device_node(fwnode);
  337. return &adev->data;
  338. } else if (fwnode->type == FWNODE_ACPI_DATA) {
  339. struct acpi_data_node *dn = to_acpi_data_node(fwnode);
  340. return &dn->data;
  341. }
  342. return NULL;
  343. }
  344. /**
  345. * acpi_node_prop_get - return an ACPI property with given name.
  346. * @fwnode: Firmware node to get the property from.
  347. * @propname: Name of the property.
  348. * @valptr: Location to store a pointer to the property value (if not %NULL).
  349. */
  350. int acpi_node_prop_get(struct fwnode_handle *fwnode, const char *propname,
  351. void **valptr)
  352. {
  353. return acpi_data_get_property(acpi_device_data_of_node(fwnode),
  354. propname, ACPI_TYPE_ANY,
  355. (const union acpi_object **)valptr);
  356. }
  357. /**
  358. * acpi_data_get_property_array - return an ACPI array property with given name
  359. * @adev: ACPI data object to get the property from
  360. * @name: Name of the property
  361. * @type: Expected type of array elements
  362. * @obj: Location to store a pointer to the property value (if not NULL)
  363. *
  364. * Look up an array property with @name and store a pointer to the resulting
  365. * ACPI object at the location pointed to by @obj if found.
  366. *
  367. * Callers must not attempt to free the returned objects. Those objects will be
  368. * freed by the ACPI core automatically during the removal of @data.
  369. *
  370. * Return: %0 if array property (package) with @name has been found (success),
  371. * %-EINVAL if the arguments are invalid,
  372. * %-ENODATA if the property doesn't exist,
  373. * %-EPROTO if the property is not a package or the type of its elements
  374. * doesn't match @type.
  375. */
  376. static int acpi_data_get_property_array(struct acpi_device_data *data,
  377. const char *name,
  378. acpi_object_type type,
  379. const union acpi_object **obj)
  380. {
  381. const union acpi_object *prop;
  382. int ret, i;
  383. ret = acpi_data_get_property(data, name, ACPI_TYPE_PACKAGE, &prop);
  384. if (ret)
  385. return ret;
  386. if (type != ACPI_TYPE_ANY) {
  387. /* Check that all elements are of correct type. */
  388. for (i = 0; i < prop->package.count; i++)
  389. if (prop->package.elements[i].type != type)
  390. return -EPROTO;
  391. }
  392. if (obj)
  393. *obj = prop;
  394. return 0;
  395. }
  396. /**
  397. * acpi_data_get_property_reference - returns handle to the referenced object
  398. * @data: ACPI device data object containing the property
  399. * @propname: Name of the property
  400. * @index: Index of the reference to return
  401. * @args: Location to store the returned reference with optional arguments
  402. *
  403. * Find property with @name, verifify that it is a package containing at least
  404. * one object reference and if so, store the ACPI device object pointer to the
  405. * target object in @args->adev. If the reference includes arguments, store
  406. * them in the @args->args[] array.
  407. *
  408. * If there's more than one reference in the property value package, @index is
  409. * used to select the one to return.
  410. *
  411. * Return: %0 on success, negative error code on failure.
  412. */
  413. static int acpi_data_get_property_reference(struct acpi_device_data *data,
  414. const char *propname, size_t index,
  415. struct acpi_reference_args *args)
  416. {
  417. const union acpi_object *element, *end;
  418. const union acpi_object *obj;
  419. struct acpi_device *device;
  420. int ret, idx = 0;
  421. ret = acpi_data_get_property(data, propname, ACPI_TYPE_ANY, &obj);
  422. if (ret)
  423. return ret;
  424. /*
  425. * The simplest case is when the value is a single reference. Just
  426. * return that reference then.
  427. */
  428. if (obj->type == ACPI_TYPE_LOCAL_REFERENCE) {
  429. if (index)
  430. return -EINVAL;
  431. ret = acpi_bus_get_device(obj->reference.handle, &device);
  432. if (ret)
  433. return ret;
  434. args->adev = device;
  435. args->nargs = 0;
  436. return 0;
  437. }
  438. /*
  439. * If it is not a single reference, then it is a package of
  440. * references followed by number of ints as follows:
  441. *
  442. * Package () { REF, INT, REF, INT, INT }
  443. *
  444. * The index argument is then used to determine which reference
  445. * the caller wants (along with the arguments).
  446. */
  447. if (obj->type != ACPI_TYPE_PACKAGE || index >= obj->package.count)
  448. return -EPROTO;
  449. element = obj->package.elements;
  450. end = element + obj->package.count;
  451. while (element < end) {
  452. u32 nargs, i;
  453. if (element->type != ACPI_TYPE_LOCAL_REFERENCE)
  454. return -EPROTO;
  455. ret = acpi_bus_get_device(element->reference.handle, &device);
  456. if (ret)
  457. return -ENODEV;
  458. element++;
  459. nargs = 0;
  460. /* assume following integer elements are all args */
  461. for (i = 0; element + i < end; i++) {
  462. int type = element[i].type;
  463. if (type == ACPI_TYPE_INTEGER)
  464. nargs++;
  465. else if (type == ACPI_TYPE_LOCAL_REFERENCE)
  466. break;
  467. else
  468. return -EPROTO;
  469. }
  470. if (idx++ == index) {
  471. args->adev = device;
  472. args->nargs = nargs;
  473. for (i = 0; i < nargs; i++)
  474. args->args[i] = element[i].integer.value;
  475. return 0;
  476. }
  477. element += nargs;
  478. }
  479. return -EPROTO;
  480. }
  481. /**
  482. * acpi_node_get_property_reference - get a handle to the referenced object.
  483. * @fwnode: Firmware node to get the property from.
  484. * @propname: Name of the property.
  485. * @index: Index of the reference to return.
  486. * @args: Location to store the returned reference with optional arguments.
  487. */
  488. int acpi_node_get_property_reference(struct fwnode_handle *fwnode,
  489. const char *name, size_t index,
  490. struct acpi_reference_args *args)
  491. {
  492. struct acpi_device_data *data = acpi_device_data_of_node(fwnode);
  493. return data ? acpi_data_get_property_reference(data, name, index, args) : -EINVAL;
  494. }
  495. EXPORT_SYMBOL_GPL(acpi_node_get_property_reference);
  496. static int acpi_data_prop_read_single(struct acpi_device_data *data,
  497. const char *propname,
  498. enum dev_prop_type proptype, void *val)
  499. {
  500. const union acpi_object *obj;
  501. int ret;
  502. if (!val)
  503. return -EINVAL;
  504. if (proptype >= DEV_PROP_U8 && proptype <= DEV_PROP_U64) {
  505. ret = acpi_data_get_property(data, propname, ACPI_TYPE_INTEGER, &obj);
  506. if (ret)
  507. return ret;
  508. switch (proptype) {
  509. case DEV_PROP_U8:
  510. if (obj->integer.value > U8_MAX)
  511. return -EOVERFLOW;
  512. *(u8 *)val = obj->integer.value;
  513. break;
  514. case DEV_PROP_U16:
  515. if (obj->integer.value > U16_MAX)
  516. return -EOVERFLOW;
  517. *(u16 *)val = obj->integer.value;
  518. break;
  519. case DEV_PROP_U32:
  520. if (obj->integer.value > U32_MAX)
  521. return -EOVERFLOW;
  522. *(u32 *)val = obj->integer.value;
  523. break;
  524. default:
  525. *(u64 *)val = obj->integer.value;
  526. break;
  527. }
  528. } else if (proptype == DEV_PROP_STRING) {
  529. ret = acpi_data_get_property(data, propname, ACPI_TYPE_STRING, &obj);
  530. if (ret)
  531. return ret;
  532. *(char **)val = obj->string.pointer;
  533. } else {
  534. ret = -EINVAL;
  535. }
  536. return ret;
  537. }
  538. int acpi_dev_prop_read_single(struct acpi_device *adev, const char *propname,
  539. enum dev_prop_type proptype, void *val)
  540. {
  541. return adev ? acpi_data_prop_read_single(&adev->data, propname, proptype, val) : -EINVAL;
  542. }
  543. static int acpi_copy_property_array_u8(const union acpi_object *items, u8 *val,
  544. size_t nval)
  545. {
  546. int i;
  547. for (i = 0; i < nval; i++) {
  548. if (items[i].type != ACPI_TYPE_INTEGER)
  549. return -EPROTO;
  550. if (items[i].integer.value > U8_MAX)
  551. return -EOVERFLOW;
  552. val[i] = items[i].integer.value;
  553. }
  554. return 0;
  555. }
  556. static int acpi_copy_property_array_u16(const union acpi_object *items,
  557. u16 *val, size_t nval)
  558. {
  559. int i;
  560. for (i = 0; i < nval; i++) {
  561. if (items[i].type != ACPI_TYPE_INTEGER)
  562. return -EPROTO;
  563. if (items[i].integer.value > U16_MAX)
  564. return -EOVERFLOW;
  565. val[i] = items[i].integer.value;
  566. }
  567. return 0;
  568. }
  569. static int acpi_copy_property_array_u32(const union acpi_object *items,
  570. u32 *val, size_t nval)
  571. {
  572. int i;
  573. for (i = 0; i < nval; i++) {
  574. if (items[i].type != ACPI_TYPE_INTEGER)
  575. return -EPROTO;
  576. if (items[i].integer.value > U32_MAX)
  577. return -EOVERFLOW;
  578. val[i] = items[i].integer.value;
  579. }
  580. return 0;
  581. }
  582. static int acpi_copy_property_array_u64(const union acpi_object *items,
  583. u64 *val, size_t nval)
  584. {
  585. int i;
  586. for (i = 0; i < nval; i++) {
  587. if (items[i].type != ACPI_TYPE_INTEGER)
  588. return -EPROTO;
  589. val[i] = items[i].integer.value;
  590. }
  591. return 0;
  592. }
  593. static int acpi_copy_property_array_string(const union acpi_object *items,
  594. char **val, size_t nval)
  595. {
  596. int i;
  597. for (i = 0; i < nval; i++) {
  598. if (items[i].type != ACPI_TYPE_STRING)
  599. return -EPROTO;
  600. val[i] = items[i].string.pointer;
  601. }
  602. return 0;
  603. }
  604. static int acpi_data_prop_read(struct acpi_device_data *data,
  605. const char *propname,
  606. enum dev_prop_type proptype,
  607. void *val, size_t nval)
  608. {
  609. const union acpi_object *obj;
  610. const union acpi_object *items;
  611. int ret;
  612. if (val && nval == 1) {
  613. ret = acpi_data_prop_read_single(data, propname, proptype, val);
  614. if (!ret)
  615. return ret;
  616. }
  617. ret = acpi_data_get_property_array(data, propname, ACPI_TYPE_ANY, &obj);
  618. if (ret)
  619. return ret;
  620. if (!val)
  621. return obj->package.count;
  622. if (nval > obj->package.count)
  623. return -EOVERFLOW;
  624. else if (nval <= 0)
  625. return -EINVAL;
  626. items = obj->package.elements;
  627. switch (proptype) {
  628. case DEV_PROP_U8:
  629. ret = acpi_copy_property_array_u8(items, (u8 *)val, nval);
  630. break;
  631. case DEV_PROP_U16:
  632. ret = acpi_copy_property_array_u16(items, (u16 *)val, nval);
  633. break;
  634. case DEV_PROP_U32:
  635. ret = acpi_copy_property_array_u32(items, (u32 *)val, nval);
  636. break;
  637. case DEV_PROP_U64:
  638. ret = acpi_copy_property_array_u64(items, (u64 *)val, nval);
  639. break;
  640. case DEV_PROP_STRING:
  641. ret = acpi_copy_property_array_string(items, (char **)val, nval);
  642. break;
  643. default:
  644. ret = -EINVAL;
  645. break;
  646. }
  647. return ret;
  648. }
  649. int acpi_dev_prop_read(struct acpi_device *adev, const char *propname,
  650. enum dev_prop_type proptype, void *val, size_t nval)
  651. {
  652. return adev ? acpi_data_prop_read(&adev->data, propname, proptype, val, nval) : -EINVAL;
  653. }
  654. /**
  655. * acpi_node_prop_read - retrieve the value of an ACPI property with given name.
  656. * @fwnode: Firmware node to get the property from.
  657. * @propname: Name of the property.
  658. * @proptype: Expected property type.
  659. * @val: Location to store the property value (if not %NULL).
  660. * @nval: Size of the array pointed to by @val.
  661. *
  662. * If @val is %NULL, return the number of array elements comprising the value
  663. * of the property. Otherwise, read at most @nval values to the array at the
  664. * location pointed to by @val.
  665. */
  666. int acpi_node_prop_read(struct fwnode_handle *fwnode, const char *propname,
  667. enum dev_prop_type proptype, void *val, size_t nval)
  668. {
  669. return acpi_data_prop_read(acpi_device_data_of_node(fwnode),
  670. propname, proptype, val, nval);
  671. }
  672. /**
  673. * acpi_get_next_subnode - Return the next child node handle for a device.
  674. * @dev: Device to find the next child node for.
  675. * @child: Handle to one of the device's child nodes or a null handle.
  676. */
  677. struct fwnode_handle *acpi_get_next_subnode(struct device *dev,
  678. struct fwnode_handle *child)
  679. {
  680. struct acpi_device *adev = ACPI_COMPANION(dev);
  681. struct list_head *head, *next;
  682. if (!adev)
  683. return NULL;
  684. if (!child || child->type == FWNODE_ACPI) {
  685. head = &adev->children;
  686. if (list_empty(head))
  687. goto nondev;
  688. if (child) {
  689. adev = to_acpi_device_node(child);
  690. next = adev->node.next;
  691. if (next == head) {
  692. child = NULL;
  693. goto nondev;
  694. }
  695. adev = list_entry(next, struct acpi_device, node);
  696. } else {
  697. adev = list_first_entry(head, struct acpi_device, node);
  698. }
  699. return acpi_fwnode_handle(adev);
  700. }
  701. nondev:
  702. if (!child || child->type == FWNODE_ACPI_DATA) {
  703. struct acpi_data_node *dn;
  704. head = &adev->data.subnodes;
  705. if (list_empty(head))
  706. return NULL;
  707. if (child) {
  708. dn = to_acpi_data_node(child);
  709. next = dn->sibling.next;
  710. if (next == head)
  711. return NULL;
  712. dn = list_entry(next, struct acpi_data_node, sibling);
  713. } else {
  714. dn = list_first_entry(head, struct acpi_data_node, sibling);
  715. }
  716. return &dn->fwnode;
  717. }
  718. return NULL;
  719. }