Commit bffbc6ea authored by Sebastian Hesselbarth's avatar Sebastian Hesselbarth Committed by Jason Cooper

irqchip: orion: Reverse irq handling priority

Non-DT irq handlers were working through irq causes from most-significant
to least-significant bit, while DT irqchip driver does it the other way
round. This revealed some more HW issues on Kirkwood peripheral IP, where
spurious sdio irqs can happen although irqs are masked.

Also, the generated binaries show that original non-DT order compared
to DT order save two instructions for each bit count check:

irqchip DT order with ffs():
  60:   e3a06001        mov     r6, #1
  64:   e2643000        rsb     r3, r4, #0
  68:   e0033004        and     r3, r3, r4
  6c:   e16f3f13        clz     r3, r3
  70:   e263301f        rsb     r3, r3, #31
  74:   e1c44316        bic     r4, r4, r6, lsl r3
  78:   e5971004        ldr     r1, [r7, #4]

Original non-DT order with fls():
  60:   e3a07001        mov     r7, #1
  64:   e16f3f14        clz     r3, r4
  68:   e263301f        rsb     r3, r3, #31
  6c:   e1c44317        bic     r4, r4, r7, lsl r3
  70:   e5951004        ldr     r1, [r5, #4]

Therefore, reverse irq bit handling back to original order by replacing
ffs() with fls().
Signed-off-by: default avatarSebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Link: https://lkml.kernel.org/r/1398719528-23607-1-git-send-email-sebastian.hesselbarth@gmail.comAcked-by: default avatarJason Cooper <jason@lakedaemon.net>
Signed-off-by: default avatarJason Cooper <jason@lakedaemon.net>
parent d7df84b3
...@@ -42,7 +42,7 @@ __exception_irq_entry orion_handle_irq(struct pt_regs *regs) ...@@ -42,7 +42,7 @@ __exception_irq_entry orion_handle_irq(struct pt_regs *regs)
u32 stat = readl_relaxed(gc->reg_base + ORION_IRQ_CAUSE) & u32 stat = readl_relaxed(gc->reg_base + ORION_IRQ_CAUSE) &
gc->mask_cache; gc->mask_cache;
while (stat) { while (stat) {
u32 hwirq = ffs(stat) - 1; u32 hwirq = __fls(stat);
u32 irq = irq_find_mapping(orion_irq_domain, u32 irq = irq_find_mapping(orion_irq_domain,
gc->irq_base + hwirq); gc->irq_base + hwirq);
handle_IRQ(irq, regs); handle_IRQ(irq, regs);
...@@ -117,7 +117,7 @@ static void orion_bridge_irq_handler(unsigned int irq, struct irq_desc *desc) ...@@ -117,7 +117,7 @@ static void orion_bridge_irq_handler(unsigned int irq, struct irq_desc *desc)
gc->mask_cache; gc->mask_cache;
while (stat) { while (stat) {
u32 hwirq = ffs(stat) - 1; u32 hwirq = __fls(stat);
generic_handle_irq(irq_find_mapping(d, gc->irq_base + hwirq)); generic_handle_irq(irq_find_mapping(d, gc->irq_base + hwirq));
stat &= ~(1 << hwirq); stat &= ~(1 << hwirq);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment