acpi_dp.h 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * Device properties, a temporary data structure for adding to ACPI code
  4. *
  5. * Copyright 2019 Google LLC
  6. * Mostly taken from coreboot file acpi_device.h
  7. */
  8. #ifndef __ACPI_DP_H
  9. #define __ACPI_DP_H
  10. struct acpi_ctx;
  11. #include <acpi/acpi_device.h>
  12. /*
  13. * Writing Device Properties objects via _DSD
  14. *
  15. * This is described in ACPI 6.3 section 6.2.5
  16. *
  17. * This provides a structure to handle nested device-specific data which ends
  18. * up in a _DSD table.
  19. *
  20. * https://www.kernel.org/doc/html/latest/firmware-guide/acpi/DSD-properties-rules.html
  21. * https://uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf
  22. * https://uefi.org/sites/default/files/resources/_DSD-hierarchical-data-extension-UUID-v1.1.pdf
  23. *
  24. * The Device Property Hierarchy can be multiple levels deep with multiple
  25. * children possible in each level. In order to support this flexibility
  26. * the device property hierarchy must be built up before being written out.
  27. *
  28. * For example:
  29. *
  30. * Child table with string and integer:
  31. * struct acpi_dp *child = acpi_dp_new_table("CHLD");
  32. * acpi_dp_add_string(child, "childstring", "CHILD");
  33. * acpi_dp_add_integer(child, "childint", 100);
  34. *
  35. * _DSD table with integer and gpio and child pointer:
  36. * struct acpi_dp *dsd = acpi_dp_new_table("_DSD");
  37. * acpi_dp_add_integer(dsd, "number1", 1);
  38. * acpi_dp_add_gpio(dsd, "gpio", "\_SB.PCI0.GPIO", 0, 0, 1);
  39. * acpi_dp_add_child(dsd, "child", child);
  40. *
  41. * Write entries into SSDT and clean up resources:
  42. * acpi_dp_write(dsd);
  43. *
  44. * Name(_DSD, Package() {
  45. * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301")
  46. * Package() {
  47. * Package() { "gpio", Package() { \_SB.PCI0.GPIO, 0, 0, 0 } }
  48. * Package() { "number1", 1 }
  49. * }
  50. * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b")
  51. * Package() {
  52. * Package() { "child", CHLD }
  53. * }
  54. * }
  55. * Name(CHLD, Package() {
  56. * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301")
  57. * Package() {
  58. * Package() { "childstring", "CHILD" }
  59. * Package() { "childint", 100 }
  60. * }
  61. * }
  62. */
  63. #define ACPI_DP_UUID "daffd814-6eba-4d8c-8a91-bc9bbf4aa301"
  64. #define ACPI_DP_CHILD_UUID "dbb8e3e6-5886-4ba6-8795-1319f52a966b"
  65. /**
  66. * enum acpi_dp_type - types of device property objects
  67. *
  68. * These refer to the types defined by struct acpi_dp below
  69. *
  70. * @ACPI_DP_TYPE_UNKNOWN: Unknown / do not use
  71. * @ACPI_DP_TYPE_INTEGER: Integer value (u64) in @integer
  72. * @ACPI_DP_TYPE_STRING: String value in @string
  73. * @ACPI_DP_TYPE_REFERENCE: Reference to another object, with value in @string
  74. * @ACPI_DP_TYPE_TABLE: Type for a top-level table which may have children
  75. * @ACPI_DP_TYPE_ARRAY: Array of items with first item in @array and following
  76. * items linked from that item's @next
  77. * @ACPI_DP_TYPE_CHILD: Child object, with siblings in that child's @next
  78. */
  79. enum acpi_dp_type {
  80. ACPI_DP_TYPE_UNKNOWN,
  81. ACPI_DP_TYPE_INTEGER,
  82. ACPI_DP_TYPE_STRING,
  83. ACPI_DP_TYPE_REFERENCE,
  84. ACPI_DP_TYPE_TABLE,
  85. ACPI_DP_TYPE_ARRAY,
  86. ACPI_DP_TYPE_CHILD,
  87. };
  88. /**
  89. * struct acpi_dp - ACPI device properties
  90. *
  91. * @type: Table type
  92. * @name: Name of object, typically _DSD but could be CHLD for a child object.
  93. * This can be NULL if there is no name
  94. * @next: Next object in list (next array element or next sibling)
  95. * @child: Pointer to first child, if @type == ACPI_DP_TYPE_CHILD, else NULL
  96. * @array: First array element, if @type == ACPI_DP_TYPE_ARRAY, else NULL
  97. * @integer: Integer value of the property, if @type == ACPI_DP_TYPE_INTEGER
  98. * @string: String value of the property, if @type == ACPI_DP_TYPE_STRING;
  99. * child name if @type == ACPI_DP_TYPE_CHILD;
  100. * reference name if @type == ACPI_DP_TYPE_REFERENCE;
  101. */
  102. struct acpi_dp {
  103. enum acpi_dp_type type;
  104. const char *name;
  105. struct acpi_dp *next;
  106. union {
  107. struct acpi_dp *child;
  108. struct acpi_dp *array;
  109. };
  110. union {
  111. u64 integer;
  112. const char *string;
  113. };
  114. };
  115. /**
  116. * acpi_dp_new_table() - Start a new Device Property table
  117. *
  118. * @ref: ACPI reference (e.g. "_DSD")
  119. * @return pointer to table, or NULL if out of memory
  120. */
  121. struct acpi_dp *acpi_dp_new_table(const char *ref);
  122. /**
  123. * acpi_dp_add_integer() - Add integer Device Property
  124. *
  125. * A new node is added to the end of the property list of @dp
  126. *
  127. * @dp: Table to add this property to
  128. * @name: Name of property, or NULL for none
  129. * @value: Integer value
  130. * @return pointer to new node, or NULL if out of memory
  131. */
  132. struct acpi_dp *acpi_dp_add_integer(struct acpi_dp *dp, const char *name,
  133. u64 value);
  134. /**
  135. * acpi_dp_add_string() - Add string Device Property
  136. *
  137. * A new node is added to the end of the property list of @dp
  138. *
  139. * @dp: Table to add this property to
  140. * @name: Name of property, or NULL for none
  141. * @string: String value
  142. * @return pointer to new node, or NULL if out of memory
  143. */
  144. struct acpi_dp *acpi_dp_add_string(struct acpi_dp *dp, const char *name,
  145. const char *string);
  146. /**
  147. * acpi_dp_add_reference() - Add reference Device Property
  148. *
  149. * A new node is added to the end of the property list of @dp
  150. *
  151. * @dp: Table to add this property to
  152. * @name: Name of property, or NULL for none
  153. * @reference: Reference value
  154. * @return pointer to new node, or NULL if out of memory
  155. */
  156. struct acpi_dp *acpi_dp_add_reference(struct acpi_dp *dp, const char *name,
  157. const char *reference);
  158. /**
  159. * acpi_dp_add_array() - Add array Device Property
  160. *
  161. * A new node is added to the end of the property list of @dp, with the array
  162. * attached to that.
  163. *
  164. * @dp: Table to add this property to
  165. * @name: Name of property, or NULL for none
  166. * @return pointer to new node, or NULL if out of memory
  167. */
  168. struct acpi_dp *acpi_dp_add_array(struct acpi_dp *dp, struct acpi_dp *array);
  169. /**
  170. * acpi_dp_add_integer_array() - Add an array of integers
  171. *
  172. * A new node is added to the end of the property list of @dp, with the array
  173. * attached to that. Each element of the array becomes a new node.
  174. *
  175. * @dp: Table to add this property to
  176. * @name: Name of property, or NULL for none
  177. * @return pointer to new array node, or NULL if out of memory
  178. */
  179. struct acpi_dp *acpi_dp_add_integer_array(struct acpi_dp *dp, const char *name,
  180. u64 *array, int len);
  181. /**
  182. * acpi_dp_add_child() - Add a child table of Device Properties
  183. *
  184. * A new node is added as a child of @dp
  185. *
  186. * @dp: Table to add this child to
  187. * @name: Name of child, or NULL for none
  188. * @child: Child node to add
  189. * @return pointer to new child node, or NULL if out of memory
  190. */
  191. struct acpi_dp *acpi_dp_add_child(struct acpi_dp *dp, const char *name,
  192. struct acpi_dp *child);
  193. /**
  194. * acpi_dp_add_gpio() - Add a GPIO to a list of Device Properties
  195. *
  196. * A new node is added to the end of the property list of @dp, with the
  197. * GPIO properties added to the the new node
  198. *
  199. * @dp: Table to add this property to
  200. * @name: Name of property
  201. * @ref: Reference to device with a _CRS containing GpioIO or GpioInt
  202. * @index: Index of the GPIO resource in _CRS starting from zero
  203. * @pin: Pin in the GPIO resource, typically zero
  204. * @polarity: GPIO polarity. Note that ACPI_IRQ_ACTIVE_BOTH is not supported
  205. * @return pointer to new node, or NULL if out of memory
  206. */
  207. struct acpi_dp *acpi_dp_add_gpio(struct acpi_dp *dp, const char *name,
  208. const char *ref, int index, int pin,
  209. enum acpi_gpio_polarity polarity);
  210. /**
  211. * acpi_dp_write() - Write Device Property hierarchy and clean up resources
  212. *
  213. * This writes the table using acpigen and then frees it
  214. *
  215. * @ctx: ACPI context
  216. * @table: Table to write
  217. * @return 0 if OK, -ve on error
  218. */
  219. int acpi_dp_write(struct acpi_ctx *ctx, struct acpi_dp *table);
  220. /**
  221. * acpi_dp_ofnode_copy_int() - Copy a property from device tree to DP
  222. *
  223. * This copies an integer property from the device tree to the ACPI DP table.
  224. *
  225. * @node: Node to copy from
  226. * @dp: DP to copy to
  227. * @prop: Property name to copy
  228. * @return 0 if OK, -ve on error
  229. */
  230. int acpi_dp_ofnode_copy_int(ofnode node, struct acpi_dp *dp, const char *prop);
  231. /**
  232. * acpi_dp_ofnode_copy_str() - Copy a property from device tree to DP
  233. *
  234. * This copies a string property from the device tree to the ACPI DP table.
  235. *
  236. * @node: Node to copy from
  237. * @dp: DP to copy to
  238. * @prop: Property name to copy
  239. * @return 0 if OK, -ve on error
  240. */
  241. int acpi_dp_ofnode_copy_str(ofnode node, struct acpi_dp *dp, const char *prop);
  242. /**
  243. * acpi_dp_dev_copy_int() - Copy a property from device tree to DP
  244. *
  245. * This copies an integer property from the device tree to the ACPI DP table.
  246. *
  247. * @dev: Device to copy from
  248. * @dp: DP to copy to
  249. * @prop: Property name to copy
  250. * @return 0 if OK, -ve on error
  251. */
  252. int acpi_dp_dev_copy_int(const struct udevice *dev, struct acpi_dp *dp,
  253. const char *prop);
  254. /**
  255. * acpi_dp_dev_copy_str() - Copy a property from device tree to DP
  256. *
  257. * This copies a string property from the device tree to the ACPI DP table.
  258. *
  259. * @dev: Device to copy from
  260. * @dp: DP to copy to
  261. * @prop: Property name to copy
  262. * @return 0 if OK, -ve on error
  263. */
  264. int acpi_dp_dev_copy_str(const struct udevice *dev, struct acpi_dp *dp,
  265. const char *prop);
  266. #endif