提交 3513cdec 编写于 作者: J Jon Hunter 提交者: Linus Walleij

gpio/omap: optimise interrupt service routine

The OMAP GPIO interrupt service routine is checking each bit in the
GPIO interrupt status register to see which bits are set. It is not
efficient to check every bit especially if only a few bits are set.
Therefore, instead of checking every bit use the __ffs() function,
which returns the location of the first set bit, to find all the set
bits.

This optimisation was suggested-by and developed in collaboration
with Felipe Balbi.
Signed-off-by: NJon Hunter <jon-hunter@ti.com>
Reviewed-by: NFelipe Balbi <balbi@ti.com>
Acked-by: NSantosh Shilimkar <santosh.shilimkar@ti.com>
Reviewed-by: NKevin Hilman <khilman@linaro.org>
Signed-off-by: NLinus Walleij <linus.walleij@linaro.org>
上级 60b18b9a
...@@ -689,7 +689,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) ...@@ -689,7 +689,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
{ {
void __iomem *isr_reg = NULL; void __iomem *isr_reg = NULL;
u32 isr; u32 isr;
unsigned int i; unsigned int bit;
struct gpio_bank *bank; struct gpio_bank *bank;
int unmasked = 0; int unmasked = 0;
struct irq_chip *chip = irq_desc_get_chip(desc); struct irq_chip *chip = irq_desc_get_chip(desc);
...@@ -730,9 +730,9 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) ...@@ -730,9 +730,9 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
if (!isr) if (!isr)
break; break;
for (i = 0; isr != 0; isr >>= 1, i++) { while (isr) {
if (!(isr & 1)) bit = __ffs(isr);
continue; isr &= ~(1 << bit);
/* /*
* Some chips can't respond to both rising and falling * Some chips can't respond to both rising and falling
...@@ -741,10 +741,10 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) ...@@ -741,10 +741,10 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
* to respond to the IRQ for the opposite direction. * to respond to the IRQ for the opposite direction.
* This will be indicated in the bank toggle_mask. * This will be indicated in the bank toggle_mask.
*/ */
if (bank->toggle_mask & (1 << i)) if (bank->toggle_mask & (1 << bit))
_toggle_gpio_edge_triggering(bank, i); _toggle_gpio_edge_triggering(bank, bit);
generic_handle_irq(irq_find_mapping(bank->domain, i)); generic_handle_irq(irq_find_mapping(bank->domain, bit));
} }
} }
/* if bank has any level sensitive GPIO pin interrupt /* if bank has any level sensitive GPIO pin interrupt
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册