static unsigned char irq2pint_lut[NR_PINTS];
 static unsigned char pint2irq_lut[NR_PINT_SYS_IRQS * NR_PINT_BITS];
 
+static unsigned int gpio_both_edge_triggered[NR_PINT_SYS_IRQS];
+static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)];
+
+
 struct pin_int_t {
        unsigned int mask_set;
        unsigned int mask_clear;
 
 }
 
-static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)];
-
 static void bfin_gpio_ack_irq(unsigned int irq)
 {
        u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
+       u32 pintbit = PINT_BIT(pint_val);
+       u8 bank = PINT_2_BANK(pint_val);
+
+       if (unlikely(gpio_both_edge_triggered[bank] & pintbit)) {
+               if (pint[bank]->invert_set & pintbit)
+                       pint[bank]->invert_clear = pintbit;
+               else
+                       pint[bank]->invert_set = pintbit;
+       }
+       pint[bank]->request = pintbit;
 
-       pint[PINT_2_BANK(pint_val)]->request = PINT_BIT(pint_val);
        SSYNC();
 }
 
        u32 pintbit = PINT_BIT(pint_val);
        u8 bank = PINT_2_BANK(pint_val);
 
+       if (unlikely(gpio_both_edge_triggered[bank] & pintbit)) {
+               if (pint[bank]->invert_set & pintbit)
+                       pint[bank]->invert_clear = pintbit;
+               else
+                       pint[bank]->invert_set = pintbit;
+       }
+
        pint[bank]->request = pintbit;
        pint[bank]->mask_clear = pintbit;
        SSYNC();
 {
        unsigned int ret;
        char buf[8];
-       u16 gpionr = irq - IRQ_PA0;
+       u16 gpionr = irq_to_gpio(irq);
        u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
 
        if (pint_val == IRQ_NOT_AVAIL) {
 
 static void bfin_gpio_irq_shutdown(unsigned int irq)
 {
+       u16 gpionr = irq_to_gpio(irq);
+
        bfin_gpio_mask_irq(irq);
-       gpio_free(irq - IRQ_PA0);
-       gpio_enabled[gpio_bank(irq - IRQ_PA0)] &= ~gpio_bit(irq - IRQ_PA0);
+       gpio_free(gpionr);
+       gpio_enabled[gpio_bank(gpionr)] &= ~gpio_bit(gpionr);
 }
 
 static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
 
        unsigned int ret;
        char buf[8];
-       u16 gpionr = irq - IRQ_PA0;
+       u16 gpionr = irq_to_gpio(irq);
        u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
        u32 pintbit = PINT_BIT(pint_val);
        u8 bank = PINT_2_BANK(pint_val);
 
        gpio_direction_input(gpionr);
 
-       if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
-               pint[bank]->edge_set = pintbit;
-       } else {
-               pint[bank]->edge_clear = pintbit;
-       }
-
        if ((type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW)))
                pint[bank]->invert_set = pintbit;       /* low or falling edge denoted by one */
        else
-               pint[bank]->invert_set = pintbit;       /* high or rising edge denoted by zero */
+               pint[bank]->invert_clear = pintbit;     /* high or rising edge denoted by zero */
 
-       if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
-               pint[bank]->invert_set = pintbit;
-       else
-               pint[bank]->invert_set = pintbit;
+       if ((type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
+           == (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
 
-       SSYNC();
+               gpio_both_edge_triggered[bank] |= pintbit;
 
-       if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
+               if (gpio_get_value(gpionr))
+                       pint[bank]->invert_set = pintbit;
+               else
+                       pint[bank]->invert_clear = pintbit;
+       } else {
+               gpio_both_edge_triggered[bank] &= ~pintbit;
+       }
+
+       if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
+               pint[bank]->edge_set = pintbit;
                set_irq_handler(irq, handle_edge_irq);
-       else
+       } else {
+               pint[bank]->edge_clear = pintbit;
                set_irq_handler(irq, handle_level_irq);
+       }
+
+       SSYNC();
 
        return 0;
 }