Skip to content

Commit

Permalink
irqchip: orion: Reverse irq handling priority
Browse files Browse the repository at this point in the history
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, torvalds#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, torvalds#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: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Link: https://lkml.kernel.org/r/1398719528-23607-1-git-send-email-sebastian.hesselbarth@gmail.com
Acked-by: Jason Cooper <jason@lakedaemon.net>
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
  • Loading branch information
shesselba authored and pstglia committed Sep 27, 2014
1 parent becf5ef commit b1a5968
Showing 1 changed file with 2 additions and 2 deletions.
4 changes: 2 additions & 2 deletions drivers/irqchip/irq-orion.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ __exception_irq_entry orion_handle_irq(struct pt_regs *regs)
u32 stat = readl_relaxed(gc->reg_base + ORION_IRQ_CAUSE) &
gc->mask_cache;
while (stat) {
u32 hwirq = ffs(stat) - 1;
u32 hwirq = __fls(stat);
u32 irq = irq_find_mapping(orion_irq_domain,
gc->irq_base + hwirq);
handle_IRQ(irq, regs);
Expand Down Expand Up @@ -117,7 +117,7 @@ static void orion_bridge_irq_handler(unsigned int irq, struct irq_desc *desc)
gc->mask_cache;

while (stat) {
u32 hwirq = ffs(stat) - 1;
u32 hwirq = __fls(stat);

generic_handle_irq(irq_find_mapping(d, gc->irq_base + hwirq));
stat &= ~(1 << hwirq);
Expand Down

0 comments on commit b1a5968

Please sign in to comment.