diff options
author | Marc Zyngier | 2015-10-13 13:51:33 +0200 |
---|---|---|
committer | Thomas Gleixner | 2015-10-13 19:01:23 +0200 |
commit | f833f57ff25450b7161798dceaf8575a48d80249 (patch) | |
tree | d1d8af957f01065cbfbf76c5f4975a0e90d013fb /drivers/irqchip/irq-gic.c | |
parent | irqdomain: Introduce a firmware-specific IRQ specifier structure (diff) | |
download | kernel-qcow2-linux-f833f57ff25450b7161798dceaf8575a48d80249.tar.gz kernel-qcow2-linux-f833f57ff25450b7161798dceaf8575a48d80249.tar.xz kernel-qcow2-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-gic.c')
-rw-r--r-- | drivers/irqchip/irq-gic.c | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index abdccfb9ad22..9262bb9b442b 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -940,6 +940,32 @@ static int gic_irq_domain_xlate(struct irq_domain *d, return ret; } +static int gic_irq_domain_translate(struct irq_domain *d, + struct irq_fwspec *fwspec, + unsigned long *hwirq, + unsigned int *type) +{ + if (is_of_node(fwspec->fwnode)) { + if (fwspec->param_count < 3) + return -EINVAL; + + /* Get the interrupt number and add 16 to skip over SGIs */ + *hwirq = fwspec->param[1] + 16; + + /* + * For SPIs, we need to add 16 more to get the GIC irq + * ID number + */ + if (!fwspec->param[0]) + *hwirq += 16; + + *type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK; + return 0; + } + + return -EINVAL; +} + #ifdef CONFIG_SMP static int gic_secondary_init(struct notifier_block *nfb, unsigned long action, void *hcpu) @@ -965,10 +991,9 @@ static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, int i, ret; irq_hw_number_t hwirq; unsigned int type = IRQ_TYPE_NONE; - struct of_phandle_args *irq_data = arg; + struct irq_fwspec *fwspec = arg; - ret = gic_irq_domain_xlate(domain, irq_data->np, irq_data->args, - irq_data->args_count, &hwirq, &type); + ret = gic_irq_domain_translate(domain, fwspec, &hwirq, &type); if (ret) return ret; @@ -979,7 +1004,7 @@ static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, } static const struct irq_domain_ops gic_irq_domain_hierarchy_ops = { - .xlate = gic_irq_domain_xlate, + .translate = gic_irq_domain_translate, .alloc = gic_irq_domain_alloc, .free = irq_domain_free_irqs_top, }; |