diff options
-rw-r--r-- | drivers/irqchip/irq-gic-v3-its.c | 38 |
1 files changed, 16 insertions, 22 deletions
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 58dc70e72c45..dc4fbbfa0212 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c | |||
@@ -53,13 +53,12 @@ struct its_collection { | |||
53 | 53 | ||
54 | /* | 54 | /* |
55 | * The ITS structure - contains most of the infrastructure, with the | 55 | * The ITS structure - contains most of the infrastructure, with the |
56 | * msi_controller, the command queue, the collections, and the list of | 56 | * top-level MSI domain, the command queue, the collections, and the |
57 | * devices writing to it. | 57 | * list of devices writing to it. |
58 | */ | 58 | */ |
59 | struct its_node { | 59 | struct its_node { |
60 | raw_spinlock_t lock; | 60 | raw_spinlock_t lock; |
61 | struct list_head entry; | 61 | struct list_head entry; |
62 | struct msi_controller msi_chip; | ||
63 | struct irq_domain *domain; | 62 | struct irq_domain *domain; |
64 | void __iomem *base; | 63 | void __iomem *base; |
65 | unsigned long phys_base; | 64 | unsigned long phys_base; |
@@ -810,7 +809,7 @@ static void its_free_tables(struct its_node *its) | |||
810 | } | 809 | } |
811 | } | 810 | } |
812 | 811 | ||
813 | static int its_alloc_tables(struct its_node *its) | 812 | static int its_alloc_tables(const char *node_name, struct its_node *its) |
814 | { | 813 | { |
815 | int err; | 814 | int err; |
816 | int i; | 815 | int i; |
@@ -853,7 +852,7 @@ static int its_alloc_tables(struct its_node *its) | |||
853 | if (order >= MAX_ORDER) { | 852 | if (order >= MAX_ORDER) { |
854 | order = MAX_ORDER - 1; | 853 | order = MAX_ORDER - 1; |
855 | pr_warn("%s: Device Table too large, reduce its page order to %u\n", | 854 | pr_warn("%s: Device Table too large, reduce its page order to %u\n", |
856 | its->msi_chip.of_node->full_name, order); | 855 | node_name, order); |
857 | } | 856 | } |
858 | } | 857 | } |
859 | 858 | ||
@@ -923,7 +922,7 @@ retry_baser: | |||
923 | 922 | ||
924 | if (val != tmp) { | 923 | if (val != tmp) { |
925 | pr_err("ITS: %s: GITS_BASER%d doesn't stick: %lx %lx\n", | 924 | pr_err("ITS: %s: GITS_BASER%d doesn't stick: %lx %lx\n", |
926 | its->msi_chip.of_node->full_name, i, | 925 | node_name, i, |
927 | (unsigned long) val, (unsigned long) tmp); | 926 | (unsigned long) val, (unsigned long) tmp); |
928 | err = -ENXIO; | 927 | err = -ENXIO; |
929 | goto out_free; | 928 | goto out_free; |
@@ -1354,6 +1353,7 @@ static int its_probe(struct device_node *node, struct irq_domain *parent) | |||
1354 | struct resource res; | 1353 | struct resource res; |
1355 | struct its_node *its; | 1354 | struct its_node *its; |
1356 | void __iomem *its_base; | 1355 | void __iomem *its_base; |
1356 | struct irq_domain *inner_domain = NULL; | ||
1357 | u32 val; | 1357 | u32 val; |
1358 | u64 baser, tmp; | 1358 | u64 baser, tmp; |
1359 | int err; | 1359 | int err; |
@@ -1397,7 +1397,6 @@ static int its_probe(struct device_node *node, struct irq_domain *parent) | |||
1397 | INIT_LIST_HEAD(&its->its_device_list); | 1397 | INIT_LIST_HEAD(&its->its_device_list); |
1398 | its->base = its_base; | 1398 | its->base = its_base; |
1399 | its->phys_base = res.start; | 1399 | its->phys_base = res.start; |
1400 | its->msi_chip.of_node = node; | ||
1401 | its->ite_size = ((readl_relaxed(its_base + GITS_TYPER) >> 4) & 0xf) + 1; | 1400 | its->ite_size = ((readl_relaxed(its_base + GITS_TYPER) >> 4) & 0xf) + 1; |
1402 | 1401 | ||
1403 | its->cmd_base = kzalloc(ITS_CMD_QUEUE_SZ, GFP_KERNEL); | 1402 | its->cmd_base = kzalloc(ITS_CMD_QUEUE_SZ, GFP_KERNEL); |
@@ -1407,7 +1406,7 @@ static int its_probe(struct device_node *node, struct irq_domain *parent) | |||
1407 | } | 1406 | } |
1408 | its->cmd_write = its->cmd_base; | 1407 | its->cmd_write = its->cmd_base; |
1409 | 1408 | ||
1410 | err = its_alloc_tables(its); | 1409 | err = its_alloc_tables(node->full_name, its); |
1411 | if (err) | 1410 | if (err) |
1412 | goto out_free_cmd; | 1411 | goto out_free_cmd; |
1413 | 1412 | ||
@@ -1443,26 +1442,21 @@ static int its_probe(struct device_node *node, struct irq_domain *parent) | |||
1443 | writeq_relaxed(0, its->base + GITS_CWRITER); | 1442 | writeq_relaxed(0, its->base + GITS_CWRITER); |
1444 | writel_relaxed(GITS_CTLR_ENABLE, its->base + GITS_CTLR); | 1443 | writel_relaxed(GITS_CTLR_ENABLE, its->base + GITS_CTLR); |
1445 | 1444 | ||
1446 | if (of_property_read_bool(its->msi_chip.of_node, "msi-controller")) { | 1445 | if (of_property_read_bool(node, "msi-controller")) { |
1447 | its->domain = irq_domain_add_tree(node, &its_domain_ops, its); | 1446 | inner_domain = irq_domain_add_tree(node, &its_domain_ops, its); |
1448 | if (!its->domain) { | 1447 | if (!inner_domain) { |
1449 | err = -ENOMEM; | 1448 | err = -ENOMEM; |
1450 | goto out_free_tables; | 1449 | goto out_free_tables; |
1451 | } | 1450 | } |
1452 | 1451 | ||
1453 | its->domain->parent = parent; | 1452 | inner_domain->parent = parent; |
1454 | its->domain->bus_token = DOMAIN_BUS_NEXUS; | 1453 | inner_domain->bus_token = DOMAIN_BUS_NEXUS; |
1455 | 1454 | ||
1456 | its->msi_chip.domain = its_pci_msi_alloc_domain(node, | 1455 | its->domain = its_pci_msi_alloc_domain(node, inner_domain); |
1457 | its->domain); | 1456 | if (!its->domain) { |
1458 | if (!its->msi_chip.domain) { | ||
1459 | err = -ENOMEM; | 1457 | err = -ENOMEM; |
1460 | goto out_free_domains; | 1458 | goto out_free_domains; |
1461 | } | 1459 | } |
1462 | |||
1463 | err = of_pci_msi_chip_add(&its->msi_chip); | ||
1464 | if (err) | ||
1465 | goto out_free_domains; | ||
1466 | } | 1460 | } |
1467 | 1461 | ||
1468 | spin_lock(&its_lock); | 1462 | spin_lock(&its_lock); |
@@ -1472,10 +1466,10 @@ static int its_probe(struct device_node *node, struct irq_domain *parent) | |||
1472 | return 0; | 1466 | return 0; |
1473 | 1467 | ||
1474 | out_free_domains: | 1468 | out_free_domains: |
1475 | if (its->msi_chip.domain) | ||
1476 | irq_domain_remove(its->msi_chip.domain); | ||
1477 | if (its->domain) | 1469 | if (its->domain) |
1478 | irq_domain_remove(its->domain); | 1470 | irq_domain_remove(its->domain); |
1471 | if (inner_domain) | ||
1472 | irq_domain_remove(inner_domain); | ||
1479 | out_free_tables: | 1473 | out_free_tables: |
1480 | its_free_tables(its); | 1474 | its_free_tables(its); |
1481 | out_free_cmd: | 1475 | out_free_cmd: |