Skip to content

Commit

Permalink
gpio: omap: protect regs access in omap_gpio_irq_handler
Browse files Browse the repository at this point in the history
The access to HW registers has to be be protected in
omap_gpio_irq_handler(), as it may race with code executed on
another CPUs.

Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Acked-by: Santosh Shilimkar <ssantosh@kernel.org>
Tested-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
  • Loading branch information
Grygorii Strashko authored and Linus Walleij committed Aug 26, 2015
1 parent e85ec6c commit 235f1eb
Showing 1 changed file with 8 additions and 0 deletions.
8 changes: 8 additions & 0 deletions drivers/gpio/gpio-omap.c
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,7 @@ static void omap_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
int unmasked = 0;
struct irq_chip *irqchip = irq_desc_get_chip(desc);
struct gpio_chip *chip = irq_desc_get_handler_data(desc);
unsigned long lock_flags;

chained_irq_enter(irqchip, desc);

Expand All @@ -732,6 +733,8 @@ static void omap_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
u32 isr_saved, level_mask = 0;
u32 enabled;

raw_spin_lock_irqsave(&bank->lock, lock_flags);

enabled = omap_get_gpio_irqbank_mask(bank);
isr_saved = isr = readl_relaxed(isr_reg) & enabled;

Expand All @@ -745,6 +748,8 @@ static void omap_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
omap_clear_gpio_irqbank(bank, isr_saved & ~level_mask);
omap_enable_gpio_irqbank(bank, isr_saved & ~level_mask);

raw_spin_unlock_irqrestore(&bank->lock, lock_flags);

/* if there is only edge sensitive GPIO pin interrupts
configured, we could unmask GPIO bank interrupt immediately */
if (!level_mask && !unmasked) {
Expand All @@ -759,6 +764,7 @@ static void omap_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
bit = __ffs(isr);
isr &= ~(BIT(bit));

raw_spin_lock_irqsave(&bank->lock, lock_flags);
/*
* Some chips can't respond to both rising and falling
* at the same time. If this irq was requested with
Expand All @@ -769,6 +775,8 @@ static void omap_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
if (bank->toggle_mask & (BIT(bit)))
omap_toggle_gpio_edge_triggering(bank, bit);

raw_spin_unlock_irqrestore(&bank->lock, lock_flags);

generic_handle_irq(irq_find_mapping(bank->chip.irqdomain,
bit));
}
Expand Down

0 comments on commit 235f1eb

Please sign in to comment.