It is useful to be able to control the order of data written to the SSDT
so that we can compare the output against known-good kernel dumps.

Add code to record each item that is added along with the device that
added it. That allows us to reorder things later if needed.

Signed-off-by: Simon Glass <s...@chromium.org>
---

 drivers/core/acpi.c | 70 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 70 insertions(+)

diff --git a/drivers/core/acpi.c b/drivers/core/acpi.c
index 18567682f2..d7ab906757 100644
--- a/drivers/core/acpi.c
+++ b/drivers/core/acpi.c
@@ -14,6 +14,32 @@
 #include <dm/device-internal.h>
 #include <dm/root.h>
 
+#define MAX_ITEMS      100
+
+/* Type of table that we collected */
+enum gen_type_t {
+       TYPE_SSDT,
+};
+
+/**
+ * struct acpi_item - Holds info about ACPI data generated by a driver method
+ *
+ * @dev: Device that generated this data
+ * @type: Table type it refers to
+ * @buf: Buffer containing the data
+ * @size: Size of the data in bytes
+ */
+struct acpi_item {
+       struct udevice *dev;
+       enum gen_type_t type;
+       char *buf;
+       int size;
+};
+
+/* List of ACPI items collected */
+static struct acpi_item acpi_item[MAX_ITEMS];
+static int item_count;
+
 int acpi_return_name(char *out_name, const char *name)
 {
        strcpy(out_name, name);
@@ -32,6 +58,43 @@ int acpi_get_name(const struct udevice *dev, char *out_name)
        return -ENOSYS;
 }
 
+/**
+ * acpi_add_item() - Add a new item to the list of data collected
+ *
+ * @ctx: ACPI context
+ * @dev: Device that generated the data
+ * @type: Table type it refers to
+ * @start: The start of the data (the end is obtained from ctx->current)
+ * @return 0 if OK, -ENOSPC if too many items, -ENOMEM if out of memory
+ */
+static int acpi_add_item(struct acpi_ctx *ctx, struct udevice *dev,
+                        enum gen_type_t type, void *start)
+{
+       struct acpi_item *item;
+       void *end = ctx->current;
+
+       if (item_count == MAX_ITEMS) {
+               log_err("Too many items\n");
+               return log_msg_ret("mem", -ENOSPC);
+       }
+
+       item = &acpi_item[item_count];
+       item->dev = dev;
+       item->type = type;
+       item->size = end - start;
+       if (!item->size)
+               return 0;
+       item->buf = malloc(item->size);
+       if (!item->buf)
+               return log_msg_ret("mem", -ENOMEM);
+       memcpy(item->buf, start, item->size);
+       item_count++;
+       log_debug("* %s: Added type %d, %p, size %x\n", dev->name, type, start,
+                 item->size);
+
+       return 0;
+}
+
 int _acpi_fill_ssdt(struct acpi_ctx *ctx, struct udevice *parent)
 {
        struct acpi_ops *aops;
@@ -40,6 +103,8 @@ int _acpi_fill_ssdt(struct acpi_ctx *ctx, struct udevice 
*parent)
 
        aops = device_get_acpi_ops(parent);
        if (aops && aops->fill_ssdt) {
+               void *start = ctx->current;
+
                log_debug("\n- %s %p\n", parent->name,
                          aops->fill_ssdt);
                ret = device_ofdata_to_platdata(parent);
@@ -48,6 +113,11 @@ int _acpi_fill_ssdt(struct acpi_ctx *ctx, struct udevice 
*parent)
                ret = aops->fill_ssdt(parent, ctx);
                if (ret)
                        return log_msg_ret("ssdt", ret);
+
+               /* Add the item to the internal list */
+               ret = acpi_add_item(ctx, parent, TYPE_SSDT, start);
+               if (ret)
+                       return log_msg_ret("add", ret);
        }
        device_foreach_child(dev, parent) {
                ret = _acpi_fill_ssdt(ctx, dev);
-- 
2.25.0.341.g760bfbb309-goog

Reply via email to