Merge branch 'liblockdep-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git...
[firefly-linux-kernel-4.4.55.git] / drivers / irqchip / irq-sun4i.c
index 7ae85ec61e56ee022a349f56f88640b0cb2ddf8f..6fcef4a95a18af9462431a1d1ef39cd0f100aaa2 100644 (file)
@@ -41,13 +41,11 @@ static void __exception_irq_entry sun4i_handle_irq(struct pt_regs *regs);
 static void sun4i_irq_ack(struct irq_data *irqd)
 {
        unsigned int irq = irqd_to_hwirq(irqd);
-       unsigned int irq_off = irq % 32;
-       int reg = irq / 32;
-       u32 val;
 
-       val = readl(sun4i_irq_base + SUN4I_IRQ_PENDING_REG(reg));
-       writel(val | (1 << irq_off),
-              sun4i_irq_base + SUN4I_IRQ_PENDING_REG(reg));
+       if (irq != 0)
+               return; /* Only IRQ 0 / the ENMI needs to be acked */
+
+       writel(BIT(0), sun4i_irq_base + SUN4I_IRQ_PENDING_REG(0));
 }
 
 static void sun4i_irq_mask(struct irq_data *irqd)
@@ -76,16 +74,16 @@ static void sun4i_irq_unmask(struct irq_data *irqd)
 
 static struct irq_chip sun4i_irq_chip = {
        .name           = "sun4i_irq",
-       .irq_ack        = sun4i_irq_ack,
+       .irq_eoi        = sun4i_irq_ack,
        .irq_mask       = sun4i_irq_mask,
        .irq_unmask     = sun4i_irq_unmask,
+       .flags          = IRQCHIP_EOI_THREADED | IRQCHIP_EOI_IF_HANDLED,
 };
 
 static int sun4i_irq_map(struct irq_domain *d, unsigned int virq,
                         irq_hw_number_t hw)
 {
-       irq_set_chip_and_handler(virq, &sun4i_irq_chip,
-                                handle_level_irq);
+       irq_set_chip_and_handler(virq, &sun4i_irq_chip, handle_fasteoi_irq);
        set_irq_flags(virq, IRQF_VALID | IRQF_PROBE);
 
        return 0;
@@ -109,7 +107,7 @@ static int __init sun4i_of_init(struct device_node *node,
        writel(0, sun4i_irq_base + SUN4I_IRQ_ENABLE_REG(1));
        writel(0, sun4i_irq_base + SUN4I_IRQ_ENABLE_REG(2));
 
-       /* Mask all the interrupts */
+       /* Unmask all the interrupts, ENABLE_REG(x) is used for masking */
        writel(0, sun4i_irq_base + SUN4I_IRQ_MASK_REG(0));
        writel(0, sun4i_irq_base + SUN4I_IRQ_MASK_REG(1));
        writel(0, sun4i_irq_base + SUN4I_IRQ_MASK_REG(2));