Hi Marc,
On Thu, Mar 20, 2014 at 4:52 AM, Marc Zyngier <marc.zyngier@xxxxxxx> wrote:
<snip>
+ /*
+ * Find out how many interrupts are supported.
+ * The GIC only supports up to 1020 interrupt sources (SGI+PPI+SPI)
+ */
+ gic_irqs = readl_relaxed(gic_data.dist_base + GICD_TYPER) & 0x1f;
+ gic_irqs = (gic_irqs + 1) * 32;
+ if (gic_irqs > 1020)
+ gic_irqs = 1020;
+ gic_data.irq_nr = gic_irqs;
+
+ gic_data.domain = irq_domain_add_linear(node, gic_irqs - 16,
+ &gic_irq_domain_ops, &gic_data);
Why gic_irqs - 16?
__irq_domain_add(of_node, size, size, 0, ops, host_data);
domain->hwirq_max = hwirq_max;
So hwirq_max is effectively set to actual_hwirq_max-16.
Later, the following warning can be triggered:
int irq_domain_associate(struct irq_domain *domain, unsigned int virq,irq_hw_number_t hwirq){struct irq_data *irq_data = irq_get_irq_data(virq);int ret;if (WARN(hwirq >= domain->hwirq_max,"error: hwirq 0x%x is too large for %s\n", (int)hwirq, domain->name))return -EINVAL;
Thanks,
z
+ gic_data.rdist = alloc_percpu(typeof(*gic_data.rdist));
+
+ if (WARN_ON(!gic_data.domain) || WARN_ON(!gic_data.rdist)) {
+ err = -ENOMEM;
+ goto out_free;
+ }
+
+ set_handle_irq(gic_handle_irq);
+
+ gic_smp_init();
+ gic_dist_init();
+ gic_cpu_init();
+
+ return 0;
+
+out_free:
+ if (gic_data.domain)
+ irq_domain_remove(gic_data.domain);
+ free_percpu(gic_data.rdist);
+out_unmap_rdist:
+ for (i = 0; i < redist_regions; i++)
+ if (redist_base[i])
+ iounmap(redist_base[i]);
+ kfree(redist_base);
+out_unmap_dist:
+ iounmap(dist_base);
+ return err;
+}
+
+IRQCHIP_DECLARE(gic_v3, "arm,gic-v3", gic_of_init);
<snip>
_______________________________________________ kvmarm mailing list kvmarm@xxxxxxxxxxxxxxxxxxxxx https://lists.cs.columbia.edu/mailman/listinfo/kvmarm