diff options
Diffstat (limited to 'arch/arm/mach-davinci/gpio.c')
-rw-r--r-- | arch/arm/mach-davinci/gpio.c | 160 |
1 files changed, 103 insertions, 57 deletions
diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c index 744755b53236..bf0ff587e46a 100644 --- a/arch/arm/mach-davinci/gpio.c +++ b/arch/arm/mach-davinci/gpio.c | |||
@@ -20,46 +20,92 @@ | |||
20 | 20 | ||
21 | #include <asm/mach/irq.h> | 21 | #include <asm/mach/irq.h> |
22 | 22 | ||
23 | static DEFINE_SPINLOCK(gpio_lock); | 23 | struct davinci_gpio_regs { |
24 | 24 | u32 dir; | |
25 | struct davinci_gpio { | 25 | u32 out_data; |
26 | struct gpio_chip chip; | 26 | u32 set_data; |
27 | struct gpio_controller *__iomem regs; | 27 | u32 clr_data; |
28 | int irq_base; | 28 | u32 in_data; |
29 | u32 set_rising; | ||
30 | u32 clr_rising; | ||
31 | u32 set_falling; | ||
32 | u32 clr_falling; | ||
33 | u32 intstat; | ||
29 | }; | 34 | }; |
30 | 35 | ||
31 | static struct davinci_gpio chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)]; | 36 | #define chip2controller(chip) \ |
37 | container_of(chip, struct davinci_gpio_controller, chip) | ||
38 | |||
39 | static struct davinci_gpio_controller chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)]; | ||
40 | static void __iomem *gpio_base; | ||
41 | |||
42 | static struct davinci_gpio_regs __iomem __init *gpio2regs(unsigned gpio) | ||
43 | { | ||
44 | void __iomem *ptr; | ||
45 | |||
46 | if (gpio < 32 * 1) | ||
47 | ptr = gpio_base + 0x10; | ||
48 | else if (gpio < 32 * 2) | ||
49 | ptr = gpio_base + 0x38; | ||
50 | else if (gpio < 32 * 3) | ||
51 | ptr = gpio_base + 0x60; | ||
52 | else if (gpio < 32 * 4) | ||
53 | ptr = gpio_base + 0x88; | ||
54 | else if (gpio < 32 * 5) | ||
55 | ptr = gpio_base + 0xb0; | ||
56 | else | ||
57 | ptr = NULL; | ||
58 | return ptr; | ||
59 | } | ||
32 | 60 | ||
33 | /* create a non-inlined version */ | 61 | static inline struct davinci_gpio_regs __iomem *irq2regs(int irq) |
34 | static struct gpio_controller __iomem * __init gpio2controller(unsigned gpio) | ||
35 | { | 62 | { |
36 | return __gpio_to_controller(gpio); | 63 | struct davinci_gpio_regs __iomem *g; |
64 | |||
65 | g = (__force struct davinci_gpio_regs __iomem *)get_irq_chip_data(irq); | ||
66 | |||
67 | return g; | ||
37 | } | 68 | } |
38 | 69 | ||
39 | static int __init davinci_gpio_irq_setup(void); | 70 | static int __init davinci_gpio_irq_setup(void); |
40 | 71 | ||
41 | /*--------------------------------------------------------------------------*/ | 72 | /*--------------------------------------------------------------------------*/ |
42 | 73 | ||
43 | /* | 74 | /* board setup code *MUST* setup pinmux and enable the GPIO clock. */ |
44 | * board setup code *MUST* set PINMUX0 and PINMUX1 as | 75 | static inline int __davinci_direction(struct gpio_chip *chip, |
45 | * needed, and enable the GPIO clock. | 76 | unsigned offset, bool out, int value) |
46 | */ | ||
47 | |||
48 | static int davinci_direction_in(struct gpio_chip *chip, unsigned offset) | ||
49 | { | 77 | { |
50 | struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip); | 78 | struct davinci_gpio_controller *d = chip2controller(chip); |
51 | struct gpio_controller *__iomem g = d->regs; | 79 | struct davinci_gpio_regs __iomem *g = d->regs; |
80 | unsigned long flags; | ||
52 | u32 temp; | 81 | u32 temp; |
82 | u32 mask = 1 << offset; | ||
53 | 83 | ||
54 | spin_lock(&gpio_lock); | 84 | spin_lock_irqsave(&d->lock, flags); |
55 | temp = __raw_readl(&g->dir); | 85 | temp = __raw_readl(&g->dir); |
56 | temp |= (1 << offset); | 86 | if (out) { |
87 | temp &= ~mask; | ||
88 | __raw_writel(mask, value ? &g->set_data : &g->clr_data); | ||
89 | } else { | ||
90 | temp |= mask; | ||
91 | } | ||
57 | __raw_writel(temp, &g->dir); | 92 | __raw_writel(temp, &g->dir); |
58 | spin_unlock(&gpio_lock); | 93 | spin_unlock_irqrestore(&d->lock, flags); |
59 | 94 | ||
60 | return 0; | 95 | return 0; |
61 | } | 96 | } |
62 | 97 | ||
98 | static int davinci_direction_in(struct gpio_chip *chip, unsigned offset) | ||
99 | { | ||
100 | return __davinci_direction(chip, offset, false, 0); | ||
101 | } | ||
102 | |||
103 | static int | ||
104 | davinci_direction_out(struct gpio_chip *chip, unsigned offset, int value) | ||
105 | { | ||
106 | return __davinci_direction(chip, offset, true, value); | ||
107 | } | ||
108 | |||
63 | /* | 109 | /* |
64 | * Read the pin's value (works even if it's set up as output); | 110 | * Read the pin's value (works even if it's set up as output); |
65 | * returns zero/nonzero. | 111 | * returns zero/nonzero. |
@@ -69,37 +115,20 @@ static int davinci_direction_in(struct gpio_chip *chip, unsigned offset) | |||
69 | */ | 115 | */ |
70 | static int davinci_gpio_get(struct gpio_chip *chip, unsigned offset) | 116 | static int davinci_gpio_get(struct gpio_chip *chip, unsigned offset) |
71 | { | 117 | { |
72 | struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip); | 118 | struct davinci_gpio_controller *d = chip2controller(chip); |
73 | struct gpio_controller *__iomem g = d->regs; | 119 | struct davinci_gpio_regs __iomem *g = d->regs; |
74 | 120 | ||
75 | return (1 << offset) & __raw_readl(&g->in_data); | 121 | return (1 << offset) & __raw_readl(&g->in_data); |
76 | } | 122 | } |
77 | 123 | ||
78 | static int | ||
79 | davinci_direction_out(struct gpio_chip *chip, unsigned offset, int value) | ||
80 | { | ||
81 | struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip); | ||
82 | struct gpio_controller *__iomem g = d->regs; | ||
83 | u32 temp; | ||
84 | u32 mask = 1 << offset; | ||
85 | |||
86 | spin_lock(&gpio_lock); | ||
87 | temp = __raw_readl(&g->dir); | ||
88 | temp &= ~mask; | ||
89 | __raw_writel(mask, value ? &g->set_data : &g->clr_data); | ||
90 | __raw_writel(temp, &g->dir); | ||
91 | spin_unlock(&gpio_lock); | ||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | /* | 124 | /* |
96 | * Assuming the pin is muxed as a gpio output, set its output value. | 125 | * Assuming the pin is muxed as a gpio output, set its output value. |
97 | */ | 126 | */ |
98 | static void | 127 | static void |
99 | davinci_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | 128 | davinci_gpio_set(struct gpio_chip *chip, unsigned offset, int value) |
100 | { | 129 | { |
101 | struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip); | 130 | struct davinci_gpio_controller *d = chip2controller(chip); |
102 | struct gpio_controller *__iomem g = d->regs; | 131 | struct davinci_gpio_regs __iomem *g = d->regs; |
103 | 132 | ||
104 | __raw_writel((1 << offset), value ? &g->set_data : &g->clr_data); | 133 | __raw_writel((1 << offset), value ? &g->set_data : &g->clr_data); |
105 | } | 134 | } |
@@ -109,6 +138,10 @@ static int __init davinci_gpio_setup(void) | |||
109 | int i, base; | 138 | int i, base; |
110 | unsigned ngpio; | 139 | unsigned ngpio; |
111 | struct davinci_soc_info *soc_info = &davinci_soc_info; | 140 | struct davinci_soc_info *soc_info = &davinci_soc_info; |
141 | struct davinci_gpio_regs *regs; | ||
142 | |||
143 | if (soc_info->gpio_type != GPIO_TYPE_DAVINCI) | ||
144 | return 0; | ||
112 | 145 | ||
113 | /* | 146 | /* |
114 | * The gpio banks conceptually expose a segmented bitmap, | 147 | * The gpio banks conceptually expose a segmented bitmap, |
@@ -124,6 +157,10 @@ static int __init davinci_gpio_setup(void) | |||
124 | if (WARN_ON(DAVINCI_N_GPIO < ngpio)) | 157 | if (WARN_ON(DAVINCI_N_GPIO < ngpio)) |
125 | ngpio = DAVINCI_N_GPIO; | 158 | ngpio = DAVINCI_N_GPIO; |
126 | 159 | ||
160 | gpio_base = ioremap(soc_info->gpio_base, SZ_4K); | ||
161 | if (WARN_ON(!gpio_base)) | ||
162 | return -ENOMEM; | ||
163 | |||
127 | for (i = 0, base = 0; base < ngpio; i++, base += 32) { | 164 | for (i = 0, base = 0; base < ngpio; i++, base += 32) { |
128 | chips[i].chip.label = "DaVinci"; | 165 | chips[i].chip.label = "DaVinci"; |
129 | 166 | ||
@@ -137,11 +174,20 @@ static int __init davinci_gpio_setup(void) | |||
137 | if (chips[i].chip.ngpio > 32) | 174 | if (chips[i].chip.ngpio > 32) |
138 | chips[i].chip.ngpio = 32; | 175 | chips[i].chip.ngpio = 32; |
139 | 176 | ||
140 | chips[i].regs = gpio2controller(base); | 177 | spin_lock_init(&chips[i].lock); |
178 | |||
179 | regs = gpio2regs(base); | ||
180 | chips[i].regs = regs; | ||
181 | chips[i].set_data = ®s->set_data; | ||
182 | chips[i].clr_data = ®s->clr_data; | ||
183 | chips[i].in_data = ®s->in_data; | ||
141 | 184 | ||
142 | gpiochip_add(&chips[i].chip); | 185 | gpiochip_add(&chips[i].chip); |
143 | } | 186 | } |
144 | 187 | ||
188 | soc_info->gpio_ctlrs = chips; | ||
189 | soc_info->gpio_ctlrs_num = DIV_ROUND_UP(ngpio, 32); | ||
190 | |||
145 | davinci_gpio_irq_setup(); | 191 | davinci_gpio_irq_setup(); |
146 | return 0; | 192 | return 0; |
147 | } | 193 | } |
@@ -161,7 +207,7 @@ pure_initcall(davinci_gpio_setup); | |||
161 | 207 | ||
162 | static void gpio_irq_disable(unsigned irq) | 208 | static void gpio_irq_disable(unsigned irq) |
163 | { | 209 | { |
164 | struct gpio_controller *__iomem g = get_irq_chip_data(irq); | 210 | struct davinci_gpio_regs __iomem *g = irq2regs(irq); |
165 | u32 mask = (u32) get_irq_data(irq); | 211 | u32 mask = (u32) get_irq_data(irq); |
166 | 212 | ||
167 | __raw_writel(mask, &g->clr_falling); | 213 | __raw_writel(mask, &g->clr_falling); |
@@ -170,7 +216,7 @@ static void gpio_irq_disable(unsigned irq) | |||
170 | 216 | ||
171 | static void gpio_irq_enable(unsigned irq) | 217 | static void gpio_irq_enable(unsigned irq) |
172 | { | 218 | { |
173 | struct gpio_controller *__iomem g = get_irq_chip_data(irq); | 219 | struct davinci_gpio_regs __iomem *g = irq2regs(irq); |
174 | u32 mask = (u32) get_irq_data(irq); | 220 | u32 mask = (u32) get_irq_data(irq); |
175 | unsigned status = irq_desc[irq].status; | 221 | unsigned status = irq_desc[irq].status; |
176 | 222 | ||
@@ -186,7 +232,7 @@ static void gpio_irq_enable(unsigned irq) | |||
186 | 232 | ||
187 | static int gpio_irq_type(unsigned irq, unsigned trigger) | 233 | static int gpio_irq_type(unsigned irq, unsigned trigger) |
188 | { | 234 | { |
189 | struct gpio_controller *__iomem g = get_irq_chip_data(irq); | 235 | struct davinci_gpio_regs __iomem *g = irq2regs(irq); |
190 | u32 mask = (u32) get_irq_data(irq); | 236 | u32 mask = (u32) get_irq_data(irq); |
191 | 237 | ||
192 | if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) | 238 | if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) |
@@ -215,7 +261,7 @@ static struct irq_chip gpio_irqchip = { | |||
215 | static void | 261 | static void |
216 | gpio_irq_handler(unsigned irq, struct irq_desc *desc) | 262 | gpio_irq_handler(unsigned irq, struct irq_desc *desc) |
217 | { | 263 | { |
218 | struct gpio_controller *__iomem g = get_irq_chip_data(irq); | 264 | struct davinci_gpio_regs __iomem *g = irq2regs(irq); |
219 | u32 mask = 0xffff; | 265 | u32 mask = 0xffff; |
220 | 266 | ||
221 | /* we only care about one bank */ | 267 | /* we only care about one bank */ |
@@ -253,7 +299,7 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc) | |||
253 | 299 | ||
254 | static int gpio_to_irq_banked(struct gpio_chip *chip, unsigned offset) | 300 | static int gpio_to_irq_banked(struct gpio_chip *chip, unsigned offset) |
255 | { | 301 | { |
256 | struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip); | 302 | struct davinci_gpio_controller *d = chip2controller(chip); |
257 | 303 | ||
258 | if (d->irq_base >= 0) | 304 | if (d->irq_base >= 0) |
259 | return d->irq_base + offset; | 305 | return d->irq_base + offset; |
@@ -276,7 +322,7 @@ static int gpio_to_irq_unbanked(struct gpio_chip *chip, unsigned offset) | |||
276 | 322 | ||
277 | static int gpio_irq_type_unbanked(unsigned irq, unsigned trigger) | 323 | static int gpio_irq_type_unbanked(unsigned irq, unsigned trigger) |
278 | { | 324 | { |
279 | struct gpio_controller *__iomem g = get_irq_chip_data(irq); | 325 | struct davinci_gpio_regs __iomem *g = irq2regs(irq); |
280 | u32 mask = (u32) get_irq_data(irq); | 326 | u32 mask = (u32) get_irq_data(irq); |
281 | 327 | ||
282 | if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) | 328 | if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) |
@@ -305,7 +351,7 @@ static int __init davinci_gpio_irq_setup(void) | |||
305 | u32 binten = 0; | 351 | u32 binten = 0; |
306 | unsigned ngpio, bank_irq; | 352 | unsigned ngpio, bank_irq; |
307 | struct davinci_soc_info *soc_info = &davinci_soc_info; | 353 | struct davinci_soc_info *soc_info = &davinci_soc_info; |
308 | struct gpio_controller *__iomem g; | 354 | struct davinci_gpio_regs __iomem *g; |
309 | 355 | ||
310 | ngpio = soc_info->gpio_num; | 356 | ngpio = soc_info->gpio_num; |
311 | 357 | ||
@@ -354,7 +400,7 @@ static int __init davinci_gpio_irq_setup(void) | |||
354 | gpio_irqchip_unbanked.set_type = gpio_irq_type_unbanked; | 400 | gpio_irqchip_unbanked.set_type = gpio_irq_type_unbanked; |
355 | 401 | ||
356 | /* default trigger: both edges */ | 402 | /* default trigger: both edges */ |
357 | g = gpio2controller(0); | 403 | g = gpio2regs(0); |
358 | __raw_writel(~0, &g->set_falling); | 404 | __raw_writel(~0, &g->set_falling); |
359 | __raw_writel(~0, &g->set_rising); | 405 | __raw_writel(~0, &g->set_rising); |
360 | 406 | ||
@@ -362,7 +408,7 @@ static int __init davinci_gpio_irq_setup(void) | |||
362 | for (gpio = 0; gpio < soc_info->gpio_unbanked; gpio++, irq++) { | 408 | for (gpio = 0; gpio < soc_info->gpio_unbanked; gpio++, irq++) { |
363 | set_irq_chip(irq, &gpio_irqchip_unbanked); | 409 | set_irq_chip(irq, &gpio_irqchip_unbanked); |
364 | set_irq_data(irq, (void *) __gpio_mask(gpio)); | 410 | set_irq_data(irq, (void *) __gpio_mask(gpio)); |
365 | set_irq_chip_data(irq, g); | 411 | set_irq_chip_data(irq, (__force void *) g); |
366 | irq_desc[irq].status |= IRQ_TYPE_EDGE_BOTH; | 412 | irq_desc[irq].status |= IRQ_TYPE_EDGE_BOTH; |
367 | } | 413 | } |
368 | 414 | ||
@@ -379,18 +425,18 @@ static int __init davinci_gpio_irq_setup(void) | |||
379 | unsigned i; | 425 | unsigned i; |
380 | 426 | ||
381 | /* disabled by default, enabled only as needed */ | 427 | /* disabled by default, enabled only as needed */ |
382 | g = gpio2controller(gpio); | 428 | g = gpio2regs(gpio); |
383 | __raw_writel(~0, &g->clr_falling); | 429 | __raw_writel(~0, &g->clr_falling); |
384 | __raw_writel(~0, &g->clr_rising); | 430 | __raw_writel(~0, &g->clr_rising); |
385 | 431 | ||
386 | /* set up all irqs in this bank */ | 432 | /* set up all irqs in this bank */ |
387 | set_irq_chained_handler(bank_irq, gpio_irq_handler); | 433 | set_irq_chained_handler(bank_irq, gpio_irq_handler); |
388 | set_irq_chip_data(bank_irq, g); | 434 | set_irq_chip_data(bank_irq, (__force void *) g); |
389 | set_irq_data(bank_irq, (void *)irq); | 435 | set_irq_data(bank_irq, (void *) irq); |
390 | 436 | ||
391 | for (i = 0; i < 16 && gpio < ngpio; i++, irq++, gpio++) { | 437 | for (i = 0; i < 16 && gpio < ngpio; i++, irq++, gpio++) { |
392 | set_irq_chip(irq, &gpio_irqchip); | 438 | set_irq_chip(irq, &gpio_irqchip); |
393 | set_irq_chip_data(irq, g); | 439 | set_irq_chip_data(irq, (__force void *) g); |
394 | set_irq_data(irq, (void *) __gpio_mask(gpio)); | 440 | set_irq_data(irq, (void *) __gpio_mask(gpio)); |
395 | set_irq_handler(irq, handle_simple_irq); | 441 | set_irq_handler(irq, handle_simple_irq); |
396 | set_irq_flags(irq, IRQF_VALID); | 442 | set_irq_flags(irq, IRQF_VALID); |
@@ -403,7 +449,7 @@ done: | |||
403 | /* BINTEN -- per-bank interrupt enable. genirq would also let these | 449 | /* BINTEN -- per-bank interrupt enable. genirq would also let these |
404 | * bits be set/cleared dynamically. | 450 | * bits be set/cleared dynamically. |
405 | */ | 451 | */ |
406 | __raw_writel(binten, soc_info->gpio_base + 0x08); | 452 | __raw_writel(binten, gpio_base + 0x08); |
407 | 453 | ||
408 | printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0)); | 454 | printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0)); |
409 | 455 | ||