Cortex-A9 GIC: Add an interface to set interrupt edge/level trigger
This commit is contained in:
parent
4feeb0c2b4
commit
e6728bac29
@ -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 */
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
=================
|
||||
|
Loading…
Reference in New Issue
Block a user