diff options
Diffstat (limited to 'drivers/irqchip/irq-armada-370-xp.c')
-rw-r--r-- | drivers/irqchip/irq-armada-370-xp.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c index 2f01073d6201..6a2e168c3ab0 100644 --- a/drivers/irqchip/irq-armada-370-xp.c +++ b/drivers/irqchip/irq-armada-370-xp.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #define ARMADA_370_XP_INT_CLEAR_ENABLE_OFFS (0x34) | 43 | #define ARMADA_370_XP_INT_CLEAR_ENABLE_OFFS (0x34) |
44 | #define ARMADA_370_XP_INT_SOURCE_CTL(irq) (0x100 + irq*4) | 44 | #define ARMADA_370_XP_INT_SOURCE_CTL(irq) (0x100 + irq*4) |
45 | #define ARMADA_370_XP_INT_SOURCE_CPU_MASK 0xF | 45 | #define ARMADA_370_XP_INT_SOURCE_CPU_MASK 0xF |
46 | #define ARMADA_370_XP_INT_IRQ_FIQ_MASK(cpuid) ((BIT(0) | BIT(8)) << cpuid) | ||
46 | 47 | ||
47 | #define ARMADA_370_XP_CPU_INTACK_OFFS (0x44) | 48 | #define ARMADA_370_XP_CPU_INTACK_OFFS (0x44) |
48 | #define ARMADA_375_PPI_CAUSE (0x10) | 49 | #define ARMADA_375_PPI_CAUSE (0x10) |
@@ -406,19 +407,29 @@ static void armada_370_xp_mpic_handle_cascade_irq(unsigned int irq, | |||
406 | struct irq_desc *desc) | 407 | struct irq_desc *desc) |
407 | { | 408 | { |
408 | struct irq_chip *chip = irq_get_chip(irq); | 409 | struct irq_chip *chip = irq_get_chip(irq); |
409 | unsigned long irqmap, irqn; | 410 | unsigned long irqmap, irqn, irqsrc, cpuid; |
410 | unsigned int cascade_irq; | 411 | unsigned int cascade_irq; |
411 | 412 | ||
412 | chained_irq_enter(chip, desc); | 413 | chained_irq_enter(chip, desc); |
413 | 414 | ||
414 | irqmap = readl_relaxed(per_cpu_int_base + ARMADA_375_PPI_CAUSE); | 415 | irqmap = readl_relaxed(per_cpu_int_base + ARMADA_375_PPI_CAUSE); |
415 | 416 | cpuid = cpu_logical_map(smp_processor_id()); | |
416 | if (irqmap & BIT(1)) { | ||
417 | armada_370_xp_handle_msi_irq(NULL, true); | ||
418 | irqmap &= ~BIT(1); | ||
419 | } | ||
420 | 417 | ||
421 | for_each_set_bit(irqn, &irqmap, BITS_PER_LONG) { | 418 | for_each_set_bit(irqn, &irqmap, BITS_PER_LONG) { |
419 | irqsrc = readl_relaxed(main_int_base + | ||
420 | ARMADA_370_XP_INT_SOURCE_CTL(irqn)); | ||
421 | |||
422 | /* Check if the interrupt is not masked on current CPU. | ||
423 | * Test IRQ (0-1) and FIQ (8-9) mask bits. | ||
424 | */ | ||
425 | if (!(irqsrc & ARMADA_370_XP_INT_IRQ_FIQ_MASK(cpuid))) | ||
426 | continue; | ||
427 | |||
428 | if (irqn == 1) { | ||
429 | armada_370_xp_handle_msi_irq(NULL, true); | ||
430 | continue; | ||
431 | } | ||
432 | |||
422 | cascade_irq = irq_find_mapping(armada_370_xp_mpic_domain, irqn); | 433 | cascade_irq = irq_find_mapping(armada_370_xp_mpic_domain, irqn); |
423 | generic_handle_irq(cascade_irq); | 434 | generic_handle_irq(cascade_irq); |
424 | } | 435 | } |