mirror of
https://github.com/apache/nuttx.git
synced 2026-09-03 15:43:01 +00:00
arch/arm: GPIO IMX9 Add support for IRQ line1 and GPIO5
Adds support to select irq line 1 to share the same GPIO with Linux Also added GPIO5 definiton for IRQ Signed-off-by: Peter van der Perk <peter.vanderperk@nxp.com>
This commit is contained in:
parent
99501bba9a
commit
79ce1647da
4 changed files with 227 additions and 6 deletions
|
|
@ -47,6 +47,6 @@
|
|||
#define NVIC_SYSH_PRIORITY_MAX 0x00 /* Zero is maximum priority */
|
||||
#define NVIC_SYSH_PRIORITY_STEP 0x40 /* Two bits of interrupt pri used */
|
||||
|
||||
#define IMX9_GPIO_NPORTS 4
|
||||
#define IMX9_GPIO_NPORTS 5
|
||||
|
||||
#endif /* __ARCH_ARM_INCLUDE_IMX9_CHIP_H */
|
||||
|
|
|
|||
|
|
@ -382,18 +382,118 @@ config IMX9_GPIO1_IRQ
|
|||
bool "GPIO1 Interrupt"
|
||||
default n
|
||||
|
||||
choice
|
||||
prompt "GPIO1 IRQ output select"
|
||||
depends on IMX9_GPIO1_IRQ
|
||||
default IMX9_GPIO1_IRQ_OUT_LINE1
|
||||
---help---
|
||||
Each IMX9 GPIO controller provides two IRQ output lines. These
|
||||
lines may be shared with other cores or domains in the SoC
|
||||
(e.g. A55 vs M7), so selecting the correct line avoids conflicts.
|
||||
|
||||
By default this subsystem uses IRQ line 1, leaving line 0 available
|
||||
for the A55 or other system components that typically rely on it.
|
||||
|
||||
config IMX9_GPIO1_IRQ_OUT_LINE0
|
||||
bool "Use GPIO1 IRQ line 0"
|
||||
|
||||
config IMX9_GPIO1_IRQ_OUT_LINE1
|
||||
bool "Use GPIO1 IRQ line 1"
|
||||
endchoice
|
||||
|
||||
config IMX9_GPIO2_IRQ
|
||||
bool "GPIO2 Interrupt"
|
||||
default n
|
||||
|
||||
choice
|
||||
prompt "GPIO2 IRQ output select"
|
||||
depends on IMX9_GPIO2_IRQ
|
||||
default IMX9_GPIO2_IRQ_OUT_LINE1
|
||||
---help---
|
||||
Each IMX9 GPIO controller provides two IRQ output lines. These
|
||||
lines may be shared with other cores or domains in the SoC
|
||||
(e.g. A55 vs M7), so selecting the correct line avoids conflicts.
|
||||
|
||||
By default this subsystem uses IRQ line 1, leaving line 0 available
|
||||
for the A55 or other system components that typically rely on it.
|
||||
|
||||
config IMX9_GPIO2_IRQ_OUT_LINE0
|
||||
bool "Use GPIO2 IRQ line 0"
|
||||
|
||||
config IMX9_GPIO2_IRQ_OUT_LINE1
|
||||
bool "Use GPIO2 IRQ line 1"
|
||||
endchoice
|
||||
|
||||
config IMX9_GPIO3_IRQ
|
||||
bool "GPIO3 Interrupt"
|
||||
default n
|
||||
|
||||
choice
|
||||
prompt "GPIO3 IRQ output select"
|
||||
depends on IMX9_GPIO3_IRQ
|
||||
default IMX9_GPIO3_IRQ_OUT_LINE1
|
||||
---help---
|
||||
Each IMX9 GPIO controller provides two IRQ output lines. These
|
||||
lines may be shared with other cores or domains in the SoC
|
||||
(e.g. A55 vs M7), so selecting the correct line avoids conflicts.
|
||||
|
||||
By default this subsystem uses IRQ line 1, leaving line 0 available
|
||||
for the A55 or other system components that typically rely on it.
|
||||
|
||||
config IMX9_GPIO3_IRQ_OUT_LINE0
|
||||
bool "Use GPIO3 IRQ line 0"
|
||||
|
||||
config IMX9_GPIO3_IRQ_OUT_LINE1
|
||||
bool "Use GPIO3 IRQ line 1"
|
||||
endchoice
|
||||
|
||||
config IMX9_GPIO4_IRQ
|
||||
bool "GPIO4 Interrupt"
|
||||
default n
|
||||
|
||||
choice
|
||||
prompt "GPIO4 IRQ output select"
|
||||
depends on IMX9_GPIO4_IRQ
|
||||
default IMX9_GPIO4_IRQ_OUT_LINE1
|
||||
---help---
|
||||
Each IMX9 GPIO controller provides two IRQ output lines. These
|
||||
lines may be shared with other cores or domains in the SoC
|
||||
(e.g. A55 vs M7), so selecting the correct line avoids conflicts.
|
||||
|
||||
By default this subsystem uses IRQ line 1, leaving line 0 available
|
||||
for the A55 or other system components that typically rely on it.
|
||||
|
||||
config IMX9_GPIO4_IRQ_OUT_LINE0
|
||||
bool "Use GPIO4 IRQ line 0"
|
||||
|
||||
config IMX9_GPIO4_IRQ_OUT_LINE1
|
||||
bool "Use GPIO4 IRQ line 1"
|
||||
endchoice
|
||||
|
||||
config IMX9_GPIO5_IRQ
|
||||
bool "GPIO5 Interrupt"
|
||||
default n
|
||||
|
||||
choice
|
||||
prompt "GPIO5 IRQ output select"
|
||||
depends on IMX9_GPIO5_IRQ
|
||||
default IMX9_GPIO5_IRQ_OUT_LINE1
|
||||
---help---
|
||||
Each IMX9 GPIO controller provides two IRQ output lines. These
|
||||
lines may be shared with other cores or domains in the SoC
|
||||
(e.g. A55 vs M7), so selecting the correct line avoids conflicts.
|
||||
|
||||
By default this subsystem uses IRQ line 1, leaving line 0 available
|
||||
for the A55 or other system components that typically rely on it.
|
||||
|
||||
config IMX9_GPIO5_IRQ_OUT_LINE0
|
||||
bool "Use GPIO5 IRQ line 0"
|
||||
|
||||
config IMX9_GPIO5_IRQ_OUT_LINE1
|
||||
bool "Use GPIO5 IRQ line 1"
|
||||
endchoice
|
||||
|
||||
|
||||
endmenu # GPIO Interrupt Configuration
|
||||
|
||||
config IMX9_LPI2C
|
||||
|
|
|
|||
|
|
@ -124,9 +124,14 @@ static int imx9_gpio_configinput(gpio_pinset_t pinset)
|
|||
{
|
||||
uint32_t port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
|
||||
uint32_t pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT;
|
||||
uint32_t reg;
|
||||
|
||||
DEBUGASSERT((unsigned int)port < IMX9_GPIO_NPORTS);
|
||||
|
||||
reg = getreg32(IMX9_GPIO_PCNS(port));
|
||||
reg &= ~(1 << pin);
|
||||
putreg32(reg, IMX9_GPIO_PCNS(port));
|
||||
|
||||
/* Configure pin as in input */
|
||||
|
||||
imx9_gpio_dirin(port, pin);
|
||||
|
|
|
|||
|
|
@ -68,6 +68,66 @@ static struct imx9_portisr_s g_isrtab[IMX9_GPIO_NPORTS];
|
|||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imx9_get_irqline_for_port
|
||||
*
|
||||
* Description:
|
||||
* iMX9 has two interrupt sources for each pin, this function fetches
|
||||
* which line is configured for a given port
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint32_t imx9_get_irqline_for_port(uint32_t port)
|
||||
{
|
||||
switch (port)
|
||||
{
|
||||
case GPIO1:
|
||||
#ifdef CONFIG_IMX9_GPIO1_IRQ_OUT_LINE0
|
||||
return 0;
|
||||
#elif defined(CONFIG_IMX9_GPIO1_IRQ_OUT_LINE1)
|
||||
return 1;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case GPIO2:
|
||||
#ifdef CONFIG_IMX9_GPIO2_IRQ_OUT_LINE0
|
||||
return 0;
|
||||
#elif defined(CONFIG_IMX9_GPIO2_IRQ_OUT_LINE1)
|
||||
return 1;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case GPIO3:
|
||||
#ifdef CONFIG_IMX9_GPIO3_IRQ_OUT_LINE0
|
||||
return 0;
|
||||
#elif defined(CONFIG_IMX9_GPIO3_IRQ_OUT_LINE1)
|
||||
return 1;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case GPIO4:
|
||||
#ifdef CONFIG_IMX9_GPIO4_IRQ_OUT_LINE0
|
||||
return 0;
|
||||
#elif defined(CONFIG_IMX9_GPIO4_IRQ_OUT_LINE1)
|
||||
return 1;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case GPIO5:
|
||||
#ifdef CONFIG_IMX9_GPIO5_IRQ_OUT_LINE0
|
||||
return 0;
|
||||
#elif defined(CONFIG_IMX9_GPIO5_IRQ_OUT_LINE1)
|
||||
return 1;
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imx9_gpio_interrupt
|
||||
*
|
||||
|
|
@ -86,7 +146,15 @@ static int imx9_gpio_interrupt(int irq, void *context, void *arg)
|
|||
|
||||
/* Get the pending interrupt indications */
|
||||
|
||||
regaddr = IMX9_GPIO_ISFR0(port);
|
||||
if (imx9_get_irqline_for_port(port))
|
||||
{
|
||||
regaddr = IMX9_GPIO_ISFR1(port);
|
||||
}
|
||||
else
|
||||
{
|
||||
regaddr = IMX9_GPIO_ISFR0(port);
|
||||
}
|
||||
|
||||
status = getreg32(regaddr);
|
||||
|
||||
/* Decode the pending interrupts */
|
||||
|
|
@ -170,31 +238,70 @@ void imx9_gpioirq_initialize(void)
|
|||
up_disable_irq(IMX9_IRQ_GPIO4_0);
|
||||
up_disable_irq(IMX9_IRQ_GPIO4_1);
|
||||
|
||||
up_disable_irq(IMX9_IRQ_GPIO5_0);
|
||||
up_disable_irq(IMX9_IRQ_GPIO5_1);
|
||||
|
||||
/* Attach the common GPIO interrupt handler and enable the interrupt */
|
||||
|
||||
#ifdef CONFIG_IMX9_GPIO1_IRQ
|
||||
#ifdef CONFIG_IMX9_GPIO1_IRQ_OUT_LINE0
|
||||
DEBUGVERIFY(irq_attach(IMX9_IRQ_GPIO1_0,
|
||||
imx9_gpio_interrupt, (void *)GPIO_PORT1));
|
||||
up_enable_irq(IMX9_IRQ_GPIO1_0);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IMX9_GPIO2_IRQ
|
||||
#ifdef CONFIG_IMX9_GPIO1_IRQ_OUT_LINE0
|
||||
DEBUGVERIFY(irq_attach(IMX9_IRQ_GPIO1_1,
|
||||
imx9_gpio_interrupt, (void *)GPIO_PORT1));
|
||||
up_enable_irq(IMX9_IRQ_GPIO1_1);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IMX9_GPIO2_IRQ_OUT_LINE0
|
||||
DEBUGVERIFY(irq_attach(IMX9_IRQ_GPIO2_0,
|
||||
imx9_gpio_interrupt, (void *)GPIO_PORT2));
|
||||
up_enable_irq(IMX9_IRQ_GPIO2_0);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IMX9_GPIO3_IRQ
|
||||
#ifdef CONFIG_IMX9_GPIO2_IRQ_OUT_LINE1
|
||||
DEBUGVERIFY(irq_attach(IMX9_IRQ_GPIO2_1,
|
||||
imx9_gpio_interrupt, (void *)GPIO_PORT2));
|
||||
up_enable_irq(IMX9_IRQ_GPIO2_1);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IMX9_GPIO3_IRQ_OUT_LINE0
|
||||
DEBUGVERIFY(irq_attach(IMX9_IRQ_GPIO3_0,
|
||||
imx9_gpio_interrupt, (void *)GPIO_PORT3));
|
||||
up_enable_irq(IMX9_IRQ_GPIO3_0);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IMX9_GPIO4_IRQ
|
||||
#ifdef CONFIG_IMX9_GPIO3_IRQ_OUT_LINE1
|
||||
DEBUGVERIFY(irq_attach(IMX9_IRQ_GPIO3_1,
|
||||
imx9_gpio_interrupt, (void *)GPIO_PORT3));
|
||||
up_enable_irq(IMX9_IRQ_GPIO3_1);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IMX9_GPIO4_IRQ_OUT_LINE0
|
||||
DEBUGVERIFY(irq_attach(IMX9_IRQ_GPIO4_0,
|
||||
imx9_gpio_interrupt, (void *)GPIO_PORT4));
|
||||
up_enable_irq(IMX9_IRQ_GPIO4_0);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IMX9_GPIO4_IRQ_OUT_LINE1
|
||||
DEBUGVERIFY(irq_attach(IMX9_IRQ_GPIO4_1,
|
||||
imx9_gpio_interrupt, (void *)GPIO_PORT4));
|
||||
up_enable_irq(IMX9_IRQ_GPIO4_1);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IMX9_GPIO5_IRQ_OUT_LINE0
|
||||
DEBUGVERIFY(irq_attach(IMX9_IRQ_GPIO5_0,
|
||||
imx9_gpio_interrupt, (void *)GPIO_PORT5));
|
||||
up_enable_irq(IMX9_IRQ_GPIO5_0);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IMX9_GPIO5_IRQ_OUT_LINE1
|
||||
DEBUGVERIFY(irq_attach(IMX9_IRQ_GPIO5_1,
|
||||
imx9_gpio_interrupt, (void *)GPIO_PORT5));
|
||||
up_enable_irq(IMX9_IRQ_GPIO5_1);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -258,6 +365,10 @@ int imx9_gpioirq_enable(gpio_pinset_t pinset)
|
|||
uint32_t regval;
|
||||
uintptr_t regaddr;
|
||||
|
||||
regval = getreg32(IMX9_GPIO_ICNS(port));
|
||||
regval &= ~(1 << (imx9_get_irqline_for_port(port)));
|
||||
putreg32(regval, IMX9_GPIO_ICNS(port));
|
||||
|
||||
/* Perform RMW to the specific pin */
|
||||
|
||||
regaddr = IMX9_GPIO_ICRN(port, pin);
|
||||
|
|
@ -285,6 +396,11 @@ int imx9_gpioirq_enable(gpio_pinset_t pinset)
|
|||
regval |= IMX9_GPIO_ICRN_FALLING;
|
||||
}
|
||||
|
||||
if (imx9_get_irqline_for_port(port))
|
||||
{
|
||||
regval |= IMX9_GPIO_ICRN_IRQS;
|
||||
}
|
||||
|
||||
putreg32(regval, regaddr);
|
||||
return OK;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue