s5j/gpio: assign IRQ slot to each WEINT signal
authorHeesub Shin <heesub.shin@samsung.com>
Thu, 13 Apr 2017 13:24:29 +0000 (22:24 +0900)
committerHeesub Shin <heesub.shin@samsung.com>
Sat, 6 May 2017 10:51:23 +0000 (19:51 +0900)
Change-Id: I661bf9feec1c0d39d11947d257cbd339ced1514a
Signed-off-by: Heesub Shin <heesub.shin@samsung.com>
os/arch/arm/include/s5j/irq.h
os/arch/arm/src/s5j/s5j_gpio.c
os/arch/arm/src/s5j/s5j_gpio_lowerhalf.c
os/arch/arm/src/s5j/s5j_irq.c

index 707f454..662d4bf 100644 (file)
@@ -73,8 +73,6 @@
  * of memory in the IRQ to handle mapping tables.
  */
 
-#define NR_IRQS                                128
-
 #define IRQ_INVALID                    0x3FF
 #define IRQ_SPI(x)                     (32 + (x))
 
 #define IRQ_CR4_VALIRQ                 IRQ_SPI(91)
 #define IRQ_CR4_VALFIQ                 IRQ_SPI(92)
 
+#define NR_VECTORS                     (IRQ_CR4_VALFIQ + 1)
+
+/* External Interrupts */
+#define IRQ_WEINT_GPG10                (NR_VECTORS + 0)
+#define IRQ_WEINT_GPG11                (NR_VECTORS + 1)
+#define IRQ_WEINT_GPG12                (NR_VECTORS + 2)
+#define IRQ_WEINT_GPG13                (NR_VECTORS + 3)
+#define IRQ_WEINT_GPG14                (NR_VECTORS + 4)
+#define IRQ_WEINT_GPG15                (NR_VECTORS + 5)
+#define IRQ_WEINT_GPG16                (NR_VECTORS + 6)
+#define IRQ_WEINT_GPG17                (NR_VECTORS + 7)
+#define IRQ_WEINT_GPG20                (NR_VECTORS + 8)
+#define IRQ_WEINT_GPG21                (NR_VECTORS + 9)
+#define IRQ_WEINT_GPG22                (NR_VECTORS + 10)
+#define IRQ_WEINT_GPG23                (NR_VECTORS + 11)
+#define IRQ_WEINT_GPG24                (NR_VECTORS + 12)
+#define IRQ_WEINT_GPG25                (NR_VECTORS + 13)
+#define IRQ_WEINT_GPG26                (NR_VECTORS + 14)
+#define IRQ_WEINT_GPG27                (NR_VECTORS + 15)
+
+#define NR_IRQS                                (NR_VECTORS + 16)
+
 #endif /* __ARCH_ARM_INCLUDE_S5J_IRQ_H */
