[v3,21/35] acpi: Support copying properties from device tree to ACPI

Message ID 20200614025523.40183-10-sjg@chromium.org
State New
Headers show
Series
  • dm: Add programmatic generation of ACPI tables (part B)
Related show

Commit Message

Simon Glass June 14, 2020, 2:55 a.m.
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 device tree for passing
to linux. Add some convenience functions to help with this.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

Changes in v3:
- Fix incorrect function names and arguments in commments
- Add error checking for acpi_dp_add...() functions

 arch/sandbox/dts/test.dts |  1 +
 include/acpi/acpi_dp.h    | 51 +++++++++++++++++++++++++++++
 lib/acpi/acpi_dp.c        | 56 ++++++++++++++++++++++++++++++++
 test/dm/acpi_dp.c         | 67 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 175 insertions(+)

Comments

Wolfgang Wallner June 16, 2020, 11:31 a.m. | #1
Hi Simon,

-----"Simon Glass" <sjg at chromium.org> schrieb: -----
> Betreff: [PATCH v3 21/35] acpi: Support copying properties from device tree to ACPI
> 
> 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 device tree for passing
> to linux. Add some convenience functions to help with this.
> 
> Signed-off-by: Simon Glass <sjg at chromium.org>
> ---
> 
> Changes in v3:
> - Fix incorrect function names and arguments in commments
> - Add error checking for acpi_dp_add...() functions
> 
>  arch/sandbox/dts/test.dts |  1 +
>  include/acpi/acpi_dp.h    | 51 +++++++++++++++++++++++++++++
>  lib/acpi/acpi_dp.c        | 56 ++++++++++++++++++++++++++++++++
>  test/dm/acpi_dp.c         | 67 +++++++++++++++++++++++++++++++++++++++
>  4 files changed, 175 insertions(+)

Reviewed-by: Wolfgang Wallner <wolfgang.wallner at br-automation.com>
Bin Meng June 29, 2020, 3 a.m. | #2
Hi Simon,

On Sun, Jun 14, 2020 at 10:55 AM Simon Glass <sjg at chromium.org> wrote:
>
> 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 device tree for passing

copy these values over to "ACPI DP table"

> to linux. Add some convenience functions to help with this.
>
> Signed-off-by: Simon Glass <sjg at chromium.org>
> ---
>
> Changes in v3:
> - Fix incorrect function names and arguments in commments
> - Add error checking for acpi_dp_add...() functions
>
>  arch/sandbox/dts/test.dts |  1 +
>  include/acpi/acpi_dp.h    | 51 +++++++++++++++++++++++++++++
>  lib/acpi/acpi_dp.c        | 56 ++++++++++++++++++++++++++++++++
>  test/dm/acpi_dp.c         | 67 +++++++++++++++++++++++++++++++++++++++
>  4 files changed, 175 insertions(+)
>
> diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
> index bad0b4f1a8..173778b09c 100644
> --- a/arch/sandbox/dts/test.dts
> +++ b/arch/sandbox/dts/test.dts
> @@ -111,6 +111,7 @@
>                 uint-value = <(-1234)>;
>                 int64-value = /bits/ 64 <0x1111222233334444>;
>                 int-array = <5678 9123 4567>;
> +               str-value = "test string";
>                 interrupts-extended = <&irq 3 0>;
>         };
>
> diff --git a/include/acpi/acpi_dp.h b/include/acpi/acpi_dp.h
> index efbec3d152..a90abcb102 100644
> --- a/include/acpi/acpi_dp.h
> +++ b/include/acpi/acpi_dp.h
> @@ -228,9 +228,60 @@ struct acpi_dp *acpi_dp_add_gpio(struct acpi_dp *dp, const char *name,
>   *
>   * This writes the table using acpigen and then frees it
>   *
> + * @ctx: ACPI context

This change should be squashed into "[v3,19/35] acpi: Support writing
Device Properties objects via _DSD"

>   * @table: Table to write
>   * @return 0 if OK, -ve on error
>   */
>  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
> diff --git a/lib/acpi/acpi_dp.c b/lib/acpi/acpi_dp.c
> index 4ff857a451..e85f077cc2 100644
> --- a/lib/acpi/acpi_dp.c
> +++ b/lib/acpi/acpi_dp.c
> @@ -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;
> +}
> diff --git a/test/dm/acpi_dp.c b/test/dm/acpi_dp.c
> index 24615c384f..4432645a3e 100644
> --- a/test/dm/acpi_dp.c
> +++ b/test/dm/acpi_dp.c
> @@ -443,3 +443,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);
> --

Other than above,
Reviewed-by: Bin Meng <bmeng.cn at gmail.com>

Regards,
Bin

Patch

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index bad0b4f1a8..173778b09c 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -111,6 +111,7 @@ 
 		uint-value = <(-1234)>;
 		int64-value = /bits/ 64 <0x1111222233334444>;
 		int-array = <5678 9123 4567>;
+		str-value = "test string";
 		interrupts-extended = <&irq 3 0>;
 	};
 
diff --git a/include/acpi/acpi_dp.h b/include/acpi/acpi_dp.h
index efbec3d152..a90abcb102 100644
--- a/include/acpi/acpi_dp.h
+++ b/include/acpi/acpi_dp.h
@@ -228,9 +228,60 @@  struct acpi_dp *acpi_dp_add_gpio(struct acpi_dp *dp, const char *name,
  *
  * This writes the table using acpigen and then frees it
  *
+ * @ctx: ACPI context
  * @table: Table to write
  * @return 0 if OK, -ve on error
  */
 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
diff --git a/lib/acpi/acpi_dp.c b/lib/acpi/acpi_dp.c
index 4ff857a451..e85f077cc2 100644
--- a/lib/acpi/acpi_dp.c
+++ b/lib/acpi/acpi_dp.c
@@ -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;
+}
diff --git a/test/dm/acpi_dp.c b/test/dm/acpi_dp.c
index 24615c384f..4432645a3e 100644
--- a/test/dm/acpi_dp.c
+++ b/test/dm/acpi_dp.c
@@ -443,3 +443,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);