Add a function to register an IORT table from an external source. Signed-off-by: Jean-Philippe Brucker <jean-philippe@xxxxxxxxxx> --- 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