diff --git a/arch/blackfin/cpu/Makefile b/arch/blackfin/cpu/Makefile
index 929fc8b..1421cb2 100644
--- a/arch/blackfin/cpu/Makefile
+++ b/arch/blackfin/cpu/Makefile
@@ -18,7 +18,7 @@ CEXTRA   := initcode.o
 SEXTRA   := start.o
 SOBJS    := interrupt.o cache.o
 COBJS-y  += cpu.o
-COBJS-y  += gpio.o
+COBJS-$(CONFIG_ADI_GPIO1) += gpio.o
 COBJS-y  += interrupts.o
 COBJS-$(CONFIG_JTAG_CONSOLE) += jtag-console.o
 COBJS-y  += os_log.o
diff --git a/arch/blackfin/cpu/gpio.c b/arch/blackfin/cpu/gpio.c
index f684be5..f74a0b7 100644
--- a/arch/blackfin/cpu/gpio.c
+++ b/arch/blackfin/cpu/gpio.c
@@ -1,5 +1,6 @@
 /*
- * GPIO Abstraction Layer
+ * ADI GPIO1 Abstraction Layer
+ * Support BF50x, BF51x, BF52x, BF53x and BF561 only.
  *
  * Copyright 2006-2010 Analog Devices Inc.
  *
@@ -55,25 +56,6 @@ static struct gpio_port_t * const gpio_array[] = {
 	(struct gpio_port_t *) FIO0_FLAG_D,
 	(struct gpio_port_t *) FIO1_FLAG_D,
 	(struct gpio_port_t *) FIO2_FLAG_D,
-#elif defined(CONFIG_BF54x)
-	(struct gpio_port_t *)PORTA_FER,
-	(struct gpio_port_t *)PORTB_FER,
-	(struct gpio_port_t *)PORTC_FER,
-	(struct gpio_port_t *)PORTD_FER,
-	(struct gpio_port_t *)PORTE_FER,
-	(struct gpio_port_t *)PORTF_FER,
-	(struct gpio_port_t *)PORTG_FER,
-	(struct gpio_port_t *)PORTH_FER,
-	(struct gpio_port_t *)PORTI_FER,
-	(struct gpio_port_t *)PORTJ_FER,
-#elif defined(CONFIG_BF60x)
-	(struct gpio_port_t *)PORTA_FER,
-	(struct gpio_port_t *)PORTB_FER,
-	(struct gpio_port_t *)PORTC_FER,
-	(struct gpio_port_t *)PORTD_FER,
-	(struct gpio_port_t *)PORTE_FER,
-	(struct gpio_port_t *)PORTF_FER,
-	(struct gpio_port_t *)PORTG_FER,
 #else
 # error no gpio arrays defined
 #endif
@@ -174,12 +156,6 @@ DECLARE_RESERVED_MAP(peri, gpio_bank(MAX_RESOURCES));
 
 inline int check_gpio(unsigned gpio)
 {
-#if defined(CONFIG_BF54x)
-	if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15
-	    || gpio == GPIO_PH14 || gpio == GPIO_PH15
-	    || gpio == GPIO_PJ14 || gpio == GPIO_PJ15)
-		return -EINVAL;
-#endif
 	if (gpio >= MAX_BLACKFIN_GPIOS)
 		return -EINVAL;
 	return 0;
@@ -218,18 +194,6 @@ static void port_setup(unsigned gpio, unsigned short usage)
 	else
 		*port_fer[gpio_bank(gpio)] |= gpio_bit(gpio);
 	SSYNC();
-#elif defined(CONFIG_BF54x)
-	if (usage == GPIO_USAGE)
-		gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio);
-	else
-		gpio_array[gpio_bank(gpio)]->port_fer |= gpio_bit(gpio);
-	SSYNC();
-#elif defined(CONFIG_BF60x)
-	if (usage == GPIO_USAGE)
-		gpio_array[gpio_bank(gpio)]->port_fer_clear = gpio_bit(gpio);
-	else
-		gpio_array[gpio_bank(gpio)]->port_fer_set = gpio_bit(gpio);
-	SSYNC();
 #endif
 }
 
@@ -304,30 +268,6 @@ static void portmux_setup(unsigned short per)
 		}
 	}
 }
-#elif defined(CONFIG_BF54x) || defined(CONFIG_BF60x)
-inline void portmux_setup(unsigned short per)
-{
-	u32 pmux;
-	u16 ident = P_IDENT(per);
-	u16 function = P_FUNCT2MUX(per);
-
-	pmux = gpio_array[gpio_bank(ident)]->port_mux;
-
-	pmux &= ~(0x3 << (2 * gpio_sub_n(ident)));
-	pmux |= (function & 0x3) << (2 * gpio_sub_n(ident));
-
-	gpio_array[gpio_bank(ident)]->port_mux = pmux;
-}
-
-inline u16 get_portmux(unsigned short per)
-{
-	u32 pmux;
-	u16 ident = P_IDENT(per);
-
-	pmux = gpio_array[gpio_bank(ident)]->port_mux;
-
-	return (pmux >> (2 * gpio_sub_n(ident)) & 0x3);
-}
 #elif defined(CONFIG_BF52x) || defined(CONFIG_BF51x)
 inline void portmux_setup(unsigned short per)
 {
@@ -344,7 +284,6 @@ inline void portmux_setup(unsigned short per)
 # define portmux_setup(...)  do { } while (0)
 #endif
 
-#if !defined(CONFIG_BF54x) && !defined(CONFIG_BF60x)
 /***********************************************************
 *
 * FUNCTIONS: Blackfin General Purpose Ports Access Functions
@@ -491,15 +430,6 @@ GET_GPIO_P(both)
 GET_GPIO_P(maska)
 GET_GPIO_P(maskb)
 
-#else /* CONFIG_BF54x */
-
-unsigned short get_gpio_dir(unsigned gpio)
-{
-	return (0x01 & (gpio_array[gpio_bank(gpio)]->dir_clear >> gpio_sub_n(gpio)));
-}
-
-#endif /* CONFIG_BF54x */
-
 /***********************************************************
 *
 * FUNCTIONS:	Blackfin Peripheral Resource Allocation
@@ -548,11 +478,7 @@ int peripheral_request(unsigned short per, const char *label)
 		 * be requested and used by several drivers
 		 */
 
