gpio: generalize for all generic gpio providers

The Blackfin gpio command isn't terribly Blackfin-specific.  So generalize
the few pieces into two new optional helpers:
	name_to_gpio() - turn a string name into a GPIO #
	gpio_status() - display current pin bindings (think /proc/gpio)

Once these pieces are pulled out, we can relocate the cmd_gpio.c into the
common directory.

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
diff --git a/arch/blackfin/cpu/Makefile b/arch/blackfin/cpu/Makefile
index 4a9e577..df10f1b 100644
--- a/arch/blackfin/cpu/Makefile
+++ b/arch/blackfin/cpu/Makefile
@@ -18,7 +18,6 @@
 SEXTRA   := start.o
 SOBJS    := interrupt.o cache.o
 COBJS-$(CONFIG_BOOTCOUNT_LIMIT) += bootcount.o
-COBJS-$(CONFIG_CMD_GPIO) += cmd_gpio.o
 COBJS-y  += cpu.o
 COBJS-y  += gpio.o
 COBJS-y  += interrupts.o
diff --git a/arch/blackfin/cpu/cmd_gpio.c b/arch/blackfin/cpu/cmd_gpio.c
deleted file mode 100644
index e96413b..0000000
--- a/arch/blackfin/cpu/cmd_gpio.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Control GPIO pins on the fly
- *
- * Copyright (c) 2008-2010 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <common.h>
-#include <command.h>
-#include <linux/ctype.h>
-
-#include <asm/blackfin.h>
-#include <asm/gpio.h>
-
-enum {
-	GPIO_INPUT,
-	GPIO_SET,
-	GPIO_CLEAR,
-	GPIO_TOGGLE,
-};
-
-int do_gpio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
-	if (argc == 2 && !strcmp(argv[1], "status")) {
-		bfin_gpio_labels();
-		return 0;
-	}
-
-	if (argc != 3)
- show_usage:
-		return cmd_usage(cmdtp);
-
-	/* parse the behavior */
-	ulong sub_cmd;
-	switch (argv[1][0]) {
-		case 'i': sub_cmd = GPIO_INPUT;  break;
-		case 's': sub_cmd = GPIO_SET;    break;
-		case 'c': sub_cmd = GPIO_CLEAR;  break;
-		case 't': sub_cmd = GPIO_TOGGLE; break;
-		default:  goto show_usage;
-	}
-
-	/* parse the pin with format: [p][port]<#> */
-	const char *str_pin = argv[2];
-
-	/* grab the [p]<port> portion */
-	ulong port_base;
-	if (tolower(*str_pin) == 'p') ++str_pin;
-	switch (tolower(*str_pin)) {
-#ifdef GPIO_PA0
-		case 'a': port_base = GPIO_PA0; break;
-#endif
-#ifdef GPIO_PB0
-		case 'b': port_base = GPIO_PB0; break;
-#endif
-#ifdef GPIO_PC0
-		case 'c': port_base = GPIO_PC0; break;
-#endif
-#ifdef GPIO_PD0
-		case 'd': port_base = GPIO_PD0; break;
-#endif
-#ifdef GPIO_PE0
-		case 'e': port_base = GPIO_PE0; break;
-#endif
-#ifdef GPIO_PF0
-		case 'f': port_base = GPIO_PF0; break;
-#endif
-#ifdef GPIO_PG0
-		case 'g': port_base = GPIO_PG0; break;
-#endif
-#ifdef GPIO_PH0
-		case 'h': port_base = GPIO_PH0; break;
-#endif
-#ifdef GPIO_PI0
-		case 'i': port_base = GPIO_PI0; break;
-#endif
-#ifdef GPIO_PJ
-		case 'j': port_base = GPIO_PJ0; break;
-#endif
-		default:  goto show_usage;
-	}
-
-	/* grab the <#> portion */
-	ulong pin = simple_strtoul(str_pin + 1, NULL, 10);
-	if (pin > 15)
-		goto show_usage;
-
-	/* grab the pin before we tweak it */
-	ulong gpio = port_base + pin;
-	gpio_request(gpio, "cmd_gpio");
-
-	/* finally, let's do it: set direction and exec command */
-	ulong value;
-	if (sub_cmd == GPIO_INPUT) {
-		gpio_direction_input(gpio);
-		value = gpio_get_value(gpio);
-	} else {
-		switch (sub_cmd) {
-			case GPIO_SET:    value = 1; break;
-			case GPIO_CLEAR:  value = 0; break;
-			case GPIO_TOGGLE: value = !gpio_get_value(gpio); break;
-			default:          goto show_usage;
-		}
-		gpio_direction_output(gpio, value);
-	}
-	printf("gpio: pin %lu on port %c (gpio %lu) value is %lu\n",
-		pin, *str_pin, gpio, value);
-
-	gpio_free(gpio);
-
-	return value;
-}
-
-U_BOOT_CMD(gpio, 3, 0, do_gpio,
-	"input/set/clear/toggle gpio output pins",
-	"<input|set|clear|toggle> <port><pin>\n"
-	"    - input/set/clear/toggle the specified pin (e.g. PF10)");
diff --git a/arch/blackfin/include/asm/gpio.h b/arch/blackfin/include/asm/gpio.h
index b650ef0..9c0e5d1 100644
--- a/arch/blackfin/include/asm/gpio.h
+++ b/arch/blackfin/include/asm/gpio.h
@@ -196,6 +196,59 @@
 	return number >= 0 && number < MAX_BLACKFIN_GPIOS;
 }
 
+#include <linux/ctype.h>
+
+static inline int name_to_gpio(const char *name)
+{
+	int port_base;
+
+	if (tolower(*name) == 'p') {
+		++name;
+
+		switch (tolower(*name)) {
+#ifdef GPIO_PA0
+		case 'a': port_base = GPIO_PA0; break;
+#endif
+#ifdef GPIO_PB0
+		case 'b': port_base = GPIO_PB0; break;
+#endif
+#ifdef GPIO_PC0
+		case 'c': port_base = GPIO_PC0; break;
+#endif
+#ifdef GPIO_PD0
+		case 'd': port_base = GPIO_PD0; break;
+#endif
+#ifdef GPIO_PE0
+		case 'e': port_base = GPIO_PE0; break;
+#endif
+#ifdef GPIO_PF0
+		case 'f': port_base = GPIO_PF0; break;
+#endif
+#ifdef GPIO_PG0
+		case 'g': port_base = GPIO_PG0; break;
+#endif
+#ifdef GPIO_PH0
+		case 'h': port_base = GPIO_PH0; break;
+#endif
+#ifdef GPIO_PI0
+		case 'i': port_base = GPIO_PI0; break;
+#endif
+#ifdef GPIO_PJ
+		case 'j': port_base = GPIO_PJ0; break;
+#endif
+		default:  return -1;
+		}
+
+		++name;
+	} else
+		port_base = 0;
+
+	return port_base + simple_strtoul(name, NULL, 10);
+}
+#define name_to_gpio(n) name_to_gpio(n)
+
+#define gpio_status() bfin_gpio_labels()
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __ARCH_BLACKFIN_GPIO_H__ */