|
@@ -78,10 +78,13 @@ static struct irq_chip crossbar_chip = {
|
|
|
static int allocate_gic_irq(struct irq_domain *domain, unsigned virq,
|
|
|
irq_hw_number_t hwirq)
|
|
|
{
|
|
|
- struct of_phandle_args args;
|
|
|
+ struct irq_fwspec fwspec;
|
|
|
int i;
|
|
|
int err;
|
|
|
|
|
|
+ if (!irq_domain_get_of_node(domain->parent))
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
raw_spin_lock(&cb->lock);
|
|
|
for (i = cb->int_max - 1; i >= 0; i--) {
|
|
|
if (cb->irq_map[i] == IRQ_FREE) {
|
|
@@ -94,13 +97,13 @@ static int allocate_gic_irq(struct irq_domain *domain, unsigned virq,
|
|
|
if (i < 0)
|
|
|
return -ENODEV;
|
|
|
|
|
|
- args.np = irq_domain_get_of_node(domain->parent);
|
|
|
- args.args_count = 3;
|
|
|
- args.args[0] = 0; /* SPI */
|
|
|
- args.args[1] = i;
|
|
|
- args.args[2] = IRQ_TYPE_LEVEL_HIGH;
|
|
|
+ fwspec.fwnode = domain->parent->fwnode;
|
|
|
+ fwspec.param_count = 3;
|
|
|
+ fwspec.param[0] = 0; /* SPI */
|
|
|
+ fwspec.param[1] = i;
|
|
|
+ fwspec.param[2] = IRQ_TYPE_LEVEL_HIGH;
|
|
|
|
|
|
- err = irq_domain_alloc_irqs_parent(domain, virq, 1, &args);
|
|
|
+ err = irq_domain_alloc_irqs_parent(domain, virq, 1, &fwspec);
|
|
|
if (err)
|
|
|
cb->irq_map[i] = IRQ_FREE;
|
|
|
else
|
|
@@ -112,16 +115,16 @@ static int allocate_gic_irq(struct irq_domain *domain, unsigned virq,
|
|
|
static int crossbar_domain_alloc(struct irq_domain *d, unsigned int virq,
|
|
|
unsigned int nr_irqs, void *data)
|
|
|
{
|
|
|
- struct of_phandle_args *args = data;
|
|
|
+ struct irq_fwspec *fwspec = data;
|
|
|
irq_hw_number_t hwirq;
|
|
|
int i;
|
|
|
|
|
|
- if (args->args_count != 3)
|
|
|
+ if (fwspec->param_count != 3)
|
|
|
return -EINVAL; /* Not GIC compliant */
|
|
|
- if (args->args[0] != 0)
|
|
|
+ if (fwspec->param[0] != 0)
|
|
|
return -EINVAL; /* No PPI should point to this domain */
|
|
|
|
|
|
- hwirq = args->args[1];
|
|
|
+ hwirq = fwspec->param[1];
|
|
|
if ((hwirq + nr_irqs) > cb->max_crossbar_sources)
|
|
|
return -EINVAL; /* Can't deal with this */
|
|
|
|
|
@@ -166,28 +169,31 @@ static void crossbar_domain_free(struct irq_domain *domain, unsigned int virq,
|
|
|
raw_spin_unlock(&cb->lock);
|
|
|
}
|
|
|
|
|
|
-static int crossbar_domain_xlate(struct irq_domain *d,
|
|
|
- struct device_node *controller,
|
|
|
- const u32 *intspec, unsigned int intsize,
|
|
|
- unsigned long *out_hwirq,
|
|
|
- unsigned int *out_type)
|
|
|
+static int crossbar_domain_translate(struct irq_domain *d,
|
|
|
+ struct irq_fwspec *fwspec,
|
|
|
+ unsigned long *hwirq,
|
|
|
+ unsigned int *type)
|
|
|
{
|
|
|
- if (irq_domain_get_of_node(d) != controller)
|
|
|
- return -EINVAL; /* Shouldn't happen, really... */
|
|
|
- if (intsize != 3)
|
|
|
- return -EINVAL; /* Not GIC compliant */
|
|
|
- if (intspec[0] != 0)
|
|
|
- return -EINVAL; /* No PPI should point to this domain */
|
|
|
+ if (is_of_node(fwspec->fwnode)) {
|
|
|
+ if (fwspec->param_count != 3)
|
|
|
+ return -EINVAL;
|
|
|
|
|
|
- *out_hwirq = intspec[1];
|
|
|
- *out_type = intspec[2];
|
|
|
- return 0;
|
|
|
+ /* No PPI should point to this domain */
|
|
|
+ if (fwspec->param[0] != 0)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ *hwirq = fwspec->param[1];
|
|
|
+ *type = fwspec->param[2];
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ return -EINVAL;
|
|
|
}
|
|
|
|
|
|
static const struct irq_domain_ops crossbar_domain_ops = {
|
|
|
- .alloc = crossbar_domain_alloc,
|
|
|
- .free = crossbar_domain_free,
|
|
|
- .xlate = crossbar_domain_xlate,
|
|
|
+ .alloc = crossbar_domain_alloc,
|
|
|
+ .free = crossbar_domain_free,
|
|
|
+ .translate = crossbar_domain_translate,
|
|
|
};
|
|
|
|
|
|
static int __init crossbar_of_init(struct device_node *node)
|