-#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x)
-		if (!((per & P_MAYSHARE) && get_portmux(per) == P_FUNCT2MUX(per))) {
-#else
 		if (!(per & P_MAYSHARE)) {
-#endif
 			/*
 			 * Allow that the identical pin function can
 			 * be requested from the same driver twice
@@ -641,7 +567,7 @@ void peripheral_free_list(const unsigned short per[])
 * MODIFICATION HISTORY :
 **************************************************************/
 
-int bfin_gpio_request(unsigned gpio, const char *label)
+int gpio_request(unsigned gpio, const char *label)
 {
 	if (check_gpio(gpio) < 0)
 		return -EINVAL;
@@ -665,11 +591,9 @@ int bfin_gpio_request(unsigned gpio, const char *label)
 		       gpio, get_label(gpio));
 		return -EBUSY;
 	}
-#if !defined(CONFIG_BF54x) && !defined(CONFIG_BF60x)
 	else {	/* Reset POLAR setting when acquiring a gpio for the first time */
 		set_gpio_polar(gpio, 0);
 	}
-#endif
 
 	reserve(gpio, gpio);
 	set_label(gpio, label);
@@ -679,27 +603,27 @@ int bfin_gpio_request(unsigned gpio, const char *label)
 	return 0;
 }
 
-#ifdef CONFIG_BFIN_GPIO_TRACK
-void bfin_gpio_free(unsigned gpio)
+int gpio_free(unsigned gpio)
 {
 	if (check_gpio(gpio) < 0)
-		return;
+		return -1;
 
 	if (unlikely(!is_reserved(gpio, gpio, 0))) {
 		gpio_error(gpio);
-		return;
+		return -1;
 	}
 
 	unreserve(gpio, gpio);
 
 	set_label(gpio, "free");
+
+	return 0;
 }
-#endif
 
-#ifdef BFIN_SPECIAL_GPIO_BANKS
+#ifdef ADI_SPECIAL_GPIO_BANKS
 DECLARE_RESERVED_MAP(special_gpio, gpio_bank(MAX_RESOURCES));
 
