aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorNicolas Pitre <nico@cam.org>2009-02-02 15:27:55 -0500
committerNicolas Pitre <nico@cam.org>2009-02-19 22:26:58 -0500
commit28d27cf4ce8378180eda32aa7d8e778c9e72a54f (patch)
treeb774e297b88a3df9e4bd89dcd7efa42f323c2c77 /arch/arm
parent22fc1db12515e1b528570c547fd27e38df792f1f (diff)
[ARM] Orion: make gpio /input/output validation separate
Especially on Kirkwood, a couple GPIOs are actually only output capable. Let's separate the ability to configure a GPIO as input or output to accommodate this restriction. Signed-off-by: Nicolas Pitre <nico@marvell.com>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/plat-orion/gpio.c29
-rw-r--r--arch/arm/plat-orion/include/plat/gpio.h6
2 files changed, 25 insertions, 10 deletions
diff --git a/arch/arm/plat-orion/gpio.c b/arch/arm/plat-orion/gpio.c
index 0d12c2164766..32eb9e33bebb 100644
--- a/arch/arm/plat-orion/gpio.c
+++ b/arch/arm/plat-orion/gpio.c
@@ -19,7 +19,8 @@
19 19
20static DEFINE_SPINLOCK(gpio_lock); 20static DEFINE_SPINLOCK(gpio_lock);
21static const char *gpio_label[GPIO_MAX]; /* non null for allocated GPIOs */ 21static const char *gpio_label[GPIO_MAX]; /* non null for allocated GPIOs */
22static unsigned long gpio_valid[BITS_TO_LONGS(GPIO_MAX)]; 22static unsigned long gpio_valid_input[BITS_TO_LONGS(GPIO_MAX)];
23static unsigned long gpio_valid_output[BITS_TO_LONGS(GPIO_MAX)];
23 24
24static inline void __set_direction(unsigned pin, int input) 25static inline void __set_direction(unsigned pin, int input)
25{ 26{
@@ -53,7 +54,7 @@ int gpio_direction_input(unsigned pin)
53{ 54{
54 unsigned long flags; 55 unsigned long flags;
55 56
56 if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) { 57 if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid_input)) {
57 pr_debug("%s: invalid GPIO %d\n", __func__, pin); 58 pr_debug("%s: invalid GPIO %d\n", __func__, pin);
58 return -EINVAL; 59 return -EINVAL;
59 } 60 }
@@ -83,7 +84,7 @@ int gpio_direction_output(unsigned pin, int value)
83 unsigned long flags; 84 unsigned long flags;
84 u32 u; 85 u32 u;
85 86
86 if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) { 87 if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid_output)) {
87 pr_debug("%s: invalid GPIO %d\n", __func__, pin); 88 pr_debug("%s: invalid GPIO %d\n", __func__, pin);
88 return -EINVAL; 89 return -EINVAL;
89 } 90 }
@@ -161,7 +162,9 @@ int gpio_request(unsigned pin, const char *label)
161 unsigned long flags; 162 unsigned long flags;
162 int ret; 163 int ret;
163 164
164 if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) { 165 if (pin >= GPIO_MAX ||
166 !(test_bit(pin, gpio_valid_input) ||
167 test_bit(pin, gpio_valid_output))) {
165 pr_debug("%s: invalid GPIO %d\n", __func__, pin); 168 pr_debug("%s: invalid GPIO %d\n", __func__, pin);
166 return -EINVAL; 169 return -EINVAL;
167 } 170 }
@@ -183,7 +186,9 @@ EXPORT_SYMBOL(gpio_request);
183 186
184void gpio_free(unsigned pin) 187void gpio_free(unsigned pin)
185{ 188{
186 if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) { 189 if (pin >= GPIO_MAX ||
190 !(test_bit(pin, gpio_valid_input) ||
191 test_bit(pin, gpio_valid_output))) {
187 pr_debug("%s: invalid GPIO %d\n", __func__, pin); 192 pr_debug("%s: invalid GPIO %d\n", __func__, pin);
188 return; 193 return;
189 } 194 }
@@ -208,12 +213,18 @@ void __init orion_gpio_set_unused(unsigned pin)
208 __set_direction(pin, 0); 213 __set_direction(pin, 0);
209} 214}
210 215
211void __init orion_gpio_set_valid(unsigned pin, int valid) 216void __init orion_gpio_set_valid(unsigned pin, int mode)
212{ 217{
213 if (valid) 218 if (mode == 1)
214 __set_bit(pin, gpio_valid); 219 mode = GPIO_INPUT_OK | GPIO_OUTPUT_OK;
220 if (mode & GPIO_INPUT_OK)
221 __set_bit(pin, gpio_valid_input);
215 else 222 else
216 __clear_bit(pin, gpio_valid); 223 __clear_bit(pin, gpio_valid_input);
224 if (mode & GPIO_OUTPUT_OK)
225 __set_bit(pin, gpio_valid_output);
226 else
227 __clear_bit(pin, gpio_valid_output);
217} 228}
218 229
219void orion_gpio_set_blink(unsigned pin, int blink) 230void orion_gpio_set_blink(unsigned pin, int blink)
diff --git a/arch/arm/plat-orion/include/plat/gpio.h b/arch/arm/plat-orion/include/plat/gpio.h
index ec743e82c876..33f6c6aec185 100644
--- a/arch/arm/plat-orion/include/plat/gpio.h
+++ b/arch/arm/plat-orion/include/plat/gpio.h
@@ -25,9 +25,13 @@ void gpio_set_value(unsigned pin, int value);
25 * Orion-specific GPIO API extensions. 25 * Orion-specific GPIO API extensions.
26 */ 26 */
27void orion_gpio_set_unused(unsigned pin); 27void orion_gpio_set_unused(unsigned pin);
28void orion_gpio_set_valid(unsigned pin, int valid);
29void orion_gpio_set_blink(unsigned pin, int blink); 28void orion_gpio_set_blink(unsigned pin, int blink);
30 29
30#define GPIO_BIDI_OK (1 << 0)
31#define GPIO_INPUT_OK (1 << 1)
32#define GPIO_OUTPUT_OK (1 << 2)
33void orion_gpio_set_valid(unsigned pin, int mode);
34
31/* 35/*
32 * GPIO interrupt handling. 36 * GPIO interrupt handling.
33 */ 37 */