diff options
author | Cyril Chemparathy <cyril@ti.com> | 2010-05-01 18:37:55 -0400 |
---|---|---|
committer | Kevin Hilman <khilman@deeprootsystems.com> | 2010-05-06 18:02:09 -0400 |
commit | b27b6d03f245e5eaf6473da58a2612077fb7cfe7 (patch) | |
tree | b6ed359c8b604edcaed5025aa83c57d77daec1a9 | |
parent | 686b634a07451fc4fe3b712fe211bfa861a53241 (diff) |
Davinci: gpio - fine grained locking
This patch eliminates the global gpio_lock, and implements a per-controller
lock instead. This also switches to irqsave/irqrestore locks in case gpios
are manipulated in isr.
Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Tested-by: Sandeep Paulraj <s-paulraj@ti.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
-rw-r--r-- | arch/arm/mach-davinci/gpio.c | 9 | ||||
-rw-r--r-- | arch/arm/mach-davinci/include/mach/gpio.h | 3 |
2 files changed, 8 insertions, 4 deletions
diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c index e422cd300d4c..b62d5e2bd37e 100644 --- a/arch/arm/mach-davinci/gpio.c +++ b/arch/arm/mach-davinci/gpio.c | |||
@@ -33,8 +33,6 @@ struct davinci_gpio_regs { | |||
33 | u32 intstat; | 33 | u32 intstat; |
34 | }; | 34 | }; |
35 | 35 | ||
36 | static DEFINE_SPINLOCK(gpio_lock); | ||
37 | |||
38 | #define chip2controller(chip) \ | 36 | #define chip2controller(chip) \ |
39 | container_of(chip, struct davinci_gpio_controller, chip) | 37 | container_of(chip, struct davinci_gpio_controller, chip) |
40 | 38 | ||
@@ -83,10 +81,11 @@ static inline int __davinci_direction(struct gpio_chip *chip, | |||
83 | { | 81 | { |
84 | struct davinci_gpio_controller *d = chip2controller(chip); | 82 | struct davinci_gpio_controller *d = chip2controller(chip); |
85 | struct davinci_gpio_regs __iomem *g = d->regs; | 83 | struct davinci_gpio_regs __iomem *g = d->regs; |
84 | unsigned long flags; | ||
86 | u32 temp; | 85 | u32 temp; |
87 | u32 mask = 1 << offset; | 86 | u32 mask = 1 << offset; |
88 | 87 | ||
89 | spin_lock(&gpio_lock); | 88 | spin_lock_irqsave(&d->lock, flags); |
90 | temp = __raw_readl(&g->dir); | 89 | temp = __raw_readl(&g->dir); |
91 | if (out) { | 90 | if (out) { |
92 | temp &= ~mask; | 91 | temp &= ~mask; |
@@ -95,7 +94,7 @@ static inline int __davinci_direction(struct gpio_chip *chip, | |||
95 | temp |= mask; | 94 | temp |= mask; |
96 | } | 95 | } |
97 | __raw_writel(temp, &g->dir); | 96 | __raw_writel(temp, &g->dir); |
98 | spin_unlock(&gpio_lock); | 97 | spin_unlock_irqrestore(&d->lock, flags); |
99 | 98 | ||
100 | return 0; | 99 | return 0; |
101 | } | 100 | } |
@@ -175,6 +174,8 @@ static int __init davinci_gpio_setup(void) | |||
175 | if (chips[i].chip.ngpio > 32) | 174 | if (chips[i].chip.ngpio > 32) |
176 | chips[i].chip.ngpio = 32; | 175 | chips[i].chip.ngpio = 32; |
177 | 176 | ||
177 | spin_lock_init(&chips[i].lock); | ||
178 | |||
178 | regs = gpio2regs(base); | 179 | regs = gpio2regs(base); |
179 | chips[i].regs = regs; | 180 | chips[i].regs = regs; |
180 | chips[i].set_data = ®s->set_data; | 181 | chips[i].set_data = ®s->set_data; |
diff --git a/arch/arm/mach-davinci/include/mach/gpio.h b/arch/arm/mach-davinci/include/mach/gpio.h index 9a71a26eb77f..504cc180a60b 100644 --- a/arch/arm/mach-davinci/include/mach/gpio.h +++ b/arch/arm/mach-davinci/include/mach/gpio.h | |||
@@ -14,6 +14,8 @@ | |||
14 | #define __DAVINCI_GPIO_H | 14 | #define __DAVINCI_GPIO_H |
15 | 15 | ||
16 | #include <linux/io.h> | 16 | #include <linux/io.h> |
17 | #include <linux/spinlock.h> | ||
18 | |||
17 | #include <asm-generic/gpio.h> | 19 | #include <asm-generic/gpio.h> |
18 | 20 | ||
19 | #include <mach/irqs.h> | 21 | #include <mach/irqs.h> |
@@ -52,6 +54,7 @@ enum davinci_gpio_type { | |||
52 | struct davinci_gpio_controller { | 54 | struct davinci_gpio_controller { |
53 | struct gpio_chip chip; | 55 | struct gpio_chip chip; |
54 | int irq_base; | 56 | int irq_base; |
57 | spinlock_t lock; | ||
55 | void __iomem *regs; | 58 | void __iomem *regs; |
56 | void __iomem *set_data; | 59 | void __iomem *set_data; |
57 | void __iomem *clr_data; | 60 | void __iomem *clr_data; |