aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/irqchip
diff options
context:
space:
mode:
authorEzequiel Garcia <ezequiel.garcia@free-electrons.com>2014-02-10 15:00:01 -0500
committerJason Cooper <jason@lakedaemon.net>2014-02-22 01:12:13 -0500
commit9b8cf779f93bc48c0f12ef71e5bc90fd92322656 (patch)
tree8ccda9f877c6b7459bbad63109adcdef25a18e9b /drivers/irqchip
parent3efca1d15656fe7e3f57c1f5f21e596967355200 (diff)
irqchip: armada-370-xp: Add helper for the MSI IRQ handling
Introduce a helper function to handle the MSI interrupts. This makes the code more readable. In addition, this will allow to introduce a chained IRQ handler mechanism, which is needed in situations where the MPIC is used as a slave to another interrupt controller. Reviewed-by: Gregory CLEMENT <gregory.clement@free-electrons.com> Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com> Signed-off-by: Jason Cooper <jason@lakedaemon.net>
Diffstat (limited to 'drivers/irqchip')
-rw-r--r--drivers/irqchip/irq-armada-370-xp.c54
1 files changed, 30 insertions, 24 deletions
diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c
index 540956465ed2..2ba5761a638e 100644
--- a/drivers/irqchip/irq-armada-370-xp.c
+++ b/drivers/irqchip/irq-armada-370-xp.c
@@ -352,6 +352,34 @@ static struct irq_domain_ops armada_370_xp_mpic_irq_ops = {
352 .xlate = irq_domain_xlate_onecell, 352 .xlate = irq_domain_xlate_onecell,
353}; 353};
354 354
355#ifdef CONFIG_PCI_MSI
356static void armada_370_xp_handle_msi_irq(struct pt_regs *regs)
357{
358 u32 msimask, msinr;
359
360 msimask = readl_relaxed(per_cpu_int_base +
361 ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS)
362 & PCI_MSI_DOORBELL_MASK;
363
364 writel(~msimask, per_cpu_int_base +
365 ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS);
366
367 for (msinr = PCI_MSI_DOORBELL_START;
368 msinr < PCI_MSI_DOORBELL_END; msinr++) {
369 int irq;
370
371 if (!(msimask & BIT(msinr)))
372 continue;
373
374 irq = irq_find_mapping(armada_370_xp_msi_domain,
375 msinr - 16);
376 handle_IRQ(irq, regs);
377 }
378}
379#else
380static void armada_370_xp_handle_msi_irq(struct pt_regs *r) {}
381#endif
382
355static asmlinkage void __exception_irq_entry 383static asmlinkage void __exception_irq_entry
356armada_370_xp_handle_irq(struct pt_regs *regs) 384armada_370_xp_handle_irq(struct pt_regs *regs)
357{ 385{
@@ -372,31 +400,9 @@ armada_370_xp_handle_irq(struct pt_regs *regs)
372 continue; 400 continue;
373 } 401 }
374 402
375#ifdef CONFIG_PCI_MSI
376 /* MSI handling */ 403 /* MSI handling */
377 if (irqnr == 1) { 404 if (irqnr == 1)
378 u32 msimask, msinr; 405 armada_370_xp_handle_msi_irq(regs);
379
380 msimask = readl_relaxed(per_cpu_int_base +
381 ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS)
382 & PCI_MSI_DOORBELL_MASK;
383
384 writel(~msimask, per_cpu_int_base +
385 ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS);
386
387 for (msinr = PCI_MSI_DOORBELL_START;
388 msinr < PCI_MSI_DOORBELL_END; msinr++) {
389 int irq;
390
391 if (!(msimask & BIT(msinr)))
392 continue;
393
394 irq = irq_find_mapping(armada_370_xp_msi_domain,
395 msinr - 16);
396 handle_IRQ(irq, regs);
397 }
398 }
399#endif
400 406
401#ifdef CONFIG_SMP 407#ifdef CONFIG_SMP
402 /* IPI Handling */ 408 /* IPI Handling */