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