diff options
author | Ezequiel Garcia <ezequiel.garcia@free-electrons.com> | 2014-02-10 15:00:01 -0500 |
---|---|---|
committer | Jason Cooper <jason@lakedaemon.net> | 2014-02-22 01:12:13 -0500 |
commit | 9b8cf779f93bc48c0f12ef71e5bc90fd92322656 (patch) | |
tree | 8ccda9f877c6b7459bbad63109adcdef25a18e9b /drivers/irqchip | |
parent | 3efca1d15656fe7e3f57c1f5f21e596967355200 (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.c | 54 |
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 | ||
356 | static 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 | ||
380 | static void armada_370_xp_handle_msi_irq(struct pt_regs *r) {} | ||
381 | #endif | ||
382 | |||
355 | static asmlinkage void __exception_irq_entry | 383 | static asmlinkage void __exception_irq_entry |
356 | armada_370_xp_handle_irq(struct pt_regs *regs) | 384 | armada_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 */ |