diff options
author | Nicolas Pitre <nico@cam.org> | 2009-02-02 15:27:55 -0500 |
---|---|---|
committer | Nicolas Pitre <nico@cam.org> | 2009-02-19 22:26:58 -0500 |
commit | 28d27cf4ce8378180eda32aa7d8e778c9e72a54f (patch) | |
tree | b774e297b88a3df9e4bd89dcd7efa42f323c2c77 /arch/arm/plat-orion | |
parent | 22fc1db12515e1b528570c547fd27e38df792f1f (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/plat-orion')
-rw-r--r-- | arch/arm/plat-orion/gpio.c | 29 | ||||
-rw-r--r-- | arch/arm/plat-orion/include/plat/gpio.h | 6 |
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 | ||
20 | static DEFINE_SPINLOCK(gpio_lock); | 20 | static DEFINE_SPINLOCK(gpio_lock); |
21 | static const char *gpio_label[GPIO_MAX]; /* non null for allocated GPIOs */ | 21 | static const char *gpio_label[GPIO_MAX]; /* non null for allocated GPIOs */ |
22 | static unsigned long gpio_valid[BITS_TO_LONGS(GPIO_MAX)]; | 22 | static unsigned long gpio_valid_input[BITS_TO_LONGS(GPIO_MAX)]; |
23 | static unsigned long gpio_valid_output[BITS_TO_LONGS(GPIO_MAX)]; | ||
23 | 24 | ||
24 | static inline void __set_direction(unsigned pin, int input) | 25 | static 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 | ||
184 | void gpio_free(unsigned pin) | 187 | void 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 | ||
211 | void __init orion_gpio_set_valid(unsigned pin, int valid) | 216 | void __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 | ||
219 | void orion_gpio_set_blink(unsigned pin, int blink) | 230 | void 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 | */ |
27 | void orion_gpio_set_unused(unsigned pin); | 27 | void orion_gpio_set_unused(unsigned pin); |
28 | void orion_gpio_set_valid(unsigned pin, int valid); | ||
29 | void orion_gpio_set_blink(unsigned pin, int blink); | 28 | void 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) | ||
33 | void orion_gpio_set_valid(unsigned pin, int mode); | ||
34 | |||
31 | /* | 35 | /* |
32 | * GPIO interrupt handling. | 36 | * GPIO interrupt handling. |
33 | */ | 37 | */ |