diff options
-rw-r--r-- | configs/tools-only_defconfig | 1 | ||||
-rw-r--r-- | drivers/core/Kconfig | 9 | ||||
-rw-r--r-- | drivers/core/Makefile | 1 | ||||
-rw-r--r-- | drivers/core/acpi.c | 33 | ||||
-rw-r--r-- | include/dm/acpi.h | 73 | ||||
-rw-r--r-- | include/dm/device.h | 5 | ||||
-rw-r--r-- | include/log.h | 2 |
7 files changed, 124 insertions, 0 deletions
diff --git a/configs/tools-only_defconfig b/configs/tools-only_defconfig index 6ca50dc5fd3..2811b2cd37d 100644 --- a/configs/tools-only_defconfig +++ b/configs/tools-only_defconfig @@ -26,3 +26,4 @@ CONFIG_SYSRESET=y # CONFIG_VIRTIO_PCI is not set # CONFIG_VIRTIO_SANDBOX is not set # CONFIG_EFI_LOADER is not set +# CONFIG_ACPIGEN is not set diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig index 3b95b5387b9..a3b03993423 100644 --- a/drivers/core/Kconfig +++ b/drivers/core/Kconfig @@ -261,4 +261,13 @@ config DM_DEV_READ_INLINE bool default y if !OF_LIVE +config ACPIGEN + bool "Support ACPI table generation in driver model" + default y if SANDBOX || GENERATE_ACPI_TABLE + help + This option enables generation of ACPI tables using driver-model + devices. It adds a new operation struct to each driver, to support + things like generating device-specific tables and returning the ACPI + name of a device. + endmenu diff --git a/drivers/core/Makefile b/drivers/core/Makefile index bce7467da1d..c707026a3a0 100644 --- a/drivers/core/Makefile +++ b/drivers/core/Makefile @@ -3,6 +3,7 @@ # Copyright (c) 2013 Google, Inc obj-y += device.o fdtaddr.o lists.o root.o uclass.o util.o +obj-$(CONFIG_$(SPL_TPL_)ACPIGEN) += acpi.o obj-$(CONFIG_DEVRES) += devres.o obj-$(CONFIG_$(SPL_)DM_DEVICE_REMOVE) += device-remove.o obj-$(CONFIG_$(SPL_)SIMPLE_BUS) += simple-bus.o diff --git a/drivers/core/acpi.c b/drivers/core/acpi.c new file mode 100644 index 00000000000..ba50d688fef --- /dev/null +++ b/drivers/core/acpi.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Core driver model support for ACPI table generation + * + * Copyright 2019 Google LLC + * Written by Simon Glass <sjg@chromium.org> + */ + +#define LOG_CATEOGRY LOGC_ACPI + +#include <common.h> +#include <dm.h> +#include <dm/acpi.h> +#include <dm/root.h> + +int acpi_copy_name(char *out_name, const char *name) +{ + strncpy(out_name, name, ACPI_NAME_LEN); + out_name[ACPI_NAME_LEN] = '\0'; + + return 0; +} + +int acpi_get_name(const struct udevice *dev, char *out_name) +{ + struct acpi_ops *aops; + + aops = device_get_acpi_ops(dev); + if (aops && aops->get_name) + return aops->get_name(dev, out_name); + + return -ENOSYS; +} diff --git a/include/dm/acpi.h b/include/dm/acpi.h new file mode 100644 index 00000000000..ba0813fa21c --- /dev/null +++ b/include/dm/acpi.h @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Core ACPI (Advanced Configuration and Power Interface) support + * + * Copyright 2019 Google LLC + * Written by Simon Glass <sjg@chromium.org> + */ + +#ifndef __DM_ACPI_H__ +#define __DM_ACPI_H__ + +/* Allow operations to be optional for ACPI */ +#if CONFIG_IS_ENABLED(ACPIGEN) +#define ACPI_OPS_PTR(_ptr) .acpi_ops = _ptr, +#else +#define ACPI_OPS_PTR(_ptr) +#endif + +/* Length of an ACPI name string, excluding nul terminator */ +#define ACPI_NAME_LEN 4 + +/* Length of an ACPI name string including nul terminator */ +#define ACPI_NAME_MAX (ACPI_NAME_LEN + 1) + +/** + * struct acpi_ops - ACPI operations supported by driver model + */ +struct acpi_ops { + /** + * get_name() - Obtain the ACPI name of a device + * + * @dev: Device to check + * @out_name: Place to put the name, must hold at least ACPI_NAME_MAX + * bytes + * @return 0 if OK, -ENOENT if no name is available, other -ve value on + * other error + */ + int (*get_name)(const struct udevice *dev, char *out_name); +}; + +#define device_get_acpi_ops(dev) ((dev)->driver->acpi_ops) + +/** + * acpi_get_name() - Obtain the ACPI name of a device + * + * @dev: Device to check + * @out_name: Place to put the name, must hold at least ACPI_NAME_MAX + * bytes + * @return 0 if OK, -ENOENT if no name is available, other -ve value on + * other error + */ +int acpi_get_name(const struct udevice *dev, char *out_name); + +/** + * acpi_copy_name() - Copy an ACPI name to an output buffer + * + * This convenience function can be used to return a literal string as a name + * in functions that implement the get_name() method. + * + * For example: + * + * static int mydev_get_name(const struct udevice *dev, char *out_name) + * { + * return acpi_copy_name(out_name, "WIBB"); + * } + * + * @out_name: Place to put the name + * @name: Name to copy + * @return 0 (always) + */ +int acpi_copy_name(char *out_name, const char *name); + +#endif diff --git a/include/dm/device.h b/include/dm/device.h index a56164b19bb..35e19d87005 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -245,6 +245,8 @@ struct udevice_id { * pointers defined by the driver, to implement driver functions required by * the uclass. * @flags: driver flags - see DM_FLAGS_... + * @acpi_ops: Advanced Configuration and Power Interface (ACPI) operations, + * allowing the device to add things to the ACPI tables passed to Linux */ struct driver { char *name; @@ -264,6 +266,9 @@ struct driver { int per_child_platdata_auto_alloc_size; const void *ops; /* driver-specific operations */ uint32_t flags; +#if CONFIG_IS_ENABLED(ACPIGEN) + struct acpi_ops *acpi_ops; +#endif }; /* Declare a new U-Boot driver */ diff --git a/include/log.h b/include/log.h index 62fb8afbd0e..fbcbd42fb4b 100644 --- a/include/log.h +++ b/include/log.h @@ -51,6 +51,8 @@ enum log_category_t { LOGC_SANDBOX, /* Related to the sandbox board */ LOGC_BLOBLIST, /* Bloblist */ LOGC_DEVRES, /* Device resources (devres_... functions) */ + /* Advanced Configuration and Power Interface (ACPI) */ + LOGC_ACPI, LOGC_COUNT, /* Number of log categories */ LOGC_END, /* Sentinel value for a list of log categories */ |