Cortex-A9 GIC: Add an interface to set interrupt edge/level trigger

This commit is contained in:
Gregory Nutt 2016-05-16 14:42:55 -06:00
parent 4feeb0c2b4
commit e6728bac29
5 changed files with 91 additions and 1 deletions

View File

@ -523,4 +523,56 @@ int up_prioritize_irq(int irq, int priority)
return -EINVAL;
}
/****************************************************************************
* Name: arm_gic_irq_trigger
*
* Description:
* Set the trigger type for the specificd IRQ source and the current CPU.
*
* Since this API is not supported on all architectures, it should be
* avoided in common implementations where possible.
*
* Input Paramters:
* irq - The interrupt request to modify.
* edge - False: Active HIGH level sensitive, True: Rising edge sensitive
*
* Returned Value:
* Zero (OK) on success; a negated errno value is returned on any failure.
*
****************************************************************************/
int arm_gic_irq_trigger(int irq, bool edge)
{
uintptr_t regaddr;
uint32_t regval;
uint32_t intcfg;
if (irq > GIC_IRQ_SGI15 && irq < NR_IRQS)
{
/* Get the address of the Interrupt Configuration Register for this
* irq.
*/
regaddr = GIC_ICDICFR(irq);
/* Get the new Interrupt configuration bit setting */
intcfg = (edge ? (INT_ICDICFR_EDGE | INT_ICDICFR_1N) : INT_ICDICFR_1N);
/* Write the correct interrupt trigger to the Interrupt Configuration
* Register.
*/
regval = getreg32(regaddr);
regval &= ~GIC_ICDICFR_ID_MASK(irq);
regval |= GIC_ICDICFR_ID(irq, intcfg);
putreg32(regval, regaddr);
return OK;
}
return -EINVAL;
}
#endif /* CONFIG_ARMV7A_HAVE_GICv2 */

View File

@ -495,7 +495,7 @@
#define INT_ICDICFR_EDGE 2 /* Bit n+2: 1=Edge sensitive */
#define GIC_ICDICFR_ID_SHIFT(n) GIC_SHIFT16(n)
#define GIC_ICDICFR_ID_MASK(n) GIC_MASK16(n
#define GIC_ICDICFR_ID_MASK(n) GIC_MASK16(n)
# define GIC_ICDICFR_ID(n,c) ((uint32_t)(c) << GIC_SHIFT16(n))
/* PPI Status Register */
@ -720,6 +720,26 @@ void arm_gic0_initialize(void);
void arm_gic_initialize(void);
/****************************************************************************
* Name: arm_gic_irq_trigger
*
* Description:
* Set the trigger type for the specificd IRQ source and the current CPU.
*
* Since this API is not supported on all architectures, it should be
* avoided in common implementations where possible.
*
* Input Paramters:
* irq - The interrupt request to modify.
* edge - False: Active HIGH level sensitive, True: Rising edge sensitive
*
* Returned Value:
* Zero (OK) on success; a negated errno value is returned on any failure.
*
****************************************************************************/
int arm_gic_irq_trigger(int irq, bool edge);
/****************************************************************************
* Name: arm_decodeirq
*

View File

@ -57,6 +57,7 @@
#include "up_arch.h"
#include "up_internal.h"
#include "gic.h"
#include "chip/imx_uart.h"
#include "imx_config.h"
#include "imx_lowputc.h"
@ -613,6 +614,10 @@ static int imx_attach(struct uart_dev_s *dev)
ret = irq_attach(priv->irq, priv->handler);
if (ret == OK)
{
/* Configure as a (high) level interrupt */
(void)arm_gic_irq_trigger(priv->irq, false);
/* Enable the interrupt (RX and TX interrupts are still disabled
* in the UART
*/

View File

@ -46,6 +46,7 @@
#include <arch/irq.h>
#include "up_arch.h"
#include "gic.h"
#include "chip/imx_ccm.h"
#include "chip/imx_gpt.h"
@ -235,6 +236,10 @@ void up_timer_initialize(void)
cr |= GPT_CR_EN;
putreg32(cr, IMX_GPT_CR);
/* Configure as a (rising) edge-triggered interrupt */
(void)arm_gic_irq_trigger(IMX_IRQ_GPT, true);
/* Attach the timer interrupt vector */
(void)irq_attach(IMX_IRQ_GPT, (xcpt_t)up_timerisr);

View File

@ -46,6 +46,14 @@ no interrupt driver serial console output (syslog, printf).
2016-05-16: I know get serial interrupts (but not timer interrupts). This
involves a few changes to GIC bit settings that I do not fully understand.
With this change, the NSH serial console works:
MX6Q SABRESD U-Boot > ABEFGHILMN
NuttShell (NSH)
nsh>
But there are still no timer interrupts.
Platform Features
=================