aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-davinci/gpio.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-10-12 09:05:39 -0400
committerIngo Molnar <mingo@elte.hu>2008-10-12 09:05:39 -0400
commita9b9e81c915e4a57ac3b21d1a7fa7ff184639780 (patch)
tree98304395fbb5b9c74fca35b196cd414c1949f280 /arch/arm/mach-davinci/gpio.c
parenta8b71a2810386a5ac8f43d2095fe3355f0d8db37 (diff)
parentfd048088306656824958e7783ffcee27e241b361 (diff)
Merge branch 'linus' into x86/memory-corruption-check
Diffstat (limited to 'arch/arm/mach-davinci/gpio.c')
-rw-r--r--arch/arm/mach-davinci/gpio.c138
1 files changed, 72 insertions, 66 deletions
diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c
index c9cb4f09b18f..b49e9d092aab 100644
--- a/arch/arm/mach-davinci/gpio.c
+++ b/arch/arm/mach-davinci/gpio.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * TI DaVinci GPIO Support 2 * TI DaVinci GPIO Support
3 * 3 *
4 * Copyright (c) 2006 David Brownell 4 * Copyright (c) 2006-2007 David Brownell
5 * Copyright (c) 2007, MontaVista Software, Inc. <source@mvista.com> 5 * Copyright (c) 2007, MontaVista Software, Inc. <source@mvista.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
@@ -26,47 +26,45 @@
26 26
27#include <asm/mach/irq.h> 27#include <asm/mach/irq.h>
28 28
29static DEFINE_SPINLOCK(gpio_lock);
30static DECLARE_BITMAP(gpio_in_use, DAVINCI_N_GPIO);
31 29
32int gpio_request(unsigned gpio, const char *tag) 30static DEFINE_SPINLOCK(gpio_lock);
33{
34 if (gpio >= DAVINCI_N_GPIO)
35 return -EINVAL;
36 31
37 if (test_and_set_bit(gpio, gpio_in_use)) 32struct davinci_gpio {
38 return -EBUSY; 33 struct gpio_chip chip;
34 struct gpio_controller *__iomem regs;
35};
39 36
40 return 0; 37static struct davinci_gpio chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)];
41}
42EXPORT_SYMBOL(gpio_request);
43 38
44void gpio_free(unsigned gpio)
45{
46 if (gpio >= DAVINCI_N_GPIO)
47 return;
48
49 clear_bit(gpio, gpio_in_use);
50}
51EXPORT_SYMBOL(gpio_free);
52 39
53/* create a non-inlined version */ 40/* create a non-inlined version */
54static struct gpio_controller *__iomem gpio2controller(unsigned gpio) 41static struct gpio_controller *__iomem __init gpio2controller(unsigned gpio)
55{ 42{
56 return __gpio_to_controller(gpio); 43 return __gpio_to_controller(gpio);
57} 44}
58 45
46
47/*--------------------------------------------------------------------------*/
48
59/* 49/*
60 * Assuming the pin is muxed as a gpio output, set its output value. 50 * board setup code *MUST* set PINMUX0 and PINMUX1 as
51 * needed, and enable the GPIO clock.
61 */ 52 */
62void __gpio_set(unsigned gpio, int value) 53
54static int davinci_direction_in(struct gpio_chip *chip, unsigned offset)
63{ 55{
64 struct gpio_controller *__iomem g = gpio2controller(gpio); 56 struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip);
57 struct gpio_controller *__iomem g = d->regs;
58 u32 temp;
65 59
66 __raw_writel(__gpio_mask(gpio), value ? &g->set_data : &g->clr_data); 60 spin_lock(&gpio_lock);
67} 61 temp = __raw_readl(&g->dir);
68EXPORT_SYMBOL(__gpio_set); 62 temp |= (1 << offset);
63 __raw_writel(temp, &g->dir);
64 spin_unlock(&gpio_lock);
69 65
66 return 0;
67}
70 68
71/* 69/*
72 * Read the pin's value (works even if it's set up as output); 70 * Read the pin's value (works even if it's set up as output);
@@ -75,61 +73,72 @@ EXPORT_SYMBOL(__gpio_set);
75 * Note that changes are synched to the GPIO clock, so reading values back 73 * Note that changes are synched to the GPIO clock, so reading values back
76 * right after you've set them may give old values. 74 * right after you've set them may give old values.
77 */ 75 */
78int __gpio_get(unsigned gpio) 76static int davinci_gpio_get(struct gpio_chip *chip, unsigned offset)
79{ 77{
80 struct gpio_controller *__iomem g = gpio2controller(gpio); 78 struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip);
79 struct gpio_controller *__iomem g = d->regs;
81 80
82 return !!(__gpio_mask(gpio) & __raw_readl(&g->in_data)); 81 return (1 << offset) & __raw_readl(&g->in_data);
83} 82}
84EXPORT_SYMBOL(__gpio_get);
85 83
86 84static int
87/*--------------------------------------------------------------------------*/ 85davinci_direction_out(struct gpio_chip *chip, unsigned offset, int value)
88
89/*
90 * board setup code *MUST* set PINMUX0 and PINMUX1 as
91 * needed, and enable the GPIO clock.
92 */
93
94int gpio_direction_input(unsigned gpio)
95{ 86{
96 struct gpio_controller *__iomem g = gpio2controller(gpio); 87 struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip);
88 struct gpio_controller *__iomem g = d->regs;
97 u32 temp; 89 u32 temp;
98 u32 mask; 90 u32 mask = 1 << offset;
99
100 if (!g)
101 return -EINVAL;
102 91
103 spin_lock(&gpio_lock); 92 spin_lock(&gpio_lock);
104 mask = __gpio_mask(gpio);
105 temp = __raw_readl(&g->dir); 93 temp = __raw_readl(&g->dir);
106 temp |= mask; 94 temp &= ~mask;
95 __raw_writel(mask, value ? &g->set_data : &g->clr_data);
107 __raw_writel(temp, &g->dir); 96 __raw_writel(temp, &g->dir);
108 spin_unlock(&gpio_lock); 97 spin_unlock(&gpio_lock);
109 return 0; 98 return 0;
110} 99}
111EXPORT_SYMBOL(gpio_direction_input);
112 100
113int gpio_direction_output(unsigned gpio, int value) 101/*
102 * Assuming the pin is muxed as a gpio output, set its output value.
103 */
104static void
105davinci_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
114{ 106{
115 struct gpio_controller *__iomem g = gpio2controller(gpio); 107 struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip);
116 u32 temp; 108 struct gpio_controller *__iomem g = d->regs;
117 u32 mask;
118 109
119 if (!g) 110 __raw_writel((1 << offset), value ? &g->set_data : &g->clr_data);
120 return -EINVAL; 111}
112
113static int __init davinci_gpio_setup(void)
114{
115 int i, base;
116
117 for (i = 0, base = 0;
118 i < ARRAY_SIZE(chips);
119 i++, base += 32) {
120 chips[i].chip.label = "DaVinci";
121
122 chips[i].chip.direction_input = davinci_direction_in;
123 chips[i].chip.get = davinci_gpio_get;
124 chips[i].chip.direction_output = davinci_direction_out;
125 chips[i].chip.set = davinci_gpio_set;
126
127 chips[i].chip.base = base;
128 chips[i].chip.ngpio = DAVINCI_N_GPIO - base;
129 if (chips[i].chip.ngpio > 32)
130 chips[i].chip.ngpio = 32;
131
132 chips[i].regs = gpio2controller(base);
133
134 gpiochip_add(&chips[i].chip);
135 }
121 136
122 spin_lock(&gpio_lock);
123 mask = __gpio_mask(gpio);
124 temp = __raw_readl(&g->dir);
125 temp &= ~mask;
126 __raw_writel(mask, value ? &g->set_data : &g->clr_data);
127 __raw_writel(temp, &g->dir);
128 spin_unlock(&gpio_lock);
129 return 0; 137 return 0;
130} 138}
131EXPORT_SYMBOL(gpio_direction_output); 139pure_initcall(davinci_gpio_setup);
132 140
141/*--------------------------------------------------------------------------*/
133/* 142/*
134 * We expect irqs will normally be set up as input pins, but they can also be 143 * We expect irqs will normally be set up as input pins, but they can also be
135 * used as output pins ... which is convenient for testing. 144 * used as output pins ... which is convenient for testing.
@@ -201,7 +210,6 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
201 desc->chip->ack(irq); 210 desc->chip->ack(irq);
202 while (1) { 211 while (1) {
203 u32 status; 212 u32 status;
204 struct irq_desc *gpio;
205 int n; 213 int n;
206 int res; 214 int res;
207 215
@@ -215,12 +223,10 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
215 223
216 /* now demux them to the right lowlevel handler */ 224 /* now demux them to the right lowlevel handler */
217 n = (int)get_irq_data(irq); 225 n = (int)get_irq_data(irq);
218 gpio = &irq_desc[n];
219 while (status) { 226 while (status) {
220 res = ffs(status); 227 res = ffs(status);
221 n += res; 228 n += res;
222 gpio += res; 229 generic_handle_irq(n - 1);
223 desc_handle_irq(n - 1, gpio - 1);
224 status >>= res; 230 status >>= res;
225 } 231 }
226 } 232 }