summaryrefslogtreecommitdiffstats
path: root/drivers/irqchip/irq-crossbar.c
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2015-10-13 13:51:33 +0200
committerThomas Gleixner <tglx@linutronix.de>2015-10-13 19:01:23 +0200
commitf833f57ff25450b7161798dceaf8575a48d80249 (patch)
treed1d8af957f01065cbfbf76c5f4975a0e90d013fb /drivers/irqchip/irq-crossbar.c
parentirqdomain: Introduce a firmware-specific IRQ specifier structure (diff)
downloadlinux-f833f57ff25450b7161798dceaf8575a48d80249.tar.xz
linux-f833f57ff25450b7161798dceaf8575a48d80249.zip
irqchip: Convert all alloc/xlate users from of_node to fwnode
Since we now have a generic data structure to express an interrupt specifier, convert all hierarchical irqchips that are OF based to use a fwnode_handle as part of their alloc and xlate (which becomes translate) callbacks. As most of these drivers have dependencies (they exchange IRQ specifiers), change them all in a single, massive patch... Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Reviewed-and-tested-by: Hanjun Guo <hanjun.guo@linaro.org> Tested-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Cc: <linux-arm-kernel@lists.infradead.org> Cc: Tomasz Nowicki <tomasz.nowicki@linaro.org> Cc: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com> Cc: Graeme Gregory <graeme@xora.org.uk> Cc: Jake Oshins <jakeo@microsoft.com> Cc: Jiang Liu <jiang.liu@linux.intel.com> Cc: Jason Cooper <jason@lakedaemon.net> Cc: Rafael J. Wysocki <rjw@rjwysocki.net> Link: http://lkml.kernel.org/r/1444737105-31573-6-git-send-email-marc.zyngier@arm.com Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'drivers/irqchip/irq-crossbar.c')
-rw-r--r--drivers/irqchip/irq-crossbar.c62
1 files changed, 34 insertions, 28 deletions
diff --git a/drivers/irqchip/irq-crossbar.c b/drivers/irqchip/irq-crossbar.c
index f1d666a835a8..75573fa431ba 100644
--- a/drivers/irqchip/irq-crossbar.c
+++ b/drivers/irqchip/irq-crossbar.c
@@ -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)