aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-davinci/gpio.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-06-14 16:42:43 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-14 16:42:43 -0400
commit2cf4d4514d5b43c1f3b64bd0ec8b9853bde8f1dc (patch)
treee35a625496acc6ac852846d40b8851186b9d1ac4 /arch/arm/mach-davinci/gpio.c
parent44b7532b8b464f606053562400719c9c21276037 (diff)
parentce53895a5d24e0ee19fb92f56c17323fb4c9ab27 (diff)
Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm: (417 commits) MAINTAINERS: EB110ATX is not ebsa110 MAINTAINERS: update Eric Miao's email address and status fb: add support of LCD display controller on pxa168/910 (base layer) [ARM] 5552/1: ep93xx get_uart_rate(): use EP93XX_SYSCON_PWRCNT and EP93XX_SYSCON_PWRCN [ARM] pxa/sharpsl_pm: zaurus needs generic pxa suspend/resume routines [ARM] 5544/1: Trust PrimeCell resource sizes [ARM] pxa/sharpsl_pm: cleanup of gpio-related code. [ARM] pxa/sharpsl_pm: drop set_irq_type calls [ARM] pxa/sharpsl_pm: merge pxa-specific code into generic one [ARM] pxa/sharpsl_pm: merge the two sharpsl_pm.c since it's now pxa specific [ARM] sa1100: remove unused collie_pm.c [ARM] pxa: fix the conflicting non-static declarations of global_gpios[] [ARM] 5550/1: Add default configure file for w90p910 platform [ARM] 5549/1: Add clock api for w90p910 platform. [ARM] 5548/1: Add gpio api for w90p910 platform [ARM] 5551/1: Add multi-function pin api for w90p910 platform. [ARM] Make ARM_VIC_NR depend on ARM_VIC [ARM] 5546/1: ARM PL022 SSP/SPI driver v3 ARM: OMAP4: SMP: Update defconfig for OMAP4430 ARM: OMAP4: SMP: Enable SMP support for OMAP4430 ...
Diffstat (limited to 'arch/arm/mach-davinci/gpio.c')
-rw-r--r--arch/arm/mach-davinci/gpio.c63
1 files changed, 31 insertions, 32 deletions
diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c
index 1aba41c6351e..1b6532159c58 100644
--- a/arch/arm/mach-davinci/gpio.c
+++ b/arch/arm/mach-davinci/gpio.c
@@ -23,6 +23,7 @@
23#include <mach/cputype.h> 23#include <mach/cputype.h>
24#include <mach/irqs.h> 24#include <mach/irqs.h>
25#include <mach/hardware.h> 25#include <mach/hardware.h>
26#include <mach/common.h>
26#include <mach/gpio.h> 27#include <mach/gpio.h>
27 28
28#include <asm/mach/irq.h> 29#include <asm/mach/irq.h>
@@ -37,14 +38,13 @@ struct davinci_gpio {
37 38
38static struct davinci_gpio chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)]; 39static struct davinci_gpio chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)];
39 40
40static unsigned __initdata ngpio;
41
42/* create a non-inlined version */ 41/* create a non-inlined version */
43static struct gpio_controller __iomem * __init gpio2controller(unsigned gpio) 42static struct gpio_controller __iomem * __init gpio2controller(unsigned gpio)
44{ 43{
45 return __gpio_to_controller(gpio); 44 return __gpio_to_controller(gpio);
46} 45}
47 46
47static int __init davinci_gpio_irq_setup(void);
48 48
49/*--------------------------------------------------------------------------*/ 49/*--------------------------------------------------------------------------*/
50 50
@@ -115,23 +115,16 @@ davinci_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
115static int __init davinci_gpio_setup(void) 115static int __init davinci_gpio_setup(void)
116{ 116{
117 int i, base; 117 int i, base;
118 unsigned ngpio;
119 struct davinci_soc_info *soc_info = &davinci_soc_info;
118 120
119 /* The gpio banks conceptually expose a segmented bitmap, 121 /*
122 * The gpio banks conceptually expose a segmented bitmap,
120 * and "ngpio" is one more than the largest zero-based 123 * and "ngpio" is one more than the largest zero-based
121 * bit index that's valid. 124 * bit index that's valid.
122 */ 125 */
123 if (cpu_is_davinci_dm355()) { /* or dm335() */ 126 ngpio = soc_info->gpio_num;
124 ngpio = 104; 127 if (ngpio == 0) {
125 } else if (cpu_is_davinci_dm644x()) { /* or dm337() */
126 ngpio = 71;
127 } else if (cpu_is_davinci_dm646x()) {
128 /* NOTE: each bank has several "reserved" bits,
129 * unusable as GPIOs. Only 33 of the GPIO numbers
130 * are usable, and we're not rejecting the others.
131 */
132 ngpio = 43;
133 } else {
134 /* if cpu_is_davinci_dm643x() ngpio = 111 */
135 pr_err("GPIO setup: how many GPIOs?\n"); 128 pr_err("GPIO setup: how many GPIOs?\n");
136 return -EINVAL; 129 return -EINVAL;
137 } 130 }
@@ -157,6 +150,7 @@ static int __init davinci_gpio_setup(void)
157 gpiochip_add(&chips[i].chip); 150 gpiochip_add(&chips[i].chip);
158 } 151 }
159 152
153 davinci_gpio_irq_setup();
160 return 0; 154 return 0;
161} 155}
162pure_initcall(davinci_gpio_setup); 156pure_initcall(davinci_gpio_setup);
@@ -187,10 +181,15 @@ static void gpio_irq_enable(unsigned irq)
187{ 181{
188 struct gpio_controller *__iomem g = get_irq_chip_data(irq); 182 struct gpio_controller *__iomem g = get_irq_chip_data(irq);
189 u32 mask = __gpio_mask(irq_to_gpio(irq)); 183 u32 mask = __gpio_mask(irq_to_gpio(irq));
184 unsigned status = irq_desc[irq].status;
185
186 status &= IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING;
187 if (!status)
188 status = IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING;
190 189
191 if (irq_desc[irq].status & IRQ_TYPE_EDGE_FALLING) 190 if (status & IRQ_TYPE_EDGE_FALLING)
192 __raw_writel(mask, &g->set_falling); 191 __raw_writel(mask, &g->set_falling);
193 if (irq_desc[irq].status & IRQ_TYPE_EDGE_RISING) 192 if (status & IRQ_TYPE_EDGE_RISING)
194 __raw_writel(mask, &g->set_rising); 193 __raw_writel(mask, &g->set_rising);
195} 194}
196 195
@@ -205,10 +204,13 @@ static int gpio_irq_type(unsigned irq, unsigned trigger)
205 irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK; 204 irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK;
206 irq_desc[irq].status |= trigger; 205 irq_desc[irq].status |= trigger;
207 206
208 __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_FALLING) 207 /* don't enable the IRQ if it's currently disabled */
209 ? &g->set_falling : &g->clr_falling); 208 if (irq_desc[irq].depth == 0) {
210 __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_RISING) 209 __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_FALLING)
211 ? &g->set_rising : &g->clr_rising); 210 ? &g->set_falling : &g->clr_falling);
211 __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_RISING)
212 ? &g->set_rising : &g->clr_rising);
213 }
212 return 0; 214 return 0;
213} 215}
214 216
@@ -230,6 +232,7 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
230 mask <<= 16; 232 mask <<= 16;
231 233
232 /* temporarily mask (level sensitive) parent IRQ */ 234 /* temporarily mask (level sensitive) parent IRQ */
235 desc->chip->mask(irq);
233 desc->chip->ack(irq); 236 desc->chip->ack(irq);
234 while (1) { 237 while (1) {
235 u32 status; 238 u32 status;
@@ -268,17 +271,15 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
268static int __init davinci_gpio_irq_setup(void) 271static int __init davinci_gpio_irq_setup(void)
269{ 272{
270 unsigned gpio, irq, bank; 273 unsigned gpio, irq, bank;
271 unsigned bank_irq;
272 struct clk *clk; 274 struct clk *clk;
273 u32 binten = 0; 275 u32 binten = 0;
276 unsigned ngpio, bank_irq;
277 struct davinci_soc_info *soc_info = &davinci_soc_info;
278
279 ngpio = soc_info->gpio_num;
274 280
275 if (cpu_is_davinci_dm355()) { /* or dm335() */ 281 bank_irq = soc_info->gpio_irq;
276 bank_irq = IRQ_DM355_GPIOBNK0; 282 if (bank_irq == 0) {
277 } else if (cpu_is_davinci_dm644x()) {
278 bank_irq = IRQ_GPIOBNK0;
279 } else if (cpu_is_davinci_dm646x()) {
280 bank_irq = IRQ_DM646X_GPIOBNK0;
281 } else {
282 printk(KERN_ERR "Don't know first GPIO bank IRQ.\n"); 283 printk(KERN_ERR "Don't know first GPIO bank IRQ.\n");
283 return -EINVAL; 284 return -EINVAL;
284 } 285 }
@@ -318,11 +319,9 @@ static int __init davinci_gpio_irq_setup(void)
318 /* BINTEN -- per-bank interrupt enable. genirq would also let these 319 /* BINTEN -- per-bank interrupt enable. genirq would also let these
319 * bits be set/cleared dynamically. 320 * bits be set/cleared dynamically.
320 */ 321 */
321 __raw_writel(binten, (void *__iomem) 322 __raw_writel(binten, soc_info->gpio_base + 0x08);
322 IO_ADDRESS(DAVINCI_GPIO_BASE + 0x08));
323 323
324 printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0)); 324 printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0));
325 325
326 return 0; 326 return 0;
327} 327}
328arch_initcall(davinci_gpio_irq_setup);