Commit a50d7156f171c9ee1f1b58d354114fbdcf4faf1e
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
Merge branch 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq fixes from Thomas Gleixner: "Two fixlets for the armada SoC interrupt controller" * 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: irqchip: armada-370-xp: Fix MPIC interrupt handling irqchip: armada-370-xp: Fix MSI interrupt handling
Showing 1 changed file Side-by-side Diff
drivers/irqchip/irq-armada-370-xp.c
... | ... | @@ -43,6 +43,7 @@ |
43 | 43 | #define ARMADA_370_XP_INT_CLEAR_ENABLE_OFFS (0x34) |
44 | 44 | #define ARMADA_370_XP_INT_SOURCE_CTL(irq) (0x100 + irq*4) |
45 | 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 | 48 | #define ARMADA_370_XP_CPU_INTACK_OFFS (0x44) |
48 | 49 | #define ARMADA_375_PPI_CAUSE (0x10) |
49 | 50 | |
50 | 51 | |
51 | 52 | |
... | ... | @@ -406,19 +407,29 @@ |
406 | 407 | struct irq_desc *desc) |
407 | 408 | { |
408 | 409 | struct irq_chip *chip = irq_get_chip(irq); |
409 | - unsigned long irqmap, irqn; | |
410 | + unsigned long irqmap, irqn, irqsrc, cpuid; | |
410 | 411 | unsigned int cascade_irq; |
411 | 412 | |
412 | 413 | chained_irq_enter(chip, desc); |
413 | 414 | |
414 | 415 | irqmap = readl_relaxed(per_cpu_int_base + ARMADA_375_PPI_CAUSE); |
416 | + cpuid = cpu_logical_map(smp_processor_id()); | |
415 | 417 | |
416 | - if (irqmap & BIT(0)) { | |
417 | - armada_370_xp_handle_msi_irq(NULL, true); | |
418 | - irqmap &= ~BIT(0); | |
419 | - } | |
420 | - | |
421 | 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 | 433 | cascade_irq = irq_find_mapping(armada_370_xp_mpic_domain, irqn); |
423 | 434 | generic_handle_irq(cascade_irq); |
424 | 435 | } |