|
@@ -700,16 +700,12 @@ static int gic_irq_domain_xlate(struct irq_domain *d, struct device_node *ctrlr,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int gic_irq_domain_alloc(struct irq_domain *d, unsigned int virq,
|
|
|
- unsigned int nr_irqs, void *arg)
|
|
|
+static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq,
|
|
|
+ irq_hw_number_t hwirq)
|
|
|
{
|
|
|
- struct irq_fwspec *fwspec = arg;
|
|
|
- irq_hw_number_t hwirq;
|
|
|
int err;
|
|
|
|
|
|
- if (fwspec->param[0] == GIC_SHARED) {
|
|
|
- hwirq = GIC_SHARED_TO_HWIRQ(fwspec->param[1]);
|
|
|
-
|
|
|
+ if (hwirq >= GIC_SHARED_HWIRQ_BASE) {
|
|
|
/* verify that shared irqs don't conflict with an IPI irq */
|
|
|
if (test_bit(GIC_HWIRQ_TO_SHARED(hwirq), ipi_resrv))
|
|
|
return -EBUSY;
|
|
@@ -723,8 +719,6 @@ static int gic_irq_domain_alloc(struct irq_domain *d, unsigned int virq,
|
|
|
return gic_shared_irq_domain_map(d, virq, hwirq, 0);
|
|
|
}
|
|
|
|
|
|
- hwirq = GIC_LOCAL_TO_HWIRQ(fwspec->param[1]);
|
|
|
-
|
|
|
switch (GIC_HWIRQ_TO_LOCAL(hwirq)) {
|
|
|
case GIC_LOCAL_INT_TIMER:
|
|
|
case GIC_LOCAL_INT_PERFCTR:
|
|
@@ -758,6 +752,20 @@ static int gic_irq_domain_alloc(struct irq_domain *d, unsigned int virq,
|
|
|
return gic_local_irq_domain_map(d, virq, hwirq);
|
|
|
}
|
|
|
|
|
|
+static int gic_irq_domain_alloc(struct irq_domain *d, unsigned int virq,
|
|
|
+ unsigned int nr_irqs, void *arg)
|
|
|
+{
|
|
|
+ struct irq_fwspec *fwspec = arg;
|
|
|
+ irq_hw_number_t hwirq;
|
|
|
+
|
|
|
+ if (fwspec->param[0] == GIC_SHARED)
|
|
|
+ hwirq = GIC_SHARED_TO_HWIRQ(fwspec->param[1]);
|
|
|
+ else
|
|
|
+ hwirq = GIC_LOCAL_TO_HWIRQ(fwspec->param[1]);
|
|
|
+
|
|
|
+ return gic_irq_domain_map(d, virq, hwirq);
|
|
|
+}
|
|
|
+
|
|
|
void gic_irq_domain_free(struct irq_domain *d, unsigned int virq,
|
|
|
unsigned int nr_irqs)
|
|
|
{
|
|
@@ -767,6 +775,7 @@ static const struct irq_domain_ops gic_irq_domain_ops = {
|
|
|
.xlate = gic_irq_domain_xlate,
|
|
|
.alloc = gic_irq_domain_alloc,
|
|
|
.free = gic_irq_domain_free,
|
|
|
+ .map = gic_irq_domain_map,
|
|
|
};
|
|
|
|
|
|
static int gic_ipi_domain_xlate(struct irq_domain *d, struct device_node *ctrlr,
|
|
@@ -872,38 +881,6 @@ static struct irq_domain_ops gic_ipi_domain_ops = {
|
|
|
.match = gic_ipi_domain_match,
|
|
|
};
|
|
|
|
|
|
-static void __init gic_map_single_int(struct device_node *node,
|
|
|
- unsigned int irq)
|
|
|
-{
|
|
|
- unsigned int linux_irq;
|
|
|
- struct irq_fwspec local_int_fwspec = {
|
|
|
- .fwnode = &node->fwnode,
|
|
|
- .param_count = 3,
|
|
|
- .param = {
|
|
|
- [0] = GIC_LOCAL,
|
|
|
- [1] = irq,
|
|
|
- [2] = IRQ_TYPE_NONE,
|
|
|
- },
|
|
|
- };
|
|
|
-
|
|
|
- if (!gic_local_irq_is_routable(irq))
|
|
|
- return;
|
|
|
-
|
|
|
- linux_irq = irq_create_fwspec_mapping(&local_int_fwspec);
|
|
|
- WARN_ON(!linux_irq);
|
|
|
-}
|
|
|
-
|
|
|
-static void __init gic_map_interrupts(struct device_node *node)
|
|
|
-{
|
|
|
- gic_map_single_int(node, GIC_LOCAL_INT_WD);
|
|
|
- gic_map_single_int(node, GIC_LOCAL_INT_COMPARE);
|
|
|
- gic_map_single_int(node, GIC_LOCAL_INT_TIMER);
|
|
|
- gic_map_single_int(node, GIC_LOCAL_INT_PERFCTR);
|
|
|
- gic_map_single_int(node, GIC_LOCAL_INT_SWINT0);
|
|
|
- gic_map_single_int(node, GIC_LOCAL_INT_SWINT1);
|
|
|
- gic_map_single_int(node, GIC_LOCAL_INT_FDC);
|
|
|
-}
|
|
|
-
|
|
|
static void __init __gic_init(unsigned long gic_base_addr,
|
|
|
unsigned long gic_addrspace_size,
|
|
|
unsigned int cpu_vec, unsigned int irqbase,
|
|
@@ -997,7 +974,6 @@ static void __init __gic_init(unsigned long gic_base_addr,
|
|
|
|
|
|
bitmap_copy(ipi_available, ipi_resrv, GIC_MAX_INTRS);
|
|
|
gic_basic_init();
|
|
|
- gic_map_interrupts(node);
|
|
|
}
|
|
|
|
|
|
void __init gic_init(unsigned long gic_base_addr,
|