diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-14 16:42:43 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-14 16:42:43 -0400 |
commit | 2cf4d4514d5b43c1f3b64bd0ec8b9853bde8f1dc (patch) | |
tree | e35a625496acc6ac852846d40b8851186b9d1ac4 /arch/arm/mach-davinci/gpio.c | |
parent | 44b7532b8b464f606053562400719c9c21276037 (diff) | |
parent | ce53895a5d24e0ee19fb92f56c17323fb4c9ab27 (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.c | 63 |
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 | ||
38 | static struct davinci_gpio chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)]; | 39 | static struct davinci_gpio chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)]; |
39 | 40 | ||
40 | static unsigned __initdata ngpio; | ||
41 | |||
42 | /* create a non-inlined version */ | 41 | /* create a non-inlined version */ |
43 | static struct gpio_controller __iomem * __init gpio2controller(unsigned gpio) | 42 | static 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 | ||
47 | static 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) | |||
115 | static int __init davinci_gpio_setup(void) | 115 | static 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 | } |
162 | pure_initcall(davinci_gpio_setup); | 156 | pure_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) | |||
268 | static int __init davinci_gpio_irq_setup(void) | 271 | static 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 | } |
328 | arch_initcall(davinci_gpio_irq_setup); | ||