Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=7ca722533979d47563e75a40c86c405153818b83
Commit:     7ca722533979d47563e75a40c86c405153818b83
Parent:     4e9f9fd5148004b983b29e15de66918e71da56c0
Author:     Herbert Valerio Riedel <[EMAIL PROTECTED]>
AuthorDate: Mon Nov 26 18:45:59 2007 +0100
Committer:  Russell King <[EMAIL PROTECTED]>
CommitDate: Sat Jan 26 14:37:31 2008 +0000

    [ARM] 4669/1: ep93xx: simplify GPIO code and cleanups
    
    This patch renumbers the (virtual) GPIO line numbering to have all
    irq-capable gpio lines <= EP93XX_GPIO_LINE_MAX_IRQ by swapping the
    port f range with the port c range; This simplifies code such as
    
     #define IRQ_EP93XX_GPIO(x)  (64 + (((x) + (((x) >> 2) & 8)) & 0x1f))
    
    or
    
     if (line >= 0 && line < 16) {
        /* Port A/B */
     } else if (line >= 40 && line < 48) {
        /* Port F */
     }
    
    considerably; in addition to the renumbering this patch also
    introduces macro constants EP93XX_GPIO_LINE_MAX_IRQ and
    EP93XX_GPIO_LINE_MAX, and replaces most magic numbers by those and
    invocations of gpio_to_irq()/irq_to_gpio().
    
    Signed-off-by: Herbert Valerio Riedel <[EMAIL PROTECTED]>
    Acked-by: Lennert Buytenhek <[EMAIL PROTECTED]>
    Signed-off-by: Russell King <[EMAIL PROTECTED]>
---
 arch/arm/mach-ep93xx/core.c        |  147 +++++++++++++++++-------------------
 include/asm-arm/arch-ep93xx/gpio.h |   27 +++----
 include/asm-arm/arch-ep93xx/irqs.h |    6 --
 3 files changed, 82 insertions(+), 98 deletions(-)

diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 8a73406..58957d7 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -157,35 +157,35 @@ static unsigned char gpio_int_enabled[3];
 static unsigned char gpio_int_type1[3];
 static unsigned char gpio_int_type2[3];
 
-static void update_gpio_int_params(int abf)
+/* Port ordering is: A B F */
+static const u8 int_type1_register_offset[3]   = { 0x90, 0xac, 0x4c };
+static const u8 int_type2_register_offset[3]   = { 0x94, 0xb0, 0x50 };
+static const u8 eoi_register_offset[3]         = { 0x98, 0xb4, 0x54 };
+static const u8 int_en_register_offset[3]      = { 0x9c, 0xb8, 0x5c };
+
+static void update_gpio_int_params(unsigned port)
 {
-       if (abf == 0) {
-               __raw_writeb(0, EP93XX_GPIO_A_INT_ENABLE);
-               __raw_writeb(gpio_int_type2[0], EP93XX_GPIO_A_INT_TYPE2);
-               __raw_writeb(gpio_int_type1[0], EP93XX_GPIO_A_INT_TYPE1);
-               __raw_writeb(gpio_int_unmasked[0] & gpio_int_enabled[0], 
EP93XX_GPIO_A_INT_ENABLE);
-       } else if (abf == 1) {
-               __raw_writeb(0, EP93XX_GPIO_B_INT_ENABLE);
-               __raw_writeb(gpio_int_type2[1], EP93XX_GPIO_B_INT_TYPE2);
-               __raw_writeb(gpio_int_type1[1], EP93XX_GPIO_B_INT_TYPE1);
-               __raw_writeb(gpio_int_unmasked[1] & gpio_int_enabled[1], 
EP93XX_GPIO_B_INT_ENABLE);
-       } else if (abf == 2) {
-               __raw_writeb(0, EP93XX_GPIO_F_INT_ENABLE);
-               __raw_writeb(gpio_int_type2[2], EP93XX_GPIO_F_INT_TYPE2);
-               __raw_writeb(gpio_int_type1[2], EP93XX_GPIO_F_INT_TYPE1);
-               __raw_writeb(gpio_int_unmasked[2] & gpio_int_enabled[2], 
EP93XX_GPIO_F_INT_ENABLE);
-       } else {
-               BUG();
-       }
-}
+       BUG_ON(port > 2);
 
+       __raw_writeb(0, EP93XX_GPIO_REG(int_en_register_offset[port]));
+
+       __raw_writeb(gpio_int_type2[port],
+               EP93XX_GPIO_REG(int_type2_register_offset[port]));
+
+       __raw_writeb(gpio_int_type1[port],
+               EP93XX_GPIO_REG(int_type1_register_offset[port]));
+
+       __raw_writeb(gpio_int_unmasked[port] & gpio_int_enabled[port],
+               EP93XX_GPIO_REG(int_en_register_offset[port]));
+}
 
