📄 intr.c
字号:
// Valid board-level interrupt?
if (g_pBLRegs && (irq >= IRQ_MAINSTONEII_GPIO0_MIN) && (irq <= IRQ_MAINSTONEII_GPIO0_MAX))
{
UINT32 TempVal = (INREG32((PULONG)&g_pBLRegs->int_msk_en) & ~INTMSK_RESERVED_BITS);
OUTREG32((PULONG)&g_pBLRegs->int_msk_en, (TempVal & ~FPGA_INT_BIT(irq)));
// Masking the interrupt at the FPGA controller is enough - no need to mask the Bulverde GPIO0 interrupt.
irq = OAL_INTR_IRQ_UNDEFINED;
}
#if !WM_MAINSTONEII_FPGA_PEN_DETECT
/*
* Disable the pen detect interrupt.
*/
if ( g_pGPIORegs && ( IRQ_GPIOXX_2_PEN_DETECT == irq ) )
{
g_pGPIORegs->PEN_DETECT_GPIO_REG(GRER) &= ~GPIO_BIT(PEN_DETECT_GPIO_NUM);
}
#endif
OALMSG(OAL_INTR&&OAL_VERBOSE, (L"-BSPIntrDisableIrq(irq = %d\r\n", irq));
return irq;
}
//------------------------------------------------------------------------------
//
// Function: BSPIntrDoneIrq
//
// This function is called from OALIntrDoneIrq to finish interrupt on
// secondary interrupt controller or GPIO controller.
//
UINT32 BSPIntrDoneIrq(UINT32 irq)
{
OALMSG(OAL_INTR&&OAL_VERBOSE, (L"+BSPIntrDoneIrq(%d)\r\n", irq));
// Valid board-level interrupt?
if (g_pBLRegs && (irq >= IRQ_MAINSTONEII_GPIO0_MIN) && (irq <= IRQ_MAINSTONEII_GPIO0_MAX))
{
UINT32 TempVal;
TempVal = INREG32((PULONG)&g_pBLRegs->int_set_clr) & ~INTSETCLR_RESERVED_BITS;
OUTREG32((PULONG)&g_pBLRegs->int_set_clr, (TempVal & ~FPGA_INT_BIT(irq)));
TempVal = (INREG32((PULONG)&g_pBLRegs->int_msk_en) & ~INTMSK_RESERVED_BITS);
OUTREG32((PULONG)&g_pBLRegs->int_msk_en, (TempVal | FPGA_INT_BIT(irq)));
// Masking the interrupt at the FPGA controller is enough - no need to mask the Bulverde GPIO0 interrupt.
irq = OAL_INTR_IRQ_UNDEFINED;
}
#if !WM_MAINSTONEII_FPGA_PEN_DETECT
/*
* Enable the pen detect interrupt.
*/
if ( g_pGPIORegs && ( IRQ_GPIOXX_2_PEN_DETECT == irq ) )
{
g_pGPIORegs->PEN_DETECT_GPIO_REG(GRER) |= GPIO_BIT(PEN_DETECT_GPIO_NUM);
}
#endif
OALMSG(OAL_INTR&&OAL_VERBOSE, (L"-BSPIntrDoneIrq(irq = %d)\r\n", irq));
return irq;
}
//------------------------------------------------------------------------------
//
// Function: BSPIntrActiveIrq
//
// This function is called from interrupt handler to give BSP chance to
// translate IRQ in case of secondary interrupt controller.
//
UINT32 BSPIntrActiveIrq(UINT32 irq)
{
OALMSG(OAL_INTR&&OAL_VERBOSE, (L"+BSPIntrActiveIrq(%d)\r\n", irq));
switch(irq)
{
case IRQ_GPIO0:
irq = FPGAInterruptHandler(irq);
break;
case IRQ_GPIO1:
break;
case IRQ_GPIOXX_2:
irq = GPIOInterruptHandler(irq);
break;
default:
break;
}
OALMSG(OAL_INTR&&OAL_VERBOSE, (L"-BSPIntrActiveIrq(%d)\r\n", irq));
return irq;
}
//------------------------------------------------------------------------------
//
// Function: FPGAInterruptHandler
//
// This function is called from the BSP ISR to handle an FPGA interrupt.
//
static UINT32 FPGAInterruptHandler(UINT32 irq)
{
UINT8 nInt;
UINT32 TempVal;
// Read the pending FPGA interrupts and ignore masked/reserved interrupts.
TempVal = INREG32((PULONG)&g_pBLRegs->int_set_clr);
TempVal &= (INREG32((PULONG)&g_pBLRegs->int_msk_en) & ~INTMSK_RESERVED_BITS);
// Scan through the pending interrupts and look for a match.
for (nInt = IRQ_MAINSTONEII_GPIO0_MIN ; nInt <= IRQ_MAINSTONEII_GPIO0_MAX ; nInt++)
{
if (TempVal & FPGA_INT_BIT(nInt))
{
// Mask and clear the interrupt (note that we must write 0's to the reserved bits).
// Interrupt acknowledge occurs in the SMC ISR routine
TempVal = INREG32((PULONG)&g_pBLRegs->int_msk_en) & ~INTMSK_RESERVED_BITS;
OUTREG32((PULONG)&g_pBLRegs->int_msk_en, (TempVal & ~FPGA_INT_BIT(nInt)));
TempVal = INREG32((PULONG)&g_pBLRegs->int_set_clr) & ~INTSETCLR_RESERVED_BITS;
OUTREG32((PULONG)&g_pBLRegs->int_set_clr, (TempVal & ~FPGA_INT_BIT(nInt)));
break;
}
}
// If we see the PCCARD client IRQ asserted, look to see if the card is present in the
// slot. The MainstoneII PCCARD FPGA implementation is asserting the client IRQ upon
// card removal which can cause problems down the line when we try to read from the card.
//
if (nInt == IRQ_GPIO0_PCMCIA_S0)
{
if (g_pBLRegs->pcmcia0_srcr & PCMCIA_S0_nCD_MASK) nInt = IRQ_GPIO0;
}
if (nInt == IRQ_GPIO0_PCMCIA_S1)
{
if (g_pBLRegs->pcmcia1_srcr & PCMCIA_S1_nCD_MASK) nInt = IRQ_GPIO0;
}
// *** The following is to work around a problem in the MainstoneII FPGA ***
//
// Bulverde requires a minimum GPIO0 deassertion period before the GPIO0
// signal can be reasserted. Failure to comply can lead to problems with
// GPIO0 interrupt detection. As well, because the FPGA interrupt masking
// operation is a non-atomic read-modify-write operation, it's possible
// that an async FPGA interrupt can assert during that sequence which
// in turn violates Bulverde's GPIO0 timing requirements.
//
// 1. First, we'll save off the current interrupt mask (it will be later restored).
TempVal = (INREG32((PULONG)&g_pBLRegs->int_msk_en) & ~INTMSK_RESERVED_BITS);
// 2. Disable all FPGA interrupts (disable FPGA GPIO0 assertion to Bulverde).
OUTREG32((PULONG)&g_pBLRegs->int_msk_en, 0);
// 3. Clear the Bulverde GPIO0 falling edge detection.
OUTREG32((PULONG)&g_pGPIORegs->GEDR0, XLLP_GPIO_BIT_0);
// 4. Wait...
OALStall(1);
// 5. Restore the FPGA mask (this will cause any pending interrupts to assert
// to the Bulverde).
OUTREG32((PULONG)&g_pBLRegs->int_msk_en, TempVal);
return((nInt <= IRQ_MAINSTONEII_GPIO0_MAX) ? nInt : irq);
}
//------------------------------------------------------------------------------
//
// Function: GPIOInterruptHandler
//
// This function is called from the BSP ISR to handle an FPGA interrupt.
// NOTE: This function only handles the pen detect GPIO.
//
static UINT32 GPIOInterruptHandler(UINT32 irq)
{
UINT32 retval = 0;
volatile BULVERDE_INTR_REG *pIntrRegs = NULL;
pIntrRegs = (volatile BULVERDE_INTR_REG *) OALPAtoVA(BULVERDE_BASE_REG_PA_INTC, FALSE);
g_pGPIORegs = (volatile BULVERDE_GPIO_REG *) OALPAtoVA(BULVERDE_BASE_REG_PA_GPIO, FALSE);
// Disable GPIO interrupts
pIntrRegs->icmr &= ~XLLP_INTC_GPIOXX_2;
#if !WM_MAINSTONEII_FPGA_PEN_DETECT
// Check for the pen down interrupt.
if ( g_pGPIORegs->PEN_DETECT_GPIO_REG(GEDR) &
PEN_DETECT_GPIO_MASK
)
{
// Set the pen down GPIO bit to clear the edge detect status.
g_pGPIORegs->PEN_DETECT_GPIO_REG(GEDR) =
GPIO_BIT(PEN_DETECT_GPIO_NUM);
// Disable the Rising-Edge detect of the pen down GPIO.
g_pGPIORegs->PEN_DETECT_GPIO_REG(GRER) &=
~GPIO_BIT(PEN_DETECT_GPIO_NUM);
retval = IRQ_GPIOXX_2_PEN_DETECT;
}
#endif // !WM_MAINSTONEII_FPGA_PEN_DETECT
// Enable GPIO interrupts.
pIntrRegs->icmr |= XLLP_INTC_GPIOXX_2;
return(retval);
}
//------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -