From b2bac4060891f9d9977e40633fb0405a3867edc9 Mon Sep 17 00:00:00 2001 From: Heesub Shin Date: Thu, 13 Apr 2017 22:24:29 +0900 Subject: [PATCH] s5j/gpio: assign IRQ slot to each WEINT signal Change-Id: I661bf9feec1c0d39d11947d257cbd339ced1514a Signed-off-by: Heesub Shin --- os/arch/arm/include/s5j/irq.h | 24 +++++++++++-- os/arch/arm/src/s5j/s5j_gpio.c | 62 ++++++++++++++++++++++++++++++-- os/arch/arm/src/s5j/s5j_gpio_lowerhalf.c | 33 +++++++---------- os/arch/arm/src/s5j/s5j_irq.c | 2 ++ 4 files changed, 95 insertions(+), 26 deletions(-) diff --git a/os/arch/arm/include/s5j/irq.h b/os/arch/arm/include/s5j/irq.h index 707f454..662d4bf 100644 --- a/os/arch/arm/include/s5j/irq.h +++ b/os/arch/arm/include/s5j/irq.h @@ -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)) @@ -152,4 +150,26 @@ #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 */ diff --git a/os/arch/arm/src/s5j/s5j_gpio.c b/os/arch/arm/src/s5j/s5j_gpio.c index ac5e3ba..10d6480 100644 --- a/os/arch/arm/src/s5j/s5j_gpio.c +++ b/os/arch/arm/src/s5j/s5j_gpio.c @@ -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); +} diff --git a/os/arch/arm/src/s5j/s5j_gpio_lowerhalf.c b/os/arch/arm/src/s5j/s5j_gpio_lowerhalf.c index 626fe6a..e4b413e 100644 --- a/os/arch/arm/src/s5j/s5j_gpio_lowerhalf.c +++ b/os/arch/arm/src/s5j/s5j_gpio_lowerhalf.c @@ -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); } /**************************************************************************** diff --git a/os/arch/arm/src/s5j/s5j_irq.c b/os/arch/arm/src/s5j/s5j_irq.c index aedaad3..bf07e0e 100644 --- a/os/arch/arm/src/s5j/s5j_irq.c +++ b/os/arch/arm/src/s5j/s5j_irq.c @@ -105,5 +105,7 @@ void up_irqinitialize(void) arm_gic0_initialize(); arm_gic_initialize(); + s5j_gpio_irqinitialize(); + (void)irqenable(); } -- 2.7.4