diff options
author | Mark A. Greer <mgreer@mvista.com> | 2009-04-15 15:40:35 -0400 |
---|---|---|
committer | Kevin Hilman <khilman@deeprootsystems.com> | 2009-05-28 18:16:30 -0400 |
commit | a994955cc091a8a51b7d7412174d9cf6de04d26b (patch) | |
tree | 14c62610ee3ec0aa59fa5df49d4bf5ac88c8eb4c /arch | |
parent | 951d6f6d703110790256abfce03ced117d2dcc6b (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')
-rw-r--r-- | arch/arm/mach-davinci/dm355.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-davinci/dm644x.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-davinci/dm646x.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-davinci/gpio.c | 39 | ||||
-rw-r--r-- | arch/arm/mach-davinci/include/mach/common.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-davinci/include/mach/gpio.h | 14 |
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 | ||
652 | void __init dm355_init(void) | 656 | void __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 | ||
595 | void __init dm644x_init(void) | 599 | void __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 | ||
574 | void __init dm646x_init(void) | 578 | void __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 | ||
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 | { |
@@ -116,23 +115,16 @@ davinci_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | |||
116 | static int __init davinci_gpio_setup(void) | 115 | static 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) | |||
279 | static int __init davinci_gpio_irq_setup(void) | 271 | static 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 | ||
63 | extern struct davinci_soc_info davinci_soc_info; | 66 | extern 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 | ||
148 | static inline int irq_to_gpio(unsigned irq) | 150 | static 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 */ |