|
@@ -2267,13 +2267,14 @@ static void its_free_device(struct its_device *its_dev)
|
|
|
kfree(its_dev);
|
|
kfree(its_dev);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static int its_alloc_device_irq(struct its_device *dev, irq_hw_number_t *hwirq)
|
|
|
|
|
|
|
+static int its_alloc_device_irq(struct its_device *dev, int nvecs, irq_hw_number_t *hwirq)
|
|
|
{
|
|
{
|
|
|
int idx;
|
|
int idx;
|
|
|
|
|
|
|
|
- idx = find_first_zero_bit(dev->event_map.lpi_map,
|
|
|
|
|
- dev->event_map.nr_lpis);
|
|
|
|
|
- if (idx == dev->event_map.nr_lpis)
|
|
|
|
|
|
|
+ idx = bitmap_find_free_region(dev->event_map.lpi_map,
|
|
|
|
|
+ dev->event_map.nr_lpis,
|
|
|
|
|
+ get_count_order(nvecs));
|
|
|
|
|
+ if (idx < 0)
|
|
|
return -ENOSPC;
|
|
return -ENOSPC;
|
|
|
|
|
|
|
|
*hwirq = dev->event_map.lpi_base + idx;
|
|
*hwirq = dev->event_map.lpi_base + idx;
|
|
@@ -2369,21 +2370,21 @@ static int its_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
|
|
|
int err;
|
|
int err;
|
|
|
int i;
|
|
int i;
|
|
|
|
|
|
|
|
- for (i = 0; i < nr_irqs; i++) {
|
|
|
|
|
- err = its_alloc_device_irq(its_dev, &hwirq);
|
|
|
|
|
- if (err)
|
|
|
|
|
- return err;
|
|
|
|
|
|
|
+ err = its_alloc_device_irq(its_dev, nr_irqs, &hwirq);
|
|
|
|
|
+ if (err)
|
|
|
|
|
+ return err;
|
|
|
|
|
|
|
|
- err = its_irq_gic_domain_alloc(domain, virq + i, hwirq);
|
|
|
|
|
|
|
+ for (i = 0; i < nr_irqs; i++) {
|
|
|
|
|
+ err = its_irq_gic_domain_alloc(domain, virq + i, hwirq + i);
|
|
|
if (err)
|
|
if (err)
|
|
|
return err;
|
|
return err;
|
|
|
|
|
|
|
|
irq_domain_set_hwirq_and_chip(domain, virq + i,
|
|
irq_domain_set_hwirq_and_chip(domain, virq + i,
|
|
|
- hwirq, &its_irq_chip, its_dev);
|
|
|
|
|
|
|
+ hwirq + i, &its_irq_chip, its_dev);
|
|
|
irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(virq + i)));
|
|
irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(virq + i)));
|
|
|
pr_debug("ID:%d pID:%d vID:%d\n",
|
|
pr_debug("ID:%d pID:%d vID:%d\n",
|
|
|
- (int)(hwirq - its_dev->event_map.lpi_base),
|
|
|
|
|
- (int) hwirq, virq + i);
|
|
|
|
|
|
|
+ (int)(hwirq + i - its_dev->event_map.lpi_base),
|
|
|
|
|
+ (int)(hwirq + i), virq + i);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
return 0;
|