MIPS: Don't overflow cevt-r4k.c calculations at high clock rates.
[linux-2.6.git] / arch / blackfin / kernel / bfin_gpio.c
index 51dac55..42833ee 100644 (file)
@@ -1,30 +1,9 @@
 /*
- * File:         arch/blackfin/kernel/bfin_gpio.c
- * Based on:
- * Author:       Michael Hennerich (hennerich@blackfin.uclinux.org)
+ * GPIO Abstraction Layer
  *
- * Created:
- * Description:  GPIO Abstraction Layer
+ * Copyright 2006-2009 Analog Devices Inc.
  *
- * Modified:
- *               Copyright 2008 Analog Devices Inc.
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ * Licensed under the GPL-2 or later
  */
 
 #include <linux/delay.h>
@@ -69,7 +48,7 @@ enum {
 static struct gpio_port_t * const gpio_array[] = {
 #if defined(BF533_FAMILY) || defined(BF538_FAMILY)
        (struct gpio_port_t *) FIO_FLAG_D,
-#elif defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY)
+#elif defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x)
        (struct gpio_port_t *) PORTFIO,
        (struct gpio_port_t *) PORTGIO,
        (struct gpio_port_t *) PORTHIO,
@@ -77,7 +56,7 @@ 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(BF548_FAMILY)
+#elif defined(CONFIG_BF54x)
        (struct gpio_port_t *)PORTA_FER,
        (struct gpio_port_t *)PORTB_FER,
        (struct gpio_port_t *)PORTC_FER,
@@ -93,7 +72,7 @@ static struct gpio_port_t * const gpio_array[] = {
 #endif
 };
 
-#if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY)
+#if defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x)
 static unsigned short * const port_fer[] = {
        (unsigned short *) PORTF_FER,
        (unsigned short *) PORTG_FER,
@@ -109,11 +88,11 @@ static unsigned short * const port_mux[] = {
 
 static const
 u8 pmux_offset[][16] = {
-#  if defined(BF527_FAMILY)
+#  if defined(CONFIG_BF52x)
        { 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 4, 6, 8, 8, 10, 10 }, /* PORTF */
        { 0, 0, 0, 0, 0, 2, 2, 4, 4, 6, 8, 10, 10, 10, 12, 12 }, /* PORTG */
        { 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 4, 4, 4, 4, 4 }, /* PORTH */
-#  elif defined(BF518_FAMILY)
+#  elif defined(CONFIG_BF51x)
        { 0, 2, 2, 2, 2, 2, 2, 4, 6, 6, 6, 8, 8, 8, 8, 10 }, /* PORTF */
        { 0, 0, 0, 2, 4, 6, 6, 6, 8, 10, 10, 12, 14, 14, 14, 14 }, /* PORTG */
        { 0, 0, 0, 0, 2, 2, 4, 6, 10, 10, 10, 10, 10, 10, 10, 10 }, /* PORTH */
@@ -121,6 +100,12 @@ u8 pmux_offset[][16] = {
 };
 # endif
 
+#elif defined(BF538_FAMILY)
+static unsigned short * const port_fer[] = {
+       (unsigned short *) PORTCIO_FER,
+       (unsigned short *) PORTDIO_FER,
+       (unsigned short *) PORTEIO_FER,
+};
 #endif
 
 static unsigned short reserved_gpio_map[GPIO_BANK_NUM];
@@ -139,7 +124,7 @@ static struct gpio_port_s gpio_bank_saved[GPIO_BANK_NUM];
 
 inline int check_gpio(unsigned gpio)
 {
-#if defined(BF548_FAMILY)
+#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)
@@ -184,16 +169,37 @@ static int cmp_label(unsigned short ident, const char *label)
 
 static void port_setup(unsigned gpio, unsigned short usage)
 {
+#if defined(BF538_FAMILY)
+       /*
+        * BF538/9 Port C,D and E are special.
+        * Inverted PORT_FER polarity on CDE and no PORF_FER on F
+        * Regular PORT F GPIOs are handled here, CDE are exclusively
+        * managed by GPIOLIB
+        */
+
+       if (gpio < MAX_BLACKFIN_GPIOS || gpio >= MAX_RESOURCES)
+               return;
+
+       gpio -= MAX_BLACKFIN_GPIOS;
+
+       if (usage == GPIO_USAGE)
+               *port_fer[gpio_bank(gpio)] |= gpio_bit(gpio);
+       else
+               *port_fer[gpio_bank(gpio)] &= ~gpio_bit(gpio);
+       SSYNC();
+       return;
+#endif
+
        if (check_gpio(gpio))
                return;
 
-#if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY)
+#if defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x)
        if (usage == GPIO_USAGE)
                *port_fer[gpio_bank(gpio)] &= ~gpio_bit(gpio);
        else
                *port_fer[gpio_bank(gpio)] |= gpio_bit(gpio);
        SSYNC();
-#elif defined(BF548_FAMILY)
+#elif defined(CONFIG_BF54x)
        if (usage == GPIO_USAGE)
                gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio);
        else
@@ -273,7 +279,7 @@ static void portmux_setup(unsigned short per)
                }
        }
 }
-#elif defined(BF548_FAMILY)
+#elif defined(CONFIG_BF54x)
 inline void portmux_setup(unsigned short per)
 {
        u32 pmux;
@@ -297,7 +303,7 @@ inline u16 get_portmux(unsigned short per)
 
        return (pmux >> (2 * gpio_sub_n(ident)) & 0x3);
 }
-#elif defined(BF527_FAMILY) || defined(BF518_FAMILY)
+#elif defined(CONFIG_BF52x) || defined(CONFIG_BF51x)
 inline void portmux_setup(unsigned short per)
 {
        u16 pmux, ident = P_IDENT(per), function = P_FUNCT2MUX(per);
@@ -313,16 +319,7 @@ inline void portmux_setup(unsigned short per)
 # define portmux_setup(...)  do { } while (0)
 #endif
 
-static int __init bfin_gpio_init(void)
-{
-       printk(KERN_INFO "Blackfin GPIO Controller\n");
-
-       return 0;
-}
-arch_initcall(bfin_gpio_init);
-
-
-#ifndef BF548_FAMILY
+#ifndef CONFIG_BF54x
 /***********************************************************
 *
 * FUNCTIONS: Blackfin General Purpose Ports Access Functions
@@ -478,9 +475,7 @@ GET_GPIO_P(maskb)
 
 
 #ifdef CONFIG_PM
-
 static unsigned short wakeup_map[GPIO_BANK_NUM];
-static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS];
 
 static const unsigned int sic_iwr_irqs[] = {
 #if defined(BF533_FAMILY)
@@ -489,7 +484,7 @@ static const unsigned int sic_iwr_irqs[] = {
        IRQ_PROG_INTB, IRQ_PORTG_INTB, IRQ_MAC_TX
 #elif defined(BF538_FAMILY)
        IRQ_PORTF_INTB
-#elif defined(BF527_FAMILY) || defined(BF518_FAMILY)
+#elif defined(CONFIG_BF52x) || defined(CONFIG_BF51x)
        IRQ_PORTF_INTB, IRQ_PORTG_INTB, IRQ_PORTH_INTB
 #elif defined(BF561_FAMILY)
        IRQ_PROG0_INTB, IRQ_PROG1_INTB, IRQ_PROG2_INTB
@@ -517,112 +512,26 @@ static const unsigned int sic_iwr_irqs[] = {
 *************************************************************
 * MODIFICATION HISTORY :
 **************************************************************/
-int gpio_pm_wakeup_request(unsigned gpio, unsigned char type)
-{
-       unsigned long flags;
-
-       if ((check_gpio(gpio) < 0) || !type)
-               return -EINVAL;
-
-       local_irq_save_hw(flags);
-       wakeup_map[gpio_bank(gpio)] |= gpio_bit(gpio);
-       wakeup_flags_map[gpio] = type;
-       local_irq_restore_hw(flags);
-
-       return 0;
-}
-EXPORT_SYMBOL(gpio_pm_wakeup_request);
-
-void gpio_pm_wakeup_free(unsigned gpio)
+int gpio_pm_wakeup_ctrl(unsigned gpio, unsigned ctrl)
 {
        unsigned long flags;
 
        if (check_gpio(gpio) < 0)
-               return;
+               return -EINVAL;
 
        local_irq_save_hw(flags);
-
-       wakeup_map[gpio_bank(gpio)] &= ~gpio_bit(gpio);
-
-       local_irq_restore_hw(flags);
-}
-EXPORT_SYMBOL(gpio_pm_wakeup_free);
-
-static int bfin_gpio_wakeup_type(unsigned gpio, unsigned char type)
-{
-       port_setup(gpio, GPIO_USAGE);
-       set_gpio_dir(gpio, 0);
-       set_gpio_inen(gpio, 1);
-
-       if (type & (PM_WAKE_RISING | PM_WAKE_FALLING))
-               set_gpio_edge(gpio, 1);
-        else
-               set_gpio_edge(gpio, 0);
-
-       if ((type & (PM_WAKE_BOTH_EDGES)) == (PM_WAKE_BOTH_EDGES))
-               set_gpio_both(gpio, 1);
+       if (ctrl)
+               wakeup_map[gpio_bank(gpio)] |= gpio_bit(gpio);
        else
-               set_gpio_both(gpio, 0);
+               wakeup_map[gpio_bank(gpio)] &= ~gpio_bit(gpio);
 
-       if ((type & (PM_WAKE_FALLING | PM_WAKE_LOW)))
-               set_gpio_polar(gpio, 1);
-       else
-               set_gpio_polar(gpio, 0);
-
-       SSYNC();
-
-       return 0;
-}
-
-u32 bfin_pm_standby_setup(void)
-{
-       u16 bank, mask, i, gpio;
-
-       for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
-               mask = wakeup_map[gpio_bank(i)];
-               bank = gpio_bank(i);
-
-               gpio_bank_saved[bank].maskb = gpio_array[bank]->maskb;
-               gpio_array[bank]->maskb = 0;
-
-               if (mask) {
-#if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY)
-                       gpio_bank_saved[bank].fer   = *port_fer[bank];
-#endif
-                       gpio_bank_saved[bank].inen  = gpio_array[bank]->inen;
-                       gpio_bank_saved[bank].polar = gpio_array[bank]->polar;
-                       gpio_bank_saved[bank].dir   = gpio_array[bank]->dir;
-                       gpio_bank_saved[bank].edge  = gpio_array[bank]->edge;
-                       gpio_bank_saved[bank].both  = gpio_array[bank]->both;
-                       gpio_bank_saved[bank].reserved =
-                                               reserved_gpio_map[bank];
-
-                       gpio = i;
-
-                       while (mask) {
-                               if ((mask & 1) && (wakeup_flags_map[gpio] !=
-                                       PM_WAKE_IGNORE)) {
-                                       reserved_gpio_map[gpio_bank(gpio)] |=
-                                                       gpio_bit(gpio);
-                                       bfin_gpio_wakeup_type(gpio,
-                                               wakeup_flags_map[gpio]);
-                                       set_gpio_data(gpio, 0); /*Clear*/
-                               }
-                               gpio++;
-                               mask >>= 1;
-                       }
-
-                       bfin_internal_set_wake(sic_iwr_irqs[bank], 1);
-                       gpio_array[bank]->maskb_set = wakeup_map[gpio_bank(i)];
-               }
-       }
-
-       AWA_DUMMY_READ(maskb_set);
+       set_gpio_maskb(gpio, ctrl);
+       local_irq_restore_hw(flags);
 
        return 0;
 }
 
-void bfin_pm_standby_restore(void)
+int bfin_pm_standby_ctrl(unsigned ctrl)
 {
        u16 bank, mask, i;
 
@@ -630,24 +539,10 @@ void bfin_pm_standby_restore(void)
                mask = wakeup_map[gpio_bank(i)];
                bank = gpio_bank(i);
 
-               if (mask) {
-#if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY)
-                       *port_fer[bank]         = gpio_bank_saved[bank].fer;
-#endif
-                       gpio_array[bank]->inen  = gpio_bank_saved[bank].inen;
-                       gpio_array[bank]->dir   = gpio_bank_saved[bank].dir;
-                       gpio_array[bank]->polar = gpio_bank_saved[bank].polar;
-                       gpio_array[bank]->edge  = gpio_bank_saved[bank].edge;
-                       gpio_array[bank]->both  = gpio_bank_saved[bank].both;
-
-                       reserved_gpio_map[bank] =
-                                       gpio_bank_saved[bank].reserved;
-                       bfin_internal_set_wake(sic_iwr_irqs[bank], 0);
-               }
-
-               gpio_array[bank]->maskb = gpio_bank_saved[bank].maskb;
+               if (mask)
+                       bfin_internal_set_wake(sic_iwr_irqs[bank], ctrl);
        }
-       AWA_DUMMY_READ(maskb);
+       return 0;
 }
 
 void bfin_gpio_pm_hibernate_suspend(void)
@@ -657,9 +552,9 @@ void bfin_gpio_pm_hibernate_suspend(void)
        for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
                bank = gpio_bank(i);
 
-#if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY)
+#if defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x)
                gpio_bank_saved[bank].fer = *port_fer[bank];
-#if defined(BF527_FAMILY) || defined(BF518_FAMILY)
+#if defined(CONFIG_BF52x) || defined(CONFIG_BF51x)
                gpio_bank_saved[bank].mux = *port_mux[bank];
 #else
                if (bank == 0)
@@ -685,8 +580,8 @@ void bfin_gpio_pm_hibernate_restore(void)
        for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
                bank = gpio_bank(i);
 
-#if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY)
-#if defined(BF527_FAMILY) || defined(BF518_FAMILY)
+#if defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x)
+#if defined(CONFIG_BF52x) || defined(CONFIG_BF51x)
                *port_mux[bank] = gpio_bank_saved[bank].mux;
 #else
                if (bank == 0)
@@ -695,14 +590,12 @@ void bfin_gpio_pm_hibernate_restore(void)
                *port_fer[bank] = gpio_bank_saved[bank].fer;
 #endif
                gpio_array[bank]->inen  = gpio_bank_saved[bank].inen;
+               gpio_array[bank]->data_set = gpio_bank_saved[bank].data
+                                               & gpio_bank_saved[bank].dir;
                gpio_array[bank]->dir   = gpio_bank_saved[bank].dir;
                gpio_array[bank]->polar = gpio_bank_saved[bank].polar;
                gpio_array[bank]->edge  = gpio_bank_saved[bank].edge;
                gpio_array[bank]->both  = gpio_bank_saved[bank].both;
-
-               gpio_array[bank]->data_set = gpio_bank_saved[bank].data
-                                               | gpio_bank_saved[bank].dir;
-
                gpio_array[bank]->maska = gpio_bank_saved[bank].maska;
        }
        AWA_DUMMY_READ(maska);
@@ -710,19 +603,14 @@ void bfin_gpio_pm_hibernate_restore(void)
 
 
 #endif
-#else /* BF548_FAMILY */
+#else /* CONFIG_BF54x */
 #ifdef CONFIG_PM
 
-u32 bfin_pm_standby_setup(void)
+int bfin_pm_standby_ctrl(unsigned ctrl)
 {
        return 0;
 }
 
-void bfin_pm_standby_restore(void)
-{
-
-}
-
 void bfin_gpio_pm_hibernate_suspend(void)
 {
        int i, bank;
@@ -733,7 +621,6 @@ void bfin_gpio_pm_hibernate_suspend(void)
                gpio_bank_saved[bank].fer = gpio_array[bank]->port_fer;
                gpio_bank_saved[bank].mux = gpio_array[bank]->port_mux;
                gpio_bank_saved[bank].data = gpio_array[bank]->data;
-               gpio_bank_saved[bank].data = gpio_array[bank]->data;
                gpio_bank_saved[bank].inen = gpio_array[bank]->inen;
                gpio_bank_saved[bank].dir = gpio_array[bank]->dir_set;
        }
@@ -762,7 +649,7 @@ unsigned short get_gpio_dir(unsigned gpio)
 }
 EXPORT_SYMBOL(get_gpio_dir);
 
