]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
acpi: Support copying properties from device tree to ACPI
authorSimon Glass <sjg@chromium.org>
Tue, 7 Jul 2020 19:11:58 +0000 (13:11 -0600)
committerBin Meng <bmeng.cn@gmail.com>
Fri, 17 Jul 2020 06:32:24 +0000 (14:32 +0800)
Some drivers in Linux support both device tree and ACPI. U-Boot itself
uses Linux device-tree bindings for its own configuration but does not use
ACPI.

It is convenient to copy these values over to the ACPI DP table for
passing to linux. Add some convenience functions to help with this.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
arch/sandbox/dts/test.dts
include/acpi/acpi_dp.h
lib/acpi/acpi_dp.c
test/dm/acpi_dp.c

index 0d8ffd179a868197817dc77a67f047f77018d3a4..f0d8f12d40134a472c8a2ce802ddfb962343c024 100644 (file)
                uint-value = <(-1234)>;
                int64-value = /bits/ 64 <0x1111222233334444>;
                int-array = <5678 9123 4567>;
+               str-value = "test string";
                interrupts-extended = <&irq 3 0>;
        };
 
index b89e0b8c4932c375fe969957d6f1e2ffb7e228d2..0b514bce59ce038840763e566cb495e27f281b1f 100644 (file)
@@ -234,4 +234,54 @@ struct acpi_dp *acpi_dp_add_gpio(struct acpi_dp *dp, const char *name,
  */
 int acpi_dp_write(struct acpi_ctx *ctx, struct acpi_dp *table);
 
+/**
+ * acpi_dp_ofnode_copy_int() - Copy a property from device tree to DP
+ *
+ * This copies an integer property from the device tree to the ACPI DP table.
+ *
+ * @node: Node to copy from
+ * @dp: DP to copy to
+ * @prop: Property name to copy
+ * @return 0 if OK, -ve on error
+ */
+int acpi_dp_ofnode_copy_int(ofnode node, struct acpi_dp *dp, const char *prop);
+
+/**
+ * acpi_dp_ofnode_copy_str() - Copy a property from device tree to DP
+ *
+ * This copies a string property from the device tree to the ACPI DP table.
+ *
+ * @node: Node to copy from
+ * @dp: DP to copy to
+ * @prop: Property name to copy
+ * @return 0 if OK, -ve on error
+ */
+int acpi_dp_ofnode_copy_str(ofnode node, struct acpi_dp *dp, const char *prop);
+
+/**
+ * acpi_dp_dev_copy_int() - Copy a property from device tree to DP
+ *
+ * This copies an integer property from the device tree to the ACPI DP table.
+ *
+ * @dev: Device to copy from
+ * @dp: DP to copy to
+ * @prop: Property name to copy
+ * @return 0 if OK, -ve on error
+ */
+int acpi_dp_dev_copy_int(const struct udevice *dev, struct acpi_dp *dp,
+                        const char *prop);
+
+/**
+ * acpi_dp_dev_copy_str() - Copy a property from device tree to DP
+ *
+ * This copies a string property from the device tree to the ACPI DP table.
+ *
+ * @dev: Device to copy from
+ * @dp: DP to copy to
+ * @prop: Property name to copy
+ * @return 0 if OK, -ve on error
+ */
+int acpi_dp_dev_copy_str(const struct udevice *dev, struct acpi_dp *dp,
+                        const char *prop);
+
 #endif
index e8de5651c8351a5b31848160942e3b9b00e9e633..579cab4771512dd851fe0ce98371b8d8c94c6fa0 100644 (file)
@@ -344,3 +344,59 @@ struct acpi_dp *acpi_dp_add_gpio(struct acpi_dp *dp, const char *name,
 
        return gpio;
 }
+
+int acpi_dp_ofnode_copy_int(ofnode node, struct acpi_dp *dp, const char *prop)
+{
+       int ret;
+       u32 val = 0;
+
+       ret = ofnode_read_u32(node, prop, &val);
+       if (ret)
+               return ret;
+       if (!acpi_dp_add_integer(dp, prop, val))
+               return log_ret(-ENOMEM);
+
+       return 0;
+}
+
+int acpi_dp_ofnode_copy_str(ofnode node, struct acpi_dp *dp, const char *prop)
+{
+       const char *val;
+
+       val = ofnode_read_string(node, prop);
+       if (!val)
+               return -EINVAL;
+       if (!acpi_dp_add_string(dp, prop, val))
+               return log_ret(-ENOMEM);
+
+       return 0;
+}
+
+int acpi_dp_dev_copy_int(const struct udevice *dev, struct acpi_dp *dp,
+                        const char *prop)
+{
+       int ret;
+       u32 val = 0;
+
+       ret = dev_read_u32(dev, prop, &val);
+       if (ret)
+               return ret;
+       if (!acpi_dp_add_integer(dp, prop, val))
+               return log_ret(-ENOMEM);
+
+       return ret;
+}
+
+int acpi_dp_dev_copy_str(const struct udevice *dev, struct acpi_dp *dp,
+                        const char *prop)
+{
+       const char *val;
+
+       val = dev_read_string(dev, prop);
+       if (!val)
+               return -EINVAL;
+       if (!acpi_dp_add_string(dp, prop, val))
+               return log_ret(-ENOMEM);
+
+       return 0;
+}
index 8b812260b19f5ea2c25c1f73289cb5cccf2e238b..93604b87e18bcca22c776c1dff348e589584bf41 100644 (file)
@@ -423,3 +423,70 @@ static int dm_test_acpi_dp_gpio(struct unit_test_state *uts)
        return 0;
 }
 DM_TEST(dm_test_acpi_dp_gpio, 0);
