@@ -98,8 +98,38 @@ static struct msi_domain_info its_pci_msi_domain_info = {
.chip = &its_msi_irq_chip,
};
-struct irq_domain *its_pci_msi_alloc_domain(struct device_node *np,
- struct irq_domain *parent)
+static struct of_device_id its_device_id[] = {
+ { .compatible = "arm,gic-v3-its", },
+ {},
+};
+
+static int __init its_pci_msi_init(void)
{
- return pci_msi_create_irq_domain(np, &its_pci_msi_domain_info, parent);
+ struct device_node *np;
+ struct irq_domain *parent;
+
+ for (np = of_find_matching_node(NULL, its_device_id); np;
+ np = of_find_matching_node(np, its_device_id)) {
+ if (!of_property_read_bool(np, "msi-controller"))
+ continue;
+
+ parent = irq_find_matching_host(np, DOMAIN_BUS_PLATFORM_MSI);
+ if (!parent) {
+ pr_err("%s: unable to locate ITS domain\n",
+ np->full_name);
+ continue;
+ }
+
+ if (!pci_msi_create_irq_domain(np, &its_pci_msi_domain_info,
+ parent)) {
+ pr_err("%s: unable to create PCI domain\n",
+ np->full_name);
+ continue;
+ }
+
+ pr_info("PCI/MSI: %s domain created\n", np->full_name);
+ }
+
+ return 0;
}
+subsys_initcall(its_pci_msi_init);
@@ -60,7 +60,6 @@ struct its_collection {
struct its_node {
raw_spinlock_t lock;
struct list_head entry;
- struct irq_domain *domain;
void __iomem *base;
unsigned long phys_base;
struct its_cmd_block *cmd_base;
@@ -1316,7 +1315,7 @@ static int its_probe(struct device_node *node, struct irq_domain *parent)
struct resource res;
struct its_node *its;
void __iomem *its_base;
- struct irq_domain *inner_domain = NULL;
+ struct irq_domain *inner_domain;
u32 val;
u64 baser, tmp;
int err;
@@ -1414,12 +1413,6 @@ static int its_probe(struct device_node *node, struct irq_domain *parent)
inner_domain->parent = parent;
inner_domain->bus_token = DOMAIN_BUS_PLATFORM_MSI;
-
- its->domain = its_pci_msi_alloc_domain(node, inner_domain);
- if (!its->domain) {
- err = -ENOMEM;
- goto out_free_domains;
- }
}
spin_lock(&its_lock);
@@ -1428,11 +1421,6 @@ static int its_probe(struct device_node *node, struct irq_domain *parent)
return 0;
-out_free_domains:
- if (its->domain)
- irq_domain_remove(its->domain);
- if (inner_domain)
- irq_domain_remove(inner_domain);
out_free_tables:
its_free_tables(its);
out_free_cmd:
@@ -392,9 +392,6 @@ int its_init(struct device_node *node, struct rdists *rdists,
int its_msi_prepare(struct irq_domain *domain, u32 dev_id,
int nvec, msi_alloc_info_t *info);
-struct irq_domain *its_pci_msi_alloc_domain(struct device_node *node,
- struct irq_domain *parent);
-
#endif
#endif
We can now lookup the base ITS domain, making it possible to initialize the PCI/MSI code independently from the main ITS subsystem. Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> --- drivers/irqchip/irq-gic-v3-its-pci-msi.c | 36 +++++++++++++++++++++++++++++--- drivers/irqchip/irq-gic-v3-its.c | 14 +------------ include/linux/irqchip/arm-gic-v3.h | 3 --- 3 files changed, 34 insertions(+), 19 deletions(-)