-static unsigned char data_register_offset[8] = {
-       0x00, 0x04, 0x08, 0x0c, 0x20, 0x30, 0x38, 0x40,
+/* Port ordering is: A B F D E C G H */
+static const u8 data_register_offset[8] = {
+       0x00, 0x04, 0x30, 0x0c, 0x20, 0x08, 0x38, 0x40,
 };
 
-static unsigned char data_direction_register_offset[8] = {
-       0x10, 0x14, 0x18, 0x1c, 0x24, 0x34, 0x3c, 0x44,
+static const u8 data_direction_register_offset[8] = {
+       0x10, 0x14, 0x34, 0x1c, 0x24, 0x18, 0x3c, 0x44,
 };
 
 static void ep93xx_gpio_set_direction(unsigned line, int direction)
@@ -199,14 +199,10 @@ static void ep93xx_gpio_set_direction(unsigned line, int 
direction)
 
        local_irq_save(flags);
        if (direction == GPIO_OUT) {
-               if (line >= 0 && line < 16) {
-                       /* Port A/B.  */
+               if (line >= 0 && line <= EP93XX_GPIO_LINE_MAX_IRQ) {
+                       /* Port A/B/F */
                        gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7));
                        update_gpio_int_params(line >> 3);
-               } else if (line >= 40 && line < 48) {
-                       /* Port F.  */
-                       gpio_int_unmasked[2] &= ~(1 << (line & 7));
-                       update_gpio_int_params(2);
                }
 
                v = __raw_readb(data_direction_register);
@@ -228,7 +224,7 @@ EXPORT_SYMBOL(gpio_line_config);
 
 int gpio_direction_input(unsigned gpio)
 {
-       if (gpio > EP93XX_GPIO_LINE_H(7))
+       if (gpio > EP93XX_GPIO_LINE_MAX)
                return -EINVAL;
 
        ep93xx_gpio_set_direction(gpio, GPIO_IN);
@@ -239,7 +235,7 @@ EXPORT_SYMBOL(gpio_direction_input);
 
 int gpio_direction_output(unsigned gpio, int value)
 {
-       if (gpio > EP93XX_GPIO_LINE_H(7))
+       if (gpio > EP93XX_GPIO_LINE_MAX)
                return -EINVAL;
 
        gpio_set_value(gpio, value);
@@ -290,47 +286,50 @@ static void ep93xx_gpio_ab_irq_handler(unsigned int irq, 
struct irq_desc *desc)
        status = __raw_readb(EP93XX_GPIO_A_INT_STATUS);
        for (i = 0; i < 8; i++) {
                if (status & (1 << i)) {
-                       desc = irq_desc + IRQ_EP93XX_GPIO(0) + i;
-                       desc_handle_irq(IRQ_EP93XX_GPIO(0) + i, desc);
+                       int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_A(0)) + i;
+                       desc = irq_desc + gpio_irq;
+                       desc_handle_irq(gpio_irq, desc);
                }
        }
 
        status = __raw_readb(EP93XX_GPIO_B_INT_STATUS);
        for (i = 0; i < 8; i++) {
                if (status & (1 << i)) {
-                       desc = irq_desc + IRQ_EP93XX_GPIO(8) + i;
-                       desc_handle_irq(IRQ_EP93XX_GPIO(8) + i, desc);
+                       int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_B(0)) + i;
+                       desc = irq_desc + gpio_irq;
+                       desc_handle_irq(gpio_irq, desc);
                }
        }
 }
 
 static void ep93xx_gpio_f_irq_handler(unsigned int irq, struct irq_desc *desc)
 {
-       int gpio_irq = IRQ_EP93XX_GPIO(16) + (((irq + 1) & 7) ^ 4);
+       /*
+        * map discontiguous hw irq range to continous sw irq range:
+        *
+        *  IRQ_EP93XX_GPIO{0..7}MUX -> gpio_to_irq(EP93XX_GPIO_LINE_F({0..7})
+        */
+       int port_f_idx = ((irq + 1) & 7) ^ 4; /* {19..22,47..50} -> {0..7} */
+       int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_F(0)) + port_f_idx;
 
        desc_handle_irq(gpio_irq, irq_desc + gpio_irq);
 }
 
 static void ep93xx_gpio_irq_mask_ack(unsigned int irq)
 {
-       int line = irq - IRQ_EP93XX_GPIO(0);
+       int line = irq_to_gpio(irq);
        int port = line >> 3;
+       int port_mask = 1 << (line & 7);
 
-       gpio_int_unmasked[port] &= ~(1 << (line & 7));
+       gpio_int_unmasked[port] &= ~port_mask;
        update_gpio_int_params(port);
 
-       if (port == 0) {
-               __raw_writel(1 << (line & 7), EP93XX_GPIO_A_INT_ACK);
-       } else if (port == 1) {
-               __raw_writel(1 << (line & 7), EP93XX_GPIO_B_INT_ACK);
-       } else if (port == 2) {
-               __raw_writel(1 << (line & 7), EP93XX_GPIO_F_INT_ACK);
-       }
+       __raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
 }
 
 static void ep93xx_gpio_irq_mask(unsigned int irq)
 {
-       int line = irq - IRQ_EP93XX_GPIO(0);
+       int line = irq_to_gpio(irq);
        int port = line >> 3;
 
        gpio_int_unmasked[port] &= ~(1 << (line & 7));
@@ -339,7 +338,7 @@ static void ep93xx_gpio_irq_mask(unsigned int irq)
 
 static void ep93xx_gpio_irq_unmask(unsigned int irq)
 {
-       int line = irq - IRQ_EP93XX_GPIO(0);
+       int line = irq_to_gpio(irq);
        int port = line >> 3;
 
        gpio_int_unmasked[port] |= 1 << (line & 7);
@@ -354,37 +353,30 @@ static void ep93xx_gpio_irq_unmask(unsigned int irq)
  */
 static int ep93xx_gpio_irq_type(unsigned int irq, unsigned int type)
 {
-       int port;
-       int line;
+       const int gpio = irq_to_gpio(irq);
+       const int port = gpio >> 3;
+       const int port_mask = 1 << (gpio & 7);
 
-       line = irq - IRQ_EP93XX_GPIO(0);
-       if (line >= 0 && line < 16) {
-               ep93xx_gpio_set_direction(line, GPIO_IN);
-       } else {
-               ep93xx_gpio_set_direction(EP93XX_GPIO_LINE_F(line-16), GPIO_IN);
-       }
-
-       port = line >> 3;
-       line &= 7;
+       ep93xx_gpio_set_direction(gpio, GPIO_IN);
 
        if (type & IRQT_RISING) {
-               gpio_int_enabled[port] |= 1 << line;
-               gpio_int_type1[port] |= 1 << line;
-               gpio_int_type2[port] |= 1 << line;
+               gpio_int_enabled[port] |= port_mask;
+               gpio_int_type1[port] |= port_mask;
+               gpio_int_type2[port] |= port_mask;
        } else if (type & IRQT_FALLING) {
-               gpio_int_enabled[port] |= 1 << line;
-               gpio_int_type1[port] |= 1 << line;
-               gpio_int_type2[port] &= ~(1 << line);
+               gpio_int_enabled[port] |= port_mask;
+               gpio_int_type1[port] |= port_mask;
+               gpio_int_type2[port] &= ~port_mask;
        } else if (type & IRQT_HIGH) {
-               gpio_int_enabled[port] |= 1 << line;
-               gpio_int_type1[port] &= ~(1 << line);
-               gpio_int_type2[port] |= 1 << line;
+               gpio_int_enabled[port] |= port_mask;
+               gpio_int_type1[port] &= ~port_mask;
+               gpio_int_type2[port] |= port_mask;
        } else if (type & IRQT_LOW) {
-               gpio_int_enabled[port] |= 1 << line;
-               gpio_int_type1[port] &= ~(1 << line);
-               gpio_int_type2[port] &= ~(1 << line);
+               gpio_int_enabled[port] |= port_mask;
+               gpio_int_type1[port] &= ~port_mask;
+               gpio_int_type2[port] &= ~port_mask;
        } else {
-               gpio_int_enabled[port] &= ~(1 << line);
+               gpio_int_enabled[port] &= ~port_mask;
        }
        update_gpio_int_params(port);
 
@@ -402,15 +394,16 @@ static struct irq_chip ep93xx_gpio_irq_chip = {
 
 void __init ep93xx_init_irq(void)
 {
-       int irq;
+       int gpio_irq;
 
        vic_init((void *)EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK);
        vic_init((void *)EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK);
 
-       for (irq = IRQ_EP93XX_GPIO(0); irq <= IRQ_EP93XX_GPIO(23); irq++) {
-               set_irq_chip(irq, &ep93xx_gpio_irq_chip);
-               set_irq_handler(irq, handle_level_irq);
-               set_irq_flags(irq, IRQF_VALID);
+       for (gpio_irq = gpio_to_irq(0);
+            gpio_irq <= gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ); ++gpio_irq) {
+               set_irq_chip(gpio_irq, &ep93xx_gpio_irq_chip);
+               set_irq_handler(gpio_irq, handle_level_irq);
+               set_irq_flags(gpio_irq, IRQF_VALID);
        }
 
        set_irq_chained_handler(IRQ_EP93XX_GPIO_AB, ep93xx_gpio_ab_irq_handler);
diff --git a/include/asm-arm/arch-ep93xx/gpio.h 
b/include/asm-arm/arch-ep93xx/gpio.h
index fc1e57d..cebb64b 100644
--- a/include/asm-arm/arch-ep93xx/gpio.h
+++ b/include/asm-arm/arch-ep93xx/gpio.h
@@ -28,7 +28,7 @@
 #define EP93XX_GPIO_LINE_EGPIO15       EP93XX_GPIO_LINE_B(7)
 
 /* GPIO port C.  */
-#define EP93XX_GPIO_LINE_C(x)          ((x) + 16)
+#define EP93XX_GPIO_LINE_C(x)          ((x) + 40)
 #define EP93XX_GPIO_LINE_ROW0          EP93XX_GPIO_LINE_C(0)
 #define EP93XX_GPIO_LINE_ROW1          EP93XX_GPIO_LINE_C(1)
 #define EP93XX_GPIO_LINE_ROW2          EP93XX_GPIO_LINE_C(2)
@@ -61,7 +61,7 @@
 #define EP93XX_GPIO_LINE_IDEDA2                EP93XX_GPIO_LINE_E(7)
 
 /* GPIO port F.  */
-#define EP93XX_GPIO_LINE_F(x)          ((x) + 40)
+#define EP93XX_GPIO_LINE_F(x)          ((x) + 16)
 #define EP93XX_GPIO_LINE_WP            EP93XX_GPIO_LINE_F(0)
 #define EP93XX_GPIO_LINE_MCCD1         EP93XX_GPIO_LINE_F(1)
 #define EP93XX_GPIO_LINE_MCCD2         EP93XX_GPIO_LINE_F(2)
@@ -93,11 +93,17 @@
 #define EP93XX_GPIO_LINE_DD6           EP93XX_GPIO_LINE_H(6)
 #define EP93XX_GPIO_LINE_DD7           EP93XX_GPIO_LINE_H(7)
 
+/* maximum value for gpio line identifiers */
+#define EP93XX_GPIO_LINE_MAX           EP93XX_GPIO_LINE_H(7)
+
+/* maximum value for irq capable line identifiers */
+#define EP93XX_GPIO_LINE_MAX_IRQ       EP93XX_GPIO_LINE_F(7)
+
 /* new generic GPIO API - see Documentation/gpio.txt */
 
 static inline int gpio_request(unsigned gpio, const char *label)
 {
-       if (gpio > EP93XX_GPIO_LINE_H(7))
+       if (gpio > EP93XX_GPIO_LINE_MAX)
                return -EINVAL;
        return 0;
 }
@@ -116,29 +122,20 @@ void gpio_set_value(unsigned gpio, int value);
 /*
  * Map GPIO A0..A7  (0..7)  to irq 64..71,
  *          B0..B7  (7..15) to irq 72..79, and
- *          F0..F7 (40..47) to irq 80..87.
+ *          F0..F7 (16..24) to irq 80..87.
  */
 
 static inline int gpio_to_irq(unsigned gpio)
 {
-       if (gpio <= EP93XX_GPIO_LINE_EGPIO15)
+       if (gpio <= EP93XX_GPIO_LINE_MAX_IRQ)
                return 64 + gpio;
 
-       if (gpio >= EP93XX_GPIO_LINE_F(0) && gpio <= EP93XX_GPIO_LINE_F(7))
-               return 80 + (gpio - EP93XX_GPIO_LINE_F(0));
-
        return -EINVAL;
 }
 
 static inline int irq_to_gpio(unsigned irq)
 {
-       if (irq >= 64 && irq <= 79)
-               return irq - 64;
-
-       if (irq >= 80 && irq <= 87)
-               return (irq - 80) + EP93XX_GPIO_LINE_F(0);
-
-       return -EINVAL;
+       return irq - gpio_to_irq(0);
 }
 
 /* obsolete specific GPIO API */
diff --git a/include/asm-arm/arch-ep93xx/irqs.h 
b/include/asm-arm/arch-ep93xx/irqs.h
index 2a8c636..53d4a68 100644
--- a/include/asm-arm/arch-ep93xx/irqs.h
+++ b/include/asm-arm/arch-ep93xx/irqs.h
@@ -67,12 +67,6 @@
 #define IRQ_EP93XX_SAI                 60
 #define EP93XX_VIC2_VALID_IRQ_MASK     0x1fffffff
 
-/*
- * Map GPIO A0..A7 to irq 64..71, B0..B7 to 72..79, and
- * F0..F7 to 80..87.
- */
-#define IRQ_EP93XX_GPIO(x)             (64 + (((x) + (((x) >> 2) & 8)) & 0x1f))
-
 #define NR_EP93XX_IRQS                 (64 + 24)
 
 #define EP93XX_BOARD_IRQ(x)            (NR_EP93XX_IRQS + (x))
-
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