diff options
Diffstat (limited to 'kernel/drivers/irqchip/irq-crossbar.c')
-rw-r--r-- | kernel/drivers/irqchip/irq-crossbar.c | 65 |
1 files changed, 35 insertions, 30 deletions
diff --git a/kernel/drivers/irqchip/irq-crossbar.c b/kernel/drivers/irqchip/irq-crossbar.c index c12bb9333..75573fa43 100644 --- a/kernel/drivers/irqchip/irq-crossbar.c +++ b/kernel/drivers/irqchip/irq-crossbar.c @@ -11,13 +11,12 @@ */ #include <linux/err.h> #include <linux/io.h> +#include <linux/irqchip.h> #include <linux/irqdomain.h> #include <linux/of_address.h> #include <linux/of_irq.h> #include <linux/slab.h> -#include "irqchip.h" - #define IRQ_FREE -1 #define IRQ_RESERVED -2 #define IRQ_SKIP -3 @@ -79,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) { @@ -95,13 +97,13 @@ static int allocate_gic_irq(struct irq_domain *domain, unsigned virq, if (i < 0) return -ENODEV; - args.np = domain->parent->of_node; - 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 @@ -113,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 */ @@ -167,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 (d->of_node != 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) |