Add a function to register an IORT table from an external source.
Signed-off-by: Jean-Philippe Brucker <[email protected]>
---
drivers/acpi/iort.c | 22 ++++++++++++++++++++--
include/linux/acpi_iort.h | 10 ++++++++++
2 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c
index d62a9ea26fae..9c6c91e06f8f 100644
--- a/drivers/acpi/iort.c
+++ b/drivers/acpi/iort.c
@@ -144,6 +144,7 @@ typedef acpi_status (*iort_find_node_callback)
/* Root pointer to the mapped IORT table */
static struct acpi_table_header *iort_table;
+static enum iort_table_source iort_table_source;
static LIST_HEAD(iort_msi_chip_list);
static DEFINE_SPINLOCK(iort_msi_chip_lock);
@@ -1617,11 +1618,28 @@ static void __init iort_init_platform_devices(void)
}
}
+void __init acpi_iort_register_table(struct acpi_table_header *table,
+ enum iort_table_source source)
+{
+ /*
+ * Firmware or hypervisor should know better than give us two IORT
+ * tables.
+ */
+ if (WARN_ON(iort_table))
+ return;
+
+ iort_table = table;
+ iort_table_source = source;
+
+ iort_init_platform_devices();
+}
+
void __init acpi_iort_init(void)
{
acpi_status status;
+ static struct acpi_table_header *table;
- status = acpi_get_table(ACPI_SIG_IORT, 0, &iort_table);
+ status = acpi_get_table(ACPI_SIG_IORT, 0, &table);
if (ACPI_FAILURE(status)) {
if (status != AE_NOT_FOUND) {
const char *msg = acpi_format_exception(status);
@@ -1632,5 +1650,5 @@ void __init acpi_iort_init(void)
return;
}
- iort_init_platform_devices();
+ acpi_iort_register_table(table, IORT_SOURCE_IORT);
}
diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
index 8e7e2ec37f1b..f4db5fff07cf 100644
--- a/include/linux/acpi_iort.h
+++ b/include/linux/acpi_iort.h
@@ -11,6 +11,11 @@
#include <linux/fwnode.h>
#include <linux/irqdomain.h>
+enum iort_table_source {
+ IORT_SOURCE_IORT, /* The Real Thing */
+ IORT_SOURCE_VIOT, /* Paravirtual extensions */
+};
+
#define IORT_IRQ_MASK(irq) (irq & 0xffffffffULL)
#define IORT_IRQ_TRIGGER_MASK(irq) ((irq >> 32) & 0xffffffffULL)
@@ -27,6 +32,8 @@ int iort_register_domain_token(int trans_id, phys_addr_t base,
void iort_deregister_domain_token(int trans_id);
struct fwnode_handle *iort_find_domain_token(int trans_id);
#ifdef CONFIG_ACPI_IORT
+void acpi_iort_register_table(struct acpi_table_header *table,
+ enum iort_table_source source);
void acpi_iort_init(void);
u32 iort_msi_map_rid(struct device *dev, u32 req_id);
struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id);
@@ -37,6 +44,9 @@ void iort_dma_setup(struct device *dev, u64 *dma_addr, u64
*size);
const struct iommu_ops *iort_iommu_configure(struct device *dev);
int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head
*head);
#else
+static void acpi_iort_register_table(struct acpi_table_header *table,
+ enum iort_table_source source)
+{ }
static inline void acpi_iort_init(void) { }
static inline u32 iort_msi_map_rid(struct device *dev, u32 req_id)
{ return req_id; }
--
2.24.0
_______________________________________________
iommu mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/iommu