diff options
author | Simon Glass <sjg@chromium.org> | 2020-04-26 18:19:46 +0300 |
---|---|---|
committer | Bin Meng <bmeng.cn@gmail.com> | 2020-04-30 12:16:12 +0300 |
commit | 93f7f82782cb3d2bd55215ce984887efc6cddfed (patch) | |
tree | 6dede3cc6b74da87d67b67cffd6675de6bf03b15 /drivers/core/acpi.c | |
parent | fa04cef6443eab008b99f6439ec8a3b9939253b4 (diff) | |
download | u-boot-93f7f82782cb3d2bd55215ce984887efc6cddfed.tar.xz |
acpi: Add a method to write tables for a device
A device may want to write out ACPI tables to describe itself to Linux.
Add a method to permit this.
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
Diffstat (limited to 'drivers/core/acpi.c')
-rw-r--r-- | drivers/core/acpi.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/drivers/core/acpi.c b/drivers/core/acpi.c index ba50d688fe..e09905cf2a 100644 --- a/drivers/core/acpi.c +++ b/drivers/core/acpi.c @@ -11,8 +11,17 @@ #include <common.h> #include <dm.h> #include <dm/acpi.h> +#include <dm/device-internal.h> #include <dm/root.h> +/* Type of method to call */ +enum method_t { + METHOD_WRITE_TABLES, +}; + +/* Prototype for all methods */ +typedef int (*acpi_method)(const struct udevice *dev, struct acpi_ctx *ctx); + int acpi_copy_name(char *out_name, const char *name) { strncpy(out_name, name, ACPI_NAME_LEN); @@ -31,3 +40,56 @@ int acpi_get_name(const struct udevice *dev, char *out_name) return -ENOSYS; } + +acpi_method acpi_get_method(struct udevice *dev, enum method_t method) +{ + struct acpi_ops *aops; + + aops = device_get_acpi_ops(dev); + if (aops) { + switch (method) { + case METHOD_WRITE_TABLES: + return aops->write_tables; + } + } + + return NULL; +} + +int acpi_recurse_method(struct acpi_ctx *ctx, struct udevice *parent, + enum method_t method) +{ + struct udevice *dev; + acpi_method func; + int ret; + + func = acpi_get_method(parent, method); + if (func) { + log_debug("\n"); + log_debug("- %s %p\n", parent->name, func); + ret = device_ofdata_to_platdata(parent); + if (ret) + return log_msg_ret("ofdata", ret); + ret = func(parent, ctx); + if (ret) + return log_msg_ret("func", ret); + } + device_foreach_child(dev, parent) { + ret = acpi_recurse_method(ctx, dev, method); + if (ret) + return log_msg_ret("recurse", ret); + } + + return 0; +} + +int acpi_write_dev_tables(struct acpi_ctx *ctx) +{ + int ret; + + log_debug("Writing device tables\n"); + ret = acpi_recurse_method(ctx, dm_root(), METHOD_WRITE_TABLES); + log_debug("Writing finished, err=%d\n", ret); + + return ret; +} |