-int bfin_special_gpio_request(unsigned gpio, const char *label)
+int special_gpio_request(unsigned gpio, const char *label)
 {
 	/*
 	 * Allow that the identical GPIO can
@@ -731,7 +655,7 @@ int bfin_special_gpio_request(unsigned gpio, const char *label)
 	return 0;
 }
 
-void bfin_special_gpio_free(unsigned gpio)
+void special_gpio_free(unsigned gpio)
 {
 	if (unlikely(!is_reserved(special_gpio, gpio, 0))) {
 		gpio_error(gpio);
@@ -744,21 +668,13 @@ void bfin_special_gpio_free(unsigned gpio)
 }
 #endif
 
-static inline void __bfin_gpio_direction_input(unsigned gpio)
+static inline void __gpio_direction_input(unsigned gpio)
 {
-#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x)
-	gpio_array[gpio_bank(gpio)]->dir_clear = gpio_bit(gpio);
-#else
 	gpio_array[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio);
-#endif
-#if defined(CONFIG_BF60x)
-	gpio_array[gpio_bank(gpio)]->inen_set = gpio_bit(gpio);
-#else
 	gpio_array[gpio_bank(gpio)]->inen |= gpio_bit(gpio);
-#endif
 }
 
-int bfin_gpio_direction_input(unsigned gpio)
+int gpio_direction_input(unsigned gpio)
 {
 	unsigned long flags;
 
@@ -768,31 +684,24 @@ int bfin_gpio_direction_input(unsigned gpio)
 	}
 
 	local_irq_save(flags);
-	__bfin_gpio_direction_input(gpio);
+	__gpio_direction_input(gpio);
 	AWA_DUMMY_READ(inen);
 	local_irq_restore(flags);
 
 	return 0;
 }
 
-void bfin_gpio_toggle_value(unsigned gpio)
-{
-#ifdef CONFIG_BF54x
-	gpio_set_value(gpio, !gpio_get_value(gpio));
-#else
-	gpio_array[gpio_bank(gpio)]->toggle = gpio_bit(gpio);
-#endif
-}
-
-void bfin_gpio_set_value(unsigned gpio, int arg)
+int gpio_set_value(unsigned gpio, int arg)
 {
 	if (arg)
 		gpio_array[gpio_bank(gpio)]->data_set = gpio_bit(gpio);
 	else
 		gpio_array[gpio_bank(gpio)]->data_clear = gpio_bit(gpio);
+
+	return 0;
 }
 
-int bfin_gpio_direction_output(unsigned gpio, int value)
+int gpio_direction_output(unsigned gpio, int value)
 {
 	unsigned long flags;
 
@@ -803,17 +712,9 @@ int bfin_gpio_direction_output(unsigned gpio, int value)
 
 	local_irq_save(flags);
 
-#if defined(CONFIG_BF60x)
-	gpio_array[gpio_bank(gpio)]->inen_clear = gpio_bit(gpio);
-#else
 	gpio_array[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio);
-#endif
 	gpio_set_value(gpio, value);
-#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x)
-	gpio_array[gpio_bank(gpio)]->dir_set = gpio_bit(gpio);
-#else
 	gpio_array[gpio_bank(gpio)]->dir |= gpio_bit(gpio);
-#endif
 
 	AWA_DUMMY_READ(dir);
 	local_irq_restore(flags);
@@ -821,11 +722,8 @@ int bfin_gpio_direction_output(unsigned gpio, int value)
 	return 0;
 }
 
-int bfin_gpio_get_value(unsigned gpio)
+int gpio_get_value(unsigned gpio)
 {
-#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x)
-	return (1 & (gpio_array[gpio_bank(gpio)]->data >> gpio_sub_n(gpio)));
-#else
 	unsigned long flags;
 
 	if (unlikely(get_gpio_edge(gpio))) {
@@ -838,7 +736,6 @@ int bfin_gpio_get_value(unsigned gpio)
 		return ret;
 	} else
 		return get_gpio_data(gpio);
-#endif
 }
 
 /* If we are booting from SPI and our board lacks a strong enough pull up,
@@ -860,8 +757,7 @@ void bfin_reset_boot_spi_cs(unsigned short pin)
 	udelay(1);
 }
 
-#ifdef CONFIG_BFIN_GPIO_TRACK
-void bfin_gpio_labels(void)
+void gpio_labels(void)
 {
 	int c, gpio;
 
@@ -877,4 +773,3 @@ void bfin_gpio_labels(void)
 			continue;
 	}
 }
-#endif
diff --git a/arch/blackfin/include/asm/gpio.h b/arch/blackfin/include/asm/gpio.h
index 05131b5..58a6191 100644
--- a/arch/blackfin/include/asm/gpio.h
+++ b/arch/blackfin/include/asm/gpio.h
@@ -7,6 +7,8 @@
 #ifndef __ARCH_BLACKFIN_GPIO_H__
 #define __ARCH_BLACKFIN_GPIO_H__
 
+#include <asm-generic/gpio.h>
+
 #define gpio_bank(x)	((x) >> 4)
 #define gpio_bit(x)	(1<<((x) & 0xF))
 #define gpio_sub_n(x)	((x) & 0xF)
@@ -65,10 +67,11 @@
 
 #define PERIPHERAL_USAGE 1
 #define GPIO_USAGE 0
+#define MAX_GPIOS MAX_BLACKFIN_GPIOS
 
 #ifndef __ASSEMBLY__
 
-#if !defined(CONFIG_BF54x) && !defined(CONFIG_BF60x)
+#ifdef CONFIG_ADI_GPIO1
 void set_gpio_dir(unsigned, unsigned short);
 void set_gpio_inen(unsigned, unsigned short);
 void set_gpio_polar(unsigned, unsigned short);
@@ -140,61 +143,16 @@ struct gpio_port_t {
 };
 #endif
 
-#ifdef CONFIG_BFIN_GPIO_TRACK
-void bfin_gpio_labels(void);
-void bfin_gpio_free(unsigned gpio);
-#else
-#define bfin_gpio_labels()
-#define bfin_gpio_free(gpio)
-#define bfin_gpio_request(gpio, label) bfin_gpio_request(gpio)
-#define bfin_special_gpio_request(gpio, label) bfin_special_gpio_request(gpio)
-#endif
-
-#ifdef BFIN_SPECIAL_GPIO_BANKS
-void bfin_special_gpio_free(unsigned gpio);
-int bfin_special_gpio_request(unsigned gpio, const char *label);
+#ifdef ADI_SPECIAL_GPIO_BANKS
+void special_gpio_free(unsigned gpio);
+int special_gpio_request(unsigned gpio, const char *label);
 #endif
 
-int bfin_gpio_request(unsigned gpio, const char *label);
-int bfin_gpio_direction_input(unsigned gpio);
-int bfin_gpio_direction_output(unsigned gpio, int value);
-int bfin_gpio_get_value(unsigned gpio);
-void bfin_gpio_set_value(unsigned gpio, int value);
-void bfin_gpio_toggle_value(unsigned gpio);
-
-static inline int gpio_request(unsigned gpio, const char *label)
-{
-	return bfin_gpio_request(gpio, label);
-}
-
-static inline void gpio_free(unsigned gpio)
-{
-	return bfin_gpio_free(gpio);
-}
-
-static inline int gpio_direction_input(unsigned gpio)
-{
-	return bfin_gpio_direction_input(gpio);
-}
-
-static inline int gpio_direction_output(unsigned gpio, int value)
-{
-	return bfin_gpio_direction_output(gpio, value);
-}
-
-static inline int gpio_get_value(unsigned gpio)
-{
-	return bfin_gpio_get_value(gpio);
-}
-
-static inline void gpio_set_value(unsigned gpio, int value)
-{
-	return bfin_gpio_set_value(gpio, value);
-}
+void gpio_labels(void);
 
 static inline int gpio_is_valid(int number)
 {
-	return number >= 0 && number < MAX_BLACKFIN_GPIOS;
+	return number >= 0 && number < MAX_GPIOS;
 }
 
 #include <linux/ctype.h>
@@ -248,7 +206,7 @@ static inline int name_to_gpio(const char *name)
 }
 #define name_to_gpio(n) name_to_gpio(n)
 
-#define gpio_status() bfin_gpio_labels()
+#define gpio_status() gpio_labels()
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/arch/blackfin/include/asm/portmux.h b/arch/blackfin/include/asm/portmux.h
index 300ef44..003694b 100644
--- a/arch/blackfin/include/asm/portmux.h
+++ b/arch/blackfin/include/asm/portmux.h
@@ -17,11 +17,6 @@
 #define P_MAYSHARE	0x2000
 #define P_DONTCARE	0x1000
 
-#ifndef CONFIG_BFIN_GPIO_TRACK
-#define peripheral_request(per, label) peripheral_request(per)
-#define peripheral_request_list(per, label) peripheral_request_list(per)
-#endif
-
 #ifndef __ASSEMBLY__
 
 int peripheral_request(unsigned short per, const char *label);
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 2d97b4f..5d2a1d4 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -46,6 +46,7 @@ COBJS-$(CONFIG_OMAP_GPIO)	+= omap_gpio.o
 COBJS-$(CONFIG_DB8500_GPIO)	+= db8500_gpio.o
 COBJS-$(CONFIG_BCM2835_GPIO)	+= bcm2835_gpio.o
 COBJS-$(CONFIG_S3C2440_GPIO)	+= s3c2440_gpio.o
+COBJS-$(CONFIG_ADI_GPIO2)	+= adi_gpio2.o
 
 COBJS	:= $(COBJS-y)
 SRCS 	:= $(COBJS:.o=.c)
diff --git a/drivers/gpio/adi_gpio2.c b/drivers/gpio/adi_gpio2.c
new file mode 100644
index 0000000..7a034eb
--- /dev/null
+++ b/drivers/gpio/adi_gpio2.c
@@ -0,0 +1,440 @@
+/*
+ * ADI GPIO2 Abstraction Layer
+ * Support BF54x, BF60x and future processors.
+ *
+ * Copyright 2008-2013 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later
+ */
+
+#include <common.h>
+#include <asm/errno.h>
+#include <asm/gpio.h>
+#include <asm/portmux.h>
+
+static struct gpio_port_t * const gpio_array[] = {
+	(struct gpio_port_t *)PORTA_FER,
+	(struct gpio_port_t *)PORTB_FER,
+	(struct gpio_port_t *)PORTC_FER,
+	(struct gpio_port_t *)PORTD_FER,
+	(struct gpio_port_t *)PORTE_FER,
+	(struct gpio_port_t *)PORTF_FER,
+	(struct gpio_port_t *)PORTG_FER,
+#if defined(CONFIG_BF54x)
+	(struct gpio_port_t *)PORTH_FER,
+	(struct gpio_port_t *)PORTI_FER,
+	(struct gpio_port_t *)PORTJ_FER,
+#endif
+};
+
+#define RESOURCE_LABEL_SIZE	16
+
+static struct str_ident {
+	char name[RESOURCE_LABEL_SIZE];
+} str_ident[MAX_RESOURCES];
+
+static void gpio_error(unsigned gpio)
+{
+	printf("adi_gpio2: GPIO %d wasn't requested!\n", gpio);
+}
+
+static void set_label(unsigned short ident, const char *label)
+{
+	if (label) {
+		strncpy(str_ident[ident].name, label,
+			RESOURCE_LABEL_SIZE);
+		str_ident[ident].name[RESOURCE_LABEL_SIZE - 1] = 0;
+	}
+}
+
+static char *get_label(unsigned short ident)
+{
+	return *str_ident[ident].name ? str_ident[ident].name : "UNKNOWN";
+}
+
+static int cmp_label(unsigned short ident, const char *label)
+{
+	if (label == NULL)
+		printf("adi_gpio2: please provide none-null label\n");
+
+	if (label)
+		return strcmp(str_ident[ident].name, label);
+	else
+		return -EINVAL;
+}
+
+#define map_entry(m, i)      reserved_##m##_map[gpio_bank(i)]
+#define is_reserved(m, i, e) (map_entry(m, i) & gpio_bit(i))
+#define reserve(m, i)        (map_entry(m, i) |= gpio_bit(i))
+#define unreserve(m, i)      (map_entry(m, i) &= ~gpio_bit(i))
+#define DECLARE_RESERVED_MAP(m, c) unsigned short reserved_##m##_map[c]
+
+static DECLARE_RESERVED_MAP(gpio, GPIO_BANK_NUM);
+static DECLARE_RESERVED_MAP(peri, gpio_bank(MAX_RESOURCES));
+
+inline int check_gpio(unsigned gpio)
+{
+#if defined(CONFIG_BF54x)
+	if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15 ||
+		gpio == GPIO_PH14 || gpio == GPIO_PH15 ||
+		gpio == GPIO_PJ14 || gpio == GPIO_PJ15)
+		return -EINVAL;
+#endif
+	if (gpio >= MAX_GPIOS)
+		return -EINVAL;
+	return 0;
+}
+
+static void port_setup(unsigned gpio, unsigned short usage)
+{
+#if defined(CONFIG_BF54x)
+	if (usage == GPIO_USAGE)
+		gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio);
+	else
+		gpio_array[gpio_bank(gpio)]->port_fer |= gpio_bit(gpio);
+#else
+	if (usage == GPIO_USAGE)
+		gpio_array[gpio_bank(gpio)]->port_fer_clear = gpio_bit(gpio);
+	else
+		gpio_array[gpio_bank(gpio)]->port_fer_set = gpio_bit(gpio);
+#endif
+	SSYNC();
+}
+
+inline void portmux_setup(unsigned short per)
+{
+	u32 pmux;
+	u16 ident = P_IDENT(per);
+	u16 function = P_FUNCT2MUX(per);
+
+	pmux = gpio_array[gpio_bank(ident)]->port_mux;
+
+	pmux &= ~(0x3 << (2 * gpio_sub_n(ident)));
+	pmux |= (function & 0x3) << (2 * gpio_sub_n(ident));
+
+	gpio_array[gpio_bank(ident)]->port_mux = pmux;
+}
+
+inline u16 get_portmux(unsigned short per)
+{
+	u32 pmux;
+	u16 ident = P_IDENT(per);
+
+	pmux = gpio_array[gpio_bank(ident)]->port_mux;
+
+	return pmux >> (2 * gpio_sub_n(ident)) & 0x3;
+}
+
+unsigned short get_gpio_dir(unsigned gpio)
+{
+	return 0x01 &
+		(gpio_array[gpio_bank(gpio)]->dir_clear >> gpio_sub_n(gpio));
+}
+
+/***********************************************************
+*
+* FUNCTIONS:	Peripheral Resource Allocation
+*		and PortMux Setup
+*
+* INPUTS/OUTPUTS:
+* per	Peripheral Identifier
+* label	String
+*
+* DESCRIPTION: Peripheral Resource Allocation and Setup API
+**************************************************************/
+
+int peripheral_request(unsigned short per, const char *label)
+{
+	unsigned short ident = P_IDENT(per);
+
+	/*
+	 * Don't cares are pins with only one dedicated function
+	 */
+
+	if (per & P_DONTCARE)
+		return 0;
+
+	if (!(per & P_DEFINED))
+		return -ENODEV;
+
+	BUG_ON(ident >= MAX_RESOURCES);
+
+	/* If a pin can be muxed as either GPIO or peripheral, make
+	 * sure it is not already a GPIO pin when we request it.
+	 */
+	if (unlikely(!check_gpio(ident) && is_reserved(gpio, ident, 1))) {
+		printf("%s: Peripheral %d is already reserved as GPIO by %s!\n",
+		       __func__, ident, get_label(ident));
+		return -EBUSY;
+	}
+
+	if (unlikely(is_reserved(peri, ident, 1))) {
+		/*
+		 * Pin functions like AMC address strobes my
+		 * be requested and used by several drivers
+		 */
+
+		if (!((per & P_MAYSHARE) &&
+			get_portmux(per) == P_FUNCT2MUX(per))) {
+			/*
+			 * Allow that the identical pin function can
+			 * be requested from the same driver twice
+			 */
+
+			if (cmp_label(ident, label) == 0)
+				goto anyway;
+
+			printf("%s: Peripheral %d function %d is already "
+				"reserved by %s!\n", __func__, ident,
+				P_FUNCT2MUX(per), get_label(ident));
+			return -EBUSY;
+		}
+	}
+
+ anyway:
+	reserve(peri, ident);
+
+	portmux_setup(per);
+	port_setup(ident, PERIPHERAL_USAGE);
+
+	set_label(ident, label);
+
+	return 0;
+}
+
+int peripheral_request_list(const unsigned short per[], const char *label)
+{
+	u16 cnt;
+	int ret;
+
+	for (cnt = 0; per[cnt] != 0; cnt++) {
+		ret = peripheral_request(per[cnt], label);
+
+		if (ret < 0) {
+			for (; cnt > 0; cnt--)
+				peripheral_free(per[cnt - 1]);
+
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+void peripheral_free(unsigned short per)
+{
+	unsigned short ident = P_IDENT(per);
+
+	if (per & P_DONTCARE)
+		return;
+
+	if (!(per & P_DEFINED))
+		return;
+
+	if (unlikely(!is_reserved(peri, ident, 0)))
+		return;
+
+	if (!(per & P_MAYSHARE))
+		port_setup(ident, GPIO_USAGE);
+
+	unreserve(peri, ident);
+
+	set_label(ident, "free");
+}
+
+void peripheral_free_list(const unsigned short per[])
+{
+	u16 cnt;
+	for (cnt = 0; per[cnt] != 0; cnt++)
+		peripheral_free(per[cnt]);
+}
+
+/***********************************************************
+*
+* FUNCTIONS: GPIO Driver
+*
+* INPUTS/OUTPUTS:
+* gpio	PIO Number between 0 and MAX_GPIOS
+* label	String
+*
+* DESCRIPTION: GPIO Driver API
+**************************************************************/
+
+int gpio_request(unsigned gpio, const char *label)
+{
+	if (check_gpio(gpio) < 0)
+		return -EINVAL;
+
+	/*
+	 * Allow that the identical GPIO can
+	 * be requested from the same driver twice
+	 * Do nothing and return -
+	 */
+
+	if (cmp_label(gpio, label) == 0)
+		return 0;
+
+	if (unlikely(is_reserved(gpio, gpio, 1))) {
+		printf("adi_gpio2: GPIO %d is already reserved by %s!\n",
+			gpio, get_label(gpio));
+		return -EBUSY;
+	}
+	if (unlikely(is_reserved(peri, gpio, 1))) {
+		printf("adi_gpio2: GPIO %d is already reserved as Peripheral "
+			"by %s!\n", gpio, get_label(gpio));
+		return -EBUSY;
+	}
+
+	reserve(gpio, gpio);
+	set_label(gpio, label);
+
+	port_setup(gpio, GPIO_USAGE);
+
+	return 0;
+}
+
+int gpio_free(unsigned gpio)
+{
+	if (check_gpio(gpio) < 0)
+		return -1;
+
+	if (unlikely(!is_reserved(gpio, gpio, 0))) {
+		gpio_error(gpio);
+		return -1;
+	}
+
+	unreserve(gpio, gpio);
+
+	set_label(gpio, "free");
+
+	return 0;
+}
+
+#ifdef ADI_SPECIAL_GPIO_BANKS
+static DECLARE_RESERVED_MAP(special_gpio, gpio_bank(MAX_RESOURCES));
+
+int special_gpio_request(unsigned gpio, const char *label)
+{
+	/*
+	 * Allow that the identical GPIO can
+	 * be requested from the same driver twice
+	 * Do nothing and return -
+	 */
+
+	if (cmp_label(gpio, label) == 0)
+		return 0;
+
+	if (unlikely(is_reserved(special_gpio, gpio, 1))) {
+		printf("adi_gpio2: GPIO %d is already reserved by %s!\n",
+			gpio, get_label(gpio));
+		return -EBUSY;
+	}
+	if (unlikely(is_reserved(peri, gpio, 1))) {
+		printf("adi_gpio2: GPIO %d is already reserved as Peripheral "
+			"by %s!\n", gpio, get_label(gpio));
+
+		return -EBUSY;
+	}
+
+	reserve(special_gpio, gpio);
+	reserve(peri, gpio);
+
+	set_label(gpio, label);
+	port_setup(gpio, GPIO_USAGE);
+
+	return 0;
+}
+
+void special_gpio_free(unsigned gpio)
+{
+	if (unlikely(!is_reserved(special_gpio, gpio, 0))) {
+		gpio_error(gpio);
+		return;
+	}
+
+	reserve(special_gpio, gpio);
+	reserve(peri, gpio);
+	set_label(gpio, "free");
+}
+#endif
+
+static inline void __gpio_direction_input(unsigned gpio)
+{
+	gpio_array[gpio_bank(gpio)]->dir_clear = gpio_bit(gpio);
+#if defined(CONFIG_BF54x)
+	gpio_array[gpio_bank(gpio)]->inen |= gpio_bit(gpio);
+#else
+	gpio_array[gpio_bank(gpio)]->inen_set = gpio_bit(gpio);
+#endif
+}
+
+int gpio_direction_input(unsigned gpio)
+{
+	unsigned long flags;
+
+	if (!is_reserved(gpio, gpio, 0)) {
+		gpio_error(gpio);
+		return -EINVAL;
+	}
+
+	local_irq_save(flags);
+	__gpio_direction_input(gpio);
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+int gpio_set_value(unsigned gpio, int arg)
+{
+	if (arg)
+		gpio_array[gpio_bank(gpio)]->data_set = gpio_bit(gpio);
+	else
+		gpio_array[gpio_bank(gpio)]->data_clear = gpio_bit(gpio);
+
+	return 0;
+}
+
+int gpio_direction_output(unsigned gpio, int value)
+{
+	unsigned long flags;
+
+	if (!is_reserved(gpio, gpio, 0)) {
+		gpio_error(gpio);
+		return -EINVAL;
+	}
+
+	local_irq_save(flags);
+
+#if defined(CONFIG_BF54x)
+	gpio_array[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio);
+#else
+	gpio_array[gpio_bank(gpio)]->inen_clear = gpio_bit(gpio);
+#endif
+	gpio_set_value(gpio, value);
+	gpio_array[gpio_bank(gpio)]->dir_set = gpio_bit(gpio);
+
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+int gpio_get_value(unsigned gpio)
+{
+	return 1 & (gpio_array[gpio_bank(gpio)]->data >> gpio_sub_n(gpio));
+}
+
+void gpio_labels(void)
+{
+	int c, gpio;
+
+	for (c = 0; c < MAX_RESOURCES; c++) {
+		gpio = is_reserved(gpio, c, 1);
+		if (!check_gpio(c) && gpio)
+			printf("GPIO_%d:\t%s\tGPIO %s\n", c, get_label(c),
+				get_gpio_dir(c) ? "OUTPUT" : "INPUT");
+		else if (is_reserved(peri, c, 1))
+			printf("GPIO_%d:\t%s\tPeripheral\n", c, get_label(c));
+		else
+			continue;
+	}
+}
diff --git a/include/configs/bf548-ezkit.h b/include/configs/bf548-ezkit.h
index 7ed0ea9..da5f029 100644
--- a/include/configs/bf548-ezkit.h
+++ b/include/configs/bf548-ezkit.h
@@ -182,6 +182,8 @@
 #define CONFIG_UART_CONSOLE	1
 #define CONFIG_BFIN_SPI_IMG_SIZE 0x50000
 
+#define CONFIG_ADI_GPIO2
+
 #undef CONFIG_VIDEO
 #ifdef CONFIG_VIDEO
 #define EASYLOGO_HEADER < asm/bfin_logo_230x230_gzip.h >
diff --git a/include/configs/bf609-ezkit.h b/include/configs/bf609-ezkit.h
index e7b02a5..1a43e1b 100644
--- a/include/configs/bf609-ezkit.h
+++ b/include/configs/bf609-ezkit.h
@@ -149,6 +149,8 @@
 #define CONFIG_SYS_MEMTEST_END (CONFIG_STACKBASE - 20*1024*1024 + 4)
 #define CONFIG_BFIN_SOFT_SWITCH
 
+#define CONFIG_ADI_GPIO2
+
 #if 0
 #define CONFIG_UART_MEM 1024
 #undef CONFIG_UART_CONSOLE
diff --git a/include/configs/bfin_adi_common.h b/include/configs/bfin_adi_common.h
index c751dd7..e1a6fe3 100644
--- a/include/configs/bfin_adi_common.h
+++ b/include/configs/bfin_adi_common.h
@@ -323,5 +323,7 @@
 #  define CONFIG_WATCHDOG_TIMEOUT_MSECS 5000
 # endif
 #endif
-
+#ifndef CONFIG_ADI_GPIO2
+# define CONFIG_ADI_GPIO1
+#endif
 #endif
