Generate ACPI information for this device so that Linux can use it
correctly.

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

(no changes since v1)

Changes in v1:
- Capitalise ACPI_OPS_PTR
- Update for acpi_device_write_i2c_dev() return-value change
- Use acpi,ddn instead of acpi,desc

 drivers/tpm/cr50_i2c.c | 55 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/drivers/tpm/cr50_i2c.c b/drivers/tpm/cr50_i2c.c
index 1942c07c605..64831a42232 100644
--- a/drivers/tpm/cr50_i2c.c
+++ b/drivers/tpm/cr50_i2c.c
@@ -14,11 +14,14 @@
 #include <log.h>
 #include <spl.h>
 #include <tpm-v2.h>
+#include <acpi/acpigen.h>
+#include <acpi/acpi_device.h>
 #include <asm/gpio.h>
 #include <asm/io.h>
 #include <asm/arch/iomap.h>
 #include <asm/arch/pm.h>
 #include <linux/delay.h>
+#include <dm/acpi.h>
 
 enum {
        TIMEOUT_INIT_MS         = 30000, /* Very long timeout for TPM init */
@@ -581,6 +584,53 @@ static int cr50_i2c_cleanup(struct udevice *dev)
        return 0;
 }
 
+static int cr50_acpi_fill_ssdt(const struct udevice *dev, struct acpi_ctx *ctx)
+{
+       char scope[ACPI_PATH_MAX];
+       char name[ACPI_NAME_MAX];
+       const char *hid;
+       int ret;
+
+       ret = acpi_device_scope(dev, scope, sizeof(scope));
+       if (ret)
+               return log_msg_ret("scope", ret);
+       ret = acpi_get_name(dev, name);
+       if (ret)
+               return log_msg_ret("name", ret);
+
+       hid = dev_read_string(dev, "acpi,hid");
+       if (!hid)
+               return log_msg_ret("hid", ret);
+
+       /* Device */
+       acpigen_write_scope(ctx, scope);
+       acpigen_write_device(ctx, name);
+       acpigen_write_name_string(ctx, "_HID", hid);
+       acpigen_write_name_integer(ctx, "_UID",
+                                  dev_read_u32_default(dev, "acpi,uid", 0));
+       acpigen_write_name_string(ctx, "_DDN",
+                                 dev_read_string(dev, "acpi,ddn"));
+       acpigen_write_sta(ctx, acpi_device_status(dev));
+
+       /* Resources */
+       acpigen_write_name(ctx, "_CRS");
+       acpigen_write_resourcetemplate_header(ctx);
+       ret = acpi_device_write_i2c_dev(ctx, dev);
+       if (ret < 0)
+               return log_msg_ret("i2c", ret);
+       ret = acpi_device_write_interrupt_or_gpio(ctx, (struct udevice *)dev,
+                                                 "ready-gpios");
+       if (ret < 0)
+               return log_msg_ret("irq_gpio", ret);
+
+       acpigen_write_resourcetemplate_footer(ctx);
+
+       acpigen_pop_len(ctx); /* Device */
+       acpigen_pop_len(ctx); /* Scope */
+
+       return 0;
+}
+
 enum {
        TPM_TIMEOUT_MS          = 5,
        SHORT_TIMEOUT_MS        = 750,
@@ -653,6 +703,10 @@ static int cr50_i2c_probe(struct udevice *dev)
        return 0;
 }
 
+struct acpi_ops cr50_acpi_ops = {
+       .fill_ssdt      = cr50_acpi_fill_ssdt,
+};
+
 static const struct tpm_ops cr50_i2c_ops = {
        .open           = cr50_i2c_open,
        .get_desc       = cr50_i2c_get_desc,
@@ -675,5 +729,6 @@ U_BOOT_DRIVER(cr50_i2c) = {
        .probe  = cr50_i2c_probe,
        .remove = cr50_i2c_cleanup,
        .priv_auto_alloc_size = sizeof(struct cr50_priv),
+       ACPI_OPS_PTR(&cr50_acpi_ops)
        .flags          = DM_FLAG_OS_PREPARE,
 };
-- 
2.28.0.526.ge36021eeef-goog

Reply via email to