diff options
author | Marc Zyngier <marc.zyngier@arm.com> | 2015-10-13 07:51:33 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2015-10-13 13:01:23 -0400 |
commit | f833f57ff25450b7161798dceaf8575a48d80249 (patch) | |
tree | d1d8af957f01065cbfbf76c5f4975a0e90d013fb | |
parent | 11e4438ee330fab0f216ee7cc1b651cb2ddceb5d (diff) |
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>
-rw-r--r-- | arch/arm/mach-exynos/suspend.c | 55 | ||||
-rw-r--r-- | arch/arm/mach-imx/gpc.c | 55 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap-wakeupgen.c | 55 | ||||
-rw-r--r-- | drivers/irqchip/irq-crossbar.c | 62 | ||||
-rw-r--r-- | drivers/irqchip/irq-gic-v2m.c | 18 | ||||
-rw-r--r-- | drivers/irqchip/irq-gic-v3-its.c | 20 | ||||
-rw-r--r-- | drivers/irqchip/irq-gic-v3.c | 49 | ||||
-rw-r--r-- | drivers/irqchip/irq-gic.c | 33 | ||||
-rw-r--r-- | drivers/irqchip/irq-imx-gpcv2.c | 64 | ||||
-rw-r--r-- | drivers/irqchip/irq-mtk-sysirq.c | 49 | ||||
-rw-r--r-- | drivers/irqchip/irq-nvic.c | 18 | ||||
-rw-r--r-- | drivers/irqchip/irq-tegra.c | 55 | ||||
-rw-r--r-- | drivers/irqchip/irq-vf610-mscm-ir.c | 42 |
13 files changed, 323 insertions, 252 deletions
diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c index af97afc6127a..5a7e47ceec91 100644 --- a/arch/arm/mach-exynos/suspend.c +++ b/arch/arm/mach-exynos/suspend.c | |||
@@ -177,54 +177,57 @@ static struct irq_chip exynos_pmu_chip = { | |||
177 | #endif | 177 | #endif |
178 | }; | 178 | }; |
179 | 179 | ||
180 | static int exynos_pmu_domain_xlate(struct irq_domain *domain, | 180 | static int exynos_pmu_domain_translate(struct irq_domain *d, |
181 | struct device_node *controller, | 181 | struct irq_fwspec *fwspec, |
182 | const u32 *intspec, | 182 | unsigned long *hwirq, |
183 | unsigned int intsize, | 183 | unsigned int *type) |
184 | unsigned long *out_hwirq, | ||
185 | unsigned int *out_type) | ||
186 | { | 184 | { |
187 | if (irq_domain_get_of_node(domain) != controller) | 185 | if (is_of_node(fwspec->fwnode)) { |
188 | return -EINVAL; /* Shouldn't happen, really... */ | 186 | if (fwspec->param_count != 3) |
189 | if (intsize != 3) | 187 | return -EINVAL; |
190 | return -EINVAL; /* Not GIC compliant */ | ||
191 | if (intspec[0] != 0) | ||
192 | return -EINVAL; /* No PPI should point to this domain */ | ||
193 | 188 | ||
194 | *out_hwirq = intspec[1]; | 189 | /* No PPI should point to this domain */ |
195 | *out_type = intspec[2]; | 190 | if (fwspec->param[0] != 0) |
196 | return 0; | 191 | return -EINVAL; |
192 | |||
193 | *hwirq = fwspec->param[1]; | ||
194 | *type = fwspec->param[2]; | ||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | return -EINVAL; | ||
197 | } | 199 | } |
198 | 200 | ||
199 | static int exynos_pmu_domain_alloc(struct irq_domain *domain, | 201 | static int exynos_pmu_domain_alloc(struct irq_domain *domain, |
200 | unsigned int virq, | 202 | unsigned int virq, |
201 | unsigned int nr_irqs, void *data) | 203 | unsigned int nr_irqs, void *data) |
202 | { | 204 | { |
203 | struct of_phandle_args *args = data; | 205 | struct irq_fwspec *fwspec = data; |
204 | struct of_phandle_args parent_args; | 206 | struct irq_fwspec parent_fwspec; |
205 | irq_hw_number_t hwirq; | 207 | irq_hw_number_t hwirq; |
206 | int i; | 208 | int i; |
207 | 209 | ||
208 | if (args->args_count != 3) | 210 | if (fwspec->param_count != 3) |
209 | return -EINVAL; /* Not GIC compliant */ | 211 | return -EINVAL; /* Not GIC compliant */ |
210 | if (args->args[0] != 0) | 212 | if (fwspec->param[0] != 0) |
211 | return -EINVAL; /* No PPI should point to this domain */ | 213 | return -EINVAL; /* No PPI should point to this domain */ |
212 | 214 | ||
213 | hwirq = args->args[1]; | 215 | hwirq = fwspec->param[1]; |
214 | 216 | ||
215 | for (i = 0; i < nr_irqs; i++) | 217 | for (i = 0; i < nr_irqs; i++) |
216 | irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, | 218 | irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, |
217 | &exynos_pmu_chip, NULL); | 219 | &exynos_pmu_chip, NULL); |
218 | 220 | ||
219 | parent_args = *args; | 221 | parent_fwspec = *fwspec; |
220 | parent_args.np = irq_domain_get_of_node(domain->parent); | 222 | parent_fwspec.fwnode = domain->parent->fwnode; |
221 | return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &parent_args); | 223 | return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, |
224 | &parent_fwspec); | ||
222 | } | 225 | } |
223 | 226 | ||
224 | static const struct irq_domain_ops exynos_pmu_domain_ops = { | 227 | static const struct irq_domain_ops exynos_pmu_domain_ops = { |
225 | .xlate = exynos_pmu_domain_xlate, | 228 | .translate = exynos_pmu_domain_translate, |
226 | .alloc = exynos_pmu_domain_alloc, | 229 | .alloc = exynos_pmu_domain_alloc, |
227 | .free = irq_domain_free_irqs_common, | 230 | .free = irq_domain_free_irqs_common, |
228 | }; | 231 | }; |
229 | 232 | ||
230 | static int __init exynos_pmu_irq_init(struct device_node *node, | 233 | static int __init exynos_pmu_irq_init(struct device_node *node, |
diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c index 7b32255028fe..10bf7159b27d 100644 --- a/arch/arm/mach-imx/gpc.c +++ b/arch/arm/mach-imx/gpc.c | |||
@@ -181,40 +181,42 @@ static struct irq_chip imx_gpc_chip = { | |||
181 | #endif | 181 | #endif |
182 | }; | 182 | }; |
183 | 183 | ||
184 | static int imx_gpc_domain_xlate(struct irq_domain *domain, | 184 | static int imx_gpc_domain_translate(struct irq_domain *d, |
185 | struct device_node *controller, | 185 | struct irq_fwspec *fwspec, |
186 | const u32 *intspec, | 186 | unsigned long *hwirq, |
187 | unsigned int intsize, | 187 | unsigned int *type) |
188 | unsigned long *out_hwirq, | ||
189 | unsigned int *out_type) | ||
190 | { | 188 | { |
191 | if (irq_domain_get_of_node(domain) != controller) | 189 | if (is_of_node(fwspec->fwnode)) { |
192 | return -EINVAL; /* Shouldn't happen, really... */ | 190 | if (fwspec->param_count != 3) |
193 | if (intsize != 3) | 191 | return -EINVAL; |
194 | return -EINVAL; /* Not GIC compliant */ | ||
195 | if (intspec[0] != 0) | ||
196 | return -EINVAL; /* No PPI should point to this domain */ | ||
197 | 192 | ||
198 | *out_hwirq = intspec[1]; | 193 | /* No PPI should point to this domain */ |
199 | *out_type = intspec[2]; | 194 | if (fwspec->param[0] != 0) |
200 | return 0; | 195 | return -EINVAL; |
196 | |||
197 | *hwirq = fwspec->param[1]; | ||
198 | *type = fwspec->param[2]; | ||
199 | return 0; | ||
200 | } | ||
201 | |||
202 | return -EINVAL; | ||
201 | } | 203 | } |
202 | 204 | ||
203 | static int imx_gpc_domain_alloc(struct irq_domain *domain, | 205 | static int imx_gpc_domain_alloc(struct irq_domain *domain, |
204 | unsigned int irq, | 206 | unsigned int irq, |
205 | unsigned int nr_irqs, void *data) | 207 | unsigned int nr_irqs, void *data) |
206 | { | 208 | { |
207 | struct of_phandle_args *args = data; | 209 | struct irq_fwspec *fwspec = data; |
208 | struct of_phandle_args parent_args; | 210 | struct irq_fwspec parent_fwspec; |
209 | irq_hw_number_t hwirq; | 211 | irq_hw_number_t hwirq; |
210 | int i; | 212 | int i; |
211 | 213 | ||
212 | if (args->args_count != 3) | 214 | if (fwspec->param_count != 3) |
213 | return -EINVAL; /* Not GIC compliant */ | 215 | return -EINVAL; /* Not GIC compliant */ |
214 | if (args->args[0] != 0) | 216 | if (fwspec->param[0] != 0) |
215 | return -EINVAL; /* No PPI should point to this domain */ | 217 | return -EINVAL; /* No PPI should point to this domain */ |
216 | 218 | ||
217 | hwirq = args->args[1]; | 219 | hwirq = fwspec->param[1]; |
218 | if (hwirq >= GPC_MAX_IRQS) | 220 | if (hwirq >= GPC_MAX_IRQS) |
219 | return -EINVAL; /* Can't deal with this */ | 221 | return -EINVAL; /* Can't deal with this */ |
220 | 222 | ||
@@ -222,15 +224,16 @@ static int imx_gpc_domain_alloc(struct irq_domain *domain, | |||
222 | irq_domain_set_hwirq_and_chip(domain, irq + i, hwirq + i, | 224 | irq_domain_set_hwirq_and_chip(domain, irq + i, hwirq + i, |
223 | &imx_gpc_chip, NULL); | 225 | &imx_gpc_chip, NULL); |
224 | 226 | ||
225 | parent_args = *args; | 227 | parent_fwspec = *fwspec; |
226 | parent_args.np = irq_domain_get_of_node(domain->parent); | 228 | parent_fwspec.fwnode = domain->parent->fwnode; |
227 | return irq_domain_alloc_irqs_parent(domain, irq, nr_irqs, &parent_args); | 229 | return irq_domain_alloc_irqs_parent(domain, irq, nr_irqs, |
230 | &parent_fwspec); | ||
228 | } | 231 | } |
229 | 232 | ||
230 | static const struct irq_domain_ops imx_gpc_domain_ops = { | 233 | static const struct irq_domain_ops imx_gpc_domain_ops = { |
231 | .xlate = imx_gpc_domain_xlate, | 234 | .translate = imx_gpc_domain_translate, |
232 | .alloc = imx_gpc_domain_alloc, | 235 | .alloc = imx_gpc_domain_alloc, |
233 | .free = irq_domain_free_irqs_common, | 236 | .free = irq_domain_free_irqs_common, |
234 | }; | 237 | }; |
235 | 238 | ||
236 | static int __init imx_gpc_init(struct device_node *node, | 239 | static int __init imx_gpc_init(struct device_node *node, |
diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c index f0f7ffd64b1a..db7e0bab3587 100644 --- a/arch/arm/mach-omap2/omap-wakeupgen.c +++ b/arch/arm/mach-omap2/omap-wakeupgen.c | |||
@@ -399,40 +399,42 @@ static struct irq_chip wakeupgen_chip = { | |||
399 | #endif | 399 | #endif |
400 | }; | 400 | }; |
401 | 401 | ||
402 | static int wakeupgen_domain_xlate(struct irq_domain *domain, | 402 | static int wakeupgen_domain_translate(struct irq_domain *d, |
403 | struct device_node *controller, | 403 | struct irq_fwspec *fwspec, |
404 | const u32 *intspec, | 404 | unsigned long *hwirq, |
405 | unsigned int intsize, | 405 | unsigned int *type) |
406 | unsigned long *out_hwirq, | ||
407 | unsigned int *out_type) | ||
408 | { | 406 | { |
409 | if (irq_domain_get_of_node(domain) != controller) | 407 | if (is_of_node(fwspec->fwnode)) { |
410 | return -EINVAL; /* Shouldn't happen, really... */ | 408 | if (fwspec->param_count != 3) |
411 | if (intsize != 3) | 409 | return -EINVAL; |
412 | return -EINVAL; /* Not GIC compliant */ | ||
413 | if (intspec[0] != 0) | ||
414 | return -EINVAL; /* No PPI should point to this domain */ | ||
415 | 410 | ||
416 | *out_hwirq = intspec[1]; | 411 | /* No PPI should point to this domain */ |
417 | *out_type = intspec[2]; | 412 | if (fwspec->param[0] != 0) |
418 | return 0; | 413 | return -EINVAL; |
414 | |||
415 | *hwirq = fwspec->param[1]; | ||
416 | *type = fwspec->param[2]; | ||
417 | return 0; | ||
418 | } | ||
419 | |||
420 | return -EINVAL; | ||
419 | } | 421 | } |
420 | 422 | ||
421 | static int wakeupgen_domain_alloc(struct irq_domain *domain, | 423 | static int wakeupgen_domain_alloc(struct irq_domain *domain, |
422 | unsigned int virq, | 424 | unsigned int virq, |
423 | unsigned int nr_irqs, void *data) | 425 | unsigned int nr_irqs, void *data) |
424 | { | 426 | { |
425 | struct of_phandle_args *args = data; | 427 | struct irq_fwspec *fwspec = data; |
426 | struct of_phandle_args parent_args; | 428 | struct irq_fwspec parent_fwspec; |
427 | irq_hw_number_t hwirq; | 429 | irq_hw_number_t hwirq; |
428 | int i; | 430 | int i; |
429 | 431 | ||
430 | if (args->args_count != 3) | 432 | if (fwspec->param_count != 3) |
431 | return -EINVAL; /* Not GIC compliant */ | 433 | return -EINVAL; /* Not GIC compliant */ |
432 | if (args->args[0] != 0) | 434 | if (fwspec->param[0] != 0) |
433 | return -EINVAL; /* No PPI should point to this domain */ | 435 | return -EINVAL; /* No PPI should point to this domain */ |
434 | 436 | ||
435 | hwirq = args->args[1]; | 437 | hwirq = fwspec->param[1]; |
436 | if (hwirq >= MAX_IRQS) | 438 | if (hwirq >= MAX_IRQS) |
437 | return -EINVAL; /* Can't deal with this */ | 439 | return -EINVAL; /* Can't deal with this */ |
438 | 440 | ||
@@ -440,15 +442,16 @@ static int wakeupgen_domain_alloc(struct irq_domain *domain, | |||
440 | irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, | 442 | irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, |
441 | &wakeupgen_chip, NULL); | 443 | &wakeupgen_chip, NULL); |
442 | 444 | ||
443 | parent_args = *args; | 445 | parent_fwspec = *fwspec; |
444 | parent_args.np = irq_domain_get_of_node(domain->parent); | 446 | parent_fwspec.fwnode = domain->parent->fwnode; |
445 | return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &parent_args); | 447 | return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, |
448 | &parent_fwspec); | ||
446 | } | 449 | } |
447 | 450 | ||
448 | static const struct irq_domain_ops wakeupgen_domain_ops = { | 451 | static const struct irq_domain_ops wakeupgen_domain_ops = { |
449 | .xlate = wakeupgen_domain_xlate, | 452 | .translate = wakeupgen_domain_translate, |
450 | .alloc = wakeupgen_domain_alloc, | 453 | .alloc = wakeupgen_domain_alloc, |
451 | .free = irq_domain_free_irqs_common, | 454 | .free = irq_domain_free_irqs_common, |
452 | }; | 455 | }; |
453 | 456 | ||
454 | /* | 457 | /* |
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 = { | |||
78 | static int allocate_gic_irq(struct irq_domain *domain, unsigned virq, | 78 | static int allocate_gic_irq(struct irq_domain *domain, unsigned virq, |
79 | irq_hw_number_t hwirq) | 79 | irq_hw_number_t hwirq) |
80 | { | 80 | { |
81 | struct of_phandle_args args; | 81 | struct irq_fwspec fwspec; |
82 | int i; | 82 | int i; |
83 | int err; | 83 | int err; |
84 | 84 | ||
85 | if (!irq_domain_get_of_node(domain->parent)) | ||
86 | return -EINVAL; | ||
87 | |||
85 | raw_spin_lock(&cb->lock); | 88 | raw_spin_lock(&cb->lock); |
86 | for (i = cb->int_max - 1; i >= 0; i--) { | 89 | for (i = cb->int_max - 1; i >= 0; i--) { |
87 | if (cb->irq_map[i] == IRQ_FREE) { | 90 | if (cb->irq_map[i] == IRQ_FREE) { |
@@ -94,13 +97,13 @@ static int allocate_gic_irq(struct irq_domain *domain, unsigned virq, | |||
94 | if (i < 0) | 97 | if (i < 0) |
95 | return -ENODEV; | 98 | return -ENODEV; |
96 | 99 | ||
97 | args.np = irq_domain_get_of_node(domain->parent); | 100 | fwspec.fwnode = domain->parent->fwnode; |
98 | args.args_count = 3; | 101 | fwspec.param_count = 3; |
99 | args.args[0] = 0; /* SPI */ | 102 | fwspec.param[0] = 0; /* SPI */ |
100 | args.args[1] = i; | 103 | fwspec.param[1] = i; |
101 | args.args[2] = IRQ_TYPE_LEVEL_HIGH; | 104 | fwspec.param[2] = IRQ_TYPE_LEVEL_HIGH; |
102 | 105 | ||
103 | err = irq_domain_alloc_irqs_parent(domain, virq, 1, &args); | 106 | err = irq_domain_alloc_irqs_parent(domain, virq, 1, &fwspec); |
104 | if (err) | 107 | if (err) |
105 | cb->irq_map[i] = IRQ_FREE; | 108 | cb->irq_map[i] = IRQ_FREE; |
106 | else | 109 | else |
@@ -112,16 +115,16 @@ static int allocate_gic_irq(struct irq_domain *domain, unsigned virq, | |||
112 | static int crossbar_domain_alloc(struct irq_domain *d, unsigned int virq, | 115 | static int crossbar_domain_alloc(struct irq_domain *d, unsigned int virq, |
113 | unsigned int nr_irqs, void *data) | 116 | unsigned int nr_irqs, void *data) |
114 | { | 117 | { |
115 | struct of_phandle_args *args = data; | 118 | struct irq_fwspec *fwspec = data; |
116 | irq_hw_number_t hwirq; | 119 | irq_hw_number_t hwirq; |
117 | int i; | 120 | int i; |
118 | 121 | ||
119 | if (args->args_count != 3) | 122 | if (fwspec->param_count != 3) |
120 | return -EINVAL; /* Not GIC compliant */ | 123 | return -EINVAL; /* Not GIC compliant */ |
121 | if (args->args[0] != 0) | 124 | if (fwspec->param[0] != 0) |
122 | return -EINVAL; /* No PPI should point to this domain */ | 125 | return -EINVAL; /* No PPI should point to this domain */ |
123 | 126 | ||
124 | hwirq = args->args[1]; | 127 | hwirq = fwspec->param[1]; |
125 | if ((hwirq + nr_irqs) > cb->max_crossbar_sources) | 128 | if ((hwirq + nr_irqs) > cb->max_crossbar_sources) |
126 | return -EINVAL; /* Can't deal with this */ | 129 | return -EINVAL; /* Can't deal with this */ |
127 | 130 | ||
@@ -166,28 +169,31 @@ static void crossbar_domain_free(struct irq_domain *domain, unsigned int virq, | |||
166 | raw_spin_unlock(&cb->lock); | 169 | raw_spin_unlock(&cb->lock); |
167 | } | 170 | } |
168 | 171 | ||
169 | static int crossbar_domain_xlate(struct irq_domain *d, | 172 | static int crossbar_domain_translate(struct irq_domain *d, |
170 | struct device_node *controller, | 173 | struct irq_fwspec *fwspec, |
171 | const u32 *intspec, unsigned int intsize, | 174 | unsigned long *hwirq, |
172 | unsigned long *out_hwirq, | 175 | unsigned int *type) |
173 | unsigned int *out_type) | ||
174 | { | 176 | { |
175 | if (irq_domain_get_of_node(d) != controller) | 177 | if (is_of_node(fwspec->fwnode)) { |
176 | return -EINVAL; /* Shouldn't happen, really... */ | 178 | if (fwspec->param_count != 3) |
177 | if (intsize != 3) | 179 | return -EINVAL; |
178 | return -EINVAL; /* Not GIC compliant */ | ||
179 | if (intspec[0] != 0) | ||
180 | return -EINVAL; /* No PPI should point to this domain */ | ||
181 | 180 | ||
182 | *out_hwirq = intspec[1]; | 181 | /* No PPI should point to this domain */ |
183 | *out_type = intspec[2]; | 182 | if (fwspec->param[0] != 0) |
184 | return 0; | 183 | return -EINVAL; |
184 | |||
185 | *hwirq = fwspec->param[1]; | ||
186 | *type = fwspec->param[2]; | ||
187 | return 0; | ||
188 | } | ||
189 | |||
190 | return -EINVAL; | ||
185 | } | 191 | } |
186 | 192 | ||
187 | static const struct irq_domain_ops crossbar_domain_ops = { | 193 | static const struct irq_domain_ops crossbar_domain_ops = { |
188 | .alloc = crossbar_domain_alloc, | 194 | .alloc = crossbar_domain_alloc, |
189 | .free = crossbar_domain_free, | 195 | .free = crossbar_domain_free, |
190 | .xlate = crossbar_domain_xlate, | 196 | .translate = crossbar_domain_translate, |
191 | }; | 197 | }; |
192 | 198 | ||
193 | static int __init crossbar_of_init(struct device_node *node) | 199 | static int __init crossbar_of_init(struct device_node *node) |
diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c index 7c268eed402a..3b88e17d237c 100644 --- a/drivers/irqchip/irq-gic-v2m.c +++ b/drivers/irqchip/irq-gic-v2m.c | |||
@@ -124,17 +124,21 @@ static int gicv2m_irq_gic_domain_alloc(struct irq_domain *domain, | |||
124 | unsigned int virq, | 124 | unsigned int virq, |
125 | irq_hw_number_t hwirq) | 125 | irq_hw_number_t hwirq) |
126 | { | 126 | { |
127 | struct of_phandle_args args; | 127 | struct irq_fwspec fwspec; |
128 | struct irq_data *d; | 128 | struct irq_data *d; |
129 | int err; | 129 | int err; |
130 | 130 | ||
131 | args.np = irq_domain_get_of_node(domain->parent); | 131 | if (is_of_node(domain->parent->fwnode)) { |
132 | args.args_count = 3; | 132 | fwspec.fwnode = domain->parent->fwnode; |
133 | args.args[0] = 0; | 133 | fwspec.param_count = 3; |
134 | args.args[1] = hwirq - 32; | 134 | fwspec.param[0] = 0; |
135 | args.args[2] = IRQ_TYPE_EDGE_RISING; | 135 | fwspec.param[1] = hwirq - 32; |
136 | fwspec.param[2] = IRQ_TYPE_EDGE_RISING; | ||
137 | } else { | ||
138 | return -EINVAL; | ||
139 | } | ||
136 | 140 | ||
137 | err = irq_domain_alloc_irqs_parent(domain, virq, 1, &args); | 141 | err = irq_domain_alloc_irqs_parent(domain, virq, 1, &fwspec); |
138 | if (err) | 142 | if (err) |
139 | return err; | 143 | return err; |
140 | 144 | ||
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 3cfafaba5300..e23d1d18f9d6 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c | |||
@@ -1265,15 +1265,19 @@ static int its_irq_gic_domain_alloc(struct irq_domain *domain, | |||
1265 | unsigned int virq, | 1265 | unsigned int virq, |
1266 | irq_hw_number_t hwirq) | 1266 | irq_hw_number_t hwirq) |
1267 | { | 1267 | { |
1268 | struct of_phandle_args args; | 1268 | struct irq_fwspec fwspec; |
1269 | 1269 | ||
1270 | args.np = irq_domain_get_of_node(domain->parent); | 1270 | if (irq_domain_get_of_node(domain->parent)) { |
1271 | args.args_count = 3; | 1271 | fwspec.fwnode = domain->parent->fwnode; |
1272 | args.args[0] = GIC_IRQ_TYPE_LPI; | 1272 | fwspec.param_count = 3; |
1273 | args.args[1] = hwirq; | 1273 | fwspec.param[0] = GIC_IRQ_TYPE_LPI; |
1274 | args.args[2] = IRQ_TYPE_EDGE_RISING; | 1274 | fwspec.param[1] = hwirq; |
1275 | fwspec.param[2] = IRQ_TYPE_EDGE_RISING; | ||
1276 | } else { | ||
1277 | return -EINVAL; | ||
1278 | } | ||
1275 | 1279 | ||
1276 | return irq_domain_alloc_irqs_parent(domain, virq, 1, &args); | 1280 | return irq_domain_alloc_irqs_parent(domain, virq, 1, &fwspec); |
1277 | } | 1281 | } |
1278 | 1282 | ||
1279 | static int its_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, | 1283 | static int its_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, |
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 5793880c91c6..05d010b652f5 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c | |||
@@ -737,32 +737,30 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq, | |||
737 | return 0; | 737 | return 0; |
738 | } | 738 | } |
739 | 739 | ||
740 | static int gic_irq_domain_xlate(struct irq_domain *d, | 740 | static int gic_irq_domain_translate(struct irq_domain *d, |
741 | struct device_node *controller, | 741 | struct irq_fwspec *fwspec, |
742 | const u32 *intspec, unsigned int intsize, | 742 | unsigned long *hwirq, |
743 | unsigned long *out_hwirq, unsigned int *out_type) | 743 | unsigned int *type) |
744 | { | 744 | { |
745 | if (irq_domain_get_of_node(d) != controller) | 745 | if (is_of_node(fwspec->fwnode)) { |
746 | return -EINVAL; | 746 | if (fwspec->param_count < 3) |
747 | if (intsize < 3) | 747 | return -EINVAL; |
748 | return -EINVAL; | ||
749 | 748 | ||
750 | switch(intspec[0]) { | 749 | /* Get the interrupt number and add 16 to skip over SGIs */ |
751 | case 0: /* SPI */ | 750 | *hwirq = fwspec->param[1] + 16; |
752 | *out_hwirq = intspec[1] + 32; | 751 | |
753 | break; | 752 | /* |
754 | case 1: /* PPI */ | 753 | * For SPIs, we need to add 16 more to get the GIC irq |
755 | *out_hwirq = intspec[1] + 16; | 754 | * ID number |
756 | break; | 755 | */ |
757 | case GIC_IRQ_TYPE_LPI: /* LPI */ | 756 | if (!fwspec->param[0]) |
758 | *out_hwirq = intspec[1]; | 757 | *hwirq += 16; |
759 | break; | 758 | |
760 | default: | 759 | *type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK; |
761 | return -EINVAL; | 760 | return 0; |
762 | } | 761 | } |
763 | 762 | ||
764 | *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK; | 763 | return -EINVAL; |
765 | return 0; | ||
766 | } | 764 | } |
767 | 765 | ||
768 | static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, | 766 | static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, |
@@ -771,10 +769,9 @@ static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, | |||
771 | int i, ret; | 769 | int i, ret; |
772 | irq_hw_number_t hwirq; | 770 | irq_hw_number_t hwirq; |
773 | unsigned int type = IRQ_TYPE_NONE; | 771 | unsigned int type = IRQ_TYPE_NONE; |
774 | struct of_phandle_args *irq_data = arg; | 772 | struct irq_fwspec *fwspec = arg; |
775 | 773 | ||
776 | ret = gic_irq_domain_xlate(domain, irq_data->np, irq_data->args, | 774 | ret = gic_irq_domain_translate(domain, fwspec, &hwirq, &type); |
777 | irq_data->args_count, &hwirq, &type); | ||
778 | if (ret) | 775 | if (ret) |
779 | return ret; | 776 | return ret; |
780 | 777 | ||
@@ -797,7 +794,7 @@ static void gic_irq_domain_free(struct irq_domain *domain, unsigned int virq, | |||
797 | } | 794 | } |
798 | 795 | ||
799 | static const struct irq_domain_ops gic_irq_domain_ops = { | 796 | static const struct irq_domain_ops gic_irq_domain_ops = { |
800 | .xlate = gic_irq_domain_xlate, | 797 | .translate = gic_irq_domain_translate, |
801 | .alloc = gic_irq_domain_alloc, | 798 | .alloc = gic_irq_domain_alloc, |
802 | .free = gic_irq_domain_free, | 799 | .free = gic_irq_domain_free, |
803 | }; | 800 | }; |
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, | |||
940 | return ret; | 940 | return ret; |
941 | } | 941 | } |
942 | 942 | ||
943 | static int gic_irq_domain_translate(struct irq_domain *d, | ||
944 | struct irq_fwspec *fwspec, | ||
945 | unsigned long *hwirq, | ||
946 | unsigned int *type) | ||
947 | { | ||
948 | if (is_of_node(fwspec->fwnode)) { | ||
949 | if (fwspec->param_count < 3) | ||
950 | return -EINVAL; | ||
951 | |||
952 | /* Get the interrupt number and add 16 to skip over SGIs */ | ||
953 | *hwirq = fwspec->param[1] + 16; | ||
954 | |||
955 | /* | ||
956 | * For SPIs, we need to add 16 more to get the GIC irq | ||
957 | * ID number | ||
958 | */ | ||
959 | if (!fwspec->param[0]) | ||
960 | *hwirq += 16; | ||
961 | |||
962 | *type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK; | ||
963 | return 0; | ||
964 | } | ||
965 | |||
966 | return -EINVAL; | ||
967 | } | ||
968 | |||
943 | #ifdef CONFIG_SMP | 969 | #ifdef CONFIG_SMP |
944 | static int gic_secondary_init(struct notifier_block *nfb, unsigned long action, | 970 | static int gic_secondary_init(struct notifier_block *nfb, unsigned long action, |
945 | void *hcpu) | 971 | void *hcpu) |
@@ -965,10 +991,9 @@ static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, | |||
965 | int i, ret; | 991 | int i, ret; |
966 | irq_hw_number_t hwirq; | 992 | irq_hw_number_t hwirq; |
967 | unsigned int type = IRQ_TYPE_NONE; | 993 | unsigned int type = IRQ_TYPE_NONE; |
968 | struct of_phandle_args *irq_data = arg; | 994 | struct irq_fwspec *fwspec = arg; |
969 | 995 | ||
970 | ret = gic_irq_domain_xlate(domain, irq_data->np, irq_data->args, | 996 | ret = gic_irq_domain_translate(domain, fwspec, &hwirq, &type); |
971 | irq_data->args_count, &hwirq, &type); | ||
972 | if (ret) | 997 | if (ret) |
973 | return ret; | 998 | return ret; |
974 | 999 | ||
@@ -979,7 +1004,7 @@ static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, | |||
979 | } | 1004 | } |
980 | 1005 | ||
981 | static const struct irq_domain_ops gic_irq_domain_hierarchy_ops = { | 1006 | static const struct irq_domain_ops gic_irq_domain_hierarchy_ops = { |
982 | .xlate = gic_irq_domain_xlate, | 1007 | .translate = gic_irq_domain_translate, |
983 | .alloc = gic_irq_domain_alloc, | 1008 | .alloc = gic_irq_domain_alloc, |
984 | .free = irq_domain_free_irqs_top, | 1009 | .free = irq_domain_free_irqs_top, |
985 | }; | 1010 | }; |
diff --git a/drivers/irqchip/irq-imx-gpcv2.c b/drivers/irqchip/irq-imx-gpcv2.c index 05302cef76dd..15af9a9753e5 100644 --- a/drivers/irqchip/irq-imx-gpcv2.c +++ b/drivers/irqchip/irq-imx-gpcv2.c | |||
@@ -150,49 +150,42 @@ static struct irq_chip gpcv2_irqchip_data_chip = { | |||
150 | #endif | 150 | #endif |
151 | }; | 151 | }; |
152 | 152 | ||
153 | static int imx_gpcv2_domain_xlate(struct irq_domain *domain, | 153 | static int imx_gpcv2_domain_translate(struct irq_domain *d, |
154 | struct device_node *controller, | 154 | struct irq_fwspec *fwspec, |
155 | const u32 *intspec, | 155 | unsigned long *hwirq, |
156 | unsigned int intsize, | 156 | unsigned int *type) |
157 | unsigned long *out_hwirq, | ||
158 | unsigned int *out_type) | ||
159 | { | 157 | { |
160 | /* Shouldn't happen, really... */ | 158 | if (is_of_node(fwspec->fwnode)) { |
161 | if (irq_domain_get_of_node(domain) != controller) | 159 | if (fwspec->param_count != 3) |
162 | return -EINVAL; | 160 | return -EINVAL; |
163 | 161 | ||
164 | /* Not GIC compliant */ | 162 | /* No PPI should point to this domain */ |
165 | if (intsize != 3) | 163 | if (fwspec->param[0] != 0) |
166 | return -EINVAL; | 164 | return -EINVAL; |
167 | 165 | ||
168 | /* No PPI should point to this domain */ | 166 | *hwirq = fwspec->param[1]; |
169 | if (intspec[0] != 0) | 167 | *type = fwspec->param[2]; |
170 | return -EINVAL; | 168 | return 0; |
169 | } | ||
171 | 170 | ||
172 | *out_hwirq = intspec[1]; | 171 | return -EINVAL; |
173 | *out_type = intspec[2]; | ||
174 | return 0; | ||
175 | } | 172 | } |
176 | 173 | ||
177 | static int imx_gpcv2_domain_alloc(struct irq_domain *domain, | 174 | static int imx_gpcv2_domain_alloc(struct irq_domain *domain, |
178 | unsigned int irq, unsigned int nr_irqs, | 175 | unsigned int irq, unsigned int nr_irqs, |
179 | void *data) | 176 | void *data) |
180 | { | 177 | { |
181 | struct of_phandle_args *args = data; | 178 | struct irq_fwspec *fwspec = data; |
182 | struct of_phandle_args parent_args; | 179 | struct irq_fwspec parent_fwspec; |
183 | irq_hw_number_t hwirq; | 180 | irq_hw_number_t hwirq; |
181 | unsigned int type; | ||
182 | int err; | ||
184 | int i; | 183 | int i; |
185 | 184 | ||
186 | /* Not GIC compliant */ | 185 | err = imx_gpcv2_domain_translate(domain, fwspec, &hwirq, &type); |
187 | if (args->args_count != 3) | 186 | if (err) |
188 | return -EINVAL; | 187 | return err; |
189 | |||
190 | /* No PPI should point to this domain */ | ||
191 | if (args->args[0] != 0) | ||
192 | return -EINVAL; | ||
193 | 188 | ||
194 | /* Can't deal with this */ | ||
195 | hwirq = args->args[1]; | ||
196 | if (hwirq >= GPC_MAX_IRQS) | 189 | if (hwirq >= GPC_MAX_IRQS) |
197 | return -EINVAL; | 190 | return -EINVAL; |
198 | 191 | ||
@@ -201,15 +194,16 @@ static int imx_gpcv2_domain_alloc(struct irq_domain *domain, | |||
201 | &gpcv2_irqchip_data_chip, domain->host_data); | 194 | &gpcv2_irqchip_data_chip, domain->host_data); |
202 | } | 195 | } |
203 | 196 | ||
204 | parent_args = *args; | 197 | parent_fwspec = *fwspec; |
205 | parent_args.np = irq_domain_get_of_node(domain->parent); | 198 | parent_fwspec.fwnode = domain->parent->fwnode; |
206 | return irq_domain_alloc_irqs_parent(domain, irq, nr_irqs, &parent_args); | 199 | return irq_domain_alloc_irqs_parent(domain, irq, nr_irqs, |
200 | &parent_fwspec); | ||
207 | } | 201 | } |
208 | 202 | ||
209 | static struct irq_domain_ops gpcv2_irqchip_data_domain_ops = { | 203 | static struct irq_domain_ops gpcv2_irqchip_data_domain_ops = { |
210 | .xlate = imx_gpcv2_domain_xlate, | 204 | .translate = imx_gpcv2_domain_translate, |
211 | .alloc = imx_gpcv2_domain_alloc, | 205 | .alloc = imx_gpcv2_domain_alloc, |
212 | .free = irq_domain_free_irqs_common, | 206 | .free = irq_domain_free_irqs_common, |
213 | }; | 207 | }; |
214 | 208 | ||
215 | static int __init imx_gpcv2_irqchip_init(struct device_node *node, | 209 | static int __init imx_gpcv2_irqchip_init(struct device_node *node, |
diff --git a/drivers/irqchip/irq-mtk-sysirq.c b/drivers/irqchip/irq-mtk-sysirq.c index b07216688cd9..63ac73b1d9c8 100644 --- a/drivers/irqchip/irq-mtk-sysirq.c +++ b/drivers/irqchip/irq-mtk-sysirq.c | |||
@@ -67,22 +67,25 @@ static struct irq_chip mtk_sysirq_chip = { | |||
67 | .irq_set_affinity = irq_chip_set_affinity_parent, | 67 | .irq_set_affinity = irq_chip_set_affinity_parent, |
68 | }; | 68 | }; |
69 | 69 | ||
70 | static int mtk_sysirq_domain_xlate(struct irq_domain *d, | 70 | static int mtk_sysirq_domain_translate(struct irq_domain *d, |
71 | struct device_node *controller, | 71 | struct irq_fwspec *fwspec, |
72 | const u32 *intspec, unsigned int intsize, | 72 | unsigned long *hwirq, |
73 | unsigned long *out_hwirq, | 73 | unsigned int *type) |
74 | unsigned int *out_type) | ||
75 | { | 74 | { |
76 | if (intsize != 3) | 75 | if (is_of_node(fwspec->fwnode)) { |
77 | return -EINVAL; | 76 | if (fwspec->param_count != 3) |
77 | return -EINVAL; | ||
78 | 78 | ||
79 | /* sysirq doesn't support PPI */ | 79 | /* No PPI should point to this domain */ |
80 | if (intspec[0]) | 80 | if (fwspec->param[0] != 0) |
81 | return -EINVAL; | 81 | return -EINVAL; |
82 | 82 | ||
83 | *out_hwirq = intspec[1]; | 83 | *hwirq = fwspec->param[1]; |
84 | *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK; | 84 | *type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK; |
85 | return 0; | 85 | return 0; |
86 | } | ||
87 | |||
88 | return -EINVAL; | ||
86 | } | 89 | } |
87 | 90 | ||
88 | static int mtk_sysirq_domain_alloc(struct irq_domain *domain, unsigned int virq, | 91 | static int mtk_sysirq_domain_alloc(struct irq_domain *domain, unsigned int virq, |
@@ -90,30 +93,30 @@ static int mtk_sysirq_domain_alloc(struct irq_domain *domain, unsigned int virq, | |||
90 | { | 93 | { |
91 | int i; | 94 | int i; |
92 | irq_hw_number_t hwirq; | 95 | irq_hw_number_t hwirq; |
93 | struct of_phandle_args *irq_data = arg; | 96 | struct irq_fwspec *fwspec = arg; |
94 | struct of_phandle_args gic_data = *irq_data; | 97 | struct irq_fwspec gic_fwspec = *fwspec; |
95 | 98 | ||
96 | if (irq_data->args_count != 3) | 99 | if (fwspec->param_count != 3) |
97 | return -EINVAL; | 100 | return -EINVAL; |
98 | 101 | ||
99 | /* sysirq doesn't support PPI */ | 102 | /* sysirq doesn't support PPI */ |
100 | if (irq_data->args[0]) | 103 | if (fwspec->param[0]) |
101 | return -EINVAL; | 104 | return -EINVAL; |
102 | 105 | ||
103 | hwirq = irq_data->args[1]; | 106 | hwirq = fwspec->param[1]; |
104 | for (i = 0; i < nr_irqs; i++) | 107 | for (i = 0; i < nr_irqs; i++) |
105 | irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, | 108 | irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, |
106 | &mtk_sysirq_chip, | 109 | &mtk_sysirq_chip, |
107 | domain->host_data); | 110 | domain->host_data); |
108 | 111 | ||
109 | gic_data.np = irq_domain_get_of_node(domain->parent); | 112 | gic_fwspec.fwnode = domain->parent->fwnode; |
110 | return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &gic_data); | 113 | return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &gic_fwspec); |
111 | } | 114 | } |
112 | 115 | ||
113 | static const struct irq_domain_ops sysirq_domain_ops = { | 116 | static const struct irq_domain_ops sysirq_domain_ops = { |
114 | .xlate = mtk_sysirq_domain_xlate, | 117 | .translate = mtk_sysirq_domain_translate, |
115 | .alloc = mtk_sysirq_domain_alloc, | 118 | .alloc = mtk_sysirq_domain_alloc, |
116 | .free = irq_domain_free_irqs_common, | 119 | .free = irq_domain_free_irqs_common, |
117 | }; | 120 | }; |
118 | 121 | ||
119 | static int __init mtk_sysirq_of_init(struct device_node *node, | 122 | static int __init mtk_sysirq_of_init(struct device_node *node, |
diff --git a/drivers/irqchip/irq-nvic.c b/drivers/irqchip/irq-nvic.c index a878b8d03868..b1777104fd9f 100644 --- a/drivers/irqchip/irq-nvic.c +++ b/drivers/irqchip/irq-nvic.c | |||
@@ -48,16 +48,26 @@ nvic_handle_irq(irq_hw_number_t hwirq, struct pt_regs *regs) | |||
48 | handle_IRQ(irq, regs); | 48 | handle_IRQ(irq, regs); |
49 | } | 49 | } |
50 | 50 | ||
51 | static int nvic_irq_domain_translate(struct irq_domain *d, | ||
52 | struct irq_fwspec *fwspec, | ||
53 | unsigned long *hwirq, unsigned int *type) | ||
54 | { | ||
55 | if (WARN_ON(fwspec->param_count < 1)) | ||
56 | return -EINVAL; | ||
57 | *hwirq = fwspec->param[0]; | ||
58 | *type = IRQ_TYPE_NONE; | ||
59 | return 0; | ||
60 | } | ||
61 | |||
51 | static int nvic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, | 62 | static int nvic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, |
52 | unsigned int nr_irqs, void *arg) | 63 | unsigned int nr_irqs, void *arg) |
53 | { | 64 | { |
54 | int i, ret; | 65 | int i, ret; |
55 | irq_hw_number_t hwirq; | 66 | irq_hw_number_t hwirq; |
56 | unsigned int type = IRQ_TYPE_NONE; | 67 | unsigned int type = IRQ_TYPE_NONE; |
57 | struct of_phandle_args *irq_data = arg; | 68 | struct irq_fwspec *fwspec = arg; |
58 | 69 | ||
59 | ret = irq_domain_xlate_onecell(domain, irq_data->np, irq_data->args, | 70 | ret = nvic_irq_domain_translate(domain, fwspec, &hwirq, &type); |
60 | irq_data->args_count, &hwirq, &type); | ||
61 | if (ret) | 71 | if (ret) |
62 | return ret; | 72 | return ret; |
63 | 73 | ||
@@ -68,7 +78,7 @@ static int nvic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, | |||
68 | } | 78 | } |
69 | 79 | ||
70 | static const struct irq_domain_ops nvic_irq_domain_ops = { | 80 | static const struct irq_domain_ops nvic_irq_domain_ops = { |
71 | .xlate = irq_domain_xlate_onecell, | 81 | .translate = nvic_irq_domain_translate, |
72 | .alloc = nvic_irq_domain_alloc, | 82 | .alloc = nvic_irq_domain_alloc, |
73 | .free = irq_domain_free_irqs_top, | 83 | .free = irq_domain_free_irqs_top, |
74 | }; | 84 | }; |
diff --git a/drivers/irqchip/irq-tegra.c b/drivers/irqchip/irq-tegra.c index 7bbf22658c31..557e15e57e63 100644 --- a/drivers/irqchip/irq-tegra.c +++ b/drivers/irqchip/irq-tegra.c | |||
@@ -220,41 +220,43 @@ static struct irq_chip tegra_ictlr_chip = { | |||
220 | #endif | 220 | #endif |
221 | }; | 221 | }; |
222 | 222 | ||
223 | static int tegra_ictlr_domain_xlate(struct irq_domain *domain, | 223 | static int tegra_ictlr_domain_translate(struct irq_domain *d, |
224 | struct device_node *controller, | 224 | struct irq_fwspec *fwspec, |
225 | const u32 *intspec, | 225 | unsigned long *hwirq, |
226 | unsigned int intsize, | 226 | unsigned int *type) |
227 | unsigned long *out_hwirq, | ||
228 | unsigned int *out_type) | ||
229 | { | 227 | { |
230 | if (irq_domain_get_of_node(domain) != controller) | 228 | if (is_of_node(fwspec->fwnode)) { |
231 | return -EINVAL; /* Shouldn't happen, really... */ | 229 | if (fwspec->param_count != 3) |
232 | if (intsize != 3) | 230 | return -EINVAL; |
233 | return -EINVAL; /* Not GIC compliant */ | ||
234 | if (intspec[0] != GIC_SPI) | ||
235 | return -EINVAL; /* No PPI should point to this domain */ | ||
236 | 231 | ||
237 | *out_hwirq = intspec[1]; | 232 | /* No PPI should point to this domain */ |
238 | *out_type = intspec[2]; | 233 | if (fwspec->param[0] != 0) |
239 | return 0; | 234 | return -EINVAL; |
235 | |||
236 | *hwirq = fwspec->param[1]; | ||
237 | *type = fwspec->param[2]; | ||
238 | return 0; | ||
239 | } | ||
240 | |||
241 | return -EINVAL; | ||
240 | } | 242 | } |
241 | 243 | ||
242 | static int tegra_ictlr_domain_alloc(struct irq_domain *domain, | 244 | static int tegra_ictlr_domain_alloc(struct irq_domain *domain, |
243 | unsigned int virq, | 245 | unsigned int virq, |
244 | unsigned int nr_irqs, void *data) | 246 | unsigned int nr_irqs, void *data) |
245 | { | 247 | { |
246 | struct of_phandle_args *args = data; | 248 | struct irq_fwspec *fwspec = data; |
247 | struct of_phandle_args parent_args; | 249 | struct irq_fwspec parent_fwspec; |
248 | struct tegra_ictlr_info *info = domain->host_data; | 250 | struct tegra_ictlr_info *info = domain->host_data; |
249 | irq_hw_number_t hwirq; | 251 | irq_hw_number_t hwirq; |
250 | unsigned int i; | 252 | unsigned int i; |
251 | 253 | ||
252 | if (args->args_count != 3) | 254 | if (fwspec->param_count != 3) |
253 | return -EINVAL; /* Not GIC compliant */ | 255 | return -EINVAL; /* Not GIC compliant */ |
254 | if (args->args[0] != GIC_SPI) | 256 | if (fwspec->param[0] != GIC_SPI) |
255 | return -EINVAL; /* No PPI should point to this domain */ | 257 | return -EINVAL; /* No PPI should point to this domain */ |
256 | 258 | ||
257 | hwirq = args->args[1]; | 259 | hwirq = fwspec->param[1]; |
258 | if (hwirq >= (num_ictlrs * 32)) | 260 | if (hwirq >= (num_ictlrs * 32)) |
259 | return -EINVAL; | 261 | return -EINVAL; |
260 | 262 | ||
@@ -266,9 +268,10 @@ static int tegra_ictlr_domain_alloc(struct irq_domain *domain, | |||
266 | info->base[ictlr]); | 268 | info->base[ictlr]); |
267 | } | 269 | } |
268 | 270 | ||
269 | parent_args = *args; | 271 | parent_fwspec = *fwspec; |
270 | parent_args.np = irq_domain_get_of_node(domain->parent); | 272 | parent_fwspec.fwnode = domain->parent->fwnode; |
271 | return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &parent_args); | 273 | return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, |
274 | &parent_fwspec); | ||
272 | } | 275 | } |
273 | 276 | ||
274 | static void tegra_ictlr_domain_free(struct irq_domain *domain, | 277 | static void tegra_ictlr_domain_free(struct irq_domain *domain, |
@@ -284,9 +287,9 @@ static void tegra_ictlr_domain_free(struct irq_domain *domain, | |||
284 | } | 287 | } |
285 | 288 | ||
286 | static const struct irq_domain_ops tegra_ictlr_domain_ops = { | 289 | static const struct irq_domain_ops tegra_ictlr_domain_ops = { |
287 | .xlate = tegra_ictlr_domain_xlate, | 290 | .translate = tegra_ictlr_domain_translate, |
288 | .alloc = tegra_ictlr_domain_alloc, | 291 | .alloc = tegra_ictlr_domain_alloc, |
289 | .free = tegra_ictlr_domain_free, | 292 | .free = tegra_ictlr_domain_free, |
290 | }; | 293 | }; |
291 | 294 | ||
292 | static int __init tegra_ictlr_init(struct device_node *node, | 295 | static int __init tegra_ictlr_init(struct device_node *node, |
diff --git a/drivers/irqchip/irq-vf610-mscm-ir.c b/drivers/irqchip/irq-vf610-mscm-ir.c index ae82d7e15c63..56b5e3cb9de2 100644 --- a/drivers/irqchip/irq-vf610-mscm-ir.c +++ b/drivers/irqchip/irq-vf610-mscm-ir.c | |||
@@ -130,35 +130,51 @@ static int vf610_mscm_ir_domain_alloc(struct irq_domain *domain, unsigned int vi | |||
130 | { | 130 | { |
131 | int i; | 131 | int i; |
132 | irq_hw_number_t hwirq; | 132 | irq_hw_number_t hwirq; |
133 | struct of_phandle_args *irq_data = arg; | 133 | struct irq_fwspec *fwspec = arg; |
134 | struct of_phandle_args gic_data; | 134 | struct irq_fwspec parent_fwspec; |
135 | 135 | ||
136 | if (irq_data->args_count != 2) | 136 | if (!irq_domain_get_of_node(domain->parent)) |
137 | return -EINVAL; | 137 | return -EINVAL; |
138 | 138 | ||
139 | hwirq = irq_data->args[0]; | 139 | if (fwspec->param_count != 2) |
140 | return -EINVAL; | ||
141 | |||
142 | hwirq = fwspec->param[0]; | ||
140 | for (i = 0; i < nr_irqs; i++) | 143 | for (i = 0; i < nr_irqs; i++) |
141 | irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, | 144 | irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, |
142 | &vf610_mscm_ir_irq_chip, | 145 | &vf610_mscm_ir_irq_chip, |
143 | domain->host_data); | 146 | domain->host_data); |
144 | 147 | ||
145 | gic_data.np = irq_domain_get_of_node(domain->parent); | 148 | parent_fwspec.fwnode = domain->parent->fwnode; |
146 | 149 | ||
147 | if (mscm_ir_data->is_nvic) { | 150 | if (mscm_ir_data->is_nvic) { |
148 | gic_data.args_count = 1; | 151 | parent_fwspec.param_count = 1; |
149 | gic_data.args[0] = irq_data->args[0]; | 152 | parent_fwspec.param[0] = fwspec->param[0]; |
150 | } else { | 153 | } else { |
151 | gic_data.args_count = 3; | 154 | parent_fwspec.param_count = 3; |
152 | gic_data.args[0] = GIC_SPI; | 155 | parent_fwspec.param[0] = GIC_SPI; |
153 | gic_data.args[1] = irq_data->args[0]; | 156 | parent_fwspec.param[1] = fwspec->param[0]; |
154 | gic_data.args[2] = irq_data->args[1]; | 157 | parent_fwspec.param[2] = fwspec->param[1]; |
155 | } | 158 | } |
156 | 159 | ||
157 | return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &gic_data); | 160 | return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, |
161 | &parent_fwspec); | ||
162 | } | ||
163 | |||
164 | static int vf610_mscm_ir_domain_translate(struct irq_domain *d, | ||
165 | struct irq_fwspec *fwspec, | ||
166 | unsigned long *hwirq, | ||
167 | unsigned int *type) | ||
168 | { | ||
169 | if (WARN_ON(fwspec->param_count < 2)) | ||
170 | return -EINVAL; | ||
171 | *hwirq = fwspec->param[0]; | ||
172 | *type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK; | ||
173 | return 0; | ||
158 | } | 174 | } |
159 | 175 | ||
160 | static const struct irq_domain_ops mscm_irq_domain_ops = { | 176 | static const struct irq_domain_ops mscm_irq_domain_ops = { |
161 | .xlate = irq_domain_xlate_twocell, | 177 | .translate = vf610_mscm_ir_domain_translate, |
162 | .alloc = vf610_mscm_ir_domain_alloc, | 178 | .alloc = vf610_mscm_ir_domain_alloc, |
163 | .free = irq_domain_free_irqs_common, | 179 | .free = irq_domain_free_irqs_common, |
164 | }; | 180 | }; |