Commit 28d27cf4 authored by Nicolas Pitre's avatar Nicolas Pitre

[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: default avatarNicolas Pitre <nico@marvell.com>
parent 22fc1db1
...@@ -19,7 +19,8 @@ ...@@ -19,7 +19,8 @@
static DEFINE_SPINLOCK(gpio_lock); static DEFINE_SPINLOCK(gpio_lock);
static const char *gpio_label[GPIO_MAX]; /* non null for allocated GPIOs */ static const char *gpio_label[GPIO_MAX]; /* non null for allocated GPIOs */
static unsigned long gpio_valid[BITS_TO_LONGS(GPIO_MAX)]; static unsigned long gpio_valid_input[BITS_TO_LONGS(GPIO_MAX)];
static unsigned long gpio_valid_output[BITS_TO_LONGS(GPIO_MAX)];
static inline void __set_direction(unsigned pin, int input) static inline void __set_direction(unsigned pin, int input)
{ {
...@@ -53,7 +54,7 @@ int gpio_direction_input(unsigned pin) ...@@ -53,7 +54,7 @@ int gpio_direction_input(unsigned pin)
{ {
unsigned long flags; unsigned long flags;
if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) { if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid_input)) {
pr_debug("%s: invalid GPIO %d\n", __func__, pin); pr_debug("%s: invalid GPIO %d\n", __func__, pin);
return -EINVAL; return -EINVAL;
} }
...@@ -83,7 +84,7 @@ int gpio_direction_output(unsigned pin, int value) ...@@ -83,7 +84,7 @@ int gpio_direction_output(unsigned pin, int value)
unsigned long flags; unsigned long flags;
u32 u; u32 u;
if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) { if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid_output)) {
pr_debug("%s: invalid GPIO %d\n", __func__, pin); pr_debug("%s: invalid GPIO %d\n", __func__, pin);
return -EINVAL; return -EINVAL;
} }
...@@ -161,7 +162,9 @@ int gpio_request(unsigned pin, const char *label) ...@@ -161,7 +162,9 @@ int gpio_request(unsigned pin, const char *label)
unsigned long flags; unsigned long flags;
int ret; int ret;
if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) { if (pin >= GPIO_MAX ||
!(test_bit(pin, gpio_valid_input) ||
test_bit(pin, gpio_valid_output))) {
pr_debug("%s: invalid GPIO %d\n", __func__, pin); pr_debug("%s: invalid GPIO %d\n", __func__, pin);
return -EINVAL; return -EINVAL;
} }
...@@ -183,7 +186,9 @@ EXPORT_SYMBOL(gpio_request); ...@@ -183,7 +186,9 @@ EXPORT_SYMBOL(gpio_request);
void gpio_free(unsigned pin) void gpio_free(unsigned pin)
{ {
if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) { if (pin >= GPIO_MAX ||
!(test_bit(pin, gpio_valid_input) ||
test_bit(pin, gpio_valid_output))) {
pr_debug("%s: invalid GPIO %d\n", __func__, pin); pr_debug("%s: invalid GPIO %d\n", __func__, pin);
return; return;
} }
...@@ -208,12 +213,18 @@ void __init orion_gpio_set_unused(unsigned pin) ...@@ -208,12 +213,18 @@ void __init orion_gpio_set_unused(unsigned pin)
__set_direction(pin, 0); __set_direction(pin, 0);
} }
void __init orion_gpio_set_valid(unsigned pin, int valid) void __init orion_gpio_set_valid(unsigned pin, int mode)
{ {
if (valid) if (mode == 1)
__set_bit(pin, gpio_valid); mode = GPIO_INPUT_OK | GPIO_OUTPUT_OK;
if (mode & GPIO_INPUT_OK)
__set_bit(pin, gpio_valid_input);
else else
__clear_bit(pin, gpio_valid); __clear_bit(pin, gpio_valid_input);
if (mode & GPIO_OUTPUT_OK)
__set_bit(pin, gpio_valid_output);
else
__clear_bit(pin, gpio_valid_output);
} }
void orion_gpio_set_blink(unsigned pin, int blink) void orion_gpio_set_blink(unsigned pin, int blink)
......
...@@ -25,9 +25,13 @@ void gpio_set_value(unsigned pin, int value); ...@@ -25,9 +25,13 @@ void gpio_set_value(unsigned pin, int value);
* Orion-specific GPIO API extensions. * Orion-specific GPIO API extensions.
*/ */
void orion_gpio_set_unused(unsigned pin); void orion_gpio_set_unused(unsigned pin);
void orion_gpio_set_valid(unsigned pin, int valid);
void orion_gpio_set_blink(unsigned pin, int blink); void orion_gpio_set_blink(unsigned pin, int blink);
#define GPIO_BIDI_OK (1 << 0)
#define GPIO_INPUT_OK (1 << 1)
#define GPIO_OUTPUT_OK (1 << 2)
void orion_gpio_set_valid(unsigned pin, int mode);
/* /*
* GPIO interrupt handling. * GPIO interrupt handling.
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment