diff options
author | Yuriy Kolerov <yuriy.kolerov@synopsys.com> | 2016-11-08 02:08:31 -0500 |
---|---|---|
committer | Vineet Gupta <vgupta@synopsys.com> | 2016-11-08 15:05:10 -0500 |
commit | 34e71e4cbb8eb467dbcfb3afbd2b95ff2b08f482 (patch) | |
tree | 966bf5fe9c434972a1a6be5b37653c65b1ecaeb2 | |
parent | 19dbc76228899be555b84a09fd3a364c2ce86bbb (diff) |
ARC: IRQ: Do not use hwirq as virq and vice versa
This came up when reviewing code to address missing IRQ affinity
setting in AXS103 platform and/or implementing hierarchical IRQ domains
- smp_ipi_irq_setup() callers pass hwirq but in turn calls
request_percpu_irq() which expects a linux virq. So invoke
irq_find_mapping() to do the conversion
(also explicitify this in code by renaming the args appropriately)
- idu_of_init()/idu_cascade_isr() were similarly using linux virq where
hwirq is expected, so do the conversion using irqd_to_hwirq() helper
Signed-off-by: Yuriy Kolerov <yuriy.kolerov@synopsys.com>
[vgupta: made changelog a bit concise a bit]
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
-rw-r--r-- | arch/arc/include/asm/smp.h | 4 | ||||
-rw-r--r-- | arch/arc/kernel/mcip.c | 19 | ||||
-rw-r--r-- | arch/arc/kernel/smp.c | 13 |
3 files changed, 20 insertions, 16 deletions
diff --git a/arch/arc/include/asm/smp.h b/arch/arc/include/asm/smp.h index 89fdd1b0a76e..0861007d9ef3 100644 --- a/arch/arc/include/asm/smp.h +++ b/arch/arc/include/asm/smp.h | |||
@@ -37,9 +37,9 @@ extern const char *arc_platform_smp_cpuinfo(void); | |||
37 | * API expected BY platform smp code (FROM arch smp code) | 37 | * API expected BY platform smp code (FROM arch smp code) |
38 | * | 38 | * |
39 | * smp_ipi_irq_setup: | 39 | * smp_ipi_irq_setup: |
40 | * Takes @cpu and @irq to which the arch-common ISR is hooked up | 40 | * Takes @cpu and @hwirq to which the arch-common ISR is hooked up |
41 | */ | 41 | */ |
42 | extern int smp_ipi_irq_setup(int cpu, int irq); | 42 | extern int smp_ipi_irq_setup(int cpu, irq_hw_number_t hwirq); |
43 | 43 | ||
44 | /* | 44 | /* |
45 | * struct plat_smp_ops - SMP callbacks provided by platform to ARC SMP | 45 | * struct plat_smp_ops - SMP callbacks provided by platform to ARC SMP |
diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c index c424d5abc318..6d18bb871926 100644 --- a/arch/arc/kernel/mcip.c +++ b/arch/arc/kernel/mcip.c | |||
@@ -207,16 +207,15 @@ static struct irq_chip idu_irq_chip = { | |||
207 | 207 | ||
208 | }; | 208 | }; |
209 | 209 | ||
210 | static int idu_first_irq; | 210 | static irq_hw_number_t idu_first_hwirq; |
211 | 211 | ||
212 | static void idu_cascade_isr(struct irq_desc *desc) | 212 | static void idu_cascade_isr(struct irq_desc *desc) |
213 | { | 213 | { |
214 | struct irq_domain *domain = irq_desc_get_handler_data(desc); | 214 | struct irq_domain *idu_domain = irq_desc_get_handler_data(desc); |
215 | unsigned int core_irq = irq_desc_get_irq(desc); | 215 | irq_hw_number_t core_hwirq = irqd_to_hwirq(irq_desc_get_irq_data(desc)); |
216 | unsigned int idu_irq; | 216 | irq_hw_number_t idu_hwirq = core_hwirq - idu_first_hwirq; |
217 | 217 | ||
218 | idu_irq = core_irq - idu_first_irq; | 218 | generic_handle_irq(irq_find_mapping(idu_domain, idu_hwirq)); |
219 | generic_handle_irq(irq_find_mapping(domain, idu_irq)); | ||
220 | } | 219 | } |
221 | 220 | ||
222 | static int idu_irq_map(struct irq_domain *d, unsigned int virq, irq_hw_number_t hwirq) | 221 | static int idu_irq_map(struct irq_domain *d, unsigned int virq, irq_hw_number_t hwirq) |
@@ -282,7 +281,7 @@ idu_of_init(struct device_node *intc, struct device_node *parent) | |||
282 | struct irq_domain *domain; | 281 | struct irq_domain *domain; |
283 | /* Read IDU BCR to confirm nr_irqs */ | 282 | /* Read IDU BCR to confirm nr_irqs */ |
284 | int nr_irqs = of_irq_count(intc); | 283 | int nr_irqs = of_irq_count(intc); |
285 | int i, irq; | 284 | int i, virq; |
286 | struct mcip_bcr mp; | 285 | struct mcip_bcr mp; |
287 | 286 | ||
288 | READ_BCR(ARC_REG_MCIP_BCR, mp); | 287 | READ_BCR(ARC_REG_MCIP_BCR, mp); |
@@ -303,11 +302,11 @@ idu_of_init(struct device_node *intc, struct device_node *parent) | |||
303 | * however we need it to get the parent virq and set IDU handler | 302 | * however we need it to get the parent virq and set IDU handler |
304 | * as first level isr | 303 | * as first level isr |
305 | */ | 304 | */ |
306 | irq = irq_of_parse_and_map(intc, i); | 305 | virq = irq_of_parse_and_map(intc, i); |
307 | if (!i) | 306 | if (!i) |
308 | idu_first_irq = irq; | 307 | idu_first_hwirq = irqd_to_hwirq(irq_get_irq_data(virq)); |
309 | 308 | ||
310 | irq_set_chained_handler_and_data(irq, idu_cascade_isr, domain); | 309 | irq_set_chained_handler_and_data(virq, idu_cascade_isr, domain); |
311 | } | 310 | } |
312 | 311 | ||
313 | __mcip_cmd(CMD_IDU_ENABLE, 0); | 312 | __mcip_cmd(CMD_IDU_ENABLE, 0); |
diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c index f00029e9cbe4..88674d972c9d 100644 --- a/arch/arc/kernel/smp.c +++ b/arch/arc/kernel/smp.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/atomic.h> | 22 | #include <linux/atomic.h> |
23 | #include <linux/cpumask.h> | 23 | #include <linux/cpumask.h> |
24 | #include <linux/reboot.h> | 24 | #include <linux/reboot.h> |
25 | #include <linux/irqdomain.h> | ||
25 | #include <asm/processor.h> | 26 | #include <asm/processor.h> |
26 | #include <asm/setup.h> | 27 | #include <asm/setup.h> |
27 | #include <asm/mach_desc.h> | 28 | #include <asm/mach_desc.h> |
@@ -353,20 +354,24 @@ irqreturn_t do_IPI(int irq, void *dev_id) | |||
353 | */ | 354 | */ |
354 | static DEFINE_PER_CPU(int, ipi_dev); | 355 | static DEFINE_PER_CPU(int, ipi_dev); |
355 | 356 | ||
356 | int smp_ipi_irq_setup(int cpu, int irq) | 357 | int smp_ipi_irq_setup(int cpu, irq_hw_number_t hwirq) |
357 | { | 358 | { |
358 | int *dev = per_cpu_ptr(&ipi_dev, cpu); | 359 | int *dev = per_cpu_ptr(&ipi_dev, cpu); |
360 | unsigned int virq = irq_find_mapping(NULL, hwirq); | ||
361 | |||
362 | if (!virq) | ||
363 | panic("Cannot find virq for root domain and hwirq=%lu", hwirq); | ||
359 | 364 | ||
360 | /* Boot cpu calls request, all call enable */ | 365 | /* Boot cpu calls request, all call enable */ |
361 | if (!cpu) { | 366 | if (!cpu) { |
362 | int rc; | 367 | int rc; |
363 | 368 | ||
364 | rc = request_percpu_irq(irq, do_IPI, "IPI Interrupt", dev); | 369 | rc = request_percpu_irq(virq, do_IPI, "IPI Interrupt", dev); |
365 | if (rc) | 370 | if (rc) |
366 | panic("Percpu IRQ request failed for %d\n", irq); | 371 | panic("Percpu IRQ request failed for %u\n", virq); |
367 | } | 372 | } |
368 | 373 | ||
369 | enable_percpu_irq(irq, 0); | 374 | enable_percpu_irq(virq, 0); |
370 | 375 | ||
371 | return 0; | 376 | return 0; |
372 | } | 377 | } |