+
+/* Test copying info from the device tree to ACPI tables */
+static int dm_test_acpi_dp_copy(struct unit_test_state *uts)
+{
+       struct acpi_ctx *ctx;
+       struct udevice *dev;
+       struct acpi_dp *dp;
+       ofnode node;
+       u8 *ptr;
+
+       ut_assertok(alloc_context(&ctx));
+
+       dp = acpi_dp_new_table("FRED");
+       ut_assertnonnull(dp);
+
+       ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev));
+       ut_asserteq_str("a-test", dev->name);
+
+       ut_assertok(acpi_dp_dev_copy_int(dev, dp, "int-value"));
+       ut_asserteq(-EINVAL, acpi_dp_dev_copy_int(dev, dp, "missing-value"));
+       ut_assertok(acpi_dp_dev_copy_int(dev, dp, "uint-value"));
+
+       ut_assertok(acpi_dp_dev_copy_str(dev, dp, "str-value"));
+       ut_asserteq(-EINVAL, acpi_dp_dev_copy_str(dev, dp, "missing-value"));
+
+       node = ofnode_path("/chosen");
+       ut_assert(ofnode_valid(node));
+       ut_assertok(acpi_dp_ofnode_copy_int(node, dp, "int-values"));
+       ut_asserteq(-EINVAL,
+                   acpi_dp_ofnode_copy_int(node, dp, "missing-value"));
+
+       ut_assertok(acpi_dp_ofnode_copy_str(node, dp, "setting"));
+       ut_asserteq(-EINVAL,
+                   acpi_dp_ofnode_copy_str(node, dp, "missing-value"));
+
+       ptr = acpigen_get_current(ctx);
+       ut_assertok(acpi_dp_write(ctx, dp));
+       ut_asserteq(0x9d, acpigen_get_current(ctx) - ptr);
+
+       ut_asserteq(STRING_PREFIX, ptr[0x2b]);
+       ut_asserteq_str("int-value", (char *)ptr + 0x2c);
+       ut_asserteq(WORD_PREFIX, ptr[0x36]);
+       ut_asserteq(1234, get_unaligned((u16 *)(ptr + 0x37)));
+
+       ut_asserteq(STRING_PREFIX, ptr[0x3e]);
+       ut_asserteq_str("uint-value", (char *)ptr + 0x3f);
+       ut_asserteq(DWORD_PREFIX, ptr[0x4a]);
+       ut_asserteq(-1234, get_unaligned((u32 *)(ptr + 0x4b)));
+
+       ut_asserteq(STRING_PREFIX, ptr[0x54]);
+       ut_asserteq_str("str-value", (char *)ptr + 0x55);
+       ut_asserteq(STRING_PREFIX, ptr[0x5f]);
+       ut_asserteq_str("test string", (char *)ptr + 0x60);
+
+       ut_asserteq(STRING_PREFIX, ptr[0x71]);
+       ut_asserteq_str("int-values", (char *)ptr + 0x72);
+       ut_asserteq(WORD_PREFIX, ptr[0x7d]);
+       ut_asserteq(0x1937, get_unaligned((u16 *)(ptr + 0x7e)));
+
+       ut_asserteq(STRING_PREFIX, ptr[0x85]);
+       ut_asserteq_str("setting", (char *)ptr + 0x86);
+       ut_asserteq(STRING_PREFIX, ptr[0x8e]);
+       ut_asserteq_str("sunrise ohoka", (char *)(ptr + 0x8f));
+
+       return 0;
+}
+DM_TEST(dm_test_acpi_dp_copy, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);