@@ -594,6 +594,9 @@ config ACPI_PRMT
substantially increase computational overhead related to the
initialization of some server systems.
+config ACPI_NHLT
+ bool
+
endif # ACPI
config X86_PM_TIMER
@@ -93,6 +93,7 @@ obj-$(CONFIG_ACPI) += container.o
obj-$(CONFIG_ACPI_THERMAL) += thermal.o
obj-$(CONFIG_ACPI_PLATFORM_PROFILE) += platform_profile.o
obj-$(CONFIG_ACPI_NFIT) += nfit/
+obj-$(CONFIG_ACPI_NHLT) += nhlt.o
obj-$(CONFIG_ACPI_NUMA) += numa/
obj-$(CONFIG_ACPI) += acpi_memhotplug.o
obj-$(CONFIG_ACPI_HOTPLUG_IOAPIC) += ioapic.o
new file mode 100644
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright(c) 2023 Intel Corporation. All rights reserved.
+//
+// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
+// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
+//
+
+#include <linux/export.h>
+#include <acpi/nhlt.h>
+
+struct acpi_table_nhlt *acpi_gbl_nhlt;
+EXPORT_SYMBOL_GPL(acpi_gbl_nhlt);
+
+static struct acpi_table_nhlt empty_nhlt = {
+ .header = {
+ .signature = ACPI_SIG_NHLT,
+ },
+};
+
+/**
+ * acpi_nhlt_get_gbl_table - Retrieve a pointer to the first NHLT table.
+ *
+ * If there is no NHLT in the system, acpi_gbl_nhlt will instead point to an
+ * empty table.
+ *
+ * Return: ACPI status code of the operation.
+ */
+acpi_status acpi_nhlt_get_gbl_table(void)
+{
+ acpi_status status;
+
+ status = acpi_get_table(ACPI_SIG_NHLT, 0, (struct acpi_table_header **)(&acpi_gbl_nhlt));
+ if (!acpi_gbl_nhlt)
+ acpi_gbl_nhlt = &empty_nhlt;
+ return status;
+}
+EXPORT_SYMBOL_GPL(acpi_nhlt_get_gbl_table);
+
+/**
+ * acpi_nhlt_put_gbl_table - Release the global NHLT table.
+ */
+void acpi_nhlt_put_gbl_table(void)
+{
+ acpi_put_table((struct acpi_table_header *)acpi_gbl_nhlt);
+}
+EXPORT_SYMBOL_GPL(acpi_nhlt_put_gbl_table);
@@ -63,4 +63,34 @@
__cfg->capabilities_size == struct_size(__cfg, mics, __cfg->num_mics) ? \
__cfg : NULL; })
+#if IS_ENABLED(CONFIG_ACPI_NHLT)
+
+/*
+ * System-wide pointer to the first NHLT table.
+ *
+ * A sound driver may utilize acpi_nhlt_get/put_gbl_table() on its
+ * initialization and removal respectively to avoid excessive mapping
+ * and unmapping of the memory occupied by the table between streaming
+ * operations.
+ */
+extern struct acpi_table_nhlt *acpi_gbl_nhlt;
+
+acpi_status acpi_nhlt_get_gbl_table(void);
+void acpi_nhlt_put_gbl_table(void);
+
+#else /* !CONFIG_ACPI_NHLT */
+
+#define acpi_gbl_nhlt NULL
+
+static inline acpi_status acpi_nhlt_get_gbl_table(void)
+{
+ return AE_NOT_FOUND;
+}
+
+static inline void acpi_nhlt_put_gbl_table(void)
+{
+}
+
+#endif /* CONFIG_ACPI_NHLT */
+
#endif /* __ACPI_NHLT_H__ */
While there is no strict limit to amount of NHLT tables present, usually just the first one is utilized. To simplify implementation of sound drivers, provide publicly accessible pointer. Accessing it after calling acpi_nhlt_get_gbl_table() yields the first NHLT table met during the scan. Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com> --- drivers/acpi/Kconfig | 3 +++ drivers/acpi/Makefile | 1 + drivers/acpi/nhlt.c | 47 +++++++++++++++++++++++++++++++++++++++++++ include/acpi/nhlt.h | 30 +++++++++++++++++++++++++++ 4 files changed, 81 insertions(+) create mode 100644 drivers/acpi/nhlt.c