[adm5120] add support for GPIO IRQs
authorGabor Juhos <juhosg@openwrt.org>
Mon, 10 Dec 2007 14:05:01 +0000 (14:05 +0000)
committerGabor Juhos <juhosg@openwrt.org>
Mon, 10 Dec 2007 14:05:01 +0000 (14:05 +0000)
SVN-Revision: 9700

target/linux/adm5120/files/arch/mips/adm5120/board.c
target/linux/adm5120/files/arch/mips/adm5120/gpio.c
target/linux/adm5120/files/arch/mips/adm5120/irq.c
target/linux/adm5120/files/include/asm-mips/mach-adm5120/adm5120_info.h
target/linux/adm5120/files/include/asm-mips/mach-adm5120/adm5120_switch.h

index c5ee4e3e7296553ff227ac193b0cb45162ca3be7..0ac85f529feab9004afac41c014e98c1fa14b0a6 100644 (file)
@@ -83,6 +83,8 @@ static int __init adm5120_board_setup(void)
 
        memcpy(&adm5120_board_name, board->name, ADM5120_BOARD_NAMELEN);
 
+       adm5120_gpio_init();
+
        adm5120_board_reset = board->board_reset;
        if (board->eth_num_ports > 0)
                adm5120_eth_num_ports = board->eth_num_ports;
index 075ea874165e7c562d7ac4d6c870cd18a7a03cf1..a6cfdcbe098f644fd0f87de62ca2e52653e0e0e2 100644 (file)
@@ -37,7 +37,7 @@
 #include <adm5120_defs.h>
 #include <adm5120_info.h>
 #include <adm5120_switch.h>
-
+#include <adm5120_irq.h>
 
 #define GPIO_READ(r)           readl((r))
 #define GPIO_WRITE(v, r)       writel((v), (r))
@@ -46,6 +46,7 @@
 struct adm5120_gpio_line {
        u32 flags;
        const char *label;
+       int irq;
 };
 
 #define GPIO_FLAG_VALID                0x01
@@ -71,36 +72,25 @@ static struct led_desc led_table[15] = {
        LED_DESC(4, 0), LED_DESC(4, 1), LED_DESC(4, 2)
 };
 
-static struct adm5120_gpio_line adm5120_gpio_map[ADM5120_GPIO_COUNT] = {
-       [ADM5120_GPIO_PIN0] = {.flags = GPIO_FLAG_VALID},
-       [ADM5120_GPIO_PIN1] = {.flags = GPIO_FLAG_VALID},
-       [ADM5120_GPIO_PIN2] = {.flags = GPIO_FLAG_VALID},
-       [ADM5120_GPIO_PIN3] = {.flags = GPIO_FLAG_VALID},
-       [ADM5120_GPIO_PIN4] = {.flags = GPIO_FLAG_VALID},
-       [ADM5120_GPIO_PIN5] = {.flags = GPIO_FLAG_VALID},
-       [ADM5120_GPIO_PIN6] = {.flags = GPIO_FLAG_VALID},
-       [ADM5120_GPIO_PIN7] = {.flags = GPIO_FLAG_VALID},
-       [ADM5120_GPIO_P0L0] = {.flags = GPIO_FLAG_VALID},
-       [ADM5120_GPIO_P0L1] = {.flags = GPIO_FLAG_VALID},
-       [ADM5120_GPIO_P0L2] = {.flags = GPIO_FLAG_VALID},
-       [ADM5120_GPIO_P1L0] = {.flags = GPIO_FLAG_VALID},
-       [ADM5120_GPIO_P1L1] = {.flags = GPIO_FLAG_VALID},
-       [ADM5120_GPIO_P1L2] = {.flags = GPIO_FLAG_VALID},
-       [ADM5120_GPIO_P2L0] = {.flags = GPIO_FLAG_VALID},
-       [ADM5120_GPIO_P2L1] = {.flags = GPIO_FLAG_VALID},
-       [ADM5120_GPIO_P2L2] = {.flags = GPIO_FLAG_VALID},
-       [ADM5120_GPIO_P3L0] = {.flags = GPIO_FLAG_VALID},
-       [ADM5120_GPIO_P3L1] = {.flags = GPIO_FLAG_VALID},
-       [ADM5120_GPIO_P3L2] = {.flags = GPIO_FLAG_VALID},
-       [ADM5120_GPIO_P4L0] = {.flags = GPIO_FLAG_VALID},
-       [ADM5120_GPIO_P4L1] = {.flags = GPIO_FLAG_VALID},
-       [ADM5120_GPIO_P4L2] = {.flags = GPIO_FLAG_VALID}
-};
+static struct adm5120_gpio_line adm5120_gpio_map[ADM5120_GPIO_COUNT];
+
+/*-------------------------------------------------------------------------*/
+
+static inline int gpio_is_invalid(unsigned gpio)
+{
+       if ((gpio > ADM5120_GPIO_MAX) ||
+               (adm5120_gpio_map[gpio].flags & GPIO_FLAG_VALID) == 0);
+               return 0;
 
-#define gpio_is_invalid(g) ((g) > ADM5120_GPIO_MAX || \
-               ((adm5120_gpio_map[(g)].flags & GPIO_FLAG_VALID) == 0))
+       return 1;
+}
+
+static inline int gpio_is_used(unsigned gpio)
+{
+       return ((adm5120_gpio_map[gpio].flags & GPIO_FLAG_USED) != 0);
+}
 
