ARM: S5PV310: Add irq_mask to handle combiner irqs properly
authorChanghwan Youn <chaos.youn@samsung.com>
Mon, 29 Nov 2010 08:05:16 +0000 (17:05 +0900)
committerKukjin Kim <kgene.kim@samsung.com>
Wed, 8 Dec 2010 09:11:37 +0000 (18:11 +0900)
The 4 combiner groups use same registers to handle the interrupt.
In previous implementation, the whole registers are checked to find
which interupt is occurred and thus interrupt in other groups can
be detected. This patch adds irq_mask to solve this problem.

Signed-off-by: Changhwan Youn <chaos.youn@samsung.com>
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
arch/arm/mach-s5pv310/irq-combiner.c

index c3f88c3faf6c79b943aabbe420d3aa2e976be761..aad5c3d525d172c3a665e45968d66f5771b4d830 100644 (file)
@@ -24,6 +24,7 @@ static DEFINE_SPINLOCK(irq_controller_lock);
 
 struct combiner_chip_data {
        unsigned int irq_offset;
+       unsigned int irq_mask;
        void __iomem *base;
 };
 
@@ -62,6 +63,7 @@ static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
        spin_lock(&irq_controller_lock);
        status = __raw_readl(chip_data->base + COMBINER_INT_STATUS);
        spin_unlock(&irq_controller_lock);
+       status &= chip_data->irq_mask;
 
        if (status == 0)
                goto out;
@@ -104,10 +106,12 @@ void __init combiner_init(unsigned int combiner_nr, void __iomem *base,
 
        combiner_data[combiner_nr].base = base;
        combiner_data[combiner_nr].irq_offset = irq_start;
+       combiner_data[combiner_nr].irq_mask = 0xff << ((combiner_nr % 4) << 3);
 
        /* Disable all interrupts */
 
-       __raw_writel(0xffffffff, base + COMBINER_ENABLE_CLEAR);
+       __raw_writel(combiner_data[combiner_nr].irq_mask,
+                    base + COMBINER_ENABLE_CLEAR);
 
        /* Setup the Linux IRQ subsystem */