1 /* SPDX-License-Identifier: GPL-2.0 */
3 * Device properties, a temporary data structure for adding to ACPI code
5 * Copyright 2019 Google LLC
6 * Mostly taken from coreboot file acpi_device.h
15 * Writing Device Properties objects via _DSD
17 * This is described in ACPI 6.3 section 6.2.5
19 * This provides a structure to handle nested device-specific data which ends
22 * https://www.kernel.org/doc/html/latest/firmware-guide/acpi/DSD-properties-rules.html
23 * https://uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf
24 * https://uefi.org/sites/default/files/resources/_DSD-hierarchical-data-extension-UUID-v1.1.pdf
26 * The Device Property Hierarchy can be multiple levels deep with multiple
27 * children possible in each level. In order to support this flexibility
28 * the device property hierarchy must be built up before being written out.
32 * Child table with string and integer:
33 * struct acpi_dp *child = acpi_dp_new_table("CHLD");
34 * acpi_dp_add_string(child, "childstring", "CHILD");
35 * acpi_dp_add_integer(child, "childint", 100);
37 * _DSD table with integer and gpio and child pointer:
38 * struct acpi_dp *dsd = acpi_dp_new_table("_DSD");
39 * acpi_dp_add_integer(dsd, "number1", 1);
40 * acpi_dp_add_gpio(dsd, "gpio", "\_SB.PCI0.GPIO", 0, 0, 1);
41 * acpi_dp_add_child(dsd, "child", child);
43 * Write entries into SSDT and clean up resources:
46 * Name(_DSD, Package() {
47 * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301")
49 * Package() { "gpio", Package() { \_SB.PCI0.GPIO, 0, 0, 0 } }
50 * Package() { "number1", 1 }
52 * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b")
54 * Package() { "child", CHLD }
57 * Name(CHLD, Package() {
58 * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301")
60 * Package() { "childstring", "CHILD" }
61 * Package() { "childint", 100 }
66 #define ACPI_DP_UUID "daffd814-6eba-4d8c-8a91-bc9bbf4aa301"
67 #define ACPI_DP_CHILD_UUID "dbb8e3e6-5886-4ba6-8795-1319f52a966b"
70 * enum acpi_dp_type - types of device property objects
72 * These refer to the types defined by struct acpi_dp below
74 * @ACPI_DP_TYPE_UNKNOWN: Unknown / do not use
75 * @ACPI_DP_TYPE_INTEGER: Integer value (u64) in @integer
76 * @ACPI_DP_TYPE_STRING: String value in @string
77 * @ACPI_DP_TYPE_REFERENCE: Reference to another object, with value in @string
78 * @ACPI_DP_TYPE_TABLE: Type for a top-level table which may have children
79 * @ACPI_DP_TYPE_ARRAY: Array of items with first item in @array and following
80 * items linked from that item's @next
81 * @ACPI_DP_TYPE_CHILD: Child object, with siblings in that child's @next
87 ACPI_DP_TYPE_REFERENCE,
94 * struct acpi_dp - ACPI device properties
97 * @name: Name of object, typically _DSD but could be CHLD for a child object.
98 * This can be NULL if there is no name
99 * @next: Next object in list (next array element or next sibling)
100 * @child: Pointer to first child, if @type == ACPI_DP_TYPE_CHILD, else NULL
101 * @array: First array element, if @type == ACPI_DP_TYPE_ARRAY, else NULL
102 * @integer: Integer value of the property, if @type == ACPI_DP_TYPE_INTEGER
103 * @string: String value of the property, if @type == ACPI_DP_TYPE_STRING;
104 * child name if @type == ACPI_DP_TYPE_CHILD;
105 * reference name if @type == ACPI_DP_TYPE_REFERENCE;
108 enum acpi_dp_type type;
110 struct acpi_dp *next;
112 struct acpi_dp *child;
113 struct acpi_dp *array;
122 * acpi_dp_new_table() - Start a new Device Property table
124 * @ref: ACPI reference (e.g. "_DSD")
125 * @return pointer to table, or NULL if out of memory
127 struct acpi_dp *acpi_dp_new_table(const char *ref);
130 * acpi_dp_add_integer() - Add integer Device Property
132 * A new node is added to the end of the property list of @dp
134 * @dp: Table to add this property to
135 * @name: Name of property, or NULL for none
136 * @value: Integer value
137 * @return pointer to new node, or NULL if out of memory
139 struct acpi_dp *acpi_dp_add_integer(struct acpi_dp *dp, const char *name,
143 * acpi_dp_add_string() - Add string Device Property
145 * A new node is added to the end of the property list of @dp
147 * @dp: Table to add this property to
148 * @name: Name of property, or NULL for none
149 * @string: String value
150 * @return pointer to new node, or NULL if out of memory
152 struct acpi_dp *acpi_dp_add_string(struct acpi_dp *dp, const char *name,
156 * acpi_dp_add_reference() - Add reference Device Property
158 * A new node is added to the end of the property list of @dp
160 * @dp: Table to add this property to
161 * @name: Name of property, or NULL for none
162 * @reference: Reference value
163 * @return pointer to new node, or NULL if out of memory
165 struct acpi_dp *acpi_dp_add_reference(struct acpi_dp *dp, const char *name,
166 const char *reference);
169 * acpi_dp_add_array() - Add array Device Property
171 * A new node is added to the end of the property list of @dp, with the array
174 * @dp: Table to add this property to
175 * @name: Name of property, or NULL for none
176 * @return pointer to new node, or NULL if out of memory
178 struct acpi_dp *acpi_dp_add_array(struct acpi_dp *dp, struct acpi_dp *array);
181 * acpi_dp_add_integer_array() - Add an array of integers
183 * A new node is added to the end of the property list of @dp, with the array
184 * attached to that. Each element of the array becomes a new node.
186 * @dp: Table to add this property to
187 * @name: Name of property, or NULL for none
188 * @return pointer to new array node, or NULL if out of memory
190 struct acpi_dp *acpi_dp_add_integer_array(struct acpi_dp *dp, const char *name,
191 u64 *array, int len);
194 * acpi_dp_add_child() - Add a child table of Device Properties
196 * A new node is added as a child of @dp
198 * @dp: Table to add this child to
199 * @name: Name of child, or NULL for none
200 * @child: Child node to add
201 * @return pointer to new child node, or NULL if out of memory
203 struct acpi_dp *acpi_dp_add_child(struct acpi_dp *dp, const char *name,
204 struct acpi_dp *child);
207 * acpi_dp_write() - Write Device Property hierarchy and clean up resources
209 * This writes the table using acpigen and then frees it
212 * @table: Table to write
213 * @return 0 if OK, -ve on error
215 int acpi_dp_write(struct acpi_ctx *ctx, struct acpi_dp *table);