diff options
author | Colin Cross <ccross@android.com> | 2011-06-06 16:38:18 -0400 |
---|---|---|
committer | Kevin Hilman <khilman@ti.com> | 2011-06-06 19:12:34 -0400 |
commit | 85ec7b970553369e0c956fab1d7a6022f2a99369 (patch) | |
tree | ee66d404199eb4a1cd0c1608b30377e798c305b3 /drivers/gpio | |
parent | 0622b25bf071fd83c6eef6b61fb5f3f12a418528 (diff) |
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.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 5ad827a1a3e..01f74a8459d 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) | |||
1126 | { | 1126 | { |
1127 | unsigned int gpio = d->irq - IH_GPIO_BASE; | 1127 | unsigned int gpio = d->irq - IH_GPIO_BASE; |
1128 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); | 1128 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); |
1129 | unsigned long flags; | ||
1129 | 1130 | ||
1131 | spin_lock_irqsave(&bank->lock, flags); | ||
1130 | _reset_gpio(bank, gpio); | 1132 | _reset_gpio(bank, gpio); |
1133 | spin_unlock_irqrestore(&bank->lock, flags); | ||
1131 | } | 1134 | } |
1132 | 1135 | ||
1133 | static void gpio_ack_irq(struct irq_data *d) | 1136 | static void gpio_ack_irq(struct irq_data *d) |
@@ -1142,9 +1145,12 @@ static void gpio_mask_irq(struct irq_data *d) | |||
1142 | { | 1145 | { |
1143 | unsigned int gpio = d->irq - IH_GPIO_BASE; | 1146 | unsigned int gpio = d->irq - IH_GPIO_BASE; |
1144 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); | 1147 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); |
1148 | unsigned long flags; | ||
1145 | 1149 | ||
1150 | spin_lock_irqsave(&bank->lock, flags); | ||
1146 | _set_gpio_irqenable(bank, gpio, 0); | 1151 | _set_gpio_irqenable(bank, gpio, 0); |
1147 | _set_gpio_triggering(bank, get_gpio_index(gpio), IRQ_TYPE_NONE); | 1152 | _set_gpio_triggering(bank, get_gpio_index(gpio), IRQ_TYPE_NONE); |
1153 | spin_unlock_irqrestore(&bank->lock, flags); | ||
1148 | } | 1154 | } |
1149 | 1155 | ||
1150 | static void gpio_unmask_irq(struct irq_data *d) | 1156 | static void gpio_unmask_irq(struct irq_data *d) |
@@ -1153,7 +1159,9 @@ static void gpio_unmask_irq(struct irq_data *d) | |||
1153 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); | 1159 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); |
1154 | unsigned int irq_mask = 1 << get_gpio_index(gpio); | 1160 | unsigned int irq_mask = 1 << get_gpio_index(gpio); |
1155 | u32 trigger = irqd_get_trigger_type(d); | 1161 | u32 trigger = irqd_get_trigger_type(d); |
1162 | unsigned long flags; | ||
1156 | 1163 | ||
1164 | spin_lock_irqsave(&bank->lock, flags); | ||
1157 | if (trigger) | 1165 | if (trigger) |
1158 | _set_gpio_triggering(bank, get_gpio_index(gpio), trigger); | 1166 | _set_gpio_triggering(bank, get_gpio_index(gpio), trigger); |
1159 | 1167 | ||
@@ -1165,6 +1173,7 @@ static void gpio_unmask_irq(struct irq_data *d) | |||
1165 | } | 1173 | } |
1166 | 1174 | ||
1167 | _set_gpio_irqenable(bank, gpio, 1); | 1175 | _set_gpio_irqenable(bank, gpio, 1); |
1176 | spin_unlock_irqrestore(&bank->lock, flags); | ||
1168 | } | 1177 | } |
1169 | 1178 | ||
1170 | static struct irq_chip gpio_irq_chip = { | 1179 | static struct irq_chip gpio_irq_chip = { |