aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-davinci/dm365.c3
-rw-r--r--arch/arm/mach-davinci/gpio.c105
-rw-r--r--arch/arm/mach-davinci/include/mach/common.h1
-rw-r--r--arch/arm/mach-davinci/include/mach/gpio.h8
4 files changed, 105 insertions, 12 deletions
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
index e5873bc0a0fa..f02bce8eeba4 100644
--- a/arch/arm/mach-davinci/dm365.c
+++ b/arch/arm/mach-davinci/dm365.c
@@ -882,7 +882,8 @@ static struct davinci_soc_info davinci_soc_info_dm365 = {
882 .timer_info = &dm365_timer_info, 882 .timer_info = &dm365_timer_info,
883 .gpio_base = IO_ADDRESS(DAVINCI_GPIO_BASE), 883 .gpio_base = IO_ADDRESS(DAVINCI_GPIO_BASE),
884 .gpio_num = 104, 884 .gpio_num = 104,
885 .gpio_irq = 44, 885 .gpio_irq = IRQ_DM365_GPIO0,
886 .gpio_unbanked = 8, /* really 16 ... skip muxed GPIOs */
886 .serial_dev = &dm365_serial_device, 887 .serial_dev = &dm365_serial_device,
887 .emac_pdata = &dm365_emac_pdata, 888 .emac_pdata = &dm365_emac_pdata,
888 .sram_dma = 0x00010000, 889 .sram_dma = 0x00010000,
diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c
index 1b6532159c58..f6ea9db11f41 100644
--- a/arch/arm/mach-davinci/gpio.c
+++ b/arch/arm/mach-davinci/gpio.c
@@ -34,6 +34,7 @@ static DEFINE_SPINLOCK(gpio_lock);
34struct davinci_gpio { 34struct davinci_gpio {
35 struct gpio_chip chip; 35 struct gpio_chip chip;
36 struct gpio_controller *__iomem regs; 36 struct gpio_controller *__iomem regs;
37 int irq_base;
37}; 38};
38 39
39static struct davinci_gpio chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)]; 40static struct davinci_gpio chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)];
@@ -161,8 +162,7 @@ pure_initcall(davinci_gpio_setup);
161 * used as output pins ... which is convenient for testing. 162 * used as output pins ... which is convenient for testing.
162 * 163 *
163 * NOTE: The first few GPIOs also have direct INTC hookups in addition 164 * NOTE: The first few GPIOs also have direct INTC hookups in addition
164 * to their GPIOBNK0 irq, with a bit less overhead but less flexibility 165 * to their GPIOBNK0 irq, with a bit less overhead.
165 * on triggering (e.g. no edge options). We don't try to use those.
166 * 166 *
167 * All those INTC hookups (direct, plus several IRQ banks) can also 167 * All those INTC hookups (direct, plus several IRQ banks) can also
168 * serve as EDMA event triggers. 168 * serve as EDMA event triggers.
@@ -171,7 +171,7 @@ pure_initcall(davinci_gpio_setup);
171static void gpio_irq_disable(unsigned irq) 171static void gpio_irq_disable(unsigned irq)
172{ 172{
173 struct gpio_controller *__iomem g = get_irq_chip_data(irq); 173 struct gpio_controller *__iomem g = get_irq_chip_data(irq);
174 u32 mask = __gpio_mask(irq_to_gpio(irq)); 174 u32 mask = (u32) get_irq_data(irq);
175 175
176 __raw_writel(mask, &g->clr_falling); 176 __raw_writel(mask, &g->clr_falling);
177 __raw_writel(mask, &g->clr_rising); 177 __raw_writel(mask, &g->clr_rising);
@@ -180,7 +180,7 @@ static void gpio_irq_disable(unsigned irq)
180static void gpio_irq_enable(unsigned irq) 180static void gpio_irq_enable(unsigned irq)
181{ 181{
182 struct gpio_controller *__iomem g = get_irq_chip_data(irq); 182 struct gpio_controller *__iomem g = get_irq_chip_data(irq);
183 u32 mask = __gpio_mask(irq_to_gpio(irq)); 183 u32 mask = (u32) get_irq_data(irq);
184 unsigned status = irq_desc[irq].status; 184 unsigned status = irq_desc[irq].status;
185 185
186 status &= IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING; 186 status &= IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING;
@@ -196,7 +196,7 @@ static void gpio_irq_enable(unsigned irq)
196static int gpio_irq_type(unsigned irq, unsigned trigger) 196static int gpio_irq_type(unsigned irq, unsigned trigger)
197{ 197{
198 struct gpio_controller *__iomem g = get_irq_chip_data(irq); 198 struct gpio_controller *__iomem g = get_irq_chip_data(irq);
199 u32 mask = __gpio_mask(irq_to_gpio(irq)); 199 u32 mask = (u32) get_irq_data(irq);
200 200
201 if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) 201 if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
202 return -EINVAL; 202 return -EINVAL;
@@ -260,6 +260,45 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
260 /* now it may re-trigger */ 260 /* now it may re-trigger */
261} 261}
262 262
263static int gpio_to_irq_banked(struct gpio_chip *chip, unsigned offset)
264{
265 struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip);
266
267 if (d->irq_base >= 0)
268 return d->irq_base + offset;
269 else
270 return -ENODEV;
271}
272
273static int gpio_to_irq_unbanked(struct gpio_chip *chip, unsigned offset)
274{
275 struct davinci_soc_info *soc_info = &davinci_soc_info;
276
277 /* NOTE: we assume for now that only irqs in the first gpio_chip
278 * can provide direct-mapped IRQs to AINTC (up to 32 GPIOs).
279 */
280 if (offset < soc_info->gpio_unbanked)
281 return soc_info->gpio_irq + offset;
282 else
283 return -ENODEV;
284}
285
286static int gpio_irq_type_unbanked(unsigned irq, unsigned trigger)
287{
288 struct gpio_controller *__iomem g = get_irq_chip_data(irq);
289 u32 mask = (u32) get_irq_data(irq);
290
291 if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
292 return -EINVAL;
293
294 __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_FALLING)
295 ? &g->set_falling : &g->clr_falling);
296 __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_RISING)
297 ? &g->set_rising : &g->clr_rising);
298
299 return 0;
300}
301
263/* 302/*
264 * NOTE: for suspend/resume, probably best to make a platform_device with 303 * NOTE: for suspend/resume, probably best to make a platform_device with
265 * suspend_late/resume_resume calls hooking into results of the set_wake() 304 * suspend_late/resume_resume calls hooking into results of the set_wake()
@@ -275,6 +314,7 @@ static int __init davinci_gpio_irq_setup(void)
275 u32 binten = 0; 314 u32 binten = 0;
276 unsigned ngpio, bank_irq; 315 unsigned ngpio, bank_irq;
277 struct davinci_soc_info *soc_info = &davinci_soc_info; 316 struct davinci_soc_info *soc_info = &davinci_soc_info;
317 struct gpio_controller *__iomem g;
278 318
279 ngpio = soc_info->gpio_num; 319 ngpio = soc_info->gpio_num;
280 320
@@ -292,12 +332,63 @@ static int __init davinci_gpio_irq_setup(void)
292 } 332 }
293 clk_enable(clk); 333 clk_enable(clk);
294 334
335 /* Arrange gpio_to_irq() support, handling either direct IRQs or
336 * banked IRQs. Having GPIOs in the first GPIO bank use direct
337 * IRQs, while the others use banked IRQs, would need some setup
338 * tweaks to recognize hardware which can do that.
339 */
340 for (gpio = 0, bank = 0; gpio < ngpio; bank++, gpio += 32) {
341 chips[bank].chip.to_irq = gpio_to_irq_banked;
342 chips[bank].irq_base = soc_info->gpio_unbanked
343 ? -EINVAL
344 : (soc_info->intc_irq_num + gpio);
345 }
346
347 /*
348 * AINTC can handle direct/unbanked IRQs for GPIOs, with the GPIO
349 * controller only handling trigger modes. We currently assume no
350 * IRQ mux conflicts; gpio_irq_type_unbanked() is only for GPIOs.
351 */
352 if (soc_info->gpio_unbanked) {
353 static struct irq_chip gpio_irqchip_unbanked;
354
355 /* pass "bank 0" GPIO IRQs to AINTC */
356 chips[0].chip.to_irq = gpio_to_irq_unbanked;
357 binten = BIT(0);
358
359 /* AINTC handles mask/unmask; GPIO handles triggering */
360 irq = bank_irq;
361 gpio_irqchip_unbanked = *get_irq_desc_chip(irq_to_desc(irq));
362 gpio_irqchip_unbanked.name = "GPIO-AINTC";
363 gpio_irqchip_unbanked.set_type = gpio_irq_type_unbanked;
364
365 /* default trigger: both edges */
366 g = gpio2controller(0);
367 __raw_writel(~0, &g->set_falling);
368 __raw_writel(~0, &g->set_rising);
369
370 /* set the direct IRQs up to use that irqchip */
371 for (gpio = 0; gpio < soc_info->gpio_unbanked; gpio++, irq++) {
372 set_irq_chip(irq, &gpio_irqchip_unbanked);
373 set_irq_data(irq, (void *) __gpio_mask(gpio));
374 set_irq_chip_data(irq, g);
375 irq_desc[irq].status |= IRQ_TYPE_EDGE_BOTH;
376 }
377
378 goto done;
379 }
380
381 /*
382 * Or, AINTC can handle IRQs for banks of 16 GPIO IRQs, which we
383 * then chain through our own handler.
384 */
295 for (gpio = 0, irq = gpio_to_irq(0), bank = 0; 385 for (gpio = 0, irq = gpio_to_irq(0), bank = 0;
296 gpio < ngpio; 386 gpio < ngpio;
297 bank++, bank_irq++) { 387 bank++, bank_irq++) {
298 struct gpio_controller *__iomem g = gpio2controller(gpio);
299 unsigned i; 388 unsigned i;
300 389
390 /* disabled by default, enabled only as needed */
391 g = gpio2controller(gpio);
301 __raw_writel(~0, &g->clr_falling); 392 __raw_writel(~0, &g->clr_falling);
302 __raw_writel(~0, &g->clr_rising); 393 __raw_writel(~0, &g->clr_rising);
303 394
@@ -309,6 +400,7 @@ static int __init davinci_gpio_irq_setup(void)
309 for (i = 0; i < 16 && gpio < ngpio; i++, irq++, gpio++) { 400 for (i = 0; i < 16 && gpio < ngpio; i++, irq++, gpio++) {
310 set_irq_chip(irq, &gpio_irqchip); 401 set_irq_chip(irq, &gpio_irqchip);
311 set_irq_chip_data(irq, g); 402 set_irq_chip_data(irq, g);
403 set_irq_data(irq, (void *) __gpio_mask(gpio));
312 set_irq_handler(irq, handle_simple_irq); 404 set_irq_handler(irq, handle_simple_irq);
313 set_irq_flags(irq, IRQF_VALID); 405 set_irq_flags(irq, IRQF_VALID);
314 } 406 }
@@ -316,6 +408,7 @@ static int __init davinci_gpio_irq_setup(void)
316 binten |= BIT(bank); 408 binten |= BIT(bank);
317 } 409 }
318 410
411done:
319 /* BINTEN -- per-bank interrupt enable. genirq would also let these 412 /* BINTEN -- per-bank interrupt enable. genirq would also let these
320 * bits be set/cleared dynamically. 413 * bits be set/cleared dynamically.
321 */ 414 */
diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h
index b21393b24d65..1fd3917cae4e 100644
--- a/arch/arm/mach-davinci/include/mach/common.h
+++ b/arch/arm/mach-davinci/include/mach/common.h
@@ -63,6 +63,7 @@ struct davinci_soc_info {
63 void __iomem *gpio_base; 63 void __iomem *gpio_base;
64 unsigned gpio_num; 64 unsigned gpio_num;
65 unsigned gpio_irq; 65 unsigned gpio_irq;
66 unsigned gpio_unbanked;
66 struct platform_device *serial_dev; 67 struct platform_device *serial_dev;
67 struct emac_platform_data *emac_pdata; 68 struct emac_platform_data *emac_pdata;
68 dma_addr_t sram_dma; 69 dma_addr_t sram_dma;
diff --git a/arch/arm/mach-davinci/include/mach/gpio.h b/arch/arm/mach-davinci/include/mach/gpio.h
index ae0745568316..ebcc29babeae 100644
--- a/arch/arm/mach-davinci/include/mach/gpio.h
+++ b/arch/arm/mach-davinci/include/mach/gpio.h
@@ -142,15 +142,13 @@ static inline int gpio_cansleep(unsigned gpio)
142 142
143static inline int gpio_to_irq(unsigned gpio) 143static inline int gpio_to_irq(unsigned gpio)
144{ 144{
145 if (gpio >= DAVINCI_N_GPIO) 145 return __gpio_to_irq(gpio);
146 return -EINVAL;
147 return davinci_soc_info.intc_irq_num + gpio;
148} 146}
149 147
150static inline int irq_to_gpio(unsigned irq) 148static inline int irq_to_gpio(unsigned irq)
151{ 149{
152 /* caller guarantees gpio_to_irq() succeeded */ 150 /* don't support the reverse mapping */
153 return irq - davinci_soc_info.intc_irq_num; 151 return -ENOSYS;
154} 152}
155 153
156#endif /* __DAVINCI_GPIO_H */ 154#endif /* __DAVINCI_GPIO_H */