This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 8e32a3ce24 imx93_gpioirq: Fix the GPIO interrupt source names
8e32a3ce24 is described below

commit 8e32a3ce243bdb9f0966a0a4e39fa629a04b3f36
Author: Ville Juven <[email protected]>
AuthorDate: Mon Apr 15 17:47:35 2024 +0300

    imx93_gpioirq: Fix the GPIO interrupt source names
    
    The original assumption was that the interrupt numbers are divided
    so that 16 pins from 1 port are handled by a single interrupt source.
    
    So source 0 would handle pins 0-15 and source 1 would handle pins 16-31.
    This assumption is wrong, each pin has two sources, thus there are two
    interrupt lines for each pin.
    
    The driver uses source 0, and leaves source 1 disabled.
---
 arch/arm64/include/imx9/imx93_irq.h |  16 ++---
 arch/arm64/src/imx9/imx9_gpio.h     |  14 ++++
 arch/arm64/src/imx9/imx9_gpioirq.c  | 134 +++++++++++-------------------------
 3 files changed, 61 insertions(+), 103 deletions(-)

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 */
-
-  up_disable_irq(IMX9_IRQ_GPIO1_0_15);
-  up_disable_irq(IMX9_IRQ_GPIO1_16_31);
-
-  up_disable_irq(IMX9_IRQ_GPIO2_0_15);
-  up_disable_irq(IMX9_IRQ_GPIO2_16_31);
-
-  up_disable_irq(IMX9_IRQ_GPIO3_0_15);
-  up_disable_irq(IMX9_IRQ_GPIO3_16_31);
-
-  up_disable_irq(IMX9_IRQ_GPIO4_0_15);
-  up_disable_irq(IMX9_IRQ_GPIO4_16_31);
-
-  /* Attach all configured GPIO interrupts and enable the interrupt at the
-   * NVIC
-   */
-
-  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_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_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_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);
+  /* Disable all GPIO interrupts */
+
+  up_disable_irq(IMX9_IRQ_GPIO1_0);
+  up_disable_irq(IMX9_IRQ_GPIO1_1);
+
+  up_disable_irq(IMX9_IRQ_GPIO2_0);
+  up_disable_irq(IMX9_IRQ_GPIO2_1);
+
+  up_disable_irq(IMX9_IRQ_GPIO3_0);
+  up_disable_irq(IMX9_IRQ_GPIO3_1);
+
+  up_disable_irq(IMX9_IRQ_GPIO4_0);
+  up_disable_irq(IMX9_IRQ_GPIO4_1);
+
+  /* Attach the common GPIO interrupt handler and enable the interrupt */
+
+  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,
+                         imx9_gpio_interrupt, (void *)GPIO_PORT2));
+  up_enable_irq(IMX9_IRQ_GPIO2_0);
+
+  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,
+                         imx9_gpio_interrupt, (void *)GPIO_PORT4));
+  up_enable_irq(IMX9_IRQ_GPIO4_0);
 }
 
 /****************************************************************************

Reply via email to