History

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

Yuriy Kolerov committed 10 years ago

Commit 34e71e41 parent 19dbc763 files · +20 −16Browse files

Unified · Split

3 files
  1. arch/arc/include/asm/smp.h +2 −2
  2. arch/arc/kernel/mcip.c +9 −10
  3. arch/arc/kernel/smp.c +9 −4
arch/arc/include/asm/smp.h+2−2
@@ -37,9 +37,9 @@ extern const char *arc_platform_smp_cpuinfo(void); · 36 unmodified lines
3737 * API expected BY platform smp code (FROM arch smp code)
3838 *
3939 * 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
4141 */
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);
4343
4444 /*
4545 * struct plat_smp_ops - SMP callbacks provided by platform to ARC SMP
arch/arc/kernel/mcip.c+9−10
@@ -207,16 +207,15 @@ static struct irq_chip idu_irq_chip = { · 206 unmodified lines
207207
208208 };
209209
210−static int idu_first_irq;
210+static irq_hw_number_t idu_first_hwirq;
211211
212212 static void idu_cascade_isr(struct irq_desc *desc)
213213 {
214− struct irq_domain *domain = irq_desc_get_handler_data(desc);
215− unsigned int core_irq = irq_desc_get_irq(desc);
216− unsigned int idu_irq;
214+ struct irq_domain *idu_domain = irq_desc_get_handler_data(desc);
215+ irq_hw_number_t core_hwirq = irqd_to_hwirq(irq_desc_get_irq_data(desc));
216+ irq_hw_number_t idu_hwirq = core_hwirq - idu_first_hwirq;
217217
218− idu_irq = core_irq - idu_first_irq;
219− generic_handle_irq(irq_find_mapping(domain, idu_irq));
218+ generic_handle_irq(irq_find_mapping(idu_domain, idu_hwirq));
220219 }
221220
222221 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) · 59 unmodified lines
282281 struct irq_domain *domain;
283282 /* Read IDU BCR to confirm nr_irqs */
284283 int nr_irqs = of_irq_count(intc);
285− int i, irq;
284+ int i, virq;
286285 struct mcip_bcr mp;
287286
288287 READ_BCR(ARC_REG_MCIP_BCR, mp);
@@ -303,11 +302,11 @@ idu_of_init(struct device_node *intc, struct device_node *parent) · 14 unmodified lines
303302 * however we need it to get the parent virq and set IDU handler
304303 * as first level isr
305304 */
306− irq = irq_of_parse_and_map(intc, i);
305+ virq = irq_of_parse_and_map(intc, i);
307306 if (!i)
308− idu_first_irq = irq;
307+ idu_first_hwirq = irqd_to_hwirq(irq_get_irq_data(virq));
309308
310− irq_set_chained_handler_and_data(irq, idu_cascade_isr, domain);
309+ irq_set_chained_handler_and_data(virq, idu_cascade_isr, domain);
311310 }
312311
313312 __mcip_cmd(CMD_IDU_ENABLE, 0);
arch/arc/kernel/smp.c+9−4
@@ -22,6 +22,7 @@ · 21 unmodified lines
2222 #include <linux/atomic.h>
2323 #include <linux/cpumask.h>
2424 #include <linux/reboot.h>
25+#include <linux/irqdomain.h>
2526 #include <asm/processor.h>
2627 #include <asm/setup.h>
2728 #include <asm/mach_desc.h>
@@ -353,20 +354,24 @@ irqreturn_t do_IPI(int irq, void *dev_id) · 325 unmodified lines
353354 */
354355 static DEFINE_PER_CPU(int, ipi_dev);
355356
356−int smp_ipi_irq_setup(int cpu, int irq)
357+int smp_ipi_irq_setup(int cpu, irq_hw_number_t hwirq)
357358 {
358359 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);
359364
360365 /* Boot cpu calls request, all call enable */
361366 if (!cpu) {
362367 int rc;
363368
364− rc = request_percpu_irq(irq, do_IPI, "IPI Interrupt", dev);
369+ rc = request_percpu_irq(virq, do_IPI, "IPI Interrupt", dev);
365370 if (rc)
366− panic("Percpu IRQ request failed for %d\n", irq);
371+ panic("Percpu IRQ request failed for %u\n", virq);
367372 }
368373
369− enable_percpu_irq(irq, 0);
374+ enable_percpu_irq(virq, 0);
370375
371376 return 0;
372377 }