-#endif /* BF548_FAMILY */
+#endif /* CONFIG_BF54x */
 
 /***********************************************************
 *
@@ -795,6 +682,8 @@ int peripheral_request(unsigned short per, const char *label)
        if (!(per & P_DEFINED))
                return -ENODEV;
 
+       BUG_ON(ident >= MAX_RESOURCES);
+
        local_irq_save_hw(flags);
 
        /* If a pin can be muxed as either GPIO or peripheral, make
@@ -802,7 +691,8 @@ int peripheral_request(unsigned short per, const char *label)
         */
        if (unlikely(!check_gpio(ident) &&
            reserved_gpio_map[gpio_bank(ident)] & gpio_bit(ident))) {
-               dump_stack();
+               if (system_state == SYSTEM_BOOTING)
+                       dump_stack();
                printk(KERN_ERR
                       "%s: Peripheral %d is already reserved as GPIO by %s !\n",
                       __func__, ident, get_label(ident));
@@ -817,7 +707,7 @@ int peripheral_request(unsigned short per, const char *label)
                 * be requested and used by several drivers
                 */
 
-#ifdef BF548_FAMILY
+#ifdef CONFIG_BF54x
                if (!((per & P_MAYSHARE) && get_portmux(per) == P_FUNCT2MUX(per))) {
 #else
                if (!(per & P_MAYSHARE)) {
@@ -830,7 +720,8 @@ int peripheral_request(unsigned short per, const char *label)
                        if (cmp_label(ident, label) == 0)
                                goto anyway;
 
-                       dump_stack();
+                       if (system_state == SYSTEM_BOOTING)
+                               dump_stack();
                        printk(KERN_ERR
                               "%s: Peripheral %d function %d is already reserved by %s !\n",
                               __func__, ident, P_FUNCT2MUX(per), get_label(ident));
@@ -946,14 +837,16 @@ int bfin_gpio_request(unsigned gpio, const char *label)
        }
 
        if (unlikely(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
-               dump_stack();
+               if (system_state == SYSTEM_BOOTING)
+                       dump_stack();
                printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved by %s !\n",
                       gpio, get_label(gpio));
                local_irq_restore_hw(flags);
                return -EBUSY;
        }
        if (unlikely(reserved_peri_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
-               dump_stack();
+               if (system_state == SYSTEM_BOOTING)
+                       dump_stack();
                printk(KERN_ERR
                       "bfin-gpio: GPIO %d is already reserved as Peripheral by %s !\n",
                       gpio, get_label(gpio));
@@ -964,7 +857,7 @@ int bfin_gpio_request(unsigned gpio, const char *label)
                printk(KERN_NOTICE "bfin-gpio: GPIO %d is already reserved as gpio-irq!"
                       " (Documentation/blackfin/bfin-gpio-notes.txt)\n", gpio);
        }
-#ifndef BF548_FAMILY
+#ifndef CONFIG_BF54x
        else {  /* Reset POLAR setting when acquiring a gpio for the first time */
                set_gpio_polar(gpio, 0);
        }
@@ -993,7 +886,8 @@ void bfin_gpio_free(unsigned gpio)
        local_irq_save_hw(flags);
 
        if (unlikely(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))) {
-               dump_stack();
+               if (system_state == SYSTEM_BOOTING)
+                       dump_stack();
                gpio_error(gpio);
                local_irq_restore_hw(flags);
                return;
@@ -1007,6 +901,76 @@ void bfin_gpio_free(unsigned gpio)
 }
 EXPORT_SYMBOL(bfin_gpio_free);
 
+#ifdef BFIN_SPECIAL_GPIO_BANKS
+static unsigned short reserved_special_gpio_map[gpio_bank(MAX_RESOURCES)];
+
+int bfin_special_gpio_request(unsigned gpio, const char *label)
+{
+       unsigned long flags;
+
+       local_irq_save_hw(flags);
+
+       /*
+        * Allow that the identical GPIO can
+        * be requested from the same driver twice
+        * Do nothing and return -
+        */
+
+       if (cmp_label(gpio, label) == 0) {
+               local_irq_restore_hw(flags);
+               return 0;
+       }
+
+       if (unlikely(reserved_special_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
+               local_irq_restore_hw(flags);
+               printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved by %s !\n",
+                      gpio, get_label(gpio));
+
+               return -EBUSY;
+       }
+       if (unlikely(reserved_peri_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
+               local_irq_restore_hw(flags);
+               printk(KERN_ERR
+                      "bfin-gpio: GPIO %d is already reserved as Peripheral by %s !\n",
+                      gpio, get_label(gpio));
+
+               return -EBUSY;
+       }
+
+       reserved_special_gpio_map[gpio_bank(gpio)] |= gpio_bit(gpio);
+       reserved_peri_map[gpio_bank(gpio)] |= gpio_bit(gpio);
+
+       set_label(gpio, label);
+       local_irq_restore_hw(flags);
+       port_setup(gpio, GPIO_USAGE);
+
+       return 0;
+}
+EXPORT_SYMBOL(bfin_special_gpio_request);
+
+void bfin_special_gpio_free(unsigned gpio)
+{
+       unsigned long flags;
+
+       might_sleep();
+
+       local_irq_save_hw(flags);
+
+       if (unlikely(!(reserved_special_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))) {
+               gpio_error(gpio);
+               local_irq_restore_hw(flags);
+               return;
+       }
+
+       reserved_special_gpio_map[gpio_bank(gpio)] &= ~gpio_bit(gpio);
+       reserved_peri_map[gpio_bank(gpio)] &= ~gpio_bit(gpio);
+       set_label(gpio, "free");
+       local_irq_restore_hw(flags);
+}
+EXPORT_SYMBOL(bfin_special_gpio_free);
+#endif
+
+
 int bfin_gpio_irq_request(unsigned gpio, const char *label)
 {
        unsigned long flags;
@@ -1016,16 +980,9 @@ int bfin_gpio_irq_request(unsigned gpio, const char *label)
 
        local_irq_save_hw(flags);
 
-       if (unlikely(reserved_gpio_irq_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
-               dump_stack();
-               printk(KERN_ERR
-                      "bfin-gpio: GPIO %d is already reserved as gpio-irq !\n",
-                      gpio);
-               local_irq_restore_hw(flags);
-               return -EBUSY;
-       }
        if (unlikely(reserved_peri_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
-               dump_stack();
+               if (system_state == SYSTEM_BOOTING)
+                       dump_stack();
                printk(KERN_ERR
                       "bfin-gpio: GPIO %d is already reserved as Peripheral by %s !\n",
                       gpio, get_label(gpio));
@@ -1057,7 +1014,8 @@ void bfin_gpio_irq_free(unsigned gpio)
        local_irq_save_hw(flags);
 
        if (unlikely(!(reserved_gpio_irq_map[gpio_bank(gpio)] & gpio_bit(gpio)))) {
-               dump_stack();
+               if (system_state == SYSTEM_BOOTING)
+                       dump_stack();
                gpio_error(gpio);
                local_irq_restore_hw(flags);
                return;
@@ -1072,7 +1030,7 @@ void bfin_gpio_irq_free(unsigned gpio)
 
 static inline void __bfin_gpio_direction_input(unsigned gpio)
 {
-#ifdef BF548_FAMILY
+#ifdef CONFIG_BF54x
        gpio_array[gpio_bank(gpio)]->dir_clear = gpio_bit(gpio);
 #else
        gpio_array[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio);
@@ -1100,13 +1058,13 @@ EXPORT_SYMBOL(bfin_gpio_direction_input);
 
 void bfin_gpio_irq_prepare(unsigned gpio)
 {
-#ifdef BF548_FAMILY
+#ifdef CONFIG_BF54x
        unsigned long flags;
 #endif
 
        port_setup(gpio, GPIO_USAGE);
 
-#ifdef BF548_FAMILY
+#ifdef CONFIG_BF54x
        local_irq_save_hw(flags);
        __bfin_gpio_direction_input(gpio);
        local_irq_restore_hw(flags);
@@ -1135,7 +1093,7 @@ int bfin_gpio_direction_output(unsigned gpio, int value)
 
        gpio_array[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio);
        gpio_set_value(gpio, value);
-#ifdef BF548_FAMILY
+#ifdef CONFIG_BF54x
        gpio_array[gpio_bank(gpio)]->dir_set = gpio_bit(gpio);
 #else
        gpio_array[gpio_bank(gpio)]->dir |= gpio_bit(gpio);
@@ -1150,7 +1108,7 @@ EXPORT_SYMBOL(bfin_gpio_direction_output);
 
 int bfin_gpio_get_value(unsigned gpio)
 {
-#ifdef BF548_FAMILY
+#ifdef CONFIG_BF54x
        return (1 & (gpio_array[gpio_bank(gpio)]->data >> gpio_sub_n(gpio)));
 #else
        unsigned long flags;
@@ -1224,44 +1182,50 @@ __initcall(gpio_register_proc);
 #endif
 
 #ifdef CONFIG_GPIOLIB
-int bfin_gpiolib_direction_input(struct gpio_chip *chip, unsigned gpio)
+static int bfin_gpiolib_direction_input(struct gpio_chip *chip, unsigned gpio)
 {
        return bfin_gpio_direction_input(gpio);
 }
 
-int bfin_gpiolib_direction_output(struct gpio_chip *chip, unsigned gpio, int level)
+static int bfin_gpiolib_direction_output(struct gpio_chip *chip, unsigned gpio, int level)
 {
        return bfin_gpio_direction_output(gpio, level);
 }
 
-int bfin_gpiolib_get_value(struct gpio_chip *chip, unsigned gpio)
+static int bfin_gpiolib_get_value(struct gpio_chip *chip, unsigned gpio)
 {
        return bfin_gpio_get_value(gpio);
 }
 
-void bfin_gpiolib_set_value(struct gpio_chip *chip, unsigned gpio, int value)
+static void bfin_gpiolib_set_value(struct gpio_chip *chip, unsigned gpio, int value)
 {
        return bfin_gpio_set_value(gpio, value);
 }
 
-int bfin_gpiolib_gpio_request(struct gpio_chip *chip, unsigned gpio)
+static int bfin_gpiolib_gpio_request(struct gpio_chip *chip, unsigned gpio)
 {
        return bfin_gpio_request(gpio, chip->label);
 }
 
-void bfin_gpiolib_gpio_free(struct gpio_chip *chip, unsigned gpio)
+static void bfin_gpiolib_gpio_free(struct gpio_chip *chip, unsigned gpio)
 {
        return bfin_gpio_free(gpio);
 }
 
+static int bfin_gpiolib_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
+{
+       return gpio + GPIO_IRQ_BASE;
+}
+
 static struct gpio_chip bfin_chip = {
-       .label                  = "Blackfin-GPIOlib",
+       .label                  = "BFIN-GPIO",
        .direction_input        = bfin_gpiolib_direction_input,
        .get                    = bfin_gpiolib_get_value,
        .direction_output       = bfin_gpiolib_direction_output,
        .set                    = bfin_gpiolib_set_value,
        .request                = bfin_gpiolib_gpio_request,
        .free                   = bfin_gpiolib_gpio_free,
+       .to_irq                 = bfin_gpiolib_gpio_to_irq,
        .base                   = 0,
        .ngpio                  = MAX_BLACKFIN_GPIOS,
 };