aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYuriy Kolerov <yuriy.kolerov@synopsys.com>2016-11-08 02:08:31 -0500
committerVineet Gupta <vgupta@synopsys.com>2016-11-08 15:05:10 -0500
commit34e71e4cbb8eb467dbcfb3afbd2b95ff2b08f482 (patch)
tree966bf5fe9c434972a1a6be5b37653c65b1ecaeb2
parent19dbc76228899be555b84a09fd3a364c2ce86bbb (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.h4
-rw-r--r--arch/arc/kernel/mcip.c19
-rw-r--r--arch/arc/kernel/smp.c13
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 */
42extern int smp_ipi_irq_setup(int cpu, int irq); 42extern 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
210static int idu_first_irq; 210static irq_hw_number_t idu_first_hwirq;
211 211
212static void idu_cascade_isr(struct irq_desc *desc) 212static 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
222static int idu_irq_map(struct irq_domain *d, unsigned int virq, irq_hw_number_t hwirq) 221static 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 */
354static DEFINE_PER_CPU(int, ipi_dev); 355static DEFINE_PER_CPU(int, ipi_dev);
355 356
356int smp_ipi_irq_setup(int cpu, int irq) 357int 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}