property.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551
  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. /* ACPI _DSD device properties UUID: daffd814-6eba-4d8c-8a91-bc9bbf4aa301 */
  20. static const u8 prp_uuid[16] = {
  21. 0x14, 0xd8, 0xff, 0xda, 0xba, 0x6e, 0x8c, 0x4d,
  22. 0x8a, 0x91, 0xbc, 0x9b, 0xbf, 0x4a, 0xa3, 0x01
  23. };
  24. static bool acpi_property_value_ok(const union acpi_object *value)
  25. {
  26. int j;
  27. /*
  28. * The value must be an integer, a string, a reference, or a package
  29. * whose every element must be an integer, a string, or a reference.
  30. */
  31. switch (value->type) {
  32. case ACPI_TYPE_INTEGER:
  33. case ACPI_TYPE_STRING:
  34. case ACPI_TYPE_LOCAL_REFERENCE:
  35. return true;
  36. case ACPI_TYPE_PACKAGE:
  37. for (j = 0; j < value->package.count; j++)
  38. switch (value->package.elements[j].type) {
  39. case ACPI_TYPE_INTEGER:
  40. case ACPI_TYPE_STRING:
  41. case ACPI_TYPE_LOCAL_REFERENCE:
  42. continue;
  43. default:
  44. return false;
  45. }
  46. return true;
  47. }
  48. return false;
  49. }
  50. static bool acpi_properties_format_valid(const union acpi_object *properties)
  51. {
  52. int i;
  53. for (i = 0; i < properties->package.count; i++) {
  54. const union acpi_object *property;
  55. property = &properties->package.elements[i];
  56. /*
  57. * Only two elements allowed, the first one must be a string and
  58. * the second one has to satisfy certain conditions.
  59. */
  60. if (property->package.count != 2
  61. || property->package.elements[0].type != ACPI_TYPE_STRING
  62. || !acpi_property_value_ok(&property->package.elements[1]))
  63. return false;
  64. }
  65. return true;
  66. }
  67. static void acpi_init_of_compatible(struct acpi_device *adev)
  68. {
  69. const union acpi_object *of_compatible;
  70. struct acpi_hardware_id *hwid;
  71. bool acpi_of = false;
  72. int ret;
  73. /*
  74. * Check if the special PRP0001 ACPI ID is present and in that
  75. * case we fill in Device Tree compatible properties for this
  76. * device.
  77. */
  78. list_for_each_entry(hwid, &adev->pnp.ids, list) {
  79. if (!strcmp(hwid->id, "PRP0001")) {
  80. acpi_of = true;
  81. break;
  82. }
  83. }
  84. if (!acpi_of)
  85. return;
  86. ret = acpi_dev_get_property_array(adev, "compatible", ACPI_TYPE_STRING,
  87. &of_compatible);
  88. if (ret) {
  89. ret = acpi_dev_get_property(adev, "compatible",
  90. ACPI_TYPE_STRING, &of_compatible);
  91. if (ret) {
  92. acpi_handle_warn(adev->handle,
  93. "PRP0001 requires compatible property\n");
  94. return;
  95. }
  96. }
  97. adev->data.of_compatible = of_compatible;
  98. }
  99. void acpi_init_properties(struct acpi_device *adev)
  100. {
  101. struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
  102. const union acpi_object *desc;
  103. acpi_status status;
  104. int i;
  105. status = acpi_evaluate_object_typed(adev->handle, "_DSD", NULL, &buf,
  106. ACPI_TYPE_PACKAGE);
  107. if (ACPI_FAILURE(status))
  108. return;
  109. desc = buf.pointer;
  110. if (desc->package.count % 2)
  111. goto fail;
  112. /* Look for the device properties UUID. */
  113. for (i = 0; i < desc->package.count; i += 2) {
  114. const union acpi_object *uuid, *properties;
  115. uuid = &desc->package.elements[i];
  116. properties = &desc->package.elements[i + 1];
  117. /*
  118. * The first element must be a UUID and the second one must be
  119. * a package.
  120. */
  121. if (uuid->type != ACPI_TYPE_BUFFER || uuid->buffer.length != 16
  122. || properties->type != ACPI_TYPE_PACKAGE)
  123. break;
  124. if (memcmp(uuid->buffer.pointer, prp_uuid, sizeof(prp_uuid)))
  125. continue;
  126. /*
  127. * We found the matching UUID. Now validate the format of the
  128. * package immediately following it.
  129. */
  130. if (!acpi_properties_format_valid(properties))
  131. break;
  132. adev->data.pointer = buf.pointer;
  133. adev->data.properties = properties;
  134. acpi_init_of_compatible(adev);
  135. return;
  136. }
  137. fail:
  138. dev_warn(&adev->dev, "Returned _DSD data is not valid, skipping\n");
  139. ACPI_FREE(buf.pointer);
  140. }
  141. void acpi_free_properties(struct acpi_device *adev)
  142. {
  143. ACPI_FREE((void *)adev->data.pointer);
  144. adev->data.of_compatible = NULL;
  145. adev->data.pointer = NULL;
  146. adev->data.properties = NULL;
  147. }
  148. /**
  149. * acpi_dev_get_property - return an ACPI property with given name
  150. * @adev: ACPI device to get property
  151. * @name: Name of the property
  152. * @type: Expected property type
  153. * @obj: Location to store the property value (if not %NULL)
  154. *
  155. * Look up a property with @name and store a pointer to the resulting ACPI
  156. * object at the location pointed to by @obj if found.
  157. *
  158. * Callers must not attempt to free the returned objects. These objects will be
  159. * freed by the ACPI core automatically during the removal of @adev.
  160. *
  161. * Return: %0 if property with @name has been found (success),
  162. * %-EINVAL if the arguments are invalid,
  163. * %-ENODATA if the property doesn't exist,
  164. * %-EPROTO if the property value type doesn't match @type.
  165. */
  166. int acpi_dev_get_property(struct acpi_device *adev, const char *name,
  167. acpi_object_type type, const union acpi_object **obj)
  168. {
  169. const union acpi_object *properties;
  170. int i;
  171. if (!adev || !name)
  172. return -EINVAL;
  173. if (!adev->data.pointer || !adev->data.properties)
  174. return -ENODATA;
  175. properties = adev->data.properties;
  176. for (i = 0; i < properties->package.count; i++) {
  177. const union acpi_object *propname, *propvalue;
  178. const union acpi_object *property;
  179. property = &properties->package.elements[i];
  180. propname = &property->package.elements[0];
  181. propvalue = &property->package.elements[1];
  182. if (!strcmp(name, propname->string.pointer)) {
  183. if (type != ACPI_TYPE_ANY && propvalue->type != type)
  184. return -EPROTO;
  185. else if (obj)
  186. *obj = propvalue;
  187. return 0;
  188. }
  189. }
  190. return -ENODATA;
  191. }
  192. EXPORT_SYMBOL_GPL(acpi_dev_get_property);
  193. /**
  194. * acpi_dev_get_property_array - return an ACPI array property with given name
  195. * @adev: ACPI device to get property
  196. * @name: Name of the property
  197. * @type: Expected type of array elements
  198. * @obj: Location to store a pointer to the property value (if not NULL)
  199. *
  200. * Look up an array property with @name and store a pointer to the resulting
  201. * ACPI object at the location pointed to by @obj if found.
  202. *
  203. * Callers must not attempt to free the returned objects. Those objects will be
  204. * freed by the ACPI core automatically during the removal of @adev.
  205. *
  206. * Return: %0 if array property (package) with @name has been found (success),
  207. * %-EINVAL if the arguments are invalid,
  208. * %-ENODATA if the property doesn't exist,
  209. * %-EPROTO if the property is not a package or the type of its elements
  210. * doesn't match @type.
  211. */
  212. int acpi_dev_get_property_array(struct acpi_device *adev, const char *name,
  213. acpi_object_type type,
  214. const union acpi_object **obj)
  215. {
  216. const union acpi_object *prop;
  217. int ret, i;
  218. ret = acpi_dev_get_property(adev, name, ACPI_TYPE_PACKAGE, &prop);
  219. if (ret)
  220. return ret;
  221. if (type != ACPI_TYPE_ANY) {
  222. /* Check that all elements are of correct type. */
  223. for (i = 0; i < prop->package.count; i++)
  224. if (prop->package.elements[i].type != type)
  225. return -EPROTO;
  226. }
  227. if (obj)
  228. *obj = prop;
  229. return 0;
  230. }
  231. EXPORT_SYMBOL_GPL(acpi_dev_get_property_array);
  232. /**
  233. * acpi_dev_get_property_reference - returns handle to the referenced object
  234. * @adev: ACPI device to get property
  235. * @name: Name of the property
  236. * @index: Index of the reference to return
  237. * @args: Location to store the returned reference with optional arguments
  238. *
  239. * Find property with @name, verifify that it is a package containing at least
  240. * one object reference and if so, store the ACPI device object pointer to the
  241. * target object in @args->adev. If the reference includes arguments, store
  242. * them in the @args->args[] array.
  243. *
  244. * If there's more than one reference in the property value package, @index is
  245. * used to select the one to return.
  246. *
  247. * Return: %0 on success, negative error code on failure.
  248. */
  249. int acpi_dev_get_property_reference(struct acpi_device *adev,
  250. const char *name, size_t index,
  251. struct acpi_reference_args *args)
  252. {
  253. const union acpi_object *element, *end;
  254. const union acpi_object *obj;
  255. struct acpi_device *device;
  256. int ret, idx = 0;
  257. ret = acpi_dev_get_property(adev, name, ACPI_TYPE_ANY, &obj);
  258. if (ret)
  259. return ret;
  260. /*
  261. * The simplest case is when the value is a single reference. Just
  262. * return that reference then.
  263. */
  264. if (obj->type == ACPI_TYPE_LOCAL_REFERENCE) {
  265. if (index)
  266. return -EINVAL;
  267. ret = acpi_bus_get_device(obj->reference.handle, &device);
  268. if (ret)
  269. return ret;
  270. args->adev = device;
  271. args->nargs = 0;
  272. return 0;
  273. }
  274. /*
  275. * If it is not a single reference, then it is a package of
  276. * references followed by number of ints as follows:
  277. *
  278. * Package () { REF, INT, REF, INT, INT }
  279. *
  280. * The index argument is then used to determine which reference
  281. * the caller wants (along with the arguments).
  282. */
  283. if (obj->type != ACPI_TYPE_PACKAGE || index >= obj->package.count)
  284. return -EPROTO;
  285. element = obj->package.elements;
  286. end = element + obj->package.count;
  287. while (element < end) {
  288. u32 nargs, i;
  289. if (element->type != ACPI_TYPE_LOCAL_REFERENCE)
  290. return -EPROTO;
  291. ret = acpi_bus_get_device(element->reference.handle, &device);
  292. if (ret)
  293. return -ENODEV;
  294. element++;
  295. nargs = 0;
  296. /* assume following integer elements are all args */
  297. for (i = 0; element + i < end; i++) {
  298. int type = element[i].type;
  299. if (type == ACPI_TYPE_INTEGER)
  300. nargs++;
  301. else if (type == ACPI_TYPE_LOCAL_REFERENCE)
  302. break;
  303. else
  304. return -EPROTO;
  305. }
  306. if (idx++ == index) {
  307. args->adev = device;
  308. args->nargs = nargs;
  309. for (i = 0; i < nargs; i++)
  310. args->args[i] = element[i].integer.value;
  311. return 0;
  312. }
  313. element += nargs;
  314. }
  315. return -EPROTO;
  316. }
  317. EXPORT_SYMBOL_GPL(acpi_dev_get_property_reference);
  318. int acpi_dev_prop_get(struct acpi_device *adev, const char *propname,
  319. void **valptr)
  320. {
  321. return acpi_dev_get_property(adev, propname, ACPI_TYPE_ANY,
  322. (const union acpi_object **)valptr);
  323. }
  324. int acpi_dev_prop_read_single(struct acpi_device *adev, const char *propname,
  325. enum dev_prop_type proptype, void *val)
  326. {
  327. const union acpi_object *obj;
  328. int ret;
  329. if (!val)
  330. return -EINVAL;
  331. if (proptype >= DEV_PROP_U8 && proptype <= DEV_PROP_U64) {
  332. ret = acpi_dev_get_property(adev, propname, ACPI_TYPE_INTEGER, &obj);
  333. if (ret)
  334. return ret;
  335. switch (proptype) {
  336. case DEV_PROP_U8:
  337. if (obj->integer.value > U8_MAX)
  338. return -EOVERFLOW;
  339. *(u8 *)val = obj->integer.value;
  340. break;
  341. case DEV_PROP_U16:
  342. if (obj->integer.value > U16_MAX)
  343. return -EOVERFLOW;
  344. *(u16 *)val = obj->integer.value;
  345. break;
  346. case DEV_PROP_U32:
  347. if (obj->integer.value > U32_MAX)
  348. return -EOVERFLOW;
  349. *(u32 *)val = obj->integer.value;
  350. break;
  351. default:
  352. *(u64 *)val = obj->integer.value;
  353. break;
  354. }
  355. } else if (proptype == DEV_PROP_STRING) {
  356. ret = acpi_dev_get_property(adev, propname, ACPI_TYPE_STRING, &obj);
  357. if (ret)
  358. return ret;
  359. *(char **)val = obj->string.pointer;
  360. } else {
  361. ret = -EINVAL;
  362. }
  363. return ret;
  364. }
  365. static int acpi_copy_property_array_u8(const union acpi_object *items, u8 *val,
  366. size_t nval)
  367. {
  368. int i;
  369. for (i = 0; i < nval; i++) {
  370. if (items[i].type != ACPI_TYPE_INTEGER)
  371. return -EPROTO;
  372. if (items[i].integer.value > U8_MAX)
  373. return -EOVERFLOW;
  374. val[i] = items[i].integer.value;
  375. }
  376. return 0;
  377. }
  378. static int acpi_copy_property_array_u16(const union acpi_object *items,
  379. u16 *val, size_t nval)
  380. {
  381. int i;
  382. for (i = 0; i < nval; i++) {
  383. if (items[i].type != ACPI_TYPE_INTEGER)
  384. return -EPROTO;
  385. if (items[i].integer.value > U16_MAX)
  386. return -EOVERFLOW;
  387. val[i] = items[i].integer.value;
  388. }
  389. return 0;
  390. }
  391. static int acpi_copy_property_array_u32(const union acpi_object *items,
  392. u32 *val, size_t nval)
  393. {
  394. int i;
  395. for (i = 0; i < nval; i++) {
  396. if (items[i].type != ACPI_TYPE_INTEGER)
  397. return -EPROTO;
  398. if (items[i].integer.value > U32_MAX)
  399. return -EOVERFLOW;
  400. val[i] = items[i].integer.value;
  401. }
  402. return 0;
  403. }
  404. static int acpi_copy_property_array_u64(const union acpi_object *items,
  405. u64 *val, size_t nval)
  406. {
  407. int i;
  408. for (i = 0; i < nval; i++) {
  409. if (items[i].type != ACPI_TYPE_INTEGER)
  410. return -EPROTO;
  411. val[i] = items[i].integer.value;
  412. }
  413. return 0;
  414. }
  415. static int acpi_copy_property_array_string(const union acpi_object *items,
  416. char **val, size_t nval)
  417. {
  418. int i;
  419. for (i = 0; i < nval; i++) {
  420. if (items[i].type != ACPI_TYPE_STRING)
  421. return -EPROTO;
  422. val[i] = items[i].string.pointer;
  423. }
  424. return 0;
  425. }
  426. int acpi_dev_prop_read(struct acpi_device *adev, const char *propname,
  427. enum dev_prop_type proptype, void *val, size_t nval)
  428. {
  429. const union acpi_object *obj;
  430. const union acpi_object *items;
  431. int ret;
  432. if (val && nval == 1) {
  433. ret = acpi_dev_prop_read_single(adev, propname, proptype, val);
  434. if (!ret)
  435. return ret;
  436. }
  437. ret = acpi_dev_get_property_array(adev, propname, ACPI_TYPE_ANY, &obj);
  438. if (ret)
  439. return ret;
  440. if (!val)
  441. return obj->package.count;
  442. else if (nval <= 0)
  443. return -EINVAL;
  444. if (nval > obj->package.count)
  445. return -EOVERFLOW;
  446. items = obj->package.elements;
  447. switch (proptype) {
  448. case DEV_PROP_U8:
  449. ret = acpi_copy_property_array_u8(items, (u8 *)val, nval);
  450. break;
  451. case DEV_PROP_U16:
  452. ret = acpi_copy_property_array_u16(items, (u16 *)val, nval);
  453. break;
  454. case DEV_PROP_U32:
  455. ret = acpi_copy_property_array_u32(items, (u32 *)val, nval);
  456. break;
  457. case DEV_PROP_U64:
  458. ret = acpi_copy_property_array_u64(items, (u64 *)val, nval);
  459. break;
  460. case DEV_PROP_STRING:
  461. ret = acpi_copy_property_array_string(items, (char **)val, nval);
  462. break;
  463. default:
  464. ret = -EINVAL;
  465. break;
  466. }
  467. return ret;
  468. }