From: Guo Ren <ren_...@c-sky.com>

Here is the previous interrupt processing flow:
while (pending) {
^^^^^^^^^^^^^^^ It's unnecessary!
        get irq
        handle_level/fasteoi_irq {
                mask irq
                driver irq handler
                unmask irq
        }
        irq_exit {
                preempt_count_sub(HARDIRQ_OFFSET);
                if (!in_interrupt() && local_softirq_pending())
                        invoke_softirq();
Because:                ^^^^^^^^^^^^^^^^ linux enable irq Here!
        }
}

Because linux enable the irq in irq_exit() before ret, we needn't loop
read pending register again for next irq which is done during irq_exit().

Signed-off-by: Guo Ren <ren_...@c-sky.com>
Cc: Thomas Gleixner <t...@linutronix.de>
Cc: Marc Zyngier <marc.zyng...@arm.com>
---
 drivers/irqchip/irq-csky-apb-intc.c | 36 ++++++++++++++++++------------------
 drivers/irqchip/irq-csky-mpintc.c   |  8 ++------
 2 files changed, 20 insertions(+), 24 deletions(-)

diff --git a/drivers/irqchip/irq-csky-apb-intc.c 
b/drivers/irqchip/irq-csky-apb-intc.c
index fcc5444..ae4c59b 100644
--- a/drivers/irqchip/irq-csky-apb-intc.c
+++ b/drivers/irqchip/irq-csky-apb-intc.c
@@ -150,7 +150,7 @@ ck_intc_init_comm(struct device_node *node, struct 
device_node *parent)
        return 0;
 }
 
-static inline bool handle_irq_perbit(struct pt_regs *regs, u32 hwirq,
+static inline bool handle_irq_onebit(struct pt_regs *regs, u32 hwirq,
                                     u32 irq_base)
 {
        if (hwirq == 0)
@@ -166,16 +166,15 @@ static void gx_irq_handler(struct pt_regs *regs)
 {
        bool ret;
 
-retry:
-       ret = handle_irq_perbit(regs,
+       ret = handle_irq_onebit(regs,
                        readl(reg_base + GX_INTC_PEN63_32), 32);
        if (ret)
-               goto retry;
+               return;
 
-       ret = handle_irq_perbit(regs,
+       ret = handle_irq_onebit(regs,
                        readl(reg_base + GX_INTC_PEN31_00), 0);
-       if (ret)
-               goto retry;
+       if (!ret)
+               pr_err("%s: none irq pending!\n", __func__);
 }
 
 static int __init
@@ -277,29 +276,30 @@ static void ck_irq_handler(struct pt_regs *regs)
        void __iomem *reg_pen_lo = reg_base + CK_INTC_PEN31_00;
        void __iomem *reg_pen_hi = reg_base + CK_INTC_PEN63_32;
 
-retry:
        /* handle 0 - 63 irqs */
-       ret = handle_irq_perbit(regs, readl(reg_pen_hi), 32);
+       ret = handle_irq_onebit(regs, readl(reg_pen_hi), 32);
        if (ret)
-               goto retry;
+               return;
 
-       ret = handle_irq_perbit(regs, readl(reg_pen_lo), 0);
+       ret = handle_irq_onebit(regs, readl(reg_pen_lo), 0);
        if (ret)
-               goto retry;
+               return;
 
-       if (nr_irq == INTC_IRQS)
+       if (nr_irq == INTC_IRQS) {
+               pr_err("%s: none irq pending!\n", __func__);
                return;
+       }
 
        /* handle 64 - 127 irqs */
-       ret = handle_irq_perbit(regs,
+       ret = handle_irq_onebit(regs,
                        readl(reg_pen_hi + CK_INTC_DUAL_BASE), 96);
        if (ret)
-               goto retry;
+               return;
 
-       ret = handle_irq_perbit(regs,
+       ret = handle_irq_onebit(regs,
                        readl(reg_pen_lo + CK_INTC_DUAL_BASE), 64);
-       if (ret)
-               goto retry;
+       if (!ret)
+               pr_err("%s: none irq pending!\n", __func__);
 }
 
 static int __init
diff --git a/drivers/irqchip/irq-csky-mpintc.c 
b/drivers/irqchip/irq-csky-mpintc.c
index 9edc6d3..37ff62b 100644
--- a/drivers/irqchip/irq-csky-mpintc.c
+++ b/drivers/irqchip/irq-csky-mpintc.c
@@ -36,7 +36,6 @@ static void __iomem *INTCL_base;
 #define INTCL_CFGR     0x14
 #define INTCL_PRTR     0x20
 #define INTCL_SIGR     0x60
-#define INTCL_HPPIR    0x68
 #define INTCL_RDYIR    0x6c
 #define INTCL_SENR     0xa0
 #define INTCL_CENR     0xa4
@@ -48,11 +47,8 @@ static void csky_mpintc_handler(struct pt_regs *regs)
 {
        void __iomem *reg_base = this_cpu_read(intcl_reg);
 
-       do {
-               handle_domain_irq(root_domain,
-                                 readl_relaxed(reg_base + INTCL_RDYIR),
-                                 regs);
-       } while (readl_relaxed(reg_base + INTCL_HPPIR) & BIT(31));
+       handle_domain_irq(root_domain,
+               readl_relaxed(reg_base + INTCL_RDYIR), regs);
 }
 
 static void csky_mpintc_enable(struct irq_data *d)
-- 
2.7.4

Reply via email to