property.c 23 KB

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