aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2018-05-27 11:39:55 -0400
committerMarc Zyngier <marc.zyngier@arm.com>2018-07-16 09:22:19 -0400
commit147c8f376e5526ebfaf2827734916414db52a3c4 (patch)
treee119d83c2ae863e4e8277aad6f42e1111a104d49 /drivers
parentfe8e93504ce870cb60b5dca97d13d861a53d7353 (diff)
irqchip/gic-v3-its: Move minimum LPI requirements to individual busses
At the moment, the core ITS driver imposes the allocation to be in chunks of 32. As we want to relax this on a per bus basis, let's move the the the allocation constraints to each bus. No functionnal change. Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c3
-rw-r--r--drivers/irqchip/irq-gic-v3-its-pci-msi.c6
-rw-r--r--drivers/irqchip/irq-gic-v3-its-platform-msi.c2
-rw-r--r--drivers/irqchip/irq-gic-v3-its.c11
4 files changed, 16 insertions, 6 deletions
diff --git a/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c b/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c
index 4eca5c763766..606efa64adff 100644
--- a/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c
@@ -45,6 +45,9 @@ static int its_fsl_mc_msi_prepare(struct irq_domain *msi_domain,
45 */ 45 */
46 info->scratchpad[0].ul = mc_bus_dev->icid; 46 info->scratchpad[0].ul = mc_bus_dev->icid;
47 msi_info = msi_get_domain_info(msi_domain->parent); 47 msi_info = msi_get_domain_info(msi_domain->parent);
48
49 /* Allocate at least 32 MSIs, and always as a power of 2 */
50 nvec = max_t(int, 32, roundup_pow_of_two(nvec));
48 return msi_info->ops->msi_prepare(msi_domain->parent, dev, nvec, info); 51 return msi_info->ops->msi_prepare(msi_domain->parent, dev, nvec, info);
49} 52}
50 53
diff --git a/drivers/irqchip/irq-gic-v3-its-pci-msi.c b/drivers/irqchip/irq-gic-v3-its-pci-msi.c
index 25a98de5cfb2..75c3cafabc6a 100644
--- a/drivers/irqchip/irq-gic-v3-its-pci-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-pci-msi.c
@@ -86,8 +86,10 @@ static int its_pci_msi_prepare(struct irq_domain *domain, struct device *dev,
86 /* ITS specific DeviceID, as the core ITS ignores dev. */ 86 /* ITS specific DeviceID, as the core ITS ignores dev. */
87 info->scratchpad[0].ul = pci_msi_domain_get_msi_rid(domain, pdev); 87 info->scratchpad[0].ul = pci_msi_domain_get_msi_rid(domain, pdev);
88 88
89 return msi_info->ops->msi_prepare(domain->parent, 89 /* Allocate at least 32 MSIs, and always as a power of 2 */
90 dev, max(nvec, alias_count), info); 90 nvec = max(nvec, alias_count);
91 nvec = max_t(int, 32, roundup_pow_of_two(nvec));
92 return msi_info->ops->msi_prepare(domain->parent, dev, nvec, info);
91} 93}
92 94
93static struct msi_domain_ops its_pci_msi_ops = { 95static struct msi_domain_ops its_pci_msi_ops = {
diff --git a/drivers/irqchip/irq-gic-v3-its-platform-msi.c b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
index 8881a053c173..7b8e87b493fe 100644
--- a/drivers/irqchip/irq-gic-v3-its-platform-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
@@ -73,6 +73,8 @@ static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
73 /* ITS specific DeviceID, as the core ITS ignores dev. */ 73 /* ITS specific DeviceID, as the core ITS ignores dev. */
74 info->scratchpad[0].ul = dev_id; 74 info->scratchpad[0].ul = dev_id;
75 75
76 /* Allocate at least 32 MSIs, and always as a power of 2 */
77 nvec = max_t(int, 32, roundup_pow_of_two(nvec));
76 return msi_info->ops->msi_prepare(domain->parent, 78 return msi_info->ops->msi_prepare(domain->parent,
77 dev, nvec, info); 79 dev, nvec, info);
78} 80}
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 20244006cd82..03ac8d05279d 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -2200,12 +2200,15 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
2200 if (!its_alloc_device_table(its, dev_id)) 2200 if (!its_alloc_device_table(its, dev_id))
2201 return NULL; 2201 return NULL;
2202 2202
2203 if (WARN_ON(!is_power_of_2(nvecs)))
2204 nvecs = roundup_pow_of_two(nvecs);
2205
2203 dev = kzalloc(sizeof(*dev), GFP_KERNEL); 2206 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
2204 /* 2207 /*
2205 * We allocate at least one chunk worth of LPIs bet device, 2208 * Even if the device wants a single LPI, the ITT must be
2206 * and thus that many ITEs. The device may require less though. 2209 * sized as a power of two (and you need at least one bit...).
2207 */ 2210 */
2208 nr_ites = max(IRQS_PER_CHUNK, roundup_pow_of_two(nvecs)); 2211 nr_ites = max(2, nvecs);
2209 sz = nr_ites * its->ite_size; 2212 sz = nr_ites * its->ite_size;
2210 sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1; 2213 sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1;
2211 itt = kzalloc(sz, GFP_KERNEL); 2214 itt = kzalloc(sz, GFP_KERNEL);
@@ -2861,7 +2864,7 @@ static int its_vpe_irq_domain_alloc(struct irq_domain *domain, unsigned int virq
2861 2864
2862 BUG_ON(!vm); 2865 BUG_ON(!vm);
2863 2866
2864 bitmap = its_lpi_alloc_chunks(nr_irqs, &base, &nr_ids); 2867 bitmap = its_lpi_alloc_chunks(roundup_pow_of_two(nr_irqs), &base, &nr_ids);
2865 if (!bitmap) 2868 if (!bitmap)
2866 return -ENOMEM; 2869 return -ENOMEM;
2867 2870