-#define gpio_is_used(g)        ((adm5120_gpio_map[(g)].flags & GPIO_FLAG_USED) != 0)
+/*-------------------------------------------------------------------------*/
 
 /*
  * Helpers for GPIO lines in GPIO_CONF0 register
@@ -247,6 +237,8 @@ static inline int leds_get_value(unsigned led)
        return 1;
 }
 
+/*-------------------------------------------------------------------------*/
+
 /*
  * Main GPIO support routines
  */
@@ -325,29 +317,74 @@ EXPORT_SYMBOL(adm5120_gpio_free);
 
 int adm5120_gpio_to_irq(unsigned gpio)
 {
-       /* FIXME: not yet implemented */
-       return -EINVAL;
+       if (gpio > ADM5120_GPIO_MAX)
+               return -EINVAL;
+
+       return adm5120_gpio_map[gpio].irq;
 }
 EXPORT_SYMBOL(adm5120_gpio_to_irq);
 
 int adm5120_irq_to_gpio(unsigned irq)
 {
-       /* FIXME: not yet implemented */
+       int i;
+
+       for (i = 0; i < ADM5120_GPIO_COUNT; i++)
+               if (adm5120_gpio_map[i].irq == irq)
+                       return i;
+
        return -EINVAL;
 }
 EXPORT_SYMBOL(adm5120_irq_to_gpio);
 
-static int __init adm5120_gpio_init(void)
+/*-------------------------------------------------------------------------*/
+
+void __init adm5120_gpio_csx0_enable(void)
+{
+       u32 t;
+
+       t = SW_READ_REG(GPIO_CONF2);
+       t |= GPIO_CONF2_CSX0;
+       SW_WRITE_REG(GPIO_CONF2, t);
+
+       adm5120_gpio_map[ADM5120_GPIO_PIN1].flags &= ~GPIO_FLAG_VALID;
+       adm5120_gpio_map[ADM5120_GPIO_PIN2].irq = ADM5120_IRQ_GPIO2;
+}
+
+void __init adm5120_gpio_csx1_enable(void)
+{
+       u32 t;
+
+       t = SW_READ_REG(GPIO_CONF2);
+       t |= GPIO_CONF2_CSX1;
+       SW_WRITE_REG(GPIO_CONF2, t);
+
+       adm5120_gpio_map[ADM5120_GPIO_PIN3].flags &= ~GPIO_FLAG_VALID;
+       if (adm5120_package_bga())
+               adm5120_gpio_map[ADM5120_GPIO_PIN4].irq = ADM5120_IRQ_GPIO4;
+}
+
+void __init adm5120_gpio_ew_enable(void)
+{
+       u32 t;
+
+       t = SW_READ_REG(GPIO_CONF2);
+       t |= GPIO_CONF2_EW;
+       SW_WRITE_REG(GPIO_CONF2, t);
+}
+
+void __init adm5120_gpio_init(void)
 {
        int i;
 
+       SW_WRITE_REG(GPIO_CONF2, 0);
+
+       for (i = 0; i < ADM5120_GPIO_COUNT; i++)
+               adm5120_gpio_map[i].flags = GPIO_FLAG_VALID;
+
        if (adm5120_package_pqfp()) {
-               /* GPIO pins 4-7 are unavailable in ADM5120P */
-               for (i = ADM5120_GPIO_PIN4; i <= ADM5120_GPIO_PIN7; i++)
-                       adm5120_gpio_map[i].flags &= ~GPIO_FLAG_VALID;
+               adm5120_gpio_map[ADM5120_GPIO_PIN4].flags &= ~GPIO_FLAG_VALID;
+               adm5120_gpio_map[ADM5120_GPIO_PIN5].flags &= ~GPIO_FLAG_VALID;
+               adm5120_gpio_map[ADM5120_GPIO_PIN6].flags &= ~GPIO_FLAG_VALID;
+               adm5120_gpio_map[ADM5120_GPIO_PIN7].flags &= ~GPIO_FLAG_VALID;
        }
-
-       return 0;
 }
