diff --git a/arch/arm64/include/imx9/imx93_irq.h b/arch/arm64/include/imx9/imx93_irq.h index 5e5de4ba43..010a1b3e25 100644 --- a/arch/arm64/include/imx9/imx93_irq.h +++ b/arch/arm64/include/imx9/imx93_irq.h @@ -31,8 +31,8 @@ #define IMX9_IRQ_RESERVED39 (IMX9_IRQ_EXT + 7) /* 1-bit or 2-bit ECC or Parity error from CA55 platform cache */ #define IMX9_IRQ_CAN1 (IMX9_IRQ_EXT + 8) /* CAN1 interrupt */ #define IMX9_IRQ_CAN1_ERROR (IMX9_IRQ_EXT + 9) /* CAN1 error interrupt */ -#define IMX9_IRQ_GPIO1_0_15 (IMX9_IRQ_EXT + 10) /* General Purpose Input/Output 1 interrupt 0 */ -#define IMX9_IRQ_GPIO1_16_31 (IMX9_IRQ_EXT + 11) /* General Purpose Input/Output 1 interrupt 1 */ +#define IMX9_IRQ_GPIO1_0 (IMX9_IRQ_EXT + 10) /* General Purpose Input/Output 1 interrupt 0 */ +#define IMX9_IRQ_GPIO1_1 (IMX9_IRQ_EXT + 11) /* General Purpose Input/Output 1 interrupt 1 */ #define IMX9_IRQ_I3C1 (IMX9_IRQ_EXT + 12) /* Improved Inter-Integrated Circuit 1 interrupt */ #define IMX9_IRQ_LPI2C1 (IMX9_IRQ_EXT + 13) /* Low Power Inter-Integrated Circuit module 1 */ #define IMX9_IRQ_LPI2C2 (IMX9_IRQ_EXT + 14) /* Low Power Inter-Integrated Circuit module 2 */ @@ -78,10 +78,10 @@ #define IMX9_IRQ_FLEXIO2 (IMX9_IRQ_EXT + 54) /* Flexible IO 2 interrupt */ #define IMX9_IRQ_FLEXSPI1 (IMX9_IRQ_EXT + 55) /* FlexSPI controller interface interrupt 1 */ #define IMX9_IRQ_RESERVED88 (IMX9_IRQ_EXT + 56) /* Reserved interrupt */ -#define IMX9_IRQ_GPIO2_0_15 (IMX9_IRQ_EXT + 57) /* General Purpose Input/Output 2 interrupt 0 */ -#define IMX9_IRQ_GPIO2_16_31 (IMX9_IRQ_EXT + 58) /* General Purpose Input/Output 2 interrupt 1 */ -#define IMX9_IRQ_GPIO3_0_15 (IMX9_IRQ_EXT + 59) /* General Purpose Input/Output 3 interrupt 0 */ -#define IMX9_IRQ_GPIO3_16_31 (IMX9_IRQ_EXT + 60) /* General Purpose Input/Output 3 interrupt 1 */ +#define IMX9_IRQ_GPIO2_0 (IMX9_IRQ_EXT + 57) /* General Purpose Input/Output 2 interrupt 0 */ +#define IMX9_IRQ_GPIO2_1 (IMX9_IRQ_EXT + 58) /* General Purpose Input/Output 2 interrupt 1 */ +#define IMX9_IRQ_GPIO3_0 (IMX9_IRQ_EXT + 59) /* General Purpose Input/Output 3 interrupt 0 */ +#define IMX9_IRQ_GPIO3_1 (IMX9_IRQ_EXT + 60) /* General Purpose Input/Output 3 interrupt 1 */ #define IMX9_IRQ_I3C2 (IMX9_IRQ_EXT + 61) /* Improved Inter-Integrated Circuit 2 interrupt */ #define IMX9_IRQ_LPI2C3 (IMX9_IRQ_EXT + 62) /* Low Power Inter-Integrated Circuit module 3 */ #define IMX9_IRQ_LPI2C4 (IMX9_IRQ_EXT + 63) /* Low Power Inter-Integrated Circuit module 4 */ @@ -210,8 +210,8 @@ #define IMX9_IRQ_RESERVED218 (IMX9_IRQ_EXT + 186) /* Reserved interrupt */ #define IMX9_IRQ_USB1 (IMX9_IRQ_EXT + 187) /* USB-1 Wake-up Interrupt */ #define IMX9_IRQ_USB2 (IMX9_IRQ_EXT + 188) /* USB-2 Wake-up Interrupt */ -#define IMX9_IRQ_GPIO4_0_15 (IMX9_IRQ_EXT + 189) /* General Purpose Input/Output 4 interrupt 0 */ -#define IMX9_IRQ_GPIO4_16_31 (IMX9_IRQ_EXT + 190) /* General Purpose Input/Output 4 interrupt 1 */ +#define IMX9_IRQ_GPIO4_0 (IMX9_IRQ_EXT + 189) /* General Purpose Input/Output 4 interrupt 0 */ +#define IMX9_IRQ_GPIO4_1 (IMX9_IRQ_EXT + 190) /* General Purpose Input/Output 4 interrupt 1 */ #define IMX9_IRQ_LPSPI5 (IMX9_IRQ_EXT + 191) /* Low Power Serial Peripheral Interface 5 */ #define IMX9_IRQ_LPSPI6 (IMX9_IRQ_EXT + 192) /* Low Power Serial Peripheral Interface 6 */ #define IMX9_IRQ_LPSPI7 (IMX9_IRQ_EXT + 193) /* Low Power Serial Peripheral Interface 7 */ diff --git a/arch/arm64/src/imx9/imx9_gpio.h b/arch/arm64/src/imx9/imx9_gpio.h index 229d4d635a..1c7f44a53f 100644 --- a/arch/arm64/src/imx9/imx9_gpio.h +++ b/arch/arm64/src/imx9/imx9_gpio.h @@ -274,6 +274,20 @@ void imx9_gpio_write(gpio_pinset_t pinset, bool value); bool imx9_gpio_read(gpio_pinset_t pinset); +/**************************************************************************** + * Name: imx9_gpioirq_attach + * + * Description: + * Attach a pin interrupt handler. + * + ****************************************************************************/ + +#ifdef CONFIG_IMX9_GPIO_IRQ +int imx9_gpioirq_attach(gpio_pinset_t pinset, xcpt_t isr, void *arg); +#else +#define imx9_gpioirq_attach(pinset, isr, arg) 0 +#endif + /**************************************************************************** * Name: imx9_gpioirq_configure * diff --git a/arch/arm64/src/imx9/imx9_gpioirq.c b/arch/arm64/src/imx9/imx9_gpioirq.c index e8ba83642c..3d75e90798 100644 --- a/arch/arm64/src/imx9/imx9_gpioirq.c +++ b/arch/arm64/src/imx9/imx9_gpioirq.c @@ -66,16 +66,17 @@ static struct imx9_portisr_s g_isrtab[IMX9_GPIO_NPORTS]; ****************************************************************************/ /**************************************************************************** - * Name: imx9_gpioN_A_B_interrupt + * Name: imx9_gpio_interrupt * * Description: - * GPIO interrupt handlers. + * GPIO interrupt handlers. iMX9 has two interrupt sources for each pin, + * the NuttX driver uses source 0. * ****************************************************************************/ -static int imx9_gpio_0_15_interrupt(int irq, void *context, void *arg) +static int imx9_gpio_interrupt(int irq, void *context, void *arg) { - uint32_t port = *(uint32_t *)arg; + uint32_t port = (uint32_t)((uintptr_t)arg) >> GPIO_PORT_SHIFT; uint32_t status; uint32_t pin; uint32_t regaddr; @@ -83,56 +84,13 @@ static int imx9_gpio_0_15_interrupt(int irq, void *context, void *arg) /* Get the pending interrupt indications */ regaddr = IMX9_GPIO_ISFR0(port); - status = getreg32(regaddr) & 0x0000ffff; + status = getreg32(regaddr); /* Decode the pending interrupts */ - for (pin = 0; pin < 16 && status != 0; pin++) + for (pin = 0; pin < 32 && status != 0; pin++) { - /* Is the IRQ associate with this pin pending? */ - - uint32_t mask = (1 << pin); - if ((status & mask) != 0) - { - struct imx9_portisr_s *isrtab; - - /* Yes, clear the status bit and dispatch the interrupt */ - - putreg32(mask, regaddr); - status &= ~mask; - - /* Get the interrupt table for this port */ - - isrtab = &g_isrtab[port]; - if (isrtab->pins[pin].isr != NULL) - { - /* Run the user handler with the user's argument */ - - isrtab->pins[pin].isr(irq, context, isrtab->pins[pin].arg); - } - } - } - - return OK; -} - -static int imx9_gpio_16_31_interrupt(int irq, void *context, void *arg) -{ - uint32_t port = *(uint32_t *)arg; - uint32_t status; - uint32_t pin; - uint32_t regaddr; - - /* Get the pending interrupt indications */ - - regaddr = IMX9_GPIO_ISFR0(port); - status = getreg32(regaddr) & 0xffff0000; - - /* Decode the pending interrupts */ - - for (pin = 16; pin < 32 && status != 0; pin++) - { - /* Is the IRQ associate with this pin pending? */ + /* Is the IRQ associated with this pin pending? */ uint32_t mask = (1 << pin); if ((status & mask) != 0) @@ -189,51 +147,37 @@ void imx9_gpioirq_initialize(void) } } - /* Disable all unconfigured GPIO interrupts at the NVIC */ + /* Disable all GPIO interrupts */ - up_disable_irq(IMX9_IRQ_GPIO1_0_15); - up_disable_irq(IMX9_IRQ_GPIO1_16_31); + up_disable_irq(IMX9_IRQ_GPIO1_0); + up_disable_irq(IMX9_IRQ_GPIO1_1); - up_disable_irq(IMX9_IRQ_GPIO2_0_15); - up_disable_irq(IMX9_IRQ_GPIO2_16_31); + up_disable_irq(IMX9_IRQ_GPIO2_0); + up_disable_irq(IMX9_IRQ_GPIO2_1); - up_disable_irq(IMX9_IRQ_GPIO3_0_15); - up_disable_irq(IMX9_IRQ_GPIO3_16_31); + up_disable_irq(IMX9_IRQ_GPIO3_0); + up_disable_irq(IMX9_IRQ_GPIO3_1); - up_disable_irq(IMX9_IRQ_GPIO4_0_15); - up_disable_irq(IMX9_IRQ_GPIO4_16_31); + up_disable_irq(IMX9_IRQ_GPIO4_0); + up_disable_irq(IMX9_IRQ_GPIO4_1); - /* Attach all configured GPIO interrupts and enable the interrupt at the - * NVIC - */ + /* Attach the common GPIO interrupt handler and enable the interrupt */ - DEBUGVERIFY(irq_attach(IMX9_IRQ_GPIO1_0_15, - imx9_gpio_0_15_interrupt, (void *)1)); - up_enable_irq(IMX9_IRQ_GPIO1_0_15); - DEBUGVERIFY(irq_attach(IMX9_IRQ_GPIO1_16_31, - imx9_gpio_16_31_interrupt, (void *)1)); - up_enable_irq(IMX9_IRQ_GPIO1_16_31); + DEBUGVERIFY(irq_attach(IMX9_IRQ_GPIO1_0, + imx9_gpio_interrupt, (void *)GPIO_PORT1)); + up_enable_irq(IMX9_IRQ_GPIO1_0); - DEBUGVERIFY(irq_attach(IMX9_IRQ_GPIO2_0_15, - imx9_gpio_0_15_interrupt, (void *)2)); - up_enable_irq(IMX9_IRQ_GPIO1_0_15); - DEBUGVERIFY(irq_attach(IMX9_IRQ_GPIO2_16_31, - imx9_gpio_16_31_interrupt, (void *)2)); - up_enable_irq(IMX9_IRQ_GPIO1_16_31); + DEBUGVERIFY(irq_attach(IMX9_IRQ_GPIO2_0, + imx9_gpio_interrupt, (void *)GPIO_PORT2)); + up_enable_irq(IMX9_IRQ_GPIO2_0); - DEBUGVERIFY(irq_attach(IMX9_IRQ_GPIO3_0_15, - imx9_gpio_0_15_interrupt, (void *)3)); - up_enable_irq(IMX9_IRQ_GPIO1_0_15); - DEBUGVERIFY(irq_attach(IMX9_IRQ_GPIO3_16_31, - imx9_gpio_16_31_interrupt, (void *)3)); - up_enable_irq(IMX9_IRQ_GPIO1_16_31); + DEBUGVERIFY(irq_attach(IMX9_IRQ_GPIO3_0, + imx9_gpio_interrupt, (void *)GPIO_PORT3)); + up_enable_irq(IMX9_IRQ_GPIO3_0); - DEBUGVERIFY(irq_attach(IMX9_IRQ_GPIO4_0_15, - imx9_gpio_0_15_interrupt, (void *)4)); - up_enable_irq(IMX9_IRQ_GPIO1_0_15); - DEBUGVERIFY(irq_attach(IMX9_IRQ_GPIO4_16_31, - imx9_gpio_16_31_interrupt, (void *)4)); - up_enable_irq(IMX9_IRQ_GPIO1_16_31); + DEBUGVERIFY(irq_attach(IMX9_IRQ_GPIO4_0, + imx9_gpio_interrupt, (void *)GPIO_PORT4)); + up_enable_irq(IMX9_IRQ_GPIO4_0); } /****************************************************************************