aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
authorColin Cross <ccross@android.com>2011-06-06 13:38:18 -0700
committerKevin Hilman <khilman@ti.com>2011-06-06 16:12:34 -0700
commit85ec7b970553369e0c956fab1d7a6022f2a99369 (patch)
treeee66d404199eb4a1cd0c1608b30377e798c305b3 /drivers/gpio
parent0622b25bf071fd83c6eef6b61fb5f3f12a418528 (diff)
downloadkernel_samsung_smdk4412-85ec7b970553369e0c956fab1d7a6022f2a99369.zip
kernel_samsung_smdk4412-85ec7b970553369e0c956fab1d7a6022f2a99369.tar.gz
kernel_samsung_smdk4412-85ec7b970553369e0c956fab1d7a6022f2a99369.tar.bz2
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: Colin Cross <ccross@android.com> Signed-off-by: Kevin Hilman <khilman@ti.com>
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/gpio-omap.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 5ad827a..01f74a8 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -1126,8 +1126,11 @@ static void gpio_irq_shutdown(struct irq_data *d)
{
unsigned int gpio = d->irq - IH_GPIO_BASE;
struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
+ unsigned long flags;
+ spin_lock_irqsave(&bank->lock, flags);
_reset_gpio(bank, gpio);
+ spin_unlock_irqrestore(&bank->lock, flags);
}
static void gpio_ack_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;
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_triggering(bank, get_gpio_index(gpio), IRQ_TYPE_NONE);
+ spin_unlock_irqrestore(&bank->lock, flags);
}
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);
unsigned int irq_mask = 1 << get_gpio_index(gpio);
u32 trigger = irqd_get_trigger_type(d);
+ unsigned long flags;
+ spin_lock_irqsave(&bank->lock, flags);
if (trigger)
_set_gpio_triggering(bank, get_gpio_index(gpio), trigger);
@@ -1165,6 +1173,7 @@ static void gpio_unmask_irq(struct irq_data *d)
}
_set_gpio_irqenable(bank, gpio, 1);
+ spin_unlock_irqrestore(&bank->lock, flags);
}
static struct irq_chip gpio_irq_chip = {