aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-davinci
diff options
context:
space:
mode:
authorMark A. Greer <mgreer@mvista.com>2009-04-15 15:40:35 -0400
committerKevin Hilman <khilman@deeprootsystems.com>2009-05-28 18:16:30 -0400
commita994955cc091a8a51b7d7412174d9cf6de04d26b (patch)
tree14c62610ee3ec0aa59fa5df49d4bf5ac88c8eb4c /arch/arm/mach-davinci
parent951d6f6d703110790256abfce03ced117d2dcc6b (diff)
davinci: Make GPIO code more generic
The current gpio code needs to know the number of gpio irqs there are and what the bank irq number is. To determine those values, it checks the SoC type. It also assumes that the base address and the number of irqs the interrupt controller uses is fixed. To clean up the SoC checks and make it support different base addresses and interrupt controllers, have the SoC-specific code set those values in the soc_info structure and have the gpio code reference them there. Signed-off-by: Mark A. Greer <mgreer@mvista.com> Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
Diffstat (limited to 'arch/arm/mach-davinci')
-rw-r--r--arch/arm/mach-davinci/dm355.c4
-rw-r--r--arch/arm/mach-davinci/dm644x.c4
-rw-r--r--arch/arm/mach-davinci/dm646x.c4
-rw-r--r--arch/arm/mach-davinci/gpio.c39
-rw-r--r--arch/arm/mach-davinci/include/mach/common.h3
-rw-r--r--arch/arm/mach-davinci/include/mach/gpio.h14
6 files changed, 37 insertions, 31 deletions
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index 1b7c16cd2672..757def752010 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -13,6 +13,7 @@
13#include <linux/clk.h> 13#include <linux/clk.h>
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/dma-mapping.h> 15#include <linux/dma-mapping.h>
16#include <linux/gpio.h>
16 17
17#include <linux/spi/spi.h> 18#include <linux/spi/spi.h>
18 19
@@ -647,6 +648,9 @@ static struct davinci_soc_info davinci_soc_info_dm355 = {
647 .intc_irq_num = DAVINCI_N_AINTC_IRQ, 648 .intc_irq_num = DAVINCI_N_AINTC_IRQ,
648 .timer_info = &dm355_timer_info, 649 .timer_info = &dm355_timer_info,
649 .wdt_base = IO_ADDRESS(DAVINCI_WDOG_BASE), 650 .wdt_base = IO_ADDRESS(DAVINCI_WDOG_BASE),
651 .gpio_base = IO_ADDRESS(DAVINCI_GPIO_BASE),
652 .gpio_num = 104,
653 .gpio_irq = IRQ_DM355_GPIOBNK0,
650}; 654};
651 655
652void __init dm355_init(void) 656void __init dm355_init(void)
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index c66269264cca..cfd918e41e2d 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -12,6 +12,7 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/clk.h> 13#include <linux/clk.h>
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/gpio.h>
15 16
16#include <asm/mach/map.h> 17#include <asm/mach/map.h>
17 18
@@ -590,6 +591,9 @@ static struct davinci_soc_info davinci_soc_info_dm644x = {
590 .intc_irq_num = DAVINCI_N_AINTC_IRQ, 591 .intc_irq_num = DAVINCI_N_AINTC_IRQ,
591 .timer_info = &dm644x_timer_info, 592 .timer_info = &dm644x_timer_info,
592 .wdt_base = IO_ADDRESS(DAVINCI_WDOG_BASE), 593 .wdt_base = IO_ADDRESS(DAVINCI_WDOG_BASE),
594 .gpio_base = IO_ADDRESS(DAVINCI_GPIO_BASE),
595 .gpio_num = 71,
596 .gpio_irq = IRQ_GPIOBNK0,
593}; 597};
594 598
595void __init dm644x_init(void) 599void __init dm644x_init(void)
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index 83d67cf6935f..f980c2f95de4 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -12,6 +12,7 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/clk.h> 13#include <linux/clk.h>
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/gpio.h>
15 16
16#include <asm/mach/map.h> 17#include <asm/mach/map.h>
17 18
@@ -569,6 +570,9 @@ static struct davinci_soc_info davinci_soc_info_dm646x = {
569 .intc_irq_num = DAVINCI_N_AINTC_IRQ, 570 .intc_irq_num = DAVINCI_N_AINTC_IRQ,
570 .timer_info = &dm646x_timer_info, 571 .timer_info = &dm646x_timer_info,
571 .wdt_base = IO_ADDRESS(DAVINCI_WDOG_BASE), 572 .wdt_base = IO_ADDRESS(DAVINCI_WDOG_BASE),
573 .gpio_base = IO_ADDRESS(DAVINCI_GPIO_BASE),
574 .gpio_num = 43, /* Only 33 usable */
575 .gpio_irq = IRQ_DM646X_GPIOBNK0,
572}; 576};
573 577
574void __init dm646x_init(void) 578void __init dm646x_init(void)
diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c
index 40327b557d79..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,8 +38,6 @@ 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{
@@ -116,23 +115,16 @@ davinci_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
116static int __init davinci_gpio_setup(void) 115static int __init davinci_gpio_setup(void)
117{ 116{
118 int i, base; 117 int i, base;
118 unsigned ngpio;
119 struct davinci_soc_info *soc_info = &davinci_soc_info;
119 120
120 /* The gpio banks conceptually expose a segmented bitmap, 121 /*
122 * The gpio banks conceptually expose a segmented bitmap,
121 * and "ngpio" is one more than the largest zero-based 123 * and "ngpio" is one more than the largest zero-based
122 * bit index that's valid. 124 * bit index that's valid.
123 */ 125 */
124 if (cpu_is_davinci_dm355()) { /* or dm335() */ 126 ngpio = soc_info->gpio_num;
125 ngpio = 104; 127 if (ngpio == 0) {
126 } else if (cpu_is_davinci_dm644x()) { /* or dm337() */
127 ngpio = 71;
128 } else if (cpu_is_davinci_dm646x()) {
129 /* NOTE: each bank has several "reserved" bits,
130 * unusable as GPIOs. Only 33 of the GPIO numbers
131 * are usable, and we're not rejecting the others.
132 */
133 ngpio = 43;
134 } else {
135 /* if cpu_is_davinci_dm643x() ngpio = 111 */
136 pr_err("GPIO setup: how many GPIOs?\n"); 128 pr_err("GPIO setup: how many GPIOs?\n");
137 return -EINVAL; 129 return -EINVAL;
138 } 130 }
@@ -279,17 +271,15 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
279static int __init davinci_gpio_irq_setup(void) 271static int __init davinci_gpio_irq_setup(void)
280{ 272{
281 unsigned gpio, irq, bank; 273 unsigned gpio, irq, bank;
282 unsigned bank_irq;
283 struct clk *clk; 274 struct clk *clk;
284 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;
285 280
286 if (cpu_is_davinci_dm355()) { /* or dm335() */ 281 bank_irq = soc_info->gpio_irq;
287 bank_irq = IRQ_DM355_GPIOBNK0; 282 if (bank_irq == 0) {
288 } else if (cpu_is_davinci_dm644x()) {
289 bank_irq = IRQ_GPIOBNK0;
290 } else if (cpu_is_davinci_dm646x()) {
291 bank_irq = IRQ_DM646X_GPIOBNK0;
292 } else {
293 printk(KERN_ERR "Don't know first GPIO bank IRQ.\n"); 283 printk(KERN_ERR "Don't know first GPIO bank IRQ.\n");
294 return -EINVAL; 284 return -EINVAL;
295 } 285 }
@@ -329,8 +319,7 @@ static int __init davinci_gpio_irq_setup(void)
329 /* BINTEN -- per-bank interrupt enable. genirq would also let these 319 /* BINTEN -- per-bank interrupt enable. genirq would also let these
330 * bits be set/cleared dynamically. 320 * bits be set/cleared dynamically.
331 */ 321 */
332 __raw_writel(binten, (void *__iomem) 322 __raw_writel(binten, soc_info->gpio_base + 0x08);
333 IO_ADDRESS(DAVINCI_GPIO_BASE + 0x08));
334 323
335 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));
336 325
diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h
index d63703826a60..06ff6d6e3678 100644
--- a/arch/arm/mach-davinci/include/mach/common.h
+++ b/arch/arm/mach-davinci/include/mach/common.h
@@ -58,6 +58,9 @@ struct davinci_soc_info {
58 unsigned long intc_irq_num; 58 unsigned long intc_irq_num;
59 struct davinci_timer_info *timer_info; 59 struct davinci_timer_info *timer_info;
60 void __iomem *wdt_base; 60 void __iomem *wdt_base;
61 void __iomem *gpio_base;
62 unsigned gpio_num;
63 unsigned gpio_irq;
61}; 64};
62 65
63extern struct davinci_soc_info davinci_soc_info; 66extern struct davinci_soc_info davinci_soc_info;
diff --git a/arch/arm/mach-davinci/include/mach/gpio.h b/arch/arm/mach-davinci/include/mach/gpio.h
index efe3281364e6..ae0745568316 100644
--- a/arch/arm/mach-davinci/include/mach/gpio.h
+++ b/arch/arm/mach-davinci/include/mach/gpio.h
@@ -17,6 +17,7 @@
17#include <asm-generic/gpio.h> 17#include <asm-generic/gpio.h>
18 18
19#include <mach/irqs.h> 19#include <mach/irqs.h>
20#include <mach/common.h>
20 21
21#define DAVINCI_GPIO_BASE 0x01C67000 22#define DAVINCI_GPIO_BASE 0x01C67000
22 23
@@ -67,15 +68,16 @@ static inline struct gpio_controller *__iomem
67__gpio_to_controller(unsigned gpio) 68__gpio_to_controller(unsigned gpio)
68{ 69{
69 void *__iomem ptr; 70 void *__iomem ptr;
71 void __iomem *base = davinci_soc_info.gpio_base;
70 72
71 if (gpio < 32 * 1) 73 if (gpio < 32 * 1)
72 ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x10); 74 ptr = base + 0x10;
73 else if (gpio < 32 * 2) 75 else if (gpio < 32 * 2)
74 ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x38); 76 ptr = base + 0x38;
75 else if (gpio < 32 * 3) 77 else if (gpio < 32 * 3)
76 ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x60); 78 ptr = base + 0x60;
77 else if (gpio < 32 * 4) 79 else if (gpio < 32 * 4)
78 ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x88); 80 ptr = base + 0x88;
79 else 81 else
80 ptr = NULL; 82 ptr = NULL;
81 return ptr; 83 return ptr;
@@ -142,13 +144,13 @@ static inline int gpio_to_irq(unsigned gpio)
142{ 144{
143 if (gpio >= DAVINCI_N_GPIO) 145 if (gpio >= DAVINCI_N_GPIO)
144 return -EINVAL; 146 return -EINVAL;
145 return DAVINCI_N_AINTC_IRQ + gpio; 147 return davinci_soc_info.intc_irq_num + gpio;
146} 148}
147 149
148static inline int irq_to_gpio(unsigned irq) 150static inline int irq_to_gpio(unsigned irq)
149{ 151{
150 /* caller guarantees gpio_to_irq() succeeded */ 152 /* caller guarantees gpio_to_irq() succeeded */
151 return irq - DAVINCI_N_AINTC_IRQ; 153 return irq - davinci_soc_info.intc_irq_num;
152} 154}
153 155
154#endif /* __DAVINCI_GPIO_H */ 156#endif /* __DAVINCI_GPIO_H */