-
-pure_initcall(adm5120_gpio_init);
index 6e3fc62220d83b41f5c8fc0f2e5049d62d3f5791..361dcb8628afddf0618827ed6cf663811d96774e 100644 (file)
@@ -76,7 +76,7 @@ static void adm5120_intc_irq_mask(unsigned int irq)
 static int adm5120_intc_irq_set_type(unsigned int irq, unsigned int flow_type)
 {
        /* TODO: not yet tested */
-#if 1
+
        unsigned int sense;
        unsigned long mode;
        int err = 0;
@@ -114,13 +114,13 @@ static int adm5120_intc_irq_set_type(unsigned int irq, unsigned int flow_type)
                        mode &= (1 << (irq-ADM5120_INTC_IRQ_BASE));
 
                INTC_WRITE(INTC_REG_INT_MODE, mode);
-               /* fallthrogh */
+               /* fallthrough */
        default:
                irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK;
                irq_desc[irq].status |= sense;
                break;
        }
-#endif
+
        return 0;
 }
 
@@ -161,10 +161,13 @@ static void __init adm5120_intc_irq_init(int base)
 
        /* disable all interrupts */
        INTC_WRITE(INTC_REG_IRQ_DISABLE, INTC_INT_ALL);
+
        /* setup all interrupts to generate IRQ instead of FIQ */
        INTC_WRITE(INTC_REG_INT_MODE, 0);
+
        /* set active level for all external interrupts to HIGH */
        INTC_WRITE(INTC_REG_INT_LEVEL, 0);
+
        /* disable usage of the TEST_SOURCE register */
        INTC_WRITE(INTC_REG_IRQ_SOURCE_SELECT, 0);
 
index ac452ef30f169b81467c99d02e4bccecbfb5dc4c..7d92a510bd210a2ebe280c5df3cf5b90fa556048 100644 (file)
@@ -68,6 +68,11 @@ extern void adm5120_halt(void);
 
 extern void (*adm5120_board_reset)(void);
 
+extern void adm5120_gpio_init(void) __init;
+extern void adm5120_gpio_csx0_enable(void) __init;
+extern void adm5120_gpio_csx1_enable(void) __init;
+extern void adm5120_gpio_ew_enable(void) __init;
+
 static inline int adm5120_package_pqfp(void)
 {
        return (adm5120_package == ADM5120_PACKAGE_PQFP);
index a40175b03b5207cd88eca921f94caf27bdeadbb2..f96c7d50c78c2ebb0eff4684cb5acf06120e8d00 100644 (file)
 #define GPIO_CONF0_OE_MASK     (0xFF << GPIO_CONF0_OE_SHIFT)
 #define GPIO_CONF0_OV_MASK     (0xFF << GPIO_CONF0_OV_SHIFT)
 
+/* GPIO_CONF2 register bits */
+#define GPIO_CONF2_CSX0                BIT(4)  /* enable CSX0:INTX0 on GPIO 1:2 */
+#define GPIO_CONF2_CSX1                BIT(5)  /* enable CSX1:INTX1 on GPIO 3:4 */
+#define GPIO_CONF2_EW          BIT(6)  /* enable wait state pin for CSX0/1 */
+
 /* INT_STATUS/INT_MASK register bits */
 #define SWITCH_INT_SHD         BIT(0)  /* Send High Done */
 #define SWITCH_INT_SLD         BIT(1)  /* Send Low Done */