Commit 85ec7b97 authored by Colin Cross's avatar Colin Cross Committed by Kevin Hilman

GPIO: OMAP: add locking around calls to _set_gpio_triggering

_set_gpio_triggering uses read-modify-write on bank registers,
lock bank->lock around all calls to it to prevent register
corruption if two cpus access gpios in the same bank at the
same time.
Signed-off-by: default avatarColin Cross <ccross@android.com>
Signed-off-by: default avatarKevin Hilman <khilman@ti.com>
parent 0622b25b
...@@ -1126,8 +1126,11 @@ static void gpio_irq_shutdown(struct irq_data *d) ...@@ -1126,8 +1126,11 @@ static void gpio_irq_shutdown(struct irq_data *d)
{ {
unsigned int gpio = d->irq - IH_GPIO_BASE; unsigned int gpio = d->irq - IH_GPIO_BASE;
struct gpio_bank *bank = irq_data_get_irq_chip_data(d); struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
unsigned long flags;
spin_lock_irqsave(&bank->lock, flags);
_reset_gpio(bank, gpio); _reset_gpio(bank, gpio);
spin_unlock_irqrestore(&bank->lock, flags);
} }
static void gpio_ack_irq(struct irq_data *d) static void gpio_ack_irq(struct irq_data *d)
...@@ -1142,9 +1145,12 @@ static void gpio_mask_irq(struct irq_data *d) ...@@ -1142,9 +1145,12 @@ static void gpio_mask_irq(struct irq_data *d)
{ {
unsigned int gpio = d->irq - IH_GPIO_BASE; unsigned int gpio = d->irq - IH_GPIO_BASE;
struct gpio_bank *bank = irq_data_get_irq_chip_data(d); struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
unsigned long flags;
spin_lock_irqsave(&bank->lock, flags);
_set_gpio_irqenable(bank, gpio, 0); _set_gpio_irqenable(bank, gpio, 0);
_set_gpio_triggering(bank, get_gpio_index(gpio), IRQ_TYPE_NONE); _set_gpio_triggering(bank, get_gpio_index(gpio), IRQ_TYPE_NONE);
spin_unlock_irqrestore(&bank->lock, flags);
} }
static void gpio_unmask_irq(struct irq_data *d) static void gpio_unmask_irq(struct irq_data *d)
...@@ -1153,7 +1159,9 @@ static void gpio_unmask_irq(struct irq_data *d) ...@@ -1153,7 +1159,9 @@ static void gpio_unmask_irq(struct irq_data *d)
struct gpio_bank *bank = irq_data_get_irq_chip_data(d); struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
unsigned int irq_mask = 1 << get_gpio_index(gpio); unsigned int irq_mask = 1 << get_gpio_index(gpio);
u32 trigger = irqd_get_trigger_type(d); u32 trigger = irqd_get_trigger_type(d);
unsigned long flags;
spin_lock_irqsave(&bank->lock, flags);
if (trigger) if (trigger)
_set_gpio_triggering(bank, get_gpio_index(gpio), trigger); _set_gpio_triggering(bank, get_gpio_index(gpio), trigger);
...@@ -1165,6 +1173,7 @@ static void gpio_unmask_irq(struct irq_data *d) ...@@ -1165,6 +1173,7 @@ static void gpio_unmask_irq(struct irq_data *d)
} }
_set_gpio_irqenable(bank, gpio, 1); _set_gpio_irqenable(bank, gpio, 1);
spin_unlock_irqrestore(&bank->lock, flags);
} }
static struct irq_chip gpio_irq_chip = { static struct irq_chip gpio_irq_chip = {
......
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