Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=8baf560b4c901fb554d15e056aaa7f34b2345be5
Commit:     8baf560b4c901fb554d15e056aaa7f34b2345be5
Parent:     471b9a6c7304d5f59503d111e71e60a7e19fb9a0
Author:     Michael Hennerich <[EMAIL PROTECTED]>
AuthorDate: Mon Dec 24 18:51:34 2007 +0800
Committer:  Bryan Wu <[EMAIL PROTECTED]>
CommitDate: Mon Dec 24 18:51:34 2007 +0800

    [Blackfin] arch: Enable both edge triggered GPIO IRQs on BF54x and use 
irq_to_gpio()
    
    Signed-off-by: Michael Hennerich <[EMAIL PROTECTED]>
    Signed-off-by: Bryan Wu <[EMAIL PROTECTED]>
---
 arch/blackfin/mach-common/ints-priority-sc.c |   67 ++++++++++++++++++--------
 1 files changed, 46 insertions(+), 21 deletions(-)

diff --git a/arch/blackfin/mach-common/ints-priority-sc.c 
b/arch/blackfin/mach-common/ints-priority-sc.c
index 36ef4d1..dec42ac 100644
--- a/arch/blackfin/mach-common/ints-priority-sc.c
+++ b/arch/blackfin/mach-common/ints-priority-sc.c
@@ -483,6 +483,10 @@ static void bfin_demux_gpio_irq(unsigned int intb_irq,
 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;
@@ -549,13 +553,20 @@ void init_pint_lut(void)
 
 }
 
-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();
 }
 
@@ -565,6 +576,13 @@ static void bfin_gpio_mask_ack_irq(unsigned int irq)
        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();
@@ -593,7 +611,7 @@ static unsigned int bfin_gpio_irq_startup(unsigned int irq)
 {
        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) {
@@ -618,9 +636,11 @@ static unsigned int bfin_gpio_irq_startup(unsigned int irq)
 
 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)
@@ -628,7 +648,7 @@ 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);
@@ -660,28 +680,33 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned 
int type)
 
        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;
 }
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to