index ac5e3ba..10d6480 100644 (file)
@@ -130,14 +130,32 @@ static struct gpio_bank s5jt200_gpio_bank[] = {
                .name = "GPG1",
                .base = (void *)(GPIO_CON_BASE + 0xa0),
                .nr_port = 8,
-               .isr_num = { IRQ_GPIO_GIC_0, },
+               .isr_num = {
+                       IRQ_WEINT_GPG10,
+                       IRQ_WEINT_GPG11,
+                       IRQ_WEINT_GPG12,
+                       IRQ_WEINT_GPG13,
+                       IRQ_WEINT_GPG14,
+                       IRQ_WEINT_GPG15,
+                       IRQ_WEINT_GPG16,
+                       IRQ_WEINT_GPG17,
+               },
                .group_type = GPIO_GROUP_COMMON,
        },
        [GPG2] = {
                .name = "GPG2",
                .base = (void *)(GPIO_CON_BASE + 0xc0),
                .nr_port = 8,
-               .isr_num = { IRQ_GPIO_GIC_1, },
+               .isr_num = {
+                       IRQ_WEINT_GPG20,
+                       IRQ_WEINT_GPG21,
+                       IRQ_WEINT_GPG22,
+                       IRQ_WEINT_GPG23,
+                       IRQ_WEINT_GPG24,
+                       IRQ_WEINT_GPG25,
+                       IRQ_WEINT_GPG26,
+                       IRQ_WEINT_GPG27,
+               },
                .group_type = GPIO_GROUP_COMMON,
        },
        [GPG3] = {
@@ -151,7 +169,11 @@ static struct gpio_bank s5jt200_gpio_bank[] = {
                .name = "GPA0",
                .base = (void *)(GPIO_CON_BASE + 0x100),
                .nr_port = 3,
-               .isr_num = { IRQ_EINT0, IRQ_EINT1, IRQ_EINT2 },
+               .isr_num = {
+                       IRQ_EINT0,
+                       IRQ_EINT1,
+                       IRQ_EINT2,
+               },
                .group_type = GPIO_GROUP_COMMON,
        },
        [GPA1] = {
@@ -1201,3 +1223,37 @@ struct gpio_bank *gpio_to_bank(int gpio)
 
        return s5jt200_gpio_bank + bank;
 }
+
+static int gic_interrupt(int irq, FAR void *context, FAR void *arg)
+{
+       int gpio_irq;
+       uint32_t intpnd;
+
+       if (irq == IRQ_GPIO_GIC_0) {
+               irq = IRQ_WEINT_GPG10;
+               intpnd = getreg32(0x80040900);
+       } else {
+               irq = IRQ_WEINT_GPG20;
+               intpnd = getreg32(0x80040904);
+       }
+
+       /* Dispatch each GPIO interrupt */
+       for (gpio_irq = 0; intpnd; gpio_irq++) {
+               if (intpnd & (1 << gpio_irq)) {
+                       irq_dispatch(irq + gpio_irq, context);
+                       intpnd &= ~(1 << gpio_irq);
+               }
+       }
+
+       return OK;
+}
+
+void s5j_gpio_irqinitialize(void)
+{
+       /* Attach the GPIO interrupt handler for second-level irq decoding */
+       DEBUGVERIFY(irq_attach(IRQ_GPIO_GIC_0, gic_interrupt, NULL));
+       DEBUGVERIFY(irq_attach(IRQ_GPIO_GIC_1, gic_interrupt, NULL));
+
+       up_enable_irq(IRQ_GPIO_GIC_0);
+       up_enable_irq(IRQ_GPIO_GIC_1);
+}
index 626fe6a..e4b413e 100644 (file)
@@ -224,24 +224,12 @@ static u32 gpio_get_irq_id(int gpio)
  *  -1, if Error
  *
  ****************************************************************************/
-static int s5j_gpio_irq_handler(int irq, void *context, void *arg)
+static int s5j_gpio_irq_handler(int irq, FAR void *context, FAR void *arg)
 {
-       int i;
-       struct gpio_dev_s *dev;
-
-       for (i = 0; i < NUM_GPIO; i++) {
-               if (s5j_gpio_all[i] && ((((struct s5j_gpio_priv *)(s5j_gpio_all[i]->priv))->isr_num) & 0x3ff) == irq) {
-                               break;
-               }
-       }
-
-       if (i == NUM_GPIO) {
-               return -1;
-       }
-
-       gpio_eint_clear_pending(((struct s5j_gpio_priv *)(s5j_gpio_all[i]->priv))->gpio);
+       struct gpio_dev_s *dev = (struct gpio_dev_s *)arg;
+       struct s5j_gpio_priv *priv = (struct s5j_gpio_priv *)dev->priv;
 
-       dev = s5j_gpio_all[i];
+       gpio_eint_clear_pending(priv->gpio);
 
        if (dev->callback) {
                s5j_gpio_poll_expiry(1, (uint32_t)dev);
@@ -249,7 +237,7 @@ static int s5j_gpio_irq_handler(int irq, void *context, void *arg)
 
 #ifdef CONFIG_GPIO
 #ifndef CONFIG_DISABLE_POLL
-       gpio_notify(s5j_gpio_all[i]);
+       gpio_notify(dev);
 #endif
 #endif
 
@@ -273,6 +261,7 @@ static void s5j_gpio_enable_irq(struct gpio_dev_s *dev)
 {
        int gpio;
        int irq;
+       int pin;
 
        gpio = ((struct s5j_gpio_priv *)(dev->priv))->gpio;
 
@@ -280,9 +269,10 @@ static void s5j_gpio_enable_irq(struct gpio_dev_s *dev)
        gpio_eint_clear_pending(gpio);
        gpio_eint_unmask(gpio);
 
-       irq = gpio_to_bank(gpio)->isr_num[s5j_gpio_port(gpio)];
-       (void)irq_attach(irq, (xcpt_t)s5j_gpio_irq_handler, NULL);
-       up_enable_irq(irq);
+       pin = s5j_gpio_port(gpio);
+       irq = gpio_to_bank(gpio)->isr_num[pin];
+
+       irq_attach(irq, s5j_gpio_irq_handler, dev);
 }
 
 /****************************************************************************
@@ -307,7 +297,8 @@ static void s5j_gpio_disable_irq(struct gpio_dev_s *dev)
        gpio_eint_clear_pending(gpio);
        gpio_eint_unmask(gpio);
        irq = gpio_to_bank(gpio)->isr_num[s5j_gpio_port(gpio)];
-       up_disable_irq(irq);
+
+       irq_detach(irq);
 }
 
 /****************************************************************************
index aedaad3..bf07e0e 100644 (file)
@@ -105,5 +105,7 @@ void up_irqinitialize(void)
        arm_gic0_initialize();
        arm_gic_initialize();
 
+       s5j_gpio_irqinitialize();
+
        (void)irqenable();
 }