@@ -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);
}
@@ -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; }
Add a function to register an IORT table from an external source. Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org> --- drivers/acpi/iort.c | 22 ++++++++++++++++++++-- include/linux/acpi_iort.h | 10 ++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-)